Skip to content

Commit b1c1ef0

Browse files
authored
Merge pull request #694 from AnswerDotAI/fix-missing-param-bug
update `_formitem` so that it doesn't raise `KeyError`
2 parents 0ab40c3 + 166c36a commit b1c1ef0

File tree

2 files changed

+81
-5
lines changed

2 files changed

+81
-5
lines changed

fasthtml/core.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -131,7 +131,7 @@ def _is_body(anno): return issubclass(anno, (dict,ns)) or _annotations(anno)
131131
# %% ../nbs/api/00_core.ipynb
132132
def _formitem(form, k):
133133
"Return single item `k` from `form` if len 1, otherwise return list"
134-
if isinstance(form, dict): return form[k]
134+
if isinstance(form, dict): return form.get(k)
135135
o = form.getlist(k)
136136
return o[0] if len(o) == 1 else o if o else None
137137

nbs/api/00_core.ipynb

Lines changed: 80 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -131,7 +131,7 @@
131131
{
132132
"data": {
133133
"text/plain": [
134-
"datetime.datetime(2025, 3, 16, 14, 0)"
134+
"datetime.datetime(2025, 3, 28, 14, 0)"
135135
]
136136
},
137137
"execution_count": null,
@@ -487,7 +487,7 @@
487487
"#| export\n",
488488
"def _formitem(form, k):\n",
489489
" \"Return single item `k` from `form` if len 1, otherwise return list\"\n",
490-
" if isinstance(form, dict): return form[k]\n",
490+
" if isinstance(form, dict): return form.get(k)\n",
491491
" o = form.getlist(k)\n",
492492
" return o[0] if len(o) == 1 else o if o else None"
493493
]
@@ -713,6 +713,82 @@
713713
"print(response.text)"
714714
]
715715
},
716+
{
717+
"cell_type": "markdown",
718+
"id": "34066c89",
719+
"metadata": {},
720+
"source": [
721+
"**Missing Request Params**"
722+
]
723+
},
724+
{
725+
"cell_type": "markdown",
726+
"id": "06259883",
727+
"metadata": {},
728+
"source": [
729+
"If a request param has a default value (e.g. `a:str=''`), the request is valid even if the user doesn't include the param in their request."
730+
]
731+
},
732+
{
733+
"cell_type": "code",
734+
"execution_count": null,
735+
"id": "c369a89c",
736+
"metadata": {},
737+
"outputs": [
738+
{
739+
"name": "stdout",
740+
"output_type": "stream",
741+
"text": [
742+
"[<starlette.requests.Request object>, <starlette.applications.Starlette object>, '']\n"
743+
]
744+
}
745+
],
746+
"source": [
747+
"def g(req, this:Starlette, a:str=''): ...\n",
748+
"\n",
749+
"async def f(req):\n",
750+
" a = await _wrap_req(req, _params(g))\n",
751+
" return Response(str(a))\n",
752+
"\n",
753+
"client = TestClient(Starlette(routes=[Route('/', f, methods=['POST'])]))\n",
754+
"response = client.post('/', json={}) # no param in request\n",
755+
"print(response.text)"
756+
]
757+
},
758+
{
759+
"cell_type": "markdown",
760+
"id": "35b68f4f",
761+
"metadata": {},
762+
"source": [
763+
"If we remove the default value and re-run the request, we should get the following error `Missing required field: a`."
764+
]
765+
},
766+
{
767+
"cell_type": "code",
768+
"execution_count": null,
769+
"id": "b33b43a7",
770+
"metadata": {},
771+
"outputs": [
772+
{
773+
"name": "stdout",
774+
"output_type": "stream",
775+
"text": [
776+
"Missing required field: a\n"
777+
]
778+
}
779+
],
780+
"source": [
781+
"def g(req, this:Starlette, a:str): ...\n",
782+
"\n",
783+
"async def f(req):\n",
784+
" a = await _wrap_req(req, _params(g))\n",
785+
" return Response(str(a))\n",
786+
"\n",
787+
"client = TestClient(Starlette(routes=[Route('/', f, methods=['POST'])]))\n",
788+
"response = client.post('/', json={}) # no param in request\n",
789+
"print(response.text)"
790+
]
791+
},
716792
{
717793
"cell_type": "code",
718794
"execution_count": null,
@@ -3342,9 +3418,9 @@
33423418
],
33433419
"metadata": {
33443420
"kernelspec": {
3345-
"display_name": "python3",
3421+
"display_name": "python",
33463422
"language": "python",
3347-
"name": "python3"
3423+
"name": "python"
33483424
}
33493425
},
33503426
"nbformat": 4,

0 commit comments

Comments
 (0)