Skip to main content

Python wrapper for Decko — build, validate, and render presentations programmatically

Project description

decko-py

Python wrapper for Decko — build, validate, and render presentations programmatically.

Install

pip install decko-py

Quick start

from decko_py import DeckBuilder, TitleSlide

html = (
    DeckBuilder()
    .meta("My Presentation", author="Alice")
    .theme("midnight")
    .slide(TitleSlide(headline="Hello, World!"))
    .render_html()
)

# or save to file
DeckBuilder().meta("My Deck").theme("nova").slide(...).save("deck.html")

Models

All Pydantic v2 models. Import from decko_py or decko_py.models:

from decko_py import (
    Deck, DeckMeta, DeckTheme, Slide,
    TextBlock, CodeBlock, ListBlock, MediaBlock,
    MetricBlock, ChartBlock, ChartData, ChartDataset,
    TableBlock, CalloutBlock, DividerBlock, GroupBlock,
    XBlock, BlockAnimation, Composition,
    FadeTransition, PanTransition,
)

Serialization

All models serialize to camelCase JSON (matching the TypeScript schema):

block = TextBlock(content="Hello", display="heading")
block.model_dump(by_alias=True)
# {"type": "text", "display": "heading", "content": "Hello"}

Custom blocks

Register server-side renderers for x-* blocks:

from decko_py import BlockRegistry, XBlock

registry = BlockRegistry()

@registry.register("x-badge")
def render_badge(block: XBlock) -> str:
    return f'<span class="badge">{block.props["label"]}</span>'

html = DeckBuilder()...render_html(block_registry=registry)

Templates

23 built-in templates across 5 categories. Each has a matching typed slide class:

Category Template ID Typed slide class
narrative title-slide TitleSlide
narrative section-break SectionBreakSlide
narrative agenda AgendaSlide
narrative closing ClosingSlide
narrative quote QuoteSlide
content single-column SingleColumnSlide
content two-column TwoColumnSlide
content header-body HeaderBodySlide
content bullets-media BulletsMediaSlide
content three-up ThreeUpSlide
data big-metric BigMetricSlide
data metric-trio MetricTrioSlide
data chart-callout ChartCalloutSlide
data table-slide TableSlide
visual full-bleed-media FullBleedMediaSlide
visual media-caption MediaCaptionSlide
visual image-grid ImageGridSlide
visual comparison ComparisonSlide
visual kinetic-canvas KineticCanvasSlide
visual kinetic-hero KineticHeroSlide
technical code-walkthrough CodeWalkthroughSlide
technical architecture-diagram ArchitectureDiagramSlide
technical terminal TerminalSlide

Typed slide classes expose named, typed slot fields — no raw slots dict required. Plain strings auto-coerce to TextBlock:

from decko_py import TitleSlide, HeaderBodySlide, ListBlock
from decko_py.models.rich_text import ListItem

DeckBuilder()
    .slide(TitleSlide(
        headline="My Deck",          # str → TextBlock automatically
        subtitle="Subtitle here",
        notes="Speaker notes here",  # shown in presenter mode
    ))
    .slide(HeaderBodySlide(
        title="Why Decko?",
        body=ListBlock(display="bullets", items=[
            ListItem(text="Fully typed"),
            ListItem(text="23 built-in templates"),
        ]),
    ))

DeckBuilder.slide() accepts both typed slide classes and raw Slide objects.

Inspect slot requirements at the REPL:

TitleSlide.slots_info()
# TitleSlide [title-slide]
#   headline             required   text  max_chars=120
#   subtitle             optional   text  max_chars=200
#   eyebrow              optional   text  max_chars=60
#   logo                 optional   media

TitleSlide.definition()  # returns the full BaseTemplate catalog entry

DeckBuilder.build() auto-validates content budgets by default. Pass strict=False to skip:

deck = builder.build()               # raises ValueError on budget violations
deck = builder.build(strict=False)   # skip validation

Extend BaseTemplate to define custom templates:

from decko_py import BaseTemplate, TemplateSlot, ContentBudget, AiHints

class SplitTemplate(BaseTemplate):
    id: str = "split"
    name: str = "Split Slide"
    category: str = "content"
    description: str = "Two-column layout."
    slots: list[TemplateSlot] = [
        TemplateSlot(id="left", accepts=["text", "list"], required=True,
                     content_budget=ContentBudget(max_chars=300)),
        TemplateSlot(id="right", accepts=["text", "media"], required=True,
                     content_budget=ContentBudget(max_chars=300)),
    ]
    layout_modes: list[str] = ["split"]
    ai_hints: AiHints = AiHints(
        when_to_use="Side-by-side comparison.",
        good_for=["comparisons", "text + image"],
        avoid=["charts", "tables"],
        suggested_follow_up=["header-body"],
    )

Validation

Register templates before validating. register_defaults loads all 23 built-ins:

from decko_py import validate_content, TemplateRegistry, register_defaults

reg = TemplateRegistry()
register_defaults(reg)

violations = validate_content(deck, reg)
for v in violations:
    print(f"Slide {v.slide_index}, slot '{v.slot_id}': {v.field} exceeded ({v.actual} > {v.budget})")

CDN config

from decko_py import CdnConfig, HtmlRenderer

cdn = CdnConfig(version="1.2.3")
renderer = HtmlRenderer(cdn=cdn)
html = renderer.render(deck)

Development

git clone https://github.com/rchrdcrngl/decko_python.git
cd decko_python
python -m venv .venv && source .venv/bin/activate
pip install -e ".[dev]"
pytest
ruff check src/ tests/
mypy src/decko_py

CI/CD

  • CI: runs on every push/PR — lint (ruff), type check (mypy), tests (pytest) across Python 3.10–3.12
  • Publish: triggers on GitHub release → builds wheel + sdist → publishes to PyPI via OIDC trusted publishing (no API key required)

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

decko_py-0.2.0.tar.gz (37.5 kB view details)

Uploaded Source

Built Distribution

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

decko_py-0.2.0-py3-none-any.whl (26.2 kB view details)

Uploaded Python 3

File details

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

File metadata

  • Download URL: decko_py-0.2.0.tar.gz
  • Upload date:
  • Size: 37.5 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for decko_py-0.2.0.tar.gz
Algorithm Hash digest
SHA256 2b81206ce6a150c883d2bad2a2f3241b2de74e0402a290535f385fd258ce3249
MD5 a56ec5fda9df8c8a6e921b019522cf9f
BLAKE2b-256 ca6b7af9e418a09a725fb19db80bc804c746c919bec1e03be1ea9f1c4f33eb85

See more details on using hashes here.

Provenance

The following attestation bundles were made for decko_py-0.2.0.tar.gz:

Publisher: publish.yml on rchrdcrngl/decko_python

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

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

File metadata

  • Download URL: decko_py-0.2.0-py3-none-any.whl
  • Upload date:
  • Size: 26.2 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for decko_py-0.2.0-py3-none-any.whl
Algorithm Hash digest
SHA256 e773256a8f97524633f5a872cc889630ba256fffabc24c413e6ef3ade15900d5
MD5 74f633ae3c18215a9c5a53acbad5b75f
BLAKE2b-256 11de5410a9253baa88f2e3b7b044195bd3074bb897bc8af509854e7f924b6c2a

See more details on using hashes here.

Provenance

The following attestation bundles were made for decko_py-0.2.0-py3-none-any.whl:

Publisher: publish.yml on rchrdcrngl/decko_python

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

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