Skip to content

Commit

Permalink
[#3196] Add DebugToolbar to the Flask stack
Browse files Browse the repository at this point in the history
Similarly to Django debug toolbar, it offers a lot of really useful
information when debugging.

https://flask-debugtoolbar.readthedocs.io

It requires SECRET_KEY to be set up, which we will need for the sessions
anyway. As with the repoze.who auth token, we fall back to
`beaker.session.secret` if it's not present.
  • Loading branch information
amercader committed Aug 18, 2016
1 parent e26bf56 commit fb24f71
Show file tree
Hide file tree
Showing 3 changed files with 51 additions and 1 deletion.
20 changes: 20 additions & 0 deletions ckan/config/middleware/flask_app.py
Expand Up @@ -3,6 +3,10 @@
from flask import Flask
from werkzeug.exceptions import HTTPException

from flask_debugtoolbar import DebugToolbarExtension

from paste.deploy.converters import asbool

from ckan.common import config


Expand All @@ -14,7 +18,10 @@ def make_flask_stack(conf, **app_conf):
""" This has to pass the flask app through all the same middleware that
Pylons used """

debug = asbool(app_conf.get('debug', app_conf.get('DEBUG', False)))

app = flask_app = CKANFlask(__name__)
app.debug = debug

# Update Flask config with the CKAN values. We use the common config
# object as values might have been modified on `load_environment`
Expand All @@ -24,6 +31,19 @@ def make_flask_stack(conf, **app_conf):
app.config.update(conf)
app.config.update(app_conf)

# Do all the Flask-specific stuff before adding other middlewares

# Secret key needed for flask-debug-toolbar and sessions
if not app.config.get('SECRET_KEY'):
app.config['SECRET_KEY'] = config.get('beaker.session.secret')
if not app.config.get('SECRET_KEY'):
raise RuntimeError(u'You must provide a value for the secret key'
' with the SECRET_KEY config option')

if debug:
app.config['DEBUG_TB_INTERCEPT_REDIRECTS'] = False
DebugToolbarExtension(app)

@app.route('/hello', methods=['GET'])
def hello_world():
return 'Hello World, this is served by Flask'
Expand Down
31 changes: 30 additions & 1 deletion ckan/tests/config/test_middleware.py
Expand Up @@ -2,11 +2,12 @@

import mock
import wsgiref
from nose.tools import assert_equals, assert_not_equals, eq_
from nose.tools import assert_equals, assert_not_equals, eq_, assert_raises
from routes import url_for

import ckan.plugins as p
import ckan.tests.helpers as helpers
from ckan.common import config

from ckan.config.middleware import AskAppDispatcherMiddleware
from ckan.config.middleware.flask_app import CKANFlask
Expand Down Expand Up @@ -409,3 +410,31 @@ class MockPylonsController(p.toolkit.BaseController):

def view(self):
return 'Hello World, this is served from a Pylons extension'


class TestSecretKey(object):

@helpers.change_config('SECRET_KEY', 'super_secret_stuff')
def test_secret_key_is_used_if_present(self):

app = helpers._get_test_app()

eq_(app.flask_app.config['SECRET_KEY'],
u'super_secret_stuff')

@helpers.change_config('SECRET_KEY', None)
def test_beaker_secret_is_used_by_default(self):

app = helpers._get_test_app()

eq_(app.flask_app.config['SECRET_KEY'],
config['beaker.session.secret'])

@helpers.change_config('SECRET_KEY', None)
@helpers.change_config('beaker.session.secret', None)
def test_no_beaker_secret_crashes(self):

assert_raises(ValueError, helpers._get_test_app)

# TODO: When Pylons is finally removed, we should test for
# RuntimeError instead (thrown on `make_flask_stack`)
1 change: 1 addition & 0 deletions dev-requirements.txt
Expand Up @@ -4,6 +4,7 @@ beautifulsoup4==4.4.1
coveralls #Let Unpinned - Requires latest coveralls
docutils==0.12
factory-boy==2.1.1
Flask-DebugToolbar==0.10.0
httpretty==0.8.3
mock==2.0.0
pep8==1.4.6
Expand Down

0 comments on commit fb24f71

Please sign in to comment.