RuleStack

Configs

Stacks

Compare

Diff

RuleStack

Configs

Stacks

Compare

Diff

Read API

RuleStack

Configs

Stacks

Compare

Diff

Read API

Configs/Cursor rules/ai-evals-course/isaac-fasthtml-workshop

Cursor rule

.cursor/rules/fasthtml.mdc

[object Object]

Cursor rules

Quality

81/100

Scores the file, not the repository.

Length

1,195 words

30 headings · 13 code blocks

Repository

69

— · pushed 363 days ago

Last changed

3 days ago

First indexed 3 days ago.
ai-evals-course/isaac-fasthtml-workshop/.cursor/rules/fasthtml.mdcRawGitHub
1---
2description:
3globs: fasthtml_app/**/*
4alwaysApply: false
5---
6 
7# Project Structure
8 
9The main file for the project is [main_sqlite.py](mdc:fasthtml_app/main_sqlite.py) It uses MonsterUI for styling. MonsterUI is a python first UI component library that primarily leverages FrankenUI and Tailwind, but also includes headers and functionality form DaisyUI, Katex, HighlightJS, and others.
10 
11You can run the server with the command `python app/main_sqlite.py`, which will start the server on http://localhost:5001.
12 
13# Tech Stack
14 
15- FastHTML is the web application framework. It is built on top of starlette and uvicorn.
16- MonsterUI is a UI component library designed to work well with FastHTML
17- Fastlite is a sqlite library that is a small wrapper on top of sqlite-utils
18 
19# Key documentation files:
20 
21These are relevant documents that should be referenced while building a FastHTML App.
22 
23- [fasthtml.mdc](mdc:.cursor/rules/fasthtml.mdc): Minimal HTMX integration exaples to show how HTMX can be used with fasthtml
24- [db.md](mdc:ref_docs/db.md): MiniDataAPI Spec for database operations
25- [monsterui_api.md](mdc:ref_docs/monsterui_api.md).md : MonsterUI full API list and idiomatic examples for UI components
26 
27# FastHTML examples
28 
29Reference these examples when constructing new FastHTML applications.
30 
31- [annotation.md](mdc:ref_docs/annotation.md): A siple example of a annotation app to evaluate search results.
32- Adv_app: Example FastHTML To-Do-List application that demonstrates core FastHTML features including authentication, HTMX integration, and database operations. It allows users to create, edit, delete, and reorder todos with markdown support, using SQLite for storage.
33 
34# FastHTML Rules
35 
36- Use `serve()` directly - no need for uvicorn or separate ASGI server
37- Not compatible with FastAPI syntax - FastHTML is for HTML-first apps, not API services
38- Define routes with decorators and return HTML components or strings
39- Use python FastTags (ie `Div`, `P`) instead of raw HTML where possible
40- Use HTMX for interactive features, vanilla JS where needed. No React/Vue/Svelte
41 
42# UI Design Elements with MonsterUI
43 
44- Use defaults as much as possible, for example `Container` in monsterui already has defaults for margins
45- Use `*T` for button styling consistency, for example `ButtonT.destructive` for a red delete button or `ButtonT.primary` for a CTA button
46- Use `Label*` functions for forms as much as possible (e.g. `LabelInput`, `LabelRange`) which creates and links both the `FormLabel` and user input appropriately to avoid boiler plate
47 
48## Basic Complete App Example
49 
50```python
51from fasthtml.common import *
52from monsterui.all import *
53 
54app, rt = fast_app(hdrs=Theme.blue.headers()) # Use MonsterUI blue theme
55 
56@rt
57def index():
58 socials = (('github','https://github.com/AnswerDotAI/MonsterUI'),
59 ('twitter','https://twitter.com/isaac_flath/'),
60 ('linkedin','https://www.linkedin.com/in/isaacflath/'))
61 return Titled("Your First App",
62 Card(
63 P("Your first MonsterUI app", cls=TextPresets.muted_sm),
64 # LabelInput, DivLAigned, and UkIconLink are non-semantic MonsterUI FT Components,
65 LabelInput('Email', type='email', required=True),
66 footer=DivLAligned(*[UkIconLink(icon,href=url) for icon,url in socials])))
67```
68 
69## Card and Flex Layout Components Example
70 
71```python
72def TeamCard(name, role, location="Remote"):
73 icons = ("mail", "linkedin", "github")
74 return Card(
75 DivLAligned(
76 DiceBearAvatar(name, h=24, w=24),
77 Div(H3(name), P(role))),
78 footer=DivFullySpaced(
79 DivHStacked(UkIcon("map-pin", height=16), P(location)),
80 DivHStacked(*(UkIconLink(icon, height=16) for icon in icons))))
81```
82 
83## Forms and User Inputs Example
84 
85```python
86def MonsterForm():
87 relationship = ["Parent",'Sibling', "Friend"]
88 return Div(
89 DivCentered(
90 H3("Emergency Contact Form"),
91 P("Please fill out the form completely", cls=TextPresets.muted_sm)),
92 Form(
93 Grid(LabelInput("Name",id='name'),LabelInput("Email", id='email')),
94 H3("Relationship to patient"),
95 Grid(*[LabelCheckboxX(o) for o in relationship], cols=4, cls='space-y-3'),
96 DivCentered(Button("Submit Form", cls=ButtonT.primary))),
97 cls='space-y-4')
98```
99 
100## Markdown Text Styling Example
101 
102```python
103render_md("""
104# My Document
105 
106> Important note here
107 
108+ List item with **bold**
109+ Another with `code`
110 
111```python
112def hello():
113 print("world")
114```
115""")
116```
117 
118## Semantic Text Styling Example
119 
120```python
121def SemanticText():
122 return Card(
123 H1("MonsterUI's Semantic Text"),
124 P(
125 Strong("MonsterUI"), " brings the power of semantic HTML to life with ",
126 Em("beautiful styling"), " and ", Mark("zero configuration"), "."),
127 Blockquote(
128 P("Write semantic HTML in pure Python, get modern styling for free."),
129 Cite("MonsterUI Team")),
130 footer=Small("Released February 2025"),)
131```
132 
133# Data Storage
134 
135- `fastlite` (SQLite) included and preferred.
136- `sqlite-utils` is also a good option and sqlite-utils is compatible with fastlite
137 
138## Creating Tables
139 
140```python
141class Book: isbn: str; title: str; pages: int; userid: int
142# The transform arg instructs fastlite to change the db schema when fields change.
143# Create only creates a table if the table doesn't exist.
144books = db.create(Book, pk='isbn', transform=True)
145
146class User: id: int; name: str; active: bool = True
147# If no pk is provided, id is used as the primary key.
148users = db.create(User, transform=True)
149```
150 
151## Crud operations
152 
153```python
154# creating records
155user = users.insert(name='Alex',active=False)
156# List all records
157users()
158# Limit, offset, and order results:
159users(order_by='name', limit=2, offset=1)
160# Filter on the results
161users(where="name='Alex'")
162# Placeholder for avoiding injection attacks
163users("name=?", where_args=('Alex',))
164# fetch by primary key
165users[user.id]
166# Record exists check based on primary key
1671 in users
168# Updates
169user.name='Lauren'
170user.active=True
171users.update(user)
172# Deleting records
173users.delete(user.id)
174```
175 
176# Interactivity
177 
178JS can be added via a `Script` tag. Small scripts should be inline, where larger ones should use a seperate `.js` file.
179 
180```python
181def index():
182 data = {'somedata':'fill me in…'}
183 # `Titled` returns a title tag and an h1 tag with the 1st param, along with all other params as HTML in a `Main` parent element.
184 return Titled("Chart Demo", Div(id="myDiv"), Script(f"var data = {data}; Plotly.newPlot('myDiv', data);"))
185```
186 
187However, it is preferred to use HTMX. See a few examples of how HTMX with FastHTMl and MonsterUI works.
188 
189## File Upload Example
190 
191```python
192@rt
193def index():
194 inp = Card(
195 H3("Drag and drop images here"),
196 # HTMX for uploading multiple images
197 Input(type="file",name="images", multiple=True, required=True,
198 # Call the upload route on change
199 hx_post=upload, hx_target="#image-list", hx_swap="afterbegin", hx_trigger="change",
200 # encoding for multipart
201 hx_encoding="multipart/form-data",accept="image/*"))
202 
203 return DivCentered(inp, H3("👇 Uploaded images 👇"), Div(id="image-list"))
204 
205async def ImageCard(image):
206 contents = await image.read()
207 # Create a base64 string
208 img_data = f"data:{image.content_type};base64,{b64encode(contents).decode()}"
209 # Create a card with the image
210 return Card(H4(image.filename), Img(src=img_data, alt=image.filename))
211 
212@rt
213async def upload(images: list[UploadFile]):
214 # Create a grid filled with 1 image card per image
215 return Grid(*[await ImageCard(image) for image in images])
216```
217 
218## Cascading DropDown Example
219 
220```python
221def mk_opts(nm, cs):
222 return (
223 ft.Option(f'-- select {nm} --', disabled='', selected='', value=''),
224 *map(ft.Option, cs))
225 
226@rt
227def get_lessons(chapter: str):
228 return ft.Select(*mk_opts('lesson', lessons[chapter]), name='lesson')
229 
230@rt
231def index():
232 chapter_dropdown = ft.Select(
233 *mk_opts('chapter', chapters),
234 name='chapter',
235 hx_get=get_lessons, hx_target='#lessons',
236 label='Chapter:')
237 
238 return Container(
239 DivLAligned(FormLabel("Chapter:", for_="chapter"),chapter_dropdown),
240 DivLAligned(
241 FormLabel("Lesson:", for_="lesson"),
242 Div(id='lessons')),
243 cls='space-y-4')
244```
245 
246 
247 
248Session data in Websockets
249Session data is shared between standard HTTP routes and Websockets. This means you can access, for example, logged in user ID inside websocket handler:
250```
251 
252from fasthtml.common import *
253 
254app = FastHTML(exts='ws')
255rt = app.route
256 
257@rt('/login')
258def get(session):
259 session["person"] = "Bob"
260 return "ok"
261 
262@app.ws('/ws')
263async def ws(msg:str, send, session):
264 await send(Div(f'Hello {session.get("person")}' + msg, id='notifications'))
265 
266serve()
267```
268 
269 
270```
271 Real-Time Chat App
272Let’s put our new websocket knowledge to use by building a simple chat app. We will create a chat app where multiple users can send and receive messages in real time.
273 
274Let’s start by defining the app and the home page:
275 
276from fasthtml.common import *
277 
278app = FastHTML(exts='ws')
279rt = app.route
280 
281msgs = []
282@rt('/')
283def home(): return Div(
284 Div(Ul(*[Li(m) for m in msgs], id='msg-list')),
285 Form(Input(id='msg'), id='form', ws_send=True),
286 hx_ext='ws', ws_connect='/ws')
287 
288Now, let’s handle the websocket connection. We’ll add a new route for this along with an on_conn and on_disconn function to keep track of the users currently connected to the websocket. Finally, we will handle the logic for sending messages to all connected users.
289 
290users = {}
291def on_conn(ws, send): users[str(id(ws))] = send
292def on_disconn(ws): users.pop(str(id(ws)), None)
293 
294@app.ws('/ws', conn=on_conn, disconn=on_disconn)
295async def ws(msg:str):
296 msgs.append(msg)
297 # Use associated `send` function to send message to each user
298 for u in users.values(): await u(Ul(*[Li(m) for m in msgs], id='msg-list'))
299 
300serve()
301```
302 
303 
304 
305 
306 

