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.AsepriteExporter[source]

Bases: PaletteExporter

Export ordered RGB swatches with a transparent entry by default.

Up to 256 total entries use indexed pixels; larger palettes use RGBA pixels. Accepts 1-65,534 input colors by default, or 1-65,535 with transparency off. Names and duplicate colors are preserved. Palette metadata supplies the layer name and grid columns, not a native palette-title field. Other metadata is not represented. None/zero columns produce a horizontal strip.

property metadata: ExporterMetadata

Describe the dependency-free .aseprite color exporter.

class color_tools.exporters.AsepriteExportOptions(include_transparent=True)[source]

Bases: ExportOptionsBase

Control Aseprite palette serialization.

include_transparent defaults to True: prepend a named transparent-black entry at index zero without modifying input records. Supplied colors shift by one index and remain opaque. Set False to export only supplied colors. The added entry counts toward grid layout and the 256-entry indexed limit.

Parameters:

include_transparent (bool)

include_transparent: bool
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 (str) – Distribution/package name used when installing the dependency, such as "swatch" or "Pillow".

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

  • extra (str | None) – 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 (str) – Machine-readable format identifier, such as "gpl", "jasc_pal", or "ase".

  • description (str) – Human-readable format description.

  • file_extension (str) – Default file extension without the leading dot.

  • supports_colors (bool) – Whether this exporter supports ColorRecord palettes.

  • supports_filaments (bool) – Whether this exporter supports FilamentRecord palettes.

  • supports_palette_metadata (bool) –

    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 (bool) – Whether the output format is binary rather than text.

  • is_image (bool) – Whether the output format is an image.

  • dependencies (tuple[ExporterDependency, ...]) – Optional third-party packages required by the exporter.

  • options_type (type[ExportOptionsBase] | None) – 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.FilamentExportData(filaments, metadata=FilamentMetadata())[source]

Bases: object

Ordered filaments and metadata shared by importers and exporters.

The model is format-neutral. Importers can return it for inspection or format conversion, while exporters that do not use collection metadata can consume its filaments list through the standard fallback.

Variables:
Parameters:
filaments: list[FilamentRecord]
metadata: FilamentMetadata
class color_tools.exporters.FilamentMetadata(name='', author='', description='', tags=(), owned_filament_ids=(), properties=_empty_properties())[source]

Bases: object

Descriptive and inventory metadata for a filament collection.

Ownership and external-format identifiers belong to collection metadata, not to FilamentRecord, because they describe user state or an interchange format rather than the filament product itself.

Variables:
  • name (str) – Human-readable collection name.

  • author (str) – Collection creator or author.

  • description (str) – Optional longer collection description.

  • tags (tuple[str, ...]) – Searchable or descriptive collection tags.

  • owned_filament_ids (tuple[str, ...]) – Color Tools filament IDs marked as owned.

  • properties (dict[str, Any]) – Additional format-specific metadata needed for a loss-aware round trip, such as external identifier mappings.

Parameters:
name: str
author: str
description: str
tags: tuple[str, ...]
owned_filament_ids: tuple[str, ...]
properties: dict[str, Any]
__post_init__()[source]

Normalize collection metadata text and identifiers.

Return type:

None

property has_metadata: bool

Return whether the collection contains meaningful metadata.

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.GLSLExporter[source]

Bases: PaletteExporter

Export palettes as reusable GLSL vec3 or vec4 definitions.

property metadata: ExporterMetadata

Return metadata describing the GLSL exporter.

class color_tools.exporters.GLSLExportOptions(representation='array', normalized=True, include_alpha=False, include_metadata=True, include_names_as_comments=True, variable_name='PALETTE', identifier_prefix='', precision=6, include_size_constant=True, include_version=False, version='330 core')[source]

Bases: ExportOptionsBase

Configuration for GLSL source-code palette export.

