Skip to content

Configuration

renderkit.core.config.ConversionConfig dataclass

Configuration for image sequence to video conversion.

Source code in src/renderkit/core/config.py
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
@dataclass
class ConversionConfig:
    """Configuration for image sequence to video conversion."""

    input_pattern: str
    output_path: str
    prefetch_workers: int = 1
    fps: Optional[float] = None
    color_space_preset: ColorSpacePreset = ColorSpacePreset.LINEAR_TO_SRGB
    width: Optional[int] = None
    height: Optional[int] = None
    codec: str = "libx264"
    bitrate: Optional[int] = None
    quality: int = 10  # 0-10, 10 is best
    layer: Optional[str] = None  # Specific layer to extract (e.g. "diffuse")
    start_frame: Optional[int] = None
    end_frame: Optional[int] = None
    explicit_input_color_space: Optional[str] = (
        None  # Force specific input space (e.g. "ACES - ACEScg")
    )
    burnin_config: Optional[BurnInConfig] = None
    contact_sheet_mode: bool = False
    contact_sheet_config: Optional[ContactSheetConfig] = None

    def __post_init__(self) -> None:
        """Validate configuration after initialization."""
        if self.prefetch_workers <= 0:
            raise ConfigurationError("Prefetch workers must be greater than 0")
        if self.fps is not None and self.fps <= 0:
            raise ConfigurationError("FPS must be greater than 0")
        if self.width is not None and self.width <= 0:
            raise ConfigurationError("Width must be greater than 0")
        if self.height is not None and self.height <= 0:
            raise ConfigurationError("Height must be greater than 0")
        if self.bitrate is not None and self.bitrate <= 0:
            raise ConfigurationError("Bitrate must be greater than 0")
        if not 0 <= self.quality <= 10:
            raise ConfigurationError("Quality must be between 0 and 10")
        if self.start_frame is not None and self.end_frame is not None:
            if self.start_frame > self.end_frame:
                raise ConfigurationError("Start frame must be <= end frame")
        if self.contact_sheet_mode and self.contact_sheet_config is None:
            raise ConfigurationError(
                "Contact sheet config is required when contact sheet mode is enabled"
            )

__post_init__()

Validate configuration after initialization.

Source code in src/renderkit/core/config.py
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
def __post_init__(self) -> None:
    """Validate configuration after initialization."""
    if self.prefetch_workers <= 0:
        raise ConfigurationError("Prefetch workers must be greater than 0")
    if self.fps is not None and self.fps <= 0:
        raise ConfigurationError("FPS must be greater than 0")
    if self.width is not None and self.width <= 0:
        raise ConfigurationError("Width must be greater than 0")
    if self.height is not None and self.height <= 0:
        raise ConfigurationError("Height must be greater than 0")
    if self.bitrate is not None and self.bitrate <= 0:
        raise ConfigurationError("Bitrate must be greater than 0")
    if not 0 <= self.quality <= 10:
        raise ConfigurationError("Quality must be between 0 and 10")
    if self.start_frame is not None and self.end_frame is not None:
        if self.start_frame > self.end_frame:
            raise ConfigurationError("Start frame must be <= end frame")
    if self.contact_sheet_mode and self.contact_sheet_config is None:
        raise ConfigurationError(
            "Contact sheet config is required when contact sheet mode is enabled"
        )

renderkit.core.config.ConversionConfigBuilder

Builder for ConversionConfig using Builder pattern.

