indic-itn 0.1.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- indic_itn-0.1.0/LICENSE +21 -0
- indic_itn-0.1.0/PKG-INFO +104 -0
- indic_itn-0.1.0/README.md +78 -0
- indic_itn-0.1.0/pyproject.toml +82 -0
- indic_itn-0.1.0/setup.cfg +4 -0
- indic_itn-0.1.0/src/indic_itn/__init__.py +7 -0
- indic_itn-0.1.0/src/indic_itn/base.py +105 -0
- indic_itn-0.1.0/src/indic_itn/detector.py +447 -0
- indic_itn-0.1.0/src/indic_itn/loader.py +21 -0
- indic_itn-0.1.0/src/indic_itn/main.py +138 -0
- indic_itn-0.1.0/src/indic_itn/parsers/__init__.py +23 -0
- indic_itn-0.1.0/src/indic_itn/parsers/base.py +31 -0
- indic_itn-0.1.0/src/indic_itn/parsers/currency.py +105 -0
- indic_itn-0.1.0/src/indic_itn/parsers/date.py +78 -0
- indic_itn-0.1.0/src/indic_itn/parsers/decimal.py +103 -0
- indic_itn-0.1.0/src/indic_itn/parsers/number.py +96 -0
- indic_itn-0.1.0/src/indic_itn/parsers/otp.py +72 -0
- indic_itn-0.1.0/src/indic_itn/parsers/percentage.py +60 -0
- indic_itn-0.1.0/src/indic_itn/parsers/phone.py +89 -0
- indic_itn-0.1.0/src/indic_itn/parsers/time.py +263 -0
- indic_itn-0.1.0/src/indic_itn/rewriter.py +52 -0
- indic_itn-0.1.0/src/indic_itn/tokenizer.py +42 -0
- indic_itn-0.1.0/src/indic_itn.egg-info/PKG-INFO +104 -0
- indic_itn-0.1.0/src/indic_itn.egg-info/SOURCES.txt +39 -0
- indic_itn-0.1.0/src/indic_itn.egg-info/dependency_links.txt +1 -0
- indic_itn-0.1.0/src/indic_itn.egg-info/requires.txt +8 -0
- indic_itn-0.1.0/src/indic_itn.egg-info/top_level.txt +1 -0
- indic_itn-0.1.0/tests/test_architecture.py +228 -0
- indic_itn-0.1.0/tests/test_currency_parser.py +52 -0
- indic_itn-0.1.0/tests/test_date_parser.py +52 -0
- indic_itn-0.1.0/tests/test_decimal_parser.py +45 -0
- indic_itn-0.1.0/tests/test_detector.py +172 -0
- indic_itn-0.1.0/tests/test_itn.py +73 -0
- indic_itn-0.1.0/tests/test_number_parser.py +77 -0
- indic_itn-0.1.0/tests/test_otp_parser.py +59 -0
- indic_itn-0.1.0/tests/test_percentage_parser.py +41 -0
- indic_itn-0.1.0/tests/test_phone_parser.py +54 -0
- indic_itn-0.1.0/tests/test_resources.py +88 -0
- indic_itn-0.1.0/tests/test_rewriter.py +92 -0
- indic_itn-0.1.0/tests/test_time_parser.py +147 -0
- indic_itn-0.1.0/tests/test_tokenizer.py +91 -0
indic_itn-0.1.0/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 indic-itn contributors
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
indic_itn-0.1.0/PKG-INFO
ADDED
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: indic-itn
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: Inverse Text Normalization (ITN) for Indic languages
|
|
5
|
+
License: MIT
|
|
6
|
+
Classifier: Development Status :: 3 - Alpha
|
|
7
|
+
Classifier: Intended Audience :: Developers
|
|
8
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
9
|
+
Classifier: Programming Language :: Python :: 3
|
|
10
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
11
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
12
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
13
|
+
Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
|
|
14
|
+
Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
|
15
|
+
Requires-Python: >=3.11
|
|
16
|
+
Description-Content-Type: text/markdown
|
|
17
|
+
License-File: LICENSE
|
|
18
|
+
Provides-Extra: dev
|
|
19
|
+
Requires-Dist: black>=24.0.0; extra == "dev"
|
|
20
|
+
Requires-Dist: mypy>=1.9.0; extra == "dev"
|
|
21
|
+
Requires-Dist: pre-commit>=3.6.0; extra == "dev"
|
|
22
|
+
Requires-Dist: pytest>=8.0.0; extra == "dev"
|
|
23
|
+
Requires-Dist: pytest-cov>=4.1.0; extra == "dev"
|
|
24
|
+
Requires-Dist: ruff>=0.3.0; extra == "dev"
|
|
25
|
+
Dynamic: license-file
|
|
26
|
+
|
|
27
|
+
# indic-itn
|
|
28
|
+
|
|
29
|
+
Inverse Text Normalization (ITN) for Indic languages.
|
|
30
|
+
|
|
31
|
+
## Installation
|
|
32
|
+
|
|
33
|
+
To install the package in editable mode for development:
|
|
34
|
+
|
|
35
|
+
```bash
|
|
36
|
+
pip install -e .
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
To install dev dependencies as well:
|
|
40
|
+
|
|
41
|
+
```bash
|
|
42
|
+
pip install -e ".[dev]"
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
## Usage
|
|
46
|
+
|
|
47
|
+
```python
|
|
48
|
+
from indic_itn import HindiITN
|
|
49
|
+
|
|
50
|
+
# Instantiate the ITN processor
|
|
51
|
+
itn = HindiITN()
|
|
52
|
+
|
|
53
|
+
# Normalize text (placeholder)
|
|
54
|
+
# text = "कक्षा दो" -> "कक्षा 2"
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
## Development and Tooling
|
|
58
|
+
|
|
59
|
+
This project uses modern tooling for maintaining code quality:
|
|
60
|
+
|
|
61
|
+
### Code Formatting and Linting
|
|
62
|
+
|
|
63
|
+
We use [Ruff](https://github.com/astral-sh/ruff) and [Black](https://github.com/psf/black) for formatting, linting, and imports sorting.
|
|
64
|
+
|
|
65
|
+
```bash
|
|
66
|
+
# Run Ruff lint check
|
|
67
|
+
ruff check .
|
|
68
|
+
|
|
69
|
+
# Run Ruff formatter check
|
|
70
|
+
ruff format --check .
|
|
71
|
+
|
|
72
|
+
# Run Black formatting check
|
|
73
|
+
black --check .
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
### Type Checking
|
|
77
|
+
|
|
78
|
+
We use [MyPy](https://github.com/python/mypy) for static type checking.
|
|
79
|
+
|
|
80
|
+
```bash
|
|
81
|
+
mypy src tests
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
### Running Tests
|
|
85
|
+
|
|
86
|
+
We use [Pytest](https://github.com/pytest-dev/pytest) for unit testing along with `pytest-cov` for coverage.
|
|
87
|
+
|
|
88
|
+
```bash
|
|
89
|
+
pytest
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
### Pre-commit Hooks
|
|
93
|
+
|
|
94
|
+
To set up pre-commit hooks:
|
|
95
|
+
|
|
96
|
+
```bash
|
|
97
|
+
pre-commit install
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
To run hooks on all files manually:
|
|
101
|
+
|
|
102
|
+
```bash
|
|
103
|
+
pre-commit run --all-files
|
|
104
|
+
```
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
# indic-itn
|
|
2
|
+
|
|
3
|
+
Inverse Text Normalization (ITN) for Indic languages.
|
|
4
|
+
|
|
5
|
+
## Installation
|
|
6
|
+
|
|
7
|
+
To install the package in editable mode for development:
|
|
8
|
+
|
|
9
|
+
```bash
|
|
10
|
+
pip install -e .
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
To install dev dependencies as well:
|
|
14
|
+
|
|
15
|
+
```bash
|
|
16
|
+
pip install -e ".[dev]"
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
## Usage
|
|
20
|
+
|
|
21
|
+
```python
|
|
22
|
+
from indic_itn import HindiITN
|
|
23
|
+
|
|
24
|
+
# Instantiate the ITN processor
|
|
25
|
+
itn = HindiITN()
|
|
26
|
+
|
|
27
|
+
# Normalize text (placeholder)
|
|
28
|
+
# text = "कक्षा दो" -> "कक्षा 2"
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
## Development and Tooling
|
|
32
|
+
|
|
33
|
+
This project uses modern tooling for maintaining code quality:
|
|
34
|
+
|
|
35
|
+
### Code Formatting and Linting
|
|
36
|
+
|
|
37
|
+
We use [Ruff](https://github.com/astral-sh/ruff) and [Black](https://github.com/psf/black) for formatting, linting, and imports sorting.
|
|
38
|
+
|
|
39
|
+
```bash
|
|
40
|
+
# Run Ruff lint check
|
|
41
|
+
ruff check .
|
|
42
|
+
|
|
43
|
+
# Run Ruff formatter check
|
|
44
|
+
ruff format --check .
|
|
45
|
+
|
|
46
|
+
# Run Black formatting check
|
|
47
|
+
black --check .
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
### Type Checking
|
|
51
|
+
|
|
52
|
+
We use [MyPy](https://github.com/python/mypy) for static type checking.
|
|
53
|
+
|
|
54
|
+
```bash
|
|
55
|
+
mypy src tests
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
### Running Tests
|
|
59
|
+
|
|
60
|
+
We use [Pytest](https://github.com/pytest-dev/pytest) for unit testing along with `pytest-cov` for coverage.
|
|
61
|
+
|
|
62
|
+
```bash
|
|
63
|
+
pytest
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
### Pre-commit Hooks
|
|
67
|
+
|
|
68
|
+
To set up pre-commit hooks:
|
|
69
|
+
|
|
70
|
+
```bash
|
|
71
|
+
pre-commit install
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
To run hooks on all files manually:
|
|
75
|
+
|
|
76
|
+
```bash
|
|
77
|
+
pre-commit run --all-files
|
|
78
|
+
```
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
[build-system]
|
|
2
|
+
requires = ["setuptools>=61.0.0", "wheel"]
|
|
3
|
+
build-backend = "setuptools.build_meta"
|
|
4
|
+
|
|
5
|
+
[project]
|
|
6
|
+
name = "indic-itn"
|
|
7
|
+
version = "0.1.0"
|
|
8
|
+
description = "Inverse Text Normalization (ITN) for Indic languages"
|
|
9
|
+
readme = "README.md"
|
|
10
|
+
requires-python = ">=3.11"
|
|
11
|
+
license = { text = "MIT" }
|
|
12
|
+
classifiers = [
|
|
13
|
+
"Development Status :: 3 - Alpha",
|
|
14
|
+
"Intended Audience :: Developers",
|
|
15
|
+
"License :: OSI Approved :: MIT License",
|
|
16
|
+
"Programming Language :: Python :: 3",
|
|
17
|
+
"Programming Language :: Python :: 3.11",
|
|
18
|
+
"Programming Language :: Python :: 3.12",
|
|
19
|
+
"Programming Language :: Python :: 3.13",
|
|
20
|
+
"Topic :: Scientific/Engineering :: Artificial Intelligence",
|
|
21
|
+
"Topic :: Software Development :: Libraries :: Python Modules",
|
|
22
|
+
]
|
|
23
|
+
dependencies = []
|
|
24
|
+
|
|
25
|
+
[project.optional-dependencies]
|
|
26
|
+
dev = [
|
|
27
|
+
"black>=24.0.0",
|
|
28
|
+
"mypy>=1.9.0",
|
|
29
|
+
"pre-commit>=3.6.0",
|
|
30
|
+
"pytest>=8.0.0",
|
|
31
|
+
"pytest-cov>=4.1.0",
|
|
32
|
+
"ruff>=0.3.0",
|
|
33
|
+
]
|
|
34
|
+
|
|
35
|
+
[tool.setuptools.packages.find]
|
|
36
|
+
where = ["src"]
|
|
37
|
+
|
|
38
|
+
[tool.black]
|
|
39
|
+
line-length = 88
|
|
40
|
+
target-version = ["py311"]
|
|
41
|
+
|
|
42
|
+
[tool.ruff]
|
|
43
|
+
line-length = 88
|
|
44
|
+
target-version = "py311"
|
|
45
|
+
|
|
46
|
+
[tool.ruff.lint]
|
|
47
|
+
select = [
|
|
48
|
+
"E", # pycodestyle errors
|
|
49
|
+
"W", # pycodestyle warnings
|
|
50
|
+
"F", # pyflakes
|
|
51
|
+
"I", # isort
|
|
52
|
+
"N", # pep8-naming
|
|
53
|
+
"D", # pydocstyle
|
|
54
|
+
"UP", # pyupgrade
|
|
55
|
+
"RUF", # Ruff-specific rules
|
|
56
|
+
]
|
|
57
|
+
ignore = [
|
|
58
|
+
"D100", # Missing docstring in public module
|
|
59
|
+
"D104", # Missing docstring in public package
|
|
60
|
+
"RUF001", # Ambiguous unicode characters (e.g. Devanagari zero '०' lookalike warning)
|
|
61
|
+
]
|
|
62
|
+
|
|
63
|
+
[tool.ruff.lint.pydocstyle]
|
|
64
|
+
convention = "google"
|
|
65
|
+
|
|
66
|
+
[tool.mypy]
|
|
67
|
+
python_version = "3.11"
|
|
68
|
+
strict = true
|
|
69
|
+
warn_unreachable = true
|
|
70
|
+
pretty = true
|
|
71
|
+
show_error_codes = true
|
|
72
|
+
|
|
73
|
+
[[tool.mypy.overrides]]
|
|
74
|
+
module = "tests.*"
|
|
75
|
+
disallow_untyped_defs = false
|
|
76
|
+
disallow_incomplete_defs = false
|
|
77
|
+
|
|
78
|
+
[tool.pytest.ini_options]
|
|
79
|
+
minversion = "8.0"
|
|
80
|
+
addopts = "-ra -q --cov=indic_itn --cov-report=term-missing"
|
|
81
|
+
testpaths = ["tests"]
|
|
82
|
+
python_files = ["test_*.py"]
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
"""Core domain classes and base interfaces for the ITN pipeline."""
|
|
2
|
+
|
|
3
|
+
from abc import ABC, abstractmethod
|
|
4
|
+
from dataclasses import dataclass, field
|
|
5
|
+
from typing import Any
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
@dataclass(frozen=True)
|
|
9
|
+
class Token:
|
|
10
|
+
"""A single token within the input text.
|
|
11
|
+
|
|
12
|
+
Attributes:
|
|
13
|
+
text: The text content of the token.
|
|
14
|
+
start_idx: The starting character index (inclusive) in the source text.
|
|
15
|
+
end_idx: The ending character index (exclusive) in the source text.
|
|
16
|
+
"""
|
|
17
|
+
|
|
18
|
+
text: str
|
|
19
|
+
start_idx: int
|
|
20
|
+
end_idx: int
|
|
21
|
+
|
|
22
|
+
@property
|
|
23
|
+
def value(self) -> str:
|
|
24
|
+
"""Alias for text."""
|
|
25
|
+
return self.text
|
|
26
|
+
|
|
27
|
+
@property
|
|
28
|
+
def start_offset(self) -> int:
|
|
29
|
+
"""Alias for start_idx."""
|
|
30
|
+
return self.start_idx
|
|
31
|
+
|
|
32
|
+
@property
|
|
33
|
+
def end_offset(self) -> int:
|
|
34
|
+
"""Alias for end_idx."""
|
|
35
|
+
return self.end_idx
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
@dataclass(frozen=True)
|
|
39
|
+
class Entity:
|
|
40
|
+
"""A detected entity that requires normalization.
|
|
41
|
+
|
|
42
|
+
Attributes:
|
|
43
|
+
text: The raw spoken text representing the entity.
|
|
44
|
+
entity_type: The type of entity (e.g., "number", "date", "currency").
|
|
45
|
+
start_idx: The starting character index (inclusive) in the source text.
|
|
46
|
+
end_idx: The ending character index (exclusive) in the source text.
|
|
47
|
+
metadata: Optional dictionary containing additional structured details
|
|
48
|
+
about the detected entity.
|
|
49
|
+
"""
|
|
50
|
+
|
|
51
|
+
text: str
|
|
52
|
+
entity_type: str
|
|
53
|
+
start_idx: int
|
|
54
|
+
end_idx: int
|
|
55
|
+
metadata: dict[str, Any] = field(default_factory=dict, hash=False, compare=False)
|
|
56
|
+
|
|
57
|
+
|
|
58
|
+
class BaseTokenizer(ABC):
|
|
59
|
+
"""Abstract base class for all tokenizers in the ITN pipeline."""
|
|
60
|
+
|
|
61
|
+
@abstractmethod
|
|
62
|
+
def tokenize(self, text: str) -> list[Token]:
|
|
63
|
+
"""Split input text into a list of Token objects.
|
|
64
|
+
|
|
65
|
+
Args:
|
|
66
|
+
text: The raw input text.
|
|
67
|
+
|
|
68
|
+
Returns:
|
|
69
|
+
A list of Token objects with their corresponding indices.
|
|
70
|
+
"""
|
|
71
|
+
pass
|
|
72
|
+
|
|
73
|
+
|
|
74
|
+
class BaseEntityDetector(ABC):
|
|
75
|
+
"""Abstract base class for detecting normalizeable entities in tokenized text."""
|
|
76
|
+
|
|
77
|
+
@abstractmethod
|
|
78
|
+
def detect(self, tokens: list[Token]) -> list[Entity]:
|
|
79
|
+
"""Detect entities from the list of tokens.
|
|
80
|
+
|
|
81
|
+
Args:
|
|
82
|
+
tokens: A list of input Token objects.
|
|
83
|
+
|
|
84
|
+
Returns:
|
|
85
|
+
A list of detected Entity objects.
|
|
86
|
+
"""
|
|
87
|
+
pass
|
|
88
|
+
|
|
89
|
+
|
|
90
|
+
class BaseRewriter(ABC):
|
|
91
|
+
"""Abstract base class for rewriting the input text with normalized values."""
|
|
92
|
+
|
|
93
|
+
@abstractmethod
|
|
94
|
+
def rewrite(self, text: str, entity_rewrites: dict[Entity, str]) -> str:
|
|
95
|
+
"""Replace raw entities in the input text with their normalized string values.
|
|
96
|
+
|
|
97
|
+
Args:
|
|
98
|
+
text: The original input text.
|
|
99
|
+
entity_rewrites: A dictionary mapping each detected Entity to its
|
|
100
|
+
normalized string representation.
|
|
101
|
+
|
|
102
|
+
Returns:
|
|
103
|
+
The final normalized text.
|
|
104
|
+
"""
|
|
105
|
+
pass
|