Skip to content

Custom Generators

Jag_k edited this page Feb 18, 2025 · 1 revision

Custom Generators

This guide explains how to create and use custom generators in pydantic-settings-export.

Overview

Custom generators allow you to:

  • Create new output formats
  • Customize existing formats
  • Add special processing
  • Integrate with other tools

Basic Structure

Every generator needs:

  1. Configuration class
  2. Generator implementation
  3. Registration with the system

Minimal Example

from pathlib import Path
from pydantic import BaseModel, Field
from pydantic_settings_export.generators import AbstractGenerator
from pydantic_settings_export.models import SettingsInfoModel


class HTMLGeneratorSettings(BaseModel):
    """Configuration for HTML generator."""
    paths: list[Path] = Field(
        default_factory=list,
        description="Output file paths"
    )
    include_css: bool = Field(
        True,
        description="Include default CSS"
    )

    
class HTMLGenerator(AbstractGenerator):
    """Generate HTML documentation."""
    name = "html"  # Unique identifier
    config = HTMLGeneratorSettings

    def generate_single(self, settings_info: SettingsInfoModel, level: int = 1) -> str:
        result = ["<html><body>", f"<h{level}>{settings_info.name}</h{level}>"]

        if settings_info.docs:
            result.append(f"<p>{settings_info.docs}</p>")

        result.append("<table>")
        for field in settings_info.fields:
            result.append(
                f"<tr>"
                f"<td>{field.name}</td>"
                f"<td>{' | '.join(field.types)}</td>"
                f"<td>{field.default or 'required'}</td>"
                f"</tr>"
            )
        result.append("</table></body></html>")

        return "\n".join(result)

See Parsers for details.

Configuration Options

Add flexible configuration:

from pathlib import Path
from typing import Literal

from pydantic import BaseModel, Field


class AdvancedGeneratorSettings(BaseModel):
    paths: list[Path]
    template: str = Field(
        "default.html",
        description="HTML template to use"
    )
    css_framework: Literal["bootstrap", "tailwind", "none"] = "none"
    minify: bool = False

Integration

Using Your Generator

from pydantic_settings_export import Exporter, PSESettings
from your_package.generators import HTMLGenerator

pse_settings = PSESettings()
exporter = Exporter(
    pse_settings,
    generators=[
        HTMLGenerator(
            pse_settings,
            HTMLGenerator.config(
                paths=["docs/settings.md.html"],
                include_css=True
            )
        )
    ]
)

Configuration

# pyproject.toml
[tool.pydantic_settings_export.generators.html]
paths = ["docs/settings.md.html"]
include_css = true
template = "custom.html"

Best Practices

  1. Naming

    • Use clear, unique generator names
    • Follow naming conventions
    • Document name conflicts
  2. Configuration

    • Provide sensible defaults
    • Validate inputs
    • Document options clearly
  3. Output

    • Handle all edge cases
    • Escape special characters
    • Format consistently
  4. Testing

    • Test with various inputs
    • Verify output format
    • Check error handling

Common Issues

  1. Name Conflicts

    from pydantic_settings_export import AbstractGenerator
    
    # Already exists
    class MarkdownGenerator(AbstractGenerator):
        name = "markdown"  # Will raise ValueError because a generator with this name already exists
        ...
  2. Missing Configuration

    from pydantic_settings_export import AbstractGenerator
    
    # Incomplete
    class BadGenerator(AbstractGenerator):
        name = "bad"
        # Missing config class!
        ...

Related Topics

Clone this wiki locally