Skip to content

Instantly share code, notes, and snippets.

@gingerlime
Created February 15, 2014 19:00
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save gingerlime/9023629 to your computer and use it in GitHub Desktop.
Save gingerlime/9023629 to your computer and use it in GitHub Desktop.
trying to use url_prefix with Flask
#!/usr/bin/env python
# coding=utf8
from flask import Flask, Blueprint, redirect, url_for
from flask.ext.bootstrap import Bootstrap
bp = Blueprint('blueprint', __name__)
app = Flask(__name__)
Bootstrap(app)
app.register_blueprint(bp, prefix='/prefix')
# when using `@app.route` this works, but url is `/`
# with @bp.route neither `/` nor `/prefix` work
@bp.route('/', methods=('GET', 'POST',))
def index():
return 'index'
@bp.route('/go_home')
def go_home():
return redirect(url_for('index'))
if '__main__' == __name__:
app.run(debug=True)
@mbr
Copy link

mbr commented Feb 15, 2014

You're doing things in the wrong order. =)

When you register the blueprint, it adds its own routes to the app - at that point no routes are defined. The fix is simply moving the app below the creation of the blueprint. See the example below:

@mbr
Copy link

mbr commented Feb 15, 2014

Example::

#!/usr/bin/env python
# coding=utf8

from flask import Flask, Blueprint, redirect, url_for
from flask.ext.bootstrap import Bootstrap

bp = Blueprint('blueprint', __name__)


# when using `@app.route` this works, but url is `/`
# with @bp.route neither `/` nor `/prefix` work
@bp.route('/', methods=('GET', 'POST',))
def index():
    return 'index'


@bp.route('/go_home')
def go_home():
    return redirect(url_for('index'))


app = Flask(__name__)
Bootstrap(app)
app.register_blueprint(bp, prefix='/prefix')

if '__main__' == __name__:
    app.run(debug=True)

@mbr
Copy link

mbr commented Feb 15, 2014

Also note that this problem does not even occur if you move each blueprint to a separate file, as you should (though it's good to have tried and run into this problem and learned something from it =)).

Another thing to adopt is the create app pattern: http://flask.pocoo.org/docs/patterns/appfactories/

Finally, you could end up with a structure like this:

myapp/__init__.py:

from flask import Flask
from flask_bootstrap import Bootstrap  # note that flask.ext. is deprecated, use flask_ instead for newer extensions
from flask_appconfig import AppConfig  # optional and disclaimer: I wrote flask-appconfig. see https://github.com/mbr/flask-appconfig

from .someblueprint import someblueprint

def create_app(configfile=None):
    app = Flask(__name__)
    AppConfig(app)
    Bootstrap(app)

    app.register_blueprint(someblueprint, prefix='/prefix')
    return app

myapp/someblueprint.py

from flask import Blueprint

someblueprint = Blueprint('someblueprint', __name__)

@someblueprint.route('/', methods=('GET', 'POST',))
def index():
    return 'index'


@someblueprint.route('/go_home')
def go_home():
    # note that i'm using '.index', not 'index' - the latter would redirect to the app, not the blueprint
    return redirect(url_for('.index'))

Since it's now a package __init__.py file, you cannot run the application using ifmain anymore. Therefore you need to write something like this apprunner.py:

from myapp import create_app

create_app().run(debug=True)

Of course, if you use appconfig, you can eschew this step when developing (using flaskdev, see the appconfig docs for details). Finally, all this requires a working virtualenv and setup.py, but that'll you'll have to google for yourself.

Good luck.

@gingerlime
Copy link
Author

Wow. Thanks a bunch @mbr. So much useful and clear info. I definitely learned something (actually, learned way-more than I expected). And interestingly, I was thinking about tackling how to manage configs, so flask-appconfig looks very useful as well.

To be honest, as a side-note, this whole thing started as an experiment using a micro-framework after working for some time with Django/Rails. So my thinking was doing something quick-n-dirty, and keeping almost everything in one file. It is essentially a one-form app to charge credit cards via stripe. I realise that things evolve rather quickly and soon enough you have to start splitting and tidying-up, managing configs etc. So I'm beginning to wonder if micro-frameworks really save so much. But I certainly appreciate the experience, and having kind people to help me like you did is very encouraging, regardless of the framework or technology. I'm very thankful for your help Marc!

@gingerlime
Copy link
Author

just noticed that in some places in the documentation, e.g. https://pypi.python.org/pypi/Flask-Bootstrap and http://pythonhosted.org/Flask-Bootstrap/bootstrap2.html?highlight=ext#usage - it still shows the deprecated method of importing Bootstrap from flask.ext.bootstrap import Bootstrap

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment