Skip to main content

No project description provided

Project description

logo

Schorle (pronounced as ˈʃɔʁlə) is a server-driven UI kit for Python with async support.


Latest Python Release We use black for formatting codecov


Note: This project is in an early stage of development. It is not ready for production use.

Installation

pip install schorle

Usage

Take a look at the examples directory.

Concepts

We use the following approaches to handle various cases:

  • Rendering HTML elements is done using Python functions.
  • HTMX for server interop
  • Hyperscript for client-side scripting

Elements

In contrast to using templating engines, Schorle uses Python functions to create HTML elements. This approach allows for better type checking and code completion.

from schorle.element import div, button


def my_element():
    return div().append(
        button().text("Click me!")
    )

For more complex cases, you can use with-blocks:

from schorle.element import div, button


def my_element():
    with div() as container:
        container >> button().text("Click me!")
    return container

For multi-nesting cases, you can call tag-methods directly on the parent:

from schorle.element import div, button


def my_element():
    with div() as complex_container:
        with complex_container.div() as container:
            container.button().text("Click me!")

        with complex_container.div() as another_container:
            another_container >> button().text("No, click me!")

    return complex_container

Handlers

Handler is just a dataclass with information on how to handle a specific trigger, for instance:

from schorle.attrs import Handler, Swap, Classes, post
from schorle.element import button, form, Element, div
from schorle.icon import icon
from schorle.app import Schorle
from fastapi import Form
from typing import Annotated

app = Schorle()


def input_component():
    with form(
            Classes("flex flex-row justify-center items-center w-96 space-x-2"),
            handler=Handler(post("/add"), "#tasks", Swap.before_end),
            hsx="""
                on htmx:afterRequest
                    my.reset()
                    add .btn-disabled to #add-button
        """,
    ) as this:
        this >> button(
            Classes("btn btn-primary btn-square btn-disabled"),
            element_id="add-button",
        ).append(icon("plus"))

    return this


def task_view(task: str) -> Element:
    return div().text(f"Task: {task}")


@app.backend.post("/add")
def add_task(task: Annotated[str, Form()]):
    return task_view(task).to_response()

Client-side scripting

For client-side scripting,Hyperscript is used:

from schorle.element import button
from schorle.attrs import Classes


def counter():
    return button(
        Classes("btn btn-primary"),
        hsx="""
            init
                set my.count to 0
            on click
                set my.count to my.count + 1
                put `Clicked ${my.count} times!` into me
            """,
    ).text("Click me!")

We plan to introduce a Python-to-Hyperscript transpiler in the future.

Rendering the elements

To render a specific element as HTML Response, use the to_response function:

from schorle.element import div
from schorle.app import Schorle

app = Schorle()


@app.backend.get("/task/{task_id:int}")
def get_task(task_id: int):
    return div().text(f"Task {task_id}").to_response()

To render the whole document, do it like this:

from schorle.element import div
from schorle.app import Schorle

app = Schorle()


@app.backend.get("/")
def get_home():
    return app.doc.include(
        div().text("Hello, world!")
    ).to_response()

Running the application

Schorle application is a thin wrapper around FastAPI. To run the application, use uvicorn:

uvicorn examples.todo:app --reload

Under the hood, Schorle uses FastAPI, so you can use all the features provided by FastAPI. To access the FastAPI application instance, use the backend attribute:

from schorle.app import Schorle

app = Schorle()

app.backend.add_middleware(...)  # add FastAPI middleware

Dev reload

Schorle supports dev reload out of the box. To enable it, use the --reload flag:

uvicorn examples.todo:app --reload

On any change in the code, the server will restart automatically, and the client will re-fetch the page.

Tech stack

Roadmap

  • Add more elements
  • Add dev reload
  • Add support for icons
  • Add support for onload events
  • Python-to-Hyperscript transpiler
  • Add convenient attributes API
  • Add more examples
  • Add tests
  • Add CI/CD
  • Add documentation
  • Add support for Plotly-based charts
  • Add support for Vega-based charts
  • Refactor the imports

Project details


Download files

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

Source Distribution

schorle-0.0.21.tar.gz (137.1 kB view hashes)

Uploaded Source

Built Distribution

schorle-0.0.21-py3-none-any.whl (15.2 kB view hashes)

Uploaded Python 3

Supported by

AWS AWS Cloud computing and Security Sponsor Datadog Datadog Monitoring Fastly Fastly CDN Google Google Download Analytics Microsoft Microsoft PSF Sponsor Pingdom Pingdom Monitoring Sentry Sentry Error logging StatusPage StatusPage Status page