Implemented upload
This commit is contained in:
		@@ -1,21 +1,100 @@
 | 
			
		||||
#!/usr/bin/env python3
 | 
			
		||||
import tempfile
 | 
			
		||||
import os
 | 
			
		||||
from flask import request, jsonify, current_app, abort, Response
 | 
			
		||||
from flask_classful import FlaskView, route
 | 
			
		||||
from model import db, Default, AIModel
 | 
			
		||||
from minio.error import BucketAlreadyExists, BucketAlreadyOwnedByYou, ResponseError, NoSuchKey
 | 
			
		||||
from schemas import AIModelSchema, DefaultSchema
 | 
			
		||||
from schemas import AIModelSchema, DefaultSchema, InfoSchema
 | 
			
		||||
from marshmallow.exceptions import ValidationError
 | 
			
		||||
from utils import json_required, storage
 | 
			
		||||
from pyAudioAnalysis.audioTrainTest import load_model, load_model_knn
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class ModelView(FlaskView):
 | 
			
		||||
    aimodel_schema = AIModelSchema(many=False)
 | 
			
		||||
    default_schema = DefaultSchema(many=False)
 | 
			
		||||
    info_schema = InfoSchema(many=False)
 | 
			
		||||
 | 
			
		||||
    def _ensure_buckets(self):
 | 
			
		||||
        for bucket_name in [current_app.config['MINIO_MEANS_BUCKET_NAME'],
 | 
			
		||||
                            current_app.config['MINIO_MODEL_BUCKET_NAME']]:
 | 
			
		||||
            try:
 | 
			
		||||
                storage.connection.make_bucket(bucket_name)
 | 
			
		||||
 | 
			
		||||
            except BucketAlreadyOwnedByYou as err:
 | 
			
		||||
                pass
 | 
			
		||||
            except BucketAlreadyExists as err:
 | 
			
		||||
                pass
 | 
			
		||||
                # Everything else should be raised
 | 
			
		||||
 | 
			
		||||
    @json_required
 | 
			
		||||
    def post(self):
 | 
			
		||||
        return jsonify({})
 | 
			
		||||
 | 
			
		||||
        # get important data from the request
 | 
			
		||||
        try:
 | 
			
		||||
            info = self.info_schema.loads(request.form.get('info'))
 | 
			
		||||
        except ValidationError as e:
 | 
			
		||||
            abort(400, str(e))
 | 
			
		||||
 | 
			
		||||
        # check for conflict
 | 
			
		||||
        m = AIModel.query.filter_by(id=info['id']).first()
 | 
			
		||||
        if m:
 | 
			
		||||
            abort(409)
 | 
			
		||||
 | 
			
		||||
        # get and validate file
 | 
			
		||||
        model_file = request.files['modelFile']
 | 
			
		||||
 | 
			
		||||
        if model_file.content_length <= 0:
 | 
			
		||||
            abort(411, f"Content length for modelFile is not a positive integer or missing.")
 | 
			
		||||
 | 
			
		||||
        means_file = request.files['meansFile']
 | 
			
		||||
 | 
			
		||||
        if means_file.content_length <= 0:
 | 
			
		||||
            abort(411, f"Content length for meansFile is not a positive integer or missing.")
 | 
			
		||||
 | 
			
		||||
        # create bucket if necessary
 | 
			
		||||
        self._ensure_buckets()
 | 
			
		||||
 | 
			
		||||
        # Temporarily save the file, because pyAudioAnalysis can only read files
 | 
			
		||||
        _, temp_model_filename = tempfile.mkstemp()
 | 
			
		||||
        temp_means_filename = temp_model_filename + "MEANS"
 | 
			
		||||
 | 
			
		||||
        model_file.save(temp_model_filename)
 | 
			
		||||
        means_file.save(temp_means_filename)
 | 
			
		||||
 | 
			
		||||
        try:
 | 
			
		||||
 | 
			
		||||
            if info['type'] == 'knn':
 | 
			
		||||
                _, _, _, _, mid_window, mid_step, short_window, short_step, compute_beat \
 | 
			
		||||
                    = load_model_knn(temp_model_filename)
 | 
			
		||||
            else:
 | 
			
		||||
                _, _, _, _, mid_window, mid_step, short_window, short_step, compute_beat \
 | 
			
		||||
                    = load_model(temp_model_filename)
 | 
			
		||||
 | 
			
		||||
            # Because of pyAudiomeme the files already saved, so we just use the file uploader functions
 | 
			
		||||
            storage.connection.fput_object(
 | 
			
		||||
                current_app.config['MINIO_MODEL_BUCKET_NAME'],
 | 
			
		||||
                str(info['id']),
 | 
			
		||||
                temp_model_filename
 | 
			
		||||
            )
 | 
			
		||||
 | 
			
		||||
            storage.connection.fput_object(
 | 
			
		||||
                current_app.config['MINIO_MEANS_BUCKET_NAME'],
 | 
			
		||||
                str(info['id']),
 | 
			
		||||
                temp_means_filename
 | 
			
		||||
            )
 | 
			
		||||
 | 
			
		||||
        finally:
 | 
			
		||||
            os.remove(temp_model_filename)
 | 
			
		||||
            os.remove(temp_means_filename)
 | 
			
		||||
 | 
			
		||||
        m = AIModel(mid_window=mid_window, mid_step=mid_step, short_window=short_window, short_step=short_step,
 | 
			
		||||
                    compute_beat=compute_beat, type=info['type'])
 | 
			
		||||
 | 
			
		||||
        db.session.add(m)
 | 
			
		||||
        db.session.commit()
 | 
			
		||||
 | 
			
		||||
        return jsonify(self.aimodel_schema.dump(m)), 200
 | 
			
		||||
 | 
			
		||||
    def get(self, _id: str):
 | 
			
		||||
 | 
			
		||||
@@ -26,7 +105,7 @@ class ModelView(FlaskView):
 | 
			
		||||
            m = AIModel.query.fiter_by(id=_id).first_or_404()
 | 
			
		||||
 | 
			
		||||
        try:
 | 
			
		||||
            data = storage.connection.get_object(current_app.config['MINIO_BUCKET_NAME'], m.id)
 | 
			
		||||
            data = storage.connection.get_object(current_app.config['MINIO_BUCKET_NAME'], str(m.id))
 | 
			
		||||
        except NoSuchKey:
 | 
			
		||||
            abort(500, "The ID is stored in the database but not int the Object Store")
 | 
			
		||||
 | 
			
		||||
@@ -70,4 +149,4 @@ class ModelView(FlaskView):
 | 
			
		||||
        db.session.add(new_default)
 | 
			
		||||
        db.session.commit()
 | 
			
		||||
 | 
			
		||||
        return jsonify(self.aimodel_schema.dump(m))
 | 
			
		||||
        return '', 204
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user