Skip to main content

A Python DSL for HTML + CSS

Project description

Ooklept logo

ooklept


                      [ OOKLEPT ]
                     ( Egg Thief )
                          |
         +----------------+----------------+
         |                                 |
     [ oo- ]                          [ -klept ]
 (Combining Form)                  (Combining Form)
         |                                 |
   Ancient Greek                     Ancient Greek
    ᾠόν (ōión)                       κλέπτης (kléptēs)
     "an egg"                           "a thief"

ooklept or 'egg thief' refers to python(🐍) the snake that steals bird's eggs(🪺/🥚).

Here python(The programming language) steals HTML+CSS and makes a DSL for them.

ooklept.Element

Element is the fundamental building block of Ooklept. Every HTML element—from a simple <div> to a complex nested page—is represented by an Element instance.

The API is designed around method chaining, context managers, and typed attributes, allowing HTML to be written in idiomatic Python.


Creating an Element

Create an element by providing its HTML tag name.

from ooklept import Element

div = Element("div")
print(div)

Output

<div></div>

Adding Attributes

Use .attr() to assign HTML attributes.

div = (
    Element("div")
    .attr(id="main", title="Hello")
)

print(div)

Output

<div id="main" title="Hello"></div>

Attributes may also be supplied using a dictionary.

Element("div").attr({
    "data-user": "alice",
    "aria-hidden": "true",
})

Dictionary values take precedence over keyword arguments when the same attribute is provided.


Boolean Attributes

Boolean HTML attributes are rendered only when their value is True.

Element("input").attr(disabled=True)

Output

<input disabled />
Element("input").attr(disabled=False)

Output

<input />

CSS Classes

Use .class_() to assign CSS classes.

Element("div").class_("container")

Output

<div class="container"></div>

Multiple classes may be provided.

Element("div").class_("container fluid", "shadow")

Output

<div class="container fluid shadow"></div>

Calling .class_() repeatedly does not duplicate existing classes. If an existing class is added again, it is moved to the end while preserving uniqueness.


Inline Styles

Use .style() to define inline CSS.

Element("div").style(color="red")

Output

<div style="color:red;"></div>

Multiple properties may be supplied.

Element("div").style(
    color="white",
    background_color="black",
    margin="10px",
)

Output

<div style="color:white; background-color:black; margin:10px;"></div>

Properties may also be provided as a dictionary.

Element("div").style({
    "border-radius": "8px",
    "padding": "1rem",
})

Dictionary values override duplicate keyword arguments.


Adding Text

Use .text() to insert escaped text into an element.

Element("p").text("Hello, world!")

Output

<p>Hello, world!</p>

Text is automatically HTML escaped.

Element("p").text("<b>Hello</b>")

Output

<p>&lt;b&gt;Hello&lt;/b&gt;</p>

Nesting Elements

Element implements Python's context manager protocol, making deeply nested HTML easy to write.

with Element("div") as page:
    Element("h1").text("Ooklept")
    Element("p").text("Hello!")

print(page)

Output

<div>
    <h1>Ooklept</h1>
    <p>Hello!</p>
</div>

Nested contexts work naturally.

with Element("div") as page:
    with Element("section"):
        Element("h2").text("Title")
        Element("p").text("Content")

Produces

<div>
    <section>
        <h2>Title</h2>
        <p>Content</p>
    </section>
</div>

Method Chaining

All modifier methods return the element itself, allowing concise fluent code.

card = (
    Element("div")
    .attr(id="profile")
    .class_("card")
    .style(
        padding="1rem",
        border="1px solid #ddd",
    )
    .text("Hello!")
)

Void Elements

Void elements (such as img, br, input, and hr) cannot contain children.

Element("img")

Output

<img />

Attempting to enter a void element as a context manager raises an exception.

with Element("img"):
    ...

Automatic Escaping

Ooklept automatically escapes HTML special characters inside:

  • text nodes
  • attribute values
  • class values
  • style attribute values

Example

Element("div").attr(title='"Hello"')

Produces

<div title="&quot;Hello&quot;"></div>

This prevents accidental HTML injection while keeping the API simple.


Typed Keyword Arguments

If your editor supports static typing, Ooklept provides autocomplete for standard HTML attributes and CSS properties through Python type hints.

For example,

Element("div").attr(
    hidden=True,
    draggable="true",
)

Element("div").style(
    background_color="red",
    font_size="18px",
)

Python identifiers are automatically converted into valid HTML/CSS names where necessary.

For example:

Python HTML/CSS
class_ class
http_equiv http-equiv
background_color background-color

Complete Example

from ooklept import Element

with Element("main").class_("container") as page:

    Element("h1").text("Welcome")

    with Element("section").class_("content"):

        (
            Element("button")
            .class_("btn", "btn-primary")
            .style(
                background_color="#2563eb",
                color="white",
                padding="0.75rem 1rem",
            )
            .text("Click me")
        )

print(page)

Produces

<main class="container">
    <h1>Welcome</h1>
    <section class="content">
        <button
            class="btn btn-primary"
            style="background-color:#2563eb; color:white; padding:0.75rem 1rem;"
        >
            Click me
        </button>
    </section>
</main>

Summary

Element provides a Pythonic interface for generating HTML with:

  • Fluent method chaining
  • Automatic HTML escaping
  • Typed HTML attributes and CSS properties
  • Context-manager-based nesting
  • Automatic child management
  • Support for boolean attributes
  • Unique CSS class handling
  • Proper handling of HTML void elements

Together, these features enable expressive, readable, and type-safe HTML generation entirely in Python.

Project details


Release history Release notifications | RSS feed

This version

1.0

Download files

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

Source Distribution

ooklept-1.0.tar.gz (147.8 kB view details)

Uploaded Source

Built Distribution

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

ooklept-1.0-py3-none-any.whl (148.5 kB view details)

Uploaded Python 3

File details

Details for the file ooklept-1.0.tar.gz.

File metadata

  • Download URL: ooklept-1.0.tar.gz
  • Upload date:
  • Size: 147.8 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.14.5

File hashes

Hashes for ooklept-1.0.tar.gz
Algorithm Hash digest
SHA256 6d8aff25f986de6fd3052b087f76210fceac123d961e9aa5bdf0773a516f0144
MD5 3a2d49ae38617bd4b3c5da0d60f5cdde
BLAKE2b-256 7ea433163394ea1fb696f47106f4cfe2f2cf2f5cf9e72d5550b0ee346e2a2ddd

See more details on using hashes here.

File details

Details for the file ooklept-1.0-py3-none-any.whl.

File metadata

  • Download URL: ooklept-1.0-py3-none-any.whl
  • Upload date:
  • Size: 148.5 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.14.5

File hashes

Hashes for ooklept-1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 26a677a10b180332affa8365b0f3e8719a1cca92ac246616036538070b20661a
MD5 5878f0bcfe1734b8bc1c08082f4dd76d
BLAKE2b-256 72ecf5dc376e721535dfe84c54aca4e9a5d4cc86c00a7e7dd3376e0cc9783a9c

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