Date: Sat, 31 Jan 2026 15:44:22 +0800
Subject: [PATCH 06/10] [vibe coding] feat: support multi-version docs (#159)
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
## Summary
close #104
## Solution Description
1. 多版本文档构建系统
- 集成 sphinx-multiversion 扩展,支持为多个分支和标签构建文档
- 配置了版本白名单规则:
- 标签格式:v *.*.*(如 v1.0.0, v1.1.0)
- 分支:main 和 develop
- 自动创建重定向页面,默认跳转到 develop 版本
2. Makefile 新增命令
- `make docs-multiversion`:构建所有版本的文档
- `make docs-serve`:启动支持自动重载的开发服务器
- `make docs`:单版本构建(已更新注释)
## Summary by CodeRabbit
* **New Features**
* Multi-version documentation build and a local doc server with
auto-reload for live previews
* Version selector dropdown in the docs UI to switch between
documentation versions
* **Documentation**
* New styling and banners for version-aware documentation and a redirect
to the latest version for easy access
✏️ Tip: You can customize this high-level summary in your review
settings.
---
Makefile | 12 ++++++-
docs/_static/custom.css | 66 +++++++++++++++++++++++++++++++++++++
docs/_templates/layout.html | 18 ++++++++++
docs/build_multiversion.sh | 50 ++++++++++++++++++++++++++++
docs/conf.py | 23 +++++++++++++
5 files changed, 168 insertions(+), 1 deletion(-)
create mode 100644 docs/_templates/layout.html
create mode 100755 docs/build_multiversion.sh
diff --git a/Makefile b/Makefile
index 6b6e5ae4..0885a3c6 100644
--- a/Makefile
+++ b/Makefile
@@ -34,10 +34,20 @@ test-integration-embedded: ## Run embedded integration tests
@$(UV) run pytest tests/integration_tests/ -v --log-cli-level=INFO -k embedded
.PHONY: docs
-docs: ## Build documentation
+docs: ## Build documentation (single version)
@echo ">> Building documentation"
@$(UV) run sphinx-build -b html docs docs/_build/html
+.PHONY: docs-multiversion
+docs-multiversion: ## Build multi-version documentation
+ @echo ">> Building multi-version documentation"
+ @bash docs/build_multiversion.sh
+
+.PHONY: docs-serve
+docs-serve: ## Serve documentation with auto-reload
+ @echo ">> Starting documentation server"
+ @$(UV) run sphinx-autobuild docs docs/_build/html --host 127.0.0.1 --port 8000
+
.PHONY: build
build: ## Build package
@echo ">> Building package"
diff --git a/docs/_static/custom.css b/docs/_static/custom.css
index e69de29b..853148d2 100644
--- a/docs/_static/custom.css
+++ b/docs/_static/custom.css
@@ -0,0 +1,66 @@
+/* 版本选择器下拉框样式 - 放在左侧导航栏搜索框下方 */
+.version-selector-dropdown {
+ display: flex;
+ align-items: center;
+ gap: 8px;
+ margin-top: 8px;
+ border-radius: 50px;
+}
+
+.version-selector-dropdown label {
+ font-size: 13px;
+ font-weight: 600;
+ color: #fff;
+ margin: 0;
+ white-space: nowrap;
+}
+
+.version-selector-dropdown select {
+ flex: 1;
+ padding: 6px 10px;
+ font-size: 13px;
+ color: #404040;
+ background-color: #fff;
+ border: 1px solid #d0d0d0;
+ border-radius: 4px;
+ cursor: pointer;
+ outline: none;
+ transition: all 0.2s ease;
+}
+
+.version-selector-dropdown select:hover {
+ border-color: #2980b9;
+}
+
+.version-selector-dropdown select:focus {
+ border-color: #2980b9;
+ box-shadow: 0 0 0 2px rgba(41, 128, 185, 0.1);
+}
+
+/* RTD 主题版本横幅样式 - 隐藏左下角的版本选择器 */
+.rst-versions {
+ display: none !important;
+}
+
+/* 版本警告横幅 */
+.version-warning {
+ padding: 10px 15px;
+ margin-bottom: 20px;
+ background-color: #fff3cd;
+ border: 1px solid #ffeaa7;
+ border-radius: 4px;
+ color: #856404;
+}
+
+.version-warning strong {
+ font-weight: bold;
+}
+
+.version-warning a {
+ color: #856404;
+ text-decoration: underline;
+}
+
+.version-warning a:hover {
+ color: #533f03;
+}
diff --git a/docs/_templates/layout.html b/docs/_templates/layout.html
new file mode 100644
index 00000000..2bdb8d8c
--- /dev/null
+++ b/docs/_templates/layout.html
@@ -0,0 +1,18 @@
+{% extends "!layout.html" %}
+
+{# 在左侧导航栏的搜索框下方插入版本选择器 #}
+{% block sidebartitle %}
+ {{ super() }}
+ {% if versions %}
+
+
+
+
+ {% endif %}
+{% endblock %}
diff --git a/docs/build_multiversion.sh b/docs/build_multiversion.sh
new file mode 100755
index 00000000..9abd9c90
--- /dev/null
+++ b/docs/build_multiversion.sh
@@ -0,0 +1,50 @@
+#!/bin/bash
+# 构建多版本文档的脚本
+
+set -e
+
+# 颜色输出
+GREEN='\033[0;32m'
+BLUE='\033[0;34m'
+NC='\033[0m' # No Color
+
+echo -e "${BLUE}开始构建多版本文档...${NC}"
+
+# 确保在项目根目录
+cd "$(dirname "$0")/.."
+
+# 激活虚拟环境(如果存在)
+if [ -d ".venv" ]; then
+ echo -e "${GREEN}激活虚拟环境...${NC}"
+ source .venv/bin/activate
+fi
+
+# 清理旧的构建文件
+echo -e "${GREEN}清理旧的构建文件...${NC}"
+rm -rf docs/_build/html
+
+# 使用 sphinx-multiversion 构建文档
+echo -e "${GREEN}使用 sphinx-multiversion 构建文档...${NC}"
+sphinx-multiversion docs docs/_build/html
+
+# 创建重定向到最新版本的 index.html
+echo -e "${GREEN}创建重定向页面...${NC}"
+cat > docs/_build/html/index.html << 'EOF'
+
+
+
+ Redirecting to latest version
+
+
+
+
+
+ Redirecting to latest version...
+
+
+EOF
+
+echo -e "${BLUE}多版本文档构建完成!${NC}"
+echo -e "${GREEN}文档位置: docs/_build/html${NC}"
+echo -e "${GREEN}可以使用以下命令启动本地服务器查看:${NC}"
+echo -e " cd docs/_build/html && python -m http.server 8000"
diff --git a/docs/conf.py b/docs/conf.py
index 1b1be534..75897341 100644
--- a/docs/conf.py
+++ b/docs/conf.py
@@ -26,6 +26,7 @@
"sphinx.ext.viewcode",
"sphinx.ext.napoleon",
"myst_parser",
+ "sphinx_multiversion",
]
# Enable Markdown in docstrings
@@ -59,3 +60,25 @@
# HTML theme
html_theme = "sphinx_rtd_theme"
html_static_path = ["_static"]
+html_css_files = [
+ "custom.css",
+]
+
+# Sphinx-multiversion configuration
+# 配置要包含的分支和标签
+smv_tag_whitelist = r"^v\d+\.\d+\.\d+$" # 匹配 v1.0.0 格式的标签
+smv_branch_whitelist = r"^(main|develop)$" # 包含 main 和 develop 分支
+smv_remote_whitelist = r"^origin$" # 只使用 origin 远程仓库
+smv_released_pattern = r"^refs/tags/.*$" # 标记已发布的版本
+
+# 自定义模板路径
+templates_path = ["_templates"]
+
+# 版本横幅配置
+html_context = {
+ "display_github": True,
+ "github_user": "oceanbase",
+ "github_repo": "pyseekdb",
+ "github_version": "develop",
+ "conf_py_path": "/docs/",
+}
From dc87918ff22a96dc43cf422157326ded9dc4afec Mon Sep 17 00:00:00 2001
From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com>
Date: Sat, 31 Jan 2026 15:53:02 +0800
Subject: [PATCH 07/10] Bump protobuf from 6.33.2 to 6.33.5 (#160)
Bumps [protobuf](https://github.com/protocolbuffers/protobuf) from
6.33.2 to 6.33.5.
Release notes
Sourced from protobuf's
releases.
Protocol Buffers v34.0-rc1
Announcements
Bazel
Compiler
C++
... (truncated)
Commits
[](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores)
Dependabot will resolve any conflicts with this PR as long as you don't
alter it yourself. You can also trigger a rebase manually by commenting
`@dependabot rebase`.
[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)
---
Dependabot commands and options
You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits
that have been made to it
- `@dependabot merge` will merge this PR after your CI passes on it
- `@dependabot squash and merge` will squash and merge this PR after
your CI passes on it
- `@dependabot cancel merge` will cancel a previously requested merge
and block automerging
- `@dependabot reopen` will reopen this PR if it is closed
- `@dependabot close` will close this PR and stop Dependabot recreating
it. You can achieve the same result by closing it manually
- `@dependabot show ignore conditions` will show all
of the ignore conditions of the specified dependency
- `@dependabot ignore this major version` will close this PR and stop
Dependabot creating any more for this major version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this minor version` will close this PR and stop
Dependabot creating any more for this minor version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this dependency` will close this PR and stop
Dependabot creating any more for this dependency (unless you reopen the
PR or upgrade to it yourself)
You can disable automated security fix PRs for this repo from the
[Security Alerts
page](https://github.com/oceanbase/pyseekdb/network/alerts).
Signed-off-by: dependabot[bot]
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
---
uv.lock | 18 +++++++++---------
1 file changed, 9 insertions(+), 9 deletions(-)
diff --git a/uv.lock b/uv.lock
index dc335b1d..1ca532d0 100644
--- a/uv.lock
+++ b/uv.lock
@@ -1051,17 +1051,17 @@ wheels = [
[[package]]
name = "protobuf"
-version = "6.33.2"
+version = "6.33.5"
source = { registry = "https://pypi.org/simple" }
-sdist = { url = "https://files.pythonhosted.org/packages/34/44/e49ecff446afeec9d1a66d6bbf9adc21e3c7cea7803a920ca3773379d4f6/protobuf-6.33.2.tar.gz", hash = "sha256:56dc370c91fbb8ac85bc13582c9e373569668a290aa2e66a590c2a0d35ddb9e4", size = 444296, upload-time = "2025-12-06T00:17:53.311Z" }
+sdist = { url = "https://files.pythonhosted.org/packages/ba/25/7c72c307aafc96fa87062aa6291d9f7c94836e43214d43722e86037aac02/protobuf-6.33.5.tar.gz", hash = "sha256:6ddcac2a081f8b7b9642c09406bc6a4290128fce5f471cddd165960bb9119e5c", size = 444465, upload-time = "2026-01-29T21:51:33.494Z" }
wheels = [
- { url = "https://files.pythonhosted.org/packages/bc/91/1e3a34881a88697a7354ffd177e8746e97a722e5e8db101544b47e84afb1/protobuf-6.33.2-cp310-abi3-win32.whl", hash = "sha256:87eb388bd2d0f78febd8f4c8779c79247b26a5befad525008e49a6955787ff3d", size = 425603, upload-time = "2025-12-06T00:17:41.114Z" },
- { url = "https://files.pythonhosted.org/packages/64/20/4d50191997e917ae13ad0a235c8b42d8c1ab9c3e6fd455ca16d416944355/protobuf-6.33.2-cp310-abi3-win_amd64.whl", hash = "sha256:fc2a0e8b05b180e5fc0dd1559fe8ebdae21a27e81ac77728fb6c42b12c7419b4", size = 436930, upload-time = "2025-12-06T00:17:43.278Z" },
- { url = "https://files.pythonhosted.org/packages/b2/ca/7e485da88ba45c920fb3f50ae78de29ab925d9e54ef0de678306abfbb497/protobuf-6.33.2-cp39-abi3-macosx_10_9_universal2.whl", hash = "sha256:d9b19771ca75935b3a4422957bc518b0cecb978b31d1dd12037b088f6bcc0e43", size = 427621, upload-time = "2025-12-06T00:17:44.445Z" },
- { url = "https://files.pythonhosted.org/packages/7d/4f/f743761e41d3b2b2566748eb76bbff2b43e14d5fcab694f494a16458b05f/protobuf-6.33.2-cp39-abi3-manylinux2014_aarch64.whl", hash = "sha256:b5d3b5625192214066d99b2b605f5783483575656784de223f00a8d00754fc0e", size = 324460, upload-time = "2025-12-06T00:17:45.678Z" },
- { url = "https://files.pythonhosted.org/packages/b1/fa/26468d00a92824020f6f2090d827078c09c9c587e34cbfd2d0c7911221f8/protobuf-6.33.2-cp39-abi3-manylinux2014_s390x.whl", hash = "sha256:8cd7640aee0b7828b6d03ae518b5b4806fdfc1afe8de82f79c3454f8aef29872", size = 339168, upload-time = "2025-12-06T00:17:46.813Z" },
- { url = "https://files.pythonhosted.org/packages/56/13/333b8f421738f149d4fe5e49553bc2a2ab75235486259f689b4b91f96cec/protobuf-6.33.2-cp39-abi3-manylinux2014_x86_64.whl", hash = "sha256:1f8017c48c07ec5859106533b682260ba3d7c5567b1ca1f24297ce03384d1b4f", size = 323270, upload-time = "2025-12-06T00:17:48.253Z" },
- { url = "https://files.pythonhosted.org/packages/0e/15/4f02896cc3df04fc465010a4c6a0cd89810f54617a32a70ef531ed75d61c/protobuf-6.33.2-py3-none-any.whl", hash = "sha256:7636aad9bb01768870266de5dc009de2d1b936771b38a793f73cbbf279c91c5c", size = 170501, upload-time = "2025-12-06T00:17:52.211Z" },
+ { url = "https://files.pythonhosted.org/packages/b1/79/af92d0a8369732b027e6d6084251dd8e782c685c72da161bd4a2e00fbabb/protobuf-6.33.5-cp310-abi3-win32.whl", hash = "sha256:d71b040839446bac0f4d162e758bea99c8251161dae9d0983a3b88dee345153b", size = 425769, upload-time = "2026-01-29T21:51:21.751Z" },
+ { url = "https://files.pythonhosted.org/packages/55/75/bb9bc917d10e9ee13dee8607eb9ab963b7cf8be607c46e7862c748aa2af7/protobuf-6.33.5-cp310-abi3-win_amd64.whl", hash = "sha256:3093804752167bcab3998bec9f1048baae6e29505adaf1afd14a37bddede533c", size = 437118, upload-time = "2026-01-29T21:51:24.022Z" },
+ { url = "https://files.pythonhosted.org/packages/a2/6b/e48dfc1191bc5b52950246275bf4089773e91cb5ba3592621723cdddca62/protobuf-6.33.5-cp39-abi3-macosx_10_9_universal2.whl", hash = "sha256:a5cb85982d95d906df1e2210e58f8e4f1e3cdc088e52c921a041f9c9a0386de5", size = 427766, upload-time = "2026-01-29T21:51:25.413Z" },
+ { url = "https://files.pythonhosted.org/packages/4e/b1/c79468184310de09d75095ed1314b839eb2f72df71097db9d1404a1b2717/protobuf-6.33.5-cp39-abi3-manylinux2014_aarch64.whl", hash = "sha256:9b71e0281f36f179d00cbcb119cb19dec4d14a81393e5ea220f64b286173e190", size = 324638, upload-time = "2026-01-29T21:51:26.423Z" },
+ { url = "https://files.pythonhosted.org/packages/c5/f5/65d838092fd01c44d16037953fd4c2cc851e783de9b8f02b27ec4ffd906f/protobuf-6.33.5-cp39-abi3-manylinux2014_s390x.whl", hash = "sha256:8afa18e1d6d20af15b417e728e9f60f3aa108ee76f23c3b2c07a2c3b546d3afd", size = 339411, upload-time = "2026-01-29T21:51:27.446Z" },
+ { url = "https://files.pythonhosted.org/packages/9b/53/a9443aa3ca9ba8724fdfa02dd1887c1bcd8e89556b715cfbacca6b63dbec/protobuf-6.33.5-cp39-abi3-manylinux2014_x86_64.whl", hash = "sha256:cbf16ba3350fb7b889fca858fb215967792dc125b35c7976ca4818bee3521cf0", size = 323465, upload-time = "2026-01-29T21:51:28.925Z" },
+ { url = "https://files.pythonhosted.org/packages/57/bf/2086963c69bdac3d7cff1cc7ff79b8ce5ea0bec6797a017e1be338a46248/protobuf-6.33.5-py3-none-any.whl", hash = "sha256:69915a973dd0f60f31a08b8318b73eab2bd6a392c79184b3612226b0a3f8ec02", size = 170687, upload-time = "2026-01-29T21:51:32.557Z" },
]
[[package]]
From 82f1f4e45504acfdc0051decfd6d122eae97e891 Mon Sep 17 00:00:00 2001
From: Jingchao
Date: Sat, 31 Jan 2026 16:14:26 +0800
Subject: [PATCH 08/10] feat: add pyseekdb CLI entry point in pyproject.toml
(#161)
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Introduce a **CLI for pyseekdb** to support debugging and managing
SeekDB databases/collections (close #55).
### Changes
- **CLI 模块**
- 新增
`src/pyseekdb/cli/__init__.py`、`src/pyseekdb/cli/main.py`,实现命令行入口与子命令分发。
- **连接方式**(与 spec 一致)
- 嵌入式:`--path`(默认当前目录下 `seekdb.db`)。
- 服务端:`--host`、`--port`(默认
2881)、`--tenant`、`--database`、`--user`、`--password`(或环境变量
`SEEKDB_PASSWORD`)。
- **子命令**
- **db**:`list` / `create ` / `delete `(数据库管理)。
- **collections**(别名 **coll**):`list` / `create [--dimension N]`
/ `delete ` / `info [--sample N]`(collection 管理及预览)。
- **sql**:执行原始 SQL(调试用)。
- **query**:按文本对指定 collection 做向量/语义查询(`--text`、`--n`)。
- **get**:按 id 或 limit 拉取 collection 文档(`--ids`、`--limit`)。
- **输出**:全局 `-o table`(默认)或 `-o json`。
- **入口**:在 `pyproject.toml` 中增加 `[project.scripts]`,将 `pyseekdb` 指向
`pyseekdb.cli:main`。
## Solution Description
针对 [issue #55](https://github.com/oceanbase/pyseekdb/issues/55),基于现有
`Client` / `AdminClient` 和 spec 中的连接与能力说明,实现一个统一的 CLI,便于:
- **管理**:列出/创建/删除数据库与 collections,查看 collection 信息与样本数据。
- **调试**:执行任意 SQL、对 collection 做 query/get,支持 table 与 json 两种输出。
CLI 复用 `Client()` 与 `AdminClient()`
的工厂逻辑,支持嵌入式(`--path`)与服务端(`--host`/`--port` 等)两种模式;子命令通过 argparse
组织,无额外依赖。
## Test plan
- 安装后执行 `pyseekdb --help`、`pyseekdb db --help`、`pyseekdb collections
--help` 等,确认子命令与参数展示正确。
- 在嵌入式或服务端环境下分别验证:`db list`、`collections list`、`collections info
--sample N`、`sql "SHOW TABLES"`、`query --text "..."`、`get
--limit N` 及 `-o json` 输出,确认无报错且结果符合预期。
related to https://github.com/oceanbase/pyseekdb/issues/55
## Summary by CodeRabbit
* **New Features**
* Packs a command-line interface (CLI) as a public executable entry
point.
* Adds DB management commands: list, create, delete.
* Adds collection commands: list, create, delete, info (with optional
sample).
* Adds query, document retrieval, and raw SQL execution commands.
* Supports embedded/server connection modes, configurable credentials,
and output formats (table or JSON).
✏️ Tip: You can customize this high-level summary in your review
settings.
---
pyproject.toml | 3 +
src/pyseekdb/cli/__init__.py | 14 ++
src/pyseekdb/cli/main.py | 400 +++++++++++++++++++++++++++++++++++
3 files changed, 417 insertions(+)
create mode 100644 src/pyseekdb/cli/__init__.py
create mode 100644 src/pyseekdb/cli/main.py
diff --git a/pyproject.toml b/pyproject.toml
index 38406b6a..11067c2b 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -100,6 +100,9 @@ ignore = [
[tool.ruff.format]
preview = true
+[project.scripts]
+pyseekdb = "pyseekdb.cli:main"
+
[build-system]
requires = ["pdm-backend"]
build-backend = "pdm.backend"
diff --git a/src/pyseekdb/cli/__init__.py b/src/pyseekdb/cli/__init__.py
new file mode 100644
index 00000000..f9062630
--- /dev/null
+++ b/src/pyseekdb/cli/__init__.py
@@ -0,0 +1,14 @@
+"""
+pyseekdb CLI - Debug and manage seekdb collections/databases.
+
+Usage:
+ pyseekdb [OPTIONS] db list|create|delete ...
+ pyseekdb [OPTIONS] collections list|create|delete|info ...
+ pyseekdb [OPTIONS] sql "SELECT ..."
+ pyseekdb [OPTIONS] query --text "..." [--n 5]
+ pyseekdb [OPTIONS] get [--limit 10] [--ids id1,id2]
+"""
+
+from .main import main
+
+__all__ = ["main"]
diff --git a/src/pyseekdb/cli/main.py b/src/pyseekdb/cli/main.py
new file mode 100644
index 00000000..39a7b993
--- /dev/null
+++ b/src/pyseekdb/cli/main.py
@@ -0,0 +1,400 @@
+"""
+CLI main: argument parsing, connection factory, and subcommand dispatch.
+"""
+
+import argparse
+import json
+import os
+import sys
+from typing import Any
+
+from .. import AdminClient, Client
+from ..client.admin_client import _AdminClientProxy, _ClientProxy
+from ..client.configuration import HNSWConfiguration
+
+
+def _add_connection_args(parser: argparse.ArgumentParser) -> None:
+ """Add global connection options (embedded vs server)."""
+ g = parser.add_argument_group("connection (choose one)")
+ g.add_argument(
+ "--path",
+ metavar="DIR",
+ default=None,
+ help="Embedded mode: path to seekdb data directory (default: seekdb.db in cwd)",
+ )
+ g.add_argument("--host", default=None, help="Server mode: host (e.g. localhost)")
+ g.add_argument("--port", type=int, default=2881, help="Server mode: port (default: 2881)")
+ g.add_argument("--tenant", default="sys", help="Server mode: tenant (default: sys)")
+ g.add_argument("--database", "-d", default="test", help="Database name (default: test)")
+ g.add_argument("--user", default="root", help="Server mode: user (default: root)")
+ g.add_argument(
+ "--password",
+ "-p",
+ default=None,
+ help="Server mode: password (or set SEEKDB_PASSWORD)",
+ )
+ parser.add_argument(
+ "-o",
+ "--output",
+ choices=["table", "json"],
+ default="table",
+ help="Output format (default: table)",
+ )
+
+
+def _make_client(args: argparse.Namespace) -> _ClientProxy:
+ """Build Client from parsed args (for collection operations)."""
+ password = args.password or os.environ.get("SEEKDB_PASSWORD", "")
+ return Client(
+ path=args.path,
+ host=args.host,
+ port=args.port,
+ tenant=args.tenant,
+ database=args.database,
+ user=args.user,
+ password=password,
+ )
+
+
+def _make_admin(args: argparse.Namespace) -> _AdminClientProxy:
+ """Build AdminClient from parsed args (for db operations)."""
+ password = args.password or os.environ.get("SEEKDB_PASSWORD", "")
+ return AdminClient(
+ path=args.path,
+ host=args.host,
+ port=args.port,
+ tenant=args.tenant,
+ user=args.user,
+ password=password,
+ )
+
+
+def _execute_sql(client: _ClientProxy, sql: str) -> Any:
+ """Run raw SQL using the underlying server (for debug)."""
+ server = client._server
+ return server._execute(sql)
+
+
+def _print_table(rows: list[dict[str, Any]] | None, columns: list[str] | None = None) -> None:
+ """Print rows as a simple text table."""
+ if not rows:
+ print("(0 rows)")
+ return
+ if columns is None:
+ columns = list(rows[0].keys()) if rows else []
+ col_widths = [max(len(str(c)), 3) for c in columns]
+ for r in rows:
+ for i, c in enumerate(columns):
+ val = r.get(c, "")
+ if isinstance(val, (dict, list)):
+ val = json.dumps(val, ensure_ascii=False)[:40]
+ col_widths[i] = max(col_widths[i], min(len(str(val)), 50))
+ fmt = " ".join(f"%-{w}s" for w in col_widths)
+ print(fmt % tuple(columns))
+ print("-" * (sum(col_widths) + 2 * (len(columns) - 1)))
+ for r in rows:
+ cells = []
+ for c in columns:
+ v = r.get(c, "")
+ if isinstance(v, (dict, list)):
+ v = json.dumps(v, ensure_ascii=False)[:40]
+ s = str(v)
+ if len(s) > 50:
+ s = s[:47] + "..."
+ cells.append(s)
+ print(fmt % tuple(cells))
+
+
+def _print_json(obj: Any) -> None:
+ """Print object as JSON."""
+ if hasattr(obj, "__iter__") and not isinstance(obj, (str, dict)):
+ obj = list(obj)
+ print(json.dumps(obj, indent=2, ensure_ascii=False, default=str))
+
+
+# ---------- Commands ----------
+
+
+def cmd_db_list(args: argparse.Namespace) -> int:
+ """List databases."""
+ admin = _make_admin(args)
+ try:
+ dbs = admin.list_databases()
+ rows = [{"name": d.name, "tenant": d.tenant or ""} for d in dbs]
+ if args.output == "json":
+ _print_json(rows)
+ else:
+ _print_table(rows, ["name", "tenant"])
+ return 0
+ finally:
+ admin._server._cleanup()
+
+
+def cmd_db_create(args: argparse.Namespace) -> int:
+ """Create database."""
+ admin = _make_admin(args)
+ try:
+ admin.create_database(args.name, tenant=args.tenant)
+ print(f"Created database: {args.name}")
+ return 0
+ finally:
+ admin._server._cleanup()
+
+
+def cmd_db_delete(args: argparse.Namespace) -> int:
+ """Delete database."""
+ admin = _make_admin(args)
+ try:
+ admin.delete_database(args.name, tenant=args.tenant)
+ print(f"Deleted database: {args.name}")
+ return 0
+ finally:
+ admin._server._cleanup()
+
+
+def cmd_collections_list(args: argparse.Namespace) -> int:
+ """List collections."""
+ client = _make_client(args)
+ try:
+ colls = client.list_collections()
+ rows = [
+ {
+ "name": c.name,
+ "dimension": c.dimension or "",
+ "distance": c.distance or "",
+ }
+ for c in colls
+ ]
+ if args.output == "json":
+ _print_json(rows)
+ else:
+ _print_table(rows, ["name", "dimension", "distance"])
+ return 0
+ finally:
+ client._server._cleanup()
+
+
+def cmd_collections_create(args: argparse.Namespace) -> int:
+ """Create collection."""
+ client = _make_client(args)
+ try:
+ config = HNSWConfiguration(dimension=args.dimension) if args.dimension else None
+ client.create_collection(args.name, configuration=config)
+ print(f"Created collection: {args.name}")
+ return 0
+ finally:
+ client._server._cleanup()
+
+
+def cmd_collections_delete(args: argparse.Namespace) -> int:
+ """Delete collection."""
+ client = _make_client(args)
+ try:
+ client.delete_collection(args.name)
+ print(f"Deleted collection: {args.name}")
+ return 0
+ finally:
+ client._server._cleanup()
+
+
+def cmd_collections_info(args: argparse.Namespace) -> int:
+ """Show collection info (schema, count, sample)."""
+ client = _make_client(args)
+ try:
+ if not client.has_collection(args.name):
+ print(f"Collection not found: {args.name}", file=sys.stderr)
+ return 1
+ coll = client.get_collection(args.name)
+ info = {
+ "name": coll.name,
+ "dimension": coll.dimension,
+ "distance": coll.distance,
+ "metadata": coll.metadata,
+ "count": coll.count(),
+ }
+ if args.output == "json":
+ sample = coll.peek(limit=args.sample) if args.sample and info["count"] > 0 else {}
+ payload = {"info": info, "sample": sample}
+ _print_json(payload)
+ else:
+ print(f"Name: {info['name']}")
+ print(f"Dimension: {info['dimension']}")
+ print(f"Distance: {info['distance']}")
+ print(f"Count: {info['count']}")
+ if info.get("metadata"):
+ print(f"Metadata: {info['metadata']}")
+ if args.sample and info["count"] > 0:
+ sample = coll.peek(limit=args.sample)
+ print("\nSample (peek):")
+ for i in range(len(sample["ids"])):
+ print(f" id={sample['ids'][i]}")
+ if sample.get("documents"):
+ doc = sample["documents"][i]
+ print(f" document: {str(doc)[:80]}...")
+ if sample.get("metadatas"):
+ print(f" metadata: {sample['metadatas'][i]}")
+ return 0
+ finally:
+ client._server._cleanup()
+
+
+def cmd_sql(args: argparse.Namespace) -> int:
+ """Execute raw SQL (debug)."""
+ client = _make_client(args)
+ try:
+ result = _execute_sql(client, args.sql)
+ if result is None:
+ print("OK")
+ return 0
+ if args.output == "json":
+ # result may be list of tuples or list of dicts
+ if not result:
+ _print_json([])
+ elif hasattr(result[0], "keys"):
+ _print_json(result)
+ else:
+ _print_json([list(r) for r in result])
+ else:
+ if not result:
+ print("(0 rows)")
+ elif hasattr(result[0], "keys"):
+ _print_table(result)
+ else:
+ cols = [f"col_{i}" for i in range(len(result[0]))]
+ _print_table([dict(zip(cols, r, strict=True)) for r in result], cols)
+ return 0
+ finally:
+ client._server._cleanup()
+
+
+def cmd_query(args: argparse.Namespace) -> int:
+ """Query collection by text or embedding."""
+ client = _make_client(args)
+ try:
+ if not client.has_collection(args.collection):
+ print(f"Collection not found: {args.collection}", file=sys.stderr)
+ return 1
+ coll = client.get_collection(args.collection)
+ if args.text:
+ res = coll.query(
+ query_texts=[args.text], n_results=args.n, include=args.include or ["documents", "metadatas"]
+ )
+ else:
+ print("Specify --text for query by text (embedding not supported in CLI)", file=sys.stderr)
+ return 1
+ if args.output == "json":
+ _print_json(res)
+ else:
+ ids = res.get("ids", [[]])[0]
+ docs = res.get("documents", [[]])[0] if res.get("documents") else []
+ metas = res.get("metadatas", [[]])[0] if res.get("metadatas") else []
+ dists = res.get("distances", [[]])[0] if res.get("distances") else []
+ for i in range(len(ids)):
+ print(f"id={ids[i]} distance={dists[i] if i < len(dists) else ''}")
+ if i < len(docs):
+ print(f" document: {str(docs[i])[:80]}...")
+ if i < len(metas):
+ print(f" metadata: {metas[i]}")
+ return 0
+ finally:
+ client._server._cleanup()
+
+
+def cmd_get(args: argparse.Namespace) -> int:
+ """Get documents from collection by ids or limit."""
+ client = _make_client(args)
+ try:
+ if not client.has_collection(args.collection):
+ print(f"Collection not found: {args.collection}", file=sys.stderr)
+ return 1
+ coll = client.get_collection(args.collection)
+ ids = None
+ if args.ids:
+ ids = [x.strip() for x in args.ids.split(",") if x.strip()]
+ res = coll.get(
+ ids=ids,
+ limit=args.limit,
+ include=args.include or ["documents", "metadatas"],
+ )
+ if args.output == "json":
+ _print_json(res)
+ else:
+ for i in range(len(res.get("ids", []))):
+ print(f"id={res['ids'][i]}")
+ if res.get("documents") and i < len(res["documents"]):
+ print(f" document: {str(res['documents'][i])[:80]}...")
+ if res.get("metadatas") and i < len(res["metadatas"]):
+ print(f" metadata: {res['metadatas'][i]}")
+ return 0
+ finally:
+ client._server._cleanup()
+
+
+def main(argv: list[str] | None = None) -> int:
+ """CLI entry point."""
+ parser = argparse.ArgumentParser(
+ prog="pyseekdb",
+ description="seekdb CLI: debug and manage collections/databases (see spec.md).",
+ )
+ _add_connection_args(parser)
+ sub = parser.add_subparsers(dest="command", required=True, help="command")
+
+ # db
+ db = sub.add_parser("db", help="Database (admin) operations")
+ db_sub = db.add_subparsers(dest="db_command", required=True)
+ db_list = db_sub.add_parser("list", help="List databases")
+ db_list.set_defaults(func=cmd_db_list)
+ db_create = db_sub.add_parser("create", help="Create database")
+ db_create.add_argument("name", help="Database name")
+ db_create.set_defaults(func=cmd_db_create)
+ db_delete = db_sub.add_parser("delete", help="Delete database")
+ db_delete.add_argument("name", help="Database name")
+ db_delete.set_defaults(func=cmd_db_delete)
+
+ # collections (and alias coll)
+ def _add_collection_subparsers(parent: argparse.ArgumentParser) -> None:
+ csub = parent.add_subparsers(dest="coll_command", required=True)
+ csub.add_parser("list", help="List collections").set_defaults(func=cmd_collections_list)
+ create = csub.add_parser("create", help="Create collection")
+ create.add_argument("name", help="Collection name")
+ create.add_argument("--dimension", type=int, default=None, help="Vector dimension")
+ create.set_defaults(func=cmd_collections_create)
+ delete = csub.add_parser("delete", help="Delete collection")
+ delete.add_argument("name", help="Collection name")
+ delete.set_defaults(func=cmd_collections_delete)
+ info = csub.add_parser("info", help="Show collection info and optional sample")
+ info.add_argument("name", help="Collection name")
+ info.add_argument("--sample", type=int, default=0, metavar="N", help="Peek first N rows")
+ info.set_defaults(func=cmd_collections_info)
+
+ _add_collection_subparsers(sub.add_parser("collections", help="Collection operations"))
+ _add_collection_subparsers(sub.add_parser("coll", help="Alias for collections"))
+
+ # sql
+ sql_p = sub.add_parser("sql", help="Execute raw SQL (debug)")
+ _add_connection_args(sql_p)
+ sql_p.add_argument("sql", help="SQL statement")
+ sql_p.set_defaults(func=cmd_sql)
+
+ # query
+ query_p = sub.add_parser("query", help="Query collection by text")
+ _add_connection_args(query_p)
+ query_p.add_argument("collection", help="Collection name")
+ query_p.add_argument(
+ "--text", "-t", required=True, help="Query text (will be embedded if collection has embedding)"
+ )
+ query_p.add_argument("--n", type=int, default=10, help="Number of results (default: 10)")
+ query_p.add_argument("--include", nargs="+", default=None, help="Include fields: documents, metadatas, embeddings")
+ query_p.set_defaults(func=cmd_query)
+
+ # get
+ get_p = sub.add_parser("get", help="Get documents from collection")
+ _add_connection_args(get_p)
+ get_p.add_argument("collection", help="Collection name")
+ get_p.add_argument("--ids", default=None, help="Comma-separated IDs")
+ get_p.add_argument("--limit", type=int, default=10, help="Max rows (default: 10)")
+ get_p.add_argument("--include", nargs="+", default=None, help="Include fields")
+ get_p.set_defaults(func=cmd_get)
+
+ args = parser.parse_args(argv)
+ return args.func(args)
From 38e58bfe1716a3865f39ec2948a21637f0d17186 Mon Sep 17 00:00:00 2001
From: wangyunlai
Date: Mon, 2 Feb 2026 16:23:46 +0800
Subject: [PATCH 09/10] fix ruff check (#162)
## Summary
close #137
refactor DefaultEmbeddingFunction.
Split it into two classes: OnnxEmbeddingFunction and
DefaultEmbeddingFunction.
DefaultEmbeddingFunction worked based on OnnxEmbeddingFunction.
OnnxEmbeddingFunction can execute model based on ONNX.
## Summary by CodeRabbit
* **New Features**
* Added a standalone ONNX-based embedding implementation and exposed it
as an embedding option.
* **Refactor**
* Default embedding now delegates embedding work to the new ONNX
embedding path for simpler, modular behavior.
* **Breaking Change**
* Removed several public embedding-related attributes and updated the
default embedding constructor signature.
* **Tests**
* Added unit tests for the ONNX embedding and adjusted test startup path
handling.
---
src/pyseekdb/client/embedding_function.py | 372 ++---------------
.../utils/embedding_functions/__init__.py | 2 +
.../onnx_embedding_function.py | 392 ++++++++++++++++++
tests/integration_tests/conftest.py | 9 +-
.../test_onnx_embedding_function.py | 72 ++++
5 files changed, 495 insertions(+), 352 deletions(-)
create mode 100644 src/pyseekdb/utils/embedding_functions/onnx_embedding_function.py
create mode 100644 tests/unit_tests/test_onnx_embedding_function.py
diff --git a/src/pyseekdb/client/embedding_function.py b/src/pyseekdb/client/embedding_function.py
index 5d1d2d86..460e335b 100644
--- a/src/pyseekdb/client/embedding_function.py
+++ b/src/pyseekdb/client/embedding_function.py
@@ -5,12 +5,9 @@
for converting text documents to vector embeddings.
"""
-import contextlib
import logging
-import os
+import warnings
from abc import abstractmethod
-from functools import cached_property
-from pathlib import Path
from typing import (
Any,
ClassVar,
@@ -20,15 +17,6 @@
runtime_checkable,
)
-import httpx
-import numpy as np
-import numpy.typing as npt
-
-# Set Hugging Face mirror endpoint for better download speed in China
-# Users can override this by setting HF_ENDPOINT environment variable
-if "HF_ENDPOINT" not in os.environ:
- os.environ["HF_ENDPOINT"] = "https://hf-mirror.com"
-
logger = logging.getLogger(__name__)
# Type variable for input types
@@ -152,11 +140,8 @@ class DefaultEmbeddingFunction(EmbeddingFunction[Documents]):
>>> print(len(embeddings[0])) # 384
"""
- MODEL_NAME = "all-MiniLM-L6-v2"
- HF_MODEL_ID = "sentence-transformers/all-MiniLM-L6-v2" # Hugging Face model ID
- DOWNLOAD_PATH = Path.home() / ".cache" / "pyseekdb" / "onnx_models" / MODEL_NAME
- EXTRACTED_FOLDER_NAME = "onnx"
- ARCHIVE_FILENAME = "onnx.tar.gz"
+ _MODEL_NAME = "all-MiniLM-L6-v2"
+ _HF_MODEL_ID = "sentence-transformers/all-MiniLM-L6-v2" # Hugging Face model ID
_DIMENSION = 384 # all-MiniLM-L6-v2 produces 384-dimensional embeddings
def __init__(
@@ -168,344 +153,35 @@ def __init__(
Initialize the default embedding function.
Args:
- model_name: Name of the model (currently only 'all-MiniLM-L6-v2' is supported).
- Default is 'all-MiniLM-L6-v2' (384 dimensions).
- preferred_providers: The preferred ONNX runtime providers.
- Defaults to None (uses available providers).
+ model_name: str = "all-MiniLM-L6-v2", # Deprecated. Will be removed in a future version.
+ preferred_providers: list[str] | None = None, # Deprecated. Will be removed in a future version.
+ # The preferred ONNX runtime providers. Defaults to None (uses available providers).
"""
- if model_name != "all-MiniLM-L6-v2":
- raise ValueError(f"Currently only 'all-MiniLM-L6-v2' is supported, got '{model_name}'")
- self.model_name = model_name
-
- # Validate preferred_providers
- if preferred_providers and not all(isinstance(i, str) for i in preferred_providers):
- raise ValueError("Preferred providers must be a list of strings")
- if preferred_providers and len(preferred_providers) != len(set(preferred_providers)):
- raise ValueError("Preferred providers must be unique")
-
- self._preferred_providers = preferred_providers
-
- # Import required modules
- import onnxruntime as ort_module
- import tokenizers
- import tqdm
+ if model_name != self._MODEL_NAME:
+ raise ValueError(f"Currently only '{self._MODEL_NAME}' is supported, got '{model_name}'")
+ if preferred_providers:
+ warnings.warn(
+ "preferred_providers is deprecated and will be removed in a future version. "
+ "Use the preferred_providers argument of OnnxEmbeddingFunction instead.",
+ DeprecationWarning,
+ stacklevel=2,
+ )
+ self.model_name = self._MODEL_NAME
+ from pyseekdb.utils.embedding_functions import OnnxEmbeddingFunction
- self.ort = ort_module
- self.tokenizers = tokenizers # Store the module
- self.tqdm = tqdm.tqdm
+ self._onnx = OnnxEmbeddingFunction(
+ model_name=self._MODEL_NAME,
+ hf_model_id=self._HF_MODEL_ID,
+ dimension=self._DIMENSION,
+ )
@property
def dimension(self) -> int:
- """Get the dimension of embeddings produced by this function"""
+ """Get the dimension of embeddings produced by this function."""
return self._DIMENSION
- def _download(self, url: str, fname: str, chunk_size: int = 8192) -> None:
- """
- Download a file from the URL and save it to the file path.
-
- Args:
- url: The URL to download the file from.
- fname: The path to save the file to.
- chunk_size: The chunk size to use when downloading (default: 8192 for better speed).
- """
- logger.info(f"Downloading from {url}")
- # Use Client to ensure correct handling of redirects
- with httpx.Client(timeout=600.0, follow_redirects=True) as client, client.stream("GET", url) as resp:
- resp.raise_for_status()
- total = int(resp.headers.get("content-length", 0))
- with (
- open(fname, "wb") as file,
- self.tqdm(
- desc=os.path.basename(fname),
- total=total,
- unit="iB",
- unit_scale=True,
- unit_divisor=1024,
- ) as bar,
- ):
- for data in resp.iter_bytes(chunk_size=chunk_size):
- size = file.write(data)
- bar.update(size)
-
- def _get_hf_endpoint(self) -> str:
- """Get Hugging Face endpoint URL, using HF_ENDPOINT environment variable if set."""
- return os.environ.get("HF_ENDPOINT", "https://huggingface.co")
-
- def _download_from_huggingface(self) -> bool: # noqa: C901
- """
- Download model files from Hugging Face (supports mirror acceleration).
-
- Returns:
- True if download successful, False otherwise.
- """
- try:
- hf_endpoint = self._get_hf_endpoint()
- # Remove trailing slash
- hf_endpoint = hf_endpoint.rstrip("/")
-
- # List of files to download
- # ONNX model files are in the onnx/ subdirectory, other files in the root directory
- files_to_download = {
- "onnx/model.onnx": "model.onnx", # ONNX file in onnx subdirectory
- "tokenizer.json": "tokenizer.json",
- "config.json": "config.json",
- "special_tokens_map.json": "special_tokens_map.json",
- "tokenizer_config.json": "tokenizer_config.json",
- "vocab.txt": "vocab.txt",
- }
-
- extracted_folder = os.path.join(self.DOWNLOAD_PATH, self.EXTRACTED_FOLDER_NAME)
- os.makedirs(extracted_folder, exist_ok=True)
-
- logger.info(f"Downloading model from Hugging Face (endpoint: {hf_endpoint})")
-
- # Download each file
- for hf_filename, local_filename in files_to_download.items():
- local_path = os.path.join(extracted_folder, local_filename)
-
- # Skip if file already exists
- if os.path.exists(local_path):
- continue
-
- # Construct Hugging Face download URL
- # Format: https://hf-mirror.com/sentence-transformers/all-MiniLM-L6-v2/resolve/main/onnx/model.onnx
- # Or: https://hf-mirror.com/sentence-transformers/all-MiniLM-L6-v2/resolve/main/tokenizer.json
- url = f"{hf_endpoint}/{self.HF_MODEL_ID}/resolve/main/{hf_filename}"
-
- try:
- # First check if file exists (HEAD request)
- with contextlib.suppress(Exception):
- head_resp = httpx.head(url, timeout=10.0, follow_redirects=True)
- if head_resp.status_code == 404:
- logger.warning(f"File {hf_filename} not found on Hugging Face (404), will try fallback")
- return False
-
- self._download(url, local_path, chunk_size=8192)
- logger.info(f"Successfully downloaded {local_filename}")
- except httpx.HTTPStatusError as e:
- if e.response.status_code == 404:
- logger.warning(f"File {hf_filename} not found on Hugging Face (404), will try fallback")
- return False
- logger.warning(f"HTTP error downloading {hf_filename} from Hugging Face: {e}")
- if os.path.exists(local_path):
- os.remove(local_path)
- return False
- except Exception as e:
- logger.warning(f"Failed to download {hf_filename} from Hugging Face: {e}")
- # If download fails, try to delete partially downloaded file
- if os.path.exists(local_path):
- os.remove(local_path)
- return False
-
- # Verify critical files exist
- if not os.path.exists(os.path.join(extracted_folder, "model.onnx")):
- logger.error("model.onnx not found after download")
- return False
- if not os.path.exists(os.path.join(extracted_folder, "tokenizer.json")):
- logger.error("tokenizer.json not found after download")
- return False
-
- logger.info("Successfully downloaded all model files from Hugging Face")
- return True # noqa: TRY300
-
- except Exception:
- logger.exception("Error downloading from Hugging Face")
- return False
-
- def _forward(self, documents: list[str], batch_size: int = 32) -> npt.NDArray[np.float32]:
- """
- Generate embeddings for a list of documents.
-
- Args:
- documents: The documents to generate embeddings for.
- batch_size: The batch size to use when generating embeddings.
-
- Returns:
- The embeddings for the documents.
- """
- all_embeddings = []
- for i in range(0, len(documents), batch_size):
- batch = documents[i : i + batch_size]
-
- # Encode each document separately
- encoded = [self.tokenizer.encode(d) for d in batch]
-
- # Check if any document exceeds the max tokens
- for doc_tokens in encoded:
- if len(doc_tokens.ids) > self.max_tokens():
- raise ValueError(
- f"Document length {len(doc_tokens.ids)} is greater than the max tokens {self.max_tokens()}"
- )
-
- # Create input arrays exactly like the working standalone script
- # Create input arrays, ensuring int64 type
- input_ids = np.array([e.ids for e in encoded], dtype=np.int64)
- attention_mask = np.array([e.attention_mask for e in encoded], dtype=np.int64)
-
- # Ensure 2D arrays (batch_size, seq_length)
- if input_ids.ndim == 1:
- input_ids = input_ids.reshape(1, -1)
- if attention_mask.ndim == 1:
- attention_mask = attention_mask.reshape(1, -1)
-
- # Use zeros_like to create token_type_ids, ensuring exact shape match
- token_type_ids = np.zeros_like(input_ids, dtype=np.int64)
-
- # Ensure all arrays are contiguous, which is important for onnxruntime 1.19.0
- input_ids = np.ascontiguousarray(input_ids, dtype=np.int64)
- attention_mask = np.ascontiguousarray(attention_mask, dtype=np.int64)
- token_type_ids = np.ascontiguousarray(token_type_ids, dtype=np.int64)
-
- onnx_input = {
- "input_ids": input_ids,
- "attention_mask": attention_mask,
- "token_type_ids": token_type_ids,
- }
-
- model_output = self.model.run(None, onnx_input)
- last_hidden_state = model_output[0]
-
- # Mean pooling (exactly as in the code)
- # Note: attention_mask needs to be converted to float type for floating point operations
- attention_mask_float = attention_mask.astype(np.float32)
- input_mask_expanded = np.broadcast_to(np.expand_dims(attention_mask_float, -1), last_hidden_state.shape)
- embeddings = np.sum(last_hidden_state * input_mask_expanded, 1) / np.clip(
- input_mask_expanded.sum(1), a_min=1e-9, a_max=None
- )
-
- embeddings = embeddings.astype(np.float32)
- all_embeddings.append(embeddings)
-
- return np.concatenate(all_embeddings)
-
- @cached_property
- def tokenizer(self) -> Any:
- """
- Get the tokenizer for the model.
-
- Returns:
- The tokenizer for the model.
- """
- tokenizer = self.tokenizers.Tokenizer.from_file(
- os.path.join(self.DOWNLOAD_PATH, self.EXTRACTED_FOLDER_NAME, "tokenizer.json")
- )
- # max_seq_length = 256, for some reason sentence-transformers uses 256
- # even though the HF config has a max length of 128
- tokenizer.enable_truncation(max_length=256)
- tokenizer.enable_padding(pad_id=0, pad_token="[PAD]", length=256) # noqa: S106
- return tokenizer
-
- @cached_property
- def model(self) -> Any:
- """
- Get the model.
-
- Returns:
- The model.
- """
- if self._preferred_providers is None or len(self._preferred_providers) == 0:
- if len(self.ort.get_available_providers()) > 0:
- logger.debug(
- f"WARNING: No ONNX providers provided, defaulting to available providers: "
- f"{self.ort.get_available_providers()}"
- )
- self._preferred_providers = self.ort.get_available_providers()
- elif not set(self._preferred_providers).issubset(set(self.ort.get_available_providers())):
- raise ValueError(
- f"Preferred providers must be subset of available providers: {self.ort.get_available_providers()}"
- )
-
- # Create minimal session options to avoid issues
- so = self.ort.SessionOptions()
- so.log_severity_level = 3
- # Disable all optimizations that might cause issues
- so.graph_optimization_level = self.ort.GraphOptimizationLevel.ORT_DISABLE_ALL
- so.execution_mode = self.ort.ExecutionMode.ORT_SEQUENTIAL
- so.inter_op_num_threads = 1
- so.intra_op_num_threads = 1
-
- if self._preferred_providers and "CoreMLExecutionProvider" in self._preferred_providers:
- # remove CoreMLExecutionProvider from the list, it is not as well optimized as CPU.
- self._preferred_providers.remove("CoreMLExecutionProvider")
-
- return self.ort.InferenceSession(
- os.path.join(self.DOWNLOAD_PATH, self.EXTRACTED_FOLDER_NAME, "model.onnx"),
- # Force CPU execution provider to avoid provider issues
- providers=["CPUExecutionProvider"],
- sess_options=so,
- )
-
- def _download_model_if_not_exists(self) -> None:
- """
- Download from Hugging Face with image mirror if the model doesn't exist.
- """
- onnx_files = [
- "config.json",
- "model.onnx",
- "special_tokens_map.json",
- "tokenizer_config.json",
- "tokenizer.json",
- "vocab.txt",
- ]
- extracted_folder = os.path.join(self.DOWNLOAD_PATH, self.EXTRACTED_FOLDER_NAME)
- onnx_files_exist = True
- for f in onnx_files:
- if not os.path.exists(os.path.join(extracted_folder, f)):
- onnx_files_exist = False
- break
-
- # Model is not downloaded yet
- if not onnx_files_exist:
- os.makedirs(self.DOWNLOAD_PATH, exist_ok=True)
-
- logger.info("Attempting to download model from Hugging Face...")
- hf_endpoint = self._get_hf_endpoint()
- if not self._download_from_huggingface():
- raise RuntimeError(
- f"Failed to download model from Hugging Face (endpoint: {hf_endpoint}). "
- f"Please check your network connection or set HF_ENDPOINT environment variable "
- f"to use a mirror site (e.g., export HF_ENDPOINT='https://hf-mirror.com'). "
- f"Model ID: {self.HF_MODEL_ID}"
- )
- logger.info("Model downloaded successfully from Hugging Face")
-
- def max_tokens(self) -> int:
- """Get the maximum number of tokens supported by the model."""
- return 256
-
def __call__(self, documents: Documents) -> Embeddings:
- """
- Generate embeddings for the given documents.
-
- Args:
- documents: Single document (str) or list of documents (List[str])
-
- Returns:
- List of embedding vectors
-
- Example:
- >>> ef = DefaultEmbeddingFunction()
- >>> # Single document
- >>> embedding = ef("Hello world")
- >>> # Multiple documents
- >>> embeddings = ef(["Hello", "World"])
- """
- # Handle single string input
- if isinstance(documents, str):
- documents = [documents]
-
- # Handle empty input
- if not documents:
- return []
-
- # Only download the model when it is actually used
- self._download_model_if_not_exists()
-
- # Generate embeddings
- embeddings = self._forward(documents)
-
- # Convert numpy arrays to lists
- return [embedding.tolist() for embedding in embeddings]
+ return self._onnx(documents)
@staticmethod
def name() -> str:
diff --git a/src/pyseekdb/utils/embedding_functions/__init__.py b/src/pyseekdb/utils/embedding_functions/__init__.py
index eace5d2d..de32a65b 100644
--- a/src/pyseekdb/utils/embedding_functions/__init__.py
+++ b/src/pyseekdb/utils/embedding_functions/__init__.py
@@ -13,6 +13,7 @@
from .mistral_embedding_function import MistralEmbeddingFunction
from .morph_embedding_function import MorphEmbeddingFunction
from .ollama_embedding_function import OllamaEmbeddingFunction
+from .onnx_embedding_function import OnnxEmbeddingFunction
from .openai_base_embedding_function import OpenAIBaseEmbeddingFunction
from .openai_embedding_function import OpenAIEmbeddingFunction
from .qwen_embedding_function import QwenEmbeddingFunction
@@ -32,6 +33,7 @@
"MistralEmbeddingFunction",
"MorphEmbeddingFunction",
"OllamaEmbeddingFunction",
+ "OnnxEmbeddingFunction",
"OpenAIBaseEmbeddingFunction",
"OpenAIEmbeddingFunction",
"QwenEmbeddingFunction",
diff --git a/src/pyseekdb/utils/embedding_functions/onnx_embedding_function.py b/src/pyseekdb/utils/embedding_functions/onnx_embedding_function.py
new file mode 100644
index 00000000..8328cf0a
--- /dev/null
+++ b/src/pyseekdb/utils/embedding_functions/onnx_embedding_function.py
@@ -0,0 +1,392 @@
+"""
+ONNX-based embedding function implementation.
+
+This module provides a generic ONNX embedding function that can run
+sentence-transformer style models via onnxruntime.
+"""
+
+import contextlib
+import logging
+import os
+from functools import cached_property
+from pathlib import Path
+from typing import Any
+
+import httpx
+import numpy as np
+import numpy.typing as npt
+
+logger = logging.getLogger(__name__)
+
+Documents = str | list[str]
+Embeddings = list[list[float]]
+
+
+class OnnxEmbeddingFunction:
+ """
+ Generic ONNX runtime embedding function.
+
+ This class handles model download, tokenizer/model loading, and embedding
+ generation using onnxruntime.
+ """
+
+ EXTRACTED_FOLDER_NAME = "onnx"
+ ARCHIVE_FILENAME = "onnx.tar.gz"
+
+ def __init__(
+ self,
+ model_name: str,
+ hf_model_id: str,
+ dimension: int,
+ download_path: Path | None = None,
+ preferred_providers: list[str] | None = None,
+ ):
+ """
+ Initialize an ONNX embedding function.
+
+ Args:
+ model_name: Name of the model (used for cache directory naming).
+ hf_model_id: Hugging Face model ID.
+ dimension: Output embedding dimension.
+ download_path: Optional cache path override.
+ preferred_providers: Preferred ONNX runtime providers.
+ """
+ if not model_name:
+ raise ValueError("model_name must be a non-empty string")
+ if not hf_model_id:
+ raise ValueError("hf_model_id must be a non-empty string")
+ if dimension <= 0:
+ raise ValueError("dimension must be a positive integer")
+
+ self.model_name = model_name
+ self.hf_model_id = hf_model_id
+ self._dimension = dimension
+ self.download_path = (
+ download_path
+ if download_path is not None
+ else Path.home() / ".cache" / "pyseekdb" / "onnx_models" / model_name
+ )
+
+ # Validate preferred_providers
+ if preferred_providers and not all(isinstance(i, str) for i in preferred_providers):
+ raise ValueError("Preferred providers must be a list of strings")
+ if preferred_providers and len(preferred_providers) != len(set(preferred_providers)):
+ raise ValueError("Preferred providers must be unique")
+
+ self._preferred_providers = preferred_providers
+
+ # Import required modules lazily to avoid hard dependencies at import time
+ import onnxruntime as ort_module
+ import tokenizers
+ import tqdm
+
+ self.ort = ort_module
+ self.tokenizers = tokenizers # Store the module
+ self.tqdm = tqdm.tqdm
+
+ @property
+ def dimension(self) -> int:
+ """Get the dimension of embeddings produced by this function."""
+ return self._dimension
+
+ def _download(self, url: str, fname: str, chunk_size: int = 8192) -> None:
+ """
+ Download a file from the URL and save it to the file path.
+
+ Args:
+ url: The URL to download the file from.
+ fname: The path to save the file to.
+ chunk_size: The chunk size to use when downloading.
+ """
+ logger.info(f"Downloading from {url}")
+ # Use Client to ensure correct handling of redirects
+ with httpx.Client(timeout=600.0, follow_redirects=True) as client, client.stream("GET", url) as resp:
+ resp.raise_for_status()
+ total = int(resp.headers.get("content-length", 0))
+ with (
+ open(fname, "wb") as file,
+ self.tqdm(
+ desc=os.path.basename(fname),
+ total=total,
+ unit="iB",
+ unit_scale=True,
+ unit_divisor=1024,
+ ) as bar,
+ ):
+ for data in resp.iter_bytes(chunk_size=chunk_size):
+ size = file.write(data)
+ bar.update(size)
+
+ def _get_hf_endpoint(self) -> str:
+ """Get Hugging Face endpoint URL, using HF_ENDPOINT environment variable if set."""
+ return os.environ.get("HF_ENDPOINT", "https://hf-mirror.com")
+
+ def _download_from_huggingface(self) -> bool: # noqa: C901
+ """
+ Download model files from Hugging Face (supports mirror acceleration).
+
+ Returns:
+ True if download successful, False otherwise.
+ """
+ try:
+ hf_endpoint = self._get_hf_endpoint()
+ # Remove trailing slash
+ hf_endpoint = hf_endpoint.rstrip("/")
+
+ # List of files to download
+ # ONNX model files are in the onnx/ subdirectory, other files in the root directory
+ files_to_download = {
+ "onnx/model.onnx": "model.onnx", # ONNX file in onnx subdirectory
+ "tokenizer.json": "tokenizer.json",
+ "config.json": "config.json",
+ "special_tokens_map.json": "special_tokens_map.json",
+ "tokenizer_config.json": "tokenizer_config.json",
+ "vocab.txt": "vocab.txt",
+ }
+
+ extracted_folder = os.path.join(self.download_path, self.EXTRACTED_FOLDER_NAME)
+ os.makedirs(extracted_folder, exist_ok=True)
+
+ logger.info(f"Downloading model from Hugging Face (endpoint: {hf_endpoint})")
+
+ # Download each file
+ for hf_filename, local_filename in files_to_download.items():
+ local_path = os.path.join(extracted_folder, local_filename)
+
+ # Skip if file already exists
+ if os.path.exists(local_path):
+ continue
+
+ # Construct Hugging Face download URL
+ url = f"{hf_endpoint}/{self.hf_model_id}/resolve/main/{hf_filename}"
+
+ try:
+ # First check if file exists (HEAD request)
+ with contextlib.suppress(Exception):
+ head_resp = httpx.head(url, timeout=10.0, follow_redirects=True)
+ if head_resp.status_code == 404:
+ logger.warning(f"File {hf_filename} not found on Hugging Face (404), will try fallback")
+ return False
+
+ self._download(url, local_path, chunk_size=8192)
+ logger.info(f"Successfully downloaded {local_filename}")
+ except httpx.HTTPStatusError as e:
+ if e.response.status_code == 404:
+ logger.warning(f"File {hf_filename} not found on Hugging Face (404), will try fallback")
+ return False
+ logger.warning(f"HTTP error downloading {hf_filename} from Hugging Face: {e}")
+ if os.path.exists(local_path):
+ os.remove(local_path)
+ return False
+ except Exception as e:
+ logger.warning(f"Failed to download {hf_filename} from Hugging Face: {e}")
+ # If download fails, try to delete partially downloaded file
+ if os.path.exists(local_path):
+ os.remove(local_path)
+ return False
+
+ # Verify critical files exist
+ if not os.path.exists(os.path.join(extracted_folder, "model.onnx")):
+ logger.error("model.onnx not found after download")
+ return False
+ if not os.path.exists(os.path.join(extracted_folder, "tokenizer.json")):
+ logger.error("tokenizer.json not found after download")
+ return False
+
+ logger.info("Successfully downloaded all model files from Hugging Face")
+ return True # noqa: TRY300
+
+ except Exception:
+ logger.exception("Error downloading from Hugging Face")
+ return False
+
+ def _forward(self, documents: list[str], batch_size: int = 32) -> npt.NDArray[np.float32]:
+ """
+ Generate embeddings for a list of documents.
+
+ Args:
+ documents: The documents to generate embeddings for.
+ batch_size: The batch size to use when generating embeddings.
+
+ Returns:
+ The embeddings for the documents.
+ """
+ all_embeddings = []
+ for i in range(0, len(documents), batch_size):
+ batch = documents[i : i + batch_size]
+
+ # Encode each document separately
+ encoded = [self.tokenizer.encode(d) for d in batch]
+
+ # Check if any document exceeds the max tokens
+ for doc_tokens in encoded:
+ if len(doc_tokens.ids) > self.max_tokens():
+ raise ValueError(
+ f"Document length {len(doc_tokens.ids)} is greater than the max tokens {self.max_tokens()}"
+ )
+
+ # Create input arrays exactly like the working standalone script
+ # Create input arrays, ensuring int64 type
+ input_ids = np.array([e.ids for e in encoded], dtype=np.int64)
+ attention_mask = np.array([e.attention_mask for e in encoded], dtype=np.int64)
+
+ # Ensure 2D arrays (batch_size, seq_length)
+ if input_ids.ndim == 1:
+ input_ids = input_ids.reshape(1, -1)
+ if attention_mask.ndim == 1:
+ attention_mask = attention_mask.reshape(1, -1)
+
+ # Use zeros_like to create token_type_ids, ensuring exact shape match
+ token_type_ids = np.zeros_like(input_ids, dtype=np.int64)
+
+ # Ensure all arrays are contiguous, which is important for onnxruntime 1.19.0
+ input_ids = np.ascontiguousarray(input_ids, dtype=np.int64)
+ attention_mask = np.ascontiguousarray(attention_mask, dtype=np.int64)
+ token_type_ids = np.ascontiguousarray(token_type_ids, dtype=np.int64)
+
+ onnx_input = {
+ "input_ids": input_ids,
+ "attention_mask": attention_mask,
+ "token_type_ids": token_type_ids,
+ }
+
+ model_output = self.model.run(None, onnx_input)
+ last_hidden_state = model_output[0]
+
+ # Mean pooling (exactly as in the code)
+ # Note: attention_mask needs to be converted to float type for floating point operations
+ attention_mask_float = attention_mask.astype(np.float32)
+ input_mask_expanded = np.broadcast_to(np.expand_dims(attention_mask_float, -1), last_hidden_state.shape)
+ embeddings = np.sum(last_hidden_state * input_mask_expanded, 1) / np.clip(
+ input_mask_expanded.sum(1), a_min=1e-9, a_max=None
+ )
+
+ embeddings = embeddings.astype(np.float32)
+ all_embeddings.append(embeddings)
+
+ return np.concatenate(all_embeddings)
+
+ @cached_property
+ def tokenizer(self) -> Any:
+ """
+ Get the tokenizer for the model.
+
+ Returns:
+ The tokenizer for the model.
+ """
+ tokenizer = self.tokenizers.Tokenizer.from_file(
+ os.path.join(self.download_path, self.EXTRACTED_FOLDER_NAME, "tokenizer.json")
+ )
+ # max_seq_length = 256, for some reason sentence-transformers uses 256
+ # even though the HF config has a max length of 128
+ tokenizer.enable_truncation(max_length=256)
+ tokenizer.enable_padding(pad_id=0, pad_token="[PAD]", length=256) # noqa: S106
+ return tokenizer
+
+ @cached_property
+ def model(self) -> Any:
+ """
+ Get the model.
+
+ Returns:
+ The model.
+ """
+ if self._preferred_providers is None or len(self._preferred_providers) == 0:
+ if len(self.ort.get_available_providers()) > 0:
+ logger.debug(
+ f"WARNING: No ONNX providers provided, defaulting to available providers: "
+ f"{self.ort.get_available_providers()}"
+ )
+ self._preferred_providers = self.ort.get_available_providers()
+ elif not set(self._preferred_providers).issubset(set(self.ort.get_available_providers())):
+ raise ValueError(
+ f"Preferred providers must be subset of available providers: {self.ort.get_available_providers()}"
+ )
+
+ # Create minimal session options to avoid issues
+ so = self.ort.SessionOptions()
+ so.log_severity_level = 3
+ # Disable all optimizations that might cause issues
+ so.graph_optimization_level = self.ort.GraphOptimizationLevel.ORT_DISABLE_ALL
+ so.execution_mode = self.ort.ExecutionMode.ORT_SEQUENTIAL
+ so.inter_op_num_threads = 1
+ so.intra_op_num_threads = 1
+
+ if self._preferred_providers and "CoreMLExecutionProvider" in self._preferred_providers:
+ # remove CoreMLExecutionProvider from the list, it is not as well optimized as CPU.
+ self._preferred_providers.remove("CoreMLExecutionProvider")
+
+ return self.ort.InferenceSession(
+ os.path.join(self.download_path, self.EXTRACTED_FOLDER_NAME, "model.onnx"),
+ # Force CPU execution provider to avoid provider issues
+ providers=["CPUExecutionProvider"],
+ sess_options=so,
+ )
+
+ def _download_model_if_not_exists(self) -> None:
+ """
+ Download from Hugging Face with image mirror if the model doesn't exist.
+ """
+ onnx_files = [
+ "config.json",
+ "model.onnx",
+ "special_tokens_map.json",
+ "tokenizer_config.json",
+ "tokenizer.json",
+ "vocab.txt",
+ ]
+ extracted_folder = os.path.join(self.download_path, self.EXTRACTED_FOLDER_NAME)
+ onnx_files_exist = True
+ for f in onnx_files:
+ if not os.path.exists(os.path.join(extracted_folder, f)):
+ onnx_files_exist = False
+ break
+
+ # Model is not downloaded yet
+ if not onnx_files_exist:
+ os.makedirs(self.download_path, exist_ok=True)
+
+ logger.info("Attempting to download model from Hugging Face...")
+ hf_endpoint = self._get_hf_endpoint()
+ if not self._download_from_huggingface():
+ raise RuntimeError(
+ f"Failed to download model from Hugging Face (endpoint: {hf_endpoint}). "
+ f"Please check your network connection or set HF_ENDPOINT environment variable "
+ f"to use a mirror site (e.g., export HF_ENDPOINT='https://hf-mirror.com'). "
+ f"Model ID: {self.hf_model_id}"
+ )
+ logger.info("Model downloaded successfully from Hugging Face")
+
+ def max_tokens(self) -> int:
+ """Get the maximum number of tokens supported by the model."""
+ return 256
+
+ def __call__(self, documents: Documents) -> Embeddings:
+ """
+ Generate embeddings for the given documents.
+
+ Args:
+ documents: Single document (str) or list of documents (List[str])
+
+ Returns:
+ List of embedding vectors
+ """
+ # Handle single string input
+ if isinstance(documents, str):
+ documents = [documents]
+
+ # Handle empty input
+ if not documents:
+ return []
+
+ # Only download the model when it is actually used
+ self._download_model_if_not_exists()
+
+ # Generate embeddings
+ embeddings = self._forward(documents)
+
+ # Convert numpy arrays to lists
+ return [embedding.tolist() for embedding in embeddings]
+
+ def __repr__(self) -> str:
+ return f"OnnxEmbeddingFunction(model_name='{self.model_name}')"
diff --git a/tests/integration_tests/conftest.py b/tests/integration_tests/conftest.py
index 3739e7dc..257c24df 100644
--- a/tests/integration_tests/conftest.py
+++ b/tests/integration_tests/conftest.py
@@ -10,15 +10,16 @@
import pytest
-# Add project path
-project_root = Path(__file__).parent.parent
-sys.path.insert(0, str(project_root))
+# Add project path (repo root + src)
+repo_root = Path(__file__).resolve().parents[2]
+src_root = repo_root / "src"
+sys.path.insert(0, str(src_root))
import pyseekdb # noqa: E402
# ==================== Environment Variable Configuration ====================
# Embedded mode
-SEEKDB_PATH = os.environ.get("SEEKDB_PATH", os.path.join(project_root, "seekdb.db"))
+SEEKDB_PATH = os.environ.get("SEEKDB_PATH", os.path.join(repo_root, "seekdb.db"))
SEEKDB_DATABASE = os.environ.get("SEEKDB_DATABASE", "test")
# Server mode
diff --git a/tests/unit_tests/test_onnx_embedding_function.py b/tests/unit_tests/test_onnx_embedding_function.py
new file mode 100644
index 00000000..4f34b339
--- /dev/null
+++ b/tests/unit_tests/test_onnx_embedding_function.py
@@ -0,0 +1,72 @@
+"""
+Unit tests for OnnxEmbeddingFunction.
+"""
+
+from __future__ import annotations
+
+import pytest
+
+from pyseekdb.utils.embedding_functions.onnx_embedding_function import OnnxEmbeddingFunction
+
+
+def _make_onnx() -> OnnxEmbeddingFunction:
+ return OnnxEmbeddingFunction(
+ model_name="all-MiniLM-L6-v2",
+ hf_model_id="sentence-transformers/all-MiniLM-L6-v2",
+ dimension=384,
+ preferred_providers=None,
+ )
+
+
+def test_init_validates_model_name() -> None:
+ with pytest.raises(ValueError, match="model_name must be a non-empty string"):
+ OnnxEmbeddingFunction(model_name="", hf_model_id="org/test", dimension=3)
+
+
+def test_init_validates_hf_model_id() -> None:
+ with pytest.raises(ValueError, match="hf_model_id must be a non-empty string"):
+ OnnxEmbeddingFunction(model_name="test", hf_model_id="", dimension=3)
+
+
+def test_init_validates_dimension() -> None:
+ with pytest.raises(ValueError, match="dimension must be a positive integer"):
+ OnnxEmbeddingFunction(model_name="test", hf_model_id="org/test", dimension=0)
+
+
+def test_init_validates_preferred_providers() -> None:
+ with pytest.raises(ValueError, match="Preferred providers must be a list of strings"):
+ OnnxEmbeddingFunction(model_name="test", hf_model_id="org/test", dimension=3, preferred_providers=[1]) # type: ignore[list-item]
+ with pytest.raises(ValueError, match="Preferred providers must be unique"):
+ OnnxEmbeddingFunction(
+ model_name="test",
+ hf_model_id="org/test",
+ dimension=3,
+ preferred_providers=["CPUExecutionProvider", "CPUExecutionProvider"],
+ )
+
+
+def test_dimension_property() -> None:
+ ef = _make_onnx()
+ assert ef.dimension == 384
+
+
+def test_call_empty_returns_empty() -> None:
+ ef = _make_onnx()
+ assert ef([]) == []
+
+
+def test_call_generates_embeddings() -> None:
+ pytest.importorskip("onnxruntime")
+ pytest.importorskip("tokenizers")
+ pytest.importorskip("tqdm")
+
+ ef = _make_onnx()
+ embeddings = ef("hello world")
+
+ assert isinstance(embeddings, list)
+ assert len(embeddings) == 1
+ assert len(embeddings[0]) == ef.dimension
+
+
+if __name__ == "__main__":
+ pytest.main([__file__, "-v", "-s"])
From fab366b4201fc56c3779c93bbe294840cb23296d Mon Sep 17 00:00:00 2001
From: wangyunlai
Date: Mon, 2 Feb 2026 19:57:31 +0800
Subject: [PATCH 10/10] support python3.14 by using sentence-transformers
(#163)
## Summary
close #70
Pyseekdb depends on onnxruntime to execute default embedding function.
But onnxruntime doesn't support python3.14 yet and we waited it too
long.
## Solution Description
We use Sentence Transformers to execute default embedding model on
python3.14.
## Summary by CodeRabbit
* **New Features**
* Broadened Python support to include newer 3.14+ runtimes with an
optimized embedding backend on those versions
* **Chores**
* CI updated to run tests across multiple Python versions and test modes
with more robust pass/fail checks
* Dependency declarations adjusted for broader Python compatibility and
conditional packages
* Reduced routine log verbosity for successful client operations;
improved connection-close log details
* Deferred network library imports to improve import-time behavior
* **Tests**
* Added and refactored tests to validate embedding behavior across
Python versions and simplified integration flows
---
.github/workflows/ci.yml | 15 +-
pyproject.toml | 11 +-
src/pyseekdb/__init__.py | 5 +-
src/pyseekdb/client/client_base.py | 18 +-
src/pyseekdb/client/client_seekdb_embedded.py | 2 +-
src/pyseekdb/client/embedding_function.py | 23 +-
.../onnx_embedding_function.py | 4 +-
...llection_hybrid_search_source_inference.py | 66 +---
.../test_default_embedding_function.py | 17 +
.../test_onnx_embedding_function.py | 112 +++---
uv.lock | 337 +++++++++++++++++-
11 files changed, 446 insertions(+), 164 deletions(-)
diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index 256bd8b0..4868c2e9 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -63,6 +63,10 @@ jobs:
unit-test:
runs-on: ubuntu-latest
+ strategy:
+ fail-fast: false
+ matrix:
+ python-version: ['3.11', '3.14']
steps:
- name: Check out code
uses: actions/checkout@v4
@@ -70,7 +74,7 @@ jobs:
- name: Set up environment
uses: ./.github/actions/setup-python-env
with:
- python-version: '3.11'
+ python-version: ${{ matrix.python-version }}
- name: Install depencies for unit tests
run: |
@@ -83,8 +87,9 @@ jobs:
else
log_level=INFO
fi
+ set -o pipefail
uv run pytest tests/unit_tests/ -v --log-cli-level=${log_level} | tee pytest.log
- tail -n 1 pytest.log | grep -q 'failed' && exit 1 || exit 0
+ tail -n 1 pytest.log | grep '=======' | grep 'passed' |grep -q 'failed' && exit 1 || exit 0
- name: Run integration tests without any test mode
run: |
@@ -93,8 +98,9 @@ jobs:
else
log_level=INFO
fi
+ set -o pipefail
uv run pytest tests/integration_tests/ -v --log-cli-level=${log_level} -k "not server and not embedded and not oceanbase" | tee pytest.log
- tail -n 1 pytest.log | grep -q 'failed' && exit 1 || exit 0
+ tail -n 1 pytest.log | grep '=======' | grep 'passed' | grep -q 'failed' && exit 1 || exit 0
integration-test:
runs-on: ubuntu-latest
@@ -155,5 +161,6 @@ jobs:
else
log_level=INFO
fi
+ set -o pipefail
uv run pytest tests/integration_tests/ -v --log-cli-level=${log_level} -k "${{ matrix.test_mode }}" | tee pytest.log
- tail -n 1 pytest.log | grep -q 'failed' && exit 1 || exit 0
+ tail -n 1 pytest.log | grep '=======' | grep 'passed' | grep -q 'failed' && exit 1 || exit 0
diff --git a/pyproject.toml b/pyproject.toml
index 11067c2b..f519f93d 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -5,17 +5,18 @@ description = "A unified Python client for seekdb that supports embedded, server
readme = "README.md"
license = { text = "Apache-2.0" }
authors = [{ name = "OceanBase", email = "open_oceanbase@oceanbase.com" }]
-requires-python = ">=3.11,<3.14"
+requires-python = ">=3.11,<4"
classifiers = [
"Development Status :: 4 - Beta",
]
dependencies = [
"pymysql>=1.1.1",
"pylibseekdb; sys_platform == \"linux\"",
- "onnxruntime>=1.19.0",
- "tokenizers>=0.15.0",
- "httpx",
- "tqdm",
+ "onnxruntime>=1.19.0; python_version < \"3.14\"",
+ "tokenizers>=0.15.0; python_version < \"3.14\"",
+ "httpx; python_version < \"3.14\"",
+ "tqdm; python_version < \"3.14\"",
+ "sentence-transformers; python_version >= \"3.14\"",
"tenacity",
"numpy>=1.26",
]
diff --git a/src/pyseekdb/__init__.py b/src/pyseekdb/__init__.py
index fabcaf6b..86c10492 100644
--- a/src/pyseekdb/__init__.py
+++ b/src/pyseekdb/__init__.py
@@ -60,10 +60,11 @@
import importlib.metadata
-# Note: pylibseekdb built with ABI=0 and onnxruntime built with ABI=1, so there's a conflict between the two libraries.
+# Note: pylibseekdb built with ABI=0 and torch built with ABI=1, so there's a conflict between the two libraries.
# pylibseekdb is built both with ABI=0 and the -Bsymbolic flag, so we can load libraries with ABI=1 first
# and then pylibseekdb to avoid these conflicts.
-import onnxruntime # noqa: F401
+if importlib.util.find_spec("torch"):
+ import torch # noqa: F401
from .client import (
AdminAPI,
diff --git a/src/pyseekdb/client/client_base.py b/src/pyseekdb/client/client_base.py
index ced46c02..18cd4166 100644
--- a/src/pyseekdb/client/client_base.py
+++ b/src/pyseekdb/client/client_base.py
@@ -1376,10 +1376,10 @@ def _collection_add( # noqa: C901
elif documents:
# embeddings not provided but documents are provided, check for embedding_function
if embedding_function is not None:
- logger.info(f"Generating embeddings for {len(documents)} documents using embedding function")
+ logger.debug(f"Generating embeddings for {len(documents)} documents using embedding function")
try:
embeddings = embedding_function(documents)
- logger.info(f"✅ Successfully generated {len(embeddings)} embeddings")
+ logger.debug(f"✅ Successfully generated {len(embeddings)} embeddings")
except Exception as e:
logger.exception("Failed to generate embeddings")
raise ValueError(f"Failed to generate embeddings from documents: {e}") from e
@@ -1472,7 +1472,7 @@ def _collection_add( # noqa: C901
logger.debug(f"Executing SQL: {sql}")
self._execute(sql)
- logger.info(f"✅ Successfully added {num_items} item(s) to collection '{collection_name}'")
+ logger.debug(f"✅ Successfully added {num_items} item(s) to collection '{collection_name}'")
def _collection_update( # noqa: C901
self,
@@ -1533,10 +1533,10 @@ def _collection_update( # noqa: C901
elif documents:
# embeddings not provided but documents are provided, check for embedding_function
if embedding_function is not None:
- logger.info(f"Generating embeddings for {len(documents)} documents using embedding function")
+ logger.debug(f"Generating embeddings for {len(documents)} documents using embedding function")
try:
embeddings = embedding_function(documents)
- logger.info(f"✅ Successfully generated {len(embeddings)} embeddings")
+ logger.debug(f"✅ Successfully generated {len(embeddings)} embeddings")
except Exception as e:
logger.exception("Failed to generate embeddings")
raise ValueError(f"Failed to generate embeddings from documents: {e}") from e
@@ -1675,7 +1675,7 @@ def _collection_upsert( # noqa: C901
elif documents:
# embeddings not provided but documents are provided, check for embedding_function
if embedding_function is not None:
- logger.info(f"Generating embeddings for {len(documents)} documents using embedding function")
+ logger.debug(f"Generating embeddings for {len(documents)} documents using embedding function")
try:
embeddings = embedding_function(documents)
logger.info(f"✅ Successfully generated {len(embeddings)} embeddings")
@@ -1818,7 +1818,7 @@ def _collection_delete(
where_document: Filter condition on documents (optional)
**kwargs: Additional parameters
"""
- logger.info(f"Deleting data from collection '{collection_name}'")
+ logger.debug(f"Deleting data from collection '{collection_name}'")
# Validate that at least one filter is provided
if not ids and not where and not where_document:
@@ -1849,7 +1849,7 @@ def _collection_delete(
use_context_manager = self._use_context_manager_for_cursor()
self._execute_query_with_cursor(conn, sql, params, use_context_manager)
- logger.info(f"✅ Successfully deleted data from collection '{collection_name}'")
+ logger.debug(f"✅ Successfully deleted data from collection '{collection_name}'")
# -------------------- DQL Operations --------------------
# Note: _collection_query() and _collection_get() are implemented below with common SQL-based logic
@@ -3267,7 +3267,7 @@ def _collection_count(self, collection_id: str | None, collection_name: str) ->
Returns:
Item count
"""
- logger.info(f"Counting items in collection '{collection_name}'")
+ logger.debug(f"Counting items in collection '{collection_name}'")
conn = self._ensure_connection()
# Convert collection name to table name
diff --git a/src/pyseekdb/client/client_seekdb_embedded.py b/src/pyseekdb/client/client_seekdb_embedded.py
index 156656a6..48532580 100644
--- a/src/pyseekdb/client/client_seekdb_embedded.py
+++ b/src/pyseekdb/client/client_seekdb_embedded.py
@@ -93,7 +93,7 @@ def _cleanup(self):
if self._connection is not None:
self._connection.close()
self._connection = None
- logger.info("Connection closed")
+ logger.info(f"Connection closed: path={self.path}, database={self.database}")
def is_connected(self) -> bool:
"""Check connection status"""
diff --git a/src/pyseekdb/client/embedding_function.py b/src/pyseekdb/client/embedding_function.py
index 460e335b..0c7f249c 100644
--- a/src/pyseekdb/client/embedding_function.py
+++ b/src/pyseekdb/client/embedding_function.py
@@ -6,6 +6,7 @@
"""
import logging
+import sys
import warnings
from abc import abstractmethod
from typing import (
@@ -167,13 +168,21 @@ def __init__(
stacklevel=2,
)
self.model_name = self._MODEL_NAME
- from pyseekdb.utils.embedding_functions import OnnxEmbeddingFunction
+ if sys.version_info >= (3, 14):
+ from pyseekdb.utils.embedding_functions.sentence_transformer_embedding_function import (
+ SentenceTransformerEmbeddingFunction,
+ )
- self._onnx = OnnxEmbeddingFunction(
- model_name=self._MODEL_NAME,
- hf_model_id=self._HF_MODEL_ID,
- dimension=self._DIMENSION,
- )
+ self._backend = SentenceTransformerEmbeddingFunction(model_name=self._MODEL_NAME)
+ else:
+ from pyseekdb.utils.embedding_functions import OnnxEmbeddingFunction
+
+ self._backend = OnnxEmbeddingFunction(
+ model_name=self._MODEL_NAME,
+ hf_model_id=self._HF_MODEL_ID,
+ dimension=self._DIMENSION,
+ preferred_providers=preferred_providers,
+ )
@property
def dimension(self) -> int:
@@ -181,7 +190,7 @@ def dimension(self) -> int:
return self._DIMENSION
def __call__(self, documents: Documents) -> Embeddings:
- return self._onnx(documents)
+ return self._backend(documents)
@staticmethod
def name() -> str:
diff --git a/src/pyseekdb/utils/embedding_functions/onnx_embedding_function.py b/src/pyseekdb/utils/embedding_functions/onnx_embedding_function.py
index 8328cf0a..6fad2f99 100644
--- a/src/pyseekdb/utils/embedding_functions/onnx_embedding_function.py
+++ b/src/pyseekdb/utils/embedding_functions/onnx_embedding_function.py
@@ -12,7 +12,6 @@
from pathlib import Path
from typing import Any
-import httpx
import numpy as np
import numpy.typing as npt
@@ -100,6 +99,8 @@ def _download(self, url: str, fname: str, chunk_size: int = 8192) -> None:
"""
logger.info(f"Downloading from {url}")
# Use Client to ensure correct handling of redirects
+ import httpx
+
with httpx.Client(timeout=600.0, follow_redirects=True) as client, client.stream("GET", url) as resp:
resp.raise_for_status()
total = int(resp.headers.get("content-length", 0))
@@ -148,6 +149,7 @@ def _download_from_huggingface(self) -> bool: # noqa: C901
os.makedirs(extracted_folder, exist_ok=True)
logger.info(f"Downloading model from Hugging Face (endpoint: {hf_endpoint})")
+ import httpx
# Download each file
for hf_filename, local_filename in files_to_download.items():
diff --git a/tests/integration_tests/test_collection_hybrid_search_source_inference.py b/tests/integration_tests/test_collection_hybrid_search_source_inference.py
index bbf2cbfe..8ee21afb 100644
--- a/tests/integration_tests/test_collection_hybrid_search_source_inference.py
+++ b/tests/integration_tests/test_collection_hybrid_search_source_inference.py
@@ -7,19 +7,14 @@
import contextlib
import json
-import time
import uuid
from pymysql.converters import escape_string
from pyseekdb import HNSWConfiguration
-from pyseekdb.client.meta_info import CollectionNames
class TestCollectionHybridSearchSourceInferenceRealDB:
- _QUERY_TIMEOUT_SECONDS = 10.0
- _QUERY_RETRY_INTERVAL_SECONDS = 0.2
-
def _unique_collection_name(self, prefix: str) -> str:
# Keep names short to avoid MySQL/OceanBase identifier length limits after
# internal table-name prefixing (e.g. "c$v1$...").
@@ -83,7 +78,7 @@ def _get_sql_query(self, client, table_name: str, search_parm: dict) -> str:
return query_sql.strip().strip("'\"")
return str(query_sql)
- def test_include_infers_source_result_shape_matrix(self, server_client):
+ def test_include_infers_source_result_shape_matrix(self, db_client):
"""
Verify `_source` inference end-to-end:
1) GET_SQL result columns match requested include (avoid returning large unused columns like embedding)
@@ -92,85 +87,33 @@ def test_include_infers_source_result_shape_matrix(self, server_client):
collection_name = self._unique_collection_name("hs_include_matrix")
collection = None
try:
- collection, dimension = self._create_test_collection(server_client, collection_name)
+ collection, dimension = self._create_test_collection(db_client, collection_name)
self._insert_test_data(collection, dimension=dimension)
query_vector = self._generate_query_vector(dimension)
knn = {"query_embeddings": query_vector, "n_results": 2}
- table_name = (
- CollectionNames.table_name_v2(collection.id)
- if getattr(collection, "id", None)
- else CollectionNames.table_name(collection.name)
- )
-
- def execute_get_sql(include: list[str] | None) -> tuple[dict, list[dict]]:
- search_parm = server_client._server._build_search_parm(
- query=None,
- knn=knn,
- rank=None,
- n_results=2,
- include=include,
- dimension=dimension,
- )
- query_sql = self._get_sql_query(server_client, table_name, search_parm)
- deadline = time.time() + self._QUERY_TIMEOUT_SECONDS
- last_exc: Exception | None = None
- while time.time() < deadline:
- try:
- rows = server_client._server._execute(query_sql)
- if rows:
- return search_parm, rows
- except Exception as exc:
- last_exc = exc
- time.sleep(self._QUERY_RETRY_INTERVAL_SECONDS)
- if last_exc is not None:
- raise AssertionError("Timed out waiting for GET_SQL query to return rows") from last_exc
- raise AssertionError("Timed out waiting for GET_SQL query to return rows")
-
- def assert_columns(rows: list[dict], *, present: set[str], absent: set[str]) -> None:
- assert rows
- keys = {str(k).lower() for k in rows[0]}
- for col in present:
- assert col in keys
- for col in absent:
- assert col not in keys
# 1) include=None: default returns documents+metadatas; should not return embedding column
- _, rows = execute_get_sql(include=None)
- assert_columns(rows, present={"document", "metadata"}, absent={"embedding"})
-
default_include = collection.hybrid_search(knn=knn, n_results=2)
assert set(default_include.keys()) == {"ids", "distances", "documents", "metadatas"}
assert all(isinstance(d, str) for d in default_include["documents"][0])
assert all(isinstance(m, dict) and m for m in default_include["metadatas"][0])
# 2) include=[]: ids/distances only; should not return document/metadata/embedding columns
- _, rows = execute_get_sql(include=[])
- assert_columns(rows, present=set(), absent={"document", "metadata", "embedding"})
-
ids_only = collection.hybrid_search(knn=knn, n_results=2, include=[])
assert set(ids_only.keys()) == {"ids", "distances"}
# 3) include=["documents"]: only document column
- _, rows = execute_get_sql(include=["documents"])
- assert_columns(rows, present={"document"}, absent={"metadata", "embedding"})
-
docs_only = collection.hybrid_search(knn=knn, n_results=2, include=["documents"])
assert set(docs_only.keys()) == {"ids", "distances", "documents"}
assert all(isinstance(d, str) for d in docs_only["documents"][0])
# 4) include=["metadatas"]: only metadata column
- _, rows = execute_get_sql(include=["metadatas"])
- assert_columns(rows, present={"metadata"}, absent={"document", "embedding"})
-
metadatas_only = collection.hybrid_search(knn=knn, n_results=2, include=["metadatas"])
assert set(metadatas_only.keys()) == {"ids", "distances", "metadatas"}
assert all(isinstance(m, dict) and m for m in metadatas_only["metadatas"][0])
# 5) include=["embeddings"]: only embedding column
- _, rows = execute_get_sql(include=["embeddings"])
- assert_columns(rows, present={"embedding"}, absent={"document", "metadata"})
-
embeddings_only = collection.hybrid_search(knn=knn, n_results=2, include=["embeddings"])
assert set(embeddings_only.keys()) == {"ids", "distances", "embeddings"}
first_embedding = embeddings_only["embeddings"][0][0]
@@ -178,16 +121,13 @@ def assert_columns(rows: list[dict], *, present: set[str], absent: set[str]) ->
assert len(first_embedding) == dimension
# 6) include=["documents","embeddings"]: document+embedding columns
- _, rows = execute_get_sql(include=["documents", "embeddings"])
- assert_columns(rows, present={"document", "embedding"}, absent={"metadata"})
-
docs_and_embeddings = collection.hybrid_search(knn=knn, n_results=2, include=["documents", "embeddings"])
assert set(docs_and_embeddings.keys()) == {"ids", "distances", "documents", "embeddings"}
assert all(isinstance(d, str) for d in docs_and_embeddings["documents"][0])
assert all(isinstance(e, list) and len(e) == dimension for e in docs_and_embeddings["embeddings"][0])
finally:
with contextlib.suppress(Exception):
- server_client.delete_collection(name=collection_name)
+ db_client.delete_collection(name=collection_name)
# NOTE: `HybridSearch` fluent builder was removed on `develop` (rollback enhanced hybrid search).
# Keep this file focused on verifying OceanBase GET_SQL `_source` inference and result shapes.
diff --git a/tests/unit_tests/test_default_embedding_function.py b/tests/unit_tests/test_default_embedding_function.py
index 37c3f410..0d0969e4 100644
--- a/tests/unit_tests/test_default_embedding_function.py
+++ b/tests/unit_tests/test_default_embedding_function.py
@@ -2,6 +2,7 @@
Unit tests for DefaultEmbeddingFunction.
"""
+import sys
from typing import Any
import pytest
@@ -59,5 +60,21 @@ def test_persistence_roundtrip(self):
assert restored_ef.model_name == original_ef.model_name
+def test_default_embedding_function_on_py314():
+ if sys.version_info < (3, 14):
+ pytest.skip("Python < 3.14")
+ embedding_function = DefaultEmbeddingFunction()
+ assert embedding_function.dimension == 384
+ assert len(embedding_function("hello")[0]) == 384
+
+
+def test_default_embedding_function_uses_onnx_on_pre314():
+ if sys.version_info >= (3, 14):
+ pytest.skip("Python >= 3.14")
+ embedding_function = DefaultEmbeddingFunction()
+ assert embedding_function.dimension == 384
+ assert len(embedding_function("hello")[0]) == 384
+
+
if __name__ == "__main__":
pytest.main([__file__, "-v", "-s"])
diff --git a/tests/unit_tests/test_onnx_embedding_function.py b/tests/unit_tests/test_onnx_embedding_function.py
index 4f34b339..f1825e6e 100644
--- a/tests/unit_tests/test_onnx_embedding_function.py
+++ b/tests/unit_tests/test_onnx_embedding_function.py
@@ -4,68 +4,74 @@
from __future__ import annotations
+import importlib
+
import pytest
from pyseekdb.utils.embedding_functions.onnx_embedding_function import OnnxEmbeddingFunction
-def _make_onnx() -> OnnxEmbeddingFunction:
- return OnnxEmbeddingFunction(
- model_name="all-MiniLM-L6-v2",
- hf_model_id="sentence-transformers/all-MiniLM-L6-v2",
- dimension=384,
- preferred_providers=None,
- )
-
-
-def test_init_validates_model_name() -> None:
- with pytest.raises(ValueError, match="model_name must be a non-empty string"):
- OnnxEmbeddingFunction(model_name="", hf_model_id="org/test", dimension=3)
-
-
-def test_init_validates_hf_model_id() -> None:
- with pytest.raises(ValueError, match="hf_model_id must be a non-empty string"):
- OnnxEmbeddingFunction(model_name="test", hf_model_id="", dimension=3)
-
-
-def test_init_validates_dimension() -> None:
- with pytest.raises(ValueError, match="dimension must be a positive integer"):
- OnnxEmbeddingFunction(model_name="test", hf_model_id="org/test", dimension=0)
+def is_onnx_available() -> bool:
+ """Check if onnxruntime is available for testing."""
+ return importlib.util.find_spec("onnxruntime") is not None
-def test_init_validates_preferred_providers() -> None:
- with pytest.raises(ValueError, match="Preferred providers must be a list of strings"):
- OnnxEmbeddingFunction(model_name="test", hf_model_id="org/test", dimension=3, preferred_providers=[1]) # type: ignore[list-item]
- with pytest.raises(ValueError, match="Preferred providers must be unique"):
- OnnxEmbeddingFunction(
- model_name="test",
- hf_model_id="org/test",
- dimension=3,
- preferred_providers=["CPUExecutionProvider", "CPUExecutionProvider"],
+# Skip this test by default - it requires external API access and API keys
+@pytest.mark.skipif(
+ not is_onnx_available(),
+ reason="onnxruntime is not available",
+)
+class TestOnnxEmbeddingFunction:
+ def _make_onnx(self) -> OnnxEmbeddingFunction:
+ return OnnxEmbeddingFunction(
+ model_name="all-MiniLM-L6-v2",
+ hf_model_id="sentence-transformers/all-MiniLM-L6-v2",
+ dimension=384,
+ preferred_providers=None,
)
-
-def test_dimension_property() -> None:
- ef = _make_onnx()
- assert ef.dimension == 384
-
-
-def test_call_empty_returns_empty() -> None:
- ef = _make_onnx()
- assert ef([]) == []
-
-
-def test_call_generates_embeddings() -> None:
- pytest.importorskip("onnxruntime")
- pytest.importorskip("tokenizers")
- pytest.importorskip("tqdm")
-
- ef = _make_onnx()
- embeddings = ef("hello world")
-
- assert isinstance(embeddings, list)
- assert len(embeddings) == 1
- assert len(embeddings[0]) == ef.dimension
+ def test_init_validates_model_name(self) -> None:
+ with pytest.raises(ValueError, match="model_name must be a non-empty string"):
+ OnnxEmbeddingFunction(model_name="", hf_model_id="org/test", dimension=3)
+
+ def test_init_validates_hf_model_id(self) -> None:
+ with pytest.raises(ValueError, match="hf_model_id must be a non-empty string"):
+ OnnxEmbeddingFunction(model_name="test", hf_model_id="", dimension=3)
+
+ def test_init_validates_dimension(self) -> None:
+ with pytest.raises(ValueError, match="dimension must be a positive integer"):
+ OnnxEmbeddingFunction(model_name="test", hf_model_id="org/test", dimension=0)
+
+ def test_init_validates_preferred_providers(self) -> None:
+ with pytest.raises(ValueError, match="Preferred providers must be a list of strings"):
+ OnnxEmbeddingFunction(model_name="test", hf_model_id="org/test", dimension=3, preferred_providers=[1]) # type: ignore[list-item]
+ with pytest.raises(ValueError, match="Preferred providers must be unique"):
+ OnnxEmbeddingFunction(
+ model_name="test",
+ hf_model_id="org/test",
+ dimension=3,
+ preferred_providers=["CPUExecutionProvider", "CPUExecutionProvider"],
+ )
+
+ def test_dimension_property(self) -> None:
+ ef = self._make_onnx()
+ assert ef.dimension == 384
+
+ def test_call_empty_returns_empty(self) -> None:
+ ef = self._make_onnx()
+ assert ef([]) == []
+
+ def test_call_generates_embeddings(self) -> None:
+ pytest.importorskip("onnxruntime")
+ pytest.importorskip("tokenizers")
+ pytest.importorskip("tqdm")
+
+ ef = self._make_onnx()
+ embeddings = ef("hello world")
+
+ assert isinstance(embeddings, list)
+ assert len(embeddings) == 1
+ assert len(embeddings[0]) == ef.dimension
if __name__ == "__main__":
diff --git a/uv.lock b/uv.lock
index 1ca532d0..101dd5b0 100644
--- a/uv.lock
+++ b/uv.lock
@@ -1,8 +1,9 @@
version = 1
revision = 3
-requires-python = ">=3.11, <3.14"
+requires-python = ">=3.11, <4"
resolution-markers = [
- "python_full_version >= '3.12'",
+ "python_full_version >= '3.14'",
+ "python_full_version >= '3.12' and python_full_version < '3.14'",
"python_full_version < '3.12'",
]
@@ -30,7 +31,7 @@ dependencies = [
{ name = "jsonschema" },
{ name = "narwhals" },
{ name = "packaging" },
- { name = "typing-extensions" },
+ { name = "typing-extensions", marker = "python_full_version < '3.15'" },
]
sdist = { url = "https://files.pythonhosted.org/packages/f7/c0/184a89bd5feba14ff3c41cfaf1dd8a82c05f5ceedbc92145e17042eb08a4/altair-6.0.0.tar.gz", hash = "sha256:614bf5ecbe2337347b590afb111929aa9c16c9527c4887d96c9bc7f6640756b4", size = 763834, upload-time = "2025-11-12T08:59:11.519Z" }
wheels = [
@@ -167,6 +168,22 @@ wheels = [
{ url = "https://files.pythonhosted.org/packages/89/66/c7a9e1b7429be72123441bfdbaf2bc13faab3f90b933f664db506dea5915/charset_normalizer-3.4.4-cp313-cp313-win32.whl", hash = "sha256:9b35f4c90079ff2e2edc5b26c0c77925e5d2d255c42c74fdb70fb49b172726ac", size = 99404, upload-time = "2025-10-14T04:41:29.95Z" },
{ url = "https://files.pythonhosted.org/packages/c4/26/b9924fa27db384bdcd97ab83b4f0a8058d96ad9626ead570674d5e737d90/charset_normalizer-3.4.4-cp313-cp313-win_amd64.whl", hash = "sha256:b435cba5f4f750aa6c0a0d92c541fb79f69a387c91e61f1795227e4ed9cece14", size = 107092, upload-time = "2025-10-14T04:41:31.188Z" },
{ url = "https://files.pythonhosted.org/packages/af/8f/3ed4bfa0c0c72a7ca17f0380cd9e4dd842b09f664e780c13cff1dcf2ef1b/charset_normalizer-3.4.4-cp313-cp313-win_arm64.whl", hash = "sha256:542d2cee80be6f80247095cc36c418f7bddd14f4a6de45af91dfad36d817bba2", size = 100408, upload-time = "2025-10-14T04:41:32.624Z" },
+ { url = "https://files.pythonhosted.org/packages/2a/35/7051599bd493e62411d6ede36fd5af83a38f37c4767b92884df7301db25d/charset_normalizer-3.4.4-cp314-cp314-macosx_10_13_universal2.whl", hash = "sha256:da3326d9e65ef63a817ecbcc0df6e94463713b754fe293eaa03da99befb9a5bd", size = 207746, upload-time = "2025-10-14T04:41:33.773Z" },
+ { url = "https://files.pythonhosted.org/packages/10/9a/97c8d48ef10d6cd4fcead2415523221624bf58bcf68a802721a6bc807c8f/charset_normalizer-3.4.4-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:8af65f14dc14a79b924524b1e7fffe304517b2bff5a58bf64f30b98bbc5079eb", size = 147889, upload-time = "2025-10-14T04:41:34.897Z" },
+ { url = "https://files.pythonhosted.org/packages/10/bf/979224a919a1b606c82bd2c5fa49b5c6d5727aa47b4312bb27b1734f53cd/charset_normalizer-3.4.4-cp314-cp314-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:74664978bb272435107de04e36db5a9735e78232b85b77d45cfb38f758efd33e", size = 143641, upload-time = "2025-10-14T04:41:36.116Z" },
+ { url = "https://files.pythonhosted.org/packages/ba/33/0ad65587441fc730dc7bd90e9716b30b4702dc7b617e6ba4997dc8651495/charset_normalizer-3.4.4-cp314-cp314-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:752944c7ffbfdd10c074dc58ec2d5a8a4cd9493b314d367c14d24c17684ddd14", size = 160779, upload-time = "2025-10-14T04:41:37.229Z" },
+ { url = "https://files.pythonhosted.org/packages/67/ed/331d6b249259ee71ddea93f6f2f0a56cfebd46938bde6fcc6f7b9a3d0e09/charset_normalizer-3.4.4-cp314-cp314-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:d1f13550535ad8cff21b8d757a3257963e951d96e20ec82ab44bc64aeb62a191", size = 159035, upload-time = "2025-10-14T04:41:38.368Z" },
+ { url = "https://files.pythonhosted.org/packages/67/ff/f6b948ca32e4f2a4576aa129d8bed61f2e0543bf9f5f2b7fc3758ed005c9/charset_normalizer-3.4.4-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:ecaae4149d99b1c9e7b88bb03e3221956f68fd6d50be2ef061b2381b61d20838", size = 152542, upload-time = "2025-10-14T04:41:39.862Z" },
+ { url = "https://files.pythonhosted.org/packages/16/85/276033dcbcc369eb176594de22728541a925b2632f9716428c851b149e83/charset_normalizer-3.4.4-cp314-cp314-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:cb6254dc36b47a990e59e1068afacdcd02958bdcce30bb50cc1700a8b9d624a6", size = 149524, upload-time = "2025-10-14T04:41:41.319Z" },
+ { url = "https://files.pythonhosted.org/packages/9e/f2/6a2a1f722b6aba37050e626530a46a68f74e63683947a8acff92569f979a/charset_normalizer-3.4.4-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:c8ae8a0f02f57a6e61203a31428fa1d677cbe50c93622b4149d5c0f319c1d19e", size = 150395, upload-time = "2025-10-14T04:41:42.539Z" },
+ { url = "https://files.pythonhosted.org/packages/60/bb/2186cb2f2bbaea6338cad15ce23a67f9b0672929744381e28b0592676824/charset_normalizer-3.4.4-cp314-cp314-musllinux_1_2_armv7l.whl", hash = "sha256:47cc91b2f4dd2833fddaedd2893006b0106129d4b94fdb6af1f4ce5a9965577c", size = 143680, upload-time = "2025-10-14T04:41:43.661Z" },
+ { url = "https://files.pythonhosted.org/packages/7d/a5/bf6f13b772fbb2a90360eb620d52ed8f796f3c5caee8398c3b2eb7b1c60d/charset_normalizer-3.4.4-cp314-cp314-musllinux_1_2_ppc64le.whl", hash = "sha256:82004af6c302b5d3ab2cfc4cc5f29db16123b1a8417f2e25f9066f91d4411090", size = 162045, upload-time = "2025-10-14T04:41:44.821Z" },
+ { url = "https://files.pythonhosted.org/packages/df/c5/d1be898bf0dc3ef9030c3825e5d3b83f2c528d207d246cbabe245966808d/charset_normalizer-3.4.4-cp314-cp314-musllinux_1_2_riscv64.whl", hash = "sha256:2b7d8f6c26245217bd2ad053761201e9f9680f8ce52f0fcd8d0755aeae5b2152", size = 149687, upload-time = "2025-10-14T04:41:46.442Z" },
+ { url = "https://files.pythonhosted.org/packages/a5/42/90c1f7b9341eef50c8a1cb3f098ac43b0508413f33affd762855f67a410e/charset_normalizer-3.4.4-cp314-cp314-musllinux_1_2_s390x.whl", hash = "sha256:799a7a5e4fb2d5898c60b640fd4981d6a25f1c11790935a44ce38c54e985f828", size = 160014, upload-time = "2025-10-14T04:41:47.631Z" },
+ { url = "https://files.pythonhosted.org/packages/76/be/4d3ee471e8145d12795ab655ece37baed0929462a86e72372fd25859047c/charset_normalizer-3.4.4-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:99ae2cffebb06e6c22bdc25801d7b30f503cc87dbd283479e7b606f70aff57ec", size = 154044, upload-time = "2025-10-14T04:41:48.81Z" },
+ { url = "https://files.pythonhosted.org/packages/b0/6f/8f7af07237c34a1defe7defc565a9bc1807762f672c0fde711a4b22bf9c0/charset_normalizer-3.4.4-cp314-cp314-win32.whl", hash = "sha256:f9d332f8c2a2fcbffe1378594431458ddbef721c1769d78e2cbc06280d8155f9", size = 99940, upload-time = "2025-10-14T04:41:49.946Z" },
+ { url = "https://files.pythonhosted.org/packages/4b/51/8ade005e5ca5b0d80fb4aff72a3775b325bdc3d27408c8113811a7cbe640/charset_normalizer-3.4.4-cp314-cp314-win_amd64.whl", hash = "sha256:8a6562c3700cce886c5be75ade4a5db4214fda19fede41d9792d100288d8f94c", size = 107104, upload-time = "2025-10-14T04:41:51.051Z" },
+ { url = "https://files.pythonhosted.org/packages/da/5f/6b8f83a55bb8278772c5ae54a577f3099025f9ade59d0136ac24a0df4bde/charset_normalizer-3.4.4-cp314-cp314-win_arm64.whl", hash = "sha256:de00632ca48df9daf77a2c65a484531649261ec9f25489917f09e455cb09ddb2", size = 100743, upload-time = "2025-10-14T04:41:52.122Z" },
{ url = "https://files.pythonhosted.org/packages/0a/4c/925909008ed5a988ccbb72dcc897407e5d6d3bd72410d69e051fc0c14647/charset_normalizer-3.4.4-py3-none-any.whl", hash = "sha256:7a32c560861a02ff789ad905a2fe94e3f840803362c84fecf1851cb4cf3dc37f", size = 53402, upload-time = "2025-10-14T04:42:31.76Z" },
]
@@ -196,7 +213,7 @@ name = "coloredlogs"
version = "15.0.1"
source = { registry = "https://pypi.org/simple" }
dependencies = [
- { name = "humanfriendly" },
+ { name = "humanfriendly", marker = "python_full_version < '3.14'" },
]
sdist = { url = "https://files.pythonhosted.org/packages/cc/c7/eed8f27100517e8c0e6b923d5f0845d0cb99763da6fdee00478f91db7325/coloredlogs-15.0.1.tar.gz", hash = "sha256:7c991aa71a4577af2f82600d8f8f3a89f936baeaf9b50a9c197da014e5bf16b0", size = 278520, upload-time = "2021-06-11T10:22:45.202Z" }
wheels = [
@@ -302,6 +319,13 @@ wheels = [
{ url = "https://files.pythonhosted.org/packages/4a/1d/04513e3cab8f29ab8c109d309ddd21a2705afab9d52f2ba1151e0c14f086/hf_xet-1.2.0-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:6de1fc44f58f6dd937956c8d304d8c2dea264c80680bcfa61ca4a15e7b76780f", size = 3408448, upload-time = "2025-10-24T19:04:20.951Z" },
{ url = "https://files.pythonhosted.org/packages/f0/7c/60a2756d7feec7387db3a1176c632357632fbe7849fce576c5559d4520c7/hf_xet-1.2.0-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:f182f264ed2acd566c514e45da9f2119110e48a87a327ca271027904c70c5832", size = 3503401, upload-time = "2025-10-24T19:04:22.549Z" },
{ url = "https://files.pythonhosted.org/packages/4e/64/48fffbd67fb418ab07451e4ce641a70de1c40c10a13e25325e24858ebe5a/hf_xet-1.2.0-cp313-cp313t-win_amd64.whl", hash = "sha256:293a7a3787e5c95d7be1857358a9130694a9c6021de3f27fa233f37267174382", size = 2900866, upload-time = "2025-10-24T19:04:33.461Z" },
+ { url = "https://files.pythonhosted.org/packages/e2/51/f7e2caae42f80af886db414d4e9885fac959330509089f97cccb339c6b87/hf_xet-1.2.0-cp314-cp314t-macosx_10_12_x86_64.whl", hash = "sha256:10bfab528b968c70e062607f663e21e34e2bba349e8038db546646875495179e", size = 2861861, upload-time = "2025-10-24T19:04:19.01Z" },
+ { url = "https://files.pythonhosted.org/packages/6e/1d/a641a88b69994f9371bd347f1dd35e5d1e2e2460a2e350c8d5165fc62005/hf_xet-1.2.0-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:2a212e842647b02eb6a911187dc878e79c4aa0aa397e88dd3b26761676e8c1f8", size = 2717699, upload-time = "2025-10-24T19:04:17.306Z" },
+ { url = "https://files.pythonhosted.org/packages/df/e0/e5e9bba7d15f0318955f7ec3f4af13f92e773fbb368c0b8008a5acbcb12f/hf_xet-1.2.0-cp314-cp314t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:30e06daccb3a7d4c065f34fc26c14c74f4653069bb2b194e7f18f17cbe9939c0", size = 3314885, upload-time = "2025-10-24T19:04:07.642Z" },
+ { url = "https://files.pythonhosted.org/packages/21/90/b7fe5ff6f2b7b8cbdf1bd56145f863c90a5807d9758a549bf3d916aa4dec/hf_xet-1.2.0-cp314-cp314t-manylinux_2_28_aarch64.whl", hash = "sha256:29c8fc913a529ec0a91867ce3d119ac1aac966e098cf49501800c870328cc090", size = 3221550, upload-time = "2025-10-24T19:04:05.55Z" },
+ { url = "https://files.pythonhosted.org/packages/6f/cb/73f276f0a7ce46cc6a6ec7d6c7d61cbfe5f2e107123d9bbd0193c355f106/hf_xet-1.2.0-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:66e159cbfcfbb29f920db2c09ed8b660eb894640d284f102ada929b6e3dc410a", size = 3408010, upload-time = "2025-10-24T19:04:28.598Z" },
+ { url = "https://files.pythonhosted.org/packages/b8/1e/d642a12caa78171f4be64f7cd9c40e3ca5279d055d0873188a58c0f5fbb9/hf_xet-1.2.0-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:9c91d5ae931510107f148874e9e2de8a16052b6f1b3ca3c1b12f15ccb491390f", size = 3503264, upload-time = "2025-10-24T19:04:30.397Z" },
+ { url = "https://files.pythonhosted.org/packages/17/b5/33764714923fa1ff922770f7ed18c2daae034d21ae6e10dbf4347c854154/hf_xet-1.2.0-cp314-cp314t-win_amd64.whl", hash = "sha256:210d577732b519ac6ede149d2f2f34049d44e8622bf14eb3d63bbcd2d4b332dc", size = 2901071, upload-time = "2025-10-24T19:04:37.463Z" },
{ url = "https://files.pythonhosted.org/packages/96/2d/22338486473df5923a9ab7107d375dbef9173c338ebef5098ef593d2b560/hf_xet-1.2.0-cp37-abi3-macosx_10_12_x86_64.whl", hash = "sha256:46740d4ac024a7ca9b22bebf77460ff43332868b661186a8e46c227fdae01848", size = 2866099, upload-time = "2025-10-24T19:04:15.366Z" },
{ url = "https://files.pythonhosted.org/packages/7f/8c/c5becfa53234299bc2210ba314eaaae36c2875e0045809b82e40a9544f0c/hf_xet-1.2.0-cp37-abi3-macosx_11_0_arm64.whl", hash = "sha256:27df617a076420d8845bea087f59303da8be17ed7ec0cd7ee3b9b9f579dff0e4", size = 2722178, upload-time = "2025-10-24T19:04:13.695Z" },
{ url = "https://files.pythonhosted.org/packages/9a/92/cf3ab0b652b082e66876d08da57fcc6fa2f0e6c70dfbbafbd470bb73eb47/hf_xet-1.2.0-cp37-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3651fd5bfe0281951b988c0facbe726aa5e347b103a675f49a3fa8144c7968fd", size = 3320214, upload-time = "2025-10-24T19:04:03.596Z" },
@@ -363,7 +387,7 @@ name = "humanfriendly"
version = "10.0"
source = { registry = "https://pypi.org/simple" }
dependencies = [
- { name = "pyreadline3", marker = "sys_platform == 'win32'" },
+ { name = "pyreadline3", marker = "python_full_version < '3.14' and sys_platform == 'win32'" },
]
sdist = { url = "https://files.pythonhosted.org/packages/cc/3f/2c29224acb2e2df4d2046e4c73ee2662023c58ff5b113c4c1adac0886c43/humanfriendly-10.0.tar.gz", hash = "sha256:6b0b831ce8f15f7300721aa49829fc4e83921a9a301cc7f606be6686a2288ddc", size = 360702, upload-time = "2021-09-17T21:40:43.31Z" }
wheels = [
@@ -468,6 +492,31 @@ wheels = [
{ url = "https://files.pythonhosted.org/packages/05/17/710bf8472d1dff0d3caf4ced6031060091c1320f84ee7d5dcbed1f352417/jiter-0.12.0-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:351d54f2b09a41600ffea43d081522d792e81dcfb915f6d2d242744c1cc48beb", size = 361272, upload-time = "2025-11-09T20:48:06.951Z" },
{ url = "https://files.pythonhosted.org/packages/fb/f1/1dcc4618b59761fef92d10bcbb0b038b5160be653b003651566a185f1a5c/jiter-0.12.0-cp313-cp313t-win_amd64.whl", hash = "sha256:2a5e90604620f94bf62264e7c2c038704d38217b7465b863896c6d7c902b06c7", size = 204604, upload-time = "2025-11-09T20:48:08.328Z" },
{ url = "https://files.pythonhosted.org/packages/d9/32/63cb1d9f1c5c6632a783c0052cde9ef7ba82688f7065e2f0d5f10a7e3edb/jiter-0.12.0-cp313-cp313t-win_arm64.whl", hash = "sha256:88ef757017e78d2860f96250f9393b7b577b06a956ad102c29c8237554380db3", size = 185628, upload-time = "2025-11-09T20:48:09.572Z" },
+ { url = "https://files.pythonhosted.org/packages/a8/99/45c9f0dbe4a1416b2b9a8a6d1236459540f43d7fb8883cff769a8db0612d/jiter-0.12.0-cp314-cp314-macosx_10_12_x86_64.whl", hash = "sha256:c46d927acd09c67a9fb1416df45c5a04c27e83aae969267e98fba35b74e99525", size = 312478, upload-time = "2025-11-09T20:48:10.898Z" },
+ { url = "https://files.pythonhosted.org/packages/4c/a7/54ae75613ba9e0f55fcb0bc5d1f807823b5167cc944e9333ff322e9f07dd/jiter-0.12.0-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:774ff60b27a84a85b27b88cd5583899c59940bcc126caca97eb2a9df6aa00c49", size = 318706, upload-time = "2025-11-09T20:48:12.266Z" },
+ { url = "https://files.pythonhosted.org/packages/59/31/2aa241ad2c10774baf6c37f8b8e1f39c07db358f1329f4eb40eba179c2a2/jiter-0.12.0-cp314-cp314-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c5433fab222fb072237df3f637d01b81f040a07dcac1cb4a5c75c7aa9ed0bef1", size = 351894, upload-time = "2025-11-09T20:48:13.673Z" },
+ { url = "https://files.pythonhosted.org/packages/54/4f/0f2759522719133a9042781b18cc94e335b6d290f5e2d3e6899d6af933e3/jiter-0.12.0-cp314-cp314-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:f8c593c6e71c07866ec6bfb790e202a833eeec885022296aff6b9e0b92d6a70e", size = 365714, upload-time = "2025-11-09T20:48:15.083Z" },
+ { url = "https://files.pythonhosted.org/packages/dc/6f/806b895f476582c62a2f52c453151edd8a0fde5411b0497baaa41018e878/jiter-0.12.0-cp314-cp314-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:90d32894d4c6877a87ae00c6b915b609406819dce8bc0d4e962e4de2784e567e", size = 478989, upload-time = "2025-11-09T20:48:16.706Z" },
+ { url = "https://files.pythonhosted.org/packages/86/6c/012d894dc6e1033acd8db2b8346add33e413ec1c7c002598915278a37f79/jiter-0.12.0-cp314-cp314-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:798e46eed9eb10c3adbbacbd3bdb5ecd4cf7064e453d00dbef08802dae6937ff", size = 378615, upload-time = "2025-11-09T20:48:18.614Z" },
+ { url = "https://files.pythonhosted.org/packages/87/30/d718d599f6700163e28e2c71c0bbaf6dace692e7df2592fd793ac9276717/jiter-0.12.0-cp314-cp314-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b3f1368f0a6719ea80013a4eb90ba72e75d7ea67cfc7846db2ca504f3df0169a", size = 364745, upload-time = "2025-11-09T20:48:20.117Z" },
+ { url = "https://files.pythonhosted.org/packages/8f/85/315b45ce4b6ddc7d7fceca24068543b02bdc8782942f4ee49d652e2cc89f/jiter-0.12.0-cp314-cp314-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:65f04a9d0b4406f7e51279710b27484af411896246200e461d80d3ba0caa901a", size = 386502, upload-time = "2025-11-09T20:48:21.543Z" },
+ { url = "https://files.pythonhosted.org/packages/74/0b/ce0434fb40c5b24b368fe81b17074d2840748b4952256bab451b72290a49/jiter-0.12.0-cp314-cp314-musllinux_1_1_aarch64.whl", hash = "sha256:fd990541982a24281d12b67a335e44f117e4c6cbad3c3b75c7dea68bf4ce3a67", size = 519845, upload-time = "2025-11-09T20:48:22.964Z" },
+ { url = "https://files.pythonhosted.org/packages/e8/a3/7a7a4488ba052767846b9c916d208b3ed114e3eb670ee984e4c565b9cf0d/jiter-0.12.0-cp314-cp314-musllinux_1_1_x86_64.whl", hash = "sha256:b111b0e9152fa7df870ecaebb0bd30240d9f7fff1f2003bcb4ed0f519941820b", size = 510701, upload-time = "2025-11-09T20:48:24.483Z" },
+ { url = "https://files.pythonhosted.org/packages/c3/16/052ffbf9d0467b70af24e30f91e0579e13ded0c17bb4a8eb2aed3cb60131/jiter-0.12.0-cp314-cp314-win32.whl", hash = "sha256:a78befb9cc0a45b5a5a0d537b06f8544c2ebb60d19d02c41ff15da28a9e22d42", size = 205029, upload-time = "2025-11-09T20:48:25.749Z" },
+ { url = "https://files.pythonhosted.org/packages/e4/18/3cf1f3f0ccc789f76b9a754bdb7a6977e5d1d671ee97a9e14f7eb728d80e/jiter-0.12.0-cp314-cp314-win_amd64.whl", hash = "sha256:e1fe01c082f6aafbe5c8faf0ff074f38dfb911d53f07ec333ca03f8f6226debf", size = 204960, upload-time = "2025-11-09T20:48:27.415Z" },
+ { url = "https://files.pythonhosted.org/packages/02/68/736821e52ecfdeeb0f024b8ab01b5a229f6b9293bbdb444c27efade50b0f/jiter-0.12.0-cp314-cp314-win_arm64.whl", hash = "sha256:d72f3b5a432a4c546ea4bedc84cce0c3404874f1d1676260b9c7f048a9855451", size = 185529, upload-time = "2025-11-09T20:48:29.125Z" },
+ { url = "https://files.pythonhosted.org/packages/30/61/12ed8ee7a643cce29ac97c2281f9ce3956eb76b037e88d290f4ed0d41480/jiter-0.12.0-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:e6ded41aeba3603f9728ed2b6196e4df875348ab97b28fc8afff115ed42ba7a7", size = 318974, upload-time = "2025-11-09T20:48:30.87Z" },
+ { url = "https://files.pythonhosted.org/packages/2d/c6/f3041ede6d0ed5e0e79ff0de4c8f14f401bbf196f2ef3971cdbe5fd08d1d/jiter-0.12.0-cp314-cp314t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a947920902420a6ada6ad51892082521978e9dd44a802663b001436e4b771684", size = 345932, upload-time = "2025-11-09T20:48:32.658Z" },
+ { url = "https://files.pythonhosted.org/packages/d5/5d/4d94835889edd01ad0e2dbfc05f7bdfaed46292e7b504a6ac7839aa00edb/jiter-0.12.0-cp314-cp314t-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:add5e227e0554d3a52cf390a7635edaffdf4f8fce4fdbcef3cc2055bb396a30c", size = 367243, upload-time = "2025-11-09T20:48:34.093Z" },
+ { url = "https://files.pythonhosted.org/packages/fd/76/0051b0ac2816253a99d27baf3dda198663aff882fa6ea7deeb94046da24e/jiter-0.12.0-cp314-cp314t-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:3f9b1cda8fcb736250d7e8711d4580ebf004a46771432be0ae4796944b5dfa5d", size = 479315, upload-time = "2025-11-09T20:48:35.507Z" },
+ { url = "https://files.pythonhosted.org/packages/70/ae/83f793acd68e5cb24e483f44f482a1a15601848b9b6f199dacb970098f77/jiter-0.12.0-cp314-cp314t-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:deeb12a2223fe0135c7ff1356a143d57f95bbf1f4a66584f1fc74df21d86b993", size = 380714, upload-time = "2025-11-09T20:48:40.014Z" },
+ { url = "https://files.pythonhosted.org/packages/b1/5e/4808a88338ad2c228b1126b93fcd8ba145e919e886fe910d578230dabe3b/jiter-0.12.0-cp314-cp314t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c596cc0f4cb574877550ce4ecd51f8037469146addd676d7c1a30ebe6391923f", size = 365168, upload-time = "2025-11-09T20:48:41.462Z" },
+ { url = "https://files.pythonhosted.org/packages/0c/d4/04619a9e8095b42aef436b5aeb4c0282b4ff1b27d1db1508df9f5dc82750/jiter-0.12.0-cp314-cp314t-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:5ab4c823b216a4aeab3fdbf579c5843165756bd9ad87cc6b1c65919c4715f783", size = 387893, upload-time = "2025-11-09T20:48:42.921Z" },
+ { url = "https://files.pythonhosted.org/packages/17/ea/d3c7e62e4546fdc39197fa4a4315a563a89b95b6d54c0d25373842a59cbe/jiter-0.12.0-cp314-cp314t-musllinux_1_1_aarch64.whl", hash = "sha256:e427eee51149edf962203ff8db75a7514ab89be5cb623fb9cea1f20b54f1107b", size = 520828, upload-time = "2025-11-09T20:48:44.278Z" },
+ { url = "https://files.pythonhosted.org/packages/cc/0b/c6d3562a03fd767e31cb119d9041ea7958c3c80cb3d753eafb19b3b18349/jiter-0.12.0-cp314-cp314t-musllinux_1_1_x86_64.whl", hash = "sha256:edb868841f84c111255ba5e80339d386d937ec1fdce419518ce1bd9370fac5b6", size = 511009, upload-time = "2025-11-09T20:48:45.726Z" },
+ { url = "https://files.pythonhosted.org/packages/aa/51/2cb4468b3448a8385ebcd15059d325c9ce67df4e2758d133ab9442b19834/jiter-0.12.0-cp314-cp314t-win32.whl", hash = "sha256:8bbcfe2791dfdb7c5e48baf646d37a6a3dcb5a97a032017741dea9f817dca183", size = 205110, upload-time = "2025-11-09T20:48:47.033Z" },
+ { url = "https://files.pythonhosted.org/packages/b2/c5/ae5ec83dec9c2d1af805fd5fe8f74ebded9c8670c5210ec7820ce0dbeb1e/jiter-0.12.0-cp314-cp314t-win_amd64.whl", hash = "sha256:2fa940963bf02e1d8226027ef461e36af472dea85d36054ff835aeed944dd873", size = 205223, upload-time = "2025-11-09T20:48:49.076Z" },
+ { url = "https://files.pythonhosted.org/packages/97/9a/3c5391907277f0e55195550cf3fa8e293ae9ee0c00fb402fec1e38c0c82f/jiter-0.12.0-cp314-cp314t-win_arm64.whl", hash = "sha256:506c9708dd29b27288f9f8f1140c3cb0e3d8ddb045956d7757b1fa0e0f39a473", size = 185564, upload-time = "2025-11-09T20:48:50.376Z" },
{ url = "https://files.pythonhosted.org/packages/fe/54/5339ef1ecaa881c6948669956567a64d2670941925f245c434f494ffb0e5/jiter-0.12.0-graalpy311-graalpy242_311_native-macosx_10_12_x86_64.whl", hash = "sha256:4739a4657179ebf08f85914ce50332495811004cc1747852e8b2041ed2aab9b8", size = 311144, upload-time = "2025-11-09T20:49:10.503Z" },
{ url = "https://files.pythonhosted.org/packages/27/74/3446c652bffbd5e81ab354e388b1b5fc1d20daac34ee0ed11ff096b1b01a/jiter-0.12.0-graalpy311-graalpy242_311_native-macosx_11_0_arm64.whl", hash = "sha256:41da8def934bf7bec16cb24bd33c0ca62126d2d45d81d17b864bd5ad721393c3", size = 305877, upload-time = "2025-11-09T20:49:12.269Z" },
{ url = "https://files.pythonhosted.org/packages/a1/f4/ed76ef9043450f57aac2d4fbeb27175aa0eb9c38f833be6ef6379b3b9a86/jiter-0.12.0-graalpy311-graalpy242_311_native-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9c44ee814f499c082e69872d426b624987dbc5943ab06e9bbaa4f81989fdb79e", size = 340419, upload-time = "2025-11-09T20:49:13.803Z" },
@@ -576,6 +625,28 @@ wheels = [
{ url = "https://files.pythonhosted.org/packages/80/d6/2d1b89f6ca4bff1036499b1e29a1d02d282259f3681540e16563f27ebc23/markupsafe-3.0.3-cp313-cp313t-win32.whl", hash = "sha256:69c0b73548bc525c8cb9a251cddf1931d1db4d2258e9599c28c07ef3580ef354", size = 14612, upload-time = "2025-09-27T18:37:02.639Z" },
{ url = "https://files.pythonhosted.org/packages/2b/98/e48a4bfba0a0ffcf9925fe2d69240bfaa19c6f7507b8cd09c70684a53c1e/markupsafe-3.0.3-cp313-cp313t-win_amd64.whl", hash = "sha256:1b4b79e8ebf6b55351f0d91fe80f893b4743f104bff22e90697db1590e47a218", size = 15200, upload-time = "2025-09-27T18:37:03.582Z" },
{ url = "https://files.pythonhosted.org/packages/0e/72/e3cc540f351f316e9ed0f092757459afbc595824ca724cbc5a5d4263713f/markupsafe-3.0.3-cp313-cp313t-win_arm64.whl", hash = "sha256:ad2cf8aa28b8c020ab2fc8287b0f823d0a7d8630784c31e9ee5edea20f406287", size = 13973, upload-time = "2025-09-27T18:37:04.929Z" },
+ { url = "https://files.pythonhosted.org/packages/33/8a/8e42d4838cd89b7dde187011e97fe6c3af66d8c044997d2183fbd6d31352/markupsafe-3.0.3-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:eaa9599de571d72e2daf60164784109f19978b327a3910d3e9de8c97b5b70cfe", size = 11619, upload-time = "2025-09-27T18:37:06.342Z" },
+ { url = "https://files.pythonhosted.org/packages/b5/64/7660f8a4a8e53c924d0fa05dc3a55c9cee10bbd82b11c5afb27d44b096ce/markupsafe-3.0.3-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:c47a551199eb8eb2121d4f0f15ae0f923d31350ab9280078d1e5f12b249e0026", size = 12029, upload-time = "2025-09-27T18:37:07.213Z" },
+ { url = "https://files.pythonhosted.org/packages/da/ef/e648bfd021127bef5fa12e1720ffed0c6cbb8310c8d9bea7266337ff06de/markupsafe-3.0.3-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:f34c41761022dd093b4b6896d4810782ffbabe30f2d443ff5f083e0cbbb8c737", size = 24408, upload-time = "2025-09-27T18:37:09.572Z" },
+ { url = "https://files.pythonhosted.org/packages/41/3c/a36c2450754618e62008bf7435ccb0f88053e07592e6028a34776213d877/markupsafe-3.0.3-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:457a69a9577064c05a97c41f4e65148652db078a3a509039e64d3467b9e7ef97", size = 23005, upload-time = "2025-09-27T18:37:10.58Z" },
+ { url = "https://files.pythonhosted.org/packages/bc/20/b7fdf89a8456b099837cd1dc21974632a02a999ec9bf7ca3e490aacd98e7/markupsafe-3.0.3-cp314-cp314-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:e8afc3f2ccfa24215f8cb28dcf43f0113ac3c37c2f0f0806d8c70e4228c5cf4d", size = 22048, upload-time = "2025-09-27T18:37:11.547Z" },
+ { url = "https://files.pythonhosted.org/packages/9a/a7/591f592afdc734f47db08a75793a55d7fbcc6902a723ae4cfbab61010cc5/markupsafe-3.0.3-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:ec15a59cf5af7be74194f7ab02d0f59a62bdcf1a537677ce67a2537c9b87fcda", size = 23821, upload-time = "2025-09-27T18:37:12.48Z" },
+ { url = "https://files.pythonhosted.org/packages/7d/33/45b24e4f44195b26521bc6f1a82197118f74df348556594bd2262bda1038/markupsafe-3.0.3-cp314-cp314-musllinux_1_2_riscv64.whl", hash = "sha256:0eb9ff8191e8498cca014656ae6b8d61f39da5f95b488805da4bb029cccbfbaf", size = 21606, upload-time = "2025-09-27T18:37:13.485Z" },
+ { url = "https://files.pythonhosted.org/packages/ff/0e/53dfaca23a69fbfbbf17a4b64072090e70717344c52eaaaa9c5ddff1e5f0/markupsafe-3.0.3-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:2713baf880df847f2bece4230d4d094280f4e67b1e813eec43b4c0e144a34ffe", size = 23043, upload-time = "2025-09-27T18:37:14.408Z" },
+ { url = "https://files.pythonhosted.org/packages/46/11/f333a06fc16236d5238bfe74daccbca41459dcd8d1fa952e8fbd5dccfb70/markupsafe-3.0.3-cp314-cp314-win32.whl", hash = "sha256:729586769a26dbceff69f7a7dbbf59ab6572b99d94576a5592625d5b411576b9", size = 14747, upload-time = "2025-09-27T18:37:15.36Z" },
+ { url = "https://files.pythonhosted.org/packages/28/52/182836104b33b444e400b14f797212f720cbc9ed6ba34c800639d154e821/markupsafe-3.0.3-cp314-cp314-win_amd64.whl", hash = "sha256:bdc919ead48f234740ad807933cdf545180bfbe9342c2bb451556db2ed958581", size = 15341, upload-time = "2025-09-27T18:37:16.496Z" },
+ { url = "https://files.pythonhosted.org/packages/6f/18/acf23e91bd94fd7b3031558b1f013adfa21a8e407a3fdb32745538730382/markupsafe-3.0.3-cp314-cp314-win_arm64.whl", hash = "sha256:5a7d5dc5140555cf21a6fefbdbf8723f06fcd2f63ef108f2854de715e4422cb4", size = 14073, upload-time = "2025-09-27T18:37:17.476Z" },
+ { url = "https://files.pythonhosted.org/packages/3c/f0/57689aa4076e1b43b15fdfa646b04653969d50cf30c32a102762be2485da/markupsafe-3.0.3-cp314-cp314t-macosx_10_13_x86_64.whl", hash = "sha256:1353ef0c1b138e1907ae78e2f6c63ff67501122006b0f9abad68fda5f4ffc6ab", size = 11661, upload-time = "2025-09-27T18:37:18.453Z" },
+ { url = "https://files.pythonhosted.org/packages/89/c3/2e67a7ca217c6912985ec766c6393b636fb0c2344443ff9d91404dc4c79f/markupsafe-3.0.3-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:1085e7fbddd3be5f89cc898938f42c0b3c711fdcb37d75221de2666af647c175", size = 12069, upload-time = "2025-09-27T18:37:19.332Z" },
+ { url = "https://files.pythonhosted.org/packages/f0/00/be561dce4e6ca66b15276e184ce4b8aec61fe83662cce2f7d72bd3249d28/markupsafe-3.0.3-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:1b52b4fb9df4eb9ae465f8d0c228a00624de2334f216f178a995ccdcf82c4634", size = 25670, upload-time = "2025-09-27T18:37:20.245Z" },
+ { url = "https://files.pythonhosted.org/packages/50/09/c419f6f5a92e5fadde27efd190eca90f05e1261b10dbd8cbcb39cd8ea1dc/markupsafe-3.0.3-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:fed51ac40f757d41b7c48425901843666a6677e3e8eb0abcff09e4ba6e664f50", size = 23598, upload-time = "2025-09-27T18:37:21.177Z" },
+ { url = "https://files.pythonhosted.org/packages/22/44/a0681611106e0b2921b3033fc19bc53323e0b50bc70cffdd19f7d679bb66/markupsafe-3.0.3-cp314-cp314t-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:f190daf01f13c72eac4efd5c430a8de82489d9cff23c364c3ea822545032993e", size = 23261, upload-time = "2025-09-27T18:37:22.167Z" },
+ { url = "https://files.pythonhosted.org/packages/5f/57/1b0b3f100259dc9fffe780cfb60d4be71375510e435efec3d116b6436d43/markupsafe-3.0.3-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:e56b7d45a839a697b5eb268c82a71bd8c7f6c94d6fd50c3d577fa39a9f1409f5", size = 24835, upload-time = "2025-09-27T18:37:23.296Z" },
+ { url = "https://files.pythonhosted.org/packages/26/6a/4bf6d0c97c4920f1597cc14dd720705eca0bf7c787aebc6bb4d1bead5388/markupsafe-3.0.3-cp314-cp314t-musllinux_1_2_riscv64.whl", hash = "sha256:f3e98bb3798ead92273dc0e5fd0f31ade220f59a266ffd8a4f6065e0a3ce0523", size = 22733, upload-time = "2025-09-27T18:37:24.237Z" },
+ { url = "https://files.pythonhosted.org/packages/14/c7/ca723101509b518797fedc2fdf79ba57f886b4aca8a7d31857ba3ee8281f/markupsafe-3.0.3-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:5678211cb9333a6468fb8d8be0305520aa073f50d17f089b5b4b477ea6e67fdc", size = 23672, upload-time = "2025-09-27T18:37:25.271Z" },
+ { url = "https://files.pythonhosted.org/packages/fb/df/5bd7a48c256faecd1d36edc13133e51397e41b73bb77e1a69deab746ebac/markupsafe-3.0.3-cp314-cp314t-win32.whl", hash = "sha256:915c04ba3851909ce68ccc2b8e2cd691618c4dc4c4232fb7982bca3f41fd8c3d", size = 14819, upload-time = "2025-09-27T18:37:26.285Z" },
+ { url = "https://files.pythonhosted.org/packages/1a/8a/0402ba61a2f16038b48b39bccca271134be00c5c9f0f623208399333c448/markupsafe-3.0.3-cp314-cp314t-win_amd64.whl", hash = "sha256:4faffd047e07c38848ce017e8725090413cd80cbc23d86e55c587bf979e579c9", size = 15426, upload-time = "2025-09-27T18:37:27.316Z" },
+ { url = "https://files.pythonhosted.org/packages/70/bc/6f1c2f612465f5fa89b95bead1f44dcb607670fd42891d8fdcd5d039f4f4/markupsafe-3.0.3-cp314-cp314t-win_arm64.whl", hash = "sha256:32001d6a8fc98c8cb5c947787c5d08b0a50663d139f1305bac5885d98d9b40fa", size = 14146, upload-time = "2025-09-27T18:37:28.327Z" },
]
[[package]]
@@ -701,6 +772,27 @@ wheels = [
{ url = "https://files.pythonhosted.org/packages/ac/52/41f3d71296a3dcaa4f456aaa3c6fc8e745b43d0552b6bde56571bb4b4a0f/numpy-2.4.0-cp313-cp313t-win32.whl", hash = "sha256:20c115517513831860c573996e395707aa9fb691eb179200125c250e895fcd93", size = 6076216, upload-time = "2025-12-20T16:17:11.437Z" },
{ url = "https://files.pythonhosted.org/packages/35/ff/46fbfe60ab0710d2a2b16995f708750307d30eccbb4c38371ea9e986866e/numpy-2.4.0-cp313-cp313t-win_amd64.whl", hash = "sha256:b48e35f4ab6f6a7597c46e301126ceba4c44cd3280e3750f85db48b082624fa4", size = 12444263, upload-time = "2025-12-20T16:17:13.182Z" },
{ url = "https://files.pythonhosted.org/packages/a3/e3/9189ab319c01d2ed556c932ccf55064c5d75bb5850d1df7a482ce0badead/numpy-2.4.0-cp313-cp313t-win_arm64.whl", hash = "sha256:4d1cfce39e511069b11e67cd0bd78ceff31443b7c9e5c04db73c7a19f572967c", size = 10378265, upload-time = "2025-12-20T16:17:15.211Z" },
+ { url = "https://files.pythonhosted.org/packages/ab/ed/52eac27de39d5e5a6c9aadabe672bc06f55e24a3d9010cd1183948055d76/numpy-2.4.0-cp314-cp314-macosx_10_15_x86_64.whl", hash = "sha256:c95eb6db2884917d86cde0b4d4cf31adf485c8ec36bf8696dd66fa70de96f36b", size = 16647476, upload-time = "2025-12-20T16:17:17.671Z" },
+ { url = "https://files.pythonhosted.org/packages/77/c0/990ce1b7fcd4e09aeaa574e2a0a839589e4b08b2ca68070f1acb1fea6736/numpy-2.4.0-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:65167da969cd1ec3a1df31cb221ca3a19a8aaa25370ecb17d428415e93c1935e", size = 12374563, upload-time = "2025-12-20T16:17:20.216Z" },
+ { url = "https://files.pythonhosted.org/packages/37/7c/8c5e389c6ae8f5fd2277a988600d79e9625db3fff011a2d87ac80b881a4c/numpy-2.4.0-cp314-cp314-macosx_14_0_arm64.whl", hash = "sha256:3de19cfecd1465d0dcf8a5b5ea8b3155b42ed0b639dba4b71e323d74f2a3be5e", size = 5203107, upload-time = "2025-12-20T16:17:22.47Z" },
+ { url = "https://files.pythonhosted.org/packages/e6/94/ca5b3bd6a8a70a5eec9a0b8dd7f980c1eff4b8a54970a9a7fef248ef564f/numpy-2.4.0-cp314-cp314-macosx_14_0_x86_64.whl", hash = "sha256:6c05483c3136ac4c91b4e81903cb53a8707d316f488124d0398499a4f8e8ef51", size = 6538067, upload-time = "2025-12-20T16:17:24.001Z" },
+ { url = "https://files.pythonhosted.org/packages/79/43/993eb7bb5be6761dde2b3a3a594d689cec83398e3f58f4758010f3b85727/numpy-2.4.0-cp314-cp314-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:36667db4d6c1cea79c8930ab72fadfb4060feb4bfe724141cd4bd064d2e5f8ce", size = 14411926, upload-time = "2025-12-20T16:17:25.822Z" },
+ { url = "https://files.pythonhosted.org/packages/03/75/d4c43b61de473912496317a854dac54f1efec3eeb158438da6884b70bb90/numpy-2.4.0-cp314-cp314-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:9a818668b674047fd88c4cddada7ab8f1c298812783e8328e956b78dc4807f9f", size = 16354295, upload-time = "2025-12-20T16:17:28.308Z" },
+ { url = "https://files.pythonhosted.org/packages/b8/0a/b54615b47ee8736a6461a4bb6749128dd3435c5a759d5663f11f0e9af4ac/numpy-2.4.0-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:1ee32359fb7543b7b7bd0b2f46294db27e29e7bbdf70541e81b190836cd83ded", size = 16190242, upload-time = "2025-12-20T16:17:30.993Z" },
+ { url = "https://files.pythonhosted.org/packages/98/ce/ea207769aacad6246525ec6c6bbd66a2bf56c72443dc10e2f90feed29290/numpy-2.4.0-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:e493962256a38f58283de033d8af176c5c91c084ea30f15834f7545451c42059", size = 18280875, upload-time = "2025-12-20T16:17:33.327Z" },
+ { url = "https://files.pythonhosted.org/packages/17/ef/ec409437aa962ea372ed601c519a2b141701683ff028f894b7466f0ab42b/numpy-2.4.0-cp314-cp314-win32.whl", hash = "sha256:6bbaebf0d11567fa8926215ae731e1d58e6ec28a8a25235b8a47405d301332db", size = 6002530, upload-time = "2025-12-20T16:17:35.729Z" },
+ { url = "https://files.pythonhosted.org/packages/5f/4a/5cb94c787a3ed1ac65e1271b968686521169a7b3ec0b6544bb3ca32960b0/numpy-2.4.0-cp314-cp314-win_amd64.whl", hash = "sha256:3d857f55e7fdf7c38ab96c4558c95b97d1c685be6b05c249f5fdafcbd6f9899e", size = 12435890, upload-time = "2025-12-20T16:17:37.599Z" },
+ { url = "https://files.pythonhosted.org/packages/48/a0/04b89db963af9de1104975e2544f30de89adbf75b9e75f7dd2599be12c79/numpy-2.4.0-cp314-cp314-win_arm64.whl", hash = "sha256:bb50ce5fb202a26fd5404620e7ef820ad1ab3558b444cb0b55beb7ef66cd2d63", size = 10591892, upload-time = "2025-12-20T16:17:39.649Z" },
+ { url = "https://files.pythonhosted.org/packages/53/e5/d74b5ccf6712c06c7a545025a6a71bfa03bdc7e0568b405b0d655232fd92/numpy-2.4.0-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:355354388cba60f2132df297e2d53053d4063f79077b67b481d21276d61fc4df", size = 12494312, upload-time = "2025-12-20T16:17:41.714Z" },
+ { url = "https://files.pythonhosted.org/packages/c2/08/3ca9cc2ddf54dfee7ae9a6479c071092a228c68aef08252aa08dac2af002/numpy-2.4.0-cp314-cp314t-macosx_14_0_arm64.whl", hash = "sha256:1d8f9fde5f6dc1b6fc34df8162f3b3079365468703fee7f31d4e0cc8c63baed9", size = 5322862, upload-time = "2025-12-20T16:17:44.145Z" },
+ { url = "https://files.pythonhosted.org/packages/87/74/0bb63a68394c0c1e52670cfff2e309afa41edbe11b3327d9af29e4383f34/numpy-2.4.0-cp314-cp314t-macosx_14_0_x86_64.whl", hash = "sha256:e0434aa22c821f44eeb4c650b81c7fbdd8c0122c6c4b5a576a76d5a35625ecd9", size = 6644986, upload-time = "2025-12-20T16:17:46.203Z" },
+ { url = "https://files.pythonhosted.org/packages/06/8f/9264d9bdbcf8236af2823623fe2f3981d740fc3461e2787e231d97c38c28/numpy-2.4.0-cp314-cp314t-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:40483b2f2d3ba7aad426443767ff5632ec3156ef09742b96913787d13c336471", size = 14457958, upload-time = "2025-12-20T16:17:48.017Z" },
+ { url = "https://files.pythonhosted.org/packages/8c/d9/f9a69ae564bbc7236a35aa883319364ef5fd41f72aa320cc1cbe66148fe2/numpy-2.4.0-cp314-cp314t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:d9e6a7664ddd9746e20b7325351fe1a8408d0a2bf9c63b5e898290ddc8f09544", size = 16398394, upload-time = "2025-12-20T16:17:50.409Z" },
+ { url = "https://files.pythonhosted.org/packages/34/c7/39241501408dde7f885d241a98caba5421061a2c6d2b2197ac5e3aa842d8/numpy-2.4.0-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:ecb0019d44f4cdb50b676c5d0cb4b1eae8e15d1ed3d3e6639f986fc92b2ec52c", size = 16241044, upload-time = "2025-12-20T16:17:52.661Z" },
+ { url = "https://files.pythonhosted.org/packages/7c/95/cae7effd90e065a95e59fe710eeee05d7328ed169776dfdd9f789e032125/numpy-2.4.0-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:d0ffd9e2e4441c96a9c91ec1783285d80bf835b677853fc2770a89d50c1e48ac", size = 18321772, upload-time = "2025-12-20T16:17:54.947Z" },
+ { url = "https://files.pythonhosted.org/packages/96/df/3c6c279accd2bfb968a76298e5b276310bd55d243df4fa8ac5816d79347d/numpy-2.4.0-cp314-cp314t-win32.whl", hash = "sha256:77f0d13fa87036d7553bf81f0e1fe3ce68d14c9976c9851744e4d3e91127e95f", size = 6148320, upload-time = "2025-12-20T16:17:57.249Z" },
+ { url = "https://files.pythonhosted.org/packages/92/8d/f23033cce252e7a75cae853d17f582e86534c46404dea1c8ee094a9d6d84/numpy-2.4.0-cp314-cp314t-win_amd64.whl", hash = "sha256:b1f5b45829ac1848893f0ddf5cb326110604d6df96cdc255b0bf9edd154104d4", size = 12623460, upload-time = "2025-12-20T16:17:58.963Z" },
+ { url = "https://files.pythonhosted.org/packages/a4/4f/1f8475907d1a7c4ef9020edf7f39ea2422ec896849245f00688e4b268a71/numpy-2.4.0-cp314-cp314t-win_arm64.whl", hash = "sha256:23a3e9d1a6f360267e8fbb38ba5db355a6a7e9be71d7fce7ab3125e88bb646c8", size = 10661799, upload-time = "2025-12-20T16:18:01.078Z" },
{ url = "https://files.pythonhosted.org/packages/4b/ef/088e7c7342f300aaf3ee5f2c821c4b9996a1bef2aaf6a49cc8ab4883758e/numpy-2.4.0-pp311-pypy311_pp73-macosx_10_15_x86_64.whl", hash = "sha256:b54c83f1c0c0f1d748dca0af516062b8829d53d1f0c402be24b4257a9c48ada6", size = 16819003, upload-time = "2025-12-20T16:18:03.41Z" },
{ url = "https://files.pythonhosted.org/packages/ff/ce/a53017b5443b4b84517182d463fc7bcc2adb4faa8b20813f8e5f5aeb5faa/numpy-2.4.0-pp311-pypy311_pp73-macosx_11_0_arm64.whl", hash = "sha256:aabb081ca0ec5d39591fc33018cd4b3f96e1a2dd6756282029986d00a785fba4", size = 12567105, upload-time = "2025-12-20T16:18:05.594Z" },
{ url = "https://files.pythonhosted.org/packages/77/58/5ff91b161f2ec650c88a626c3905d938c89aaadabd0431e6d9c1330c83e2/numpy-2.4.0-pp311-pypy311_pp73-macosx_14_0_arm64.whl", hash = "sha256:8eafe7c36c8430b7794edeab3087dec7bf31d634d92f2af9949434b9d1964cba", size = 5395590, upload-time = "2025-12-20T16:18:08.031Z" },
@@ -849,12 +941,12 @@ name = "onnxruntime"
version = "1.23.2"
source = { registry = "https://pypi.org/simple" }
dependencies = [
- { name = "coloredlogs" },
- { name = "flatbuffers" },
- { name = "numpy" },
- { name = "packaging" },
- { name = "protobuf" },
- { name = "sympy" },
+ { name = "coloredlogs", marker = "python_full_version < '3.14'" },
+ { name = "flatbuffers", marker = "python_full_version < '3.14'" },
+ { name = "numpy", marker = "python_full_version < '3.14'" },
+ { name = "packaging", marker = "python_full_version < '3.14'" },
+ { name = "protobuf", marker = "python_full_version < '3.14'" },
+ { name = "sympy", marker = "python_full_version < '3.14'" },
]
wheels = [
{ url = "https://files.pythonhosted.org/packages/44/be/467b00f09061572f022ffd17e49e49e5a7a789056bad95b54dfd3bee73ff/onnxruntime-1.23.2-cp311-cp311-macosx_13_0_arm64.whl", hash = "sha256:6f91d2c9b0965e86827a5ba01531d5b669770b01775b23199565d6c1f136616c", size = 17196113, upload-time = "2025-10-22T03:47:33.526Z" },
@@ -943,6 +1035,19 @@ wheels = [
{ url = "https://files.pythonhosted.org/packages/44/23/78d645adc35d94d1ac4f2a3c4112ab6f5b8999f4898b8cdf01252f8df4a9/pandas-2.3.3-cp313-cp313t-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:900f47d8f20860de523a1ac881c4c36d65efcb2eb850e6948140fa781736e110", size = 12121912, upload-time = "2025-09-29T23:23:05.042Z" },
{ url = "https://files.pythonhosted.org/packages/53/da/d10013df5e6aaef6b425aa0c32e1fc1f3e431e4bcabd420517dceadce354/pandas-2.3.3-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:a45c765238e2ed7d7c608fc5bc4a6f88b642f2f01e70c0c23d2224dd21829d86", size = 12712160, upload-time = "2025-09-29T23:23:28.57Z" },
{ url = "https://files.pythonhosted.org/packages/bd/17/e756653095a083d8a37cbd816cb87148debcfcd920129b25f99dd8d04271/pandas-2.3.3-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:c4fc4c21971a1a9f4bdb4c73978c7f7256caa3e62b323f70d6cb80db583350bc", size = 13199233, upload-time = "2025-09-29T23:24:24.876Z" },
+ { url = "https://files.pythonhosted.org/packages/04/fd/74903979833db8390b73b3a8a7d30d146d710bd32703724dd9083950386f/pandas-2.3.3-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:ee15f284898e7b246df8087fc82b87b01686f98ee67d85a17b7ab44143a3a9a0", size = 11540635, upload-time = "2025-09-29T23:25:52.486Z" },
+ { url = "https://files.pythonhosted.org/packages/21/00/266d6b357ad5e6d3ad55093a7e8efc7dd245f5a842b584db9f30b0f0a287/pandas-2.3.3-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:1611aedd912e1ff81ff41c745822980c49ce4a7907537be8692c8dbc31924593", size = 10759079, upload-time = "2025-09-29T23:26:33.204Z" },
+ { url = "https://files.pythonhosted.org/packages/ca/05/d01ef80a7a3a12b2f8bbf16daba1e17c98a2f039cbc8e2f77a2c5a63d382/pandas-2.3.3-cp314-cp314-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:6d2cefc361461662ac48810cb14365a365ce864afe85ef1f447ff5a1e99ea81c", size = 11814049, upload-time = "2025-09-29T23:27:15.384Z" },
+ { url = "https://files.pythonhosted.org/packages/15/b2/0e62f78c0c5ba7e3d2c5945a82456f4fac76c480940f805e0b97fcbc2f65/pandas-2.3.3-cp314-cp314-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:ee67acbbf05014ea6c763beb097e03cd629961c8a632075eeb34247120abcb4b", size = 12332638, upload-time = "2025-09-29T23:27:51.625Z" },
+ { url = "https://files.pythonhosted.org/packages/c5/33/dd70400631b62b9b29c3c93d2feee1d0964dc2bae2e5ad7a6c73a7f25325/pandas-2.3.3-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:c46467899aaa4da076d5abc11084634e2d197e9460643dd455ac3db5856b24d6", size = 12886834, upload-time = "2025-09-29T23:28:21.289Z" },
+ { url = "https://files.pythonhosted.org/packages/d3/18/b5d48f55821228d0d2692b34fd5034bb185e854bdb592e9c640f6290e012/pandas-2.3.3-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:6253c72c6a1d990a410bc7de641d34053364ef8bcd3126f7e7450125887dffe3", size = 13409925, upload-time = "2025-09-29T23:28:58.261Z" },
+ { url = "https://files.pythonhosted.org/packages/a6/3d/124ac75fcd0ecc09b8fdccb0246ef65e35b012030defb0e0eba2cbbbe948/pandas-2.3.3-cp314-cp314-win_amd64.whl", hash = "sha256:1b07204a219b3b7350abaae088f451860223a52cfb8a6c53358e7948735158e5", size = 11109071, upload-time = "2025-09-29T23:32:27.484Z" },
+ { url = "https://files.pythonhosted.org/packages/89/9c/0e21c895c38a157e0faa1fb64587a9226d6dd46452cac4532d80c3c4a244/pandas-2.3.3-cp314-cp314t-macosx_10_13_x86_64.whl", hash = "sha256:2462b1a365b6109d275250baaae7b760fd25c726aaca0054649286bcfbb3e8ec", size = 12048504, upload-time = "2025-09-29T23:29:31.47Z" },
+ { url = "https://files.pythonhosted.org/packages/d7/82/b69a1c95df796858777b68fbe6a81d37443a33319761d7c652ce77797475/pandas-2.3.3-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:0242fe9a49aa8b4d78a4fa03acb397a58833ef6199e9aa40a95f027bb3a1b6e7", size = 11410702, upload-time = "2025-09-29T23:29:54.591Z" },
+ { url = "https://files.pythonhosted.org/packages/f9/88/702bde3ba0a94b8c73a0181e05144b10f13f29ebfc2150c3a79062a8195d/pandas-2.3.3-cp314-cp314t-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:a21d830e78df0a515db2b3d2f5570610f5e6bd2e27749770e8bb7b524b89b450", size = 11634535, upload-time = "2025-09-29T23:30:21.003Z" },
+ { url = "https://files.pythonhosted.org/packages/a4/1e/1bac1a839d12e6a82ec6cb40cda2edde64a2013a66963293696bbf31fbbb/pandas-2.3.3-cp314-cp314t-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:2e3ebdb170b5ef78f19bfb71b0dc5dc58775032361fa188e814959b74d726dd5", size = 12121582, upload-time = "2025-09-29T23:30:43.391Z" },
+ { url = "https://files.pythonhosted.org/packages/44/91/483de934193e12a3b1d6ae7c8645d083ff88dec75f46e827562f1e4b4da6/pandas-2.3.3-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:d051c0e065b94b7a3cea50eb1ec32e912cd96dba41647eb24104b6c6c14c5788", size = 12699963, upload-time = "2025-09-29T23:31:10.009Z" },
+ { url = "https://files.pythonhosted.org/packages/70/44/5191d2e4026f86a2a109053e194d3ba7a31a2d10a9c2348368c63ed4e85a/pandas-2.3.3-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:3869faf4bd07b3b66a9f462417d0ca3a9df29a9f6abd5d0d0dbab15dac7abe87", size = 13202175, upload-time = "2025-09-29T23:31:59.173Z" },
]
[[package]]
@@ -998,6 +1103,31 @@ wheels = [
{ url = "https://files.pythonhosted.org/packages/86/77/eacc62356b4cf81abe99ff9dbc7402750044aed02cfd6a503f7c6fc11f3e/pillow-12.1.0-cp313-cp313t-win32.whl", hash = "sha256:7315f9137087c4e0ee73a761b163fc9aa3b19f5f606a7fc08d83fd3e4379af65", size = 6336445, upload-time = "2026-01-02T09:12:14.775Z" },
{ url = "https://files.pythonhosted.org/packages/e7/3c/57d81d0b74d218706dafccb87a87ea44262c43eef98eb3b164fd000e0491/pillow-12.1.0-cp313-cp313t-win_amd64.whl", hash = "sha256:0ddedfaa8b5f0b4ffbc2fa87b556dc59f6bb4ecb14a53b33f9189713ae8053c0", size = 7045354, upload-time = "2026-01-02T09:12:16.599Z" },
{ url = "https://files.pythonhosted.org/packages/ac/82/8b9b97bba2e3576a340f93b044a3a3a09841170ab4c1eb0d5c93469fd32f/pillow-12.1.0-cp313-cp313t-win_arm64.whl", hash = "sha256:80941e6d573197a0c28f394753de529bb436b1ca990ed6e765cf42426abc39f8", size = 2454547, upload-time = "2026-01-02T09:12:18.704Z" },
+ { url = "https://files.pythonhosted.org/packages/8c/87/bdf971d8bbcf80a348cc3bacfcb239f5882100fe80534b0ce67a784181d8/pillow-12.1.0-cp314-cp314-ios_13_0_arm64_iphoneos.whl", hash = "sha256:5cb7bc1966d031aec37ddb9dcf15c2da5b2e9f7cc3ca7c54473a20a927e1eb91", size = 4062533, upload-time = "2026-01-02T09:12:20.791Z" },
+ { url = "https://files.pythonhosted.org/packages/ff/4f/5eb37a681c68d605eb7034c004875c81f86ec9ef51f5be4a63eadd58859a/pillow-12.1.0-cp314-cp314-ios_13_0_arm64_iphonesimulator.whl", hash = "sha256:97e9993d5ed946aba26baf9c1e8cf18adbab584b99f452ee72f7ee8acb882796", size = 4138546, upload-time = "2026-01-02T09:12:23.664Z" },
+ { url = "https://files.pythonhosted.org/packages/11/6d/19a95acb2edbace40dcd582d077b991646b7083c41b98da4ed7555b59733/pillow-12.1.0-cp314-cp314-ios_13_0_x86_64_iphonesimulator.whl", hash = "sha256:414b9a78e14ffeb98128863314e62c3f24b8a86081066625700b7985b3f529bd", size = 3601163, upload-time = "2026-01-02T09:12:26.338Z" },
+ { url = "https://files.pythonhosted.org/packages/fc/36/2b8138e51cb42e4cc39c3297713455548be855a50558c3ac2beebdc251dd/pillow-12.1.0-cp314-cp314-macosx_10_15_x86_64.whl", hash = "sha256:e6bdb408f7c9dd2a5ff2b14a3b0bb6d4deb29fb9961e6eb3ae2031ae9a5cec13", size = 5266086, upload-time = "2026-01-02T09:12:28.782Z" },
+ { url = "https://files.pythonhosted.org/packages/53/4b/649056e4d22e1caa90816bf99cef0884aed607ed38075bd75f091a607a38/pillow-12.1.0-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:3413c2ae377550f5487991d444428f1a8ae92784aac79caa8b1e3b89b175f77e", size = 4657344, upload-time = "2026-01-02T09:12:31.117Z" },
+ { url = "https://files.pythonhosted.org/packages/6c/6b/c5742cea0f1ade0cd61485dc3d81f05261fc2276f537fbdc00802de56779/pillow-12.1.0-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:e5dcbe95016e88437ecf33544ba5db21ef1b8dd6e1b434a2cb2a3d605299e643", size = 6232114, upload-time = "2026-01-02T09:12:32.936Z" },
+ { url = "https://files.pythonhosted.org/packages/bf/8f/9f521268ce22d63991601aafd3d48d5ff7280a246a1ef62d626d67b44064/pillow-12.1.0-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:d0a7735df32ccbcc98b98a1ac785cc4b19b580be1bdf0aeb5c03223220ea09d5", size = 8042708, upload-time = "2026-01-02T09:12:34.78Z" },
+ { url = "https://files.pythonhosted.org/packages/1a/eb/257f38542893f021502a1bbe0c2e883c90b5cff26cc33b1584a841a06d30/pillow-12.1.0-cp314-cp314-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:0c27407a2d1b96774cbc4a7594129cc027339fd800cd081e44497722ea1179de", size = 6347762, upload-time = "2026-01-02T09:12:36.748Z" },
+ { url = "https://files.pythonhosted.org/packages/c4/5a/8ba375025701c09b309e8d5163c5a4ce0102fa86bbf8800eb0d7ac87bc51/pillow-12.1.0-cp314-cp314-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:15c794d74303828eaa957ff8070846d0efe8c630901a1c753fdc63850e19ecd9", size = 7039265, upload-time = "2026-01-02T09:12:39.082Z" },
+ { url = "https://files.pythonhosted.org/packages/cf/dc/cf5e4cdb3db533f539e88a7bbf9f190c64ab8a08a9bc7a4ccf55067872e4/pillow-12.1.0-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:c990547452ee2800d8506c4150280757f88532f3de2a58e3022e9b179107862a", size = 6462341, upload-time = "2026-01-02T09:12:40.946Z" },
+ { url = "https://files.pythonhosted.org/packages/d0/47/0291a25ac9550677e22eda48510cfc4fa4b2ef0396448b7fbdc0a6946309/pillow-12.1.0-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:b63e13dd27da389ed9475b3d28510f0f954bca0041e8e551b2a4eb1eab56a39a", size = 7165395, upload-time = "2026-01-02T09:12:42.706Z" },
+ { url = "https://files.pythonhosted.org/packages/4f/4c/e005a59393ec4d9416be06e6b45820403bb946a778e39ecec62f5b2b991e/pillow-12.1.0-cp314-cp314-win32.whl", hash = "sha256:1a949604f73eb07a8adab38c4fe50791f9919344398bdc8ac6b307f755fc7030", size = 6431413, upload-time = "2026-01-02T09:12:44.944Z" },
+ { url = "https://files.pythonhosted.org/packages/1c/af/f23697f587ac5f9095d67e31b81c95c0249cd461a9798a061ed6709b09b5/pillow-12.1.0-cp314-cp314-win_amd64.whl", hash = "sha256:4f9f6a650743f0ddee5593ac9e954ba1bdbc5e150bc066586d4f26127853ab94", size = 7176779, upload-time = "2026-01-02T09:12:46.727Z" },
+ { url = "https://files.pythonhosted.org/packages/b3/36/6a51abf8599232f3e9afbd16d52829376a68909fe14efe29084445db4b73/pillow-12.1.0-cp314-cp314-win_arm64.whl", hash = "sha256:808b99604f7873c800c4840f55ff389936ef1948e4e87645eaf3fccbc8477ac4", size = 2543105, upload-time = "2026-01-02T09:12:49.243Z" },
+ { url = "https://files.pythonhosted.org/packages/82/54/2e1dd20c8749ff225080d6ba465a0cab4387f5db0d1c5fb1439e2d99923f/pillow-12.1.0-cp314-cp314t-macosx_10_15_x86_64.whl", hash = "sha256:bc11908616c8a283cf7d664f77411a5ed2a02009b0097ff8abbba5e79128ccf2", size = 5268571, upload-time = "2026-01-02T09:12:51.11Z" },
+ { url = "https://files.pythonhosted.org/packages/57/61/571163a5ef86ec0cf30d265ac2a70ae6fc9e28413d1dc94fa37fae6bda89/pillow-12.1.0-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:896866d2d436563fa2a43a9d72f417874f16b5545955c54a64941e87c1376c61", size = 4660426, upload-time = "2026-01-02T09:12:52.865Z" },
+ { url = "https://files.pythonhosted.org/packages/5e/e1/53ee5163f794aef1bf84243f755ee6897a92c708505350dd1923f4afec48/pillow-12.1.0-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:8e178e3e99d3c0ea8fc64b88447f7cac8ccf058af422a6cedc690d0eadd98c51", size = 6269908, upload-time = "2026-01-02T09:12:54.884Z" },
+ { url = "https://files.pythonhosted.org/packages/bc/0b/b4b4106ff0ee1afa1dc599fde6ab230417f800279745124f6c50bcffed8e/pillow-12.1.0-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:079af2fb0c599c2ec144ba2c02766d1b55498e373b3ac64687e43849fbbef5bc", size = 8074733, upload-time = "2026-01-02T09:12:56.802Z" },
+ { url = "https://files.pythonhosted.org/packages/19/9f/80b411cbac4a732439e629a26ad3ef11907a8c7fc5377b7602f04f6fe4e7/pillow-12.1.0-cp314-cp314t-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:bdec5e43377761c5dbca620efb69a77f6855c5a379e32ac5b158f54c84212b14", size = 6381431, upload-time = "2026-01-02T09:12:58.823Z" },
+ { url = "https://files.pythonhosted.org/packages/8f/b7/d65c45db463b66ecb6abc17c6ba6917a911202a07662247e1355ce1789e7/pillow-12.1.0-cp314-cp314t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:565c986f4b45c020f5421a4cea13ef294dde9509a8577f29b2fc5edc7587fff8", size = 7068529, upload-time = "2026-01-02T09:13:00.885Z" },
+ { url = "https://files.pythonhosted.org/packages/50/96/dfd4cd726b4a45ae6e3c669fc9e49deb2241312605d33aba50499e9d9bd1/pillow-12.1.0-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:43aca0a55ce1eefc0aefa6253661cb54571857b1a7b2964bd8a1e3ef4b729924", size = 6492981, upload-time = "2026-01-02T09:13:03.314Z" },
+ { url = "https://files.pythonhosted.org/packages/4d/1c/b5dc52cf713ae46033359c5ca920444f18a6359ce1020dd3e9c553ea5bc6/pillow-12.1.0-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:0deedf2ea233722476b3a81e8cdfbad786f7adbed5d848469fa59fe52396e4ef", size = 7191878, upload-time = "2026-01-02T09:13:05.276Z" },
+ { url = "https://files.pythonhosted.org/packages/53/26/c4188248bd5edaf543864fe4834aebe9c9cb4968b6f573ce014cc42d0720/pillow-12.1.0-cp314-cp314t-win32.whl", hash = "sha256:b17fbdbe01c196e7e159aacb889e091f28e61020a8abeac07b68079b6e626988", size = 6438703, upload-time = "2026-01-02T09:13:07.491Z" },
+ { url = "https://files.pythonhosted.org/packages/b8/0e/69ed296de8ea05cb03ee139cee600f424ca166e632567b2d66727f08c7ed/pillow-12.1.0-cp314-cp314t-win_amd64.whl", hash = "sha256:27b9baecb428899db6c0de572d6d305cfaf38ca1596b5c0542a5182e3e74e8c6", size = 7182927, upload-time = "2026-01-02T09:13:09.841Z" },
+ { url = "https://files.pythonhosted.org/packages/fc/f5/68334c015eed9b5cff77814258717dec591ded209ab5b6fb70e2ae873d1d/pillow-12.1.0-cp314-cp314t-win_arm64.whl", hash = "sha256:f61333d817698bdcdd0f9d7793e365ac3d2a21c1f1eb02b32ad6aefb8d8ea831", size = 2545104, upload-time = "2026-01-02T09:13:12.068Z" },
{ url = "https://files.pythonhosted.org/packages/8b/bc/224b1d98cffd7164b14707c91aac83c07b047fbd8f58eba4066a3e53746a/pillow-12.1.0-pp311-pypy311_pp73-macosx_10_15_x86_64.whl", hash = "sha256:ca94b6aac0d7af2a10ba08c0f888b3d5114439b6b3ef39968378723622fed377", size = 5228605, upload-time = "2026-01-02T09:13:14.084Z" },
{ url = "https://files.pythonhosted.org/packages/0c/ca/49ca7769c4550107de049ed85208240ba0f330b3f2e316f24534795702ce/pillow-12.1.0-pp311-pypy311_pp73-macosx_11_0_arm64.whl", hash = "sha256:351889afef0f485b84078ea40fe33727a0492b9af3904661b0abbafee0355b72", size = 4622245, upload-time = "2026-01-02T09:13:15.964Z" },
{ url = "https://files.pythonhosted.org/packages/73/48/fac807ce82e5955bcc2718642b94b1bd22a82a6d452aea31cbb678cddf12/pillow-12.1.0-pp311-pypy311_pp73-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:bb0984b30e973f7e2884362b7d23d0a348c7143ee559f38ef3eaab640144204c", size = 5247593, upload-time = "2026-01-02T09:13:17.913Z" },
@@ -1098,6 +1228,20 @@ wheels = [
{ url = "https://files.pythonhosted.org/packages/b9/f0/77aa5198fd3943682b2e4faaf179a674f0edea0d55d326d83cb2277d9363/pyarrow-22.0.0-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:a9d9ffdc2ab696f6b15b4d1f7cec6658e1d788124418cb30030afbae31c64746", size = 48066216, upload-time = "2025-10-24T10:07:43.528Z" },
{ url = "https://files.pythonhosted.org/packages/79/87/a1937b6e78b2aff18b706d738c9e46ade5bfcf11b294e39c87706a0089ac/pyarrow-22.0.0-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:ec1a15968a9d80da01e1d30349b2b0d7cc91e96588ee324ce1b5228175043e95", size = 50288552, upload-time = "2025-10-24T10:07:53.519Z" },
{ url = "https://files.pythonhosted.org/packages/60/ae/b5a5811e11f25788ccfdaa8f26b6791c9807119dffcf80514505527c384c/pyarrow-22.0.0-cp313-cp313t-win_amd64.whl", hash = "sha256:bba208d9c7decf9961998edf5c65e3ea4355d5818dd6cd0f6809bec1afb951cc", size = 28262504, upload-time = "2025-10-24T10:08:00.932Z" },
+ { url = "https://files.pythonhosted.org/packages/bd/b0/0fa4d28a8edb42b0a7144edd20befd04173ac79819547216f8a9f36f9e50/pyarrow-22.0.0-cp314-cp314-macosx_12_0_arm64.whl", hash = "sha256:9bddc2cade6561f6820d4cd73f99a0243532ad506bc510a75a5a65a522b2d74d", size = 34224062, upload-time = "2025-10-24T10:08:14.101Z" },
+ { url = "https://files.pythonhosted.org/packages/0f/a8/7a719076b3c1be0acef56a07220c586f25cd24de0e3f3102b438d18ae5df/pyarrow-22.0.0-cp314-cp314-macosx_12_0_x86_64.whl", hash = "sha256:e70ff90c64419709d38c8932ea9fe1cc98415c4f87ea8da81719e43f02534bc9", size = 35990057, upload-time = "2025-10-24T10:08:21.842Z" },
+ { url = "https://files.pythonhosted.org/packages/89/3c/359ed54c93b47fb6fe30ed16cdf50e3f0e8b9ccfb11b86218c3619ae50a8/pyarrow-22.0.0-cp314-cp314-manylinux_2_28_aarch64.whl", hash = "sha256:92843c305330aa94a36e706c16209cd4df274693e777ca47112617db7d0ef3d7", size = 45068002, upload-time = "2025-10-24T10:08:29.034Z" },
+ { url = "https://files.pythonhosted.org/packages/55/fc/4945896cc8638536ee787a3bd6ce7cec8ec9acf452d78ec39ab328efa0a1/pyarrow-22.0.0-cp314-cp314-manylinux_2_28_x86_64.whl", hash = "sha256:6dda1ddac033d27421c20d7a7943eec60be44e0db4e079f33cc5af3b8280ccde", size = 47737765, upload-time = "2025-10-24T10:08:38.559Z" },
+ { url = "https://files.pythonhosted.org/packages/cd/5e/7cb7edeb2abfaa1f79b5d5eb89432356155c8426f75d3753cbcb9592c0fd/pyarrow-22.0.0-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:84378110dd9a6c06323b41b56e129c504d157d1a983ce8f5443761eb5256bafc", size = 48048139, upload-time = "2025-10-24T10:08:46.784Z" },
+ { url = "https://files.pythonhosted.org/packages/88/c6/546baa7c48185f5e9d6e59277c4b19f30f48c94d9dd938c2a80d4d6b067c/pyarrow-22.0.0-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:854794239111d2b88b40b6ef92aa478024d1e5074f364033e73e21e3f76b25e0", size = 50314244, upload-time = "2025-10-24T10:08:55.771Z" },
+ { url = "https://files.pythonhosted.org/packages/3c/79/755ff2d145aafec8d347bf18f95e4e81c00127f06d080135dfc86aea417c/pyarrow-22.0.0-cp314-cp314-win_amd64.whl", hash = "sha256:b883fe6fd85adad7932b3271c38ac289c65b7337c2c132e9569f9d3940620730", size = 28757501, upload-time = "2025-10-24T10:09:59.891Z" },
+ { url = "https://files.pythonhosted.org/packages/0e/d2/237d75ac28ced3147912954e3c1a174df43a95f4f88e467809118a8165e0/pyarrow-22.0.0-cp314-cp314t-macosx_12_0_arm64.whl", hash = "sha256:7a820d8ae11facf32585507c11f04e3f38343c1e784c9b5a8b1da5c930547fe2", size = 34355506, upload-time = "2025-10-24T10:09:02.953Z" },
+ { url = "https://files.pythonhosted.org/packages/1e/2c/733dfffe6d3069740f98e57ff81007809067d68626c5faef293434d11bd6/pyarrow-22.0.0-cp314-cp314t-macosx_12_0_x86_64.whl", hash = "sha256:c6ec3675d98915bf1ec8b3c7986422682f7232ea76cad276f4c8abd5b7319b70", size = 36047312, upload-time = "2025-10-24T10:09:10.334Z" },
+ { url = "https://files.pythonhosted.org/packages/7c/2b/29d6e3782dc1f299727462c1543af357a0f2c1d3c160ce199950d9ca51eb/pyarrow-22.0.0-cp314-cp314t-manylinux_2_28_aarch64.whl", hash = "sha256:3e739edd001b04f654b166204fc7a9de896cf6007eaff33409ee9e50ceaff754", size = 45081609, upload-time = "2025-10-24T10:09:18.61Z" },
+ { url = "https://files.pythonhosted.org/packages/8d/42/aa9355ecc05997915af1b7b947a7f66c02dcaa927f3203b87871c114ba10/pyarrow-22.0.0-cp314-cp314t-manylinux_2_28_x86_64.whl", hash = "sha256:7388ac685cab5b279a41dfe0a6ccd99e4dbf322edfb63e02fc0443bf24134e91", size = 47703663, upload-time = "2025-10-24T10:09:27.369Z" },
+ { url = "https://files.pythonhosted.org/packages/ee/62/45abedde480168e83a1de005b7b7043fd553321c1e8c5a9a114425f64842/pyarrow-22.0.0-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:f633074f36dbc33d5c05b5dc75371e5660f1dbf9c8b1d95669def05e5425989c", size = 48066543, upload-time = "2025-10-24T10:09:34.908Z" },
+ { url = "https://files.pythonhosted.org/packages/84/e9/7878940a5b072e4f3bf998770acafeae13b267f9893af5f6d4ab3904b67e/pyarrow-22.0.0-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:4c19236ae2402a8663a2c8f21f1870a03cc57f0bef7e4b6eb3238cc82944de80", size = 50288838, upload-time = "2025-10-24T10:09:44.394Z" },
+ { url = "https://files.pythonhosted.org/packages/7b/03/f335d6c52b4a4761bcc83499789a1e2e16d9d201a58c327a9b5cc9a41bd9/pyarrow-22.0.0-cp314-cp314t-win_amd64.whl", hash = "sha256:0c34fe18094686194f204a3b1787a27456897d8a2d62caf84b61e8dfbc0252ae", size = 29185594, upload-time = "2025-10-24T10:09:53.111Z" },
]
[[package]]
@@ -1166,6 +1310,34 @@ wheels = [
{ url = "https://files.pythonhosted.org/packages/1a/d9/c248c103856f807ef70c18a4f986693a46a8ffe1602e5d361485da502d20/pydantic_core-2.41.5-cp313-cp313-win32.whl", hash = "sha256:650ae77860b45cfa6e2cdafc42618ceafab3a2d9a3811fcfbd3bbf8ac3c40d36", size = 1994679, upload-time = "2025-11-04T13:40:50.619Z" },
{ url = "https://files.pythonhosted.org/packages/9e/8b/341991b158ddab181cff136acd2552c9f35bd30380422a639c0671e99a91/pydantic_core-2.41.5-cp313-cp313-win_amd64.whl", hash = "sha256:79ec52ec461e99e13791ec6508c722742ad745571f234ea6255bed38c6480f11", size = 2019766, upload-time = "2025-11-04T13:40:52.631Z" },
{ url = "https://files.pythonhosted.org/packages/73/7d/f2f9db34af103bea3e09735bb40b021788a5e834c81eedb541991badf8f5/pydantic_core-2.41.5-cp313-cp313-win_arm64.whl", hash = "sha256:3f84d5c1b4ab906093bdc1ff10484838aca54ef08de4afa9de0f5f14d69639cd", size = 1981005, upload-time = "2025-11-04T13:40:54.734Z" },
+ { url = "https://files.pythonhosted.org/packages/ea/28/46b7c5c9635ae96ea0fbb779e271a38129df2550f763937659ee6c5dbc65/pydantic_core-2.41.5-cp314-cp314-macosx_10_12_x86_64.whl", hash = "sha256:3f37a19d7ebcdd20b96485056ba9e8b304e27d9904d233d7b1015db320e51f0a", size = 2119622, upload-time = "2025-11-04T13:40:56.68Z" },
+ { url = "https://files.pythonhosted.org/packages/74/1a/145646e5687e8d9a1e8d09acb278c8535ebe9e972e1f162ed338a622f193/pydantic_core-2.41.5-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:1d1d9764366c73f996edd17abb6d9d7649a7eb690006ab6adbda117717099b14", size = 1891725, upload-time = "2025-11-04T13:40:58.807Z" },
+ { url = "https://files.pythonhosted.org/packages/23/04/e89c29e267b8060b40dca97bfc64a19b2a3cf99018167ea1677d96368273/pydantic_core-2.41.5-cp314-cp314-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:25e1c2af0fce638d5f1988b686f3b3ea8cd7de5f244ca147c777769e798a9cd1", size = 1915040, upload-time = "2025-11-04T13:41:00.853Z" },
+ { url = "https://files.pythonhosted.org/packages/84/a3/15a82ac7bd97992a82257f777b3583d3e84bdb06ba6858f745daa2ec8a85/pydantic_core-2.41.5-cp314-cp314-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:506d766a8727beef16b7adaeb8ee6217c64fc813646b424d0804d67c16eddb66", size = 2063691, upload-time = "2025-11-04T13:41:03.504Z" },
+ { url = "https://files.pythonhosted.org/packages/74/9b/0046701313c6ef08c0c1cf0e028c67c770a4e1275ca73131563c5f2a310a/pydantic_core-2.41.5-cp314-cp314-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:4819fa52133c9aa3c387b3328f25c1facc356491e6135b459f1de698ff64d869", size = 2213897, upload-time = "2025-11-04T13:41:05.804Z" },
+ { url = "https://files.pythonhosted.org/packages/8a/cd/6bac76ecd1b27e75a95ca3a9a559c643b3afcd2dd62086d4b7a32a18b169/pydantic_core-2.41.5-cp314-cp314-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2b761d210c9ea91feda40d25b4efe82a1707da2ef62901466a42492c028553a2", size = 2333302, upload-time = "2025-11-04T13:41:07.809Z" },
+ { url = "https://files.pythonhosted.org/packages/4c/d2/ef2074dc020dd6e109611a8be4449b98cd25e1b9b8a303c2f0fca2f2bcf7/pydantic_core-2.41.5-cp314-cp314-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:22f0fb8c1c583a3b6f24df2470833b40207e907b90c928cc8d3594b76f874375", size = 2064877, upload-time = "2025-11-04T13:41:09.827Z" },
+ { url = "https://files.pythonhosted.org/packages/18/66/e9db17a9a763d72f03de903883c057b2592c09509ccfe468187f2a2eef29/pydantic_core-2.41.5-cp314-cp314-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:2782c870e99878c634505236d81e5443092fba820f0373997ff75f90f68cd553", size = 2180680, upload-time = "2025-11-04T13:41:12.379Z" },
+ { url = "https://files.pythonhosted.org/packages/d3/9e/3ce66cebb929f3ced22be85d4c2399b8e85b622db77dad36b73c5387f8f8/pydantic_core-2.41.5-cp314-cp314-musllinux_1_1_aarch64.whl", hash = "sha256:0177272f88ab8312479336e1d777f6b124537d47f2123f89cb37e0accea97f90", size = 2138960, upload-time = "2025-11-04T13:41:14.627Z" },
+ { url = "https://files.pythonhosted.org/packages/a6/62/205a998f4327d2079326b01abee48e502ea739d174f0a89295c481a2272e/pydantic_core-2.41.5-cp314-cp314-musllinux_1_1_armv7l.whl", hash = "sha256:63510af5e38f8955b8ee5687740d6ebf7c2a0886d15a6d65c32814613681bc07", size = 2339102, upload-time = "2025-11-04T13:41:16.868Z" },
+ { url = "https://files.pythonhosted.org/packages/3c/0d/f05e79471e889d74d3d88f5bd20d0ed189ad94c2423d81ff8d0000aab4ff/pydantic_core-2.41.5-cp314-cp314-musllinux_1_1_x86_64.whl", hash = "sha256:e56ba91f47764cc14f1daacd723e3e82d1a89d783f0f5afe9c364b8bb491ccdb", size = 2326039, upload-time = "2025-11-04T13:41:18.934Z" },
+ { url = "https://files.pythonhosted.org/packages/ec/e1/e08a6208bb100da7e0c4b288eed624a703f4d129bde2da475721a80cab32/pydantic_core-2.41.5-cp314-cp314-win32.whl", hash = "sha256:aec5cf2fd867b4ff45b9959f8b20ea3993fc93e63c7363fe6851424c8a7e7c23", size = 1995126, upload-time = "2025-11-04T13:41:21.418Z" },
+ { url = "https://files.pythonhosted.org/packages/48/5d/56ba7b24e9557f99c9237e29f5c09913c81eeb2f3217e40e922353668092/pydantic_core-2.41.5-cp314-cp314-win_amd64.whl", hash = "sha256:8e7c86f27c585ef37c35e56a96363ab8de4e549a95512445b85c96d3e2f7c1bf", size = 2015489, upload-time = "2025-11-04T13:41:24.076Z" },
+ { url = "https://files.pythonhosted.org/packages/4e/bb/f7a190991ec9e3e0ba22e4993d8755bbc4a32925c0b5b42775c03e8148f9/pydantic_core-2.41.5-cp314-cp314-win_arm64.whl", hash = "sha256:e672ba74fbc2dc8eea59fb6d4aed6845e6905fc2a8afe93175d94a83ba2a01a0", size = 1977288, upload-time = "2025-11-04T13:41:26.33Z" },
+ { url = "https://files.pythonhosted.org/packages/92/ed/77542d0c51538e32e15afe7899d79efce4b81eee631d99850edc2f5e9349/pydantic_core-2.41.5-cp314-cp314t-macosx_10_12_x86_64.whl", hash = "sha256:8566def80554c3faa0e65ac30ab0932b9e3a5cd7f8323764303d468e5c37595a", size = 2120255, upload-time = "2025-11-04T13:41:28.569Z" },
+ { url = "https://files.pythonhosted.org/packages/bb/3d/6913dde84d5be21e284439676168b28d8bbba5600d838b9dca99de0fad71/pydantic_core-2.41.5-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:b80aa5095cd3109962a298ce14110ae16b8c1aece8b72f9dafe81cf597ad80b3", size = 1863760, upload-time = "2025-11-04T13:41:31.055Z" },
+ { url = "https://files.pythonhosted.org/packages/5a/f0/e5e6b99d4191da102f2b0eb9687aaa7f5bea5d9964071a84effc3e40f997/pydantic_core-2.41.5-cp314-cp314t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3006c3dd9ba34b0c094c544c6006cc79e87d8612999f1a5d43b769b89181f23c", size = 1878092, upload-time = "2025-11-04T13:41:33.21Z" },
+ { url = "https://files.pythonhosted.org/packages/71/48/36fb760642d568925953bcc8116455513d6e34c4beaa37544118c36aba6d/pydantic_core-2.41.5-cp314-cp314t-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:72f6c8b11857a856bcfa48c86f5368439f74453563f951e473514579d44aa612", size = 2053385, upload-time = "2025-11-04T13:41:35.508Z" },
+ { url = "https://files.pythonhosted.org/packages/20/25/92dc684dd8eb75a234bc1c764b4210cf2646479d54b47bf46061657292a8/pydantic_core-2.41.5-cp314-cp314t-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:5cb1b2f9742240e4bb26b652a5aeb840aa4b417c7748b6f8387927bc6e45e40d", size = 2218832, upload-time = "2025-11-04T13:41:37.732Z" },
+ { url = "https://files.pythonhosted.org/packages/e2/09/f53e0b05023d3e30357d82eb35835d0f6340ca344720a4599cd663dca599/pydantic_core-2.41.5-cp314-cp314t-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:bd3d54f38609ff308209bd43acea66061494157703364ae40c951f83ba99a1a9", size = 2327585, upload-time = "2025-11-04T13:41:40Z" },
+ { url = "https://files.pythonhosted.org/packages/aa/4e/2ae1aa85d6af35a39b236b1b1641de73f5a6ac4d5a7509f77b814885760c/pydantic_core-2.41.5-cp314-cp314t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2ff4321e56e879ee8d2a879501c8e469414d948f4aba74a2d4593184eb326660", size = 2041078, upload-time = "2025-11-04T13:41:42.323Z" },
+ { url = "https://files.pythonhosted.org/packages/cd/13/2e215f17f0ef326fc72afe94776edb77525142c693767fc347ed6288728d/pydantic_core-2.41.5-cp314-cp314t-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:d0d2568a8c11bf8225044aa94409e21da0cb09dcdafe9ecd10250b2baad531a9", size = 2173914, upload-time = "2025-11-04T13:41:45.221Z" },
+ { url = "https://files.pythonhosted.org/packages/02/7a/f999a6dcbcd0e5660bc348a3991c8915ce6599f4f2c6ac22f01d7a10816c/pydantic_core-2.41.5-cp314-cp314t-musllinux_1_1_aarch64.whl", hash = "sha256:a39455728aabd58ceabb03c90e12f71fd30fa69615760a075b9fec596456ccc3", size = 2129560, upload-time = "2025-11-04T13:41:47.474Z" },
+ { url = "https://files.pythonhosted.org/packages/3a/b1/6c990ac65e3b4c079a4fb9f5b05f5b013afa0f4ed6780a3dd236d2cbdc64/pydantic_core-2.41.5-cp314-cp314t-musllinux_1_1_armv7l.whl", hash = "sha256:239edca560d05757817c13dc17c50766136d21f7cd0fac50295499ae24f90fdf", size = 2329244, upload-time = "2025-11-04T13:41:49.992Z" },
+ { url = "https://files.pythonhosted.org/packages/d9/02/3c562f3a51afd4d88fff8dffb1771b30cfdfd79befd9883ee094f5b6c0d8/pydantic_core-2.41.5-cp314-cp314t-musllinux_1_1_x86_64.whl", hash = "sha256:2a5e06546e19f24c6a96a129142a75cee553cc018ffee48a460059b1185f4470", size = 2331955, upload-time = "2025-11-04T13:41:54.079Z" },
+ { url = "https://files.pythonhosted.org/packages/5c/96/5fb7d8c3c17bc8c62fdb031c47d77a1af698f1d7a406b0f79aaa1338f9ad/pydantic_core-2.41.5-cp314-cp314t-win32.whl", hash = "sha256:b4ececa40ac28afa90871c2cc2b9ffd2ff0bf749380fbdf57d165fd23da353aa", size = 1988906, upload-time = "2025-11-04T13:41:56.606Z" },
+ { url = "https://files.pythonhosted.org/packages/22/ed/182129d83032702912c2e2d8bbe33c036f342cc735737064668585dac28f/pydantic_core-2.41.5-cp314-cp314t-win_amd64.whl", hash = "sha256:80aa89cad80b32a912a65332f64a4450ed00966111b6615ca6816153d3585a8c", size = 1981607, upload-time = "2025-11-04T13:41:58.889Z" },
+ { url = "https://files.pythonhosted.org/packages/9f/ed/068e41660b832bb0b1aa5b58011dea2a3fe0ba7861ff38c4d4904c1c1a99/pydantic_core-2.41.5-cp314-cp314t-win_arm64.whl", hash = "sha256:35b44f37a3199f771c3eaa53051bc8a70cd7b54f333531c59e29fd4db5d15008", size = 1974769, upload-time = "2025-11-04T13:42:01.186Z" },
{ url = "https://files.pythonhosted.org/packages/11/72/90fda5ee3b97e51c494938a4a44c3a35a9c96c19bba12372fb9c634d6f57/pydantic_core-2.41.5-graalpy311-graalpy242_311_native-macosx_10_12_x86_64.whl", hash = "sha256:b96d5f26b05d03cc60f11a7761a5ded1741da411e7fe0909e27a5e6a0cb7b034", size = 2115441, upload-time = "2025-11-04T13:42:39.557Z" },
{ url = "https://files.pythonhosted.org/packages/1f/53/8942f884fa33f50794f119012dc6a1a02ac43a56407adaac20463df8e98f/pydantic_core-2.41.5-graalpy311-graalpy242_311_native-macosx_11_0_arm64.whl", hash = "sha256:634e8609e89ceecea15e2d61bc9ac3718caaaa71963717bf3c8f38bfde64242c", size = 1930291, upload-time = "2025-11-04T13:42:42.169Z" },
{ url = "https://files.pythonhosted.org/packages/79/c8/ecb9ed9cd942bce09fc888ee960b52654fbdbede4ba6c2d6e0d3b1d8b49c/pydantic_core-2.41.5-graalpy311-graalpy242_311_native-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:93e8740d7503eb008aa2df04d3b9735f845d43ae845e6dcd2be0b55a2da43cd2", size = 1948632, upload-time = "2025-11-04T13:42:44.564Z" },
@@ -1222,6 +1394,10 @@ wheels = [
{ url = "https://files.pythonhosted.org/packages/8c/b6/a81291350f864f8c2bf58c1d413b2fdce24cc57cc0866f71b23e2f3406b3/pylibseekdb-1.0.0.post1-cp313-cp313-manylinux_2_28_x86_64.whl", hash = "sha256:e12ac23e8409fdb7785d8054ff4361910e761540ab7eafede9aa464e7dbc1ac7", size = 80346064, upload-time = "2025-11-17T11:01:38.447Z" },
{ url = "https://files.pythonhosted.org/packages/bb/f9/4b83f9118a2884be01e09362fa9963f6e7892fd4bed326059445072485c6/pylibseekdb-1.0.0.post1-cp313-cp313t-manylinux_2_28_aarch64.whl", hash = "sha256:82d2c56dbce6d41f2059cd4285292f00bf801eb6f5c36df12ab30eb18c714070", size = 59927878, upload-time = "2025-11-17T11:31:28.833Z" },
{ url = "https://files.pythonhosted.org/packages/b1/93/28c9ff560032b7e7fe2fb5e76979b482c75de516838775c956b3999b00c5/pylibseekdb-1.0.0.post1-cp313-cp313t-manylinux_2_28_x86_64.whl", hash = "sha256:7249a82f55e1e8f4c13c0f6a1a773fa95902d8e2334c674491e601b2efbcc89b", size = 80349282, upload-time = "2025-11-17T11:01:43.298Z" },
+ { url = "https://files.pythonhosted.org/packages/ea/0b/0084a0d78deb0dfc6ff36b4f6ae64c091398a2e3ef3ee7b3db0d8d78e115/pylibseekdb-1.0.0.post1-cp314-cp314-manylinux_2_28_aarch64.whl", hash = "sha256:c1113b6b6579a8743cb6dcceed3a21473713c988cab91650c85e01d58682a4b7", size = 59929351, upload-time = "2025-11-17T11:31:38.231Z" },
+ { url = "https://files.pythonhosted.org/packages/8a/f1/615f960f70f5b8caf512f8c32c93b4677fa638da2d8ed2bc792d1fb76264/pylibseekdb-1.0.0.post1-cp314-cp314-manylinux_2_28_x86_64.whl", hash = "sha256:fb8b195338f42a0c5d021b0ad67aad342348167adacdb500eadd3c649a93d485", size = 80353322, upload-time = "2025-11-17T11:01:47.772Z" },
+ { url = "https://files.pythonhosted.org/packages/9d/7f/a3c81ef9c4fab8f2c8d48d7a184100c59e70f384310ddbb12a135d6ec082/pylibseekdb-1.0.0.post1-cp314-cp314t-manylinux_2_28_aarch64.whl", hash = "sha256:4cdb0b11e64b465c77dc52a76ec46ab9ff85eba2c5af7ef5f2a4001288e1c49a", size = 59935108, upload-time = "2025-11-17T11:31:46.795Z" },
+ { url = "https://files.pythonhosted.org/packages/cc/24/2dfc7721493e492e50d29cda9fee99360a39334b6e63aef0f9895cb9be8c/pylibseekdb-1.0.0.post1-cp314-cp314t-manylinux_2_28_x86_64.whl", hash = "sha256:9878fb337111d3c3367a936aee61fac34238f0d0901cedf7773d061855407d06", size = 80354154, upload-time = "2025-11-17T11:01:52.224Z" },
]
[[package]]
@@ -1237,6 +1413,10 @@ wheels = [
{ url = "https://files.pythonhosted.org/packages/13/aa/ac67fe8376af4ecc6619d453692caac2bb3bd6473e3236767baee17c6bc9/pylibseekdb_runtime-1.0.0.post1-cp313-cp313-manylinux_2_28_x86_64.whl", hash = "sha256:d58a30a9ea32238ec7db72bc6c8e199c3e4a2c54ffda039c0fc69573c78afdf8", size = 86347710, upload-time = "2025-11-17T11:02:21.603Z" },
{ url = "https://files.pythonhosted.org/packages/b7/7b/ad6e1b82f57f24e5bf6aedff61cae60a54ad0ce6994a94df9ab04378ff40/pylibseekdb_runtime-1.0.0.post1-cp313-cp313t-manylinux_2_28_aarch64.whl", hash = "sha256:b491b37347d2e806c9359e6c73ad5c399cd6bf9c3fa7daa8ee0b75b513f486ad", size = 84222093, upload-time = "2025-11-17T11:32:55.587Z" },
{ url = "https://files.pythonhosted.org/packages/82/e3/74d77fdc385c6b0b9c46ac36c1fe745438af6a23deecca881d5a49f35af0/pylibseekdb_runtime-1.0.0.post1-cp313-cp313t-manylinux_2_28_x86_64.whl", hash = "sha256:82bc2201dde2fd94f60ba7b4e52406602d40feff4301a4f5af82188beb5d9a2c", size = 86365110, upload-time = "2025-11-17T11:02:26.111Z" },
+ { url = "https://files.pythonhosted.org/packages/c0/c4/9e351a8c52c508091c3af1b802b0a66043282669eb8f50007b71b70782ce/pylibseekdb_runtime-1.0.0.post1-cp314-cp314-manylinux_2_28_aarch64.whl", hash = "sha256:57e46c2dec66f255e9a1a34476f5e80348b2ddfaa8ee8b39c6c6509506e45446", size = 84224151, upload-time = "2025-11-17T11:33:05.546Z" },
+ { url = "https://files.pythonhosted.org/packages/ea/23/aa13383e5fb18200dc2bc86c46f0158012f0cbabecd5cfbe3ac4bda064cb/pylibseekdb_runtime-1.0.0.post1-cp314-cp314-manylinux_2_28_x86_64.whl", hash = "sha256:eec0d00d824620b2f36635c12c920a3f3cd03a5509521d8a618a800b1b75ae04", size = 86354643, upload-time = "2025-11-17T11:02:32.552Z" },
+ { url = "https://files.pythonhosted.org/packages/77/bd/73d0525048c30fa2ff18fe4516943095d452e77484a27def88fe8fa17438/pylibseekdb_runtime-1.0.0.post1-cp314-cp314t-manylinux_2_28_aarch64.whl", hash = "sha256:aa2f6be0abdc0b4e35f2971cf96c26a72d1715901b85a7584ed4e395cf999027", size = 84222095, upload-time = "2025-11-17T11:33:15.46Z" },
+ { url = "https://files.pythonhosted.org/packages/0f/3d/22d4bd6cba2fd8093e01cd1246dfee7f970306cf6c60520481135f305eed/pylibseekdb_runtime-1.0.0.post1-cp314-cp314t-manylinux_2_28_x86_64.whl", hash = "sha256:916771f9fc6a613d0b8334f1688eb4519b314cd30a21c5e83096f84a039c7b06", size = 86352963, upload-time = "2025-11-17T11:02:37.896Z" },
]
[[package]]
@@ -1280,14 +1460,15 @@ name = "pyseekdb"
version = "1.0.0b4"
source = { editable = "." }
dependencies = [
- { name = "httpx" },
+ { name = "httpx", marker = "python_full_version < '3.14'" },
{ name = "numpy" },
- { name = "onnxruntime" },
+ { name = "onnxruntime", marker = "python_full_version < '3.14'" },
{ name = "pylibseekdb", marker = "sys_platform == 'linux'" },
{ name = "pymysql" },
+ { name = "sentence-transformers", marker = "python_full_version >= '3.14'" },
{ name = "tenacity" },
- { name = "tokenizers" },
- { name = "tqdm" },
+ { name = "tokenizers", marker = "python_full_version < '3.14'" },
+ { name = "tqdm", marker = "python_full_version < '3.14'" },
]
[package.dev-dependencies]
@@ -1303,14 +1484,15 @@ dev = [
[package.metadata]
requires-dist = [
- { name = "httpx" },
+ { name = "httpx", marker = "python_full_version < '3.14'" },
{ name = "numpy", specifier = ">=1.26" },
- { name = "onnxruntime", specifier = ">=1.19.0" },
+ { name = "onnxruntime", marker = "python_full_version < '3.14'", specifier = ">=1.19.0" },
{ name = "pylibseekdb", marker = "sys_platform == 'linux'" },
{ name = "pymysql", specifier = ">=1.1.1" },
+ { name = "sentence-transformers", marker = "python_full_version >= '3.14'" },
{ name = "tenacity" },
- { name = "tokenizers", specifier = ">=0.15.0" },
- { name = "tqdm" },
+ { name = "tokenizers", marker = "python_full_version < '3.14'", specifier = ">=0.15.0" },
+ { name = "tqdm", marker = "python_full_version < '3.14'" },
]
[package.metadata.requires-dev]
@@ -1405,6 +1587,24 @@ wheels = [
{ url = "https://files.pythonhosted.org/packages/de/94/980b50a6531b3019e45ddeada0626d45fa85cbe22300844a7983285bed3b/pyyaml-6.0.3-cp313-cp313-win32.whl", hash = "sha256:d0eae10f8159e8fdad514efdc92d74fd8d682c933a6dd088030f3834bc8e6b26", size = 137427, upload-time = "2025-09-25T21:32:32.58Z" },
{ url = "https://files.pythonhosted.org/packages/97/c9/39d5b874e8b28845e4ec2202b5da735d0199dbe5b8fb85f91398814a9a46/pyyaml-6.0.3-cp313-cp313-win_amd64.whl", hash = "sha256:79005a0d97d5ddabfeeea4cf676af11e647e41d81c9a7722a193022accdb6b7c", size = 154090, upload-time = "2025-09-25T21:32:33.659Z" },
{ url = "https://files.pythonhosted.org/packages/73/e8/2bdf3ca2090f68bb3d75b44da7bbc71843b19c9f2b9cb9b0f4ab7a5a4329/pyyaml-6.0.3-cp313-cp313-win_arm64.whl", hash = "sha256:5498cd1645aa724a7c71c8f378eb29ebe23da2fc0d7a08071d89469bf1d2defb", size = 140246, upload-time = "2025-09-25T21:32:34.663Z" },
+ { url = "https://files.pythonhosted.org/packages/9d/8c/f4bd7f6465179953d3ac9bc44ac1a8a3e6122cf8ada906b4f96c60172d43/pyyaml-6.0.3-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:8d1fab6bb153a416f9aeb4b8763bc0f22a5586065f86f7664fc23339fc1c1fac", size = 181814, upload-time = "2025-09-25T21:32:35.712Z" },
+ { url = "https://files.pythonhosted.org/packages/bd/9c/4d95bb87eb2063d20db7b60faa3840c1b18025517ae857371c4dd55a6b3a/pyyaml-6.0.3-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:34d5fcd24b8445fadc33f9cf348c1047101756fd760b4dacb5c3e99755703310", size = 173809, upload-time = "2025-09-25T21:32:36.789Z" },
+ { url = "https://files.pythonhosted.org/packages/92/b5/47e807c2623074914e29dabd16cbbdd4bf5e9b2db9f8090fa64411fc5382/pyyaml-6.0.3-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:501a031947e3a9025ed4405a168e6ef5ae3126c59f90ce0cd6f2bfc477be31b7", size = 766454, upload-time = "2025-09-25T21:32:37.966Z" },
+ { url = "https://files.pythonhosted.org/packages/02/9e/e5e9b168be58564121efb3de6859c452fccde0ab093d8438905899a3a483/pyyaml-6.0.3-cp314-cp314-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:b3bc83488de33889877a0f2543ade9f70c67d66d9ebb4ac959502e12de895788", size = 836355, upload-time = "2025-09-25T21:32:39.178Z" },
+ { url = "https://files.pythonhosted.org/packages/88/f9/16491d7ed2a919954993e48aa941b200f38040928474c9e85ea9e64222c3/pyyaml-6.0.3-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:c458b6d084f9b935061bc36216e8a69a7e293a2f1e68bf956dcd9e6cbcd143f5", size = 794175, upload-time = "2025-09-25T21:32:40.865Z" },
+ { url = "https://files.pythonhosted.org/packages/dd/3f/5989debef34dc6397317802b527dbbafb2b4760878a53d4166579111411e/pyyaml-6.0.3-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:7c6610def4f163542a622a73fb39f534f8c101d690126992300bf3207eab9764", size = 755228, upload-time = "2025-09-25T21:32:42.084Z" },
+ { url = "https://files.pythonhosted.org/packages/d7/ce/af88a49043cd2e265be63d083fc75b27b6ed062f5f9fd6cdc223ad62f03e/pyyaml-6.0.3-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:5190d403f121660ce8d1d2c1bb2ef1bd05b5f68533fc5c2ea899bd15f4399b35", size = 789194, upload-time = "2025-09-25T21:32:43.362Z" },
+ { url = "https://files.pythonhosted.org/packages/23/20/bb6982b26a40bb43951265ba29d4c246ef0ff59c9fdcdf0ed04e0687de4d/pyyaml-6.0.3-cp314-cp314-win_amd64.whl", hash = "sha256:4a2e8cebe2ff6ab7d1050ecd59c25d4c8bd7e6f400f5f82b96557ac0abafd0ac", size = 156429, upload-time = "2025-09-25T21:32:57.844Z" },
+ { url = "https://files.pythonhosted.org/packages/f4/f4/a4541072bb9422c8a883ab55255f918fa378ecf083f5b85e87fc2b4eda1b/pyyaml-6.0.3-cp314-cp314-win_arm64.whl", hash = "sha256:93dda82c9c22deb0a405ea4dc5f2d0cda384168e466364dec6255b293923b2f3", size = 143912, upload-time = "2025-09-25T21:32:59.247Z" },
+ { url = "https://files.pythonhosted.org/packages/7c/f9/07dd09ae774e4616edf6cda684ee78f97777bdd15847253637a6f052a62f/pyyaml-6.0.3-cp314-cp314t-macosx_10_13_x86_64.whl", hash = "sha256:02893d100e99e03eda1c8fd5c441d8c60103fd175728e23e431db1b589cf5ab3", size = 189108, upload-time = "2025-09-25T21:32:44.377Z" },
+ { url = "https://files.pythonhosted.org/packages/4e/78/8d08c9fb7ce09ad8c38ad533c1191cf27f7ae1effe5bb9400a46d9437fcf/pyyaml-6.0.3-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:c1ff362665ae507275af2853520967820d9124984e0f7466736aea23d8611fba", size = 183641, upload-time = "2025-09-25T21:32:45.407Z" },
+ { url = "https://files.pythonhosted.org/packages/7b/5b/3babb19104a46945cf816d047db2788bcaf8c94527a805610b0289a01c6b/pyyaml-6.0.3-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:6adc77889b628398debc7b65c073bcb99c4a0237b248cacaf3fe8a557563ef6c", size = 831901, upload-time = "2025-09-25T21:32:48.83Z" },
+ { url = "https://files.pythonhosted.org/packages/8b/cc/dff0684d8dc44da4d22a13f35f073d558c268780ce3c6ba1b87055bb0b87/pyyaml-6.0.3-cp314-cp314t-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:a80cb027f6b349846a3bf6d73b5e95e782175e52f22108cfa17876aaeff93702", size = 861132, upload-time = "2025-09-25T21:32:50.149Z" },
+ { url = "https://files.pythonhosted.org/packages/b1/5e/f77dc6b9036943e285ba76b49e118d9ea929885becb0a29ba8a7c75e29fe/pyyaml-6.0.3-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:00c4bdeba853cc34e7dd471f16b4114f4162dc03e6b7afcc2128711f0eca823c", size = 839261, upload-time = "2025-09-25T21:32:51.808Z" },
+ { url = "https://files.pythonhosted.org/packages/ce/88/a9db1376aa2a228197c58b37302f284b5617f56a5d959fd1763fb1675ce6/pyyaml-6.0.3-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:66e1674c3ef6f541c35191caae2d429b967b99e02040f5ba928632d9a7f0f065", size = 805272, upload-time = "2025-09-25T21:32:52.941Z" },
+ { url = "https://files.pythonhosted.org/packages/da/92/1446574745d74df0c92e6aa4a7b0b3130706a4142b2d1a5869f2eaa423c6/pyyaml-6.0.3-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:16249ee61e95f858e83976573de0f5b2893b3677ba71c9dd36b9cf8be9ac6d65", size = 829923, upload-time = "2025-09-25T21:32:54.537Z" },
+ { url = "https://files.pythonhosted.org/packages/f0/7a/1c7270340330e575b92f397352af856a8c06f230aa3e76f86b39d01b416a/pyyaml-6.0.3-cp314-cp314t-win_amd64.whl", hash = "sha256:4ad1906908f2f5ae4e5a8ddfce73c320c2a1429ec52eafd27138b7f1cbe341c9", size = 174062, upload-time = "2025-09-25T21:32:55.767Z" },
+ { url = "https://files.pythonhosted.org/packages/f1/12/de94a39c2ef588c7e6455cfbe7343d3b2dc9d6b6b2f40c4c6565744c873d/pyyaml-6.0.3-cp314-cp314t-win_arm64.whl", hash = "sha256:ebc55a14a21cb14062aa4162f906cd962b28e2e9ea38f9b4391244cd8de4ae0b", size = 149341, upload-time = "2025-09-25T21:32:56.828Z" },
]
[[package]]
@@ -1483,6 +1683,34 @@ wheels = [
{ url = "https://files.pythonhosted.org/packages/4f/f9/8bd6b656592f925b6845fcbb4d57603a3ac2fb2373344ffa1ed70aa6820a/regex-2025.11.3-cp313-cp313t-win32.whl", hash = "sha256:9ddc42e68114e161e51e272f667d640f97e84a2b9ef14b7477c53aac20c2d59a", size = 268792, upload-time = "2025-11-03T21:32:44.13Z" },
{ url = "https://files.pythonhosted.org/packages/e5/87/0e7d603467775ff65cd2aeabf1b5b50cc1c3708556a8b849a2fa4dd1542b/regex-2025.11.3-cp313-cp313t-win_amd64.whl", hash = "sha256:7a7c7fdf755032ffdd72c77e3d8096bdcb0eb92e89e17571a196f03d88b11b3c", size = 280214, upload-time = "2025-11-03T21:32:45.853Z" },
{ url = "https://files.pythonhosted.org/packages/8d/d0/2afc6f8e94e2b64bfb738a7c2b6387ac1699f09f032d363ed9447fd2bb57/regex-2025.11.3-cp313-cp313t-win_arm64.whl", hash = "sha256:df9eb838c44f570283712e7cff14c16329a9f0fb19ca492d21d4b7528ee6821e", size = 271469, upload-time = "2025-11-03T21:32:48.026Z" },
+ { url = "https://files.pythonhosted.org/packages/31/e9/f6e13de7e0983837f7b6d238ad9458800a874bf37c264f7923e63409944c/regex-2025.11.3-cp314-cp314-macosx_10_13_universal2.whl", hash = "sha256:9697a52e57576c83139d7c6f213d64485d3df5bf84807c35fa409e6c970801c6", size = 489089, upload-time = "2025-11-03T21:32:50.027Z" },
+ { url = "https://files.pythonhosted.org/packages/a3/5c/261f4a262f1fa65141c1b74b255988bd2fa020cc599e53b080667d591cfc/regex-2025.11.3-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:e18bc3f73bd41243c9b38a6d9f2366cd0e0137a9aebe2d8ff76c5b67d4c0a3f4", size = 291059, upload-time = "2025-11-03T21:32:51.682Z" },
+ { url = "https://files.pythonhosted.org/packages/8e/57/f14eeb7f072b0e9a5a090d1712741fd8f214ec193dba773cf5410108bb7d/regex-2025.11.3-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:61a08bcb0ec14ff4e0ed2044aad948d0659604f824cbd50b55e30b0ec6f09c73", size = 288900, upload-time = "2025-11-03T21:32:53.569Z" },
+ { url = "https://files.pythonhosted.org/packages/3c/6b/1d650c45e99a9b327586739d926a1cd4e94666b1bd4af90428b36af66dc7/regex-2025.11.3-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:c9c30003b9347c24bcc210958c5d167b9e4f9be786cb380a7d32f14f9b84674f", size = 799010, upload-time = "2025-11-03T21:32:55.222Z" },
+ { url = "https://files.pythonhosted.org/packages/99/ee/d66dcbc6b628ce4e3f7f0cbbb84603aa2fc0ffc878babc857726b8aab2e9/regex-2025.11.3-cp314-cp314-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:4e1e592789704459900728d88d41a46fe3969b82ab62945560a31732ffc19a6d", size = 864893, upload-time = "2025-11-03T21:32:57.239Z" },
+ { url = "https://files.pythonhosted.org/packages/bf/2d/f238229f1caba7ac87a6c4153d79947fb0261415827ae0f77c304260c7d3/regex-2025.11.3-cp314-cp314-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:6538241f45eb5a25aa575dbba1069ad786f68a4f2773a29a2bd3dd1f9de787be", size = 911522, upload-time = "2025-11-03T21:32:59.274Z" },
+ { url = "https://files.pythonhosted.org/packages/bd/3d/22a4eaba214a917c80e04f6025d26143690f0419511e0116508e24b11c9b/regex-2025.11.3-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:bce22519c989bb72a7e6b36a199384c53db7722fe669ba891da75907fe3587db", size = 803272, upload-time = "2025-11-03T21:33:01.393Z" },
+ { url = "https://files.pythonhosted.org/packages/84/b1/03188f634a409353a84b5ef49754b97dbcc0c0f6fd6c8ede505a8960a0a4/regex-2025.11.3-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:66d559b21d3640203ab9075797a55165d79017520685fb407b9234d72ab63c62", size = 787958, upload-time = "2025-11-03T21:33:03.379Z" },
+ { url = "https://files.pythonhosted.org/packages/99/6a/27d072f7fbf6fadd59c64d210305e1ff865cc3b78b526fd147db768c553b/regex-2025.11.3-cp314-cp314-musllinux_1_2_ppc64le.whl", hash = "sha256:669dcfb2e38f9e8c69507bace46f4889e3abbfd9b0c29719202883c0a603598f", size = 859289, upload-time = "2025-11-03T21:33:05.374Z" },
+ { url = "https://files.pythonhosted.org/packages/9a/70/1b3878f648e0b6abe023172dacb02157e685564853cc363d9961bcccde4e/regex-2025.11.3-cp314-cp314-musllinux_1_2_s390x.whl", hash = "sha256:32f74f35ff0f25a5021373ac61442edcb150731fbaa28286bbc8bb1582c89d02", size = 850026, upload-time = "2025-11-03T21:33:07.131Z" },
+ { url = "https://files.pythonhosted.org/packages/dd/d5/68e25559b526b8baab8e66839304ede68ff6727237a47727d240006bd0ff/regex-2025.11.3-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:e6c7a21dffba883234baefe91bc3388e629779582038f75d2a5be918e250f0ed", size = 789499, upload-time = "2025-11-03T21:33:09.141Z" },
+ { url = "https://files.pythonhosted.org/packages/fc/df/43971264857140a350910d4e33df725e8c94dd9dee8d2e4729fa0d63d49e/regex-2025.11.3-cp314-cp314-win32.whl", hash = "sha256:795ea137b1d809eb6836b43748b12634291c0ed55ad50a7d72d21edf1cd565c4", size = 271604, upload-time = "2025-11-03T21:33:10.9Z" },
+ { url = "https://files.pythonhosted.org/packages/01/6f/9711b57dc6894a55faf80a4c1b5aa4f8649805cb9c7aef46f7d27e2b9206/regex-2025.11.3-cp314-cp314-win_amd64.whl", hash = "sha256:9f95fbaa0ee1610ec0fc6b26668e9917a582ba80c52cc6d9ada15e30aa9ab9ad", size = 280320, upload-time = "2025-11-03T21:33:12.572Z" },
+ { url = "https://files.pythonhosted.org/packages/f1/7e/f6eaa207d4377481f5e1775cdeb5a443b5a59b392d0065f3417d31d80f87/regex-2025.11.3-cp314-cp314-win_arm64.whl", hash = "sha256:dfec44d532be4c07088c3de2876130ff0fbeeacaa89a137decbbb5f665855a0f", size = 273372, upload-time = "2025-11-03T21:33:14.219Z" },
+ { url = "https://files.pythonhosted.org/packages/c3/06/49b198550ee0f5e4184271cee87ba4dfd9692c91ec55289e6282f0f86ccf/regex-2025.11.3-cp314-cp314t-macosx_10_13_universal2.whl", hash = "sha256:ba0d8a5d7f04f73ee7d01d974d47c5834f8a1b0224390e4fe7c12a3a92a78ecc", size = 491985, upload-time = "2025-11-03T21:33:16.555Z" },
+ { url = "https://files.pythonhosted.org/packages/ce/bf/abdafade008f0b1c9da10d934034cb670432d6cf6cbe38bbb53a1cfd6cf8/regex-2025.11.3-cp314-cp314t-macosx_10_13_x86_64.whl", hash = "sha256:442d86cf1cfe4faabf97db7d901ef58347efd004934da045c745e7b5bd57ac49", size = 292669, upload-time = "2025-11-03T21:33:18.32Z" },
+ { url = "https://files.pythonhosted.org/packages/f9/ef/0c357bb8edbd2ad8e273fcb9e1761bc37b8acbc6e1be050bebd6475f19c1/regex-2025.11.3-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:fd0a5e563c756de210bb964789b5abe4f114dacae9104a47e1a649b910361536", size = 291030, upload-time = "2025-11-03T21:33:20.048Z" },
+ { url = "https://files.pythonhosted.org/packages/79/06/edbb67257596649b8fb088d6aeacbcb248ac195714b18a65e018bf4c0b50/regex-2025.11.3-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:bf3490bcbb985a1ae97b2ce9ad1c0f06a852d5b19dde9b07bdf25bf224248c95", size = 807674, upload-time = "2025-11-03T21:33:21.797Z" },
+ { url = "https://files.pythonhosted.org/packages/f4/d9/ad4deccfce0ea336296bd087f1a191543bb99ee1c53093dcd4c64d951d00/regex-2025.11.3-cp314-cp314t-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:3809988f0a8b8c9dcc0f92478d6501fac7200b9ec56aecf0ec21f4a2ec4b6009", size = 873451, upload-time = "2025-11-03T21:33:23.741Z" },
+ { url = "https://files.pythonhosted.org/packages/13/75/a55a4724c56ef13e3e04acaab29df26582f6978c000ac9cd6810ad1f341f/regex-2025.11.3-cp314-cp314t-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:f4ff94e58e84aedb9c9fce66d4ef9f27a190285b451420f297c9a09f2b9abee9", size = 914980, upload-time = "2025-11-03T21:33:25.999Z" },
+ { url = "https://files.pythonhosted.org/packages/67/1e/a1657ee15bd9116f70d4a530c736983eed997b361e20ecd8f5ca3759d5c5/regex-2025.11.3-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:7eb542fd347ce61e1321b0a6b945d5701528dca0cd9759c2e3bb8bd57e47964d", size = 812852, upload-time = "2025-11-03T21:33:27.852Z" },
+ { url = "https://files.pythonhosted.org/packages/b8/6f/f7516dde5506a588a561d296b2d0044839de06035bb486b326065b4c101e/regex-2025.11.3-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:d6c2d5919075a1f2e413c00b056ea0c2f065b3f5fe83c3d07d325ab92dce51d6", size = 795566, upload-time = "2025-11-03T21:33:32.364Z" },
+ { url = "https://files.pythonhosted.org/packages/d9/dd/3d10b9e170cc16fb34cb2cef91513cf3df65f440b3366030631b2984a264/regex-2025.11.3-cp314-cp314t-musllinux_1_2_ppc64le.whl", hash = "sha256:3f8bf11a4827cc7ce5a53d4ef6cddd5ad25595d3c1435ef08f76825851343154", size = 868463, upload-time = "2025-11-03T21:33:34.459Z" },
+ { url = "https://files.pythonhosted.org/packages/f5/8e/935e6beff1695aa9085ff83195daccd72acc82c81793df480f34569330de/regex-2025.11.3-cp314-cp314t-musllinux_1_2_s390x.whl", hash = "sha256:22c12d837298651e5550ac1d964e4ff57c3f56965fc1812c90c9fb2028eaf267", size = 854694, upload-time = "2025-11-03T21:33:36.793Z" },
+ { url = "https://files.pythonhosted.org/packages/92/12/10650181a040978b2f5720a6a74d44f841371a3d984c2083fc1752e4acf6/regex-2025.11.3-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:62ba394a3dda9ad41c7c780f60f6e4a70988741415ae96f6d1bf6c239cf01379", size = 799691, upload-time = "2025-11-03T21:33:39.079Z" },
+ { url = "https://files.pythonhosted.org/packages/67/90/8f37138181c9a7690e7e4cb388debbd389342db3c7381d636d2875940752/regex-2025.11.3-cp314-cp314t-win32.whl", hash = "sha256:4bf146dca15cdd53224a1bf46d628bd7590e4a07fbb69e720d561aea43a32b38", size = 274583, upload-time = "2025-11-03T21:33:41.302Z" },
+ { url = "https://files.pythonhosted.org/packages/8f/cd/867f5ec442d56beb56f5f854f40abcfc75e11d10b11fdb1869dd39c63aaf/regex-2025.11.3-cp314-cp314t-win_amd64.whl", hash = "sha256:adad1a1bcf1c9e76346e091d22d23ac54ef28e1365117d99521631078dfec9de", size = 284286, upload-time = "2025-11-03T21:33:43.324Z" },
+ { url = "https://files.pythonhosted.org/packages/20/31/32c0c4610cbc070362bf1d2e4ea86d1ea29014d400a6d6c2486fcfd57766/regex-2025.11.3-cp314-cp314t-win_arm64.whl", hash = "sha256:c54f768482cef41e219720013cd05933b6f971d9562544d691c68699bf2b6801", size = 274741, upload-time = "2025-11-03T21:33:45.557Z" },
]
[[package]]
@@ -1586,6 +1814,35 @@ wheels = [
{ 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" },
@@ -1684,6 +1941,18 @@ wheels = [
{ url = "https://files.pythonhosted.org/packages/fe/56/a85473cd75f200c9759e3a5f0bcab2d116c92a8a02ee08ccd73b870f8bb4/scikit_learn-1.8.0-cp313-cp313t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:80832434a6cc114f5219211eec13dcbc16c2bac0e31ef64c6d346cde3cf054cb", size = 8925045, upload-time = "2025-12-10T07:08:22.11Z" },
{ url = "https://files.pythonhosted.org/packages/cc/b7/64d8cfa896c64435ae57f4917a548d7ac7a44762ff9802f75a79b77cb633/scikit_learn-1.8.0-cp313-cp313t-win_amd64.whl", hash = "sha256:ee787491dbfe082d9c3013f01f5991658b0f38aa8177e4cd4bf434c58f551702", size = 8507994, upload-time = "2025-12-10T07:08:23.943Z" },
{ url = "https://files.pythonhosted.org/packages/5e/37/e192ea709551799379958b4c4771ec507347027bb7c942662c7fbeba31cb/scikit_learn-1.8.0-cp313-cp313t-win_arm64.whl", hash = "sha256:bf97c10a3f5a7543f9b88cbf488d33d175e9146115a451ae34568597ba33dcde", size = 7869518, upload-time = "2025-12-10T07:08:25.71Z" },
+ { url = "https://files.pythonhosted.org/packages/24/05/1af2c186174cc92dcab2233f327336058c077d38f6fe2aceb08e6ab4d509/scikit_learn-1.8.0-cp314-cp314-macosx_10_15_x86_64.whl", hash = "sha256:c22a2da7a198c28dd1a6e1136f19c830beab7fdca5b3e5c8bba8394f8a5c45b3", size = 8528667, upload-time = "2025-12-10T07:08:27.541Z" },
+ { url = "https://files.pythonhosted.org/packages/a8/25/01c0af38fe969473fb292bba9dc2b8f9b451f3112ff242c647fee3d0dfe7/scikit_learn-1.8.0-cp314-cp314-macosx_12_0_arm64.whl", hash = "sha256:6b595b07a03069a2b1740dc08c2299993850ea81cce4fe19b2421e0c970de6b7", size = 8066524, upload-time = "2025-12-10T07:08:29.822Z" },
+ { url = "https://files.pythonhosted.org/packages/be/ce/a0623350aa0b68647333940ee46fe45086c6060ec604874e38e9ab7d8e6c/scikit_learn-1.8.0-cp314-cp314-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:29ffc74089f3d5e87dfca4c2c8450f88bdc61b0fc6ed5d267f3988f19a1309f6", size = 8657133, upload-time = "2025-12-10T07:08:31.865Z" },
+ { url = "https://files.pythonhosted.org/packages/b8/cb/861b41341d6f1245e6ca80b1c1a8c4dfce43255b03df034429089ca2a2c5/scikit_learn-1.8.0-cp314-cp314-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:fb65db5d7531bccf3a4f6bec3462223bea71384e2cda41da0f10b7c292b9e7c4", size = 8923223, upload-time = "2025-12-10T07:08:34.166Z" },
+ { url = "https://files.pythonhosted.org/packages/76/18/a8def8f91b18cd1ba6e05dbe02540168cb24d47e8dcf69e8d00b7da42a08/scikit_learn-1.8.0-cp314-cp314-win_amd64.whl", hash = "sha256:56079a99c20d230e873ea40753102102734c5953366972a71d5cb39a32bc40c6", size = 8096518, upload-time = "2025-12-10T07:08:36.339Z" },
+ { url = "https://files.pythonhosted.org/packages/d1/77/482076a678458307f0deb44e29891d6022617b2a64c840c725495bee343f/scikit_learn-1.8.0-cp314-cp314-win_arm64.whl", hash = "sha256:3bad7565bc9cf37ce19a7c0d107742b320c1285df7aab1a6e2d28780df167242", size = 7754546, upload-time = "2025-12-10T07:08:38.128Z" },
+ { url = "https://files.pythonhosted.org/packages/2d/d1/ef294ca754826daa043b2a104e59960abfab4cf653891037d19dd5b6f3cf/scikit_learn-1.8.0-cp314-cp314t-macosx_10_15_x86_64.whl", hash = "sha256:4511be56637e46c25721e83d1a9cea9614e7badc7040c4d573d75fbe257d6fd7", size = 8848305, upload-time = "2025-12-10T07:08:41.013Z" },
+ { url = "https://files.pythonhosted.org/packages/5b/e2/b1f8b05138ee813b8e1a4149f2f0d289547e60851fd1bb268886915adbda/scikit_learn-1.8.0-cp314-cp314t-macosx_12_0_arm64.whl", hash = "sha256:a69525355a641bf8ef136a7fa447672fb54fe8d60cab5538d9eb7c6438543fb9", size = 8432257, upload-time = "2025-12-10T07:08:42.873Z" },
+ { url = "https://files.pythonhosted.org/packages/26/11/c32b2138a85dcb0c99f6afd13a70a951bfdff8a6ab42d8160522542fb647/scikit_learn-1.8.0-cp314-cp314t-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:c2656924ec73e5939c76ac4c8b026fc203b83d8900362eb2599d8aee80e4880f", size = 8678673, upload-time = "2025-12-10T07:08:45.362Z" },
+ { url = "https://files.pythonhosted.org/packages/c7/57/51f2384575bdec454f4fe4e7a919d696c9ebce914590abf3e52d47607ab8/scikit_learn-1.8.0-cp314-cp314t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:15fc3b5d19cc2be65404786857f2e13c70c83dd4782676dd6814e3b89dc8f5b9", size = 8922467, upload-time = "2025-12-10T07:08:47.408Z" },
+ { url = "https://files.pythonhosted.org/packages/35/4d/748c9e2872637a57981a04adc038dacaa16ba8ca887b23e34953f0b3f742/scikit_learn-1.8.0-cp314-cp314t-win_amd64.whl", hash = "sha256:00d6f1d66fbcf4eba6e356e1420d33cc06c70a45bb1363cd6f6a8e4ebbbdece2", size = 8774395, upload-time = "2025-12-10T07:08:49.337Z" },
+ { url = "https://files.pythonhosted.org/packages/60/22/d7b2ebe4704a5e50790ba089d5c2ae308ab6bb852719e6c3bd4f04c3a363/scikit_learn-1.8.0-cp314-cp314t-win_arm64.whl", hash = "sha256:f28dd15c6bb0b66ba09728cf09fd8736c304be29409bd8445a080c1280619e8c", size = 8002647, upload-time = "2025-12-10T07:08:51.601Z" },
]
[[package]]
@@ -1735,6 +2004,26 @@ wheels = [
{ url = "https://files.pythonhosted.org/packages/ab/f2/b31d75cb9b5fa4dd39a0a931ee9b33e7f6f36f23be5ef560bf72e0f92f32/scipy-1.16.3-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:e7efa2681ea410b10dde31a52b18b0154d66f2485328830e45fdf183af5aefc6", size = 38796678, upload-time = "2025-10-28T17:35:26.354Z" },
{ url = "https://files.pythonhosted.org/packages/b4/1e/b3723d8ff64ab548c38d87055483714fefe6ee20e0189b62352b5e015bb1/scipy-1.16.3-cp313-cp313t-win_amd64.whl", hash = "sha256:2d1ae2cf0c350e7705168ff2429962a89ad90c2d49d1dd300686d8b2a5af22fc", size = 38640178, upload-time = "2025-10-28T17:35:35.304Z" },
{ url = "https://files.pythonhosted.org/packages/8e/f3/d854ff38789aca9b0cc23008d607ced9de4f7ab14fa1ca4329f86b3758ca/scipy-1.16.3-cp313-cp313t-win_arm64.whl", hash = "sha256:0c623a54f7b79dd88ef56da19bc2873afec9673a48f3b85b18e4d402bdd29a5a", size = 25803246, upload-time = "2025-10-28T17:35:42.155Z" },
+ { url = "https://files.pythonhosted.org/packages/99/f6/99b10fd70f2d864c1e29a28bbcaa0c6340f9d8518396542d9ea3b4aaae15/scipy-1.16.3-cp314-cp314-macosx_10_14_x86_64.whl", hash = "sha256:875555ce62743e1d54f06cdf22c1e0bc47b91130ac40fe5d783b6dfa114beeb6", size = 36606469, upload-time = "2025-10-28T17:36:08.741Z" },
+ { url = "https://files.pythonhosted.org/packages/4d/74/043b54f2319f48ea940dd025779fa28ee360e6b95acb7cd188fad4391c6b/scipy-1.16.3-cp314-cp314-macosx_12_0_arm64.whl", hash = "sha256:bb61878c18a470021fb515a843dc7a76961a8daceaaaa8bad1332f1bf4b54657", size = 28872043, upload-time = "2025-10-28T17:36:16.599Z" },
+ { url = "https://files.pythonhosted.org/packages/4d/e1/24b7e50cc1c4ee6ffbcb1f27fe9f4c8b40e7911675f6d2d20955f41c6348/scipy-1.16.3-cp314-cp314-macosx_14_0_arm64.whl", hash = "sha256:f2622206f5559784fa5c4b53a950c3c7c1cf3e84ca1b9c4b6c03f062f289ca26", size = 20862952, upload-time = "2025-10-28T17:36:22.966Z" },
+ { url = "https://files.pythonhosted.org/packages/dd/3a/3e8c01a4d742b730df368e063787c6808597ccb38636ed821d10b39ca51b/scipy-1.16.3-cp314-cp314-macosx_14_0_x86_64.whl", hash = "sha256:7f68154688c515cdb541a31ef8eb66d8cd1050605be9dcd74199cbd22ac739bc", size = 23508512, upload-time = "2025-10-28T17:36:29.731Z" },
+ { url = "https://files.pythonhosted.org/packages/1f/60/c45a12b98ad591536bfe5330cb3cfe1850d7570259303563b1721564d458/scipy-1.16.3-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:8b3c820ddb80029fe9f43d61b81d8b488d3ef8ca010d15122b152db77dc94c22", size = 33413639, upload-time = "2025-10-28T17:36:37.982Z" },
+ { url = "https://files.pythonhosted.org/packages/71/bc/35957d88645476307e4839712642896689df442f3e53b0fa016ecf8a3357/scipy-1.16.3-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:d3837938ae715fc0fe3c39c0202de3a8853aff22ca66781ddc2ade7554b7e2cc", size = 35704729, upload-time = "2025-10-28T17:36:46.547Z" },
+ { url = "https://files.pythonhosted.org/packages/3b/15/89105e659041b1ca11c386e9995aefacd513a78493656e57789f9d9eab61/scipy-1.16.3-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:aadd23f98f9cb069b3bd64ddc900c4d277778242e961751f77a8cb5c4b946fb0", size = 36086251, upload-time = "2025-10-28T17:36:55.161Z" },
+ { url = "https://files.pythonhosted.org/packages/1a/87/c0ea673ac9c6cc50b3da2196d860273bc7389aa69b64efa8493bdd25b093/scipy-1.16.3-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:b7c5f1bda1354d6a19bc6af73a649f8285ca63ac6b52e64e658a5a11d4d69800", size = 38716681, upload-time = "2025-10-28T17:37:04.1Z" },
+ { url = "https://files.pythonhosted.org/packages/91/06/837893227b043fb9b0d13e4bd7586982d8136cb249ffb3492930dab905b8/scipy-1.16.3-cp314-cp314-win_amd64.whl", hash = "sha256:e5d42a9472e7579e473879a1990327830493a7047506d58d73fc429b84c1d49d", size = 39358423, upload-time = "2025-10-28T17:38:20.005Z" },
+ { url = "https://files.pythonhosted.org/packages/95/03/28bce0355e4d34a7c034727505a02d19548549e190bedd13a721e35380b7/scipy-1.16.3-cp314-cp314-win_arm64.whl", hash = "sha256:6020470b9d00245926f2d5bb93b119ca0340f0d564eb6fbaad843eaebf9d690f", size = 26135027, upload-time = "2025-10-28T17:38:24.966Z" },
+ { url = "https://files.pythonhosted.org/packages/b2/6f/69f1e2b682efe9de8fe9f91040f0cd32f13cfccba690512ba4c582b0bc29/scipy-1.16.3-cp314-cp314t-macosx_10_14_x86_64.whl", hash = "sha256:e1d27cbcb4602680a49d787d90664fa4974063ac9d4134813332a8c53dbe667c", size = 37028379, upload-time = "2025-10-28T17:37:14.061Z" },
+ { url = "https://files.pythonhosted.org/packages/7c/2d/e826f31624a5ebbab1cd93d30fd74349914753076ed0593e1d56a98c4fb4/scipy-1.16.3-cp314-cp314t-macosx_12_0_arm64.whl", hash = "sha256:9b9c9c07b6d56a35777a1b4cc8966118fb16cfd8daf6743867d17d36cfad2d40", size = 29400052, upload-time = "2025-10-28T17:37:21.709Z" },
+ { url = "https://files.pythonhosted.org/packages/69/27/d24feb80155f41fd1f156bf144e7e049b4e2b9dd06261a242905e3bc7a03/scipy-1.16.3-cp314-cp314t-macosx_14_0_arm64.whl", hash = "sha256:3a4c460301fb2cffb7f88528f30b3127742cff583603aa7dc964a52c463b385d", size = 21391183, upload-time = "2025-10-28T17:37:29.559Z" },
+ { url = "https://files.pythonhosted.org/packages/f8/d3/1b229e433074c5738a24277eca520a2319aac7465eea7310ea6ae0e98ae2/scipy-1.16.3-cp314-cp314t-macosx_14_0_x86_64.whl", hash = "sha256:f667a4542cc8917af1db06366d3f78a5c8e83badd56409f94d1eac8d8d9133fa", size = 23930174, upload-time = "2025-10-28T17:37:36.306Z" },
+ { url = "https://files.pythonhosted.org/packages/16/9d/d9e148b0ec680c0f042581a2be79a28a7ab66c0c4946697f9e7553ead337/scipy-1.16.3-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:f379b54b77a597aa7ee5e697df0d66903e41b9c85a6dd7946159e356319158e8", size = 33497852, upload-time = "2025-10-28T17:37:42.228Z" },
+ { url = "https://files.pythonhosted.org/packages/2f/22/4e5f7561e4f98b7bea63cf3fd7934bff1e3182e9f1626b089a679914d5c8/scipy-1.16.3-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:4aff59800a3b7f786b70bfd6ab551001cb553244988d7d6b8299cb1ea653b353", size = 35798595, upload-time = "2025-10-28T17:37:48.102Z" },
+ { url = "https://files.pythonhosted.org/packages/83/42/6644d714c179429fc7196857866f219fef25238319b650bb32dde7bf7a48/scipy-1.16.3-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:da7763f55885045036fabcebd80144b757d3db06ab0861415d1c3b7c69042146", size = 36186269, upload-time = "2025-10-28T17:37:53.72Z" },
+ { url = "https://files.pythonhosted.org/packages/ac/70/64b4d7ca92f9cf2e6fc6aaa2eecf80bb9b6b985043a9583f32f8177ea122/scipy-1.16.3-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:ffa6eea95283b2b8079b821dc11f50a17d0571c92b43e2b5b12764dc5f9b285d", size = 38802779, upload-time = "2025-10-28T17:37:59.393Z" },
+ { url = "https://files.pythonhosted.org/packages/61/82/8d0e39f62764cce5ffd5284131e109f07cf8955aef9ab8ed4e3aa5e30539/scipy-1.16.3-cp314-cp314t-win_amd64.whl", hash = "sha256:d9f48cafc7ce94cf9b15c6bffdc443a81a27bf7075cf2dcd5c8b40f85d10c4e7", size = 39471128, upload-time = "2025-10-28T17:38:05.259Z" },
+ { url = "https://files.pythonhosted.org/packages/64/47/a494741db7280eae6dc033510c319e34d42dd41b7ac0c7ead39354d1a2b5/scipy-1.16.3-cp314-cp314t-win_arm64.whl", hash = "sha256:21d9d6b197227a12dcbf9633320a4e34c6b0e51c57268df255a0942983bac562", size = 26464127, upload-time = "2025-10-28T17:38:11.34Z" },
]
[[package]]
@@ -2088,6 +2377,14 @@ wheels = [
{ url = "https://files.pythonhosted.org/packages/f4/dd/f1c0d879f2863ef209e18823a988dc7a1bf40470750e3ebe927efdb9407f/torch-2.9.1-cp313-cp313t-manylinux_2_28_x86_64.whl", hash = "sha256:8301a7b431e51764629208d0edaa4f9e4c33e6df0f2f90b90e261d623df6a4e2", size = 899748978, upload-time = "2025-11-12T15:23:04.568Z" },
{ url = "https://files.pythonhosted.org/packages/1f/9f/6986b83a53b4d043e36f3f898b798ab51f7f20fdf1a9b01a2720f445043d/torch-2.9.1-cp313-cp313t-win_amd64.whl", hash = "sha256:2e1c42c0ae92bf803a4b2409fdfed85e30f9027a66887f5e7dcdbc014c7531db", size = 111176995, upload-time = "2025-11-12T15:22:01.618Z" },
{ url = "https://files.pythonhosted.org/packages/40/60/71c698b466dd01e65d0e9514b5405faae200c52a76901baf6906856f17e4/torch-2.9.1-cp313-none-macosx_11_0_arm64.whl", hash = "sha256:2c14b3da5df416cf9cb5efab83aa3056f5b8cd8620b8fde81b4987ecab730587", size = 74480347, upload-time = "2025-11-12T15:21:57.648Z" },
+ { url = "https://files.pythonhosted.org/packages/48/50/c4b5112546d0d13cc9eaa1c732b823d676a9f49ae8b6f97772f795874a03/torch-2.9.1-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:1edee27a7c9897f4e0b7c14cfc2f3008c571921134522d5b9b5ec4ebbc69041a", size = 74433245, upload-time = "2025-11-12T15:22:39.027Z" },
+ { url = "https://files.pythonhosted.org/packages/81/c9/2628f408f0518b3bae49c95f5af3728b6ab498c8624ab1e03a43dd53d650/torch-2.9.1-cp314-cp314-manylinux_2_28_aarch64.whl", hash = "sha256:19d144d6b3e29921f1fc70503e9f2fc572cde6a5115c0c0de2f7ca8b1483e8b6", size = 104134804, upload-time = "2025-11-12T15:22:35.222Z" },
+ { url = "https://files.pythonhosted.org/packages/28/fc/5bc91d6d831ae41bf6e9e6da6468f25330522e92347c9156eb3f1cb95956/torch-2.9.1-cp314-cp314-manylinux_2_28_x86_64.whl", hash = "sha256:c432d04376f6d9767a9852ea0def7b47a7bbc8e7af3b16ac9cf9ce02b12851c9", size = 899747132, upload-time = "2025-11-12T15:23:36.068Z" },
+ { url = "https://files.pythonhosted.org/packages/63/5d/e8d4e009e52b6b2cf1684bde2a6be157b96fb873732542fb2a9a99e85a83/torch-2.9.1-cp314-cp314-win_amd64.whl", hash = "sha256:d187566a2cdc726fc80138c3cdb260970fab1c27e99f85452721f7759bbd554d", size = 110934845, upload-time = "2025-11-12T15:22:48.367Z" },
+ { url = "https://files.pythonhosted.org/packages/bd/b2/2d15a52516b2ea3f414643b8de68fa4cb220d3877ac8b1028c83dc8ca1c4/torch-2.9.1-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:cb10896a1f7fedaddbccc2017ce6ca9ecaaf990f0973bdfcf405439750118d2c", size = 74823558, upload-time = "2025-11-12T15:22:43.392Z" },
+ { url = "https://files.pythonhosted.org/packages/86/5c/5b2e5d84f5b9850cd1e71af07524d8cbb74cba19379800f1f9f7c997fc70/torch-2.9.1-cp314-cp314t-manylinux_2_28_aarch64.whl", hash = "sha256:0a2bd769944991c74acf0c4ef23603b9c777fdf7637f115605a4b2d8023110c7", size = 104145788, upload-time = "2025-11-12T15:23:52.109Z" },
+ { url = "https://files.pythonhosted.org/packages/a9/8c/3da60787bcf70add986c4ad485993026ac0ca74f2fc21410bc4eb1bb7695/torch-2.9.1-cp314-cp314t-manylinux_2_28_x86_64.whl", hash = "sha256:07c8a9660bc9414c39cac530ac83b1fb1b679d7155824144a40a54f4a47bfa73", size = 899735500, upload-time = "2025-11-12T15:24:08.788Z" },
+ { url = "https://files.pythonhosted.org/packages/db/2b/f7818f6ec88758dfd21da46b6cd46af9d1b3433e53ddbb19ad1e0da17f9b/torch-2.9.1-cp314-cp314t-win_amd64.whl", hash = "sha256:c88d3299ddeb2b35dcc31753305612db485ab6f1823e37fb29451c8b2732b87e", size = 111163659, upload-time = "2025-11-12T15:23:20.009Z" },
]
[[package]]
@@ -2151,6 +2448,8 @@ wheels = [
{ url = "https://files.pythonhosted.org/packages/f2/50/9a8358d3ef58162c0a415d173cfb45b67de60176e1024f71fbc4d24c0b6d/triton-3.5.1-cp312-cp312-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:d2c6b915a03888ab931a9fd3e55ba36785e1fe70cbea0b40c6ef93b20fc85232", size = 170470207, upload-time = "2025-11-11T17:41:00.253Z" },
{ url = "https://files.pythonhosted.org/packages/27/46/8c3bbb5b0a19313f50edcaa363b599e5a1a5ac9683ead82b9b80fe497c8d/triton-3.5.1-cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:f3f4346b6ebbd4fad18773f5ba839114f4826037c9f2f34e0148894cd5dd3dba", size = 170470410, upload-time = "2025-11-11T17:41:06.319Z" },
{ url = "https://files.pythonhosted.org/packages/37/92/e97fcc6b2c27cdb87ce5ee063d77f8f26f19f06916aa680464c8104ef0f6/triton-3.5.1-cp313-cp313t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:0b4d2c70127fca6a23e247f9348b8adde979d2e7a20391bfbabaac6aebc7e6a8", size = 170579924, upload-time = "2025-11-11T17:41:12.455Z" },
+ { url = "https://files.pythonhosted.org/packages/a4/e6/c595c35e5c50c4bc56a7bac96493dad321e9e29b953b526bbbe20f9911d0/triton-3.5.1-cp314-cp314-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:d0637b1efb1db599a8e9dc960d53ab6e4637db7d4ab6630a0974705d77b14b60", size = 170480488, upload-time = "2025-11-11T17:41:18.222Z" },
+ { url = "https://files.pythonhosted.org/packages/16/b5/b0d3d8b901b6a04ca38df5e24c27e53afb15b93624d7fd7d658c7cd9352a/triton-3.5.1-cp314-cp314t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:bac7f7d959ad0f48c0e97d6643a1cc0fd5786fe61cb1f83b537c6b2d54776478", size = 170582192, upload-time = "2025-11-11T17:41:23.963Z" },
]
[[package]]