### Run the FastHTML-Gallery Project
Source: https://github.com/answerdotai/fasthtml-gallery/blob/main/README.md
Execute this command to start the main application server for the gallery.
```bash
python main.py
```
--------------------------------
### Install Project Dependencies
Source: https://github.com/answerdotai/fasthtml-gallery/blob/main/README.md
Use this command to install all necessary Python packages for the project.
```bash
pip install -r requirements.txt
```
--------------------------------
### CSV Editor Application Setup
Source: https://github.com/answerdotai/fasthtml-gallery/blob/main/llms_ctx.txt
Initializes the FastHTML app, database, and defines headers for the CSV editor. It includes a route to download an example CSV file.
```python
from fasthtml.common import *
from uuid import uuid4
db = database('sqlite.db')
hdrs = (Style('''
button,input { margin: 0 1rem; }
[role="group"] { border: 1px solid #ccc; }
.edited { outline: 2px solid orange; }
'''), )
app, rt = fast_app(hdrs=hdrs)
@rt
async def get_test_file():
import httpx
url = "https://raw.githubusercontent.com/AnswerDotAI/FastHTML-Gallery/refs/heads/main/examples/applications/csv_editor/ex_data.csv"
response = await httpx.AsyncClient().get(url)
return Response(response.text, media_type="text/csv",
headers={'Content-Disposition': 'attachment; filename="ex_data.csv"'})
@rt
def index(sess):
if 'id' not in sess: sess['id'] = str(uuid4())
return Titled("CSV Uploader",
A('Download Example CSV', href="get_test_file", download="ex_data.csv"),
Group(Input(type="file", name="csv_file", accept=".csv"),
Button("Upload", hx_post="upload", hx_target="#results",
hx_encoding="multipart/form-data", hx_include='previous input'),
A('Download', href='download', type="button")),
Div(id="results"))
```
--------------------------------
### WebSocket Integration Setup
Source: https://github.com/answerdotai/fasthtml-gallery/blob/main/llms_ctx.txt
Initializes a Fasthtml application with WebSocket support enabled. This is a basic setup for applications requiring real-time communication.
```Python
from fasthtml.common import *
from collections import deque
app, rt = fast_app(exts='ws')
```
--------------------------------
### Todo Application Setup
Source: https://github.com/answerdotai/fasthtml-gallery/blob/main/llms_ctx.txt
Initializes a Fasthtml application with database integration for a todo list. It sets up a database table, defines a model, and returns connector and model objects.
```Python
app, rt, todos, Todo= fast_app('intermediate_todo.db',hdrs=Theme.slate.headers(),
title=str,done=bool,due=date, id=int,pk='id')
```
--------------------------------
### FastHTML Application Setup and Index Route
Source: https://github.com/answerdotai/fasthtml-gallery/blob/main/llms_ctx.txt
Sets up the FastHTML application and defines the main index route. This route initializes session data and renders the main form for the cellular automaton.
```python
app, rt = fast_app()
@rt
def index(sess):
if 'id' not in sess: sess['id'] = str(uuid4())
return Title("Cellular Automata"),Main(Div(
Div(P(explanation,id="explanations")),
Form(Group(
Div(hx_target='this', hx_swap='outerHTML')(Label(_for="rule_number", cls="form-label")("Rule"),
Input(type='number', name="rule_number", id='rule_set', value="30",hx_post='validate/rule_number')),
Div(hx_target='this', hx_swap='outerHTML')(Label("Generations", cls="form-label"),
Input(type='number',name="generations", id='generations_set', value="50", hx_post='validate/generations', hx_indicator='#generationsind')),
Div(hx_target='this', hx_swap='outerHTML')(Label("Width", cls="form-label"),
Input(type='number',name="width", id='width_set', value="100", hx_post='validate/width', hx_indicator='#widthind')) ,
Button(cls="btn btn-active btn-primary", type="submit", hx_get="run",
hx_target="#grid", hx_include="[name='rule_number'],[name='generations'],[name='width']", hx_swap="outerHTML")("Run"))),
Group(
Div(style="margin-left:50px")(
Div(id="progress_bar"),
Div(id="grid")),
Div(style="margin-right:50px; max-width:200px")(
mk_button(False),
Div(id="rule"),
))))
```
--------------------------------
### Toast Notification Example
Source: https://github.com/answerdotai/fasthtml-gallery/blob/main/llms_ctx.txt
Shows how to display a toast notification using the MonsterUI library integrated with Fasthtml. Configure toast appearance and duration.
```Python
from fasthtml.common import *
from monsterui.all import *
app, rt = fast_app(hdrs=Theme.blue.headers())
@rt
def index():
return Div(cls="flex items-center justify-center h-screen")(
Button("Show Toast", cls="bg-blue-500 text-white", hx_get="toast", hx_target="body", hx_swap="afterbegin")
)
@rt
def toast(): return Toast("Here's your toast š!", dur=2, cls=[ToastVT.top, ToastHT.center], alert_cls="text-white bg-green-500 border-green-500")
```
--------------------------------
### Bulk Update Example with Fasthtml
Source: https://github.com/answerdotai/fasthtml-gallery/blob/main/llms_ctx.txt
Demonstrates how to perform a bulk update on table data using Fasthtml, including form submission and response handling.
```python
from fasthtml.common import *
from collections import defaultdict
app, rt = fast_app()
default_data = [
{'id': 1, 'name': 'Alice', 'age': 25},
{'id': 2, 'name': 'Bob', 'age': 30},
{'id': 3, 'name': 'Charlie', 'age': 28},
]
data = defaultdict(lambda: [dict(d) for d in default_data])
@rt
def index(session):
# if no id, create one so diff users changes don't conflict
if not session.get('id'): session['id'] = unqid()
# Create a table based on the current users data
rows = []
for item in data[session['id']]:
rows.append(
Tr(Td(str(item['id']))),
Td(Input(value=item['name'], name=f"name{item['id']}", _id=f"name{item['id']}")),
Td(Input(value=str(item['age']), name=f"age{item['id']}", _id=f"age{item['id']}"))))
return Div(
Form(
Table(
Thead(Tr(map(Th, ('ID', 'Name', 'Age')))),
Tbody(*rows)),
# Bulk update button that submits all inputs from the table because it's inside fot form.
Button('Bulk Update', hx_post="update", hx_target='#response', hx_indicator="#loading", _type="button", hx_vals={'id': session['id']})),
# Response div that will be updated with the result of the bulk update
Div(id='response'),
# Loading indicator that will be shown when the bulk update is happening
Div(id="loading", style="display:none;", _class="loader"))
@rt
async def update(request, id:str):
changes = []
form_data = await request.form()
# Iterate over the items in the users data
for item in data[id]:
# Get the new name and age from the form data
new_name = form_data.get(f"name{item['id']}")
new_age = form_data.get(f"age{item['id']}")
# Check if the item has changed and if so add it to the changes list
if new_name != item['name'] or new_age != str(item['age']):
changes.append(f"Row {item['id']} changed: Name {item['name']} ā {new_name}, Age {item['age']} ā {new_age}")
item['name'] = new_name
item['age'] = int(new_age)
# Return the changes or a message if there are no changes
return Div(*[Div(change) for change in changes]) if changes else Div("No changes detected")
serve()
```
--------------------------------
### Annotate Text Application Setup
Source: https://github.com/answerdotai/fasthtml-gallery/blob/main/llms_ctx.txt
Sets up the FastHTML application with necessary links for Tailwind CSS, DaisyUI, and custom scripts. It also initializes the database and loads dummy data for the annotation task.
```python
from fasthtml.common import *
import json
import httpx
# Set up the app, including daisyui and tailwind for the chat component
tlink = Script(src="https://cdn.tailwindcss.com?plugins=typography"),
dlink = Link(rel="stylesheet", href="https://cdn.jsdelivr.net/npm/daisyui@4.11.1/dist/full.min.css")
def Arrow(arrow, hx_get, id):
# Grey out button if you're at the end
if arrow == "ā": ptr_evnts = "pointer-events-none opacity-50" if id == 1 else ""
elif arrow == "ā": ptr_evnts = " pointer-events-none opacity-50" if id == total_items_length - 1 else ""
# CSS Styling for both arrow buttons
common_classes = "relative inline-flex items-center bg-indigo-600 px-3 py-2 text-sm font-semibold text-white shadow-sm hover:bg-indigo-500 focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-indigo-600"
return A(Span(arrow, cls="sr-only"),
Span(arrow, cls="h-5 w-5", aria_hidden="true"),
hx_get=hx_get, hx_swap="outerHTML",
cls=f" {'' if arrow=='ā' else '-ml-px'} rounded-{'l' if arrow=='ā' else 'r'}-md {common_classes} {ptr_evnts}")
def AnnotateButton(value, feedback):
# Different button styling if it's already marked as correct/incorrect
classes = '' if feedback=='correct' else 'btn-outline'
# Green for correct red for incorrect
classes += f" btn-{'success' if value=='correct' else 'error'}"
classes += ' mr-2' if value=='correct' else ''
return Button(value.capitalize(), name='feedback', value=value, cls='btn hover:text-white '+classes)
def render(Item):
messages = json.loads(Item.messages)
card_header = Div(cls="border-b border-gray-200 bg-white p-4")(
Div(cls="flex justify-between items-center mb-4")(
H3(f"Sample {Item.id} out of {total_items_length}" if total_items_length else "No samples in DB", cls="text-base font-semibold leading-6 text-gray-9000"),
Div(cls="flex-shrink-0")(
Arrow("ā", f"{Item.id - 2}" if Item.id > 0 else "#", Item.id),
Arrow("ā", f"{Item.id}" if Item.id < total_items_length - 1 else "#", Item.id))),
Div(cls="-ml-4 -mt-4 flex flex-wrap items-center justify-between sm:flex-nowrap")(
Div(cls="ml-4 mt-4")(
P(messages[0]['content'], cls="mt-1 text-sm text-gray-500 max-h-16 overflow-y-auto whitespace-pre-wrap"))))
card_buttons_form = Div(cls="mt-4")(
Form(cls="flex items-center", method="post", hx_post=f"{Item.id}", target_id=f"item_{Item.id}", hx_swap="outerHTML", hx_encoding="multipart/form-data")(
Input(type="text", name="notes", value=Item.notes, placeholder="Additional notes?", cls="flex-grow p-2 my-4 border border-gray-300 rounded-md text-sm focus:outline-none focus:ring-2 focus:ring-indigo-500 focus:border-indigo-500 bg-transparent"),
Div(cls="flex-shrink-0 ml-4")(
AnnotateButton('correct', Item.feedback),
AnnotateButton('incorrect', Item.feedback))))
# Card component
card = Div(cls=" flex flex-col h-full flex-grow overflow-auto", id=f"item_{Item.id}",
style="min-height: calc(100vh - 6rem); max-height: calc(100vh - 16rem);")(
card_header,
Div(cls="bg-white shadow rounded-b-lg p-4 pt-0 pb-10 flex-grow overflow-scroll")(
Div(messages[1]['content'], id="main_text", cls="mt-2 w-full rounded-t-lg text-sm whitespace-pre-wrap h-auto marked"),
card_buttons_form))
return card
hdrs=(tlink, dlink, picolink, MarkdownJS(), HighlightJS())
app, rt, texts_db, Item = fast_app('texts.db',hdrs=hdrs, render=render, bodykw={"data-theme":"light"},
id=int, messages=list, feedback=bool, notes=str, pk='id')
# Get Dummy Data
data_url = 'https://raw.githubusercontent.com/AnswerDotAI/fasthtml-example/main/annotate_text/data/dummy_data.jsonl'
response = httpx.get(data_url)
# Insert Dummy Data into Db
for line in response.text.splitlines():
item = json.loads(line)
texts_db.insert(messages=json.dumps(item), feedback=None, notes='')
```
--------------------------------
### FastHTML App Initialization
Source: https://github.com/answerdotai/fasthtml-gallery/blob/main/llms_ctx.txt
Initializes a FastHTML application with custom headers. This is typically done at the start of your application.
```python
app, rt = fast_app(hdrs=(plotly_headers,))
```
--------------------------------
### Cellular Automata Setup
Source: https://github.com/answerdotai/fasthtml-gallery/blob/main/llms_ctx.txt
This snippet sets up the foundational elements for a Cellular Automata simulation using FastHTML. It defines the rule binding, initial state, color mapping, and helper functions for creating the visual grid.
```python
from fasthtml.common import *
from starlette.responses import Response
from uuid import uuid4
generator = {}
bindict = {
(1,1,1):0,
(1,1,0):1,
(1,0,1):2,
(1,0,0):3,
(0,1,1):4,
(0,1,0):5,
(0,0,1):6,
(0,0,0):7}
initial_row = [0]*50 + [1] + [0]*50
color_map = {0:"white", 1:"black"}
```
```python
explanation = Div(
H1("Cellular Automata"),
H4("Input explanations:"),
Ul(Li(Strong("Rule: "),"Determines the next state of a cell based on the current state of the cell and its neighbors."),
Li(Strong("Generations: "),"Determines how many generations to run the automaton."),
Li(Strong("Width: "),"Determines the width of the grid."),))
def progress_bar(percent_complete: float):
return Div(hx_swap_oob="innerHTML:#progress_bar")(Progress(value=percent_complete))
def mk_box(color,size=5):
return Div(cls="box", style=f"background-color:{color_map[color]};height:{size}px;width:{size}px;margin:0;display:inline-block;")
def mk_row(colors,font_size=0,size=5):
return Div(*[mk_box(color,size) for color in colors], cls="row",style=f"font-size:{font_size}px;")
def mk_button(show):
return Button("Hide Rule" if show else "Show Rule",
hx_get="show_rule?show=" + ("False" if show else "True"),
hx_target="#rule", id="sh_rule", hx_swap_oob="outerHTML",
hx_include="[name='rule_number']")
```
--------------------------------
### Message History and Rendering Setup
Source: https://github.com/answerdotai/fasthtml-gallery/blob/main/llms_ctx.txt
Initializes a deque for storing recent messages and a dictionary for users. Sets up a style for message boxes and defines a function to render messages.
```python
from collections import deque
# All messages here, but only most recent 15 are stored
messages = deque(maxlen=15)
users = {}
# Takes all the messages and renders them
box_style = "border: 1px solid #ccc; border-radius: 10px; padding: 10px; margin: 5px 0;"
def render_messages(messages):
return Div(*[Div(m, style=box_style) for m in messages], id='msg-list')
```
--------------------------------
### Tic Tac Toe Game Setup
Source: https://github.com/answerdotai/fasthtml-gallery/blob/main/llms_ctx.txt
Initializes the FastHTML app for a Tic Tac Toe game, including global styles, headers with Tailwind CSS, and game state variables.
```python
from fasthtml.common import *
style = Style("""body{
min-height: 100vh;
margin:0;
background-color: #1A1A1E;
display:grid;
}""" ) # custom style to be applied globally.
hdrs = (Script(src="https://cdn.tailwindcss.com") ,
Link(rel="stylesheet", href="/files/examples/applications/tic_tac_toe/output.css"))
app, rt = fast_app(hdrs=(hdrs, style), pico=False)
current_state_index = -1 #Used to navigate the current snapshot of the board
button_states = [[None for _ in range(9)] for _ in range(9)] #2D array to store snapshots of board
win_states = [
[0, 1, 2],
[3, 4, 5],
[6, 7, 8],
[0, 3, 6],
[1, 4, 7],
[2, 5, 8],
[0, 4, 8],
[2, 4, 6],
] #possible win streaks/states for Xs and Os
winner_found_game_ended = False
def check_win(player) -> bool:
global button_states, current_state_index, winner_found_game_ended
"""Checks if there's a win streak present in the board. Uses the win states list to check
If text at all text indices are equal and its not the placeholder text ("."), change the global variable "winner_found_game_ended" to True"""
for cell_1, cell_2, cell_3 in win_states:
if (
```
--------------------------------
### Clickable SVG Circles with Timer
Source: https://github.com/answerdotai/fasthtml-gallery/blob/main/llms_ctx.txt
This example involves clicking SVG circles. It tracks the number of clicks and measures the time taken to click three circles.
```python
from fasthtml.common import *
from fasthtml.svg import *
from random import randint
from uuid import uuid4
import time
timer = {}
app, rt = fast_app(hdrs=[Script(src="https://d3js.org/d3.v7.min.js")])
class Timer:
def __init__(self):
self.start = time.time()
def stop(self):
self.stop = time.time()
return self.stop - self.start
def mk_circle(count):
return Circle(cx=randint(20,180),cy=randint(10,70),r=randint(5,15),fill="red",
id="circle",hx_get=f"click/{count+1}", hx_swap="outerHTML")
def mk_click_count(count):
return P(f"You have clicked {count} times",id="click-count")
@rt
def index(sess):
if 'id' not in sess: sess['id'] = str(uuid4())
return Div(
P("Click the circle 3 times"),
mk_click_count(0),P(id="timer"),
Svg(viewBox="0 0 200 80",id="svg-box")(mk_circle(0)))
@rt("/click/{count}")
def click(count: int,sess):
et = ""
if count == 1: timer[sess['id']] = Timer()
if count == 3:
elapsed_time=timer[sess['id']].stop()
count = 0
et=f"Time to click 3 times: {elapsed_time:.2f} seconds"
return SvgInb(mk_circle(count)),mk_click_count(count)(hx_swap_oob="outerHTML"),P(et,id="timer",hx_swap_oob="outerHTML")
serve()
```
--------------------------------
### FastHTML Active Search Example
Source: https://github.com/answerdotai/fasthtml-gallery/blob/main/llms_ctx.txt
Demonstrates an active search functionality using FastHTML and Htmx. It displays a list of contacts and allows filtering based on search input.
```python
from fasthtml.common import *
app, rt = fast_app()
# Example contacts data
contacts = [
{"first_name": "Venus", "last_name": "Grimes", "email": "lectus.rutrum@Duisa.edu"},
{"first_name": "Fletcher", "last_name": "Owen", "email": "metus@Aenean.org"},
{"first_name": "William", "last_name": "Hale", "email": "eu.dolor@risusodio.edu"},
{"first_name": "TaShya", "last_name": "Cash", "email": "tincidunt.orci.quis@nuncnullavulputate.co.uk"},
{"first_name": "Kevyn", "last_name": "Hoover", "email": "tristique.pellentesque.tellus@Cumsociis.co.uk"},
{"first_name": "Jakeem", "last_name": "Walker", "email": "Morbi.vehicula.Pellentesque@faucibusorci.org"},
{"first_name": "Malcolm", "last_name": "Trujillo", "email": "sagittis@velit.edu"},
{"first_name": "Wynne", "last_name": "Rice", "email": "augue.id@felisorciadipiscing.edu"},
{"first_name": "Evangeline", "last_name": "Klein", "email": "adipiscing.lobortis@sem.org"},
{"first_name": "Jennifer", "last_name": "Russell", "email": "sapien.Aenean.massa@risus.com"},
{"first_name": "Rama", "last_name": "Freeman", "email": "Proin@quamPellentesquehabitant.net"},
{"first_name": "Jena", "last_name": "Mathis", "email": "non.cursus.non@Phaselluselit.com"},
{"first_name": "Alexandra", "last_name": "Maynard", "email": "porta.elit.a@anequeNullam.ca"},
{"first_name": "Tallulah", "last_name": "Haley", "email": "ligula@id.net"},
{"first_name": "Timon", "last_name": "Small", "email": "velit.Quisque.varius@gravidaPraesent.org"},
]
# Mapping of keys to clean labels
mapping = {
"first_name": "First Name",
"last_name": "Last Name",
"email": "Email"
}
keys = list(mapping)
def show_contacts(contacts: list[dict]):
# HTML rows for all given contacts
return [Tr(*[Td(contact[col]) for col in keys]) for contact in contacts]
```
--------------------------------
### Dynamically Add Table Rows
Source: https://github.com/answerdotai/fasthtml-gallery/blob/main/llms_ctx.txt
Demonstrates how to dynamically add rows to an HTML table using HTMX. The 'Load More...' button triggers a GET request to 'add_row' which appends a new row to the table.
```python
from uuid import uuid4
from fasthtml.common import *
app, rt = fast_app()
agent_num = 0
@rt
def add_row():
global agent_num
agent_num += 1
return Tr(map(Td, (
f"Agent Smith {agent_num}",
f"smith{agent_num}@matrix.com",
uuid4())))
@rt
def index():
first_row = add_row()
return Div(
H1("Click to Load"),
P("Dynamically add rows to a table using HTMX."),
Table(Tr(map(Th, ("Name", "Email", "ID"))), first_row, id='tbl'),
Button("Load More...", get=add_row, hx_target="#tbl", hx_swap="beforeend"),
style="text-align: center;")
serve()
```
--------------------------------
### Delete Table Row Example
Source: https://github.com/answerdotai/fasthtml-gallery/blob/main/llms_ctx.txt
This snippet is a placeholder for an example demonstrating how to delete a row from an HTML table using Fasthtml and HTMX.
```python
from fasthtml.common import *
app, rt = fast_app()
```
--------------------------------
### Draggable SVG Rectangle with D3.js
Source: https://github.com/answerdotai/fasthtml-gallery/blob/main/llms_ctx.txt
An example of making an SVG rectangle draggable using D3.js. It requires including the D3.js library in the HTML headers.
```python
from fasthtml.common import *
from fasthtml.svg import *
app, rt = fast_app(hdrs=[Script(src="https://d3js.org/d3.v7.min.js")])
@rt
def index():
return Div(
P("Click and drag an SVG rectangle with D3"),
Svg(viewBox="0 0 200 200",id="svg-box")(
Rect(x=5,y=5,width=10,height=10,fill="red",id="rect")),
Script('''
window.onload = function() {
var svg = d3.select("svg");
var dragHandler = d3.drag()
.on("start", function (e) {
var current = d3.select(this);
deltaX = current.attr("x") - e.x;
deltaY = current.attr("y") - e.y;})
.on("drag", function (e) {
d3.select(this)
.attr("x", e.x+deltaX)
.attr("y", e.y+deltaY);});
svg.select("#rect").call(dragHandler);}
'''))
serve()
```
--------------------------------
### Altair Demo Index Page
Source: https://github.com/answerdotai/fasthtml-gallery/blob/main/llms_ctx.txt
Sets up the main page for the Altair demo. It includes a title, a placeholder for the chart, and a button to trigger chart updates.
```Python
@rt
def index():
return Title("Altair Demo"), Main(
H1("Altair Demo"),
Div(id="chart"),
Button("Increment", get=increment, hx_target="#chart", hx_swap="innerHTML"),
style="margin: 20px"
)
```
--------------------------------
### Importing Common and UI Components
Source: https://github.com/answerdotai/fasthtml-gallery/blob/main/llms_ctx.txt
This snippet demonstrates importing common Fasthtml components along with specific components from the monsterui library and datetime utilities.
```Python
from fasthtml.common import *
from datetime import date,datetime
from monsterui.all import *
```
--------------------------------
### Basic HTML Template with Toggle
Source: https://github.com/answerdotai/fasthtml-gallery/blob/main/llms_ctx.txt
Demonstrates creating a basic HTML structure with a toggleable content section using Fasthtml's templating capabilities.
```Python
from fasthtml.common import *
app, rt = fast_app()
def mk_button(show):
return Button("Toggle", id="toggle", hx_get="toggle", hx_target="#content", hx_swap="outerHTML", hx_vars={ 'show': not show })
@rt
def index():
return Div(mk_button(False), Div(id="content"))
@rt
def toggle(show: bool):
return Div(
Div(mk_button(show)),
Div(content if show else ''))
```
--------------------------------
### Configurable Select Input
Source: https://github.com/answerdotai/fasthtml-gallery/blob/main/llms_ctx.txt
Shows how to create a configurable select input with a search box using Fasthtml and MonsterUI. Options can be dynamically added via a form submission.
```python
from fasthtml.common import *
from monsterui.all import *
app, rt = fast_app(hdrs=Theme.blue.headers())
@rt
def index(): return Container(H1('Configurable Select'), mk_form())
@rt
def mk_form(add_option:str=None, options:str='isaac,hamel,curtis'):
opts = options.split(',')
if add_option: opts.append(add_option)
return Form(
# fh-frankenui helper that adds both a form label and input
# and does proper linking with for, id, and name automatically
LabelInput("Add an Option", id="add_option"),
Button("Add"),
# fh-frankenui select allows for search boxes
Select(map(Option, opts), searchable=True),
# When the "Add" button is pressed, make a new form
get=mk_form,
# Store options state in DOM
hx_vals={"options": ','.join(opts)},
# Replace the whole form
hx_swap="outerHTML")
serve()
```
--------------------------------
### Main Page Index Route
Source: https://github.com/answerdotai/fasthtml-gallery/blob/main/llms_ctx.txt
Renders the main page of the todo application, displaying the title, a todo form, and the list of todos.
```Python
@rt
async def index():
"""Main page of the app"""
return Titled('Todo List',mk_todo_form(),Div(mk_todo_list(),id='todo-list'))
```
--------------------------------
### FastHTML Quantum Gate Application Route
Source: https://github.com/answerdotai/fasthtml-gallery/blob/main/llms_ctx.txt
Handles the application of quantum gates to a state and updates the visualization. This route is triggered by user interaction with the buttons on the index page.
```python
@app.get('/apply_gate/{gate}')
def update_state_apply_gate(gate: str=None, gates: str=None):
if gates is None: gates = []
else:
# Transform from circuit representation to gate names
gates = [g for g in gates if g in single_qubit_gates.keys()]
gates.append(gate)
# Create initial state
state = np.array([1, 0]) # |0> basis state
for gate in gates: state = single_qubit_gates[gate] @ state
# Create visualization
return Div(plot_bloch(state),
H4(f"Quantum Circuit: {visualize_circuit(gates)}", id="quantum_circuit"),
id="chart")
```
--------------------------------
### Cascading Dropdowns with Fasthtml
Source: https://github.com/answerdotai/fasthtml-gallery/blob/main/llms_ctx.txt
Implements cascading dropdowns where selecting a chapter dynamically loads its corresponding lessons using Fasthtml.
```python
from fasthtml.common import *
app, rt = fast_app()
chapters = ['ch1', 'ch2', 'ch3']
lesssons = {
'ch1': ['lesson1', 'lesson2', 'lesson3'],
'ch2': ['lesson4', 'lesson5', 'lesson6'],
'ch3': ['lesson7', 'lesson8', 'lesson9']}
def mk_opts(nm, cs):
return (
Option(f'-- select {nm} --', disabled='', selected='', value=''),
*map(Option, cs))
@rt
def get_lessons(chapter: str):
return Select(*mk_opts('lesson', lessons[chapter]), name='lesson')
@rt
def index():
chapter_dropdown = Select(
*mk_opts('chapter', chapters),
name='chapter',
get='get_lessons', hx_target='#lessons')
return Div(
Div(Label("Chapter:", for_="chapter"),
chapter_dropdown),
Div(Label("Lesson:", for_="lesson"),
Div(Div(id='lessons')),
))
serve()
```
--------------------------------
### Data Annotation Tool with FastHTML
Source: https://github.com/answerdotai/fasthtml-gallery/blob/main/llms_ctx.txt
This snippet demonstrates a basic web application for annotating text data. It includes routes for displaying items, submitting feedback, and updating the database. Ensure you have a `texts_db` function available.
```python
total_items_length = len(texts_db())
print(f"Inserted {total_items_length} items from dummy data")
@rt("/{idx}")
def post(idx: int, feedback: str = None, notes: str = None):
print(f"Posting feedback: {feedback} and notes: {notes} for item {idx}")
items = texts_db()
item = texts_db.get(idx)
item.feedback, item.notes = feedback, notes
texts_db.update(item)
next_item = next((i for i in items if i.id > item.id), items[0])
print(f"Updated item {item.id} with feedback: {feedback} and notes: {notes} moving to {next_item.id}")
return next_item
@rt("/")
@rt("/{idx}")
def get(idx:int = 0):
items = texts_db()
index = idx
if index >= len(items): index = len(items) - 1 if items else 0
# Container for card and buttons
content = Div(cls="w-full max-w-2xl mx-auto flex flex-col max-h-full")(H1('LLM generated text annotation tool with FastHTML (and Tailwind)',cls="text-xl font-bold text-center text-gray-800 mb-8"),
items[index])
return Main(content,
cls="container mx-auto min-h-screen bg-gray-100 p-8 flex flex-col",
hx_target="this")
```
--------------------------------
### FastHTML Index Route with Interactive Bloch Sphere
Source: https://github.com/answerdotai/fasthtml-gallery/blob/main/llms_ctx.txt
Defines the main index route for a FastHTML application. It sets up an interactive Bloch Sphere visualization with buttons to apply quantum gates.
```python
app, rt = fast_app(hdrs=(plotly_headers,))
@rt
def index():
desc = """
The Bloch Sphere is a 3D visualization of a single quantum state.
You can interact with the buttons (Gates) to see how the state changes. See the description below for more information on what each gate represents.
"""
hx_vals = 'js:{"gates": document.getElementById("quantum_circuit").textContent}'
return (Title("Interactive Bloch Sphere"),
Main(P(desc),
*[Button(gate, hx_get=f"apply_gate/{gate}", hx_target="#chart", hx_swap="innerHTML", hx_vals=hx_vals, title=f"Apply {gate} gate") for gate in single_qubit_gates.keys()],
Button("Reset", hx_get="reset", hx_target="#chart", hx_swap="innerHTML", title="Reset the circuit"),
Div(update_state_apply_gate.__wrapped__(), id="chart"),
H4("Available gates"),
Ul(Li(Strong("H : "),"Hadamard gate. Puts the state in superposition. "),
Li(Strong("X : "),"Pauli-X (NOT) gate. Rotate 180 degrees around the X-Axis."),
Li(Strong("Y : "),"Pauli-Y ("bit-flip") gate. Rotate 180 degrees around the Y-Axis."),
Li(Strong("Z : "),"Pauli-Z ("phase-flip") gate. Rotate 180 degrees around the Z-Axis."),
Li(Strong("S : "),"Phase gate. Rotates around the Z-axis by 90 degrees."),
Li(Strong("T : "),"Ļ/8 gate. Rotates around the Z-axis by 45 degrees."))))
@rt
def reset(): return update_state_apply_gate.__wrapped__()
```
--------------------------------
### FastHTML Route to Display Rule Details
Source: https://github.com/answerdotai/fasthtml-gallery/blob/main/llms_ctx.txt
Handles requests to display detailed information about a specific rule. It formats the rule number into a binary representation and conditionally displays rule components.
```python
@rt('/show_rule')
def get(rule_number: int, show: bool):
rule = [int(x) for x in f'{rule_number:08b}']
return Div(
Div(mk_button(show)),
Div(*[Group(
Div(mk_row(list(k),font_size=10,size=20),style="max-width:100px"),
Div(P(" -> "),style="max-width:100px"),
Div(mk_box(rule[v],size=20),style="max-width:100px")) for k,v in bindict.items()] if show else '')
)
```
--------------------------------
### Custom Keybindings with HTMX
Source: https://github.com/answerdotai/fasthtml-gallery/blob/main/llms_ctx.txt
Illustrates how to trigger actions using custom keybindings with HTMX. The button can be activated by a click or by pressing the 'U' key when focus is in the body.
```python
from fasthtml.common import *
app, rt = fast_app()
@rt
def index():return Titled(
"Custom Keybindings with HTMX",
render_button("DO IT (Press `Shift + u`)"))
@rt
def doit(): return render_button("š DID IT! ")
def render_button(text):
return Button(text,
# Auto-focus on load
autofocus=True,
# Activate with click or U key as long as focus is in body
hx_trigger="click, keyup[key=='U'] from:body",
get=doit)
serve()
```
--------------------------------
### Two Column Form Grid with Live Updates
Source: https://github.com/answerdotai/fasthtml-gallery/blob/main/llms_ctx.txt
Implements a two-column layout with a form on the left and a results area on the right. Form inputs trigger updates in the results section with a delay.
```Python
from fasthtml.common import *
app, rt = fast_app()
@rt
def index():
return Titled('Try editing fields:',
Grid(Div(
Form(post="submit", hx_target="#result", hx_trigger="input delay:200ms")(
Select(Option("One"), Option("Two"), id="select"),
Input(value='j', id="name", placeholder="Name"),
Input(value='h', id="email", placeholder="Email")
)),
Div(id="result")))
@rt
def submit(d:dict):
return Div(*[Div(P(Strong(k),': ',v)) for k,v in d.items()])
serve()
```
--------------------------------
### FastHTML Quantum Circuit Visualization Function
Source: https://github.com/answerdotai/fasthtml-gallery/blob/main/llms_ctx.txt
A helper function to generate a string representation of the quantum circuit. This is used to display the current state of the circuit.
```python
def visualize_circuit(gates: list[str]):
circuit = "|0ā©-"
circuit += "".join([f"[{gate}]ā" for gate in gates]) + "|"
return circuit
```
--------------------------------
### FastHTML Route to Run Cellular Automaton Simulation
Source: https://github.com/answerdotai/fasthtml-gallery/blob/main/llms_ctx.txt
Executes the cellular automaton simulation based on provided rule, generations, and width. It includes input validation and returns either an error message or the simulation grid.
```python
@rt('/run')
def get(rule_number: int, generations: int, width: int, sess):
errors = {'rule_number': validate_rule_number(rule_number),
'generations': validate_generations(generations),
'width': validate_width(width)}
# Removes the None values from the errors dictionary (No errors)
errors = {k: v for k, v in errors.items() if v is not None}
# Return Button with error message if they exist
if errors:
return Div(Div(id="grid"),
Div(id="progress_bar",hx_swap_oob="outerHTML:#progress_bar"),
Div(id='submit-btn-container',hx_swap_oob="outerHTML:#submit-btn-container")(
Button(cls="btn btn-active btn-primary", type="submit",
hx_get="run", hx_target="#grid",
hx_include="[name='rule_number'],[name='generations'],[name='width']", hx_swap="outerHTML")("Run"),
*[Div(error, style='color: red;') for error in errors.values()]))
start = [0]*(width//2) + [1] + [0]*(width//2)
global generator
generator[sess['id']] = run(rule=rule_number,generations=generations,start=start)
return Div(
Div(style=f"width: {(width+1)*5}px",id="progress_bar",hx_swap_oob="outerHTML:#progress_bar"),
Div(id="next",hx_trigger="every .1s", hx_get="next", hx_target="#grid",hx_swap="beforeend"),id="grid")
```
--------------------------------
### Todo List Form Submission
Source: https://github.com/answerdotai/fasthtml-gallery/blob/main/llms_ctx.txt
This snippet shows how to create a todo list with a form that adds items to the list. The input field is reset using hx_swap_oob after submitting a message.
```Python
add = Form(Group(mk_input(), Button("Add")),
post="insert_todo", target_id='todo-list', hx_swap="beforeend")
card = Card(Ul(*todos(), id='todo-list'), header=add, footer=Div(id='current-todo')),
title = 'Todo list'
return Title(title), Main(H1(title), card, cls='container')
```
```Python
@rt
async def insert_todo(todo:Todo):
if not todo.title.strip():
return mk_input(hx_swap_oob='true')
return todos.insert(todo), mk_input( hx_swap_oob='true')
serve()
```
--------------------------------
### FastHTML Route to Fetch Next Simulation Step
Source: https://github.com/answerdotai/fasthtml-gallery/blob/main/llms_ctx.txt
Fetches the next step of the cellular automaton simulation. It updates the progress bar and the grid, or signals completion if the simulation is finished.
```python
@rt('/next')
def get(sess):
global generator
g,val = next(generator[sess['id']],(False,False))
if val: return Div(
progress_bar(g),
mk_row(val))
else:
del generator[sess['id']]
return Response(status_code=286)
```
--------------------------------
### Plot Bloch Sphere with Plotly
Source: https://github.com/answerdotai/fasthtml-gallery/blob/main/llms_ctx.txt
Generates an interactive 3D Bloch sphere visualization for a given quantum state vector using Plotly and Fasthtml. Requires numpy and plotly libraries.
```python
import numpy as np
import plotly.graph_objects as go
from fasthtml.common import plotly2fasthtml
def calculate_coordinates(theta, phi):
x = np.sin(theta) * np.cos(phi)
y = np.sin(theta) * np.sin(phi)
z = np.cos(theta)
return x, y, z
def create_scenes():
axis2ticktext = {'X': ['|-ā©', '|+ā©'], 'Y': ['|-iā©', '|iā©'], 'Z': ['|1ā©', '|0ā©']}
scenes = {}
for axis in ['X','Y','Z']:
scenes[f'{axis.lower()}axis'] = dict(title=dict(text=axis, font=dict(size=25)),
range=[-1.2, 1.2], tickvals=[-1, 1],
ticktext=axis2ticktext[axis],
tickfont=dict(size=15) )
return scenes
def plot_bloch(state: np.array):
fig = go.Figure()
# State vector coordinates
alpha, beta = state[0], state[1]
theta = 2 * np.arccos(np.abs(alpha))
phi = np.angle(beta) - np.angle(alpha)
x, y, z = calculate_coordinates(theta, phi)
# Surface coordinates
surface_phi, surface_theta = np.mgrid[0:2*np.pi:100j, 0:np.pi:50j]
xs, ys, zs = calculate_coordinates(surface_theta, surface_phi)
fig.add_trace(go.Surface(x=xs, y=ys, z=zs, opacity=0.5, colorscale='Blues', showscale=False))
fig.add_trace(go.Scatter3d(x=[0, x],y=[0, y],z=[0, z], mode='lines+markers+text', marker=dict(size=10, color='green'),
line=dict(color='green', width=8), textposition="top center", showlegend=True,name=f"{alpha:.2f}|0ā© + {beta:.2f}|1ā©"))
# Mark basis states
fig.add_trace(go.Scatter3d(x=[0, 0, 1, -1, 0, 0],y=[0, 0, 0, 0, 1, -1], z=[1, -1, 0, 0, 0, 0],
mode='markers', marker=dict(size=5, color='black'), hovertext=['|0ā©', '|1ā©', '|+ā©', '|-ā©', '|iā©', '|-iā©'],
showlegend=False, name="Basis states"))
# Add lines across axes
boundary_phi = np.linspace(0, 2 * np.pi, 100)
coords = [(np.cos(boundary_phi), np.sin(boundary_phi), np.zeros_like(boundary_phi)),
(np.zeros_like(boundary_phi), np.cos(boundary_phi), np.sin(boundary_phi)),
(np.cos(boundary_phi), np.zeros_like(boundary_phi), np.sin(boundary_phi)) ]
for x, y, z in coords:
fig.add_trace(go.Scatter3d(x=x, y=y, z=z, mode='lines', line=dict(color='black', width=2), showlegend=False, name="Axes"))
fig.update_layout(scene=dict(**create_scenes(), aspectmode='cube',),
legend=dict( font=dict(size=20), x=0.05,y=0.95, xanchor='left', yanchor='top', bgcolor='rgba(0,0,0,0)',),
margin=dict(l=0, r=0, t=0, b=0))
return plotly2fasthtml(fig)
```
--------------------------------
### Loading Indicator with HTMX
Source: https://github.com/answerdotai/fasthtml-gallery/blob/main/llms_ctx.txt
Demonstrates how to use a loading indicator while an HTMX request is in progress. This provides visual feedback to the user during asynchronous operations.
```python
from fasthtml.common import *
from monsterui.all import *
import asyncio
app, rt = fast_app(hdrs=Theme.blue.headers())
@rt
def index():
return Titled("Loading Demo",
# Button to trigger an HTMX request
Button("Load", id='load',
# Trigger HTMX request to add content to #content
get=load, hx_target='#content', hx_swap='beforeend',
# While request in flight, show loading indicator
hx_indicator='#loading'),
# A place to put content from request
Div(id='content'),
# Loading indicator ready for htmx use
# For more options see https://monsterui.answer.ai/api_ref/docs_loading
Loading(id='loading', htmx_indicator=True))
@rt
async def load():
# Sleep for a second to simulate a long request
await asyncio.sleep(1)
return P("Loading Demo")
serve()
```