Skip to main content

Helper functions and classes for the Datastar library (https://data-star.dev/)

Project description

Datastar Python SDK

The datastar-py package provides a Python SDK for working with Datastar.

Datastar sends responses back to the browser using SSE. This allows the backend to send any number of events, from zero to infinity in response to a single request.

datastar-py has helpers for creating those responses, formatting the events, reading signals from the frontend, and generating the data-* HTML attributes.

The event generator can be used with any framework. There are also custom helpers included for the following frameworks:

Framework-specific helpers are kept in their own packages. e.g. datastar_py.quart Make sure to use the helpers from the package of the framework you are using.

Here is a full example using the quart framework showing many of the features available in this package.

import asyncio
from datetime import datetime

from datastar_py import ServerSentEventGenerator as SSE, attribute_generator as data
from datastar_py.quart import datastar_response, read_signals
from quart import Quart

app = Quart(__name__)

# Import frontend library via Content Distribution Network, create targets for Server Sent Events
@app.route("/")
def index():
    return f"""
        <html>
            <head>
                <script type="module" src="https://cdn.jsdelivr.net/gh/starfederation/datastar@v1.0.0-RC.7/bundles/datastar.js"></script>
            </head>
            <body {data.init("@get('/updates')")}>
                <span id="currentTime"></span><br>
                <span data-text="$currentTime"></span>
            </body>
        </html>
    """


@app.route("/updates")
@datastar_response
async def updates():
    # Retrieve a dictionary with the current state of the signals from the frontend
    signals = await read_signals()
    # Alternate updating an element from the backend, and updating a signal from the backend
    while True:
        yield SSE.patch_elements(
            f"""<span id="currentTime">{datetime.now().isoformat()}"""
        )
        await asyncio.sleep(1)
        yield SSE.patch_signals({"currentTime": f"{datetime.now().isoformat()}"})
        await asyncio.sleep(1)


app.run()

Starting examples for each framework can be found in the examples directory.

Event Generation Helpers

This helper is used to generate the actual events that are sent over SSE. They are just text blobs that can be sent using any framework. These can even be used by frameworks not directly supported in this library if you set up the headers of the SSE response yourself.

Response Helpers

A datastar response consists of 0..N datastar events. There are response classes included to make this easy in all of the supported frameworks. Each framework also exposes a @datastar_response decorator that will wrap return values (including generators) into the right response class while preserving sync handlers as sync so frameworks can keep them in their threadpools.

The following examples will work across all supported frameworks when the response class is imported from the appropriate framework package. e.g. from datastar_py.quart import DatastarResponse The containing functions are not shown here, as they will differ per framework.

# per framework Response import. (Replace 'fastapi' with your framework.) e.g.:
# from datastar_py.fastapi import DatastarResponse
from datastar_py import ServerSentEventGenerator as SSE

# 0 events, a 204
@app.get("zero")
def zero_event():
    return DatastarResponse()
# 1 event
@app.get("one")
def one_event():
    return DatastarResponse(SSE.patch_elements("<div id='mydiv'></div>"))
# 2 events
@app.get("two")
def two_event():
    return DatastarResponse([
        SSE.patch_elements("<div id='mydiv'></div>"),
        SSE.patch_signals({"mysignal": "myval"}),
    ])

# N events, a long lived stream (for all frameworks but sanic)
@app.get("/updates")
async def updates():
    async def _():
        while True:
            yield SSE.patch_elements("<div id='mydiv'></div>")
            await asyncio.sleep(1)
    return DatastarResponse(_())

# A long lived stream for sanic
@app.get("/updates")
async def updates(request):
    response = await datastar_respond(request)
    # which is just a helper for the following
    # response = await request.respond(DatastarResponse())
    while True:
        await response.send(SSE.patch_elements("<div id='mydiv'></div>"))
        await asyncio.sleep(1)

Response Decorator

To make returning a DatastarResponse simpler, there is a decorator datastar_response available that automatically wraps a function result in DatastarResponse. It works on async and regular functions and generator functions. The main use case is when using a generator function, as you can avoid a second generator function inside your response function. The decorator works the same for any of the supported frameworks, and should be used under any routing decorator from the framework.

# Import the decorator from the package specific to your framework
from datastar_py.sanic import datastar_response, ServerSentEventGenerator as SSE

@app.get('/my_route')
@datastar_response
async def my_route(request):
    while True:
        yield SSE.patch_elements("<div id='mydiv'></div>")
        await asyncio.sleep(1)

Signal Helpers

The current state of the datastar signals is included by default in every datastar request. A helper is included to load those signals for each framework. read_signals. The usage varies per framework so check the signature for your framework. You usually need to pass the request in.

from datastar_py.quart import read_signals

@app.route("/updates")
async def updates():
    signals = await read_signals()

Attribute Generation Helper

Datastar allows HTML generation to be done on the backend. datastar-py includes a helper to generate data-* attributes in your HTML with IDE completion and type checking. It can be used with many different HTML generation libraries.

from datastar_py import attribute_generator as data

# htpy
button(data.on("click", "console.log('clicked')").debounce(1000).stop)["My Button"]
# FastHTML
Button("My Button", data.on("click", "console.log('clicked')").debounce(1000).stop)
Button(data.on("click", "console.log('clicked')").debounce(1000).stop)("My Button")
# f-strings
f"<button {data.on("click", "console.log('clicked')").debounce(1000).stop}>My Button</button>"
# Jinja, but no editor completion :(
<button {{data.on("click", "console.log('clicked')").debounce(1000).stop}}>My Button</button>

When using datastar with a different alias, you can instantiate the class yourself.

from datastar_py.attributes import AttributeGenerator

data = AttributeGenerator(alias="data-star-")

# htmy (htmy will transform _ into - unless the attribute starts with _, which will be stripped)
data = AttributeGenerator(alias="_data-")
html.button("My Button", **data.on("click", "console.log('clicked')").debounce("1s").stop)

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

datastar_py-1.0.2.tar.gz (129.5 kB view details)

Uploaded Source

Built Distribution

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

datastar_py-1.0.2-py3-none-any.whl (19.7 kB view details)

Uploaded Python 3

File details

Details for the file datastar_py-1.0.2.tar.gz.

File metadata

  • Download URL: datastar_py-1.0.2.tar.gz
  • Upload date:
  • Size: 129.5 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.11.17 {"installer":{"name":"uv","version":"0.11.17","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"CachyOS Linux","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}

File hashes

Hashes for datastar_py-1.0.2.tar.gz
Algorithm Hash digest
SHA256 c6f86e2b48c3a5ea08570a4e958267307a5ffc0253c259f054dc3bb6de8a2c0e
MD5 0b249e32e91c37c7f8a5b2204a8b6da7
BLAKE2b-256 d956697b0c2300985f5143384696fd4854cfdcadf6839577fde49d5b9e0d9000

See more details on using hashes here.

File details

Details for the file datastar_py-1.0.2-py3-none-any.whl.

File metadata

  • Download URL: datastar_py-1.0.2-py3-none-any.whl
  • Upload date:
  • Size: 19.7 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.11.17 {"installer":{"name":"uv","version":"0.11.17","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"CachyOS Linux","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}

File hashes

Hashes for datastar_py-1.0.2-py3-none-any.whl
Algorithm Hash digest
SHA256 d84735e5cc55ed85e02f80bbab01c2877e7ed7a6185cc144f802a9821616c9d3
MD5 ca351d65ff5c67be6c4e94ff83c9141b
BLAKE2b-256 0f142cffb0ef9a69d113349f483786c435abf06ea5091e275328cc163b2a2f23

See more details on using hashes here.

Supported by

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