Source code in src/renderkit/core/config.py
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
class ConversionConfigBuilder:
    """Builder for ConversionConfig using Builder pattern."""

    def __init__(self) -> None:
        """Initialize the builder."""
        self._input_pattern: Optional[str] = None
        self._output_path: Optional[str] = None
        self._prefetch_workers: int = 1
        self._fps: Optional[float] = None
        self._color_space_preset: ColorSpacePreset = ColorSpacePreset.LINEAR_TO_SRGB
        self._width: Optional[int] = None
        self._height: Optional[int] = None
        self._codec: str = "libx264"
        self._bitrate: Optional[int] = None
        self._quality: int = 10
        self._layer: Optional[str] = None
        self._start_frame: Optional[int] = None
        self._end_frame: Optional[int] = None
        self._explicit_input_color_space: Optional[str] = None
        self._burnin_config: Optional[BurnInConfig] = None
        self._contact_sheet_mode: bool = False
        self._contact_sheet_config: Optional[ContactSheetConfig] = None

    def with_input_pattern(self, pattern: str) -> "ConversionConfigBuilder":
        """Set the input file pattern."""
        self._input_pattern = pattern
        return self

    def with_output_path(self, path: str) -> "ConversionConfigBuilder":
        """Set the output video path."""
        self._output_path = path
        return self

    def with_prefetch_workers(self, workers: int) -> "ConversionConfigBuilder":
        """Set number of prefetch worker threads for frame reads."""
        self._prefetch_workers = workers
        return self

    def with_fps(self, fps: float) -> "ConversionConfigBuilder":
        """Set the frame rate."""
        self._fps = fps
        return self

    def with_color_space_preset(self, preset: ColorSpacePreset) -> "ConversionConfigBuilder":
        """Set the color space preset."""
        self._color_space_preset = preset
        return self

    def with_explicit_input_color_space(self, space_name: str) -> "ConversionConfigBuilder":
        """Set explicit input color space name (for OCIO)."""
        self._explicit_input_color_space = space_name
        return self

    def with_resolution(self, width: int, height: int) -> "ConversionConfigBuilder":
        """Set the output resolution."""
        self._width = width
        self._height = height
        return self

    def with_codec(self, codec: str) -> "ConversionConfigBuilder":
        """Set the video codec."""
        self._codec = codec
        return self

    def with_bitrate(self, bitrate: int) -> "ConversionConfigBuilder":
        """Set the video bitrate."""
        self._bitrate = bitrate
        return self

    def with_quality(self, quality: int) -> "ConversionConfigBuilder":
        """Set the video quality (0-10)."""
        self._quality = quality
        return self

    def with_layer(self, layer: str) -> "ConversionConfigBuilder":
        """Set the EXR layer to extract."""
        self._layer = layer
        return self

    def with_frame_range(
        self, start: Optional[int], end: Optional[int]
    ) -> "ConversionConfigBuilder":
        """Set the frame range."""
        self._start_frame = start
        self._end_frame = end
        return self

    def with_burnin(self, config: BurnInConfig) -> "ConversionConfigBuilder":
        """Set the burn-in configuration."""
        self._burnin_config = config
        return self

    def with_contact_sheet(
        self, enabled: bool = True, config: Optional[ContactSheetConfig] = None
    ) -> "ConversionConfigBuilder":
        """Enable contact sheet mode."""
        self._contact_sheet_mode = enabled
        self._contact_sheet_config = config
        return self

    def build(self) -> ConversionConfig:
        """Build the ConversionConfig object."""
        if self._input_pattern is None:
            raise ConfigurationError("Input pattern is required")
        if self._output_path is None:
            raise ConfigurationError("Output path is required")

        return ConversionConfig(
            input_pattern=self._input_pattern,
            output_path=self._output_path,
            prefetch_workers=self._prefetch_workers,
            fps=self._fps,
            color_space_preset=self._color_space_preset,
            width=self._width,
            height=self._height,
            codec=self._codec,
            bitrate=self._bitrate,
            quality=self._quality,
            layer=self._layer,
            start_frame=self._start_frame,
            end_frame=self._end_frame,
            explicit_input_color_space=self._explicit_input_color_space,
            burnin_config=self._burnin_config,
            contact_sheet_mode=self._contact_sheet_mode,
            contact_sheet_config=self._contact_sheet_config,
        )

__init__()

Initialize the builder.

Source code in src/renderkit/core/config.py
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
def __init__(self) -> None:
    """Initialize the builder."""
    self._input_pattern: Optional[str] = None
    self._output_path: Optional[str] = None
    self._prefetch_workers: int = 1
    self._fps: Optional[float] = None
    self._color_space_preset: ColorSpacePreset = ColorSpacePreset.LINEAR_TO_SRGB
    self._width: Optional[int] = None
    self._height: Optional[int] = None
    self._codec: str = "libx264"
    self._bitrate: Optional[int] = None
    self._quality: int = 10
    self._layer: Optional[str] = None
    self._start_frame: Optional[int] = None
    self._end_frame: Optional[int] = None
    self._explicit_input_color_space: Optional[str] = None
    self._burnin_config: Optional[BurnInConfig] = None
    self._contact_sheet_mode: bool = False
    self._contact_sheet_config: Optional[ContactSheetConfig] = None