Commands it names

  • python app/main_sqlite.py

Sections

  • Project Structure
  • Tech Stack
  • Key documentation files:
  • FastHTML examples
  • FastHTML Rules
  • UI Design Elements with MonsterUI
  • Basic Complete App Example
  • Card and Flex Layout Components Example
  • Forms and User Inputs Example
  • Markdown Text Styling Example
  • My Document
  • Semantic Text Styling Example
  • Data Storage
  • Creating Tables
  • The transform arg instructs fastlite to change the db schema when fields change.
  • Create only creates a table if the table doesn't exist.
  • If no pk is provided, id is used as the primary key.
  • Crud operations
  • creating records
  • List all records
  • Limit, offset, and order results:
  • Filter on the results
  • Placeholder for avoiding injection attacks
  • fetch by primary key
  • Record exists check based on primary key
  • Updates
  • Deleting records
  • Interactivity
  • File Upload Example
  • Cascading DropDown Example

What it covers

architecturetypesdatabaseuido-notdocs

Stack — with the evidence

react

(0.70)

fastapi

(0.70)

vite

(0.70)

javascript

(0.50)

python

(0.50)

Glob targeting

  • fasthtml_app/**/*

Format

Cursor rules

The most expressive format here. Many small .mdc files, each with frontmatter declaring when it should load, so a rule about migrations only enters context when a migration is open. Costs the most to maintain and only one editor reads it.

