sanic: strict_slashes is not respected from the application level

Describe the bug This issue is porting from huge-success/sanic-openapi#102. When using Sanic(strict_slashes=True), it won’t be apply to any blueprint.

Code snippet

from sanic import Sanic, Blueprint
from sanic.response import text

app = Sanic(strict_slashes=True)


bp = Blueprint("bp")


@bp.get("/test")
async def test(request):
    return text("test")


app.blueprint(bp)

for route in app.router.routes_all:
    print(route)

Output:

/test
/test/

Expected behavior The strict_slashes in app level should be respected until user override it by setting Blueprint(..., strict_slashes=True) or in blueprint’s route level.

Environment (please complete the following information):

Additional context None

About this issue

  • Original URL
  • State: closed
  • Created 5 years ago
  • Comments: 16 (16 by maintainers)

Most upvoted comments

@chenjr0719 @ahopkins Agreed. I am changing the original PR to only include the changes required for addressing the strict_slashes option inheritance against the defined hierarchy.

As for the change of default behavior implemented currently, let me move that discussion to the thread in community and see what comes out of it.

I’m working on a new router idea that would, among other things, address this. So unless anyone else wants to address this separately, I’ll have a fix for this in my proposed router.

@harshanarayana

  1. If you want to override the strict_slashes behavior you can individually do that either at the route or BP level while creating the routes

  2. strict_slashes once applied at the BP or Application level are set for the lifetime of the object. So technically, DO NOT change this value once decided. You can override them individually at route level as required.

Totally agree both.

  1. If there is a strict_slashes=True anywhere in the hierarchy that we ultimately decide upon, every URL needs to terminate with a trailing / irrespective of how they are represented in the Route level.

I don’t think this is strict_slashes supposed to do. At current implementation, It depends on the uri of the route.

When the strict_slashes=False, no matter your uri ends with slash or not, it will create two endpoints, one with slash, another one without slash.

app = Sanic(strict_slashes=False)


@app.get("/test")
def test(request):
    return text("Test")


assert app.test_client.get("/test")[1].status == 200
assert app.test_client.get("/test/")[1].status == 200

When the strict_slashes=True and the uri ends without slash, there will be only one endpoint /test be created.

app = Sanic(strict_slashes=True)


@app.get("/test")
def test(request):
    return text("Test")


assert app.test_client.get("/test")[1].status == 200
assert app.test_client.get("/test/")[1].status == 404

In the other hand, when the uri ends with slash, it will be opposite to the above case.

app = Sanic(strict_slashes=True)


@app.get("/test/")
def test(request):
    return text("Test")


assert app.test_client.get("/test")[1].status == 404
assert app.test_client.get("/test/")[1].status == 200

I like your idea about when strict_slashes=True all uri should ends with slash. It can simplify most cases. But, it also changes the behavior of strict_slashes totally. I’m afraid it will cause a big impact to users.

I suggest to separate current discussion to two parts, one is about the override mechanism, another is how strict_slashes works.

  1. About the override mechanism, I think we both agree it should be route -> blueprint -> application.
  2. About how strict_slashes works, I have to say that we need more time and feedback to determine should we change it’s behavior or not. And I think this might also related to #1420.

@ahopkins Works for me. However, I just opened a new PR with WIP tag to address this + the other dependency issue. Take a look when you can and let me know your feedback. It’s pending few documentation changes

@chenjr0719

@chenjr0719 😉 Was just joking. When I am done with the POC for it (probably not till next week at the earliest), I will definitely be looking for as much feedback and thoughts as possible since it will potentially be a big change (I am trying to make sure there will not be any API changes though).

Cool, expecting your awesome work.