Skip to main content

API Reference

Complete API reference for the Boards generators system, covering all classes, methods, and utilities.

Core Classes​

BaseGenerator​

Abstract base class for all generators in the Boards system.

from boards.generators.base import BaseGenerator

Class Attributes​

class MyGenerator(BaseGenerator):
name: str # Unique identifier for the generator
artifact_type: str # Type of artifact produced
description: str # Human-readable description

name (str, required) : Unique string identifier for the generator (e.g., "flux-pro", "whisper")

artifact_type (str, required) : Type of artifact this generator produces. Must be one of: "image", "video", "audio", "text", "lora"

description (str, required) : Brief human-readable description of what the generator does

Required Methods​

get_input_schema() → Type[BaseModel] : Returns the Pydantic model class that defines the input schema for this generator.

def get_input_schema(self) -> Type[BaseModel]:
return MyInputClass

generate(inputs: BaseModel) → BaseModel : Executes the generation process using the provided validated inputs.

async def generate(self, inputs: BaseModel) -> BaseModel:
# Implementation here
return MyOutputClass(...)

estimate_cost(inputs: BaseModel) → float : Estimates the cost of running this generation in USD.

async def estimate_cost(self, inputs: BaseModel) -> float:
return 0.05 # $0.05 USD

Optional Methods​

get_output_schema() → Type[BaseModel] : Returns the Pydantic model class that defines the output schema. Override if you need custom output schema definition.

def get_output_schema(self) -> Type[BaseModel]:
return MyOutputClass

Magic Methods​

repr() → str : String representation of the generator instance.

>>> generator = FluxProGenerator()
>>> repr(generator)
'<FluxProGenerator(name=\'flux-pro\', type=\'image\')>'

Artifact Types​

ImageArtifact​

Represents generated or input images.

from boards.generators.artifacts import ImageArtifact

artifact = ImageArtifact(
generation_id="gen_123",
storage_url="https://...",
width=1024,
height=1024,
format="png"
)

Fields​

generation_id (str, required) : ID of the generation that created this artifact

storage_url (str, required) : URL where the image file is stored

width (int, required) : Image width in pixels

height (int, required) : Image height in pixels

format (str, required) : Image format (png, jpg, webp, gif, etc.)

Properties​

# Calculate aspect ratio
aspect_ratio = artifact.width / artifact.height

# Calculate megapixels
megapixels = (artifact.width * artifact.height) / 1_000_000

VideoArtifact​

Represents generated or input videos.

from boards.generators.artifacts import VideoArtifact

artifact = VideoArtifact(
generation_id="gen_456",
storage_url="https://...",
width=1920,
height=1080,
format="mp4",
duration=30.5, # Optional
fps=30.0 # Optional
)

Required Fields​

generation_id (str) : Generation that created this video

storage_url (str) : URL where video is stored

width (int) : Video width in pixels

height (int) : Video height in pixels

format (str) : Video format (mp4, webm, mov, avi, etc.)

Optional Fields​

duration (Optional[float]) : Duration in seconds

fps (Optional[float]) : Frames per second

Calculated Properties​

# Total frames (if duration and fps available)
if artifact.duration and artifact.fps:
total_frames = artifact.duration * artifact.fps

# Resolution description
resolution = f"{artifact.width}x{artifact.height}"

AudioArtifact​

Represents generated or input audio files.

from boards.generators.artifacts import AudioArtifact

artifact = AudioArtifact(
generation_id="gen_789",
storage_url="https://...",
format="mp3",
duration=120.0, # Optional
sample_rate=44100, # Optional
channels=2 # Optional
)

Required Fields​

generation_id (str) : Generation that created this audio

storage_url (str) : URL where audio is stored

format (str) : Audio format (mp3, wav, flac, ogg, m4a, etc.)

Optional Fields​

duration (Optional[float]) : Duration in seconds

sample_rate (Optional[int]) : Sample rate in Hz (e.g., 44100, 48000)

channels (Optional[int]) : Number of audio channels (1=mono, 2=stereo)

TextArtifact​

Represents generated or input text content.

from boards.generators.artifacts import TextArtifact

