#!/usr/bin/env python3 from flask import jsonify, request, abort, current_app, Response from flask_classful import FlaskView from minio.error import BucketAlreadyExists, BucketAlreadyOwnedByYou, ResponseError, NoSuchKey, NoSuchBucket from marshmallow import ValidationError from utils import storage from schemas import DescriptionSchema import opentracing class ObjectView(FlaskView): description_schema = DescriptionSchema(many=False) @staticmethod def _check_existance(tag: str) -> bool: # ez aztán igen try: storage.connection.stat_object(current_app.config['MINIO_BUCKET_NAME'], tag) except NoSuchKey: return False except NoSuchBucket: return False return True def post(self): # get important data from the request with opentracing.tracer.start_active_span('parseAndValidate'): try: description = self.description_schema.loads(request.form.get('description')) except ValidationError as e: return abort(400, str(e)) # get and validate file file = request.files['soundFile'] if file.content_type != 'audio/wave': return abort(400, f"{file.content_type} is not audio/wave") if file.content_length <= 0: return abort(411, f"Content length for soundFile is not a positive integer or missing.") with opentracing.tracer.start_active_span('ensureBuckets'): # create bucket if necessary try: storage.connection.make_bucket(current_app.config['MINIO_BUCKET_NAME']) except BucketAlreadyOwnedByYou as err: pass except BucketAlreadyExists as err: pass # Everything else should be raised with opentracing.tracer.start_active_span('checkExistence'): # check for conflict if self._check_existance(description['tag']): return abort(409) with opentracing.tracer.start_active_span( 'minio.putObject', tags={ "bucket": current_app.config['MINIO_BUCKET_NAME'], "object_name": description['tag'], "length": file.content_length } ): # poot file into bucket try: storage.connection.put_object(current_app.config['MINIO_BUCKET_NAME'], description['tag'], file, file.content_length, content_type=file.content_type) except ResponseError: # TODO: Check if object already exists... somehow raise return jsonify({"status": "200"}), 200 # TODO: 200 should be OK but that would be inconsistent with the errors def get(self, tag: str): # TODO: Validate tag try: data = storage.connection.get_object(current_app.config['MINIO_BUCKET_NAME'], tag) except NoSuchKey: return abort(404) return Response(data.stream(), mimetype=data.headers['Content-type']) def delete(self, tag: str): # TODO: Validate tag if not self._check_existance(tag): return abort(404) storage.connection.remove_object(current_app.config['MINIO_BUCKET_NAME'], tag) return jsonify({"status": "200"}), 200