# Jupyter compatibility ``` python from httpx import get, AsyncClient ``` ## Helper functions ------------------------------------------------------------------------ source ### 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`* ------------------------------------------------------------------------ source ### nb_serve_async > nb_serve_async (app, log_level='error', port=8000, host='0.0.0.0', > **kwargs) *Async version of [`nb_serve`](https://www.fastht.ml/docs/api/jupyter.html#nb_serve)* ------------------------------------------------------------------------ source ### is_port_free > is_port_free (port, host='localhost') *Check if `port` is free on `host`* ------------------------------------------------------------------------ source ### wait_port_free > wait_port_free (port, host='localhost', max_wait=3) *Wait for `port` to be free on `host`* ## Using FastHTML in Jupyter ------------------------------------------------------------------------ source ### show > show (*s, iframe=False, height='auto', style=None) *Same as fasthtml.components.show, but also adds `htmx.process()`* ------------------------------------------------------------------------ source ### render_ft > render_ft () ------------------------------------------------------------------------ source ### htmx_config_port > htmx_config_port (port=8000) ------------------------------------------------------------------------ source ### 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. ``` python app = FastHTML() rt = app.route @app.route def index(): return 'hi' port = 8000 server = JupyUvi(app, port=port) ``` ``` python 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. ``` python server.stop() ``` ``` python app = FastHTML() rt = app.route @app.route async def index(): return 'hi' server = JupyUvi(app, port=port, start=False) await server.start_async() ``` ``` python print((await AsyncClient().get(f'http://localhost:{port}')).text) ``` hi ------------------------------------------------------------------------ source ### 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`* ``` python server = JupyUviAsync(app, port=port) await server.start() ``` ``` python async with AsyncClient() as client: r = await client.get(f'http://localhost:{port}') print(r.text) ``` hi ``` python 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. ``` python fh_cfg['auto_id' ]=True ``` After importing `fasthtml.jupyter` and calling [`render_ft()`](https://www.fastht.ml/docs/api/jupyter.html#render_ft), FT components render directly in the notebook. ``` python show(*def_hdrs()) render_ft() ``` ``` python (c := Div('Cogito ergo sum')) ```
Cogito ergo sum
Handlers are written just like a regular web app: ``` python server = JupyUvi(app, port=port) ``` ``` python @rt def hoho(): return P('loaded!'), Div('hee hee', id=c, hx_swap_oob='true') ``` All the usual `hx_*` attributes can be used: ``` python 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. ``` python (c := Div('')) ```
``` python @rt def foo(): return Div('foo bar') P('hi', hx_get=foo, hx_trigger='load', hx_target=c) ```

hi

``` python 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`](https://www.fastht.ml/docs/api/jupyter.html#htmx) function creates an auto-sizing IFrame for a web app. ------------------------------------------------------------------------ source ### 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.* ``` python @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!')) ``` ``` python server.start() ``` ``` python # Run the notebook locally to see the HTMX iframe in action HTMX() ``` ``` python server.stop() ``` ------------------------------------------------------------------------ source ### ws_client > ws_client (app, nm='', host='localhost', port=8000, ws_connect='/ws', > frame=True, link=True, **kwargs)