build()

Build the ConversionConfig object.

Source code in src/renderkit/core/config.py
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
def build(self) -> ConversionConfig:
    """Build the ConversionConfig object."""
    if self._input_pattern is None:
        raise ConfigurationError("Input pattern is required")
    if self._output_path is None:
        raise ConfigurationError("Output path is required")

    return ConversionConfig(
        input_pattern=self._input_pattern,
        output_path=self._output_path,
        prefetch_workers=self._prefetch_workers,
        fps=self._fps,
        color_space_preset=self._color_space_preset,
        width=self._width,
        height=self._height,
        codec=self._codec,
        bitrate=self._bitrate,
        quality=self._quality,
        layer=self._layer,
        start_frame=self._start_frame,
        end_frame=self._end_frame,
        explicit_input_color_space=self._explicit_input_color_space,
        burnin_config=self._burnin_config,
        contact_sheet_mode=self._contact_sheet_mode,
        contact_sheet_config=self._contact_sheet_config,
    )

with_bitrate(bitrate)

Set the video bitrate.

Source code in src/renderkit/core/config.py
250
251
252
253
def with_bitrate(self, bitrate: int) -> "ConversionConfigBuilder":
    """Set the video bitrate."""
    self._bitrate = bitrate
    return self

with_burnin(config)

Set the burn-in configuration.

Source code in src/renderkit/core/config.py
273
274
275
276
def with_burnin(self, config: BurnInConfig) -> "ConversionConfigBuilder":
    """Set the burn-in configuration."""
    self._burnin_config = config
    return self

with_codec(codec)

Set the video codec.

Source code in src/renderkit/core/config.py
245
246
247
248
def with_codec(self, codec: str) -> "ConversionConfigBuilder":
    """Set the video codec."""
    self._codec = codec
    return self

with_color_space_preset(preset)

Set the color space preset.

Source code in src/renderkit/core/config.py
229
230
231
232
def with_color_space_preset(self, preset: ColorSpacePreset) -> "ConversionConfigBuilder":
    """Set the color space preset."""
    self._color_space_preset = preset
    return self

with_contact_sheet(enabled=True, config=None)

Enable contact sheet mode.

Source code in src/renderkit/core/config.py
278
279
280
281
282
283
284
def with_contact_sheet(
    self, enabled: bool = True, config: Optional[ContactSheetConfig] = None
) -> "ConversionConfigBuilder":
    """Enable contact sheet mode."""
    self._contact_sheet_mode = enabled
    self._contact_sheet_config = config
    return self

with_explicit_input_color_space(space_name)

Set explicit input color space name (for OCIO).

Source code in src/renderkit/core/config.py
234
235
236
237
def with_explicit_input_color_space(self, space_name: str) -> "ConversionConfigBuilder":
    """Set explicit input color space name (for OCIO)."""
    self._explicit_input_color_space = space_name
    return self

with_fps(fps)

Set the frame rate.

Source code in src/renderkit/core/config.py
224
225
226
227
def with_fps(self, fps: float) -> "ConversionConfigBuilder":
    """Set the frame rate."""
    self._fps = fps
    return self

with_frame_range(start, end)

Set the frame range.

Source code in src/renderkit/core/config.py
265
266
267
268
269
270
271
def with_frame_range(
    self, start: Optional[int], end: Optional[int]
) -> "ConversionConfigBuilder":
    """Set the frame range."""
    self._start_frame = start
    self._end_frame = end
    return self

with_input_pattern(pattern)

Set the input file pattern.

Source code in src/renderkit/core/config.py
209
210
211
212
def with_input_pattern(self, pattern: str) -> "ConversionConfigBuilder":
    """Set the input file pattern."""
    self._input_pattern = pattern
    return self

with_layer(layer)

Set the EXR layer to extract.

Source code in src/renderkit/core/config.py
260
261
262
263
def with_layer(self, layer: str) -> "ConversionConfigBuilder":
    """Set the EXR layer to extract."""
    self._layer = layer
    return self

with_output_path(path)

Set the output video path.

Source code in src/renderkit/core/config.py
214
215
216
217
def with_output_path(self, path: str) -> "ConversionConfigBuilder":
    """Set the output video path."""
    self._output_path = path
    return self

with_prefetch_workers(workers)

Set number of prefetch worker threads for frame reads.

