Skip to main content

indic-itn (v0.2.4)

Inverse Text Normalization (ITN) for Multilingual Indian Languages (Hindi, Tamil, Telugu, Kannada, etc.).

indic-itn converts spoken-form ASR (Automatic Speech Recognition) transcriptions into normalized written representations across phone numbers, numbers, dates, times, currency, decimals, percentages, ordinals, and OTPs while strictly preserving all surrounding context words and punctuation.


Architectural Highlights & Guarantees

  • Zero Context Deletion: Operating on span-based substitutions (text[:start] + normalized_span + text[end:]), ensuring surrounding text before and after numeric expressions is never lost or corrupted.
  • Language Plugin Architecture: Decouples core normalization engine logic from language-specific vocabulary. Adding a new language (e.g. Malayalam ml) requires creating a language plugin directory without touching the core engine.
  • Specialized Phone Number Entity: Phone numbers are processed as unformatted digit sequences (9876543210), supporting spoken native/English digits, repeated digit phrases (double/triple), optional country codes (+91), plus, and zero.
  • Deterministic Entity Priority Resolution: Candidate spans are classified and resolved in strict priority order (URL > Email > Phone > OTP > Date > Time > Currency > Decimal > Percentage > Ordinal > Number) to prevent overlapping span corruption.
  • Code-Switching Support: Seamlessly handles mixed Indic script and English spoken digit expressions (e.g. "mera phone number hai nine eight seven six...").
  • 100% Backward Compatibility: Full support for legacy entry points (HindiITN, TeluguITN, KannadaITN, TamilITN, IndicITN, Token, Entity, load_resource).

Architecture Overview

Raw ASR Spoken Text
      │
      ▼
indic_itn.core.tokenizer (IndicTokenizer)
      │
      ▼
indic_itn.core.entity_detector (Span candidate detection & priority resolution)
      ├── Phone Entity Handler
      ├── Date Entity Handler
      ├── Time Entity Handler
      ├── Currency Entity Handler
      ├── Decimal Entity Handler
      ├── Percentage Entity Handler
      ├── Ordinal Entity Handler
      ├── OTP Entity Handler
      └── General Number Entity Handler
      │
      ▼
indic_itn.languages.<lang> (Language Lexical Parser & Semantic Mapper)
      │
      ▼
indic_itn.entities.<entity> (Canonical Renderer)
      │
      ▼
indic_itn.core.span_replacer (Right-to-Left Safe Substring Replacer)
      │
      ▼
indic_itn.normalization.postprocess (Whitespace & Punctuation Cleanup)
      │
      ▼
Final Normalized Written Text

Installation

pip install indic-itn

Or install locally in editable mode for development:

pip install -e ".[dev]"

Usage

1. Functional API (normalize_text)

from indic_itn import normalize_text

# Phone number with surrounding words
print(normalize_text("call me on nine eight seven six five four three two one zero tomorrow", language="hi"))
# Output: "call me on 9876543210 tomorrow"

# Currency
print(normalize_text("I have five hundred rupees in my account", language="hi"))
# Output: "I have 500 rupees in my account"

# Time & Date
print(normalize_text("meeting is at five thirty pm", language="hi"))
# Output: "meeting is at 5:30 pm"

2. Object-Oriented Orchestrators

from indic_itn import HindiITN, TamilITN, TeluguITN, KannadaITN

# Hindi
hi = HindiITN()
print(hi.normalize("मेरा नंबर नौ आठ सात छह पाँच चार तीन दो एक शून्य है"))
# Output: "मेरा नंबर 9876543210 है"

# Tamil
ta = TamilITN()
print(ta.normalize("என் போன் நம்பர் ஒன்பது எட்டு ஏழு ஆறு ஐந்து நான்கு மூன்று இரண்டு ஒன்று பூஜ்யம்"))
# Output: "என் போன் நம்பர் 9876543210"

# Telugu
te = TeluguITN()
print(te.normalize("నా ఫోన్ నంబర్ తొమ్మిది ఎనిమిది ఏడు ఆరు ఐదు నాలుగు మూడు రెండు ఒకటి సున్నా ఉంది"))
# Output: "నా ఫోన్ నంబర్ 9876543210 ఉంది"

# Kannada
kn = KannadaITN()
print(kn.normalize("ನನ್ನ ಬಳಿ ಐದು ನೂರು ರೂಪಾಯಿ ಇದೆ"))
# Output: "ನನ್ನ ಬಳಿ ₹500 ಇದೆ"

3. Debug & Entity Metadata Mode

from indic_itn import IndicITNEngine

