Extending and integrating
September 1, 2026 · View on GitHub
This page covers using the library outside a voice assistant, tuning the matcher, adding a language, and shipping your own wordlists.
Exact vs. fuzzy matching
color_from_description(..., fuzzy=True) (the default) is forgiving: it tolerates typos and loose
phrasing, which is what a spoken or typed request usually needs. The trade-off is that short filler
words can incidentally match a color name.
For entity extraction over arbitrary prose, pass fuzzy=False. Matching then requires a color name
to appear as a substring, so words like "the", "door" or "keep" resolve to None and only genuine
color phrases survive. examples/ner_colors.py builds a span extractor
on top of this.
from ovos_color_parser import color_from_description
color_from_description("keep the door shut", fuzzy=True) # may match something
color_from_description("keep", fuzzy=False) # None
color_from_description("navy blue", fuzzy=False).hex_str # '#0B32B4'
Reusing the bundled modifier wordlists
Locales with a color_descriptors.json ship saturation/brightness/temperature/opacity adjectives.
You can read them to detect modifier words in your own text processing:
from ovos_color_parser.matching import _get_color_adjectives
adjectives = _get_color_adjectives("en") # {"low_brightness": ["dark", ...], ...}
modifiers = {w.lower() for group in adjectives.values() for w in group}
"dark" in modifiers # True
Standalone vs. OVOS
Nothing in the package imports OVOS, so the same call works in a script or a skill — only the input plumbing differs.
# standalone
from ovos_color_parser import color_from_description
hex_str = color_from_description("moss green", lang="en").hex_str
# inside a skill handler
def handle_set_color(self, message):
color = color_from_description(message.data["utterance"], lang=self.lang)
if color:
self.set_lamp(color.hex_str)
Because lang is just a BCP-47 tag, wiring the library into any framework is a matter of passing
that framework's active language through.
Custom wordlists at runtime
Wordlists are plain {"#RRGGBB": "name"} JSON. To parse against your own palette, add a locale
directory (see below) or reuse the models directly:
from ovos_color_parser import sRGBAColor, closest_color
brand = {"#0A66C2": "Brand Blue", "#F5A623": "Brand Amber", "#2E2E2E": "Brand Ink"}
palette = [sRGBAColor.from_hex_str(h, name=n) for h, n in brand.items()]
picked = closest_color(sRGBAColor.from_hex_str("#0B5FB0"), palette)
print(picked.name) # 'Brand Blue'
Adding a language
- Create
ovos_color_parser/res/<lang>-<REGION>/colors.jsonwith{"#RRGGBB": "name", ...}. - Optionally add more wordlist files (any
*.jsonwith the same shape) — they are all merged. - Optionally add
color_descriptors.json(copy the key structure fromen-US) to enable light/dark/vivid/warm/transparent modifiers, andobject_colors.jsonfor prototypical object colors ("carrot", "banana"). - Add anchor words for the language to
test/test_languages.py.
A requested tag resolves to the closest bundled locale: exact case-insensitive tag first, then any locale sharing the primary language subtag. See languages.md for the current locale list and per-language vocabulary notes.