Is there a way to have FastAPI treat a parameter the same if it does or does not have a trailing / ?
I want to replicate this in a more concise manner and/or configure FastAPI so I don't have to do this for each path similarly
@app.post("/extract")
@app.post("/extract/")
async def create_extraction(...):
EDIT: simplified example code
What version of fastapi are you using? As of 0.50.0 the trailing slash should be automatically stripped now that fastapi's using the latest version of starlette.
Also for what it's worth, even without that feature you could always do something like this:
@app.post("/extract/?")
async def create_extraction(...):
since routes can take regexes.
[RESOLVED]
@jmriebold we're unfortunately pinned on version 0.47.1
I wasn't aware that FastAPI supported regex. Awesome! Thanks!
Thanks for the help @jmriebold ! :bowing_man:
Thanks for reporting back and closing the issue @mwilson8 :+1:
FYI, @jmriebold I don't think path routes can take regex's anymore like this.
Since Starlette version 0.13.5 regex is escaped. See the PR here: https://github.com/encode/starlette/pull/932 and further discussion here: https://github.com/encode/starlette/pull/1010
also... in my testing, Starlette is flexible about the trailing slash (and i think by extension fastapi) so you shouldn't need the trailing ?.
Yeah, I noticed that too. Appears to be the case that regexes were never intentionally supported, it was just an artifact of how paths were constructed.
It seems like the best option is to just allow Starlette to do the redirect for you, so long as you are okay with redirects. Note, that curl usually doesn't automatically redirect. And neither does requests for POSTs. So there are some valid reasons to not want your users to have to deal with redirects if you have routes they are using programmatically.
If you don't want the redirect, I think the other option is using multiple decorators as suggested in the original question.
I wish Starlette didn't perform a redirect but just directly accessed the other route, if it matched it. There's probably a good reason they don't do this, though.
Yeah I personally thought regexes were an elegant way to do it, but have since switched to an explicit redirect route.
I think this Starlette release broke a lot of services (including mine), and forces us to choose between ugly
@router.get("/block", response_model=pydantic_models.BlockResponse)
@router.get("/block/", response_model=pydantic_models.BlockResponse)
async def blocks(request: Request):
...
And ugly
def slash_patcher(app):
app.router.redirect_slashes = False
routes = copy.deepcopy(app.router.routes)
for r in routes:
if r.path.endswith("/"):
app.add_route(r.path.rstrip("/"), ...)
else:
app.add_route(r.path + "/", ...)
Maybe we can fix it somehow in general way?
Thanks for sharing your slash patcher.
Perhaps a pull request or new issue would get the ball rolling?
I don't think this is a good solution: for example /docs become a mess:

Yea, pretty gross. I also think this is probably easier handled in Starlette
In our team we decided to patch proxy-server for all our FastAPI applications: it ensures that every request does not contain \ at the end of path. (otherwise it just removes slashes) :|
Most helpful comment
What version of fastapi are you using? As of 0.50.0 the trailing slash should be automatically stripped now that fastapi's using the latest version of starlette.
Also for what it's worth, even without that feature you could always do something like this:
since routes can take regexes.