caul-core 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.
- caul_core-0.1.0/.gitignore +213 -0
- caul_core-0.1.0/.python-version +1 -0
- caul_core-0.1.0/PKG-INFO +13 -0
- caul_core-0.1.0/README.md +3 -0
- caul_core-0.1.0/caul_core/__init__.py +0 -0
- caul_core-0.1.0/caul_core/asr_pipeline.py +77 -0
- caul_core-0.1.0/caul_core/config.py +165 -0
- caul_core-0.1.0/caul_core/constants.py +178 -0
- caul_core-0.1.0/caul_core/objects.py +246 -0
- caul_core-0.1.0/pyproject.toml +30 -0
- caul_core-0.1.0/uv.lock +211 -0
|
@@ -0,0 +1,213 @@
|
|
|
1
|
+
# Byte-compiled / optimized / DLL files
|
|
2
|
+
__pycache__/
|
|
3
|
+
*.py[codz]
|
|
4
|
+
*$py.class
|
|
5
|
+
|
|
6
|
+
# C extensions
|
|
7
|
+
*.so
|
|
8
|
+
|
|
9
|
+
# Models
|
|
10
|
+
.models/
|
|
11
|
+
|
|
12
|
+
# Distribution / packaging
|
|
13
|
+
.Python
|
|
14
|
+
build/
|
|
15
|
+
develop-eggs/
|
|
16
|
+
dist/
|
|
17
|
+
downloads/
|
|
18
|
+
eggs/
|
|
19
|
+
.eggs/
|
|
20
|
+
lib/
|
|
21
|
+
lib64/
|
|
22
|
+
parts/
|
|
23
|
+
sdist/
|
|
24
|
+
var/
|
|
25
|
+
wheels/
|
|
26
|
+
share/python-wheels/
|
|
27
|
+
*.egg-info/
|
|
28
|
+
.installed.cfg
|
|
29
|
+
*.egg
|
|
30
|
+
MANIFEST
|
|
31
|
+
|
|
32
|
+
# PyInstaller
|
|
33
|
+
# Usually these files are written by a python script from a template
|
|
34
|
+
# before PyInstaller builds the exe, so as to inject date/other infos into it.
|
|
35
|
+
*.manifest
|
|
36
|
+
*.spec
|
|
37
|
+
|
|
38
|
+
# Installer logs
|
|
39
|
+
pip-log.txt
|
|
40
|
+
pip-delete-this-directory.txt
|
|
41
|
+
|
|
42
|
+
# Unit test / coverage reports
|
|
43
|
+
htmlcov/
|
|
44
|
+
.tox/
|
|
45
|
+
.nox/
|
|
46
|
+
.coverage
|
|
47
|
+
.coverage.*
|
|
48
|
+
.cache
|
|
49
|
+
nosetests.xml
|
|
50
|
+
coverage.xml
|
|
51
|
+
*.cover
|
|
52
|
+
*.py.cover
|
|
53
|
+
.hypothesis/
|
|
54
|
+
.pytest_cache/
|
|
55
|
+
cover/
|
|
56
|
+
|
|
57
|
+
# Translations
|
|
58
|
+
*.mo
|
|
59
|
+
*.pot
|
|
60
|
+
|
|
61
|
+
# Django stuff:
|
|
62
|
+
*.log
|
|
63
|
+
local_settings.py
|
|
64
|
+
db.sqlite3
|
|
65
|
+
db.sqlite3-journal
|
|
66
|
+
|
|
67
|
+
# Flask stuff:
|
|
68
|
+
instance/
|
|
69
|
+
.webassets-cache
|
|
70
|
+
|
|
71
|
+
# Scrapy stuff:
|
|
72
|
+
.scrapy
|
|
73
|
+
|
|
74
|
+
# Sphinx documentation
|
|
75
|
+
docs/_build/
|
|
76
|
+
|
|
77
|
+
# PyBuilder
|
|
78
|
+
.pybuilder/
|
|
79
|
+
target/
|
|
80
|
+
|
|
81
|
+
# Jupyter Notebook
|
|
82
|
+
.ipynb_checkpoints
|
|
83
|
+
|
|
84
|
+
# IPython
|
|
85
|
+
profile_default/
|
|
86
|
+
ipython_config.py
|
|
87
|
+
|
|
88
|
+
# pyenv
|
|
89
|
+
# For a library or package, you might want to ignore these files since the code is
|
|
90
|
+
# intended to run in multiple environments; otherwise, check them in:
|
|
91
|
+
# .python-version
|
|
92
|
+
|
|
93
|
+
# pipenv
|
|
94
|
+
# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
|
|
95
|
+
# However, in case of collaboration, if having platform-specific dependencies or dependencies
|
|
96
|
+
# having no cross-platform support, pipenv may install dependencies that don't work, or not
|
|
97
|
+
# install all needed dependencies.
|
|
98
|
+
#Pipfile.lock
|
|
99
|
+
|
|
100
|
+
# UV
|
|
101
|
+
# Similar to Pipfile.lock, it is generally recommended to include uv.lock in version control.
|
|
102
|
+
# This is especially recommended for binary packages to ensure reproducibility, and is more
|
|
103
|
+
# commonly ignored for libraries.
|
|
104
|
+
#uv.lock
|
|
105
|
+
|
|
106
|
+
# poetry
|
|
107
|
+
# Similar to Pipfile.lock, it is generally recommended to include poetry.lock in version control.
|
|
108
|
+
# This is especially recommended for binary packages to ensure reproducibility, and is more
|
|
109
|
+
# commonly ignored for libraries.
|
|
110
|
+
# https://python-poetry.org/docs/basic-usage/#commit-your-poetrylock-file-to-version-control
|
|
111
|
+
#poetry.lock
|
|
112
|
+
#poetry.toml
|
|
113
|
+
|
|
114
|
+
# pdm
|
|
115
|
+
# Similar to Pipfile.lock, it is generally recommended to include pdm.lock in version control.
|
|
116
|
+
# pdm recommends including project-wide configuration in pdm.toml, but excluding .pdm-python.
|
|
117
|
+
# https://pdm-project.org/en/latest/usage/project/#working-with-version-control
|
|
118
|
+
#pdm.lock
|
|
119
|
+
#pdm.toml
|
|
120
|
+
.pdm-python
|
|
121
|
+
.pdm-build/
|
|
122
|
+
|
|
123
|
+
# pixi
|
|
124
|
+
# Similar to Pipfile.lock, it is generally recommended to include pixi.lock in version control.
|
|
125
|
+
#pixi.lock
|
|
126
|
+
# Pixi creates a virtual environment in the .pixi directory, just like venv module creates one
|
|
127
|
+
# in the .venv directory. It is recommended not to include this directory in version control.
|
|
128
|
+
.pixi
|
|
129
|
+
|
|
130
|
+
# PEP 582; used by e.g. github.com/David-OConnor/pyflow and github.com/pdm-project/pdm
|
|
131
|
+
__pypackages__/
|
|
132
|
+
|
|
133
|
+
# Celery stuff
|
|
134
|
+
celerybeat-schedule
|
|
135
|
+
celerybeat.pid
|
|
136
|
+
|
|
137
|
+
# SageMath parsed files
|
|
138
|
+
*.sage.py
|
|
139
|
+
|
|
140
|
+
# Environments
|
|
141
|
+
.env
|
|
142
|
+
.envrc
|
|
143
|
+
.venv
|
|
144
|
+
env/
|
|
145
|
+
venv/
|
|
146
|
+
ENV/
|
|
147
|
+
env.bak/
|
|
148
|
+
venv.bak/
|
|
149
|
+
|
|
150
|
+
# Spyder project settings
|
|
151
|
+
.spyderproject
|
|
152
|
+
.spyproject
|
|
153
|
+
|
|
154
|
+
# Rope project settings
|
|
155
|
+
.ropeproject
|
|
156
|
+
|
|
157
|
+
# mkdocs documentation
|
|
158
|
+
/site
|
|
159
|
+
|
|
160
|
+
# mypy
|
|
161
|
+
.mypy_cache/
|
|
162
|
+
.dmypy.json
|
|
163
|
+
dmypy.json
|
|
164
|
+
|
|
165
|
+
# Pyre type checker
|
|
166
|
+
.pyre/
|
|
167
|
+
|
|
168
|
+
# pytype static type analyzer
|
|
169
|
+
.pytype/
|
|
170
|
+
|
|
171
|
+
# Cython debug symbols
|
|
172
|
+
cython_debug/
|
|
173
|
+
|
|
174
|
+
# PyCharm
|
|
175
|
+
# JetBrains specific template is maintained in a separate JetBrains.gitignore that can
|
|
176
|
+
# be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore
|
|
177
|
+
# and can be added to the global gitignore or merged into this file. For a more nuclear
|
|
178
|
+
# option (not recommended) you can uncomment the following to ignore the entire idea folder.
|
|
179
|
+
#.idea/
|
|
180
|
+
|
|
181
|
+
# Abstra
|
|
182
|
+
# Abstra is an AI-powered process automation framework.
|
|
183
|
+
# Ignore directories containing user credentials, local state, and settings.
|
|
184
|
+
# Learn more at https://abstra.io/docs
|
|
185
|
+
.abstra/
|
|
186
|
+
|
|
187
|
+
# Visual Studio Code
|
|
188
|
+
# Visual Studio Code specific template is maintained in a separate VisualStudioCode.gitignore
|
|
189
|
+
# that can be found at https://github.com/github/gitignore/blob/main/Global/VisualStudioCode.gitignore
|
|
190
|
+
# and can be added to the global gitignore or merged into this file. However, if you prefer,
|
|
191
|
+
# you could uncomment the following to ignore the entire vscode folder
|
|
192
|
+
# .vscode/
|
|
193
|
+
|
|
194
|
+
# Ruff stuff:
|
|
195
|
+
.ruff_cache/
|
|
196
|
+
|
|
197
|
+
# PyPI configuration file
|
|
198
|
+
.pypirc
|
|
199
|
+
|
|
200
|
+
# Cursor
|
|
201
|
+
# Cursor is an AI-powered code editor. `.cursorignore` specifies files/directories to
|
|
202
|
+
# exclude from AI features like autocomplete and code analysis. Recommended for sensitive data
|
|
203
|
+
# refer to https://docs.cursor.com/context/ignore-files
|
|
204
|
+
.cursorignore
|
|
205
|
+
.cursorindexingignore
|
|
206
|
+
|
|
207
|
+
# Marimo
|
|
208
|
+
marimo/_static/
|
|
209
|
+
marimo/_lsp/
|
|
210
|
+
__marimo__/
|
|
211
|
+
|
|
212
|
+
# Others
|
|
213
|
+
*.idea/
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
3.13
|
caul_core-0.1.0/PKG-INFO
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: caul-core
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: core objects for caul ASR
|
|
5
|
+
Author-email: Lion Summerbell <lsummerbell@icij.org>
|
|
6
|
+
Requires-Python: <3.14.0,>=3.11.0
|
|
7
|
+
Requires-Dist: icij-common~=0.8.1
|
|
8
|
+
Requires-Dist: pydantic-extra-types[pycountry]~=2.11
|
|
9
|
+
Description-Content-Type: text/markdown
|
|
10
|
+
|
|
11
|
+
# Core caul objects
|
|
12
|
+
|
|
13
|
+
Separates core configs and objects for separate import without having to pull in heavier `caul` dependencies.
|
|
File without changes
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
import logging
|
|
2
|
+
from typing import Self
|
|
3
|
+
|
|
4
|
+
from icij_common.pydantic_utils import make_enum_discriminator, tagged_union
|
|
5
|
+
from pydantic import Discriminator, Field
|
|
6
|
+
|
|
7
|
+
from .objects import BaseModel, ASRModel, TorchDevice
|
|
8
|
+
from .config import (
|
|
9
|
+
PreprocessorConfig,
|
|
10
|
+
InferenceRunnerConfig,
|
|
11
|
+
PostprocessorConfig,
|
|
12
|
+
ParakeetPreprocessorConfig,
|
|
13
|
+
ParakeetInferenceRunnerConfig,
|
|
14
|
+
ParakeetPostprocessorConfig,
|
|
15
|
+
FireRedASR2PreprocessorConfig,
|
|
16
|
+
FireRedASR2InferenceRunnerConfig,
|
|
17
|
+
FireRedASR2PostprocessorConfig,
|
|
18
|
+
FasterWhisperPreprocessorConfig,
|
|
19
|
+
FasterWhisperInferenceRunnerConfig,
|
|
20
|
+
FasterWhisperPostprocessorConfig,
|
|
21
|
+
)
|
|
22
|
+
|
|
23
|
+
logger = logging.getLogger(__name__)
|
|
24
|
+
|
|
25
|
+
PreprocessorConfig_ = tagged_union(
|
|
26
|
+
PreprocessorConfig.__subclasses__(), lambda t: t.model.default.value
|
|
27
|
+
)
|
|
28
|
+
|
|
29
|
+
InferenceRunnerConfig_ = tagged_union(
|
|
30
|
+
InferenceRunnerConfig.__subclasses__(), lambda t: t.model.default.value
|
|
31
|
+
)
|
|
32
|
+
|
|
33
|
+
PostprocessorConfig_ = tagged_union(
|
|
34
|
+
PostprocessorConfig.__subclasses__(), lambda t: t.model.default.value
|
|
35
|
+
)
|
|
36
|
+
|
|
37
|
+
model_discriminator = make_enum_discriminator("model", ASRModel)
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
class ASRPipelineConfig(BaseModel): # pylint: disable=too-few-public-methods
|
|
41
|
+
device: TorchDevice = TorchDevice.CPU
|
|
42
|
+
preprocessing: PreprocessorConfig_ = Field(
|
|
43
|
+
discriminator=Discriminator(model_discriminator),
|
|
44
|
+
)
|
|
45
|
+
inference: InferenceRunnerConfig_ = Field(
|
|
46
|
+
default_factory=InferenceRunnerConfig,
|
|
47
|
+
discriminator=Discriminator(model_discriminator),
|
|
48
|
+
)
|
|
49
|
+
postprocessing: PostprocessorConfig_ = Field(
|
|
50
|
+
discriminator=Discriminator(model_discriminator),
|
|
51
|
+
)
|
|
52
|
+
|
|
53
|
+
@classmethod
|
|
54
|
+
def parakeet(cls) -> Self:
|
|
55
|
+
return cls(
|
|
56
|
+
preprocessing=ParakeetPreprocessorConfig(),
|
|
57
|
+
inference=ParakeetInferenceRunnerConfig(),
|
|
58
|
+
postprocessing=ParakeetPostprocessorConfig(),
|
|
59
|
+
)
|
|
60
|
+
|
|
61
|
+
@classmethod
|
|
62
|
+
def fireredasr2(cls, tmp_dir_fallback: bool = True) -> Self:
|
|
63
|
+
return cls(
|
|
64
|
+
preprocessing=FireRedASR2PreprocessorConfig(),
|
|
65
|
+
inference=FireRedASR2InferenceRunnerConfig(
|
|
66
|
+
tmp_dir_fallback=tmp_dir_fallback
|
|
67
|
+
),
|
|
68
|
+
postprocessing=FireRedASR2PostprocessorConfig(),
|
|
69
|
+
)
|
|
70
|
+
|
|
71
|
+
@classmethod
|
|
72
|
+
def faster_whisper(cls) -> Self:
|
|
73
|
+
return cls(
|
|
74
|
+
preprocessing=FasterWhisperPreprocessorConfig(),
|
|
75
|
+
inference=FasterWhisperInferenceRunnerConfig(),
|
|
76
|
+
postprocessing=FasterWhisperPostprocessorConfig(),
|
|
77
|
+
)
|
|
@@ -0,0 +1,165 @@
|
|
|
1
|
+
from abc import ABC
|
|
2
|
+
from typing import ClassVar
|
|
3
|
+
|
|
4
|
+
from icij_common.registrable import RegistrableConfig
|
|
5
|
+
from pydantic import Field
|
|
6
|
+
|
|
7
|
+
from .constants import (
|
|
8
|
+
DEFAULT_SAMPLE_RATE,
|
|
9
|
+
DEFAULT_BATCH_SIZE,
|
|
10
|
+
DEFAULT_MAX_FRAMES,
|
|
11
|
+
DEFAULT_LARGE_FILE_THRESHOLD_BYTES,
|
|
12
|
+
PARAKEET_INFERENCE_MAX_FRAMES,
|
|
13
|
+
PARAKEET_MODEL_REF,
|
|
14
|
+
FIREREDASR2_USE_HALF_DEFAULT,
|
|
15
|
+
FIREREDASR2_BEAM_SIZE_DEFAULT,
|
|
16
|
+
FIREREDASR2_NBEST_DEFAULT,
|
|
17
|
+
FIREREDASR2_DECODE_MAX_LEN_DEFAULT,
|
|
18
|
+
FIREREDASR2_SOFTMAX_SMOOTHING_DEFAULT,
|
|
19
|
+
FIREREDASR2_AED_LENGTH_PENALTY_DEFAULT,
|
|
20
|
+
FIREREDASR2_EOS_PENALTY_DEFAULT,
|
|
21
|
+
FIREREDASR2_RETURN_TIMESTAMP_DEFAULT,
|
|
22
|
+
FIREREDASR2_INFERENCE_MAX_FRAMES,
|
|
23
|
+
FASTER_WHISPER_COMPUTE_TYPE_DEFAULT,
|
|
24
|
+
FASTER_WHISPER_WORD_TIMESTAMPS_DEFAULT,
|
|
25
|
+
FASTER_WHISPER_BEAM_SIZE_DEFAULT,
|
|
26
|
+
FASTER_WHISPER_BEST_OF_DEFAULT,
|
|
27
|
+
FASTER_WHISPER_PATIENCE_DEFAULT,
|
|
28
|
+
FASTER_WHISPER_LENGTH_PENALTY_DEFAULT,
|
|
29
|
+
FASTER_WHISPER_REPETITION_PENALTY_DEFAULT,
|
|
30
|
+
FASTER_WHISPER_NO_REPEAT_NGRAM_SIZE_DEFAULT,
|
|
31
|
+
FASTER_WHISPER_LOG_PROB_THRESHOLD_DEFAULT,
|
|
32
|
+
FASTER_WHISPER_NO_SPEECH_THRESHOLD_DEFAULT,
|
|
33
|
+
FASTER_WHISPER_COMPRESSION_RATIO_THRESHOLD_DEFAULT,
|
|
34
|
+
FASTER_WHISPER_CONDITION_ON_PREVIOUS_TEXT_DEFAULT,
|
|
35
|
+
FASTER_WHISPER_PROMPT_RESET_ON_TEMPERATURE_DEFAULT,
|
|
36
|
+
FASTER_WHISPER_TEMPERATURES_DEFAULT,
|
|
37
|
+
FASTER_WHISPER_SUPPRESS_BLANK_DEFAULT,
|
|
38
|
+
FASTER_WHISPER_LARGE_V3_TURBO_SUPPRESSED_TOKENS,
|
|
39
|
+
FASTER_WHISPER_WITHOUT_TIMESTAMPS_DEFAULT,
|
|
40
|
+
FASTER_WHISPER_MAX_INITIAL_TIMESTAMP_DEFAULT,
|
|
41
|
+
FASTER_WHISPER_PREPEND_PUNCTUATIONS_DEFAULT,
|
|
42
|
+
FASTER_WHISPER_APPEND_PUNCTUATIONS_DEFAULT,
|
|
43
|
+
FASTER_WHISPER_MULTILINGUAL_DEFAULT,
|
|
44
|
+
FASTER_WHISPER_CLIP_TIMESTAMPS_DEFAULT,
|
|
45
|
+
)
|
|
46
|
+
from .objects import BaseModel, ASRModel, FasterWhisperModel
|
|
47
|
+
|
|
48
|
+
|
|
49
|
+
class _BaseConfig(BaseModel, RegistrableConfig, ABC): ...
|
|
50
|
+
|
|
51
|
+
|
|
52
|
+
class PreprocessorConfig(_BaseConfig):
|
|
53
|
+
registry_key: ClassVar[str] = Field(frozen=True, default="model")
|
|
54
|
+
model: ClassVar[ASRModel]
|
|
55
|
+
|
|
56
|
+
max_frames: int = DEFAULT_MAX_FRAMES
|
|
57
|
+
batch_size: int = DEFAULT_BATCH_SIZE
|
|
58
|
+
sample_rate: int = DEFAULT_SAMPLE_RATE
|
|
59
|
+
large_file_threshold_bytes: int = DEFAULT_LARGE_FILE_THRESHOLD_BYTES
|
|
60
|
+
|
|
61
|
+
|
|
62
|
+
class InferenceRunnerConfig(_BaseConfig):
|
|
63
|
+
registry_key: ClassVar[str] = Field(frozen=True, default="model")
|
|
64
|
+
model: ClassVar[ASRModel]
|
|
65
|
+
|
|
66
|
+
tmp_dir_fallback: bool = False
|
|
67
|
+
|
|
68
|
+
|
|
69
|
+
class PostprocessorConfig(_BaseConfig):
|
|
70
|
+
registry_key: ClassVar[str] = Field(frozen=True, default="model")
|
|
71
|
+
model: ClassVar[ASRModel]
|
|
72
|
+
|
|
73
|
+
|
|
74
|
+
# Parakeet
|
|
75
|
+
|
|
76
|
+
|
|
77
|
+
class ParakeetPreprocessorConfig(PreprocessorConfig):
|
|
78
|
+
model: ClassVar[str] = Field(default=ASRModel.PARAKEET)
|
|
79
|
+
|
|
80
|
+
max_frames: int = PARAKEET_INFERENCE_MAX_FRAMES
|
|
81
|
+
|
|
82
|
+
|
|
83
|
+
class ParakeetInferenceRunnerConfig(InferenceRunnerConfig):
|
|
84
|
+
model: ClassVar[str] = Field(frozen=True, default=ASRModel.PARAKEET)
|
|
85
|
+
model_name: str = PARAKEET_MODEL_REF
|
|
86
|
+
return_timestamps: bool = True
|
|
87
|
+
|
|
88
|
+
|
|
89
|
+
class ParakeetPostprocessorConfig(PostprocessorConfig):
|
|
90
|
+
model: ClassVar[str] = Field(frozen=True, default=ASRModel.PARAKEET)
|
|
91
|
+
|
|
92
|
+
|
|
93
|
+
# Faster Whisper
|
|
94
|
+
|
|
95
|
+
|
|
96
|
+
class FasterWhisperPreprocessorConfig(PreprocessorConfig):
|
|
97
|
+
model: ClassVar[str] = Field(default=ASRModel.FASTER_WHISPER)
|
|
98
|
+
|
|
99
|
+
|
|
100
|
+
class FasterWhisperInferenceRunnerConfig(InferenceRunnerConfig):
|
|
101
|
+
model: ClassVar[str] = Field(frozen=True, default=ASRModel.FASTER_WHISPER)
|
|
102
|
+
|
|
103
|
+
whisper_model_name: FasterWhisperModel = FasterWhisperModel.MEDIUM
|
|
104
|
+
|
|
105
|
+
compute_type: str = FASTER_WHISPER_COMPUTE_TYPE_DEFAULT
|
|
106
|
+
word_timestamps: bool = FASTER_WHISPER_WORD_TIMESTAMPS_DEFAULT
|
|
107
|
+
beam_size: int = FASTER_WHISPER_BEAM_SIZE_DEFAULT
|
|
108
|
+
best_of: int = FASTER_WHISPER_BEST_OF_DEFAULT
|
|
109
|
+
patience: int = FASTER_WHISPER_PATIENCE_DEFAULT
|
|
110
|
+
length_penalty: int = FASTER_WHISPER_LENGTH_PENALTY_DEFAULT
|
|
111
|
+
repetition_penalty: int = FASTER_WHISPER_REPETITION_PENALTY_DEFAULT
|
|
112
|
+
no_repeat_ngram_size: int = FASTER_WHISPER_NO_REPEAT_NGRAM_SIZE_DEFAULT
|
|
113
|
+
log_prob_threshold: float = FASTER_WHISPER_LOG_PROB_THRESHOLD_DEFAULT
|
|
114
|
+
no_speech_threshold: float = FASTER_WHISPER_NO_SPEECH_THRESHOLD_DEFAULT
|
|
115
|
+
compression_ratio_threshold: float = (
|
|
116
|
+
FASTER_WHISPER_COMPRESSION_RATIO_THRESHOLD_DEFAULT
|
|
117
|
+
)
|
|
118
|
+
condition_on_previous_text: bool = FASTER_WHISPER_CONDITION_ON_PREVIOUS_TEXT_DEFAULT
|
|
119
|
+
prompt_reset_on_temperature: float = (
|
|
120
|
+
FASTER_WHISPER_PROMPT_RESET_ON_TEMPERATURE_DEFAULT
|
|
121
|
+
)
|
|
122
|
+
temperatures: list[float] = FASTER_WHISPER_TEMPERATURES_DEFAULT
|
|
123
|
+
initial_prompt: str | None = None
|
|
124
|
+
prefix: str | None = None
|
|
125
|
+
suppress_blank: bool = FASTER_WHISPER_SUPPRESS_BLANK_DEFAULT
|
|
126
|
+
suppress_tokens: list[int] = FASTER_WHISPER_LARGE_V3_TURBO_SUPPRESSED_TOKENS
|
|
127
|
+
without_timestamps: bool = FASTER_WHISPER_WITHOUT_TIMESTAMPS_DEFAULT
|
|
128
|
+
max_initial_timestamp: float = FASTER_WHISPER_MAX_INITIAL_TIMESTAMP_DEFAULT
|
|
129
|
+
prepend_punctuations: str = FASTER_WHISPER_PREPEND_PUNCTUATIONS_DEFAULT
|
|
130
|
+
append_punctuations: str = FASTER_WHISPER_APPEND_PUNCTUATIONS_DEFAULT
|
|
131
|
+
multilingual: bool = FASTER_WHISPER_MULTILINGUAL_DEFAULT
|
|
132
|
+
max_new_tokens: int | None = None
|
|
133
|
+
clip_timestamps: list[float] = FASTER_WHISPER_CLIP_TIMESTAMPS_DEFAULT
|
|
134
|
+
hallucination_silence_threshold: float | None = None
|
|
135
|
+
hotwords: str | None = None
|
|
136
|
+
|
|
137
|
+
|
|
138
|
+
class FasterWhisperPostprocessorConfig(PostprocessorConfig):
|
|
139
|
+
model: ClassVar[str] = Field(frozen=True, default=ASRModel.FASTER_WHISPER)
|
|
140
|
+
|
|
141
|
+
|
|
142
|
+
# FireRedASR2s
|
|
143
|
+
|
|
144
|
+
|
|
145
|
+
class FireRedASR2PreprocessorConfig(PreprocessorConfig):
|
|
146
|
+
model: ClassVar[str] = Field(default=ASRModel.FIREREDASR2_AED)
|
|
147
|
+
|
|
148
|
+
max_frames: int = FIREREDASR2_INFERENCE_MAX_FRAMES
|
|
149
|
+
|
|
150
|
+
|
|
151
|
+
class FireRedASR2InferenceRunnerConfig(InferenceRunnerConfig):
|
|
152
|
+
model: ClassVar[str] = Field(frozen=True, default=ASRModel.FIREREDASR2_AED)
|
|
153
|
+
|
|
154
|
+
use_half: bool = FIREREDASR2_USE_HALF_DEFAULT
|
|
155
|
+
beam_size: int = FIREREDASR2_BEAM_SIZE_DEFAULT
|
|
156
|
+
nbest: int = FIREREDASR2_NBEST_DEFAULT
|
|
157
|
+
decode_max_len: int = FIREREDASR2_DECODE_MAX_LEN_DEFAULT
|
|
158
|
+
softmax_smoothing: float = FIREREDASR2_SOFTMAX_SMOOTHING_DEFAULT
|
|
159
|
+
aed_length_penalty: float = FIREREDASR2_AED_LENGTH_PENALTY_DEFAULT
|
|
160
|
+
eos_penalty: float = FIREREDASR2_EOS_PENALTY_DEFAULT
|
|
161
|
+
return_timestamp: bool = FIREREDASR2_RETURN_TIMESTAMP_DEFAULT
|
|
162
|
+
|
|
163
|
+
|
|
164
|
+
class FireRedASR2PostprocessorConfig(PostprocessorConfig):
|
|
165
|
+
model: ClassVar[str] = Field(frozen=True, default=ASRModel.FIREREDASR2_AED)
|
|
@@ -0,0 +1,178 @@
|
|
|
1
|
+
DEFAULT_SAMPLE_RATE = 16000
|
|
2
|
+
DEFAULT_BATCH_SIZE = 32
|
|
3
|
+
DEFAULT_MAX_FRAMES = 25 * 60 * DEFAULT_SAMPLE_RATE # twenty-five minutes
|
|
4
|
+
DEFAULT_LARGE_FILE_THRESHOLD_BYTES = 30 * 1024 * 1024 # 30mb
|
|
5
|
+
|
|
6
|
+
# Parakeet
|
|
7
|
+
|
|
8
|
+
PARAKEET_MODEL_REF = "nvidia/parakeet-tdt-0.6b-v3"
|
|
9
|
+
PARAKEET_INFERENCE_MAX_DURATION_S = (
|
|
10
|
+
20 * 60 # actually 24, but we want to give ourselves some room to avoid CUDA OOMs
|
|
11
|
+
)
|
|
12
|
+
PARAKEET_INFERENCE_MAX_FRAMES = PARAKEET_INFERENCE_MAX_DURATION_S * DEFAULT_SAMPLE_RATE
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
# Faster Whisper (SYSTRAN/faster-whisper)
|
|
16
|
+
|
|
17
|
+
FASTER_WHISPER_COMPUTE_TYPE_DEFAULT = "float32"
|
|
18
|
+
FASTER_WHISPER_WORD_TIMESTAMPS_DEFAULT = True
|
|
19
|
+
FASTER_WHISPER_BEAM_SIZE_DEFAULT = 5
|
|
20
|
+
FASTER_WHISPER_BEST_OF_DEFAULT = 5
|
|
21
|
+
FASTER_WHISPER_PATIENCE_DEFAULT = 1
|
|
22
|
+
FASTER_WHISPER_LENGTH_PENALTY_DEFAULT = 1
|
|
23
|
+
FASTER_WHISPER_REPETITION_PENALTY_DEFAULT = 1
|
|
24
|
+
FASTER_WHISPER_NO_REPEAT_NGRAM_SIZE_DEFAULT = 0
|
|
25
|
+
FASTER_WHISPER_LOG_PROB_THRESHOLD_DEFAULT = -1.0
|
|
26
|
+
FASTER_WHISPER_NO_SPEECH_THRESHOLD_DEFAULT = 0.6
|
|
27
|
+
FASTER_WHISPER_COMPRESSION_RATIO_THRESHOLD_DEFAULT = 2.4
|
|
28
|
+
FASTER_WHISPER_CONDITION_ON_PREVIOUS_TEXT_DEFAULT = False
|
|
29
|
+
FASTER_WHISPER_PROMPT_RESET_ON_TEMPERATURE_DEFAULT = 0.5
|
|
30
|
+
FASTER_WHISPER_TEMPERATURES_DEFAULT = [0.0]
|
|
31
|
+
FASTER_WHISPER_SUPPRESS_BLANK_DEFAULT = True
|
|
32
|
+
FASTER_WHISPER_WITHOUT_TIMESTAMPS_DEFAULT = True
|
|
33
|
+
FASTER_WHISPER_MAX_INITIAL_TIMESTAMP_DEFAULT = 0.0
|
|
34
|
+
FASTER_WHISPER_PREPEND_PUNCTUATIONS_DEFAULT = "\"'‘’“¿([{—-"
|
|
35
|
+
FASTER_WHISPER_APPEND_PUNCTUATIONS_DEFAULT = "\"'’”.。,,!!??::””)]、結}"
|
|
36
|
+
FASTER_WHISPER_MULTILINGUAL_DEFAULT = False
|
|
37
|
+
FASTER_WHISPER_CLIP_TIMESTAMPS_DEFAULT = []
|
|
38
|
+
FASTER_WHISPER_LARGE_V3_TURBO_SUPPRESSED_TOKENS = [
|
|
39
|
+
1,
|
|
40
|
+
2,
|
|
41
|
+
7,
|
|
42
|
+
8,
|
|
43
|
+
9,
|
|
44
|
+
10,
|
|
45
|
+
14,
|
|
46
|
+
25,
|
|
47
|
+
26,
|
|
48
|
+
27,
|
|
49
|
+
28,
|
|
50
|
+
29,
|
|
51
|
+
31,
|
|
52
|
+
58,
|
|
53
|
+
59,
|
|
54
|
+
60,
|
|
55
|
+
61,
|
|
56
|
+
62,
|
|
57
|
+
63,
|
|
58
|
+
90,
|
|
59
|
+
91,
|
|
60
|
+
92,
|
|
61
|
+
93,
|
|
62
|
+
359,
|
|
63
|
+
503,
|
|
64
|
+
522,
|
|
65
|
+
542,
|
|
66
|
+
873,
|
|
67
|
+
893,
|
|
68
|
+
902,
|
|
69
|
+
918,
|
|
70
|
+
922,
|
|
71
|
+
931,
|
|
72
|
+
1350,
|
|
73
|
+
1853,
|
|
74
|
+
1982,
|
|
75
|
+
2460,
|
|
76
|
+
2627,
|
|
77
|
+
3246,
|
|
78
|
+
3253,
|
|
79
|
+
3268,
|
|
80
|
+
3536,
|
|
81
|
+
3846,
|
|
82
|
+
3961,
|
|
83
|
+
4183,
|
|
84
|
+
4667,
|
|
85
|
+
6585,
|
|
86
|
+
6647,
|
|
87
|
+
7273,
|
|
88
|
+
9061,
|
|
89
|
+
9383,
|
|
90
|
+
10428,
|
|
91
|
+
10929,
|
|
92
|
+
11938,
|
|
93
|
+
12033,
|
|
94
|
+
12331,
|
|
95
|
+
12562,
|
|
96
|
+
13793,
|
|
97
|
+
14157,
|
|
98
|
+
14635,
|
|
99
|
+
15265,
|
|
100
|
+
15618,
|
|
101
|
+
16553,
|
|
102
|
+
16604,
|
|
103
|
+
18362,
|
|
104
|
+
18956,
|
|
105
|
+
20075,
|
|
106
|
+
21675,
|
|
107
|
+
22520,
|
|
108
|
+
26130,
|
|
109
|
+
26161,
|
|
110
|
+
26435,
|
|
111
|
+
28279,
|
|
112
|
+
29464,
|
|
113
|
+
31650,
|
|
114
|
+
32302,
|
|
115
|
+
32470,
|
|
116
|
+
36865,
|
|
117
|
+
42863,
|
|
118
|
+
47425,
|
|
119
|
+
49870,
|
|
120
|
+
50254,
|
|
121
|
+
50258,
|
|
122
|
+
50359,
|
|
123
|
+
50360,
|
|
124
|
+
50361,
|
|
125
|
+
50362,
|
|
126
|
+
50363,
|
|
127
|
+
]
|
|
128
|
+
|
|
129
|
+
# FireRedASR2s
|
|
130
|
+
|
|
131
|
+
FIREREDASR2_MODEL_HUB_PREFIX = "FireRedTeam/FireRed"
|
|
132
|
+
FIREREDASR2_INFERENCE_MAX_DURATION_S = 60
|
|
133
|
+
FIREREDASR2_INFERENCE_MAX_FRAMES = (
|
|
134
|
+
FIREREDASR2_INFERENCE_MAX_DURATION_S * DEFAULT_SAMPLE_RATE
|
|
135
|
+
)
|
|
136
|
+
FIREREDASR2_USE_HALF_DEFAULT = False
|
|
137
|
+
FIREREDASR2_BEAM_SIZE_DEFAULT = 3
|
|
138
|
+
FIREREDASR2_NBEST_DEFAULT = 1
|
|
139
|
+
FIREREDASR2_DECODE_MAX_LEN_DEFAULT = 0
|
|
140
|
+
FIREREDASR2_SOFTMAX_SMOOTHING_DEFAULT = 1.25
|
|
141
|
+
FIREREDASR2_AED_LENGTH_PENALTY_DEFAULT = 0.6
|
|
142
|
+
FIREREDASR2_EOS_PENALTY_DEFAULT = 1.0
|
|
143
|
+
FIREREDASR2_RETURN_TIMESTAMP_DEFAULT = True
|
|
144
|
+
|
|
145
|
+
# Languages
|
|
146
|
+
PARAKEET_TDT_0_6B_V3_LANGUAGES = {
|
|
147
|
+
"bg",
|
|
148
|
+
"hr",
|
|
149
|
+
"cs",
|
|
150
|
+
"da",
|
|
151
|
+
"nl",
|
|
152
|
+
"en",
|
|
153
|
+
"et",
|
|
154
|
+
"fi",
|
|
155
|
+
"fr",
|
|
156
|
+
"de",
|
|
157
|
+
"el",
|
|
158
|
+
"hu",
|
|
159
|
+
"it",
|
|
160
|
+
"lv",
|
|
161
|
+
"lt",
|
|
162
|
+
"mt",
|
|
163
|
+
"pl",
|
|
164
|
+
"pt",
|
|
165
|
+
"ro",
|
|
166
|
+
"sk",
|
|
167
|
+
"sl",
|
|
168
|
+
"es",
|
|
169
|
+
"sv",
|
|
170
|
+
"ru",
|
|
171
|
+
"uk",
|
|
172
|
+
}
|
|
173
|
+
FIREREDASR2_LANGUAGES = {"zh"}
|
|
174
|
+
|
|
175
|
+
|
|
176
|
+
# Silero
|
|
177
|
+
|
|
178
|
+
SILERO_VAD_MODEL = "silero_vad"
|
|
@@ -0,0 +1,246 @@
|
|
|
1
|
+
import datetime
|
|
2
|
+
import math
|
|
3
|
+
from dataclasses import dataclass
|
|
4
|
+
from enum import StrEnum, unique
|
|
5
|
+
from pathlib import Path
|
|
6
|
+
from typing import Self, TYPE_CHECKING
|
|
7
|
+
|
|
8
|
+
import uuid
|
|
9
|
+
|
|
10
|
+
import langcodes
|
|
11
|
+
from icij_common.pydantic_utils import icij_config, merge_configs, no_enum_values_config
|
|
12
|
+
from pydantic import BaseModel as _BaseModel, Field, GetCoreSchemaHandler, TypeAdapter
|
|
13
|
+
from pydantic_core import core_schema
|
|
14
|
+
from pydantic_extra_types.language_code import LanguageAlpha2
|
|
15
|
+
|
|
16
|
+
from .constants import PARAKEET_TDT_0_6B_V3_LANGUAGES, FIREREDASR2_LANGUAGES
|
|
17
|
+
|
|
18
|
+
if TYPE_CHECKING:
|
|
19
|
+
import torch
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
# Enums
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
class FireRedASR2ModelRef(StrEnum):
|
|
26
|
+
ASR2 = "ASR2"
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
class FireRedASR2ModelTag(StrEnum):
|
|
30
|
+
AED = "aed"
|
|
31
|
+
LLM = "llm"
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
class VadModelRef(StrEnum):
|
|
35
|
+
SILERO_MODEL = "snakers4/silero-vad"
|
|
36
|
+
PYANNOTE_MODEL = "pyannote/segmentation-3.0"
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
class TorchDevice(StrEnum):
|
|
40
|
+
CPU = "cpu"
|
|
41
|
+
GPU = "cuda"
|
|
42
|
+
MPS = "mps"
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
@unique
|
|
46
|
+
class FasterWhisperModel(StrEnum):
|
|
47
|
+
TINY = "tiny"
|
|
48
|
+
BASE = "base"
|
|
49
|
+
SMALL = "small"
|
|
50
|
+
MEDIUM = "medium"
|
|
51
|
+
LARGE = "large"
|
|
52
|
+
LARGE_V3 = "large-v3"
|
|
53
|
+
DISTIL_LARGE_V3 = "distil-large-v3"
|
|
54
|
+
|
|
55
|
+
@property
|
|
56
|
+
def to_repo_id(self) -> str:
|
|
57
|
+
match self:
|
|
58
|
+
case FasterWhisperModel.TINY:
|
|
59
|
+
return "Systran/faster-whisper-tiny"
|
|
60
|
+
case FasterWhisperModel.BASE:
|
|
61
|
+
return "Systran/faster-whisper-base"
|
|
62
|
+
case FasterWhisperModel.SMALL:
|
|
63
|
+
return "Systran/faster-whisper-small"
|
|
64
|
+
case FasterWhisperModel.MEDIUM:
|
|
65
|
+
return "Systran/faster-whisper-medium"
|
|
66
|
+
case FasterWhisperModel.LARGE:
|
|
67
|
+
return "Systran/faster-whisper-large-v3"
|
|
68
|
+
case FasterWhisperModel.LARGE_V3:
|
|
69
|
+
return "Systran/faster-whisper-large-v3"
|
|
70
|
+
case FasterWhisperModel.DISTIL_LARGE_V3:
|
|
71
|
+
return "Systran/faster-distil-whisper-large-v3"
|
|
72
|
+
case _:
|
|
73
|
+
raise NotImplementedError(f"invalid faster whisper model {self}")
|
|
74
|
+
|
|
75
|
+
|
|
76
|
+
# Models
|
|
77
|
+
|
|
78
|
+
|
|
79
|
+
class BaseModel(_BaseModel):
|
|
80
|
+
model_config = merge_configs(icij_config(), no_enum_values_config())
|
|
81
|
+
|
|
82
|
+
|
|
83
|
+
class IETFLanguage(str):
|
|
84
|
+
@classmethod
|
|
85
|
+
def __get_pydantic_core_schema__(cls, source, handler: GetCoreSchemaHandler):
|
|
86
|
+
return core_schema.no_info_plain_validator_function(cls.validate)
|
|
87
|
+
|
|
88
|
+
@classmethod
|
|
89
|
+
def validate(cls, v):
|
|
90
|
+
tag = langcodes.get(str(v))
|
|
91
|
+
if not tag.is_valid():
|
|
92
|
+
raise ValueError(f"Invalid IETF language: {v}")
|
|
93
|
+
return cls(v)
|
|
94
|
+
|
|
95
|
+
|
|
96
|
+
ASRLanguage = IETFLanguage | LanguageAlpha2
|
|
97
|
+
_LANGUAGE_TYPE_ADAPTER = TypeAdapter(ASRLanguage)
|
|
98
|
+
|
|
99
|
+
_VALIDATED_PARAKEET_LANGUAGES = {
|
|
100
|
+
_LANGUAGE_TYPE_ADAPTER.validate_python(lang)
|
|
101
|
+
for lang in PARAKEET_TDT_0_6B_V3_LANGUAGES
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
_VALIDATED_FIREREDASR2_LANGUAGES = {
|
|
105
|
+
_LANGUAGE_TYPE_ADAPTER.validate_python(lang) for lang in FIREREDASR2_LANGUAGES
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
|
|
109
|
+
class ASRModel(StrEnum):
|
|
110
|
+
PARAKEET = "parakeet"
|
|
111
|
+
FASTER_WHISPER = "faster_whisper"
|
|
112
|
+
FIREREDASR2_AED = "fireredasr2_aed"
|
|
113
|
+
|
|
114
|
+
def supported_languages(self) -> set[ASRLanguage]:
|
|
115
|
+
match self:
|
|
116
|
+
case ASRModel.PARAKEET:
|
|
117
|
+
return _VALIDATED_PARAKEET_LANGUAGES
|
|
118
|
+
case ASRModel.FASTER_WHISPER:
|
|
119
|
+
return set()
|
|
120
|
+
case ASRModel.FIREREDASR2_AED:
|
|
121
|
+
return _VALIDATED_FIREREDASR2_LANGUAGES
|
|
122
|
+
case _:
|
|
123
|
+
msg = f"model {self} should expose supported languages"
|
|
124
|
+
raise NotImplementedError(msg)
|
|
125
|
+
|
|
126
|
+
|
|
127
|
+
class ASRResult(BaseModel):
|
|
128
|
+
"""Base result class for ASR models"""
|
|
129
|
+
|
|
130
|
+
input_ordering: int = -1
|
|
131
|
+
transcription: list[tuple] = Field(default_factory=list)
|
|
132
|
+
score: float = 1.0
|
|
133
|
+
|
|
134
|
+
@property
|
|
135
|
+
def duration(self) -> float:
|
|
136
|
+
if not self.transcription:
|
|
137
|
+
return 0.0
|
|
138
|
+
total = sum(end - start for start, end, _ in self.transcription)
|
|
139
|
+
return total
|
|
140
|
+
|
|
141
|
+
@classmethod
|
|
142
|
+
def from_parakeet_hypothesis(cls, hypothesis: "Hypothesis", **extra) -> Self:
|
|
143
|
+
"""Parse a hypothesis returned by a Parakeet RNN model
|
|
144
|
+
|
|
145
|
+
:param hypothesis: Parakeet hypothesis
|
|
146
|
+
:return: copy of self
|
|
147
|
+
"""
|
|
148
|
+
|
|
149
|
+
# there's some weird inconsistency here between nemo versions
|
|
150
|
+
timestamps = hypothesis.timestamp
|
|
151
|
+
transcription = [
|
|
152
|
+
(s["start"], s["end"], s["segment"]) for s in timestamps["segment"]
|
|
153
|
+
]
|
|
154
|
+
return cls(transcription=transcription, score=hypothesis.score, **extra)
|
|
155
|
+
|
|
156
|
+
@classmethod
|
|
157
|
+
def from_fireredasr2_result(cls, result: dict, **extra) -> Self:
|
|
158
|
+
"""Parse a result dict returned by a FireRedASR2 AED model
|
|
159
|
+
|
|
160
|
+
:param result: dict with keys 'text', 'confidence', 'dur_s', 'timestamp'
|
|
161
|
+
:return: ASRResult
|
|
162
|
+
"""
|
|
163
|
+
text = result.get("text") or ""
|
|
164
|
+
timestamp = result.get("timestamp") or []
|
|
165
|
+
if timestamp:
|
|
166
|
+
start_s = float(timestamp[0][1])
|
|
167
|
+
end_s = float(timestamp[-1][2])
|
|
168
|
+
else:
|
|
169
|
+
start_s = 0.0
|
|
170
|
+
end_s = float(result.get("dur_s") or 0.0)
|
|
171
|
+
transcription = [(start_s, end_s, text)] if text.strip() else []
|
|
172
|
+
confidence = result.get("confidence")
|
|
173
|
+
score = float(confidence) if confidence is not None else -1.0
|
|
174
|
+
return cls(transcription=transcription, score=score, **extra)
|
|
175
|
+
|
|
176
|
+
@classmethod
|
|
177
|
+
def from_faster_whisper_result(cls, segments, **extra) -> Self:
|
|
178
|
+
"""Parse segments returned by a faster-whisper model
|
|
179
|
+
|
|
180
|
+
:param segments: iterable of Segment objects with start, end, text, avg_logprob
|
|
181
|
+
:return: ASRResult
|
|
182
|
+
"""
|
|
183
|
+
transcription = []
|
|
184
|
+
weighted_logprob = 0.0
|
|
185
|
+
total_duration = 0.0
|
|
186
|
+
for segment in segments:
|
|
187
|
+
duration = segment.end - segment.start
|
|
188
|
+
transcription.append((segment.start, segment.end, segment.text))
|
|
189
|
+
weighted_logprob += segment.avg_logprob * duration
|
|
190
|
+
total_duration += duration
|
|
191
|
+
score = math.exp(weighted_logprob / total_duration) if total_duration else -1.0
|
|
192
|
+
return cls(transcription=transcription, score=score, **extra)
|
|
193
|
+
|
|
194
|
+
def __add__(self, other: Self) -> Self:
|
|
195
|
+
if not isinstance(other, ASRResult):
|
|
196
|
+
msg = f"expected {ASRResult.__class__.__class__} but found: {type(other)}"
|
|
197
|
+
raise TypeError(msg)
|
|
198
|
+
|
|
199
|
+
if other.input_ordering != self.input_ordering:
|
|
200
|
+
raise ValueError("can't merge transcriptions from different inputs")
|
|
201
|
+
|
|
202
|
+
transcription = self.transcription + other.transcription
|
|
203
|
+
# We have to weight by total segment len
|
|
204
|
+
total_duration = self.duration + other.duration
|
|
205
|
+
score = 1.0
|
|
206
|
+
if total_duration:
|
|
207
|
+
score = self.score * self.duration + other.score * other.duration
|
|
208
|
+
score /= total_duration
|
|
209
|
+
return ASRResult(
|
|
210
|
+
input_ordering=self.input_ordering, transcription=transcription, score=score
|
|
211
|
+
)
|
|
212
|
+
|
|
213
|
+
|
|
214
|
+
def _utc_now() -> datetime.datetime:
|
|
215
|
+
return datetime.datetime.now(datetime.timezone.utc).replace(microsecond=0)
|
|
216
|
+
|
|
217
|
+
|
|
218
|
+
def _uuid() -> str:
|
|
219
|
+
return uuid.uuid4().hex
|
|
220
|
+
|
|
221
|
+
|
|
222
|
+
class InputMetadata(BaseModel):
|
|
223
|
+
"""Preprocessed input metadata"""
|
|
224
|
+
|
|
225
|
+
duration_s: float
|
|
226
|
+
input_ordering: int = -1
|
|
227
|
+
preprocessed_at: datetime.datetime = Field(default_factory=_utc_now)
|
|
228
|
+
uuid: str = Field(default_factory=_uuid)
|
|
229
|
+
input_format: str | None = None
|
|
230
|
+
input_file_path: Path | None = None
|
|
231
|
+
preprocessed_file_path: Path | None = None
|
|
232
|
+
|
|
233
|
+
|
|
234
|
+
class PreprocessedInput(BaseModel):
|
|
235
|
+
metadata: InputMetadata
|
|
236
|
+
|
|
237
|
+
|
|
238
|
+
@dataclass(frozen=True)
|
|
239
|
+
class PreprocessedInputWithTensor:
|
|
240
|
+
# Avoid importing torch when importing objects
|
|
241
|
+
|
|
242
|
+
metadata: InputMetadata
|
|
243
|
+
tensor: "torch.Tensor | list | None" = None
|
|
244
|
+
|
|
245
|
+
|
|
246
|
+
PreprocessorOutput = PreprocessedInput | PreprocessedInputWithTensor
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
[project]
|
|
2
|
+
name = "caul-core"
|
|
3
|
+
dynamic = ["version"]
|
|
4
|
+
description = "core objects for caul ASR"
|
|
5
|
+
authors = [
|
|
6
|
+
{name = "Lion Summerbell", email = "lsummerbell@icij.org"}
|
|
7
|
+
]
|
|
8
|
+
readme = "README.md"
|
|
9
|
+
requires-python = ">=3.11.0, <3.14.0"
|
|
10
|
+
dependencies = [
|
|
11
|
+
"icij-common~=0.8.1",
|
|
12
|
+
"pydantic-extra-types[pycountry]~=2.11",
|
|
13
|
+
]
|
|
14
|
+
|
|
15
|
+
[tool.uv]
|
|
16
|
+
package = true
|
|
17
|
+
|
|
18
|
+
[build-system]
|
|
19
|
+
requires = ["hatchling", "uv-dynamic-versioning"]
|
|
20
|
+
build-backend = "hatchling.build"
|
|
21
|
+
|
|
22
|
+
[tool.hatch.version]
|
|
23
|
+
source = "uv-dynamic-versioning"
|
|
24
|
+
|
|
25
|
+
[tool.hatch.build.targets.wheel]
|
|
26
|
+
packages = ["caul_core"]
|
|
27
|
+
|
|
28
|
+
[tool.uv-dynamic-versioning]
|
|
29
|
+
fallback-version = "0.0.0"
|
|
30
|
+
pattern-prefix = "caul-core-"
|
caul_core-0.1.0/uv.lock
ADDED
|
@@ -0,0 +1,211 @@
|
|
|
1
|
+
version = 1
|
|
2
|
+
revision = 3
|
|
3
|
+
requires-python = ">=3.11.0, <3.14.0"
|
|
4
|
+
|
|
5
|
+
[[package]]
|
|
6
|
+
name = "aiostream"
|
|
7
|
+
version = "0.7.1"
|
|
8
|
+
source = { registry = "https://pypi.org/simple" }
|
|
9
|
+
dependencies = [
|
|
10
|
+
{ name = "typing-extensions" },
|
|
11
|
+
]
|
|
12
|
+
sdist = { url = "https://files.pythonhosted.org/packages/8b/65/b9b69695702b76a878c9879f2ee80cefce75bc5cb864fc100460bc1c5380/aiostream-0.7.1.tar.gz", hash = "sha256:272aaa0d8f83beb906f5aa9022bb59046bb7a103fa3770f807c31f918595acf6", size = 44059, upload-time = "2025-10-13T20:02:06.961Z" }
|
|
13
|
+
wheels = [
|
|
14
|
+
{ url = "https://files.pythonhosted.org/packages/52/a0/d7c6ca304140f3f49987d710e15bc164248924a35d8cdfac2f6e87fca041/aiostream-0.7.1-py3-none-any.whl", hash = "sha256:ea8739e9158ee6a606b3feedf3762721c3507344e540d09a10984c5e88a13b37", size = 41416, upload-time = "2025-10-13T20:02:05.535Z" },
|
|
15
|
+
]
|
|
16
|
+
|
|
17
|
+
[[package]]
|
|
18
|
+
name = "annotated-types"
|
|
19
|
+
version = "0.7.0"
|
|
20
|
+
source = { registry = "https://pypi.org/simple" }
|
|
21
|
+
sdist = { url = "https://files.pythonhosted.org/packages/ee/67/531ea369ba64dcff5ec9c3402f9f51bf748cec26dde048a2f973a4eea7f5/annotated_types-0.7.0.tar.gz", hash = "sha256:aff07c09a53a08bc8cfccb9c85b05f1aa9a2a6f23728d790723543408344ce89", size = 16081, upload-time = "2024-05-20T21:33:25.928Z" }
|
|
22
|
+
wheels = [
|
|
23
|
+
{ url = "https://files.pythonhosted.org/packages/78/b6/6307fbef88d9b5ee7421e68d78a9f162e0da4900bc5f5793f6d3d0e34fb8/annotated_types-0.7.0-py3-none-any.whl", hash = "sha256:1f02e8b43a8fbbc3f3e0d4f0f4bfc8131bcb4eebe8849b8e5c773f3a1c582a53", size = 13643, upload-time = "2024-05-20T21:33:24.1Z" },
|
|
24
|
+
]
|
|
25
|
+
|
|
26
|
+
[[package]]
|
|
27
|
+
name = "caul-core"
|
|
28
|
+
version = "0.1.0"
|
|
29
|
+
source = { virtual = "." }
|
|
30
|
+
dependencies = [
|
|
31
|
+
{ name = "icij-common" },
|
|
32
|
+
{ name = "pydantic-extra-types", extra = ["pycountry"] },
|
|
33
|
+
]
|
|
34
|
+
|
|
35
|
+
[package.metadata]
|
|
36
|
+
requires-dist = [
|
|
37
|
+
{ name = "icij-common", specifier = "~=0.8.1" },
|
|
38
|
+
{ name = "pydantic-extra-types", extras = ["pycountry"], specifier = "~=2.11" },
|
|
39
|
+
]
|
|
40
|
+
|
|
41
|
+
[[package]]
|
|
42
|
+
name = "icij-common"
|
|
43
|
+
version = "0.8.2"
|
|
44
|
+
source = { registry = "https://pypi.org/simple" }
|
|
45
|
+
dependencies = [
|
|
46
|
+
{ name = "aiostream" },
|
|
47
|
+
{ name = "pydantic" },
|
|
48
|
+
{ name = "pydantic-settings" },
|
|
49
|
+
]
|
|
50
|
+
sdist = { url = "https://files.pythonhosted.org/packages/e0/51/91d85cc23e275bb51a5cae47873af9a7160f62797b25663d902cf38e6ab7/icij_common-0.8.2.tar.gz", hash = "sha256:7db68266d8facb43142131d81e998cd74c6ae73508456743e00df43a15cc2995", size = 15937, upload-time = "2026-04-07T12:13:39.774Z" }
|
|
51
|
+
wheels = [
|
|
52
|
+
{ url = "https://files.pythonhosted.org/packages/15/5a/99d123230023124ba4ec67765feb2a04b656ae1f473a14f6b29cc54b02bf/icij_common-0.8.2-py3-none-any.whl", hash = "sha256:c5a1a3ccd54e7bf53acad293a0af50ab15156b225791b43383197b896bae955f", size = 20565, upload-time = "2026-04-07T12:13:38.709Z" },
|
|
53
|
+
]
|
|
54
|
+
|
|
55
|
+
[[package]]
|
|
56
|
+
name = "pycountry"
|
|
57
|
+
version = "26.2.16"
|
|
58
|
+
source = { registry = "https://pypi.org/simple" }
|
|
59
|
+
sdist = { url = "https://files.pythonhosted.org/packages/de/1d/061b9e7a48b85cfd69f33c33d2ef784a531c359399ad764243399673c8f5/pycountry-26.2.16.tar.gz", hash = "sha256:5b6027d453fcd6060112b951dd010f01f168b51b4bf8a1f1fc8c95c8d94a0801", size = 7711342, upload-time = "2026-02-17T03:42:52.367Z" }
|
|
60
|
+
wheels = [
|
|
61
|
+
{ url = "https://files.pythonhosted.org/packages/9c/42/7703bd45b62fecd44cd7d3495423097e2f7d28bc2e99e7c1af68892ab157/pycountry-26.2.16-py3-none-any.whl", hash = "sha256:115c4baf7cceaa30f59a4694d79483c9167dbce7a9de4d3d571c5f3ea77c305a", size = 8044600, upload-time = "2026-02-17T03:42:49.777Z" },
|
|
62
|
+
]
|
|
63
|
+
|
|
64
|
+
[[package]]
|
|
65
|
+
name = "pydantic"
|
|
66
|
+
version = "2.13.4"
|
|
67
|
+
source = { registry = "https://pypi.org/simple" }
|
|
68
|
+
dependencies = [
|
|
69
|
+
{ name = "annotated-types" },
|
|
70
|
+
{ name = "pydantic-core" },
|
|
71
|
+
{ name = "typing-extensions" },
|
|
72
|
+
{ name = "typing-inspection" },
|
|
73
|
+
]
|
|
74
|
+
sdist = { url = "https://files.pythonhosted.org/packages/18/a5/b60d21ac674192f8ab0ba4e9fd860690f9b4a6e51ca5df118733b487d8d6/pydantic-2.13.4.tar.gz", hash = "sha256:c40756b57adaa8b1efeeced5c196f3f3b7c435f90e84ea7f443901bec8099ef6", size = 844775, upload-time = "2026-05-06T13:43:05.343Z" }
|
|
75
|
+
wheels = [
|
|
76
|
+
{ url = "https://files.pythonhosted.org/packages/fd/7b/122376b1fd3c62c1ed9dc80c931ace4844b3c55407b6fb2d199377c9736f/pydantic-2.13.4-py3-none-any.whl", hash = "sha256:45a282cde31d808236fd7ea9d919b128653c8b38b393d1c4ab335c62924d9aba", size = 472262, upload-time = "2026-05-06T13:43:02.641Z" },
|
|
77
|
+
]
|
|
78
|
+
|
|
79
|
+
[[package]]
|
|
80
|
+
name = "pydantic-core"
|
|
81
|
+
version = "2.46.4"
|
|
82
|
+
source = { registry = "https://pypi.org/simple" }
|
|
83
|
+
dependencies = [
|
|
84
|
+
{ name = "typing-extensions" },
|
|
85
|
+
]
|
|
86
|
+
sdist = { url = "https://files.pythonhosted.org/packages/9d/56/921726b776ace8d8f5db44c4ef961006580d91dc52b803c489fafd1aa249/pydantic_core-2.46.4.tar.gz", hash = "sha256:62f875393d7f270851f20523dd2e29f082bcc82292d66db2b64ea71f64b6e1c1", size = 471464, upload-time = "2026-05-06T13:37:06.98Z" }
|
|
87
|
+
wheels = [
|
|
88
|
+
{ url = "https://files.pythonhosted.org/packages/5c/fa/6d7708d2cfc1a832acb6aeb0cd16e801902df8a0f583bb3b4b527fde022e/pydantic_core-2.46.4-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:0e96592440881c74a213e5ad528e2b24d3d4f940de2766bed9010ab1d9e51594", size = 2111872, upload-time = "2026-05-06T13:40:27.596Z" },
|
|
89
|
+
{ url = "https://files.pythonhosted.org/packages/ae/6f/aa064a3e74b5745afbdf250594f38e7ead05e2d651bcb35994b9417a0d4d/pydantic_core-2.46.4-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:e0d65b8c354be7fb5f720c3caa8bc940bc2d20ce749c8e06135f07f8ed95dd7c", size = 1948255, upload-time = "2026-05-06T13:39:12.574Z" },
|
|
90
|
+
{ url = "https://files.pythonhosted.org/packages/43/3a/41114a9f7569b84b4d84e7a018c57c56347dac30c0d4a872946ec4e36c46/pydantic_core-2.46.4-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7bfb192b3f4b9e8a89b6277b6ce787564f62cfd272055f6e685726b111dc7826", size = 1972827, upload-time = "2026-05-06T13:38:19.841Z" },
|
|
91
|
+
{ url = "https://files.pythonhosted.org/packages/ef/25/1ab42e8048fe551934d9884e8d64daa7e990ad386f310a15981aeb6a5b08/pydantic_core-2.46.4-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:9037063db01f09b09e237c282b6792bd4da634b5402c4e7f0c61effed7701a04", size = 2041051, upload-time = "2026-05-06T13:38:10.447Z" },
|
|
92
|
+
{ url = "https://files.pythonhosted.org/packages/94/c2/1a934597ddf08da410385b3b7aae91956a5a76c635effef456074fad7e88/pydantic_core-2.46.4-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:fc010ab034c8c7452522748bf937df58020d256ccae0874463d1f4d01758af8e", size = 2221314, upload-time = "2026-05-06T13:40:13.089Z" },
|
|
93
|
+
{ url = "https://files.pythonhosted.org/packages/02/6d/9e8ad178c9c4df27ad3c8f25d1fe2a7ab0d2ba0559fad4aee5d3d1f16771/pydantic_core-2.46.4-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:8c5dac79fa1614d1e06ca695109c6105923bd9c7d1d6c918d4e637b7e6b32fd3", size = 2285146, upload-time = "2026-05-06T13:38:59.224Z" },
|
|
94
|
+
{ url = "https://files.pythonhosted.org/packages/80/50/540cd3aeefc041beb111125c4bff779831a2111fc6b15a9138cda277d32c/pydantic_core-2.46.4-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f9fa868638bf362d3d138ea55829cefb3d5f4b0d7f142234382a15e2485dbec4", size = 2089685, upload-time = "2026-05-06T13:38:17.762Z" },
|
|
95
|
+
{ url = "https://files.pythonhosted.org/packages/6b/a4/b440ad35f05f6a38f89fa0f149accb3f0e02be94ca5e15f3c449a61b4bc9/pydantic_core-2.46.4-cp311-cp311-manylinux_2_31_riscv64.whl", hash = "sha256:17299feefe090f2caa5b8e37222bb5f663e4935a8bfa6931d4102e5df1a9f398", size = 2115420, upload-time = "2026-05-06T13:37:58.195Z" },
|
|
96
|
+
{ url = "https://files.pythonhosted.org/packages/99/61/de4f55db8dfd57bfdfa9a12ec90fe1b57c4f41062f7ca86f08586b3e0ac0/pydantic_core-2.46.4-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:4c63ebc82684aa89d9a3bcbd13d515b3be44250dc68dd3bd81526c1cb31286c3", size = 2165122, upload-time = "2026-05-06T13:37:01.167Z" },
|
|
97
|
+
{ url = "https://files.pythonhosted.org/packages/f7/52/7c529d7bdb2d1068bd52f51fe32572c8301f9a4febf1948f10639f1436f5/pydantic_core-2.46.4-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:aaa2a54443eff1950ba5ddc6b6ccda0d9c84a364276a62f969bdf2a390650848", size = 2182573, upload-time = "2026-05-06T13:38:45.04Z" },
|
|
98
|
+
{ url = "https://files.pythonhosted.org/packages/37/b3/7c40325848ba78247f2812dcf9c7274e38cd801820ca6dd9fe63bcfb0eb4/pydantic_core-2.46.4-cp311-cp311-musllinux_1_1_armv7l.whl", hash = "sha256:18e5ceec2ab67e6d5f1a9085e5a24c9c4e2ac4545730bfe668680bca05e555f3", size = 2317139, upload-time = "2026-05-06T13:37:15.539Z" },
|
|
99
|
+
{ url = "https://files.pythonhosted.org/packages/d9/37/f913f81a657c865b75da6c0dbed79876073c2a43b5bd9edbe8da785e4d49/pydantic_core-2.46.4-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:a0f62d0a58f4e7da165457e995725421e0064f2255d8eccebc49f41bbc23b109", size = 2360433, upload-time = "2026-05-06T13:37:30.099Z" },
|
|
100
|
+
{ url = "https://files.pythonhosted.org/packages/c4/67/6acaa1be2567f9256b056d8477158cac7240813956ce86e49deae8e173b4/pydantic_core-2.46.4-cp311-cp311-win32.whl", hash = "sha256:041bde0a48fd37cf71cab1c9d56d3e8625a3793fef1f7dd232b3ff37e978ecda", size = 1985513, upload-time = "2026-05-06T13:38:15.669Z" },
|
|
101
|
+
{ url = "https://files.pythonhosted.org/packages/aa/e6/c505f83dfeda9a2e5c995cfd872949e4d05e12f7feb3dca72f633daefa94/pydantic_core-2.46.4-cp311-cp311-win_amd64.whl", hash = "sha256:6f2eeda33a839975441c86a4119e1383c50b47faf0cbb5176985565c6bb02c33", size = 2071114, upload-time = "2026-05-06T13:40:35.416Z" },
|
|
102
|
+
{ url = "https://files.pythonhosted.org/packages/0f/da/7a263a96d965d9d0df5e8de8a475f33495451117035b09acb110288c381f/pydantic_core-2.46.4-cp311-cp311-win_arm64.whl", hash = "sha256:14f4c5d6db102bd796a627bbb3a17b4cf4574b9ae861d8b7c9a9661c6dd3362d", size = 2044298, upload-time = "2026-05-06T13:38:29.754Z" },
|
|
103
|
+
{ url = "https://files.pythonhosted.org/packages/ce/8c/af022f0af448d7747c5154288d46b5f2bc5f17366eaa0e23e9aa04d59f3b/pydantic_core-2.46.4-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:3245406455a5d98187ec35530fd772b1d799b26667980872c8d4614991e2c4a2", size = 2106158, upload-time = "2026-05-06T13:38:57.215Z" },
|
|
104
|
+
{ url = "https://files.pythonhosted.org/packages/19/95/6195171e385007300f0f5574592e467c568becce2d937a0b6804f218bc49/pydantic_core-2.46.4-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:962ccbab7b642487b1d8b7df90ef677e03134cf1fd8880bf698649b22a69371f", size = 1951724, upload-time = "2026-05-06T13:37:02.697Z" },
|
|
105
|
+
{ url = "https://files.pythonhosted.org/packages/8e/bc/f47d1ff9cbb1620e1b5b697eef06010035735f07820180e74178226b27b3/pydantic_core-2.46.4-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8233f2947cf85404441fd7e0085f53b10c93e0ee78611099b5c7237e36aacbf7", size = 1975742, upload-time = "2026-05-06T13:37:09.448Z" },
|
|
106
|
+
{ url = "https://files.pythonhosted.org/packages/5b/11/9b9a5b0306345664a2da6410877af6e8082481b5884b3ddd78d47c6013ce/pydantic_core-2.46.4-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:3a233125ac121aa3ffba9a2b59edfc4a985a76092dc8279586ab4b71390875e7", size = 2052418, upload-time = "2026-05-06T13:37:38.234Z" },
|
|
107
|
+
{ url = "https://files.pythonhosted.org/packages/f1/b7/a65fec226f5d78fc39f4a13c4cc0c768c22b113438f60c14adc9d2865038/pydantic_core-2.46.4-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:5b712b53160b79a5850310b912a5ef8e57e56947c8ad690c227f5c9d7e561712", size = 2232274, upload-time = "2026-05-06T13:38:27.753Z" },
|
|
108
|
+
{ url = "https://files.pythonhosted.org/packages/68/f0/92039db98b907ef49269a8271f67db9cb78ae2fc68062ef7e4e77adb5f61/pydantic_core-2.46.4-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:9401557acd873c3a7f3eb9383edef8ac4968f9510e340f4808d427e75667e7b4", size = 2309940, upload-time = "2026-05-06T13:38:05.353Z" },
|
|
109
|
+
{ url = "https://files.pythonhosted.org/packages/5f/97/2aab507d3d00ca626e8e57c1eac6a79e4e5fbcc63eb99733ff55d1717f65/pydantic_core-2.46.4-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:926c9541b14b12b1681dca8a0b75feb510b06c6341b70a8e500c2fdcff837cce", size = 2094516, upload-time = "2026-05-06T13:39:10.577Z" },
|
|
110
|
+
{ url = "https://files.pythonhosted.org/packages/22/37/a8aca44d40d737dde2bc05b3c6c07dff0de07ce6f82e9f3167aeaf4d5dea/pydantic_core-2.46.4-cp312-cp312-manylinux_2_31_riscv64.whl", hash = "sha256:56cb4851bcaf3d117eddcef4fe66afd750a50274b0da8e22be256d10e5611987", size = 2136854, upload-time = "2026-05-06T13:40:22.59Z" },
|
|
111
|
+
{ url = "https://files.pythonhosted.org/packages/24/99/fcef1b79238c06a8cbec70819ac722ba76e02bc8ada9b0fd66eba40da01b/pydantic_core-2.46.4-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:c68fcd102d71ea85c5b2dfac3f4f8476eff42a9e078fd5faefff6d145063536b", size = 2180306, upload-time = "2026-05-06T13:40:10.666Z" },
|
|
112
|
+
{ url = "https://files.pythonhosted.org/packages/ae/6c/fc44000918855b42779d007ae63b0532794739027b2f417321cddbc44f6a/pydantic_core-2.46.4-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:b2f69dec1725e79a012d920df1707de5caf7ed5e08f3be4435e25803efc47458", size = 2190044, upload-time = "2026-05-06T13:40:43.231Z" },
|
|
113
|
+
{ url = "https://files.pythonhosted.org/packages/6b/65/d9cadc9f1920d7a127ad2edba16c1db7916e59719285cd6c94600b0080ba/pydantic_core-2.46.4-cp312-cp312-musllinux_1_1_armv7l.whl", hash = "sha256:8d0820e8192167f80d88d64038e609c31452eeca865b4e1d9950a27a4609b00b", size = 2329133, upload-time = "2026-05-06T13:39:57.365Z" },
|
|
114
|
+
{ url = "https://files.pythonhosted.org/packages/d0/cf/c873d91679f3a30bcf5e7ac280ce5573483e72295307685120d0d5ad3416/pydantic_core-2.46.4-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:fbdb89b3e1c94a30cc5edfce477c6e6a5dc4d8f84665b455c27582f211a1c72c", size = 2374464, upload-time = "2026-05-06T13:38:06.976Z" },
|
|
115
|
+
{ url = "https://files.pythonhosted.org/packages/47/bd/6f2fc8188f31bf10590f1e98e7b306336161fac930a8c514cd7bd828c7dc/pydantic_core-2.46.4-cp312-cp312-win32.whl", hash = "sha256:9aa768456404a8bf48a4406685ac2bec8e72b62c69313734fa3b73cf33b3a894", size = 1974823, upload-time = "2026-05-06T13:40:47.985Z" },
|
|
116
|
+
{ url = "https://files.pythonhosted.org/packages/40/8c/985c1d41ea1107c2534abd9870e4ed5c8e7669b5c308297835c001e7a1c4/pydantic_core-2.46.4-cp312-cp312-win_amd64.whl", hash = "sha256:e9c26f834c65f5752f3f06cb08cb86a913ceb7274d0db6e267808a708b46bc89", size = 2072919, upload-time = "2026-05-06T13:39:21.153Z" },
|
|
117
|
+
{ url = "https://files.pythonhosted.org/packages/c4/ba/f463d006e0c47373ca7ec5e1a261c59dc01ef4d62b2657af925fb0deee3a/pydantic_core-2.46.4-cp312-cp312-win_arm64.whl", hash = "sha256:4fc73cb559bdb54b1134a706a2802a4cddd27a0633f5abb7e53056268751ac6a", size = 2027604, upload-time = "2026-05-06T13:39:03.753Z" },
|
|
118
|
+
{ url = "https://files.pythonhosted.org/packages/51/a2/5d30b469c5267a17b39dec53208222f76a8d351dfac4af661888c5aee77d/pydantic_core-2.46.4-cp313-cp313-macosx_10_12_x86_64.whl", hash = "sha256:5d5902252db0d3cedf8d4a1bc68f70eeb430f7e4c7104c8c476753519b423008", size = 2106306, upload-time = "2026-05-06T13:37:48.029Z" },
|
|
119
|
+
{ url = "https://files.pythonhosted.org/packages/c1/81/4fa520eaffa8bd7d1525e644cd6d39e7d60b1592bc5b516693c7340b50f1/pydantic_core-2.46.4-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:c94f0688e7b8d0a67abf40e57a7eaaecd17cc9586706a31b76c031f63df052b4", size = 1951906, upload-time = "2026-05-06T13:37:17.012Z" },
|
|
120
|
+
{ url = "https://files.pythonhosted.org/packages/03/d5/fd02da45b659668b05923b17ba3a0100a0a3d5541e3bd8fcc4ecb711309e/pydantic_core-2.46.4-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f027324c56cd5406ca49c124b0db10e56c69064fec039acc571c29020cc87c76", size = 1976802, upload-time = "2026-05-06T13:37:35.113Z" },
|
|
121
|
+
{ url = "https://files.pythonhosted.org/packages/21/f2/95727e1368be3d3ed485eaab7adbd7dda408f33f7a36e8b48e0144002b91/pydantic_core-2.46.4-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:e739fee756ba1010f8bcccb534252e85a35fe45ae92c295a06059ce58b74ccd3", size = 2052446, upload-time = "2026-05-06T13:37:12.313Z" },
|
|
122
|
+
{ url = "https://files.pythonhosted.org/packages/9c/86/5d99feea3f77c7234b8718075b23db11532773c1a0dbd9b9490215dc2eeb/pydantic_core-2.46.4-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:9d56801be94b86a9da183e5f3766e6310752b99ff647e38b09a9500d88e46e76", size = 2232757, upload-time = "2026-05-06T13:39:01.149Z" },
|
|
123
|
+
{ url = "https://files.pythonhosted.org/packages/d2/3a/508ac615935ef7588cf6d9e9b91309fdc2da751af865e02a9098de88258c/pydantic_core-2.46.4-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2412e734dcb48da14d4e4006b82b46b74f2518b8a26ee7e58c6844a6cd6d03c4", size = 2309275, upload-time = "2026-05-06T13:37:41.406Z" },
|
|
124
|
+
{ url = "https://files.pythonhosted.org/packages/07/f8/41db9de19d7987d6b04715a02b3b40aea467000275d9d758ffaa31af7d50/pydantic_core-2.46.4-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9551187363ffc0de2a00b2e47c25aeaeb1020b69b668762966df15fc5659dd5a", size = 2094467, upload-time = "2026-05-06T13:39:18.847Z" },
|
|
125
|
+
{ url = "https://files.pythonhosted.org/packages/2c/e2/f35033184cb11d0052daf4416e8e10a502ea2ac006fc4f459aee872727d1/pydantic_core-2.46.4-cp313-cp313-manylinux_2_31_riscv64.whl", hash = "sha256:0186750b482eefa11d7f435892b09c5c606193ef3375bcf94aa00ae6bfb66262", size = 2134417, upload-time = "2026-05-06T13:40:17.944Z" },
|
|
126
|
+
{ url = "https://files.pythonhosted.org/packages/7e/7b/6ceeb1cc90e193862f444ebe373d8fdf613f0a82572dde03fb10734c6c71/pydantic_core-2.46.4-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:5855698a4856556d86e8e6cd8434bc3ac0314ee8e12089ae0e143f64c6256e4e", size = 2179782, upload-time = "2026-05-06T13:40:32.618Z" },
|
|
127
|
+
{ url = "https://files.pythonhosted.org/packages/5a/f2/c8d7773ede6af08036423a00ae0ceffce266c3c52a096c435d68c896083f/pydantic_core-2.46.4-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:cbaf13819775b7f769bf4a1f066cb6df7a28d4480081a589828ef190226881cd", size = 2188782, upload-time = "2026-05-06T13:36:51.018Z" },
|
|
128
|
+
{ url = "https://files.pythonhosted.org/packages/59/31/0c864784e31f09f05cdd87606f08923b9c9e7f6e51dd27f20f62f975ce9f/pydantic_core-2.46.4-cp313-cp313-musllinux_1_1_armv7l.whl", hash = "sha256:633147d34cf4550417f12e2b1a0383973bdf5cdfde212cb09e9a581cf10820be", size = 2328334, upload-time = "2026-05-06T13:40:37.764Z" },
|
|
129
|
+
{ url = "https://files.pythonhosted.org/packages/c2/eb/4f6c8a41efa30baa755590f4141abf3a8c370fab610915733e74134a7270/pydantic_core-2.46.4-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:82cf5301172168103724d49a1444d3378cb20cdee30b116a1bd6031236298a5d", size = 2372986, upload-time = "2026-05-06T13:39:34.152Z" },
|
|
130
|
+
{ url = "https://files.pythonhosted.org/packages/5b/24/b375a480d53113860c299764bfe9f349a3dc9108b3adc0d7f0d786492ebf/pydantic_core-2.46.4-cp313-cp313-win32.whl", hash = "sha256:9fa8ae11da9e2b3126c6426f147e0fba88d96d65921799bb30c6abd1cb2c97fb", size = 1973693, upload-time = "2026-05-06T13:37:55.072Z" },
|
|
131
|
+
{ url = "https://files.pythonhosted.org/packages/7e/e8/cff247591966f2d22ec8c003cd7587e27b7ba7b81ab2fb888e3ab75dc285/pydantic_core-2.46.4-cp313-cp313-win_amd64.whl", hash = "sha256:6b3ace8194b0e5204818c92802dcdca7fc6d88aabbb799d7c795540d9cd6d292", size = 2071819, upload-time = "2026-05-06T13:38:49.139Z" },
|
|
132
|
+
{ url = "https://files.pythonhosted.org/packages/c6/1a/f4aee670d5670e9e148e0c82c7db98d780be566c6e6a97ee8035528ca0b3/pydantic_core-2.46.4-cp313-cp313-win_arm64.whl", hash = "sha256:184c081504d17f1c1066e430e117142b2c77d9448a97f7b65c6ac9fd9aee238d", size = 2027411, upload-time = "2026-05-06T13:40:45.796Z" },
|
|
133
|
+
{ url = "https://files.pythonhosted.org/packages/ee/a4/73995fd4ebbb46ba0ee51e6fa049b8f02c40daebb762208feda8a6b7894d/pydantic_core-2.46.4-graalpy311-graalpy242_311_native-macosx_10_12_x86_64.whl", hash = "sha256:14d4edf427bdcf950a8a02d7cb44a08614388dd6e1bdcbf4f67504fa7887da9c", size = 2111589, upload-time = "2026-05-06T13:37:10.817Z" },
|
|
134
|
+
{ url = "https://files.pythonhosted.org/packages/fb/7f/f37d3a5e8bfcc2e403f5c57a730f2d815693fb42119e8ea48b3789335af1/pydantic_core-2.46.4-graalpy311-graalpy242_311_native-macosx_11_0_arm64.whl", hash = "sha256:0ce40cd7b21210e99342afafbd4d0f76d784eb5b1d60f3bdc566be4983c6c73b", size = 1944552, upload-time = "2026-05-06T13:36:56.717Z" },
|
|
135
|
+
{ url = "https://files.pythonhosted.org/packages/15/3c/d7eb777b3ff43e8433a4efb39a17aa8fd98a4ee8561a24a67ef5db07b2d6/pydantic_core-2.46.4-graalpy311-graalpy242_311_native-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:90884113d8b48f760e9587002789ddd741e76ab9f89518cd1e43b1f1a52ec44b", size = 1982984, upload-time = "2026-05-06T13:39:06.207Z" },
|
|
136
|
+
{ url = "https://files.pythonhosted.org/packages/63/87/70b9f40170a81afd55ca26c9b2acb25c20d64bcfbf888fafecb3ba077d4c/pydantic_core-2.46.4-graalpy311-graalpy242_311_native-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:66ce7632c22d837c95301830e111ad0128a32b8207533b60896a96c4915192ea", size = 2138417, upload-time = "2026-05-06T13:39:45.476Z" },
|
|
137
|
+
{ url = "https://files.pythonhosted.org/packages/9d/1d/8987ad40f65ae1432753072f214fb5c74fe47ffbd0698bb9cbbb585664f8/pydantic_core-2.46.4-graalpy312-graalpy250_312_native-macosx_10_12_x86_64.whl", hash = "sha256:1d8ba486450b14f3b1d63bc521d410ec7565e52f887b9fb671791886436a42f7", size = 2095527, upload-time = "2026-05-06T13:39:52.283Z" },
|
|
138
|
+
{ url = "https://files.pythonhosted.org/packages/64/d3/84c282a7eee1d3ac4c0377546ef5a1ea436ce26840d9ac3b7ed54a377507/pydantic_core-2.46.4-graalpy312-graalpy250_312_native-macosx_11_0_arm64.whl", hash = "sha256:3009f12e4e90b7f88b4f9adb1b0c4a3d58fe7820f3238c190047209d148026df", size = 1936024, upload-time = "2026-05-06T13:40:15.671Z" },
|
|
139
|
+
{ url = "https://files.pythonhosted.org/packages/d7/ca/eac61596cdeb4d7e174d3dc0bd8a6238f14f75f97a24e7b7db4c7e7340a0/pydantic_core-2.46.4-graalpy312-graalpy250_312_native-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ad785e92e6dc634c21555edc8bd6b64957ab844541bcb96a1366c202951ae526", size = 1990696, upload-time = "2026-05-06T13:38:34.717Z" },
|
|
140
|
+
{ url = "https://files.pythonhosted.org/packages/fa/c3/7c8b240552251faf6b3a957db200fcfbbcec36763c050428b601e0c9b83b/pydantic_core-2.46.4-graalpy312-graalpy250_312_native-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:00c603d540afdd6b80eb39f078f33ebd46211f02f33e34a32d9f053bba711de0", size = 2147590, upload-time = "2026-05-06T13:39:29.883Z" },
|
|
141
|
+
{ url = "https://files.pythonhosted.org/packages/11/cb/428de0385b6c8d44b716feba566abfacfbd23ee3c4439faa789a1456242f/pydantic_core-2.46.4-pp311-pypy311_pp73-macosx_10_12_x86_64.whl", hash = "sha256:0c563b08bca408dc7f65f700633d8442fffb2421fc47b8101377e9fd65051ff0", size = 2112782, upload-time = "2026-05-06T13:37:04.016Z" },
|
|
142
|
+
{ url = "https://files.pythonhosted.org/packages/0b/b5/6a17bdadd0fc1f170adfd05a20d37c832f52b117b4d9131da1f41bb097ce/pydantic_core-2.46.4-pp311-pypy311_pp73-macosx_11_0_arm64.whl", hash = "sha256:db06ffe51636ffe9ca531fe9023dd64bdd794be8754cb5df57c5498ae5b518a7", size = 1952146, upload-time = "2026-05-06T13:39:43.092Z" },
|
|
143
|
+
{ url = "https://files.pythonhosted.org/packages/2a/dc/03734d80e362cd43ef65428e9de77c730ce7f2f11c60d2b1e1b39f0fbf99/pydantic_core-2.46.4-pp311-pypy311_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:133878133d271ade3d41d1bfb2a45ec38dbdbda40bc065921c6b04e4630127e2", size = 2134492, upload-time = "2026-05-06T13:36:58.124Z" },
|
|
144
|
+
{ url = "https://files.pythonhosted.org/packages/de/df/5e5ffc085ed07cc22d298134d3d911c63e91f6a0eb91fe646750a3209910/pydantic_core-2.46.4-pp311-pypy311_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:9bc519fbf2b7578398853d815009ae5e4d4603d12f4e3f91da8c06852d3da3e9", size = 2156604, upload-time = "2026-05-06T13:37:49.88Z" },
|
|
145
|
+
{ url = "https://files.pythonhosted.org/packages/81/44/6e112a4253e56f5705467cbab7ab5e91ee7398ba3d56d358635958893d3e/pydantic_core-2.46.4-pp311-pypy311_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:c7a7bd4e39e8e4c12c39cd480356842b6a8a06e41b23a55a5e3e191718838ddf", size = 2183828, upload-time = "2026-05-06T13:37:43.053Z" },
|
|
146
|
+
{ url = "https://files.pythonhosted.org/packages/ac/ad/5565071e937d8e752842ac241463944c9eb14c87e2d269f2658a5bd05e98/pydantic_core-2.46.4-pp311-pypy311_pp73-musllinux_1_1_armv7l.whl", hash = "sha256:d396ec2b979760aaf3218e76c24e65bd0aca24983298653b3a9d7a45f9e47b30", size = 2310000, upload-time = "2026-05-06T13:37:56.694Z" },
|
|
147
|
+
{ url = "https://files.pythonhosted.org/packages/4f/c3/66883a5cec183e7fba4d024b4cbbe61851a63750ef606b0afecc46d1f2bf/pydantic_core-2.46.4-pp311-pypy311_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:86e1a4418c6cd97d60c95c71164158eaf7324fae7b0923264016baa993eba6fc", size = 2361286, upload-time = "2026-05-06T13:40:05.667Z" },
|
|
148
|
+
{ url = "https://files.pythonhosted.org/packages/4b/2d/69abac8f838090bbecd5df894befb2c2619e7996a98ddb949db9f3b93225/pydantic_core-2.46.4-pp311-pypy311_pp73-win_amd64.whl", hash = "sha256:d51026d73fcfd93610abc7b27789c26b313920fcfb20e27462d74a7f8b06e983", size = 2193071, upload-time = "2026-05-06T13:38:08.682Z" },
|
|
149
|
+
]
|
|
150
|
+
|
|
151
|
+
[[package]]
|
|
152
|
+
name = "pydantic-extra-types"
|
|
153
|
+
version = "2.11.1"
|
|
154
|
+
source = { registry = "https://pypi.org/simple" }
|
|
155
|
+
dependencies = [
|
|
156
|
+
{ name = "pydantic" },
|
|
157
|
+
{ name = "typing-extensions" },
|
|
158
|
+
]
|
|
159
|
+
sdist = { url = "https://files.pythonhosted.org/packages/66/71/dba38ee2651f84f7842206adbd2233d8bbdb59fb85e9fa14232486a8c471/pydantic_extra_types-2.11.1.tar.gz", hash = "sha256:46792d2307383859e923d8fcefa82108b1a141f8a9c0198982b3832ab5ef1049", size = 172002, upload-time = "2026-03-16T08:08:03.92Z" }
|
|
160
|
+
wheels = [
|
|
161
|
+
{ url = "https://files.pythonhosted.org/packages/17/c1/3226e6d7f5a4f736f38ac11a6fbb262d701889802595cdb0f53a885ac2e0/pydantic_extra_types-2.11.1-py3-none-any.whl", hash = "sha256:1722ea2bddae5628ace25f2aa685b69978ef533123e5638cfbddb999e0100ec1", size = 79526, upload-time = "2026-03-16T08:08:02.533Z" },
|
|
162
|
+
]
|
|
163
|
+
|
|
164
|
+
[package.optional-dependencies]
|
|
165
|
+
pycountry = [
|
|
166
|
+
{ name = "pycountry" },
|
|
167
|
+
]
|
|
168
|
+
|
|
169
|
+
[[package]]
|
|
170
|
+
name = "pydantic-settings"
|
|
171
|
+
version = "2.14.1"
|
|
172
|
+
source = { registry = "https://pypi.org/simple" }
|
|
173
|
+
dependencies = [
|
|
174
|
+
{ name = "pydantic" },
|
|
175
|
+
{ name = "python-dotenv" },
|
|
176
|
+
{ name = "typing-inspection" },
|
|
177
|
+
]
|
|
178
|
+
sdist = { url = "https://files.pythonhosted.org/packages/07/60/1d1e59c9c90d54591469ada7d268251f71c24bdb765f1a8a832cee8c6653/pydantic_settings-2.14.1.tar.gz", hash = "sha256:e874d3bec7e787b0c9958277956ed9b4dd5de6a80e162188fdaff7c5e26fd5fa", size = 235551, upload-time = "2026-05-08T13:40:06.542Z" }
|
|
179
|
+
wheels = [
|
|
180
|
+
{ url = "https://files.pythonhosted.org/packages/ae/8d/f1af3832f5e6eb13ba94ee809e72b8ecb5eef226d27ee0bef7d963d943c7/pydantic_settings-2.14.1-py3-none-any.whl", hash = "sha256:6e3c7edfd8277687cdc598f56e5cff0e9bfff0910a3749deaa8d4401c3a2b9de", size = 60964, upload-time = "2026-05-08T13:40:04.958Z" },
|
|
181
|
+
]
|
|
182
|
+
|
|
183
|
+
[[package]]
|
|
184
|
+
name = "python-dotenv"
|
|
185
|
+
version = "1.2.2"
|
|
186
|
+
source = { registry = "https://pypi.org/simple" }
|
|
187
|
+
sdist = { url = "https://files.pythonhosted.org/packages/82/ed/0301aeeac3e5353ef3d94b6ec08bbcabd04a72018415dcb29e588514bba8/python_dotenv-1.2.2.tar.gz", hash = "sha256:2c371a91fbd7ba082c2c1dc1f8bf89ca22564a087c2c287cd9b662adde799cf3", size = 50135, upload-time = "2026-03-01T16:00:26.196Z" }
|
|
188
|
+
wheels = [
|
|
189
|
+
{ url = "https://files.pythonhosted.org/packages/0b/d7/1959b9648791274998a9c3526f6d0ec8fd2233e4d4acce81bbae76b44b2a/python_dotenv-1.2.2-py3-none-any.whl", hash = "sha256:1d8214789a24de455a8b8bd8ae6fe3c6b69a5e3d64aa8a8e5d68e694bbcb285a", size = 22101, upload-time = "2026-03-01T16:00:25.09Z" },
|
|
190
|
+
]
|
|
191
|
+
|
|
192
|
+
[[package]]
|
|
193
|
+
name = "typing-extensions"
|
|
194
|
+
version = "4.15.0"
|
|
195
|
+
source = { registry = "https://pypi.org/simple" }
|
|
196
|
+
sdist = { url = "https://files.pythonhosted.org/packages/72/94/1a15dd82efb362ac84269196e94cf00f187f7ed21c242792a923cdb1c61f/typing_extensions-4.15.0.tar.gz", hash = "sha256:0cea48d173cc12fa28ecabc3b837ea3cf6f38c6d1136f85cbaaf598984861466", size = 109391, upload-time = "2025-08-25T13:49:26.313Z" }
|
|
197
|
+
wheels = [
|
|
198
|
+
{ url = "https://files.pythonhosted.org/packages/18/67/36e9267722cc04a6b9f15c7f3441c2363321a3ea07da7ae0c0707beb2a9c/typing_extensions-4.15.0-py3-none-any.whl", hash = "sha256:f0fa19c6845758ab08074a0cfa8b7aecb71c999ca73d62883bc25cc018c4e548", size = 44614, upload-time = "2025-08-25T13:49:24.86Z" },
|
|
199
|
+
]
|
|
200
|
+
|
|
201
|
+
[[package]]
|
|
202
|
+
name = "typing-inspection"
|
|
203
|
+
version = "0.4.2"
|
|
204
|
+
source = { registry = "https://pypi.org/simple" }
|
|
205
|
+
dependencies = [
|
|
206
|
+
{ name = "typing-extensions" },
|
|
207
|
+
]
|
|
208
|
+
sdist = { url = "https://files.pythonhosted.org/packages/55/e3/70399cb7dd41c10ac53367ae42139cf4b1ca5f36bb3dc6c9d33acdb43655/typing_inspection-0.4.2.tar.gz", hash = "sha256:ba561c48a67c5958007083d386c3295464928b01faa735ab8547c5692e87f464", size = 75949, upload-time = "2025-10-01T02:14:41.687Z" }
|
|
209
|
+
wheels = [
|
|
210
|
+
{ url = "https://files.pythonhosted.org/packages/dc/9b/47798a6c91d8bdb567fe2698fe81e0c6b7cb7ef4d13da4114b41d239f65d/typing_inspection-0.4.2-py3-none-any.whl", hash = "sha256:4ed1cacbdc298c220f1bd249ed5287caa16f34d44ef4e9c3d0cbad5b521545e7", size = 14611, upload-time = "2025-10-01T02:14:40.154Z" },
|
|
211
|
+
]
|