Variables:
  • representation (Literal['array', 'constants', 'defines']) – "array" emits one indexed constant array, "constants" emits named const values, and "defines" emits named preprocessor definitions.

  • normalized (bool) – Divide RGB channels by 255 and emit values in the 0.0-1.0 range. When false, raw 0-255 channels are emitted with a .0 suffix.

  • include_alpha (bool) – Emit vec4 values with an opaque alpha channel instead of vec3 values.

  • include_metadata (bool) – Include available palette metadata as leading line comments.

  • include_names_as_comments (bool) – Add color names after entries in the array representation.

  • variable_name (str) – GLSL identifier used for the array and its optional size constant.

  • identifier_prefix (str) – Prefix applied to generated constant and macro identifiers.

  • precision (int) – Decimal places used for normalized channels. Must be at least one.

  • include_size_constant (bool) – Emit <variable_name>_SIZE with the number of colors.

  • include_version (bool) – Emit a #version directive as the first line.

  • version (str) – Version directive value, such as "330 core" or "300 es".

Parameters:
  • representation (Literal['array', 'constants', 'defines'])

  • normalized (bool)

  • include_alpha (bool)

  • include_metadata (bool)

  • include_names_as_comments (bool)

  • variable_name (str)

  • identifier_prefix (str)

  • precision (int)

  • include_size_constant (bool)

  • include_version (bool)

  • version (str)

representation: Literal['array', 'constants', 'defines']
normalized: bool
include_alpha: bool
include_metadata: bool
include_names_as_comments: bool
variable_name: str
identifier_prefix: str
precision: int
include_size_constant: bool
include_version: bool
version: str
__post_init__()[source]

Validate GLSL export options.

Return type:

None

class color_tools.exporters.HexExporter[source]

Bases: PaletteExporter

Export color palettes as plain-text hexadecimal RGB values.

Each color is written as lowercase rrggbb on its own line with no leading # by default. HexExportOptions(uppercase=True) selects uppercase output for an individual Python export operation.

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.HexExportOptions(uppercase=False)[source]

Bases: ExportOptionsBase

Configure letter casing in plain-text HEX palette output.

Parameters:

uppercase (bool)

uppercase: bool
__post_init__()[source]

Validate HEX export options.

Return type:

None

class color_tools.exporters.HueForgeExporter[source]

Bases: PaletteExporter

Export filament records as a HueForge filament-library document.

Every record must have a TD value and a nonempty, unique Color Tools ID. Stable HueForge UUIDs are derived from those IDs with UUIDv5, so repeated exports of the same records retain their identities.

The exporter raises ValueError rather than silently omitting records without TD values. Callers can prefilter with FilamentFilterCriteria(has_td=True) or use the CLI’s --has-td option.

property metadata: ExporterMetadata

Return metadata describing the HueForge exporter.

class color_tools.exporters.HueForgeExportOptions(owned=True)[source]

Bases: ExportOptionsBase

Configure whether exported filaments are marked as owned.

owned defaults to true because a generated HueForge library normally represents the caller’s available filament collection. Set it to false to create entries that HueForge should not initially mark as owned.

Parameters:

owned (bool)

owned: bool
__post_init__()[source]

Validate HueForge export options.

Return type:

None

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 the Paint.NET exporter.

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:
export_filament_data(data, output_path=None, options=None)[source]

Export filaments together with collection-level metadata.

Exporters without a metadata-aware implementation automatically fall back to ordinary filament export and ignore collection metadata.

Parameters:
Return type:

str

Returns:

Path to the exported file as a string.

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 (Literal['dict', 'list', 'tuple', 'constants']) –

    Python structure used to represent the palette.

    Supported values:

    • "dict"

    • "list"

    • "tuple"

    • "constants"

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

    Color representation.

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

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

  • normalized (bool) –

    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 (bool) –

    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 (bool) – When exporting PaletteExportData, emit palette metadata as a separate dictionary.

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

  • variable_name (str) –

    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 (int) – 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,