Source code in src/renderkit/core/config.py
219
220
221
222
def with_prefetch_workers(self, workers: int) -> "ConversionConfigBuilder":
    """Set number of prefetch worker threads for frame reads."""
    self._prefetch_workers = workers
    return self

with_quality(quality)

Set the video quality (0-10).

Source code in src/renderkit/core/config.py
255
256
257
258
def with_quality(self, quality: int) -> "ConversionConfigBuilder":
    """Set the video quality (0-10)."""
    self._quality = quality
    return self

with_resolution(width, height)

Set the output resolution.

Source code in src/renderkit/core/config.py
239
240
241
242
243
def with_resolution(self, width: int, height: int) -> "ConversionConfigBuilder":
    """Set the output resolution."""
    self._width = width
    self._height = height
    return self

renderkit.core.config.ContactSheetConfig dataclass

Configuration for contact sheet layout in multi-AOV mode.

Source code in src/renderkit/core/config.py
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
@dataclass
class ContactSheetConfig:
    """Configuration for contact sheet layout in multi-AOV mode."""

    columns: int = 4
    thumbnail_width: Optional[int] = None
    padding: int = 4
    background_color: tuple[float, float, float] = (0.1, 0.1, 0.1)
    show_labels: bool = True
    font_size: int = 16
    layer_width: Optional[int] = None
    layer_height: Optional[int] = None

    def __post_init__(self) -> None:
        """Validate configuration."""
        if self.font_size <= 0:
            raise ConfigurationError("Font size must be greater than 0")
        if self.columns <= 0:
            raise ConfigurationError("Columns must be greater than 0")
        if self.thumbnail_width is not None and self.thumbnail_width <= 0:
            raise ConfigurationError("Thumbnail width must be greater than 0")
        if self.padding < 0:
            raise ConfigurationError("Padding cannot be negative")
        if self.layer_width is not None and self.layer_width <= 0:
            raise ConfigurationError("Layer width must be greater than 0")
        if self.layer_height is not None and self.layer_height <= 0:
            raise ConfigurationError("Layer height must be greater than 0")

    def resolve_layer_size(self, source_width: int, source_height: int) -> tuple[int, int]:
        """Resolve target layer size based on config or source resolution."""
        target_w = self.layer_width
        target_h = self.layer_height

        if target_w is None and target_h is None:
            if self.thumbnail_width is None:
                return source_width, source_height
            target_w = self.thumbnail_width

        if target_w is None:
            assert target_h is not None
            scale = target_h / source_height
            target_w = max(1, int(source_width * scale))
        if target_h is None:
            assert target_w is not None
            scale = target_w / source_width
            target_h = max(1, int(source_height * scale))

        return target_w, target_h

__post_init__()

Validate configuration.

Source code in src/renderkit/core/config.py
45
46
47
48
49
50
51
52
53
54
55
56
57
58
def __post_init__(self) -> None:
    """Validate configuration."""
    if self.font_size <= 0:
        raise ConfigurationError("Font size must be greater than 0")
    if self.columns <= 0:
        raise ConfigurationError("Columns must be greater than 0")
    if self.thumbnail_width is not None and self.thumbnail_width <= 0:
        raise ConfigurationError("Thumbnail width must be greater than 0")
    if self.padding < 0:
        raise ConfigurationError("Padding cannot be negative")
    if self.layer_width is not None and self.layer_width <= 0:
        raise ConfigurationError("Layer width must be greater than 0")
    if self.layer_height is not None and self.layer_height <= 0:
        raise ConfigurationError("Layer height must be greater than 0")

resolve_layer_size(source_width, source_height)

Resolve target layer size based on config or source resolution.

Source code in src/renderkit/core/config.py
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
def resolve_layer_size(self, source_width: int, source_height: int) -> tuple[int, int]:
    """Resolve target layer size based on config or source resolution."""
    target_w = self.layer_width
    target_h = self.layer_height

    if target_w is None and target_h is None:
        if self.thumbnail_width is None:
            return source_width, source_height
        target_w = self.thumbnail_width

    if target_w is None:
        assert target_h is not None
        scale = target_h / source_height
        target_w = max(1, int(source_width * scale))
    if target_h is None:
        assert target_w is not None
        scale = target_w / source_width
        target_h = max(1, int(source_height * scale))

    return target_w, target_h

renderkit.core.config.ContactSheetConfigBuilder

