This release is a pre-release and may not be stable for production use.
ovos-lang-parser
Map spoken and written language names to standard IETF/BCP-47 language codes, and back, in many languages, offline, with a two-function API.
"Brazilian Portuguese" -> "pt-br"
"alemão" (Portuguese) -> "de"
"pt-br" -> "Português do Brasil" (rendered in Portuguese)
"pt-br" -> "Brazilian Portuguese" (rendered in English)
The library understands language names written in 21 languages (see
Coverage). A user can say "French" in English, "français" in French, or
"Französisch" in German, and each resolves to the code fr. This is the piece you need
whenever a human names a language in free text and your code needs a canonical code to act
on: routing to a translation/TTS/STT engine, tagging an entity, or normalizing a messy
label.
It ships as part of OpenVoiceOS, but has no OVOS runtime dependency and is useful in any plain-Python project.
Install
pip install ovos-lang-parser
# or
uv add ovos-lang-parser
Runtime dependencies are small: langcodes for tag
normalization and ovos-utils for the fuzzy matcher. There are no models and no network
calls: the wordlists are bundled.
30-second quickstart
from ovos_lang_parser import extract_langcode, pronounce_lang
# name -> code (second arg is the language the text is written in)
print(extract_langcode("Brazilian Portuguese", "en")) # -> ('pt-br', 1.0)
print(extract_langcode("translate this to German", "en")) # -> ('de', 1.0)
# code -> name, rendered in a chosen language
print(pronounce_lang("de", "en")) # -> German
print(pronounce_lang("de", "pt")) # -> Alemão
That is the whole surface for most callers: extract_langcode reads a name out of text and
returns (code, confidence). pronounce_lang turns a code back into a human name.
The API in one screen
| Function | Purpose | Returns |
|---|---|---|
extract_langcode(text, lang) |
Find the language named in text (written in lang) |
(langcode, confidence). Confidence is 0.0 to 1.0, and an exact name match is 1.0 |
pronounce_lang(langcode, lang) |
Human name of langcode, rendered in lang |
str (falls back to the base tag, then to langcode unchanged) |
get_lang_data(lang) |
The full {name: code} table for lang |
dict[str, str] |
LANGS |
Codes of the languages a name can be written in | list[str] |
In both functions lang is the language the names are written in, not the language being
named. extract_langcode("français", "fr") and extract_langcode("French", "en") both give
fr. See docs/api.md for full signatures, the confidence model, and edge
behavior.
Use it outside OVOS
The same two functions cover a range of standalone jobs. Each example below is a runnable
script under examples/: run pip install ovos-lang-parser, then run the script.
No OVOS stack is required.
Entity extraction / NER: pull a language out of free text
You have a sentence and want to know which language it mentions.
from ovos_lang_parser import extract_langcode
for text in ["translate this to Brazilian Portuguese",
"can you say it in Mandarin Chinese?",
"I'd like the subtitles in Greek"]:
code, conf = extract_langcode(text, "en")
if conf >= 0.7:
print(f"{text!r} -> {code} ({conf:.2f})")
Because matching is fuzzy, apply a confidence threshold to decide whether a language was
really mentioned. Full script:
examples/ner_language_mentions.py.
Routing: pick a translation / TTS / STT engine by name
A user names a target language. You resolve it to a code and hand that to whatever engine your pipeline drives.
from ovos_lang_parser import extract_langcode
def resolve_target(user_request, spoken_in="en"):
code, conf = extract_langcode(user_request, spoken_in)
return code if conf >= 0.7 else None
print(resolve_target("read it back to me in German")) # -> de (feed to your TTS)
Full script (with a mock engine table): examples/routing.py.
Normalization: canonicalize messy names and autonyms to one code
Aliases, autonyms, and localized spellings all collapse to a single canonical code, so you can deduplicate and standardize labels regardless of how they were written.
from ovos_lang_parser import extract_langcode
labels = [("Deutsch", "de"), ("alemão", "pt"), ("German", "en"), ("allemand", "fr")]
for name, written_in in labels:
code, _ = extract_langcode(name, written_in)
print(f"{name:>10} -> {code}") # all -> de
Full script: examples/normalization.py.
In an OVOS skill vs. standalone
The API is identical. Only where you get text and lang differs.
# Standalone language-routing utility
code, conf = extract_langcode(user_input, "en")
# Inside an OVOS skill, the utterance and its language come from the session
class MySkill(OVOSSkill):
def handle_translate(self, message):
utterance = message.data["utterance"]
code, conf = extract_langcode(utterance, self.lang)
...
Coverage
Names can be written in 21 languages. Each carries a table of a few hundred target languages keyed by ISO 639 code.
an Aragonese |
ar Arabic |
ast Asturian |
bg Bulgarian |
ca Catalan |
da Danish |
de German |
en English |
es Spanish |
eu Basque |
fr French |
fy Frisian |
gl Galician |
hr Croatian |
it Italian |
kab Kabyle |
nl Dutch |
oc Occitan |
pt Portuguese |
ro Romanian |
sk Slovak |
The live list is always ovos_lang_parser.LANGS. Adding a language means dropping in one
JSON file. See docs/coverage.md and docs/extending.md.
Documentation
- docs/api.md: full reference, confidence model, edge behavior
- docs/coverage.md: supported languages and the data model
- docs/extending.md: add a language wordlist
- examples/: runnable scripts for each use case
Related projects
- ovos-number-parser: numbers
- ovos-date-parser: dates and times
- ovos-color-parser: colors
License
Apache 2.0. See LICENSE.
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file ovos_lang_parser-0.7.1a4.tar.gz.
File metadata
- Download URL: ovos_lang_parser-0.7.1a4.tar.gz
- Upload date:
- Size: 45.5 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via:
twine/7.0.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
a753ad1b46f63540a00dec3a2a2827a99c383519fbd648ec4cf817578e417bf0
|
|
| MD5 |
8cd64b13320938178163c9d943d94ff4
|
|
| BLAKE2b-256 |
64466165c42e3e78c5431e6ab346312be3cbf690d15ab7263816e6f05a6fa7e6
|
File details
Details for the file ovos_lang_parser-0.7.1a4-py3-none-any.whl.
File metadata
- Download URL: ovos_lang_parser-0.7.1a4-py3-none-any.whl
- Upload date:
- Size: 45.1 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via:
twine/7.0.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
ced37b059da8f5fbc3620539e83e6bf863a56f6d1239a5ff0e904dd994363992
|
|
| MD5 |
e4009712ca12ff3ac6a338064ea5d211
|
|
| BLAKE2b-256 |
e412727f61dccd3c7fd827ddbd0ef316018a2613d907eb623e5c0c01a1e60c27
|