color_tools.exporters

Palette exporter package.

This package exposes the public palette-exporter API and imports concrete exporter modules so they can register themselves with the exporter registry.

Architecture:
  1. Exporters subclass PaletteExporter.

  2. Exporters register themselves with @register_exporter.

  3. registry.py owns exporter discovery and lookup.

  4. This module exposes the public package API.

class color_tools.exporters.AutoForgeExporter[source]

Bases: PaletteExporter

Export filament palettes to AutoForge CSV format.

AutoForge expects the following columns:

Brand,Name,TD,Color,Owned

Example

Bambu Lab PLA Basic,Jet Black,0.1,#000000,TRUE

The Brand field is assembled from the filament maker, material type, and finish. All exported filaments are marked as owned.

property metadata: ExporterMetadata

Return metadata describing the AutoForge exporter.

class color_tools.exporters.ASEExporter[source]

Bases: PaletteExporter

Export color palettes as Adobe Swatch Exchange (ASE) files.

Colors are written as RGB Process swatches. RGB channel values are normalized from 8-bit integer values (0-255) to the 0.0-1.0 range expected by the swatch package.

Color names are preserved when available.

When export_palette() is used with a palette name, all swatches are contained in a named ASE Color Group.

property metadata: ExporterMetadata

Return metadata describing the ASE exporter.

class color_tools.exporters.CSVExporter[source]

Bases: PaletteExporter

Export colors and filaments to generic CSV format.

Color columns:

name, hex, rgb, hsl, lab, lch

Filament columns are derived from the FilamentRecord dataclass fields.

Tuple-based color values are stored as comma-separated values inside individual CSV cells.

COLOR_FIELDS = ('name', 'hex', 'rgb', 'hsl', 'lab', 'lch')
property metadata: ExporterMetadata

Return metadata describing the generic CSV exporter.

class color_tools.exporters.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.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

class color_tools.exporters.GPLExporter[source]

Bases: PaletteExporter

Export color palettes in GIMP Palette (.gpl) format.

GPL is a plain-text RGB palette format supported by a broad range of graphics applications.

Palette and color names are sanitized to prevent embedded line breaks from corrupting the file structure.

Palette-aware export preserves:

  • name

  • columns

Author, description, and tags are written as GPL comments when present.

property metadata: ExporterMetadata

Return metadata describing the GPL exporter.

class color_tools.exporters.HexExporter[source]

Bases: PaletteExporter

Export color palettes as plain-text hexadecimal RGB values.

Each color is written as uppercase RRGGBB on its own line with no leading #.

This representation matches the HEX palette format commonly exported by Lospec and other palette-oriented tools.

property metadata: ExporterMetadata

Return metadata describing the HEX exporter.

class color_tools.exporters.JascPalExporter[source]

Bases: PaletteExporter

Export color palettes in JASC-PAL format.

JASC-PAL stores 8-bit RGB values as plain text. Color names and alpha values are not supported by the format.

property metadata: ExporterMetadata

Return metadata describing the JASC-PAL exporter.

class color_tools.exporters.JSONExporter[source]

Bases: PaletteExporter

Export colors and filaments as generic JSON.

Records are serialized directly from their dataclass representation, preserving the available application-level fields without adapting them to a third-party palette specification.

Palette-aware export additionally preserves the complete PaletteMetadata dataclass.

property metadata: ExporterMetadata

Return metadata describing the generic JSON exporter.

class color_tools.exporters.LospecExporter[source]

Bases: PaletteExporter

Export color palettes using Lospec’s JSON palette representation.

Lospec palettes contain:

  • name

  • author

  • colors

Each color is represented as an RRGGBB hexadecimal string without a leading #.

Palette-level metadata is preserved when export_palette() is used.

property metadata: ExporterMetadata

Return metadata describing the Lospec exporter.

exception color_tools.exporters.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.PaintNetExporter[source]

Bases: PaletteExporter

Export color palettes in Paint.NET palette format.

Paint.NET stores colors as 8-digit hexadecimal ARGB values:

AARRGGBB

Since ColorRecord currently contains opaque RGB colors, alpha is always written as FF.

Paint.NET palettes support a maximum of 96 palette entries. Optionally, palettes may be padded to 96 entries with opaque white.

MAX_COLORS = 96
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.

class color_tools.exporters.PaintNetExportOptions(pad_to_96=False)[source]

Bases: ExportOptionsBase

Options controlling Paint.NET palette serialization.

Parameters:

pad_to_96 (bool)

pad_to_96: bool
class color_tools.exporters.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'
class color_tools.exporters.PaletteLutExporter[source]

Bases: PaletteExporter

Export color palettes as N×1 RGB PNG lookup textures.

Each palette entry is written as one pixel in palette order.

The resulting image is suitable for uploading directly to a GPU texture and sampling by palette index. NEAREST filtering is recommended so texture sampling does not interpolate between adjacent palette entries.

Example:

>>> from color_tools.exporters import get_exporter
>>> from color_tools import load_palette
>>>
>>> exporter = get_exporter("palette_lut")
>>> palette = load_palette("nes")
>>> path = exporter.export_colors(
...     palette.records,
...     "nes.png",
... )

