htpy - HTML in Python
htpy is a Python library designed for generating HTML in plain Python code, eliminating the need for separate templating languages. It aims to make writing HTML fun and efficient, leveraging Python's features like static typing and debugging. The current version is 25.12.0, and it follows a frequent release cadence, often monthly.
Common errors
-
ValueError: Invalid whitespace in class shorthand. Expected '.foo.bar', not '.foo bar'
cause Attempting to specify multiple CSS classes using spaces instead of dots in the shorthand syntax.fixReplace spaces with dots for multiple classes: `div(".class1.class2")` instead of `div(".class1 class2")`. -
RuntimeError: Generator was already consumed.
cause An `htpy` element with a generator as a child was rendered or iterated over more than once.fixIf the content needs to be processed multiple times, ensure the generator is converted to a list or tuple (e.g., `ul[tuple(li[item] for item in items)]`) or recreate the generator for each use. -
AttributeError: 'Element' object has no attribute 'render_node' OR TypeError: 'Element' object is not iterable
cause Using deprecated methods `render_node()` or `iter_node()`, or directly iterating over `htpy` elements in newer versions.fixUse `str(element)` to get the full HTML string, or `element.iter_chunks()` for iterable streaming output. -
NameError: name 'div' is not defined
cause An HTML element (like `div`, `p`, `html`) was used without being imported from the `htpy` module.fixAdd the missing element to your imports: `from htpy import div` (or `from htpy import html, body, div` for multiple elements).
Warnings
- breaking Specifying multiple CSS classes using whitespace in the shorthand syntax (e.g., `div(".foo bar")`) will now raise a `ValueError`.
- breaking Rendering a generator (e.g., a generator comprehension used as children) more than once will now raise an exception, as generators are single-use iterators.
- deprecated The methods `render_node()` and `iter_node()` are deprecated, along with direct iteration over `htpy` elements.
- gotcha Asynchronous rendering capabilities were added, impacting how `htpy` can be used with ASGI frameworks like Starlette and FastAPI.
Install
-
pip install htpy
Imports
- html, body, div, p, ul, li
from htpy import html, body, div, p, ul, li
- htpy
import htpy as h
- HtpyResponse
from htpy.starlette import HtpyResponse
- Context
from htpy import Context
- with_children
from htpy import with_children
- Renderable
from htpy import Renderable
Quickstart
from htpy import body, h1, head, html, li, title, ul
menu = ["egg+bacon", "bacon+spam", "eggs+spam"]
page = html[
head[title["Today's menu"]],
body[
h1["Menu"],
ul(".menu")[(li[item] for item in menu)],
],
]
print(page)