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,