artifact = TextArtifact(
generation_id="gen_text",
content="The generated text content...",
format="plain" # Optional, defaults to "plain"
)

Fields​

generation_id (str, required) : Generation that created this text

content (str, required) : The actual text content

format (str, optional) : Text format, defaults to "plain". Common values: "plain", "markdown", "html", "json", "code", "csv"

Special Note​

Unlike other artifacts, TextArtifact stores content directly. Use artifact.content to access the text, not resolve_artifact().

# Correct way to use text content
text_content = artifact.content

# Don't do this with TextArtifact
# file_path = await resolve_artifact(artifact) # Will raise an error

LoRArtifact​

Represents LoRA (Low-Rank Adaptation) model files.

from boards.generators.artifacts import LoRArtifact

artifact = LoRArtifact(
generation_id="gen_lora",
storage_url="https://...",
base_model="stable-diffusion-v1-5",
format="safetensors",
trigger_words=["anime_style", "cel_shading"] # Optional
)

Fields​

generation_id (str, required) : Generation that created this LoRA

storage_url (str, required) : URL where LoRA file is stored

base_model (str, required) : Base model this LoRA was trained on

format (str, required) : File format (safetensors, ckpt, bin, etc.)

trigger_words (Optional[list[str]]) : List of trigger words for this LoRA

Registry System​

GeneratorRegistry​

Central registry for managing generators.

from boards.generators.registry import GeneratorRegistry, registry

# Use global instance
generator = registry.get("flux-pro")

# Or create your own
my_registry = GeneratorRegistry()

Methods​

register(generator: BaseGenerator) → None : Register a generator instance.

registry.register(MyGenerator())

# Raises ValueError if generator name already registered

get(name: str) → Optional[BaseGenerator] : Get generator by name, returns None if not found.

generator = registry.get("flux-pro")
if generator:
result = await generator.generate(inputs)

list_all() → list[BaseGenerator] : Return all registered generators.

all_generators = registry.list_all()
print(f"Total generators: {len(all_generators)}")

list_by_artifact_type(artifact_type: str) → list[BaseGenerator] : Return generators that produce the specified artifact type.

image_generators = registry.list_by_artifact_type("image")
video_generators = registry.list_by_artifact_type("video")

list_names() → list[str] : Return list of all registered generator names.

names = registry.list_names()
print("Available generators:", ", ".join(names))

unregister(name: str) → bool : Remove generator by name. Returns True if found and removed.

success = registry.unregister("old-generator")
if success:
print("Generator removed")

clear() → None : Remove all registered generators.

registry.clear()
assert len(registry) == 0

Magic Methods​

contains(name: str) → bool : Check if generator with name is registered.

if "flux-pro" in registry:
print("FLUX Pro is available")

len() → int : Return number of registered generators.

print(f"Registry has {len(registry)} generators")

Global Registry​

The system provides a global registry instance:

from boards.generators.registry import registry

# This is a singleton instance used throughout the system
assert registry is registry # Same instance

Artifact Resolution​

resolve_artifact()​

Converts artifact references to local file paths for use with provider SDKs.

from boards.generators.resolution import resolve_artifact

async def my_function(image_artifact: ImageArtifact):
file_path = await resolve_artifact(image_artifact)
# Now you can use file_path with any provider SDK

Parameters​

artifact (Union[AudioArtifact, VideoArtifact, ImageArtifact, LoRArtifact]) : Artifact to resolve to a local file path

Returns​

str : Local file path that can be used with provider SDKs

Raises​

ValueError : If trying to resolve a TextArtifact (use .content property instead)

httpx.HTTPError : If downloading the artifact fails

Behavior​

  • If storage_url is already a local file path, returns it directly
  • If storage_url is a remote URL, downloads to a temporary file and returns the path
  • Handles file extensions based on the artifact's format field
  • Cleans up temporary files on download failure
# Example usage
async def process_image(image_artifact: ImageArtifact):
try:
image_path = await resolve_artifact(image_artifact)

# Use with any provider SDK
result = await some_sdk.process_image(image_path)

