Fastapi: [QUESTION] trailing slash in parameter vs non

Created on 17 Mar 2020  路  12Comments  路  Source: tiangolo/fastapi

First check

  • [x] I used the GitHub search to find a similar issue and didn't find it.
  • [x] I searched the FastAPI documentation, with the integrated search.
  • [x] I already searched in Google "How to X in FastAPI" and didn't find any information.

Description

Is there a way to have FastAPI treat a parameter the same if it does or does not have a trailing / ?

Additional context

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

question

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:

@app.post("/extract/?")
async def create_extraction(...):

since routes can take regexes.

All 12 comments

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:

image

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) :|

Was this page helpful?
0 / 5 - 0 ratings