#!/usr/bin/env python3 import logging import json from xeger import Xeger from flask_restful import Resource from flask import request import requests from db import db from models import SampleMetadata from rabbitmqqueue import rabbitmq_channel from schemas import SampleSchema from config import * """ Flask Restful endpoints """ __author__ = '@tormakris' __copyright__ = "Copyright 2020, Birbnetes Team" __module_name__ = "endpoints" __version__text__ = "1" LOGGER = logging.getLogger(__name__) class SampleResource(Resource): """ Sample endpoint See: https://swagger.kmlabz.com/?urls.primaryName=Input%20Service """ samplemetadatas_schema = SampleMetadata(many=True, exclude=['id', 'device_id', 'device_date', 'tag', 'timestamp']) def post(self): """ Post request send to the endpoint :return: """ if 'file' not in request.files: return {"err_msg": "no file found"}, 469 else: soundfile = request.files['file'] if 'description' not in request.form: return {"err_msg": "no description found"}, 470 else: description = request.form.get("description") if soundfile.content_type != 'audio/wave': LOGGER.info( f"Input file was not WAV.") return {'err_msg': 'Input file not a wave file.'}, 415 try: desc = json.loads(description) except Exception as e: LOGGER.exception(e) return {'err_msg': 'Input JSON could not be parsed'}, 400 validate_errors = SampleSchema().validate(desc) if validate_errors: LOGGER.error( "Input JSON did not conform to schema. It was: {}".format(desc)) return {'err_msg': 'Input JSON schema invalid'}, 417 xeger = Xeger(limit=30) generated_tag = xeger.xeger(r'^[a-zA-Z]+[0-9a-zA-Z_]*$') record = SampleMetadata( device_id=desc['device_id'], device_date=desc['date'], tag=generated_tag) try: db.session.add(record) requests.post( f"http://{STORAGE_HOSTNAME}/object", files={ 'tag': (None, generated_tag), 'file': ( 'wave.wav', soundfile, soundfile.content_type)}) rabbitmq_channel.basic_publish( exchange=RABBITMQ_EXCHANGE, routing_key='feature', body=generated_tag) except Exception as e: LOGGER.exception(e) db.session.rollback() return {"err_msg": str( e), "hint": "DB or downstream service error"}, 569 db.session.commit() return {"tag": generated_tag}, 200 def get(self): """ Get all stored items :return: """ samples = SampleMetadata.query.all() return list(samples), 200 class SampleParameterResource(Resource): """ Sample endpoint with parameters """ samplemetadata_schema = SampleMetadata(many=False) def get(self, tag: str): """ Get a specific item :param tag: :return: """ sample = SampleMetadata.query.filter_by(tag=tag).first_or_404() return self.samplemetadata_schema.dump(sample), 200