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
What Is the Fastest Way to Open Urls in New Tabs via Selenium - Python
Is There Any Difference Between "Foo Is None" and "Foo == None"
Python How to Pad Numpy Array with Zeros
Importing from a Relative Path in Python
What's the Best Way to Find the Inverse of Datetime.Isocalendar()
Bin Elements Per Row - Vectorized 2D Bincount for Numpy
Store Mouse Click Event Coordinates with Matplotlib
How to Overwrite/Print Over the Current Line in Windows Command Line
When Are Objects Garbage Collected in Python
Processing Single File from Multiple Processes
How to Prevent Errno 32 Broken Pipe
Plotting 3D Polygons in Python-Matplotlib
List of Dicts To/From Dict of Lists
Drawing Lines Between Two Plots in Matplotlib
Matplotlib and Ipython-Notebook: Displaying Exactly the Figure That Will Be Saved