Skip to content

Commit 213ec14

Browse files
committed
fix failing form parsing test
1 parent 33c4b1f commit 213ec14

File tree

2 files changed

+23
-55
lines changed

2 files changed

+23
-55
lines changed

fasthtml/core.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -127,7 +127,7 @@ async def _from_body(req, p):
127127
anno = p.annotation
128128
# Get the fields and types of type `anno`, if available
129129
d = _annotations(anno)
130-
cargs = {k:_form_arg(k, v, d) for k,v in form2dict(form).items()}
130+
cargs = {k:_form_arg(k, v, d) for k,v in form2dict(form).items() if not d or k in d}
131131
return anno(**cargs)
132132

133133
# %% ../nbs/00_core.ipynb 37

nbs/00_core.ipynb

Lines changed: 22 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -145,7 +145,7 @@
145145
{
146146
"data": {
147147
"text/plain": [
148-
"datetime.datetime(2024, 7, 17, 14, 0)"
148+
"datetime.datetime(2024, 7, 18, 14, 0)"
149149
]
150150
},
151151
"execution_count": null,
@@ -595,7 +595,7 @@
595595
" anno = p.annotation\n",
596596
" # Get the fields and types of type `anno`, if available\n",
597597
" d = _annotations(anno)\n",
598-
" cargs = {k:_form_arg(k, v, d) for k,v in form2dict(form).items()}\n",
598+
" cargs = {k:_form_arg(k, v, d) for k,v in form2dict(form).items() if not d or k in d}\n",
599599
" return anno(**cargs)"
600600
]
601601
},
@@ -1033,7 +1033,7 @@
10331033
{
10341034
"data": {
10351035
"text/plain": [
1036-
"'2c25d03b-24f2-4946-833a-50ac832a1576'"
1036+
"'08b63b51-be3a-4f54-8d26-4cd27eb17c0d'"
10371037
]
10381038
},
10391039
"execution_count": null,
@@ -1463,33 +1463,10 @@
14631463
"outputs": [],
14641464
"source": [
14651465
"@app.post('/profile/me')\n",
1466-
"def profile_update(username: str): return username"
1467-
]
1468-
},
1469-
{
1470-
"cell_type": "code",
1471-
"execution_count": null,
1472-
"id": "277b1db0",
1473-
"metadata": {},
1474-
"outputs": [],
1475-
"source": [
1476-
"# Working post request, this is our control\n",
1477-
"test_r(cli, '/profile/me', 'Alexis', 'post',\n",
1478-
" data={'username' : 'Alexis'})"
1479-
]
1480-
},
1481-
{
1482-
"cell_type": "code",
1483-
"execution_count": null,
1484-
"id": "93d18dfa",
1485-
"metadata": {},
1486-
"outputs": [],
1487-
"source": [
1488-
"# Failing post request due to missing required username parameter\n",
1489-
"try:\n",
1490-
" test_r(cli, '/profile/me', 'Alexis', 'post', data={})\n",
1491-
"except AssertionError as e:\n",
1492-
" assert \"Missing required field: username\" in str(e)"
1466+
"def profile_update(username: str): return username\n",
1467+
"\n",
1468+
"test_r(cli, '/profile/me', 'Alexis', 'post', data={'username' : 'Alexis'})\n",
1469+
"test_r(cli, '/profile/me', 'Missing required field: username', 'post', data={})"
14931470
]
14941471
},
14951472
{
@@ -1517,14 +1494,14 @@
15171494
"@dataclass\n",
15181495
"class Bodie: a:int;b:str\n",
15191496
"\n",
1520-
"@rt(\"/bodie/{nm}/\")\n",
1497+
"@rt(\"/bodie/{nm}\")\n",
15211498
"async def post(nm:str, data:Bodie):\n",
15221499
" res = asdict(data)\n",
15231500
" res['nm'] = nm\n",
15241501
" return res\n",
15251502
"\n",
15261503
"@app.post(\"/bodied/\")\n",
1527-
"async def bodied(nm:str, data:dict): return data\n",
1504+
"async def bodied(data:dict): return data\n",
15281505
"\n",
15291506
"nt = namedtuple('Bodient', ['a','b'])\n",
15301507
"\n",
@@ -1549,28 +1526,11 @@
15491526
"execution_count": null,
15501527
"id": "48f0a45e",
15511528
"metadata": {},
1552-
"outputs": [
1553-
{
1554-
"ename": "AssertionError",
1555-
"evalue": "==:\nNot Found\n{\"a\":1,\"b\":\"foo\",\"nm\":\"me\"}",
1556-
"output_type": "error",
1557-
"traceback": [
1558-
"\u001b[0;31m---------------------------------------------------------------------------\u001b[0m",
1559-
"\u001b[0;31mAssertionError\u001b[0m Traceback (most recent call last)",
1560-
"Cell \u001b[0;32mIn[89], line 3\u001b[0m\n\u001b[1;32m 1\u001b[0m d \u001b[38;5;241m=\u001b[39m \u001b[38;5;28mdict\u001b[39m(a\u001b[38;5;241m=\u001b[39m\u001b[38;5;241m1\u001b[39m, b\u001b[38;5;241m=\u001b[39m\u001b[38;5;124m'\u001b[39m\u001b[38;5;124mfoo\u001b[39m\u001b[38;5;124m'\u001b[39m)\n\u001b[0;32m----> 3\u001b[0m \u001b[43mtest_r\u001b[49m\u001b[43m(\u001b[49m\u001b[43mcli\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;124;43m'\u001b[39;49m\u001b[38;5;124;43m/bodie/me\u001b[39;49m\u001b[38;5;124;43m'\u001b[39;49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;124;43m'\u001b[39;49m\u001b[38;5;124;43m{\u001b[39;49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[38;5;124;43ma\u001b[39;49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[38;5;124;43m:1,\u001b[39;49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[38;5;124;43mb\u001b[39;49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[38;5;124;43m:\u001b[39;49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[38;5;124;43mfoo\u001b[39;49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[38;5;124;43m,\u001b[39;49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[38;5;124;43mnm\u001b[39;49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[38;5;124;43m:\u001b[39;49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[38;5;124;43mme\u001b[39;49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[38;5;124;43m}\u001b[39;49m\u001b[38;5;124;43m'\u001b[39;49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;124;43m'\u001b[39;49m\u001b[38;5;124;43mpost\u001b[39;49m\u001b[38;5;124;43m'\u001b[39;49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mdata\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43md\u001b[49m\u001b[43m)\u001b[49m\n\u001b[1;32m 4\u001b[0m \u001b[38;5;66;03m# This test should not be working, as the \"nm\" arguement isn't provided and there isn't a default\u001b[39;00m\n\u001b[1;32m 5\u001b[0m test_r(cli, \u001b[38;5;124m'\u001b[39m\u001b[38;5;124m/bodied/\u001b[39m\u001b[38;5;124m'\u001b[39m, \u001b[38;5;124m'\u001b[39m\u001b[38;5;124m{\u001b[39m\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124ma\u001b[39m\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124m:\u001b[39m\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124m1\u001b[39m\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124m,\u001b[39m\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mb\u001b[39m\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124m:\u001b[39m\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mfoo\u001b[39m\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124m}\u001b[39m\u001b[38;5;124m'\u001b[39m, \u001b[38;5;124m'\u001b[39m\u001b[38;5;124mpost\u001b[39m\u001b[38;5;124m'\u001b[39m, data\u001b[38;5;241m=\u001b[39md)\n",
1561-
"Cell \u001b[0;32mIn[66], line 3\u001b[0m, in \u001b[0;36mtest_r\u001b[0;34m(cli, path, exp, meth, hx, **kwargs)\u001b[0m\n\u001b[1;32m 1\u001b[0m \u001b[38;5;28;01mdef\u001b[39;00m \u001b[38;5;21mtest_r\u001b[39m(cli, path, exp, meth\u001b[38;5;241m=\u001b[39m\u001b[38;5;124m'\u001b[39m\u001b[38;5;124mget\u001b[39m\u001b[38;5;124m'\u001b[39m, hx\u001b[38;5;241m=\u001b[39m\u001b[38;5;28;01mFalse\u001b[39;00m, \u001b[38;5;241m*\u001b[39m\u001b[38;5;241m*\u001b[39mkwargs):\n\u001b[1;32m 2\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m hx: kwargs[\u001b[38;5;124m'\u001b[39m\u001b[38;5;124mheaders\u001b[39m\u001b[38;5;124m'\u001b[39m] \u001b[38;5;241m=\u001b[39m {\u001b[38;5;124m'\u001b[39m\u001b[38;5;124mhx-request\u001b[39m\u001b[38;5;124m'\u001b[39m:\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124m1\u001b[39m\u001b[38;5;124m\"\u001b[39m}\n\u001b[0;32m----> 3\u001b[0m \u001b[43mtest_eq\u001b[49m\u001b[43m(\u001b[49m\u001b[38;5;28;43mgetattr\u001b[39;49m\u001b[43m(\u001b[49m\u001b[43mcli\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mmeth\u001b[49m\u001b[43m)\u001b[49m\u001b[43m(\u001b[49m\u001b[43mpath\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;241;43m*\u001b[39;49m\u001b[38;5;241;43m*\u001b[39;49m\u001b[43mkwargs\u001b[49m\u001b[43m)\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mtext\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mexp\u001b[49m\u001b[43m)\u001b[49m\n",
1562-
"File \u001b[0;32m~/.virtualenvs/fasthtml/lib/python3.10/site-packages/fastcore-1.5.51-py3.10.egg/fastcore/test.py:37\u001b[0m, in \u001b[0;36mtest_eq\u001b[0;34m(a, b)\u001b[0m\n\u001b[1;32m 35\u001b[0m \u001b[38;5;28;01mdef\u001b[39;00m \u001b[38;5;21mtest_eq\u001b[39m(a,b):\n\u001b[1;32m 36\u001b[0m \u001b[38;5;124m\"\u001b[39m\u001b[38;5;124m`test` that `a==b`\u001b[39m\u001b[38;5;124m\"\u001b[39m\n\u001b[0;32m---> 37\u001b[0m \u001b[43mtest\u001b[49m\u001b[43m(\u001b[49m\u001b[43ma\u001b[49m\u001b[43m,\u001b[49m\u001b[43mb\u001b[49m\u001b[43m,\u001b[49m\u001b[43mequals\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mcname\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[38;5;124;43m'\u001b[39;49m\u001b[38;5;124;43m==\u001b[39;49m\u001b[38;5;124;43m'\u001b[39;49m\u001b[43m)\u001b[49m\n",
1563-
"File \u001b[0;32m~/.virtualenvs/fasthtml/lib/python3.10/site-packages/fastcore-1.5.51-py3.10.egg/fastcore/test.py:27\u001b[0m, in \u001b[0;36mtest\u001b[0;34m(a, b, cmp, cname)\u001b[0m\n\u001b[1;32m 25\u001b[0m \u001b[38;5;124m\"\u001b[39m\u001b[38;5;124m`assert` that `cmp(a,b)`; display inputs and `cname or cmp.__name__` if it fails\u001b[39m\u001b[38;5;124m\"\u001b[39m\n\u001b[1;32m 26\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m cname \u001b[38;5;129;01mis\u001b[39;00m \u001b[38;5;28;01mNone\u001b[39;00m: cname\u001b[38;5;241m=\u001b[39mcmp\u001b[38;5;241m.\u001b[39m\u001b[38;5;18m__name__\u001b[39m\n\u001b[0;32m---> 27\u001b[0m \u001b[38;5;28;01massert\u001b[39;00m cmp(a,b),\u001b[38;5;124mf\u001b[39m\u001b[38;5;124m\"\u001b[39m\u001b[38;5;132;01m{\u001b[39;00mcname\u001b[38;5;132;01m}\u001b[39;00m\u001b[38;5;124m:\u001b[39m\u001b[38;5;130;01m\\n\u001b[39;00m\u001b[38;5;132;01m{\u001b[39;00ma\u001b[38;5;132;01m}\u001b[39;00m\u001b[38;5;130;01m\\n\u001b[39;00m\u001b[38;5;132;01m{\u001b[39;00mb\u001b[38;5;132;01m}\u001b[39;00m\u001b[38;5;124m\"\u001b[39m\n",
1564-
"\u001b[0;31mAssertionError\u001b[0m: ==:\nNot Found\n{\"a\":1,\"b\":\"foo\",\"nm\":\"me\"}"
1565-
]
1566-
}
1567-
],
1529+
"outputs": [],
15681530
"source": [
15691531
"d = dict(a=1, b='foo')\n",
15701532
"\n",
1571-
"test_r(cli, '/bodie/me', '{\"a\":1,\"b\":\"foo\",\"nm\":\"me\"}', 'post', data=d)\n",
1572-
"# This test should not be working, as the \"nm\" arguement isn't\n",
1573-
"# provided and there isn't a default\n",
1533+
"test_r(cli, '/bodie/me', '{\"a\":1,\"b\":\"foo\",\"nm\":\"me\"}', 'post', data=dict(a=1, b='foo', nm='me'))\n",
15741534
"test_r(cli, '/bodied/', '{\"a\":\"1\",\"b\":\"foo\"}', 'post', data=d)\n",
15751535
"test_r(cli, '/bodie2/', 'a: 1; b: foo', 'post', data={'a':1})\n",
15761536
"test_r(cli, '/bodient/', '{\"a\":\"1\",\"b\":\"foo\"}', 'post', data=d)\n",
@@ -1607,7 +1567,7 @@
16071567
{
16081568
"data": {
16091569
"text/plain": [
1610-
"'Cookie was set at time 23:41:43.695239'"
1570+
"'Cookie was set at time 16:31:31.377931'"
16111571
]
16121572
},
16131573
"execution_count": null,
@@ -1648,13 +1608,13 @@
16481608
"name": "stdout",
16491609
"output_type": "stream",
16501610
"text": [
1651-
"Set to 2024-07-17 23:41:43.724183\n"
1611+
"Set to 2024-07-18 16:31:31.423484\n"
16521612
]
16531613
},
16541614
{
16551615
"data": {
16561616
"text/plain": [
1657-
"'Session time: 23:41:43.724183'"
1617+
"'Session time: 16:31:31.423484'"
16581618
]
16591619
},
16601620
"execution_count": null,
@@ -1786,6 +1746,14 @@
17861746
"#|hide\n",
17871747
"import nbdev; nbdev.nbdev_export()"
17881748
]
1749+
},
1750+
{
1751+
"cell_type": "code",
1752+
"execution_count": null,
1753+
"id": "5d9d25c7",
1754+
"metadata": {},
1755+
"outputs": [],
1756+
"source": []
17891757
}
17901758
],
17911759
"metadata": {

0 commit comments

Comments
 (0)