glfm 1.0.4__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.
- glfm-1.0.4/LICENCE +21 -0
- glfm-1.0.4/PKG-INFO +344 -0
- glfm-1.0.4/README.md +315 -0
- glfm-1.0.4/pyproject.toml +55 -0
- glfm-1.0.4/setup.cfg +4 -0
- glfm-1.0.4/src/glfm/__init__.py +19 -0
- glfm-1.0.4/src/glfm/_version.py +18 -0
- glfm-1.0.4/src/glfm/build_unified.py +197 -0
- glfm-1.0.4/src/glfm/config.py +170 -0
- glfm-1.0.4/src/glfm/data/override_scripts.json +23 -0
- glfm-1.0.4/src/glfm/data/uralic_languages.json +8 -0
- glfm-1.0.4/src/glfm/download.py +127 -0
- glfm-1.0.4/src/glfm/loaders/__init__.py +18 -0
- glfm-1.0.4/src/glfm/loaders/load_cldr_likely_subtags.py +167 -0
- glfm-1.0.4/src/glfm/loaders/load_glottolog.py +79 -0
- glfm-1.0.4/src/glfm/loaders/load_iso_639.py +187 -0
- glfm-1.0.4/src/glfm/loaders/load_override_scripts.py +51 -0
- glfm-1.0.4/src/glfm/loaders/load_pos_stats.py +54 -0
- glfm-1.0.4/src/glfm/loaders/load_uralic_languages.py +70 -0
- glfm-1.0.4/src/glfm/loaders/load_wiktionary_languages.py +61 -0
- glfm-1.0.4/src/glfm/loaders/load_written_languages.py +66 -0
- glfm-1.0.4/src/glfm/logic/__init__.py +17 -0
- glfm-1.0.4/src/glfm/logic/build_bcp47.py +42 -0
- glfm-1.0.4/src/glfm/logic/build_extinct_json.py +97 -0
- glfm-1.0.4/src/glfm/logic/decide_default_region.py +46 -0
- glfm-1.0.4/src/glfm/logic/decide_default_script.py +89 -0
- glfm-1.0.4/src/glfm/logic/decide_fallback.py +37 -0
- glfm-1.0.4/src/glfm/logic/is_uralic.py +41 -0
- glfm-1.0.4/src/glfm/logic/resolve_cldr_key.py +35 -0
- glfm-1.0.4/src/glfm/logic/set_uralic_langs.py +34 -0
- glfm-1.0.4/src/glfm/models/__init__.py +11 -0
- glfm-1.0.4/src/glfm/models/iso_639_2.py +108 -0
- glfm-1.0.4/src/glfm/models/iso_639_3.py +140 -0
- glfm-1.0.4/src/glfm/models/language.py +72 -0
- glfm-1.0.4/src/glfm/paths.py +70 -0
- glfm-1.0.4/src/glfm/run_full_pipeline.py +215 -0
- glfm-1.0.4/src/glfm/tools/__init__.py +9 -0
- glfm-1.0.4/src/glfm/tools/all_language_tests.py +169 -0
- glfm-1.0.4/src/glfm/tools/build_consumer_dataset.py +169 -0
- glfm-1.0.4/src/glfm/tools/build_glottolog_json.py +302 -0
- glfm-1.0.4/src/glfm/tools/build_iso_data.py +213 -0
- glfm-1.0.4/src/glfm/tools/build_pos_stats.py +111 -0
- glfm-1.0.4/src/glfm/tools/compress_stdlib.py +125 -0
- glfm-1.0.4/src/glfm/tools/compute_nearest_languages.py +336 -0
- glfm-1.0.4/src/glfm/tools/convert_to_msgpack.py +112 -0
- glfm-1.0.4/src/glfm/tools/generate_iso_files.py +179 -0
- glfm-1.0.4/src/glfm/tools/generate_report.py +216 -0
- glfm-1.0.4/src/glfm/tools/parse_iso_files.py +249 -0
- glfm-1.0.4/src/glfm/tools/run_full_pipeline_test.py +129 -0
- glfm-1.0.4/src/glfm/tools/validate_bcp47.py +87 -0
- glfm-1.0.4/src/glfm/tools/validate_fallbacks.py +106 -0
- glfm-1.0.4/src/glfm/tools/validate_glottolog.py +109 -0
- glfm-1.0.4/src/glfm/tools/validate_iso_consistency.py +101 -0
- glfm-1.0.4/src/glfm/tools/validate_pos_stats.py +88 -0
- glfm-1.0.4/src/glfm/tools/visualize_fallbacks.py +143 -0
- glfm-1.0.4/src/glfm.egg-info/PKG-INFO +344 -0
- glfm-1.0.4/src/glfm.egg-info/SOURCES.txt +58 -0
- glfm-1.0.4/src/glfm.egg-info/dependency_links.txt +1 -0
- glfm-1.0.4/src/glfm.egg-info/requires.txt +7 -0
- glfm-1.0.4/src/glfm.egg-info/top_level.txt +1 -0
glfm-1.0.4/LICENCE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
Copyright (c) 2026 Tuomas Lähteenmäki
|
|
2
|
+
|
|
3
|
+
Licensed under the MIT License.
|
|
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.
|
glfm-1.0.4/PKG-INFO
ADDED
|
@@ -0,0 +1,344 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: glfm
|
|
3
|
+
Version: 1.0.4
|
|
4
|
+
Summary: A comprehensive JSON database mapping over 7,700 languages (ISO 639-3) to language families (ISO 639-5) for RSS tools and localization workflows.
|
|
5
|
+
Author: Tuomas Lähteenmäki
|
|
6
|
+
License-Expression: MIT
|
|
7
|
+
Project-URL: Homepage, https://codeberg.org/lahtis/GLFM
|
|
8
|
+
Project-URL: Repository, https://codeberg.org/lahtis/GLFM
|
|
9
|
+
Keywords: python,linux,localization,iso639-3,bcp47,language-mapping,nlp
|
|
10
|
+
Classifier: Programming Language :: Python :: 3
|
|
11
|
+
Classifier: Programming Language :: Python :: 3.9
|
|
12
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
13
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
14
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
15
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
16
|
+
Classifier: Operating System :: POSIX :: Linux
|
|
17
|
+
Classifier: Topic :: Text Processing :: Linguistic
|
|
18
|
+
Classifier: Topic :: Software Development :: Internationalization
|
|
19
|
+
Requires-Python: >=3.9
|
|
20
|
+
Description-Content-Type: text/markdown
|
|
21
|
+
License-File: LICENCE
|
|
22
|
+
Provides-Extra: dev
|
|
23
|
+
Requires-Dist: numpy>=1.26.0; extra == "dev"
|
|
24
|
+
Requires-Dist: requests>=2.28.0; extra == "dev"
|
|
25
|
+
Requires-Dist: msgpack>=1.0.5; extra == "dev"
|
|
26
|
+
Requires-Dist: graphviz>=0.20; extra == "dev"
|
|
27
|
+
Requires-Dist: lang2vec>=1.1.0; extra == "dev"
|
|
28
|
+
Dynamic: license-file
|
|
29
|
+
|
|
30
|
+
# Global Language Family Mapper (GLFM)
|
|
31
|
+
|
|
32
|
+
A modular, JSON-based language database and validation pipeline for over 7,900 languages (ISO 639-3), including Uralic/Finno-Ugric languages. Designed for RSS feeds, localization, and NLP workflows.
|
|
33
|
+
|
|
34
|
+
- **Author:** Tuomas Lähteenmäki
|
|
35
|
+
- **License:** MIT
|
|
36
|
+
- **Version:** 1.0.4
|
|
37
|
+
|
|
38
|
+
---
|
|
39
|
+
|
|
40
|
+

