Capture Arbitrary Path in Flask Route

Capture arbitrary path in Flask route

Use the path converter to capture arbitrary length paths: <path:path> will capture a path and pass it to the path argument. The default converter captures a single string but stops at slashes, which is why your first url matched but the second didn't.

If you also want to match the root directory (a leading slash and empty path), you can add another rule that sets a default value for the path argument.

@app.route('/', defaults={'path': ''})
@app.route('/<path:path>')
def get_dir(path):
return path

There are other built-in converters such as int and float, and it's possible to write your own as well for more complex cases.

Catch all routes for Flask

You can follow this guideline: https://flask.palletsprojects.com/en/1.1.x/api/#url-route-registrations

from flask import Flask
app = Flask(__name__)

@app.route('/', defaults={'path': ''})
@app.route('/<path:path>')
def catch_all(path):
return 'You want path: %s' % path

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

Match an arbitrary path, or the empty string, without adding multiple Flask route decorators

It's reasonable to assign multiple rules to the same endpoint. That's the most straightforward solution.


If you want one rule, you can write a custom converter to capture either the empty string or arbitrary data beginning with a slash.

from flask import Flask
from werkzeug.routing import BaseConverter

class WildcardConverter(BaseConverter):
regex = r'(|/.*?)'
weight = 200

app = Flask(__name__)
app.url_map.converters['wildcard'] = WildcardConverter

@app.route('/users<wildcard:path>')
def users(path):
return path

c = app.test_client()
print(c.get('/users').data) # b''
print(c.get('/users-no-prefix').data) # (404 NOT FOUND)
print(c.get('/users/').data) # b'/'
print(c.get('/users/400617/edit').data) # b'/400617/edit'

If you actually want to match anything prefixed with /users, for example /users-no-slash/test, change the rule to be more permissive: regex = r'.*?'.

How to capture arbitrary paths at one route in FastAPI?

Since FastAPI is based on Starlette, you can use what they call "converters" with your route parameters, using type path in this case, which "returns the rest of the path, including any additional / characers."

See https://www.starlette.io/routing/#path-parameters for reference.

If your react (or vue or ...) app is using a base path, you can do something like this, which assigns anything after /my-app/ to the rest_of_path variable:

@app.get("/my-app/{rest_of_path:path}")
async def serve_my_app(request: Request, rest_of_path: str):
print("rest_of_path: "+rest_of_path)
return templates.TemplateResponse("index.html", {"request": request})

If you are not using a unique base path like /my-app/ (which seems to be your use case), you can still accomplish this with a catch-all route, which should go after any other routes so that it doesn't overwrite them:

@app.route("/{full_path:path}")
async def catch_all(request: Request, full_path: str):
print("full_path: "+full_path)
return templates.TemplateResponse("index.html", {"request": request})

(In fact you would want to use this catch-all regardless in order to catch the difference between requests for /my-app/ and /my-app)

In python flask, how do you get the path parameters outside of the route function?

It's possible to use request.view_args.
The documentation defines it this way:

A dict of view arguments that matched the request.

Here's an example:

@app.route("/data/<section>")
def data(section):
assert section == request.view_args['section']

Flask: why having path converter in root route doesn't work?

static_url_path conflicts with routing. Flask thinks that path after / is reserved for static files, therefore path converter didn't work. See: URL routing conflicts for static files in Flask dev server

Pass file path as parameter in Flask app.route()

Try this:

@app.route('/<a>/<b>/<c>/<d>/<e>/<path:f>')

See: http://flask.pocoo.org/snippets/76/

Cast a dynamic Flask URL route path to string

You forgot @ before routing decorators. Change it this way:

@app.route('/')
@app.route('/<path:path>')

and it will work.



Related Topics



Leave a reply



Submit