Ukrainian ITN
Fast WFST-based Inverse Text Normalization (ITN) for Ukrainian. The Python package uses a Rust runtime and ships with compiled grammars, so using it does not require Pynini, OpenFST, or a C++ toolchain.
Supported semiotic classes: cardinal, ordinal, decimal, fraction, measure, money, date, time,
telephone, electronic (e-mail/URL), century (Roman numerals), number sign (№), ranges
(numeric/time/date), durations & half-quantities, decades, legal references, scores,
versions, IPv4, postal codes, street addresses.
Also supports high-priority spoken abbreviations and time day-period/time-zone forms.
Punctuation-aware (built for ASR output): "сто гривень, будь ласка!" -> ₴100, будь ласка!,
"нуль шістдесят сім, сто двадцять три, сорок п'ять, шістдесят сім" -> 0671234567
Common Ukrainian apostrophes (', ’, ʼ) and uppercase ASR/text input are accepted
without changing the spelling or case of ordinary words.
Installation
pip install ukrainian_itn
Installing from source also requires a current Rust toolchain. Published wheels include the compiled extension and grammar files.
Usage
from ukrainian_itn import normalize
normalize("це трапилося дві тисячі дев'ятнадцятого числа") # це трапилося 2019-го числа
normalize("мінус п'ять цілих одна десята відсотка") # -5.1 %
normalize("двадцять дві тисячі сто один") # 22101
normalize("сьома година двадцять п'ять хвилин") # 07:25
normalize("МІНУС П’ЯТЬ ГРИВЕНЬ") # -₴5
normalize("третя година дня за київським часом") # 15:00 Europe/Kyiv
normalize("підключи ю ес бі та вай фай") # підключи USB та Wi-Fi
The bundled grammars are loaded lazily on the first call and cached for the lifetime of
the process. normalize is thread-safe.
From command line
echo "це трапилося дві тисячі дев'ятнадцятого числа" | python -m ukrainian_itn
# or, after `pip install ukrainian_itn`:
echo "це трапилося дві тисячі дев'ятнадцятого числа" | ukrainian-itn
Options:
-h, --help Show this help message and exit
-j, --json Return result as JSON
-v, --verbose Print original input and normalized to compare
--version Show version
Will return це трапилося 2019-го числа. Lines the grammar cannot parse are reported to
stderr and skipped (exit code 1).
JSON output
For more advanced usage you can get json output
from ukrainian_itn import normalize
normalize("це трапилося дві тисячі дев'ятнадцятого числа", json=True)
# >>> '[{"word": "це"}, {"word": "трапилося"}, {"ordinal": "2019"}, {"word": "числа"}]'
The returned string is guaranteed to be valid JSON, including when pass-through tokens contain quotes, backslashes, control characters, or non-BMP Unicode.
Rust runtime
The reusable crate uses rustfst and can be embedded in another Rust application without Python or PyO3 at runtime. To regenerate/export grammars, install the optional grammar tooling first:
pip install "ukrainian_itn[grammar]"
python -m ukrainian_itn.export grammars_export
cargo test
cargo build --release
echo "двадцять дві тисячі сто один" | ./target/release/ukrainian_itn_cli # 22101
The reusable crate lives under crates/ukrainian-itn. Its default feature set is
PyO3-free, so another Rust application can depend on it directly:
[dependencies]
ukrainian-itn = { path = "../itn-uk/crates/ukrainian-itn" }
use ukrainian_itn::InverseNormalizer;
let normalizer = InverseNormalizer::new()?;
assert_eq!(normalizer.normalize("двадцять дві тисячі сто один")?, "22101");
# Ok::<(), anyhow::Error>(())
Python bindings are available behind the optional python Cargo feature. Maturin enables
that feature when building the Python wheel; ordinary Rust builds leave it disabled.
Backend-specific Python types remain internal so the public Python API is
implementation-independent.
Grammar development
Pynini is only used to edit, test, and recompile the grammar definitions. It is not imported by the public Python API and is not an installation dependency. Install it with:
pip install "ukrainian_itn[grammar]"
On platforms without a Pynini wheel, OpenFST development headers may also be needed. The grammar tooling exposes taggers and verbalizers directly. For example:
from ukrainian_itn.wfst import get_normalizer, apply_fst_text
apply_fst_text("мінус п'ять цілих одна десята відсотка", get_normalizer().classify.fst)
This returns tokens { measure { negative: "true" integer_part: "5" fractional_part: "1" units: "%" } }.
Development
uv sync # install the native package and standard test tools
uv sync --extra grammar # additionally install Pynini for grammar work/full tests
uv run pytest # run tests
uv run ruff check . # lint
uv build # build sdist + wheel
Releasing
The release workflow runs when a v* tag is pushed. The tag must match the version in
pyproject.toml, crates/ukrainian-itn/Cargo.toml, and ukrainian_itn/__init__.py:
git tag v0.4.1
git push origin v0.4.1
It builds an sdist and ABI3 wheels for Linux (x86-64 and ARM64), macOS (Intel and Apple
Silicon), and Windows (x86-64), publishes them to PyPI, and attaches them to a GitHub
Release. PyPI trusted publishing must be configured for the RustedBytes/uk-itn
repository, .github/workflows/release.yml workflow, and pypi environment. The
PyPI project name must be ukrainian-itn (the canonical form of the distribution
metadata name ukrainian_itn), not the repository name uk-itn or the legacy
distribution name ukr-itn.
Metadata
Release files for ukrainian-itn 0.4.1
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| ukrainian_itn-0.4.1.tar.gz | 1.1 MB | Details |
Built distributions (wheels)
| File | Reset | |||
|---|---|---|---|---|
| ukrainian_itn-0.4.1-cp39-abi3-win_amd64.whl | CPython 3.9 | abi3 | Windows x86-64 | Details |
| ukrainian_itn-0.4.1-cp39-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl | CPython 3.9 | abi3 | Linux glibc 2.17+ x86-64 | Details |
| ukrainian_itn-0.4.1-cp39-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl | CPython 3.9 | abi3 | Linux glibc 2.17+ ARM64 | Details |
| ukrainian_itn-0.4.1-cp39-abi3-macosx_11_0_arm64.whl | CPython 3.9 | abi3 | macOS 11.0+ ARM64 | Details |
| ukrainian_itn-0.4.1-cp39-abi3-macosx_10_12_x86_64.whl | CPython 3.9 | abi3 | macOS 10.12+ x86-64 | Details |
Total release size: 11.8 MB
Release files / ukrainian_itn-0.4.1.tar.gz
| Download URL | ukrainian_itn-0.4.1.tar.gz |
|---|---|
| Size | 1.1 MB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
1423edfe36a6b57df432ffa98ada6fbcf4a34ba328ce7e33ce99b5dd5060e336
|
|
BLAKE2b-256 checksum How to use checksums |
4066ad1bc8ad06c40a202411724762d659e5f4d6749a1ec7eac9e956c16b78f5
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
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 Sep 21, 2026.
Transparency logRelease files / ukrainian_itn-0.4.1-cp39-abi3-win_amd64.whl
| Download URL | ukrainian_itn-0.4.1-cp39-abi3-win_amd64.whl |
|---|---|
| Size | 2.0 MB |
| Tags | CPython 3.9 Windows x86-64 abi3 |
|
SHA-256 checksum How to use checksums |
b031a1587c334848abe2320bc9116813c1a851a9c9527140fe93e65b870b8b13
|
|
BLAKE2b-256 checksum How to use checksums |
24a3a24e0008a1f455324579552773cea80023b91b191d3614e0bf3d6111c288
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
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 Sep 21, 2026.
Transparency logRelease files / ukrainian_itn-0.4.1-cp39-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
| Download URL | ukrainian_itn-0.4.1-cp39-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl |
|---|---|
| Size | 2.2 MB |
| Tags | CPython 3.9 Linux glibc 2.17+ x86-64 abi3 |
|
SHA-256 checksum How to use checksums |
50fd412242620af37589e5534b7103e44cbb43d82c9b0f741adf655cdcc38af4
|
|
BLAKE2b-256 checksum How to use checksums |
6f44422b63415f0a5e2e131cbe239e47d347806854dfe4625da0e22040d8b072
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
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 Sep 21, 2026.
Transparency logRelease files / ukrainian_itn-0.4.1-cp39-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
| Download URL | ukrainian_itn-0.4.1-cp39-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl |
|---|---|
| Size | 2.2 MB |
| Tags | CPython 3.9 Linux glibc 2.17+ ARM64 abi3 |
|
SHA-256 checksum How to use checksums |
a7f65646f60d9767a0401adb4dd32af3e492a0179384efcb60612e91bbbcaa82
|
|
BLAKE2b-256 checksum How to use checksums |
de8e5ee3463170d7195f758194b9df0bfa4cca926fa6c175ba888a856d92637a
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
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 Sep 21, 2026.
Transparency logRelease files / ukrainian_itn-0.4.1-cp39-abi3-macosx_11_0_arm64.whl
| Download URL | ukrainian_itn-0.4.1-cp39-abi3-macosx_11_0_arm64.whl |
|---|---|
| Size | 2.1 MB |
| Tags | CPython 3.9 abi3 macOS 11.0+ ARM64 |
|
SHA-256 checksum How to use checksums |
2a48dc17dfd51d83be50154f02ef069ce39ff89bc40725aecfca0649fc598641
|
|
BLAKE2b-256 checksum How to use checksums |
25d2d269c0436017ade1f78efbae9c1b4bd79587c096b23f517fa04a8d92a891
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
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 Sep 21, 2026.
Transparency logRelease files / ukrainian_itn-0.4.1-cp39-abi3-macosx_10_12_x86_64.whl
| Download URL | ukrainian_itn-0.4.1-cp39-abi3-macosx_10_12_x86_64.whl |
|---|---|
| Size | 2.1 MB |
| Tags | CPython 3.9 abi3 macOS 10.12+ x86-64 |
|
SHA-256 checksum How to use checksums |
df04ce00c36e0a8fb255f28c69234e98b57bd17a07456a9b82ca82dc2f1cfdaa
|
|
BLAKE2b-256 checksum How to use checksums |
ac20f5795aa8b4c6f56633859579a84ae40bfe1c8ef0be810db4ea1d672c28ae
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
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 Sep 21, 2026.
Transparency log