What the corpus says about it

Repository

Owner
ai-evals-course
Language
—
License
—
Archived
no

All configs in this repo

Also in ai-evals-course/isaac-fasthtml-workshop

Diff this repo’s formats

One repository carrying more than one format is the comparison this product exists for: does anyone actually write different content in each file, or is one a copy of the other?

The other instruction files in this repository
RepositoryFormatStackCoversScoreChanged
ai-evals-course/isaac-fasthtml-workshop.cursor/rules/fastapi-react-backend-rules.mdc · 69Cursor rulesreactfastapi+3lint-formatstyledependenciesdo-not40/1003 days ago
ai-evals-course/isaac-fasthtml-workshop.cursor/rules/fastapi-react-frontend-rules.mdc · 69Cursor rulesreactfastapi+3lint-formatstyledependenciesdo-not54/1003 days ago
ai-evals-course/isaac-fasthtml-workshop.cursor/rules/htmx.mdc · 69Cursor rulesreactfastapi+3database54/1003 days ago
ai-evals-course/isaac-fasthtml-workshop.cursor/rules/ui.mdc · 69Cursor rulesreactfastapi+3no sections16/1003 days ago
Diff against .cursor/rules/fastapi-react-backend-rules.mdc Diff against .cursor/rules/fastapi-react-frontend-rules.mdc Diff against .cursor/rules/htmx.mdc Diff against .cursor/rules/ui.mdc

