from httpx import get, AsyncClientJupyter compatibility
Helper functions
nb_serve
nb_serve (app, log_level='error', port=8000, host='0.0.0.0', **kwargs)
Start a Jupyter compatible uvicorn server with ASGI app on port with log_level
nb_serve_async
nb_serve_async (app, log_level='error', port=8000, host='0.0.0.0', **kwargs)
Async version of nb_serve
is_port_free
is_port_free (port, host='localhost')
Check if port is free on host
wait_port_free
wait_port_free (port, host='localhost', max_wait=3)
Wait for port to be free on host
Using FastHTML in Jupyter
show
show (*s, iframe=False, height='auto', style=None)
Same as fasthtml.components.show, but also adds htmx.process()
render_ft
render_ft ()
htmx_config_port
htmx_config_port (port=8000)
JupyUvi
JupyUvi (app, log_level='error', host='0.0.0.0', port=8000, start=True, **kwargs)
Start and stop a Jupyter compatible uvicorn server with ASGI app on port with log_level
Creating an object of this class also starts the Uvicorn server. It runs in a separate thread, so you can use normal HTTP client functions in a notebook.
app = FastHTML()
rt = app.route
@app.route
def index(): return 'hi'
port = 8000
server = JupyUvi(app, port=port)get(f'http://localhost:{port}').text'hi'
You can stop the server, modify routes, and start the server again without restarting the notebook or recreating the server or application.
server.stop()app = FastHTML()
rt = app.route
@app.route
async def index(): return 'hi'
server = JupyUvi(app, port=port, start=False)
await server.start_async()print((await AsyncClient().get(f'http://localhost:{port}')).text)hi
JupyUviAsync
JupyUviAsync (app, log_level='error', host='0.0.0.0', port=8000, **kwargs)
Start and stop an async Jupyter compatible uvicorn server with ASGI app on port with log_level
server = JupyUviAsync(app, port=port)
await server.start()async with AsyncClient() as client:
    r = await client.get(f'http://localhost:{port}')
print(r.text)hi
server.stop()Using a notebook as a web app
You can also run an HTMX web app directly in a notebook. To make this work, you have to add the default FastHTML headers to the DOM of the notebook with show(*def_hdrs()). Additionally, you might find it convenient to use auto_id mode, in which the ID of an FT object is automatically generated if not provided.
fh_cfg['auto_id' ]=TrueAfter importing fasthtml.jupyter and calling render_ft(), FT components render directly in the notebook.
show(*def_hdrs())
render_ft()(c := Div('Cogito ergo sum'))Handlers are written just like a regular web app:
server = JupyUvi(app, port=port)@rt
def hoho(): return P('loaded!'), Div('hee hee', id=c, hx_swap_oob='true')All the usual hx_* attributes can be used:
P('not loaded', hx_get=hoho, hx_trigger='load')not loaded
FT components can be used directly both as id values and as hx_target values.
(c := Div(''))@rt
def foo(): return Div('foo bar')
P('hi', hx_get=foo, hx_trigger='load', hx_target=c)hi
server.stop()Running apps in an IFrame
Using an IFrame can be a good idea to get complete isolation of the styles and scripts in an app. The HTMX function creates an auto-sizing IFrame for a web app.
HTMX
HTMX (path='', app=None, host='localhost', port=8000, height='auto', link=False, iframe=True)
An iframe which displays the HTMX application in a notebook.
@rt
def index():
    return Div(
        P(A('Click me', hx_get=update, hx_target='#result')),
        P(A('No me!', hx_get=update, hx_target='#result')),
        Div(id='result'))
@rt
def update(): return Div(P('Hi!'),P('There!'))server.start()# Run the notebook locally to see the HTMX iframe in action
HTMX()server.stop()ws_client
ws_client (app, nm='', host='localhost', port=8000, ws_connect='/ws', frame=True, link=True, **kwargs)