Skip to main content

nutq

Script conversion and text normalization for Tajik, Persian, Dari and Uzbek — in pure Python, with no dependencies.

nutq (нутқ · نطق · nutq) means "speech" in all three languages.

More than 150 million people speak these languages, and many of them write them in more than one script. Text-to-speech systems, chat bots, search engines and language models need the same text in a consistent form and the numbers spelled out, and there is little open tooling for that. nutq gives you one small, tested API for both jobs, and other languages can be added as plugins.

Tajik tg Persian fa Dari fa-AF Uzbek uz
Scripts Cyrillic · Latin · Perso-Arabic Perso-Arabic Perso-Arabic Latin · Cyrillic
Script conversion Cyrl ↔ Latn, Cyrl → Arab, Arab → Cyrl (experimental) via tg via tg Cyrl ↔ Latn
Numbers → words cardinal, ordinal cardinal, ordinal cardinal, ordinal cardinal, ordinal
Normalization for speech numbers, decimals, %, money, dates, times, phone and version numbers, °C, abbreviations + Solar Hijri dates + Afghan month names Latin and Cyrillic
Character cleanup look-alike letters ي/ك → ی/ک, digits, ZWNJ same as fa apostrophes oʻ gʻ ʼ

Status: beta. Each rule is tested, but native speakers still need to review many of them. See Linguistic review.

Install

pip install nutq

(Not yet published. Until then: pip install -e . from a clone.)

Usage

import nutq

# Script conversion
nutq.convert("Забони тоҷикӣ", "tg", to="Arab")      # 'زبان تاجیکی'
nutq.convert("Тоҷикистон", "tg", to="Latn")          # 'Tojikiston'
nutq.convert("Ўзбекистон", "uz", to="Latn")          # 'Oʻzbekiston'
nutq.convert("O'zbekiston", "uz", to="Cyrl")         # 'Ўзбекистон'

# Numbers to words
nutq.number_to_words(2026, "tg")                     # 'ду ҳазору бисту шаш'
nutq.number_to_words(2026, "fa")                     # 'دو هزار و بیست و شش'
nutq.number_to_words(3, "uz", ordinal=True)          # 'uchinchi'
nutq.number_to_words(4, "uz", script="Cyrl", ordinal=True)  # 'тўртинчи'

# Normalization for TTS and language models
nutq.normalize("Нархи 25 $ аст, 12.03.2026", "tg")
# 'Нархи бисту панҷ доллар аст, дувоздаҳуми марти соли ду ҳазору бисту шаш'
nutq.normalize("۱۴۰۵/۰۱/۱۲، ۱۵٪", "fa")
# 'دوازدهم فروردین هزار و چهارصد و پنج، پانزده درصد'
nutq.normalize("2026-yil 12-mart, 2,5 kg", "uz")
# 'ikki ming yigirma oltinchi yil oʻn ikkinchi mart, ikki butun oʻndan besh kilogramm'

# Character cleanup only
nutq.clean("Тoҷик", "tg")      # 'Тоҷик'  (the "o" was Latin)
nutq.clean("كتابي", "fa")       # 'کتابی'

Language codes follow BCP-47 / ISO 639 (tg, fa, fa-AF, prs, uz, ...). Scripts are ISO 15924 codes (Cyrl, Latn, Arab) or names ("latin"). If you don't pass source=, convert detects the source script.

Command line

nutq convert --lang tg --to Arab "Забони тоҷикӣ"
nutq normalize --lang uz "Narxi 25 $, 15% chegirma"
nutq number --lang fa --ordinal 23
echo "O'zbekiston" | nutq convert -l uz -t Cyrl
nutq languages

How Tajik → Perso-Arabic works

Tajik Cyrillic writes every vowel. Persian script leaves out short vowels and has several letters for one sound (с = س ص ث). A rule-only converter therefore cannot be exact. nutq works in three steps:

  1. Word list — lang/tg/data/arabic_words.tsv holds the spellings rules can't guess (китоб → کتاب, илм → علم).
  2. Suffixes and stems — plural -ҳо/-ён, object -ро → را, izafat -и, comparative -тар/-тарин, the linking -у → و, verb prefixes ме-/наме- → می‌/نمی‌, and stems like хонд → خواند, кун → کن.
  3. Letter rules for everything else. They are correct for many common words (нон → نان, Самарқанд → سمرقند).

Arabic → Cyrillic is experimental. Without a dictionary, an unvowelled word can only be read approximately.

