ngano 0.1.0__py3-none-any.whl

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.
ngano/__init__.py ADDED
@@ -0,0 +1,92 @@
1
+ """ngano: an open catalogue and streaming loader for African-language speech data.
2
+
3
+ ngano (Shona: folk stories, the oral tradition) catalogues speech and text
4
+ corpora for African languages and streams many of them through one canonical
5
+ row schema, so a single loop can read across datasets that agree on nothing.
6
+
7
+ The catalogue ships inside the package, so this works offline and without a
8
+ Hugging Face token:
9
+
10
+ >>> from ngano import Catalogue
11
+ >>> cat = Catalogue()
12
+ >>> shona = cat.datasets(language="sna", commercial=True, task="ASR")
13
+
14
+ Languages are BCP 47 tags whose primary subtag is an ISO 639-3 code, so Shona is
15
+ ``sna`` and Nigerian English is ``eng-NG``. A filter also accepts a bare code or
16
+ any catalogued name, for example ``isiZulu``, and resolves it to a tag.
17
+
18
+ Streaming needs the network, but never materialises a dataset::
19
+
20
+ from ngano import load
21
+ stream = load(language=["sna", "nde"], commercial=True, limit=100)
22
+ for row in stream:
23
+ print(row.transcript, row.duration_s)
24
+
25
+ Catalogue data is CC-BY-4.0, the code is MIT. Figures are reproduced as each
26
+ source published them, and self-reported claims of 20,000 hours or more are
27
+ flagged in the catalogue and excluded from every total.
28
+ """
29
+
30
+ from __future__ import annotations
31
+
32
+ from .auth import resolve_token
33
+ from .catalogue import DEFAULT_API_BASE, Catalogue, default_catalogue
34
+ from .errors import (
35
+ CatalogueError,
36
+ DatasetNotFoundError,
37
+ GatedDatasetError,
38
+ LoaderError,
39
+ MissingDependencyError,
40
+ NganoError,
41
+ )
42
+ from .filters import Filter
43
+ from .languages import (
44
+ LanguageCode,
45
+ LanguageRegistry,
46
+ canonicalise_tag,
47
+ default_registry,
48
+ resolve_language,
49
+ resolve_languages,
50
+ slugify_name,
51
+ )
52
+ from .loader import INTERLEAVE_STRATEGIES, Stream, load, load_dataset
53
+ from .mapping import ColumnPlan, FieldMap, build_row, normalise_column
54
+ from .models import AudioRef, CountryRecord, DatasetRecord, LanguageRecord, Row
55
+
56
+ #: The installed package version, following semantic versioning.
57
+ __version__ = "0.1.0"
58
+
59
+ __all__ = [
60
+ "AudioRef",
61
+ "Catalogue",
62
+ "CatalogueError",
63
+ "ColumnPlan",
64
+ "CountryRecord",
65
+ "DEFAULT_API_BASE",
66
+ "DatasetNotFoundError",
67
+ "DatasetRecord",
68
+ "FieldMap",
69
+ "Filter",
70
+ "GatedDatasetError",
71
+ "INTERLEAVE_STRATEGIES",
72
+ "LanguageCode",
73
+ "LanguageRecord",
74
+ "LanguageRegistry",
75
+ "LoaderError",
76
+ "MissingDependencyError",
77
+ "NganoError",
78
+ "Row",
79
+ "Stream",
80
+ "__version__",
81
+ "build_row",
82
+ "canonicalise_tag",
83
+ "default_catalogue",
84
+ "default_registry",
85
+ "load",
86
+ "load_dataset",
87
+ "normalise_column",
88
+ "resolve_language",
89
+ "resolve_languages",
90
+ "resolve_token",
91
+ "slugify_name",
92
+ ]
ngano/auth.py ADDED
@@ -0,0 +1,41 @@
1
+ """Hugging Face token resolution.
2
+
3
+ ngano itself needs no credentials: the catalogue is public and the API is
4
+ unauthenticated. A token is only ever used when streaming a gated Hugging Face
5
+ dataset.
6
+ """
7
+
8
+ from __future__ import annotations
9
+
10
+ import os
11
+ from typing import Optional
12
+
13
+ __all__ = ["resolve_token", "TOKEN_ENV_VARS"]
14
+
15
+ #: Environment variables checked, in order, when no token is passed.
16
+ TOKEN_ENV_VARS = ("HF_TOKEN", "HUGGING_FACE_HUB_TOKEN")
17
+
18
+
19
+ def resolve_token(explicit: Optional[str] = None) -> Optional[str]:
20
+ """Resolve the Hugging Face token to use.
21
+
22
+ The order is: the explicit argument, then ``HF_TOKEN``, then
23
+ ``HUGGING_FACE_HUB_TOKEN``, then anonymous access.
24
+
25
+ Args:
26
+ explicit: A token passed directly by the caller.
27
+
28
+ Returns:
29
+ The token, or ``None`` for anonymous access.
30
+
31
+ Example:
32
+ >>> resolve_token("hf_abc")
33
+ 'hf_abc'
34
+ """
35
+ if explicit:
36
+ return explicit.strip() or None
37
+ for name in TOKEN_ENV_VARS:
38
+ value = os.environ.get(name)
39
+ if value and value.strip():
40
+ return value.strip()
41
+ return None