Skip to content

Instantly share code, notes, and snippets.

@karlcow
Last active August 29, 2015 14:13
Show Gist options
  • Select an option

  • Save karlcow/1dddeda674923adfa7ea to your computer and use it in GitHub Desktop.

Select an option

Save karlcow/1dddeda674923adfa7ea to your computer and use it in GitHub Desktop.
Routing and Flask for redirects.

Exploration for understanding what is the best way to manage routing in Flask in terms of performance, maintainability, use cases.

Started with a question on stackoverflow.

Flask allows for redirect. It helps for managing operational redirects. But I haven't found any elegant way to manage URI persistence (aka the fabric of time) on a long term.

from flask import redirect

@app.route('/shiny')
def shiny_web():
    '''DEPRECATED.'''
    return redirect('/new_black', 301)

@app.route('/new_black')
def new_black():
    '''This is the new feature.'''
    return render_template('cool_new_stuff.html')

That's a way to manage it. Though I have the feeling that little by little the code will be crumpled with old def here and there and that might create a maintenance issue on the long term. Cool URIs don't break.

Maybe another way could be (I haven't tested yet, putting my thoughts down).

from flask import redirect
    
@app.route('/new_black')
@app.route('/shiny', defaults={'status': 301})
def new_black():
    '''This is the new feature.'''

    if status == 301:
        return redirect('/new_black', 301)

    return render_template('cool_new_stuff.html')

I could also imagine a module where you could track with a counter how many times the old URL is being accessed on a daily basis. And at a point when it is not accessed anymore for a long period of time you could decide to send a 410 Gone instead of the 301 Permanent Redirect.

I also can imagine a file, something like legacy.url with inside a syntax managing the routing. That might create other types of performance issues.

301 /shiny /new_black
410 /there 

Question:

  • Have you thought about this in the context of Flask?
  • What was your strategy?
  • Have you experience performance impact by choosing one strategy over another one?
# Found in https://github.com/mic-e/eventdigest/blob/master/localshortener/__main__.py
import flask
from eventdigest.util import redirects
site = flask.Flask("shortener")
@site.route('/<link>')
def redirecter(link):
try:
return flask.redirect(redirects[link])
except KeyError:
return "unknown redirect"
if __name__ == '__main__':
site.run(port=8080)
# found on http://stackoverflow.com/questions/13317536/get-a-list-of-all-routes-defined-in-the-app?lq=1
# This one explains how to access the list of all routes.
All the routes for an application are stored on [`app.url_map`][1] which is an instance of [`werkzeug.routing.Map`][2]. You can iterate over the [`Rule`][3] instances by using the [`iter_rules`][4] method:
from flask import Flask, render_template, url_for
app = Flask(__name__)
def has_no_empty_params(rule):
defaults = rule.defaults if rule.defaults is not None else ()
arguments = rule.arguments if rule.arguments is not None else ()
return len(defaults) >= len(arguments)
@app.route("/site-map")
def site_map():
links = []
for rule in app.url_map.iter_rules():
# Filter out rules we can't navigate to in a browser
# and rules that require parameters
if "GET" in rule.methods and has_no_empty_params(rule):
url = url_for(rule.endpoint)
links.append((url, rule.endpoint))
# links is now a list of url, endpoint tuples
See http://stackoverflow.com/questions/13151161/display-links-to-new-webpages-created/13161594#13161594 for a bit more information.
[1]: http://flask.pocoo.org/docs/api/#flask.Flask.url_map
[2]: http://werkzeug.pocoo.org/docs/routing/#werkzeug.routing.Map
[3]: http://werkzeug.pocoo.org/docs/routing/#werkzeug.routing.Rule
[4]: http://werkzeug.pocoo.org/docs/routing/#werkzeug.routing.Map.iter_rules
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment