Skip to main content

Palestine

A Python library for building and rendering HTML using a DOM and component model.

Installation

pip install palestine

Requires Python 3.14+.

Quick start

from palestine import Document, Html, Body, Div, Text

doc = Document()
html = Html()
body = Body()
doc.append_child(html)
html.append_child(body)

page = Div(class_="container")
page.append_child(Text("Hello from Palestine"))
body.append_child(page)

print(doc)

Output:

<!DOCTYPE html>
<html><body><div class="container">Hello from Palestine</div></body></html>

What it looks like

Build a DOM tree

from palestine import Div, Text, Button

card = Div(class_="card")
card.append_child(Text("Title"))
card.append_child(Button(type="submit").append_child(Text("Click")))

# Move nodes between parents automatically
other = Div()
other.append_child(card)  # Detaches from previous parent

Render HTML

from palestine import Div, Text, RawText

# Text is escaped automatically
div = Div()
div.append_child(Text("<script>"))  # Renders as &lt;script&gt;

# RawText is for trusted markup
div.append_child(RawText("<svg>...</svg>"))  # Renders as-is

Compose components

from palestine import Div, H1, P, Text

def Card(title, content):
    card = Div(class_="card")
    card.append_child(H1().append_child(Text(title)))
    card.append_child(P().append_child(Text(content)))
    return card

page = Div()
page.append_child(Card("First", "Content here"))
page.append_child(Card("Second", "More content"))

Parse and manipulate HTML

from palestine import parse_html

doc = parse_html('<div class="box"><p>Hello</p></div>')
div = doc.query_selector(".box")
div.append_child(parse_html("<span>World</span>"))

Templates

from palestine import Template

tmpl = Template("<h1>{{ title }}</h1><p>{{ content }}</p>")
html = tmpl.render(title="My Page", content="Hello world")

Forms and validation

from palestine import FormBuilder, FormValidator, Required, Email

form = FormBuilder(action="/submit", method="post")
form.add_text("name", "Name", required=True)
form.add_email("email", "Email", required=True)
form.add_submit("Register")

validator = FormValidator({
    "name": [Required()],
    "email": [Required(), Email()],
})
errors = validator.validate({"name": "", "email": "invalid"})

Features

  • DOM primitives: Node, Element, Text, RawText, Comment, Document
  • HTML elements: All standard HTML5 elements
  • Rendering: HTML serialization, pretty printing, minification, streaming
  • Parsing: HTML to DOM conversion
  • Templates: Variable substitution and control flow
  • Components: Reusable UI composition
  • Forms: Form building and validation
  • Security: HTML sanitization, escaping, URL validation
  • VDOM: Virtual DOM with diff/patch

Architecture

Palestine is built around a mutable DOM tree:

Node
  ├── Element (tag, attributes, children)
  ├── Text (escaped content)
  ├── RawText (trusted markup)
  ├── Comment
  └── Document (root node)

Components are functions that compose elements. The renderer serializes the tree to HTML.

Status

Early-stage project. The core DOM, rendering, and template engine are functional and tested.

The parser is built on Python's html.parser and does not implement the full WHATWG HTML parsing algorithm. It handles common cases but may differ from browser parsing on malformed input.

The API may change between versions.

License

MIT

Download files

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

Source Distribution

palestine-0.2.2.tar.gz (34.0 kB view details)

Uploaded Source

Built Distribution

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

palestine-0.2.2-py3-none-any.whl (41.5 kB view details)

Uploaded Python 3

File details

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

File metadata

  • Download URL: palestine-0.2.2.tar.gz
  • Upload date:
  • Size: 34.0 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/7.0.0 CPython/3.14.2

File hashes

Hashes for palestine-0.2.2.tar.gz
Algorithm Hash digest
SHA256 6605bae095dc1b08897e59042224e268d3994e294b38538bbec3792995d164ff
MD5 a3f9d747c288fa1ece7ec879fdd51b57
BLAKE2b-256 0b69462f661ce2bcd37599bbe86c94ec0191105ddb3c8b9c63eef637a06467af

See more details on using hashes here.

File details

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

File metadata

  • Download URL: palestine-0.2.2-py3-none-any.whl
  • Upload date:
  • Size: 41.5 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/7.0.0 CPython/3.14.2

File hashes

Hashes for palestine-0.2.2-py3-none-any.whl
Algorithm Hash digest
SHA256 2a3797b772ece78a283fa990c19b08b409b15369e78842df06790c3b21d55ffa
MD5 a3b6d01c1c3fd77e5757f8d84a748bdf
BLAKE2b-256 4918ca6c0ad85343888cff58b35a8ad4daecd591c8563aab5d832d266cacad90

See more details on using hashes here.

Release history Release notifications | RSS feed

0.2.3

2 files

This release

0.2.2 This release

2 files

0.2.1

2 files

0.2.0

2 files

0.1.0

2 files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page