Skip to content
This repository has been archived by the owner on Sep 14, 2019. It is now read-only.

Commit

Permalink
Deploy with gunicorn.
Browse files Browse the repository at this point in the history
[Resolves #20]
  • Loading branch information
jmcarp committed Aug 15, 2015
1 parent 1d0fc6f commit 64b01e1
Show file tree
Hide file tree
Showing 7 changed files with 64 additions and 42 deletions.
2 changes: 1 addition & 1 deletion Procfile
@@ -1 +1 @@
web: invoke serve --port $VCAP_APP_PORT
web: gunicorn main:app --bind 0.0.0.0:$VCAP_APP_PORT --config hooks.py
42 changes: 42 additions & 0 deletions app.py
@@ -0,0 +1,42 @@
import os

from sandman import app

from flask import request
from flask.ext.cors import CORS
from flask.ext.basicauth import BasicAuth

import aws
import utils
import config

def make_app():
app.json_encoder = utils.APIJSONEncoder
app.config['CASE_INSENSITIVE'] = config.CASE_INSENSITIVE
app.config['SQLALCHEMY_DATABASE_URI'] = config.SQLA_URI
app.config['BASIC_AUTH_USERNAME'] = os.environ.get('AUTOAPI_ADMIN_USERNAME', '')
app.config['BASIC_AUTH_PASSWORD'] = os.environ.get('AUTOAPI_ADMIN_PASSWORD', '')

CORS(app)
basic_auth = BasicAuth(app)

@app.before_request
def refresh():
tables = utils.get_tables()
if tables != app.config['SQLALCHEMY_TABLES']:
utils.refresh_tables()
app.config['SQLALCHEMY_TABLES'] = tables
app.config['SQLALCHEMY_TABLES'] = utils.get_tables()

@app.before_request
def protect_admin():
if request.path.startswith('/admin/'):
if not basic_auth.authenticate():
return basic_auth.challenge()

blueprint = aws.make_blueprint()
app.register_blueprint(blueprint)

utils.activate(admin=True)

return app
11 changes: 11 additions & 0 deletions hooks.py
@@ -0,0 +1,11 @@
import os
import sys
import multiprocessing

sys.path.insert(0, os.getcwd())
import aws

def when_ready(server):
pool = multiprocessing.Pool(processes=1)
pool.apply_async(aws.fetch_bucket)
pool.close()
3 changes: 3 additions & 0 deletions main.py
@@ -0,0 +1,3 @@
from app import make_app

app = make_app()
1 change: 1 addition & 0 deletions requirements.txt
Expand Up @@ -3,6 +3,7 @@ csvkit>=0.9.1
invoke>=0.10.1
pandas>=0.16.2
requests>=2.7.0
gunicorn>=19.3.0
cryptography>=1.0
Flask-Cors>=2.1.0
Flask-BasicAuth>=0.2.0
Expand Down
40 changes: 0 additions & 40 deletions tasks.py
@@ -1,13 +1,7 @@
import os
import logging
import concurrent.futures

from invoke import task, run
from flask import request
from flask.ext.cors import CORS
from flask.ext.basicauth import BasicAuth

import aws
import utils
import config

Expand All @@ -28,38 +22,4 @@ def apify(filename, tablename=None):
utils.drop_table(tablename)
utils.load_table(filename, tablename)
utils.index_table(tablename, config.CASE_INSENSITIVE)
utils.activate(base=utils.ReadOnlyModel)
logger.info('Finished importing {0}'.format(filename))

@task
def serve(host='0.0.0.0', port=5000, debug=False):
from sandman import app
app.json_encoder = utils.APIJSONEncoder
app.config['SERVER_PORT'] = port
app.config['CASE_INSENSITIVE'] = config.CASE_INSENSITIVE
app.config['SQLALCHEMY_DATABASE_URI'] = config.SQLA_URI
app.config['BASIC_AUTH_USERNAME'] = os.environ.get('AUTOAPI_ADMIN_USERNAME', '')
app.config['BASIC_AUTH_PASSWORD'] = os.environ.get('AUTOAPI_ADMIN_PASSWORD', '')

CORS(app)
basic_auth = BasicAuth(app)

@app.before_request
def protect_admin():
if request.path.startswith('/admin/'):
if not basic_auth.authenticate():
return basic_auth.challenge()

blueprint = aws.make_blueprint()
app.register_blueprint(blueprint)

# Activate sandman with existing models
utils.activate(admin=True)

# Load bucket in a separate process, then re-activate sandman in the main process
pool = concurrent.futures.ProcessPoolExecutor()
future = pool.submit(aws.fetch_bucket)
future.add_done_callback(utils.activate)
pool.shutdown(wait=False)

app.run(host=host, port=port, debug=debug)
7 changes: 6 additions & 1 deletion utils.py
Expand Up @@ -79,6 +79,11 @@ def drop_table(tablename, metadata=None, engine=None):
pass
refresh_tables()

def get_tables(engine=None):
engine = engine or sa.create_engine(config.SQLA_URI)
inspector = sa.engine.reflection.Inspector.from_engine(db.engine)
return set(inspector.get_table_names())

def refresh_tables():
db.metadata.clear()
activate(base=ReadOnlyModel, reflect_all=True, browser=False, admin=False)
activate()

0 comments on commit 64b01e1

Please sign in to comment.