diff --git a/.github/workflows/debian.yml b/.github/workflows/debian.yml index 2efc6324..229589aa 100644 --- a/.github/workflows/debian.yml +++ b/.github/workflows/debian.yml @@ -97,7 +97,7 @@ jobs: - name: Build local wheel run: | - uv sync --frozen --all-extras --no-install-project --no-install-workspace --no-sources + uv sync --locked --all-extras --no-install-project --no-install-workspace --no-sources uv build --wheel --out-dir /tmp/wheels/ - name: Download .deb artifact diff --git a/.github/workflows/homebrew.yml b/.github/workflows/homebrew.yml index eb73d94d..95432efd 100644 --- a/.github/workflows/homebrew.yml +++ b/.github/workflows/homebrew.yml @@ -55,7 +55,7 @@ jobs: - name: Build local sdist run: | - uv sync --frozen --all-extras --no-install-project --no-install-workspace --no-sources + uv sync --locked --all-extras --no-install-project --no-install-workspace --no-sources uv build --sdist --out-dir /tmp/sdist/ - name: Generate formula from local sdist diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml index f851489e..cf756de0 100644 --- a/.github/workflows/lint.yml +++ b/.github/workflows/lint.yml @@ -4,6 +4,10 @@ on: workflow_dispatch: push: +env: + UV_NO_SOURCES: "1" + PYTHONPATH: ${{ github.workspace }}/abx-pkg:${{ github.workspace }}/abx-plugins:${{ github.workspace }}/abx-dl + jobs: lint: runs-on: ubuntu-22.04 @@ -13,6 +17,15 @@ jobs: submodules: true fetch-depth: 1 + - name: Clone abx-pkg + run: git clone --depth=1 https://github.com/ArchiveBox/abx-pkg.git abx-pkg + + - name: Clone abx-plugins + run: git clone --depth=1 https://github.com/ArchiveBox/abx-plugins.git abx-plugins + + - name: Clone abx-dl + run: git clone --depth=1 https://github.com/ArchiveBox/abx-dl.git abx-dl + - name: Set up Python uses: actions/setup-python@v5 with: @@ -25,7 +38,9 @@ jobs: enable-cache: true - name: Install dependencies with uv - run: uv sync --all-extras --all-groups --no-sources --no-cache + run: | + uv sync --all-extras --all-groups --no-sources --no-cache + uv pip install -e ./abx-pkg -e ./abx-plugins[dev] -e ./abx-dl - name: Run prek - run: uv run --no-sync prek run --all-files + run: uv run --no-sync --no-sources prek run --all-files diff --git a/.github/workflows/pip.yml b/.github/workflows/pip.yml index c6c06c34..dce9cb73 100755 --- a/.github/workflows/pip.yml +++ b/.github/workflows/pip.yml @@ -39,7 +39,7 @@ jobs: version: 1.0 - name: UV install archivebox dev + run sub-dependencies - run: uv sync --frozen --all-extras --no-install-project --no-install-workspace --no-sources + run: uv sync --locked --all-extras --no-install-project --no-install-workspace --no-sources - name: UV build archivebox and archivebox/pkgs/* packages run: | @@ -53,13 +53,13 @@ jobs: password: ${{ secrets.PYPI_PAT_SECRET }} - name: UV install archivebox and archivebox/pkgs/* locally for tests - run: uv sync --frozen --all-extras --no-sources + run: uv sync --locked --all-extras --no-sources - name: UV run archivebox init + archivebox version run: | mkdir -p data && cd data - uv run --no-sync archivebox init \ - && uv run --no-sync archivebox version + uv run --no-sync --no-sources archivebox init \ + && uv run --no-sync --no-sources archivebox version # && uv run archivebox add 'https://example.com' \ # && uv run archivebox status \ # || (echo "UV Failed to run archivebox!" && exit 1) diff --git a/.github/workflows/test-parallel.yml b/.github/workflows/test-parallel.yml index 0d66faa9..adc03a6f 100644 --- a/.github/workflows/test-parallel.yml +++ b/.github/workflows/test-parallel.yml @@ -10,6 +10,7 @@ env: PYTHONIOENCODING: utf-8 PYTHONLEGACYWINDOWSSTDIO: utf-8 USE_COLOR: False + UV_NO_SOURCES: "1" jobs: discover-tests: @@ -55,6 +56,8 @@ jobs: name: ${{ matrix.test.name }} runs-on: ubuntu-22.04 needs: discover-tests + env: + PYTHONPATH: ${{ github.workspace }}/abx-pkg:${{ github.workspace }}/abx-plugins:${{ github.workspace }}/abx-dl strategy: fail-fast: false @@ -68,6 +71,15 @@ jobs: submodules: true fetch-depth: 1 + - name: Clone abx-pkg + run: git clone --depth=1 https://github.com/ArchiveBox/abx-pkg.git abx-pkg + + - name: Clone abx-plugins + run: git clone --depth=1 https://github.com/ArchiveBox/abx-plugins.git abx-plugins + + - name: Clone abx-dl + run: git clone --depth=1 https://github.com/ArchiveBox/abx-dl.git abx-dl + - name: Set up Python ${{ matrix.python }} uses: actions/setup-python@v4 with: @@ -100,15 +112,18 @@ jobs: - name: Install dependencies with uv run: | uv sync --dev --all-extras --no-sources + uv pip install -e ./abx-pkg -e ./abx-plugins[dev] -e ./abx-dl - name: Run test - ${{ matrix.test.name }} run: | mkdir -p tests/out - uv run --no-sync pytest -xvs "${{ matrix.test.path }}" --basetemp=tests/out --ignore=archivebox/pkgs + uv run --no-sync --no-sources pytest -xvs "${{ matrix.test.path }}" --basetemp=tests/out --ignore=archivebox/pkgs plugin-tests: name: Plugin tests runs-on: ubuntu-22.04 + env: + PYTHONPATH: ${{ github.workspace }}/abx-pkg:${{ github.workspace }}/abx-plugins:${{ github.workspace }}/abx-dl steps: - uses: actions/checkout@v4 @@ -116,6 +131,15 @@ jobs: submodules: true fetch-depth: 1 + - name: Clone abx-pkg + run: git clone --depth=1 https://github.com/ArchiveBox/abx-pkg.git abx-pkg + + - name: Clone abx-plugins + run: git clone --depth=1 https://github.com/ArchiveBox/abx-plugins.git abx-plugins + + - name: Clone abx-dl + run: git clone --depth=1 https://github.com/ArchiveBox/abx-dl.git abx-dl + - name: Set up Python 3.13 uses: actions/setup-python@v4 with: @@ -148,6 +172,7 @@ jobs: - name: Install dependencies with uv run: | uv sync --dev --all-extras --no-sources + uv pip install -e ./abx-pkg -e ./abx-plugins[dev] -e ./abx-dl - name: Run plugin tests env: @@ -155,4 +180,4 @@ jobs: TWOCAPTCHA_API_KEY: ${{ secrets.TWOCAPTCHA_API_KEY }} API_KEY_2CAPTCHA: ${{ secrets.TWOCAPTCHA_API_KEY }} run: | - uv run --no-sync bash ./bin/test_plugins.sh --no-coverage + uv run --no-sync --no-sources bash ./bin/test_plugins.sh --no-coverage diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 83df0e32..bd77bc47 100755 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -6,10 +6,13 @@ env: PYTHONIOENCODING: utf-8 PYTHONLEGACYWINDOWSSTDIO: utf-8 USE_COLOR: False + UV_NO_SOURCES: "1" jobs: python_tests: runs-on: ${{ matrix.os }} + env: + PYTHONPATH: ${{ github.workspace }}/abx-pkg:${{ github.workspace }}/abx-plugins:${{ github.workspace }}/abx-dl strategy: matrix: @@ -23,6 +26,15 @@ jobs: submodules: true fetch-depth: 1 + - name: Clone abx-pkg + run: git clone --depth=1 https://github.com/ArchiveBox/abx-pkg.git abx-pkg + + - name: Clone abx-plugins + run: git clone --depth=1 https://github.com/ArchiveBox/abx-plugins.git abx-plugins + + - name: Clone abx-dl + run: git clone --depth=1 https://github.com/ArchiveBox/abx-dl.git abx-dl + ### Setup Python & JS Languages - name: Set up Python ${{ matrix.python }} uses: actions/setup-python@v4 @@ -57,6 +69,7 @@ jobs: - name: Install dependencies with uv run: | uv sync --dev --all-extras --no-sources + uv pip install -e ./abx-pkg -e ./abx-plugins[dev] -e ./abx-dl ### Run the tests - name: Directory listing for debugging @@ -67,14 +80,14 @@ jobs: - name: Archivebox version run: | mkdir -p tests/out/data - DATA_DIR="$PWD/tests/out/data" uv run --no-sync archivebox version + DATA_DIR="$PWD/tests/out/data" uv run --no-sync --no-sources archivebox version - name: Test built package with pytest # TODO: remove this exception for windows once we get tests passing on that platform if: ${{ !contains(matrix.os, 'windows') }} run: | mkdir -p tests/out - uv run --no-sync pytest -s archivebox/tests --basetemp=tests/out --ignore=archivebox/pkgs + uv run --no-sync --no-sources pytest -s archivebox/tests --basetemp=tests/out --ignore=archivebox/pkgs - name: Run plugin tests if: ${{ !contains(matrix.os, 'windows') }} @@ -83,7 +96,7 @@ jobs: TWOCAPTCHA_API_KEY: ${{ secrets.TWOCAPTCHA_API_KEY }} API_KEY_2CAPTCHA: ${{ secrets.TWOCAPTCHA_API_KEY }} run: | - uv run --no-sync bash ./bin/test_plugins.sh --no-coverage + uv run --no-sync --no-sources bash ./bin/test_plugins.sh --no-coverage docker_tests: runs-on: ubuntu-latest diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 62a3d0b4..2d752534 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -29,12 +29,12 @@ repos: hooks: - id: ruff-format name: ruff-format - entry: uv run --active ruff format + entry: uv run --active --no-sources ruff format language: system types_or: [python, pyi] - id: ruff-check name: ruff-check - entry: uv run --active ruff check --fix + entry: uv run --active --no-sources ruff check --fix language: system types_or: [python, pyi] diff --git a/archivebox/config/views.py b/archivebox/config/views.py index 23dbbe59..069ee6da 100644 --- a/archivebox/config/views.py +++ b/archivebox/config/views.py @@ -99,7 +99,7 @@ def get_installed_binary_change_url(name: str, binary: Binary | None) -> str | N if binary is None or not binary.id: return None - base_url = binary.admin_change_url or f"{INSTALLED_BINARIES_BASE_URL}{binary.id}/change/" + base_url = getattr(binary, "admin_change_url", None) or f"{INSTALLED_BINARIES_BASE_URL}{binary.id}/change/" changelist_filters = urlencode({"q": name}) return f"{base_url}?{urlencode({'_changelist_filters': changelist_filters})}" @@ -360,8 +360,12 @@ def _binary_sort_key(binary: Binary) -> tuple[int, int, int, Any]: def get_db_binaries_by_name() -> dict[str, Binary]: grouped: dict[str, list[Binary]] = {} + binary_name_aliases = { + "youtube-dl": "yt-dlp", + } for binary in Binary.objects.all(): - grouped.setdefault(binary.name, []).append(binary) + canonical_name = binary_name_aliases.get(binary.name, binary.name) + grouped.setdefault(canonical_name, []).append(binary) return {name: max(records, key=_binary_sort_key) for name, records in grouped.items()} @@ -424,10 +428,11 @@ def binaries_list_view(request: HttpRequest, **kwargs) -> TableContext: for name in all_binary_names: binary = db_binaries.get(name) + binary_is_valid = bool(binary and getattr(binary, "is_valid", getattr(binary, "abspath", None))) rows["Binary Name"].append(ItemLink(name, key=name)) - if binary and binary.is_valid: + if binary_is_valid: rows["Found Version"].append(f"✅ {binary.version}" if binary.version else "✅ found") rows["Provided By"].append(binary.binprovider or "-") rows["Found Abspath"].append(binary.abspath or "-") @@ -446,9 +451,13 @@ def binaries_list_view(request: HttpRequest, **kwargs) -> TableContext: def binary_detail_view(request: HttpRequest, key: str, **kwargs) -> ItemContext: assert is_superuser(request), "Must be a superuser to view configuration settings." + key = { + "youtube-dl": "yt-dlp", + }.get(key, key) db_binary = get_db_binaries_by_name().get(key) - if db_binary and db_binary.is_valid: - binary_data = db_binary.to_json() + binary_is_valid = bool(db_binary and getattr(db_binary, "is_valid", getattr(db_binary, "abspath", None))) + if binary_is_valid: + binary_data = db_binary.to_json() if hasattr(db_binary, "to_json") else db_binary.__dict__ section: SectionData = { "name": key, "description": mark_safe(render_binary_detail_description(key, binary_data, db_binary)), diff --git a/archivebox/tests/test_hooks.py b/archivebox/tests/test_hooks.py index 14983a27..363b580f 100755 --- a/archivebox/tests/test_hooks.py +++ b/archivebox/tests/test_hooks.py @@ -381,9 +381,7 @@ print(json.dumps({"type": "ArchiveResult", "status": "succeeded", "output_str": def test_js_hook_execution(self): """JavaScript hook should execute and output JSONL.""" - # Skip if node not available - if shutil.which("node") is None: - self.skipTest("Node.js not available") + self.assertIsNotNone(shutil.which("node"), "Node.js not available") hook_path = self.work_dir / "test_hook.js" hook_path.write_text("""#!/usr/bin/env node diff --git a/archivebox/tests/test_migrations_08_to_09.py b/archivebox/tests/test_migrations_08_to_09.py index e628723d..7264a06d 100644 --- a/archivebox/tests/test_migrations_08_to_09.py +++ b/archivebox/tests/test_migrations_08_to_09.py @@ -14,11 +14,14 @@ import shutil import sqlite3 import tempfile import unittest +import json from pathlib import Path from .migrations_helpers import ( + SCHEMA_0_7, SCHEMA_0_8, seed_0_8_data, + seed_0_7_data, run_archivebox, create_data_dir_structure, verify_snapshot_count, @@ -525,19 +528,47 @@ class TestFilesystemMigration08to09(unittest.TestCase): 4. All files are moved (no data loss) 5. Old archive/timestamp/ directories are cleaned up """ - # Use the real 0.7.2 database which has actual ArchiveResults with files - gold_db = Path("/Users/squash/Local/Code/archiveboxes/archivebox-migration-path/archivebox-v0.7.2/data") - if not gold_db.exists(): - self.skipTest(f"Gold standard database not found at {gold_db}") + create_data_dir_structure(self.work_dir) + conn = sqlite3.connect(str(self.db_path)) + conn.executescript(SCHEMA_0_7) + conn.close() + original_data = seed_0_7_data(self.db_path) + conn = sqlite3.connect(str(self.db_path)) + cursor = conn.cursor() + for i, snapshot in enumerate(original_data["snapshots"]): + legacy_timestamp = str(1704110400 + (i * 86400)) + cursor.execute( + "UPDATE core_snapshot SET timestamp = ? WHERE id = ?", + (legacy_timestamp, snapshot["id"]), + ) + cursor.execute( + "UPDATE core_archiveresult SET pwd = ? WHERE snapshot_id = ?", + (f"/data/archive/{legacy_timestamp}", snapshot["id"]), + ) + snapshot["timestamp"] = legacy_timestamp + conn.commit() + conn.close() - # Copy gold database to test directory - import shutil - - for item in gold_db.iterdir(): - if item.is_dir(): - shutil.copytree(item, self.work_dir / item.name, dirs_exist_ok=True) - else: - shutil.copy2(item, self.work_dir / item.name) + sample_files = [ + "favicon.ico", + "screenshot.png", + "singlefile.html", + "headers.json", + ] + for snapshot in original_data["snapshots"]: + snapshot_dir = self.work_dir / "archive" / snapshot["timestamp"] + snapshot_dir.mkdir(parents=True, exist_ok=True) + (snapshot_dir / "index.json").write_text( + json.dumps( + { + "url": snapshot["url"], + "timestamp": snapshot["timestamp"], + "title": snapshot["title"], + }, + ), + ) + for sample_file in sample_files: + (snapshot_dir / sample_file).write_text(f"{snapshot['url']}::{sample_file}") # Count archive directories and files BEFORE migration archive_dir = self.work_dir / "archive" @@ -552,12 +583,6 @@ class TestFilesystemMigration08to09(unittest.TestCase): files_before_count = len(files_before) # Sample some specific files to check they're preserved - sample_files = [ - "favicon.ico", - "screenshot.png", - "singlefile.html", - "headers.json", - ] sample_paths_before = {} for d in dirs_before: if d.is_dir(): @@ -742,32 +767,30 @@ class TestFilesystemMigration08to09(unittest.TestCase): print(f"[*] ArchiveResults linked to Process: {linked_count}") # Verify data migration happened correctly - # The 0.7.2 gold database has 44 ArchiveResults self.assertEqual( archiveresult_count, - 44, - f"Expected 44 ArchiveResults from 0.7.2 database, got {archiveresult_count}", + len(original_data["archiveresults"]), + f"Expected {len(original_data['archiveresults'])} ArchiveResults after migration, got {archiveresult_count}", ) # Each ArchiveResult should create one Process record self.assertEqual( process_count, - 44, - f"Expected 44 Process records (1 per ArchiveResult), got {process_count}", + len(original_data["archiveresults"]), + f"Expected {len(original_data['archiveresults'])} Process records (1 per ArchiveResult), got {process_count}", ) - # The 44 ArchiveResults use 7 unique binaries (curl, wget, etc.) self.assertEqual( binary_count, - 7, - f"Expected 7 unique Binary records, got {binary_count}", + 5, + f"Expected 5 unique Binary records, got {binary_count}", ) # ALL ArchiveResults should be linked to Process records self.assertEqual( linked_count, - 44, - f"Expected all 44 ArchiveResults linked to Process, got {linked_count}", + len(original_data["archiveresults"]), + f"Expected all {len(original_data['archiveresults'])} ArchiveResults linked to Process, got {linked_count}", ) diff --git a/archivebox/tests/test_runner.py b/archivebox/tests/test_runner.py index 93c9069b..21835ba4 100644 --- a/archivebox/tests/test_runner.py +++ b/archivebox/tests/test_runner.py @@ -77,7 +77,6 @@ def test_run_snapshot_reuses_crawl_bus_for_all_snapshots(monkeypatch): monkeypatch.setattr(runner_module, "create_bus", fake_create_bus) monkeypatch.setattr(runner_module, "discover_plugins", lambda: {}) monkeypatch.setattr(runner_module, "ProcessService", _DummyService) - monkeypatch.setattr(runner_module, "MachineService", _DummyService) monkeypatch.setattr(runner_module, "BinaryService", _DummyService) monkeypatch.setattr(runner_module, "TagService", _DummyService) monkeypatch.setattr(runner_module, "CrawlService", _DummyService) @@ -232,7 +231,6 @@ def test_runner_prepare_refreshes_network_interface_and_attaches_current_process monkeypatch.setattr(runner_module, "discover_plugins", lambda: {}) monkeypatch.setattr(runner_module, "create_bus", lambda **kwargs: _DummyBus(kwargs["name"])) monkeypatch.setattr(runner_module, "ProcessService", _DummyService) - monkeypatch.setattr(runner_module, "MachineService", _DummyService) monkeypatch.setattr(runner_module, "BinaryService", _DummyService) monkeypatch.setattr(runner_module, "TagService", _DummyService) monkeypatch.setattr(runner_module, "CrawlService", _DummyService) @@ -405,8 +403,8 @@ def test_installed_binary_config_overrides_do_not_map_hardcoded_artifacts_to_con ) assert "SINGLEFILE_BINARY" not in overrides - assert overrides["LIB_DIR"] == "/tmp/shared-lib" - assert overrides["LIB_BIN_DIR"] == "/tmp/shared-lib/bin" + assert "LIB_DIR" not in overrides + assert "LIB_BIN_DIR" not in overrides def test_run_snapshot_skips_descendant_when_max_size_already_reached(monkeypatch): @@ -425,7 +423,6 @@ def test_run_snapshot_skips_descendant_when_max_size_already_reached(monkeypatch monkeypatch.setattr(runner_module, "discover_plugins", lambda: {}) monkeypatch.setattr(runner_module, "create_bus", lambda **kwargs: _DummyBus(kwargs["name"])) monkeypatch.setattr(runner_module, "ProcessService", _DummyService) - monkeypatch.setattr(runner_module, "MachineService", _DummyService) monkeypatch.setattr(runner_module, "BinaryService", _DummyService) monkeypatch.setattr(runner_module, "TagService", _DummyService) monkeypatch.setattr(runner_module, "CrawlService", _DummyService) @@ -616,7 +613,6 @@ def test_crawl_runner_finalizes_with_sync_to_async_for_is_finished(monkeypatch): monkeypatch.setattr(runner_module, "create_bus", lambda *args, **kwargs: _DummyBus("runner")) monkeypatch.setattr(runner_module, "discover_plugins", lambda: {}) monkeypatch.setattr(runner_module, "ProcessService", _DummyService) - monkeypatch.setattr(runner_module, "MachineService", _DummyService) monkeypatch.setattr(runner_module, "BinaryService", _DummyService) monkeypatch.setattr(runner_module, "TagService", _DummyService) monkeypatch.setattr(runner_module, "CrawlService", _DummyService) diff --git a/archivebox/tests/test_server_security_browser.py b/archivebox/tests/test_server_security_browser.py index aecc08f2..ef59e9b6 100644 --- a/archivebox/tests/test_server_security_browser.py +++ b/archivebox/tests/test_server_security_browser.py @@ -174,15 +174,14 @@ def _resolve_browser(shared_lib: Path) -> Path | None: @pytest.fixture(scope="session") def browser_runtime(tmp_path_factory): - if shutil.which("node") is None or shutil.which("npm") is None: - pytest.skip("Node.js and npm are required for browser security tests") + assert shutil.which("node") is not None, "Node.js is required for browser security tests" + assert shutil.which("npm") is not None, "npm is required for browser security tests" shared_lib = tmp_path_factory.mktemp("archivebox_browser_lib") _ensure_puppeteer(shared_lib) browser = _resolve_browser(shared_lib) - if not browser: - pytest.skip("No Chrome/Chromium binary available for browser security tests") + assert browser, "No Chrome/Chromium binary available for browser security tests" return { "node_modules_dir": shared_lib / "npm" / "node_modules", diff --git a/pyproject.toml b/pyproject.toml index 29c54d8a..e805ebe3 100755 --- a/pyproject.toml +++ b/pyproject.toml @@ -144,6 +144,7 @@ dev = [ "pytest-django>=4.11.1", "pytest>=8.3.3", "pytest-cov>=6.0.0", + "pytest-httpserver>=1.1.0", "coverage[toml]>=7.6.0", "bottle>=0.13.1", ### LINTING @@ -158,12 +159,6 @@ environments = ["sys_platform == 'darwin'", "sys_platform == 'linux'"] package = true # compile-bytecode = true -[tool.uv.sources] -abxbus = { path = "../abxbus", editable = true } -abx-pkg = { path = "../abx-pkg", editable = true } -abx-plugins = { path = "../abx-plugins", editable = true } -abx-dl = { path = "../abx-dl", editable = true } - [build-system] requires = ["pdm-backend"] build-backend = "pdm.backend" diff --git a/uv.lock b/uv.lock index d9dd1bc6..aad4a982 100644 --- a/uv.lock +++ b/uv.lock @@ -15,7 +15,7 @@ supported-markers = [ [[package]] name = "abx-dl" version = "1.10.19" -source = { editable = "../abx-dl" } +source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "abx-pkg", marker = "sys_platform == 'darwin' or sys_platform == 'linux'" }, { name = "abx-plugins", marker = "sys_platform == 'darwin' or sys_platform == 'linux'" }, @@ -23,160 +23,59 @@ dependencies = [ { name = "platformdirs", marker = "sys_platform == 'darwin' or sys_platform == 'linux'" }, { name = "psutil", marker = "sys_platform == 'darwin' or sys_platform == 'linux'" }, { name = "pydantic", marker = "sys_platform == 'darwin' or sys_platform == 'linux'" }, - { name = "pydantic-settings", marker = "sys_platform == 'darwin' or sys_platform == 'linux'" }, { name = "requests", marker = "sys_platform == 'darwin' or sys_platform == 'linux'" }, { name = "rich", marker = "sys_platform == 'darwin' or sys_platform == 'linux'" }, { name = "rich-click", marker = "sys_platform == 'darwin' or sys_platform == 'linux'" }, ] - -[package.metadata] -requires-dist = [ - { name = "abx-pkg", editable = "../abx-pkg" }, - { name = "abx-plugins", editable = "../abx-plugins" }, - { name = "abxbus", editable = "../abxbus" }, - { name = "flake8", marker = "extra == 'dev'", specifier = ">=7.1.1" }, - { name = "flask", marker = "extra == 'dev'", specifier = ">=3.0" }, - { name = "mypy", marker = "extra == 'dev'", specifier = ">=1.11.2" }, - { name = "platformdirs", specifier = ">=4.0.0" }, - { name = "psutil", specifier = ">=7.2.1" }, - { name = "pydantic", specifier = ">=2.0.0" }, - { name = "pydantic-settings", specifier = ">=2.0.0" }, - { name = "pytest", marker = "extra == 'dev'", specifier = ">=8.0.0" }, - { name = "pytest-xdist", marker = "extra == 'dev'", specifier = ">=3.5.0" }, - { name = "requests", specifier = ">=2.28.0" }, - { name = "rich", specifier = ">=13.0.0" }, - { name = "rich-click", specifier = ">=1.8.0" }, - { name = "ruff", marker = "extra == 'dev'", specifier = ">=0.6.6" }, -] -provides-extras = ["dev"] - -[package.metadata.requires-dev] -dev = [ - { name = "flask", specifier = ">=3.0" }, - { name = "prek", specifier = ">=0.3.6" }, - { name = "pyright", specifier = ">=1.1.408" }, - { name = "ruff", specifier = ">=0.15.7" }, - { name = "ty", specifier = ">=0.0.24" }, +sdist = { url = "https://files.pythonhosted.org/packages/ea/3f/11e0439bcb3fa07ab8996db6ad5d787c786be9dd724b408ffcbb5dfe9e75/abx_dl-1.10.19.tar.gz", hash = "sha256:2ced9b0745bee7868354d015c8a092493e17103190df57d4adc2eb5f66657ebf", size = 68707, upload-time = "2026-03-23T19:59:09.097Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/91/6e/54015ba068571c8c6c3f85bb09d3ed9f890af5084531caa487a9a94058e3/abx_dl-1.10.19-py3-none-any.whl", hash = "sha256:a621799a6f4ce198a478624ca19589eaca54239d5c77d2398aaaf8d7e7d21da5", size = 73238, upload-time = "2026-03-23T19:59:08.026Z" }, ] [[package]] name = "abx-pkg" version = "1.9.19" -source = { editable = "../abx-pkg" } +source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "pip", marker = "sys_platform == 'darwin' or sys_platform == 'linux'" }, { name = "platformdirs", marker = "sys_platform == 'darwin' or sys_platform == 'linux'" }, { name = "pydantic", marker = "sys_platform == 'darwin' or sys_platform == 'linux'" }, { name = "typing-extensions", marker = "sys_platform == 'darwin' or sys_platform == 'linux'" }, ] - -[package.metadata] -requires-dist = [ - { name = "abx-pkg", extras = ["rich", "pyinfra", "ansible"], marker = "extra == 'all'" }, - { name = "ansible", marker = "extra == 'ansible'", specifier = ">=12.3.0" }, - { name = "ansible-core", marker = "extra == 'ansible'", specifier = ">=2.0.0" }, - { name = "ansible-runner", marker = "extra == 'ansible'", specifier = ">=2.4.2" }, - { name = "pip", specifier = ">=26.0.1" }, - { name = "platformdirs", specifier = ">=4.9.2" }, - { name = "pydantic", specifier = ">=2.12.5" }, - { name = "pyinfra", marker = "extra == 'pyinfra'", specifier = ">=3.6.1" }, - { name = "rich", marker = "extra == 'rich'", specifier = ">=14.0.0" }, - { name = "typing-extensions", specifier = ">=4.15.0" }, -] -provides-extras = ["rich", "pyinfra", "ansible", "all"] - -[package.metadata.requires-dev] -dev = [ - { name = "django", specifier = ">=4.0" }, - { name = "django-admin-data-views", specifier = ">=0.3.1" }, - { name = "django-jsonform", specifier = ">=2.22.0" }, - { name = "django-pydantic-field", specifier = ">=0.3.9" }, - { name = "django-stubs", specifier = ">=5.0.0" }, - { name = "mypy", specifier = ">=1.19.1" }, - { name = "prek", specifier = ">=0.3.6" }, - { name = "pyright" }, - { name = "pytest", specifier = ">=9.0.2" }, - { name = "rich", specifier = ">=14.0.0" }, - { name = "ruff", specifier = ">=0.15.7" }, - { name = "ty", specifier = ">=0.0.24" }, +sdist = { url = "https://files.pythonhosted.org/packages/d0/54/a195241e80c9d814bf8a2895c10c661554264d45c92deec26c6b6f30785e/abx_pkg-1.9.19.tar.gz", hash = "sha256:7e32173953e5194fb8dbaf038167a69d0347869eb9118a00b5d6711b8f4e78c1", size = 152588, upload-time = "2026-03-23T19:35:43.469Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/67/68/2362eccb3515f88e507494ee7d50a43531effeeba73041618d67f44927ce/abx_pkg-1.9.19-py3-none-any.whl", hash = "sha256:dc9ea2639369fca32626205c2519febaf8517058ad57ad62b38700368ffd43ac", size = 64769, upload-time = "2026-03-23T19:35:44.449Z" }, ] [[package]] name = "abx-plugins" version = "1.10.19" -source = { editable = "../abx-plugins" } +source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "abx-pkg", marker = "sys_platform == 'darwin' or sys_platform == 'linux'" }, - { name = "abxbus", marker = "sys_platform == 'darwin' or sys_platform == 'linux'" }, - { name = "jambo", marker = "sys_platform == 'darwin' or sys_platform == 'linux'" }, + { name = "pydantic-settings", marker = "sys_platform == 'darwin' or sys_platform == 'linux'" }, { name = "rich-click", marker = "sys_platform == 'darwin' or sys_platform == 'linux'" }, ] - -[package.metadata] -requires-dist = [ - { name = "abx-pkg", editable = "../abx-pkg" }, - { name = "abxbus", editable = "../abxbus" }, - { name = "feedparser", marker = "extra == 'dev'", specifier = ">=6.0.0" }, - { name = "jambo", specifier = ">=0.1.7" }, - { name = "jinja2", marker = "extra == 'dev'", specifier = ">=3.1.0" }, - { name = "pyright", marker = "extra == 'dev'", specifier = ">=1.1.408" }, - { name = "pytest", marker = "extra == 'dev'", specifier = ">=9.0.2" }, - { name = "pytest-httpserver", marker = "extra == 'dev'", specifier = ">=1.1.0" }, - { name = "requests", marker = "extra == 'dev'", specifier = ">=2.28.0" }, - { name = "rich-click", specifier = ">=1.9.7" }, - { name = "ruff", marker = "extra == 'dev'", specifier = ">=0.15.2" }, - { name = "ty", marker = "extra == 'dev'", specifier = ">=0.0.18" }, +sdist = { url = "https://files.pythonhosted.org/packages/80/87/32386ec18b046e5f746ab50d80e3c032f5b42b394fee7db02929f650baf5/abx_plugins-1.10.19.tar.gz", hash = "sha256:fc78c172a68e71b05345346b4de7f808ada2e146e0364805a68ab071d777d2a3", size = 539024, upload-time = "2026-03-23T19:40:44.526Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/cc/22/13a830f446161c24389d49fd91ba23beb864ddc02c1c40bcaa28ffe41d79/abx_plugins-1.10.19-py3-none-any.whl", hash = "sha256:0f6d0853292bcce819d04b621f640d893dcaed5a19bf6aa87ac059e7d40d469b", size = 751506, upload-time = "2026-03-23T19:40:45.797Z" }, ] -provides-extras = ["dev"] - -[package.metadata.requires-dev] -dev = [{ name = "prek", specifier = ">=0.3.6" }] [[package]] name = "abxbus" version = "2.4.9" -source = { editable = "../abxbus" } +source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "aiofiles", marker = "sys_platform == 'darwin' or sys_platform == 'linux'" }, { name = "anyio", marker = "sys_platform == 'darwin' or sys_platform == 'linux'" }, + { name = "portalocker", marker = "sys_platform == 'darwin' or sys_platform == 'linux'" }, { name = "pydantic", marker = "sys_platform == 'darwin' or sys_platform == 'linux'" }, { name = "typing-extensions", marker = "sys_platform == 'darwin' or sys_platform == 'linux'" }, { name = "uuid7", marker = "sys_platform == 'darwin' or sys_platform == 'linux'" }, ] - -[package.metadata] -requires-dist = [ - { name = "aiofiles", specifier = ">=24.1.0" }, - { name = "anyio", specifier = ">=4.9.0" }, - { name = "asyncpg", marker = "extra == 'bridges'", specifier = ">=0.31.0" }, - { name = "asyncpg", marker = "extra == 'postgres'", specifier = ">=0.31.0" }, - { name = "nats-py", marker = "extra == 'bridges'", specifier = ">=2.13.1" }, - { name = "nats-py", marker = "extra == 'nats'", specifier = ">=2.13.1" }, - { name = "pydantic", specifier = ">=2.11.5" }, - { name = "redis", marker = "extra == 'bridges'", specifier = ">=7.1.1" }, - { name = "redis", marker = "extra == 'redis'", specifier = ">=7.1.1" }, - { name = "typing-extensions", specifier = ">=4.12.2" }, - { name = "uuid7", specifier = ">=0.1.0" }, -] -provides-extras = ["postgres", "nats", "redis", "bridges"] - -[package.metadata.requires-dev] -dev = [ - { name = "build", specifier = ">=1.2.2" }, - { name = "codespell", specifier = ">=2.4.1" }, - { name = "fastapi", specifier = ">=0.118.0" }, - { name = "ipdb", specifier = ">=0.13.13" }, - { name = "prek", specifier = ">=0.3.3" }, - { name = "psutil", specifier = ">=7.0.0" }, - { name = "pyright", specifier = ">=1.1.404" }, - { name = "pytest", specifier = ">=8.3.5" }, - { name = "pytest-asyncio", specifier = ">=1.1.0" }, - { name = "pytest-cov", specifier = ">=6.2.1" }, - { name = "pytest-httpserver", specifier = ">=1.0.8" }, - { name = "pytest-timeout", specifier = ">=2.4.0" }, - { name = "pytest-xdist", specifier = ">=3.7.0" }, - { name = "ruff", specifier = ">=0.15.1" }, - { name = "ty", specifier = ">=0.0.1a19" }, +sdist = { url = "https://files.pythonhosted.org/packages/56/bf/3341d60838432dd391b812b557b1e1d5f5d367fab87fbbd16d0ecc268b76/abxbus-2.4.9.tar.gz", hash = "sha256:af2942c972d8f828346579d647a5466990d8469a3bb3727047d01d84c250879e", size = 116437, upload-time = "2026-03-23T19:34:46.556Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/41/d7/29a3823e93c8eaaca62a00cdb985c873cba7553e2b45870a1828f69908ed/abxbus-2.4.9-py3-none-any.whl", hash = "sha256:b46098e86a49cf195963cbff8be182e834368a20868c11ad4bd3c70a4e00b257", size = 111562, upload-time = "2026-03-23T19:34:45.465Z" }, ] [[package]] @@ -301,6 +200,7 @@ dev = [ { name = "pytest", marker = "sys_platform == 'darwin' or sys_platform == 'linux'" }, { name = "pytest-cov", marker = "sys_platform == 'darwin' or sys_platform == 'linux'" }, { name = "pytest-django", marker = "sys_platform == 'darwin' or sys_platform == 'linux'" }, + { name = "pytest-httpserver", marker = "sys_platform == 'darwin' or sys_platform == 'linux'" }, { name = "recommonmark", marker = "sys_platform == 'darwin' or sys_platform == 'linux'" }, { name = "requests-tracker", marker = "sys_platform == 'darwin' or sys_platform == 'linux'" }, { name = "ruff", marker = "sys_platform == 'darwin' or sys_platform == 'linux'" }, @@ -316,10 +216,10 @@ dev = [ [package.metadata] requires-dist = [ - { name = "abx-dl", editable = "../abx-dl" }, - { name = "abx-pkg", editable = "../abx-pkg" }, - { name = "abx-plugins", editable = "../abx-plugins" }, - { name = "abxbus", editable = "../abxbus" }, + { name = "abx-dl", specifier = ">=1.10.19" }, + { name = "abx-pkg", specifier = ">=1.9.19" }, + { name = "abx-plugins", specifier = ">=1.10.19" }, + { name = "abxbus", specifier = ">=2.4.9" }, { name = "archivebox", extras = ["sonic", "ldap", "debug"], marker = "extra == 'all'" }, { name = "atomicwrites", specifier = "==1.4.1" }, { name = "base32-crockford", specifier = ">=0.3.0" }, @@ -381,6 +281,7 @@ dev = [ { name = "pytest", specifier = ">=8.3.3" }, { name = "pytest-cov", specifier = ">=6.0.0" }, { name = "pytest-django", specifier = ">=4.11.1" }, + { name = "pytest-httpserver", specifier = ">=1.1.0" }, { name = "recommonmark", specifier = ">=0.7.1" }, { name = "requests-tracker", specifier = ">=0.3.3" }, { name = "ruff", specifier = ">=0.6.6" }, @@ -1002,15 +903,6 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/36/85/c4e42d21cf748c696b8c05316bbd8e8666f17eeda0cf1743056f4cf7622b/djdt_flamegraph-0.2.13-py2.py3-none-any.whl", hash = "sha256:b3252b8cc9b586829166cc158b26952626cd6f41a3ffa92dceef2f5dbe5b99a0", size = 15256, upload-time = "2020-01-17T05:40:37.799Z" }, ] -[[package]] -name = "dnspython" -version = "2.8.0" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/8c/8b/57666417c0f90f08bcafa776861060426765fdb422eb10212086fb811d26/dnspython-2.8.0.tar.gz", hash = "sha256:181d3c6996452cb1189c4046c61599b84a5a86e099562ffde77d26984ff26d0f", size = 368251, upload-time = "2025-09-07T18:58:00.022Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/ba/5a/18ad964b0086c6e62e2e7500f7edc89e3faa45033c71c1893d34eed2b2de/dnspython-2.8.0-py3-none-any.whl", hash = "sha256:01d9bbc4a2d76bf0db7c1f729812ded6d912bd318d3b1cf81d30c0f845dbf3af", size = 331094, upload-time = "2025-09-07T18:57:58.071Z" }, -] - [[package]] name = "docutils" version = "0.22.4" @@ -1020,19 +912,6 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/02/10/5da547df7a391dcde17f59520a231527b8571e6f46fc8efb02ccb370ab12/docutils-0.22.4-py3-none-any.whl", hash = "sha256:d0013f540772d1420576855455d050a2180186c91c15779301ac2ccb3eeb68de", size = 633196, upload-time = "2025-12-18T19:00:18.077Z" }, ] -[[package]] -name = "email-validator" -version = "2.3.0" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "dnspython", marker = "sys_platform == 'darwin' or sys_platform == 'linux'" }, - { name = "idna", marker = "sys_platform == 'darwin' or sys_platform == 'linux'" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/f5/22/900cb125c76b7aaa450ce02fd727f452243f2e91a61af068b40adba60ea9/email_validator-2.3.0.tar.gz", hash = "sha256:9fc05c37f2f6cf439ff414f8fc46d917929974a82244c20eb10231ba60c54426", size = 51238, upload-time = "2025-08-26T13:09:06.831Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/de/15/545e2b6cf2e3be84bc1ed85613edd75b8aea69807a71c26f4ca6a9258e82/email_validator-2.3.0-py3-none-any.whl", hash = "sha256:80f13f623413e6b197ae73bb10bf4eb0908faf509ad8362c5edeb0be7fd450b4", size = 35604, upload-time = "2025-08-26T13:09:05.858Z" }, -] - [[package]] name = "et-xmlfile" version = "2.0.0" @@ -1220,17 +1099,6 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/d9/33/1f075bf72b0b747cb3288d011319aaf64083cf2efef8354174e3ed4540e2/ipython_pygments_lexers-1.1.1-py3-none-any.whl", hash = "sha256:a9462224a505ade19a605f71f8fa63c2048833ce50abc86768a0d81d876dc81c", size = 8074, upload-time = "2025-01-17T11:24:33.271Z" }, ] -[[package]] -name = "jambo" -version = "0.1.7" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "email-validator", marker = "sys_platform == 'darwin' or sys_platform == 'linux'" }, - { name = "jsonschema", marker = "sys_platform == 'darwin' or sys_platform == 'linux'" }, - { name = "pydantic", marker = "sys_platform == 'darwin' or sys_platform == 'linux'" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/91/f5/74de157c7aece6a070f99f18201a0e2f46cdfd0f9e337efd411745ed9b22/jambo-0.1.7.tar.gz", hash = "sha256:df89ab8209ebdf7a6e92252ec925979cd3d32811bf4a8182a97dc35b7df58f74", size = 137822, upload-time = "2026-01-14T19:17:30.302Z" } - [[package]] name = "jedi" version = "0.19.2" @@ -1255,33 +1123,6 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/62/a1/3d680cbfd5f4b8f15abc1d571870c5fc3e594bb582bc3b64ea099db13e56/jinja2-3.1.6-py3-none-any.whl", hash = "sha256:85ece4451f492d0c13c5dd7c13a64681a86afae63a5f347908daf103ce6d2f67", size = 134899, upload-time = "2025-03-05T20:05:00.369Z" }, ] -[[package]] -name = "jsonschema" -version = "4.26.0" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "attrs", marker = "sys_platform == 'darwin' or sys_platform == 'linux'" }, - { name = "jsonschema-specifications", marker = "sys_platform == 'darwin' or sys_platform == 'linux'" }, - { name = "referencing", marker = "sys_platform == 'darwin' or sys_platform == 'linux'" }, - { name = "rpds-py", marker = "sys_platform == 'darwin' or sys_platform == 'linux'" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/b3/fc/e067678238fa451312d4c62bf6e6cf5ec56375422aee02f9cb5f909b3047/jsonschema-4.26.0.tar.gz", hash = "sha256:0c26707e2efad8aa1bfc5b7ce170f3fccc2e4918ff85989ba9ffa9facb2be326", size = 366583, upload-time = "2026-01-07T13:41:07.246Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/69/90/f63fb5873511e014207a475e2bb4e8b2e570d655b00ac19a9a0ca0a385ee/jsonschema-4.26.0-py3-none-any.whl", hash = "sha256:d489f15263b8d200f8387e64b4c3a75f06629559fb73deb8fdfb525f2dab50ce", size = 90630, upload-time = "2026-01-07T13:41:05.306Z" }, -] - -[[package]] -name = "jsonschema-specifications" -version = "2025.9.1" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "referencing", marker = "sys_platform == 'darwin' or sys_platform == 'linux'" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/19/74/a633ee74eb36c44aa6d1095e7cc5569bebf04342ee146178e2d36600708b/jsonschema_specifications-2025.9.1.tar.gz", hash = "sha256:b540987f239e745613c7a9176f3edb72b832a4ac465cf02712288397832b5e8d", size = 32855, upload-time = "2025-09-08T01:34:59.186Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/41/45/1a4ed80516f02155c51f51e8cedb3c1902296743db0bbc66608a0db2814f/jsonschema_specifications-2025.9.1-py3-none-any.whl", hash = "sha256:98802fee3a11ee76ecaca44429fda8a41bff98b00a0f2838151b113f210cc6fe", size = 18437, upload-time = "2025-09-08T01:34:57.871Z" }, -] - [[package]] name = "lexid" version = "2021.1006" @@ -1778,6 +1619,15 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/54/20/4d324d65cc6d9205fabedc306948156824eb9f0ee1633355a8f7ec5c66bf/pluggy-1.6.0-py3-none-any.whl", hash = "sha256:e920276dd6813095e9377c0bc5566d94c932c33b27a3e3945d8389c374dd4746", size = 20538, upload-time = "2025-05-15T12:30:06.134Z" }, ] +[[package]] +name = "portalocker" +version = "3.2.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/5e/77/65b857a69ed876e1951e88aaba60f5ce6120c33703f7cb61a3c894b8c1b6/portalocker-3.2.0.tar.gz", hash = "sha256:1f3002956a54a8c3730586c5c77bf18fae4149e07eaf1c29fc3faf4d5a3f89ac", size = 95644, upload-time = "2025-06-14T13:20:40.03Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/4b/a6/38c8e2f318bf67d338f4d629e93b0b4b9af331f455f0390ea8ce4a099b26/portalocker-3.2.0-py3-none-any.whl", hash = "sha256:3cdc5f565312224bc570c49337bd21428bba0ef363bbcf58b9ef4a9f11779968", size = 22424, upload-time = "2025-06-14T13:20:38.083Z" }, +] + [[package]] name = "prek" version = "0.3.8" @@ -2057,6 +1907,18 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/83/a5/41d091f697c09609e7ef1d5d61925494e0454ebf51de7de05f0f0a728f1d/pytest_django-4.12.0-py3-none-any.whl", hash = "sha256:3ff300c49f8350ba2953b90297d23bf5f589db69545f56f1ec5f8cff5da83e85", size = 26123, upload-time = "2026-02-14T18:40:47.381Z" }, ] +[[package]] +name = "pytest-httpserver" +version = "1.1.5" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "werkzeug", marker = "sys_platform == 'darwin' or sys_platform == 'linux'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/50/17/ad187f46998814014f7cda309de700b87c0eb4b2e111e18bc8c819be7116/pytest_httpserver-1.1.5.tar.gz", hash = "sha256:dc3d82e1fe00e491829d8939c549bf4bd9b39a260f87113c619b9d517c2f8ff1", size = 70974, upload-time = "2026-02-14T13:27:23.412Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/ec/df/0bdf90b84c6a586a9fd2b509523a3ab26b1cc1b1dba2fb62a32e4411ea9e/pytest_httpserver-1.1.5-py3-none-any.whl", hash = "sha256:ee83feb587ab652c0c6729598db2820e9048233bac8df756818b7845a1621d0a", size = 23330, upload-time = "2026-02-14T13:27:22.119Z" }, +] + [[package]] name = "python-benedict" version = "0.35.0" @@ -2224,19 +2086,6 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/c6/77/ed589c75db5d02a77a1d5d2d9abc63f29676467d396c64277f98b50b79c2/recommonmark-0.7.1-py2.py3-none-any.whl", hash = "sha256:1b1db69af0231efce3fa21b94ff627ea33dee7079a01dd0a7f8482c3da148b3f", size = 10214, upload-time = "2020-12-17T19:24:55.137Z" }, ] -[[package]] -name = "referencing" -version = "0.37.0" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "attrs", marker = "sys_platform == 'darwin' or sys_platform == 'linux'" }, - { name = "rpds-py", marker = "sys_platform == 'darwin' or sys_platform == 'linux'" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/22/f5/df4e9027acead3ecc63e50fe1e36aca1523e1719559c499951bb4b53188f/referencing-0.37.0.tar.gz", hash = "sha256:44aefc3142c5b842538163acb373e24cce6632bd54bdb01b21ad5863489f50d8", size = 78036, upload-time = "2025-10-13T15:30:48.871Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/2c/58/ca301544e1fa93ed4f80d724bf5b194f6e4b945841c5bfd555878eea9fcb/referencing-0.37.0-py3-none-any.whl", hash = "sha256:381329a9f99628c9069361716891d34ad94af76e461dcb0335825aecc7692231", size = 26766, upload-time = "2025-10-13T15:30:47.625Z" }, -] - [[package]] name = "regex" version = "2026.2.28" @@ -2360,62 +2209,6 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/04/54/6f679c435d28e0a568d8e8a7c0a93a09010818634c3c3907fc98d8983770/roman_numerals-4.1.0-py3-none-any.whl", hash = "sha256:647ba99caddc2cc1e55a51e4360689115551bf4476d90e8162cf8c345fe233c7", size = 7676, upload-time = "2025-12-17T18:25:33.098Z" }, ] -[[package]] -name = "rpds-py" -version = "0.30.0" -source = { registry = "https://pypi.org/simple" } -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" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/ed/dc/d61221eb88ff410de3c49143407f6f3147acf2538c86f2ab7ce65ae7d5f9/rpds_py-0.30.0-cp313-cp313-macosx_10_12_x86_64.whl", hash = "sha256:f83424d738204d9770830d35290ff3273fbb02b41f919870479fab14b9d303b2", size = 374887, upload-time = "2025-11-30T20:22:41.812Z" }, - { url = "https://files.pythonhosted.org/packages/fd/32/55fb50ae104061dbc564ef15cc43c013dc4a9f4527a1f4d99baddf56fe5f/rpds_py-0.30.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:e7536cd91353c5273434b4e003cbda89034d67e7710eab8761fd918ec6c69cf8", size = 358904, upload-time = "2025-11-30T20:22:43.479Z" }, - { url = "https://files.pythonhosted.org/packages/58/70/faed8186300e3b9bdd138d0273109784eea2396c68458ed580f885dfe7ad/rpds_py-0.30.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2771c6c15973347f50fece41fc447c054b7ac2ae0502388ce3b6738cd366e3d4", size = 389945, upload-time = "2025-11-30T20:22:44.819Z" }, - { url = "https://files.pythonhosted.org/packages/bd/a8/073cac3ed2c6387df38f71296d002ab43496a96b92c823e76f46b8af0543/rpds_py-0.30.0-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:0a59119fc6e3f460315fe9d08149f8102aa322299deaa5cab5b40092345c2136", size = 407783, upload-time = "2025-11-30T20:22:46.103Z" }, - { url = "https://files.pythonhosted.org/packages/77/57/5999eb8c58671f1c11eba084115e77a8899d6e694d2a18f69f0ba471ec8b/rpds_py-0.30.0-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:76fec018282b4ead0364022e3c54b60bf368b9d926877957a8624b58419169b7", size = 515021, upload-time = "2025-11-30T20:22:47.458Z" }, - { url = "https://files.pythonhosted.org/packages/e0/af/5ab4833eadc36c0a8ed2bc5c0de0493c04f6c06de223170bd0798ff98ced/rpds_py-0.30.0-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:692bef75a5525db97318e8cd061542b5a79812d711ea03dbc1f6f8dbb0c5f0d2", size = 414589, upload-time = "2025-11-30T20:22:48.872Z" }, - { url = "https://files.pythonhosted.org/packages/b7/de/f7192e12b21b9e9a68a6d0f249b4af3fdcdff8418be0767a627564afa1f1/rpds_py-0.30.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9027da1ce107104c50c81383cae773ef5c24d296dd11c99e2629dbd7967a20c6", size = 394025, upload-time = "2025-11-30T20:22:50.196Z" }, - { url = "https://files.pythonhosted.org/packages/91/c4/fc70cd0249496493500e7cc2de87504f5aa6509de1e88623431fec76d4b6/rpds_py-0.30.0-cp313-cp313-manylinux_2_31_riscv64.whl", hash = "sha256:9cf69cdda1f5968a30a359aba2f7f9aa648a9ce4b580d6826437f2b291cfc86e", size = 408895, upload-time = "2025-11-30T20:22:51.87Z" }, - { url = "https://files.pythonhosted.org/packages/58/95/d9275b05ab96556fefff73a385813eb66032e4c99f411d0795372d9abcea/rpds_py-0.30.0-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:a4796a717bf12b9da9d3ad002519a86063dcac8988b030e405704ef7d74d2d9d", size = 422799, upload-time = "2025-11-30T20:22:53.341Z" }, - { url = "https://files.pythonhosted.org/packages/06/c1/3088fc04b6624eb12a57eb814f0d4997a44b0d208d6cace713033ff1a6ba/rpds_py-0.30.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:5d4c2aa7c50ad4728a094ebd5eb46c452e9cb7edbfdb18f9e1221f597a73e1e7", size = 572731, upload-time = "2025-11-30T20:22:54.778Z" }, - { url = "https://files.pythonhosted.org/packages/d8/42/c612a833183b39774e8ac8fecae81263a68b9583ee343db33ab571a7ce55/rpds_py-0.30.0-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:ba81a9203d07805435eb06f536d95a266c21e5b2dfbf6517748ca40c98d19e31", size = 599027, upload-time = "2025-11-30T20:22:56.212Z" }, - { url = "https://files.pythonhosted.org/packages/5f/60/525a50f45b01d70005403ae0e25f43c0384369ad24ffe46e8d9068b50086/rpds_py-0.30.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:945dccface01af02675628334f7cf49c2af4c1c904748efc5cf7bbdf0b579f95", size = 563020, upload-time = "2025-11-30T20:22:58.2Z" }, - { url = "https://files.pythonhosted.org/packages/ff/1b/b10de890a0def2a319a2626334a7f0ae388215eb60914dbac8a3bae54435/rpds_py-0.30.0-cp313-cp313t-macosx_10_12_x86_64.whl", hash = "sha256:eb0b93f2e5c2189ee831ee43f156ed34e2a89a78a66b98cadad955972548be5a", size = 364443, upload-time = "2025-11-30T20:23:04.878Z" }, - { url = "https://files.pythonhosted.org/packages/0d/bf/27e39f5971dc4f305a4fb9c672ca06f290f7c4e261c568f3dea16a410d47/rpds_py-0.30.0-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:922e10f31f303c7c920da8981051ff6d8c1a56207dbdf330d9047f6d30b70e5e", size = 353375, upload-time = "2025-11-30T20:23:06.342Z" }, - { url = "https://files.pythonhosted.org/packages/40/58/442ada3bba6e8e6615fc00483135c14a7538d2ffac30e2d933ccf6852232/rpds_py-0.30.0-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:cdc62c8286ba9bf7f47befdcea13ea0e26bf294bda99758fd90535cbaf408000", size = 383850, upload-time = "2025-11-30T20:23:07.825Z" }, - { url = "https://files.pythonhosted.org/packages/14/14/f59b0127409a33c6ef6f5c1ebd5ad8e32d7861c9c7adfa9a624fc3889f6c/rpds_py-0.30.0-cp313-cp313t-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:47f9a91efc418b54fb8190a6b4aa7813a23fb79c51f4bb84e418f5476c38b8db", size = 392812, upload-time = "2025-11-30T20:23:09.228Z" }, - { url = "https://files.pythonhosted.org/packages/b3/66/e0be3e162ac299b3a22527e8913767d869e6cc75c46bd844aa43fb81ab62/rpds_py-0.30.0-cp313-cp313t-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1f3587eb9b17f3789ad50824084fa6f81921bbf9a795826570bda82cb3ed91f2", size = 517841, upload-time = "2025-11-30T20:23:11.186Z" }, - { url = "https://files.pythonhosted.org/packages/3d/55/fa3b9cf31d0c963ecf1ba777f7cf4b2a2c976795ac430d24a1f43d25a6ba/rpds_py-0.30.0-cp313-cp313t-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:39c02563fc592411c2c61d26b6c5fe1e51eaa44a75aa2c8735ca88b0d9599daa", size = 408149, upload-time = "2025-11-30T20:23:12.864Z" }, - { url = "https://files.pythonhosted.org/packages/60/ca/780cf3b1a32b18c0f05c441958d3758f02544f1d613abf9488cd78876378/rpds_py-0.30.0-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:51a1234d8febafdfd33a42d97da7a43f5dcb120c1060e352a3fbc0c6d36e2083", size = 383843, upload-time = "2025-11-30T20:23:14.638Z" }, - { url = "https://files.pythonhosted.org/packages/82/86/d5f2e04f2aa6247c613da0c1dd87fcd08fa17107e858193566048a1e2f0a/rpds_py-0.30.0-cp313-cp313t-manylinux_2_31_riscv64.whl", hash = "sha256:eb2c4071ab598733724c08221091e8d80e89064cd472819285a9ab0f24bcedb9", size = 396507, upload-time = "2025-11-30T20:23:16.105Z" }, - { url = "https://files.pythonhosted.org/packages/4b/9a/453255d2f769fe44e07ea9785c8347edaf867f7026872e76c1ad9f7bed92/rpds_py-0.30.0-cp313-cp313t-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:6bdfdb946967d816e6adf9a3d8201bfad269c67efe6cefd7093ef959683c8de0", size = 414949, upload-time = "2025-11-30T20:23:17.539Z" }, - { url = "https://files.pythonhosted.org/packages/a3/31/622a86cdc0c45d6df0e9ccb6becdba5074735e7033c20e401a6d9d0e2ca0/rpds_py-0.30.0-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:c77afbd5f5250bf27bf516c7c4a016813eb2d3e116139aed0096940c5982da94", size = 565790, upload-time = "2025-11-30T20:23:19.029Z" }, - { url = "https://files.pythonhosted.org/packages/1c/5d/15bbf0fb4a3f58a3b1c67855ec1efcc4ceaef4e86644665fff03e1b66d8d/rpds_py-0.30.0-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:61046904275472a76c8c90c9ccee9013d70a6d0f73eecefd38c1ae7c39045a08", size = 590217, upload-time = "2025-11-30T20:23:20.885Z" }, - { url = "https://files.pythonhosted.org/packages/6d/61/21b8c41f68e60c8cc3b2e25644f0e3681926020f11d06ab0b78e3c6bbff1/rpds_py-0.30.0-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:4c5f36a861bc4b7da6516dbdf302c55313afa09b81931e8280361a4f6c9a2d27", size = 555806, upload-time = "2025-11-30T20:23:22.488Z" }, - { url = "https://files.pythonhosted.org/packages/86/81/dad16382ebbd3d0e0328776d8fd7ca94220e4fa0798d1dc5e7da48cb3201/rpds_py-0.30.0-cp314-cp314-macosx_10_12_x86_64.whl", hash = "sha256:68f19c879420aa08f61203801423f6cd5ac5f0ac4ac82a2368a9fcd6a9a075e0", size = 362099, upload-time = "2025-11-30T20:23:27.316Z" }, - { url = "https://files.pythonhosted.org/packages/2b/60/19f7884db5d5603edf3c6bce35408f45ad3e97e10007df0e17dd57af18f8/rpds_py-0.30.0-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:ec7c4490c672c1a0389d319b3a9cfcd098dcdc4783991553c332a15acf7249be", size = 353192, upload-time = "2025-11-30T20:23:29.151Z" }, - { url = "https://files.pythonhosted.org/packages/bf/c4/76eb0e1e72d1a9c4703c69607cec123c29028bff28ce41588792417098ac/rpds_py-0.30.0-cp314-cp314-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f251c812357a3fed308d684a5079ddfb9d933860fc6de89f2b7ab00da481e65f", size = 384080, upload-time = "2025-11-30T20:23:30.785Z" }, - { url = "https://files.pythonhosted.org/packages/72/87/87ea665e92f3298d1b26d78814721dc39ed8d2c74b86e83348d6b48a6f31/rpds_py-0.30.0-cp314-cp314-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:ac98b175585ecf4c0348fd7b29c3864bda53b805c773cbf7bfdaffc8070c976f", size = 394841, upload-time = "2025-11-30T20:23:32.209Z" }, - { url = "https://files.pythonhosted.org/packages/77/ad/7783a89ca0587c15dcbf139b4a8364a872a25f861bdb88ed99f9b0dec985/rpds_py-0.30.0-cp314-cp314-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:3e62880792319dbeb7eb866547f2e35973289e7d5696c6e295476448f5b63c87", size = 516670, upload-time = "2025-11-30T20:23:33.742Z" }, - { url = "https://files.pythonhosted.org/packages/5b/3c/2882bdac942bd2172f3da574eab16f309ae10a3925644e969536553cb4ee/rpds_py-0.30.0-cp314-cp314-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:4e7fc54e0900ab35d041b0601431b0a0eb495f0851a0639b6ef90f7741b39a18", size = 408005, upload-time = "2025-11-30T20:23:35.253Z" }, - { url = "https://files.pythonhosted.org/packages/ce/81/9a91c0111ce1758c92516a3e44776920b579d9a7c09b2b06b642d4de3f0f/rpds_py-0.30.0-cp314-cp314-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:47e77dc9822d3ad616c3d5759ea5631a75e5809d5a28707744ef79d7a1bcfcad", size = 382112, upload-time = "2025-11-30T20:23:36.842Z" }, - { url = "https://files.pythonhosted.org/packages/cf/8e/1da49d4a107027e5fbc64daeab96a0706361a2918da10cb41769244b805d/rpds_py-0.30.0-cp314-cp314-manylinux_2_31_riscv64.whl", hash = "sha256:b4dc1a6ff022ff85ecafef7979a2c6eb423430e05f1165d6688234e62ba99a07", size = 399049, upload-time = "2025-11-30T20:23:38.343Z" }, - { url = "https://files.pythonhosted.org/packages/df/5a/7ee239b1aa48a127570ec03becbb29c9d5a9eb092febbd1699d567cae859/rpds_py-0.30.0-cp314-cp314-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:4559c972db3a360808309e06a74628b95eaccbf961c335c8fe0d590cf587456f", size = 415661, upload-time = "2025-11-30T20:23:40.263Z" }, - { url = "https://files.pythonhosted.org/packages/70/ea/caa143cf6b772f823bc7929a45da1fa83569ee49b11d18d0ada7f5ee6fd6/rpds_py-0.30.0-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:0ed177ed9bded28f8deb6ab40c183cd1192aa0de40c12f38be4d59cd33cb5c65", size = 565606, upload-time = "2025-11-30T20:23:42.186Z" }, - { url = "https://files.pythonhosted.org/packages/64/91/ac20ba2d69303f961ad8cf55bf7dbdb4763f627291ba3d0d7d67333cced9/rpds_py-0.30.0-cp314-cp314-musllinux_1_2_i686.whl", hash = "sha256:ad1fa8db769b76ea911cb4e10f049d80bf518c104f15b3edb2371cc65375c46f", size = 591126, upload-time = "2025-11-30T20:23:44.086Z" }, - { url = "https://files.pythonhosted.org/packages/21/20/7ff5f3c8b00c8a95f75985128c26ba44503fb35b8e0259d812766ea966c7/rpds_py-0.30.0-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:46e83c697b1f1c72b50e5ee5adb4353eef7406fb3f2043d64c33f20ad1c2fc53", size = 553371, upload-time = "2025-11-30T20:23:46.004Z" }, - { url = "https://files.pythonhosted.org/packages/9e/68/154fe0194d83b973cdedcdcc88947a2752411165930182ae41d983dcefa6/rpds_py-0.30.0-cp314-cp314t-macosx_10_12_x86_64.whl", hash = "sha256:7e6ecfcb62edfd632e56983964e6884851786443739dbfe3582947e87274f7cb", size = 364868, upload-time = "2025-11-30T20:23:52.494Z" }, - { url = "https://files.pythonhosted.org/packages/83/69/8bbc8b07ec854d92a8b75668c24d2abcb1719ebf890f5604c61c9369a16f/rpds_py-0.30.0-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:a1d0bc22a7cdc173fedebb73ef81e07faef93692b8c1ad3733b67e31e1b6e1b8", size = 353747, upload-time = "2025-11-30T20:23:54.036Z" }, - { url = "https://files.pythonhosted.org/packages/ab/00/ba2e50183dbd9abcce9497fa5149c62b4ff3e22d338a30d690f9af970561/rpds_py-0.30.0-cp314-cp314t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0d08f00679177226c4cb8c5265012eea897c8ca3b93f429e546600c971bcbae7", size = 383795, upload-time = "2025-11-30T20:23:55.556Z" }, - { url = "https://files.pythonhosted.org/packages/05/6f/86f0272b84926bcb0e4c972262f54223e8ecc556b3224d281e6598fc9268/rpds_py-0.30.0-cp314-cp314t-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:5965af57d5848192c13534f90f9dd16464f3c37aaf166cc1da1cae1fd5a34898", size = 393330, upload-time = "2025-11-30T20:23:57.033Z" }, - { url = "https://files.pythonhosted.org/packages/cb/e9/0e02bb2e6dc63d212641da45df2b0bf29699d01715913e0d0f017ee29438/rpds_py-0.30.0-cp314-cp314t-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:9a4e86e34e9ab6b667c27f3211ca48f73dba7cd3d90f8d5b11be56e5dbc3fb4e", size = 518194, upload-time = "2025-11-30T20:23:58.637Z" }, - { url = "https://files.pythonhosted.org/packages/ee/ca/be7bca14cf21513bdf9c0606aba17d1f389ea2b6987035eb4f62bd923f25/rpds_py-0.30.0-cp314-cp314t-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e5d3e6b26f2c785d65cc25ef1e5267ccbe1b069c5c21b8cc724efee290554419", size = 408340, upload-time = "2025-11-30T20:24:00.2Z" }, - { url = "https://files.pythonhosted.org/packages/c2/c7/736e00ebf39ed81d75544c0da6ef7b0998f8201b369acf842f9a90dc8fce/rpds_py-0.30.0-cp314-cp314t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:626a7433c34566535b6e56a1b39a7b17ba961e97ce3b80ec62e6f1312c025551", size = 383765, upload-time = "2025-11-30T20:24:01.759Z" }, - { url = "https://files.pythonhosted.org/packages/4a/3f/da50dfde9956aaf365c4adc9533b100008ed31aea635f2b8d7b627e25b49/rpds_py-0.30.0-cp314-cp314t-manylinux_2_31_riscv64.whl", hash = "sha256:acd7eb3f4471577b9b5a41baf02a978e8bdeb08b4b355273994f8b87032000a8", size = 396834, upload-time = "2025-11-30T20:24:03.687Z" }, - { url = "https://files.pythonhosted.org/packages/4e/00/34bcc2565b6020eab2623349efbdec810676ad571995911f1abdae62a3a0/rpds_py-0.30.0-cp314-cp314t-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:fe5fa731a1fa8a0a56b0977413f8cacac1768dad38d16b3a296712709476fbd5", size = 415470, upload-time = "2025-11-30T20:24:05.232Z" }, - { url = "https://files.pythonhosted.org/packages/8c/28/882e72b5b3e6f718d5453bd4d0d9cf8df36fddeb4ddbbab17869d5868616/rpds_py-0.30.0-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:74a3243a411126362712ee1524dfc90c650a503502f135d54d1b352bd01f2404", size = 565630, upload-time = "2025-11-30T20:24:06.878Z" }, - { url = "https://files.pythonhosted.org/packages/3b/97/04a65539c17692de5b85c6e293520fd01317fd878ea1995f0367d4532fb1/rpds_py-0.30.0-cp314-cp314t-musllinux_1_2_i686.whl", hash = "sha256:3e8eeb0544f2eb0d2581774be4c3410356eba189529a6b3e36bbbf9696175856", size = 591148, upload-time = "2025-11-30T20:24:08.445Z" }, - { url = "https://files.pythonhosted.org/packages/85/70/92482ccffb96f5441aab93e26c4d66489eb599efdcf96fad90c14bbfb976/rpds_py-0.30.0-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:dbd936cde57abfee19ab3213cf9c26be06d60750e60a8e4dd85d1ab12c8b1f40", size = 556030, upload-time = "2025-11-30T20:24:10.956Z" }, -] - [[package]] name = "ruff" version = "0.15.7" @@ -2928,6 +2721,18 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/68/5a/199c59e0a824a3db2b89c5d2dade7ab5f9624dbf6448dc291b46d5ec94d3/wcwidth-0.6.0-py3-none-any.whl", hash = "sha256:1a3a1e510b553315f8e146c54764f4fb6264ffad731b3d78088cdb1478ffbdad", size = 94189, upload-time = "2026-02-06T19:19:39.646Z" }, ] +[[package]] +name = "werkzeug" +version = "3.1.7" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "markupsafe", marker = "sys_platform == 'darwin' or sys_platform == 'linux'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/b5/43/76ded108b296a49f52de6bac5192ca1c4be84e886f9b5c9ba8427d9694fd/werkzeug-3.1.7.tar.gz", hash = "sha256:fb8c01fe6ab13b9b7cdb46892b99b1d66754e1d7ab8e542e865ec13f526b5351", size = 875700, upload-time = "2026-03-24T01:08:07.687Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/7f/b2/0bba9bbb4596d2d2f285a16c2ab04118f6b957d8441566e1abb892e6a6b2/werkzeug-3.1.7-py3-none-any.whl", hash = "sha256:4b314d81163a3e1a169b6a0be2a000a0e204e8873c5de6586f453c55688d422f", size = 226295, upload-time = "2026-03-24T01:08:06.133Z" }, +] + [[package]] name = "wheel" version = "0.46.3"