Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save allanfreitas/d271cf7faebd99a03fe99ec5f25fc4ce to your computer and use it in GitHub Desktop.
Save allanfreitas/d271cf7faebd99a03fe99ec5f25fc4ce to your computer and use it in GitHub Desktop.
Example of how to split a Flask blueprint into multiple files, with routes in each file, and of how to register all those routes.
"""
Note: can't put in a subdirectory for this example (GitHub Gists
doesn't allow subdirectories). Recommended to move this file to
foo/bar.py.
"""
routes = []
def ping_bar():
return 'Ping bar'
routes.append(dict(
rule='/ping-bar/',
view_func=ping_bar))
def save_bar():
return 'Save bar'
routes.append(dict(
rule='/save-bar/',
view_func=save_bar,
options=dict(methods=['POST',])))
"""
Note: can't put in a subdirectory for this example (GitHub Gists
doesn't allow subdirectories). Recommended to move this file to
foo/baz.py.
"""
routes = []
def call_baz():
return 'Call baz'
routes.append(dict(
rule='/call-baz/',
view_func=call_baz))
def delete_baz():
return 'Delete baz'
routes.append(dict(
rule='/delete-baz/',
view_func=delete_baz,
options=dict(methods=['GET', 'POST'])))
Very helpfull example. I exemined your way of solving problem and came up to this solution:
"""
Application router decoretor.
Use this to append or get rout list for specific modules.
"""
from functools import wraps
ROUTES = dict()
def bluprint_add_routes(blueprint, routes):
"""Assign url route function configuration to given blueprint."""
for route in routes:
blueprint.add_url_rule(
route['rule'],
endpoint=route.get('endpoint', None),
view_func=route['view_func'],
**route.get('options', {}))
def get_routes(module):
"""Filter routes by given module name."""
if module in ROUTES.keys():
return list(ROUTES[module])
else:
return ()
def application_route(rule, **kargs):
"""Decorator function that collects application routes."""
def wrapper(funcion): # pylint: disable=missing-docstring
if funcion.__module__ not in ROUTES.keys():
ROUTES[funcion.__module__] = []
ROUTES[funcion.__module__].append(dict(
rule=rule,
view_func=funcion,
options=kargs,
))
@wraps(funcion)
def wrapped(*args, **kwargs): # pylint: disable=missing-docstring
return funcion(*args, **kwargs)
return wrapped
return wrapper
So you can do smth like this:
"""
Public module.
Handles requests for unathorised users.
"""
from flask import Blueprint
from app.utils.route import bluprint_add_routes
from app.public.pages import ROUTES as PAGE_ROUTES
from app.public.contact_us import ROUTES as CONTACT_US_ROUTES
BLUEPRINT = Blueprint('public', __name__,
template_folder='../templates/public')
bluprint_add_routes(BLUEPRINT, PAGE_ROUTES + CONTACT_US_ROUTES)
"""Public pages for unathorised users."""
from flask import render_template
from app.utils.route import application_route, get_routes
@application_route("/")
def home():
"""Show main landing page."""
return render_template('home.jade', page=None)
@application_route("/<slug>")
def page(slug):
"""Show custom public page."""
return render_template('page.jade', page=None)
ROUTES = get_routes("app.public.pages")
from flask import Flask
app = Flask(__name__)
app.debug = True
@app.route('/')
def home():
return 'App home'
from foo import mod
app.register_blueprint(mod, url_prefix='/foo')
if __name__ == '__main__':
app.run()
"""
Note: can't put in a subdirectory for this example (GitHub Gists
doesn't allow subdirectories). Recommended to move this file to
foo/__init__.py, and to change the imports to
'from .bar' and 'from .baz'.
"""
from flask import Blueprint
mod = Blueprint('foo', __name__)
@mod.route('/')
def home():
return 'Foo home'
from bar import routes as bar_routes
from baz import routes as baz_routes
routes = (
bar_routes +
baz_routes)
for r in routes:
mod.add_url_rule(
r['rule'],
endpoint=r.get('endpoint', None),
view_func=r['view_func'],
**r.get('options', {}))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment