Try an interactive version of this dialog: Sign up at solve.it.com, click Upload, and pass this URL.
1. FastHTML Setup
from fastcore.utils import *
from fasthtml.common import *
from fasthtml.jupyter import *
import fasthtml.components as fc
import httpxIdempotent server startup for CRAFT files
On each kernel start/restart:
- If nothing is on port 8000 →
xargs -rdoes nothing (the-rflag means "don't run if no input") - If something is on port 8000 → it gets killed, then your server takes over
This ensures the FastHTML server always starts cleanly, regardless of prior state.
import subprocess
def kill_port(port=8000):
subprocess.run(f"lsof -ti:{port} | xargs -r kill -9", shell=True)
kill_port()hdrs = (
Script(src='https://cdn.jsdelivr.net/npm/@tailwindcss/browser@4'),
Link(href='https://unpkg.com/leaflet@1.9.4/dist/leaflet.css', integrity="sha256-p4NxAoJBhIIN+hmNHrzRCf9tD/miZyoHS5obTRR9BMY=", crossorigin="", rel='stylesheet', type='text/css'),
Script(src="https://unpkg.com/leaflet@1.9.4/dist/leaflet.js", integrity="sha256-20nQCchB9co0qIjJZRGuk2/Z9VM+kNiyxNV1lvTlZBo=", crossorigin=""),
)# Note: We need to set a custom session cookie for FastHTML sessions to work in SolveIt since (for now) SolveIt uses the default one (this might change in the future)
if 'srv' not in globals() or not srv:
app = FastHTML(hdrs=hdrs, session_cookie='fh_template_session')
rt = app.route
srv = JupyUvi(app)# used to run our app later
def get_preview(app): return partial(HTMX, app=app, host=None, port=None)
preview = get_preview(app)2. Add Leaflet Route
@rt enables route creation directly in SolveIt dialogs!
@rt
def index():
return Div(
Div(id="map", style="width:100vw;height:100vh;"),
Script("""
var map = L.map('map').setView([51.505, -0.09], 13);
L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
attribution: '© OpenStreetMap'
}).addTo(map);
""")
)5. Run FastHTML App
import json
from IPython.display import IFrame
IFrame(f"https://{json.loads(os.environ['PUBLIC_DOMAINS'])['8000']}", width=800, height=500)