From babdd7afb96f0377506e6d023b9e81437793c789 Mon Sep 17 00:00:00 2001 From: Irozuku Date: Mon, 13 Jul 2026 15:30:14 -0400 Subject: [PATCH 1/8] feat: add grad-cam dice-ml and lime dependencies --- pyproject.toml | 3 + uv.lock | 531 +++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 534 insertions(+) diff --git a/pyproject.toml b/pyproject.toml index b7b221db6..612ae1339 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -72,6 +72,9 @@ dependencies = [ "pywebview", "openml", "oslo.concurrency", + "grad-cam>=1.5.5", + "dice-ml>=0.12", + "lime>=0.2.0.1", ] [project.optional-dependencies] diff --git a/uv.lock b/uv.lock index 75de2dd8d..b9bea0266 100644 --- a/uv.lock +++ b/uv.lock @@ -1432,10 +1432,12 @@ dependencies = [ { name = "cmaes" }, { name = "controlnet-aux" }, { name = "datasets" }, + { name = "dice-ml" }, { name = "diffusers" }, { name = "evaluate" }, { name = "fastapi", extra = ["all"] }, { name = "filetype" }, + { name = "grad-cam" }, { name = "greenery" }, { name = "httpx" }, { name = "huey" }, @@ -1444,6 +1446,7 @@ dependencies = [ { name = "imblearn" }, { name = "joblib" }, { name = "kink" }, + { name = "lime" }, { name = "llvmlite" }, { name = "numba", version = "0.47.0", source = { registry = "https://pypi.org/simple" }, marker = "(python_full_version >= '3.12' and platform_machine == 'x86_64' and sys_platform == 'darwin') or (python_full_version < '3.12' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (platform_machine != 'x86_64' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (sys_platform != 'darwin' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda')" }, { name = "numba", version = "0.66.0", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.12' or platform_machine != 'x86_64' or sys_platform != 'darwin' or (extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda')" }, @@ -1527,10 +1530,12 @@ requires-dist = [ { name = "cmaes" }, { name = "controlnet-aux" }, { name = "datasets" }, + { name = "dice-ml", specifier = ">=0.12" }, { name = "diffusers" }, { name = "evaluate" }, { name = "fastapi", extras = ["all"] }, { name = "filetype" }, + { name = "grad-cam", specifier = ">=1.5.5" }, { name = "greenery", specifier = "==3.2" }, { name = "httpx" }, { name = "huey" }, @@ -1539,6 +1544,7 @@ requires-dist = [ { name = "imblearn" }, { name = "joblib" }, { name = "kink" }, + { name = "lime", specifier = ">=0.2.0.1" }, { name = "llama-cpp-python", marker = "extra == 'cpu'", index = "https://abetlen.github.io/llama-cpp-python/whl/cpu", conflict = { package = "dashai", extra = "cpu" } }, { name = "llama-cpp-python", marker = "extra == 'cuda'" }, { name = "llvmlite" }, @@ -1641,6 +1647,28 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/cc/34/8cc73273414405086c58852916e4031812a6a30fe04c057e37ad99397b7f/detect_installer-0.1.0-py3-none-any.whl", hash = "sha256:034fb20fd665c36e6ba52b8821525ea07fb4f7f938cac459df889fb33801528a", size = 4539, upload-time = "2026-02-23T10:40:23.807Z" }, ] +[[package]] +name = "dice-ml" +version = "0.12" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "jsonschema" }, + { name = "lightgbm" }, + { name = "numpy", version = "2.2.6", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.11' or (extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda')" }, + { name = "numpy", version = "2.4.6", source = { registry = "https://pypi.org/simple" }, marker = "(python_full_version >= '3.11' and platform_machine != 'x86_64') or (python_full_version == '3.11.*' and platform_machine == 'x86_64' and sys_platform == 'darwin') or (python_full_version < '3.11' and platform_machine != 'x86_64' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (python_full_version != '3.11.*' and platform_machine == 'x86_64' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (python_full_version >= '3.11' and sys_platform != 'darwin') or (sys_platform != 'darwin' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda')" }, + { name = "numpy", version = "2.5.0", source = { registry = "https://pypi.org/simple" }, marker = "(python_full_version >= '3.12' and platform_machine == 'x86_64' and sys_platform == 'darwin') or (python_full_version < '3.12' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (platform_machine != 'x86_64' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (sys_platform != 'darwin' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda')" }, + { name = "pandas" }, + { name = "raiutils" }, + { name = "scikit-learn" }, + { name = "tqdm" }, + { name = "xgboost", version = "3.2.0", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.12' or (extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda')" }, + { name = "xgboost", version = "3.3.0", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.12' or (extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda')" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/72/84/05049e71e51caf266c89f6eec4c93c90e0c086d3b75c30c7ffa4d4dd40dc/dice_ml-0.12.tar.gz", hash = "sha256:3e40771ef82ad1084ffe1dd098b801f9cd9d7cdf40efba1b85e38a615ae5a75b", size = 15024998, upload-time = "2025-07-13T17:35:33.481Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/9a/a2/63c11da0358ac2e931b0ab2e2cf203d9a234beeb201d62708733f7f7eea7/dice_ml-0.12-py3-none-any.whl", hash = "sha256:77d8195a40e36ff82ffa4c7fc4d19f364f099497b1be46b2123c7396a2e4bbae", size = 2528224, upload-time = "2025-07-13T17:35:31.115Z" }, +] + [[package]] name = "diffusers" version = "0.39.0" @@ -2252,6 +2280,32 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/da/71/ae30dadffc90b9006d77af76b393cb9dfbfc9629f339fc1574a1c52e6806/future-1.0.0-py3-none-any.whl", hash = "sha256:929292d34f5872e70396626ef385ec22355a1fae8ad29e1a734c3e43f9fbc216", size = 491326, upload-time = "2024-02-21T11:52:35.956Z" }, ] +[[package]] +name = "grad-cam" +version = "1.5.5" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "matplotlib", version = "3.10.9", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.11' or (extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda')" }, + { name = "matplotlib", version = "3.11.0", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.11' or (extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda')" }, + { name = "numpy", version = "2.2.6", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.11' or (extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda')" }, + { name = "numpy", version = "2.4.6", source = { registry = "https://pypi.org/simple" }, marker = "(python_full_version >= '3.11' and platform_machine != 'x86_64') or (python_full_version == '3.11.*' and platform_machine == 'x86_64' and sys_platform == 'darwin') or (python_full_version < '3.11' and platform_machine != 'x86_64' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (python_full_version != '3.11.*' and platform_machine == 'x86_64' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (python_full_version >= '3.11' and sys_platform != 'darwin') or (sys_platform != 'darwin' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda')" }, + { name = "numpy", version = "2.5.0", source = { registry = "https://pypi.org/simple" }, marker = "(python_full_version >= '3.12' and platform_machine == 'x86_64' and sys_platform == 'darwin') or (python_full_version < '3.12' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (platform_machine != 'x86_64' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (sys_platform != 'darwin' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda')" }, + { name = "opencv-python" }, + { name = "pillow" }, + { name = "scikit-learn" }, + { name = "torch", version = "2.11.0+cu128", source = { registry = "https://download.pytorch.org/whl/cu128" }, marker = "extra == 'extra-6-dashai-cuda'" }, + { name = "torch", version = "2.12.1", source = { registry = "https://download.pytorch.org/whl/cpu" }, marker = "(python_full_version < '3.15' and platform_machine != 'x86_64' and sys_platform == 'darwin' and extra == 'extra-6-dashai-cpu') or (python_full_version < '3.12' and platform_machine == 'x86_64' and sys_platform == 'darwin' and extra == 'extra-6-dashai-cpu') or (python_full_version >= '3.15' and platform_machine != 'x86_64' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (python_full_version >= '3.12' and platform_machine == 'x86_64' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (sys_platform != 'darwin' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda')" }, + { name = "torch", version = "2.12.1", source = { registry = "https://pypi.org/simple" }, marker = "(extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (extra != 'extra-6-dashai-cpu' and extra != 'extra-6-dashai-cuda')" }, + { name = "torch", version = "2.12.1+cpu", source = { registry = "https://download.pytorch.org/whl/cpu" }, marker = "(python_full_version >= '3.15' and platform_machine != 'x86_64' and extra == 'extra-6-dashai-cpu') or (python_full_version >= '3.12' and platform_machine == 'x86_64' and extra == 'extra-6-dashai-cpu') or (python_full_version < '3.15' and platform_machine != 'x86_64' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (python_full_version < '3.12' and platform_machine == 'x86_64' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (sys_platform != 'darwin' and extra == 'extra-6-dashai-cpu')" }, + { name = "torchvision", version = "0.26.0+cu128", source = { registry = "https://download.pytorch.org/whl/cu128" }, marker = "extra == 'extra-6-dashai-cuda'" }, + { name = "torchvision", version = "0.27.1", source = { registry = "https://download.pytorch.org/whl/cpu" }, marker = "(python_full_version < '3.15' and platform_machine != 'x86_64' and sys_platform == 'darwin' and extra == 'extra-6-dashai-cpu') or (python_full_version < '3.12' and platform_machine == 'x86_64' and sys_platform == 'darwin' and extra == 'extra-6-dashai-cpu') or (python_full_version >= '3.15' and platform_machine != 'x86_64' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (python_full_version >= '3.12' and platform_machine == 'x86_64' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (sys_platform != 'darwin' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda')" }, + { name = "torchvision", version = "0.27.1", source = { registry = "https://pypi.org/simple" }, marker = "(extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (extra != 'extra-6-dashai-cpu' and extra != 'extra-6-dashai-cuda')" }, + { name = "torchvision", version = "0.27.1+cpu", source = { registry = "https://download.pytorch.org/whl/cpu" }, marker = "(python_full_version >= '3.15' and platform_machine != 'x86_64' and extra == 'extra-6-dashai-cpu') or (python_full_version >= '3.12' and platform_machine == 'x86_64' and extra == 'extra-6-dashai-cpu') or (python_full_version < '3.15' and platform_machine != 'x86_64' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (python_full_version < '3.12' and platform_machine == 'x86_64' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (sys_platform != 'darwin' and extra == 'extra-6-dashai-cpu')" }, + { name = "tqdm" }, + { name = "ttach" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/ee/b3/e8b060e69d4de4b4d8a86868762dbc1ecaa58affa538a8af201a38a408ef/grad-cam-1.5.5.tar.gz", hash = "sha256:690c433d226d35c89c9eb170462db204909cb06b39c7381e6880a49b6fc37015", size = 7783293, upload-time = "2025-04-07T05:13:54.984Z" } + [[package]] name = "greenery" version = "3.2" @@ -2820,6 +2874,34 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/7b/91/984aca2ec129e2757d1e4e3c81c3fcda9d0f85b74670a094cc443d9ee949/joblib-1.5.3-py3-none-any.whl", hash = "sha256:5fc3c5039fc5ca8c0276333a188bbd59d6b7ab37fe6632daa76bc7f9ec18e713", size = 309071, upload-time = "2025-12-15T08:41:44.973Z" }, ] +[[package]] +name = "jsonschema" +version = "4.26.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "attrs" }, + { name = "jsonschema-specifications" }, + { name = "referencing" }, + { name = "rpds-py", version = "0.30.0", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.11' or (extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda')" }, + { name = "rpds-py", version = "2026.6.3", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.11' or (extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda')" }, +] +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" }, +] +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 = "kink" version = "0.9.0" @@ -3061,6 +3143,27 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/06/e6/42a475bfca683b0cd5366f6dd06580062b7e567bb8534d225c877c2f14f3/librt-0.12.0-cp314-cp314t-win_arm64.whl", hash = "sha256:bca1472acbd473eff61059b4409f802c5a1bcb4cd0344d06f939df9c4c125d40", size = 104282, upload-time = "2026-06-30T16:14:09.29Z" }, ] +[[package]] +name = "lightgbm" +version = "4.6.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "numpy", version = "2.2.6", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.11' or (extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda')" }, + { name = "numpy", version = "2.4.6", source = { registry = "https://pypi.org/simple" }, marker = "(python_full_version >= '3.11' and platform_machine != 'x86_64') or (python_full_version == '3.11.*' and platform_machine == 'x86_64' and sys_platform == 'darwin') or (python_full_version < '3.11' and platform_machine != 'x86_64' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (python_full_version != '3.11.*' and platform_machine == 'x86_64' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (python_full_version >= '3.11' and sys_platform != 'darwin') or (sys_platform != 'darwin' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda')" }, + { name = "numpy", version = "2.5.0", source = { registry = "https://pypi.org/simple" }, marker = "(python_full_version >= '3.12' and platform_machine == 'x86_64' and sys_platform == 'darwin') or (python_full_version < '3.12' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (platform_machine != 'x86_64' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (sys_platform != 'darwin' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda')" }, + { name = "scipy", version = "1.15.3", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.11' or (extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda')" }, + { name = "scipy", version = "1.17.1", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version == '3.11.*' or (extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda')" }, + { name = "scipy", version = "1.18.0", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.12' or (extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda')" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/68/0b/a2e9f5c5da7ef047cc60cef37f86185088845e8433e54d2e7ed439cce8a3/lightgbm-4.6.0.tar.gz", hash = "sha256:cb1c59720eb569389c0ba74d14f52351b573af489f230032a1c9f314f8bab7fe", size = 1703705, upload-time = "2025-02-15T04:03:03.111Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/f2/75/cffc9962cca296bc5536896b7e65b4a7cdeb8db208e71b9c0133c08f8f7e/lightgbm-4.6.0-py3-none-macosx_10_15_x86_64.whl", hash = "sha256:b7a393de8a334d5c8e490df91270f0763f83f959574d504c7ccb9eee4aef70ed", size = 2010151, upload-time = "2025-02-15T04:02:50.961Z" }, + { url = "https://files.pythonhosted.org/packages/21/1b/550ee378512b78847930f5d74228ca1fdba2a7fbdeaac9aeccc085b0e257/lightgbm-4.6.0-py3-none-macosx_12_0_arm64.whl", hash = "sha256:2dafd98d4e02b844ceb0b61450a660681076b1ea6c7adb8c566dfd66832aafad", size = 1592172, upload-time = "2025-02-15T04:02:53.937Z" }, + { url = "https://files.pythonhosted.org/packages/64/41/4fbde2c3d29e25ee7c41d87df2f2e5eda65b431ee154d4d462c31041846c/lightgbm-4.6.0-py3-none-manylinux2014_aarch64.whl", hash = "sha256:4d68712bbd2b57a0b14390cbf9376c1d5ed773fa2e71e099cac588703b590336", size = 3454567, upload-time = "2025-02-15T04:02:56.443Z" }, + { url = "https://files.pythonhosted.org/packages/42/86/dabda8fbcb1b00bcfb0003c3776e8ade1aa7b413dff0a2c08f457dace22f/lightgbm-4.6.0-py3-none-manylinux_2_28_x86_64.whl", hash = "sha256:cb19b5afea55b5b61cbb2131095f50538bd608a00655f23ad5d25ae3e3bf1c8d", size = 3569831, upload-time = "2025-02-15T04:02:58.925Z" }, + { url = "https://files.pythonhosted.org/packages/5e/23/f8b28ca248bb629b9e08f877dd2965d1994e1674a03d67cd10c5246da248/lightgbm-4.6.0-py3-none-win_amd64.whl", hash = "sha256:37089ee95664b6550a7189d887dbf098e3eadab03537e411f52c63c121e3ba4b", size = 1451509, upload-time = "2025-02-15T04:03:01.515Z" }, +] + [[package]] name = "lightning-utilities" version = "0.15.3" @@ -3074,6 +3177,26 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/25/f4/ead6e0e37209b07c9baa3e984ccdb0348ca370b77cea3aaea8ddbb097e00/lightning_utilities-0.15.3-py3-none-any.whl", hash = "sha256:6c55f1bee70084a1cbeaa41ada96e4b3a0fea5909e844dd335bd80f5a73c5f91", size = 31906, upload-time = "2026-02-22T14:48:52.488Z" }, ] +[[package]] +name = "lime" +version = "0.2.0.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "matplotlib", version = "3.10.9", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.11' or (extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda')" }, + { name = "matplotlib", version = "3.11.0", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.11' or (extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda')" }, + { name = "numpy", version = "2.2.6", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.11' or (extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda')" }, + { name = "numpy", version = "2.4.6", source = { registry = "https://pypi.org/simple" }, marker = "(python_full_version >= '3.11' and platform_machine != 'x86_64') or (python_full_version == '3.11.*' and platform_machine == 'x86_64' and sys_platform == 'darwin') or (python_full_version < '3.11' and platform_machine != 'x86_64' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (python_full_version != '3.11.*' and platform_machine == 'x86_64' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (python_full_version >= '3.11' and sys_platform != 'darwin') or (sys_platform != 'darwin' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda')" }, + { name = "numpy", version = "2.5.0", source = { registry = "https://pypi.org/simple" }, marker = "(python_full_version >= '3.12' and platform_machine == 'x86_64' and sys_platform == 'darwin') or (python_full_version < '3.12' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (platform_machine != 'x86_64' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (sys_platform != 'darwin' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda')" }, + { name = "scikit-image", version = "0.25.2", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.11' or (extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda')" }, + { name = "scikit-image", version = "0.26.0", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.11' or (extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda')" }, + { name = "scikit-learn" }, + { name = "scipy", version = "1.15.3", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.11' or (extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda')" }, + { name = "scipy", version = "1.17.1", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version == '3.11.*' or (extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda')" }, + { name = "scipy", version = "1.18.0", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.12' or (extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda')" }, + { name = "tqdm" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/f5/86/91a13127d83d793ecb50eb75e716f76e6eda809b6803c5a4ff462339789e/lime-0.2.0.1.tar.gz", hash = "sha256:76960e4f055feb53e89b5022383bafc87b63f25bac6265984b0a333d1a57f781", size = 275719, upload-time = "2020-06-26T21:38:15.46Z" } + [[package]] name = "llama-cpp-python" version = "0.3.32" @@ -6161,6 +6284,41 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/69/76/37c0ccd5ab968a6a438f9c623aeecc84c202ab2fabc6a8fd927580c15b5a/QtPy-2.4.3-py3-none-any.whl", hash = "sha256:72095afe13673e017946cc258b8d5da43314197b741ed2890e563cf384b51aa1", size = 95045, upload-time = "2025-02-11T15:09:24.162Z" }, ] +[[package]] +name = "raiutils" +version = "0.4.2" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "numpy", version = "2.2.6", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.11' or (extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda')" }, + { name = "numpy", version = "2.4.6", source = { registry = "https://pypi.org/simple" }, marker = "(python_full_version >= '3.11' and platform_machine != 'x86_64') or (python_full_version == '3.11.*' and platform_machine == 'x86_64' and sys_platform == 'darwin') or (python_full_version < '3.11' and platform_machine != 'x86_64' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (python_full_version != '3.11.*' and platform_machine == 'x86_64' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (python_full_version >= '3.11' and sys_platform != 'darwin') or (sys_platform != 'darwin' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda')" }, + { name = "numpy", version = "2.5.0", source = { registry = "https://pypi.org/simple" }, marker = "(python_full_version >= '3.12' and platform_machine == 'x86_64' and sys_platform == 'darwin') or (python_full_version < '3.12' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (platform_machine != 'x86_64' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (sys_platform != 'darwin' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda')" }, + { name = "pandas" }, + { name = "requests" }, + { name = "scikit-learn" }, + { name = "scipy", version = "1.15.3", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.11' or (extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda')" }, + { name = "scipy", version = "1.17.1", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version == '3.11.*' or (extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda')" }, + { name = "scipy", version = "1.18.0", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.12' or (extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda')" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/df/4b/ec9518b3f59b38e14be6db4863bfe021e05fab8434bd883f416fbea93351/raiutils-0.4.2.tar.gz", hash = "sha256:d210a4d5a059e48388d341ee02cb87f3c92bbf1f0bcbcecf04fd93a599d2dca4", size = 19817, upload-time = "2024-04-15T21:13:58.204Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/51/81/dde454fb014545f8e3b35b49947e9093f255e95a6ebc2883c75e6d9f8598/raiutils-0.4.2-py3-none-any.whl", hash = "sha256:69b8966c1f5f9ba8e5c4b8ff802b3cd3a379f3a1234f9e412369315d87998192", size = 17554, upload-time = "2024-04-15T21:13:57.117Z" }, +] + +[[package]] +name = "referencing" +version = "0.37.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "attrs" }, + { name = "rpds-py", version = "0.30.0", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.11' or (extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda')" }, + { name = "rpds-py", version = "2026.6.3", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.11' or (extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda')" }, + { name = "typing-extensions", marker = "python_full_version < '3.13' or (extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda')" }, +] +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.6.28" @@ -6463,6 +6621,291 @@ 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" } +resolution-markers = [ + "python_full_version < '3.11' and extra != 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda'", + "python_full_version < '3.11' and sys_platform != 'darwin' and extra == 'extra-6-dashai-cpu' and extra != 'extra-6-dashai-cuda'", + "python_full_version < '3.11' and sys_platform == 'darwin' and extra == 'extra-6-dashai-cpu' and extra != 'extra-6-dashai-cuda'", + "python_full_version < '3.11' and extra != 'extra-6-dashai-cpu' and extra != 'extra-6-dashai-cuda'", +] +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/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" }, + { 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" }, + { 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" }, + { 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" }, + { 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" }, + { 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" }, + { 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" }, + { 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" }, + { 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" }, + { 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" }, + { 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" }, + { 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" }, + { 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" }, + { 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" }, + { 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" }, + { 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" }, + { 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" }, + { url = "https://files.pythonhosted.org/packages/42/bb/1463f0b1722b7f45431bdd468301991d1328b16cffe0b1c2918eba2c4eee/rpds_py-0.30.0-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:07ae8a593e1c3c6b82ca3292efbe73c30b61332fd612e05abee07c79359f292f", size = 402932, upload-time = "2025-11-30T20:21:58.47Z" }, + { url = "https://files.pythonhosted.org/packages/99/ee/2520700a5c1f2d76631f948b0736cdf9b0acb25abd0ca8e889b5c62ac2e3/rpds_py-0.30.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:12f90dd7557b6bd57f40abe7747e81e0c0b119bef015ea7726e69fe550e394a4", size = 525830, upload-time = "2025-11-30T20:21:59.699Z" }, + { url = "https://files.pythonhosted.org/packages/e0/ad/bd0331f740f5705cc555a5e17fdf334671262160270962e69a2bdef3bf76/rpds_py-0.30.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:99b47d6ad9a6da00bec6aabe5a6279ecd3c06a329d4aa4771034a21e335c3a97", size = 412033, upload-time = "2025-11-30T20:22:00.991Z" }, + { url = "https://files.pythonhosted.org/packages/f8/1e/372195d326549bb51f0ba0f2ecb9874579906b97e08880e7a65c3bef1a99/rpds_py-0.30.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:33f559f3104504506a44bb666b93a33f5d33133765b0c216a5bf2f1e1503af89", size = 390828, upload-time = "2025-11-30T20:22:02.723Z" }, + { url = "https://files.pythonhosted.org/packages/ab/2b/d88bb33294e3e0c76bc8f351a3721212713629ffca1700fa94979cb3eae8/rpds_py-0.30.0-cp311-cp311-manylinux_2_31_riscv64.whl", hash = "sha256:946fe926af6e44f3697abbc305ea168c2c31d3e3ef1058cf68f379bf0335a78d", size = 404683, upload-time = "2025-11-30T20:22:04.367Z" }, + { url = "https://files.pythonhosted.org/packages/50/32/c759a8d42bcb5289c1fac697cd92f6fe01a018dd937e62ae77e0e7f15702/rpds_py-0.30.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:495aeca4b93d465efde585977365187149e75383ad2684f81519f504f5c13038", size = 421583, upload-time = "2025-11-30T20:22:05.814Z" }, + { url = "https://files.pythonhosted.org/packages/2b/81/e729761dbd55ddf5d84ec4ff1f47857f4374b0f19bdabfcf929164da3e24/rpds_py-0.30.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:d9a0ca5da0386dee0655b4ccdf46119df60e0f10da268d04fe7cc87886872ba7", size = 572496, upload-time = "2025-11-30T20:22:07.713Z" }, + { url = "https://files.pythonhosted.org/packages/14/f6/69066a924c3557c9c30baa6ec3a0aa07526305684c6f86c696b08860726c/rpds_py-0.30.0-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:8d6d1cc13664ec13c1b84241204ff3b12f9bb82464b8ad6e7a5d3486975c2eed", size = 598669, upload-time = "2025-11-30T20:22:09.312Z" }, + { url = "https://files.pythonhosted.org/packages/5f/48/905896b1eb8a05630d20333d1d8ffd162394127b74ce0b0784ae04498d32/rpds_py-0.30.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:3896fa1be39912cf0757753826bc8bdc8ca331a28a7c4ae46b7a21280b06bb85", size = 561011, upload-time = "2025-11-30T20:22:11.309Z" }, + { url = "https://files.pythonhosted.org/packages/22/16/cd3027c7e279d22e5eb431dd3c0fbc677bed58797fe7581e148f3f68818b/rpds_py-0.30.0-cp311-cp311-win32.whl", hash = "sha256:55f66022632205940f1827effeff17c4fa7ae1953d2b74a8581baaefb7d16f8c", size = 221406, upload-time = "2025-11-30T20:22:13.101Z" }, + { url = "https://files.pythonhosted.org/packages/fa/5b/e7b7aa136f28462b344e652ee010d4de26ee9fd16f1bfd5811f5153ccf89/rpds_py-0.30.0-cp311-cp311-win_amd64.whl", hash = "sha256:a51033ff701fca756439d641c0ad09a41d9242fa69121c7d8769604a0a629825", size = 236024, upload-time = "2025-11-30T20:22:14.853Z" }, + { url = "https://files.pythonhosted.org/packages/14/a6/364bba985e4c13658edb156640608f2c9e1d3ea3c81b27aa9d889fff0e31/rpds_py-0.30.0-cp311-cp311-win_arm64.whl", hash = "sha256:47b0ef6231c58f506ef0b74d44e330405caa8428e770fec25329ed2cb971a229", size = 229069, upload-time = "2025-11-30T20:22:16.577Z" }, + { url = "https://files.pythonhosted.org/packages/03/e7/98a2f4ac921d82f33e03f3835f5bf3a4a40aa1bfdc57975e74a97b2b4bdd/rpds_py-0.30.0-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:a161f20d9a43006833cd7068375a94d035714d73a172b681d8881820600abfad", size = 375086, upload-time = "2025-11-30T20:22:17.93Z" }, + { url = "https://files.pythonhosted.org/packages/4d/a1/bca7fd3d452b272e13335db8d6b0b3ecde0f90ad6f16f3328c6fb150c889/rpds_py-0.30.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:6abc8880d9d036ecaafe709079969f56e876fcf107f7a8e9920ba6d5a3878d05", size = 359053, upload-time = "2025-11-30T20:22:19.297Z" }, + { url = "https://files.pythonhosted.org/packages/65/1c/ae157e83a6357eceff62ba7e52113e3ec4834a84cfe07fa4b0757a7d105f/rpds_py-0.30.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ca28829ae5f5d569bb62a79512c842a03a12576375d5ece7d2cadf8abe96ec28", size = 390763, upload-time = "2025-11-30T20:22:21.661Z" }, + { url = "https://files.pythonhosted.org/packages/d4/36/eb2eb8515e2ad24c0bd43c3ee9cd74c33f7ca6430755ccdb240fd3144c44/rpds_py-0.30.0-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:a1010ed9524c73b94d15919ca4d41d8780980e1765babf85f9a2f90d247153dd", size = 408951, upload-time = "2025-11-30T20:22:23.408Z" }, + { url = "https://files.pythonhosted.org/packages/d6/65/ad8dc1784a331fabbd740ef6f71ce2198c7ed0890dab595adb9ea2d775a1/rpds_py-0.30.0-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f8d1736cfb49381ba528cd5baa46f82fdc65c06e843dab24dd70b63d09121b3f", size = 514622, upload-time = "2025-11-30T20:22:25.16Z" }, + { url = "https://files.pythonhosted.org/packages/63/8e/0cfa7ae158e15e143fe03993b5bcd743a59f541f5952e1546b1ac1b5fd45/rpds_py-0.30.0-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:d948b135c4693daff7bc2dcfc4ec57237a29bd37e60c2fabf5aff2bbacf3e2f1", size = 414492, upload-time = "2025-11-30T20:22:26.505Z" }, + { url = "https://files.pythonhosted.org/packages/60/1b/6f8f29f3f995c7ffdde46a626ddccd7c63aefc0efae881dc13b6e5d5bb16/rpds_py-0.30.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:47f236970bccb2233267d89173d3ad2703cd36a0e2a6e92d0560d333871a3d23", size = 394080, upload-time = "2025-11-30T20:22:27.934Z" }, + { url = "https://files.pythonhosted.org/packages/6d/d5/a266341051a7a3ca2f4b750a3aa4abc986378431fc2da508c5034d081b70/rpds_py-0.30.0-cp312-cp312-manylinux_2_31_riscv64.whl", hash = "sha256:2e6ecb5a5bcacf59c3f912155044479af1d0b6681280048b338b28e364aca1f6", size = 408680, upload-time = "2025-11-30T20:22:29.341Z" }, + { url = "https://files.pythonhosted.org/packages/10/3b/71b725851df9ab7a7a4e33cf36d241933da66040d195a84781f49c50490c/rpds_py-0.30.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:a8fa71a2e078c527c3e9dc9fc5a98c9db40bcc8a92b4e8858e36d329f8684b51", size = 423589, upload-time = "2025-11-30T20:22:31.469Z" }, + { url = "https://files.pythonhosted.org/packages/00/2b/e59e58c544dc9bd8bd8384ecdb8ea91f6727f0e37a7131baeff8d6f51661/rpds_py-0.30.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:73c67f2db7bc334e518d097c6d1e6fed021bbc9b7d678d6cc433478365d1d5f5", size = 573289, upload-time = "2025-11-30T20:22:32.997Z" }, + { url = "https://files.pythonhosted.org/packages/da/3e/a18e6f5b460893172a7d6a680e86d3b6bc87a54c1f0b03446a3c8c7b588f/rpds_py-0.30.0-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:5ba103fb455be00f3b1c2076c9d4264bfcb037c976167a6047ed82f23153f02e", size = 599737, upload-time = "2025-11-30T20:22:34.419Z" }, + { url = "https://files.pythonhosted.org/packages/5c/e2/714694e4b87b85a18e2c243614974413c60aa107fd815b8cbc42b873d1d7/rpds_py-0.30.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:7cee9c752c0364588353e627da8a7e808a66873672bcb5f52890c33fd965b394", size = 563120, upload-time = "2025-11-30T20:22:35.903Z" }, + { url = "https://files.pythonhosted.org/packages/6f/ab/d5d5e3bcedb0a77f4f613706b750e50a5a3ba1c15ccd3665ecc636c968fd/rpds_py-0.30.0-cp312-cp312-win32.whl", hash = "sha256:1ab5b83dbcf55acc8b08fc62b796ef672c457b17dbd7820a11d6c52c06839bdf", size = 223782, upload-time = "2025-11-30T20:22:37.271Z" }, + { url = "https://files.pythonhosted.org/packages/39/3b/f786af9957306fdc38a74cef405b7b93180f481fb48453a114bb6465744a/rpds_py-0.30.0-cp312-cp312-win_amd64.whl", hash = "sha256:a090322ca841abd453d43456ac34db46e8b05fd9b3b4ac0c78bcde8b089f959b", size = 240463, upload-time = "2025-11-30T20:22:39.021Z" }, + { url = "https://files.pythonhosted.org/packages/f3/d2/b91dc748126c1559042cfe41990deb92c4ee3e2b415f6b5234969ffaf0cc/rpds_py-0.30.0-cp312-cp312-win_arm64.whl", hash = "sha256:669b1805bd639dd2989b281be2cfd951c6121b65e729d9b843e9639ef1fd555e", size = 230868, upload-time = "2025-11-30T20:22:40.493Z" }, + { 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/0b/5d/47c4655e9bcd5ca907148535c10e7d489044243cc9941c16ed7cd53be91d/rpds_py-0.30.0-cp313-cp313-win32.whl", hash = "sha256:b40fb160a2db369a194cb27943582b38f79fc4887291417685f3ad693c5a1d5d", size = 223139, upload-time = "2025-11-30T20:23:00.209Z" }, + { url = "https://files.pythonhosted.org/packages/f2/e1/485132437d20aa4d3e1d8b3fb5a5e65aa8139f1e097080c2a8443201742c/rpds_py-0.30.0-cp313-cp313-win_amd64.whl", hash = "sha256:806f36b1b605e2d6a72716f321f20036b9489d29c51c91f4dd29a3e3afb73b15", size = 240224, upload-time = "2025-11-30T20:23:02.008Z" }, + { url = "https://files.pythonhosted.org/packages/24/95/ffd128ed1146a153d928617b0ef673960130be0009c77d8fbf0abe306713/rpds_py-0.30.0-cp313-cp313-win_arm64.whl", hash = "sha256:d96c2086587c7c30d44f31f42eae4eac89b60dabbac18c7669be3700f13c3ce1", size = 230645, upload-time = "2025-11-30T20:23:03.43Z" }, + { 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/f9/39/7e067bb06c31de48de3eb200f9fc7c58982a4d3db44b07e73963e10d3be9/rpds_py-0.30.0-cp313-cp313t-win32.whl", hash = "sha256:3d4a69de7a3e50ffc214ae16d79d8fbb0922972da0356dcf4d0fdca2878559c6", size = 211341, upload-time = "2025-11-30T20:23:24.449Z" }, + { url = "https://files.pythonhosted.org/packages/0a/4d/222ef0b46443cf4cf46764d9c630f3fe4abaa7245be9417e56e9f52b8f65/rpds_py-0.30.0-cp313-cp313t-win_amd64.whl", hash = "sha256:f14fc5df50a716f7ece6a80b6c78bb35ea2ca47c499e422aa4463455dd96d56d", size = 225768, upload-time = "2025-11-30T20:23:25.908Z" }, + { 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/72/c7/81dadd7b27c8ee391c132a6b192111ca58d866577ce2d9b0ca157552cce0/rpds_py-0.30.0-cp314-cp314-win32.whl", hash = "sha256:ee454b2a007d57363c2dfd5b6ca4a5d7e2c518938f8ed3b706e37e5d470801ed", size = 215298, upload-time = "2025-11-30T20:23:47.696Z" }, + { url = "https://files.pythonhosted.org/packages/3e/d2/1aaac33287e8cfb07aab2e6b8ac1deca62f6f65411344f1433c55e6f3eb8/rpds_py-0.30.0-cp314-cp314-win_amd64.whl", hash = "sha256:95f0802447ac2d10bcc69f6dc28fe95fdf17940367b21d34e34c737870758950", size = 228604, upload-time = "2025-11-30T20:23:49.501Z" }, + { url = "https://files.pythonhosted.org/packages/e8/95/ab005315818cc519ad074cb7784dae60d939163108bd2b394e60dc7b5461/rpds_py-0.30.0-cp314-cp314-win_arm64.whl", hash = "sha256:613aa4771c99f03346e54c3f038e4cc574ac09a3ddfb0e8878487335e96dead6", size = 222391, upload-time = "2025-11-30T20:23:50.96Z" }, + { 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" }, + { url = "https://files.pythonhosted.org/packages/20/53/7c7e784abfa500a2b6b583b147ee4bb5a2b3747a9166bab52fec4b5b5e7d/rpds_py-0.30.0-cp314-cp314t-win32.whl", hash = "sha256:dc824125c72246d924f7f796b4f63c1e9dc810c7d9e2355864b3c3a73d59ade0", size = 211570, upload-time = "2025-11-30T20:24:12.735Z" }, + { url = "https://files.pythonhosted.org/packages/d0/02/fa464cdfbe6b26e0600b62c528b72d8608f5cc49f96b8d6e38c95d60c676/rpds_py-0.30.0-cp314-cp314t-win_amd64.whl", hash = "sha256:27f4b0e92de5bfbc6f86e43959e6edd1425c33b5e69aab0984a72047f2bcf1e3", size = 226532, upload-time = "2025-11-30T20:24:14.634Z" }, + { url = "https://files.pythonhosted.org/packages/69/71/3f34339ee70521864411f8b6992e7ab13ac30d8e4e3309e07c7361767d91/rpds_py-0.30.0-pp311-pypy311_pp73-macosx_10_12_x86_64.whl", hash = "sha256:c2262bdba0ad4fc6fb5545660673925c2d2a5d9e2e0fb603aad545427be0fc58", size = 372292, upload-time = "2025-11-30T20:24:16.537Z" }, + { url = "https://files.pythonhosted.org/packages/57/09/f183df9b8f2d66720d2ef71075c59f7e1b336bec7ee4c48f0a2b06857653/rpds_py-0.30.0-pp311-pypy311_pp73-macosx_11_0_arm64.whl", hash = "sha256:ee6af14263f25eedc3bb918a3c04245106a42dfd4f5c2285ea6f997b1fc3f89a", size = 362128, upload-time = "2025-11-30T20:24:18.086Z" }, + { url = "https://files.pythonhosted.org/packages/7a/68/5c2594e937253457342e078f0cc1ded3dd7b2ad59afdbf2d354869110a02/rpds_py-0.30.0-pp311-pypy311_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3adbb8179ce342d235c31ab8ec511e66c73faa27a47e076ccc92421add53e2bb", size = 391542, upload-time = "2025-11-30T20:24:20.092Z" }, + { url = "https://files.pythonhosted.org/packages/49/5c/31ef1afd70b4b4fbdb2800249f34c57c64beb687495b10aec0365f53dfc4/rpds_py-0.30.0-pp311-pypy311_pp73-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:250fa00e9543ac9b97ac258bd37367ff5256666122c2d0f2bc97577c60a1818c", size = 404004, upload-time = "2025-11-30T20:24:22.231Z" }, + { url = "https://files.pythonhosted.org/packages/e3/63/0cfbea38d05756f3440ce6534d51a491d26176ac045e2707adc99bb6e60a/rpds_py-0.30.0-pp311-pypy311_pp73-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:9854cf4f488b3d57b9aaeb105f06d78e5529d3145b1e4a41750167e8c213c6d3", size = 527063, upload-time = "2025-11-30T20:24:24.302Z" }, + { url = "https://files.pythonhosted.org/packages/42/e6/01e1f72a2456678b0f618fc9a1a13f882061690893c192fcad9f2926553a/rpds_py-0.30.0-pp311-pypy311_pp73-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:993914b8e560023bc0a8bf742c5f303551992dcb85e247b1e5c7f4a7d145bda5", size = 413099, upload-time = "2025-11-30T20:24:25.916Z" }, + { url = "https://files.pythonhosted.org/packages/b8/25/8df56677f209003dcbb180765520c544525e3ef21ea72279c98b9aa7c7fb/rpds_py-0.30.0-pp311-pypy311_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:58edca431fb9b29950807e301826586e5bbf24163677732429770a697ffe6738", size = 392177, upload-time = "2025-11-30T20:24:27.834Z" }, + { url = "https://files.pythonhosted.org/packages/4a/b4/0a771378c5f16f8115f796d1f437950158679bcd2a7c68cf251cfb00ed5b/rpds_py-0.30.0-pp311-pypy311_pp73-manylinux_2_31_riscv64.whl", hash = "sha256:dea5b552272a944763b34394d04577cf0f9bd013207bc32323b5a89a53cf9c2f", size = 406015, upload-time = "2025-11-30T20:24:29.457Z" }, + { url = "https://files.pythonhosted.org/packages/36/d8/456dbba0af75049dc6f63ff295a2f92766b9d521fa00de67a2bd6427d57a/rpds_py-0.30.0-pp311-pypy311_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:ba3af48635eb83d03f6c9735dfb21785303e73d22ad03d489e88adae6eab8877", size = 423736, upload-time = "2025-11-30T20:24:31.22Z" }, + { url = "https://files.pythonhosted.org/packages/13/64/b4d76f227d5c45a7e0b796c674fd81b0a6c4fbd48dc29271857d8219571c/rpds_py-0.30.0-pp311-pypy311_pp73-musllinux_1_2_aarch64.whl", hash = "sha256:dff13836529b921e22f15cb099751209a60009731a68519630a24d61f0b1b30a", size = 573981, upload-time = "2025-11-30T20:24:32.934Z" }, + { url = "https://files.pythonhosted.org/packages/20/91/092bacadeda3edf92bf743cc96a7be133e13a39cdbfd7b5082e7ab638406/rpds_py-0.30.0-pp311-pypy311_pp73-musllinux_1_2_i686.whl", hash = "sha256:1b151685b23929ab7beec71080a8889d4d6d9fa9a983d213f07121205d48e2c4", size = 599782, upload-time = "2025-11-30T20:24:35.169Z" }, + { url = "https://files.pythonhosted.org/packages/d1/b7/b95708304cd49b7b6f82fdd039f1748b66ec2b21d6a45180910802f1abf1/rpds_py-0.30.0-pp311-pypy311_pp73-musllinux_1_2_x86_64.whl", hash = "sha256:ac37f9f516c51e5753f27dfdef11a88330f04de2d564be3991384b2f3535d02e", size = 562191, upload-time = "2025-11-30T20:24:36.853Z" }, +] + +[[package]] +name = "rpds-py" +version = "2026.6.3" +source = { registry = "https://pypi.org/simple" } +resolution-markers = [ + "python_full_version >= '3.15' and platform_machine == 'x86_64' and sys_platform == 'darwin' and extra != 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda'", + "python_full_version == '3.14.*' and platform_machine == 'x86_64' and sys_platform == 'darwin' and extra != 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda'", + "python_full_version == '3.13.*' and platform_machine == 'x86_64' and sys_platform == 'darwin' and extra != 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda'", + "python_full_version == '3.12.*' and platform_machine == 'x86_64' and sys_platform == 'darwin' and extra != 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda'", + "(python_full_version >= '3.15' and platform_machine != 'x86_64' and extra != 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (python_full_version >= '3.15' and sys_platform != 'darwin' and extra != 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda')", + "(python_full_version == '3.14.*' and platform_machine != 'x86_64' and extra != 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (python_full_version == '3.14.*' and sys_platform != 'darwin' and extra != 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda')", + "(python_full_version == '3.13.*' and platform_machine != 'x86_64' and extra != 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (python_full_version == '3.13.*' and sys_platform != 'darwin' and extra != 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda')", + "(python_full_version == '3.12.*' and platform_machine != 'x86_64' and extra != 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (python_full_version == '3.12.*' and sys_platform != 'darwin' and extra != 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda')", + "python_full_version == '3.11.*' and extra != 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda'", + "python_full_version >= '3.15' and platform_machine == 'x86_64' and sys_platform == 'darwin' and extra == 'extra-6-dashai-cpu' and extra != 'extra-6-dashai-cuda'", + "python_full_version == '3.14.*' and platform_machine == 'x86_64' and sys_platform == 'darwin' and extra == 'extra-6-dashai-cpu' and extra != 'extra-6-dashai-cuda'", + "python_full_version == '3.13.*' and platform_machine == 'x86_64' and sys_platform == 'darwin' and extra == 'extra-6-dashai-cpu' and extra != 'extra-6-dashai-cuda'", + "python_full_version == '3.12.*' and platform_machine == 'x86_64' and sys_platform == 'darwin' and extra == 'extra-6-dashai-cpu' and extra != 'extra-6-dashai-cuda'", + "python_full_version >= '3.15' and sys_platform != 'darwin' and extra == 'extra-6-dashai-cpu' and extra != 'extra-6-dashai-cuda'", + "python_full_version == '3.14.*' and sys_platform != 'darwin' and extra == 'extra-6-dashai-cpu' and extra != 'extra-6-dashai-cuda'", + "python_full_version == '3.13.*' and sys_platform != 'darwin' and extra == 'extra-6-dashai-cpu' and extra != 'extra-6-dashai-cuda'", + "python_full_version == '3.12.*' and sys_platform != 'darwin' and extra == 'extra-6-dashai-cpu' and extra != 'extra-6-dashai-cuda'", + "python_full_version >= '3.15' and platform_machine != 'x86_64' and sys_platform == 'darwin' and extra == 'extra-6-dashai-cpu' and extra != 'extra-6-dashai-cuda'", + "python_full_version == '3.14.*' and platform_machine != 'x86_64' and sys_platform == 'darwin' and extra == 'extra-6-dashai-cpu' and extra != 'extra-6-dashai-cuda'", + "python_full_version == '3.13.*' and platform_machine != 'x86_64' and sys_platform == 'darwin' and extra == 'extra-6-dashai-cpu' and extra != 'extra-6-dashai-cuda'", + "python_full_version == '3.12.*' and platform_machine != 'x86_64' and sys_platform == 'darwin' and extra == 'extra-6-dashai-cpu' and extra != 'extra-6-dashai-cuda'", + "python_full_version == '3.11.*' and sys_platform != 'darwin' and extra == 'extra-6-dashai-cpu' and extra != 'extra-6-dashai-cuda'", + "python_full_version == '3.11.*' and sys_platform == 'darwin' and extra == 'extra-6-dashai-cpu' and extra != 'extra-6-dashai-cuda'", + "python_full_version >= '3.15' and platform_machine == 'x86_64' and sys_platform == 'darwin' and extra != 'extra-6-dashai-cpu' and extra != 'extra-6-dashai-cuda'", + "python_full_version == '3.14.*' and platform_machine == 'x86_64' and sys_platform == 'darwin' and extra != 'extra-6-dashai-cpu' and extra != 'extra-6-dashai-cuda'", + "python_full_version == '3.13.*' and platform_machine == 'x86_64' and sys_platform == 'darwin' and extra != 'extra-6-dashai-cpu' and extra != 'extra-6-dashai-cuda'", + "python_full_version == '3.12.*' and platform_machine == 'x86_64' and sys_platform == 'darwin' and extra != 'extra-6-dashai-cpu' and extra != 'extra-6-dashai-cuda'", + "(python_full_version >= '3.15' and platform_machine != 'x86_64' and extra != 'extra-6-dashai-cpu' and extra != 'extra-6-dashai-cuda') or (python_full_version >= '3.15' and sys_platform != 'darwin' and extra != 'extra-6-dashai-cpu' and extra != 'extra-6-dashai-cuda')", + "(python_full_version == '3.14.*' and platform_machine != 'x86_64' and extra != 'extra-6-dashai-cpu' and extra != 'extra-6-dashai-cuda') or (python_full_version == '3.14.*' and sys_platform != 'darwin' and extra != 'extra-6-dashai-cpu' and extra != 'extra-6-dashai-cuda')", + "(python_full_version == '3.13.*' and platform_machine != 'x86_64' and extra != 'extra-6-dashai-cpu' and extra != 'extra-6-dashai-cuda') or (python_full_version == '3.13.*' and sys_platform != 'darwin' and extra != 'extra-6-dashai-cpu' and extra != 'extra-6-dashai-cuda')", + "(python_full_version == '3.12.*' and platform_machine != 'x86_64' and extra != 'extra-6-dashai-cpu' and extra != 'extra-6-dashai-cuda') or (python_full_version == '3.12.*' and sys_platform != 'darwin' and extra != 'extra-6-dashai-cpu' and extra != 'extra-6-dashai-cuda')", + "python_full_version == '3.11.*' and extra != 'extra-6-dashai-cpu' and extra != 'extra-6-dashai-cuda'", +] +sdist = { url = "https://files.pythonhosted.org/packages/aa/2a/9618a122aeb2a169a28b03889a2995fe297588964333d4a7d67bdf46e147/rpds_py-2026.6.3.tar.gz", hash = "sha256:1cebd1337c242e4ec2293e541f712b2da849b29f48f0c293684b71c0632625d4", size = 64051, upload-time = "2026-06-30T07:17:53.009Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/94/1f/a2dca5ffdbf1d475ffc4e80e4d5d720ff3a00f691795910116960ee12511/rpds_py-2026.6.3-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:7b689145a1485c335569bd056464f3243a29af7ed3871c7be31ad624ba239bc7", size = 342174, upload-time = "2026-06-30T07:14:54.821Z" }, + { url = "https://files.pythonhosted.org/packages/4d/dc/323d08583c0832911768663d1944f0107fcd4088704858d84b5e06d105a0/rpds_py-2026.6.3-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:db08f45aecde626498fb3df07bcf6d2ec040af42e859a4f5040d79c200342911", size = 345513, upload-time = "2026-06-30T07:14:56.515Z" }, + { url = "https://files.pythonhosted.org/packages/0b/2a/e31989834d18d2f26ec1d2774c5b1eb3331df4ea8ada525175294c94b48a/rpds_py-2026.6.3-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:acc992ab27b15f852c76755eb2ab7dce86585ddadba6fa5946e58556088845b4", size = 373783, upload-time = "2026-06-30T07:14:57.736Z" }, + { url = "https://files.pythonhosted.org/packages/87/fe/e80107ee3639585c9941c17d6a42cd65325022f656c023191fce78c324c8/rpds_py-2026.6.3-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:7f88d653e7b3b779d71ae7454e20dcc9b6bae903f33c269db9f2be41bda3f261", size = 378316, upload-time = "2026-06-30T07:14:59.077Z" }, + { url = "https://files.pythonhosted.org/packages/22/6f/81e3adf81acfb6fa694de2a6e4e7d8863121e3e0799e0a7725e6cf5679c4/rpds_py-2026.6.3-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e52655eaf81e32593abedaa4bfe33170c8cfedf3365ed9be6e11e07f148f0278", size = 499423, upload-time = "2026-06-30T07:15:00.488Z" }, + { url = "https://files.pythonhosted.org/packages/2d/9a/41263969df0ce3d9af2a96d5005a288200af1989aed3354bfceb5fc0b21f/rpds_py-2026.6.3-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:dfcc8b909769d19db55c7cc9541eb64b9b774b1057ffffb4f1048070475bb9f9", size = 386077, upload-time = "2026-06-30T07:15:01.911Z" }, + { url = "https://files.pythonhosted.org/packages/5e/19/7e98f468bd50346faff5b10e5297374b443bfdddacc8e9fbc65984539597/rpds_py-2026.6.3-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9c1255b302953c86a486b81d330d5ee1d5bd937691ce271b6be0ef0e299eaab7", size = 371315, upload-time = "2026-06-30T07:15:03.317Z" }, + { url = "https://files.pythonhosted.org/packages/99/3c/2b973b4d371906a134b03decfea7f5d9835a2c6d263454392e15b64b5b18/rpds_py-2026.6.3-cp311-cp311-manylinux_2_31_riscv64.whl", hash = "sha256:8d2294a31386bfa251d8c8a39472beee17db67d4f1a6eabea665d35c9a4461c3", size = 383502, upload-time = "2026-06-30T07:15:04.627Z" }, + { url = "https://files.pythonhosted.org/packages/98/2a/12e2799500af0a307bca76b63361c51f9fe479223561489c29eea1f2ee41/rpds_py-2026.6.3-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:f8f23ead891a3b762f35ab3b04623da7056545b48aa60d59957e6789914545da", size = 402673, upload-time = "2026-06-30T07:15:05.856Z" }, + { url = "https://files.pythonhosted.org/packages/2d/e3/21e5872d165fe08be4f229e3d5ee9d90019c0bf0e5538de60dbd54009450/rpds_py-2026.6.3-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:421aba32367055614287a4292b6a17f1939c9452299f7a0209c117e990b646d4", size = 549964, upload-time = "2026-06-30T07:15:07.159Z" }, + { url = "https://files.pythonhosted.org/packages/1a/d0/5ee0fe36844297de8123bee27bc12078c1a7416ad9f1b8a8ca18d6b0c0ac/rpds_py-2026.6.3-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:1e5822dfc2f0d4ab7e745eaa6d85945069329beeccef965af3f3bb26058fcab6", size = 615446, upload-time = "2026-06-30T07:15:08.531Z" }, + { url = "https://files.pythonhosted.org/packages/b1/80/1ea5873cb683f2fbe5f21b23ea1f6d179ead19f3c5b249b7eb5dca568ef2/rpds_py-2026.6.3-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:83e35b57523816c8613fd0776b40cd8bb9f596b37ddd2692eb4a6bb5ab2f8c93", size = 576975, upload-time = "2026-06-30T07:15:09.97Z" }, + { url = "https://files.pythonhosted.org/packages/c9/e1/90ef639217a5ddb15b7f4f61b1c33911fd044ad03c311bafdd2bcab85582/rpds_py-2026.6.3-cp311-cp311-win32.whl", hash = "sha256:de3eceba0b683bcbb1ab93da016d0270df1f9ae7be716b40214c5dafac6ea45a", size = 204453, upload-time = "2026-06-30T07:15:11.324Z" }, + { url = "https://files.pythonhosted.org/packages/f2/b7/b7a1695d7af36f521fb11e80d6d3adbd744f73b921859bd3c2a2c0dc706f/rpds_py-2026.6.3-cp311-cp311-win_amd64.whl", hash = "sha256:2c54a076ca4d370980ab57bc0e31df57bbe8d41340436a90ef8b1219a3cbb127", size = 223219, upload-time = "2026-06-30T07:15:12.476Z" }, + { url = "https://files.pythonhosted.org/packages/d7/a2/145afacf796e4506062825941176ad9445c2dcf2b3b6a1f13d3030a15e19/rpds_py-2026.6.3-cp311-cp311-win_arm64.whl", hash = "sha256:168c733a7112e071bb7a66460e667edfcff06c017a3c523f7a8a8e08d0140804", size = 219137, upload-time = "2026-06-30T07:15:13.631Z" }, + { url = "https://files.pythonhosted.org/packages/5c/be/2e8974163072e7bab7df1a5acd54c4498e75e35d6d18b864d3a9d5dadc92/rpds_py-2026.6.3-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:a0811d33247c3d6128a3001d763f2aa056bb3425204335400ac54f89eec3a0d0", size = 343691, upload-time = "2026-06-30T07:15:14.96Z" }, + { url = "https://files.pythonhosted.org/packages/a4/73/319dfa745dd668efe89309141ded489126461fcecd2b8f3a3cda185129b6/rpds_py-2026.6.3-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:538949e262e46caa31ac01bdb3c1e8f642622922cacbabbae6a8445d9dc33eaf", size = 338542, upload-time = "2026-06-30T07:15:16.267Z" }, + { url = "https://files.pythonhosted.org/packages/21/63/4239893be1c4d09b709b1a8f6be4188f0870084ff547f46606b8a75f1b03/rpds_py-2026.6.3-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:55927d532399c2c646100ff7feb48eaa940ad70f42cd68e1328f3ded9f81ca24", size = 368180, upload-time = "2026-06-30T07:15:17.62Z" }, + { url = "https://files.pythonhosted.org/packages/1c/ca/9c5de382225234ceb37b1844ebdb140db12b2a278bb9efe2fcd19f6c82ce/rpds_py-2026.6.3-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:f56f1695bc5c0871cbc33dc0130fcf503aab0c57dcc5a6700a4f49eba4f2652e", size = 375067, upload-time = "2026-06-30T07:15:18.952Z" }, + { url = "https://files.pythonhosted.org/packages/87/dc/863f69d1bf04ade34b7fe0d59b9fdf6f0135fe2d7cbca74f1d665589559d/rpds_py-2026.6.3-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:270b293dae9058fc9fcedab50f13cebf46fb8ed1d1d54e0521a9da5d6b211975", size = 490509, upload-time = "2026-06-30T07:15:20.434Z" }, + { url = "https://files.pythonhosted.org/packages/ce/ef/eac16a12048b45ec7c7fa94f2be3438a5f26bf9cc8580b18a1cfd609b7f6/rpds_py-2026.6.3-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:127565fead0a10943b282957bd5447804ff3160ad79f2ad2635e6d249e380680", size = 382754, upload-time = "2026-06-30T07:15:21.831Z" }, + { url = "https://files.pythonhosted.org/packages/04/8f/d2f3f532616be4d06c316ef119683e832bd3d41e112bf3a88f4151c95b17/rpds_py-2026.6.3-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ecabd69db66de867690f9797f2f8fa27ba501bbc24540cbdbdc649cd15888ba6", size = 366189, upload-time = "2026-06-30T07:15:23.371Z" }, + { url = "https://files.pythonhosted.org/packages/e3/29/41a7b0e98a4b44cd676ab7598419623373eb43b20be68c084935c1a8cf88/rpds_py-2026.6.3-cp312-cp312-manylinux_2_31_riscv64.whl", hash = "sha256:58eadac9cd119677b60e1cf8ac4052f35949d71b8a9e5556efccbe82533cf22a", size = 377750, upload-time = "2026-06-30T07:15:24.659Z" }, + { url = "https://files.pythonhosted.org/packages/2e/05/ecda0bec46f9a1565090bcdc941d023f6a25aff85fda28f89f8d19878152/rpds_py-2026.6.3-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:7491ee23305ac3eb59e492b6945881f5cd77a6f731061a3f25b77fd40f9e99a4", size = 395576, upload-time = "2026-06-30T07:15:25.987Z" }, + { url = "https://files.pythonhosted.org/packages/68/a8/6ed52f03ee6cb854ce78785cc9a9a672eb880e83fd7224d471f667d151f1/rpds_py-2026.6.3-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:2c99f7e8ccb3dd6e3e4bfeac657a7b208c9bac8075f4b078c02d7404c34107fa", size = 543807, upload-time = "2026-06-30T07:15:27.356Z" }, + { url = "https://files.pythonhosted.org/packages/8f/d6/156c0d3eea27ba09b92562ba2364ba124c0a061b199e17eac637cd25a5e2/rpds_py-2026.6.3-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:62698275682bf121181861295c9181e789030a2d516071f5b8f3c23c170cd0fc", size = 611187, upload-time = "2026-06-30T07:15:28.931Z" }, + { url = "https://files.pythonhosted.org/packages/f1/31/774212ed989c62f7f310220089f9b0a3fb8f40f5443d1727abd5d9f52bc9/rpds_py-2026.6.3-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:a214c993455f99a89aaeadc9b21241900037adc9d97203e374d75513c5911822", size = 573030, upload-time = "2026-06-30T07:15:30.553Z" }, + { url = "https://files.pythonhosted.org/packages/c9/50/22f73127a41f1ce4f87fe39aadfb9a126345801c274aa93ae88456249327/rpds_py-2026.6.3-cp312-cp312-win32.whl", hash = "sha256:501f9f04a588d6a09179368c57071301445191767c64e4b52a6aa9871f1ef5ed", size = 202185, upload-time = "2026-06-30T07:15:32.027Z" }, + { url = "https://files.pythonhosted.org/packages/04/3a/f0ee4d4dde9d3b69dedf1b5f74e7a40017046d55052d173e418c6a94f960/rpds_py-2026.6.3-cp312-cp312-win_amd64.whl", hash = "sha256:2c958bf94822e9290a40aaf2a822d4bc5c88099093e3948ad6c571eca9272e5f", size = 220394, upload-time = "2026-06-30T07:15:33.359Z" }, + { url = "https://files.pythonhosted.org/packages/f3/83/3382fe37f809b59f02aac04dbc4e765b480b46ee0227ed516e3bdc4d3dfc/rpds_py-2026.6.3-cp312-cp312-win_arm64.whl", hash = "sha256:22bffe6042b9bcb0822bcd1955ec00e245daf17b4344e4ed8e9551b976b63e96", size = 215753, upload-time = "2026-06-30T07:15:34.778Z" }, + { url = "https://files.pythonhosted.org/packages/a4/9e/b818ee580026ec578138e961027a68820c40afeb1ec8f6819b54fb99e196/rpds_py-2026.6.3-cp313-cp313-macosx_10_12_x86_64.whl", hash = "sha256:3cfe765c1da0072636ca06628261e0ea05688e160d5c8a03e0217c3854037223", size = 343012, upload-time = "2026-06-30T07:15:36.005Z" }, + { url = "https://files.pythonhosted.org/packages/f3/6b/686d9dc4359a8f163cfbbf89ee0b4e586431de22fe8248edb63a8cf50d49/rpds_py-2026.6.3-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:f4d78253f6996be4901669ad25319f842f740eccf4d58e3c7f3dd39e6dde1d8f", size = 338203, upload-time = "2026-06-30T07:15:37.462Z" }, + { url = "https://files.pythonhosted.org/packages/9e/9b/069aa329940f8207615e091f5eedbbd40e1e15eac68a0790fd05ccdf796c/rpds_py-2026.6.3-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:54f45a148e28767bf343d33a684693c70e451c6f4c0e9904709a723fafbdfc1f", size = 367984, upload-time = "2026-06-30T07:15:39.008Z" }, + { url = "https://files.pythonhosted.org/packages/14/db/34c203e4becff3703e4d3bc121842c00b8689197f398161203a880052f4e/rpds_py-2026.6.3-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:842e7b070435622248c7a2c44ae53fa1440e073cc3023bc919fed570884097a7", size = 374815, upload-time = "2026-06-30T07:15:40.253Z" }, + { url = "https://files.pythonhosted.org/packages/ee/7d/8071067d2cc453d916ad836e828c943f575e8a44612537759002a1e07381/rpds_py-2026.6.3-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:8020133a74bd81b4572dd8e4be028a6b1ebcd70e6726edc3918008c08bee6ee6", size = 490545, upload-time = "2026-06-30T07:15:41.729Z" }, + { url = "https://files.pythonhosted.org/packages/a3/42/da06c5aa8f0484ff07f270787434204d9f4535e2f8c3b51ed402267e63c3/rpds_py-2026.6.3-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:cdc7e35386f3847df728fbcb5e887e2d79c19e2fa1eba9e51b6621d23e3243af", size = 382828, upload-time = "2026-06-30T07:15:43.327Z" }, + { url = "https://files.pythonhosted.org/packages/57/d7/fe978efc2ae50abe48eb7464668ea99f53c010c60aeebb7b35ad27f23661/rpds_py-2026.6.3-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:acac386b453c2516111b50985d60ce46e7fadb5ea71ae7b25f4c946935bf27cf", size = 365678, upload-time = "2026-06-30T07:15:44.992Z" }, + { url = "https://files.pythonhosted.org/packages/69/9d/1d8922e1990b2a6eb532b6ff53d3e73d2b3bbffc84116c75826bee73dfc6/rpds_py-2026.6.3-cp313-cp313-manylinux_2_31_riscv64.whl", hash = "sha256:425560c6fa0415f27261727bb20bd097568485e5eb0c121f1949417d1c516885", size = 377811, upload-time = "2026-06-30T07:15:46.523Z" }, + { url = "https://files.pythonhosted.org/packages/b1/3d/198dceafb4fb034a6a47347e1b0735d34e0bd4a50be4e898d408ee66cb14/rpds_py-2026.6.3-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:a550fb4950a06dde3beb4721f5ad4b25bf4513784665b0a8522c792e2bd822a4", size = 395382, upload-time = "2026-06-30T07:15:47.955Z" }, + { url = "https://files.pythonhosted.org/packages/1f/f1/13968e49655d40b6b19d8b9140296bbc6f1d86b3f0f6c346cf9f1adddf4b/rpds_py-2026.6.3-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:4f4bca01b63096f606e095734dd56e74e175f94cfbf24ff3d63281cec61f7bb7", size = 543832, upload-time = "2026-06-30T07:15:49.33Z" }, + { url = "https://files.pythonhosted.org/packages/ac/ab/289bcb1b90bd3e40a2900c561fa0e2087345ecbb094f0b870f2345142b7c/rpds_py-2026.6.3-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:ccffae9a092a00deb7efd545fe5e2c33c33b88e7c054337e9a74c179347d0b7d", size = 611011, upload-time = "2026-06-30T07:15:50.847Z" }, + { url = "https://files.pythonhosted.org/packages/1e/16/5043105e679436ccfbc8e5e0dd2d663ed18a8b8113515fd06a5e5d77c83e/rpds_py-2026.6.3-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:1cf01971c4f2c5553b772a542e4aaf191789cd331bc2cd4ff0e6e65ba49e1e97", size = 572431, upload-time = "2026-06-30T07:15:52.394Z" }, + { url = "https://files.pythonhosted.org/packages/85/ed/adab103321c0a6565d5ae1c2998349bc3ee175b82ccc5ae8fc04cc413075/rpds_py-2026.6.3-cp313-cp313-win32.whl", hash = "sha256:8c3d1e9c15b9d51ca0391e13da1a25a0a4df3c58a37c9dc368e0736cf7f69df0", size = 201710, upload-time = "2026-06-30T07:15:53.894Z" }, + { url = "https://files.pythonhosted.org/packages/7b/ed/a03b09668e74e5dabbf2e211f6468e1820c0552f7b0500082da31841bf7b/rpds_py-2026.6.3-cp313-cp313-win_amd64.whl", hash = "sha256:9250a9a0a6fd4648b3f868da8d91a4c52b5811a62df58e753d50ae4454a36f80", size = 219454, upload-time = "2026-06-30T07:15:55.25Z" }, + { url = "https://files.pythonhosted.org/packages/27/17/b8642c12930b71bc2b25831f6708ccf0f75abcd11883932ec9ce54ba3a78/rpds_py-2026.6.3-cp313-cp313-win_arm64.whl", hash = "sha256:900a67df3fd1660b035a4761c4ce73c382ea6b35f90f9863c36c6fd8bf8b09bb", size = 215063, upload-time = "2026-06-30T07:15:56.573Z" }, + { url = "https://files.pythonhosted.org/packages/b6/36/7fbe9dcdaf857fb3f63c2a2284b62492d95f5e8334e947e5fb6e7f68c9be/rpds_py-2026.6.3-cp314-cp314-macosx_10_12_x86_64.whl", hash = "sha256:931908d9fc855d8f74783377822be318edb6dcb19e47169dc038f9a1bf60b06e", size = 344510, upload-time = "2026-06-30T07:15:57.921Z" }, + { url = "https://files.pythonhosted.org/packages/ba/54/f785cc3d3f60839ca57a5af4927a9f347b07b2799c373fc20f7949f87c7e/rpds_py-2026.6.3-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:d7469697dce35be237db177d42e2a2ee26e6dcc5fc052078a6fefabd288c6edd", size = 339495, upload-time = "2026-06-30T07:15:59.238Z" }, + { url = "https://files.pythonhosted.org/packages/63/ef/d4cdaf309e6b095b43597103cf8c0b951d6cca2acce68c474f75ec12e0c7/rpds_py-2026.6.3-cp314-cp314-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bcfbcf66006befb9fd2aeaa9e01feaf881b4dc330a02ba07d2322b1c11be7b5d", size = 369454, upload-time = "2026-06-30T07:16:01.021Z" }, + { url = "https://files.pythonhosted.org/packages/96/4a/9559a68b7ee15db09d7981212e8c2e219d2a1d6d4faa0391d813c3496a36/rpds_py-2026.6.3-cp314-cp314-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:847927daf4cffbd4e90e42bc890069897101edd015f956cb8721b3473372edda", size = 374583, upload-time = "2026-06-30T07:16:02.287Z" }, + { url = "https://files.pythonhosted.org/packages/ef/75/8964aa7d2c6e8ac43eba8eb6e6b0fdda1f46d39f2fc3e6aa9f2cb17f485d/rpds_py-2026.6.3-cp314-cp314-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:aca6c1ef08a82bfe327cc156da694660f599923e2e6665b6d81c9c2d0ac9ffc8", size = 492919, upload-time = "2026-06-30T07:16:03.723Z" }, + { url = "https://files.pythonhosted.org/packages/8f/97/6908094ac804115e65aedfd90f1b5fee4eebebd3f6c4cfc5419939267565/rpds_py-2026.6.3-cp314-cp314-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:ae50181a047c871561212bb97f7932a2d45fb53e947bd9b57ebad85b529cbc53", size = 383725, upload-time = "2026-06-30T07:16:05.305Z" }, + { url = "https://files.pythonhosted.org/packages/d1/9c/0d1fdc2e7aba23e290d603bc494e97bd205bae262ce33c6b32a69768ed5e/rpds_py-2026.6.3-cp314-cp314-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dc319e5a1de4b6913aac94bf6a2f9e847371e0a140a43dd4991db1a09bc2d504", size = 367255, upload-time = "2026-06-30T07:16:07.086Z" }, + { url = "https://files.pythonhosted.org/packages/c4/fe/f0209ca4a9ed074bc8acb44dfd0e81c3122e94c9689f5645b7973a866719/rpds_py-2026.6.3-cp314-cp314-manylinux_2_31_riscv64.whl", hash = "sha256:e4316bf32babbed84e691e352faf967ce2f0f024174a8643c37c94a1080374fc", size = 379060, upload-time = "2026-06-30T07:16:08.525Z" }, + { url = "https://files.pythonhosted.org/packages/c6/8d/f1cc54c616b9d8897de8738aac148d20afca93f68187475fe194d09a71b9/rpds_py-2026.6.3-cp314-cp314-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:8c6e5a2f750cc71c3e3b11d71661f21d6f9bc6cebc6564b1466417a1ec03ec77", size = 395960, upload-time = "2026-06-30T07:16:09.989Z" }, + { url = "https://files.pythonhosted.org/packages/fb/04/aafff00f73aeca2945f734f1d483c64ab8f472d0864ab02377fd8e89c3b2/rpds_py-2026.6.3-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:4470ce197d4090875cf6affbf1f853338387428df97c4fb7b7106317b8214698", size = 545356, upload-time = "2026-06-30T07:16:11.816Z" }, + { url = "https://files.pythonhosted.org/packages/fd/cc/e229663b9e4ddac5a4acbe9085dd80a71af2a5d356b8b39d6bff233f24b0/rpds_py-2026.6.3-cp314-cp314-musllinux_1_2_i686.whl", hash = "sha256:ea964164cc9afa72d4d9b23cc28dafae93693c0a53e0b42acbff15b22c3f9ddd", size = 612319, upload-time = "2026-06-30T07:16:13.586Z" }, + { url = "https://files.pythonhosted.org/packages/e3/7a/8a0e6d3e6cd066af108b71b43122c3fe158dd9eb86acac626593a2582eb1/rpds_py-2026.6.3-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:639c8929aa0afe81be836b04de888460d6bed38b9c54cfc18da8f6bfabf5af5d", size = 573508, upload-time = "2026-06-30T07:16:15.23Z" }, + { url = "https://files.pythonhosted.org/packages/87/03/2a69ab618a789cf6cf85c86bb844c62d090e700ab1a2aa676b3741b6c516/rpds_py-2026.6.3-cp314-cp314-win32.whl", hash = "sha256:882076c00c0a608b131187055ddc5ae29f2e7eaf870d6168980420d58528a5c8", size = 202504, upload-time = "2026-06-30T07:16:16.893Z" }, + { url = "https://files.pythonhosted.org/packages/85/62/a3892ba945f4e24c78f352e5de3c7620d8479f73f211406a97263d13c7d2/rpds_py-2026.6.3-cp314-cp314-win_amd64.whl", hash = "sha256:0be972be84cfcaf46c8c6edf690ca0f154ac17babf1f6a955a51579b34ad2dc5", size = 220380, upload-time = "2026-06-30T07:16:18.108Z" }, + { url = "https://files.pythonhosted.org/packages/3d/e7/c2bd44dc831931815ad11ebb5f430b5a0a4d3caa9de837107876c30c3432/rpds_py-2026.6.3-cp314-cp314-win_arm64.whl", hash = "sha256:2a9c6f195058cb45335e8cc3802745c603d716eb96bc9625950c1aac71c0c703", size = 215976, upload-time = "2026-06-30T07:16:19.654Z" }, + { url = "https://files.pythonhosted.org/packages/79/9c/fff7b74bce9a091ec9a012a03f9ff5f69364eaf9451060dfc4486da2ffdd/rpds_py-2026.6.3-cp314-cp314t-macosx_10_12_x86_64.whl", hash = "sha256:f90938e92afda60266da758ee7d363447f7f0138c9559f9e1811629580582d90", size = 346840, upload-time = "2026-06-30T07:16:21.268Z" }, + { url = "https://files.pythonhosted.org/packages/e9/44/77bcb1168b33704908295533d27f10eb811e9e3e193e8993dc99572211d3/rpds_py-2026.6.3-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:ec829541c45bca16e61c7ae50c20501f213605beb75d1aba91a6ee37fbbb56a4", size = 340282, upload-time = "2026-06-30T07:16:22.875Z" }, + { url = "https://files.pythonhosted.org/packages/87/3c/7a9081c7c9e645b39efe19e4ffbeccd80add246327cd9b888aecffd72317/rpds_py-2026.6.3-cp314-cp314t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:afd70d95892096cdb26f15a00c45907b17817577aa8d1c76b2dcc2788391f9e9", size = 370403, upload-time = "2026-06-30T07:16:24.415Z" }, + { url = "https://files.pythonhosted.org/packages/f7/69/af47021eb7dad6ff3396cb001c08f0f3c4d06c20253f75be6421a59fe6b7/rpds_py-2026.6.3-cp314-cp314t-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:29dfa0533a5d4c94d4dfa1b694fcb56c9c63aad8330ffdd816fd225d0a7a162f", size = 376055, upload-time = "2026-06-30T07:16:26.111Z" }, + { url = "https://files.pythonhosted.org/packages/81/fc/a3bcf517084396a6dd258c592567a3c011ba4557f2fde23dceaf26e74f2e/rpds_py-2026.6.3-cp314-cp314t-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:af05d726809bff6b141be124d4c7ce998f9c9c7f30edb1f46c07aa103d540b41", size = 494419, upload-time = "2026-06-30T07:16:27.596Z" }, + { url = "https://files.pythonhosted.org/packages/c9/eb/13d529d1788135425c7bf207f8463458ca5d92e43f3f701365b83e9dffc1/rpds_py-2026.6.3-cp314-cp314t-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:9826217f048f620d9a712672818bf231442c1b35d96b227a07eabd11b4bb6945", size = 384848, upload-time = "2026-06-30T07:16:29.183Z" }, + { url = "https://files.pythonhosted.org/packages/8e/f4/b7ac49f30013aba8f7b9566b1dd07e81de95e708c1374b7bacc5b9bc5c9c/rpds_py-2026.6.3-cp314-cp314t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:536bceea4fa4acf7e1c61da2b5786304367c816c8895be71b8f537c480b0ea1f", size = 371369, upload-time = "2026-06-30T07:16:30.912Z" }, + { url = "https://files.pythonhosted.org/packages/31/86/6260bafa622f788b07ddec0e52d810305c8b9b0b8c27f58a2ab04bf62b4f/rpds_py-2026.6.3-cp314-cp314t-manylinux_2_31_riscv64.whl", hash = "sha256:bc0011654b91cc4fb2ae701bec0a0ba1e552c0714247fa7af6c59e0ccfa3a4e1", size = 379673, upload-time = "2026-06-30T07:16:32.486Z" }, + { url = "https://files.pythonhosted.org/packages/19/c3/03f1ee79a047b48daeca157c89a18509cde22b6b951d642b9b0af1be660a/rpds_py-2026.6.3-cp314-cp314t-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:539d75de9e0d536c84ff18dfeb805398e58227001ce09231a26a08b9aed1ee0e", size = 397500, upload-time = "2026-06-30T07:16:34.471Z" }, + { url = "https://files.pythonhosted.org/packages/f0/95/8ed0cd8c377dca12aea498f119fe639fc474d1461545c39d2b5872eb1c0f/rpds_py-2026.6.3-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:166cf54d9f44fc6ceb53c7860258dde44a81406646de79f8ed3234fca3b6e538", size = 545978, upload-time = "2026-06-30T07:16:36.45Z" }, + { url = "https://files.pythonhosted.org/packages/d3/f2/0eb57f0eaa83f8fc152a7e03de968ab77e1f00732bebc892b190c6eebde7/rpds_py-2026.6.3-cp314-cp314t-musllinux_1_2_i686.whl", hash = "sha256:d34c20167764fbcf927194d532dd7e0c56772f0a5f943fa5ef9e9afbba8fb9db", size = 613350, upload-time = "2026-06-30T07:16:38.213Z" }, + { url = "https://files.pythonhosted.org/packages/5b/de/e0674bdbc3ef7634989b3f854c3f34bc1f587d36e5bfdc5c378d57034619/rpds_py-2026.6.3-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:ea7bb13b7c9a29791f87a0387ba7d3ad3a6d783d827e4d3f27b40a0ff44495e2", size = 576486, upload-time = "2026-06-30T07:16:39.797Z" }, + { url = "https://files.pythonhosted.org/packages/f2/f6/21101359743cd136ada781e8210a85769578422ba460672eea0e29739200/rpds_py-2026.6.3-cp314-cp314t-win32.whl", hash = "sha256:6de4744d05bd1aa1be4ed7ea1189e3979196808008113bbbf899a460966b925e", size = 201068, upload-time = "2026-06-30T07:16:41.316Z" }, + { url = "https://files.pythonhosted.org/packages/a6/b2/9574d4d44f7760c2aa32d92a0a4f41698e33f5b204a0bf5c9758f52c79d5/rpds_py-2026.6.3-cp314-cp314t-win_amd64.whl", hash = "sha256:c7b9a2f8f4d8e90af72571d3d495deebdd7e3c75451f5b41719aee166e940fc2", size = 220600, upload-time = "2026-06-30T07:16:43.091Z" }, + { url = "https://files.pythonhosted.org/packages/08/ae/f23a2697e6ee6340a578b0f136be6483657bef0c6f9497b752bb5c0964bb/rpds_py-2026.6.3-cp315-cp315-macosx_10_12_x86_64.whl", hash = "sha256:e059c5dde6452b44424bd1834557556c226b57781dee1227af23518459722b13", size = 344726, upload-time = "2026-06-30T07:16:44.5Z" }, + { url = "https://files.pythonhosted.org/packages/c3/63/e7b3a1a5358dd32c930a1062d8e15b67fd6e8922e81df9e91706d66ee5c8/rpds_py-2026.6.3-cp315-cp315-macosx_11_0_arm64.whl", hash = "sha256:2f7c26fbc5acd2522b95d4177fe4710ffd8e9b20529e703ffbf8db4d93903f05", size = 339587, upload-time = "2026-06-30T07:16:46.255Z" }, + { url = "https://files.pythonhosted.org/packages/ec/64/10a85681916ca55fffb91b0a211f84e34297c109243484dd6394660a8a7c/rpds_py-2026.6.3-cp315-cp315-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a3086b538543802f84c843911242db20447de00d8752dd0efc936dbcf02218ba", size = 369585, upload-time = "2026-06-30T07:16:48.101Z" }, + { url = "https://files.pythonhosted.org/packages/76/c2/baf95c7c38823e12ba34407c5f5767a89e5cf2233895e56f608167ae9493/rpds_py-2026.6.3-cp315-cp315-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:8f2e5c5ee828d42cb11760761c0af6507927bec42d0ad5458f97c9203b054617", size = 375479, upload-time = "2026-06-30T07:16:49.93Z" }, + { url = "https://files.pythonhosted.org/packages/6a/94/0aad06c72d65101e11d33528d438cda99a39ce0da99466e156158f2541d3/rpds_py-2026.6.3-cp315-cp315-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ed0c1e5d10cdc7135537988c74a0188da68e2f3c30813ba3744ab1e42e0480f9", size = 492418, upload-time = "2026-06-30T07:16:51.641Z" }, + { url = "https://files.pythonhosted.org/packages/b5/17/de3f5a479a1f056535d7489819639d8cd591ea6281d700390b43b1abd745/rpds_py-2026.6.3-cp315-cp315-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:8c2642a7603ec0b16ed77da4555db3b4b472341904873788327c0b0d7b95f1bb", size = 384123, upload-time = "2026-06-30T07:16:53.622Z" }, + { url = "https://files.pythonhosted.org/packages/46/7d/bf09bd1b145bb2671c03e1e6d1ab8651858d90d8c7dfeadd85a37a934fd8/rpds_py-2026.6.3-cp315-cp315-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8e4320744c1ffdd95a603def63344bfab2d33edeab301c5007e7de9f9f5b3885", size = 367351, upload-time = "2026-06-30T07:16:55.241Z" }, + { url = "https://files.pythonhosted.org/packages/a3/ea/1bb734f314b8be319149ddee80b18bd41372bdcfbdf88d28131c0cd37719/rpds_py-2026.6.3-cp315-cp315-manylinux_2_31_riscv64.whl", hash = "sha256:a9f4645593036b81bbdb36b9c8e0ea0d1c3fee968c4d59db0344c14087ef143a", size = 378827, upload-time = "2026-06-30T07:16:56.841Z" }, + { url = "https://files.pythonhosted.org/packages/4b/93/d9611e5b25e26df9a3649813ed66193ace9347a7c7fc4ab7cf70e94851c0/rpds_py-2026.6.3-cp315-cp315-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:e55d236be29255554da47abe5c577637db7c24a02b8b46f0ca9524c855801868", size = 395966, upload-time = "2026-06-30T07:16:58.557Z" }, + { url = "https://files.pythonhosted.org/packages/c3/cb/99d77e16e5534ae1d90629bbe419ba6ee170833a6a85e3aa1cc41726fbbc/rpds_py-2026.6.3-cp315-cp315-musllinux_1_2_aarch64.whl", hash = "sha256:24e9c5386e16669b674a69c156c8eeefcb578f3b3397b713b08e6d60f3c7b187", size = 545680, upload-time = "2026-06-30T07:17:00.164Z" }, + { url = "https://files.pythonhosted.org/packages/59/15/11a29755f790cef7a2f755e8e14f4f0c33f39489e1893a632a2eee59672b/rpds_py-2026.6.3-cp315-cp315-musllinux_1_2_i686.whl", hash = "sha256:c60924535c75f1566b6eb75b5c31a48a43fef04fa2d0d201acbad8a9969c6107", size = 611853, upload-time = "2026-06-30T07:17:01.962Z" }, + { url = "https://files.pythonhosted.org/packages/68/86/0c27547e21644da938fb530f7e1a8148dd24d02db07e7a5f2567a17ce710/rpds_py-2026.6.3-cp315-cp315-musllinux_1_2_x86_64.whl", hash = "sha256:38a2fea2787428f811719ceb9114cb78964a3138838320c29ac39526c79c16ba", size = 573715, upload-time = "2026-06-30T07:17:03.693Z" }, + { url = "https://files.pythonhosted.org/packages/29/71/4d8fcf700931815594bce892255bbd973b94efaf0fc1932b0590df18d886/rpds_py-2026.6.3-cp315-cp315-win32.whl", hash = "sha256:d483fe17f01ad64b7bf7cc38fcefff1ca9fb83f8c2b2542b68f97ffe0611b369", size = 202864, upload-time = "2026-06-30T07:17:05.746Z" }, + { url = "https://files.pythonhosted.org/packages/eb/62/b577562de0edbb55b2be85ce5fd09c33e386b9b13eee09833af4240fd5c4/rpds_py-2026.6.3-cp315-cp315-win_amd64.whl", hash = "sha256:67e3a721ffc5d8d2210d3671872298c4a84e4b8035cfe42ffd7cde35d772b146", size = 220430, upload-time = "2026-06-30T07:17:07.471Z" }, + { url = "https://files.pythonhosted.org/packages/c8/95/d6d0b2509825141eef60669a5739eec88dbc6a48053d6c92993a5704defe/rpds_py-2026.6.3-cp315-cp315-win_arm64.whl", hash = "sha256:6e84adbcf4bf841aed8116a8264b9f50b4cb3e7bd89b516122e616ac56ca269e", size = 215877, upload-time = "2026-06-30T07:17:09.008Z" }, + { url = "https://files.pythonhosted.org/packages/b7/bf/f3ea278f0afd615c1d0f19cb69043a41526e2bb600c2b536eb192218eb27/rpds_py-2026.6.3-cp315-cp315t-macosx_10_12_x86_64.whl", hash = "sha256:ae6dd8f10bd17aad820876d24caec9efdafd80a318d16c0a48edb5e136902c6b", size = 346933, upload-time = "2026-06-30T07:17:10.762Z" }, + { url = "https://files.pythonhosted.org/packages/9d/29/9907bdf1c5346763cf10b7f6852aad86652168c259def904cbe0082c5864/rpds_py-2026.6.3-cp315-cp315t-macosx_11_0_arm64.whl", hash = "sha256:bdbd97738551fca3917c1bd7188bec1920bb520104f28e7e1007f9ceb17b7690", size = 340274, upload-time = "2026-06-30T07:17:12.266Z" }, + { url = "https://files.pythonhosted.org/packages/6f/2c/8e03767b5778ef25cebf74a7a91a2c3806f8eced4c92cb7406bbe060756d/rpds_py-2026.6.3-cp315-cp315t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8b95977e7211527ab0ba576e286d023389fbeeb32a6b7b771665d333c60e5342", size = 370763, upload-time = "2026-06-30T07:17:14.107Z" }, + { url = "https://files.pythonhosted.org/packages/2e/e1/df2a7e1ba2efd796af26194250b8d42c821b46592311595162af9ef0528d/rpds_py-2026.6.3-cp315-cp315t-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:d15fde0e6fb0d88a60d221204873743e5d9f0b7d29165e62cd86d0413ad74ba6", size = 376467, upload-time = "2026-06-30T07:17:15.76Z" }, + { url = "https://files.pythonhosted.org/packages/6b/de/8a0814d1946af29cb068fb259aa8622f856df1d0bab58429448726b537f5/rpds_py-2026.6.3-cp315-cp315t-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a136d453475ac0fcbda502ef1e6504bd28d6d904700915d278deeab0d00fe140", size = 496689, upload-time = "2026-06-30T07:17:17.308Z" }, + { url = "https://files.pythonhosted.org/packages/df/f3/f19e0c852ba13694f5a79f3b719331051573cb5693feacf8a88ffffc3a71/rpds_py-2026.6.3-cp315-cp315t-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f826877d462181e5eb1c26a0026b8d0cab05d99844ecb6d8bf3627a2ca0c0442", size = 385340, upload-time = "2026-06-30T07:17:18.928Z" }, + { url = "https://files.pythonhosted.org/packages/e2/ae/7ec3a9d2d4351f99e37bcb06b6b6f954512646bfdbf9742e1de727865daf/rpds_py-2026.6.3-cp315-cp315t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:79486287de1730dbaff3dbd124d0ca4d2ef7f9d29bf2544f1f93c09b5bcbbd12", size = 372179, upload-time = "2026-06-30T07:17:20.539Z" }, + { url = "https://files.pythonhosted.org/packages/d3/ac/9cee911dff2aaa9a5a8354f6610bf2e6a616de9197c5fff4f54f82585f1e/rpds_py-2026.6.3-cp315-cp315t-manylinux_2_31_riscv64.whl", hash = "sha256:808345f53cb952433ca2816f1604ff3515608a81784954f38d4452acfe8e61d5", size = 379993, upload-time = "2026-06-30T07:17:22.212Z" }, + { url = "https://files.pythonhosted.org/packages/83/6b/7c2a07ba88d1e9a936612f7a5d067467ed03d971d5a06f7d309dff044a7e/rpds_py-2026.6.3-cp315-cp315t-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:1967debc37f64f2c4dc90a7f563aec558b471966e12adcac4e1c4240496b6ebf", size = 398909, upload-time = "2026-06-30T07:17:23.66Z" }, + { url = "https://files.pythonhosted.org/packages/97/0b/776ffcb66783637b0031f6d58d6fb55913c8b5abf00aeecd46bf933fb477/rpds_py-2026.6.3-cp315-cp315t-musllinux_1_2_aarch64.whl", hash = "sha256:f0840b5b17057f7fd918b76183a4b5a0635f43e14eb2ce60dce1d4ee4707ea00", size = 546584, upload-time = "2026-06-30T07:17:25.264Z" }, + { url = "https://files.pythonhosted.org/packages/55/33/ba3bc04d7092bd553c9b2b195624992d2cc4f3de1f380b7b93cbee67bd79/rpds_py-2026.6.3-cp315-cp315t-musllinux_1_2_i686.whl", hash = "sha256:faa679d19a6696fd54259ad321251ad77a13e70e03dd834daa762a44fb6196ef", size = 614357, upload-time = "2026-06-30T07:17:26.888Z" }, + { url = "https://files.pythonhosted.org/packages/8b/71/14edf065f04630b1a8472f7653cad03f6c478bcf95ea0e6aed55451e33ea/rpds_py-2026.6.3-cp315-cp315t-musllinux_1_2_x86_64.whl", hash = "sha256:23a439f31ccbeff1574e24889128821d1f7917470e830cf6544dced1c662262a", size = 576533, upload-time = "2026-06-30T07:17:28.546Z" }, + { url = "https://files.pythonhosted.org/packages/ba/76/65002b08596c389105720a8c0d22298b8dc25a4baf89b2ce431343c8b1de/rpds_py-2026.6.3-cp315-cp315t-win32.whl", hash = "sha256:913ca42ccad3f8cc6e292b587ae8ae49c8c823e5dce51a736252fc7c7cdfa577", size = 201204, upload-time = "2026-06-30T07:17:30.193Z" }, + { url = "https://files.pythonhosted.org/packages/8c/97/d855d6b3c322d1f27e26f5241c42016b56cf01377ea8ed348285f54652f0/rpds_py-2026.6.3-cp315-cp315t-win_amd64.whl", hash = "sha256:ae3d4fe8c0b9213624fdce7279d70e3b148b682ca20719ebd193a23ebfa47324", size = 220719, upload-time = "2026-06-30T07:17:31.788Z" }, + { url = "https://files.pythonhosted.org/packages/b4/9c/f0d19ac587fd0e4ab6b72cda355e9c5a6166b01ef7e064e437aef8eb9fef/rpds_py-2026.6.3-pp311-pypy311_pp73-macosx_10_12_x86_64.whl", hash = "sha256:4cf2d36a2357e4d07bb5a4f98801265327b48256867816cfd2ceb001e9754a8f", size = 349791, upload-time = "2026-06-30T07:17:33.315Z" }, + { url = "https://files.pythonhosted.org/packages/38/c7/1d49d204c9fd2ee6c537601dc4c1ba921e03363ca576bfab94a00254ac9a/rpds_py-2026.6.3-pp311-pypy311_pp73-macosx_11_0_arm64.whl", hash = "sha256:30c6dc199b24a5e3e81d50da0f00858c5bbdb2617a750395687f4339c5818171", size = 352842, upload-time = "2026-06-30T07:17:34.897Z" }, + { url = "https://files.pythonhosted.org/packages/ac/e5/c0b5dc93cd0d4c06ce1f438907649514e2ea077bcd911e3154a51e96c38e/rpds_py-2026.6.3-pp311-pypy311_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9891e594296ab9dada6551c8e7b387b2721f27a67eecd528412e8906247a7b90", size = 382094, upload-time = "2026-06-30T07:17:36.514Z" }, + { url = "https://files.pythonhosted.org/packages/0d/54/ec0e907b4ca8d541112db352409bd15f871c9b243e0c92c9b5a46ae96f01/rpds_py-2026.6.3-pp311-pypy311_pp73-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:b5c2dc92304aa48a4a60443b548bb12f12e119d4b72f314015e67b9e1be97fca", size = 388662, upload-time = "2026-06-30T07:17:38.235Z" }, + { url = "https://files.pythonhosted.org/packages/d3/f4/921c22a4fd0f1c1ac13a3996ffbf0aa67951e2c8ad0d1d9574938a2932e8/rpds_py-2026.6.3-pp311-pypy311_pp73-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:127e08c0642d880cf32ca47ec2a4a77b901f7e2dd1ad9762adb13955d72ffcc9", size = 504896, upload-time = "2026-06-30T07:17:39.689Z" }, + { url = "https://files.pythonhosted.org/packages/0b/1b/a114b972cefa1ab1cdb3c7bb177cd3844a12826c507c722d3a73516dbbaf/rpds_py-2026.6.3-pp311-pypy311_pp73-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:8bb68f03f395eb793220b45c097bd4d8c32944393da0fad8b999efac0868fc8c", size = 391545, upload-time = "2026-06-30T07:17:41.336Z" }, + { url = "https://files.pythonhosted.org/packages/4e/98/af9b3db77d47fcbe6c8c1f36e2c2147ec70292819e99c325f871584a1c11/rpds_py-2026.6.3-pp311-pypy311_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a3450b693fde92133e9f51060568a4c31fcca76d5e53bbd611e689ca446517e9", size = 380059, upload-time = "2026-06-30T07:17:42.857Z" }, + { url = "https://files.pythonhosted.org/packages/c9/ba/0efd8668b97c1d26a61566386c636a7a7a09829e474fdf807caa15a2c844/rpds_py-2026.6.3-pp311-pypy311_pp73-manylinux_2_31_riscv64.whl", hash = "sha256:5e8d07bddee435a2ff6f1920e18feff28d0bc4533e42f4bf6927fbd073312c41", size = 393235, upload-time = "2026-06-30T07:17:44.637Z" }, + { url = "https://files.pythonhosted.org/packages/62/90/8c139ee9690f73b0829f32647de6f40d826f8f443af6fa72644f96351aac/rpds_py-2026.6.3-pp311-pypy311_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:3a83ae6c67b7676b9878378547ca8e93ed77a580037bcbcd1d32f739e1e6089c", size = 413008, upload-time = "2026-06-30T07:17:46.225Z" }, + { url = "https://files.pythonhosted.org/packages/9c/97/0043896fdd7828ce09a1d9a8b06433714d0960fc4ff3fc4aa72b666b764e/rpds_py-2026.6.3-pp311-pypy311_pp73-musllinux_1_2_aarch64.whl", hash = "sha256:2bfd04c19ddbd6640de0b51894d764bd2758854d5b75bd102d2ef10cb9c293a9", size = 558118, upload-time = "2026-06-30T07:17:47.759Z" }, + { url = "https://files.pythonhosted.org/packages/f6/40/02355f0e134f783a8f9814c4680a1bd311d37671577a5964ea838573ff37/rpds_py-2026.6.3-pp311-pypy311_pp73-musllinux_1_2_i686.whl", hash = "sha256:ca6546b66be9dc4738b1b043d5ebd5488c66c578c5ff0fd0e8065313fe3afb76", size = 623138, upload-time = "2026-06-30T07:17:49.355Z" }, + { url = "https://files.pythonhosted.org/packages/10/85/48f0abdcef5cce4e034c7a5b0ceeceba0b01bf0d942824f4bb720afe2dec/rpds_py-2026.6.3-pp311-pypy311_pp73-musllinux_1_2_x86_64.whl", hash = "sha256:8e65860d238379ed982fd9ba690579b5e95af2f4840f99c772816dbe573cb826", size = 586486, upload-time = "2026-06-30T07:17:51.141Z" }, +] + [[package]] name = "ruff" version = "0.15.20" @@ -8294,6 +8737,15 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/f0/ac/229b7d4589d2e5937310e72c6d46e89599d16a4a12b479ffa1499fee8eb8/triton-3.7.1-cp314-cp314t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:10ba85fa2cca4a2fbdeb36bf1cb082f2c252bda55bf9fccd74f65ec5bc647e68", size = 197824404, upload-time = "2026-06-17T19:53:42.772Z" }, ] +[[package]] +name = "ttach" +version = "0.0.3" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/91/5d/4c49e0eca4206bc25eff4ba89cee51b781466e2e3aad2f1057fd5d2634be/ttach-0.0.3.tar.gz", hash = "sha256:120c4dd881feb0e9c8dd63b154f2655891c3e20689b68a94d162bfd5557bcb48", size = 9600, upload-time = "2020-07-09T14:44:09.035Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/8d/a3/ee48a184a185c1897c582c72240c2c8a0d0aeb5f8051a71d4e4cd930c52d/ttach-0.0.3-py3-none-any.whl", hash = "sha256:7000bb4334f856b0c79a341df386c92f1c76faf091043cc3cd7f541d2149faf8", size = 9839, upload-time = "2020-07-09T14:44:08.006Z" }, +] + [[package]] name = "typer" version = "0.26.8" @@ -8922,6 +9374,85 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/19/d4/225027a913621a879b429a043674aa35220e6ce67785acad4f7bd0c4ff33/xarray_einstats-0.10.0-py3-none-any.whl", hash = "sha256:fa3169b46cee29092db820d8bbc203148bada4fc970ee75e62cbf3dd7c5a8945", size = 39099, upload-time = "2026-02-19T18:13:53.174Z" }, ] +[[package]] +name = "xgboost" +version = "3.2.0" +source = { registry = "https://pypi.org/simple" } +resolution-markers = [ + "python_full_version == '3.11.*' and extra != 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda'", + "python_full_version < '3.11' and extra != 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda'", + "python_full_version == '3.11.*' and sys_platform != 'darwin' and extra == 'extra-6-dashai-cpu' and extra != 'extra-6-dashai-cuda'", + "python_full_version == '3.11.*' and sys_platform == 'darwin' and extra == 'extra-6-dashai-cpu' and extra != 'extra-6-dashai-cuda'", + "python_full_version < '3.11' and sys_platform != 'darwin' and extra == 'extra-6-dashai-cpu' and extra != 'extra-6-dashai-cuda'", + "python_full_version < '3.11' and sys_platform == 'darwin' and extra == 'extra-6-dashai-cpu' and extra != 'extra-6-dashai-cuda'", + "python_full_version == '3.11.*' and extra != 'extra-6-dashai-cpu' and extra != 'extra-6-dashai-cuda'", + "python_full_version < '3.11' and extra != 'extra-6-dashai-cpu' and extra != 'extra-6-dashai-cuda'", +] +dependencies = [ + { name = "numpy", version = "2.2.6", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.11' or (extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda')" }, + { name = "numpy", version = "2.4.6", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version == '3.11.*' or (extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda')" }, + { name = "nvidia-nccl-cu12", marker = "(python_full_version < '3.12' and sys_platform == 'linux') or (python_full_version >= '3.12' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (sys_platform != 'linux' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda')" }, + { name = "scipy", version = "1.15.3", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.11' or (extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda')" }, + { name = "scipy", version = "1.17.1", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version == '3.11.*' or (extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda')" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/91/bb/1eb0242409d22db725d7a88088e6cfd6556829fb0736f9ff69aa9f1e9455/xgboost-3.2.0.tar.gz", hash = "sha256:99b0e9a2a64896cdaf509c5e46372d336c692406646d20f2af505003c0c5d70d", size = 1263936, upload-time = "2026-02-10T11:03:05.542Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/2d/49/6e4cdd877c24adf56cb3586bc96d93d4dcd780b5ea1efb32e1ee0de08bae/xgboost-3.2.0-py3-none-macosx_10_15_x86_64.whl", hash = "sha256:2f661966d3e322536d9c448090a870fcba1e32ee5760c10b7c46bac7a342079a", size = 2507014, upload-time = "2026-02-10T10:50:57.44Z" }, + { url = "https://files.pythonhosted.org/packages/93/f1/c09ef1add609453aa3ba5bafcd0d1c1a805c1263c0b60138ec968f8ec296/xgboost-3.2.0-py3-none-macosx_12_0_arm64.whl", hash = "sha256:eabbd40d474b8dbf6cb3536325f9150b9e6f0db32d18de9914fb3227d0bef5b7", size = 2328527, upload-time = "2026-02-10T10:51:17.502Z" }, + { url = "https://files.pythonhosted.org/packages/96/9f/d9914a7b8df842832850b1a18e5f47aaa071c217cdd1da2ae9deb291018b/xgboost-3.2.0-py3-none-manylinux_2_28_aarch64.whl", hash = "sha256:852eabc6d3b3702a59bf78dbfdcd1cb9c4d3a3b6e5ed1f8781d8b9512354fdd2", size = 131100954, upload-time = "2026-02-10T11:02:42.704Z" }, + { url = "https://files.pythonhosted.org/packages/79/98/679de17c2caa4fd3b0b4386ecf7377301702cb0afb22930a07c142fcb1d8/xgboost-3.2.0-py3-none-manylinux_2_28_x86_64.whl", hash = "sha256:99b4a6bbcb47212fec5cf5fbe12347215f073c08967431b0122cfbd1ee70312c", size = 131748579, upload-time = "2026-02-10T10:54:40.424Z" }, + { url = "https://files.pythonhosted.org/packages/1f/3d/1661dd114a914a67e3f7ab66fa1382e7599c2a8c340f314ad30a3e2b4d08/xgboost-3.2.0-py3-none-win_amd64.whl", hash = "sha256:0d169736fd836fc13646c7ab787167b3a8110351c2c6bc770c755ee1618f0442", size = 101681668, upload-time = "2026-02-10T10:59:31.202Z" }, +] + +[[package]] +name = "xgboost" +version = "3.3.0" +source = { registry = "https://pypi.org/simple" } +resolution-markers = [ + "python_full_version >= '3.15' and platform_machine == 'x86_64' and sys_platform == 'darwin' and extra != 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda'", + "python_full_version == '3.14.*' and platform_machine == 'x86_64' and sys_platform == 'darwin' and extra != 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda'", + "python_full_version == '3.13.*' and platform_machine == 'x86_64' and sys_platform == 'darwin' and extra != 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda'", + "python_full_version == '3.12.*' and platform_machine == 'x86_64' and sys_platform == 'darwin' and extra != 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda'", + "(python_full_version >= '3.15' and platform_machine != 'x86_64' and extra != 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (python_full_version >= '3.15' and sys_platform != 'darwin' and extra != 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda')", + "(python_full_version == '3.14.*' and platform_machine != 'x86_64' and extra != 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (python_full_version == '3.14.*' and sys_platform != 'darwin' and extra != 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda')", + "(python_full_version == '3.13.*' and platform_machine != 'x86_64' and extra != 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (python_full_version == '3.13.*' and sys_platform != 'darwin' and extra != 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda')", + "(python_full_version == '3.12.*' and platform_machine != 'x86_64' and extra != 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (python_full_version == '3.12.*' and sys_platform != 'darwin' and extra != 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda')", + "python_full_version >= '3.15' and platform_machine == 'x86_64' and sys_platform == 'darwin' and extra == 'extra-6-dashai-cpu' and extra != 'extra-6-dashai-cuda'", + "python_full_version == '3.14.*' and platform_machine == 'x86_64' and sys_platform == 'darwin' and extra == 'extra-6-dashai-cpu' and extra != 'extra-6-dashai-cuda'", + "python_full_version == '3.13.*' and platform_machine == 'x86_64' and sys_platform == 'darwin' and extra == 'extra-6-dashai-cpu' and extra != 'extra-6-dashai-cuda'", + "python_full_version == '3.12.*' and platform_machine == 'x86_64' and sys_platform == 'darwin' and extra == 'extra-6-dashai-cpu' and extra != 'extra-6-dashai-cuda'", + "python_full_version >= '3.15' and sys_platform != 'darwin' and extra == 'extra-6-dashai-cpu' and extra != 'extra-6-dashai-cuda'", + "python_full_version == '3.14.*' and sys_platform != 'darwin' and extra == 'extra-6-dashai-cpu' and extra != 'extra-6-dashai-cuda'", + "python_full_version == '3.13.*' and sys_platform != 'darwin' and extra == 'extra-6-dashai-cpu' and extra != 'extra-6-dashai-cuda'", + "python_full_version == '3.12.*' and sys_platform != 'darwin' and extra == 'extra-6-dashai-cpu' and extra != 'extra-6-dashai-cuda'", + "python_full_version >= '3.15' and platform_machine != 'x86_64' and sys_platform == 'darwin' and extra == 'extra-6-dashai-cpu' and extra != 'extra-6-dashai-cuda'", + "python_full_version == '3.14.*' and platform_machine != 'x86_64' and sys_platform == 'darwin' and extra == 'extra-6-dashai-cpu' and extra != 'extra-6-dashai-cuda'", + "python_full_version == '3.13.*' and platform_machine != 'x86_64' and sys_platform == 'darwin' and extra == 'extra-6-dashai-cpu' and extra != 'extra-6-dashai-cuda'", + "python_full_version == '3.12.*' and platform_machine != 'x86_64' and sys_platform == 'darwin' and extra == 'extra-6-dashai-cpu' and extra != 'extra-6-dashai-cuda'", + "python_full_version >= '3.15' and platform_machine == 'x86_64' and sys_platform == 'darwin' and extra != 'extra-6-dashai-cpu' and extra != 'extra-6-dashai-cuda'", + "python_full_version == '3.14.*' and platform_machine == 'x86_64' and sys_platform == 'darwin' and extra != 'extra-6-dashai-cpu' and extra != 'extra-6-dashai-cuda'", + "python_full_version == '3.13.*' and platform_machine == 'x86_64' and sys_platform == 'darwin' and extra != 'extra-6-dashai-cpu' and extra != 'extra-6-dashai-cuda'", + "python_full_version == '3.12.*' and platform_machine == 'x86_64' and sys_platform == 'darwin' and extra != 'extra-6-dashai-cpu' and extra != 'extra-6-dashai-cuda'", + "(python_full_version >= '3.15' and platform_machine != 'x86_64' and extra != 'extra-6-dashai-cpu' and extra != 'extra-6-dashai-cuda') or (python_full_version >= '3.15' and sys_platform != 'darwin' and extra != 'extra-6-dashai-cpu' and extra != 'extra-6-dashai-cuda')", + "(python_full_version == '3.14.*' and platform_machine != 'x86_64' and extra != 'extra-6-dashai-cpu' and extra != 'extra-6-dashai-cuda') or (python_full_version == '3.14.*' and sys_platform != 'darwin' and extra != 'extra-6-dashai-cpu' and extra != 'extra-6-dashai-cuda')", + "(python_full_version == '3.13.*' and platform_machine != 'x86_64' and extra != 'extra-6-dashai-cpu' and extra != 'extra-6-dashai-cuda') or (python_full_version == '3.13.*' and sys_platform != 'darwin' and extra != 'extra-6-dashai-cpu' and extra != 'extra-6-dashai-cuda')", + "(python_full_version == '3.12.*' and platform_machine != 'x86_64' and extra != 'extra-6-dashai-cpu' and extra != 'extra-6-dashai-cuda') or (python_full_version == '3.12.*' and sys_platform != 'darwin' and extra != 'extra-6-dashai-cpu' and extra != 'extra-6-dashai-cuda')", +] +dependencies = [ + { name = "numpy", version = "2.4.6", source = { registry = "https://pypi.org/simple" }, marker = "(python_full_version >= '3.12' and platform_machine != 'x86_64') or (python_full_version < '3.12' and platform_machine != 'x86_64' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (python_full_version >= '3.12' and sys_platform != 'darwin') or (platform_machine == 'x86_64' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (sys_platform != 'darwin' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda')" }, + { name = "numpy", version = "2.5.0", source = { registry = "https://pypi.org/simple" }, marker = "(python_full_version >= '3.12' and platform_machine == 'x86_64' and sys_platform == 'darwin') or (python_full_version < '3.12' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (platform_machine != 'x86_64' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (sys_platform != 'darwin' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda')" }, + { name = "nvidia-nccl-cu12", marker = "(python_full_version >= '3.12' and sys_platform == 'linux') or (python_full_version < '3.12' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (sys_platform != 'linux' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda')" }, + { name = "scipy", version = "1.18.0", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.12' or (extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda')" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/fd/41/846d4de2b8fc694073fd3ac5052caf68caa1ea11cb7fa32d7ad9c049b232/xgboost-3.3.0.tar.gz", hash = "sha256:58bcb8a4cace648cdab7b94fa4f16d2c9ff26d90dd4d26907168106fa06d8746", size = 1224702, upload-time = "2026-06-17T21:26:50.846Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/fc/72/3b68983c0215ef65d48e9eeb1f168c3c6e3d62a61ece605de3209c79cae1/xgboost-3.3.0-py3-none-macosx_10_15_x86_64.whl", hash = "sha256:07688a377046b8640897b62421150bf73c6cc7101823474ec6ad08b93290f587", size = 2553505, upload-time = "2026-06-17T21:21:32.146Z" }, + { url = "https://files.pythonhosted.org/packages/c9/62/b49e756822b29909d0c95ed334662dc6c7c81a99ec6bc10dc18e69f3d6e7/xgboost-3.3.0-py3-none-macosx_12_0_arm64.whl", hash = "sha256:af7cea10f418b7c251ddc8da440f57bdab2990b5fc9f74a35a92b0f150ea287d", size = 2376040, upload-time = "2026-06-17T21:22:01.981Z" }, + { url = "https://files.pythonhosted.org/packages/47/3a/a0adcd1ee28f525bd5c9dc3ebe78a7599bf97c22866d6449f967b829e338/xgboost-3.3.0-py3-none-manylinux_2_28_aarch64.whl", hash = "sha256:624a83aeb1e7ba081719795db179f4ce6fff12e79de05cd9baf15ee48fd22f0e", size = 98180629, upload-time = "2026-06-17T21:24:00.804Z" }, + { url = "https://files.pythonhosted.org/packages/47/1f/8b3e578cfd8e3bcdb4374e2bbe0b40b4e5320accb5cbdcf535ecc512eb5c/xgboost-3.3.0-py3-none-manylinux_2_28_x86_64.whl", hash = "sha256:f59edaf28eccd1c519788607c72ed907ee6cedfa933d706620bc1612d24b354e", size = 98716607, upload-time = "2026-06-17T21:26:21.058Z" }, + { url = "https://files.pythonhosted.org/packages/07/6b/087fd5d28fdbb90d385c50ee9308a820241b82feebdf42e72e19a48e4b32/xgboost-3.3.0-py3-none-win_amd64.whl", hash = "sha256:b06057f6a018fc04e6b3e0c15568ca636b8151a5b5f333478e500fcaf4fc7594", size = 69522696, upload-time = "2026-06-17T21:20:53.707Z" }, +] + [[package]] name = "xlrd" version = "2.0.2" From 9a3e11be22563f45ef529426172339ee6b250ff8 Mon Sep 17 00:00:00 2001 From: Irozuku Date: Mon, 13 Jul 2026 15:43:25 -0400 Subject: [PATCH 2/8] feat: add ten explainers with typed artifact plots --- .../registry/component_registry.py | 4 +- .../explainers/contrastive_shap.py | 458 ++++++++++++++++++ .../explainers/dice_counterfactual.py | 452 +++++++++++++++++ .../explainability/explainers/grad_cam.py | 292 +++++++++++ .../explainers/image_explainer_utils.py | 170 +++++++ .../explainability/explainers/lime_text.py | 319 ++++++++++++ .../explainers/nearest_counterfactual.py | 414 ++++++++++++++++ .../explainers/occlusion_saliency.py | 347 +++++++++++++ .../explainers/regression_kernel_shap.py | 337 +++++++++++++ .../regression_partial_dependence.py | 244 ++++++++++ ...gression_permutation_feature_importance.py | 312 ++++++++++++ .../explainers/token_ablation.py | 358 ++++++++++++++ DashAI/back/initial_components.py | 30 ++ .../back/explainers/test_image_explainers.py | 151 ++++++ tests/back/explainers/test_lib_explainers.py | 175 +++++++ tests/back/explainers/test_new_explainers.py | 225 +++++++++ tests/back/explainers/test_task_explainers.py | 306 ++++++++++++ tests/back/registries/test_registry.py | 16 + 18 files changed, 4609 insertions(+), 1 deletion(-) create mode 100644 DashAI/back/explainability/explainers/contrastive_shap.py create mode 100644 DashAI/back/explainability/explainers/dice_counterfactual.py create mode 100644 DashAI/back/explainability/explainers/grad_cam.py create mode 100644 DashAI/back/explainability/explainers/image_explainer_utils.py create mode 100644 DashAI/back/explainability/explainers/lime_text.py create mode 100644 DashAI/back/explainability/explainers/nearest_counterfactual.py create mode 100644 DashAI/back/explainability/explainers/occlusion_saliency.py create mode 100644 DashAI/back/explainability/explainers/regression_kernel_shap.py create mode 100644 DashAI/back/explainability/explainers/regression_partial_dependence.py create mode 100644 DashAI/back/explainability/explainers/regression_permutation_feature_importance.py create mode 100644 DashAI/back/explainability/explainers/token_ablation.py create mode 100644 tests/back/explainers/test_image_explainers.py create mode 100644 tests/back/explainers/test_lib_explainers.py create mode 100644 tests/back/explainers/test_new_explainers.py create mode 100644 tests/back/explainers/test_task_explainers.py diff --git a/DashAI/back/dependencies/registry/component_registry.py b/DashAI/back/dependencies/registry/component_registry.py index 98da941f7..89b336b1b 100644 --- a/DashAI/back/dependencies/registry/component_registry.py +++ b/DashAI/back/dependencies/registry/component_registry.py @@ -454,7 +454,8 @@ def get_related_components(self, component_id: str) -> List[Dict[str, Any]]: """Obtain any related component of the given component name. If the component has no related components, then the method returns an empty - list. + list. Related names that are not registered components (e.g. an explainer + declared by a model but provided by an uninstalled plugin) are skipped. Parameters ---------- @@ -479,4 +480,5 @@ def get_related_components(self, component_id: str) -> List[Dict[str, Any]]: return [ self.__getitem__(related_component_id) for related_component_id in self._relationship_manager[component_id] + if self.__contains__(related_component_id) ] diff --git a/DashAI/back/explainability/explainers/contrastive_shap.py b/DashAI/back/explainability/explainers/contrastive_shap.py new file mode 100644 index 000000000..4b2ef9f7f --- /dev/null +++ b/DashAI/back/explainability/explainers/contrastive_shap.py @@ -0,0 +1,458 @@ +from typing import List + +from DashAI.back.core.artifacts import Artifact, PlotlyArtifact, TextArtifact +from DashAI.back.core.schema_fields import ( + BaseSchema, + bool_field, + float_field, + schema_field, + string_field, +) +from DashAI.back.core.utils import MultilingualString +from DashAI.back.explainability.local_explainer import BaseLocalExplainer +from DashAI.back.models.base_model import BaseModel + + +class ContrastiveShapSchema(BaseSchema): + """Schema for ContrastiveShap explainer hyperparameters. + + Configures the foil class the explanation contrasts against and the + background sampling used to fit the underlying SHAP explainer. + """ + + foil_class: schema_field( + string_field(), + placeholder="second_most_probable", + description=MultilingualString( + en=( + "Class to contrast against (the foil in 'why P rather than " + "Q?'). Enter an exact class name, or leave " + "'second_most_probable' to contrast against the runner-up " + "class of each instance." + ), + es=( + "Clase contra la que se contrasta (el foil en '¿por qué P y " + "no Q?'). Ingrese un nombre de clase exacto, o deje " + "'second_most_probable' para contrastar con la segunda clase " + "más probable de cada instancia." + ), + pt=( + "Classe contra a qual contrastar (o foil em 'por que P e não " + "Q?'). Insira um nome de classe exato, ou deixe " + "'second_most_probable' para contrastar com a segunda classe " + "mais provável de cada instância." + ), + zh=( + "对比的目标类别('为什么是P而不是Q'中的Q)。" + "输入准确的类别名称,或保留'second_most_probable'以对比每个实例的第二可能类别。" + ), + de=( + "Klasse, gegen die kontrastiert wird (das Foil in 'warum P " + "statt Q?'). Geben Sie einen exakten Klassennamen ein oder " + "belassen Sie 'second_most_probable', um gegen die " + "zweitwahrscheinlichste Klasse zu kontrastieren." + ), + ), + alias=MultilingualString( + en="Foil class", + es="Clase foil", + pt="Classe foil", + zh="对比类别", + de="Foil-Klasse", + ), + ) # type: ignore + + fit_parameter_sample_background_data: schema_field( + bool_field(), + placeholder=True, + description=MultilingualString( + en=( + "'true' if background data must be sampled; otherwise the " + "entire training set is used. Smaller datasets speed up the " + "algorithm runtime." + ), + es=( + "'true' si se deben muestrear los datos de fondo; de lo " + "contrario se usa el conjunto de entrenamiento completo. " + "Conjuntos más pequeños reducen el tiempo de ejecución." + ), + pt=( + "'true' se os dados de fundo devem ser amostrados; caso " + "contrário, usa-se o conjunto de treinamento completo. " + "Conjuntos menores reduzem o tempo de execução." + ), + zh=( + "如果需要对背景数据进行采样则为'true';否则使用整个训练集。较小的数据集可加速算法运行。" + ), + de=( + "'true', wenn Hintergrunddaten gesamplet werden müssen; sonst " + "wird der gesamte Trainingssatz verwendet. Kleinere " + "Datensätze beschleunigen die Laufzeit." + ), + ), + alias=MultilingualString( + en="Sample background data", + es="Muestrear datos de fondo", + pt="Amostrar dados de fundo", + zh="采样背景数据", + de="Hintergrunddaten samplen", + ), + ) # type: ignore + + fit_parameter_background_fraction: schema_field( + float_field(ge=0, le=1), + placeholder=0.2, + description=MultilingualString( + en=( + "If 'Sample background data' is selected, fraction of " + "background samples to draw from the training set." + ), + es=( + "Si se selecciona 'Muestrear datos de fondo', proporción de " + "muestras de fondo a extraer del conjunto de entrenamiento." + ), + pt=( + "Se 'Amostrar dados de fundo' estiver selecionado, fração de " + "amostras de fundo a extrair do conjunto de treinamento." + ), + zh=("如果选择了'采样背景数据',则为从训练集中抽取的背景样本比例。"), + de=( + "Wenn 'Hintergrunddaten samplen' ausgewählt ist, Anteil der " + "Hintergrundproben aus dem Trainingssatz." + ), + ), + alias=MultilingualString( + en="Background fraction", + es="Fracción de fondo", + pt="Fração de fundo", + zh="背景比例", + de="Hintergrundfraktion", + ), + ) # type: ignore + + +class ContrastiveShap(BaseLocalExplainer): + """Contrastive local explainer: why class P rather than class Q? + + Standard attribution methods answer "why did the model predict P?". + Contrastive explanations answer the question people actually ask: "why P + rather than Q?". This explainer computes Kernel SHAP attributions for both + the predicted class (the fact) and a contrast class (the foil), and + reports the per-feature difference. Features with a large positive delta + are the ones that pushed the model towards the fact and away from the + foil. + + The foil can be a fixed class name, or the second most probable class of + each instance (default). + + References + ---------- + - [1] Miller, T. (2019). "Explanation in Artificial Intelligence: + Insights from the Social Sciences." Artificial Intelligence 267. + https://arxiv.org/abs/1706.07269 + - [2] Lundberg, S.M. & Lee, S.I. (2017). "A Unified Approach to + Interpreting Model Predictions." NeurIPS 30. + https://arxiv.org/abs/1705.07874 + """ + + COMPATIBLE_COMPONENTS = ["TabularClassificationTask"] + DISPLAY_NAME = MultilingualString( + en="Contrastive SHAP (why P rather than Q)", + es="SHAP contrastivo (por qué P y no Q)", + pt="SHAP contrastivo (por que P e não Q)", + zh="对比SHAP(为什么是P而不是Q)", + de="Kontrastives SHAP (warum P statt Q)", + ) + DESCRIPTION = MultilingualString( + en=( + "Explains why the model predicted one class rather than another " + "by contrasting SHAP attributions between the two classes." + ), + es=( + "Explica por qué el modelo predijo una clase y no otra, " + "contrastando las atribuciones SHAP entre ambas clases." + ), + pt=( + "Explica por que o modelo previu uma classe e não outra, " + "contrastando as atribuições SHAP entre as duas classes." + ), + zh=("通过对比两个类别之间的SHAP归因,解释模型为什么预测一个类别而不是另一个。"), + de=( + "Erklärt, warum das Modell eine Klasse statt einer anderen " + "vorhergesagt hat, durch Kontrastierung der SHAP-Attributionen " + "beider Klassen." + ), + ) + COLOR = "#00695C" + SCHEMA = ContrastiveShapSchema + + def __init__( + self, + model: BaseModel, + foil_class: str = "second_most_probable", + ) -> None: + """Initialize a new instance of a ContrastiveShap explainer. + + Parameters + ---------- + model : BaseModel + Model to be explained. + foil_class : str + Name of the class to contrast against, or + 'second_most_probable' to use the runner-up class per instance. + """ + super().__init__(model) + self.foil_class = foil_class + + def fit( + self, + background_dataset, + sample_background_data=False, + background_fraction=None, + **kwargs, + ): + """Fit the underlying Kernel SHAP explainer on background data. + + Parameters + ---------- + background_dataset : Tuple[DatasetDict, DatasetDict] + Tuple ``(x, y)`` with the dataset splits; the train split is used + as SHAP background data. + sample_background_data : bool + True if the background data must be sampled. + background_fraction : float + Fraction of the training samples used as background data when + ``sample_background_data`` is True. + **kwargs : Any + Ignored; present for interface compatibility. + + Returns + ------- + ContrastiveShap + The fitted explainer instance (``self``). + """ + import shap + + x, y = background_dataset + x_train = x["train"] + y_train = y["train"] + + background_data = x_train.to_pandas() + feature_names = list(x_train.column_names) + + if bool(sample_background_data) and background_fraction: + n_samples = max(1, int(background_fraction * len(background_data))) + background_data = shap.sample(background_data, n_samples) + + self.explainer = shap.KernelExplainer( + model=self.model.predict, + data=background_data, + feature_names=feature_names, + ) + + output_column = y_train.column_names[0] + target_names = y_train.types[output_column].categories + self.metadata = { + "feature_names": feature_names, + "target_names": list(target_names), + } + + return self + + def _resolve_foil(self, prediction, fact_class: int) -> int: + """Resolve the foil class index for one instance. + + Parameters + ---------- + prediction : np.ndarray + Per-class probabilities for the instance. + fact_class : int + Index of the predicted (fact) class. + + Returns + ------- + int + Index of the foil class. Falls back to the second most probable + class when the configured name is unknown or equals the fact. + """ + import numpy as np + + target_names = self.metadata["target_names"] + if self.foil_class in target_names: + foil = target_names.index(self.foil_class) + if foil != fact_class: + return foil + + order = np.argsort(prediction)[::-1] + return int(order[1]) if len(order) > 1 else fact_class + + def explain_instance(self, instances): + """Compute contrastive SHAP attributions for the given instances. + + Parameters + ---------- + instances : DatasetDict + Instances to be explained. + + Returns + ------- + dict + Dictionary with, for each instance, the fact and foil classes and + the per-feature attribution difference (fact minus foil). + """ + import numpy as np + + from DashAI.back.dataloaders.classes.dashai_dataset import to_dashai_dataset + + dataset = to_dashai_dataset(instances) + X = dataset.to_pandas() + + predictions = np.asarray(self.model.predict(dataset)) + + shap_values = self.explainer.shap_values(X=X) + # (n_instances, n_features, n_classes) -> (n_instances, n_classes, + # n_features), same normalization used by the KernelShap explainer. + shap_values = np.array(shap_values).transpose(0, 2, 1) + + explanation = {"metadata": self.metadata} + for i, (instance, prediction, contributions) in enumerate( + zip(X.to_numpy(), predictions, shap_values) # noqa: B905 + ): + fact_class = int(np.argmax(prediction)) + foil_class = self._resolve_foil(prediction, fact_class) + delta = contributions[fact_class] - contributions[foil_class] + + explanation[i] = { + "instance_values": instance.tolist(), + "model_prediction": prediction.tolist(), + "fact_class": fact_class, + "foil_class": foil_class, + "fact_shap_values": np.round(contributions[fact_class], 3).tolist(), + "foil_shap_values": np.round(contributions[foil_class], 3).tolist(), + "delta_values": np.round(delta, 3).tolist(), + } + + return explanation + + def _create_plot(self, data, fact_name, foil_name, fact_prob, foil_prob): + """Create the contrastive bar plot for one instance. + + Parameters + ---------- + data : pd.DataFrame + Dataframe with 'label' and 'delta' columns, sorted for plotting. + fact_name : str + Name of the predicted class. + foil_name : str + Name of the foil class. + fact_prob : float + Predicted probability of the fact class. + foil_prob : float + Predicted probability of the foil class. + + Returns + ------- + plotly.graph_objs.Figure + The Plotly figure. + """ + import plotly.graph_objs as go + + colors = [ + "rgb(231,63,116)" if value >= 0 else "rgb(47,138,196)" + for value in data["delta"] + ] + + fig = go.Figure( + go.Bar( + x=data["delta"], + y=data["label"], + orientation="h", + marker={"color": colors}, + text=data["delta"], + textposition="auto", + ) + ) + + fig.update_layout( + title={ + "text": ( + f"Why {fact_name} (p={fact_prob}) rather than " + f"{foil_name} (p={foil_prob})?" + ), + "font": {"size": 14}, + }, + margin={"pad": 20, "l": 100, "r": 60, "t": 60, "b": 40}, + xaxis={"title_text": "Attribution difference (fact - foil)"}, + yaxis={"showgrid": True}, + ) + + return fig + + def plot(self, explanation: dict) -> List[Artifact]: + """Render each instance as a contrastive bar plot plus a text summary. + + Parameters + ---------- + explanation : dict + Dictionary with the explanation generated by the explainer. + + Returns + ------- + List[Artifact] + A list of typed artifacts: one plotly and one text artifact per + explained instance. + """ + import numpy as np + import pandas as pd + + exp = explanation.copy() + metadata = exp.pop("metadata") + feature_names = metadata["feature_names"] + target_names = metadata["target_names"] + max_features = 8 + + artifacts = [] + for i in exp: + instance = exp[i] + fact_class = instance["fact_class"] + foil_class = instance["foil_class"] + fact_name = target_names[fact_class] + foil_name = target_names[foil_class] + prediction = instance["model_prediction"] + fact_prob = float(np.round(prediction[fact_class], 3)) + foil_prob = float(np.round(prediction[foil_class], 3)) + + data = pd.DataFrame( + { + "features": feature_names, + "values": instance["instance_values"], + "delta": instance["delta_values"], + } + ) + data["delta_abs"] = data["delta"].abs() + data = data.sort_values(by="delta_abs", ascending=True) + if len(data) > max_features: + data = data.iloc[-max_features:, :] + data["label"] = data["features"] + "=" + data["values"].map(str) + + title = f"Instance {int(i) + 1}" + fig = self._create_plot(data, fact_name, foil_name, fact_prob, foil_prob) + artifacts.append(PlotlyArtifact(payload=fig, title=title)) + + top = data.iloc[::-1].head(3) + top_features = ", ".join( + f"{feature}={value}" + for feature, value in zip( + top["features"].tolist(), + top["values"].tolist(), + strict=True, + ) + ) + summary = ( + f"The model predicted {fact_name} (p={fact_prob}) rather than " + f"{foil_name} (p={foil_prob}) mainly because of: " + f"{top_features}." + ) + artifacts.append(TextArtifact(payload=summary, title=title)) + + return artifacts diff --git a/DashAI/back/explainability/explainers/dice_counterfactual.py b/DashAI/back/explainability/explainers/dice_counterfactual.py new file mode 100644 index 000000000..d7fc87712 --- /dev/null +++ b/DashAI/back/explainability/explainers/dice_counterfactual.py @@ -0,0 +1,452 @@ +from typing import List + +from DashAI.back.core.artifacts import ( + Artifact, + TableArtifact, + TablePayload, + TextArtifact, +) +from DashAI.back.core.schema_fields import ( + BaseSchema, + enum_field, + int_field, + schema_field, + string_field, +) +from DashAI.back.core.utils import MultilingualString +from DashAI.back.explainability.local_explainer import BaseLocalExplainer +from DashAI.back.models.base_model import BaseModel + + +class DiceCounterfactualSchema(BaseSchema): + """Schema for the DiCE counterfactual explainer hyperparameters. + + Configures how many counterfactuals are generated, the generation + method and the class the counterfactuals should reach. + """ + + total_cfs: schema_field( + int_field(ge=1, le=10), + placeholder=3, + description=MultilingualString( + en="Number of counterfactual examples to generate per instance.", + es="Número de ejemplos contrafactuales a generar por instancia.", + pt="Número de exemplos contrafactuais a gerar por instância.", + zh="为每个实例生成的反事实示例数量。", + de="Anzahl der pro Instanz erzeugten kontrafaktischen Beispiele.", + ), + alias=MultilingualString( + en="Number of counterfactuals", + es="Número de contrafactuales", + pt="Número de contrafactuais", + zh="反事实数量", + de="Anzahl kontrafaktischer Beispiele", + ), + ) # type: ignore + + method: schema_field( + enum_field(enum=["random", "genetic", "kdtree"]), + placeholder="random", + description=MultilingualString( + en=( + "Counterfactual search strategy: 'random' (random sampling of " + "feature perturbations), 'genetic' (genetic algorithm " + "optimizing proximity and diversity) or 'kdtree' (closest " + "real training examples)." + ), + es=( + "Estrategia de búsqueda: 'random' (muestreo aleatorio de " + "perturbaciones), 'genetic' (algoritmo genético que optimiza " + "proximidad y diversidad) o 'kdtree' (ejemplos reales más " + "cercanos del entrenamiento)." + ), + pt=( + "Estratégia de busca: 'random' (amostragem aleatória de " + "perturbações), 'genetic' (algoritmo genético que otimiza " + "proximidade e diversidade) ou 'kdtree' (exemplos reais mais " + "próximos do treinamento)." + ), + zh=( + "反事实搜索策略:'random'(随机采样特征扰动)、" + "'genetic'(优化接近度和多样性的遗传算法)或'kdtree'(最近的真实训练样本)。" + ), + de=( + "Suchstrategie: 'random' (zufällige Merkmalsstörungen), " + "'genetic' (genetischer Algorithmus für Nähe und Diversität) " + "oder 'kdtree' (nächstgelegene echte Trainingsbeispiele)." + ), + ), + alias=MultilingualString( + en="Search method", + es="Método de búsqueda", + pt="Método de busca", + zh="搜索方法", + de="Suchmethode", + ), + ) # type: ignore + + desired_class: schema_field( + string_field(), + placeholder="opposite", + description=MultilingualString( + en=( + "Class the counterfactuals should reach. Enter an exact class " + "name, or leave 'opposite' to target the runner-up class of " + "each instance." + ), + es=( + "Clase que los contrafactuales deben alcanzar. Ingrese un " + "nombre de clase exacto, o deje 'opposite' para apuntar a la " + "segunda clase más probable de cada instancia." + ), + pt=( + "Classe que os contrafactuais devem alcançar. Insira um nome " + "de classe exato, ou deixe 'opposite' para apontar à segunda " + "classe mais provável de cada instância." + ), + zh="反事实应达到的类别。输入准确的类别名称,或保留'opposite'以针对每个实例的第二可能类别。", + de=( + "Klasse, die die kontrafaktischen Beispiele erreichen sollen. " + "Geben Sie einen exakten Klassennamen ein oder belassen Sie " + "'opposite' für die zweitwahrscheinlichste Klasse." + ), + ), + alias=MultilingualString( + en="Desired class", + es="Clase deseada", + pt="Classe desejada", + zh="目标类别", + de="Zielklasse", + ), + ) # type: ignore + + +class _SklearnProbaShim: + """Adapter exposing the sklearn-native interface DiCE expects. + + DashAI classifiers override ``predict`` to return probabilities; DiCE + expects ``predict`` to return class labels and ``predict_proba`` to + return probabilities. + """ + + def __init__(self, model): + self._model = model + + def predict_proba(self, x): + """Return the class-probability matrix for ``x``.""" + return self._model.predict_proba(x) + + def predict(self, x): + """Return hard class labels derived from the probabilities.""" + import numpy as np + + return np.argmax(self._model.predict_proba(x), axis=1) + + +class DiceCounterfactual(BaseLocalExplainer): + """Diverse counterfactual explanations via the DiCE library. + + For each instance, generates a set of synthetic examples that the model + classifies as a different (desired) class while staying close to the + original instance, answering "what minimal changes would flip this + prediction?". Unlike the Nearest Counterfactual explainer (which returns + real training rows), DiCE synthesizes new feature combinations and + optimizes for both proximity and diversity. + + Note: DiCE queries the underlying estimator directly with raw feature + values, so it is intended for datasets with numeric features. + + References + ---------- + - [1] Mothilal, R.K., Sharma, A. & Tan, C. (2020). "Explaining Machine + Learning Classifiers through Diverse Counterfactual Explanations." + FAT* 2020. https://arxiv.org/abs/1905.07697 + - [2] https://github.com/interpretml/DiCE + """ + + DISPLAY_NAME = MultilingualString( + en="DiCE Counterfactuals", + es="Contrafactuales DiCE", + pt="Contrafactuais DiCE", + zh="DiCE反事实", + de="DiCE-Kontrafaktuale", + ) + DESCRIPTION = MultilingualString( + en=( + "Generates diverse synthetic examples with minimal changes that " + "flip the model's prediction to a desired class." + ), + es=( + "Genera ejemplos sintéticos diversos con cambios mínimos que " + "invierten la predicción del modelo hacia una clase deseada." + ), + pt=( + "Gera exemplos sintéticos diversos com mudanças mínimas que " + "invertem a previsão do modelo para uma classe desejada." + ), + zh="生成具有最小变化的多样化合成示例,将模型预测翻转到目标类别。", + de=( + "Erzeugt diverse synthetische Beispiele mit minimalen Änderungen, " + "die die Modellvorhersage zu einer gewünschten Klasse kippen." + ), + ) + COLOR = "#6A1B9A" + SCHEMA = DiceCounterfactualSchema + + def __init__( + self, + model: BaseModel, + total_cfs: int = 3, + method: str = "random", + desired_class: str = "opposite", + ) -> None: + """Initialize a new instance of a DiceCounterfactual explainer. + + Parameters + ---------- + model : BaseModel + Classification model to be explained. + total_cfs : int + Number of counterfactuals generated per instance. + method : str + DiCE search method: 'random', 'genetic' or 'kdtree'. + desired_class : str + Class name the counterfactuals should reach, or 'opposite' for + the runner-up class of each instance. + """ + super().__init__(model) + self.total_cfs = total_cfs + self.method = method + self.desired_class = desired_class + + def fit(self, background_dataset, **kwargs): + """Build the DiCE data and model interfaces from the train split. + + Parameters + ---------- + background_dataset : Tuple[DatasetDict, DatasetDict] + Tuple ``(x, y)`` with the dataset splits. + **kwargs : Any + Ignored; present for interface compatibility. + + Returns + ------- + DiceCounterfactual + The fitted explainer instance (``self``). + """ + import dice_ml + import numpy as np + + x, y = background_dataset + x_train = x["train"] + y_train = y["train"] + + train_frame = x_train.to_pandas() + self.feature_names = list(train_frame.columns) + + output_column = y_train.column_names[0] + target_names = [str(c) for c in y_train.types[output_column].categories] + self.metadata = { + "feature_names": self.feature_names, + "target_names": target_names, + } + self.output_column = output_column + + labels = y_train.to_pandas()[output_column].astype(str) + encoded = labels.map({name: k for k, name in enumerate(target_names)}) + train_frame = train_frame.copy() + train_frame[output_column] = encoded.to_numpy() + + continuous = [ + column + for column in self.feature_names + if np.issubdtype(train_frame[column].dtype, np.number) + ] + + data_interface = dice_ml.Data( + dataframe=train_frame, + continuous_features=continuous, + outcome_name=output_column, + ) + model_interface = dice_ml.Model( + model=_SklearnProbaShim(self.model), + backend="sklearn", + model_type="classifier", + ) + self._dice = dice_ml.Dice(data_interface, model_interface, method=self.method) + + return self + + def _resolve_desired_class(self, prediction, fact_class: int): + """Resolve DiCE's desired_class argument for one instance. + + Parameters + ---------- + prediction : np.ndarray + Per-class probabilities for the instance. + fact_class : int + Index of the predicted class. + + Returns + ------- + int or str + A class index, or the literal 'opposite' for binary problems. + """ + import numpy as np + + target_names = self.metadata["target_names"] + if self.desired_class in target_names: + desired = target_names.index(self.desired_class) + if desired != fact_class: + return desired + + if len(target_names) == 2: + return "opposite" + order = np.argsort(prediction)[::-1] + return int(order[1]) + + def explain_instance(self, instances): + """Generate counterfactual examples for each instance. + + Parameters + ---------- + instances : DatasetDict + Instances to be explained. + + Returns + ------- + dict + Dictionary with, for each instance, the model prediction and the + generated counterfactual examples. + """ + import numpy as np + + from DashAI.back.dataloaders.classes.dashai_dataset import to_dashai_dataset + + dataset = to_dashai_dataset(instances) + X = dataset.to_pandas()[self.feature_names] + + predictions = np.asarray(self.model.predict(dataset)) + + explanation = {"metadata": self.metadata} + for i in range(len(X)): + row = X.iloc[[i]] + fact_class = int(np.argmax(predictions[i])) + desired = self._resolve_desired_class(predictions[i], fact_class) + + counterfactuals = [] + try: + result = self._dice.generate_counterfactuals( + row, + total_CFs=self.total_cfs, + desired_class=desired, + ) + cfs_frame = result.cf_examples_list[0].final_cfs_df + if cfs_frame is not None: + for _, cf_row in cfs_frame.iterrows(): + values = [cf_row[f] for f in self.feature_names] + changed = [ + feature + for j, feature in enumerate(self.feature_names) + if not np.isclose(float(values[j]), float(row.iloc[0, j])) + ] + counterfactuals.append( + { + "values": [float(v) for v in values], + "predicted_class": int(cf_row[self.output_column]), + "changed_features": changed, + } + ) + except Exception: # noqa: BLE001 - DiCE may fail to find CFs + counterfactuals = [] + + explanation[i] = { + "instance_values": row.iloc[0].tolist(), + "model_prediction": predictions[i].tolist(), + "predicted_class": fact_class, + "counterfactuals": counterfactuals, + } + + return explanation + + def plot(self, explanation: dict) -> List[Artifact]: + """Render each instance as a comparison table plus a text summary. + + Parameters + ---------- + explanation : dict + Dictionary with the explanation generated by the explainer. + + Returns + ------- + List[Artifact] + A list of typed artifacts: one table and one text artifact per + explained instance. + """ + import numpy as np + + exp = explanation.copy() + metadata = exp.pop("metadata") + feature_names = metadata["feature_names"] + target_names = metadata["target_names"] + + artifacts = [] + for i in exp: + instance = exp[i] + predicted_class = instance["predicted_class"] + predicted_name = target_names[predicted_class] + predicted_prob = float( + np.round(instance["model_prediction"][predicted_class], 3) + ) + counterfactuals = instance["counterfactuals"] + + columns = ["Feature", "Instance"] + [ + f"Counterfactual {k + 1}" for k in range(len(counterfactuals)) + ] + rows = [] + highlight = [] + for row_idx, feature in enumerate(feature_names): + row = [feature, instance["instance_values"][row_idx]] + for cf_idx, counterfactual in enumerate(counterfactuals): + row.append(counterfactual["values"][row_idx]) + if feature in counterfactual["changed_features"]: + highlight.append({"row": row_idx, "column": 2 + cf_idx}) + rows.append(row) + + prediction_row = ["Predicted class", predicted_name] + [ + target_names[counterfactual["predicted_class"]] + for counterfactual in counterfactuals + ] + rows.append(prediction_row) + for cf_idx in range(len(counterfactuals)): + highlight.append({"row": len(feature_names), "column": 2 + cf_idx}) + + title = f"Instance {int(i) + 1}" + artifacts.append( + TableArtifact( + payload=TablePayload( + columns=columns, rows=rows, highlight=highlight + ), + title=title, + ) + ) + + if counterfactuals: + lines = [f"The model predicted {predicted_name} (p={predicted_prob})."] + for cf_idx, counterfactual in enumerate(counterfactuals): + cf_name = target_names[counterfactual["predicted_class"]] + changed = ", ".join(counterfactual["changed_features"]) or "nothing" + lines.append( + f"Counterfactual {cf_idx + 1}: changing {changed} " + f"yields {cf_name}." + ) + summary = "\n".join(lines) + else: + summary = ( + f"The model predicted {predicted_name} " + f"(p={predicted_prob}). DiCE could not generate " + "counterfactuals for this instance." + ) + artifacts.append(TextArtifact(payload=summary, title=title)) + + return artifacts diff --git a/DashAI/back/explainability/explainers/grad_cam.py b/DashAI/back/explainability/explainers/grad_cam.py new file mode 100644 index 000000000..616c6a513 --- /dev/null +++ b/DashAI/back/explainability/explainers/grad_cam.py @@ -0,0 +1,292 @@ +from typing import List + +from DashAI.back.core.artifacts import Artifact, TextArtifact +from DashAI.back.core.schema_fields import ( + BaseSchema, + enum_field, + schema_field, +) +from DashAI.back.core.utils import MultilingualString +from DashAI.back.explainability.explainers.image_explainer_utils import ( + get_target_names, + get_torch_module, + get_transform, + heatmap_overlay_artifact, + iter_pil_images, +) +from DashAI.back.explainability.local_explainer import BaseLocalExplainer +from DashAI.back.models.base_model import BaseModel + + +class GradCamSchema(BaseSchema): + """Schema for the Grad-CAM explainer hyperparameters. + + Configures the CAM variant used to compute the class activation map. + """ + + method: schema_field( + enum_field(enum=["gradcam", "gradcam++", "eigencam"]), + placeholder="gradcam", + description=MultilingualString( + en=( + "CAM variant: 'gradcam' (original), 'gradcam++' (better for " + "multiple occurrences of a class) or 'eigencam' " + "(gradient-free, first principal component of activations)." + ), + es=( + "Variante de CAM: 'gradcam' (original), 'gradcam++' (mejor " + "para múltiples ocurrencias de una clase) o 'eigencam' (sin " + "gradientes, primera componente principal de activaciones)." + ), + pt=( + "Variante de CAM: 'gradcam' (original), 'gradcam++' (melhor " + "para múltiplas ocorrências de uma classe) ou 'eigencam' (sem " + "gradientes, primeira componente principal das ativações)." + ), + zh=( + "CAM变体:'gradcam'(原始)、'gradcam++'(更适合类别多次出现)" + "或'eigencam'(无梯度,激活的第一主成分)。" + ), + de=( + "CAM-Variante: 'gradcam' (Original), 'gradcam++' (besser bei " + "mehrfachem Auftreten einer Klasse) oder 'eigencam' " + "(gradientenfrei, erste Hauptkomponente der Aktivierungen)." + ), + ), + alias=MultilingualString( + en="CAM method", + es="Método CAM", + pt="Método CAM", + zh="CAM方法", + de="CAM-Methode", + ), + ) # type: ignore + + +class GradCam(BaseLocalExplainer): + """Gradient-based class activation maps for image classifiers. + + Grad-CAM backpropagates the score of the predicted class to the last + convolutional layer and weights its activation maps by the averaged + gradients, producing a heatmap of the image regions that most influenced + the prediction. This is a white-box method: it requires a torch module + with a convolutional backbone, so it works with all DashAI image + classifiers except the MLP (use Occlusion Saliency there instead). + + Implemented on top of the ``pytorch-grad-cam`` library. + + References + ---------- + - [1] Selvaraju, R.R. et al. (2017). "Grad-CAM: Visual Explanations from + Deep Networks via Gradient-based Localization." ICCV 2017. + https://arxiv.org/abs/1610.02391 + - [2] https://github.com/jacobgil/pytorch-grad-cam + """ + + DISPLAY_NAME = MultilingualString( + en="Grad-CAM", + es="Grad-CAM", + pt="Grad-CAM", + zh="Grad-CAM", + de="Grad-CAM", + ) + DESCRIPTION = MultilingualString( + en=( + "Highlights the image regions that most influenced the model's " + "prediction using gradient-weighted class activation maps." + ), + es=( + "Resalta las regiones de la imagen que más influyeron en la " + "predicción del modelo usando mapas de activación ponderados por " + "gradientes." + ), + pt=( + "Destaca as regiões da imagem que mais influenciaram a previsão " + "do modelo usando mapas de ativação ponderados por gradientes." + ), + zh="使用梯度加权类激活图突出显示对模型预测影响最大的图像区域。", + de=( + "Hebt die Bildregionen hervor, die die Vorhersage des Modells am " + "stärksten beeinflusst haben, mittels gradientengewichteter " + "Klassenaktivierungskarten." + ), + ) + COLOR = "#C62828" + SCHEMA = GradCamSchema + + def __init__(self, model: BaseModel, method: str = "gradcam") -> None: + """Initialize a new instance of a GradCam explainer. + + Parameters + ---------- + model : BaseModel + Image classification model to be explained. + method : str + CAM variant: 'gradcam', 'gradcam++' or 'eigencam'. + """ + super().__init__(model) + self.method = method + + def fit(self, background_dataset, **kwargs): + """Store class names in the model's class-index order. + + Parameters + ---------- + background_dataset : Tuple[DatasetDict, DatasetDict] + Tuple ``(x, y)`` with the dataset splits. + **kwargs : Any + Ignored; present for interface compatibility. + + Returns + ------- + GradCam + The fitted explainer instance (``self``). + """ + _, y = background_dataset + self.metadata = {"target_names": get_target_names(self.model, y)} + return self + + @staticmethod + def _find_target_layer(module): + """Return the last Conv2d layer of the module. + + Parameters + ---------- + module : torch.nn.Module + The model's torch module. + + Returns + ------- + torch.nn.Conv2d + The last convolutional layer. + + Raises + ------ + ValueError + If the module has no convolutional layer. + """ + import torch + + target = None + for layer in module.modules(): + if isinstance(layer, torch.nn.Conv2d): + target = layer + if target is None: + raise ValueError( + "Grad-CAM requires a convolutional backbone, but the model " + "has no Conv2d layer. Use Occlusion Saliency for " + "non-convolutional image models." + ) + return target + + def explain_instance(self, instances): + """Compute a class activation map for each image. + + Parameters + ---------- + instances : DashAIDataset + Images to be explained; the first column must contain images. + + Returns + ------- + dict + Dictionary with, for each image, the resized image, the CAM + heatmap and the model prediction. + """ + import numpy as np + import torch + from pytorch_grad_cam import EigenCAM, GradCAM, GradCAMPlusPlus + from pytorch_grad_cam.utils.model_targets import ClassifierOutputTarget + + cam_classes = { + "gradcam": GradCAM, + "gradcam++": GradCAMPlusPlus, + "eigencam": EigenCAM, + } + cam_class = cam_classes[self.method] + + module = get_torch_module(self.model) + target_layer = self._find_target_layer(module) + transform = get_transform(self.model) + image_size = int(getattr(self.model, "image_size", 224)) + device = getattr(self.model, "device", torch.device("cpu")) + + module = module.to(device).eval() + + explanation = {"metadata": self.metadata} + with cam_class(model=module, target_layers=[target_layer]) as cam: + for i, pil_image in enumerate(iter_pil_images(instances)): + tensor = transform(pil_image).unsqueeze(0).to(device) + + with torch.no_grad(): + probs = torch.softmax(module(tensor), dim=1)[0] + predicted_class = int(torch.argmax(probs)) + + grayscale = cam( + input_tensor=tensor, + targets=[ClassifierOutputTarget(predicted_class)], + )[0] + + resized = pil_image.resize((image_size, image_size)) + explanation[i] = { + "image": np.asarray(resized, dtype=np.uint8).tolist(), + "heatmap": np.round(grayscale, 4).tolist(), + "model_prediction": np.round( + probs.detach().cpu().numpy(), 4 + ).tolist(), + "predicted_class": predicted_class, + } + + return explanation + + def plot(self, explanation: dict) -> List[Artifact]: + """Render each image as a heatmap overlay plus a text summary. + + Parameters + ---------- + explanation : dict + Dictionary with the explanation generated by the explainer. + + Returns + ------- + List[Artifact] + A list of typed artifacts: one plotly overlay and one text + artifact per explained image. + """ + import numpy as np + + exp = explanation.copy() + metadata = exp.pop("metadata") + target_names = metadata["target_names"] + + artifacts = [] + for i in exp: + instance = exp[i] + predicted_class = instance["predicted_class"] + predicted_name = target_names[predicted_class] + predicted_prob = float( + np.round(instance["model_prediction"][predicted_class], 3) + ) + + title = f"Image {int(i) + 1}" + subtitle = ( + f"{self.method}: regions supporting {predicted_name} " + f"(p={predicted_prob})" + ) + artifacts.append( + heatmap_overlay_artifact( + instance["image"], instance["heatmap"], title, subtitle + ) + ) + artifacts.append( + TextArtifact( + payload=( + f"The model predicted {predicted_name} " + f"(p={predicted_prob}). Highlighted regions are the " + "areas whose activations most supported this class." + ), + title=title, + ) + ) + + return artifacts diff --git a/DashAI/back/explainability/explainers/image_explainer_utils.py b/DashAI/back/explainability/explainers/image_explainer_utils.py new file mode 100644 index 000000000..31e645d7b --- /dev/null +++ b/DashAI/back/explainability/explainers/image_explainer_utils.py @@ -0,0 +1,170 @@ +"""Shared helpers for image-classification explainers. + +These helpers define the (minimal) white-box capability contract image +explainers rely on: + +- ``model.model`` is the underlying ``torch.nn.Module``. +- ``model.get_inference_transform()`` returns the exact transform the model + applies to input images (all DashAI image classifiers expose it). +- ``model.image_size`` (int) is the model's input resolution. +- ``model.idx_to_label`` maps class indices to label names. +""" + +from typing import Any, List + +from DashAI.back.core.artifacts import PlotlyArtifact + + +def get_torch_module(model: Any): + """Return the underlying ``torch.nn.Module`` of a DashAI image model. + + Parameters + ---------- + model : Any + The DashAI model wrapper. + + Returns + ------- + torch.nn.Module + The trained torch module. + + Raises + ------ + ValueError + If the model does not expose a torch module. + """ + import torch + + module = getattr(model, "model", None) + if module is None or not isinstance(module, torch.nn.Module): + raise ValueError( + "This explainer requires a model exposing its torch module via " + f"the 'model' attribute; got {type(model).__name__}." + ) + return module + + +def get_transform(model: Any): + """Return the model's inference transform, with a plain fallback. + + Parameters + ---------- + model : Any + The DashAI model wrapper. + + Returns + ------- + Callable + A transform mapping a PIL image to a normalized tensor. + """ + if hasattr(model, "get_inference_transform"): + return model.get_inference_transform() + + from torchvision import transforms + + image_size = int(getattr(model, "image_size", 224)) + return transforms.Compose( + [ + transforms.Lambda(lambda img: img.convert("RGB")), + transforms.Resize((image_size, image_size)), + transforms.ToTensor(), + ] + ) + + +def get_target_names(model: Any, y_dataset) -> List[str]: + """Resolve class names in the model's class-index order. + + Prefers the model's ``idx_to_label`` mapping (which reflects the label + order used at training time) and falls back to the sorted categories of + the target column. + + Parameters + ---------- + model : Any + The DashAI model wrapper. + y_dataset : Any + Target splits; ``y_dataset["train"]`` must expose ``column_names`` + and ``types``. + + Returns + ------- + List[str] + Class names indexed by model output position. + """ + idx_to_label = getattr(model, "idx_to_label", None) + if idx_to_label: + return [str(idx_to_label[key]) for key in sorted(idx_to_label)] + + y_train = y_dataset["train"] + output_column = y_train.column_names[0] + return sorted(str(c) for c in y_train.types[output_column].categories) + + +def iter_pil_images(instances): + """Yield the PIL image of each row in an image dataset. + + Parameters + ---------- + instances : Any + A DashAIDataset (or compatible) whose first column holds images + exposing ``to_pil()``. + + Yields + ------ + PIL.Image.Image + Each image converted to RGB. + """ + image_column = list(instances.features.keys())[0] + for index in range(len(instances)): + yield instances[index][image_column].to_pil().convert("RGB") + + +def heatmap_overlay_artifact( + image_uint8, + heatmap, + title: str, + subtitle: str, +) -> PlotlyArtifact: + """Build a plotly artifact with a jet heatmap blended over an image. + + Parameters + ---------- + image_uint8 : array-like + RGB image of shape (H, W, 3), uint8 values. + heatmap : array-like + Saliency map of shape (H, W) with values in [0, 1]. + title : str + Artifact title (shown in the instance selector). + subtitle : str + Figure title (e.g. predicted class and probability). + + Returns + ------- + PlotlyArtifact + The plotly artifact with the blended overlay figure. + """ + import numpy as np + import plotly.graph_objs as go + + image = np.asarray(image_uint8, dtype=np.float32) / 255.0 + cam = np.clip(np.asarray(heatmap, dtype=np.float32), 0.0, 1.0) + + # Jet-like colormap, avoids a matplotlib/cv2 dependency at plot time. + red = np.clip(1.5 - np.abs(4 * cam - 3), 0, 1) + green = np.clip(1.5 - np.abs(4 * cam - 2), 0, 1) + blue = np.clip(1.5 - np.abs(4 * cam - 1), 0, 1) + colored = np.stack([red, green, blue], axis=-1) + + blended = (0.5 * image + 0.5 * colored) * 255.0 + blended = blended.astype(np.uint8) + + fig = go.Figure(go.Image(z=blended)) + fig.update_layout( + title={"text": subtitle, "font": {"size": 14}}, + margin={"l": 10, "r": 10, "t": 50, "b": 10}, + xaxis={"visible": False}, + yaxis={"visible": False}, + ) + + return PlotlyArtifact(payload=fig, title=title) diff --git a/DashAI/back/explainability/explainers/lime_text.py b/DashAI/back/explainability/explainers/lime_text.py new file mode 100644 index 000000000..89c8f5626 --- /dev/null +++ b/DashAI/back/explainability/explainers/lime_text.py @@ -0,0 +1,319 @@ +from typing import List + +from DashAI.back.core.artifacts import Artifact, PlotlyArtifact, TextArtifact +from DashAI.back.core.schema_fields import ( + BaseSchema, + int_field, + schema_field, +) +from DashAI.back.core.utils import MultilingualString +from DashAI.back.explainability.local_explainer import BaseLocalExplainer +from DashAI.back.models.base_model import BaseModel + + +class LimeTextSchema(BaseSchema): + """Schema for the LIME text explainer hyperparameters. + + Configures how many words are reported and how many perturbed samples + LIME draws to fit its local surrogate model. + """ + + num_features: schema_field( + int_field(ge=1, le=50), + placeholder=10, + description=MultilingualString( + en="Maximum number of words reported in the explanation.", + es="Número máximo de palabras reportadas en la explicación.", + pt="Número máximo de palavras reportadas na explicação.", + zh="解释中报告的最大词数。", + de="Maximale Anzahl der in der Erklärung gemeldeten Wörter.", + ), + alias=MultilingualString( + en="Number of words", + es="Número de palabras", + pt="Número de palavras", + zh="词数", + de="Anzahl der Wörter", + ), + ) # type: ignore + + num_samples: schema_field( + int_field(ge=100, le=5000), + placeholder=1000, + description=MultilingualString( + en=( + "Number of perturbed texts sampled to fit the local surrogate " + "model. More samples give more stable explanations but take " + "longer." + ), + es=( + "Número de textos perturbados muestreados para ajustar el " + "modelo sustituto local. Más muestras dan explicaciones más " + "estables pero tardan más." + ), + pt=( + "Número de textos perturbados amostrados para ajustar o " + "modelo substituto local. Mais amostras dão explicações mais " + "estáveis, mas demoram mais." + ), + zh="为拟合局部代理模型而采样的扰动文本数量。样本越多解释越稳定,但耗时越长。", + de=( + "Anzahl der gestörten Texte zum Anpassen des lokalen " + "Ersatzmodells. Mehr Stichproben ergeben stabilere " + "Erklärungen, dauern aber länger." + ), + ), + alias=MultilingualString( + en="Number of samples", + es="Número de muestras", + pt="Número de amostras", + zh="样本数量", + de="Anzahl der Stichproben", + ), + ) # type: ignore + + +class LimeText(BaseLocalExplainer): + """LIME explanations for text classification models. + + Fits a sparse linear surrogate model on random word-masked variants of + the input text, weighting variants by similarity to the original. The + surrogate's coefficients estimate each word's contribution to the + predicted class. Model agnostic: only ``predict`` is queried. Compared to + Token Ablation (one word at a time), LIME captures joint effects of + removing several words but is stochastic and needs more model calls. + + References + ---------- + - [1] Ribeiro, M.T., Singh, S. & Guestrin, C. (2016). "'Why Should I + Trust You?' Explaining the Predictions of Any Classifier." + KDD 2016. https://arxiv.org/abs/1602.04938 + - [2] https://github.com/marcotcr/lime + """ + + COMPATIBLE_COMPONENTS = ["TextClassificationTask"] + DISPLAY_NAME = MultilingualString( + en="LIME (text)", + es="LIME (texto)", + pt="LIME (texto)", + zh="LIME(文本)", + de="LIME (Text)", + ) + DESCRIPTION = MultilingualString( + en=( + "Fits a local linear surrogate on word-masked text variants to " + "estimate each word's contribution to the prediction." + ), + es=( + "Ajusta un sustituto lineal local sobre variantes del texto con " + "palabras enmascaradas para estimar la contribución de cada " + "palabra a la predicción." + ), + pt=( + "Ajusta um substituto linear local em variantes do texto com " + "palavras mascaradas para estimar a contribuição de cada palavra " + "à previsão." + ), + zh="在词遮蔽的文本变体上拟合局部线性代理模型,以估计每个词对预测的贡献。", + de=( + "Passt ein lokales lineares Ersatzmodell auf wortmaskierten " + "Textvarianten an, um den Beitrag jedes Wortes zur Vorhersage zu " + "schätzen." + ), + ) + COLOR = "#2E7D32" + SCHEMA = LimeTextSchema + + def __init__( + self, + model: BaseModel, + num_features: int = 10, + num_samples: int = 1000, + ) -> None: + """Initialize a new instance of a LimeText explainer. + + Parameters + ---------- + model : BaseModel + Text classification model to be explained. + num_features : int + Maximum number of words reported per explanation. + num_samples : int + Number of perturbed texts sampled by LIME. + """ + super().__init__(model) + self.num_features = num_features + self.num_samples = num_samples + + def fit(self, background_dataset, **kwargs): + """Store class names from the training targets. + + Parameters + ---------- + background_dataset : Tuple[DatasetDict, DatasetDict] + Tuple ``(x, y)`` with the dataset splits. + **kwargs : Any + Ignored; present for interface compatibility. + + Returns + ------- + LimeText + The fitted explainer instance (``self``). + """ + _, y = background_dataset + y_train = y["train"] + + output_column = y_train.column_names[0] + target_names = y_train.types[output_column].categories + self.metadata = {"target_names": [str(c) for c in target_names]} + + return self + + def explain_instance(self, instances): + """Compute LIME word attributions for each instance. + + Parameters + ---------- + instances : DatasetDict + Instances to be explained; must contain a single text column + (tokenizer artifact columns are ignored). + + Returns + ------- + dict + Dictionary with, for each instance, the word weights and the + model prediction. + """ + import numpy as np + import pandas as pd + from lime.lime_text import LimeTextExplainer + + from DashAI.back.dataloaders.classes.dashai_dataset import to_dashai_dataset + + dataset = to_dashai_dataset(instances) + X = dataset.to_pandas() + + # Same guard as TokenAblation: the job may hand over a dataset the + # model already prepared (tokenized), so rebuild from raw text only. + tokenizer_columns = {"input_ids", "attention_mask", "token_type_ids", "label"} + text_columns = [c for c in X.columns if c not in tokenizer_columns] + if not text_columns: + raise ValueError(f"No text column found among columns: {list(X.columns)}") + text_column = text_columns[0] + texts = X[text_column].astype(str).tolist() + + def classifier_fn(variant_texts): + variants_dataset = to_dashai_dataset( + pd.DataFrame({text_column: list(variant_texts)}) + ) + return np.asarray(self.model.predict(variants_dataset)) + + base_dataset = to_dashai_dataset(pd.DataFrame({text_column: texts})) + base_predictions = np.asarray(self.model.predict(base_dataset)) + + target_names = self.metadata["target_names"] + lime_explainer = LimeTextExplainer(class_names=target_names, random_state=0) + + explanation = {"metadata": {**self.metadata, "text_column": text_column}} + for i, text in enumerate(texts): + predicted_class = int(np.argmax(base_predictions[i])) + + lime_result = lime_explainer.explain_instance( + text, + classifier_fn, + labels=(predicted_class,), + num_features=self.num_features, + num_samples=self.num_samples, + ) + word_weights = [ + [word, float(np.round(weight, 4))] + for word, weight in lime_result.as_list(label=predicted_class) + ] + + explanation[i] = { + "text": text, + "word_weights": word_weights, + "model_prediction": base_predictions[i].tolist(), + "predicted_class": predicted_class, + } + + return explanation + + def plot(self, explanation: dict) -> List[Artifact]: + """Render each instance as a word-weight bar plot plus a summary. + + Parameters + ---------- + explanation : dict + Dictionary with the explanation generated by the explainer. + + Returns + ------- + List[Artifact] + A list of typed artifacts: one plotly and one text artifact per + explained instance. + """ + import numpy as np + import plotly.graph_objs as go + + exp = explanation.copy() + metadata = exp.pop("metadata") + target_names = metadata["target_names"] + + artifacts = [] + for i in exp: + instance = exp[i] + predicted_class = instance["predicted_class"] + predicted_name = target_names[predicted_class] + predicted_prob = float( + np.round(instance["model_prediction"][predicted_class], 3) + ) + word_weights = sorted( + instance["word_weights"], key=lambda pair: abs(pair[1]) + ) + + words = [pair[0] for pair in word_weights] + weights = [pair[1] for pair in word_weights] + colors = [ + "rgb(231,63,116)" if value >= 0 else "rgb(47,138,196)" + for value in weights + ] + fig = go.Figure( + go.Bar( + x=weights, + y=words, + orientation="h", + marker={"color": colors}, + text=weights, + textposition="auto", + ) + ) + fig.update_layout( + title={ + "text": ( + f"LIME word weights for {predicted_name} (p={predicted_prob})" + ), + "font": {"size": 14}, + }, + margin={"pad": 20, "l": 100, "r": 60, "t": 60, "b": 40}, + xaxis={"title_text": "Weight (towards predicted class)"}, + yaxis={"showgrid": True}, + ) + + title = f"Instance {int(i) + 1}" + artifacts.append(PlotlyArtifact(payload=fig, title=title)) + + top = list(reversed(word_weights))[:3] + top_words = ", ".join(f"'{word}' ({weight:+})" for word, weight in top) + artifacts.append( + TextArtifact( + payload=( + f"The model predicted {predicted_name} " + f"(p={predicted_prob}). Most influential words: " + f"{top_words}." + ), + title=title, + ) + ) + + return artifacts diff --git a/DashAI/back/explainability/explainers/nearest_counterfactual.py b/DashAI/back/explainability/explainers/nearest_counterfactual.py new file mode 100644 index 000000000..513448e25 --- /dev/null +++ b/DashAI/back/explainability/explainers/nearest_counterfactual.py @@ -0,0 +1,414 @@ +from typing import List + +from DashAI.back.core.artifacts import ( + Artifact, + TableArtifact, + TablePayload, + TextArtifact, +) +from DashAI.back.core.schema_fields import ( + BaseSchema, + enum_field, + int_field, + schema_field, +) +from DashAI.back.core.utils import MultilingualString +from DashAI.back.explainability.local_explainer import BaseLocalExplainer +from DashAI.back.models.base_model import BaseModel + + +class NearestCounterfactualSchema(BaseSchema): + """Schema for NearestCounterfactual explainer hyperparameters. + + Configures how many counterfactual examples are retrieved per instance and + the distance metric used to rank candidate examples. + """ + + n_counterfactuals: schema_field( + int_field(ge=1, le=10), + placeholder=3, + description=MultilingualString( + en=( + "Number of counterfactual examples to retrieve for each " + "instance. Each counterfactual is a real training example " + "that the model classifies differently." + ), + es=( + "Número de ejemplos contrafactuales a recuperar por cada " + "instancia. Cada contrafactual es un ejemplo real de " + "entrenamiento que el modelo clasifica de forma distinta." + ), + pt=( + "Número de exemplos contrafactuais a recuperar para cada " + "instância. Cada contrafactual é um exemplo real de " + "treinamento que o modelo classifica de forma diferente." + ), + zh=( + "为每个实例检索的反事实示例数量。每个反事实都是模型分类不同的真实训练样本。" + ), + de=( + "Anzahl der kontrafaktischen Beispiele pro Instanz. Jedes " + "kontrafaktische Beispiel ist ein echtes Trainingsbeispiel, " + "das das Modell anders klassifiziert." + ), + ), + alias=MultilingualString( + en="Number of counterfactuals", + es="Número de contrafactuales", + pt="Número de contrafactuais", + zh="反事实数量", + de="Anzahl kontrafaktischer Beispiele", + ), + ) # type: ignore + + distance: schema_field( + enum_field(enum=["l1", "l2"]), + placeholder="l1", + description=MultilingualString( + en=( + "Distance used to rank candidate counterfactuals. Numeric " + "features are normalized by their range; non-numeric features " + "add a constant penalty when they differ." + ), + es=( + "Distancia usada para ordenar los contrafactuales candidatos. " + "Las características numéricas se normalizan por su rango; " + "las no numéricas agregan una penalización constante cuando " + "difieren." + ), + pt=( + "Distância usada para ordenar os contrafactuais candidatos. " + "As características numéricas são normalizadas pelo seu " + "intervalo; as não numéricas adicionam uma penalização " + "constante quando diferem." + ), + zh=( + "用于对候选反事实排序的距离。数值特征按范围归一化;非数值特征在不同时增加固定惩罚。" + ), + de=( + "Distanz zur Rangordnung der kontrafaktischen Kandidaten. " + "Numerische Merkmale werden über ihren Wertebereich " + "normalisiert; nicht numerische Merkmale erhalten bei " + "Abweichung eine konstante Strafe." + ), + ), + alias=MultilingualString( + en="Distance metric", + es="Métrica de distancia", + pt="Métrica de distância", + zh="距离度量", + de="Distanzmetrik", + ), + ) # type: ignore + + +class NearestCounterfactual(BaseLocalExplainer): + """Case-based counterfactual explainer for tabular classification. + + For each instance to explain, this explainer answers "what would have to + be different for the model to predict another class?" by retrieving the + nearest real training examples that the model classifies differently + (nearest unlike neighbors). Because counterfactuals are actual dataset + rows, they are always plausible and never out of distribution, unlike + synthetic perturbation-based counterfactuals. + + The explainer is fully model agnostic: it only queries ``predict``. + + References + ---------- + - [1] Wachter, S., Mittelstadt, B. & Russell, C. (2017). "Counterfactual + Explanations without Opening the Black Box." Harvard JOLT 31(2). + https://arxiv.org/abs/1711.00399 + - [2] Keane, M.T. & Smyth, B. (2020). "Good Counterfactuals and Where to + Find Them." ICCBR 2020. https://arxiv.org/abs/2005.13997 + """ + + COMPATIBLE_COMPONENTS = ["TabularClassificationTask"] + DISPLAY_NAME = MultilingualString( + en="Nearest Counterfactual", + es="Contrafactual más cercano", + pt="Contrafactual mais próximo", + zh="最近反事实", + de="Nächstes kontrafaktisches Beispiel", + ) + DESCRIPTION = MultilingualString( + en=( + "Finds the closest real examples classified differently by the " + "model, showing which feature changes would flip the prediction." + ), + es=( + "Encuentra los ejemplos reales más cercanos clasificados de forma " + "distinta por el modelo, mostrando qué cambios de características " + "invertirían la predicción." + ), + pt=( + "Encontra os exemplos reais mais próximos classificados de forma " + "diferente pelo modelo, mostrando quais mudanças de " + "características inverteriam a previsão." + ), + zh=("查找模型分类不同的最近真实示例,展示哪些特征变化会翻转预测。"), + de=( + "Findet die nächstgelegenen realen Beispiele, die das Modell " + "anders klassifiziert, und zeigt, welche Merkmalsänderungen die " + "Vorhersage kippen würden." + ), + ) + COLOR = "#7B1FA2" + SCHEMA = NearestCounterfactualSchema + + def __init__( + self, + model: BaseModel, + n_counterfactuals: int = 3, + distance: str = "l1", + ) -> None: + """Initialize a new instance of a NearestCounterfactual explainer. + + Parameters + ---------- + model : BaseModel + Model to be explained. + n_counterfactuals : int + Number of counterfactual examples retrieved per instance. + distance : str + Distance used to rank candidates: 'l1' or 'l2'. + """ + super().__init__(model) + self.n_counterfactuals = n_counterfactuals + self.distance = distance + + def fit(self, background_dataset, **kwargs): + """Store the background data and its model predictions. + + Parameters + ---------- + background_dataset : Tuple[DatasetDict, DatasetDict] + Tuple ``(x, y)`` with the dataset splits. The train split is used + as the pool of counterfactual candidates. + **kwargs : Any + Ignored; present for interface compatibility. + + Returns + ------- + NearestCounterfactual + The fitted explainer instance (``self``). + """ + import numpy as np + + x, y = background_dataset + x_train = x["train"] + y_train = y["train"] + + self.background_data = x_train.to_pandas() + self.feature_names = list(x_train.column_names) + + background_probs = self.model.predict(x_train) + self.background_classes = np.argmax(np.asarray(background_probs), axis=1) + + # Per-feature range for numeric columns, used to normalize distances. + self._numeric_columns = [ + column + for column in self.background_data.columns + if np.issubdtype(self.background_data[column].dtype, np.number) + ] + ranges = {} + for column in self._numeric_columns: + column_range = float( + self.background_data[column].max() - self.background_data[column].min() + ) + ranges[column] = column_range if column_range > 0 else 1.0 + self._ranges = ranges + + output_column = y_train.column_names[0] + target_names = y_train.types[output_column].categories + self.metadata = { + "feature_names": self.feature_names, + "target_names": list(target_names), + } + + return self + + def _distances(self, instance_row, candidates): + """Compute normalized distances between one instance and candidates. + + Parameters + ---------- + instance_row : pd.Series + The instance to explain. + candidates : pd.DataFrame + Candidate counterfactual rows. + + Returns + ------- + np.ndarray + One distance per candidate row. + """ + import numpy as np + + total = np.zeros(len(candidates), dtype=float) + for column in candidates.columns: + if column in self._ranges: + diff = ( + np.abs( + candidates[column].to_numpy(dtype=float) + - float(instance_row[column]) + ) + / self._ranges[column] + ) + total += diff if self.distance == "l1" else diff**2 + else: + mismatch = ( + candidates[column].to_numpy() != instance_row[column] + ).astype(float) + total += mismatch + + return np.sqrt(total) if self.distance == "l2" else total + + def explain_instance(self, instances): + """Retrieve the nearest counterfactual examples for each instance. + + Parameters + ---------- + instances : DatasetDict + Instances to be explained. + + Returns + ------- + dict + Dictionary with, for each instance, the model prediction and the + retrieved counterfactual examples. + """ + import numpy as np + + from DashAI.back.dataloaders.classes.dashai_dataset import to_dashai_dataset + + dataset = to_dashai_dataset(instances) + X = dataset.to_pandas() + + predictions = np.asarray(self.model.predict(dataset)) + + explanation = {"metadata": self.metadata} + for i, (_, instance_row) in enumerate(X.iterrows()): + predicted_class = int(np.argmax(predictions[i])) + + candidate_mask = self.background_classes != predicted_class + candidates = self.background_data[candidate_mask] + + counterfactuals = [] + if len(candidates) > 0: + distances = self._distances(instance_row, candidates) + order = np.argsort(distances)[: self.n_counterfactuals] + for rank in order: + row = candidates.iloc[int(rank)] + changed_features = [ + feature + for feature in self.feature_names + if row[feature] != instance_row[feature] + ] + candidate_index = int(candidates.index[int(rank)]) + counterfactuals.append( + { + "values": row.tolist(), + "predicted_class": int( + self.background_classes[ + self.background_data.index.get_loc(candidate_index) + ] + ), + "distance": float(np.round(distances[int(rank)], 4)), + "changed_features": changed_features, + } + ) + + explanation[i] = { + "instance_values": instance_row.tolist(), + "model_prediction": predictions[i].tolist(), + "predicted_class": predicted_class, + "counterfactuals": counterfactuals, + } + + return explanation + + def plot(self, explanation: dict) -> List[Artifact]: + """Render each instance as a comparison table plus a text summary. + + Parameters + ---------- + explanation : dict + Dictionary with the explanation generated by the explainer. + + Returns + ------- + List[Artifact] + A list of typed artifacts: one table and one text artifact per + explained instance. + """ + import numpy as np + + exp = explanation.copy() + metadata = exp.pop("metadata") + feature_names = metadata["feature_names"] + target_names = metadata["target_names"] + + artifacts = [] + for i in exp: + instance = exp[i] + instance_values = instance["instance_values"] + predicted_class = instance["predicted_class"] + predicted_name = target_names[predicted_class] + predicted_prob = float( + np.round(instance["model_prediction"][predicted_class], 3) + ) + counterfactuals = instance["counterfactuals"] + + columns = ["Feature", "Instance"] + [ + f"Counterfactual {k + 1}" for k in range(len(counterfactuals)) + ] + rows = [] + highlight = [] + for row_idx, feature in enumerate(feature_names): + row = [feature, instance_values[row_idx]] + for cf_idx, counterfactual in enumerate(counterfactuals): + row.append(counterfactual["values"][row_idx]) + if feature in counterfactual["changed_features"]: + highlight.append({"row": row_idx, "column": 2 + cf_idx}) + rows.append(row) + + prediction_row = ["Predicted class", predicted_name] + [ + target_names[counterfactual["predicted_class"]] + for counterfactual in counterfactuals + ] + rows.append(prediction_row) + for cf_idx in range(len(counterfactuals)): + highlight.append({"row": len(feature_names), "column": 2 + cf_idx}) + + title = f"Instance {int(i) + 1}" + artifacts.append( + TableArtifact( + payload=TablePayload( + columns=columns, rows=rows, highlight=highlight + ), + title=title, + ) + ) + + if counterfactuals: + lines = [ + (f"The model predicted {predicted_name} (p={predicted_prob}).") + ] + for cf_idx, counterfactual in enumerate(counterfactuals): + cf_name = target_names[counterfactual["predicted_class"]] + changed = ", ".join(counterfactual["changed_features"]) or "nothing" + lines.append( + f"Counterfactual {cf_idx + 1}: changing {changed} " + f"yields {cf_name} " + f"(distance {counterfactual['distance']})." + ) + summary = "\n".join(lines) + else: + summary = ( + f"The model predicted {predicted_name} (p={predicted_prob}). " + "No counterfactual examples were found in the training data." + ) + artifacts.append(TextArtifact(payload=summary, title=title)) + + return artifacts diff --git a/DashAI/back/explainability/explainers/occlusion_saliency.py b/DashAI/back/explainability/explainers/occlusion_saliency.py new file mode 100644 index 000000000..44fe05bff --- /dev/null +++ b/DashAI/back/explainability/explainers/occlusion_saliency.py @@ -0,0 +1,347 @@ +from typing import List + +from DashAI.back.core.artifacts import Artifact, TextArtifact +from DashAI.back.core.schema_fields import ( + BaseSchema, + int_field, + schema_field, +) +from DashAI.back.core.utils import MultilingualString +from DashAI.back.explainability.explainers.image_explainer_utils import ( + get_target_names, + get_torch_module, + get_transform, + heatmap_overlay_artifact, + iter_pil_images, +) +from DashAI.back.explainability.local_explainer import BaseLocalExplainer +from DashAI.back.models.base_model import BaseModel + + +class OcclusionSaliencySchema(BaseSchema): + """Schema for the Occlusion Saliency explainer hyperparameters. + + Configures the size and stride of the occlusion patch, in pixels of the + model's input resolution. + """ + + patch_size: schema_field( + int_field(ge=4, le=128), + placeholder=16, + description=MultilingualString( + en=( + "Side (in pixels) of the square patch that is occluded at " + "each position. Smaller patches give finer maps but require " + "more model evaluations." + ), + es=( + "Lado (en píxeles) del parche cuadrado que se ocluye en cada " + "posición. Parches más pequeños dan mapas más finos pero " + "requieren más evaluaciones del modelo." + ), + pt=( + "Lado (em pixels) do patch quadrado ocluído em cada posição. " + "Patches menores dão mapas mais finos, mas requerem mais " + "avaliações do modelo." + ), + zh="每个位置遮挡的正方形补丁的边长(像素)。较小的补丁产生更精细的图,但需要更多模型评估。", + de=( + "Seitenlänge (in Pixeln) des quadratischen Patches, der an " + "jeder Position verdeckt wird. Kleinere Patches ergeben " + "feinere Karten, erfordern aber mehr Modellauswertungen." + ), + ), + alias=MultilingualString( + en="Patch size", + es="Tamaño del parche", + pt="Tamanho do patch", + zh="补丁大小", + de="Patchgröße", + ), + ) # type: ignore + + stride: schema_field( + int_field(ge=2, le=64), + placeholder=8, + description=MultilingualString( + en=( + "Step (in pixels) between consecutive patch positions. " + "Smaller strides give smoother maps but require more model " + "evaluations." + ), + es=( + "Paso (en píxeles) entre posiciones consecutivas del parche. " + "Pasos más pequeños dan mapas más suaves pero requieren más " + "evaluaciones del modelo." + ), + pt=( + "Passo (em pixels) entre posições consecutivas do patch. " + "Passos menores dão mapas mais suaves, mas requerem mais " + "avaliações do modelo." + ), + zh="连续补丁位置之间的步长(像素)。较小的步长产生更平滑的图,但需要更多模型评估。", + de=( + "Schrittweite (in Pixeln) zwischen aufeinanderfolgenden " + "Patchpositionen. Kleinere Schritte ergeben glattere Karten, " + "erfordern aber mehr Modellauswertungen." + ), + ), + alias=MultilingualString( + en="Stride", + es="Paso", + pt="Passo", + zh="步长", + de="Schrittweite", + ), + ) # type: ignore + + +class OcclusionSaliency(BaseLocalExplainer): + """Perturbation-based saliency maps for image classifiers. + + Slides a gray patch over the image and records how much the predicted + class probability drops at each position. Regions whose occlusion causes + a large drop are the ones the model relied on. Unlike Grad-CAM, this + method needs no gradients or convolutional layers, so it works with every + DashAI image classifier including the MLP; the trade-off is one model + evaluation per patch position. + + References + ---------- + - [1] Zeiler, M.D. & Fergus, R. (2014). "Visualizing and Understanding + Convolutional Networks." ECCV 2014. https://arxiv.org/abs/1311.2901 + """ + + DISPLAY_NAME = MultilingualString( + en="Occlusion Saliency", + es="Saliencia por oclusión", + pt="Saliência por oclusão", + zh="遮挡显著性", + de="Okklusions-Salienz", + ) + DESCRIPTION = MultilingualString( + en=( + "Slides a gray patch over the image and maps how much each " + "region's occlusion lowers the predicted class probability." + ), + es=( + "Desliza un parche gris sobre la imagen y mapea cuánto baja la " + "probabilidad de la clase predicha al ocluir cada región." + ), + pt=( + "Desliza um patch cinza sobre a imagem e mapeia o quanto a " + "oclusão de cada região reduz a probabilidade da classe prevista." + ), + zh="在图像上滑动灰色补丁,映射遮挡每个区域对预测类别概率的降低程度。", + de=( + "Schiebt einen grauen Patch über das Bild und kartiert, wie stark " + "die Verdeckung jeder Region die vorhergesagte " + "Klassenwahrscheinlichkeit senkt." + ), + ) + COLOR = "#AD1457" + SCHEMA = OcclusionSaliencySchema + + def __init__( + self, + model: BaseModel, + patch_size: int = 16, + stride: int = 8, + ) -> None: + """Initialize a new instance of an OcclusionSaliency explainer. + + Parameters + ---------- + model : BaseModel + Image classification model to be explained. + patch_size : int + Side of the occluded square patch, in pixels. + stride : int + Step between consecutive patch positions, in pixels. + """ + super().__init__(model) + self.patch_size = patch_size + self.stride = stride + + def fit(self, background_dataset, **kwargs): + """Store class names in the model's class-index order. + + Parameters + ---------- + background_dataset : Tuple[DatasetDict, DatasetDict] + Tuple ``(x, y)`` with the dataset splits. + **kwargs : Any + Ignored; present for interface compatibility. + + Returns + ------- + OcclusionSaliency + The fitted explainer instance (``self``). + """ + _, y = background_dataset + self.metadata = {"target_names": get_target_names(self.model, y)} + return self + + def _occlusion_map(self, module, tensor, predicted_class, device): + """Compute the probability-drop map for one image tensor. + + Parameters + ---------- + module : torch.nn.Module + The model's torch module in eval mode. + tensor : torch.Tensor + Input tensor of shape (1, C, H, W). + predicted_class : int + Class whose probability drop is measured. + device : torch.device + Device to run the evaluations on. + + Returns + ------- + np.ndarray + Saliency map of shape (H, W), normalized to [0, 1]. + """ + import numpy as np + import torch + + _, _, height, width = tensor.shape + baseline = tensor.mean(dim=(2, 3), keepdim=True) + + with torch.no_grad(): + base_prob = torch.softmax(module(tensor), dim=1)[0, predicted_class] + base_prob = float(base_prob) + + positions = [ + (top, left) + for top in range(0, max(height - self.patch_size, 0) + 1, self.stride) + for left in range(0, max(width - self.patch_size, 0) + 1, self.stride) + ] + + drops = np.zeros((height, width), dtype=np.float32) + counts = np.zeros((height, width), dtype=np.float32) + + batch_size = 32 + with torch.no_grad(): + for start in range(0, len(positions), batch_size): + batch_positions = positions[start : start + batch_size] + occluded = tensor.repeat(len(batch_positions), 1, 1, 1) + for j, (top, left) in enumerate(batch_positions): + occluded[ + j, + :, + top : top + self.patch_size, + left : left + self.patch_size, + ] = baseline[0] + probs = torch.softmax(module(occluded.to(device)), dim=1)[ + :, predicted_class + ] + for j, (top, left) in enumerate(batch_positions): + drop = base_prob - float(probs[j]) + drops[ + top : top + self.patch_size, + left : left + self.patch_size, + ] += drop + counts[ + top : top + self.patch_size, + left : left + self.patch_size, + ] += 1.0 + + saliency = drops / np.maximum(counts, 1.0) + saliency = np.clip(saliency, 0.0, None) + max_value = saliency.max() + if max_value > 0: + saliency = saliency / max_value + return saliency + + def explain_instance(self, instances): + """Compute an occlusion saliency map for each image. + + Parameters + ---------- + instances : DashAIDataset + Images to be explained; the first column must contain images. + + Returns + ------- + dict + Dictionary with, for each image, the resized image, the saliency + map and the model prediction. + """ + import numpy as np + import torch + + module = get_torch_module(self.model) + transform = get_transform(self.model) + image_size = int(getattr(self.model, "image_size", 224)) + device = getattr(self.model, "device", torch.device("cpu")) + + module = module.to(device).eval() + + explanation = {"metadata": self.metadata} + for i, pil_image in enumerate(iter_pil_images(instances)): + tensor = transform(pil_image).unsqueeze(0).to(device) + + with torch.no_grad(): + probs = torch.softmax(module(tensor), dim=1)[0] + predicted_class = int(torch.argmax(probs)) + + saliency = self._occlusion_map(module, tensor, predicted_class, device) + + resized = pil_image.resize((image_size, image_size)) + explanation[i] = { + "image": np.asarray(resized, dtype=np.uint8).tolist(), + "heatmap": np.round(saliency, 4).tolist(), + "model_prediction": np.round(probs.detach().cpu().numpy(), 4).tolist(), + "predicted_class": predicted_class, + } + + return explanation + + def plot(self, explanation: dict) -> List[Artifact]: + """Render each image as a saliency overlay plus a text summary. + + Parameters + ---------- + explanation : dict + Dictionary with the explanation generated by the explainer. + + Returns + ------- + List[Artifact] + A list of typed artifacts: one plotly overlay and one text + artifact per explained image. + """ + import numpy as np + + exp = explanation.copy() + metadata = exp.pop("metadata") + target_names = metadata["target_names"] + + artifacts = [] + for i in exp: + instance = exp[i] + predicted_class = instance["predicted_class"] + predicted_name = target_names[predicted_class] + predicted_prob = float( + np.round(instance["model_prediction"][predicted_class], 3) + ) + + title = f"Image {int(i) + 1}" + subtitle = f"Occlusion saliency for {predicted_name} (p={predicted_prob})" + artifacts.append( + heatmap_overlay_artifact( + instance["image"], instance["heatmap"], title, subtitle + ) + ) + artifacts.append( + TextArtifact( + payload=( + f"The model predicted {predicted_name} " + f"(p={predicted_prob}). Highlighted regions are those " + "whose occlusion most lowered that probability." + ), + title=title, + ) + ) + + return artifacts diff --git a/DashAI/back/explainability/explainers/regression_kernel_shap.py b/DashAI/back/explainability/explainers/regression_kernel_shap.py new file mode 100644 index 000000000..2d0a05838 --- /dev/null +++ b/DashAI/back/explainability/explainers/regression_kernel_shap.py @@ -0,0 +1,337 @@ +from typing import List + +from DashAI.back.core.artifacts import Artifact, PlotlyArtifact, TextArtifact +from DashAI.back.core.schema_fields import ( + BaseSchema, + bool_field, + float_field, + schema_field, +) +from DashAI.back.core.utils import MultilingualString +from DashAI.back.explainability.local_explainer import BaseLocalExplainer +from DashAI.back.models.base_model import BaseModel + + +class RegressionKernelShapSchema(BaseSchema): + """Schema for the regression Kernel SHAP explainer hyperparameters. + + Configures the background sampling used to fit the SHAP explainer. + """ + + fit_parameter_sample_background_data: schema_field( + bool_field(), + placeholder=True, + description=MultilingualString( + en=( + "'true' if background data must be sampled; otherwise the " + "entire training set is used. Smaller datasets speed up the " + "algorithm runtime." + ), + es=( + "'true' si se deben muestrear los datos de fondo; de lo " + "contrario se usa el conjunto de entrenamiento completo. " + "Conjuntos más pequeños reducen el tiempo de ejecución." + ), + pt=( + "'true' se os dados de fundo devem ser amostrados; caso " + "contrário, usa-se o conjunto de treinamento completo. " + "Conjuntos menores reduzem o tempo de execução." + ), + zh=( + "如果需要对背景数据进行采样则为'true';" + "否则使用整个训练集。较小的数据集可加速算法运行。" + ), + de=( + "'true', wenn Hintergrunddaten gesamplet werden müssen; sonst " + "wird der gesamte Trainingssatz verwendet. Kleinere " + "Datensätze beschleunigen die Laufzeit." + ), + ), + alias=MultilingualString( + en="Sample background data", + es="Muestrear datos de fondo", + pt="Amostrar dados de fundo", + zh="采样背景数据", + de="Hintergrunddaten samplen", + ), + ) # type: ignore + + fit_parameter_background_fraction: schema_field( + float_field(ge=0, le=1), + placeholder=0.2, + description=MultilingualString( + en=( + "If 'Sample background data' is selected, fraction of " + "background samples to draw from the training set." + ), + es=( + "Si se selecciona 'Muestrear datos de fondo', proporción de " + "muestras de fondo a extraer del conjunto de entrenamiento." + ), + pt=( + "Se 'Amostrar dados de fundo' estiver selecionado, fração de " + "amostras de fundo a extrair do conjunto de treinamento." + ), + zh="如果选择了'采样背景数据',则为从训练集中抽取的背景样本比例。", + de=( + "Wenn 'Hintergrunddaten samplen' ausgewählt ist, Anteil der " + "Hintergrundproben aus dem Trainingssatz." + ), + ), + alias=MultilingualString( + en="Background fraction", + es="Fracción de fondo", + pt="Fração de fundo", + zh="背景比例", + de="Hintergrundfraktion", + ), + ) # type: ignore + + +class RegressionKernelShap(BaseLocalExplainer): + """Model agnostic local explainer for regression via Kernel SHAP. + + For each instance, estimates how much each feature value pushed the + model's numeric prediction above or below the expected (baseline) output, + using the Kernel SHAP weighted linear model over sampled feature + coalitions. The model is treated as a black box: only ``predict`` is + queried. + + References + ---------- + - [1] Lundberg, S.M. & Lee, S.I. (2017). "A Unified Approach to + Interpreting Model Predictions." NeurIPS 30. + https://arxiv.org/abs/1705.07874 + - [2] https://shap.readthedocs.io/en/latest/generated/shap.KernelExplainer.html + """ + + COMPATIBLE_COMPONENTS = ["RegressionTask"] + DISPLAY_NAME = MultilingualString( + en="Kernel SHAP (regression)", + es="Kernel SHAP (regresión)", + pt="Kernel SHAP (regressão)", + zh="Kernel SHAP(回归)", + de="Kernel SHAP (Regression)", + ) + DESCRIPTION = MultilingualString( + en=( + "Attributes a regression model's numeric prediction to each " + "feature value using SHAP values." + ), + es=( + "Atribuye la predicción numérica de un modelo de regresión a cada " + "valor de característica usando valores SHAP." + ), + pt=( + "Atribui a previsão numérica de um modelo de regressão a cada " + "valor de característica usando valores SHAP." + ), + zh="使用SHAP值将回归模型的数值预测归因于每个特征值。", + de=( + "Ordnet die numerische Vorhersage eines Regressionsmodells jedem " + "Merkmalswert mittels SHAP-Werten zu." + ), + ) + COLOR = "#00838F" + SCHEMA = RegressionKernelShapSchema + + def __init__(self, model: BaseModel) -> None: + """Initialize a new instance of a RegressionKernelShap explainer. + + Parameters + ---------- + model : BaseModel + Regression model to be explained. + """ + super().__init__(model) + + def fit( + self, + background_dataset, + sample_background_data=False, + background_fraction=None, + **kwargs, + ): + """Fit the Kernel SHAP explainer on background data. + + Parameters + ---------- + background_dataset : Tuple[DatasetDict, DatasetDict] + Tuple ``(x, y)`` with the dataset splits; the train split is used + as SHAP background data. + sample_background_data : bool + True if the background data must be sampled. + background_fraction : float + Fraction of the training samples used as background data when + ``sample_background_data`` is True. + **kwargs : Any + Ignored; present for interface compatibility. + + Returns + ------- + RegressionKernelShap + The fitted explainer instance (``self``). + """ + import shap + + x, y = background_dataset + x_train = x["train"] + y_train = y["train"] + + background_data = x_train.to_pandas() + feature_names = list(x_train.column_names) + + if bool(sample_background_data) and background_fraction: + n_samples = max(1, int(background_fraction * len(background_data))) + background_data = shap.sample(background_data, n_samples) + + self.explainer = shap.KernelExplainer( + model=self.model.predict, + data=background_data, + feature_names=feature_names, + ) + + self.metadata = { + "feature_names": feature_names, + "output_column": y_train.column_names[0], + } + + return self + + def explain_instance(self, instances): + """Compute SHAP values for each instance. + + Parameters + ---------- + instances : DatasetDict + Instances to be explained. + + Returns + ------- + dict + Dictionary with, for each instance, the model prediction, the + baseline value and the per-feature SHAP values. + """ + import numpy as np + + from DashAI.back.dataloaders.classes.dashai_dataset import to_dashai_dataset + + dataset = to_dashai_dataset(instances) + X = dataset.to_pandas() + + predictions = np.asarray(self.model.predict(dataset)).ravel() + + shap_values = np.asarray(self.explainer.shap_values(X=X)) + # Single-output models may yield (n, n_features) or (n, n_features, 1). + if shap_values.ndim == 3: + shap_values = shap_values[..., 0] + + base_value = np.asarray(self.explainer.expected_value).ravel()[0] + + explanation = { + "metadata": self.metadata, + "base_value": float(np.round(base_value, 3)), + } + for i, (instance, prediction, contributions) in enumerate( + zip(X.to_numpy(), predictions, shap_values, strict=True) + ): + explanation[i] = { + "instance_values": instance.tolist(), + "model_prediction": float(np.round(prediction, 3)), + "shap_values": np.round(contributions, 3).tolist(), + } + + return explanation + + def plot(self, explanation: dict) -> List[Artifact]: + """Render each instance as a SHAP bar plot plus a text summary. + + Parameters + ---------- + explanation : dict + Dictionary with the explanation generated by the explainer. + + Returns + ------- + List[Artifact] + A list of typed artifacts: one plotly and one text artifact per + explained instance. + """ + import numpy as np + import pandas as pd + import plotly.graph_objs as go + + exp = explanation.copy() + metadata = exp.pop("metadata") + base_value = exp.pop("base_value") + feature_names = metadata["feature_names"] + output_column = metadata["output_column"] + max_features = 8 + + artifacts = [] + for i in exp: + instance = exp[i] + prediction = instance["model_prediction"] + + data = pd.DataFrame( + { + "features": feature_names, + "values": instance["instance_values"], + "shap_values": instance["shap_values"], + } + ) + data["shap_abs"] = data["shap_values"].abs() + data = data.sort_values(by="shap_abs", ascending=True) + if len(data) > max_features: + data = data.iloc[-max_features:, :] + data["label"] = data["features"] + "=" + data["values"].map(str) + + colors = [ + "rgb(231,63,116)" if value >= 0 else "rgb(47,138,196)" + for value in data["shap_values"] + ] + fig = go.Figure( + go.Bar( + x=data["shap_values"], + y=data["label"], + orientation="h", + marker={"color": colors}, + text=data["shap_values"], + textposition="auto", + ) + ) + fig.update_layout( + title={ + "text": ( + f"{output_column}: prediction f(x)={prediction}, " + f"baseline E[f(x)]={base_value}" + ), + "font": {"size": 14}, + }, + margin={"pad": 20, "l": 100, "r": 60, "t": 60, "b": 40}, + xaxis={"title_text": "SHAP value (impact on prediction)"}, + yaxis={"showgrid": True}, + ) + + title = f"Instance {int(i) + 1}" + artifacts.append(PlotlyArtifact(payload=fig, title=title)) + + top = data.iloc[::-1].head(3) + top_features = ", ".join( + f"{feature}={value} ({shap:+})" + for feature, value, shap in zip( + top["features"].tolist(), + top["values"].tolist(), + top["shap_values"].tolist(), + strict=True, + ) + ) + delta = float(np.round(prediction - base_value, 3)) + summary = ( + f"The model predicted {output_column}={prediction}, " + f"{delta:+} from the baseline {base_value}. " + f"Main contributions: {top_features}." + ) + artifacts.append(TextArtifact(payload=summary, title=title)) + + return artifacts diff --git a/DashAI/back/explainability/explainers/regression_partial_dependence.py b/DashAI/back/explainability/explainers/regression_partial_dependence.py new file mode 100644 index 000000000..19142b1fc --- /dev/null +++ b/DashAI/back/explainability/explainers/regression_partial_dependence.py @@ -0,0 +1,244 @@ +from typing import List + +from DashAI.back.core.artifacts import Artifact, PlotlyArtifact +from DashAI.back.core.schema_fields import ( + BaseSchema, + float_field, + int_field, + schema_field, +) +from DashAI.back.core.utils import MultilingualString +from DashAI.back.explainability.global_explainer import BaseGlobalExplainer +from DashAI.back.models.base_model import BaseModel + + +class RegressionPartialDependenceSchema(BaseSchema): + """Schema for the regression Partial Dependence explainer. + + Configures the grid resolution and the percentile range of each + feature's grid. + """ + + grid_resolution: schema_field( + int_field(ge=5, le=200), + placeholder=50, + description=MultilingualString( + en="Number of equally spaced grid points per feature.", + es="Número de puntos de la grilla equiespaciados por característica.", + pt="Número de pontos de grade igualmente espaçados por característica.", + zh="每个特征等距网格点的数量。", + de="Anzahl gleichmäßig verteilter Gitterpunkte pro Merkmal.", + ), + alias=MultilingualString( + en="Grid resolution", + es="Resolución de la grilla", + pt="Resolução da grade", + zh="网格分辨率", + de="Gitterauflösung", + ), + ) # type: ignore + + lower_percentile: schema_field( + float_field(ge=0.0, le=1.0), + placeholder=0.05, + description=MultilingualString( + en="Lower percentile of the feature values used as grid start.", + es="Percentil inferior de los valores usados como inicio de la grilla.", + pt="Percentil inferior dos valores usados como início da grade.", + zh="用作网格起点的特征值下分位数。", + de="Unteres Perzentil der Merkmalswerte als Gitterstart.", + ), + alias=MultilingualString( + en="Lower percentile", + es="Percentil inferior", + pt="Percentil inferior", + zh="下分位数", + de="Unteres Perzentil", + ), + ) # type: ignore + + upper_percentile: schema_field( + float_field(ge=0.0, le=1.0), + placeholder=0.95, + description=MultilingualString( + en="Upper percentile of the feature values used as grid end.", + es="Percentil superior de los valores usados como fin de la grilla.", + pt="Percentil superior dos valores usados como fim da grade.", + zh="用作网格终点的特征值上分位数。", + de="Oberes Perzentil der Merkmalswerte als Gitterende.", + ), + alias=MultilingualString( + en="Upper percentile", + es="Percentil superior", + pt="Percentil superior", + zh="上分位数", + de="Oberes Perzentil", + ), + ) # type: ignore + + +class RegressionPartialDependence(BaseGlobalExplainer): + """Partial dependence curves for regression models. + + For each numeric feature, sweeps a grid of values, replaces the feature + with each grid value across the test set and averages the model's + predictions, showing the marginal effect of the feature on the predicted + value. Model agnostic (only ``predict`` is queried); assumes features are + not strongly correlated. + + References + ---------- + - [1] Friedman, J.H. (2001). "Greedy Function Approximation: A Gradient + Boosting Machine." Annals of Statistics 29(5). + - [2] https://scikit-learn.org/stable/modules/partial_dependence.html + """ + + COMPATIBLE_COMPONENTS = ["RegressionTask"] + DISPLAY_NAME = MultilingualString( + en="Partial Dependence (regression)", + es="Dependencia Parcial (regresión)", + pt="Dependência Parcial (regressão)", + zh="部分依赖(回归)", + de="Partielle Abhängigkeit (Regression)", + ) + DESCRIPTION = MultilingualString( + en=( + "Shows how the model's predicted value changes on average as each " + "feature sweeps through its range." + ), + es=( + "Muestra cómo cambia en promedio el valor predicho por el modelo " + "a medida que cada característica recorre su rango." + ), + pt=( + "Mostra como o valor previsto pelo modelo muda em média à medida " + "que cada característica percorre seu intervalo." + ), + zh="展示随着每个特征遍历其取值范围,模型预测值的平均变化。", + de=( + "Zeigt, wie sich der vorhergesagte Wert des Modells im Mittel " + "ändert, wenn jedes Merkmal seinen Wertebereich durchläuft." + ), + ) + COLOR = "#5D4037" + SCHEMA = RegressionPartialDependenceSchema + + def __init__( + self, + model: BaseModel, + grid_resolution: int = 50, + lower_percentile: float = 0.05, + upper_percentile: float = 0.95, + ): + """Initialise the regression Partial Dependence explainer. + + Parameters + ---------- + model : BaseModel + The trained DashAI regression model to be explained. + grid_resolution : int + Number of grid points per feature. + lower_percentile : float + Lower percentile of the feature values used as grid start. + upper_percentile : float + Upper percentile of the feature values used as grid end. + """ + super().__init__(model) + assert lower_percentile < upper_percentile, ( + "lower_percentile must be smaller than upper_percentile" + ) + self.grid_resolution = grid_resolution + self.lower_percentile = lower_percentile + self.upper_percentile = upper_percentile + + def explain(self, dataset): + """Compute partial dependence curves on the test split. + + Parameters + ---------- + dataset : Tuple[DatasetDict, DatasetDict] + A ``(x, y)`` pair where each element has at least a ``"test"`` + split. + + Returns + ------- + dict + Mapping from feature name to ``{"grid_values", "average"}``, + plus a ``"metadata"`` entry with the output column name. + """ + import numpy as np + + x, y = dataset + x_test = x["test"].to_pandas() + + # Cap rows to bound the number of model evaluations. + max_rows = 200 + if len(x_test) > max_rows: + x_test = x_test.iloc[:max_rows] + + output_column = y["test"].column_names[0] + explanation = {"metadata": {"output_column": output_column}} + + for column in x_test.columns: + if not np.issubdtype(x_test[column].dtype, np.number): + continue + + values = x_test[column].to_numpy(dtype=float) + start = np.quantile(values, self.lower_percentile) + stop = np.quantile(values, self.upper_percentile) + grid = np.linspace(start, stop, self.grid_resolution) + + averages = [] + frame = x_test.copy() + for grid_value in grid: + frame[column] = grid_value + predictions = np.asarray(self.model.predict(frame)).ravel() + averages.append(float(np.round(np.mean(predictions), 4))) + + explanation[column] = { + "grid_values": np.round(grid, 4).tolist(), + "average": averages, + } + + return explanation + + def plot(self, explanation: dict) -> List[Artifact]: + """Create one line-plot artifact per feature. + + Parameters + ---------- + explanation : dict + Output of :meth:`explain`. + + Returns + ------- + List[Artifact] + A list of artifacts: one plotly artifact per numeric feature. + """ + import plotly.graph_objs as go + + exp = explanation.copy() + metadata = exp.pop("metadata") + output_column = metadata["output_column"] + + artifacts = [] + for feature, curve in exp.items(): + fig = go.Figure( + go.Scatter( + x=curve["grid_values"], + y=curve["average"], + mode="lines", + ) + ) + fig.update_layout( + title={ + "text": f"Partial dependence of {output_column} on {feature}", + "font": {"size": 14}, + }, + xaxis={"title_text": feature}, + yaxis={"title_text": f"Average predicted {output_column}"}, + margin={"l": 60, "r": 30, "t": 50, "b": 50}, + ) + artifacts.append(PlotlyArtifact(payload=fig, title=feature)) + + return artifacts diff --git a/DashAI/back/explainability/explainers/regression_permutation_feature_importance.py b/DashAI/back/explainability/explainers/regression_permutation_feature_importance.py new file mode 100644 index 000000000..3749ac8a5 --- /dev/null +++ b/DashAI/back/explainability/explainers/regression_permutation_feature_importance.py @@ -0,0 +1,312 @@ +from typing import List + +from DashAI.back.core.artifacts import Artifact, PlotlyArtifact +from DashAI.back.core.schema_fields import ( + BaseSchema, + enum_field, + float_field, + int_field, + schema_field, +) +from DashAI.back.core.utils import MultilingualString +from DashAI.back.explainability.global_explainer import BaseGlobalExplainer +from DashAI.back.models.base_model import BaseModel + + +class RegressionPermutationFeatureImportanceSchema(BaseSchema): + """Schema for the regression Permutation Feature Importance explainer. + + Configures the regression scoring metric, the number of permutation + repeats per feature and the random seed. + """ + + scoring: schema_field( + enum_field(enum=["r2", "neg_mean_squared_error", "neg_mean_absolute_error"]), + placeholder="r2", + description=MultilingualString( + en=( + "Regression metric used to evaluate how the model's " + "performance changes when a particular feature is shuffled." + ), + es=( + "Métrica de regresión utilizada para evaluar cómo cambia el " + "rendimiento del modelo cuando se baraja una característica." + ), + pt=( + "Métrica de regressão usada para avaliar como o desempenho do " + "modelo muda quando uma característica é embaralhada." + ), + zh="用于评估特定特征被打乱时模型性能变化的回归指标。", + de=( + "Regressionsmetrik zur Bewertung, wie sich die Modellleistung " + "ändert, wenn ein bestimmtes Merkmal permutiert wird." + ), + ), + alias=MultilingualString( + en="Scoring metric", + es="Métrica de evaluación", + pt="Métrica de avaliação", + zh="评分指标", + de="Bewertungsmetrik", + ), + ) # type: ignore + + n_repeats: schema_field( + int_field(ge=1), + placeholder=10, + description=MultilingualString( + en="Number of times to permute a feature.", + es="Número de veces que se permuta una característica.", + pt="Número de vezes que uma característica é permutada.", + zh="对特征进行排列的次数。", + de="Anzahl der Permutationen eines Merkmals.", + ), + alias=MultilingualString( + en="Number of repeats", + es="Número de repeticiones", + pt="Número de repetições", + zh="重复次数", + de="Anzahl der Wiederholungen", + ), + ) # type: ignore + + random_state: schema_field( + int_field(), + placeholder=0, + description=MultilingualString( + en=( + "Seed for the random number generator to control permutations " + "of each feature." + ), + es=( + "Semilla del generador aleatorio para controlar las " + "permutaciones de cada característica." + ), + pt=( + "Semente do gerador de números aleatórios para controlar as " + "permutações de cada característica." + ), + zh="用于控制每个特征排列的随机数生成器种子。", + de=( + "Startwert für den Zufallszahlengenerator zur Steuerung der " + "Permutationen jedes Merkmals." + ), + ), + alias=MultilingualString( + en="Random state", + es="Semilla aleatoria", + pt="Estado aleatório", + zh="随机状态", + de="Zufallszustand", + ), + ) # type: ignore + + max_samples_fraction: schema_field( + float_field(ge=0.0, le=1.0), + placeholder=1.0, + description=MultilingualString( + en=( + "Fraction of samples to draw from the test set to calculate " + "feature importance at each repetition." + ), + es=( + "Fracción de muestras a extraer del conjunto de prueba para " + "calcular la importancia en cada repetición." + ), + pt=( + "Fração de amostras a extrair do conjunto de teste para " + "calcular a importância a cada repetição." + ), + zh="每次重复时从测试集中抽取的样本比例。", + de=( + "Anteil der aus dem Testdatensatz gezogenen Stichproben zur " + "Berechnung der Merkmalswichtigkeit." + ), + ), + alias=MultilingualString( + en="Max samples fraction", + es="Fracción máxima de muestras", + pt="Fração máxima de amostras", + zh="最大样本比例", + de="Maximaler Stichprobenanteil", + ), + ) # type: ignore + + +class RegressionPermutationFeatureImportance(BaseGlobalExplainer): + """Global permutation feature importance for regression models. + + Measures the importance of each feature by randomly shuffling its values + across the test set and recording the resulting decrease in a regression + scoring metric (R2, negative MSE or negative MAE). Repeating the + permutation ``n_repeats`` times yields a mean importance and standard + deviation per feature. The method is model agnostic and computed on held + out data. + + References + ---------- + - [1] Breiman, L. (2001). "Random Forests." Machine Learning, 45(1), 5-32. + - [2] Fisher, A. et al. (2019). "All Models are Wrong, but Many are + Useful." JMLR, 20(177), 1-81. https://arxiv.org/abs/1801.01489 + """ + + COMPATIBLE_COMPONENTS = ["RegressionTask"] + DISPLAY_NAME = MultilingualString( + en="Permutation Feature Importance (regression)", + es="Importancia por Permutación (regresión)", + pt="Importância por Permutação (regressão)", + zh="排列特征重要性(回归)", + de="Permutations-Merkmalswichtigkeit (Regression)", + ) + DESCRIPTION = MultilingualString( + en=( + "Assesses feature importance for regression models by measuring " + "the drop in a regression metric when a feature's values are " + "randomly shuffled." + ), + es=( + "Evalúa la importancia de las características en modelos de " + "regresión midiendo la caída de una métrica de regresión cuando " + "los valores de una característica se barajan aleatoriamente." + ), + pt=( + "Avalia a importância das características em modelos de regressão " + "medindo a queda de uma métrica de regressão quando os valores de " + "uma característica são embaralhados aleatoriamente." + ), + zh="通过测量特征值被随机打乱时回归指标的下降来评估回归模型的特征重要性。", + de=( + "Bewertet die Merkmalswichtigkeit von Regressionsmodellen durch " + "Messung des Abfalls einer Regressionsmetrik, wenn die Werte " + "eines Merkmals zufällig permutiert werden." + ), + ) + COLOR = "#3F51B5" + SCHEMA = RegressionPermutationFeatureImportanceSchema + + def __init__( + self, + model: BaseModel, + scoring: str = "r2", + n_repeats: int = 10, + random_state: int = None, + max_samples_fraction: float = 1.0, + ): + """Initialise the regression permutation feature importance explainer. + + Parameters + ---------- + model : BaseModel + The trained DashAI regression model to be explained. + scoring : str + Regression metric: 'r2', 'neg_mean_squared_error' or + 'neg_mean_absolute_error'. + n_repeats : int + Number of times each feature is permuted. + random_state : int or None + Seed for the random number generator controlling permutations. + max_samples_fraction : float + Fraction of the test set sampled for the calculation. + """ + super().__init__(model) + + from sklearn.metrics import mean_absolute_error, mean_squared_error, r2_score + + metrics = { + "r2": r2_score, + "neg_mean_squared_error": lambda y_true, y_pred: ( + -mean_squared_error(y_true, y_pred) + ), + "neg_mean_absolute_error": lambda y_true, y_pred: ( + -mean_absolute_error(y_true, y_pred) + ), + } + + self.scoring_name = scoring + self.scoring = metrics[scoring] + self.n_repeats = n_repeats + self.random_state = random_state + self.max_samples_fraction = max_samples_fraction + + def explain(self, dataset): + """Compute permutation feature importance on the test split. + + Parameters + ---------- + dataset : Tuple[DatasetDict, DatasetDict] + A ``(x, y)`` pair where each element has at least a ``"test"`` + split. + + Returns + ------- + dict + Dictionary with keys ``"features"``, ``"importances_mean"`` and + ``"importances_std"``. + """ + import numpy as np + + x, y = dataset + x_test = x["test"].to_pandas() + y_test = y["test"].to_pandas().to_numpy().ravel() + + rng = np.random.RandomState(self.random_state) + n_samples = max(1, int(len(x_test) * self.max_samples_fraction)) + sample_indexes = rng.choice(len(x_test), size=n_samples, replace=False) + x_sample = x_test.iloc[sample_indexes].reset_index(drop=True) + y_sample = y_test[sample_indexes] + + baseline_score = self.scoring( + y_sample, np.asarray(self.model.predict(x_sample)).ravel() + ) + + results = {"features": [], "importances_mean": [], "importances_std": []} + for column in x_sample.columns: + importances = [] + for _ in range(self.n_repeats): + x_permuted = x_sample.copy() + x_permuted[column] = x_sample[column].to_numpy()[ + rng.permutation(n_samples) + ] + permuted_score = self.scoring( + y_sample, np.asarray(self.model.predict(x_permuted)).ravel() + ) + importances.append(baseline_score - permuted_score) + + results["features"].append(column) + results["importances_mean"].append(float(np.round(np.mean(importances), 3))) + results["importances_std"].append(float(np.round(np.std(importances), 3))) + + return results + + def plot(self, explanation: dict) -> List[Artifact]: + """Create a bar chart of feature importances. + + Parameters + ---------- + explanation : dict + Output of :meth:`explain`. + + Returns + ------- + List[Artifact] + A list with a single plotly artifact holding the importance bar + chart. + """ + import pandas as pd + import plotly.express as px + + data = pd.DataFrame.from_dict(explanation) + data = data.sort_values(by=["importances_mean"], ascending=True) + + fig = px.bar( + data, + x=data["importances_mean"], + y=data["features"], + error_x=data["importances_std"], + ) + fig.update_layout( + xaxis_title=f"Importance ({self.scoring_name})", + yaxis_title=None, + ) + + return [PlotlyArtifact(payload=fig, title="Permutation Feature Importance")] diff --git a/DashAI/back/explainability/explainers/token_ablation.py b/DashAI/back/explainability/explainers/token_ablation.py new file mode 100644 index 000000000..b0f20b488 --- /dev/null +++ b/DashAI/back/explainability/explainers/token_ablation.py @@ -0,0 +1,358 @@ +from typing import List + +from DashAI.back.core.artifacts import Artifact, PlotlyArtifact, TextArtifact +from DashAI.back.core.schema_fields import ( + BaseSchema, + enum_field, + int_field, + schema_field, +) +from DashAI.back.core.utils import MultilingualString +from DashAI.back.explainability.local_explainer import BaseLocalExplainer +from DashAI.back.models.base_model import BaseModel + + +class TokenAblationSchema(BaseSchema): + """Schema for the Token Ablation explainer hyperparameters. + + Configures how many tokens are evaluated per instance and how ablated + tokens are replaced. + """ + + max_tokens: schema_field( + int_field(ge=1, le=256), + placeholder=50, + description=MultilingualString( + en=( + "Maximum number of tokens (whitespace-separated words) " + "evaluated per instance. Texts longer than this are truncated " + "for the analysis to bound the number of model calls." + ), + es=( + "Número máximo de tokens (palabras separadas por espacios) " + "evaluados por instancia. Los textos más largos se truncan " + "para el análisis para limitar las llamadas al modelo." + ), + pt=( + "Número máximo de tokens (palavras separadas por espaços) " + "avaliados por instância. Textos mais longos são truncados " + "para a análise para limitar as chamadas ao modelo." + ), + zh="每个实例评估的最大token数(按空格分词)。超长文本将被截断以限制模型调用次数。", + de=( + "Maximale Anzahl der pro Instanz ausgewerteten Tokens (durch " + "Leerzeichen getrennte Wörter). Längere Texte werden für die " + "Analyse gekürzt, um die Modellaufrufe zu begrenzen." + ), + ), + alias=MultilingualString( + en="Max tokens", + es="Máximo de tokens", + pt="Máximo de tokens", + zh="最大token数", + de="Maximale Tokenanzahl", + ), + ) # type: ignore + + replacement: schema_field( + enum_field(enum=["remove", "unk"]), + placeholder="remove", + description=MultilingualString( + en=( + "How an ablated token is handled: 'remove' deletes it from " + "the text, 'unk' replaces it with the [UNK] placeholder." + ), + es=( + "Cómo se trata un token eliminado: 'remove' lo borra del " + "texto, 'unk' lo reemplaza por el marcador [UNK]." + ), + pt=( + "Como um token removido é tratado: 'remove' o exclui do " + "texto, 'unk' o substitui pelo marcador [UNK]." + ), + zh="被消融token的处理方式:'remove'从文本中删除,'unk'替换为[UNK]占位符。", + de=( + "Behandlung eines entfernten Tokens: 'remove' löscht es aus " + "dem Text, 'unk' ersetzt es durch den Platzhalter [UNK]." + ), + ), + alias=MultilingualString( + en="Replacement strategy", + es="Estrategia de reemplazo", + pt="Estratégia de substituição", + zh="替换策略", + de="Ersetzungsstrategie", + ), + ) # type: ignore + + +class TokenAblation(BaseLocalExplainer): + """Occlusion-based local explainer for text classification. + + For each instance, ablates one token at a time (removing it or replacing + it with an [UNK] placeholder) and measures how much the predicted class + probability drops. Tokens whose removal causes a large drop are the ones + the model relied on for its prediction. The method is model agnostic: it + only queries ``predict``, so it works with any text classifier. + + References + ---------- + - [1] Zeiler, M.D. & Fergus, R. (2014). "Visualizing and Understanding + Convolutional Networks." ECCV 2014. https://arxiv.org/abs/1311.2901 + - [2] Li, J. et al. (2016). "Understanding Neural Networks through + Representation Erasure." https://arxiv.org/abs/1612.08220 + """ + + COMPATIBLE_COMPONENTS = ["TextClassificationTask"] + DISPLAY_NAME = MultilingualString( + en="Token Ablation", + es="Ablación de tokens", + pt="Ablação de tokens", + zh="Token消融", + de="Token-Ablation", + ) + DESCRIPTION = MultilingualString( + en=( + "Measures each word's importance by removing it from the text " + "and recording the drop in the predicted class probability." + ), + es=( + "Mide la importancia de cada palabra eliminándola del texto y " + "registrando la caída en la probabilidad de la clase predicha." + ), + pt=( + "Mede a importância de cada palavra removendo-a do texto e " + "registrando a queda na probabilidade da classe prevista." + ), + zh="通过从文本中删除每个词并记录预测类别概率的下降来衡量词的重要性。", + de=( + "Misst die Wichtigkeit jedes Wortes, indem es aus dem Text " + "entfernt und der Rückgang der vorhergesagten " + "Klassenwahrscheinlichkeit erfasst wird." + ), + ) + COLOR = "#E65100" + SCHEMA = TokenAblationSchema + + def __init__( + self, + model: BaseModel, + max_tokens: int = 50, + replacement: str = "remove", + ) -> None: + """Initialize a new instance of a TokenAblation explainer. + + Parameters + ---------- + model : BaseModel + Text classification model to be explained. + max_tokens : int + Maximum number of tokens evaluated per instance. + replacement : str + 'remove' to delete the token, 'unk' to replace it with [UNK]. + """ + super().__init__(model) + self.max_tokens = max_tokens + self.replacement = replacement + + def fit(self, background_dataset, **kwargs): + """Store class names from the training targets. + + Parameters + ---------- + background_dataset : Tuple[DatasetDict, DatasetDict] + Tuple ``(x, y)`` with the dataset splits. + **kwargs : Any + Ignored; present for interface compatibility. + + Returns + ------- + TokenAblation + The fitted explainer instance (``self``). + """ + _, y = background_dataset + y_train = y["train"] + + output_column = y_train.column_names[0] + target_names = y_train.types[output_column].categories + self.metadata = {"target_names": list(target_names)} + + return self + + def _ablate(self, tokens, index): + """Build the text variant with the token at ``index`` ablated. + + Parameters + ---------- + tokens : List[str] + Whitespace tokens of the original text. + index : int + Position of the token to ablate. + + Returns + ------- + str + The perturbed text. + """ + if self.replacement == "unk": + variant = tokens.copy() + variant[index] = "[UNK]" + return " ".join(variant) + return " ".join(tokens[:index] + tokens[index + 1 :]) + + def explain_instance(self, instances): + """Compute token importances for each instance. + + Parameters + ---------- + instances : DatasetDict + Instances to be explained; must contain a single text column. + + Returns + ------- + dict + Dictionary with, for each instance, the tokens, their importance + (probability drop when ablated) and the model prediction. + """ + import numpy as np + import pandas as pd + + from DashAI.back.dataloaders.classes.dashai_dataset import to_dashai_dataset + + dataset = to_dashai_dataset(instances) + X = dataset.to_pandas() + + # The job may hand over an already-prepared dataset (e.g. tokenized by + # a transformer model, adding input_ids/attention_mask columns). + # Rebuild a clean single-text-column dataset so that model.predict can + # run its own preparation from raw text. + tokenizer_columns = {"input_ids", "attention_mask", "token_type_ids", "label"} + text_columns = [c for c in X.columns if c not in tokenizer_columns] + if not text_columns: + raise ValueError(f"No text column found among columns: {list(X.columns)}") + text_column = text_columns[0] + texts = X[text_column].astype(str).tolist() + + base_dataset = to_dashai_dataset(pd.DataFrame({text_column: texts})) + base_predictions = np.asarray(self.model.predict(base_dataset)) + + explanation = {"metadata": {**self.metadata, "text_column": text_column}} + for i, text in enumerate(texts): + tokens = str(text).split()[: self.max_tokens] + predicted_class = int(np.argmax(base_predictions[i])) + base_prob = float(base_predictions[i][predicted_class]) + + importances = [] + if tokens: + variants = [self._ablate(tokens, index) for index in range(len(tokens))] + variants_dataset = to_dashai_dataset( + pd.DataFrame({text_column: variants}) + ) + variant_predictions = np.asarray(self.model.predict(variants_dataset)) + importances = [ + float( + np.round(base_prob - variant_predictions[j][predicted_class], 4) + ) + for j in range(len(tokens)) + ] + + explanation[i] = { + "text": str(text), + "tokens": tokens, + "token_importances": importances, + "model_prediction": base_predictions[i].tolist(), + "predicted_class": predicted_class, + } + + return explanation + + def plot(self, explanation: dict) -> List[Artifact]: + """Render each instance as a token importance bar plot plus a summary. + + Parameters + ---------- + explanation : dict + Dictionary with the explanation generated by the explainer. + + Returns + ------- + List[Artifact] + A list of typed artifacts: one plotly and one text artifact per + explained instance. + """ + import numpy as np + import pandas as pd + import plotly.graph_objs as go + + exp = explanation.copy() + metadata = exp.pop("metadata") + target_names = metadata["target_names"] + max_tokens_plotted = 15 + + artifacts = [] + for i in exp: + instance = exp[i] + predicted_class = instance["predicted_class"] + predicted_name = target_names[predicted_class] + predicted_prob = float( + np.round(instance["model_prediction"][predicted_class], 3) + ) + + data = pd.DataFrame( + { + "tokens": [ + f"{token} ({position})" + for position, token in enumerate(instance["tokens"]) + ], + "importances": instance["token_importances"], + } + ) + data["importance_abs"] = data["importances"].abs() + data = data.sort_values(by="importance_abs", ascending=True) + if len(data) > max_tokens_plotted: + data = data.iloc[-max_tokens_plotted:, :] + + colors = [ + "rgb(231,63,116)" if value >= 0 else "rgb(47,138,196)" + for value in data["importances"] + ] + fig = go.Figure( + go.Bar( + x=data["importances"], + y=data["tokens"], + orientation="h", + marker={"color": colors}, + text=data["importances"], + textposition="auto", + ) + ) + fig.update_layout( + title={ + "text": ( + f"Token importance for prediction {predicted_name} " + f"(p={predicted_prob})" + ), + "font": {"size": 14}, + }, + margin={"pad": 20, "l": 100, "r": 60, "t": 60, "b": 40}, + xaxis={"title_text": "Probability drop when token is ablated"}, + yaxis={"showgrid": True}, + ) + + title = f"Instance {int(i) + 1}" + artifacts.append(PlotlyArtifact(payload=fig, title=title)) + + top = data.iloc[::-1].head(3) + top_tokens = ", ".join( + f"'{token}' ({importance:+})" + for token, importance in zip( + top["tokens"].tolist(), top["importances"].tolist(), strict=True + ) + ) + summary = ( + f"The model predicted {predicted_name} (p={predicted_prob}). " + f"Most influential tokens: {top_tokens}." + ) + artifacts.append(TextArtifact(payload=summary, title=title)) + + return artifacts diff --git a/DashAI/back/initial_components.py b/DashAI/back/initial_components.py index 3c26524e7..18ac12d7b 100644 --- a/DashAI/back/initial_components.py +++ b/DashAI/back/initial_components.py @@ -76,11 +76,31 @@ from DashAI.back.dataset_sources.zenodo_dataset_source import ZenodoDatasetSource # Explainers +from DashAI.back.explainability.explainers.contrastive_shap import ContrastiveShap +from DashAI.back.explainability.explainers.dice_counterfactual import ( + DiceCounterfactual, +) +from DashAI.back.explainability.explainers.grad_cam import GradCam from DashAI.back.explainability.explainers.kernel_shap import KernelShap +from DashAI.back.explainability.explainers.lime_text import LimeText +from DashAI.back.explainability.explainers.nearest_counterfactual import ( + NearestCounterfactual, +) +from DashAI.back.explainability.explainers.occlusion_saliency import OcclusionSaliency from DashAI.back.explainability.explainers.partial_dependence import PartialDependence from DashAI.back.explainability.explainers.permutation_feature_importance import ( PermutationFeatureImportance, ) +from DashAI.back.explainability.explainers.regression_kernel_shap import ( + RegressionKernelShap, +) +from DashAI.back.explainability.explainers.regression_partial_dependence import ( + RegressionPartialDependence, +) +from DashAI.back.explainability.explainers.regression_permutation_feature_importance import ( # noqa: E501 + RegressionPermutationFeatureImportance, +) +from DashAI.back.explainability.explainers.token_ablation import TokenAblation # Explorers from DashAI.back.exploration.explorers.box_plot import BoxPlotExplorer @@ -442,9 +462,19 @@ def get_initial_components(): GenerativeJob, PipelineJob, # Explainers + ContrastiveShap, + DiceCounterfactual, + GradCam, KernelShap, + LimeText, + NearestCounterfactual, + OcclusionSaliency, PartialDependence, PermutationFeatureImportance, + RegressionKernelShap, + RegressionPartialDependence, + RegressionPermutationFeatureImportance, + TokenAblation, # Explorers DescribeExplorer, ScatterPlotExplorer, diff --git a/tests/back/explainers/test_image_explainers.py b/tests/back/explainers/test_image_explainers.py new file mode 100644 index 000000000..bed104c2e --- /dev/null +++ b/tests/back/explainers/test_image_explainers.py @@ -0,0 +1,151 @@ +import numpy as np +import pytest +from PIL import Image + +from DashAI.back.explainability.explainers.grad_cam import GradCam +from DashAI.back.explainability.explainers.occlusion_saliency import ( + OcclusionSaliency, +) + +IMAGE_SIZE = 32 + + +class _FakeImageValue: + """Wraps a PIL image behind the DashAI image type interface.""" + + def __init__(self, pil_image): + self._pil_image = pil_image + + def to_pil(self): + return self._pil_image + + +class _FakeImageDataset: + """Minimal stand-in for a DashAIDataset holding one image column.""" + + def __init__(self, images): + self._rows = [{"image": _FakeImageValue(image)} for image in images] + self.features = {"image": None} + + def __len__(self): + return len(self._rows) + + def __getitem__(self, index): + return self._rows[index] + + +class _ConvImageModel: + """Tiny convolutional image classifier exposing the capability contract.""" + + def __init__(self): + import torch + import torch.nn as nn + + torch.manual_seed(0) + self.image_size = IMAGE_SIZE + self.device = torch.device("cpu") + self.idx_to_label = {0: "cat", 1: "dog"} + self.model = nn.Sequential( + nn.Conv2d(3, 4, 3, padding=1), + nn.ReLU(), + nn.AdaptiveAvgPool2d(4), + nn.Flatten(), + nn.Linear(4 * 4 * 4, 2), + ) + + def get_inference_transform(self): + from torchvision import transforms + + return transforms.Compose( + [ + transforms.Lambda(lambda img: img.convert("RGB")), + transforms.Resize((self.image_size, self.image_size)), + transforms.ToTensor(), + ] + ) + + +class _MlpImageModel(_ConvImageModel): + """Image model with no convolutional layers (like MLPImageClassifier).""" + + def __init__(self): + import torch + import torch.nn as nn + + super().__init__() + torch.manual_seed(0) + self.model = nn.Sequential( + nn.Flatten(), + nn.Linear(3 * IMAGE_SIZE * IMAGE_SIZE, 2), + ) + + +@pytest.fixture(name="images") +def images_fixture(): + rng = np.random.RandomState(0) + return [ + Image.fromarray( + rng.randint(0, 255, size=(IMAGE_SIZE, IMAGE_SIZE, 3), dtype=np.uint8) + ) + for _ in range(2) + ] + + +def _assert_image_explanation(explanation, n_instances): + assert explanation["metadata"]["target_names"] == ["cat", "dog"] + instance_keys = [key for key in explanation if key != "metadata"] + assert len(instance_keys) == n_instances + + for key in instance_keys: + instance = explanation[key] + heatmap = np.asarray(instance["heatmap"]) + assert heatmap.shape == (IMAGE_SIZE, IMAGE_SIZE) + assert heatmap.min() >= 0.0 + assert heatmap.max() <= 1.0 + assert np.asarray(instance["image"]).shape == (IMAGE_SIZE, IMAGE_SIZE, 3) + assert instance["predicted_class"] in (0, 1) + assert len(instance["model_prediction"]) == 2 + + +@pytest.mark.parametrize("method", ["gradcam", "gradcam++"]) +def test_grad_cam(images, method): + model = _ConvImageModel() + explainer = GradCam(model, method=method) + explainer.fit((None, None)) + + explanation = explainer.explain_instance(_FakeImageDataset(images)) + _assert_image_explanation(explanation, len(images)) + + artifacts = explainer.plot(explanation) + assert len(artifacts) == 2 * len(images) + assert [a.type for a in artifacts[:2]] == ["plotly", "text"] + + +def test_grad_cam_rejects_non_convolutional_models(images): + explainer = GradCam(_MlpImageModel()) + explainer.fit((None, None)) + + with pytest.raises(ValueError, match="convolutional"): + explainer.explain_instance(_FakeImageDataset(images)) + + +def test_occlusion_saliency(images): + model = _ConvImageModel() + explainer = OcclusionSaliency(model, patch_size=8, stride=8) + explainer.fit((None, None)) + + explanation = explainer.explain_instance(_FakeImageDataset(images)) + _assert_image_explanation(explanation, len(images)) + + artifacts = explainer.plot(explanation) + assert len(artifacts) == 2 * len(images) + assert [a.type for a in artifacts[:2]] == ["plotly", "text"] + + +def test_occlusion_saliency_works_without_conv_layers(images): + # Unlike Grad-CAM, occlusion only needs forward passes. + explainer = OcclusionSaliency(_MlpImageModel(), patch_size=8, stride=8) + explainer.fit((None, None)) + + explanation = explainer.explain_instance(_FakeImageDataset(images)) + _assert_image_explanation(explanation, len(images)) diff --git a/tests/back/explainers/test_lib_explainers.py b/tests/back/explainers/test_lib_explainers.py new file mode 100644 index 000000000..e1f7d684d --- /dev/null +++ b/tests/back/explainers/test_lib_explainers.py @@ -0,0 +1,175 @@ +import copy + +import numpy as np +import pandas as pd +import pyarrow as pa +import pytest + +from DashAI.back.dataloaders.classes.csv_dataloader import CSVDataLoader +from DashAI.back.dataloaders.classes.dashai_dataset import ( + DashAIDataset, + select_columns, + split_dataset, + split_indexes, +) +from DashAI.back.explainability.explainers.dice_counterfactual import ( + DiceCounterfactual, +) +from DashAI.back.explainability.explainers.lime_text import LimeText +from DashAI.back.models.scikit_learn.decision_tree_classifier import ( + DecisionTreeClassifier, +) +from DashAI.back.types.categorical import Categorical +from DashAI.back.types.utils import save_types_in_arrow_metadata +from DashAI.back.types.value_types import Float + +INPUT_COLUMNS = [ + "SepalLengthCm", + "SepalWidthCm", + "PetalLengthCm", + "PetalWidthCm", +] +OUTPUT_COLUMNS = ["Species"] +TARGETS = [ + "Iris-setosa", + "Iris-versicolor", + "Iris-virginica", +] + + +@pytest.fixture(scope="module", name="dataset") +def tabular_dataset_fixture(): + dataset_path = "tests/back/explainers/iris.csv" + dataloader = CSVDataLoader() + + datasetdict = dataloader.load_data( + filepath_or_buffer=dataset_path, + temp_path="tests/back/explainers", + params={ + "separator": ",", + "schema": { + "SepalLengthCm": {"type": "Float", "dtype": "float64"}, + "SepalWidthCm": {"type": "Float", "dtype": "float64"}, + "PetalLengthCm": {"type": "Float", "dtype": "float64"}, + "PetalWidthCm": {"type": "Float", "dtype": "float64"}, + "Species": {"type": "Categorical", "dtype": "string"}, + }, + }, + ) + datasetdict.types = { + "SepalLengthCm": Float(arrow_type=pa.float64()), + "SepalWidthCm": Float(arrow_type=pa.float64()), + "PetalLengthCm": Float(arrow_type=pa.float64()), + "PetalWidthCm": Float(arrow_type=pa.float64()), + "Species": Categorical(values=TARGETS), + } + + new_table = save_types_in_arrow_metadata( + datasetdict.arrow_table, + {col: dtype.to_string() for col, dtype in datasetdict.types.items()}, + ) + + datasetdict = DashAIDataset( + new_table, splits=datasetdict.splits, types=datasetdict.types + ) + + total_rows = datasetdict.num_rows + train_indexes, test_indexes, val_indexes = split_indexes( + total_rows=total_rows, train_size=0.7, test_size=0.1, val_size=0.2 + ) + split_dataset_dict = split_dataset( + datasetdict, + train_indexes=train_indexes, + test_indexes=test_indexes, + val_indexes=val_indexes, + ) + + x, y = select_columns(split_dataset_dict, INPUT_COLUMNS, OUTPUT_COLUMNS) + + y = split_dataset(y) + x = split_dataset(x) + + return x, y + + +@pytest.fixture(scope="module", name="trained_model") +def trained_model(dataset): + x, y = dataset + model = DecisionTreeClassifier( + criterion="gini", + max_depth=3, + min_samples_split=2, + min_samples_leaf=1, + max_features=None, + ) + model.train(x["train"], y["train"]) + + return model + + +def test_dice_counterfactual(trained_model, dataset): + x, _ = dataset + + explainer = DiceCounterfactual(trained_model, total_cfs=2, method="random") + explainer.fit(copy.deepcopy(dataset)) + + instances = x["test"].select(range(2)) + explanation = explainer.explain_instance(instances) + + metadata = explanation["metadata"] + assert metadata["feature_names"] == INPUT_COLUMNS + assert set(metadata["target_names"]) == set(TARGETS) + + instance_keys = [key for key in explanation if key != "metadata"] + assert len(instance_keys) == 2 + + found_any = False + for key in instance_keys: + instance = explanation[key] + assert len(instance["instance_values"]) == len(INPUT_COLUMNS) + assert 0 <= instance["predicted_class"] < len(TARGETS) + for counterfactual in instance["counterfactuals"]: + found_any = True + assert len(counterfactual["values"]) == len(INPUT_COLUMNS) + # A counterfactual must reach a different class. + assert counterfactual["predicted_class"] != instance["predicted_class"] + # DiCE's random search on iris should find counterfactuals. + assert found_any + + artifacts = explainer.plot(explanation) + assert len(artifacts) == 2 * len(instance_keys) + types = {a.type for a in artifacts} + assert types == {"table", "text"} + + +class DummyTextModel: + """Predicts positive when the text contains the word 'good'.""" + + def predict(self, dataset): + frame = dataset.to_pandas() + texts = frame.iloc[:, 0].tolist() + return np.array( + [[0.1, 0.9] if "good" in str(t).split() else [0.9, 0.1] for t in texts] + ) + + +def test_lime_text(): + explainer = LimeText(DummyTextModel(), num_features=5, num_samples=200) + explainer.metadata = {"target_names": ["negative", "positive"]} + + instances = pd.DataFrame({"text": ["this movie was good indeed"]}) + explanation = explainer.explain_instance(instances) + + instance = explanation[0] + assert instance["predicted_class"] == 1 + + word_weights = dict(instance["word_weights"]) + assert "good" in word_weights + # 'good' drives the dummy model towards the positive class. + assert word_weights["good"] > 0 + assert word_weights["good"] == max(word_weights.values()) + + artifacts = explainer.plot(explanation) + assert len(artifacts) == 2 + assert [a.type for a in artifacts] == ["plotly", "text"] + assert "good" in artifacts[1].payload diff --git a/tests/back/explainers/test_new_explainers.py b/tests/back/explainers/test_new_explainers.py new file mode 100644 index 000000000..279a9be2b --- /dev/null +++ b/tests/back/explainers/test_new_explainers.py @@ -0,0 +1,225 @@ +import copy + +import numpy as np +import pyarrow as pa +import pytest + +from DashAI.back.dataloaders.classes.csv_dataloader import CSVDataLoader +from DashAI.back.dataloaders.classes.dashai_dataset import ( + DashAIDataset, + select_columns, + split_dataset, + split_indexes, +) +from DashAI.back.explainability.explainers.contrastive_shap import ContrastiveShap +from DashAI.back.explainability.explainers.nearest_counterfactual import ( + NearestCounterfactual, +) +from DashAI.back.models.scikit_learn.decision_tree_classifier import ( + DecisionTreeClassifier, +) +from DashAI.back.types.categorical import Categorical +from DashAI.back.types.utils import save_types_in_arrow_metadata +from DashAI.back.types.value_types import Float + +INPUT_COLUMNS = [ + "SepalLengthCm", + "SepalWidthCm", + "PetalLengthCm", + "PetalWidthCm", +] +OUTPUT_COLUMNS = ["Species"] +TARGETS = [ + "Iris-setosa", + "Iris-versicolor", + "Iris-virginica", +] + + +@pytest.fixture(scope="module", name="dataset") +def tabular_model_fixture(): + dataset_path = "tests/back/explainers/iris.csv" + dataloader = CSVDataLoader() + + datasetdict = dataloader.load_data( + filepath_or_buffer=dataset_path, + temp_path="tests/back/explainers", + params={ + "separator": ",", + "schema": { + "SepalLengthCm": {"type": "Float", "dtype": "float64"}, + "SepalWidthCm": {"type": "Float", "dtype": "float64"}, + "PetalLengthCm": {"type": "Float", "dtype": "float64"}, + "PetalWidthCm": {"type": "Float", "dtype": "float64"}, + "Species": {"type": "Categorical", "dtype": "string"}, + }, + }, + ) + datasetdict.types = { + "SepalLengthCm": Float(arrow_type=pa.float64()), + "SepalWidthCm": Float(arrow_type=pa.float64()), + "PetalLengthCm": Float(arrow_type=pa.float64()), + "PetalWidthCm": Float(arrow_type=pa.float64()), + "Species": Categorical(values=TARGETS), + } + + new_table = save_types_in_arrow_metadata( + datasetdict.arrow_table, + {col: dtype.to_string() for col, dtype in datasetdict.types.items()}, + ) + + datasetdict = DashAIDataset( + new_table, splits=datasetdict.splits, types=datasetdict.types + ) + + total_rows = datasetdict.num_rows + train_indexes, test_indexes, val_indexes = split_indexes( + total_rows=total_rows, train_size=0.7, test_size=0.1, val_size=0.2 + ) + split_dataset_dict = split_dataset( + datasetdict, + train_indexes=train_indexes, + test_indexes=test_indexes, + val_indexes=val_indexes, + ) + + x, y = select_columns(split_dataset_dict, INPUT_COLUMNS, OUTPUT_COLUMNS) + + y = split_dataset(y) + x = split_dataset(x) + + return x, y + + +@pytest.fixture(scope="module", name="trained_model") +def trained_model(dataset): + x, y = dataset + model = DecisionTreeClassifier( + criterion="gini", + max_depth=3, + min_samples_split=2, + min_samples_leaf=1, + max_features=None, + ) + model.train(x["train"], y["train"]) + + return model + + +def test_nearest_counterfactual(trained_model, dataset): + x, _ = dataset + n_counterfactuals = 2 + + explainer = NearestCounterfactual( + trained_model, n_counterfactuals=n_counterfactuals, distance="l1" + ) + explainer.fit(copy.deepcopy(dataset)) + + instances = x["test"] + explanation = explainer.explain_instance(instances) + + metadata = explanation["metadata"] + assert set(metadata["target_names"]) == set(TARGETS) + assert metadata["feature_names"] == INPUT_COLUMNS + + instance_keys = [key for key in explanation if key != "metadata"] + assert len(instance_keys) == instances.num_rows + + for key in instance_keys: + instance = explanation[key] + assert len(instance["instance_values"]) == len(INPUT_COLUMNS) + assert len(instance["model_prediction"]) == len(TARGETS) + assert len(instance["counterfactuals"]) <= n_counterfactuals + + for counterfactual in instance["counterfactuals"]: + # A counterfactual must be classified differently. + assert counterfactual["predicted_class"] != instance["predicted_class"] + assert counterfactual["distance"] >= 0 + assert len(counterfactual["values"]) == len(INPUT_COLUMNS) + + artifacts = explainer.plot(explanation) + # One table and one text artifact per instance. + assert len(artifacts) == 2 * len(instance_keys) + tables = [a for a in artifacts if a.type == "table"] + texts = [a for a in artifacts if a.type == "text"] + assert len(tables) == len(instance_keys) + assert len(texts) == len(instance_keys) + + first_table = tables[0].payload + # Feature rows plus the predicted class row. + assert len(first_table.rows) == len(INPUT_COLUMNS) + 1 + for cell in first_table.highlight: + assert 0 <= cell.row < len(first_table.rows) + assert 0 <= cell.column < len(first_table.columns) + + +def test_nearest_counterfactual_distance_l2(trained_model, dataset): + x, _ = dataset + + explainer = NearestCounterfactual(trained_model, n_counterfactuals=1, distance="l2") + explainer.fit(copy.deepcopy(dataset)) + + instances = x["test"].select(range(2)) + explanation = explainer.explain_instance(instances) + + instance_keys = [key for key in explanation if key != "metadata"] + assert len(instance_keys) == 2 + for key in instance_keys: + assert len(explanation[key]["counterfactuals"]) == 1 + + +def test_contrastive_shap(trained_model, dataset): + x, _ = dataset + + explainer = ContrastiveShap(trained_model) + explainer.fit( + copy.deepcopy(dataset), + sample_background_data=True, + background_fraction=0.3, + ) + + instances = x["test"].select(range(3)) + explanation = explainer.explain_instance(instances) + + metadata = explanation["metadata"] + assert set(metadata["target_names"]) == set(TARGETS) + + instance_keys = [key for key in explanation if key != "metadata"] + assert len(instance_keys) == 3 + + for key in instance_keys: + instance = explanation[key] + assert instance["fact_class"] != instance["foil_class"] + assert len(instance["delta_values"]) == len(INPUT_COLUMNS) + + delta = np.asarray(instance["delta_values"]) + fact = np.asarray(instance["fact_shap_values"]) + foil = np.asarray(instance["foil_shap_values"]) + assert np.allclose(delta, fact - foil, atol=1e-2) + + artifacts = explainer.plot(explanation) + assert len(artifacts) == 2 * len(instance_keys) + assert [a.type for a in artifacts[:2]] == ["plotly", "text"] + assert "rather than" in artifacts[1].payload + + +def test_contrastive_shap_fixed_foil(trained_model, dataset): + x, _ = dataset + + explainer = ContrastiveShap(trained_model, foil_class="Iris-virginica") + explainer.fit(copy.deepcopy(dataset)) + + instances = x["test"].select(range(2)) + explanation = explainer.explain_instance(instances) + + target_names = explanation["metadata"]["target_names"] + virginica = target_names.index("Iris-virginica") + + instance_keys = [key for key in explanation if key != "metadata"] + for key in instance_keys: + instance = explanation[key] + if instance["fact_class"] != virginica: + assert instance["foil_class"] == virginica + else: + # Fixed foil equals the fact: falls back to the runner-up class. + assert instance["foil_class"] != virginica diff --git a/tests/back/explainers/test_task_explainers.py b/tests/back/explainers/test_task_explainers.py new file mode 100644 index 000000000..5722beb9a --- /dev/null +++ b/tests/back/explainers/test_task_explainers.py @@ -0,0 +1,306 @@ +import copy + +import numpy as np +import pandas as pd +import pyarrow as pa +import pytest + +from DashAI.back.dataloaders.classes.csv_dataloader import CSVDataLoader +from DashAI.back.dataloaders.classes.dashai_dataset import ( + DashAIDataset, + select_columns, + split_dataset, + split_indexes, +) +from DashAI.back.explainability.explainers.regression_kernel_shap import ( + RegressionKernelShap, +) +from DashAI.back.explainability.explainers.regression_partial_dependence import ( + RegressionPartialDependence, +) +from DashAI.back.explainability.explainers.regression_permutation_feature_importance import ( # noqa: E501 + RegressionPermutationFeatureImportance, +) +from DashAI.back.explainability.explainers.token_ablation import TokenAblation +from DashAI.back.models.scikit_learn.linear_regression import LinearRegression +from DashAI.back.types.categorical import Categorical +from DashAI.back.types.utils import save_types_in_arrow_metadata +from DashAI.back.types.value_types import Float + +REGRESSION_INPUT_COLUMNS = [ + "SepalLengthCm", + "SepalWidthCm", + "PetalLengthCm", +] +REGRESSION_OUTPUT_COLUMNS = ["PetalWidthCm"] + + +@pytest.fixture(scope="module", name="regression_dataset") +def regression_dataset_fixture(): + dataset_path = "tests/back/explainers/iris.csv" + dataloader = CSVDataLoader() + + datasetdict = dataloader.load_data( + filepath_or_buffer=dataset_path, + temp_path="tests/back/explainers", + params={ + "separator": ",", + "schema": { + "SepalLengthCm": {"type": "Float", "dtype": "float64"}, + "SepalWidthCm": {"type": "Float", "dtype": "float64"}, + "PetalLengthCm": {"type": "Float", "dtype": "float64"}, + "PetalWidthCm": {"type": "Float", "dtype": "float64"}, + "Species": {"type": "Categorical", "dtype": "string"}, + }, + }, + ) + datasetdict.types = { + "SepalLengthCm": Float(arrow_type=pa.float64()), + "SepalWidthCm": Float(arrow_type=pa.float64()), + "PetalLengthCm": Float(arrow_type=pa.float64()), + "PetalWidthCm": Float(arrow_type=pa.float64()), + "Species": Categorical( + values=["Iris-setosa", "Iris-versicolor", "Iris-virginica"] + ), + } + + new_table = save_types_in_arrow_metadata( + datasetdict.arrow_table, + {col: dtype.to_string() for col, dtype in datasetdict.types.items()}, + ) + + datasetdict = DashAIDataset( + new_table, splits=datasetdict.splits, types=datasetdict.types + ) + + total_rows = datasetdict.num_rows + train_indexes, test_indexes, val_indexes = split_indexes( + total_rows=total_rows, train_size=0.7, test_size=0.1, val_size=0.2 + ) + split_dataset_dict = split_dataset( + datasetdict, + train_indexes=train_indexes, + test_indexes=test_indexes, + val_indexes=val_indexes, + ) + + x, y = select_columns( + split_dataset_dict, REGRESSION_INPUT_COLUMNS, REGRESSION_OUTPUT_COLUMNS + ) + + y = split_dataset(y) + x = split_dataset(x) + + return x, y + + +@pytest.fixture(scope="module", name="trained_regressor") +def trained_regressor(regression_dataset): + x, y = regression_dataset + model = LinearRegression(fit_intercept=True) + model.train(x["train"], y["train"]) + + return model + + +def test_regression_permutation_feature_importance( + trained_regressor, regression_dataset +): + explainer = RegressionPermutationFeatureImportance( + trained_regressor, + scoring="r2", + n_repeats=5, + random_state=0, + max_samples_fraction=1.0, + ) + explanation = explainer.explain(copy.deepcopy(regression_dataset)) + + assert explanation["features"] == REGRESSION_INPUT_COLUMNS + assert len(explanation["importances_mean"]) == len(REGRESSION_INPUT_COLUMNS) + assert len(explanation["importances_std"]) == len(REGRESSION_INPUT_COLUMNS) + # PetalLengthCm is highly correlated with PetalWidthCm: its importance + # must be positive. + petal_length = explanation["features"].index("PetalLengthCm") + assert explanation["importances_mean"][petal_length] > 0 + + artifacts = explainer.plot(explanation) + assert len(artifacts) == 1 + assert artifacts[0].type == "plotly" + assert artifacts[0].title == "Permutation Feature Importance" + + +@pytest.mark.parametrize( + "scoring", ["neg_mean_squared_error", "neg_mean_absolute_error"] +) +def test_regression_pfi_other_scorings(trained_regressor, regression_dataset, scoring): + explainer = RegressionPermutationFeatureImportance( + trained_regressor, scoring=scoring, n_repeats=3, random_state=0 + ) + explanation = explainer.explain(copy.deepcopy(regression_dataset)) + assert len(explanation["importances_mean"]) == len(REGRESSION_INPUT_COLUMNS) + + +def test_regression_kernel_shap(trained_regressor, regression_dataset): + x, _ = regression_dataset + + explainer = RegressionKernelShap(trained_regressor) + explainer.fit( + copy.deepcopy(regression_dataset), + sample_background_data=True, + background_fraction=0.3, + ) + + instances = x["test"].select(range(3)) + explanation = explainer.explain_instance(instances) + + assert explanation["metadata"]["feature_names"] == REGRESSION_INPUT_COLUMNS + assert explanation["metadata"]["output_column"] == "PetalWidthCm" + + base_value = explanation["base_value"] + instance_keys = [ + key for key in explanation if key not in ("metadata", "base_value") + ] + assert len(instance_keys) == 3 + + for key in instance_keys: + instance = explanation[key] + assert len(instance["shap_values"]) == len(REGRESSION_INPUT_COLUMNS) + # SHAP values are additive: base + contributions ~= prediction. + reconstructed = base_value + sum(instance["shap_values"]) + assert reconstructed == pytest.approx(instance["model_prediction"], abs=0.05) + + artifacts = explainer.plot(explanation) + assert len(artifacts) == 2 * len(instance_keys) + assert [a.type for a in artifacts[:2]] == ["plotly", "text"] + assert "baseline" in artifacts[1].payload + + +def test_regression_partial_dependence(trained_regressor, regression_dataset): + explainer = RegressionPartialDependence( + trained_regressor, + grid_resolution=10, + lower_percentile=0.05, + upper_percentile=0.95, + ) + explanation = explainer.explain(copy.deepcopy(regression_dataset)) + + assert explanation["metadata"]["output_column"] == "PetalWidthCm" + for feature in REGRESSION_INPUT_COLUMNS: + assert len(explanation[feature]["grid_values"]) == 10 + assert len(explanation[feature]["average"]) == 10 + grid = explanation[feature]["grid_values"] + assert grid == sorted(grid) + + # PetalLengthCm drives PetalWidthCm: its PDP curve must not be flat. + petal_curve = explanation["PetalLengthCm"]["average"] + assert max(petal_curve) - min(petal_curve) > 0.1 + + artifacts = explainer.plot(explanation) + assert len(artifacts) == len(REGRESSION_INPUT_COLUMNS) + assert all(a.type == "plotly" for a in artifacts) + assert artifacts[0].title in REGRESSION_INPUT_COLUMNS + + +def test_regression_pdp_invalid_percentiles(trained_regressor): + with pytest.raises(AssertionError): + RegressionPartialDependence( + trained_regressor, lower_percentile=0.9, upper_percentile=0.1 + ) + + +class DummyTextModel: + """Predicts positive when the text contains the word 'good'. + + Mimics the transformer models' strictness: predict raises if the dataset + has more than one text column (see ``tokenize_data`` in + ``base_text_classification_transformer``). + """ + + def predict(self, dataset): + frame = dataset.to_pandas() + text_columns = [col for col in frame.columns if col != "label"] + if len(text_columns) != 1: + raise ValueError(f"Expected exactly one text column, found: {text_columns}") + texts = frame[text_columns[0]].tolist() + return np.array( + [[0.1, 0.9] if "good" in str(t).split() else [0.9, 0.1] for t in texts] + ) + + +class _FakeTargetSplit: + """Minimal stand-in for a DashAIDataset target split.""" + + column_names = ["label"] + types = {"label": Categorical(values=["negative", "positive"])} + + +def test_token_ablation_fit_reads_target_names(): + explainer = TokenAblation(DummyTextModel()) + explainer.fit((None, {"train": _FakeTargetSplit()})) + assert explainer.metadata["target_names"] == ["negative", "positive"] + + +def test_token_ablation_explains_influential_tokens(): + explainer = TokenAblation(DummyTextModel(), max_tokens=20, replacement="remove") + explainer.metadata = {"target_names": ["negative", "positive"]} + + instances = pd.DataFrame( + {"text": ["this movie was good indeed", "terrible boring plot"]} + ) + explanation = explainer.explain_instance(instances) + + first = explanation[0] + assert first["predicted_class"] == 1 + tokens = first["tokens"] + importances = first["token_importances"] + assert len(tokens) == len(importances) + + # Removing 'good' flips the dummy model: it must be the top token. + good_importance = importances[tokens.index("good")] + assert good_importance == pytest.approx(0.8, abs=1e-6) + assert all(importance <= good_importance for importance in importances) + + second = explanation[1] + assert second["predicted_class"] == 0 + # No single token changes the dummy model's negative prediction. + assert all( + importance == pytest.approx(0.0, abs=1e-6) + for importance in second["token_importances"] + ) + + artifacts = explainer.plot(explanation) + assert len(artifacts) == 4 + assert [a.type for a in artifacts[:2]] == ["plotly", "text"] + assert "good" in artifacts[1].payload + + +def test_token_ablation_ignores_tokenizer_columns(): + # The explainer job hands over datasets already prepared by the model; + # transformer models add input_ids/attention_mask columns. The explainer + # must rebuild a clean single-text-column dataset before predicting. + explainer = TokenAblation(DummyTextModel(), max_tokens=10) + explainer.metadata = {"target_names": ["negative", "positive"]} + + instances = pd.DataFrame( + { + "text": ["good stuff", "bad stuff"], + "input_ids": [[101, 102], [101, 103]], + "attention_mask": [[1, 1], [1, 1]], + } + ) + explanation = explainer.explain_instance(instances) + + assert explanation["metadata"]["text_column"] == "text" + assert explanation[0]["predicted_class"] == 1 + assert explanation[1]["predicted_class"] == 0 + + +def test_token_ablation_unk_replacement(): + explainer = TokenAblation(DummyTextModel(), max_tokens=10, replacement="unk") + explainer.metadata = {"target_names": ["negative", "positive"]} + + instances = pd.DataFrame({"text": ["good"]}) + explanation = explainer.explain_instance(instances) + + # Single token replaced by [UNK]: prediction flips, importance 0.8. + assert explanation[0]["token_importances"] == [pytest.approx(0.8, abs=1e-6)] diff --git a/tests/back/registries/test_registry.py b/tests/back/registries/test_registry.py index 51e7bae3e..d66214eb7 100644 --- a/tests/back/registries/test_registry.py +++ b/tests/back/registries/test_registry.py @@ -497,6 +497,22 @@ def test_relationships_module(): ] +def test_get_related_components_skips_unregistered_names(): + test_registry = ComponentRegistry(initial_components=[Component1]) + + # RelatedComponent2 declares Component1 (registered) and Component2 + # (NOT registered): lookups must skip the unregistered name. + test_registry.register_component(RelatedComponent2) + + assert test_registry.get_related_components("RelatedComponent2") == [ + COMPONENT1_DICT + ] + assert [ + component["name"] + for component in test_registry.get_related_components("Component1") + ] == ["RelatedComponent2"] + + def test_compatible_components_merge_across_bases(): test_registry = ComponentRegistry( initial_components=[ From eda5755f9ca31f88201f2883ea2ed3bae48aea27 Mon Sep 17 00:00:00 2001 From: Irozuku Date: Mon, 13 Jul 2026 15:55:49 -0400 Subject: [PATCH 3/8] feat: declare image explainers on torch image models --- .../explainers/image_explainer_utils.py | 43 +++++++++++++------ .../base_torchvision_image_classifier.py | 2 +- DashAI/back/models/cnn_image_classifier.py | 2 +- DashAI/back/models/lenet5_image_classifier.py | 2 +- DashAI/back/models/mlp_image_classifier.py | 2 +- .../back/explainers/test_image_explainers.py | 11 ----- 6 files changed, 34 insertions(+), 28 deletions(-) diff --git a/DashAI/back/explainability/explainers/image_explainer_utils.py b/DashAI/back/explainability/explainers/image_explainer_utils.py index 31e645d7b..3f48466b4 100644 --- a/DashAI/back/explainability/explainers/image_explainer_utils.py +++ b/DashAI/back/explainability/explainers/image_explainer_utils.py @@ -1,13 +1,15 @@ """Shared helpers for image-classification explainers. These helpers define the (minimal) white-box capability contract image -explainers rely on: +explainers rely on; models expose no explainability-specific methods, +only their existing public state: - ``model.model`` is the underlying ``torch.nn.Module``. -- ``model.get_inference_transform()`` returns the exact transform the model - applies to input images (all DashAI image classifiers expose it). - ``model.image_size`` (int) is the model's input resolution. - ``model.idx_to_label`` maps class indices to label names. + +The inference transform is reconstructed on the explainer side by +:func:`get_transform` from that public state. """ from typing import Any, List @@ -45,7 +47,13 @@ def get_torch_module(model: Any): def get_transform(model: Any): - """Return the model's inference transform, with a plain fallback. + """Build the model's inference transform from its public state. + + Preprocessing knowledge lives on the explainer side so models carry no + explainability responsibilities. The transform replicates what each + model family applies internally when predicting: torchvision-backbone + classifiers add the ImageNet normalization; every other image model + gets a plain resize plus tensor conversion based on ``image_size``. Parameters ---------- @@ -57,20 +65,29 @@ def get_transform(model: Any): Callable A transform mapping a PIL image to a normalized tensor. """ - if hasattr(model, "get_inference_transform"): - return model.get_inference_transform() - from torchvision import transforms image_size = int(getattr(model, "image_size", 224)) - return transforms.Compose( - [ - transforms.Lambda(lambda img: img.convert("RGB")), - transforms.Resize((image_size, image_size)), - transforms.ToTensor(), - ] + steps = [ + transforms.Lambda(lambda img: img.convert("RGB")), + transforms.Resize((image_size, image_size)), + transforms.ToTensor(), + ] + + from DashAI.back.models.base_torchvision_image_classifier import ( + TorchvisionImageClassifier, ) + if isinstance(model, TorchvisionImageClassifier): + steps.append( + transforms.Normalize( + mean=[0.485, 0.456, 0.406], + std=[0.229, 0.224, 0.225], + ) + ) + + return transforms.Compose(steps) + def get_target_names(model: Any, y_dataset) -> List[str]: """Resolve class names in the model's class-index order. diff --git a/DashAI/back/models/base_torchvision_image_classifier.py b/DashAI/back/models/base_torchvision_image_classifier.py index be18391d7..e4fbf56be 100644 --- a/DashAI/back/models/base_torchvision_image_classifier.py +++ b/DashAI/back/models/base_torchvision_image_classifier.py @@ -347,7 +347,7 @@ class TorchvisionImageClassifier(BaseModel, abc.ABC): """ SCHEMA = TorchvisionImageClassifierSchema - COMPATIBLE_COMPONENTS = ["ImageClassificationTask"] + COMPATIBLE_COMPONENTS = ["ImageClassificationTask", "GradCam", "OcclusionSaliency"] @abc.abstractmethod def _build_backbone(self, num_classes: int, pretrained: bool): diff --git a/DashAI/back/models/cnn_image_classifier.py b/DashAI/back/models/cnn_image_classifier.py index 606a5ec71..a13db88d8 100644 --- a/DashAI/back/models/cnn_image_classifier.py +++ b/DashAI/back/models/cnn_image_classifier.py @@ -411,7 +411,7 @@ class CNNImageClassifier(BaseModel): """ SCHEMA = CNNImageClassifierSchema - COMPATIBLE_COMPONENTS = ["ImageClassificationTask"] + COMPATIBLE_COMPONENTS = ["ImageClassificationTask", "GradCam", "OcclusionSaliency"] DISPLAY_NAME: str = MultilingualString( en="CNN Image Classifier", es="Clasificador de Imágenes CNN", diff --git a/DashAI/back/models/lenet5_image_classifier.py b/DashAI/back/models/lenet5_image_classifier.py index abd50387a..2b8fba34a 100644 --- a/DashAI/back/models/lenet5_image_classifier.py +++ b/DashAI/back/models/lenet5_image_classifier.py @@ -327,7 +327,7 @@ class LeNet5ImageClassifier(BaseModel): """ SCHEMA = LeNet5ImageClassifierSchema - COMPATIBLE_COMPONENTS = ["ImageClassificationTask"] + COMPATIBLE_COMPONENTS = ["ImageClassificationTask", "GradCam", "OcclusionSaliency"] DISPLAY_NAME: str = MultilingualString( en="LeNet-5", es="LeNet-5", diff --git a/DashAI/back/models/mlp_image_classifier.py b/DashAI/back/models/mlp_image_classifier.py index 12293361d..4b5418eaa 100644 --- a/DashAI/back/models/mlp_image_classifier.py +++ b/DashAI/back/models/mlp_image_classifier.py @@ -358,7 +358,7 @@ class MLPImageClassifier(BaseModel): """ SCHEMA = MLPImageClassifierSchema - COMPATIBLE_COMPONENTS = ["ImageClassificationTask"] + COMPATIBLE_COMPONENTS = ["ImageClassificationTask", "OcclusionSaliency"] DISPLAY_NAME: str = MultilingualString( en="MLP Image Classifier", es="Clasificador de Imágenes MLP", diff --git a/tests/back/explainers/test_image_explainers.py b/tests/back/explainers/test_image_explainers.py index bed104c2e..d41080c13 100644 --- a/tests/back/explainers/test_image_explainers.py +++ b/tests/back/explainers/test_image_explainers.py @@ -53,17 +53,6 @@ def __init__(self): nn.Linear(4 * 4 * 4, 2), ) - def get_inference_transform(self): - from torchvision import transforms - - return transforms.Compose( - [ - transforms.Lambda(lambda img: img.convert("RGB")), - transforms.Resize((self.image_size, self.image_size)), - transforms.ToTensor(), - ] - ) - class _MlpImageModel(_ConvImageModel): """Image model with no convolutional layers (like MLPImageClassifier).""" From d06f9509476082f878ee54c9202d7d3559a21a9a Mon Sep 17 00:00:00 2001 From: Irozuku Date: Mon, 13 Jul 2026 16:28:44 -0400 Subject: [PATCH 4/8] fix: correct formatting in docstrings and comments --- .../explainability/explainers/image_explainer_utils.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/DashAI/back/explainability/explainers/image_explainer_utils.py b/DashAI/back/explainability/explainers/image_explainer_utils.py index 3f48466b4..bf8581d07 100644 --- a/DashAI/back/explainability/explainers/image_explainer_utils.py +++ b/DashAI/back/explainability/explainers/image_explainer_utils.py @@ -1,7 +1,7 @@ """Shared helpers for image-classification explainers. -These helpers define the (minimal) white-box capability contract image -explainers rely on; models expose no explainability-specific methods, +These helpers define the (minimal) white box capability contract image +explainers rely on; models expose no explainability specific methods, only their existing public state: - ``model.model`` is the underlying ``torch.nn.Module``. @@ -147,9 +147,9 @@ def heatmap_overlay_artifact( Parameters ---------- - image_uint8 : array-like + image_uint8 : array like RGB image of shape (H, W, 3), uint8 values. - heatmap : array-like + heatmap : array like Saliency map of shape (H, W) with values in [0, 1]. title : str Artifact title (shown in the instance selector). @@ -167,7 +167,7 @@ def heatmap_overlay_artifact( image = np.asarray(image_uint8, dtype=np.float32) / 255.0 cam = np.clip(np.asarray(heatmap, dtype=np.float32), 0.0, 1.0) - # Jet-like colormap, avoids a matplotlib/cv2 dependency at plot time. + # Jet like colormap, avoids a matplotlib/cv2 dependency at plot time. red = np.clip(1.5 - np.abs(4 * cam - 3), 0, 1) green = np.clip(1.5 - np.abs(4 * cam - 2), 0, 1) blue = np.clip(1.5 - np.abs(4 * cam - 1), 0, 1) From e5f709893a6f2e0d761d2e920cf0bfb1704c56dc Mon Sep 17 00:00:00 2001 From: Irozuku Date: Mon, 13 Jul 2026 17:16:51 -0400 Subject: [PATCH 5/8] feat: enforce image explainer support via model mixins --- .../explainers/image_explainer_utils.py | 54 ++++++++----------- .../base_torchvision_image_classifier.py | 28 +++++++++- DashAI/back/models/cnn_image_classifier.py | 25 ++++++++- DashAI/back/models/image_explainable_model.py | 43 +++++++++++++++ DashAI/back/models/lenet5_image_classifier.py | 25 ++++++++- DashAI/back/models/mlp_image_classifier.py | 25 ++++++++- .../scikit_learn/sklearn_like_classifier.py | 10 +++- .../back/explainers/test_image_explainers.py | 14 ++++- 8 files changed, 180 insertions(+), 44 deletions(-) create mode 100644 DashAI/back/models/image_explainable_model.py diff --git a/DashAI/back/explainability/explainers/image_explainer_utils.py b/DashAI/back/explainability/explainers/image_explainer_utils.py index bf8581d07..bba338cd4 100644 --- a/DashAI/back/explainability/explainers/image_explainer_utils.py +++ b/DashAI/back/explainability/explainers/image_explainer_utils.py @@ -1,15 +1,13 @@ """Shared helpers for image-classification explainers. These helpers define the (minimal) white box capability contract image -explainers rely on; models expose no explainability specific methods, -only their existing public state: +explainers rely on: - ``model.model`` is the underlying ``torch.nn.Module``. -- ``model.image_size`` (int) is the model's input resolution. +- ``model.get_inference_transform()`` returns the exact transform the + model applies to input images (enforced by the image explainable model + mixins in ``DashAI.back.models.image_explainable_model``). - ``model.idx_to_label`` maps class indices to label names. - -The inference transform is reconstructed on the explainer side by -:func:`get_transform` from that public state. """ from typing import Any, List @@ -47,13 +45,12 @@ def get_torch_module(model: Any): def get_transform(model: Any): - """Build the model's inference transform from its public state. + """Return the model's inference transform. - Preprocessing knowledge lives on the explainer side so models carry no - explainability responsibilities. The transform replicates what each - model family applies internally when predicting: torchvision-backbone - classifiers add the ImageNet normalization; every other image model - gets a plain resize plus tensor conversion based on ``image_size``. + Models compatible with image explainers implement + ``get_inference_transform`` (enforced by the + ``OcclusionSaliencyCompatibleModel`` / ``GradCamCompatibleModel`` + mixins), exposing the exact preprocessing they apply to input images. Parameters ---------- @@ -64,29 +61,20 @@ def get_transform(model: Any): ------- Callable A transform mapping a PIL image to a normalized tensor. - """ - from torchvision import transforms - - image_size = int(getattr(model, "image_size", 224)) - steps = [ - transforms.Lambda(lambda img: img.convert("RGB")), - transforms.Resize((image_size, image_size)), - transforms.ToTensor(), - ] - from DashAI.back.models.base_torchvision_image_classifier import ( - TorchvisionImageClassifier, - ) - - if isinstance(model, TorchvisionImageClassifier): - steps.append( - transforms.Normalize( - mean=[0.485, 0.456, 0.406], - std=[0.229, 0.224, 0.225], - ) + Raises + ------ + ValueError + If the model does not implement ``get_inference_transform``. + """ + transform_factory = getattr(model, "get_inference_transform", None) + if transform_factory is None: + raise ValueError( + "This explainer requires a model implementing " + "'get_inference_transform' (see the image explainable model " + f"mixins); got {type(model).__name__}." ) - - return transforms.Compose(steps) + return transform_factory() def get_target_names(model: Any, y_dataset) -> List[str]: diff --git a/DashAI/back/models/base_torchvision_image_classifier.py b/DashAI/back/models/base_torchvision_image_classifier.py index e4fbf56be..700cd5f24 100644 --- a/DashAI/back/models/base_torchvision_image_classifier.py +++ b/DashAI/back/models/base_torchvision_image_classifier.py @@ -14,6 +14,7 @@ ) from DashAI.back.core.utils import MultilingualString from DashAI.back.models.base_model import BaseModel +from DashAI.back.models.image_explainable_model import GradCamCompatibleModel from DashAI.back.models.utils import DEVICE_ENUM, DEVICE_PLACEHOLDER, DEVICE_TO_IDX @@ -337,7 +338,7 @@ def __getitem__(self, idx): return _ImageDataset(x_dataset, y_dataset, image_size) -class TorchvisionImageClassifier(BaseModel, abc.ABC): +class TorchvisionImageClassifier(BaseModel, GradCamCompatibleModel, abc.ABC): """Abstract base for torchvision image classifiers. Subclasses must implement: @@ -347,7 +348,7 @@ class TorchvisionImageClassifier(BaseModel, abc.ABC): """ SCHEMA = TorchvisionImageClassifierSchema - COMPATIBLE_COMPONENTS = ["ImageClassificationTask", "GradCam", "OcclusionSaliency"] + COMPATIBLE_COMPONENTS = ["ImageClassificationTask"] @abc.abstractmethod def _build_backbone(self, num_classes: int, pretrained: bool): @@ -412,6 +413,29 @@ def _freeze_backbone_params(self): for p in self._classifier_head().parameters(): p.requires_grad = True + def get_inference_transform(self): + """Return the transform applied to input images at inference time. + + Returns + ------- + Callable + Resize, tensor conversion and the ImageNet normalization used + by the training pipeline. + """ + from torchvision import transforms + + return transforms.Compose( + [ + transforms.Lambda(lambda img: img.convert("RGB")), + transforms.Resize((self.image_size, self.image_size)), + transforms.ToTensor(), + transforms.Normalize( + mean=[0.485, 0.456, 0.406], + std=[0.229, 0.224, 0.225], + ), + ] + ) + def prepare_output(self, dataset, is_fit=False): """Encode string labels to integer indices matching the model's class order.""" import pyarrow as pa diff --git a/DashAI/back/models/cnn_image_classifier.py b/DashAI/back/models/cnn_image_classifier.py index a13db88d8..acbc81cdb 100644 --- a/DashAI/back/models/cnn_image_classifier.py +++ b/DashAI/back/models/cnn_image_classifier.py @@ -11,6 +11,7 @@ ) from DashAI.back.core.utils import MultilingualString from DashAI.back.models.base_model import BaseModel +from DashAI.back.models.image_explainable_model import GradCamCompatibleModel from DashAI.back.models.utils import DEVICE_ENUM, DEVICE_PLACEHOLDER, DEVICE_TO_IDX @@ -402,7 +403,7 @@ def forward(self, x): ) -class CNNImageClassifier(BaseModel): +class CNNImageClassifier(BaseModel, GradCamCompatibleModel): """CNN-based image classifier. A convolutional neural network with configurable depth and width that @@ -411,7 +412,8 @@ class CNNImageClassifier(BaseModel): """ SCHEMA = CNNImageClassifierSchema - COMPATIBLE_COMPONENTS = ["ImageClassificationTask", "GradCam", "OcclusionSaliency"] + COMPATIBLE_COMPONENTS = ["ImageClassificationTask"] + DISPLAY_NAME: str = MultilingualString( en="CNN Image Classifier", es="Clasificador de Imágenes CNN", @@ -507,6 +509,25 @@ def _validate_architecture(self): f"for {self.num_conv_blocks} convolutional block(s)." ) + def get_inference_transform(self): + """Return the transform applied to input images at inference time. + + Returns + ------- + Callable + Resize and tensor conversion matching the training pipeline + (no normalization). + """ + from torchvision import transforms + + return transforms.Compose( + [ + transforms.Lambda(lambda img: img.convert("RGB")), + transforms.Resize((self.image_size, self.image_size)), + transforms.ToTensor(), + ] + ) + def prepare_output(self, dataset, is_fit=False): """Encode string labels to integer indices matching the model's class order.""" import pyarrow as pa diff --git a/DashAI/back/models/image_explainable_model.py b/DashAI/back/models/image_explainable_model.py new file mode 100644 index 000000000..cd2a7fd7e --- /dev/null +++ b/DashAI/back/models/image_explainable_model.py @@ -0,0 +1,43 @@ +"""Mixins declaring image explainer support on model classes. + +Models that support white-box image explainers inherit one of these mixins +instead of listing the explainers manually: the mixin carries the +``COMPATIBLE_COMPONENTS`` entries (merged with the task entries through the +registry MRO union) and forces the model to implement the inference +transform the explainers need to prepare input tensors. +""" + +from abc import ABC, abstractmethod + + +class OcclusionSaliencyCompatibleModel(ABC): + """Marks a torch image model as compatible with occlusion explainers. + + Any torch image model (convolutional or not) can support perturbation + based explainers such as ``OcclusionSaliency``. Subclasses must expose + the exact preprocessing they apply to input images. + """ + + COMPATIBLE_COMPONENTS = ["OcclusionSaliency"] + + @abstractmethod + def get_inference_transform(self): + """Return the transform applied to input images at inference time. + + Returns + ------- + Callable + A transform mapping a PIL image to the normalized tensor the + model consumes. + """ + raise NotImplementedError + + +class GradCamCompatibleModel(OcclusionSaliencyCompatibleModel, ABC): + """Marks a convolutional torch image model as compatible with Grad-CAM. + + Requires a convolutional backbone (Grad-CAM hooks the last ``Conv2d`` + layer). Implies occlusion saliency support. + """ + + COMPATIBLE_COMPONENTS = ["GradCam"] diff --git a/DashAI/back/models/lenet5_image_classifier.py b/DashAI/back/models/lenet5_image_classifier.py index 2b8fba34a..66011ca03 100644 --- a/DashAI/back/models/lenet5_image_classifier.py +++ b/DashAI/back/models/lenet5_image_classifier.py @@ -11,6 +11,7 @@ ) from DashAI.back.core.utils import MultilingualString from DashAI.back.models.base_model import BaseModel +from DashAI.back.models.image_explainable_model import GradCamCompatibleModel from DashAI.back.models.utils import DEVICE_ENUM, DEVICE_PLACEHOLDER, DEVICE_TO_IDX @@ -318,7 +319,7 @@ def forward(self, x): return _LeNet5(input_channels, input_size, num_classes, dropout_rate) -class LeNet5ImageClassifier(BaseModel): +class LeNet5ImageClassifier(BaseModel, GradCamCompatibleModel): """LeNet-5 image classifier (LeCun et al., 1998). The original convolutional neural network architecture, featuring two @@ -327,7 +328,8 @@ class LeNet5ImageClassifier(BaseModel): """ SCHEMA = LeNet5ImageClassifierSchema - COMPATIBLE_COMPONENTS = ["ImageClassificationTask", "GradCam", "OcclusionSaliency"] + COMPATIBLE_COMPONENTS = ["ImageClassificationTask"] + DISPLAY_NAME: str = MultilingualString( en="LeNet-5", es="LeNet-5", @@ -410,6 +412,25 @@ def __init__( self.idx_to_label = {} self.label_to_idx = {} + def get_inference_transform(self): + """Return the transform applied to input images at inference time. + + Returns + ------- + Callable + Resize and tensor conversion matching the training pipeline + (no normalization). + """ + from torchvision import transforms + + return transforms.Compose( + [ + transforms.Lambda(lambda img: img.convert("RGB")), + transforms.Resize((self.image_size, self.image_size)), + transforms.ToTensor(), + ] + ) + def prepare_output(self, dataset, is_fit=False): """Encode string labels to integer indices matching the model's class order.""" import pyarrow as pa diff --git a/DashAI/back/models/mlp_image_classifier.py b/DashAI/back/models/mlp_image_classifier.py index 4b5418eaa..cc2d32e0a 100644 --- a/DashAI/back/models/mlp_image_classifier.py +++ b/DashAI/back/models/mlp_image_classifier.py @@ -12,6 +12,7 @@ ) from DashAI.back.core.utils import MultilingualString from DashAI.back.models.base_model import BaseModel +from DashAI.back.models.image_explainable_model import OcclusionSaliencyCompatibleModel from DashAI.back.models.utils import DEVICE_ENUM, DEVICE_PLACEHOLDER, DEVICE_TO_IDX @@ -350,7 +351,7 @@ def forward(self, x): return _MLP(input_dim, output_dim, hidden_dims, dropout_rate) -class MLPImageClassifier(BaseModel): +class MLPImageClassifier(BaseModel, OcclusionSaliencyCompatibleModel): """MLP-based image classifier. A feed-forward neural network that flattens image pixels and passes them @@ -358,7 +359,8 @@ class MLPImageClassifier(BaseModel): """ SCHEMA = MLPImageClassifierSchema - COMPATIBLE_COMPONENTS = ["ImageClassificationTask", "OcclusionSaliency"] + COMPATIBLE_COMPONENTS = ["ImageClassificationTask"] + DISPLAY_NAME: str = MultilingualString( en="MLP Image Classifier", es="Clasificador de Imágenes MLP", @@ -445,6 +447,25 @@ def __init__( self.idx_to_label = {} self.label_to_idx = {} + def get_inference_transform(self): + """Return the transform applied to input images at inference time. + + Returns + ------- + Callable + Resize and tensor conversion matching the training pipeline + (no normalization). + """ + from torchvision import transforms + + return transforms.Compose( + [ + transforms.Lambda(lambda img: img.convert("RGB")), + transforms.Resize((self.image_size, self.image_size)), + transforms.ToTensor(), + ] + ) + def prepare_output(self, dataset, is_fit=False): """Encode string labels to integer indices matching the model's class order.""" import pyarrow as pa diff --git a/DashAI/back/models/scikit_learn/sklearn_like_classifier.py b/DashAI/back/models/scikit_learn/sklearn_like_classifier.py index 919f81a57..d6eda8167 100644 --- a/DashAI/back/models/scikit_learn/sklearn_like_classifier.py +++ b/DashAI/back/models/scikit_learn/sklearn_like_classifier.py @@ -9,15 +9,21 @@ class SklearnLikeClassifier(SklearnLikeModel): - """Abstract mixin for scikit-learn-style classification models. + """Abstract mixin for scikit-learn style classification models. Extends ``SklearnLikeModel`` with a ``predict`` method that converts a ``DashAIDataset`` into a NumPy array, calls the wrapped sklearn estimator's - ``predict_proba``, and returns the class-probability matrix. Concrete + ``predict_proba``, and returns the class probability matrix. Concrete classifier wrappers (e.g. ``SVC``, ``RandomForestClassifier``) inherit from this class and from a ``BaseSchema`` subclass. + + Declares the model specific explainers that need sklearn classifier + semantics (``predict_proba``); subclasses inherit them through the + registry's MRO merge of ``COMPATIBLE_COMPONENTS``. """ + COMPATIBLE_COMPONENTS = ["DiceCounterfactual"] + def predict(self, x_pred: "DashAIDataset") -> "ndarray": """Make a prediction with the model diff --git a/tests/back/explainers/test_image_explainers.py b/tests/back/explainers/test_image_explainers.py index d41080c13..692f58130 100644 --- a/tests/back/explainers/test_image_explainers.py +++ b/tests/back/explainers/test_image_explainers.py @@ -6,6 +6,7 @@ from DashAI.back.explainability.explainers.occlusion_saliency import ( OcclusionSaliency, ) +from DashAI.back.models.image_explainable_model import GradCamCompatibleModel IMAGE_SIZE = 32 @@ -34,7 +35,7 @@ def __getitem__(self, index): return self._rows[index] -class _ConvImageModel: +class _ConvImageModel(GradCamCompatibleModel): """Tiny convolutional image classifier exposing the capability contract.""" def __init__(self): @@ -53,6 +54,17 @@ def __init__(self): nn.Linear(4 * 4 * 4, 2), ) + def get_inference_transform(self): + from torchvision import transforms + + return transforms.Compose( + [ + transforms.Lambda(lambda img: img.convert("RGB")), + transforms.Resize((self.image_size, self.image_size)), + transforms.ToTensor(), + ] + ) + class _MlpImageModel(_ConvImageModel): """Image model with no convolutional layers (like MLPImageClassifier).""" From 7044201cd3e497da9df68cd0f3d33a360d5a08f7 Mon Sep 17 00:00:00 2001 From: Irozuku Date: Tue, 14 Jul 2026 10:29:22 -0400 Subject: [PATCH 6/8] fix: install cpu torch in CI to avoid nccl cu12/cu13 clash dice-ml pulls xgboost, which depends on nvidia-nccl-cu12 on linux. Plain uv sync installs the default PyPI torch (CUDA 13 build), whose libtorch_cuda.so needs nvidia-nccl-cu13; with both nccl packages installed the loader resolves the cu12 libnccl.so.2 and torch import fails with undefined symbol ncclCommResume. Sync with --extra cpu as publish.yml already does, and pass --no-sync to uv run so it does not re-sync back to the default (CUDA) torch build. --- .github/workflows/build-test.yaml | 4 ++-- .github/workflows/db-migrations.yaml | 12 ++++++------ 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/.github/workflows/build-test.yaml b/.github/workflows/build-test.yaml index d7d5a0b1c..0af2d908a 100644 --- a/.github/workflows/build-test.yaml +++ b/.github/workflows/build-test.yaml @@ -47,7 +47,7 @@ jobs: enable-cache: true - name: Install dependencies - run: uv sync --locked + run: uv sync --locked --extra cpu - name: Prepare frontend build run: mkdir -p DashAI/front/build @@ -57,4 +57,4 @@ jobs: name: react-build path: DashAI/front/build - name: Test with pytest - run: uv run pytest -v + run: uv run --no-sync pytest -v diff --git a/.github/workflows/db-migrations.yaml b/.github/workflows/db-migrations.yaml index a8449f959..b7f774207 100644 --- a/.github/workflows/db-migrations.yaml +++ b/.github/workflows/db-migrations.yaml @@ -26,7 +26,7 @@ jobs: enable-cache: true - name: Install dependencies - run: uv sync --locked + run: uv sync --locked --extra cpu - name: Set DB env vars run: | @@ -36,7 +36,7 @@ jobs: - name: Show Alembic info run: | - uv run alembic --version + uv run --no-sync alembic --version echo "DB will be at: $DATABASE_URL" - name: Prepare temp dir @@ -47,15 +47,15 @@ jobs: # upgrade to head - name: Upgrade to head run: | - uv run alembic -x url="$DATABASE_URL" upgrade head + uv run --no-sync alembic -x url="$DATABASE_URL" upgrade head # Checks downgrade and upgrade again (reversibility) - name: Downgrade to base and upgrade again (reversibility check) run: | - uv run alembic -x url="$DATABASE_URL" downgrade base - uv run alembic -x url="$DATABASE_URL" upgrade head + uv run --no-sync alembic -x url="$DATABASE_URL" downgrade base + uv run --no-sync alembic -x url="$DATABASE_URL" upgrade head - name: Check for pending autogenerate (python-based) env: PYTHONPATH: "${PYTHONPATH}:." - run: uv run python -m scripts.ci_alembic_check + run: uv run --no-sync python -m scripts.ci_alembic_check From 706f6656e8ae005b625fb22d54d0491bf7905e54 Mon Sep 17 00:00:00 2001 From: Irozuku Date: Tue, 14 Jul 2026 10:40:00 -0400 Subject: [PATCH 7/8] fix: skip llama-cpp-python install in CI The 0.3.32 macos arm64 wheel on the llama-cpp cpu index is a corrupt zip (trailing bytes after end-of-central-directory) and uv refuses to extract it. Tests do not need llama_cpp (all imports are guarded), so exclude it from the CI install instead of pinning around the broken artifact. --- .github/workflows/build-test.yaml | 2 +- .github/workflows/db-migrations.yaml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/build-test.yaml b/.github/workflows/build-test.yaml index 0af2d908a..49af1e1b7 100644 --- a/.github/workflows/build-test.yaml +++ b/.github/workflows/build-test.yaml @@ -47,7 +47,7 @@ jobs: enable-cache: true - name: Install dependencies - run: uv sync --locked --extra cpu + run: uv sync --locked --extra cpu --no-install-package llama-cpp-python - name: Prepare frontend build run: mkdir -p DashAI/front/build diff --git a/.github/workflows/db-migrations.yaml b/.github/workflows/db-migrations.yaml index b7f774207..dac7cf502 100644 --- a/.github/workflows/db-migrations.yaml +++ b/.github/workflows/db-migrations.yaml @@ -26,7 +26,7 @@ jobs: enable-cache: true - name: Install dependencies - run: uv sync --locked --extra cpu + run: uv sync --locked --extra cpu --no-install-package llama-cpp-python - name: Set DB env vars run: | From 011438ef3d159e84b1e047208eff4f9ad98c05b0 Mon Sep 17 00:00:00 2001 From: Irozuku Date: Tue, 14 Jul 2026 11:05:24 -0400 Subject: [PATCH 8/8] fix: require shap>=0.48 for numpy 2.3+ compatibility Python 3.10/3.11 resolved shap 0.46.0 (0.52.0 needs python >= 3.12), which passes abstract dtypes like np.floating to numpy; numpy 2.3 made that a TypeError, breaking the kernel shap and contrastive explainer tests on 3.10/3.11 across all platforms. The floor moves those interpreters to shap 0.49.1. Verified the explainer suite passes on 3.11 with shap 0.49.1 and numpy 2.4.6. --- pyproject.toml | 2 +- uv.lock | 389 +++++++++++++++++++++++++++++-------------------- 2 files changed, 233 insertions(+), 158 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index 612ae1339..0d60fe7d0 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -38,7 +38,7 @@ dependencies = [ "Pillow", "beartype", "plotly", - "shap", + "shap>=0.48", "pymc-bart", # pymc still imports the pre-1.0 arviz API (InferenceData, concat) but its # metadata sets no upper bound, so the resolver must be capped here diff --git a/uv.lock b/uv.lock index b9bea0266..89da68bdf 100644 --- a/uv.lock +++ b/uv.lock @@ -51,8 +51,8 @@ source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "huggingface-hub" }, { name = "numpy", version = "2.2.6", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.11' or (extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda')" }, - { name = "numpy", version = "2.4.6", source = { registry = "https://pypi.org/simple" }, marker = "(python_full_version >= '3.11' and platform_machine != 'x86_64') or (python_full_version == '3.11.*' and platform_machine == 'x86_64' and sys_platform == 'darwin') or (python_full_version < '3.11' and platform_machine != 'x86_64' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (python_full_version != '3.11.*' and platform_machine == 'x86_64' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (python_full_version >= '3.11' and sys_platform != 'darwin') or (sys_platform != 'darwin' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda')" }, - { name = "numpy", version = "2.5.0", source = { registry = "https://pypi.org/simple" }, marker = "(python_full_version >= '3.12' and platform_machine == 'x86_64' and sys_platform == 'darwin') or (python_full_version < '3.12' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (platform_machine != 'x86_64' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (sys_platform != 'darwin' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda')" }, + { name = "numpy", version = "2.4.6", source = { registry = "https://pypi.org/simple" }, marker = "(python_full_version >= '3.12' and python_full_version < '3.15' and platform_machine == 'x86_64' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (python_full_version >= '3.11' and platform_machine != 'x86_64') or (python_full_version == '3.11.*' and platform_machine == 'x86_64' and sys_platform == 'darwin') or (python_full_version >= '3.15' and platform_machine == 'x86_64' and sys_platform == 'darwin') or (python_full_version >= '3.11' and sys_platform != 'darwin') or (python_full_version < '3.11' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (sys_platform != 'darwin' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda')" }, + { name = "numpy", version = "2.5.0", source = { registry = "https://pypi.org/simple" }, marker = "(python_full_version >= '3.12' and python_full_version < '3.15' and platform_machine == 'x86_64' and sys_platform == 'darwin') or (python_full_version < '3.12' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (python_full_version >= '3.15' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (platform_machine != 'x86_64' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (sys_platform != 'darwin' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda')" }, { name = "packaging" }, { name = "psutil" }, { name = "pyyaml" }, @@ -349,8 +349,8 @@ dependencies = [ { name = "matplotlib", version = "3.10.9", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.11' or (extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda')" }, { name = "matplotlib", version = "3.11.0", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.11' or (extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda')" }, { name = "numpy", version = "2.2.6", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.11' or (extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda')" }, - { name = "numpy", version = "2.4.6", source = { registry = "https://pypi.org/simple" }, marker = "(python_full_version >= '3.11' and platform_machine != 'x86_64') or (python_full_version == '3.11.*' and platform_machine == 'x86_64' and sys_platform == 'darwin') or (python_full_version < '3.11' and platform_machine != 'x86_64' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (python_full_version != '3.11.*' and platform_machine == 'x86_64' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (python_full_version >= '3.11' and sys_platform != 'darwin') or (sys_platform != 'darwin' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda')" }, - { name = "numpy", version = "2.5.0", source = { registry = "https://pypi.org/simple" }, marker = "(python_full_version >= '3.12' and platform_machine == 'x86_64' and sys_platform == 'darwin') or (python_full_version < '3.12' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (platform_machine != 'x86_64' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (sys_platform != 'darwin' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda')" }, + { name = "numpy", version = "2.4.6", source = { registry = "https://pypi.org/simple" }, marker = "(python_full_version >= '3.12' and python_full_version < '3.15' and platform_machine == 'x86_64' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (python_full_version >= '3.11' and platform_machine != 'x86_64') or (python_full_version == '3.11.*' and platform_machine == 'x86_64' and sys_platform == 'darwin') or (python_full_version >= '3.15' and platform_machine == 'x86_64' and sys_platform == 'darwin') or (python_full_version >= '3.11' and sys_platform != 'darwin') or (python_full_version < '3.11' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (sys_platform != 'darwin' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda')" }, + { name = "numpy", version = "2.5.0", source = { registry = "https://pypi.org/simple" }, marker = "(python_full_version >= '3.12' and python_full_version < '3.15' and platform_machine == 'x86_64' and sys_platform == 'darwin') or (python_full_version < '3.12' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (python_full_version >= '3.15' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (platform_machine != 'x86_64' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (sys_platform != 'darwin' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda')" }, { name = "packaging" }, { name = "pandas" }, { name = "platformdirs" }, @@ -426,8 +426,8 @@ resolution-markers = [ ] dependencies = [ { name = "lazy-loader", marker = "python_full_version >= '3.12' or (extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda')" }, - { name = "numpy", version = "2.4.6", source = { registry = "https://pypi.org/simple" }, marker = "(python_full_version >= '3.12' and platform_machine != 'x86_64') or (python_full_version < '3.12' and platform_machine != 'x86_64' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (python_full_version >= '3.12' and sys_platform != 'darwin') or (platform_machine == 'x86_64' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (sys_platform != 'darwin' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda')" }, - { name = "numpy", version = "2.5.0", source = { registry = "https://pypi.org/simple" }, marker = "(python_full_version >= '3.12' and platform_machine == 'x86_64' and sys_platform == 'darwin') or (python_full_version < '3.12' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (platform_machine != 'x86_64' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (sys_platform != 'darwin' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda')" }, + { name = "numpy", version = "2.4.6", source = { registry = "https://pypi.org/simple" }, marker = "(python_full_version >= '3.12' and platform_machine != 'x86_64') or (python_full_version >= '3.15' and platform_machine == 'x86_64' and sys_platform == 'darwin') or (python_full_version < '3.12' and platform_machine != 'x86_64' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (python_full_version < '3.15' and platform_machine == 'x86_64' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (python_full_version >= '3.12' and sys_platform != 'darwin') or (sys_platform != 'darwin' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda')" }, + { name = "numpy", version = "2.5.0", source = { registry = "https://pypi.org/simple" }, marker = "(python_full_version >= '3.12' and python_full_version < '3.15' and platform_machine == 'x86_64' and sys_platform == 'darwin') or (python_full_version < '3.12' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (python_full_version >= '3.15' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (platform_machine != 'x86_64' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (sys_platform != 'darwin' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda')" }, { name = "typing-extensions", marker = "python_full_version >= '3.12' or (extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda')" }, { name = "xarray", version = "2026.4.0", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.12' or (extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda')" }, ] @@ -497,8 +497,8 @@ resolution-markers = [ "(python_full_version == '3.12.*' and platform_machine != 'x86_64' and extra != 'extra-6-dashai-cpu' and extra != 'extra-6-dashai-cuda') or (python_full_version == '3.12.*' and sys_platform != 'darwin' and extra != 'extra-6-dashai-cpu' and extra != 'extra-6-dashai-cuda')", ] dependencies = [ - { name = "numpy", version = "2.4.6", source = { registry = "https://pypi.org/simple" }, marker = "(python_full_version >= '3.12' and platform_machine != 'x86_64') or (python_full_version < '3.12' and platform_machine != 'x86_64' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (python_full_version >= '3.12' and sys_platform != 'darwin') or (platform_machine == 'x86_64' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (sys_platform != 'darwin' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda')" }, - { name = "numpy", version = "2.5.0", source = { registry = "https://pypi.org/simple" }, marker = "(python_full_version >= '3.12' and platform_machine == 'x86_64' and sys_platform == 'darwin') or (python_full_version < '3.12' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (platform_machine != 'x86_64' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (sys_platform != 'darwin' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda')" }, + { name = "numpy", version = "2.4.6", source = { registry = "https://pypi.org/simple" }, marker = "(python_full_version >= '3.12' and platform_machine != 'x86_64') or (python_full_version >= '3.15' and platform_machine == 'x86_64' and sys_platform == 'darwin') or (python_full_version < '3.12' and platform_machine != 'x86_64' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (python_full_version < '3.15' and platform_machine == 'x86_64' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (python_full_version >= '3.12' and sys_platform != 'darwin') or (sys_platform != 'darwin' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda')" }, + { name = "numpy", version = "2.5.0", source = { registry = "https://pypi.org/simple" }, marker = "(python_full_version >= '3.12' and python_full_version < '3.15' and platform_machine == 'x86_64' and sys_platform == 'darwin') or (python_full_version < '3.12' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (python_full_version >= '3.15' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (platform_machine != 'x86_64' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (sys_platform != 'darwin' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda')" }, { name = "scipy", version = "1.18.0", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.12' or (extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda')" }, ] sdist = { url = "https://files.pythonhosted.org/packages/4c/97/fd555a4b16ac349f297c786dab1a3270b3540677b0222a84e517441eb338/arviz_stats-1.2.0.tar.gz", hash = "sha256:fc49e6e75f4fce953987a9bf17dc39950e1f12e7cd73f865257e5d1b6a5ee114", size = 157554, upload-time = "2026-06-12T16:20:11.552Z" } @@ -861,8 +861,8 @@ version = "0.13.0" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "numpy", version = "2.2.6", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.11' or (extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda')" }, - { name = "numpy", version = "2.4.6", source = { registry = "https://pypi.org/simple" }, marker = "(python_full_version >= '3.11' and platform_machine != 'x86_64') or (python_full_version == '3.11.*' and platform_machine == 'x86_64' and sys_platform == 'darwin') or (python_full_version < '3.11' and platform_machine != 'x86_64' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (python_full_version != '3.11.*' and platform_machine == 'x86_64' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (python_full_version >= '3.11' and sys_platform != 'darwin') or (sys_platform != 'darwin' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda')" }, - { name = "numpy", version = "2.5.0", source = { registry = "https://pypi.org/simple" }, marker = "(python_full_version >= '3.12' and platform_machine == 'x86_64' and sys_platform == 'darwin') or (python_full_version < '3.12' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (platform_machine != 'x86_64' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (sys_platform != 'darwin' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda')" }, + { name = "numpy", version = "2.4.6", source = { registry = "https://pypi.org/simple" }, marker = "(python_full_version >= '3.12' and python_full_version < '3.15' and platform_machine == 'x86_64' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (python_full_version >= '3.11' and platform_machine != 'x86_64') or (python_full_version == '3.11.*' and platform_machine == 'x86_64' and sys_platform == 'darwin') or (python_full_version >= '3.15' and platform_machine == 'x86_64' and sys_platform == 'darwin') or (python_full_version >= '3.11' and sys_platform != 'darwin') or (python_full_version < '3.11' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (sys_platform != 'darwin' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda')" }, + { name = "numpy", version = "2.5.0", source = { registry = "https://pypi.org/simple" }, marker = "(python_full_version >= '3.12' and python_full_version < '3.15' and platform_machine == 'x86_64' and sys_platform == 'darwin') or (python_full_version < '3.12' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (python_full_version >= '3.15' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (platform_machine != 'x86_64' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (sys_platform != 'darwin' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda')" }, ] sdist = { url = "https://files.pythonhosted.org/packages/3d/9f/ae4edb7dec820e84fef7a90b753ae5c72c66a05ffa69a7894771024386a7/cmaes-0.13.0.tar.gz", hash = "sha256:69a252b0291d08100351e37c2918c7c6d929b02ab7dcd9dd14fc02c7c98cc1b9", size = 61265, upload-time = "2026-03-28T07:41:55.249Z" } wheels = [ @@ -1014,8 +1014,8 @@ resolution-markers = [ "python_full_version == '3.11.*' and extra != 'extra-6-dashai-cpu' and extra != 'extra-6-dashai-cuda'", ] dependencies = [ - { name = "numpy", version = "2.4.6", source = { registry = "https://pypi.org/simple" }, marker = "(python_full_version >= '3.11' and platform_machine != 'x86_64') or (python_full_version == '3.11.*' and platform_machine == 'x86_64' and sys_platform == 'darwin') or (python_full_version < '3.11' and platform_machine != 'x86_64' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (python_full_version != '3.11.*' and platform_machine == 'x86_64' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (python_full_version >= '3.11' and sys_platform != 'darwin') or (sys_platform != 'darwin' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda')" }, - { name = "numpy", version = "2.5.0", source = { registry = "https://pypi.org/simple" }, marker = "(python_full_version >= '3.12' and platform_machine == 'x86_64' and sys_platform == 'darwin') or (python_full_version < '3.12' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (platform_machine != 'x86_64' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (sys_platform != 'darwin' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda')" }, + { name = "numpy", version = "2.4.6", source = { registry = "https://pypi.org/simple" }, marker = "(python_full_version >= '3.12' and python_full_version < '3.15' and platform_machine == 'x86_64' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (python_full_version >= '3.11' and platform_machine != 'x86_64') or (python_full_version == '3.11.*' and platform_machine == 'x86_64' and sys_platform == 'darwin') or (python_full_version >= '3.15' and platform_machine == 'x86_64' and sys_platform == 'darwin') or (python_full_version >= '3.11' and sys_platform != 'darwin') or (python_full_version < '3.11' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (sys_platform != 'darwin' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda')" }, + { name = "numpy", version = "2.5.0", source = { registry = "https://pypi.org/simple" }, marker = "(python_full_version >= '3.12' and python_full_version < '3.15' and platform_machine == 'x86_64' and sys_platform == 'darwin') or (python_full_version < '3.12' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (python_full_version >= '3.15' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (platform_machine != 'x86_64' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (sys_platform != 'darwin' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda')" }, ] sdist = { url = "https://files.pythonhosted.org/packages/58/01/1253e6698a07380cd31a736d248a3f2a50a7c88779a1813da27503cadc2a/contourpy-1.3.3.tar.gz", hash = "sha256:083e12155b210502d0bca491432bb04d56dc3432f95a979b429f2848c3dbe880", size = 13466174, upload-time = "2025-07-26T12:03:12.549Z" } wheels = [ @@ -1102,8 +1102,8 @@ dependencies = [ { name = "huggingface-hub" }, { name = "importlib-metadata" }, { name = "numpy", version = "2.2.6", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.11' or (extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda')" }, - { name = "numpy", version = "2.4.6", source = { registry = "https://pypi.org/simple" }, marker = "(python_full_version >= '3.11' and platform_machine != 'x86_64') or (python_full_version == '3.11.*' and platform_machine == 'x86_64' and sys_platform == 'darwin') or (python_full_version < '3.11' and platform_machine != 'x86_64' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (python_full_version != '3.11.*' and platform_machine == 'x86_64' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (python_full_version >= '3.11' and sys_platform != 'darwin') or (sys_platform != 'darwin' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda')" }, - { name = "numpy", version = "2.5.0", source = { registry = "https://pypi.org/simple" }, marker = "(python_full_version >= '3.12' and platform_machine == 'x86_64' and sys_platform == 'darwin') or (python_full_version < '3.12' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (platform_machine != 'x86_64' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (sys_platform != 'darwin' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda')" }, + { name = "numpy", version = "2.4.6", source = { registry = "https://pypi.org/simple" }, marker = "(python_full_version >= '3.12' and python_full_version < '3.15' and platform_machine == 'x86_64' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (python_full_version >= '3.11' and platform_machine != 'x86_64') or (python_full_version == '3.11.*' and platform_machine == 'x86_64' and sys_platform == 'darwin') or (python_full_version >= '3.15' and platform_machine == 'x86_64' and sys_platform == 'darwin') or (python_full_version >= '3.11' and sys_platform != 'darwin') or (python_full_version < '3.11' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (sys_platform != 'darwin' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda')" }, + { name = "numpy", version = "2.5.0", source = { registry = "https://pypi.org/simple" }, marker = "(python_full_version >= '3.12' and python_full_version < '3.15' and platform_machine == 'x86_64' and sys_platform == 'darwin') or (python_full_version < '3.12' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (python_full_version >= '3.15' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (platform_machine != 'x86_64' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (sys_platform != 'darwin' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda')" }, { name = "opencv-python-headless" }, { name = "pillow" }, { name = "scikit-image", version = "0.25.2", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.11' or (extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda')" }, @@ -1447,12 +1447,13 @@ dependencies = [ { name = "joblib" }, { name = "kink" }, { name = "lime" }, - { name = "llvmlite" }, - { name = "numba", version = "0.47.0", source = { registry = "https://pypi.org/simple" }, marker = "(python_full_version >= '3.12' and platform_machine == 'x86_64' and sys_platform == 'darwin') or (python_full_version < '3.12' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (platform_machine != 'x86_64' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (sys_platform != 'darwin' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda')" }, - { name = "numba", version = "0.66.0", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.12' or platform_machine != 'x86_64' or sys_platform != 'darwin' or (extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda')" }, + { name = "llvmlite", version = "0.45.1", source = { registry = "https://pypi.org/simple" }, marker = "(python_full_version >= '3.12' and python_full_version < '3.15' and platform_machine == 'x86_64' and sys_platform == 'darwin') or (python_full_version < '3.12' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (python_full_version >= '3.15' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (platform_machine != 'x86_64' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (sys_platform != 'darwin' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda')" }, + { name = "llvmlite", version = "0.48.0", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.12' or python_full_version >= '3.15' or platform_machine != 'x86_64' or sys_platform != 'darwin' or (extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda')" }, + { name = "numba", version = "0.47.0", source = { registry = "https://pypi.org/simple" }, marker = "(python_full_version >= '3.12' and python_full_version < '3.15' and platform_machine == 'x86_64' and sys_platform == 'darwin') or (python_full_version < '3.12' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (python_full_version >= '3.15' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (platform_machine != 'x86_64' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (sys_platform != 'darwin' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda')" }, + { name = "numba", version = "0.66.0", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.12' or python_full_version >= '3.15' or platform_machine != 'x86_64' or sys_platform != 'darwin' or (extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda')" }, { name = "numpy", version = "2.2.6", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.11' or (extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda')" }, - { name = "numpy", version = "2.4.6", source = { registry = "https://pypi.org/simple" }, marker = "(python_full_version >= '3.11' and platform_machine != 'x86_64') or (python_full_version == '3.11.*' and platform_machine == 'x86_64' and sys_platform == 'darwin') or (python_full_version < '3.11' and platform_machine != 'x86_64' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (python_full_version != '3.11.*' and platform_machine == 'x86_64' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (python_full_version >= '3.11' and sys_platform != 'darwin') or (sys_platform != 'darwin' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda')" }, - { name = "numpy", version = "2.5.0", source = { registry = "https://pypi.org/simple" }, marker = "(python_full_version >= '3.12' and platform_machine == 'x86_64' and sys_platform == 'darwin') or (python_full_version < '3.12' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (platform_machine != 'x86_64' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (sys_platform != 'darwin' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda')" }, + { name = "numpy", version = "2.4.6", source = { registry = "https://pypi.org/simple" }, marker = "(python_full_version >= '3.12' and python_full_version < '3.15' and platform_machine == 'x86_64' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (python_full_version >= '3.11' and platform_machine != 'x86_64') or (python_full_version == '3.11.*' and platform_machine == 'x86_64' and sys_platform == 'darwin') or (python_full_version >= '3.15' and platform_machine == 'x86_64' and sys_platform == 'darwin') or (python_full_version >= '3.11' and sys_platform != 'darwin') or (python_full_version < '3.11' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (sys_platform != 'darwin' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda')" }, + { name = "numpy", version = "2.5.0", source = { registry = "https://pypi.org/simple" }, marker = "(python_full_version >= '3.12' and python_full_version < '3.15' and platform_machine == 'x86_64' and sys_platform == 'darwin') or (python_full_version < '3.12' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (python_full_version >= '3.15' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (platform_machine != 'x86_64' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (sys_platform != 'darwin' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda')" }, { name = "nvidia-ml-py" }, { name = "opencv-python" }, { name = "openml" }, @@ -1473,8 +1474,8 @@ dependencies = [ { name = "scikit-learn" }, { name = "sentencepiece" }, { name = "setuptools" }, - { name = "shap", version = "0.46.0", source = { registry = "https://pypi.org/simple" }, marker = "(python_full_version < '3.12' and platform_machine != 'x86_64') or (python_full_version < '3.12' and sys_platform != 'darwin') or (platform_machine == 'x86_64' and sys_platform == 'darwin') or (platform_machine != 'x86_64' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (sys_platform != 'darwin' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda')" }, - { name = "shap", version = "0.52.0", source = { registry = "https://pypi.org/simple" }, marker = "(python_full_version >= '3.12' and platform_machine != 'x86_64') or (python_full_version < '3.12' and platform_machine != 'x86_64' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (python_full_version >= '3.12' and sys_platform != 'darwin') or (platform_machine == 'x86_64' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (sys_platform != 'darwin' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda')" }, + { name = "shap", version = "0.49.1", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.12' or (python_full_version >= '3.15' and platform_machine == 'x86_64' and sys_platform == 'darwin') or (python_full_version < '3.15' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (platform_machine != 'x86_64' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (sys_platform != 'darwin' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda')" }, + { name = "shap", version = "0.52.0", source = { registry = "https://pypi.org/simple" }, marker = "(python_full_version >= '3.12' and python_full_version < '3.15') or (python_full_version >= '3.12' and platform_machine != 'x86_64') or (python_full_version >= '3.15' and platform_machine == 'x86_64' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (python_full_version >= '3.12' and sys_platform != 'darwin') or (python_full_version < '3.12' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (sys_platform != 'darwin' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda')" }, { name = "sqlalchemy" }, { name = "starlette" }, { name = "streaming-form-data" }, @@ -1569,7 +1570,7 @@ requires-dist = [ { name = "scikit-learn", specifier = "<1.8.0" }, { name = "sentencepiece" }, { name = "setuptools", specifier = ">=65.0.0,<82" }, - { name = "shap" }, + { name = "shap", specifier = ">=0.48" }, { name = "sqlalchemy" }, { name = "starlette" }, { name = "streaming-form-data" }, @@ -1611,8 +1612,8 @@ dependencies = [ { name = "huggingface-hub" }, { name = "multiprocess" }, { name = "numpy", version = "2.2.6", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.11' or (extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda')" }, - { name = "numpy", version = "2.4.6", source = { registry = "https://pypi.org/simple" }, marker = "(python_full_version >= '3.11' and platform_machine != 'x86_64') or (python_full_version == '3.11.*' and platform_machine == 'x86_64' and sys_platform == 'darwin') or (python_full_version < '3.11' and platform_machine != 'x86_64' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (python_full_version != '3.11.*' and platform_machine == 'x86_64' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (python_full_version >= '3.11' and sys_platform != 'darwin') or (sys_platform != 'darwin' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda')" }, - { name = "numpy", version = "2.5.0", source = { registry = "https://pypi.org/simple" }, marker = "(python_full_version >= '3.12' and platform_machine == 'x86_64' and sys_platform == 'darwin') or (python_full_version < '3.12' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (platform_machine != 'x86_64' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (sys_platform != 'darwin' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda')" }, + { name = "numpy", version = "2.4.6", source = { registry = "https://pypi.org/simple" }, marker = "(python_full_version >= '3.12' and python_full_version < '3.15' and platform_machine == 'x86_64' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (python_full_version >= '3.11' and platform_machine != 'x86_64') or (python_full_version == '3.11.*' and platform_machine == 'x86_64' and sys_platform == 'darwin') or (python_full_version >= '3.15' and platform_machine == 'x86_64' and sys_platform == 'darwin') or (python_full_version >= '3.11' and sys_platform != 'darwin') or (python_full_version < '3.11' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (sys_platform != 'darwin' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda')" }, + { name = "numpy", version = "2.5.0", source = { registry = "https://pypi.org/simple" }, marker = "(python_full_version >= '3.12' and python_full_version < '3.15' and platform_machine == 'x86_64' and sys_platform == 'darwin') or (python_full_version < '3.12' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (python_full_version >= '3.15' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (platform_machine != 'x86_64' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (sys_platform != 'darwin' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda')" }, { name = "packaging" }, { name = "pandas" }, { name = "pyarrow" }, @@ -1655,8 +1656,8 @@ dependencies = [ { name = "jsonschema" }, { name = "lightgbm" }, { name = "numpy", version = "2.2.6", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.11' or (extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda')" }, - { name = "numpy", version = "2.4.6", source = { registry = "https://pypi.org/simple" }, marker = "(python_full_version >= '3.11' and platform_machine != 'x86_64') or (python_full_version == '3.11.*' and platform_machine == 'x86_64' and sys_platform == 'darwin') or (python_full_version < '3.11' and platform_machine != 'x86_64' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (python_full_version != '3.11.*' and platform_machine == 'x86_64' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (python_full_version >= '3.11' and sys_platform != 'darwin') or (sys_platform != 'darwin' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda')" }, - { name = "numpy", version = "2.5.0", source = { registry = "https://pypi.org/simple" }, marker = "(python_full_version >= '3.12' and platform_machine == 'x86_64' and sys_platform == 'darwin') or (python_full_version < '3.12' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (platform_machine != 'x86_64' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (sys_platform != 'darwin' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda')" }, + { name = "numpy", version = "2.4.6", source = { registry = "https://pypi.org/simple" }, marker = "(python_full_version >= '3.12' and python_full_version < '3.15' and platform_machine == 'x86_64' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (python_full_version >= '3.11' and platform_machine != 'x86_64') or (python_full_version == '3.11.*' and platform_machine == 'x86_64' and sys_platform == 'darwin') or (python_full_version >= '3.15' and platform_machine == 'x86_64' and sys_platform == 'darwin') or (python_full_version >= '3.11' and sys_platform != 'darwin') or (python_full_version < '3.11' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (sys_platform != 'darwin' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda')" }, + { name = "numpy", version = "2.5.0", source = { registry = "https://pypi.org/simple" }, marker = "(python_full_version >= '3.12' and python_full_version < '3.15' and platform_machine == 'x86_64' and sys_platform == 'darwin') or (python_full_version < '3.12' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (python_full_version >= '3.15' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (platform_machine != 'x86_64' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (sys_platform != 'darwin' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda')" }, { name = "pandas" }, { name = "raiutils" }, { name = "scikit-learn" }, @@ -1679,8 +1680,8 @@ dependencies = [ { name = "huggingface-hub" }, { name = "importlib-metadata" }, { name = "numpy", version = "2.2.6", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.11' or (extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda')" }, - { name = "numpy", version = "2.4.6", source = { registry = "https://pypi.org/simple" }, marker = "(python_full_version >= '3.11' and platform_machine != 'x86_64') or (python_full_version == '3.11.*' and platform_machine == 'x86_64' and sys_platform == 'darwin') or (python_full_version < '3.11' and platform_machine != 'x86_64' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (python_full_version != '3.11.*' and platform_machine == 'x86_64' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (python_full_version >= '3.11' and sys_platform != 'darwin') or (sys_platform != 'darwin' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda')" }, - { name = "numpy", version = "2.5.0", source = { registry = "https://pypi.org/simple" }, marker = "(python_full_version >= '3.12' and platform_machine == 'x86_64' and sys_platform == 'darwin') or (python_full_version < '3.12' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (platform_machine != 'x86_64' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (sys_platform != 'darwin' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda')" }, + { name = "numpy", version = "2.4.6", source = { registry = "https://pypi.org/simple" }, marker = "(python_full_version >= '3.12' and python_full_version < '3.15' and platform_machine == 'x86_64' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (python_full_version >= '3.11' and platform_machine != 'x86_64') or (python_full_version == '3.11.*' and platform_machine == 'x86_64' and sys_platform == 'darwin') or (python_full_version >= '3.15' and platform_machine == 'x86_64' and sys_platform == 'darwin') or (python_full_version >= '3.11' and sys_platform != 'darwin') or (python_full_version < '3.11' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (sys_platform != 'darwin' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda')" }, + { name = "numpy", version = "2.5.0", source = { registry = "https://pypi.org/simple" }, marker = "(python_full_version >= '3.12' and python_full_version < '3.15' and platform_machine == 'x86_64' and sys_platform == 'darwin') or (python_full_version < '3.12' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (python_full_version >= '3.15' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (platform_machine != 'x86_64' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (sys_platform != 'darwin' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda')" }, { name = "pillow" }, { name = "regex" }, { name = "requests" }, @@ -1840,8 +1841,8 @@ dependencies = [ { name = "huggingface-hub" }, { name = "multiprocess" }, { name = "numpy", version = "2.2.6", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.11' or (extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda')" }, - { name = "numpy", version = "2.4.6", source = { registry = "https://pypi.org/simple" }, marker = "(python_full_version >= '3.11' and platform_machine != 'x86_64') or (python_full_version == '3.11.*' and platform_machine == 'x86_64' and sys_platform == 'darwin') or (python_full_version < '3.11' and platform_machine != 'x86_64' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (python_full_version != '3.11.*' and platform_machine == 'x86_64' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (python_full_version >= '3.11' and sys_platform != 'darwin') or (sys_platform != 'darwin' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda')" }, - { name = "numpy", version = "2.5.0", source = { registry = "https://pypi.org/simple" }, marker = "(python_full_version >= '3.12' and platform_machine == 'x86_64' and sys_platform == 'darwin') or (python_full_version < '3.12' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (platform_machine != 'x86_64' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (sys_platform != 'darwin' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda')" }, + { name = "numpy", version = "2.4.6", source = { registry = "https://pypi.org/simple" }, marker = "(python_full_version >= '3.12' and python_full_version < '3.15' and platform_machine == 'x86_64' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (python_full_version >= '3.11' and platform_machine != 'x86_64') or (python_full_version == '3.11.*' and platform_machine == 'x86_64' and sys_platform == 'darwin') or (python_full_version >= '3.15' and platform_machine == 'x86_64' and sys_platform == 'darwin') or (python_full_version >= '3.11' and sys_platform != 'darwin') or (python_full_version < '3.11' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (sys_platform != 'darwin' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda')" }, + { name = "numpy", version = "2.5.0", source = { registry = "https://pypi.org/simple" }, marker = "(python_full_version >= '3.12' and python_full_version < '3.15' and platform_machine == 'x86_64' and sys_platform == 'darwin') or (python_full_version < '3.12' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (python_full_version >= '3.15' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (platform_machine != 'x86_64' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (sys_platform != 'darwin' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda')" }, { name = "packaging" }, { name = "pandas" }, { name = "requests" }, @@ -2288,8 +2289,8 @@ dependencies = [ { name = "matplotlib", version = "3.10.9", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.11' or (extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda')" }, { name = "matplotlib", version = "3.11.0", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.11' or (extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda')" }, { name = "numpy", version = "2.2.6", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.11' or (extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda')" }, - { name = "numpy", version = "2.4.6", source = { registry = "https://pypi.org/simple" }, marker = "(python_full_version >= '3.11' and platform_machine != 'x86_64') or (python_full_version == '3.11.*' and platform_machine == 'x86_64' and sys_platform == 'darwin') or (python_full_version < '3.11' and platform_machine != 'x86_64' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (python_full_version != '3.11.*' and platform_machine == 'x86_64' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (python_full_version >= '3.11' and sys_platform != 'darwin') or (sys_platform != 'darwin' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda')" }, - { name = "numpy", version = "2.5.0", source = { registry = "https://pypi.org/simple" }, marker = "(python_full_version >= '3.12' and platform_machine == 'x86_64' and sys_platform == 'darwin') or (python_full_version < '3.12' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (platform_machine != 'x86_64' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (sys_platform != 'darwin' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda')" }, + { name = "numpy", version = "2.4.6", source = { registry = "https://pypi.org/simple" }, marker = "(python_full_version >= '3.12' and python_full_version < '3.15' and platform_machine == 'x86_64' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (python_full_version >= '3.11' and platform_machine != 'x86_64') or (python_full_version == '3.11.*' and platform_machine == 'x86_64' and sys_platform == 'darwin') or (python_full_version >= '3.15' and platform_machine == 'x86_64' and sys_platform == 'darwin') or (python_full_version >= '3.11' and sys_platform != 'darwin') or (python_full_version < '3.11' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (sys_platform != 'darwin' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda')" }, + { name = "numpy", version = "2.5.0", source = { registry = "https://pypi.org/simple" }, marker = "(python_full_version >= '3.12' and python_full_version < '3.15' and platform_machine == 'x86_64' and sys_platform == 'darwin') or (python_full_version < '3.12' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (python_full_version >= '3.15' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (platform_machine != 'x86_64' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (sys_platform != 'darwin' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda')" }, { name = "opencv-python" }, { name = "pillow" }, { name = "scikit-learn" }, @@ -2416,8 +2417,8 @@ version = "1.8.1" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "numpy", version = "2.2.6", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.11' or (extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda')" }, - { name = "numpy", version = "2.4.6", source = { registry = "https://pypi.org/simple" }, marker = "(python_full_version >= '3.11' and platform_machine != 'x86_64') or (python_full_version == '3.11.*' and platform_machine == 'x86_64' and sys_platform == 'darwin') or (python_full_version < '3.11' and platform_machine != 'x86_64' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (python_full_version != '3.11.*' and platform_machine == 'x86_64' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (python_full_version >= '3.11' and sys_platform != 'darwin') or (sys_platform != 'darwin' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda')" }, - { name = "numpy", version = "2.5.0", source = { registry = "https://pypi.org/simple" }, marker = "(python_full_version >= '3.12' and platform_machine == 'x86_64' and sys_platform == 'darwin') or (python_full_version < '3.12' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (platform_machine != 'x86_64' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (sys_platform != 'darwin' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda')" }, + { name = "numpy", version = "2.4.6", source = { registry = "https://pypi.org/simple" }, marker = "(python_full_version >= '3.12' and python_full_version < '3.15' and platform_machine == 'x86_64' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (python_full_version >= '3.11' and platform_machine != 'x86_64') or (python_full_version == '3.11.*' and platform_machine == 'x86_64' and sys_platform == 'darwin') or (python_full_version >= '3.15' and platform_machine == 'x86_64' and sys_platform == 'darwin') or (python_full_version >= '3.11' and sys_platform != 'darwin') or (python_full_version < '3.11' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (sys_platform != 'darwin' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda')" }, + { name = "numpy", version = "2.5.0", source = { registry = "https://pypi.org/simple" }, marker = "(python_full_version >= '3.12' and python_full_version < '3.15' and platform_machine == 'x86_64' and sys_platform == 'darwin') or (python_full_version < '3.12' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (python_full_version >= '3.15' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (platform_machine != 'x86_64' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (sys_platform != 'darwin' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda')" }, { name = "packaging" }, ] sdist = { url = "https://files.pythonhosted.org/packages/ef/03/92d6cc02c0055158167255980461155d6e17f1c4143c03f8bcc18d3e3f3a/h5netcdf-1.8.1.tar.gz", hash = "sha256:9b396a4cc346050fc1a4df8523bc1853681ec3544e0449027ae397cb953c7a16", size = 78679, upload-time = "2026-01-23T07:35:31.233Z" } @@ -2431,8 +2432,8 @@ version = "3.16.0" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "numpy", version = "2.2.6", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.11' or (extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda')" }, - { name = "numpy", version = "2.4.6", source = { registry = "https://pypi.org/simple" }, marker = "(python_full_version >= '3.11' and platform_machine != 'x86_64') or (python_full_version == '3.11.*' and platform_machine == 'x86_64' and sys_platform == 'darwin') or (python_full_version < '3.11' and platform_machine != 'x86_64' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (python_full_version != '3.11.*' and platform_machine == 'x86_64' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (python_full_version >= '3.11' and sys_platform != 'darwin') or (sys_platform != 'darwin' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda')" }, - { name = "numpy", version = "2.5.0", source = { registry = "https://pypi.org/simple" }, marker = "(python_full_version >= '3.12' and platform_machine == 'x86_64' and sys_platform == 'darwin') or (python_full_version < '3.12' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (platform_machine != 'x86_64' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (sys_platform != 'darwin' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda')" }, + { name = "numpy", version = "2.4.6", source = { registry = "https://pypi.org/simple" }, marker = "(python_full_version >= '3.12' and python_full_version < '3.15' and platform_machine == 'x86_64' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (python_full_version >= '3.11' and platform_machine != 'x86_64') or (python_full_version == '3.11.*' and platform_machine == 'x86_64' and sys_platform == 'darwin') or (python_full_version >= '3.15' and platform_machine == 'x86_64' and sys_platform == 'darwin') or (python_full_version >= '3.11' and sys_platform != 'darwin') or (python_full_version < '3.11' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (sys_platform != 'darwin' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda')" }, + { name = "numpy", version = "2.5.0", source = { registry = "https://pypi.org/simple" }, marker = "(python_full_version >= '3.12' and python_full_version < '3.15' and platform_machine == 'x86_64' and sys_platform == 'darwin') or (python_full_version < '3.12' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (python_full_version >= '3.15' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (platform_machine != 'x86_64' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (sys_platform != 'darwin' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda')" }, ] sdist = { url = "https://files.pythonhosted.org/packages/db/33/acd0ce6863b6c0d7735007df01815403f5589a21ff8c2e1ee2587a38f548/h5py-3.16.0.tar.gz", hash = "sha256:a0dbaad796840ccaa67a4c144a0d0c8080073c34c76d5a6941d6818678ef2738", size = 446526, upload-time = "2026-03-06T13:49:08.07Z" } wheels = [ @@ -2634,8 +2635,8 @@ dependencies = [ { name = "networkx", version = "3.4.2", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.11' or (extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda')" }, { name = "networkx", version = "3.6.1", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.11' or (extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda')" }, { name = "numpy", version = "2.2.6", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.11' or (extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda')" }, - { name = "numpy", version = "2.4.6", source = { registry = "https://pypi.org/simple" }, marker = "(python_full_version >= '3.11' and platform_machine != 'x86_64') or (python_full_version == '3.11.*' and platform_machine == 'x86_64' and sys_platform == 'darwin') or (python_full_version < '3.11' and platform_machine != 'x86_64' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (python_full_version != '3.11.*' and platform_machine == 'x86_64' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (python_full_version >= '3.11' and sys_platform != 'darwin') or (sys_platform != 'darwin' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda')" }, - { name = "numpy", version = "2.5.0", source = { registry = "https://pypi.org/simple" }, marker = "(python_full_version >= '3.12' and platform_machine == 'x86_64' and sys_platform == 'darwin') or (python_full_version < '3.12' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (platform_machine != 'x86_64' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (sys_platform != 'darwin' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda')" }, + { name = "numpy", version = "2.4.6", source = { registry = "https://pypi.org/simple" }, marker = "(python_full_version >= '3.12' and python_full_version < '3.15' and platform_machine == 'x86_64' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (python_full_version >= '3.11' and platform_machine != 'x86_64') or (python_full_version == '3.11.*' and platform_machine == 'x86_64' and sys_platform == 'darwin') or (python_full_version >= '3.15' and platform_machine == 'x86_64' and sys_platform == 'darwin') or (python_full_version >= '3.11' and sys_platform != 'darwin') or (python_full_version < '3.11' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (sys_platform != 'darwin' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda')" }, + { name = "numpy", version = "2.5.0", source = { registry = "https://pypi.org/simple" }, marker = "(python_full_version >= '3.12' and python_full_version < '3.15' and platform_machine == 'x86_64' and sys_platform == 'darwin') or (python_full_version < '3.12' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (python_full_version >= '3.15' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (platform_machine != 'x86_64' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (sys_platform != 'darwin' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda')" }, { name = "py4j" }, { name = "scipy", version = "1.15.3", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.11' or (extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda')" }, { name = "scipy", version = "1.17.1", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version == '3.11.*' or (extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda')" }, @@ -2763,8 +2764,8 @@ version = "2.37.3" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "numpy", version = "2.2.6", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.11' or (extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda')" }, - { name = "numpy", version = "2.4.6", source = { registry = "https://pypi.org/simple" }, marker = "(python_full_version >= '3.11' and platform_machine != 'x86_64') or (python_full_version == '3.11.*' and platform_machine == 'x86_64' and sys_platform == 'darwin') or (python_full_version < '3.11' and platform_machine != 'x86_64' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (python_full_version != '3.11.*' and platform_machine == 'x86_64' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (python_full_version >= '3.11' and sys_platform != 'darwin') or (sys_platform != 'darwin' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda')" }, - { name = "numpy", version = "2.5.0", source = { registry = "https://pypi.org/simple" }, marker = "(python_full_version >= '3.12' and platform_machine == 'x86_64' and sys_platform == 'darwin') or (python_full_version < '3.12' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (platform_machine != 'x86_64' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (sys_platform != 'darwin' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda')" }, + { name = "numpy", version = "2.4.6", source = { registry = "https://pypi.org/simple" }, marker = "(python_full_version >= '3.12' and python_full_version < '3.15' and platform_machine == 'x86_64' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (python_full_version >= '3.11' and platform_machine != 'x86_64') or (python_full_version == '3.11.*' and platform_machine == 'x86_64' and sys_platform == 'darwin') or (python_full_version >= '3.15' and platform_machine == 'x86_64' and sys_platform == 'darwin') or (python_full_version >= '3.11' and sys_platform != 'darwin') or (python_full_version < '3.11' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (sys_platform != 'darwin' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda')" }, + { name = "numpy", version = "2.5.0", source = { registry = "https://pypi.org/simple" }, marker = "(python_full_version >= '3.12' and python_full_version < '3.15' and platform_machine == 'x86_64' and sys_platform == 'darwin') or (python_full_version < '3.12' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (python_full_version >= '3.15' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (platform_machine != 'x86_64' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (sys_platform != 'darwin' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda')" }, { name = "pillow" }, ] sdist = { url = "https://files.pythonhosted.org/packages/b1/84/93bcd1300216ea50811cee96873b84a1bebf8d0489ffaf7f2a3756bab866/imageio-2.37.3.tar.gz", hash = "sha256:bbb37efbfc4c400fcd534b367b91fcd66d5da639aaa138034431a1c5e0a41451", size = 389673, upload-time = "2026-03-09T11:31:12.573Z" } @@ -2788,8 +2789,8 @@ source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "joblib" }, { name = "numpy", version = "2.2.6", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.11' or (extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda')" }, - { name = "numpy", version = "2.4.6", source = { registry = "https://pypi.org/simple" }, marker = "(python_full_version >= '3.11' and platform_machine != 'x86_64') or (python_full_version == '3.11.*' and platform_machine == 'x86_64' and sys_platform == 'darwin') or (python_full_version < '3.11' and platform_machine != 'x86_64' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (python_full_version != '3.11.*' and platform_machine == 'x86_64' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (python_full_version >= '3.11' and sys_platform != 'darwin') or (sys_platform != 'darwin' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda')" }, - { name = "numpy", version = "2.5.0", source = { registry = "https://pypi.org/simple" }, marker = "(python_full_version >= '3.12' and platform_machine == 'x86_64' and sys_platform == 'darwin') or (python_full_version < '3.12' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (platform_machine != 'x86_64' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (sys_platform != 'darwin' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda')" }, + { name = "numpy", version = "2.4.6", source = { registry = "https://pypi.org/simple" }, marker = "(python_full_version >= '3.12' and python_full_version < '3.15' and platform_machine == 'x86_64' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (python_full_version >= '3.11' and platform_machine != 'x86_64') or (python_full_version == '3.11.*' and platform_machine == 'x86_64' and sys_platform == 'darwin') or (python_full_version >= '3.15' and platform_machine == 'x86_64' and sys_platform == 'darwin') or (python_full_version >= '3.11' and sys_platform != 'darwin') or (python_full_version < '3.11' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (sys_platform != 'darwin' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda')" }, + { name = "numpy", version = "2.5.0", source = { registry = "https://pypi.org/simple" }, marker = "(python_full_version >= '3.12' and python_full_version < '3.15' and platform_machine == 'x86_64' and sys_platform == 'darwin') or (python_full_version < '3.12' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (python_full_version >= '3.15' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (platform_machine != 'x86_64' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (sys_platform != 'darwin' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda')" }, { name = "scikit-learn" }, { name = "scipy", version = "1.15.3", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.11' or (extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda')" }, { name = "scipy", version = "1.17.1", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version == '3.11.*' or (extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda')" }, @@ -3149,8 +3150,8 @@ version = "4.6.0" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "numpy", version = "2.2.6", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.11' or (extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda')" }, - { name = "numpy", version = "2.4.6", source = { registry = "https://pypi.org/simple" }, marker = "(python_full_version >= '3.11' and platform_machine != 'x86_64') or (python_full_version == '3.11.*' and platform_machine == 'x86_64' and sys_platform == 'darwin') or (python_full_version < '3.11' and platform_machine != 'x86_64' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (python_full_version != '3.11.*' and platform_machine == 'x86_64' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (python_full_version >= '3.11' and sys_platform != 'darwin') or (sys_platform != 'darwin' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda')" }, - { name = "numpy", version = "2.5.0", source = { registry = "https://pypi.org/simple" }, marker = "(python_full_version >= '3.12' and platform_machine == 'x86_64' and sys_platform == 'darwin') or (python_full_version < '3.12' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (platform_machine != 'x86_64' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (sys_platform != 'darwin' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda')" }, + { name = "numpy", version = "2.4.6", source = { registry = "https://pypi.org/simple" }, marker = "(python_full_version >= '3.12' and python_full_version < '3.15' and platform_machine == 'x86_64' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (python_full_version >= '3.11' and platform_machine != 'x86_64') or (python_full_version == '3.11.*' and platform_machine == 'x86_64' and sys_platform == 'darwin') or (python_full_version >= '3.15' and platform_machine == 'x86_64' and sys_platform == 'darwin') or (python_full_version >= '3.11' and sys_platform != 'darwin') or (python_full_version < '3.11' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (sys_platform != 'darwin' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda')" }, + { name = "numpy", version = "2.5.0", source = { registry = "https://pypi.org/simple" }, marker = "(python_full_version >= '3.12' and python_full_version < '3.15' and platform_machine == 'x86_64' and sys_platform == 'darwin') or (python_full_version < '3.12' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (python_full_version >= '3.15' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (platform_machine != 'x86_64' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (sys_platform != 'darwin' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda')" }, { name = "scipy", version = "1.15.3", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.11' or (extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda')" }, { name = "scipy", version = "1.17.1", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version == '3.11.*' or (extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda')" }, { name = "scipy", version = "1.18.0", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.12' or (extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda')" }, @@ -3185,8 +3186,8 @@ dependencies = [ { name = "matplotlib", version = "3.10.9", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.11' or (extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda')" }, { name = "matplotlib", version = "3.11.0", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.11' or (extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda')" }, { name = "numpy", version = "2.2.6", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.11' or (extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda')" }, - { name = "numpy", version = "2.4.6", source = { registry = "https://pypi.org/simple" }, marker = "(python_full_version >= '3.11' and platform_machine != 'x86_64') or (python_full_version == '3.11.*' and platform_machine == 'x86_64' and sys_platform == 'darwin') or (python_full_version < '3.11' and platform_machine != 'x86_64' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (python_full_version != '3.11.*' and platform_machine == 'x86_64' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (python_full_version >= '3.11' and sys_platform != 'darwin') or (sys_platform != 'darwin' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda')" }, - { name = "numpy", version = "2.5.0", source = { registry = "https://pypi.org/simple" }, marker = "(python_full_version >= '3.12' and platform_machine == 'x86_64' and sys_platform == 'darwin') or (python_full_version < '3.12' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (platform_machine != 'x86_64' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (sys_platform != 'darwin' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda')" }, + { name = "numpy", version = "2.4.6", source = { registry = "https://pypi.org/simple" }, marker = "(python_full_version >= '3.12' and python_full_version < '3.15' and platform_machine == 'x86_64' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (python_full_version >= '3.11' and platform_machine != 'x86_64') or (python_full_version == '3.11.*' and platform_machine == 'x86_64' and sys_platform == 'darwin') or (python_full_version >= '3.15' and platform_machine == 'x86_64' and sys_platform == 'darwin') or (python_full_version >= '3.11' and sys_platform != 'darwin') or (python_full_version < '3.11' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (sys_platform != 'darwin' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda')" }, + { name = "numpy", version = "2.5.0", source = { registry = "https://pypi.org/simple" }, marker = "(python_full_version >= '3.12' and python_full_version < '3.15' and platform_machine == 'x86_64' and sys_platform == 'darwin') or (python_full_version < '3.12' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (python_full_version >= '3.15' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (platform_machine != 'x86_64' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (sys_platform != 'darwin' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda')" }, { name = "scikit-image", version = "0.25.2", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.11' or (extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda')" }, { name = "scikit-image", version = "0.26.0", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.11' or (extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda')" }, { name = "scikit-learn" }, @@ -3223,8 +3224,8 @@ dependencies = [ { name = "diskcache" }, { name = "jinja2" }, { name = "numpy", version = "2.2.6", source = { registry = "https://pypi.org/simple" }, marker = "(python_full_version < '3.11' and extra == 'extra-6-dashai-cpu') or (extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda')" }, - { name = "numpy", version = "2.4.6", source = { registry = "https://pypi.org/simple" }, marker = "(python_full_version == '3.11.*' and platform_machine == 'x86_64' and sys_platform == 'darwin' and extra == 'extra-6-dashai-cpu') or (python_full_version >= '3.11' and platform_machine != 'x86_64' and extra == 'extra-6-dashai-cpu') or (python_full_version < '3.11' and platform_machine != 'x86_64' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (python_full_version != '3.11.*' and platform_machine == 'x86_64' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (python_full_version >= '3.11' and sys_platform != 'darwin' and extra == 'extra-6-dashai-cpu') or (sys_platform != 'darwin' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda')" }, - { name = "numpy", version = "2.5.0", source = { registry = "https://pypi.org/simple" }, marker = "(python_full_version >= '3.12' and platform_machine == 'x86_64' and sys_platform == 'darwin' and extra == 'extra-6-dashai-cpu') or (python_full_version < '3.12' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (platform_machine != 'x86_64' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (sys_platform != 'darwin' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda')" }, + { name = "numpy", version = "2.4.6", source = { registry = "https://pypi.org/simple" }, marker = "(python_full_version >= '3.12' and python_full_version < '3.15' and platform_machine == 'x86_64' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (python_full_version == '3.11.*' and platform_machine == 'x86_64' and sys_platform == 'darwin' and extra == 'extra-6-dashai-cpu') or (python_full_version >= '3.15' and platform_machine == 'x86_64' and sys_platform == 'darwin' and extra == 'extra-6-dashai-cpu') or (python_full_version >= '3.11' and platform_machine != 'x86_64' and extra == 'extra-6-dashai-cpu') or (python_full_version >= '3.11' and sys_platform != 'darwin' and extra == 'extra-6-dashai-cpu') or (python_full_version < '3.11' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (sys_platform != 'darwin' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda')" }, + { name = "numpy", version = "2.5.0", source = { registry = "https://pypi.org/simple" }, marker = "(python_full_version >= '3.12' and python_full_version < '3.15' and platform_machine == 'x86_64' and sys_platform == 'darwin' and extra == 'extra-6-dashai-cpu') or (python_full_version < '3.12' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (python_full_version >= '3.15' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (platform_machine != 'x86_64' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (sys_platform != 'darwin' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda')" }, { name = "typing-extensions" }, ] wheels = [ @@ -3258,16 +3259,78 @@ dependencies = [ { name = "diskcache" }, { name = "jinja2" }, { name = "numpy", version = "2.2.6", source = { registry = "https://pypi.org/simple" }, marker = "(python_full_version < '3.11' and extra == 'extra-6-dashai-cuda') or (extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda')" }, - { name = "numpy", version = "2.4.6", source = { registry = "https://pypi.org/simple" }, marker = "(python_full_version == '3.11.*' and platform_machine == 'x86_64' and sys_platform == 'darwin' and extra == 'extra-6-dashai-cuda') or (python_full_version >= '3.11' and platform_machine != 'x86_64' and extra == 'extra-6-dashai-cuda') or (python_full_version < '3.11' and platform_machine != 'x86_64' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (python_full_version != '3.11.*' and platform_machine == 'x86_64' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (python_full_version >= '3.11' and sys_platform != 'darwin' and extra == 'extra-6-dashai-cuda') or (sys_platform != 'darwin' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda')" }, - { name = "numpy", version = "2.5.0", source = { registry = "https://pypi.org/simple" }, marker = "(python_full_version >= '3.12' and platform_machine == 'x86_64' and sys_platform == 'darwin' and extra == 'extra-6-dashai-cuda') or (python_full_version < '3.12' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (platform_machine != 'x86_64' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (sys_platform != 'darwin' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda')" }, + { name = "numpy", version = "2.4.6", source = { registry = "https://pypi.org/simple" }, marker = "(python_full_version >= '3.12' and python_full_version < '3.15' and platform_machine == 'x86_64' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (python_full_version == '3.11.*' and platform_machine == 'x86_64' and sys_platform == 'darwin' and extra == 'extra-6-dashai-cuda') or (python_full_version >= '3.15' and platform_machine == 'x86_64' and sys_platform == 'darwin' and extra == 'extra-6-dashai-cuda') or (python_full_version >= '3.11' and platform_machine != 'x86_64' and extra == 'extra-6-dashai-cuda') or (python_full_version >= '3.11' and sys_platform != 'darwin' and extra == 'extra-6-dashai-cuda') or (python_full_version < '3.11' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (sys_platform != 'darwin' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda')" }, + { name = "numpy", version = "2.5.0", source = { registry = "https://pypi.org/simple" }, marker = "(python_full_version >= '3.12' and python_full_version < '3.15' and platform_machine == 'x86_64' and sys_platform == 'darwin' and extra == 'extra-6-dashai-cuda') or (python_full_version < '3.12' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (python_full_version >= '3.15' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (platform_machine != 'x86_64' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (sys_platform != 'darwin' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda')" }, { name = "typing-extensions" }, ] sdist = { url = "https://files.pythonhosted.org/packages/18/c8/3eb9c10c138eaa9d6148471701476169322eafbd825fdc13ec326552b516/llama_cpp_python-0.3.32.tar.gz", hash = "sha256:b06502361770f82eb08b7f1a192eb084b9ead2b88fe32cda8c397a2782eabde6", size = 70308017, upload-time = "2026-06-29T05:59:48.626Z" } +[[package]] +name = "llvmlite" +version = "0.45.1" +source = { registry = "https://pypi.org/simple" } +resolution-markers = [ + "python_full_version == '3.14.*' and platform_machine == 'x86_64' and sys_platform == 'darwin'", + "python_full_version == '3.13.*' and platform_machine == 'x86_64' and sys_platform == 'darwin'", + "python_full_version == '3.12.*' and platform_machine == 'x86_64' and sys_platform == 'darwin'", +] +sdist = { url = "https://files.pythonhosted.org/packages/99/8d/5baf1cef7f9c084fb35a8afbde88074f0d6a727bc63ef764fe0e7543ba40/llvmlite-0.45.1.tar.gz", hash = "sha256:09430bb9d0bb58fc45a45a57c7eae912850bedc095cd0810a57de109c69e1c32", size = 185600, upload-time = "2025-10-01T17:59:52.046Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/cf/6d/585c84ddd9d2a539a3c3487792b3cf3f988e28ec4fa281bf8b0e055e1166/llvmlite-0.45.1-cp310-cp310-macosx_10_15_x86_64.whl", hash = "sha256:1b1af0c910af0978aa55fa4f60bbb3e9f39b41e97c2a6d94d199897be62ba07a", size = 43043523, upload-time = "2025-10-01T18:02:58.621Z" }, + { url = "https://files.pythonhosted.org/packages/ae/34/992bd12d3ff245e0801bcf6013961daa8c19c9b9c2e61cb4b8bce94566f9/llvmlite-0.45.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:02a164db2d79088bbd6e0d9633b4fe4021d6379d7e4ac7cc85ed5f44b06a30c5", size = 37253122, upload-time = "2025-10-01T18:03:55.159Z" }, + { url = "https://files.pythonhosted.org/packages/a6/7b/6d7585998a5991fa74dc925aae57913ba8c7c2efff909de9d34cc1cd3c27/llvmlite-0.45.1-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:f2d47f34e4029e6df3395de34cc1c66440a8d72712993a6e6168db228686711b", size = 56288210, upload-time = "2025-10-01T18:00:41.978Z" }, + { url = "https://files.pythonhosted.org/packages/b5/e2/a4abea058633bfc82eb08fd69ce242c118fdb9b0abad1fdcbe0bc6aedab5/llvmlite-0.45.1-cp310-cp310-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:f7319e5f9f90720578a7f56fbc805bdfb4bc071b507c7611f170d631c3c0f1e0", size = 55140958, upload-time = "2025-10-01T18:01:55.694Z" }, + { url = "https://files.pythonhosted.org/packages/74/c0/233468e96ed287b953239c3b24b1d69df47c6ba9262bfdca98eda7e83a04/llvmlite-0.45.1-cp310-cp310-win_amd64.whl", hash = "sha256:4edb62e685867799e336723cb9787ec6598d51d0b1ed9af0f38e692aa757e898", size = 38132232, upload-time = "2025-10-01T18:04:41.538Z" }, + { url = "https://files.pythonhosted.org/packages/04/ad/9bdc87b2eb34642c1cfe6bcb4f5db64c21f91f26b010f263e7467e7536a3/llvmlite-0.45.1-cp311-cp311-macosx_10_15_x86_64.whl", hash = "sha256:60f92868d5d3af30b4239b50e1717cb4e4e54f6ac1c361a27903b318d0f07f42", size = 43043526, upload-time = "2025-10-01T18:03:15.051Z" }, + { url = "https://files.pythonhosted.org/packages/a5/ea/c25c6382f452a943b4082da5e8c1665ce29a62884e2ec80608533e8e82d5/llvmlite-0.45.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:98baab513e19beb210f1ef39066288784839a44cd504e24fff5d17f1b3cf0860", size = 37253118, upload-time = "2025-10-01T18:04:06.783Z" }, + { url = "https://files.pythonhosted.org/packages/fe/af/85fc237de98b181dbbe8647324331238d6c52a3554327ccdc83ced28efba/llvmlite-0.45.1-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:3adc2355694d6a6fbcc024d59bb756677e7de506037c878022d7b877e7613a36", size = 56288209, upload-time = "2025-10-01T18:01:00.168Z" }, + { url = "https://files.pythonhosted.org/packages/0a/df/3daf95302ff49beff4230065e3178cd40e71294968e8d55baf4a9e560814/llvmlite-0.45.1-cp311-cp311-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:2f3377a6db40f563058c9515dedcc8a3e562d8693a106a28f2ddccf2c8fcf6ca", size = 55140958, upload-time = "2025-10-01T18:02:11.199Z" }, + { url = "https://files.pythonhosted.org/packages/a4/56/4c0d503fe03bac820ecdeb14590cf9a248e120f483bcd5c009f2534f23f0/llvmlite-0.45.1-cp311-cp311-win_amd64.whl", hash = "sha256:f9c272682d91e0d57f2a76c6d9ebdfccc603a01828cdbe3d15273bdca0c3363a", size = 38132232, upload-time = "2025-10-01T18:04:52.181Z" }, + { url = "https://files.pythonhosted.org/packages/e2/7c/82cbd5c656e8991bcc110c69d05913be2229302a92acb96109e166ae31fb/llvmlite-0.45.1-cp312-cp312-macosx_10_15_x86_64.whl", hash = "sha256:28e763aba92fe9c72296911e040231d486447c01d4f90027c8e893d89d49b20e", size = 43043524, upload-time = "2025-10-01T18:03:30.666Z" }, + { url = "https://files.pythonhosted.org/packages/9d/bc/5314005bb2c7ee9f33102c6456c18cc81745d7055155d1218f1624463774/llvmlite-0.45.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:1a53f4b74ee9fd30cb3d27d904dadece67a7575198bd80e687ee76474620735f", size = 37253123, upload-time = "2025-10-01T18:04:18.177Z" }, + { url = "https://files.pythonhosted.org/packages/96/76/0f7154952f037cb320b83e1c952ec4a19d5d689cf7d27cb8a26887d7bbc1/llvmlite-0.45.1-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:5b3796b1b1e1c14dcae34285d2f4ea488402fbd2c400ccf7137603ca3800864f", size = 56288211, upload-time = "2025-10-01T18:01:24.079Z" }, + { url = "https://files.pythonhosted.org/packages/00/b1/0b581942be2683ceb6862d558979e87387e14ad65a1e4db0e7dd671fa315/llvmlite-0.45.1-cp312-cp312-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:779e2f2ceefef0f4368548685f0b4adde34e5f4b457e90391f570a10b348d433", size = 55140958, upload-time = "2025-10-01T18:02:30.482Z" }, + { url = "https://files.pythonhosted.org/packages/33/94/9ba4ebcf4d541a325fd8098ddc073b663af75cc8b065b6059848f7d4dce7/llvmlite-0.45.1-cp312-cp312-win_amd64.whl", hash = "sha256:9e6c9949baf25d9aa9cd7cf0f6d011b9ca660dd17f5ba2b23bdbdb77cc86b116", size = 38132231, upload-time = "2025-10-01T18:05:03.664Z" }, + { url = "https://files.pythonhosted.org/packages/1d/e2/c185bb7e88514d5025f93c6c4092f6120c6cea8fe938974ec9860fb03bbb/llvmlite-0.45.1-cp313-cp313-macosx_10_15_x86_64.whl", hash = "sha256:d9ea9e6f17569a4253515cc01dade70aba536476e3d750b2e18d81d7e670eb15", size = 43043524, upload-time = "2025-10-01T18:03:43.249Z" }, + { url = "https://files.pythonhosted.org/packages/09/b8/b5437b9ecb2064e89ccf67dccae0d02cd38911705112dd0dcbfa9cd9a9de/llvmlite-0.45.1-cp313-cp313-macosx_12_0_arm64.whl", hash = "sha256:c9f3cadee1630ce4ac18ea38adebf2a4f57a89bd2740ce83746876797f6e0bfb", size = 37253121, upload-time = "2025-10-01T18:04:30.557Z" }, + { url = "https://files.pythonhosted.org/packages/f7/97/ad1a907c0173a90dd4df7228f24a3ec61058bc1a9ff8a0caec20a0cc622e/llvmlite-0.45.1-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:57c48bf2e1083eedbc9406fb83c4e6483017879714916fe8be8a72a9672c995a", size = 56288210, upload-time = "2025-10-01T18:01:40.26Z" }, + { url = "https://files.pythonhosted.org/packages/32/d8/c99c8ac7a326e9735401ead3116f7685a7ec652691aeb2615aa732b1fc4a/llvmlite-0.45.1-cp313-cp313-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:3aa3dfceda4219ae39cf18806c60eeb518c1680ff834b8b311bd784160b9ce40", size = 55140957, upload-time = "2025-10-01T18:02:46.244Z" }, + { url = "https://files.pythonhosted.org/packages/09/56/ed35668130e32dbfad2eb37356793b0a95f23494ab5be7d9bf5cb75850ee/llvmlite-0.45.1-cp313-cp313-win_amd64.whl", hash = "sha256:080e6f8d0778a8239cd47686d402cb66eb165e421efa9391366a9b7e5810a38b", size = 38132232, upload-time = "2025-10-01T18:05:14.477Z" }, +] + [[package]] name = "llvmlite" version = "0.48.0" source = { registry = "https://pypi.org/simple" } +resolution-markers = [ + "python_full_version >= '3.15' and platform_machine == 'x86_64' and sys_platform == 'darwin' and extra != 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda'", + "(python_full_version >= '3.15' and platform_machine != 'x86_64' and extra != 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (python_full_version >= '3.15' and sys_platform != 'darwin' and extra != 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda')", + "(python_full_version == '3.14.*' and platform_machine != 'x86_64' and extra != 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (python_full_version == '3.14.*' and sys_platform != 'darwin' and extra != 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda')", + "(python_full_version == '3.13.*' and platform_machine != 'x86_64' and extra != 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (python_full_version == '3.13.*' and sys_platform != 'darwin' and extra != 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda')", + "(python_full_version == '3.12.*' and platform_machine != 'x86_64' and extra != 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (python_full_version == '3.12.*' and sys_platform != 'darwin' and extra != 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda')", + "python_full_version == '3.11.*' and extra != 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda'", + "python_full_version < '3.11' and extra != 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda'", + "python_full_version >= '3.15' and platform_machine == 'x86_64' and sys_platform == 'darwin' and extra == 'extra-6-dashai-cpu' and extra != 'extra-6-dashai-cuda'", + "python_full_version >= '3.15' and sys_platform != 'darwin' and extra == 'extra-6-dashai-cpu' and extra != 'extra-6-dashai-cuda'", + "python_full_version == '3.14.*' and sys_platform != 'darwin' and extra == 'extra-6-dashai-cpu' and extra != 'extra-6-dashai-cuda'", + "python_full_version == '3.13.*' and sys_platform != 'darwin' and extra == 'extra-6-dashai-cpu' and extra != 'extra-6-dashai-cuda'", + "python_full_version == '3.12.*' and sys_platform != 'darwin' and extra == 'extra-6-dashai-cpu' and extra != 'extra-6-dashai-cuda'", + "python_full_version >= '3.15' and platform_machine != 'x86_64' and sys_platform == 'darwin' and extra == 'extra-6-dashai-cpu' and extra != 'extra-6-dashai-cuda'", + "python_full_version == '3.14.*' and platform_machine != 'x86_64' and sys_platform == 'darwin' and extra == 'extra-6-dashai-cpu' and extra != 'extra-6-dashai-cuda'", + "python_full_version == '3.13.*' and platform_machine != 'x86_64' and sys_platform == 'darwin' and extra == 'extra-6-dashai-cpu' and extra != 'extra-6-dashai-cuda'", + "python_full_version == '3.12.*' and platform_machine != 'x86_64' and sys_platform == 'darwin' and extra == 'extra-6-dashai-cpu' and extra != 'extra-6-dashai-cuda'", + "python_full_version == '3.11.*' and sys_platform != 'darwin' and extra == 'extra-6-dashai-cpu' and extra != 'extra-6-dashai-cuda'", + "python_full_version == '3.11.*' and sys_platform == 'darwin' and extra == 'extra-6-dashai-cpu' and extra != 'extra-6-dashai-cuda'", + "python_full_version < '3.11' and sys_platform != 'darwin' and extra == 'extra-6-dashai-cpu' and extra != 'extra-6-dashai-cuda'", + "python_full_version < '3.11' and sys_platform == 'darwin' and extra == 'extra-6-dashai-cpu' and extra != 'extra-6-dashai-cuda'", + "python_full_version >= '3.15' and platform_machine == 'x86_64' and sys_platform == 'darwin' and extra != 'extra-6-dashai-cpu' and extra != 'extra-6-dashai-cuda'", + "(python_full_version >= '3.15' and platform_machine != 'x86_64' and extra != 'extra-6-dashai-cpu' and extra != 'extra-6-dashai-cuda') or (python_full_version >= '3.15' and sys_platform != 'darwin' and extra != 'extra-6-dashai-cpu' and extra != 'extra-6-dashai-cuda')", + "(python_full_version == '3.14.*' and platform_machine != 'x86_64' and extra != 'extra-6-dashai-cpu' and extra != 'extra-6-dashai-cuda') or (python_full_version == '3.14.*' and sys_platform != 'darwin' and extra != 'extra-6-dashai-cpu' and extra != 'extra-6-dashai-cuda')", + "(python_full_version == '3.13.*' and platform_machine != 'x86_64' and extra != 'extra-6-dashai-cpu' and extra != 'extra-6-dashai-cuda') or (python_full_version == '3.13.*' and sys_platform != 'darwin' and extra != 'extra-6-dashai-cpu' and extra != 'extra-6-dashai-cuda')", + "(python_full_version == '3.12.*' and platform_machine != 'x86_64' and extra != 'extra-6-dashai-cpu' and extra != 'extra-6-dashai-cuda') or (python_full_version == '3.12.*' and sys_platform != 'darwin' and extra != 'extra-6-dashai-cpu' and extra != 'extra-6-dashai-cuda')", + "python_full_version == '3.11.*' and extra != 'extra-6-dashai-cpu' and extra != 'extra-6-dashai-cuda'", + "python_full_version < '3.11' and extra != 'extra-6-dashai-cpu' and extra != 'extra-6-dashai-cuda'", +] sdist = { url = "https://files.pythonhosted.org/packages/dc/a0/acc8ffcd5bdc63df0097e22c719bfcd61b604358343089313a8aebbb24ab/llvmlite-0.48.0.tar.gz", hash = "sha256:543b19f9ef8f3c7c60d1468191e4ee1b1537bf9f8a3d56f64c0ddd98de92edd2", size = 184016, upload-time = "2026-07-02T20:20:05.308Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/a2/4e/32543c42568fb321b3bdfcf9106e4116ab8f5a7bbcfd9ecf5569b0c07d83/llvmlite-0.48.0-cp310-cp310-macosx_12_0_arm64.whl", hash = "sha256:614aad57df707e3172efd5165f2aa7da6a0c6897e40dce590bf756396815ba76", size = 40480650, upload-time = "2026-07-01T18:41:01.945Z" }, @@ -3658,8 +3721,8 @@ dependencies = [ { name = "cycler", marker = "python_full_version >= '3.11' or (extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda')" }, { name = "fonttools", marker = "python_full_version >= '3.11' or (extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda')" }, { name = "kiwisolver", marker = "python_full_version >= '3.11' or (extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda')" }, - { name = "numpy", version = "2.4.6", source = { registry = "https://pypi.org/simple" }, marker = "(python_full_version >= '3.11' and platform_machine != 'x86_64') or (python_full_version == '3.11.*' and platform_machine == 'x86_64' and sys_platform == 'darwin') or (python_full_version < '3.11' and platform_machine != 'x86_64' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (python_full_version != '3.11.*' and platform_machine == 'x86_64' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (python_full_version >= '3.11' and sys_platform != 'darwin') or (sys_platform != 'darwin' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda')" }, - { name = "numpy", version = "2.5.0", source = { registry = "https://pypi.org/simple" }, marker = "(python_full_version >= '3.12' and platform_machine == 'x86_64' and sys_platform == 'darwin') or (python_full_version < '3.12' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (platform_machine != 'x86_64' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (sys_platform != 'darwin' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda')" }, + { name = "numpy", version = "2.4.6", source = { registry = "https://pypi.org/simple" }, marker = "(python_full_version >= '3.12' and python_full_version < '3.15' and platform_machine == 'x86_64' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (python_full_version >= '3.11' and platform_machine != 'x86_64') or (python_full_version == '3.11.*' and platform_machine == 'x86_64' and sys_platform == 'darwin') or (python_full_version >= '3.15' and platform_machine == 'x86_64' and sys_platform == 'darwin') or (python_full_version >= '3.11' and sys_platform != 'darwin') or (python_full_version < '3.11' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (sys_platform != 'darwin' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda')" }, + { name = "numpy", version = "2.5.0", source = { registry = "https://pypi.org/simple" }, marker = "(python_full_version >= '3.12' and python_full_version < '3.15' and platform_machine == 'x86_64' and sys_platform == 'darwin') or (python_full_version < '3.12' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (python_full_version >= '3.15' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (platform_machine != 'x86_64' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (sys_platform != 'darwin' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda')" }, { name = "packaging", marker = "python_full_version >= '3.11' or (extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda')" }, { name = "pillow", marker = "python_full_version >= '3.11' or (extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda')" }, { name = "pyparsing", marker = "python_full_version >= '3.11' or (extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda')" }, @@ -4093,15 +4156,14 @@ name = "numba" version = "0.47.0" source = { registry = "https://pypi.org/simple" } resolution-markers = [ - "python_full_version >= '3.15' and platform_machine == 'x86_64' and sys_platform == 'darwin'", "python_full_version == '3.14.*' and platform_machine == 'x86_64' and sys_platform == 'darwin'", "python_full_version == '3.13.*' and platform_machine == 'x86_64' and sys_platform == 'darwin'", "python_full_version == '3.12.*' and platform_machine == 'x86_64' and sys_platform == 'darwin'", ] dependencies = [ - { name = "llvmlite", marker = "(python_full_version >= '3.12' and platform_machine == 'x86_64' and sys_platform == 'darwin') or (python_full_version < '3.12' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (platform_machine != 'x86_64' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (sys_platform != 'darwin' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda')" }, - { name = "numpy", version = "2.5.0", source = { registry = "https://pypi.org/simple" }, marker = "(python_full_version >= '3.12' and platform_machine == 'x86_64' and sys_platform == 'darwin') or (python_full_version < '3.12' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (platform_machine != 'x86_64' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (sys_platform != 'darwin' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda')" }, - { name = "setuptools", marker = "(python_full_version >= '3.12' and platform_machine == 'x86_64' and sys_platform == 'darwin') or (python_full_version < '3.12' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (platform_machine != 'x86_64' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (sys_platform != 'darwin' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda')" }, + { name = "llvmlite", version = "0.45.1", source = { registry = "https://pypi.org/simple" }, marker = "(python_full_version >= '3.12' and python_full_version < '3.15' and platform_machine == 'x86_64' and sys_platform == 'darwin') or (python_full_version < '3.12' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (python_full_version >= '3.15' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (platform_machine != 'x86_64' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (sys_platform != 'darwin' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda')" }, + { name = "numpy", version = "2.5.0", source = { registry = "https://pypi.org/simple" }, marker = "(python_full_version >= '3.12' and python_full_version < '3.15' and platform_machine == 'x86_64' and sys_platform == 'darwin') or (python_full_version < '3.12' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (python_full_version >= '3.15' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (platform_machine != 'x86_64' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (sys_platform != 'darwin' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda')" }, + { name = "setuptools", marker = "(python_full_version >= '3.12' and python_full_version < '3.15' and platform_machine == 'x86_64' and sys_platform == 'darwin') or (python_full_version < '3.12' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (python_full_version >= '3.15' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (platform_machine != 'x86_64' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (sys_platform != 'darwin' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda')" }, ] sdist = { url = "https://files.pythonhosted.org/packages/b0/2a/975f49e156dae4edd3ab5afc60e2b3d65add014db2ddbbc23b9bb89882a4/numba-0.47.0.tar.gz", hash = "sha256:c0703df0a0ea2e29fbef7937d9849cc4734253066cb5820c5d6e0851876e3b0a", size = 1935290, upload-time = "2020-01-03T17:03:47.391Z" } @@ -4110,12 +4172,14 @@ name = "numba" version = "0.66.0" source = { registry = "https://pypi.org/simple" } resolution-markers = [ + "python_full_version >= '3.15' and platform_machine == 'x86_64' and sys_platform == 'darwin' and extra != 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda'", "(python_full_version >= '3.15' and platform_machine != 'x86_64' and extra != 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (python_full_version >= '3.15' and sys_platform != 'darwin' and extra != 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda')", "(python_full_version == '3.14.*' and platform_machine != 'x86_64' and extra != 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (python_full_version == '3.14.*' and sys_platform != 'darwin' and extra != 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda')", "(python_full_version == '3.13.*' and platform_machine != 'x86_64' and extra != 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (python_full_version == '3.13.*' and sys_platform != 'darwin' and extra != 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda')", "(python_full_version == '3.12.*' and platform_machine != 'x86_64' and extra != 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (python_full_version == '3.12.*' and sys_platform != 'darwin' and extra != 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda')", "python_full_version == '3.11.*' and extra != 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda'", "python_full_version < '3.11' and extra != 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda'", + "python_full_version >= '3.15' and platform_machine == 'x86_64' and sys_platform == 'darwin' and extra == 'extra-6-dashai-cpu' and extra != 'extra-6-dashai-cuda'", "python_full_version >= '3.15' and sys_platform != 'darwin' and extra == 'extra-6-dashai-cpu' and extra != 'extra-6-dashai-cuda'", "python_full_version == '3.14.*' and sys_platform != 'darwin' and extra == 'extra-6-dashai-cpu' and extra != 'extra-6-dashai-cuda'", "python_full_version == '3.13.*' and sys_platform != 'darwin' and extra == 'extra-6-dashai-cpu' and extra != 'extra-6-dashai-cuda'", @@ -4128,6 +4192,7 @@ resolution-markers = [ "python_full_version == '3.11.*' and sys_platform == 'darwin' and extra == 'extra-6-dashai-cpu' and extra != 'extra-6-dashai-cuda'", "python_full_version < '3.11' and sys_platform != 'darwin' and extra == 'extra-6-dashai-cpu' and extra != 'extra-6-dashai-cuda'", "python_full_version < '3.11' and sys_platform == 'darwin' and extra == 'extra-6-dashai-cpu' and extra != 'extra-6-dashai-cuda'", + "python_full_version >= '3.15' and platform_machine == 'x86_64' and sys_platform == 'darwin' and extra != 'extra-6-dashai-cpu' and extra != 'extra-6-dashai-cuda'", "(python_full_version >= '3.15' and platform_machine != 'x86_64' and extra != 'extra-6-dashai-cpu' and extra != 'extra-6-dashai-cuda') or (python_full_version >= '3.15' and sys_platform != 'darwin' and extra != 'extra-6-dashai-cpu' and extra != 'extra-6-dashai-cuda')", "(python_full_version == '3.14.*' and platform_machine != 'x86_64' and extra != 'extra-6-dashai-cpu' and extra != 'extra-6-dashai-cuda') or (python_full_version == '3.14.*' and sys_platform != 'darwin' and extra != 'extra-6-dashai-cpu' and extra != 'extra-6-dashai-cuda')", "(python_full_version == '3.13.*' and platform_machine != 'x86_64' and extra != 'extra-6-dashai-cpu' and extra != 'extra-6-dashai-cuda') or (python_full_version == '3.13.*' and sys_platform != 'darwin' and extra != 'extra-6-dashai-cpu' and extra != 'extra-6-dashai-cuda')", @@ -4136,9 +4201,9 @@ resolution-markers = [ "python_full_version < '3.11' and extra != 'extra-6-dashai-cpu' and extra != 'extra-6-dashai-cuda'", ] dependencies = [ - { name = "llvmlite", marker = "python_full_version < '3.12' or platform_machine != 'x86_64' or sys_platform != 'darwin' or (extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda')" }, + { name = "llvmlite", version = "0.48.0", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.12' or python_full_version >= '3.15' or platform_machine != 'x86_64' or sys_platform != 'darwin' or (extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda')" }, { name = "numpy", version = "2.2.6", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.11' or (extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda')" }, - { name = "numpy", version = "2.4.6", source = { registry = "https://pypi.org/simple" }, marker = "(python_full_version >= '3.11' and platform_machine != 'x86_64') or (python_full_version == '3.11.*' and platform_machine == 'x86_64' and sys_platform == 'darwin') or (python_full_version < '3.11' and platform_machine != 'x86_64' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (python_full_version != '3.11.*' and platform_machine == 'x86_64' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (python_full_version >= '3.11' and sys_platform != 'darwin') or (sys_platform != 'darwin' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda')" }, + { name = "numpy", version = "2.4.6", source = { registry = "https://pypi.org/simple" }, marker = "(python_full_version >= '3.12' and python_full_version < '3.15' and platform_machine == 'x86_64' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (python_full_version >= '3.11' and platform_machine != 'x86_64') or (python_full_version == '3.11.*' and platform_machine == 'x86_64' and sys_platform == 'darwin') or (python_full_version >= '3.15' and platform_machine == 'x86_64' and sys_platform == 'darwin') or (python_full_version >= '3.11' and sys_platform != 'darwin') or (python_full_version < '3.11' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (sys_platform != 'darwin' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda')" }, ] sdist = { url = "https://files.pythonhosted.org/packages/ae/a0/570e3dc53e5602b49108f62a13e529f1eec8bfc7ef37d49c825924dcf546/numba-0.66.0.tar.gz", hash = "sha256:b900e63a0e26c05ea9a6d5a3a5a0a177cb64c5011887bf43edb8c3ed2c38d363", size = 2806181, upload-time = "2026-07-01T23:12:46.36Z" } wheels = [ @@ -4241,11 +4306,13 @@ name = "numpy" version = "2.4.6" source = { registry = "https://pypi.org/simple" } resolution-markers = [ + "python_full_version >= '3.15' and platform_machine == 'x86_64' and sys_platform == 'darwin' and extra != 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda'", "(python_full_version >= '3.15' and platform_machine != 'x86_64' and extra != 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (python_full_version >= '3.15' and sys_platform != 'darwin' and extra != 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda')", "(python_full_version == '3.14.*' and platform_machine != 'x86_64' and extra != 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (python_full_version == '3.14.*' and sys_platform != 'darwin' and extra != 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda')", "(python_full_version == '3.13.*' and platform_machine != 'x86_64' and extra != 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (python_full_version == '3.13.*' and sys_platform != 'darwin' and extra != 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda')", "(python_full_version == '3.12.*' and platform_machine != 'x86_64' and extra != 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (python_full_version == '3.12.*' and sys_platform != 'darwin' and extra != 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda')", "python_full_version == '3.11.*' and extra != 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda'", + "python_full_version >= '3.15' and platform_machine == 'x86_64' and sys_platform == 'darwin' and extra == 'extra-6-dashai-cpu' and extra != 'extra-6-dashai-cuda'", "python_full_version >= '3.15' and sys_platform != 'darwin' and extra == 'extra-6-dashai-cpu' and extra != 'extra-6-dashai-cuda'", "python_full_version == '3.14.*' and sys_platform != 'darwin' and extra == 'extra-6-dashai-cpu' and extra != 'extra-6-dashai-cuda'", "python_full_version == '3.13.*' and sys_platform != 'darwin' and extra == 'extra-6-dashai-cpu' and extra != 'extra-6-dashai-cuda'", @@ -4256,6 +4323,7 @@ resolution-markers = [ "python_full_version == '3.12.*' and platform_machine != 'x86_64' and sys_platform == 'darwin' and extra == 'extra-6-dashai-cpu' and extra != 'extra-6-dashai-cuda'", "python_full_version == '3.11.*' and sys_platform != 'darwin' and extra == 'extra-6-dashai-cpu' and extra != 'extra-6-dashai-cuda'", "python_full_version == '3.11.*' and sys_platform == 'darwin' and extra == 'extra-6-dashai-cpu' and extra != 'extra-6-dashai-cuda'", + "python_full_version >= '3.15' and platform_machine == 'x86_64' and sys_platform == 'darwin' and extra != 'extra-6-dashai-cpu' and extra != 'extra-6-dashai-cuda'", "(python_full_version >= '3.15' and platform_machine != 'x86_64' and extra != 'extra-6-dashai-cpu' and extra != 'extra-6-dashai-cuda') or (python_full_version >= '3.15' and sys_platform != 'darwin' and extra != 'extra-6-dashai-cpu' and extra != 'extra-6-dashai-cuda')", "(python_full_version == '3.14.*' and platform_machine != 'x86_64' and extra != 'extra-6-dashai-cpu' and extra != 'extra-6-dashai-cuda') or (python_full_version == '3.14.*' and sys_platform != 'darwin' and extra != 'extra-6-dashai-cpu' and extra != 'extra-6-dashai-cuda')", "(python_full_version == '3.13.*' and platform_machine != 'x86_64' and extra != 'extra-6-dashai-cpu' and extra != 'extra-6-dashai-cuda') or (python_full_version == '3.13.*' and sys_platform != 'darwin' and extra != 'extra-6-dashai-cpu' and extra != 'extra-6-dashai-cuda')", @@ -4342,7 +4410,6 @@ name = "numpy" version = "2.5.0" source = { registry = "https://pypi.org/simple" } resolution-markers = [ - "python_full_version >= '3.15' and platform_machine == 'x86_64' and sys_platform == 'darwin'", "python_full_version == '3.14.*' and platform_machine == 'x86_64' and sys_platform == 'darwin'", "python_full_version == '3.13.*' and platform_machine == 'x86_64' and sys_platform == 'darwin'", "python_full_version == '3.12.*' and platform_machine == 'x86_64' and sys_platform == 'darwin'", @@ -4734,8 +4801,8 @@ version = "5.0.0.93" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "numpy", version = "2.2.6", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.11' or (extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda')" }, - { name = "numpy", version = "2.4.6", source = { registry = "https://pypi.org/simple" }, marker = "(python_full_version >= '3.11' and platform_machine != 'x86_64') or (python_full_version == '3.11.*' and platform_machine == 'x86_64' and sys_platform == 'darwin') or (python_full_version < '3.11' and platform_machine != 'x86_64' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (python_full_version != '3.11.*' and platform_machine == 'x86_64' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (python_full_version >= '3.11' and sys_platform != 'darwin') or (sys_platform != 'darwin' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda')" }, - { name = "numpy", version = "2.5.0", source = { registry = "https://pypi.org/simple" }, marker = "(python_full_version >= '3.12' and platform_machine == 'x86_64' and sys_platform == 'darwin') or (python_full_version < '3.12' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (platform_machine != 'x86_64' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (sys_platform != 'darwin' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda')" }, + { name = "numpy", version = "2.4.6", source = { registry = "https://pypi.org/simple" }, marker = "(python_full_version >= '3.12' and python_full_version < '3.15' and platform_machine == 'x86_64' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (python_full_version >= '3.11' and platform_machine != 'x86_64') or (python_full_version == '3.11.*' and platform_machine == 'x86_64' and sys_platform == 'darwin') or (python_full_version >= '3.15' and platform_machine == 'x86_64' and sys_platform == 'darwin') or (python_full_version >= '3.11' and sys_platform != 'darwin') or (python_full_version < '3.11' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (sys_platform != 'darwin' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda')" }, + { name = "numpy", version = "2.5.0", source = { registry = "https://pypi.org/simple" }, marker = "(python_full_version >= '3.12' and python_full_version < '3.15' and platform_machine == 'x86_64' and sys_platform == 'darwin') or (python_full_version < '3.12' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (python_full_version >= '3.15' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (platform_machine != 'x86_64' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (sys_platform != 'darwin' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda')" }, ] sdist = { url = "https://files.pythonhosted.org/packages/79/4c/a438d23e09ce2033c09f7b784ad2fbdb0adf529e434101ed28f142226f98/opencv_python-5.0.0.93.tar.gz", hash = "sha256:66aac3e5b5faa48d4025816592f3af19e4bfc2c68dec067bae2dbb4ca10aa9e2", size = 81802749, upload-time = "2026-07-02T06:59:53.815Z" } wheels = [ @@ -4755,8 +4822,8 @@ version = "5.0.0.93" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "numpy", version = "2.2.6", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.11' or (extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda')" }, - { name = "numpy", version = "2.4.6", source = { registry = "https://pypi.org/simple" }, marker = "(python_full_version >= '3.11' and platform_machine != 'x86_64') or (python_full_version == '3.11.*' and platform_machine == 'x86_64' and sys_platform == 'darwin') or (python_full_version < '3.11' and platform_machine != 'x86_64' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (python_full_version != '3.11.*' and platform_machine == 'x86_64' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (python_full_version >= '3.11' and sys_platform != 'darwin') or (sys_platform != 'darwin' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda')" }, - { name = "numpy", version = "2.5.0", source = { registry = "https://pypi.org/simple" }, marker = "(python_full_version >= '3.12' and platform_machine == 'x86_64' and sys_platform == 'darwin') or (python_full_version < '3.12' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (platform_machine != 'x86_64' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (sys_platform != 'darwin' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda')" }, + { name = "numpy", version = "2.4.6", source = { registry = "https://pypi.org/simple" }, marker = "(python_full_version >= '3.12' and python_full_version < '3.15' and platform_machine == 'x86_64' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (python_full_version >= '3.11' and platform_machine != 'x86_64') or (python_full_version == '3.11.*' and platform_machine == 'x86_64' and sys_platform == 'darwin') or (python_full_version >= '3.15' and platform_machine == 'x86_64' and sys_platform == 'darwin') or (python_full_version >= '3.11' and sys_platform != 'darwin') or (python_full_version < '3.11' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (sys_platform != 'darwin' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda')" }, + { name = "numpy", version = "2.5.0", source = { registry = "https://pypi.org/simple" }, marker = "(python_full_version >= '3.12' and python_full_version < '3.15' and platform_machine == 'x86_64' and sys_platform == 'darwin') or (python_full_version < '3.12' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (python_full_version >= '3.15' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (platform_machine != 'x86_64' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (sys_platform != 'darwin' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda')" }, ] sdist = { url = "https://files.pythonhosted.org/packages/1d/99/76b7c80252aa83c1af16393454aafd125a0287101afe8deb0a6821af0e30/opencv_python_headless-5.0.0.93.tar.gz", hash = "sha256:b82f9831daab90b725c7c1ee1b36cb5732c367096ac76d119e64e14eb70d5f3c", size = 81817738, upload-time = "2026-07-02T07:01:06.039Z" } wheels = [ @@ -4778,8 +4845,8 @@ dependencies = [ { name = "liac-arff" }, { name = "minio" }, { name = "numpy", version = "2.2.6", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.11' or (extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda')" }, - { name = "numpy", version = "2.4.6", source = { registry = "https://pypi.org/simple" }, marker = "(python_full_version >= '3.11' and platform_machine != 'x86_64') or (python_full_version == '3.11.*' and platform_machine == 'x86_64' and sys_platform == 'darwin') or (python_full_version < '3.11' and platform_machine != 'x86_64' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (python_full_version != '3.11.*' and platform_machine == 'x86_64' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (python_full_version >= '3.11' and sys_platform != 'darwin') or (sys_platform != 'darwin' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda')" }, - { name = "numpy", version = "2.5.0", source = { registry = "https://pypi.org/simple" }, marker = "(python_full_version >= '3.12' and platform_machine == 'x86_64' and sys_platform == 'darwin') or (python_full_version < '3.12' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (platform_machine != 'x86_64' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (sys_platform != 'darwin' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda')" }, + { name = "numpy", version = "2.4.6", source = { registry = "https://pypi.org/simple" }, marker = "(python_full_version >= '3.12' and python_full_version < '3.15' and platform_machine == 'x86_64' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (python_full_version >= '3.11' and platform_machine != 'x86_64') or (python_full_version == '3.11.*' and platform_machine == 'x86_64' and sys_platform == 'darwin') or (python_full_version >= '3.15' and platform_machine == 'x86_64' and sys_platform == 'darwin') or (python_full_version >= '3.11' and sys_platform != 'darwin') or (python_full_version < '3.11' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (sys_platform != 'darwin' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda')" }, + { name = "numpy", version = "2.5.0", source = { registry = "https://pypi.org/simple" }, marker = "(python_full_version >= '3.12' and python_full_version < '3.15' and platform_machine == 'x86_64' and sys_platform == 'darwin') or (python_full_version < '3.12' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (python_full_version >= '3.15' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (platform_machine != 'x86_64' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (sys_platform != 'darwin' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda')" }, { name = "packaging" }, { name = "pandas" }, { name = "pyarrow" }, @@ -4817,8 +4884,8 @@ dependencies = [ { name = "alembic" }, { name = "colorlog" }, { name = "numpy", version = "2.2.6", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.11' or (extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda')" }, - { name = "numpy", version = "2.4.6", source = { registry = "https://pypi.org/simple" }, marker = "(python_full_version >= '3.11' and platform_machine != 'x86_64') or (python_full_version == '3.11.*' and platform_machine == 'x86_64' and sys_platform == 'darwin') or (python_full_version < '3.11' and platform_machine != 'x86_64' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (python_full_version != '3.11.*' and platform_machine == 'x86_64' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (python_full_version >= '3.11' and sys_platform != 'darwin') or (sys_platform != 'darwin' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda')" }, - { name = "numpy", version = "2.5.0", source = { registry = "https://pypi.org/simple" }, marker = "(python_full_version >= '3.12' and platform_machine == 'x86_64' and sys_platform == 'darwin') or (python_full_version < '3.12' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (platform_machine != 'x86_64' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (sys_platform != 'darwin' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda')" }, + { name = "numpy", version = "2.4.6", source = { registry = "https://pypi.org/simple" }, marker = "(python_full_version >= '3.12' and python_full_version < '3.15' and platform_machine == 'x86_64' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (python_full_version >= '3.11' and platform_machine != 'x86_64') or (python_full_version == '3.11.*' and platform_machine == 'x86_64' and sys_platform == 'darwin') or (python_full_version >= '3.15' and platform_machine == 'x86_64' and sys_platform == 'darwin') or (python_full_version >= '3.11' and sys_platform != 'darwin') or (python_full_version < '3.11' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (sys_platform != 'darwin' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda')" }, + { name = "numpy", version = "2.5.0", source = { registry = "https://pypi.org/simple" }, marker = "(python_full_version >= '3.12' and python_full_version < '3.15' and platform_machine == 'x86_64' and sys_platform == 'darwin') or (python_full_version < '3.12' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (python_full_version >= '3.15' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (platform_machine != 'x86_64' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (sys_platform != 'darwin' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda')" }, { name = "packaging" }, { name = "pyyaml" }, { name = "sqlalchemy" }, @@ -4967,8 +5034,8 @@ version = "2.3.3" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "numpy", version = "2.2.6", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.11' or (extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda')" }, - { name = "numpy", version = "2.4.6", source = { registry = "https://pypi.org/simple" }, marker = "(python_full_version >= '3.11' and platform_machine != 'x86_64') or (python_full_version == '3.11.*' and platform_machine == 'x86_64' and sys_platform == 'darwin') or (python_full_version < '3.11' and platform_machine != 'x86_64' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (python_full_version != '3.11.*' and platform_machine == 'x86_64' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (python_full_version >= '3.11' and sys_platform != 'darwin') or (sys_platform != 'darwin' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda')" }, - { name = "numpy", version = "2.5.0", source = { registry = "https://pypi.org/simple" }, marker = "(python_full_version >= '3.12' and platform_machine == 'x86_64' and sys_platform == 'darwin') or (python_full_version < '3.12' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (platform_machine != 'x86_64' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (sys_platform != 'darwin' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda')" }, + { name = "numpy", version = "2.4.6", source = { registry = "https://pypi.org/simple" }, marker = "(python_full_version >= '3.12' and python_full_version < '3.15' and platform_machine == 'x86_64' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (python_full_version >= '3.11' and platform_machine != 'x86_64') or (python_full_version == '3.11.*' and platform_machine == 'x86_64' and sys_platform == 'darwin') or (python_full_version >= '3.15' and platform_machine == 'x86_64' and sys_platform == 'darwin') or (python_full_version >= '3.11' and sys_platform != 'darwin') or (python_full_version < '3.11' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (sys_platform != 'darwin' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda')" }, + { name = "numpy", version = "2.5.0", source = { registry = "https://pypi.org/simple" }, marker = "(python_full_version >= '3.12' and python_full_version < '3.15' and platform_machine == 'x86_64' and sys_platform == 'darwin') or (python_full_version < '3.12' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (python_full_version >= '3.15' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (platform_machine != 'x86_64' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (sys_platform != 'darwin' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda')" }, { name = "python-dateutil" }, { name = "pytz" }, { name = "tzdata" }, @@ -5726,8 +5793,8 @@ dependencies = [ { name = "arviz", marker = "python_full_version >= '3.11' or (extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda')" }, { name = "cachetools", marker = "python_full_version >= '3.11' or (extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda')" }, { name = "cloudpickle", marker = "python_full_version >= '3.11' or (extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda')" }, - { name = "numpy", version = "2.4.6", source = { registry = "https://pypi.org/simple" }, marker = "(python_full_version >= '3.11' and platform_machine != 'x86_64') or (python_full_version == '3.11.*' and platform_machine == 'x86_64' and sys_platform == 'darwin') or (python_full_version < '3.11' and platform_machine != 'x86_64' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (python_full_version != '3.11.*' and platform_machine == 'x86_64' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (python_full_version >= '3.11' and sys_platform != 'darwin') or (sys_platform != 'darwin' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda')" }, - { name = "numpy", version = "2.5.0", source = { registry = "https://pypi.org/simple" }, marker = "(python_full_version >= '3.12' and platform_machine == 'x86_64' and sys_platform == 'darwin') or (python_full_version < '3.12' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (platform_machine != 'x86_64' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (sys_platform != 'darwin' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda')" }, + { name = "numpy", version = "2.4.6", source = { registry = "https://pypi.org/simple" }, marker = "(python_full_version >= '3.12' and python_full_version < '3.15' and platform_machine == 'x86_64' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (python_full_version >= '3.11' and platform_machine != 'x86_64') or (python_full_version == '3.11.*' and platform_machine == 'x86_64' and sys_platform == 'darwin') or (python_full_version >= '3.15' and platform_machine == 'x86_64' and sys_platform == 'darwin') or (python_full_version >= '3.11' and sys_platform != 'darwin') or (python_full_version < '3.11' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (sys_platform != 'darwin' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda')" }, + { name = "numpy", version = "2.5.0", source = { registry = "https://pypi.org/simple" }, marker = "(python_full_version >= '3.12' and python_full_version < '3.15' and platform_machine == 'x86_64' and sys_platform == 'darwin') or (python_full_version < '3.12' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (python_full_version >= '3.15' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (platform_machine != 'x86_64' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (sys_platform != 'darwin' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda')" }, { name = "pandas", marker = "python_full_version >= '3.11' or (extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda')" }, { name = "pytensor", version = "2.35.1", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.11' or (extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda')" }, { name = "rich", marker = "python_full_version >= '3.11' or (extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda')" }, @@ -5805,10 +5872,10 @@ dependencies = [ { name = "arviz-stats", version = "0.8.0", source = { registry = "https://pypi.org/simple" }, extra = ["xarray"], marker = "python_full_version == '3.11.*' or (extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda')" }, { name = "arviz-stats", version = "1.2.0", source = { registry = "https://pypi.org/simple" }, extra = ["xarray"], marker = "python_full_version >= '3.12' or (extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda')" }, { name = "matplotlib", version = "3.11.0", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.11' or (extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda')" }, - { name = "numba", version = "0.47.0", source = { registry = "https://pypi.org/simple" }, marker = "(python_full_version >= '3.12' and platform_machine == 'x86_64' and sys_platform == 'darwin') or (python_full_version < '3.12' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (platform_machine != 'x86_64' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (sys_platform != 'darwin' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda')" }, - { name = "numba", version = "0.66.0", source = { registry = "https://pypi.org/simple" }, marker = "(python_full_version >= '3.11' and platform_machine != 'x86_64') or (python_full_version == '3.11.*' and platform_machine == 'x86_64' and sys_platform == 'darwin') or (python_full_version < '3.11' and platform_machine != 'x86_64' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (python_full_version != '3.11.*' and platform_machine == 'x86_64' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (python_full_version >= '3.11' and sys_platform != 'darwin') or (sys_platform != 'darwin' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda')" }, - { name = "numpy", version = "2.4.6", source = { registry = "https://pypi.org/simple" }, marker = "(python_full_version >= '3.11' and platform_machine != 'x86_64') or (python_full_version == '3.11.*' and platform_machine == 'x86_64' and sys_platform == 'darwin') or (python_full_version < '3.11' and platform_machine != 'x86_64' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (python_full_version != '3.11.*' and platform_machine == 'x86_64' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (python_full_version >= '3.11' and sys_platform != 'darwin') or (sys_platform != 'darwin' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda')" }, - { name = "numpy", version = "2.5.0", source = { registry = "https://pypi.org/simple" }, marker = "(python_full_version >= '3.12' and platform_machine == 'x86_64' and sys_platform == 'darwin') or (python_full_version < '3.12' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (platform_machine != 'x86_64' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (sys_platform != 'darwin' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda')" }, + { name = "numba", version = "0.47.0", source = { registry = "https://pypi.org/simple" }, marker = "(python_full_version >= '3.12' and python_full_version < '3.15' and platform_machine == 'x86_64' and sys_platform == 'darwin') or (python_full_version < '3.12' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (python_full_version >= '3.15' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (platform_machine != 'x86_64' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (sys_platform != 'darwin' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda')" }, + { name = "numba", version = "0.66.0", source = { registry = "https://pypi.org/simple" }, marker = "(python_full_version >= '3.12' and python_full_version < '3.15' and platform_machine == 'x86_64' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (python_full_version >= '3.11' and platform_machine != 'x86_64') or (python_full_version == '3.11.*' and platform_machine == 'x86_64' and sys_platform == 'darwin') or (python_full_version >= '3.15' and platform_machine == 'x86_64' and sys_platform == 'darwin') or (python_full_version >= '3.11' and sys_platform != 'darwin') or (python_full_version < '3.11' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (sys_platform != 'darwin' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda')" }, + { name = "numpy", version = "2.4.6", source = { registry = "https://pypi.org/simple" }, marker = "(python_full_version >= '3.12' and python_full_version < '3.15' and platform_machine == 'x86_64' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (python_full_version >= '3.11' and platform_machine != 'x86_64') or (python_full_version == '3.11.*' and platform_machine == 'x86_64' and sys_platform == 'darwin') or (python_full_version >= '3.15' and platform_machine == 'x86_64' and sys_platform == 'darwin') or (python_full_version >= '3.11' and sys_platform != 'darwin') or (python_full_version < '3.11' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (sys_platform != 'darwin' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda')" }, + { name = "numpy", version = "2.5.0", source = { registry = "https://pypi.org/simple" }, marker = "(python_full_version >= '3.12' and python_full_version < '3.15' and platform_machine == 'x86_64' and sys_platform == 'darwin') or (python_full_version < '3.12' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (python_full_version >= '3.15' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (platform_machine != 'x86_64' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (sys_platform != 'darwin' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda')" }, { name = "pymc", version = "5.26.1", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.11' or (extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda')" }, ] sdist = { url = "https://files.pythonhosted.org/packages/ac/d1/0de1909cc35f7b5df98fa5bd93585f1489a1bb59161d10e023acfa7c6c59/pymc_bart-0.11.0.tar.gz", hash = "sha256:fc107a29f12c7a4345fca33ae3fda5208da4788e0f5e776a37a71cb871097d95", size = 43418, upload-time = "2025-10-21T10:27:59.548Z" } @@ -6027,8 +6094,8 @@ dependencies = [ { name = "filelock", marker = "python_full_version >= '3.11' or (extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda')" }, { name = "logical-unification", marker = "python_full_version >= '3.11' or (extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda')" }, { name = "minikanren", marker = "python_full_version >= '3.11' or (extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda')" }, - { name = "numpy", version = "2.4.6", source = { registry = "https://pypi.org/simple" }, marker = "(python_full_version >= '3.11' and platform_machine != 'x86_64') or (python_full_version == '3.11.*' and platform_machine == 'x86_64' and sys_platform == 'darwin') or (python_full_version < '3.11' and platform_machine != 'x86_64' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (python_full_version != '3.11.*' and platform_machine == 'x86_64' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (python_full_version >= '3.11' and sys_platform != 'darwin') or (sys_platform != 'darwin' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda')" }, - { name = "numpy", version = "2.5.0", source = { registry = "https://pypi.org/simple" }, marker = "(python_full_version >= '3.12' and platform_machine == 'x86_64' and sys_platform == 'darwin') or (python_full_version < '3.12' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (platform_machine != 'x86_64' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (sys_platform != 'darwin' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda')" }, + { name = "numpy", version = "2.4.6", source = { registry = "https://pypi.org/simple" }, marker = "(python_full_version >= '3.12' and python_full_version < '3.15' and platform_machine == 'x86_64' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (python_full_version >= '3.11' and platform_machine != 'x86_64') or (python_full_version == '3.11.*' and platform_machine == 'x86_64' and sys_platform == 'darwin') or (python_full_version >= '3.15' and platform_machine == 'x86_64' and sys_platform == 'darwin') or (python_full_version >= '3.11' and sys_platform != 'darwin') or (python_full_version < '3.11' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (sys_platform != 'darwin' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda')" }, + { name = "numpy", version = "2.5.0", source = { registry = "https://pypi.org/simple" }, marker = "(python_full_version >= '3.12' and python_full_version < '3.15' and platform_machine == 'x86_64' and sys_platform == 'darwin') or (python_full_version < '3.12' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (python_full_version >= '3.15' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (platform_machine != 'x86_64' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (sys_platform != 'darwin' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda')" }, { name = "scipy", version = "1.17.1", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version == '3.11.*' or (extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda')" }, { name = "scipy", version = "1.18.0", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.12' or (extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda')" }, { name = "setuptools", marker = "python_full_version >= '3.11' or (extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda')" }, @@ -6290,8 +6357,8 @@ version = "0.4.2" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "numpy", version = "2.2.6", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.11' or (extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda')" }, - { name = "numpy", version = "2.4.6", source = { registry = "https://pypi.org/simple" }, marker = "(python_full_version >= '3.11' and platform_machine != 'x86_64') or (python_full_version == '3.11.*' and platform_machine == 'x86_64' and sys_platform == 'darwin') or (python_full_version < '3.11' and platform_machine != 'x86_64' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (python_full_version != '3.11.*' and platform_machine == 'x86_64' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (python_full_version >= '3.11' and sys_platform != 'darwin') or (sys_platform != 'darwin' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda')" }, - { name = "numpy", version = "2.5.0", source = { registry = "https://pypi.org/simple" }, marker = "(python_full_version >= '3.12' and platform_machine == 'x86_64' and sys_platform == 'darwin') or (python_full_version < '3.12' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (platform_machine != 'x86_64' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (sys_platform != 'darwin' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda')" }, + { name = "numpy", version = "2.4.6", source = { registry = "https://pypi.org/simple" }, marker = "(python_full_version >= '3.12' and python_full_version < '3.15' and platform_machine == 'x86_64' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (python_full_version >= '3.11' and platform_machine != 'x86_64') or (python_full_version == '3.11.*' and platform_machine == 'x86_64' and sys_platform == 'darwin') or (python_full_version >= '3.15' and platform_machine == 'x86_64' and sys_platform == 'darwin') or (python_full_version >= '3.11' and sys_platform != 'darwin') or (python_full_version < '3.11' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (sys_platform != 'darwin' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda')" }, + { name = "numpy", version = "2.5.0", source = { registry = "https://pypi.org/simple" }, marker = "(python_full_version >= '3.12' and python_full_version < '3.15' and platform_machine == 'x86_64' and sys_platform == 'darwin') or (python_full_version < '3.12' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (python_full_version >= '3.15' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (platform_machine != 'x86_64' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (sys_platform != 'darwin' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda')" }, { name = "pandas" }, { name = "requests" }, { name = "scikit-learn" }, @@ -6939,8 +7006,8 @@ dependencies = [ { name = "colorama" }, { name = "lxml" }, { name = "numpy", version = "2.2.6", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.11' or (extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda')" }, - { name = "numpy", version = "2.4.6", source = { registry = "https://pypi.org/simple" }, marker = "(python_full_version >= '3.11' and platform_machine != 'x86_64') or (python_full_version == '3.11.*' and platform_machine == 'x86_64' and sys_platform == 'darwin') or (python_full_version < '3.11' and platform_machine != 'x86_64' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (python_full_version != '3.11.*' and platform_machine == 'x86_64' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (python_full_version >= '3.11' and sys_platform != 'darwin') or (sys_platform != 'darwin' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda')" }, - { name = "numpy", version = "2.5.0", source = { registry = "https://pypi.org/simple" }, marker = "(python_full_version >= '3.12' and platform_machine == 'x86_64' and sys_platform == 'darwin') or (python_full_version < '3.12' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (platform_machine != 'x86_64' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (sys_platform != 'darwin' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda')" }, + { name = "numpy", version = "2.4.6", source = { registry = "https://pypi.org/simple" }, marker = "(python_full_version >= '3.12' and python_full_version < '3.15' and platform_machine == 'x86_64' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (python_full_version >= '3.11' and platform_machine != 'x86_64') or (python_full_version == '3.11.*' and platform_machine == 'x86_64' and sys_platform == 'darwin') or (python_full_version >= '3.15' and platform_machine == 'x86_64' and sys_platform == 'darwin') or (python_full_version >= '3.11' and sys_platform != 'darwin') or (python_full_version < '3.11' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (sys_platform != 'darwin' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda')" }, + { name = "numpy", version = "2.5.0", source = { registry = "https://pypi.org/simple" }, marker = "(python_full_version >= '3.12' and python_full_version < '3.15' and platform_machine == 'x86_64' and sys_platform == 'darwin') or (python_full_version < '3.12' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (python_full_version >= '3.15' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (platform_machine != 'x86_64' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (sys_platform != 'darwin' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda')" }, { name = "portalocker" }, { name = "regex" }, { name = "tabulate" }, @@ -7061,8 +7128,8 @@ dependencies = [ { name = "imageio", marker = "python_full_version >= '3.11' or (extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda')" }, { name = "lazy-loader", marker = "python_full_version >= '3.11' or (extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda')" }, { name = "networkx", version = "3.6.1", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.11' or (extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda')" }, - { name = "numpy", version = "2.4.6", source = { registry = "https://pypi.org/simple" }, marker = "(python_full_version >= '3.11' and platform_machine != 'x86_64') or (python_full_version == '3.11.*' and platform_machine == 'x86_64' and sys_platform == 'darwin') or (python_full_version < '3.11' and platform_machine != 'x86_64' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (python_full_version != '3.11.*' and platform_machine == 'x86_64' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (python_full_version >= '3.11' and sys_platform != 'darwin') or (sys_platform != 'darwin' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda')" }, - { name = "numpy", version = "2.5.0", source = { registry = "https://pypi.org/simple" }, marker = "(python_full_version >= '3.12' and platform_machine == 'x86_64' and sys_platform == 'darwin') or (python_full_version < '3.12' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (platform_machine != 'x86_64' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (sys_platform != 'darwin' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda')" }, + { name = "numpy", version = "2.4.6", source = { registry = "https://pypi.org/simple" }, marker = "(python_full_version >= '3.12' and python_full_version < '3.15' and platform_machine == 'x86_64' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (python_full_version >= '3.11' and platform_machine != 'x86_64') or (python_full_version == '3.11.*' and platform_machine == 'x86_64' and sys_platform == 'darwin') or (python_full_version >= '3.15' and platform_machine == 'x86_64' and sys_platform == 'darwin') or (python_full_version >= '3.11' and sys_platform != 'darwin') or (python_full_version < '3.11' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (sys_platform != 'darwin' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda')" }, + { name = "numpy", version = "2.5.0", source = { registry = "https://pypi.org/simple" }, marker = "(python_full_version >= '3.12' and python_full_version < '3.15' and platform_machine == 'x86_64' and sys_platform == 'darwin') or (python_full_version < '3.12' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (python_full_version >= '3.15' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (platform_machine != 'x86_64' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (sys_platform != 'darwin' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda')" }, { name = "packaging", marker = "python_full_version >= '3.11' or (extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda')" }, { name = "pillow", marker = "python_full_version >= '3.11' or (extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda')" }, { name = "scipy", version = "1.17.1", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version == '3.11.*' or (extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda')" }, @@ -7129,8 +7196,8 @@ source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "joblib" }, { name = "numpy", version = "2.2.6", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.11' or (extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda')" }, - { name = "numpy", version = "2.4.6", source = { registry = "https://pypi.org/simple" }, marker = "(python_full_version >= '3.11' and platform_machine != 'x86_64') or (python_full_version == '3.11.*' and platform_machine == 'x86_64' and sys_platform == 'darwin') or (python_full_version < '3.11' and platform_machine != 'x86_64' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (python_full_version != '3.11.*' and platform_machine == 'x86_64' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (python_full_version >= '3.11' and sys_platform != 'darwin') or (sys_platform != 'darwin' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda')" }, - { name = "numpy", version = "2.5.0", source = { registry = "https://pypi.org/simple" }, marker = "(python_full_version >= '3.12' and platform_machine == 'x86_64' and sys_platform == 'darwin') or (python_full_version < '3.12' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (platform_machine != 'x86_64' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (sys_platform != 'darwin' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda')" }, + { name = "numpy", version = "2.4.6", source = { registry = "https://pypi.org/simple" }, marker = "(python_full_version >= '3.12' and python_full_version < '3.15' and platform_machine == 'x86_64' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (python_full_version >= '3.11' and platform_machine != 'x86_64') or (python_full_version == '3.11.*' and platform_machine == 'x86_64' and sys_platform == 'darwin') or (python_full_version >= '3.15' and platform_machine == 'x86_64' and sys_platform == 'darwin') or (python_full_version >= '3.11' and sys_platform != 'darwin') or (python_full_version < '3.11' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (sys_platform != 'darwin' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda')" }, + { name = "numpy", version = "2.5.0", source = { registry = "https://pypi.org/simple" }, marker = "(python_full_version >= '3.12' and python_full_version < '3.15' and platform_machine == 'x86_64' and sys_platform == 'darwin') or (python_full_version < '3.12' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (python_full_version >= '3.15' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (platform_machine != 'x86_64' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (sys_platform != 'darwin' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda')" }, { name = "scipy", version = "1.15.3", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.11' or (extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda')" }, { name = "scipy", version = "1.17.1", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version == '3.11.*' or (extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda')" }, { name = "scipy", version = "1.18.0", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.12' or (extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda')" }, @@ -7344,8 +7411,8 @@ resolution-markers = [ "(python_full_version == '3.12.*' and platform_machine != 'x86_64' and extra != 'extra-6-dashai-cpu' and extra != 'extra-6-dashai-cuda') or (python_full_version == '3.12.*' and sys_platform != 'darwin' and extra != 'extra-6-dashai-cpu' and extra != 'extra-6-dashai-cuda')", ] dependencies = [ - { name = "numpy", version = "2.4.6", source = { registry = "https://pypi.org/simple" }, marker = "(python_full_version >= '3.12' and platform_machine != 'x86_64') or (python_full_version < '3.12' and platform_machine != 'x86_64' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (python_full_version >= '3.12' and sys_platform != 'darwin') or (platform_machine == 'x86_64' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (sys_platform != 'darwin' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda')" }, - { name = "numpy", version = "2.5.0", source = { registry = "https://pypi.org/simple" }, marker = "(python_full_version >= '3.12' and platform_machine == 'x86_64' and sys_platform == 'darwin') or (python_full_version < '3.12' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (platform_machine != 'x86_64' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (sys_platform != 'darwin' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda')" }, + { name = "numpy", version = "2.4.6", source = { registry = "https://pypi.org/simple" }, marker = "(python_full_version >= '3.12' and platform_machine != 'x86_64') or (python_full_version >= '3.15' and platform_machine == 'x86_64' and sys_platform == 'darwin') or (python_full_version < '3.12' and platform_machine != 'x86_64' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (python_full_version < '3.15' and platform_machine == 'x86_64' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (python_full_version >= '3.12' and sys_platform != 'darwin') or (sys_platform != 'darwin' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda')" }, + { name = "numpy", version = "2.5.0", source = { registry = "https://pypi.org/simple" }, marker = "(python_full_version >= '3.12' and python_full_version < '3.15' and platform_machine == 'x86_64' and sys_platform == 'darwin') or (python_full_version < '3.12' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (python_full_version >= '3.15' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (platform_machine != 'x86_64' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (sys_platform != 'darwin' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda')" }, ] sdist = { url = "https://files.pythonhosted.org/packages/a7/25/c2700dfaf6442b4effaa91af24ebce5dc9d31bb4a69706313aae70d72cd0/scipy-1.18.0.tar.gz", hash = "sha256:67b2ad2ad54c72ca6d04975a9b2df8c3638c34ddd5b28738e94fc2b57929d378", size = 30774447, upload-time = "2026-06-19T15:01:43.456Z" } wheels = [ @@ -7479,66 +7546,62 @@ wheels = [ [[package]] name = "shap" -version = "0.46.0" +version = "0.49.1" source = { registry = "https://pypi.org/simple" } resolution-markers = [ "python_full_version >= '3.15' and platform_machine == 'x86_64' and sys_platform == 'darwin' and extra != 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda'", - "python_full_version == '3.14.*' and platform_machine == 'x86_64' and sys_platform == 'darwin' and extra != 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda'", - "python_full_version == '3.13.*' and platform_machine == 'x86_64' and sys_platform == 'darwin' and extra != 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda'", - "python_full_version == '3.12.*' and platform_machine == 'x86_64' and sys_platform == 'darwin' and extra != 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda'", "python_full_version == '3.11.*' and extra != 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda'", "python_full_version < '3.11' and extra != 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda'", "python_full_version >= '3.15' and platform_machine == 'x86_64' and sys_platform == 'darwin' and extra == 'extra-6-dashai-cpu' and extra != 'extra-6-dashai-cuda'", - "python_full_version == '3.14.*' and platform_machine == 'x86_64' and sys_platform == 'darwin' and extra == 'extra-6-dashai-cpu' and extra != 'extra-6-dashai-cuda'", - "python_full_version == '3.13.*' and platform_machine == 'x86_64' and sys_platform == 'darwin' and extra == 'extra-6-dashai-cpu' and extra != 'extra-6-dashai-cuda'", - "python_full_version == '3.12.*' and platform_machine == 'x86_64' and sys_platform == 'darwin' and extra == 'extra-6-dashai-cpu' and extra != 'extra-6-dashai-cuda'", "python_full_version == '3.11.*' and sys_platform != 'darwin' and extra == 'extra-6-dashai-cpu' and extra != 'extra-6-dashai-cuda'", "python_full_version == '3.11.*' and sys_platform == 'darwin' and extra == 'extra-6-dashai-cpu' and extra != 'extra-6-dashai-cuda'", "python_full_version < '3.11' and sys_platform != 'darwin' and extra == 'extra-6-dashai-cpu' and extra != 'extra-6-dashai-cuda'", "python_full_version < '3.11' and sys_platform == 'darwin' and extra == 'extra-6-dashai-cpu' and extra != 'extra-6-dashai-cuda'", "python_full_version >= '3.15' and platform_machine == 'x86_64' and sys_platform == 'darwin' and extra != 'extra-6-dashai-cpu' and extra != 'extra-6-dashai-cuda'", - "python_full_version == '3.14.*' and platform_machine == 'x86_64' and sys_platform == 'darwin' and extra != 'extra-6-dashai-cpu' and extra != 'extra-6-dashai-cuda'", - "python_full_version == '3.13.*' and platform_machine == 'x86_64' and sys_platform == 'darwin' and extra != 'extra-6-dashai-cpu' and extra != 'extra-6-dashai-cuda'", - "python_full_version == '3.12.*' and platform_machine == 'x86_64' and sys_platform == 'darwin' and extra != 'extra-6-dashai-cpu' and extra != 'extra-6-dashai-cuda'", "python_full_version == '3.11.*' and extra != 'extra-6-dashai-cpu' and extra != 'extra-6-dashai-cuda'", "python_full_version < '3.11' and extra != 'extra-6-dashai-cpu' and extra != 'extra-6-dashai-cuda'", ] dependencies = [ - { name = "cloudpickle", marker = "(python_full_version < '3.12' and platform_machine != 'x86_64') or (python_full_version < '3.12' and sys_platform != 'darwin') or (platform_machine == 'x86_64' and sys_platform == 'darwin') or (platform_machine != 'x86_64' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (sys_platform != 'darwin' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda')" }, - { name = "numba", version = "0.47.0", source = { registry = "https://pypi.org/simple" }, marker = "(python_full_version >= '3.12' and platform_machine == 'x86_64' and sys_platform == 'darwin') or (python_full_version < '3.12' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (platform_machine != 'x86_64' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (sys_platform != 'darwin' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda')" }, - { name = "numba", version = "0.66.0", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.12' or (extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda')" }, + { name = "cloudpickle", marker = "python_full_version < '3.12' or (python_full_version >= '3.15' and platform_machine == 'x86_64' and sys_platform == 'darwin') or (python_full_version < '3.15' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (platform_machine != 'x86_64' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (sys_platform != 'darwin' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda')" }, + { name = "numba", version = "0.66.0", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.12' or (python_full_version >= '3.15' and platform_machine == 'x86_64' and sys_platform == 'darwin') or (python_full_version < '3.15' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (platform_machine != 'x86_64' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (sys_platform != 'darwin' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda')" }, { name = "numpy", version = "2.2.6", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.11' or (extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda')" }, - { name = "numpy", version = "2.4.6", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version == '3.11.*' or (extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda')" }, - { name = "numpy", version = "2.5.0", source = { registry = "https://pypi.org/simple" }, marker = "(python_full_version >= '3.12' and platform_machine == 'x86_64' and sys_platform == 'darwin') or (python_full_version < '3.12' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (platform_machine != 'x86_64' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (sys_platform != 'darwin' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda')" }, - { name = "packaging", marker = "(python_full_version < '3.12' and platform_machine != 'x86_64') or (python_full_version < '3.12' and sys_platform != 'darwin') or (platform_machine == 'x86_64' and sys_platform == 'darwin') or (platform_machine != 'x86_64' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (sys_platform != 'darwin' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda')" }, - { name = "pandas", marker = "(python_full_version < '3.12' and platform_machine != 'x86_64') or (python_full_version < '3.12' and sys_platform != 'darwin') or (platform_machine == 'x86_64' and sys_platform == 'darwin') or (platform_machine != 'x86_64' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (sys_platform != 'darwin' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda')" }, - { name = "scikit-learn", marker = "(python_full_version < '3.12' and platform_machine != 'x86_64') or (python_full_version < '3.12' and sys_platform != 'darwin') or (platform_machine == 'x86_64' and sys_platform == 'darwin') or (platform_machine != 'x86_64' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (sys_platform != 'darwin' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda')" }, + { name = "numpy", version = "2.4.6", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version == '3.11.*' or (python_full_version >= '3.12' and python_full_version < '3.15' and platform_machine == 'x86_64' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (python_full_version >= '3.15' and platform_machine == 'x86_64' and sys_platform == 'darwin') or (python_full_version != '3.11.*' and platform_machine != 'x86_64' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (python_full_version < '3.11' and platform_machine == 'x86_64' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (sys_platform != 'darwin' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda')" }, + { name = "packaging", marker = "python_full_version < '3.12' or (python_full_version >= '3.15' and platform_machine == 'x86_64' and sys_platform == 'darwin') or (python_full_version < '3.15' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (platform_machine != 'x86_64' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (sys_platform != 'darwin' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda')" }, + { name = "pandas", marker = "python_full_version < '3.12' or (python_full_version >= '3.15' and platform_machine == 'x86_64' and sys_platform == 'darwin') or (python_full_version < '3.15' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (platform_machine != 'x86_64' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (sys_platform != 'darwin' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda')" }, + { name = "scikit-learn", marker = "python_full_version < '3.12' or (python_full_version >= '3.15' and platform_machine == 'x86_64' and sys_platform == 'darwin') or (python_full_version < '3.15' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (platform_machine != 'x86_64' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (sys_platform != 'darwin' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda')" }, { name = "scipy", version = "1.15.3", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.11' or (extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda')" }, { name = "scipy", version = "1.17.1", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version == '3.11.*' or (extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda')" }, - { name = "scipy", version = "1.18.0", source = { registry = "https://pypi.org/simple" }, marker = "(python_full_version >= '3.12' and platform_machine == 'x86_64' and sys_platform == 'darwin') or (python_full_version < '3.12' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (platform_machine != 'x86_64' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (sys_platform != 'darwin' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda')" }, - { name = "slicer", marker = "(python_full_version < '3.12' and platform_machine != 'x86_64') or (python_full_version < '3.12' and sys_platform != 'darwin') or (platform_machine == 'x86_64' and sys_platform == 'darwin') or (platform_machine != 'x86_64' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (sys_platform != 'darwin' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda')" }, - { name = "tqdm", marker = "(python_full_version < '3.12' and platform_machine != 'x86_64') or (python_full_version < '3.12' and sys_platform != 'darwin') or (platform_machine == 'x86_64' and sys_platform == 'darwin') or (platform_machine != 'x86_64' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (sys_platform != 'darwin' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda')" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/47/46/1b497452be642e19af56044814dfe32ee795805b443378821136729017a0/shap-0.46.0.tar.gz", hash = "sha256:bdaa5b098be5a958348015e940f6fd264339b5db1e651f9898a3117be95b05a0", size = 1214102, upload-time = "2024-06-27T10:17:22.263Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/13/a8/97442ec8e7aaad01d860768232b3b7051adb0560a9c79e52ce5e1222cbf1/shap-0.46.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:905b2d7a0262ef820785a7c0e3c7f24c9d281e6f934edb65cbe811fe0e971187", size = 459332, upload-time = "2024-06-27T10:16:34.71Z" }, - { url = "https://files.pythonhosted.org/packages/00/b3/2795a586a4446c8cbf04b6e8f15c19b4a6fb867e5c6cf9fcbca97d56a20b/shap-0.46.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:bccbb30ffbf8b9ed53e476d0c1319fdfcbeac455fe9df277fb0d570d92790e80", size = 455839, upload-time = "2024-06-27T10:16:37.654Z" }, - { url = "https://files.pythonhosted.org/packages/13/a6/b75760a52664dd82d530f9e232918bb74d1d6c39abcf34523c4f75cd4264/shap-0.46.0-cp310-cp310-manylinux_2_12_x86_64.manylinux2010_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9633d3d7174acc01455538169ca6e6344f570530384548631aeadcf7bfdaaaea", size = 540067, upload-time = "2024-06-27T10:16:39.713Z" }, - { url = "https://files.pythonhosted.org/packages/35/13/70e07364855b05d8aa628ec5aec4f038444ede0e26eee2be00c38077ee72/shap-0.46.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c6097eb2ab7e8c194254bac3e462266490fbdd43bfe35a1014e9ee21c4ef10ee", size = 537808, upload-time = "2024-06-27T10:16:41.955Z" }, - { url = "https://files.pythonhosted.org/packages/b4/fc/dd28e6838630cd436914116aa07a019753a40b956a05831b71bd3f7ce914/shap-0.46.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:0cf7c6e3f056cf3bfd16bcfd5744d0cc25b851555b1e750a3ab889b3077d2d05", size = 1538235, upload-time = "2024-06-27T10:16:43.681Z" }, - { url = "https://files.pythonhosted.org/packages/ae/fe/f9e4d5e002bb58047c81edb6448579c179925c3807c98589ee70953587ab/shap-0.46.0-cp310-cp310-win_amd64.whl", hash = "sha256:949bd7fa40371c3f1885a30ae0611dd481bf4ac90066ff726c73cb5bb393032b", size = 456103, upload-time = "2024-06-27T10:16:46.764Z" }, - { url = "https://files.pythonhosted.org/packages/e5/a1/43bd69f32ddf381a09de18ea94d4b215d5ced3a24ff1a7b7d1a9401b5b85/shap-0.46.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:f18217c98f39fd485d541f6aab0b860b3be74b69b21d4faf11959e3fcba765c5", size = 459333, upload-time = "2024-06-27T10:16:48.872Z" }, - { url = "https://files.pythonhosted.org/packages/5f/9e/dce41d5ec9e79add65faf4381d8d4492247b29daaa6cc7d7fd0298abc1e2/shap-0.46.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:5bbdae4489577c6fce1cfe2d9d8f3d5b96d69284d29645fe651f78f6e965aeb4", size = 455835, upload-time = "2024-06-27T10:16:51.074Z" }, - { url = "https://files.pythonhosted.org/packages/06/6a/09e3cb9864118337c0f3c2a0dc5add6b642e9f672665062e186d67ba992d/shap-0.46.0-cp311-cp311-manylinux_2_12_x86_64.manylinux2010_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:13d36dc58d1e8c010feb4e7da71c77d23626a52d12d16b02869e793b11be4695", size = 540163, upload-time = "2024-06-27T10:16:53.179Z" }, - { url = "https://files.pythonhosted.org/packages/c3/74/440eacbdf21c1b2e0a5b6962b79d4435e56a88588043d144a16c7785a596/shap-0.46.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:70e06fdfdf53d5fb932c82f4529397552b262e0ccce734f5226fb1e1eab2bc3e", size = 537765, upload-time = "2024-06-27T10:16:54.763Z" }, - { url = "https://files.pythonhosted.org/packages/08/e6/027ca36efcc8871eda4084bde5e4658a90e84006086186e39588fd03b396/shap-0.46.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:943f0806fa00b4fafb174f172a73d88de2d8600e6d69c2e2bff833f00e6c4c21", size = 1538290, upload-time = "2024-06-27T10:16:56.819Z" }, - { url = "https://files.pythonhosted.org/packages/82/29/923869e92c74bf07ec2b9a52ad5ac67d4184c873ba33ada7d4584356463a/shap-0.46.0-cp311-cp311-win_amd64.whl", hash = "sha256:c972a2efdc9fc00d543efaa55805eca947b8c418d065962d967824c2d5d295d0", size = 456103, upload-time = "2024-06-27T10:16:58.433Z" }, - { url = "https://files.pythonhosted.org/packages/05/c5/3c4fe600dd71fd2785d21f86a3e7f1f13de60c9b434052e05ba17598f81e/shap-0.46.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:a9cc9be191562bea1a782baff912854d267c6f4831bbf454d8d7bb7df7ddb214", size = 459316, upload-time = "2024-06-27T10:17:00.313Z" }, - { url = "https://files.pythonhosted.org/packages/4d/1a/c00a1e7a68a4af29f2b40c8a8740dd241cba6cc58cd6ac266956a954a41d/shap-0.46.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:ab1fecfb43604605be17e26ae12bde4406c451c46b54b980d9570cec03fbc239", size = 455333, upload-time = "2024-06-27T10:17:02.719Z" }, - { url = "https://files.pythonhosted.org/packages/7f/0a/e3ab0dcddf4db1158fbf0d6c96348ba5f3031275f59088e0e3b7630cdcde/shap-0.46.0-cp312-cp312-manylinux_2_12_x86_64.manylinux2010_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b216adf2a17b0e0694f17965ac29354ca8c4f27ac3c66f68bf6fc4cb2aa28207", size = 543894, upload-time = "2024-06-27T10:17:04.941Z" }, - { url = "https://files.pythonhosted.org/packages/8f/8f/ca077689b76161b51b420031b88948ef92ade55730e85490215222734729/shap-0.46.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b6e5dc5257b747a784f7a9b3acb64216a9011f01734f3c96b27fe5e15ae5f99f", size = 540735, upload-time = "2024-06-27T10:17:06.61Z" }, - { url = "https://files.pythonhosted.org/packages/6e/b6/169de0d8971c91decd3dacfd63edeeedfc1bba30bfc6abf8480142aafd48/shap-0.46.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:1230bf973463041dfa15734f290fbf3ab9c6e4e8222339c76f68fc355b940d80", size = 1537953, upload-time = "2024-06-27T10:17:08.225Z" }, - { url = "https://files.pythonhosted.org/packages/04/58/b2ea558ec8d9ed3728e83dfacb1b920c54a1a1f6feee2632c04676c3c1e9/shap-0.46.0-cp312-cp312-win_amd64.whl", hash = "sha256:0cbbf996537b2a42d3bc7f2a13492988822ee1bfd7220700989408dfb9e1c5ad", size = 456226, upload-time = "2024-06-27T10:17:10.589Z" }, + { name = "scipy", version = "1.18.0", source = { registry = "https://pypi.org/simple" }, marker = "(python_full_version >= '3.15' and platform_machine == 'x86_64' and sys_platform == 'darwin') or (python_full_version < '3.15' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (platform_machine != 'x86_64' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (sys_platform != 'darwin' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda')" }, + { name = "slicer", marker = "python_full_version < '3.12' or (python_full_version >= '3.15' and platform_machine == 'x86_64' and sys_platform == 'darwin') or (python_full_version < '3.15' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (platform_machine != 'x86_64' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (sys_platform != 'darwin' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda')" }, + { name = "tqdm", marker = "python_full_version < '3.12' or (python_full_version >= '3.15' and platform_machine == 'x86_64' and sys_platform == 'darwin') or (python_full_version < '3.15' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (platform_machine != 'x86_64' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (sys_platform != 'darwin' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda')" }, + { name = "typing-extensions", marker = "python_full_version < '3.12' or (python_full_version >= '3.15' and platform_machine == 'x86_64' and sys_platform == 'darwin') or (python_full_version < '3.15' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (platform_machine != 'x86_64' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (sys_platform != 'darwin' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda')" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/dc/c6/9823a7f483aa9f3179fc359c10d22da9e418b1a7a3fc99a42b705d05e82a/shap-0.49.1.tar.gz", hash = "sha256:1114ecd804fff29f50d522ce6031082fcf42fe4a32fb1b5da233b2415d784c8c", size = 4084725, upload-time = "2025-10-14T10:04:49.75Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/15/a1/66b4f04995ee23ff8638c21294f1a3a6dc87397af54c87aeeb037500f71f/shap-0.49.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:40140ec5d306719f89daee1df27805a71bcc1ac39630832455d316d0306d1283", size = 558950, upload-time = "2025-10-14T10:04:08.441Z" }, + { url = "https://files.pythonhosted.org/packages/06/76/2142615fa5cc745fd66beb066d00db123cc86d614a31ca8029b29537a959/shap-0.49.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:6e9977f1e0b6bba57967de600e8e6047b3e4643d06a4671f2dba1a97c1b5ab3e", size = 556605, upload-time = "2025-10-14T10:04:10.049Z" }, + { url = "https://files.pythonhosted.org/packages/a8/3a/e28014ffc23f386da3d69abd978838e653fff5641831e5a34aade3f4dfe7/shap-0.49.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:54ad4c38e6af56eaa1c892bb3af550a35df15ca0d27d2d41c1d1619ca6a2ba75", size = 1000329, upload-time = "2025-10-14T10:04:11.359Z" }, + { url = "https://files.pythonhosted.org/packages/bd/09/734325f0a9ab9d3dfa5c0908a927027b3d95b3f6929bb62d88e840b85abf/shap-0.49.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fcd832e97038648ba89f659863322d5cd3ea0815e18c36dd48cd7ae1ca9f264b", size = 1000713, upload-time = "2025-10-14T10:04:12.573Z" }, + { url = "https://files.pythonhosted.org/packages/e9/a2/0518acabb104e21fecda65b0202e41edd06637c44dac15e2197e7d13a002/shap-0.49.1-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:7fc2e864908277dca2b1d9c59a18b3f31576b985bd024f39b0c3cb7e2c7441db", size = 2065477, upload-time = "2025-10-14T10:04:13.874Z" }, + { url = "https://files.pythonhosted.org/packages/af/e1/3d52717b617b9ad1e4d0c9634d3b7c52a913540fde27c4b4663a7ee76b87/shap-0.49.1-cp310-cp310-win_amd64.whl", hash = "sha256:4f5bec3d061b4f4889e1ac4e9b676aede2875778ff44b9d5f5a844cbe6788fd2", size = 547034, upload-time = "2025-10-14T10:04:16.17Z" }, + { url = "https://files.pythonhosted.org/packages/1d/08/d433b7d18a8b51a7d10477120f78877d806d2eb86283cb1661318d865f3d/shap-0.49.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:1e208a0129c721bd0eba6268a9ffac4610dbc8a833d07d2ad9f39541bb737f06", size = 558742, upload-time = "2025-10-14T10:04:17.45Z" }, + { url = "https://files.pythonhosted.org/packages/c2/35/72929fdad25e055aff9dfbeb48c044682fc3b815d90cee4036b90bd65f4c/shap-0.49.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:0b878470bdf6800069c25d2a8598eb0548aa1e6826becd39cca253521cc14866", size = 556486, upload-time = "2025-10-14T10:04:18.934Z" }, + { url = "https://files.pythonhosted.org/packages/02/be/d92623be2c584784e99a8eb9a6cd02263b4eb363c9e49fa14c20f824bcbb/shap-0.49.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:118577d40c53f005268024e59f6a10cbcafbb6d03b3d97dce7c0c7510190ebaa", size = 1025978, upload-time = "2025-10-14T10:04:20.096Z" }, + { url = "https://files.pythonhosted.org/packages/14/e9/e4079b5de26a8269121ce38125e130c147dac7b59611e0bd94be10f9444e/shap-0.49.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f424465699aa2dda8057656c6b6d3cb927cf29b054c5bb01cfffcb9efa5dbf98", size = 1027831, upload-time = "2025-10-14T10:04:21.666Z" }, + { url = "https://files.pythonhosted.org/packages/49/ff/e22e1d899ed56384a2395d6121d6e21833c518c01c5b6c52fce3c0b0cbab/shap-0.49.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:d505834fdf2a159e88b1dcdeddfd79f101fd789ba89d589faf0aaec060c0bad9", size = 2092627, upload-time = "2025-10-14T10:04:22.894Z" }, + { url = "https://files.pythonhosted.org/packages/17/48/bbcd638a391ac0fb30033398a3cca60ba5c36941d962dd74958e67069108/shap-0.49.1-cp311-cp311-win_amd64.whl", hash = "sha256:897c7e6fa98d66482282c8f898c97ade181d714ecaf581da0dab5c49adb9f62c", size = 546845, upload-time = "2025-10-14T10:04:24.238Z" }, + { url = "https://files.pythonhosted.org/packages/92/7a/ccecf7a9158baa10bdc5146907c72dd5f85c762cb5f16cdc74d15cebb8a1/shap-0.49.1-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:c652dc77f1fffe73f5a3def3356c5090e2e6401c261e4fe5329d83cb6251e772", size = 559663, upload-time = "2025-10-14T10:04:25.412Z" }, + { url = "https://files.pythonhosted.org/packages/ee/c6/c43382d6c891fcf067d0a9f6d954351e3c7d330f4328c5816769b796aa27/shap-0.49.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:c23f1493205e648634680c8974e82e7f4b2e96ae3a7eca2251680172bd197ae9", size = 556265, upload-time = "2025-10-14T10:04:27.098Z" }, + { url = "https://files.pythonhosted.org/packages/c0/71/f7db7a5a2cedaa3ac52f58f453172d613be041bedd9509ce5b5cba2096a6/shap-0.49.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:41147740c42821023e1b60185ce8be989656ccac266cc9490d7a8e3ad53c556a", size = 1022419, upload-time = "2025-10-14T10:04:28.793Z" }, + { url = "https://files.pythonhosted.org/packages/c2/a4/96ca9a69dd669ff835ddef875c5dd8e07599103769417d3e9051fd97d470/shap-0.49.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ef9952929d4a7e6763d2716938067bdad762217e3afb46cabfc15a62c012b364", size = 1027074, upload-time = "2025-10-14T10:04:30.2Z" }, + { url = "https://files.pythonhosted.org/packages/fc/9a/89ed1ac8beffe8ff8e09c12cb351bc3c79ddaadcc47ca6ee434d76e464d7/shap-0.49.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:e823417eb0a01947cd9bd763bef2e534c5aef7a7c2952b1badfa969c7d59d3b3", size = 2088172, upload-time = "2025-10-14T10:04:31.725Z" }, + { url = "https://files.pythonhosted.org/packages/4a/28/11422c1c3aa022a06e76cbfa3267e1750cedc00c1e02ef1ccae9c88cd6f4/shap-0.49.1-cp312-cp312-win_amd64.whl", hash = "sha256:cb28043decfec3f35f795421eb5a81545f629b7f60bbf7449cd2843a7f1c8cc6", size = 548036, upload-time = "2025-10-14T10:04:33.087Z" }, + { url = "https://files.pythonhosted.org/packages/e9/5c/030bbfa19605ca4ad66a753d55e76aee5093be6748a6d33eda89e5613995/shap-0.49.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:333cd8e8c427badda92d5ada9e7aad1e3e1e8e7e0398da51a18b7ffb03514e45", size = 558604, upload-time = "2025-10-14T10:04:34.298Z" }, + { url = "https://files.pythonhosted.org/packages/2c/7f/7e7b78e9fac6f891096fb6a59a6d4db23243b0af2369ae54e161f513c485/shap-0.49.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:f4faf61560f73a66f4f26bc027c91f8939201979c4db24949dca305ba0a2ad36", size = 555311, upload-time = "2025-10-14T10:04:35.582Z" }, + { url = "https://files.pythonhosted.org/packages/f2/be/25283a0f8c30deaf897b89a0dbfd490d330f6fc68caa6f19db6e130832e9/shap-0.49.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b440da658d9aee7711bf642c9b4826d81f588fb478cd9e90c068646e90f56669", size = 1016897, upload-time = "2025-10-14T10:04:36.856Z" }, + { url = "https://files.pythonhosted.org/packages/5c/91/a63e563f3dc8e134db12dd155a1a6ed5e0649f79fc8ac651aac1088e8652/shap-0.49.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d8dfa5654eccf4d13dcb262a10314a4e0eb1060db842b2ef31e9fb0038168bc1", size = 1022476, upload-time = "2025-10-14T10:04:38.171Z" }, + { url = "https://files.pythonhosted.org/packages/15/a2/89303c1f7eb206658bf9ec974dc6e69b0a6bd309cf5de0cfa8f92f5a8eb3/shap-0.49.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:ed3080030a6000d3737841c5770ed555b8a922b794fa0ba5aae1e45655eda1fa", size = 2087940, upload-time = "2025-10-14T10:04:39.497Z" }, + { url = "https://files.pythonhosted.org/packages/84/bd/0b9b3e19b9b8cda51463f8a749dc354eb9c87f42eddcbfdf742dceb3746b/shap-0.49.1-cp313-cp313-win_amd64.whl", hash = "sha256:6af779344c23b12a47063aab7fc135fefbdb5849233c1813f11dd8cf2fc73bea", size = 547806, upload-time = "2025-10-14T10:04:40.712Z" }, ] [[package]] @@ -7546,10 +7609,16 @@ name = "shap" version = "0.52.0" source = { registry = "https://pypi.org/simple" } resolution-markers = [ + "python_full_version == '3.14.*' and platform_machine == 'x86_64' and sys_platform == 'darwin' and extra != 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda'", + "python_full_version == '3.13.*' and platform_machine == 'x86_64' and sys_platform == 'darwin' and extra != 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda'", + "python_full_version == '3.12.*' and platform_machine == 'x86_64' and sys_platform == 'darwin' and extra != 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda'", "(python_full_version >= '3.15' and platform_machine != 'x86_64' and extra != 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (python_full_version >= '3.15' and sys_platform != 'darwin' and extra != 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda')", "(python_full_version == '3.14.*' and platform_machine != 'x86_64' and extra != 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (python_full_version == '3.14.*' and sys_platform != 'darwin' and extra != 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda')", "(python_full_version == '3.13.*' and platform_machine != 'x86_64' and extra != 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (python_full_version == '3.13.*' and sys_platform != 'darwin' and extra != 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda')", "(python_full_version == '3.12.*' and platform_machine != 'x86_64' and extra != 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (python_full_version == '3.12.*' and sys_platform != 'darwin' and extra != 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda')", + "python_full_version == '3.14.*' and platform_machine == 'x86_64' and sys_platform == 'darwin' and extra == 'extra-6-dashai-cpu' and extra != 'extra-6-dashai-cuda'", + "python_full_version == '3.13.*' and platform_machine == 'x86_64' and sys_platform == 'darwin' and extra == 'extra-6-dashai-cpu' and extra != 'extra-6-dashai-cuda'", + "python_full_version == '3.12.*' and platform_machine == 'x86_64' and sys_platform == 'darwin' and extra == 'extra-6-dashai-cpu' and extra != 'extra-6-dashai-cuda'", "python_full_version >= '3.15' and sys_platform != 'darwin' and extra == 'extra-6-dashai-cpu' and extra != 'extra-6-dashai-cuda'", "python_full_version == '3.14.*' and sys_platform != 'darwin' and extra == 'extra-6-dashai-cpu' and extra != 'extra-6-dashai-cuda'", "python_full_version == '3.13.*' and sys_platform != 'darwin' and extra == 'extra-6-dashai-cpu' and extra != 'extra-6-dashai-cuda'", @@ -7558,22 +7627,28 @@ resolution-markers = [ "python_full_version == '3.14.*' and platform_machine != 'x86_64' and sys_platform == 'darwin' and extra == 'extra-6-dashai-cpu' and extra != 'extra-6-dashai-cuda'", "python_full_version == '3.13.*' and platform_machine != 'x86_64' and sys_platform == 'darwin' and extra == 'extra-6-dashai-cpu' and extra != 'extra-6-dashai-cuda'", "python_full_version == '3.12.*' and platform_machine != 'x86_64' and sys_platform == 'darwin' and extra == 'extra-6-dashai-cpu' and extra != 'extra-6-dashai-cuda'", + "python_full_version == '3.14.*' and platform_machine == 'x86_64' and sys_platform == 'darwin' and extra != 'extra-6-dashai-cpu' and extra != 'extra-6-dashai-cuda'", + "python_full_version == '3.13.*' and platform_machine == 'x86_64' and sys_platform == 'darwin' and extra != 'extra-6-dashai-cpu' and extra != 'extra-6-dashai-cuda'", + "python_full_version == '3.12.*' and platform_machine == 'x86_64' and sys_platform == 'darwin' and extra != 'extra-6-dashai-cpu' and extra != 'extra-6-dashai-cuda'", "(python_full_version >= '3.15' and platform_machine != 'x86_64' and extra != 'extra-6-dashai-cpu' and extra != 'extra-6-dashai-cuda') or (python_full_version >= '3.15' and sys_platform != 'darwin' and extra != 'extra-6-dashai-cpu' and extra != 'extra-6-dashai-cuda')", "(python_full_version == '3.14.*' and platform_machine != 'x86_64' and extra != 'extra-6-dashai-cpu' and extra != 'extra-6-dashai-cuda') or (python_full_version == '3.14.*' and sys_platform != 'darwin' and extra != 'extra-6-dashai-cpu' and extra != 'extra-6-dashai-cuda')", "(python_full_version == '3.13.*' and platform_machine != 'x86_64' and extra != 'extra-6-dashai-cpu' and extra != 'extra-6-dashai-cuda') or (python_full_version == '3.13.*' and sys_platform != 'darwin' and extra != 'extra-6-dashai-cpu' and extra != 'extra-6-dashai-cuda')", "(python_full_version == '3.12.*' and platform_machine != 'x86_64' and extra != 'extra-6-dashai-cpu' and extra != 'extra-6-dashai-cuda') or (python_full_version == '3.12.*' and sys_platform != 'darwin' and extra != 'extra-6-dashai-cpu' and extra != 'extra-6-dashai-cuda')", ] dependencies = [ - { name = "cloudpickle", marker = "(python_full_version >= '3.12' and platform_machine != 'x86_64') or (python_full_version < '3.12' and platform_machine != 'x86_64' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (python_full_version >= '3.12' and sys_platform != 'darwin') or (platform_machine == 'x86_64' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (sys_platform != 'darwin' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda')" }, - { name = "llvmlite", marker = "(python_full_version >= '3.12' and platform_machine != 'x86_64') or (python_full_version < '3.12' and platform_machine != 'x86_64' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (python_full_version >= '3.12' and sys_platform != 'darwin') or (platform_machine == 'x86_64' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (sys_platform != 'darwin' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda')" }, + { name = "cloudpickle", marker = "(python_full_version >= '3.12' and python_full_version < '3.15') or (python_full_version >= '3.12' and platform_machine != 'x86_64') or (python_full_version >= '3.15' and platform_machine == 'x86_64' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (python_full_version >= '3.12' and sys_platform != 'darwin') or (python_full_version < '3.12' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (sys_platform != 'darwin' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda')" }, + { name = "llvmlite", version = "0.45.1", source = { registry = "https://pypi.org/simple" }, marker = "(python_full_version >= '3.12' and python_full_version < '3.15' and platform_machine == 'x86_64' and sys_platform == 'darwin') or (python_full_version < '3.12' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (python_full_version >= '3.15' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (platform_machine != 'x86_64' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (sys_platform != 'darwin' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda')" }, + { name = "llvmlite", version = "0.48.0", source = { registry = "https://pypi.org/simple" }, marker = "(python_full_version >= '3.12' and platform_machine != 'x86_64') or (python_full_version < '3.12' and platform_machine != 'x86_64' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (python_full_version >= '3.12' and sys_platform != 'darwin') or (platform_machine == 'x86_64' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (sys_platform != 'darwin' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda')" }, + { name = "numba", version = "0.47.0", source = { registry = "https://pypi.org/simple" }, marker = "(python_full_version >= '3.12' and python_full_version < '3.15' and platform_machine == 'x86_64' and sys_platform == 'darwin') or (python_full_version < '3.12' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (python_full_version >= '3.15' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (platform_machine != 'x86_64' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (sys_platform != 'darwin' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda')" }, { name = "numba", version = "0.66.0", source = { registry = "https://pypi.org/simple" }, marker = "(python_full_version >= '3.12' and platform_machine != 'x86_64') or (python_full_version < '3.12' and platform_machine != 'x86_64' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (python_full_version >= '3.12' and sys_platform != 'darwin') or (platform_machine == 'x86_64' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (sys_platform != 'darwin' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda')" }, { name = "numpy", version = "2.4.6", source = { registry = "https://pypi.org/simple" }, marker = "(python_full_version >= '3.12' and platform_machine != 'x86_64') or (python_full_version < '3.12' and platform_machine != 'x86_64' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (python_full_version >= '3.12' and sys_platform != 'darwin') or (platform_machine == 'x86_64' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (sys_platform != 'darwin' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda')" }, - { name = "packaging", marker = "(python_full_version >= '3.12' and platform_machine != 'x86_64') or (python_full_version < '3.12' and platform_machine != 'x86_64' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (python_full_version >= '3.12' and sys_platform != 'darwin') or (platform_machine == 'x86_64' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (sys_platform != 'darwin' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda')" }, - { name = "pandas", marker = "(python_full_version >= '3.12' and platform_machine != 'x86_64') or (python_full_version < '3.12' and platform_machine != 'x86_64' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (python_full_version >= '3.12' and sys_platform != 'darwin') or (platform_machine == 'x86_64' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (sys_platform != 'darwin' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda')" }, - { name = "scikit-learn", marker = "(python_full_version >= '3.12' and platform_machine != 'x86_64') or (python_full_version < '3.12' and platform_machine != 'x86_64' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (python_full_version >= '3.12' and sys_platform != 'darwin') or (platform_machine == 'x86_64' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (sys_platform != 'darwin' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda')" }, - { name = "scipy", version = "1.18.0", source = { registry = "https://pypi.org/simple" }, marker = "(python_full_version >= '3.12' and platform_machine != 'x86_64') or (python_full_version < '3.12' and platform_machine != 'x86_64' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (python_full_version >= '3.12' and sys_platform != 'darwin') or (platform_machine == 'x86_64' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (sys_platform != 'darwin' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda')" }, - { name = "slicer", marker = "(python_full_version >= '3.12' and platform_machine != 'x86_64') or (python_full_version < '3.12' and platform_machine != 'x86_64' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (python_full_version >= '3.12' and sys_platform != 'darwin') or (platform_machine == 'x86_64' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (sys_platform != 'darwin' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda')" }, - { name = "tqdm", marker = "(python_full_version >= '3.12' and platform_machine != 'x86_64') or (python_full_version < '3.12' and platform_machine != 'x86_64' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (python_full_version >= '3.12' and sys_platform != 'darwin') or (platform_machine == 'x86_64' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (sys_platform != 'darwin' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda')" }, + { name = "numpy", version = "2.5.0", source = { registry = "https://pypi.org/simple" }, marker = "(python_full_version >= '3.12' and python_full_version < '3.15' and platform_machine == 'x86_64' and sys_platform == 'darwin') or (python_full_version < '3.12' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (python_full_version >= '3.15' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (platform_machine != 'x86_64' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (sys_platform != 'darwin' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda')" }, + { name = "packaging", marker = "(python_full_version >= '3.12' and python_full_version < '3.15') or (python_full_version >= '3.12' and platform_machine != 'x86_64') or (python_full_version >= '3.15' and platform_machine == 'x86_64' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (python_full_version >= '3.12' and sys_platform != 'darwin') or (python_full_version < '3.12' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (sys_platform != 'darwin' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda')" }, + { name = "pandas", marker = "(python_full_version >= '3.12' and python_full_version < '3.15') or (python_full_version >= '3.12' and platform_machine != 'x86_64') or (python_full_version >= '3.15' and platform_machine == 'x86_64' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (python_full_version >= '3.12' and sys_platform != 'darwin') or (python_full_version < '3.12' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (sys_platform != 'darwin' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda')" }, + { name = "scikit-learn", marker = "(python_full_version >= '3.12' and python_full_version < '3.15') or (python_full_version >= '3.12' and platform_machine != 'x86_64') or (python_full_version >= '3.15' and platform_machine == 'x86_64' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (python_full_version >= '3.12' and sys_platform != 'darwin') or (python_full_version < '3.12' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (sys_platform != 'darwin' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda')" }, + { name = "scipy", version = "1.18.0", source = { registry = "https://pypi.org/simple" }, marker = "(python_full_version >= '3.12' and python_full_version < '3.15') or (python_full_version >= '3.12' and platform_machine != 'x86_64') or (python_full_version >= '3.15' and platform_machine == 'x86_64' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (python_full_version >= '3.12' and sys_platform != 'darwin') or (python_full_version < '3.12' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (sys_platform != 'darwin' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda')" }, + { name = "slicer", marker = "(python_full_version >= '3.12' and python_full_version < '3.15') or (python_full_version >= '3.12' and platform_machine != 'x86_64') or (python_full_version >= '3.15' and platform_machine == 'x86_64' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (python_full_version >= '3.12' and sys_platform != 'darwin') or (python_full_version < '3.12' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (sys_platform != 'darwin' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda')" }, + { name = "tqdm", marker = "(python_full_version >= '3.12' and python_full_version < '3.15') or (python_full_version >= '3.12' and platform_machine != 'x86_64') or (python_full_version >= '3.15' and platform_machine == 'x86_64' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (python_full_version >= '3.12' and sys_platform != 'darwin') or (python_full_version < '3.12' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (sys_platform != 'darwin' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda')" }, ] sdist = { url = "https://files.pythonhosted.org/packages/fc/0a/aa278f42c08cb47f2bb503085be0c521da2886929c6605b6105748a7590f/shap-0.52.0.tar.gz", hash = "sha256:81d4ae478f67f8122de1bb411dc4e3ddff0604cbc27dc9cb8ea66d5c73462fd2", size = 4192842, upload-time = "2026-05-28T14:17:49.011Z" } wheels = [ @@ -8133,8 +8208,8 @@ resolution-markers = [ "(python_full_version == '3.12.*' and platform_machine != 'x86_64' and extra != 'extra-6-dashai-cpu' and extra != 'extra-6-dashai-cuda') or (python_full_version == '3.12.*' and sys_platform != 'darwin' and extra != 'extra-6-dashai-cpu' and extra != 'extra-6-dashai-cuda')", ] dependencies = [ - { name = "numpy", version = "2.4.6", source = { registry = "https://pypi.org/simple" }, marker = "(python_full_version >= '3.12' and platform_machine != 'x86_64') or (python_full_version < '3.12' and platform_machine != 'x86_64' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (python_full_version >= '3.12' and sys_platform != 'darwin') or (platform_machine == 'x86_64' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (sys_platform != 'darwin' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda')" }, - { name = "numpy", version = "2.5.0", source = { registry = "https://pypi.org/simple" }, marker = "(python_full_version >= '3.12' and platform_machine == 'x86_64' and sys_platform == 'darwin') or (python_full_version < '3.12' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (platform_machine != 'x86_64' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (sys_platform != 'darwin' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda')" }, + { name = "numpy", version = "2.4.6", source = { registry = "https://pypi.org/simple" }, marker = "(python_full_version >= '3.12' and platform_machine != 'x86_64') or (python_full_version >= '3.15' and platform_machine == 'x86_64' and sys_platform == 'darwin') or (python_full_version < '3.12' and platform_machine != 'x86_64' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (python_full_version < '3.15' and platform_machine == 'x86_64' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (python_full_version >= '3.12' and sys_platform != 'darwin') or (sys_platform != 'darwin' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda')" }, + { name = "numpy", version = "2.5.0", source = { registry = "https://pypi.org/simple" }, marker = "(python_full_version >= '3.12' and python_full_version < '3.15' and platform_machine == 'x86_64' and sys_platform == 'darwin') or (python_full_version < '3.12' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (python_full_version >= '3.15' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (platform_machine != 'x86_64' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (sys_platform != 'darwin' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda')" }, ] sdist = { url = "https://files.pythonhosted.org/packages/b7/38/5e2ecef5af2f4fd4a89bb8d6240de9458bab4d51a4cbd97aeb3a0cd618e2/tifffile-2026.6.1.tar.gz", hash = "sha256:626c892c0e899d959b9438e7c0e1491dc154a7fead1f1f37a991724a50eceba9", size = 429694, upload-time = "2026-05-31T23:57:12.165Z" } wheels = [ @@ -8466,8 +8541,8 @@ source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "lightning-utilities" }, { name = "numpy", version = "2.2.6", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.11' or (extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda')" }, - { name = "numpy", version = "2.4.6", source = { registry = "https://pypi.org/simple" }, marker = "(python_full_version >= '3.11' and platform_machine != 'x86_64') or (python_full_version == '3.11.*' and platform_machine == 'x86_64' and sys_platform == 'darwin') or (python_full_version < '3.11' and platform_machine != 'x86_64' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (python_full_version != '3.11.*' and platform_machine == 'x86_64' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (python_full_version >= '3.11' and sys_platform != 'darwin') or (sys_platform != 'darwin' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda')" }, - { name = "numpy", version = "2.5.0", source = { registry = "https://pypi.org/simple" }, marker = "(python_full_version >= '3.12' and platform_machine == 'x86_64' and sys_platform == 'darwin') or (python_full_version < '3.12' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (platform_machine != 'x86_64' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (sys_platform != 'darwin' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda')" }, + { name = "numpy", version = "2.4.6", source = { registry = "https://pypi.org/simple" }, marker = "(python_full_version >= '3.12' and python_full_version < '3.15' and platform_machine == 'x86_64' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (python_full_version >= '3.11' and platform_machine != 'x86_64') or (python_full_version == '3.11.*' and platform_machine == 'x86_64' and sys_platform == 'darwin') or (python_full_version >= '3.15' and platform_machine == 'x86_64' and sys_platform == 'darwin') or (python_full_version >= '3.11' and sys_platform != 'darwin') or (python_full_version < '3.11' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (sys_platform != 'darwin' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda')" }, + { name = "numpy", version = "2.5.0", source = { registry = "https://pypi.org/simple" }, marker = "(python_full_version >= '3.12' and python_full_version < '3.15' and platform_machine == 'x86_64' and sys_platform == 'darwin') or (python_full_version < '3.12' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (python_full_version >= '3.15' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (platform_machine != 'x86_64' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (sys_platform != 'darwin' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda')" }, { name = "packaging" }, { name = "torch", version = "2.11.0+cu128", source = { registry = "https://download.pytorch.org/whl/cu128" }, marker = "extra == 'extra-6-dashai-cuda'" }, { name = "torch", version = "2.12.1", source = { registry = "https://download.pytorch.org/whl/cpu" }, marker = "(python_full_version < '3.15' and platform_machine != 'x86_64' and sys_platform == 'darwin' and extra == 'extra-6-dashai-cpu') or (python_full_version < '3.12' and platform_machine == 'x86_64' and sys_platform == 'darwin' and extra == 'extra-6-dashai-cpu') or (python_full_version >= '3.15' and platform_machine != 'x86_64' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (python_full_version >= '3.12' and platform_machine == 'x86_64' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (sys_platform != 'darwin' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda')" }, @@ -8497,8 +8572,8 @@ resolution-markers = [ ] dependencies = [ { name = "numpy", version = "2.2.6", source = { registry = "https://pypi.org/simple" }, marker = "(python_full_version < '3.11' and extra == 'extra-6-dashai-cuda') or (extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda')" }, - { name = "numpy", version = "2.4.6", source = { registry = "https://pypi.org/simple" }, marker = "(python_full_version == '3.11.*' and platform_machine == 'x86_64' and sys_platform == 'darwin' and extra == 'extra-6-dashai-cuda') or (python_full_version >= '3.11' and platform_machine != 'x86_64' and extra == 'extra-6-dashai-cuda') or (python_full_version < '3.11' and platform_machine != 'x86_64' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (python_full_version != '3.11.*' and platform_machine == 'x86_64' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (python_full_version >= '3.11' and sys_platform != 'darwin' and extra == 'extra-6-dashai-cuda') or (sys_platform != 'darwin' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda')" }, - { name = "numpy", version = "2.5.0", source = { registry = "https://pypi.org/simple" }, marker = "(python_full_version >= '3.12' and platform_machine == 'x86_64' and sys_platform == 'darwin' and extra == 'extra-6-dashai-cuda') or (python_full_version < '3.12' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (platform_machine != 'x86_64' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (sys_platform != 'darwin' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda')" }, + { name = "numpy", version = "2.4.6", source = { registry = "https://pypi.org/simple" }, marker = "(python_full_version >= '3.12' and python_full_version < '3.15' and platform_machine == 'x86_64' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (python_full_version == '3.11.*' and platform_machine == 'x86_64' and sys_platform == 'darwin' and extra == 'extra-6-dashai-cuda') or (python_full_version >= '3.15' and platform_machine == 'x86_64' and sys_platform == 'darwin' and extra == 'extra-6-dashai-cuda') or (python_full_version >= '3.11' and platform_machine != 'x86_64' and extra == 'extra-6-dashai-cuda') or (python_full_version >= '3.11' and sys_platform != 'darwin' and extra == 'extra-6-dashai-cuda') or (python_full_version < '3.11' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (sys_platform != 'darwin' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda')" }, + { name = "numpy", version = "2.5.0", source = { registry = "https://pypi.org/simple" }, marker = "(python_full_version >= '3.12' and python_full_version < '3.15' and platform_machine == 'x86_64' and sys_platform == 'darwin' and extra == 'extra-6-dashai-cuda') or (python_full_version < '3.12' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (python_full_version >= '3.15' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (platform_machine != 'x86_64' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (sys_platform != 'darwin' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda')" }, { name = "pillow", marker = "extra == 'extra-6-dashai-cuda'" }, { name = "torch", version = "2.11.0+cu128", source = { registry = "https://download.pytorch.org/whl/cu128" }, marker = "extra == 'extra-6-dashai-cuda'" }, ] @@ -8570,8 +8645,8 @@ resolution-markers = [ ] dependencies = [ { name = "numpy", version = "2.2.6", source = { registry = "https://pypi.org/simple" }, marker = "(python_full_version < '3.11' and extra != 'extra-6-dashai-cpu' and extra != 'extra-6-dashai-cuda') or (extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda')" }, - { name = "numpy", version = "2.4.6", source = { registry = "https://pypi.org/simple" }, marker = "(python_full_version == '3.11.*' and platform_machine == 'x86_64' and sys_platform == 'darwin' and extra != 'extra-6-dashai-cpu' and extra != 'extra-6-dashai-cuda') or (python_full_version >= '3.11' and platform_machine != 'x86_64' and extra != 'extra-6-dashai-cpu' and extra != 'extra-6-dashai-cuda') or (python_full_version >= '3.11' and sys_platform != 'darwin' and extra != 'extra-6-dashai-cpu' and extra != 'extra-6-dashai-cuda') or (extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda')" }, - { name = "numpy", version = "2.5.0", source = { registry = "https://pypi.org/simple" }, marker = "(python_full_version >= '3.12' and platform_machine == 'x86_64' and sys_platform == 'darwin' and extra != 'extra-6-dashai-cpu' and extra != 'extra-6-dashai-cuda') or (extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda')" }, + { name = "numpy", version = "2.4.6", source = { registry = "https://pypi.org/simple" }, marker = "(python_full_version >= '3.12' and python_full_version < '3.15' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (python_full_version == '3.11.*' and platform_machine == 'x86_64' and sys_platform == 'darwin' and extra != 'extra-6-dashai-cpu' and extra != 'extra-6-dashai-cuda') or (python_full_version >= '3.15' and platform_machine == 'x86_64' and sys_platform == 'darwin' and extra != 'extra-6-dashai-cpu' and extra != 'extra-6-dashai-cuda') or (python_full_version >= '3.11' and platform_machine != 'x86_64' and extra != 'extra-6-dashai-cpu' and extra != 'extra-6-dashai-cuda') or (python_full_version >= '3.11' and sys_platform != 'darwin' and extra != 'extra-6-dashai-cpu' and extra != 'extra-6-dashai-cuda') or (python_full_version < '3.11' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (python_full_version == '3.11.*' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (python_full_version >= '3.15' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (platform_machine != 'x86_64' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (sys_platform != 'darwin' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda')" }, + { name = "numpy", version = "2.5.0", source = { registry = "https://pypi.org/simple" }, marker = "(python_full_version >= '3.12' and python_full_version < '3.15' and platform_machine == 'x86_64' and sys_platform == 'darwin' and extra != 'extra-6-dashai-cpu' and extra != 'extra-6-dashai-cuda') or (extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda')" }, { name = "pillow", marker = "(extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (extra != 'extra-6-dashai-cpu' and extra != 'extra-6-dashai-cuda')" }, { name = "torch", version = "2.12.1", source = { registry = "https://pypi.org/simple" }, marker = "(extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (extra != 'extra-6-dashai-cpu' and extra != 'extra-6-dashai-cuda')" }, ] @@ -8621,8 +8696,8 @@ resolution-markers = [ ] dependencies = [ { name = "numpy", version = "2.2.6", source = { registry = "https://pypi.org/simple" }, marker = "(python_full_version < '3.11' and sys_platform != 'darwin' and extra == 'extra-6-dashai-cpu') or (python_full_version >= '3.11' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (sys_platform == 'darwin' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda')" }, - { name = "numpy", version = "2.4.6", source = { registry = "https://pypi.org/simple" }, marker = "(python_full_version >= '3.15' and platform_machine != 'x86_64' and sys_platform == 'darwin' and extra == 'extra-6-dashai-cpu') or (python_full_version < '3.15' and platform_machine != 'x86_64' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (python_full_version >= '3.11' and sys_platform != 'darwin' and extra == 'extra-6-dashai-cpu') or (platform_machine == 'x86_64' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (sys_platform != 'darwin' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda')" }, - { name = "numpy", version = "2.5.0", source = { registry = "https://pypi.org/simple" }, marker = "(python_full_version >= '3.12' and platform_machine == 'x86_64' and sys_platform == 'darwin' and extra == 'extra-6-dashai-cpu') or (python_full_version < '3.12' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (platform_machine != 'x86_64' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (sys_platform != 'darwin' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda')" }, + { name = "numpy", version = "2.4.6", source = { registry = "https://pypi.org/simple" }, marker = "(python_full_version >= '3.11' and sys_platform != 'darwin' and extra == 'extra-6-dashai-cpu') or (python_full_version >= '3.15' and sys_platform == 'darwin' and extra == 'extra-6-dashai-cpu') or (python_full_version < '3.15' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (sys_platform != 'darwin' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda')" }, + { name = "numpy", version = "2.5.0", source = { registry = "https://pypi.org/simple" }, marker = "(python_full_version >= '3.12' and python_full_version < '3.15' and platform_machine == 'x86_64' and sys_platform == 'darwin' and extra == 'extra-6-dashai-cpu') or (python_full_version < '3.12' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (python_full_version >= '3.15' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (platform_machine != 'x86_64' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (sys_platform != 'darwin' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda')" }, { name = "pillow", marker = "(python_full_version >= '3.15' and platform_machine != 'x86_64' and extra == 'extra-6-dashai-cpu') or (python_full_version >= '3.12' and platform_machine == 'x86_64' and extra == 'extra-6-dashai-cpu') or (python_full_version < '3.15' and platform_machine != 'x86_64' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (python_full_version < '3.12' and platform_machine == 'x86_64' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (sys_platform != 'darwin' and extra == 'extra-6-dashai-cpu')" }, { name = "torch", version = "2.12.1+cpu", source = { registry = "https://download.pytorch.org/whl/cpu" }, marker = "(python_full_version >= '3.15' and platform_machine != 'x86_64' and extra == 'extra-6-dashai-cpu') or (python_full_version >= '3.12' and platform_machine == 'x86_64' and extra == 'extra-6-dashai-cpu') or (python_full_version < '3.15' and platform_machine != 'x86_64' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (python_full_version < '3.12' and platform_machine == 'x86_64' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (sys_platform != 'darwin' and extra == 'extra-6-dashai-cpu')" }, ] @@ -8666,8 +8741,8 @@ source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "huggingface-hub" }, { name = "numpy", version = "2.2.6", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.11' or (extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda')" }, - { name = "numpy", version = "2.4.6", source = { registry = "https://pypi.org/simple" }, marker = "(python_full_version >= '3.11' and platform_machine != 'x86_64') or (python_full_version == '3.11.*' and platform_machine == 'x86_64' and sys_platform == 'darwin') or (python_full_version < '3.11' and platform_machine != 'x86_64' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (python_full_version != '3.11.*' and platform_machine == 'x86_64' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (python_full_version >= '3.11' and sys_platform != 'darwin') or (sys_platform != 'darwin' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda')" }, - { name = "numpy", version = "2.5.0", source = { registry = "https://pypi.org/simple" }, marker = "(python_full_version >= '3.12' and platform_machine == 'x86_64' and sys_platform == 'darwin') or (python_full_version < '3.12' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (platform_machine != 'x86_64' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (sys_platform != 'darwin' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda')" }, + { name = "numpy", version = "2.4.6", source = { registry = "https://pypi.org/simple" }, marker = "(python_full_version >= '3.12' and python_full_version < '3.15' and platform_machine == 'x86_64' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (python_full_version >= '3.11' and platform_machine != 'x86_64') or (python_full_version == '3.11.*' and platform_machine == 'x86_64' and sys_platform == 'darwin') or (python_full_version >= '3.15' and platform_machine == 'x86_64' and sys_platform == 'darwin') or (python_full_version >= '3.11' and sys_platform != 'darwin') or (python_full_version < '3.11' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (sys_platform != 'darwin' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda')" }, + { name = "numpy", version = "2.5.0", source = { registry = "https://pypi.org/simple" }, marker = "(python_full_version >= '3.12' and python_full_version < '3.15' and platform_machine == 'x86_64' and sys_platform == 'darwin') or (python_full_version < '3.12' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (python_full_version >= '3.15' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (platform_machine != 'x86_64' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (sys_platform != 'darwin' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda')" }, { name = "packaging" }, { name = "pyyaml" }, { name = "regex" }, @@ -9078,8 +9153,8 @@ dependencies = [ { name = "matplotlib", version = "3.10.9", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.11' or (extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda')" }, { name = "matplotlib", version = "3.11.0", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.11' or (extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda')" }, { name = "numpy", version = "2.2.6", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.11' or (extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda')" }, - { name = "numpy", version = "2.4.6", source = { registry = "https://pypi.org/simple" }, marker = "(python_full_version >= '3.11' and platform_machine != 'x86_64') or (python_full_version == '3.11.*' and platform_machine == 'x86_64' and sys_platform == 'darwin') or (python_full_version < '3.11' and platform_machine != 'x86_64' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (python_full_version != '3.11.*' and platform_machine == 'x86_64' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (python_full_version >= '3.11' and sys_platform != 'darwin') or (sys_platform != 'darwin' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda')" }, - { name = "numpy", version = "2.5.0", source = { registry = "https://pypi.org/simple" }, marker = "(python_full_version >= '3.12' and platform_machine == 'x86_64' and sys_platform == 'darwin') or (python_full_version < '3.12' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (platform_machine != 'x86_64' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (sys_platform != 'darwin' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda')" }, + { name = "numpy", version = "2.4.6", source = { registry = "https://pypi.org/simple" }, marker = "(python_full_version >= '3.12' and python_full_version < '3.15' and platform_machine == 'x86_64' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (python_full_version >= '3.11' and platform_machine != 'x86_64') or (python_full_version == '3.11.*' and platform_machine == 'x86_64' and sys_platform == 'darwin') or (python_full_version >= '3.15' and platform_machine == 'x86_64' and sys_platform == 'darwin') or (python_full_version >= '3.11' and sys_platform != 'darwin') or (python_full_version < '3.11' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (sys_platform != 'darwin' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda')" }, + { name = "numpy", version = "2.5.0", source = { registry = "https://pypi.org/simple" }, marker = "(python_full_version >= '3.12' and python_full_version < '3.15' and platform_machine == 'x86_64' and sys_platform == 'darwin') or (python_full_version < '3.12' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (python_full_version >= '3.15' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (platform_machine != 'x86_64' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (sys_platform != 'darwin' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda')" }, { name = "pillow" }, ] sdist = { url = "https://files.pythonhosted.org/packages/6f/04/a3d3c4b94a35586ddb97c6a3c508913159161cd558b34f315b382b924bf7/wordcloud-1.9.6.tar.gz", hash = "sha256:df17c468ff903bd0aba4f87c6540745d13a4931220dd4937cb363ad85a4771b9", size = 27563741, upload-time = "2026-01-22T02:08:52.976Z" } @@ -9279,8 +9354,8 @@ resolution-markers = [ "python_full_version == '3.11.*' and extra != 'extra-6-dashai-cpu' and extra != 'extra-6-dashai-cuda'", ] dependencies = [ - { name = "numpy", version = "2.4.6", source = { registry = "https://pypi.org/simple" }, marker = "(python_full_version >= '3.11' and platform_machine != 'x86_64') or (python_full_version == '3.11.*' and platform_machine == 'x86_64' and sys_platform == 'darwin') or (python_full_version < '3.11' and platform_machine != 'x86_64' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (python_full_version != '3.11.*' and platform_machine == 'x86_64' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (python_full_version >= '3.11' and sys_platform != 'darwin') or (sys_platform != 'darwin' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda')" }, - { name = "numpy", version = "2.5.0", source = { registry = "https://pypi.org/simple" }, marker = "(python_full_version >= '3.12' and platform_machine == 'x86_64' and sys_platform == 'darwin') or (python_full_version < '3.12' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (platform_machine != 'x86_64' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (sys_platform != 'darwin' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda')" }, + { name = "numpy", version = "2.4.6", source = { registry = "https://pypi.org/simple" }, marker = "(python_full_version >= '3.12' and python_full_version < '3.15' and platform_machine == 'x86_64' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (python_full_version >= '3.11' and platform_machine != 'x86_64') or (python_full_version == '3.11.*' and platform_machine == 'x86_64' and sys_platform == 'darwin') or (python_full_version >= '3.15' and platform_machine == 'x86_64' and sys_platform == 'darwin') or (python_full_version >= '3.11' and sys_platform != 'darwin') or (python_full_version < '3.11' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (sys_platform != 'darwin' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda')" }, + { name = "numpy", version = "2.5.0", source = { registry = "https://pypi.org/simple" }, marker = "(python_full_version >= '3.12' and python_full_version < '3.15' and platform_machine == 'x86_64' and sys_platform == 'darwin') or (python_full_version < '3.12' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (python_full_version >= '3.15' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (platform_machine != 'x86_64' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (sys_platform != 'darwin' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda')" }, { name = "packaging", marker = "python_full_version >= '3.11' or (extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda')" }, { name = "pandas", marker = "python_full_version >= '3.11' or (extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda')" }, ] @@ -9364,8 +9439,8 @@ resolution-markers = [ "(python_full_version == '3.12.*' and platform_machine != 'x86_64' and extra != 'extra-6-dashai-cpu' and extra != 'extra-6-dashai-cuda') or (python_full_version == '3.12.*' and sys_platform != 'darwin' and extra != 'extra-6-dashai-cpu' and extra != 'extra-6-dashai-cuda')", ] dependencies = [ - { name = "numpy", version = "2.4.6", source = { registry = "https://pypi.org/simple" }, marker = "(python_full_version >= '3.12' and platform_machine != 'x86_64') or (python_full_version < '3.12' and platform_machine != 'x86_64' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (python_full_version >= '3.12' and sys_platform != 'darwin') or (platform_machine == 'x86_64' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (sys_platform != 'darwin' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda')" }, - { name = "numpy", version = "2.5.0", source = { registry = "https://pypi.org/simple" }, marker = "(python_full_version >= '3.12' and platform_machine == 'x86_64' and sys_platform == 'darwin') or (python_full_version < '3.12' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (platform_machine != 'x86_64' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (sys_platform != 'darwin' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda')" }, + { name = "numpy", version = "2.4.6", source = { registry = "https://pypi.org/simple" }, marker = "(python_full_version >= '3.12' and platform_machine != 'x86_64') or (python_full_version >= '3.15' and platform_machine == 'x86_64' and sys_platform == 'darwin') or (python_full_version < '3.12' and platform_machine != 'x86_64' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (python_full_version < '3.15' and platform_machine == 'x86_64' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (python_full_version >= '3.12' and sys_platform != 'darwin') or (sys_platform != 'darwin' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda')" }, + { name = "numpy", version = "2.5.0", source = { registry = "https://pypi.org/simple" }, marker = "(python_full_version >= '3.12' and python_full_version < '3.15' and platform_machine == 'x86_64' and sys_platform == 'darwin') or (python_full_version < '3.12' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (python_full_version >= '3.15' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (platform_machine != 'x86_64' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (sys_platform != 'darwin' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda')" }, { name = "scipy", version = "1.18.0", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.12' or (extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda')" }, { name = "xarray", version = "2026.4.0", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.12' or (extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda')" }, ] @@ -9439,8 +9514,8 @@ resolution-markers = [ "(python_full_version == '3.12.*' and platform_machine != 'x86_64' and extra != 'extra-6-dashai-cpu' and extra != 'extra-6-dashai-cuda') or (python_full_version == '3.12.*' and sys_platform != 'darwin' and extra != 'extra-6-dashai-cpu' and extra != 'extra-6-dashai-cuda')", ] dependencies = [ - { name = "numpy", version = "2.4.6", source = { registry = "https://pypi.org/simple" }, marker = "(python_full_version >= '3.12' and platform_machine != 'x86_64') or (python_full_version < '3.12' and platform_machine != 'x86_64' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (python_full_version >= '3.12' and sys_platform != 'darwin') or (platform_machine == 'x86_64' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (sys_platform != 'darwin' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda')" }, - { name = "numpy", version = "2.5.0", source = { registry = "https://pypi.org/simple" }, marker = "(python_full_version >= '3.12' and platform_machine == 'x86_64' and sys_platform == 'darwin') or (python_full_version < '3.12' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (platform_machine != 'x86_64' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (sys_platform != 'darwin' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda')" }, + { name = "numpy", version = "2.4.6", source = { registry = "https://pypi.org/simple" }, marker = "(python_full_version >= '3.12' and platform_machine != 'x86_64') or (python_full_version >= '3.15' and platform_machine == 'x86_64' and sys_platform == 'darwin') or (python_full_version < '3.12' and platform_machine != 'x86_64' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (python_full_version < '3.15' and platform_machine == 'x86_64' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (python_full_version >= '3.12' and sys_platform != 'darwin') or (sys_platform != 'darwin' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda')" }, + { name = "numpy", version = "2.5.0", source = { registry = "https://pypi.org/simple" }, marker = "(python_full_version >= '3.12' and python_full_version < '3.15' and platform_machine == 'x86_64' and sys_platform == 'darwin') or (python_full_version < '3.12' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (python_full_version >= '3.15' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (platform_machine != 'x86_64' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (sys_platform != 'darwin' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda')" }, { name = "nvidia-nccl-cu12", marker = "(python_full_version >= '3.12' and sys_platform == 'linux') or (python_full_version < '3.12' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda') or (sys_platform != 'linux' and extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda')" }, { name = "scipy", version = "1.18.0", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.12' or (extra == 'extra-6-dashai-cpu' and extra == 'extra-6-dashai-cuda')" }, ]