Starlette version 0.33.0 #2361
-
Hello, After upgrading to Starlette 0.33.0 I came across an issue using the The example you can run is this: from flask import Flask, request
from starlette.applications import Starlette
from starlette.routing import Mount, Route
from a2wsgi.wsgi import WSGIMiddleware
@flask_app.route("/")
def flask_main():
name = request.args.get("name", "Starlette")
return f"Hello, {escape(name)} from Flask!"
echo_paths_routes = [
Mount(
"/flask",
name="mount",
app=WSGIMiddleware(flask_app),
),
]
def test_paths_with_root_path(test_client_factory):
app = Starlette(routes=echo_paths_routes)
client = test_client_factory(app, base_url="https://www.example.org/")
response = client.get("/flask")
assert response.status_code == 200 This before the release was returning 200 but now its a simple 404. What Am I missing? For instance, I understand that FastAPI overrides the This also happens if you do a Starlette application and add it into the Example: app = Starlette(
routes=[Mount('/another', app=Starlette(...))]
) |
Beta Was this translation helpful? Give feedback.
Replies: 14 comments 16 replies
-
@Kludex not sure if you could help? |
Beta Was this translation helpful? Give feedback.
-
Apparently, this is also being reflected here. As far as I could also internally debug and based on the ASGI assumption that originated the new route_path , the final doesn't contain the root_path + path as per ASGI specification (as far as I could read) but this last one I can't be 100% sure as I haven't run a lot of tests on it but what it was reported by solara reflects exactly the errors I was also presenting here. |
Beta Was this translation helpful? Give feedback.
-
I need to investigate a bit. About solara, @maartenbreddels told me it was on them. 👀 |
Beta Was this translation helpful? Give feedback.
-
Thank you @Kludex . Solara I found yesterday and thankfully it is not Starlette then. The rest I literally had some tests using exactly the example I put here and since the last version, not passing anymore giving a 404. I will investigate more as well on my side and if I find any solution beforehand, I will share. |
Beta Was this translation helpful? Give feedback.
-
Still looking into it, what I currently see is that with starlette_routes = [
Route("/", endpoint=myroot),
Mount("/solara_mount/", routes=solara.server.starlette.routes),
]
starlette_app = Starlette(routes=starlette_routes) I never see |
Beta Was this translation helpful? Give feedback.
-
@maartenbreddels yes because before 0.33.0 the “path” and “root_path” were being set in the child_scope and now its “route_root_path” and “route_path” and actually that is what is blowing up a few of our cases too. When i changed (for testing) those new values to the previous version (path and root_path) in the child_scope, it started to work again. |
Beta Was this translation helpful? Give feedback.
-
@maartenbreddels this for testing to prove the new way works but in theory we should not do it, I think. @Kludex is investigating on his side as well and he is pretty good in these type of things 👍🏼 Another finding that I found is that the From the ef build_environ(scope: Scope, body: Body) -> Environ:
"""
Builds a scope and request body into a WSGI environ object.
"""
allow_rewrite_environ = {
"SCRIPT_NAME": scope.get("root_path", "").encode("utf8").decode("latin1"),
}
for key in allow_rewrite_environ.keys():
environ_var = os.environ.get(key, "")
if environ_var:
allow_rewrite_environ[key] = unicode_to_wsgi(environ_var)
environ = {
**allow_rewrite_environ,
"asgi.scope": scope,
"REQUEST_METHOD": scope["method"],
"PATH_INFO": scope["path"].encode("utf8").decode("latin1"),
"QUERY_STRING": scope["query_string"].decode("ascii"),
"SERVER_PROTOCOL": f"HTTP/{scope['http_version']}",
"wsgi.version": (1, 0),
"wsgi.url_scheme": scope.get("scheme", "http"),
"wsgi.input": body,
"wsgi.errors": sys.stdout,
"wsgi.multithread": True,
"wsgi.multiprocess": True,
"wsgi.run_once": False,
} This leads me to believe the |
Beta Was this translation helpful? Give feedback.
-
widgetti/solara#413 seems to work with starlette 0.32 and 0.33. Would love @Kludex 's opinion on this. |
Beta Was this translation helpful? Give feedback.
-
I agree @maartenbreddels mostly because the ASGI documentation also states the set of a I'm sure @Kludex has some insights on this and how we can fix without breaking an conformity with the ASGI references. Starlette prior to 0.33.0 has those and this is why it works for you and basically for all of us but there is more into it and lets allow @Kludex run his own investigation in the matter. |
Beta Was this translation helpful? Give feedback.
-
I wonder if root_path not being set is simply a bug in 0.33? Meaning that without root_path being set here in the test at https://github.com/encode/starlette/pull/2352/files#diff-d161c06bc3b5d600a6118ab40b4194a81d226f5f3fdbe17022dc501d823a4f95R1250 |
Beta Was this translation helpful? Give feedback.
-
Hm, not sure if it was a bug or simply removed because I can see an route_root_map that previously was the root_map but again, the team should know better about this |
Beta Was this translation helpful? Give feedback.
-
@maartenbreddels @Kludex after a lot of tests I still have the same errors. Everything that I posted here, the examples, the ASGI docs it's where is failing. 0.33.0 change is causing this. Not to put pressure, just to confirm that this causes an issue |
Beta Was this translation helpful? Give feedback.
-
@abersheeran do you know something obvious that I did wrong here? |
Beta Was this translation helpful? Give feedback.
-
@abersheeran I'm a little bit confused so apologies if I will say something wrong if I don't have the whole scope of the problem but according to the asgi read the docs The scope should contain "path" and "root_path" (let's ignore the right or wrong approach for this purpose). As far as I could see in the latest release of Starlette, that was renamed to "route_path" and "route_root_path" and passed into the scope. You mentioned above this now conforms with the ASGI spec. What am I missing here? Maybe I'm not understanding the whole problem but based on the image, it looks like it is not but again, I might be totally wrong (which is probably the case). Would you mind helping me understand what I'm not seeing, please? EDIT: Unless what I'm referring as child scope (in case of the mount) its just internal and then somewhere it builds the "path" and "root_path" in the final scope from those fields. |
Beta Was this translation helpful? Give feedback.
Yes, now the code should conform to the ASGI standard.