...         )
class color_tools.exporters.UserColorsExporter(data_dir=None)[source]

Bases: object

Plan and explicitly apply safe updates to user-colors.json.

plan() is read-only and is therefore the default operation. apply() validates that the destination has not changed since planning, validates the complete prospective document, atomically replaces the data file, and refreshes its SHA-256 sidecar.

Parameters:

data_dir (Path | str | None)

property destination: Path

Return the managed user-colors.json path.

plan(data, *, conflict_policy='error')[source]

Build a read-only merge plan for imported or selected colors.

Return type:

UserColorExportPlan

Parameters:
apply(plan)[source]

Apply a previously reviewed plan and return its structured result.

Return type:

UserColorExportResult

Parameters:

plan (UserColorExportPlan)

class color_tools.exporters.UserColorExportChange(action, incoming, existing=None, message='')[source]

Bases: object

One decision made while planning a user-color update.

Parameters:
action: Literal['added', 'updated', 'unchanged', 'skipped', 'conflict']
incoming: ColorRecord
existing: ColorRecord | None
message: str
class color_tools.exporters.UserColorExportPlan(destination, sidecar, conflict_policy, input_count, user_records, changes, expected_destination_hash, destination_existed)[source]

Bases: object

Immutable dry-run plan for one user-colors.json update.

Parameters:
destination: Path
sidecar: Path
conflict_policy: Literal['error', 'skip', 'replace']
input_count: int
user_records: tuple[ColorRecord, ...]
changes: tuple[UserColorExportChange, ...]
expected_destination_hash: str | None
destination_existed: bool
property conflicts: tuple[UserColorExportChange, ...]

Return unresolved conflicts that prevent applying this plan.

property can_apply: bool

Return whether this plan contains no unresolved conflicts.

property would_write: bool

Return whether applying this plan would change or create the file.

count(action)[source]

Count planned decisions having the requested action.

Return type:

int

Parameters:

action (Literal['added', 'updated', 'unchanged', 'skipped', 'conflict'])

property accepted_count: int

Return additions, updates, and exact unchanged matches.

property skipped_count: int

Return conflicts intentionally retained under the skip policy.

property rejected_count: int

Return unresolved conflicts that prevent application.

class color_tools.exporters.UserColorExportResult(plan, applied, data_written, sidecar_written)[source]

Bases: object

Outcome of explicitly applying a user-color export plan.

Parameters:
plan: UserColorExportPlan
applied: bool
data_written: bool
sidecar_written: bool
class color_tools.exporters.UserFilamentsExporter(data_dir=None)[source]

Bases: object

Plan and explicitly apply ID-based user-filaments.json updates.

Stable filament IDs are the sole replacement key. Equal descriptive fields or RGB values under different IDs remain distinct filament products. plan() never writes; apply() validates the prospective catalog, rejects stale plans, atomically replaces the user file, and refreshes its SHA-256 sidecar.

Parameters:

data_dir (Path | str | None)

property destination: Path

Return the managed user-filaments.json path.

plan(data, *, conflict_policy='error')[source]

Build a read-only, ID-based merge plan for filament records.

Return type:

UserFilamentExportPlan

Parameters:
apply(plan)[source]

Apply a reviewed plan after stale-state and catalog validation.

Return type:

UserFilamentExportResult

Parameters:

plan (UserFilamentExportPlan)

class color_tools.exporters.UserFilamentExportChange(action, incoming, existing=None, message='')[source]

Bases: object

One ID-based decision made while planning a filament update.

Parameters:
action: Literal['added', 'updated', 'unchanged', 'skipped', 'conflict']
incoming: FilamentRecord
existing: FilamentRecord | None
message: str
class color_tools.exporters.UserFilamentExportPlan(destination, sidecar, conflict_policy, input_count, user_records, changes, warnings, expected_destination_hash, destination_existed)[source]

