HTML via Python
Project description
sodom
sodom if you prefer HTML via Python.
sodom is a project that utilizes Python's context manager to generate HTML on serverside. It provides a native way to create HTML documents using plaint dependency-free Python.
No more need to use templating engines and limited language subsets (jinja
, mako
), strange syntax of nested arrays (lxml.builder.E
) or unsupported one (pyxl
). There is dominate
and you want to use it? sodom is faster.
Example
# sodom/example.py
...
import platform
from sodom import *
from sodom.attrs import Attrs
def __example__():
with html(lang='en') as doc:
with head():
with slot(name='HEADER'):
meta(charset='utf-8')
meta(
name='viewport',
content='width=device-width, initial-scale=1, shrink-to-fit=no',
)
slot(name='title')
link(
rel='stylesheet',
href='https://cdn.jsdelivr.net/npm/bulma@1.0.0/css/bulma.min.css',
)
with body():
with section() < Attrs(class_='section'):
with div(class_='container'):
title('Hello world!!1!')
with p(class_='subtitle'):
text('My first website with ')
with a(href='https://pypi.org/project/sodom/'):
strong('sodom')
text(' on your '); strong(f'{platform.node()}/{platform.system()}'); text('!')
doc.render_html_now()
Installation
python -m pip install git+https://codeberg.org/protasov/sodom
or
python -m pip install sodom
Concepts
Elements
sodom provide 3 types of elements:
-
NormanElement
- HTML element that may hasAttrs
and contain nested elements such as anotherNormanElement
,VoidElement
ortext
from sodom import * from sodom.renderers import render_now with div() as doc: br() text('foo') render_now(doc)
-
VoidElement
- HTML element that may has onlyAttrs
from sodom import * from sodom.renderers import render_now doc = input(type='number') render_now(doc)
-
text
- HTML element appends provided text into children list ofNormalElement
from sodom import * from sodom.renderers import render_now text('bar') # raise exception, `text` should be called in NormalElement context # ----- with div() as doc: text('baz') render_now(doc)
Attributes
sodom has special Attrs
class to represent HTML attributes. It inherit builtin dict[str, str]
and provide base tools to merging attributes. Merge means adding attribute values to end of existing ones or create new attribute.
# merge into new `Attrs` instance
Attrs(foo='bar').merge({'foo': 'baz'})
Attrs(foo='bar').merge(Attrs(foo='baz'))
Attrs(foo='bar').merge(dict(foo='baz'))
Attrs(foo='bar') | {'foo': 'baz'}
Attrs(foo='bar') | Attrs(foo='baz')
Attrs(foo='bar') | dict(foo='baz')
# merge into left `Attrs` instance
Attrs(foo='bar').merge_update({'foo': 'baz'})
Attrs(foo='bar').merge_update(Attrs(foo='baz'))
Attrs(foo='bar').merge_update(dict(foo='baz'))
Attrs(foo='bar') |= {'foo': 'baz'}
Attrs(foo='bar') |= Attrs(foo='baz')
Attrs(foo='bar') |= dict(foo='baz')
# result:
Attrs({'foo': 'bar baz'})
Render context
Render context is a list of settings to generate code from Elements.
sodom provide ABCRenderContext as abstract base class and HTMLRenderContext
as a context to generate HTML code.
from sodom import *
from sodom.contexts import *
doc = div(foo_bar='baz')
doc.render_now(ctx=ctx(underscore_replacer='_'))
Result:
<!--instead of default `<div foo-bar="baz"></div>` you'll receive:-->
<div foo_bar="baz"></div>
Renderings
You can render elements and attr after building via:
- (for elements:)
DOMElement.stream
- to stream result of rendering via render context fromctx=
VoidElement.stream
NormalElement.stream
DOMElement.stream_html
- to stream result of rendering via HTMLRenderContextVoidElement.stream_html
NormalElement.stream_html
DOMElement.render
- to render via render context fromctx=
VoidElement.render
NormalElement.render
DOMElement.render_html
- to render HTML via HTMLRenderContextVoidElement.render_html
NormalElement.render_html
DOMElement.render_now
- to render HTML into your default browser (/default profile)VoidElement.render_now
NormalElement.render_now
- (for attributes:)
Attrs.stream
- to stream result of rendering via render context fromctx=
Attrs.render
(VoidElement.render
,NormalElement.render
) - to render via render context fromctx=
Streaming
sodom also support streaming rendered elements - every element of element tree can be rendered and yielded separately via DOMElement.stream
. It can be useful if your http server support something like:
Schemes of streaming:
NormalElement
:- tag head
- yield from element's children
- tag end
VoidElement
andtext
- whole element
More features
Performance:
sodom is faster than dominate
. Check sodom.tests.test_performance_dominate
or use pytest -vv -s -k test_performance sodom/tests.py
Processing/Threading/Asyncing:
Actively using ContextVar
. Tested with asyncio
and ThreadPoolExecutor
. Check sodom.tests.TestContext
Feedback
If you have any feedback, text me inbox@protaz.ru
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
File details
Details for the file sodom-2a9.tar.gz
.
File metadata
- Download URL: sodom-2a9.tar.gz
- Upload date:
- Size: 39.0 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/5.1.1 CPython/3.12.3
File hashes
Algorithm | Hash digest | |
---|---|---|
SHA256 | 93e384808b9bbbe590885fd04672257a3a7619c5bafa62c531e1a3232c1c2d13 |
|
MD5 | ecff98ed3ac5094087a540e6723a26d7 |
|
BLAKE2b-256 | 651c9c0a6dd99bbfeba6eadc1be5ee70a62f23352f1354995c943738e2a17ac9 |