GLSL indexed lookup:

uniform sampler2D u_palette;
uniform int u_palette_size;

float u = (float(i) + 0.5) / float(u_palette_size);
vec3 color = texture(
    u_palette,
    vec2(u, 0.5)
).rgb;
property metadata: ExporterMetadata

Return metadata describing the palette LUT exporter.

class color_tools.exporters.RiffPalExporter[source]

Bases: PaletteExporter

Export color palettes in Microsoft RIFF PAL format.

RIFF PAL is a binary Windows palette format based on the RIFF container. It stores an ordered sequence of 8-bit RGB palette entries.

Color names and alpha values are not supported by this exporter.

PALETTE_VERSION = 768
property metadata: ExporterMetadata

Return metadata describing the RIFF PAL exporter.

class color_tools.exporters.CSSExporter[source]

Bases: PaletteExporter

Export color palettes as CSS custom properties.

property metadata: ExporterMetadata

Return metadata describing the CSS exporter.

class color_tools.exporters.SketchPaletteExporter[source]

Bases: PaletteExporter

Export color palettes in SketchPalette JSON format.

COMPATIBLE_VERSION = '1.4'
PLUGIN_VERSION = '1.4'
property metadata: ExporterMetadata

Return metadata describing the SketchPalette exporter.

class color_tools.exporters.SOCExporter[source]

Bases: PaletteExporter

Export color palettes in LibreOffice/OpenOffice SOC format.

OFFICE_NS = 'urn:oasis:names:tc:opendocument:xmlns:office:1.0'
DRAW_NS = 'urn:oasis:names:tc:opendocument:xmlns:drawing:1.0'
SVG_NS = 'http://www.w3.org/2000/svg'
OOO_NS = 'http://openoffice.org/2004/office'
property metadata: ExporterMetadata

Return metadata describing the SOC exporter.

class color_tools.exporters.ScribusExporter[source]

Bases: PaletteExporter

Export color palettes in Scribus XML palette format.

Colors are written as RGB process swatches.

Palette-aware export preserves the palette name using the SCRIBUSCOLORS root Name attribute.

property metadata: ExporterMetadata

Return metadata describing the Scribus exporter.

class color_tools.exporters.KPLExporter[source]

Bases: PaletteExporter

Export color palettes in Krita Palette (.kpl) format.

Krita’s native palette format supports color-managed swatches, groups, arbitrary grid positioning, multiple color spaces, spot colors, and embedded ICC profiles.

This exporter currently targets the subset represented by ColorRecord:

  • ungrouped colors

  • built-in sRGB

  • U8 bit depth

  • non-spot colors

  • sequential grid positioning

Palette metadata is used for the KPL palette name, description, and grid column count.

MIMETYPE = 'application/x-krita-palette'
FORMAT_VERSION = '1.0'
DEFAULT_COLUMNS = 16
property metadata: ExporterMetadata

Return metadata describing the KPL exporter.

class color_tools.exporters.SwatchImageExporter[source]

Bases: PaletteExporter

Export palettes as presentation-oriented PNG swatch sheets.

Each palette entry is rendered as a rounded card containing a large color sample, color name, and optionally several color-space representations.

Palette-aware export additionally displays palette name and description when available.

Pillow is loaded lazily so the exporter package remains importable when the image optional extra is not installed.

Export-specific display settings are supplied through SwatchImageOptions rather than through the exporter constructor. This allows the registry to continue constructing exporters without arguments.

Example

>>> from color_tools.exporters import get_exporter
>>> from color_tools.exporters.swatch_image_exporter import (
...     SwatchImageOptions,
... )
>>>
>>> exporter = get_exporter("swatch_image")
>>>
>>> exporter.export_palette(
...     palette,
...     "palette.png",
...     options=SwatchImageOptions(
...         show_rgb=True,
...         show_hsl=True,
...         show_lab=True,
...         show_lch=True,
...     ),
... )
IMAGE_WIDTH = 1600
OUTER_MARGIN = 64
HEADER_GAP = 28
CARD_WIDTH = 280
CARD_GAP = 28
CARD_PADDING = 18
CARD_RADIUS = 20
SWATCH_HEIGHT = 150
SWATCH_RADIUS = 16
SWATCH_BORDER_WIDTH = 1
TITLE_FONT_SIZE = 64
DESCRIPTION_FONT_SIZE = 22
NAME_FONT_SIZE = 21
VALUE_FONT_SIZE = 17
INDEX_FONT_SIZE = 15
NAME_VALUE_GAP = 10
VALUE_LINE_GAP = 6
CARD_BOTTOM_PADDING = 18
BACKGROUND = (245, 245, 245)
CARD_BACKGROUND = (255, 255, 255)
TEXT_PRIMARY = (30, 30, 30)
TEXT_SECONDARY = (85, 85, 85)
SWATCH_BORDER = (218, 218, 218)
INDEX_BACKGROUND = (238, 238, 238)
INDEX_TEXT = (80, 80, 80)
property metadata: ExporterMetadata

Return metadata describing the swatch image exporter.

class color_tools.exporters.PythonExporter[source]

