Write responsive web apps in full python
—
Comprehensive HTML element system with 60+ node classes covering all HTML5 elements, plus utilities for HTML parsing and document building. All HTML elements support event handling, real-time DOM updates, and automatic synchronization between Python objects and the browser DOM.
Core function for creating HTML documents and parsing existing HTML content into Python objects.
def HTML(*args, **kwargs) -> 'Node':
"""
Create an HTML document or container with child elements.
Args:
*args: Child nodes or text content
**kwargs: HTML attributes
Returns:
Node: HTML container node
"""
def parse_html(html_string: str) -> 'Node':
"""
Parse HTML string into Lona node objects.
Args:
html_string (str): HTML content to parse
Returns:
Node: Parsed HTML as node objects
"""from lona.html import HTML, H1, P, Div
# Create HTML structure
html = HTML(
H1('Welcome to Lona'),
P('This is a paragraph with ', Strong('bold text'), '.'),
Div(
P('Nested content'),
id='main-content',
class_='container'
)
)
# Parse existing HTML
from lona.html import parse_html
parsed = parse_html('<div><h1>Hello</h1><p>World</p></div>')Foundation class for all HTML elements providing common functionality for content manipulation, attribute handling, and DOM synchronization.
class Node:
def __init__(self, *args, **kwargs):
"""
Initialize an HTML node.
Args:
*args: Child nodes or text content
**kwargs: HTML attributes
"""
def set_text(self, text: str):
"""
Set the text content of the node.
Args:
text (str): New text content
"""
def get_text(self) -> str:
"""
Get the text content of the node.
Returns:
str: Current text content
"""
def append(self, *nodes):
"""
Append child nodes.
Args:
*nodes: Nodes to append
"""
def prepend(self, *nodes):
"""
Prepend child nodes.
Args:
*nodes: Nodes to prepend
"""
def insert(self, index: int, *nodes):
"""
Insert nodes at specific index.
Args:
index (int): Position to insert at
*nodes: Nodes to insert
"""
def remove(self, *nodes):
"""
Remove child nodes.
Args:
*nodes: Nodes to remove
"""
def clear(self):
"""
Remove all child nodes.
"""
def get_attribute(self, name: str):
"""
Get an HTML attribute value.
Args:
name (str): Attribute name
Returns:
Attribute value or None
"""
def set_attribute(self, name: str, value):
"""
Set an HTML attribute.
Args:
name (str): Attribute name
value: Attribute value
"""
def remove_attribute(self, name: str):
"""
Remove an HTML attribute.
Args:
name (str): Attribute name to remove
"""
def has_attribute(self, name: str) -> bool:
"""
Check if node has an attribute.
Args:
name (str): Attribute name
Returns:
bool: True if attribute exists
"""
def add_class(self, class_name: str):
"""
Add a CSS class.
Args:
class_name (str): Class name to add
"""
def remove_class(self, class_name: str):
"""
Remove a CSS class.
Args:
class_name (str): Class name to remove
"""
def has_class(self, class_name: str) -> bool:
"""
Check if node has a CSS class.
Args:
class_name (str): Class name to check
Returns:
bool: True if class exists
"""
def toggle_class(self, class_name: str):
"""
Toggle a CSS class.
Args:
class_name (str): Class name to toggle
"""
# Properties
tag_name: str # HTML tag name
attributes: dict # HTML attributes
nodes: list # Child nodes
parent: 'Node' # Parent node
id_: str # Element ID (use underscore to avoid Python keyword)
class_: str # CSS classes (use underscore to avoid Python keyword)HTML5 document structure elements for organizing page layout and semantics.
class Html(Node):
"""HTML root element."""
class Head(Node):
"""Document head element."""
class Body(Node):
"""Document body element."""
class Title(Node):
"""Document title element."""
class Meta(Node):
"""Meta information element."""
class Link(Node):
"""External resource link element."""
class Base(Node):
"""Document base URL element."""
class Style(Node):
"""CSS style element."""Elements for organizing and structuring page content into logical sections.
class H1(Node):
"""Level 1 heading."""
class H2(Node):
"""Level 2 heading."""
class H3(Node):
"""Level 3 heading."""
class H4(Node):
"""Level 4 heading."""
class H5(Node):
"""Level 5 heading."""
class H6(Node):
"""Level 6 heading."""
class Header(Node):
"""Page or section header."""
class Footer(Node):
"""Page or section footer."""
class Nav(Node):
"""Navigation section."""
class Main(Node):
"""Main content area."""
class Section(Node):
"""Generic section."""
class Article(Node):
"""Self-contained content."""
class Aside(Node):
"""Sidebar content."""
class Address(Node):
"""Contact information."""
class HGroup(Node):
"""Heading group."""Elements for organizing and displaying text content, lists, and paragraphs.
class P(Node):
"""Paragraph element."""
class Div(Node):
"""Generic container."""
class Span(Node):
"""Generic inline container."""
class Ul(Node):
"""Unordered list."""
class Ol(Node):
"""Ordered list."""
class Li(Node):
"""List item."""
class Dl(Node):
"""Description list."""
class Dt(Node):
"""Description term."""
class Dd(Node):
"""Description definition."""
class BlockQuote(Node):
"""Block quotation."""
class Figure(Node):
"""Figure with caption."""
class FigCaption(Node):
"""Figure caption."""
class Hr(Node):
"""Horizontal rule."""
class Pre(Node):
"""Preformatted text."""
class Menu(Node):
"""Menu list."""Elements for adding semantic meaning and formatting to inline text content.
class A(Node):
"""Anchor/link element."""
class Strong(Node):
"""Strong importance."""
class Em(Node):
"""Emphasized text."""
class B(Node):
"""Bold text."""
class I(Node):
"""Italic text."""
class U(Node):
"""Underlined text."""
class S(Node):
"""Strikethrough text."""
class Mark(Node):
"""Highlighted text."""
class Small(Node):
"""Small text."""
class Sub(Node):
"""Subscript."""
class Sup(Node):
"""Superscript."""
class Code(Node):
"""Inline code."""
class Kbd(Node):
"""Keyboard input."""
class Samp(Node):
"""Sample output."""
class Var(Node):
"""Variable."""
class Time(Node):
"""Date/time."""
class Abbr(Node):
"""Abbreviation."""
class Dfn(Node):
"""Definition."""
class Q(Node):
"""Inline quotation."""
class Cite(Node):
"""Citation."""
class Ruby(Node):
"""Ruby annotation."""
class Rt(Node):
"""Ruby text."""
class Rp(Node):
"""Ruby parentheses."""
class Bdi(Node):
"""Bidirectional isolation."""
class Bdo(Node):
"""Bidirectional override."""
class Wbr(Node):
"""Line break opportunity."""
class Br(Node):
"""Line break."""Interactive form elements for user input and data collection with built-in event handling.
class Form(Node):
"""HTML form."""
class Input(Node):
"""Generic input element."""
class TextInput(Node):
"""Text input field."""
class NumberInput(Node):
"""Number input field."""
class TextArea(Node):
"""Multi-line text input."""
class Button(Node):
"""Button element."""
class Select(Node):
"""Dropdown selection."""
class Option(Node):
"""Select option."""
class CheckBox(Node):
"""Checkbox input."""
class RadioButton(Node):
"""Radio button input."""
class RadioGroup(Node):
"""Radio button group."""
class Label(Node):
"""Form label."""
class Fieldset(Node):
"""Form field grouping."""
class Legend(Node):
"""Fieldset caption."""
class Progress(Node):
"""Progress indicator."""
class Meter(Node):
"""Measurement gauge."""
class Output(Node):
"""Calculation result."""
class Datalist(Node):
"""Input suggestions."""from lona.html import HTML, Form, TextInput, Button, Label, CheckBox
from lona.events import CHANGE
@app.route('/form')
class FormView(View):
def handle_request(self, request):
name_input = TextInput(placeholder='Enter your name')
email_input = TextInput(type='email', placeholder='Enter your email')
subscribe_checkbox = CheckBox()
submit_button = Button('Submit', type='submit')
form = Form(
Label('Name:', name_input),
Label('Email:', email_input),
Label(subscribe_checkbox, ' Subscribe to newsletter'),
submit_button
)
self.show(HTML(form))
# Wait for form submission
self.await_click(submit_button)
# Get form values
name = name_input.value
email = email_input.value
subscribed = subscribe_checkbox.checked
# Process form data...Elements for creating structured tabular data displays.
class Table(Node):
"""HTML table."""
class THead(Node):
"""Table header group."""
class TBody(Node):
"""Table body group."""
class TFoot(Node):
"""Table footer group."""
class Tr(Node):
"""Table row."""
class Th(Node):
"""Table header cell."""
class Td(Node):
"""Table data cell."""
class Col(Node):
"""Table column."""
class ColGroup(Node):
"""Table column group."""
class Caption(Node):
"""Table caption."""from lona.html import HTML, Table, THead, TBody, Tr, Th, Td
@app.route('/table')
class TableView(View):
def handle_request(self, request):
table = Table(
THead(
Tr(Th('Name'), Th('Age'), Th('City'))
),
TBody(
Tr(Td('John'), Td('30'), Td('New York')),
Tr(Td('Jane'), Td('25'), Td('London')),
Tr(Td('Bob'), Td('35'), Td('Paris'))
)
)
return HTML(table)Elements for embedding images, audio, video, and other media content.
class Img(Node):
"""Image element."""
class Audio(Node):
"""Audio player."""
class Video(Node):
"""Video player."""
class Track(Node):
"""Media track."""
class Source(Node):
"""Media source."""
class Canvas(Node):
"""Drawing canvas."""from lona.html import HTML, Img, Video, Source
@app.route('/media')
class MediaView(View):
def handle_request(self, request):
image = Img(src='/static/photo.jpg', alt='A beautiful photo')
video = Video(
Source(src='/static/video.mp4', type='video/mp4'),
Source(src='/static/video.webm', type='video/webm'),
controls=True,
width=640,
height=480
)
return HTML(image, video)Specialized interactive elements for enhanced user interfaces.
class Details(Node):
"""Collapsible details."""
class Summary(Node):
"""Details summary."""
class Dialog(Node):
"""Modal dialog."""Base class for creating custom reusable components that combine multiple HTML elements.
class Widget(Node):
"""
Base class for custom widgets/components.
Widgets are reusable components that can encapsulate
complex HTML structures and behavior.
"""
def __init__(self, *args, **kwargs):
"""
Initialize a custom widget.
Args:
*args: Widget arguments
**kwargs: Widget keyword arguments
"""
def setup(self):
"""
Setup method called after widget initialization.
Override this to build widget content.
"""
def render(self) -> 'Node':
"""
Render the widget content.
Returns:
Node: Widget HTML content
"""from lona.html import Widget, Div, H3, P, Button
class Alert(Widget):
def __init__(self, message, alert_type='info'):
self.message = message
self.alert_type = alert_type
super().__init__()
def setup(self):
close_button = Button('×', class_='close-btn')
self.nodes = [
Div(
close_button,
H3('Alert'),
P(self.message),
class_=f'alert alert-{self.alert_type}'
)
]
# Usage in view
@app.route('/alerts')
class AlertView(View):
def handle_request(self, request):
success_alert = Alert('Operation completed successfully!', 'success')
warning_alert = Alert('Please check your input.', 'warning')
return HTML(success_alert, warning_alert)Advanced HTML parsing and manipulation utilities for working with external HTML content.
class NodeHTMLParser:
"""
HTML parser class for converting HTML strings to Lona nodes.
"""
def __init__(self):
"""Initialize the HTML parser."""
def feed(self, html_string: str):
"""
Parse HTML string and return node objects.
Args:
html_string (str): HTML content to parse
Returns:
List of Node objects
"""
def close(self):
"""Close the parser and return final results."""Constants and utility collections used throughout the HTML system.
# Node class mappings
NODE_CLASSES: dict # Maps HTML tag names to node classes
# Input element mappings
INPUT_NODE_CLASSES: dict # Maps input types to input node classes
# Self-closing HTML tags
SELF_CLOSING_TAGS: list # List of self-closing HTML tag names
# Utility constants
VOID_ELEMENTS: set # HTML void elements that cannot have content
BOOLEAN_ATTRIBUTES: set # HTML boolean attributesfrom typing import Union, Optional, Dict, List, Any
# Node content types
NodeContent = Union[str, int, float, 'Node']
HTMLContent = Union[NodeContent, List[NodeContent]]
AttributeValue = Union[str, int, float, bool, None]
AttributeDict = Dict[str, AttributeValue]
# HTML parsing types
HTMLString = str
ParsedNodes = List['Node']
# Widget types
WidgetArgs = tuple
WidgetKwargs = Dict[str, Any]Install with Tessl CLI
npx tessl i tessl/pypi-lona