personal memory agent
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

refactor(supervisor): cgroup boundary + pgroup subtree + single termination path

Replace POSIX-session child management with cgroup-as-boundary +
pgroup-as-subtree. Unify termination through ManagedProcess.terminate();
eliminate sol-spawning-sol inner subprocesses; route fire-and-forget Popens
through TaskQueue via callosum; replace orphan-name reaping with cgroup-
membership sweep; move scheduler dedup truth into the supervisor; add
TaskQueue shutdown coverage. Bump Python floor to 3.11 for process_group=0.

- systemd unit: KillMode=control-group, TimeoutStopSec=30
- start_new_session=True -> process_group=0 in runner, cortex, providers/cli
- Drop supervisor-local ManagedProcess; service metadata in _SERVICE_STATE
- Inner sol import (plaud) and per-file sol indexer subprocess loops removed;
import_one() callable extracted from importers/cli main()
- journal_archive and models.request_health_recheck now emit supervisor.request
via callosum_send instead of detached Popen
- Cgroup sweep at startup (Linux + systemd-only); orphan-name reaper deleted
- Supervisor-side dedup with still_running/wedged classification; supervisor
writes health/scheduler.json (atomic + locked); scheduler reloads in check()
- TaskQueue.shutdown() parallel-terminates active tasks before service shutdown
- SIGTERM cleanup handlers added to cortex and sense (parity with link)

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

+1405 -1348
+1 -1
AGENTS.md
··· 263 263 - **Imports:** prefer absolute (`from think.utils import get_journal`), grouped stdlib → third-party → local, one per line. 264 264 - **Type hints** on function signatures; `mypy` via `make check`. 265 265 - **Dependencies:** managed by [uv](https://docs.astral.sh/uv/). `pyproject.toml` is authoritative; `uv.lock` is committed; `make install` syncs; `make update` refreshes. 266 - - **Python 3.10+.** 266 + - **Python 3.11+.** 267 267 268 268 ## 10. Commit hygiene 269 269
+1 -1
README.md
··· 6 6 7 7 solstone runs in the background on your computer, experiencing your day along with you. AI agents transcribe, extract entities, detect meetings, build knowledge graphs, and surface daily insights — all without any manual input. everything stays on your machine in daily journal directories. open source, local-first, no cloud required. 8 8 9 - Python 3.10+, Linux + macOS, AGPL-3.0-only, maintained by [sol pbc](https://solpbc.org). 9 + Python 3.11+, Linux + macOS, AGPL-3.0-only, maintained by [sol pbc](https://solpbc.org). 10 10 11 11 <img src="docs/static/screenshot-home.png" alt="solstone daily dashboard" width="800"> 12 12
+1 -1
docs/INSTALL.md
··· 4 4 5 5 ## Prerequisites 6 6 7 - - Python 3.10 or later 7 + - Python 3.11 or later 8 8 - [uv](https://docs.astral.sh/uv/) (Python package manager) 9 9 - Git 10 10 - ffmpeg (for audio processing)
+1 -1
docs/project-structure.md
··· 21 21 22 22 ## Package Organization 23 23 24 - - **Python**: Requires Python 3.10+ 24 + - **Python**: Requires Python 3.11+ 25 25 - **Modules**: Each top-level folder is a Python package with `__init__.py` unless it is data-only (e.g., `tests/fixtures/`) 26 26 - **Imports**: Prefer absolute imports (e.g., `from think.utils import setup_cli`) whenever feasible 27 27 - **Entry Points**: Commands are registered in `think/sol_cli.py`'s `COMMANDS` dict (pyproject.toml just defines the `sol` entry point)
+10
observe/sense.py
··· 15 15 import json 16 16 import logging 17 17 import os 18 + import signal 18 19 import subprocess 19 20 import threading 20 21 import time ··· 1038 1039 } 1039 1040 1040 1041 1042 + def _install_sigterm_handler(sensor: FileSensor) -> None: 1043 + def handle_sigterm(_signum, _frame) -> None: 1044 + logger.info("SIGTERM received, shutting down observe sensor") 1045 + sensor.stop() 1046 + 1047 + signal.signal(signal.SIGTERM, handle_sigterm) 1048 + 1049 + 1041 1050 def main(): 1042 1051 """CLI entry point.""" 1043 1052 parser = argparse.ArgumentParser(description="Unified observe file processor") ··· 1153 1162 else: 1154 1163 # Event mode: listen for Callosum events 1155 1164 logger.info("Starting observe sensor in event mode...") 1165 + _install_sigterm_handler(sensor) 1156 1166 try: 1157 1167 sensor.start() 1158 1168 except KeyboardInterrupt:
+3 -6
pyproject.toml
··· 7 7 version = "0.1.0" 8 8 description = "Navigate Life Intelligently" 9 9 readme = "README.md" 10 - requires-python = ">=3.10" 10 + requires-python = ">=3.11" 11 11 license = {text = "AGPL-3.0-only"} 12 12 authors = [ 13 13 {name = "Jer+AI", email = "jeremie.miller@gmail.com"} ··· 19 19 "Operating System :: POSIX :: Linux", 20 20 "Operating System :: MacOS :: MacOS X", 21 21 "Programming Language :: Python :: 3", 22 - "Programming Language :: Python :: 3.10", 23 22 "Programming Language :: Python :: 3.11", 24 23 "Programming Language :: Python :: 3.12", 25 24 "Programming Language :: Python :: 3.13", ··· 97 96 [project.optional-dependencies] 98 97 parakeet-onnx-cpu = [ 99 98 "onnx-asr>=0.11.0", 100 - "onnxruntime>=1.20.0,!=1.24.1,<1.25.0; python_version < '3.11'", 101 - "onnxruntime>=1.25.0; python_version >= '3.11'", 99 + "onnxruntime>=1.25.0", 102 100 "huggingface-hub>=0.24", 103 101 ] 104 102 parakeet-onnx-cuda = [ 105 103 "onnx-asr>=0.11.0", 106 - "onnxruntime-gpu>=1.20.0,!=1.24.1,<1.25.0; python_version < '3.11'", 107 - "onnxruntime-gpu>=1.25.0; python_version >= '3.11'", 104 + "onnxruntime-gpu>=1.25.0", 108 105 "huggingface-hub>=0.24", 109 106 "nvidia-cuda-runtime-cu12", 110 107 "nvidia-cudnn-cu12",
+4 -1
tests/test_cli_provider.py
··· 487 487 callback = JSONEventCallback(events.append) 488 488 aggregator = ThinkingAggregator(callback, model="test-model") 489 489 captured_cwd = None 490 + captured_process_group = None 490 491 491 492 async def create_subprocess_exec(*args, **kwargs): 492 - nonlocal captured_cwd 493 + nonlocal captured_cwd, captured_process_group 493 494 captured_cwd = kwargs["cwd"] 495 + captured_process_group = kwargs["process_group"] 494 496 return _make_process([], [], 0) 495 497 496 498 runner = CLIRunner( ··· 512 514 asyncio.run(runner.run()) 513 515 514 516 assert captured_cwd == "/tmp" 517 + assert captured_process_group == 0 515 518 516 519 def test_read_tool_budget_overflow_terminates_process_group(self): 517 520 events = []
+14
tests/test_cortex.py
··· 5 5 6 6 import json 7 7 import os 8 + import signal 8 9 import sys 9 10 from pathlib import Path 10 11 from unittest.mock import MagicMock, patch ··· 87 88 assert cortex_service.talents_dir.exists() 88 89 89 90 91 + def test_cortex_installs_sigterm_handler(): 92 + from think import cortex 93 + 94 + previous = signal.getsignal(signal.SIGTERM) 95 + signal.signal(signal.SIGTERM, signal.SIG_DFL) 96 + try: 97 + cortex._install_sigterm_handler(MagicMock()) 98 + assert signal.getsignal(signal.SIGTERM) is not signal.SIG_DFL 99 + finally: 100 + signal.signal(signal.SIGTERM, previous) 101 + 102 + 90 103 @patch("think.cortex.subprocess.Popen") 91 104 @patch("think.cortex.threading.Thread") 92 105 @patch("think.cortex.threading.Timer") ··· 133 146 assert call_args[1]["stdin"] is not None 134 147 assert call_args[1]["stdout"] is not None 135 148 assert call_args[1]["stderr"] is not None 149 + assert call_args[1]["process_group"] == 0 136 150 137 151 # Check NDJSON was written to stdin 138 152 mock_process.stdin.write.assert_called_once()
+85
tests/test_importer.py
··· 1174 1174 assert (tmp_path / "imports" / "20260303_120000" / "manifest.json").exists() 1175 1175 1176 1176 1177 + def test_import_one_returns_metadata(tmp_path, monkeypatch): 1178 + mod = importlib.import_module("think.importers.cli") 1179 + 1180 + ics_file = tmp_path / "calendar.ics" 1181 + ics_file.write_text("BEGIN:VCALENDAR\nEND:VCALENDAR") 1182 + 1183 + mock_imp = _make_mock_file_importer() 1184 + callosum = MagicMock() 1185 + 1186 + monkeypatch.setenv("SOLSTONE_JOURNAL", str(tmp_path)) 1187 + monkeypatch.setattr( 1188 + "think.importers.file_importer.get_file_importer", lambda name: mock_imp 1189 + ) 1190 + monkeypatch.setattr(mod, "CallosumConnection", lambda **kwargs: callosum) 1191 + monkeypatch.setattr(mod, "get_rev", lambda: "test-rev") 1192 + monkeypatch.setattr(mod, "_status_emitter", lambda: None) 1193 + monkeypatch.setattr(mod, "index_file", lambda journal, file_path: True) 1194 + 1195 + result = mod.import_one( 1196 + ics_file, 1197 + source="ics", 1198 + timestamp="20260303_120000", 1199 + ) 1200 + 1201 + assert result is not None 1202 + assert result["processed_timestamp"] == "20260303_120000" 1203 + assert result["entries_written"] == 42 1204 + assert result["entities_seeded"] == 5 1205 + assert result["all_created_files"] == [ 1206 + "/journal/20250101/import.ics/imported.jsonl" 1207 + ] 1208 + assert result["source_type"] == "ics" 1209 + 1210 + 1211 + def test_import_one_invalid_timestamp_raises_value_error(tmp_path): 1212 + mod = importlib.import_module("think.importers.cli") 1213 + media = tmp_path / "note.txt" 1214 + media.write_text("hello", encoding="utf-8") 1215 + 1216 + with pytest.raises(ValueError, match="timestamp must be in YYYYMMDD_HHMMSS format"): 1217 + mod.import_one(media, timestamp="not-a-timestamp") 1218 + 1219 + 1220 + def test_file_importer_indexes_created_files_in_process(tmp_path, monkeypatch): 1221 + mod = importlib.import_module("think.importers.cli") 1222 + 1223 + ics_file = tmp_path / "calendar.ics" 1224 + ics_file.write_text("BEGIN:VCALENDAR\nEND:VCALENDAR") 1225 + 1226 + created_files = [ 1227 + str(tmp_path / "chronicle" / "20250101" / "import.ics" / "one.md"), 1228 + str(tmp_path / "chronicle" / "20250102" / "import.ics" / "two.md"), 1229 + ] 1230 + mock_imp = _make_mock_file_importer() 1231 + mock_imp.process.return_value = ImportResult( 1232 + entries_written=2, 1233 + entities_seeded=0, 1234 + files_created=created_files, 1235 + errors=[], 1236 + summary="Imported 2 events", 1237 + ) 1238 + callosum = MagicMock() 1239 + index_mock = MagicMock(return_value=True) 1240 + 1241 + monkeypatch.setenv("SOLSTONE_JOURNAL", str(tmp_path)) 1242 + monkeypatch.setattr( 1243 + "think.importers.file_importer.get_file_importer", lambda name: mock_imp 1244 + ) 1245 + monkeypatch.setattr(mod, "CallosumConnection", lambda **kwargs: callosum) 1246 + monkeypatch.setattr(mod, "get_rev", lambda: "test-rev") 1247 + monkeypatch.setattr(mod, "_status_emitter", lambda: None) 1248 + monkeypatch.setattr(mod, "index_file", index_mock) 1249 + 1250 + mod.import_one( 1251 + ics_file, 1252 + source="ics", 1253 + timestamp="20260303_120000", 1254 + ) 1255 + 1256 + assert [call.args for call in index_mock.call_args_list] == [ 1257 + (str(tmp_path), created_files[0]), 1258 + (str(tmp_path), created_files[1]), 1259 + ] 1260 + 1261 + 1177 1262 def test_ics_creation_timestamp_last_modified(): 1178 1263 mod = importlib.import_module("think.importers.ics") 1179 1264 icalendar = importlib.import_module("icalendar")
+57
tests/test_importer_sync.py
··· 412 412 assert state["files"]["short1"]["skip_reason"] == "too_short" 413 413 414 414 415 + def test_plaud_sync_save_calls_import_one_in_process(tmp_path, monkeypatch): 416 + from think.importers.plaud import PlaudBackend 417 + from think.importers.sync import load_sync_state 418 + 419 + monkeypatch.setenv("PLAUD_ACCESS_TOKEN", "test-token") 420 + 421 + def fake_download(_session, _url, dest_path, progress_cb=None): 422 + dest_path.write_bytes(b"audio") 423 + if progress_cb: 424 + progress_cb() 425 + return True 426 + 427 + with ( 428 + patch("think.importers.plaud.list_files", side_effect=_mock_list_files), 429 + patch("think.importers.plaud.get_temp_url", return_value="https://temp"), 430 + patch("think.importers.plaud.download_to_file", side_effect=fake_download), 431 + patch("think.importers.plaud.import_one") as import_mock, 432 + ): 433 + result = PlaudBackend().sync(tmp_path, dry_run=False) 434 + 435 + assert result["downloaded"] == 2 436 + assert import_mock.call_count == 2 437 + for call in import_mock.call_args_list: 438 + assert call.kwargs["source"] == "plaud" 439 + assert call.kwargs["auto"] is True 440 + assert call.kwargs["timestamp"] 441 + 442 + state = load_sync_state(tmp_path, "plaud") 443 + assert state["files"]["file1"]["status"] == "imported" 444 + assert state["files"]["file2"]["status"] == "imported" 445 + 446 + 447 + def test_plaud_sync_save_records_import_one_errors(tmp_path, monkeypatch): 448 + from think.importers.plaud import PlaudBackend 449 + 450 + monkeypatch.setenv("PLAUD_ACCESS_TOKEN", "test-token") 451 + 452 + def fake_download(_session, _url, dest_path, progress_cb=None): 453 + dest_path.write_bytes(b"audio") 454 + return True 455 + 456 + with ( 457 + patch("think.importers.plaud.list_files", side_effect=_mock_list_files), 458 + patch("think.importers.plaud.get_temp_url", return_value="https://temp"), 459 + patch("think.importers.plaud.download_to_file", side_effect=fake_download), 460 + patch( 461 + "think.importers.plaud.import_one", 462 + side_effect=RuntimeError("import boom"), 463 + ), 464 + ): 465 + result = PlaudBackend().sync(tmp_path, dry_run=False) 466 + 467 + assert result["downloaded"] == 0 468 + assert len(result["errors"]) == 2 469 + assert all("import boom" in error for error in result["errors"]) 470 + 471 + 415 472 def test_plaud_sync_cli_flag(capsys, monkeypatch, tmp_path): 416 473 """sol import --sync plaud runs sync in dry-run mode.""" 417 474 import sys
+26 -32
tests/test_journal_archive_importer.py
··· 109 109 target = tmp_path / "target" 110 110 _reset_journal(monkeypatch, target) 111 111 112 - popen = MagicMock() 113 - monkeypatch.setattr(journal_archive.subprocess, "Popen", popen) 112 + send = MagicMock(return_value=True) 113 + monkeypatch.setattr(journal_archive, "callosum_send", send) 114 114 115 115 result = journal_archive.JournalArchiveImporter().process( 116 116 archive_path, ··· 126 126 assert (target / "chronicle" / "20260101" / "default" / "090000_300").exists() 127 127 assert (target / "entities" / "source_person" / "entity.json").exists() 128 128 assert (target / "imports" / "20260101_090000" / "manifest.json").exists() 129 - popen.assert_called_once_with( 130 - ["sol", "indexer", "--rescan-full"], 131 - stdout=journal_archive.subprocess.DEVNULL, 132 - stderr=journal_archive.subprocess.DEVNULL, 133 - start_new_session=True, 129 + send.assert_called_once_with( 130 + "supervisor", 131 + "request", 132 + cmd=["sol", "indexer", "--rescan-full"], 134 133 ) 135 134 136 135 ··· 173 172 monkeypatch.setattr(mod, "get_rev", lambda: "test-rev") 174 173 monkeypatch.setattr(mod, "_status_emitter", lambda: None) 175 174 176 - with pytest.raises(journal_archive.MergeLockError, match="pid"): 175 + with pytest.raises(SystemExit, match="pid"): 177 176 mod.main() 178 177 179 178 assert mock_imp.process.call_count == 0 ··· 217 216 monkeypatch.setattr(mod, "CallosumConnection", lambda **kwargs: callosum) 218 217 monkeypatch.setattr(mod, "get_rev", lambda: "test-rev") 219 218 monkeypatch.setattr(mod, "_status_emitter", lambda: None) 220 - monkeypatch.setattr(journal_archive.subprocess, "Popen", MagicMock()) 219 + monkeypatch.setattr(journal_archive, "callosum_send", MagicMock(return_value=True)) 221 220 222 - with pytest.raises(journal_archive.MergeLockError, match="pid"): 221 + with pytest.raises(SystemExit, match="pid"): 223 222 mod.main() 224 223 225 224 emit_kinds = [call.args[:2] for call in callosum.emit.call_args_list] ··· 289 288 290 289 target = tmp_path / "target" 291 290 _reset_journal(monkeypatch, target) 292 - monkeypatch.setattr(journal_archive.subprocess, "Popen", MagicMock()) 291 + monkeypatch.setattr(journal_archive, "callosum_send", MagicMock(return_value=True)) 293 292 294 293 events: list[tuple[int, int, str | None]] = [] 295 294 ··· 360 359 361 360 target = tmp_path / "target" 362 361 _reset_journal(monkeypatch, target) 363 - monkeypatch.setattr(journal_archive.subprocess, "Popen", MagicMock()) 362 + monkeypatch.setattr(journal_archive, "callosum_send", MagicMock(return_value=True)) 364 363 365 364 merge_mod = importlib.import_module("think.merge") 366 365 original_copytree = merge_mod.shutil.copytree ··· 412 411 413 412 target = tmp_path / "target" 414 413 _reset_journal(monkeypatch, target) 415 - monkeypatch.setattr(journal_archive.subprocess, "Popen", MagicMock()) 414 + monkeypatch.setattr(journal_archive, "callosum_send", MagicMock(return_value=True)) 416 415 _write_json( 417 416 target / "entities" / "shared_person" / "entity.json", 418 417 { ··· 456 455 457 456 target = tmp_path / "target" 458 457 _reset_journal(monkeypatch, target) 459 - popen = MagicMock() 460 - monkeypatch.setattr(journal_archive.subprocess, "Popen", popen) 458 + send = MagicMock(return_value=True) 459 + monkeypatch.setattr(journal_archive, "callosum_send", send) 461 460 462 461 result = journal_archive.JournalArchiveImporter().process( 463 462 archive_path, ··· 469 468 assert result.merge_summary is not None 470 469 assert result.merge_summary["segments_copied"] == 1 471 470 assert not (target / "chronicle").exists() 472 - popen.assert_not_called() 471 + send.assert_not_called() 473 472 474 473 475 474 def test_journal_archive_importer_safe_extract_rejects_escape_target( ··· 542 541 shutil.rmtree(temp_dir, ignore_errors=True) 543 542 544 543 545 - def test_journal_archive_importer_process_starts_async_full_rescan( 544 + def test_journal_archive_importer_process_requests_async_full_rescan( 546 545 tmp_path, monkeypatch 547 546 ): 548 547 archive_path = tmp_path / "journal-export.zip" ··· 553 552 554 553 target = tmp_path / "target" 555 554 _reset_journal(monkeypatch, target) 556 - popen = MagicMock() 557 - monkeypatch.setattr(journal_archive.subprocess, "Popen", popen) 555 + send = MagicMock(return_value=True) 556 + monkeypatch.setattr(journal_archive, "callosum_send", send) 558 557 559 558 journal_archive.JournalArchiveImporter().process( 560 559 archive_path, ··· 562 561 import_id="20260426_120000", 563 562 ) 564 563 565 - popen.assert_called_once_with( 566 - ["sol", "indexer", "--rescan-full"], 567 - stdout=journal_archive.subprocess.DEVNULL, 568 - stderr=journal_archive.subprocess.DEVNULL, 569 - start_new_session=True, 564 + send.assert_called_once_with( 565 + "supervisor", 566 + "request", 567 + cmd=["sol", "indexer", "--rescan-full"], 570 568 ) 571 569 572 570 573 - def test_journal_archive_importer_process_warns_when_full_rescan_launch_fails( 571 + def test_journal_archive_importer_warns_when_callosum_send_fails( 574 572 tmp_path, monkeypatch, caplog 575 573 ): 576 574 archive_path = tmp_path / "journal-export.zip" ··· 581 579 582 580 target = tmp_path / "target" 583 581 _reset_journal(monkeypatch, target) 584 - monkeypatch.setattr( 585 - journal_archive.subprocess, 586 - "Popen", 587 - MagicMock(side_effect=OSError("nope")), 588 - ) 582 + monkeypatch.setattr(journal_archive, "callosum_send", MagicMock(return_value=False)) 589 583 590 584 with caplog.at_level("WARNING"): 591 585 result = journal_archive.JournalArchiveImporter().process( ··· 595 589 ) 596 590 597 591 assert result.errors == [] 598 - assert "Failed to start full index rescan" in caplog.text 592 + assert "post-merge full reindex: callosum_send returned false" in caplog.text 599 593 600 594 601 595 def test_journal_archive_importer_process_cleans_extract_dir_on_success_and_error( ··· 609 603 610 604 target = tmp_path / "target" 611 605 _reset_journal(monkeypatch, target) 612 - monkeypatch.setattr(journal_archive.subprocess, "Popen", MagicMock()) 606 + monkeypatch.setattr(journal_archive, "callosum_send", MagicMock(return_value=True)) 613 607 614 608 journal_archive.JournalArchiveImporter().process( 615 609 archive_path,
+23
tests/test_models.py
··· 35 35 get_context_registry, 36 36 get_usage_cost, 37 37 iter_token_log, 38 + request_health_recheck, 38 39 resolve_provider, 39 40 ) 40 41 ··· 989 990 ) 990 991 991 992 mock_validate_schema.assert_not_called() 993 + 994 + 995 + def test_request_health_recheck_emits_callosum_request(): 996 + with patch("think.models.callosum_send", return_value=True) as send: 997 + request_health_recheck() 998 + 999 + send.assert_called_once_with( 1000 + "supervisor", 1001 + "request", 1002 + cmd=["sol", "providers", "check", "--targeted"], 1003 + ) 1004 + 1005 + 1006 + def test_request_health_recheck_does_not_raise_on_send_failure(caplog): 1007 + with ( 1008 + patch("think.models.callosum_send", return_value=False) as send, 1009 + caplog.at_level(logging.WARNING), 1010 + ): 1011 + request_health_recheck() 1012 + 1013 + send.assert_called_once() 1014 + assert "request_health_recheck: callosum_send returned false" in caplog.text
+33 -7
tests/test_scheduler.py
··· 921 921 assert call_kwargs[0][1] == "request" 922 922 assert call_kwargs[1]["cmd"] == ["sol", "test-task", "-v"] 923 923 assert call_kwargs[1]["ref"].startswith("sched:a:") 924 - 925 - # State should be updated 926 - assert "a" in mod._state 927 - assert mod._state["a"]["last_run"] > 0 924 + assert call_kwargs[1]["scheduler_name"] == "a" 928 925 929 - # State file should be written 930 - saved = _read_state(journal_path) 931 - assert "a" in saved 926 + assert "a" not in mod._state 927 + assert not (journal_path / "health" / "scheduler.json").exists() 932 928 933 929 def test_daily_boundary_submits(self, journal_path): 934 930 """Crossing a day boundary submits due daily tasks.""" ··· 1014 1010 1015 1011 callosum.emit.assert_called_once() 1016 1012 assert callosum.emit.call_args[1]["cmd"] == ["sol", "new-task"] 1013 + 1014 + def test_check_reloads_state_before_due_checks(self, journal_path): 1015 + """State written by supervisor is reloaded before due checks.""" 1016 + import think.scheduler as mod 1017 + 1018 + callosum = Mock() 1019 + callosum.emit = Mock(return_value=True) 1020 + 1021 + _write_config( 1022 + journal_path, 1023 + { 1024 + "a": {"cmd": ["sol", "x"], "every": "hourly"}, 1025 + }, 1026 + ) 1027 + mod.init(callosum) 1028 + mod._state = {} 1029 + mod._last_hour = datetime(2026, 2, 17, 13, 0) 1030 + mod._last_daily_mark = datetime(2026, 2, 17, 0, 0) 1031 + _write_state( 1032 + journal_path, 1033 + { 1034 + "a": {"last_run": datetime(2026, 2, 17, 14, 0, 30).timestamp()}, 1035 + }, 1036 + ) 1037 + 1038 + with _fake_now(datetime(2026, 2, 17, 14, 1)): 1039 + mod.check() 1040 + 1041 + callosum.emit.assert_not_called() 1042 + assert "a" in mod._state 1017 1043 1018 1044 def test_emit_failure_no_state_update(self, journal_path): 1019 1045 """If emit fails, last_run should not be updated."""
+13
tests/test_sense.py
··· 3 3 4 4 """Tests for observe.sense module.""" 5 5 6 + import signal 6 7 import tempfile 7 8 import threading 8 9 import time ··· 33 34 34 35 assert item.file_path == path 35 36 assert item.observer == "my-observer" 37 + 38 + 39 + def test_sense_installs_sigterm_handler(): 40 + from observe import sense 41 + 42 + previous = signal.getsignal(signal.SIGTERM) 43 + signal.signal(signal.SIGTERM, signal.SIG_DFL) 44 + try: 45 + sense._install_sigterm_handler(MagicMock()) 46 + assert signal.getsignal(signal.SIGTERM) is not signal.SIG_DFL 47 + finally: 48 + signal.signal(signal.SIGTERM, previous) 36 49 37 50 38 51 # --- HandlerQueue Tests ---
+2
tests/test_service.py
··· 69 69 70 70 assert "Type=simple" in unit 71 71 assert "Restart=on-failure" in unit 72 + assert "KillMode=control-group" in unit 73 + assert "TimeoutStopSec=30" in unit 72 74 assert ( 73 75 f"ExecStart={Path.home() / '.local' / 'bin' / 'sol'} supervisor 5015" 74 76 in unit
+423 -67
tests/test_supervisor.py
··· 3 3 4 4 import importlib 5 5 import io 6 + import json 6 7 import os 7 - import signal 8 8 import subprocess 9 9 import sys 10 + import threading 10 11 from unittest.mock import MagicMock 11 12 12 13 import psutil ··· 37 38 stderr=None, 38 39 text=False, 39 40 bufsize=-1, 40 - start_new_session=False, 41 + process_group=None, 41 42 env=None, 42 43 ): 43 44 proc = DummyProc() ··· 58 59 assert stderr == subprocess.PIPE 59 60 60 61 62 + def test_launch_process_records_service_state(monkeypatch): 63 + mod = importlib.import_module("think.supervisor") 64 + mod._SERVICE_STATE.clear() 65 + 66 + process = MagicMock() 67 + process.pid = 12345 68 + managed = mod.RunnerManagedProcess( 69 + process=process, 70 + name="unit", 71 + log_writer=MagicMock(), 72 + cmd=["sol", "sense"], 73 + _threads=[], 74 + ref="ref-1", 75 + _start_time=100.0, 76 + _callosum=None, 77 + ) 78 + 79 + def fake_spawn(cmd, *, ref=None, callosum=None, day=None): 80 + assert cmd == ["sol", "sense"] 81 + assert ref == "ref-1" 82 + assert day is None 83 + return managed 84 + 85 + monkeypatch.setattr(mod.RunnerManagedProcess, "spawn", fake_spawn) 86 + 87 + result = mod._launch_process( 88 + "unit", 89 + ["sol", "sense"], 90 + restart=True, 91 + shutdown_timeout=7, 92 + ref="ref-1", 93 + ) 94 + 95 + assert result is managed 96 + assert isinstance(result, mod.RunnerManagedProcess) 97 + assert mod._SERVICE_STATE["unit"] == { 98 + "restart": True, 99 + "shutdown_timeout": 7, 100 + } 101 + 102 + 61 103 def test_parse_args_remote_flag(): 62 104 """Test that parse_args includes --remote flag.""" 63 105 mod = importlib.reload(importlib.import_module("think.supervisor")) ··· 97 139 98 140 def test_shutdown_stops_in_reverse_order(monkeypatch): 99 141 """Shutdown stops services in reverse order.""" 142 + mod = importlib.import_module("think.supervisor") 100 143 operations = [] 101 144 102 - class MockProc: 103 - def __init__(self, name): 104 - self._name = name 105 - 106 - def terminate(self): 107 - operations.append(("terminate", self._name)) 108 - 109 - def wait(self, timeout=None): 110 - operations.append(("wait", self._name)) 111 - 112 - def kill(self): 113 - pass 114 - 115 - def poll(self): 116 - return None 117 - 118 145 class MockManaged: 119 146 def __init__(self, name): 120 147 self.name = name 121 - self.process = MockProc(name) 122 - self.shutdown_timeout = 15 123 - 124 - def cleanup(self): 125 - operations.append(("cleanup", self.name)) 148 + self.terminate = MagicMock( 149 + side_effect=lambda timeout=None: operations.append( 150 + ("terminate", self.name, timeout) 151 + ) 152 + ) 153 + self.cleanup = MagicMock( 154 + side_effect=lambda: operations.append(("cleanup", self.name)) 155 + ) 126 156 127 157 procs = [ 128 158 MockManaged("convey"), 129 159 MockManaged("sense"), 130 160 MockManaged("cortex"), 131 161 ] 162 + mod._SERVICE_STATE.clear() 163 + for managed in procs: 164 + mod._SERVICE_STATE[managed.name] = { 165 + "restart": True, 166 + "shutdown_timeout": 15, 167 + } 132 168 133 169 for managed in reversed(procs): 134 - proc = managed.process 135 - try: 136 - proc.terminate() 137 - except Exception: 138 - pass 139 - try: 140 - proc.wait(timeout=managed.shutdown_timeout) 141 - except Exception: 142 - pass 143 - managed.cleanup() 170 + mod._stop_process(managed) 144 171 145 172 assert operations == [ 146 - ("terminate", "cortex"), 147 - ("wait", "cortex"), 173 + ("terminate", "cortex", 15), 148 174 ("cleanup", "cortex"), 149 - ("terminate", "sense"), 150 - ("wait", "sense"), 175 + ("terminate", "sense", 15), 151 176 ("cleanup", "sense"), 152 - ("terminate", "convey"), 153 - ("wait", "convey"), 177 + ("terminate", "convey", 15), 154 178 ("cleanup", "convey"), 155 179 ] 156 180 ··· 554 578 555 579 class _TaskProcessStub: 556 580 def __init__(self): 557 - self.send_signal = MagicMock() 558 - self.kill = MagicMock() 581 + self.poll = MagicMock(return_value=None) 582 + self.pid = 12345 559 583 560 584 561 585 class _TaskManagedStub: 562 586 def __init__(self, *, cmd, start_time=100.0): 587 + self.name = "task" 563 588 self.cmd = cmd 564 589 self.start_time = start_time 565 590 self.process = _TaskProcessStub() 591 + self.ref = "ref-1" 592 + self.terminate = MagicMock() 593 + self.cleanup = MagicMock() 566 594 567 595 568 596 def test_taskqueue_set_cap_records_cap(): ··· 574 602 assert queue._caps["import"] == 1800 575 603 576 604 577 - def test_enforce_deadlines_sends_sigterm_when_elapsed_exceeds_cap(caplog): 605 + def test_task_queue_history_records_completion(tmp_path, monkeypatch): 606 + mod = importlib.import_module("think.supervisor") 607 + monkeypatch.setenv("SOLSTONE_JOURNAL", str(tmp_path)) 608 + (tmp_path / "health").mkdir(parents=True, exist_ok=True) 609 + 610 + queue = mod.TaskQueue(on_queue_change=None) 611 + callosum = MagicMock() 612 + 613 + class FakeCallosum: 614 + def start(self, callback=None): 615 + return None 616 + 617 + def emit(self, *args, **kwargs): 618 + return callosum.emit(*args, **kwargs) 619 + 620 + def stop(self): 621 + return None 622 + 623 + managed = MagicMock() 624 + managed.pid = 12345 625 + managed.wait.return_value = 0 626 + managed.cleanup = MagicMock() 627 + 628 + def fake_spawn(cmd, *, ref=None, callosum=None, day=None): 629 + managed.cmd = cmd 630 + managed.ref = ref 631 + return managed 632 + 633 + monkeypatch.setattr(mod, "CallosumConnection", FakeCallosum) 634 + monkeypatch.setattr(mod.RunnerManagedProcess, "spawn", fake_spawn) 635 + 636 + queue._run_task( 637 + ["ref-1"], 638 + ["sol", "heartbeat"], 639 + "heartbeat", 640 + None, 641 + "heartbeat", 642 + ) 643 + 644 + assert list(queue._history) == [ 645 + { 646 + "name": "heartbeat", 647 + "cmd": ["sol", "heartbeat"], 648 + "ref": "ref-1", 649 + "ended_at": queue._history[0]["ended_at"], 650 + "exit_status": "ok", 651 + "scheduler_name": "heartbeat", 652 + } 653 + ] 654 + 655 + 656 + def test_scheduler_completion_updates_scheduler_json(tmp_path, monkeypatch): 657 + mod = importlib.import_module("think.supervisor") 658 + monkeypatch.setenv("SOLSTONE_JOURNAL", str(tmp_path)) 659 + health_dir = tmp_path / "health" 660 + health_dir.mkdir(parents=True, exist_ok=True) 661 + state_path = health_dir / "scheduler.json" 662 + state_path.write_text( 663 + '{"heartbeat": {"custom": "kept"}, "other": {"last_run": 1}}', 664 + encoding="utf-8", 665 + ) 666 + 667 + mod._record_scheduler_completion( 668 + "heartbeat", 669 + ended_at=123.0, 670 + exit_status="ok", 671 + ref="ref-1", 672 + cmd=["sol", "heartbeat"], 673 + ) 674 + 675 + data = json.loads(state_path.read_text(encoding="utf-8")) 676 + assert data["heartbeat"] == { 677 + "custom": "kept", 678 + "last_run": 123.0, 679 + "last_status": "ok", 680 + "last_ref": "ref-1", 681 + } 682 + assert data["other"] == {"last_run": 1} 683 + 684 + 685 + def test_run_task_completes_when_scheduler_writeback_fails(monkeypatch): 686 + mod = importlib.import_module("think.supervisor") 687 + queue = mod.TaskQueue(on_queue_change=None) 688 + callosum = MagicMock() 689 + 690 + class FakeCallosum: 691 + def start(self, callback=None): 692 + return None 693 + 694 + def emit(self, *args, **kwargs): 695 + return callosum.emit(*args, **kwargs) 696 + 697 + def stop(self): 698 + return callosum.stop() 699 + 700 + managed = MagicMock() 701 + managed.pid = 12345 702 + managed.wait.return_value = 0 703 + managed.cleanup = MagicMock() 704 + 705 + def fake_spawn(cmd, *, ref=None, callosum=None, day=None): 706 + managed.cmd = cmd 707 + managed.ref = ref 708 + return managed 709 + 710 + monkeypatch.setattr(mod, "CallosumConnection", FakeCallosum) 711 + monkeypatch.setattr(mod.RunnerManagedProcess, "spawn", fake_spawn) 712 + monkeypatch.setattr( 713 + mod, 714 + "_record_scheduler_completion", 715 + MagicMock(side_effect=OSError("disk full")), 716 + ) 717 + process_next = MagicMock() 718 + monkeypatch.setattr(queue, "_process_next", process_next) 719 + 720 + queue._run_task( 721 + ["ref-1"], 722 + ["sol", "heartbeat"], 723 + "heartbeat", 724 + None, 725 + "heartbeat", 726 + ) 727 + 728 + callosum.stop.assert_called_once() 729 + process_next.assert_called_once_with("heartbeat") 730 + 731 + 732 + def test_record_scheduler_completion_serializes_concurrent_writes( 733 + tmp_path, monkeypatch 734 + ): 735 + mod = importlib.import_module("think.supervisor") 736 + monkeypatch.setenv("SOLSTONE_JOURNAL", str(tmp_path)) 737 + 738 + threads = [ 739 + threading.Thread( 740 + target=mod._record_scheduler_completion, 741 + args=(name,), 742 + kwargs={ 743 + "ended_at": ended_at, 744 + "exit_status": "ok", 745 + "ref": f"ref-{name}", 746 + "cmd": ["sol", name], 747 + }, 748 + ) 749 + for name, ended_at in [("first", 101.0), ("second", 202.0)] 750 + ] 751 + 752 + for thread in threads: 753 + thread.start() 754 + for thread in threads: 755 + thread.join() 756 + 757 + state_path = tmp_path / "health" / "scheduler.json" 758 + data = json.loads(state_path.read_text(encoding="utf-8")) 759 + assert data["first"]["last_run"] == 101.0 760 + assert data["second"]["last_run"] == 202.0 761 + 762 + 763 + def test_task_history_records_cap_kill_as_timeout(monkeypatch): 764 + mod = importlib.import_module("think.supervisor") 765 + queue = mod.TaskQueue(on_queue_change=None) 766 + queue.set_cap("import", 50) 767 + callosum = MagicMock() 768 + 769 + class FakeCallosum: 770 + def start(self, callback=None): 771 + return None 772 + 773 + def emit(self, *args, **kwargs): 774 + return callosum.emit(*args, **kwargs) 775 + 776 + def stop(self): 777 + return None 778 + 779 + managed = MagicMock() 780 + managed.pid = 12345 781 + managed.cmd = ["sol", "import"] 782 + managed.ref = "ref-1" 783 + managed.start_time = 100.0 784 + managed.cleanup = MagicMock() 785 + 786 + def wait(): 787 + queue.enforce_deadlines(200.0) 788 + return -15 789 + 790 + managed.wait.side_effect = wait 791 + 792 + def fake_spawn(cmd, *, ref=None, callosum=None, day=None): 793 + return managed 794 + 795 + monkeypatch.setattr(mod, "CallosumConnection", FakeCallosum) 796 + monkeypatch.setattr(mod.RunnerManagedProcess, "spawn", fake_spawn) 797 + monkeypatch.setattr(mod, "_start_termination_thread", MagicMock()) 798 + 799 + queue._run_task(["ref-1"], ["sol", "import"], "import") 800 + 801 + assert queue._history[0]["exit_status"] == "timeout" 802 + 803 + 804 + def test_handle_task_request_skips_still_running(monkeypatch): 805 + mod = importlib.import_module("think.supervisor") 806 + queue = mod.TaskQueue(on_queue_change=None) 807 + managed = _TaskManagedStub(cmd=["sol", "import"], start_time=100.0) 808 + queue._active["active-ref"] = managed 809 + queue.set_cap("import", 50) 810 + callosum = MagicMock() 811 + 812 + monkeypatch.setattr(mod, "_task_queue", queue) 813 + monkeypatch.setattr(mod, "_supervisor_callosum", callosum) 814 + monkeypatch.setattr(mod.time, "time", lambda: 150.0) 815 + 816 + mod._handle_task_request( 817 + { 818 + "tract": "supervisor", 819 + "event": "request", 820 + "cmd": ["sol", "import", "--sync", "plaud"], 821 + "ref": "requested-ref", 822 + "scheduler_name": "sync-plaud", 823 + } 824 + ) 825 + 826 + callosum.emit.assert_called_once_with( 827 + "supervisor", 828 + "skipped", 829 + reason="still_running", 830 + ref="requested-ref", 831 + active_ref="active-ref", 832 + cmd=["sol", "import", "--sync", "plaud"], 833 + scheduler_name="sync-plaud", 834 + ) 835 + assert queue._queues == {} 836 + 837 + 838 + def test_handle_task_request_skips_wedged(monkeypatch): 839 + mod = importlib.import_module("think.supervisor") 840 + queue = mod.TaskQueue(on_queue_change=None) 841 + managed = _TaskManagedStub(cmd=["sol", "import"], start_time=100.0) 842 + queue._active["active-ref"] = managed 843 + queue.set_cap("import", 50) 844 + callosum = MagicMock() 845 + 846 + monkeypatch.setattr(mod, "_task_queue", queue) 847 + monkeypatch.setattr(mod, "_supervisor_callosum", callosum) 848 + monkeypatch.setattr(mod.time, "time", lambda: 201.0) 849 + 850 + mod._handle_task_request( 851 + { 852 + "tract": "supervisor", 853 + "event": "request", 854 + "cmd": ["sol", "import", "--sync", "plaud"], 855 + "ref": "requested-ref", 856 + } 857 + ) 858 + 859 + assert callosum.emit.call_args.kwargs["reason"] == "wedged" 860 + assert callosum.emit.call_args.kwargs["active_ref"] == "active-ref" 861 + 862 + 863 + def test_task_queue_shutdown_terminates_active_tasks(): 864 + mod = importlib.import_module("think.supervisor") 865 + queue = mod.TaskQueue(on_queue_change=None) 866 + first = _TaskManagedStub(cmd=["sol", "import"]) 867 + second = _TaskManagedStub(cmd=["sol", "indexer"]) 868 + queue._active = {"first": first, "second": second} 869 + 870 + assert queue.shutdown() == 2 871 + 872 + first.terminate.assert_called_once_with(timeout=10.0) 873 + second.terminate.assert_called_once_with(timeout=10.0) 874 + 875 + 876 + def test_task_queue_shutdown_empty_is_noop(): 877 + mod = importlib.import_module("think.supervisor") 878 + queue = mod.TaskQueue(on_queue_change=None) 879 + 880 + assert queue.shutdown() == 0 881 + 882 + 883 + def test_task_queue_shutdown_continues_after_timeout(): 884 + mod = importlib.import_module("think.supervisor") 885 + queue = mod.TaskQueue(on_queue_change=None) 886 + first = _TaskManagedStub(cmd=["sol", "import"]) 887 + second = _TaskManagedStub(cmd=["sol", "indexer"]) 888 + first.terminate.side_effect = subprocess.TimeoutExpired( 889 + cmd=["sol", "import"], timeout=10 890 + ) 891 + queue._active = {"first": first, "second": second} 892 + 893 + assert queue.shutdown() == 2 894 + 895 + first.terminate.assert_called_once_with(timeout=10.0) 896 + second.terminate.assert_called_once_with(timeout=10.0) 897 + 898 + 899 + def test_enforce_deadlines_terminates_when_elapsed_exceeds_cap(caplog, monkeypatch): 578 900 mod = importlib.import_module("think.supervisor") 579 901 queue = mod.TaskQueue(on_queue_change=None) 580 902 managed = _TaskManagedStub( ··· 584 906 queue._active["ref-1"] = managed 585 907 queue.set_cap("import", 50) 586 908 909 + def terminate_now(key, managed_arg, timeout, reason): 910 + assert key == "ref-1" 911 + assert managed_arg is managed 912 + assert timeout == 2.0 913 + assert reason == "cap" 914 + managed_arg.terminate(timeout=timeout) 915 + 916 + monkeypatch.setattr(mod, "_start_termination_thread", terminate_now) 587 917 caplog.set_level("WARNING") 588 918 queue.enforce_deadlines(200.0) 589 919 590 - managed.process.send_signal.assert_called_once_with(signal.SIGTERM) 591 - assert queue._terminations["ref-1"] == 200.0 920 + managed.terminate.assert_called_once_with(timeout=2.0) 592 921 assert ( 593 922 "Task import (cmd=sol import --sync plaud --save, ref=ref-1) exceeded " 594 - "max_runtime of 50s (elapsed=100s); sending SIGTERM" 923 + "max_runtime of 50s (elapsed=100s); terminating" 595 924 ) in caplog.text 596 925 597 926 598 - def test_enforce_deadlines_escalates_to_sigkill_after_15s(caplog): 927 + def test_terminate_managed_logs_timeout(caplog): 599 928 mod = importlib.import_module("think.supervisor") 600 - queue = mod.TaskQueue(on_queue_change=None) 601 929 managed = _TaskManagedStub(cmd=["sol", "import"], start_time=100.0) 602 - queue._active["ref-1"] = managed 603 - queue._terminations["ref-1"] = 200.0 930 + managed.terminate.side_effect = subprocess.TimeoutExpired( 931 + cmd=managed.cmd, timeout=3 932 + ) 604 933 605 934 caplog.set_level("WARNING") 606 - queue.enforce_deadlines(216.0) 935 + mod._terminate_managed(managed, 3, reason="test") 607 936 608 - managed.process.kill.assert_called_once_with() 609 - assert queue._terminations["ref-1"] == 0.0 610 - assert ( 611 - "Task import (ref=ref-1) did not exit 15s after SIGTERM; sending SIGKILL" 612 - ) in caplog.text 937 + managed.terminate.assert_called_once_with(timeout=3) 938 + assert "task did not terminate within 3.0s for test" in caplog.text 613 939 614 940 615 - def test_enforce_deadlines_clears_termination_state_when_ref_exits(): 941 + def test_enforce_deadlines_noop_when_no_cap(): 616 942 mod = importlib.import_module("think.supervisor") 617 943 queue = mod.TaskQueue(on_queue_change=None) 618 - queue._terminations["ref-1"] = 200.0 944 + managed = _TaskManagedStub(cmd=["sol", "import"], start_time=100.0) 945 + queue._active["ref-1"] = managed 946 + 947 + queue.enforce_deadlines(10_000.0) 948 + 949 + managed.terminate.assert_not_called() 950 + 951 + 952 + def test_restart_service_uses_single_termination_path(monkeypatch): 953 + mod = importlib.import_module("think.supervisor") 954 + managed = _TaskManagedStub(cmd=["sol", "sense"], start_time=100.0) 955 + managed.name = "sense" 956 + managed.ref = "ref-sense" 957 + mod._managed_procs = [managed] 958 + mod._SERVICE_STATE.clear() 959 + mod._SERVICE_STATE["sense"] = { 960 + "restart": False, 961 + "shutdown_timeout": 7, 962 + } 963 + 964 + def terminate_now(key, managed_arg, timeout, reason): 965 + assert key == "sense" 966 + assert managed_arg is managed 967 + assert timeout == 7 968 + assert reason == "restart" 969 + managed_arg.terminate(timeout=timeout) 619 970 620 - queue.enforce_deadlines(216.0) 971 + monkeypatch.setattr(mod, "_start_termination_thread", terminate_now) 621 972 622 - assert "ref-1" not in queue._terminations 973 + assert mod._restart_service("sense") is True 974 + managed.terminate.assert_called_once_with(timeout=7) 975 + assert mod._SERVICE_STATE["sense"]["restart"] is True 623 976 624 977 625 - def test_enforce_deadlines_noop_when_no_cap(): 978 + def test_stop_process_uses_service_shutdown_timeout(): 626 979 mod = importlib.import_module("think.supervisor") 627 - queue = mod.TaskQueue(on_queue_change=None) 628 - managed = _TaskManagedStub(cmd=["sol", "import"], start_time=100.0) 629 - queue._active["ref-1"] = managed 980 + managed = _TaskManagedStub(cmd=["sol", "link"], start_time=100.0) 981 + managed.name = "link" 982 + mod._SERVICE_STATE.clear() 983 + mod._SERVICE_STATE["link"] = { 984 + "restart": True, 985 + "shutdown_timeout": 9, 986 + } 630 987 631 - queue.enforce_deadlines(10_000.0) 988 + mod._stop_process(managed) 632 989 633 - managed.process.send_signal.assert_not_called() 634 - managed.process.kill.assert_not_called() 635 - assert queue._terminations == {} 990 + managed.terminate.assert_called_once_with(timeout=9) 991 + managed.cleanup.assert_called_once_with() 636 992 637 993 638 994 def test_supervisor_singleton_lock_acquired(tmp_path, monkeypatch):
+81
tests/test_supervisor_cgroup.py
··· 1 + # SPDX-License-Identifier: AGPL-3.0-only 2 + # Copyright (c) 2026 sol pbc 3 + 4 + import os 5 + import signal 6 + import sys 7 + 8 + import pytest 9 + 10 + from think import supervisor 11 + 12 + LINUX_ONLY = pytest.mark.skipif( 13 + sys.platform != "linux", reason="cgroup sweep is Linux-only" 14 + ) 15 + 16 + 17 + def test_parse_self_cgroup_path_v2(): 18 + text = ( 19 + "0::/user.slice/user-1000.slice/user@1000.service/app.slice/solstone.service\n" 20 + ) 21 + assert ( 22 + supervisor._parse_self_cgroup_path(text) 23 + == "/user.slice/user-1000.slice/user@1000.service/app.slice/solstone.service" 24 + ) 25 + assert supervisor._parse_self_cgroup_path("1:name=systemd:/ignored\n") is None 26 + assert supervisor._parse_self_cgroup_path("0::\n") is None 27 + 28 + 29 + def test_is_systemd_service_cgroup_matches_solstone_service(): 30 + path = "/user.slice/user-1000.slice/user@1000.service/app.slice/solstone.service" 31 + assert supervisor._is_systemd_service_cgroup(path) is True 32 + 33 + 34 + def test_is_systemd_service_cgroup_rejects_terminal_scope(): 35 + path = "/user.slice/user-1000.slice/session-2.scope" 36 + assert supervisor._is_systemd_service_cgroup(path) is False 37 + assert supervisor._is_systemd_service_cgroup(None) is False 38 + 39 + 40 + @LINUX_ONLY 41 + def test_sweep_cgroup_skips_non_systemd_scope(monkeypatch): 42 + kills = [] 43 + monkeypatch.setattr(supervisor, "_read_self_cgroup_path", lambda: "session-2.scope") 44 + monkeypatch.setattr( 45 + supervisor.os, "kill", lambda pid, sig: kills.append((pid, sig)) 46 + ) 47 + 48 + assert supervisor._sweep_cgroup_at_startup() == 0 49 + assert kills == [] 50 + 51 + 52 + @LINUX_ONLY 53 + def test_sweep_cgroup_terms_and_kills_survivors(monkeypatch): 54 + own_pid = os.getpid() 55 + kills = [] 56 + 57 + monkeypatch.setattr( 58 + supervisor, 59 + "_read_self_cgroup_path", 60 + lambda: ( 61 + "/user.slice/user-1000.slice/user@1000.service/app.slice/solstone.service" 62 + ), 63 + ) 64 + monkeypatch.setattr( 65 + supervisor.Path, 66 + "read_text", 67 + lambda self: f"{own_pid}\n111\n222\n", 68 + ) 69 + monkeypatch.setattr( 70 + supervisor.os, "kill", lambda pid, sig: kills.append((pid, sig)) 71 + ) 72 + monkeypatch.setattr(supervisor.psutil, "pid_exists", lambda pid: pid == 222) 73 + monkeypatch.setattr(supervisor.time, "time", lambda: 100.0) 74 + monkeypatch.setattr(supervisor.time, "sleep", lambda _seconds: None) 75 + 76 + assert supervisor._sweep_cgroup_at_startup(grace=0.0) == 2 77 + assert kills == [ 78 + (111, signal.SIGTERM), 79 + (222, signal.SIGTERM), 80 + (222, signal.SIGKILL), 81 + ]
-88
tests/test_supervisor_orphans.py
··· 1 - # SPDX-License-Identifier: AGPL-3.0-only 2 - # Copyright (c) 2026 sol pbc 3 - 4 - import signal 5 - 6 - import psutil 7 - 8 - from think import supervisor 9 - 10 - 11 - class FakeProcess: 12 - def __init__(self, pid: int, name: str, ppid: int): 13 - self._info = {"pid": pid, "name": name, "ppid": ppid} 14 - 15 - @property 16 - def info(self): 17 - return self._info 18 - 19 - 20 - class VanishedProcess: 21 - @property 22 - def info(self): 23 - raise psutil.NoSuchProcess(pid=4) 24 - 25 - 26 - def test_find_reparented_sol_workers_filters_name_and_ppid(monkeypatch): 27 - monkeypatch.setattr(supervisor.sys, "platform", "linux") 28 - monkeypatch.setattr( 29 - supervisor.psutil, 30 - "process_iter", 31 - lambda attrs: [ 32 - FakeProcess(100, "sol:cortex", 1), 33 - FakeProcess(101, "sol:cortex", 999), 34 - FakeProcess(102, "bash", 1), 35 - VanishedProcess(), 36 - ], 37 - ) 38 - 39 - assert supervisor._find_reparented_sol_workers() == [(100, "sol:cortex")] 40 - 41 - 42 - def test_reap_orphan_workers_empty_is_quiet(monkeypatch): 43 - logs = [] 44 - monkeypatch.setattr(supervisor.os, "kill", lambda *_args: logs.append("kill")) 45 - monkeypatch.setattr( 46 - supervisor.logging, "warning", lambda *_args: logs.append("log") 47 - ) 48 - monkeypatch.setattr( 49 - supervisor.logging, "exception", lambda *_args: logs.append("log") 50 - ) 51 - 52 - assert supervisor._reap_orphan_workers([]) == 0 53 - assert logs == [] 54 - 55 - 56 - def test_reap_orphan_workers_sigterms_then_sigkills_survivors(monkeypatch): 57 - calls = [] 58 - times = iter([0.0, 0.0, 0.06]) 59 - 60 - monkeypatch.setattr( 61 - supervisor.os, "kill", lambda pid, sig: calls.append((pid, sig)) 62 - ) 63 - monkeypatch.setattr(supervisor.time, "time", lambda: next(times)) 64 - monkeypatch.setattr(supervisor.time, "sleep", lambda _seconds: None) 65 - monkeypatch.setattr(supervisor.psutil, "pid_exists", lambda pid: pid == 100) 66 - 67 - assert ( 68 - supervisor._reap_orphan_workers( 69 - [(100, "sol:cortex"), (101, "sol:sense")], grace=0.05 70 - ) 71 - == 2 72 - ) 73 - assert calls == [ 74 - (100, signal.SIGTERM), 75 - (101, signal.SIGTERM), 76 - (100, signal.SIGKILL), 77 - ] 78 - 79 - 80 - def test_find_reparented_sol_workers_noop_on_macos(monkeypatch): 81 - monkeypatch.setattr(supervisor.sys, "platform", "darwin") 82 - monkeypatch.setattr( 83 - supervisor.psutil, 84 - "process_iter", 85 - lambda _attrs: (_ for _ in ()).throw(AssertionError("unexpected")), 86 - ) 87 - 88 - assert supervisor._find_reparented_sol_workers() == []
+7 -1
tests/test_supervisor_startup.py
··· 32 32 "refs": ["pending-ref"], 33 33 "cmd": ["sol", "indexer", "--rescan"], 34 34 "day": "20260418", 35 + "scheduler_name": None, 35 36 } 36 37 ] 37 38 assert queue.collect_queue_counts() == {"pending": 1} ··· 82 83 assert len(started) == 1 83 84 assert started[0][0] == ["ref-1"] 84 85 assert queue._queues["indexer"] == [ 85 - {"refs": ["ref-2"], "cmd": ["sol", "indexer", "--rescan"], "day": None} 86 + { 87 + "refs": ["ref-2"], 88 + "cmd": ["sol", "indexer", "--rescan"], 89 + "day": None, 90 + "scheduler_name": None, 91 + } 86 92 ] 87 93 88 94
+1 -1
tests/verify_browser.py
··· 259 259 env=env, 260 260 stdout=subprocess.DEVNULL, 261 261 stderr=self._stderr_file, 262 - start_new_session=True, 262 + process_group=0, 263 263 ) 264 264 except Exception as exc: 265 265 self._stderr_file.close()
+10 -1
think/cortex.py
··· 342 342 env=env, 343 343 bufsize=1, 344 344 cwd=subprocess_cwd, 345 - start_new_session=True, 345 + process_group=0, 346 346 ) 347 347 348 348 # Send input and close stdin ··· 891 891 892 892 # Start the service 893 893 cortex = CortexService() 894 + _install_sigterm_handler(cortex) 894 895 895 896 try: 896 897 cortex.start() 897 898 except KeyboardInterrupt: 898 899 logging.getLogger(__name__).info("Shutting down Cortex service") 899 900 cortex.stop() 901 + 902 + 903 + def _install_sigterm_handler(cortex: CortexService) -> None: 904 + def handle_sigterm(_signum, _frame) -> None: 905 + logging.getLogger(__name__).info("SIGTERM received, shutting down Cortex") 906 + cortex.stop() 907 + 908 + signal.signal(signal.SIGTERM, handle_sigterm) 900 909 901 910 902 911 if __name__ == "__main__":
+224 -158
think/importers/cli.py
··· 24 24 ) 25 25 from think.importers.text import _read_transcript, process_transcript 26 26 from think.importers.utils import save_import_segments 27 + from think.indexer.journal import index_file 27 28 from think.streams import stream_name, update_stream, write_segment_stream 28 29 from think.utils import ( 29 30 day_path, ··· 321 322 print("Everything is up to date.") 322 323 323 324 324 - def main() -> None: 325 - global _callosum, _message_queue, _import_id, _current_stage, _start_time 326 - global _stage_start_time, _stages_run, _status_thread, _status_running 327 - 328 - parser = argparse.ArgumentParser(description="Import a media file into the journal") 329 - parser.add_argument("media", nargs="?", help="Path to audio or text file") 330 - parser.add_argument( 331 - "--timestamp", help="Timestamp YYYYMMDD_HHMMSS for journal entry" 332 - ) 333 - parser.add_argument( 334 - "--facet", 335 - type=str, 336 - default=None, 337 - help="Facet name for this import", 338 - ) 339 - parser.add_argument( 340 - "--setting", 341 - type=str, 342 - default=None, 343 - help="Contextual setting description to store with import metadata", 344 - ) 345 - parser.add_argument( 346 - "--source", 347 - type=str, 348 - default=None, 349 - help="Import source type (apple, plaud, audio, text, or a file importer name). Auto-detected if omitted.", 350 - ) 351 - parser.add_argument( 352 - "--force", 353 - action="store_true", 354 - help="Force re-import by deleting existing import directory", 355 - ) 356 - parser.add_argument( 357 - "--auto", 358 - nargs="?", 359 - const=True, 360 - default=None, 361 - help="Auto-accept detected timestamp. Optionally provide guidance text for the LLM (e.g., --auto 'timestamps are Pacific time').", 362 - ) 363 - parser.add_argument( 364 - "--dry-run", 365 - action="store_true", 366 - help="Show what would be imported without writing to the journal", 367 - ) 368 - parser.add_argument( 369 - "--backends", 370 - action="store_true", 371 - help="List syncable importer backends", 372 - ) 373 - parser.add_argument( 374 - "--sync", 375 - type=str, 376 - metavar="BACKEND", 377 - help="Sync catalog from a backend (e.g., plaud). Shows status by default.", 378 - ) 379 - parser.add_argument( 380 - "--save", 381 - action="store_true", 382 - help="With --sync: download and import new files (default is dry-run)", 383 - ) 384 - parser.add_argument( 385 - "--path", 386 - type=str, 387 - default=None, 388 - help="With --sync: override the default source directory path", 389 - ) 390 - parser.add_argument( 391 - "--list-importers", 392 - action="store_true", 393 - help="List available file importers", 394 - ) 395 - parser.add_argument( 396 - "--json", 397 - action="store_true", 398 - help="Output results as JSON (file importers only)", 325 + def import_one( 326 + media: str | Path, 327 + *, 328 + timestamp: str | None = None, 329 + facet: str | None = None, 330 + setting: str | None = None, 331 + source: str | None = None, 332 + force: bool = False, 333 + auto: bool | str | None = None, 334 + dry_run: bool = False, 335 + json_output: bool = False, 336 + verbose: bool = False, 337 + ) -> dict[str, Any] | None: 338 + args = argparse.Namespace( 339 + media=os.path.expanduser(str(media)), 340 + timestamp=timestamp, 341 + facet=facet, 342 + setting=setting, 343 + source=source, 344 + force=force, 345 + auto=auto, 346 + dry_run=dry_run, 347 + json=json_output, 348 + verbose=verbose, 399 349 ) 400 - args, extra = setup_cli(parser, parse_known=True) 401 - require_solstone() 402 - if extra and not args.timestamp: 403 - args.timestamp = extra[0] 404 - 405 - # Dispatch journal-source subcommand 406 - if args.media == "journal-source": 407 - import sys 408 - 409 - from think.importers.journal_source_cli import main as journal_source_main 410 - 411 - forwarded_args = sys.argv[1:] 412 - if "journal-source" in forwarded_args: 413 - idx = forwarded_args.index("journal-source") 414 - forwarded_args = forwarded_args[:idx] + forwarded_args[idx + 1 :] 415 - else: 416 - forwarded_args = extra 417 - sys.argv = [sys.argv[0]] + forwarded_args 418 - journal_source_main() 419 - return 420 - 421 - if args.backends: 422 - from think.importers.sync import get_syncable_backends 350 + return _import_one_from_args(args) 423 351 424 - backends = get_syncable_backends() 425 - if backends: 426 - print("Syncable backends:") 427 - for b in backends: 428 - print(f" {b.name}") 429 - else: 430 - print("No syncable backends available") 431 - return 432 352 433 - if args.list_importers: 434 - from think.importers.file_importer import get_file_importers 435 - 436 - importers = get_file_importers() 437 - if args.json: 438 - print( 439 - json.dumps( 440 - [ 441 - { 442 - "name": imp.name, 443 - "display_name": imp.display_name, 444 - "file_patterns": imp.file_patterns, 445 - "description": imp.description, 446 - } 447 - for imp in importers 448 - ] 449 - ) 450 - ) 451 - elif importers: 452 - print("File importers:") 453 - for imp in importers: 454 - patterns = ", ".join(imp.file_patterns) 455 - print(f" {imp.name:<12} {imp.display_name} ({patterns})") 456 - print(f" {imp.description}") 457 - else: 458 - print("No file importers available") 459 - return 460 - 461 - if args.sync: 462 - extra: dict[str, Any] = {} 463 - if args.path: 464 - extra["source_path"] = Path(os.path.expanduser(args.path)) 465 - if args.force: 466 - extra["force"] = True 467 - _run_sync(args.sync, dry_run=not args.save, **extra) 468 - return 469 - 470 - if not args.media: 471 - parser.error("the following arguments are required: media") 353 + def _import_one_from_args(args: argparse.Namespace) -> dict[str, Any] | None: 354 + global _callosum, _message_queue, _import_id, _current_stage, _start_time 355 + global _stage_start_time, _stages_run, _status_thread, _status_running 472 356 473 357 args.media = os.path.expanduser(args.media) 474 358 ··· 488 372 if args.source in FILE_IMPORTER_REGISTRY: 489 373 _file_importer = get_file_importer(args.source) 490 374 if _file_importer is None: 491 - raise SystemExit(f"Failed to load file importer: {args.source}") 375 + raise ValueError(f"Failed to load file importer: {args.source}") 492 376 import_source = args.source 493 377 494 378 # Also try file importer detection for directories ··· 539 423 print(f"Detected timestamp: {detected_timestamp} ({display})") 540 424 print("\nRun:") 541 425 print(f" sol import {args.media} --timestamp {detected_timestamp}") 542 - return 426 + return { 427 + "skipped": True, 428 + "reason": "timestamp_required", 429 + "detected_timestamp": detected_timestamp, 430 + } 543 431 else: 544 - raise SystemExit( 432 + raise ValueError( 545 433 "Could not detect timestamp. Please provide --timestamp YYYYMMDD_HHMMSS" 546 434 ) 547 435 548 436 if not TIME_RE.fullmatch(args.timestamp): 549 - raise SystemExit("timestamp must be in YYYYMMDD_HHMMSS format") 437 + raise ValueError("timestamp must be in YYYYMMDD_HHMMSS format") 550 438 551 439 base_dt = dt.datetime.strptime(args.timestamp, "%Y%m%d_%H%M%S") 552 440 day = base_dt.strftime("%Y%m%d") ··· 596 484 print(f" Entities: {preview.entity_count}") 597 485 print(f" Summary: {preview.summary}") 598 486 print() 599 - return 487 + return { 488 + "dry_run": True, 489 + "importer": _file_importer.name, 490 + "source": args.media, 491 + "item_count": preview.item_count, 492 + "entity_count": preview.entity_count, 493 + } 600 494 601 495 if args.dry_run: 602 496 from think.importers.plaud import format_size ··· 702 596 force=True, 703 597 dry_run=True, 704 598 ) 705 - return 599 + return { 600 + "dry_run": True, 601 + "source": args.media, 602 + "timestamp": args.timestamp, 603 + "source_type": import_source, 604 + } 706 605 707 606 # Copy to imports/ if file is not already there 708 607 if needs_setup: ··· 806 705 f"This file was already imported on {imported_at} " 807 706 f"({entry_count} entries). Use --force to re-import." 808 707 ) 809 - return 708 + return { 709 + "skipped": True, 710 + "reason": "already_imported", 711 + "imported_at": imported_at, 712 + "entry_count": entry_count, 713 + } 810 714 else: 811 715 from think.importers.shared import hash_source 812 716 ··· 938 842 # Index imported files so they're searchable 939 843 if result.files_created: 940 844 _set_stage("indexing") 941 - import subprocess 942 845 943 846 for created_file in result.files_created: 944 847 try: 945 - subprocess.run( 946 - ["sol", "indexer", "--rescan-file", created_file], 947 - capture_output=True, 948 - timeout=60, 949 - ) 848 + index_file(str(journal_root), created_file) 950 849 except Exception as exc: 951 850 logger.warning("Failed to index %s: %s", created_file, exc) 952 851 ··· 1228 1127 entities_seeded=processing_results.get("entities_seeded", 0), 1229 1128 date_range=processing_results.get("date_range"), 1230 1129 ) 1130 + return processing_results 1231 1131 1232 1132 except Exception as e: 1233 1133 duration_ms = int((time.monotonic() - _start_time) * 1000) ··· 1282 1182 _status_thread.join(timeout=6) 1283 1183 if _callosum: 1284 1184 _callosum.stop() 1185 + 1186 + 1187 + def main() -> None: 1188 + global _callosum, _message_queue, _import_id, _current_stage, _start_time 1189 + global _stage_start_time, _stages_run, _status_thread, _status_running 1190 + 1191 + parser = argparse.ArgumentParser(description="Import a media file into the journal") 1192 + parser.add_argument("media", nargs="?", help="Path to audio or text file") 1193 + parser.add_argument( 1194 + "--timestamp", help="Timestamp YYYYMMDD_HHMMSS for journal entry" 1195 + ) 1196 + parser.add_argument( 1197 + "--facet", 1198 + type=str, 1199 + default=None, 1200 + help="Facet name for this import", 1201 + ) 1202 + parser.add_argument( 1203 + "--setting", 1204 + type=str, 1205 + default=None, 1206 + help="Contextual setting description to store with import metadata", 1207 + ) 1208 + parser.add_argument( 1209 + "--source", 1210 + type=str, 1211 + default=None, 1212 + help="Import source type (apple, plaud, audio, text, or a file importer name). Auto-detected if omitted.", 1213 + ) 1214 + parser.add_argument( 1215 + "--force", 1216 + action="store_true", 1217 + help="Force re-import by deleting existing import directory", 1218 + ) 1219 + parser.add_argument( 1220 + "--auto", 1221 + nargs="?", 1222 + const=True, 1223 + default=None, 1224 + help="Auto-accept detected timestamp. Optionally provide guidance text for the LLM (e.g., --auto 'timestamps are Pacific time').", 1225 + ) 1226 + parser.add_argument( 1227 + "--dry-run", 1228 + action="store_true", 1229 + help="Show what would be imported without writing to the journal", 1230 + ) 1231 + parser.add_argument( 1232 + "--backends", 1233 + action="store_true", 1234 + help="List syncable importer backends", 1235 + ) 1236 + parser.add_argument( 1237 + "--sync", 1238 + type=str, 1239 + metavar="BACKEND", 1240 + help="Sync catalog from a backend (e.g., plaud). Shows status by default.", 1241 + ) 1242 + parser.add_argument( 1243 + "--save", 1244 + action="store_true", 1245 + help="With --sync: download and import new files (default is dry-run)", 1246 + ) 1247 + parser.add_argument( 1248 + "--path", 1249 + type=str, 1250 + default=None, 1251 + help="With --sync: override the default source directory path", 1252 + ) 1253 + parser.add_argument( 1254 + "--list-importers", 1255 + action="store_true", 1256 + help="List available file importers", 1257 + ) 1258 + parser.add_argument( 1259 + "--json", 1260 + action="store_true", 1261 + help="Output results as JSON (file importers only)", 1262 + ) 1263 + args, extra = setup_cli(parser, parse_known=True) 1264 + require_solstone() 1265 + if extra and not args.timestamp: 1266 + args.timestamp = extra[0] 1267 + 1268 + # Dispatch journal-source subcommand 1269 + if args.media == "journal-source": 1270 + import sys 1271 + 1272 + from think.importers.journal_source_cli import main as journal_source_main 1273 + 1274 + forwarded_args = sys.argv[1:] 1275 + if "journal-source" in forwarded_args: 1276 + idx = forwarded_args.index("journal-source") 1277 + forwarded_args = forwarded_args[:idx] + forwarded_args[idx + 1 :] 1278 + else: 1279 + forwarded_args = extra 1280 + sys.argv = [sys.argv[0]] + forwarded_args 1281 + journal_source_main() 1282 + return 1283 + 1284 + if args.backends: 1285 + from think.importers.sync import get_syncable_backends 1286 + 1287 + backends = get_syncable_backends() 1288 + if backends: 1289 + print("Syncable backends:") 1290 + for b in backends: 1291 + print(f" {b.name}") 1292 + else: 1293 + print("No syncable backends available") 1294 + return 1295 + 1296 + if args.list_importers: 1297 + from think.importers.file_importer import get_file_importers 1298 + 1299 + importers = get_file_importers() 1300 + if args.json: 1301 + print( 1302 + json.dumps( 1303 + [ 1304 + { 1305 + "name": imp.name, 1306 + "display_name": imp.display_name, 1307 + "file_patterns": imp.file_patterns, 1308 + "description": imp.description, 1309 + } 1310 + for imp in importers 1311 + ] 1312 + ) 1313 + ) 1314 + elif importers: 1315 + print("File importers:") 1316 + for imp in importers: 1317 + patterns = ", ".join(imp.file_patterns) 1318 + print(f" {imp.name:<12} {imp.display_name} ({patterns})") 1319 + print(f" {imp.description}") 1320 + else: 1321 + print("No file importers available") 1322 + return 1323 + 1324 + if args.sync: 1325 + extra: dict[str, Any] = {} 1326 + if args.path: 1327 + extra["source_path"] = Path(os.path.expanduser(args.path)) 1328 + if args.force: 1329 + extra["force"] = True 1330 + _run_sync(args.sync, dry_run=not args.save, **extra) 1331 + return 1332 + 1333 + if not args.media: 1334 + parser.error("the following arguments are required: media") 1335 + 1336 + try: 1337 + import_one( 1338 + args.media, 1339 + timestamp=args.timestamp, 1340 + facet=args.facet, 1341 + setting=args.setting, 1342 + source=args.source, 1343 + force=args.force, 1344 + auto=args.auto, 1345 + dry_run=args.dry_run, 1346 + json_output=args.json, 1347 + verbose=args.verbose, 1348 + ) 1349 + except Exception as exc: 1350 + raise SystemExit(str(exc)) from exc 1285 1351 1286 1352 1287 1353 if __name__ == "__main__":
+8 -12
think/importers/journal_archive.py
··· 11 11 import os 12 12 import re 13 13 import shutil 14 - import subprocess 15 14 import zipfile 16 15 from contextlib import contextmanager 17 16 from dataclasses import asdict, dataclass, field 18 17 from pathlib import Path 19 18 from typing import Any, Callable, Iterator 20 19 20 + from think.callosum import callosum_send 21 21 from think.entities.journal import get_journal_principal 22 22 from think.importers.file_importer import ImportPreview, ImportResult 23 23 from think.merge import ProgressCallback, merge_journals ··· 549 549 ) 550 550 merge_summary = asdict(summary) 551 551 if not dry_run: 552 - try: 553 - subprocess.Popen( 554 - ["sol", "indexer", "--rescan-full"], 555 - stdout=subprocess.DEVNULL, 556 - stderr=subprocess.DEVNULL, 557 - start_new_session=True, 558 - ) 559 - except OSError as exc: 552 + ok = callosum_send( 553 + "supervisor", 554 + "request", 555 + cmd=["sol", "indexer", "--rescan-full"], 556 + ) 557 + if not ok: 560 558 logger.warning( 561 - "Failed to start full index rescan for journal archive import %s: %s", 562 - import_id, 563 - exc, 559 + "post-merge full reindex: callosum_send returned false" 564 560 ) 565 561 566 562 return ImportResult(
+19 -50
think/importers/plaud.py
··· 9 9 import os 10 10 import pathlib 11 11 import re 12 - import subprocess 13 12 import tempfile 14 13 import time 15 14 from pathlib import Path ··· 18 17 import requests 19 18 from requests.adapters import HTTPAdapter 20 19 from urllib3.util.retry import Retry 20 + 21 + from think.importers.cli import import_one 21 22 22 23 logger = logging.getLogger(__name__) 23 24 ··· 446 447 downloaded = 0 447 448 errors: list[str] = [] 448 449 449 - # Verbose detection — pass logging flags to subprocesses 450 - verbose = logger.isEnabledFor(logging.INFO) 451 - debug = logger.isEnabledFor(logging.DEBUG) 452 - 453 450 # Inactivity-based sync timeout: bail if no file completes 454 451 # within this window. The inner import process has its own 455 452 # 600s inactivity timeout for stall detection, so this is a ··· 531 528 532 529 logger.info(" Downloaded -> %s", dest_path.name) 533 530 534 - # Run through import pipeline 535 - import_cmd = [ 536 - "sol", 537 - "import", 538 - str(dest_path), 539 - "--timestamp", 540 - ts, 541 - "--source", 542 - "plaud", 543 - "--auto", 544 - ] 545 - if debug: 546 - import_cmd.append("-d") 547 - elif verbose: 548 - import_cmd.append("-v") 549 - 550 531 logger.info(" Importing %s...", ts) 551 532 import_start = time.monotonic() 552 533 553 - # No subprocess timeout — the inner import process has its 554 - # own inactivity-based timeout (600s) for stall detection. 555 - if verbose: 556 - proc = subprocess.run(import_cmd) 557 - else: 558 - proc = subprocess.run( 559 - import_cmd, 560 - capture_output=True, 561 - text=True, 534 + try: 535 + import_one( 536 + dest_path, 537 + timestamp=ts, 538 + source="plaud", 539 + auto=True, 540 + verbose=False, 562 541 ) 563 - import_elapsed = int(time.monotonic() - import_start) 564 - last_completed = time.monotonic() 565 - 566 - if proc.returncode == 0: 542 + except Exception as exc: 543 + import_elapsed = int(time.monotonic() - import_start) 544 + last_completed = time.monotonic() 545 + msg = f"{filename}: import failed — {exc}" 546 + logger.warning("Import failed for %s: %s", filename, exc) 547 + logger.warning(" FAILED — %s", msg) 548 + errors.append(msg) 549 + else: 550 + import_elapsed = int(time.monotonic() - import_start) 551 + last_completed = time.monotonic() 567 552 info["status"] = "imported" 568 553 info["import_timestamp"] = ts 569 554 info["imported_at"] = dt.datetime.now().isoformat() 570 555 downloaded += 1 571 556 logger.info(" Imported successfully (%ss)", import_elapsed) 572 - else: 573 - if verbose: 574 - msg = ( 575 - f"{filename}: import failed " 576 - f"(exit code {proc.returncode}, {import_elapsed}s)" 577 - ) 578 - else: 579 - stderr_tail = ( 580 - proc.stderr.strip().split("\n")[-1] if proc.stderr else "" 581 - ) 582 - msg = f"{filename}: import failed — {stderr_tail}" 583 - logger.warning( 584 - "Import failed for %s: %s", filename, proc.stderr 585 - ) 586 - logger.warning(" FAILED — %s", msg) 587 - errors.append(msg) 588 557 589 558 result["downloaded"] = downloaded 590 559 result["errors"] = errors
+9 -15
think/models.py
··· 7 7 import json 8 8 import logging 9 9 import os 10 - import subprocess 11 10 import time 12 11 from datetime import datetime, timezone 13 12 from pathlib import Path ··· 16 15 import frontmatter 17 16 from jsonschema import Draft202012Validator 18 17 18 + from think.callosum import callosum_send 19 19 from think.utils import get_config, get_journal, now_ms 20 20 21 21 logger = logging.getLogger(__name__) ··· 1280 1280 1281 1281 1282 1282 def request_health_recheck() -> None: 1283 - """Request a health re-check by spawning a background process. 1284 - 1285 - Fire-and-forget; errors are logged but never propagated. 1286 - """ 1287 - try: 1288 - subprocess.Popen( 1289 - ["sol", "providers", "check", "--targeted"], 1290 - stdout=subprocess.DEVNULL, 1291 - stderr=subprocess.DEVNULL, 1292 - ) 1293 - except Exception: 1294 - logging.getLogger(__name__).debug( 1295 - "Failed to request health recheck", exc_info=True 1296 - ) 1283 + """Request a health re-check through the supervisor.""" 1284 + ok = callosum_send( 1285 + "supervisor", 1286 + "request", 1287 + cmd=["sol", "providers", "check", "--targeted"], 1288 + ) 1289 + if not ok: 1290 + logger.warning("request_health_recheck: callosum_send returned false") 1297 1291 1298 1292 1299 1293 def generate_with_result(
+1 -1
think/providers/cli.py
··· 436 436 limit=1024 * 1024, 437 437 cwd=str(self.cwd), 438 438 env=proc_env, 439 - start_new_session=True, 439 + process_group=0, 440 440 ) 441 441 442 442 def _send_prompt(self, process: asyncio.subprocess.Process) -> None:
+1 -1
think/runner.py
··· 291 291 text=True, 292 292 bufsize=1, 293 293 env=env, 294 - start_new_session=True, 294 + process_group=0, 295 295 ) 296 296 except Exception as exc: 297 297 log_writer.close()
+10 -8
think/scheduler.py
··· 17 17 import json 18 18 import logging 19 19 import tempfile 20 - import time 21 20 from datetime import datetime, timedelta 22 21 from pathlib import Path 23 22 from typing import Any ··· 408 407 Called each supervisor tick (~1s). Does nothing unless an hour or day 409 408 boundary has been crossed since the last check. 410 409 """ 411 - global _entries, _last_hour, _last_daily_mark, _last_weekly_mark 410 + global _entries, _state, _last_hour, _last_daily_mark, _last_weekly_mark 412 411 413 412 if _last_hour is None: 414 413 return ··· 430 429 431 430 # Boundary crossed — reload config for freshest definitions 432 431 _entries = load_config() 432 + _state = load_state() 433 433 _last_hour = current_hour 434 434 # Recompute with potentially updated _daily_time from config reload 435 435 new_daily_mark = _compute_daily_mark(now, _daily_time) ··· 466 466 cmd = entry["cmd"] 467 467 468 468 if _callosum: 469 - ok = _callosum.emit("supervisor", "request", cmd=cmd, ref=ref) 469 + ok = _callosum.emit( 470 + "supervisor", 471 + "request", 472 + cmd=cmd, 473 + ref=ref, 474 + scheduler_name=name, 475 + ) 470 476 if ok: 471 477 logger.info( 472 478 "Scheduled task submitted: %s → %s (ref=%s)", ··· 474 480 " ".join(cmd), 475 481 ref, 476 482 ) 477 - _state.setdefault(name, {})["last_run"] = time.time() 478 483 submitted = True 479 484 else: 480 485 logger.warning( ··· 484 489 logger.warning("No callosum connection for scheduled task: %s", name) 485 490 486 491 if submitted: 487 - try: 488 - save_state() 489 - except Exception as exc: 490 - logger.warning("Failed to save scheduler state: %s", exc) 492 + logger.debug("Submitted scheduled task batch") 491 493 492 494 493 495 def collect_status() -> list[dict[str, Any]]:
+2
think/service.py
··· 222 222 f"ExecStart={sol} supervisor {port}\n" 223 223 f"Restart=on-failure\n" 224 224 f"RestartSec=5\n" 225 + f"KillMode=control-group\n" 226 + f"TimeoutStopSec=30\n" 225 227 f"{env_lines}\n" 226 228 f"\n" 227 229 f"[Install]\n"
+307 -184
think/supervisor.py
··· 5 5 6 6 import argparse 7 7 import asyncio 8 + import concurrent.futures 8 9 import json 9 10 import logging 10 11 import os 11 12 import signal 12 13 import subprocess 13 14 import sys 15 + import tempfile 14 16 import threading 15 17 import time 16 - from dataclasses import dataclass, field 18 + from collections import deque 17 19 from datetime import datetime 18 20 from pathlib import Path 21 + from typing import Any 19 22 20 23 import psutil 21 24 22 25 from think import routines, scheduler 23 26 from think.callosum import CallosumConnection, CallosumServer 24 27 from think.maint import run_pending_tasks 25 - from think.runner import DailyLogWriter 26 28 from think.runner import ManagedProcess as RunnerManagedProcess 27 29 from think.utils import ( 28 30 EXIT_TEMPFAIL, ··· 42 44 CHECK_INTERVAL = 30 43 45 MAX_UPDATED_CATCHUP = 4 44 46 TEMPFAIL_DELAY = 15 # seconds to wait before retrying a tempfail exit 45 - _ORPHAN_WORKER_NAMES = { 46 - "sol:convey", 47 - "sol:sense", 48 - "sol:cortex", 49 - "sol:link", 50 - "sol:think", 51 - "sol:heartbeat", 52 - } 47 + logger = logging.getLogger(__name__) 53 48 _SERVICE_LIFECYCLE_VERBS = { 54 49 "start", 55 50 "stop", ··· 67 62 _supervisor_start: float | None = None 68 63 69 64 70 - def _find_reparented_sol_workers() -> list[tuple[int, str]]: 71 - if sys.platform != "linux": 72 - return [] 65 + def _parse_self_cgroup_path(text: str) -> str | None: 66 + """Parse cgroup v2 line `0::/path` from /proc/self/cgroup contents.""" 67 + for line in text.splitlines(): 68 + if line.startswith("0::"): 69 + return line[3:].strip() or None 70 + return None 73 71 74 - orphans: list[tuple[int, str]] = [] 75 - for proc in psutil.process_iter(["pid", "name", "ppid"]): 76 - try: 77 - info = proc.info 78 - pid = int(info["pid"]) 79 - name = str(info.get("name") or "") 80 - ppid = int(info.get("ppid") or 0) 81 - except (KeyError, TypeError, ValueError): 82 - continue 83 - except (psutil.NoSuchProcess, psutil.AccessDenied, psutil.ZombieProcess): 84 - continue 85 - if name in _ORPHAN_WORKER_NAMES and ppid == 1: 86 - orphans.append((pid, name)) 87 - return orphans 72 + 73 + def _read_self_cgroup_path() -> str | None: 74 + try: 75 + return _parse_self_cgroup_path(Path("/proc/self/cgroup").read_text()) 76 + except OSError: 77 + return None 78 + 79 + 80 + def _is_systemd_service_cgroup(cgroup_path: str | None) -> bool: 81 + # Only sweep when this supervisor owns the cgroup; dev shells share scopes. 82 + if not cgroup_path: 83 + return False 84 + from think.service import SYSTEMD_UNIT 85 + 86 + return f"{SYSTEMD_UNIT}.service" in cgroup_path 88 87 89 88 90 - def _reap_orphan_workers(orphans: list[tuple[int, str]], grace: float = 5.0) -> int: 91 - if not orphans: 89 + def _sweep_cgroup_at_startup(grace: float = 5.0) -> int: 90 + if sys.platform != "linux": 91 + return 0 92 + cgroup_path = _read_self_cgroup_path() 93 + if not _is_systemd_service_cgroup(cgroup_path): 94 + return 0 95 + procs_file = Path("/sys/fs/cgroup") / cgroup_path.lstrip("/") / "cgroup.procs" 96 + try: 97 + pids = [int(pid) for pid in procs_file.read_text().split() if pid.strip()] 98 + except OSError: 92 99 return 0 93 100 94 - reaped = 0 95 - for pid, name in orphans: 101 + own_pid = os.getpid() 102 + targets = [pid for pid in pids if pid != own_pid] 103 + if not targets: 104 + return 0 105 + 106 + logger.info("cgroup sweep: terminating %d residual process(es)", len(targets)) 107 + for pid in targets: 96 108 try: 97 - logging.warning("Terminating orphaned sol worker %s (PID %d)", name, pid) 98 109 os.kill(pid, signal.SIGTERM) 99 - reaped += 1 100 110 except ProcessLookupError: 101 - reaped += 1 102 - except (PermissionError, OSError): 103 - logging.exception( 104 - "Failed to terminate orphaned sol worker %s (PID %d)", name, pid 105 - ) 111 + pass 106 112 107 113 deadline = time.time() + grace 108 114 while time.time() < deadline: 109 - if all(not psutil.pid_exists(pid) for pid, _name in orphans): 110 - return reaped 111 - time.sleep(0.1) 115 + if not any(psutil.pid_exists(pid) for pid in targets): 116 + break 117 + time.sleep(0.2) 112 118 113 - for pid, name in orphans: 114 - if not psutil.pid_exists(pid): 115 - continue 119 + survivors = [pid for pid in targets if psutil.pid_exists(pid)] 120 + for pid in survivors: 116 121 try: 117 - logging.warning("Killing orphaned sol worker %s (PID %d)", name, pid) 118 122 os.kill(pid, signal.SIGKILL) 119 123 except ProcessLookupError: 120 - continue 121 - except (PermissionError, OSError): 122 - logging.exception( 123 - "Failed to kill orphaned sol worker %s (PID %d)", name, pid 124 - ) 125 - return reaped 124 + pass 125 + return len(targets) 126 126 127 127 128 128 class CallosumLogHandler(logging.Handler): ··· 197 197 ] = {} # command_name -> {"ref": str, "thread": Thread} 198 198 self._queues: dict[str, list] = {} # command_name -> list of {refs, cmd} dicts 199 199 self._active: dict[str, RunnerManagedProcess] = {} # ref -> process 200 + self._history: deque[dict[str, Any]] = deque(maxlen=100) 201 + self._cap_terminated: set[str] = set() 200 202 self._caps: dict[str, int] = {} 201 - self._terminations: dict[str, float] = {} 202 203 self._pending: list[dict] = [] 203 204 self._ready = ready 204 205 self._lock = threading.Lock() ··· 235 236 cmd: list[str], 236 237 ref: str | None = None, 237 238 day: str | None = None, 239 + scheduler_name: str | None = None, 238 240 ) -> str | None: 239 241 """Submit a task for execution. 240 242 ··· 254 256 255 257 with self._lock: 256 258 if not self._ready: 257 - self._pending.append({"refs": [ref], "cmd": cmd, "day": day}) 259 + self._pending.append( 260 + { 261 + "refs": [ref], 262 + "cmd": cmd, 263 + "day": day, 264 + "scheduler_name": scheduler_name, 265 + } 266 + ) 258 267 should_notify_pending = True 259 268 else: 260 269 should_notify_pending = False ··· 293 302 logging.debug(f"Ref already tracked for queued task: {ref}") 294 303 return None 295 304 else: 296 - queue.append({"refs": [ref], "cmd": cmd, "day": day}) 305 + queue.append( 306 + { 307 + "refs": [ref], 308 + "cmd": cmd, 309 + "day": day, 310 + "scheduler_name": scheduler_name, 311 + } 312 + ) 297 313 logging.info( 298 314 f"Queued task {cmd_name}: {' '.join(cmd)} ref={ref} " 299 315 f"(queue: {len(queue)})" ··· 302 318 else: 303 319 # Not running - mark as running and start 304 320 # Thread is set to None here; _run_task registers it on entry 305 - self._running[cmd_name] = {"ref": ref, "thread": None} 321 + self._running[cmd_name] = { 322 + "ref": ref, 323 + "thread": None, 324 + "scheduler_name": scheduler_name, 325 + } 306 326 should_start = True 307 327 308 328 # Notify outside lock ··· 314 334 if should_start: 315 335 threading.Thread( 316 336 target=self._run_task, 317 - args=([ref], cmd, cmd_name, day), 337 + args=([ref], cmd, cmd_name, day, scheduler_name), 318 338 daemon=True, 319 339 ).start() 320 340 return ref ··· 326 346 with self._lock: 327 347 self._caps[cmd_name] = seconds 328 348 349 + def get_active_by_cmd_name(self, name: str) -> str | None: 350 + """Return the first active ref matching a command name.""" 351 + with self._lock: 352 + for ref, managed in self._active.items(): 353 + if self.get_command_name(managed.cmd) == name: 354 + return ref 355 + return None 356 + 329 357 def enforce_deadlines(self, now: float) -> None: 330 358 """Enforce configured task runtime caps without blocking the supervisor tick.""" 331 359 with self._lock: 332 - active_refs = set(self._active) 333 - for ref in list(self._terminations): 334 - if ref not in active_refs: 335 - self._terminations.pop(ref, None) 336 - 337 360 for ref, managed in list(self._active.items()): 338 361 cmd_name = self.get_command_name(managed.cmd) 339 - termination_started = self._terminations.get(ref) 340 - if termination_started is not None: 341 - if termination_started <= 0: 342 - continue 343 - if now - termination_started >= 15: 344 - logging.warning( 345 - "Task %s (ref=%s) did not exit 15s after SIGTERM; " 346 - "sending SIGKILL", 347 - cmd_name, 348 - ref, 349 - ) 350 - try: 351 - managed.process.kill() 352 - except (ProcessLookupError, OSError): 353 - pass 354 - self._terminations[ref] = 0.0 355 - continue 356 - 357 362 cap = self._caps.get(cmd_name) 358 363 if not cap: 359 364 continue ··· 365 370 elapsed_seconds = int(elapsed) 366 371 logging.warning( 367 372 "Task %s (cmd=%s, ref=%s) exceeded max_runtime of %ds " 368 - "(elapsed=%ds); sending SIGTERM", 373 + "(elapsed=%ds); terminating", 369 374 cmd_name, 370 375 " ".join(managed.cmd), 371 376 ref, 372 377 cap, 373 378 elapsed_seconds, 374 379 ) 375 - try: 376 - managed.process.send_signal(signal.SIGTERM) 377 - self._terminations[ref] = now 378 - except (ProcessLookupError, OSError): 379 - pass 380 + self._cap_terminated.add(ref) 381 + _start_termination_thread(ref, managed, timeout=2.0, reason="cap") 380 382 381 383 def set_ready(self) -> None: 382 384 """Allow buffered tasks to start dispatching through the normal queue path.""" ··· 390 392 if pending: 391 393 self._notify_queue_change("pending") 392 394 for entry in pending: 393 - self.submit(entry["cmd"], ref=entry["refs"][0], day=entry.get("day")) 395 + self.submit( 396 + entry["cmd"], 397 + ref=entry["refs"][0], 398 + day=entry.get("day"), 399 + scheduler_name=entry.get("scheduler_name"), 400 + ) 394 401 395 402 def _run_task( 396 403 self, ··· 398 405 cmd: list[str], 399 406 cmd_name: str, 400 407 day: str | None = None, 408 + scheduler_name: str | None = None, 401 409 ) -> None: 402 410 """Execute a task and handle completion. 403 411 ··· 416 424 managed = None 417 425 primary_ref = refs[0] 418 426 service = cmd_name 427 + exit_status = "error" 419 428 420 429 try: 421 430 callosum.start() ··· 436 445 ) 437 446 438 447 exit_code = managed.wait() 448 + exit_status = "ok" if exit_code == 0 else "error" 439 449 440 450 for ref in refs: 441 451 callosum.emit( ··· 455 465 ) 456 466 457 467 except Exception as e: 468 + if isinstance(e, subprocess.TimeoutExpired): 469 + exit_status = "timeout" 458 470 logging.exception( 459 471 f"Task {cmd_name} ({primary_ref}) encountered exception: {e}" 460 472 ) ··· 468 480 exit_code=-1, 469 481 ) 470 482 finally: 471 - # Each cleanup step is isolated so _process_next always runs. 472 - # A disk-full or other OS error in cleanup must never stall the queue. 473 483 try: 474 484 if managed: 475 485 managed.cleanup() ··· 477 487 logging.exception(f"Task {cmd_name} ({primary_ref}): cleanup failed") 478 488 with self._lock: 479 489 self._active.pop(primary_ref, None) 490 + if primary_ref in self._cap_terminated: 491 + exit_status = "timeout" 492 + self._cap_terminated.discard(primary_ref) 493 + ended_at = time.time() 494 + self._history.append( 495 + { 496 + "name": cmd_name, 497 + "cmd": list(cmd), 498 + "ref": primary_ref, 499 + "ended_at": ended_at, 500 + "exit_status": exit_status, 501 + "scheduler_name": scheduler_name, 502 + } 503 + ) 504 + if scheduler_name: 505 + try: 506 + _record_scheduler_completion( 507 + scheduler_name, 508 + ended_at=ended_at, 509 + exit_status=exit_status, 510 + ref=primary_ref, 511 + cmd=cmd, 512 + ) 513 + except Exception as exc: 514 + logger.warning("scheduler completion writeback failed: %s", exc) 480 515 try: 481 516 callosum.stop() 482 517 except Exception: ··· 490 525 next_cmd = None 491 526 refs = None 492 527 day = None 528 + scheduler_name = None 493 529 494 530 with self._lock: 495 531 queue = self._queues.get(cmd_name, []) ··· 498 534 refs = entry["refs"] 499 535 next_cmd = entry["cmd"] 500 536 day = entry.get("day") 537 + scheduler_name = entry.get("scheduler_name") 501 538 # Thread is set to None here; _run_task registers it on entry 502 - self._running[cmd_name] = {"ref": refs[0], "thread": None} 539 + self._running[cmd_name] = { 540 + "ref": refs[0], 541 + "thread": None, 542 + "scheduler_name": scheduler_name, 543 + } 503 544 logging.info( 504 545 f"Dequeued task {cmd_name}: {' '.join(next_cmd)} refs={refs} " 505 546 f"(remaining: {len(queue)})" ··· 512 553 if next_cmd: 513 554 threading.Thread( 514 555 target=self._run_task, 515 - args=(refs, next_cmd, cmd_name, day), 556 + args=(refs, next_cmd, cmd_name, day, scheduler_name), 516 557 daemon=True, 517 558 ).start() 518 559 ··· 535 576 managed.terminate() 536 577 return True 537 578 579 + def shutdown(self, timeout: float = 10.0) -> int: 580 + with self._lock: 581 + active = list(self._active.items()) 582 + if not active: 583 + return 0 584 + 585 + def _terminate(item: tuple[str, RunnerManagedProcess]) -> None: 586 + ref, managed = item 587 + try: 588 + managed.terminate(timeout=timeout) 589 + except subprocess.TimeoutExpired: 590 + logger.warning( 591 + "task %s did not exit within %ss; KILL sent", ref, timeout 592 + ) 593 + except OSError as exc: 594 + logger.warning("task %s terminate raised: %s", ref, exc) 595 + 596 + with concurrent.futures.ThreadPoolExecutor(max_workers=len(active)) as executor: 597 + list(executor.map(_terminate, active)) 598 + return len(active) 599 + 538 600 def get_status(self, ref: str) -> dict: 539 601 """Get status of a task.""" 540 602 if ref not in self._active: ··· 586 648 _supervisor_callosum: CallosumConnection | None = None 587 649 588 650 # Global reference to managed processes for restart control 589 - _managed_procs: list[ManagedProcess] = [] 651 + _managed_procs: list[RunnerManagedProcess] = [] 652 + _SERVICE_STATE: dict[str, dict[str, Any]] = {} 653 + _termination_threads: dict[str, threading.Thread] = {} 654 + _termination_threads_lock = threading.Lock() 655 + _SCHEDULER_JSON_LOCK = threading.Lock() 590 656 591 657 # Global reference to in-process Callosum server 592 658 _callosum_server: CallosumServer | None = None 593 659 _callosum_thread: threading.Thread | None = None 594 - 595 - # Restart request tracking for SIGKILL enforcement 596 - _restart_requests: dict[str, tuple[float, subprocess.Popen]] = {} 597 660 598 661 # Track whether running in remote mode (upload-only, no local processing) 599 662 _is_remote_mode: bool = False ··· 687 750 return _RESTART_POLICIES.setdefault(name, RestartPolicy()) 688 751 689 752 690 - @dataclass 691 - class ManagedProcess: 692 - """Wrapper around RunnerManagedProcess for restart policy tracking.""" 693 - 694 - process: subprocess.Popen 695 - name: str 696 - log_writer: DailyLogWriter 697 - cmd: list[str] 698 - restart: bool = False 699 - shutdown_timeout: int = 15 700 - threads: list[threading.Thread] = field(default_factory=list) 701 - ref: str = "" 702 - 703 - def cleanup(self) -> None: 704 - for thread in self.threads: 705 - thread.join(timeout=1) 706 - self.log_writer.close() 707 - 708 - 709 753 def _launch_process( 710 754 name: str, 711 755 cmd: list[str], 712 756 *, 713 757 restart: bool = False, 758 + shutdown_timeout: int = 15, 714 759 ref: str | None = None, 715 - ) -> ManagedProcess: 760 + ) -> RunnerManagedProcess: 716 761 # NOTE: All child processes should include -v for verbose logging by default. 717 762 # This ensures their output is captured in logs for debugging. 718 763 """Launch process with automatic output logging and restart policy tracking.""" ··· 734 779 735 780 if policy: 736 781 policy.record_start() 782 + _SERVICE_STATE[name] = { 783 + "restart": restart, 784 + "shutdown_timeout": shutdown_timeout, 785 + } 737 786 738 787 # Emit started event 739 788 if _supervisor_callosum: ··· 745 794 ref=managed.ref, 746 795 ) 747 796 748 - # Wrap in ManagedProcess for restart tracking 749 - return ManagedProcess( 750 - process=managed.process, 751 - name=name, 752 - log_writer=managed.log_writer, 753 - cmd=list(cmd), 754 - restart=restart, 755 - threads=managed._threads, 756 - ref=managed.ref, 757 - ) 797 + return managed 798 + 799 + 800 + def _terminate_managed( 801 + managed: RunnerManagedProcess, timeout: float, *, reason: str 802 + ) -> None: 803 + logger.info("Terminating %s for %s", managed.name, reason) 804 + try: 805 + managed.terminate(timeout=timeout) 806 + except subprocess.TimeoutExpired: 807 + logger.warning( 808 + "%s did not terminate within %.1fs for %s", 809 + managed.name, 810 + timeout, 811 + reason, 812 + ) 813 + 814 + 815 + def _start_termination_thread( 816 + key: str, managed: RunnerManagedProcess, timeout: float, reason: str 817 + ) -> None: 818 + def run() -> None: 819 + try: 820 + _terminate_managed(managed, timeout, reason=reason) 821 + finally: 822 + with _termination_threads_lock: 823 + if _termination_threads.get(key) is threading.current_thread(): 824 + _termination_threads.pop(key, None) 825 + 826 + with _termination_threads_lock: 827 + existing = _termination_threads.get(key) 828 + if existing and existing.is_alive(): 829 + return 830 + 831 + thread = threading.Thread( 832 + target=run, 833 + daemon=True, 834 + name=f"terminate-{key}", 835 + ) 836 + _termination_threads[key] = thread 837 + thread.start() 838 + 839 + 840 + def _stop_process(managed: RunnerManagedProcess) -> None: 841 + timeout = _SERVICE_STATE.get(managed.name, {}).get("shutdown_timeout", 15) 842 + _terminate_managed(managed, timeout, reason="shutdown") 843 + managed.cleanup() 844 + 845 + 846 + def _record_scheduler_completion( 847 + scheduler_name: str, 848 + *, 849 + ended_at: float, 850 + exit_status: str, 851 + ref: str, 852 + cmd: list[str], 853 + ) -> None: 854 + health_dir = Path(get_journal()) / "health" 855 + health_dir.mkdir(parents=True, exist_ok=True) 856 + state_path = health_dir / "scheduler.json" 857 + with _SCHEDULER_JSON_LOCK: 858 + try: 859 + with open(state_path, "r", encoding="utf-8") as file: 860 + state = json.load(file) 861 + except FileNotFoundError: 862 + state = {} 863 + except (json.JSONDecodeError, OSError) as exc: 864 + logger.warning( 865 + "Failed to load scheduler state for completion write: %s", exc 866 + ) 867 + state = {} 868 + 869 + current = state.get(scheduler_name) 870 + if not isinstance(current, dict): 871 + current = {} 872 + current.update( 873 + { 874 + "last_run": ended_at, 875 + "last_status": exit_status, 876 + "last_ref": ref, 877 + } 878 + ) 879 + state[scheduler_name] = current 880 + 881 + fd, tmp_path = tempfile.mkstemp( 882 + dir=health_dir, suffix=".tmp", prefix=".scheduler_" 883 + ) 884 + tmp_file = Path(tmp_path) 885 + try: 886 + with open(fd, "w", encoding="utf-8") as file: 887 + json.dump(state, file, indent=2) 888 + tmp_file.replace(state_path) 889 + except BaseException: 890 + tmp_file.unlink(missing_ok=True) 891 + raise 758 892 759 893 760 894 def _emit_queue_event(cmd_name: str, running_ref: str, queue: list) -> None: ··· 802 936 logging.error(f"Invalid task request: missing cmd: {message}") 803 937 return 804 938 805 - ref = message.get("ref") 939 + ref = message.get("ref") or str(now_ms()) 806 940 day = message.get("day") 941 + scheduler_name = message.get("scheduler_name") 807 942 if _task_queue: 808 - _task_queue.submit(cmd, ref, day=day) 943 + cmd_name = TaskQueue.get_command_name(cmd) 944 + active_ref = _task_queue.get_active_by_cmd_name(cmd_name) 945 + if active_ref: 946 + with _task_queue._lock: 947 + managed = _task_queue._active.get(active_ref) 948 + cap = _task_queue._caps.get(cmd_name, 0) 949 + runtime = time.time() - managed.start_time if managed else 0 950 + reason = "wedged" if cap and runtime > 2 * cap else "still_running" 951 + if _supervisor_callosum: 952 + _supervisor_callosum.emit( 953 + "supervisor", 954 + "skipped", 955 + reason=reason, 956 + ref=ref, 957 + active_ref=active_ref, 958 + cmd=cmd, 959 + scheduler_name=scheduler_name, 960 + ) 961 + return 962 + _task_queue.submit(cmd, ref, day=day, scheduler_name=scheduler_name) 809 963 810 964 811 965 def _restart_service(service: str) -> bool: 812 - """Send SIGINT to a managed service to trigger graceful restart. 966 + """Terminate a managed service to trigger graceful restart. 813 967 814 968 Returns True if the service was found and running, False if not found 815 969 or already exited. ··· 822 976 ) 823 977 return False 824 978 825 - logging.info(f"Restart requested for {service}, sending SIGINT...") 979 + state = _SERVICE_STATE.setdefault(service, {}) 980 + state["restart"] = True 981 + timeout = state.get("shutdown_timeout", 15) 982 + 983 + logging.info(f"Restart requested for {service}, terminating...") 826 984 827 985 if _supervisor_callosum: 828 986 _supervisor_callosum.emit( ··· 833 991 ref=proc.ref, 834 992 ) 835 993 836 - try: 837 - proc.process.send_signal(signal.SIGINT) 838 - _restart_requests[service] = (time.time(), proc.process) 839 - except Exception as e: 840 - logging.error(f"Failed to send SIGINT to {service}: {e}") 994 + _start_termination_thread(service, proc, timeout=timeout, reason="restart") 841 995 return True 842 996 843 997 logging.warning(f"Cannot restart {service}: not found in managed processes") ··· 874 1028 return {"status": "not_found"} 875 1029 876 1030 877 - def collect_status(procs: list[ManagedProcess]) -> dict: 1031 + def collect_status(procs: list[RunnerManagedProcess]) -> dict: 878 1032 """Collect current supervisor status for broadcasting.""" 879 1033 now = time.time() 880 1034 ··· 938 1092 } 939 1093 940 1094 941 - def start_sense() -> ManagedProcess: 1095 + def start_sense() -> RunnerManagedProcess: 942 1096 """Launch sol sense with output logging.""" 943 1097 return _launch_process("sense", ["sol", "sense", "-v"], restart=True) 944 1098 ··· 1023 1177 _callosum_thread = None 1024 1178 1025 1179 1026 - def start_cortex_server() -> ManagedProcess: 1180 + def start_cortex_server() -> RunnerManagedProcess: 1027 1181 """Launch the Cortex WebSocket API server.""" 1028 1182 cmd = ["sol", "cortex", "-v"] 1029 1183 return _launch_process("cortex", cmd, restart=True) 1030 1184 1031 1185 1032 - def start_link_server() -> ManagedProcess: 1186 + def start_link_server() -> RunnerManagedProcess: 1033 1187 """Launch the link tunnel service (spl home-side endpoint).""" 1034 1188 cmd = ["sol", "link", "-v"] 1035 1189 return _launch_process("link", cmd, restart=True) ··· 1037 1191 1038 1192 def start_convey_server( 1039 1193 verbose: bool, debug: bool = False, port: int = 0 1040 - ) -> tuple[ManagedProcess, int]: 1194 + ) -> tuple[RunnerManagedProcess, int]: 1041 1195 """Launch the Convey web application with optional verbose and debug logging. 1042 1196 1043 1197 Returns: 1044 - Tuple of (ManagedProcess, resolved_port) where resolved_port is the 1198 + Tuple of (RunnerManagedProcess, resolved_port) where resolved_port is the 1045 1199 actual port being used (auto-selected if port was 0). 1046 1200 """ 1047 1201 # Resolve port 0 to an available port before launching ··· 1055 1209 return _launch_process("convey", cmd, restart=True), resolved_port 1056 1210 1057 1211 1058 - def check_runner_exits(procs: list[ManagedProcess]) -> list[ManagedProcess]: 1212 + def check_runner_exits( 1213 + procs: list[RunnerManagedProcess], 1214 + ) -> list[RunnerManagedProcess]: 1059 1215 """Return managed processes that have exited.""" 1060 1216 1061 - exited: list[ManagedProcess] = [] 1217 + exited: list[RunnerManagedProcess] = [] 1062 1218 for managed in procs: 1063 1219 if managed.process.poll() is not None: 1064 1220 exited.append(managed) 1065 1221 return exited 1066 1222 1067 1223 1068 - async def handle_runner_exits(procs: list[ManagedProcess]) -> None: 1224 + async def handle_runner_exits(procs: list[RunnerManagedProcess]) -> None: 1069 1225 """Check for and handle exited processes with restart policy.""" 1070 1226 exited = check_runner_exits(procs) 1071 1227 if not exited: ··· 1083 1239 logging.error(msg) 1084 1240 1085 1241 for managed in exited: 1086 - # Clear any pending restart request for this service 1087 - _restart_requests.pop(managed.name, None) 1088 - 1089 1242 returncode = managed.process.returncode 1090 1243 is_tempfail = returncode == EXIT_TEMPFAIL 1091 1244 logging.info("%s exited with code %s", managed.name, returncode) ··· 1110 1263 managed.cleanup() 1111 1264 1112 1265 # Handle restart if needed 1113 - if managed.restart and not shutdown_requested: 1266 + restart = _SERVICE_STATE.get(managed.name, {}).get("restart", False) 1267 + if restart and not shutdown_requested: 1114 1268 # Tempfail: use fixed longer delay, don't burn through backoff 1115 1269 if is_tempfail: 1116 1270 delay = TEMPFAIL_DELAY ··· 1130 1284 continue 1131 1285 logging.info("Restarting %s...", managed.name) 1132 1286 try: 1287 + state = _SERVICE_STATE.get(managed.name, {}) 1133 1288 new_proc = _launch_process( 1134 1289 managed.name, 1135 1290 managed.cmd, 1136 1291 restart=True, 1292 + shutdown_timeout=state.get("shutdown_timeout", 15), 1137 1293 ) 1138 1294 except Exception as exc: 1139 1295 logging.exception("Failed to restart %s: %s", managed.name, exc) ··· 1417 1573 *, 1418 1574 daily: bool = True, 1419 1575 schedule: bool = True, 1420 - procs: list[ManagedProcess] | None = None, 1576 + procs: list[RunnerManagedProcess] | None = None, 1421 1577 ) -> None: 1422 1578 """Main supervision loop. Runs at 1-second intervals for responsiveness. 1423 1579 ··· 1430 1586 while ( 1431 1587 not shutdown_requested 1432 1588 ): # pragma: no cover - loop checked via unit tests by patching 1433 - # Check for restart timeouts (enforce SIGKILL after 15s) 1434 - for service, (start_time, proc) in list(_restart_requests.items()): 1435 - if proc.poll() is not None: # Already exited 1436 - _restart_requests.pop(service, None) 1437 - elif time.time() - start_time > 15: 1438 - logging.warning( 1439 - f"{service} did not exit within 15s after SIGINT, sending SIGKILL" 1440 - ) 1441 - try: 1442 - proc.kill() 1443 - except Exception as e: 1444 - logging.error(f"Failed to kill {service}: {e}") 1445 - # Don't delete here - let handle_runner_exits clean up 1446 - 1447 1589 if _task_queue: 1448 1590 _task_queue.enforce_deadlines(time.time()) 1449 1591 ··· 1603 1745 # Written here, not at _supervisor_start, to minimize drift from psutil create_time(). 1604 1746 start_time_path.write_text(str(time.time())) 1605 1747 logging.info("Singleton lock acquired (PID %d)", os.getpid()) 1606 - orphans = _find_reparented_sol_workers() 1607 - _reap_orphan_workers(orphans) 1748 + _sweep_cgroup_at_startup() 1608 1749 1609 1750 # Set up signal handlers 1610 1751 signal.signal(signal.SIGINT, handle_shutdown) ··· 1618 1759 global _managed_procs, _supervisor_callosum, _is_remote_mode 1619 1760 global _digest_submitted_this_boot 1620 1761 global _task_queue 1621 - procs: list[ManagedProcess] = [] 1762 + procs: list[RunnerManagedProcess] = [] 1622 1763 convey_port = None 1623 1764 1624 1765 # Remote mode: run sync instead of local processing ··· 1794 1935 logging.info("Stopping all processes...") 1795 1936 print("\nShutting down gracefully (this may take a moment)...", flush=True) 1796 1937 1797 - def _stop_process(managed: ManagedProcess) -> None: 1798 - name = managed.name 1799 - logging.info("Stopping %s...", name) 1800 - print(f" Stopping {name}...", end="", flush=True) 1801 - try: 1802 - timeout = getattr(managed, "shutdown_timeout", 15) 1803 - managed.terminate(timeout=timeout) 1804 - print(" done", flush=True) 1805 - except subprocess.TimeoutExpired: 1806 - logging.warning("%s did not terminate gracefully, killing...", name) 1807 - print(" timeout, forcing kill...", flush=True) 1808 - finally: 1809 - managed.cleanup() 1938 + if _task_queue: 1939 + _task_queue.shutdown(timeout=10) 1810 1940 1811 1941 # Stop services in reverse order 1812 1942 for managed in reversed(procs): 1813 1943 _stop_process(managed) 1814 - 1815 - # Save scheduler state before disconnecting 1816 - if schedule_enabled and scheduler._state: 1817 - try: 1818 - scheduler.save_state() 1819 - except Exception as exc: 1820 - logging.warning("Failed to save scheduler state on shutdown: %s", exc) 1821 1944 1822 1945 if schedule_enabled: 1823 1946 try:
+28 -711
uv.lock
··· 1 1 version = 1 2 2 revision = 3 3 - requires-python = ">=3.10" 3 + requires-python = ">=3.11" 4 4 resolution-markers = [ 5 - "python_full_version >= '3.14' and platform_machine != 's390x' and sys_platform == 'win32'", 6 - "python_full_version >= '3.14' and platform_machine != 's390x' and sys_platform == 'emscripten'", 7 - "python_full_version >= '3.14' and platform_machine != 's390x' and sys_platform != 'emscripten' and sys_platform != 'win32'", 8 - "python_full_version == '3.13.*' and platform_machine != 's390x' and sys_platform == 'win32'", 9 - "python_full_version == '3.13.*' and platform_machine != 's390x' and sys_platform == 'emscripten'", 10 - "python_full_version == '3.13.*' and platform_machine != 's390x' and sys_platform != 'emscripten' and sys_platform != 'win32'", 11 - "python_full_version >= '3.14' and platform_machine == 's390x' and sys_platform == 'win32'", 12 - "python_full_version >= '3.14' and platform_machine == 's390x' and sys_platform == 'emscripten'", 13 - "python_full_version >= '3.14' and platform_machine == 's390x' and sys_platform != 'emscripten' and sys_platform != 'win32'", 14 - "python_full_version == '3.13.*' and platform_machine == 's390x' and sys_platform == 'win32'", 15 - "python_full_version == '3.13.*' and platform_machine == 's390x' and sys_platform == 'emscripten'", 16 - "python_full_version == '3.13.*' and platform_machine == 's390x' and sys_platform != 'emscripten' and sys_platform != 'win32'", 17 - "python_full_version == '3.12.*' and platform_machine != 's390x' and sys_platform == 'win32'", 18 - "python_full_version == '3.12.*' and platform_machine != 's390x' and sys_platform == 'emscripten'", 19 - "python_full_version == '3.12.*' and platform_machine != 's390x' and sys_platform != 'emscripten' and sys_platform != 'win32'", 20 - "python_full_version == '3.12.*' and platform_machine == 's390x' and sys_platform == 'win32'", 21 - "python_full_version == '3.12.*' and platform_machine == 's390x' and sys_platform == 'emscripten'", 22 - "python_full_version == '3.12.*' and platform_machine == 's390x' and sys_platform != 'emscripten' and sys_platform != 'win32'", 23 - "python_full_version == '3.11.*' and platform_machine != 's390x' and sys_platform == 'win32'", 24 - "python_full_version == '3.11.*' and platform_machine != 's390x' and sys_platform == 'emscripten'", 25 - "python_full_version == '3.11.*' and platform_machine != 's390x' and sys_platform != 'emscripten' and sys_platform != 'win32'", 26 - "python_full_version == '3.11.*' and platform_machine == 's390x' and sys_platform == 'win32'", 27 - "python_full_version == '3.11.*' and platform_machine == 's390x' and sys_platform == 'emscripten'", 28 - "python_full_version == '3.11.*' and platform_machine == 's390x' and sys_platform != 'emscripten' and sys_platform != 'win32'", 29 - "python_full_version < '3.11' and platform_machine != 's390x'", 30 - "python_full_version < '3.11' and platform_machine == 's390x'", 5 + "python_full_version >= '3.13'", 6 + "python_full_version < '3.13'", 31 7 ] 32 8 33 9 [[package]] ··· 72 48 version = "4.12.1" 73 49 source = { registry = "https://pypi.org/simple" } 74 50 dependencies = [ 75 - { name = "exceptiongroup", marker = "python_full_version < '3.11'" }, 76 51 { name = "idna" }, 77 52 { name = "typing-extensions", marker = "python_full_version < '3.13'" }, 78 53 ] ··· 85 60 name = "asgiref" 86 61 version = "3.11.1" 87 62 source = { registry = "https://pypi.org/simple" } 88 - dependencies = [ 89 - { name = "typing-extensions", marker = "python_full_version < '3.11'" }, 90 - ] 91 63 sdist = { url = "https://files.pythonhosted.org/packages/63/40/f03da1264ae8f7cfdbf9146542e5e7e8100a4c66ab48e791df9a03d3f6c0/asgiref-3.11.1.tar.gz", hash = "sha256:5f184dc43b7e763efe848065441eac62229c9f7b0475f41f80e207a114eda4ce", size = 38550, upload-time = "2026-02-03T13:30:14.33Z" } 92 64 wheels = [ 93 65 { url = "https://files.pythonhosted.org/packages/5c/0a/a72d10ed65068e115044937873362e6e32fab1b7dce0046aeb224682c989/asgiref-3.11.1-py3-none-any.whl", hash = "sha256:e8667a091e69529631969fd45dc268fa79b99c92c5fcdda727757e52146ec133", size = 24345, upload-time = "2026-02-03T13:30:13.039Z" }, ··· 108 80 source = { registry = "https://pypi.org/simple" } 109 81 sdist = { url = "https://files.pythonhosted.org/packages/78/cd/3a83ffbc3cc25b39721d174487fb0d51a76582f4a1703f98e46170ce83d4/av-16.1.0.tar.gz", hash = "sha256:a094b4fd87a3721dacf02794d3d2c82b8d712c85b9534437e82a8a978c175ffd", size = 4285203, upload-time = "2026-01-11T07:31:33.772Z" } 110 82 wheels = [ 111 - { url = "https://files.pythonhosted.org/packages/97/51/2217a9249409d2e88e16e3f16f7c0def9fd3e7ffc4238b2ec211f9935bdb/av-16.1.0-cp310-cp310-macosx_11_0_x86_64.whl", hash = "sha256:2395748b0c34fe3a150a1721e4f3d4487b939520991b13e7b36f8926b3b12295", size = 26942590, upload-time = "2026-01-09T20:17:58.588Z" }, 112 - { url = "https://files.pythonhosted.org/packages/bf/cd/a7070f4febc76a327c38808e01e2ff6b94531fe0b321af54ea3915165338/av-16.1.0-cp310-cp310-macosx_14_0_arm64.whl", hash = "sha256:72d7ac832710a158eeb7a93242370aa024a7646516291c562ee7f14a7ea881fd", size = 21507910, upload-time = "2026-01-09T20:18:02.309Z" }, 113 - { url = "https://files.pythonhosted.org/packages/ae/30/ec812418cd9b297f0238fe20eb0747d8a8b68d82c5f73c56fe519a274143/av-16.1.0-cp310-cp310-manylinux_2_28_aarch64.whl", hash = "sha256:6cbac833092e66b6b0ac4d81ab077970b8ca874951e9c3974d41d922aaa653ed", size = 38738309, upload-time = "2026-01-09T20:18:04.701Z" }, 114 - { url = "https://files.pythonhosted.org/packages/3a/b8/6c5795bf1f05f45c5261f8bce6154e0e5e86b158a6676650ddd77c28805e/av-16.1.0-cp310-cp310-manylinux_2_28_x86_64.whl", hash = "sha256:eb990672d97c18f99c02f31c8d5750236f770ffe354b5a52c5f4d16c5e65f619", size = 40293006, upload-time = "2026-01-09T20:18:07.238Z" }, 115 - { url = "https://files.pythonhosted.org/packages/a7/44/5e183bcb9333fc3372ee6e683be8b0c9b515a506894b2d32ff465430c074/av-16.1.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:05ad70933ac3b8ef896a820ea64b33b6cca91a5fac5259cb9ba7fa010435be15", size = 40123516, upload-time = "2026-01-09T20:18:09.955Z" }, 116 - { url = "https://files.pythonhosted.org/packages/12/1d/b5346d582a3c3d958b4d26a2cc63ce607233582d956121eb20d2bbe55c2e/av-16.1.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:d831a1062a3c47520bf99de6ec682bd1d64a40dfa958e5457bb613c5270e7ce3", size = 41463289, upload-time = "2026-01-09T20:18:12.459Z" }, 117 - { url = "https://files.pythonhosted.org/packages/fa/31/acc946c0545f72b8d0d74584cb2a0ade9b7dfe2190af3ef9aa52a2e3c0b1/av-16.1.0-cp310-cp310-win_amd64.whl", hash = "sha256:358ab910fef3c5a806c55176f2b27e5663b33c4d0a692dafeb049c6ed71f8aff", size = 31754959, upload-time = "2026-01-09T20:18:14.718Z" }, 118 83 { url = "https://files.pythonhosted.org/packages/48/d0/b71b65d1b36520dcb8291a2307d98b7fc12329a45614a303ff92ada4d723/av-16.1.0-cp311-cp311-macosx_11_0_x86_64.whl", hash = "sha256:e88ad64ee9d2b9c4c5d891f16c22ae78e725188b8926eb88187538d9dd0b232f", size = 26927747, upload-time = "2026-01-09T20:18:16.976Z" }, 119 84 { url = "https://files.pythonhosted.org/packages/2f/79/720a5a6ccdee06eafa211b945b0a450e3a0b8fc3d12922f0f3c454d870d2/av-16.1.0-cp311-cp311-macosx_14_0_arm64.whl", hash = "sha256:cb296073fa6935724de72593800ba86ae49ed48af03960a4aee34f8a611f442b", size = 21492232, upload-time = "2026-01-09T20:18:19.266Z" }, 120 85 { url = "https://files.pythonhosted.org/packages/8e/4f/a1ba8d922f2f6d1a3d52419463ef26dd6c4d43ee364164a71b424b5ae204/av-16.1.0-cp311-cp311-manylinux_2_28_aarch64.whl", hash = "sha256:720edd4d25aa73723c1532bb0597806d7b9af5ee34fc02358782c358cfe2f879", size = 39291737, upload-time = "2026-01-09T20:18:21.513Z" }, ··· 169 134 ] 170 135 171 136 [[package]] 172 - name = "backports-asyncio-runner" 173 - version = "1.2.0" 174 - source = { registry = "https://pypi.org/simple" } 175 - sdist = { url = "https://files.pythonhosted.org/packages/8e/ff/70dca7d7cb1cbc0edb2c6cc0c38b65cba36cccc491eca64cabd5fe7f8670/backports_asyncio_runner-1.2.0.tar.gz", hash = "sha256:a5aa7b2b7d8f8bfcaa2b57313f70792df84e32a2a746f585213373f900b42162", size = 69893, upload-time = "2025-07-02T02:27:15.685Z" } 176 - wheels = [ 177 - { url = "https://files.pythonhosted.org/packages/a0/59/76ab57e3fe74484f48a53f8e337171b4a2349e506eabe136d7e01d059086/backports_asyncio_runner-1.2.0-py3-none-any.whl", hash = "sha256:0da0a936a8aeb554eccb426dc55af3ba63bcdc69fa1a600b5bb305413a4477b5", size = 12313, upload-time = "2025-07-02T02:27:14.263Z" }, 178 - ] 179 - 180 - [[package]] 181 137 name = "blessed" 182 138 version = "1.30.0" 183 139 source = { registry = "https://pypi.org/simple" } ··· 205 161 source = { registry = "https://pypi.org/simple" } 206 162 sdist = { url = "https://files.pythonhosted.org/packages/f7/16/c92ca344d646e71a43b8bb353f0a6490d7f6e06210f8554c8f874e454285/brotli-1.2.0.tar.gz", hash = "sha256:e310f77e41941c13340a95976fe66a8a95b01e783d430eeaf7a2f87e0a57dd0a", size = 7388632, upload-time = "2025-11-05T18:39:42.86Z" } 207 163 wheels = [ 208 - { url = "https://files.pythonhosted.org/packages/64/10/a090475284fc4a71aed40a96f32e44a7fe5bda39687353dd977720b211b6/brotli-1.2.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:3b90b767916ac44e93a8e28ce6adf8d551e43affb512f2377c732d486ac6514e", size = 863089, upload-time = "2025-11-05T18:38:01.181Z" }, 209 - { url = "https://files.pythonhosted.org/packages/03/41/17416630e46c07ac21e378c3464815dd2e120b441e641bc516ac32cc51d2/brotli-1.2.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:6be67c19e0b0c56365c6a76e393b932fb0e78b3b56b711d180dd7013cb1fd984", size = 445442, upload-time = "2025-11-05T18:38:02.434Z" }, 210 - { url = "https://files.pythonhosted.org/packages/24/31/90cc06584deb5d4fcafc0985e37741fc6b9717926a78674bbb3ce018957e/brotli-1.2.0-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:0bbd5b5ccd157ae7913750476d48099aaf507a79841c0d04a9db4415b14842de", size = 1532658, upload-time = "2025-11-05T18:38:03.588Z" }, 211 - { url = "https://files.pythonhosted.org/packages/62/17/33bf0c83bcbc96756dfd712201d87342732fad70bb3472c27e833a44a4f9/brotli-1.2.0-cp310-cp310-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:3f3c908bcc404c90c77d5a073e55271a0a498f4e0756e48127c35d91cf155947", size = 1631241, upload-time = "2025-11-05T18:38:04.582Z" }, 212 - { url = "https://files.pythonhosted.org/packages/48/10/f47854a1917b62efe29bc98ac18e5d4f71df03f629184575b862ef2e743b/brotli-1.2.0-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:1b557b29782a643420e08d75aea889462a4a8796e9a6cf5621ab05a3f7da8ef2", size = 1424307, upload-time = "2025-11-05T18:38:05.587Z" }, 213 - { url = "https://files.pythonhosted.org/packages/e4/b7/f88eb461719259c17483484ea8456925ee057897f8e64487d76e24e5e38d/brotli-1.2.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:81da1b229b1889f25adadc929aeb9dbc4e922bd18561b65b08dd9343cfccca84", size = 1488208, upload-time = "2025-11-05T18:38:06.613Z" }, 214 - { url = "https://files.pythonhosted.org/packages/26/59/41bbcb983a0c48b0b8004203e74706c6b6e99a04f3c7ca6f4f41f364db50/brotli-1.2.0-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:ff09cd8c5eec3b9d02d2408db41be150d8891c5566addce57513bf546e3d6c6d", size = 1597574, upload-time = "2025-11-05T18:38:07.838Z" }, 215 - { url = "https://files.pythonhosted.org/packages/8e/e6/8c89c3bdabbe802febb4c5c6ca224a395e97913b5df0dff11b54f23c1788/brotli-1.2.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:a1778532b978d2536e79c05dac2d8cd857f6c55cd0c95ace5b03740824e0e2f1", size = 1492109, upload-time = "2025-11-05T18:38:08.816Z" }, 216 - { url = "https://files.pythonhosted.org/packages/ed/9a/4b19d4310b2dbd545c0c33f176b0528fa68c3cd0754e34b2f2bcf56548ae/brotli-1.2.0-cp310-cp310-win32.whl", hash = "sha256:b232029d100d393ae3c603c8ffd7e3fe6f798c5e28ddca5feabb8e8fdb732997", size = 334461, upload-time = "2025-11-05T18:38:10.729Z" }, 217 - { url = "https://files.pythonhosted.org/packages/ac/39/70981d9f47705e3c2b95c0847dfa3e7a37aa3b7c6030aedc4873081ed005/brotli-1.2.0-cp310-cp310-win_amd64.whl", hash = "sha256:ef87b8ab2704da227e83a246356a2b179ef826f550f794b2c52cddb4efbd0196", size = 369035, upload-time = "2025-11-05T18:38:11.827Z" }, 218 164 { url = "https://files.pythonhosted.org/packages/7a/ef/f285668811a9e1ddb47a18cb0b437d5fc2760d537a2fe8a57875ad6f8448/brotli-1.2.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:15b33fe93cedc4caaff8a0bd1eb7e3dab1c61bb22a0bf5bdfdfd97cd7da79744", size = 863110, upload-time = "2025-11-05T18:38:12.978Z" }, 219 165 { url = "https://files.pythonhosted.org/packages/50/62/a3b77593587010c789a9d6eaa527c79e0848b7b860402cc64bc0bc28a86c/brotli-1.2.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:898be2be399c221d2671d29eed26b6b2713a02c2119168ed914e7d00ceadb56f", size = 445438, upload-time = "2025-11-05T18:38:14.208Z" }, 220 166 { url = "https://files.pythonhosted.org/packages/cd/e1/7fadd47f40ce5549dc44493877db40292277db373da5053aff181656e16e/brotli-1.2.0-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:350c8348f0e76fff0a0fd6c26755d2653863279d086d3aa2c290a6a7251135dd", size = 1534420, upload-time = "2025-11-05T18:38:15.111Z" }, ··· 300 246 ] 301 247 sdist = { url = "https://files.pythonhosted.org/packages/eb/56/b1ba7935a17738ae8453301356628e8147c79dbb825bcbc73dc7401f9846/cffi-2.0.0.tar.gz", hash = "sha256:44d1b5909021139fe36001ae048dbdde8214afa20200eda0f64c068cac5d5529", size = 523588, upload-time = "2025-09-08T23:24:04.541Z" } 302 248 wheels = [ 303 - { url = "https://files.pythonhosted.org/packages/93/d7/516d984057745a6cd96575eea814fe1edd6646ee6efd552fb7b0921dec83/cffi-2.0.0-cp310-cp310-macosx_10_13_x86_64.whl", hash = "sha256:0cf2d91ecc3fcc0625c2c530fe004f82c110405f101548512cce44322fa8ac44", size = 184283, upload-time = "2025-09-08T23:22:08.01Z" }, 304 - { url = "https://files.pythonhosted.org/packages/9e/84/ad6a0b408daa859246f57c03efd28e5dd1b33c21737c2db84cae8c237aa5/cffi-2.0.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:f73b96c41e3b2adedc34a7356e64c8eb96e03a3782b535e043a986276ce12a49", size = 180504, upload-time = "2025-09-08T23:22:10.637Z" }, 305 - { url = "https://files.pythonhosted.org/packages/50/bd/b1a6362b80628111e6653c961f987faa55262b4002fcec42308cad1db680/cffi-2.0.0-cp310-cp310-manylinux1_i686.manylinux2014_i686.manylinux_2_17_i686.manylinux_2_5_i686.whl", hash = "sha256:53f77cbe57044e88bbd5ed26ac1d0514d2acf0591dd6bb02a3ae37f76811b80c", size = 208811, upload-time = "2025-09-08T23:22:12.267Z" }, 306 - { url = "https://files.pythonhosted.org/packages/4f/27/6933a8b2562d7bd1fb595074cf99cc81fc3789f6a6c05cdabb46284a3188/cffi-2.0.0-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:3e837e369566884707ddaf85fc1744b47575005c0a229de3327f8f9a20f4efeb", size = 216402, upload-time = "2025-09-08T23:22:13.455Z" }, 307 - { url = "https://files.pythonhosted.org/packages/05/eb/b86f2a2645b62adcfff53b0dd97e8dfafb5c8aa864bd0d9a2c2049a0d551/cffi-2.0.0-cp310-cp310-manylinux2014_ppc64le.manylinux_2_17_ppc64le.whl", hash = "sha256:5eda85d6d1879e692d546a078b44251cdd08dd1cfb98dfb77b670c97cee49ea0", size = 203217, upload-time = "2025-09-08T23:22:14.596Z" }, 308 - { url = "https://files.pythonhosted.org/packages/9f/e0/6cbe77a53acf5acc7c08cc186c9928864bd7c005f9efd0d126884858a5fe/cffi-2.0.0-cp310-cp310-manylinux2014_s390x.manylinux_2_17_s390x.whl", hash = "sha256:9332088d75dc3241c702d852d4671613136d90fa6881da7d770a483fd05248b4", size = 203079, upload-time = "2025-09-08T23:22:15.769Z" }, 309 - { url = "https://files.pythonhosted.org/packages/98/29/9b366e70e243eb3d14a5cb488dfd3a0b6b2f1fb001a203f653b93ccfac88/cffi-2.0.0-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:fc7de24befaeae77ba923797c7c87834c73648a05a4bde34b3b7e5588973a453", size = 216475, upload-time = "2025-09-08T23:22:17.427Z" }, 310 - { url = "https://files.pythonhosted.org/packages/21/7a/13b24e70d2f90a322f2900c5d8e1f14fa7e2a6b3332b7309ba7b2ba51a5a/cffi-2.0.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:cf364028c016c03078a23b503f02058f1814320a56ad535686f90565636a9495", size = 218829, upload-time = "2025-09-08T23:22:19.069Z" }, 311 - { url = "https://files.pythonhosted.org/packages/60/99/c9dc110974c59cc981b1f5b66e1d8af8af764e00f0293266824d9c4254bc/cffi-2.0.0-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:e11e82b744887154b182fd3e7e8512418446501191994dbf9c9fc1f32cc8efd5", size = 211211, upload-time = "2025-09-08T23:22:20.588Z" }, 312 - { url = "https://files.pythonhosted.org/packages/49/72/ff2d12dbf21aca1b32a40ed792ee6b40f6dc3a9cf1644bd7ef6e95e0ac5e/cffi-2.0.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:8ea985900c5c95ce9db1745f7933eeef5d314f0565b27625d9a10ec9881e1bfb", size = 218036, upload-time = "2025-09-08T23:22:22.143Z" }, 313 - { url = "https://files.pythonhosted.org/packages/e2/cc/027d7fb82e58c48ea717149b03bcadcbdc293553edb283af792bd4bcbb3f/cffi-2.0.0-cp310-cp310-win32.whl", hash = "sha256:1f72fb8906754ac8a2cc3f9f5aaa298070652a0ffae577e0ea9bd480dc3c931a", size = 172184, upload-time = "2025-09-08T23:22:23.328Z" }, 314 - { url = "https://files.pythonhosted.org/packages/33/fa/072dd15ae27fbb4e06b437eb6e944e75b068deb09e2a2826039e49ee2045/cffi-2.0.0-cp310-cp310-win_amd64.whl", hash = "sha256:b18a3ed7d5b3bd8d9ef7a8cb226502c6bf8308df1525e1cc676c3680e7176739", size = 182790, upload-time = "2025-09-08T23:22:24.752Z" }, 315 249 { url = "https://files.pythonhosted.org/packages/12/4a/3dfd5f7850cbf0d06dc84ba9aa00db766b52ca38d8b86e3a38314d52498c/cffi-2.0.0-cp311-cp311-macosx_10_13_x86_64.whl", hash = "sha256:b4c854ef3adc177950a8dfc81a86f5115d2abd545751a304c5bcf2c2c7283cfe", size = 184344, upload-time = "2025-09-08T23:22:26.456Z" }, 316 250 { url = "https://files.pythonhosted.org/packages/4f/8b/f0e4c441227ba756aafbe78f117485b25bb26b1c059d01f137fa6d14896b/cffi-2.0.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:2de9a304e27f7596cd03d16f1b7c72219bd944e99cc52b84d0145aefb07cbd3c", size = 180560, upload-time = "2025-09-08T23:22:28.197Z" }, 317 251 { url = "https://files.pythonhosted.org/packages/b1/b7/1200d354378ef52ec227395d95c2576330fd22a869f7a70e88e1447eb234/cffi-2.0.0-cp311-cp311-manylinux1_i686.manylinux2014_i686.manylinux_2_17_i686.manylinux_2_5_i686.whl", hash = "sha256:baf5215e0ab74c16e2dd324e8ec067ef59e41125d3eade2b863d294fd5035c92", size = 209613, upload-time = "2025-09-08T23:22:29.475Z" }, ··· 379 313 source = { registry = "https://pypi.org/simple" } 380 314 sdist = { url = "https://files.pythonhosted.org/packages/13/69/33ddede1939fdd074bce5434295f38fae7136463422fe4fd3e0e89b98062/charset_normalizer-3.4.4.tar.gz", hash = "sha256:94537985111c35f28720e43603b8e7b43a6ecfb2ce1d3058bbe955b73404e21a", size = 129418, upload-time = "2025-10-14T04:42:32.879Z" } 381 315 wheels = [ 382 - { url = "https://files.pythonhosted.org/packages/1f/b8/6d51fc1d52cbd52cd4ccedd5b5b2f0f6a11bbf6765c782298b0f3e808541/charset_normalizer-3.4.4-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:e824f1492727fa856dd6eda4f7cee25f8518a12f3c4a56a74e8095695089cf6d", size = 209709, upload-time = "2025-10-14T04:40:11.385Z" }, 383 - { url = "https://files.pythonhosted.org/packages/5c/af/1f9d7f7faafe2ddfb6f72a2e07a548a629c61ad510fe60f9630309908fef/charset_normalizer-3.4.4-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:4bd5d4137d500351a30687c2d3971758aac9a19208fc110ccb9d7188fbe709e8", size = 148814, upload-time = "2025-10-14T04:40:13.135Z" }, 384 - { url = "https://files.pythonhosted.org/packages/79/3d/f2e3ac2bbc056ca0c204298ea4e3d9db9b4afe437812638759db2c976b5f/charset_normalizer-3.4.4-cp310-cp310-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:027f6de494925c0ab2a55eab46ae5129951638a49a34d87f4c3eda90f696b4ad", size = 144467, upload-time = "2025-10-14T04:40:14.728Z" }, 385 - { url = "https://files.pythonhosted.org/packages/ec/85/1bf997003815e60d57de7bd972c57dc6950446a3e4ccac43bc3070721856/charset_normalizer-3.4.4-cp310-cp310-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:f820802628d2694cb7e56db99213f930856014862f3fd943d290ea8438d07ca8", size = 162280, upload-time = "2025-10-14T04:40:16.14Z" }, 386 - { url = "https://files.pythonhosted.org/packages/3e/8e/6aa1952f56b192f54921c436b87f2aaf7c7a7c3d0d1a765547d64fd83c13/charset_normalizer-3.4.4-cp310-cp310-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:798d75d81754988d2565bff1b97ba5a44411867c0cf32b77a7e8f8d84796b10d", size = 159454, upload-time = "2025-10-14T04:40:17.567Z" }, 387 - { url = "https://files.pythonhosted.org/packages/36/3b/60cbd1f8e93aa25d1c669c649b7a655b0b5fb4c571858910ea9332678558/charset_normalizer-3.4.4-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:9d1bb833febdff5c8927f922386db610b49db6e0d4f4ee29601d71e7c2694313", size = 153609, upload-time = "2025-10-14T04:40:19.08Z" }, 388 - { url = "https://files.pythonhosted.org/packages/64/91/6a13396948b8fd3c4b4fd5bc74d045f5637d78c9675585e8e9fbe5636554/charset_normalizer-3.4.4-cp310-cp310-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:9cd98cdc06614a2f768d2b7286d66805f94c48cde050acdbbb7db2600ab3197e", size = 151849, upload-time = "2025-10-14T04:40:20.607Z" }, 389 - { url = "https://files.pythonhosted.org/packages/b7/7a/59482e28b9981d105691e968c544cc0df3b7d6133152fb3dcdc8f135da7a/charset_normalizer-3.4.4-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:077fbb858e903c73f6c9db43374fd213b0b6a778106bc7032446a8e8b5b38b93", size = 151586, upload-time = "2025-10-14T04:40:21.719Z" }, 390 - { url = "https://files.pythonhosted.org/packages/92/59/f64ef6a1c4bdd2baf892b04cd78792ed8684fbc48d4c2afe467d96b4df57/charset_normalizer-3.4.4-cp310-cp310-musllinux_1_2_armv7l.whl", hash = "sha256:244bfb999c71b35de57821b8ea746b24e863398194a4014e4c76adc2bbdfeff0", size = 145290, upload-time = "2025-10-14T04:40:23.069Z" }, 391 - { url = "https://files.pythonhosted.org/packages/6b/63/3bf9f279ddfa641ffa1962b0db6a57a9c294361cc2f5fcac997049a00e9c/charset_normalizer-3.4.4-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:64b55f9dce520635f018f907ff1b0df1fdc31f2795a922fb49dd14fbcdf48c84", size = 163663, upload-time = "2025-10-14T04:40:24.17Z" }, 392 - { url = "https://files.pythonhosted.org/packages/ed/09/c9e38fc8fa9e0849b172b581fd9803bdf6e694041127933934184e19f8c3/charset_normalizer-3.4.4-cp310-cp310-musllinux_1_2_riscv64.whl", hash = "sha256:faa3a41b2b66b6e50f84ae4a68c64fcd0c44355741c6374813a800cd6695db9e", size = 151964, upload-time = "2025-10-14T04:40:25.368Z" }, 393 - { url = "https://files.pythonhosted.org/packages/d2/d1/d28b747e512d0da79d8b6a1ac18b7ab2ecfd81b2944c4c710e166d8dd09c/charset_normalizer-3.4.4-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:6515f3182dbe4ea06ced2d9e8666d97b46ef4c75e326b79bb624110f122551db", size = 161064, upload-time = "2025-10-14T04:40:26.806Z" }, 394 - { url = "https://files.pythonhosted.org/packages/bb/9a/31d62b611d901c3b9e5500c36aab0ff5eb442043fb3a1c254200d3d397d9/charset_normalizer-3.4.4-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:cc00f04ed596e9dc0da42ed17ac5e596c6ccba999ba6bd92b0e0aef2f170f2d6", size = 155015, upload-time = "2025-10-14T04:40:28.284Z" }, 395 - { url = "https://files.pythonhosted.org/packages/1f/f3/107e008fa2bff0c8b9319584174418e5e5285fef32f79d8ee6a430d0039c/charset_normalizer-3.4.4-cp310-cp310-win32.whl", hash = "sha256:f34be2938726fc13801220747472850852fe6b1ea75869a048d6f896838c896f", size = 99792, upload-time = "2025-10-14T04:40:29.613Z" }, 396 - { url = "https://files.pythonhosted.org/packages/eb/66/e396e8a408843337d7315bab30dbf106c38966f1819f123257f5520f8a96/charset_normalizer-3.4.4-cp310-cp310-win_amd64.whl", hash = "sha256:a61900df84c667873b292c3de315a786dd8dac506704dea57bc957bd31e22c7d", size = 107198, upload-time = "2025-10-14T04:40:30.644Z" }, 397 - { url = "https://files.pythonhosted.org/packages/b5/58/01b4f815bf0312704c267f2ccb6e5d42bcc7752340cd487bc9f8c3710597/charset_normalizer-3.4.4-cp310-cp310-win_arm64.whl", hash = "sha256:cead0978fc57397645f12578bfd2d5ea9138ea0fac82b2f63f7f7c6877986a69", size = 100262, upload-time = "2025-10-14T04:40:32.108Z" }, 398 316 { url = "https://files.pythonhosted.org/packages/ed/27/c6491ff4954e58a10f69ad90aca8a1b6fe9c5d3c6f380907af3c37435b59/charset_normalizer-3.4.4-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:6e1fcf0720908f200cd21aa4e6750a48ff6ce4afe7ff5a79a90d5ed8a08296f8", size = 206988, upload-time = "2025-10-14T04:40:33.79Z" }, 399 317 { url = "https://files.pythonhosted.org/packages/94/59/2e87300fe67ab820b5428580a53cad894272dbb97f38a7a814a2a1ac1011/charset_normalizer-3.4.4-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:5f819d5fe9234f9f82d75bdfa9aef3a3d72c4d24a6e57aeaebba32a704553aa0", size = 147324, upload-time = "2025-10-14T04:40:34.961Z" }, 400 318 { url = "https://files.pythonhosted.org/packages/07/fb/0cf61dc84b2b088391830f6274cb57c82e4da8bbc2efeac8c025edb88772/charset_normalizer-3.4.4-cp311-cp311-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:a59cb51917aa591b1c4e6a43c132f0cdc3c76dbad6155df4e28ee626cc77a0a3", size = 142742, upload-time = "2025-10-14T04:40:36.105Z" }, ··· 489 407 source = { registry = "https://pypi.org/simple" } 490 408 sdist = { url = "https://files.pythonhosted.org/packages/11/43/3e4ac666cc35f231fa70c94e9f38459299de1a152813f9d2f60fc5f3ecaf/coverage-7.13.3.tar.gz", hash = "sha256:f7f6182d3dfb8802c1747eacbfe611b669455b69b7c037484bb1efbbb56711ac", size = 826832, upload-time = "2026-02-03T14:02:30.944Z" } 491 409 wheels = [ 492 - { url = "https://files.pythonhosted.org/packages/ab/07/1c8099563a8a6c389a31c2d0aa1497cee86d6248bb4b9ba5e779215db9f9/coverage-7.13.3-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:0b4f345f7265cdbdb5ec2521ffff15fa49de6d6c39abf89fc7ad68aa9e3a55f0", size = 219143, upload-time = "2026-02-03T13:59:40.459Z" }, 493 - { url = "https://files.pythonhosted.org/packages/69/39/a892d44af7aa092cab70e0cc5cdbba18eeccfe1d6930695dab1742eef9e9/coverage-7.13.3-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:96c3be8bae9d0333e403cc1a8eb078a7f928b5650bae94a18fb4820cc993fb9b", size = 219663, upload-time = "2026-02-03T13:59:41.951Z" }, 494 - { url = "https://files.pythonhosted.org/packages/9a/25/9669dcf4c2bb4c3861469e6db20e52e8c11908cf53c14ec9b12e9fd4d602/coverage-7.13.3-cp310-cp310-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:d6f4a21328ea49d38565b55599e1c02834e76583a6953e5586d65cb1efebd8f8", size = 246424, upload-time = "2026-02-03T13:59:43.418Z" }, 495 - { url = "https://files.pythonhosted.org/packages/f3/68/d9766c4e298aca62ea5d9543e1dd1e4e1439d7284815244d8b7db1840bfb/coverage-7.13.3-cp310-cp310-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:fc970575799a9d17d5c3fafd83a0f6ccf5d5117cdc9ad6fbd791e9ead82418b0", size = 248228, upload-time = "2026-02-03T13:59:44.816Z" }, 496 - { url = "https://files.pythonhosted.org/packages/f0/e2/eea6cb4a4bd443741adf008d4cccec83a1f75401df59b6559aca2bdd9710/coverage-7.13.3-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:87ff33b652b3556b05e204ae20793d1f872161b0fa5ec8a9ac76f8430e152ed6", size = 250103, upload-time = "2026-02-03T13:59:46.271Z" }, 497 - { url = "https://files.pythonhosted.org/packages/db/77/664280ecd666c2191610842177e2fab9e5dbdeef97178e2078fed46a3d2c/coverage-7.13.3-cp310-cp310-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:7df8759ee57b9f3f7b66799b7660c282f4375bef620ade1686d6a7b03699e75f", size = 247107, upload-time = "2026-02-03T13:59:48.53Z" }, 498 - { url = "https://files.pythonhosted.org/packages/2b/df/2a672eab99e0d0eba52d8a63e47dc92245eee26954d1b2d3c8f7d372151f/coverage-7.13.3-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:f45c9bcb16bee25a798ccba8a2f6a1251b19de6a0d617bb365d7d2f386c4e20e", size = 248143, upload-time = "2026-02-03T13:59:50.027Z" }, 499 - { url = "https://files.pythonhosted.org/packages/a5/dc/a104e7a87c13e57a358b8b9199a8955676e1703bb372d79722b54978ae45/coverage-7.13.3-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:318b2e4753cbf611061e01b6cc81477e1cdfeb69c36c4a14e6595e674caadb56", size = 246148, upload-time = "2026-02-03T13:59:52.025Z" }, 500 - { url = "https://files.pythonhosted.org/packages/2b/89/e113d3a58dc20b03b7e59aed1e53ebc9ca6167f961876443e002b10e3ae9/coverage-7.13.3-cp310-cp310-musllinux_1_2_riscv64.whl", hash = "sha256:24db3959de8ee394eeeca89ccb8ba25305c2da9a668dd44173394cbd5aa0777f", size = 246414, upload-time = "2026-02-03T13:59:53.859Z" }, 501 - { url = "https://files.pythonhosted.org/packages/3f/60/a3fd0a6e8d89b488396019a2268b6a1f25ab56d6d18f3be50f35d77b47dc/coverage-7.13.3-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:be14d0622125edef21b3a4d8cd2d138c4872bf6e38adc90fd92385e3312f406a", size = 247023, upload-time = "2026-02-03T13:59:55.454Z" }, 502 - { url = "https://files.pythonhosted.org/packages/19/fa/de4840bb939dbb22ba0648a6d8069fa91c9cf3b3fca8b0d1df461e885b3d/coverage-7.13.3-cp310-cp310-win32.whl", hash = "sha256:53be4aab8ddef18beb6188f3a3fdbf4d1af2277d098d4e618be3a8e6c88e74be", size = 221751, upload-time = "2026-02-03T13:59:57.383Z" }, 503 - { url = "https://files.pythonhosted.org/packages/de/87/233ff8b7ef62fb63f58c78623b50bef69681111e0c4d43504f422d88cda4/coverage-7.13.3-cp310-cp310-win_amd64.whl", hash = "sha256:bfeee64ad8b4aae3233abb77eb6b52b51b05fa89da9645518671b9939a78732b", size = 222686, upload-time = "2026-02-03T13:59:58.825Z" }, 504 410 { url = "https://files.pythonhosted.org/packages/ec/09/1ac74e37cf45f17eb41e11a21854f7f92a4c2d6c6098ef4a1becb0c6d8d3/coverage-7.13.3-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:5907605ee20e126eeee2abe14aae137043c2c8af2fa9b38d2ab3b7a6b8137f73", size = 219276, upload-time = "2026-02-03T14:00:00.296Z" }, 505 411 { url = "https://files.pythonhosted.org/packages/2e/cb/71908b08b21beb2c437d0d5870c4ec129c570ca1b386a8427fcdb11cf89c/coverage-7.13.3-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:a88705500988c8acad8b8fd86c2a933d3aa96bec1ddc4bc5cb256360db7bbd00", size = 219776, upload-time = "2026-02-03T14:00:02.414Z" }, 506 412 { url = "https://files.pythonhosted.org/packages/09/85/c4f3dd69232887666a2c0394d4be21c60ea934d404db068e6c96aa59cd87/coverage-7.13.3-cp311-cp311-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:7bbb5aa9016c4c29e3432e087aa29ebee3f8fda089cfbfb4e6d64bd292dcd1c2", size = 250196, upload-time = "2026-02-03T14:00:04.197Z" }, ··· 593 499 source = { registry = "https://pypi.org/simple" } 594 500 dependencies = [ 595 501 { name = "cffi", marker = "platform_python_implementation != 'PyPy'" }, 596 - { name = "typing-extensions", marker = "python_full_version < '3.11'" }, 597 502 ] 598 503 sdist = { url = "https://files.pythonhosted.org/packages/78/19/f748958276519adf6a0c1e79e7b8860b4830dda55ccdf29f2719b5fc499c/cryptography-46.0.4.tar.gz", hash = "sha256:bfd019f60f8abc2ed1b9be4ddc21cfef059c841d86d710bb69909a688cbb8f59", size = 749301, upload-time = "2026-01-28T00:24:37.379Z" } 599 504 wheels = [ ··· 665 570 version = "4.7.1" 666 571 source = { registry = "https://pypi.org/simple" } 667 572 dependencies = [ 668 - { name = "numpy", version = "2.2.6", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.11'" }, 669 - { name = "numpy", version = "2.3.5", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.11'" }, 573 + { name = "numpy" }, 670 574 { name = "pyyaml" }, 671 575 { name = "setuptools" }, 672 576 ] 673 577 wheels = [ 674 - { url = "https://files.pythonhosted.org/packages/cb/e0/b69c40c3d739b213a78d327071240590792071b4f890e34088b03b95bb1e/ctranslate2-4.7.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:9017a355dd7c6d29dc3bca6e9fc74827306c61b702c66bb1f6b939655e7de3fa", size = 1255773, upload-time = "2026-02-04T06:11:04.769Z" }, 675 - { url = "https://files.pythonhosted.org/packages/51/29/e5c2fc1253e3fb9b2c86997f36524bba182a8ed77fb4f8fe8444a5649191/ctranslate2-4.7.1-cp310-cp310-macosx_11_0_x86_64.whl", hash = "sha256:6abcd0552285e7173475836f9d133e04dfc3e42ca8e6930f65eaa4b8b13a47fa", size = 11914945, upload-time = "2026-02-04T06:11:06.853Z" }, 676 - { url = "https://files.pythonhosted.org/packages/03/25/e7fe847d3f02c84d2e9c5e8312434fbeab5af3d8916b6c8e2bdbe860d052/ctranslate2-4.7.1-cp310-cp310-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:8492cba605319e0d7f2760180957d5a2a435dfdebcef1a75d2ade740e6b9fb0b", size = 16547973, upload-time = "2026-02-04T06:11:09.021Z" }, 677 - { url = "https://files.pythonhosted.org/packages/68/75/074ed22bc340c2e26c09af6bf85859b586516e4e2d753b20189936d0dcf7/ctranslate2-4.7.1-cp310-cp310-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:688bd82482b5d057eff5bc1e727f11bb9a1277b7e4fce8ab01fd3bb70e69294b", size = 38636471, upload-time = "2026-02-04T06:11:12.146Z" }, 678 - { url = "https://files.pythonhosted.org/packages/76/b6/9baf8a565f6dcdbfbc9cfd179dd6214529838cda4e91e89b616045a670f0/ctranslate2-4.7.1-cp310-cp310-win_amd64.whl", hash = "sha256:3b39a5f4e3c87ac91976996458a64ba08a7cbf974dc0be4e6df83a9e040d4bd2", size = 18842389, upload-time = "2026-02-04T06:11:15.154Z" }, 679 578 { url = "https://files.pythonhosted.org/packages/da/25/41920ccee68e91cb6fa0fc9e8078ab2b7839f2c668f750dc123144cb7c6e/ctranslate2-4.7.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:f74200bab9996b14a57cf6f7cb27d0921ceedc4acc1e905598e3e85b4d75b1ec", size = 1256943, upload-time = "2026-02-04T06:11:17.781Z" }, 680 579 { url = "https://files.pythonhosted.org/packages/79/22/bc81fcc9f10ba4da3ffd1a9adec15cfb73cb700b3bbe69c6c8b55d333316/ctranslate2-4.7.1-cp311-cp311-macosx_11_0_x86_64.whl", hash = "sha256:59b427eb3ac999a746315b03a63942fddd351f511db82ba1a66880d4dea98e25", size = 11916445, upload-time = "2026-02-04T06:11:19.938Z" }, 681 580 { url = "https://files.pythonhosted.org/packages/0a/a7/494a66bb02c7926331cadfff51d5ce81f5abfb1e8d05d7f2459082f31b48/ctranslate2-4.7.1-cp311-cp311-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:95f0c1051c180669d2a83a44b44b518b2d1683de125f623bbc81ad5dd6f6141c", size = 16696997, upload-time = "2026-02-04T06:11:22.697Z" }, ··· 722 621 ] 723 622 724 623 [[package]] 725 - name = "exceptiongroup" 726 - version = "1.3.1" 727 - source = { registry = "https://pypi.org/simple" } 728 - dependencies = [ 729 - { name = "typing-extensions", marker = "python_full_version < '3.11'" }, 730 - ] 731 - sdist = { url = "https://files.pythonhosted.org/packages/50/79/66800aadf48771f6b62f7eb014e352e5d06856655206165d775e675a02c9/exceptiongroup-1.3.1.tar.gz", hash = "sha256:8b412432c6055b0b7d14c310000ae93352ed6754f70fa8f7c34141f91c4e3219", size = 30371, upload-time = "2025-11-21T23:01:54.787Z" } 732 - wheels = [ 733 - { url = "https://files.pythonhosted.org/packages/8a/0e/97c33bf5009bdbac74fd2beace167cab3f978feb69cc36f1ef79360d6c4e/exceptiongroup-1.3.1-py3-none-any.whl", hash = "sha256:a7a39a3bd276781e98394987d3a5701d0c4edffb633bb7a5144577f82c773598", size = 16740, upload-time = "2025-11-21T23:01:53.443Z" }, 734 - ] 735 - 736 - [[package]] 737 624 name = "faster-whisper" 738 625 version = "1.2.1" 739 626 source = { registry = "https://pypi.org/simple" } ··· 741 628 { name = "av" }, 742 629 { name = "ctranslate2" }, 743 630 { name = "huggingface-hub" }, 744 - { name = "onnxruntime", version = "1.24.3", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.11'" }, 745 - { name = "onnxruntime", version = "1.25.0", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.11'" }, 631 + { name = "onnxruntime" }, 746 632 { name = "tokenizers" }, 747 633 { name = "tqdm" }, 748 634 ] ··· 808 694 source = { registry = "https://pypi.org/simple" } 809 695 sdist = { url = "https://files.pythonhosted.org/packages/9a/08/7012b00a9a5874311b639c3920270c36ee0c445b69d9989a85e5c92ebcb0/fonttools-4.62.1.tar.gz", hash = "sha256:e54c75fd6041f1122476776880f7c3c3295ffa31962dc6ebe2543c00dca58b5d", size = 3580737, upload-time = "2026-03-13T13:54:25.52Z" } 810 696 wheels = [ 811 - { url = "https://files.pythonhosted.org/packages/5a/ff/532ed43808b469c807e8cb6b21358da3fe6fd51486b3a8c93db0bb5d957f/fonttools-4.62.1-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:ad5cca75776cd453b1b035b530e943334957ae152a36a88a320e779d61fc980c", size = 2873740, upload-time = "2026-03-13T13:52:11.822Z" }, 812 - { url = "https://files.pythonhosted.org/packages/85/e4/2318d2b430562da7227010fb2bb029d2fa54d7b46443ae8942bab224e2a0/fonttools-4.62.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:0b3ae47e8636156a9accff64c02c0924cbebad62854c4a6dbdc110cd5b4b341a", size = 2417649, upload-time = "2026-03-13T13:52:14.605Z" }, 813 - { url = "https://files.pythonhosted.org/packages/4c/28/40f15523b5188598018e7956899fed94eb7debec89e2dd70cb4a8df90492/fonttools-4.62.1-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:c9b9e288b4da2f64fd6180644221749de651703e8d0c16bd4b719533a3a7d6e3", size = 4935213, upload-time = "2026-03-13T13:52:17.399Z" }, 814 - { url = "https://files.pythonhosted.org/packages/42/09/7dbe3d7023f57d9b580cfa832109d521988112fd59dddfda3fddda8218f9/fonttools-4.62.1-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:7bca7a1c1faf235ffe25d4f2e555246b4750220b38de8261d94ebc5ce8a23c23", size = 4892374, upload-time = "2026-03-13T13:52:20.175Z" }, 815 - { url = "https://files.pythonhosted.org/packages/d1/2d/84509a2e32cb925371560ef5431365d8da2183c11d98e5b4b8b4e42426a5/fonttools-4.62.1-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:b4e0fcf265ad26e487c56cb12a42dffe7162de708762db951e1b3f755319507d", size = 4911856, upload-time = "2026-03-13T13:52:22.777Z" }, 816 - { url = "https://files.pythonhosted.org/packages/a5/80/df28131379eed93d9e6e6fccd3bf6e3d077bebbfe98cc83f21bbcd83ed02/fonttools-4.62.1-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:2d850f66830a27b0d498ee05adb13a3781637b1826982cd7e2b3789ef0cc71ae", size = 5031712, upload-time = "2026-03-13T13:52:25.14Z" }, 817 - { url = "https://files.pythonhosted.org/packages/3d/03/3c8f09aad64230cd6d921ae7a19f9603c36f70930b00459f112706f6769a/fonttools-4.62.1-cp310-cp310-win32.whl", hash = "sha256:486f32c8047ccd05652aba17e4a8819a3a9d78570eb8a0e3b4503142947880ed", size = 1507878, upload-time = "2026-03-13T13:52:28.149Z" }, 818 - { url = "https://files.pythonhosted.org/packages/dd/ec/f53f626f8f3e89f4cadd8fc08f3452c8fd182c951ad5caa35efac22b29ab/fonttools-4.62.1-cp310-cp310-win_amd64.whl", hash = "sha256:5a648bde915fba9da05ae98856987ca91ba832949a9e2888b48c47ef8b96c5a9", size = 1556766, upload-time = "2026-03-13T13:52:30.814Z" }, 819 697 { url = "https://files.pythonhosted.org/packages/88/39/23ff32561ec8d45a4d48578b4d241369d9270dc50926c017570e60893701/fonttools-4.62.1-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:40975849bac44fb0b9253d77420c6d8b523ac4dcdcefeff6e4d706838a5b80f7", size = 2871039, upload-time = "2026-03-13T13:52:33.127Z" }, 820 698 { url = "https://files.pythonhosted.org/packages/24/7f/66d3f8a9338a9b67fe6e1739f47e1cd5cee78bd3bc1206ef9b0b982289a5/fonttools-4.62.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:9dde91633f77fa576879a0c76b1d89de373cae751a98ddf0109d54e173b40f14", size = 2416346, upload-time = "2026-03-13T13:52:35.676Z" }, 821 699 { url = "https://files.pythonhosted.org/packages/aa/53/5276ceba7bff95da7793a07c5284e1da901cf00341ce5e2f3273056c0cca/fonttools-4.62.1-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:6acb4109f8bee00fec985c8c7afb02299e35e9c94b57287f3ea542f28bd0b0a7", size = 5100897, upload-time = "2026-03-13T13:52:38.102Z" }, ··· 1127 1005 source = { registry = "https://pypi.org/simple" } 1128 1006 sdist = { url = "https://files.pythonhosted.org/packages/0d/5e/4ec91646aee381d01cdb9974e30882c9cd3b8c5d1079d6b5ff4af522439a/jiter-0.13.0.tar.gz", hash = "sha256:f2839f9c2c7e2dffc1bc5929a510e14ce0a946be9365fd1219e7ef342dae14f4", size = 164847, upload-time = "2026-02-02T12:37:56.441Z" } 1129 1007 wheels = [ 1130 - { url = "https://files.pythonhosted.org/packages/d0/5a/41da76c5ea07bec1b0472b6b2fdb1b651074d504b19374d7e130e0cdfb25/jiter-0.13.0-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:2ffc63785fd6c7977defe49b9824ae6ce2b2e2b77ce539bdaf006c26da06342e", size = 311164, upload-time = "2026-02-02T12:35:17.688Z" }, 1131 - { url = "https://files.pythonhosted.org/packages/40/cb/4a1bf994a3e869f0d39d10e11efb471b76d0ad70ecbfb591427a46c880c2/jiter-0.13.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:4a638816427006c1e3f0013eb66d391d7a3acda99a7b0cf091eff4497ccea33a", size = 320296, upload-time = "2026-02-02T12:35:19.828Z" }, 1132 - { url = "https://files.pythonhosted.org/packages/09/82/acd71ca9b50ecebadc3979c541cd717cce2fe2bc86236f4fa597565d8f1a/jiter-0.13.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:19928b5d1ce0ff8c1ee1b9bdef3b5bfc19e8304f1b904e436caf30bc15dc6cf5", size = 352742, upload-time = "2026-02-02T12:35:21.258Z" }, 1133 - { url = "https://files.pythonhosted.org/packages/71/03/d1fc996f3aecfd42eb70922edecfb6dd26421c874503e241153ad41df94f/jiter-0.13.0-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:309549b778b949d731a2f0e1594a3f805716be704a73bf3ad9a807eed5eb5721", size = 363145, upload-time = "2026-02-02T12:35:24.653Z" }, 1134 - { url = "https://files.pythonhosted.org/packages/f1/61/a30492366378cc7a93088858f8991acd7d959759fe6138c12a4644e58e81/jiter-0.13.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:bcdabaea26cb04e25df3103ce47f97466627999260290349a88c8136ecae0060", size = 487683, upload-time = "2026-02-02T12:35:26.162Z" }, 1135 - { url = "https://files.pythonhosted.org/packages/20/4e/4223cffa9dbbbc96ed821c5aeb6bca510848c72c02086d1ed3f1da3d58a7/jiter-0.13.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a3a377af27b236abbf665a69b2bdd680e3b5a0bd2af825cd3b81245279a7606c", size = 373579, upload-time = "2026-02-02T12:35:27.582Z" }, 1136 - { url = "https://files.pythonhosted.org/packages/fe/c9/b0489a01329ab07a83812d9ebcffe7820a38163c6d9e7da644f926ff877c/jiter-0.13.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fe49d3ff6db74321f144dff9addd4a5874d3105ac5ba7c5b77fac099cfae31ae", size = 362904, upload-time = "2026-02-02T12:35:28.925Z" }, 1137 - { url = "https://files.pythonhosted.org/packages/05/af/53e561352a44afcba9a9bc67ee1d320b05a370aed8df54eafe714c4e454d/jiter-0.13.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:2113c17c9a67071b0f820733c0893ed1d467b5fcf4414068169e5c2cabddb1e2", size = 392380, upload-time = "2026-02-02T12:35:30.385Z" }, 1138 - { url = "https://files.pythonhosted.org/packages/76/2a/dd805c3afb8ed5b326c5ae49e725d1b1255b9754b1b77dbecdc621b20773/jiter-0.13.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:ab1185ca5c8b9491b55ebf6c1e8866b8f68258612899693e24a92c5fdb9455d5", size = 517939, upload-time = "2026-02-02T12:35:31.865Z" }, 1139 - { url = "https://files.pythonhosted.org/packages/20/2a/7b67d76f55b8fe14c937e7640389612f05f9a4145fc28ae128aaa5e62257/jiter-0.13.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:9621ca242547edc16400981ca3231e0c91c0c4c1ab8573a596cd9bb3575d5c2b", size = 551696, upload-time = "2026-02-02T12:35:33.306Z" }, 1140 - { url = "https://files.pythonhosted.org/packages/85/9c/57cdd64dac8f4c6ab8f994fe0eb04dc9fd1db102856a4458fcf8a99dfa62/jiter-0.13.0-cp310-cp310-win32.whl", hash = "sha256:a7637d92b1c9d7a771e8c56f445c7f84396d48f2e756e5978840ecba2fac0894", size = 204592, upload-time = "2026-02-02T12:35:34.58Z" }, 1141 - { url = "https://files.pythonhosted.org/packages/a7/38/f4f3ea5788b8a5bae7510a678cdc747eda0c45ffe534f9878ff37e7cf3b3/jiter-0.13.0-cp310-cp310-win_amd64.whl", hash = "sha256:c1b609e5cbd2f52bb74fb721515745b407df26d7b800458bd97cb3b972c29e7d", size = 206016, upload-time = "2026-02-02T12:35:36.435Z" }, 1142 1008 { url = "https://files.pythonhosted.org/packages/71/29/499f8c9eaa8a16751b1c0e45e6f5f1761d180da873d417996cc7bddc8eef/jiter-0.13.0-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:ea026e70a9a28ebbdddcbcf0f1323128a8db66898a06eaad3a4e62d2f554d096", size = 311157, upload-time = "2026-02-02T12:35:37.758Z" }, 1143 1009 { url = "https://files.pythonhosted.org/packages/50/f6/566364c777d2ab450b92100bea11333c64c38d32caf8dc378b48e5b20c46/jiter-0.13.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:66aa3e663840152d18cc8ff1e4faad3dd181373491b9cfdc6004b92198d67911", size = 319729, upload-time = "2026-02-02T12:35:39.246Z" }, 1144 1010 { url = "https://files.pythonhosted.org/packages/73/dd/560f13ec5e4f116d8ad2658781646cca91b617ae3b8758d4a5076b278f70/jiter-0.13.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c3524798e70655ff19aec58c7d05adb1f074fecff62da857ea9be2b908b6d701", size = 354766, upload-time = "2026-02-02T12:35:40.662Z" }, ··· 1260 1126 source = { registry = "https://pypi.org/simple" } 1261 1127 sdist = { url = "https://files.pythonhosted.org/packages/3a/2c/84076b352107ce12d56f28c313f1aca1be332d953dd96aec7b84976e6d53/kaldi-native-fbank-1.22.3.tar.gz", hash = "sha256:387bf87225c6b83c93ae652eeaef1b4d531994b6e398e7a77189de340674f9af", size = 71013, upload-time = "2025-10-09T02:31:21.487Z" } 1262 1128 wheels = [ 1263 - { url = "https://files.pythonhosted.org/packages/dc/c1/ff7a8c85a100dbef0df6473579cb78b1527f01d34859432de3f38d5a38d1/kaldi_native_fbank-1.22.3-cp310-cp310-macosx_10_15_x86_64.whl", hash = "sha256:af04cae53beb6da1e28e57e053d16118513e5fbe8d16ce0b3261f1b1b396af0a", size = 244533, upload-time = "2025-10-09T02:28:39.795Z" }, 1264 - { url = "https://files.pythonhosted.org/packages/9f/d5/be771230ba2f071ad036a9224139fa4e0ac576b8abac15209342fc63ef86/kaldi_native_fbank-1.22.3-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:947cb8fae3611244b15006bd42263fe56afe583077e7006aac4bdb0e10dc5a4f", size = 227900, upload-time = "2025-10-09T02:33:05.679Z" }, 1265 - { url = "https://files.pythonhosted.org/packages/3c/9a/2ba3bcdf8b0d78339d3bb17307f70113d32bfc5492917d254995e61fd1c0/kaldi_native_fbank-1.22.3-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:f1e6b8c587dfe4f646b3a62f4b4ee840a83f4c491fe4bdfb74ccd9937ce17cdc", size = 296954, upload-time = "2025-10-09T02:30:26.143Z" }, 1266 - { url = "https://files.pythonhosted.org/packages/2b/09/9031a517a0655e54c5bb8f243078798c19441f037b70a3f10b8aad82d073/kaldi_native_fbank-1.22.3-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:c710b62442a43720db853cbafbf57ea3f920b593128dfb8fb88e08d6a8225772", size = 320031, upload-time = "2025-10-09T02:30:45.244Z" }, 1267 - { url = "https://files.pythonhosted.org/packages/3e/14/3f0d13909fee89d3826279a129bc3261c677fb1f39db1c4f714d92918762/kaldi_native_fbank-1.22.3-cp310-cp310-win32.whl", hash = "sha256:4d3c97ee08b9d3d528ff4fe8a20aeb7484eea06b2ccb7a3b5a7c86fa3b065b44", size = 272314, upload-time = "2025-10-09T02:30:24.4Z" }, 1268 - { url = "https://files.pythonhosted.org/packages/94/dd/0be9a61d373449d9782dad3b259892720bdc90c553cf618cb45a1c6443c0/kaldi_native_fbank-1.22.3-cp310-cp310-win_amd64.whl", hash = "sha256:1eb9a3a9c87597872a48acc167de7321b4660bc3a10ed2f552c5f633015b1b61", size = 302723, upload-time = "2025-10-09T02:28:31.64Z" }, 1269 1129 { url = "https://files.pythonhosted.org/packages/9d/d0/07ab65d7c8389f56f8c772a55f8846a81c24d973abecfc0275c2c833f63e/kaldi_native_fbank-1.22.3-cp311-cp311-macosx_10_15_x86_64.whl", hash = "sha256:6b9ef5b6302ee45628a51a4484cb4f41006af02141508939c09ce36899fb3f41", size = 245879, upload-time = "2025-10-09T02:28:04.7Z" }, 1270 1130 { url = "https://files.pythonhosted.org/packages/64/2b/3132083b930fa6411f14469f36c465b7d2fba29a8a3e121d8fd6baffc8ea/kaldi_native_fbank-1.22.3-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:29452f2900e771086e9022dde17a92d191217ab3e34ca7dc361bd9be53e94fb4", size = 229180, upload-time = "2025-10-09T02:29:35.356Z" }, 1271 1131 { url = "https://files.pythonhosted.org/packages/e3/53/720ffbe8b30de203570f397866334eb4c6364c9214699010f2086de911ff/kaldi_native_fbank-1.22.3-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:d48e5dd8e897bf4509be2c6eeb4bbab728eaaef1f214ae0510c96219c4253d17", size = 299054, upload-time = "2025-10-09T02:28:42.011Z" }, ··· 1306 1166 source = { registry = "https://pypi.org/simple" } 1307 1167 sdist = { url = "https://files.pythonhosted.org/packages/e7/24/5f3646ff414285e0f7708fa4e946b9bf538345a41d1c375c439467721a5e/librt-0.7.8.tar.gz", hash = "sha256:1a4ede613941d9c3470b0368be851df6bb78ab218635512d0370b27a277a0862", size = 148323, upload-time = "2026-01-14T12:56:16.876Z" } 1308 1168 wheels = [ 1309 - { url = "https://files.pythonhosted.org/packages/44/13/57b06758a13550c5f09563893b004f98e9537ee6ec67b7df85c3571c8832/librt-0.7.8-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:b45306a1fc5f53c9330fbee134d8b3227fe5da2ab09813b892790400aa49352d", size = 56521, upload-time = "2026-01-14T12:54:40.066Z" }, 1310 - { url = "https://files.pythonhosted.org/packages/c2/24/bbea34d1452a10612fb45ac8356f95351ba40c2517e429602160a49d1fd0/librt-0.7.8-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:864c4b7083eeee250ed55135d2127b260d7eb4b5e953a9e5df09c852e327961b", size = 58456, upload-time = "2026-01-14T12:54:41.471Z" }, 1311 - { url = "https://files.pythonhosted.org/packages/04/72/a168808f92253ec3a810beb1eceebc465701197dbc7e865a1c9ceb3c22c7/librt-0.7.8-cp310-cp310-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:6938cc2de153bc927ed8d71c7d2f2ae01b4e96359126c602721340eb7ce1a92d", size = 164392, upload-time = "2026-01-14T12:54:42.843Z" }, 1312 - { url = "https://files.pythonhosted.org/packages/14/5c/4c0d406f1b02735c2e7af8ff1ff03a6577b1369b91aa934a9fa2cc42c7ce/librt-0.7.8-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:66daa6ac5de4288a5bbfbe55b4caa7bf0cd26b3269c7a476ffe8ce45f837f87d", size = 172959, upload-time = "2026-01-14T12:54:44.602Z" }, 1313 - { url = "https://files.pythonhosted.org/packages/82/5f/3e85351c523f73ad8d938989e9a58c7f59fb9c17f761b9981b43f0025ce7/librt-0.7.8-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:4864045f49dc9c974dadb942ac56a74cd0479a2aafa51ce272c490a82322ea3c", size = 186717, upload-time = "2026-01-14T12:54:45.986Z" }, 1314 - { url = "https://files.pythonhosted.org/packages/08/f8/18bfe092e402d00fe00d33aa1e01dda1bd583ca100b393b4373847eade6d/librt-0.7.8-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:a36515b1328dc5b3ffce79fe204985ca8572525452eacabee2166f44bb387b2c", size = 184585, upload-time = "2026-01-14T12:54:47.139Z" }, 1315 - { url = "https://files.pythonhosted.org/packages/4e/fc/f43972ff56fd790a9fa55028a52ccea1875100edbb856b705bd393b601e3/librt-0.7.8-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:b7e7f140c5169798f90b80d6e607ed2ba5059784968a004107c88ad61fb3641d", size = 180497, upload-time = "2026-01-14T12:54:48.946Z" }, 1316 - { url = "https://files.pythonhosted.org/packages/e1/3a/25e36030315a410d3ad0b7d0f19f5f188e88d1613d7d3fd8150523ea1093/librt-0.7.8-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:ff71447cb778a4f772ddc4ce360e6ba9c95527ed84a52096bd1bbf9fee2ec7c0", size = 200052, upload-time = "2026-01-14T12:54:50.382Z" }, 1317 - { url = "https://files.pythonhosted.org/packages/fc/b8/f3a5a1931ae2a6ad92bf6893b9ef44325b88641d58723529e2c2935e8abe/librt-0.7.8-cp310-cp310-win32.whl", hash = "sha256:047164e5f68b7a8ebdf9fae91a3c2161d3192418aadd61ddd3a86a56cbe3dc85", size = 43477, upload-time = "2026-01-14T12:54:51.815Z" }, 1318 - { url = "https://files.pythonhosted.org/packages/fe/91/c4202779366bc19f871b4ad25db10fcfa1e313c7893feb942f32668e8597/librt-0.7.8-cp310-cp310-win_amd64.whl", hash = "sha256:d6f254d096d84156a46a84861183c183d30734e52383602443292644d895047c", size = 49806, upload-time = "2026-01-14T12:54:53.149Z" }, 1319 1169 { url = "https://files.pythonhosted.org/packages/1b/a3/87ea9c1049f2c781177496ebee29430e4631f439b8553a4969c88747d5d8/librt-0.7.8-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:ff3e9c11aa260c31493d4b3197d1e28dd07768594a4f92bec4506849d736248f", size = 56507, upload-time = "2026-01-14T12:54:54.156Z" }, 1320 1170 { url = "https://files.pythonhosted.org/packages/5e/4a/23bcef149f37f771ad30203d561fcfd45b02bc54947b91f7a9ac34815747/librt-0.7.8-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:ddb52499d0b3ed4aa88746aaf6f36a08314677d5c346234c3987ddc506404eac", size = 58455, upload-time = "2026-01-14T12:54:55.978Z" }, 1321 1171 { url = "https://files.pythonhosted.org/packages/22/6e/46eb9b85c1b9761e0f42b6e6311e1cc544843ac897457062b9d5d0b21df4/librt-0.7.8-cp311-cp311-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:e9c0afebbe6ce177ae8edba0c7c4d626f2a0fc12c33bb993d163817c41a7a05c", size = 164956, upload-time = "2026-01-14T12:54:57.311Z" }, ··· 1400 1250 source = { registry = "https://pypi.org/simple" } 1401 1251 sdist = { url = "https://files.pythonhosted.org/packages/7e/99/7690b6d4034fffd95959cbe0c02de8deb3098cc577c67bb6a24fe5d7caa7/markupsafe-3.0.3.tar.gz", hash = "sha256:722695808f4b6457b320fdc131280796bdceb04ab50fe1795cd540799ebe1698", size = 80313, upload-time = "2025-09-27T18:37:40.426Z" } 1402 1252 wheels = [ 1403 - { url = "https://files.pythonhosted.org/packages/e8/4b/3541d44f3937ba468b75da9eebcae497dcf67adb65caa16760b0a6807ebb/markupsafe-3.0.3-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:2f981d352f04553a7171b8e44369f2af4055f888dfb147d55e42d29e29e74559", size = 11631, upload-time = "2025-09-27T18:36:05.558Z" }, 1404 - { url = "https://files.pythonhosted.org/packages/98/1b/fbd8eed11021cabd9226c37342fa6ca4e8a98d8188a8d9b66740494960e4/markupsafe-3.0.3-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:e1c1493fb6e50ab01d20a22826e57520f1284df32f2d8601fdd90b6304601419", size = 12057, upload-time = "2025-09-27T18:36:07.165Z" }, 1405 - { url = "https://files.pythonhosted.org/packages/40/01/e560d658dc0bb8ab762670ece35281dec7b6c1b33f5fbc09ebb57a185519/markupsafe-3.0.3-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:1ba88449deb3de88bd40044603fafffb7bc2b055d626a330323a9ed736661695", size = 22050, upload-time = "2025-09-27T18:36:08.005Z" }, 1406 - { url = "https://files.pythonhosted.org/packages/af/cd/ce6e848bbf2c32314c9b237839119c5a564a59725b53157c856e90937b7a/markupsafe-3.0.3-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:f42d0984e947b8adf7dd6dde396e720934d12c506ce84eea8476409563607591", size = 20681, upload-time = "2025-09-27T18:36:08.881Z" }, 1407 - { url = "https://files.pythonhosted.org/packages/c9/2a/b5c12c809f1c3045c4d580b035a743d12fcde53cf685dbc44660826308da/markupsafe-3.0.3-cp310-cp310-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:c0c0b3ade1c0b13b936d7970b1d37a57acde9199dc2aecc4c336773e1d86049c", size = 20705, upload-time = "2025-09-27T18:36:10.131Z" }, 1408 - { url = "https://files.pythonhosted.org/packages/cf/e3/9427a68c82728d0a88c50f890d0fc072a1484de2f3ac1ad0bfc1a7214fd5/markupsafe-3.0.3-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:0303439a41979d9e74d18ff5e2dd8c43ed6c6001fd40e5bf2e43f7bd9bbc523f", size = 21524, upload-time = "2025-09-27T18:36:11.324Z" }, 1409 - { url = "https://files.pythonhosted.org/packages/bc/36/23578f29e9e582a4d0278e009b38081dbe363c5e7165113fad546918a232/markupsafe-3.0.3-cp310-cp310-musllinux_1_2_riscv64.whl", hash = "sha256:d2ee202e79d8ed691ceebae8e0486bd9a2cd4794cec4824e1c99b6f5009502f6", size = 20282, upload-time = "2025-09-27T18:36:12.573Z" }, 1410 - { url = "https://files.pythonhosted.org/packages/56/21/dca11354e756ebd03e036bd8ad58d6d7168c80ce1fe5e75218e4945cbab7/markupsafe-3.0.3-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:177b5253b2834fe3678cb4a5f0059808258584c559193998be2601324fdeafb1", size = 20745, upload-time = "2025-09-27T18:36:13.504Z" }, 1411 - { url = "https://files.pythonhosted.org/packages/87/99/faba9369a7ad6e4d10b6a5fbf71fa2a188fe4a593b15f0963b73859a1bbd/markupsafe-3.0.3-cp310-cp310-win32.whl", hash = "sha256:2a15a08b17dd94c53a1da0438822d70ebcd13f8c3a95abe3a9ef9f11a94830aa", size = 14571, upload-time = "2025-09-27T18:36:14.779Z" }, 1412 - { url = "https://files.pythonhosted.org/packages/d6/25/55dc3ab959917602c96985cb1253efaa4ff42f71194bddeb61eb7278b8be/markupsafe-3.0.3-cp310-cp310-win_amd64.whl", hash = "sha256:c4ffb7ebf07cfe8931028e3e4c85f0357459a3f9f9490886198848f4fa002ec8", size = 15056, upload-time = "2025-09-27T18:36:16.125Z" }, 1413 - { url = "https://files.pythonhosted.org/packages/d0/9e/0a02226640c255d1da0b8d12e24ac2aa6734da68bff14c05dd53b94a0fc3/markupsafe-3.0.3-cp310-cp310-win_arm64.whl", hash = "sha256:e2103a929dfa2fcaf9bb4e7c091983a49c9ac3b19c9061b6d5427dd7d14d81a1", size = 13932, upload-time = "2025-09-27T18:36:17.311Z" }, 1414 1253 { url = "https://files.pythonhosted.org/packages/08/db/fefacb2136439fc8dd20e797950e749aa1f4997ed584c62cfb8ef7c2be0e/markupsafe-3.0.3-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:1cc7ea17a6824959616c525620e387f6dd30fec8cb44f649e31712db02123dad", size = 11631, upload-time = "2025-09-27T18:36:18.185Z" }, 1415 1254 { url = "https://files.pythonhosted.org/packages/e1/2e/5898933336b61975ce9dc04decbc0a7f2fee78c30353c5efba7f2d6ff27a/markupsafe-3.0.3-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:4bd4cd07944443f5a265608cc6aab442e4f74dff8088b0dfc8238647b8f6ae9a", size = 12058, upload-time = "2025-09-27T18:36:19.444Z" }, 1416 1255 { url = "https://files.pythonhosted.org/packages/1d/09/adf2df3699d87d1d8184038df46a9c80d78c0148492323f4693df54e17bb/markupsafe-3.0.3-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:6b5420a1d9450023228968e7e6a9ce57f65d148ab56d2313fcd589eee96a7a50", size = 24287, upload-time = "2025-09-27T18:36:20.768Z" }, ··· 1492 1331 name = "mistune" 1493 1332 version = "3.2.0" 1494 1333 source = { registry = "https://pypi.org/simple" } 1495 - dependencies = [ 1496 - { name = "typing-extensions", marker = "python_full_version < '3.11'" }, 1497 - ] 1498 1334 sdist = { url = "https://files.pythonhosted.org/packages/9d/55/d01f0c4b45ade6536c51170b9043db8b2ec6ddf4a35c7ea3f5f559ac935b/mistune-3.2.0.tar.gz", hash = "sha256:708487c8a8cdd99c9d90eb3ed4c3ed961246ff78ac82f03418f5183ab70e398a", size = 95467, upload-time = "2025-12-23T11:36:34.994Z" } 1499 1335 wheels = [ 1500 1336 { url = "https://files.pythonhosted.org/packages/9b/f7/4a5e785ec9fbd65146a27b6b70b6cdc161a66f2024e4b04ac06a67f5578b/mistune-3.2.0-py3-none-any.whl", hash = "sha256:febdc629a3c78616b94393c6580551e0e34cc289987ec6c35ed3f4be42d0eee1", size = 53598, upload-time = "2025-12-23T11:36:33.211Z" }, 1501 1337 ] 1502 1338 1503 1339 [[package]] 1504 - name = "mpmath" 1505 - version = "1.3.0" 1506 - source = { registry = "https://pypi.org/simple" } 1507 - sdist = { url = "https://files.pythonhosted.org/packages/e0/47/dd32fa426cc72114383ac549964eecb20ecfd886d1e5ccf5340b55b02f57/mpmath-1.3.0.tar.gz", hash = "sha256:7a28eb2a9774d00c7bc92411c19a89209d5da7c4c9a9e227be8330a23a25b91f", size = 508106, upload-time = "2023-03-07T16:47:11.061Z" } 1508 - wheels = [ 1509 - { url = "https://files.pythonhosted.org/packages/43/e3/7d92a15f894aa0c9c4b49b8ee9ac9850d6e63b03c9c32c0367a13ae62209/mpmath-1.3.0-py3-none-any.whl", hash = "sha256:a0b2b9fe80bbcd81a6647ff13108738cfb482d481d826cc0e02f5b35e5c88d2c", size = 536198, upload-time = "2023-03-07T16:47:09.197Z" }, 1510 - ] 1511 - 1512 - [[package]] 1513 1340 name = "mypy" 1514 1341 version = "1.19.1" 1515 1342 source = { registry = "https://pypi.org/simple" } ··· 1517 1344 { name = "librt", marker = "platform_python_implementation != 'PyPy'" }, 1518 1345 { name = "mypy-extensions" }, 1519 1346 { name = "pathspec" }, 1520 - { name = "tomli", marker = "python_full_version < '3.11'" }, 1521 1347 { name = "typing-extensions" }, 1522 1348 ] 1523 1349 sdist = { url = "https://files.pythonhosted.org/packages/f5/db/4efed9504bc01309ab9c2da7e352cc223569f05478012b5d9ece38fd44d2/mypy-1.19.1.tar.gz", hash = "sha256:19d88bb05303fe63f71dd2c6270daca27cb9401c4ca8255fe50d1d920e0eb9ba", size = 3582404, upload-time = "2025-12-15T05:03:48.42Z" } 1524 1350 wheels = [ 1525 - { url = "https://files.pythonhosted.org/packages/2f/63/e499890d8e39b1ff2df4c0c6ce5d371b6844ee22b8250687a99fd2f657a8/mypy-1.19.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:5f05aa3d375b385734388e844bc01733bd33c644ab48e9684faa54e5389775ec", size = 13101333, upload-time = "2025-12-15T05:03:03.28Z" }, 1526 - { url = "https://files.pythonhosted.org/packages/72/4b/095626fc136fba96effc4fd4a82b41d688ab92124f8c4f7564bffe5cf1b0/mypy-1.19.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:022ea7279374af1a5d78dfcab853fe6a536eebfda4b59deab53cd21f6cd9f00b", size = 12164102, upload-time = "2025-12-15T05:02:33.611Z" }, 1527 - { url = "https://files.pythonhosted.org/packages/0c/5b/952928dd081bf88a83a5ccd49aaecfcd18fd0d2710c7ff07b8fb6f7032b9/mypy-1.19.1-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:ee4c11e460685c3e0c64a4c5de82ae143622410950d6be863303a1c4ba0e36d6", size = 12765799, upload-time = "2025-12-15T05:03:28.44Z" }, 1528 - { url = "https://files.pythonhosted.org/packages/2a/0d/93c2e4a287f74ef11a66fb6d49c7a9f05e47b0a4399040e6719b57f500d2/mypy-1.19.1-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:de759aafbae8763283b2ee5869c7255391fbc4de3ff171f8f030b5ec48381b74", size = 13522149, upload-time = "2025-12-15T05:02:36.011Z" }, 1529 - { url = "https://files.pythonhosted.org/packages/7b/0e/33a294b56aaad2b338d203e3a1d8b453637ac36cb278b45005e0901cf148/mypy-1.19.1-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:ab43590f9cd5108f41aacf9fca31841142c786827a74ab7cc8a2eacb634e09a1", size = 13810105, upload-time = "2025-12-15T05:02:40.327Z" }, 1530 - { url = "https://files.pythonhosted.org/packages/0e/fd/3e82603a0cb66b67c5e7abababce6bf1a929ddf67bf445e652684af5c5a0/mypy-1.19.1-cp310-cp310-win_amd64.whl", hash = "sha256:2899753e2f61e571b3971747e302d5f420c3fd09650e1951e99f823bc3089dac", size = 10057200, upload-time = "2025-12-15T05:02:51.012Z" }, 1531 1351 { url = "https://files.pythonhosted.org/packages/ef/47/6b3ebabd5474d9cdc170d1342fbf9dddc1b0ec13ec90bf9004ee6f391c31/mypy-1.19.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:d8dfc6ab58ca7dda47d9237349157500468e404b17213d44fc1cb77bce532288", size = 13028539, upload-time = "2025-12-15T05:03:44.129Z" }, 1532 1352 { url = "https://files.pythonhosted.org/packages/5c/a6/ac7c7a88a3c9c54334f53a941b765e6ec6c4ebd65d3fe8cdcfbe0d0fd7db/mypy-1.19.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:e3f276d8493c3c97930e354b2595a44a21348b320d859fb4a2b9f66da9ed27ab", size = 12083163, upload-time = "2025-12-15T05:03:37.679Z" }, 1533 1353 { url = "https://files.pythonhosted.org/packages/67/af/3afa9cf880aa4a2c803798ac24f1d11ef72a0c8079689fac5cfd815e2830/mypy-1.19.1-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:2abb24cf3f17864770d18d673c85235ba52456b36a06b6afc1e07c1fdcd3d0e6", size = 12687629, upload-time = "2025-12-15T05:02:31.526Z" }, ··· 1566 1386 1567 1387 [[package]] 1568 1388 name = "numpy" 1569 - version = "2.2.6" 1570 - source = { registry = "https://pypi.org/simple" } 1571 - resolution-markers = [ 1572 - "python_full_version < '3.11' and platform_machine != 's390x'", 1573 - "python_full_version < '3.11' and platform_machine == 's390x'", 1574 - ] 1575 - sdist = { url = "https://files.pythonhosted.org/packages/76/21/7d2a95e4bba9dc13d043ee156a356c0a8f0c6309dff6b21b4d71a073b8a8/numpy-2.2.6.tar.gz", hash = "sha256:e29554e2bef54a90aa5cc07da6ce955accb83f21ab5de01a62c8478897b264fd", size = 20276440, upload-time = "2025-05-17T22:38:04.611Z" } 1576 - wheels = [ 1577 - { url = "https://files.pythonhosted.org/packages/9a/3e/ed6db5be21ce87955c0cbd3009f2803f59fa08df21b5df06862e2d8e2bdd/numpy-2.2.6-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:b412caa66f72040e6d268491a59f2c43bf03eb6c96dd8f0307829feb7fa2b6fb", size = 21165245, upload-time = "2025-05-17T21:27:58.555Z" }, 1578 - { url = "https://files.pythonhosted.org/packages/22/c2/4b9221495b2a132cc9d2eb862e21d42a009f5a60e45fc44b00118c174bff/numpy-2.2.6-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:8e41fd67c52b86603a91c1a505ebaef50b3314de0213461c7a6e99c9a3beff90", size = 14360048, upload-time = "2025-05-17T21:28:21.406Z" }, 1579 - { url = "https://files.pythonhosted.org/packages/fd/77/dc2fcfc66943c6410e2bf598062f5959372735ffda175b39906d54f02349/numpy-2.2.6-cp310-cp310-macosx_14_0_arm64.whl", hash = "sha256:37e990a01ae6ec7fe7fa1c26c55ecb672dd98b19c3d0e1d1f326fa13cb38d163", size = 5340542, upload-time = "2025-05-17T21:28:30.931Z" }, 1580 - { url = "https://files.pythonhosted.org/packages/7a/4f/1cb5fdc353a5f5cc7feb692db9b8ec2c3d6405453f982435efc52561df58/numpy-2.2.6-cp310-cp310-macosx_14_0_x86_64.whl", hash = "sha256:5a6429d4be8ca66d889b7cf70f536a397dc45ba6faeb5f8c5427935d9592e9cf", size = 6878301, upload-time = "2025-05-17T21:28:41.613Z" }, 1581 - { url = "https://files.pythonhosted.org/packages/eb/17/96a3acd228cec142fcb8723bd3cc39c2a474f7dcf0a5d16731980bcafa95/numpy-2.2.6-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:efd28d4e9cd7d7a8d39074a4d44c63eda73401580c5c76acda2ce969e0a38e83", size = 14297320, upload-time = "2025-05-17T21:29:02.78Z" }, 1582 - { url = "https://files.pythonhosted.org/packages/b4/63/3de6a34ad7ad6646ac7d2f55ebc6ad439dbbf9c4370017c50cf403fb19b5/numpy-2.2.6-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fc7b73d02efb0e18c000e9ad8b83480dfcd5dfd11065997ed4c6747470ae8915", size = 16801050, upload-time = "2025-05-17T21:29:27.675Z" }, 1583 - { url = "https://files.pythonhosted.org/packages/07/b6/89d837eddef52b3d0cec5c6ba0456c1bf1b9ef6a6672fc2b7873c3ec4e2e/numpy-2.2.6-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:74d4531beb257d2c3f4b261bfb0fc09e0f9ebb8842d82a7b4209415896adc680", size = 15807034, upload-time = "2025-05-17T21:29:51.102Z" }, 1584 - { url = "https://files.pythonhosted.org/packages/01/c8/dc6ae86e3c61cfec1f178e5c9f7858584049b6093f843bca541f94120920/numpy-2.2.6-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:8fc377d995680230e83241d8a96def29f204b5782f371c532579b4f20607a289", size = 18614185, upload-time = "2025-05-17T21:30:18.703Z" }, 1585 - { url = "https://files.pythonhosted.org/packages/5b/c5/0064b1b7e7c89137b471ccec1fd2282fceaae0ab3a9550f2568782d80357/numpy-2.2.6-cp310-cp310-win32.whl", hash = "sha256:b093dd74e50a8cba3e873868d9e93a85b78e0daf2e98c6797566ad8044e8363d", size = 6527149, upload-time = "2025-05-17T21:30:29.788Z" }, 1586 - { url = "https://files.pythonhosted.org/packages/a3/dd/4b822569d6b96c39d1215dbae0582fd99954dcbcf0c1a13c61783feaca3f/numpy-2.2.6-cp310-cp310-win_amd64.whl", hash = "sha256:f0fd6321b839904e15c46e0d257fdd101dd7f530fe03fd6359c1ea63738703f3", size = 12904620, upload-time = "2025-05-17T21:30:48.994Z" }, 1587 - { url = "https://files.pythonhosted.org/packages/da/a8/4f83e2aa666a9fbf56d6118faaaf5f1974d456b1823fda0a176eff722839/numpy-2.2.6-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:f9f1adb22318e121c5c69a09142811a201ef17ab257a1e66ca3025065b7f53ae", size = 21176963, upload-time = "2025-05-17T21:31:19.36Z" }, 1588 - { url = "https://files.pythonhosted.org/packages/b3/2b/64e1affc7972decb74c9e29e5649fac940514910960ba25cd9af4488b66c/numpy-2.2.6-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:c820a93b0255bc360f53eca31a0e676fd1101f673dda8da93454a12e23fc5f7a", size = 14406743, upload-time = "2025-05-17T21:31:41.087Z" }, 1589 - { url = "https://files.pythonhosted.org/packages/4a/9f/0121e375000b5e50ffdd8b25bf78d8e1a5aa4cca3f185d41265198c7b834/numpy-2.2.6-cp311-cp311-macosx_14_0_arm64.whl", hash = "sha256:3d70692235e759f260c3d837193090014aebdf026dfd167834bcba43e30c2a42", size = 5352616, upload-time = "2025-05-17T21:31:50.072Z" }, 1590 - { url = "https://files.pythonhosted.org/packages/31/0d/b48c405c91693635fbe2dcd7bc84a33a602add5f63286e024d3b6741411c/numpy-2.2.6-cp311-cp311-macosx_14_0_x86_64.whl", hash = "sha256:481b49095335f8eed42e39e8041327c05b0f6f4780488f61286ed3c01368d491", size = 6889579, upload-time = "2025-05-17T21:32:01.712Z" }, 1591 - { url = "https://files.pythonhosted.org/packages/52/b8/7f0554d49b565d0171eab6e99001846882000883998e7b7d9f0d98b1f934/numpy-2.2.6-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b64d8d4d17135e00c8e346e0a738deb17e754230d7e0810ac5012750bbd85a5a", size = 14312005, upload-time = "2025-05-17T21:32:23.332Z" }, 1592 - { url = "https://files.pythonhosted.org/packages/b3/dd/2238b898e51bd6d389b7389ffb20d7f4c10066d80351187ec8e303a5a475/numpy-2.2.6-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ba10f8411898fc418a521833e014a77d3ca01c15b0c6cdcce6a0d2897e6dbbdf", size = 16821570, upload-time = "2025-05-17T21:32:47.991Z" }, 1593 - { url = "https://files.pythonhosted.org/packages/83/6c/44d0325722cf644f191042bf47eedad61c1e6df2432ed65cbe28509d404e/numpy-2.2.6-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:bd48227a919f1bafbdda0583705e547892342c26fb127219d60a5c36882609d1", size = 15818548, upload-time = "2025-05-17T21:33:11.728Z" }, 1594 - { url = "https://files.pythonhosted.org/packages/ae/9d/81e8216030ce66be25279098789b665d49ff19eef08bfa8cb96d4957f422/numpy-2.2.6-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:9551a499bf125c1d4f9e250377c1ee2eddd02e01eac6644c080162c0c51778ab", size = 18620521, upload-time = "2025-05-17T21:33:39.139Z" }, 1595 - { url = "https://files.pythonhosted.org/packages/6a/fd/e19617b9530b031db51b0926eed5345ce8ddc669bb3bc0044b23e275ebe8/numpy-2.2.6-cp311-cp311-win32.whl", hash = "sha256:0678000bb9ac1475cd454c6b8c799206af8107e310843532b04d49649c717a47", size = 6525866, upload-time = "2025-05-17T21:33:50.273Z" }, 1596 - { url = "https://files.pythonhosted.org/packages/31/0a/f354fb7176b81747d870f7991dc763e157a934c717b67b58456bc63da3df/numpy-2.2.6-cp311-cp311-win_amd64.whl", hash = "sha256:e8213002e427c69c45a52bbd94163084025f533a55a59d6f9c5b820774ef3303", size = 12907455, upload-time = "2025-05-17T21:34:09.135Z" }, 1597 - { url = "https://files.pythonhosted.org/packages/82/5d/c00588b6cf18e1da539b45d3598d3557084990dcc4331960c15ee776ee41/numpy-2.2.6-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:41c5a21f4a04fa86436124d388f6ed60a9343a6f767fced1a8a71c3fbca038ff", size = 20875348, upload-time = "2025-05-17T21:34:39.648Z" }, 1598 - { url = "https://files.pythonhosted.org/packages/66/ee/560deadcdde6c2f90200450d5938f63a34b37e27ebff162810f716f6a230/numpy-2.2.6-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:de749064336d37e340f640b05f24e9e3dd678c57318c7289d222a8a2f543e90c", size = 14119362, upload-time = "2025-05-17T21:35:01.241Z" }, 1599 - { url = "https://files.pythonhosted.org/packages/3c/65/4baa99f1c53b30adf0acd9a5519078871ddde8d2339dc5a7fde80d9d87da/numpy-2.2.6-cp312-cp312-macosx_14_0_arm64.whl", hash = "sha256:894b3a42502226a1cac872f840030665f33326fc3dac8e57c607905773cdcde3", size = 5084103, upload-time = "2025-05-17T21:35:10.622Z" }, 1600 - { url = "https://files.pythonhosted.org/packages/cc/89/e5a34c071a0570cc40c9a54eb472d113eea6d002e9ae12bb3a8407fb912e/numpy-2.2.6-cp312-cp312-macosx_14_0_x86_64.whl", hash = "sha256:71594f7c51a18e728451bb50cc60a3ce4e6538822731b2933209a1f3614e9282", size = 6625382, upload-time = "2025-05-17T21:35:21.414Z" }, 1601 - { url = "https://files.pythonhosted.org/packages/f8/35/8c80729f1ff76b3921d5c9487c7ac3de9b2a103b1cd05e905b3090513510/numpy-2.2.6-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f2618db89be1b4e05f7a1a847a9c1c0abd63e63a1607d892dd54668dd92faf87", size = 14018462, upload-time = "2025-05-17T21:35:42.174Z" }, 1602 - { url = "https://files.pythonhosted.org/packages/8c/3d/1e1db36cfd41f895d266b103df00ca5b3cbe965184df824dec5c08c6b803/numpy-2.2.6-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fd83c01228a688733f1ded5201c678f0c53ecc1006ffbc404db9f7a899ac6249", size = 16527618, upload-time = "2025-05-17T21:36:06.711Z" }, 1603 - { url = "https://files.pythonhosted.org/packages/61/c6/03ed30992602c85aa3cd95b9070a514f8b3c33e31124694438d88809ae36/numpy-2.2.6-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:37c0ca431f82cd5fa716eca9506aefcabc247fb27ba69c5062a6d3ade8cf8f49", size = 15505511, upload-time = "2025-05-17T21:36:29.965Z" }, 1604 - { url = "https://files.pythonhosted.org/packages/b7/25/5761d832a81df431e260719ec45de696414266613c9ee268394dd5ad8236/numpy-2.2.6-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:fe27749d33bb772c80dcd84ae7e8df2adc920ae8297400dabec45f0dedb3f6de", size = 18313783, upload-time = "2025-05-17T21:36:56.883Z" }, 1605 - { url = "https://files.pythonhosted.org/packages/57/0a/72d5a3527c5ebffcd47bde9162c39fae1f90138c961e5296491ce778e682/numpy-2.2.6-cp312-cp312-win32.whl", hash = "sha256:4eeaae00d789f66c7a25ac5f34b71a7035bb474e679f410e5e1a94deb24cf2d4", size = 6246506, upload-time = "2025-05-17T21:37:07.368Z" }, 1606 - { url = "https://files.pythonhosted.org/packages/36/fa/8c9210162ca1b88529ab76b41ba02d433fd54fecaf6feb70ef9f124683f1/numpy-2.2.6-cp312-cp312-win_amd64.whl", hash = "sha256:c1f9540be57940698ed329904db803cf7a402f3fc200bfe599334c9bd84a40b2", size = 12614190, upload-time = "2025-05-17T21:37:26.213Z" }, 1607 - { url = "https://files.pythonhosted.org/packages/f9/5c/6657823f4f594f72b5471f1db1ab12e26e890bb2e41897522d134d2a3e81/numpy-2.2.6-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:0811bb762109d9708cca4d0b13c4f67146e3c3b7cf8d34018c722adb2d957c84", size = 20867828, upload-time = "2025-05-17T21:37:56.699Z" }, 1608 - { url = "https://files.pythonhosted.org/packages/dc/9e/14520dc3dadf3c803473bd07e9b2bd1b69bc583cb2497b47000fed2fa92f/numpy-2.2.6-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:287cc3162b6f01463ccd86be154f284d0893d2b3ed7292439ea97eafa8170e0b", size = 14143006, upload-time = "2025-05-17T21:38:18.291Z" }, 1609 - { url = "https://files.pythonhosted.org/packages/4f/06/7e96c57d90bebdce9918412087fc22ca9851cceaf5567a45c1f404480e9e/numpy-2.2.6-cp313-cp313-macosx_14_0_arm64.whl", hash = "sha256:f1372f041402e37e5e633e586f62aa53de2eac8d98cbfb822806ce4bbefcb74d", size = 5076765, upload-time = "2025-05-17T21:38:27.319Z" }, 1610 - { url = "https://files.pythonhosted.org/packages/73/ed/63d920c23b4289fdac96ddbdd6132e9427790977d5457cd132f18e76eae0/numpy-2.2.6-cp313-cp313-macosx_14_0_x86_64.whl", hash = "sha256:55a4d33fa519660d69614a9fad433be87e5252f4b03850642f88993f7b2ca566", size = 6617736, upload-time = "2025-05-17T21:38:38.141Z" }, 1611 - { url = "https://files.pythonhosted.org/packages/85/c5/e19c8f99d83fd377ec8c7e0cf627a8049746da54afc24ef0a0cb73d5dfb5/numpy-2.2.6-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f92729c95468a2f4f15e9bb94c432a9229d0d50de67304399627a943201baa2f", size = 14010719, upload-time = "2025-05-17T21:38:58.433Z" }, 1612 - { url = "https://files.pythonhosted.org/packages/19/49/4df9123aafa7b539317bf6d342cb6d227e49f7a35b99c287a6109b13dd93/numpy-2.2.6-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1bc23a79bfabc5d056d106f9befb8d50c31ced2fbc70eedb8155aec74a45798f", size = 16526072, upload-time = "2025-05-17T21:39:22.638Z" }, 1613 - { url = "https://files.pythonhosted.org/packages/b2/6c/04b5f47f4f32f7c2b0e7260442a8cbcf8168b0e1a41ff1495da42f42a14f/numpy-2.2.6-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:e3143e4451880bed956e706a3220b4e5cf6172ef05fcc397f6f36a550b1dd868", size = 15503213, upload-time = "2025-05-17T21:39:45.865Z" }, 1614 - { url = "https://files.pythonhosted.org/packages/17/0a/5cd92e352c1307640d5b6fec1b2ffb06cd0dabe7d7b8227f97933d378422/numpy-2.2.6-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:b4f13750ce79751586ae2eb824ba7e1e8dba64784086c98cdbbcc6a42112ce0d", size = 18316632, upload-time = "2025-05-17T21:40:13.331Z" }, 1615 - { url = "https://files.pythonhosted.org/packages/f0/3b/5cba2b1d88760ef86596ad0f3d484b1cbff7c115ae2429678465057c5155/numpy-2.2.6-cp313-cp313-win32.whl", hash = "sha256:5beb72339d9d4fa36522fc63802f469b13cdbe4fdab4a288f0c441b74272ebfd", size = 6244532, upload-time = "2025-05-17T21:43:46.099Z" }, 1616 - { url = "https://files.pythonhosted.org/packages/cb/3b/d58c12eafcb298d4e6d0d40216866ab15f59e55d148a5658bb3132311fcf/numpy-2.2.6-cp313-cp313-win_amd64.whl", hash = "sha256:b0544343a702fa80c95ad5d3d608ea3599dd54d4632df855e4c8d24eb6ecfa1c", size = 12610885, upload-time = "2025-05-17T21:44:05.145Z" }, 1617 - { url = "https://files.pythonhosted.org/packages/6b/9e/4bf918b818e516322db999ac25d00c75788ddfd2d2ade4fa66f1f38097e1/numpy-2.2.6-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:0bca768cd85ae743b2affdc762d617eddf3bcf8724435498a1e80132d04879e6", size = 20963467, upload-time = "2025-05-17T21:40:44Z" }, 1618 - { url = "https://files.pythonhosted.org/packages/61/66/d2de6b291507517ff2e438e13ff7b1e2cdbdb7cb40b3ed475377aece69f9/numpy-2.2.6-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:fc0c5673685c508a142ca65209b4e79ed6740a4ed6b2267dbba90f34b0b3cfda", size = 14225144, upload-time = "2025-05-17T21:41:05.695Z" }, 1619 - { url = "https://files.pythonhosted.org/packages/e4/25/480387655407ead912e28ba3a820bc69af9adf13bcbe40b299d454ec011f/numpy-2.2.6-cp313-cp313t-macosx_14_0_arm64.whl", hash = "sha256:5bd4fc3ac8926b3819797a7c0e2631eb889b4118a9898c84f585a54d475b7e40", size = 5200217, upload-time = "2025-05-17T21:41:15.903Z" }, 1620 - { url = "https://files.pythonhosted.org/packages/aa/4a/6e313b5108f53dcbf3aca0c0f3e9c92f4c10ce57a0a721851f9785872895/numpy-2.2.6-cp313-cp313t-macosx_14_0_x86_64.whl", hash = "sha256:fee4236c876c4e8369388054d02d0e9bb84821feb1a64dd59e137e6511a551f8", size = 6712014, upload-time = "2025-05-17T21:41:27.321Z" }, 1621 - { url = "https://files.pythonhosted.org/packages/b7/30/172c2d5c4be71fdf476e9de553443cf8e25feddbe185e0bd88b096915bcc/numpy-2.2.6-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e1dda9c7e08dc141e0247a5b8f49cf05984955246a327d4c48bda16821947b2f", size = 14077935, upload-time = "2025-05-17T21:41:49.738Z" }, 1622 - { url = "https://files.pythonhosted.org/packages/12/fb/9e743f8d4e4d3c710902cf87af3512082ae3d43b945d5d16563f26ec251d/numpy-2.2.6-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f447e6acb680fd307f40d3da4852208af94afdfab89cf850986c3ca00562f4fa", size = 16600122, upload-time = "2025-05-17T21:42:14.046Z" }, 1623 - { url = "https://files.pythonhosted.org/packages/12/75/ee20da0e58d3a66f204f38916757e01e33a9737d0b22373b3eb5a27358f9/numpy-2.2.6-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:389d771b1623ec92636b0786bc4ae56abafad4a4c513d36a55dce14bd9ce8571", size = 15586143, upload-time = "2025-05-17T21:42:37.464Z" }, 1624 - { url = "https://files.pythonhosted.org/packages/76/95/bef5b37f29fc5e739947e9ce5179ad402875633308504a52d188302319c8/numpy-2.2.6-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:8e9ace4a37db23421249ed236fdcdd457d671e25146786dfc96835cd951aa7c1", size = 18385260, upload-time = "2025-05-17T21:43:05.189Z" }, 1625 - { url = "https://files.pythonhosted.org/packages/09/04/f2f83279d287407cf36a7a8053a5abe7be3622a4363337338f2585e4afda/numpy-2.2.6-cp313-cp313t-win32.whl", hash = "sha256:038613e9fb8c72b0a41f025a7e4c3f0b7a1b5d768ece4796b674c8f3fe13efff", size = 6377225, upload-time = "2025-05-17T21:43:16.254Z" }, 1626 - { url = "https://files.pythonhosted.org/packages/67/0e/35082d13c09c02c011cf21570543d202ad929d961c02a147493cb0c2bdf5/numpy-2.2.6-cp313-cp313t-win_amd64.whl", hash = "sha256:6031dd6dfecc0cf9f668681a37648373bddd6421fff6c66ec1624eed0180ee06", size = 12771374, upload-time = "2025-05-17T21:43:35.479Z" }, 1627 - { url = "https://files.pythonhosted.org/packages/9e/3b/d94a75f4dbf1ef5d321523ecac21ef23a3cd2ac8b78ae2aac40873590229/numpy-2.2.6-pp310-pypy310_pp73-macosx_10_15_x86_64.whl", hash = "sha256:0b605b275d7bd0c640cad4e5d30fa701a8d59302e127e5f79138ad62762c3e3d", size = 21040391, upload-time = "2025-05-17T21:44:35.948Z" }, 1628 - { url = "https://files.pythonhosted.org/packages/17/f4/09b2fa1b58f0fb4f7c7963a1649c64c4d315752240377ed74d9cd878f7b5/numpy-2.2.6-pp310-pypy310_pp73-macosx_14_0_x86_64.whl", hash = "sha256:7befc596a7dc9da8a337f79802ee8adb30a552a94f792b9c9d18c840055907db", size = 6786754, upload-time = "2025-05-17T21:44:47.446Z" }, 1629 - { url = "https://files.pythonhosted.org/packages/af/30/feba75f143bdc868a1cc3f44ccfa6c4b9ec522b36458e738cd00f67b573f/numpy-2.2.6-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ce47521a4754c8f4593837384bd3424880629f718d87c5d44f8ed763edd63543", size = 16643476, upload-time = "2025-05-17T21:45:11.871Z" }, 1630 - { url = "https://files.pythonhosted.org/packages/37/48/ac2a9584402fb6c0cd5b5d1a91dcf176b15760130dd386bbafdbfe3640bf/numpy-2.2.6-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:d042d24c90c41b54fd506da306759e06e568864df8ec17ccc17e9e884634fd00", size = 12812666, upload-time = "2025-05-17T21:45:31.426Z" }, 1631 - ] 1632 - 1633 - [[package]] 1634 - name = "numpy" 1635 1389 version = "2.3.5" 1636 1390 source = { registry = "https://pypi.org/simple" } 1637 - resolution-markers = [ 1638 - "python_full_version >= '3.14' and platform_machine != 's390x' and sys_platform == 'win32'", 1639 - "python_full_version >= '3.14' and platform_machine != 's390x' and sys_platform == 'emscripten'", 1640 - "python_full_version >= '3.14' and platform_machine != 's390x' and sys_platform != 'emscripten' and sys_platform != 'win32'", 1641 - "python_full_version == '3.13.*' and platform_machine != 's390x' and sys_platform == 'win32'", 1642 - "python_full_version == '3.13.*' and platform_machine != 's390x' and sys_platform == 'emscripten'", 1643 - "python_full_version == '3.13.*' and platform_machine != 's390x' and sys_platform != 'emscripten' and sys_platform != 'win32'", 1644 - "python_full_version >= '3.14' and platform_machine == 's390x' and sys_platform == 'win32'", 1645 - "python_full_version >= '3.14' and platform_machine == 's390x' and sys_platform == 'emscripten'", 1646 - "python_full_version >= '3.14' and platform_machine == 's390x' and sys_platform != 'emscripten' and sys_platform != 'win32'", 1647 - "python_full_version == '3.13.*' and platform_machine == 's390x' and sys_platform == 'win32'", 1648 - "python_full_version == '3.13.*' and platform_machine == 's390x' and sys_platform == 'emscripten'", 1649 - "python_full_version == '3.13.*' and platform_machine == 's390x' and sys_platform != 'emscripten' and sys_platform != 'win32'", 1650 - "python_full_version == '3.12.*' and platform_machine != 's390x' and sys_platform == 'win32'", 1651 - "python_full_version == '3.12.*' and platform_machine != 's390x' and sys_platform == 'emscripten'", 1652 - "python_full_version == '3.12.*' and platform_machine != 's390x' and sys_platform != 'emscripten' and sys_platform != 'win32'", 1653 - "python_full_version == '3.12.*' and platform_machine == 's390x' and sys_platform == 'win32'", 1654 - "python_full_version == '3.12.*' and platform_machine == 's390x' and sys_platform == 'emscripten'", 1655 - "python_full_version == '3.12.*' and platform_machine == 's390x' and sys_platform != 'emscripten' and sys_platform != 'win32'", 1656 - "python_full_version == '3.11.*' and platform_machine != 's390x' and sys_platform == 'win32'", 1657 - "python_full_version == '3.11.*' and platform_machine != 's390x' and sys_platform == 'emscripten'", 1658 - "python_full_version == '3.11.*' and platform_machine != 's390x' and sys_platform != 'emscripten' and sys_platform != 'win32'", 1659 - "python_full_version == '3.11.*' and platform_machine == 's390x' and sys_platform == 'win32'", 1660 - "python_full_version == '3.11.*' and platform_machine == 's390x' and sys_platform == 'emscripten'", 1661 - "python_full_version == '3.11.*' and platform_machine == 's390x' and sys_platform != 'emscripten' and sys_platform != 'win32'", 1662 - ] 1663 1391 sdist = { url = "https://files.pythonhosted.org/packages/76/65/21b3bc86aac7b8f2862db1e808f1ea22b028e30a225a34a5ede9bf8678f2/numpy-2.3.5.tar.gz", hash = "sha256:784db1dcdab56bf0517743e746dfb0f885fc68d948aba86eeec2cba234bdf1c0", size = 20584950, upload-time = "2025-11-16T22:52:42.067Z" } 1664 1392 wheels = [ 1665 1393 { url = "https://files.pythonhosted.org/packages/43/77/84dd1d2e34d7e2792a236ba180b5e8fcc1e3e414e761ce0253f63d7f572e/numpy-2.3.5-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:de5672f4a7b200c15a4127042170a694d4df43c992948f5e1af57f0174beed10", size = 17034641, upload-time = "2025-11-16T22:49:19.336Z" }, ··· 1821 1549 version = "0.11.0" 1822 1550 source = { registry = "https://pypi.org/simple" } 1823 1551 dependencies = [ 1824 - { name = "numpy", version = "2.2.6", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.11'" }, 1825 - { name = "numpy", version = "2.3.5", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.11'" }, 1826 - { name = "typing-extensions", marker = "python_full_version < '3.11'" }, 1552 + { name = "numpy" }, 1827 1553 ] 1828 1554 sdist = { url = "https://files.pythonhosted.org/packages/78/f6/b154881761a593312f509522f99542acffa2516f7a1df6ddf5660ad4a162/onnx_asr-0.11.0.tar.gz", hash = "sha256:57ad8d9571dc17db95f0daf9ba432b9472383de320c610735850e56b5375a37d", size = 43665, upload-time = "2026-03-23T02:30:57.349Z" } 1829 1555 wheels = [ ··· 1832 1558 1833 1559 [[package]] 1834 1560 name = "onnxruntime" 1835 - version = "1.24.3" 1836 - source = { registry = "https://pypi.org/simple" } 1837 - resolution-markers = [ 1838 - "python_full_version < '3.11' and platform_machine != 's390x'", 1839 - "python_full_version < '3.11' and platform_machine == 's390x'", 1840 - ] 1841 - dependencies = [ 1842 - { name = "flatbuffers", marker = "python_full_version < '3.11'" }, 1843 - { name = "numpy", version = "2.2.6", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.11'" }, 1844 - { name = "packaging", marker = "python_full_version < '3.11'" }, 1845 - { name = "protobuf", marker = "python_full_version < '3.11'" }, 1846 - { name = "sympy", marker = "python_full_version < '3.11'" }, 1847 - ] 1848 - wheels = [ 1849 - { url = "https://files.pythonhosted.org/packages/15/41/3253db975a90c3ce1d475e2a230773a21cd7998537f0657947df6fb79861/onnxruntime-1.24.3-cp311-cp311-macosx_14_0_arm64.whl", hash = "sha256:3e6456801c66b095c5cd68e690ca25db970ea5202bd0c5b84a2c3ef7731c5a3c", size = 17332766, upload-time = "2026-03-05T17:18:59.714Z" }, 1850 - { url = "https://files.pythonhosted.org/packages/7e/c5/3af6b325f1492d691b23844d88ed26844c1164620860c5efe95c0e22782d/onnxruntime-1.24.3-cp311-cp311-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:8b2ebc54c6d8281dccff78d4b06e47d4cf07535937584ab759448390a70f4978", size = 15130330, upload-time = "2026-03-05T16:34:53.831Z" }, 1851 - { url = "https://files.pythonhosted.org/packages/03/4b/f96b46c1866a293ed23ca2cf5e5a63d413ad3a951da60dd877e3c56cbbca/onnxruntime-1.24.3-cp311-cp311-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:fb56575d7794bf0781156955610c9e651c9504c64d42ec880784b6106244882d", size = 17213247, upload-time = "2026-03-05T17:17:59.812Z" }, 1852 - { url = "https://files.pythonhosted.org/packages/36/13/27cf4d8df2578747584e8758aeb0b673b60274048510257f1f084b15e80e/onnxruntime-1.24.3-cp311-cp311-win_amd64.whl", hash = "sha256:c958222ef9eff54018332beecd32d5d94a3ab079d8821937b333811bf4da0d39", size = 12595530, upload-time = "2026-03-05T17:18:49.356Z" }, 1853 - { url = "https://files.pythonhosted.org/packages/19/8c/6d9f31e6bae72a8079be12ed8ba36c4126a571fad38ded0a1b96f60f6896/onnxruntime-1.24.3-cp311-cp311-win_arm64.whl", hash = "sha256:a8f761857ebaf58a85b9e42422d03207f1d39e6bb8fecfdbf613bac5b9710723", size = 12261715, upload-time = "2026-03-05T17:18:39.699Z" }, 1854 - { url = "https://files.pythonhosted.org/packages/d0/7f/dfdc4e52600fde4c02d59bfe98c4b057931c1114b701e175aee311a9bc11/onnxruntime-1.24.3-cp312-cp312-macosx_14_0_arm64.whl", hash = "sha256:0d244227dc5e00a9ae15a7ac1eba4c4460d7876dfecafe73fb00db9f1d914d91", size = 17342578, upload-time = "2026-03-05T17:19:02.403Z" }, 1855 - { url = "https://files.pythonhosted.org/packages/1c/dc/1f5489f7b21817d4ad352bf7a92a252bd5b438bcbaa7ad20ea50814edc79/onnxruntime-1.24.3-cp312-cp312-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:0a9847b870b6cb462652b547bc98c49e0efb67553410a082fde1918a38707452", size = 15150105, upload-time = "2026-03-05T16:34:56.897Z" }, 1856 - { url = "https://files.pythonhosted.org/packages/28/7c/fd253da53594ab8efbefdc85b3638620ab1a6aab6eb7028a513c853559ce/onnxruntime-1.24.3-cp312-cp312-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:b354afce3333f2859c7e8706d84b6c552beac39233bcd3141ce7ab77b4cabb5d", size = 17237101, upload-time = "2026-03-05T17:18:02.561Z" }, 1857 - { url = "https://files.pythonhosted.org/packages/71/5f/eaabc5699eeed6a9188c5c055ac1948ae50138697a0428d562ac970d7db5/onnxruntime-1.24.3-cp312-cp312-win_amd64.whl", hash = "sha256:44ea708c34965439170d811267c51281d3897ecfc4aa0087fa25d4a4c3eb2e4a", size = 12597638, upload-time = "2026-03-05T17:18:52.141Z" }, 1858 - { url = "https://files.pythonhosted.org/packages/cc/5c/d8066c320b90610dbeb489a483b132c3b3879b2f93f949fb5d30cfa9b119/onnxruntime-1.24.3-cp312-cp312-win_arm64.whl", hash = "sha256:48d1092b44ca2ba6f9543892e7c422c15a568481403c10440945685faf27a8d8", size = 12270943, upload-time = "2026-03-05T17:18:42.006Z" }, 1859 - { url = "https://files.pythonhosted.org/packages/51/8d/487ece554119e2991242d4de55de7019ac6e47ee8dfafa69fcf41d37f8ed/onnxruntime-1.24.3-cp313-cp313-macosx_14_0_arm64.whl", hash = "sha256:34a0ea5ff191d8420d9c1332355644148b1bf1a0d10c411af890a63a9f662aa7", size = 17342706, upload-time = "2026-03-05T16:35:10.813Z" }, 1860 - { url = "https://files.pythonhosted.org/packages/dd/25/8b444f463c1ac6106b889f6235c84f01eec001eaf689c3eff8c69cf48fae/onnxruntime-1.24.3-cp313-cp313-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:1fd2ec7bb0fabe42f55e8337cfc9b1969d0d14622711aac73d69b4bd5abb5ed7", size = 15149956, upload-time = "2026-03-05T16:34:59.264Z" }, 1861 - { url = "https://files.pythonhosted.org/packages/34/fc/c9182a3e1ab46940dd4f30e61071f59eee8804c1f641f37ce6e173633fb6/onnxruntime-1.24.3-cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:df8e70e732fe26346faaeec9147fa38bef35d232d2495d27e93dd221a2d473a9", size = 17237370, upload-time = "2026-03-05T17:18:05.258Z" }, 1862 - { url = "https://files.pythonhosted.org/packages/05/7e/3b549e1f4538514118bff98a1bcd6481dd9a17067f8c9af77151621c9a5c/onnxruntime-1.24.3-cp313-cp313-win_amd64.whl", hash = "sha256:2d3706719be6ad41d38a2250998b1d87758a20f6ea4546962e21dc79f1f1fd2b", size = 12597939, upload-time = "2026-03-05T17:18:54.772Z" }, 1863 - { url = "https://files.pythonhosted.org/packages/80/41/9696a5c4631a0caa75cc8bc4efd30938fd483694aa614898d087c3ee6d29/onnxruntime-1.24.3-cp313-cp313-win_arm64.whl", hash = "sha256:b082f3ba9519f0a1a1e754556bc7e635c7526ef81b98b3f78da4455d25f0437b", size = 12270705, upload-time = "2026-03-05T17:18:44.774Z" }, 1864 - { url = "https://files.pythonhosted.org/packages/b7/65/a26c5e59e3b210852ee04248cf8843c81fe7d40d94cf95343b66efe7eec9/onnxruntime-1.24.3-cp313-cp313t-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:72f956634bc2e4bd2e8b006bef111849bd42c42dea37bd0a4c728404fdaf4d34", size = 15161796, upload-time = "2026-03-05T16:35:02.871Z" }, 1865 - { url = "https://files.pythonhosted.org/packages/f3/25/2035b4aa2ccb5be6acf139397731ec507c5f09e199ab39d3262b22ffa1ac/onnxruntime-1.24.3-cp313-cp313t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:78d1f25eed4ab9959db70a626ed50ee24cf497e60774f59f1207ac8556399c4d", size = 17240936, upload-time = "2026-03-05T17:18:09.534Z" }, 1866 - { url = "https://files.pythonhosted.org/packages/f9/a4/b3240ea84b92a3efb83d49cc16c04a17ade1ab47a6a95c4866d15bf0ac35/onnxruntime-1.24.3-cp314-cp314-macosx_14_0_arm64.whl", hash = "sha256:a6b4bce87d96f78f0a9bf5cefab3303ae95d558c5bfea53d0bf7f9ea207880a8", size = 17344149, upload-time = "2026-03-05T16:35:13.382Z" }, 1867 - { url = "https://files.pythonhosted.org/packages/bb/4a/4b56757e51a56265e8c56764d9c36d7b435045e05e3b8a38bedfc5aedba3/onnxruntime-1.24.3-cp314-cp314-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:d48f36c87b25ab3b2b4c88826c96cf1399a5631e3c2c03cc27d6a1e5d6b18eb4", size = 15151571, upload-time = "2026-03-05T16:35:05.679Z" }, 1868 - { url = "https://files.pythonhosted.org/packages/cf/14/c6fb84980cec8f682a523fcac7c2bdd6b311e7f342c61ce48d3a9cb87fc6/onnxruntime-1.24.3-cp314-cp314-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:e104d33a409bf6e3f30f0e8198ec2aaf8d445b8395490a80f6e6ad56da98e400", size = 17238951, upload-time = "2026-03-05T17:18:12.394Z" }, 1869 - { url = "https://files.pythonhosted.org/packages/57/14/447e1400165aca8caf35dabd46540eb943c92f3065927bb4d9bcbc91e221/onnxruntime-1.24.3-cp314-cp314-win_amd64.whl", hash = "sha256:e785d73fbd17421c2513b0bb09eb25d88fa22c8c10c3f5d6060589efa5537c5b", size = 12903820, upload-time = "2026-03-05T17:18:57.123Z" }, 1870 - { url = "https://files.pythonhosted.org/packages/1d/ec/6b2fa5702e4bbba7339ca5787a9d056fc564a16079f8833cc6ba4798da1c/onnxruntime-1.24.3-cp314-cp314-win_arm64.whl", hash = "sha256:951e897a275f897a05ffbcaa615d98777882decaeb80c9216c68cdc62f849f53", size = 12594089, upload-time = "2026-03-05T17:18:47.169Z" }, 1871 - { url = "https://files.pythonhosted.org/packages/12/dc/cd06cba3ddad92ceb17b914a8e8d49836c79e38936e26bde6e368b62c1fe/onnxruntime-1.24.3-cp314-cp314t-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:4d4e70ce578aa214c74c7a7a9226bc8e229814db4a5b2d097333b81279ecde36", size = 15162789, upload-time = "2026-03-05T16:35:08.282Z" }, 1872 - { url = "https://files.pythonhosted.org/packages/a6/d6/413e98ab666c6fb9e8be7d1c6eb3bd403b0bea1b8d42db066dab98c7df07/onnxruntime-1.24.3-cp314-cp314t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:02aaf6ddfa784523b6873b4176a79d508e599efe12ab0ea1a3a6e7314408b7aa", size = 17240738, upload-time = "2026-03-05T17:18:15.203Z" }, 1873 - ] 1874 - 1875 - [[package]] 1876 - name = "onnxruntime" 1877 1561 version = "1.25.0" 1878 1562 source = { registry = "https://pypi.org/simple" } 1879 - resolution-markers = [ 1880 - "python_full_version >= '3.14' and platform_machine != 's390x' and sys_platform == 'win32'", 1881 - "python_full_version >= '3.14' and platform_machine != 's390x' and sys_platform == 'emscripten'", 1882 - "python_full_version >= '3.14' and platform_machine != 's390x' and sys_platform != 'emscripten' and sys_platform != 'win32'", 1883 - "python_full_version == '3.13.*' and platform_machine != 's390x' and sys_platform == 'win32'", 1884 - "python_full_version == '3.13.*' and platform_machine != 's390x' and sys_platform == 'emscripten'", 1885 - "python_full_version == '3.13.*' and platform_machine != 's390x' and sys_platform != 'emscripten' and sys_platform != 'win32'", 1886 - "python_full_version >= '3.14' and platform_machine == 's390x' and sys_platform == 'win32'", 1887 - "python_full_version >= '3.14' and platform_machine == 's390x' and sys_platform == 'emscripten'", 1888 - "python_full_version >= '3.14' and platform_machine == 's390x' and sys_platform != 'emscripten' and sys_platform != 'win32'", 1889 - "python_full_version == '3.13.*' and platform_machine == 's390x' and sys_platform == 'win32'", 1890 - "python_full_version == '3.13.*' and platform_machine == 's390x' and sys_platform == 'emscripten'", 1891 - "python_full_version == '3.13.*' and platform_machine == 's390x' and sys_platform != 'emscripten' and sys_platform != 'win32'", 1892 - "python_full_version == '3.12.*' and platform_machine != 's390x' and sys_platform == 'win32'", 1893 - "python_full_version == '3.12.*' and platform_machine != 's390x' and sys_platform == 'emscripten'", 1894 - "python_full_version == '3.12.*' and platform_machine != 's390x' and sys_platform != 'emscripten' and sys_platform != 'win32'", 1895 - "python_full_version == '3.12.*' and platform_machine == 's390x' and sys_platform == 'win32'", 1896 - "python_full_version == '3.12.*' and platform_machine == 's390x' and sys_platform == 'emscripten'", 1897 - "python_full_version == '3.12.*' and platform_machine == 's390x' and sys_platform != 'emscripten' and sys_platform != 'win32'", 1898 - "python_full_version == '3.11.*' and platform_machine != 's390x' and sys_platform == 'win32'", 1899 - "python_full_version == '3.11.*' and platform_machine != 's390x' and sys_platform == 'emscripten'", 1900 - "python_full_version == '3.11.*' and platform_machine != 's390x' and sys_platform != 'emscripten' and sys_platform != 'win32'", 1901 - "python_full_version == '3.11.*' and platform_machine == 's390x' and sys_platform == 'win32'", 1902 - "python_full_version == '3.11.*' and platform_machine == 's390x' and sys_platform == 'emscripten'", 1903 - "python_full_version == '3.11.*' and platform_machine == 's390x' and sys_platform != 'emscripten' and sys_platform != 'win32'", 1904 - ] 1905 1563 dependencies = [ 1906 - { name = "flatbuffers", marker = "python_full_version >= '3.11'" }, 1907 - { name = "numpy", version = "2.3.5", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.11'" }, 1908 - { name = "packaging", marker = "python_full_version >= '3.11'" }, 1909 - { name = "protobuf", marker = "python_full_version >= '3.11'" }, 1564 + { name = "flatbuffers" }, 1565 + { name = "numpy" }, 1566 + { name = "packaging" }, 1567 + { name = "protobuf" }, 1910 1568 ] 1911 1569 wheels = [ 1912 1570 { url = "https://files.pythonhosted.org/packages/66/67/edb2cb6c4a38ebf539c3529c5449d68b8031f3006d8ee36574a6d45559b2/onnxruntime-1.25.0-cp311-cp311-macosx_14_0_arm64.whl", hash = "sha256:a71baa8e0e2f3417106e3a8b2183fd5741875b998041f1a2422a1d0240f302cb", size = 17727193, upload-time = "2026-04-22T17:20:31.582Z" }, ··· 1937 1595 1938 1596 [[package]] 1939 1597 name = "onnxruntime-gpu" 1940 - version = "1.24.3" 1941 - source = { registry = "https://pypi.org/simple" } 1942 - resolution-markers = [ 1943 - "python_full_version < '3.11' and platform_machine != 's390x'", 1944 - "python_full_version < '3.11' and platform_machine == 's390x'", 1945 - ] 1946 - dependencies = [ 1947 - { name = "flatbuffers", marker = "python_full_version < '3.11'" }, 1948 - { name = "numpy", version = "2.2.6", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.11'" }, 1949 - { name = "packaging", marker = "python_full_version < '3.11'" }, 1950 - { name = "protobuf", marker = "python_full_version < '3.11'" }, 1951 - { name = "sympy", marker = "python_full_version < '3.11'" }, 1952 - ] 1953 - wheels = [ 1954 - { url = "https://files.pythonhosted.org/packages/28/f4/c8050f3f4916ab6c75432724f0ba51c1548dc1c3d66d40c0f8a9611e370f/onnxruntime_gpu-1.24.3-cp311-cp311-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:ac922633819e1cdc81c9b3a28b5e37d788805307bbaa708a01a3d7150e345625", size = 252750845, upload-time = "2026-03-05T16:35:33.604Z" }, 1955 - { url = "https://files.pythonhosted.org/packages/07/b7/81e8936354651915192a362a1718253c6d03da6b902a95237aa392b1d260/onnxruntime_gpu-1.24.3-cp311-cp311-win_amd64.whl", hash = "sha256:0fe6ece3042db149f36f4991cbebd19a690b7ffd82af89450a261b47f4704a37", size = 207192429, upload-time = "2026-03-05T16:39:57.015Z" }, 1956 - { url = "https://files.pythonhosted.org/packages/24/fa/58ceca812214c9c1a286407c376e42e0b7de3e2c6e14b61cdf3caf6d6d9c/onnxruntime_gpu-1.24.3-cp312-cp312-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:537bdd6d95006a9200ae81f2e73ba9e621e723fdf0deb5901e2e62fb2cccf876", size = 252756089, upload-time = "2026-03-05T16:35:46.004Z" }, 1957 - { url = "https://files.pythonhosted.org/packages/3c/07/2f36920b513bd8939e25591153e37d9cfda94115bd119f2874da0750fce2/onnxruntime_gpu-1.24.3-cp312-cp312-win_amd64.whl", hash = "sha256:d72065b3ab5fdaef74d8b6b8f39b7ce20d89731610e3e63cb40e997d3dce177e", size = 207197001, upload-time = "2026-03-05T16:40:05.691Z" }, 1958 - { url = "https://files.pythonhosted.org/packages/49/57/9e6206dac76e08f028d2ae95f2ab1b3a7c3317fb6c0374a530aad48dab5c/onnxruntime_gpu-1.24.3-cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:3242a70010934e5bb0aeaa9dde4c25c6c2da577b55c6308c0caa828ba3b7be23", size = 252753349, upload-time = "2026-03-05T16:35:58.09Z" }, 1959 - { url = "https://files.pythonhosted.org/packages/4e/ae/f0be395602c13a3a8d22fa6632133550a64536c58bc3623abbba5d0a575e/onnxruntime_gpu-1.24.3-cp313-cp313-win_amd64.whl", hash = "sha256:a423b164dbc26cb7f8736367b11698c2a7294748d3c144c39542ecac28d225c9", size = 207197331, upload-time = "2026-03-05T16:40:14.944Z" }, 1960 - { url = "https://files.pythonhosted.org/packages/b4/af/a64c9789769d8d7fabc6d35dcce2f2897b2d9e0fe113044efc2903f7cd07/onnxruntime_gpu-1.24.3-cp313-cp313t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:9696d54974a1313ef0d87f4cbd04f9abfd13839194638d52bb5967a15615341d", size = 252762923, upload-time = "2026-03-05T16:36:10.043Z" }, 1961 - { url = "https://files.pythonhosted.org/packages/c1/bb/1cf7dffac2fb01e8de9f0882438165f7543f0aab57f86d1f587e6faa8528/onnxruntime_gpu-1.24.3-cp314-cp314-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:b8ca744f40b33380bc9136988213e574c927d2b919ed42149977e006b138f74f", size = 252754914, upload-time = "2026-03-05T16:36:30.739Z" }, 1962 - { url = "https://files.pythonhosted.org/packages/cf/39/3949d56103bd9cd9381de59b060f9bce8dc2c7363f465bf207ebd0c7a5d0/onnxruntime_gpu-1.24.3-cp314-cp314-win_amd64.whl", hash = "sha256:c60c44e2b388720e6670a948b52626f3d089e960ef7da66e4fa6b2b33a11116f", size = 209599131, upload-time = "2026-03-05T16:40:24.074Z" }, 1963 - { url = "https://files.pythonhosted.org/packages/f3/60/51bfbcf2d0540dbfa426a73a9b80046b71a63de7303d16c0f2682c8edfd2/onnxruntime_gpu-1.24.3-cp314-cp314t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:29048407a2398361d93de5537c2d2079d79d720337a0743d4a2cc28db981e776", size = 252764115, upload-time = "2026-03-05T16:36:44.681Z" }, 1964 - ] 1965 - 1966 - [[package]] 1967 - name = "onnxruntime-gpu" 1968 1598 version = "1.25.0" 1969 1599 source = { registry = "https://pypi.org/simple" } 1970 - resolution-markers = [ 1971 - "python_full_version >= '3.14' and platform_machine != 's390x' and sys_platform == 'win32'", 1972 - "python_full_version >= '3.14' and platform_machine != 's390x' and sys_platform == 'emscripten'", 1973 - "python_full_version >= '3.14' and platform_machine != 's390x' and sys_platform != 'emscripten' and sys_platform != 'win32'", 1974 - "python_full_version == '3.13.*' and platform_machine != 's390x' and sys_platform == 'win32'", 1975 - "python_full_version == '3.13.*' and platform_machine != 's390x' and sys_platform == 'emscripten'", 1976 - "python_full_version == '3.13.*' and platform_machine != 's390x' and sys_platform != 'emscripten' and sys_platform != 'win32'", 1977 - "python_full_version >= '3.14' and platform_machine == 's390x' and sys_platform == 'win32'", 1978 - "python_full_version >= '3.14' and platform_machine == 's390x' and sys_platform == 'emscripten'", 1979 - "python_full_version >= '3.14' and platform_machine == 's390x' and sys_platform != 'emscripten' and sys_platform != 'win32'", 1980 - "python_full_version == '3.13.*' and platform_machine == 's390x' and sys_platform == 'win32'", 1981 - "python_full_version == '3.13.*' and platform_machine == 's390x' and sys_platform == 'emscripten'", 1982 - "python_full_version == '3.13.*' and platform_machine == 's390x' and sys_platform != 'emscripten' and sys_platform != 'win32'", 1983 - "python_full_version == '3.12.*' and platform_machine != 's390x' and sys_platform == 'win32'", 1984 - "python_full_version == '3.12.*' and platform_machine != 's390x' and sys_platform == 'emscripten'", 1985 - "python_full_version == '3.12.*' and platform_machine != 's390x' and sys_platform != 'emscripten' and sys_platform != 'win32'", 1986 - "python_full_version == '3.12.*' and platform_machine == 's390x' and sys_platform == 'win32'", 1987 - "python_full_version == '3.12.*' and platform_machine == 's390x' and sys_platform == 'emscripten'", 1988 - "python_full_version == '3.12.*' and platform_machine == 's390x' and sys_platform != 'emscripten' and sys_platform != 'win32'", 1989 - "python_full_version == '3.11.*' and platform_machine != 's390x' and sys_platform == 'win32'", 1990 - "python_full_version == '3.11.*' and platform_machine != 's390x' and sys_platform == 'emscripten'", 1991 - "python_full_version == '3.11.*' and platform_machine != 's390x' and sys_platform != 'emscripten' and sys_platform != 'win32'", 1992 - "python_full_version == '3.11.*' and platform_machine == 's390x' and sys_platform == 'win32'", 1993 - "python_full_version == '3.11.*' and platform_machine == 's390x' and sys_platform == 'emscripten'", 1994 - "python_full_version == '3.11.*' and platform_machine == 's390x' and sys_platform != 'emscripten' and sys_platform != 'win32'", 1995 - ] 1996 1600 dependencies = [ 1997 - { name = "flatbuffers", marker = "python_full_version >= '3.11'" }, 1998 - { name = "numpy", version = "2.3.5", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.11'" }, 1999 - { name = "packaging", marker = "python_full_version >= '3.11'" }, 2000 - { name = "protobuf", marker = "python_full_version >= '3.11'" }, 1601 + { name = "flatbuffers" }, 1602 + { name = "numpy" }, 1603 + { name = "packaging" }, 1604 + { name = "protobuf" }, 2001 1605 ] 2002 1606 wheels = [ 2003 1607 { url = "https://files.pythonhosted.org/packages/2d/7e/f58f8fc505a876b31fd2a34c1eb8f9863b75bf1589c3297c8efd48b93151/onnxruntime_gpu-1.25.0-cp311-cp311-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:e8625bb31ee2d88524414e7458cc604f4f958f323ef8832cc00882f6cd42b9a1", size = 270337732, upload-time = "2026-04-22T17:27:59.993Z" }, ··· 2036 1640 version = "4.13.0.92" 2037 1641 source = { registry = "https://pypi.org/simple" } 2038 1642 dependencies = [ 2039 - { name = "numpy", version = "2.2.6", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.11'" }, 2040 - { name = "numpy", version = "2.3.5", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.11'" }, 1643 + { name = "numpy" }, 2041 1644 ] 2042 1645 wheels = [ 2043 1646 { url = "https://files.pythonhosted.org/packages/79/42/2310883be3b8826ac58c3f2787b9358a2d46923d61f88fedf930bc59c60c/opencv_python_headless-4.13.0.92-cp37-abi3-macosx_13_0_arm64.whl", hash = "sha256:1a7d040ac656c11b8c38677cc8cccdc149f98535089dbe5b081e80a4e5903209", size = 46247192, upload-time = "2026-02-05T07:01:35.187Z" }, ··· 2086 1689 source = { registry = "https://pypi.org/simple" } 2087 1690 sdist = { url = "https://files.pythonhosted.org/packages/d0/02/d52c733a2452ef1ffcc123b68e6606d07276b0e358db70eabad7e40042b7/pillow-12.1.0.tar.gz", hash = "sha256:5c5ae0a06e9ea030ab786b0251b32c7e4ce10e58d983c0d5c56029455180b5b9", size = 46977283, upload-time = "2026-01-02T09:13:29.892Z" } 2088 1691 wheels = [ 2089 - { url = "https://files.pythonhosted.org/packages/fe/41/f73d92b6b883a579e79600d391f2e21cb0df767b2714ecbd2952315dfeef/pillow-12.1.0-cp310-cp310-macosx_10_10_x86_64.whl", hash = "sha256:fb125d860738a09d363a88daa0f59c4533529a90e564785e20fe875b200b6dbd", size = 5304089, upload-time = "2026-01-02T09:10:24.953Z" }, 2090 - { url = "https://files.pythonhosted.org/packages/94/55/7aca2891560188656e4a91ed9adba305e914a4496800da6b5c0a15f09edf/pillow-12.1.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:cad302dc10fac357d3467a74a9561c90609768a6f73a1923b0fd851b6486f8b0", size = 4657815, upload-time = "2026-01-02T09:10:27.063Z" }, 2091 - { url = "https://files.pythonhosted.org/packages/e9/d2/b28221abaa7b4c40b7dba948f0f6a708bd7342c4d47ce342f0ea39643974/pillow-12.1.0-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:a40905599d8079e09f25027423aed94f2823adaf2868940de991e53a449e14a8", size = 6222593, upload-time = "2026-01-02T09:10:29.115Z" }, 2092 - { url = "https://files.pythonhosted.org/packages/71/b8/7a61fb234df6a9b0b479f69e66901209d89ff72a435b49933f9122f94cac/pillow-12.1.0-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:92a7fe4225365c5e3a8e598982269c6d6698d3e783b3b1ae979e7819f9cd55c1", size = 8027579, upload-time = "2026-01-02T09:10:31.182Z" }, 2093 - { url = "https://files.pythonhosted.org/packages/ea/51/55c751a57cc524a15a0e3db20e5cde517582359508d62305a627e77fd295/pillow-12.1.0-cp310-cp310-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:f10c98f49227ed8383d28174ee95155a675c4ed7f85e2e573b04414f7e371bda", size = 6335760, upload-time = "2026-01-02T09:10:33.02Z" }, 2094 - { url = "https://files.pythonhosted.org/packages/dc/7c/60e3e6f5e5891a1a06b4c910f742ac862377a6fe842f7184df4a274ce7bf/pillow-12.1.0-cp310-cp310-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:8637e29d13f478bc4f153d8daa9ffb16455f0a6cb287da1b432fdad2bfbd66c7", size = 7027127, upload-time = "2026-01-02T09:10:35.009Z" }, 2095 - { url = "https://files.pythonhosted.org/packages/06/37/49d47266ba50b00c27ba63a7c898f1bb41a29627ced8c09e25f19ebec0ff/pillow-12.1.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:21e686a21078b0f9cb8c8a961d99e6a4ddb88e0fc5ea6e130172ddddc2e5221a", size = 6449896, upload-time = "2026-01-02T09:10:36.793Z" }, 2096 - { url = "https://files.pythonhosted.org/packages/f9/e5/67fd87d2913902462cd9b79c6211c25bfe95fcf5783d06e1367d6d9a741f/pillow-12.1.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:2415373395a831f53933c23ce051021e79c8cd7979822d8cc478547a3f4da8ef", size = 7151345, upload-time = "2026-01-02T09:10:39.064Z" }, 2097 - { url = "https://files.pythonhosted.org/packages/bd/15/f8c7abf82af68b29f50d77c227e7a1f87ce02fdc66ded9bf603bc3b41180/pillow-12.1.0-cp310-cp310-win32.whl", hash = "sha256:e75d3dba8fc1ddfec0cd752108f93b83b4f8d6ab40e524a95d35f016b9683b09", size = 6325568, upload-time = "2026-01-02T09:10:41.035Z" }, 2098 - { url = "https://files.pythonhosted.org/packages/d4/24/7d1c0e160b6b5ac2605ef7d8be537e28753c0db5363d035948073f5513d7/pillow-12.1.0-cp310-cp310-win_amd64.whl", hash = "sha256:64efdf00c09e31efd754448a383ea241f55a994fd079866b92d2bbff598aad91", size = 7032367, upload-time = "2026-01-02T09:10:43.09Z" }, 2099 - { url = "https://files.pythonhosted.org/packages/f4/03/41c038f0d7a06099254c60f618d0ec7be11e79620fc23b8e85e5b31d9a44/pillow-12.1.0-cp310-cp310-win_arm64.whl", hash = "sha256:f188028b5af6b8fb2e9a76ac0f841a575bd1bd396e46ef0840d9b88a48fdbcea", size = 2452345, upload-time = "2026-01-02T09:10:44.795Z" }, 2100 1692 { url = "https://files.pythonhosted.org/packages/43/c4/bf8328039de6cc22182c3ef007a2abfbbdab153661c0a9aa78af8d706391/pillow-12.1.0-cp311-cp311-macosx_10_10_x86_64.whl", hash = "sha256:a83e0850cb8f5ac975291ebfc4170ba481f41a28065277f7f735c202cd8e0af3", size = 5304057, upload-time = "2026-01-02T09:10:46.627Z" }, 2101 1693 { url = "https://files.pythonhosted.org/packages/43/06/7264c0597e676104cc22ca73ee48f752767cd4b1fe084662620b17e10120/pillow-12.1.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:b6e53e82ec2db0717eabb276aa56cf4e500c9a7cec2c2e189b55c24f65a3e8c0", size = 4657811, upload-time = "2026-01-02T09:10:49.548Z" }, 2102 1694 { url = "https://files.pythonhosted.org/packages/72/64/f9189e44474610daf83da31145fa56710b627b5c4c0b9c235e34058f6b31/pillow-12.1.0-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:40a8e3b9e8773876d6e30daed22f016509e3987bab61b3b7fe309d7019a87451", size = 6232243, upload-time = "2026-01-02T09:10:51.62Z" }, ··· 2283 1875 ] 2284 1876 sdist = { url = "https://files.pythonhosted.org/packages/71/70/23b021c950c2addd24ec408e9ab05d59b035b39d97cdc1130e1bce647bb6/pydantic_core-2.41.5.tar.gz", hash = "sha256:08daa51ea16ad373ffd5e7606252cc32f07bc72b28284b6bc9c6df804816476e", size = 460952, upload-time = "2025-11-04T13:43:49.098Z" } 2285 1877 wheels = [ 2286 - { url = "https://files.pythonhosted.org/packages/c6/90/32c9941e728d564b411d574d8ee0cf09b12ec978cb22b294995bae5549a5/pydantic_core-2.41.5-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:77b63866ca88d804225eaa4af3e664c5faf3568cea95360d21f4725ab6e07146", size = 2107298, upload-time = "2025-11-04T13:39:04.116Z" }, 2287 - { url = "https://files.pythonhosted.org/packages/fb/a8/61c96a77fe28993d9a6fb0f4127e05430a267b235a124545d79fea46dd65/pydantic_core-2.41.5-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:dfa8a0c812ac681395907e71e1274819dec685fec28273a28905df579ef137e2", size = 1901475, upload-time = "2025-11-04T13:39:06.055Z" }, 2288 - { url = "https://files.pythonhosted.org/packages/5d/b6/338abf60225acc18cdc08b4faef592d0310923d19a87fba1faf05af5346e/pydantic_core-2.41.5-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5921a4d3ca3aee735d9fd163808f5e8dd6c6972101e4adbda9a4667908849b97", size = 1918815, upload-time = "2025-11-04T13:39:10.41Z" }, 2289 - { url = "https://files.pythonhosted.org/packages/d1/1c/2ed0433e682983d8e8cba9c8d8ef274d4791ec6a6f24c58935b90e780e0a/pydantic_core-2.41.5-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:e25c479382d26a2a41b7ebea1043564a937db462816ea07afa8a44c0866d52f9", size = 2065567, upload-time = "2025-11-04T13:39:12.244Z" }, 2290 - { url = "https://files.pythonhosted.org/packages/b3/24/cf84974ee7d6eae06b9e63289b7b8f6549d416b5c199ca2d7ce13bbcf619/pydantic_core-2.41.5-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f547144f2966e1e16ae626d8ce72b4cfa0caedc7fa28052001c94fb2fcaa1c52", size = 2230442, upload-time = "2025-11-04T13:39:13.962Z" }, 2291 - { url = "https://files.pythonhosted.org/packages/fd/21/4e287865504b3edc0136c89c9c09431be326168b1eb7841911cbc877a995/pydantic_core-2.41.5-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:6f52298fbd394f9ed112d56f3d11aabd0d5bd27beb3084cc3d8ad069483b8941", size = 2350956, upload-time = "2025-11-04T13:39:15.889Z" }, 2292 - { url = "https://files.pythonhosted.org/packages/a8/76/7727ef2ffa4b62fcab916686a68a0426b9b790139720e1934e8ba797e238/pydantic_core-2.41.5-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:100baa204bb412b74fe285fb0f3a385256dad1d1879f0a5cb1499ed2e83d132a", size = 2068253, upload-time = "2025-11-04T13:39:17.403Z" }, 2293 - { url = "https://files.pythonhosted.org/packages/d5/8c/a4abfc79604bcb4c748e18975c44f94f756f08fb04218d5cb87eb0d3a63e/pydantic_core-2.41.5-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:05a2c8852530ad2812cb7914dc61a1125dc4e06252ee98e5638a12da6cc6fb6c", size = 2177050, upload-time = "2025-11-04T13:39:19.351Z" }, 2294 - { url = "https://files.pythonhosted.org/packages/67/b1/de2e9a9a79b480f9cb0b6e8b6ba4c50b18d4e89852426364c66aa82bb7b3/pydantic_core-2.41.5-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:29452c56df2ed968d18d7e21f4ab0ac55e71dc59524872f6fc57dcf4a3249ed2", size = 2147178, upload-time = "2025-11-04T13:39:21Z" }, 2295 - { url = "https://files.pythonhosted.org/packages/16/c1/dfb33f837a47b20417500efaa0378adc6635b3c79e8369ff7a03c494b4ac/pydantic_core-2.41.5-cp310-cp310-musllinux_1_1_armv7l.whl", hash = "sha256:d5160812ea7a8a2ffbe233d8da666880cad0cbaf5d4de74ae15c313213d62556", size = 2341833, upload-time = "2025-11-04T13:39:22.606Z" }, 2296 - { url = "https://files.pythonhosted.org/packages/47/36/00f398642a0f4b815a9a558c4f1dca1b4020a7d49562807d7bc9ff279a6c/pydantic_core-2.41.5-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:df3959765b553b9440adfd3c795617c352154e497a4eaf3752555cfb5da8fc49", size = 2321156, upload-time = "2025-11-04T13:39:25.843Z" }, 2297 - { url = "https://files.pythonhosted.org/packages/7e/70/cad3acd89fde2010807354d978725ae111ddf6d0ea46d1ea1775b5c1bd0c/pydantic_core-2.41.5-cp310-cp310-win32.whl", hash = "sha256:1f8d33a7f4d5a7889e60dc39856d76d09333d8a6ed0f5f1190635cbec70ec4ba", size = 1989378, upload-time = "2025-11-04T13:39:27.92Z" }, 2298 - { url = "https://files.pythonhosted.org/packages/76/92/d338652464c6c367e5608e4488201702cd1cbb0f33f7b6a85a60fe5f3720/pydantic_core-2.41.5-cp310-cp310-win_amd64.whl", hash = "sha256:62de39db01b8d593e45871af2af9e497295db8d73b085f6bfd0b18c83c70a8f9", size = 2013622, upload-time = "2025-11-04T13:39:29.848Z" }, 2299 1878 { url = "https://files.pythonhosted.org/packages/e8/72/74a989dd9f2084b3d9530b0915fdda64ac48831c30dbf7c72a41a5232db8/pydantic_core-2.41.5-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:a3a52f6156e73e7ccb0f8cced536adccb7042be67cb45f9562e12b319c119da6", size = 2105873, upload-time = "2025-11-04T13:39:31.373Z" }, 2300 1879 { url = "https://files.pythonhosted.org/packages/12/44/37e403fd9455708b3b942949e1d7febc02167662bf1a7da5b78ee1ea2842/pydantic_core-2.41.5-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:7f3bf998340c6d4b0c9a2f02d6a400e51f123b59565d74dc60d252ce888c260b", size = 1899826, upload-time = "2025-11-04T13:39:32.897Z" }, 2301 1880 { url = "https://files.pythonhosted.org/packages/33/7f/1d5cab3ccf44c1935a359d51a8a2a9e1a654b744b5e7f80d41b88d501eec/pydantic_core-2.41.5-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:378bec5c66998815d224c9ca994f1e14c0c21cb95d2f52b6021cc0b2a58f2a5a", size = 1917869, upload-time = "2025-11-04T13:39:34.469Z" }, ··· 2374 1953 { url = "https://files.pythonhosted.org/packages/aa/81/05e400037eaf55ad400bcd318c05bb345b57e708887f07ddb2d20e3f0e98/pydantic_core-2.41.5-graalpy312-graalpy250_312_native-macosx_11_0_arm64.whl", hash = "sha256:aabf5777b5c8ca26f7824cb4a120a740c9588ed58df9b2d196ce92fba42ff8dc", size = 1915388, upload-time = "2025-11-04T13:42:52.215Z" }, 2375 1954 { url = "https://files.pythonhosted.org/packages/6e/0d/e3549b2399f71d56476b77dbf3cf8937cec5cd70536bdc0e374a421d0599/pydantic_core-2.41.5-graalpy312-graalpy250_312_native-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c007fe8a43d43b3969e8469004e9845944f1a80e6acd47c150856bb87f230c56", size = 1942879, upload-time = "2025-11-04T13:42:56.483Z" }, 2376 1955 { url = "https://files.pythonhosted.org/packages/f7/07/34573da085946b6a313d7c42f82f16e8920bfd730665de2d11c0c37a74b5/pydantic_core-2.41.5-graalpy312-graalpy250_312_native-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:76d0819de158cd855d1cbb8fcafdf6f5cf1eb8e470abe056d5d161106e38062b", size = 2139017, upload-time = "2025-11-04T13:42:59.471Z" }, 2377 - { url = "https://files.pythonhosted.org/packages/e6/b0/1a2aa41e3b5a4ba11420aba2d091b2d17959c8d1519ece3627c371951e73/pydantic_core-2.41.5-pp310-pypy310_pp73-macosx_10_12_x86_64.whl", hash = "sha256:b5819cd790dbf0c5eb9f82c73c16b39a65dd6dd4d1439dcdea7816ec9adddab8", size = 2103351, upload-time = "2025-11-04T13:43:02.058Z" }, 2378 - { url = "https://files.pythonhosted.org/packages/a4/ee/31b1f0020baaf6d091c87900ae05c6aeae101fa4e188e1613c80e4f1ea31/pydantic_core-2.41.5-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:5a4e67afbc95fa5c34cf27d9089bca7fcab4e51e57278d710320a70b956d1b9a", size = 1925363, upload-time = "2025-11-04T13:43:05.159Z" }, 2379 - { url = "https://files.pythonhosted.org/packages/e1/89/ab8e86208467e467a80deaca4e434adac37b10a9d134cd2f99b28a01e483/pydantic_core-2.41.5-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ece5c59f0ce7d001e017643d8d24da587ea1f74f6993467d85ae8a5ef9d4f42b", size = 2135615, upload-time = "2025-11-04T13:43:08.116Z" }, 2380 - { url = "https://files.pythonhosted.org/packages/99/0a/99a53d06dd0348b2008f2f30884b34719c323f16c3be4e6cc1203b74a91d/pydantic_core-2.41.5-pp310-pypy310_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:16f80f7abe3351f8ea6858914ddc8c77e02578544a0ebc15b4c2e1a0e813b0b2", size = 2175369, upload-time = "2025-11-04T13:43:12.49Z" }, 2381 - { url = "https://files.pythonhosted.org/packages/6d/94/30ca3b73c6d485b9bb0bc66e611cff4a7138ff9736b7e66bcf0852151636/pydantic_core-2.41.5-pp310-pypy310_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:33cb885e759a705b426baada1fe68cbb0a2e68e34c5d0d0289a364cf01709093", size = 2144218, upload-time = "2025-11-04T13:43:15.431Z" }, 2382 - { url = "https://files.pythonhosted.org/packages/87/57/31b4f8e12680b739a91f472b5671294236b82586889ef764b5fbc6669238/pydantic_core-2.41.5-pp310-pypy310_pp73-musllinux_1_1_armv7l.whl", hash = "sha256:c8d8b4eb992936023be7dee581270af5c6e0697a8559895f527f5b7105ecd36a", size = 2329951, upload-time = "2025-11-04T13:43:18.062Z" }, 2383 - { url = "https://files.pythonhosted.org/packages/7d/73/3c2c8edef77b8f7310e6fb012dbc4b8551386ed575b9eb6fb2506e28a7eb/pydantic_core-2.41.5-pp310-pypy310_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:242a206cd0318f95cd21bdacff3fcc3aab23e79bba5cac3db5a841c9ef9c6963", size = 2318428, upload-time = "2025-11-04T13:43:20.679Z" }, 2384 - { url = "https://files.pythonhosted.org/packages/2f/02/8559b1f26ee0d502c74f9cca5c0d2fd97e967e083e006bbbb4e97f3a043a/pydantic_core-2.41.5-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:d3a978c4f57a597908b7e697229d996d77a6d3c94901e9edee593adada95ce1a", size = 2147009, upload-time = "2025-11-04T13:43:23.286Z" }, 2385 1956 { url = "https://files.pythonhosted.org/packages/5f/9b/1b3f0e9f9305839d7e84912f9e8bfbd191ed1b1ef48083609f0dabde978c/pydantic_core-2.41.5-pp311-pypy311_pp73-macosx_10_12_x86_64.whl", hash = "sha256:b2379fa7ed44ddecb5bfe4e48577d752db9fc10be00a6b7446e9663ba143de26", size = 2101980, upload-time = "2025-11-04T13:43:25.97Z" }, 2386 1957 { url = "https://files.pythonhosted.org/packages/a4/ed/d71fefcb4263df0da6a85b5d8a7508360f2f2e9b3bf5814be9c8bccdccc1/pydantic_core-2.41.5-pp311-pypy311_pp73-macosx_11_0_arm64.whl", hash = "sha256:266fb4cbf5e3cbd0b53669a6d1b039c45e3ce651fd5442eff4d07c2cc8d66808", size = 1923865, upload-time = "2025-11-04T13:43:28.763Z" }, 2387 1958 { url = "https://files.pythonhosted.org/packages/ce/3a/626b38db460d675f873e4444b4bb030453bbe7b4ba55df821d026a0493c4/pydantic_core-2.41.5-pp311-pypy311_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:58133647260ea01e4d0500089a8c4f07bd7aa6ce109682b1426394988d8aaacc", size = 2134256, upload-time = "2025-11-04T13:43:31.71Z" }, ··· 2436 2007 name = "pypdf" 2437 2008 version = "6.7.0" 2438 2009 source = { registry = "https://pypi.org/simple" } 2439 - dependencies = [ 2440 - { name = "typing-extensions", marker = "python_full_version < '3.11'" }, 2441 - ] 2442 2010 sdist = { url = "https://files.pythonhosted.org/packages/10/45/8340de1c752bfda2da912ea0fa8c9a432f7de3f6315e82f1c0847811dff6/pypdf-6.7.0.tar.gz", hash = "sha256:eb95e244d9f434e6cfd157272283339ef586e593be64ee699c620f756d5c3f7e", size = 5299947, upload-time = "2026-02-08T14:47:11.897Z" } 2443 2011 wheels = [ 2444 2012 { url = "https://files.pythonhosted.org/packages/ed/f1/c92e75a0eb18bb10845e792054ded113010de958b6d4998e201c029417bb/pypdf-6.7.0-py3-none-any.whl", hash = "sha256:62e85036d50839cbdf45b8067c2c1a1b925517514d7cba4cbe8755a6c2829bc9", size = 330557, upload-time = "2026-02-08T14:47:10.111Z" }, ··· 2459 2027 source = { registry = "https://pypi.org/simple" } 2460 2028 dependencies = [ 2461 2029 { name = "colorama", marker = "sys_platform == 'win32'" }, 2462 - { name = "exceptiongroup", marker = "python_full_version < '3.11'" }, 2463 2030 { name = "iniconfig" }, 2464 2031 { name = "packaging" }, 2465 2032 { name = "pluggy" }, 2466 2033 { name = "pygments" }, 2467 - { name = "tomli", marker = "python_full_version < '3.11'" }, 2468 2034 ] 2469 2035 sdist = { url = "https://files.pythonhosted.org/packages/d1/db/7ef3487e0fb0049ddb5ce41d3a49c235bf9ad299b6a25d5780a89f19230f/pytest-9.0.2.tar.gz", hash = "sha256:75186651a92bd89611d1d9fc20f0b4345fd827c41ccd5c299a868a05d70edf11", size = 1568901, upload-time = "2025-12-06T21:30:51.014Z" } 2470 2036 wheels = [ ··· 2476 2042 version = "1.3.0" 2477 2043 source = { registry = "https://pypi.org/simple" } 2478 2044 dependencies = [ 2479 - { name = "backports-asyncio-runner", marker = "python_full_version < '3.11'" }, 2480 2045 { name = "pytest" }, 2481 2046 { name = "typing-extensions", marker = "python_full_version < '3.13'" }, 2482 2047 ] ··· 2571 2136 source = { registry = "https://pypi.org/simple" } 2572 2137 sdist = { url = "https://files.pythonhosted.org/packages/05/8e/961c0007c59b8dd7729d542c61a4d537767a59645b82a0b521206e1e25c2/pyyaml-6.0.3.tar.gz", hash = "sha256:d76623373421df22fb4cf8817020cbb7ef15c725b9d5e45f17e189bfc384190f", size = 130960, upload-time = "2025-09-25T21:33:16.546Z" } 2573 2138 wheels = [ 2574 - { url = "https://files.pythonhosted.org/packages/f4/a0/39350dd17dd6d6c6507025c0e53aef67a9293a6d37d3511f23ea510d5800/pyyaml-6.0.3-cp310-cp310-macosx_10_13_x86_64.whl", hash = "sha256:214ed4befebe12df36bcc8bc2b64b396ca31be9304b8f59e25c11cf94a4c033b", size = 184227, upload-time = "2025-09-25T21:31:46.04Z" }, 2575 - { url = "https://files.pythonhosted.org/packages/05/14/52d505b5c59ce73244f59c7a50ecf47093ce4765f116cdb98286a71eeca2/pyyaml-6.0.3-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:02ea2dfa234451bbb8772601d7b8e426c2bfa197136796224e50e35a78777956", size = 174019, upload-time = "2025-09-25T21:31:47.706Z" }, 2576 - { url = "https://files.pythonhosted.org/packages/43/f7/0e6a5ae5599c838c696adb4e6330a59f463265bfa1e116cfd1fbb0abaaae/pyyaml-6.0.3-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:b30236e45cf30d2b8e7b3e85881719e98507abed1011bf463a8fa23e9c3e98a8", size = 740646, upload-time = "2025-09-25T21:31:49.21Z" }, 2577 - { url = "https://files.pythonhosted.org/packages/2f/3a/61b9db1d28f00f8fd0ae760459a5c4bf1b941baf714e207b6eb0657d2578/pyyaml-6.0.3-cp310-cp310-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:66291b10affd76d76f54fad28e22e51719ef9ba22b29e1d7d03d6777a9174198", size = 840793, upload-time = "2025-09-25T21:31:50.735Z" }, 2578 - { url = "https://files.pythonhosted.org/packages/7a/1e/7acc4f0e74c4b3d9531e24739e0ab832a5edf40e64fbae1a9c01941cabd7/pyyaml-6.0.3-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:9c7708761fccb9397fe64bbc0395abcae8c4bf7b0eac081e12b809bf47700d0b", size = 770293, upload-time = "2025-09-25T21:31:51.828Z" }, 2579 - { url = "https://files.pythonhosted.org/packages/8b/ef/abd085f06853af0cd59fa5f913d61a8eab65d7639ff2a658d18a25d6a89d/pyyaml-6.0.3-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:418cf3f2111bc80e0933b2cd8cd04f286338bb88bdc7bc8e6dd775ebde60b5e0", size = 732872, upload-time = "2025-09-25T21:31:53.282Z" }, 2580 - { url = "https://files.pythonhosted.org/packages/1f/15/2bc9c8faf6450a8b3c9fc5448ed869c599c0a74ba2669772b1f3a0040180/pyyaml-6.0.3-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:5e0b74767e5f8c593e8c9b5912019159ed0533c70051e9cce3e8b6aa699fcd69", size = 758828, upload-time = "2025-09-25T21:31:54.807Z" }, 2581 - { url = "https://files.pythonhosted.org/packages/a3/00/531e92e88c00f4333ce359e50c19b8d1de9fe8d581b1534e35ccfbc5f393/pyyaml-6.0.3-cp310-cp310-win32.whl", hash = "sha256:28c8d926f98f432f88adc23edf2e6d4921ac26fb084b028c733d01868d19007e", size = 142415, upload-time = "2025-09-25T21:31:55.885Z" }, 2582 - { url = "https://files.pythonhosted.org/packages/2a/fa/926c003379b19fca39dd4634818b00dec6c62d87faf628d1394e137354d4/pyyaml-6.0.3-cp310-cp310-win_amd64.whl", hash = "sha256:bdb2c67c6c1390b63c6ff89f210c8fd09d9a1217a465701eac7316313c915e4c", size = 158561, upload-time = "2025-09-25T21:31:57.406Z" }, 2583 2139 { url = "https://files.pythonhosted.org/packages/6d/16/a95b6757765b7b031c9374925bb718d55e0a9ba8a1b6a12d25962ea44347/pyyaml-6.0.3-cp311-cp311-macosx_10_13_x86_64.whl", hash = "sha256:44edc647873928551a01e7a563d7452ccdebee747728c1080d881d68af7b997e", size = 185826, upload-time = "2025-09-25T21:31:58.655Z" }, 2584 2140 { url = "https://files.pythonhosted.org/packages/16/19/13de8e4377ed53079ee996e1ab0a9c33ec2faf808a4647b7b4c0d46dd239/pyyaml-6.0.3-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:652cb6edd41e718550aad172851962662ff2681490a8a711af6a4d288dd96824", size = 175577, upload-time = "2025-09-25T21:32:00.088Z" }, 2585 2141 { url = "https://files.pythonhosted.org/packages/0c/62/d2eb46264d4b157dae1275b573017abec435397aa59cbcdab6fc978a8af4/pyyaml-6.0.3-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:10892704fc220243f5305762e276552a0395f7beb4dbf9b14ec8fd43b57f126c", size = 775556, upload-time = "2025-09-25T21:32:01.31Z" }, ··· 2635 2191 source = { registry = "https://pypi.org/simple" } 2636 2192 sdist = { url = "https://files.pythonhosted.org/packages/d3/28/9d808fe62375b9aab5ba92fa9b29371297b067c2790b2d7cda648b1e2f8d/rapidfuzz-3.14.3.tar.gz", hash = "sha256:2491937177868bc4b1e469087601d53f925e8d270ccc21e07404b4b5814b7b5f", size = 57863900, upload-time = "2025-11-01T11:54:52.321Z" } 2637 2193 wheels = [ 2638 - { url = "https://files.pythonhosted.org/packages/69/d1/0efa42a602ed466d3ca1c462eed5d62015c3fd2a402199e2c4b87aa5aa25/rapidfuzz-3.14.3-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:b9fcd4d751a4fffa17aed1dde41647923c72c74af02459ad1222e3b0022da3a1", size = 1952376, upload-time = "2025-11-01T11:52:29.175Z" }, 2639 - { url = "https://files.pythonhosted.org/packages/be/00/37a169bb28b23850a164e6624b1eb299e1ad73c9e7c218ee15744e68d628/rapidfuzz-3.14.3-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:4ad73afb688b36864a8d9b7344a9cf6da186c471e5790cbf541a635ee0f457f2", size = 1390903, upload-time = "2025-11-01T11:52:31.239Z" }, 2640 - { url = "https://files.pythonhosted.org/packages/3c/91/b37207cbbdb6eaafac3da3f55ea85287b27745cb416e75e15769b7d8abe8/rapidfuzz-3.14.3-cp310-cp310-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:c5fb2d978a601820d2cfd111e2c221a9a7bfdf84b41a3ccbb96ceef29f2f1ac7", size = 1385655, upload-time = "2025-11-01T11:52:32.852Z" }, 2641 - { url = "https://files.pythonhosted.org/packages/f2/bb/ca53e518acf43430be61f23b9c5987bd1e01e74fcb7a9ee63e00f597aefb/rapidfuzz-3.14.3-cp310-cp310-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:1d83b8b712fa37e06d59f29a4b49e2e9e8635e908fbc21552fe4d1163db9d2a1", size = 3164708, upload-time = "2025-11-01T11:52:34.618Z" }, 2642 - { url = "https://files.pythonhosted.org/packages/df/e1/7667bf2db3e52adb13cb933dd4a6a2efc66045d26fa150fc0feb64c26d61/rapidfuzz-3.14.3-cp310-cp310-manylinux_2_31_armv7l.whl", hash = "sha256:dc8c07801df5206b81ed6bd6c35cb520cf9b6c64b9b0d19d699f8633dc942897", size = 1221106, upload-time = "2025-11-01T11:52:36.069Z" }, 2643 - { url = "https://files.pythonhosted.org/packages/05/8a/84d9f2d46a2c8eb2ccae81747c4901fa10fe4010aade2d57ce7b4b8e02ec/rapidfuzz-3.14.3-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:c71ce6d4231e5ef2e33caa952bfe671cb9fd42e2afb11952df9fad41d5c821f9", size = 2406048, upload-time = "2025-11-01T11:52:37.936Z" }, 2644 - { url = "https://files.pythonhosted.org/packages/3c/a9/a0b7b7a1b81a020c034eb67c8e23b7e49f920004e295378de3046b0d99e1/rapidfuzz-3.14.3-cp310-cp310-musllinux_1_2_armv7l.whl", hash = "sha256:0e38828d1381a0cceb8a4831212b2f673d46f5129a1897b0451c883eaf4a1747", size = 2527020, upload-time = "2025-11-01T11:52:39.657Z" }, 2645 - { url = "https://files.pythonhosted.org/packages/b4/bc/416df7d108b99b4942ba04dd4cf73c45c3aadb3ef003d95cad78b1d12eb9/rapidfuzz-3.14.3-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:da2a007434323904719158e50f3076a4dadb176ce43df28ed14610c773cc9825", size = 4273958, upload-time = "2025-11-01T11:52:41.017Z" }, 2646 - { url = "https://files.pythonhosted.org/packages/81/d0/b81e041c17cd475002114e0ab8800e4305e60837882cb376a621e520d70f/rapidfuzz-3.14.3-cp310-cp310-win32.whl", hash = "sha256:fce3152f94afcfd12f3dd8cf51e48fa606e3cb56719bccebe3b401f43d0714f9", size = 1725043, upload-time = "2025-11-01T11:52:42.465Z" }, 2647 - { url = "https://files.pythonhosted.org/packages/09/6b/64ad573337d81d64bc78a6a1df53a72a71d54d43d276ce0662c2e95a1f35/rapidfuzz-3.14.3-cp310-cp310-win_amd64.whl", hash = "sha256:37d3c653af15cd88592633e942f5407cb4c64184efab163c40fcebad05f25141", size = 1542273, upload-time = "2025-11-01T11:52:44.005Z" }, 2648 - { url = "https://files.pythonhosted.org/packages/f4/5e/faf76e259bc15808bc0b86028f510215c3d755b6c3a3911113079485e561/rapidfuzz-3.14.3-cp310-cp310-win_arm64.whl", hash = "sha256:cc594bbcd3c62f647dfac66800f307beaee56b22aaba1c005e9c4c40ed733923", size = 814875, upload-time = "2025-11-01T11:52:45.405Z" }, 2649 2194 { url = "https://files.pythonhosted.org/packages/76/25/5b0a33ad3332ee1213068c66f7c14e9e221be90bab434f0cb4defa9d6660/rapidfuzz-3.14.3-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:dea2d113e260a5da0c4003e0a5e9fdf24a9dc2bb9eaa43abd030a1e46ce7837d", size = 1953885, upload-time = "2025-11-01T11:52:47.75Z" }, 2650 2195 { url = "https://files.pythonhosted.org/packages/2d/ab/f1181f500c32c8fcf7c966f5920c7e56b9b1d03193386d19c956505c312d/rapidfuzz-3.14.3-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:e6c31a4aa68cfa75d7eede8b0ed24b9e458447db604c2db53f358be9843d81d3", size = 1390200, upload-time = "2025-11-01T11:52:49.491Z" }, 2651 2196 { url = "https://files.pythonhosted.org/packages/14/2a/0f2de974ececad873865c6bb3ea3ad07c976ac293d5025b2d73325aac1d4/rapidfuzz-3.14.3-cp311-cp311-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:02821366d928e68ddcb567fed8723dad7ea3a979fada6283e6914d5858674850", size = 1389319, upload-time = "2025-11-01T11:52:51.224Z" }, ··· 2767 2312 source = { registry = "https://pypi.org/simple" } 2768 2313 sdist = { url = "https://files.pythonhosted.org/packages/20/af/3f2f423103f1113b36230496629986e0ef7e199d2aa8392452b484b38ced/rpds_py-0.30.0.tar.gz", hash = "sha256:dd8ff7cf90014af0c0f787eea34794ebf6415242ee1d6fa91eaba725cc441e84", size = 69469, upload-time = "2025-11-30T20:24:38.837Z" } 2769 2314 wheels = [ 2770 - { url = "https://files.pythonhosted.org/packages/06/0c/0c411a0ec64ccb6d104dcabe0e713e05e153a9a2c3c2bd2b32ce412166fe/rpds_py-0.30.0-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:679ae98e00c0e8d68a7fda324e16b90fd5260945b45d3b824c892cec9eea3288", size = 370490, upload-time = "2025-11-30T20:21:33.256Z" }, 2771 - { url = "https://files.pythonhosted.org/packages/19/6a/4ba3d0fb7297ebae71171822554abe48d7cab29c28b8f9f2c04b79988c05/rpds_py-0.30.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:4cc2206b76b4f576934f0ed374b10d7ca5f457858b157ca52064bdfc26b9fc00", size = 359751, upload-time = "2025-11-30T20:21:34.591Z" }, 2772 - { url = "https://files.pythonhosted.org/packages/cd/7c/e4933565ef7f7a0818985d87c15d9d273f1a649afa6a52ea35ad011195ea/rpds_py-0.30.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:389a2d49eded1896c3d48b0136ead37c48e221b391c052fba3f4055c367f60a6", size = 389696, upload-time = "2025-11-30T20:21:36.122Z" }, 2773 - { url = "https://files.pythonhosted.org/packages/5e/01/6271a2511ad0815f00f7ed4390cf2567bec1d4b1da39e2c27a41e6e3b4de/rpds_py-0.30.0-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:32c8528634e1bf7121f3de08fa85b138f4e0dc47657866630611b03967f041d7", size = 403136, upload-time = "2025-11-30T20:21:37.728Z" }, 2774 - { url = "https://files.pythonhosted.org/packages/55/64/c857eb7cd7541e9b4eee9d49c196e833128a55b89a9850a9c9ac33ccf897/rpds_py-0.30.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f207f69853edd6f6700b86efb84999651baf3789e78a466431df1331608e5324", size = 524699, upload-time = "2025-11-30T20:21:38.92Z" }, 2775 - { url = "https://files.pythonhosted.org/packages/9c/ed/94816543404078af9ab26159c44f9e98e20fe47e2126d5d32c9d9948d10a/rpds_py-0.30.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:67b02ec25ba7a9e8fa74c63b6ca44cf5707f2fbfadae3ee8e7494297d56aa9df", size = 412022, upload-time = "2025-11-30T20:21:40.407Z" }, 2776 - { url = "https://files.pythonhosted.org/packages/61/b5/707f6cf0066a6412aacc11d17920ea2e19e5b2f04081c64526eb35b5c6e7/rpds_py-0.30.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0c0e95f6819a19965ff420f65578bacb0b00f251fefe2c8b23347c37174271f3", size = 390522, upload-time = "2025-11-30T20:21:42.17Z" }, 2777 - { url = "https://files.pythonhosted.org/packages/13/4e/57a85fda37a229ff4226f8cbcf09f2a455d1ed20e802ce5b2b4a7f5ed053/rpds_py-0.30.0-cp310-cp310-manylinux_2_31_riscv64.whl", hash = "sha256:a452763cc5198f2f98898eb98f7569649fe5da666c2dc6b5ddb10fde5a574221", size = 404579, upload-time = "2025-11-30T20:21:43.769Z" }, 2778 - { url = "https://files.pythonhosted.org/packages/f9/da/c9339293513ec680a721e0e16bf2bac3db6e5d7e922488de471308349bba/rpds_py-0.30.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:e0b65193a413ccc930671c55153a03ee57cecb49e6227204b04fae512eb657a7", size = 421305, upload-time = "2025-11-30T20:21:44.994Z" }, 2779 - { url = "https://files.pythonhosted.org/packages/f9/be/522cb84751114f4ad9d822ff5a1aa3c98006341895d5f084779b99596e5c/rpds_py-0.30.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:858738e9c32147f78b3ac24dc0edb6610000e56dc0f700fd5f651d0a0f0eb9ff", size = 572503, upload-time = "2025-11-30T20:21:46.91Z" }, 2780 - { url = "https://files.pythonhosted.org/packages/a2/9b/de879f7e7ceddc973ea6e4629e9b380213a6938a249e94b0cdbcc325bb66/rpds_py-0.30.0-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:da279aa314f00acbb803da1e76fa18666778e8a8f83484fba94526da5de2cba7", size = 598322, upload-time = "2025-11-30T20:21:48.709Z" }, 2781 - { url = "https://files.pythonhosted.org/packages/48/ac/f01fc22efec3f37d8a914fc1b2fb9bcafd56a299edbe96406f3053edea5a/rpds_py-0.30.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:7c64d38fb49b6cdeda16ab49e35fe0da2e1e9b34bc38bd78386530f218b37139", size = 560792, upload-time = "2025-11-30T20:21:50.024Z" }, 2782 - { url = "https://files.pythonhosted.org/packages/e2/da/4e2b19d0f131f35b6146425f846563d0ce036763e38913d917187307a671/rpds_py-0.30.0-cp310-cp310-win32.whl", hash = "sha256:6de2a32a1665b93233cde140ff8b3467bdb9e2af2b91079f0333a0974d12d464", size = 221901, upload-time = "2025-11-30T20:21:51.32Z" }, 2783 - { url = "https://files.pythonhosted.org/packages/96/cb/156d7a5cf4f78a7cc571465d8aec7a3c447c94f6749c5123f08438bcf7bc/rpds_py-0.30.0-cp310-cp310-win_amd64.whl", hash = "sha256:1726859cd0de969f88dc8673bdd954185b9104e05806be64bcd87badbe313169", size = 235823, upload-time = "2025-11-30T20:21:52.505Z" }, 2784 2315 { url = "https://files.pythonhosted.org/packages/4d/6e/f964e88b3d2abee2a82c1ac8366da848fce1c6d834dc2132c3fda3970290/rpds_py-0.30.0-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:a2bffea6a4ca9f01b3f8e548302470306689684e61602aa3d141e34da06cf425", size = 370157, upload-time = "2025-11-30T20:21:53.789Z" }, 2785 2316 { url = "https://files.pythonhosted.org/packages/94/ba/24e5ebb7c1c82e74c4e4f33b2112a5573ddc703915b13a073737b59b86e0/rpds_py-0.30.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:dc4f992dfe1e2bc3ebc7444f6c7051b4bc13cd8e33e43511e8ffd13bf407010d", size = 359676, upload-time = "2025-11-30T20:21:55.475Z" }, 2786 2317 { url = "https://files.pythonhosted.org/packages/84/86/04dbba1b087227747d64d80c3b74df946b986c57af0a9f0c98726d4d7a3b/rpds_py-0.30.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:422c3cb9856d80b09d30d2eb255d0754b23e090034e1deb4083f8004bd0761e4", size = 389938, upload-time = "2025-11-30T20:21:57.079Z" }, ··· 2922 2453 2923 2454 [[package]] 2924 2455 name = "scikit-learn" 2925 - version = "1.7.2" 2926 - source = { registry = "https://pypi.org/simple" } 2927 - resolution-markers = [ 2928 - "python_full_version < '3.11' and platform_machine != 's390x'", 2929 - "python_full_version < '3.11' and platform_machine == 's390x'", 2930 - ] 2931 - dependencies = [ 2932 - { name = "joblib", marker = "python_full_version < '3.11'" }, 2933 - { name = "numpy", version = "2.2.6", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.11'" }, 2934 - { name = "scipy", version = "1.15.3", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.11'" }, 2935 - { name = "threadpoolctl", marker = "python_full_version < '3.11'" }, 2936 - ] 2937 - sdist = { url = "https://files.pythonhosted.org/packages/98/c2/a7855e41c9d285dfe86dc50b250978105dce513d6e459ea66a6aeb0e1e0c/scikit_learn-1.7.2.tar.gz", hash = "sha256:20e9e49ecd130598f1ca38a1d85090e1a600147b9c02fa6f15d69cb53d968fda", size = 7193136, upload-time = "2025-09-09T08:21:29.075Z" } 2938 - wheels = [ 2939 - { url = "https://files.pythonhosted.org/packages/ba/3e/daed796fd69cce768b8788401cc464ea90b306fb196ae1ffed0b98182859/scikit_learn-1.7.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:6b33579c10a3081d076ab403df4a4190da4f4432d443521674637677dc91e61f", size = 9336221, upload-time = "2025-09-09T08:20:19.328Z" }, 2940 - { url = "https://files.pythonhosted.org/packages/1c/ce/af9d99533b24c55ff4e18d9b7b4d9919bbc6cd8f22fe7a7be01519a347d5/scikit_learn-1.7.2-cp310-cp310-macosx_12_0_arm64.whl", hash = "sha256:36749fb62b3d961b1ce4fedf08fa57a1986cd409eff2d783bca5d4b9b5fce51c", size = 8653834, upload-time = "2025-09-09T08:20:22.073Z" }, 2941 - { url = "https://files.pythonhosted.org/packages/58/0e/8c2a03d518fb6bd0b6b0d4b114c63d5f1db01ff0f9925d8eb10960d01c01/scikit_learn-1.7.2-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:7a58814265dfc52b3295b1900cfb5701589d30a8bb026c7540f1e9d3499d5ec8", size = 9660938, upload-time = "2025-09-09T08:20:24.327Z" }, 2942 - { url = "https://files.pythonhosted.org/packages/2b/75/4311605069b5d220e7cf5adabb38535bd96f0079313cdbb04b291479b22a/scikit_learn-1.7.2-cp310-cp310-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:4a847fea807e278f821a0406ca01e387f97653e284ecbd9750e3ee7c90347f18", size = 9477818, upload-time = "2025-09-09T08:20:26.845Z" }, 2943 - { url = "https://files.pythonhosted.org/packages/7f/9b/87961813c34adbca21a6b3f6b2bea344c43b30217a6d24cc437c6147f3e8/scikit_learn-1.7.2-cp310-cp310-win_amd64.whl", hash = "sha256:ca250e6836d10e6f402436d6463d6c0e4d8e0234cfb6a9a47835bd392b852ce5", size = 8886969, upload-time = "2025-09-09T08:20:29.329Z" }, 2944 - { url = "https://files.pythonhosted.org/packages/43/83/564e141eef908a5863a54da8ca342a137f45a0bfb71d1d79704c9894c9d1/scikit_learn-1.7.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:c7509693451651cd7361d30ce4e86a1347493554f172b1c72a39300fa2aea79e", size = 9331967, upload-time = "2025-09-09T08:20:32.421Z" }, 2945 - { url = "https://files.pythonhosted.org/packages/18/d6/ba863a4171ac9d7314c4d3fc251f015704a2caeee41ced89f321c049ed83/scikit_learn-1.7.2-cp311-cp311-macosx_12_0_arm64.whl", hash = "sha256:0486c8f827c2e7b64837c731c8feff72c0bd2b998067a8a9cbc10643c31f0fe1", size = 8648645, upload-time = "2025-09-09T08:20:34.436Z" }, 2946 - { url = "https://files.pythonhosted.org/packages/ef/0e/97dbca66347b8cf0ea8b529e6bb9367e337ba2e8be0ef5c1a545232abfde/scikit_learn-1.7.2-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:89877e19a80c7b11a2891a27c21c4894fb18e2c2e077815bcade10d34287b20d", size = 9715424, upload-time = "2025-09-09T08:20:36.776Z" }, 2947 - { url = "https://files.pythonhosted.org/packages/f7/32/1f3b22e3207e1d2c883a7e09abb956362e7d1bd2f14458c7de258a26ac15/scikit_learn-1.7.2-cp311-cp311-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:8da8bf89d4d79aaec192d2bda62f9b56ae4e5b4ef93b6a56b5de4977e375c1f1", size = 9509234, upload-time = "2025-09-09T08:20:38.957Z" }, 2948 - { url = "https://files.pythonhosted.org/packages/9f/71/34ddbd21f1da67c7a768146968b4d0220ee6831e4bcbad3e03dd3eae88b6/scikit_learn-1.7.2-cp311-cp311-win_amd64.whl", hash = "sha256:9b7ed8d58725030568523e937c43e56bc01cadb478fc43c042a9aca1dacb3ba1", size = 8894244, upload-time = "2025-09-09T08:20:41.166Z" }, 2949 - { url = "https://files.pythonhosted.org/packages/a7/aa/3996e2196075689afb9fce0410ebdb4a09099d7964d061d7213700204409/scikit_learn-1.7.2-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:8d91a97fa2b706943822398ab943cde71858a50245e31bc71dba62aab1d60a96", size = 9259818, upload-time = "2025-09-09T08:20:43.19Z" }, 2950 - { url = "https://files.pythonhosted.org/packages/43/5d/779320063e88af9c4a7c2cf463ff11c21ac9c8bd730c4a294b0000b666c9/scikit_learn-1.7.2-cp312-cp312-macosx_12_0_arm64.whl", hash = "sha256:acbc0f5fd2edd3432a22c69bed78e837c70cf896cd7993d71d51ba6708507476", size = 8636997, upload-time = "2025-09-09T08:20:45.468Z" }, 2951 - { url = "https://files.pythonhosted.org/packages/5c/d0/0c577d9325b05594fdd33aa970bf53fb673f051a45496842caee13cfd7fe/scikit_learn-1.7.2-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:e5bf3d930aee75a65478df91ac1225ff89cd28e9ac7bd1196853a9229b6adb0b", size = 9478381, upload-time = "2025-09-09T08:20:47.982Z" }, 2952 - { url = "https://files.pythonhosted.org/packages/82/70/8bf44b933837ba8494ca0fc9a9ab60f1c13b062ad0197f60a56e2fc4c43e/scikit_learn-1.7.2-cp312-cp312-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:b4d6e9deed1a47aca9fe2f267ab8e8fe82ee20b4526b2c0cd9e135cea10feb44", size = 9300296, upload-time = "2025-09-09T08:20:50.366Z" }, 2953 - { url = "https://files.pythonhosted.org/packages/c6/99/ed35197a158f1fdc2fe7c3680e9c70d0128f662e1fee4ed495f4b5e13db0/scikit_learn-1.7.2-cp312-cp312-win_amd64.whl", hash = "sha256:6088aa475f0785e01bcf8529f55280a3d7d298679f50c0bb70a2364a82d0b290", size = 8731256, upload-time = "2025-09-09T08:20:52.627Z" }, 2954 - { url = "https://files.pythonhosted.org/packages/ae/93/a3038cb0293037fd335f77f31fe053b89c72f17b1c8908c576c29d953e84/scikit_learn-1.7.2-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:0b7dacaa05e5d76759fb071558a8b5130f4845166d88654a0f9bdf3eb57851b7", size = 9212382, upload-time = "2025-09-09T08:20:54.731Z" }, 2955 - { url = "https://files.pythonhosted.org/packages/40/dd/9a88879b0c1104259136146e4742026b52df8540c39fec21a6383f8292c7/scikit_learn-1.7.2-cp313-cp313-macosx_12_0_arm64.whl", hash = "sha256:abebbd61ad9e1deed54cca45caea8ad5f79e1b93173dece40bb8e0c658dbe6fe", size = 8592042, upload-time = "2025-09-09T08:20:57.313Z" }, 2956 - { url = "https://files.pythonhosted.org/packages/46/af/c5e286471b7d10871b811b72ae794ac5fe2989c0a2df07f0ec723030f5f5/scikit_learn-1.7.2-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:502c18e39849c0ea1a5d681af1dbcf15f6cce601aebb657aabbfe84133c1907f", size = 9434180, upload-time = "2025-09-09T08:20:59.671Z" }, 2957 - { url = "https://files.pythonhosted.org/packages/f1/fd/df59faa53312d585023b2da27e866524ffb8faf87a68516c23896c718320/scikit_learn-1.7.2-cp313-cp313-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:7a4c328a71785382fe3fe676a9ecf2c86189249beff90bf85e22bdb7efaf9ae0", size = 9283660, upload-time = "2025-09-09T08:21:01.71Z" }, 2958 - { url = "https://files.pythonhosted.org/packages/a7/c7/03000262759d7b6f38c836ff9d512f438a70d8a8ddae68ee80de72dcfb63/scikit_learn-1.7.2-cp313-cp313-win_amd64.whl", hash = "sha256:63a9afd6f7b229aad94618c01c252ce9e6fa97918c5ca19c9a17a087d819440c", size = 8702057, upload-time = "2025-09-09T08:21:04.234Z" }, 2959 - { url = "https://files.pythonhosted.org/packages/55/87/ef5eb1f267084532c8e4aef98a28b6ffe7425acbfd64b5e2f2e066bc29b3/scikit_learn-1.7.2-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:9acb6c5e867447b4e1390930e3944a005e2cb115922e693c08a323421a6966e8", size = 9558731, upload-time = "2025-09-09T08:21:06.381Z" }, 2960 - { url = "https://files.pythonhosted.org/packages/93/f8/6c1e3fc14b10118068d7938878a9f3f4e6d7b74a8ddb1e5bed65159ccda8/scikit_learn-1.7.2-cp313-cp313t-macosx_12_0_arm64.whl", hash = "sha256:2a41e2a0ef45063e654152ec9d8bcfc39f7afce35b08902bfe290c2498a67a6a", size = 9038852, upload-time = "2025-09-09T08:21:08.628Z" }, 2961 - { url = "https://files.pythonhosted.org/packages/83/87/066cafc896ee540c34becf95d30375fe5cbe93c3b75a0ee9aa852cd60021/scikit_learn-1.7.2-cp313-cp313t-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:98335fb98509b73385b3ab2bd0639b1f610541d3988ee675c670371d6a87aa7c", size = 9527094, upload-time = "2025-09-09T08:21:11.486Z" }, 2962 - { url = "https://files.pythonhosted.org/packages/9c/2b/4903e1ccafa1f6453b1ab78413938c8800633988c838aa0be386cbb33072/scikit_learn-1.7.2-cp313-cp313t-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:191e5550980d45449126e23ed1d5e9e24b2c68329ee1f691a3987476e115e09c", size = 9367436, upload-time = "2025-09-09T08:21:13.602Z" }, 2963 - { url = "https://files.pythonhosted.org/packages/b5/aa/8444be3cfb10451617ff9d177b3c190288f4563e6c50ff02728be67ad094/scikit_learn-1.7.2-cp313-cp313t-win_amd64.whl", hash = "sha256:57dc4deb1d3762c75d685507fbd0bc17160144b2f2ba4ccea5dc285ab0d0e973", size = 9275749, upload-time = "2025-09-09T08:21:15.96Z" }, 2964 - { url = "https://files.pythonhosted.org/packages/d9/82/dee5acf66837852e8e68df6d8d3a6cb22d3df997b733b032f513d95205b7/scikit_learn-1.7.2-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:fa8f63940e29c82d1e67a45d5297bdebbcb585f5a5a50c4914cc2e852ab77f33", size = 9208906, upload-time = "2025-09-09T08:21:18.557Z" }, 2965 - { url = "https://files.pythonhosted.org/packages/3c/30/9029e54e17b87cb7d50d51a5926429c683d5b4c1732f0507a6c3bed9bf65/scikit_learn-1.7.2-cp314-cp314-macosx_12_0_arm64.whl", hash = "sha256:f95dc55b7902b91331fa4e5845dd5bde0580c9cd9612b1b2791b7e80c3d32615", size = 8627836, upload-time = "2025-09-09T08:21:20.695Z" }, 2966 - { url = "https://files.pythonhosted.org/packages/60/18/4a52c635c71b536879f4b971c2cedf32c35ee78f48367885ed8025d1f7ee/scikit_learn-1.7.2-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:9656e4a53e54578ad10a434dc1f993330568cfee176dff07112b8785fb413106", size = 9426236, upload-time = "2025-09-09T08:21:22.645Z" }, 2967 - { url = "https://files.pythonhosted.org/packages/99/7e/290362f6ab582128c53445458a5befd471ed1ea37953d5bcf80604619250/scikit_learn-1.7.2-cp314-cp314-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:96dc05a854add0e50d3f47a1ef21a10a595016da5b007c7d9cd9d0bffd1fcc61", size = 9312593, upload-time = "2025-09-09T08:21:24.65Z" }, 2968 - { url = "https://files.pythonhosted.org/packages/8e/87/24f541b6d62b1794939ae6422f8023703bbf6900378b2b34e0b4384dfefd/scikit_learn-1.7.2-cp314-cp314-win_amd64.whl", hash = "sha256:bb24510ed3f9f61476181e4db51ce801e2ba37541def12dc9333b946fc7a9cf8", size = 8820007, upload-time = "2025-09-09T08:21:26.713Z" }, 2969 - ] 2970 - 2971 - [[package]] 2972 - name = "scikit-learn" 2973 2456 version = "1.8.0" 2974 2457 source = { registry = "https://pypi.org/simple" } 2975 - resolution-markers = [ 2976 - "python_full_version >= '3.14' and platform_machine != 's390x' and sys_platform == 'win32'", 2977 - "python_full_version >= '3.14' and platform_machine != 's390x' and sys_platform == 'emscripten'", 2978 - "python_full_version >= '3.14' and platform_machine != 's390x' and sys_platform != 'emscripten' and sys_platform != 'win32'", 2979 - "python_full_version == '3.13.*' and platform_machine != 's390x' and sys_platform == 'win32'", 2980 - "python_full_version == '3.13.*' and platform_machine != 's390x' and sys_platform == 'emscripten'", 2981 - "python_full_version == '3.13.*' and platform_machine != 's390x' and sys_platform != 'emscripten' and sys_platform != 'win32'", 2982 - "python_full_version >= '3.14' and platform_machine == 's390x' and sys_platform == 'win32'", 2983 - "python_full_version >= '3.14' and platform_machine == 's390x' and sys_platform == 'emscripten'", 2984 - "python_full_version >= '3.14' and platform_machine == 's390x' and sys_platform != 'emscripten' and sys_platform != 'win32'", 2985 - "python_full_version == '3.13.*' and platform_machine == 's390x' and sys_platform == 'win32'", 2986 - "python_full_version == '3.13.*' and platform_machine == 's390x' and sys_platform == 'emscripten'", 2987 - "python_full_version == '3.13.*' and platform_machine == 's390x' and sys_platform != 'emscripten' and sys_platform != 'win32'", 2988 - "python_full_version == '3.12.*' and platform_machine != 's390x' and sys_platform == 'win32'", 2989 - "python_full_version == '3.12.*' and platform_machine != 's390x' and sys_platform == 'emscripten'", 2990 - "python_full_version == '3.12.*' and platform_machine != 's390x' and sys_platform != 'emscripten' and sys_platform != 'win32'", 2991 - "python_full_version == '3.12.*' and platform_machine == 's390x' and sys_platform == 'win32'", 2992 - "python_full_version == '3.12.*' and platform_machine == 's390x' and sys_platform == 'emscripten'", 2993 - "python_full_version == '3.12.*' and platform_machine == 's390x' and sys_platform != 'emscripten' and sys_platform != 'win32'", 2994 - "python_full_version == '3.11.*' and platform_machine != 's390x' and sys_platform == 'win32'", 2995 - "python_full_version == '3.11.*' and platform_machine != 's390x' and sys_platform == 'emscripten'", 2996 - "python_full_version == '3.11.*' and platform_machine != 's390x' and sys_platform != 'emscripten' and sys_platform != 'win32'", 2997 - "python_full_version == '3.11.*' and platform_machine == 's390x' and sys_platform == 'win32'", 2998 - "python_full_version == '3.11.*' and platform_machine == 's390x' and sys_platform == 'emscripten'", 2999 - "python_full_version == '3.11.*' and platform_machine == 's390x' and sys_platform != 'emscripten' and sys_platform != 'win32'", 3000 - ] 3001 2458 dependencies = [ 3002 - { name = "joblib", marker = "python_full_version >= '3.11'" }, 3003 - { name = "numpy", version = "2.3.5", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.11'" }, 3004 - { name = "scipy", version = "1.17.1", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.11'" }, 3005 - { name = "threadpoolctl", marker = "python_full_version >= '3.11'" }, 2459 + { name = "joblib" }, 2460 + { name = "numpy" }, 2461 + { name = "scipy" }, 2462 + { name = "threadpoolctl" }, 3006 2463 ] 3007 2464 sdist = { url = "https://files.pythonhosted.org/packages/0e/d4/40988bf3b8e34feec1d0e6a051446b1f66225f8529b9309becaeef62b6c4/scikit_learn-1.8.0.tar.gz", hash = "sha256:9bccbb3b40e3de10351f8f5068e105d0f4083b1a65fa07b6634fbc401a6287fd", size = 7335585, upload-time = "2025-12-10T07:08:53.618Z" } 3008 2465 wheels = [ ··· 3046 2503 3047 2504 [[package]] 3048 2505 name = "scipy" 3049 - version = "1.15.3" 3050 - source = { registry = "https://pypi.org/simple" } 3051 - resolution-markers = [ 3052 - "python_full_version < '3.11' and platform_machine != 's390x'", 3053 - "python_full_version < '3.11' and platform_machine == 's390x'", 3054 - ] 3055 - dependencies = [ 3056 - { name = "numpy", version = "2.2.6", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.11'" }, 3057 - ] 3058 - sdist = { url = "https://files.pythonhosted.org/packages/0f/37/6964b830433e654ec7485e45a00fc9a27cf868d622838f6b6d9c5ec0d532/scipy-1.15.3.tar.gz", hash = "sha256:eae3cf522bc7df64b42cad3925c876e1b0b6c35c1337c93e12c0f366f55b0eaf", size = 59419214, upload-time = "2025-05-08T16:13:05.955Z" } 3059 - wheels = [ 3060 - { url = "https://files.pythonhosted.org/packages/78/2f/4966032c5f8cc7e6a60f1b2e0ad686293b9474b65246b0c642e3ef3badd0/scipy-1.15.3-cp310-cp310-macosx_10_13_x86_64.whl", hash = "sha256:a345928c86d535060c9c2b25e71e87c39ab2f22fc96e9636bd74d1dbf9de448c", size = 38702770, upload-time = "2025-05-08T16:04:20.849Z" }, 3061 - { url = "https://files.pythonhosted.org/packages/a0/6e/0c3bf90fae0e910c274db43304ebe25a6b391327f3f10b5dcc638c090795/scipy-1.15.3-cp310-cp310-macosx_12_0_arm64.whl", hash = "sha256:ad3432cb0f9ed87477a8d97f03b763fd1d57709f1bbde3c9369b1dff5503b253", size = 30094511, upload-time = "2025-05-08T16:04:27.103Z" }, 3062 - { url = "https://files.pythonhosted.org/packages/ea/b1/4deb37252311c1acff7f101f6453f0440794f51b6eacb1aad4459a134081/scipy-1.15.3-cp310-cp310-macosx_14_0_arm64.whl", hash = "sha256:aef683a9ae6eb00728a542b796f52a5477b78252edede72b8327a886ab63293f", size = 22368151, upload-time = "2025-05-08T16:04:31.731Z" }, 3063 - { url = "https://files.pythonhosted.org/packages/38/7d/f457626e3cd3c29b3a49ca115a304cebb8cc6f31b04678f03b216899d3c6/scipy-1.15.3-cp310-cp310-macosx_14_0_x86_64.whl", hash = "sha256:1c832e1bd78dea67d5c16f786681b28dd695a8cb1fb90af2e27580d3d0967e92", size = 25121732, upload-time = "2025-05-08T16:04:36.596Z" }, 3064 - { url = "https://files.pythonhosted.org/packages/db/0a/92b1de4a7adc7a15dcf5bddc6e191f6f29ee663b30511ce20467ef9b82e4/scipy-1.15.3-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:263961f658ce2165bbd7b99fa5135195c3a12d9bef045345016b8b50c315cb82", size = 35547617, upload-time = "2025-05-08T16:04:43.546Z" }, 3065 - { url = "https://files.pythonhosted.org/packages/8e/6d/41991e503e51fc1134502694c5fa7a1671501a17ffa12716a4a9151af3df/scipy-1.15.3-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9e2abc762b0811e09a0d3258abee2d98e0c703eee49464ce0069590846f31d40", size = 37662964, upload-time = "2025-05-08T16:04:49.431Z" }, 3066 - { url = "https://files.pythonhosted.org/packages/25/e1/3df8f83cb15f3500478c889be8fb18700813b95e9e087328230b98d547ff/scipy-1.15.3-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:ed7284b21a7a0c8f1b6e5977ac05396c0d008b89e05498c8b7e8f4a1423bba0e", size = 37238749, upload-time = "2025-05-08T16:04:55.215Z" }, 3067 - { url = "https://files.pythonhosted.org/packages/93/3e/b3257cf446f2a3533ed7809757039016b74cd6f38271de91682aa844cfc5/scipy-1.15.3-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:5380741e53df2c566f4d234b100a484b420af85deb39ea35a1cc1be84ff53a5c", size = 40022383, upload-time = "2025-05-08T16:05:01.914Z" }, 3068 - { url = "https://files.pythonhosted.org/packages/d1/84/55bc4881973d3f79b479a5a2e2df61c8c9a04fcb986a213ac9c02cfb659b/scipy-1.15.3-cp310-cp310-win_amd64.whl", hash = "sha256:9d61e97b186a57350f6d6fd72640f9e99d5a4a2b8fbf4b9ee9a841eab327dc13", size = 41259201, upload-time = "2025-05-08T16:05:08.166Z" }, 3069 - { url = "https://files.pythonhosted.org/packages/96/ab/5cc9f80f28f6a7dff646c5756e559823614a42b1939d86dd0ed550470210/scipy-1.15.3-cp311-cp311-macosx_10_13_x86_64.whl", hash = "sha256:993439ce220d25e3696d1b23b233dd010169b62f6456488567e830654ee37a6b", size = 38714255, upload-time = "2025-05-08T16:05:14.596Z" }, 3070 - { url = "https://files.pythonhosted.org/packages/4a/4a/66ba30abe5ad1a3ad15bfb0b59d22174012e8056ff448cb1644deccbfed2/scipy-1.15.3-cp311-cp311-macosx_12_0_arm64.whl", hash = "sha256:34716e281f181a02341ddeaad584205bd2fd3c242063bd3423d61ac259ca7eba", size = 30111035, upload-time = "2025-05-08T16:05:20.152Z" }, 3071 - { url = "https://files.pythonhosted.org/packages/4b/fa/a7e5b95afd80d24313307f03624acc65801846fa75599034f8ceb9e2cbf6/scipy-1.15.3-cp311-cp311-macosx_14_0_arm64.whl", hash = "sha256:3b0334816afb8b91dab859281b1b9786934392aa3d527cd847e41bb6f45bee65", size = 22384499, upload-time = "2025-05-08T16:05:24.494Z" }, 3072 - { url = "https://files.pythonhosted.org/packages/17/99/f3aaddccf3588bb4aea70ba35328c204cadd89517a1612ecfda5b2dd9d7a/scipy-1.15.3-cp311-cp311-macosx_14_0_x86_64.whl", hash = "sha256:6db907c7368e3092e24919b5e31c76998b0ce1684d51a90943cb0ed1b4ffd6c1", size = 25152602, upload-time = "2025-05-08T16:05:29.313Z" }, 3073 - { url = "https://files.pythonhosted.org/packages/56/c5/1032cdb565f146109212153339f9cb8b993701e9fe56b1c97699eee12586/scipy-1.15.3-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:721d6b4ef5dc82ca8968c25b111e307083d7ca9091bc38163fb89243e85e3889", size = 35503415, upload-time = "2025-05-08T16:05:34.699Z" }, 3074 - { url = "https://files.pythonhosted.org/packages/bd/37/89f19c8c05505d0601ed5650156e50eb881ae3918786c8fd7262b4ee66d3/scipy-1.15.3-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:39cb9c62e471b1bb3750066ecc3a3f3052b37751c7c3dfd0fd7e48900ed52982", size = 37652622, upload-time = "2025-05-08T16:05:40.762Z" }, 3075 - { url = "https://files.pythonhosted.org/packages/7e/31/be59513aa9695519b18e1851bb9e487de66f2d31f835201f1b42f5d4d475/scipy-1.15.3-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:795c46999bae845966368a3c013e0e00947932d68e235702b5c3f6ea799aa8c9", size = 37244796, upload-time = "2025-05-08T16:05:48.119Z" }, 3076 - { url = "https://files.pythonhosted.org/packages/10/c0/4f5f3eeccc235632aab79b27a74a9130c6c35df358129f7ac8b29f562ac7/scipy-1.15.3-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:18aaacb735ab38b38db42cb01f6b92a2d0d4b6aabefeb07f02849e47f8fb3594", size = 40047684, upload-time = "2025-05-08T16:05:54.22Z" }, 3077 - { url = "https://files.pythonhosted.org/packages/ab/a7/0ddaf514ce8a8714f6ed243a2b391b41dbb65251affe21ee3077ec45ea9a/scipy-1.15.3-cp311-cp311-win_amd64.whl", hash = "sha256:ae48a786a28412d744c62fd7816a4118ef97e5be0bee968ce8f0a2fba7acf3bb", size = 41246504, upload-time = "2025-05-08T16:06:00.437Z" }, 3078 - { url = "https://files.pythonhosted.org/packages/37/4b/683aa044c4162e10ed7a7ea30527f2cbd92e6999c10a8ed8edb253836e9c/scipy-1.15.3-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:6ac6310fdbfb7aa6612408bd2f07295bcbd3fda00d2d702178434751fe48e019", size = 38766735, upload-time = "2025-05-08T16:06:06.471Z" }, 3079 - { url = "https://files.pythonhosted.org/packages/7b/7e/f30be3d03de07f25dc0ec926d1681fed5c732d759ac8f51079708c79e680/scipy-1.15.3-cp312-cp312-macosx_12_0_arm64.whl", hash = "sha256:185cd3d6d05ca4b44a8f1595af87f9c372bb6acf9c808e99aa3e9aa03bd98cf6", size = 30173284, upload-time = "2025-05-08T16:06:11.686Z" }, 3080 - { url = "https://files.pythonhosted.org/packages/07/9c/0ddb0d0abdabe0d181c1793db51f02cd59e4901da6f9f7848e1f96759f0d/scipy-1.15.3-cp312-cp312-macosx_14_0_arm64.whl", hash = "sha256:05dc6abcd105e1a29f95eada46d4a3f251743cfd7d3ae8ddb4088047f24ea477", size = 22446958, upload-time = "2025-05-08T16:06:15.97Z" }, 3081 - { url = "https://files.pythonhosted.org/packages/af/43/0bce905a965f36c58ff80d8bea33f1f9351b05fad4beaad4eae34699b7a1/scipy-1.15.3-cp312-cp312-macosx_14_0_x86_64.whl", hash = "sha256:06efcba926324df1696931a57a176c80848ccd67ce6ad020c810736bfd58eb1c", size = 25242454, upload-time = "2025-05-08T16:06:20.394Z" }, 3082 - { url = "https://files.pythonhosted.org/packages/56/30/a6f08f84ee5b7b28b4c597aca4cbe545535c39fe911845a96414700b64ba/scipy-1.15.3-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c05045d8b9bfd807ee1b9f38761993297b10b245f012b11b13b91ba8945f7e45", size = 35210199, upload-time = "2025-05-08T16:06:26.159Z" }, 3083 - { url = "https://files.pythonhosted.org/packages/0b/1f/03f52c282437a168ee2c7c14a1a0d0781a9a4a8962d84ac05c06b4c5b555/scipy-1.15.3-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:271e3713e645149ea5ea3e97b57fdab61ce61333f97cfae392c28ba786f9bb49", size = 37309455, upload-time = "2025-05-08T16:06:32.778Z" }, 3084 - { url = "https://files.pythonhosted.org/packages/89/b1/fbb53137f42c4bf630b1ffdfc2151a62d1d1b903b249f030d2b1c0280af8/scipy-1.15.3-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:6cfd56fc1a8e53f6e89ba3a7a7251f7396412d655bca2aa5611c8ec9a6784a1e", size = 36885140, upload-time = "2025-05-08T16:06:39.249Z" }, 3085 - { url = "https://files.pythonhosted.org/packages/2e/2e/025e39e339f5090df1ff266d021892694dbb7e63568edcfe43f892fa381d/scipy-1.15.3-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:0ff17c0bb1cb32952c09217d8d1eed9b53d1463e5f1dd6052c7857f83127d539", size = 39710549, upload-time = "2025-05-08T16:06:45.729Z" }, 3086 - { url = "https://files.pythonhosted.org/packages/e6/eb/3bf6ea8ab7f1503dca3a10df2e4b9c3f6b3316df07f6c0ded94b281c7101/scipy-1.15.3-cp312-cp312-win_amd64.whl", hash = "sha256:52092bc0472cfd17df49ff17e70624345efece4e1a12b23783a1ac59a1b728ed", size = 40966184, upload-time = "2025-05-08T16:06:52.623Z" }, 3087 - { url = "https://files.pythonhosted.org/packages/73/18/ec27848c9baae6e0d6573eda6e01a602e5649ee72c27c3a8aad673ebecfd/scipy-1.15.3-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:2c620736bcc334782e24d173c0fdbb7590a0a436d2fdf39310a8902505008759", size = 38728256, upload-time = "2025-05-08T16:06:58.696Z" }, 3088 - { url = "https://files.pythonhosted.org/packages/74/cd/1aef2184948728b4b6e21267d53b3339762c285a46a274ebb7863c9e4742/scipy-1.15.3-cp313-cp313-macosx_12_0_arm64.whl", hash = "sha256:7e11270a000969409d37ed399585ee530b9ef6aa99d50c019de4cb01e8e54e62", size = 30109540, upload-time = "2025-05-08T16:07:04.209Z" }, 3089 - { url = "https://files.pythonhosted.org/packages/5b/d8/59e452c0a255ec352bd0a833537a3bc1bfb679944c4938ab375b0a6b3a3e/scipy-1.15.3-cp313-cp313-macosx_14_0_arm64.whl", hash = "sha256:8c9ed3ba2c8a2ce098163a9bdb26f891746d02136995df25227a20e71c396ebb", size = 22383115, upload-time = "2025-05-08T16:07:08.998Z" }, 3090 - { url = "https://files.pythonhosted.org/packages/08/f5/456f56bbbfccf696263b47095291040655e3cbaf05d063bdc7c7517f32ac/scipy-1.15.3-cp313-cp313-macosx_14_0_x86_64.whl", hash = "sha256:0bdd905264c0c9cfa74a4772cdb2070171790381a5c4d312c973382fc6eaf730", size = 25163884, upload-time = "2025-05-08T16:07:14.091Z" }, 3091 - { url = "https://files.pythonhosted.org/packages/a2/66/a9618b6a435a0f0c0b8a6d0a2efb32d4ec5a85f023c2b79d39512040355b/scipy-1.15.3-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:79167bba085c31f38603e11a267d862957cbb3ce018d8b38f79ac043bc92d825", size = 35174018, upload-time = "2025-05-08T16:07:19.427Z" }, 3092 - { url = "https://files.pythonhosted.org/packages/b5/09/c5b6734a50ad4882432b6bb7c02baf757f5b2f256041da5df242e2d7e6b6/scipy-1.15.3-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c9deabd6d547aee2c9a81dee6cc96c6d7e9a9b1953f74850c179f91fdc729cb7", size = 37269716, upload-time = "2025-05-08T16:07:25.712Z" }, 3093 - { url = "https://files.pythonhosted.org/packages/77/0a/eac00ff741f23bcabd352731ed9b8995a0a60ef57f5fd788d611d43d69a1/scipy-1.15.3-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:dde4fc32993071ac0c7dd2d82569e544f0bdaff66269cb475e0f369adad13f11", size = 36872342, upload-time = "2025-05-08T16:07:31.468Z" }, 3094 - { url = "https://files.pythonhosted.org/packages/fe/54/4379be86dd74b6ad81551689107360d9a3e18f24d20767a2d5b9253a3f0a/scipy-1.15.3-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:f77f853d584e72e874d87357ad70f44b437331507d1c311457bed8ed2b956126", size = 39670869, upload-time = "2025-05-08T16:07:38.002Z" }, 3095 - { url = "https://files.pythonhosted.org/packages/87/2e/892ad2862ba54f084ffe8cc4a22667eaf9c2bcec6d2bff1d15713c6c0703/scipy-1.15.3-cp313-cp313-win_amd64.whl", hash = "sha256:b90ab29d0c37ec9bf55424c064312930ca5f4bde15ee8619ee44e69319aab163", size = 40988851, upload-time = "2025-05-08T16:08:33.671Z" }, 3096 - { url = "https://files.pythonhosted.org/packages/1b/e9/7a879c137f7e55b30d75d90ce3eb468197646bc7b443ac036ae3fe109055/scipy-1.15.3-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:3ac07623267feb3ae308487c260ac684b32ea35fd81e12845039952f558047b8", size = 38863011, upload-time = "2025-05-08T16:07:44.039Z" }, 3097 - { url = "https://files.pythonhosted.org/packages/51/d1/226a806bbd69f62ce5ef5f3ffadc35286e9fbc802f606a07eb83bf2359de/scipy-1.15.3-cp313-cp313t-macosx_12_0_arm64.whl", hash = "sha256:6487aa99c2a3d509a5227d9a5e889ff05830a06b2ce08ec30df6d79db5fcd5c5", size = 30266407, upload-time = "2025-05-08T16:07:49.891Z" }, 3098 - { url = "https://files.pythonhosted.org/packages/e5/9b/f32d1d6093ab9eeabbd839b0f7619c62e46cc4b7b6dbf05b6e615bbd4400/scipy-1.15.3-cp313-cp313t-macosx_14_0_arm64.whl", hash = "sha256:50f9e62461c95d933d5c5ef4a1f2ebf9a2b4e83b0db374cb3f1de104d935922e", size = 22540030, upload-time = "2025-05-08T16:07:54.121Z" }, 3099 - { url = "https://files.pythonhosted.org/packages/e7/29/c278f699b095c1a884f29fda126340fcc201461ee8bfea5c8bdb1c7c958b/scipy-1.15.3-cp313-cp313t-macosx_14_0_x86_64.whl", hash = "sha256:14ed70039d182f411ffc74789a16df3835e05dc469b898233a245cdfd7f162cb", size = 25218709, upload-time = "2025-05-08T16:07:58.506Z" }, 3100 - { url = "https://files.pythonhosted.org/packages/24/18/9e5374b617aba742a990581373cd6b68a2945d65cc588482749ef2e64467/scipy-1.15.3-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0a769105537aa07a69468a0eefcd121be52006db61cdd8cac8a0e68980bbb723", size = 34809045, upload-time = "2025-05-08T16:08:03.929Z" }, 3101 - { url = "https://files.pythonhosted.org/packages/e1/fe/9c4361e7ba2927074360856db6135ef4904d505e9b3afbbcb073c4008328/scipy-1.15.3-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9db984639887e3dffb3928d118145ffe40eff2fa40cb241a306ec57c219ebbbb", size = 36703062, upload-time = "2025-05-08T16:08:09.558Z" }, 3102 - { url = "https://files.pythonhosted.org/packages/b7/8e/038ccfe29d272b30086b25a4960f757f97122cb2ec42e62b460d02fe98e9/scipy-1.15.3-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:40e54d5c7e7ebf1aa596c374c49fa3135f04648a0caabcb66c52884b943f02b4", size = 36393132, upload-time = "2025-05-08T16:08:15.34Z" }, 3103 - { url = "https://files.pythonhosted.org/packages/10/7e/5c12285452970be5bdbe8352c619250b97ebf7917d7a9a9e96b8a8140f17/scipy-1.15.3-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:5e721fed53187e71d0ccf382b6bf977644c533e506c4d33c3fb24de89f5c3ed5", size = 38979503, upload-time = "2025-05-08T16:08:21.513Z" }, 3104 - { url = "https://files.pythonhosted.org/packages/81/06/0a5e5349474e1cbc5757975b21bd4fad0e72ebf138c5592f191646154e06/scipy-1.15.3-cp313-cp313t-win_amd64.whl", hash = "sha256:76ad1fb5f8752eabf0fa02e4cc0336b4e8f021e2d5f061ed37d6d264db35e3ca", size = 40308097, upload-time = "2025-05-08T16:08:27.627Z" }, 3105 - ] 3106 - 3107 - [[package]] 3108 - name = "scipy" 3109 2506 version = "1.17.1" 3110 2507 source = { registry = "https://pypi.org/simple" } 3111 - resolution-markers = [ 3112 - "python_full_version >= '3.14' and platform_machine != 's390x' and sys_platform == 'win32'", 3113 - "python_full_version >= '3.14' and platform_machine != 's390x' and sys_platform == 'emscripten'", 3114 - "python_full_version >= '3.14' and platform_machine != 's390x' and sys_platform != 'emscripten' and sys_platform != 'win32'", 3115 - "python_full_version == '3.13.*' and platform_machine != 's390x' and sys_platform == 'win32'", 3116 - "python_full_version == '3.13.*' and platform_machine != 's390x' and sys_platform == 'emscripten'", 3117 - "python_full_version == '3.13.*' and platform_machine != 's390x' and sys_platform != 'emscripten' and sys_platform != 'win32'", 3118 - "python_full_version >= '3.14' and platform_machine == 's390x' and sys_platform == 'win32'", 3119 - "python_full_version >= '3.14' and platform_machine == 's390x' and sys_platform == 'emscripten'", 3120 - "python_full_version >= '3.14' and platform_machine == 's390x' and sys_platform != 'emscripten' and sys_platform != 'win32'", 3121 - "python_full_version == '3.13.*' and platform_machine == 's390x' and sys_platform == 'win32'", 3122 - "python_full_version == '3.13.*' and platform_machine == 's390x' and sys_platform == 'emscripten'", 3123 - "python_full_version == '3.13.*' and platform_machine == 's390x' and sys_platform != 'emscripten' and sys_platform != 'win32'", 3124 - "python_full_version == '3.12.*' and platform_machine != 's390x' and sys_platform == 'win32'", 3125 - "python_full_version == '3.12.*' and platform_machine != 's390x' and sys_platform == 'emscripten'", 3126 - "python_full_version == '3.12.*' and platform_machine != 's390x' and sys_platform != 'emscripten' and sys_platform != 'win32'", 3127 - "python_full_version == '3.12.*' and platform_machine == 's390x' and sys_platform == 'win32'", 3128 - "python_full_version == '3.12.*' and platform_machine == 's390x' and sys_platform == 'emscripten'", 3129 - "python_full_version == '3.12.*' and platform_machine == 's390x' and sys_platform != 'emscripten' and sys_platform != 'win32'", 3130 - "python_full_version == '3.11.*' and platform_machine != 's390x' and sys_platform == 'win32'", 3131 - "python_full_version == '3.11.*' and platform_machine != 's390x' and sys_platform == 'emscripten'", 3132 - "python_full_version == '3.11.*' and platform_machine != 's390x' and sys_platform != 'emscripten' and sys_platform != 'win32'", 3133 - "python_full_version == '3.11.*' and platform_machine == 's390x' and sys_platform == 'win32'", 3134 - "python_full_version == '3.11.*' and platform_machine == 's390x' and sys_platform == 'emscripten'", 3135 - "python_full_version == '3.11.*' and platform_machine == 's390x' and sys_platform != 'emscripten' and sys_platform != 'win32'", 3136 - ] 3137 2508 dependencies = [ 3138 - { name = "numpy", version = "2.3.5", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.11'" }, 2509 + { name = "numpy" }, 3139 2510 ] 3140 2511 sdist = { url = "https://files.pythonhosted.org/packages/7a/97/5a3609c4f8d58b039179648e62dd220f89864f56f7357f5d4f45c29eb2cc/scipy-1.17.1.tar.gz", hash = "sha256:95d8e012d8cb8816c226aef832200b1d45109ed4464303e997c5b13122b297c0", size = 30573822, upload-time = "2026-02-23T00:26:24.851Z" } 3141 2512 wheels = [ ··· 3207 2578 source = { registry = "https://pypi.org/simple" } 3208 2579 sdist = { url = "https://files.pythonhosted.org/packages/8d/48/49393a96a2eef1ab418b17475fb92b8fcfad83d099e678751b05472e69de/setproctitle-1.3.7.tar.gz", hash = "sha256:bc2bc917691c1537d5b9bca1468437176809c7e11e5694ca79a9ca12345dcb9e", size = 27002, upload-time = "2025-09-05T12:51:25.278Z" } 3209 2580 wheels = [ 3210 - { url = "https://files.pythonhosted.org/packages/f2/48/fb401ec8c4953d519d05c87feca816ad668b8258448ff60579ac7a1c1386/setproctitle-1.3.7-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:cf555b6299f10a6eb44e4f96d2f5a3884c70ce25dc5c8796aaa2f7b40e72cb1b", size = 18079, upload-time = "2025-09-05T12:49:07.732Z" }, 3211 - { url = "https://files.pythonhosted.org/packages/cc/a3/c2b0333c2716fb3b4c9a973dd113366ac51b4f8d56b500f4f8f704b4817a/setproctitle-1.3.7-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:690b4776f9c15aaf1023bb07d7c5b797681a17af98a4a69e76a1d504e41108b7", size = 13099, upload-time = "2025-09-05T12:49:09.222Z" }, 3212 - { url = "https://files.pythonhosted.org/packages/0e/f8/17bda581c517678260e6541b600eeb67745f53596dc077174141ba2f6702/setproctitle-1.3.7-cp310-cp310-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:00afa6fc507967d8c9d592a887cdc6c1f5742ceac6a4354d111ca0214847732c", size = 31793, upload-time = "2025-09-05T12:49:10.297Z" }, 3213 - { url = "https://files.pythonhosted.org/packages/27/d1/76a33ae80d4e788ecab9eb9b53db03e81cfc95367ec7e3fbf4989962fedd/setproctitle-1.3.7-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:9e02667f6b9fc1238ba753c0f4b0a37ae184ce8f3bbbc38e115d99646b3f4cd3", size = 32779, upload-time = "2025-09-05T12:49:12.157Z" }, 3214 - { url = "https://files.pythonhosted.org/packages/59/27/1a07c38121967061564f5e0884414a5ab11a783260450172d4fc68c15621/setproctitle-1.3.7-cp310-cp310-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:83fcd271567d133eb9532d3b067c8a75be175b2b3b271e2812921a05303a693f", size = 34578, upload-time = "2025-09-05T12:49:13.393Z" }, 3215 - { url = "https://files.pythonhosted.org/packages/d8/d4/725e6353935962d8bb12cbf7e7abba1d0d738c7f6935f90239d8e1ccf913/setproctitle-1.3.7-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:13fe37951dda1a45c35d77d06e3da5d90e4f875c4918a7312b3b4556cfa7ff64", size = 32030, upload-time = "2025-09-05T12:49:15.362Z" }, 3216 - { url = "https://files.pythonhosted.org/packages/67/24/e4677ae8e1cb0d549ab558b12db10c175a889be0974c589c428fece5433e/setproctitle-1.3.7-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:a05509cfb2059e5d2ddff701d38e474169e9ce2a298cf1b6fd5f3a213a553fe5", size = 33363, upload-time = "2025-09-05T12:49:16.829Z" }, 3217 - { url = "https://files.pythonhosted.org/packages/55/d4/69ce66e4373a48fdbb37489f3ded476bb393e27f514968c3a69a67343ae0/setproctitle-1.3.7-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:6da835e76ae18574859224a75db6e15c4c2aaa66d300a57efeaa4c97ca4c7381", size = 31508, upload-time = "2025-09-05T12:49:18.032Z" }, 3218 - { url = "https://files.pythonhosted.org/packages/4b/5a/42c1ed0e9665d068146a68326529b5686a1881c8b9197c2664db4baf6aeb/setproctitle-1.3.7-cp310-cp310-win32.whl", hash = "sha256:9e803d1b1e20240a93bac0bc1025363f7f80cb7eab67dfe21efc0686cc59ad7c", size = 12558, upload-time = "2025-09-05T12:49:19.742Z" }, 3219 - { url = "https://files.pythonhosted.org/packages/dc/fe/dd206cc19a25561921456f6cb12b405635319299b6f366e0bebe872abc18/setproctitle-1.3.7-cp310-cp310-win_amd64.whl", hash = "sha256:a97200acc6b64ec4cada52c2ecaf1fba1ef9429ce9c542f8a7db5bcaa9dcbd95", size = 13245, upload-time = "2025-09-05T12:49:21.023Z" }, 3220 2581 { url = "https://files.pythonhosted.org/packages/04/cd/1b7ba5cad635510720ce19d7122154df96a2387d2a74217be552887c93e5/setproctitle-1.3.7-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:a600eeb4145fb0ee6c287cb82a2884bd4ec5bbb076921e287039dcc7b7cc6dd0", size = 18085, upload-time = "2025-09-05T12:49:22.183Z" }, 3221 2582 { url = "https://files.pythonhosted.org/packages/8f/1a/b2da0a620490aae355f9d72072ac13e901a9fec809a6a24fc6493a8f3c35/setproctitle-1.3.7-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:97a090fed480471bb175689859532709e28c085087e344bca45cf318034f70c4", size = 13097, upload-time = "2025-09-05T12:49:23.322Z" }, 3222 2583 { url = "https://files.pythonhosted.org/packages/18/2e/bd03ff02432a181c1787f6fc2a678f53b7dacdd5ded69c318fe1619556e8/setproctitle-1.3.7-cp311-cp311-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:1607b963e7b53e24ec8a2cb4e0ab3ae591d7c6bf0a160feef0551da63452b37f", size = 32191, upload-time = "2025-09-05T12:49:24.567Z" }, ··· 3277 2638 { url = "https://files.pythonhosted.org/packages/e7/e3/54b496ac724e60e61cc3447f02690105901ca6d90da0377dffe49ff99fc7/setproctitle-1.3.7-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:1fae595d032b30dab4d659bece20debd202229fce12b55abab978b7f30783d73", size = 33958, upload-time = "2025-09-05T12:50:39.841Z" }, 3278 2639 { url = "https://files.pythonhosted.org/packages/ea/a8/c84bb045ebf8c6fdc7f7532319e86f8380d14bbd3084e6348df56bdfe6fd/setproctitle-1.3.7-cp314-cp314t-win32.whl", hash = "sha256:02432f26f5d1329ab22279ff863c83589894977063f59e6c4b4845804a08f8c2", size = 12745, upload-time = "2025-09-05T12:50:41.377Z" }, 3279 2640 { url = "https://files.pythonhosted.org/packages/08/b6/3a5a4f9952972791a9114ac01dfc123f0df79903577a3e0a7a404a695586/setproctitle-1.3.7-cp314-cp314t-win_amd64.whl", hash = "sha256:cbc388e3d86da1f766d8fc2e12682e446064c01cea9f88a88647cfe7c011de6a", size = 13469, upload-time = "2025-09-05T12:50:42.67Z" }, 3280 - { url = "https://files.pythonhosted.org/packages/34/8a/aff5506ce89bc3168cb492b18ba45573158d528184e8a9759a05a09088a9/setproctitle-1.3.7-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:eb440c5644a448e6203935ed60466ec8d0df7278cd22dc6cf782d07911bcbea6", size = 12654, upload-time = "2025-09-05T12:51:17.141Z" }, 3281 - { url = "https://files.pythonhosted.org/packages/41/89/5b6f2faedd6ced3d3c085a5efbd91380fb1f61f4c12bc42acad37932f4e9/setproctitle-1.3.7-pp310-pypy310_pp73-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:502b902a0e4c69031b87870ff4986c290ebbb12d6038a70639f09c331b18efb2", size = 14284, upload-time = "2025-09-05T12:51:18.393Z" }, 3282 - { url = "https://files.pythonhosted.org/packages/0a/c0/4312fed3ca393a29589603fd48f17937b4ed0638b923bac75a728382e730/setproctitle-1.3.7-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:f6f268caeabb37ccd824d749e7ce0ec6337c4ed954adba33ec0d90cc46b0ab78", size = 13282, upload-time = "2025-09-05T12:51:19.703Z" }, 3283 2641 { url = "https://files.pythonhosted.org/packages/c3/5b/5e1c117ac84e3cefcf8d7a7f6b2461795a87e20869da065a5c087149060b/setproctitle-1.3.7-pp311-pypy311_pp73-macosx_11_0_arm64.whl", hash = "sha256:b1cac6a4b0252b8811d60b6d8d0f157c0fdfed379ac89c25a914e6346cf355a1", size = 12587, upload-time = "2025-09-05T12:51:21.195Z" }, 3284 2642 { url = "https://files.pythonhosted.org/packages/73/02/b9eadc226195dcfa90eed37afe56b5dd6fa2f0e5220ab8b7867b8862b926/setproctitle-1.3.7-pp311-pypy311_pp73-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:f1704c9e041f2b1dc38f5be4552e141e1432fba3dd52c72eeffd5bc2db04dc65", size = 14286, upload-time = "2025-09-05T12:51:22.61Z" }, 3285 2643 { url = "https://files.pythonhosted.org/packages/28/26/1be1d2a53c2a91ec48fa2ff4a409b395f836798adf194d99de9c059419ea/setproctitle-1.3.7-pp311-pypy311_pp73-win_amd64.whl", hash = "sha256:b08b61976ffa548bd5349ce54404bf6b2d51bd74d4f1b241ed1b0f25bce09c3a", size = 13282, upload-time = "2025-09-05T12:51:24.094Z" }, ··· 3356 2714 { name = "markdown" }, 3357 2715 { name = "mistune" }, 3358 2716 { name = "mypy" }, 3359 - { name = "numpy", version = "2.2.6", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.11'" }, 3360 - { name = "numpy", version = "2.3.5", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.11'" }, 3361 - { name = "onnxruntime", version = "1.24.3", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.11' and sys_platform == 'darwin'" }, 3362 - { name = "onnxruntime", version = "1.25.0", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.11' and sys_platform == 'darwin'" }, 2717 + { name = "numpy" }, 2718 + { name = "onnxruntime", marker = "sys_platform == 'darwin'" }, 3363 2719 { name = "openai" }, 3364 2720 { name = "opencv-python-headless" }, 3365 2721 { name = "pdf2image" }, ··· 3378 2734 { name = "rapidfuzz" }, 3379 2735 { name = "requests" }, 3380 2736 { name = "ruff" }, 3381 - { name = "scikit-learn", version = "1.7.2", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.11'" }, 3382 - { name = "scikit-learn", version = "1.8.0", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.11'" }, 2737 + { name = "scikit-learn" }, 3383 2738 { name = "setproctitle" }, 3384 2739 { name = "soundfile" }, 3385 2740 { name = "timefhuman" }, ··· 3394 2749 parakeet-onnx-cpu = [ 3395 2750 { name = "huggingface-hub" }, 3396 2751 { name = "onnx-asr" }, 3397 - { name = "onnxruntime", version = "1.24.3", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.11'" }, 3398 - { name = "onnxruntime", version = "1.25.0", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.11'" }, 2752 + { name = "onnxruntime" }, 3399 2753 ] 3400 2754 parakeet-onnx-cuda = [ 3401 2755 { name = "huggingface-hub" }, ··· 3407 2761 { name = "nvidia-curand-cu12" }, 3408 2762 { name = "nvidia-nvjitlink-cu12" }, 3409 2763 { name = "onnx-asr" }, 3410 - { name = "onnxruntime-gpu", version = "1.24.3", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.11'" }, 3411 - { name = "onnxruntime-gpu", version = "1.25.0", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.11'" }, 2764 + { name = "onnxruntime-gpu" }, 3412 2765 ] 3413 2766 3414 2767 [package.metadata] ··· 3443 2796 { name = "nvidia-nvjitlink-cu12", marker = "extra == 'parakeet-onnx-cuda'" }, 3444 2797 { name = "onnx-asr", marker = "extra == 'parakeet-onnx-cpu'", specifier = ">=0.11.0" }, 3445 2798 { name = "onnx-asr", marker = "extra == 'parakeet-onnx-cuda'", specifier = ">=0.11.0" }, 3446 - { name = "onnxruntime", marker = "python_full_version >= '3.11' and extra == 'parakeet-onnx-cpu'", specifier = ">=1.25.0" }, 3447 - { name = "onnxruntime", marker = "python_full_version < '3.11' and extra == 'parakeet-onnx-cpu'", specifier = ">=1.20.0,!=1.24.1,<1.25.0" }, 3448 2799 { name = "onnxruntime", marker = "sys_platform == 'darwin'", specifier = ">=1.20.0,!=1.24.1" }, 3449 - { name = "onnxruntime-gpu", marker = "python_full_version >= '3.11' and extra == 'parakeet-onnx-cuda'", specifier = ">=1.25.0" }, 3450 - { name = "onnxruntime-gpu", marker = "python_full_version < '3.11' and extra == 'parakeet-onnx-cuda'", specifier = ">=1.20.0,!=1.24.1,<1.25.0" }, 2800 + { name = "onnxruntime", marker = "extra == 'parakeet-onnx-cpu'", specifier = ">=1.25.0" }, 2801 + { name = "onnxruntime-gpu", marker = "extra == 'parakeet-onnx-cuda'", specifier = ">=1.25.0" }, 3451 2802 { name = "openai", specifier = ">=1.2.0" }, 3452 2803 { name = "opencv-python-headless" }, 3453 2804 { name = "pdf2image" }, ··· 3484 2835 source = { registry = "https://pypi.org/simple" } 3485 2836 dependencies = [ 3486 2837 { name = "cffi" }, 3487 - { name = "numpy", version = "2.2.6", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.11'" }, 3488 - { name = "numpy", version = "2.3.5", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.11'" }, 2838 + { name = "numpy" }, 3489 2839 ] 3490 2840 sdist = { url = "https://files.pythonhosted.org/packages/e1/41/9b873a8c055582859b239be17902a85339bec6a30ad162f98c9b0288a2cc/soundfile-0.13.1.tar.gz", hash = "sha256:b2c68dab1e30297317080a5b43df57e302584c49e2942defdde0acccc53f0e5b", size = 46156, upload-time = "2025-01-25T09:17:04.831Z" } 3491 2841 wheels = [ ··· 3499 2849 ] 3500 2850 3501 2851 [[package]] 3502 - name = "sympy" 3503 - version = "1.14.0" 3504 - source = { registry = "https://pypi.org/simple" } 3505 - dependencies = [ 3506 - { name = "mpmath", marker = "python_full_version < '3.11'" }, 3507 - ] 3508 - sdist = { url = "https://files.pythonhosted.org/packages/83/d3/803453b36afefb7c2bb238361cd4ae6125a569b4db67cd9e79846ba2d68c/sympy-1.14.0.tar.gz", hash = "sha256:d3d3fe8df1e5a0b42f0e7bdf50541697dbe7d23746e894990c030e2b05e72517", size = 7793921, upload-time = "2025-04-27T18:05:01.611Z" } 3509 - wheels = [ 3510 - { url = "https://files.pythonhosted.org/packages/a2/09/77d55d46fd61b4a135c444fc97158ef34a095e5681d0a6c10b75bf356191/sympy-1.14.0-py3-none-any.whl", hash = "sha256:e091cc3e99d2141a0ba2847328f5479b05d94a6635cb96148ccb3f34671bd8f5", size = 6299353, upload-time = "2025-04-27T18:04:59.103Z" }, 3511 - ] 3512 - 3513 - [[package]] 3514 2852 name = "tenacity" 3515 2853 version = "9.1.4" 3516 2854 source = { registry = "https://pypi.org/simple" } ··· 3600 2938 { url = "https://files.pythonhosted.org/packages/fd/18/a545c4ea42af3df6effd7d13d250ba77a0a86fb20393143bbb9a92e434d4/tokenizers-0.22.2-cp39-abi3-win32.whl", hash = "sha256:a6bf3f88c554a2b653af81f3204491c818ae2ac6fbc09e76ef4773351292bc92", size = 2502363, upload-time = "2026-01-05T10:45:20.593Z" }, 3601 2939 { url = "https://files.pythonhosted.org/packages/65/71/0670843133a43d43070abeb1949abfdef12a86d490bea9cd9e18e37c5ff7/tokenizers-0.22.2-cp39-abi3-win_amd64.whl", hash = "sha256:c9ea31edff2968b44a88f97d784c2f16dc0729b8b143ed004699ebca91f05c48", size = 2747786, upload-time = "2026-01-05T10:45:18.411Z" }, 3602 2940 { url = "https://files.pythonhosted.org/packages/72/f4/0de46cfa12cdcbcd464cc59fde36912af405696f687e53a091fb432f694c/tokenizers-0.22.2-cp39-abi3-win_arm64.whl", hash = "sha256:9ce725d22864a1e965217204946f830c37876eee3b2ba6fc6255e8e903d5fcbc", size = 2612133, upload-time = "2026-01-05T10:45:17.232Z" }, 3603 - { url = "https://files.pythonhosted.org/packages/84/04/655b79dbcc9b3ac5f1479f18e931a344af67e5b7d3b251d2dcdcd7558592/tokenizers-0.22.2-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:753d47ebd4542742ef9261d9da92cd545b2cacbb48349a1225466745bb866ec4", size = 3282301, upload-time = "2026-01-05T10:40:34.858Z" }, 3604 - { url = "https://files.pythonhosted.org/packages/46/cd/e4851401f3d8f6f45d8480262ab6a5c8cb9c4302a790a35aa14eeed6d2fd/tokenizers-0.22.2-pp310-pypy310_pp73-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:e10bf9113d209be7cd046d40fbabbaf3278ff6d18eb4da4c500443185dc1896c", size = 3161308, upload-time = "2026-01-05T10:40:40.737Z" }, 3605 - { url = "https://files.pythonhosted.org/packages/6f/6e/55553992a89982cd12d4a66dddb5e02126c58677ea3931efcbe601d419db/tokenizers-0.22.2-pp310-pypy310_pp73-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:64d94e84f6660764e64e7e0b22baa72f6cd942279fdbb21d46abd70d179f0195", size = 3718964, upload-time = "2026-01-05T10:40:46.56Z" }, 3606 - { url = "https://files.pythonhosted.org/packages/59/8c/b1c87148aa15e099243ec9f0cf9d0e970cc2234c3257d558c25a2c5304e6/tokenizers-0.22.2-pp310-pypy310_pp73-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f01a9c019878532f98927d2bacb79bbb404b43d3437455522a00a30718cdedb5", size = 3373542, upload-time = "2026-01-05T10:40:52.803Z" }, 3607 2941 ] 3608 2942 3609 2943 [[package]] ··· 3793 3127 source = { registry = "https://pypi.org/simple" } 3794 3128 sdist = { url = "https://files.pythonhosted.org/packages/21/e6/26d09fab466b7ca9c7737474c52be4f76a40301b08362eb2dbc19dcc16c1/websockets-15.0.1.tar.gz", hash = "sha256:82544de02076bafba038ce055ee6412d68da13ab47f0c60cab827346de828dee", size = 177016, upload-time = "2025-03-05T20:03:41.606Z" } 3795 3129 wheels = [ 3796 - { url = "https://files.pythonhosted.org/packages/1e/da/6462a9f510c0c49837bbc9345aca92d767a56c1fb2939e1579df1e1cdcf7/websockets-15.0.1-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:d63efaa0cd96cf0c5fe4d581521d9fa87744540d4bc999ae6e08595a1014b45b", size = 175423, upload-time = "2025-03-05T20:01:35.363Z" }, 3797 - { url = "https://files.pythonhosted.org/packages/1c/9f/9d11c1a4eb046a9e106483b9ff69bce7ac880443f00e5ce64261b47b07e7/websockets-15.0.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:ac60e3b188ec7574cb761b08d50fcedf9d77f1530352db4eef1707fe9dee7205", size = 173080, upload-time = "2025-03-05T20:01:37.304Z" }, 3798 - { url = "https://files.pythonhosted.org/packages/d5/4f/b462242432d93ea45f297b6179c7333dd0402b855a912a04e7fc61c0d71f/websockets-15.0.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:5756779642579d902eed757b21b0164cd6fe338506a8083eb58af5c372e39d9a", size = 173329, upload-time = "2025-03-05T20:01:39.668Z" }, 3799 - { url = "https://files.pythonhosted.org/packages/6e/0c/6afa1f4644d7ed50284ac59cc70ef8abd44ccf7d45850d989ea7310538d0/websockets-15.0.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0fdfe3e2a29e4db3659dbd5bbf04560cea53dd9610273917799f1cde46aa725e", size = 182312, upload-time = "2025-03-05T20:01:41.815Z" }, 3800 - { url = "https://files.pythonhosted.org/packages/dd/d4/ffc8bd1350b229ca7a4db2a3e1c482cf87cea1baccd0ef3e72bc720caeec/websockets-15.0.1-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4c2529b320eb9e35af0fa3016c187dffb84a3ecc572bcee7c3ce302bfeba52bf", size = 181319, upload-time = "2025-03-05T20:01:43.967Z" }, 3801 - { url = "https://files.pythonhosted.org/packages/97/3a/5323a6bb94917af13bbb34009fac01e55c51dfde354f63692bf2533ffbc2/websockets-15.0.1-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ac1e5c9054fe23226fb11e05a6e630837f074174c4c2f0fe442996112a6de4fb", size = 181631, upload-time = "2025-03-05T20:01:46.104Z" }, 3802 - { url = "https://files.pythonhosted.org/packages/a6/cc/1aeb0f7cee59ef065724041bb7ed667b6ab1eeffe5141696cccec2687b66/websockets-15.0.1-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:5df592cd503496351d6dc14f7cdad49f268d8e618f80dce0cd5a36b93c3fc08d", size = 182016, upload-time = "2025-03-05T20:01:47.603Z" }, 3803 - { url = "https://files.pythonhosted.org/packages/79/f9/c86f8f7af208e4161a7f7e02774e9d0a81c632ae76db2ff22549e1718a51/websockets-15.0.1-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:0a34631031a8f05657e8e90903e656959234f3a04552259458aac0b0f9ae6fd9", size = 181426, upload-time = "2025-03-05T20:01:48.949Z" }, 3804 - { url = "https://files.pythonhosted.org/packages/c7/b9/828b0bc6753db905b91df6ae477c0b14a141090df64fb17f8a9d7e3516cf/websockets-15.0.1-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:3d00075aa65772e7ce9e990cab3ff1de702aa09be3940d1dc88d5abf1ab8a09c", size = 181360, upload-time = "2025-03-05T20:01:50.938Z" }, 3805 - { url = "https://files.pythonhosted.org/packages/89/fb/250f5533ec468ba6327055b7d98b9df056fb1ce623b8b6aaafb30b55d02e/websockets-15.0.1-cp310-cp310-win32.whl", hash = "sha256:1234d4ef35db82f5446dca8e35a7da7964d02c127b095e172e54397fb6a6c256", size = 176388, upload-time = "2025-03-05T20:01:52.213Z" }, 3806 - { url = "https://files.pythonhosted.org/packages/1c/46/aca7082012768bb98e5608f01658ff3ac8437e563eca41cf068bd5849a5e/websockets-15.0.1-cp310-cp310-win_amd64.whl", hash = "sha256:39c1fec2c11dc8d89bba6b2bf1556af381611a173ac2b511cf7231622058af41", size = 176830, upload-time = "2025-03-05T20:01:53.922Z" }, 3807 3130 { url = "https://files.pythonhosted.org/packages/9f/32/18fcd5919c293a398db67443acd33fde142f283853076049824fc58e6f75/websockets-15.0.1-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:823c248b690b2fd9303ba00c4f66cd5e2d8c3ba4aa968b2779be9532a4dad431", size = 175423, upload-time = "2025-03-05T20:01:56.276Z" }, 3808 3131 { url = "https://files.pythonhosted.org/packages/76/70/ba1ad96b07869275ef42e2ce21f07a5b0148936688c2baf7e4a1f60d5058/websockets-15.0.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:678999709e68425ae2593acf2e3ebcbcf2e69885a5ee78f9eb80e6e371f1bf57", size = 173082, upload-time = "2025-03-05T20:01:57.563Z" }, 3809 3132 { url = "https://files.pythonhosted.org/packages/86/f2/10b55821dd40eb696ce4704a87d57774696f9451108cff0d2824c97e0f97/websockets-15.0.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:d50fd1ee42388dcfb2b3676132c78116490976f1300da28eb629272d5d93e905", size = 173330, upload-time = "2025-03-05T20:01:59.063Z" }, ··· 3837 3160 { url = "https://files.pythonhosted.org/packages/33/2b/1f168cb6041853eef0362fb9554c3824367c5560cbdaad89ac40f8c2edfc/websockets-15.0.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:558d023b3df0bffe50a04e710bc87742de35060580a293c2a984299ed83bc4e4", size = 182195, upload-time = "2025-03-05T20:02:51.561Z" }, 3838 3161 { url = "https://files.pythonhosted.org/packages/86/eb/20b6cdf273913d0ad05a6a14aed4b9a85591c18a987a3d47f20fa13dcc47/websockets-15.0.1-cp313-cp313-win32.whl", hash = "sha256:ba9e56e8ceeeedb2e080147ba85ffcd5cd0711b89576b83784d8605a7df455fa", size = 176393, upload-time = "2025-03-05T20:02:53.814Z" }, 3839 3162 { url = "https://files.pythonhosted.org/packages/1b/6c/c65773d6cab416a64d191d6ee8a8b1c68a09970ea6909d16965d26bfed1e/websockets-15.0.1-cp313-cp313-win_amd64.whl", hash = "sha256:e09473f095a819042ecb2ab9465aee615bd9c2028e4ef7d933600a8401c79561", size = 176837, upload-time = "2025-03-05T20:02:55.237Z" }, 3840 - { url = "https://files.pythonhosted.org/packages/02/9e/d40f779fa16f74d3468357197af8d6ad07e7c5a27ea1ca74ceb38986f77a/websockets-15.0.1-pp310-pypy310_pp73-macosx_10_15_x86_64.whl", hash = "sha256:0c9e74d766f2818bb95f84c25be4dea09841ac0f734d1966f415e4edfc4ef1c3", size = 173109, upload-time = "2025-03-05T20:03:17.769Z" }, 3841 - { url = "https://files.pythonhosted.org/packages/bc/cd/5b887b8585a593073fd92f7c23ecd3985cd2c3175025a91b0d69b0551372/websockets-15.0.1-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:1009ee0c7739c08a0cd59de430d6de452a55e42d6b522de7aa15e6f67db0b8e1", size = 173343, upload-time = "2025-03-05T20:03:19.094Z" }, 3842 - { url = "https://files.pythonhosted.org/packages/fe/ae/d34f7556890341e900a95acf4886833646306269f899d58ad62f588bf410/websockets-15.0.1-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:76d1f20b1c7a2fa82367e04982e708723ba0e7b8d43aa643d3dcd404d74f1475", size = 174599, upload-time = "2025-03-05T20:03:21.1Z" }, 3843 - { url = "https://files.pythonhosted.org/packages/71/e6/5fd43993a87db364ec60fc1d608273a1a465c0caba69176dd160e197ce42/websockets-15.0.1-pp310-pypy310_pp73-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f29d80eb9a9263b8d109135351caf568cc3f80b9928bccde535c235de55c22d9", size = 174207, upload-time = "2025-03-05T20:03:23.221Z" }, 3844 - { url = "https://files.pythonhosted.org/packages/2b/fb/c492d6daa5ec067c2988ac80c61359ace5c4c674c532985ac5a123436cec/websockets-15.0.1-pp310-pypy310_pp73-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b359ed09954d7c18bbc1680f380c7301f92c60bf924171629c5db97febb12f04", size = 174155, upload-time = "2025-03-05T20:03:25.321Z" }, 3845 - { url = "https://files.pythonhosted.org/packages/68/a1/dcb68430b1d00b698ae7a7e0194433bce4f07ded185f0ee5fb21e2a2e91e/websockets-15.0.1-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:cad21560da69f4ce7658ca2cb83138fb4cf695a2ba3e475e0559e05991aa8122", size = 176884, upload-time = "2025-03-05T20:03:27.934Z" }, 3846 3163 { url = "https://files.pythonhosted.org/packages/fa/a8/5b41e0da817d64113292ab1f8247140aac61cbf6cfd085d6a0fa77f4984f/websockets-15.0.1-py3-none-any.whl", hash = "sha256:f7a866fbc1e97b5c617ee4116daaa09b722101d4a3c170c787450ba409f9736f", size = 169743, upload-time = "2025-03-05T20:03:39.41Z" }, 3847 3164 ] 3848 3165