Main brez modelov

This commit is contained in:
Marko Ferme
2022-12-07 06:22:36 +01:00
parent 89fa62796e
commit 1cd7663d49
93 changed files with 98496 additions and 508 deletions
+5
View File
@@ -0,0 +1,5 @@
MDB_DATABASE=
MDB_HOST=
MDB_PORT=
MDB_USER=
MDB_PASSWORD=
-1
View File
@@ -4,7 +4,6 @@ import connexion
from swagger_server import encoder
def main():
app = connexion.App(__name__, specification_dir='./swagger/')
app.app.json_encoder = encoder.JSONEncoder
@@ -1,30 +0,0 @@
import connexion
import six
from swagger_server import util
def datoteka_v_besedilo_post(file=None): # noqa: E501
"""Pretvori datoteko formata pdf, doc, docx, ppt, xls,... v besedilo
# noqa: E501
:param file:
:type file: strstr
:rtype: str
"""
return 'do some magic!'
def get_text_ocr(file=None): # noqa: E501
"""Pretvori datoteko formata pdf, doc, docx, ppt, xls,... v besedilo s pomočjo ocr razpoznavanja
# noqa: E501
:param file:
:type file: strstr
:rtype: str
"""
return 'do some magic!'
@@ -1,21 +1,88 @@
import codecs
import os
import connexion
import six
import json
from pathlib import Path
from swagger_server.models.izlusci_async_body import IzlusciAsyncBody # noqa: E501
from swagger_server.models.izlusci_sync_body import IzlusciSyncBody # noqa: E501
from swagger_server.requets_db.models.vrsta import JobManager
from swagger_server.utils import cl_utils
from swagger_server.util import get_random_filename, create_random_file_in_tmp_folder
import requests
from werkzeug.utils import secure_filename
from swagger_server.models.izlusci_body import IzlusciBody # noqa: E501
from swagger_server.models.terminoloski_kandidat import TerminoloskiKandidat # noqa: E501
from swagger_server import util
ATEapi_endpoint = "http://ate-api:5000/predict"
# endpoint below to be used only for development purposes (don't need to run docker)
# ATEapi_endpoint = "http://localhost:5000/predict"
def get_candidates(body): # noqa: E501
"""Izlusci terminološke kandidate iz seznama besedil v conllu obliki
def do_izlusci(conllus, prepovedane_besede):
tmp_file_path = ""
try:
big_conllu = cl_utils.multipla_conllus_to_one_from_conllus_arr(conllus)
tmp_file_path = create_random_file_in_tmp_folder(big_conllu, ".conllu")
fp = open(tmp_file_path, 'rb')
try:
files = [
('file', ('temp_1.conllu', fp, 'application/octet-stream'))
]
res = requests.post(ATEapi_endpoint, files=files)
data = json.loads(res.text)
finally:
fp.close()
os.remove(tmp_file_path)
ret = {'terminoloski_kandidati': [
{
'POSoznake': tk['msd'],
'kandidat': tk['terms'], # more to bit lemma al terms?
'kanonicnaoblika': tk['canonical'],
'ranking': tk['ranking'],
'podporneutezi': [
0.0, # ????????
0.0 # ??????
],
'pogostostpojavljanja': [0, 0] # ???????
}
for tk in data if tk['terms'] not in prepovedane_besede
]}
return ret, 200
except Exception as e:
return str(e), 500
def get_candidates_async(body): # noqa: E501
"""Izlusci terminološke kandidate iz seznama besedil v conllu obliki [asinhrono, ustvari novi job]
# noqa: E501
:param body:
:param body:
:type body: dict | bytes
:rtype: str
"""
if connexion.request.is_json:
body = IzlusciAsyncBody.from_dict(connexion.request.get_json()) # noqa: E501
job, is_old_job = JobManager.create_job(4, json.dumps(body.to_dict()))
if job is None:
return "Something went wrong", 500
ret = {'check_job_url': f'{connexion.request.url_root}/job/{job.id}'}
return ret, 200
def get_candidates_sync(body): # noqa: E501
"""Izlusci terminološke kandidate iz seznama besedil v conllu obliki [sihrono, rezultat v sami zahtevi]
# noqa: E501
:param body:
:type body: dict | bytes
:rtype: List[TerminoloskiKandidat]
"""
if connexion.request.is_json:
body = IzlusciBody.from_dict(connexion.request.get_json()) # noqa: E501
return 'do some magic!'
body = IzlusciSyncBody.from_dict(connexion.request.get_json()) # noqa: E501
return do_izlusci(body.conllus, body.prepovedane_besede)
@@ -0,0 +1,233 @@
import datetime
import json
import os.path
import traceback
import peewee
import asyncio
import concurrent.futures as cf
from swagger_server.controllers.extract_controller import do_izlusci
from swagger_server.models.job_response import JobResponse # noqa: E501
from swagger_server.requets_db.models.vrsta import (Job)
from threading import Thread
from swagger_server.utils import cl_utils
from swagger_server.utils import txt_utils
from werkzeug.datastructures import FileStorage
import threading
import time
CLASSLA_CONCURANCE_LIMIT = 3
DOC2TEXT_CONCURANCE_LIMIT = 3
ATEAPI_CONCURANCE_LIMIT = 2
classla_sem = threading.Semaphore(CLASSLA_CONCURANCE_LIMIT)
doc2text_sem = threading.Semaphore(DOC2TEXT_CONCURANCE_LIMIT)
ateapi_sem = threading.Semaphore(ATEAPI_CONCURANCE_LIMIT)
def delete_job(job_id): # noqa: E501
"""Izbriše job
# noqa: E501
:param job_id:
:type job_id: int
:rtype: str
"""
return 'Endpoint currently disabled'
def get_job_status(job_id): # noqa: E501
"""Vrne status
# noqa: E501
:param job_id:
:type job_id: int
:rtype: JobResponse
"""
try:
job = Job.get_by_id(job_id)
if job.started_on is None:
return JobResponse(job_status="waiting in que", created_on=job.created_on), 200
if job.started_on is not None and job.finished_on is None:
return JobResponse(job_status="currently processing", created_on=job.created_on,
started_on=job.started_on), 200
if job.started_on is not None and job.finished_on is not None:
return JobResponse(job_status="finished processing", created_on=job.created_on, started_on=job.started_on,
finished_on=job.finished_on, job_result=job.job_output), 200
except peewee.DoesNotExist:
return "Job with this ID does not exist", 404
def clear_up_unfinished_jobs():
"""
In case server crashed while jobs were in queue...
"""
Job.update(started_on=None).where(Job.started_on.is_null(False), Job.finished_on.is_null()).execute()
if os.path.exists('tmp'):
for tmp_file in os.listdir('tmp'):
if not Job.select().where(Job.input_file == tmp_file).exists():
os.remove(f'tmp/{tmp_file}')
async def try_do_jobs():
with cf.ThreadPoolExecutor(max_workers=3) as ex:
ex.submit(try_do_jobs_classla)
ex.submit(try_do_jobs_doc2text)
ex.submit(try_do_jobs_ateapi)
### Job looping
def try_do_jobs_ateapi():
while True:
try:
if ateapi_sem._value > 0:
unfinished_jobs = Job.select() \
.where(Job.finished_on.is_null(), Job.started_on.is_null(), Job.job_type == 4) \
.limit(ateapi_sem._value)
with cf.ThreadPoolExecutor(max_workers=ATEAPI_CONCURANCE_LIMIT) as ex:
[ex.submit(execute_ateapi_job, job) for job in unfinished_jobs]
except Exception as e:
print(f"Exception in try_do_jobs_ateapi")
traceback.print_exc()
finally:
time.sleep(3)
### Job looping
def try_do_jobs_classla():
time.sleep(15) # wait for tokenizers to load for classla ...
while True:
try:
if cl_utils.nlp_loaded:
if classla_sem._value > 0:
unfinished_jobs_txt = Job.select() \
.where(Job.finished_on.is_null(), Job.job_type == 2,
Job.input_file.is_null(False)) \
.limit(classla_sem._value)
unfinished_jobs_no_txt = Job.select() \
.where(Job.finished_on.is_null(), Job.started_on.is_null(), Job.job_type == 2,
Job.input_file.is_null()) \
.limit(classla_sem._value)
unfinished_jobs = [j for j in unfinished_jobs_txt] + [j for j in unfinished_jobs_no_txt]
unfinished_jobs = unfinished_jobs[:classla_sem._value]
with cf.ThreadPoolExecutor(max_workers=CLASSLA_CONCURANCE_LIMIT) as ex:
[ex.submit(execute_classla_job, job) for job in unfinished_jobs]
except Exception as e:
print(f"Exception in try_do_jobs_classla")
traceback.print_exc()
finally:
time.sleep(3)
### Job looping
def try_do_jobs_doc2text():
while True:
try:
if doc2text_sem._value > 0:
unfinished_jobs = Job.select() \
.where(Job.finished_on.is_null(), Job.started_on.is_null(), Job.job_type << [1, 12, 3, 32]) \
.limit(doc2text_sem._value)
with cf.ThreadPoolExecutor(max_workers=DOC2TEXT_CONCURANCE_LIMIT) as ex:
[ex.submit(execute_doc2text_job, job) for job in unfinished_jobs]
except Exception as e:
print(f"Exception in try_do_jobs_doc2text")
traceback.print_exc()
finally:
time.sleep(3)
async def prep_jobs(tasks):
await asyncio.gather(*tasks)
def execute_doc2text_job(job: Job):
try:
doc2text_sem.acquire()
del_file = False
job.started_on = datetime.datetime.utcnow()
job.save()
tmp_file_path = job.input_file
if not os.path.exists(tmp_file_path):
job.finished_on = datetime.datetime.utcnow()
job.job_output = "ERROR - Temporary file went missing, couldn't properly finish job"
job.save()
return
with open(tmp_file_path, 'rb+') as f:
file = FileStorage(f)
jtype = job.job_type
text = ""
if jtype in [1, 12]:
text, _ = txt_utils.extract_text_prepResp(file)
elif jtype in [3, 32]:
text, _ = txt_utils.ocr_text_prepResp(file)
if jtype in [1, 3]:
job.job_output = text
job.finished_on = datetime.datetime.utcnow()
elif jtype in [12, 32]:
job.job_input = text
job.job_type = 2
job.input_size = len(text)
del_file = True
job.save()
if del_file:
try:
os.remove(tmp_file_path)
except:
pass
except:
job.started_on = None
job.save()
finally:
doc2text_sem.release()
def execute_classla_job(job: Job):
try:
classla_sem.acquire()
job.started_on = datetime.datetime.utcnow()
job.save()
conllu, _ = cl_utils.raw_text_to_conllu(job.job_input)
job.job_output = conllu
job.finished_on = datetime.datetime.utcnow()
job.save()
finally:
classla_sem.release()
def execute_ateapi_job(job: Job):
try:
ateapi_sem.acquire()
job.started_on = datetime.datetime.utcnow()
job.save()
info = json.loads(job.job_input)
ret_json, _ = do_izlusci(info['conllus'], info['prepovedane_besede'])
job.job_output = ret_json
job.finished_on = datetime.datetime.utcnow()
job.save()
finally:
ateapi_sem.release()
clear_up_unfinished_jobs()
loop = asyncio.get_event_loop()
def loop_in_thread(loop):
asyncio.set_event_loop(loop)
loop.run_until_complete(try_do_jobs())
t = Thread(target=loop_in_thread, args=(loop,))
t.start()
@@ -0,0 +1,96 @@
import connexion
from swagger_server.models.oznaci_besedilo_async_body import OznaciBesediloAsyncBody # noqa: E501
from swagger_server.requets_db.models.vrsta import (JobManager)
def get_text(body): # noqa: E501
"""Označi besedilo s classlo/stanzo z uporabo slovenskih modelov ter vrne conll-u format
# noqa: E501
:param body:
:type body: dict | bytes
:rtype: str
"""
if connexion.request.is_json:
body = OznaciBesediloAsyncBody.from_dict(connexion.request.get_json()) # noqa: E501
else:
return "Request in wrong format", 400
# conllu = cl_utils.raw_text_to_conllu(body.besedilo)
# return conllu
job, is_old_job = JobManager.create_job(2, body.besedilo)
if job is None:
return "Something went wrong", 500
ret = {'check_job_url': f'{connexion.request.url_root}/job/{job.id}'}
return ret, 200 # Todo: Update swagger to the newest response template later
def get_conllu_from_file_async(file=None): # noqa: E501
"""Pretvori datoteko v besedilo in označi s classlo/stanzo z uporabo slovenskih modelov ter vrne conll-u format
# noqa: E501
:param file:
:type file: strstr
:rtype: str
"""
job, is_old_job = JobManager.create_job(12, file)
if job is None:
return "Something went wrong", 500
ret = {'check_job_url': f'{connexion.request.url_root}/job/{job.id}'}
return ret, 200
def get_conllu_from_file_ocr_async(file=None): # noqa: E501
"""Pretvori datoteko v besedilo in označi s classlo/stanzo z uporabo slovenskih modelov ter vrne conll-u format
# noqa: E501
:param file:
:type file: strstr
:rtype: str
"""
job, is_old_job = JobManager.create_job(32, file)
if job is None:
return "Something went wrong", 500
ret = {'check_job_url': f'{connexion.request.url_root}/job/{job.id}'}
return ret, 200
def get_text_from_doc_async(file=None): # noqa: E501
"""Pretvori datoteko v besedilo, vrača tekst
# noqa: E501
:param file:
:type file: strstr
:rtype: str
"""
job, is_old_job = JobManager.create_job(1, file)
if job is None:
return "Something went wrong", 500
ret = {'check_job_url': f'{connexion.request.url_root}/job/{job.id}'}
return ret, 200
def get_text_from_file_ocr_async(file=None): # noqa: E501
"""Pretvori datoteko v besedilo s pomočjo ocr razpoznavanja, vrača tekst
# noqa: E501
:param file:
:type file: strstr
:rtype: str
"""
job, is_old_job = JobManager.create_job(3, file)
if job is None:
return "Something went wrong", 500
ret = {'check_job_url': f'{connexion.request.url_root}/job/{job.id}'}
return ret, 200
@@ -1,19 +0,0 @@
import connexion
import six
from swagger_server import util
def get_text(body): # noqa: E501
"""Označi besedilo s classlo/stanzo z uporabo slovenskih modelov ter vrne conll-u format
# noqa: E501
:param body:
:type body: dict | bytes
:rtype: str
"""
if connexion.request.is_json:
body = str.from_dict(connexion.request.get_json()) # noqa: E501
return 'do some magic!'
@@ -0,0 +1,81 @@
from swagger_server.utils import cl_utils
from swagger_server.utils import txt_utils
def datoteka_v_besedilo_in_classla(file=None): # noqa: E501
"""Pretvori datoteko formata pdf, doc, docx, ppt, xls,... vrača conllu
# noqa: E501
:param file:
:type file: strstr
:rtype: str
"""
if not cl_utils.nlp_loaded:
return "NLP Models still loading up since server restart, please try again later.", 500
if file is None:
return "No file provided", 400
try:
txt, _ = txt_utils.extract_text_prepResp(file)
return cl_utils.raw_text_to_conllu(txt)
except Exception as e:
return str(e), 500
def datoteka_v_besedilo_sync_post(file=None): # noqa: E501
"""Pretvori datoteko formata pdf, doc, docx, ppt, xls,... vrača besedilo
# noqa: E501
:param file:
:type file: strstr
:rtype: str
"""
if file is None:
return "No file provided", 400
try:
return txt_utils.extract_text_prepResp(file)
except Exception as e:
print(e)
return str(e), 500
def get_conllu_ocr(file=None): # noqa: E501
"""Pretvori datoteko formata pdf, doc, docx, ppt, xls,... v conllu s pomočjo ocr razpoznavanja
# noqa: E501
:param file:
:type file: strstr
:rtype: str
"""
if not cl_utils.nlp_loaded:
return "NLP Models still loading up since server restart, please try again later.", 500
if file is None:
return "No file provided", 400
try:
txt, _ = txt_utils.ocr_text_prepResp(file)
return cl_utils.raw_text_to_conllu(txt)
except Exception as e:
return str(e), 500
def get_text_ocr(file=None): # noqa: E501
"""Pretvori datoteko formata pdf, doc, docx, ppt, xls,... v besedilo s pomočjo ocr razpoznavanja
# noqa: E501
:param file:
:type file: strstr
:rtype: str
"""
if file is None:
return "No file provided", 400
try:
return txt_utils.ocr_text_prepResp(file)
except Exception as e:
return str(e), 500
+74 -41
View File
@@ -1,21 +1,6 @@
import connexion
import six
from swagger_server.models.terminoloski_kandidat import TerminoloskiKandidat # noqa: E501
from swagger_server.utils import db_utils
from swagger_server import util
def get_conllu(id): # noqa: E501
"""Vrne CoNNL-U po id-ju datoteke
# noqa: E501
:param id:
:type id: int
:rtype: str
"""
return 'do some magic!'
from flask import send_file
def get_conllus(leta, vrste, kljucnebesede, cerifpodrocja): # noqa: E501
@@ -34,10 +19,16 @@ def get_conllus(leta, vrste, kljucnebesede, cerifpodrocja): # noqa: E501
:rtype: List[str]
"""
return 'do some magic!'
if not kljucnebesede:
return "Manjkajo kljucne besede", 400
#zaenkrat ne potrebujemo te storitve
files = db_utils.get_files_by_udc(kljucnebesede)
if not files:
return 'Nobena datoteka ne ustreza iskalnemu pogoju', 404
return ' '.join(files), 200
def get_extracted_words(leta, vrste, kljucnebesede, cerifpodrocja): # noqa: E501
def get_extracted_words(leta=None, vrste=None, kljucnebesede=None, udk=None): # noqa: E501
"""Vrne terminloške kandidate glede na
# noqa: E501
@@ -53,21 +44,10 @@ def get_extracted_words(leta, vrste, kljucnebesede, cerifpodrocja): # noqa: E50
:rtype: List[TerminoloskiKandidat]
"""
return 'do some magic!'
files = db_utils.vrni_oss_terminoloske_kandidate(leta, vrste, kljucnebesede, udk)
return files, 200
def get_file(id): # noqa: E501
"""Vrne binarni zapis v originalnem formatu po id-ju datoteke
# noqa: E501
:param id:
:type id: int
:rtype: List[bytearray]
"""
return 'do some magic!'
def get_files(leta, vrste, kljucnebesede, cerifpodrocja): # noqa: E501
"""Vrne seznam binarnih zapisov v originalnem formatu glede na iskalne pogoje
@@ -85,10 +65,16 @@ def get_files(leta, vrste, kljucnebesede, cerifpodrocja): # noqa: E501
:rtype: List[List[bytearray]]
"""
return 'do some magic!'
if not kljucnebesede:
return "Manjkajo kljucne besede", 400
#zaenkrat ne potrebujemo te storitve
files = db_utils.get_files_by_udc(kljucnebesede)
if not files:
return 'Nobena datoteka ne ustreza iskalnemu pogoju', 404
return ' '.join(files), 200
def get_number_texts(leta, vrste, kljucnebesede, cerifpodrocja): # noqa: E501
def get_number_texts(leta=None, vrste=None, kljucnebesede=None, udk=None): # noqa: E501
"""Vrne število besedil glede na iskalne pogoje
# noqa: E501
@@ -100,11 +86,15 @@ def get_number_texts(leta, vrste, kljucnebesede, cerifpodrocja): # noqa: E501
:param kljucnebesede:
:type kljucnebesede: List[str]
:param cerifpodrocja:
:type cerifpodrocja: List[int]
:type udc: List[int]
:rtype: int
"""
return 'do some magic!'
#if not kljucnebesede:
# return "Manjkajo kljucne besede", 400
files = db_utils.vrni_oss_dokumente(leta, vrste, kljucnebesede, udk)
return len(files), 200
def get_texts(leta, vrste, kljucnebesede, cerifpodrocja): # noqa: E501
@@ -123,17 +113,60 @@ def get_texts(leta, vrste, kljucnebesede, cerifpodrocja): # noqa: E501
:rtype: List[str]
"""
return 'do some magic!'
if not kljucnebesede:
return "Manjkajo kljucne besede", 400
#zaenkrat ne potrebujemo te storitve
files = db_utils.get_files_by_udc(kljucnebesede)
if not files:
return 'Nobena datoteka ne ustreza iskalnemu pogoju', 404
return ' '.join(files), 200
def oss_besedilo_po_id_get(id): # noqa: E501
def get_conllu(file_id): # noqa: E501
"""Vrne CoNNL-U po id-ju datoteke
# noqa: E501
:param file_id:
:type file_id: int
:rtype: str
"""
try:
return send_file(util.get_conllu_file_path_by_id(file_id), download_name=f'{file_id}.conllu')
except FileNotFoundError as e:
return "The conllu with this ID doesn't exist.", 404
def get_file(file_id): # noqa: E501
"""Vrne binarni zapis v originalnem formatu po id-ju datoteke
# noqa: E501
:param file_id:
:type file_id: int
:rtype: List[bytearray]
"""
try:
return send_file(util.get_original_file_path_by_id(file_id), download_name=f'{file_id}.xml')
except FileNotFoundError as e:
return "The file with this ID doesn't exist.", 404
def oss_besedilo_po_id_get(file_id): # noqa: E501
"""Vrne besedilo po id-ju datoteke
# noqa: E501
:param id:
:type id: int
:param file_id:
:type file_id: int
:rtype: str
"""
return 'do some magic!'
try:
f = util.get_original_file_path_by_id(file_id)
print(f) # for debugging purposes on the server, delete this later
return send_file(util.get_original_file_path_by_id(file_id), download_name=f'{file_id}.xml')
except FileNotFoundError as e:
return "The file with this ID doesn't exist.", 404
+12 -3
View File
@@ -3,7 +3,16 @@
# flake8: noqa
from __future__ import absolute_import
# import models into model package
from swagger_server.models.datoteka_v_besedilo_body import DatotekaVBesediloBody
from swagger_server.models.datoteka_v_besedilo_ocr_body import DatotekaVBesediloOcrBody
from swagger_server.models.izlusci_body import IzlusciBody
from swagger_server.models.datoteka_v_besedilo_async_body import DatotekaVBesediloAsyncBody
from swagger_server.models.datoteka_v_besedilo_async_ocr_body import DatotekaVBesediloAsyncOcrBody
from swagger_server.models.datoteka_v_besedilo_sync_body import DatotekaVBesediloSyncBody
from swagger_server.models.datoteka_v_besedilo_sync_ocr_body import DatotekaVBesediloSyncOcrBody
from swagger_server.models.datoteka_v_conllu_async_body import DatotekaVConlluAsyncBody
from swagger_server.models.datoteka_v_conllu_async_ocr_body import DatotekaVConlluAsyncOcrBody
from swagger_server.models.datoteka_v_conllu_sync_body import DatotekaVConlluSyncBody
from swagger_server.models.datoteka_v_conllu_sync_ocr_body import DatotekaVConlluSyncOcrBody
from swagger_server.models.job_response import JobResponse
from swagger_server.models.oznaci_besedilo_async_body import OznaciBesediloAsyncBody
from swagger_server.models.terminoloski_kandidat import TerminoloskiKandidat
from swagger_server.models.izlusci_async_body import IzlusciAsyncBody
from swagger_server.models.izlusci_sync_body import IzlusciSyncBody
@@ -0,0 +1,64 @@
# coding: utf-8
from __future__ import absolute_import
from datetime import date, datetime # noqa: F401
from typing import List, Dict # noqa: F401
from swagger_server.models.base_model_ import Model
from swagger_server import util
class DatotekaVBesediloAsyncBody(Model):
"""NOTE: This class is auto generated by the swagger code generator program.
Do not edit the class manually.
"""
def __init__(self, file: str=None): # noqa: E501
"""DatotekaVBesediloAsyncBody - a model defined in Swagger
:param file: The file of this DatotekaVBesediloAsyncBody. # noqa: E501
:type file: str
"""
self.swagger_types = {
'file': str
}
self.attribute_map = {
'file': 'file'
}
self._file = file
@classmethod
def from_dict(cls, dikt) -> 'DatotekaVBesediloAsyncBody':
"""Returns the dict as a model
:param dikt: A dict.
:type: dict
:return: The datotekaVBesediloAsync_body of this DatotekaVBesediloAsyncBody. # noqa: E501
:rtype: DatotekaVBesediloAsyncBody
"""
return util.deserialize_model(dikt, cls)
@property
def file(self) -> str:
"""Gets the file of this DatotekaVBesediloAsyncBody.
:return: The file of this DatotekaVBesediloAsyncBody.
:rtype: str
"""
return self._file
@file.setter
def file(self, file: str):
"""Sets the file of this DatotekaVBesediloAsyncBody.
:param file: The file of this DatotekaVBesediloAsyncBody.
:type file: str
"""
if file is None:
raise ValueError("Invalid value for `file`, must not be `None`") # noqa: E501
self._file = file
@@ -0,0 +1,64 @@
# coding: utf-8
from __future__ import absolute_import
from datetime import date, datetime # noqa: F401
from typing import List, Dict # noqa: F401
from swagger_server.models.base_model_ import Model
from swagger_server import util
class DatotekaVBesediloAsyncOcrBody(Model):
"""NOTE: This class is auto generated by the swagger code generator program.
Do not edit the class manually.
"""
def __init__(self, file: str=None): # noqa: E501
"""DatotekaVBesediloAsyncOcrBody - a model defined in Swagger
:param file: The file of this DatotekaVBesediloAsyncOcrBody. # noqa: E501
:type file: str
"""
self.swagger_types = {
'file': str
}
self.attribute_map = {
'file': 'file'
}
self._file = file
@classmethod
def from_dict(cls, dikt) -> 'DatotekaVBesediloAsyncOcrBody':
"""Returns the dict as a model
:param dikt: A dict.
:type: dict
:return: The datotekaVBesediloAsync_ocr_body of this DatotekaVBesediloAsyncOcrBody. # noqa: E501
:rtype: DatotekaVBesediloAsyncOcrBody
"""
return util.deserialize_model(dikt, cls)
@property
def file(self) -> str:
"""Gets the file of this DatotekaVBesediloAsyncOcrBody.
:return: The file of this DatotekaVBesediloAsyncOcrBody.
:rtype: str
"""
return self._file
@file.setter
def file(self, file: str):
"""Sets the file of this DatotekaVBesediloAsyncOcrBody.
:param file: The file of this DatotekaVBesediloAsyncOcrBody.
:type file: str
"""
if file is None:
raise ValueError("Invalid value for `file`, must not be `None`") # noqa: E501
self._file = file
@@ -0,0 +1,64 @@
# coding: utf-8
from __future__ import absolute_import
from datetime import date, datetime # noqa: F401
from typing import List, Dict # noqa: F401
from swagger_server.models.base_model_ import Model
from swagger_server import util
class DatotekaVBesediloSyncBody(Model):
"""NOTE: This class is auto generated by the swagger code generator program.
Do not edit the class manually.
"""
def __init__(self, file: str=None): # noqa: E501
"""DatotekaVBesediloSyncBody - a model defined in Swagger
:param file: The file of this DatotekaVBesediloSyncBody. # noqa: E501
:type file: str
"""
self.swagger_types = {
'file': str
}
self.attribute_map = {
'file': 'file'
}
self._file = file
@classmethod
def from_dict(cls, dikt) -> 'DatotekaVBesediloSyncBody':
"""Returns the dict as a model
:param dikt: A dict.
:type: dict
:return: The datotekaVBesediloSync_body of this DatotekaVBesediloSyncBody. # noqa: E501
:rtype: DatotekaVBesediloSyncBody
"""
return util.deserialize_model(dikt, cls)
@property
def file(self) -> str:
"""Gets the file of this DatotekaVBesediloSyncBody.
:return: The file of this DatotekaVBesediloSyncBody.
:rtype: str
"""
return self._file
@file.setter
def file(self, file: str):
"""Sets the file of this DatotekaVBesediloSyncBody.
:param file: The file of this DatotekaVBesediloSyncBody.
:type file: str
"""
if file is None:
raise ValueError("Invalid value for `file`, must not be `None`") # noqa: E501
self._file = file
@@ -0,0 +1,64 @@
# coding: utf-8
from __future__ import absolute_import
from datetime import date, datetime # noqa: F401
from typing import List, Dict # noqa: F401
from swagger_server.models.base_model_ import Model
from swagger_server import util
class DatotekaVBesediloSyncOcrBody(Model):
"""NOTE: This class is auto generated by the swagger code generator program.
Do not edit the class manually.
"""
def __init__(self, file: str=None): # noqa: E501
"""DatotekaVBesediloSyncOcrBody - a model defined in Swagger
:param file: The file of this DatotekaVBesediloSyncOcrBody. # noqa: E501
:type file: str
"""
self.swagger_types = {
'file': str
}
self.attribute_map = {
'file': 'file'
}
self._file = file
@classmethod
def from_dict(cls, dikt) -> 'DatotekaVBesediloSyncOcrBody':
"""Returns the dict as a model
:param dikt: A dict.
:type: dict
:return: The datotekaVBesediloSync_ocr_body of this DatotekaVBesediloSyncOcrBody. # noqa: E501
:rtype: DatotekaVBesediloSyncOcrBody
"""
return util.deserialize_model(dikt, cls)
@property
def file(self) -> str:
"""Gets the file of this DatotekaVBesediloSyncOcrBody.
:return: The file of this DatotekaVBesediloSyncOcrBody.
:rtype: str
"""
return self._file
@file.setter
def file(self, file: str):
"""Sets the file of this DatotekaVBesediloSyncOcrBody.
:param file: The file of this DatotekaVBesediloSyncOcrBody.
:type file: str
"""
if file is None:
raise ValueError("Invalid value for `file`, must not be `None`") # noqa: E501
self._file = file
@@ -9,15 +9,15 @@ from swagger_server.models.base_model_ import Model
from swagger_server import util
class DatotekaVBesediloOcrBody(Model):
class DatotekaVConlluAsyncBody(Model):
"""NOTE: This class is auto generated by the swagger code generator program.
Do not edit the class manually.
"""
def __init__(self, file: str=None): # noqa: E501
"""DatotekaVBesediloOcrBody - a model defined in Swagger
"""DatotekaVConlluAsyncBody - a model defined in Swagger
:param file: The file of this DatotekaVBesediloOcrBody. # noqa: E501
:param file: The file of this DatotekaVConlluAsyncBody. # noqa: E501
:type file: str
"""
self.swagger_types = {
@@ -30,32 +30,32 @@ class DatotekaVBesediloOcrBody(Model):
self._file = file
@classmethod
def from_dict(cls, dikt) -> 'DatotekaVBesediloOcrBody':
def from_dict(cls, dikt) -> 'DatotekaVConlluAsyncBody':
"""Returns the dict as a model
:param dikt: A dict.
:type: dict
:return: The datotekaVBesedilo_ocr_body of this DatotekaVBesediloOcrBody. # noqa: E501
:rtype: DatotekaVBesediloOcrBody
:return: The datotekaVConlluAsync_body of this DatotekaVConlluAsyncBody. # noqa: E501
:rtype: DatotekaVConlluAsyncBody
"""
return util.deserialize_model(dikt, cls)
@property
def file(self) -> str:
"""Gets the file of this DatotekaVBesediloOcrBody.
"""Gets the file of this DatotekaVConlluAsyncBody.
:return: The file of this DatotekaVBesediloOcrBody.
:return: The file of this DatotekaVConlluAsyncBody.
:rtype: str
"""
return self._file
@file.setter
def file(self, file: str):
"""Sets the file of this DatotekaVBesediloOcrBody.
"""Sets the file of this DatotekaVConlluAsyncBody.
:param file: The file of this DatotekaVBesediloOcrBody.
:param file: The file of this DatotekaVConlluAsyncBody.
:type file: str
"""
if file is None:
@@ -0,0 +1,64 @@
# coding: utf-8
from __future__ import absolute_import
from datetime import date, datetime # noqa: F401
from typing import List, Dict # noqa: F401
from swagger_server.models.base_model_ import Model
from swagger_server import util
class DatotekaVConlluAsyncOcrBody(Model):
"""NOTE: This class is auto generated by the swagger code generator program.
Do not edit the class manually.
"""
def __init__(self, file: str=None): # noqa: E501
"""DatotekaVConlluAsyncOcrBody - a model defined in Swagger
:param file: The file of this DatotekaVConlluAsyncOcrBody. # noqa: E501
:type file: str
"""
self.swagger_types = {
'file': str
}
self.attribute_map = {
'file': 'file'
}
self._file = file
@classmethod
def from_dict(cls, dikt) -> 'DatotekaVConlluAsyncOcrBody':
"""Returns the dict as a model
:param dikt: A dict.
:type: dict
:return: The datotekaVConlluAsync_ocr_body of this DatotekaVConlluAsyncOcrBody. # noqa: E501
:rtype: DatotekaVConlluAsyncOcrBody
"""
return util.deserialize_model(dikt, cls)
@property
def file(self) -> str:
"""Gets the file of this DatotekaVConlluAsyncOcrBody.
:return: The file of this DatotekaVConlluAsyncOcrBody.
:rtype: str
"""
return self._file
@file.setter
def file(self, file: str):
"""Sets the file of this DatotekaVConlluAsyncOcrBody.
:param file: The file of this DatotekaVConlluAsyncOcrBody.
:type file: str
"""
if file is None:
raise ValueError("Invalid value for `file`, must not be `None`") # noqa: E501
self._file = file
@@ -9,15 +9,15 @@ from swagger_server.models.base_model_ import Model
from swagger_server import util
class DatotekaVBesediloBody(Model):
class DatotekaVConlluSyncBody(Model):
"""NOTE: This class is auto generated by the swagger code generator program.
Do not edit the class manually.
"""
def __init__(self, file: str=None): # noqa: E501
"""DatotekaVBesediloBody - a model defined in Swagger
"""DatotekaVConlluSyncBody - a model defined in Swagger
:param file: The file of this DatotekaVBesediloBody. # noqa: E501
:param file: The file of this DatotekaVConlluSyncBody. # noqa: E501
:type file: str
"""
self.swagger_types = {
@@ -30,32 +30,32 @@ class DatotekaVBesediloBody(Model):
self._file = file
@classmethod
def from_dict(cls, dikt) -> 'DatotekaVBesediloBody':
def from_dict(cls, dikt) -> 'DatotekaVConlluSyncBody':
"""Returns the dict as a model
:param dikt: A dict.
:type: dict
:return: The datotekaVBesedilo_body of this DatotekaVBesediloBody. # noqa: E501
:rtype: DatotekaVBesediloBody
:return: The datotekaVConlluSync_body of this DatotekaVConlluSyncBody. # noqa: E501
:rtype: DatotekaVConlluSyncBody
"""
return util.deserialize_model(dikt, cls)
@property
def file(self) -> str:
"""Gets the file of this DatotekaVBesediloBody.
"""Gets the file of this DatotekaVConlluSyncBody.
:return: The file of this DatotekaVBesediloBody.
:return: The file of this DatotekaVConlluSyncBody.
:rtype: str
"""
return self._file
@file.setter
def file(self, file: str):
"""Sets the file of this DatotekaVBesediloBody.
"""Sets the file of this DatotekaVConlluSyncBody.
:param file: The file of this DatotekaVBesediloBody.
:param file: The file of this DatotekaVConlluSyncBody.
:type file: str
"""
if file is None:
@@ -0,0 +1,64 @@
# coding: utf-8
from __future__ import absolute_import
from datetime import date, datetime # noqa: F401
from typing import List, Dict # noqa: F401
from swagger_server.models.base_model_ import Model
from swagger_server import util
class DatotekaVConlluSyncOcrBody(Model):
"""NOTE: This class is auto generated by the swagger code generator program.
Do not edit the class manually.
"""
def __init__(self, file: str=None): # noqa: E501
"""DatotekaVConlluSyncOcrBody - a model defined in Swagger
:param file: The file of this DatotekaVConlluSyncOcrBody. # noqa: E501
:type file: str
"""
self.swagger_types = {
'file': str
}
self.attribute_map = {
'file': 'file'
}
self._file = file
@classmethod
def from_dict(cls, dikt) -> 'DatotekaVConlluSyncOcrBody':
"""Returns the dict as a model
:param dikt: A dict.
:type: dict
:return: The datotekaVConlluSync_ocr_body of this DatotekaVConlluSyncOcrBody. # noqa: E501
:rtype: DatotekaVConlluSyncOcrBody
"""
return util.deserialize_model(dikt, cls)
@property
def file(self) -> str:
"""Gets the file of this DatotekaVConlluSyncOcrBody.
:return: The file of this DatotekaVConlluSyncOcrBody.
:rtype: str
"""
return self._file
@file.setter
def file(self, file: str):
"""Sets the file of this DatotekaVConlluSyncOcrBody.
:param file: The file of this DatotekaVConlluSyncOcrBody.
:type file: str
"""
if file is None:
raise ValueError("Invalid value for `file`, must not be `None`") # noqa: E501
self._file = file
@@ -0,0 +1,88 @@
# coding: utf-8
from __future__ import absolute_import
from datetime import date, datetime # noqa: F401
from typing import List, Dict # noqa: F401
from swagger_server.models.base_model_ import Model
from swagger_server import util
class IzlusciAsyncBody(Model):
"""NOTE: This class is auto generated by the swagger code generator program.
Do not edit the class manually.
"""
def __init__(self, conllus: List[str]=None, prepovedane_besede: List[str]=None): # noqa: E501
"""IzlusciAsyncBody - a model defined in Swagger
:param conllus: The conllus of this IzlusciAsyncBody. # noqa: E501
:type conllus: List[str]
:param prepovedane_besede: The prepovedane_besede of this IzlusciAsyncBody. # noqa: E501
:type prepovedane_besede: List[str]
"""
self.swagger_types = {
'conllus': List[str],
'prepovedane_besede': List[str]
}
self.attribute_map = {
'conllus': 'conllus',
'prepovedane_besede': 'prepovedaneBesede'
}
self._conllus = conllus
self._prepovedane_besede = prepovedane_besede
@classmethod
def from_dict(cls, dikt) -> 'IzlusciAsyncBody':
"""Returns the dict as a model
:param dikt: A dict.
:type: dict
:return: The izlusciAsync_body of this IzlusciAsyncBody. # noqa: E501
:rtype: IzlusciAsyncBody
"""
return util.deserialize_model(dikt, cls)
@property
def conllus(self) -> List[str]:
"""Gets the conllus of this IzlusciAsyncBody.
:return: The conllus of this IzlusciAsyncBody.
:rtype: List[str]
"""
return self._conllus
@conllus.setter
def conllus(self, conllus: List[str]):
"""Sets the conllus of this IzlusciAsyncBody.
:param conllus: The conllus of this IzlusciAsyncBody.
:type conllus: List[str]
"""
self._conllus = conllus
@property
def prepovedane_besede(self) -> List[str]:
"""Gets the prepovedane_besede of this IzlusciAsyncBody.
:return: The prepovedane_besede of this IzlusciAsyncBody.
:rtype: List[str]
"""
return self._prepovedane_besede
@prepovedane_besede.setter
def prepovedane_besede(self, prepovedane_besede: List[str]):
"""Sets the prepovedane_besede of this IzlusciAsyncBody.
:param prepovedane_besede: The prepovedane_besede of this IzlusciAsyncBody.
:type prepovedane_besede: List[str]
"""
self._prepovedane_besede = prepovedane_besede
@@ -9,17 +9,17 @@ from swagger_server.models.base_model_ import Model
from swagger_server import util
class IzlusciBody(Model):
class IzlusciSyncBody(Model):
"""NOTE: This class is auto generated by the swagger code generator program.
Do not edit the class manually.
"""
def __init__(self, conllus: List[str]=None, prepovedane_besede: List[str]=None): # noqa: E501
"""IzlusciBody - a model defined in Swagger
"""IzlusciSyncBody - a model defined in Swagger
:param conllus: The conllus of this IzlusciBody. # noqa: E501
:param conllus: The conllus of this IzlusciSyncBody. # noqa: E501
:type conllus: List[str]
:param prepovedane_besede: The prepovedane_besede of this IzlusciBody. # noqa: E501
:param prepovedane_besede: The prepovedane_besede of this IzlusciSyncBody. # noqa: E501
:type prepovedane_besede: List[str]
"""
self.swagger_types = {
@@ -35,32 +35,32 @@ class IzlusciBody(Model):
self._prepovedane_besede = prepovedane_besede
@classmethod
def from_dict(cls, dikt) -> 'IzlusciBody':
def from_dict(cls, dikt) -> 'IzlusciSyncBody':
"""Returns the dict as a model
:param dikt: A dict.
:type: dict
:return: The izlusci_body of this IzlusciBody. # noqa: E501
:rtype: IzlusciBody
:return: The izlusciSync_body of this IzlusciSyncBody. # noqa: E501
:rtype: IzlusciSyncBody
"""
return util.deserialize_model(dikt, cls)
@property
def conllus(self) -> List[str]:
"""Gets the conllus of this IzlusciBody.
"""Gets the conllus of this IzlusciSyncBody.
:return: The conllus of this IzlusciBody.
:return: The conllus of this IzlusciSyncBody.
:rtype: List[str]
"""
return self._conllus
@conllus.setter
def conllus(self, conllus: List[str]):
"""Sets the conllus of this IzlusciBody.
"""Sets the conllus of this IzlusciSyncBody.
:param conllus: The conllus of this IzlusciBody.
:param conllus: The conllus of this IzlusciSyncBody.
:type conllus: List[str]
"""
@@ -68,20 +68,20 @@ class IzlusciBody(Model):
@property
def prepovedane_besede(self) -> List[str]:
"""Gets the prepovedane_besede of this IzlusciBody.
"""Gets the prepovedane_besede of this IzlusciSyncBody.
:return: The prepovedane_besede of this IzlusciBody.
:return: The prepovedane_besede of this IzlusciSyncBody.
:rtype: List[str]
"""
return self._prepovedane_besede
@prepovedane_besede.setter
def prepovedane_besede(self, prepovedane_besede: List[str]):
"""Sets the prepovedane_besede of this IzlusciBody.
"""Sets the prepovedane_besede of this IzlusciSyncBody.
:param prepovedane_besede: The prepovedane_besede of this IzlusciBody.
:param prepovedane_besede: The prepovedane_besede of this IzlusciSyncBody.
:type prepovedane_besede: List[str]
"""
+172
View File
@@ -0,0 +1,172 @@
# coding: utf-8
from __future__ import absolute_import
from datetime import date, datetime # noqa: F401
from typing import List, Dict # noqa: F401
from swagger_server.models.base_model_ import Model
from swagger_server import util
class JobResponse(Model):
"""NOTE: This class is auto generated by the swagger code generator program.
Do not edit the class manually.
"""
def __init__(self, job_status: str=None, finished_on: datetime=None, started_on: datetime=None, created_on: datetime=None, job_result: str=None): # noqa: E501
"""JobResponse - a model defined in Swagger
:param job_status: The job_status of this JobResponse. # noqa: E501
:type job_status: str
:param finished_on: The finished_on of this JobResponse. # noqa: E501
:type finished_on: datetime
:param started_on: The started_on of this JobResponse. # noqa: E501
:type started_on: datetime
:param created_on: The created_on of this JobResponse. # noqa: E501
:type created_on: datetime
:param job_result: The job_result of this JobResponse. # noqa: E501
:type job_result: str
"""
self.swagger_types = {
'job_status': str,
'finished_on': datetime,
'started_on': datetime,
'created_on': datetime,
'job_result': str
}
self.attribute_map = {
'job_status': 'job_status',
'finished_on': 'finished_on',
'started_on': 'started_on',
'created_on': 'created_on',
'job_result': 'job_result'
}
self._job_status = job_status
self._finished_on = finished_on
self._started_on = started_on
self._created_on = created_on
self._job_result = job_result
@classmethod
def from_dict(cls, dikt) -> 'JobResponse':
"""Returns the dict as a model
:param dikt: A dict.
:type: dict
:return: The JobResponse of this JobResponse. # noqa: E501
:rtype: JobResponse
"""
return util.deserialize_model(dikt, cls)
@property
def job_status(self) -> str:
"""Gets the job_status of this JobResponse.
:return: The job_status of this JobResponse.
:rtype: str
"""
return self._job_status
@job_status.setter
def job_status(self, job_status: str):
"""Sets the job_status of this JobResponse.
:param job_status: The job_status of this JobResponse.
:type job_status: str
"""
allowed_values = ["waiting in que", "currently processing", "finished processing"] # noqa: E501
if job_status not in allowed_values:
raise ValueError(
"Invalid value for `job_status` ({0}), must be one of {1}"
.format(job_status, allowed_values)
)
self._job_status = job_status
@property
def finished_on(self) -> datetime:
"""Gets the finished_on of this JobResponse.
:return: The finished_on of this JobResponse.
:rtype: datetime
"""
return self._finished_on
@finished_on.setter
def finished_on(self, finished_on: datetime):
"""Sets the finished_on of this JobResponse.
:param finished_on: The finished_on of this JobResponse.
:type finished_on: datetime
"""
self._finished_on = finished_on
@property
def started_on(self) -> datetime:
"""Gets the started_on of this JobResponse.
:return: The started_on of this JobResponse.
:rtype: datetime
"""
return self._started_on
@started_on.setter
def started_on(self, started_on: datetime):
"""Sets the started_on of this JobResponse.
:param started_on: The started_on of this JobResponse.
:type started_on: datetime
"""
self._started_on = started_on
@property
def created_on(self) -> datetime:
"""Gets the created_on of this JobResponse.
:return: The created_on of this JobResponse.
:rtype: datetime
"""
return self._created_on
@created_on.setter
def created_on(self, created_on: datetime):
"""Sets the created_on of this JobResponse.
:param created_on: The created_on of this JobResponse.
:type created_on: datetime
"""
self._created_on = created_on
@property
def job_result(self) -> str:
"""Gets the job_result of this JobResponse.
:return: The job_result of this JobResponse.
:rtype: str
"""
return self._job_result
@job_result.setter
def job_result(self, job_result: str):
"""Sets the job_result of this JobResponse.
:param job_result: The job_result of this JobResponse.
:type job_result: str
"""
self._job_result = job_result
@@ -0,0 +1,62 @@
# coding: utf-8
from __future__ import absolute_import
from datetime import date, datetime # noqa: F401
from typing import List, Dict # noqa: F401
from swagger_server.models.base_model_ import Model
from swagger_server import util
class OznaciBesediloAsyncBody(Model):
"""NOTE: This class is auto generated by the swagger code generator program.
Do not edit the class manually.
"""
def __init__(self, besedilo: str=None): # noqa: E501
"""OznaciBesediloAsyncBody - a model defined in Swagger
:param besedilo: The besedilo of this OznaciBesediloAsyncBody. # noqa: E501
:type besedilo: str
"""
self.swagger_types = {
'besedilo': str
}
self.attribute_map = {
'besedilo': 'besedilo'
}
self._besedilo = besedilo
@classmethod
def from_dict(cls, dikt) -> 'OznaciBesediloAsyncBody':
"""Returns the dict as a model
:param dikt: A dict.
:type: dict
:return: The oznaciBesediloAsync_body of this OznaciBesediloAsyncBody. # noqa: E501
:rtype: OznaciBesediloAsyncBody
"""
return util.deserialize_model(dikt, cls)
@property
def besedilo(self) -> str:
"""Gets the besedilo of this OznaciBesediloAsyncBody.
:return: The besedilo of this OznaciBesediloAsyncBody.
:rtype: str
"""
return self._besedilo
@besedilo.setter
def besedilo(self, besedilo: str):
"""Sets the besedilo of this OznaciBesediloAsyncBody.
:param besedilo: The besedilo of this OznaciBesediloAsyncBody.
:type besedilo: str
"""
self._besedilo = besedilo
+90
View File
@@ -0,0 +1,90 @@
import pathlib
import werkzeug.datastructures
from peewee import *
from datetime import datetime
import os
from swagger_server.util import get_random_filename
from werkzeug.utils import secure_filename
LOCAL_PATH = "requets_db/dbs"
SERVER_PATH = "swagger_server/requets_db/dbs"
if not os.path.exists(LOCAL_PATH):
if os.path.exists('requets_db'):
os.makedirs(LOCAL_PATH, exist_ok=True)
elif os.path.exists('swagger_server/requets_db'):
os.makedirs(SERVER_PATH, exist_ok=True)
DB = f'{LOCAL_PATH}/jobs.db'
if not os.path.exists(LOCAL_PATH):
DB = f'{SERVER_PATH}/jobs.db'
db = SqliteDatabase(DB, pragmas={
# 'journal_mode': 'wal',
'cache_size': -1 * 128 * 1024, # 128MB
'foreign_keys': 1
})
class BaseModel(Model):
class Meta:
database = db
class Job(BaseModel):
id = AutoField(index=True)
job_type = IntegerField()
job_input = TextField(index=True, null=True)
job_output = TextField(null=True)
created_on = DateTimeField(default=datetime.utcnow)
finished_on = DateTimeField(null=True)
started_on = DateTimeField(null=True)
input_size = IntegerField()
input_file = TextField(index=True, null=True)
db.drop_tables([Job]) # TODO: After pushing this, comment it and push again
db.create_tables([Job])
class JobManager:
@staticmethod
def create_job(job_type, job_input) -> Tuple(Job, bool):
"""
:param: job_type
:possibilities:
# 1 = pretvori datoteko v besedilo, 2 = oznaci besedilo, 12 = oboje
# 3 = pretvori dat v besedilo OCR, 2 = oznaci besedilo, 32 = oboje
# 4 = izlusci async
:return: Job object, Did already exist boolean
"""
try:
if job_type in [2, 4]:
job, is_new = Job.get_or_create(job_type=job_type, job_input=job_input, input_size=len(job_input))
elif job_type in [1, 3, 12, 32]:
tmp_file = ""
while True:
# just in case a VERY rare chance of a same generate name happens
tmp_file = "tmp/" + secure_filename(get_random_filename() + "_" + job_input.filename)
if not os.path.exists(tmp_file):
break
pathlib.Path('tmp').mkdir(exist_ok=True)
job_input: werkzeug.datastructures.FileStorage
job_input.save(tmp_file)
job, is_new = Job.get_or_create(job_type=job_type, input_file=tmp_file, input_size=-1)
return job, is_new
except Exception as e:
print(f'Exception at creating a job: {e}')
return None, False
# try:
# job = Job.get_or_none(Job.job_input == job_input, Job.job_type == job_type)
# if job:
# return job, True
# job = Job.create(job_type=job_type, job_input=job_input, input_size=len(job_input))
# return job, False
# except Exception as e:
# print(f'Exception at creating a job: {e}')
# return None, False
+350 -66
View File
@@ -6,18 +6,64 @@ servers:
- url: http://localhost:8089
description: Generated server url
paths:
/oznaciBesedilo:
/job/{job_id}:
get:
tags:
- jobs
summary: Vrne status
operationId: get_job_status
parameters:
- name: job_id
in: path
required: true
style: simple
explode: false
schema:
type: integer
format: int64
responses:
"200":
description: OK
content:
application/json:
schema:
$ref: '#/components/schemas/JobResponse'
x-openapi-router-controller: swagger_server.controllers.jobs_controller
delete:
tags:
- jobs
summary: Izbriše job
operationId: delete_job
parameters:
- name: job_id
in: path
required: true
style: simple
explode: false
schema:
type: integer
format: int64
responses:
"200":
description: OK
content:
'*/*':
schema:
type: string
x-content-type: '*/*'
x-openapi-router-controller: swagger_server.controllers.jobs_controller
/oznaciBesediloAsync:
post:
tags:
- marktext
summary: Označi besedilo s classlo/stanzo z uporabo slovenskih modelov ter vrne
conll-u format
- marktext-async
summary: Označi surovo (angl. raw) besedilo s classlo/stanzo z uporabo slovenskih
modelov ter vrne conll-u format
operationId: get_text
requestBody:
content:
application/json:
schema:
type: string
$ref: '#/components/schemas/oznaciBesediloAsync_body'
required: true
responses:
"200":
@@ -27,18 +73,101 @@ paths:
schema:
type: string
x-content-type: '*/*'
x-openapi-router-controller: swagger_server.controllers.marktext_controller
/izlusci:
x-openapi-router-controller: swagger_server.controllers.marktext_async_controller
/datotekaVBesediloAsync:
post:
tags:
- marktext-async
summary: "Pretvori datoteko v besedilo, vrača tekst"
operationId: get_text_from_doc_async
requestBody:
content:
multipart/form-data:
schema:
$ref: '#/components/schemas/datotekaVBesediloAsync_body'
responses:
"200":
description: OK
content:
'*/*':
schema:
type: string
x-content-type: '*/*'
x-openapi-router-controller: swagger_server.controllers.marktext_async_controller
/datotekaVConlluAsync:
post:
tags:
- marktext-async
summary: Pretvori datoteko v besedilo in označi s classlo/stanzo z uporabo slovenskih
modelov ter vrne conll-u format
operationId: get_conllu_from_file_async
requestBody:
content:
multipart/form-data:
schema:
$ref: '#/components/schemas/datotekaVConlluAsync_body'
responses:
"200":
description: OK
content:
'*/*':
schema:
type: string
x-content-type: '*/*'
x-openapi-router-controller: swagger_server.controllers.marktext_async_controller
/datotekaVConlluAsync/ocr:
post:
tags:
- marktext-async
summary: Pretvori datoteko v besedilo in označi s classlo/stanzo z uporabo slovenskih
modelov ter vrne conll-u format
operationId: get_conllu_from_file_ocr_async
requestBody:
content:
multipart/form-data:
schema:
$ref: '#/components/schemas/datotekaVConlluAsync_ocr_body'
responses:
"200":
description: OK
content:
'*/*':
schema:
type: string
x-content-type: '*/*'
x-openapi-router-controller: swagger_server.controllers.marktext_async_controller
/datotekaVBesediloAsync/ocr:
post:
tags:
- marktext-async
summary: "Pretvori datoteko v besedilo s pomočjo ocr razpoznavanja, vrača tekst"
operationId: get_text_from_file_ocr_async
requestBody:
content:
multipart/form-data:
schema:
$ref: '#/components/schemas/datotekaVBesediloAsync_ocr_body'
responses:
"200":
description: OK
content:
'*/*':
schema:
type: string
x-content-type: '*/*'
x-openapi-router-controller: swagger_server.controllers.marktext_async_controller
/izlusciSync:
post:
tags:
- extract
summary: Izlusci terminološke kandidate iz seznama besedil v conllu obliki
operationId: get_candidates
summary: "Izlusci terminološke kandidate iz seznama besedil v conllu obliki\
\ [sihrono, rezultat v sami zahtevi]"
operationId: get_candidates_sync
requestBody:
content:
application/json:
schema:
$ref: '#/components/schemas/izlusci_body'
$ref: '#/components/schemas/izlusciSync_body'
required: true
responses:
"200":
@@ -51,10 +180,52 @@ paths:
$ref: '#/components/schemas/TerminoloskiKandidat'
x-content-type: '*/*'
x-openapi-router-controller: swagger_server.controllers.extract_controller
/datotekaVBesedilo/ocr:
/izlusciAsync:
post:
tags:
- doc-2text
- extract
summary: "Izlusci terminološke kandidate iz seznama besedil v conllu obliki\
\ [asinhrono, ustvari novi job]"
operationId: get_candidates_async
requestBody:
content:
application/json:
schema:
$ref: '#/components/schemas/izlusciAsync_body'
required: true
responses:
"200":
description: OK
content:
'*/*':
schema:
type: string
x-content-type: '*/*'
x-openapi-router-controller: swagger_server.controllers.extract_controller
/datotekaVBesediloSync:
post:
tags:
- marktext-sync
summary: "Pretvori datoteko formata pdf, doc, docx, ppt, xls,... vrača besedilo"
operationId: datoteka_v_besedilo_sync_post
requestBody:
content:
multipart/form-data:
schema:
$ref: '#/components/schemas/datotekaVBesediloSync_body'
responses:
"200":
description: OK
content:
'*/*':
schema:
type: string
x-content-type: '*/*'
x-openapi-router-controller: swagger_server.controllers.marktext_sync_controller
/datotekaVBesediloSync/ocr:
post:
tags:
- marktext-sync
summary: "Pretvori datoteko formata pdf, doc, docx, ppt, xls,... v besedilo\
\ s pomočjo ocr razpoznavanja"
operationId: get_text_ocr
@@ -62,7 +233,7 @@ paths:
content:
multipart/form-data:
schema:
$ref: '#/components/schemas/datotekaVBesedilo_ocr_body'
$ref: '#/components/schemas/datotekaVBesediloSync_ocr_body'
responses:
"200":
description: OK
@@ -71,18 +242,18 @@ paths:
schema:
type: string
x-content-type: '*/*'
x-openapi-router-controller: swagger_server.controllers.doc2text_controller
/datotekaVBesedilo/:
x-openapi-router-controller: swagger_server.controllers.marktext_sync_controller
/datotekaVConlluSync:
post:
tags:
- doc-2text
summary: "Pretvori datoteko formata pdf, doc, docx, ppt, xls,... v besedilo"
operationId: datoteka_v_besedilo_post
- marktext-sync
summary: "Pretvori datoteko formata pdf, doc, docx, ppt, xls,... vrača conllu"
operationId: datoteka_v_besedilo_in_classla
requestBody:
content:
multipart/form-data:
schema:
$ref: '#/components/schemas/datotekaVBesedilo_body'
$ref: '#/components/schemas/datotekaVConlluSync_body'
responses:
"200":
description: OK
@@ -91,7 +262,28 @@ paths:
schema:
type: string
x-content-type: '*/*'
x-openapi-router-controller: swagger_server.controllers.doc2text_controller
x-openapi-router-controller: swagger_server.controllers.marktext_sync_controller
/datotekaVConlluSync/ocr:
post:
tags:
- marktext-sync
summary: "Pretvori datoteko formata pdf, doc, docx, ppt, xls,... v conllu s\
\ pomočjo ocr razpoznavanja"
operationId: get_conllu_ocr
requestBody:
content:
multipart/form-data:
schema:
$ref: '#/components/schemas/datotekaVConlluSync_ocr_body'
responses:
"200":
description: OK
content:
'*/*':
schema:
type: string
x-content-type: '*/*'
x-openapi-router-controller: swagger_server.controllers.marktext_sync_controller
/oss/steviloBesedilPoIskanju:
get:
tags:
@@ -101,7 +293,7 @@ paths:
parameters:
- name: leta
in: query
required: true
required: false
style: form
explode: true
schema:
@@ -111,25 +303,7 @@ paths:
format: int64
- name: vrste
in: query
required: true
style: form
explode: true
schema:
type: array
items:
type: string
- name: kljucnebesede
in: query
required: true
style: form
explode: true
schema:
type: array
items:
type: string
- name: cerifpodrocja
in: query
required: true
required: false
style: form
explode: true
schema:
@@ -137,6 +311,24 @@ paths:
items:
type: integer
format: int64
- name: kljucnebesede
in: query
required: false
style: form
explode: true
schema:
type: array
items:
type: string
- name: udk
in: query
required: false
style: form
explode: true
schema:
type: array
items:
type: string
responses:
"200":
description: OK
@@ -156,7 +348,7 @@ paths:
parameters:
- name: leta
in: query
required: true
required: false
style: form
explode: true
schema:
@@ -166,25 +358,7 @@ paths:
format: int64
- name: vrste
in: query
required: true
style: form
explode: true
schema:
type: array
items:
type: string
- name: kljucnebesede
in: query
required: true
style: form
explode: true
schema:
type: array
items:
type: string
- name: cerifpodrocja
in: query
required: true
required: false
style: form
explode: true
schema:
@@ -192,6 +366,24 @@ paths:
items:
type: integer
format: int64
- name: kljucnebesede
in: query
required: false
style: form
explode: true
schema:
type: array
items:
type: string
- name: udk
in: query
required: false
style: form
explode: true
schema:
type: array
items:
type: string
responses:
"200":
description: OK
@@ -270,7 +462,7 @@ paths:
summary: Vrne binarni zapis v originalnem formatu po id-ju datoteke
operationId: get_file
parameters:
- name: id
- name: file_id
in: query
required: true
style: form
@@ -353,7 +545,7 @@ paths:
summary: Vrne CoNNL-U po id-ju datoteke
operationId: get_conllu
parameters:
- name: id
- name: file_id
in: query
required: true
style: form
@@ -377,7 +569,7 @@ paths:
summary: Vrne besedilo po id-ju datoteke
operationId: oss_besedilo_po_id_get
parameters:
- name: id
- name: file_id
in: query
required: true
style: form
@@ -485,7 +677,72 @@ components:
kanonicnaoblika: kanonicnaoblika
nosilnautez: 0.8008282
kandidat: kandidat
izlusci_body:
JobResponse:
required:
- finished_job
type: object
properties:
job_status:
type: string
enum:
- waiting in que
- currently processing
- finished processing
finished_on:
type: string
format: date-time
started_on:
type: string
format: date-time
created_on:
type: string
format: date-time
job_result:
type: string
example:
job_status: waiting in que
started_on: 2000-01-23T04:56:07.000+00:00
created_on: 2000-01-23T04:56:07.000+00:00
finished_on: 2000-01-23T04:56:07.000+00:00
job_result: job_result
oznaciBesediloAsync_body:
type: object
properties:
besedilo:
type: string
datotekaVBesediloAsync_body:
required:
- file
type: object
properties:
file:
type: string
format: binary
datotekaVConlluAsync_body:
required:
- file
type: object
properties:
file:
type: string
format: binary
datotekaVConlluAsync_ocr_body:
required:
- file
type: object
properties:
file:
type: string
format: binary
datotekaVBesediloAsync_ocr_body:
required:
- file
type: object
properties:
file:
type: string
format: binary
izlusciSync_body:
type: object
properties:
conllus:
@@ -496,7 +753,18 @@ components:
type: array
items:
type: string
datotekaVBesedilo_ocr_body:
izlusciAsync_body:
type: object
properties:
conllus:
type: array
items:
type: string
prepovedaneBesede:
type: array
items:
type: string
datotekaVBesediloSync_body:
required:
- file
type: object
@@ -504,7 +772,23 @@ components:
file:
type: string
format: binary
datotekaVBesedilo_body:
datotekaVBesediloSync_ocr_body:
required:
- file
type: object
properties:
file:
type: string
format: binary
datotekaVConlluSync_body:
required:
- file
type: object
properties:
file:
type: string
format: binary
datotekaVConlluSync_ocr_body:
required:
- file
type: object
-16
View File
@@ -1,16 +0,0 @@
import logging
import connexion
from flask_testing import TestCase
from swagger_server.encoder import JSONEncoder
class BaseTestCase(TestCase):
def create_app(self):
logging.getLogger('connexion.operation').setLevel('ERROR')
app = connexion.App(__name__, specification_dir='../swagger/')
app.app.json_encoder = JSONEncoder
app.add_api('swagger.yaml')
return app.app
+16
View File
@@ -0,0 +1,16 @@
#!/usr/bin/env python3
import connexion
from swagger_server import encoder
def main():
app = connexion.App(__name__, specification_dir='./swagger/')
app.app.json_encoder = encoder.JSONEncoder
app.add_api('swagger.yaml', arguments={'title': 'OpenAPI definition'}, pythonic_params=True)
app.run(port=8080)
if __name__ == '__main__':
main()
+20
View File
@@ -0,0 +1,20 @@
from connexion.apps.flask_app import FlaskJSONEncoder
import six
from swagger_server.models.base_model_ import Model
class JSONEncoder(FlaskJSONEncoder):
include_nulls = False
def default(self, o):
if isinstance(o, Model):
dikt = {}
for attr, _ in six.iteritems(o.swagger_types):
value = getattr(o, attr)
if value is None and not self.include_nulls:
continue
attr = o.attribute_map[attr]
dikt[attr] = value
return dikt
return FlaskJSONEncoder.default(self, o)
@@ -1,45 +0,0 @@
# coding: utf-8
from __future__ import absolute_import
from flask import json
from six import BytesIO
from swagger_server.test import BaseTestCase
class TestDoc2textController(BaseTestCase):
"""Doc2textController integration test stubs"""
def test_datoteka_v_besedilo_post(self):
"""Test case for datoteka_v_besedilo_post
Pretvori datoteko formata pdf, doc, docx, ppt, xls,... v besedilo
"""
data = dict(file='file_example')
response = self.client.open(
'/datotekaVBesedilo/',
method='POST',
data=data,
content_type='multipart/form-data')
self.assert200(response,
'Response body is : ' + response.data.decode('utf-8'))
def test_get_text_ocr(self):
"""Test case for get_text_ocr
Pretvori datoteko formata pdf, doc, docx, ppt, xls,... v besedilo s pomočjo ocr razpoznavanja
"""
data = dict(file='file_example')
response = self.client.open(
'/datotekaVBesedilo/ocr',
method='POST',
data=data,
content_type='multipart/form-data')
self.assert200(response,
'Response body is : ' + response.data.decode('utf-8'))
if __name__ == '__main__':
import unittest
unittest.main()
@@ -1,33 +0,0 @@
# coding: utf-8
from __future__ import absolute_import
from flask import json
from six import BytesIO
from swagger_server.models.izlusci_body import IzlusciBody # noqa: E501
from swagger_server.models.terminoloski_kandidat import TerminoloskiKandidat # noqa: E501
from swagger_server.test import BaseTestCase
class TestExtractController(BaseTestCase):
"""ExtractController integration test stubs"""
def test_get_candidates(self):
"""Test case for get_candidates
Izlusci terminološke kandidate iz seznama besedil v conllu obliki
"""
body = IzlusciBody()
response = self.client.open(
'/izlusci',
method='POST',
data=json.dumps(body),
content_type='application/json')
self.assert200(response,
'Response body is : ' + response.data.decode('utf-8'))
if __name__ == '__main__':
import unittest
unittest.main()
@@ -1,31 +0,0 @@
# coding: utf-8
from __future__ import absolute_import
from flask import json
from six import BytesIO
from swagger_server.test import BaseTestCase
class TestMarktextController(BaseTestCase):
"""MarktextController integration test stubs"""
def test_get_text(self):
"""Test case for get_text
Označi besedilo s classlo/stanzo z uporabo slovenskih modelov ter vrne conll-u format
"""
body = 'body_example'
response = self.client.open(
'/oznaciBesedilo',
method='POST',
data=json.dumps(body),
content_type='application/json')
self.assert200(response,
'Response body is : ' + response.data.decode('utf-8'))
if __name__ == '__main__':
import unittest
unittest.main()
-137
View File
@@ -1,137 +0,0 @@
# coding: utf-8
from __future__ import absolute_import
from flask import json
from six import BytesIO
from swagger_server.models.terminoloski_kandidat import TerminoloskiKandidat # noqa: E501
from swagger_server.test import BaseTestCase
class TestOssController(BaseTestCase):
"""OssController integration test stubs"""
def test_get_conllu(self):
"""Test case for get_conllu
Vrne CoNNL-U po id-ju datoteke
"""
query_string = [('id', 789)]
response = self.client.open(
'/oss/conlluPoId',
method='GET',
query_string=query_string)
self.assert200(response,
'Response body is : ' + response.data.decode('utf-8'))
def test_get_conllus(self):
"""Test case for get_conllus
Vrne seznam CoNNL-U-jev glede na iskalne pogoje
"""
query_string = [('leta', 56),
('vrste', 'vrste_example'),
('kljucnebesede', 'kljucnebesede_example'),
('cerifpodrocja', 56)]
response = self.client.open(
'/oss/conlluPoIskanju',
method='GET',
query_string=query_string)
self.assert200(response,
'Response body is : ' + response.data.decode('utf-8'))
def test_get_extracted_words(self):
"""Test case for get_extracted_words
Vrne terminloške kandidate glede na
"""
query_string = [('leta', 56),
('vrste', 'vrste_example'),
('kljucnebesede', 'kljucnebesede_example'),
('cerifpodrocja', 56)]
response = self.client.open(
'/oss/izlusciPoIskanju',
method='GET',
query_string=query_string)
self.assert200(response,
'Response body is : ' + response.data.decode('utf-8'))
def test_get_file(self):
"""Test case for get_file
Vrne binarni zapis v originalnem formatu po id-ju datoteke
"""
query_string = [('id', 789)]
response = self.client.open(
'/oss/datotekaPoId',
method='GET',
query_string=query_string)
self.assert200(response,
'Response body is : ' + response.data.decode('utf-8'))
def test_get_files(self):
"""Test case for get_files
Vrne seznam binarnih zapisov v originalnem formatu glede na iskalne pogoje
"""
query_string = [('leta', 56),
('vrste', 'vrste_example'),
('kljucnebesede', 'kljucnebesede_example'),
('cerifpodrocja', 56)]
response = self.client.open(
'/oss/datotekePoIskanju',
method='GET',
query_string=query_string)
self.assert200(response,
'Response body is : ' + response.data.decode('utf-8'))
def test_get_number_texts(self):
"""Test case for get_number_texts
Vrne število besedil glede na iskalne pogoje
"""
query_string = [('leta', 56),
('vrste', 'vrste_example'),
('kljucnebesede', 'kljucnebesede_example'),
('cerifpodrocja', 56)]
response = self.client.open(
'/oss/steviloBesedilPoIskanju',
method='GET',
query_string=query_string)
self.assert200(response,
'Response body is : ' + response.data.decode('utf-8'))
def test_get_texts(self):
"""Test case for get_texts
Vrne seznam besedil glede na iskalne pogoje
"""
query_string = [('leta', 56),
('vrste', 'vrste_example'),
('kljucnebesede', 'kljucnebesede_example'),
('cerifpodrocja', 56)]
response = self.client.open(
'/oss/besedilaPoIskanju',
method='GET',
query_string=query_string)
self.assert200(response,
'Response body is : ' + response.data.decode('utf-8'))
def test_oss_besedilo_po_id_get(self):
"""Test case for oss_besedilo_po_id_get
Vrne besedilo po id-ju datoteke
"""
query_string = [('id', 789)]
response = self.client.open(
'/oss/besediloPoId',
method='GET',
query_string=query_string)
self.assert200(response,
'Response body is : ' + response.data.decode('utf-8'))
if __name__ == '__main__':
import unittest
unittest.main()
+32
View File
@@ -0,0 +1,32 @@
# coding: utf-8
import sys
if sys.version_info < (3, 7):
import typing
def is_generic(klass):
""" Determine whether klass is a generic class """
return type(klass) == typing.GenericMeta
def is_dict(klass):
""" Determine whether klass is a Dict """
return klass.__extra__ == dict
def is_list(klass):
""" Determine whether klass is a List """
return klass.__extra__ == list
else:
def is_generic(klass):
""" Determine whether klass is a generic class """
return hasattr(klass, '__origin__')
def is_dict(klass):
""" Determine whether klass is a Dict """
return klass.__origin__ == dict
def is_list(klass):
""" Determine whether klass is a List """
return klass.__origin__ == list
+142
View File
@@ -0,0 +1,142 @@
import datetime
import six
import typing
from swagger_server import type_util
def _deserialize(data, klass):
"""Deserializes dict, list, str into an object.
:param data: dict, list or str.
:param klass: class literal, or string of class name.
:return: object.
"""
if data is None:
return None
if klass in six.integer_types or klass in (float, str, bool, bytearray):
return _deserialize_primitive(data, klass)
elif klass == object:
return _deserialize_object(data)
elif klass == datetime.date:
return deserialize_date(data)
elif klass == datetime.datetime:
return deserialize_datetime(data)
elif type_util.is_generic(klass):
if type_util.is_list(klass):
return _deserialize_list(data, klass.__args__[0])
if type_util.is_dict(klass):
return _deserialize_dict(data, klass.__args__[1])
else:
return deserialize_model(data, klass)
def _deserialize_primitive(data, klass):
"""Deserializes to primitive type.
:param data: data to deserialize.
:param klass: class literal.
:return: int, long, float, str, bool.
:rtype: int | long | float | str | bool
"""
try:
value = klass(data)
except UnicodeEncodeError:
value = six.u(data)
except TypeError:
value = data
return value
def _deserialize_object(value):
"""Return an original value.
:return: object.
"""
return value
def deserialize_date(string):
"""Deserializes string to date.
:param string: str.
:type string: str
:return: date.
:rtype: date
"""
try:
from dateutil.parser import parse
return parse(string).date()
except ImportError:
return string
def deserialize_datetime(string):
"""Deserializes string to datetime.
The string should be in iso8601 datetime format.
:param string: str.
:type string: str
:return: datetime.
:rtype: datetime
"""
try:
from dateutil.parser import parse
return parse(string)
except ImportError:
return string
def deserialize_model(data, klass):
"""Deserializes list or dict to model.
:param data: dict, list.
:type data: dict | list
:param klass: class literal.
:return: model object.
"""
instance = klass()
if not instance.swagger_types:
return data
for attr, attr_type in six.iteritems(instance.swagger_types):
if data is not None \
and instance.attribute_map[attr] in data \
and isinstance(data, (list, dict)):
value = data[instance.attribute_map[attr]]
setattr(instance, attr, _deserialize(value, attr_type))
return instance
def _deserialize_list(data, boxed_type):
"""Deserializes a list and its elements.
:param data: list to deserialize.
:type data: list
:param boxed_type: class literal.
:return: deserialized list.
:rtype: list
"""
return [_deserialize(sub_data, boxed_type)
for sub_data in data]
def _deserialize_dict(data, boxed_type):
"""Deserializes a dict and its elements.
:param data: dict to deserialize.
:type data: dict
:param boxed_type: class literal.
:return: deserialized dict.
:rtype: dict
"""
return {k: _deserialize(v, boxed_type)
for k, v in six.iteritems(data)}
+73
View File
@@ -1,8 +1,18 @@
import codecs
import datetime
import os.path
import pathlib
import six
import typing
import werkzeug.datastructures
from werkzeug.utils import secure_filename
from swagger_server import type_util
import pandas as pd
import string
import random
def _deserialize(data, klass):
@@ -140,3 +150,66 @@ def _deserialize_dict(data, boxed_type):
"""
return {k: _deserialize(v, boxed_type)
for k, v in six.iteritems(data)}
def is_docker() -> bool:
# todo: better way of checking if we're on docker or if we're in the develoment enviroment
return not os.path.exists('.env')
def get_conllu_file_path_by_id(file_id):
r = f'classla_OS2022/conll/rsdo_doc-{file_id}.plainText.conllu'
if is_docker():
return f'/usr/src/app/{r}'
return f'../mnt/ssd/ds_ftp/{r}'
def get_original_file_path_by_id(file_id):
r = f'classla_OS2022/besedila/rsdo_doc-{file_id}.xml'
if is_docker():
return f'/usr/src/app/{r}'
return f'../mnt/ssd/ds_ftp/{r}'
def get_tei_file_path_by_id(file_id):
r = f'classla_OS2022/tei/rsdo_doc-{file_id}.plainText.tei.xml'
if is_docker():
return f'/usr/src/app/{r}'
return f'../mnt/ssd/ds_ftp/{r}'
def get_files_by_keywords(kljucnebesede):
ret = []
kljucnebesede = [k.lower() for k in kljucnebesede]
# Temporary solution until connection with mariadb is fixed
ngrams_path = "classla_OS2022/ngrams/" if is_docker() else "../mnt/ssd/ds_ftp/classla_OS2022/ngrams/"
print("Looping trough ngrams")
for path, dirs, files, in os.walk(ngrams_path):
for i, _file in enumerate(files[:100]):
if i % 500 == 0: print(f"{i}/{len(files)}")
file = f'{ngrams_path}{_file}'
data = pd.read_csv(file, sep='\t')
amount = len(data[data['ngram_len'] == 1 & data['gram_text'].str.lower().isin(kljucnebesede)])
# this should be 1
if amount >= 1:
ret.append(_file[9:][:-12])
return ret
def get_random_filename():
ts = str(int(datetime.datetime.now().timestamp()))
extra = ''.join(random.choices(string.ascii_letters + string.digits, k=8))
return f'{ts}_{extra}'
def create_random_file_in_tmp_folder(fill_content, extension=""):
pathlib.Path('tmp').mkdir(exist_ok=True)
tmp_file = ""
while True:
# just in case a VERY rare chance of a same generate name happens
tmp_file = "tmp/" + secure_filename(get_random_filename() + extension)
if not os.path.exists(tmp_file):
break
with codecs.open(tmp_file, 'w', 'utf-8') as f:
f.write(fill_content)
return tmp_file
View File
+47
View File
@@ -0,0 +1,47 @@
import classla
import time
from swagger_server import util
from pathlib import Path
import re
nlp_loaded = False
nlpSlo = classla.Pipeline('sl', processors='tokenize,ner,pos,lemma,depparse')
nlp_loaded = True
sent_extractor = re.compile(r"# sent_id = \d+\.\d+(.*?)\n\n", re.MULTILINE | re.DOTALL)
def raw_text_to_conllu(text):
try:
docall = nlpSlo(text)
docallconllu = docall.to_conll()
return docallconllu, 200
except Exception as e:
return e, 400
def multipla_conllus_to_one_from_file_ids(list_file_ids):
sent_cnt = 1
ret = "# newpar id = 1\n"
files = [f'{util.get_conllu_file_path_by_id(i)}' for i in list_file_ids]
for file in files:
txt = Path(file).read_text('utf-8')
matches = sent_extractor.finditer(txt)
for match in matches:
ret += f'# sent_id = 1.{sent_cnt}{match.group(1)}\n\n'
sent_cnt += 1
return ret
def multipla_conllus_to_one_from_conllus_arr(list_conllus):
sent_cnt = 1
ret = "# newpar id = 1\n"
for conllu in list_conllus:
conllu = conllu.replace('\r\n', '\n')
matches = sent_extractor.finditer(conllu)
for match in matches:
ret += f'# sent_id = 1.{sent_cnt}{match.group(1)}\n\n'
sent_cnt += 1
return ret
+225
View File
@@ -0,0 +1,225 @@
import mariadb
import os
import sys
import requests
import json
database_info = {
'database': os.getenv("MDB_DATABASE", "oss"),
'host': os.getenv("MDB_HOST", "localhost"),
'port': int(os.getenv("PORT", 3306)) ,
'user': os.getenv("MDB_USER", "root"),
'password': os.getenv("MDB_PASSWORD", "root"),
}
canonapi_endpoint = "http://canonizer:5000/rest_api/canonize"
cur = None
# Connect to MariaDB Platform
def get_files_by_udc(udc):
ret = []
try:
print(database_info)
conn = mariadb.connect(**database_info)
cur = conn.cursor()
where_in = ','.join(['%s'] * len(udc))
print(where_in)
sql = "select distinct xml_id from metadata_udc where udk IN (%s)" % (where_in)
print(sql)
cur.execute(sql,udc)
#cur.execute(f'SELECT COUNT(*) FROM os2022_ngrams')
ret = list(cur)
except mariadb.Error as e:
print(f"Error connecting to MariaDB Platform: {e}")
return ret
def vrni_oss_dokumente(leta, vrste, kljucnebesede, udk):
ret = []
try:
print(database_info)
conn = mariadb.connect(**database_info)
cur = conn.cursor()
sql = "select distinct document_id from metadata"
where=""
params=[]
if (udk):
where_in_udk = ','.join(['%s'] * len(udk))
where=" udk IN (%s) " % (where_in_udk)
params=udk
if (leta):
where_in_leta = ','.join(['%s'] * len(leta))
if (where):
where=where+ " AND "
where=where + " leto IN (%s) " % (where_in_leta)
params=params+leta
if (vrste):
if (where):
where=where+ " AND "
where_in_vrste = ','.join(['%s'] * len(vrste))
where=where + " tipologija IN (%s) " % (where_in_vrste)
params=params+vrste
if (kljucnebesede):
if (where):
where=where+ " AND "
where_in_kb = ','.join(['%s'] * len(kljucnebesede))
where=where + " kljucnabeseda IN (%s) " % (where_in_kb)
params=params+kljucnebesede
if(where):
sql=sql+" where " + where + ";"
print(sql)
print(params)
cur.execute(sql,params)
ret = list(cur)
except mariadb.Error as e:
print(f"Error connecting to MariaDB Platform: {e}")
return ret
def vrni_oss_terminoloske_kandidate(leta, vrste, kljucnebesede, udk):
ret = []
try:
print(database_info)
conn = mariadb.connect(**database_info)
cur = conn.cursor()
sql = "select distinct document_id from metadata"
where=""
params=[]
if (udk):
where_in_udk = ','.join(['%s'] * len(udk))
where=" udk IN (%s) " % (where_in_udk)
params=udk
if (leta):
where_in_leta = ','.join(['%s'] * len(leta))
if (where):
where=where+ " AND "
where=where + " leto IN (%s) " % (where_in_leta)
params=params+leta
if (vrste):
if (where):
where=where+ " AND "
where_in_vrste = ','.join(['%s'] * len(vrste))
where=where + " tipologija IN (%s) " % (where_in_vrste)
params=params+vrste
if (kljucnebesede):
if (where):
where=where+ " AND "
where_in_kb = ','.join(['%s'] * len(kljucnebesede))
where=where + " kljucnabeseda IN (%s) " % (where_in_kb)
params=params+kljucnebesede
if(where):
sql=sql+" where " + where
print(sql)
print(params)
sqltk=f"""Select ngram,upos,avg(tfidf) as tfidf, sum(tf) as tf from (
SELECT tf.ngram, tf.upos,(0.5+0.5*(tf.tf/d.maxtf))*log(152000/df.df)*(-1*log(1-((dff.df)/(1+df.df)))) as tfidf, tf.tf as tf
FROM ngrams_upos_tf tf, documents d,
(
Select ngram, upos, count(*) as df from ngrams_upos_tf TF
where document_id in
({sql})
group by TF.ngram, TF.upos
) dff, ngrams_upos_df df
where
tf.document_id=d.document_id and
df.ngram=tf.ngram AND df.upos=tf.upos and
dff.ngram=tf.ngram AND dff.upos=tf.upos
) X
group by ngram,upos
order by tfidf desc
limit 1000;"""
#
print (sqltk)
cur.execute(sqltk,params)
terms=cur.fetchall()
#ret = list(cur)
can = {'forms':[
ngram
for ngram in terms
]
}
res = requests.post(ATEapi_endpoint, json=can)
data = res.json().canonical_forms
ret = {'terminoloski_kandidati': [
{
'POSoznake': x.upos,
'kandidat': x.ngram, # more to bit lemma al terms?
'kanonicnaoblika': d,
'ranking': x.tfidf,
'podporneutezi': [
0.0, # ????????
0.0 # ??????
],
'pogostostpojavljanja': [tf, 0] # ???????
}
for d,x in zip(data,cur)
]}
except mariadb.Error as e:
print(f"Error connecting to MariaDB Platform: {e}")
return ret
# class BaseModel(Model):
# class Meta:
# database = db
#
#
# class os2022_ngrams(BaseModel):
# file_id = IntegerField()
# sent_id = FloatField()
# ngram_len = IntegerField()
# frequency_g_t = IntegerField()
# gram_text = TextField()
# lemma_text = TextField()
# xpos_text = TextField()
# upos_text = TextField()
#
# db.connect()
#class Ngrams_Manager:
#@staticmethod
#def get_by_file_id(file_id):
#try:
# cur.execute(f'SELECT * from os2022_ngrams WHERE file_id = {file_id}')
# cur.execute(f'SELECT COUNT(*) FROM os2022_ngrams')
# return list(cur)
# return 1
#except Exception as e:
#print(e, 'EXC')
#return 0
+117
View File
@@ -0,0 +1,117 @@
import os.path
import pytesseract
import requests
import docx
import xml.etree.ElementTree as ET
from PyPDF2 import PdfReader
from swagger_server.utils import cl_utils
import cv2
import numpy as np
import magic
import re
#to še mora v env
tika_server = "http://tika2:9999/tika"
# endpoint below to be used only for development purposes (don't need to run docker)
# tika_server = "http://rsdo.lhrs.feri.um.si:9998/tika"
def extract_text_prepResp(file, content_type=""):
content_type = file.content_type
if content_type is None:
content_type = magic.from_file(file.stream.name, mime=True)
content = ""
if tika_responding():
try:
response = requests.put(tika_server, data=file, headers={"Accept": "text/plain; charset=UTF-8"})
content = response.text
#preveri če je pretvorba uspešna
# original string
res = re.findall(r'\w+', content)
#preveri, če imamo vsaj 10 besed in če je povprečna dolžina >3 in < 12
#če to drži, idi v ocr
reslen=map(lambda n:len(n),res)
print(f"Število besed je {len(res)}")
if len(res)>0 :
avglen=sum(reslen)/len(res)
else:
avglen=0
print(f"Povprečna dolžina besede je {avglen}")
if(len(res)<10 or avglen<4 or avglen>11):
print("Besedilo je sumljivo, gremo v OCR in damo file na začetek!")
file.seek(0)
response = requests.put(tika_server, data=file, headers={"X-Tika-PDFOcrStrategy": "ocr_only", "X-Tika-OCRLanguage": "slv+eng",
"Accept": "text/plain; charset=UTF-8"})
content = response.text
#odstranim še vse prelome vrstic, ker imamo s tem probleme
content=' '.join(content.splitlines())
except:
content = "ERROR - something went wrong when reading file with tika"
#if content == "":
# if "openxmlformats-officedocument.wordprocessingml.document" in content_type:
# content = '\n'.join([p.text for p in docx.Document(file).paragraphs])
# elif "application/pdf" in content_type:
# reader = PdfReader(file)
# content = '\n'.join([p.extract_text() for p in reader.pages])
# content = content
# elif "text/xml" in content_type:
# root = ET.parse(file).getroot()
# plainText = root.findall('PlainText')
# if len(plainText) == 0:
# return "Didn't find anything in PlainText", 400
# content = '\n'.join([pt.text for pt in plainText])
# # elif "text/plain" in file.content_type:
# else:
# try:
# content = file.read().decode('utf-8')
# except:
# content = "ERROR - something went wrong when reading file with not-tika method!"
return content, 200
def ocr_text_prepResp(file):
content = ""
if tika_responding():
try:
response = requests.put(tika_server, data=file,
headers={"X-Tika-PDFOcrStrategy": "ocr_only", "X-Tika-OCRLanguage": "slv+eng",
"Accept": "text/plain; charset=UTF-8"})
content = response.text
except:
content = "ERROR - something went wrong when reading file with tika (OCR)"
if content == "":
try:
win_p = "C:/Program Files/Tesseract-OCR/tesseract.exe"
if os.path.exists(win_p):
pytesseract.pytesseract.tesseract_cmd = win_p
# convert string data to numpy array
file_bytes = np.fromstring(file.read(), np.uint8)
# convert numpy array to image
img = cv2.imdecode(file_bytes, cv2.IMREAD_COLOR)
conf = '-l eng+slv'
content = pytesseract.image_to_string(img, config=conf)
except:
content = "ERROR - something went wrong when reading file with not-tika method! (OCR)"
return content, 200
def tika_responding():
try:
ret = requests.get(tika_server)
return ret.status_code == 200
except:
return False