diff --git a/.python-version b/.python-version
index 9575d51..0f44168 100644
--- a/.python-version
+++ b/.python-version
@@ -1 +1 @@
-3.6.1
+3.6.4
diff --git a/.travis.yml b/.travis.yml
deleted file mode 100644
index e157568..0000000
--- a/.travis.yml
+++ /dev/null
@@ -1,13 +0,0 @@
-language: python
-
-python:
- - "3.6"
- - "3.5"
- - "3.4"
- - "2.7"
-
-install:
- - pip install -r requirements.txt
-
-script:
- - python manage.py test
diff --git a/Dockerfile b/Dockerfile
index 5628c26..24ec179 100644
--- a/Dockerfile
+++ b/Dockerfile
@@ -1,4 +1,5 @@
-FROM python:3.6.1
+# base image
+FROM python:3.6.4-alpine
# set working directory
RUN mkdir -p /usr/src/app
@@ -8,4 +9,4 @@ WORKDIR /usr/src/app
ADD ./requirements.txt /usr/src/app/requirements.txt
# install requirements
-RUN pip install -r requirements.txt
\ No newline at end of file
+RUN pip install -r requirements.txt
diff --git a/LICENSE b/LICENSE
index e1757be..54a7a05 100644
--- a/LICENSE
+++ b/LICENSE
@@ -1,5 +1,5 @@
The MIT License (MIT)
-Copyright (c) 2017 Michael Herman
+Copyright (c) 2018 Michael Herman
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
diff --git a/README.md b/README.md
index e600978..2d59f53 100644
--- a/README.md
+++ b/README.md
@@ -11,7 +11,3 @@ $ docker-compose up -d
```
Open your browser to http://localhost:5001
-
-### Example
-
-
\ No newline at end of file
diff --git a/app.png b/app.png
deleted file mode 100644
index b5c233c..0000000
Binary files a/app.png and /dev/null differ
diff --git a/docker-compose.yml b/docker-compose.yml
index 439519f..a89077b 100644
--- a/docker-compose.yml
+++ b/docker-compose.yml
@@ -1,4 +1,4 @@
-version: '2.1'
+version: '3.5'
services:
@@ -6,26 +6,34 @@ services:
build: .
image: web
container_name: web
- environment:
- - APP_SETTINGS=project.server.config.DevelopmentConfig
ports:
- '5001:5000'
- command: python manage.py runserver -h 0.0.0.0
+ command: python manage.py run -h 0.0.0.0
volumes:
- .:/usr/src/app
+ environment:
+ - FLASK_DEBUG=1
+ - APP_SETTINGS=project.server.config.DevelopmentConfig
depends_on:
- redis
worker:
image: web
- container_name: worker
- environment:
- - APP_SETTINGS=project.server.config.DevelopmentConfig
command: python manage.py run_worker
volumes:
- .:/usr/src/app
+ environment:
+ - APP_SETTINGS=project.server.config.DevelopmentConfig
depends_on:
- redis
redis:
image: redis:3.2.11
+
+ dashboard:
+ build: ./project/dashboard
+ image: dashboard
+ container_name: dashboard
+ ports:
+ - '9181:9181'
+ command: rq-dashboard -H redis
diff --git a/manage.py b/manage.py
index 0efa129..1af94fd 100644
--- a/manage.py
+++ b/manage.py
@@ -1,20 +1,20 @@
# manage.py
-import os
import unittest
import redis
from rq import Connection, Worker
-from flask_script import Manager
+from flask.cli import FlaskGroup
-from project.server import app
+from project.server import create_app
-manager = Manager(app)
+app = create_app()
+cli = FlaskGroup(create_app=create_app)
-@manager.command
+@cli.command()
def test():
"""Runs the unit tests without test coverage."""
tests = unittest.TestLoader().discover('project/tests', pattern='test*.py')
@@ -24,7 +24,7 @@ def test():
return 1
-@manager.command
+@cli.command()
def run_worker():
redis_url = app.config['REDIS_URL']
redis_connection = redis.from_url(redis_url)
@@ -32,5 +32,6 @@ def run_worker():
worker = Worker(app.config['QUEUES'])
worker.work()
+
if __name__ == '__main__':
- manager.run()
+ cli()
diff --git a/project/client/static/main.js b/project/client/static/main.js
index c5a1265..61c8bdc 100644
--- a/project/client/static/main.js
+++ b/project/client/static/main.js
@@ -15,8 +15,8 @@ $('.btn').on('click', function() {
})
.fail((err) => {
console.log(err)
- })
-})
+ });
+});
function getStatus(taskID) {
$.ajax({
@@ -30,7 +30,7 @@ function getStatus(taskID) {
${res.data.task_status} |
${res.data.task_result} |
`
- $('#tasks').prepend(html)
+ $('#tasks').prepend(html);
const taskStatus = res.data.task_status;
if (taskStatus === 'finished' || taskStatus === 'failed') return false;
setTimeout(function() {
@@ -39,6 +39,5 @@ function getStatus(taskID) {
})
.fail((err) => {
console.log(err)
- })
+ });
}
-
diff --git a/project/client/templates/_base.html b/project/client/templates/_base.html
index 8cb66d0..31ad653 100644
--- a/project/client/templates/_base.html
+++ b/project/client/templates/_base.html
@@ -9,7 +9,7 @@
-
+
{% block css %}{% endblock %}
@@ -25,8 +25,8 @@
-
-
+
+
{% block js %}{% endblock %}
diff --git a/project/dashboard/Dockerfile b/project/dashboard/Dockerfile
new file mode 100644
index 0000000..292552a
--- /dev/null
+++ b/project/dashboard/Dockerfile
@@ -0,0 +1,7 @@
+FROM python:3.6.4-alpine
+
+RUN pip install rq-dashboard
+
+EXPOSE 9181
+
+CMD ["rq-dashboard"]
diff --git a/project/server/__init__.py b/project/server/__init__.py
index eb05a49..c768578 100644
--- a/project/server/__init__.py
+++ b/project/server/__init__.py
@@ -7,18 +7,31 @@
from flask_bootstrap import Bootstrap
-app = Flask(
- __name__,
- template_folder='../client/templates',
- static_folder='../client/static'
-)
+# instantiate the extensions
+bootstrap = Bootstrap()
-app_settings = os.getenv('APP_SETTINGS', 'project.server.config.DevelopmentConfig')
-app.config.from_object(app_settings)
+def create_app(script_info=None):
-bootstrap = Bootstrap(app)
+ # instantiate the app
+ app = Flask(
+ __name__,
+ template_folder='../client/templates',
+ static_folder='../client/static'
+ )
+ # set config
+ app_settings = os.getenv('APP_SETTINGS')
+ app.config.from_object(app_settings)
-from project.server.main.views import main_blueprint
-app.register_blueprint(main_blueprint)
+ # set up extensions
+ bootstrap.init_app(app)
+
+ # register blueprints
+ from project.server.main.views import main_blueprint
+ app.register_blueprint(main_blueprint)
+
+ # shell context for flask cli
+ app.shell_context_processor({'app': app})
+
+ return app
diff --git a/project/server/config.py b/project/server/config.py
index 055adff..94fe3c4 100644
--- a/project/server/config.py
+++ b/project/server/config.py
@@ -6,25 +6,18 @@
class BaseConfig(object):
"""Base configuration."""
- DEBUG = False
WTF_CSRF_ENABLED = True
REDIS_URL = 'redis://redis:6379/0'
QUEUES = ['default']
+
class DevelopmentConfig(BaseConfig):
"""Development configuration."""
- DEBUG = True
WTF_CSRF_ENABLED = False
class TestingConfig(BaseConfig):
"""Testing configuration."""
- DEBUG = True
TESTING = True
WTF_CSRF_ENABLED = False
PRESERVE_CONTEXT_ON_EXCEPTION = False
-
-
-class ProductionConfig(BaseConfig):
- """Production configuration."""
- DEBUG = False
diff --git a/project/server/main/tasks.py b/project/server/main/tasks.py
index 80faf77..d4a3964 100644
--- a/project/server/main/tasks.py
+++ b/project/server/main/tasks.py
@@ -6,4 +6,4 @@
def create_task(task_type):
time.sleep(int(task_type) * 10)
- return True
\ No newline at end of file
+ return True
diff --git a/project/server/main/views.py b/project/server/main/views.py
index 3524447..0a2c1f3 100644
--- a/project/server/main/views.py
+++ b/project/server/main/views.py
@@ -2,11 +2,13 @@
import redis
-from rq import Queue, push_connection, pop_connection
-from flask import current_app, render_template, Blueprint, jsonify, request
+from rq import Queue, Connection
+from flask import render_template, Blueprint, jsonify, \
+ request, current_app
from project.server.main.tasks import create_task
+
main_blueprint = Blueprint('main', __name__,)
@@ -18,8 +20,9 @@ def home():
@main_blueprint.route('/tasks', methods=['POST'])
def run_task():
task_type = request.form['type']
- q = Queue()
- task = q.enqueue(create_task, task_type)
+ with Connection(redis.from_url(current_app.config['REDIS_URL'])):
+ q = Queue()
+ task = q.enqueue(create_task, task_type)
response_object = {
'status': 'success',
'data': {
@@ -31,8 +34,9 @@ def run_task():
@main_blueprint.route('/tasks/', methods=['GET'])
def get_status(task_id):
- q = Queue()
- task = q.fetch_job(task_id)
+ with Connection(redis.from_url(current_app.config['REDIS_URL'])):
+ q = Queue()
+ task = q.fetch_job(task_id)
if task:
response_object = {
'status': 'success',
@@ -41,17 +45,7 @@ def get_status(task_id):
'task_status': task.get_status(),
'task_result': task.result,
}
- }
+ }
else:
response_object = {'status': 'error'}
return jsonify(response_object)
-
-
-@main_blueprint.before_request
-def push_rq_connection():
- push_connection(redis.from_url(current_app.config['REDIS_URL']))
-
-
-@main_blueprint.teardown_request
-def pop_rq_connection(exception=None):
- pop_connection()
\ No newline at end of file
diff --git a/project/tests/base.py b/project/tests/base.py
index 8078acc..6ad9fc1 100644
--- a/project/tests/base.py
+++ b/project/tests/base.py
@@ -3,7 +3,9 @@
from flask_testing import TestCase
-from project.server import app
+from project.server import create_app
+
+app = create_app()
class BaseTestCase(TestCase):
diff --git a/project/tests/test__config.py b/project/tests/test__config.py
index dcd9284..85defa0 100644
--- a/project/tests/test__config.py
+++ b/project/tests/test__config.py
@@ -1,4 +1,4 @@
-# project/server/tests/test_config.py
+# project/server/tests/test__config.py
import unittest
@@ -6,7 +6,9 @@
from flask import current_app
from flask_testing import TestCase
-from project.server import app
+from project.server import create_app
+
+app = create_app()
class TestDevelopmentConfig(TestCase):
@@ -34,17 +36,5 @@ def test_app_is_testing(self):
self.assertTrue(app.config['WTF_CSRF_ENABLED'] is False)
-class TestProductionConfig(TestCase):
-
- def create_app(self):
- app.config.from_object('project.server.config.ProductionConfig')
- return app
-
- def test_app_is_production(self):
- self.assertFalse(current_app.config['TESTING'])
- self.assertTrue(app.config['DEBUG'] is False)
- self.assertTrue(app.config['WTF_CSRF_ENABLED'] is True)
-
-
if __name__ == '__main__':
unittest.main()
diff --git a/requirements.txt b/requirements.txt
index 71b6ac6..e0825f0 100644
--- a/requirements.txt
+++ b/requirements.txt
@@ -4,4 +4,4 @@ Flask-Script==2.0.6
Flask-Testing==0.6.2
Flask-WTF==0.14.2
redis==2.10.6
-rq==0.8.2
\ No newline at end of file
+rq==0.10.0