Skip to main content

Minimal library for stackable, renderable Pydantic models

Project description

Pydantic Stack Core

Typed hierarchical composition for structured text generation through nested Pydantic models.

Overview

Pydantic Stack Core enables building complex documents through nested, typed Pydantic models that render to composite strings via recursive composition. The power isn't in simple string concatenation - it's in creating typed document trees where each node knows how to render itself and its children.

The Core Pattern: Nested Typed Composition

Unlike simple templating, this library enables you to:

  • Nest typed Pydantic models within other models arbitrarily deep
  • Have each model render itself AND its nested children
  • Get full type safety and validation at every level
  • Build complex documents from reusable, composable pieces

Installation

[Installation instructions pending PyPI publication]

Quick Start - Simple Example

from pydantic_stack_core import RenderablePiece, MetaStack, generate_output_from_metastack

# Simple atomic pieces
class Title(RenderablePiece):
    text: str
    level: int = 1
    
    def render(self) -> str:
        return f"{'#' * self.level} {self.text}"

class Paragraph(RenderablePiece):
    content: str
    
    def render(self) -> str:
        return self.content

# Basic usage
stack = MetaStack(pieces=[
    Title(text="Hello", level=1),
    Paragraph(content="World")
])
output = generate_output_from_metastack(stack)

The Real Power: Nested Composition

from pydantic_stack_core import RenderablePiece
from typing import List

# Level 1: Atomic piece
class Author(RenderablePiece):
    name: str
    bio: str
    
    def render(self) -> str:
        return f"**{self.name}** - {self.bio}"

# Level 2: Piece containing other pieces
class CodeExample(RenderablePiece):
    language: str
    code: str
    explanation: str
    
    def render(self) -> str:
        return f"```{self.language}\n{self.code}\n```\n{self.explanation}"

# Level 3: Nested composition with typed fields!
class Section(RenderablePiece):
    title: str
    content: str
    code_examples: List[CodeExample]  # NESTED TYPED MODELS!
    
    def render(self) -> str:
        output = f"## {self.title}\n\n{self.content}\n\n"
        for example in self.code_examples:
            output += example.render() + "\n\n"  # RECURSIVE RENDERING!
        return output

# Level 4: Deep hierarchical document
class BlogPost(RenderablePiece):
    title: str
    author: Author  # NESTED MODEL AS FIELD!
    sections: List[Section]  # LIST OF NESTED MODELS!
    
    def render(self) -> str:
        output = f"# {self.title}\n\n"
        output += self.author.render() + "\n\n"
        for section in self.sections:
            output += section.render()  # CASCADING RENDERS!
        return output

# Build complex document through typed composition
blog = BlogPost(
    title="Understanding Pydantic Stack",
    author=Author(name="Isaac", bio="Building compound intelligence"),
    sections=[
        Section(
            title="Getting Started",
            content="This library enables nested typed composition.",
            code_examples=[
                CodeExample(
                    language="python",
                    code="class MyModel(RenderablePiece):\n    pass",
                    explanation="Define your model by inheriting RenderablePiece"
                )
            ]
        )
    ]
)

# Single render call triggers entire tree!
output = blog.render()

This creates a fully typed document tree where:

  • Type safety: Can't put an Author where a Section belongs
  • Validation: Pydantic validates at every level
  • Composition: Sections contain CodeExamples, BlogPosts contain Sections
  • Recursive rendering: Each piece renders itself and its children

Advanced Usage

Custom Separators

# Control spacing between pieces
stack = MetaStack(
    pieces=[...],
    separator="\n\n"  # Double newline between pieces
)

Nested Stacks

Since MetaStack is also a RenderablePiece, you can nest them:

section1 = MetaStack(pieces=[
    Title(text="Section 1", level=2),
    Paragraph(content="Section content...")
])

section2 = MetaStack(pieces=[
    Title(text="Section 2", level=2), 
    Paragraph(content="More content...")
])

document = MetaStack(pieces=[
    Title(text="Main Document", level=1),
    section1,
    section2
])

Custom Rendering Logic

class NumberedList(RenderablePiece):
    items: List[str]
    
    def render(self) -> str:
        return "\n".join(f"{i+1}. {item}" for i, item in enumerate(self.items))

class BulletList(RenderablePiece):
    items: List[str]
    
    def render(self) -> str:
        return "\n".join(f"• {item}" for item in self.items)

Use Cases

  • Documentation Generation: Create structured docs from data
  • Code Generation: Build source code from templates
  • Report Creation: Compose complex reports from components
  • Template Systems: Build flexible, reusable content templates
  • Agent Outputs: Systematic text generation for AI agents

Integration with HEAVEN Ecosystem

Pydantic Stack Core integrates with:

  • Payload Discovery: For systematic content generation workflows
  • Powerset Agents: For structured agent outputs
  • MetaStack Powerset Agent: For learning and applying stacking patterns

Development

# Clone and install for development
git clone https://github.com/sancovp/pydantic-stack-core
cd pydantic-stack-core
pip install -e ".[dev]"

# Run tests
pytest

# Format code
black .
ruff check .

Why Stack-Based?

The stack metaphor makes composition intuitive:

  1. Sequential: Pieces render in order
  2. Nestable: Stacks can contain other stacks
  3. Separable: Control spacing between pieces
  4. Extensible: Easy to add new piece types

This approach scales from simple text formatting to complex document generation while keeping the API minimal and predictable.

License

MIT License - see LICENSE file for details.

Part of HEAVEN Ecosystem

This library is part of the HEAVEN (Hierarchical Event-based Agent-Versatile Environment Network) ecosystem for AI agent development.

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

pydantic_stack_core-0.1.2.tar.gz (6.6 kB view details)

Uploaded Source

Built Distribution

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

pydantic_stack_core-0.1.2-py3-none-any.whl (7.4 kB view details)

Uploaded Python 3

File details

Details for the file pydantic_stack_core-0.1.2.tar.gz.

File metadata

  • Download URL: pydantic_stack_core-0.1.2.tar.gz
  • Upload date:
  • Size: 6.6 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for pydantic_stack_core-0.1.2.tar.gz
Algorithm Hash digest
SHA256 d16cbc8617e1e5989354f15ed964e6159b34fdeb8de42646c5989d9fb7934c03
MD5 3e9701226c2673f4c0f890210d466941
BLAKE2b-256 6dd69b0596de785a208d68b52bc47c798c98bd8f4d79d0966cac26f5b42afac4

See more details on using hashes here.

File details

Details for the file pydantic_stack_core-0.1.2-py3-none-any.whl.

File metadata

File hashes

Hashes for pydantic_stack_core-0.1.2-py3-none-any.whl
Algorithm Hash digest
SHA256 da22cb5c72272e808e178751f7ecd6e1a84b643234dd6f43bed4e3f03e83041f
MD5 6456a90348d4bba74ed45c37e7ca6bf7
BLAKE2b-256 69c2008e79c25dcd49de36ef5165119a02644135a02eb84f677b066f03953cf9

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