AnswerDotAI / AnswerDotAI/fasthtml
[BUG] Missing function type hints result in `None` for function inputs in FastHTML
- Dominant language
- Jupyter Notebook
- Stars
- 7k
- Forks
- 319
- Avg merge
- 28m
- Merged PRs (30d)
- 3
Description
## Description
When using FastHTML, omitting type hints for function parameters causes input values to default to None, resulting in a TypeError. This behavior is inconsistent with the expected functionality where inputs should retain their values regardless of type hints.
## Issue
Below is a sample code (adapted from [FastHTML Tutorials](https://docs.fastht.ml/tutorials/by_example.html#htmx)):
```python
import fasthtml.components as fh_components
from fasthtml.core import FastHTML, serve
app = FastHTML()
route = app.route
@app.get("/")
def home():
return fh_components.Form(
fh_components.Input(type="text", id="input_1", name="input 1"),
fh_components.Input(type="text", id="input_2", name="input 2"),
fh_components.Button("Submit", id="submit", hx_post="/submit", hx_target="#response"),
), fh_components.Div(id="response")
@app.post("/submit")
def demo_fn(input_1: str, input_2: str):
response = inp_1 + " " + inp_2
return response
serve()
```
The above code works perfectly!
but if we change the demo_fn removing the type hints as:
```python
@app.post("/submit")
def demo_fn(input_1, input_2):
response = inp_1 + " " + inp_2
return response
```
This throws error:
```
File "/workspaces/demoapp/test.py", line 17, in demo_fn
response = inp_1 + " " + inp_2
~~~~~~^~~~~
TypeError: unsupported operand type(s) for +: 'NoneType' and 'str'
```
on debugging, we found that missing types are making the values `None` for some weird reason.
This must be a bug in how fastHTL handles the data!
## Expected behavior
FastHTML should not convert the function inputs to `None` if the function input param type hints are missing.
## Found workaround/fix
A workaround was found, by tapping into the form request. but this should work without this hack/workaround.
here is the workaround:
```python
import fasthtml.components as fh_components
from fasthtml.core import FastHTML, serve, Request
app = FastHTML()
route = app.route
@app.get("/")
def home():
return fh_components.Form(
fh_components.Input(type="text", id="input_1", name="input 1"),
fh_components.Input(type="text", id="input_2", name="input 2"),
fh_components.Button("Submit", id="submit", hx_post="/submit", hx_target="#response"),
), fh_components.Div(id="response")
@app.post("/submit")
async def demo_fn(request: Request):
form_data = await request.form()
input_1 = form_data.get("input_1")
input_2 = form_data.get("input_2")
return input_1 + input_2
serve()
```
PS: discovered this bug & workaround while working on a project with @soumik12345
Contributor guide
Research direction
Start by reproducing the issue with the FastHTML route and demo_fn entry points shown in the report, comparing parameter binding with and without type annotations. Inspect how FastHTML handles the Request and route parameters, then verify that unannotated form inputs retain their submitted values without the workaround.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- python
- Domain
- backend
- Issue type
- Bug
- Difficulty
- 3/5
- Estimated time
- 1-2 days
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 35/100