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 Distributions

No source distribution files available for this release.See tutorial on generating distribution archives.

Built Distributions

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

hyperhtml-0.1.0-cp310-abi3-win_amd64.whl (436.2 kB view details)

Uploaded CPython 3.10+Windows x86-64

hyperhtml-0.1.0-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.0-cp310-abi3-manylinux_2_28_aarch64.whl (514.2 kB view details)

Uploaded CPython 3.10+manylinux: glibc 2.28+ ARM64

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

Uploaded CPython 3.10+macOS 11.0+ ARM64

hyperhtml-0.1.0-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.0-cp310-abi3-win_amd64.whl.

File metadata

  • Download URL: hyperhtml-0.1.0-cp310-abi3-win_amd64.whl
  • Upload date:
  • Size: 436.2 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.0-cp310-abi3-win_amd64.whl
Algorithm Hash digest
SHA256 246ffee1455608f1b19388521b2ec0792f9ffa067a05a21c1eee7add48c8a933
MD5 b09f29949ab68cbe2d6c0682521238c6
BLAKE2b-256 1a29ddd4bca593b036f97d34c5206386d8391da74ee517a24d183466f7a05685

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for hyperhtml-0.1.0-cp310-abi3-manylinux_2_28_x86_64.whl
Algorithm Hash digest
SHA256 0f9f616ab41974e6b93aa73680ff691ccdb6b1c19d70f828dab608a21fc6da2f
MD5 b81b6ac8d36b4c56cf48e135cd7c1ec7
BLAKE2b-256 7c3162d8b9ab169a78df10a2033d6a5e0159508ad2dc634b311f3fcf5ee1e810

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for hyperhtml-0.1.0-cp310-abi3-manylinux_2_28_aarch64.whl
Algorithm Hash digest
SHA256 35e97bcfbd7816eb296f2e813adc1857b15bc952739a97a5cbedecce4fca57e3
MD5 aef10a29d0a03ba62733e1d5ea1e823d
BLAKE2b-256 df7ca3bb4a5ea563549c70199d8f83597e01a78d9ee2cc0daf9a396fa5917912

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for hyperhtml-0.1.0-cp310-abi3-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 95be36c78c51cf0343938318cbe6d87b4d0c61ec3c7bd0d4c012fc94253020d8
MD5 125994b30f8f881788bbf0a4134222e5
BLAKE2b-256 750adc103e1cf147633b16e4bf67c976d05a38bc37f1d57226ad965f98dbc22a

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for hyperhtml-0.1.0-cp310-abi3-macosx_10_12_x86_64.whl
Algorithm Hash digest
SHA256 1b179122830fc15e2833fdd35617f062b4ab2ee3833b5b3054378ec27e9b35e1
MD5 0ae122dbac15f3be169330ab7336a956
BLAKE2b-256 63e75583d1784b0b415d5b7dfae8737878470759fe20d66acc8781077a6b0258

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