Describe the bug
It looks like Starlette's routes are not populating self.param_convertors
so, when using request.url_for
and passing query parameters, the route does not match (I think this is the code) and url_for
fails with a NoMatchFound
To Reproduce
I think this view will do it, sorry if I've elided anything important:
@router.get("/", name='events_list')
def list_object(
offset: int = Query(0),
request: Request = Required
):
next = request.url_for('events_list', offset=42)
...
Expected behavior
I'd expect url_for
to return something like 'http://testserver/events/?offset=42'
Actual behavior
../diary/api/events.py:57: in list_object
next = request.url_for('events_list', offset=42)
/Users/chris/Library/Caches/pypoetry/virtualenvs/diary-py3.7/lib/python3.7/site-packages/starlette/requests.py:117: in url_for
url_path = router.url_path_for(name, **path_params)
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
self = <fastapi.routing.APIRouter object at 0x105e855f8>, name = 'events_list'
path_params = {'offset': 42}
route = <fastapi.routing.APIRoute object at 0x106c5ecf8>
def url_path_for(self, name: str, **path_params: str) -> URLPath:
for route in self.routes:
try:
return route.url_path_for(name, **path_params)
except NoMatchFound:
pass
> raise NoMatchFound()
E starlette.routing.NoMatchFound
Environment:
kind of remember having been bitten by this
worth trying to not use name but _name @router.get("/", _name='events_list')
edit: scrap that it was when I had name in the path
On Fri, Jun 21, 2019 at 9:27 AM Chris Withers notifications@github.com
wrote:
Describe the bug
It looks like Starlette's routes are not populating self.param_convertors
so, when using request.url_for and passing query parameters, the route
does not match (I think this is the code
https://github.com/encode/starlette/blob/8c8cc2ec0a5cb834a9a15b871ae8b480503abb67/starlette/routing.py#L190)
and url_for fails with a NoMatchFoundTo Reproduce
I think this view will do it, sorry if I've elided anything important:@router.get("/", name='events_list')
def list_object(
offset: int = Query(0),
request: Request = Required
):
next = request.url_for('events_list', offset=42)
...Expected behavior
I'd expect url_for to return something like '
http://testserver/events/?offset=42'Actual behavior
../diary/api/events.py:57: in list_object
next = request.url_for('events_list', offset=42)
/Users/chris/Library/Caches/pypoetry/virtualenvs/diary-py3.7/lib/python3.7/site-packages/starlette/requests.py:117: in url_for
url_path = router.url_path_for(name, **path_params)
self =
, name = 'events_list'
path_params = {'offset': 42}
route =def url_path_for(self, name: str, **path_params: str) -> URLPath: for route in self.routes: try: return route.url_path_for(name, **path_params) except NoMatchFound: pass
raise NoMatchFound()
E starlette.routing.NoMatchFound
Environment:
- FastAPI Version [e.g. 0.3.0], get it with: 0.30.0
—
You are receiving this because you are subscribed to this thread.
Reply to this email directly, view it on GitHub
https://github.com/tiangolo/fastapi/issues/323?email_source=notifications&email_token=AAINSPSFZHB2SRXYNPHHGGDP3R7G5A5CNFSM4H2NXBQKYY3PNVWWK3TUL52HS4DFUVEXG43VMWVGG33NNVSW45C7NFSM4G24THVQ,
or mute the thread
https://github.com/notifications/unsubscribe-auth/AAINSPV2YX74QQHVECCWAJTP3R7G5ANCNFSM4H2NXBQA
.
--
benoit barthelet
http://pgp.mit.edu/pks/lookup?op=get&search=0xF150E01A72F6D2EE
I see you discovered the problem and requested the feature here: https://github.com/encode/starlette/issues/560
So I'll close this issue now, as that would actually be a Starlette feature request.
For completeness, for anyone coming afterwards, request.url_for()
receives path parameters, not query parameters.
For anyone interested in doing this themselves, the following code may be useful.
https://gist.github.com/jacksmith15/b220686eae16d52a10ef59b5de09c213
This goes a bit further than starlette's feature request, as it leverages FastAPI's parameter validation to prevent bad URLs being generated.
Most helpful comment
I see you discovered the problem and requested the feature here: https://github.com/encode/starlette/issues/560
So I'll close this issue now, as that would actually be a Starlette feature request.
For completeness, for anyone coming afterwards,
request.url_for()
receives path parameters, not query parameters.