Similar configs

Same format, overlapping stack, ranked by quality.

Same format, overlapping stack, ranked by quality
RepositoryFormatStackCoversScoreChanged
TechSquidTV/Hermes.cursor/rules/10-hermes-api.mdc · 45Cursor rulestypescriptpytest+15testlint-formatstylearch+5100/1003 days ago
dodgecfr/combatfilms-webapp.cursor/rules/frontend.mdc · 0Cursor rulestypescriptturborepo+15setuptestlint-formatstyle+799/1003 days ago
deifos/clipmira-subtitles.cursor/rules/frontend.mdc · 1Cursor rulestypescriptnextjs+5setuptestlint-formatstyle+799/1003 days ago
markstev/mark-starter.cursor/rules/frontend.mdc · 0Cursor rulestypescriptturborepo+14setuptestlint-formatstyle+699/1003 days ago
Allymahmoud/case-intake-platform.cursor/rules/frontend.mdc · 0Cursor rulestypescriptturborepo+13setuptestlint-formatstyle+799/1003 days ago
langflow-ai/langflow.cursor/rules/docs_development.mdc · 153kCursor rulespythonnode+16setupbuildtestlint-format+797/1003 days ago
TechSquidTV/Hermes.cursor/rules/20-hermes-api-tests.mdc · 45Cursor rulestypescriptpytest+15teststyletesting-strategysecurity+397/1003 days ago
skillrecordings/egghead-next.cursor/rules/gh-task-plan.mdc · 1.4kCursor rulestypescriptnode+14teststylearchtypes+296/1003 days ago
RuleStack

Built by

Kynth Studio

Directory

Configs
Stacks
Compare formats
Diff two configs
Best AGENTS.md examples

Formats

AGENTS.md
CLAUDE.md
Cursor rules
Copilot instructions

Reference

Read API
Corpus health
Privacy Policy
Terms

RuleStack

RuleStack

Built by

Kynth Studio

Directory

Configs
Stacks
Compare formats
Diff two configs
Best AGENTS.md examples

Formats

AGENTS.md
CLAUDE.md
Cursor rules
Copilot instructions

Reference

Read API
Corpus health
Privacy Policy
Terms

RuleStack

RuleStack

Built by

Kynth Studio

Directory

Configs
Stacks
Compare formats
Diff two configs
Best AGENTS.md examples

Formats

AGENTS.md
CLAUDE.md
Cursor rules
Copilot instructions

Reference

Read API
Corpus health
Privacy Policy
Terms

RuleStack