|
131 | 131 | {
|
132 | 132 | "data": {
|
133 | 133 | "text/plain": [
|
134 |
| - "datetime.datetime(2024, 10, 26, 14, 0)" |
| 134 | + "datetime.datetime(2024, 10, 28, 14, 0)" |
135 | 135 | ]
|
136 | 136 | },
|
137 | 137 | "execution_count": null,
|
|
487 | 487 | "#| export\n",
|
488 | 488 | "def _formitem(form, k):\n",
|
489 | 489 | " \"Return single item `k` from `form` if len 1, otherwise return list\"\n",
|
| 490 | + " if isinstance(form, dict): return form[k]\n", |
490 | 491 | " o = form.getlist(k)\n",
|
491 | 492 | " return o[0] if len(o) == 1 else o if o else None"
|
492 | 493 | ]
|
|
501 | 502 | "#| export\n",
|
502 | 503 | "def form2dict(form: FormData) -> dict:\n",
|
503 | 504 | " \"Convert starlette form data to a dict\"\n",
|
| 505 | + " if isinstance(form, dict): return form\n", |
504 | 506 | " return {k: _formitem(form, k) for k in form}"
|
505 | 507 | ]
|
506 | 508 | },
|
|
529 | 531 | "async def parse_form(req: Request) -> FormData:\n",
|
530 | 532 | " \"Starlette errors on empty multipart forms, so this checks for that situation\"\n",
|
531 | 533 | " ctype = req.headers.get(\"Content-Type\", \"\")\n",
|
| 534 | + " if ctype=='application/json': return await req.json()\n", |
532 | 535 | " if not ctype.startswith(\"multipart/form-data\"): return await req.form()\n",
|
533 | 536 | " try: boundary = ctype.split(\"boundary=\")[1].strip()\n",
|
534 | 537 | " except IndexError: raise HTTPException(400, \"Invalid form-data: no boundary\")\n",
|
|
550 | 553 | " anno = p.annotation\n",
|
551 | 554 | " # Get the fields and types of type `anno`, if available\n",
|
552 | 555 | " d = _annotations(anno)\n",
|
553 |
| - " if req.headers.get('content-type', None)=='application/json': data = await req.json()\n", |
554 |
| - " else: data = form2dict(await parse_form(req))\n", |
| 556 | + " data = form2dict(await parse_form(req))\n", |
555 | 557 | " if req.query_params: data = {**data, **dict(req.query_params)}\n",
|
556 | 558 | " cargs = {k: _form_arg(k, v, d) for k, v in data.items() if not d or k in d}\n",
|
557 | 559 | " return anno(**cargs)"
|
|
1541 | 1543 | "id": "b163c933",
|
1542 | 1544 | "metadata": {},
|
1543 | 1545 | "outputs": [
|
1544 |
| - { |
1545 |
| - "data": { |
1546 |
| - "text/html": [ |
1547 |
| - "<meta charset=\"utf-8\">\n", |
1548 |
| - "<meta name=\"viewport\" content=\"width=device-width, initial-scale=1, viewport-fit=cover\">\n", |
1549 |
| - "<script src=\"https://unpkg.com/htmx.org@next/dist/htmx.min.js\"></script><script src=\"https://cdn.jsdelivr.net/gh/answerdotai/fasthtml-js@1.0.4/fasthtml.js\"></script><script src=\"https://cdn.jsdelivr.net/gh/answerdotai/surreal@main/surreal.js\"></script><script src=\"https://cdn.jsdelivr.net/gh/gnat/css-scope-inline@main/script.js\"></script><script>\n", |
1550 |
| - " function sendmsg() {\n", |
1551 |
| - " window.parent.postMessage({height: document.documentElement.offsetHeight}, '*');\n", |
1552 |
| - " }\n", |
1553 |
| - " window.onload = function() {\n", |
1554 |
| - " sendmsg();\n", |
1555 |
| - " document.body.addEventListener('htmx:afterSettle', sendmsg);\n", |
1556 |
| - " document.body.addEventListener('htmx:wsAfterMessage', sendmsg);\n", |
1557 |
| - " };</script>" |
1558 |
| - ], |
1559 |
| - "text/plain": [ |
1560 |
| - "<IPython.core.display.HTML object>" |
1561 |
| - ] |
1562 |
| - }, |
1563 |
| - "metadata": {}, |
1564 |
| - "output_type": "display_data" |
1565 |
| - }, |
1566 | 1546 | {
|
1567 | 1547 | "data": {
|
1568 | 1548 | "text/plain": [
|
|
1612 | 1592 | "execution_count": null,
|
1613 | 1593 | "id": "645d8d95",
|
1614 | 1594 | "metadata": {},
|
1615 |
| - "outputs": [ |
1616 |
| - { |
1617 |
| - "data": { |
1618 |
| - "text/html": [ |
1619 |
| - "<meta charset=\"utf-8\">\n", |
1620 |
| - "<meta name=\"viewport\" content=\"width=device-width, initial-scale=1, viewport-fit=cover\">\n", |
1621 |
| - "<script src=\"https://unpkg.com/htmx.org@next/dist/htmx.min.js\"></script><script src=\"https://cdn.jsdelivr.net/gh/answerdotai/fasthtml-js@1.0.4/fasthtml.js\"></script><script src=\"https://cdn.jsdelivr.net/gh/answerdotai/surreal@main/surreal.js\"></script><script src=\"https://cdn.jsdelivr.net/gh/gnat/css-scope-inline@main/script.js\"></script><script>\n", |
1622 |
| - " function sendmsg() {\n", |
1623 |
| - " window.parent.postMessage({height: document.documentElement.offsetHeight}, '*');\n", |
1624 |
| - " }\n", |
1625 |
| - " window.onload = function() {\n", |
1626 |
| - " sendmsg();\n", |
1627 |
| - " document.body.addEventListener('htmx:afterSettle', sendmsg);\n", |
1628 |
| - " document.body.addEventListener('htmx:wsAfterMessage', sendmsg);\n", |
1629 |
| - " };</script>" |
1630 |
| - ], |
1631 |
| - "text/plain": [ |
1632 |
| - "<IPython.core.display.HTML object>" |
1633 |
| - ] |
1634 |
| - }, |
1635 |
| - "metadata": {}, |
1636 |
| - "output_type": "display_data" |
1637 |
| - } |
1638 |
| - ], |
| 1595 | + "outputs": [], |
1639 | 1596 | "source": [
|
1640 | 1597 | "app,cli,rt = get_cli(FastHTML(secret_key='soopersecret'))"
|
1641 | 1598 | ]
|
|
2054 | 2011 | "id": "bb8154cc",
|
2055 | 2012 | "metadata": {},
|
2056 | 2013 | "outputs": [
|
2057 |
| - { |
2058 |
| - "data": { |
2059 |
| - "text/html": [ |
2060 |
| - "<meta charset=\"utf-8\">\n", |
2061 |
| - "<meta name=\"viewport\" content=\"width=device-width, initial-scale=1, viewport-fit=cover\">\n", |
2062 |
| - "<script src=\"https://unpkg.com/htmx.org@next/dist/htmx.min.js\"></script><script src=\"https://cdn.jsdelivr.net/gh/answerdotai/fasthtml-js@1.0.4/fasthtml.js\"></script><script src=\"https://cdn.jsdelivr.net/gh/answerdotai/surreal@main/surreal.js\"></script><script src=\"https://cdn.jsdelivr.net/gh/gnat/css-scope-inline@main/script.js\"></script><script>\n", |
2063 |
| - " function sendmsg() {\n", |
2064 |
| - " window.parent.postMessage({height: document.documentElement.offsetHeight}, '*');\n", |
2065 |
| - " }\n", |
2066 |
| - " window.onload = function() {\n", |
2067 |
| - " sendmsg();\n", |
2068 |
| - " document.body.addEventListener('htmx:afterSettle', sendmsg);\n", |
2069 |
| - " document.body.addEventListener('htmx:wsAfterMessage', sendmsg);\n", |
2070 |
| - " };</script>" |
2071 |
| - ], |
2072 |
| - "text/plain": [ |
2073 |
| - "<IPython.core.display.HTML object>" |
2074 |
| - ] |
2075 |
| - }, |
2076 |
| - "metadata": {}, |
2077 |
| - "output_type": "display_data" |
2078 |
| - }, |
2079 | 2014 | {
|
2080 | 2015 | "data": {
|
2081 | 2016 | "text/plain": [
|
|
2412 | 2347 | "name": "stdout",
|
2413 | 2348 | "output_type": "stream",
|
2414 | 2349 | "text": [
|
2415 |
| - "Set to 2024-10-26 07:52:13.419267\n" |
| 2350 | + "Set to 2024-10-28 20:22:34.772989\n" |
2416 | 2351 | ]
|
2417 | 2352 | },
|
2418 | 2353 | {
|
2419 | 2354 | "data": {
|
2420 | 2355 | "text/plain": [
|
2421 |
| - "'Session time: 2024-10-26 07:52:13.419267'" |
| 2356 | + "'Session time: 2024-10-28 20:22:34.772989'" |
2422 | 2357 | ]
|
2423 | 2358 | },
|
2424 | 2359 | "execution_count": null,
|
|
2527 | 2462 | "execution_count": null,
|
2528 | 2463 | "id": "1f11eab1",
|
2529 | 2464 | "metadata": {},
|
2530 |
| - "outputs": [ |
2531 |
| - { |
2532 |
| - "data": { |
2533 |
| - "text/html": [ |
2534 |
| - "<meta charset=\"utf-8\">\n", |
2535 |
| - "<meta name=\"viewport\" content=\"width=device-width, initial-scale=1, viewport-fit=cover\">\n", |
2536 |
| - "<script src=\"https://unpkg.com/htmx.org@next/dist/htmx.min.js\"></script><script src=\"https://cdn.jsdelivr.net/gh/answerdotai/fasthtml-js@1.0.4/fasthtml.js\"></script><script src=\"https://cdn.jsdelivr.net/gh/answerdotai/surreal@main/surreal.js\"></script><script src=\"https://cdn.jsdelivr.net/gh/gnat/css-scope-inline@main/script.js\"></script><script>\n", |
2537 |
| - " function sendmsg() {\n", |
2538 |
| - " window.parent.postMessage({height: document.documentElement.offsetHeight}, '*');\n", |
2539 |
| - " }\n", |
2540 |
| - " window.onload = function() {\n", |
2541 |
| - " sendmsg();\n", |
2542 |
| - " document.body.addEventListener('htmx:afterSettle', sendmsg);\n", |
2543 |
| - " document.body.addEventListener('htmx:wsAfterMessage', sendmsg);\n", |
2544 |
| - " };</script>" |
2545 |
| - ], |
2546 |
| - "text/plain": [ |
2547 |
| - "<IPython.core.display.HTML object>" |
2548 |
| - ] |
2549 |
| - }, |
2550 |
| - "metadata": {}, |
2551 |
| - "output_type": "display_data" |
2552 |
| - } |
2553 |
| - ], |
| 2465 | + "outputs": [], |
2554 | 2466 | "source": [
|
2555 | 2467 | "def _not_found(req, exc): return Div('nope')\n",
|
2556 | 2468 | "\n",
|
|
2566 | 2478 | "execution_count": null,
|
2567 | 2479 | "id": "063b7f43",
|
2568 | 2480 | "metadata": {},
|
2569 |
| - "outputs": [ |
2570 |
| - { |
2571 |
| - "data": { |
2572 |
| - "text/html": [ |
2573 |
| - "<meta charset=\"utf-8\">\n", |
2574 |
| - "<meta name=\"viewport\" content=\"width=device-width, initial-scale=1, viewport-fit=cover\">\n", |
2575 |
| - "<script src=\"https://unpkg.com/htmx.org@next/dist/htmx.min.js\"></script><script src=\"https://cdn.jsdelivr.net/gh/answerdotai/fasthtml-js@1.0.4/fasthtml.js\"></script><script src=\"https://cdn.jsdelivr.net/gh/answerdotai/surreal@main/surreal.js\"></script><script src=\"https://cdn.jsdelivr.net/gh/gnat/css-scope-inline@main/script.js\"></script><script>\n", |
2576 |
| - " function sendmsg() {\n", |
2577 |
| - " window.parent.postMessage({height: document.documentElement.offsetHeight}, '*');\n", |
2578 |
| - " }\n", |
2579 |
| - " window.onload = function() {\n", |
2580 |
| - " sendmsg();\n", |
2581 |
| - " document.body.addEventListener('htmx:afterSettle', sendmsg);\n", |
2582 |
| - " document.body.addEventListener('htmx:wsAfterMessage', sendmsg);\n", |
2583 |
| - " };</script>" |
2584 |
| - ], |
2585 |
| - "text/plain": [ |
2586 |
| - "<IPython.core.display.HTML object>" |
2587 |
| - ] |
2588 |
| - }, |
2589 |
| - "metadata": {}, |
2590 |
| - "output_type": "display_data" |
2591 |
| - } |
2592 |
| - ], |
| 2481 | + "outputs": [], |
2593 | 2482 | "source": [
|
2594 | 2483 | "app,cli,rt = get_cli(FastHTML())\n",
|
2595 | 2484 | "\n",
|
|
2606 | 2495 | "execution_count": null,
|
2607 | 2496 | "id": "efd6fc6c",
|
2608 | 2497 | "metadata": {},
|
2609 |
| - "outputs": [ |
2610 |
| - { |
2611 |
| - "data": { |
2612 |
| - "text/html": [ |
2613 |
| - "<meta charset=\"utf-8\">\n", |
2614 |
| - "<meta name=\"viewport\" content=\"width=device-width, initial-scale=1, viewport-fit=cover\">\n", |
2615 |
| - "<script src=\"https://unpkg.com/htmx.org@next/dist/htmx.min.js\"></script><script src=\"https://cdn.jsdelivr.net/gh/answerdotai/fasthtml-js@1.0.4/fasthtml.js\"></script><script src=\"https://cdn.jsdelivr.net/gh/answerdotai/surreal@main/surreal.js\"></script><script src=\"https://cdn.jsdelivr.net/gh/gnat/css-scope-inline@main/script.js\"></script><script>\n", |
2616 |
| - " function sendmsg() {\n", |
2617 |
| - " window.parent.postMessage({height: document.documentElement.offsetHeight}, '*');\n", |
2618 |
| - " }\n", |
2619 |
| - " window.onload = function() {\n", |
2620 |
| - " sendmsg();\n", |
2621 |
| - " document.body.addEventListener('htmx:afterSettle', sendmsg);\n", |
2622 |
| - " document.body.addEventListener('htmx:wsAfterMessage', sendmsg);\n", |
2623 |
| - " };</script>" |
2624 |
| - ], |
2625 |
| - "text/plain": [ |
2626 |
| - "<IPython.core.display.HTML object>" |
2627 |
| - ] |
2628 |
| - }, |
2629 |
| - "metadata": {}, |
2630 |
| - "output_type": "display_data" |
2631 |
| - } |
2632 |
| - ], |
| 2498 | + "outputs": [], |
2633 | 2499 | "source": [
|
2634 | 2500 | "auth = user_pwd_auth(testuser='spycraft')\n",
|
2635 | 2501 | "app,cli,rt = get_cli(FastHTML(middleware=[auth]))\n",
|
|
2646 | 2512 | "execution_count": null,
|
2647 | 2513 | "id": "32520197",
|
2648 | 2514 | "metadata": {},
|
2649 |
| - "outputs": [ |
2650 |
| - { |
2651 |
| - "data": { |
2652 |
| - "text/html": [ |
2653 |
| - "<meta charset=\"utf-8\">\n", |
2654 |
| - "<meta name=\"viewport\" content=\"width=device-width, initial-scale=1, viewport-fit=cover\">\n", |
2655 |
| - "<script src=\"https://unpkg.com/htmx.org@next/dist/htmx.min.js\"></script><script src=\"https://cdn.jsdelivr.net/gh/answerdotai/fasthtml-js@1.0.4/fasthtml.js\"></script><script src=\"https://cdn.jsdelivr.net/gh/answerdotai/surreal@main/surreal.js\"></script><script src=\"https://cdn.jsdelivr.net/gh/gnat/css-scope-inline@main/script.js\"></script><script>\n", |
2656 |
| - " function sendmsg() {\n", |
2657 |
| - " window.parent.postMessage({height: document.documentElement.offsetHeight}, '*');\n", |
2658 |
| - " }\n", |
2659 |
| - " window.onload = function() {\n", |
2660 |
| - " sendmsg();\n", |
2661 |
| - " document.body.addEventListener('htmx:afterSettle', sendmsg);\n", |
2662 |
| - " document.body.addEventListener('htmx:wsAfterMessage', sendmsg);\n", |
2663 |
| - " };</script>" |
2664 |
| - ], |
2665 |
| - "text/plain": [ |
2666 |
| - "<IPython.core.display.HTML object>" |
2667 |
| - ] |
2668 |
| - }, |
2669 |
| - "metadata": {}, |
2670 |
| - "output_type": "display_data" |
2671 |
| - } |
2672 |
| - ], |
| 2515 | + "outputs": [], |
2673 | 2516 | "source": [
|
2674 | 2517 | "auth = user_pwd_auth(testuser='spycraft')\n",
|
2675 | 2518 | "app,cli,rt = get_cli(FastHTML(middleware=[auth]))\n",
|
|
2754 | 2597 | "execution_count": null,
|
2755 | 2598 | "id": "cd413b0d",
|
2756 | 2599 | "metadata": {},
|
2757 |
| - "outputs": [ |
2758 |
| - { |
2759 |
| - "data": { |
2760 |
| - "text/html": [ |
2761 |
| - "<meta charset=\"utf-8\">\n", |
2762 |
| - "<meta name=\"viewport\" content=\"width=device-width, initial-scale=1, viewport-fit=cover\">\n", |
2763 |
| - "<script src=\"https://unpkg.com/htmx.org@next/dist/htmx.min.js\"></script><script src=\"https://cdn.jsdelivr.net/gh/answerdotai/fasthtml-js@1.0.4/fasthtml.js\"></script><script src=\"https://cdn.jsdelivr.net/gh/answerdotai/surreal@main/surreal.js\"></script><script src=\"https://cdn.jsdelivr.net/gh/gnat/css-scope-inline@main/script.js\"></script><script>\n", |
2764 |
| - " function sendmsg() {\n", |
2765 |
| - " window.parent.postMessage({height: document.documentElement.offsetHeight}, '*');\n", |
2766 |
| - " }\n", |
2767 |
| - " window.onload = function() {\n", |
2768 |
| - " sendmsg();\n", |
2769 |
| - " document.body.addEventListener('htmx:afterSettle', sendmsg);\n", |
2770 |
| - " document.body.addEventListener('htmx:wsAfterMessage', sendmsg);\n", |
2771 |
| - " };</script>" |
2772 |
| - ], |
2773 |
| - "text/plain": [ |
2774 |
| - "<IPython.core.display.HTML object>" |
2775 |
| - ] |
2776 |
| - }, |
2777 |
| - "metadata": {}, |
2778 |
| - "output_type": "display_data" |
2779 |
| - } |
2780 |
| - ], |
| 2600 | + "outputs": [], |
2781 | 2601 | "source": [
|
2782 | 2602 | "app,cli,_ = get_cli(FastHTML())\n",
|
2783 | 2603 | "ar.to_app(app)"
|
|
2851 | 2671 | "execution_count": null,
|
2852 | 2672 | "id": "7438435e",
|
2853 | 2673 | "metadata": {},
|
2854 |
| - "outputs": [ |
2855 |
| - { |
2856 |
| - "data": { |
2857 |
| - "text/html": [ |
2858 |
| - "<meta charset=\"utf-8\">\n", |
2859 |
| - "<meta name=\"viewport\" content=\"width=device-width, initial-scale=1, viewport-fit=cover\">\n", |
2860 |
| - "<script src=\"https://unpkg.com/htmx.org@next/dist/htmx.min.js\"></script><script src=\"https://cdn.jsdelivr.net/gh/answerdotai/fasthtml-js@1.0.4/fasthtml.js\"></script><script src=\"https://cdn.jsdelivr.net/gh/answerdotai/surreal@main/surreal.js\"></script><script src=\"https://cdn.jsdelivr.net/gh/gnat/css-scope-inline@main/script.js\"></script><script>\n", |
2861 |
| - " function sendmsg() {\n", |
2862 |
| - " window.parent.postMessage({height: document.documentElement.offsetHeight}, '*');\n", |
2863 |
| - " }\n", |
2864 |
| - " window.onload = function() {\n", |
2865 |
| - " sendmsg();\n", |
2866 |
| - " document.body.addEventListener('htmx:afterSettle', sendmsg);\n", |
2867 |
| - " document.body.addEventListener('htmx:wsAfterMessage', sendmsg);\n", |
2868 |
| - " };</script>" |
2869 |
| - ], |
2870 |
| - "text/plain": [ |
2871 |
| - "<IPython.core.display.HTML object>" |
2872 |
| - ] |
2873 |
| - }, |
2874 |
| - "metadata": {}, |
2875 |
| - "output_type": "display_data" |
2876 |
| - } |
2877 |
| - ], |
| 2674 | + "outputs": [], |
2878 | 2675 | "source": [
|
2879 | 2676 | "app,cli,rt = get_cli(FastHTML(secret_key='soopersecret'))"
|
2880 | 2677 | ]
|
|
2921 | 2718 | {
|
2922 | 2719 | "data": {
|
2923 | 2720 | "text/plain": [
|
2924 |
| - "'Cookie was set at time 07:52:14.289735'" |
| 2721 | + "'Cookie was set at time 20:22:35.467691'" |
2925 | 2722 | ]
|
2926 | 2723 | },
|
2927 | 2724 | "execution_count": null,
|
|
0 commit comments