throw out marshmallow
All checks were successful
continuous-integration/drone/push Build is passing

This commit is contained in:
Torma Kristóf 2020-03-31 16:51:31 +02:00
parent fefbb63f67
commit 479ca0f44d
Signed by: tormakris
GPG Key ID: DC83C4F2C41B1047
10 changed files with 102 additions and 75 deletions

View File

@ -136,4 +136,4 @@ dmypy.json
.git/ .git/
*.yml *.yml
contrib/* contrib/*
postman/* postman/*

View File

@ -16,4 +16,4 @@ COPY ./src .
EXPOSE 8080 EXPOSE 8080
ENTRYPOINT ["gunicorn", "-b", "0.0.0.0:8080", "--workers", "1", "--threads", "8", "app:app"] ENTRYPOINT ["gunicorn", "-b", "0.0.0.0:8080", "--workers", "1", "--threads", "1", "app:app"]

39
docker-compose.yml Normal file
View File

@ -0,0 +1,39 @@
version: '3'
networks:
rabbitmq:
external: false
postgres:
external: false
services:
test-db:
image: postgres:12
restart: always
ports:
- "127.0.0.1:5432:5432"
environment:
- POSTGRES_USER=input-service
- POSTGRES_PASSWORD=input-service
- POSTGRES_DB=input-service
networks:
- postgres
volumes:
- postres-volume:/var/lib/postgresql/data
rabbitmq:
image: "rabbitmq:3"
hostname: "test-rabbitmq"
environment:
RABBITMQ_ERLANG_COOKIE: "akjahsfvbkueasnvfjkhsga"
RABBITMQ_DEFAULT_USER: "rabbitmq"
RABBITMQ_DEFAULT_PASS: "rabbitmq"
RABBITMQ_DEFAULT_VHOST: "/"
networks:
- rabbitmq
ports:
- "127.0.0.1:15672:15672"
- "127.0.0.1:5672:5672"
volumes:
postres-volume:

View File

@ -1,6 +1,5 @@
sentry_sdk sentry_sdk[flask]
gunicorn gunicorn
marshmallow
Flask Flask
Flask-RESTful Flask-RESTful
requests requests
@ -8,5 +7,6 @@ werkzeug
filetype filetype
sqlalchemy sqlalchemy
flask_sqlalchemy flask_sqlalchemy
rstr xeger
pika pika
psycopg2-binary

View File

@ -1,14 +1,14 @@
#!/usr/bin/env python3 #!/usr/bin/env python3
import logging import logging
import sentry_sdk
from flask import Flask from flask import Flask
from flask_restful import Api from flask_restful import Api
import sentry_sdk
from sentry_sdk.integrations.flask import FlaskIntegration from sentry_sdk.integrations.flask import FlaskIntegration
import pika
import rabbitmqqueue
from config import * from config import *
from db import db from db import db
from resources import * from resources import SampleResource, SampleParameterResource
""" """
Main Flask RESTful API Main Flask RESTful API
@ -37,10 +37,6 @@ db.init_app(app)
with app.app_context(): with app.app_context():
db.create_all() db.create_all()
rabbitmq = pika.BlockingConnection(pika.ConnectionParameters(host=RABBITMQ_HOST))
rabbitmq_channel = rabbitmq.channel()
rabbitmq_channel.queue_declare(RABBITMQ_QUEUE)
formatter = logging.Formatter( formatter = logging.Formatter(
fmt="%(asctime)s - %(levelname)s - %(module)s - %(message)s" fmt="%(asctime)s - %(levelname)s - %(module)s - %(message)s"
) )
@ -53,7 +49,7 @@ logger.setLevel(logging.DEBUG)
logger.addHandler(handler) logger.addHandler(handler)
api.add_resource(SampleResource, "/v1/input/sample") api.add_resource(SampleResource, "/v1/input/sample")
api.add_resource(SampleParameterResource, '/v1/input/sample<str:tag>') api.add_resource(SampleParameterResource, '/v1/input/sample/<tag>')
if __name__ == "__main__": if __name__ == "__main__":
app.run( app.run(

View File

@ -18,12 +18,15 @@ DEBUG = os.environ.get("INPUT_SERVICE_DEBUG", True)
SENTRY_DSN = os.environ.get("SENTRY_DSN") SENTRY_DSN = os.environ.get("SENTRY_DSN")
RELEASE_ID = os.environ.get("RELEASE_ID") RELEASE_ID = os.environ.get("RELEASE_ID", "test")
RELEASEMODE = os.environ.get("INPUT_SERVICE_RELEASEMODE") RELEASEMODE = os.environ.get("INPUT_SERVICE_RELEASEMODE", "dev")
RABBITMQ_HOST = os.getenv("INPUT_RABBITMQ_HOSTNAME", "localhost") RABBITMQ_HOST = os.getenv("INPUT_RABBITMQ_HOSTNAME", "localhost")
RABBITMQ_EXCHANGE = os.getenv("INPUT_RABBITMQ_EXCHANGE", "wave-extract") RABBITMQ_EXCHANGE = os.getenv("INPUT_RABBITMQ_EXCHANGE", "wave-extract")
RABBITMQ_QUEUE = os.getenv("INPUT_RABBITMQ_QUEUE", "wave-extract") RABBITMQ_QUEUE = os.getenv("INPUT_RABBITMQ_QUEUE", "wave-extract")
RABBITMQ_USERNAME = os.getenv("INPUT_RABBITMQ_USERNAME", "rabbitmq")
RABBITMQ_PASSWORD = os.getenv("INPUT_RABBITMQ_PASSWORD", "rabbitmq")
POSTGRES_HOSTNAME = os.getenv("INPUT_POSTGRES_HOSTNAME", "localhost") POSTGRES_HOSTNAME = os.getenv("INPUT_POSTGRES_HOSTNAME", "localhost")
POSTGRES_USERNAME = os.getenv("INPUT_POSTGRES_USERNAME", "input-service") POSTGRES_USERNAME = os.getenv("INPUT_POSTGRES_USERNAME", "input-service")
POSTGRES_PASSWORD = os.getenv("INPUT_POSTGRES_PASSWORD", "input-service") POSTGRES_PASSWORD = os.getenv("INPUT_POSTGRES_PASSWORD", "input-service")

View File

@ -1,5 +1,5 @@
#!/usr/bin/env python3 #!/usr/bin/env python3
import db from db import db
from sqlalchemy.sql import func from sqlalchemy.sql import func
""" """

18
src/rabbitmqqueue.py Normal file
View File

@ -0,0 +1,18 @@
#!/usr/bin/env python3
import pika
from config import *
"""
Rabbitmq setup
"""
__author__ = '@tormakris'
__copyright__ = "Copyright 2020, Birbnetes Team"
__module_name__ = "endpoints"
__version__text__ = "1"
credentials = pika.PlainCredentials(RABBITMQ_USERNAME, RABBITMQ_PASSWORD)
rabbitmq = pika.BlockingConnection(pika.ConnectionParameters(host=RABBITMQ_HOST,credentials=credentials))
rabbitmq_channel = rabbitmq.channel()
rabbitmq_channel.queue_declare(RABBITMQ_QUEUE)

View File

@ -1,15 +1,13 @@
#!/usr/bin/env python3 #!/usr/bin/env python3
from app import rabbitmq_channel
import logging import logging
import json from xeger import Xeger
import rstr from flask_restful import Resource
from flask_restful import Resource, reqparse from flask import request
from werkzeug.datastructures import FileStorage
import requests import requests
import filetype import filetype
from db import db from db import db
from models import SampleMetadata from models import SampleMetadata
from schemas import * from rabbitmqqueue import rabbitmq_channel
from config import * from config import *
""" """
@ -35,35 +33,33 @@ class SampleResource(Resource):
Post request send to the endpoint Post request send to the endpoint
:return: :return:
""" """
parse = reqparse.RequestParser() if 'file' not in request.files:
parse.add_argument('soundFile', type=FileStorage, location='soundFile') return {"status": "error", "message": "no file found"}, 469
parse.add_argument('description', type=str, location='description') else:
args = parse.parse_args() soundfile = request.files['file']
soundFile = args['soundFile']
description = args['description'] if 'date' not in request.form:
kind = filetype.guess(soundFile) return {"status": "error", "message": "no date found"}, 470
if kind.mime != 'wav': else:
date = request.form.get("date")
if 'device_id' not in request.form:
return {"status": "error", "message": "no device_id found"}, 471
else:
device_id = request.form.get("device_id")
kind = filetype.guess(soundfile)
if kind is None or kind.mime != 'wav':
LOGGER.error( LOGGER.error(
"Input file was not WAV. Recieved metadata: {}", f"Input file was not WAV. Recieved metadata: device_id: {device_id}")
description)
return {'status': 'error', 'message': 'Input file not WAV.'}, 415 return {'status': 'error', 'message': 'Input file not WAV.'}, 415
try:
desc = json.loads(description) xeger = Xeger(limit=32)
except Exception as e: generated_tag = xeger.xeger(r'^[a-zA-Z]+[0-9a-zA-Z_]*$')
LOGGER.exception(e)
return {'status': 'error',
'message': '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: {}", desc)
return {'status': 'error',
'message': 'Input JSON schema invalid'}, 417
generated_tag = rstr.xeger(r'^[a-zA-Z]+[0-9a-zA-Z_]*$', 2, 32)
record = SampleMetadata( record = SampleMetadata(
device_id=desc['device_id'], device_id=device_id,
device_date=desc['date'], device_date=date,
tag=generated_tag) tag=generated_tag)
try: try:
db.session.add(record) db.session.add(record)
@ -73,7 +69,7 @@ class SampleResource(Resource):
'tag': (None, generated_tag), 'tag': (None, generated_tag),
'file': ( 'file': (
'wave.wav', 'wave.wav',
soundFile, soundfile,
kind.mime)}) kind.mime)})
rabbitmq_channel.basic_publish( rabbitmq_channel.basic_publish(
exchange=RABBITMQ_EXCHANGE, exchange=RABBITMQ_EXCHANGE,
@ -93,7 +89,7 @@ class SampleResource(Resource):
Get all stored items Get all stored items
:return: :return:
""" """
samples = SampleMetadata.query.get.all() samples = SampleMetadata.query.all()
return {"status": "ok", "message": samples}, 200 return {"status": "ok", "message": samples}, 200

View File

@ -1,25 +0,0 @@
#!/usr/bin/env python3
from marshmallow import Schema, fields
"""
Schemas of input objects
"""
__author__ = "@tormakris"
__copyright__ = "Copyright 2020, Birbnetes Team"
__module_name__ = "schemas"
__version__text__ = "1"
class SampleSchema(Schema):
""" /v1/email/pay - POST
Parameters:
- date (date)
- device_id (str)
"""
date = fields.Date(required=True)
device_id = fields.Str(required=True)