Bases: PaletteExporter

Export palettes as Python source code.

This exporter is intended to produce source that can be dropped directly into Python applications, games, tools, and rendering code.

Several output structures are available through PythonExportOptions:

  • Dictionary

  • List

  • Tuple

  • Named constants

RGB values may be emitted as 0-255 integers or normalized floating-point values. Hexadecimal strings are also supported.

Example:

>>> exporter = get_exporter("python")
>>> exporter.export_palette(
...     palette,
...     "palette.py",
...     options=PythonExportOptions(
...         representation="dict",
...         normalized=True,
...         variable_name="GAME_COLORS",
...     ),
... )

Result:

GAME_COLORS_METADATA = {
    ...
}

GAME_COLORS = {
    "Medium Blue": (0.207843, 0.411765, 0.721569),
    ...
}

The generated structure is intentionally predictable so a future color_tools Python importer can safely parse canonical exporter output using Python’s AST without executing the source file.

property metadata: ExporterMetadata

Return metadata describing the Python exporter.

class color_tools.exporters.PythonExportOptions(representation='dict', value_format='rgb', normalized=False, include_alpha=False, include_metadata=True, include_names_as_comments=True, variable_name='PALETTE', precision=6)[source]

Bases: ExportOptionsBase

Per-export configuration for Python source-code palettes.

Variables:
  • representation

    Python structure used to represent the palette.

    Supported values:

    • "dict"

    • "list"

    • "tuple"

    • "constants"

  • value_format

    Color representation.

    "rgb" produces tuples such as (53, 105, 184).

    "hex" produces strings such as "#3569B8".

  • normalized

    Emit RGB channels as normalized floating-point values in the range 0.0-1.0 instead of integers in the range 0-255.

    Only valid with value_format="rgb".

  • include_alpha

    Add a fully opaque alpha channel to RGB values.

    Integer output uses 255.

    Normalized output uses 1.0.

    Only valid with value_format="rgb".

  • include_metadata – When exporting PaletteExportData, emit palette metadata as a separate dictionary.

  • include_names_as_comments – Include color names as trailing comments for list and tuple representations.

  • variable_name

    Python variable used for dict, list, and tuple representations.

    The metadata variable is derived from this name by appending _METADATA.

    For example:

    variable_name="UI_COLORS"
    

    produces:

    UI_COLORS_METADATA = {…} UI_COLORS = {…}

  • precision – Decimal precision used for normalized floating-point channels.

Parameters:
  • representation (Literal['dict', 'list', 'tuple', 'constants'])

  • value_format (Literal['rgb', 'hex'])

  • normalized (bool)

  • include_alpha (bool)

  • include_metadata (bool)

  • include_names_as_comments (bool)

  • variable_name (str)

  • precision (int)

representation: Literal['dict', 'list', 'tuple', 'constants']
value_format: Literal['rgb', 'hex']
normalized: bool
include_alpha: bool
include_metadata: bool
include_names_as_comments: bool
variable_name: str
precision: int
__post_init__()[source]

Validate Python exporter options.

Return type:

None

color_tools.exporters.get_exporter(format_name)[source]

Create an exporter instance by format name.

Parameters:

format_name (str) – Exporter identifier from ExporterMetadata.name.

Return type:

PaletteExporter

Returns:

A fresh instance of the requested exporter.

Raises:

ValueError – If the requested format is not registered.

Example

>>> exporter = get_exporter("json")
>>> print(exporter.metadata.description)
JSON format (raw data, backup/restore)
color_tools.exporters.list_export_formats(data_type='both', *, available_only=True)[source]

List registered export formats.

Formats may be filtered by the type of data they support and, optionally, by whether all of their required dependencies are currently installed.

Parameters:
  • data_type (str) –

    Data type to filter by:

    • "colors"

    • "filaments"

    • "both"

    "both" means exporters supporting either type, preserving the behavior of the previous exporter registry.

  • available_only (bool) – When True, omit exporters whose optional dependencies are missing. When False, include all registered exporters that match data_type.

Return type:

dict[str, str]

Returns:

Dictionary mapping exporter name to human-readable description.

Raises:

ValueError – If data_type is not one of the supported values.

color_tools.exporters.register_exporter(cls)[source]

Register an exporter class.

The exporter is instantiated once during registration so its metadata can be inspected. The class itself is stored in the registry and fresh exporter instances are created when requested with get_exporter().

Parameters:

cls (type[PaletteExporter]) – Exporter class to register.

Return type:

type[PaletteExporter]

Returns:

The same exporter class, unchanged, allowing this function to be used as a class decorator.

Raises:

ValueError – If another exporter is already registered with the same metadata name.

Example

>>> from color_tools.exporters.base import (
...     ExporterMetadata,
...     PaletteExporter,
... )
>>> from color_tools.exporters.registry import register_exporter
>>>
>>> @register_exporter
... class MyExporter(PaletteExporter):
...     @property
...     def metadata(self) -> ExporterMetadata:
...         return ExporterMetadata(
...             name="myformat",
...             description="My custom format",
...             file_extension="txt",
...             supports_colors=True,
...             supports_filaments=False,
...         )