This commit is contained in:
parent
17927b472d
commit
d807bc6b00
@ -6,6 +6,7 @@ from minio.error import NoSuchKey
|
|||||||
from schemas import AIModelSchema, DefaultSchema, InfoSchema
|
from schemas import AIModelSchema, DefaultSchema, InfoSchema
|
||||||
from marshmallow.exceptions import ValidationError
|
from marshmallow.exceptions import ValidationError
|
||||||
from utils import multipart_required, storage, ensure_buckets
|
from utils import multipart_required, storage, ensure_buckets
|
||||||
|
import opentracing
|
||||||
|
|
||||||
|
|
||||||
class CNNView(FlaskView):
|
class CNNView(FlaskView):
|
||||||
@ -21,88 +22,155 @@ class CNNView(FlaskView):
|
|||||||
def post(self):
|
def post(self):
|
||||||
|
|
||||||
# get important data from the request
|
# get important data from the request
|
||||||
try:
|
with opentracing.tracer.start_active_span('parseAndValidate'):
|
||||||
info = self.info_schema.loads(request.form.get('info'))
|
try:
|
||||||
except ValidationError as e:
|
info = self.info_schema.loads(request.form.get('info'))
|
||||||
abort(400, str(e))
|
except ValidationError as e:
|
||||||
|
return abort(400, str(e))
|
||||||
|
|
||||||
# check for conflict
|
# check for conflict
|
||||||
m = AIModel.query.filter_by(id=info['id']).first()
|
m = AIModel.query.filter_by(id=info['id']).first()
|
||||||
if m:
|
if m:
|
||||||
abort(409)
|
return abort(409)
|
||||||
|
|
||||||
# get and validate file
|
# get and validate file
|
||||||
model_file = request.files['modelFile']
|
model_file = request.files['modelFile']
|
||||||
|
|
||||||
if model_file.content_length <= 0:
|
if model_file.content_length <= 0:
|
||||||
abort(411, f"Content length for modelFile is not a positive integer or missing.")
|
return abort(411, f"Content length for modelFile is not a positive integer or missing.")
|
||||||
|
|
||||||
weights_file = request.files['weightsFile']
|
weights_file = request.files['weightsFile']
|
||||||
|
|
||||||
if weights_file.content_length <= 0:
|
if weights_file.content_length <= 0:
|
||||||
abort(411, f"Content length for weightsFile is not a positive integer or missing.")
|
return abort(411, f"Content length for weightsFile is not a positive integer or missing.")
|
||||||
|
|
||||||
# create bucket if necessary
|
# create bucket if necessary
|
||||||
ensure_buckets()
|
with opentracing.tracer.start_active_span('ensureBuckets'):
|
||||||
|
ensure_buckets()
|
||||||
|
|
||||||
# Create the entry in the db
|
# Create the entry in the db
|
||||||
m = AIModel(id=info['id'], type=AIModelType.cnn, target_class_name=info['target_class_name'])
|
with opentracing.tracer.start_active_span('sqlalchemy.create'):
|
||||||
|
m = AIModel(id=info['id'], type=AIModelType.cnn, target_class_name=info['target_class_name'])
|
||||||
|
db.session.add(m)
|
||||||
|
|
||||||
# Put files into MinIO
|
# Put files into MinIO
|
||||||
storage.connection.put_object(
|
with opentracing.tracer.start_active_span('putObjectsInMinio'):
|
||||||
current_app.config['MINIO_CNN_BUCKET_NAME'],
|
with opentracing.tracer.start_active_span(
|
||||||
self.MODEL_DIRECTORY + str(m.id),
|
'minio.putObject',
|
||||||
model_file,
|
tags={
|
||||||
model_file.content_length,
|
"bucket": current_app.config['MINIO_CNN_BUCKET_NAME'],
|
||||||
content_type=model_file.content_type
|
"object_name": self.MODEL_DIRECTORY + str(m.id),
|
||||||
)
|
"length": model_file.content_length,
|
||||||
|
"component": "model"
|
||||||
|
}
|
||||||
|
):
|
||||||
|
storage.connection.put_object(
|
||||||
|
current_app.config['MINIO_CNN_BUCKET_NAME'],
|
||||||
|
self.MODEL_DIRECTORY + str(m.id),
|
||||||
|
model_file,
|
||||||
|
model_file.content_length,
|
||||||
|
content_type=model_file.content_type
|
||||||
|
)
|
||||||
|
with opentracing.tracer.start_active_span(
|
||||||
|
'minio.putObject',
|
||||||
|
tags={
|
||||||
|
"bucket": current_app.config['MINIO_CNN_BUCKET_NAME'],
|
||||||
|
"object_name": self.WEIGHTS_DIRECTORY + str(m.id),
|
||||||
|
"length": model_file.content_type,
|
||||||
|
"component": "weights"
|
||||||
|
}
|
||||||
|
):
|
||||||
|
storage.connection.put_object(
|
||||||
|
current_app.config['MINIO_CNN_BUCKET_NAME'],
|
||||||
|
self.WEIGHTS_DIRECTORY + str(m.id),
|
||||||
|
weights_file,
|
||||||
|
weights_file.content_length,
|
||||||
|
content_type=weights_file.content_type
|
||||||
|
)
|
||||||
|
|
||||||
storage.connection.put_object(
|
with opentracing.tracer.start_active_span('sqlalchemy.commit'):
|
||||||
current_app.config['MINIO_CNN_BUCKET_NAME'],
|
db.session.commit()
|
||||||
self.WEIGHTS_DIRECTORY + str(m.id),
|
|
||||||
weights_file,
|
|
||||||
weights_file.content_length,
|
|
||||||
content_type=weights_file.content_type
|
|
||||||
)
|
|
||||||
|
|
||||||
db.session.add(m)
|
|
||||||
db.session.commit()
|
|
||||||
|
|
||||||
return jsonify(self.aimodel_schema.dump(m)), 200
|
return jsonify(self.aimodel_schema.dump(m)), 200
|
||||||
|
|
||||||
def delete(self, id_: str):
|
def delete(self, id_: str):
|
||||||
|
|
||||||
if id_ == "$default":
|
with opentracing.tracer.start_active_span(
|
||||||
default = Default.query.filter_by(type=AIModelType.cnn).first_or_404()
|
'sqlalchemy.select',
|
||||||
m = default.aimodel
|
tags={"aimodel_type": AIModelType.cnn, "id": id_}
|
||||||
else:
|
):
|
||||||
m = AIModel.query.filter_by(type=AIModelType.cnn, id=id_).first_or_404()
|
if id_ == "$default":
|
||||||
|
default = Default.query.filter_by(type=AIModelType.cnn).first_or_404()
|
||||||
|
m = default.aimodel
|
||||||
|
else:
|
||||||
|
m = AIModel.query.filter_by(type=AIModelType.cnn, id=id_).first_or_404()
|
||||||
|
|
||||||
storage.connection.remove_object(current_app.config['MINIO_CNN_BUCKET_NAME'], self.WEIGHTS_DIRECTORY + str(m.id))
|
with opentracing.tracer.start_active_span('removeFromMinio'):
|
||||||
storage.connection.remove_object(current_app.config['MINIO_CNN_BUCKET_NAME'], self.MODEL_DIRECTORY + str(m.id))
|
with opentracing.tracer.start_active_span(
|
||||||
|
'minio.removeObject',
|
||||||
|
tags={
|
||||||
|
"bucket": current_app.config['MINIO_CNN_BUCKET_NAME'],
|
||||||
|
"object_name": self.WEIGHTS_DIRECTORY + str(m.id),
|
||||||
|
"component": "weights"
|
||||||
|
}
|
||||||
|
):
|
||||||
|
storage.connection.remove_object(current_app.config['MINIO_CNN_BUCKET_NAME'],
|
||||||
|
self.WEIGHTS_DIRECTORY + str(m.id))
|
||||||
|
|
||||||
db.session.delete(m)
|
with opentracing.tracer.start_active_span(
|
||||||
db.session.commit()
|
'minio.removeObject',
|
||||||
|
tags={
|
||||||
|
"bucket": current_app.config['MINIO_CNN_BUCKET_NAME'],
|
||||||
|
"object_name": self.MODEL_DIRECTORY + str(m.id),
|
||||||
|
"component": "model"
|
||||||
|
}
|
||||||
|
):
|
||||||
|
storage.connection.remove_object(current_app.config['MINIO_CNN_BUCKET_NAME'],
|
||||||
|
self.MODEL_DIRECTORY + str(m.id))
|
||||||
|
|
||||||
|
with opentracing.tracer.start_active_span(
|
||||||
|
'sqlalchemy.delete',
|
||||||
|
tags={"aimodel_type": AIModelType.cnn, "id": id_}
|
||||||
|
):
|
||||||
|
db.session.delete(m)
|
||||||
|
|
||||||
|
with opentracing.tracer.start_active_span('sqlalchemy.commit'):
|
||||||
|
db.session.commit()
|
||||||
|
|
||||||
return '', 204
|
return '', 204
|
||||||
|
|
||||||
@route('<id_>/file')
|
@route('<id_>/file')
|
||||||
def get_file(self, id_: str):
|
def get_file(self, id_: str):
|
||||||
|
|
||||||
if id_ == "$default":
|
with opentracing.tracer.start_active_span(
|
||||||
default = Default.query.filter_by(type=AIModelType.cnn).first_or_404()
|
'sqlalchemy.select',
|
||||||
m = default.aimodel
|
tags={"aimodel_type": AIModelType.cnn, "id": id_}
|
||||||
else:
|
):
|
||||||
m = AIModel.query.filter_by(type=AIModelType.cnn, id=id_).first_or_404()
|
if id_ == "$default":
|
||||||
|
default = Default.query.filter_by(type=AIModelType.cnn).first_or_404()
|
||||||
|
m = default.aimodel
|
||||||
|
else:
|
||||||
|
m = AIModel.query.filter_by(type=AIModelType.cnn, id=id_).first_or_404()
|
||||||
|
|
||||||
if "weights" in request.args:
|
if "weights" in request.args:
|
||||||
path = self.WEIGHTS_DIRECTORY + str(m.id)
|
path = self.WEIGHTS_DIRECTORY + str(m.id)
|
||||||
|
component = "weights"
|
||||||
else:
|
else:
|
||||||
path = self.MODEL_DIRECTORY + str(m.id)
|
path = self.MODEL_DIRECTORY + str(m.id)
|
||||||
|
component = "model"
|
||||||
|
|
||||||
try:
|
with opentracing.tracer.start_active_span(
|
||||||
data = storage.connection.get_object(current_app.config['MINIO_CNN_BUCKET_NAME'], path)
|
'minio.getObject',
|
||||||
except NoSuchKey:
|
tags={
|
||||||
abort(500, "The ID is stored in the database but not int the Object Store")
|
"bucket": current_app.config['MINIO_CNN_BUCKET_NAME'],
|
||||||
|
"object_name": path,
|
||||||
|
"component": component
|
||||||
|
}
|
||||||
|
):
|
||||||
|
# Note: this only initiates the download, the file download itself is streamed
|
||||||
|
try:
|
||||||
|
data = storage.connection.get_object(current_app.config['MINIO_CNN_BUCKET_NAME'], path)
|
||||||
|
except NoSuchKey:
|
||||||
|
return abort(500, "The ID is stored in the database but not int the Object Store")
|
||||||
|
|
||||||
return Response(data.stream(), mimetype=data.headers['Content-type'])
|
return Response(data.stream(), mimetype=data.headers['Content-type'])
|
||||||
|
@ -9,6 +9,8 @@ from model import db, AIModel, AIModelType, Default
|
|||||||
|
|
||||||
from schemas import AIModelSchema, DefaultSchema
|
from schemas import AIModelSchema, DefaultSchema
|
||||||
|
|
||||||
|
import opentracing
|
||||||
|
|
||||||
|
|
||||||
class RootView(FlaskView):
|
class RootView(FlaskView):
|
||||||
route_base = '/'
|
route_base = '/'
|
||||||
@ -21,7 +23,9 @@ class RootView(FlaskView):
|
|||||||
## Shared stuff goes here
|
## Shared stuff goes here
|
||||||
|
|
||||||
def index(self):
|
def index(self):
|
||||||
models = AIModel.query.all()
|
with opentracing.tracer.start_active_span('sqlalchemy.select'):
|
||||||
|
models = AIModel.query.all()
|
||||||
|
|
||||||
return jsonify(self.aimodels_schema.dump(models))
|
return jsonify(self.aimodels_schema.dump(models))
|
||||||
|
|
||||||
@route('/<type_>')
|
@route('/<type_>')
|
||||||
@ -29,9 +33,11 @@ class RootView(FlaskView):
|
|||||||
try:
|
try:
|
||||||
aimodel_type = AIModelType[type_]
|
aimodel_type = AIModelType[type_]
|
||||||
except KeyError:
|
except KeyError:
|
||||||
abort(404, "Unknown type")
|
return abort(404, "Unknown type")
|
||||||
|
|
||||||
|
with opentracing.tracer.start_active_span('sqlalchemy.select', tags={"aimodel_type": aimodel_type}):
|
||||||
|
models = AIModel.query.filter_by(type=aimodel_type).all()
|
||||||
|
|
||||||
models = AIModel.query.filter_by(type=aimodel_type).all()
|
|
||||||
return jsonify(self.aimodels_schema.dump(models)), 200
|
return jsonify(self.aimodels_schema.dump(models)), 200
|
||||||
|
|
||||||
@route('/<type_>/<id_>')
|
@route('/<type_>/<id_>')
|
||||||
@ -39,32 +45,41 @@ class RootView(FlaskView):
|
|||||||
try:
|
try:
|
||||||
aimodel_type = AIModelType[type_]
|
aimodel_type = AIModelType[type_]
|
||||||
except KeyError:
|
except KeyError:
|
||||||
abort(404, "Unknown type")
|
return abort(404, "Unknown type")
|
||||||
|
|
||||||
if id_ == "$default":
|
with opentracing.tracer.start_active_span(
|
||||||
default = Default.query.filter_by(type=aimodel_type).first_or_404()
|
'sqlalchemy.select',
|
||||||
m = default.aimodel
|
tags={"aimodel_type": aimodel_type, "id": id_}
|
||||||
else:
|
):
|
||||||
m = AIModel.query.filter_by(type=aimodel_type, id=id_).first_or_404()
|
if id_ == "$default":
|
||||||
|
|
||||||
|
default = Default.query.filter_by(type=aimodel_type).first_or_404()
|
||||||
|
m = default.aimodel
|
||||||
|
else:
|
||||||
|
m = AIModel.query.filter_by(type=aimodel_type, id=id_).first_or_404()
|
||||||
|
|
||||||
# Append download links
|
# Append download links
|
||||||
details = self.aimodel_schema.dump(m)
|
with opentracing.tracer.start_active_span(
|
||||||
|
'compileResponseDict',
|
||||||
|
tags={"id": id_}
|
||||||
|
):
|
||||||
|
details = self.aimodel_schema.dump(m)
|
||||||
|
|
||||||
# Vagy ez, vagy visszateszem a saját view-jébe és duplikálva lesz az egész
|
# Vagy ez, vagy visszateszem a saját view-jébe és duplikálva lesz az egész
|
||||||
if aimodel_type == AIModelType.cnn:
|
if aimodel_type == AIModelType.cnn:
|
||||||
details.update({
|
details.update({
|
||||||
"files": {
|
"files": {
|
||||||
"model": url_for("CNNView:get_file", id_=m.id),
|
"model": url_for("CNNView:get_file", id_=m.id),
|
||||||
"weights": url_for("CNNView:get_file", id_=m.id, weights=''),
|
"weights": url_for("CNNView:get_file", id_=m.id, weights=''),
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
elif aimodel_type == AIModelType.svm:
|
elif aimodel_type == AIModelType.svm:
|
||||||
details.update({
|
details.update({
|
||||||
"files": {
|
"files": {
|
||||||
"model": url_for("SVMView:get_file", id_=m.id),
|
"model": url_for("SVMView:get_file", id_=m.id),
|
||||||
"means": url_for("SVMView:get_file", id_=m.id, means=''),
|
"means": url_for("SVMView:get_file", id_=m.id, means=''),
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
return jsonify(details)
|
return jsonify(details)
|
||||||
|
|
||||||
@ -75,18 +90,24 @@ class RootView(FlaskView):
|
|||||||
try:
|
try:
|
||||||
aimodel_type = AIModelType[type_]
|
aimodel_type = AIModelType[type_]
|
||||||
except KeyError:
|
except KeyError:
|
||||||
abort(404, "Unknown type")
|
return abort(404, "Unknown type")
|
||||||
|
|
||||||
try:
|
try:
|
||||||
req = self.default_schema.load(request.json)
|
req = self.default_schema.load(request.json)
|
||||||
except ValidationError as e:
|
except ValidationError as e:
|
||||||
abort(400, str(e))
|
return abort(400, str(e))
|
||||||
|
|
||||||
m = AIModel.query.filter_by(type=aimodel_type, id=req['id']).first_or_404()
|
with opentracing.tracer.start_active_span('sqlalchemy.select'):
|
||||||
|
m = AIModel.query.filter_by(type=aimodel_type, id=req['id']).first_or_404()
|
||||||
|
|
||||||
Default.query.filter_by(type=aimodel_type).delete()
|
with opentracing.tracer.start_active_span('sqlalchemy.delete'):
|
||||||
new_default = Default(type=aimodel_type, aimodel=m)
|
Default.query.filter_by(type=aimodel_type).delete()
|
||||||
db.session.add(new_default)
|
|
||||||
db.session.commit()
|
with opentracing.tracer.start_active_span('sqlalchemy.create'):
|
||||||
|
new_default = Default(type=aimodel_type, aimodel=m)
|
||||||
|
db.session.add(new_default)
|
||||||
|
|
||||||
|
with opentracing.tracer.start_active_span('sqlalchemy.commit'):
|
||||||
|
db.session.commit()
|
||||||
|
|
||||||
return '', 204
|
return '', 204
|
||||||
|
@ -9,6 +9,7 @@ from schemas import AIModelSchema, InfoSchema
|
|||||||
from marshmallow.exceptions import ValidationError
|
from marshmallow.exceptions import ValidationError
|
||||||
from utils import storage, ensure_buckets, multipart_required
|
from utils import storage, ensure_buckets, multipart_required
|
||||||
from pyAudioAnalysis.audioTrainTest import load_model
|
from pyAudioAnalysis.audioTrainTest import load_model
|
||||||
|
import opentracing
|
||||||
|
|
||||||
|
|
||||||
class SVMView(FlaskView):
|
class SVMView(FlaskView):
|
||||||
@ -24,94 +25,130 @@ class SVMView(FlaskView):
|
|||||||
def post(self):
|
def post(self):
|
||||||
|
|
||||||
# get important data from the request
|
# get important data from the request
|
||||||
try:
|
with opentracing.tracer.start_active_span('parseAndValidate'):
|
||||||
info = self.info_schema.loads(request.form.get('info'))
|
try:
|
||||||
except ValidationError as e:
|
info = self.info_schema.loads(request.form.get('info'))
|
||||||
abort(400, str(e))
|
except ValidationError as e:
|
||||||
|
return abort(400, str(e))
|
||||||
|
|
||||||
# check for conflict
|
# check for conflict
|
||||||
m = AIModel.query.filter_by(id=info['id']).first()
|
m = AIModel.query.filter_by(id=info['id']).first()
|
||||||
if m:
|
if m:
|
||||||
abort(409)
|
return abort(409)
|
||||||
|
|
||||||
# get and validate file
|
# get and validate file
|
||||||
model_file = request.files['modelFile']
|
model_file = request.files['modelFile']
|
||||||
|
|
||||||
if model_file.content_length <= 0:
|
if model_file.content_length <= 0:
|
||||||
abort(411, f"Content length for modelFile is not a positive integer or missing.")
|
return abort(411, f"Content length for modelFile is not a positive integer or missing.")
|
||||||
|
|
||||||
means_file = request.files['meansFile']
|
means_file = request.files['meansFile']
|
||||||
|
|
||||||
if means_file.content_length <= 0:
|
if means_file.content_length <= 0:
|
||||||
abort(411, f"Content length for meansFile is not a positive integer or missing.")
|
return abort(411, f"Content length for meansFile is not a positive integer or missing.")
|
||||||
|
|
||||||
# create bucket if necessary
|
# create bucket if necessary
|
||||||
ensure_buckets()
|
with opentracing.tracer.start_active_span('ensureBuckets'):
|
||||||
|
ensure_buckets()
|
||||||
|
|
||||||
# Temporarily save the file, because pyAudioAnalysis can only read files
|
# Temporarily save the file, because pyAudioAnalysis can only read files
|
||||||
temp_model_handle, temp_model_filename = tempfile.mkstemp()
|
with opentracing.tracer.start_active_span('tempfile.save'):
|
||||||
temp_means_filename = temp_model_filename + "MEANS"
|
temp_model_handle, temp_model_filename = tempfile.mkstemp()
|
||||||
|
temp_means_filename = temp_model_filename + "MEANS"
|
||||||
|
|
||||||
os.close(temp_model_handle) # BRUUUUH
|
os.close(temp_model_handle) # BRUUUUH
|
||||||
|
|
||||||
model_file.save(temp_model_filename)
|
model_file.save(temp_model_filename)
|
||||||
means_file.save(temp_means_filename)
|
means_file.save(temp_means_filename)
|
||||||
|
|
||||||
try:
|
with opentracing.tracer.start_active_span('pyAudioAnalysis.readModel'):
|
||||||
|
try:
|
||||||
|
|
||||||
_, _, _, classes, mid_window, mid_step, short_window, short_step, compute_beat \
|
_, _, _, classes, mid_window, mid_step, short_window, short_step, compute_beat \
|
||||||
= load_model(temp_model_filename)
|
= load_model(temp_model_filename)
|
||||||
|
|
||||||
if info['target_class_name'] not in classes:
|
if info['target_class_name'] not in classes:
|
||||||
abort(400, f"This model does not have a class named {info['target_class_name']}")
|
return abort(400, f"This model does not have a class named {info['target_class_name']}")
|
||||||
|
|
||||||
# Because of pyAudiomeme the files already saved, so we just use the file uploader functions
|
# Because of pyAudiomeme the files already saved, so we just use the file uploader functions
|
||||||
storage.connection.fput_object(
|
storage.connection.fput_object(
|
||||||
current_app.config['MINIO_SVM_BUCKET_NAME'],
|
current_app.config['MINIO_SVM_BUCKET_NAME'],
|
||||||
self.MODEL_DIRECTORY + str(info['id']),
|
self.MODEL_DIRECTORY + str(info['id']),
|
||||||
temp_model_filename
|
temp_model_filename
|
||||||
|
)
|
||||||
|
|
||||||
|
storage.connection.fput_object(
|
||||||
|
current_app.config['MINIO_SVM_BUCKET_NAME'],
|
||||||
|
self.MEANS_DIRECTORY + str(info['id']),
|
||||||
|
temp_means_filename
|
||||||
|
)
|
||||||
|
|
||||||
|
finally:
|
||||||
|
os.remove(temp_model_filename)
|
||||||
|
os.remove(temp_means_filename)
|
||||||
|
|
||||||
|
with opentracing.tracer.start_active_span('sqlalchemy.create'):
|
||||||
|
m = AIModel(id=info['id'], type=AIModelType.svm, target_class_name=info['target_class_name'])
|
||||||
|
db.session.add(m)
|
||||||
|
|
||||||
|
d = SVMDetails(
|
||||||
|
aimodel=m,
|
||||||
|
mid_window=mid_window,
|
||||||
|
mid_step=mid_step,
|
||||||
|
short_window=short_window,
|
||||||
|
short_step=short_step,
|
||||||
|
compute_beat=compute_beat
|
||||||
)
|
)
|
||||||
|
db.session.add(d)
|
||||||
|
|
||||||
storage.connection.fput_object(
|
with opentracing.tracer.start_active_span('sqlalchemy.commit'):
|
||||||
current_app.config['MINIO_SVM_BUCKET_NAME'],
|
db.session.commit()
|
||||||
self.MEANS_DIRECTORY + str(info['id']),
|
|
||||||
temp_means_filename
|
|
||||||
)
|
|
||||||
|
|
||||||
finally:
|
|
||||||
os.remove(temp_model_filename)
|
|
||||||
os.remove(temp_means_filename)
|
|
||||||
|
|
||||||
m = AIModel(id=info['id'], type=AIModelType.svm, target_class_name=info['target_class_name'])
|
|
||||||
|
|
||||||
d = SVMDetails(
|
|
||||||
aimodel=m,
|
|
||||||
mid_window=mid_window,
|
|
||||||
mid_step=mid_step,
|
|
||||||
short_window=short_window,
|
|
||||||
short_step=short_step,
|
|
||||||
compute_beat=compute_beat
|
|
||||||
)
|
|
||||||
|
|
||||||
db.session.add(m)
|
|
||||||
db.session.add(d)
|
|
||||||
db.session.commit()
|
|
||||||
|
|
||||||
return jsonify(self.aimodel_schema.dump(m)), 200
|
return jsonify(self.aimodel_schema.dump(m)), 200
|
||||||
|
|
||||||
def delete(self, id_: str):
|
def delete(self, id_: str):
|
||||||
|
|
||||||
if id_ == "$default":
|
with opentracing.tracer.start_active_span(
|
||||||
default = Default.query.filter_by(type=AIModelType.svm).first_or_404()
|
'sqlalchemy.select',
|
||||||
m = default.aimodel
|
tags={"aimodel_type": AIModelType.svm, "id": id_}
|
||||||
else:
|
):
|
||||||
m = AIModel.query.filter_by(type=AIModelType.svm, id=id_).first_or_404()
|
if id_ == "$default":
|
||||||
|
default = Default.query.filter_by(type=AIModelType.svm).first_or_404()
|
||||||
|
m = default.aimodel
|
||||||
|
else:
|
||||||
|
m = AIModel.query.filter_by(type=AIModelType.svm, id=id_).first_or_404()
|
||||||
|
|
||||||
storage.connection.remove_object(current_app.config['MINIO_SVM_BUCKET_NAME'], self.MEANS_DIRECTORY + str(m.id))
|
with opentracing.tracer.start_active_span('removeFromMinio'):
|
||||||
storage.connection.remove_object(current_app.config['MINIO_SVM_BUCKET_NAME'], self.MODEL_DIRECTORY + str(m.id))
|
with opentracing.tracer.start_active_span(
|
||||||
|
'minio.removeObject',
|
||||||
|
tags={
|
||||||
|
"bucket": current_app.config['MINIO_SVM_BUCKET_NAME'],
|
||||||
|
"object_name": self.MEANS_DIRECTORY + str(m.id),
|
||||||
|
"component": "means"
|
||||||
|
}
|
||||||
|
):
|
||||||
|
storage.connection.remove_object(current_app.config['MINIO_SVM_BUCKET_NAME'],
|
||||||
|
self.MEANS_DIRECTORY + str(m.id))
|
||||||
|
|
||||||
db.session.delete(m)
|
with opentracing.tracer.start_active_span(
|
||||||
db.session.commit()
|
'minio.removeObject',
|
||||||
|
tags={
|
||||||
|
"bucket": current_app.config['MINIO_SVM_BUCKET_NAME'],
|
||||||
|
"object_name": self.MODEL_DIRECTORY + str(m.id),
|
||||||
|
"component": "model"
|
||||||
|
}
|
||||||
|
):
|
||||||
|
storage.connection.remove_object(current_app.config['MINIO_SVM_BUCKET_NAME'],
|
||||||
|
self.MODEL_DIRECTORY + str(m.id))
|
||||||
|
|
||||||
|
with opentracing.tracer.start_active_span(
|
||||||
|
'sqlalchemy.delete',
|
||||||
|
tags={"aimodel_type": AIModelType.svm, "id": id_}
|
||||||
|
):
|
||||||
|
db.session.delete(m)
|
||||||
|
|
||||||
|
with opentracing.tracer.start_active_span('sqlalchemy.commit'):
|
||||||
|
db.session.commit()
|
||||||
|
|
||||||
return '', 204
|
return '', 204
|
||||||
|
|
||||||
@ -119,20 +156,34 @@ class SVMView(FlaskView):
|
|||||||
@route('<id_>/file')
|
@route('<id_>/file')
|
||||||
def get_file(self, id_: str):
|
def get_file(self, id_: str):
|
||||||
|
|
||||||
if id_ == "$default":
|
with opentracing.tracer.start_active_span(
|
||||||
default = Default.query.filter_by(type=AIModelType.svm).first_or_404()
|
'sqlalchemy.select',
|
||||||
m = default.aimodel
|
tags={"aimodel_type": AIModelType.svm, "id": id_}
|
||||||
else:
|
):
|
||||||
m = AIModel.query.filter_by(type=AIModelType.svm, id=id_).first_or_404()
|
if id_ == "$default":
|
||||||
|
default = Default.query.filter_by(type=AIModelType.svm).first_or_404()
|
||||||
|
m = default.aimodel
|
||||||
|
else:
|
||||||
|
m = AIModel.query.filter_by(type=AIModelType.svm, id=id_).first_or_404()
|
||||||
|
|
||||||
if "means" in request.args:
|
if "means" in request.args:
|
||||||
path = self.MEANS_DIRECTORY + str(m.id)
|
path = self.MEANS_DIRECTORY + str(m.id)
|
||||||
|
component = "means"
|
||||||
else:
|
else:
|
||||||
path = self.MODEL_DIRECTORY + str(m.id)
|
path = self.MODEL_DIRECTORY + str(m.id)
|
||||||
|
component = "model"
|
||||||
|
|
||||||
try:
|
with opentracing.tracer.start_active_span(
|
||||||
data = storage.connection.get_object(current_app.config['MINIO_SVM_BUCKET_NAME'], path)
|
'minio.getObject',
|
||||||
except NoSuchKey:
|
tags={
|
||||||
abort(500, "The ID is stored in the database but not int the Object Store")
|
"bucket": current_app.config['MINIO_SVM_BUCKET_NAME'],
|
||||||
|
"object_name": path,
|
||||||
|
"component": component
|
||||||
|
}
|
||||||
|
):
|
||||||
|
try:
|
||||||
|
data = storage.connection.get_object(current_app.config['MINIO_SVM_BUCKET_NAME'], path)
|
||||||
|
except NoSuchKey:
|
||||||
|
return abort(500, "The ID is stored in the database but not int the Object Store")
|
||||||
|
|
||||||
return Response(data.stream(), mimetype=data.headers['Content-type'])
|
return Response(data.stream(), mimetype=data.headers['Content-type'])
|
||||||
|
@ -1,11 +1,11 @@
|
|||||||
requests
|
requests
|
||||||
blinker
|
blinker
|
||||||
Flask
|
Flask~=1.1.2
|
||||||
marshmallow
|
marshmallow~=3.7.1
|
||||||
Flask-Classful
|
Flask-Classful
|
||||||
Flask-SQLAlchemy
|
Flask-SQLAlchemy
|
||||||
SQLAlchemy-Utils
|
SQLAlchemy-Utils
|
||||||
SQLAlchemy
|
SQLAlchemy~=1.3.19
|
||||||
marshmallow-sqlalchemy~=0.26.1
|
marshmallow-sqlalchemy~=0.26.1
|
||||||
marshmallow-enum
|
marshmallow-enum
|
||||||
psycopg2-binary
|
psycopg2-binary
|
||||||
@ -13,6 +13,7 @@ minio~=6.0.0
|
|||||||
flask_minio
|
flask_minio
|
||||||
sentry-sdk
|
sentry-sdk
|
||||||
py-healthcheck
|
py-healthcheck
|
||||||
|
Werkzeug~=1.0.1
|
||||||
|
|
||||||
cython
|
cython
|
||||||
|
|
||||||
@ -25,7 +26,7 @@ joblib==0.14.1
|
|||||||
kiwisolver==1.2.0
|
kiwisolver==1.2.0
|
||||||
matplotlib==3.2.1
|
matplotlib==3.2.1
|
||||||
numpy==1.18.2
|
numpy==1.18.2
|
||||||
pyAudioAnalysis==0.3.0
|
pyAudioAnalysis==0.3.6
|
||||||
pydub==0.23.1
|
pydub==0.23.1
|
||||||
pyparsing==2.4.6
|
pyparsing==2.4.6
|
||||||
python-dateutil==2.8.1
|
python-dateutil==2.8.1
|
||||||
@ -35,4 +36,5 @@ simplejson==3.17.0
|
|||||||
six==1.14.0
|
six==1.14.0
|
||||||
|
|
||||||
jaeger-client
|
jaeger-client
|
||||||
Flask-Opentracing
|
Flask-Opentracing
|
||||||
|
opentracing~=2.4.0
|
Loading…
Reference in New Issue
Block a user