Bases: object

Immutable dry-run plan for one user-filaments.json update.

Parameters:
destination: Path
sidecar: Path
conflict_policy: Literal['error', 'skip', 'replace']
input_count: int
user_records: tuple[FilamentRecord, ...]
changes: tuple[UserFilamentExportChange, ...]
warnings: tuple[str, ...]
expected_destination_hash: str | None
destination_existed: bool
property conflicts: tuple[UserFilamentExportChange, ...]

Return unresolved same-ID conflicts that prevent application.

property can_apply: bool

Return whether this plan contains no unresolved conflicts.

property would_write: bool

Return whether applying this plan would change or create the file.

count(action)[source]

Count planned decisions having the requested action.

Return type:

int

Parameters:

action (Literal['added', 'updated', 'unchanged', 'skipped', 'conflict'])

property accepted_count: int

Return additions, updates, and exact unchanged matches.

property skipped_count: int

Return same-ID conflicts retained under the skip policy.

property rejected_count: int

Return unresolved same-ID conflicts that prevent application.

class color_tools.exporters.UserFilamentExportResult(plan, applied, data_written, sidecar_written)[source]

Bases: object

Outcome of explicitly applying a user-filament export plan.

Parameters:
plan: UserFilamentExportPlan
applied: bool
data_written: bool
sidecar_written: bool
class color_tools.exporters.OwnedFilamentsExporter(data_dir=None)[source]

Bases: object

Plan and apply additive ownership changes against the merged catalog.

This state-aware exporter writes only owned-filaments.json. It never creates or changes filament records, never removes existing ownership, and never writes a sidecar. plan() is read-only; apply() must be called explicitly after every selected ID resolves in the effective system-plus-user catalog.

Parameters:

data_dir (Path | str | None)

property destination: Path

Return the managed owned-filaments.json path.

plan(data)[source]

Build a read-only additive ownership plan.

FilamentExportData uses its metadata’s final owned_filament_ids. A direct iterable supports callers that already have Color Tools IDs. External identifiers must be reconciled before reaching this operation.

Return type:

OwnedFilamentExportPlan

Parameters:

data (FilamentExportData | Iterable[object])

apply(plan)[source]

Apply a reviewed plan after stale-state and catalog validation.

Return type:

OwnedFilamentExportResult

Parameters:

plan (OwnedFilamentExportPlan)

class color_tools.exporters.OwnedFilamentExportChange(action, filament_id, record=None, message='')[source]

Bases: object

One ownership-selection decision for a final Color Tools ID.

Parameters:
action: Literal['added', 'already_owned', 'unknown']
filament_id: str
record: FilamentRecord | None
message: str
class color_tools.exporters.OwnedFilamentExportPlan(destination, input_count, owned_filament_ids, changes, expected_destination_hash, destination_existed)[source]

Bases: object

Read-only additive plan for one owned-filaments.json update.

Parameters:
destination: Path
input_count: int
owned_filament_ids: tuple[str, ...]
changes: tuple[OwnedFilamentExportChange, ...]
expected_destination_hash: str | None
destination_existed: bool
property unmatched: tuple[OwnedFilamentExportChange, ...]

Return unknown IDs that prevent application.

property can_apply: bool

Return whether every selected ID exists in the effective catalog.

property would_write: bool

Return whether applying would add at least one ownership ID.

count(action)[source]

Count planned decisions having the requested action.

Return type:

int

Parameters:

action (Literal['added', 'already_owned', 'unknown'])

property accepted_count: int

Return selected IDs that are new or already owned.

property rejected_count: int

Return selected IDs absent from the effective catalog.

class color_tools.exporters.OwnedFilamentExportResult(plan, applied, data_written)[source]

Bases: object

Outcome of explicitly applying an owned-filament export plan.

Parameters:
plan: OwnedFilamentExportPlan
applied: bool
data_written: bool