Skip to main content

Backend-neutral Hyper HTML templates for Python

Project description

Hyper

CI PyPI License: MIT

Write type-safe HTML in .hyper files and import it directly from Python. Hyper compiles templates in memory, with no CLI, build step, or generated .py files.

uv add hyperhtml

Requires Python 3.10 or newer.

Render a component

Create app/templates/Greeting.hyper:

name: str
---
<h1>Hello, {name}!</h1>

Import it in a FastAPI endpoint:

from fastapi import FastAPI
from fastapi.responses import HTMLResponse

from app.templates import Greeting

app = FastAPI()

@app.get("/", response_class=HTMLResponse)
def home():
    return Greeting(name="World")

The response is:

<h1>Hello, World!</h1>

Hyper compiles Greeting.hyper on first import and caches it for the life of the process.

Use Django

Return a component directly from a Django view:

from django.http import HttpResponse

from app.templates import Greeting


def home(request):
    return HttpResponse(Greeting(name="World"))

To call Hyper components from Django templates, install the extra:

uv add "hyperhtml[django]"

Add the app, context processor, and builtin to your existing Django settings:

INSTALLED_APPS = [
    # ...
    "hyperhtml.integrations.django",
]

TEMPLATES = [{
    # ...
    "OPTIONS": {
        "context_processors": [
            # ...
            "hyperhtml.integrations.django.context_processors.components",
        ],
        "builtins": [
            "hyperhtml.integrations.django.templatetags.hyper",
        ],
    },
}]

Components in Django template directories become available by name:

{% hyper Greeting name=user.first_name / %}

Use Jinja

Install the Jinja extra:

uv add "hyperhtml[jinja2]"

Add the extension to an environment with a filesystem loader:

from jinja2 import Environment, FileSystemLoader

from hyperhtml.integrations.jinja2 import HyperExtension


env = Environment(
    loader=FileSystemLoader("templates"),
    extensions=[HyperExtension],
)

.hyper files under templates/ become Jinja globals:

{{ Greeting(name="Ada") }}

Both Jinja and Django preserve Hyper output as safe HTML. Hyper still escapes values passed into components.

Compose components

Components compose like HTML elements:

# app/components/ProductCard.hyper
name: str
price: float
image: str
on_sale: bool = False
---
<div class={["card", {"sale": on_sale}]}>
    <img src={image} alt={name} />
    <h3>{name}</h3>
    if on_sale:
        <span class="badge">Sale</span>
    end
    <p class="price">${price:.2f}</p>
</div>
# app/pages/Store.hyper
from app.components import ProductCard
from app.models import Product

products: list[Product]
---
<main>
    for product in products:
        <{ProductCard}
            name={product.name}
            price={product.price}
            image={product.image}
            on_sale={product.on_sale}
        />
    end
</main>

Use control flow

The template body accepts Python control flow. Blocks end with end:

from app.enums import Status
from app.models import Product

status: Status
products: list[Product]
---
match status:
    case Status.LOADING:
        <div class="spinner"></div>
    case Status.ERROR:
        <p class="error">Something went wrong</p>
    case Status.OK:
        if not products:
            <p>No products found</p>
        else:
            for product in products:
                <p>{product.name}</p>
            end
        end
end

Stream a response

Every component exposes its generated function as .stream:

from fastapi.responses import StreamingResponse

from app.pages import Store


@app.get("/store")
def store():
    return StreamingResponse(
        Store.stream(products=products),
        media_type="text/html",
    )

IDE support

  • JetBrains: syntax highlighting, Python language injection, and compiler diagnostics
  • TextMate and VS Code: syntax highlighting

Contributing

See CONTRIBUTING.md.

License

MIT

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

hyperhtml-0.1.1.tar.gz (150.1 kB view details)

Uploaded Source

Built Distributions

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

hyperhtml-0.1.1-cp310-abi3-win_amd64.whl (436.1 kB view details)

Uploaded CPython 3.10+Windows x86-64

hyperhtml-0.1.1-cp310-abi3-manylinux_2_28_x86_64.whl (561.1 kB view details)

Uploaded CPython 3.10+manylinux: glibc 2.28+ x86-64

hyperhtml-0.1.1-cp310-abi3-manylinux_2_28_aarch64.whl (514.2 kB view details)

Uploaded CPython 3.10+manylinux: glibc 2.28+ ARM64

