Add redis and celery support

master
esensar 2018-09-20 22:05:03 +02:00
parent eea90a606f
commit 95c7027239
16 changed files with 101 additions and 53 deletions

3
.env 100644
View File

@ -0,0 +1,3 @@
DATABASE_URL="postgresql://localhost"
REDIS_URL=redis://localhost:6379
CELERY_TASK_SERIALIZER=json

View File

@ -1,2 +1,3 @@
release: ./release-tasks.sh release: ./release-tasks.sh
web: gunicorn app:app -w 4 --preload web: gunicorn app.core:app -w 4 --preload
worker: celery -A app.celery_builder.celery worker

View File

@ -1,46 +0,0 @@
# App initialization
from flask_api import FlaskAPI
from flask_sqlalchemy import SQLAlchemy
from flask_bcrypt import Bcrypt
from flasgger import Swagger
from flask_cors import CORS
app = FlaskAPI(__name__, instance_relative_config=True)
app.config.from_object('config')
app.config.from_pyfile('config.py', silent=True)
db = SQLAlchemy(app)
bcrypt = Bcrypt(app)
swagger = Swagger(app, template_file='swagger/template.yaml')
CORS(app)
def setup_blueprints(app):
"""
Sets up all of the blueprints for application
All blueprints should be imported in this method and then added
API blueprint should expose all resources, while other
blueprints expose other domain specific functionalities
They are exposed as blueprints just for consistency, otherwise
they are just simple python packages/modules
"""
from .accounts import accounts_bp
from .devices import devices_bp
from .dashboard import dashboard_bp
from .api import api_bp
from .mqtt import mqtt_bp
app.register_blueprint(accounts_bp)
app.register_blueprint(devices_bp)
app.register_blueprint(dashboard_bp)
app.register_blueprint(mqtt_bp)
app.register_blueprint(api_bp, url_prefix='/api')
setup_blueprints(app)
@app.route("/")
def root():
return "Hello World!"

View File

@ -1,4 +1,4 @@
from app import bcrypt from app.core import bcrypt
from flask import Blueprint from flask import Blueprint
from .models import Account from .models import Account

View File

@ -1,6 +1,6 @@
import jwt import jwt
import datetime import datetime
from app import db, app from app.core import db, app
from calendar import timegm from calendar import timegm

View File

@ -0,0 +1,9 @@
# App initialization
from flask import Flask
from .tasks import celery as celery_configurator
app = Flask(__name__, instance_relative_config=True)
app.config.from_object('config')
app.config.from_pyfile('config.py', silent=True)
app.config['MQTT_CLIENT_ID'] = 'final-iot-backend-server-worker'
celery = celery_configurator.make_celery(app)

48
app/core.py 100644
View File

@ -0,0 +1,48 @@
# App initialization
from flask_api import FlaskAPI
from flask_sqlalchemy import SQLAlchemy
from flask_bcrypt import Bcrypt
from flasgger import Swagger
from flask_cors import CORS
from .tasks import celery as celery_configurator
app = FlaskAPI(__name__, instance_relative_config=True)
app.config.from_object('config')
app.config.from_pyfile('config.py', silent=True)
db = SQLAlchemy(app)
bcrypt = Bcrypt(app)
swagger = Swagger(app, template_file='swagger/template.yaml')
CORS(app)
celery = celery_configurator.make_celery(app)
def setup_blueprints(app):
"""
Sets up all of the blueprints for application
All blueprints should be imported in this method and then added
API blueprint should expose all resources, while other
blueprints expose other domain specific functionalities
They are exposed as blueprints just for consistency, otherwise
they are just simple python packages/modules
"""
from .accounts import accounts_bp
from .devices import devices_bp
from .dashboard import dashboard_bp
from .api import api_bp
from .mqtt import mqtt_bp
app.register_blueprint(accounts_bp)
app.register_blueprint(devices_bp)
app.register_blueprint(dashboard_bp)
app.register_blueprint(mqtt_bp)
app.register_blueprint(api_bp, url_prefix='/api')
setup_blueprints(app)
@app.route("/")
def root():
return "Hello World!"

View File

@ -1,4 +1,4 @@
from app import db from app.core import db
from sqlalchemy.dialects.postgresql import JSON from sqlalchemy.dialects.postgresql import JSON

