indic-language-utils 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_language_utils-0.1.0/.env.example +4 -0
- indic_language_utils-0.1.0/.github/workflows/ci.yml +30 -0
- indic_language_utils-0.1.0/.github/workflows/publish.yml +31 -0
- indic_language_utils-0.1.0/.gitignore +10 -0
- indic_language_utils-0.1.0/.indic-language-utils.toml +31 -0
- indic_language_utils-0.1.0/.pre-commit-config.yaml +34 -0
- indic_language_utils-0.1.0/LICENSE +21 -0
- indic_language_utils-0.1.0/PKG-INFO +88 -0
- indic_language_utils-0.1.0/README.md +44 -0
- indic_language_utils-0.1.0/docs/adapter-author-guide.md +36 -0
- indic_language_utils-0.1.0/docs/configuration.md +187 -0
- indic_language_utils-0.1.0/docs/detection.md +325 -0
- indic_language_utils-0.1.0/docs/index.md +90 -0
- indic_language_utils-0.1.0/docs/processors.md +83 -0
- indic_language_utils-0.1.0/docs/translation.md +352 -0
- indic_language_utils-0.1.0/docs/user-guide.md +255 -0
- indic_language_utils-0.1.0/examples/langdetect/README.md +162 -0
- indic_language_utils-0.1.0/examples/langdetect/bhashini_demo.py +210 -0
- indic_language_utils-0.1.0/examples/langdetect/fasttext_demo.py +138 -0
- indic_language_utils-0.1.0/examples/langdetect/multi_service_demo.py +195 -0
- indic_language_utils-0.1.0/examples/translation/README.md +226 -0
- indic_language_utils-0.1.0/examples/translation/demo.py +116 -0
- indic_language_utils-0.1.0/examples/translation/googletrans_demo.py +124 -0
- indic_language_utils-0.1.0/mkdocs.yml +47 -0
- indic_language_utils-0.1.0/plans/architecture-proposal.md +387 -0
- indic_language_utils-0.1.0/pyproject.toml +67 -0
- indic_language_utils-0.1.0/src/indic_language_utils/__init__.py +178 -0
- indic_language_utils-0.1.0/src/indic_language_utils/cache.py +343 -0
- indic_language_utils-0.1.0/src/indic_language_utils/concurrency.py +30 -0
- indic_language_utils-0.1.0/src/indic_language_utils/config.py +389 -0
- indic_language_utils-0.1.0/src/indic_language_utils/detection/__init__.py +52 -0
- indic_language_utils-0.1.0/src/indic_language_utils/detection/bhashini_detect.py +202 -0
- indic_language_utils-0.1.0/src/indic_language_utils/detection/cache.py +171 -0
- indic_language_utils-0.1.0/src/indic_language_utils/detection/client.py +292 -0
- indic_language_utils-0.1.0/src/indic_language_utils/detection/fasttext.py +198 -0
- indic_language_utils-0.1.0/src/indic_language_utils/detection/helpers.py +178 -0
- indic_language_utils-0.1.0/src/indic_language_utils/detection/models.py +99 -0
- indic_language_utils-0.1.0/src/indic_language_utils/detection/protocols.py +19 -0
- indic_language_utils-0.1.0/src/indic_language_utils/detection/sync.py +93 -0
- indic_language_utils-0.1.0/src/indic_language_utils/errors.py +94 -0
- indic_language_utils-0.1.0/src/indic_language_utils/languages.py +138 -0
- indic_language_utils-0.1.0/src/indic_language_utils/models.py +75 -0
- indic_language_utils-0.1.0/src/indic_language_utils/processors.py +21 -0
- indic_language_utils-0.1.0/src/indic_language_utils/providers/__init__.py +29 -0
- indic_language_utils-0.1.0/src/indic_language_utils/providers/base.py +119 -0
- indic_language_utils-0.1.0/src/indic_language_utils/providers/bhashini.py +292 -0
- indic_language_utils-0.1.0/src/indic_language_utils/py.typed +0 -0
- indic_language_utils-0.1.0/src/indic_language_utils/retry.py +62 -0
- indic_language_utils-0.1.0/src/indic_language_utils/routing.py +70 -0
- indic_language_utils-0.1.0/src/indic_language_utils/telemetry.py +62 -0
- indic_language_utils-0.1.0/src/indic_language_utils/timing.py +32 -0
- indic_language_utils-0.1.0/src/indic_language_utils/translation/__init__.py +78 -0
- indic_language_utils-0.1.0/src/indic_language_utils/translation/bhashini_translate.py +206 -0
- indic_language_utils-0.1.0/src/indic_language_utils/translation/cache.py +142 -0
- indic_language_utils-0.1.0/src/indic_language_utils/translation/catalog.py +59 -0
- indic_language_utils-0.1.0/src/indic_language_utils/translation/client.py +418 -0
- indic_language_utils-0.1.0/src/indic_language_utils/translation/google_translate.py +419 -0
- indic_language_utils-0.1.0/src/indic_language_utils/translation/helpers.py +220 -0
- indic_language_utils-0.1.0/src/indic_language_utils/translation/models.py +95 -0
- indic_language_utils-0.1.0/src/indic_language_utils/translation/processing.py +290 -0
- indic_language_utils-0.1.0/src/indic_language_utils/translation/protocols.py +22 -0
- indic_language_utils-0.1.0/src/indic_language_utils/translation/sync.py +119 -0
- indic_language_utils-0.1.0/tests/__init__.py +0 -0
- indic_language_utils-0.1.0/tests/provider_contract.py +39 -0
- indic_language_utils-0.1.0/tests/support.py +36 -0
- indic_language_utils-0.1.0/tests/test_bhashini.py +244 -0
- indic_language_utils-0.1.0/tests/test_bhashini_detection.py +230 -0
- indic_language_utils-0.1.0/tests/test_cache.py +93 -0
- indic_language_utils-0.1.0/tests/test_config_telemetry_errors.py +39 -0
- indic_language_utils-0.1.0/tests/test_detection_cache.py +131 -0
- indic_language_utils-0.1.0/tests/test_detection_client.py +180 -0
- indic_language_utils-0.1.0/tests/test_detection_helpers.py +52 -0
- indic_language_utils-0.1.0/tests/test_detection_sync.py +58 -0
- indic_language_utils-0.1.0/tests/test_fasttext_detection.py +141 -0
- indic_language_utils-0.1.0/tests/test_file_config.py +187 -0
- indic_language_utils-0.1.0/tests/test_google_translate.py +373 -0
- indic_language_utils-0.1.0/tests/test_languages.py +25 -0
- indic_language_utils-0.1.0/tests/test_providers_routing.py +78 -0
- indic_language_utils-0.1.0/tests/test_retry_concurrency.py +93 -0
- indic_language_utils-0.1.0/tests/test_sqlite_cache.py +96 -0
- indic_language_utils-0.1.0/tests/test_translation_client.py +183 -0
- indic_language_utils-0.1.0/tests/test_translation_helpers.py +161 -0
- indic_language_utils-0.1.0/tests/test_translation_persistent_cache.py +87 -0
- indic_language_utils-0.1.0/tests/test_translation_processing.py +84 -0
- indic_language_utils-0.1.0/tests/test_translation_sync.py +37 -0
- indic_language_utils-0.1.0/tests/translation_support.py +82 -0
- indic_language_utils-0.1.0/uv.lock +933 -0
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
# Bhashini inference API credentials (required for live tests and translation)
|
|
2
|
+
BHASHINI_API_KEY="your-bhashini-api-key-here"
|
|
3
|
+
BHASHINI_ENDPOINT_URL="https://dhruva-api.bhashini.gov.in/services/inference/pipeline"
|
|
4
|
+
BHASHINI_TRANSLATION_SERVICE_ID="ai4bharat/indictrans-v2-all-gpu--t4"
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
name: CI
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
pull_request:
|
|
6
|
+
|
|
7
|
+
jobs:
|
|
8
|
+
test:
|
|
9
|
+
runs-on: ubuntu-latest
|
|
10
|
+
strategy:
|
|
11
|
+
matrix:
|
|
12
|
+
python-version: ["3.11", "3.12"]
|
|
13
|
+
steps:
|
|
14
|
+
- uses: actions/checkout@v4
|
|
15
|
+
- uses: astral-sh/setup-uv@v6
|
|
16
|
+
with:
|
|
17
|
+
python-version: ${{ matrix.python-version }}
|
|
18
|
+
- run: uv sync --locked --dev
|
|
19
|
+
- run: uv run ruff format --check .
|
|
20
|
+
- run: uv run ruff check .
|
|
21
|
+
- run: uv run mypy
|
|
22
|
+
- run: uv run pytest
|
|
23
|
+
- run: uv build
|
|
24
|
+
- name: Test the built wheel
|
|
25
|
+
run: |
|
|
26
|
+
wheel_venv="$(mktemp -d)/venv"
|
|
27
|
+
uv venv "$wheel_venv"
|
|
28
|
+
uv pip install --python "$wheel_venv/bin/python" dist/*.whl
|
|
29
|
+
cd /tmp
|
|
30
|
+
"$wheel_venv/bin/python" -c 'import indic_language_utils; assert indic_language_utils.__version__ == "0.1.0"'
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
name: Publish to PyPI
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
tags:
|
|
6
|
+
- "v*"
|
|
7
|
+
|
|
8
|
+
jobs:
|
|
9
|
+
pypi-publish:
|
|
10
|
+
name: Publish to PyPI
|
|
11
|
+
runs-on: ubuntu-latest
|
|
12
|
+
environment:
|
|
13
|
+
name: pypi
|
|
14
|
+
url: https://pypi.org/p/indic-language-utils
|
|
15
|
+
permissions:
|
|
16
|
+
id-token: write
|
|
17
|
+
contents: read
|
|
18
|
+
|
|
19
|
+
steps:
|
|
20
|
+
- uses: actions/checkout@v4
|
|
21
|
+
|
|
22
|
+
- name: Install uv
|
|
23
|
+
uses: astral-sh/setup-uv@v6
|
|
24
|
+
with:
|
|
25
|
+
python-version: "3.12"
|
|
26
|
+
|
|
27
|
+
- name: Build package distributions
|
|
28
|
+
run: uv build
|
|
29
|
+
|
|
30
|
+
- name: Publish to PyPI
|
|
31
|
+
uses: pypa/gh-action-pypi-publish@release/v1
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
[cache]
|
|
2
|
+
enabled = true
|
|
3
|
+
backend = "sqlite"
|
|
4
|
+
path = ".cache/translations.sqlite3"
|
|
5
|
+
namespace = "language-utils"
|
|
6
|
+
max_entries = 50000
|
|
7
|
+
ttl_seconds = 86400
|
|
8
|
+
|
|
9
|
+
[retry]
|
|
10
|
+
max_attempts = 3
|
|
11
|
+
base_delay_seconds = 0.5
|
|
12
|
+
max_delay_seconds = 2.0
|
|
13
|
+
|
|
14
|
+
[telemetry]
|
|
15
|
+
logging_enabled = true
|
|
16
|
+
metrics_enabled = true
|
|
17
|
+
traces_enabled = true
|
|
18
|
+
include_content = false
|
|
19
|
+
|
|
20
|
+
[providers.bhashini]
|
|
21
|
+
endpoint = "https://dhruva-api.bhashini.gov.in/services/inference/pipeline"
|
|
22
|
+
translation_service_id = "ai4bharat/indictrans-v2-all-gpu--t4"
|
|
23
|
+
timeout_seconds = 20.0
|
|
24
|
+
max_concurrency = 8
|
|
25
|
+
|
|
26
|
+
[providers.googletrans]
|
|
27
|
+
timeout_seconds = 20.0
|
|
28
|
+
max_concurrency = 4
|
|
29
|
+
|
|
30
|
+
[routes]
|
|
31
|
+
translation = ["bhashini", "googletrans"]
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
repos:
|
|
2
|
+
- repo: https://github.com/pre-commit/pre-commit-hooks
|
|
3
|
+
rev: v5.0.0
|
|
4
|
+
hooks:
|
|
5
|
+
- id: trailing-whitespace
|
|
6
|
+
- id: end-of-file-fixer
|
|
7
|
+
- id: check-yaml
|
|
8
|
+
args: [--unsafe]
|
|
9
|
+
- id: check-toml
|
|
10
|
+
- id: check-added-large-files
|
|
11
|
+
args: [--maxkb=5120]
|
|
12
|
+
|
|
13
|
+
- repo: local
|
|
14
|
+
hooks:
|
|
15
|
+
- id: ruff-format
|
|
16
|
+
name: ruff format
|
|
17
|
+
entry: uv run ruff format
|
|
18
|
+
language: system
|
|
19
|
+
types_or: [python, markdown]
|
|
20
|
+
require_serial: true
|
|
21
|
+
|
|
22
|
+
- id: ruff-check
|
|
23
|
+
name: ruff check
|
|
24
|
+
entry: uv run ruff check --fix
|
|
25
|
+
language: system
|
|
26
|
+
types: [python]
|
|
27
|
+
require_serial: true
|
|
28
|
+
|
|
29
|
+
- id: mypy
|
|
30
|
+
name: mypy
|
|
31
|
+
entry: uv run mypy
|
|
32
|
+
language: system
|
|
33
|
+
types: [python]
|
|
34
|
+
pass_filenames: false
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Harikesh Kushwaha 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.
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
Metadata-Version: 2.5
|
|
2
|
+
Name: indic-language-utils
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: Provider-neutral foundations for Indian language applications
|
|
5
|
+
Project-URL: Documentation, https://github.com/indic-language-utils/indic-language-utils
|
|
6
|
+
Project-URL: Source, https://github.com/indic-language-utils/indic-language-utils
|
|
7
|
+
Author: indic-language-utils contributors
|
|
8
|
+
License: MIT License
|
|
9
|
+
|
|
10
|
+
Copyright (c) 2026 Harikesh Kushwaha contributors
|
|
11
|
+
|
|
12
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
13
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
14
|
+
in the Software without restriction, including without limitation the rights
|
|
15
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
16
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
17
|
+
furnished to do so, subject to the following conditions:
|
|
18
|
+
|
|
19
|
+
The above copyright notice and this permission notice shall be included in all
|
|
20
|
+
copies or substantial portions of the Software.
|
|
21
|
+
|
|
22
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
23
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
24
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
25
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
26
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
27
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
28
|
+
SOFTWARE.
|
|
29
|
+
License-File: LICENSE
|
|
30
|
+
Keywords: indic,language,speech,translation
|
|
31
|
+
Classifier: Development Status :: 2 - Pre-Alpha
|
|
32
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
33
|
+
Classifier: Programming Language :: Python :: 3
|
|
34
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
35
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
36
|
+
Classifier: Typing :: Typed
|
|
37
|
+
Requires-Python: <3.13,>=3.11
|
|
38
|
+
Requires-Dist: httpx<1,>=0.28
|
|
39
|
+
Provides-Extra: googletrans
|
|
40
|
+
Requires-Dist: googletrans>=4.0.2; extra == 'googletrans'
|
|
41
|
+
Provides-Extra: local-tld
|
|
42
|
+
Requires-Dist: fasttext-langdetect>=1.1.1; extra == 'local-tld'
|
|
43
|
+
Description-Content-Type: text/markdown
|
|
44
|
+
|
|
45
|
+
# indic-language-utils
|
|
46
|
+
|
|
47
|
+
A Python 3.11 and 3.12 library for Indian-language translation, text language detection, transliteration, speech-to-text, and text-to-speech. The project uses `uv` and will be published on PyPI as `indic-language-utils`. Its Python import is `indic_language_utils`. The code is licensed under the MIT License.
|
|
48
|
+
|
|
49
|
+
Phase 0 implements the shared library foundation, Phase 1 adds structured translation with Bhashini and Google Translate adapters, and Phase 2 adds text language detection with local FastText and cloud Bhashini adapters. Runtime caching can use bounded process memory or persistent SQLite storage. The architecture and ecosystem review is in [plans/architecture-proposal.md](plans/architecture-proposal.md).
|
|
50
|
+
|
|
51
|
+
The intended shape is a small core with optional provider packages. Applications should be able to start with local or low-cost providers during a proof of concept, then change routing configuration for production without rewriting text and audio handling.
|
|
52
|
+
|
|
53
|
+
Work will be delivered in this order:
|
|
54
|
+
|
|
55
|
+
- shared library foundation
|
|
56
|
+
- text translation
|
|
57
|
+
- text language detection, abbreviated as TLD
|
|
58
|
+
- transliteration
|
|
59
|
+
- non-streaming speech-to-text, abbreviated as STT
|
|
60
|
+
- non-streaming text-to-speech, abbreviated as TTS
|
|
61
|
+
|
|
62
|
+
Provider work starts with Bhashini and then Sarvam. Unofficial Google or Microsoft adapters can be added later as opt-in extras or external plugins. Optional dependency groups will keep translation-only installations free of speech and audio dependencies.
|
|
63
|
+
|
|
64
|
+
Cross-cutting requirements include structured-text preservation, bounded concurrency, retries, routing and fallback, versioned terminology, caching, logging, metrics, and explicit data-retention controls.
|
|
65
|
+
|
|
66
|
+
## Development
|
|
67
|
+
|
|
68
|
+
Install the locked development environment with `uv sync --dev`. The usual checks are:
|
|
69
|
+
|
|
70
|
+
```console
|
|
71
|
+
uv run pre-commit install
|
|
72
|
+
uv run ruff format .
|
|
73
|
+
uv run ruff check .
|
|
74
|
+
uv run mypy
|
|
75
|
+
uv run pytest
|
|
76
|
+
uv build
|
|
77
|
+
uv run mkdocs serve
|
|
78
|
+
uv run mkdocs build
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
The runtime uses HTTPX for Bhashini's reusable asynchronous HTTP client. For usage and guides, see:
|
|
82
|
+
|
|
83
|
+
- [docs/user-guide.md](docs/user-guide.md) for system capabilities and getting started
|
|
84
|
+
- [docs/translation.md](docs/translation.md) for translation features and examples
|
|
85
|
+
- [docs/detection.md](docs/detection.md) for text language and script detection
|
|
86
|
+
- [docs/configuration.md](docs/configuration.md) for TOML and environment loading
|
|
87
|
+
- [docs/processors.md](docs/processors.md) for processor composition and markdown protection
|
|
88
|
+
- [docs/adapter-author-guide.md](docs/adapter-author-guide.md) for provider integration
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
# indic-language-utils
|
|
2
|
+
|
|
3
|
+
A Python 3.11 and 3.12 library for Indian-language translation, text language detection, transliteration, speech-to-text, and text-to-speech. The project uses `uv` and will be published on PyPI as `indic-language-utils`. Its Python import is `indic_language_utils`. The code is licensed under the MIT License.
|
|
4
|
+
|
|
5
|
+
Phase 0 implements the shared library foundation, Phase 1 adds structured translation with Bhashini and Google Translate adapters, and Phase 2 adds text language detection with local FastText and cloud Bhashini adapters. Runtime caching can use bounded process memory or persistent SQLite storage. The architecture and ecosystem review is in [plans/architecture-proposal.md](plans/architecture-proposal.md).
|
|
6
|
+
|
|
7
|
+
The intended shape is a small core with optional provider packages. Applications should be able to start with local or low-cost providers during a proof of concept, then change routing configuration for production without rewriting text and audio handling.
|
|
8
|
+
|
|
9
|
+
Work will be delivered in this order:
|
|
10
|
+
|
|
11
|
+
- shared library foundation
|
|
12
|
+
- text translation
|
|
13
|
+
- text language detection, abbreviated as TLD
|
|
14
|
+
- transliteration
|
|
15
|
+
- non-streaming speech-to-text, abbreviated as STT
|
|
16
|
+
- non-streaming text-to-speech, abbreviated as TTS
|
|
17
|
+
|
|
18
|
+
Provider work starts with Bhashini and then Sarvam. Unofficial Google or Microsoft adapters can be added later as opt-in extras or external plugins. Optional dependency groups will keep translation-only installations free of speech and audio dependencies.
|
|
19
|
+
|
|
20
|
+
Cross-cutting requirements include structured-text preservation, bounded concurrency, retries, routing and fallback, versioned terminology, caching, logging, metrics, and explicit data-retention controls.
|
|
21
|
+
|
|
22
|
+
## Development
|
|
23
|
+
|
|
24
|
+
Install the locked development environment with `uv sync --dev`. The usual checks are:
|
|
25
|
+
|
|
26
|
+
```console
|
|
27
|
+
uv run pre-commit install
|
|
28
|
+
uv run ruff format .
|
|
29
|
+
uv run ruff check .
|
|
30
|
+
uv run mypy
|
|
31
|
+
uv run pytest
|
|
32
|
+
uv build
|
|
33
|
+
uv run mkdocs serve
|
|
34
|
+
uv run mkdocs build
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
The runtime uses HTTPX for Bhashini's reusable asynchronous HTTP client. For usage and guides, see:
|
|
38
|
+
|
|
39
|
+
- [docs/user-guide.md](docs/user-guide.md) for system capabilities and getting started
|
|
40
|
+
- [docs/translation.md](docs/translation.md) for translation features and examples
|
|
41
|
+
- [docs/detection.md](docs/detection.md) for text language and script detection
|
|
42
|
+
- [docs/configuration.md](docs/configuration.md) for TOML and environment loading
|
|
43
|
+
- [docs/processors.md](docs/processors.md) for processor composition and markdown protection
|
|
44
|
+
- [docs/adapter-author-guide.md](docs/adapter-author-guide.md) for provider integration
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
# Adapter author guide
|
|
2
|
+
|
|
3
|
+
An adapter is an object with a `ProviderIdentity` and a tuple of `CapabilityDeclaration` values. It implements only its concrete capability protocol. There is no shared provider base class.
|
|
4
|
+
|
|
5
|
+
Register an adapter explicitly with `ProviderRegistry.register`. Declare canonical `LanguageTag` values, supported pairs, required features, and named limits. Do not place provider-specific language codes in public models. Convert them inside the adapter.
|
|
6
|
+
|
|
7
|
+
Adapters that own reusable clients implement `start()` and `close()`. `ResourceManager` starts resources in order, closes them in reverse order, and supports `async with`.
|
|
8
|
+
|
|
9
|
+
Map provider failures to the matching exception in `indic_language_utils.errors`. Exception messages and structured fields must not contain request content, credentials, headers, or raw provider responses. Mark only rate limits, timeouts, and temporary provider failures as retryable.
|
|
10
|
+
|
|
11
|
+
This illustrative provider declares a fake operation. It is not a supported language capability:
|
|
12
|
+
|
|
13
|
+
```python
|
|
14
|
+
from dataclasses import dataclass
|
|
15
|
+
|
|
16
|
+
from indic_language_utils.models import ProviderIdentity
|
|
17
|
+
from indic_language_utils.providers import CapabilityDeclaration, CapabilityId, ProviderRegistry
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
@dataclass
|
|
21
|
+
class ExampleProvider:
|
|
22
|
+
identity = ProviderIdentity("example")
|
|
23
|
+
capabilities = (CapabilityDeclaration(CapabilityId.TRANSLATION),)
|
|
24
|
+
|
|
25
|
+
async def start(self) -> None:
|
|
26
|
+
pass
|
|
27
|
+
|
|
28
|
+
async def close(self) -> None:
|
|
29
|
+
pass
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
registry = ProviderRegistry()
|
|
33
|
+
registry.register(ExampleProvider())
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
Real translation models and provider methods arrive in Phase 1.
|
|
@@ -0,0 +1,187 @@
|
|
|
1
|
+
# Configuration
|
|
2
|
+
|
|
3
|
+
The library uses a tiered configuration system combining TOML project files, user configurations, environment variables, and programmatic overrides. Settings are validated strictly on load; unknown keys or invalid data types raise a `ConfigurationError`.
|
|
4
|
+
|
|
5
|
+
## Configuration Precedence
|
|
6
|
+
|
|
7
|
+
`Settings.load()` evaluates configuration sources in the following order, from lowest to highest precedence:
|
|
8
|
+
|
|
9
|
+
- Library defaults
|
|
10
|
+
- User configuration at `~/.config/indic-language-utils/config.toml` (or `$XDG_CONFIG_HOME/indic-language-utils/config.toml`)
|
|
11
|
+
- The nearest `.indic-language-utils.toml` found by walking upward from the current working directory
|
|
12
|
+
- An explicit configuration file specified via `Settings.load(path=...)` or the `ILU_CONFIG_FILE` environment variable
|
|
13
|
+
- Environment variables (`ILU_*`, `BHASHINI_*`, and `TRANSLATION_SERVICE_PROVIDER`)
|
|
14
|
+
- Programmatic overrides passed via `Settings.load(overrides=...)`
|
|
15
|
+
|
|
16
|
+
Only existing discovered files are merged. If an explicit configuration path is provided, that file must exist.
|
|
17
|
+
|
|
18
|
+
## Project Configuration File
|
|
19
|
+
|
|
20
|
+
A project configuration file (`.indic-language-utils.toml`) can be placed at the root of a project repository. The following example illustrates all supported configuration sections:
|
|
21
|
+
|
|
22
|
+
```toml
|
|
23
|
+
[cache]
|
|
24
|
+
enabled = true
|
|
25
|
+
backend = "sqlite"
|
|
26
|
+
path = ".cache/translations.sqlite3"
|
|
27
|
+
namespace = "my-application"
|
|
28
|
+
max_entries = 50000
|
|
29
|
+
ttl_seconds = 86400
|
|
30
|
+
|
|
31
|
+
[retry]
|
|
32
|
+
max_attempts = 3
|
|
33
|
+
base_delay_seconds = 0.25
|
|
34
|
+
max_delay_seconds = 5.0
|
|
35
|
+
|
|
36
|
+
[telemetry]
|
|
37
|
+
logging_enabled = true
|
|
38
|
+
metrics_enabled = true
|
|
39
|
+
traces_enabled = true
|
|
40
|
+
include_content = false
|
|
41
|
+
|
|
42
|
+
[providers.bhashini]
|
|
43
|
+
endpoint = "https://dhruva-api.bhashini.gov.in/services/inference/pipeline"
|
|
44
|
+
translation_service_id = "default-translation-model-id"
|
|
45
|
+
detection_service_id = "default-tld-model-id"
|
|
46
|
+
timeout_seconds = 20.0
|
|
47
|
+
max_concurrency = 8
|
|
48
|
+
|
|
49
|
+
[providers.bhashini.translation_service_ids]
|
|
50
|
+
"hi-IN" = "service-for-any-source-to-hindi"
|
|
51
|
+
"en-IN>ta-IN" = "service-for-english-to-tamil"
|
|
52
|
+
|
|
53
|
+
[providers.googletrans]
|
|
54
|
+
timeout_seconds = 20.0
|
|
55
|
+
max_concurrency = 4
|
|
56
|
+
|
|
57
|
+
[routes]
|
|
58
|
+
translation = ["bhashini", "googletrans"]
|
|
59
|
+
text_language_detection = ["bhashini", "fasttext"]
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
Relative cache paths resolve relative to the current working directory of the process. In production containers or multi-directory environments, specify an absolute path.
|
|
63
|
+
|
|
64
|
+
## Secrets and Environment Variables
|
|
65
|
+
|
|
66
|
+
TOML files are strictly prohibited from storing credentials, passwords, tokens, or API keys. Attempting to define fields containing sensitive terms (such as `api_key`, `token`, `secret`, or `password`) raises a `ConfigurationError`.
|
|
67
|
+
|
|
68
|
+
All sensitive values must be supplied via environment variables.
|
|
69
|
+
|
|
70
|
+
### Provider Credentials and Overrides
|
|
71
|
+
|
|
72
|
+
Bhashini credentials and service endpoints:
|
|
73
|
+
|
|
74
|
+
```console
|
|
75
|
+
# Required for Bhashini live API calls
|
|
76
|
+
export BHASHINI_API_KEY="your-bhashini-api-key"
|
|
77
|
+
|
|
78
|
+
# Optional overrides for endpoints and service IDs
|
|
79
|
+
export BHASHINI_ENDPOINT_URL="https://dhruva-api.bhashini.gov.in/services/inference/pipeline"
|
|
80
|
+
export BHASHINI_TRANSLATION_SERVICE_ID="your-translation-service-id"
|
|
81
|
+
export BHASHINI_DETECTION_SERVICE_ID="your-tld-service-id"
|
|
82
|
+
export BHASHINI_TIMEOUT_SECONDS="20"
|
|
83
|
+
export BHASHINI_MAX_CONCURRENCY="8"
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
To quickly select an active translation provider during development without editing configuration files:
|
|
87
|
+
|
|
88
|
+
```console
|
|
89
|
+
export TRANSLATION_SERVICE_PROVIDER="googletrans"
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
### Shared System Settings
|
|
93
|
+
|
|
94
|
+
Global cache, retry, telemetry, and routing settings use the `ILU_` prefix:
|
|
95
|
+
|
|
96
|
+
```console
|
|
97
|
+
# Caching settings
|
|
98
|
+
export ILU_CACHE_ENABLED="true"
|
|
99
|
+
export ILU_CACHE_BACKEND="sqlite"
|
|
100
|
+
export ILU_CACHE_PATH="/var/lib/indic-language-utils/cache.sqlite3"
|
|
101
|
+
export ILU_CACHE_NAMESPACE="my-app"
|
|
102
|
+
export ILU_CACHE_MAX_ENTRIES="50000"
|
|
103
|
+
export ILU_CACHE_TTL_SECONDS="86400"
|
|
104
|
+
|
|
105
|
+
# Retry settings
|
|
106
|
+
export ILU_RETRY_MAX_ATTEMPTS="3"
|
|
107
|
+
export ILU_RETRY_BASE_DELAY_SECONDS="0.25"
|
|
108
|
+
export ILU_RETRY_MAX_DELAY_SECONDS="5.0"
|
|
109
|
+
|
|
110
|
+
# Telemetry settings
|
|
111
|
+
export ILU_LOGGING_ENABLED="true"
|
|
112
|
+
export ILU_METRICS_ENABLED="true"
|
|
113
|
+
export ILU_TRACES_ENABLED="true"
|
|
114
|
+
export ILU_TELEMETRY_INCLUDE_CONTENT="false"
|
|
115
|
+
|
|
116
|
+
# Route overrides (comma-separated provider names in priority order)
|
|
117
|
+
export ILU_ROUTE_TRANSLATION="bhashini,googletrans"
|
|
118
|
+
export ILU_ROUTE_TEXT_LANGUAGE_DETECTION="bhashini,fasttext"
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
## Programmatic Loading and Overrides
|
|
122
|
+
|
|
123
|
+
### Automatic Discovery
|
|
124
|
+
|
|
125
|
+
The easiest way to initialize a client is via the built-in factories, which call `Settings.load()` automatically:
|
|
126
|
+
|
|
127
|
+
```python
|
|
128
|
+
from indic_language_utils import get_translation_client
|
|
129
|
+
|
|
130
|
+
# Automatically reads .indic-language-utils.toml and environment variables
|
|
131
|
+
client = get_translation_client()
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
### Explicit Settings Loading
|
|
135
|
+
|
|
136
|
+
For granular control over settings loading:
|
|
137
|
+
|
|
138
|
+
```python
|
|
139
|
+
from pathlib import Path
|
|
140
|
+
from indic_language_utils import Settings
|
|
141
|
+
|
|
142
|
+
# Load settings from a specific TOML file
|
|
143
|
+
settings = Settings.load(path=Path("/etc/indic-language-utils/production.toml"))
|
|
144
|
+
|
|
145
|
+
# Load settings with test overrides
|
|
146
|
+
test_settings = Settings.load(
|
|
147
|
+
overrides={
|
|
148
|
+
"cache": {"enabled": False},
|
|
149
|
+
"retry": {"max_attempts": 1},
|
|
150
|
+
}
|
|
151
|
+
)
|
|
152
|
+
```
|
|
153
|
+
|
|
154
|
+
### Building Custom Clients from Settings
|
|
155
|
+
|
|
156
|
+
Assemble a client pipeline explicitly using loaded settings:
|
|
157
|
+
|
|
158
|
+
```python
|
|
159
|
+
from indic_language_utils import (
|
|
160
|
+
BhashiniConfig,
|
|
161
|
+
BhashiniTranslationProvider,
|
|
162
|
+
CacheKeyBuilder,
|
|
163
|
+
CapabilityId,
|
|
164
|
+
GoogleTranslateProvider,
|
|
165
|
+
OrderedRouter,
|
|
166
|
+
ProviderRegistry,
|
|
167
|
+
Settings,
|
|
168
|
+
TranslationClient,
|
|
169
|
+
create_translation_cache,
|
|
170
|
+
)
|
|
171
|
+
|
|
172
|
+
settings = Settings.load()
|
|
173
|
+
|
|
174
|
+
registry = ProviderRegistry()
|
|
175
|
+
if "bhashini" in settings.providers:
|
|
176
|
+
registry.register(BhashiniTranslationProvider(BhashiniConfig.from_settings(settings)))
|
|
177
|
+
registry.register(GoogleTranslateProvider())
|
|
178
|
+
|
|
179
|
+
route = settings.routes.get("translation", ("bhashini", "googletrans"))
|
|
180
|
+
router = OrderedRouter(registry, {CapabilityId.TRANSLATION: route})
|
|
181
|
+
|
|
182
|
+
client = TranslationClient(
|
|
183
|
+
router=router,
|
|
184
|
+
cache=create_translation_cache(settings.cache),
|
|
185
|
+
cache_keys=CacheKeyBuilder(settings.cache.namespace),
|
|
186
|
+
)
|
|
187
|
+
```
|