return result
except httpx.HTTPError as e:
print(f"Failed to download image: {e}")
raise

Storage Functions​

Functions for creating artifact instances from generated content.

store_image_result()​

from boards.generators.resolution import store_image_result

artifact = await store_image_result(
storage_url="https://storage.com/image.png",
format="png",
generation_id="gen_123",
width=1024,
height=1024
)

Parameters:

  • storage_url (str): URL where image is stored
  • format (str): Image format
  • generation_id (str): Generation that created this
  • width (int): Image width in pixels
  • height (int): Image height in pixels

Returns: ImageArtifact

store_video_result()​

from boards.generators.resolution import store_video_result

artifact = await store_video_result(
storage_url="https://storage.com/video.mp4",
format="mp4",
generation_id="gen_456",
width=1920,
height=1080,
duration=30.0, # Optional
fps=24.0 # Optional
)

Parameters:

  • storage_url (str): URL where video is stored
  • format (str): Video format
  • generation_id (str): Generation that created this
  • width (int): Video width in pixels
  • height (int): Video height in pixels
  • duration (Optional[float]): Duration in seconds
  • fps (Optional[float]): Frames per second

Returns: VideoArtifact

store_audio_result()​

from boards.generators.resolution import store_audio_result

artifact = await store_audio_result(
storage_url="https://storage.com/audio.mp3",
format="mp3",
generation_id="gen_789",
duration=120.0, # Optional
sample_rate=44100, # Optional
channels=2 # Optional
)

Parameters:

  • storage_url (str): URL where audio is stored
  • format (str): Audio format
  • generation_id (str): Generation that created this
  • duration (Optional[float]): Duration in seconds
  • sample_rate (Optional[int]): Sample rate in Hz
  • channels (Optional[int]): Number of channels

Returns: AudioArtifact

Pydantic Integration​

Field Validation​

Use Pydantic's field validation for input schemas:

from pydantic import BaseModel, Field, field_validator
from typing import Self

class ValidatedInput(BaseModel):
prompt: str = Field(min_length=1, max_length=500)
quality: float = Field(ge=0.0, le=1.0)

@field_validator('prompt')
@classmethod
def validate_prompt(cls, v: str) -> str:
if 'forbidden' in v.lower():
raise ValueError('Prompt contains forbidden content')
return v.strip()

Common Field Constraints​

String Fields:

prompt: str = Field(
min_length=1, # Minimum length
max_length=500, # Maximum length
pattern=r"^[a-zA-Z\s]+$" # Regex pattern
)

Numeric Fields:

strength: float = Field(
ge=0.0, # Greater than or equal
le=1.0, # Less than or equal
gt=0.0, # Greater than (exclusive)
lt=1.0 # Less than (exclusive)
)

steps: int = Field(
ge=1,
le=500,
description="Number of inference steps"
)

List Fields:

items: list[str] = Field(
min_items=1, # Minimum number of items
max_items=10, # Maximum number of items
unique_items=True # All items must be unique
)

Model Validators​

Cross-field validation using model validators:

from pydantic import model_validator

class ConditionalInput(BaseModel):
mode: str
text_input: Optional[str] = None
image_input: Optional[ImageArtifact] = None

@model_validator(mode='after')
def validate_conditional_fields(self) -> Self:
if self.mode == "text" and not self.text_input:
raise ValueError("text_input required when mode='text'")
elif self.mode == "image" and not self.image_input:
raise ValueError("image_input required when mode='image'")
return self

JSON Schema Generation​

Generate JSON schemas for frontend integration:

class MyInput(BaseModel):
prompt: str = Field(description="Generation prompt")
strength: float = Field(default=0.75, ge=0.0, le=1.0)

# Generate JSON schema
schema = MyInput.model_json_schema()

# Example output:
{
"type": "object",
"properties": {
"prompt": {
"type": "string",
"description": "Generation prompt",
"title": "Prompt"
},
"strength": {
"type": "number",
"default": 0.75,
"maximum": 1.0,
"minimum": 0.0,
"title": "Strength"
}
},
"required": ["prompt"],
"title": "MyInput"
}

Error Handling​

