From fc6fa1cdb961482656e9acfdff008ae68767e28b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Felix=20M=C3=BCller?= Date: Wed, 28 Jan 2026 21:05:30 +0100 Subject: [PATCH] feat: replace fast-langdetect with lingua-language-detector Migrate language detection from fast-langdetect + fasttext-predict to lingua-language-detector (Rust/PyO3). This eliminates the NumPy copy-error workaround, removes runtime model downloads, and enables Python 3.13/3.14 support. - Replace dependencies in pyproject.toml, add 3.13/3.14 classifiers - Rewrite _default_language_detector in language.py to use lingua - Rewrite _create_language_detector in postedit.py, remove fasttext workaround methods and unused imports - Remove fasttext logger suppression and download patching from translate_cli.py - Update tests to mock lingua instead of fast-langdetect - Bump .python-version to 3.13, update CI matrix to [3.10, 3.13] Co-Authored-By: Claude Opus 4.5 --- .github/workflows/build.yml | 2 +- .python-version | 2 +- pyproject.toml | 7 +- src/scribae/language.py | 57 ++--------- src/scribae/translate/postedit.py | 78 ++------------ src/scribae/translate_cli.py | 18 +--- tests/unit/language_test.py | 59 ++++------- tests/unit/test_postedit.py | 100 +++++------------- tests/unit/write_cli_test.py | 1 + uv.lock | 165 +++++++++--------------------- 10 files changed, 116 insertions(+), 373 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 0ddffa8..84bd099 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -35,7 +35,7 @@ jobs: strategy: fail-fast: false matrix: - python-version: ["3.10", "3.12"] + python-version: ["3.10", "3.13"] steps: - name: Checkout code uses: actions/checkout@v6 diff --git a/.python-version b/.python-version index e4fba21..24ee5b1 100644 --- a/.python-version +++ b/.python-version @@ -1 +1 @@ -3.12 +3.13 diff --git a/pyproject.toml b/pyproject.toml index 8ea0b3e..ad41e2c 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -26,6 +26,8 @@ classifiers = [ "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.11", "Programming Language :: Python :: 3.12", + "Programming Language :: Python :: 3.13", + "Programming Language :: Python :: 3.14", "Topic :: Text Processing", "Topic :: Text Processing :: Linguistic", ] @@ -38,8 +40,7 @@ dependencies = [ "transformers>=4.46.3", "sentencepiece>=0.2.0", "sacremoses>=0.1.1", - "fast-langdetect>=1.0.0", - "fasttext-predict==0.9.2.4", + "lingua-language-detector>=2.0.0", "tomli>=2.0.0;python_version<'3.11'", ] @@ -105,7 +106,7 @@ disallow_untyped_defs = true warn_unused_ignores = true [[tool.mypy.overrides]] -module = ["frontmatter", "yaml", "tomli"] +module = ["frontmatter", "lingua", "yaml", "tomli"] ignore_missing_imports = true [tool.pytest.ini_options] diff --git a/src/scribae/language.py b/src/scribae/language.py index 9466d94..6615ac1 100644 --- a/src/scribae/language.py +++ b/src/scribae/language.py @@ -136,36 +136,21 @@ def _detect_language(text: str, language_detector: Callable[[str], str] | None) def _default_language_detector() -> Callable[[str], str]: - copy_error = "Unable to avoid copy while creating an array as requested" try: - import fast_langdetect # type: ignore[import-untyped] - except Exception as exc: # pragma: no cover - defensive fallback + from lingua import LanguageDetectorBuilder + except ImportError as exc: # pragma: no cover - defensive fallback return _naive_detector(exc) try: - detector = fast_langdetect.LangDetector() + detector = LanguageDetectorBuilder.from_all_languages().build() except Exception as exc: # pragma: no cover - defensive fallback return _naive_detector(exc) - naive = _naive_detector(None) - def _detect(sample: str) -> str: - try: - results = detector.detect(sample, model="auto", k=1, threshold=0.0) - except ValueError as exc: - if copy_error in str(exc): - results = _detect_with_fasttext_copy_fix(detector, sample) - else: - return naive(sample) - except Exception: - return naive(sample) - if not results: - return naive(sample) - first = results[0] - lang = first.get("lang") if isinstance(first, Mapping) else None - if not isinstance(lang, str) or not lang: - return naive(sample) - return normalize_language(lang) + result = detector.detect_language_of(sample) + if result is None: + raise LanguageResolutionError("lingua could not identify the language.") + return result.iso_code_639_1.name.lower() return _detect @@ -194,34 +179,6 @@ def _report(reporter: Callable[[str], None] | None, message: str) -> None: reporter(message) -def _detect_with_fasttext_copy_fix(detector: Any, text: str) -> list[dict[str, object]]: - try: - ft_model = detector._get_model(low_memory=False, fallback_on_memory_error=True) - processed = detector._preprocess_text(text) - normalized = detector._normalize_text(processed, detector.config.normalize_input) - except Exception: - return [] - - if "\n" in normalized: - return [] - - raw_predictor = getattr(ft_model, "f", None) - if raw_predictor is None or not hasattr(raw_predictor, "predict"): - return [] - - try: - predictions = raw_predictor.predict(f"{normalized}\n", 1, 0.0, "strict") - except Exception: - return [] - - if not predictions: - return [] - - scored = [(str(label).replace("__label__", ""), min(float(score), 1.0)) for score, label in predictions] - scored.sort(key=lambda item: item[1], reverse=True) - return [{"lang": label, "score": score} for label, score in scored] - - __all__ = [ "LanguageResolution", "LanguageResolutionError", diff --git a/src/scribae/translate/postedit.py b/src/scribae/translate/postedit.py index fb5141e..55fd616 100644 --- a/src/scribae/translate/postedit.py +++ b/src/scribae/translate/postedit.py @@ -1,11 +1,9 @@ from __future__ import annotations import asyncio -import importlib -import os from collections.abc import Callable, Iterable from dataclasses import dataclass -from typing import TYPE_CHECKING, Any, Literal, cast +from typing import TYPE_CHECKING from pydantic_ai import Agent, NativeOutput, UnexpectedModelBehavior from pydantic_ai.settings import ModelSettings @@ -202,80 +200,18 @@ def _get_language_detector(self) -> Callable[[str], str]: return self._language_detector def _create_language_detector(self) -> Callable[[str], str]: - fast_langdetect = importlib.import_module("fast_langdetect") - config_kwargs: dict[str, Any] = {} - env_model_path = os.getenv("FASTTEXT_LID_MODEL") - if env_model_path: - config_kwargs["custom_model_path"] = env_model_path + from lingua import LanguageDetectorBuilder - config = fast_langdetect.LangDetectConfig(**config_kwargs) if config_kwargs else None - detector = fast_langdetect.LangDetector(config) if config else fast_langdetect.LangDetector() + detector = LanguageDetectorBuilder.from_all_languages().build() def _detect(text: str) -> str: - results = self._detect_labels(detector, text, model="auto", k=1, threshold=0.0) - if not results: - raise UnexpectedModelBehavior("language detector returned no labels") - lang = results[0].get("lang") - if not isinstance(lang, str) or not lang: - raise UnexpectedModelBehavior("language detector returned invalid language label") - return self._normalize_lang(lang) + result = detector.detect_language_of(text) + if result is None: + raise UnexpectedModelBehavior("lingua could not identify the language") + return self._normalize_lang(result.iso_code_639_1.name.lower()) return _detect - def _detect_labels( - self, - detector: Any, - text: str, - *, - model: Literal["lite", "full", "auto"], - k: int, - threshold: float, - ) -> list[dict[str, object]]: - try: - return cast(list[dict[str, object]], detector.detect(text, model=model, k=k, threshold=threshold)) - except ValueError as exc: - message = str(exc) - copy_error = "Unable to avoid copy while creating an array as requested" - if copy_error not in message: - raise - return self._detect_with_fasttext_copy_fix(detector, text, model=model, k=k, threshold=threshold) - - def _detect_with_fasttext_copy_fix( - self, - detector: Any, - text: str, - *, - model: Literal["lite", "full", "auto"], - k: int, - threshold: float, - ) -> list[dict[str, object]]: - if model not in {"lite", "full", "auto"}: - raise UnexpectedModelBehavior(f"Invalid language detection model '{model}'") - - if model == "lite": - ft_model = detector._get_model(low_memory=True, fallback_on_memory_error=False) - elif model == "full": - ft_model = detector._get_model(low_memory=False, fallback_on_memory_error=False) - else: - ft_model = detector._get_model(low_memory=False, fallback_on_memory_error=True) - - processed = detector._preprocess_text(text) - normalized = detector._normalize_text(processed, detector.config.normalize_input) - if "\n" in normalized: - raise UnexpectedModelBehavior("language detection input contains newline characters") - - raw_predictor = getattr(ft_model, "f", None) - if raw_predictor is None or not hasattr(raw_predictor, "predict"): - raise UnexpectedModelBehavior("fasttext model missing raw predictor for copy-safe language detection") - - predictions = cast(list[tuple[float, str]], raw_predictor.predict(f"{normalized}\n", k, threshold, "strict")) - if not predictions: - return [] - - scored = [(str(label).replace("__label__", ""), min(float(score), 1.0)) for score, label in predictions] - scored.sort(key=lambda item: item[1], reverse=True) - return [{"lang": label, "score": score} for label, score in scored] - def _leading_markdown_marker(self, line: str) -> str: """Return the Markdown prefix (blockquote, list, heading) if present.""" import re diff --git a/src/scribae/translate_cli.py b/src/scribae/translate_cli.py index f17a58c..3410000 100644 --- a/src/scribae/translate_cli.py +++ b/src/scribae/translate_cli.py @@ -26,7 +26,7 @@ translate_app = typer.Typer() -_LIBRARY_LOGGERS = ("transformers", "huggingface_hub", "sentencepiece", "fasttext", "fast_langdetect") +_LIBRARY_LOGGERS = ("transformers", "huggingface_hub", "sentencepiece") _LANGUAGE_CODE_RE = re.compile(r"^[A-Za-z]{2,3}$|^[A-Za-z]{3}[-_][A-Za-z]{4}$") @@ -58,22 +58,6 @@ def _configure_library_logging() -> None: except Exception: pass - try: - import fast_langdetect.infer as fast_langdetect_infer # type: ignore[import-untyped] - import robust_downloader # type: ignore[import-untyped] - - original_download = robust_downloader.download - if getattr(original_download, "__name__", "") != "quiet_download": - - def quiet_download(*args: Any, **kwargs: Any) -> None: - kwargs.setdefault("show_progress", False) - kwargs.setdefault("logging_level", logging.ERROR) - original_download(*args, **kwargs) - - robust_downloader.download = quiet_download - fast_langdetect_infer.download = quiet_download - except Exception: - pass def _load_glossary(path: Path | None) -> dict[str, str]: diff --git a/tests/unit/language_test.py b/tests/unit/language_test.py index 2f0f759..23f0684 100644 --- a/tests/unit/language_test.py +++ b/tests/unit/language_test.py @@ -95,56 +95,35 @@ def invoke(prompt: str) -> str: ) -def test_default_language_detector_handles_numpy_copy_error(monkeypatch: pytest.MonkeyPatch) -> None: - class Capture: - predict_args: tuple[str, int, float, str] | None = None - model_args: tuple[bool, bool] | None = None +def test_default_language_detector_uses_lingua(monkeypatch: pytest.MonkeyPatch) -> None: + captured: dict[str, object] = {} - capture = Capture() + class FakeIsoCode: + name = "FR" - class FakeConfig: - normalize_input = True - - class FakePredictor: - def predict(self, text: str, k: int, threshold: float, mode: str) -> list[tuple[float, str]]: - capture.predict_args = (text, k, threshold, mode) - return [(0.8, "__label__FR")] - - class FakeModel: - def __init__(self) -> None: - self.f = FakePredictor() + class FakeLanguageResult: + iso_code_639_1 = FakeIsoCode() class FakeDetector: - config = FakeConfig() - - def detect( - self, - text: str, - model: str = "auto", - k: int = 1, - threshold: float = 0.0, - ) -> list[dict[str, object]]: - raise ValueError("Unable to avoid copy while creating an array as requested.") - - def _get_model(self, low_memory: bool, fallback_on_memory_error: bool) -> FakeModel: - capture.model_args = (low_memory, fallback_on_memory_error) - return FakeModel() + def detect_language_of(self, text: str) -> FakeLanguageResult: + captured["text"] = text + return FakeLanguageResult() - def _preprocess_text(self, text: str) -> str: - return text + class FakeBuilder: + @staticmethod + def from_all_languages() -> "FakeBuilder": + return FakeBuilder() - def _normalize_text(self, text: str, normalize_input: bool) -> str: - return text + def build(self) -> FakeDetector: + return FakeDetector() - class FakeModule: - LangDetector = FakeDetector + class FakeLinguaModule: + LanguageDetectorBuilder = FakeBuilder - monkeypatch.setitem(sys.modules, "fast_langdetect", FakeModule()) + monkeypatch.setitem(sys.modules, "lingua", FakeLinguaModule()) detector = language._default_language_detector() detected = detector("Bonjour le monde") assert detected == "fr" - assert capture.predict_args is not None - assert capture.predict_args[1:] == (1, 0.0, "strict") - assert capture.model_args == (False, True) + assert captured["text"] == "Bonjour le monde" diff --git a/tests/unit/test_postedit.py b/tests/unit/test_postedit.py index 2b6669c..df3fa8a 100644 --- a/tests/unit/test_postedit.py +++ b/tests/unit/test_postedit.py @@ -3,8 +3,7 @@ from __future__ import annotations import asyncio -from pathlib import Path -from typing import Any, cast +from typing import cast import pytest from pydantic_ai import Agent, UnexpectedModelBehavior @@ -251,85 +250,38 @@ def test_rejects_unexpected_language(self) -> None: with pytest.raises(UnexpectedModelBehavior): validator("Bonjour tout le monde") - def test_language_detection_uses_fast_langdetect(self, tmp_path: Path, monkeypatch: pytest.MonkeyPatch) -> None: - model_path = tmp_path / "lid.176.bin" - posteditor = LLMPostEditor(create_agent=False, language_detector=None) - monkeypatch.setenv("FASTTEXT_LID_MODEL", str(model_path)) - - captured: dict[str, Any] = {} - - class FakeConfig: - def __init__(self, **kwargs: object) -> None: - captured["config_kwargs"] = kwargs - - class FakeDetector: - def __init__(self, config: FakeConfig | None = None) -> None: - captured["config"] = config - - def detect( - self, - text: str, - model: str = "auto", - k: int = 1, - threshold: float = 0.0, - ) -> list[dict[str, object]]: - captured["detect_args"] = (text, model, k, threshold) - return [{"lang": "DE", "score": 0.9}] - - class FakeModule: - LangDetectConfig = FakeConfig - LangDetector = FakeDetector - - fake_module = FakeModule() - monkeypatch.setattr("scribae.translate.postedit.importlib.import_module", lambda name: fake_module) - - detector = posteditor._create_language_detector() - lang = detector("Hallo Welt") - - assert lang == "de" - assert captured["config_kwargs"] == {"custom_model_path": str(model_path)} - assert captured["detect_args"][1:] == ("auto", 1, 0.0) + def test_language_detection_uses_lingua(self, monkeypatch: pytest.MonkeyPatch) -> None: + import sys + import types - def test_language_detection_falls_back_on_numpy_copy_error(self) -> None: posteditor = LLMPostEditor(create_agent=False, language_detector=None) + captured: dict[str, object] = {} - class FakeDetector: - config = type("Config", (), {"normalize_input": True})() - - def __init__(self) -> None: - self.called = {"detect": 0, "predict": 0} - - def detect( - self, text: str, model: str = "auto", k: int = 1, threshold: float = 0.0 - ) -> list[dict[str, object]]: - self.called["detect"] += 1 - raise ValueError("Unable to avoid copy while creating an array as requested.") - - def _get_model(self, low_memory: bool, fallback_on_memory_error: bool) -> Any: - self.called["predict"] += 1 + class FakeIsoCode: + name = "DE" - class RawPredictor: - def __init__(self) -> None: - class F: - def predict( - self_inner, text: str, k: int, threshold: float, mode: str - ) -> list[tuple[float, str]]: - return [(0.9, "__label__EN")] + class FakeLanguageResult: + iso_code_639_1 = FakeIsoCode() - self.f = F() + class FakeDetector: + def detect_language_of(self, text: str) -> FakeLanguageResult: + captured["text"] = text + return FakeLanguageResult() - return RawPredictor() + class FakeBuilder: + @staticmethod + def from_all_languages() -> FakeBuilder: + return FakeBuilder() - def _preprocess_text(self, text: str) -> str: - return text + def build(self) -> FakeDetector: + return FakeDetector() - def _normalize_text(self, text: str, normalize_input: bool) -> str: - return text + fake_lingua = types.ModuleType("lingua") + fake_lingua.LanguageDetectorBuilder = FakeBuilder # type: ignore[attr-defined] + monkeypatch.setitem(sys.modules, "lingua", fake_lingua) - detector = FakeDetector() - results = posteditor._detect_labels(detector, "Hello", model="auto", k=1, threshold=0.0) + detector = posteditor._create_language_detector() + lang = detector("Hallo Welt") - assert results[0]["lang"] == "EN" - assert results[0]["score"] == 0.9 - assert detector.called["detect"] == 1 - assert detector.called["predict"] == 1 + assert lang == "de" + assert captured["text"] == "Hallo Welt" diff --git a/tests/unit/write_cli_test.py b/tests/unit/write_cli_test.py index b57bc3c..5765170 100644 --- a/tests/unit/write_cli_test.py +++ b/tests/unit/write_cli_test.py @@ -54,6 +54,7 @@ def __call__( def recording_llm(monkeypatch: pytest.MonkeyPatch) -> RecordingLLM: recorder = RecordingLLM() monkeypatch.setattr("scribae.write._invoke_model", recorder) + monkeypatch.setattr("scribae.language._default_language_detector", lambda: lambda _text: "en") return recorder diff --git a/uv.lock b/uv.lock index 7c760b6..916227b 100644 --- a/uv.lock +++ b/uv.lock @@ -551,18 +551,6 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/d1/d6/3965ed04c63042e047cb6a3e6ed1a63a35087b6a609aa3a15ed8ac56c221/colorama-0.4.6-py2.py3-none-any.whl", hash = "sha256:4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6", size = 25335, upload-time = "2022-10-25T02:36:20.889Z" }, ] -[[package]] -name = "colorlog" -version = "6.10.1" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "colorama", marker = "sys_platform == 'win32'" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/a2/61/f083b5ac52e505dfc1c624eafbf8c7589a0d7f32daa398d2e7590efa5fda/colorlog-6.10.1.tar.gz", hash = "sha256:eb4ae5cb65fe7fec7773c2306061a8e63e02efc2c72eba9d27b0fa23c94f1321", size = 17162, upload-time = "2025-10-16T16:14:11.978Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/6d/c1/e419ef3723a074172b68aaa89c9f3de486ed4c2399e2dbd8113a4fdcaf9e/colorlog-6.10.1-py3-none-any.whl", hash = "sha256:2d7e8348291948af66122cff006c9f8da6255d224e7cf8e37d8de2df3bad8c9c", size = 11743, upload-time = "2025-10-16T16:14:10.512Z" }, -] - [[package]] name = "cryptography" version = "46.0.3" @@ -798,20 +786,6 @@ lua = [ { name = "lupa" }, ] -[[package]] -name = "fast-langdetect" -version = "1.0.0" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "fasttext-predict" }, - { name = "requests" }, - { name = "robust-downloader" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/53/15/85b0137066be418b6249d8e8d98e2b16c072c65b80c293b9438fdea1be5e/fast_langdetect-1.0.0.tar.gz", hash = "sha256:ea8ac6a8914e0ff1bfc1bbc0f25992eb913ddb69e63ea1b24e907e263d0cd113", size = 796192, upload-time = "2025-09-17T06:32:26.86Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/f6/71/0db1ac89f8661048ebc22d62f503a2e147cb6872c5f2aeb659c1f02c1694/fast_langdetect-1.0.0-py3-none-any.whl", hash = "sha256:aab9e3435cc667ac8ba8b1a38872f75492f65b7087901d0f3a02a88d436cd22a", size = 789944, upload-time = "2025-09-17T06:32:25.363Z" }, -] - [[package]] name = "fastavro" version = "1.12.1" @@ -886,78 +860,6 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/fc/dc/f7dd14213bf511690dccaa5094d436947c253b418c86c86211d1c76e6e44/fastmcp-2.14.3-py3-none-any.whl", hash = "sha256:103c6b4c6e97a9acc251c81d303f110fe4f2bdba31353df515d66272bf1b9414", size = 416220, upload-time = "2026-01-12T20:00:42.543Z" }, ] -[[package]] -name = "fasttext-predict" -version = "0.9.2.4" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/fc/0e/9defbb9385bcb1104cc1d686a14f7d9fafe5fe43f220cccb00f33d91bb47/fasttext_predict-0.9.2.4.tar.gz", hash = "sha256:18a6fb0d74c7df9280db1f96cb75d990bfd004fa9d669493ea3dd3d54f84dbc7", size = 16332, upload-time = "2024-11-23T17:24:44.801Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/fc/ee/2350a58c071f873a454aae6bf60900fc3ddb024da3478407ac2057cbc757/fasttext_predict-0.9.2.4-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:ba432f33228928df5f2af6dfa50560cd77f9859914cffd652303fb02ba100456", size = 103885, upload-time = "2024-11-23T17:22:42.533Z" }, - { url = "https://files.pythonhosted.org/packages/fd/68/e2f8a82c02b6c4333d454a1b0464942d3dae92e4657c08411035c99fe074/fasttext_predict-0.9.2.4-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:6a8e8f17eb894d450168d2590e23d809e845bd4fad5e39b5708dacb2fdb9b2c7", size = 96415, upload-time = "2024-11-23T17:22:44.452Z" }, - { url = "https://files.pythonhosted.org/packages/a0/77/0c045793c56b9d143c44fab50f05506c47585532cc5a8f1668bf7b899ddf/fasttext_predict-0.9.2.4-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:19565fdf0bb9427831cfc75fca736ab9d71ba7ce02e3ea951e5839beb66560b6", size = 281643, upload-time = "2024-11-23T17:22:46.342Z" }, - { url = "https://files.pythonhosted.org/packages/5b/ce/c735a67b858bbdb915f3de6d12bc0ad47f0bf0dfce8fc4d42b2ce65e1226/fasttext_predict-0.9.2.4-cp310-cp310-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:cb6986815506e3261c0b3f6227dce49eeb4fd3422dab9cd37e2db2fb3691c68b", size = 306088, upload-time = "2024-11-23T17:22:47.571Z" }, - { url = "https://files.pythonhosted.org/packages/52/a1/b5838f96b6b10f9d4166fd5a5bdc2c32fc42500c236c6318512c5ede99a9/fasttext_predict-0.9.2.4-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:229dfdf8943dd76231206c7c9179e3f99d45879e5b654626ee7b73b7fa495d53", size = 294031, upload-time = "2024-11-23T17:22:49.617Z" }, - { url = "https://files.pythonhosted.org/packages/76/0c/c655919969568ffc7667185595ae56c9cb35a3c4ec3c351654eebea75de5/fasttext_predict-0.9.2.4-cp310-cp310-manylinux_2_31_armv7l.whl", hash = "sha256:397016ebfa9ec06d6dba09c29e295eea583ea3f45fa4592cc832b257dc84522e", size = 234108, upload-time = "2024-11-23T17:22:51.525Z" }, - { url = "https://files.pythonhosted.org/packages/f1/f0/b88ea4e4549d49b3202e0b4312f9bc1a42742618aaf2696d63508f861282/fasttext_predict-0.9.2.4-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:fc93f9f8f7e982eb635bc860688be04f355fab3d76a243037e26862646f50430", size = 1209246, upload-time = "2024-11-23T17:22:53.656Z" }, - { url = "https://files.pythonhosted.org/packages/59/dc/1a916fe673f67066f6bb25b5372c282db8924a231662e250646e3ce90f93/fasttext_predict-0.9.2.4-cp310-cp310-musllinux_1_2_armv7l.whl", hash = "sha256:f4be96ac0b01a3cda82be90e7f6afdafab98919995825c27babd2749a8319be9", size = 1098972, upload-time = "2024-11-23T17:22:55.792Z" }, - { url = "https://files.pythonhosted.org/packages/b5/9e/ef3aba387a9efdeefce2d9537ee9404b4b8bafe3f1209c8efa6a6cb8022d/fasttext_predict-0.9.2.4-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:f505f737f9493d22ee0c54af7c7eb7828624d5089a1e85072bdb1bd7d3f8f82e", size = 1385514, upload-time = "2024-11-23T17:22:58.022Z" }, - { url = "https://files.pythonhosted.org/packages/29/d8/b930d3eda35da0ad66335bfb154cb063cfc071dc9b7affe64ae0d90ac04c/fasttext_predict-0.9.2.4-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:9ce69f28862dd551d43e27aa0a8de924b6b34412bff998c23c3d4abd70813183", size = 1275740, upload-time = "2024-11-23T17:23:00.376Z" }, - { url = "https://files.pythonhosted.org/packages/da/13/2611784710956acc1195bcc1ad476fb4d115a30a64175e8064bb83bc30ec/fasttext_predict-0.9.2.4-cp310-cp310-win32.whl", hash = "sha256:864b6bb543275aee74360eee1d2cc23a440f09991e97efcdcf0b9a5af00f9aa9", size = 90247, upload-time = "2024-11-23T17:23:01.534Z" }, - { url = "https://files.pythonhosted.org/packages/6d/33/df75b2a1e207eda91efe35766e09dba41ef735e390b156c9c3adc0014e68/fasttext_predict-0.9.2.4-cp310-cp310-win_amd64.whl", hash = "sha256:7e72abe12c13fd12f8bb137b1f7561096fbd3bb24905a27d9e93a4921ee68dc6", size = 103099, upload-time = "2024-11-23T17:23:02.526Z" }, - { url = "https://files.pythonhosted.org/packages/c7/12/5c1ddcc721c569132f6340498527b421dcb523470a0aee1b39fcb76c9fe3/fasttext_predict-0.9.2.4-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:147996c86aa0928c7118f85d18b6a77c458db9ca236db26d44ee5ceaab0c0b6b", size = 105258, upload-time = "2024-11-23T17:23:04.364Z" }, - { url = "https://files.pythonhosted.org/packages/9f/69/6efd7db47f95a5e2e6e71f69ab3271f5002e99bb88c8f1639c109609cf12/fasttext_predict-0.9.2.4-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:5342f7363709e22524a31750c21e4b735b6666749a167fc03cc3bbf18ea8eccd", size = 97636, upload-time = "2024-11-23T17:23:06.166Z" }, - { url = "https://files.pythonhosted.org/packages/a7/67/953ca1707fdb2c4bfc5b495b78f98116b45e7b5c39a76875c8b6dcf81ce4/fasttext_predict-0.9.2.4-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6cbecd3908909339316f61db38030ce43890c25bddb06c955191458af13ccfc5", size = 284910, upload-time = "2024-11-23T17:23:07.296Z" }, - { url = "https://files.pythonhosted.org/packages/ef/c7/b60cf7e58baab5c798f616b2fa0692b8f78d6fc6279574fcfbd7c5235edb/fasttext_predict-0.9.2.4-cp311-cp311-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:9de4fcfb54bec35be6b0dffcdc5ace1a3a07f79ee3e8d33d13b82cc4116c5f2f", size = 308768, upload-time = "2024-11-23T17:23:08.5Z" }, - { url = "https://files.pythonhosted.org/packages/ee/4d/fe2d0619494700f2a85db4cf8050977e1215f484ac8596187301655dc516/fasttext_predict-0.9.2.4-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5af82e09227d993befc00271407b9d3c8aae81d34b35f96208223faf609f4b0c", size = 298342, upload-time = "2024-11-23T17:23:10.408Z" }, - { url = "https://files.pythonhosted.org/packages/ea/06/f31dc802a2c9acab454eae47902674d92e381a97a363034d359961a955ce/fasttext_predict-0.9.2.4-cp311-cp311-manylinux_2_31_armv7l.whl", hash = "sha256:337ee60179f32e8b0efa822e59316de15709c7684e7854021b4f6af82b7767ac", size = 236374, upload-time = "2024-11-23T17:23:12.435Z" }, - { url = "https://files.pythonhosted.org/packages/33/91/a4252c22f2fda855298ef683981d9986f89f9d36fd40ef4c2868cd84e4fd/fasttext_predict-0.9.2.4-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:aa9da0c52e65a45dbc87df67015ec1d2712f04de47733e197176550521feea87", size = 1212640, upload-time = "2024-11-23T17:23:13.804Z" }, - { url = "https://files.pythonhosted.org/packages/ca/3e/47e9e844d15e2b7f64e1a2f1e5897b5c1d59b23ebff64494000259610d2c/fasttext_predict-0.9.2.4-cp311-cp311-musllinux_1_2_armv7l.whl", hash = "sha256:495efde8afb622266c0e4de41978a6db731a0a685e1db032e7d22937850c9b44", size = 1100895, upload-time = "2024-11-23T17:23:16.109Z" }, - { url = "https://files.pythonhosted.org/packages/8a/f1/d49bfb81cd3b544021698f6feab1dca2fcca432097978828ad8322eab50b/fasttext_predict-0.9.2.4-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:e5726ba34d79a143b69426e29905eb4d3f4ee8aee94927b3bea3dd566712986b", size = 1385913, upload-time = "2024-11-23T17:23:17.806Z" }, - { url = "https://files.pythonhosted.org/packages/ed/4a/37bd8d31e46116fcb203b4899aeec32a3adbacf8b09ba3f5d9e3f864b7e4/fasttext_predict-0.9.2.4-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:5ac2f35830705c61dd848314c4c077a393608c181725dc353a69361821aa69a8", size = 1279522, upload-time = "2024-11-23T17:23:20.205Z" }, - { url = "https://files.pythonhosted.org/packages/64/4c/3ec10626e0b25527d10ed258ac1d7c56e5f88100d5c7abba093f918deff6/fasttext_predict-0.9.2.4-cp311-cp311-win32.whl", hash = "sha256:7b2f8a5cf5f2c451777dbb7ea4957c7919a57ce29a4157a0a381933c9ea6fa70", size = 91396, upload-time = "2024-11-23T17:23:22.194Z" }, - { url = "https://files.pythonhosted.org/packages/34/b0/456578e7269dace3d7a80a34b30c7757aea6aa34601853c58e5ad186d3d6/fasttext_predict-0.9.2.4-cp311-cp311-win_amd64.whl", hash = "sha256:83a3c00fdb73a304bc529bc0ae0e225bc2cb956fcfb8e1c7a882b2a1aaa97e19", size = 104390, upload-time = "2024-11-23T17:23:23.332Z" }, - { url = "https://files.pythonhosted.org/packages/fb/fa/612bf85ce8928120843279ae256f4fffbb9758af81536ddf25f9136b1759/fasttext_predict-0.9.2.4-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:dcf8661da4f515551523470a745df246121f7e19736fcf3f48f04287963e6279", size = 104836, upload-time = "2024-11-23T17:23:25.219Z" }, - { url = "https://files.pythonhosted.org/packages/7a/04/106b6fe3f980d6a4f41bfb3106be22d42f87b1e8beb2959361ee4ee08960/fasttext_predict-0.9.2.4-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:99dbfcc3f353da2639fd04fc574a65ff4195b018311f790583147cdc6eb122f4", size = 97377, upload-time = "2024-11-23T17:23:26.319Z" }, - { url = "https://files.pythonhosted.org/packages/57/b9/b4962c92bd93dd234ea1d1cab643a86d948dab3f269e34a554a004ed6524/fasttext_predict-0.9.2.4-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:427e99ba963b2c744ed7233304037a83b7adece97de6f361cfd356aa43cb87f3", size = 283102, upload-time = "2024-11-23T17:23:27.497Z" }, - { url = "https://files.pythonhosted.org/packages/1d/18/92203820cf00b9a34f40f10456e4ed3019010a9b13a87e11d8b98cd98933/fasttext_predict-0.9.2.4-cp312-cp312-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:8b9480cc75a906571a8e5fc717b91b4783f1820aaa5ed36a304d689280de8602", size = 307416, upload-time = "2024-11-23T17:23:28.68Z" }, - { url = "https://files.pythonhosted.org/packages/06/8d/334cd9acb84e569d37617444661ca7b59d1bc1a83abe42aa845d23fb1273/fasttext_predict-0.9.2.4-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:11ef7af2a4431c76d2226e47334e86b9c4a78a98f6cb68b1ce9a1fc20e04c904", size = 296055, upload-time = "2024-11-23T17:23:29.934Z" }, - { url = "https://files.pythonhosted.org/packages/08/0b/2c83cc67eb5a29f182c8ea425e4b026db0593712edb8eaaf082501ca349f/fasttext_predict-0.9.2.4-cp312-cp312-manylinux_2_31_armv7l.whl", hash = "sha256:ecb0b854596ba847742597b35c2d0134fcf3a59214d09351d01535854078d56b", size = 237279, upload-time = "2024-11-23T17:23:31.358Z" }, - { url = "https://files.pythonhosted.org/packages/14/81/0f1b3bda499ffeb7109fe51d9321dc74100db5a4801e3f9a9efe2348922d/fasttext_predict-0.9.2.4-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:fbbcfefac10f625d95fc42f28d76cc5bf0c12875f147b5a79108a2669e64a2dc", size = 1214253, upload-time = "2024-11-23T17:23:33.529Z" }, - { url = "https://files.pythonhosted.org/packages/d1/e6/b1a177a990c29b043a9658f9f4ec7234576ad31939362f9760c237f91d6d/fasttext_predict-0.9.2.4-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:a8cb78a00c04b7eb7da18b4805f8557b36911dc4375c947d8938897d2e131841", size = 1099909, upload-time = "2024-11-23T17:23:34.983Z" }, - { url = "https://files.pythonhosted.org/packages/09/a0/7f23c7c4398f399552f39144849868991da543b66b9bfa8f49a6550fdd46/fasttext_predict-0.9.2.4-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:299ae56ad53e1381c65030143da7bcae12546fd32bc019215592ec1ee40fd19e", size = 1384102, upload-time = "2024-11-23T17:23:37.237Z" }, - { url = "https://files.pythonhosted.org/packages/e4/2c/568cf15fd48e4cefd0e605af62da5f5f51db3b012f8441d201d0a1173eb1/fasttext_predict-0.9.2.4-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:091938062002fe30d214f6e493a3a1e6180d401212d37eea23c29f4b55f3f347", size = 1281283, upload-time = "2024-11-23T17:23:39.676Z" }, - { url = "https://files.pythonhosted.org/packages/e7/68/0967ec3d5333c23fae1f1bdb851fa896f8f6068ef0ca3a8afee1aa2ee57d/fasttext_predict-0.9.2.4-cp312-cp312-win32.whl", hash = "sha256:981b8d9734623f8f9a8003970f765e14b1d91ee82c59c35e8eba6b76368fa95e", size = 91089, upload-time = "2024-11-23T17:23:41.082Z" }, - { url = "https://files.pythonhosted.org/packages/a7/c5/11c1f50b47f492d562974878ec34b6a0b84699f8b05e1cc3a75c65349784/fasttext_predict-0.9.2.4-cp312-cp312-win_amd64.whl", hash = "sha256:bd3c33971c241577b0767e55d97acfda790f77378f9d5ee7872b6ee4bd63130b", size = 104889, upload-time = "2024-11-23T17:23:42.193Z" }, - { url = "https://files.pythonhosted.org/packages/89/fc/5cd65224c33e33d6faec3fa1047162dc266ed2213016139d936bd36fb7c3/fasttext_predict-0.9.2.4-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:ddb85e62c95e4e02d417c782e3434ef65554df19e3522f5230f6be15a9373c05", size = 104916, upload-time = "2024-11-23T17:23:43.367Z" }, - { url = "https://files.pythonhosted.org/packages/d9/53/8d542773e32c9d98dd8c680e390fe7e6d4fc92ab3439dc1bb8e70c46c7ad/fasttext_predict-0.9.2.4-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:102129d45cf98dda871e83ae662f71d999b9ef6ff26bc842ffc1520a1f82930c", size = 97502, upload-time = "2024-11-23T17:23:44.447Z" }, - { url = "https://files.pythonhosted.org/packages/50/99/049fd6b01937705889bd9a00c31e5c55f0ae4b7704007b2ef7a82bf2b867/fasttext_predict-0.9.2.4-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:05ba6a0fbf8cb2141b8ca2bc461db97af8ac31a62341e4696a75048b9de39e10", size = 282951, upload-time = "2024-11-23T17:23:46.31Z" }, - { url = "https://files.pythonhosted.org/packages/83/cb/79b71709edbb53c3c5f8a8b60fe2d3bc98d28a8e75367c89afedf3307aa9/fasttext_predict-0.9.2.4-cp313-cp313-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0c7a779215571296ecfcf86545cb30ec3f1c6f43cbcd69f83cc4f67049375ea1", size = 307377, upload-time = "2024-11-23T17:23:47.685Z" }, - { url = "https://files.pythonhosted.org/packages/7c/4a/b15b7be003e76613173cc77d9c6cce4bf086073079354e0177deaa768f59/fasttext_predict-0.9.2.4-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ddd2f03f3f206585543f5274b1dbc5f651bae141a1b14c9d5225c2a12e5075c2", size = 295746, upload-time = "2024-11-23T17:23:49.024Z" }, - { url = "https://files.pythonhosted.org/packages/e3/d3/f030cd45bdd4b052fcf23e730fdf0804e024b0cad43d7c7f8704faaec2f5/fasttext_predict-0.9.2.4-cp313-cp313-manylinux_2_31_armv7l.whl", hash = "sha256:748f9edc3222a1fb7a61331c4e06d3b7f2390ae493f91f09d372a00b81762a8d", size = 236939, upload-time = "2024-11-23T17:23:50.306Z" }, - { url = "https://files.pythonhosted.org/packages/a2/01/6f2985afd58fdc5f4ecd058d5d9427d03081d468960982df97316c03f6bb/fasttext_predict-0.9.2.4-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:1aee47a40757cd24272b34eaf9ceeea86577fd0761b0fd0e41599c6549abdf04", size = 1214189, upload-time = "2024-11-23T17:23:51.647Z" }, - { url = "https://files.pythonhosted.org/packages/75/07/931bcdd4e2406e45e54d57e056c2e0766616a5280a18fbf6ef078aa439ab/fasttext_predict-0.9.2.4-cp313-cp313-musllinux_1_2_armv7l.whl", hash = "sha256:6ff0f152391ee03ffc18495322100c01735224f7843533a7c4ff33c8853d7be1", size = 1099889, upload-time = "2024-11-23T17:23:53.127Z" }, - { url = "https://files.pythonhosted.org/packages/a2/eb/6521b4bbf387252a96a6dc0f54986f078a93db0a9d4ba77258dcf1fa8be7/fasttext_predict-0.9.2.4-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:4d92f5265318b41d6e68659fd459babbff692484e492c5013995b90a56b517c9", size = 1383959, upload-time = "2024-11-23T17:23:54.521Z" }, - { url = "https://files.pythonhosted.org/packages/b7/6b/d56606761afb3a3912c52971f0f804e2e9065f049c412b96c47d6fca6218/fasttext_predict-0.9.2.4-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:3a7720cce1b8689d88df76cac1425e84f9911c69a4e40a5309d7d3435e1bb97c", size = 1281097, upload-time = "2024-11-23T17:23:55.9Z" }, - { url = "https://files.pythonhosted.org/packages/91/83/55bb4a37bb3b3a428941f4e1323c345a662254f576f8860b3098d9742510/fasttext_predict-0.9.2.4-cp313-cp313-win32.whl", hash = "sha256:d16acfced7871ed0cd55b476f0dbdddc7a5da1ffc9745a3c5674846cf1555886", size = 91137, upload-time = "2024-11-23T17:23:57.886Z" }, - { url = "https://files.pythonhosted.org/packages/9c/1d/c1ccc8790ce54200c84164d99282f088dddb9760aeefc8860856aafa40b4/fasttext_predict-0.9.2.4-cp313-cp313-win_amd64.whl", hash = "sha256:96a23328729ce62a851f8953582e576ca075ee78d637df4a78a2b3609784849e", size = 104896, upload-time = "2024-11-23T17:23:59.028Z" }, - { url = "https://files.pythonhosted.org/packages/a4/c9/a1ccc749c59e2480767645ecc03bd842a7fa5b2b780d69ac370e6f8298d2/fasttext_predict-0.9.2.4-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:b1357d0d9d8568db84668b57e7c6880b9c46f757e8954ad37634402d36f09dba", size = 109401, upload-time = "2024-11-23T17:24:00.191Z" }, - { url = "https://files.pythonhosted.org/packages/90/1f/33182b76eb0524155e8ff93e7939feaf5325385e5ff2a154f383d9a02317/fasttext_predict-0.9.2.4-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:9604c464c5d86c7eba34b040080be7012e246ef512b819e428b7deb817290dae", size = 102131, upload-time = "2024-11-23T17:24:02.052Z" }, - { url = "https://files.pythonhosted.org/packages/2b/df/1886daea373382e573f28ce49e3fc8fb6b0ee0c84e2b0becf5b254cd93fb/fasttext_predict-0.9.2.4-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:cc6da186c2e4497cbfaba9c5424e58c7b72728b25d980829eb96daccd7cface1", size = 287396, upload-time = "2024-11-23T17:24:03.294Z" }, - { url = "https://files.pythonhosted.org/packages/35/8f/d1c2c0f0251bee898d508253a437683b0480a1074cfb25ded1f7fdbb925a/fasttext_predict-0.9.2.4-cp313-cp313t-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:366ed2ca4f4170418f3585e92059cf17ee2c963bf179111c5b8ba48f06cd69d1", size = 311090, upload-time = "2024-11-23T17:24:04.625Z" }, - { url = "https://files.pythonhosted.org/packages/5d/52/07d6ed46148662fae84166bc69d944caca87fabc850ebfbd9640b20dafe7/fasttext_predict-0.9.2.4-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2f1877edbb815a43e7d38cc7332202e759054cf0b5a4b7e34a743c0f5d6e7333", size = 300359, upload-time = "2024-11-23T17:24:06.486Z" }, - { url = "https://files.pythonhosted.org/packages/fa/a1/751ff471a991e5ed0bae9e7fa6fc8d8ab76b233a7838a27d70d62bed0c8e/fasttext_predict-0.9.2.4-cp313-cp313t-manylinux_2_31_armv7l.whl", hash = "sha256:f63c31352ba6fc910290b0fe12733770acd8cfa0945fcb9cf3984d241abcfc9d", size = 241164, upload-time = "2024-11-23T17:24:08.501Z" }, - { url = "https://files.pythonhosted.org/packages/94/19/e251f699a0e9c001fa672ea0929c456160faa68ecfafc19e8def09982b6a/fasttext_predict-0.9.2.4-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:898e14b03fbfb0a8d9a5185a0a00ff656772b3baa37cad122e06e8e4d6da3832", size = 1218629, upload-time = "2024-11-23T17:24:10.04Z" }, - { url = "https://files.pythonhosted.org/packages/1d/46/1af2f779f8cfd746496a226581f747d3051888e3e3c5b2ca37231e5d04f8/fasttext_predict-0.9.2.4-cp313-cp313t-musllinux_1_2_armv7l.whl", hash = "sha256:a33bb5832a69fc54d18cadcf015677c1acb5ccc7f0125d261df2a89f8aff01f6", size = 1100535, upload-time = "2024-11-23T17:24:11.5Z" }, - { url = "https://files.pythonhosted.org/packages/4c/b7/900ccd74a9ba8be7ca6d04bba684e9c43fb0dbed8a3d12ec0536228e2c32/fasttext_predict-0.9.2.4-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:7fe9e98bd0701d598bf245eb2fbf592145cd03551684a2102a4b301294b9bd87", size = 1387651, upload-time = "2024-11-23T17:24:13.135Z" }, - { url = "https://files.pythonhosted.org/packages/0b/5a/99fdaed054079f7c96e70df0d7016c4eb6b9e487a614396dd8f849244a52/fasttext_predict-0.9.2.4-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:dcb8c5a74c1785f005fd83d445137437b79ac70a2dfbfe4bb1b09aa5643be545", size = 1286189, upload-time = "2024-11-23T17:24:14.615Z" }, - { url = "https://files.pythonhosted.org/packages/87/6a/9114d65b3f7a9c20a62b9d2ca3b770ee65de849e4131cc7aa58cdc50cb07/fasttext_predict-0.9.2.4-cp313-cp313t-win32.whl", hash = "sha256:a85c7de3d4480faa12b930637fca9c23144d1520786fedf9ba8edd8642ed4aea", size = 95905, upload-time = "2024-11-23T17:24:15.868Z" }, - { url = "https://files.pythonhosted.org/packages/31/fb/6d251f3fdfe3346ee60d091f55106513e509659ee005ad39c914182c96f4/fasttext_predict-0.9.2.4-cp313-cp313t-win_amd64.whl", hash = "sha256:be0933fa4af7abae09c703d28f9e17c80e7069eb6f92100b21985b777f4ea275", size = 110325, upload-time = "2024-11-23T17:24:16.984Z" }, - { url = "https://files.pythonhosted.org/packages/20/ba/c7fe88fbf59935118b9a756e3ae671d8ddcdd58170f4e53d60d9863b29e6/fasttext_predict-0.9.2.4-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b11ba9414aa71754f798a102cf7d3df53307055b2b0f0b258a3f2d59c5a12cfa", size = 133206, upload-time = "2024-11-23T17:24:38.986Z" }, - { url = "https://files.pythonhosted.org/packages/50/a6/8807d54b25905d3d91e7b16705632a3ccf4adf6457daae959c4f42987c27/fasttext_predict-0.9.2.4-pp310-pypy310_pp73-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:3c89c769e3646bdb341487a68835239f35a4a0959cc1a8d8a7d215f40b22a230", size = 149227, upload-time = "2024-11-23T17:24:40.285Z" }, - { url = "https://files.pythonhosted.org/packages/27/4a/55ae88864d5711822ecf6f37d54d655dc2e3617ae70d07bf28c08d9bea5f/fasttext_predict-0.9.2.4-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5f3b9cd4a2cf4c4853323f57c5da6ecffca6aeb9b6d8751ee40fe611d6edf8dd", size = 140205, upload-time = "2024-11-23T17:24:42.307Z" }, - { url = "https://files.pythonhosted.org/packages/a0/33/1b5baa8960548100fddc40908780f0c18fddff8a514f9cd3dd0f6676746d/fasttext_predict-0.9.2.4-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:1c92905396c74e5cb29ddbfa763b5addec1581b6e0eae4cbe82248dfe733557e", size = 102845, upload-time = "2024-11-23T17:24:43.64Z" }, -] - [[package]] name = "filelock" version = "3.20.3" @@ -1654,6 +1556,53 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/fc/85/69f92b2a7b3c0f88ffe107c86b952b397004b5b8ea5a81da3d9c04c04422/librt-0.7.8-cp314-cp314t-win_arm64.whl", hash = "sha256:8766ece9de08527deabcd7cb1b4f1a967a385d26e33e536d6d8913db6ef74f06", size = 40550, upload-time = "2026-01-14T12:56:01.542Z" }, ] +[[package]] +name = "lingua-language-detector" +version = "2.1.1" +source = { registry = "https://pypi.org/simple" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/77/48/1aae0f9a74ca0d61bd0af6000d436a6af9929482ac5cb44f5c8e7ffe71d8/lingua_language_detector-2.1.1-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:9c195a39f3b9ebeec9af72acf03a0b13132bff09147cd50d99001c060a998eaa", size = 96064810, upload-time = "2025-05-27T20:40:09.879Z" }, + { url = "https://files.pythonhosted.org/packages/02/f9/6489ce213a2d3d5bad1f0114c22772d3e7a3d93cf66423cc1371c078e777/lingua_language_detector-2.1.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:fbd56b2f830f77819f8f97ecc11bff421133ced2da7c2cf9e05ebfe0e9f625f5", size = 96721535, upload-time = "2025-05-27T20:40:15.988Z" }, + { url = "https://files.pythonhosted.org/packages/ba/17/f1ccdec51d84a9a39efa1bf184f1e1ea831410d98636bd8bdb0b65273467/lingua_language_detector-2.1.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:07a2447576fabbf7f381b82be6de2336f55f54d7836b0ac6eed721f3b79cabe4", size = 96162140, upload-time = "2025-05-27T20:40:21.738Z" }, + { url = "https://files.pythonhosted.org/packages/5a/58/9a7c650aa6b068b995106be4c3502a0983122a70e65ec685038e82822d40/lingua_language_detector-2.1.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:deec7c9d5a72d7434144952cd5c3b85923d7a858264baa9c21018cb0e2e929fb", size = 96234399, upload-time = "2025-05-27T20:40:32.124Z" }, + { url = "https://files.pythonhosted.org/packages/d2/a6/472063fe4884d337525a2591accce55e7a2420cb7e21f35e283cf5e84d4e/lingua_language_detector-2.1.1-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:db18582802ae49d03fe4330d13bbb9285532f157f3e7be291f83ed2ea90ea190", size = 96336857, upload-time = "2025-05-27T20:40:37.209Z" }, + { url = "https://files.pythonhosted.org/packages/08/94/afba267556509b9bad4f28c86669520a94ff03d73f890840975289f36dd4/lingua_language_detector-2.1.1-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:8230d7a08d0477d136f22ec53cf8eaffaa90b273a7ab616d972298360c2a4090", size = 96405934, upload-time = "2025-05-27T20:40:42.161Z" }, + { url = "https://files.pythonhosted.org/packages/c2/27/09d7d7bde906297ffc0b1d8fbd599035e8e4d6c17ed568c30b00b4f5761b/lingua_language_detector-2.1.1-cp310-cp310-win_amd64.whl", hash = "sha256:d0429b482e8b3def24ad4e5565eb187a389c35cf0506ac7ed7ef7360e7369ec7", size = 95871563, upload-time = "2025-05-27T20:40:47.241Z" }, + { url = "https://files.pythonhosted.org/packages/c1/dd/f5ee4e6a07d5871d6c30a1ab6b58843bb87bb8a4a95cfd3de04919a01652/lingua_language_detector-2.1.1-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:cd9f734f67da00d37d93a1354f7c44d86c83b297cc078d7f31f1fd8a7deddef9", size = 96065409, upload-time = "2025-05-27T20:40:52.341Z" }, + { url = "https://files.pythonhosted.org/packages/a7/f6/1ab95d5bef46cf6e4386892ae8bd417372eb231610d297d4463c4941a70f/lingua_language_detector-2.1.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:7e82bcb924d09e552a52bc79265d5e49a5863b6b7297524adc4fb7c4564ebb5d", size = 96721827, upload-time = "2025-05-27T20:40:58.367Z" }, + { url = "https://files.pythonhosted.org/packages/c4/81/2598350ecc0133a81c0f2ea63f2e7c4d58645837f37fabbd0c5c5521912f/lingua_language_detector-2.1.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e94ad32a46f04b670a939623b69d7d7008221d15e20b3d975d284304d9d6c788", size = 96161868, upload-time = "2025-05-27T20:41:04.485Z" }, + { url = "https://files.pythonhosted.org/packages/66/5e/e2a285f299f55532904e5a57985fbcda436396d4e4cb8dde959d9cf0533a/lingua_language_detector-2.1.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2a468c3fc9eaa6db733a347fee768fe171e76fac2c4bc49951e26bc79aec6a2a", size = 96234047, upload-time = "2025-05-27T20:41:10.359Z" }, + { url = "https://files.pythonhosted.org/packages/56/e7/1d0d145898716438a7ebdc4a57bf6f287bad839eb8ccee1dbb460fff9591/lingua_language_detector-2.1.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:430e9e517427070f20d1b9eaff88633614d332cdcd119a519cefcd8c9f3d67e9", size = 96336336, upload-time = "2025-05-27T20:41:15.823Z" }, + { url = "https://files.pythonhosted.org/packages/d8/ee/13a61cbd2e2d1a3d9ac3d87ed2996e6cb7233e5d39dfb60bf77dc543dcb4/lingua_language_detector-2.1.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:69a408fc0bb372a46afec6d0744077b9932c64df7c02ad517bf37c5c7e3734bb", size = 96405574, upload-time = "2025-05-27T20:41:21.232Z" }, + { url = "https://files.pythonhosted.org/packages/08/79/2b57032c1eee8c95b710a66a3d791bb8c9024def7aa7f1318209f3437bcc/lingua_language_detector-2.1.1-cp311-cp311-win_amd64.whl", hash = "sha256:fa3c9cfe7f7d9dc857ba22f14c2dfc7834e2dac131afaa737f3a59adae3ea553", size = 95870960, upload-time = "2025-05-27T20:41:26.734Z" }, + { url = "https://files.pythonhosted.org/packages/ab/fe/33eae6e11979278017d2e781d0ea1e2c3cf18f70284c7fce32d1e9a0df5f/lingua_language_detector-2.1.1-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:80acd7652f95ae569e6a03ffcb0cb9522ea3fde2328b9c6fac15b1d24ba382d9", size = 96059493, upload-time = "2025-05-27T20:41:32.018Z" }, + { url = "https://files.pythonhosted.org/packages/48/bd/fed4a8a1d3d016fb69e9de5bfd03a4eac131f698d8254eb60be1ba67a67e/lingua_language_detector-2.1.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:0a18d3bf0039ef8746f8df391cff885b47e2a3762bb30883eceac3d449fd1fc8", size = 96718240, upload-time = "2025-05-27T20:41:37.576Z" }, + { url = "https://files.pythonhosted.org/packages/78/0f/e85720ea17dde1463a847b963d24ea7c43c8cc600c6bdd5ff64775f4578a/lingua_language_detector-2.1.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3de2070ab293457a4f0fc1bd87f34de2e98c8348205b40b5667e043485950a64", size = 96161618, upload-time = "2025-05-27T20:41:43.86Z" }, + { url = "https://files.pythonhosted.org/packages/42/41/22ce56bb34ed8ea418e67ac448f557af3a9a446defb523fb7b85e822e32b/lingua_language_detector-2.1.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6a398e4871fe8e32ff5711eaabb09ebdf4f80420d73e5d646a6cae0468c7c47e", size = 96236811, upload-time = "2025-05-27T20:41:49.737Z" }, + { url = "https://files.pythonhosted.org/packages/28/88/873a9df437f71ff0b5e58b9d764289c3a9df6d32c706ba3f0f0361eb8f10/lingua_language_detector-2.1.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:f9e116206431eb283a4bc9107407a58b7d093870ae9d50ab43e39796db029fc5", size = 96335066, upload-time = "2025-05-27T20:41:55.914Z" }, + { url = "https://files.pythonhosted.org/packages/09/13/9d618ccf34d70688514336c256af4c7fb861e94b009ed0962cbd72e87567/lingua_language_detector-2.1.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:6e1c950dceafd5ee12b6267d9f71987c572a1ee9f18b6465c722fcde9b0d5149", size = 96407990, upload-time = "2025-05-27T20:42:04.39Z" }, + { url = "https://files.pythonhosted.org/packages/af/56/ec90f90afcdf09b3c1ed52f4c65430d5454e5ef2cc101220b91a37bfb719/lingua_language_detector-2.1.1-cp312-cp312-win_amd64.whl", hash = "sha256:a54d976a1daa8ecb5fd3f36e1ed5d3f9a363beed6edca22e88e49a8af9c4757a", size = 95868446, upload-time = "2025-05-27T20:42:10.226Z" }, + { url = "https://files.pythonhosted.org/packages/b8/54/f95fe718a889f7b57e507580d2713e29dfc5eaadbe4ad323bfd631fc9490/lingua_language_detector-2.1.1-cp313-cp313-macosx_10_12_x86_64.whl", hash = "sha256:6190e7632d08467dd3d148134743c4c40ccb4c84d6f3313508ffd73a8210c614", size = 96059594, upload-time = "2025-05-27T20:42:15.713Z" }, + { url = "https://files.pythonhosted.org/packages/c6/f2/61aad0aecf707e112bae4340275934eb4098c6c3040ffe7ae316498ea78f/lingua_language_detector-2.1.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:bbf22f8b1715f577f8cda4758d61ff3c1f5238d48b8cbe035a3c2064edf7b0a5", size = 96718187, upload-time = "2025-05-27T20:42:20.97Z" }, + { url = "https://files.pythonhosted.org/packages/c4/82/0571a607046a73284e43f46b4ef22f903156799f4ee96aa5b466ace632a8/lingua_language_detector-2.1.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:fe21c948a387fd9aa0b994853eb47cfedcc738a91530193de839ef0977ecc0de", size = 96161005, upload-time = "2025-05-27T20:42:26.985Z" }, + { url = "https://files.pythonhosted.org/packages/79/27/647e2a112e974d24e98f1168004522960d47991e122f43438e75fd1d06e2/lingua_language_detector-2.1.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d55300513d9e2e0e034f6fd6b8cf111ba9faf49ba20cc060d67b403c3d356148", size = 96236397, upload-time = "2025-05-27T20:42:32.103Z" }, + { url = "https://files.pythonhosted.org/packages/82/c6/2e9cc80bdd621648e4e27c3d40dc04bd7fc85fbfd5698692217008b15090/lingua_language_detector-2.1.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:354040a3c2ac748623966373cc64de34e8f14b0043c09aa334fdccf3456bf5d0", size = 96334444, upload-time = "2025-05-27T20:42:37.381Z" }, + { url = "https://files.pythonhosted.org/packages/14/ae/5c700dc7b4b7d975df93c67b9d80fe2fd153da703721d1e5faa7c97bd194/lingua_language_detector-2.1.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:17110a40f9346a4c24291b170d0deb815bd615427c4857342a7f513813717148", size = 96407649, upload-time = "2025-05-27T20:42:45.921Z" }, + { url = "https://files.pythonhosted.org/packages/9f/5d/aec2634a8a54c654e5fb5816d703c72263360a23e682bb7f5a4f77e06e70/lingua_language_detector-2.1.1-cp313-cp313-win_amd64.whl", hash = "sha256:53cc131d9c7be64a88b1e20633d66c62a2779776e11a26e32bac80fb19b43f33", size = 95868425, upload-time = "2025-05-27T20:42:51.148Z" }, + { url = "https://files.pythonhosted.org/packages/d7/c3/941f5cd8019bcfc049813df8b7ecacf01d059bcdeb9bb9382bd36cd11847/lingua_language_detector-2.1.1-pp310-pypy310_pp73-macosx_10_12_x86_64.whl", hash = "sha256:a857dd48a801f6a492a7832dc812c1a256f83da93725897abff7534321b0b7b1", size = 96067308, upload-time = "2025-05-27T20:42:56.407Z" }, + { url = "https://files.pythonhosted.org/packages/5b/b5/a299004221cd8c07d74cdbeb12aede65127aa2f3fee78a0fbf093f82f2b8/lingua_language_detector-2.1.1-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:197b2a394015298b80a12f61294094800560761227dcb27003f957c378059b20", size = 96724123, upload-time = "2025-05-27T20:43:01.221Z" }, + { url = "https://files.pythonhosted.org/packages/80/e4/2e5cf9426b74fbe3c1b1df961790ad611a97c1191789cfa1bf02b2231d61/lingua_language_detector-2.1.1-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b359f2571ff7ca6b4b998a3fc10fa87f136dbd4e4809af5283bb6b7093e88a07", size = 96163932, upload-time = "2025-05-27T20:43:07.094Z" }, + { url = "https://files.pythonhosted.org/packages/4d/72/f61f1e9678cc19cfb5141149382104c5885a46a4678e8467a443642e7559/lingua_language_detector-2.1.1-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5a6370392683607a34e941ea05088fde197d5dc37b8abb088fada7a51749ca44", size = 96235568, upload-time = "2025-05-27T20:43:12.299Z" }, + { url = "https://files.pythonhosted.org/packages/5e/e2/4bc76452c16e238f9cb639de3bc16e8cd511868b43c9d1f76748d4ae2dc8/lingua_language_detector-2.1.1-pp310-pypy310_pp73-musllinux_1_2_aarch64.whl", hash = "sha256:5f0917b9210b59acb0d2c0979a78f3e54dcf9967d54885a4a8d34264d5a07720", size = 96338520, upload-time = "2025-05-27T20:43:17.821Z" }, + { url = "https://files.pythonhosted.org/packages/a4/9d/f50d27185cce1d040e9c4f33e3ba87daa825bdaf92d7c9285e4476a430c1/lingua_language_detector-2.1.1-pp310-pypy310_pp73-musllinux_1_2_x86_64.whl", hash = "sha256:284077366b7ca3b2c4ecc492f3e40570f6afeaee2bf44153d347fa100137561b", size = 96406159, upload-time = "2025-05-27T20:43:23.444Z" }, + { url = "https://files.pythonhosted.org/packages/78/5a/d322b6606011ab86ca65a28e357b3fa177fccce704a2523d1607861e195f/lingua_language_detector-2.1.1-pp311-pypy311_pp73-macosx_10_12_x86_64.whl", hash = "sha256:c121e6340bb4cb051e1469adc4575790a94a47f03999155c028fd5cfb4a7516b", size = 96067286, upload-time = "2025-05-27T20:43:31.017Z" }, + { url = "https://files.pythonhosted.org/packages/4d/49/4647f3e482db0ab61c0f2ca395157062ef0fcf418e7dc0c89d54a53d0504/lingua_language_detector-2.1.1-pp311-pypy311_pp73-macosx_11_0_arm64.whl", hash = "sha256:d3790a8761c37d2c4c2aa287c1a6a1f8d3d5d9b0d74c276ffd37243385cc33f0", size = 96724272, upload-time = "2025-05-27T20:43:35.921Z" }, + { url = "https://files.pythonhosted.org/packages/09/14/8367387fea0ececc36a6cf551d188d83a28411e896d1235f3e24d63f99b3/lingua_language_detector-2.1.1-pp311-pypy311_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2477f75cc871d20bafdcb56f9d51be25d57c37d9ea5d7301cc592761dc68c963", size = 96163870, upload-time = "2025-05-27T20:43:40.869Z" }, + { url = "https://files.pythonhosted.org/packages/45/f9/8fc1fa832b596360c64b2ba4771782f53d4bef9f52f5affb438a42a78425/lingua_language_detector-2.1.1-pp311-pypy311_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:98f6128ea7b6122b23dab9168cd447fe85a3cc90d0272b7ea67034453715d306", size = 96235444, upload-time = "2025-05-27T20:43:48.403Z" }, + { url = "https://files.pythonhosted.org/packages/dc/99/ed79463a1a3cc91cf5f48f4f9083b64b6b642e63d75a42c33f594cd1c942/lingua_language_detector-2.1.1-pp311-pypy311_pp73-musllinux_1_2_aarch64.whl", hash = "sha256:178b65db951cdfbd17d05a2eb629e177e5495e57e2b41b6789e82db4df126ff7", size = 96338252, upload-time = "2025-05-27T20:43:54.834Z" }, + { url = "https://files.pythonhosted.org/packages/05/56/da535866dac54f9738e49ba7473004d4400ef937c0467e1267f8cd9901b2/lingua_language_detector-2.1.1-pp311-pypy311_pp73-musllinux_1_2_x86_64.whl", hash = "sha256:1703cd369d74bde4fd6df8f21988c66231d8c85589e7ce535c3e251e0d4ee4c5", size = 96406052, upload-time = "2025-05-27T20:44:01.578Z" }, +] + [[package]] name = "logfire" version = "4.19.0" @@ -3669,20 +3618,6 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/13/2f/b4530fbf948867702d0a3f27de4a6aab1d156f406d72852ab902c4d04de9/rich_rst-1.3.2-py3-none-any.whl", hash = "sha256:a99b4907cbe118cf9d18b0b44de272efa61f15117c61e39ebdc431baf5df722a", size = 12567, upload-time = "2025-10-14T16:49:42.953Z" }, ] -[[package]] -name = "robust-downloader" -version = "0.0.2" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "colorlog" }, - { name = "requests" }, - { name = "tqdm" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/63/20/8d28efa080f58fa06f6378875ac482ee511c076369e5293a2e65128cf9a0/robust-downloader-0.0.2.tar.gz", hash = "sha256:08c938b96e317abe6b037e34230a91bda9b5d613f009bca4a47664997c61de90", size = 15785, upload-time = "2023-11-13T03:00:20.637Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/56/a1/779e9d0ebbdc704411ce30915a1105eb01aeaa9e402d7e446613ff8fb121/robust_downloader-0.0.2-py3-none-any.whl", hash = "sha256:8fe08bfb64d714fd1a048a7df6eb7b413eb4e624309a49db2c16fbb80a62869d", size = 15534, upload-time = "2023-11-13T03:00:18.957Z" }, -] - [[package]] name = "rpds-py" version = "0.30.0" @@ -3901,8 +3836,7 @@ name = "scribae" version = "0.1.0" source = { editable = "." } dependencies = [ - { name = "fast-langdetect" }, - { name = "fasttext-predict" }, + { name = "lingua-language-detector" }, { name = "pydantic" }, { name = "pydantic-ai" }, { name = "python-frontmatter" }, @@ -3932,8 +3866,7 @@ dev = [ [package.metadata] requires-dist = [ - { name = "fast-langdetect", specifier = ">=1.0.0" }, - { name = "fasttext-predict", specifier = "==0.9.2.4" }, + { name = "lingua-language-detector", specifier = ">=2.0.0" }, { name = "pydantic", specifier = ">=2.12.4" }, { name = "pydantic-ai", specifier = ">=1.12.0" }, { name = "python-frontmatter", specifier = ">=1.1.0" },