color_tools.exporters.base

Base classes, metadata, and dependency handling for palette exporters.

This module defines the common exporter interface used by all palette export formats. Exporters declare their capabilities and optional dependencies through ExporterMetadata, while PaletteExporter provides consistent validation, dependency checking, filename generation, palette-aware export support, and optional per-export configuration.

Design:
  • PaletteExporter:

    Base class defining the exporter interface.

  • ExporterMetadata:

    Describes format capabilities and output characteristics.

  • ExporterDependency:

    Describes an optional third-party dependency.

  • MissingExporterDependencyError:

    Raised when an optional dependency is required but unavailable.

  • PaletteExportData:

    Supplies exporters with both ordered palette colors and optional palette-level metadata.

  • ExportOptionsBase:

    Base class for strongly typed exporter-specific configuration.

Exporters only need to override the operations they actually support.

For example, a colors-only exporter implements _export_colors_impl() but does not need to provide a placeholder _export_filaments_impl().

Palette-aware exporters may additionally override _export_palette_impl() when their format can preserve metadata such as palette name, author, description, or preferred column count. Exporters that do not override it automatically fall back to normal color export.

Configurable exporters remain stateless. They declare an options type in their metadata and override the appropriate options-aware implementation method.

Existing exporters that do not accept options do not need to change.

Example

>>> from color_tools.exporters.base import (
...     ExporterMetadata,
...     PaletteExporter,
... )
>>>
>>> class MyExporter(PaletteExporter):
...     @property
...     def metadata(self) -> ExporterMetadata:
...         return ExporterMetadata(
...             name="myformat",
...             description="My custom palette format",
...             file_extension="txt",
...             supports_colors=True,
...             supports_filaments=False,
...         )
...
...     def _export_colors_impl(self, colors, output_path):
...         # Implementation here.
...         return str(output_path)
class color_tools.exporters.base.ExporterDependency(package, import_name, extra=None)[source]

Bases: object

Optional third-party dependency required by an exporter.

Variables:
  • package – Distribution/package name used when installing the dependency, such as "swatch" or "Pillow".

  • import_name – Python module name used to test whether the dependency is installed, such as "swatch" or "PIL".

  • extra – Optional color-tools dependency extra that installs the package, such as "image".

Parameters:
  • package (str)

  • import_name (str)

  • extra (str | None)

Example

>>> dependency = ExporterDependency(
...     package="swatch",
...     import_name="swatch",
...     extra="image",
... )
package: str
import_name: str
extra: str | None
class color_tools.exporters.base.ExporterMetadata(name, description, file_extension, supports_colors, supports_filaments, supports_palette_metadata=False, is_binary=False, is_image=False, dependencies=(), options_type=None)[source]

Bases: object

Metadata describing an exporter’s capabilities.

Variables:
  • name – Machine-readable format identifier, such as "gpl", "jasc_pal", or "ase".

  • description – Human-readable format description.

  • file_extension – Default file extension without the leading dot.

  • supports_colors – Whether this exporter supports ColorRecord palettes.

  • supports_filaments – Whether this exporter supports FilamentRecord palettes.

  • supports_palette_metadata

    Whether this exporter preserves palette-level metadata when export_palette() is used.

    This flag is informational. All color exporters may be called through export_palette(); exporters that do not preserve metadata simply fall back to normal color export.

  • is_binary – Whether the output format is binary rather than text.

  • is_image – Whether the output format is an image.

  • dependencies – Optional third-party packages required by the exporter.

  • options_type – Exporter-specific ExportOptionsBase subclass accepted by this exporter. None means the exporter does not accept per-export configuration.

Parameters:

Example

