2

How can I make a catch all route, that only handles directories and one that handles files?

Below is a simple example

from flask import Flask
app = Flask(__name__)

@app.route('/foo')
def foo_file():
    return 'Queried: foo file'

@app.route('/foo/')
def foo_dir():
    return 'Queried:  foo dir'

@app.route('/<path:path>')
def file(path):
    return 'Queried file: {0}'.format(path)

@app.route('/')
@app.route('/<path:path>/')
def folder(path):
    return 'Queried folder: {0}'.format(path)

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

When I access http:\\127.0.0.1:5000\foo It calls foo_file() and for http:\\127.0.0.1:5000\foo\ it calls foo_dir(). But querying http:\\127.0.0.1:5000\bar and http:\\127.0.0.1:5000\bar\ both call file(). How can I change that?

I know I can check the trailing slash and reroute manually, I was just wondering if there's another way.

marc_s
  • 732,580
  • 175
  • 1,330
  • 1,459
P3trus
  • 6,747
  • 8
  • 40
  • 54

1 Answers1

7

You could just do this...

@app.route('/<path:path>')
def catch_all(path):
    if path.endswith('/'):
        return handle_folder(path)
    else:
        return handle_file(path)
FogleBird
  • 74,300
  • 25
  • 125
  • 131
  • Thats what I'm ccurrently doing. I wss just thinking if there's a builtin way in Flask to do it. – P3trus Jan 22 '13 at 06:35
  • I tried swapping the order of defining the file and folder functions in your original example, but then Flask redirects to force an ending slash. So I think this is the way to go - keep it simple. – FogleBird Jan 22 '13 at 11:32
  • Regarding ordering of routes see this answer: https://stackoverflow.com/a/25011800. Apparently Flask sorts the routes by length and variable content rather than using the order of declaration. – pbatey Oct 14 '21 at 16:32