A collection of utilities for FastHTML projects
Project description
fh_utils
A collection of utilities for FastHTML projects
Features
- Jupyter notebook extension to run FastHTML apps.
- Add Tailwind CSS / DaisyUI to your app without any boilerplate.
- Icon packs: Heroicons, Ionicons, Phosphor, Lucide, FontAwesome, Bootstrap, Boxicons.
Docs
Installation
pip install fh_utils
uv add fh_utils
If you don’t like to pip install, feel free to copy and paste the code! The project is structured to make copying and pasting easy.
Jupyter Extension
One line magic to serve your app
and displaying in the notebook
from fasthtml.common import Title, Main, H1, P, Button, fast_app
app, rt = fast_app()
count = 0
@rt("/")
def home():
return Title("Count Demo"), Main(
H1("Count Demo"),
P(f"Count is set to {count}", id="count"),
Button("Increment", hx_post="/increment", hx_target="#count", hx_swap="innerHTML"),
)
@rt
def increment():
global count
count += 1
return f"Count is set to {count}"
%load_ext fh_utils
%fh app
The line magic can be used multiple time in the notebook
print("Current count is", count) # new value
count = 1234
%fh app
Full syntax
%fh?
%fh app [--page PAGE] [-w WIDTH] [-h HEIGHT] [-p PORT] app
Tailwindcss and Daisycss
Add Tailwind/Daisy to your app without any boilerplate
from fh_utils.tailwind import add_daisy_and_tailwind, add_tailwind, tailwind_compile
app, rt = fast_app(pico=False, static_path="public")
# Usage 1: Add Tailwind CSS
# The output css is saved as temporary file and served at /fh-utils/tailwindcss
add_tailwind(app)
# Usage 2: Add DaisyUI along with Tailwind CSS
add_daisy_and_tailwind(app)
# Usage 3: Customize Tailwind configuration
add_tailwind(app, cfg=Path("tailwind.config.js").read_text(), css="your custom css")
# Usage 4: Serve via FastHTML's static route
# Note: Don't forget to add public/app.css to your .gitignore
tailwind_compile("public/app.css")
app, rt = fast_app(hdrs=[Link(rel="stylesheet", href="app.css")], pico=False, static_path="public")
The Tailwind CLI is automatically downloaded, and your CSS files are compiled, served, and integrated into your app.
[!NOTE]
Under the hood, we use the bundle provided by dobicinaitis/tailwind-cli-extra. Please consider giving the author a star for recognition.
Bonus: Using Tailwind CSS IntelliSense in VSCode
-
Install the Tailwind CSS IntelliSense extension
-
Create a
tailwind.config.js
file at the root of your project and ensure that */.py is included in the content paths:
module.exports = {
content: ["**/*.py"],
};
See here for a full example of config
- Add the following settings to your .vscode/settings.json file to enable IntelliSense support for Tailwind classes in Python:
{
"tailwindCSS.classAttributes": ["class", "cls"],
"tailwindCSS.includeLanguages": {
"python": "html"
}
}
Icons
The icons are downloaded from github and saved in cache.
https://phosphoricons.com - MIT
https://heroicons.com - MIT
https://ionic.io/ionicons - MIT
https://lucide.dev - Lucide License
https://fontawesome.com - CC BY 4.0
https://icons.getbootstrap.com - MIT
https://boxicons.com - MIT
from fh_utils.icons import HeroIcon, IonIcon, LcIcon, PhIcon, FaIcon, BsIcon, BoxIcon
# Works nicely with tailwind
kw = dict(cls="size-10 fill-green-100 stroke-red-500 rotate-45")
PhIcon("airplane-in-flight", **kw)
Heroicon("chart-bar-square", **kw)
IonIcon("boat", **kw)
LcIcon("message-square-heart", **kw)
FaIcon("bell", **kw)
BsIcon("bell", **kw)
BoxIcon("smile", **kw)
# And without tailwind
kw = dict(width=40, stroke="red", fill="green")
PhIcon("airplane-in-flight", "fill", **kw)
Heroicon("chart-bar-square", "20/solid", **kw)
IonIcon("boat", "sharp", **kw)
LcIcon("message-square-heart", **kw)
FaIcon("apple", "brands", **kw)
BsIcon("apple", **kw)
BoxIcon("smile", **kw)
Dev
uv sync
uv run pytest
uv run examples/demo.py
rm -rf dist && uv build
uvx twine upload dist/*
Project details
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.