Skip to main content

Storybook-like development tools for starlette-html components

Project description

starlette-html-stories

starlette-html-stories provides development tools for documenting, previewing, and testing starlette-html components in Starlette apps.

It gives you a simple way to:

  • collect component examples in one place
  • document design-system usage next to the component examples
  • render stories as isolated Starlette pages during development
  • pass example data as regular Python arguments
  • add story-local routes for HTMX interactions

The goal is to make your app UI easier to discover, reuse, and keep consistent as it grows.

You might also like my other Starlette packages that I use and maintain:

Package Description
starlette-html Python-first HTML DSL
starlette-hot-reload Hot reload for static files
starlette-tailwindcss Tailwind CSS integration

Installation

uv add starlette-html-stories
# or
pip install starlette-html-stories

Usage

Step 1: Compose html_stories in lifespan

html_stories only activates when app.debug is True.

from contextlib import asynccontextmanager

from starlette.applications import Starlette
from starlette_html_stories import html_stories

@asynccontextmanager
async def lifespan(app: Starlette):
    async with html_stories(
        app=app,
        directory="src/app/ui/stories",
    ):
        yield


app = Starlette(debug=True, routes=[...], lifespan=lifespan)

Then open /__stories__/ in your browser.

Step 2: Write a component story

Stories are plain Python functions.

from app.ui.components import UserCard
from starlette_html_stories import stories, story

stories(title="Design System/UserCard", component=UserCard)

# Shows the default user card state used across the app.
@story(args={"user": {"name": "Ada", "email": "ada@example.com"}})
def Default(args):
    return UserCard(user=args["user"])

The leading comment is used as story documentation. You can also use a function docstring or pass docs= explicitly.

@story(args={"user": {"name": "Grace", "email": "grace@example.com"}})
def GraceHopper(args):
    """Shows a second user fixture for documentation and visual checks."""
    return UserCard(user=args["user"])

Preview Layout

Use preview_layout when stories should use your app shell, global CSS, or design-system layout.

from contextlib import asynccontextmanager
from functools import partial

from app.ui.layouts import BaseLayout
from starlette_html_stories import html_stories


@asynccontextmanager
async def lifespan(app):
    async with html_stories(
        app=app,
        directory="src/app/ui/stories",
        preview_layout=partial(BaseLayout, page_title="Stories"),
    ):
        yield

This keeps each story focused on the component:

@story(args={"user": {"name": "Ada", "email": "ada@example.com"}})
def Default(args):
    return UserCard(user=args["user"])

HTMX-Friendly Stories

Story-local routes make interactive examples possible without wiring a story to your real business logic.

Use ctx.url_for(...) to point HTMX attributes at a route owned by the current story.

@story(routes=[Route("/load-more", load_more, name="load_more")])
def WithLoadMore(ctx):
    return Feed(
        hx_get=ctx.url_for("load_more"),
        hx_target="#feed",
    )

Example App

The repository includes a basic example.

uv run uvicorn examples.basic:app --reload

Open:

  • http://127.0.0.1:8000/
  • http://127.0.0.1:8000/__stories__/

Development

Run the development server when working on starlette-html-stories itself:

just dev

This starts tools/app.py, which uses the dev-only starlette-tailwindcss dependency to build and watch tools/styles.css. The generated CSS is written to src/starlette_html_stories/static/stories.css, ignored by git, and bundled with the published package.

For release, run:

just build
uv publish

License

MIT

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

starlette_html_stories-0.2.0.tar.gz (12.6 kB view details)

Uploaded Source

Built Distribution

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

starlette_html_stories-0.2.0-py3-none-any.whl (16.0 kB view details)

Uploaded Python 3

File details

Details for the file starlette_html_stories-0.2.0.tar.gz.

File metadata

  • Download URL: starlette_html_stories-0.2.0.tar.gz
  • Upload date:
  • Size: 12.6 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: uv/0.11.4 {"installer":{"name":"uv","version":"0.11.4","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

File hashes

Hashes for starlette_html_stories-0.2.0.tar.gz
Algorithm Hash digest
SHA256 e42ad92378ba2a31a423b2ee1f529dde11de25056f4988eb5d71fe0360a3350b
MD5 1fcd913d7cbdb179eda30677a6e584c7
BLAKE2b-256 ed29126567fbd94cb4bad4caac1aa0cd7b3d6d8e0249f4c36b5017ea6db36a51

See more details on using hashes here.

File details

Details for the file starlette_html_stories-0.2.0-py3-none-any.whl.

File metadata

  • Download URL: starlette_html_stories-0.2.0-py3-none-any.whl
  • Upload date:
  • Size: 16.0 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: uv/0.11.4 {"installer":{"name":"uv","version":"0.11.4","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

File hashes

Hashes for starlette_html_stories-0.2.0-py3-none-any.whl
Algorithm Hash digest
SHA256 ab897d4f7646a0c12b1a88c160c6889c422a94741f35f1ad83d2cc68cbfb37e0
MD5 fb6e47fb33ee053fe23da02ec07ca3e4
BLAKE2b-256 5053006c08ca00490a7c699b9685c1b5b070bfe0fa63417c5d0dd69c46f404c2

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