Builder for ContactSheetConfig.

Source code in src/renderkit/core/config.py
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
class ContactSheetConfigBuilder:
    """Builder for ContactSheetConfig."""

    def __init__(self) -> None:
        """Initialize builder."""
        self._columns: int = 4
        self._thumbnail_width: Optional[int] = None
        self._padding: int = 4
        self._background_color: tuple[float, float, float] = (0.1, 0.1, 0.1)
        self._show_labels: bool = True
        self._font_size: int = 16
        self._layer_width: Optional[int] = None
        self._layer_height: Optional[int] = None

    def with_columns(self, columns: int) -> "ContactSheetConfigBuilder":
        """Set number of columns."""
        self._columns = columns
        return self

    def with_thumbnail_width(self, width: int) -> "ContactSheetConfigBuilder":
        """Set thumbnail width."""
        self._thumbnail_width = width
        return self

    def with_layer_size(
        self, width: int, height: Optional[int] = None
    ) -> "ContactSheetConfigBuilder":
        """Set explicit per-layer size."""
        self._layer_width = width
        self._layer_height = height
        return self

    def with_padding(self, padding: int) -> "ContactSheetConfigBuilder":
        """Set padding between thumbnails."""
        self._padding = padding
        return self

    def with_labels(self, show: bool, font_size: int = 16) -> "ContactSheetConfigBuilder":
        """Set label options."""
        self._show_labels = show
        self._font_size = font_size
        return self

    def build(self) -> ContactSheetConfig:
        """Build ContactSheetConfig."""
        return ContactSheetConfig(
            columns=self._columns,
            thumbnail_width=self._thumbnail_width,
            padding=self._padding,
            background_color=self._background_color,
            show_labels=self._show_labels,
            font_size=self._font_size,
            layer_width=self._layer_width,
            layer_height=self._layer_height,
        )

__init__()

Initialize builder.

Source code in src/renderkit/core/config.py
85
86
87
88
89
90
91
92
93
94
def __init__(self) -> None:
    """Initialize builder."""
    self._columns: int = 4
    self._thumbnail_width: Optional[int] = None
    self._padding: int = 4
    self._background_color: tuple[float, float, float] = (0.1, 0.1, 0.1)
    self._show_labels: bool = True
    self._font_size: int = 16
    self._layer_width: Optional[int] = None
    self._layer_height: Optional[int] = None

build()

Build ContactSheetConfig.

Source code in src/renderkit/core/config.py
125
126
127
128
129
130
131
132
133
134
135
136
def build(self) -> ContactSheetConfig:
    """Build ContactSheetConfig."""
    return ContactSheetConfig(
        columns=self._columns,
        thumbnail_width=self._thumbnail_width,
        padding=self._padding,
        background_color=self._background_color,
        show_labels=self._show_labels,
        font_size=self._font_size,
        layer_width=self._layer_width,
        layer_height=self._layer_height,
    )

with_columns(columns)

Set number of columns.

Source code in src/renderkit/core/config.py
96
97
98
99
def with_columns(self, columns: int) -> "ContactSheetConfigBuilder":
    """Set number of columns."""
    self._columns = columns
    return self

with_labels(show, font_size=16)

Set label options.

Source code in src/renderkit/core/config.py
119
120
121
122
123
def with_labels(self, show: bool, font_size: int = 16) -> "ContactSheetConfigBuilder":
    """Set label options."""
    self._show_labels = show
    self._font_size = font_size
    return self

with_layer_size(width, height=None)

Set explicit per-layer size.

Source code in src/renderkit/core/config.py
106
107
108
109
110
111
112
def with_layer_size(
    self, width: int, height: Optional[int] = None
) -> "ContactSheetConfigBuilder":
    """Set explicit per-layer size."""
    self._layer_width = width
    self._layer_height = height
    return self

with_padding(padding)

Set padding between thumbnails.

Source code in src/renderkit/core/config.py
114
115
116
117
def with_padding(self, padding: int) -> "ContactSheetConfigBuilder":
    """Set padding between thumbnails."""
    self._padding = padding
    return self

with_thumbnail_width(width)

Set thumbnail width.

Source code in src/renderkit/core/config.py
101
102
103
104
def with_thumbnail_width(self, width: int) -> "ContactSheetConfigBuilder":
    """Set thumbnail width."""
    self._thumbnail_width = width
    return self