mirror of
https://github.com/qdrant/landing_page.git
synced 2026-10-08 20:38:31 +02:00
Test Edge code snippets (#2179)
* Add Edge and FastEmbed as Python dependencies * Make Edge code snippets testable
This commit is contained in:
@@ -4,7 +4,9 @@ version = "0.1.0"
|
|||||||
requires-python = ">=3.12"
|
requires-python = ">=3.12"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"datasets>=4.4.1",
|
"datasets>=4.4.1",
|
||||||
|
"fastembed",
|
||||||
"qdrant-client",
|
"qdrant-client",
|
||||||
|
"qdrant-edge-py"
|
||||||
]
|
]
|
||||||
|
|
||||||
[tool.uv.sources]
|
[tool.uv.sources]
|
||||||
@@ -16,5 +18,5 @@ dev = [
|
|||||||
]
|
]
|
||||||
|
|
||||||
[[tool.mypy.overrides]]
|
[[tool.mypy.overrides]]
|
||||||
module = ["datasets"]
|
module = ["datasets", "qdrant_edge"]
|
||||||
ignore_missing_imports = true
|
ignore_missing_imports = true
|
||||||
|
|||||||
+324
@@ -267,6 +267,27 @@ wheels = [
|
|||||||
{ url = "https://files.pythonhosted.org/packages/50/3d/9373ad9c56321fdab5b41197068e1d8c25883b3fea29dd361f9b55116869/dill-0.4.0-py3-none-any.whl", hash = "sha256:44f54bf6412c2c8464c14e8243eb163690a9800dbe2c367330883b19c7561049", size = 119668, upload-time = "2025-04-16T00:41:47.671Z" },
|
{ url = "https://files.pythonhosted.org/packages/50/3d/9373ad9c56321fdab5b41197068e1d8c25883b3fea29dd361f9b55116869/dill-0.4.0-py3-none-any.whl", hash = "sha256:44f54bf6412c2c8464c14e8243eb163690a9800dbe2c367330883b19c7561049", size = 119668, upload-time = "2025-04-16T00:41:47.671Z" },
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "fastembed"
|
||||||
|
version = "0.7.4"
|
||||||
|
source = { registry = "https://pypi.org/simple" }
|
||||||
|
dependencies = [
|
||||||
|
{ name = "huggingface-hub" },
|
||||||
|
{ name = "loguru" },
|
||||||
|
{ name = "mmh3" },
|
||||||
|
{ name = "numpy" },
|
||||||
|
{ name = "onnxruntime" },
|
||||||
|
{ name = "pillow" },
|
||||||
|
{ name = "py-rust-stemmers" },
|
||||||
|
{ name = "requests" },
|
||||||
|
{ name = "tokenizers" },
|
||||||
|
{ name = "tqdm" },
|
||||||
|
]
|
||||||
|
sdist = { url = "https://files.pythonhosted.org/packages/4c/c2/9c708680de1b54480161e0505f9d6d3d8eb47a1dc1a1f7f3c5106ba355d2/fastembed-0.7.4.tar.gz", hash = "sha256:8b8a4ea860ca295002f4754e8f5820a636e1065a9444959e18d5988d7f27093b", size = 68807, upload-time = "2025-12-05T12:08:10.447Z" }
|
||||||
|
wheels = [
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/10/3b/8da01492bc8b69184257d0c951bf0e77aec8ce110f06d8ce16c6ed9084f7/fastembed-0.7.4-py3-none-any.whl", hash = "sha256:79250a775f70bd6addb0e054204df042b5029ecae501e40e5bbd08e75844ad83", size = 108491, upload-time = "2025-12-05T12:08:09.059Z" },
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "filelock"
|
name = "filelock"
|
||||||
version = "3.20.0"
|
version = "3.20.0"
|
||||||
@@ -276,6 +297,14 @@ wheels = [
|
|||||||
{ url = "https://files.pythonhosted.org/packages/76/91/7216b27286936c16f5b4d0c530087e4a54eead683e6b0b73dd0c64844af6/filelock-3.20.0-py3-none-any.whl", hash = "sha256:339b4732ffda5cd79b13f4e2711a31b0365ce445d95d243bb996273d072546a2", size = 16054, upload-time = "2025-10-08T18:03:48.35Z" },
|
{ url = "https://files.pythonhosted.org/packages/76/91/7216b27286936c16f5b4d0c530087e4a54eead683e6b0b73dd0c64844af6/filelock-3.20.0-py3-none-any.whl", hash = "sha256:339b4732ffda5cd79b13f4e2711a31b0365ce445d95d243bb996273d072546a2", size = 16054, upload-time = "2025-10-08T18:03:48.35Z" },
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "flatbuffers"
|
||||||
|
version = "25.12.19"
|
||||||
|
source = { registry = "https://pypi.org/simple" }
|
||||||
|
wheels = [
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/e8/2d/d2a548598be01649e2d46231d151a6c56d10b964d94043a335ae56ea2d92/flatbuffers-25.12.19-py2.py3-none-any.whl", hash = "sha256:7634f50c427838bb021c2d66a3d1168e9d199b0607e6329399f04846d42e20b4", size = 26661, upload-time = "2025-12-19T23:16:13.622Z" },
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "frozenlist"
|
name = "frozenlist"
|
||||||
version = "1.8.0"
|
version = "1.8.0"
|
||||||
@@ -552,6 +581,108 @@ wheels = [
|
|||||||
{ url = "https://files.pythonhosted.org/packages/0e/61/66938bbb5fc52dbdf84594873d5b51fb1f7c7794e9c0f5bd885f30bc507b/idna-3.11-py3-none-any.whl", hash = "sha256:771a87f49d9defaf64091e6e6fe9c18d4833f140bd19464795bc32d966ca37ea", size = 71008, upload-time = "2025-10-12T14:55:18.883Z" },
|
{ url = "https://files.pythonhosted.org/packages/0e/61/66938bbb5fc52dbdf84594873d5b51fb1f7c7794e9c0f5bd885f30bc507b/idna-3.11-py3-none-any.whl", hash = "sha256:771a87f49d9defaf64091e6e6fe9c18d4833f140bd19464795bc32d966ca37ea", size = 71008, upload-time = "2025-10-12T14:55:18.883Z" },
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "loguru"
|
||||||
|
version = "0.7.3"
|
||||||
|
source = { registry = "https://pypi.org/simple" }
|
||||||
|
dependencies = [
|
||||||
|
{ name = "colorama", marker = "sys_platform == 'win32'" },
|
||||||
|
{ name = "win32-setctime", marker = "sys_platform == 'win32'" },
|
||||||
|
]
|
||||||
|
sdist = { url = "https://files.pythonhosted.org/packages/3a/05/a1dae3dffd1116099471c643b8924f5aa6524411dc6c63fdae648c4f1aca/loguru-0.7.3.tar.gz", hash = "sha256:19480589e77d47b8d85b2c827ad95d49bf31b0dcde16593892eb51dd18706eb6", size = 63559, upload-time = "2024-12-06T11:20:56.608Z" }
|
||||||
|
wheels = [
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/0c/29/0348de65b8cc732daa3e33e67806420b2ae89bdce2b04af740289c5c6c8c/loguru-0.7.3-py3-none-any.whl", hash = "sha256:31a33c10c8e1e10422bfd431aeb5d351c7cf7fa671e3c4df004162264b28220c", size = 61595, upload-time = "2024-12-06T11:20:54.538Z" },
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "mmh3"
|
||||||
|
version = "5.2.0"
|
||||||
|
source = { registry = "https://pypi.org/simple" }
|
||||||
|
sdist = { url = "https://files.pythonhosted.org/packages/a7/af/f28c2c2f51f31abb4725f9a64bc7863d5f491f6539bd26aee2a1d21a649e/mmh3-5.2.0.tar.gz", hash = "sha256:1efc8fec8478e9243a78bb993422cf79f8ff85cb4cf6b79647480a31e0d950a8", size = 33582, upload-time = "2025-07-29T07:43:48.49Z" }
|
||||||
|
wheels = [
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/bf/6a/d5aa7edb5c08e0bd24286c7d08341a0446f9a2fbbb97d96a8a6dd81935ee/mmh3-5.2.0-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:384eda9361a7bf83a85e09447e1feafe081034af9dd428893701b959230d84be", size = 56141, upload-time = "2025-07-29T07:42:13.456Z" },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/08/49/131d0fae6447bc4a7299ebdb1a6fb9d08c9f8dcf97d75ea93e8152ddf7ab/mmh3-5.2.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:2c9da0d568569cc87315cb063486d761e38458b8ad513fedd3dc9263e1b81bcd", size = 40681, upload-time = "2025-07-29T07:42:14.306Z" },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/8f/6f/9221445a6bcc962b7f5ff3ba18ad55bba624bacdc7aa3fc0a518db7da8ec/mmh3-5.2.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:86d1be5d63232e6eb93c50881aea55ff06eb86d8e08f9b5417c8c9b10db9db96", size = 40062, upload-time = "2025-07-29T07:42:15.08Z" },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/1e/d4/6bb2d0fef81401e0bb4c297d1eb568b767de4ce6fc00890bc14d7b51ecc4/mmh3-5.2.0-cp312-cp312-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:bf7bee43e17e81671c447e9c83499f53d99bf440bc6d9dc26a841e21acfbe094", size = 97333, upload-time = "2025-07-29T07:42:16.436Z" },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/44/e0/ccf0daff8134efbb4fbc10a945ab53302e358c4b016ada9bf97a6bdd50c1/mmh3-5.2.0-cp312-cp312-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:7aa18cdb58983ee660c9c400b46272e14fa253c675ed963d3812487f8ca42037", size = 103310, upload-time = "2025-07-29T07:42:17.796Z" },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/02/63/1965cb08a46533faca0e420e06aff8bbaf9690a6f0ac6ae6e5b2e4544687/mmh3-5.2.0-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:ae9d032488fcec32d22be6542d1a836f00247f40f320844dbb361393b5b22773", size = 106178, upload-time = "2025-07-29T07:42:19.281Z" },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/c2/41/c883ad8e2c234013f27f92061200afc11554ea55edd1bcf5e1accd803a85/mmh3-5.2.0-cp312-cp312-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:e1861fb6b1d0453ed7293200139c0a9011eeb1376632e048e3766945b13313c5", size = 113035, upload-time = "2025-07-29T07:42:20.356Z" },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/df/b5/1ccade8b1fa625d634a18bab7bf08a87457e09d5ec8cf83ca07cbea9d400/mmh3-5.2.0-cp312-cp312-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:99bb6a4d809aa4e528ddfe2c85dd5239b78b9dd14be62cca0329db78505e7b50", size = 120784, upload-time = "2025-07-29T07:42:21.377Z" },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/77/1c/919d9171fcbdcdab242e06394464ccf546f7d0f3b31e0d1e3a630398782e/mmh3-5.2.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:1f8d8b627799f4e2fcc7c034fed8f5f24dc7724ff52f69838a3d6d15f1ad4765", size = 99137, upload-time = "2025-07-29T07:42:22.344Z" },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/66/8a/1eebef5bd6633d36281d9fc83cf2e9ba1ba0e1a77dff92aacab83001cee4/mmh3-5.2.0-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:b5995088dd7023d2d9f310a0c67de5a2b2e06a570ecfd00f9ff4ab94a67cde43", size = 98664, upload-time = "2025-07-29T07:42:23.269Z" },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/13/41/a5d981563e2ee682b21fb65e29cc0f517a6734a02b581359edd67f9d0360/mmh3-5.2.0-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:1a5f4d2e59d6bba8ef01b013c472741835ad961e7c28f50c82b27c57748744a4", size = 106459, upload-time = "2025-07-29T07:42:24.238Z" },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/24/31/342494cd6ab792d81e083680875a2c50fa0c5df475ebf0b67784f13e4647/mmh3-5.2.0-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:fd6e6c3d90660d085f7e73710eab6f5545d4854b81b0135a3526e797009dbda3", size = 110038, upload-time = "2025-07-29T07:42:25.629Z" },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/28/44/efda282170a46bb4f19c3e2b90536513b1d821c414c28469a227ca5a1789/mmh3-5.2.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:c4a2f3d83879e3de2eb8cbf562e71563a8ed15ee9b9c2e77ca5d9f73072ac15c", size = 97545, upload-time = "2025-07-29T07:42:27.04Z" },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/68/8f/534ae319c6e05d714f437e7206f78c17e66daca88164dff70286b0e8ea0c/mmh3-5.2.0-cp312-cp312-win32.whl", hash = "sha256:2421b9d665a0b1ad724ec7332fb5a98d075f50bc51a6ff854f3a1882bd650d49", size = 40805, upload-time = "2025-07-29T07:42:28.032Z" },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/b8/f6/f6abdcfefcedab3c964868048cfe472764ed358c2bf6819a70dd4ed4ed3a/mmh3-5.2.0-cp312-cp312-win_amd64.whl", hash = "sha256:72d80005b7634a3a2220f81fbeb94775ebd12794623bb2e1451701ea732b4aa3", size = 41597, upload-time = "2025-07-29T07:42:28.894Z" },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/15/fd/f7420e8cbce45c259c770cac5718badf907b302d3a99ec587ba5ce030237/mmh3-5.2.0-cp312-cp312-win_arm64.whl", hash = "sha256:3d6bfd9662a20c054bc216f861fa330c2dac7c81e7fb8307b5e32ab5b9b4d2e0", size = 39350, upload-time = "2025-07-29T07:42:29.794Z" },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/d8/fa/27f6ab93995ef6ad9f940e96593c5dd24744d61a7389532b0fec03745607/mmh3-5.2.0-cp313-cp313-android_21_arm64_v8a.whl", hash = "sha256:e79c00eba78f7258e5b354eccd4d7907d60317ced924ea4a5f2e9d83f5453065", size = 40874, upload-time = "2025-07-29T07:42:30.662Z" },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/11/9c/03d13bcb6a03438bc8cac3d2e50f80908d159b31a4367c2e1a7a077ded32/mmh3-5.2.0-cp313-cp313-android_21_x86_64.whl", hash = "sha256:956127e663d05edbeec54df38885d943dfa27406594c411139690485128525de", size = 42012, upload-time = "2025-07-29T07:42:31.539Z" },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/4e/78/0865d9765408a7d504f1789944e678f74e0888b96a766d578cb80b040999/mmh3-5.2.0-cp313-cp313-ios_13_0_arm64_iphoneos.whl", hash = "sha256:c3dca4cb5b946ee91b3d6bb700d137b1cd85c20827f89fdf9c16258253489044", size = 39197, upload-time = "2025-07-29T07:42:32.374Z" },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/3e/12/76c3207bd186f98b908b6706c2317abb73756d23a4e68ea2bc94825b9015/mmh3-5.2.0-cp313-cp313-ios_13_0_arm64_iphonesimulator.whl", hash = "sha256:e651e17bfde5840e9e4174b01e9e080ce49277b70d424308b36a7969d0d1af73", size = 39840, upload-time = "2025-07-29T07:42:33.227Z" },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/5d/0d/574b6cce5555c9f2b31ea189ad44986755eb14e8862db28c8b834b8b64dc/mmh3-5.2.0-cp313-cp313-ios_13_0_x86_64_iphonesimulator.whl", hash = "sha256:9f64bf06f4bf623325fda3a6d02d36cd69199b9ace99b04bb2d7fd9f89688504", size = 40644, upload-time = "2025-07-29T07:42:34.099Z" },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/52/82/3731f8640b79c46707f53ed72034a58baad400be908c87b0088f1f89f986/mmh3-5.2.0-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:ddc63328889bcaee77b743309e5c7d2d52cee0d7d577837c91b6e7cc9e755e0b", size = 56153, upload-time = "2025-07-29T07:42:35.031Z" },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/4f/34/e02dca1d4727fd9fdeaff9e2ad6983e1552804ce1d92cc796e5b052159bb/mmh3-5.2.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:bb0fdc451fb6d86d81ab8f23d881b8d6e37fc373a2deae1c02d27002d2ad7a05", size = 40684, upload-time = "2025-07-29T07:42:35.914Z" },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/8f/36/3dee40767356e104967e6ed6d102ba47b0b1ce2a89432239b95a94de1b89/mmh3-5.2.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:b29044e1ffdb84fe164d0a7ea05c7316afea93c00f8ed9449cf357c36fc4f814", size = 40057, upload-time = "2025-07-29T07:42:36.755Z" },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/31/58/228c402fccf76eb39a0a01b8fc470fecf21965584e66453b477050ee0e99/mmh3-5.2.0-cp313-cp313-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:58981d6ea9646dbbf9e59a30890cbf9f610df0e4a57dbfe09215116fd90b0093", size = 97344, upload-time = "2025-07-29T07:42:37.675Z" },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/34/82/fc5ce89006389a6426ef28e326fc065b0fbaaed230373b62d14c889f47ea/mmh3-5.2.0-cp313-cp313-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:7e5634565367b6d98dc4aa2983703526ef556b3688ba3065edb4b9b90ede1c54", size = 103325, upload-time = "2025-07-29T07:42:38.591Z" },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/09/8c/261e85777c6aee1ebd53f2f17e210e7481d5b0846cd0b4a5c45f1e3761b8/mmh3-5.2.0-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:b0271ac12415afd3171ab9a3c7cbfc71dee2c68760a7dc9d05bf8ed6ddfa3a7a", size = 106240, upload-time = "2025-07-29T07:42:39.563Z" },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/70/73/2f76b3ad8a3d431824e9934403df36c0ddacc7831acf82114bce3c4309c8/mmh3-5.2.0-cp313-cp313-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:45b590e31bc552c6f8e2150ff1ad0c28dd151e9f87589e7eaf508fbdd8e8e908", size = 113060, upload-time = "2025-07-29T07:42:40.585Z" },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/9f/b9/7ea61a34e90e50a79a9d87aa1c0b8139a7eaf4125782b34b7d7383472633/mmh3-5.2.0-cp313-cp313-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:bdde97310d59604f2a9119322f61b31546748499a21b44f6715e8ced9308a6c5", size = 120781, upload-time = "2025-07-29T07:42:41.618Z" },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/0f/5b/ae1a717db98c7894a37aeedbd94b3f99e6472a836488f36b6849d003485b/mmh3-5.2.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:fc9c5f280438cf1c1a8f9abb87dc8ce9630a964120cfb5dd50d1e7ce79690c7a", size = 99174, upload-time = "2025-07-29T07:42:42.587Z" },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/e3/de/000cce1d799fceebb6d4487ae29175dd8e81b48e314cba7b4da90bcf55d7/mmh3-5.2.0-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:c903e71fd8debb35ad2a4184c1316b3cb22f64ce517b4e6747f25b0a34e41266", size = 98734, upload-time = "2025-07-29T07:42:43.996Z" },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/79/19/0dc364391a792b72fbb22becfdeacc5add85cc043cd16986e82152141883/mmh3-5.2.0-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:eed4bba7ff8a0d37106ba931ab03bdd3915fbb025bcf4e1f0aa02bc8114960c5", size = 106493, upload-time = "2025-07-29T07:42:45.07Z" },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/3c/b1/bc8c28e4d6e807bbb051fefe78e1156d7f104b89948742ad310612ce240d/mmh3-5.2.0-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:1fdb36b940e9261aff0b5177c5b74a36936b902f473180f6c15bde26143681a9", size = 110089, upload-time = "2025-07-29T07:42:46.122Z" },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/3b/a2/d20f3f5c95e9c511806686c70d0a15479cc3941c5f322061697af1c1ff70/mmh3-5.2.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:7303aab41e97adcf010a09efd8f1403e719e59b7705d5e3cfed3dd7571589290", size = 97571, upload-time = "2025-07-29T07:42:47.18Z" },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/7b/23/665296fce4f33488deec39a750ffd245cfc07aafb0e3ef37835f91775d14/mmh3-5.2.0-cp313-cp313-win32.whl", hash = "sha256:03e08c6ebaf666ec1e3d6ea657a2d363bb01effd1a9acfe41f9197decaef0051", size = 40806, upload-time = "2025-07-29T07:42:48.166Z" },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/59/b0/92e7103f3b20646e255b699e2d0327ce53a3f250e44367a99dc8be0b7c7a/mmh3-5.2.0-cp313-cp313-win_amd64.whl", hash = "sha256:7fddccd4113e7b736706e17a239a696332360cbaddf25ae75b57ba1acce65081", size = 41600, upload-time = "2025-07-29T07:42:49.371Z" },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/99/22/0b2bd679a84574647de538c5b07ccaa435dbccc37815067fe15b90fe8dad/mmh3-5.2.0-cp313-cp313-win_arm64.whl", hash = "sha256:fa0c966ee727aad5406d516375593c5f058c766b21236ab8985693934bb5085b", size = 39349, upload-time = "2025-07-29T07:42:50.268Z" },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/f7/ca/a20db059a8a47048aaf550da14a145b56e9c7386fb8280d3ce2962dcebf7/mmh3-5.2.0-cp314-cp314-ios_13_0_arm64_iphoneos.whl", hash = "sha256:e5015f0bb6eb50008bed2d4b1ce0f2a294698a926111e4bb202c0987b4f89078", size = 39209, upload-time = "2025-07-29T07:42:51.559Z" },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/98/dd/e5094799d55c7482d814b979a0fd608027d0af1b274bfb4c3ea3e950bfd5/mmh3-5.2.0-cp314-cp314-ios_13_0_arm64_iphonesimulator.whl", hash = "sha256:e0f3ed828d709f5b82d8bfe14f8856120718ec4bd44a5b26102c3030a1e12501", size = 39843, upload-time = "2025-07-29T07:42:52.536Z" },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/f4/6b/7844d7f832c85400e7cc89a1348e4e1fdd38c5a38415bb5726bbb8fcdb6c/mmh3-5.2.0-cp314-cp314-ios_13_0_x86_64_iphonesimulator.whl", hash = "sha256:f35727c5118aba95f0397e18a1a5b8405425581bfe53e821f0fb444cbdc2bc9b", size = 40648, upload-time = "2025-07-29T07:42:53.392Z" },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/1f/bf/71f791f48a21ff3190ba5225807cbe4f7223360e96862c376e6e3fb7efa7/mmh3-5.2.0-cp314-cp314-macosx_10_13_universal2.whl", hash = "sha256:3bc244802ccab5220008cb712ca1508cb6a12f0eb64ad62997156410579a1770", size = 56164, upload-time = "2025-07-29T07:42:54.267Z" },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/70/1f/f87e3d34d83032b4f3f0f528c6d95a98290fcacf019da61343a49dccfd51/mmh3-5.2.0-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:ff3d50dc3fe8a98059f99b445dfb62792b5d006c5e0b8f03c6de2813b8376110", size = 40692, upload-time = "2025-07-29T07:42:55.234Z" },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/a6/e2/db849eaed07117086f3452feca8c839d30d38b830ac59fe1ce65af8be5ad/mmh3-5.2.0-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:37a358cc881fe796e099c1db6ce07ff757f088827b4e8467ac52b7a7ffdca647", size = 40068, upload-time = "2025-07-29T07:42:56.158Z" },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/df/6b/209af927207af77425b044e32f77f49105a0b05d82ff88af6971d8da4e19/mmh3-5.2.0-cp314-cp314-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:b9a87025121d1c448f24f27ff53a5fe7b6ef980574b4a4f11acaabe702420d63", size = 97367, upload-time = "2025-07-29T07:42:57.037Z" },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/ca/e0/78adf4104c425606a9ce33fb351f790c76a6c2314969c4a517d1ffc92196/mmh3-5.2.0-cp314-cp314-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:1ba55d6ca32eeef8b2625e1e4bfc3b3db52bc63014bd7e5df8cc11bf2b036b12", size = 103306, upload-time = "2025-07-29T07:42:58.522Z" },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/a3/79/c2b89f91b962658b890104745b1b6c9ce38d50a889f000b469b91eeb1b9e/mmh3-5.2.0-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:c9ff37ba9f15637e424c2ab57a1a590c52897c845b768e4e0a4958084ec87f22", size = 106312, upload-time = "2025-07-29T07:42:59.552Z" },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/4b/14/659d4095528b1a209be90934778c5ffe312177d51e365ddcbca2cac2ec7c/mmh3-5.2.0-cp314-cp314-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:a094319ec0db52a04af9fdc391b4d39a1bc72bc8424b47c4411afb05413a44b5", size = 113135, upload-time = "2025-07-29T07:43:00.745Z" },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/8d/6f/cd7734a779389a8a467b5c89a48ff476d6f2576e78216a37551a97e9e42a/mmh3-5.2.0-cp314-cp314-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:c5584061fd3da584659b13587f26c6cad25a096246a481636d64375d0c1f6c07", size = 120775, upload-time = "2025-07-29T07:43:02.124Z" },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/1d/ca/8256e3b96944408940de3f9291d7e38a283b5761fe9614d4808fcf27bd62/mmh3-5.2.0-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:ecbfc0437ddfdced5e7822d1ce4855c9c64f46819d0fdc4482c53f56c707b935", size = 99178, upload-time = "2025-07-29T07:43:03.182Z" },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/8a/32/39e2b3cf06b6e2eb042c984dab8680841ac2a0d3ca6e0bea30db1f27b565/mmh3-5.2.0-cp314-cp314-musllinux_1_2_i686.whl", hash = "sha256:7b986d506a8e8ea345791897ba5d8ba0d9d8820cd4fc3e52dbe6de19388de2e7", size = 98738, upload-time = "2025-07-29T07:43:04.207Z" },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/61/d3/7bbc8e0e8cf65ebbe1b893ffa0467b7ecd1bd07c3bbf6c9db4308ada22ec/mmh3-5.2.0-cp314-cp314-musllinux_1_2_ppc64le.whl", hash = "sha256:38d899a156549da8ef6a9f1d6f7ef231228d29f8f69bce2ee12f5fba6d6fd7c5", size = 106510, upload-time = "2025-07-29T07:43:05.656Z" },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/10/99/b97e53724b52374e2f3859046f0eb2425192da356cb19784d64bc17bb1cf/mmh3-5.2.0-cp314-cp314-musllinux_1_2_s390x.whl", hash = "sha256:d86651fa45799530885ba4dab3d21144486ed15285e8784181a0ab37a4552384", size = 110053, upload-time = "2025-07-29T07:43:07.204Z" },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/ac/62/3688c7d975ed195155671df68788c83fed6f7909b6ec4951724c6860cb97/mmh3-5.2.0-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:c463d7c1c4cfc9d751efeaadd936bbba07b5b0ed81a012b3a9f5a12f0872bd6e", size = 97546, upload-time = "2025-07-29T07:43:08.226Z" },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/ca/3b/c6153250f03f71a8b7634cded82939546cdfba02e32f124ff51d52c6f991/mmh3-5.2.0-cp314-cp314-win32.whl", hash = "sha256:bb4fe46bdc6104fbc28db7a6bacb115ee6368ff993366bbd8a2a7f0076e6f0c0", size = 41422, upload-time = "2025-07-29T07:43:09.216Z" },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/74/01/a27d98bab083a435c4c07e9d1d720d4c8a578bf4c270bae373760b1022be/mmh3-5.2.0-cp314-cp314-win_amd64.whl", hash = "sha256:7c7f0b342fd06044bedd0b6e72177ddc0076f54fd89ee239447f8b271d919d9b", size = 42135, upload-time = "2025-07-29T07:43:10.183Z" },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/cb/c9/dbba5507e95429b8b380e2ba091eff5c20a70a59560934dff0ad8392b8c8/mmh3-5.2.0-cp314-cp314-win_arm64.whl", hash = "sha256:3193752fc05ea72366c2b63ff24b9a190f422e32d75fdeae71087c08fff26115", size = 39879, upload-time = "2025-07-29T07:43:11.106Z" },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/b5/d1/c8c0ef839c17258b9de41b84f663574fabcf8ac2007b7416575e0f65ff6e/mmh3-5.2.0-cp314-cp314t-macosx_10_13_universal2.whl", hash = "sha256:69fc339d7202bea69ef9bd7c39bfdf9fdabc8e6822a01eba62fb43233c1b3932", size = 57696, upload-time = "2025-07-29T07:43:11.989Z" },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/2f/55/95e2b9ff201e89f9fe37036037ab61a6c941942b25cdb7b6a9df9b931993/mmh3-5.2.0-cp314-cp314t-macosx_10_13_x86_64.whl", hash = "sha256:12da42c0a55c9d86ab566395324213c319c73ecb0c239fad4726324212b9441c", size = 41421, upload-time = "2025-07-29T07:43:13.269Z" },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/77/79/9be23ad0b7001a4b22752e7693be232428ecc0a35068a4ff5c2f14ef8b20/mmh3-5.2.0-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:f7f9034c7cf05ddfaac8d7a2e63a3c97a840d4615d0a0e65ba8bdf6f8576e3be", size = 40853, upload-time = "2025-07-29T07:43:14.888Z" },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/ac/1b/96b32058eda1c1dee8264900c37c359a7325c1f11f5ff14fd2be8e24eff9/mmh3-5.2.0-cp314-cp314t-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:11730eeb16dfcf9674fdea9bb6b8e6dd9b40813b7eb839bc35113649eef38aeb", size = 109694, upload-time = "2025-07-29T07:43:15.816Z" },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/8d/6f/a2ae44cd7dad697b6dea48390cbc977b1e5ca58fda09628cbcb2275af064/mmh3-5.2.0-cp314-cp314t-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:932a6eec1d2e2c3c9e630d10f7128d80e70e2d47fe6b8c7ea5e1afbd98733e65", size = 117438, upload-time = "2025-07-29T07:43:16.865Z" },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/a0/08/bfb75451c83f05224a28afeaf3950c7b793c0b71440d571f8e819cfb149a/mmh3-5.2.0-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:3ca975c51c5028947bbcfc24966517aac06a01d6c921e30f7c5383c195f87991", size = 120409, upload-time = "2025-07-29T07:43:18.207Z" },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/9f/ea/8b118b69b2ff8df568f742387d1a159bc654a0f78741b31437dd047ea28e/mmh3-5.2.0-cp314-cp314t-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:5b0b58215befe0f0e120b828f7645e97719bbba9f23b69e268ed0ac7adde8645", size = 125909, upload-time = "2025-07-29T07:43:19.39Z" },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/3e/11/168cc0b6a30650032e351a3b89b8a47382da541993a03af91e1ba2501234/mmh3-5.2.0-cp314-cp314t-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:29c2b9ce61886809d0492a274a5a53047742dea0f703f9c4d5d223c3ea6377d3", size = 135331, upload-time = "2025-07-29T07:43:20.435Z" },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/31/05/e3a9849b1c18a7934c64e831492c99e67daebe84a8c2f2c39a7096a830e3/mmh3-5.2.0-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:a367d4741ac0103f8198c82f429bccb9359f543ca542b06a51f4f0332e8de279", size = 110085, upload-time = "2025-07-29T07:43:21.92Z" },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/d9/d5/a96bcc306e3404601418b2a9a370baec92af84204528ba659fdfe34c242f/mmh3-5.2.0-cp314-cp314t-musllinux_1_2_i686.whl", hash = "sha256:5a5dba98e514fb26241868f6eb90a7f7ca0e039aed779342965ce24ea32ba513", size = 111195, upload-time = "2025-07-29T07:43:23.066Z" },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/af/29/0fd49801fec5bff37198684e0849b58e0dab3a2a68382a357cfffb0fafc3/mmh3-5.2.0-cp314-cp314t-musllinux_1_2_ppc64le.whl", hash = "sha256:941603bfd75a46023807511c1ac2f1b0f39cccc393c15039969806063b27e6db", size = 116919, upload-time = "2025-07-29T07:43:24.178Z" },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/2d/04/4f3c32b0a2ed762edca45d8b46568fc3668e34f00fb1e0a3b5451ec1281c/mmh3-5.2.0-cp314-cp314t-musllinux_1_2_s390x.whl", hash = "sha256:132dd943451a7c7546978863d2f5a64977928410782e1a87d583cb60eb89e667", size = 123160, upload-time = "2025-07-29T07:43:25.26Z" },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/91/76/3d29eaa38821730633d6a240d36fa8ad2807e9dfd432c12e1a472ed211eb/mmh3-5.2.0-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:f698733a8a494466432d611a8f0d1e026f5286dee051beea4b3c3146817e35d5", size = 110206, upload-time = "2025-07-29T07:43:26.699Z" },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/44/1c/ccf35892684d3a408202e296e56843743e0b4fb1629e59432ea88cdb3909/mmh3-5.2.0-cp314-cp314t-win32.whl", hash = "sha256:6d541038b3fc360ec538fc116de87462627944765a6750308118f8b509a8eec7", size = 41970, upload-time = "2025-07-29T07:43:27.666Z" },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/75/b2/b9e4f1e5adb5e21eb104588fcee2cd1eaa8308255173481427d5ecc4284e/mmh3-5.2.0-cp314-cp314t-win_amd64.whl", hash = "sha256:e912b19cf2378f2967d0c08e86ff4c6c360129887f678e27e4dde970d21b3f4d", size = 43063, upload-time = "2025-07-29T07:43:28.582Z" },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/6a/fc/0e61d9a4e29c8679356795a40e48f647b4aad58d71bfc969f0f8f56fb912/mmh3-5.2.0-cp314-cp314t-win_arm64.whl", hash = "sha256:e7884931fe5e788163e7b3c511614130c2c59feffdc21112290a194487efb2e9", size = 40455, upload-time = "2025-07-29T07:43:29.563Z" },
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "mpmath"
|
||||||
|
version = "1.3.0"
|
||||||
|
source = { registry = "https://pypi.org/simple" }
|
||||||
|
sdist = { url = "https://files.pythonhosted.org/packages/e0/47/dd32fa426cc72114383ac549964eecb20ecfd886d1e5ccf5340b55b02f57/mpmath-1.3.0.tar.gz", hash = "sha256:7a28eb2a9774d00c7bc92411c19a89209d5da7c4c9a9e227be8330a23a25b91f", size = 508106, upload-time = "2023-03-07T16:47:11.061Z" }
|
||||||
|
wheels = [
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/43/e3/7d92a15f894aa0c9c4b49b8ee9ac9850d6e63b03c9c32c0367a13ae62209/mpmath-1.3.0-py3-none-any.whl", hash = "sha256:a0b2b9fe80bbcd81a6647ff13108738cfb482d481d826cc0e02f5b35e5c88d2c", size = 536198, upload-time = "2023-03-07T16:47:09.197Z" },
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "multidict"
|
name = "multidict"
|
||||||
version = "6.7.0"
|
version = "6.7.0"
|
||||||
@@ -772,6 +903,39 @@ wheels = [
|
|||||||
{ url = "https://files.pythonhosted.org/packages/2d/fd/4b5eb0b3e888d86aee4d198c23acec7d214baaf17ea93c1adec94c9518b9/numpy-2.3.5-cp314-cp314t-win_arm64.whl", hash = "sha256:6203fdf9f3dc5bdaed7319ad8698e685c7a3be10819f41d32a0723e611733b42", size = 10545459, upload-time = "2025-11-16T22:52:20.55Z" },
|
{ url = "https://files.pythonhosted.org/packages/2d/fd/4b5eb0b3e888d86aee4d198c23acec7d214baaf17ea93c1adec94c9518b9/numpy-2.3.5-cp314-cp314t-win_arm64.whl", hash = "sha256:6203fdf9f3dc5bdaed7319ad8698e685c7a3be10819f41d32a0723e611733b42", size = 10545459, upload-time = "2025-11-16T22:52:20.55Z" },
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "onnxruntime"
|
||||||
|
version = "1.24.2"
|
||||||
|
source = { registry = "https://pypi.org/simple" }
|
||||||
|
dependencies = [
|
||||||
|
{ name = "flatbuffers" },
|
||||||
|
{ name = "numpy" },
|
||||||
|
{ name = "packaging" },
|
||||||
|
{ name = "protobuf" },
|
||||||
|
{ name = "sympy" },
|
||||||
|
]
|
||||||
|
wheels = [
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/23/1c/38af1cfe82c75d2b205eb5019834b0f2b0b6647ec8a20a3086168e413570/onnxruntime-1.24.2-cp312-cp312-macosx_14_0_arm64.whl", hash = "sha256:d8a50b422d45c0144864c0977d04ad4fa50a8a48e5153056ab1f7d06ea9fc3e2", size = 17217857, upload-time = "2026-02-19T17:15:14.297Z" },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/01/8a/e2d4332ae18d6383376e75141cd914256bee12c3cc439f42260eb176ceb9/onnxruntime-1.24.2-cp312-cp312-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:76c44fc9a89dcefcd5a4ab5c6bbbb9ff1604325ab2d5d0bc9ff5a9cba7b37f4a", size = 15027167, upload-time = "2026-02-19T17:13:21.92Z" },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/35/af/ad86cfbfd65d5a86204b3a30893e92c0cf3f1a56280efc5a12e69d81f52d/onnxruntime-1.24.2-cp312-cp312-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:09aa6f8d766b4afc3cfba68dd10be39586b49f9462fbd1386c5d5644239461ca", size = 17106547, upload-time = "2026-02-19T17:14:05.758Z" },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/ee/62/9d725326f933bf8323e309956a17e52d33fb59d35bb5dda1886f94352938/onnxruntime-1.24.2-cp312-cp312-win_amd64.whl", hash = "sha256:ebcee9276420a65e5fa08b05f18379c2271b5992617e5bdc0d0d6c5ea395c1a1", size = 12506161, upload-time = "2026-02-19T17:14:59.377Z" },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/aa/a9/7b06efd5802db881860d961a7cb4efacb058ed694c1c8f096c0c1499d017/onnxruntime-1.24.2-cp312-cp312-win_arm64.whl", hash = "sha256:8d770a934513f6e17937baf3438eaaec5983a23cdaedb81c9fc0dfcf26831c24", size = 12169884, upload-time = "2026-02-19T17:14:49.962Z" },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/9c/98/8f5b9ae63f7f6dd5fb2d192454b915ec966a421fdd0effeeef5be7f7221f/onnxruntime-1.24.2-cp313-cp313-macosx_14_0_arm64.whl", hash = "sha256:038ebcd8363c3835ea83eed66129e1d11d8219438892dfb7dc7656c4d4dfa1f9", size = 17217884, upload-time = "2026-02-19T17:13:36.193Z" },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/55/e6/dc4dc59565c93506c45017c0dd3f536f6d1b7bc97047821af13fba2e3def/onnxruntime-1.24.2-cp313-cp313-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:8235cc11e118ad749c497ba93288c04073eccd8cc6cc508c8a7988ae36ab52d8", size = 15026995, upload-time = "2026-02-19T17:13:25.029Z" },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/ac/62/6f2851cf3237a91bc04cdb35434293a623d4f6369f79836929600da574ba/onnxruntime-1.24.2-cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:e92b46cc6d8be4286436a05382a881c88d85a2ae1ea9cfe5e6fab89f2c3e89cc", size = 17106308, upload-time = "2026-02-19T17:14:09.817Z" },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/62/5a/1e2b874daf24f26e98af14281fdbdd6ae1ed548ba471c01ea2a3084c55bb/onnxruntime-1.24.2-cp313-cp313-win_amd64.whl", hash = "sha256:1fd824ee4f6fb811bc47ffec2b25f129f31a087214ca91c8b4f6fda32962b78f", size = 12506095, upload-time = "2026-02-19T17:15:02.434Z" },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/2d/6f/8fac5eecb94f861d56a43ede3c2ebcdce60132952d3b72003f3e3d91483c/onnxruntime-1.24.2-cp313-cp313-win_arm64.whl", hash = "sha256:d8cf0acbf90771fff012c33eb2749e8aca2a8b4c66c672f30ee77c140a6fba5b", size = 12168564, upload-time = "2026-02-19T17:14:52.28Z" },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/35/e4/7dfed3f445f7289a0abff709d012439c6c901915390704dd918e5f47aad3/onnxruntime-1.24.2-cp313-cp313t-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:e22fb5d9ac51b61f50cca155ce2927576cc2c42501ede6c0df23a1aeb070bdd5", size = 15036844, upload-time = "2026-02-19T17:13:27.928Z" },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/90/45/9d52397e30b0d8c1692afcec5184ca9372ff4d6b0f6039bba9ad479a2563/onnxruntime-1.24.2-cp313-cp313t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:2956f5220e7be8b09482ae5726caabf78eb549142cdb28523191a38e57fb6119", size = 17117779, upload-time = "2026-02-19T17:14:13.862Z" },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/a9/c8/2321cd06ddbb4321326df365ccb8345cdb4e05643f539729f3943c706e97/onnxruntime-1.24.2-cp314-cp314-macosx_14_0_arm64.whl", hash = "sha256:487e3fdedc24bc93f2acdf47c622de49b3999fb5754e7cfa466e5533a0215051", size = 17219405, upload-time = "2026-02-19T17:13:39.925Z" },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/ad/ff/a2cdf95d2647f2a5076eb3fc49ae662e375c4eb5c7b6b675f910f96c8e15/onnxruntime-1.24.2-cp314-cp314-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:9c33398bd6ab1a6b7de9410af7360cd8b6312bc0c4848ddb738456c13dfbec4b", size = 15027713, upload-time = "2026-02-19T17:13:30.693Z" },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/0d/74/a1913b3a0fc2f27fe1751e9545745a3f35fd7833e3438a4208b4e215778f/onnxruntime-1.24.2-cp314-cp314-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:2658b3ce6cb33bdeddfcd74c6da509510310717611220cf2106e6c401febabe5", size = 17106108, upload-time = "2026-02-19T17:14:16.619Z" },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/0a/bd/fca80d282bca9848b2c8e101c764432dd61a0e9d2377d1c8b3bab13235d0/onnxruntime-1.24.2-cp314-cp314-win_amd64.whl", hash = "sha256:45b4f68ffec95b2cc0dc96b2b413f69ace9a80a0e5400023c5ac61f73a7a3fdf", size = 12808967, upload-time = "2026-02-19T17:15:05.1Z" },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/6d/eb/6b154dd61cac410cacf27a9f53bbf49f4dbfe5b3982f3f5b0247c7bf7b78/onnxruntime-1.24.2-cp314-cp314-win_arm64.whl", hash = "sha256:6c501aaaaa674e689aaac501e26eb96aba908ebc067fe761fbcbed868bd694a6", size = 12491892, upload-time = "2026-02-19T17:14:54.584Z" },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/6f/84/14e5e804836476d3ef6ac07afe3ed6bdf01b69f8ef3ce6ae82c6c80b6d62/onnxruntime-1.24.2-cp314-cp314t-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:5360d3fd9c08ce17fff757759ce4b152852be14d597130f41174d8271f954630", size = 15036834, upload-time = "2026-02-19T17:13:33.65Z" },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/3a/27/ecdd3ae7d49d9f54820ededce2d88ddc3333b9ac9bb5f1d0d6aa3148c686/onnxruntime-1.24.2-cp314-cp314t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:05a2792b5ef9278a89415a1f39d0a22192a872168257100503a5157165a38e7b", size = 17117770, upload-time = "2026-02-19T17:14:20.048Z" },
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "packaging"
|
name = "packaging"
|
||||||
version = "25.0"
|
version = "25.0"
|
||||||
@@ -837,6 +1001,72 @@ wheels = [
|
|||||||
{ url = "https://files.pythonhosted.org/packages/cc/20/ff623b09d963f88bfde16306a54e12ee5ea43e9b597108672ff3a408aad6/pathspec-0.12.1-py3-none-any.whl", hash = "sha256:a0d503e138a4c123b27490a4f7beda6a01c6f288df0e4a8b79c7eb0dc7b4cc08", size = 31191, upload-time = "2023-12-10T22:30:43.14Z" },
|
{ url = "https://files.pythonhosted.org/packages/cc/20/ff623b09d963f88bfde16306a54e12ee5ea43e9b597108672ff3a408aad6/pathspec-0.12.1-py3-none-any.whl", hash = "sha256:a0d503e138a4c123b27490a4f7beda6a01c6f288df0e4a8b79c7eb0dc7b4cc08", size = 31191, upload-time = "2023-12-10T22:30:43.14Z" },
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "pillow"
|
||||||
|
version = "11.3.0"
|
||||||
|
source = { registry = "https://pypi.org/simple" }
|
||||||
|
sdist = { url = "https://files.pythonhosted.org/packages/f3/0d/d0d6dea55cd152ce3d6767bb38a8fc10e33796ba4ba210cbab9354b6d238/pillow-11.3.0.tar.gz", hash = "sha256:3828ee7586cd0b2091b6209e5ad53e20d0649bbe87164a459d0676e035e8f523", size = 47113069, upload-time = "2025-07-01T09:16:30.666Z" }
|
||||||
|
wheels = [
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/40/fe/1bc9b3ee13f68487a99ac9529968035cca2f0a51ec36892060edcc51d06a/pillow-11.3.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:fdae223722da47b024b867c1ea0be64e0df702c5e0a60e27daad39bf960dd1e4", size = 5278800, upload-time = "2025-07-01T09:14:17.648Z" },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/2c/32/7e2ac19b5713657384cec55f89065fb306b06af008cfd87e572035b27119/pillow-11.3.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:921bd305b10e82b4d1f5e802b6850677f965d8394203d182f078873851dada69", size = 4686296, upload-time = "2025-07-01T09:14:19.828Z" },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/8e/1e/b9e12bbe6e4c2220effebc09ea0923a07a6da1e1f1bfbc8d7d29a01ce32b/pillow-11.3.0-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:eb76541cba2f958032d79d143b98a3a6b3ea87f0959bbe256c0b5e416599fd5d", size = 5871726, upload-time = "2025-07-03T13:10:04.448Z" },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/8d/33/e9200d2bd7ba00dc3ddb78df1198a6e80d7669cce6c2bdbeb2530a74ec58/pillow-11.3.0-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:67172f2944ebba3d4a7b54f2e95c786a3a50c21b88456329314caaa28cda70f6", size = 7644652, upload-time = "2025-07-03T13:10:10.391Z" },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/41/f1/6f2427a26fc683e00d985bc391bdd76d8dd4e92fac33d841127eb8fb2313/pillow-11.3.0-cp312-cp312-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:97f07ed9f56a3b9b5f49d3661dc9607484e85c67e27f3e8be2c7d28ca032fec7", size = 5977787, upload-time = "2025-07-01T09:14:21.63Z" },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/e4/c9/06dd4a38974e24f932ff5f98ea3c546ce3f8c995d3f0985f8e5ba48bba19/pillow-11.3.0-cp312-cp312-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:676b2815362456b5b3216b4fd5bd89d362100dc6f4945154ff172e206a22c024", size = 6645236, upload-time = "2025-07-01T09:14:23.321Z" },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/40/e7/848f69fb79843b3d91241bad658e9c14f39a32f71a301bcd1d139416d1be/pillow-11.3.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:3e184b2f26ff146363dd07bde8b711833d7b0202e27d13540bfe2e35a323a809", size = 6086950, upload-time = "2025-07-01T09:14:25.237Z" },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/0b/1a/7cff92e695a2a29ac1958c2a0fe4c0b2393b60aac13b04a4fe2735cad52d/pillow-11.3.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:6be31e3fc9a621e071bc17bb7de63b85cbe0bfae91bb0363c893cbe67247780d", size = 6723358, upload-time = "2025-07-01T09:14:27.053Z" },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/26/7d/73699ad77895f69edff76b0f332acc3d497f22f5d75e5360f78cbcaff248/pillow-11.3.0-cp312-cp312-win32.whl", hash = "sha256:7b161756381f0918e05e7cb8a371fff367e807770f8fe92ecb20d905d0e1c149", size = 6275079, upload-time = "2025-07-01T09:14:30.104Z" },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/8c/ce/e7dfc873bdd9828f3b6e5c2bbb74e47a98ec23cc5c74fc4e54462f0d9204/pillow-11.3.0-cp312-cp312-win_amd64.whl", hash = "sha256:a6444696fce635783440b7f7a9fc24b3ad10a9ea3f0ab66c5905be1c19ccf17d", size = 6986324, upload-time = "2025-07-01T09:14:31.899Z" },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/16/8f/b13447d1bf0b1f7467ce7d86f6e6edf66c0ad7cf44cf5c87a37f9bed9936/pillow-11.3.0-cp312-cp312-win_arm64.whl", hash = "sha256:2aceea54f957dd4448264f9bf40875da0415c83eb85f55069d89c0ed436e3542", size = 2423067, upload-time = "2025-07-01T09:14:33.709Z" },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/1e/93/0952f2ed8db3a5a4c7a11f91965d6184ebc8cd7cbb7941a260d5f018cd2d/pillow-11.3.0-cp313-cp313-ios_13_0_arm64_iphoneos.whl", hash = "sha256:1c627742b539bba4309df89171356fcb3cc5a9178355b2727d1b74a6cf155fbd", size = 2128328, upload-time = "2025-07-01T09:14:35.276Z" },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/4b/e8/100c3d114b1a0bf4042f27e0f87d2f25e857e838034e98ca98fe7b8c0a9c/pillow-11.3.0-cp313-cp313-ios_13_0_arm64_iphonesimulator.whl", hash = "sha256:30b7c02f3899d10f13d7a48163c8969e4e653f8b43416d23d13d1bbfdc93b9f8", size = 2170652, upload-time = "2025-07-01T09:14:37.203Z" },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/aa/86/3f758a28a6e381758545f7cdb4942e1cb79abd271bea932998fc0db93cb6/pillow-11.3.0-cp313-cp313-ios_13_0_x86_64_iphonesimulator.whl", hash = "sha256:7859a4cc7c9295f5838015d8cc0a9c215b77e43d07a25e460f35cf516df8626f", size = 2227443, upload-time = "2025-07-01T09:14:39.344Z" },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/01/f4/91d5b3ffa718df2f53b0dc109877993e511f4fd055d7e9508682e8aba092/pillow-11.3.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:ec1ee50470b0d050984394423d96325b744d55c701a439d2bd66089bff963d3c", size = 5278474, upload-time = "2025-07-01T09:14:41.843Z" },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/f9/0e/37d7d3eca6c879fbd9dba21268427dffda1ab00d4eb05b32923d4fbe3b12/pillow-11.3.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:7db51d222548ccfd274e4572fdbf3e810a5e66b00608862f947b163e613b67dd", size = 4686038, upload-time = "2025-07-01T09:14:44.008Z" },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/ff/b0/3426e5c7f6565e752d81221af9d3676fdbb4f352317ceafd42899aaf5d8a/pillow-11.3.0-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:2d6fcc902a24ac74495df63faad1884282239265c6839a0a6416d33faedfae7e", size = 5864407, upload-time = "2025-07-03T13:10:15.628Z" },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/fc/c1/c6c423134229f2a221ee53f838d4be9d82bab86f7e2f8e75e47b6bf6cd77/pillow-11.3.0-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:f0f5d8f4a08090c6d6d578351a2b91acf519a54986c055af27e7a93feae6d3f1", size = 7639094, upload-time = "2025-07-03T13:10:21.857Z" },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/ba/c9/09e6746630fe6372c67c648ff9deae52a2bc20897d51fa293571977ceb5d/pillow-11.3.0-cp313-cp313-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:c37d8ba9411d6003bba9e518db0db0c58a680ab9fe5179f040b0463644bc9805", size = 5973503, upload-time = "2025-07-01T09:14:45.698Z" },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/d5/1c/a2a29649c0b1983d3ef57ee87a66487fdeb45132df66ab30dd37f7dbe162/pillow-11.3.0-cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:13f87d581e71d9189ab21fe0efb5a23e9f28552d5be6979e84001d3b8505abe8", size = 6642574, upload-time = "2025-07-01T09:14:47.415Z" },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/36/de/d5cc31cc4b055b6c6fd990e3e7f0f8aaf36229a2698501bcb0cdf67c7146/pillow-11.3.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:023f6d2d11784a465f09fd09a34b150ea4672e85fb3d05931d89f373ab14abb2", size = 6084060, upload-time = "2025-07-01T09:14:49.636Z" },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/d5/ea/502d938cbaeec836ac28a9b730193716f0114c41325db428e6b280513f09/pillow-11.3.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:45dfc51ac5975b938e9809451c51734124e73b04d0f0ac621649821a63852e7b", size = 6721407, upload-time = "2025-07-01T09:14:51.962Z" },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/45/9c/9c5e2a73f125f6cbc59cc7087c8f2d649a7ae453f83bd0362ff7c9e2aee2/pillow-11.3.0-cp313-cp313-win32.whl", hash = "sha256:a4d336baed65d50d37b88ca5b60c0fa9d81e3a87d4a7930d3880d1624d5b31f3", size = 6273841, upload-time = "2025-07-01T09:14:54.142Z" },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/23/85/397c73524e0cd212067e0c969aa245b01d50183439550d24d9f55781b776/pillow-11.3.0-cp313-cp313-win_amd64.whl", hash = "sha256:0bce5c4fd0921f99d2e858dc4d4d64193407e1b99478bc5cacecba2311abde51", size = 6978450, upload-time = "2025-07-01T09:14:56.436Z" },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/17/d2/622f4547f69cd173955194b78e4d19ca4935a1b0f03a302d655c9f6aae65/pillow-11.3.0-cp313-cp313-win_arm64.whl", hash = "sha256:1904e1264881f682f02b7f8167935cce37bc97db457f8e7849dc3a6a52b99580", size = 2423055, upload-time = "2025-07-01T09:14:58.072Z" },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/dd/80/a8a2ac21dda2e82480852978416cfacd439a4b490a501a288ecf4fe2532d/pillow-11.3.0-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:4c834a3921375c48ee6b9624061076bc0a32a60b5532b322cc0ea64e639dd50e", size = 5281110, upload-time = "2025-07-01T09:14:59.79Z" },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/44/d6/b79754ca790f315918732e18f82a8146d33bcd7f4494380457ea89eb883d/pillow-11.3.0-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:5e05688ccef30ea69b9317a9ead994b93975104a677a36a8ed8106be9260aa6d", size = 4689547, upload-time = "2025-07-01T09:15:01.648Z" },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/49/20/716b8717d331150cb00f7fdd78169c01e8e0c219732a78b0e59b6bdb2fd6/pillow-11.3.0-cp313-cp313t-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:1019b04af07fc0163e2810167918cb5add8d74674b6267616021ab558dc98ced", size = 5901554, upload-time = "2025-07-03T13:10:27.018Z" },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/74/cf/a9f3a2514a65bb071075063a96f0a5cf949c2f2fce683c15ccc83b1c1cab/pillow-11.3.0-cp313-cp313t-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:f944255db153ebb2b19c51fe85dd99ef0ce494123f21b9db4877ffdfc5590c7c", size = 7669132, upload-time = "2025-07-03T13:10:33.01Z" },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/98/3c/da78805cbdbee9cb43efe8261dd7cc0b4b93f2ac79b676c03159e9db2187/pillow-11.3.0-cp313-cp313t-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:1f85acb69adf2aaee8b7da124efebbdb959a104db34d3a2cb0f3793dbae422a8", size = 6005001, upload-time = "2025-07-01T09:15:03.365Z" },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/6c/fa/ce044b91faecf30e635321351bba32bab5a7e034c60187fe9698191aef4f/pillow-11.3.0-cp313-cp313t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:05f6ecbeff5005399bb48d198f098a9b4b6bdf27b8487c7f38ca16eeb070cd59", size = 6668814, upload-time = "2025-07-01T09:15:05.655Z" },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/7b/51/90f9291406d09bf93686434f9183aba27b831c10c87746ff49f127ee80cb/pillow-11.3.0-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:a7bc6e6fd0395bc052f16b1a8670859964dbd7003bd0af2ff08342eb6e442cfe", size = 6113124, upload-time = "2025-07-01T09:15:07.358Z" },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/cd/5a/6fec59b1dfb619234f7636d4157d11fb4e196caeee220232a8d2ec48488d/pillow-11.3.0-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:83e1b0161c9d148125083a35c1c5a89db5b7054834fd4387499e06552035236c", size = 6747186, upload-time = "2025-07-01T09:15:09.317Z" },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/49/6b/00187a044f98255225f172de653941e61da37104a9ea60e4f6887717e2b5/pillow-11.3.0-cp313-cp313t-win32.whl", hash = "sha256:2a3117c06b8fb646639dce83694f2f9eac405472713fcb1ae887469c0d4f6788", size = 6277546, upload-time = "2025-07-01T09:15:11.311Z" },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/e8/5c/6caaba7e261c0d75bab23be79f1d06b5ad2a2ae49f028ccec801b0e853d6/pillow-11.3.0-cp313-cp313t-win_amd64.whl", hash = "sha256:857844335c95bea93fb39e0fa2726b4d9d758850b34075a7e3ff4f4fa3aa3b31", size = 6985102, upload-time = "2025-07-01T09:15:13.164Z" },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/f3/7e/b623008460c09a0cb38263c93b828c666493caee2eb34ff67f778b87e58c/pillow-11.3.0-cp313-cp313t-win_arm64.whl", hash = "sha256:8797edc41f3e8536ae4b10897ee2f637235c94f27404cac7297f7b607dd0716e", size = 2424803, upload-time = "2025-07-01T09:15:15.695Z" },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/73/f4/04905af42837292ed86cb1b1dabe03dce1edc008ef14c473c5c7e1443c5d/pillow-11.3.0-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:d9da3df5f9ea2a89b81bb6087177fb1f4d1c7146d583a3fe5c672c0d94e55e12", size = 5278520, upload-time = "2025-07-01T09:15:17.429Z" },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/41/b0/33d79e377a336247df6348a54e6d2a2b85d644ca202555e3faa0cf811ecc/pillow-11.3.0-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:0b275ff9b04df7b640c59ec5a3cb113eefd3795a8df80bac69646ef699c6981a", size = 4686116, upload-time = "2025-07-01T09:15:19.423Z" },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/49/2d/ed8bc0ab219ae8768f529597d9509d184fe8a6c4741a6864fea334d25f3f/pillow-11.3.0-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:0743841cabd3dba6a83f38a92672cccbd69af56e3e91777b0ee7f4dba4385632", size = 5864597, upload-time = "2025-07-03T13:10:38.404Z" },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/b5/3d/b932bb4225c80b58dfadaca9d42d08d0b7064d2d1791b6a237f87f661834/pillow-11.3.0-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:2465a69cf967b8b49ee1b96d76718cd98c4e925414ead59fdf75cf0fd07df673", size = 7638246, upload-time = "2025-07-03T13:10:44.987Z" },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/09/b5/0487044b7c096f1b48f0d7ad416472c02e0e4bf6919541b111efd3cae690/pillow-11.3.0-cp314-cp314-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:41742638139424703b4d01665b807c6468e23e699e8e90cffefe291c5832b027", size = 5973336, upload-time = "2025-07-01T09:15:21.237Z" },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/a8/2d/524f9318f6cbfcc79fbc004801ea6b607ec3f843977652fdee4857a7568b/pillow-11.3.0-cp314-cp314-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:93efb0b4de7e340d99057415c749175e24c8864302369e05914682ba642e5d77", size = 6642699, upload-time = "2025-07-01T09:15:23.186Z" },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/6f/d2/a9a4f280c6aefedce1e8f615baaa5474e0701d86dd6f1dede66726462bbd/pillow-11.3.0-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:7966e38dcd0fa11ca390aed7c6f20454443581d758242023cf36fcb319b1a874", size = 6083789, upload-time = "2025-07-01T09:15:25.1Z" },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/fe/54/86b0cd9dbb683a9d5e960b66c7379e821a19be4ac5810e2e5a715c09a0c0/pillow-11.3.0-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:98a9afa7b9007c67ed84c57c9e0ad86a6000da96eaa638e4f8abe5b65ff83f0a", size = 6720386, upload-time = "2025-07-01T09:15:27.378Z" },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/e7/95/88efcaf384c3588e24259c4203b909cbe3e3c2d887af9e938c2022c9dd48/pillow-11.3.0-cp314-cp314-win32.whl", hash = "sha256:02a723e6bf909e7cea0dac1b0e0310be9d7650cd66222a5f1c571455c0a45214", size = 6370911, upload-time = "2025-07-01T09:15:29.294Z" },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/2e/cc/934e5820850ec5eb107e7b1a72dd278140731c669f396110ebc326f2a503/pillow-11.3.0-cp314-cp314-win_amd64.whl", hash = "sha256:a418486160228f64dd9e9efcd132679b7a02a5f22c982c78b6fc7dab3fefb635", size = 7117383, upload-time = "2025-07-01T09:15:31.128Z" },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/d6/e9/9c0a616a71da2a5d163aa37405e8aced9a906d574b4a214bede134e731bc/pillow-11.3.0-cp314-cp314-win_arm64.whl", hash = "sha256:155658efb5e044669c08896c0c44231c5e9abcaadbc5cd3648df2f7c0b96b9a6", size = 2511385, upload-time = "2025-07-01T09:15:33.328Z" },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/1a/33/c88376898aff369658b225262cd4f2659b13e8178e7534df9e6e1fa289f6/pillow-11.3.0-cp314-cp314t-macosx_10_13_x86_64.whl", hash = "sha256:59a03cdf019efbfeeed910bf79c7c93255c3d54bc45898ac2a4140071b02b4ae", size = 5281129, upload-time = "2025-07-01T09:15:35.194Z" },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/1f/70/d376247fb36f1844b42910911c83a02d5544ebd2a8bad9efcc0f707ea774/pillow-11.3.0-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:f8a5827f84d973d8636e9dc5764af4f0cf2318d26744b3d902931701b0d46653", size = 4689580, upload-time = "2025-07-01T09:15:37.114Z" },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/eb/1c/537e930496149fbac69efd2fc4329035bbe2e5475b4165439e3be9cb183b/pillow-11.3.0-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:ee92f2fd10f4adc4b43d07ec5e779932b4eb3dbfbc34790ada5a6669bc095aa6", size = 5902860, upload-time = "2025-07-03T13:10:50.248Z" },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/bd/57/80f53264954dcefeebcf9dae6e3eb1daea1b488f0be8b8fef12f79a3eb10/pillow-11.3.0-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:c96d333dcf42d01f47b37e0979b6bd73ec91eae18614864622d9b87bbd5bbf36", size = 7670694, upload-time = "2025-07-03T13:10:56.432Z" },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/70/ff/4727d3b71a8578b4587d9c276e90efad2d6fe0335fd76742a6da08132e8c/pillow-11.3.0-cp314-cp314t-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:4c96f993ab8c98460cd0c001447bff6194403e8b1d7e149ade5f00594918128b", size = 6005888, upload-time = "2025-07-01T09:15:39.436Z" },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/05/ae/716592277934f85d3be51d7256f3636672d7b1abfafdc42cf3f8cbd4b4c8/pillow-11.3.0-cp314-cp314t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:41342b64afeba938edb034d122b2dda5db2139b9a4af999729ba8818e0056477", size = 6670330, upload-time = "2025-07-01T09:15:41.269Z" },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/e7/bb/7fe6cddcc8827b01b1a9766f5fdeb7418680744f9082035bdbabecf1d57f/pillow-11.3.0-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:068d9c39a2d1b358eb9f245ce7ab1b5c3246c7c8c7d9ba58cfa5b43146c06e50", size = 6114089, upload-time = "2025-07-01T09:15:43.13Z" },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/8b/f5/06bfaa444c8e80f1a8e4bff98da9c83b37b5be3b1deaa43d27a0db37ef84/pillow-11.3.0-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:a1bc6ba083b145187f648b667e05a2534ecc4b9f2784c2cbe3089e44868f2b9b", size = 6748206, upload-time = "2025-07-01T09:15:44.937Z" },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/f0/77/bc6f92a3e8e6e46c0ca78abfffec0037845800ea38c73483760362804c41/pillow-11.3.0-cp314-cp314t-win32.whl", hash = "sha256:118ca10c0d60b06d006be10a501fd6bbdfef559251ed31b794668ed569c87e12", size = 6377370, upload-time = "2025-07-01T09:15:46.673Z" },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/4a/82/3a721f7d69dca802befb8af08b7c79ebcab461007ce1c18bd91a5d5896f9/pillow-11.3.0-cp314-cp314t-win_amd64.whl", hash = "sha256:8924748b688aa210d79883357d102cd64690e56b923a186f35a82cbc10f997db", size = 7121500, upload-time = "2025-07-01T09:15:48.512Z" },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/89/c7/5572fa4a3f45740eaab6ae86fcdf7195b55beac1371ac8c619d880cfe948/pillow-11.3.0-cp314-cp314t-win_arm64.whl", hash = "sha256:79ea0d14d3ebad43ec77ad5272e6ff9bba5b679ef73375ea760261207fa8e0aa", size = 2512835, upload-time = "2025-07-01T09:15:50.399Z" },
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "portalocker"
|
name = "portalocker"
|
||||||
version = "2.10.1"
|
version = "2.10.1"
|
||||||
@@ -948,6 +1178,34 @@ wheels = [
|
|||||||
{ url = "https://files.pythonhosted.org/packages/08/b4/46310463b4f6ceef310f8348786f3cff181cea671578e3d9743ba61a459e/protobuf-6.33.1-py3-none-any.whl", hash = "sha256:d595a9fd694fdeb061a62fbe10eb039cc1e444df81ec9bb70c7fc59ebcb1eafa", size = 170477, upload-time = "2025-11-13T16:44:17.633Z" },
|
{ url = "https://files.pythonhosted.org/packages/08/b4/46310463b4f6ceef310f8348786f3cff181cea671578e3d9743ba61a459e/protobuf-6.33.1-py3-none-any.whl", hash = "sha256:d595a9fd694fdeb061a62fbe10eb039cc1e444df81ec9bb70c7fc59ebcb1eafa", size = 170477, upload-time = "2025-11-13T16:44:17.633Z" },
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "py-rust-stemmers"
|
||||||
|
version = "0.1.5"
|
||||||
|
source = { registry = "https://pypi.org/simple" }
|
||||||
|
sdist = { url = "https://files.pythonhosted.org/packages/8e/63/4fbc14810c32d2a884e2e94e406a7d5bf8eee53e1103f558433817230342/py_rust_stemmers-0.1.5.tar.gz", hash = "sha256:e9c310cfb5c2470d7c7c8a0484725965e7cab8b1237e106a0863d5741da3e1f7", size = 9388, upload-time = "2025-02-19T13:56:28.708Z" }
|
||||||
|
wheels = [
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/43/e1/ea8ac92454a634b1bb1ee0a89c2f75a4e6afec15a8412527e9bbde8c6b7b/py_rust_stemmers-0.1.5-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:29772837126a28263bf54ecd1bc709dd569d15a94d5e861937813ce51e8a6df4", size = 286085, upload-time = "2025-02-19T13:55:23.871Z" },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/cb/32/fe1cc3d36a19c1ce39792b1ed151ddff5ee1d74c8801f0e93ff36e65f885/py_rust_stemmers-0.1.5-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:4d62410ada44a01e02974b85d45d82f4b4c511aae9121e5f3c1ba1d0bea9126b", size = 272021, upload-time = "2025-02-19T13:55:25.685Z" },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/0a/38/b8f94e5e886e7ab181361a0911a14fb923b0d05b414de85f427e773bf445/py_rust_stemmers-0.1.5-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b28ef729a4c83c7d9418be3c23c0372493fcccc67e86783ff04596ef8a208cdf", size = 310547, upload-time = "2025-02-19T13:55:26.891Z" },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/a9/08/62e97652d359b75335486f4da134a6f1c281f38bd3169ed6ecfb276448c3/py_rust_stemmers-0.1.5-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:a979c3f4ff7ad94a0d4cf566ca7bfecebb59e66488cc158e64485cf0c9a7879f", size = 315237, upload-time = "2025-02-19T13:55:28.116Z" },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/1c/b9/fc0278432f288d2be4ee4d5cc80fd8013d604506b9b0503e8b8cae4ba1c3/py_rust_stemmers-0.1.5-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1c3593d895453fa06bf70a7b76d6f00d06def0f91fc253fe4260920650c5e078", size = 324419, upload-time = "2025-02-19T13:55:29.211Z" },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/6b/5b/74e96eaf622fe07e83c5c389d101540e305e25f76a6d0d6fb3d9e0506db8/py_rust_stemmers-0.1.5-cp312-cp312-manylinux_2_28_x86_64.whl", hash = "sha256:96ccc7fd042ffc3f7f082f2223bb7082ed1423aa6b43d5d89ab23e321936c045", size = 324792, upload-time = "2025-02-19T13:55:30.948Z" },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/4f/f7/b76816d7d67166e9313915ad486c21d9e7da0ac02703e14375bb1cb64b5a/py_rust_stemmers-0.1.5-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:ef18cfced2c9c676e0d7d172ba61c3fab2aa6969db64cc8f5ca33a7759efbefe", size = 488014, upload-time = "2025-02-19T13:55:32.066Z" },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/b9/ed/7d9bed02f78d85527501f86a867cd5002d97deb791b9a6b1b45b00100010/py_rust_stemmers-0.1.5-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:541d4b5aa911381e3d37ec483abb6a2cf2351b4f16d5e8d77f9aa2722956662a", size = 575582, upload-time = "2025-02-19T13:55:34.005Z" },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/93/40/eafd1b33688e8e8ae946d1ef25c4dc93f5b685bd104b9c5573405d7e1d30/py_rust_stemmers-0.1.5-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:ffd946a36e9ac17ca96821963663012e04bc0ee94d21e8b5ae034721070b436c", size = 493267, upload-time = "2025-02-19T13:55:35.294Z" },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/2f/6a/15135b69e4fd28369433eb03264d201b1b0040ba534b05eddeb02a276684/py_rust_stemmers-0.1.5-cp312-none-win_amd64.whl", hash = "sha256:6ed61e1207f3b7428e99b5d00c055645c6415bb75033bff2d06394cbe035fd8e", size = 209395, upload-time = "2025-02-19T13:55:36.519Z" },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/80/b8/030036311ec25952bf3083b6c105be5dee052a71aa22d5fbeb857ebf8c1c/py_rust_stemmers-0.1.5-cp313-cp313-macosx_10_12_x86_64.whl", hash = "sha256:398b3a843a9cd4c5d09e726246bc36f66b3d05b0a937996814e91f47708f5db5", size = 286086, upload-time = "2025-02-19T13:55:37.581Z" },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/ed/be/0465dcb3a709ee243d464e89231e3da580017f34279d6304de291d65ccb0/py_rust_stemmers-0.1.5-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:4e308fc7687901f0c73603203869908f3156fa9c17c4ba010a7fcc98a7a1c5f2", size = 272019, upload-time = "2025-02-19T13:55:39.183Z" },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/ab/b6/76ca5b1f30cba36835938b5d9abee0c130c81833d51b9006264afdf8df3c/py_rust_stemmers-0.1.5-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1f9efc4da5e734bdd00612e7506de3d0c9b7abc4b89d192742a0569d0d1fe749", size = 310545, upload-time = "2025-02-19T13:55:40.339Z" },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/56/8f/5be87618cea2fe2e70e74115a20724802bfd06f11c7c43514b8288eb6514/py_rust_stemmers-0.1.5-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:cc2cc8d2b36bc05b8b06506199ac63d437360ae38caefd98cd19e479d35afd42", size = 315236, upload-time = "2025-02-19T13:55:41.55Z" },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/00/02/ea86a316aee0f0a9d1449ad4dbffff38f4cf0a9a31045168ae8b95d8bdf8/py_rust_stemmers-0.1.5-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a231dc6f0b2a5f12a080dfc7abd9e6a4ea0909290b10fd0a4620e5a0f52c3d17", size = 324419, upload-time = "2025-02-19T13:55:42.693Z" },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/2a/fd/1612c22545dcc0abe2f30fc08f30a2332f2224dd536fa1508444a9ca0e39/py_rust_stemmers-0.1.5-cp313-cp313-manylinux_2_28_x86_64.whl", hash = "sha256:5845709d48afc8b29e248f42f92431155a3d8df9ba30418301c49c6072b181b0", size = 324794, upload-time = "2025-02-19T13:55:43.896Z" },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/66/18/8a547584d7edac9e7ac9c7bdc53228d6f751c0f70a317093a77c386c8ddc/py_rust_stemmers-0.1.5-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:e48bfd5e3ce9d223bfb9e634dc1425cf93ee57eef6f56aa9a7120ada3990d4be", size = 488014, upload-time = "2025-02-19T13:55:45.088Z" },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/3b/87/4619c395b325e26048a6e28a365afed754614788ba1f49b2eefb07621a03/py_rust_stemmers-0.1.5-cp313-cp313-musllinux_1_2_armv7l.whl", hash = "sha256:35d32f6e7bdf6fd90e981765e32293a8be74def807147dea9fdc1f65d6ce382f", size = 575582, upload-time = "2025-02-19T13:55:46.436Z" },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/98/6e/214f1a889142b7df6d716e7f3fea6c41e87bd6c29046aa57e175d452b104/py_rust_stemmers-0.1.5-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:191ea8bf922c984631ffa20bf02ef0ad7eec0465baeaed3852779e8f97c7e7a3", size = 493269, upload-time = "2025-02-19T13:55:49.057Z" },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/e1/b9/c5185df277576f995ae34418eb2b2ac12f30835412270f9e05c52face521/py_rust_stemmers-0.1.5-cp313-none-win_amd64.whl", hash = "sha256:e564c9efdbe7621704e222b53bac265b0e4fbea788f07c814094f0ec6b80adcf", size = 209397, upload-time = "2025-02-19T13:55:50.853Z" },
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "pyarrow"
|
name = "pyarrow"
|
||||||
version = "22.0.0"
|
version = "22.0.0"
|
||||||
@@ -1174,6 +1432,21 @@ dependencies = [
|
|||||||
{ name = "urllib3" },
|
{ name = "urllib3" },
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "qdrant-edge-py"
|
||||||
|
version = "0.5.0"
|
||||||
|
source = { registry = "https://pypi.org/simple" }
|
||||||
|
wheels = [
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/b5/74/aa0f9f593325104c72ecd127536af5997e04a9c66b43115fb272f704b130/qdrant_edge_py-0.5.0-cp310-abi3-macosx_10_12_x86_64.whl", hash = "sha256:32e0e3a4a2356d1a9a8d8209084d529a09490c9750e11603d2a256470dbedd10", size = 8963017, upload-time = "2026-01-19T17:52:32.879Z" },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/bd/e9/2fe177ca4e35fc89ff0b57f194c4272c9d61776243438e70c4a0df493f7b/qdrant_edge_py-0.5.0-cp310-abi3-macosx_11_0_arm64.whl", hash = "sha256:374e8c401713d467dac505abc3c6634bec482cb795961e56e8e4c0eafb49afe8", size = 8630038, upload-time = "2026-01-19T17:52:35.424Z" },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/60/4c/4267e4b0d227b4fb1a083f9fb0bd86f3601b6afd8eaf82d617199395f45a/qdrant_edge_py-0.5.0-cp310-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e92309e0ceb67b129ca9cfe97c158cc1d974b34ce109f127be7ced83fc87f95f", size = 9368631, upload-time = "2026-01-19T17:52:37.428Z" },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/af/e4/1c046502d10e944ae3eb49b7893668c9a7422044b4de5d77420696f1eadd/qdrant_edge_py-0.5.0-cp310-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:fb3f776c78639780a19732548737c926ea9f80f0565ab64560aba5560abc568a", size = 9094018, upload-time = "2026-01-19T17:52:39.197Z" },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/60/e3/ed0f644f573a20b8ab03d4eef900a12fe02aad592093a9e40f485bd043b7/qdrant_edge_py-0.5.0-cp310-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:04919c193050907d12775b3232796af64a85f751750bf93dc451ef2968865f19", size = 9368787, upload-time = "2026-01-19T17:52:40.999Z" },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/63/71/9399389978aacc341802a80bd6bc44d6106c669b8c58750072a032535661/qdrant_edge_py-0.5.0-cp310-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:30d11c321c579ed5f71532b99ca3b1ca33cb1ca2419ae0944830edfaab4b7a47", size = 9276227, upload-time = "2026-01-19T17:52:42.987Z" },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/06/3e/8b923b96593201e9d9a00361c456bd6b3559b9204ee913ded80d5fae10af/qdrant_edge_py-0.5.0-cp310-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:5172665b9db5a26f167a20c5094b1f6081ef17797d02829811e62a6cbb516293", size = 9608614, upload-time = "2026-01-19T17:52:44.793Z" },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/47/56/5da083ed1e37c0ab20dbcfef5fb9b42d2e75a648a543de260a21e0adbe30/qdrant_edge_py-0.5.0-cp310-abi3-win_amd64.whl", hash = "sha256:a6706401b1cc7d683e454ce0e76aa31d6664ec04b94bbc8c79268f082943657b", size = 8971559, upload-time = "2026-01-19T17:52:46.91Z" },
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "requests"
|
name = "requests"
|
||||||
version = "2.32.5"
|
version = "2.32.5"
|
||||||
@@ -1222,7 +1495,9 @@ version = "0.1.0"
|
|||||||
source = { virtual = "." }
|
source = { virtual = "." }
|
||||||
dependencies = [
|
dependencies = [
|
||||||
{ name = "datasets" },
|
{ name = "datasets" },
|
||||||
|
{ name = "fastembed" },
|
||||||
{ name = "qdrant-client" },
|
{ name = "qdrant-client" },
|
||||||
|
{ name = "qdrant-edge-py" },
|
||||||
]
|
]
|
||||||
|
|
||||||
[package.dev-dependencies]
|
[package.dev-dependencies]
|
||||||
@@ -1233,12 +1508,52 @@ dev = [
|
|||||||
[package.metadata]
|
[package.metadata]
|
||||||
requires-dist = [
|
requires-dist = [
|
||||||
{ name = "datasets", specifier = ">=4.4.1" },
|
{ name = "datasets", specifier = ">=4.4.1" },
|
||||||
|
{ name = "fastembed" },
|
||||||
{ name = "qdrant-client", git = "https://github.com/qdrant/qdrant-client?tag=v1.17.0" },
|
{ name = "qdrant-client", git = "https://github.com/qdrant/qdrant-client?tag=v1.17.0" },
|
||||||
|
{ name = "qdrant-edge-py" },
|
||||||
]
|
]
|
||||||
|
|
||||||
[package.metadata.requires-dev]
|
[package.metadata.requires-dev]
|
||||||
dev = [{ name = "mypy", specifier = ">=1.18.2" }]
|
dev = [{ name = "mypy", specifier = ">=1.18.2" }]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "sympy"
|
||||||
|
version = "1.14.0"
|
||||||
|
source = { registry = "https://pypi.org/simple" }
|
||||||
|
dependencies = [
|
||||||
|
{ name = "mpmath" },
|
||||||
|
]
|
||||||
|
sdist = { url = "https://files.pythonhosted.org/packages/83/d3/803453b36afefb7c2bb238361cd4ae6125a569b4db67cd9e79846ba2d68c/sympy-1.14.0.tar.gz", hash = "sha256:d3d3fe8df1e5a0b42f0e7bdf50541697dbe7d23746e894990c030e2b05e72517", size = 7793921, upload-time = "2025-04-27T18:05:01.611Z" }
|
||||||
|
wheels = [
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/a2/09/77d55d46fd61b4a135c444fc97158ef34a095e5681d0a6c10b75bf356191/sympy-1.14.0-py3-none-any.whl", hash = "sha256:e091cc3e99d2141a0ba2847328f5479b05d94a6635cb96148ccb3f34671bd8f5", size = 6299353, upload-time = "2025-04-27T18:04:59.103Z" },
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "tokenizers"
|
||||||
|
version = "0.22.2"
|
||||||
|
source = { registry = "https://pypi.org/simple" }
|
||||||
|
dependencies = [
|
||||||
|
{ name = "huggingface-hub" },
|
||||||
|
]
|
||||||
|
sdist = { url = "https://files.pythonhosted.org/packages/73/6f/f80cfef4a312e1fb34baf7d85c72d4411afde10978d4657f8cdd811d3ccc/tokenizers-0.22.2.tar.gz", hash = "sha256:473b83b915e547aa366d1eee11806deaf419e17be16310ac0a14077f1e28f917", size = 372115, upload-time = "2026-01-05T10:45:15.988Z" }
|
||||||
|
wheels = [
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/92/97/5dbfabf04c7e348e655e907ed27913e03db0923abb5dfdd120d7b25630e1/tokenizers-0.22.2-cp39-abi3-macosx_10_12_x86_64.whl", hash = "sha256:544dd704ae7238755d790de45ba8da072e9af3eea688f698b137915ae959281c", size = 3100275, upload-time = "2026-01-05T10:41:02.158Z" },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/2e/47/174dca0502ef88b28f1c9e06b73ce33500eedfac7a7692108aec220464e7/tokenizers-0.22.2-cp39-abi3-macosx_11_0_arm64.whl", hash = "sha256:1e418a55456beedca4621dbab65a318981467a2b188e982a23e117f115ce5001", size = 2981472, upload-time = "2026-01-05T10:41:00.276Z" },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/d6/84/7990e799f1309a8b87af6b948f31edaa12a3ed22d11b352eaf4f4b2e5753/tokenizers-0.22.2-cp39-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2249487018adec45d6e3554c71d46eb39fa8ea67156c640f7513eb26f318cec7", size = 3290736, upload-time = "2026-01-05T10:40:32.165Z" },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/78/59/09d0d9ba94dcd5f4f1368d4858d24546b4bdc0231c2354aa31d6199f0399/tokenizers-0.22.2-cp39-abi3-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:25b85325d0815e86e0bac263506dd114578953b7b53d7de09a6485e4a160a7dd", size = 3168835, upload-time = "2026-01-05T10:40:38.847Z" },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/47/50/b3ebb4243e7160bda8d34b731e54dd8ab8b133e50775872e7a434e524c28/tokenizers-0.22.2-cp39-abi3-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:bfb88f22a209ff7b40a576d5324bf8286b519d7358663db21d6246fb17eea2d5", size = 3521673, upload-time = "2026-01-05T10:40:56.614Z" },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/e0/fa/89f4cb9e08df770b57adb96f8cbb7e22695a4cb6c2bd5f0c4f0ebcf33b66/tokenizers-0.22.2-cp39-abi3-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1c774b1276f71e1ef716e5486f21e76333464f47bece56bbd554485982a9e03e", size = 3724818, upload-time = "2026-01-05T10:40:44.507Z" },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/64/04/ca2363f0bfbe3b3d36e95bf67e56a4c88c8e3362b658e616d1ac185d47f2/tokenizers-0.22.2-cp39-abi3-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:df6c4265b289083bf710dff49bc51ef252f9d5be33a45ee2bed151114a56207b", size = 3379195, upload-time = "2026-01-05T10:40:51.139Z" },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/2e/76/932be4b50ef6ccedf9d3c6639b056a967a86258c6d9200643f01269211ca/tokenizers-0.22.2-cp39-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:369cc9fc8cc10cb24143873a0d95438bb8ee257bb80c71989e3ee290e8d72c67", size = 3274982, upload-time = "2026-01-05T10:40:58.331Z" },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/1d/28/5f9f5a4cc211b69e89420980e483831bcc29dade307955cc9dc858a40f01/tokenizers-0.22.2-cp39-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:29c30b83d8dcd061078b05ae0cb94d3c710555fbb44861139f9f83dcca3dc3e4", size = 9478245, upload-time = "2026-01-05T10:41:04.053Z" },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/6c/fb/66e2da4704d6aadebf8cb39f1d6d1957df667ab24cff2326b77cda0dcb85/tokenizers-0.22.2-cp39-abi3-musllinux_1_2_armv7l.whl", hash = "sha256:37ae80a28c1d3265bb1f22464c856bd23c02a05bb211e56d0c5301a435be6c1a", size = 9560069, upload-time = "2026-01-05T10:45:10.673Z" },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/16/04/fed398b05caa87ce9b1a1bb5166645e38196081b225059a6edaff6440fac/tokenizers-0.22.2-cp39-abi3-musllinux_1_2_i686.whl", hash = "sha256:791135ee325f2336f498590eb2f11dc5c295232f288e75c99a36c5dbce63088a", size = 9899263, upload-time = "2026-01-05T10:45:12.559Z" },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/05/a1/d62dfe7376beaaf1394917e0f8e93ee5f67fea8fcf4107501db35996586b/tokenizers-0.22.2-cp39-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:38337540fbbddff8e999d59970f3c6f35a82de10053206a7562f1ea02d046fa5", size = 10033429, upload-time = "2026-01-05T10:45:14.333Z" },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/fd/18/a545c4ea42af3df6effd7d13d250ba77a0a86fb20393143bbb9a92e434d4/tokenizers-0.22.2-cp39-abi3-win32.whl", hash = "sha256:a6bf3f88c554a2b653af81f3204491c818ae2ac6fbc09e76ef4773351292bc92", size = 2502363, upload-time = "2026-01-05T10:45:20.593Z" },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/65/71/0670843133a43d43070abeb1949abfdef12a86d490bea9cd9e18e37c5ff7/tokenizers-0.22.2-cp39-abi3-win_amd64.whl", hash = "sha256:c9ea31edff2968b44a88f97d784c2f16dc0729b8b143ed004699ebca91f05c48", size = 2747786, upload-time = "2026-01-05T10:45:18.411Z" },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/72/f4/0de46cfa12cdcbcd464cc59fde36912af405696f687e53a091fb432f694c/tokenizers-0.22.2-cp39-abi3-win_arm64.whl", hash = "sha256:9ce725d22864a1e965217204946f830c37876eee3b2ba6fc6255e8e903d5fcbc", size = 2612133, upload-time = "2026-01-05T10:45:17.232Z" },
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "tqdm"
|
name = "tqdm"
|
||||||
version = "4.67.1"
|
version = "4.67.1"
|
||||||
@@ -1303,6 +1618,15 @@ wheels = [
|
|||||||
{ url = "https://files.pythonhosted.org/packages/a7/c2/fe1e52489ae3122415c51f387e221dd0773709bad6c6cdaa599e8a2c5185/urllib3-2.5.0-py3-none-any.whl", hash = "sha256:e6b01673c0fa6a13e374b50871808eb3bf7046c4b125b216f6bf1cc604cff0dc", size = 129795, upload-time = "2025-06-18T14:07:40.39Z" },
|
{ url = "https://files.pythonhosted.org/packages/a7/c2/fe1e52489ae3122415c51f387e221dd0773709bad6c6cdaa599e8a2c5185/urllib3-2.5.0-py3-none-any.whl", hash = "sha256:e6b01673c0fa6a13e374b50871808eb3bf7046c4b125b216f6bf1cc604cff0dc", size = 129795, upload-time = "2025-06-18T14:07:40.39Z" },
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "win32-setctime"
|
||||||
|
version = "1.2.0"
|
||||||
|
source = { registry = "https://pypi.org/simple" }
|
||||||
|
sdist = { url = "https://files.pythonhosted.org/packages/b3/8f/705086c9d734d3b663af0e9bb3d4de6578d08f46b1b101c2442fd9aecaa2/win32_setctime-1.2.0.tar.gz", hash = "sha256:ae1fdf948f5640aae05c511ade119313fb6a30d7eabe25fef9764dca5873c4c0", size = 4867, upload-time = "2024-12-07T15:28:28.314Z" }
|
||||||
|
wheels = [
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/e1/07/c6fe3ad3e685340704d314d765b7912993bcb8dc198f0e7a89382d37974b/win32_setctime-1.2.0-py3-none-any.whl", hash = "sha256:95d644c4e708aba81dc3704a116d8cbc974d70b3bdb8be1d150e36be6e9d1390", size = 4083, upload-time = "2024-12-07T15:28:26.465Z" },
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "xxhash"
|
name = "xxhash"
|
||||||
version = "3.6.0"
|
version = "3.6.0"
|
||||||
|
|||||||
@@ -17,43 +17,13 @@ When creating a snapshot for synchronization, specify the applicable server-side
|
|||||||
|
|
||||||
First, craft a snapshot URL:
|
First, craft a snapshot URL:
|
||||||
|
|
||||||
```python
|
{{< code-snippet path="/documentation/headless/snippets/edge/synchronization-patterns/" block="snapshot-url" >}}
|
||||||
COLLECTION_NAME="edge-collection"
|
|
||||||
|
|
||||||
snapshot_url = f"{QDRANT_URL}/collections/{COLLECTION_NAME}/shards/0/snapshot"
|
|
||||||
```
|
|
||||||
|
|
||||||
Note that this example uses shard ID `0`.
|
Note that this example uses shard ID `0`.
|
||||||
|
|
||||||
Using the snapshot URL, you can download the snapshot to the local disk and use its data to initialize a new Edge Shard.
|
Using the snapshot URL, you can download the snapshot to the local disk and use its data to initialize a new Edge Shard.
|
||||||
|
|
||||||
```python
|
{{< code-snippet path="/documentation/headless/snippets/edge/synchronization-patterns/" block="restore-snapshot" >}}
|
||||||
from pathlib import Path
|
|
||||||
from qdrant_edge import EdgeShard
|
|
||||||
import requests
|
|
||||||
import shutil
|
|
||||||
import tempfile
|
|
||||||
|
|
||||||
SHARD_DIRECTORY = "./qdrant-edge-directory"
|
|
||||||
data_dir = Path(SHARD_DIRECTORY)
|
|
||||||
|
|
||||||
with tempfile.TemporaryDirectory(dir=data_dir.parent) as restore_dir:
|
|
||||||
snapshot_path = Path(restore_dir) / "shard.snapshot"
|
|
||||||
|
|
||||||
with requests.get(snapshot_url, headers={"api-key": QDRANT_API_KEY}, stream=True) as r:
|
|
||||||
r.raise_for_status()
|
|
||||||
with open(snapshot_path, "wb") as f:
|
|
||||||
for chunk in r.iter_content(chunk_size=8192):
|
|
||||||
f.write(chunk)
|
|
||||||
|
|
||||||
if data_dir.exists():
|
|
||||||
shutil.rmtree(data_dir)
|
|
||||||
data_dir.mkdir(parents=True, exist_ok=True)
|
|
||||||
|
|
||||||
EdgeShard.unpack_snapshot(str(snapshot_path), str(data_dir))
|
|
||||||
|
|
||||||
edge_shard = EdgeShard(SHARD_DIRECTORY)
|
|
||||||
```
|
|
||||||
|
|
||||||
This code first downloads the snapshot to a temporary directory. Next, `EdgeShard.unpack_snapshot` unpacks the downloaded snapshot into the data directory, and a new instance of `EdgeShard` is created using the unpacked snapshot's data and configuration.
|
This code first downloads the snapshot to a temporary directory. Next, `EdgeShard.unpack_snapshot` unpacks the downloaded snapshot into the data directory, and a new instance of `EdgeShard` is created using the unpacked snapshot's data and configuration.
|
||||||
|
|
||||||
@@ -63,22 +33,7 @@ The `edge_shard` will use the same configuration and the same file structure as
|
|||||||
|
|
||||||
To keep an Edge Shard updated with new data from a server collection, you can periodically download and apply a snapshot. Restoring a full snapshot every time would create unnecessary overhead. Instead, you can use partial snapshots to restore changes since the last snapshot. A partial snapshot contains only those segments that have changed, based on the Edge Shard's manifest that describes all its segments and metadata. The `EdgeShard` class provides an `update_from_snapshot` method to update an Edge Shard from a partial snapshot.
|
To keep an Edge Shard updated with new data from a server collection, you can periodically download and apply a snapshot. Restoring a full snapshot every time would create unnecessary overhead. Instead, you can use partial snapshots to restore changes since the last snapshot. A partial snapshot contains only those segments that have changed, based on the Edge Shard's manifest that describes all its segments and metadata. The `EdgeShard` class provides an `update_from_snapshot` method to update an Edge Shard from a partial snapshot.
|
||||||
|
|
||||||
```Python
|
{{< code-snippet path="/documentation/headless/snippets/edge/synchronization-patterns/" block="update-from-snapshot" >}}
|
||||||
manifest = edge_shard.snapshot_manifest()
|
|
||||||
|
|
||||||
url = f"{QDRANT_URL}/collections/{COLLECTION_NAME}/shards/0/snapshot/partial/create"
|
|
||||||
|
|
||||||
with tempfile.TemporaryDirectory(dir=data_dir) as temp_dir:
|
|
||||||
partial_snapshot_path = Path(temp_dir) / "partial.snapshot"
|
|
||||||
response = requests.post(url, headers={"api-key": QDRANT_API_KEY}, json=manifest, stream=True)
|
|
||||||
response.raise_for_status()
|
|
||||||
|
|
||||||
with open(partial_snapshot_path, "wb") as f:
|
|
||||||
for chunk in response.iter_content(chunk_size=8192):
|
|
||||||
f.write(chunk)
|
|
||||||
|
|
||||||
edge_shard.update_from_snapshot(str(partial_snapshot_path))
|
|
||||||
```
|
|
||||||
|
|
||||||
## Update a Server Collection from an Edge Shard
|
## Update a Server Collection from an Edge Shard
|
||||||
|
|
||||||
@@ -94,99 +49,24 @@ First, initialize:
|
|||||||
<summary>Details</summary>
|
<summary>Details</summary>
|
||||||
|
|
||||||
Initialize an Edge Shard:
|
Initialize an Edge Shard:
|
||||||
```python
|
{{< code-snippet path="/documentation/headless/snippets/edge/synchronization-patterns/" block="initialize-edge-shard" >}}
|
||||||
from pathlib import Path
|
|
||||||
from qdrant_edge import (
|
|
||||||
Distance,
|
|
||||||
EdgeConfig,
|
|
||||||
VectorDataConfig,
|
|
||||||
)
|
|
||||||
|
|
||||||
SHARD_DIRECTORY = "./qdrant-edge-directory"
|
|
||||||
VECTOR_NAME="my-vector"
|
|
||||||
VECTOR_DIMENSION=4
|
|
||||||
|
|
||||||
Path(SHARD_DIRECTORY).mkdir(parents=True, exist_ok=True)
|
|
||||||
config = EdgeConfig(
|
|
||||||
vector_data={
|
|
||||||
VECTOR_NAME: VectorDataConfig(
|
|
||||||
size=VECTOR_DIMENSION,
|
|
||||||
distance=Distance.Cosine,
|
|
||||||
)
|
|
||||||
}
|
|
||||||
)
|
|
||||||
|
|
||||||
edge_shard = EdgeShard(SHARD_DIRECTORY, config)
|
|
||||||
```
|
|
||||||
|
|
||||||
Initialize a Qdrant client connection to the server and create the target collection if it does not exist:
|
Initialize a Qdrant client connection to the server and create the target collection if it does not exist:
|
||||||
|
|
||||||
```python
|
{{< code-snippet path="/documentation/headless/snippets/edge/synchronization-patterns/" block="initialize-server-client" >}}
|
||||||
from qdrant_client import QdrantClient, models
|
|
||||||
|
|
||||||
server_client = QdrantClient(url=QDRANT_URL, api_key=QDRANT_API_KEY)
|
|
||||||
|
|
||||||
COLLECTION_NAME="edge-collection"
|
|
||||||
|
|
||||||
if not server_client.collection_exists(collection_name=COLLECTION_NAME):
|
|
||||||
|
|
||||||
server_client.create_collection(
|
|
||||||
collection_name=COLLECTION_NAME,
|
|
||||||
vectors_config={VECTOR_NAME: models.VectorParams(size=VECTOR_DIMENSION, distance=models.Distance.COSINE)}
|
|
||||||
)
|
|
||||||
```
|
|
||||||
</details>
|
</details>
|
||||||
|
|
||||||
Next, instantiate the queue that will hold the points that need to be synchronized with the server:
|
Next, instantiate the queue that will hold the points that need to be synchronized with the server:
|
||||||
|
|
||||||
```python
|
{{< code-snippet path="/documentation/headless/snippets/edge/synchronization-patterns/" block="create-upload-queue" >}}
|
||||||
from queue import Empty, Queue
|
|
||||||
|
|
||||||
# This is in-memory queue
|
|
||||||
# For production use cases consider persisting changes
|
|
||||||
upload_queue = Queue()
|
|
||||||
```
|
|
||||||
|
|
||||||
When adding or updating points in the Edge Shard, also enqueue the point for synchronization with the server.
|
When adding or updating points in the Edge Shard, also enqueue the point for synchronization with the server.
|
||||||
|
|
||||||
```python
|
{{< code-snippet path="/documentation/headless/snippets/edge/synchronization-patterns/" block="upsert-point" >}}
|
||||||
from qdrant_edge import ( Point, UpdateOperation )
|
|
||||||
from qdrant_client import models
|
|
||||||
|
|
||||||
id=1
|
|
||||||
vector=[0.1, 0.2, 0.3, 0.4]
|
|
||||||
payload={"color": "red"}
|
|
||||||
|
|
||||||
point = Point(
|
|
||||||
id=id,
|
|
||||||
vector={VECTOR_NAME: vector},
|
|
||||||
payload=payload
|
|
||||||
)
|
|
||||||
|
|
||||||
edge_shard.update(UpdateOperation.upsert_points([point]))
|
|
||||||
|
|
||||||
rest_point = models.PointStruct(id=id, vector={VECTOR_NAME: vector}, payload=payload)
|
|
||||||
|
|
||||||
upload_queue.put(rest_point)
|
|
||||||
```
|
|
||||||
|
|
||||||
A background worker can process the upload queue and synchronize points with the server collection.
|
A background worker can process the upload queue and synchronize points with the server collection.
|
||||||
This example uploads points in batches of up to 10 points at a time:
|
This example uploads points in batches of up to 10 points at a time:
|
||||||
|
|
||||||
```python
|
{{< code-snippet path="/documentation/headless/snippets/edge/synchronization-patterns/" block="process-upload-queue" >}}
|
||||||
BATCH_SIZE = 10
|
|
||||||
points_to_upload = []
|
|
||||||
|
|
||||||
while len(points_to_upload) < BATCH_SIZE:
|
|
||||||
try:
|
|
||||||
points_to_upload.append(upload_queue.get_nowait())
|
|
||||||
except Empty:
|
|
||||||
break
|
|
||||||
|
|
||||||
if points_to_upload:
|
|
||||||
server_client.upsert(
|
|
||||||
collection_name=COLLECTION_NAME, points=points_to_upload
|
|
||||||
)
|
|
||||||
```
|
|
||||||
|
|
||||||
Make sure to properly handle errors and retries in case of network issues or server unavailability.
|
Make sure to properly handle errors and retries in case of network issues or server unavailability.
|
||||||
|
|||||||
@@ -17,23 +17,7 @@ pip install fastembed qdrant-edge-py
|
|||||||
|
|
||||||
Next, download the embedding models and save them locally on the device. Instantiate instances of `ImageEmbedding` and `TextEmbedding`, setting the `cache_dir` parameter to a local directory:
|
Next, download the embedding models and save them locally on the device. Instantiate instances of `ImageEmbedding` and `TextEmbedding`, setting the `cache_dir` parameter to a local directory:
|
||||||
|
|
||||||
```python
|
{{< code-snippet path="/documentation/headless/snippets/edge/fastembed/" block="download-models" >}}
|
||||||
from fastembed import ImageEmbedding, TextEmbedding
|
|
||||||
|
|
||||||
TEXT_MODEL_NAME='Qdrant/clip-ViT-B-32-text'
|
|
||||||
VISION_MODEL_NAME='Qdrant/clip-ViT-B-32-vision'
|
|
||||||
MODELS_DIR="./qdrant-edge-directory/models"
|
|
||||||
|
|
||||||
ImageEmbedding(
|
|
||||||
model_name=VISION_MODEL_NAME,
|
|
||||||
cache_dir=MODELS_DIR
|
|
||||||
)
|
|
||||||
|
|
||||||
TextEmbedding(
|
|
||||||
model_name=TEXT_MODEL_NAME,
|
|
||||||
cache_dir=MODELS_DIR
|
|
||||||
)
|
|
||||||
```
|
|
||||||
|
|
||||||
The models will be downloaded and cached in the specified `MODELS_DIR` directory, from where you can use them to generate embeddings.
|
The models will be downloaded and cached in the specified `MODELS_DIR` directory, from where you can use them to generate embeddings.
|
||||||
|
|
||||||
@@ -44,58 +28,13 @@ First, initialize an Edge Shard as described in the [Qdrant Edge Quickstart Guid
|
|||||||
<details>
|
<details>
|
||||||
<summary>Details</summary>
|
<summary>Details</summary>
|
||||||
|
|
||||||
```python
|
{{< code-snippet path="/documentation/headless/snippets/edge/fastembed/" block="initialize-edge-shard" >}}
|
||||||
from pathlib import Path
|
|
||||||
from qdrant_edge import (
|
|
||||||
Distance,
|
|
||||||
EdgeConfig,
|
|
||||||
EdgeShard,
|
|
||||||
VectorDataConfig,
|
|
||||||
)
|
|
||||||
|
|
||||||
SHARD_DIRECTORY = "./qdrant-edge-directory"
|
|
||||||
VECTOR_DIMENSION = 512
|
|
||||||
VECTOR_NAME="my-vector"
|
|
||||||
|
|
||||||
Path(SHARD_DIRECTORY).mkdir(parents=True, exist_ok=True)
|
|
||||||
config = EdgeConfig(
|
|
||||||
vector_data={
|
|
||||||
VECTOR_NAME: VectorDataConfig(
|
|
||||||
size=VECTOR_DIMENSION,
|
|
||||||
distance=Distance.Cosine,
|
|
||||||
)
|
|
||||||
}
|
|
||||||
)
|
|
||||||
|
|
||||||
edge_shard = EdgeShard(SHARD_DIRECTORY, config)
|
|
||||||
```
|
|
||||||
|
|
||||||
</details>
|
</details>
|
||||||
|
|
||||||
Assuming you have an image file `temp.jpg`, you can generate an embedding for it using FastEmbed's `ImageEmbedding` class and then store it in the Edge Shard:
|
Assuming you have an image file `temp.jpg`, you can generate an embedding for it using FastEmbed's `ImageEmbedding` class and then store it in the Edge Shard:
|
||||||
|
|
||||||
```python
|
{{< code-snippet path="/documentation/headless/snippets/edge/fastembed/" block="embed-and-store-image" >}}
|
||||||
from pathlib import Path
|
|
||||||
from qdrant_edge import Point, UpdateOperation
|
|
||||||
import uuid
|
|
||||||
|
|
||||||
IMAGES_DIR = "images"
|
|
||||||
|
|
||||||
model = ImageEmbedding(
|
|
||||||
model_name=VISION_MODEL_NAME,
|
|
||||||
cache_dir=MODELS_DIR,
|
|
||||||
local_files_only=True
|
|
||||||
)
|
|
||||||
|
|
||||||
embeddings = list(model.embed([Path(IMAGES_DIR) / "temp.jpg"]))[0]
|
|
||||||
|
|
||||||
point = Point(
|
|
||||||
id=str(uuid.uuid4()),
|
|
||||||
vector={VECTOR_NAME: embeddings.tolist()}
|
|
||||||
)
|
|
||||||
|
|
||||||
edge_shard.update(UpdateOperation.upsert_points([point]))
|
|
||||||
```
|
|
||||||
|
|
||||||
Note the use of `cache_dir=MODELS_DIR` and `local_files_only=True` to load the image embedding model from the local directory where it was previously downloaded.
|
Note the use of `cache_dir=MODELS_DIR` and `local_files_only=True` to load the image embedding model from the local directory where it was previously downloaded.
|
||||||
|
|
||||||
@@ -103,25 +42,6 @@ Note the use of `cache_dir=MODELS_DIR` and `local_files_only=True` to load the i
|
|||||||
|
|
||||||
At query time, you can generate text embeddings using FastEmbed's `TextEmbedding` class. For example, to query the Edge Shard:
|
At query time, you can generate text embeddings using FastEmbed's `TextEmbedding` class. For example, to query the Edge Shard:
|
||||||
|
|
||||||
```python
|
{{< code-snippet path="/documentation/headless/snippets/edge/fastembed/" block="query-with-text-embedding" >}}
|
||||||
from qdrant_edge import Query, QueryRequest
|
|
||||||
|
|
||||||
model = TextEmbedding(
|
|
||||||
model_name=TEXT_MODEL_NAME,
|
|
||||||
cache_dir=MODELS_DIR,
|
|
||||||
local_files_only=True
|
|
||||||
)
|
|
||||||
|
|
||||||
embeddings = list(model.embed(["<search terms>"]))[0]
|
|
||||||
|
|
||||||
results = edge_shard.query(
|
|
||||||
QueryRequest(
|
|
||||||
query=Query.Nearest(embeddings.tolist(),using=VECTOR_NAME),
|
|
||||||
limit=10,
|
|
||||||
with_vector=False,
|
|
||||||
with_payload=True
|
|
||||||
)
|
|
||||||
)
|
|
||||||
```
|
|
||||||
|
|
||||||
Again, using `cache_dir=MODELS_DIR` and `local_files_only=True` ensures the text embedding model is loaded from the local directory.
|
Again, using `cache_dir=MODELS_DIR` and `local_files_only=True` ensures the text embedding model is loaded from the local directory.
|
||||||
@@ -17,106 +17,47 @@ pip install qdrant-edge-py
|
|||||||
|
|
||||||
A Qdrant Edge Shard stores its data in a local directory on disk. Create the directory if it doesn't exist yet:
|
A Qdrant Edge Shard stores its data in a local directory on disk. Create the directory if it doesn't exist yet:
|
||||||
|
|
||||||
```python
|
{{< code-snippet path="/documentation/headless/snippets/edge/quickstart/" block="create-storage-directory" >}}
|
||||||
from pathlib import Path
|
|
||||||
|
|
||||||
SHARD_DIRECTORY = "./qdrant-edge-directory"
|
|
||||||
|
|
||||||
Path(SHARD_DIRECTORY).mkdir(parents=True, exist_ok=True)
|
|
||||||
```
|
|
||||||
|
|
||||||
## Configure the Edge Shard
|
## Configure the Edge Shard
|
||||||
|
|
||||||
An Edge Shard is configured with a definition of the dense and sparse vectors that can be stored in the Edge Shard, similar to how you would configure a Qdrant collection. Set up a configuration by creating an instance of `EdgeConfig`:
|
An Edge Shard is configured with a definition of the dense and sparse vectors that can be stored in the Edge Shard, similar to how you would configure a Qdrant collection. Set up a configuration by creating an instance of `EdgeConfig`:
|
||||||
|
|
||||||
```python
|
{{< code-snippet path="/documentation/headless/snippets/edge/quickstart/" block="configure-edge-shard" >}}
|
||||||
from qdrant_edge import (
|
|
||||||
Distance,
|
|
||||||
EdgeConfig,
|
|
||||||
VectorDataConfig,
|
|
||||||
)
|
|
||||||
|
|
||||||
VECTOR_NAME="my-vector"
|
|
||||||
VECTOR_DIMENSION=4
|
|
||||||
|
|
||||||
config = EdgeConfig(
|
|
||||||
vector_data={
|
|
||||||
VECTOR_NAME: VectorDataConfig(
|
|
||||||
size=VECTOR_DIMENSION,
|
|
||||||
distance=Distance.Cosine,
|
|
||||||
)
|
|
||||||
}
|
|
||||||
)
|
|
||||||
```
|
|
||||||
|
|
||||||
## Initialize the Edge Shard
|
## Initialize the Edge Shard
|
||||||
|
|
||||||
Now you can create an instance of `EdgeShard` with the storage directory and the configuration:
|
Now you can create an instance of `EdgeShard` with the storage directory and the configuration:
|
||||||
|
|
||||||
```python
|
{{< code-snippet path="/documentation/headless/snippets/edge/quickstart/" block="initialize-edge-shard" >}}
|
||||||
from qdrant_edge import EdgeShard
|
|
||||||
|
|
||||||
edge_shard = EdgeShard(SHARD_DIRECTORY, config)
|
|
||||||
```
|
|
||||||
|
|
||||||
## Work with Points
|
## Work with Points
|
||||||
|
|
||||||
An Edge Shard has several methods to work with points. To add points, use the `update` method:
|
An Edge Shard has several methods to work with points. To add points, use the `update` method:
|
||||||
|
|
||||||
```python
|
{{< code-snippet path="/documentation/headless/snippets/edge/quickstart/" block="upsert-points" >}}
|
||||||
from qdrant_edge import ( Point, UpdateOperation )
|
|
||||||
|
|
||||||
point = Point(
|
|
||||||
id=1,
|
|
||||||
vector={VECTOR_NAME: [0.1, 0.2, 0.3, 0.4]},
|
|
||||||
payload={"color": "red"}
|
|
||||||
)
|
|
||||||
|
|
||||||
edge_shard.update(UpdateOperation.upsert_points([point]))
|
|
||||||
```
|
|
||||||
|
|
||||||
To retrieve a point by ID, use the `retrieve` method:
|
To retrieve a point by ID, use the `retrieve` method:
|
||||||
|
|
||||||
```python
|
{{< code-snippet path="/documentation/headless/snippets/edge/quickstart/" block="retrieve-point" >}}
|
||||||
point = edge_shard.retrieve(
|
|
||||||
point_ids=[1],
|
|
||||||
with_payload=True,
|
|
||||||
with_vector=False
|
|
||||||
)
|
|
||||||
```
|
|
||||||
|
|
||||||
## Query Points
|
## Query Points
|
||||||
|
|
||||||
To query points in the Edge Shard, use the `query` method:
|
To query points in the Edge Shard, use the `query` method:
|
||||||
|
|
||||||
```python
|
{{< code-snippet path="/documentation/headless/snippets/edge/quickstart/" block="query-points" >}}
|
||||||
from qdrant_edge import Query, QueryRequest
|
|
||||||
|
|
||||||
results = edge_shard.query(
|
|
||||||
QueryRequest(
|
|
||||||
query=Query.Nearest([0.2, 0.1, 0.9, 0.7], using=VECTOR_NAME),
|
|
||||||
limit=10,
|
|
||||||
with_vector=False,
|
|
||||||
with_payload=True
|
|
||||||
)
|
|
||||||
)
|
|
||||||
```
|
|
||||||
|
|
||||||
## Close the Edge Shard
|
## Close the Edge Shard
|
||||||
|
|
||||||
When shutting down your application, close the Edge Shard to ensure all data is flushed to disk. The data is persisted on disk and can be used to reopen the Edge Shard.
|
When shutting down your application, close the Edge Shard to ensure all data is flushed to disk. The data is persisted on disk and can be used to reopen the Edge Shard.
|
||||||
|
|
||||||
```python
|
{{< code-snippet path="/documentation/headless/snippets/edge/quickstart/" block="close-edge-shard" >}}
|
||||||
edge_shard.close()
|
|
||||||
```
|
|
||||||
|
|
||||||
## Load Existing Edge Shard from Disk
|
## Load Existing Edge Shard from Disk
|
||||||
|
|
||||||
After closing an Edge Shard, you can reopen it by loading its data and configuration from disk. Create a new `EdgeShard` instance with the storage directory and provide `None` for the configuration:
|
After closing an Edge Shard, you can reopen it by loading its data and configuration from disk. Create a new `EdgeShard` instance with the storage directory:
|
||||||
|
|
||||||
```python
|
{{< code-snippet path="/documentation/headless/snippets/edge/quickstart/" block="load-edge-shard" >}}
|
||||||
edge_shard = EdgeShard(SHARD_DIRECTORY)
|
|
||||||
```
|
|
||||||
|
|
||||||
## More Examples
|
## More Examples
|
||||||
|
|
||||||
|
|||||||
@@ -31,98 +31,19 @@ For an example implementation of the patterns described in this guide, refer to
|
|||||||
|
|
||||||
The mutable Edge Shard will manage local data updates. It can be initialized from scratch, as detailed in the [Qdrant Edge Quickstart Guide](/documentation/edge/edge-quickstart/).
|
The mutable Edge Shard will manage local data updates. It can be initialized from scratch, as detailed in the [Qdrant Edge Quickstart Guide](/documentation/edge/edge-quickstart/).
|
||||||
|
|
||||||
```python
|
{{< code-snippet path="/documentation/headless/snippets/edge/synchronization-guide/" block="initialize-mutable-shard" >}}
|
||||||
from pathlib import Path
|
|
||||||
from qdrant_edge import (
|
|
||||||
Distance,
|
|
||||||
EdgeConfig,
|
|
||||||
EdgeShard,
|
|
||||||
VectorDataConfig,
|
|
||||||
)
|
|
||||||
|
|
||||||
MUTABLE_SHARD_DIR = "./qdrant-edge-directory/mutable"
|
|
||||||
|
|
||||||
Path(MUTABLE_SHARD_DIR).mkdir(parents=True, exist_ok=True)
|
|
||||||
|
|
||||||
VECTOR_NAME="my-vector"
|
|
||||||
VECTOR_DIMENSION=4
|
|
||||||
|
|
||||||
config = EdgeConfig(
|
|
||||||
vector_data={
|
|
||||||
VECTOR_NAME: VectorDataConfig(
|
|
||||||
size=VECTOR_DIMENSION,
|
|
||||||
distance=Distance.Cosine,
|
|
||||||
)
|
|
||||||
}
|
|
||||||
)
|
|
||||||
|
|
||||||
mutable_shard = EdgeShard(MUTABLE_SHARD_DIR, config)
|
|
||||||
```
|
|
||||||
|
|
||||||
### 2. Initialize an Immutable Edge Shard from a Server Snapshot
|
### 2. Initialize an Immutable Edge Shard from a Server Snapshot
|
||||||
|
|
||||||
Next, create the immutable Edge Shard from a snapshot on the server, as outlined in [Initialize Edge Shard from existing Qdrant Collection](/documentation/edge/edge-data-synchronization-patterns/#initialize-edge-shard-from-existing-qdrant-collection):
|
Next, create the immutable Edge Shard from a snapshot on the server, as outlined in [Initialize Edge Shard from existing Qdrant Collection](/documentation/edge/edge-data-synchronization-patterns/#initialize-edge-shard-from-existing-qdrant-collection):
|
||||||
|
|
||||||
```python
|
{{< code-snippet path="/documentation/headless/snippets/edge/synchronization-guide/" block="initialize-immutable-shard" >}}
|
||||||
import requests
|
|
||||||
import tempfile
|
|
||||||
import shutil
|
|
||||||
|
|
||||||
COLLECTION_NAME="edge-collection"
|
|
||||||
snapshot_url = f"{QDRANT_URL}/collections/{COLLECTION_NAME}/shards/0/snapshot"
|
|
||||||
|
|
||||||
IMMUTABLE_SHARD_DIR = "./qdrant-edge-directory/mutable"
|
|
||||||
data_dir = Path(IMMUTABLE_SHARD_DIR)
|
|
||||||
|
|
||||||
with tempfile.TemporaryDirectory(dir=data_dir.parent) as restore_dir:
|
|
||||||
snapshot_path = Path(restore_dir) / "shard.snapshot"
|
|
||||||
|
|
||||||
with requests.get(snapshot_url, headers={"api-key": QDRANT_API_KEY}, stream=True) as r:
|
|
||||||
r.raise_for_status()
|
|
||||||
with open(snapshot_path, "wb") as f:
|
|
||||||
for chunk in r.iter_content(chunk_size=8192):
|
|
||||||
f.write(chunk)
|
|
||||||
|
|
||||||
immutable_shard = None
|
|
||||||
if data_dir.exists():
|
|
||||||
shutil.rmtree(data_dir)
|
|
||||||
data_dir.mkdir(parents=True, exist_ok=True)
|
|
||||||
|
|
||||||
EdgeShard.unpack_snapshot(str(snapshot_path), str(data_dir))
|
|
||||||
|
|
||||||
immutable_shard = EdgeShard(IMMUTABLE_SHARD_DIR)
|
|
||||||
```
|
|
||||||
|
|
||||||
### 3. Implement a Dual-Write Mechanism
|
### 3. Implement a Dual-Write Mechanism
|
||||||
|
|
||||||
With both Edge Shards initialized, you can implement a dual-write mechanism in your application as outlined in [Update a Server Collection from an Edge Shard](/documentation/edge/edge-data-synchronization-patterns/#update-a-server-collection-from-an-edge-shard). When adding or updating a point, write it to the mutable Edge Shard and enqueue it for writing to the server collection.
|
With both Edge Shards initialized, you can implement a dual-write mechanism in your application as outlined in [Update a Server Collection from an Edge Shard](/documentation/edge/edge-data-synchronization-patterns/#update-a-server-collection-from-an-edge-shard). When adding or updating a point, write it to the mutable Edge Shard and enqueue it for writing to the server collection.
|
||||||
|
|
||||||
```python
|
{{< code-snippet path="/documentation/headless/snippets/edge/synchronization-guide/" block="dual-write" >}}
|
||||||
from qdrant_edge import ( Point, UpdateOperation )
|
|
||||||
from qdrant_client import models
|
|
||||||
import time
|
|
||||||
|
|
||||||
SYNC_TIMESTAMP_KEY="timestamp"
|
|
||||||
|
|
||||||
id=2
|
|
||||||
vector=[0.4, 0.3, 0.2, 0.1]
|
|
||||||
payload={
|
|
||||||
"color": "green",
|
|
||||||
SYNC_TIMESTAMP_KEY: time.time()
|
|
||||||
}
|
|
||||||
|
|
||||||
point = Point(
|
|
||||||
id=id,
|
|
||||||
vector={VECTOR_NAME: vector},
|
|
||||||
payload=payload
|
|
||||||
)
|
|
||||||
|
|
||||||
mutable_shard.update(UpdateOperation.upsert_points([point]))
|
|
||||||
|
|
||||||
rest_point = models.PointStruct(id=id, vector={VECTOR_NAME: vector}, payload=payload)
|
|
||||||
|
|
||||||
upload_queue.put(rest_point)
|
|
||||||
```
|
|
||||||
|
|
||||||
Each point's payload should include a timestamp field (`SYNC_TIMESTAMP_KEY` in this example) that records when the point was upserted. This timestamp is used to deduplicate data when the immutable Edge Shard is synchronized with the server.
|
Each point's payload should include a timestamp field (`SYNC_TIMESTAMP_KEY` in this example) that records when the point was upserted. This timestamp is used to deduplicate data when the immutable Edge Shard is synchronized with the server.
|
||||||
|
|
||||||
@@ -132,82 +53,17 @@ You can periodically update the immutable Edge Shard with changes from the serve
|
|||||||
|
|
||||||
While restoring a snapshot, you may want to pause and buffer any ongoing data updates on the mutable Edge Shard. Before taking the snapshot, ensure all queued data has been written to the server. After the restoration is complete, you can resume normal operations. Refer to the [Qdrant Edge Demo GitHub repository](https://github.com/qdrant/qdrant-edge-demo) for an example implementation.
|
While restoring a snapshot, you may want to pause and buffer any ongoing data updates on the mutable Edge Shard. Before taking the snapshot, ensure all queued data has been written to the server. After the restoration is complete, you can resume normal operations. Refer to the [Qdrant Edge Demo GitHub repository](https://github.com/qdrant/qdrant-edge-demo) for an example implementation.
|
||||||
|
|
||||||
```python
|
{{< code-snippet path="/documentation/headless/snippets/edge/synchronization-guide/" block="update-immutable-shard" >}}
|
||||||
import time
|
|
||||||
|
|
||||||
manifest = immutable_shard.snapshot_manifest()
|
|
||||||
|
|
||||||
url = f"{QDRANT_URL}/collections/{COLLECTION_NAME}/shards/0/snapshot/partial/create"
|
|
||||||
|
|
||||||
sync_timestamp = time.time()
|
|
||||||
|
|
||||||
with tempfile.TemporaryDirectory(dir=data_dir) as temp_dir:
|
|
||||||
partial_snapshot_path = Path(temp_dir) / "partial.snapshot"
|
|
||||||
response = requests.post(url, headers={"api-key": QDRANT_API_KEY}, json=manifest, stream=True)
|
|
||||||
response.raise_for_status()
|
|
||||||
|
|
||||||
with open(partial_snapshot_path, "wb") as f:
|
|
||||||
for chunk in response.iter_content(chunk_size=8192):
|
|
||||||
f.write(chunk)
|
|
||||||
|
|
||||||
immutable_shard.update_from_snapshot(str(partial_snapshot_path))
|
|
||||||
```
|
|
||||||
|
|
||||||
This example records a `sync_timestamp` at the time of creating the partial snapshot. All points that were added to the mutable Edge Shard before this timestamp are now restored to the immutable Edge Shard. These duplicate points can now be deleted from the mutable Edge Shard:
|
This example records a `sync_timestamp` at the time of creating the partial snapshot. All points that were added to the mutable Edge Shard before this timestamp are now restored to the immutable Edge Shard. These duplicate points can now be deleted from the mutable Edge Shard:
|
||||||
|
|
||||||
```python
|
{{< code-snippet path="/documentation/headless/snippets/edge/synchronization-guide/" block="delete-synced-points" >}}
|
||||||
from qdrant_edge import (
|
|
||||||
Filter,
|
|
||||||
FieldCondition,
|
|
||||||
RangeFloat
|
|
||||||
)
|
|
||||||
|
|
||||||
mutable_shard.update(
|
|
||||||
UpdateOperation.delete_points_by_filter(Filter(
|
|
||||||
must=[
|
|
||||||
FieldCondition(
|
|
||||||
key=SYNC_TIMESTAMP_KEY, range=RangeFloat(lte=sync_timestamp)
|
|
||||||
)
|
|
||||||
])
|
|
||||||
)
|
|
||||||
```
|
|
||||||
|
|
||||||
### 5. Query Both Edge Shards
|
### 5. Query Both Edge Shards
|
||||||
|
|
||||||
To provide a unified search experience across all data, query both the mutable and immutable Edge Shards and merge the two result sets. Since a point may exist in both Edge Shards, deduplicate the results based on point ID.
|
To provide a unified search experience across all data, query both the mutable and immutable Edge Shards and merge the two result sets. Since a point may exist in both Edge Shards, deduplicate the results based on point ID.
|
||||||
|
|
||||||
```python
|
{{< code-snippet path="/documentation/headless/snippets/edge/synchronization-guide/" block="query-both-shards" >}}
|
||||||
from qdrant_edge import Query, QueryRequest
|
|
||||||
|
|
||||||
query_request = QueryRequest(
|
|
||||||
query=Query.Nearest([0.2, 0.1, 0.9, 0.7], using=VECTOR_NAME),
|
|
||||||
limit=10,
|
|
||||||
with_vector=False,
|
|
||||||
with_payload=True
|
|
||||||
)
|
|
||||||
|
|
||||||
mutable_results = mutable_shard.query(query_request)
|
|
||||||
immutable_results = immutable_shard.query(query_request)
|
|
||||||
|
|
||||||
all_results = list(mutable_results) + list(immutable_results)
|
|
||||||
all_results.sort(key=lambda x: x.score, reverse=True)
|
|
||||||
|
|
||||||
seen_ids = set()
|
|
||||||
unique_results = []
|
|
||||||
for result in all_results:
|
|
||||||
if result.id not in seen_ids:
|
|
||||||
seen_ids.add(result.id)
|
|
||||||
unique_results.append(result)
|
|
||||||
|
|
||||||
results= [
|
|
||||||
{
|
|
||||||
"id": result.id,
|
|
||||||
"score": result.score,
|
|
||||||
"payload": result.payload
|
|
||||||
}
|
|
||||||
for result in unique_results[:10]
|
|
||||||
]
|
|
||||||
```
|
|
||||||
|
|
||||||
## Support
|
## Support
|
||||||
|
|
||||||
|
|||||||
+17
@@ -0,0 +1,17 @@
|
|||||||
|
```python
|
||||||
|
from fastembed import ImageEmbedding, TextEmbedding
|
||||||
|
|
||||||
|
TEXT_MODEL_NAME='Qdrant/clip-ViT-B-32-text'
|
||||||
|
VISION_MODEL_NAME='Qdrant/clip-ViT-B-32-vision'
|
||||||
|
MODELS_DIR="./qdrant-edge-directory/models"
|
||||||
|
|
||||||
|
ImageEmbedding(
|
||||||
|
model_name=VISION_MODEL_NAME,
|
||||||
|
cache_dir=MODELS_DIR
|
||||||
|
)
|
||||||
|
|
||||||
|
TextEmbedding(
|
||||||
|
model_name=TEXT_MODEL_NAME,
|
||||||
|
cache_dir=MODELS_DIR
|
||||||
|
)
|
||||||
|
```
|
||||||
+22
@@ -0,0 +1,22 @@
|
|||||||
|
```python
|
||||||
|
from pathlib import Path
|
||||||
|
from qdrant_edge import Point, UpdateOperation
|
||||||
|
import uuid
|
||||||
|
|
||||||
|
IMAGES_DIR = "images"
|
||||||
|
|
||||||
|
image_model = ImageEmbedding(
|
||||||
|
model_name=VISION_MODEL_NAME,
|
||||||
|
cache_dir=MODELS_DIR,
|
||||||
|
local_files_only=True
|
||||||
|
)
|
||||||
|
|
||||||
|
embeddings = list(image_model.embed([Path(IMAGES_DIR) / "temp.jpg"]))[0]
|
||||||
|
|
||||||
|
point = Point(
|
||||||
|
id=str(uuid.uuid4()),
|
||||||
|
vector={VECTOR_NAME: embeddings.tolist()}
|
||||||
|
)
|
||||||
|
|
||||||
|
edge_shard.update(UpdateOperation.upsert_points([point]))
|
||||||
|
```
|
||||||
+25
@@ -0,0 +1,25 @@
|
|||||||
|
```python
|
||||||
|
from pathlib import Path
|
||||||
|
from qdrant_edge import (
|
||||||
|
Distance,
|
||||||
|
EdgeConfig,
|
||||||
|
EdgeShard,
|
||||||
|
VectorDataConfig,
|
||||||
|
)
|
||||||
|
|
||||||
|
SHARD_DIRECTORY = "./qdrant-edge-directory"
|
||||||
|
VECTOR_DIMENSION = 512
|
||||||
|
VECTOR_NAME="my-vector"
|
||||||
|
|
||||||
|
Path(SHARD_DIRECTORY).mkdir(parents=True, exist_ok=True)
|
||||||
|
config = EdgeConfig(
|
||||||
|
vector_data={
|
||||||
|
VECTOR_NAME: VectorDataConfig(
|
||||||
|
size=VECTOR_DIMENSION,
|
||||||
|
distance=Distance.Cosine,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
edge_shard = EdgeShard(SHARD_DIRECTORY, config)
|
||||||
|
```
|
||||||
+81
@@ -0,0 +1,81 @@
|
|||||||
|
```python
|
||||||
|
from fastembed import ImageEmbedding, TextEmbedding
|
||||||
|
|
||||||
|
TEXT_MODEL_NAME='Qdrant/clip-ViT-B-32-text'
|
||||||
|
VISION_MODEL_NAME='Qdrant/clip-ViT-B-32-vision'
|
||||||
|
MODELS_DIR="./qdrant-edge-directory/models"
|
||||||
|
|
||||||
|
ImageEmbedding(
|
||||||
|
model_name=VISION_MODEL_NAME,
|
||||||
|
cache_dir=MODELS_DIR
|
||||||
|
)
|
||||||
|
|
||||||
|
TextEmbedding(
|
||||||
|
model_name=TEXT_MODEL_NAME,
|
||||||
|
cache_dir=MODELS_DIR
|
||||||
|
)
|
||||||
|
|
||||||
|
from pathlib import Path
|
||||||
|
from qdrant_edge import (
|
||||||
|
Distance,
|
||||||
|
EdgeConfig,
|
||||||
|
EdgeShard,
|
||||||
|
VectorDataConfig,
|
||||||
|
)
|
||||||
|
|
||||||
|
SHARD_DIRECTORY = "./qdrant-edge-directory"
|
||||||
|
VECTOR_DIMENSION = 512
|
||||||
|
VECTOR_NAME="my-vector"
|
||||||
|
|
||||||
|
Path(SHARD_DIRECTORY).mkdir(parents=True, exist_ok=True)
|
||||||
|
config = EdgeConfig(
|
||||||
|
vector_data={
|
||||||
|
VECTOR_NAME: VectorDataConfig(
|
||||||
|
size=VECTOR_DIMENSION,
|
||||||
|
distance=Distance.Cosine,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
edge_shard = EdgeShard(SHARD_DIRECTORY, config)
|
||||||
|
|
||||||
|
from pathlib import Path
|
||||||
|
from qdrant_edge import Point, UpdateOperation
|
||||||
|
import uuid
|
||||||
|
|
||||||
|
IMAGES_DIR = "images"
|
||||||
|
|
||||||
|
image_model = ImageEmbedding(
|
||||||
|
model_name=VISION_MODEL_NAME,
|
||||||
|
cache_dir=MODELS_DIR,
|
||||||
|
local_files_only=True
|
||||||
|
)
|
||||||
|
|
||||||
|
embeddings = list(image_model.embed([Path(IMAGES_DIR) / "temp.jpg"]))[0]
|
||||||
|
|
||||||
|
point = Point(
|
||||||
|
id=str(uuid.uuid4()),
|
||||||
|
vector={VECTOR_NAME: embeddings.tolist()}
|
||||||
|
)
|
||||||
|
|
||||||
|
edge_shard.update(UpdateOperation.upsert_points([point]))
|
||||||
|
|
||||||
|
from qdrant_edge import Query, QueryRequest
|
||||||
|
|
||||||
|
text_model = TextEmbedding(
|
||||||
|
model_name=TEXT_MODEL_NAME,
|
||||||
|
cache_dir=MODELS_DIR,
|
||||||
|
local_files_only=True
|
||||||
|
)
|
||||||
|
|
||||||
|
embeddings = list(text_model.embed(["<search terms>"]))[0]
|
||||||
|
|
||||||
|
results = edge_shard.query(
|
||||||
|
QueryRequest(
|
||||||
|
query=Query.Nearest(embeddings.tolist(),using=VECTOR_NAME),
|
||||||
|
limit=10,
|
||||||
|
with_vector=False,
|
||||||
|
with_payload=True
|
||||||
|
)
|
||||||
|
)
|
||||||
|
```
|
||||||
+20
@@ -0,0 +1,20 @@
|
|||||||
|
```python
|
||||||
|
from qdrant_edge import Query, QueryRequest
|
||||||
|
|
||||||
|
text_model = TextEmbedding(
|
||||||
|
model_name=TEXT_MODEL_NAME,
|
||||||
|
cache_dir=MODELS_DIR,
|
||||||
|
local_files_only=True
|
||||||
|
)
|
||||||
|
|
||||||
|
embeddings = list(text_model.embed(["<search terms>"]))[0]
|
||||||
|
|
||||||
|
results = edge_shard.query(
|
||||||
|
QueryRequest(
|
||||||
|
query=Query.Nearest(embeddings.tolist(),using=VECTOR_NAME),
|
||||||
|
limit=10,
|
||||||
|
with_vector=False,
|
||||||
|
with_payload=True
|
||||||
|
)
|
||||||
|
)
|
||||||
|
```
|
||||||
@@ -0,0 +1,87 @@
|
|||||||
|
# @block-start download-models
|
||||||
|
from fastembed import ImageEmbedding, TextEmbedding
|
||||||
|
|
||||||
|
TEXT_MODEL_NAME='Qdrant/clip-ViT-B-32-text'
|
||||||
|
VISION_MODEL_NAME='Qdrant/clip-ViT-B-32-vision'
|
||||||
|
MODELS_DIR="./qdrant-edge-directory/models"
|
||||||
|
|
||||||
|
ImageEmbedding(
|
||||||
|
model_name=VISION_MODEL_NAME,
|
||||||
|
cache_dir=MODELS_DIR
|
||||||
|
)
|
||||||
|
|
||||||
|
TextEmbedding(
|
||||||
|
model_name=TEXT_MODEL_NAME,
|
||||||
|
cache_dir=MODELS_DIR
|
||||||
|
)
|
||||||
|
# @block-end download-models
|
||||||
|
|
||||||
|
# @block-start initialize-edge-shard
|
||||||
|
from pathlib import Path
|
||||||
|
from qdrant_edge import (
|
||||||
|
Distance,
|
||||||
|
EdgeConfig,
|
||||||
|
EdgeShard,
|
||||||
|
VectorDataConfig,
|
||||||
|
)
|
||||||
|
|
||||||
|
SHARD_DIRECTORY = "./qdrant-edge-directory"
|
||||||
|
VECTOR_DIMENSION = 512
|
||||||
|
VECTOR_NAME="my-vector"
|
||||||
|
|
||||||
|
Path(SHARD_DIRECTORY).mkdir(parents=True, exist_ok=True)
|
||||||
|
config = EdgeConfig(
|
||||||
|
vector_data={
|
||||||
|
VECTOR_NAME: VectorDataConfig(
|
||||||
|
size=VECTOR_DIMENSION,
|
||||||
|
distance=Distance.Cosine,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
edge_shard = EdgeShard(SHARD_DIRECTORY, config)
|
||||||
|
# @block-end initialize-edge-shard
|
||||||
|
|
||||||
|
# @block-start embed-and-store-image
|
||||||
|
from pathlib import Path
|
||||||
|
from qdrant_edge import Point, UpdateOperation
|
||||||
|
import uuid
|
||||||
|
|
||||||
|
IMAGES_DIR = "images"
|
||||||
|
|
||||||
|
image_model = ImageEmbedding(
|
||||||
|
model_name=VISION_MODEL_NAME,
|
||||||
|
cache_dir=MODELS_DIR,
|
||||||
|
local_files_only=True
|
||||||
|
)
|
||||||
|
|
||||||
|
embeddings = list(image_model.embed([Path(IMAGES_DIR) / "temp.jpg"]))[0]
|
||||||
|
|
||||||
|
point = Point(
|
||||||
|
id=str(uuid.uuid4()),
|
||||||
|
vector={VECTOR_NAME: embeddings.tolist()}
|
||||||
|
)
|
||||||
|
|
||||||
|
edge_shard.update(UpdateOperation.upsert_points([point]))
|
||||||
|
# @block-end embed-and-store-image
|
||||||
|
|
||||||
|
# @block-start query-with-text-embedding
|
||||||
|
from qdrant_edge import Query, QueryRequest
|
||||||
|
|
||||||
|
text_model = TextEmbedding(
|
||||||
|
model_name=TEXT_MODEL_NAME,
|
||||||
|
cache_dir=MODELS_DIR,
|
||||||
|
local_files_only=True
|
||||||
|
)
|
||||||
|
|
||||||
|
embeddings = list(text_model.embed(["<search terms>"]))[0]
|
||||||
|
|
||||||
|
results = edge_shard.query(
|
||||||
|
QueryRequest(
|
||||||
|
query=Query.Nearest(embeddings.tolist(),using=VECTOR_NAME),
|
||||||
|
limit=10,
|
||||||
|
with_vector=False,
|
||||||
|
with_payload=True
|
||||||
|
)
|
||||||
|
)
|
||||||
|
# @block-end query-with-text-embedding
|
||||||
+3
@@ -0,0 +1,3 @@
|
|||||||
|
```python
|
||||||
|
edge_shard.close()
|
||||||
|
```
|
||||||
+19
@@ -0,0 +1,19 @@
|
|||||||
|
```python
|
||||||
|
from qdrant_edge import (
|
||||||
|
Distance,
|
||||||
|
EdgeConfig,
|
||||||
|
VectorDataConfig,
|
||||||
|
)
|
||||||
|
|
||||||
|
VECTOR_NAME="my-vector"
|
||||||
|
VECTOR_DIMENSION=4
|
||||||
|
|
||||||
|
config = EdgeConfig(
|
||||||
|
vector_data={
|
||||||
|
VECTOR_NAME: VectorDataConfig(
|
||||||
|
size=VECTOR_DIMENSION,
|
||||||
|
distance=Distance.Cosine,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
)
|
||||||
|
```
|
||||||
+7
@@ -0,0 +1,7 @@
|
|||||||
|
```python
|
||||||
|
from pathlib import Path
|
||||||
|
|
||||||
|
SHARD_DIRECTORY = "./qdrant-edge-directory"
|
||||||
|
|
||||||
|
Path(SHARD_DIRECTORY).mkdir(parents=True, exist_ok=True)
|
||||||
|
```
|
||||||
+5
@@ -0,0 +1,5 @@
|
|||||||
|
```python
|
||||||
|
from qdrant_edge import EdgeShard
|
||||||
|
|
||||||
|
edge_shard = EdgeShard(SHARD_DIRECTORY, config)
|
||||||
|
```
|
||||||
+3
@@ -0,0 +1,3 @@
|
|||||||
|
```python
|
||||||
|
edge_shard = EdgeShard(SHARD_DIRECTORY)
|
||||||
|
```
|
||||||
+60
@@ -0,0 +1,60 @@
|
|||||||
|
```python
|
||||||
|
from pathlib import Path
|
||||||
|
|
||||||
|
SHARD_DIRECTORY = "./qdrant-edge-directory"
|
||||||
|
|
||||||
|
Path(SHARD_DIRECTORY).mkdir(parents=True, exist_ok=True)
|
||||||
|
|
||||||
|
from qdrant_edge import (
|
||||||
|
Distance,
|
||||||
|
EdgeConfig,
|
||||||
|
VectorDataConfig,
|
||||||
|
)
|
||||||
|
|
||||||
|
VECTOR_NAME="my-vector"
|
||||||
|
VECTOR_DIMENSION=4
|
||||||
|
|
||||||
|
config = EdgeConfig(
|
||||||
|
vector_data={
|
||||||
|
VECTOR_NAME: VectorDataConfig(
|
||||||
|
size=VECTOR_DIMENSION,
|
||||||
|
distance=Distance.Cosine,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
from qdrant_edge import EdgeShard
|
||||||
|
|
||||||
|
edge_shard = EdgeShard(SHARD_DIRECTORY, config)
|
||||||
|
|
||||||
|
from qdrant_edge import ( Point, UpdateOperation )
|
||||||
|
|
||||||
|
point = Point(
|
||||||
|
id=1,
|
||||||
|
vector={VECTOR_NAME: [0.1, 0.2, 0.3, 0.4]},
|
||||||
|
payload={"color": "red"}
|
||||||
|
)
|
||||||
|
|
||||||
|
edge_shard.update(UpdateOperation.upsert_points([point]))
|
||||||
|
|
||||||
|
point = edge_shard.retrieve(
|
||||||
|
point_ids=[1],
|
||||||
|
with_payload=True,
|
||||||
|
with_vector=False
|
||||||
|
)
|
||||||
|
|
||||||
|
from qdrant_edge import Query, QueryRequest
|
||||||
|
|
||||||
|
results = edge_shard.query(
|
||||||
|
QueryRequest(
|
||||||
|
query=Query.Nearest([0.2, 0.1, 0.9, 0.7], using=VECTOR_NAME),
|
||||||
|
limit=10,
|
||||||
|
with_vector=False,
|
||||||
|
with_payload=True
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
edge_shard.close()
|
||||||
|
|
||||||
|
edge_shard = EdgeShard(SHARD_DIRECTORY)
|
||||||
|
```
|
||||||
+12
@@ -0,0 +1,12 @@
|
|||||||
|
```python
|
||||||
|
from qdrant_edge import Query, QueryRequest
|
||||||
|
|
||||||
|
results = edge_shard.query(
|
||||||
|
QueryRequest(
|
||||||
|
query=Query.Nearest([0.2, 0.1, 0.9, 0.7], using=VECTOR_NAME),
|
||||||
|
limit=10,
|
||||||
|
with_vector=False,
|
||||||
|
with_payload=True
|
||||||
|
)
|
||||||
|
)
|
||||||
|
```
|
||||||
+7
@@ -0,0 +1,7 @@
|
|||||||
|
```python
|
||||||
|
point = edge_shard.retrieve(
|
||||||
|
point_ids=[1],
|
||||||
|
with_payload=True,
|
||||||
|
with_vector=False
|
||||||
|
)
|
||||||
|
```
|
||||||
+11
@@ -0,0 +1,11 @@
|
|||||||
|
```python
|
||||||
|
from qdrant_edge import ( Point, UpdateOperation )
|
||||||
|
|
||||||
|
point = Point(
|
||||||
|
id=1,
|
||||||
|
vector={VECTOR_NAME: [0.1, 0.2, 0.3, 0.4]},
|
||||||
|
payload={"color": "red"}
|
||||||
|
)
|
||||||
|
|
||||||
|
edge_shard.update(UpdateOperation.upsert_points([point]))
|
||||||
|
```
|
||||||
@@ -0,0 +1,74 @@
|
|||||||
|
# @block-start create-storage-directory
|
||||||
|
from pathlib import Path
|
||||||
|
|
||||||
|
SHARD_DIRECTORY = "./qdrant-edge-directory"
|
||||||
|
|
||||||
|
Path(SHARD_DIRECTORY).mkdir(parents=True, exist_ok=True)
|
||||||
|
# @block-end create-storage-directory
|
||||||
|
|
||||||
|
# @block-start configure-edge-shard
|
||||||
|
from qdrant_edge import (
|
||||||
|
Distance,
|
||||||
|
EdgeConfig,
|
||||||
|
VectorDataConfig,
|
||||||
|
)
|
||||||
|
|
||||||
|
VECTOR_NAME="my-vector"
|
||||||
|
VECTOR_DIMENSION=4
|
||||||
|
|
||||||
|
config = EdgeConfig(
|
||||||
|
vector_data={
|
||||||
|
VECTOR_NAME: VectorDataConfig(
|
||||||
|
size=VECTOR_DIMENSION,
|
||||||
|
distance=Distance.Cosine,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
)
|
||||||
|
# @block-end configure-edge-shard
|
||||||
|
|
||||||
|
# @block-start initialize-edge-shard
|
||||||
|
from qdrant_edge import EdgeShard
|
||||||
|
|
||||||
|
edge_shard = EdgeShard(SHARD_DIRECTORY, config)
|
||||||
|
# @block-end initialize-edge-shard
|
||||||
|
|
||||||
|
# @block-start upsert-points
|
||||||
|
from qdrant_edge import ( Point, UpdateOperation )
|
||||||
|
|
||||||
|
point = Point(
|
||||||
|
id=1,
|
||||||
|
vector={VECTOR_NAME: [0.1, 0.2, 0.3, 0.4]},
|
||||||
|
payload={"color": "red"}
|
||||||
|
)
|
||||||
|
|
||||||
|
edge_shard.update(UpdateOperation.upsert_points([point]))
|
||||||
|
# @block-end upsert-points
|
||||||
|
|
||||||
|
# @block-start retrieve-point
|
||||||
|
point = edge_shard.retrieve(
|
||||||
|
point_ids=[1],
|
||||||
|
with_payload=True,
|
||||||
|
with_vector=False
|
||||||
|
)
|
||||||
|
# @block-end retrieve-point
|
||||||
|
|
||||||
|
# @block-start query-points
|
||||||
|
from qdrant_edge import Query, QueryRequest
|
||||||
|
|
||||||
|
results = edge_shard.query(
|
||||||
|
QueryRequest(
|
||||||
|
query=Query.Nearest([0.2, 0.1, 0.9, 0.7], using=VECTOR_NAME),
|
||||||
|
limit=10,
|
||||||
|
with_vector=False,
|
||||||
|
with_payload=True
|
||||||
|
)
|
||||||
|
)
|
||||||
|
# @block-end query-points
|
||||||
|
|
||||||
|
# @block-start close-edge-shard
|
||||||
|
edge_shard.close()
|
||||||
|
# @block-end close-edge-shard
|
||||||
|
|
||||||
|
# @block-start load-edge-shard
|
||||||
|
edge_shard = EdgeShard(SHARD_DIRECTORY)
|
||||||
|
# @block-end load-edge-shard
|
||||||
+17
@@ -0,0 +1,17 @@
|
|||||||
|
```python
|
||||||
|
from qdrant_edge import (
|
||||||
|
Filter,
|
||||||
|
FieldCondition,
|
||||||
|
RangeFloat
|
||||||
|
)
|
||||||
|
|
||||||
|
mutable_shard.update(
|
||||||
|
UpdateOperation.delete_points_by_filter(Filter(
|
||||||
|
must=[
|
||||||
|
FieldCondition(
|
||||||
|
key=SYNC_TIMESTAMP_KEY, range=RangeFloat(lte=sync_timestamp)
|
||||||
|
)
|
||||||
|
])
|
||||||
|
)
|
||||||
|
)
|
||||||
|
```
|
||||||
+26
@@ -0,0 +1,26 @@
|
|||||||
|
```python
|
||||||
|
from qdrant_edge import ( Point, UpdateOperation )
|
||||||
|
from qdrant_client import models
|
||||||
|
import time
|
||||||
|
|
||||||
|
SYNC_TIMESTAMP_KEY="timestamp"
|
||||||
|
|
||||||
|
id=2
|
||||||
|
vector=[0.4, 0.3, 0.2, 0.1]
|
||||||
|
payload={
|
||||||
|
"color": "green",
|
||||||
|
SYNC_TIMESTAMP_KEY: time.time()
|
||||||
|
}
|
||||||
|
|
||||||
|
point = Point(
|
||||||
|
id=id,
|
||||||
|
vector={VECTOR_NAME: vector},
|
||||||
|
payload=payload
|
||||||
|
)
|
||||||
|
|
||||||
|
mutable_shard.update(UpdateOperation.upsert_points([point]))
|
||||||
|
|
||||||
|
rest_point = models.PointStruct(id=id, vector={VECTOR_NAME: vector}, payload=payload)
|
||||||
|
|
||||||
|
upload_queue.put(rest_point)
|
||||||
|
```
|
||||||
+29
@@ -0,0 +1,29 @@
|
|||||||
|
```python
|
||||||
|
import requests
|
||||||
|
import tempfile
|
||||||
|
import shutil
|
||||||
|
|
||||||
|
COLLECTION_NAME="edge-collection"
|
||||||
|
snapshot_url = f"{QDRANT_URL}/collections/{COLLECTION_NAME}/shards/0/snapshot"
|
||||||
|
|
||||||
|
IMMUTABLE_SHARD_DIR = "./qdrant-edge-directory/mutable"
|
||||||
|
data_dir = Path(IMMUTABLE_SHARD_DIR)
|
||||||
|
|
||||||
|
with tempfile.TemporaryDirectory(dir=data_dir.parent) as restore_dir:
|
||||||
|
snapshot_path = Path(restore_dir) / "shard.snapshot"
|
||||||
|
|
||||||
|
with requests.get(snapshot_url, headers={"api-key": QDRANT_API_KEY}, stream=True) as r:
|
||||||
|
r.raise_for_status()
|
||||||
|
with open(snapshot_path, "wb") as f:
|
||||||
|
for chunk in r.iter_content(chunk_size=8192):
|
||||||
|
f.write(chunk)
|
||||||
|
|
||||||
|
immutable_shard = None
|
||||||
|
if data_dir.exists():
|
||||||
|
shutil.rmtree(data_dir)
|
||||||
|
data_dir.mkdir(parents=True, exist_ok=True)
|
||||||
|
|
||||||
|
EdgeShard.unpack_snapshot(str(snapshot_path), str(data_dir))
|
||||||
|
|
||||||
|
immutable_shard = EdgeShard(IMMUTABLE_SHARD_DIR)
|
||||||
|
```
|
||||||
+27
@@ -0,0 +1,27 @@
|
|||||||
|
```python
|
||||||
|
from pathlib import Path
|
||||||
|
from qdrant_edge import (
|
||||||
|
Distance,
|
||||||
|
EdgeConfig,
|
||||||
|
EdgeShard,
|
||||||
|
VectorDataConfig,
|
||||||
|
)
|
||||||
|
|
||||||
|
MUTABLE_SHARD_DIR = "./qdrant-edge-directory/mutable"
|
||||||
|
|
||||||
|
Path(MUTABLE_SHARD_DIR).mkdir(parents=True, exist_ok=True)
|
||||||
|
|
||||||
|
VECTOR_NAME="my-vector"
|
||||||
|
VECTOR_DIMENSION=4
|
||||||
|
|
||||||
|
config = EdgeConfig(
|
||||||
|
vector_data={
|
||||||
|
VECTOR_NAME: VectorDataConfig(
|
||||||
|
size=VECTOR_DIMENSION,
|
||||||
|
distance=Distance.Cosine,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
mutable_shard = EdgeShard(MUTABLE_SHARD_DIR, config)
|
||||||
|
```
|
||||||
+146
@@ -0,0 +1,146 @@
|
|||||||
|
```python
|
||||||
|
from pathlib import Path
|
||||||
|
from qdrant_edge import (
|
||||||
|
Distance,
|
||||||
|
EdgeConfig,
|
||||||
|
EdgeShard,
|
||||||
|
VectorDataConfig,
|
||||||
|
)
|
||||||
|
|
||||||
|
MUTABLE_SHARD_DIR = "./qdrant-edge-directory/mutable"
|
||||||
|
|
||||||
|
Path(MUTABLE_SHARD_DIR).mkdir(parents=True, exist_ok=True)
|
||||||
|
|
||||||
|
VECTOR_NAME="my-vector"
|
||||||
|
VECTOR_DIMENSION=4
|
||||||
|
|
||||||
|
config = EdgeConfig(
|
||||||
|
vector_data={
|
||||||
|
VECTOR_NAME: VectorDataConfig(
|
||||||
|
size=VECTOR_DIMENSION,
|
||||||
|
distance=Distance.Cosine,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
mutable_shard = EdgeShard(MUTABLE_SHARD_DIR, config)
|
||||||
|
|
||||||
|
import requests
|
||||||
|
import tempfile
|
||||||
|
import shutil
|
||||||
|
|
||||||
|
COLLECTION_NAME="edge-collection"
|
||||||
|
snapshot_url = f"{QDRANT_URL}/collections/{COLLECTION_NAME}/shards/0/snapshot"
|
||||||
|
|
||||||
|
IMMUTABLE_SHARD_DIR = "./qdrant-edge-directory/mutable"
|
||||||
|
data_dir = Path(IMMUTABLE_SHARD_DIR)
|
||||||
|
|
||||||
|
with tempfile.TemporaryDirectory(dir=data_dir.parent) as restore_dir:
|
||||||
|
snapshot_path = Path(restore_dir) / "shard.snapshot"
|
||||||
|
|
||||||
|
with requests.get(snapshot_url, headers={"api-key": QDRANT_API_KEY}, stream=True) as r:
|
||||||
|
r.raise_for_status()
|
||||||
|
with open(snapshot_path, "wb") as f:
|
||||||
|
for chunk in r.iter_content(chunk_size=8192):
|
||||||
|
f.write(chunk)
|
||||||
|
|
||||||
|
immutable_shard = None
|
||||||
|
if data_dir.exists():
|
||||||
|
shutil.rmtree(data_dir)
|
||||||
|
data_dir.mkdir(parents=True, exist_ok=True)
|
||||||
|
|
||||||
|
EdgeShard.unpack_snapshot(str(snapshot_path), str(data_dir))
|
||||||
|
|
||||||
|
immutable_shard = EdgeShard(IMMUTABLE_SHARD_DIR)
|
||||||
|
|
||||||
|
from qdrant_edge import ( Point, UpdateOperation )
|
||||||
|
from qdrant_client import models
|
||||||
|
import time
|
||||||
|
|
||||||
|
SYNC_TIMESTAMP_KEY="timestamp"
|
||||||
|
|
||||||
|
id=2
|
||||||
|
vector=[0.4, 0.3, 0.2, 0.1]
|
||||||
|
payload={
|
||||||
|
"color": "green",
|
||||||
|
SYNC_TIMESTAMP_KEY: time.time()
|
||||||
|
}
|
||||||
|
|
||||||
|
point = Point(
|
||||||
|
id=id,
|
||||||
|
vector={VECTOR_NAME: vector},
|
||||||
|
payload=payload
|
||||||
|
)
|
||||||
|
|
||||||
|
mutable_shard.update(UpdateOperation.upsert_points([point]))
|
||||||
|
|
||||||
|
rest_point = models.PointStruct(id=id, vector={VECTOR_NAME: vector}, payload=payload)
|
||||||
|
|
||||||
|
upload_queue.put(rest_point)
|
||||||
|
|
||||||
|
import time
|
||||||
|
|
||||||
|
manifest = immutable_shard.snapshot_manifest()
|
||||||
|
|
||||||
|
url = f"{QDRANT_URL}/collections/{COLLECTION_NAME}/shards/0/snapshot/partial/create"
|
||||||
|
|
||||||
|
sync_timestamp = time.time()
|
||||||
|
|
||||||
|
with tempfile.TemporaryDirectory(dir=data_dir) as temp_dir:
|
||||||
|
partial_snapshot_path = Path(temp_dir) / "partial.snapshot"
|
||||||
|
response = requests.post(url, headers={"api-key": QDRANT_API_KEY}, json=manifest, stream=True)
|
||||||
|
response.raise_for_status()
|
||||||
|
|
||||||
|
with open(partial_snapshot_path, "wb") as f:
|
||||||
|
for chunk in response.iter_content(chunk_size=8192):
|
||||||
|
f.write(chunk)
|
||||||
|
|
||||||
|
immutable_shard.update_from_snapshot(str(partial_snapshot_path))
|
||||||
|
|
||||||
|
from qdrant_edge import (
|
||||||
|
Filter,
|
||||||
|
FieldCondition,
|
||||||
|
RangeFloat
|
||||||
|
)
|
||||||
|
|
||||||
|
mutable_shard.update(
|
||||||
|
UpdateOperation.delete_points_by_filter(Filter(
|
||||||
|
must=[
|
||||||
|
FieldCondition(
|
||||||
|
key=SYNC_TIMESTAMP_KEY, range=RangeFloat(lte=sync_timestamp)
|
||||||
|
)
|
||||||
|
])
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
from qdrant_edge import Query, QueryRequest
|
||||||
|
|
||||||
|
query_request = QueryRequest(
|
||||||
|
query=Query.Nearest([0.2, 0.1, 0.9, 0.7], using=VECTOR_NAME),
|
||||||
|
limit=10,
|
||||||
|
with_vector=False,
|
||||||
|
with_payload=True
|
||||||
|
)
|
||||||
|
|
||||||
|
mutable_results = mutable_shard.query(query_request)
|
||||||
|
immutable_results = immutable_shard.query(query_request)
|
||||||
|
|
||||||
|
all_results = list(mutable_results) + list(immutable_results)
|
||||||
|
all_results.sort(key=lambda x: x.score, reverse=True)
|
||||||
|
|
||||||
|
seen_ids = set()
|
||||||
|
unique_results = []
|
||||||
|
for result in all_results:
|
||||||
|
if result.id not in seen_ids:
|
||||||
|
seen_ids.add(result.id)
|
||||||
|
unique_results.append(result)
|
||||||
|
|
||||||
|
results= [
|
||||||
|
{
|
||||||
|
"id": result.id,
|
||||||
|
"score": result.score,
|
||||||
|
"payload": result.payload
|
||||||
|
}
|
||||||
|
for result in unique_results[:10]
|
||||||
|
]
|
||||||
|
```
|
||||||
+32
@@ -0,0 +1,32 @@
|
|||||||
|
```python
|
||||||
|
from qdrant_edge import Query, QueryRequest
|
||||||
|
|
||||||
|
query_request = QueryRequest(
|
||||||
|
query=Query.Nearest([0.2, 0.1, 0.9, 0.7], using=VECTOR_NAME),
|
||||||
|
limit=10,
|
||||||
|
with_vector=False,
|
||||||
|
with_payload=True
|
||||||
|
)
|
||||||
|
|
||||||
|
mutable_results = mutable_shard.query(query_request)
|
||||||
|
immutable_results = immutable_shard.query(query_request)
|
||||||
|
|
||||||
|
all_results = list(mutable_results) + list(immutable_results)
|
||||||
|
all_results.sort(key=lambda x: x.score, reverse=True)
|
||||||
|
|
||||||
|
seen_ids = set()
|
||||||
|
unique_results = []
|
||||||
|
for result in all_results:
|
||||||
|
if result.id not in seen_ids:
|
||||||
|
seen_ids.add(result.id)
|
||||||
|
unique_results.append(result)
|
||||||
|
|
||||||
|
results= [
|
||||||
|
{
|
||||||
|
"id": result.id,
|
||||||
|
"score": result.score,
|
||||||
|
"payload": result.payload
|
||||||
|
}
|
||||||
|
for result in unique_results[:10]
|
||||||
|
]
|
||||||
|
```
|
||||||
+20
@@ -0,0 +1,20 @@
|
|||||||
|
```python
|
||||||
|
import time
|
||||||
|
|
||||||
|
manifest = immutable_shard.snapshot_manifest()
|
||||||
|
|
||||||
|
url = f"{QDRANT_URL}/collections/{COLLECTION_NAME}/shards/0/snapshot/partial/create"
|
||||||
|
|
||||||
|
sync_timestamp = time.time()
|
||||||
|
|
||||||
|
with tempfile.TemporaryDirectory(dir=data_dir) as temp_dir:
|
||||||
|
partial_snapshot_path = Path(temp_dir) / "partial.snapshot"
|
||||||
|
response = requests.post(url, headers={"api-key": QDRANT_API_KEY}, json=manifest, stream=True)
|
||||||
|
response.raise_for_status()
|
||||||
|
|
||||||
|
with open(partial_snapshot_path, "wb") as f:
|
||||||
|
for chunk in response.iter_content(chunk_size=8192):
|
||||||
|
f.write(chunk)
|
||||||
|
|
||||||
|
immutable_shard.update_from_snapshot(str(partial_snapshot_path))
|
||||||
|
```
|
||||||
+165
@@ -0,0 +1,165 @@
|
|||||||
|
# @hide-start
|
||||||
|
# mypy: disable-error-code="import-untyped"
|
||||||
|
from queue import Queue
|
||||||
|
from qdrant_client import models
|
||||||
|
QDRANT_URL=""
|
||||||
|
QDRANT_API_KEY=""
|
||||||
|
upload_queue: Queue[models.PointStruct] = Queue()
|
||||||
|
# @hide-end
|
||||||
|
|
||||||
|
# @block-start initialize-mutable-shard
|
||||||
|
from pathlib import Path
|
||||||
|
from qdrant_edge import (
|
||||||
|
Distance,
|
||||||
|
EdgeConfig,
|
||||||
|
EdgeShard,
|
||||||
|
VectorDataConfig,
|
||||||
|
)
|
||||||
|
|
||||||
|
MUTABLE_SHARD_DIR = "./qdrant-edge-directory/mutable"
|
||||||
|
|
||||||
|
Path(MUTABLE_SHARD_DIR).mkdir(parents=True, exist_ok=True)
|
||||||
|
|
||||||
|
VECTOR_NAME="my-vector"
|
||||||
|
VECTOR_DIMENSION=4
|
||||||
|
|
||||||
|
config = EdgeConfig(
|
||||||
|
vector_data={
|
||||||
|
VECTOR_NAME: VectorDataConfig(
|
||||||
|
size=VECTOR_DIMENSION,
|
||||||
|
distance=Distance.Cosine,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
mutable_shard = EdgeShard(MUTABLE_SHARD_DIR, config)
|
||||||
|
# @block-end initialize-mutable-shard
|
||||||
|
|
||||||
|
# @block-start initialize-immutable-shard
|
||||||
|
import requests
|
||||||
|
import tempfile
|
||||||
|
import shutil
|
||||||
|
|
||||||
|
COLLECTION_NAME="edge-collection"
|
||||||
|
snapshot_url = f"{QDRANT_URL}/collections/{COLLECTION_NAME}/shards/0/snapshot"
|
||||||
|
|
||||||
|
IMMUTABLE_SHARD_DIR = "./qdrant-edge-directory/mutable"
|
||||||
|
data_dir = Path(IMMUTABLE_SHARD_DIR)
|
||||||
|
|
||||||
|
with tempfile.TemporaryDirectory(dir=data_dir.parent) as restore_dir:
|
||||||
|
snapshot_path = Path(restore_dir) / "shard.snapshot"
|
||||||
|
|
||||||
|
with requests.get(snapshot_url, headers={"api-key": QDRANT_API_KEY}, stream=True) as r:
|
||||||
|
r.raise_for_status()
|
||||||
|
with open(snapshot_path, "wb") as f:
|
||||||
|
for chunk in r.iter_content(chunk_size=8192):
|
||||||
|
f.write(chunk)
|
||||||
|
|
||||||
|
immutable_shard = None
|
||||||
|
if data_dir.exists():
|
||||||
|
shutil.rmtree(data_dir)
|
||||||
|
data_dir.mkdir(parents=True, exist_ok=True)
|
||||||
|
|
||||||
|
EdgeShard.unpack_snapshot(str(snapshot_path), str(data_dir))
|
||||||
|
|
||||||
|
immutable_shard = EdgeShard(IMMUTABLE_SHARD_DIR)
|
||||||
|
# @block-end initialize-immutable-shard
|
||||||
|
|
||||||
|
# @block-start dual-write
|
||||||
|
from qdrant_edge import ( Point, UpdateOperation )
|
||||||
|
from qdrant_client import models
|
||||||
|
import time
|
||||||
|
|
||||||
|
SYNC_TIMESTAMP_KEY="timestamp"
|
||||||
|
|
||||||
|
id=2
|
||||||
|
vector=[0.4, 0.3, 0.2, 0.1]
|
||||||
|
payload={
|
||||||
|
"color": "green",
|
||||||
|
SYNC_TIMESTAMP_KEY: time.time()
|
||||||
|
}
|
||||||
|
|
||||||
|
point = Point(
|
||||||
|
id=id,
|
||||||
|
vector={VECTOR_NAME: vector},
|
||||||
|
payload=payload
|
||||||
|
)
|
||||||
|
|
||||||
|
mutable_shard.update(UpdateOperation.upsert_points([point]))
|
||||||
|
|
||||||
|
rest_point = models.PointStruct(id=id, vector={VECTOR_NAME: vector}, payload=payload)
|
||||||
|
|
||||||
|
upload_queue.put(rest_point)
|
||||||
|
# @block-end dual-write
|
||||||
|
|
||||||
|
# @block-start update-immutable-shard
|
||||||
|
import time
|
||||||
|
|
||||||
|
manifest = immutable_shard.snapshot_manifest()
|
||||||
|
|
||||||
|
url = f"{QDRANT_URL}/collections/{COLLECTION_NAME}/shards/0/snapshot/partial/create"
|
||||||
|
|
||||||
|
sync_timestamp = time.time()
|
||||||
|
|
||||||
|
with tempfile.TemporaryDirectory(dir=data_dir) as temp_dir:
|
||||||
|
partial_snapshot_path = Path(temp_dir) / "partial.snapshot"
|
||||||
|
response = requests.post(url, headers={"api-key": QDRANT_API_KEY}, json=manifest, stream=True)
|
||||||
|
response.raise_for_status()
|
||||||
|
|
||||||
|
with open(partial_snapshot_path, "wb") as f:
|
||||||
|
for chunk in response.iter_content(chunk_size=8192):
|
||||||
|
f.write(chunk)
|
||||||
|
|
||||||
|
immutable_shard.update_from_snapshot(str(partial_snapshot_path))
|
||||||
|
# @block-end update-immutable-shard
|
||||||
|
|
||||||
|
# @block-start delete-synced-points
|
||||||
|
from qdrant_edge import (
|
||||||
|
Filter,
|
||||||
|
FieldCondition,
|
||||||
|
RangeFloat
|
||||||
|
)
|
||||||
|
|
||||||
|
mutable_shard.update(
|
||||||
|
UpdateOperation.delete_points_by_filter(Filter(
|
||||||
|
must=[
|
||||||
|
FieldCondition(
|
||||||
|
key=SYNC_TIMESTAMP_KEY, range=RangeFloat(lte=sync_timestamp)
|
||||||
|
)
|
||||||
|
])
|
||||||
|
)
|
||||||
|
)
|
||||||
|
# @block-end delete-synced-points
|
||||||
|
|
||||||
|
# @block-start query-both-shards
|
||||||
|
from qdrant_edge import Query, QueryRequest
|
||||||
|
|
||||||
|
query_request = QueryRequest(
|
||||||
|
query=Query.Nearest([0.2, 0.1, 0.9, 0.7], using=VECTOR_NAME),
|
||||||
|
limit=10,
|
||||||
|
with_vector=False,
|
||||||
|
with_payload=True
|
||||||
|
)
|
||||||
|
|
||||||
|
mutable_results = mutable_shard.query(query_request)
|
||||||
|
immutable_results = immutable_shard.query(query_request)
|
||||||
|
|
||||||
|
all_results = list(mutable_results) + list(immutable_results)
|
||||||
|
all_results.sort(key=lambda x: x.score, reverse=True)
|
||||||
|
|
||||||
|
seen_ids = set()
|
||||||
|
unique_results = []
|
||||||
|
for result in all_results:
|
||||||
|
if result.id not in seen_ids:
|
||||||
|
seen_ids.add(result.id)
|
||||||
|
unique_results.append(result)
|
||||||
|
|
||||||
|
results= [
|
||||||
|
{
|
||||||
|
"id": result.id,
|
||||||
|
"score": result.score,
|
||||||
|
"payload": result.payload
|
||||||
|
}
|
||||||
|
for result in unique_results[:10]
|
||||||
|
]
|
||||||
|
# @block-end query-both-shards
|
||||||
+7
@@ -0,0 +1,7 @@
|
|||||||
|
```python
|
||||||
|
from queue import Empty, Queue
|
||||||
|
|
||||||
|
# This is in-memory queue
|
||||||
|
# For production use cases consider persisting changes
|
||||||
|
upload_queue: Queue[models.PointStruct] = Queue()
|
||||||
|
```
|
||||||
+24
@@ -0,0 +1,24 @@
|
|||||||
|
```python
|
||||||
|
from pathlib import Path
|
||||||
|
from qdrant_edge import (
|
||||||
|
Distance,
|
||||||
|
EdgeConfig,
|
||||||
|
VectorDataConfig,
|
||||||
|
)
|
||||||
|
|
||||||
|
SHARD_DIRECTORY = "./qdrant-edge-directory"
|
||||||
|
VECTOR_NAME="my-vector"
|
||||||
|
VECTOR_DIMENSION=4
|
||||||
|
|
||||||
|
Path(SHARD_DIRECTORY).mkdir(parents=True, exist_ok=True)
|
||||||
|
config = EdgeConfig(
|
||||||
|
vector_data={
|
||||||
|
VECTOR_NAME: VectorDataConfig(
|
||||||
|
size=VECTOR_DIMENSION,
|
||||||
|
distance=Distance.Cosine,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
edge_shard = EdgeShard(SHARD_DIRECTORY, config)
|
||||||
|
```
|
||||||
+14
@@ -0,0 +1,14 @@
|
|||||||
|
```python
|
||||||
|
from qdrant_client import QdrantClient, models
|
||||||
|
|
||||||
|
server_client = QdrantClient(url=QDRANT_URL, api_key=QDRANT_API_KEY)
|
||||||
|
|
||||||
|
COLLECTION_NAME="edge-collection"
|
||||||
|
|
||||||
|
if not server_client.collection_exists(collection_name=COLLECTION_NAME):
|
||||||
|
|
||||||
|
server_client.create_collection(
|
||||||
|
collection_name=COLLECTION_NAME,
|
||||||
|
vectors_config={VECTOR_NAME: models.VectorParams(size=VECTOR_DIMENSION, distance=models.Distance.COSINE)}
|
||||||
|
)
|
||||||
|
```
|
||||||
+15
@@ -0,0 +1,15 @@
|
|||||||
|
```python
|
||||||
|
BATCH_SIZE = 10
|
||||||
|
points_to_upload: list[models.PointStruct] = []
|
||||||
|
|
||||||
|
while len(points_to_upload) < BATCH_SIZE:
|
||||||
|
try:
|
||||||
|
points_to_upload.append(upload_queue.get_nowait())
|
||||||
|
except Empty:
|
||||||
|
break
|
||||||
|
|
||||||
|
if points_to_upload:
|
||||||
|
server_client.upsert(
|
||||||
|
collection_name=COLLECTION_NAME, points=points_to_upload
|
||||||
|
)
|
||||||
|
```
|
||||||
+121
@@ -0,0 +1,121 @@
|
|||||||
|
```python
|
||||||
|
COLLECTION_NAME="edge-collection"
|
||||||
|
|
||||||
|
snapshot_url = f"{QDRANT_URL}/collections/{COLLECTION_NAME}/shards/0/snapshot"
|
||||||
|
|
||||||
|
from pathlib import Path
|
||||||
|
from qdrant_edge import EdgeShard
|
||||||
|
import requests
|
||||||
|
import shutil
|
||||||
|
import tempfile
|
||||||
|
|
||||||
|
SHARD_DIRECTORY = "./qdrant-edge-directory"
|
||||||
|
data_dir = Path(SHARD_DIRECTORY)
|
||||||
|
|
||||||
|
with tempfile.TemporaryDirectory(dir=data_dir.parent) as restore_dir:
|
||||||
|
snapshot_path = Path(restore_dir) / "shard.snapshot"
|
||||||
|
|
||||||
|
with requests.get(snapshot_url, headers={"api-key": QDRANT_API_KEY}, stream=True) as r:
|
||||||
|
r.raise_for_status()
|
||||||
|
with open(snapshot_path, "wb") as f:
|
||||||
|
for chunk in r.iter_content(chunk_size=8192):
|
||||||
|
f.write(chunk)
|
||||||
|
|
||||||
|
if data_dir.exists():
|
||||||
|
shutil.rmtree(data_dir)
|
||||||
|
data_dir.mkdir(parents=True, exist_ok=True)
|
||||||
|
|
||||||
|
EdgeShard.unpack_snapshot(str(snapshot_path), str(data_dir))
|
||||||
|
|
||||||
|
edge_shard = EdgeShard(SHARD_DIRECTORY)
|
||||||
|
|
||||||
|
manifest = edge_shard.snapshot_manifest()
|
||||||
|
|
||||||
|
url = f"{QDRANT_URL}/collections/{COLLECTION_NAME}/shards/0/snapshot/partial/create"
|
||||||
|
|
||||||
|
with tempfile.TemporaryDirectory(dir=data_dir) as temp_dir:
|
||||||
|
partial_snapshot_path = Path(temp_dir) / "partial.snapshot"
|
||||||
|
response = requests.post(url, headers={"api-key": QDRANT_API_KEY}, json=manifest, stream=True)
|
||||||
|
response.raise_for_status()
|
||||||
|
|
||||||
|
with open(partial_snapshot_path, "wb") as f:
|
||||||
|
for chunk in response.iter_content(chunk_size=8192):
|
||||||
|
f.write(chunk)
|
||||||
|
|
||||||
|
edge_shard.update_from_snapshot(str(partial_snapshot_path))
|
||||||
|
|
||||||
|
from pathlib import Path
|
||||||
|
from qdrant_edge import (
|
||||||
|
Distance,
|
||||||
|
EdgeConfig,
|
||||||
|
VectorDataConfig,
|
||||||
|
)
|
||||||
|
|
||||||
|
SHARD_DIRECTORY = "./qdrant-edge-directory"
|
||||||
|
VECTOR_NAME="my-vector"
|
||||||
|
VECTOR_DIMENSION=4
|
||||||
|
|
||||||
|
Path(SHARD_DIRECTORY).mkdir(parents=True, exist_ok=True)
|
||||||
|
config = EdgeConfig(
|
||||||
|
vector_data={
|
||||||
|
VECTOR_NAME: VectorDataConfig(
|
||||||
|
size=VECTOR_DIMENSION,
|
||||||
|
distance=Distance.Cosine,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
edge_shard = EdgeShard(SHARD_DIRECTORY, config)
|
||||||
|
|
||||||
|
from qdrant_client import QdrantClient, models
|
||||||
|
|
||||||
|
server_client = QdrantClient(url=QDRANT_URL, api_key=QDRANT_API_KEY)
|
||||||
|
|
||||||
|
COLLECTION_NAME="edge-collection"
|
||||||
|
|
||||||
|
if not server_client.collection_exists(collection_name=COLLECTION_NAME):
|
||||||
|
|
||||||
|
server_client.create_collection(
|
||||||
|
collection_name=COLLECTION_NAME,
|
||||||
|
vectors_config={VECTOR_NAME: models.VectorParams(size=VECTOR_DIMENSION, distance=models.Distance.COSINE)}
|
||||||
|
)
|
||||||
|
|
||||||
|
from queue import Empty, Queue
|
||||||
|
|
||||||
|
# This is in-memory queue
|
||||||
|
# For production use cases consider persisting changes
|
||||||
|
upload_queue: Queue[models.PointStruct] = Queue()
|
||||||
|
|
||||||
|
from qdrant_edge import ( Point, UpdateOperation )
|
||||||
|
from qdrant_client import models
|
||||||
|
|
||||||
|
id=1
|
||||||
|
vector=[0.1, 0.2, 0.3, 0.4]
|
||||||
|
payload={"color": "red"}
|
||||||
|
|
||||||
|
point = Point(
|
||||||
|
id=id,
|
||||||
|
vector={VECTOR_NAME: vector},
|
||||||
|
payload=payload
|
||||||
|
)
|
||||||
|
|
||||||
|
edge_shard.update(UpdateOperation.upsert_points([point]))
|
||||||
|
|
||||||
|
rest_point = models.PointStruct(id=id, vector={VECTOR_NAME: vector}, payload=payload)
|
||||||
|
|
||||||
|
upload_queue.put(rest_point)
|
||||||
|
|
||||||
|
BATCH_SIZE = 10
|
||||||
|
points_to_upload: list[models.PointStruct] = []
|
||||||
|
|
||||||
|
while len(points_to_upload) < BATCH_SIZE:
|
||||||
|
try:
|
||||||
|
points_to_upload.append(upload_queue.get_nowait())
|
||||||
|
except Empty:
|
||||||
|
break
|
||||||
|
|
||||||
|
if points_to_upload:
|
||||||
|
server_client.upsert(
|
||||||
|
collection_name=COLLECTION_NAME, points=points_to_upload
|
||||||
|
)
|
||||||
|
```
|
||||||
+27
@@ -0,0 +1,27 @@
|
|||||||
|
```python
|
||||||
|
from pathlib import Path
|
||||||
|
from qdrant_edge import EdgeShard
|
||||||
|
import requests
|
||||||
|
import shutil
|
||||||
|
import tempfile
|
||||||
|
|
||||||
|
SHARD_DIRECTORY = "./qdrant-edge-directory"
|
||||||
|
data_dir = Path(SHARD_DIRECTORY)
|
||||||
|
|
||||||
|
with tempfile.TemporaryDirectory(dir=data_dir.parent) as restore_dir:
|
||||||
|
snapshot_path = Path(restore_dir) / "shard.snapshot"
|
||||||
|
|
||||||
|
with requests.get(snapshot_url, headers={"api-key": QDRANT_API_KEY}, stream=True) as r:
|
||||||
|
r.raise_for_status()
|
||||||
|
with open(snapshot_path, "wb") as f:
|
||||||
|
for chunk in r.iter_content(chunk_size=8192):
|
||||||
|
f.write(chunk)
|
||||||
|
|
||||||
|
if data_dir.exists():
|
||||||
|
shutil.rmtree(data_dir)
|
||||||
|
data_dir.mkdir(parents=True, exist_ok=True)
|
||||||
|
|
||||||
|
EdgeShard.unpack_snapshot(str(snapshot_path), str(data_dir))
|
||||||
|
|
||||||
|
edge_shard = EdgeShard(SHARD_DIRECTORY)
|
||||||
|
```
|
||||||
+5
@@ -0,0 +1,5 @@
|
|||||||
|
```python
|
||||||
|
COLLECTION_NAME="edge-collection"
|
||||||
|
|
||||||
|
snapshot_url = f"{QDRANT_URL}/collections/{COLLECTION_NAME}/shards/0/snapshot"
|
||||||
|
```
|
||||||
+16
@@ -0,0 +1,16 @@
|
|||||||
|
```python
|
||||||
|
manifest = edge_shard.snapshot_manifest()
|
||||||
|
|
||||||
|
url = f"{QDRANT_URL}/collections/{COLLECTION_NAME}/shards/0/snapshot/partial/create"
|
||||||
|
|
||||||
|
with tempfile.TemporaryDirectory(dir=data_dir) as temp_dir:
|
||||||
|
partial_snapshot_path = Path(temp_dir) / "partial.snapshot"
|
||||||
|
response = requests.post(url, headers={"api-key": QDRANT_API_KEY}, json=manifest, stream=True)
|
||||||
|
response.raise_for_status()
|
||||||
|
|
||||||
|
with open(partial_snapshot_path, "wb") as f:
|
||||||
|
for chunk in response.iter_content(chunk_size=8192):
|
||||||
|
f.write(chunk)
|
||||||
|
|
||||||
|
edge_shard.update_from_snapshot(str(partial_snapshot_path))
|
||||||
|
```
|
||||||
+20
@@ -0,0 +1,20 @@
|
|||||||
|
```python
|
||||||
|
from qdrant_edge import ( Point, UpdateOperation )
|
||||||
|
from qdrant_client import models
|
||||||
|
|
||||||
|
id=1
|
||||||
|
vector=[0.1, 0.2, 0.3, 0.4]
|
||||||
|
payload={"color": "red"}
|
||||||
|
|
||||||
|
point = Point(
|
||||||
|
id=id,
|
||||||
|
vector={VECTOR_NAME: vector},
|
||||||
|
payload=payload
|
||||||
|
)
|
||||||
|
|
||||||
|
edge_shard.update(UpdateOperation.upsert_points([point]))
|
||||||
|
|
||||||
|
rest_point = models.PointStruct(id=id, vector={VECTOR_NAME: vector}, payload=payload)
|
||||||
|
|
||||||
|
upload_queue.put(rest_point)
|
||||||
|
```
|
||||||
+141
@@ -0,0 +1,141 @@
|
|||||||
|
# @hide-start
|
||||||
|
# mypy: disable-error-code="import-untyped"
|
||||||
|
QDRANT_URL=""
|
||||||
|
QDRANT_API_KEY=""
|
||||||
|
# @hide-end
|
||||||
|
|
||||||
|
# @block-start snapshot-url
|
||||||
|
COLLECTION_NAME="edge-collection"
|
||||||
|
|
||||||
|
snapshot_url = f"{QDRANT_URL}/collections/{COLLECTION_NAME}/shards/0/snapshot"
|
||||||
|
# @block-end snapshot-url
|
||||||
|
|
||||||
|
# @block-start restore-snapshot
|
||||||
|
from pathlib import Path
|
||||||
|
from qdrant_edge import EdgeShard
|
||||||
|
import requests
|
||||||
|
import shutil
|
||||||
|
import tempfile
|
||||||
|
|
||||||
|
SHARD_DIRECTORY = "./qdrant-edge-directory"
|
||||||
|
data_dir = Path(SHARD_DIRECTORY)
|
||||||
|
|
||||||
|
with tempfile.TemporaryDirectory(dir=data_dir.parent) as restore_dir:
|
||||||
|
snapshot_path = Path(restore_dir) / "shard.snapshot"
|
||||||
|
|
||||||
|
with requests.get(snapshot_url, headers={"api-key": QDRANT_API_KEY}, stream=True) as r:
|
||||||
|
r.raise_for_status()
|
||||||
|
with open(snapshot_path, "wb") as f:
|
||||||
|
for chunk in r.iter_content(chunk_size=8192):
|
||||||
|
f.write(chunk)
|
||||||
|
|
||||||
|
if data_dir.exists():
|
||||||
|
shutil.rmtree(data_dir)
|
||||||
|
data_dir.mkdir(parents=True, exist_ok=True)
|
||||||
|
|
||||||
|
EdgeShard.unpack_snapshot(str(snapshot_path), str(data_dir))
|
||||||
|
|
||||||
|
edge_shard = EdgeShard(SHARD_DIRECTORY)
|
||||||
|
# @block-end restore-snapshot
|
||||||
|
|
||||||
|
# @block-start update-from-snapshot
|
||||||
|
manifest = edge_shard.snapshot_manifest()
|
||||||
|
|
||||||
|
url = f"{QDRANT_URL}/collections/{COLLECTION_NAME}/shards/0/snapshot/partial/create"
|
||||||
|
|
||||||
|
with tempfile.TemporaryDirectory(dir=data_dir) as temp_dir:
|
||||||
|
partial_snapshot_path = Path(temp_dir) / "partial.snapshot"
|
||||||
|
response = requests.post(url, headers={"api-key": QDRANT_API_KEY}, json=manifest, stream=True)
|
||||||
|
response.raise_for_status()
|
||||||
|
|
||||||
|
with open(partial_snapshot_path, "wb") as f:
|
||||||
|
for chunk in response.iter_content(chunk_size=8192):
|
||||||
|
f.write(chunk)
|
||||||
|
|
||||||
|
edge_shard.update_from_snapshot(str(partial_snapshot_path))
|
||||||
|
# @block-end update-from-snapshot
|
||||||
|
|
||||||
|
# @block-start initialize-edge-shard
|
||||||
|
from pathlib import Path
|
||||||
|
from qdrant_edge import (
|
||||||
|
Distance,
|
||||||
|
EdgeConfig,
|
||||||
|
VectorDataConfig,
|
||||||
|
)
|
||||||
|
|
||||||
|
SHARD_DIRECTORY = "./qdrant-edge-directory"
|
||||||
|
VECTOR_NAME="my-vector"
|
||||||
|
VECTOR_DIMENSION=4
|
||||||
|
|
||||||
|
Path(SHARD_DIRECTORY).mkdir(parents=True, exist_ok=True)
|
||||||
|
config = EdgeConfig(
|
||||||
|
vector_data={
|
||||||
|
VECTOR_NAME: VectorDataConfig(
|
||||||
|
size=VECTOR_DIMENSION,
|
||||||
|
distance=Distance.Cosine,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
edge_shard = EdgeShard(SHARD_DIRECTORY, config)
|
||||||
|
# @block-end initialize-edge-shard
|
||||||
|
|
||||||
|
# @block-start initialize-server-client
|
||||||
|
from qdrant_client import QdrantClient, models
|
||||||
|
|
||||||
|
server_client = QdrantClient(url=QDRANT_URL, api_key=QDRANT_API_KEY)
|
||||||
|
|
||||||
|
COLLECTION_NAME="edge-collection"
|
||||||
|
|
||||||
|
if not server_client.collection_exists(collection_name=COLLECTION_NAME):
|
||||||
|
|
||||||
|
server_client.create_collection(
|
||||||
|
collection_name=COLLECTION_NAME,
|
||||||
|
vectors_config={VECTOR_NAME: models.VectorParams(size=VECTOR_DIMENSION, distance=models.Distance.COSINE)}
|
||||||
|
)
|
||||||
|
# @block-end initialize-server-client
|
||||||
|
|
||||||
|
# @block-start create-upload-queue
|
||||||
|
from queue import Empty, Queue
|
||||||
|
|
||||||
|
# This is in-memory queue
|
||||||
|
# For production use cases consider persisting changes
|
||||||
|
upload_queue: Queue[models.PointStruct] = Queue()
|
||||||
|
# @block-end create-upload-queue
|
||||||
|
|
||||||
|
# @block-start upsert-point
|
||||||
|
from qdrant_edge import ( Point, UpdateOperation )
|
||||||
|
from qdrant_client import models
|
||||||
|
|
||||||
|
id=1
|
||||||
|
vector=[0.1, 0.2, 0.3, 0.4]
|
||||||
|
payload={"color": "red"}
|
||||||
|
|
||||||
|
point = Point(
|
||||||
|
id=id,
|
||||||
|
vector={VECTOR_NAME: vector},
|
||||||
|
payload=payload
|
||||||
|
)
|
||||||
|
|
||||||
|
edge_shard.update(UpdateOperation.upsert_points([point]))
|
||||||
|
|
||||||
|
rest_point = models.PointStruct(id=id, vector={VECTOR_NAME: vector}, payload=payload)
|
||||||
|
|
||||||
|
upload_queue.put(rest_point)
|
||||||
|
# @block-end upsert-point
|
||||||
|
|
||||||
|
# @block-start process-upload-queue
|
||||||
|
BATCH_SIZE = 10
|
||||||
|
points_to_upload: list[models.PointStruct] = []
|
||||||
|
|
||||||
|
while len(points_to_upload) < BATCH_SIZE:
|
||||||
|
try:
|
||||||
|
points_to_upload.append(upload_queue.get_nowait())
|
||||||
|
except Empty:
|
||||||
|
break
|
||||||
|
|
||||||
|
if points_to_upload:
|
||||||
|
server_client.upsert(
|
||||||
|
collection_name=COLLECTION_NAME, points=points_to_upload
|
||||||
|
)
|
||||||
|
# @block-end process-upload-queue
|
||||||
Reference in New Issue
Block a user