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.1.tar.gz (39.6 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.1-py3-none-any.whl (27.2 kB view details)

Uploaded Python 3

File details

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

File metadata

  • Download URL: decko_py-0.2.1.tar.gz
  • Upload date:
  • Size: 39.6 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.1.tar.gz
Algorithm Hash digest
SHA256 f23e496b5f58aebd628e635f2f2e47e66384cab434d262a3014c6b7282f500dc
MD5 18e160aef7fa065fb3246719586afc4c
BLAKE2b-256 57812c45d5a6dfbd8f7dced820c25a971de6b223fab0fa98fd8bfef88504f978

See more details on using hashes here.

Provenance

The following attestation bundles were made for decko_py-0.2.1.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.1-py3-none-any.whl.

File metadata

  • Download URL: decko_py-0.2.1-py3-none-any.whl
  • Upload date:
  • Size: 27.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.1-py3-none-any.whl
Algorithm Hash digest
SHA256 4d49266cb685bfa081130740a6c72563dc9ff9a147b79db8280a7b32cf3f03ed
MD5 fc84407b5349f77d14768df2b9f1a493
BLAKE2b-256 b64cf168fb4fa5fc6372ade2d1ee7c9d3011783cfb2a5a7ea61d270bd3b479a8

See more details on using hashes here.

Provenance

The following attestation bundles were made for decko_py-0.2.1-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