View File

@ -1,7 +1,7 @@
import sys import sys
from flask import Blueprint from flask import Blueprint
from .models import Device, Recording, DeviceAssociation, DeviceType from .models import Device, Recording, DeviceAssociation, DeviceType
from app import app from app.core import app
devices_bp = Blueprint('devices', __name__) devices_bp = Blueprint('devices', __name__)

View File

@ -1,5 +1,5 @@
from datetime import datetime from datetime import datetime
from app import db from app.core import db
from sqlalchemy.dialects.postgresql import JSON from sqlalchemy.dialects.postgresql import JSON

View File

@ -27,6 +27,10 @@ class MqttClient:
def handle_disconnect(): def handle_disconnect():
print('MQTT client disconnected') print('MQTT client disconnected')
@MqttClient.mqtt.on_log()
def handle_logging(client, userdata, level, buf):
print(level, buf)
print('MQTT client initialized') print('MQTT client initialized')
@staticmethod @staticmethod

View File

View File

@ -0,0 +1,18 @@
from celery import Celery
def make_celery(app):
celery = Celery(
app.import_name,
backend=app.config['CELERY_RESULT_BACKEND'],
broker=app.config['CELERY_BROKER_URL']
)
celery.conf.update(app.config)
class ContextTask(celery.Task):
def __call__(self, *args, **kwargs):
with app.app_context():
return self.run(*args, **kwargs)
celery.Task = ContextTask
return celery

View File

View File

@ -28,12 +28,17 @@ CSRF_SESSION_KEY = "secret"
SECRET_KEY = "?['Z(Z\x83Y \x06T\x12\x96<\xff\x12\xe0\x1b\xd1J\xe0\xd9ld" SECRET_KEY = "?['Z(Z\x83Y \x06T\x12\x96<\xff\x12\xe0\x1b\xd1J\xe0\xd9ld"
# MQTT configuration # MQTT configuration
MQTT_CLIENT_ID = 'final-iot-backend-server'
MQTT_BROKER_URL = 'broker.hivemq.com' MQTT_BROKER_URL = 'broker.hivemq.com'
MQTT_BROKER_PORT = 1883 MQTT_BROKER_PORT = 1883
MQTT_USERNAME = 'user' MQTT_USERNAME = 'user'
MQTT_PASSWORD = 'secret' MQTT_PASSWORD = 'secret'
MQTT_REFRESH_TIME = 1.0 # refresh time in seconds MQTT_REFRESH_TIME = 1.0 # refresh time in seconds
# Celery config
CELERY_BROKER_URL = os.environ['REDIS_URL']
CELERY_RESULT_BACKEND = os.environ['REDIS_URL']
# Flassger config # Flassger config
SWAGGER = { SWAGGER = {
'uiversion': 3 'uiversion': 3

View File

@ -1,6 +1,9 @@
alembic==0.9.9 alembic==0.9.9
amqp==2.3.2
aniso8601==3.0.0 aniso8601==3.0.0
bcrypt==3.1.4 bcrypt==3.1.4
billiard==3.5.0.4
celery==4.2.0
cffi==1.11.5 cffi==1.11.5
click==6.7 click==6.7
flasgger==0.8.3 flasgger==0.8.3
@ -17,6 +20,7 @@ gunicorn==19.8.1
itsdangerous==0.24 itsdangerous==0.24
Jinja2==2.10 Jinja2==2.10
jsonschema==2.6.0 jsonschema==2.6.0
kombu==4.2.1
Mako==1.0.7 Mako==1.0.7
MarkupSafe==1.0 MarkupSafe==1.0
marshmallow==3.0.0b9 marshmallow==3.0.0b9
@ -29,9 +33,11 @@ PyJWT==1.6.1
python-dateutil==2.7.2 python-dateutil==2.7.2
python-editor==1.0.3 python-editor==1.0.3
pytz==2018.4 pytz==2018.4
PyYAML==3.12 PyYAML==3.13
redis==2.10.6
six==1.11.0 six==1.11.0
SQLAlchemy==1.2.7 SQLAlchemy==1.2.7
typing==3.6.4 typing==3.6.4
vine==1.1.4
webargs==3.0.0 webargs==3.0.0
Werkzeug==0.14.1 Werkzeug==0.14.1