engine = IndicITNEngine(lang="hi")
debug_info = engine.normalize("call nine eight seven six five four three two one zero at five pm", return_entities=True)

print(debug_info)
# Output:
# {
#   "original_text": "call nine eight seven six five four three two one zero at five pm",
#   "normalized_text": "call 9876543210 at 5:00 pm",
#   "detected_spans": [
#     {"start": 5, "end": 53, "original": "nine eight...", "normalized": "9876543210", "entity_type": "phone"},
#     {"start": 57, "end": 64, "original": "five pm", "normalized": "5:00 pm", "entity_type": "time"}
#   ]
# }

How to Add a New Language

Adding support for a 5th Indian language (e.g. Malayalam ml) requires zero modifications to the core engine:

Step 1: Create Resource Directory

Add JSON files in src/indic_itn/resources/ml/:

  • numbers.json (digits, numbers, tens, hundreds, multipliers)
  • keywords.json (script_range, script_digits, currency, time, phone, otp, decimal, percentage)
  • temporal.json (months, date_words, weekdays)
  • ordinals.json (ordinal words mapping)

Step 2: Implement Language Plugin Class

Create src/indic_itn/languages/malayalam/normalizer.py:

from indic_itn.languages.base import BaseLanguage

class MalayalamLanguage(BaseLanguage):
    def __init__(self) -> None:
        super().__init__(lang_code="ml")

Step 3: Register Language

Register the language plugin dynamically or in default registry:

from indic_itn import register_language, normalize_text
from indic_itn.languages.malayalam.normalizer import MalayalamLanguage

register_language("ml", MalayalamLanguage)

# Use immediately
print(normalize_text("spoken text in malayalam", language="ml"))

How to Add a New Entity Type

  1. Create a handler class in src/indic_itn/entities/my_entity.py inheriting from BaseEntityHandler.
  2. Implement entity_type property and parse(span, lang) method.
  3. Register handler in IndicITNEngine.entity_handlers.

Quality Metrics & Benchmark Dataset

indic-itn includes an extensive 400-example benchmark test dataset (tests/fixtures/benchmark_dataset.json) covering 100 test samples each for Hindi, Tamil, Telugu, and Kannada across numbers, phone numbers, dates, times, currency, decimals, percentages, and mixed language contexts.

Metric Target Benchmark Score
Final Normalization Accuracy >= 98.0% 100.00% (400/400)
Context Preservation Accuracy 100.0% 100.00% (400/400)
Entity Detection Accuracy >= 98.0% 100.00% (400/400)

Running Benchmark Suite

pytest tests/benchmark/test_benchmark.py -s

Testing & Quality Assurance

Running Full Test Suite

pytest --cov=indic_itn --cov-report=term-missing

Running Static Type Checker & Linter

mypy src
ruff check src tests

Release files for indic-itn 0.2.7

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

Source distribution (sdist)

Source distribution for indic-itn 0.2.7
File Size Uploaded
indic_itn-0.2.7.tar.gz 93.0 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for indic-itn 0.2.7
File Interpreter ABI Platform
indic_itn-0.2.7-py3-none-any.whl Python 3 none any Details

Total release size: 192.3 kB

Release files / indic_itn-0.2.7.tar.gz

Download URL indic_itn-0.2.7.tar.gz
Size 93.0 kB
Tags Source
SHA-256 checksum
How to use checksums
766d4197265b2aaef35d6e3d38f9438bff71309f0c7907023f93f3fe9426faad
BLAKE2b-256 checksum
How to use checksums
64600895b8a60ee98e57f3842aec539c1b23f1b303b32a000da27057146aa6a3
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.11.5

Release files / indic_itn-0.2.7-py3-none-any.whl

Download URL indic_itn-0.2.7-py3-none-any.whl
Size 99.3 kB
Tags Python 3
SHA-256 checksum
How to use checksums
4000cd6ddc3b41b49eb1b7f3b1c505504695a1a5e84863cdc49da07036ad59f9
BLAKE2b-256 checksum
How to use checksums
2e0022c85cabe83a02ff6d037b4ce6514ba0f0a2d1e9e85ef3b6174a8c4c7383
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.11.5

Release history Release notifications | RSS feed

0.2.10

2 release files

0.2.9

2 release files

0.2.8

2 release files

This release

0.2.7 This release

2 release files

0.2.6

2 release files

0.2.5

2 release files

0.2.4

2 release files

0.2.3

2 release files

0.2.2

2 release files

0.2.1

2 release files

0.2.0

2 release files

0.1.0

2 release files

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