[BUG] function name that is decorated by route controls if route can be matched or not rather than the route
Closed this issue · 3 comments
Describe the bug
I get an error starlette.routing.NoMatchFound: No route exists for name "get_lesson" and params "".
if the function name that is decorated by @app.route
does not match the get=
argument in a component.
for example, in the below cascading dropdowns example I want to show a different dropdown based on the selection in an initial dropdown. The function name get_lesson_bug
, is incompatible with get=get_lesson
and causes the NoMatchFound error. If I change the function name to get_lesson
it works, but this is unexpected behavior.
Minimal Reproducible Example
from fasthtml.common import *
app, rt = fast_app()
chapters = ['ch1', 'ch2', 'ch3']
lessons = {
'ch1': ['lesson1', 'lesson2', 'lesson3'],
'ch2': ['lesson4', 'lesson5', 'lesson6'],
}
def mk_opts(nm, cs):
return (
Option(f'-- select {nm} --', disabled='', selected='', value=''),
*map(Option, cs))
@app.get('/get_lesson')
def get_lesson_bug(chapter: str):
return Select(*mk_opts('lesson', lessons[chapter]), name='lesson')
@app.get('/')
def homepage():
chapter_dropdown = Select(
*mk_opts('chapter', chapters),
name='chapter',
get='get_lesson', hx_target='#lesson')
return Div(
Div(
Label("Chapter:", for_="chapter"),
chapter_dropdown),
Div(
Label("Lesson:", for_="lesson"),
Div(Div(id='lesson')),
))
serve()
removing _bug
allows the route to be found
Expected behavior
If I use the function name get_lesson_bug
, with @app.get('/get_lesson')
I expect the argument get=get_lesson
to use the value supplied to @app.get
not the function name. similar to how values are passed to hx_post that refer to routes.
Environment Information
Please provide the following version information:
- fastlite version: 0.0.9
- fastcore version: 1.7.8
- fasthtml version: 0.6.4
Confirmation
Please confirm the following:
- I have read the FAQ (https://docs.fastht.ml/explains/faq.html)
- I have provided a minimal reproducible example
- I have included the versions of fastlite, fastcore, and fasthtml
- I understand that this is a volunteer open source project with no commercial support.
Additional context
the docs for @app.get()
say
In the previous example, the function name (get_nm) didn’t actually matter – we could have just called it _, for instance, since we never actually call it directly. It’s just called through HTTP. In fact, we often do call our functions _ when using this style of route, since that’s one less thing we have to worry about, naming.
so I think the issue above illustrates there is a conflict with the docs https://docs.fastht.ml/explains/routes.html
@pydanny you want to look at this one? (@Isaac-Flath could possibly help point you in the right direction)
@pydanny @jph00 Based on my understanding, I don't think this is a bug, but here are my thoughts and some background. Let me know if I am misunderstanding something.
get
and post
take route names as the argument. The default name of a route is the function name, but you can name it something different via @app.get('/get_lesson',name='myCustomName')
. However, in the example provided in this issue the name
of the route is get_lesson_bug
because the default route name is the python function name (no name was passed to @app.get
)
hx_get
and hx_post
take routes as arguments so that you can specify routes. You could do hx_get='/get_lesson'
, which would route it to the /get_lesson
route. You could also do hx_get='get_lesson'
, which would route it to the same place unless you're doing something special with mounting (it's like a relative path without the leading /
). But in both these cases, it refers to the route path and not the route's name.
I think using the function name as the route name is a good default. Otherwise, we need to transform the route to a valid python name, such as replacing slashes with underscores or something and removing {params}
. I think it's clearer to have the default route name be the python function name.
Oh right thanks @Isaac-Flath -- in the version @rbavery shared on Discord I thought the names matched. But perhaps it was just a misunderstanding. I'll close this issue, but feel free to reopen it if it still doesn't work when the function name matches the get
value.