>>> metadata = ExporterMetadata(
...     name="ase",
...     description="Adobe Swatch Exchange",
...     file_extension="ase",
...     supports_colors=True,
...     supports_filaments=False,
...     supports_palette_metadata=True,
...     is_binary=True,
...     dependencies=(
...         ExporterDependency(
...             package="swatch",
...             import_name="swatch",
...             extra="image",
...         ),
...     ),
... )
name: str
description: str
file_extension: str
supports_colors: bool
supports_filaments: bool
supports_palette_metadata: bool
is_binary: bool
is_image: bool
dependencies: tuple[ExporterDependency, ...]
options_type: type[ExportOptionsBase] | None
__post_init__()[source]

Validate exporter metadata.

Return type:

None

exception color_tools.exporters.base.MissingExporterDependencyError(exporter_name, dependencies)[source]

Bases: RuntimeError

Raised when an exporter requires an unavailable optional dependency.

Variables:
  • exporter_name – Machine-readable name of the exporter that could not run.

  • dependencies – Missing dependencies required by the exporter.

Parameters:
Return type:

None

class color_tools.exporters.base.PaletteExporter[source]

Bases: ABC

Base class for all palette exporters.

Concrete exporters must provide the metadata property and implement only the export operations they support.

The base class handles:

  • Capability checking.

  • Optional dependency discovery and validation.

  • Per-export option validation.

  • Consistent unsupported-operation errors.

  • Palette-aware export fallback.

  • Timestamped filename generation.

A colors-only exporter with supports_colors=True should override _export_colors_impl().

A filament exporter with supports_filaments=True should override _export_filaments_impl().

A palette-aware exporter with supports_palette_metadata=True may override _export_palette_impl() to preserve palette-level metadata.

A configurable exporter declares metadata.options_type and overrides the appropriate options-aware implementation method.

Unsupported implementation methods do not need to be overridden.

abstract property metadata: ExporterMetadata

Return metadata describing this exporter.

Returns:

Exporter metadata including its identifier, file extension, capabilities, output characteristics, optional dependencies, and supported options type.

property missing_dependencies: tuple[ExporterDependency, ...]

Return optional dependencies that are not currently installed.

Dependency availability is checked using each dependency’s Python import name rather than its distribution/package name.

Returns:

Tuple containing every unavailable dependency. The tuple is empty when all required dependencies are installed.

property is_available: bool

Return whether all dependencies required by this exporter are available.

Exporters without optional dependencies are always available.

Returns:

True if the exporter can be used in the current environment.

export_colors(colors, output_path=None, options=None)[source]

Export colors to a file.

Parameters:
  • colors (list[ColorRecord]) – Color records to export.

  • output_path (Path | str | None) – Output path. The concrete exporter may generate a path when this is None.

  • options (ExportOptionsBase | None) – Optional exporter-specific configuration.

Return type:

str

Returns:

Path to the exported file as a string.

Raises:
export_palette(palette, output_path=None, options=None)[source]

Export colors together with optional palette-level metadata.

Exporters that do not override _export_palette_impl() automatically fall back to normal color export and ignore the metadata.

Parameters:
  • palette (PaletteExportData) – Palette colors and palette-level metadata.

  • output_path (Path | str | None) – Output path. The concrete exporter may generate a path when this is None.

  • options (ExportOptionsBase | None) – Optional exporter-specific configuration.

Return type:

str

Returns:

Path to the exported file as a string.

Raises:
export_filaments(filaments, output_path=None, options=None)[source]

Export filaments to a file.

Parameters:
  • filaments (list[FilamentRecord]) – Filament records to export.

  • output_path (Path | str | None) – Output path. The concrete exporter may generate a path when this is None.

  • options (ExportOptionsBase | None) – Optional exporter-specific configuration.

Return type:

str

Returns:

Path to the exported file as a string.

Raises:
generate_filename(data_type)[source]

Generate a timestamped filename for an export.

Format:

{data_type}_{format_name}_{YYYYMMDD}_{HHMMSS}.{extension}

Parameters:

data_type (str) – Logical type being exported, normally "colors" or "filaments".

Return type:

str

Returns:

Generated filename without a directory component.

Example

>>> exporter.generate_filename("colors")
'colors_json_20260811_081500.json'