color_tools.palette
Color palette management with fast lookup.
This module provides: 1. Data class for colors (ColorRecord) 2. Functions to load color data from JSON with user override support 3. Palette class with multiple indices for O(1) lookups 4. Nearest-color search using various distance metrics
For filament management, see color_tools.filament_palette module.
The Palette class is like a database with multiple indexes - you can search by name, RGB, HSL, etc. and get instant results!
User files (user/user-colors.json) always override core data when there are conflicts. Override information is logged for transparency.
Example
>>> from color_tools import Palette
>>>
>>> # Load CSS color database
>>> palette = Palette.load_default()
>>> print(f"Loaded {len(palette.colors)} CSS colors")
Loaded 148 CSS colors
>>>
>>> # Find exact color by name
>>> coral = palette.get_by_name("coral")
>>> print(f"Coral: RGB{coral.rgb} (#{coral.hex})")
Coral: RGB(255, 127, 80) (#FF7F50)
>>>
>>> # Find nearest color to custom RGB
>>> custom_orange = (255, 140, 60)
>>> nearest, distance = palette.nearest_color(custom_orange)
>>> print(f"Nearest to RGB{custom_orange}: {nearest.name} (ΔE: {distance:.1f})")
Nearest to RGB(255, 140, 60): darkorange (ΔE: 7.2)
- class color_tools.palette.ColorRecord(name, hex, rgb, hsl, lab, lch, source='colors.json')[source]
Bases:
objectImmutable record representing a named CSS color with precomputed color space values.
This dataclass is frozen (immutable) - once created, you can’t change it. This is perfect for colors: a color IS what it IS! 🎨
All color space values are precomputed and stored for fast access without conversion overhead. The source field tracks which JSON file provided this color, enabling user override detection and debugging.
- Variables:
name – Color name (e.g., “coral”, “lightblue”, “darkslategray”)
hex – Hex color code with # prefix (e.g., “#FF7F50”)
rgb – RGB color tuple with values 0-255 (e.g., (255, 127, 80))
hsl – HSL color tuple (H: 0-360°, S: 0-100%, L: 0-100%)
lab – CIE LAB color tuple (L: 0-100, a: ~-128 to +127, b: ~-128 to +127)
lch – CIE LCH color tuple (L: 0-100, C: 0-100+, H: 0-360°)
source – JSON filename where this record originated (default: “colors.json”)
- Parameters:
Example
>>> from color_tools import Palette >>> palette = Palette.load_default() >>> color = palette.get_by_name("coral") >>> print(f"{color.name}: RGB{color.rgb}") coral: RGB(255, 127, 80) >>> print(f"LAB: {color.lab}") LAB: (67.29, 44.61, 49.72)
- color_tools.palette.load_colors(json_path=None)[source]
Load CSS color database from JSON files (core + user additions).
Loads colors from both the core colors.json file and optional user/user-colors.json file in the data directory. Core colors are loaded first, followed by user colors.
- color_tools.palette.load_palette(name, json_path=None)[source]
Load a named retro palette from the palettes directory.
Palettes are loaded from: 1. User palettes: data/user/palettes/{name}.json (if exists) 2. Core palettes: data/palettes/{name}.json (built-in)
User palettes override core palettes with the same name.
Common built-in palettes include: - cga4: CGA 4-color palette (Palette 1, high intensity) - classic gaming! - cga16: CGA 16-color palette (full RGBI) - ega16: EGA 16-color palette (standard/default) - ega64: EGA 64-color palette (full 6-bit RGB) - vga: VGA 256-color palette (Mode 13h) - web: Web-safe 216-color palette (6x6x6 RGB cube) - gameboy: Game Boy 4-shade green palette
- Parameters:
- Return type:
- Returns:
Palette object loaded from the specified palette file
- Raises:
FileNotFoundError – If the palette file doesn’t exist
ValueError – If the palette file is malformed or contains invalid data
Example
>>> cga = load_palette("cga4") >>> color, dist = cga.nearest_color((128, 64, 200)) >>> print(f"Nearest CGA color: {color.name}")
>>> # Load custom user palette >>> custom = load_palette("my_custom_palette") >>> print(f"Loaded {len(custom.records)} colors from user palette")
- class color_tools.palette.Palette(records)[source]
Bases:
objectCSS color palette with multiple indexing strategies for fast lookup.
Think of this as a database with multiple indexes. Want to find a color by name? O(1). By RGB? O(1). By LAB? O(1). The tradeoff is memory - we keep multiple dictionaries pointing to the same ColorRecords.
For a palette with ~150 CSS colors, this is totally fine! 🚀
- Parameters:
records (List[ColorRecord])
- classmethod load_default()[source]
Load the default CSS color palette from the package data.
This is a convenience method so you don’t have to worry about file paths - just call Palette.load_default() and go!
- Return type:
- find_by_name(name)[source]
Find color by exact name match (case-insensitive).
- Return type:
- Parameters:
name (str)
- nearest_color(value, space='lab', metric='de2000', *, cmc_l=2.0, cmc_c=1.0)[source]
Find nearest color by space/metric.
This is the main search function! It iterates through all colors and finds the one with minimum distance in the specified space.
- Parameters:
value (
Tuple[float,float,float]) – Color in the specified space (RGB, HSL, LAB, or LCH)space (
str) – Color space - ‘rgb’, ‘hsl’, ‘lab’, or ‘lch’ (default: ‘lab’)metric (
str) – Distance metric - ‘euclidean’, ‘de76’, ‘de94’, ‘de2000’, ‘cmc’cmc_l (
float) – Parameters for CMC metric (default 2:1 for acceptability)cmc_c (
float) – Parameters for CMC metric (default 2:1 for acceptability)
- Return type:
- Returns:
(nearest_color_record, distance) tuple
- nearest_colors(value, space='lab', metric='de2000', count=5, *, cmc_l=2.0, cmc_c=1.0)[source]
Find the nearest N colors by space/metric.
Similar to nearest_color but returns multiple results sorted by distance.
- Parameters:
value (
Tuple[float,float,float]) – Color in the specified space (RGB, HSL, LAB, or LCH)space (
str) – Color space - ‘rgb’, ‘hsl’, ‘lab’, or ‘lch’ (default: ‘lab’)metric (
str) – Distance metric - ‘euclidean’, ‘de76’, ‘de94’, ‘de2000’, ‘cmc’count (
int) – Number of results to return (default: 5, max: 50)cmc_l (
float) – Parameters for CMC metric (default 2:1 for acceptability)cmc_c (
float) – Parameters for CMC metric (default 2:1 for acceptability)
- Return type:
- Returns:
List of (color_record, distance) tuples sorted by distance (closest first)