Skip to main content

Build HTML documents programmatically using Python objects.

Project description

luk

Create static HTML inside Python. No templates, just Python. Create objects directly or use the context manager to use control flow like if/else, add objects in loops, etcetera.

Installation

pip install luk

Quick Start

import luk

page = luk.Html(
    luk.Head(luk.Title("My Page")),
    luk.Body(
        luk.H1("Welcome"),
        luk.Div(
            luk.P("Hello, ", luk.A("world", href="https://example.com"), "!"),
            class_="container",
        ),
    ),
)

print(page.serialize())

Output:

<!DOCTYPE html><html><head><title>My Page</title></head><body><h1>Welcome</h1><div class="container"><p>Hello, <a href="https://example.com">world</a>!</p></div></body></html>

Features

Nested Elements

Pass child elements as positional arguments:

import luk

menu = luk.Ul(
    luk.Li("Home"),
    luk.Li("About"),
    luk.Li("Contact"),
)

Attributes

Pass attributes as keyword arguments:

import luk

# Use trailing underscore for reserved words (class, for, etc.)
luk.Div(class_="container", id="main")

# Underscores in names become hyphens
luk.Div(data_user_id="123")  # renders as data-user-id="123"

# Boolean attributes
luk.Input(type="checkbox", checked=True)   # renders: <input type="checkbox" checked />
luk.Input(type="checkbox", checked=False)  # renders: <input type="checkbox" />

Context Manager

Build nested structures using with statements. Elements created inside a with block are automatically appended as children:

import luk

with luk.Html() as page:
    with luk.Head():
        luk.Title("My Page")
    with luk.Body():
        with luk.Div(class_="header"):
            luk.H1("Welcome")
        with luk.Div(class_="content"):
            luk.P("Here are some items:")
            with luk.Ul():
                for e in ["First", "Second", "Third"]:
                luk.Li(f"{e} item")

print(page.serialize())

This produces the same output as the nested constructor style, but can be more readable for complex structures.

Self-Closing Elements

Void elements like <br>, <img>, <input>, and <meta> are self-closing and cannot have children:

import luk

luk.Img(src="photo.jpg", alt="A photo")  # <img src="photo.jpg" alt="A photo" />
luk.Br()                                  # <br />
luk.Input(type="text", name="email")      # <input type="text" name="email" />
luk.Meta(charset="utf-8")                 # <meta charset="utf-8" />

Script and Style Elements

Content inside <script> and <style> tags is not escaped:

import luk

luk.Script("console.log('Hello, world!');")
# <script>console.log('Hello, world!');</script>

luk.Style("body { margin: 0; }")
# <style>body { margin: 0; }</style>

Trusted Content

Use Trusted to insert pre-built HTML without escaping:

import luk

# Useful for embedding HTML from trusted sources (e.g., markdown renderers)
luk.Div(luk.Trusted("<strong>Already formatted</strong> content"))

Warning: Only use Trusted with content you control. Never use it with user input.

HTML Escaping

Text content and attribute values are automatically escaped to prevent XSS:

import luk

luk.Span("<script>alert('xss')</script>")
# <span>&lt;script&gt;alert('xss')&lt;/script&gt;</span>

luk.Div(title='He said "hello"')
# <div title="He said &quot;hello&quot;"></div>

Writing to Files

Save the rendered HTML directly to a file:

import luk

page = luk.Html(
    luk.Head(luk.Title("My Page")),
    luk.Body(luk.H1("Hello!")),
)

page.write("index.html")

Serialization Options

page.serialize()                    # Includes <!DOCTYPE html> prefix
page.serialize(prepend_doctype=False)  # Without doctype

Available Elements

Document

Html, Head, Body, Title, Meta, Link, Script, Style

Sections

Div, Section, Article, Nav, Header, Footer, Main, Aside

Headings

H1, H2, H3, H4, H5, H6

Text

P, Span, A, Strong, Em, B, I, Br, Hr, Pre, Code, Blockquote

Lists

Ul, Ol, Li

Tables

Table, Thead, Tbody, Tr, Th, Td

Forms

Form, Input, Button, Label, Select, Option, Textarea

Media

Img, Video, Audio, Source

Interactive

Details, Summary

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

luk-0.1.0.tar.gz (15.0 kB view details)

Uploaded Source

Built Distribution

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

luk-0.1.0-py3-none-any.whl (7.0 kB view details)

Uploaded Python 3

File details

Details for the file luk-0.1.0.tar.gz.

File metadata

  • Download URL: luk-0.1.0.tar.gz
  • Upload date:
  • Size: 15.0 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for luk-0.1.0.tar.gz
Algorithm Hash digest
SHA256 d85121bb068a9c330f0546d60badb0200b8c91904ca1823bfe9e99dc9414bda4
MD5 d416aed23c3c9b122b5f576426144ca6
BLAKE2b-256 3b90a3b2e1430188f4e7c875fe18d2cb6ab1865158cb0760c7b3e98ad879fb46

See more details on using hashes here.

Provenance

The following attestation bundles were made for luk-0.1.0.tar.gz:

Publisher: release.yml on sebasv/luk

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file luk-0.1.0-py3-none-any.whl.

File metadata

  • Download URL: luk-0.1.0-py3-none-any.whl
  • Upload date:
  • Size: 7.0 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for luk-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 0ac106e89a5db81c98f174680c160a5b5426110b23c5412207e7413ebf8e8567
MD5 3b98d9c89e7aaf221da4ec4d1234ab50
BLAKE2b-256 56cbc491babf515917ec4eb69a96e8ad8ecdfaec4aa6c8d19b44dbe0b8feba10

See more details on using hashes here.

Provenance

The following attestation bundles were made for luk-0.1.0-py3-none-any.whl:

Publisher: release.yml on sebasv/luk

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

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