Skip to main content

Type-safe, composable UI components for Python — server-side rendered, HTMX-first.

Project description

PyPI version Python 3.11+ License: MIT + Commons Clause mypy strict CI Docs

htmforge

Type-safe, composable UI components for Python. Server-side rendered, HTMX-first, framework-agnostic.

Why htmforge?

  • Type-safe props via Pydantic v2: props are validated on construction and on assignment.
  • Small Element primitives with safe rendering: Element.to_html() escapes text and maps Python attrs to HTML (e.g. clsclass).
  • First-class HTMX support: typed enums and helpers for hx-* attrs.
  • Framework adapters: to_fastapi(), to_flask(), to_django() on components for easy integration.

Installation

pip install htmforge

Quickstart (Flask)

Copy-pasteable minimal Flask example using a Page and a DataTable.

from flask import Flask

from htmforge.components.page import Page
from htmforge.components import DataTable
from htmforge.core.element import Element
from htmforge.elements import div, h1

app = Flask(__name__)

class UsersPage(Page):
    users: list[list[str]]

    def _body_content(self) -> list[Element | str | None]:
        return [
            div(
                h1("Users"),
                DataTable(headers=["Name", "Email"], rows=self.users),
            )
        ]

@app.route("/users")
def users():
    rows = [["Ada Lovelace", "ada@example.com"]]
    return UsersPage(title="Users", users=rows).to_flask()

if __name__ == "__main__":
    app.run(debug=True)

Elements

htmforge.elements exposes small factory functions for HTML tags. These map Pythonic attribute names to HTML and escape text safely. Example:

from htmforge.elements import div, span, input

el = div(
    span("Name:"),
    input(type="search", name="q", hx_get="/search", cls="search"),
    cls="form-row",
)
print(el.to_html())

The hx_get argument renders as hx-get, and text is escaped by default to prevent XSS.

Components

Component Description Import
Alert Dismissible info/success/warning/error box from htmforge.components import Alert
Badge Small inline label with variant classes from htmforge.components import Badge
Breadcrumb Ordered nav with aria-current for current item from htmforge.components import Breadcrumb
DataTable Table with optional HTMX reloading from htmforge.components import DataTable
FormField Label + input + optional error block from htmforge.components import FormField
Modal Trigger button + <dialog> overlay (HTMX body) from htmforge.components import Modal
Page Abstract full-page component (adds DOCTYPE) from htmforge.components.page import Page
Pagination Page links + prev/next, supports HTMX targets from htmforge.components import Pagination
SearchInput Search input with keyup debounce via HTMX from htmforge.components import SearchInput

HTMX integration

Typed enums live in htmforge.htmx: HxSwap, HxTrigger, HxTarget, and HxPushUrl. They render the correct attribute values. Example:

from htmforge.elements import button
from htmforge.htmx import HxSwap, HxTarget

btn = button(
    "Delete",
    hx_delete="/items/1",
    hx_swap=HxSwap.OUTER_HTML,
    hx_target=HxTarget.CLOSEST_TR,
)

Use hx_keyup_delay(ms) to produce keyup delay:{ms}ms trigger strings for debounced search inputs.

Framework support

FastAPI example:

from fastapi import FastAPI
from fastapi.responses import HTMLResponse

app = FastAPI()

@app.get("/", response_class=HTMLResponse)
def index():
    return UsersPage(title="Home").to_html()

Flask example (adapter shown above uses to_flask()):

from flask import Flask

app = Flask(__name__)

@app.route("/")
def index():
    return UsersPage(title="Home").to_flask()

Django example:

def index(request):
    return UsersPage(title="Home").to_django()

License

This project is licensed under the MIT License with the Commons Clause condition. It is free for personal projects, open source projects, and small businesses (see LICENSE). Organizations with annual revenue or funding over USD 1,000,000 or more than 100 employees require a separate commercial license from the author.

Contributing

See CONTRIBUTING.md and the docs site at https://mondi04.github.io/htmforge/contributing/ for contribution guidelines.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

htmforge-0.2.2.tar.gz (2.7 MB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

htmforge-0.2.2-py3-none-any.whl (27.5 kB view details)

Uploaded Python 3

File details

Details for the file htmforge-0.2.2.tar.gz.

File metadata

  • Download URL: htmforge-0.2.2.tar.gz
  • Upload date:
  • Size: 2.7 MB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.11.0

File hashes

Hashes for htmforge-0.2.2.tar.gz
Algorithm Hash digest
SHA256 0d82f58e6d92c27c6e7303ee28a5a4bfeefcc9655ea9f31d0b3bdeb249fedf1b
MD5 7068582ba8078b4c9de544646e745b04
BLAKE2b-256 adaf79024e54e620b4491acd7e89d1f4d3d4969c839082978fd19eaf3d77b9d7

See more details on using hashes here.

File details

Details for the file htmforge-0.2.2-py3-none-any.whl.

File metadata

  • Download URL: htmforge-0.2.2-py3-none-any.whl
  • Upload date:
  • Size: 27.5 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.11.0

File hashes

Hashes for htmforge-0.2.2-py3-none-any.whl
Algorithm Hash digest
SHA256 edc87e969acd0e6eec556ba0874b3a9908f572e37869a156a0171dbdbe7eb6f3
MD5 0a02733e6e48562e923c232b0b644fdd
BLAKE2b-256 87088c602f705c9c583f960eab588720a53cb5de01abb39c733d7903b6f86043

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page