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_urlis already a local file path, returns it directly - If
storage_urlis a remote URL, downloads to a temporary file and returns the path - Handles file extensions based on the artifact's
formatfield - 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 storedformat(str): Image formatgeneration_id(str): Generation that created thiswidth(int): Image width in pixelsheight(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 storedformat(str): Video formatgeneration_id(str): Generation that created thiswidth(int): Video width in pixelsheight(int): Video height in pixelsduration(Optional[float]): Duration in secondsfps(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 storedformat(str): Audio formatgeneration_id(str): Generation that created thisduration(Optional[float]): Duration in secondssample_rate(Optional[int]): Sample rate in Hzchannels(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.