diff --git a/fasthtml/core.py b/fasthtml/core.py
index f734d97d..1b7f076f 100644
--- a/fasthtml/core.py
+++ b/fasthtml/core.py
@@ -131,7 +131,7 @@ def _is_body(anno): return issubclass(anno, (dict,ns)) or _annotations(anno)
# %% ../nbs/api/00_core.ipynb
def _formitem(form, k):
"Return single item `k` from `form` if len 1, otherwise return list"
- if isinstance(form, dict): return form[k]
+ if isinstance(form, dict): return form.get(k)
o = form.getlist(k)
return o[0] if len(o) == 1 else o if o else None
diff --git a/nbs/api/00_core.ipynb b/nbs/api/00_core.ipynb
index 217039cf..f2b8c4b4 100644
--- a/nbs/api/00_core.ipynb
+++ b/nbs/api/00_core.ipynb
@@ -131,7 +131,7 @@
{
"data": {
"text/plain": [
- "datetime.datetime(2025, 3, 16, 14, 0)"
+ "datetime.datetime(2025, 3, 28, 14, 0)"
]
},
"execution_count": null,
@@ -487,7 +487,7 @@
"#| export\n",
"def _formitem(form, k):\n",
" \"Return single item `k` from `form` if len 1, otherwise return list\"\n",
- " if isinstance(form, dict): return form[k]\n",
+ " if isinstance(form, dict): return form.get(k)\n",
" o = form.getlist(k)\n",
" return o[0] if len(o) == 1 else o if o else None"
]
@@ -713,6 +713,82 @@
"print(response.text)"
]
},
+ {
+ "cell_type": "markdown",
+ "id": "34066c89",
+ "metadata": {},
+ "source": [
+ "**Missing Request Params**"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "06259883",
+ "metadata": {},
+ "source": [
+ "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."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "c369a89c",
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "[, , '']\n"
+ ]
+ }
+ ],
+ "source": [
+ "def g(req, this:Starlette, a:str=''): ...\n",
+ "\n",
+ "async def f(req):\n",
+ " a = await _wrap_req(req, _params(g))\n",
+ " return Response(str(a))\n",
+ "\n",
+ "client = TestClient(Starlette(routes=[Route('/', f, methods=['POST'])]))\n",
+ "response = client.post('/', json={}) # no param in request\n",
+ "print(response.text)"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "35b68f4f",
+ "metadata": {},
+ "source": [
+ "If we remove the default value and re-run the request, we should get the following error `Missing required field: a`."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "b33b43a7",
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "Missing required field: a\n"
+ ]
+ }
+ ],
+ "source": [
+ "def g(req, this:Starlette, a:str): ...\n",
+ "\n",
+ "async def f(req):\n",
+ " a = await _wrap_req(req, _params(g))\n",
+ " return Response(str(a))\n",
+ "\n",
+ "client = TestClient(Starlette(routes=[Route('/', f, methods=['POST'])]))\n",
+ "response = client.post('/', json={}) # no param in request\n",
+ "print(response.text)"
+ ]
+ },
{
"cell_type": "code",
"execution_count": null,
@@ -3342,9 +3418,9 @@
],
"metadata": {
"kernelspec": {
- "display_name": "python3",
+ "display_name": "python",
"language": "python",
- "name": "python3"
+ "name": "python"
}
},
"nbformat": 4,