diff --git a/.python-version b/.python-version --- a/.python-version +++ b/.python-version @@ -1,1 +1,1 @@ -3.10.14 +3.11 diff --git a/poetry.toml b/poetry.toml deleted file mode 100644 --- a/poetry.toml +++ /dev/null @@ -1,2 +0,0 @@ -[virtualenvs] -create = false diff --git a/pyproject-local-dev.toml b/pyproject-local-dev.toml deleted file mode 100644 --- a/pyproject-local-dev.toml +++ /dev/null @@ -1,41 +0,0 @@ -[tool.poetry] -name = "owi" -version = "0.2.0" -description = "Command Line Interface for the Open Web Index" -authors = ["Michael Granitzer "] -license = "MIT" -maintainers = [ - "Michael Granitzer " -] -readme = "Readme.md" - -[tool.poetry.dependencies] -python = "^3.10" -py4lexis = {version = "^2.1.1", source = "py4lexis"} -#py4lexis = {path = "../py4lexis", develop = true } -pyarrow = "^16.0.0" -tabulate = "^0.9.0" -fsspec = "^2024.3.1" -pandas = "2.0.3" -tqdm = "^4.66.2" -click= "8.1.6" -irods-fsspec="^0.0.1" -duckdb = {version = "^0.10.2"} -ipython = {version = "^8.24.0"} - -[[tool.poetry.source]] -name = "py4lexis" -url = "https://opencode.it4i.eu/api/v4/projects/107/packages/pypi/simple" - -[tool.poetry.extras] -plugins = [] - -[build-system] -requires = ["poetry-core"] -build-backend = "poetry.core.masonry.api" - -[tool.poetry.scripts] -owi = "owi.cli:main" - - - diff --git a/pyproject.toml b/pyproject.toml --- a/pyproject.toml +++ b/pyproject.toml @@ -9,7 +9,7 @@ description = "OWILIX - the Command Line Interface for slicing and consuming the Open Web Index. " readme = "Readme.md" license = { text = "MIT" } -requires-python = ">=3.10,<3.12" +requires-python = ">=3.11,<3.12" authors = [{ name = "Michael Granitzer", email = "michael.granitzer@uni-passau.de" }] maintainers = [{ name = "Michael Granitzer", email = "michael.granitzer@uni-passau.de" }] diff --git a/uv.lock b/uv.lock --- a/uv.lock +++ b/uv.lock @@ -1,10 +1,6 @@ version = 1 revision = 3 -requires-python = ">=3.10, <3.12" -resolution-markers = [ - "python_full_version >= '3.11'", - "python_full_version < '3.11'", -] +requires-python = "==3.11.*" [[package]] name = "aiobotocore" @@ -40,7 +36,6 @@ dependencies = [ { name = "aiohappyeyeballs" }, { name = "aiosignal" }, - { name = "async-timeout", version = "4.0.3", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.11'" }, { name = "attrs" }, { name = "frozenlist" }, { name = "multidict" }, @@ -48,21 +43,6 @@ ] sdist = { url = "https://files.pythonhosted.org/packages/17/7e/16e57e6cf20eb62481a2f9ce8674328407187950ccc602ad07c685279141/aiohttp-3.10.10.tar.gz", hash = "sha256:0631dd7c9f0822cc61c88586ca76d5b5ada26538097d0f1df510b082bad3411a", size = 7542993, upload-time = "2024-10-10T21:54:08.355Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/3d/dd/3d40c0e67e79c5c42671e3e268742f1ff96c6573ca43823563d01abd9475/aiohttp-3.10.10-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:be7443669ae9c016b71f402e43208e13ddf00912f47f623ee5994e12fc7d4b3f", size = 586969, upload-time = "2024-10-10T21:51:24.139Z" }, - { url = "https://files.pythonhosted.org/packages/75/64/8de41b5555e5b43ef6d4ed1261891d33fe45ecc6cb62875bfafb90b9ab93/aiohttp-3.10.10-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:7b06b7843929e41a94ea09eb1ce3927865387e3e23ebe108e0d0d09b08d25be9", size = 399367, upload-time = "2024-10-10T21:51:26.23Z" }, - { url = "https://files.pythonhosted.org/packages/96/36/27bd62ea7ce43906d1443a73691823fc82ffb8fa03276b0e2f7e1037c286/aiohttp-3.10.10-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:333cf6cf8e65f6a1e06e9eb3e643a0c515bb850d470902274239fea02033e9a8", size = 390720, upload-time = "2024-10-10T21:51:27.541Z" }, - { url = "https://files.pythonhosted.org/packages/e8/4d/d516b050d811ce0dd26325c383013c104ffa8b58bd361b82e52833f68e78/aiohttp-3.10.10-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:274cfa632350225ce3fdeb318c23b4a10ec25c0e2c880eff951a3842cf358ac1", size = 1228820, upload-time = "2024-10-10T21:51:29.135Z" }, - { url = "https://files.pythonhosted.org/packages/53/94/964d9327a3e336d89aad52260836e4ec87fdfa1207176550fdf384eaffe7/aiohttp-3.10.10-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d9e5e4a85bdb56d224f412d9c98ae4cbd032cc4f3161818f692cd81766eee65a", size = 1264616, upload-time = "2024-10-10T21:51:30.436Z" }, - { url = "https://files.pythonhosted.org/packages/0c/20/70ce17764b685ca8f5bf4d568881b4e1f1f4ea5e8170f512fdb1a33859d2/aiohttp-3.10.10-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2b606353da03edcc71130b52388d25f9a30a126e04caef1fd637e31683033abd", size = 1298402, upload-time = "2024-10-10T21:51:31.85Z" }, - { url = "https://files.pythonhosted.org/packages/d1/d1/5248225ccc687f498d06c3bca5af2647a361c3687a85eb3aedcc247ee1aa/aiohttp-3.10.10-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ab5a5a0c7a7991d90446a198689c0535be89bbd6b410a1f9a66688f0880ec026", size = 1222205, upload-time = "2024-10-10T21:51:33.257Z" }, - { url = "https://files.pythonhosted.org/packages/f2/a3/9296b27cc5d4feadf970a14d0694902a49a985f3fae71b8322a5f77b0baa/aiohttp-3.10.10-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:578a4b875af3e0daaf1ac6fa983d93e0bbfec3ead753b6d6f33d467100cdc67b", size = 1193804, upload-time = "2024-10-10T21:51:34.722Z" }, - { url = "https://files.pythonhosted.org/packages/d9/07/f3760160feb12ac51a6168a6da251a4a8f2a70733d49e6ceb9b3e6ee2f03/aiohttp-3.10.10-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:8105fd8a890df77b76dd3054cddf01a879fc13e8af576805d667e0fa0224c35d", size = 1193544, upload-time = "2024-10-10T21:51:36.099Z" }, - { url = "https://files.pythonhosted.org/packages/7e/4c/93a70f9a4ba1c30183a6dd68bfa79cddbf9a674f162f9c62e823a74a5515/aiohttp-3.10.10-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:3bcd391d083f636c06a68715e69467963d1f9600f85ef556ea82e9ef25f043f7", size = 1193047, upload-time = "2024-10-10T21:51:38.192Z" }, - { url = "https://files.pythonhosted.org/packages/ff/a3/36a1e23ff00c7a0cd696c5a28db05db25dc42bfc78c508bd78623ff62a4a/aiohttp-3.10.10-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:fbc6264158392bad9df19537e872d476f7c57adf718944cc1e4495cbabf38e2a", size = 1247201, upload-time = "2024-10-10T21:51:39.926Z" }, - { url = "https://files.pythonhosted.org/packages/55/ae/95399848557b98bb2c402d640b2276ce3a542b94dba202de5a5a1fe29abe/aiohttp-3.10.10-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:e48d5021a84d341bcaf95c8460b152cfbad770d28e5fe14a768988c461b821bc", size = 1264102, upload-time = "2024-10-10T21:51:41.275Z" }, - { url = "https://files.pythonhosted.org/packages/38/f5/02e5c72c1b60d7cceb30b982679a26167e84ac029fd35a93dd4da52c50a3/aiohttp-3.10.10-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:2609e9ab08474702cc67b7702dbb8a80e392c54613ebe80db7e8dbdb79837c68", size = 1215760, upload-time = "2024-10-10T21:51:42.666Z" }, - { url = "https://files.pythonhosted.org/packages/30/17/1463840bad10d02d0439068f37ce5af0b383884b0d5838f46fb027e233bf/aiohttp-3.10.10-cp310-cp310-win32.whl", hash = "sha256:84afcdea18eda514c25bc68b9af2a2b1adea7c08899175a51fe7c4fb6d551257", size = 362678, upload-time = "2024-10-10T21:51:44.42Z" }, - { url = "https://files.pythonhosted.org/packages/dd/01/a0ef707d93e867a43abbffee3a2cdf30559910750b9176b891628c7ad074/aiohttp-3.10.10-cp310-cp310-win_amd64.whl", hash = "sha256:9c72109213eb9d3874f7ac8c0c5fa90e072d678e117d9061c06e30c85b4cf0e6", size = 381097, upload-time = "2024-10-10T21:51:45.697Z" }, { url = "https://files.pythonhosted.org/packages/72/31/3c351d17596194e5a38ef169a4da76458952b2497b4b54645b9d483cbbb0/aiohttp-3.10.10-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:c30a0eafc89d28e7f959281b58198a9fa5e99405f716c0289b7892ca345fe45f", size = 586501, upload-time = "2024-10-10T21:51:47.051Z" }, { url = "https://files.pythonhosted.org/packages/a4/a8/a559d09eb08478cdead6b7ce05b0c4a133ba27fcdfa91e05d2e62867300d/aiohttp-3.10.10-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:258c5dd01afc10015866114e210fb7365f0d02d9d059c3c3415382ab633fcbcb", size = 398993, upload-time = "2024-10-10T21:51:49.07Z" }, { url = "https://files.pythonhosted.org/packages/c5/47/7736d4174613feef61d25332c3bd1a4f8ff5591fbd7331988238a7299485/aiohttp-3.10.10-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:15ecd889a709b0080f02721255b3f80bb261c2293d3c748151274dfea93ac871", size = 390647, upload-time = "2024-10-10T21:51:50.354Z" }, @@ -136,10 +116,8 @@ version = "4.6.0" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "exceptiongroup", marker = "python_full_version < '3.11'" }, { name = "idna" }, { name = "sniffio" }, - { name = "typing-extensions", marker = "python_full_version < '3.11'" }, ] sdist = { url = "https://files.pythonhosted.org/packages/78/49/f3f17ec11c4a91fe79275c426658e509b07547f874b14c1a526d86a83fc8/anyio-4.6.0.tar.gz", hash = "sha256:137b4559cbb034c477165047febb6ff83f390fc3b20bf181c1fc0a728cb8beeb", size = 170983, upload-time = "2024-09-21T10:33:28.479Z" } wheels = [ @@ -166,23 +144,8 @@ [[package]] name = "async-timeout" -version = "4.0.3" -source = { registry = "https://pypi.org/simple" } -resolution-markers = [ - "python_full_version < '3.11'", -] -sdist = { url = "https://files.pythonhosted.org/packages/87/d6/21b30a550dafea84b1b8eee21b5e23fa16d010ae006011221f33dcd8d7f8/async-timeout-4.0.3.tar.gz", hash = "sha256:4640d96be84d82d02ed59ea2b7105a0f7b33abe8703703cd0ab0bf87c427522f", size = 8345, upload-time = "2023-08-10T16:35:56.907Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/a7/fa/e01228c2938de91d47b307831c62ab9e4001e747789d0b05baf779a6488c/async_timeout-4.0.3-py3-none-any.whl", hash = "sha256:7405140ff1230c310e51dc27b3145b9092d659ce68ff733fb0cefe3ee42be028", size = 5721, upload-time = "2023-08-10T16:35:55.203Z" }, -] - -[[package]] -name = "async-timeout" version = "5.0.1" source = { registry = "https://pypi.org/simple" } -resolution-markers = [ - "python_full_version >= '3.11'", -] sdist = { url = "https://files.pythonhosted.org/packages/a5/ae/136395dfbfe00dfc94da3f3e136d0b13f394cba8f4841120e34226265780/async_timeout-5.0.1.tar.gz", hash = "sha256:d9321a7a3d5a6a5e187e824d2fa0793ce379a202935782d555d6e9d2735677d3", size = 9274, upload-time = "2024-11-06T16:41:39.6Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/fe/ba/e2081de779ca30d473f21f5b30e0e737c438205440784c7dfc81efc2b029/async_timeout-5.0.1-py3-none-any.whl", hash = "sha256:39e3809566ff85354557ec2398b55e096c8364bacac9405a7a1fa429e77fe76c", size = 6233, upload-time = "2024-11-06T16:41:37.9Z" }, @@ -221,20 +184,6 @@ source = { registry = "https://pypi.org/simple" } sdist = { url = "https://files.pythonhosted.org/packages/99/b6/282f5f0331b3877d4e79a8aa1cf63b5113a10f035a39bef1fa1dfe9e9e09/bitarray-3.7.1.tar.gz", hash = "sha256:795b1760418ab750826420ae24f06f392c08e21dc234f0a369a69cc00444f8ec", size = 150474, upload-time = "2025-08-28T22:18:15.346Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/42/98/bafe556fe4d97a975fa5c31965aaa282388cc91073aca57a2de206745b11/bitarray-3.7.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:a05982bb49c73463cb0f0f4bed2d8da82631708a2c2d1926107ba99651b419ec", size = 147651, upload-time = "2025-08-28T22:14:53.043Z" }, - { url = "https://files.pythonhosted.org/packages/03/87/639c1e4d869ecd7c23d517c326bfee7ab43ade5d5bd0f6ad3373edc861a8/bitarray-3.7.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:d30e7daaf228e3d69cdd8b02c0dd4199cec034c4b93c80109f56f4675a6db957", size = 143967, upload-time = "2025-08-28T22:14:55.333Z" }, - { url = "https://files.pythonhosted.org/packages/24/e9/8248a05b35f3e3667ceb103febb0d687d3f7314e4692b2048d21ed943a4e/bitarray-3.7.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:160f449bb91686f8fc9984200e78b8d793b79e382decf7eb1dc9948d7c21b36f", size = 319901, upload-time = "2025-08-28T22:14:56.742Z" }, - { url = "https://files.pythonhosted.org/packages/de/e8/47f9d8eebb793b6828baf76027b9eefc4e5e09f32b84a25821c4bc19c3c4/bitarray-3.7.1-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:6542e1cfe060badd160cd383ad93a84871595c14bb05fb8129f963248affd946", size = 339005, upload-time = "2025-08-28T22:14:58.291Z" }, - { url = "https://files.pythonhosted.org/packages/61/73/2c4695e5acd89d9904c5b3bea7b5b06df86dea15653eee6008881d18a632/bitarray-3.7.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b723f9d10f7d8259f010b87fa66e924bb4d67927d9dcff4526a755e9ee84fef4", size = 329495, upload-time = "2025-08-28T22:14:59.722Z" }, - { url = "https://files.pythonhosted.org/packages/0f/d9/dc17b9f5b7b750dc9183db0520e197f1ca635dedd48e37ad00ca450d2fab/bitarray-3.7.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ca4b6298c89b92d6b0a67dfc5f98d68ae92b08101d227263ef2033b9c9a03a72", size = 322141, upload-time = "2025-08-28T22:15:00.829Z" }, - { url = "https://files.pythonhosted.org/packages/a7/45/8fb00265c1b0313070e0a4b09a2f585fd3ee174aaa5352d971069983c983/bitarray-3.7.1-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:567d6891cb1ddbfd0051fcff3cb1bb86efc82ec818d9c5f98c37d59c1d23cc96", size = 310422, upload-time = "2025-08-28T22:15:01.964Z" }, - { url = "https://files.pythonhosted.org/packages/f6/77/04cb016694ae16ffe1a146f1a764b79e71f3ddbc7b9d78069594507c9762/bitarray-3.7.1-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:37a6a8382864a1defb5b370b66a635e04358c7334054457bbbb8645610cd95b2", size = 314796, upload-time = "2025-08-28T22:15:04.468Z" }, - { url = "https://files.pythonhosted.org/packages/b5/4f/8e15934995c5362e645ea27d9521e6b29953dc9f8df59e74525c8022e347/bitarray-3.7.1-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:01e3ba46c2dee6d47a4ab22561a01d8ee6772f681defc9fcb357097a055e48cf", size = 311222, upload-time = "2025-08-28T22:15:05.846Z" }, - { url = "https://files.pythonhosted.org/packages/f4/d2/9cc6df1ab5b9d10904bf78820e2427cf9b373376ca82af64a0b31eff7b31/bitarray-3.7.1-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:477b9456eb7d70f385dc8f097a1d66ee40771b62e47b3b3e33406dcfbc1c6a3b", size = 339685, upload-time = "2025-08-28T22:15:06.992Z" }, - { url = "https://files.pythonhosted.org/packages/ed/6d/b79e5e545a928270445c6916cf2d7613a8a8434eee8de023c900a0a08e15/bitarray-3.7.1-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:2965fd8ba31b04c42e4b696fad509dc5ab50663efca6eb06bb3b6d08587f3a09", size = 339660, upload-time = "2025-08-28T22:15:08.068Z" }, - { url = "https://files.pythonhosted.org/packages/e9/33/8b836518ba16a85c75c177aa0d6658e843b4b0c1ec5994fb9f1b28e9440d/bitarray-3.7.1-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:cc76ad7453816318d794248fba4032967eaffd992d76e5d1af10ef9d46589770", size = 320079, upload-time = "2025-08-28T22:15:09.276Z" }, - { url = "https://files.pythonhosted.org/packages/7b/8e/87603ccf798c99296fdb26b9297350f44f87cb2aced76d3b8b0446ac8cd2/bitarray-3.7.1-cp310-cp310-win32.whl", hash = "sha256:d3f38373d9b2629dedc559e647010541cc4ec4ad9bea560e2eb1017e6a00d9ef", size = 141228, upload-time = "2025-08-28T22:15:10.383Z" }, - { url = "https://files.pythonhosted.org/packages/50/06/7003c5520d2bb36edb68b016b1a83ddd5946da67b9d9982b12a8ef68d706/bitarray-3.7.1-cp310-cp310-win_amd64.whl", hash = "sha256:e39f5e85e1e3d7d84ac2217cd095b3678306c979e991532df47012880e02215d", size = 147988, upload-time = "2025-08-28T22:15:11.718Z" }, { url = "https://files.pythonhosted.org/packages/c6/0b/6fc7221d6d6508b2648f2b99dda9188dc46640023e6c2d3fb78070013901/bitarray-3.7.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:ac39319e6322c2c093a660c02cea6bb3b1ae53d049b573d4781df8896e443e04", size = 147645, upload-time = "2025-08-28T22:15:12.966Z" }, { url = "https://files.pythonhosted.org/packages/43/96/122ef83579cde311e77d5da284b71dfb5ab1c38250b6a97a4f4adae4ef5a/bitarray-3.7.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:a43f4631ecb87bedc510568fef67db53f2a20c4a5953a9d1e07457e7b1d14911", size = 143971, upload-time = "2025-08-28T22:15:14.374Z" }, { url = "https://files.pythonhosted.org/packages/f6/f9/cd0e27f8399b930fcea8b87b36de0ba8c88e8f953dbc98e81ca322352d24/bitarray-3.7.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ffd112646486a31ea5a45aa1eca0e2cd90b6a12f67e848e50349e324c24cc2e7", size = 327521, upload-time = "2025-08-28T22:15:15.381Z" }, @@ -249,12 +198,6 @@ { url = "https://files.pythonhosted.org/packages/52/63/a278c08f1e47711f71e396135c0d6d38811f551613b84af8ac7901bfaea9/bitarray-3.7.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:ddc646cec4899a137c134b13818469e4178a251d77f9f4b23229267e3da78cfb", size = 328197, upload-time = "2025-08-28T22:15:29.392Z" }, { url = "https://files.pythonhosted.org/packages/aa/73/6a74193cf565b01747ebd7979752060128e6c1423378471b04d8ed28b6f0/bitarray-3.7.1-cp311-cp311-win32.whl", hash = "sha256:a23b5f13f9b292004e94b0b13fead4dae79c7512db04dc817ff2c2478298e04a", size = 141377, upload-time = "2025-08-28T22:15:30.471Z" }, { url = "https://files.pythonhosted.org/packages/13/03/7bbaadf90b282c7f1bc21c3c4855ce869d3ecd444071b1dab55baaec9328/bitarray-3.7.1-cp311-cp311-win_amd64.whl", hash = "sha256:acc56700963f63307ac096689d4547e8061028a66bb78b90e42c5da2898898fb", size = 148203, upload-time = "2025-08-28T22:15:31.525Z" }, - { url = "https://files.pythonhosted.org/packages/58/1f/80316ba4ed605d005efeb0b09c97cecde2c66ac4deae9d1d698670e1525f/bitarray-3.7.1-pp310-pypy310_pp73-macosx_10_15_x86_64.whl", hash = "sha256:c9bf2bf29854f165a47917b8782b6cf3a7d602971bf454806208d0cbb96f797a", size = 143423, upload-time = "2025-08-28T22:17:37.879Z" }, - { url = "https://files.pythonhosted.org/packages/9e/c3/52a491e18ba41911455f145906b20898fe8e7955d0bcc5b20207bf2aba09/bitarray-3.7.1-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:002b73bf4a9f7b3ecb02260bd4dd332a6ee4d7f74ee9779a1ef342a36244d0cf", size = 139870, upload-time = "2025-08-28T22:17:39.266Z" }, - { url = "https://files.pythonhosted.org/packages/46/df/4674d16f39841fc71db6ecc6298390cbb91a7dd8c4eccd55248a4ddced06/bitarray-3.7.1-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:481239cd0966f965c2b8fa78b88614be5f12a64e7773bb5feecc567d39bb2dd5", size = 148773, upload-time = "2025-08-28T22:17:40.81Z" }, - { url = "https://files.pythonhosted.org/packages/9b/85/9cd8bc811ab446491a5bdc47a70d6d51adb21e3b005b549d2fd5e04f5c7f/bitarray-3.7.1-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f583a1fb180a123c00064fab1a3bfb9d43e574b6474be1be3f6469e0331e3e2e", size = 149609, upload-time = "2025-08-28T22:17:42.308Z" }, - { url = "https://files.pythonhosted.org/packages/ea/84/e413c51313a4093ed67f657d21519c5fc592bdb9129c0ab8c7bad226e2b8/bitarray-3.7.1-pp310-pypy310_pp73-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:3db0648536f3e08afa7ceb928153c39913f98fd50a5c3adf92a4d0d4268f213e", size = 151343, upload-time = "2025-08-28T22:17:43.749Z" }, - { url = "https://files.pythonhosted.org/packages/a5/4f/921176e539866a8f7428d92962861bbfa6104f2cea0cbdd578abe5768a83/bitarray-3.7.1-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:3875578748b484638f6ea776f534e9088cfb15eee131aac051036cba40fd5d05", size = 146847, upload-time = "2025-08-28T22:17:45.209Z" }, ] [[package]] @@ -286,22 +229,6 @@ source = { registry = "https://pypi.org/simple" } sdist = { url = "https://files.pythonhosted.org/packages/2f/c2/f9e977608bdf958650638c3f1e28f85a1b075f075ebbe77db8555463787b/Brotli-1.1.0.tar.gz", hash = "sha256:81de08ac11bcb85841e440c13611c00b67d3bf82698314928d0b676362546724", size = 7372270, upload-time = "2023-09-07T14:05:41.643Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/6d/3a/dbf4fb970c1019a57b5e492e1e0eae745d32e59ba4d6161ab5422b08eefe/Brotli-1.1.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:e1140c64812cb9b06c922e77f1c26a75ec5e3f0fb2bf92cc8c58720dec276752", size = 873045, upload-time = "2023-09-07T14:03:16.894Z" }, - { url = "https://files.pythonhosted.org/packages/dd/11/afc14026ea7f44bd6eb9316d800d439d092c8d508752055ce8d03086079a/Brotli-1.1.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:c8fd5270e906eef71d4a8d19b7c6a43760c6abcfcc10c9101d14eb2357418de9", size = 446218, upload-time = "2023-09-07T14:03:18.917Z" }, - { url = "https://files.pythonhosted.org/packages/36/83/7545a6e7729db43cb36c4287ae388d6885c85a86dd251768a47015dfde32/Brotli-1.1.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1ae56aca0402a0f9a3431cddda62ad71666ca9d4dc3a10a142b9dce2e3c0cda3", size = 2903872, upload-time = "2023-09-07T14:03:20.398Z" }, - { url = "https://files.pythonhosted.org/packages/32/23/35331c4d9391fcc0f29fd9bec2c76e4b4eeab769afbc4b11dd2e1098fb13/Brotli-1.1.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:43ce1b9935bfa1ede40028054d7f48b5469cd02733a365eec8a329ffd342915d", size = 2941254, upload-time = "2023-09-07T14:03:21.914Z" }, - { url = "https://files.pythonhosted.org/packages/3b/24/1671acb450c902edb64bd765d73603797c6c7280a9ada85a195f6b78c6e5/Brotli-1.1.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:7c4855522edb2e6ae7fdb58e07c3ba9111e7621a8956f481c68d5d979c93032e", size = 2857293, upload-time = "2023-09-07T14:03:24Z" }, - { url = "https://files.pythonhosted.org/packages/d5/00/40f760cc27007912b327fe15bf6bfd8eaecbe451687f72a8abc587d503b3/Brotli-1.1.0-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:38025d9f30cf4634f8309c6874ef871b841eb3c347e90b0851f63d1ded5212da", size = 3002385, upload-time = "2023-09-07T14:03:26.248Z" }, - { url = "https://files.pythonhosted.org/packages/b8/cb/8aaa83f7a4caa131757668c0fb0c4b6384b09ffa77f2fba9570d87ab587d/Brotli-1.1.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:e6a904cb26bfefc2f0a6f240bdf5233be78cd2488900a2f846f3c3ac8489ab80", size = 2911104, upload-time = "2023-09-07T14:03:27.849Z" }, - { url = "https://files.pythonhosted.org/packages/bc/c4/65456561d89d3c49f46b7fbeb8fe6e449f13bdc8ea7791832c5d476b2faf/Brotli-1.1.0-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:a37b8f0391212d29b3a91a799c8e4a2855e0576911cdfb2515487e30e322253d", size = 2809981, upload-time = "2023-09-07T14:03:29.92Z" }, - { url = "https://files.pythonhosted.org/packages/05/1b/cf49528437bae28abce5f6e059f0d0be6fecdcc1d3e33e7c54b3ca498425/Brotli-1.1.0-cp310-cp310-musllinux_1_1_ppc64le.whl", hash = "sha256:e84799f09591700a4154154cab9787452925578841a94321d5ee8fb9a9a328f0", size = 2935297, upload-time = "2023-09-07T14:03:32.035Z" }, - { url = "https://files.pythonhosted.org/packages/81/ff/190d4af610680bf0c5a09eb5d1eac6e99c7c8e216440f9c7cfd42b7adab5/Brotli-1.1.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:f66b5337fa213f1da0d9000bc8dc0cb5b896b726eefd9c6046f699b169c41b9e", size = 2930735, upload-time = "2023-09-07T14:03:33.801Z" }, - { url = "https://files.pythonhosted.org/packages/80/7d/f1abbc0c98f6e09abd3cad63ec34af17abc4c44f308a7a539010f79aae7a/Brotli-1.1.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:5dab0844f2cf82be357a0eb11a9087f70c5430b2c241493fc122bb6f2bb0917c", size = 2933107, upload-time = "2024-10-18T12:32:09.016Z" }, - { url = "https://files.pythonhosted.org/packages/34/ce/5a5020ba48f2b5a4ad1c0522d095ad5847a0be508e7d7569c8630ce25062/Brotli-1.1.0-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:e4fe605b917c70283db7dfe5ada75e04561479075761a0b3866c081d035b01c1", size = 2845400, upload-time = "2024-10-18T12:32:11.134Z" }, - { url = "https://files.pythonhosted.org/packages/44/89/fa2c4355ab1eecf3994e5a0a7f5492c6ff81dfcb5f9ba7859bd534bb5c1a/Brotli-1.1.0-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:1e9a65b5736232e7a7f91ff3d02277f11d339bf34099a56cdab6a8b3410a02b2", size = 3031985, upload-time = "2024-10-18T12:32:12.813Z" }, - { url = "https://files.pythonhosted.org/packages/af/a4/79196b4a1674143d19dca400866b1a4d1a089040df7b93b88ebae81f3447/Brotli-1.1.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:58d4b711689366d4a03ac7957ab8c28890415e267f9b6589969e74b6e42225ec", size = 2927099, upload-time = "2024-10-18T12:32:14.733Z" }, - { url = "https://files.pythonhosted.org/packages/e9/54/1c0278556a097f9651e657b873ab08f01b9a9ae4cac128ceb66427d7cd20/Brotli-1.1.0-cp310-cp310-win32.whl", hash = "sha256:be36e3d172dc816333f33520154d708a2657ea63762ec16b62ece02ab5e4daf2", size = 333172, upload-time = "2023-09-07T14:03:35.212Z" }, - { url = "https://files.pythonhosted.org/packages/f7/65/b785722e941193fd8b571afd9edbec2a9b838ddec4375d8af33a50b8dab9/Brotli-1.1.0-cp310-cp310-win_amd64.whl", hash = "sha256:0c6244521dda65ea562d5a69b9a26120769b7a9fb3db2fe9545935ed6735b128", size = 357255, upload-time = "2023-09-07T14:03:36.447Z" }, { url = "https://files.pythonhosted.org/packages/96/12/ad41e7fadd5db55459c4c401842b47f7fee51068f86dd2894dd0dcfc2d2a/Brotli-1.1.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:a3daabb76a78f829cafc365531c972016e4aa8d5b4bf60660ad8ecee19df7ccc", size = 873068, upload-time = "2023-09-07T14:03:37.779Z" }, { url = "https://files.pythonhosted.org/packages/95/4e/5afab7b2b4b61a84e9c75b17814198ce515343a44e2ed4488fac314cd0a9/Brotli-1.1.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:c8146669223164fc87a7e3de9f81e9423c67a79d6b3447994dfb9c95da16e2d6", size = 446244, upload-time = "2023-09-07T14:03:39.223Z" }, { url = "https://files.pythonhosted.org/packages/9d/e6/f305eb61fb9a8580c525478a4a34c5ae1a9bcb12c3aee619114940bc513d/Brotli-1.1.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:30924eb4c57903d5a7526b08ef4a584acc22ab1ffa085faceb521521d2de32dd", size = 2906500, upload-time = "2023-09-07T14:03:40.858Z" }, @@ -328,7 +255,6 @@ { name = "colorama", marker = "os_name == 'nt'" }, { name = "packaging" }, { name = "pyproject-hooks" }, - { name = "tomli", marker = "python_full_version < '3.11'" }, ] sdist = { url = "https://files.pythonhosted.org/packages/de/1c/fb62f81952f0e74c3fbf411261d1adbdd2d615c89a24b42d0fe44eb4bcf3/build-0.10.0.tar.gz", hash = "sha256:d5b71264afdb5951d6704482aac78de887c80691c52b88a9ad195983ca2c9269", size = 16465, upload-time = "2023-01-11T20:32:50.632Z" } wheels = [ @@ -382,18 +308,6 @@ ] sdist = { url = "https://files.pythonhosted.org/packages/fc/97/c783634659c2920c3fc70419e3af40972dbaf758daa229a7d6ea6135c90d/cffi-1.17.1.tar.gz", hash = "sha256:1c39c6016c32bc48dd54561950ebd6836e1670f2ae46128f67cf49e789c52824", size = 516621, upload-time = "2024-09-04T20:45:21.852Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/90/07/f44ca684db4e4f08a3fdc6eeb9a0d15dc6883efc7b8c90357fdbf74e186c/cffi-1.17.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:df8b1c11f177bc2313ec4b2d46baec87a5f3e71fc8b45dab2ee7cae86d9aba14", size = 182191, upload-time = "2024-09-04T20:43:30.027Z" }, - { url = "https://files.pythonhosted.org/packages/08/fd/cc2fedbd887223f9f5d170c96e57cbf655df9831a6546c1727ae13fa977a/cffi-1.17.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:8f2cdc858323644ab277e9bb925ad72ae0e67f69e804f4898c070998d50b1a67", size = 178592, upload-time = "2024-09-04T20:43:32.108Z" }, - { url = "https://files.pythonhosted.org/packages/de/cc/4635c320081c78d6ffc2cab0a76025b691a91204f4aa317d568ff9280a2d/cffi-1.17.1-cp310-cp310-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:edae79245293e15384b51f88b00613ba9f7198016a5948b5dddf4917d4d26382", size = 426024, upload-time = "2024-09-04T20:43:34.186Z" }, - { url = "https://files.pythonhosted.org/packages/b6/7b/3b2b250f3aab91abe5f8a51ada1b717935fdaec53f790ad4100fe2ec64d1/cffi-1.17.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:45398b671ac6d70e67da8e4224a065cec6a93541bb7aebe1b198a61b58c7b702", size = 448188, upload-time = "2024-09-04T20:43:36.286Z" }, - { url = "https://files.pythonhosted.org/packages/d3/48/1b9283ebbf0ec065148d8de05d647a986c5f22586b18120020452fff8f5d/cffi-1.17.1-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ad9413ccdeda48c5afdae7e4fa2192157e991ff761e7ab8fdd8926f40b160cc3", size = 455571, upload-time = "2024-09-04T20:43:38.586Z" }, - { url = "https://files.pythonhosted.org/packages/40/87/3b8452525437b40f39ca7ff70276679772ee7e8b394934ff60e63b7b090c/cffi-1.17.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5da5719280082ac6bd9aa7becb3938dc9f9cbd57fac7d2871717b1feb0902ab6", size = 436687, upload-time = "2024-09-04T20:43:40.084Z" }, - { url = "https://files.pythonhosted.org/packages/8d/fb/4da72871d177d63649ac449aec2e8a29efe0274035880c7af59101ca2232/cffi-1.17.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2bb1a08b8008b281856e5971307cc386a8e9c5b625ac297e853d36da6efe9c17", size = 446211, upload-time = "2024-09-04T20:43:41.526Z" }, - { url = "https://files.pythonhosted.org/packages/ab/a0/62f00bcb411332106c02b663b26f3545a9ef136f80d5df746c05878f8c4b/cffi-1.17.1-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:045d61c734659cc045141be4bae381a41d89b741f795af1dd018bfb532fd0df8", size = 461325, upload-time = "2024-09-04T20:43:43.117Z" }, - { url = "https://files.pythonhosted.org/packages/36/83/76127035ed2e7e27b0787604d99da630ac3123bfb02d8e80c633f218a11d/cffi-1.17.1-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:6883e737d7d9e4899a8a695e00ec36bd4e5e4f18fabe0aca0efe0a4b44cdb13e", size = 438784, upload-time = "2024-09-04T20:43:45.256Z" }, - { url = "https://files.pythonhosted.org/packages/21/81/a6cd025db2f08ac88b901b745c163d884641909641f9b826e8cb87645942/cffi-1.17.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:6b8b4a92e1c65048ff98cfe1f735ef8f1ceb72e3d5f0c25fdb12087a23da22be", size = 461564, upload-time = "2024-09-04T20:43:46.779Z" }, - { url = "https://files.pythonhosted.org/packages/f8/fe/4d41c2f200c4a457933dbd98d3cf4e911870877bd94d9656cc0fcb390681/cffi-1.17.1-cp310-cp310-win32.whl", hash = "sha256:c9c3d058ebabb74db66e431095118094d06abf53284d9c81f27300d0e0d8bc7c", size = 171804, upload-time = "2024-09-04T20:43:48.186Z" }, - { url = "https://files.pythonhosted.org/packages/d1/b6/0b0f5ab93b0df4acc49cae758c81fe4e5ef26c3ae2e10cc69249dfd8b3ab/cffi-1.17.1-cp310-cp310-win_amd64.whl", hash = "sha256:0f048dcf80db46f0098ccac01132761580d28e28bc0f78ae0d58048063317e15", size = 181299, upload-time = "2024-09-04T20:43:49.812Z" }, { url = "https://files.pythonhosted.org/packages/6b/f4/927e3a8899e52a27fa57a48607ff7dc91a9ebe97399b357b85a0c7892e00/cffi-1.17.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:a45e3c6913c5b87b3ff120dcdc03f6131fa0065027d0ed7ee6190736a74cd401", size = 182264, upload-time = "2024-09-04T20:43:51.124Z" }, { url = "https://files.pythonhosted.org/packages/6c/f5/6c3a8efe5f503175aaddcbea6ad0d2c96dad6f5abb205750d1b3df44ef29/cffi-1.17.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:30c5e0cb5ae493c04c8b42916e52ca38079f1b235c2f8ae5f4527b963c401caf", size = 178651, upload-time = "2024-09-04T20:43:52.872Z" }, { url = "https://files.pythonhosted.org/packages/94/dd/a3f0118e688d1b1a57553da23b16bdade96d2f9bcda4d32e7d2838047ff7/cffi-1.17.1-cp311-cp311-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f75c7ab1f9e4aca5414ed4d8e5c0e303a34f4421f8a0d47a4d019ceff0ab6af4", size = 445259, upload-time = "2024-09-04T20:43:56.123Z" }, @@ -414,21 +328,6 @@ source = { registry = "https://pypi.org/simple" } sdist = { url = "https://files.pythonhosted.org/packages/f2/4f/e1808dc01273379acc506d18f1504eb2d299bd4131743b9fc54d7be4df1e/charset_normalizer-3.4.0.tar.gz", hash = "sha256:223217c3d4f82c3ac5e29032b3f1c2eb0fb591b72161f86d93f5719079dae93e", size = 106620, upload-time = "2024-10-09T07:40:20.413Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/69/8b/825cc84cf13a28bfbcba7c416ec22bf85a9584971be15b21dd8300c65b7f/charset_normalizer-3.4.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:4f9fc98dad6c2eaa32fc3af1417d95b5e3d08aff968df0cd320066def971f9a6", size = 196363, upload-time = "2024-10-09T07:38:02.622Z" }, - { url = "https://files.pythonhosted.org/packages/23/81/d7eef6a99e42c77f444fdd7bc894b0ceca6c3a95c51239e74a722039521c/charset_normalizer-3.4.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:0de7b687289d3c1b3e8660d0741874abe7888100efe14bd0f9fd7141bcbda92b", size = 125639, upload-time = "2024-10-09T07:38:04.044Z" }, - { url = "https://files.pythonhosted.org/packages/21/67/b4564d81f48042f520c948abac7079356e94b30cb8ffb22e747532cf469d/charset_normalizer-3.4.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:5ed2e36c3e9b4f21dd9422f6893dec0abf2cca553af509b10cd630f878d3eb99", size = 120451, upload-time = "2024-10-09T07:38:04.997Z" }, - { url = "https://files.pythonhosted.org/packages/c2/72/12a7f0943dd71fb5b4e7b55c41327ac0a1663046a868ee4d0d8e9c369b85/charset_normalizer-3.4.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:40d3ff7fc90b98c637bda91c89d51264a3dcf210cade3a2c6f838c7268d7a4ca", size = 140041, upload-time = "2024-10-09T07:38:06.676Z" }, - { url = "https://files.pythonhosted.org/packages/67/56/fa28c2c3e31217c4c52158537a2cf5d98a6c1e89d31faf476c89391cd16b/charset_normalizer-3.4.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1110e22af8ca26b90bd6364fe4c763329b0ebf1ee213ba32b68c73de5752323d", size = 150333, upload-time = "2024-10-09T07:38:08.626Z" }, - { url = "https://files.pythonhosted.org/packages/f9/d2/466a9be1f32d89eb1554cf84073a5ed9262047acee1ab39cbaefc19635d2/charset_normalizer-3.4.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:86f4e8cca779080f66ff4f191a685ced73d2f72d50216f7112185dc02b90b9b7", size = 142921, upload-time = "2024-10-09T07:38:10.301Z" }, - { url = "https://files.pythonhosted.org/packages/f8/01/344ec40cf5d85c1da3c1f57566c59e0c9b56bcc5566c08804a95a6cc8257/charset_normalizer-3.4.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7f683ddc7eedd742e2889d2bfb96d69573fde1d92fcb811979cdb7165bb9c7d3", size = 144785, upload-time = "2024-10-09T07:38:12.019Z" }, - { url = "https://files.pythonhosted.org/packages/73/8b/2102692cb6d7e9f03b9a33a710e0164cadfce312872e3efc7cfe22ed26b4/charset_normalizer-3.4.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:27623ba66c183eca01bf9ff833875b459cad267aeeb044477fedac35e19ba907", size = 146631, upload-time = "2024-10-09T07:38:13.701Z" }, - { url = "https://files.pythonhosted.org/packages/d8/96/cc2c1b5d994119ce9f088a9a0c3ebd489d360a2eb058e2c8049f27092847/charset_normalizer-3.4.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:f606a1881d2663630ea5b8ce2efe2111740df4b687bd78b34a8131baa007f79b", size = 140867, upload-time = "2024-10-09T07:38:15.403Z" }, - { url = "https://files.pythonhosted.org/packages/c9/27/cde291783715b8ec30a61c810d0120411844bc4c23b50189b81188b273db/charset_normalizer-3.4.0-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:0b309d1747110feb25d7ed6b01afdec269c647d382c857ef4663bbe6ad95a912", size = 149273, upload-time = "2024-10-09T07:38:16.433Z" }, - { url = "https://files.pythonhosted.org/packages/3a/a4/8633b0fc1a2d1834d5393dafecce4a1cc56727bfd82b4dc18fc92f0d3cc3/charset_normalizer-3.4.0-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:136815f06a3ae311fae551c3df1f998a1ebd01ddd424aa5603a4336997629e95", size = 152437, upload-time = "2024-10-09T07:38:18.013Z" }, - { url = "https://files.pythonhosted.org/packages/64/ea/69af161062166b5975ccbb0961fd2384853190c70786f288684490913bf5/charset_normalizer-3.4.0-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:14215b71a762336254351b00ec720a8e85cada43b987da5a042e4ce3e82bd68e", size = 150087, upload-time = "2024-10-09T07:38:19.089Z" }, - { url = "https://files.pythonhosted.org/packages/3b/fd/e60a9d9fd967f4ad5a92810138192f825d77b4fa2a557990fd575a47695b/charset_normalizer-3.4.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:79983512b108e4a164b9c8d34de3992f76d48cadc9554c9e60b43f308988aabe", size = 145142, upload-time = "2024-10-09T07:38:20.78Z" }, - { url = "https://files.pythonhosted.org/packages/6d/02/8cb0988a1e49ac9ce2eed1e07b77ff118f2923e9ebd0ede41ba85f2dcb04/charset_normalizer-3.4.0-cp310-cp310-win32.whl", hash = "sha256:c94057af19bc953643a33581844649a7fdab902624d2eb739738a30e2b3e60fc", size = 94701, upload-time = "2024-10-09T07:38:21.851Z" }, - { url = "https://files.pythonhosted.org/packages/d6/20/f1d4670a8a723c46be695dff449d86d6092916f9e99c53051954ee33a1bc/charset_normalizer-3.4.0-cp310-cp310-win_amd64.whl", hash = "sha256:55f56e2ebd4e3bc50442fbc0888c9d8c94e4e06a933804e2af3e89e2f9c1c749", size = 102191, upload-time = "2024-10-09T07:38:23.467Z" }, { url = "https://files.pythonhosted.org/packages/9c/61/73589dcc7a719582bf56aae309b6103d2762b526bffe189d635a7fcfd998/charset_normalizer-3.4.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:0d99dd8ff461990f12d6e42c7347fd9ab2532fb70e9621ba520f9e8637161d7c", size = 193339, upload-time = "2024-10-09T07:38:24.527Z" }, { url = "https://files.pythonhosted.org/packages/77/d5/8c982d58144de49f59571f940e329ad6e8615e1e82ef84584c5eeb5e1d72/charset_normalizer-3.4.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:c57516e58fd17d03ebe67e181a4e4e2ccab1168f8c2976c6a334d4f819fe5944", size = 124366, upload-time = "2024-10-09T07:38:26.488Z" }, { url = "https://files.pythonhosted.org/packages/bf/19/411a64f01ee971bed3231111b69eb56f9331a769072de479eae7de52296d/charset_normalizer-3.4.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:6dba5d19c4dfab08e58d5b36304b3f92f3bd5d42c1a3fa37b5ba5cdf6dfcbcee", size = 118874, upload-time = "2024-10-09T07:38:28.115Z" }, @@ -557,10 +456,6 @@ { url = "https://files.pythonhosted.org/packages/bd/4c/ab0b9407d5247576290b4fd8abd06b7f51bd414f04eef0f2800675512d61/cryptography-43.0.1-cp39-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:38926c50cff6f533f8a2dae3d7f19541432610d114a70808f0926d5aaa7121e4", size = 4082606, upload-time = "2024-09-03T20:03:27.836Z" }, { url = "https://files.pythonhosted.org/packages/05/36/e532a671998d6fcfdb9122da16434347a58a6bae9465e527e450e0bc60a5/cryptography-43.0.1-cp39-abi3-win32.whl", hash = "sha256:a575913fb06e05e6b4b814d7f7468c2c660e8bb16d8d5a1faf9b33ccc569dd47", size = 2617948, upload-time = "2024-09-03T20:03:25.446Z" }, { url = "https://files.pythonhosted.org/packages/b3/c6/c09cee6968add5ff868525c3815e5dccc0e3c6e89eec58dc9135d3c40e88/cryptography-43.0.1-cp39-abi3-win_amd64.whl", hash = "sha256:d75601ad10b059ec832e78823b348bfa1a59f6b8d545db3a24fd44362a1564cb", size = 3070445, upload-time = "2024-09-03T20:03:21.179Z" }, - { url = "https://files.pythonhosted.org/packages/18/23/4175dcd935e1649865e1af7bd0b827cc9d9769a586dcc84f7cbe96839086/cryptography-43.0.1-pp310-pypy310_pp73-macosx_10_9_x86_64.whl", hash = "sha256:ea25acb556320250756e53f9e20a4177515f012c9eaea17eb7587a8c4d8ae034", size = 3152694, upload-time = "2024-09-03T20:03:46.587Z" }, - { url = "https://files.pythonhosted.org/packages/ea/45/967da50269954b993d4484bf85026c7377bd551651ebdabba94905972556/cryptography-43.0.1-pp310-pypy310_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:c1332724be35d23a854994ff0b66530119500b6053d0bd3363265f7e5e77288d", size = 3713077, upload-time = "2024-09-03T20:04:06.586Z" }, - { url = "https://files.pythonhosted.org/packages/df/e6/ccd29a1f9a6b71294e1e9f530c4d779d5dd37c8bb736c05d5fb6d98a971b/cryptography-43.0.1-pp310-pypy310_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:fba1007b3ef89946dbbb515aeeb41e30203b004f0b4b00e5e16078b518563289", size = 3915597, upload-time = "2024-09-03T20:03:38.858Z" }, - { url = "https://files.pythonhosted.org/packages/a2/80/fb7d668f1be5e4443b7ac191f68390be24f7c2ebd36011741f62c7645eb2/cryptography-43.0.1-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:5b43d1ea6b378b54a1dc99dd8a2b5be47658fe9a7ce0a58ff0b55f4b43ef2b84", size = 2989208, upload-time = "2024-09-03T20:04:12.261Z" }, ] [[package]] @@ -568,10 +463,8 @@ version = "1.6.5" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "numpy", version = "2.2.6", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.11'" }, - { name = "numpy", version = "2.3.3", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.11'" }, - { name = "scipy", version = "1.15.3", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.11'" }, - { name = "scipy", version = "1.16.2", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.11'" }, + { name = "numpy" }, + { name = "scipy" }, ] sdist = { url = "https://files.pythonhosted.org/packages/88/2f/248057ca4d22bd3ffb9bb3e9f4c208240a27e4d0ca9687d6d1d896aeec2a/datasketch-1.6.5.tar.gz", hash = "sha256:ba2848cb74f23d6d3dd444cf24edcbc47b1c34a171b1803231793ed4d74d4fcf", size = 92598, upload-time = "2024-06-04T00:44:21.23Z" } wheels = [ @@ -644,12 +537,6 @@ source = { registry = "https://pypi.org/simple" } sdist = { url = "https://files.pythonhosted.org/packages/82/93/adc0d183642fc9a602ca9b97cb16754c84b8c1d92e5b99aec412e0c419a8/duckdb-1.4.0.tar.gz", hash = "sha256:bd5edee8bd5a73b5822f2b390668597b5fcdc2d3292c244d8d933bb87ad6ac4c", size = 18453175, upload-time = "2025-09-16T10:22:41.509Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/0f/4a/b2e17dbe2953481b084f355f162ed319a67ef760e28794c6870058583aec/duckdb-1.4.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:e24e981a6c87e299201694b9bb24fff0beb04ccad399fca6f13072a59814488f", size = 31293005, upload-time = "2025-09-16T10:21:28.296Z" }, - { url = "https://files.pythonhosted.org/packages/a9/89/e34ed03cce7e35b83c1f056126aa4e8e8097eb93e7324463020f85d5cbfa/duckdb-1.4.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:db500ef2c8cb7dc1ca078740ecf1dceaa20d3f5dc5bce269be45d5cff4170c0f", size = 17288207, upload-time = "2025-09-16T10:21:31.129Z" }, - { url = "https://files.pythonhosted.org/packages/f8/17/7ff24799ee98c4dbb177c3ec6c93e38e9513828785c31757c727b47ad71e/duckdb-1.4.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:a65739b8a7106634e6e77d0e110fc5e057b88edc9df6cb1683d499a1e5aa3177", size = 14817523, upload-time = "2025-09-16T10:21:33.397Z" }, - { url = "https://files.pythonhosted.org/packages/fc/ab/7a482a76ff75212b5cf4f2172a802f2a59b4ab096416e5821aa62a305bc4/duckdb-1.4.0-cp310-cp310-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:1d59f7be24862adb803a1ddfc9c3b8cb09e6005bca0c9c6f7c631a1da1c3aa0c", size = 18410654, upload-time = "2025-09-16T10:21:35.864Z" }, - { url = "https://files.pythonhosted.org/packages/1e/f6/a235233b973652b31448b6d600604620d02fc552b90ab94ca7f645fd5ac0/duckdb-1.4.0-cp310-cp310-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:7d052a87e9edf4eb3bab0b7a6ac995676018c6083b8049421628dfa3b983a2d4", size = 20399121, upload-time = "2025-09-16T10:21:38.524Z" }, - { url = "https://files.pythonhosted.org/packages/b1/cf/63fedb74d00d7c4e19ffc73a1d8d98ee8d3d6498cf2865509c104aa8e799/duckdb-1.4.0-cp310-cp310-win_amd64.whl", hash = "sha256:0329b81e587f745b2fc6f3a488ea3188b0f029c3b5feef43792a25eaac84ac01", size = 12283288, upload-time = "2025-09-16T10:21:40.732Z" }, { url = "https://files.pythonhosted.org/packages/60/e9/b29cc5bceac52e049b20d613551a2171a092df07f26d4315f3f9651c80d4/duckdb-1.4.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:6505fed1ccae8df9f574e744c48fa32ee2feaeebe5346c2daf4d4d10a8dac5aa", size = 31290878, upload-time = "2025-09-16T10:21:43.256Z" }, { url = "https://files.pythonhosted.org/packages/1f/68/d88a15dba48bf6a4b33f1be5097ef45c83f7b9e97c854cc638a85bb07d70/duckdb-1.4.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:36974a04b29c74ac2143457e95420a7422016d050e28573060b89a90b9cf2b57", size = 17288823, upload-time = "2025-09-16T10:21:45.716Z" }, { url = "https://files.pythonhosted.org/packages/8c/7e/e3d2101dc6bbd60f2b3c1d748351ff541fc8c48790ac1218c0199cb930f6/duckdb-1.4.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:90484b896e5059f145d1facfabea38e22c54a2dcc2bd62dd6c290423f0aee258", size = 14819684, upload-time = "2025-09-16T10:21:48.117Z" }, @@ -664,18 +551,6 @@ source = { registry = "https://pypi.org/simple" } wheels = [ { url = "https://files.pythonhosted.org/packages/25/ed/e47dec0626edd468c84c04d97769e7ab4ea6457b7f54dcb3f72b17fcd876/Events-0.5-py3-none-any.whl", hash = "sha256:a7286af378ba3e46640ac9825156c93bdba7502174dd696090fdfcd4d80a1abd", size = 6758, upload-time = "2023-07-31T08:23:13.645Z" }, -] - -[[package]] -name = "exceptiongroup" -version = "1.3.0" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "typing-extensions", marker = "python_full_version < '3.11'" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/0b/9f/a65090624ecf468cdca03533906e7c69ed7588582240cfe7cc9e770b50eb/exceptiongroup-1.3.0.tar.gz", hash = "sha256:b241f5885f560bc56a59ee63ca4c6a8bfa46ae4ad651af316d4e81817bb9fd88", size = 29749, upload-time = "2025-05-10T17:42:51.123Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/36/f4/c6e662dade71f56cd2f3735141b265c3c79293c109549c1e6933b0651ffc/exceptiongroup-1.3.0-py3-none-any.whl", hash = "sha256:4d111e6e0c13d0644cad6ddaa7ed0261a0b36971f6d23e7ec9b4b9097da78a10", size = 16674, upload-time = "2025-05-10T17:42:49.33Z" }, ] [[package]] @@ -698,11 +573,6 @@ ] sdist = { url = "https://files.pythonhosted.org/packages/9f/75/6579b89c119ca75857d9fe328c0dcb05846350b16b456e9d40e91089ec75/fastwarc-0.15.2.tar.gz", hash = "sha256:529e5b58a9707d4e873e30bc63a9c05adfb80e49fe5154ea7c4569d2c217eb9c", size = 44884, upload-time = "2025-03-27T16:30:44.36Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/d0/2b/cee85100872becdb0e681474317149211b9e43021e969c5a69fdb03f6a2f/fastwarc-0.15.2-cp310-cp310-macosx_12_0_arm64.whl", hash = "sha256:74e3eaa524625f5bfb477cc933b1c5f6de818e38b2bdffc0721d23d9fb733ddf", size = 439370, upload-time = "2025-03-27T16:30:08.279Z" }, - { url = "https://files.pythonhosted.org/packages/c5/92/ebf18fef9adfb3c3310430d7f3d899240317c7a89b7baa83feb989b10274/fastwarc-0.15.2-cp310-cp310-macosx_12_0_x86_64.whl", hash = "sha256:25a3d9fc34f306ad0a1214c200e1fb179fd6aaac711b97b146c4405d666a3f31", size = 490043, upload-time = "2025-03-27T16:30:10.776Z" }, - { url = "https://files.pythonhosted.org/packages/02/b0/5ae8847d5574ada3ba9fcb85a69ca477d7da4c2db3d0c23555f9fec6db08/fastwarc-0.15.2-cp310-cp310-manylinux_2_28_aarch64.whl", hash = "sha256:07a89091acff5c34fcca319bcb71044cf4e86a85de57d2027d0227fa82f8d4e6", size = 2199598, upload-time = "2025-03-27T16:30:11.866Z" }, - { url = "https://files.pythonhosted.org/packages/22/ff/fe26244116ff941ada02652840f9e30f03b14f26ce8e53b81e72f28c12f7/fastwarc-0.15.2-cp310-cp310-manylinux_2_28_x86_64.whl", hash = "sha256:aa5729d6214a477cec8b95e5c241448270fd3f1bca22164a4e31afafa9c07e62", size = 2251813, upload-time = "2025-03-27T16:30:13.037Z" }, - { url = "https://files.pythonhosted.org/packages/7f/f8/09c3230f86dccfa5b99a1150846e539bb48299235ae31ca7881be199b57c/fastwarc-0.15.2-cp310-cp310-win_amd64.whl", hash = "sha256:5dd8496cbe478d43c0ed7e0298f055e7e3b1c97969b724c76c833f7cc733726b", size = 590127, upload-time = "2025-03-27T16:30:14.339Z" }, { url = "https://files.pythonhosted.org/packages/c9/4f/b6e2d5475d4f7e7c8d324fbbd2bf88ee7f6f9cb295f866d583db08a79563/fastwarc-0.15.2-cp311-cp311-macosx_12_0_arm64.whl", hash = "sha256:8054151212105f42cc0934115f2ccb4929055c0ffd6a06962e623f9ce52d0e52", size = 441197, upload-time = "2025-03-27T16:30:15.477Z" }, { url = "https://files.pythonhosted.org/packages/7c/51/1b0ebf224d6240e84971fcfbcb4e8ab72afcb5aeea247e7f02ac964dba2d/fastwarc-0.15.2-cp311-cp311-macosx_12_0_x86_64.whl", hash = "sha256:5bbd96ff3505f84b92743114be63b8fdfe1e88c82cb1c5784df57676e350448a", size = 492976, upload-time = "2025-03-27T16:30:16.56Z" }, { url = "https://files.pythonhosted.org/packages/59/e5/b96871c212d7aa3b5ea395cd2c5d8bd3f8d282464eef90ecfd84b96415a8/fastwarc-0.15.2-cp311-cp311-manylinux_2_28_aarch64.whl", hash = "sha256:d24397559775483f50b1df1d3be8ab5a20b169b1603ad59687c854a4bbab2151", size = 2330075, upload-time = "2025-03-27T16:30:17.858Z" }, @@ -742,21 +612,6 @@ source = { registry = "https://pypi.org/simple" } sdist = { url = "https://files.pythonhosted.org/packages/cf/3d/2102257e7acad73efc4a0c306ad3953f68c504c16982bbdfee3ad75d8085/frozenlist-1.4.1.tar.gz", hash = "sha256:c037a86e8513059a2613aaba4d817bb90b9d9b6b69aace3ce9c877e8c8ed402b", size = 37820, upload-time = "2023-12-15T08:42:23.355Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/7a/35/1328c7b0f780d34f8afc1d87ebdc2bb065a123b24766a0b475f0d67da637/frozenlist-1.4.1-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:f9aa1878d1083b276b0196f2dfbe00c9b7e752475ed3b682025ff20c1c1f51ac", size = 94315, upload-time = "2023-12-15T08:40:29.057Z" }, - { url = "https://files.pythonhosted.org/packages/f4/d6/ca016b0adcf8327714ccef969740688808c86e0287bf3a639ff582f24e82/frozenlist-1.4.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:29acab3f66f0f24674b7dc4736477bcd4bc3ad4b896f5f45379a67bce8b96868", size = 53805, upload-time = "2023-12-15T08:40:30.96Z" }, - { url = "https://files.pythonhosted.org/packages/ae/83/bcdaa437a9bd693ba658a0310f8cdccff26bd78e45fccf8e49897904a5cd/frozenlist-1.4.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:74fb4bee6880b529a0c6560885fce4dc95936920f9f20f53d99a213f7bf66776", size = 52163, upload-time = "2023-12-15T08:40:32.089Z" }, - { url = "https://files.pythonhosted.org/packages/d4/e9/759043ab7d169b74fe05ebfbfa9ee5c881c303ebc838e308346204309cd0/frozenlist-1.4.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:590344787a90ae57d62511dd7c736ed56b428f04cd8c161fcc5e7232c130c69a", size = 238595, upload-time = "2023-12-15T08:40:33.625Z" }, - { url = "https://files.pythonhosted.org/packages/f8/ce/b9de7dc61e753dc318cf0de862181b484178210c5361eae6eaf06792264d/frozenlist-1.4.1-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:068b63f23b17df8569b7fdca5517edef76171cf3897eb68beb01341131fbd2ad", size = 262428, upload-time = "2023-12-15T08:40:34.922Z" }, - { url = "https://files.pythonhosted.org/packages/36/ce/dc6f29e0352fa34ebe45421960c8e7352ca63b31630a576e8ffb381e9c08/frozenlist-1.4.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5c849d495bf5154cd8da18a9eb15db127d4dba2968d88831aff6f0331ea9bd4c", size = 258867, upload-time = "2023-12-15T08:40:36.784Z" }, - { url = "https://files.pythonhosted.org/packages/51/47/159ac53faf8a11ae5ee8bb9db10327575557504e549cfd76f447b969aa91/frozenlist-1.4.1-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:9750cc7fe1ae3b1611bb8cfc3f9ec11d532244235d75901fb6b8e42ce9229dfe", size = 229412, upload-time = "2023-12-15T08:40:38.051Z" }, - { url = "https://files.pythonhosted.org/packages/ec/25/0c87df2e53c0c5d90f7517ca0ff7aca78d050a8ec4d32c4278e8c0e52e51/frozenlist-1.4.1-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a9b2de4cf0cdd5bd2dee4c4f63a653c61d2408055ab77b151c1957f221cabf2a", size = 239539, upload-time = "2023-12-15T08:40:39.896Z" }, - { url = "https://files.pythonhosted.org/packages/97/94/a1305fa4716726ae0abf3b1069c2d922fcfd442538cb850f1be543f58766/frozenlist-1.4.1-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:0633c8d5337cb5c77acbccc6357ac49a1770b8c487e5b3505c57b949b4b82e98", size = 253379, upload-time = "2023-12-15T08:40:41.78Z" }, - { url = "https://files.pythonhosted.org/packages/53/82/274e19f122e124aee6d113188615f63b0736b4242a875f482a81f91e07e2/frozenlist-1.4.1-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:27657df69e8801be6c3638054e202a135c7f299267f1a55ed3a598934f6c0d75", size = 245901, upload-time = "2023-12-15T08:40:43.72Z" }, - { url = "https://files.pythonhosted.org/packages/b8/28/899931015b8cffbe155392fe9ca663f981a17e1adc69589ee0e1e7cdc9a2/frozenlist-1.4.1-cp310-cp310-musllinux_1_1_ppc64le.whl", hash = "sha256:f9a3ea26252bd92f570600098783d1371354d89d5f6b7dfd87359d669f2109b5", size = 263797, upload-time = "2023-12-15T08:40:45.355Z" }, - { url = "https://files.pythonhosted.org/packages/6e/4f/b8a5a2f10c4a58c52a52a40cf6cf1ffcdbf3a3b64f276f41dab989bf3ab5/frozenlist-1.4.1-cp310-cp310-musllinux_1_1_s390x.whl", hash = "sha256:4f57dab5fe3407b6c0c1cc907ac98e8a189f9e418f3b6e54d65a718aaafe3950", size = 264415, upload-time = "2023-12-15T08:40:47.29Z" }, - { url = "https://files.pythonhosted.org/packages/b0/2c/7be3bdc59dbae444864dbd9cde82790314390ec54636baf6b9ce212627ad/frozenlist-1.4.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:e02a0e11cf6597299b9f3bbd3f93d79217cb90cfd1411aec33848b13f5c656cc", size = 253964, upload-time = "2023-12-15T08:40:49.113Z" }, - { url = "https://files.pythonhosted.org/packages/2e/ec/4fb5a88f6b9a352aed45ab824dd7ce4801b7bcd379adcb927c17a8f0a1a8/frozenlist-1.4.1-cp310-cp310-win32.whl", hash = "sha256:a828c57f00f729620a442881cc60e57cfcec6842ba38e1b19fd3e47ac0ff8dc1", size = 44559, upload-time = "2023-12-15T08:40:50.319Z" }, - { url = "https://files.pythonhosted.org/packages/61/15/2b5d644d81282f00b61e54f7b00a96f9c40224107282efe4cd9d2bf1433a/frozenlist-1.4.1-cp310-cp310-win_amd64.whl", hash = "sha256:f56e2333dda1fe0f909e7cc59f021eba0d2307bc6f012a1ccf2beca6ba362439", size = 50434, upload-time = "2023-12-15T08:40:51.411Z" }, { url = "https://files.pythonhosted.org/packages/01/bc/8d33f2d84b9368da83e69e42720cff01c5e199b5a868ba4486189a4d8fa9/frozenlist-1.4.1-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:a0cb6f11204443f27a1628b0e460f37fb30f624be6051d490fa7d7e26d4af3d0", size = 97060, upload-time = "2023-12-15T08:40:52.481Z" }, { url = "https://files.pythonhosted.org/packages/af/b2/904500d6a162b98a70e510e743e7ea992241b4f9add2c8063bf666ca21df/frozenlist-1.4.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:b46c8ae3a8f1f41a0d2ef350c0b6e65822d80772fe46b653ab6b6274f61d4a49", size = 55347, upload-time = "2023-12-15T08:40:54.163Z" }, { url = "https://files.pythonhosted.org/packages/5b/9c/f12b69997d3891ddc0d7895999a00b0c6a67f66f79498c0e30f27876435d/frozenlist-1.4.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:fde5bd59ab5357e3853313127f4d3565fc7dad314a74d7b5d43c22c6a5ed2ced", size = 53374, upload-time = "2023-12-15T08:40:55.966Z" }, @@ -793,7 +648,6 @@ { name = "packaging" }, { name = "platformdirs" }, { name = "semver" }, - { name = "tomli", marker = "python_full_version < '3.11'" }, { name = "typing-extensions" }, ] sdist = { url = "https://files.pythonhosted.org/packages/6e/88/e38f434e41c520ea14feb58bee94dd14f785de5f72ab3d3a21a7fcc192ff/git_changelog-2.6.3.tar.gz", hash = "sha256:d9a5cd7bd8c7dd3eb903c9de93ea5c24b0099ba6e56937f1d9406f7d09034d96", size = 81476, upload-time = "2025-09-18T12:35:36.618Z" } @@ -831,15 +685,6 @@ source = { registry = "https://pypi.org/simple" } sdist = { url = "https://files.pythonhosted.org/packages/03/b8/704d753a5a45507a7aab61f18db9509302ed3d0a27ac7e0359ec2905b1a6/greenlet-3.2.4.tar.gz", hash = "sha256:0dca0d95ff849f9a364385f36ab49f50065d76964944638be9691e1832e9f86d", size = 188260, upload-time = "2025-08-07T13:24:33.51Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/7d/ed/6bfa4109fcb23a58819600392564fea69cdc6551ffd5e69ccf1d52a40cbc/greenlet-3.2.4-cp310-cp310-macosx_11_0_universal2.whl", hash = "sha256:8c68325b0d0acf8d91dde4e6f930967dd52a5302cd4062932a6b2e7c2969f47c", size = 271061, upload-time = "2025-08-07T13:17:15.373Z" }, - { url = "https://files.pythonhosted.org/packages/2a/fc/102ec1a2fc015b3a7652abab7acf3541d58c04d3d17a8d3d6a44adae1eb1/greenlet-3.2.4-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:94385f101946790ae13da500603491f04a76b6e4c059dab271b3ce2e283b2590", size = 629475, upload-time = "2025-08-07T13:42:54.009Z" }, - { url = "https://files.pythonhosted.org/packages/c5/26/80383131d55a4ac0fb08d71660fd77e7660b9db6bdb4e8884f46d9f2cc04/greenlet-3.2.4-cp310-cp310-manylinux2014_ppc64le.manylinux_2_17_ppc64le.whl", hash = "sha256:f10fd42b5ee276335863712fa3da6608e93f70629c631bf77145021600abc23c", size = 640802, upload-time = "2025-08-07T13:45:25.52Z" }, - { url = "https://files.pythonhosted.org/packages/9f/7c/e7833dbcd8f376f3326bd728c845d31dcde4c84268d3921afcae77d90d08/greenlet-3.2.4-cp310-cp310-manylinux2014_s390x.manylinux_2_17_s390x.whl", hash = "sha256:c8c9e331e58180d0d83c5b7999255721b725913ff6bc6cf39fa2a45841a4fd4b", size = 636703, upload-time = "2025-08-07T13:53:12.622Z" }, - { url = "https://files.pythonhosted.org/packages/e9/49/547b93b7c0428ede7b3f309bc965986874759f7d89e4e04aeddbc9699acb/greenlet-3.2.4-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:58b97143c9cc7b86fc458f215bd0932f1757ce649e05b640fea2e79b54cedb31", size = 635417, upload-time = "2025-08-07T13:18:25.189Z" }, - { url = "https://files.pythonhosted.org/packages/7f/91/ae2eb6b7979e2f9b035a9f612cf70f1bf54aad4e1d125129bef1eae96f19/greenlet-3.2.4-cp310-cp310-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:c2ca18a03a8cfb5b25bc1cbe20f3d9a4c80d8c3b13ba3df49ac3961af0b1018d", size = 584358, upload-time = "2025-08-07T13:18:23.708Z" }, - { url = "https://files.pythonhosted.org/packages/f7/85/433de0c9c0252b22b16d413c9407e6cb3b41df7389afc366ca204dbc1393/greenlet-3.2.4-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:9fe0a28a7b952a21e2c062cd5756d34354117796c6d9215a87f55e38d15402c5", size = 1113550, upload-time = "2025-08-07T13:42:37.467Z" }, - { url = "https://files.pythonhosted.org/packages/a1/8d/88f3ebd2bc96bf7747093696f4335a0a8a4c5acfcf1b757717c0d2474ba3/greenlet-3.2.4-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:8854167e06950ca75b898b104b63cc646573aa5fef1353d4508ecdd1ee76254f", size = 1137126, upload-time = "2025-08-07T13:18:20.239Z" }, - { url = "https://files.pythonhosted.org/packages/d6/6f/b60b0291d9623c496638c582297ead61f43c4b72eef5e9c926ef4565ec13/greenlet-3.2.4-cp310-cp310-win_amd64.whl", hash = "sha256:73f49b5368b5359d04e18d15828eecc1806033db5233397748f4ca813ff1056c", size = 298654, upload-time = "2025-08-07T13:50:00.469Z" }, { url = "https://files.pythonhosted.org/packages/a4/de/f28ced0a67749cac23fecb02b694f6473f47686dff6afaa211d186e2ef9c/greenlet-3.2.4-cp311-cp311-macosx_11_0_universal2.whl", hash = "sha256:96378df1de302bc38e99c3a9aa311967b7dc80ced1dcc6f171e99842987882a2", size = 272305, upload-time = "2025-08-07T13:15:41.288Z" }, { url = "https://files.pythonhosted.org/packages/09/16/2c3792cba130000bf2a31c5272999113f4764fd9d874fb257ff588ac779a/greenlet-3.2.4-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:1ee8fae0519a337f2329cb78bd7a8e128ec0f881073d43f023c7b8d4831d5246", size = 632472, upload-time = "2025-08-07T13:42:55.044Z" }, { url = "https://files.pythonhosted.org/packages/ae/8f/95d48d7e3d433e6dae5b1682e4292242a53f22df82e6d3dda81b1701a960/greenlet-3.2.4-cp311-cp311-manylinux2014_ppc64le.manylinux_2_17_ppc64le.whl", hash = "sha256:94abf90142c2a18151632371140b3dba4dee031633fe614cb592dbb6c9e17bc3", size = 644646, upload-time = "2025-08-07T13:45:26.523Z" }, @@ -982,48 +827,20 @@ [[package]] name = "ipython" -version = "8.37.0" -source = { registry = "https://pypi.org/simple" } -resolution-markers = [ - "python_full_version < '3.11'", -] -dependencies = [ - { name = "colorama", marker = "python_full_version < '3.11' and sys_platform == 'win32'" }, - { name = "decorator", marker = "python_full_version < '3.11'" }, - { name = "exceptiongroup", marker = "python_full_version < '3.11'" }, - { name = "jedi", marker = "python_full_version < '3.11'" }, - { name = "matplotlib-inline", marker = "python_full_version < '3.11'" }, - { name = "pexpect", marker = "python_full_version < '3.11' and sys_platform != 'emscripten' and sys_platform != 'win32'" }, - { name = "prompt-toolkit", marker = "python_full_version < '3.11'" }, - { name = "pygments", marker = "python_full_version < '3.11'" }, - { name = "stack-data", marker = "python_full_version < '3.11'" }, - { name = "traitlets", marker = "python_full_version < '3.11'" }, - { name = "typing-extensions", marker = "python_full_version < '3.11'" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/85/31/10ac88f3357fc276dc8a64e8880c82e80e7459326ae1d0a211b40abf6665/ipython-8.37.0.tar.gz", hash = "sha256:ca815841e1a41a1e6b73a0b08f3038af9b2252564d01fc405356d34033012216", size = 5606088, upload-time = "2025-05-31T16:39:09.613Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/91/d0/274fbf7b0b12643cbbc001ce13e6a5b1607ac4929d1b11c72460152c9fc3/ipython-8.37.0-py3-none-any.whl", hash = "sha256:ed87326596b878932dbcb171e3e698845434d8c61b8d8cd474bf663041a9dcf2", size = 831864, upload-time = "2025-05-31T16:39:06.38Z" }, -] - -[[package]] -name = "ipython" version = "9.5.0" source = { registry = "https://pypi.org/simple" } -resolution-markers = [ - "python_full_version >= '3.11'", -] dependencies = [ - { name = "colorama", marker = "python_full_version >= '3.11' and sys_platform == 'win32'" }, - { name = "decorator", marker = "python_full_version >= '3.11'" }, - { name = "ipython-pygments-lexers", marker = "python_full_version >= '3.11'" }, - { name = "jedi", marker = "python_full_version >= '3.11'" }, - { name = "matplotlib-inline", marker = "python_full_version >= '3.11'" }, - { name = "pexpect", marker = "python_full_version >= '3.11' and sys_platform != 'emscripten' and sys_platform != 'win32'" }, - { name = "prompt-toolkit", marker = "python_full_version >= '3.11'" }, - { name = "pygments", marker = "python_full_version >= '3.11'" }, - { name = "stack-data", marker = "python_full_version >= '3.11'" }, - { name = "traitlets", marker = "python_full_version >= '3.11'" }, - { name = "typing-extensions", marker = "python_full_version >= '3.11'" }, + { name = "colorama", marker = "sys_platform == 'win32'" }, + { name = "decorator" }, + { name = "ipython-pygments-lexers" }, + { name = "jedi" }, + { name = "matplotlib-inline" }, + { name = "pexpect", marker = "sys_platform != 'emscripten' and sys_platform != 'win32'" }, + { name = "prompt-toolkit" }, + { name = "pygments" }, + { name = "stack-data" }, + { name = "traitlets" }, + { name = "typing-extensions" }, ] sdist = { url = "https://files.pythonhosted.org/packages/6e/71/a86262bf5a68bf211bcc71fe302af7e05f18a2852fdc610a854d20d085e6/ipython-9.5.0.tar.gz", hash = "sha256:129c44b941fe6d9b82d36fc7a7c18127ddb1d6f02f78f867f402e2e3adde3113", size = 4389137, upload-time = "2025-08-29T12:15:21.519Z" } wheels = [ @@ -1035,7 +852,7 @@ version = "1.1.1" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "pygments", marker = "python_full_version >= '3.11'" }, + { name = "pygments" }, ] sdist = { url = "https://files.pythonhosted.org/packages/ef/4c/5dd1d8af08107f88c7f741ead7a40854b8ac24ddf9ae850afbcf698aa552/ipython_pygments_lexers-1.1.1.tar.gz", hash = "sha256:09c0138009e56b6854f9535736f4171d855c8c08a563a0dcd8022f78355c7e81", size = 8393, upload-time = "2025-01-17T11:24:34.505Z" } wheels = [ @@ -1142,16 +959,6 @@ source = { registry = "https://pypi.org/simple" } sdist = { url = "https://files.pythonhosted.org/packages/b2/97/5d42485e71dfc078108a86d6de8fa46db44a1a9295e89c5d6d4a06e23a62/markupsafe-3.0.2.tar.gz", hash = "sha256:ee55d3edf80167e48ea11a923c7386f4669df67d7994554387f84e7d8b0a2bf0", size = 20537, upload-time = "2024-10-18T15:21:54.129Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/04/90/d08277ce111dd22f77149fd1a5d4653eeb3b3eaacbdfcbae5afb2600eebd/MarkupSafe-3.0.2-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:7e94c425039cde14257288fd61dcfb01963e658efbc0ff54f5306b06054700f8", size = 14357, upload-time = "2024-10-18T15:20:51.44Z" }, - { url = "https://files.pythonhosted.org/packages/04/e1/6e2194baeae0bca1fae6629dc0cbbb968d4d941469cbab11a3872edff374/MarkupSafe-3.0.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:9e2d922824181480953426608b81967de705c3cef4d1af983af849d7bd619158", size = 12393, upload-time = "2024-10-18T15:20:52.426Z" }, - { url = "https://files.pythonhosted.org/packages/1d/69/35fa85a8ece0a437493dc61ce0bb6d459dcba482c34197e3efc829aa357f/MarkupSafe-3.0.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:38a9ef736c01fccdd6600705b09dc574584b89bea478200c5fbf112a6b0d5579", size = 21732, upload-time = "2024-10-18T15:20:53.578Z" }, - { url = "https://files.pythonhosted.org/packages/22/35/137da042dfb4720b638d2937c38a9c2df83fe32d20e8c8f3185dbfef05f7/MarkupSafe-3.0.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bbcb445fa71794da8f178f0f6d66789a28d7319071af7a496d4d507ed566270d", size = 20866, upload-time = "2024-10-18T15:20:55.06Z" }, - { url = "https://files.pythonhosted.org/packages/29/28/6d029a903727a1b62edb51863232152fd335d602def598dade38996887f0/MarkupSafe-3.0.2-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:57cb5a3cf367aeb1d316576250f65edec5bb3be939e9247ae594b4bcbc317dfb", size = 20964, upload-time = "2024-10-18T15:20:55.906Z" }, - { url = "https://files.pythonhosted.org/packages/cc/cd/07438f95f83e8bc028279909d9c9bd39e24149b0d60053a97b2bc4f8aa51/MarkupSafe-3.0.2-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:3809ede931876f5b2ec92eef964286840ed3540dadf803dd570c3b7e13141a3b", size = 21977, upload-time = "2024-10-18T15:20:57.189Z" }, - { url = "https://files.pythonhosted.org/packages/29/01/84b57395b4cc062f9c4c55ce0df7d3108ca32397299d9df00fedd9117d3d/MarkupSafe-3.0.2-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:e07c3764494e3776c602c1e78e298937c3315ccc9043ead7e685b7f2b8d47b3c", size = 21366, upload-time = "2024-10-18T15:20:58.235Z" }, - { url = "https://files.pythonhosted.org/packages/bd/6e/61ebf08d8940553afff20d1fb1ba7294b6f8d279df9fd0c0db911b4bbcfd/MarkupSafe-3.0.2-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:b424c77b206d63d500bcb69fa55ed8d0e6a3774056bdc4839fc9298a7edca171", size = 21091, upload-time = "2024-10-18T15:20:59.235Z" }, - { url = "https://files.pythonhosted.org/packages/11/23/ffbf53694e8c94ebd1e7e491de185124277964344733c45481f32ede2499/MarkupSafe-3.0.2-cp310-cp310-win32.whl", hash = "sha256:fcabf5ff6eea076f859677f5f0b6b5c1a51e70a376b0579e0eadef8db48c6b50", size = 15065, upload-time = "2024-10-18T15:21:00.307Z" }, - { url = "https://files.pythonhosted.org/packages/44/06/e7175d06dd6e9172d4a69a72592cb3f7a996a9c396eee29082826449bbc3/MarkupSafe-3.0.2-cp310-cp310-win_amd64.whl", hash = "sha256:6af100e168aa82a50e186c82875a5893c5597a0c1ccdb0d8b40240b1f28b969a", size = 15514, upload-time = "2024-10-18T15:21:01.122Z" }, { url = "https://files.pythonhosted.org/packages/6b/28/bbf83e3f76936960b850435576dd5e67034e200469571be53f69174a2dfd/MarkupSafe-3.0.2-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:9025b4018f3a1314059769c7bf15441064b2207cb3f065e6ea1e7359cb46db9d", size = 14353, upload-time = "2024-10-18T15:21:02.187Z" }, { url = "https://files.pythonhosted.org/packages/6c/30/316d194b093cde57d448a4c3209f22e3046c5bb2fb0820b118292b334be7/MarkupSafe-3.0.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:93335ca3812df2f366e80509ae119189886b0f3c2b81325d39efdb84a1e2ae93", size = 12392, upload-time = "2024-10-18T15:21:02.941Z" }, { url = "https://files.pythonhosted.org/packages/f2/96/9cdafba8445d3a53cae530aaf83c38ec64c4d5427d975c974084af5bc5d2/MarkupSafe-3.0.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2cb8438c3cbb25e220c2ab33bb226559e7afb3baec11c4f218ffa7308603c832", size = 23984, upload-time = "2024-10-18T15:21:03.953Z" }, @@ -1203,22 +1010,6 @@ 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/b9/2b/870f0ff5ecf312c58500f45950751f214b7068665e66e9bfd8bc2595587c/mmh3-5.2.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:81c504ad11c588c8629536b032940f2a359dda3b6cbfd4ad8f74cb24dcd1b0bc", size = 56119, upload-time = "2025-07-29T07:41:39.117Z" }, - { url = "https://files.pythonhosted.org/packages/3b/88/eb9a55b3f3cf43a74d6bfa8db0e2e209f966007777a1dc897c52c008314c/mmh3-5.2.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:0b898cecff57442724a0f52bf42c2de42de63083a91008fb452887e372f9c328", size = 40634, upload-time = "2025-07-29T07:41:40.626Z" }, - { url = "https://files.pythonhosted.org/packages/d1/4c/8e4b3878bf8435c697d7ce99940a3784eb864521768069feaccaff884a17/mmh3-5.2.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:be1374df449465c9f2500e62eee73a39db62152a8bdfbe12ec5b5c1cd451344d", size = 40080, upload-time = "2025-07-29T07:41:41.791Z" }, - { url = "https://files.pythonhosted.org/packages/45/ac/0a254402c8c5ca424a0a9ebfe870f5665922f932830f0a11a517b6390a09/mmh3-5.2.0-cp310-cp310-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:b0d753ad566c721faa33db7e2e0eddd74b224cdd3eaf8481d76c926603c7a00e", size = 95321, upload-time = "2025-07-29T07:41:42.659Z" }, - { url = "https://files.pythonhosted.org/packages/39/8e/29306d5eca6dfda4b899d22c95b5420db4e0ffb7e0b6389b17379654ece5/mmh3-5.2.0-cp310-cp310-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:dfbead5575f6470c17e955b94f92d62a03dfc3d07f2e6f817d9b93dc211a1515", size = 101220, upload-time = "2025-07-29T07:41:43.572Z" }, - { url = "https://files.pythonhosted.org/packages/49/f7/0dd1368e531e52a17b5b8dd2f379cce813bff2d0978a7748a506f1231152/mmh3-5.2.0-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:7434a27754049144539d2099a6d2da5d88b8bdeedf935180bf42ad59b3607aa3", size = 103991, upload-time = "2025-07-29T07:41:44.914Z" }, - { url = "https://files.pythonhosted.org/packages/35/06/abc7122c40f4abbfcef01d2dac6ec0b77ede9757e5be8b8a40a6265b1274/mmh3-5.2.0-cp310-cp310-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:cadc16e8ea64b5d9a47363013e2bea469e121e6e7cb416a7593aeb24f2ad122e", size = 110894, upload-time = "2025-07-29T07:41:45.849Z" }, - { url = "https://files.pythonhosted.org/packages/f4/2f/837885759afa4baccb8e40456e1cf76a4f3eac835b878c727ae1286c5f82/mmh3-5.2.0-cp310-cp310-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:d765058da196f68dc721116cab335e696e87e76720e6ef8ee5a24801af65e63d", size = 118327, upload-time = "2025-07-29T07:41:47.224Z" }, - { url = "https://files.pythonhosted.org/packages/40/cc/5683ba20a21bcfb3f1605b1c474f46d30354f728a7412201f59f453d405a/mmh3-5.2.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:8b0c53fe0994beade1ad7c0f13bd6fec980a0664bfbe5a6a7d64500b9ab76772", size = 101701, upload-time = "2025-07-29T07:41:48.259Z" }, - { url = "https://files.pythonhosted.org/packages/0e/24/99ab3fb940150aec8a26dbdfc39b200b5592f6aeb293ec268df93e054c30/mmh3-5.2.0-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:49037d417419863b222ae47ee562b2de9c3416add0a45c8d7f4e864be8dc4f89", size = 96712, upload-time = "2025-07-29T07:41:49.467Z" }, - { url = "https://files.pythonhosted.org/packages/61/04/d7c4cb18f1f001ede2e8aed0f9dbbfad03d161c9eea4fffb03f14f4523e5/mmh3-5.2.0-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:6ecb4e750d712abde046858ee6992b65c93f1f71b397fce7975c3860c07365d2", size = 110302, upload-time = "2025-07-29T07:41:50.387Z" }, - { url = "https://files.pythonhosted.org/packages/d8/bf/4dac37580cfda74425a4547500c36fa13ef581c8a756727c37af45e11e9a/mmh3-5.2.0-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:382a6bb3f8c6532ea084e7acc5be6ae0c6effa529240836d59352398f002e3fc", size = 111929, upload-time = "2025-07-29T07:41:51.348Z" }, - { url = "https://files.pythonhosted.org/packages/eb/b1/49f0a582c7a942fb71ddd1ec52b7d21d2544b37d2b2d994551346a15b4f6/mmh3-5.2.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:7733ec52296fc1ba22e9b90a245c821adbb943e98c91d8a330a2254612726106", size = 100111, upload-time = "2025-07-29T07:41:53.139Z" }, - { url = "https://files.pythonhosted.org/packages/dc/94/ccec09f438caeb2506f4c63bb3b99aa08a9e09880f8fc047295154756210/mmh3-5.2.0-cp310-cp310-win32.whl", hash = "sha256:127c95336f2a98c51e7682341ab7cb0be3adb9df0819ab8505a726ed1801876d", size = 40783, upload-time = "2025-07-29T07:41:54.463Z" }, - { url = "https://files.pythonhosted.org/packages/ea/f4/8d39a32c8203c1cdae88fdb04d1ea4aa178c20f159df97f4c5a2eaec702c/mmh3-5.2.0-cp310-cp310-win_amd64.whl", hash = "sha256:419005f84ba1cab47a77465a2a843562dadadd6671b8758bf179d82a15ca63eb", size = 41549, upload-time = "2025-07-29T07:41:55.295Z" }, - { url = "https://files.pythonhosted.org/packages/cc/a1/30efb1cd945e193f62574144dd92a0c9ee6463435e4e8ffce9b9e9f032f0/mmh3-5.2.0-cp310-cp310-win_arm64.whl", hash = "sha256:d22c9dcafed659fadc605538946c041722b6d1104fe619dbf5cc73b3c8a0ded8", size = 39335, upload-time = "2025-07-29T07:41:56.194Z" }, { url = "https://files.pythonhosted.org/packages/f7/87/399567b3796e134352e11a8b973cd470c06b2ecfad5468fe580833be442b/mmh3-5.2.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:7901c893e704ee3c65f92d39b951f8f34ccf8e8566768c58103fb10e55afb8c1", size = 56107, upload-time = "2025-07-29T07:41:57.07Z" }, { url = "https://files.pythonhosted.org/packages/c3/09/830af30adf8678955b247d97d3d9543dd2fd95684f3cd41c0cd9d291da9f/mmh3-5.2.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:4a5f5536b1cbfa72318ab3bfc8a8188b949260baed186b75f0abc75b95d8c051", size = 40635, upload-time = "2025-07-29T07:41:57.903Z" }, { url = "https://files.pythonhosted.org/packages/07/14/eaba79eef55b40d653321765ac5e8f6c9ac38780b8a7c2a2f8df8ee0fb72/mmh3-5.2.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:cedac4f4054b8f7859e5aed41aaa31ad03fce6851901a7fdc2af0275ac533c10", size = 40078, upload-time = "2025-07-29T07:41:58.772Z" }, @@ -1241,26 +1032,8 @@ name = "multidict" version = "6.1.0" source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "typing-extensions", marker = "python_full_version < '3.11'" }, -] sdist = { url = "https://files.pythonhosted.org/packages/d6/be/504b89a5e9ca731cd47487e91c469064f8ae5af93b7259758dcfc2b9c848/multidict-6.1.0.tar.gz", hash = "sha256:22ae2ebf9b0c69d206c003e2f6a914ea33f0a932d4aa16f236afc049d9958f4a", size = 64002, upload-time = "2024-09-09T23:49:38.163Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/29/68/259dee7fd14cf56a17c554125e534f6274c2860159692a414d0b402b9a6d/multidict-6.1.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:3380252550e372e8511d49481bd836264c009adb826b23fefcc5dd3c69692f60", size = 48628, upload-time = "2024-09-09T23:47:18.278Z" }, - { url = "https://files.pythonhosted.org/packages/50/79/53ba256069fe5386a4a9e80d4e12857ced9de295baf3e20c68cdda746e04/multidict-6.1.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:99f826cbf970077383d7de805c0681799491cb939c25450b9b5b3ced03ca99f1", size = 29327, upload-time = "2024-09-09T23:47:20.224Z" }, - { url = "https://files.pythonhosted.org/packages/ff/10/71f1379b05b196dae749b5ac062e87273e3f11634f447ebac12a571d90ae/multidict-6.1.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:a114d03b938376557927ab23f1e950827c3b893ccb94b62fd95d430fd0e5cf53", size = 29689, upload-time = "2024-09-09T23:47:21.667Z" }, - { url = "https://files.pythonhosted.org/packages/71/45/70bac4f87438ded36ad4793793c0095de6572d433d98575a5752629ef549/multidict-6.1.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b1c416351ee6271b2f49b56ad7f308072f6f44b37118d69c2cad94f3fa8a40d5", size = 126639, upload-time = "2024-09-09T23:47:23.333Z" }, - { url = "https://files.pythonhosted.org/packages/80/cf/17f35b3b9509b4959303c05379c4bfb0d7dd05c3306039fc79cf035bbac0/multidict-6.1.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:6b5d83030255983181005e6cfbac1617ce9746b219bc2aad52201ad121226581", size = 134315, upload-time = "2024-09-09T23:47:24.99Z" }, - { url = "https://files.pythonhosted.org/packages/ef/1f/652d70ab5effb33c031510a3503d4d6efc5ec93153562f1ee0acdc895a57/multidict-6.1.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3e97b5e938051226dc025ec80980c285b053ffb1e25a3db2a3aa3bc046bf7f56", size = 129471, upload-time = "2024-09-09T23:47:26.305Z" }, - { url = "https://files.pythonhosted.org/packages/a6/64/2dd6c4c681688c0165dea3975a6a4eab4944ea30f35000f8b8af1df3148c/multidict-6.1.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d618649d4e70ac6efcbba75be98b26ef5078faad23592f9b51ca492953012429", size = 124585, upload-time = "2024-09-09T23:47:27.958Z" }, - { url = "https://files.pythonhosted.org/packages/87/56/e6ee5459894c7e554b57ba88f7257dc3c3d2d379cb15baaa1e265b8c6165/multidict-6.1.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:10524ebd769727ac77ef2278390fb0068d83f3acb7773792a5080f2b0abf7748", size = 116957, upload-time = "2024-09-09T23:47:29.376Z" }, - { url = "https://files.pythonhosted.org/packages/36/9e/616ce5e8d375c24b84f14fc263c7ef1d8d5e8ef529dbc0f1df8ce71bb5b8/multidict-6.1.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:ff3827aef427c89a25cc96ded1759271a93603aba9fb977a6d264648ebf989db", size = 128609, upload-time = "2024-09-09T23:47:31.038Z" }, - { url = "https://files.pythonhosted.org/packages/8c/4f/4783e48a38495d000f2124020dc96bacc806a4340345211b1ab6175a6cb4/multidict-6.1.0-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:06809f4f0f7ab7ea2cabf9caca7d79c22c0758b58a71f9d32943ae13c7ace056", size = 123016, upload-time = "2024-09-09T23:47:32.47Z" }, - { url = "https://files.pythonhosted.org/packages/3e/b3/4950551ab8fc39862ba5e9907dc821f896aa829b4524b4deefd3e12945ab/multidict-6.1.0-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:f179dee3b863ab1c59580ff60f9d99f632f34ccb38bf67a33ec6b3ecadd0fd76", size = 133542, upload-time = "2024-09-09T23:47:34.103Z" }, - { url = "https://files.pythonhosted.org/packages/96/4d/f0ce6ac9914168a2a71df117935bb1f1781916acdecbb43285e225b484b8/multidict-6.1.0-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:aaed8b0562be4a0876ee3b6946f6869b7bcdb571a5d1496683505944e268b160", size = 130163, upload-time = "2024-09-09T23:47:35.716Z" }, - { url = "https://files.pythonhosted.org/packages/be/72/17c9f67e7542a49dd252c5ae50248607dfb780bcc03035907dafefb067e3/multidict-6.1.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:3c8b88a2ccf5493b6c8da9076fb151ba106960a2df90c2633f342f120751a9e7", size = 126832, upload-time = "2024-09-09T23:47:37.116Z" }, - { url = "https://files.pythonhosted.org/packages/71/9f/72d719e248cbd755c8736c6d14780533a1606ffb3fbb0fbd77da9f0372da/multidict-6.1.0-cp310-cp310-win32.whl", hash = "sha256:4a9cb68166a34117d6646c0023c7b759bf197bee5ad4272f420a0141d7eb03a0", size = 26402, upload-time = "2024-09-09T23:47:38.863Z" }, - { url = "https://files.pythonhosted.org/packages/04/5a/d88cd5d00a184e1ddffc82aa2e6e915164a6d2641ed3606e766b5d2f275a/multidict-6.1.0-cp310-cp310-win_amd64.whl", hash = "sha256:20b9b5fbe0b88d0bdef2012ef7dee867f874b72528cf1d08f1d59b0e3850129d", size = 28800, upload-time = "2024-09-09T23:47:40.056Z" }, { url = "https://files.pythonhosted.org/packages/93/13/df3505a46d0cd08428e4c8169a196131d1b0c4b515c3649829258843dde6/multidict-6.1.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:3efe2c2cb5763f2f1b275ad2bf7a287d3f7ebbef35648a9726e3b69284a4f3d6", size = 48570, upload-time = "2024-09-09T23:47:41.36Z" }, { url = "https://files.pythonhosted.org/packages/f0/e1/a215908bfae1343cdb72f805366592bdd60487b4232d039c437fe8f5013d/multidict-6.1.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:c7053d3b0353a8b9de430a4f4b4268ac9a4fb3481af37dfe49825bf45ca24156", size = 29316, upload-time = "2024-09-09T23:47:42.612Z" }, { url = "https://files.pythonhosted.org/packages/70/0f/6dc70ddf5d442702ed74f298d69977f904960b82368532c88e854b79f72b/multidict-6.1.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:27e5fc84ccef8dfaabb09d82b7d179c7cf1a3fbc8a966f8274fcb4ab2eb4cadb", size = 29640, upload-time = "2024-09-09T23:47:44.028Z" }, @@ -1289,8 +1062,7 @@ { name = "markdown-it-py" }, { name = "mdit-py-plugins" }, { name = "pyyaml" }, - { name = "sphinx", version = "8.1.3", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.11'" }, - { name = "sphinx", version = "8.2.3", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.11'" }, + { name = "sphinx" }, ] sdist = { url = "https://files.pythonhosted.org/packages/66/a5/9626ba4f73555b3735ad86247a8077d4603aa8628537687c839ab08bfe44/myst_parser-4.0.1.tar.gz", hash = "sha256:5cfea715e4f3574138aecbf7d54132296bfd72bb614d31168f48c477a830a7c4", size = 93985, upload-time = "2025-02-12T10:53:03.833Z" } wheels = [ @@ -1308,23 +1080,8 @@ [[package]] name = "networkx" -version = "3.4.2" -source = { registry = "https://pypi.org/simple" } -resolution-markers = [ - "python_full_version < '3.11'", -] -sdist = { url = "https://files.pythonhosted.org/packages/fd/1d/06475e1cd5264c0b870ea2cc6fdb3e37177c1e565c43f56ff17a10e3937f/networkx-3.4.2.tar.gz", hash = "sha256:307c3669428c5362aab27c8a1260aa8f47c4e91d3891f48be0141738d8d053e1", size = 2151368, upload-time = "2024-10-21T12:39:38.695Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/b9/54/dd730b32ea14ea797530a4479b2ed46a6fb250f682a9cfb997e968bf0261/networkx-3.4.2-py3-none-any.whl", hash = "sha256:df5d4365b724cf81b8c6a7312509d0c22386097011ad1abe274afd5e9d3bbc5f", size = 1723263, upload-time = "2024-10-21T12:39:36.247Z" }, -] - -[[package]] -name = "networkx" version = "3.5" source = { registry = "https://pypi.org/simple" } -resolution-markers = [ - "python_full_version >= '3.11'", -] sdist = { url = "https://files.pythonhosted.org/packages/6c/4f/ccdb8ad3a38e583f214547fd2f7ff1fc160c43a75af88e6aec213404b96a/networkx-3.5.tar.gz", hash = "sha256:d4c6f9cf81f52d69230866796b82afbccdec3db7ae4fbd1b65ea750feed50037", size = 2471065, upload-time = "2025-05-29T11:35:07.804Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/eb/8d/776adee7bbf76365fdd7f2552710282c79a4ead5d2a46408c9043a2b70ba/networkx-3.5-py3-none-any.whl", hash = "sha256:0030d386a9a06dee3565298b4a734b68589749a544acbb6c412dc9e2489ec6ec", size = 2034406, upload-time = "2025-05-29T11:35:04.961Z" }, @@ -1332,46 +1089,8 @@ [[package]] name = "numpy" -version = "2.2.6" -source = { registry = "https://pypi.org/simple" } -resolution-markers = [ - "python_full_version < '3.11'", -] -sdist = { url = "https://files.pythonhosted.org/packages/76/21/7d2a95e4bba9dc13d043ee156a356c0a8f0c6309dff6b21b4d71a073b8a8/numpy-2.2.6.tar.gz", hash = "sha256:e29554e2bef54a90aa5cc07da6ce955accb83f21ab5de01a62c8478897b264fd", size = 20276440, upload-time = "2025-05-17T22:38:04.611Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/9a/3e/ed6db5be21ce87955c0cbd3009f2803f59fa08df21b5df06862e2d8e2bdd/numpy-2.2.6-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:b412caa66f72040e6d268491a59f2c43bf03eb6c96dd8f0307829feb7fa2b6fb", size = 21165245, upload-time = "2025-05-17T21:27:58.555Z" }, - { url = "https://files.pythonhosted.org/packages/22/c2/4b9221495b2a132cc9d2eb862e21d42a009f5a60e45fc44b00118c174bff/numpy-2.2.6-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:8e41fd67c52b86603a91c1a505ebaef50b3314de0213461c7a6e99c9a3beff90", size = 14360048, upload-time = "2025-05-17T21:28:21.406Z" }, - { url = "https://files.pythonhosted.org/packages/fd/77/dc2fcfc66943c6410e2bf598062f5959372735ffda175b39906d54f02349/numpy-2.2.6-cp310-cp310-macosx_14_0_arm64.whl", hash = "sha256:37e990a01ae6ec7fe7fa1c26c55ecb672dd98b19c3d0e1d1f326fa13cb38d163", size = 5340542, upload-time = "2025-05-17T21:28:30.931Z" }, - { url = "https://files.pythonhosted.org/packages/7a/4f/1cb5fdc353a5f5cc7feb692db9b8ec2c3d6405453f982435efc52561df58/numpy-2.2.6-cp310-cp310-macosx_14_0_x86_64.whl", hash = "sha256:5a6429d4be8ca66d889b7cf70f536a397dc45ba6faeb5f8c5427935d9592e9cf", size = 6878301, upload-time = "2025-05-17T21:28:41.613Z" }, - { url = "https://files.pythonhosted.org/packages/eb/17/96a3acd228cec142fcb8723bd3cc39c2a474f7dcf0a5d16731980bcafa95/numpy-2.2.6-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:efd28d4e9cd7d7a8d39074a4d44c63eda73401580c5c76acda2ce969e0a38e83", size = 14297320, upload-time = "2025-05-17T21:29:02.78Z" }, - { url = "https://files.pythonhosted.org/packages/b4/63/3de6a34ad7ad6646ac7d2f55ebc6ad439dbbf9c4370017c50cf403fb19b5/numpy-2.2.6-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fc7b73d02efb0e18c000e9ad8b83480dfcd5dfd11065997ed4c6747470ae8915", size = 16801050, upload-time = "2025-05-17T21:29:27.675Z" }, - { url = "https://files.pythonhosted.org/packages/07/b6/89d837eddef52b3d0cec5c6ba0456c1bf1b9ef6a6672fc2b7873c3ec4e2e/numpy-2.2.6-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:74d4531beb257d2c3f4b261bfb0fc09e0f9ebb8842d82a7b4209415896adc680", size = 15807034, upload-time = "2025-05-17T21:29:51.102Z" }, - { url = "https://files.pythonhosted.org/packages/01/c8/dc6ae86e3c61cfec1f178e5c9f7858584049b6093f843bca541f94120920/numpy-2.2.6-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:8fc377d995680230e83241d8a96def29f204b5782f371c532579b4f20607a289", size = 18614185, upload-time = "2025-05-17T21:30:18.703Z" }, - { url = "https://files.pythonhosted.org/packages/5b/c5/0064b1b7e7c89137b471ccec1fd2282fceaae0ab3a9550f2568782d80357/numpy-2.2.6-cp310-cp310-win32.whl", hash = "sha256:b093dd74e50a8cba3e873868d9e93a85b78e0daf2e98c6797566ad8044e8363d", size = 6527149, upload-time = "2025-05-17T21:30:29.788Z" }, - { url = "https://files.pythonhosted.org/packages/a3/dd/4b822569d6b96c39d1215dbae0582fd99954dcbcf0c1a13c61783feaca3f/numpy-2.2.6-cp310-cp310-win_amd64.whl", hash = "sha256:f0fd6321b839904e15c46e0d257fdd101dd7f530fe03fd6359c1ea63738703f3", size = 12904620, upload-time = "2025-05-17T21:30:48.994Z" }, - { url = "https://files.pythonhosted.org/packages/da/a8/4f83e2aa666a9fbf56d6118faaaf5f1974d456b1823fda0a176eff722839/numpy-2.2.6-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:f9f1adb22318e121c5c69a09142811a201ef17ab257a1e66ca3025065b7f53ae", size = 21176963, upload-time = "2025-05-17T21:31:19.36Z" }, - { url = "https://files.pythonhosted.org/packages/b3/2b/64e1affc7972decb74c9e29e5649fac940514910960ba25cd9af4488b66c/numpy-2.2.6-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:c820a93b0255bc360f53eca31a0e676fd1101f673dda8da93454a12e23fc5f7a", size = 14406743, upload-time = "2025-05-17T21:31:41.087Z" }, - { url = "https://files.pythonhosted.org/packages/4a/9f/0121e375000b5e50ffdd8b25bf78d8e1a5aa4cca3f185d41265198c7b834/numpy-2.2.6-cp311-cp311-macosx_14_0_arm64.whl", hash = "sha256:3d70692235e759f260c3d837193090014aebdf026dfd167834bcba43e30c2a42", size = 5352616, upload-time = "2025-05-17T21:31:50.072Z" }, - { url = "https://files.pythonhosted.org/packages/31/0d/b48c405c91693635fbe2dcd7bc84a33a602add5f63286e024d3b6741411c/numpy-2.2.6-cp311-cp311-macosx_14_0_x86_64.whl", hash = "sha256:481b49095335f8eed42e39e8041327c05b0f6f4780488f61286ed3c01368d491", size = 6889579, upload-time = "2025-05-17T21:32:01.712Z" }, - { url = "https://files.pythonhosted.org/packages/52/b8/7f0554d49b565d0171eab6e99001846882000883998e7b7d9f0d98b1f934/numpy-2.2.6-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b64d8d4d17135e00c8e346e0a738deb17e754230d7e0810ac5012750bbd85a5a", size = 14312005, upload-time = "2025-05-17T21:32:23.332Z" }, - { url = "https://files.pythonhosted.org/packages/b3/dd/2238b898e51bd6d389b7389ffb20d7f4c10066d80351187ec8e303a5a475/numpy-2.2.6-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ba10f8411898fc418a521833e014a77d3ca01c15b0c6cdcce6a0d2897e6dbbdf", size = 16821570, upload-time = "2025-05-17T21:32:47.991Z" }, - { url = "https://files.pythonhosted.org/packages/83/6c/44d0325722cf644f191042bf47eedad61c1e6df2432ed65cbe28509d404e/numpy-2.2.6-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:bd48227a919f1bafbdda0583705e547892342c26fb127219d60a5c36882609d1", size = 15818548, upload-time = "2025-05-17T21:33:11.728Z" }, - { url = "https://files.pythonhosted.org/packages/ae/9d/81e8216030ce66be25279098789b665d49ff19eef08bfa8cb96d4957f422/numpy-2.2.6-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:9551a499bf125c1d4f9e250377c1ee2eddd02e01eac6644c080162c0c51778ab", size = 18620521, upload-time = "2025-05-17T21:33:39.139Z" }, - { url = "https://files.pythonhosted.org/packages/6a/fd/e19617b9530b031db51b0926eed5345ce8ddc669bb3bc0044b23e275ebe8/numpy-2.2.6-cp311-cp311-win32.whl", hash = "sha256:0678000bb9ac1475cd454c6b8c799206af8107e310843532b04d49649c717a47", size = 6525866, upload-time = "2025-05-17T21:33:50.273Z" }, - { url = "https://files.pythonhosted.org/packages/31/0a/f354fb7176b81747d870f7991dc763e157a934c717b67b58456bc63da3df/numpy-2.2.6-cp311-cp311-win_amd64.whl", hash = "sha256:e8213002e427c69c45a52bbd94163084025f533a55a59d6f9c5b820774ef3303", size = 12907455, upload-time = "2025-05-17T21:34:09.135Z" }, - { url = "https://files.pythonhosted.org/packages/9e/3b/d94a75f4dbf1ef5d321523ecac21ef23a3cd2ac8b78ae2aac40873590229/numpy-2.2.6-pp310-pypy310_pp73-macosx_10_15_x86_64.whl", hash = "sha256:0b605b275d7bd0c640cad4e5d30fa701a8d59302e127e5f79138ad62762c3e3d", size = 21040391, upload-time = "2025-05-17T21:44:35.948Z" }, - { url = "https://files.pythonhosted.org/packages/17/f4/09b2fa1b58f0fb4f7c7963a1649c64c4d315752240377ed74d9cd878f7b5/numpy-2.2.6-pp310-pypy310_pp73-macosx_14_0_x86_64.whl", hash = "sha256:7befc596a7dc9da8a337f79802ee8adb30a552a94f792b9c9d18c840055907db", size = 6786754, upload-time = "2025-05-17T21:44:47.446Z" }, - { url = "https://files.pythonhosted.org/packages/af/30/feba75f143bdc868a1cc3f44ccfa6c4b9ec522b36458e738cd00f67b573f/numpy-2.2.6-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ce47521a4754c8f4593837384bd3424880629f718d87c5d44f8ed763edd63543", size = 16643476, upload-time = "2025-05-17T21:45:11.871Z" }, - { url = "https://files.pythonhosted.org/packages/37/48/ac2a9584402fb6c0cd5b5d1a91dcf176b15760130dd386bbafdbfe3640bf/numpy-2.2.6-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:d042d24c90c41b54fd506da306759e06e568864df8ec17ccc17e9e884634fd00", size = 12812666, upload-time = "2025-05-17T21:45:31.426Z" }, -] - -[[package]] -name = "numpy" version = "2.3.3" source = { registry = "https://pypi.org/simple" } -resolution-markers = [ - "python_full_version >= '3.11'", -] sdist = { url = "https://files.pythonhosted.org/packages/d0/19/95b3d357407220ed24c139018d2518fab0a61a948e68286a25f1a4d049ff/numpy-2.3.3.tar.gz", hash = "sha256:ddc7c39727ba62b80dfdbedf400d1c10ddfa8eefbd7ec8dcb118be8b56d31029", size = 20576648, upload-time = "2025-09-09T16:54:12.543Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/7a/45/e80d203ef6b267aa29b22714fb558930b27960a0c5ce3c19c999232bb3eb/numpy-2.3.3-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:0ffc4f5caba7dfcbe944ed674b7eef683c7e94874046454bb79ed7ee0236f59d", size = 21259253, upload-time = "2025-09-09T15:56:02.094Z" }, @@ -1420,11 +1139,9 @@ { name = "duckdb" }, { name = "fsspec" }, { name = "httpx" }, - { name = "ipython", version = "8.37.0", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.11'" }, - { name = "ipython", version = "9.5.0", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.11'" }, + { name = "ipython" }, { name = "irods-fsspec" }, - { name = "numpy", version = "2.2.6", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.11'" }, - { name = "numpy", version = "2.3.3", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.11'" }, + { name = "numpy" }, { name = "pandas" }, { name = "py4lexis" }, { name = "pyarrow" }, @@ -1457,13 +1174,11 @@ ] docs = [ { name = "myst-parser" }, - { name = "sphinx", version = "8.1.3", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.11'" }, - { name = "sphinx", version = "8.2.3", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.11'" }, + { name = "sphinx" }, { name = "sphinx-multiversion" }, ] graph = [ - { name = "networkx", version = "3.4.2", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.11'" }, - { name = "networkx", version = "3.5", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.11'" }, + { name = "networkx" }, { name = "plotly" }, ] opensearch = [ @@ -1564,21 +1279,13 @@ version = "2.2.3" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "numpy", version = "2.2.6", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.11'" }, - { name = "numpy", version = "2.3.3", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.11'" }, + { name = "numpy" }, { name = "python-dateutil" }, { name = "pytz" }, { name = "tzdata" }, ] sdist = { url = "https://files.pythonhosted.org/packages/9c/d6/9f8431bacc2e19dca897724cd097b1bb224a6ad5433784a44b587c7c13af/pandas-2.2.3.tar.gz", hash = "sha256:4f18ba62b61d7e192368b84517265a99b4d7ee8912f8708660fb4a366cc82667", size = 4399213, upload-time = "2024-09-20T13:10:04.827Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/aa/70/c853aec59839bceed032d52010ff5f1b8d87dc3114b762e4ba2727661a3b/pandas-2.2.3-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:1948ddde24197a0f7add2bdc4ca83bf2b1ef84a1bc8ccffd95eda17fd836ecb5", size = 12580827, upload-time = "2024-09-20T13:08:42.347Z" }, - { url = "https://files.pythonhosted.org/packages/99/f2/c4527768739ffa4469b2b4fff05aa3768a478aed89a2f271a79a40eee984/pandas-2.2.3-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:381175499d3802cde0eabbaf6324cce0c4f5d52ca6f8c377c29ad442f50f6348", size = 11303897, upload-time = "2024-09-20T13:08:45.807Z" }, - { url = "https://files.pythonhosted.org/packages/ed/12/86c1747ea27989d7a4064f806ce2bae2c6d575b950be087837bdfcabacc9/pandas-2.2.3-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:d9c45366def9a3dd85a6454c0e7908f2b3b8e9c138f5dc38fed7ce720d8453ed", size = 66480908, upload-time = "2024-09-20T18:37:13.513Z" }, - { url = "https://files.pythonhosted.org/packages/44/50/7db2cd5e6373ae796f0ddad3675268c8d59fb6076e66f0c339d61cea886b/pandas-2.2.3-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:86976a1c5b25ae3f8ccae3a5306e443569ee3c3faf444dfd0f41cda24667ad57", size = 13064210, upload-time = "2024-09-20T13:08:48.325Z" }, - { url = "https://files.pythonhosted.org/packages/61/61/a89015a6d5536cb0d6c3ba02cebed51a95538cf83472975275e28ebf7d0c/pandas-2.2.3-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:b8661b0238a69d7aafe156b7fa86c44b881387509653fdf857bebc5e4008ad42", size = 16754292, upload-time = "2024-09-20T19:01:54.443Z" }, - { url = "https://files.pythonhosted.org/packages/ce/0d/4cc7b69ce37fac07645a94e1d4b0880b15999494372c1523508511b09e40/pandas-2.2.3-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:37e0aced3e8f539eccf2e099f65cdb9c8aa85109b0be6e93e2baff94264bdc6f", size = 14416379, upload-time = "2024-09-20T13:08:50.882Z" }, - { url = "https://files.pythonhosted.org/packages/31/9e/6ebb433de864a6cd45716af52a4d7a8c3c9aaf3a98368e61db9e69e69a9c/pandas-2.2.3-cp310-cp310-win_amd64.whl", hash = "sha256:56534ce0746a58afaf7942ba4863e0ef81c9c50d3f0ae93e9497d6a41a057645", size = 11598471, upload-time = "2024-09-20T13:08:53.332Z" }, { url = "https://files.pythonhosted.org/packages/a8/44/d9502bf0ed197ba9bf1103c9867d5904ddcaf869e52329787fc54ed70cc8/pandas-2.2.3-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:66108071e1b935240e74525006034333f98bcdb87ea116de573a6a0dccb6c039", size = 12602222, upload-time = "2024-09-20T13:08:56.254Z" }, { url = "https://files.pythonhosted.org/packages/52/11/9eac327a38834f162b8250aab32a6781339c69afe7574368fffe46387edf/pandas-2.2.3-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:7c2875855b0ff77b2a64a0365e24455d9990730d6431b9e0ee18ad8acee13dbd", size = 11321274, upload-time = "2024-09-20T13:08:58.645Z" }, { url = "https://files.pythonhosted.org/packages/45/fb/c4beeb084718598ba19aa9f5abbc8aed8b42f90930da861fcb1acdb54c3a/pandas-2.2.3-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:cd8d0c3be0515c12fed0bdbae072551c8b54b7192c7b1fda0ba56059a0179698", size = 15579836, upload-time = "2024-09-20T19:01:57.571Z" }, @@ -1692,22 +1399,6 @@ source = { registry = "https://pypi.org/simple" } sdist = { url = "https://files.pythonhosted.org/packages/a9/4d/5e5a60b78dbc1d464f8a7bbaeb30957257afdc8512cbb9dfd5659304f5cd/propcache-0.2.0.tar.gz", hash = "sha256:df81779732feb9d01e5d513fad0122efb3d53bbc75f61b2a4f29a020bc985e70", size = 40951, upload-time = "2024-10-07T12:56:36.896Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/3a/08/1963dfb932b8d74d5b09098507b37e9b96c835ba89ab8aad35aa330f4ff3/propcache-0.2.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:c5869b8fd70b81835a6f187c5fdbe67917a04d7e52b6e7cc4e5fe39d55c39d58", size = 80712, upload-time = "2024-10-07T12:54:02.193Z" }, - { url = "https://files.pythonhosted.org/packages/e6/59/49072aba9bf8a8ed958e576182d46f038e595b17ff7408bc7e8807e721e1/propcache-0.2.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:952e0d9d07609d9c5be361f33b0d6d650cd2bae393aabb11d9b719364521984b", size = 46301, upload-time = "2024-10-07T12:54:03.576Z" }, - { url = "https://files.pythonhosted.org/packages/33/a2/6b1978c2e0d80a678e2c483f45e5443c15fe5d32c483902e92a073314ef1/propcache-0.2.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:33ac8f098df0585c0b53009f039dfd913b38c1d2edafed0cedcc0c32a05aa110", size = 45581, upload-time = "2024-10-07T12:54:05.415Z" }, - { url = "https://files.pythonhosted.org/packages/43/95/55acc9adff8f997c7572f23d41993042290dfb29e404cdadb07039a4386f/propcache-0.2.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:97e48e8875e6c13909c800fa344cd54cc4b2b0db1d5f911f840458a500fde2c2", size = 208659, upload-time = "2024-10-07T12:54:06.742Z" }, - { url = "https://files.pythonhosted.org/packages/bd/2c/ef7371ff715e6cd19ea03fdd5637ecefbaa0752fee5b0f2fe8ea8407ee01/propcache-0.2.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:388f3217649d6d59292b722d940d4d2e1e6a7003259eb835724092a1cca0203a", size = 222613, upload-time = "2024-10-07T12:54:08.204Z" }, - { url = "https://files.pythonhosted.org/packages/5e/1c/fef251f79fd4971a413fa4b1ae369ee07727b4cc2c71e2d90dfcde664fbb/propcache-0.2.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f571aea50ba5623c308aa146eb650eebf7dbe0fd8c5d946e28343cb3b5aad577", size = 221067, upload-time = "2024-10-07T12:54:10.449Z" }, - { url = "https://files.pythonhosted.org/packages/8d/e7/22e76ae6fc5a1708bdce92bdb49de5ebe89a173db87e4ef597d6bbe9145a/propcache-0.2.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3dfafb44f7bb35c0c06eda6b2ab4bfd58f02729e7c4045e179f9a861b07c9850", size = 208920, upload-time = "2024-10-07T12:54:11.903Z" }, - { url = "https://files.pythonhosted.org/packages/04/3e/f10aa562781bcd8a1e0b37683a23bef32bdbe501d9cc7e76969becaac30d/propcache-0.2.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a3ebe9a75be7ab0b7da2464a77bb27febcb4fab46a34f9288f39d74833db7f61", size = 200050, upload-time = "2024-10-07T12:54:13.292Z" }, - { url = "https://files.pythonhosted.org/packages/d0/98/8ac69f638358c5f2a0043809c917802f96f86026e86726b65006830f3dc6/propcache-0.2.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:d2f0d0f976985f85dfb5f3d685697ef769faa6b71993b46b295cdbbd6be8cc37", size = 202346, upload-time = "2024-10-07T12:54:14.644Z" }, - { url = "https://files.pythonhosted.org/packages/ee/78/4acfc5544a5075d8e660af4d4e468d60c418bba93203d1363848444511ad/propcache-0.2.0-cp310-cp310-musllinux_1_2_armv7l.whl", hash = "sha256:a3dc1a4b165283bd865e8f8cb5f0c64c05001e0718ed06250d8cac9bec115b48", size = 199750, upload-time = "2024-10-07T12:54:16.286Z" }, - { url = "https://files.pythonhosted.org/packages/a2/8f/90ada38448ca2e9cf25adc2fe05d08358bda1b9446f54a606ea38f41798b/propcache-0.2.0-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:9e0f07b42d2a50c7dd2d8675d50f7343d998c64008f1da5fef888396b7f84630", size = 201279, upload-time = "2024-10-07T12:54:17.752Z" }, - { url = "https://files.pythonhosted.org/packages/08/31/0e299f650f73903da851f50f576ef09bfffc8e1519e6a2f1e5ed2d19c591/propcache-0.2.0-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:e63e3e1e0271f374ed489ff5ee73d4b6e7c60710e1f76af5f0e1a6117cd26394", size = 211035, upload-time = "2024-10-07T12:54:19.109Z" }, - { url = "https://files.pythonhosted.org/packages/85/3e/e356cc6b09064bff1c06d0b2413593e7c925726f0139bc7acef8a21e87a8/propcache-0.2.0-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:56bb5c98f058a41bb58eead194b4db8c05b088c93d94d5161728515bd52b052b", size = 215565, upload-time = "2024-10-07T12:54:20.578Z" }, - { url = "https://files.pythonhosted.org/packages/8b/54/4ef7236cd657e53098bd05aa59cbc3cbf7018fba37b40eaed112c3921e51/propcache-0.2.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:7665f04d0c7f26ff8bb534e1c65068409bf4687aa2534faf7104d7182debb336", size = 207604, upload-time = "2024-10-07T12:54:22.588Z" }, - { url = "https://files.pythonhosted.org/packages/1f/27/d01d7799c068443ee64002f0655d82fb067496897bf74b632e28ee6a32cf/propcache-0.2.0-cp310-cp310-win32.whl", hash = "sha256:7cf18abf9764746b9c8704774d8b06714bcb0a63641518a3a89c7f85cc02c2ad", size = 40526, upload-time = "2024-10-07T12:54:23.867Z" }, - { url = "https://files.pythonhosted.org/packages/bb/44/6c2add5eeafb7f31ff0d25fbc005d930bea040a1364cf0f5768750ddf4d1/propcache-0.2.0-cp310-cp310-win_amd64.whl", hash = "sha256:cfac69017ef97db2438efb854edf24f5a29fd09a536ff3a992b75990720cdc99", size = 44958, upload-time = "2024-10-07T12:54:24.983Z" }, { url = "https://files.pythonhosted.org/packages/e0/1c/71eec730e12aec6511e702ad0cd73c2872eccb7cad39de8ba3ba9de693ef/propcache-0.2.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:63f13bf09cc3336eb04a837490b8f332e0db41da66995c9fd1ba04552e516354", size = 80811, upload-time = "2024-10-07T12:54:26.165Z" }, { url = "https://files.pythonhosted.org/packages/89/c3/7e94009f9a4934c48a371632197406a8860b9f08e3f7f7d922ab69e57a41/propcache-0.2.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:608cce1da6f2672a56b24a015b42db4ac612ee709f3d29f27a00c943d9e851de", size = 46365, upload-time = "2024-10-07T12:54:28.034Z" }, { url = "https://files.pythonhosted.org/packages/c0/1d/c700d16d1d6903aeab28372fe9999762f074b80b96a0ccc953175b858743/propcache-0.2.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:466c219deee4536fbc83c08d09115249db301550625c7fef1c5563a584c9bc87", size = 45602, upload-time = "2024-10-07T12:54:29.148Z" }, @@ -1789,8 +1480,7 @@ { name = "markdown-it-py" }, { name = "mdurl" }, { name = "multidict" }, - { name = "numpy", version = "2.2.6", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.11'" }, - { name = "numpy", version = "2.3.3", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.11'" }, + { name = "numpy" }, { name = "packaging" }, { name = "pandas" }, { name = "pipdeptree" }, @@ -1832,13 +1522,6 @@ source = { registry = "https://pypi.org/simple" } sdist = { url = "https://files.pythonhosted.org/packages/7f/09/a9046344212690f0632b9c709f9bf18506522feb333c894d0de81d62341a/pyarrow-19.0.1.tar.gz", hash = "sha256:3bf266b485df66a400f282ac0b6d1b500b9d2ae73314a153dbe97d6d5cc8a99e", size = 1129437, upload-time = "2025-02-18T18:55:57.027Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/36/01/b23b514d86b839956238d3f8ef206fd2728eee87ff1b8ce150a5678d9721/pyarrow-19.0.1-cp310-cp310-macosx_12_0_arm64.whl", hash = "sha256:fc28912a2dc924dddc2087679cc8b7263accc71b9ff025a1362b004711661a69", size = 30688914, upload-time = "2025-02-18T18:51:37.575Z" }, - { url = "https://files.pythonhosted.org/packages/c6/68/218ff7cf4a0652a933e5f2ed11274f724dd43b9813cb18dd72c0a35226a2/pyarrow-19.0.1-cp310-cp310-macosx_12_0_x86_64.whl", hash = "sha256:fca15aabbe9b8355800d923cc2e82c8ef514af321e18b437c3d782aa884eaeec", size = 32102866, upload-time = "2025-02-18T18:51:44.358Z" }, - { url = "https://files.pythonhosted.org/packages/98/01/c295050d183014f4a2eb796d7d2bbfa04b6cccde7258bb68aacf6f18779b/pyarrow-19.0.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ad76aef7f5f7e4a757fddcdcf010a8290958f09e3470ea458c80d26f4316ae89", size = 41147682, upload-time = "2025-02-18T18:51:49.481Z" }, - { url = "https://files.pythonhosted.org/packages/40/17/a6c3db0b5f3678f33bbb552d2acbc16def67f89a72955b67b0109af23eb0/pyarrow-19.0.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d03c9d6f2a3dffbd62671ca070f13fc527bb1867b4ec2b98c7eeed381d4f389a", size = 42179192, upload-time = "2025-02-18T18:51:56.265Z" }, - { url = "https://files.pythonhosted.org/packages/cf/75/c7c8e599300d8cebb6cb339014800e1c720c9db2a3fcb66aa64ec84bac72/pyarrow-19.0.1-cp310-cp310-manylinux_2_28_aarch64.whl", hash = "sha256:65cf9feebab489b19cdfcfe4aa82f62147218558d8d3f0fc1e9dea0ab8e7905a", size = 40517272, upload-time = "2025-02-18T18:52:02.969Z" }, - { url = "https://files.pythonhosted.org/packages/ef/c9/68ab123ee1528699c4d5055f645ecd1dd68ff93e4699527249d02f55afeb/pyarrow-19.0.1-cp310-cp310-manylinux_2_28_x86_64.whl", hash = "sha256:41f9706fbe505e0abc10e84bf3a906a1338905cbbcf1177b71486b03e6ea6608", size = 42069036, upload-time = "2025-02-18T18:52:10.173Z" }, - { url = "https://files.pythonhosted.org/packages/54/e3/d5cfd7654084e6c0d9c3ce949e5d9e0ccad569ae1e2d5a68a3ec03b2be89/pyarrow-19.0.1-cp310-cp310-win_amd64.whl", hash = "sha256:c6cb2335a411b713fdf1e82a752162f72d4a7b5dbc588e32aa18383318b05866", size = 25277951, upload-time = "2025-02-18T18:52:15.459Z" }, { url = "https://files.pythonhosted.org/packages/a0/55/f1a8d838ec07fe3ca53edbe76f782df7b9aafd4417080eebf0b42aab0c52/pyarrow-19.0.1-cp311-cp311-macosx_12_0_arm64.whl", hash = "sha256:cc55d71898ea30dc95900297d191377caba257612f384207fe9f8293b5850f90", size = 30713987, upload-time = "2025-02-18T18:52:20.463Z" }, { url = "https://files.pythonhosted.org/packages/13/12/428861540bb54c98a140ae858a11f71d041ef9e501e6b7eb965ca7909505/pyarrow-19.0.1-cp311-cp311-macosx_12_0_x86_64.whl", hash = "sha256:7a544ec12de66769612b2d6988c36adc96fb9767ecc8ee0a4d270b10b1c51e00", size = 32135613, upload-time = "2025-02-18T18:52:25.29Z" }, { url = "https://files.pythonhosted.org/packages/2f/8a/23d7cc5ae2066c6c736bce1db8ea7bc9ac3ef97ac7e1c1667706c764d2d9/pyarrow-19.0.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0148bb4fc158bfbc3d6dfe5001d93ebeed253793fff4435167f6ce1dc4bddeae", size = 41149147, upload-time = "2025-02-18T18:52:30.975Z" }, @@ -1891,19 +1574,6 @@ ] sdist = { url = "https://files.pythonhosted.org/packages/ad/88/5f2260bdfae97aabf98f1778d43f69574390ad787afb646292a638c923d4/pydantic_core-2.33.2.tar.gz", hash = "sha256:7cb8bc3605c29176e1b105350d2e6474142d7c1bd1d9327c4a9bdb46bf827acc", size = 435195, upload-time = "2025-04-23T18:33:52.104Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/e5/92/b31726561b5dae176c2d2c2dc43a9c5bfba5d32f96f8b4c0a600dd492447/pydantic_core-2.33.2-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:2b3d326aaef0c0399d9afffeb6367d5e26ddc24d351dbc9c636840ac355dc5d8", size = 2028817, upload-time = "2025-04-23T18:30:43.919Z" }, - { url = "https://files.pythonhosted.org/packages/a3/44/3f0b95fafdaca04a483c4e685fe437c6891001bf3ce8b2fded82b9ea3aa1/pydantic_core-2.33.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:0e5b2671f05ba48b94cb90ce55d8bdcaaedb8ba00cc5359f6810fc918713983d", size = 1861357, upload-time = "2025-04-23T18:30:46.372Z" }, - { url = "https://files.pythonhosted.org/packages/30/97/e8f13b55766234caae05372826e8e4b3b96e7b248be3157f53237682e43c/pydantic_core-2.33.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0069c9acc3f3981b9ff4cdfaf088e98d83440a4c7ea1bc07460af3d4dc22e72d", size = 1898011, upload-time = "2025-04-23T18:30:47.591Z" }, - { url = "https://files.pythonhosted.org/packages/9b/a3/99c48cf7bafc991cc3ee66fd544c0aae8dc907b752f1dad2d79b1b5a471f/pydantic_core-2.33.2-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:d53b22f2032c42eaaf025f7c40c2e3b94568ae077a606f006d206a463bc69572", size = 1982730, upload-time = "2025-04-23T18:30:49.328Z" }, - { url = "https://files.pythonhosted.org/packages/de/8e/a5b882ec4307010a840fb8b58bd9bf65d1840c92eae7534c7441709bf54b/pydantic_core-2.33.2-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:0405262705a123b7ce9f0b92f123334d67b70fd1f20a9372b907ce1080c7ba02", size = 2136178, upload-time = "2025-04-23T18:30:50.907Z" }, - { url = "https://files.pythonhosted.org/packages/e4/bb/71e35fc3ed05af6834e890edb75968e2802fe98778971ab5cba20a162315/pydantic_core-2.33.2-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:4b25d91e288e2c4e0662b8038a28c6a07eaac3e196cfc4ff69de4ea3db992a1b", size = 2736462, upload-time = "2025-04-23T18:30:52.083Z" }, - { url = "https://files.pythonhosted.org/packages/31/0d/c8f7593e6bc7066289bbc366f2235701dcbebcd1ff0ef8e64f6f239fb47d/pydantic_core-2.33.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6bdfe4b3789761f3bcb4b1ddf33355a71079858958e3a552f16d5af19768fef2", size = 2005652, upload-time = "2025-04-23T18:30:53.389Z" }, - { url = "https://files.pythonhosted.org/packages/d2/7a/996d8bd75f3eda405e3dd219ff5ff0a283cd8e34add39d8ef9157e722867/pydantic_core-2.33.2-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:efec8db3266b76ef9607c2c4c419bdb06bf335ae433b80816089ea7585816f6a", size = 2113306, upload-time = "2025-04-23T18:30:54.661Z" }, - { url = "https://files.pythonhosted.org/packages/ff/84/daf2a6fb2db40ffda6578a7e8c5a6e9c8affb251a05c233ae37098118788/pydantic_core-2.33.2-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:031c57d67ca86902726e0fae2214ce6770bbe2f710dc33063187a68744a5ecac", size = 2073720, upload-time = "2025-04-23T18:30:56.11Z" }, - { url = "https://files.pythonhosted.org/packages/77/fb/2258da019f4825128445ae79456a5499c032b55849dbd5bed78c95ccf163/pydantic_core-2.33.2-cp310-cp310-musllinux_1_1_armv7l.whl", hash = "sha256:f8de619080e944347f5f20de29a975c2d815d9ddd8be9b9b7268e2e3ef68605a", size = 2244915, upload-time = "2025-04-23T18:30:57.501Z" }, - { url = "https://files.pythonhosted.org/packages/d8/7a/925ff73756031289468326e355b6fa8316960d0d65f8b5d6b3a3e7866de7/pydantic_core-2.33.2-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:73662edf539e72a9440129f231ed3757faab89630d291b784ca99237fb94db2b", size = 2241884, upload-time = "2025-04-23T18:30:58.867Z" }, - { url = "https://files.pythonhosted.org/packages/0b/b0/249ee6d2646f1cdadcb813805fe76265745c4010cf20a8eba7b0e639d9b2/pydantic_core-2.33.2-cp310-cp310-win32.whl", hash = "sha256:0a39979dcbb70998b0e505fb1556a1d550a0781463ce84ebf915ba293ccb7e22", size = 1910496, upload-time = "2025-04-23T18:31:00.078Z" }, - { url = "https://files.pythonhosted.org/packages/66/ff/172ba8f12a42d4b552917aa65d1f2328990d3ccfc01d5b7c943ec084299f/pydantic_core-2.33.2-cp310-cp310-win_amd64.whl", hash = "sha256:b0379a2b24882fef529ec3b4987cb5d003b9cda32256024e6fe1586ac45fc640", size = 1955019, upload-time = "2025-04-23T18:31:01.335Z" }, { url = "https://files.pythonhosted.org/packages/3f/8d/71db63483d518cbbf290261a1fc2839d17ff89fce7089e08cad07ccfce67/pydantic_core-2.33.2-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:4c5b0a576fb381edd6d27f0a85915c6daf2f8138dc5c267a57c08a62900758c7", size = 2028584, upload-time = "2025-04-23T18:31:03.106Z" }, { url = "https://files.pythonhosted.org/packages/24/2f/3cfa7244ae292dd850989f328722d2aef313f74ffc471184dc509e1e4e5a/pydantic_core-2.33.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:e799c050df38a639db758c617ec771fd8fb7a5f8eaaa4b27b101f266b216a246", size = 1855071, upload-time = "2025-04-23T18:31:04.621Z" }, { url = "https://files.pythonhosted.org/packages/b3/d3/4ae42d33f5e3f50dd467761304be2fa0a9417fbf09735bc2cce003480f2a/pydantic_core-2.33.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:dc46a01bf8d62f227d5ecee74178ffc448ff4e5197c756331f71efcc66dc980f", size = 1897823, upload-time = "2025-04-23T18:31:06.377Z" }, @@ -1918,15 +1588,6 @@ { url = "https://files.pythonhosted.org/packages/e0/ed/55532bb88f674d5d8f67ab121a2a13c385df382de2a1677f30ad385f7438/pydantic_core-2.33.2-cp311-cp311-win32.whl", hash = "sha256:6368900c2d3ef09b69cb0b913f9f8263b03786e5b2a387706c5afb66800efd51", size = 1910538, upload-time = "2025-04-23T18:31:20.541Z" }, { url = "https://files.pythonhosted.org/packages/fe/1b/25b7cccd4519c0b23c2dd636ad39d381abf113085ce4f7bec2b0dc755eb1/pydantic_core-2.33.2-cp311-cp311-win_amd64.whl", hash = "sha256:1e063337ef9e9820c77acc768546325ebe04ee38b08703244c1309cccc4f1bab", size = 1952909, upload-time = "2025-04-23T18:31:22.371Z" }, { url = "https://files.pythonhosted.org/packages/49/a9/d809358e49126438055884c4366a1f6227f0f84f635a9014e2deb9b9de54/pydantic_core-2.33.2-cp311-cp311-win_arm64.whl", hash = "sha256:6b99022f1d19bc32a4c2a0d544fc9a76e3be90f0b3f4af413f87d38749300e65", size = 1897786, upload-time = "2025-04-23T18:31:24.161Z" }, - { url = "https://files.pythonhosted.org/packages/30/68/373d55e58b7e83ce371691f6eaa7175e3a24b956c44628eb25d7da007917/pydantic_core-2.33.2-pp310-pypy310_pp73-macosx_10_12_x86_64.whl", hash = "sha256:5c4aa4e82353f65e548c476b37e64189783aa5384903bfea4f41580f255fddfa", size = 2023982, upload-time = "2025-04-23T18:32:53.14Z" }, - { url = "https://files.pythonhosted.org/packages/a4/16/145f54ac08c96a63d8ed6442f9dec17b2773d19920b627b18d4f10a061ea/pydantic_core-2.33.2-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:d946c8bf0d5c24bf4fe333af284c59a19358aa3ec18cb3dc4370080da1e8ad29", size = 1858412, upload-time = "2025-04-23T18:32:55.52Z" }, - { url = "https://files.pythonhosted.org/packages/41/b1/c6dc6c3e2de4516c0bb2c46f6a373b91b5660312342a0cf5826e38ad82fa/pydantic_core-2.33.2-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:87b31b6846e361ef83fedb187bb5b4372d0da3f7e28d85415efa92d6125d6e6d", size = 1892749, upload-time = "2025-04-23T18:32:57.546Z" }, - { url = "https://files.pythonhosted.org/packages/12/73/8cd57e20afba760b21b742106f9dbdfa6697f1570b189c7457a1af4cd8a0/pydantic_core-2.33.2-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:aa9d91b338f2df0508606f7009fde642391425189bba6d8c653afd80fd6bb64e", size = 2067527, upload-time = "2025-04-23T18:32:59.771Z" }, - { url = "https://files.pythonhosted.org/packages/e3/d5/0bb5d988cc019b3cba4a78f2d4b3854427fc47ee8ec8e9eaabf787da239c/pydantic_core-2.33.2-pp310-pypy310_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:2058a32994f1fde4ca0480ab9d1e75a0e8c87c22b53a3ae66554f9af78f2fe8c", size = 2108225, upload-time = "2025-04-23T18:33:04.51Z" }, - { url = "https://files.pythonhosted.org/packages/f1/c5/00c02d1571913d496aabf146106ad8239dc132485ee22efe08085084ff7c/pydantic_core-2.33.2-pp310-pypy310_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:0e03262ab796d986f978f79c943fc5f620381be7287148b8010b4097f79a39ec", size = 2069490, upload-time = "2025-04-23T18:33:06.391Z" }, - { url = "https://files.pythonhosted.org/packages/22/a8/dccc38768274d3ed3a59b5d06f59ccb845778687652daa71df0cab4040d7/pydantic_core-2.33.2-pp310-pypy310_pp73-musllinux_1_1_armv7l.whl", hash = "sha256:1a8695a8d00c73e50bff9dfda4d540b7dee29ff9b8053e38380426a85ef10052", size = 2237525, upload-time = "2025-04-23T18:33:08.44Z" }, - { url = "https://files.pythonhosted.org/packages/d4/e7/4f98c0b125dda7cf7ccd14ba936218397b44f50a56dd8c16a3091df116c3/pydantic_core-2.33.2-pp310-pypy310_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:fa754d1850735a0b0e03bcffd9d4b4343eb417e47196e4485d9cca326073a42c", size = 2238446, upload-time = "2025-04-23T18:33:10.313Z" }, - { url = "https://files.pythonhosted.org/packages/ce/91/2ec36480fdb0b783cd9ef6795753c1dea13882f2e68e73bce76ae8c21e6a/pydantic_core-2.33.2-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:a11c8d26a50bfab49002947d3d237abe4d9e4b5bdc8846a63537b6488e197808", size = 2066678, upload-time = "2025-04-23T18:33:12.224Z" }, { url = "https://files.pythonhosted.org/packages/7b/27/d4ae6487d73948d6f20dddcd94be4ea43e74349b56eba82e9bdee2d7494c/pydantic_core-2.33.2-pp311-pypy311_pp73-macosx_10_12_x86_64.whl", hash = "sha256:dd14041875d09cc0f9308e37a6f8b65f5585cf2598a53aa0123df8b129d481f8", size = 2025200, upload-time = "2025-04-23T18:33:14.199Z" }, { url = "https://files.pythonhosted.org/packages/f1/b8/b3cb95375f05d33801024079b9392a5ab45267a63400bf1866e7ce0f0de4/pydantic_core-2.33.2-pp311-pypy311_pp73-macosx_11_0_arm64.whl", hash = "sha256:d87c561733f66531dced0da6e864f44ebf89a8fba55f31407b00c2f7f9449593", size = 1859123, upload-time = "2025-04-23T18:33:16.555Z" }, { url = "https://files.pythonhosted.org/packages/05/bc/0d0b5adeda59a261cd30a1235a445bf55c7e46ae44aea28f7bd6ed46e091/pydantic_core-2.33.2-pp311-pypy311_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2f82865531efd18d6e07a04a17331af02cb7a651583c418df8266f17a63c6612", size = 1892852, upload-time = "2025-04-23T18:33:18.513Z" }, @@ -1967,11 +1628,6 @@ ] sdist = { url = "https://files.pythonhosted.org/packages/a3/0e/90e61c38504f4fbd5ed79631f85da7d5ea5e5bf997bdeaa65b28ebf04cab/pyiceberg-0.10.0.tar.gz", hash = "sha256:2525afa5e7e5fc4e72b291f8e1cc219e982d2bda5ff17e62cd05b8d91c4139f5", size = 842633, upload-time = "2025-09-11T14:59:34.044Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/d4/82/5dbcf36c13ddf528a6c4ba7f75ace2766859870e7e166096c73c8e63c457/pyiceberg-0.10.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:03a4f208f0c59c040d2a6ff51b952479358810aac28c5271de3fd1fa425f063c", size = 553282, upload-time = "2025-09-11T14:58:58.667Z" }, - { url = "https://files.pythonhosted.org/packages/ba/a0/ca556da105ce64269e46977204777f6d5e1d8595f711f6d0edb3bbc58eff/pyiceberg-0.10.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:6924f496f9a6e36f6530ce66483486f71d3cb4c08512d5aeb21095a9aa22d4b7", size = 550649, upload-time = "2025-09-11T14:59:00.931Z" }, - { url = "https://files.pythonhosted.org/packages/fa/6c/def488007282c3d9ece0ca68fd6c4c7f42c500c0125cba3b8767731bfe5e/pyiceberg-0.10.0-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:e549ca852233b1aa20f2af1a8f9276b4a064c2515be0d73d36f28282502b8728", size = 906149, upload-time = "2025-09-11T14:59:03.47Z" }, - { url = "https://files.pythonhosted.org/packages/4f/a3/08431f7c48ce3f236b1705586c73797eb03b86ca848b12adbbc2b60ed65b/pyiceberg-0.10.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:14a33da7eb579a02fc559d2e7b703a8133e81bc206bf11cb76ece9333ddfb7f3", size = 903762, upload-time = "2025-09-11T14:59:05.416Z" }, - { url = "https://files.pythonhosted.org/packages/fb/bf/5c1c978dad3e4c52c48ab40749f1e49ee0dba26872863a0a3b4385cf81d3/pyiceberg-0.10.0-cp310-cp310-win_amd64.whl", hash = "sha256:4dfafd712fec5c3776fafbb444784e20256b8674cbe243487f8cd7f99a6e8836", size = 549059, upload-time = "2025-09-11T14:59:06.968Z" }, { url = "https://files.pythonhosted.org/packages/a9/62/b6f7bed760d0896958d046ca3c188fd15467c6502bcc2dc301ac0554c1ce/pyiceberg-0.10.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:2c799c9149e06ef9ece22945d5c198ffc69f5c04b314b59a43c2d4c1bb9ade84", size = 591127, upload-time = "2025-09-11T14:59:08.72Z" }, { url = "https://files.pythonhosted.org/packages/4c/b2/294c74e70c68744a8246924fee350095cc46f97f81d1e37125011d8e1bcb/pyiceberg-0.10.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:a8c7070fe1262f50694b12241b5373ee89c8aededda82ef325cb14e5a95cc461", size = 587041, upload-time = "2025-09-11T14:59:10.643Z" }, { url = "https://files.pythonhosted.org/packages/7a/2f/9a9f0a01f0dae2cefc024a2bd84a00ff2a5d8d952f37053c46523c1dd7a6/pyiceberg-0.10.0-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:e0d1a4896f546b1e115ece4212dd02b383eeb3c7ff5c072624b15f531b776f36", size = 1135929, upload-time = "2025-09-11T14:59:12.164Z" }, @@ -2032,20 +1688,6 @@ source = { registry = "https://pypi.org/simple" } sdist = { url = "https://files.pythonhosted.org/packages/2a/b2/5e0ab902f3899ba8a3e2bc3d901a9c66a902d5e5344c46900165ce506636/pyroaring-1.0.2.tar.gz", hash = "sha256:aa4a1de882bf4a245c7c0dee8594b898e76501bc32afc0cc9ff4138784462839", size = 188739, upload-time = "2025-06-30T21:37:04.895Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/e9/87/0c573ffa56daf50df13d579a9f840b1ca8d23c272b6099baf6c85379df50/pyroaring-1.0.2-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:20967e63a7d17758e290f8121239707d086b7720de57d04844e1b0aa977786cb", size = 718892, upload-time = "2025-06-30T21:35:22.325Z" }, - { url = "https://files.pythonhosted.org/packages/a9/b4/462a9ada263f4d03d2d8f58e826d266c6049aa25ef36e32f2b3b0899b644/pyroaring-1.0.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:e6e8de37d22e7aa9a482db7153b9e2a2c966e1951ecf5aaa08cec3264ee773f9", size = 391457, upload-time = "2025-06-30T21:35:24.089Z" }, - { url = "https://files.pythonhosted.org/packages/6f/47/004a51076995d7c44e45d3d78afc4a49a6b6f10dbbac66eae0a27ee35ee0/pyroaring-1.0.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:1387a4dd91374864775fe864c058821535a7ebfa96e208622a21db962d66af15", size = 334118, upload-time = "2025-06-30T21:35:25.483Z" }, - { url = "https://files.pythonhosted.org/packages/4f/92/1a1392a2a3a2301e336862da4479a4a07a9b48073737a837d9eae5cdc095/pyroaring-1.0.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:39ae367d11eb6cdf5b1afd939ebc063f5cabf0120efee794f96289eaa4962789", size = 1862431, upload-time = "2025-06-30T21:35:26.411Z" }, - { url = "https://files.pythonhosted.org/packages/49/ad/970cca5d06898c84a4dbe9412d8a0b69c29d7bf35d1b5b9ab48f7699f427/pyroaring-1.0.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a0f55f288c72b5326a3a64fb7104e92c71501490ab4bc5ec48f54379e3f7e655", size = 2063294, upload-time = "2025-06-30T21:35:27.849Z" }, - { url = "https://files.pythonhosted.org/packages/88/c4/0a83027690d7671b9e7ab03d86cdcebd665e54cd25f0b813847b12b5bde3/pyroaring-1.0.2-cp310-cp310-manylinux_2_24_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:4302399ea8b8fcfa54e5a847d8089001f3b3c2c294b5902598e1db30a749c74e", size = 1772307, upload-time = "2025-06-30T21:35:29.706Z" }, - { url = "https://files.pythonhosted.org/packages/ab/25/c05a0754d036e2f87e11d7c1a8d6d4b5f85a8665c0c450589ec80698c2e4/pyroaring-1.0.2-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:25f4f98d99eb1fdd20300ea45241f6304f90d55820d1b3e70c73a09d4ef1bffc", size = 1799890, upload-time = "2025-06-30T21:35:30.803Z" }, - { url = "https://files.pythonhosted.org/packages/a3/a3/9ac251f3c31800549b12b178c1283616c920f3cc8026a0d1437e69631af9/pyroaring-1.0.2-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:986c5c7bd2831bd5ffa7cb14aa7f20cbf9c762619bcf6a5a4e141d14ba4aa732", size = 2839020, upload-time = "2025-06-30T21:35:32.319Z" }, - { url = "https://files.pythonhosted.org/packages/11/8e/2c18b851abe6bc41344005ce75bef3214f03b7c0f4d6244c50f7484f3327/pyroaring-1.0.2-cp310-cp310-musllinux_1_2_armv7l.whl", hash = "sha256:4c4865df32b4c980fb977140a09077d59a4f2cc86f47524c5d76b64650fec0de", size = 2652350, upload-time = "2025-06-30T21:35:33.382Z" }, - { url = "https://files.pythonhosted.org/packages/25/a8/cd399225148125d5a041c3609977919405702486a7f1d80b1c1db7c88f93/pyroaring-1.0.2-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:d32be36debb293e8e6bfc8e51f257a1e95b9bc820e0a91196d87cfebe0575af6", size = 2982292, upload-time = "2025-06-30T21:35:34.61Z" }, - { url = "https://files.pythonhosted.org/packages/fb/ed/45de038c62a5c202744c191ac9976c59042cef69c8c93ab8a640b765a68e/pyroaring-1.0.2-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:6c55caa802473ce136cbbe2f51506d5046c8b71d8e265b8fb0df011f4534af44", size = 3095006, upload-time = "2025-06-30T21:35:35.924Z" }, - { url = "https://files.pythonhosted.org/packages/f1/40/11a17a377f98ef4eb5c6305604365300b9a3793157e7b225e0f030be7919/pyroaring-1.0.2-cp310-cp310-win32.whl", hash = "sha256:703f377d0c50d7bfce0734b1256140cffaa666d9b0621fe74708b1141e8a85a7", size = 226700, upload-time = "2025-06-30T21:35:37.382Z" }, - { url = "https://files.pythonhosted.org/packages/56/87/17569a86f6826dac0b712ba4a7562961fa8101fcef9126d9140330a6fa17/pyroaring-1.0.2-cp310-cp310-win_amd64.whl", hash = "sha256:e85e3bc78fce1aa6a83cfc3a67cd36bf02c9261e4f426b6040aa0bd97a89820d", size = 277496, upload-time = "2025-06-30T21:35:38.649Z" }, - { url = "https://files.pythonhosted.org/packages/4e/91/0d3bd28061abd06a9eead21c7ada0eadc2429a309fa969621a8eeebaa9de/pyroaring-1.0.2-cp310-cp310-win_arm64.whl", hash = "sha256:108a808a07a7bb773205ab75f7cc22f235f8dffeea85c4bd28b6417fe5480a30", size = 237288, upload-time = "2025-06-30T21:35:39.592Z" }, { url = "https://files.pythonhosted.org/packages/49/79/eb0431d277f761b2e7d5eda04e7fab50a8179c9f4b073f9ee379c47e2f82/pyroaring-1.0.2-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:85a79f88d94d7586921472720c9a9fcedc5db79bff310413be049c2ca3afb349", size = 721757, upload-time = "2025-06-30T21:35:40.887Z" }, { url = "https://files.pythonhosted.org/packages/0d/1a/574b38d8204f9d7a51bf685e2df0fecbc86b90bdddbeb6fe52a8921f42e4/pyroaring-1.0.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:10e82996c70ed344773582be70b34e5b20078626fd2da5063ab396f12f2764ba", size = 393055, upload-time = "2025-06-30T21:35:41.864Z" }, { url = "https://files.pythonhosted.org/packages/8d/e1/d0d3ed23eeb545fd259eae81d8528c7547a1eaeefa595e9dd6d8b932b37a/pyroaring-1.0.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:76af7c7c72a61be1ed08062c8f7aed8020879ada0e77d2bcee6fb40657c32399", size = 335550, upload-time = "2025-06-30T21:35:43.205Z" }, @@ -2068,12 +1710,10 @@ source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "colorama", marker = "sys_platform == 'win32'" }, - { name = "exceptiongroup", marker = "python_full_version < '3.11'" }, { name = "iniconfig" }, { name = "packaging" }, { name = "pluggy" }, { name = "pygments" }, - { name = "tomli", marker = "python_full_version < '3.11'" }, ] sdist = { url = "https://files.pythonhosted.org/packages/a3/5c/00a0e072241553e1a7496d638deababa67c5058571567b92a7eaa258397c/pytest-8.4.2.tar.gz", hash = "sha256:86c0d0b93306b961d58d62a4db4879f27fe25513d4b969df351abdddb3c30e01", size = 1519618, upload-time = "2025-09-04T14:34:22.711Z" } wheels = [ @@ -2173,15 +1813,6 @@ source = { registry = "https://pypi.org/simple" } sdist = { url = "https://files.pythonhosted.org/packages/05/8e/961c0007c59b8dd7729d542c61a4d537767a59645b82a0b521206e1e25c2/pyyaml-6.0.3.tar.gz", hash = "sha256:d76623373421df22fb4cf8817020cbb7ef15c725b9d5e45f17e189bfc384190f", size = 130960, upload-time = "2025-09-25T21:33:16.546Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/f4/a0/39350dd17dd6d6c6507025c0e53aef67a9293a6d37d3511f23ea510d5800/pyyaml-6.0.3-cp310-cp310-macosx_10_13_x86_64.whl", hash = "sha256:214ed4befebe12df36bcc8bc2b64b396ca31be9304b8f59e25c11cf94a4c033b", size = 184227, upload-time = "2025-09-25T21:31:46.04Z" }, - { url = "https://files.pythonhosted.org/packages/05/14/52d505b5c59ce73244f59c7a50ecf47093ce4765f116cdb98286a71eeca2/pyyaml-6.0.3-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:02ea2dfa234451bbb8772601d7b8e426c2bfa197136796224e50e35a78777956", size = 174019, upload-time = "2025-09-25T21:31:47.706Z" }, - { url = "https://files.pythonhosted.org/packages/43/f7/0e6a5ae5599c838c696adb4e6330a59f463265bfa1e116cfd1fbb0abaaae/pyyaml-6.0.3-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:b30236e45cf30d2b8e7b3e85881719e98507abed1011bf463a8fa23e9c3e98a8", size = 740646, upload-time = "2025-09-25T21:31:49.21Z" }, - { url = "https://files.pythonhosted.org/packages/2f/3a/61b9db1d28f00f8fd0ae760459a5c4bf1b941baf714e207b6eb0657d2578/pyyaml-6.0.3-cp310-cp310-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:66291b10affd76d76f54fad28e22e51719ef9ba22b29e1d7d03d6777a9174198", size = 840793, upload-time = "2025-09-25T21:31:50.735Z" }, - { url = "https://files.pythonhosted.org/packages/7a/1e/7acc4f0e74c4b3d9531e24739e0ab832a5edf40e64fbae1a9c01941cabd7/pyyaml-6.0.3-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:9c7708761fccb9397fe64bbc0395abcae8c4bf7b0eac081e12b809bf47700d0b", size = 770293, upload-time = "2025-09-25T21:31:51.828Z" }, - { url = "https://files.pythonhosted.org/packages/8b/ef/abd085f06853af0cd59fa5f913d61a8eab65d7639ff2a658d18a25d6a89d/pyyaml-6.0.3-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:418cf3f2111bc80e0933b2cd8cd04f286338bb88bdc7bc8e6dd775ebde60b5e0", size = 732872, upload-time = "2025-09-25T21:31:53.282Z" }, - { url = "https://files.pythonhosted.org/packages/1f/15/2bc9c8faf6450a8b3c9fc5448ed869c599c0a74ba2669772b1f3a0040180/pyyaml-6.0.3-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:5e0b74767e5f8c593e8c9b5912019159ed0533c70051e9cce3e8b6aa699fcd69", size = 758828, upload-time = "2025-09-25T21:31:54.807Z" }, - { url = "https://files.pythonhosted.org/packages/a3/00/531e92e88c00f4333ce359e50c19b8d1de9fe8d581b1534e35ccfbc5f393/pyyaml-6.0.3-cp310-cp310-win32.whl", hash = "sha256:28c8d926f98f432f88adc23edf2e6d4921ac26fb084b028c733d01868d19007e", size = 142415, upload-time = "2025-09-25T21:31:55.885Z" }, - { url = "https://files.pythonhosted.org/packages/2a/fa/926c003379b19fca39dd4634818b00dec6c62d87faf628d1394e137354d4/pyyaml-6.0.3-cp310-cp310-win_amd64.whl", hash = "sha256:bdb2c67c6c1390b63c6ff89f210c8fd09d9a1217a465701eac7316313c915e4c", size = 158561, upload-time = "2025-09-25T21:31:57.406Z" }, { url = "https://files.pythonhosted.org/packages/6d/16/a95b6757765b7b031c9374925bb718d55e0a9ba8a1b6a12d25962ea44347/pyyaml-6.0.3-cp311-cp311-macosx_10_13_x86_64.whl", hash = "sha256:44edc647873928551a01e7a563d7452ccdebee747728c1080d881d68af7b997e", size = 185826, upload-time = "2025-09-25T21:31:58.655Z" }, { url = "https://files.pythonhosted.org/packages/16/19/13de8e4377ed53079ee996e1ab0a9c33ec2faf808a4647b7b4c0d46dd239/pyyaml-6.0.3-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:652cb6edd41e718550aad172851962662ff2681490a8a711af6a4d288dd96824", size = 175577, upload-time = "2025-09-25T21:32:00.088Z" }, { url = "https://files.pythonhosted.org/packages/0c/62/d2eb46264d4b157dae1275b573017abec435397aa59cbcdab6fc978a8af4/pyyaml-6.0.3-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:10892704fc220243f5305762e276552a0395f7beb4dbf9b14ec8fd43b57f126c", size = 775556, upload-time = "2025-09-25T21:32:01.31Z" }, @@ -2202,16 +1833,6 @@ ] sdist = { url = "https://files.pythonhosted.org/packages/04/0b/3c9baedbdf613ecaa7aa07027780b8867f57b6293b6ee50de316c9f3222b/pyzmq-27.1.0.tar.gz", hash = "sha256:ac0765e3d44455adb6ddbf4417dcce460fc40a05978c08efdf2948072f6db540", size = 281750, upload-time = "2025-09-08T23:10:18.157Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/67/b9/52aa9ec2867528b54f1e60846728d8b4d84726630874fee3a91e66c7df81/pyzmq-27.1.0-cp310-cp310-macosx_10_15_universal2.whl", hash = "sha256:508e23ec9bc44c0005c4946ea013d9317ae00ac67778bd47519fdf5a0e930ff4", size = 1329850, upload-time = "2025-09-08T23:07:26.274Z" }, - { url = "https://files.pythonhosted.org/packages/99/64/5653e7b7425b169f994835a2b2abf9486264401fdef18df91ddae47ce2cc/pyzmq-27.1.0-cp310-cp310-manylinux2014_i686.manylinux_2_17_i686.whl", hash = "sha256:507b6f430bdcf0ee48c0d30e734ea89ce5567fd7b8a0f0044a369c176aa44556", size = 906380, upload-time = "2025-09-08T23:07:29.78Z" }, - { url = "https://files.pythonhosted.org/packages/73/78/7d713284dbe022f6440e391bd1f3c48d9185673878034cfb3939cdf333b2/pyzmq-27.1.0-cp310-cp310-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:bf7b38f9fd7b81cb6d9391b2946382c8237fd814075c6aa9c3b746d53076023b", size = 666421, upload-time = "2025-09-08T23:07:31.263Z" }, - { url = "https://files.pythonhosted.org/packages/30/76/8f099f9d6482450428b17c4d6b241281af7ce6a9de8149ca8c1c649f6792/pyzmq-27.1.0-cp310-cp310-manylinux_2_26_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:03ff0b279b40d687691a6217c12242ee71f0fba28bf8626ff50e3ef0f4410e1e", size = 854149, upload-time = "2025-09-08T23:07:33.17Z" }, - { url = "https://files.pythonhosted.org/packages/59/f0/37fbfff06c68016019043897e4c969ceab18bde46cd2aca89821fcf4fb2e/pyzmq-27.1.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:677e744fee605753eac48198b15a2124016c009a11056f93807000ab11ce6526", size = 1655070, upload-time = "2025-09-08T23:07:35.205Z" }, - { url = "https://files.pythonhosted.org/packages/47/14/7254be73f7a8edc3587609554fcaa7bfd30649bf89cd260e4487ca70fdaa/pyzmq-27.1.0-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:dd2fec2b13137416a1c5648b7009499bcc8fea78154cd888855fa32514f3dad1", size = 2033441, upload-time = "2025-09-08T23:07:37.432Z" }, - { url = "https://files.pythonhosted.org/packages/22/dc/49f2be26c6f86f347e796a4d99b19167fc94503f0af3fd010ad262158822/pyzmq-27.1.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:08e90bb4b57603b84eab1d0ca05b3bbb10f60c1839dc471fc1c9e1507bef3386", size = 1891529, upload-time = "2025-09-08T23:07:39.047Z" }, - { url = "https://files.pythonhosted.org/packages/a3/3e/154fb963ae25be70c0064ce97776c937ecc7d8b0259f22858154a9999769/pyzmq-27.1.0-cp310-cp310-win32.whl", hash = "sha256:a5b42d7a0658b515319148875fcb782bbf118dd41c671b62dae33666c2213bda", size = 567276, upload-time = "2025-09-08T23:07:40.695Z" }, - { url = "https://files.pythonhosted.org/packages/62/b2/f4ab56c8c595abcb26b2be5fd9fa9e6899c1e5ad54964e93ae8bb35482be/pyzmq-27.1.0-cp310-cp310-win_amd64.whl", hash = "sha256:c0bb87227430ee3aefcc0ade2088100e528d5d3298a0a715a64f3d04c60ba02f", size = 632208, upload-time = "2025-09-08T23:07:42.298Z" }, - { url = "https://files.pythonhosted.org/packages/3b/e3/be2cc7ab8332bdac0522fdb64c17b1b6241a795bee02e0196636ec5beb79/pyzmq-27.1.0-cp310-cp310-win_arm64.whl", hash = "sha256:9a916f76c2ab8d045b19f2286851a38e9ac94ea91faf65bd64735924522a8b32", size = 559766, upload-time = "2025-09-08T23:07:43.869Z" }, { url = "https://files.pythonhosted.org/packages/06/5d/305323ba86b284e6fcb0d842d6adaa2999035f70f8c38a9b6d21ad28c3d4/pyzmq-27.1.0-cp311-cp311-macosx_10_15_universal2.whl", hash = "sha256:226b091818d461a3bef763805e75685e478ac17e9008f49fce2d3e52b3d58b86", size = 1333328, upload-time = "2025-09-08T23:07:45.946Z" }, { url = "https://files.pythonhosted.org/packages/bd/a0/fc7e78a23748ad5443ac3275943457e8452da67fda347e05260261108cbc/pyzmq-27.1.0-cp311-cp311-manylinux2014_i686.manylinux_2_17_i686.whl", hash = "sha256:0790a0161c281ca9723f804871b4027f2e8b5a528d357c8952d08cd1a9c15581", size = 908803, upload-time = "2025-09-08T23:07:47.551Z" }, { url = "https://files.pythonhosted.org/packages/7e/22/37d15eb05f3bdfa4abea6f6d96eb3bb58585fbd3e4e0ded4e743bc650c97/pyzmq-27.1.0-cp311-cp311-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:c895a6f35476b0c3a54e3eb6ccf41bf3018de937016e6e18748317f25d4e925f", size = 668836, upload-time = "2025-09-08T23:07:49.436Z" }, @@ -2232,11 +1853,6 @@ { url = "https://files.pythonhosted.org/packages/e6/2f/104c0a3c778d7c2ab8190e9db4f62f0b6957b53c9d87db77c284b69f33ea/pyzmq-27.1.0-cp312-abi3-win32.whl", hash = "sha256:250e5436a4ba13885494412b3da5d518cd0d3a278a1ae640e113c073a5f88edd", size = 559184, upload-time = "2025-09-08T23:08:15.163Z" }, { url = "https://files.pythonhosted.org/packages/fc/7f/a21b20d577e4100c6a41795842028235998a643b1ad406a6d4163ea8f53e/pyzmq-27.1.0-cp312-abi3-win_amd64.whl", hash = "sha256:9ce490cf1d2ca2ad84733aa1d69ce6855372cb5ce9223802450c9b2a7cba0ccf", size = 619480, upload-time = "2025-09-08T23:08:17.192Z" }, { url = "https://files.pythonhosted.org/packages/78/c2/c012beae5f76b72f007a9e91ee9401cb88c51d0f83c6257a03e785c81cc2/pyzmq-27.1.0-cp312-abi3-win_arm64.whl", hash = "sha256:75a2f36223f0d535a0c919e23615fc85a1e23b71f40c7eb43d7b1dedb4d8f15f", size = 552993, upload-time = "2025-09-08T23:08:18.926Z" }, - { url = "https://files.pythonhosted.org/packages/f3/81/a65e71c1552f74dec9dff91d95bafb6e0d33338a8dfefbc88aa562a20c92/pyzmq-27.1.0-pp310-pypy310_pp73-macosx_10_15_x86_64.whl", hash = "sha256:c17e03cbc9312bee223864f1a2b13a99522e0dc9f7c5df0177cd45210ac286e6", size = 836266, upload-time = "2025-09-08T23:09:40.048Z" }, - { url = "https://files.pythonhosted.org/packages/58/ed/0202ca350f4f2b69faa95c6d931e3c05c3a397c184cacb84cb4f8f42f287/pyzmq-27.1.0-pp310-pypy310_pp73-manylinux2014_i686.manylinux_2_17_i686.whl", hash = "sha256:f328d01128373cb6763823b2b4e7f73bdf767834268c565151eacb3b7a392f90", size = 800206, upload-time = "2025-09-08T23:09:41.902Z" }, - { url = "https://files.pythonhosted.org/packages/47/42/1ff831fa87fe8f0a840ddb399054ca0009605d820e2b44ea43114f5459f4/pyzmq-27.1.0-pp310-pypy310_pp73-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:9c1790386614232e1b3a40a958454bdd42c6d1811837b15ddbb052a032a43f62", size = 567747, upload-time = "2025-09-08T23:09:43.741Z" }, - { url = "https://files.pythonhosted.org/packages/d1/db/5c4d6807434751e3f21231bee98109aa57b9b9b55e058e450d0aef59b70f/pyzmq-27.1.0-pp310-pypy310_pp73-manylinux_2_26_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:448f9cb54eb0cee4732b46584f2710c8bc178b0e5371d9e4fc8125201e413a74", size = 747371, upload-time = "2025-09-08T23:09:45.575Z" }, - { url = "https://files.pythonhosted.org/packages/26/af/78ce193dbf03567eb8c0dc30e3df2b9e56f12a670bf7eb20f9fb532c7e8a/pyzmq-27.1.0-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:05b12f2d32112bf8c95ef2e74ec4f1d4beb01f8b5e703b38537f8849f92cb9ba", size = 544862, upload-time = "2025-09-08T23:09:47.448Z" }, { url = "https://files.pythonhosted.org/packages/4c/c6/c4dcdecdbaa70969ee1fdced6d7b8f60cfabe64d25361f27ac4665a70620/pyzmq-27.1.0-pp311-pypy311_pp73-macosx_10_15_x86_64.whl", hash = "sha256:18770c8d3563715387139060d37859c02ce40718d1faf299abddcdcc6a649066", size = 836265, upload-time = "2025-09-08T23:09:49.376Z" }, { url = "https://files.pythonhosted.org/packages/3e/79/f38c92eeaeb03a2ccc2ba9866f0439593bb08c5e3b714ac1d553e5c96e25/pyzmq-27.1.0-pp311-pypy311_pp73-manylinux2014_i686.manylinux_2_17_i686.whl", hash = "sha256:ac25465d42f92e990f8d8b0546b01c391ad431c3bf447683fdc40565941d0604", size = 800208, upload-time = "2025-09-08T23:09:51.073Z" }, { url = "https://files.pythonhosted.org/packages/49/0e/3f0d0d335c6b3abb9b7b723776d0b21fa7f3a6c819a0db6097059aada160/pyzmq-27.1.0-pp311-pypy311_pp73-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:53b40f8ae006f2734ee7608d59ed661419f087521edbfc2149c3932e9c14808c", size = 567747, upload-time = "2025-09-08T23:09:52.698Z" }, @@ -2267,8 +1883,7 @@ version = "6.4.0" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "async-timeout", version = "4.0.3", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.11'" }, - { name = "async-timeout", version = "5.0.1", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.11' and python_full_version < '3.11.3'" }, + { name = "async-timeout", marker = "python_full_version < '3.11.3'" }, ] sdist = { url = "https://files.pythonhosted.org/packages/0d/d6/e8b92798a5bd67d659d51a18170e91c16ac3b59738d91894651ee255ed49/redis-6.4.0.tar.gz", hash = "sha256:b01bc7282b8444e28ec36b261df5375183bb47a07eb9c603f284e89cbc5ef010", size = 4647399, upload-time = "2025-08-07T08:10:11.441Z" } wheels = [ @@ -2281,21 +1896,6 @@ source = { registry = "https://pypi.org/simple" } sdist = { url = "https://files.pythonhosted.org/packages/49/d3/eaa0d28aba6ad1827ad1e716d9a93e1ba963ada61887498297d3da715133/regex-2025.9.18.tar.gz", hash = "sha256:c5ba23274c61c6fef447ba6a39333297d0c247f53059dba0bca415cac511edc4", size = 400917, upload-time = "2025-09-19T00:38:35.79Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/7e/d8/7e06171db8e55f917c5b8e89319cea2d86982e3fc46b677f40358223dece/regex-2025.9.18-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:12296202480c201c98a84aecc4d210592b2f55e200a1d193235c4db92b9f6788", size = 484829, upload-time = "2025-09-19T00:35:05.215Z" }, - { url = "https://files.pythonhosted.org/packages/8d/70/bf91bb39e5bedf75ce730ffbaa82ca585584d13335306d637458946b8b9f/regex-2025.9.18-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:220381f1464a581f2ea988f2220cf2a67927adcef107d47d6897ba5a2f6d51a4", size = 288993, upload-time = "2025-09-19T00:35:08.154Z" }, - { url = "https://files.pythonhosted.org/packages/fe/89/69f79b28365eda2c46e64c39d617d5f65a2aa451a4c94de7d9b34c2dc80f/regex-2025.9.18-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:87f681bfca84ebd265278b5daa1dcb57f4db315da3b5d044add7c30c10442e61", size = 286624, upload-time = "2025-09-19T00:35:09.717Z" }, - { url = "https://files.pythonhosted.org/packages/44/31/81e62955726c3a14fcc1049a80bc716765af6c055706869de5e880ddc783/regex-2025.9.18-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:34d674cbba70c9398074c8a1fcc1a79739d65d1105de2a3c695e2b05ea728251", size = 780473, upload-time = "2025-09-19T00:35:11.013Z" }, - { url = "https://files.pythonhosted.org/packages/fb/23/07072b7e191fbb6e213dc03b2f5b96f06d3c12d7deaded84679482926fc7/regex-2025.9.18-cp310-cp310-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:385c9b769655cb65ea40b6eea6ff763cbb6d69b3ffef0b0db8208e1833d4e746", size = 849290, upload-time = "2025-09-19T00:35:12.348Z" }, - { url = "https://files.pythonhosted.org/packages/b3/f0/aec7f6a01f2a112210424d77c6401b9015675fb887ced7e18926df4ae51e/regex-2025.9.18-cp310-cp310-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:8900b3208e022570ae34328712bef6696de0804c122933414014bae791437ab2", size = 897335, upload-time = "2025-09-19T00:35:14.058Z" }, - { url = "https://files.pythonhosted.org/packages/cc/90/2e5f9da89d260de7d0417ead91a1bc897f19f0af05f4f9323313b76c47f2/regex-2025.9.18-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:c204e93bf32cd7a77151d44b05eb36f469d0898e3fba141c026a26b79d9914a0", size = 789946, upload-time = "2025-09-19T00:35:15.403Z" }, - { url = "https://files.pythonhosted.org/packages/2b/d5/1c712c7362f2563d389be66bae131c8bab121a3fabfa04b0b5bfc9e73c51/regex-2025.9.18-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:3acc471d1dd7e5ff82e6cacb3b286750decd949ecd4ae258696d04f019817ef8", size = 780787, upload-time = "2025-09-19T00:35:17.061Z" }, - { url = "https://files.pythonhosted.org/packages/4f/92/c54cdb4aa41009632e69817a5aa452673507f07e341076735a2f6c46a37c/regex-2025.9.18-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:6479d5555122433728760e5f29edb4c2b79655a8deb681a141beb5c8a025baea", size = 773632, upload-time = "2025-09-19T00:35:18.57Z" }, - { url = "https://files.pythonhosted.org/packages/db/99/75c996dc6a2231a8652d7ad0bfbeaf8a8c77612d335580f520f3ec40e30b/regex-2025.9.18-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:431bd2a8726b000eb6f12429c9b438a24062a535d06783a93d2bcbad3698f8a8", size = 844104, upload-time = "2025-09-19T00:35:20.259Z" }, - { url = "https://files.pythonhosted.org/packages/1c/f7/25aba34cc130cb6844047dbfe9716c9b8f9629fee8b8bec331aa9241b97b/regex-2025.9.18-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:0cc3521060162d02bd36927e20690129200e5ac9d2c6d32b70368870b122db25", size = 834794, upload-time = "2025-09-19T00:35:22.002Z" }, - { url = "https://files.pythonhosted.org/packages/51/eb/64e671beafa0ae29712268421597596d781704973551312b2425831d4037/regex-2025.9.18-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:a021217b01be2d51632ce056d7a837d3fa37c543ede36e39d14063176a26ae29", size = 778535, upload-time = "2025-09-19T00:35:23.298Z" }, - { url = "https://files.pythonhosted.org/packages/26/33/c0ebc0b07bd0bf88f716cca240546b26235a07710ea58e271cfe390ae273/regex-2025.9.18-cp310-cp310-win32.whl", hash = "sha256:4a12a06c268a629cb67cc1d009b7bb0be43e289d00d5111f86a2efd3b1949444", size = 264115, upload-time = "2025-09-19T00:35:25.206Z" }, - { url = "https://files.pythonhosted.org/packages/59/39/aeb11a4ae68faaec2498512cadae09f2d8a91f1f65730fe62b9bffeea150/regex-2025.9.18-cp310-cp310-win_amd64.whl", hash = "sha256:47acd811589301298c49db2c56bde4f9308d6396da92daf99cba781fa74aa450", size = 276143, upload-time = "2025-09-19T00:35:26.785Z" }, - { url = "https://files.pythonhosted.org/packages/29/04/37f2d3fc334a1031fc2767c9d89cec13c2e72207c7e7f6feae8a47f4e149/regex-2025.9.18-cp310-cp310-win_arm64.whl", hash = "sha256:16bd2944e77522275e5ee36f867e19995bcaa533dcb516753a26726ac7285442", size = 268473, upload-time = "2025-09-19T00:35:28.39Z" }, { url = "https://files.pythonhosted.org/packages/58/61/80eda662fc4eb32bfedc331f42390974c9e89c7eac1b79cd9eea4d7c458c/regex-2025.9.18-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:51076980cd08cd13c88eb7365427ae27f0d94e7cebe9ceb2bb9ffdae8fc4d82a", size = 484832, upload-time = "2025-09-19T00:35:30.011Z" }, { url = "https://files.pythonhosted.org/packages/a6/d9/33833d9abddf3f07ad48504ddb53fe3b22f353214bbb878a72eee1e3ddbf/regex-2025.9.18-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:828446870bd7dee4e0cbeed767f07961aa07f0ea3129f38b3ccecebc9742e0b8", size = 288994, upload-time = "2025-09-19T00:35:31.733Z" }, { url = "https://files.pythonhosted.org/packages/2a/b3/526ee96b0d70ea81980cbc20c3496fa582f775a52e001e2743cc33b2fa75/regex-2025.9.18-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:c28821d5637866479ec4cc23b8c990f5bc6dd24e5e4384ba4a11d38a526e1414", size = 286619, upload-time = "2025-09-19T00:35:33.221Z" }, @@ -2346,7 +1946,6 @@ dependencies = [ { name = "markdown-it-py" }, { name = "pygments" }, - { name = "typing-extensions", marker = "python_full_version < '3.11'" }, ] sdist = { url = "https://files.pythonhosted.org/packages/ab/3a/0316b28d0761c6734d6bc14e770d85506c986c85ffb239e688eeaab2c2bc/rich-13.9.4.tar.gz", hash = "sha256:439594978a49a09530cff7ebc4b5c7103ef57baf48d5ea3184f21d9a2befa098", size = 223149, upload-time = "2024-11-01T16:43:57.873Z" } wheels = [ @@ -2400,45 +1999,10 @@ [[package]] name = "scipy" -version = "1.15.3" -source = { registry = "https://pypi.org/simple" } -resolution-markers = [ - "python_full_version < '3.11'", -] -dependencies = [ - { name = "numpy", version = "2.2.6", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.11'" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/0f/37/6964b830433e654ec7485e45a00fc9a27cf868d622838f6b6d9c5ec0d532/scipy-1.15.3.tar.gz", hash = "sha256:eae3cf522bc7df64b42cad3925c876e1b0b6c35c1337c93e12c0f366f55b0eaf", size = 59419214, upload-time = "2025-05-08T16:13:05.955Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/78/2f/4966032c5f8cc7e6a60f1b2e0ad686293b9474b65246b0c642e3ef3badd0/scipy-1.15.3-cp310-cp310-macosx_10_13_x86_64.whl", hash = "sha256:a345928c86d535060c9c2b25e71e87c39ab2f22fc96e9636bd74d1dbf9de448c", size = 38702770, upload-time = "2025-05-08T16:04:20.849Z" }, - { url = "https://files.pythonhosted.org/packages/a0/6e/0c3bf90fae0e910c274db43304ebe25a6b391327f3f10b5dcc638c090795/scipy-1.15.3-cp310-cp310-macosx_12_0_arm64.whl", hash = "sha256:ad3432cb0f9ed87477a8d97f03b763fd1d57709f1bbde3c9369b1dff5503b253", size = 30094511, upload-time = "2025-05-08T16:04:27.103Z" }, - { url = "https://files.pythonhosted.org/packages/ea/b1/4deb37252311c1acff7f101f6453f0440794f51b6eacb1aad4459a134081/scipy-1.15.3-cp310-cp310-macosx_14_0_arm64.whl", hash = "sha256:aef683a9ae6eb00728a542b796f52a5477b78252edede72b8327a886ab63293f", size = 22368151, upload-time = "2025-05-08T16:04:31.731Z" }, - { url = "https://files.pythonhosted.org/packages/38/7d/f457626e3cd3c29b3a49ca115a304cebb8cc6f31b04678f03b216899d3c6/scipy-1.15.3-cp310-cp310-macosx_14_0_x86_64.whl", hash = "sha256:1c832e1bd78dea67d5c16f786681b28dd695a8cb1fb90af2e27580d3d0967e92", size = 25121732, upload-time = "2025-05-08T16:04:36.596Z" }, - { url = "https://files.pythonhosted.org/packages/db/0a/92b1de4a7adc7a15dcf5bddc6e191f6f29ee663b30511ce20467ef9b82e4/scipy-1.15.3-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:263961f658ce2165bbd7b99fa5135195c3a12d9bef045345016b8b50c315cb82", size = 35547617, upload-time = "2025-05-08T16:04:43.546Z" }, - { url = "https://files.pythonhosted.org/packages/8e/6d/41991e503e51fc1134502694c5fa7a1671501a17ffa12716a4a9151af3df/scipy-1.15.3-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9e2abc762b0811e09a0d3258abee2d98e0c703eee49464ce0069590846f31d40", size = 37662964, upload-time = "2025-05-08T16:04:49.431Z" }, - { url = "https://files.pythonhosted.org/packages/25/e1/3df8f83cb15f3500478c889be8fb18700813b95e9e087328230b98d547ff/scipy-1.15.3-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:ed7284b21a7a0c8f1b6e5977ac05396c0d008b89e05498c8b7e8f4a1423bba0e", size = 37238749, upload-time = "2025-05-08T16:04:55.215Z" }, - { url = "https://files.pythonhosted.org/packages/93/3e/b3257cf446f2a3533ed7809757039016b74cd6f38271de91682aa844cfc5/scipy-1.15.3-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:5380741e53df2c566f4d234b100a484b420af85deb39ea35a1cc1be84ff53a5c", size = 40022383, upload-time = "2025-05-08T16:05:01.914Z" }, - { url = "https://files.pythonhosted.org/packages/d1/84/55bc4881973d3f79b479a5a2e2df61c8c9a04fcb986a213ac9c02cfb659b/scipy-1.15.3-cp310-cp310-win_amd64.whl", hash = "sha256:9d61e97b186a57350f6d6fd72640f9e99d5a4a2b8fbf4b9ee9a841eab327dc13", size = 41259201, upload-time = "2025-05-08T16:05:08.166Z" }, - { url = "https://files.pythonhosted.org/packages/96/ab/5cc9f80f28f6a7dff646c5756e559823614a42b1939d86dd0ed550470210/scipy-1.15.3-cp311-cp311-macosx_10_13_x86_64.whl", hash = "sha256:993439ce220d25e3696d1b23b233dd010169b62f6456488567e830654ee37a6b", size = 38714255, upload-time = "2025-05-08T16:05:14.596Z" }, - { url = "https://files.pythonhosted.org/packages/4a/4a/66ba30abe5ad1a3ad15bfb0b59d22174012e8056ff448cb1644deccbfed2/scipy-1.15.3-cp311-cp311-macosx_12_0_arm64.whl", hash = "sha256:34716e281f181a02341ddeaad584205bd2fd3c242063bd3423d61ac259ca7eba", size = 30111035, upload-time = "2025-05-08T16:05:20.152Z" }, - { url = "https://files.pythonhosted.org/packages/4b/fa/a7e5b95afd80d24313307f03624acc65801846fa75599034f8ceb9e2cbf6/scipy-1.15.3-cp311-cp311-macosx_14_0_arm64.whl", hash = "sha256:3b0334816afb8b91dab859281b1b9786934392aa3d527cd847e41bb6f45bee65", size = 22384499, upload-time = "2025-05-08T16:05:24.494Z" }, - { url = "https://files.pythonhosted.org/packages/17/99/f3aaddccf3588bb4aea70ba35328c204cadd89517a1612ecfda5b2dd9d7a/scipy-1.15.3-cp311-cp311-macosx_14_0_x86_64.whl", hash = "sha256:6db907c7368e3092e24919b5e31c76998b0ce1684d51a90943cb0ed1b4ffd6c1", size = 25152602, upload-time = "2025-05-08T16:05:29.313Z" }, - { url = "https://files.pythonhosted.org/packages/56/c5/1032cdb565f146109212153339f9cb8b993701e9fe56b1c97699eee12586/scipy-1.15.3-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:721d6b4ef5dc82ca8968c25b111e307083d7ca9091bc38163fb89243e85e3889", size = 35503415, upload-time = "2025-05-08T16:05:34.699Z" }, - { url = "https://files.pythonhosted.org/packages/bd/37/89f19c8c05505d0601ed5650156e50eb881ae3918786c8fd7262b4ee66d3/scipy-1.15.3-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:39cb9c62e471b1bb3750066ecc3a3f3052b37751c7c3dfd0fd7e48900ed52982", size = 37652622, upload-time = "2025-05-08T16:05:40.762Z" }, - { url = "https://files.pythonhosted.org/packages/7e/31/be59513aa9695519b18e1851bb9e487de66f2d31f835201f1b42f5d4d475/scipy-1.15.3-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:795c46999bae845966368a3c013e0e00947932d68e235702b5c3f6ea799aa8c9", size = 37244796, upload-time = "2025-05-08T16:05:48.119Z" }, - { url = "https://files.pythonhosted.org/packages/10/c0/4f5f3eeccc235632aab79b27a74a9130c6c35df358129f7ac8b29f562ac7/scipy-1.15.3-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:18aaacb735ab38b38db42cb01f6b92a2d0d4b6aabefeb07f02849e47f8fb3594", size = 40047684, upload-time = "2025-05-08T16:05:54.22Z" }, - { url = "https://files.pythonhosted.org/packages/ab/a7/0ddaf514ce8a8714f6ed243a2b391b41dbb65251affe21ee3077ec45ea9a/scipy-1.15.3-cp311-cp311-win_amd64.whl", hash = "sha256:ae48a786a28412d744c62fd7816a4118ef97e5be0bee968ce8f0a2fba7acf3bb", size = 41246504, upload-time = "2025-05-08T16:06:00.437Z" }, -] - -[[package]] -name = "scipy" version = "1.16.2" source = { registry = "https://pypi.org/simple" } -resolution-markers = [ - "python_full_version >= '3.11'", -] dependencies = [ - { name = "numpy", version = "2.3.3", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.11'" }, + { name = "numpy" }, ] sdist = { url = "https://files.pythonhosted.org/packages/4c/3b/546a6f0bfe791bbb7f8d591613454d15097e53f906308ec6f7c1ce588e8e/scipy-1.16.2.tar.gz", hash = "sha256:af029b153d243a80afb6eabe40b0a07f8e35c9adc269c019f364ad747f826a6b", size = 30580599, upload-time = "2025-09-11T17:48:08.271Z" } wheels = [ @@ -2519,60 +2083,26 @@ [[package]] name = "sphinx" -version = "8.1.3" -source = { registry = "https://pypi.org/simple" } -resolution-markers = [ - "python_full_version < '3.11'", -] -dependencies = [ - { name = "alabaster", marker = "python_full_version < '3.11'" }, - { name = "babel", marker = "python_full_version < '3.11'" }, - { name = "colorama", marker = "python_full_version < '3.11' and sys_platform == 'win32'" }, - { name = "docutils", marker = "python_full_version < '3.11'" }, - { name = "imagesize", marker = "python_full_version < '3.11'" }, - { name = "jinja2", marker = "python_full_version < '3.11'" }, - { name = "packaging", marker = "python_full_version < '3.11'" }, - { name = "pygments", marker = "python_full_version < '3.11'" }, - { name = "requests", marker = "python_full_version < '3.11'" }, - { name = "snowballstemmer", marker = "python_full_version < '3.11'" }, - { name = "sphinxcontrib-applehelp", marker = "python_full_version < '3.11'" }, - { name = "sphinxcontrib-devhelp", marker = "python_full_version < '3.11'" }, - { name = "sphinxcontrib-htmlhelp", marker = "python_full_version < '3.11'" }, - { name = "sphinxcontrib-jsmath", marker = "python_full_version < '3.11'" }, - { name = "sphinxcontrib-qthelp", marker = "python_full_version < '3.11'" }, - { name = "sphinxcontrib-serializinghtml", marker = "python_full_version < '3.11'" }, - { name = "tomli", marker = "python_full_version < '3.11'" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/6f/6d/be0b61178fe2cdcb67e2a92fc9ebb488e3c51c4f74a36a7824c0adf23425/sphinx-8.1.3.tar.gz", hash = "sha256:43c1911eecb0d3e161ad78611bc905d1ad0e523e4ddc202a58a821773dc4c927", size = 8184611, upload-time = "2024-10-13T20:27:13.93Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/26/60/1ddff83a56d33aaf6f10ec8ce84b4c007d9368b21008876fceda7e7381ef/sphinx-8.1.3-py3-none-any.whl", hash = "sha256:09719015511837b76bf6e03e42eb7595ac8c2e41eeb9c29c5b755c6b677992a2", size = 3487125, upload-time = "2024-10-13T20:27:10.448Z" }, -] - -[[package]] -name = "sphinx" version = "8.2.3" source = { registry = "https://pypi.org/simple" } -resolution-markers = [ - "python_full_version >= '3.11'", -] dependencies = [ - { name = "alabaster", marker = "python_full_version >= '3.11'" }, - { name = "babel", marker = "python_full_version >= '3.11'" }, - { name = "colorama", marker = "python_full_version >= '3.11' and sys_platform == 'win32'" }, - { name = "docutils", marker = "python_full_version >= '3.11'" }, - { name = "imagesize", marker = "python_full_version >= '3.11'" }, - { name = "jinja2", marker = "python_full_version >= '3.11'" }, - { name = "packaging", marker = "python_full_version >= '3.11'" }, - { name = "pygments", marker = "python_full_version >= '3.11'" }, - { name = "requests", marker = "python_full_version >= '3.11'" }, - { name = "roman-numerals-py", marker = "python_full_version >= '3.11'" }, - { name = "snowballstemmer", marker = "python_full_version >= '3.11'" }, - { name = "sphinxcontrib-applehelp", marker = "python_full_version >= '3.11'" }, - { name = "sphinxcontrib-devhelp", marker = "python_full_version >= '3.11'" }, - { name = "sphinxcontrib-htmlhelp", marker = "python_full_version >= '3.11'" }, - { name = "sphinxcontrib-jsmath", marker = "python_full_version >= '3.11'" }, - { name = "sphinxcontrib-qthelp", marker = "python_full_version >= '3.11'" }, - { name = "sphinxcontrib-serializinghtml", marker = "python_full_version >= '3.11'" }, + { name = "alabaster" }, + { name = "babel" }, + { name = "colorama", marker = "sys_platform == 'win32'" }, + { name = "docutils" }, + { name = "imagesize" }, + { name = "jinja2" }, + { name = "packaging" }, + { name = "pygments" }, + { name = "requests" }, + { name = "roman-numerals-py" }, + { name = "snowballstemmer" }, + { name = "sphinxcontrib-applehelp" }, + { name = "sphinxcontrib-devhelp" }, + { name = "sphinxcontrib-htmlhelp" }, + { name = "sphinxcontrib-jsmath" }, + { name = "sphinxcontrib-qthelp" }, + { name = "sphinxcontrib-serializinghtml" }, ] sdist = { url = "https://files.pythonhosted.org/packages/38/ad/4360e50ed56cb483667b8e6dadf2d3fda62359593faabbe749a27c4eaca6/sphinx-8.2.3.tar.gz", hash = "sha256:398ad29dee7f63a75888314e9424d40f52ce5a6a87ae88e7071e80af296ec348", size = 8321876, upload-time = "2025-03-02T22:31:59.658Z" } wheels = [ @@ -2584,8 +2114,7 @@ version = "0.2.4" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "sphinx", version = "8.1.3", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.11'" }, - { name = "sphinx", version = "8.2.3", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.11'" }, + { name = "sphinx" }, ] sdist = { url = "https://files.pythonhosted.org/packages/9a/10/25231164a97a9016bdc73a3530af8f4a6846bdc564af1460af2ff3e59a50/sphinx-multiversion-0.2.4.tar.gz", hash = "sha256:5cd1ca9ecb5eed63cb8d6ce5e9c438ca13af4fa98e7eb6f376be541dd4990bcb", size = 7024, upload-time = "2020-08-12T15:48:20.566Z" } wheels = [ @@ -2657,14 +2186,6 @@ ] sdist = { url = "https://files.pythonhosted.org/packages/d7/bc/d59b5d97d27229b0e009bd9098cd81af71c2fa5549c580a0a67b9bed0496/sqlalchemy-2.0.43.tar.gz", hash = "sha256:788bfcef6787a7764169cfe9859fe425bf44559619e1d9f56f5bddf2ebf6f417", size = 9762949, upload-time = "2025-08-11T14:24:58.438Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/8f/4e/985f7da36f09592c5ade99321c72c15101d23c0bb7eecfd1daaca5714422/sqlalchemy-2.0.43-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:70322986c0c699dca241418fcf18e637a4369e0ec50540a2b907b184c8bca069", size = 2133162, upload-time = "2025-08-11T15:52:17.854Z" }, - { url = "https://files.pythonhosted.org/packages/37/34/798af8db3cae069461e3bc0898a1610dc469386a97048471d364dc8aae1c/sqlalchemy-2.0.43-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:87accdbba88f33efa7b592dc2e8b2a9c2cdbca73db2f9d5c510790428c09c154", size = 2123082, upload-time = "2025-08-11T15:52:19.181Z" }, - { url = "https://files.pythonhosted.org/packages/fb/0f/79cf4d9dad42f61ec5af1e022c92f66c2d110b93bb1dc9b033892971abfa/sqlalchemy-2.0.43-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c00e7845d2f692ebfc7d5e4ec1a3fd87698e4337d09e58d6749a16aedfdf8612", size = 3208871, upload-time = "2025-08-11T15:50:30.656Z" }, - { url = "https://files.pythonhosted.org/packages/56/b3/59befa58fb0e1a9802c87df02344548e6d007e77e87e6084e2131c29e033/sqlalchemy-2.0.43-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:022e436a1cb39b13756cf93b48ecce7aa95382b9cfacceb80a7d263129dfd019", size = 3209583, upload-time = "2025-08-11T15:57:47.697Z" }, - { url = "https://files.pythonhosted.org/packages/29/d2/124b50c0eb8146e8f0fe16d01026c1a073844f0b454436d8544fe9b33bd7/sqlalchemy-2.0.43-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:c5e73ba0d76eefc82ec0219d2301cb33bfe5205ed7a2602523111e2e56ccbd20", size = 3148177, upload-time = "2025-08-11T15:50:32.078Z" }, - { url = "https://files.pythonhosted.org/packages/83/f5/e369cd46aa84278107624617034a5825fedfc5c958b2836310ced4d2eadf/sqlalchemy-2.0.43-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:9c2e02f06c68092b875d5cbe4824238ab93a7fa35d9c38052c033f7ca45daa18", size = 3172276, upload-time = "2025-08-11T15:57:49.477Z" }, - { url = "https://files.pythonhosted.org/packages/de/2b/4602bf4c3477fa4c837c9774e6dd22e0389fc52310c4c4dfb7e7ba05e90d/sqlalchemy-2.0.43-cp310-cp310-win32.whl", hash = "sha256:e7a903b5b45b0d9fa03ac6a331e1c1d6b7e0ab41c63b6217b3d10357b83c8b00", size = 2101491, upload-time = "2025-08-11T15:54:59.191Z" }, - { url = "https://files.pythonhosted.org/packages/38/2d/bfc6b6143adef553a08295490ddc52607ee435b9c751c714620c1b3dd44d/sqlalchemy-2.0.43-cp310-cp310-win_amd64.whl", hash = "sha256:4bf0edb24c128b7be0c61cd17eef432e4bef507013292415f3fb7023f02b7d4b", size = 2125148, upload-time = "2025-08-11T15:55:00.593Z" }, { url = "https://files.pythonhosted.org/packages/9d/77/fa7189fe44114658002566c6fe443d3ed0ec1fa782feb72af6ef7fbe98e7/sqlalchemy-2.0.43-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:52d9b73b8fb3e9da34c2b31e6d99d60f5f99fd8c1225c9dad24aeb74a91e1d29", size = 2136472, upload-time = "2025-08-11T15:52:21.789Z" }, { url = "https://files.pythonhosted.org/packages/99/ea/92ac27f2fbc2e6c1766bb807084ca455265707e041ba027c09c17d697867/sqlalchemy-2.0.43-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:f42f23e152e4545157fa367b2435a1ace7571cab016ca26038867eb7df2c3631", size = 2126535, upload-time = "2025-08-11T15:52:23.109Z" }, { url = "https://files.pythonhosted.org/packages/94/12/536ede80163e295dc57fff69724caf68f91bb40578b6ac6583a293534849/sqlalchemy-2.0.43-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4fb1a8c5438e0c5ea51afe9c6564f951525795cf432bed0c028c1cb081276685", size = 3297521, upload-time = "2025-08-11T15:50:33.536Z" }, @@ -2755,25 +2276,6 @@ ] [[package]] -name = "tomli" -version = "2.2.1" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/18/87/302344fed471e44a87289cf4967697d07e532f2421fdaf868a303cbae4ff/tomli-2.2.1.tar.gz", hash = "sha256:cd45e1dc79c835ce60f7404ec8119f2eb06d38b1deba146f07ced3bbc44505ff", size = 17175, upload-time = "2024-11-27T22:38:36.873Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/43/ca/75707e6efa2b37c77dadb324ae7d9571cb424e61ea73fad7c56c2d14527f/tomli-2.2.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:678e4fa69e4575eb77d103de3df8a895e1591b48e740211bd1067378c69e8249", size = 131077, upload-time = "2024-11-27T22:37:54.956Z" }, - { url = "https://files.pythonhosted.org/packages/c7/16/51ae563a8615d472fdbffc43a3f3d46588c264ac4f024f63f01283becfbb/tomli-2.2.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:023aa114dd824ade0100497eb2318602af309e5a55595f76b626d6d9f3b7b0a6", size = 123429, upload-time = "2024-11-27T22:37:56.698Z" }, - { url = "https://files.pythonhosted.org/packages/f1/dd/4f6cd1e7b160041db83c694abc78e100473c15d54620083dbd5aae7b990e/tomli-2.2.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ece47d672db52ac607a3d9599a9d48dcb2f2f735c6c2d1f34130085bb12b112a", size = 226067, upload-time = "2024-11-27T22:37:57.63Z" }, - { url = "https://files.pythonhosted.org/packages/a9/6b/c54ede5dc70d648cc6361eaf429304b02f2871a345bbdd51e993d6cdf550/tomli-2.2.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6972ca9c9cc9f0acaa56a8ca1ff51e7af152a9f87fb64623e31d5c83700080ee", size = 236030, upload-time = "2024-11-27T22:37:59.344Z" }, - { url = "https://files.pythonhosted.org/packages/1f/47/999514fa49cfaf7a92c805a86c3c43f4215621855d151b61c602abb38091/tomli-2.2.1-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c954d2250168d28797dd4e3ac5cf812a406cd5a92674ee4c8f123c889786aa8e", size = 240898, upload-time = "2024-11-27T22:38:00.429Z" }, - { url = "https://files.pythonhosted.org/packages/73/41/0a01279a7ae09ee1573b423318e7934674ce06eb33f50936655071d81a24/tomli-2.2.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:8dd28b3e155b80f4d54beb40a441d366adcfe740969820caf156c019fb5c7ec4", size = 229894, upload-time = "2024-11-27T22:38:02.094Z" }, - { url = "https://files.pythonhosted.org/packages/55/18/5d8bc5b0a0362311ce4d18830a5d28943667599a60d20118074ea1b01bb7/tomli-2.2.1-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:e59e304978767a54663af13c07b3d1af22ddee3bb2fb0618ca1593e4f593a106", size = 245319, upload-time = "2024-11-27T22:38:03.206Z" }, - { url = "https://files.pythonhosted.org/packages/92/a3/7ade0576d17f3cdf5ff44d61390d4b3febb8a9fc2b480c75c47ea048c646/tomli-2.2.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:33580bccab0338d00994d7f16f4c4ec25b776af3ffaac1ed74e0b3fc95e885a8", size = 238273, upload-time = "2024-11-27T22:38:04.217Z" }, - { url = "https://files.pythonhosted.org/packages/72/6f/fa64ef058ac1446a1e51110c375339b3ec6be245af9d14c87c4a6412dd32/tomli-2.2.1-cp311-cp311-win32.whl", hash = "sha256:465af0e0875402f1d226519c9904f37254b3045fc5084697cefb9bdde1ff99ff", size = 98310, upload-time = "2024-11-27T22:38:05.908Z" }, - { url = "https://files.pythonhosted.org/packages/6a/1c/4a2dcde4a51b81be3530565e92eda625d94dafb46dbeb15069df4caffc34/tomli-2.2.1-cp311-cp311-win_amd64.whl", hash = "sha256:2d0f2fdd22b02c6d81637a3c95f8cd77f995846af7414c5c4b8d0545afa1bc4b", size = 108309, upload-time = "2024-11-27T22:38:06.812Z" }, - { url = "https://files.pythonhosted.org/packages/6e/c2/61d3e0f47e2b74ef40a68b9e6ad5984f6241a942f7cd3bbfbdbd03861ea9/tomli-2.2.1-py3-none-any.whl", hash = "sha256:cb55c73c5f4408779d0cf3eef9f762b9c9f147a77de7b258bef0a5628adc85cc", size = 14257, upload-time = "2024-11-27T22:38:35.385Z" }, -] - -[[package]] name = "tomlkit" version = "0.13.3" source = { registry = "https://pypi.org/simple" } @@ -2810,8 +2312,7 @@ dependencies = [ { name = "filelock" }, { name = "huggingface-hub" }, - { name = "numpy", version = "2.2.6", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.11'" }, - { name = "numpy", version = "2.3.3", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.11'" }, + { name = "numpy" }, { name = "packaging" }, { name = "pyyaml" }, { name = "regex" }, @@ -2941,16 +2442,6 @@ source = { registry = "https://pypi.org/simple" } sdist = { url = "https://files.pythonhosted.org/packages/95/8f/aeb76c5b46e273670962298c23e7ddde79916cb74db802131d49a85e4b7d/wrapt-1.17.3.tar.gz", hash = "sha256:f66eb08feaa410fe4eebd17f2a2c8e2e46d3476e9f8c783daa8e09e0faa666d0", size = 55547, upload-time = "2025-08-12T05:53:21.714Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/3f/23/bb82321b86411eb51e5a5db3fb8f8032fd30bd7c2d74bfe936136b2fa1d6/wrapt-1.17.3-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:88bbae4d40d5a46142e70d58bf664a89b6b4befaea7b2ecc14e03cedb8e06c04", size = 53482, upload-time = "2025-08-12T05:51:44.467Z" }, - { url = "https://files.pythonhosted.org/packages/45/69/f3c47642b79485a30a59c63f6d739ed779fb4cc8323205d047d741d55220/wrapt-1.17.3-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:e6b13af258d6a9ad602d57d889f83b9d5543acd471eee12eb51f5b01f8eb1bc2", size = 38676, upload-time = "2025-08-12T05:51:32.636Z" }, - { url = "https://files.pythonhosted.org/packages/d1/71/e7e7f5670c1eafd9e990438e69d8fb46fa91a50785332e06b560c869454f/wrapt-1.17.3-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:fd341868a4b6714a5962c1af0bd44f7c404ef78720c7de4892901e540417111c", size = 38957, upload-time = "2025-08-12T05:51:54.655Z" }, - { url = "https://files.pythonhosted.org/packages/de/17/9f8f86755c191d6779d7ddead1a53c7a8aa18bccb7cea8e7e72dfa6a8a09/wrapt-1.17.3-cp310-cp310-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:f9b2601381be482f70e5d1051a5965c25fb3625455a2bf520b5a077b22afb775", size = 81975, upload-time = "2025-08-12T05:52:30.109Z" }, - { url = "https://files.pythonhosted.org/packages/f2/15/dd576273491f9f43dd09fce517f6c2ce6eb4fe21681726068db0d0467096/wrapt-1.17.3-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:343e44b2a8e60e06a7e0d29c1671a0d9951f59174f3709962b5143f60a2a98bd", size = 83149, upload-time = "2025-08-12T05:52:09.316Z" }, - { url = "https://files.pythonhosted.org/packages/0c/c4/5eb4ce0d4814521fee7aa806264bf7a114e748ad05110441cd5b8a5c744b/wrapt-1.17.3-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:33486899acd2d7d3066156b03465b949da3fd41a5da6e394ec49d271baefcf05", size = 82209, upload-time = "2025-08-12T05:52:10.331Z" }, - { url = "https://files.pythonhosted.org/packages/31/4b/819e9e0eb5c8dc86f60dfc42aa4e2c0d6c3db8732bce93cc752e604bb5f5/wrapt-1.17.3-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:e6f40a8aa5a92f150bdb3e1c44b7e98fb7113955b2e5394122fa5532fec4b418", size = 81551, upload-time = "2025-08-12T05:52:31.137Z" }, - { url = "https://files.pythonhosted.org/packages/f8/83/ed6baf89ba3a56694700139698cf703aac9f0f9eb03dab92f57551bd5385/wrapt-1.17.3-cp310-cp310-win32.whl", hash = "sha256:a36692b8491d30a8c75f1dfee65bef119d6f39ea84ee04d9f9311f83c5ad9390", size = 36464, upload-time = "2025-08-12T05:53:01.204Z" }, - { url = "https://files.pythonhosted.org/packages/2f/90/ee61d36862340ad7e9d15a02529df6b948676b9a5829fd5e16640156627d/wrapt-1.17.3-cp310-cp310-win_amd64.whl", hash = "sha256:afd964fd43b10c12213574db492cb8f73b2f0826c8df07a68288f8f19af2ebe6", size = 38748, upload-time = "2025-08-12T05:53:00.209Z" }, - { url = "https://files.pythonhosted.org/packages/bd/c3/cefe0bd330d389c9983ced15d326f45373f4073c9f4a8c2f99b50bfea329/wrapt-1.17.3-cp310-cp310-win_arm64.whl", hash = "sha256:af338aa93554be859173c39c85243970dc6a289fa907402289eeae7543e1ae18", size = 36810, upload-time = "2025-08-12T05:52:51.906Z" }, { url = "https://files.pythonhosted.org/packages/52/db/00e2a219213856074a213503fdac0511203dceefff26e1daa15250cc01a0/wrapt-1.17.3-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:273a736c4645e63ac582c60a56b0acb529ef07f78e08dc6bfadf6a46b19c0da7", size = 53482, upload-time = "2025-08-12T05:51:45.79Z" }, { url = "https://files.pythonhosted.org/packages/5e/30/ca3c4a5eba478408572096fe9ce36e6e915994dd26a4e9e98b4f729c06d9/wrapt-1.17.3-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:5531d911795e3f935a9c23eb1c8c03c211661a5060aab167065896bbf62a5f85", size = 38674, upload-time = "2025-08-12T05:51:34.629Z" }, { url = "https://files.pythonhosted.org/packages/31/25/3e8cc2c46b5329c5957cec959cb76a10718e1a513309c31399a4dad07eb3/wrapt-1.17.3-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:0610b46293c59a3adbae3dee552b648b984176f8562ee0dba099a56cfbe4df1f", size = 38959, upload-time = "2025-08-12T05:51:56.074Z" }, @@ -2976,21 +2467,6 @@ source = { registry = "https://pypi.org/simple" } sdist = { url = "https://files.pythonhosted.org/packages/00/5e/d6e5258d69df8b4ed8c83b6664f2b47d30d2dec551a29ad72a6c69eafd31/xxhash-3.5.0.tar.gz", hash = "sha256:84f2caddf951c9cbf8dc2e22a89d4ccf5d86391ac6418fe81e3c67d0cf60b45f", size = 84241, upload-time = "2024-08-17T09:20:38.972Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/bb/8a/0e9feca390d512d293afd844d31670e25608c4a901e10202aa98785eab09/xxhash-3.5.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:ece616532c499ee9afbb83078b1b952beffef121d989841f7f4b3dc5ac0fd212", size = 31970, upload-time = "2024-08-17T09:17:35.675Z" }, - { url = "https://files.pythonhosted.org/packages/16/e6/be5aa49580cd064a18200ab78e29b88b1127e1a8c7955eb8ecf81f2626eb/xxhash-3.5.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:3171f693dbc2cef6477054a665dc255d996646b4023fe56cb4db80e26f4cc520", size = 30801, upload-time = "2024-08-17T09:17:37.353Z" }, - { url = "https://files.pythonhosted.org/packages/20/ee/b8a99ebbc6d1113b3a3f09e747fa318c3cde5b04bd9c197688fadf0eeae8/xxhash-3.5.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7c5d3e570ef46adaf93fc81b44aca6002b5a4d8ca11bd0580c07eac537f36680", size = 220927, upload-time = "2024-08-17T09:17:38.835Z" }, - { url = "https://files.pythonhosted.org/packages/58/62/15d10582ef159283a5c2b47f6d799fc3303fe3911d5bb0bcc820e1ef7ff4/xxhash-3.5.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:7cb29a034301e2982df8b1fe6328a84f4b676106a13e9135a0d7e0c3e9f806da", size = 200360, upload-time = "2024-08-17T09:17:40.851Z" }, - { url = "https://files.pythonhosted.org/packages/23/41/61202663ea9b1bd8e53673b8ec9e2619989353dba8cfb68e59a9cbd9ffe3/xxhash-3.5.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5d0d307d27099bb0cbeea7260eb39ed4fdb99c5542e21e94bb6fd29e49c57a23", size = 428528, upload-time = "2024-08-17T09:17:42.545Z" }, - { url = "https://files.pythonhosted.org/packages/f2/07/d9a3059f702dec5b3b703737afb6dda32f304f6e9da181a229dafd052c29/xxhash-3.5.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c0342aafd421795d740e514bc9858ebddfc705a75a8c5046ac56d85fe97bf196", size = 194149, upload-time = "2024-08-17T09:17:44.361Z" }, - { url = "https://files.pythonhosted.org/packages/eb/58/27caadf78226ecf1d62dbd0c01d152ed381c14c1ee4ad01f0d460fc40eac/xxhash-3.5.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:3dbbd9892c5ebffeca1ed620cf0ade13eb55a0d8c84e0751a6653adc6ac40d0c", size = 207703, upload-time = "2024-08-17T09:17:46.656Z" }, - { url = "https://files.pythonhosted.org/packages/b1/08/32d558ce23e1e068453c39aed7b3c1cdc690c177873ec0ca3a90d5808765/xxhash-3.5.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:4cc2d67fdb4d057730c75a64c5923abfa17775ae234a71b0200346bfb0a7f482", size = 216255, upload-time = "2024-08-17T09:17:48.031Z" }, - { url = "https://files.pythonhosted.org/packages/3f/d4/2b971e2d2b0a61045f842b622ef11e94096cf1f12cd448b6fd426e80e0e2/xxhash-3.5.0-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:ec28adb204b759306a3d64358a5e5c07d7b1dd0ccbce04aa76cb9377b7b70296", size = 202744, upload-time = "2024-08-17T09:17:50.045Z" }, - { url = "https://files.pythonhosted.org/packages/19/ae/6a6438864a8c4c39915d7b65effd85392ebe22710412902487e51769146d/xxhash-3.5.0-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:1328f6d8cca2b86acb14104e381225a3d7b42c92c4b86ceae814e5c400dbb415", size = 210115, upload-time = "2024-08-17T09:17:51.834Z" }, - { url = "https://files.pythonhosted.org/packages/48/7d/b3c27c27d1fc868094d02fe4498ccce8cec9fcc591825c01d6bcb0b4fc49/xxhash-3.5.0-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:8d47ebd9f5d9607fd039c1fbf4994e3b071ea23eff42f4ecef246ab2b7334198", size = 414247, upload-time = "2024-08-17T09:17:53.094Z" }, - { url = "https://files.pythonhosted.org/packages/a1/05/918f9e7d2fbbd334b829997045d341d6239b563c44e683b9a7ef8fe50f5d/xxhash-3.5.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:b96d559e0fcddd3343c510a0fe2b127fbff16bf346dd76280b82292567523442", size = 191419, upload-time = "2024-08-17T09:17:54.906Z" }, - { url = "https://files.pythonhosted.org/packages/08/29/dfe393805b2f86bfc47c290b275f0b7c189dc2f4e136fd4754f32eb18a8d/xxhash-3.5.0-cp310-cp310-win32.whl", hash = "sha256:61c722ed8d49ac9bc26c7071eeaa1f6ff24053d553146d5df031802deffd03da", size = 30114, upload-time = "2024-08-17T09:17:56.566Z" }, - { url = "https://files.pythonhosted.org/packages/7b/d7/aa0b22c4ebb7c3ccb993d4c565132abc641cd11164f8952d89eb6a501909/xxhash-3.5.0-cp310-cp310-win_amd64.whl", hash = "sha256:9bed5144c6923cc902cd14bb8963f2d5e034def4486ab0bbe1f58f03f042f9a9", size = 30003, upload-time = "2024-08-17T09:17:57.596Z" }, - { url = "https://files.pythonhosted.org/packages/69/12/f969b81541ee91b55f1ce469d7ab55079593c80d04fd01691b550e535000/xxhash-3.5.0-cp310-cp310-win_arm64.whl", hash = "sha256:893074d651cf25c1cc14e3bea4fceefd67f2921b1bb8e40fcfeba56820de80c6", size = 26773, upload-time = "2024-08-17T09:17:59.169Z" }, { url = "https://files.pythonhosted.org/packages/b8/c7/afed0f131fbda960ff15eee7f304fa0eeb2d58770fade99897984852ef23/xxhash-3.5.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:02c2e816896dc6f85922ced60097bcf6f008dedfc5073dcba32f9c8dd786f3c1", size = 31969, upload-time = "2024-08-17T09:18:00.852Z" }, { url = "https://files.pythonhosted.org/packages/8c/0c/7c3bc6d87e5235672fcc2fb42fd5ad79fe1033925f71bf549ee068c7d1ca/xxhash-3.5.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:6027dcd885e21581e46d3c7f682cfb2b870942feeed58a21c29583512c3f09f8", size = 30800, upload-time = "2024-08-17T09:18:01.863Z" }, { url = "https://files.pythonhosted.org/packages/04/9e/01067981d98069eec1c20201f8c145367698e9056f8bc295346e4ea32dd1/xxhash-3.5.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1308fa542bbdbf2fa85e9e66b1077eea3a88bef38ee8a06270b4298a7a62a166", size = 221566, upload-time = "2024-08-17T09:18:03.461Z" }, @@ -3006,11 +2482,6 @@ { url = "https://files.pythonhosted.org/packages/22/6d/db4abec29e7a567455344433d095fdb39c97db6955bb4a2c432e486b4d28/xxhash-3.5.0-cp311-cp311-win32.whl", hash = "sha256:109b436096d0a2dd039c355fa3414160ec4d843dfecc64a14077332a00aeb7da", size = 30120, upload-time = "2024-08-17T09:18:20.009Z" }, { url = "https://files.pythonhosted.org/packages/52/1c/fa3b61c0cf03e1da4767213672efe186b1dfa4fc901a4a694fb184a513d1/xxhash-3.5.0-cp311-cp311-win_amd64.whl", hash = "sha256:b702f806693201ad6c0a05ddbbe4c8f359626d0b3305f766077d51388a6bac58", size = 30003, upload-time = "2024-08-17T09:18:21.052Z" }, { url = "https://files.pythonhosted.org/packages/6b/8e/9e6fc572acf6e1cc7ccb01973c213f895cb8668a9d4c2b58a99350da14b7/xxhash-3.5.0-cp311-cp311-win_arm64.whl", hash = "sha256:c4dcb4120d0cc3cc448624147dba64e9021b278c63e34a38789b688fd0da9bf3", size = 26777, upload-time = "2024-08-17T09:18:22.809Z" }, - { url = "https://files.pythonhosted.org/packages/ab/9a/233606bada5bd6f50b2b72c45de3d9868ad551e83893d2ac86dc7bb8553a/xxhash-3.5.0-pp310-pypy310_pp73-macosx_10_15_x86_64.whl", hash = "sha256:2014c5b3ff15e64feecb6b713af12093f75b7926049e26a580e94dcad3c73d8c", size = 29732, upload-time = "2024-08-17T09:20:11.175Z" }, - { url = "https://files.pythonhosted.org/packages/0c/67/f75276ca39e2c6604e3bee6c84e9db8a56a4973fde9bf35989787cf6e8aa/xxhash-3.5.0-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:fab81ef75003eda96239a23eda4e4543cedc22e34c373edcaf744e721a163986", size = 36214, upload-time = "2024-08-17T09:20:12.335Z" }, - { url = "https://files.pythonhosted.org/packages/0f/f8/f6c61fd794229cc3848d144f73754a0c107854372d7261419dcbbd286299/xxhash-3.5.0-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4e2febf914ace002132aa09169cc572e0d8959d0f305f93d5828c4836f9bc5a6", size = 32020, upload-time = "2024-08-17T09:20:13.537Z" }, - { url = "https://files.pythonhosted.org/packages/79/d3/c029c99801526f859e6b38d34ab87c08993bf3dcea34b11275775001638a/xxhash-3.5.0-pp310-pypy310_pp73-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:5d3a10609c51da2a1c0ea0293fc3968ca0a18bd73838455b5bca3069d7f8e32b", size = 40515, upload-time = "2024-08-17T09:20:14.669Z" }, - { url = "https://files.pythonhosted.org/packages/62/e3/bef7b82c1997579c94de9ac5ea7626d01ae5858aa22bf4fcb38bf220cb3e/xxhash-3.5.0-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:5a74f23335b9689b66eb6dbe2a931a88fcd7a4c2cc4b1cb0edba8ce381c7a1da", size = 30064, upload-time = "2024-08-17T09:20:15.925Z" }, ] [[package]] @@ -3024,21 +2495,6 @@ ] sdist = { url = "https://files.pythonhosted.org/packages/46/fe/2ca2e5ef45952f3e8adb95659821a4e9169d8bbafab97eb662602ee12834/yarl-1.14.0.tar.gz", hash = "sha256:88c7d9d58aab0724b979ab5617330acb1c7030b79379c8138c1c8c94e121d1b3", size = 166127, upload-time = "2024-10-08T10:26:09.406Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/8c/27/dc4f4eabb51cf82f3ba8f8d977fba0e06006d66cee907ea12982c4c85904/yarl-1.14.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:1bfc25aa6a7c99cf86564210f79a0b7d4484159c67e01232b116e445b3036547", size = 135762, upload-time = "2024-10-08T10:23:05.012Z" }, - { url = "https://files.pythonhosted.org/packages/e7/32/e524d6c4b3acd05c88a5454cb3221b74bf7460b593deccf88f3b27361200/yarl-1.14.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:0cf21f46a15d445417de8fc89f2568852cf57fe8ca1ab3d19ddb24d45c0383ae", size = 87946, upload-time = "2024-10-08T10:23:07.804Z" }, - { url = "https://files.pythonhosted.org/packages/7f/ae/42c5fe1ae66eade3f17e442e5adce36b0d098867d5bd98e08527ff026d52/yarl-1.14.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:1dda53508df0de87b6e6b0a52d6718ff6c62a5aca8f5552748404963df639269", size = 85854, upload-time = "2024-10-08T10:23:09.925Z" }, - { url = "https://files.pythonhosted.org/packages/57/21/d653108b654daec3b9359a27f61959cf020839f97248bd345bf1ec7f1490/yarl-1.14.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:587c3cc59bc148a9b1c07a019346eda2549bc9f468acd2f9824d185749acf0a6", size = 306502, upload-time = "2024-10-08T10:23:12.05Z" }, - { url = "https://files.pythonhosted.org/packages/8f/0b/996f04d9de5523735661a90ead48ea21d7557e1a71b1f757d1b2e3baae17/yarl-1.14.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:3007a5b75cb50140708420fe688c393e71139324df599434633019314ceb8b59", size = 320849, upload-time = "2024-10-08T10:23:13.514Z" }, - { url = "https://files.pythonhosted.org/packages/7b/10/b720945c7cd294283f8809dd0407e4cd56218949a4cca3ff04995cae6f0a/yarl-1.14.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:06ff23462398333c78b6f4f8d3d70410d657a471c2c5bbe6086133be43fc8f1a", size = 318727, upload-time = "2024-10-08T10:23:15.834Z" }, - { url = "https://files.pythonhosted.org/packages/d3/3a/0c65820d2d73649d99970e1c150e4be6c057a624cb545613ce75c3ebe2a6/yarl-1.14.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:689a99a42ee4583fcb0d3a67a0204664aa1539684aed72bdafcbd505197a91c4", size = 309599, upload-time = "2024-10-08T10:23:19.096Z" }, - { url = "https://files.pythonhosted.org/packages/43/01/00f44df69b99e23790096aba5e16651694b8de087af12418578dc00730bd/yarl-1.14.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b0547ab1e9345dc468cac8368d88ea4c5bd473ebc1d8d755347d7401982b5dd8", size = 299716, upload-time = "2024-10-08T10:23:21.612Z" }, - { url = "https://files.pythonhosted.org/packages/41/1e/9c9e06f53d91f0b5ac6e69162e92d0fdd0851d4cc360f08716e29201802a/yarl-1.14.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:742aef0a99844faaac200564ea6f5e08facb285d37ea18bd1a5acf2771f3255a", size = 306355, upload-time = "2024-10-08T10:23:23.402Z" }, - { url = "https://files.pythonhosted.org/packages/65/43/db5da311d287691cc02a4f66be8ac5859bce9627d51f8d553fc4f2beb601/yarl-1.14.0-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:176110bff341b6730f64a1eb3a7070e12b373cf1c910a9337e7c3240497db76f", size = 310309, upload-time = "2024-10-08T10:23:25.391Z" }, - { url = "https://files.pythonhosted.org/packages/47/0c/271fdc45a5c2d13f9d138b039a264e35283a4ead36e7a538aefce4050d5e/yarl-1.14.0-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:46a9772a1efa93f9cd170ad33101c1817c77e0e9914d4fe33e2da299d7cf0f9b", size = 325571, upload-time = "2024-10-08T10:23:26.973Z" }, - { url = "https://files.pythonhosted.org/packages/64/7f/bde078ab75deba8387d260f387864b0f549fcdb8d5bee0d9b30406b1b7fe/yarl-1.14.0-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:ee2c68e4f2dd1b1c15b849ba1c96fac105fca6ffdb7c1e8be51da6fabbdeafb9", size = 323477, upload-time = "2024-10-08T10:23:28.566Z" }, - { url = "https://files.pythonhosted.org/packages/bb/f3/9fcf03b8826893275d2b46360986b2afba131e74eb6d722574b34b479144/yarl-1.14.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:047b258e00b99091b6f90355521f026238c63bd76dcf996d93527bb13320eefd", size = 316299, upload-time = "2024-10-08T10:23:30.197Z" }, - { url = "https://files.pythonhosted.org/packages/22/77/b3d0410dfeb0bd779d6013afc1609ba17bff4d15479cab72cc16b11af4fa/yarl-1.14.0-cp310-cp310-win32.whl", hash = "sha256:0aa92e3e30a04f9462a25077db689c4ac5ea9ab6cc68a2e563881b987d42f16d", size = 77408, upload-time = "2024-10-08T10:23:31.978Z" }, - { url = "https://files.pythonhosted.org/packages/92/69/29f5c9399d705254b2095bf117d7fb758f80057ad359b4e3224aa711b966/yarl-1.14.0-cp310-cp310-win_amd64.whl", hash = "sha256:d9baec588f015d0ee564057aa7574313c53a530662ffad930b7886becc85abdf", size = 83511, upload-time = "2024-10-08T10:23:33.424Z" }, { url = "https://files.pythonhosted.org/packages/92/aa/64fcae3d4a081e4ee07902e9e9a3b597c2577283bf6c5b59c06ef0829d90/yarl-1.14.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:07f9eaf57719d6721ab15805d85f4b01a5b509a0868d7320134371bcb652152d", size = 135761, upload-time = "2024-10-08T10:23:34.93Z" }, { url = "https://files.pythonhosted.org/packages/93/a0/5537a1da2c0ec8e11006efa0d133cdaded5ebb94ca71e87e3564b59f6c7f/yarl-1.14.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:c14b504a74e58e2deb0378b3eca10f3d076635c100f45b113c18c770b4a47a50", size = 87888, upload-time = "2024-10-08T10:23:36.391Z" }, { url = "https://files.pythonhosted.org/packages/e3/25/1d12bec8ebdc8287a3464f506ded23b30ad75a5fea3ba49526e8b473057f/yarl-1.14.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:16a682a127930f3fc4e42583becca6049e1d7214bcad23520c590edd741d2114", size = 85883, upload-time = "2024-10-08T10:23:37.802Z" }, diff --git a/owilix/cli.py b/owilix/cli.py --- a/owilix/cli.py +++ b/owilix/cli.py @@ -44,6 +44,22 @@ "owilix remote pull all" """ +# python +import inspect + +def with_class_doc(cls, where="before"): + """Merge a class' docstring into a function's docstring.""" + def deco(fn): + cls_doc = inspect.getdoc(cls) or "" + fn_doc = inspect.getdoc(fn) or "" + if where == "before": + merged = f"{cls_doc}\n\n{fn_doc}".strip() + else: + merged = f"{fn_doc}\n\n{cls_doc}".strip() + fn.__doc__ = merged + return fn + return deco + def display_license_with_agreement(license_data: Dict[str, str], console) -> bool: """ Display the license content in a paginated format and ask for user agreement. @@ -224,24 +240,12 @@ @click.command(context_settings={"ignore_unknown_options": True}) +@with_class_doc(LocalCommands, where="before") @click.argument('subcmd', required=True) @click.argument('specifier', default="all") @click.argument('args', nargs=-1) @click.pass_context def local(ctx, subcmd, specifier, args): - """ - Executes local commands on datasets stored locally. - - Args: - subcmd (str): The subcommand to execute for local operations. - specifier (str): Specifies the dataset or resource to target. - args (list): Additional arguments for the local command. - - Example: - owilix local list - owilix local help - owilix local help - """ args, kwargs = extract_args(args) LocalCommands(ctx.obj['OWI'], **ctx.obj).do(subcmd, specifier, *args, **kwargs) ctx.obj['OWI'].save_repository_stats() @@ -323,30 +327,12 @@ AdminCommands(ctx.obj['OWI'], **ctx.obj).do(subcmd, specifier, *args, **kwargs) @click.command(context_settings={"ignore_unknown_options": True}) +@with_class_doc(RemoteCommands, where="before") @click.argument('subcmd', required=True) @click.argument('specifier', default="all") @click.argument('args', nargs=-1) @click.pass_context def remote(ctx, subcmd, specifier, args): - """ - Executes commands on remote datasets or services. - - Args: - subcmd (str): The subcommand to execute for remote operations. - specifier (str): Specifies the remote dataset or resource to target. - args (list): Additional arguments for the remote command. - - Example: - owilix remote ls - - owilix remote pull all:latest - - owilix remote pull all/collectionName=legal - - owilix remote help - - owilix remote help - """ args, kwargs = extract_args(args) RemoteCommands(ctx.obj['OWI'], **ctx.obj).do(subcmd, specifier, *args, **kwargs) ctx.obj['OWI'].save_repository_stats() diff --git a/owilix/cmd/local.py b/owilix/cmd/local.py --- a/owilix/cmd/local.py +++ b/owilix/cmd/local.py @@ -1,4 +1,5 @@ import os.path +import traceback from rich.prompt import Prompt @@ -20,8 +21,26 @@ class LocalCommands(BaseCommand): """ - commands run over locally stored datasets in available via the `owilix.core.manager.OWIlixManager.local` property. + Commands for managing locally stored datasets available via the `owilix.core.manager.OWIlixManager.local` property. Usually a filesystem directory available under `~/.owi/` + + Available commands: + + - check: Validates consistency of local files and metadata + + - details: Shows detailed statistics for locally available datasets + + - ls: Lists datasets matching a specifier with optional file details + + - remove: Permanently removes datasets from local storage + + - free: Removes datasets from local cache while preserving remote copy + + - insert: Imports new files/directories into the local repository + + - analyze_jsonl: Generates statistical analysis of JSONL file contents + + - export: Exports and merges dataset files into specified output location """ _subcmds = SubCommand() @@ -33,24 +52,6 @@ def register(cls, func): """ Register a new sub-command with the RemoteCommands. """ return cls._subcmds.register(func) - -@LocalCommands.register -def check(self): - """ - checks the consistency of the local files. consistent means every dataset has either a tar.gz file - or a directory as well as a corresponding json file and the json file is valid. - """ - # todo: implement - return CommandResult(success=True, object=self.owi.local.check()) - -@LocalCommands.register -def details(self, specifier, *args, **kwargs): - """ - shows statisitcs for the locally available datasets. - """ - stats = self.dataset_stats(self.list_local_datasets_by_specifier(specifier), True) - self.show_table(stats, order=["key","value","statistics"]) - return CommandResult(success=True, object=stats, msg=f"Showed {len(stats)} stats") @LocalCommands.register @@ -472,3 +473,207 @@ msg="JSONL analysis completed (streaming, Markdown)", object={"markdown": markdown_report, "summary": summary}, ) + +@LocalCommands.register +def export(self, specifier: str, outdir: str, *args, **kwargs): + """ + Collects per-dataset Parquet metadata files and copies them to an output folder, + then merges all CIFF files found across the matching datasets using the CIFF toolkit. + + Usage: + local export [files=] + + Args: + specifier (str): Dataset specifier (same semantics as `ls`). + outdir (str): Output folder inside the local repository filesystem (self.owi.local.fs). + files (optional, kw-arg): If provided, prints files per dataset matching the provided glob. + + Behavior: + - Copies all files matching **/metadata*.parquet from each dataset into //... + (preserving relative folder structure under the dataset root). + - Collects all **/*.ciff and **/*.ciff.gz files across datasets and merges them into: + /index.ciff.gz + using the CIFF toolkit merge command (must be importable). + - Shows progress bars and a summary report. + """ + import os + ciff_merge = None + merge_import_err = "" + try: + from ciff_toolkit.merge import merge_ciff_files + ciff_merge = merge_ciff_files + except Exception: + self.console.print("[bold red]Failed to import CIFF toolkit. You need to merge the ciff files manually[/bold red]") + merge_import_err = f"Exception: {traceback.format_exc()}" + + console = self.console + console.print(f"[bold]Fetching datasets for specifier[/bold] {specifier}") + datasets = self.list_local_datasets_by_specifier(specifier) + if not datasets: + return CommandResult(success=True, object={"datasets": 0}, msg="No datasets matched the specifier.") + + # Show files per dataset if an optional files glob was provided (like in `ls`) + files_glob = kwargs.get("files") + if files_glob: + for d in datasets: + _to_show = d.metadata + _to_show["Files"] = self.owi.local.files(d, files_glob) + self.show_details(_to_show, "title") + + fs = self.owi.local.fs + + # Ensure outdir exists on the local repository filesystem + if not fs.exists(outdir): + fs.makedirs(outdir, exist_ok=True) + + # Collect sources first (for accurate progress totals) + parquet_sources = [] # list of tuples: (dataset, fullpath, relpath_under_dataset) + ciff_sources = [] # list of fullpaths + + for d in datasets: + # metadata parquet files + _meta_parqs = self.owi.local.files(d, "**/metadata*.parquet") + for p in _meta_parqs: + # compute relative path under dataset root and keep it under internalID/ + relp = rel_can_path(p, d.path) + parquet_sources.append((d, p, relp)) + + # ciff files (plain + gz) + _ciff_plain = self.owi.local.files(d, "**/*.ciff") + _ciff_gz = self.owi.local.files(d, "**/*.ciff.gz") + for cf in _ciff_plain + _ciff_gz: + ciff_sources.append(cf) + + total_parq = len(parquet_sources) + total_ciff = len(ciff_sources) + + # Copy parquet files with progress + copied = 0 + skipped = 0 + parq_errors = 0 + + with currentItemProgress() as progress: + parq_task = progress.add_task("Copying metadata parquet files", total=total_parq or 1, current_item="Setup") + + for d, src, relp in parquet_sources: + try: + # destination path: // + dest_path = os.path.join(outdir, (d.metadata.id or "unknown")+"_".join(relp.rsplit(os.path.sep))) + dest_dir = os.path.dirname(dest_path) + if not fs.exists(dest_dir): + fs.makedirs(dest_dir, exist_ok=True) + + # If dest exists with same size/mtime we can skip; otherwise, copy + do_copy = True + if fs.exists(dest_path): + try: + # Best-effort heuristic to avoid redundant copies + s_info = fs.info(src) + d_info = fs.info(dest_path) + if s_info.get("size") == d_info.get("size"): + do_copy = False + skipped += 1 + except Exception: + # If stat fails, fall back to copying + do_copy = True + + if do_copy: + # If same filesystem, leverage cp; otherwise stream copy + if compare_filesystems(fs, fs): + fs.cp(src, dest_path) + else: + with fs.open(src, "rb") as rf, fs.open(dest_path, "wb") as wf: + wf.write(rf.read()) + copied += 1 + + progress.update( + parq_task, + advance=1, + current_item=f"{'copied' if do_copy else 'skipped'} {rel_can_path(src, d.path)}" + ) + except Exception: + parq_errors += 1 + progress.update( + parq_task, + advance=1, + current_item=f"[error]copy failed[/error] {rel_can_path(src, d.path)}" + ) + + # Merge CIFF with progress + merge_output = os.path.join(outdir, "index.ciff.gz") + merged = False + merge_error = None + + with currentItemProgress() as progress: + ciff_task = progress.add_task("Merging CIFF files", total=1, current_item="Setup") + + if total_ciff == 0: + progress.update(ciff_task, advance=1, current_item="No CIFF files found") + merge_error = "No CIFF files found to merge." + elif ciff_merge is None: + progress.update(ciff_task, advance=1, current_item="CIFF merge function not available") + merge_error = f"CIFF merge function could not be imported. Last error: {merge_import_err}" + else: + try: + # Ensure output dir exists + out_dir = os.path.dirname(merge_output) + if out_dir and not fs.exists(out_dir): + fs.makedirs(out_dir, exist_ok=True) + self.console.log(f"Merging {len(ciff_sources)} CIFF files into {merge_output}") + # Call the imported merge command + if len(ciff_sources) > 1: + ciff_merge(inputs=ciff_sources, output=merge_output) # signature may vary per toolkit + else: + fs.copy(ciff_sources[0], merge_output) + merged = True + progress.update(ciff_task, advance=1, current_item=f"Merged into {merge_output}") + except Exception as e: + merge_error = f"CIFF merge failed: {e}" + self.logger.exception(f"[bold red]{merge_error}[/bold red]") + progress.update(ciff_task, advance=1, current_item="Merge failed") + + # Reporting + summary_table = Table(title="Export & Merge Summary") + summary_table.add_column("Metric") + summary_table.add_column("Value") + + summary_table.add_row("Datasets matched", str(len(datasets))) + summary_table.add_row("Parquet metadata (total found)", str(total_parq)) + summary_table.add_row("Parquet metadata copied", str(copied)) + summary_table.add_row("Parquet metadata skipped", str(skipped)) + summary_table.add_row("Parquet copy errors", str(parq_errors)) + summary_table.add_row("CIFF files found", str(total_ciff)) + summary_table.add_row("CIFF merged", "yes" if merged else "no") + summary_table.add_row("CIFF output", merge_output if merged else "-") + if merge_error: + summary_table.add_row("CIFF merge error", merge_error) + + self.console.print(summary_table) + + # Compose CommandResult + result_obj = { + "datasets": len(datasets), + "parquet": { + "found": total_parq, + "copied": copied, + "skipped": skipped, + "errors": parq_errors, + "outdir": outdir, + }, + "ciff": { + "found": total_ciff, + "merged": merged, + "output": merge_output if merged else None, + "error": merge_error, + }, + } + + msg = f"Processed {len(datasets)} datasets; copied {copied}/{total_parq} parquet files; " + if total_ciff == 0: + msg += "no CIFF files found." + elif merged: + msg += f"merged CIFF into {merge_output}." + else: + msg += "CIFF merge not completed." + + return CommandResult(success=True, object=result_obj, msg=msg) diff --git a/owilix/cmd/remote.py b/owilix/cmd/remote.py --- a/owilix/cmd/remote.py +++ b/owilix/cmd/remote.py @@ -11,6 +11,45 @@ class RemoteCommands(BaseCommand): + """ + RemoteCommands provides functionality for interacting with remote OWI repositories and datasets. + + This class implements commands for: + + - Listing remote datasets (ls) + + - Pulling datasets from remote to local (pull) + + - Pushing datasets to remote (push) + + - Comparing local and remote datasets (diff) + + - Managing remote connections (doctor, logout) + + - Advanced data querying (ddbshell) + + - Dataset catalog generation (catalog) + + Example Usage: + + ```python + # List remote datasets matching a specifier + owi remote ls "all:2025-06-9#2/collectionName=main" + + # Pull specific files from remote datasets + owi remote pull "all:2025/*" "files=['**/*.parquet']" + + # Push local datasets to remote + owi remote push "all:local/*" --overwrite True + + # Compare local and remote datasets + owi remote diff "all:2025-*" --files "**/*" + ``` + + The commands use specifiers to identify datasets and support various filters and options + for fine-grained control over data synchronization and management. + """ + _subcmds = SubCommand() def __init__(self, owi, **kwargs): @@ -42,7 +81,7 @@ @RemoteCommands.register -def ls(self, specifier, *args, details=False, files:str =None, **kwargs): +def ls(self, specifier, *args, details=False, files:str=None, groups:int = None, **kwargs): """ Lists all datasets that match the specifier in the remote data centers. @@ -50,7 +89,7 @@ specifier (str): The specifier to filter datasets. files: if "files=" is provided as argument, files per datasets are shown that match the provided glob. details: if "details=True" is provided as kw argument, datasets are shown in full details (i.e. complete metadata) - groups: if "groups" is provided as kw argument, file information is grouped and aggregated accoridng to folder structures. + groups: if "groups=int" is provided as kw argument, file information is grouped and aggregated accoridng to folder structures. the value of groups determines the depth of th folder strucutre to be shown Example Usage: @@ -268,58 +307,91 @@ @RemoteCommands.register def doctor(self, *args, **kwargs): """ - checks the connection status of the remote connections. If there are problems, you can - remove a remote with the flag --remotes + Check connection status of configured remotes. Optionally output as JSON and/or write to a file. Args: - as_json (bool): If True, output will be in JSON format instead of console output - json_file (str): If set, the output will be written to the specified file. If not set, the output will be printed to the console. + as_json (bool): If True, output JSON instead of console text. + json_file (str): If set, write JSON output to this file. """ - if len(args)>0: - for r in args: - if "=" in r: - kwargs[r.split("=")[0]] = r.split("=")[1] - _as_json = kwargs.get("as_json" , False) - _json_file = kwargs.get("json_file" , None) - _results = {} + import json + from datetime import datetime - _repos = self.owi.remote_data.get_repos() - if not _as_json: - self.console.print(f"Found {len(_repos)} configured Remote Repositories") - if len(_repos)>0: + # Allow key=value pairs in *args* to override/augment kwargs + kwargs.update(dict(a.split("=", 1) for a in args if "=" in a)) - for k,r in _repos.items(): - _results[k] = r.status() - if not _as_json: - _col = "green" if _results[k].get("status", False) else "red" - self.console.print(f"[{_col}]{k}: {_results[k].get('message','')} ({_results[k].get('backend', 'unkown backend')}:{_results[k].get('description', 'No description available')})[/{_col}]") - self.console.print("\t"+"\t".join([f + '=' + str(_results[k].get(f, False)) for f in ["user", "project", "public"]])) + def _to_bool(v): + if isinstance(v, bool): + return v + if isinstance(v, str): + return v.strip().lower() in {"1", "true", "yes", "y", "on"} + return bool(v) + + as_json = _to_bool(kwargs.get("as_json", False)) + json_file = kwargs.get("json_file") + results = {} + + repos = self.owi.remote_data.get_repos() + if not as_json: + self.console.print(f"Found {len(repos)} configured Remote Repositories") + + for name, repo in (repos or {}).items(): + try: + status = repo.status() + results[name] = status + if not as_json: + ok = status.get("status", False) + col = "green" if ok else "red" + backend = status.get("backend", "unknown backend") + desc = status.get("description", "No description available") + msg = status.get("message", "") + self.console.print(f"[{col}]{name}: {msg} ({backend}:{desc})[/{col}]") + flags = "\t".join(f"{k}={status.get(k, False)}" for k in ("user", "project", "public")) + self.console.print("\t" + flags) + except Exception as e: + err = f"{e.__class__.__name__}: {e}" + if not as_json: + self.console.exception(f"Error getting remote status for {name}: {err}",exc_info=e) + results[name] = {"error": err} + + # Environment / package info try: - import owilix - import py4lexis - self.console.print("OWI Confguration:") - self.console.print("owilix version: ", owilix.__version__) - self.console.print("py4lexis version: ", py4lexis.__version__) - self.console.print(f"\tOWI Path: {self.owi.owi_path}") - self.console.print(f"\tProject Name: {self.owi.name}") - self.console.print(f"\tLog path: {self.owi.logpath}") - self.console.print(f"\tLog file: {self.owi.logfile}") - - - if self.owi.session is not None: - self.console.print(f"\tLexis Session info (DO NOT SHARE) {self.owi.session._tokens}") - except Exception as e: - self.console.print("Error getting lexis session info") - if _as_json: - from datetime import datetime - _results["timestamp"] = datetime.now().isoformat() - if _json_file is not None: - self.console.print(f"logging json output to file {_json_file}") - with open(_json_file, "w") as f: - json.dump(_results, f) + import owilix, py4lexis # noqa: F401 + if not as_json: + self.console.print("OWI Configuration:") + self.console.print("owilix version: ", owilix.__version__) + self.console.print("py4lexis version: ", py4lexis.__version__) + self.console.print(f"\tOWI Path: {self.owi.owi_path}") + self.console.print(f"\tProject Name: {self.owi.name}") + self.console.print(f"\tLog path: {self.owi.logpath}") + self.console.print(f"\tLog file: {self.owi.logfile}") else: - self.console.print(json.dumps(_results)) + results.update({ + "owilix": {"version": owilix.__version__}, + "py4lexis": {"version": py4lexis.__version__}, + "owi_path": self.owi.owi_path, + "project_name": self.owi.name, + "log_path": self.owi.logpath, + "log_file": self.owi.logfile, + }) + + if self.owi.session is not None and not as_json: + self.console.print(f"\tLexis Session info (DO NOT SHARE) {self.owi.session._tokens}") + except Exception: + if not as_json: + self.console.print("[red]Error getting lexis session info[/red]") + + # JSON output + if as_json: + results["timestamp"] = datetime.now().isoformat() + if json_file: + self.console.print(f"logging json output to file {json_file}") + with open(json_file, "w") as f: + json.dump(results, f) + else: + self.console.print(json.dumps(results)) + return CommandResult(success=True, object=None) + @RemoteCommands.register @@ -506,8 +578,21 @@ @RemoteCommands.register def catalog(self, specifier, *args, **kwargs): - """ - prints dataset details as jsonl + """Generates a detailed catalog of datasets matching the specifier. + + This command creates: + - A CSV file containing aggregated dataset information + - Individual JSON files for each dataset with detailed stats + - Summary statistics including total size + + Args: + specifier (str): The specifier to filter datasets + file (str, optional): Output CSV file path. Defaults to "./catalog.csv" + + Example Usage: + ``` + owi remote catalog "all:2025-*" --file "./my_catalog.csv" + ``` """ import json datasets = self.list_remote_dataset_by_specifier(specifier) diff --git a/owilix/core/ciff.py b/owilix/core/ciff.py --- a/owilix/core/ciff.py +++ b/owilix/core/ciff.py @@ -1,415 +1,301 @@ +from __future__ import annotations + import tempfile -import numpy as np from pathlib import Path from typing import Callable, Optional from concurrent.futures import ThreadPoolExecutor -import queue import threading +import queue +import numpy as np - -def drop_parallel(ciff_file: Path, new_ciff_file: Path, collection_ids: set, - progress_callback: Optional[Callable[[str], None]] = None, - keep=True, threads=4): +def drop_parallel( + ciff_file: Path, + new_ciff_file: Path, + collection_ids: set, + progress_callback: Optional[Callable[[str], None]] = None, + keep: bool = True, + threads: int = 4, +): """ Keep (default) or drop documents with specified collection_docids from a CIFF file. - Memory-efficient streaming version with limited parallelization. - Args: - ciff_file: Path to input CIFF file - new_ciff_file: Path to output CIFF file - collection_ids: Set of collection_docid strings to remove/keep - progress_callback: Optional callback function for progress reporting - keep: If True, keep documents in collection_ids; if False, drop them - threads: Number of worker threads (limited benefit due to I/O constraints) + Read assumptions: + - Source CIFF is streaming: HEADER -> POSTINGS -> DOCUMENTS (no random access). + - DOCUMENTS fit in memory. + + Write (canonical): + - Output order: HEADER -> POSTINGS -> DOCUMENTS + - Header is fully recomputed for the filtered file (num_*, total_*, average_doclength). """ - - def report_progress(message: str): - """Report progress if callback is provided""" + def report(msg: str): if progress_callback: - progress_callback(f"{message} ({new_ciff_file})") + progress_callback(f"{msg} ({new_ciff_file})") - # Import here to avoid circular imports from ciff_toolkit.ciff_pb2 import Posting, DocRecord from ciff_toolkit.read import CiffReader, DEFAULT_CHUNK_SIZE from ciff_toolkit.write import CiffWriter - report_progress("Phase 1: Processing documents...") + report("Phase 1: Build doc mapping (header->postings->documents)") - # Pass 1: Process documents, build docid mapping + # ---- PASS 1: Build mapping from DOCUMENTS (need to exhaust POSTINGS first) ---- with CiffReader(ciff_file) as reader: original_header = reader.read_header() - report_progress(f"Total: {original_header.num_postings_lists} postings, {original_header.num_docs} docs") - # Skip postings lists in first pass - postings_processed = 0 + # Exhaust POSTINGS to reach DOCUMENTS (do not retain) for _ in reader.read_postings_lists(): - postings_processed += 1 - if postings_processed % 20000 == 0: - report_progress(f"Skipping postings: {postings_processed}/{original_header.num_postings_lists}") + pass - # Process documents: create old->new docid mapping and filter - old_to_new_docid = {} - docids_to_drop = set() - kept_docs = [] + num_docs_total = int(original_header.num_docs) + if num_docs_total <= 0: + # Empty input -> empty output with recomputed header + final_header = original_header.__class__() + final_header.CopyFrom(original_header) + final_header.num_docs = 0 + final_header.num_postings_lists = 0 + final_header.total_docs = 0 + final_header.total_postings_lists = 0 + final_header.total_terms_in_collection = 0 + final_header.average_doclength = 0.0 + action = "kept" if keep else "dropped" + addendum = f"Filtered: {action} {len(collection_ids)} collection IDs → 0 docs." + final_header.description = ( + f"{original_header.description}\n\n{addendum}" + if original_header.description else addendum + ) + with CiffWriter(new_ciff_file) as final_writer: + final_writer.write_header(final_header) + report("Complete: 0 docs, 0 postings lists") + return + + # Preallocate mapping helpers + drop_mask = np.zeros(num_docs_total, dtype=bool) + map_array = np.full(num_docs_total, -1, dtype=np.int32) + + kept_docs: list[DocRecord] = [] new_docid = 0 docs_processed = 0 + total_doclength_sum = 0 # for average_doclength + # Read DOCUMENTS and build arrays for doc in reader.read_documents(): docs_processed += 1 - if docs_processed % 50000 == 0: - report_progress(f"Docs: {docs_processed}/{original_header.num_docs}") + if docs_processed % 50_000 == 0: + report(f"Docs: {docs_processed}/{num_docs_total}") - should_drop = (keep and doc.collection_docid not in collection_ids) or (not keep and doc.collection_docid in collection_ids) + should_drop = (keep and doc.collection_docid not in collection_ids) or \ + ((not keep) and doc.collection_docid in collection_ids) if should_drop: - docids_to_drop.add(doc.docid) + if 0 <= doc.docid < num_docs_total: + drop_mask[doc.docid] = True else: - new_doc = DocRecord() - new_doc.docid = new_docid - new_doc.collection_docid = doc.collection_docid - new_doc.doclength = doc.doclength - old_to_new_docid[doc.docid] = new_docid - kept_docs.append(new_doc) + nd = DocRecord() + nd.docid = new_docid + nd.collection_docid = doc.collection_docid + nd.doclength = doc.doclength + kept_docs.append(nd) + + total_doclength_sum += int(doc.doclength) + + if 0 <= doc.docid < num_docs_total: + map_array[doc.docid] = new_docid new_docid += 1 - # Convert drop set for faster numpy operations - docids_to_drop_set = docids_to_drop - report_progress(f"Phase 1 done: keeping {len(kept_docs)}, dropping {len(docids_to_drop)}") + kept_count = len(kept_docs) + dropped_count = int(num_docs_total - kept_count) + avg_doclen = (float(total_doclength_sum) / kept_count) if kept_count > 0 else 0.0 + report(f"Phase 1 done: keeping {kept_count}, dropping {dropped_count}") - # Calculate document statistics - total_length = sum(doc.doclength for doc in kept_docs) if kept_docs else 0 - avg_length = total_length / len(kept_docs) if kept_docs else 0.0 - + # ---- Helper: vectorized postings transform ---- def process_postings_list_vectorized(pl): - """Vectorized processing of a single postings list using numpy""" if not pl.postings: return None - # Extract into numpy arrays for vectorized processing - docids = np.array([p.docid for p in pl.postings], dtype=np.int32) - tfs = np.array([p.tf for p in pl.postings], dtype=np.int32) + n = len(pl.postings) + docid_deltas = np.fromiter((p.docid for p in pl.postings), dtype=np.int32, count=n) + tfs = np.fromiter((p.tf for p in pl.postings), dtype=np.int32, count=n) - # Vectorized delta-gap decoding - full_docids = np.cumsum(docids) + # Decode full old docids using int64 accumulator + full_old = np.cumsum(docid_deltas, dtype=np.int64) - # Vectorized filtering - keep_mask = np.array([docid not in docids_to_drop_set for docid in full_docids], dtype=bool) + # Validate range before indexing into masks/arrays + valid_mask = (full_old >= 0) & (full_old < num_docs_total) + if not np.any(valid_mask): + return None + full_old = full_old[valid_mask] + tfs = tfs[valid_mask] + # Drop docs via boolean lookup + keep_mask = ~drop_mask[full_old] if not np.any(keep_mask): - return None # No survivors - - # Filter arrays - surviving_full_docids = full_docids[keep_mask] + return None + surviving_old = full_old[keep_mask] surviving_tfs = tfs[keep_mask] - dropped_tfs = tfs[~keep_mask] - # Map to new docids - try: - new_docids = np.array([old_to_new_docid[old_docid] for old_docid in surviving_full_docids], dtype=np.int32) - except KeyError: - return None # Skip if mapping missing + # Map old->new docids + new_docids = map_array[surviving_old] + mapped_mask = new_docids >= 0 + if not np.any(mapped_mask): + return None + if not np.all(mapped_mask): + new_docids = new_docids[mapped_mask] + surviving_tfs = surviving_tfs[mapped_mask] - # Sort by new docids - sort_indices = np.argsort(new_docids) - new_docids_sorted = new_docids[sort_indices] - surviving_tfs_sorted = surviving_tfs[sort_indices] + # Sort by new docid (stable) + order = np.argsort(new_docids, kind="stable") + new_docids_sorted = new_docids[order] + tfs_sorted = surviving_tfs[order] - # Vectorized delta-gap re-encoding - delta_gaps = np.diff(np.concatenate(([0], new_docids_sorted))) + # Re-encode delta-gaps (in-place style) + deltas = new_docids_sorted.copy() + if deltas.size: + deltas[1:] -= new_docids_sorted[:-1] - # Create new postings + # Build protobuf postings (minimal Python work) new_postings = [] - for delta, tf in zip(delta_gaps, surviving_tfs_sorted): - posting = Posting() - posting.docid = int(delta) - posting.tf = int(tf) - new_postings.append(posting) + append = new_postings.append + for dgap, tf in zip(deltas.tolist(), tfs_sorted.tolist()): + p = Posting() + p.docid = int(dgap) + p.tf = int(tf) + append(p) - # Update postings list + # Update PL in place del pl.postings[:] pl.postings.extend(new_postings) pl.df = len(new_postings) - pl.cf = max(0, pl.cf - np.sum(dropped_tfs)) - + pl.cf = int(np.sum(tfs_sorted)) return pl - report_progress("Phase 2: Streaming postings with vectorization...") + report("Phase 2: Stream/process postings (parallel) → tmp_postings; docs → tmp_docs") - # Pass 2: Stream postings lists with limited parallelization using queue - with tempfile.TemporaryFile() as tmp_file: - tmp_writer = CiffWriter(tmp_file) - filtered_postings_count = 0 + # ---- PASS 2: Write to two temp files to preserve canonical order later ---- + with tempfile.TemporaryFile() as tmp_postings_file, tempfile.TemporaryFile() as tmp_docs_file: + tmp_post_writer = CiffWriter(tmp_postings_file) + tmp_docs_writer = CiffWriter(tmp_docs_file) - # Use a small queue to limit memory usage - postings_queue = queue.Queue(maxsize=threads * 2) # Small buffer - results_queue = queue.Queue() + # Write DOCUMENTS block to its own temp now (they fit in memory) + tmp_docs_writer.write_documents(kept_docs) - # Producer thread: reads postings lists from file + # Parallel postings pipeline → write to tmp_postings_file + postings_queue: "queue.Queue[tuple[object,int]]" = queue.Queue(maxsize=max(1, threads * 2)) + results_queue: "queue.Queue[tuple[object,int]]" = queue.Queue() + def producer(): - with CiffReader(ciff_file) as reader: - reader.read_header() # Skip header - for idx, pl in enumerate(reader.read_postings_lists()): + from ciff_toolkit.read import CiffReader # local import inside thread + with CiffReader(ciff_file) as r2: + r2.read_header() + for idx, pl in enumerate(r2.read_postings_lists()): postings_queue.put((pl, idx)) - # Signal completion - for _ in range(threads): - postings_queue.put((None, -1)) + for _ in range(threads): + postings_queue.put((None, -1)) - # Worker threads: process postings lists def worker(): while True: - item = postings_queue.get() - if item[0] is None: # Completion signal + item, idx = postings_queue.get() + if item is None: results_queue.put((None, -1)) + postings_queue.task_done() break - - pl, idx = item - processed_pl = process_postings_list_vectorized(pl) - results_queue.put((processed_pl, idx)) + processed = process_postings_list_vectorized(item) + results_queue.put((processed, idx)) postings_queue.task_done() - # Start producer and workers - producer_thread = threading.Thread(target=producer) + producer_thread = threading.Thread(target=producer, daemon=True) producer_thread.start() - with ThreadPoolExecutor(max_workers=threads) as executor: - # Start worker threads - futures = [executor.submit(worker) for _ in range(threads)] + filtered_postings_count = 0 + total_terms_in_collection = 0 # sum of cf over surviving lists - # Collect results in order - processed_count = 0 - completed_workers = 0 - pending_results = {} # Store out-of-order results - next_expected_idx = 0 + pending: dict[int, object] = {} + dropped_indices: set[int] = set() + next_expected_idx = 0 + completed_workers = 0 + processed_count = 0 + + def write_pl(pl_obj): + nonlocal filtered_postings_count, total_terms_in_collection + tmp_post_writer.write_message(pl_obj) + filtered_postings_count += 1 + total_terms_in_collection += int(pl_obj.cf) + + with ThreadPoolExecutor(max_workers=threads) as pool: + for _ in range(threads): + pool.submit(worker) while completed_workers < threads: result, idx = results_queue.get() - - if idx == -1: # Worker completion signal + if idx == -1: completed_workers += 1 continue processed_count += 1 - if processed_count % 5000 == 0: - report_progress(f"Processed: {processed_count}/{original_header.num_postings_lists}") + if processed_count % 5_000 == 0: + report(f"Postings processed: {processed_count}") - if result is not None: - # Handle ordering: write results in sequence - pending_results[idx] = result - - # Write any consecutive results we can - while next_expected_idx in pending_results: - tmp_writer.write_message(pending_results.pop(next_expected_idx)) - filtered_postings_count += 1 + if result is None: + if idx == next_expected_idx: next_expected_idx += 1 - - producer_thread.join() - report_progress(f"Phase 2 done: {filtered_postings_count} postings lists") - - report_progress("Writing documents...") - tmp_writer.write_documents(kept_docs) - - report_progress("Phase 3: Creating output...") - - # Create final header - final_header = original_header.__class__() - final_header.CopyFrom(original_header) - - # Update statistics - final_header.num_postings_lists = filtered_postings_count - final_header.num_docs = len(kept_docs) - final_header.total_postings_lists = filtered_postings_count - final_header.total_docs = len(kept_docs) - final_header.total_terms_in_collection = total_length - final_header.average_doclength = avg_length - - # Update description - action = "kept" if keep else "dropped" - final_header.description = f"Filtered: {action} {len(collection_ids)} collection IDs → {len(kept_docs)} docs" - - # Write final output - with CiffWriter(new_ciff_file) as final_writer: - final_writer.write_header(final_header) - - report_progress("Copying to output...") - tmp_file.seek(0) - while chunk := tmp_file.read(DEFAULT_CHUNK_SIZE): - final_writer.write(chunk) - - report_progress(f"Complete: {len(kept_docs)} docs, {filtered_postings_count} postings") - -def drop(ciff_file: Path, new_ciff_file: Path, collection_ids: set, - progress_callback: Optional[Callable[[str], None]] = None, keep=True): - """ - Keep (default) or dsrop documents with specified collection_docids from a CIFF file. - Memory-efficient streaming approach with proper docid remapping. - - Args: - ciff_file: Path to input CIFF file - new_ciff_file: Path to output CIFF file - collection_ids: Set of collection_docid strings to remove - progress_callback: Optional callback function for progress reporting - """ - - def report_progress(message: str): - """Report progress if callback is provided""" - if progress_callback: - progress_callback(message) - - # Import here to avoid circular imports - from ciff_toolkit.ciff_pb2 import Posting, DocRecord - from ciff_toolkit.read import CiffReader, DEFAULT_CHUNK_SIZE - from ciff_toolkit.write import CiffWriter - - report_progress("Phase 1: Processing documents and building docid mapping...") - - # Pass 1: Process documents, build docid mapping - with CiffReader(ciff_file) as reader: - original_header = reader.read_header() - - report_progress(f"Total postings lists: {original_header.num_postings_lists}, Total docs: {original_header.num_docs}") - - # Skip postings lists in first pass - #postings_processed = 0 - #for _ in reader.read_postings_lists(): - # postings_processed += 1 - # if postings_processed % 10000 == 0: - # report_progress(f"Skipping postings lists: {postings_processed}/{original_header.num_postings_lists} ({new_ciff_file})") - - # Process documents: create old->new docid mapping and filter - old_to_new_docid = {} # Maps old docid -> new docid - docids_to_drop = set() # Set of old docids to drop - kept_docs = [] - new_docid = 0 - docs_processed = 0 - - for doc in reader.read_documents(): - docs_processed += 1 - if docs_processed % 10000 == 0: - report_progress(f"Processing documents: {docs_processed}/{original_header.num_docs} ({new_ciff_file})") - - if (keep and doc.collection_docid not in collection_ids) or (not keep and doc.collection_docid in collection_ids): - docids_to_drop.add(doc.docid) - else: - # Create new DocRecord to avoid protobuf object issues - new_doc = DocRecord() - new_doc.docid = new_docid # Assign new sequential docid - new_doc.collection_docid = doc.collection_docid # Preserve original collection ID - new_doc.doclength = doc.doclength # Preserve document length - - # Create mapping and store new document - old_to_new_docid[doc.docid] = new_docid - kept_docs.append(new_doc) - new_docid += 1 - - report_progress(f"Phase 1 complete: Keeping {len(kept_docs)} docs, dropping {len(docids_to_drop)} docs ({new_ciff_file})") - - # Calculate document statistics - total_length = sum(doc.doclength for doc in kept_docs) if kept_docs else 0 - avg_length = total_length / len(kept_docs) if kept_docs else 0.0 - - report_progress(f"Phase 2: Processing postings lists... ({new_ciff_file})") - - # Pass 2: Stream postings lists with optimized filtering - with tempfile.TemporaryFile() as tmp_file: - tmp_writer = CiffWriter(tmp_file) - filtered_postings_count = 0 - - with CiffReader(ciff_file) as reader: - reader.read_header() # Skip header - - # Process each postings list with optimized delta-gap handling - postings_processed = 0 - for pl in reader.read_postings_lists(): - postings_processed += 1 - if postings_processed % 5000 == 0: - report_progress(f"Processing postings lists: {postings_processed}/{original_header.num_postings_lists} ({new_ciff_file})") - - # Quick check: decode first few postings to see if any survivors - if not pl.postings: + while next_expected_idx in pending: + write_pl(pending.pop(next_expected_idx)) + next_expected_idx += 1 + while next_expected_idx in dropped_indices: + dropped_indices.remove(next_expected_idx) + next_expected_idx += 1 + else: + dropped_indices.add(idx) continue - # Optimized filtering: decode delta-gaps in batch - current_docid = 0 - survivors = [] # List of (new_full_docid, tf) tuples - cf_reduction = 0 + pending[idx] = result + while True: + if next_expected_idx in dropped_indices: + dropped_indices.remove(next_expected_idx) + next_expected_idx += 1 + continue + if next_expected_idx in pending: + write_pl(pending.pop(next_expected_idx)) + next_expected_idx += 1 + continue + break - for posting in pl.postings: - current_docid += posting.docid # Decode delta-gap + producer_thread.join() + while next_expected_idx in pending: + write_pl(pending.pop(next_expected_idx)) + next_expected_idx += 1 - if current_docid not in docids_to_drop: - # Document survives - map to new docid - if current_docid in old_to_new_docid: # Safety check - new_docid = old_to_new_docid[current_docid] - survivors.append((new_docid, posting.tf)) - else: - # Document dropped - track cf reduction - cf_reduction += posting.tf + report(f"Phase 2 done: wrote {filtered_postings_count} postings lists") - # Only process if we have survivors - if survivors: - # Sort by new docid (should already be sorted, but ensure it) - survivors.sort(key=lambda x: x[0]) - - # Create new postings with delta-gap encoding - new_postings = [] - prev_docid = 0 - - for new_docid, tf in survivors: - posting = Posting() - posting.docid = new_docid - prev_docid # Delta-gap encode - posting.tf = tf - new_postings.append(posting) - prev_docid = new_docid - - # Update postings list efficiently - del pl.postings[:] - pl.postings.extend(new_postings) - pl.df = len(new_postings) - pl.cf = max(0, pl.cf - cf_reduction) - - # Write to temporary file immediately - tmp_writer.write_message(pl) - filtered_postings_count += 1 - - report_progress(f"Phase 2 complete: Processed {filtered_postings_count} postings lists ({new_ciff_file})") - report_progress("Writing documents to temporary file...") - - # Write filtered documents to temporary file - tmp_writer.write_documents(kept_docs) - - report_progress(f"Phase 3: Creating final output file...({new_ciff_file})") - - # Create final header + # ---- Phase 3: Header & finalize in canonical order ---- final_header = original_header.__class__() final_header.CopyFrom(original_header) - # Update all statistics + # Fully recomputed for the filtered file + final_header.num_docs = kept_count final_header.num_postings_lists = filtered_postings_count - final_header.num_docs = len(kept_docs) + final_header.total_docs = kept_count final_header.total_postings_lists = filtered_postings_count - final_header.total_docs = len(kept_docs) - final_header.total_terms_in_collection = total_length - final_header.average_doclength = avg_length + final_header.total_terms_in_collection = int(total_terms_in_collection) + final_header.average_doclength = float(avg_doclen) - # Update description - dropped_count = len(collection_ids) + action = "kept" if keep else "dropped" + addendum = f"Filtered: {action} {len(collection_ids)} collection IDs → {kept_count} docs." if final_header.description: - final_header.description += f"\n\nFiltered: removed {dropped_count} collection IDs, kept {len(kept_docs)} documents." + final_header.description = f"{final_header.description}\n\n{addendum}" else: - final_header.description = f"Filtered: removed {dropped_count} collection IDs, kept {len(kept_docs)} documents." + final_header.description = addendum - # Write final output + # Write final file in canonical order: HEADER -> POSTINGS -> DOCUMENTS with CiffWriter(new_ciff_file) as final_writer: final_writer.write_header(final_header) - # Copy temporary file content - report_progress("Copying filtered data to final output...") - tmp_file.seek(0) - bytes_copied = 0 - while chunk := tmp_file.read(DEFAULT_CHUNK_SIZE): + # Copy POSTINGS block first + tmp_postings_file.seek(0) + while chunk := tmp_postings_file.read(DEFAULT_CHUNK_SIZE): final_writer.write(chunk) - bytes_copied += len(chunk) - if bytes_copied % (10 * DEFAULT_CHUNK_SIZE) == 0: - report_progress(f"Copied {bytes_copied // 1024 // 1024} MB to output...") - report_progress(f"Complete: Created {new_ciff_file} with {len(kept_docs)} documents and {filtered_postings_count} postings lists") \ No newline at end of file + # Then copy DOCUMENTS block + tmp_docs_file.seek(0) + while chunk := tmp_docs_file.read(DEFAULT_CHUNK_SIZE): + final_writer.write(chunk) + + report(f"Complete: {kept_count} docs, {filtered_postings_count} postings lists") diff --git a/owilix/core/ui.py b/owilix/core/ui.py --- a/owilix/core/ui.py +++ b/owilix/core/ui.py @@ -18,6 +18,279 @@ from owilix.core.utils import OwilixJSONEncoder from owilix.core.logging import * +import json +import logging +import sys +import contextlib +from dataclasses import is_dataclass, asdict +from typing import Any, Dict, Optional, Union + +from rich.console import Console +from rich.panel import Panel +from rich.text import Text +from rich.traceback import Traceback + +# Optional – if available in your project +try: + from owilix.core.utils import OwilixJSONEncoder # noqa + _JSON_ENCODER = OwilixJSONEncoder +except Exception: + _JSON_ENCODER = None # fallback to default json + +_LEVEL_STYLES = { + logging.DEBUG: "dim", + logging.INFO: "cyan", + logging.WARNING: "yellow", + logging.ERROR: "bold red", + logging.CRITICAL: "bold white on red", +} + +_LEVEL_LABELS = { + logging.DEBUG: "DEBUG", + logging.INFO: "INFO", + logging.WARNING: "WARN", + logging.ERROR: "ERROR", + logging.CRITICAL: "CRITICAL", +} + +class OWILIXConsole(Console): + """ + A Rich Console that mirrors logs to a standard logging.Logger. + + - Prints styled messages to the console. + - Forwards the same message to the provided logger with optional extra/context. + - Renders Rich tracebacks on exceptions and calls logger.exception. + """ + + def __init__( + self, + logger: logging.Logger = None, + *, + default_level: int = logging.INFO, + sticky_extra: Optional[Dict[str, Any]] = None, + show_time: bool = True, + log_panel: bool = False, + **console_kwargs: Any, + ) -> None: + """ + Args: + logger: The Python logger to forward messages to. + default_level: Used by .log() when no level is given. + sticky_extra: Dict merged into all logger calls (use .bind to create children). + show_time: If True, include timestamps in console output. + log_panel: If True, wrap log lines in a subtle Panel. + **console_kwargs: Passed to Rich Console (e.g., width, record, soft_wrap). + """ + super().__init__(**console_kwargs) + self._logger = logger if logger is not None else logging.getLogger("owilix") + self._default_level = default_level + self._sticky_extra = dict(sticky_extra or {}) + self._show_time = show_time + self._log_panel = log_panel + + # ---------- public API ---------- + + def bind(self, **extra: Any) -> "OWILIXConsole": + """Return a child console with merged sticky logger 'extra'.""" + merged = {**self._sticky_extra, **extra} + return OWILIXConsole( + logger=self._logger, + default_level=self._default_level, + sticky_extra=merged, + show_time=self._show_time, + log_panel=self._log_panel, + color_system=self.color_system, + force_terminal=self.force_terminal, + width=self.width, + soft_wrap=self.soft_wrap, + record=self.record, + ) + + def log( + self, + message: Union[str, Text], + *args: Any, + level: Optional[int] = None, + extra: Optional[Dict[str, Any]] = None, + json_payload: Optional[Any] = None, + panel_title: Optional[str] = None, + logger_kwargs: Optional[Dict[str, Any]] = None, + ) -> None: + """ + General-purpose logger. Prints to console and forwards to logger. + + Args: + message: Text or str to print. + *args: If provided, message will be formatted with args for logger. + level: logging level (default: self._default_level). + extra: additional logger extra. + json_payload: any object (dict/dataclass/etc) that will be rendered pretty on console + and attached to logger via extra["payload"] (JSON-encoded). + panel_title: optional panel title for console style. + logger_kwargs: passed through to logger (e.g. stacklevel=2) + """ + lvl = level if level is not None else self._default_level + style = _LEVEL_STYLES.get(lvl, "white") + label = _LEVEL_LABELS.get(lvl, "LOG") + + text = self._compose_console_text(label, message, style=style) + renderable = self._maybe_with_payload(text, json_payload) + + if self._log_panel: + renderable = Panel(renderable, title=panel_title or label, border_style=style) + + self.print(renderable) + + # Forward to logger + log_extra = self._make_logger_extra(extra, json_payload) + kw = dict(logger_kwargs or {}) + if args: + self._logger.log(lvl, str(message), *args, extra=log_extra, **kw) + else: + self._logger.log(lvl, str(message), extra=log_extra, **kw) + + def debug(self, msg: Union[str, Text], **kw: Any) -> None: + self.log(msg, level=logging.DEBUG, **kw) + + def info(self, msg: Union[str, Text], **kw: Any) -> None: + self.log(msg, level=logging.INFO, **kw) + + def warning(self, msg: Union[str, Text], **kw: Any) -> None: + self.log(msg, level=logging.WARNING, **kw) + + def error(self, msg: Union[str, Text], **kw: Any) -> None: + self.log(msg, level=logging.ERROR, **kw) + + def critical(self, msg: Union[str, Text], **kw: Any) -> None: + self.log(msg, level=logging.CRITICAL, **kw) + + def success(self, msg: Union[str, Text], **kw: Any) -> None: + """Non-standard convenience level: styled green, logs as INFO.""" + kw.setdefault("panel_title", "SUCCESS") + self.log(msg, level=logging.INFO, **kw) + + def exception( + self, + msg: Union[str, Text] = "An exception occurred", + *, + exc: Optional[BaseException] = None, + extra: Optional[Dict[str, Any]] = None, + json_payload: Optional[Any] = None, + show_locals: bool = False, + max_frames: int = 50, + logger_kwargs: Optional[Dict[str, Any]] = None, + ) -> None: + """ + Render a Rich traceback and call logger.exception(msg). + + Args: + msg: heading message + exc: explicit exception (defaults to current exception if in except block) + extra: logger extra + json_payload: structured context; attached to logger extra["payload"] + show_locals: show local vars in traceback + max_frames: limit traceback frames + logger_kwargs: forwarded to underlying logger call + """ + # console side: pretty traceback + tb = Traceback.from_exception( + *sys.exc_info() if exc is None else (type(exc), exc, exc.__traceback__), + show_locals=show_locals, + max_frames=max_frames, + suppress=[], + ) + header = self._compose_console_text("EXCEPTION", msg, style="bold red") + self.print(Panel(Group(header, tb), border_style="red", title="Error")) + + # logger side: proper exception record + log_extra = self._make_logger_extra(extra, json_payload) + kw = dict(logger_kwargs or {}) + self._logger.exception(str(msg), extra=log_extra, **kw) + + @contextlib.contextmanager + def capture_exceptions( + self, + *, + reraise: bool = True, + heading: str = "Unhandled exception", + show_locals: bool = False, + extra: Optional[Dict[str, Any]] = None, + json_payload: Optional[Any] = None, + ): + """ + Context manager to auto-catch, render, and log exceptions. + """ + try: + yield + except Exception as e: + self.exception( + heading, + exc=e, + show_locals=show_locals, + extra=extra, + json_payload=json_payload, + ) + if reraise: + raise + + # ---------- internals ---------- + + def _compose_console_text( + self, + label: str, + message: Union[str, Text], + *, + style: str = "white", + ) -> Text: + parts = [] + if self._show_time: + parts.append(Text.now().strftime("[%Y-%m-%d %H:%M:%S] ")) + parts.append(f"[{style}]{label}[/] ") + if isinstance(message, Text): + txt = Text.assemble(*parts) + txt.append_text(message) + return txt + else: + return Text.from_markup("".join(parts) + str(message)) + + def _maybe_with_payload(self, base: Union[Text, str], payload: Optional[Any]): + if payload is None: + return base + try: + obj = payload + if is_dataclass(obj): + obj = asdict(obj) + json_str = json.dumps( + obj, + indent=2, + ensure_ascii=False, + cls=_JSON_ENCODER if _JSON_ENCODER else None, + ) + # show payload under the line + return Group(base, Panel(json_str, title="payload", border_style="dim")) + except Exception: # never let payload rendering break logs + return base + + def _make_logger_extra( + self, + extra: Optional[Dict[str, Any]], + payload: Optional[Any], + ) -> Dict[str, Any]: + merged = {**self._sticky_extra} + if extra: + merged.update(extra) + if payload is not None: + try: + obj = payload + if is_dataclass(obj): + obj = asdict(obj) + merged["payload"] = json.loads( + json.dumps(obj, cls=_JSON_ENCODER if _JSON_ENCODER else None) + ) + except Exception: + # last-resort: stringify + merged["payload"] = repr(payload) + return merged class ErrorCategory(Enum): diff --git a/owilix/cmd/subcmds/query_extended.py b/owilix/cmd/subcmds/query_extended.py --- a/owilix/cmd/subcmds/query_extended.py +++ b/owilix/cmd/subcmds/query_extended.py @@ -1,27 +1,22 @@ import importlib import sys +from pathlib import Path from typing import Optional import duckdb import pandas as pd -from pathlib import Path +import pyarrow.parquet as pq +from rich.live import Live from rich.progress import Progress, SpinnerColumn, TextColumn +from rich.table import Table -from owilix.cmd.base import currentItemProgress, CommandResult, ask_yes_no -from owilix.core.duckdb import OWIlixSQLQuery, OWIDuckDBCopyExecutor, OWIDuckDBSelectExecutor +from owilix.cmd.base import CommandResult, ask_yes_no +from owilix.core.ciff import drop_parallel +from owilix.core.duckdb import OWIlixSQLQuery, OWIDuckDBCopyExecutor, OWIDuckDBSelectExecutor, ParquetBatchResult from owilix.core.metadata import Dataset, infer_metadata_from_files from owilix.core.stream import OWIDuckDBArrow -from owilix.core.ciff import drop, drop_parallel -import os, tempfile, posixpath -import pyarrow.parquet as pq -from datetime import datetime -from rich.console import Console, Group -from rich.live import Live -from rich.panel import Panel -from rich.progress import BarColumn -from rich.table import Table -from rich.text import Text from owilix.core.ui import ErrorCollector, EnhancedProgressDisplay + def aggregate(self, local_specifier: str, remote_specifier: str, select: str = "url,title,main_content", @@ -84,6 +79,7 @@ else: self.console.print(df) except Exception as e: + self.logger.exception(f"Error when running query (note that aggregate query requires 'FROM aggregates' clause): {e}") self.console.print(f"[red]Error when running query (note that aggregate query requires 'FROM aggregates' clause): [/red]" + str(e)) return CommandResult(success=True, object=all_files, msg=f"Shown {len(all_files)}") @@ -239,6 +235,8 @@ self.console.print(f" {i}. {suggestion}") else: self.console.print("✅ CIFF processing completed successfully with no errors!") + return True + return False def slice(self, local_specifier, remote_specifier, @@ -304,6 +302,10 @@ resume (bool): Whether to resume from previous execution slice_ciff (bool): if True (default), CIFF files are also sliced. Slicing will take significantly longer. **kwargs: additional parameters for metadata constructor + + TODO: slice improvements + - local files for provenance string + - check storage location and collection name. """ self.verbose = verbose @@ -326,7 +328,7 @@ all_ds_md_files = self.get_all_files(_md_file_pattern, local_specifier, remote_specifier, job_name=job_name, resume=resume) except Exception as e: - self.console.print(f"[red]Error getting dataset files: {e}[/red]") + self.console.exception(f"Error getting dataset files:", exc=e) return CommandResult(success=False, object=None, msg=f"Error getting dataset files: {e}") _datasets = list(all_ds_md_files.keys()) @@ -354,13 +356,13 @@ #### Create or Update Dataset if internalID: - _ds = self.owi.local.list(access=access, query={"internalID": internalID}) + _ds = self.owi.local.list(access=access, query={"id": internalID}) if len(_ds) != 1: return CommandResult(success=False, object=all_files, msg=f"found {len(_ds)} datasets given id {internalID}, but expected exactly 1") _ds = _ds[0] - _same = _ds.update_provenance(_datasets, files=paths, select=select, where=where) + _same = _ds.update_provenance(_datasets, files=paths, select=select, where=where) # TODO: only releative paths if len(_same) > 0 and not ignore_provenance: self.console.print(f"Dataset with id {_ds.metadata.id}/{_ds.metadata.title} already contains the same " @@ -403,9 +405,14 @@ group_name = r.get("group_name", "no group") objects_copied += count - if count > 0: + if objects_copied>0: + if isinstance(results, ParquetBatchResult): + _files = results.parquet_batch.files # print to log file i a reduced manner, but retain if results is reused + results.parquet_batch.files = [f[0][len(f[1]):] for f in _files] _changelog.append(str(results)) - + results.parquet_batch.files = _files + else: + _changelog.append(str(results)) return objects_copied # Use the existing _process_query_results method with our custom callback @@ -423,6 +430,7 @@ # Now process CIFF files with enhanced progress reporting self.console.print(f"Finished processing parquet files.") + _sliced_ciff = False if slice_ciff: self.console.print(f"Updating CIFF files for {_ds.metadata.id}/{_ds.metadata.title} now.") @@ -433,15 +441,14 @@ all_ds_ciff_files = self.get_all_files(paths + "*ciff*.gz", local_specifier, remote_specifier) if all_ds_ciff_files and _local_files: - _process_ciff_files(self, _ds, all_ds_ciff_files, _local_files, _md_file_pattern, job_name, num_threads=num_threads) + _sliced_ciff = _process_ciff_files(self, _ds, all_ds_ciff_files, _local_files, _md_file_pattern, job_name, num_threads=num_threads) else: self.console.print("No CIFF files found or no local files to process") else: self.console.print(f"CIFF File slicing ommitted by user flag. use slice_ciff=True to enable it.") except Exception as e: - self.console.print_exception() - self.console.print(f"[red]Dataset with id {_ds.metadata.id} at {_ds.path} is most likely corrupted and should be removed.[/red]") + self.console.exception(f"Dataset with id {_ds.metadata.id} at {_ds.path} is most likely corrupted and should be removed.", exc=e) success = False finally: @@ -452,13 +459,18 @@ # Infer metadata from files try: _inferred_md = infer_metadata_from_files( - self.owi.local.files_details(_ds, files_glob="**/*", count_rows=True) + self.owi.local.files_details(_ds, files_glob="**/metadata_*.parquet", count_rows=True) ) for k, v in _inferred_md.items(): _ds.metadata[k] = v - _ds.reformat_metadata() + if _sliced_ciff: + _ds.metadata["resourceType"]="owi" except Exception as e: - self.console.print(f"[yellow]Warning: Could not infer metadata: {e}[/yellow]") + self.console.exception(f"Warning: Could not infer metadata. Metadata might be distorted. Chang in json directly.", exc=e) + # Reformant metadata (e.g. title) and save it. + _ds.reformat_metadata() + self.console.print(f"Dataset Metdata reformated. New title is {_ds.metadata.title}") + _ds.save_metadata() self.console.print("Finished slicing and created new dataset:") self.show_details(_ds.metadata) @@ -482,7 +494,7 @@ _tmp_dir = None try: - # 1. create tmp dir for ciff files and copy the ciff file there locally + # 1. create tmp dir for ciff files and copy the remote ciff file there locally _tmp_dir = tempfile.mktemp() os.mkdir(_tmp_dir) source_fs = source_ds.repository.fs @@ -490,7 +502,6 @@ _, _ciff_filename = source_ciff.rsplit(source_fs.sep, 1) _tmp_ciff = os.path.join(_tmp_dir, _ciff_filename) source_fs.get(source_ciff, _tmp_ciff) - # 2. Get external ids from metadata files ids = set() for file_path in pq_files: diff --git a/tests/owilix/cmd/__init__.py b/tests/owilix/cmd/__init__.py new file mode 100644 --- /dev/null +++ b/tests/owilix/cmd/__init__.py diff --git a/tests/owilix/cmd/functional_test.py b/tests/owilix/cmd/functional_test.py new file mode 100644 --- /dev/null +++ b/tests/owilix/cmd/functional_test.py @@ -0,0 +1,365 @@ +import logging +import os +import random +import tempfile +import unittest + +from rich.console import Console + +from owilix.cmd import RemoteCommands, LocalCommands, QueryCommands +from owilix.core.manager import OWIlixConfig, OWIlixManager +from owilix.core.ui import OWILIXConsole + + +def setup(irods_only=False): + # irods_only converts lexis+http repositories to lexis repositories + _tmp_dir = os.path.join(tempfile.gettempdir(), "owilix") + + config = OWIlixConfig(os.path.join(_tmp_dir, "owilix.cfg"), no_remote = True) + _console = OWILIXConsole() + ctx = {} + ctx["CONSOLE"] = _console + ctx['TARGET'] = _tmp_dir + #config = read_config(target) + ctx['NODISPLAY'] = None + ctx['SORT'] = [] + ctx['DISPLAYORDER'] = None + ctx["SHOWFIELDS"] = None + ctx["MAX_COLS"] = 10 + ctx['AUTOYES'] = True + ctx['VERBOSE'] = False + #ctx['SLICE'] = slice + ctx["log_level"]= logging.INFO + ctx["owilix_config"] = config + + remotes, local = config.get_repositories() + if irods_only: + for r in remotes.values(): + if r.get("repository", "")=="lexis+http": + r["repository"]="lexis" + + ctx['OWI'] = OWIlixManager(_tmp_dir, + _tmp_dir + os.path.sep + ".logs", + repos=remotes|local) + return ctx + + +class BasicRemoteLocalFunctionalTest(unittest.TestCase): + + def setUp(self): + # Set up temporary directory and mock context + self.temp_dir = tempfile.mkdtemp() + self.config_path = os.path.join(self.temp_dir, "owilix.cfg") + self.ctx = setup() + + + def tearDown(self): + # Clean up temporary directory + if os.path.exists(self.temp_dir): + os.rmdir(self.temp_dir) + + def test_remote_ls(self): + + + parameters = ["all", "it4i:latest", "all/internalID=d549e27a-27ca-11ef-b992-0242ac160009", + "it4i/internalID=d549e27a-27ca-11ef-b992-0242ac160009", "all:2023-11-20#14/access=public;collectionName=main", + "lrz/internalID=706cf4d1-9a06-4a38-a4d4-5aec84ecac38", "lrz:latest"] + for param in parameters: + with self.subTest(param=param): + self.ctx["SORT"] = [(True, random.choice(["id","startDate", "totalSize", "collectionName", "objectCount", "dataCenter"]) )] + _r = RemoteCommands(self.ctx['OWI'], **self.ctx).do("ls", param, + files=random.choice([True, False]), + details=random.choice([True, False]), + group=random.choice([True, False])) + self.assertTrue(_r[0]["success"], f"Command not returned successfully for param '{param}' and context {self.ctx}") + self.assertTrue(_r[1] and len(_r[1])>0, + f"No datasets found for param '{param}'!") + + _r = RemoteCommands(self.ctx['OWI'], **self.ctx).do("ls", "all/internalID=d549e27a-27ca-11ef-b992-0242ac160009", + files= "**/*.parquet", details=True) + self.assertTrue(_r[0]["success"], f"Command not returned successfully for all/internalID=d549e27a-27ca-11ef-b992-0242ac16000 listing all files and context {self.ctx}") + self.assertTrue( + _r[1] and len(_r[1])==1, + f"No datasets found for param all/internalID=d549e27a-27ca-11ef-b992-0242ac16000") + + + def test_single_pull_plus_local(self): + _r = RemoteCommands(self.ctx['OWI'], **self.ctx).do("pull", "all/id=a962a1bb-3a65-4c24-954c-a96c99d5e95e") + self.assertTrue(_r[0]["success"], f"Command not returned successfully for context {self.ctx}") + self.assertTrue( + not(not _r[1] or len(_r[1]) != 1), + f"No datasets found with context {self.ctx}. Check if dataset with id 'a962a1bb-3a65-4c24-954c-a96c99d5e95e' still exists on server" + ) + _l = LocalCommands(self.ctx['OWI'], **self.ctx).do("ls", "all/id=a962a1bb-3a65-4c24-954c-a96c99d5e95e") + self.assertTrue(_l[0]["success"], f"Looking for local datasets wwas not successful with context {self.ctx}") + self.assertTrue( + not(not _l[1] or len(_l[1]) != 1), + f"No datasets found with context {self.ctx}. Check if dataset with id 'a962a1bb-3a65-4c24-954c-a96c99d5e95e' still exists on server" + ) + _local = _l[1][0] + _remote = _r[1][0] + for a in ["access"]: + self.assertTrue(hasattr(_local, a), f"Attribute {a} does not exist in local dataset") + self.assertTrue(hasattr(_remote, a), f"Attribute {a} does not exist in remtoe dataset") + self.assertTrue(getattr(_local, a)==getattr(_remote,a), + f"Attribute {a}have different values in local / remote: {getattr(_local, a)}!={getattr(_remote,a)}") + + for a in ["id","title", "startDate", "endDate", "totalSize", "objectCount", "fileCount", "collectionName","publicationYear", "internalID"]: + self.assertTrue(_local.metadata.get(a) is not None, f"Attribute {a} does not exist in local dataset") + self.assertTrue(_remote.metadata.get(a) is not None, f"Attribute {a} does not exist in remtoe dataset") + self.assertTrue(_remote.metadata.get(a) ==_local.metadata.get(a), + f"Attribute {a} have different values in local / remote: {_local.metadata.get(a)}!={_remote.metadata.get(a)}") + + _q = QueryCommands(self.ctx['OWI'], **self.ctx).do("less", "all/id=a962a1bb-3a65-4c24-954c-a96c99d5e95e", None, + select="url,title", + where="WHERE LOWER(url) like '%impressum%' OR LOWER(url) like '%legal%' OR LOWER(url) like '%imprint%' OR LOWER(url) like '%terms%' OR LOWER(url) like '%privacy%' OR LOWER(url) like '%contact%' OR LOWER(url) like '%agreement%' OR LOWER(title) like '%impressum%' OR LOWER(title) like '%imprint%'", + limit=10, pq_batch_size=1, as_json=True) + + self.assertTrue(_q[0]["success"], "query not successufll"+str(_q)) + + _q = QueryCommands(self.ctx['OWI'], **self.ctx).do("less", "all/id=a962a1bb-3a65-4c24-954c-a96c99d5e95e", None, + select="url,title", + where="WHERE LOWER(url) like '%impressum%' OR LOWER(url) like '%legal%' OR LOWER(url) like '%imprint%' OR LOWER(url) like '%terms%' OR LOWER(url) like '%privacy%' OR LOWER(url) like '%contact%' OR LOWER(url) like '%agreement%' OR LOWER(title) like '%impressum%' OR LOWER(title) like '%imprint%'", + limit=10, pq_batch_size=1, as_json=True) + + _q = QueryCommands(self.ctx['OWI'], **self.ctx).do("less", "all/id=a962a1bb-3a65-4c24-954c-a96c99d5e95e", None, + select="url,title", + where="WHERE LOWER(url) like '%impressum%' OR LOWER(url) like '%legal%' OR LOWER(url) like '%imprint%' OR LOWER(url) like '%terms%' OR LOWER(url) like '%privacy%' OR LOWER(url) like '%contact%' OR LOWER(url) like '%agreement%' OR LOWER(title) like '%impressum%' OR LOWER(title) like '%imprint%'", + limit=10, pq_batch_size=1, as_json=True) + + _q = QueryCommands(self.ctx['OWI'], **self.ctx).do("less", "all/id=a962a1bb-3a65-4c24-954c-a96c99d5e95e", None, + select="url,title", + where="WHERE LOWER(url) like '%impressum%' OR LOWER(url) like '%legal%' OR LOWER(url) like '%imprint%' OR LOWER(url) like '%terms%' OR LOWER(url) like '%privacy%' OR LOWER(url) like '%contact%' OR LOWER(url) like '%agreement%' OR LOWER(title) like '%impressum%' OR LOWER(title) like '%imprint%'", + limit=10, pq_batch_size=1, as_json=True) + + _q = QueryCommands(self.ctx['OWI'], **self.ctx).do("less", "all/id=a962a1bb-3a65-4c24-954c-a96c99d5e95e", None, + select="url,title", + where="WHERE LOWER(url) like '%impressum%' OR LOWER(url) like '%legal%' OR LOWER(url) like '%imprint%' OR LOWER(url) like '%terms%' OR LOWER(url) like '%privacy%' OR LOWER(url) like '%contact%' OR LOWER(url) like '%agreement%' OR LOWER(title) like '%impressum%' OR LOWER(title) like '%imprint%'", + limit=10, pq_batch_size=1, as_json=True) + + # TODO: ADDD REMOVE TO THE TEST + #_l = LocalCommands(self.ctx['OWI'], **self.ctx).do("stats") + # + #_l = LocalCommands(self.ctx['OWI'], **self.ctx).do("check") + #self.assertTrue(_l[0]["success"], f"Checking local datasets for consistency not successfull {self.ctx}") + + + _l = LocalCommands(self.ctx['OWI'], **self.ctx).do("free", "all/id=a962a1bb-3a65-4c24-954c-a96c99d5e95e") + + #_l = LocalCommands(self.ctx['OWI'], **self.ctx).do("insert", "all/id=a962a1bb-3a65-4c24-954c-a96c99d5e95e") + # TODO: Querying, + + def test_slice(self): + # Pull a known remote so we have local source data to slice + _r = RemoteCommands(self.ctx['OWI'], **self.ctx).do( + "pull", "all/id=a962a1bb-3a65-4c24-954c-a96c99d5e95e" + ) + self.assertTrue(_r[0]["success"], f"Command not returned successfully for context {self.ctx}") + self.assertTrue( + not (not _r[1] or len(_r[1]) != 1), + "No datasets found; check if dataset 'a962a1bb-3a65-4c24-954c-a96c99d5e95e' exists on server" + ) + + uniq_cn = f"userslice_test_{random.randint(1, 1_000_000)}" + + _q = QueryCommands(self.ctx['OWI'], **self.ctx).do( + "slice", + "all/id=a962a1bb-3a65-4c24-954c-a96c99d5e95e", + None, + select="url,title", + where="WHERE LOWER(url) ilike '%impressum%'", + collection_name=uniq_cn, + slice_ciff=False, + ) + self.assertTrue(_q[0]["success"], "slice command did not succeed: " + str(_q)) + + _sliced = LocalCommands(self.ctx['OWI'], **self.ctx).do("ls", f"all/collectionName={uniq_cn}") + self.assertTrue(_sliced[0]["success"], f"Listing sliced dataset failed: {self.ctx}") + self.assertTrue(_sliced[1] and len(_sliced[1]) == 1, + f"Expected exactly one dataset in collection {uniq_cn}, got: {_sliced[1]}") + ds = _sliced[1][0] + + # Metadata checks + self.assertEqual(ds.metadata.get("collectionName"), uniq_cn) + self.assertEqual(ds.metadata.get("resourceType"), "owip") + self.assertTrue(ds.metadata.get("id")) + self.assertEqual(getattr(ds, "access", None), "public") + + # Files written check + files_resp = LocalCommands(self.ctx['OWI'], **self.ctx).do( + "ls", f"all/id={ds.metadata.get('id')}", files="**/metadata_*.parquet", details=True + ) + self.assertTrue(files_resp[0]["success"], "Listing parquet files in sliced dataset failed") + self.assertTrue(files_resp[1] and len(files_resp[1]) == 1, + "Expected exactly one dataset in file listing response") + self.assertGreaterEqual(ds.metadata.get("fileCount", 0), 1) + self.assertGreaterEqual(ds.metadata.get("objectCount", 0), 1) + + # Changelog check + changelog = getattr(ds, "changelog", []) + self.assertTrue(changelog, "Changelog should not be empty after slice") + self.assertTrue( + any("Slice Result:" in str(entry) for entry in changelog), + f"Changelog does not contain expected 'Slice Result:' entry, got: {changelog}" + ) + + # Optional sanity query against the slice + sanity_q = QueryCommands(self.ctx['OWI'], **self.ctx).do( + "less", + f"all/collectionName={uniq_cn}", + None, + select="url,title", + limit=5, + pq_batch_size=1, + as_json=True + ) + self.assertTrue(sanity_q[0]["success"], "Query against sliced dataset failed: " + str(sanity_q)) + + def test_local_ls_with_files_and_groups(self): + _r = RemoteCommands(self.ctx['OWI'], **self.ctx).do( + "pull", "all/id=a962a1bb-3a65-4c24-954c-a96c99d5e95e" + ) + self.assertTrue(_r[0]["success"]) + + # ls() plain + _ls = LocalCommands(self.ctx['OWI'], **self.ctx).do( + "ls", "all/id=a962a1bb-3a65-4c24-954c-a96c99d5e95e" + ) + self.assertTrue(_ls[0]["success"], f"ls failed: {_ls}") + self.assertTrue(_ls[1] and len(_ls[1]) == 1, "Expected exactly one local dataset") + + # ls() with files glob and grouping (ensure it doesn't crash and returns datasets) + _ls_files = LocalCommands(self.ctx['OWI'], **self.ctx).do( + "ls", + "all/id=a962a1bb-3a65-4c24-954c-a96c99d5e95e", + files="**/*.parquet", + groups=2, # group depth + details=True, # harmless here; method ignores it for return payload + ) + self.assertTrue(_ls_files[0]["success"], f"ls with files/groups failed: {_ls_files}") + self.assertTrue(_ls_files[1] and len(_ls_files[1]) == 1) + + def test_local_export(self): + _r = RemoteCommands(self.ctx['OWI'], **self.ctx).do( + "pull", "all/id=a962a1bb-3a65-4c24-954c-a96c99d5e95e" + ) + self.assertTrue(_r[0]["success"]) + + # Prepare outdir inside local repo fs + outdir = os.path.join(self.ctx['TARGET'], f"export_out_{random.randint(1, 1_000_000)}") + + _exp = LocalCommands(self.ctx['OWI'], **self.ctx).do( + "export", + "all/id=a962a1bb-3a65-4c24-954c-a96c99d5e95e", + outdir, + ) + self.assertTrue(_exp[0]["success"], f"export failed: {_exp}") + obj = _exp[1] + self.assertIn("parquet", obj) + self.assertGreaterEqual(obj["parquet"]["found"], 1, "Expected at least one metadata parquet to export") + + # Verify files exist in the outdir (via local fs) + fs = self.ctx['OWI'].local.fs + exported_parqs = fs.glob(os.path.join(outdir, "**", "*.parquet")) + self.assertTrue(len(exported_parqs) >= 1, "No exported parquet files found on disk") + + # CIFF availability varies; assert shape of result + self.assertIn("ciff", obj) + self.assertIn("found", obj["ciff"]) + self.assertIn("merged", obj["ciff"]) + + def test_local_remove_on_new_slice(self): + # Start with pull + _r = RemoteCommands(self.ctx['OWI'], **self.ctx).do( + "pull", "all/id=a962a1bb-3a65-4c24-954c-a96c99d5e95e" + ) + self.assertTrue(_r[0]["success"]) + + # Create a tiny slice we can safely delete + uniq_cn = f"userslice_remove_{random.randint(1, 1_000_000)}" + _slice = QueryCommands(self.ctx['OWI'], **self.ctx).do( + "slice", + "all/id=a962a1bb-3a65-4c24-954c-a96c99d5e95e", + None, + select="url,title", + where="WHERE LOWER(url) ilike '%impressum%'", + collection_name=uniq_cn, + slice_ciff=False, + ) + self.assertTrue(_slice[0]["success"], f"slice failed before remove: {_slice}") + + # Ensure it exists locally + _ls = LocalCommands(self.ctx['OWI'], **self.ctx).do("ls", f"all/collectionName={uniq_cn}") + self.assertTrue(_ls[0]["success"] and _ls[1] and len(_ls[1]) == 1) + ds = _ls[1][0] + ds_path = ds.path + fs = self.ctx['OWI'].local.fs + self.assertTrue(fs.exists(ds_path), "Sliced dataset path should exist before remove") + + # remove() + _rm = LocalCommands(self.ctx['OWI'], **self.ctx).do("remove", f"all/collectionName={uniq_cn}") + self.assertTrue(_rm[0]["success"], f"remove failed: {_rm}") + + # Verify it's gone + _ls2 = LocalCommands(self.ctx['OWI'], **self.ctx).do("ls", f"all/collectionName={uniq_cn}") + self.assertTrue(_ls2[0]["success"]) + self.assertTrue(not _ls2[1], "Dataset should be gone after remove") + self.assertFalse(fs.exists(ds_path), "Dataset path should be removed from filesystem") + + def test_local_free_on_new_slice(self): + # Start with pull + _r = RemoteCommands(self.ctx['OWI'], **self.ctx).do( + "pull", "all/id=a962a1bb-3a65-4c24-954c-a96c99d5e95e" + ) + self.assertTrue(_r[0]["success"]) + + # Create a tiny slice we can safely free + uniq_cn = f"userslice_free_{random.randint(1, 1_000_000)}" + _slice = QueryCommands(self.ctx['OWI'], **self.ctx).do( + "slice", + "all/id=a962a1bb-3a65-4c24-954c-a96c99d5e95e", + None, + select="url,title", + where="WHERE LOWER(url) ilike '%impressum%'", + collection_name=uniq_cn, + slice_ciff=False, + ) + self.assertTrue(_slice[0]["success"]) + + # Ensure it exists locally + _ls = LocalCommands(self.ctx['OWI'], **self.ctx).do("ls", f"all/collectionName={uniq_cn}") + self.assertTrue(_ls[0]["success"] and _ls[1] and len(_ls[1]) == 1) + ds = _ls[1][0] + ds_path = ds.path + fs = self.ctx['OWI'].local.fs + self.assertTrue(fs.exists(ds_path), "Sliced dataset path should exist before free") + + # free() + _free = LocalCommands(self.ctx['OWI'], **self.ctx).do("free", f"all/collectionName={uniq_cn}") + # free() has no explicit CommandResult; just ensure the path is gone after it runs + self.assertFalse(fs.exists(ds_path), "Dataset path should be removed from filesystem after free") + + # Verify listing is empty + _ls2 = LocalCommands(self.ctx['OWI'], **self.ctx).do("ls", f"all/collectionName={uniq_cn}") + self.assertTrue(_ls2[0]["success"]) + self.assertTrue(not _ls2[1], "Dataset should be gone after free") + + + def test_warc_download(self): + # Todo: implement a test for the warc download by uploading two warcs to passau s3 + raise (NotImplemented) + + + + +#class IRODSOnlyConfigTests(OriginalConfigTests): +# +# def setUp(self): +# # Set up temporary directory and mock context +# self.temp_dir = tempfile.mkdtemp() +# self.config_path = os.path.join(self.temp_dir, "owilix.cfg") +# self.ctx = setup(True) + + # Add more test cases here as needed for extensibility +if __name__ == "__main__": + unittest.main() diff --git a/tests/owilix/core/functional_test.py b/tests/owilix/core/functional_test.py deleted file mode 100644 --- a/tests/owilix/core/functional_test.py +++ /dev/null @@ -1,166 +0,0 @@ -import logging -import os -import random -import tempfile -import unittest - -from rich.console import Console - -from owilix.cmd import RemoteCommands, LocalCommands, QueryCommands -from owilix.core.manager import OWIlixConfig, OWIlixManager - - -def setup(irods_only=False): - # irods_only converts lexis+http repositories to lexis repositories - _tmp_dir = os.path.join(tempfile.gettempdir(), "owilix") - - config = OWIlixConfig(os.path.join(_tmp_dir, "owilix.cfg"), no_remote = True) - _console = Console() - ctx = {} - ctx["CONSOLE"] = _console - ctx['TARGET'] = _tmp_dir - #config = read_config(target) - ctx['NODISPLAY'] = None - ctx['SORT'] = [] - ctx['DISPLAYORDER'] = None - ctx["SHOWFIELDS"] = None - ctx["MAX_COLS"] = 10 - ctx['AUTOYES'] = True - ctx['VERBOSE'] = False - #ctx['SLICE'] = slice - ctx["log_level"]= logging.INFO - ctx["owilix_config"] = config - - remotes, local = config.get_repositories() - if irods_only: - for r in remotes.values(): - if r.get("repository", "")=="lexis+http": - r["repository"]="lexis" - - ctx['OWI'] = OWIlixManager(_tmp_dir, - _tmp_dir + os.path.sep + ".logs", - repos=remotes|local) - return ctx - - -class OriginalConfigTests(unittest.TestCase): - - def setUp(self): - # Set up temporary directory and mock context - self.temp_dir = tempfile.mkdtemp() - self.config_path = os.path.join(self.temp_dir, "owilix.cfg") - self.ctx = setup() - - - def tearDown(self): - # Clean up temporary directory - if os.path.exists(self.temp_dir): - os.rmdir(self.temp_dir) - - def test_remote_ls(self): - - - parameters = ["all", "it4i:latest", "all/internalID=d549e27a-27ca-11ef-b992-0242ac160009", - "it4i/internalID=d549e27a-27ca-11ef-b992-0242ac160009", "all:2023-11-20#14/access=public;collectionName=main", - "lrz/internalID=706cf4d1-9a06-4a38-a4d4-5aec84ecac38", "lrz:latest"] - for param in parameters: - with self.subTest(param=param): - self.ctx["SORT"] = [(True, random.choice(["id","startDate", "totalSize", "collectionName", "objectCount", "dataCenter"]) )] - _r = RemoteCommands(self.ctx['OWI'], **self.ctx).do("ls", param) - self.assertTrue(_r[0]["success"], f"Command not returned successfully for param '{param}' and context {self.ctx}") - self.assertTrue(_r[1] and len(_r[1])>0, - f"No datasets found for param '{param}'!") - - _r = RemoteCommands(self.ctx['OWI'], **self.ctx).do("ls", "all/internalID=d549e27a-27ca-11ef-b992-0242ac160009", - files= "**/*.parquet", details=True) - self.assertTrue(_r[0]["success"], f"Command not returned successfully for all/internalID=d549e27a-27ca-11ef-b992-0242ac16000 listing all files and context {self.ctx}") - self.assertTrue( - _r[1] and len(_r[1])==1, - f"No datasets found for param all/internalID=d549e27a-27ca-11ef-b992-0242ac16000") - - - def test_single_pull_plus_local(self): - _r = RemoteCommands(self.ctx['OWI'], **self.ctx).do("pull", "all/id=a962a1bb-3a65-4c24-954c-a96c99d5e95e") - self.assertTrue(_r[0]["success"], f"Command not returned successfully for context {self.ctx}") - self.assertTrue( - not(not _r[1] or len(_r[1]) != 1), - f"No datasets found with context {self.ctx}. Check if dataset with id 'a962a1bb-3a65-4c24-954c-a96c99d5e95e' still exists on server" - ) - _l = LocalCommands(self.ctx['OWI'], **self.ctx).do("ls", "all/id=a962a1bb-3a65-4c24-954c-a96c99d5e95e") - self.assertTrue(_l[0]["success"], f"Looking for local datasets wwas not successful with context {self.ctx}") - self.assertTrue( - not(not _l[1] or len(_l[1]) != 1), - f"No datasets found with context {self.ctx}. Check if dataset with id 'a962a1bb-3a65-4c24-954c-a96c99d5e95e' still exists on server" - ) - _local = _l[1][0] - _remote = _r[1][0] - for a in ["access"]: - self.assertTrue(hasattr(_local, a), f"Attribute {a} does not exist in local dataset") - self.assertTrue(hasattr(_remote, a), f"Attribute {a} does not exist in remtoe dataset") - self.assertTrue(getattr(_local, a)==getattr(_remote,a), - f"Attribute {a}have different values in local / remote: {getattr(_local, a)}!={getattr(_remote,a)}") - - for a in ["id","title", "startDate", "endDate", "totalSize", "objectCount", "fileCount", "collectionName","publicationYear", "internalID"]: - self.assertTrue(_local.metadata.get(a) is not None, f"Attribute {a} does not exist in local dataset") - self.assertTrue(_remote.metadata.get(a) is not None, f"Attribute {a} does not exist in remtoe dataset") - self.assertTrue(_remote.metadata.get(a) ==_local.metadata.get(a), - f"Attribute {a} have different values in local / remote: {_local.metadata.get(a)}!={_remote.metadata.get(a)}") - - _q = QueryCommands(self.ctx['OWI'], **self.ctx).do("less", "all/id=a962a1bb-3a65-4c24-954c-a96c99d5e95e", None, - select="url,title", - where="WHERE LOWER(url) like '%impressum%' OR LOWER(url) like '%legal%' OR LOWER(url) like '%imprint%' OR LOWER(url) like '%terms%' OR LOWER(url) like '%privacy%' OR LOWER(url) like '%contact%' OR LOWER(url) like '%agreement%' OR LOWER(title) like '%impressum%' OR LOWER(title) like '%imprint%'", - limit=10, pq_batch_size=1, as_json=True) - - self.assertTrue(_q[0]["success"], "query not successufll"+str(_q)) - - _q = QueryCommands(self.ctx['OWI'], **self.ctx).do("less", "all/id=a962a1bb-3a65-4c24-954c-a96c99d5e95e", None, - select="url,title", - where="WHERE LOWER(url) like '%impressum%' OR LOWER(url) like '%legal%' OR LOWER(url) like '%imprint%' OR LOWER(url) like '%terms%' OR LOWER(url) like '%privacy%' OR LOWER(url) like '%contact%' OR LOWER(url) like '%agreement%' OR LOWER(title) like '%impressum%' OR LOWER(title) like '%imprint%'", - limit=10, pq_batch_size=1, as_json=True) - - _q = QueryCommands(self.ctx['OWI'], **self.ctx).do("less", "all/id=a962a1bb-3a65-4c24-954c-a96c99d5e95e", None, - select="url,title", - where="WHERE LOWER(url) like '%impressum%' OR LOWER(url) like '%legal%' OR LOWER(url) like '%imprint%' OR LOWER(url) like '%terms%' OR LOWER(url) like '%privacy%' OR LOWER(url) like '%contact%' OR LOWER(url) like '%agreement%' OR LOWER(title) like '%impressum%' OR LOWER(title) like '%imprint%'", - limit=10, pq_batch_size=1, as_json=True) - - _q = QueryCommands(self.ctx['OWI'], **self.ctx).do("less", "all/id=a962a1bb-3a65-4c24-954c-a96c99d5e95e", None, - select="url,title", - where="WHERE LOWER(url) like '%impressum%' OR LOWER(url) like '%legal%' OR LOWER(url) like '%imprint%' OR LOWER(url) like '%terms%' OR LOWER(url) like '%privacy%' OR LOWER(url) like '%contact%' OR LOWER(url) like '%agreement%' OR LOWER(title) like '%impressum%' OR LOWER(title) like '%imprint%'", - limit=10, pq_batch_size=1, as_json=True) - - _q = QueryCommands(self.ctx['OWI'], **self.ctx).do("less", "all/id=a962a1bb-3a65-4c24-954c-a96c99d5e95e", None, - select="url,title", - where="WHERE LOWER(url) like '%impressum%' OR LOWER(url) like '%legal%' OR LOWER(url) like '%imprint%' OR LOWER(url) like '%terms%' OR LOWER(url) like '%privacy%' OR LOWER(url) like '%contact%' OR LOWER(url) like '%agreement%' OR LOWER(title) like '%impressum%' OR LOWER(title) like '%imprint%'", - limit=10, pq_batch_size=1, as_json=True) - - # TODO: ADDD REMOVE TO THE TEST - #_l = LocalCommands(self.ctx['OWI'], **self.ctx).do("stats") - # - #_l = LocalCommands(self.ctx['OWI'], **self.ctx).do("check") - #self.assertTrue(_l[0]["success"], f"Checking local datasets for consistency not successfull {self.ctx}") - - - _l = LocalCommands(self.ctx['OWI'], **self.ctx).do("free", "all/id=a962a1bb-3a65-4c24-954c-a96c99d5e95e") - - #_l = LocalCommands(self.ctx['OWI'], **self.ctx).do("insert", "all/id=a962a1bb-3a65-4c24-954c-a96c99d5e95e") - # TODO: Querying, - - - def test_warc_download(self): - # Todo: implement a test for the warc download by uploading two warcs to passau s3 - raise (NotImplemented) - - - - -class IRODSOnlyConfigTests(OriginalConfigTests): - - def setUp(self): - # Set up temporary directory and mock context - self.temp_dir = tempfile.mkdtemp() - self.config_path = os.path.join(self.temp_dir, "owilix.cfg") - self.ctx = setup(True) - - # Add more test cases here as needed for extensibility -if __name__ == "__main__": - unittest.main() diff --git a/tests/owilix/core/test_drop_parallel.py b/tests/owilix/core/test_drop_parallel.py new file mode 100644 --- /dev/null +++ b/tests/owilix/core/test_drop_parallel.py @@ -0,0 +1,286 @@ +# tests/owilix/core/test_drop_merge_dump.py +import math +from pathlib import Path +import pytest + +# --- adjust these imports to your project layout --- +from owilix.core.ciff import drop_parallel +from ciff_toolkit.util import dump_ciff +from ciff_toolkit.merge import merge_ciff_files + +from ciff_toolkit.ciff_pb2 import Header, PostingsList, Posting, DocRecord +from ciff_toolkit.read import CiffReader +from ciff_toolkit.write import CiffWriter + + +# ---------- Helpers ---------- +def _make_pl(term: str, docids, tfs) -> PostingsList: + """Create a PostingsList with delta-gap encoded docids.""" + assert len(docids) == len(tfs) + pl = PostingsList() + pl.term = term + pl.df = len(docids) + pl.cf = int(sum(tfs)) + prev = 0 + for d, tf in zip(docids, tfs): + p = Posting() + p.docid = int(d - prev) # delta-gap + p.tf = int(tf) + pl.postings.append(p) + prev = d + return pl + + +def _decode_docids(pl: PostingsList): + acc = 0 + out = [] + for p in pl.postings: + acc += p.docid + out.append(acc) + return out + + +def _write_ciff_original(path: Path, *, docs_spec, pls_spec, description: str): + """ + Write a canonical/original order CIFF: + HEADER -> POSTINGS -> DOCUMENTS + docs_spec: [(collection_docid, doclength), ...] + pls_spec: [(term, [docids...], [tfs...]), ...] + """ + docs = [] + for i, (coll_id, dlen) in enumerate(docs_spec): + dr = DocRecord() + dr.docid = i + dr.collection_docid = coll_id + dr.doclength = int(dlen) + docs.append(dr) + + pls = [_make_pl(term, docids, tfs) for (term, docids, tfs) in pls_spec] + + hdr = Header() + hdr.version = 1 + hdr.num_docs = len(docs) + hdr.num_postings_lists = len(pls) + hdr.total_docs = hdr.num_docs + hdr.total_postings_lists = hdr.num_postings_lists + hdr.total_terms_in_collection = sum(pl.cf for pl in pls) + hdr.average_doclength = ( + sum(dr.doclength for dr in docs) / float(hdr.num_docs) if hdr.num_docs else 0.0 + ) + hdr.description = description + + with CiffWriter(path) as w: + w.write_header(hdr) + for pl in pls: + w.write_message(pl) # postings first + w.write_documents(docs) # documents last + + return path + + +def _read_original_order(path: Path): + """Read HEADER -> POSTINGS -> DOCUMENTS.""" + with CiffReader(path) as r: + h = r.read_header() + pls = list(r.read_postings_lists()) + docs = list(r.read_documents()) + return h, pls, docs + + +def _assert_canonical_order(path: Path): + """ + Fail early if the file is not readable in canonical order or docs look malformed. + """ + h, pls, docs = _read_original_order(path) + + # Quick structural checks + assert len(pls) == h.num_postings_lists, ( + f"{path} not canonical: postings count mismatch " + f"({len(pls)} != header {h.num_postings_lists})" + ) + assert len(docs) == h.num_docs, ( + f"{path} not canonical: docs count mismatch ({len(docs)} != header {h.num_docs})" + ) + # Check docs fields look sane + for i, d in enumerate(docs): + assert d.collection_docid != "", f"{path} not canonical: empty collection_docid at doc {i}" + assert d.docid == i, f"{path} not canonical: non-dense docids (found {d.docid} at index {i})" + assert d.doclength >= 0, f"{path} not canonical: negative length at doc {i}" + + return h, pls, docs + + +# ---------- 1) DROP behavior + dump ---------- +def test_drop_parallel_keep_subset_and_dump_canonical(tmp_path: Path, capsys: pytest.CaptureFixture): + """ + Build a tiny CIFF (original order), run drop_parallel to keep a subset, + then verify: + - Output is canonical (HEADER->POSTINGS->DOCUMENTS) + - Documents are densely reindexed with correct fields + - Postings remapped to new docids; df/cf correct + - Header stats recomputed (or set) consistently for the filtered file + - dump_ciff prints expected lines + """ + # Synthetic input with balanced terms so we can also use it later for merge + # Docs: A(3), B(2), C(5), D(1) + # Terms: + # alpha -> A,C (tfs 2,1) cf=3 (kept by AC) + # bravo -> B,D (tfs 2,1) cf=3 (kept by BD) + # charlie -> C (tf 2) cf=2 (kept by AC) + # delta -> B (tf 2) cf=2 (kept by BD) + in_path = tmp_path / "in.ciff" + _write_ciff_original( + in_path, + docs_spec=[("A", 3), ("B", 2), ("C", 5), ("D", 1)], + pls_spec=[ + ("alpha", [0, 2], [2, 1]), + ("bravo", [1, 3], [2, 1]), + ("charlie", [2], [2]), + ("delta", [1], [2]), + ], + description="Synthetic input (original order; balanced subsets)", + ) + + out_path = tmp_path / "out_keep_AC.ciff" + drop_parallel( + ciff_file=in_path, + new_ciff_file=out_path, + collection_ids={"A", "C"}, # keep A & C + keep=True, + threads=2, + ) + + # Must be canonical; fail with a clear message if not + hdr, pls, docs = _assert_canonical_order(out_path) + + # Documents expected: 0:A(3), 1:C(5) + assert len(docs) == 2 + assert (docs[0].docid, docs[0].collection_docid, docs[0].doclength) == (0, "A", 3) + assert (docs[1].docid, docs[1].collection_docid, docs[1].doclength) == (1, "C", 5) + + # Postings: alpha -> ; bravo/delta dropped + terms = {pl.term: pl for pl in pls} + assert set(terms) == {"alpha", "charlie"} + + alpha = terms["alpha"] + assert _decode_docids(alpha) == [0, 1] + assert [p.tf for p in alpha.postings] == [2, 1] + assert alpha.df == 2 and alpha.cf == 3 + + charlie = terms["charlie"] + assert _decode_docids(charlie) == [1] + assert [p.tf for p in charlie.postings] == [2] + assert charlie.df == 1 and charlie.cf == 2 + + # Header counters must match file content + assert hdr.num_docs == 2 + assert hdr.num_postings_lists == 2 + # average_doclength should be (3+5)/2 + assert math.isclose(hdr.average_doclength, 4.0, rel_tol=0, abs_tol=1e-12) + # total_terms_in_collection is sum of cf over surviving lists: 3+2=5 + assert hdr.total_terms_in_collection == 5 + + # dump must print the same lines + dump_ciff(out_path) + printed = capsys.readouterr().out + assert "num_docs: 2" in printed and "num_postings_lists: 2" in printed + assert "alpha\tdf: 2\tcf: 3" in printed + assert "charlie\tdf: 1\tcf: 2" in printed + assert "Doc 0 (A), length=3" in printed + assert "Doc 1 (C), length=5" in printed + + +# ---------- 2) MERGE after drop ---------- +def test_merge_after_two_drops_canonical_and_correct(tmp_path: Path, capsys: pytest.CaptureFixture): + """ + Drop two disjoint subsets from the same balanced input and merge them. + We verify: + - merged file is canonical + - docs are densely reindexed and ordered by collection_docid (per your merger) + - postings merged by term with correct d-gaps, df, cf + - header per-file counters reflect merged result + - dump prints expected lines + """ + # Base input exactly as above (balanced so both drops have the same total_terms_in_collection = 5) + base = tmp_path / "base.ciff" + _write_ciff_original( + base, + docs_spec=[("A", 3), ("B", 2), ("C", 5), ("D", 1)], + pls_spec=[ + ("alpha", [0, 2], [2, 1]), # A,C + ("bravo", [1, 3], [2, 1]), # B,D + ("charlie", [2], [2]), # C + ("delta", [1], [2]), # B + ], + description="Balanced input for merge-after-drop", + ) + + out_ac = tmp_path / "drop_AC.ciff" + out_bd = tmp_path / "drop_BD.ciff" + drop_parallel(base, out_ac, {"A", "C"}, keep=True, threads=2) + drop_parallel(base, out_bd, {"B", "D"}, keep=True, threads=2) + + # Sanity: both outputs must be canonical and have equal total_terms_in_collection (=5) + h_ac, pls_ac, docs_ac = _assert_canonical_order(out_ac) + h_bd, pls_bd, docs_bd = _assert_canonical_order(out_bd) + assert h_ac.total_terms_in_collection == h_bd.total_terms_in_collection == 5 + assert h_ac.num_docs == 2 and h_bd.num_docs == 2 + + merged = tmp_path / "merged.ciff" + merge_ciff_files([out_ac, out_bd], merged, show_progress=False) + + # Merged must be canonical + h, pls, docs = _assert_canonical_order(merged) + + # Your CiffMerge orders docs lexicographically by collection_docid: + # A(0), B(1), C(2), D(3) + assert [(d.docid, d.collection_docid, d.doclength) for d in docs] == [ + (0, "A", 3), + (1, "B", 2), + (2, "C", 5), + (3, "D", 1), + ] + + # Terms expected in merged: alpha (A,C), bravo (B,D), charlie (C), delta (B) + terms = {pl.term: pl for pl in pls} + assert set(terms) == {"alpha", "bravo", "charlie", "delta"} + + # alpha: A(0), C(2) -> [0,2], tfs [2,1] + alpha = terms["alpha"] + assert _decode_docids(alpha) == [0, 2] + assert [p.tf for p in alpha.postings] == [2, 1] + assert alpha.df == 2 and alpha.cf == 3 + + # bravo: B(1), D(3) -> [1,3], tfs [2,1] + bravo = terms["bravo"] + assert _decode_docids(bravo) == [1, 3] + assert [p.tf for p in bravo.postings] == [2, 1] + assert bravo.df == 2 and bravo.cf == 3 + + # charlie: C(2) -> [2], tf [2] + charlie = terms["charlie"] + assert _decode_docids(charlie) == [2] + assert [p.tf for p in charlie.postings] == [2] + assert charlie.df == 1 and charlie.cf == 2 + + # delta: B(1) -> [1], tf [2] + delta = terms["delta"] + assert _decode_docids(delta) == [1] + assert [p.tf for p in delta.postings] == [2] + assert delta.df == 1 and delta.cf == 2 + + # Header per-file counters reflect merged result + assert h.num_docs == 4 + assert h.num_postings_lists == 4 + + # dump should print consistent content + dump_ciff(merged) + printed = capsys.readouterr().out + assert "num_docs: 4" in printed + assert "num_postings_lists: 4" in printed + assert "alpha\tdf: 2\tcf: 3" in printed + assert "bravo\tdf: 2\tcf: 3" in printed + assert "charlie\tdf: 1\tcf: 2" in printed + assert "delta\tdf: 1\tcf: 2" in printed + assert "Doc 0 (A), length=3" in printed + assert "Doc 3 (D), length=1" in printed diff --git a/tests/owilix/core/test_graph_commands.py b/tests/owilix/core/test_graph_commands.py --- a/tests/owilix/core/test_graph_commands.py +++ b/tests/owilix/core/test_graph_commands.py @@ -4,7 +4,7 @@ import shutil # Import setup function and utilities from the main functional test file -from tests.repository.functional_test import setup +from tests.owilix.cmd.functional_test import setup from owilix.cmd import RemoteCommands, LocalCommands, QueryCommands