Adding a language

Each language is one folder under src/nutq/lang/. It registers a Language object, and third-party packages can add languages through an entry point without changing nutq. See CONTRIBUTING.md. Kazakh, Turkmen, Azerbaijani, Serbian and Kurdish are next on the roadmap, and we are looking for native speakers to help.

Linguistic review

Some forms are our best guess and still need a native editor to confirm them. Each one is marked verify in the source:

  • Tajik: decimals (ду бутуну панҷ даҳум) and the Perso-Arabic word list. Dates and times were confirmed by a native speaker.
  • Persian / Dari: ممیز vs اعشاریه, درصد vs فیصد, Afghan spellings of Gregorian months, یکم vs اول.
  • Uzbek: all forms. Open questions: yuz vs bir yuz, ming vs bir ming, time and date reading, and ts → ц in Latin → Cyrillic.

If you find a mistake, please open an issue with the correct form. Issues may be written in English, Tajik, Persian, Uzbek or Russian.

Development

pip install -e .
python -m unittest discover -s tests

Python 3.9+ and no dependencies.


Бо забони тоҷикӣ

nutq (нутқ) — китобхонаи кушода (open source) барои забонҳои тоҷикӣ, форсӣ, дарӣ ва ӯзбекӣ. Он ду кор мекунад:

  1. Табдили хат: тоҷикии кириллӣ ↔ лотинӣ ↔ хати форсӣ (Perso-Arabic), ӯзбекии кириллӣ ↔ лотинӣ.
  2. Тайёр кардани матн барои нутқ (TTS) ва зеҳни сунъӣ: рақамҳо, санаҳо, вақт, пул, фоиз ва ихтисораҳо бо калима навишта мешаванд. Масалан, «25 $» → «бисту панҷ доллар».
import nutq
nutq.convert("Забони тоҷикӣ", "tg", to="Arab")   # 'زبان تاجیکی'
nutq.normalize("Соати 14:30, 15% тахфиф", "tg")
# 'Соати чордаҳу сӣ, понздаҳ фоиз тахфиф'

Ҳар кас метавонад онро бепул истифода барад ва дар рушди он саҳм гузорад. Агар хатое ёбед, масалан калимае, ки бо хати форсӣ нодуруст навишта шудааст, лутфан дар GitHub issue кушоед ё калимаро ба файли arabic_words.tsv илова кунед. Ба забондонҳои ӯзбек, қазоқ, туркман, озарӣ, серб ва курд барои илова кардани забонҳои нав ниёз дорем.

License

MIT

Metadata

Release files for nutq 0.1.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for nutq 0.1.0
File Size Uploaded Provenance Actions
nutq-0.1.0.tar.gz 39.7 kB With provenance Details for nutq-0.1.0.tar.gz

Built distribution (wheel)

Table of built distributions (wheels) for nutq 0.1.0
File Interpreter ABI Platform Actions
nutq-0.1.0-py3-none-any.whl Python 3 none any Details for nutq-0.1.0-py3-none-any.whl

Total release size: 77.8 kB

Release files / nutq-0.1.0.tar.gz

Download URL nutq-0.1.0.tar.gz
Size 39.7 kB
Tags Source
SHA-256 checksum
How to use checksums
aab65a36a6317e4e07abec1f04f539bcae977075d7a2a642b54ea9a1f090133e
BLAKE2b-256 checksum
How to use checksums
ab652b4667018b6c9f7f864e0227111fc11e1c9988fb9e6bc8c930692f24e7e5
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.16

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 30, 2026.

Transparency log

Release files / nutq-0.1.0-py3-none-any.whl

Download URL nutq-0.1.0-py3-none-any.whl
Size 38.1 kB
Tags Python 3
SHA-256 checksum
How to use checksums
02dcc9f3083637b4450c3a6b1a672338bc9d55ae942c46228ebdd484b5d106a5
BLAKE2b-256 checksum
How to use checksums
1188b99b385ec992051137bcf2915002ba1ad78af397e9447366e0dfcd7d51af
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.16

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 30, 2026.

Transparency log

Security for nutq 0.1.0

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

Full provenance

All 2 files in this release have been uploaded with provenance metadata.

Select from 2 files

Attestation for nutq-0.1.0.tar.gz

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 30, 2026.

Transparency log

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Release history Release notifications | RSS feed

This release

0.1.0 This release

2 release files Full provenance

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page