lattifai 1.2.0__py3-none-any.whl → 1.2.1__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.
- lattifai/__init__.py +0 -24
- lattifai/alignment/lattice1_aligner.py +1 -1
- lattifai/alignment/lattice1_worker.py +1 -6
- lattifai/alignment/segmenter.py +1 -1
- lattifai/alignment/sentence_splitter.py +219 -0
- lattifai/alignment/tokenizer.py +10 -181
- lattifai/caption/caption.py +0 -2
- lattifai/caption/gemini_reader.py +151 -60
- lattifai/cli/transcribe.py +3 -8
- lattifai/client.py +91 -47
- lattifai/config/alignment.py +2 -2
- lattifai/mixin.py +10 -4
- lattifai/utils.py +74 -0
- {lattifai-1.2.0.dist-info → lattifai-1.2.1.dist-info}/METADATA +2 -1
- {lattifai-1.2.0.dist-info → lattifai-1.2.1.dist-info}/RECORD +19 -18
- {lattifai-1.2.0.dist-info → lattifai-1.2.1.dist-info}/WHEEL +0 -0
- {lattifai-1.2.0.dist-info → lattifai-1.2.1.dist-info}/entry_points.txt +0 -0
- {lattifai-1.2.0.dist-info → lattifai-1.2.1.dist-info}/licenses/LICENSE +0 -0
- {lattifai-1.2.0.dist-info → lattifai-1.2.1.dist-info}/top_level.txt +0 -0
lattifai/utils.py
CHANGED
|
@@ -44,6 +44,49 @@ def safe_print(text: str, **kwargs) -> None:
|
|
|
44
44
|
print(text.encode("utf-8", errors="replace").decode("utf-8"), **kwargs)
|
|
45
45
|
|
|
46
46
|
|
|
47
|
+
def _get_cache_marker_path(cache_dir: Path) -> Path:
|
|
48
|
+
"""Get the path for the cache marker file with current date."""
|
|
49
|
+
today = datetime.now().strftime("%Y%m%d")
|
|
50
|
+
return cache_dir / f".done{today}"
|
|
51
|
+
|
|
52
|
+
|
|
53
|
+
def _is_cache_valid(cache_dir: Path) -> bool:
|
|
54
|
+
"""Check if cached model is valid (exists and not older than 1 days)."""
|
|
55
|
+
if not cache_dir.exists():
|
|
56
|
+
return False
|
|
57
|
+
|
|
58
|
+
# Find any .done* marker files
|
|
59
|
+
marker_files = list(cache_dir.glob(".done*"))
|
|
60
|
+
if not marker_files:
|
|
61
|
+
return False
|
|
62
|
+
|
|
63
|
+
# Get the most recent marker file
|
|
64
|
+
latest_marker = max(marker_files, key=lambda p: p.stat().st_mtime)
|
|
65
|
+
|
|
66
|
+
# Extract date from marker filename (format: .doneYYYYMMDD)
|
|
67
|
+
try:
|
|
68
|
+
date_str = latest_marker.name.replace(".done", "")
|
|
69
|
+
marker_date = datetime.strptime(date_str, "%Y%m%d")
|
|
70
|
+
# Check if marker is older than 1 days
|
|
71
|
+
if datetime.now() - marker_date > timedelta(days=7):
|
|
72
|
+
return False
|
|
73
|
+
return True
|
|
74
|
+
except (ValueError, IndexError):
|
|
75
|
+
# Invalid marker file format, treat as invalid cache
|
|
76
|
+
return False
|
|
77
|
+
|
|
78
|
+
|
|
79
|
+
def _create_cache_marker(cache_dir: Path) -> None:
|
|
80
|
+
"""Create a cache marker file with current date and clean old markers."""
|
|
81
|
+
# Remove old marker files
|
|
82
|
+
for old_marker in cache_dir.glob(".done*"):
|
|
83
|
+
old_marker.unlink(missing_ok=True)
|
|
84
|
+
|
|
85
|
+
# Create new marker file
|
|
86
|
+
marker_path = _get_cache_marker_path(cache_dir)
|
|
87
|
+
marker_path.touch()
|
|
88
|
+
|
|
89
|
+
|
|
47
90
|
def _resolve_model_path(model_name_or_path: str, model_hub: str = "huggingface") -> str:
|
|
48
91
|
"""Resolve model path, downloading from the specified model hub when necessary.
|
|
49
92
|
|
|
@@ -66,6 +109,7 @@ def _resolve_model_path(model_name_or_path: str, model_hub: str = "huggingface")
|
|
|
66
109
|
|
|
67
110
|
if hub == "huggingface":
|
|
68
111
|
from huggingface_hub import HfApi, snapshot_download
|
|
112
|
+
from huggingface_hub.constants import HF_HUB_CACHE
|
|
69
113
|
from huggingface_hub.errors import LocalEntryNotFoundError
|
|
70
114
|
|
|
71
115
|
# Support repo_id@revision syntax
|
|
@@ -74,6 +118,20 @@ def _resolve_model_path(model_name_or_path: str, model_hub: str = "huggingface")
|
|
|
74
118
|
if "@" in model_name_or_path:
|
|
75
119
|
hf_repo_id, revision = model_name_or_path.split("@", 1)
|
|
76
120
|
|
|
121
|
+
# Determine cache directory for this model
|
|
122
|
+
cache_dir = Path(HF_HUB_CACHE) / f'models--{hf_repo_id.replace("/", "--")}'
|
|
123
|
+
|
|
124
|
+
# Check if we have a valid cached version
|
|
125
|
+
if _is_cache_valid(cache_dir):
|
|
126
|
+
# Return the snapshot path (latest version)
|
|
127
|
+
snapshots_dir = cache_dir / "snapshots"
|
|
128
|
+
if snapshots_dir.exists():
|
|
129
|
+
snapshot_dirs = [d for d in snapshots_dir.iterdir() if d.is_dir()]
|
|
130
|
+
if snapshot_dirs:
|
|
131
|
+
# Return the most recent snapshot
|
|
132
|
+
latest_snapshot = max(snapshot_dirs, key=lambda p: p.stat().st_mtime)
|
|
133
|
+
return str(latest_snapshot)
|
|
134
|
+
|
|
77
135
|
# If no specific revision/commit is provided, try to fetch the real latest SHA
|
|
78
136
|
# to bypass Hugging Face's model_info (metadata) sync lag.
|
|
79
137
|
if not revision:
|
|
@@ -91,6 +149,7 @@ def _resolve_model_path(model_name_or_path: str, model_hub: str = "huggingface")
|
|
|
91
149
|
|
|
92
150
|
try:
|
|
93
151
|
downloaded_path = snapshot_download(repo_id=hf_repo_id, repo_type="model", revision=revision)
|
|
152
|
+
_create_cache_marker(cache_dir)
|
|
94
153
|
return downloaded_path
|
|
95
154
|
except LocalEntryNotFoundError:
|
|
96
155
|
# Fall back to modelscope if HF entry not found
|
|
@@ -113,8 +172,23 @@ def _resolve_model_path(model_name_or_path: str, model_hub: str = "huggingface")
|
|
|
113
172
|
# modelscope path
|
|
114
173
|
from modelscope.hub.snapshot_download import snapshot_download as ms_snapshot
|
|
115
174
|
|
|
175
|
+
# Determine cache directory for ModelScope
|
|
176
|
+
# ModelScope uses ~/.cache/modelscope/hub/models/{org}/{model} structure
|
|
177
|
+
modelscope_cache = Path.home() / ".cache" / "modelscope" / "hub" / "models"
|
|
178
|
+
cache_dir = modelscope_cache / model_name_or_path
|
|
179
|
+
|
|
180
|
+
# Check if we have a valid cached version
|
|
181
|
+
if _is_cache_valid(cache_dir):
|
|
182
|
+
# Return the cached path directly
|
|
183
|
+
if cache_dir.exists():
|
|
184
|
+
return str(cache_dir)
|
|
185
|
+
|
|
116
186
|
try:
|
|
117
187
|
downloaded_path = ms_snapshot(model_name_or_path)
|
|
188
|
+
# Create cache marker after successful download
|
|
189
|
+
if downloaded_path:
|
|
190
|
+
actual_cache_dir = Path(downloaded_path)
|
|
191
|
+
_create_cache_marker(actual_cache_dir)
|
|
118
192
|
return downloaded_path
|
|
119
193
|
except Exception as e: # pragma: no cover
|
|
120
194
|
raise ModelLoadError(model_name_or_path, original_error=e)
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: lattifai
|
|
3
|
-
Version: 1.2.
|
|
3
|
+
Version: 1.2.1
|
|
4
4
|
Summary: Lattifai Python SDK: Seamless Integration with Lattifai's Speech and Video AI Services
|
|
5
5
|
Author-email: Lattifai Technologies <tech@lattifai.com>
|
|
6
6
|
Maintainer-email: Lattice <tech@lattifai.com>
|
|
@@ -67,6 +67,7 @@ Requires-Dist: g2p-phonemizer>=0.4.0
|
|
|
67
67
|
Requires-Dist: av
|
|
68
68
|
Requires-Dist: wtpsplit>=2.1.7
|
|
69
69
|
Requires-Dist: modelscope==1.33.0
|
|
70
|
+
Requires-Dist: error-align-fix>=0.1.2
|
|
70
71
|
Requires-Dist: OmniSenseVoice>=0.4.2
|
|
71
72
|
Requires-Dist: nemo_toolkit_asr[asr]>=2.7.0rc4
|
|
72
73
|
Requires-Dist: pyannote-audio-notorchdeps>=4.0.2
|
|
@@ -1,20 +1,21 @@
|
|
|
1
|
-
lattifai/__init__.py,sha256=
|
|
1
|
+
lattifai/__init__.py,sha256=RXa1IK8Qt6jsAnLlxecOCZmREqv2naXx6T1Fy0g6pqU,1953
|
|
2
2
|
lattifai/audio2.py,sha256=P3N8_BwiscbetzDbkbj-n8BcMu2vWD6-MvtQvGwWWf0,17448
|
|
3
|
-
lattifai/client.py,sha256=
|
|
3
|
+
lattifai/client.py,sha256=7I3tUtW8fkhUY1G7vjIuYPdqYGcgw6BbCIjjBarhlyM,21318
|
|
4
4
|
lattifai/errors.py,sha256=LyWRGVhQ6Ak2CYn9FBYAPRgQ7_VHpxzNsXI31HXD--s,11291
|
|
5
5
|
lattifai/logging.py,sha256=MbUEeOUFlF92pA9v532DiPPWKl03S7UHCJ6Z652cf0w,2860
|
|
6
|
-
lattifai/mixin.py,sha256=
|
|
6
|
+
lattifai/mixin.py,sha256=PRBRkEGmlWSpLx_qyN0uWxPoJ0MT9Fr_unFkBSjglaU,25516
|
|
7
7
|
lattifai/types.py,sha256=SjYBfwrCBOXlICvH04niFQJ7OzTx7oTaa_npfRkB67U,659
|
|
8
|
-
lattifai/utils.py,sha256=
|
|
8
|
+
lattifai/utils.py,sha256=ZvgJIM4N11BfD8wEyjoz4K_XzcXPxSRoXoU15oy1-vg,8192
|
|
9
9
|
lattifai/alignment/__init__.py,sha256=ehpkKfjNIYUx7_M-RWD_8Efcrzd9bE-NSm0QgMMVLW0,178
|
|
10
|
-
lattifai/alignment/lattice1_aligner.py,sha256=
|
|
11
|
-
lattifai/alignment/lattice1_worker.py,sha256=
|
|
10
|
+
lattifai/alignment/lattice1_aligner.py,sha256=098liE2Tvb01X5rz6iZWtokSOvfnCydjQiEkKdZeMc8,6245
|
|
11
|
+
lattifai/alignment/lattice1_worker.py,sha256=hQbZTgncPq3n-b_l-gUPDPfm460EwuZTKveErgWLWNk,10891
|
|
12
12
|
lattifai/alignment/phonemizer.py,sha256=fbhN2DOl39lW4nQWKzyUUTMUabg7v61lB1kj8SKK-Sw,1761
|
|
13
|
-
lattifai/alignment/segmenter.py,sha256=
|
|
14
|
-
lattifai/alignment/
|
|
13
|
+
lattifai/alignment/segmenter.py,sha256=0s0eABe0rLAo7eNfl0l5e_knxmZba_BjabPdqsRD45E,6284
|
|
14
|
+
lattifai/alignment/sentence_splitter.py,sha256=lwT9ZrvcuM0c9lzLCydHEbAw-TO4Z5u6zZPen-yUPUg,9090
|
|
15
|
+
lattifai/alignment/tokenizer.py,sha256=rewOcpSv6UxgC3VmuCzMyUIlHVZhJB-FbXKKk7DGNMI,15673
|
|
15
16
|
lattifai/caption/__init__.py,sha256=6MM_2j6CaqwZ81LfSy4di2EP0ykvheRjMZKAYDx2rQs,477
|
|
16
|
-
lattifai/caption/caption.py,sha256=
|
|
17
|
-
lattifai/caption/gemini_reader.py,sha256=
|
|
17
|
+
lattifai/caption/caption.py,sha256=LB6JdKovadrLOudKeQihloLik6xMYg_nj2a8g6Dg7GY,54593
|
|
18
|
+
lattifai/caption/gemini_reader.py,sha256=jD18RqOrFWYA6b2-5yZQcZEy39hu1OU7gb9i43oo0rc,19930
|
|
18
19
|
lattifai/caption/gemini_writer.py,sha256=sYPxYEmVQcEan5WVGgSrcraxs3QJRQRh8CJkl2yUQ1s,6515
|
|
19
20
|
lattifai/caption/supervision.py,sha256=DRrM8lfKU_x9aVBcLG6xnT0xIJrnc8jzHpzcSwQOg8c,905
|
|
20
21
|
lattifai/caption/text_parser.py,sha256=XDb8KTt031uJ1hg6dpbINglGOTX-6pBcghbg3DULM1I,4633
|
|
@@ -24,10 +25,10 @@ lattifai/cli/app_installer.py,sha256=gAndH3Yo97fGRDe2CQnGtOgZZ4k3_v5ftcUo5g6xbSA
|
|
|
24
25
|
lattifai/cli/caption.py,sha256=4qQ9DFhxcfaeFMY0TB5I42x4W_gOo2zY6kjXnHnFDms,6313
|
|
25
26
|
lattifai/cli/diarization.py,sha256=GTd2vnTm6cJN6Q3mFP-ShY9bZBl1_zKzWFu-4HHcMzk,4075
|
|
26
27
|
lattifai/cli/server.py,sha256=sXMfOSse9-V79slXUU8FDLeqtI5U9zeU-5YpjTIGyVw,1186
|
|
27
|
-
lattifai/cli/transcribe.py,sha256=
|
|
28
|
+
lattifai/cli/transcribe.py,sha256=1bKnFOxyO8KHbmtdrJC8ZEjBAnbuWhtejILOp9PkptQ,8047
|
|
28
29
|
lattifai/cli/youtube.py,sha256=9M2dpcUCvT7vVbXJCIxJwe9klJXoF2jUeLxiatslYso,6063
|
|
29
30
|
lattifai/config/__init__.py,sha256=Z8OudvS6fgfLNLu_2fvoXartQiYCECOnNfzDt-PfCN4,543
|
|
30
|
-
lattifai/config/alignment.py,sha256=
|
|
31
|
+
lattifai/config/alignment.py,sha256=dB-sX0ZnsCy7O2cX9NnU5UQ5aFaPANaCozESKv_k_vY,4620
|
|
31
32
|
lattifai/config/caption.py,sha256=AYOyUJ1xZsX8CBZy3GpLitbcCAHcZ9LwXui_v3vtuso,6786
|
|
32
33
|
lattifai/config/client.py,sha256=46b816MiYja3Uan_3wjnhtqDr0M6T-FqEygJ3e50IZc,1664
|
|
33
34
|
lattifai/config/diarization.py,sha256=cIkwCfsYqfMns3i6tKWcwBBBkdnhhmB_Eo0TuOPCw9o,2484
|
|
@@ -49,9 +50,9 @@ lattifai/workflow/agents.py,sha256=yEOnxnhcTvr1iOhCorNvp8B76P6nQsLRXJCu_rCYFfM,3
|
|
|
49
50
|
lattifai/workflow/base.py,sha256=8QoVIBZwJfr5mppJbtUFafHv5QR9lL-XrULjTWD0oBg,6257
|
|
50
51
|
lattifai/workflow/file_manager.py,sha256=IUWW838ta83kfwM4gpW83gsD_Tx-pa-L_RWKjiefQbQ,33017
|
|
51
52
|
lattifai/workflow/youtube.py,sha256=0B1l_8gdz_O0cy2c9AY9wRPizESQrpRuCP4rwvWRxLA,23687
|
|
52
|
-
lattifai-1.2.
|
|
53
|
-
lattifai-1.2.
|
|
54
|
-
lattifai-1.2.
|
|
55
|
-
lattifai-1.2.
|
|
56
|
-
lattifai-1.2.
|
|
57
|
-
lattifai-1.2.
|
|
53
|
+
lattifai-1.2.1.dist-info/licenses/LICENSE,sha256=xGMLmdFJy6Jkz3Hd0znyQLmcxC93FSZB5isKnEDMoQQ,1066
|
|
54
|
+
lattifai-1.2.1.dist-info/METADATA,sha256=qw4slozNhu8oHN4Hku7XP_wJ9IuKZsNCqTyGbm3E9oM,37437
|
|
55
|
+
lattifai-1.2.1.dist-info/WHEEL,sha256=SmOxYU7pzNKBqASvQJ7DjX3XGUF92lrGhMb3R6_iiqI,91
|
|
56
|
+
lattifai-1.2.1.dist-info/entry_points.txt,sha256=nHZri2VQkPYEl0tQ0dMYTpVGlCOgVWlDG_JtDR3QXF8,545
|
|
57
|
+
lattifai-1.2.1.dist-info/top_level.txt,sha256=tHSoXF26r-IGfbIP_JoYATqbmf14h5NrnNJGH4j5reI,9
|
|
58
|
+
lattifai-1.2.1.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|