-
Notifications
You must be signed in to change notification settings - Fork 257
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
17 changed files
with
595 additions
and
375 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,23 +1,20 @@ | ||
from fasthtml.common import * | ||
|
||
app = FastHTML(ws_hdr=True) | ||
app = FastHTML(exts='ws') | ||
rt = app.route | ||
|
||
msgs = [] | ||
@rt('/') | ||
def home(): return Div( | ||
Div(Ul(*[Li(m) for m in msgs], id='msg-list')), | ||
Form(Input(id='msg'), id='form', ws_send=True), | ||
hx_ext='ws', ws_connect='/ws') | ||
def home(): | ||
return Div(hx_ext='ws', ws_connect='/ws')( | ||
Div(Ul(*[Li(m) for m in msgs], id='msg-list')), | ||
Form(Input(id='msg'), id='form', ws_send=True) | ||
) | ||
|
||
users = {} | ||
def on_conn(ws, send): users[str(id(ws))] = send | ||
def on_disconn(ws): users.pop(str(id(ws)), None) | ||
|
||
@app.ws('/ws', conn=on_conn, disconn=on_disconn) | ||
async def ws(msg:str): | ||
msgs.append(msg) | ||
# Use associated `send` function to send message to each user | ||
for u in users.values(): await u(Ul(*[Li(m) for m in msgs], id='msg-list')) | ||
await send(Ul(*[Li(m) for m in msgs], id='msg-list')) | ||
|
||
send = setup_ws(app, ws) | ||
|
||
serve() | ||
serve() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -3,11 +3,11 @@ | |
# AUTOGENERATED! DO NOT EDIT! File to edit: ../nbs/api/00_core.ipynb. | ||
|
||
# %% auto 0 | ||
__all__ = ['empty', 'htmx_hdrs', 'fh_cfg', 'htmx_resps', 'htmx_exts', 'htmxsrc', 'htmxwssrc', 'fhjsscr', 'htmxctsrc', 'surrsrc', | ||
'scopesrc', 'viewport', 'charset', 'all_meths', 'parsed_date', 'snake2hyphens', 'HtmxHeaders', 'HttpHeader', | ||
'HtmxResponseHeaders', 'form2dict', 'parse_form', 'flat_xt', 'Beforeware', 'EventStream', 'signal_shutdown', | ||
'WS_RouteX', 'uri', 'decode_uri', 'flat_tuple', 'Redirect', 'RouteX', 'RouterX', 'get_key', 'def_hdrs', | ||
'FastHTML', 'serve', 'Client', 'cookie', 'reg_re_param', 'MiddlewareBase', 'FtResponse', 'unqid', 'setup_ws'] | ||
__all__ = ['empty', 'htmx_hdrs', 'fh_cfg', 'htmx_resps', 'htmx_exts', 'htmxsrc', 'fhjsscr', 'surrsrc', 'scopesrc', 'viewport', | ||
'charset', 'all_meths', 'parsed_date', 'snake2hyphens', 'HtmxHeaders', 'HttpHeader', 'HtmxResponseHeaders', | ||
'form2dict', 'parse_form', 'flat_xt', 'Beforeware', 'EventStream', 'signal_shutdown', 'WS_RouteX', 'uri', | ||
'decode_uri', 'flat_tuple', 'Redirect', 'RouteX', 'RouterX', 'get_key', 'def_hdrs', 'FastHTML', 'serve', | ||
'Client', 'cookie', 'reg_re_param', 'MiddlewareBase', 'FtResponse', 'unqid', 'setup_ws'] | ||
|
||
# %% ../nbs/api/00_core.ipynb | ||
import json,uuid,inspect,types,uvicorn,signal,asyncio,threading | ||
|
@@ -472,14 +472,14 @@ def add_ws(self, path: str, recv: callable, conn:callable=None, disconn:callable | |
"loading-states": "https://unpkg.com/[email protected]/loading-states.js", | ||
"multi-swap": "https://unpkg.com/[email protected]/multi-swap.js", | ||
"path-deps": "https://unpkg.com/[email protected]/path-deps.js", | ||
"remove-me": "https://unpkg.com/[email protected]/remove-me.js" | ||
"remove-me": "https://unpkg.com/[email protected]/remove-me.js", | ||
"ws": "https://unpkg.com/htmx-ext-ws/ws.js", | ||
"chunked-transfer": "https://unpkg.com/htmx-ext-transfer-encoding-chunked/transfer-encoding-chunked.js" | ||
} | ||
|
||
# %% ../nbs/api/00_core.ipynb | ||
htmxsrc = Script(src="https://unpkg.com/htmx.org@next/dist/htmx.min.js") | ||
htmxwssrc = Script(src="https://unpkg.com/htmx-ext-ws/ws.js") | ||
fhjsscr = Script(src="https://cdn.jsdelivr.net/gh/answerdotai/[email protected]/fasthtml.js") | ||
htmxctsrc = Script(src="https://unpkg.com/htmx-ext-transfer-encoding-chunked/transfer-encoding-chunked.js") | ||
surrsrc = Script(src="https://cdn.jsdelivr.net/gh/answerdotai/surreal@main/surreal.js") | ||
scopesrc = Script(src="https://cdn.jsdelivr.net/gh/gnat/css-scope-inline@main/script.js") | ||
viewport = Meta(name="viewport", content="width=device-width, initial-scale=1, viewport-fit=cover") | ||
|
@@ -515,28 +515,27 @@ def __str__(self): return p | |
return _lf() | ||
|
||
# %% ../nbs/api/00_core.ipynb | ||
def def_hdrs(htmx=True, ct_hdr=False, ws_hdr=False, surreal=True): | ||
def def_hdrs(htmx=True, surreal=True): | ||
"Default headers for a FastHTML app" | ||
hdrs = [] | ||
if surreal: hdrs = [surrsrc,scopesrc] + hdrs | ||
if ws_hdr: hdrs = [htmxwssrc] + hdrs | ||
if ct_hdr: hdrs = [htmxctsrc] + hdrs | ||
if htmx: hdrs = [htmxsrc,fhjsscr] + hdrs | ||
return [charset, viewport] + hdrs | ||
|
||
# %% ../nbs/api/00_core.ipynb | ||
class FastHTML(Starlette): | ||
def __init__(self, debug=False, routes=None, middleware=None, exception_handlers=None, | ||
on_startup=None, on_shutdown=None, lifespan=None, hdrs=None, ftrs=None, | ||
before=None, after=None, ws_hdr=False, ct_hdr=False, | ||
surreal=True, htmx=True, default_hdrs=True, sess_cls=SessionMiddleware, | ||
on_startup=None, on_shutdown=None, lifespan=None, hdrs=None, ftrs=None, exts=None, | ||
before=None, after=None, surreal=True, htmx=True, default_hdrs=True, sess_cls=SessionMiddleware, | ||
secret_key=None, session_cookie='session_', max_age=365*24*3600, sess_path='/', | ||
same_site='lax', sess_https_only=False, sess_domain=None, key_fname='.sesskey', | ||
htmlkw=None, **bodykw): | ||
middleware,before,after = map(_list, (middleware,before,after)) | ||
hdrs,ftrs = listify(hdrs),listify(ftrs) | ||
hdrs,ftrs,exts = map(listify, (hdrs,ftrs,exts)) | ||
exts = {k:htmx_exts[k] for k in exts} | ||
htmlkw = htmlkw or {} | ||
if default_hdrs: hdrs = def_hdrs(htmx, ct_hdr=ct_hdr, ws_hdr=ws_hdr, surreal=surreal) + hdrs | ||
if default_hdrs: hdrs = def_hdrs(htmx, surreal=surreal) + hdrs | ||
hdrs += [Script(src=ext) for ext in exts.values()] | ||
self.on_startup,self.on_shutdown,self.lifespan,self.hdrs,self.ftrs = on_startup,on_shutdown,lifespan,hdrs,ftrs | ||
self.before,self.after,self.htmlkw,self.bodykw = before,after,htmlkw,bodykw | ||
secret_key = get_key(secret_key, key_fname) | ||
|
@@ -690,11 +689,11 @@ def _add_ids(s): | |
for c in s.children: _add_ids(c) | ||
|
||
# %% ../nbs/api/00_core.ipynb | ||
def setup_ws(app): | ||
def setup_ws(app, f=noop): | ||
conns = {} | ||
async def on_connect(scope, send): conns[scope.client] = send | ||
async def on_disconnect(scope): conns.pop(scope.client) | ||
app.ws('/ws', conn=on_connect, disconn=on_disconnect)() | ||
app.ws('/ws', conn=on_connect, disconn=on_disconnect)(f) | ||
async def send(s): | ||
for o in conns.values(): await o(s) | ||
app._send = send | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,5 +1,5 @@ | ||
"""The `FastHTML` subclass of `Starlette`, along with the `RouterX` and `RouteX` classes it automatically uses.""" | ||
__all__ = ['empty', 'htmx_hdrs', 'fh_cfg', 'htmx_resps', 'htmxsrc', 'htmxwssrc', 'fhjsscr', 'htmxctsrc', 'surrsrc', 'scopesrc', 'viewport', 'charset', 'all_meths', 'parsed_date', 'snake2hyphens', 'HtmxHeaders', 'str2int', 'str2date', 'HttpHeader', 'HtmxResponseHeaders', 'form2dict', 'parse_form', 'flat_xt', 'Beforeware', 'EventStream', 'signal_shutdown', 'WS_RouteX', 'uri', 'decode_uri', 'flat_tuple', 'Redirect', 'RouteX', 'RouterX', 'get_key', 'def_hdrs', 'FastHTML', 'serve', 'Client', 'cookie', 'reg_re_param', 'MiddlewareBase', 'FtResponse'] | ||
__all__ = ['empty', 'htmx_hdrs', 'fh_cfg', 'htmx_resps', 'htmx_exts', 'htmxsrc', 'fhjsscr', 'surrsrc', 'scopesrc', 'viewport', 'charset', 'all_meths', 'parsed_date', 'snake2hyphens', 'HtmxHeaders', 'HttpHeader', 'HtmxResponseHeaders', 'form2dict', 'parse_form', 'flat_xt', 'Beforeware', 'EventStream', 'signal_shutdown', 'WS_RouteX', 'uri', 'decode_uri', 'flat_tuple', 'Redirect', 'RouteX', 'RouterX', 'get_key', 'def_hdrs', 'FastHTML', 'serve', 'Client', 'cookie', 'reg_re_param', 'MiddlewareBase', 'FtResponse', 'unqid', 'setup_ws'] | ||
import json, uuid, inspect, types, uvicorn, signal, asyncio, threading | ||
from fastcore.utils import * | ||
from fastcore.xml import * | ||
|
@@ -18,6 +18,8 @@ from warnings import warn | |
from dateutil import parser as dtparse | ||
from httpx import ASGITransport, AsyncClient | ||
from anyio import from_thread | ||
from uuid import uuid4 | ||
from base64 import b85encode, b64encode | ||
from .starlette import * | ||
empty = Parameter.empty | ||
|
||
|
@@ -50,19 +52,11 @@ class HtmxHeaders: | |
def _get_htmx(h): | ||
... | ||
|
||
def str2int(s) -> int: | ||
"""Convert `s` to an `int`""" | ||
... | ||
|
||
def _mk_list(t, v): | ||
... | ||
fh_cfg = AttrDict(indent=True) | ||
|
||
def str2date(s: str) -> date: | ||
"""`date.fromisoformat` with empty string handling""" | ||
... | ||
|
||
def _fix_anno(t): | ||
def _fix_anno(t, o): | ||
"""Create appropriate callable type for casting a `str` to type `t` (or first type in `t` if union)""" | ||
... | ||
|
||
|
@@ -228,10 +222,9 @@ class RouterX(Router): | |
|
||
def add_ws(self, path: str, recv: callable, conn: callable=None, disconn: callable=None, name=None): | ||
... | ||
htmx_exts = {'head-support': 'https://unpkg.com/[email protected]/head-support.js', 'preload': 'https://unpkg.com/[email protected]/preload.js', 'class-tools': 'https://unpkg.com/[email protected]/class-tools.js', 'loading-states': 'https://unpkg.com/[email protected]/loading-states.js', 'multi-swap': 'https://unpkg.com/[email protected]/multi-swap.js', 'path-deps': 'https://unpkg.com/[email protected]/path-deps.js', 'remove-me': 'https://unpkg.com/[email protected]/remove-me.js', 'ws': 'https://unpkg.com/htmx-ext-ws/ws.js', 'chunked-transfer': 'https://unpkg.com/htmx-ext-transfer-encoding-chunked/transfer-encoding-chunked.js'} | ||
htmxsrc = Script(src='https://unpkg.com/htmx.org@next/dist/htmx.min.js') | ||
htmxwssrc = Script(src='https://unpkg.com/htmx-ext-ws/ws.js') | ||
fhjsscr = Script(src='https://cdn.jsdelivr.net/gh/answerdotai/[email protected]/fasthtml.js') | ||
htmxctsrc = Script(src='https://unpkg.com/htmx-ext-transfer-encoding-chunked/transfer-encoding-chunked.js') | ||
surrsrc = Script(src='https://cdn.jsdelivr.net/gh/answerdotai/surreal@main/surreal.js') | ||
scopesrc = Script(src='https://cdn.jsdelivr.net/gh/gnat/css-scope-inline@main/script.js') | ||
viewport = Meta(name='viewport', content='width=device-width, initial-scale=1, viewport-fit=cover') | ||
|
@@ -249,13 +242,13 @@ def _wrap_ex(f, hdrs, ftrs, htmlkw, bodykw): | |
def _mk_locfunc(f, p): | ||
... | ||
|
||
def def_hdrs(htmx=True, ct_hdr=False, ws_hdr=False, surreal=True): | ||
def def_hdrs(htmx=True, surreal=True): | ||
"""Default headers for a FastHTML app""" | ||
... | ||
|
||
class FastHTML(Starlette): | ||
|
||
def __init__(self, debug=False, routes=None, middleware=None, exception_handlers=None, on_startup=None, on_shutdown=None, lifespan=None, hdrs=None, ftrs=None, before=None, after=None, ws_hdr=False, ct_hdr=False, surreal=True, htmx=True, default_hdrs=True, sess_cls=SessionMiddleware, secret_key=None, session_cookie='session_', max_age=365 * 24 * 3600, sess_path='/', same_site='lax', sess_https_only=False, sess_domain=None, key_fname='.sesskey', htmlkw=None, **bodykw): | ||
def __init__(self, debug=False, routes=None, middleware=None, exception_handlers=None, on_startup=None, on_shutdown=None, lifespan=None, hdrs=None, ftrs=None, exts=None, before=None, after=None, surreal=True, htmx=True, default_hdrs=True, sess_cls=SessionMiddleware, secret_key=None, session_cookie='session_', max_age=365 * 24 * 3600, sess_path='/', same_site='lax', sess_https_only=False, sess_domain=None, key_fname='.sesskey', htmlkw=None, **bodykw): | ||
... | ||
|
||
def ws(self, path: str, conn=None, disconn=None, name=None): | ||
|
@@ -309,8 +302,17 @@ class MiddlewareBase: | |
class FtResponse: | ||
"""Wrap an FT response with any Starlette `Response`""" | ||
|
||
def __init__(self, content, status_code: int=200, headers=None, cls=HTMLResponse, media_type: str | None=None, background=None): | ||
def __init__(self, content, status_code: int=200, headers=None, cls=HTMLResponse, media_type: str | None=None): | ||
... | ||
|
||
def __response__(self, req): | ||
... | ||
... | ||
|
||
def unqid(): | ||
... | ||
|
||
def _add_ids(s): | ||
... | ||
|
||
def setup_ws(app, f=noop): | ||
... |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.