hyperhtml-0.1.1-cp310-abi3-macosx_11_0_arm64.whl (493.4 kB view details)

Uploaded CPython 3.10+macOS 11.0+ ARM64

hyperhtml-0.1.1-cp310-abi3-macosx_10_12_x86_64.whl (511.5 kB view details)

Uploaded CPython 3.10+macOS 10.12+ x86-64

File details

Details for the file hyperhtml-0.1.1.tar.gz.

File metadata

  • Download URL: hyperhtml-0.1.1.tar.gz
  • Upload date:
  • Size: 150.1 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.1.0 CPython/3.13.14

File hashes

Hashes for hyperhtml-0.1.1.tar.gz
Algorithm Hash digest
SHA256 3c6f9d1e2bb24fcb2186e91d30de0383cc18d57c84fe0850e016afe8e7660e02
MD5 7da42400f8c18d89b1cb36cade414c79
BLAKE2b-256 4e4240780e70368bc5459f95c223590d03894c6f2b63c3554fe80529d61c01f6

See more details on using hashes here.

File details

Details for the file hyperhtml-0.1.1-cp310-abi3-win_amd64.whl.

File metadata

  • Download URL: hyperhtml-0.1.1-cp310-abi3-win_amd64.whl
  • Upload date:
  • Size: 436.1 kB
  • Tags: CPython 3.10+, Windows x86-64
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.1.0 CPython/3.13.14

File hashes

Hashes for hyperhtml-0.1.1-cp310-abi3-win_amd64.whl
Algorithm Hash digest
SHA256 5679109c280caa807ea323025377690fb09f40a90cf784b7aba7a240ee7e4d56
MD5 8d804905cc21d31d4ddbbd2148437198
BLAKE2b-256 0084d1b74c90c03294a1980114936bc5e26502ba978023d366f5071a879ff08a

See more details on using hashes here.

File details

Details for the file hyperhtml-0.1.1-cp310-abi3-manylinux_2_28_x86_64.whl.

File metadata

File hashes

Hashes for hyperhtml-0.1.1-cp310-abi3-manylinux_2_28_x86_64.whl
Algorithm Hash digest
SHA256 0063896c6cf01378bfa3ebea568bd880ed806e15b84d563b0cb3044e6b770fa6
MD5 a1994f6a5ee12de6dccc06b9f078fbb4
BLAKE2b-256 bf9750e4dc9cdc08481618be656563c2ad36192bbf1a4fdb4d868b576dcad90b

See more details on using hashes here.

File details

Details for the file hyperhtml-0.1.1-cp310-abi3-manylinux_2_28_aarch64.whl.

File metadata

File hashes

Hashes for hyperhtml-0.1.1-cp310-abi3-manylinux_2_28_aarch64.whl
Algorithm Hash digest
SHA256 26f0e0a2aeeedc4529b48bfc4382dc3329e9d65d209f71417733dc1c2e2eed13
MD5 987d840b8404a5df08763d834af20ee0
BLAKE2b-256 4689e3f33eab4c26d651c1682ac21434833c0314a72c5868ab8d03be0043f6fa

See more details on using hashes here.

File details

Details for the file hyperhtml-0.1.1-cp310-abi3-macosx_11_0_arm64.whl.

File metadata

File hashes

Hashes for hyperhtml-0.1.1-cp310-abi3-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 1f8ef3f0a485c16def8a41ada56601065584a651758171b8f4dd37dc33ccb61e
MD5 27754d2dbf92658f1738edbfaffba5c6
BLAKE2b-256 1ae7c2074e42f4037b16bafdc8a6d1261ffa86c05e2c04377cdce2935d3b4f1f

See more details on using hashes here.

File details

Details for the file hyperhtml-0.1.1-cp310-abi3-macosx_10_12_x86_64.whl.

File metadata

File hashes

Hashes for hyperhtml-0.1.1-cp310-abi3-macosx_10_12_x86_64.whl
Algorithm Hash digest
SHA256 bd308ea8b410643f3734708e58a3a04d1d9b98f56e668a9fc58b089bdd9a2be9
MD5 481cc136c1b86ac694c0c3ca7f0d5be0
BLAKE2b-256 5776196398682bbb54d25af85ac4634e8316ab2e6f97590d2a6f075d413aa05e

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