|
|
41
|
+

|
|
42
|
+

|
|
43
|
+
|
|
44
|
+
---
|
|
45
|
+
|
|
46
|
+
## Primary Links
|
|
47
|
+
|
|
48
|
+
- Canonical Repository (Codeberg): `https://codeberg.org/lahtis/GLFM`
|
|
49
|
+
- GitHub Mirror: `https://github.com/lahtis/GLFM`
|
|
50
|
+
|
|
51
|
+
---
|
|
52
|
+
|
|
53
|
+
## Features
|
|
54
|
+
|
|
55
|
+
- **7,900+ Languages:** Unified from ISO 639-1/2/3/5, Wikidata (Glottolog), CLDR, and POS statistics.
|
|
56
|
+
- **Nearest Language Neighbors:** Each written language includes typologically nearest languages based on URIEL/lang2vec features (syntax, phonology, inventory, family).
|
|
57
|
+
- **Accurate BCP-47 Tags:** Language, script, and region combined automatically.
|
|
58
|
+
- **Fallback Chains:** Automatically assigns fallback languages where applicable.
|
|
59
|
+
- **Uralic/Finno-Ugric Support:** Detailed mapping for Finnish, Karelian, Estonian, and related languages.
|
|
60
|
+
- **Validation Pipeline:** Full automated checks for ISO consistency, BCP-47 compliance, fallback correctness, POS stats, and Glottolog data.
|
|
61
|
+
- **Checkpoint/Resume Support:** Long-running nearest-language computations can be resumed automatically from a checkpoint.
|
|
62
|
+
|
|
63
|
+
---
|
|
64
|
+
|
|
65
|
+
## Directory Structure
|
|
66
|
+
```text
|
|
67
|
+
GLFM/
|
|
68
|
+
├── pyproject.toml
|
|
69
|
+
├── config.toml # Oletuskonfiguraatio
|
|
70
|
+
├── README.md
|
|
71
|
+
├── LICENCE
|
|
72
|
+
├── output/ # Pipeline-tuotokset (.gitignore)
|
|
73
|
+
│ ├── unified/ # unified _languages.json, languages _top20.json.gz
|
|
74
|
+
│ ├── validation/ # validation _report.md/html, errors
|
|
75
|
+
│ └── logs/
|
|
76
|
+
├── src/
|
|
77
|
+
│ └── glfm/
|
|
78
|
+
│ ├── _ _init _ _.py
|
|
79
|
+
│ ├── _version.py
|
|
80
|
+
│ ├── paths.py # Polut (cache, data, output)
|
|
81
|
+
│ ├── config.py # Konfiguraatio
|
|
82
|
+
│ ├── download.py # Datan lataus
|
|
83
|
+
│ ├── build _unified.py # Unified-tietokannan rakennus
|
|
84
|
+
│ ├── run _full _pipeline.py # Koko pipeline
|
|
85
|
+
│ ├── data/ # Sisäinen data (paketissa)
|
|
86
|
+
│ │ ├── override _scripts.json
|
|
87
|
+
│ │ └── uralic _languages.json
|
|
88
|
+
│ ├── loaders/ # Datalähteiden lataus
|
|
89
|
+
│ ├── logic/ # Logiikka (script, region, fallback, BCP-47)
|
|
90
|
+
│ ├── models/ # Datamallit (Language)
|
|
91
|
+
│ └── tools/ # Validaattorit, raportit, apuskriptit
|
|
92
|
+
└── venv/
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
> Note: Downloadable data (`iso_639_*.py`, `glottolog.json`, `cldr/`) lives in the cache (`~/.cache/glfm/data/`), not in the repo. Bundled data (`override_scripts.json`, `uralic_languages.json`) is shipped with the package (`src/glfm/data/`).
|
|
96
|
+
|
|
97
|
+
---
|
|
98
|
+
|
|
99
|
+
## Data Structure (`unified_languages.json`)
|
|
100
|
+
|
|
101
|
+
Each language is represented as a JSON object keyed by its ISO 639-3 code:
|
|
102
|
+
```text
|
|
103
|
+
"fin": {
|
|
104
|
+
"bcp47": "fi-Latn-FI",
|
|
105
|
+
"default _region": "FI",
|
|
106
|
+
"default _script": "Latn",
|
|
107
|
+
"distance _bases": [
|
|
108
|
+
"WALS",
|
|
109
|
+
"SSWL",
|
|
110
|
+
"PHOIBLE",
|
|
111
|
+
"Ethnologue",
|
|
112
|
+
"Glottolog"
|
|
113
|
+
],
|
|
114
|
+
"distance _source": "lang2vec / URIEL",
|
|
115
|
+
"distance _type": "fam",
|
|
116
|
+
"fallback": "fin",
|
|
117
|
+
"family": "Finnic",
|
|
118
|
+
"glottocode": "finn1318",
|
|
119
|
+
"glottolog": {
|
|
120
|
+
"glottocode": "finn1318",
|
|
121
|
+
"iso639 _3": "fin",
|
|
122
|
+
"family": "Finnic",
|
|
123
|
+
"macroarea": "",
|
|
124
|
+
"latitude": 62.0,
|
|
125
|
+
"longitude": 25.0,
|
|
126
|
+
"lineage": [ ],
|
|
127
|
+
"status": ""
|
|
128
|
+
},
|
|
129
|
+
"id": "fin",
|
|
130
|
+
"iso639 _1": "fi",
|
|
131
|
+
"iso639 _2B": "fin",
|
|
132
|
+
"iso639 _2T": "fin",
|
|
133
|
+
"iso639 _3": "fin",
|
|
134
|
+
"iso639 _5": "",
|
|
135
|
+
"language _type": "L",
|
|
136
|
+
"name": "Finnish",
|
|
137
|
+
"nearest _languages": [
|
|
138
|
+
{
|
|
139
|
+
"lang": "est",
|
|
140
|
+
"distance": 0.0003
|
|
141
|
+
},
|
|
142
|
+
{
|
|
143
|
+
"lang": "izh",
|
|
144
|
+
"distance": 0.0003
|
|
145
|
+
}
|
|
146
|
+
],
|
|
147
|
+
"official _name": "Finnish",
|
|
148
|
+
"pos _stats": {},
|
|
149
|
+
"uralicNLP": true,
|
|
150
|
+
"written": true,
|
|
151
|
+
"written _scripts": [
|
|
152
|
+
"Latn"
|
|
153
|
+
]
|
|
154
|
+
}
|
|
155
|
+
```
|
|
156
|
+
|
|
157
|
+
- `bcp47` is automatically generated: `lang[-Script][-Region]`.
|
|
158
|
+
- `fallback` is the default fallback language.
|
|
159
|
+
- `uralicNLP` is true if the language belongs to the Uralic/Finno-Ugric family.
|
|
160
|
+
- `written_scripts` lists all known writing scripts.
|
|
161
|
+
- `nearest_languages` ranks typologically nearest written languages by distance (up to 100 max _neighbors).
|
|
162
|
+
- `language_type` is SIL Language Type (L = Living, E = Extinct, H = Historical, A = Ancient, C = Constructed).
|
|
163
|
+
- `family` is Glottolog family name (e.g. "Finnic"), not an ISO 639-5 code.
|
|
164
|
+
- `glottocode` is Glottolog language code (e.g. "finn1318").
|
|
165
|
+
|
|
166
|
+
---
|
|
167
|
+
|
|
168
|
+
## Pipeline Overview
|
|
169
|
+
|
|
170
|
+
The pipeline is fully automated:
|
|
171
|
+
|
|
172
|
+
generate ISO → build glottolog → build unified → compute nearest → build consumer → validate → report → visualize
|
|
173
|
+
|
|
174
|
+
| Step | Module | Description |
|
|
175
|
+
| :---- | :---- | :---- |
|
|
176
|
+
| generate | `glfm.tools.generate_iso_files` | Download ISO 639 sources |
|
|
177
|
+
| glottolog | `glfm.tools.build_glottolog_json` | Fetch Glottolog metadata (Wikidata) |
|
|
178
|
+
| build | `glfm.build_unified` | Build unified database |
|
|
179
|
+
| compute | `glfm.tools.compute_nearest_languages` | Compute neighbors (lang2vec) |
|
|
180
|
+
| consumer | `glfm.tools.build_consumer_dataset` | Build consumer dataset (top-20) |
|
|
181
|
+
| bcp47 | `glfm.tools.validate_bcp47` | Validate BCP-47 |
|
|
182
|
+
| fallbacks | `glfm.tools.validate_fallbacks` | Validate fallbacks |
|
|
183
|
+
| iso | `glfm.tools.validate_iso_consistency` | Validate ISO codes |
|
|
184
|
+
| pos | `glfm.tools.validate_pos_stats` | Validate POS statistics |
|
|
185
|
+
| glotto | `glfm.tools.validate_glottolog` | Validate Glottolog |
|
|
186
|
+
| report | `glfm.tools.generate_report` | Generate reports |
|
|
187
|
+
| viz | `glfm.tools.visualize_fallbacks` | Visualize fallbacks (optional) |
|
|
188
|
+
|
|
189
|
+
---
|
|
190
|
+
|
|
191
|
+
## CLI
|
|
192
|
+
|
|
193
|
+
# Full pipeline
|
|
194
|
+
```bash
|
|
195
|
+
python3 -m glfm.run_full_pipeline
|
|
196
|
+
```
|
|
197
|
+
|
|
198
|
+
# Skip heavy neighbor computation
|
|
199
|
+
```bash
|
|
200
|
+
python3 -m glfm.run_full_pipeline --skip compute
|
|
201
|
+
```
|
|
202
|
+
|
|
203
|
+
# Run only selected steps
|
|
204
|
+
```bash
|
|
205
|
+
python3 -m glfm.run_full_pipeline --only build bcp47
|
|
206
|
+
```
|
|
207
|
+
|
|
208
|
+
# List steps
|
|
209
|
+
```bash
|
|
210
|
+
python3 -m glfm.run_full_pipeline --list
|
|
211
|
+
```
|
|
212
|
+
---
|
|
213
|
+
|
|
214
|
+
## Configuration
|
|
215
|
+
|
|
216
|
+
`config.toml` (repo root) contains default values. Users can override:
|
|
217
|
+
|
|
218
|
+
- `~/.config/glfm/config.toml`
|
|
219
|
+
- Environment variables: `GLFM_DATA_DIR`, `GLFM_CACHE_DIR`, `GLFM_OUTPUT_DIR`, `GLFM_ISO_639_3_URL`, etc.
|
|
220
|
+
|
|
221
|
+
Example:
|
|
222
|
+
```python
|
|
223
|
+
[sources.iso _639 _3 ]
|
|
224
|
+
|
|
225
|
+
url = "https ://iso639-3.sil.org/sites/iso639-3/files/downloads/iso-639-3.tab"
|
|
226
|
+
|
|
227
|
+
[sources.cldr ]
|
|
228
|
+
|
|
229
|
+
version = "48.0.0"
|
|
230
|
+
|
|
231
|
+
[sources.wikidata ]
|
|
232
|
+
|
|
233
|
+
endpoint = "https ://query.wikidata.org/sparql"
|
|
234
|
+
|
|
235
|
+
[paths ]
|
|
236
|
+
|
|
237
|
+
data _dir = "" # empty = ~/.cache/glfm/data
|
|
238
|
+
|
|
239
|
+
cache _dir = "" # empty = ~/.cache/glfm
|
|
240
|
+
```
|
|
241
|
+
---
|
|
242
|
+
|
|
243
|
+
## Quick Start
|
|
244
|
+
|
|
245
|
+
### 1 . Download data
|
|
246
|
+
```bash
|
|
247
|
+
python3 -m glfm.download
|
|
248
|
+
```
|
|
249
|
+
Or generate data from sources:
|
|
250
|
+
```bash
|
|
251
|
+
python3 -m glfm.run _full _pipeline --only generate glottolog
|
|
252
|
+
```
|
|
253
|
+
### 2 . Run the full pipeline
|
|
254
|
+
```bash
|
|
255
|
+
python3 -m glfm.run _full _pipeline
|
|
256
|
+
```
|
|
257
|
+
### 3 . Access data in Python
|
|
258
|
+
|
|
259
|
+
```python
|
|
260
|
+
import json
|
|
261
|
+
|
|
262
|
+
from pathlib import Path
|
|
263
|
+
|
|
264
|
+
unified = Path("output/unified/unified _languages.json")
|
|
265
|
+
with unified.open() as f:
|
|
266
|
+
languages = json.load(f)
|
|
267
|
+
|
|
268
|
+
fin = languages ["fin" ]
|
|
269
|
+
print(fin ["bcp47" ]) # fi-Latn-FI
|
|
270
|
+
print(fin ["family" ]) # Finnic
|
|
271
|
+
print(fin ["glottocode" ]) # finn1318
|
|
272
|
+
print(fin ["uralicNLP" ]) # True
|
|
273
|
+
print(fin ["nearest _languages" ] [:5 ]) # Top 5 nearest languages
|
|
274
|
+
```
|
|
275
|
+
|
|
276
|
+
### 4 . Consumer dataset (top-20 neighbors)
|
|
277
|
+
|
|
278
|
+
```python
|
|
279
|
+
import gzip
|
|
280
|
+
import json
|
|
281
|
+
|
|
282
|
+
with gzip.open("output/unified/languages _top20.json.gz", "rt") as f:
|
|
283
|
+
languages = json.load(f)
|
|
284
|
+
|
|
285
|
+
fin = languages ["fin" ]
|
|
286
|
+
for nb in fin ["nearest _languages" ] [:10 ]:
|
|
287
|
+
print(f"{nb ['lang' ]}: {nb ['distance' ]:.4f}")
|
|
288
|
+
```
|
|
289
|
+
|
|
290
|
+
---
|
|
291
|
+
|
|
292
|
+
## Requirements
|
|
293
|
+
|
|
294
|
+
- **Python 3.9+**
|
|
295
|
+
- **Core dependencies:** none (pure stdlib)
|
|
296
|
+
- **Dev dependencies:** `numpy`, `requests`, `msgpack`, `lang2vec`, `graphviz`, `pytest`
|
|
297
|
+
|
|
298
|
+
### Installation:
|
|
299
|
+
```bash
|
|
300
|
+
git clone https ://codeberg.org/lahtis/GLFM.git
|
|
301
|
+
|
|
302
|
+
cd GLFM
|
|
303
|
+
|
|
304
|
+
pip install -e ". [dev ]"
|
|
305
|
+
```
|
|
306
|
+
---
|
|
307
|
+
|
|
308
|
+
## Data Sources & Acknowledgments
|
|
309
|
+
|
|
310
|
+
- **Glottolog:** Hammarström, Harald & Forkel, Robert & Haspelmath, Martin & Bank, Sebastian. Glottolog. (glottolog.org) – fetched via Wikidata SPARQL.
|
|
311
|
+
- **URIEL / lang2vec:** Typological vector representations.
|
|
312
|
+
- **ISO 639:** Language code standards (ISO 639-1, 639-2, 639-3, 639-5).
|
|
313
|
+
- **CLDR / Wiktionary:** Locale display names, scripts.
|
|
314
|
+
|
|
315
|
+
---
|
|
316
|
+
|
|
317
|
+
## Contributing & Issues
|
|
318
|
+
|
|
319
|
+
[https ://codeberg.org/lahtis/GLFM](https://codeberg.org/lahtis/GLFM)
|
|
320
|
+
|
|
321
|
+
---
|
|
322
|
+
|
|
323
|
+
## License
|
|
324
|
+
|
|
325
|
+
Copyright © 2026 Tuomas Lähteenmäki
|
|
326
|
+
MIT License. See LICENSE for details.
|
|
327
|
+
|
|
328
|
+
---
|
|
329
|
+
|
|
330
|
+
## Key changes
|
|
331
|
+
|
|
332
|
+
| # | Section | Change |
|
|
333
|
+
| :---- | :---- | :---- |
|
|
334
|
+
| 1 | Python version | `3.8+` → **`3.9+`** |
|
|
335
|
+
| 2 | Directory Structure | **`src/glfm/` layout** |
|
|
336
|
+
| 3 | Data Structure | **`family: "Finnic"`**, `glottocode: "finn1318"`, `language_type: "L"` |
|
|
337
|
+
| 4 | `nearest_languages` | 5 → **100** (max) |
|
|
338
|
+
| 5 | Pipeline Overview | **12 steps** (incl. `glottolog`, `consumer`) |
|
|
339
|
+
| 6 | CLI | **`python3 -m glfm.run_full_pipeline`** |
|
|
340
|
+
| 7 | Configuration | **`config.toml`** + env vars |
|
|
341
|
+
| 8 | Requirements | **No core dependencies** (pure stdlib) |
|
|
342
|
+
| 9 | `build_top5.py` | **`build_consumer_dataset.py`** |
|
|
343
|
+
| 10 | "Glottolog future work" | **Glottolog works** (Wikidata) |
|
|
344
|
+
|
glfm-1.0.4/README.md
ADDED
|
@@ -0,0 +1,315 @@
|
|
|
1
|
+
# Global Language Family Mapper (GLFM)
|
|
2
|
+
|
|
3
|
+
A modular, JSON-based language database and validation pipeline for over 7,900 languages (ISO 639-3), including Uralic/Finno-Ugric languages. Designed for RSS feeds, localization, and NLP workflows.
|
|
4
|
+
|
|
5
|
+
- **Author:** Tuomas Lähteenmäki
|
|
6
|
+
- **License:** MIT
|
|
7
|
+
- **Version:** 1.0.4
|
|
8
|
+
|
|
9
|
+
---
|
|
10
|
+
|
|
11
|
+

|
|
12
|
+

|
|
13
|
+

|
|
14
|
+
|
|
15
|
+
---
|
|
16
|
+
|
|
17
|
+
## Primary Links
|
|
18
|
+
|
|
19
|
+
- Canonical Repository (Codeberg): `https://codeberg.org/lahtis/GLFM`
|
|
20
|
+
- GitHub Mirror: `https://github.com/lahtis/GLFM`
|
|
21
|
+
|
|
22
|
+
---
|
|
23
|
+
|
|
24
|
+
## Features
|
|
25
|
+
|
|
26
|
+
- **7,900+ Languages:** Unified from ISO 639-1/2/3/5, Wikidata (Glottolog), CLDR, and POS statistics.
|
|
27
|
+
- **Nearest Language Neighbors:** Each written language includes typologically nearest languages based on URIEL/lang2vec features (syntax, phonology, inventory, family).
|
|
28
|
+
- **Accurate BCP-47 Tags:** Language, script, and region combined automatically.
|
|
29
|
+
- **Fallback Chains:** Automatically assigns fallback languages where applicable.
|
|
30
|
+
- **Uralic/Finno-Ugric Support:** Detailed mapping for Finnish, Karelian, Estonian, and related languages.
|
|
31
|
+
- **Validation Pipeline:** Full automated checks for ISO consistency, BCP-47 compliance, fallback correctness, POS stats, and Glottolog data.
|
|
32
|
+
- **Checkpoint/Resume Support:** Long-running nearest-language computations can be resumed automatically from a checkpoint.
|
|
33
|
+
|
|
34
|
+
---
|
|
35
|
+
|
|
36
|
+
## Directory Structure
|
|
37
|
+
```text
|
|
38
|
+
GLFM/
|
|
39
|
+
├── pyproject.toml
|
|
40
|
+
├── config.toml # Oletuskonfiguraatio
|
|
41
|
+
├── README.md
|
|
42
|
+
├── LICENCE
|
|
43
|
+
├── output/ # Pipeline-tuotokset (.gitignore)
|
|
44
|
+
│ ├── unified/ # unified _languages.json, languages _top20.json.gz
|
|
45
|
+
│ ├── validation/ # validation _report.md/html, errors
|
|
46
|
+
│ └── logs/
|
|
47
|
+
├── src/
|
|
48
|
+
│ └── glfm/
|
|
49
|
+
│ ├── _ _init _ _.py
|
|
50
|
+
│ ├── _version.py
|
|
51
|
+
│ ├── paths.py # Polut (cache, data, output)
|
|
52
|
+
│ ├── config.py # Konfiguraatio
|
|
53
|
+
│ ├── download.py # Datan lataus
|
|
54
|
+
│ ├── build _unified.py # Unified-tietokannan rakennus
|
|
55
|
+
│ ├── run _full _pipeline.py # Koko pipeline
|
|
56
|
+
│ ├── data/ # Sisäinen data (paketissa)
|
|
57
|
+
│ │ ├── override _scripts.json
|
|
58
|
+
│ │ └── uralic _languages.json
|
|
59
|
+
│ ├── loaders/ # Datalähteiden lataus
|
|
60
|
+
│ ├── logic/ # Logiikka (script, region, fallback, BCP-47)
|
|
61
|
+
│ ├── models/ # Datamallit (Language)
|
|
62
|
+
│ └── tools/ # Validaattorit, raportit, apuskriptit
|
|
63
|
+
└── venv/
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
> Note: Downloadable data (`iso_639_*.py`, `glottolog.json`, `cldr/`) lives in the cache (`~/.cache/glfm/data/`), not in the repo. Bundled data (`override_scripts.json`, `uralic_languages.json`) is shipped with the package (`src/glfm/data/`).
|
|
67
|
+
|
|
68
|
+
---
|
|
69
|
+
|
|
70
|
+
## Data Structure (`unified_languages.json`)
|
|
71
|
+
|
|
72
|
+
Each language is represented as a JSON object keyed by its ISO 639-3 code:
|
|
73
|
+
```text
|
|
74
|
+
"fin": {
|
|
75
|
+
"bcp47": "fi-Latn-FI",
|
|
76
|
+
"default _region": "FI",
|
|
77
|
+
"default _script": "Latn",
|
|
78
|
+
"distance _bases": [
|
|
79
|
+
"WALS",
|
|
80
|
+
"SSWL",
|
|
81
|
+
"PHOIBLE",
|
|
82
|
+
"Ethnologue",
|
|
83
|
+
"Glottolog"
|
|
84
|
+
],
|
|
85
|
+
"distance _source": "lang2vec / URIEL",
|
|
86
|
+
"distance _type": "fam",
|
|
87
|
+
"fallback": "fin",
|
|
88
|
+
"family": "Finnic",
|
|
89
|
+
"glottocode": "finn1318",
|
|
90
|
+
"glottolog": {
|
|
91
|
+
"glottocode": "finn1318",
|
|
92
|
+
"iso639 _3": "fin",
|
|
93
|
+
"family": "Finnic",
|
|
94
|
+
"macroarea": "",
|
|
95
|
+
"latitude": 62.0,
|
|
96
|
+
"longitude": 25.0,
|
|
97
|
+
"lineage": [ ],
|
|
98
|
+
"status": ""
|
|
99
|
+
},
|
|
100
|
+
"id": "fin",
|
|
101
|
+
"iso639 _1": "fi",
|
|
102
|
+
"iso639 _2B": "fin",
|
|
103
|
+
"iso639 _2T": "fin",
|
|
104
|
+
"iso639 _3": "fin",
|
|
105
|
+
"iso639 _5": "",
|
|
106
|
+
"language _type": "L",
|
|
107
|
+
"name": "Finnish",
|
|
108
|
+
"nearest _languages": [
|
|
109
|
+
{
|
|
110
|
+
"lang": "est",
|
|
111
|
+
"distance": 0.0003
|
|
112
|
+
},
|
|
113
|
+
{
|
|
114
|
+
"lang": "izh",
|
|
115
|
+
"distance": 0.0003
|
|
116
|
+
}
|
|
117
|
+
],
|
|
118
|
+
"official _name": "Finnish",
|
|
119
|
+
"pos _stats": {},
|
|
120
|
+
"uralicNLP": true,
|
|
121
|
+
"written": true,
|
|
122
|
+
"written _scripts": [
|
|
123
|
+
"Latn"
|
|
124
|
+
]
|
|
125
|
+
}
|
|
126
|
+
```
|
|
127
|
+
|
|
128
|
+
- `bcp47` is automatically generated: `lang[-Script][-Region]`.
|
|
129
|
+
- `fallback` is the default fallback language.
|
|
130
|
+
- `uralicNLP` is true if the language belongs to the Uralic/Finno-Ugric family.
|
|
131
|
+
- `written_scripts` lists all known writing scripts.
|
|
132
|
+
- `nearest_languages` ranks typologically nearest written languages by distance (up to 100 max _neighbors).
|
|
133
|
+
- `language_type` is SIL Language Type (L = Living, E = Extinct, H = Historical, A = Ancient, C = Constructed).
|
|
134
|
+
- `family` is Glottolog family name (e.g. "Finnic"), not an ISO 639-5 code.
|
|
135
|
+
- `glottocode` is Glottolog language code (e.g. "finn1318").
|
|
136
|
+
|
|
137
|
+
---
|
|
138
|
+
|
|
139
|
+
## Pipeline Overview
|
|
140
|
+
|
|
141
|
+
The pipeline is fully automated:
|
|
142
|
+
|
|
143
|
+
generate ISO → build glottolog → build unified → compute nearest → build consumer → validate → report → visualize
|
|
144
|
+
|
|
145
|
+
| Step | Module | Description |
|
|
146
|
+
| :---- | :---- | :---- |
|
|
147
|
+
| generate | `glfm.tools.generate_iso_files` | Download ISO 639 sources |
|
|
148
|
+
| glottolog | `glfm.tools.build_glottolog_json` | Fetch Glottolog metadata (Wikidata) |
|
|
149
|
+
| build | `glfm.build_unified` | Build unified database |
|
|
150
|
+
| compute | `glfm.tools.compute_nearest_languages` | Compute neighbors (lang2vec) |
|
|
151
|
+
| consumer | `glfm.tools.build_consumer_dataset` | Build consumer dataset (top-20) |
|
|
152
|
+
| bcp47 | `glfm.tools.validate_bcp47` | Validate BCP-47 |
|
|
153
|
+
| fallbacks | `glfm.tools.validate_fallbacks` | Validate fallbacks |
|
|
154
|
+
| iso | `glfm.tools.validate_iso_consistency` | Validate ISO codes |
|
|
155
|
+
| pos | `glfm.tools.validate_pos_stats` | Validate POS statistics |
|
|
156
|
+
| glotto | `glfm.tools.validate_glottolog` | Validate Glottolog |
|
|
157
|
+
| report | `glfm.tools.generate_report` | Generate reports |
|
|
158
|
+
| viz | `glfm.tools.visualize_fallbacks` | Visualize fallbacks (optional) |
|
|
159
|
+
|
|
160
|
+
---
|
|
161
|
+
|
|
162
|
+
## CLI
|
|
163
|
+
|
|
164
|
+
# Full pipeline
|
|
165
|
+
```bash
|
|
166
|
+
python3 -m glfm.run_full_pipeline
|
|
167
|
+
```
|
|
168
|
+
|
|
169
|
+
# Skip heavy neighbor computation
|
|
170
|
+
```bash
|
|
171
|
+
python3 -m glfm.run_full_pipeline --skip compute
|
|
172
|
+
```
|
|
173
|
+
|
|
174
|
+
# Run only selected steps
|
|
175
|
+
```bash
|
|
176
|
+
python3 -m glfm.run_full_pipeline --only build bcp47
|
|
177
|
+
```
|
|
178
|
+
|
|
179
|
+
# List steps
|
|
180
|
+
```bash
|
|
181
|
+
python3 -m glfm.run_full_pipeline --list
|
|
182
|
+
```
|
|
183
|
+
---
|
|
184
|
+
|
|
185
|
+
## Configuration
|
|
186
|
+
|
|
187
|
+
`config.toml` (repo root) contains default values. Users can override:
|
|
188
|
+
|
|
189
|
+
- `~/.config/glfm/config.toml`
|
|
190
|
+
- Environment variables: `GLFM_DATA_DIR`, `GLFM_CACHE_DIR`, `GLFM_OUTPUT_DIR`, `GLFM_ISO_639_3_URL`, etc.
|
|
191
|
+
|
|
192
|
+
Example:
|
|
193
|
+
```python
|
|
194
|
+
[sources.iso _639 _3 ]
|
|
195
|
+
|
|
196
|
+
url = "https ://iso639-3.sil.org/sites/iso639-3/files/downloads/iso-639-3.tab"
|
|
197
|
+
|
|
198
|
+
[sources.cldr ]
|
|
199
|
+
|
|
200
|
+
version = "48.0.0"
|
|
201
|
+
|
|
202
|
+
[sources.wikidata ]
|
|
203
|
+
|
|
204
|
+
endpoint = "https ://query.wikidata.org/sparql"
|
|
205
|
+
|
|
206
|
+
[paths ]
|
|
207
|
+
|
|
208
|
+
data _dir = "" # empty = ~/.cache/glfm/data
|
|
209
|
+
|
|
210
|
+
cache _dir = "" # empty = ~/.cache/glfm
|
|
211
|
+
```
|
|
212
|
+
---
|
|
213
|
+
|
|
214
|
+
## Quick Start
|
|
215
|
+
|
|
216
|
+
### 1 . Download data
|
|
217
|
+
```bash
|
|
218
|
+
python3 -m glfm.download
|
|
219
|
+
```
|
|
220
|
+
Or generate data from sources:
|
|
221
|
+
```bash
|
|
222
|
+
python3 -m glfm.run _full _pipeline --only generate glottolog
|
|
223
|
+
```
|
|
224
|
+
### 2 . Run the full pipeline
|
|
225
|
+
```bash
|
|
226
|
+
python3 -m glfm.run _full _pipeline
|
|
227
|
+
```
|
|
228
|
+
### 3 . Access data in Python
|
|
229
|
+
|
|
230
|
+
```python
|
|
231
|
+
import json
|
|
232
|
+
|
|
233
|
+
from pathlib import Path
|
|
234
|
+
|
|
235
|
+
unified = Path("output/unified/unified _languages.json")
|
|
236
|
+
with unified.open() as f:
|
|
237
|
+
languages = json.load(f)
|
|
238
|
+
|
|
239
|
+
fin = languages ["fin" ]
|
|
240
|
+
print(fin ["bcp47" ]) # fi-Latn-FI
|
|
241
|
+
print(fin ["family" ]) # Finnic
|
|
242
|
+
print(fin ["glottocode" ]) # finn1318
|
|
243
|
+
print(fin ["uralicNLP" ]) # True
|
|
244
|
+
print(fin ["nearest _languages" ] [:5 ]) # Top 5 nearest languages
|
|
245
|
+
```
|
|
246
|
+
|
|
247
|
+
### 4 . Consumer dataset (top-20 neighbors)
|
|
248
|
+
|
|
249
|
+
```python
|
|
250
|
+
import gzip
|
|
251
|
+
import json
|
|
252
|
+
|
|
253
|
+
with gzip.open("output/unified/languages _top20.json.gz", "rt") as f:
|
|
254
|
+
languages = json.load(f)
|
|
255
|
+
|
|
256
|
+
fin = languages ["fin" ]
|
|
257
|
+
for nb in fin ["nearest _languages" ] [:10 ]:
|
|
258
|
+
print(f"{nb ['lang' ]}: {nb ['distance' ]:.4f}")
|
|
259
|
+
```
|
|
260
|
+
|
|
261
|
+
---
|
|
262
|
+
|
|
263
|
+
## Requirements
|
|
264
|
+
|
|
265
|
+
- **Python 3.9+**
|
|
266
|
+
- **Core dependencies:** none (pure stdlib)
|
|
267
|
+
- **Dev dependencies:** `numpy`, `requests`, `msgpack`, `lang2vec`, `graphviz`, `pytest`
|
|
268
|
+
|
|
269
|
+
### Installation:
|
|
270
|
+
```bash
|
|
271
|
+
git clone https ://codeberg.org/lahtis/GLFM.git
|
|
272
|
+
|
|
273
|
+
cd GLFM
|
|
274
|
+
|
|
275
|
+
pip install -e ". [dev ]"
|
|
276
|
+
```
|
|
277
|
+
---
|
|
278
|
+
|
|
279
|
+
## Data Sources & Acknowledgments
|
|
280
|
+
|
|
281
|
+
- **Glottolog:** Hammarström, Harald & Forkel, Robert & Haspelmath, Martin & Bank, Sebastian. Glottolog. (glottolog.org) – fetched via Wikidata SPARQL.
|
|
282
|
+
- **URIEL / lang2vec:** Typological vector representations.
|
|
283
|
+
- **ISO 639:** Language code standards (ISO 639-1, 639-2, 639-3, 639-5).
|
|
284
|
+
- **CLDR / Wiktionary:** Locale display names, scripts.
|
|
285
|
+
|
|
286
|
+
---
|
|
287
|
+
|
|
288
|
+
## Contributing & Issues
|
|
289
|
+
|
|
290
|
+
[https ://codeberg.org/lahtis/GLFM](https://codeberg.org/lahtis/GLFM)
|
|
291
|
+
|
|
292
|
+
---
|
|
293
|
+
|
|
294
|
+
## License
|
|
295
|
+
|
|
296
|
+
Copyright © 2026 Tuomas Lähteenmäki
|
|
297
|
+
MIT License. See LICENSE for details.
|
|
298
|
+
|
|
299
|
+
---
|
|
300
|
+
|
|
301
|
+
## Key changes
|
|
302
|
+
|
|
303
|
+
| # | Section | Change |
|
|
304
|
+
| :---- | :---- | :---- |
|
|
305
|
+
| 1 | Python version | `3.8+` → **`3.9+`** |
|
|
306
|
+
| 2 | Directory Structure | **`src/glfm/` layout** |
|
|
307
|
+
| 3 | Data Structure | **`family: "Finnic"`**, `glottocode: "finn1318"`, `language_type: "L"` |
|
|
308
|
+
| 4 | `nearest_languages` | 5 → **100** (max) |
|
|
309
|
+
| 5 | Pipeline Overview | **12 steps** (incl. `glottolog`, `consumer`) |
|
|
310
|
+
| 6 | CLI | **`python3 -m glfm.run_full_pipeline`** |
|
|
311
|
+
| 7 | Configuration | **`config.toml`** + env vars |
|
|
312
|
+
| 8 | Requirements | **No core dependencies** (pure stdlib) |
|
|
313
|
+
| 9 | `build_top5.py` | **`build_consumer_dataset.py`** |
|
|
314
|
+
| 10 | "Glottolog future work" | **Glottolog works** (Wikidata) |
|
|
315
|
+
|