Skip to main content

SWL (Seecr Web Lib)

Tests PyPI

Interactive web applications in Python, without a JavaScript frontend.

SWL is a small layer on top of Starlette, Jinja and htmx 4. The server renders HTML; an action answers with a short list of instructions ("put this HTML there, reload that list, close the dialog, show a toast") that SWL carries out in the browser. You write Python and templates. There is no build step, and no second application to keep in sync.

It is made for the software around data: admin screens, editors, review tools, form builders and dashboards. These are lots of forms, lists, dialogs and tabs, used every day by people who need them to work.

A taste

{% from "swl/placeholder.j2" import placeholder %}

<form hx-post="{{ register('note_add') }}">
    <input name="text" class="{{ SWL.ui.input }}">
    <button type="submit" class="{{ SWL.ui.button_primary }}">Add</button>
</form>

{{ placeholder("notes", register('notes_list')) }}
async def notes_list(request, swl, db, **kwargs):
    html = swl.template("notes/list.j2").render(notes=db.notes())
    return swl.success().hydrate("notes", html)


async def note_add(request, swl, db, **kwargs):
    async with request.form() as form:
        text = form.get("text", "").strip()
    if not text:
        return swl.fail().message("A note needs some text")
    db.add_note(text)
    return swl.success().reset_form().rehydrate("notes").toast("Note added")


__actions__ = [notes_list, note_add]

note_add doesn't render the list. It asks the list to reload itself, so notes_list stays the only place that knows how the list looks. And because a response is data, you test an action without a browser.

What you get

  • Actions: async Python functions, registered by module, with login and authorisation checks. A template gets an action's url with register("name").
  • A response builder: hydrate, rehydrate, open_modal, close_modal, open_contextmenu, toast, call (a JavaScript function), set_url, redirect, trigger, and swl.fail().message(...) for errors.
  • Placeholders and rehydrate: parts of the page that load themselves and can be reloaded by name from any action.
  • Live updates: a placeholder can reload when the data it shows changes, also in other browser tabs and for other users (over a websocket). A change can go to everyone or to specific users only, so a private conversation or a private task stays private. The page catches up after a lost connection, and you can see who is online.
  • Translations: texts marked with _(), translated with gettext into the visitor's language (their choice, or the browser's), dates and numbers too. SWL's own screens come in English, Dutch, German, French and Spanish.
  • Screens you can reload and link to: actions keep the url up to date, and a page route renders the same screen from it.
  • Ready-made parts: a modal, confirm and error dialogs, toasts and context menus, all plain HTML (<dialog>, popover). There are also login, "my account" and user management screens.
  • Your choice of CSS framework: ui.framework is "bootstrap" (the default), "tabler", "bulma" or "swl", SWL's own small stylesheet with no framework at all. Light and dark colours work with each of them.

Install

pip install swl

Or from a checkout: pip install -e .. SWL needs Python 3.11 or newer. Its dependencies, including seecr-stdlib, come from PyPI.

Try the example

The example application is a small task list. It uses nearly everything: dialogs, search as you type, tabs, a context menu, live updates between browser tabs, private tasks that only their owner hears about, screens that survive a reload, and switches for the language (English, Dutch, German, Spanish), the CSS framework and dark mode.

pip install -e .
pip install -e example/
python -m swl_tasks

Open http://127.0.0.1:8000/ and log in as demo / demo-password.

Documentation

Tests

pytest swl example/swl_tasks

The JavaScript tests (QUnit) run in a browser: python -m swl.test.server, then open http://localhost:8000/. Or headless, as the CI does:

pip install playwright && python -m playwright install chromium
python -m swl.test.run_js_tests

License

SWL is released under the MIT License; see LICENSE.

Copyright © Seecr (Seek You Too B.V.), https://seecr.nl.

Metadata

Release files for swl 5.3.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for swl 5.3.0
File Size Uploaded Provenance Actions
swl-5.3.0.tar.gz 142.3 kB With provenance Details for swl-5.3.0.tar.gz

Built distribution (wheel)

Table of built distributions (wheels) for swl 5.3.0
File Interpreter ABI Platform Actions
swl-5.3.0-py3-none-any.whl Python 3 none any Details for swl-5.3.0-py3-none-any.whl

Total release size: 274.5 kB

Release files / swl-5.3.0.tar.gz

Download URL swl-5.3.0.tar.gz
Size 142.3 kB
Tags Source
SHA-256 checksum
How to use checksums
8f98f9150db04587e2a2ee4a4b6501eeed5b78115e73227d8f113cce74e5d474
BLAKE2b-256 checksum
How to use checksums
60a3de5dde61450830d7eb0d10620db4f349f2dfa27e1111380f2e2c2847ca30
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.16

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Nov 1, 2026.

Transparency log

Release files / swl-5.3.0-py3-none-any.whl

Download URL swl-5.3.0-py3-none-any.whl
Size 132.2 kB
Tags Python 3
SHA-256 checksum
How to use checksums
de5953581bd062fc5863dde015659abbc9d5afbb6ab299dfd9a4c2789d7016cb
BLAKE2b-256 checksum
How to use checksums
8d03d5bf2f86beac1696dd7634ee61df4fed41cc5a9d36fdecf072787b4a5369
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.16

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Nov 1, 2026.

Transparency log

Security for swl 5.3.0

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

Full provenance

All 2 files in this release have been uploaded with provenance metadata.

Select from 2 files

Attestation for swl-5.3.0.tar.gz

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Nov 1, 2026.

Transparency log

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

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