Common Error Patterns​

import os
from typing import Optional

class MyGenerator(BaseGenerator):
async def generate(self, inputs: MyInput) -> MyOutput:
# 1. Environment validation
api_key = os.getenv("PROVIDER_API_KEY")
if not api_key:
raise ValueError(
"PROVIDER_API_KEY environment variable is required. "
"Get your key from https://provider.com/keys"
)

# 2. Provider-specific error handling
try:
result = await provider.generate(**inputs.dict())
except provider.AuthenticationError:
raise ValueError("Invalid API key - check PROVIDER_API_KEY")
except provider.RateLimitError as e:
retry_after = getattr(e, 'retry_after', 60)
raise ValueError(f"Rate limited - retry after {retry_after} seconds")
except provider.ValidationError as e:
raise ValueError(f"Invalid input: {e.message}")
except Exception as e:
raise RuntimeError(f"Generation failed: {str(e)}")

return MyOutput(...)

Exception Types​

The generators system uses these exception patterns:

ValueError : For user-correctable errors (missing API keys, invalid inputs, provider validation errors)

RuntimeError : For unexpected errors that users can't directly fix

httpx.HTTPError : For network/download errors when resolving artifacts

Testing Utilities​

Mock Helpers​

from boards.generators.artifacts import ImageArtifact

def create_mock_image_artifact(
generation_id: str = "test_gen",
storage_url: str = "https://mock.com/image.png",
width: int = 1024,
height: int = 1024,
format: str = "png"
) -> ImageArtifact:
"""Helper to create mock image artifacts for testing."""
return ImageArtifact(
generation_id=generation_id,
storage_url=storage_url,
width=width,
height=height,
format=format
)

Test Patterns​

import pytest
from unittest.mock import patch, AsyncMock

class TestMyGenerator:
def setup_method(self):
self.generator = MyGenerator()

@pytest.mark.asyncio
async def test_generate_success(self):
inputs = MyInput(prompt="test")

with patch.dict(os.environ, {"API_KEY": "fake-key"}):
with patch('provider.generate') as mock_gen:
mock_gen.return_value = "result_url"

with patch('my_generator.store_image_result') as mock_store:
mock_store.return_value = create_mock_image_artifact()

result = await self.generator.generate(inputs)
assert isinstance(result, MyOutput)

Type Hints​

The generators system uses comprehensive type hints:

from typing import Type, Optional, Union, List, Dict, Any
from pydantic import BaseModel
from boards.generators.base import BaseGenerator
from boards.generators.artifacts import ImageArtifact, VideoArtifact

class MyGenerator(BaseGenerator):
def get_input_schema(self) -> Type[BaseModel]:
# Returns a class, not an instance
return MyInput

async def generate(self, inputs: BaseModel) -> BaseModel:
# inputs will be validated as MyInput type
# Return type should match get_output_schema()
return MyOutput(...)

async def estimate_cost(self, inputs: BaseModel) -> float:
# Always returns float (cost in USD)
return 0.05

Integration Points​

GraphQL Integration​

Generators are automatically exposed via GraphQL:

# Automatic schema generation
query GetGenerators($artifactType: String) {
generators(artifactType: $artifactType) {
name
artifactType
description
inputSchema # JSON schema from Pydantic
outputSchema # JSON schema from Pydantic
}
}

mutation RunGeneration($generatorName: String!, $inputs: JSON!) {
runGeneration(generatorName: $generatorName, inputs: $inputs) {
id
status
estimatedCost
result {
# Polymorphic result based on artifact_type
}
}
}

Storage System Integration​

Generators integrate with the pluggable storage system:

# Storage functions will be implemented to:
# 1. Upload content to configured backend (S3, local, GCS, etc.)
# 2. Generate storage URLs
# 3. Handle metadata and thumbnails
# 4. Manage file lifecycle

Database Integration​

Generated artifacts are stored in the database with:

  • Generation metadata (model, parameters, cost)
  • Artifact relationships and lineage
  • User permissions and board associations
  • Audit trails and usage tracking

This API reference provides comprehensive coverage of all public interfaces in the Boards generators system.