From 19f7ce53a1c38d70d8450b6a2d009bd20905c7c2 Mon Sep 17 00:00:00 2001 From: Josh Taillon Date: Mon, 14 Sep 2026 11:08:37 -0600 Subject: [PATCH 01/26] ci: correct the docs version badge from pyproject.toml great-docs takes the navbar version badge from the newest GitHub Release for the whole repository and cannot filter by tag prefix, so in this monorepo it shows whichever of the two release series published most recently. The only Release so far is r-v0.1.0, which rendered as vr-v0.1.0 on the Python site. The badge is injected during great-docs' own post-render step, so it cannot be corrected mid-build. This rewrites it afterwards from pkg-py/pyproject.toml, the same way noindex-preview.py post-processes built HTML. --- .github/scripts/docs-version-badge.py | 74 ++++++++++++++++++++++ .github/scripts/test_docs_version_badge.py | 68 ++++++++++++++++++++ .github/workflows/scripts-check.yaml | 3 + 3 files changed, 145 insertions(+) create mode 100644 .github/scripts/docs-version-badge.py create mode 100644 .github/scripts/test_docs_version_badge.py diff --git a/.github/scripts/docs-version-badge.py b/.github/scripts/docs-version-badge.py new file mode 100644 index 00000000..168cea07 --- /dev/null +++ b/.github/scripts/docs-version-badge.py @@ -0,0 +1,74 @@ +"""Correct the navbar version badge on a built Python docs site, in place. + +great-docs writes the badge from the newest GitHub Release for the whole +repository, with no way to filter by tag prefix. This is a monorepo with two +release series, `r-v*` and `py-v*`, so the badge shows whichever package +released most recently and is wrong roughly half the time. The version in +pkg-py/pyproject.toml is the only authority for what the Python site +documents, so the badge is rewritten from it after the site is built. + +The badge is injected by great-docs' own post-render step, which runs inside +`great-docs build`, so there is no point at which the metadata it reads could +be corrected instead. + +Remove this script if great-docs gains a version override or a tag-prefix +filter. + +Usage: docs-version-badge.py +""" + +from __future__ import annotations + +import pathlib +import re +import sys + +# Captures the badge's attributes separately from its text, so a release-date +# title survives and an already-correct page can be left alone. The closing +# quote after the class name is what stops a longer class that merely starts +# the same way, such as version-badge-legend, from matching. +BADGE = re.compile(r'(]*>)([^<]*)()') + + +def retag(text: str, version: str) -> str | None: + """Return `text` with every badge reading `v`, or None if unchanged. + + Returning None for "nothing to do" keeps the caller from rewriting a file + it does not need to touch, and makes the function idempotent. + """ + wanted = f"v{version}" + + def replace(match: re.Match[str]) -> str: + return f"{match.group(1)}{wanted}{match.group(3)}" + + patched, count = BADGE.subn(replace, text) + if not count or patched == text: + return None + return patched + + +def main(root: str, version: str) -> int: + directory = pathlib.Path(root) + if not directory.is_dir(): + print(f"{root} is not a directory", file=sys.stderr) + return 1 + + changed = skipped = 0 + for path in sorted(directory.rglob("*.html")): + text = path.read_text(encoding="utf-8", errors="surrogateescape") + patched = retag(text, version) + if patched is None: + skipped += 1 + continue + path.write_text(patched, encoding="utf-8", errors="surrogateescape") + changed += 1 + + print(f"Corrected the version badge on {changed} page(s), skipped {skipped}.") + return 0 + + +if __name__ == "__main__": + if len(sys.argv) != 3: + print(__doc__, file=sys.stderr) + raise SystemExit(2) + raise SystemExit(main(sys.argv[1], sys.argv[2])) diff --git a/.github/scripts/test_docs_version_badge.py b/.github/scripts/test_docs_version_badge.py new file mode 100644 index 00000000..918c9ab4 --- /dev/null +++ b/.github/scripts/test_docs_version_badge.py @@ -0,0 +1,68 @@ +"""Tests for docs-version-badge.py. Run: python3 test_docs_version_badge.py""" + +import importlib.util +import pathlib +import unittest + +spec = importlib.util.spec_from_file_location( + "docs_version_badge", pathlib.Path(__file__).parent / "docs-version-badge.py" +) +assert spec and spec.loader +badge = importlib.util.module_from_spec(spec) +spec.loader.exec_module(badge) + +retag = badge.retag + + +class RetagTest(unittest.TestCase): + def test_replaces_the_badge_text(self): + page = ( + 'commons ' + 'vr-v0.1.0' + ) + out = retag(page, "0.1.0b1") + assert out is not None + self.assertIn(">v0.1.0b1<", out) + self.assertNotIn("vr-v0.1.0", out) + + def test_keeps_the_surrounding_attributes(self): + # The badge carries a release-date title attribute. Replacing the + # whole tag would drop it; only the text node should change. + page = 'vr-v0.1.0' + out = retag(page, "0.1.0b1") + assert out is not None + self.assertIn('title="Released 2026-09-11"', out) + self.assertIn(">v0.1.0b1<", out) + + def test_replaces_every_occurrence(self): + # The badge is injected into the navbar of every page, and the logo + # tooltip carries the version too. + page = ( + 'vr-v0.1.0x' + 'vr-v0.1.0' + ) + out = retag(page, "0.1.0b1") + assert out is not None + self.assertEqual(out.count(">v0.1.0b1<"), 2) + + def test_returns_none_when_there_is_no_badge(self): + self.assertIsNone(retag("no badge", "0.1.0b1")) + + def test_returns_none_when_the_badge_is_already_correct(self): + page = 'v0.1.0b1' + self.assertIsNone(retag(page, "0.1.0b1")) + + def test_is_idempotent(self): + once = retag('vr-v0.1.0', "0.1.0b1") + assert once is not None + self.assertIsNone(retag(once, "0.1.0b1")) + + def test_leaves_an_unrelated_span_alone(self): + # Anchored on the closing quote of the class attribute, so a longer + # class name that merely starts with the same text is not a badge. + page = 'vr-v0.1.0' + self.assertIsNone(retag(page, "0.1.0b1")) + + +if __name__ == "__main__": + unittest.main(verbosity=2) diff --git a/.github/workflows/scripts-check.yaml b/.github/workflows/scripts-check.yaml index 5364d8d2..9dd14358 100644 --- a/.github/workflows/scripts-check.yaml +++ b/.github/workflows/scripts-check.yaml @@ -20,3 +20,6 @@ jobs: - name: Test noindex-preview.py run: python3 .github/scripts/test_noindex_preview.py + + - name: Test docs-version-badge.py + run: python3 .github/scripts/test_docs_version_badge.py From ac3bdc336d9307cffdb59991867d4d56fb05965e Mon Sep 17 00:00:00 2001 From: Josh Taillon Date: Mon, 14 Sep 2026 11:11:23 -0600 Subject: [PATCH 02/26] docs(py): build the site with great-docs Quarto has no version selector (quarto-cli#474 is open with milestone Future) and quartodoc has none, so versioned docs on the old toolchain meant hand-rolling a manifest, a dropdown, canonical tags and redirects. great-docs does it from a versions list, and builds on quartodoc rather than replacing it. It wraps Quarto, so Quarto is still what renders the site. The design notes move to pkg-py/notes because great-docs renders everything under the directory user_guide names, and the old explicit Quarto render list that kept them out is gone. The generated changelog is off: it reads GitHub Releases for the whole repository with no tag-prefix filter, so it put the R package's notes on the Python site. --- pkg-py/.gitignore | 3 + pkg-py/docs/_quarto.yml | 102 -- pkg-py/great-docs.yml | 30 + pkg-py/{docs => }/index.qmd | 0 .../notes/2026-08-20-execution-prior-art.md | 0 .../notes/2026-08-31-trace-round-trip.md | 0 pkg-py/pyproject.toml | 3 +- pkg-py/uv.lock | 1456 ++++++++++++++--- 8 files changed, 1296 insertions(+), 298 deletions(-) delete mode 100644 pkg-py/docs/_quarto.yml create mode 100644 pkg-py/great-docs.yml rename pkg-py/{docs => }/index.qmd (100%) rename pkg-py/{docs => }/notes/2026-08-20-execution-prior-art.md (100%) rename pkg-py/{docs => }/notes/2026-08-31-trace-round-trip.md (100%) diff --git a/pkg-py/.gitignore b/pkg-py/.gitignore index 21a416cc..ec4eaefe 100644 --- a/pkg-py/.gitignore +++ b/pkg-py/.gitignore @@ -17,3 +17,6 @@ dist/ /.quarto/ **/*.quarto_ipynb + +# The site great-docs assembles and renders. +/great-docs/ diff --git a/pkg-py/docs/_quarto.yml b/pkg-py/docs/_quarto.yml deleted file mode 100644 index 666cf967..00000000 --- a/pkg-py/docs/_quarto.yml +++ /dev/null @@ -1,102 +0,0 @@ -project: - type: website - # Renders in place, because Quarto warns when its output directory sits - # outside the project. The deploy workflow copies _site into docs/py. - output-dir: _site - # Explicit, so the design notes under notes/ stay out of the site. - render: - - index.qmd - - get-started.qmd - - governance.qmd - - feature-parity.qmd - - reference/*.qmd - # Copied whole: Quarto follows the tags in favicon.html, but not the - # icons site.webmanifest names inside itself. - resources: - - favicon/** - -website: - title: "commons" - site-url: https://posit-dev.github.io/commons/py/ - repo-url: https://github.com/posit-dev/commons - repo-subdir: pkg-py - navbar: - logo: assets/logos/python-logo.svg - left: - - href: get-started.qmd - text: Get started - - href: governance.qmd - text: Security and governance - - href: feature-parity.qmd - text: Feature parity - - href: reference/index.qmd - text: API Reference - right: - - text: '' - # Absolute, so it works from a pull request preview too, which builds - # this site but not the R one. - href: https://posit-dev.github.io/commons/r/ - - icon: box-seam - href: https://pypi.org/project/commons/ - aria-label: commons on PyPI - - icon: github - href: https://github.com/posit-dev/commons - sidebar: - - id: reference - contents: reference/_sidebar.yml - page-footer: - left: "Developed by Josh Taillon, Posit Software, PBC." - right: "Site built with [Quarto](https://quarto.org/)." - -format: - html: - theme: cosmo - toc: true - css: assets/styles.css - include-in-header: favicon.html - -metadata-files: - - reference/_sidebar.yml - -quartodoc: - package: commons - title: Reference - style: pkgdown - dir: reference - sidebar: reference/_sidebar.yml - render_interlinks: false - renderer: - style: markdown - table_style: description-list - sections: - - title: Main functions - desc: | - The main agent constructor, plus the building blocks for a commons agent. - contents: - - Commons - - data_source - - semantic_layer - - measure - - context_layer - - title: Supporting types - desc: | - The objects the constructors return, and the values they carry. - contents: - - DataSource - - SemanticLayer - - ContextLayer - - Measure - - Injected - - Tag - - list_tables - - title: Shiny UI and server - desc: | - Put a commons agent inside of an interactive chat app. Needs the - `shiny` extra. - package: commons.ui - contents: - - app - - server - - theme - - commons_chat_dependency - - asset_base_url diff --git a/pkg-py/great-docs.yml b/pkg-py/great-docs.yml new file mode 100644 index 00000000..48fc3d68 --- /dev/null +++ b/pkg-py/great-docs.yml @@ -0,0 +1,30 @@ +# The site is assembled by great-docs, which generates a Quarto project into +# great-docs/ and renders it. +display_name: commons +site_url: https://posit-dev.github.io/commons/py/ +repo: https://github.com/posit-dev/commons +pypi: https://pypi.org/project/commons/ + +# The narrative pages. This is a directory, and everything under it is +# rendered, which is why the design notes live in ../notes instead. +user_guide: docs + +# The generated changelog reads GitHub Releases for the whole repository with +# no tag-prefix filter, so it renders the R package's notes on this site. +changelog: + enabled: false + +# Names are relative to the package: `ui.app`, not `commons.ui.app`. A +# section-level `package:` key is accepted and then ignored. `commons.__all__` +# does not export `ui`, so the Shiny entries only appear because they are +# listed here. +reference: + - title: Main functions + desc: The main agent constructor, plus the building blocks for a commons agent. + contents: [Commons, data_source, semantic_layer, measure, context_layer] + - title: Supporting types + desc: The objects the constructors return, and the values they carry. + contents: [DataSource, SemanticLayer, ContextLayer, Measure, Injected, Tag, list_tables] + - title: Shiny UI and server + desc: "Put a commons agent inside of an interactive chat app. Needs the `shiny` extra." + contents: [ui.app, ui.server, ui.theme, ui.commons_chat_dependency, ui.asset_base_url] diff --git a/pkg-py/docs/index.qmd b/pkg-py/index.qmd similarity index 100% rename from pkg-py/docs/index.qmd rename to pkg-py/index.qmd diff --git a/pkg-py/docs/notes/2026-08-20-execution-prior-art.md b/pkg-py/notes/2026-08-20-execution-prior-art.md similarity index 100% rename from pkg-py/docs/notes/2026-08-20-execution-prior-art.md rename to pkg-py/notes/2026-08-20-execution-prior-art.md diff --git a/pkg-py/docs/notes/2026-08-31-trace-round-trip.md b/pkg-py/notes/2026-08-31-trace-round-trip.md similarity index 100% rename from pkg-py/docs/notes/2026-08-31-trace-round-trip.md rename to pkg-py/notes/2026-08-31-trace-round-trip.md diff --git a/pkg-py/pyproject.toml b/pkg-py/pyproject.toml index 8e37f953..44113beb 100644 --- a/pkg-py/pyproject.toml +++ b/pkg-py/pyproject.toml @@ -45,8 +45,7 @@ shiny = [ [dependency-groups] dev = ["pytest>=8", "pytest-asyncio", "ruff", "pyrefly", "pandas>=2", "polars>=1", "pins>=0.9", "commons[shiny]"] docs = [ - "griffe<2", - "quartodoc>=0.11.1", + "great-docs>=0.17", ] [build-system] diff --git a/pkg-py/uv.lock b/pkg-py/uv.lock index 0f1e21fb..0df47cad 100644 --- a/pkg-py/uv.lock +++ b/pkg-py/uv.lock @@ -50,6 +50,87 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/3b/00/2344469e2084fb287c2e0b57b72910309874c3245463acd6cf5e3db69324/appdirs-1.4.4-py2.py3-none-any.whl", hash = "sha256:a841dacd6b99318a741b166adb07e19ee71a274450e68237b4650ca1055ab128", size = 9566, upload-time = "2020-05-11T07:59:49.499Z" }, ] +[[package]] +name = "appnope" +version = "1.0.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/11/f7/a82489c2b6ebe32d3e2831895ae19c77861f0eadf3bb16034484d965dbb2/appnope-1.0.0.tar.gz", hash = "sha256:685db59cb6043c3c2e528adc0b3bce3a5f8d09bcf7492c6ea650d1b7421f3c49", size = 5454, upload-time = "2026-08-20T21:36:13.748Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/46/c7/6b687cb0f83d2a51017d47953f2ee430ffad6fec2a8ebc964e0718a33eb1/appnope-1.0.0-py3-none-any.whl", hash = "sha256:6fe0c04218aab65c54c4ff81638cdbf848d89f5653b74d68638a137f200dd16e", size = 4158, upload-time = "2026-08-20T21:36:12.444Z" }, +] + +[[package]] +name = "argon2-cffi" +version = "25.1.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "argon2-cffi-bindings" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/0e/89/ce5af8a7d472a67cc819d5d998aa8c82c5d860608c4db9f46f1162d7dab9/argon2_cffi-25.1.0.tar.gz", hash = "sha256:694ae5cc8a42f4c4e2bf2ca0e64e51e23a040c6a517a85074683d3959e1346c1", size = 45706, upload-time = "2025-06-03T06:55:32.073Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/4f/d3/a8b22fa575b297cd6e3e3b0155c7e25db170edf1c74783d6a31a2490b8d9/argon2_cffi-25.1.0-py3-none-any.whl", hash = "sha256:fdc8b074db390fccb6eb4a3604ae7231f219aa669a2652e0f20e16ba513d5741", size = 14657, upload-time = "2025-06-03T06:55:30.804Z" }, +] + +[[package]] +name = "argon2-cffi-bindings" +version = "26.1.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "cffi" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/0b/43/bb8b6e8708d49a5ab36781333af092d9f483b198a2710d01281204640055/argon2_cffi_bindings-26.1.0.tar.gz", hash = "sha256:63505c71542a44b68b1e38060450fb006404170da375feb31af153e7f9c6205d", size = 1790807, upload-time = "2026-08-20T07:44:22.492Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/e7/d2/0ae991f1b2181e5be49007c574710a800ad36c2978683addb3e67c474e55/argon2_cffi_bindings-26.1.0-cp310-abi3-macosx_11_0_arm64.whl", hash = "sha256:21ca0396fe5ec995dd54431c32698189666f9224810acfa752e50d2bd94d9df2", size = 25521, upload-time = "2026-08-20T07:32:43.019Z" }, + { url = "https://files.pythonhosted.org/packages/7e/e4/ad91d8297638aa2258aad4501c306aca99480dfe76ccd638173fa3702db9/argon2_cffi_bindings-26.1.0-cp310-abi3-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:78de2d65e0b9ea7ce9d1b1c3e87297b2d7305a02c266ee2a2d6910daddd7ee69", size = 27177, upload-time = "2026-08-20T07:32:44.158Z" }, + { url = "https://files.pythonhosted.org/packages/6f/86/5363df11b86d02cf3662208e7406496327649cc90eb365bf6f4e8a54a41f/argon2_cffi_bindings-26.1.0-cp310-abi3-manylinux_2_26_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:27f1821903e2ceadcb88ec2b45ef190897b7682449c772f4d9b53e42c520cf29", size = 26597, upload-time = "2026-08-20T07:32:45.172Z" }, + { url = "https://files.pythonhosted.org/packages/f4/b5/a14dcc592652347dad23ee93b278a4da5d2a25c9ed3ebd10d68eea823a4f/argon2_cffi_bindings-26.1.0-cp310-abi3-manylinux_2_34_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:d88e5f7e60f28ae0b0cc6b2f16c43e87cd642a196a86f85e0d8bb6fe016fc16d", size = 27403, upload-time = "2026-08-20T07:32:46.13Z" }, + { url = "https://files.pythonhosted.org/packages/b3/81/b4a20d4902af7f796390bf9245ff83c5217dfa7367efa1d14986956c482b/argon2_cffi_bindings-26.1.0-cp310-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:34b7d9c24a4165a2c61cc8ae11d44d48c9ce2830fb536cb7914e11fdd9962728", size = 27132, upload-time = "2026-08-20T07:32:47.13Z" }, + { url = "https://files.pythonhosted.org/packages/7e/1b/c8de358af07b1c490e0fcb863ef98e46ddb486e45567aca5a60bd68d9daa/argon2_cffi_bindings-26.1.0-cp310-abi3-musllinux_1_2_riscv64.whl", hash = "sha256:224865cbbcb7a2bd1356741dff12b0134df726b6d44bb7b500df8e303cbd9e81", size = 27588, upload-time = "2026-08-20T07:32:48.087Z" }, + { url = "https://files.pythonhosted.org/packages/48/2f/7ee62a6e79f9309f9d9982d301b22a00010adb580c05c8109b94d7b33de0/argon2_cffi_bindings-26.1.0-cp310-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:ffff613aaa9ce6236766e2fc6dc560bb5abde7a2e2416e3db1f9ae395a2b4dd4", size = 26785, upload-time = "2026-08-20T07:32:48.977Z" }, + { url = "https://files.pythonhosted.org/packages/e9/10/960d0ee93d4897741bcaf4799c697dae2d81499f66fd1ed042a7dd54c1f4/argon2_cffi_bindings-26.1.0-cp310-abi3-win32.whl", hash = "sha256:a86c069c91a747a2c4e5c51473590aeb48172fff9b2130d23729a42d98665ecb", size = 23898, upload-time = "2026-08-20T07:32:50.114Z" }, + { url = "https://files.pythonhosted.org/packages/6d/3a/0cc14a05810e6add9bce5e87693334baa2222de5f647fa31781885b6573f/argon2_cffi_bindings-26.1.0-cp310-abi3-win_amd64.whl", hash = "sha256:2c36ff87b5dfaa477d0bd51e9d7f6abdae7c8955d2983c97419085d842154b3e", size = 25730, upload-time = "2026-08-20T07:32:51.091Z" }, + { url = "https://files.pythonhosted.org/packages/4e/db/d83cf2af140547f0b9cdaece05b2dc2dcbf991be4667331d073eff771435/argon2_cffi_bindings-26.1.0-cp310-abi3-win_arm64.whl", hash = "sha256:f9c4420a7a864fe1b86ce35befc95b8e39fb852493b81cf798671ddc265de638", size = 24478, upload-time = "2026-08-20T07:32:52.111Z" }, + { url = "https://files.pythonhosted.org/packages/bb/5f/f652055e18d2627e2eed94c7f31a792127cfe38df786635395d742321674/argon2_cffi_bindings-26.1.0-cp313-cp313-pyemscripten_2025_0_wasm32.whl", hash = "sha256:af11ac37a7c53dc16cb7950a6190851b0870fe218b6c60c0bb7ac355234e3083", size = 15434, upload-time = "2026-08-20T07:32:53.143Z" }, + { url = "https://files.pythonhosted.org/packages/76/38/de696045960f5b846d428c0fb6c130ed3da87aac2af209b05c193815404c/argon2_cffi_bindings-26.1.0-cp314-cp314-pyemscripten_2026_0_wasm32.whl", hash = "sha256:db0fcd827ca61622a01b220aadfbece01939acf53888f2cb98cd93e9b1e2c97e", size = 15449, upload-time = "2026-08-20T07:32:54.075Z" }, + { url = "https://files.pythonhosted.org/packages/91/0a/c25af768f6b75a5a71e31207f87c540656b2808c015260444a22763221ad/argon2_cffi_bindings-26.1.0-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:28524438cd3e723f25412f63d4fd516ff5bae9ae5aa56acbe2a1404398a0cf31", size = 25683, upload-time = "2026-08-20T07:32:55.05Z" }, + { url = "https://files.pythonhosted.org/packages/a8/7e/be212c751ab0bcea7f646615f933bf262e8e50b3f7bef32f861d0a2d066b/argon2_cffi_bindings-26.1.0-cp314-cp314t-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:ac82fc756a446b6ccd7139ce70efa9d8bbe541e7ad579a12dcb52764b7175c5f", size = 27311, upload-time = "2026-08-20T07:32:56.166Z" }, + { url = "https://files.pythonhosted.org/packages/a6/ee/f84b28e4afd13d3cac36c1d8fa8c239d2dc2c51cd978d02ee5d5ad98d9bb/argon2_cffi_bindings-26.1.0-cp314-cp314t-manylinux_2_26_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:6a4e68eed961a8de6928d1c17ff3dc2a547e0e923c17f8f1cd79fb7bc9502f98", size = 26771, upload-time = "2026-08-20T07:32:57.206Z" }, + { url = "https://files.pythonhosted.org/packages/21/c3/95c07a023691ecd529da9cb6a8f0779e13ebc1bdfaa86d145fdc1c6e7e79/argon2_cffi_bindings-26.1.0-cp314-cp314t-manylinux_2_34_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:151dfaad9de753f4af2a7854e707e4784f2acc434340ade64239c5b104b2d605", size = 27568, upload-time = "2026-08-20T07:32:58.361Z" }, + { url = "https://files.pythonhosted.org/packages/e6/31/3a18e31406d8694b4d6a31573c3e572fff6bed318bb744453eb653766d22/argon2_cffi_bindings-26.1.0-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:061a6919145bbf282ebf1f9c59d3135d4833c25313c8595c0d68cf7712ddfce2", size = 27280, upload-time = "2026-08-20T07:32:59.343Z" }, + { url = "https://files.pythonhosted.org/packages/0b/39/d4be4577e178b2397aa5b5575c8a309bf0da2afe05fe0c72c8f398662d63/argon2_cffi_bindings-26.1.0-cp314-cp314t-musllinux_1_2_riscv64.whl", hash = "sha256:62ff20cd130c956c7c9144d5fe35228f98b51c579b2439e988b27ef93e16c02a", size = 27776, upload-time = "2026-08-20T07:33:00.325Z" }, + { url = "https://files.pythonhosted.org/packages/71/47/78f4dd96f7411339f723b96fe24039c1bd5835102b8a5ba71ac4ec712ac7/argon2_cffi_bindings-26.1.0-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:19423e5d7ac1cc354baab59eaabf18db2ec04ef6593b5abe5a34f323c4a8f87a", size = 26932, upload-time = "2026-08-20T07:33:01.272Z" }, + { url = "https://files.pythonhosted.org/packages/3b/cd/96bfd37434cc0a848a9066c291d84b28846c4c9ea289ed9866b1164d622b/argon2_cffi_bindings-26.1.0-cp314-cp314t-win32.whl", hash = "sha256:4f84cdd868978d7b7350a566c254042d44216d9e37f241f3a6d3b1dfebeede35", size = 24878, upload-time = "2026-08-20T07:33:02.189Z" }, + { url = "https://files.pythonhosted.org/packages/f1/42/d8b6810abd9b1bd2f47ebbccf460da59c9f32e94888bea4f7b137d998797/argon2_cffi_bindings-26.1.0-cp314-cp314t-win_amd64.whl", hash = "sha256:2b741888c93147444fdfc851abd81cc207f37f7f7da42062a00deb3888e57da8", size = 26656, upload-time = "2026-08-20T07:33:03.222Z" }, + { url = "https://files.pythonhosted.org/packages/a9/d1/095d95eaf2ed1d9f77268cf3291bde148c6cd56121f8db2c74c1ba618a0e/argon2_cffi_bindings-26.1.0-cp314-cp314t-win_arm64.whl", hash = "sha256:6ab674f668d5962a3a4136ae0812519b0f1586874263723a32181d60d64137e1", size = 25378, upload-time = "2026-08-20T07:33:04.332Z" }, + { url = "https://files.pythonhosted.org/packages/66/cb/214092c39c4dbcb72cf98b12234ddac2221f8fe2c0acf29c6a70fa83be53/argon2_cffi_bindings-26.1.0-cp315-cp315t-macosx_11_0_arm64.whl", hash = "sha256:1d98e33bd8bd67d7206c124e200bf2229c4cfa8c9c19f7b44a897f0fc71837eb", size = 25683, upload-time = "2026-08-20T07:33:05.337Z" }, + { url = "https://files.pythonhosted.org/packages/83/e5/02015b83e9b05ccb85ff2ced424cf6e83a12d3810bc7f66d679a92b69ffb/argon2_cffi_bindings-26.1.0-cp315-cp315t-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:ccaf0a46cbb380f1fd102a874e32aa629fd3cb0c0e94f4943fa1f6d5edc5dac6", size = 27310, upload-time = "2026-08-20T07:33:06.344Z" }, + { url = "https://files.pythonhosted.org/packages/c3/4a/85e612787d0796878b3b4f6bd53dcd5484b6fe7b64cc6fc7b6e6a04cf835/argon2_cffi_bindings-26.1.0-cp315-cp315t-manylinux_2_26_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:f0c3103fcff20183e593459cfea6e012281c0e76ae3ed8b5565ad1b92eac3990", size = 26771, upload-time = "2026-08-20T07:33:07.429Z" }, + { url = "https://files.pythonhosted.org/packages/f6/84/ccb003b6f9969820e87656398f4d49c857def71a85ca1588a0e809afd7ce/argon2_cffi_bindings-26.1.0-cp315-cp315t-manylinux_2_34_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:c49e853a3bef9dd10329f31f702e7fa9b5c58229ff9c2ff6d069efaf09177c08", size = 27569, upload-time = "2026-08-20T07:33:08.598Z" }, + { url = "https://files.pythonhosted.org/packages/88/07/c26b76debf0998ee08fbe947ab2058ac5de37d4b9d46b06c17abaa6c4ce9/argon2_cffi_bindings-26.1.0-cp315-cp315t-musllinux_1_2_aarch64.whl", hash = "sha256:6376d4b3aca039375ca8bf92f770da0ec424a1ce3a37077a8d3c557411aa56ca", size = 27279, upload-time = "2026-08-20T07:33:09.518Z" }, + { url = "https://files.pythonhosted.org/packages/ee/0d/ead6ddc029f91bc9b9390686dad3c808ab08100d348f6266b5f93f8970ee/argon2_cffi_bindings-26.1.0-cp315-cp315t-musllinux_1_2_riscv64.whl", hash = "sha256:9bacedc04b0402837586a17f0919e3dfdd95291f441f1f56bd80ec274c2840a1", size = 27774, upload-time = "2026-08-20T07:33:10.728Z" }, + { url = "https://files.pythonhosted.org/packages/7d/47/c108530d9eb86036b78d3af4de28b83b4a2d9a70512bd10ff8e59966aab4/argon2_cffi_bindings-26.1.0-cp315-cp315t-musllinux_1_2_x86_64.whl", hash = "sha256:76ae29acace5d33355344612844d588e19deaaba4639d8bb01601e4b1418ef36", size = 26933, upload-time = "2026-08-20T07:33:11.661Z" }, + { url = "https://files.pythonhosted.org/packages/a9/02/0bfc59e781c89acf64c31c388aade9d9d1c1ea38aa1ba1292fe07f607fe9/argon2_cffi_bindings-26.1.0-cp315-cp315t-win32.whl", hash = "sha256:df612391feca41c44d20118f3b88d1b86419465cd1f5496859f715ca60ec2210", size = 24875, upload-time = "2026-08-20T07:33:12.616Z" }, + { url = "https://files.pythonhosted.org/packages/61/c7/c3e46068cddffccecb8ad94d71135e9bf62bbc789589e7dfadc7c6f59214/argon2_cffi_bindings-26.1.0-cp315-cp315t-win_amd64.whl", hash = "sha256:1a0a29ed86960e44eaace7e081bdfab4f08b012fd96ec8edba71e2ad020939e4", size = 26655, upload-time = "2026-08-20T07:33:13.521Z" }, + { url = "https://files.pythonhosted.org/packages/f4/ca/18b9c8c45fecf34b9100ec6d7946057f14a158f2eaa20ea123a3e82351cb/argon2_cffi_bindings-26.1.0-cp315-cp315t-win_arm64.whl", hash = "sha256:d157ddfab1e8b21f2f1dedda9c09645d98b5ed0b667b0626be600a345d426440", size = 25376, upload-time = "2026-08-20T07:33:14.491Z" }, + { url = "https://files.pythonhosted.org/packages/a0/b9/97f0370f99611b14efd384918613dd5cbda75f28d9bb1b677aacfeaa17df/argon2_cffi_bindings-26.1.0-pp311-pypy311_pp73-macosx_11_0_arm64.whl", hash = "sha256:19b562b1de4b9052ef1214a2821c44b6e6f22945daa102c32ae4eff929d8b6d8", size = 23055, upload-time = "2026-08-20T07:33:19.716Z" }, + { url = "https://files.pythonhosted.org/packages/ae/70/7eb3fe7bf00103cbbb569c51aef150661f22b734a782673a600ff0f52309/argon2_cffi_bindings-26.1.0-pp311-pypy311_pp73-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:49d525938467d52c923a890153c99087c9d5a937d1f6b585dbdba34ec82e397a", size = 24869, upload-time = "2026-08-20T07:33:20.671Z" }, + { url = "https://files.pythonhosted.org/packages/5b/4b/9d5919c6cb1f15df7406af0f99b048bd93936f112e3e8f4c8077bc2a9110/argon2_cffi_bindings-26.1.0-pp311-pypy311_pp73-manylinux_2_26_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:1b0bcac4d490a237e18cf91f57352920c29f77f2fa39efd0813fb81298bf17ba", size = 24216, upload-time = "2026-08-20T07:33:21.653Z" }, + { url = "https://files.pythonhosted.org/packages/a3/34/32109943bace7729233cc4ee78530baa306d8cc3c6501a64ba8cb3b58129/argon2_cffi_bindings-26.1.0-pp311-pypy311_pp73-win_amd64.whl", hash = "sha256:0cc40f7b4050bb93eb67de95d2d759322fc7ce4930b9d645581ecf4913ec651e", size = 23584, upload-time = "2026-08-20T07:33:22.613Z" }, +] + +[[package]] +name = "arrow" +version = "1.4.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "python-dateutil" }, + { name = "tzdata" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/b9/33/032cdc44182491aa708d06a68b62434140d8c50820a087fac7af37703357/arrow-1.4.0.tar.gz", hash = "sha256:ed0cc050e98001b8779e84d461b0098c4ac597e88704a655582b21d116e526d7", size = 152931, upload-time = "2025-10-18T17:46:46.761Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/ed/c9/d7977eaacb9df673210491da99e6a247e93df98c715fc43fd136ce1d3d33/arrow-1.4.0-py3-none-any.whl", hash = "sha256:749f0769958ebdc79c173ff0b0670d59051a535fa26e8eba02953dc19eb43205", size = 68797, upload-time = "2025-10-18T17:46:45.663Z" }, +] + [[package]] name = "asgiref" version = "3.12.1" @@ -59,6 +140,24 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/c0/1b/54f4ad77cd8a584fa70746c47df988e002cf1ee1eba43364d46f87803647/asgiref-3.12.1-py3-none-any.whl", hash = "sha256:fe386d1c2bff7259ea95929266d12a8cf9a8b5a1c2598402967d8792e7a7c094", size = 25478, upload-time = "2026-07-14T09:56:16.926Z" }, ] +[[package]] +name = "asttokens" +version = "3.0.2" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/25/1e/faf0f247f6f881b98fc4d6d07e14085cb89d13665084e6d6ac1dc2c03d0b/asttokens-3.0.2.tar.gz", hash = "sha256:3ecdbd8f2cc195f53ccada3a613538bb5f9ef6f6869129f13e03c30a677b8fe2", size = 63136, upload-time = "2026-07-12T03:31:49.084Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/d4/2b/04b8a15f3a1c77bc79ddf5c73875327f34b4fa75982df2b76e45e402d364/asttokens-3.0.2-py3-none-any.whl", hash = "sha256:9da13157f5b28becde0bd374fc677dcd3c290614264eff096f167c469cd9f933", size = 28702, upload-time = "2026-07-12T03:31:47.542Z" }, +] + +[[package]] +name = "async-lru" +version = "2.3.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/e8/1f/989ecfef8e64109a489fff357450cb73fa73a865a92bd8c272170a6922c2/async_lru-2.3.0.tar.gz", hash = "sha256:89bdb258a0140d7313cf8f4031d816a042202faa61d0ab310a0a538baa1c24b6", size = 16332, upload-time = "2026-03-19T01:04:32.413Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/e5/e2/c2e3abf398f80732e58b03be77bde9022550d221dd8781bf586bd4d97cc1/async_lru-2.3.0-py3-none-any.whl", hash = "sha256:eea27b01841909316f2cc739807acea1c623df2be8c5cfad7583286397bb8315", size = 8403, upload-time = "2026-03-19T01:04:30.883Z" }, +] + [[package]] name = "attrs" version = "26.1.0" @@ -69,12 +168,12 @@ wheels = [ ] [[package]] -name = "beartype" -version = "0.22.9" +name = "babel" +version = "2.18.0" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/c7/94/1009e248bbfbab11397abca7193bea6626806be9a327d399810d523a07cb/beartype-0.22.9.tar.gz", hash = "sha256:8f82b54aa723a2848a56008d18875f91c1db02c32ef6a62319a002e3e25a975f", size = 1608866, upload-time = "2025-12-13T06:50:30.72Z" } +sdist = { url = "https://files.pythonhosted.org/packages/7d/b2/51899539b6ceeeb420d40ed3cd4b7a40519404f9baf3d4ac99dc413a834b/babel-2.18.0.tar.gz", hash = "sha256:b80b99a14bd085fcacfa15c9165f651fbb3406e66cc603abf11c5750937c992d", size = 9959554, upload-time = "2026-02-01T12:30:56.078Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/71/cc/18245721fa7747065ab478316c7fea7c74777d07f37ae60db2e84f8172e8/beartype-0.22.9-py3-none-any.whl", hash = "sha256:d16c9bbc61ea14637596c5f6fbff2ee99cbe3573e46a716401734ef50c3060c2", size = 1333658, upload-time = "2025-12-13T06:50:28.266Z" }, + { url = "https://files.pythonhosted.org/packages/77/f5/21d2de20e8b8b0408f0681956ca2c69f1320a3848ac50e6e7f39c6159675/babel-2.18.0-py3-none-any.whl", hash = "sha256:e2b422b277c2b9a9630c1d7903c2a00d0830c409c59ac8cae9081c92f1aeba35", size = 10196845, upload-time = "2026-02-01T12:30:53.445Z" }, ] [[package]] @@ -91,40 +190,20 @@ wheels = [ ] [[package]] -name = "black" -version = "26.5.1" +name = "bleach" +version = "6.4.0" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "click" }, - { name = "mypy-extensions" }, - { name = "packaging" }, - { name = "pathspec" }, - { name = "platformdirs" }, - { name = "pytokens" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/c0/37/5628dd55bf2b34257fc7603f0fe97c40e3aaf24265f416a9c85c95ca1436/black-26.5.1.tar.gz", hash = "sha256:dd321f668053961824bcc1be1cc1df748b2d7e4fa28086b08331e577b0100a73", size = 679439, upload-time = "2026-05-18T16:53:36.107Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/4b/96/3c3e09f09f44a37aac36b178a279cd19aa7001bd796187a7b162a294c81f/black-26.5.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:96ae2c733b2aabdd9986e2c5df628ff3473676cd1c5faded1ff496cf6d74083c", size = 1970639, upload-time = "2026-05-18T17:05:11.461Z" }, - { url = "https://files.pythonhosted.org/packages/83/ea/5ad117b9ee3ecd933c712bcbae610006e5b7cc9f41c526cd7ed3b6c4124c/black-26.5.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:0e48b87e03bf109288e55cfceadcfa15ff5470aca2851a851950ed2926f450d7", size = 1792130, upload-time = "2026-05-18T17:05:12.983Z" }, - { url = "https://files.pythonhosted.org/packages/06/3a/7c448bc623fcdfa96672531beb5a616ea5e64f6975955254d7731ffb0ad9/black-26.5.1-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:5119fa92ae61f786e8c3662fd60aece1d0a2dd5cca5d0c79417a95e7a4272a59", size = 1846134, upload-time = "2026-05-18T17:05:14.506Z" }, - { url = "https://files.pythonhosted.org/packages/a1/5b/0b39b3a5917f0657ac014ad2edb58c139553a478adfe7f817abf1622ff6e/black-26.5.1-cp311-cp311-win_amd64.whl", hash = "sha256:30d3c14661f2792e9142cce3eeeb1cbc175b3eb5f733be0c8eeb99651e52b0c3", size = 1478883, upload-time = "2026-05-18T17:05:16.542Z" }, - { url = "https://files.pythonhosted.org/packages/4c/48/dc222692e0f95030db1bbfb6c857e76858bad09058221ea7aae815255327/black-26.5.1-cp311-cp311-win_arm64.whl", hash = "sha256:1ef92b76f7733f282fd096ea406200b5a286c42947412b0eaff3a74e3616cefe", size = 1277776, upload-time = "2026-05-18T17:05:18.029Z" }, - { url = "https://files.pythonhosted.org/packages/24/99/7744b906703228264ef73bdd534df88ec1ef3de45c4e78f6d31b9e32d0c9/black-26.5.1-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:4ad6fa01f941920f54f2bbb35f3df7673428a0ef98a0b0840c2eaef3b110efa8", size = 2012518, upload-time = "2026-05-18T17:05:20.108Z" }, - { url = "https://files.pythonhosted.org/packages/b7/c0/c5a3b1636dfd09c42534f2b3cf33506814f6d3e066fb0879ffa16c1ae860/black-26.5.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:3915f256e75a2d7cf88d8953d37f780455dc586cc72dee059c528fe77f581217", size = 1816016, upload-time = "2026-05-18T17:05:21.84Z" }, - { url = "https://files.pythonhosted.org/packages/1f/0e/36044316b65ca471d3bb6d3703fd06fb50c6b727c3562f6a5a3153634f88/black-26.5.1-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:9d98d4137277c75dfb898ec8d846c4fd68ba1e9cf77f95e2865c203dc18f4c3d", size = 1884150, upload-time = "2026-05-18T17:05:23.546Z" }, - { url = "https://files.pythonhosted.org/packages/b3/33/dafc5808c2af43672912111d7c3354af1615f7e2be3bed7a878461abbe4d/black-26.5.1-cp312-cp312-win_amd64.whl", hash = "sha256:a1dca32d9f1784af512a13410ec204c6f7f0aa9797a111c42e1c03449821c264", size = 1486825, upload-time = "2026-05-18T17:05:25.004Z" }, - { url = "https://files.pythonhosted.org/packages/82/14/b965ee6ad2a311f28bdbf692def3ee9848d2ae289dab28b27657fcee3e78/black-26.5.1-cp312-cp312-win_arm64.whl", hash = "sha256:1037d5ac7b7b310b2632ad867ec8d0e4c4819dcdb0b820f63135da746a24e418", size = 1288646, upload-time = "2026-05-18T17:05:26.477Z" }, - { url = "https://files.pythonhosted.org/packages/3f/5c/c384363980e11e25ca6b93205949bb331fbf35f4e0dbec376dfa6326cec8/black-26.5.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:2b36cf2ddf5566e205f6535f782a62194a184d33e175b64ae8c40b1737522be3", size = 2009020, upload-time = "2026-05-18T17:05:28.132Z" }, - { url = "https://files.pythonhosted.org/packages/0b/df/9f31c5e0babbfed77d505fc5d120beb98b21b33feaeded3924ea941fe360/black-26.5.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:1f7ea64ebfa01b50f693508fc39f875e264446d3b097088f84f203b9d09618a0", size = 1813335, upload-time = "2026-05-18T17:05:31.266Z" }, - { url = "https://files.pythonhosted.org/packages/fb/24/8e7b9a2fa61b0afd82209efe937557d180a1fa055bd7f6161eb9defc3719/black-26.5.1-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:ecb3e624844c798144e9bd986954e0adc81d8911a1f30f375e1252fe26e8c294", size = 1881614, upload-time = "2026-05-18T17:05:32.718Z" }, - { url = "https://files.pythonhosted.org/packages/49/ad/b4e0d9365ba8ac34f6bbab62a4b1b2dd5d618fac3fa1b8db968c844201b5/black-26.5.1-cp313-cp313-win_amd64.whl", hash = "sha256:e1a26503279b6b310669fb0b219c39e4820b77e8189fe80f522bb511f247db0a", size = 1488925, upload-time = "2026-05-18T17:05:34.259Z" }, - { url = "https://files.pythonhosted.org/packages/a1/4b/652b859bf5df88a751c30451b09338f7fd26a77d1271c666992f836b7711/black-26.5.1-cp313-cp313-win_arm64.whl", hash = "sha256:5c34b25da232ead53a6f335b76dbea124f4d152ad568b9080d6f944bc2b34b52", size = 1289883, upload-time = "2026-05-18T17:05:36.019Z" }, - { url = "https://files.pythonhosted.org/packages/a6/16/a8da8eb208c51c7f4ce74609a45d0dcc6d8a2141e45e81ee5289d1bb0d59/black-26.5.1-cp314-cp314-macosx_10_15_x86_64.whl", hash = "sha256:e88976690a64b0af98312ca958415849cb42423423c5f2ee74af4b49a97a2168", size = 2004800, upload-time = "2026-05-18T17:05:38.182Z" }, - { url = "https://files.pythonhosted.org/packages/11/8a/a479296a19e383b70a725882a6cf3d786540601ff03cabbaaf1cce864c5a/black-26.5.1-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:32d5ea7f6c8bdfa6e648326ebca1f02b0764e2a029edc6f8dce2627e19d468c3", size = 1815576, upload-time = "2026-05-18T17:05:40.309Z" }, - { url = "https://files.pythonhosted.org/packages/81/6b/cfaf3d39f25132c156a068f6b805576c9103a84086019507c70e1911ee7d/black-26.5.1-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:ea8d16dc41655aa113cd64665e7219446cd7e4ff2248d7178eaa905190c86b18", size = 1877927, upload-time = "2026-05-18T17:05:42.463Z" }, - { url = "https://files.pythonhosted.org/packages/66/76/302e313964bcff7e28df329d39f84f5270095730d85ff0acc260610a0d82/black-26.5.1-cp314-cp314-win_amd64.whl", hash = "sha256:577f21094ea469ef92ec1adaf2c9441a226d2144d01a5be2fa823cecf6543e50", size = 1511860, upload-time = "2026-05-18T17:05:43.943Z" }, - { url = "https://files.pythonhosted.org/packages/27/4e/a3827e35e0e567f9f9ee59e2a0ab979267dca98718f25547ca8c6733afd4/black-26.5.1-cp314-cp314-win_arm64.whl", hash = "sha256:ed1a20af114c301a0269bf01163d51dbef72737fd65f850001e7cbe7f3c7abae", size = 1316632, upload-time = "2026-05-18T17:05:45.521Z" }, - { url = "https://files.pythonhosted.org/packages/94/51/f975cae76d44274cc2868dc9040ac5d58d464784610234455b4e7b19c6ef/black-26.5.1-py3-none-any.whl", hash = "sha256:4ed7f7da04046d2e488437170797d3b4a4ad83906683bcb7dfc68b673bbce5e2", size = 213693, upload-time = "2026-05-18T16:53:33.964Z" }, + { name = "webencodings" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/48/3c/e12ac860709702bd5ebeb9b56a4fe334f1001246ee1b8f2b7ee28912df7d/bleach-6.4.0.tar.gz", hash = "sha256:4202482733d85cedd04e59fcb2f89f4e4c7c385a78d3c3c23c30446843a37452", size = 204857, upload-time = "2026-06-05T13:01:13.734Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/58/9d/40b6267367182187139a4000b82a3b287d84d745bccd808e75d916920e9d/bleach-6.4.0-py3-none-any.whl", hash = "sha256:4b6b6a54fff2e69a3dde9d21cc6301220bee3c3cb792187d11403fd795031081", size = 165109, upload-time = "2026-06-05T13:01:12.504Z" }, +] + +[package.optional-dependencies] +css = [ + { name = "tinycss2" }, ] [[package]] @@ -136,6 +215,104 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/0b/a7/71ac2cff56fec219ed242bb11b8efb69fcc4bec75db06fb7bfe35de520e6/certifi-2026.7.22-py3-none-any.whl", hash = "sha256:62f22742b58a1a33014a2b6b706588a8d7e2a88ae7bd1a6ebe8c992928483775", size = 136983, upload-time = "2026-07-22T03:35:11.276Z" }, ] +[[package]] +name = "cffi" +version = "2.1.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "pycparser", marker = "implementation_name != 'PyPy'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/9e/ef/008a1939e372c06329a3fce4279c02f328488f3526744906eeec3da7ad5f/cffi-2.1.1.tar.gz", hash = "sha256:dd31f52ea1086513bb9df30f8fcee9b8918323ae067a3d5b78bc826a000712be", size = 530807, upload-time = "2026-08-03T21:21:18.939Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/70/d2/16d99a0c4948febc0ebd133a13b2f688ff7f8cb04da971e1128872ce0c03/cffi-2.1.1-cp311-cp311-macosx_10_15_x86_64.whl", hash = "sha256:c8d2c9fd1f2d16f780d15127abb050d13d1a76c03a4bd87d7e4980e45e511e12", size = 183838, upload-time = "2026-08-03T21:19:29.637Z" }, + { url = "https://files.pythonhosted.org/packages/cd/95/31b535a9f0220ae9f357de4a08d57ce89cb417653c2fd9f075f50822a388/cffi-2.1.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:398aff33cee2767e3e781d2554c54bd0dff386bb437581e0d8011fde1a942ec1", size = 184168, upload-time = "2026-08-03T21:19:30.764Z" }, + { url = "https://files.pythonhosted.org/packages/ad/5a/4707a0dc1f203f5dde5a907b0d4e3c25d71120241048bd5bc6f1bb9d4e71/cffi-2.1.1-cp311-cp311-manylinux1_i686.manylinux2014_i686.manylinux_2_17_i686.manylinux_2_5_i686.whl", hash = "sha256:154852545011f779917b11c78db2358d095da62a9a172b78ad0a583ee5adc0d0", size = 211805, upload-time = "2026-08-03T21:19:31.867Z" }, + { url = "https://files.pythonhosted.org/packages/ad/66/c19feabb28485b6e0bbaaafa90837a1ef5d302e90f2178bd33f17a49879b/cffi-2.1.1-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:3311ed60d36f83378794e1009ac6258bafbf81f7888b4caa7b35a521e3f95813", size = 218716, upload-time = "2026-08-03T21:19:32.896Z" }, + { url = "https://files.pythonhosted.org/packages/a7/92/500760486c8baab49a7a8a58ba7fc3355ec3974b454b8a09e528efde9e1d/cffi-2.1.1-cp311-cp311-manylinux2014_ppc64le.manylinux_2_17_ppc64le.whl", hash = "sha256:6e192623c49c94421616a5778fba35cf0d5a8d000650c1967ef4448ee5cdd990", size = 205569, upload-time = "2026-08-03T21:19:34.142Z" }, + { url = "https://files.pythonhosted.org/packages/a5/a7/a67c733254d6e7373f7822f8082d8d6beade791e0cf12a7611f376fa61c7/cffi-2.1.1-cp311-cp311-manylinux2014_s390x.manylinux_2_17_s390x.whl", hash = "sha256:a6e721d4b0e45d5b65e87534470e67b18dcd092c83f68fba09f152b9cbc061af", size = 204907, upload-time = "2026-08-03T21:19:35.174Z" }, + { url = "https://files.pythonhosted.org/packages/f7/a4/4399daaf8f7dfee9d7c3327fdb0426ee041cc63edc358b93911ceb2bfc7a/cffi-2.1.1-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:34e261f78cb6ceaaa36f42f2613f4380d94d9c759a9c73c769ee6e0247364632", size = 217807, upload-time = "2026-08-03T21:19:36.286Z" }, + { url = "https://files.pythonhosted.org/packages/28/f7/dabe6da2466ecbd82dc62e7342dc6b1065dad990c06f00f0ede9ebf2a0ed/cffi-2.1.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:7225e4514edb64eb6740324353e0da0711954fd8d7da4576755b1c6e09b697cd", size = 221252, upload-time = "2026-08-03T21:19:37.416Z" }, + { url = "https://files.pythonhosted.org/packages/ce/87/616202d8e51342c07d2534c510111c4cc37201775ce8f60802c9335d1edd/cffi-2.1.1-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:df913725b79db7bcf03448f36b7bf8815363417d5b58deecf9305e3e30f0f21a", size = 214214, upload-time = "2026-08-03T21:19:38.507Z" }, + { url = "https://files.pythonhosted.org/packages/b4/c6/ab025d75d2c26c19b087c0124e75ee31cb65032f4fe345d356d8c507ab97/cffi-2.1.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:f5cfbc5fe74540d335175b656c725d74d90e3730c626d92575eea35029d9afaa", size = 219408, upload-time = "2026-08-03T21:19:39.809Z" }, + { url = "https://files.pythonhosted.org/packages/db/e2/7e8109f65445bdc673a7b54f02c677de462db75674220fd1335efc8eb598/cffi-2.1.1-cp311-cp311-win32.whl", hash = "sha256:f8ec5e643a9a937f64e1999eb9f75d072263751912dc5cd06d3c85f8f44be7c3", size = 174470, upload-time = "2026-08-03T21:19:41.246Z" }, + { url = "https://files.pythonhosted.org/packages/73/c0/77ba02423c2f7d7091143c45cd49e0e6575c4c1967394bb542bd923a9b74/cffi-2.1.1-cp311-cp311-win_amd64.whl", hash = "sha256:42f6930c31dc7f50732c9ae793c2786c7b6b044195967bbdde40bb9be81c4cc0", size = 185096, upload-time = "2026-08-03T21:19:42.615Z" }, + { url = "https://files.pythonhosted.org/packages/7c/47/9f1f85f9672ceda4984dc6c4f8824e8558992a2972c3d3c81fb8eb28d4ba/cffi-2.1.1-cp311-cp311-win_arm64.whl", hash = "sha256:c7659f22557c5a0bc4855cd635f55edec690cc008a40768527762cb9fb263455", size = 179941, upload-time = "2026-08-03T21:19:43.747Z" }, + { url = "https://files.pythonhosted.org/packages/10/69/43965eccfdead3b9220015fd1320e117be8c6ed01a62ffab76eeb752f5d5/cffi-2.1.1-cp312-cp312-macosx_10_15_x86_64.whl", hash = "sha256:c8c69575568085ba0b1b10c0249d779a214aea6f6522e949a0fc9fb0fcb449d0", size = 184821, upload-time = "2026-08-03T21:19:44.887Z" }, + { url = "https://files.pythonhosted.org/packages/54/7d/16e5a096677b5e313ca80cd5e5170efa3ea44624a82bb111925522da64b1/cffi-2.1.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:f81b3b8f3d4e343550fa4baa0e479bba9f2d29ce9c2e9b51d1ce1718d7442fcf", size = 184719, upload-time = "2026-08-03T21:19:46.129Z" }, + { url = "https://files.pythonhosted.org/packages/56/e6/8941622732edec876dd17d0453dce07317ae96db34f2ec1436c9d3785986/cffi-2.1.1-cp312-cp312-manylinux1_i686.manylinux2014_i686.manylinux_2_17_i686.manylinux_2_5_i686.whl", hash = "sha256:811bd1e21d32de12efca32393a0ab3f5133b54fce9bd44b8bd77ab07da14bf6a", size = 214799, upload-time = "2026-08-03T21:19:47.218Z" }, + { url = "https://files.pythonhosted.org/packages/44/de/f98430906df1545ffde0d543dd124a7a439bc2cd32b36b9c53f805df7333/cffi-2.1.1-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:68e62fe11f30d5ca8289242866f0a5291402d8529ca2178ab8afc5c9694ae890", size = 222389, upload-time = "2026-08-03T21:19:48.331Z" }, + { url = "https://files.pythonhosted.org/packages/6a/5b/717f1526b9957b34456313c31645c5b82b8fb5c3fe9e4752999be7128bfc/cffi-2.1.1-cp312-cp312-manylinux2014_ppc64le.manylinux_2_17_ppc64le.whl", hash = "sha256:4a7c934f7360e8cd64fe9efadcbd10c7c6364f531e432b9a4bf5ccbc9e0e8b50", size = 210249, upload-time = "2026-08-03T21:19:49.543Z" }, + { url = "https://files.pythonhosted.org/packages/64/b3/f8aa4f3e34986c7e4ec45072d1b1b9dd295b6b18007b45518d79726dd725/cffi-2.1.1-cp312-cp312-manylinux2014_s390x.manylinux_2_17_s390x.whl", hash = "sha256:3143d81e29e1e20a9ce10901ec369012947876596f75a222235965f2b7ae832e", size = 208775, upload-time = "2026-08-03T21:19:50.918Z" }, + { url = "https://files.pythonhosted.org/packages/b1/db/dceb9dd5b231e1da801793f8acc9f3c52a7e1afe40bb1aae37e02b0faad5/cffi-2.1.1-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:c1453022f490d2459a11819d83ad1d586e9ff65a12ac3e705ffebd46d3685dcf", size = 221822, upload-time = "2026-08-03T21:19:52.054Z" }, + { url = "https://files.pythonhosted.org/packages/a0/d2/6cd24ae3be000a634109c247d1475d62e5616d0dc78c82770942ec384248/cffi-2.1.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:208f941bb9d18e768138677f0a6d2ce01f590df56043dda1df1535ac57c88517", size = 225232, upload-time = "2026-08-03T21:19:53.109Z" }, + { url = "https://files.pythonhosted.org/packages/cb/52/3fa190537004dd7f0ab860a6dc7c0175b8667f68d1e618a46f5498d30250/cffi-2.1.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:210019b6c7cf07f081b4c54635c8cf744377001350e29cc0f81c4377b4797735", size = 223597, upload-time = "2026-08-03T21:19:54.515Z" }, + { url = "https://files.pythonhosted.org/packages/80/fb/0bb75b7039588c074b37ae99f40d9bfddf990ecb2fbc346ebccd2e56b9be/cffi-2.1.1-cp312-cp312-win32.whl", hash = "sha256:046bfc24911b37851ee1b51aab8bffe713d89c68c6a057b09484ce9fd5f69b4e", size = 175292, upload-time = "2026-08-03T21:19:55.566Z" }, + { url = "https://files.pythonhosted.org/packages/d9/79/615cc094e2fb508cade7de88d3b4f6c4ec2bab695c97bce9153dc65aadf5/cffi-2.1.1-cp312-cp312-win_amd64.whl", hash = "sha256:f53e442b08449d42821fa4a4fba000095af9f62742a500f978a9f557ec44339a", size = 185919, upload-time = "2026-08-03T21:19:56.89Z" }, + { url = "https://files.pythonhosted.org/packages/70/c6/d0ea84713fe46b243a436a18fcd47d639732747e21635c8a27191b06dc30/cffi-2.1.1-cp312-cp312-win_arm64.whl", hash = "sha256:7bde5e4cc5c10140859842b9d383af292b22639a4dffb725314baf45968cef80", size = 180093, upload-time = "2026-08-03T21:19:58.155Z" }, + { url = "https://files.pythonhosted.org/packages/9d/f4/035513d4117049066b4779dc3b7c0c0fdad175fa13731c9f4003f1cd1478/cffi-2.1.1-cp313-cp313-ios_13_0_arm64_iphoneos.whl", hash = "sha256:b5bdfd1c873d4e093aabc0ca84c4ca6dbc4f752afb5c86f146d9742580c9da2e", size = 194248, upload-time = "2026-08-03T21:19:59.399Z" }, + { url = "https://files.pythonhosted.org/packages/76/af/2aeb4dbb5fc41a04161ae9ff1518de7cec08e164f44a8ce6a4cf7fd2cd1d/cffi-2.1.1-cp313-cp313-ios_13_0_arm64_iphonesimulator.whl", hash = "sha256:31348097ff5bbe827ccc41795d4dd099d9f0625e7def00ee653c137a490c2a6c", size = 196908, upload-time = "2026-08-03T21:20:00.746Z" }, + { url = "https://files.pythonhosted.org/packages/a7/46/2e5fdde8555706dd98139a910ca11be02809f3f605ce956f655d0214e100/cffi-2.1.1-cp313-cp313-macosx_10_15_x86_64.whl", hash = "sha256:9d2055050ea716bd38b7f7f1579c275386646b4894c155a3e2f3cd62ed41b7c6", size = 184805, upload-time = "2026-08-03T21:20:02.02Z" }, + { url = "https://files.pythonhosted.org/packages/55/41/4c7042f317b9217502988f0873af87e16ad606dc20f84e546e3e6ce9764c/cffi-2.1.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:19ee6127ee34de7d83ce3d371ebc5ed91addbdcc39f9ab15ce4eb35a4e534971", size = 184764, upload-time = "2026-08-03T21:20:03.141Z" }, + { url = "https://files.pythonhosted.org/packages/43/1f/1c3d90d91811c8f86ced9ed637956c54bfe5b79ca98fe976d7f8c8979f6b/cffi-2.1.1-cp313-cp313-manylinux1_i686.manylinux2014_i686.manylinux_2_17_i686.manylinux_2_5_i686.whl", hash = "sha256:6a8dddef476fab96d066d578fc88526767b836ab5ab21754e1d5bf3879c31c7c", size = 214722, upload-time = "2026-08-03T21:20:04.377Z" }, + { url = "https://files.pythonhosted.org/packages/37/6f/3b5ce4c3b2192d250f04908f2bfd91ef34552ec8f7716a5d4abdb8d67bb2/cffi-2.1.1-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:f16c709686a78c727bbbf059f92b0bf41c6fc60deec706d2dc19f529175a6125", size = 222369, upload-time = "2026-08-03T21:20:05.544Z" }, + { url = "https://files.pythonhosted.org/packages/02/10/4b3c75dde3d9663c9e02ba05c2668b954f671d4bbe346413ca8c696b295a/cffi-2.1.1-cp313-cp313-manylinux2014_ppc64le.manylinux_2_17_ppc64le.whl", hash = "sha256:fcd22650c908d7b7da162bbfaab594a1227a15d1643a98c68b122ac642fa2264", size = 210175, upload-time = "2026-08-03T21:20:06.75Z" }, + { url = "https://files.pythonhosted.org/packages/df/62/14f74b9543e605d17701dc797b815958b8bb70b7624ce1b832ddad48ed6c/cffi-2.1.1-cp313-cp313-manylinux2014_s390x.manylinux_2_17_s390x.whl", hash = "sha256:aa9511c62d14da7aacc9b4bf51f3f697a621e83b2d6919008243c3aad168eea3", size = 208670, upload-time = "2026-08-03T21:20:08.04Z" }, + { url = "https://files.pythonhosted.org/packages/95/95/86342356ff5953b3fb06f7ef7c5bee212d45e770abc7218d451b9148313c/cffi-2.1.1-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:a931079504ecc49efed7744c476a5c343a92fabf66dec2db95edb1b2fdc770e2", size = 221824, upload-time = "2026-08-03T21:20:09.274Z" }, + { url = "https://files.pythonhosted.org/packages/eb/ff/7b3429ff53aafe931ed8a5fc69f481bbef7ba6de87ddcbb63d08f483f613/cffi-2.1.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:a2d7755bef5a12ed488f4ef1f1b69ee9191d7396083b755a5d2295f6edb4768b", size = 225148, upload-time = "2026-08-03T21:20:10.7Z" }, + { url = "https://files.pythonhosted.org/packages/34/34/a95870b9221e09cf4f2ce3178b1a210abdfe63a1bd357da940418d7b8d15/cffi-2.1.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:e0bcb7e0f677f543555d2adff3bf19c05f66cdb4796e5ff602442ab2fe3c4ef7", size = 223564, upload-time = "2026-08-03T21:20:12.165Z" }, + { url = "https://files.pythonhosted.org/packages/70/ea/839b50531021a647fb5e929f72cf97bc1ff702b5472166164b5b6e76b851/cffi-2.1.1-cp313-cp313-win32.whl", hash = "sha256:334644fbac4eff73d985a17a91226df55d0f394160c4cfb880e084c8f7161cac", size = 175263, upload-time = "2026-08-03T21:20:13.559Z" }, + { url = "https://files.pythonhosted.org/packages/60/a6/8b149b2c3f2e11aaa1618ef64500b45f50f22c57a977a4dff1aff1f91042/cffi-2.1.1-cp313-cp313-win_amd64.whl", hash = "sha256:1aa5645c30469b09530c4ebca77ebf8f17618293c58f8549cb1a543a50236e7d", size = 185688, upload-time = "2026-08-03T21:20:14.69Z" }, + { url = "https://files.pythonhosted.org/packages/01/9a/11f687cb39d6a3504060d5242f04f48c735afb4d3d533958a20594890cb2/cffi-2.1.1-cp313-cp313-win_arm64.whl", hash = "sha256:63bbfd5ded17c4840ac07cd8f1c21ba9d9708141f840b324f422f41b207e3973", size = 180078, upload-time = "2026-08-03T21:20:15.917Z" }, + { url = "https://files.pythonhosted.org/packages/d3/7b/d6bbf82b8b96e7391438898c42f5bd96dd02030fd5b64937d248220003e2/cffi-2.1.1-cp314-cp314-ios_13_0_arm64_iphoneos.whl", hash = "sha256:7dbb61fe3a7699468030f71bbe5f8a0e326a151daa91beb11a6fc1f980c55e1c", size = 194064, upload-time = "2026-08-03T21:20:17.148Z" }, + { url = "https://files.pythonhosted.org/packages/94/e6/bcc91b283be94735e268487a054004f0aa19947b6348fa367db53230abc8/cffi-2.1.1-cp314-cp314-ios_13_0_arm64_iphonesimulator.whl", hash = "sha256:f24fb43132a4c6b4cb4eb029492919b2db645be6808d738f244fd146c03c32cb", size = 196720, upload-time = "2026-08-03T21:20:18.268Z" }, + { url = "https://files.pythonhosted.org/packages/d9/99/c4b0c17cacdc9c3b8f280026286a9826d6a208c0f047591a3c3ce99b91fd/cffi-2.1.1-cp314-cp314-macosx_10_15_x86_64.whl", hash = "sha256:d28630f5854ab07ab1fd4aba756de52326c82e6be15d414b12793f1975048b54", size = 184964, upload-time = "2026-08-03T21:20:19.708Z" }, + { url = "https://files.pythonhosted.org/packages/b3/a9/9db617d05d7367c1ad0ab00b3aa6e6f9281edd689b4ee9ea0e5a84e89c97/cffi-2.1.1-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:661c298b4821edebead0c91edd2b00374d67ad7c5a1f7a91d4442633b79d6a72", size = 184962, upload-time = "2026-08-03T21:20:20.833Z" }, + { url = "https://files.pythonhosted.org/packages/67/b8/b42132ca113dc567d37684437b46ca1dafc885902b02a110a02d5b511857/cffi-2.1.1-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:58acb8ab8e295e6c5ea12f888cbb13cf21511ef2a3303a23f4325c29d17fe5c1", size = 222328, upload-time = "2026-08-03T21:20:22.118Z" }, + { url = "https://files.pythonhosted.org/packages/80/10/c5c0cbf0a657aecf59ef511409734230bf556f05a0d6c9eed7aa5c0a0166/cffi-2.1.1-cp314-cp314-manylinux2014_ppc64le.manylinux_2_17_ppc64le.whl", hash = "sha256:456a61fa52d579ebf9df2e9552ead5129855dbaff6c1e5a9b1bc408809bdc062", size = 209985, upload-time = "2026-08-03T21:20:23.401Z" }, + { url = "https://files.pythonhosted.org/packages/d5/6c/bfa0b87b03b9238148beca990292843c9396ba069b54496596594173de7b/cffi-2.1.1-cp314-cp314-manylinux2014_s390x.manylinux_2_17_s390x.whl", hash = "sha256:a4f00aa42f75d6e4595e8866e748cc1705adc0cddfeb2ca86d0d03993d63ba03", size = 208530, upload-time = "2026-08-03T21:20:24.628Z" }, + { url = "https://files.pythonhosted.org/packages/e9/02/4e7d553a7ac4b4238b38b3c1b80d486e9d4436f8d2acbf87a0997fe3f402/cffi-2.1.1-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:b0431303acaea1089ad4b3e9ce4e6518193def1118d4073ca848635ee4ea2e96", size = 221525, upload-time = "2026-08-03T21:20:25.758Z" }, + { url = "https://files.pythonhosted.org/packages/82/1d/a4aaf9babd75acb4d5f223bff71533bee748dd770a382619a798960ee9ba/cffi-2.1.1-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:64faea20f4e2613363a1a9b9c7dd73058f3ecd00133a511e72ad7c511658f527", size = 225053, upload-time = "2026-08-03T21:20:26.985Z" }, + { url = "https://files.pythonhosted.org/packages/81/10/5dc0e7bdd18e22107054288283380fc97a06ae3f1656a106908d666a3c88/cffi-2.1.1-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:5c58fe613dc5e5336357eff555824a314d8e43282600435c8d1cb6a7a2fedd13", size = 223213, upload-time = "2026-08-03T21:20:28.277Z" }, + { url = "https://files.pythonhosted.org/packages/0b/e9/d0061c364cde06ee43168a0d076ac1da512cbc380d44767b844ba34fe2b6/cffi-2.1.1-cp314-cp314-win32.whl", hash = "sha256:1a18a57b58cfb21fc28d72e876acf10eaed67a1ed96226f92af4df681d571c4c", size = 177682, upload-time = "2026-08-03T21:20:44.288Z" }, + { url = "https://files.pythonhosted.org/packages/a7/06/1c3e01e3ba14c39f6d10bfbac52753b7e22259e38088e5cfe1d704918690/cffi-2.1.1-cp314-cp314-win_amd64.whl", hash = "sha256:3222ba5d678f80a030e6afbcc33dc1ae5cb45facabb61cee2c7016b8432fde48", size = 187949, upload-time = "2026-08-03T21:20:45.623Z" }, + { url = "https://files.pythonhosted.org/packages/87/5b/da4e39efe18eeb89cf580ea9cfc66b6a7c3eadb808fc0cc1d3a295cb5a5d/cffi-2.1.1-cp314-cp314-win_arm64.whl", hash = "sha256:ab36d55f9ed2d067327667c2fea18dda018eb628dd6347aa01dda6cf1f5d3836", size = 182947, upload-time = "2026-08-03T21:20:46.955Z" }, + { url = "https://files.pythonhosted.org/packages/23/59/40338bf421c5accea1d45158170c87006ef1cd371b05c077e76476949728/cffi-2.1.1-cp314-cp314t-macosx_10_15_x86_64.whl", hash = "sha256:7750c6449dff7864bb9bb27ddfb0267756189201a3afc911d82b3caacd70dfc3", size = 188504, upload-time = "2026-08-03T21:20:29.495Z" }, + { url = "https://files.pythonhosted.org/packages/7d/47/5ecf1023850036e674c77ec4de86182d309ae344e39e7cba984b7df5d647/cffi-2.1.1-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:0beceaabe56af686895136a2de78db54ecd8e4046b236b8fd6d6cb61389e9bf2", size = 188259, upload-time = "2026-08-03T21:20:31.291Z" }, + { url = "https://files.pythonhosted.org/packages/2a/9c/92934c3bea9f785b23eba304538c0b4d37a2a96d2431eb3a1bc87a11aa19/cffi-2.1.1-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:49cbc70e6542d4ccccb936558d1064a8012541e78f821f955cff24e357776c94", size = 223864, upload-time = "2026-08-03T21:20:32.571Z" }, + { url = "https://files.pythonhosted.org/packages/4d/45/ba4c93527bc38616a8bd36488acb69a2212d60486794f0c1f318949bbb76/cffi-2.1.1-cp314-cp314t-manylinux2014_ppc64le.manylinux_2_17_ppc64le.whl", hash = "sha256:e2d65b31f36619cda3999b78b2aa9632e76b78448e7a56fc4240824200e7c4fc", size = 211538, upload-time = "2026-08-03T21:20:33.808Z" }, + { url = "https://files.pythonhosted.org/packages/80/e9/b6ef565e452acb932fb0cb5443f44a78efbd1233e566f02b5a83855e9115/cffi-2.1.1-cp314-cp314t-manylinux2014_s390x.manylinux_2_17_s390x.whl", hash = "sha256:28907ab9bfb6aa13184cfc17c6b8e1023c5ab6fd7076d8c20a35e59fe04f8f29", size = 210688, upload-time = "2026-08-03T21:20:34.974Z" }, + { url = "https://files.pythonhosted.org/packages/9a/95/eff5f0cee78d2eabc7eebffec40d3fc1876b5f3c95582e018bb4b99601f2/cffi-2.1.1-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:51b31d1c98274844cfd7838ce00bfc27c7423a4dc00fc0772fc3331c2cc90676", size = 223803, upload-time = "2026-08-03T21:20:36.564Z" }, + { url = "https://files.pythonhosted.org/packages/fa/01/579d39fb8bef00a335a23d83757b44feb24cd6345a2c451b64cb67b9c362/cffi-2.1.1-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:5e7cecbaadb83884793e05828cee59b210b24583b9c7425d0ba6a754fe22eb4e", size = 226763, upload-time = "2026-08-03T21:20:37.816Z" }, + { url = "https://files.pythonhosted.org/packages/8d/b0/0b44f47c60b01b57b6e2bbd92343f13a85a1d93bc46ccf6e47e244acd99c/cffi-2.1.1-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:25792eac27877609e7bb06d42ff88278a6624fff2ba9bbb523c09616b117e80f", size = 225688, upload-time = "2026-08-03T21:20:38.959Z" }, + { url = "https://files.pythonhosted.org/packages/eb/d2/3b7176cb570a1d3e27faf67b72f591af508036e0d8b2be2ef9af9e8c84bb/cffi-2.1.1-cp314-cp314t-win32.whl", hash = "sha256:8ef53b2de9bcb9197d31854256575d59dbac0cba72ac627bb291ef5eceb74be4", size = 182868, upload-time = "2026-08-03T21:20:40.388Z" }, + { url = "https://files.pythonhosted.org/packages/56/78/31f00c1bcd97c9bbf55f1bfdf5bc809a5de8887473e90bb9960dca825e80/cffi-2.1.1-cp314-cp314t-win_amd64.whl", hash = "sha256:616f097f2fe415bc92a247f02e11f634e1f9e9a83d327e3c915c15089c87869e", size = 194104, upload-time = "2026-08-03T21:20:41.725Z" }, + { url = "https://files.pythonhosted.org/packages/7b/1b/58496f2ed0a35de575250c02a43ab3cc2c04d494a88fed31c1cabc0fd176/cffi-2.1.1-cp314-cp314t-win_arm64.whl", hash = "sha256:ad2c86c495b899d862ea0f4b42891b8713a3bd45dd4105c7fd51c2a72f39f3a5", size = 186402, upload-time = "2026-08-03T21:20:43.042Z" }, + { url = "https://files.pythonhosted.org/packages/c1/8f/9ebe220eab48a093d1a5a5e339ab0dc7316eef3bb04d63c42f0251b61f50/cffi-2.1.1-cp315-cp315-ios_13_0_arm64_iphoneos.whl", hash = "sha256:dddad92b554513a31f272570678ba307fb9f618f05e3d4a5eacafff9eae03e1d", size = 194043, upload-time = "2026-08-03T21:20:48.179Z" }, + { url = "https://files.pythonhosted.org/packages/ff/69/844bad3ece306c4782c2ecb93597035b6690d48704b803914c199da1e8b3/cffi-2.1.1-cp315-cp315-ios_13_0_arm64_iphonesimulator.whl", hash = "sha256:da0e573f9f97159390c89d9f1a9e41908b66d408cc5b58d08cf3847d844c531b", size = 196737, upload-time = "2026-08-03T21:20:49.457Z" }, + { url = "https://files.pythonhosted.org/packages/1b/8a/af668013284634733f02d683458a0728739c7d6ddb5e14cb0c20832266fe/cffi-2.1.1-cp315-cp315-macosx_10_15_x86_64.whl", hash = "sha256:fb92203a88b3d3053034db775110081c49d28be6551923805e039924093761e4", size = 184933, upload-time = "2026-08-03T21:20:50.639Z" }, + { url = "https://files.pythonhosted.org/packages/0c/75/2f5207ff6d1a613133b23a5203cc0c2a628313b5eb3974d7956ae3c57950/cffi-2.1.1-cp315-cp315-macosx_11_0_arm64.whl", hash = "sha256:2ae64be792b8966f2c69538199728b290e34726562896df1e5dc8ffd8d8188e8", size = 185002, upload-time = "2026-08-03T21:20:52.173Z" }, + { url = "https://files.pythonhosted.org/packages/e2/31/9e1313b0a6e30e91b3b3d3fff51ae99c857c07738e3afcce1f7334e1b7ab/cffi-2.1.1-cp315-cp315-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:507a24c282e0f42f8ed737cf048572cbf580468da5555764a8331735e9c736b6", size = 222271, upload-time = "2026-08-03T21:20:53.462Z" }, + { url = "https://files.pythonhosted.org/packages/50/e3/f6234a833e6e08c7007003074723c406559eecf9b48dfc97471e5a8eb7a0/cffi-2.1.1-cp315-cp315-manylinux2014_ppc64le.manylinux_2_17_ppc64le.whl", hash = "sha256:246fa40ce8645a614ff682e0b70f37134e460eaf93a775e0cbe3cca585a67a80", size = 209919, upload-time = "2026-08-03T21:20:54.783Z" }, + { url = "https://files.pythonhosted.org/packages/0d/fc/5f74e293fced6edb51af3a46c4ccf6c23c9943774ecb375ddbd522c76add/cffi-2.1.1-cp315-cp315-manylinux2014_s390x.manylinux_2_17_s390x.whl", hash = "sha256:471cee653ae88de62096552e6d24ccb4a5adb8c8c9f10b5054d0122c15bf2779", size = 208529, upload-time = "2026-08-03T21:20:56.066Z" }, + { url = "https://files.pythonhosted.org/packages/44/16/29e6d01b388bef055ecd6ca8244b3f4d336bd09e92d5d892187b9601084e/cffi-2.1.1-cp315-cp315-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:aeae0e330c9f6acd681f647d46cefd30c29f93e3392882e792e82080c9691399", size = 221630, upload-time = "2026-08-03T21:20:57.336Z" }, + { url = "https://files.pythonhosted.org/packages/a4/18/fa7f1f6857d5eb88a4ca99ffcbfb7c387a287ccc154c64a73e86314745d7/cffi-2.1.1-cp315-cp315-musllinux_1_2_aarch64.whl", hash = "sha256:42a494cee34437f05546455144f2b5d9ac09b1face62bcfce597d2e521066688", size = 225134, upload-time = "2026-08-03T21:20:58.675Z" }, + { url = "https://files.pythonhosted.org/packages/e0/9f/e8e3dfa04a1b4c241f8c91faacad872b4d4efd051d49764ad4e2fd4b9fea/cffi-2.1.1-cp315-cp315-musllinux_1_2_x86_64.whl", hash = "sha256:cc572dace3f60ef98d7b12ff411d20f5362feb31a0439eab0085bbfd349982d7", size = 223197, upload-time = "2026-08-03T21:20:59.968Z" }, + { url = "https://files.pythonhosted.org/packages/f8/7e/8debeb04f1ab9fe2a6963964cd6f1aaf7192627b83926586a6a4e089c9fa/cffi-2.1.1-cp315-cp315-win32.whl", hash = "sha256:4f42141fc14250de6dde5ee7ea4432be017252d91f19c5ad043c084cea629cac", size = 177683, upload-time = "2026-08-03T21:21:14.901Z" }, + { url = "https://files.pythonhosted.org/packages/e0/31/5158704cc474ab65c1647932e88be78dc0873f47130e253be38bcaf13d01/cffi-2.1.1-cp315-cp315-win_amd64.whl", hash = "sha256:e6e8cff14d6fb0be70a09c0bdc58096f501952d04624ebf867e0e56da2df8960", size = 187897, upload-time = "2026-08-03T21:21:16.108Z" }, + { url = "https://files.pythonhosted.org/packages/cc/4b/b3a2da8570c704ffc0f9762cdc3ec0f02c8573798e0b5cf7f11c82bbb70f/cffi-2.1.1-cp315-cp315-win_arm64.whl", hash = "sha256:27350daa11d4f10c540e6e89dada4c54feb7256ad03e9a4dc075ebad7ba360d1", size = 182935, upload-time = "2026-08-03T21:21:17.271Z" }, + { url = "https://files.pythonhosted.org/packages/d0/ef/5443574510a1207e6f6bc38ba6e1f1de36cb48fef07b2728bb896a21f430/cffi-2.1.1-cp315-cp315t-macosx_10_15_x86_64.whl", hash = "sha256:c26608d2222fb1e94487e4a387d85f13eb55d5ed725cb25a0c589ac4ee60e7bc", size = 188464, upload-time = "2026-08-03T21:21:01.163Z" }, + { url = "https://files.pythonhosted.org/packages/7e/ae/a56fa8c4686ad50e148fcbc8d3ae0d03915ff5c30d795058988c24118cef/cffi-2.1.1-cp315-cp315t-macosx_11_0_arm64.whl", hash = "sha256:4be96343e422f2dfcd12ab5c9f5aebe03f82f737c6bffeca6830b3875cb44aab", size = 188262, upload-time = "2026-08-03T21:21:02.382Z" }, + { url = "https://files.pythonhosted.org/packages/53/b2/6187f46f2912276a3ae284076109cc5c8680482f11f766ccf26db4a86427/cffi-2.1.1-cp315-cp315t-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:937c0052c05a31ca1daf18de3158eed4dbfcb9cc107adbea227728d647be701e", size = 223779, upload-time = "2026-08-03T21:21:03.553Z" }, + { url = "https://files.pythonhosted.org/packages/8a/f6/c3ad28bd19f77047a03084424fbd4cbe997303267c14423737324be0385d/cffi-2.1.1-cp315-cp315t-manylinux2014_ppc64le.manylinux_2_17_ppc64le.whl", hash = "sha256:df423d40ee8654634421812bc3b196da3f9bd7d32929da813f8394c4348a5358", size = 211520, upload-time = "2026-08-03T21:21:04.863Z" }, + { url = "https://files.pythonhosted.org/packages/a0/cd/ccac9013a5bd9fd764de118674ab9c805b5ca10c19270d90ee273f8b2240/cffi-2.1.1-cp315-cp315t-manylinux2014_s390x.manylinux_2_17_s390x.whl", hash = "sha256:a730a083190634c65cca36ba5f489531576ebd79bcd5c8e172130f6453127231", size = 210673, upload-time = "2026-08-03T21:21:06.223Z" }, + { url = "https://files.pythonhosted.org/packages/52/86/2976131c639aead931c5bee5aba67e4b09fbeb8018b6f282f70803f923a7/cffi-2.1.1-cp315-cp315t-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:363e05fa78e15116c3c32c210ee36884fd6b9afa6d440e47112c3bd511d64cb6", size = 223835, upload-time = "2026-08-03T21:21:07.539Z" }, + { url = "https://files.pythonhosted.org/packages/ac/0c/33a7aeab2f9c76918c52e084beb39c570db3588133412929e8ec06fab90b/cffi-2.1.1-cp315-cp315t-musllinux_1_2_aarch64.whl", hash = "sha256:770de9db11e84213beec501cfcaa013b019820ca881e03344dea5844f7876d94", size = 226705, upload-time = "2026-08-03T21:21:08.774Z" }, + { url = "https://files.pythonhosted.org/packages/e3/26/2cde30fdde421130bfc18f70395731a6e6b2053c6a1978a5258ff04e72fa/cffi-2.1.1-cp315-cp315t-musllinux_1_2_x86_64.whl", hash = "sha256:7da0c5eff80f0197f3b3d1232ec5a682a9325f4ae9016a78f5f5ca35f9ced1f5", size = 225539, upload-time = "2026-08-03T21:21:09.911Z" }, + { url = "https://files.pythonhosted.org/packages/6d/cd/a361394c94b2129d604bb846f624a8e88255a3ee33129c434a00d715e64f/cffi-2.1.1-cp315-cp315t-win32.whl", hash = "sha256:06c72bb76605a4b0cd0aad6930b69d4baf7dd5d806cfc409b824191099700e66", size = 182707, upload-time = "2026-08-03T21:21:11.226Z" }, + { url = "https://files.pythonhosted.org/packages/9b/b5/ba2b299993c26577d529b6ae29841f9e15b9fcf004d65f423f4fcf94ade9/cffi-2.1.1-cp315-cp315t-win_amd64.whl", hash = "sha256:d9c275eaacd24aa73f94ffd6de08fc3f932424d8b6c376f4bed7cde376fe7bc3", size = 193772, upload-time = "2026-08-03T21:21:12.39Z" }, + { url = "https://files.pythonhosted.org/packages/aa/29/35e016098c814cd93de9cd320c66b5bfba14dc6ecedd3cb518fa7c408c69/cffi-2.1.1-cp315-cp315t-win_arm64.whl", hash = "sha256:d18e5ac0f2f03f4f518d3e23db0f0cad7faa1da8620e9c09461d443bbf6e6692", size = 186360, upload-time = "2026-08-03T21:21:13.636Z" }, +] + [[package]] name = "charset-normalizer" version = "3.5.1" @@ -347,6 +524,15 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/a7/06/3d6badcf13db419e25b07041d9c7b4a2c331d3f4e7134445ec5df57714cd/coloredlogs-15.0.1-py2.py3-none-any.whl", hash = "sha256:612ee75c546f53e92e70049c9dbfcc18c935a2b9a53b66085ce9ef6a6e5c0934", size = 46018, upload-time = "2021-06-11T10:22:42.561Z" }, ] +[[package]] +name = "comm" +version = "0.2.3" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/4c/13/7d740c5849255756bc17888787313b61fd38a0a8304fc4f073dfc46122aa/comm-0.2.3.tar.gz", hash = "sha256:2dc8048c10962d55d7ad693be1e7045d891b7ce8d999c97963a5e3e99c055971", size = 6319, upload-time = "2025-07-25T14:02:04.452Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/60/97/891a0971e1e4a8c5d2b20bbe0e524dc04548d2307fee33cdeba148fd4fc7/comm-0.2.3-py3-none-any.whl", hash = "sha256:c615d91d75f7f04f095b30d1c1711babd43bdc6419c1be9886a85f2f4e489417", size = 7294, upload-time = "2025-07-25T14:02:02.896Z" }, +] + [[package]] name = "commonmark" version = "0.9.2" @@ -399,8 +585,7 @@ dev = [ { name = "ruff" }, ] docs = [ - { name = "griffe" }, - { name = "quartodoc" }, + { name = "great-docs" }, ] [package.metadata] @@ -437,10 +622,7 @@ dev = [ { name = "pytest-asyncio" }, { name = "ruff" }, ] -docs = [ - { name = "griffe", specifier = "<2" }, - { name = "quartodoc", specifier = ">=0.11.1" }, -] +docs = [{ name = "great-docs", specifier = ">=0.17" }] [[package]] name = "databackend" @@ -451,6 +633,31 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/d7/84/582e1daf3f2eb296573c11b774abf10223e9858d4c5c5c936180b643a720/databackend-0.0.3-py3-none-any.whl", hash = "sha256:2ded97ff85a0ca272d752fbc0513f70512d2c23325e3c72de15613df7e959ef5", size = 7001, upload-time = "2024-08-21T21:09:41.137Z" }, ] +[[package]] +name = "debugpy" +version = "1.8.21" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/f2/aa/12037145b7a56eaa5b29b41872f7a21b538e807e13f32c4d3c46e59be084/debugpy-1.8.21.tar.gz", hash = "sha256:a3c53278e84c94e11bd87c53970ec391d1a67396c8b22609fcac576520e611a6", size = 1697577, upload-time = "2026-06-01T19:30:35.156Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/89/fb/cbf306d6e07a313a91e7171a98669054502840931432c227cfd505ee367f/debugpy-1.8.21-cp311-cp311-macosx_15_0_universal2.whl", hash = "sha256:da456226c7b4c69e35dbe35dcee6623d912000a77816db7856a41af1c72a0264", size = 2203120, upload-time = "2026-06-01T19:30:43.964Z" }, + { url = "https://files.pythonhosted.org/packages/aa/57/aa739bd4ad2cbf96aeb1b20b56918ddd5ae4c28b68709bfcd327f02123ee/debugpy-1.8.21-cp311-cp311-manylinux_2_34_x86_64.whl", hash = "sha256:f68b891688e61bdc08b8d364d919ff0051e0b94657b39dcd027bc3173edb7cdc", size = 3059958, upload-time = "2026-06-01T19:30:45.622Z" }, + { url = "https://files.pythonhosted.org/packages/a8/31/453d2c9a23d133fe2c8ec7ca1d816ded52a913487fe3ffef7c01b4b706af/debugpy-1.8.21-cp311-cp311-win32.whl", hash = "sha256:f843a8b08c2edeaf9b1582eed4f25441af21a297c22ff16bf76a662557aa9c9e", size = 5236515, upload-time = "2026-06-01T19:30:47.461Z" }, + { url = "https://files.pythonhosted.org/packages/60/94/6660de2f2d7bf388f229335ba4637646eebabdbf38564cb439a95a9193c9/debugpy-1.8.21-cp311-cp311-win_amd64.whl", hash = "sha256:84c564d8cc701d41843b29a92814c1f1bef6798724ca9d675c284ad9f6a547d7", size = 5256138, upload-time = "2026-06-01T19:30:49.113Z" }, + { url = "https://files.pythonhosted.org/packages/a2/df/bf625547431a9cadc9f4cbfeda38866e2b17f6aed147b625377e87834449/debugpy-1.8.21-cp312-cp312-macosx_15_0_universal2.whl", hash = "sha256:9f96713896f39c3dff0ee841f47320c3f2983d33c341e009361bb0ebc79adc4e", size = 2483609, upload-time = "2026-06-01T19:30:50.794Z" }, + { url = "https://files.pythonhosted.org/packages/bf/09/59324b903599031ff9faaec1758292409f6561a0ec2492fe4b703327705a/debugpy-1.8.21-cp312-cp312-manylinux_2_34_x86_64.whl", hash = "sha256:c193d474f0a211191f2b4449d2d06157c689013035bd952f3b617e0ef422b176", size = 3968900, upload-time = "2026-06-01T19:30:52.341Z" }, + { url = "https://files.pythonhosted.org/packages/14/cd/27f65b805d7fe005c44e1a36b9183ecdfbcdbf9d3e721a5115d461ecc7ee/debugpy-1.8.21-cp312-cp312-win32.whl", hash = "sha256:4743373c1cac7f9e74a1b9915bf1dbe0e900eca657ffb170ae07ac8363205ae9", size = 5336340, upload-time = "2026-06-01T19:30:54.047Z" }, + { url = "https://files.pythonhosted.org/packages/77/1d/c84e30c0c674184948b66f076ab271c01d940618a2824c23cd035a27bc20/debugpy-1.8.21-cp312-cp312-win_amd64.whl", hash = "sha256:bd7ba9dd3daa7c2f942c6ca8d4695a16bf9ac16b63615261c7982bc74f7ed20c", size = 5374751, upload-time = "2026-06-01T19:30:55.891Z" }, + { url = "https://files.pythonhosted.org/packages/77/6b/d817e1f8cc77aa055d37fba092e0febfdff40fe652d8d53d4cd7a86ad98d/debugpy-1.8.21-cp313-cp313-macosx_15_0_universal2.whl", hash = "sha256:13678151fc401e2d68c9880b91e28714f797d40422994572b24560ef80910a88", size = 2477398, upload-time = "2026-06-01T19:30:57.644Z" }, + { url = "https://files.pythonhosted.org/packages/48/57/412421516afc3055fa577516f00beec3d663f9b0ab330639547ae6c57720/debugpy-1.8.21-cp313-cp313-manylinux_2_34_x86_64.whl", hash = "sha256:ecbd158386c31ffe71d46f72d44d56e66331ab9b16cad649156d514368f23ab2", size = 3962096, upload-time = "2026-06-01T19:30:59.235Z" }, + { url = "https://files.pythonhosted.org/packages/c1/62/2c616337cf6ba7b07ebbc97f02c6c945a8e2f76b365e33ee809c32ee36d1/debugpy-1.8.21-cp313-cp313-win32.whl", hash = "sha256:2c2ae706dec41d99a9ca1f7ebc987a83e65578363be6f6b3ac9067504917fae1", size = 5336288, upload-time = "2026-06-01T19:31:00.79Z" }, + { url = "https://files.pythonhosted.org/packages/f8/99/9175103392f84c4b1bf7622888cdc68da07f0ff7d9e581266428f6776033/debugpy-1.8.21-cp313-cp313-win_amd64.whl", hash = "sha256:aa648733047443eb1d07682c4ef287d36a54507b643ffdf38b09a3ef002c72a0", size = 5376567, upload-time = "2026-06-01T19:31:02.56Z" }, + { url = "https://files.pythonhosted.org/packages/ce/3d/f4bbb323a548bfab2af3d6b4ffd9bf22636e55956a1285d317a1de643aad/debugpy-1.8.21-cp314-cp314-macosx_15_0_universal2.whl", hash = "sha256:9bb2a685287a2ac9b181cde89edcec64845cb51de7faaa75badb9a698bc24782", size = 2477209, upload-time = "2026-06-01T19:31:04.157Z" }, + { url = "https://files.pythonhosted.org/packages/8c/2d/6e7ec524984a1702777868de49a4c53202bddac2a432a76a093469587750/debugpy-1.8.21-cp314-cp314-manylinux_2_34_x86_64.whl", hash = "sha256:3d6922439bf33fd38a3e2c447869ebc7b97da5cd3d329ff1ef9bc06c4903437e", size = 3927115, upload-time = "2026-06-01T19:31:05.863Z" }, + { url = "https://files.pythonhosted.org/packages/97/47/d1aa6d64005a98a9144647d99306b419396f9ad7bf1d73c119e17a81fb4d/debugpy-1.8.21-cp314-cp314-win32.whl", hash = "sha256:15d4963bd5ffa48f0da0947fd06757fa7621945048a14ad7705431566d3c0e7c", size = 5336724, upload-time = "2026-06-01T19:31:07.711Z" }, + { url = "https://files.pythonhosted.org/packages/5f/67/b905b90d163af11878c1af8abafa4a25206335e112e284e413454543a6da/debugpy-1.8.21-cp314-cp314-win_amd64.whl", hash = "sha256:fe0744a12353406de0ae8ccff0d0a4a666f00801a3db8fd04e7a5f761cd520e8", size = 5373803, upload-time = "2026-06-01T19:31:09.469Z" }, + { url = "https://files.pythonhosted.org/packages/95/51/67e7cf11a53e40694f720457d5b3a1cdaaa3d5a9a633e482f225456b93ff/debugpy-1.8.21-py2.py3-none-any.whl", hash = "sha256:b1e37d333663c8851516a47364ef473da127f9caebe4417e6df6f5825a7e9a92", size = 5352888, upload-time = "2026-06-01T19:31:25.186Z" }, +] + [[package]] name = "defusedxml" version = "0.7.1" @@ -496,6 +703,24 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/e1/2c/95d9216b79e9273689d7ebce125a54503ed0c9bd7da931f0265888e99779/duckdb-1.5.5-cp314-cp314-win_arm64.whl", hash = "sha256:63e48d4b74b15aeacd688976432a7225163df8c226eddeb8536bba2d4d4ff433", size = 14470180, upload-time = "2026-07-22T10:55:14.445Z" }, ] +[[package]] +name = "executing" +version = "2.2.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/cc/28/c14e053b6762b1044f34a13aab6859bbf40456d37d23aa286ac24cfd9a5d/executing-2.2.1.tar.gz", hash = "sha256:3632cc370565f6648cc328b32435bd120a1e4ebb20c77e3fdde9a13cd1e533c4", size = 1129488, upload-time = "2025-09-01T09:48:10.866Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/c1/ea/53f2148663b321f21b5a606bd5f191517cf40b7072c0497d3c92c4a13b1e/executing-2.2.1-py2.py3-none-any.whl", hash = "sha256:760643d3452b4d777d295bb167ccc74c64a81df23fb5e08eff250c425a4b2017", size = 28317, upload-time = "2025-09-01T09:48:08.5Z" }, +] + +[[package]] +name = "fastjsonschema" +version = "2.22.2" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/33/a4/9473c7c3b87009d9c1d74034e4a0f6a35ff0d42dd0f9866d0c3ec4e9217b/fastjsonschema-2.22.2.tar.gz", hash = "sha256:72064e12356a7d6ef02165be2946b9abadbdf238536e07eb587e3dbaa33099cf", size = 385171, upload-time = "2026-08-15T19:47:08.853Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/49/82/2755c7c982086f00d4dab85bc120ec35045a9fc2191893a6ce79afe94443/fastjsonschema-2.22.2-py3-none-any.whl", hash = "sha256:0fb3915616adac85ccfdd737d26be1089845d2019819505b42d39888458f74d4", size = 27413, upload-time = "2026-08-15T19:47:04.406Z" }, +] + [[package]] name = "flatbuffers" version = "25.12.19" @@ -504,6 +729,15 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/e8/2d/d2a548598be01649e2d46231d151a6c56d10b964d94043a335ae56ea2d92/flatbuffers-25.12.19-py2.py3-none-any.whl", hash = "sha256:7634f50c427838bb021c2d66a3d1168e9d199b0607e6329399f04846d42e20b4", size = 26661, upload-time = "2025-12-19T23:16:13.622Z" }, ] +[[package]] +name = "fqdn" +version = "1.5.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/30/3e/a80a8c077fd798951169626cde3e239adeba7dab75deb3555716415bd9b0/fqdn-1.5.1.tar.gz", hash = "sha256:105ed3677e767fb5ca086a0c1f4bb66ebc3c100be518f0e0d755d9eae164d89f", size = 6015, upload-time = "2021-03-11T07:16:29.08Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/cf/58/8acf1b3e91c58313ce5cb67df61001fc9dcd21be4fadb76c1a2d540e09ed/fqdn-1.5.1-py3-none-any.whl", hash = "sha256:3a179af3761e4df6eb2e026ff9e1a3033d3587bf980a0b1b2e1e5d08d7358014", size = 9121, upload-time = "2021-03-11T07:16:28.351Z" }, +] + [[package]] name = "fsspec" version = "2025.7.0" @@ -565,6 +799,26 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/6f/d1/4adcfcb9c95e3d064c9f7aaf6cb3a4fc842d86115014b9d4094db4d465b5/google_re2-1.1.20251105-1-cp314-cp314-win_arm64.whl", hash = "sha256:1d27f3a2a947ec1f721d0f14f661108acfd4f4d34f357ce28db951cc036656e5", size = 643093, upload-time = "2025-11-05T14:58:05.761Z" }, ] +[[package]] +name = "great-docs" +version = "0.17.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "click" }, + { name = "griffe" }, + { name = "jupyter" }, + { name = "pillow" }, + { name = "py-yaml12" }, + { name = "pygments" }, + { name = "python-dotenv" }, + { name = "requests" }, + { name = "ruff" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/aa/99/d0573f286f3179efe9f3f819bc686e3f2a3c570d3643cb1f1c8979b7a5fc/great_docs-0.17.0.tar.gz", hash = "sha256:98e5408ba1e64a3c8b08a6f6619e2b2d1a83d509b8f97d1477030e3112f6948d", size = 31422143, upload-time = "2026-08-13T15:23:59.668Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/c8/88/f6f5ebd572ddf532021b87d719765b0ce59fb99dd12f6d1b25ba93ae7380/great_docs-0.17.0-py3-none-any.whl", hash = "sha256:3d2e715ca7aa3cbbf7ff47a2987dd9c65510d920ceefb793c200eb3ed509e550", size = 1034889, upload-time = "2026-08-13T15:23:57.227Z" }, +] + [[package]] name = "greenlet" version = "3.5.5" @@ -630,14 +884,37 @@ wheels = [ [[package]] name = "griffe" -version = "1.15.0" +version = "2.1.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "griffecli" }, + { name = "griffelib" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/00/44/63913c007814cab5ba9d36f25ad40dfc640c2e2931d195bd2d05f774a5d6/griffe-2.1.0.tar.gz", hash = "sha256:c58845df5a364feaabd05ee8c767b97b03e478da8aa18b9923553c812fb0d955", size = 244879, upload-time = "2026-06-19T12:05:41.262Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/6b/fb/3c65d392feae6c36dc2b55a14dd8270b7b35a3171c93b71a4d2ee4abf241/griffe-2.1.0-py3-none-any.whl", hash = "sha256:2ccdab17fb9cd76f278d7b5611cfc8f68cbe846d8d48df63dff80b62ecfa6f65", size = 5140, upload-time = "2026-06-19T12:05:39.913Z" }, +] + +[[package]] +name = "griffecli" +version = "2.1.0" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "colorama" }, + { name = "griffelib" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/0d/0c/3a471b6e31951dce2360477420d0a8d1e00dea6cf33b70f3e8c3ab6e28e1/griffe-1.15.0.tar.gz", hash = "sha256:7726e3afd6f298fbc3696e67958803e7ac843c1cfe59734b6251a40cdbfb5eea", size = 424112, upload-time = "2025-11-10T15:03:15.52Z" } +sdist = { url = "https://files.pythonhosted.org/packages/8e/c6/90f85d47af96300d629b38c25b71aad9467a620cac964a39280e822efc8a/griffecli-2.1.0.tar.gz", hash = "sha256:2ff68dbee9395fdb668b10374c51683392d697b226ac60159798f4add1ee716c", size = 56913, upload-time = "2026-06-19T12:05:43.119Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/9c/83/3b1d03d36f224edded98e9affd0467630fc09d766c0e56fb1498cbb04a9b/griffe-1.15.0-py3-none-any.whl", hash = "sha256:6f6762661949411031f5fcda9593f586e6ce8340f0ba88921a0f2ef7a81eb9a3", size = 150705, upload-time = "2025-11-10T15:03:13.549Z" }, + { url = "https://files.pythonhosted.org/packages/80/2f/513232ec1d5f5da182e4ce45a11427e37dd210844a9e2bca451fc9661fb3/griffecli-2.1.0-py3-none-any.whl", hash = "sha256:6e22b1423d562ddc510997b4be1fe89de59e19dcff78831c0f4bfc3b8134a718", size = 9500, upload-time = "2026-06-19T12:05:37.517Z" }, +] + +[[package]] +name = "griffelib" +version = "2.1.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/33/e4/8d187ea29c2e30b3a09505c567513077d6117861bde1fbd997a167f262ec/griffelib-2.1.0.tar.gz", hash = "sha256:762a186d2c6fd6794d4ea20d428d597ffb857cb56b66421651cbba15bdd5e813", size = 216234, upload-time = "2026-06-19T12:05:42.278Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/e4/d3/5268aeabf2ad82658c4e2ff3a060648d0f02f3926cb53247c0e4d0dab49e/griffelib-2.1.0-py3-none-any.whl", hash = "sha256:cc7b3d2d2865ad0b909fcc38086e3f554b5ea7acbaa7bbb7ecaa3f5dfb7d9f00", size = 142560, upload-time = "2026-06-19T12:05:38.742Z" }, ] [[package]] @@ -789,6 +1066,104 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/cb/b1/3846dd7f199d53cb17f49cba7e651e9ce294d8497c8c150530ed11865bb8/iniconfig-2.3.0-py3-none-any.whl", hash = "sha256:f631c04d2c48c52b84d0d0549c99ff3859c98df65b3101406327ecc7d53fbf12", size = 7484, upload-time = "2025-10-18T21:55:41.639Z" }, ] +[[package]] +name = "ipykernel" +version = "7.3.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "appnope", marker = "sys_platform == 'darwin'" }, + { name = "comm" }, + { name = "debugpy" }, + { name = "ipython" }, + { name = "jupyter-client" }, + { name = "jupyter-core" }, + { name = "matplotlib-inline" }, + { name = "nest-asyncio2" }, + { name = "packaging" }, + { name = "psutil" }, + { name = "pyzmq" }, + { name = "tornado" }, + { name = "traitlets" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/3d/c4/e4a38f579de4225a561305666f7541cdabb30075def2aa1ac17bd73c1fb5/ipykernel-7.3.0.tar.gz", hash = "sha256:9acaaaf97d16355166e4085afe9d225bfbdf2b7ef520f9df3be8f2b248275e09", size = 184899, upload-time = "2026-06-10T08:41:25.481Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/3d/02/77b271f5dc58bfbc0b577c877b2365d1ffea2afe66a80c13f2312820348c/ipykernel-7.3.0-py3-none-any.whl", hash = "sha256:897eb64da762549ef610698fca5e9675195ec6ac8ec7f19d81ce1ca20c876057", size = 120583, upload-time = "2026-06-10T08:41:23.648Z" }, +] + +[[package]] +name = "ipython" +version = "9.17.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "colorama", marker = "sys_platform == 'win32'" }, + { name = "ipython-pygments-lexers" }, + { name = "jedi" }, + { name = "matplotlib-inline" }, + { name = "pexpect", marker = "sys_platform != 'emscripten' and sys_platform != 'win32'" }, + { name = "prompt-toolkit" }, + { name = "psutil", marker = "sys_platform != 'cygwin' and sys_platform != 'emscripten'" }, + { name = "pygments" }, + { name = "stack-data" }, + { name = "traitlets" }, + { name = "typing-extensions", marker = "python_full_version < '3.12'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/b9/32/99451b1283ec5d92ad77073f12e1c667dc10775384d8f15c2914207149dd/ipython-9.17.1.tar.gz", hash = "sha256:8919be8c27f20a6f4423145028063f6637b42a03ce57665bb12015ee1f073529", size = 4539289, upload-time = "2026-09-01T08:29:32.6Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/2d/1e/65b59cf518c106aa755e7f7da3099027738687a862ec785060702a481320/ipython-9.17.1-py3-none-any.whl", hash = "sha256:6d1645743cfd1a07eb695d85aa2b5fa66721f8cbae9431d4049f7084bbf06509", size = 639038, upload-time = "2026-09-01T08:29:30.673Z" }, +] + +[[package]] +name = "ipython-pygments-lexers" +version = "1.1.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { 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 = [ + { url = "https://files.pythonhosted.org/packages/d9/33/1f075bf72b0b747cb3288d011319aaf64083cf2efef8354174e3ed4540e2/ipython_pygments_lexers-1.1.1-py3-none-any.whl", hash = "sha256:a9462224a505ade19a605f71f8fa63c2048833ce50abc86768a0d81d876dc81c", size = 8074, upload-time = "2025-01-17T11:24:33.271Z" }, +] + +[[package]] +name = "ipywidgets" +version = "8.1.9" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "comm" }, + { name = "ipython" }, + { name = "jupyterlab-widgets" }, + { name = "traitlets" }, + { name = "widgetsnbextension" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/c9/7c/6db60eddf38547353b06d57941f5eee22a990640ce30479fd71a810507f2/ipywidgets-8.1.9.tar.gz", hash = "sha256:bcccba38a6ec3253f7a39c943cea5b9ad01999ce071396171adbc51c6a6a8613", size = 117252, upload-time = "2026-08-18T08:54:24.123Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/c3/55/298e9b3b864a198234997e87a1471c1b17d7f3546ace6d18fb5cf1ce24b2/ipywidgets-8.1.9-py3-none-any.whl", hash = "sha256:f2b8cbcaae10252b809fbe4d7470db75c09b769a32cbf816d20e5ca6d3c5a79d", size = 140101, upload-time = "2026-08-18T08:54:22.339Z" }, +] + +[[package]] +name = "isoduration" +version = "20.11.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "arrow" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/7c/1a/3c8edc664e06e6bd06cce40c6b22da5f1429aa4224d0c590f3be21c91ead/isoduration-20.11.0.tar.gz", hash = "sha256:ac2f9015137935279eac671f94f89eb00584f940f5dc49462a0c4ee692ba1bd9", size = 11649, upload-time = "2020-11-01T11:00:00.312Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/7b/55/e5326141505c5d5e34c5e0935d2908a74e4561eca44108fbfb9c13d2911a/isoduration-20.11.0-py3-none-any.whl", hash = "sha256:b2904c2a4228c3d44f409c8ae8e2370eb21a26f7ac2ec5446df141dde3452042", size = 11321, upload-time = "2020-11-01T10:59:58.02Z" }, +] + +[[package]] +name = "jedi" +version = "0.20.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "parso" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/46/b7/a3635f6a2d7cf5b5dd98064fc1d5fbbafcb25477bcea204a3a92145d158b/jedi-0.20.0.tar.gz", hash = "sha256:c3f4ccbd276696f4b19c54618d4fb18f9fc24b0aef02acf704b23f487daa1011", size = 3119416, upload-time = "2026-05-01T23:38:47.814Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/9a/93/242e2eab5fe682ffcb8b0084bde703a41d51e17ee0f3a31ff0d9d813620a/jedi-0.20.0-py2.py3-none-any.whl", hash = "sha256:7bdd9c2634f56713299976f4cbd59cb3fa92165cc5e05ea811fb253480728b67", size = 4884812, upload-time = "2026-05-01T23:38:43.919Z" }, +] + [[package]] name = "jinja2" version = "3.1.6" @@ -896,34 +1271,288 @@ dependencies = [ ] sdist = { url = "https://files.pythonhosted.org/packages/d5/1d/537ab090f302b838943a1b56497dd53059b9a9b46a074936470173a2e207/joblib-1.6.0.tar.gz", hash = "sha256:2ccc96785b12046c08fd6d55839c12857831b54a3c1673ffadd2f04bfc4eda03", size = 327903, upload-time = "2026-08-31T09:39:04.122Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/18/53/84099323c2ec4be98d935f63c033ac4151ee83836ca1050ede3b3aadf155/joblib-1.6.0-py3-none-any.whl", hash = "sha256:3dbbf9f6e4b592a2357b854608e980fe6390d131d7a82f011a377ef2ebef7aba", size = 306115, upload-time = "2026-08-31T09:39:02.298Z" }, + { url = "https://files.pythonhosted.org/packages/18/53/84099323c2ec4be98d935f63c033ac4151ee83836ca1050ede3b3aadf155/joblib-1.6.0-py3-none-any.whl", hash = "sha256:3dbbf9f6e4b592a2357b854608e980fe6390d131d7a82f011a377ef2ebef7aba", size = 306115, upload-time = "2026-08-31T09:39:02.298Z" }, +] + +[[package]] +name = "json5" +version = "0.15.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/e4/7d/05c46a96a78147ae3bf99c2f4169ce144a70220b8d6fcd56f6ec368b8ce9/json5-0.15.0.tar.gz", hash = "sha256:7424d1f1eb1d56da6e3d70643f53619862b4ce81440bdb8ecfd6f875e5ba4a71", size = 53278, upload-time = "2026-06-19T20:08:27.716Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/eb/be/59527c99478aade6bb33a68d72e6e18dd4e6ff6eacfc7d01bdb15bc76912/json5-0.15.0-py3-none-any.whl", hash = "sha256:56636a30c0e8a4665fe2179c0212f32eae3796dea89ea6f649b9436ecdb39618", size = 36570, upload-time = "2026-06-19T20:08:26.748Z" }, +] + +[[package]] +name = "jsonpointer" +version = "3.1.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/18/c7/af399a2e7a67fd18d63c40c5e62d3af4e67b836a2107468b6a5ea24c4304/jsonpointer-3.1.1.tar.gz", hash = "sha256:0b801c7db33a904024f6004d526dcc53bbb8a4a0f4e32bfd10beadf60adf1900", size = 9068, upload-time = "2026-03-23T22:32:32.458Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/9e/6a/a83720e953b1682d2d109d3c2dbb0bc9bf28cc1cbc205be4ef4be5da709d/jsonpointer-3.1.1-py3-none-any.whl", hash = "sha256:8ff8b95779d071ba472cf5bc913028df06031797532f08a7d5b602d8b2a488ca", size = 7659, upload-time = "2026-03-23T22:32:31.568Z" }, +] + +[[package]] +name = "jsonschema" +version = "4.26.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "attrs" }, + { name = "jsonschema-specifications" }, + { name = "referencing" }, + { name = "rpds-py" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/b3/fc/e067678238fa451312d4c62bf6e6cf5ec56375422aee02f9cb5f909b3047/jsonschema-4.26.0.tar.gz", hash = "sha256:0c26707e2efad8aa1bfc5b7ce170f3fccc2e4918ff85989ba9ffa9facb2be326", size = 366583, upload-time = "2026-01-07T13:41:07.246Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/69/90/f63fb5873511e014207a475e2bb4e8b2e570d655b00ac19a9a0ca0a385ee/jsonschema-4.26.0-py3-none-any.whl", hash = "sha256:d489f15263b8d200f8387e64b4c3a75f06629559fb73deb8fdfb525f2dab50ce", size = 90630, upload-time = "2026-01-07T13:41:05.306Z" }, +] + +[package.optional-dependencies] +format-nongpl = [ + { name = "fqdn" }, + { name = "idna" }, + { name = "isoduration" }, + { name = "jsonpointer" }, + { name = "rfc3339-validator" }, + { name = "rfc3986-validator" }, + { name = "rfc3987-syntax" }, + { name = "uri-template" }, + { name = "webcolors" }, +] + +[[package]] +name = "jsonschema-specifications" +version = "2025.9.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "referencing" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/19/74/a633ee74eb36c44aa6d1095e7cc5569bebf04342ee146178e2d36600708b/jsonschema_specifications-2025.9.1.tar.gz", hash = "sha256:b540987f239e745613c7a9176f3edb72b832a4ac465cf02712288397832b5e8d", size = 32855, upload-time = "2025-09-08T01:34:59.186Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/41/45/1a4ed80516f02155c51f51e8cedb3c1902296743db0bbc66608a0db2814f/jsonschema_specifications-2025.9.1-py3-none-any.whl", hash = "sha256:98802fee3a11ee76ecaca44429fda8a41bff98b00a0f2838151b113f210cc6fe", size = 18437, upload-time = "2025-09-08T01:34:57.871Z" }, +] + +[[package]] +name = "jupyter" +version = "1.1.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "ipykernel" }, + { name = "ipywidgets" }, + { name = "jupyter-console" }, + { name = "jupyterlab" }, + { name = "nbconvert" }, + { name = "notebook" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/58/f3/af28ea964ab8bc1e472dba2e82627d36d470c51f5cd38c37502eeffaa25e/jupyter-1.1.1.tar.gz", hash = "sha256:d55467bceabdea49d7e3624af7e33d59c37fff53ed3a350e1ac957bed731de7a", size = 5714959, upload-time = "2024-08-30T07:15:48.299Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/38/64/285f20a31679bf547b75602702f7800e74dbabae36ef324f716c02804753/jupyter-1.1.1-py2.py3-none-any.whl", hash = "sha256:7a59533c22af65439b24bbe60373a4e95af8f16ac65a6c00820ad378e3f7cc83", size = 2657, upload-time = "2024-08-30T07:15:47.045Z" }, +] + +[[package]] +name = "jupyter-builder" +version = "1.2.3" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "jupyter-core" }, + { name = "traitlets" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/75/3e/56f593e6a664cd14d441724654ce8243f3cac7d3e45867cf084749c8bc75/jupyter_builder-1.2.3.tar.gz", hash = "sha256:01aba6794eb9b19e0e29ae21137ca60ba4135c70347d4b9f664a586822b8c809", size = 1024218, upload-time = "2026-09-04T18:54:09.411Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/84/aa/be79e87c50698673f196d0633fc1664607da2289f9688d1de7a1c9db9e71/jupyter_builder-1.2.3-py3-none-any.whl", hash = "sha256:c5ea5a7190c2a7b082494abade98eece1b2b5bd5dbd7d610606cbcd10a1d08b3", size = 947541, upload-time = "2026-09-04T18:54:07.644Z" }, +] + +[[package]] +name = "jupyter-client" +version = "8.10.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "jupyter-core" }, + { name = "python-dateutil" }, + { name = "pyzmq" }, + { name = "tornado" }, + { name = "traitlets" }, + { name = "typing-extensions" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/c5/2a/906772148a06e48885039e0250c340b770a55bbf37b08d6ee0449df369c3/jupyter_client-8.10.0.tar.gz", hash = "sha256:9f7116294dca55f1785be880057d44544db9b1567718d92cb33c58886afb9497", size = 360653, upload-time = "2026-08-28T12:17:10.854Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/0f/88/7c548de1f6c2ade7c931a3282da73f9274fa6a1531091be682f89c85efb9/jupyter_client-8.10.0-py3-none-any.whl", hash = "sha256:5f73f24f22fa25192cfff6b23c051932a2473a797b05734aff495b392103e14e", size = 110184, upload-time = "2026-08-28T12:17:09.028Z" }, +] + +[[package]] +name = "jupyter-console" +version = "6.6.3" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "ipykernel" }, + { name = "ipython" }, + { name = "jupyter-client" }, + { name = "jupyter-core" }, + { name = "prompt-toolkit" }, + { name = "pygments" }, + { name = "pyzmq" }, + { name = "traitlets" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/bd/2d/e2fd31e2fc41c14e2bcb6c976ab732597e907523f6b2420305f9fc7fdbdb/jupyter_console-6.6.3.tar.gz", hash = "sha256:566a4bf31c87adbfadf22cdf846e3069b59a71ed5da71d6ba4d8aaad14a53539", size = 34363, upload-time = "2023-03-06T14:13:31.02Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/ca/77/71d78d58f15c22db16328a476426f7ac4a60d3a5a7ba3b9627ee2f7903d4/jupyter_console-6.6.3-py3-none-any.whl", hash = "sha256:309d33409fcc92ffdad25f0bcdf9a4a9daa61b6f341177570fdac03de5352485", size = 24510, upload-time = "2023-03-06T14:13:28.229Z" }, +] + +[[package]] +name = "jupyter-core" +version = "5.9.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "platformdirs" }, + { name = "traitlets" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/02/49/9d1284d0dc65e2c757b74c6687b6d319b02f822ad039e5c512df9194d9dd/jupyter_core-5.9.1.tar.gz", hash = "sha256:4d09aaff303b9566c3ce657f580bd089ff5c91f5f89cf7d8846c3cdf465b5508", size = 89814, upload-time = "2025-10-16T19:19:18.444Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/e7/e7/80988e32bf6f73919a113473a604f5a8f09094de312b9d52b79c2df7612b/jupyter_core-5.9.1-py3-none-any.whl", hash = "sha256:ebf87fdc6073d142e114c72c9e29a9d7ca03fad818c5d300ce2adc1fb0743407", size = 29032, upload-time = "2025-10-16T19:19:16.783Z" }, +] + +[[package]] +name = "jupyter-events" +version = "0.12.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "jsonschema", extra = ["format-nongpl"] }, + { name = "packaging" }, + { name = "python-json-logger" }, + { name = "pyyaml" }, + { name = "referencing" }, + { name = "rfc3339-validator" }, + { name = "rfc3986-validator" }, + { name = "traitlets" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/18/f8/475c4241b2b75af0deaae453ed003c6c851766dbc44d332d8baf245dc931/jupyter_events-0.12.1.tar.gz", hash = "sha256:faff25f77218335752f35f23c5fe6e4a392a7bd99a5939ccb9b8fbf594636cf3", size = 62854, upload-time = "2026-04-20T23:17:50.66Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/eb/6c/6fcde0c8f616ed360ffd3587f7db9e225a7e62b583a04494d2f069cf64ea/jupyter_events-0.12.1-py3-none-any.whl", hash = "sha256:c366585253f537a627da52fa7ca7410c5b5301fe893f511e7b077c2d93ec8bcf", size = 19512, upload-time = "2026-04-20T23:17:48.927Z" }, +] + +[[package]] +name = "jupyter-lsp" +version = "2.3.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "jupyter-server" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/36/ff/1e4a61f5170a9a1d978f3ac3872449de6c01fc71eaf89657824c878b1549/jupyter_lsp-2.3.1.tar.gz", hash = "sha256:fdf8a4aa7d85813976d6e29e95e6a2c8f752701f926f2715305249a3829805a6", size = 55677, upload-time = "2026-04-02T08:10:06.749Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/23/e8/9d61dcbd1dce8ef418f06befd4ac084b4720429c26b0b1222bc218685eff/jupyter_lsp-2.3.1-py3-none-any.whl", hash = "sha256:71b954d834e85ff3096400554f2eefaf7fe37053036f9a782b0f7c5e42dadb81", size = 77513, upload-time = "2026-04-02T08:10:01.753Z" }, +] + +[[package]] +name = "jupyter-server" +version = "2.21.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "anyio" }, + { name = "argon2-cffi" }, + { name = "jinja2" }, + { name = "jupyter-client" }, + { name = "jupyter-core" }, + { name = "jupyter-events" }, + { name = "jupyter-server-terminals" }, + { name = "nbconvert" }, + { name = "nbformat" }, + { name = "overrides", marker = "python_full_version < '3.12'" }, + { name = "packaging" }, + { name = "prometheus-client" }, + { name = "pywinpty", marker = "os_name == 'nt'" }, + { name = "pyzmq" }, + { name = "send2trash" }, + { name = "terminado" }, + { name = "tornado" }, + { name = "traitlets" }, + { name = "websocket-client" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/cf/e0/63b481d5b21f81fe23173dfc9eb25629fa1bc174fdc4a2c19d09c1ff8124/jupyter_server-2.21.0.tar.gz", hash = "sha256:70d9a1883f57d3576ea17f4ce061ec1a7aad7ef388d00428cfb7f5e4f0022271", size = 760357, upload-time = "2026-08-27T16:06:34.049Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/cb/8a/cb97c2b353cb46cced413be8f742fa8fcd3cb1659524f27314494aa94968/jupyter_server-2.21.0-py3-none-any.whl", hash = "sha256:2ae2e5ce5e97268553e25aebe040197455673d925b5fc7995477153318160cf7", size = 393961, upload-time = "2026-08-27T16:06:31.814Z" }, +] + +[[package]] +name = "jupyter-server-terminals" +version = "0.5.4" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "pywinpty", marker = "os_name == 'nt'" }, + { name = "terminado" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/f4/a7/bcd0a9b0cbba88986fe944aaaf91bfda603e5a50bda8ed15123f381a3b2f/jupyter_server_terminals-0.5.4.tar.gz", hash = "sha256:bbda128ed41d0be9020349f9f1f2a4ab9952a73ed5f5ac9f1419794761fb87f5", size = 31770, upload-time = "2026-01-14T16:53:20.213Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/d1/2d/6674563f71c6320841fc300911a55143925112a72a883e2ca71fba4c618d/jupyter_server_terminals-0.5.4-py3-none-any.whl", hash = "sha256:55be353fc74a80bc7f3b20e6be50a55a61cd525626f578dcb66a5708e2007d14", size = 13704, upload-time = "2026-01-14T16:53:18.738Z" }, +] + +[[package]] +name = "jupyterlab" +version = "4.6.3" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "async-lru" }, + { name = "httpx" }, + { name = "ipykernel" }, + { name = "jinja2" }, + { name = "jupyter-builder" }, + { name = "jupyter-core" }, + { name = "jupyter-lsp" }, + { name = "jupyter-server" }, + { name = "jupyterlab-server" }, + { name = "notebook-shim" }, + { name = "packaging" }, + { name = "tornado" }, + { name = "traitlets" }, + { name = "typing-extensions", marker = "python_full_version < '3.12'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/00/c0/45934229995d4c6e38192ca118d93185f60808f64157e3df3c5c28f8c5fd/jupyterlab-4.6.3.tar.gz", hash = "sha256:2e3db6e3a12495ebd188276e985bf5ac502fbde3d1e8628819920210008de498", size = 28319771, upload-time = "2026-08-10T18:50:57.947Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/e9/47/242f46de028074651c9bd6d8000fc340ed0d3cdd1a0eae4387826123413a/jupyterlab-4.6.3-py3-none-any.whl", hash = "sha256:0a1ebc6567186f1eabd99536e94df7ed9e96d1e7c5ddf3e4406ae16e88abacb7", size = 17168312, upload-time = "2026-08-10T18:50:53.044Z" }, +] + +[[package]] +name = "jupyterlab-pygments" +version = "0.3.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/90/51/9187be60d989df97f5f0aba133fa54e7300f17616e065d1ada7d7646b6d6/jupyterlab_pygments-0.3.0.tar.gz", hash = "sha256:721aca4d9029252b11cfa9d185e5b5af4d54772bb8072f9b7036f4170054d35d", size = 512900, upload-time = "2023-11-23T09:26:37.44Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/b1/dd/ead9d8ea85bf202d90cc513b533f9c363121c7792674f78e0d8a854b63b4/jupyterlab_pygments-0.3.0-py3-none-any.whl", hash = "sha256:841a89020971da1d8693f1a99997aefc5dc424bb1b251fd6322462a1b8842780", size = 15884, upload-time = "2023-11-23T09:26:34.325Z" }, +] + +[[package]] +name = "jupyterlab-server" +version = "2.28.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "babel" }, + { name = "jinja2" }, + { name = "json5" }, + { name = "jsonschema" }, + { name = "jupyter-server" }, + { name = "packaging" }, + { name = "requests" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/d6/2c/90153f189e421e93c4bb4f9e3f59802a1f01abd2ac5cf40b152d7f735232/jupyterlab_server-2.28.0.tar.gz", hash = "sha256:35baa81898b15f93573e2deca50d11ac0ae407ebb688299d3a5213265033712c", size = 76996, upload-time = "2025-10-22T13:59:18.37Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/e0/07/a000fe835f76b7e1143242ab1122e6362ef1c03f23f83a045c38859c2ae0/jupyterlab_server-2.28.0-py3-none-any.whl", hash = "sha256:e4355b148fdcf34d312bbbc80f22467d6d20460e8b8736bf235577dd18506968", size = 59830, upload-time = "2025-10-22T13:59:16.767Z" }, ] [[package]] -name = "jsonschema" -version = "4.26.0" +name = "jupyterlab-widgets" +version = "3.0.17" source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "attrs" }, - { name = "jsonschema-specifications" }, - { name = "referencing" }, - { name = "rpds-py" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/b3/fc/e067678238fa451312d4c62bf6e6cf5ec56375422aee02f9cb5f909b3047/jsonschema-4.26.0.tar.gz", hash = "sha256:0c26707e2efad8aa1bfc5b7ce170f3fccc2e4918ff85989ba9ffa9facb2be326", size = 366583, upload-time = "2026-01-07T13:41:07.246Z" } +sdist = { url = "https://files.pythonhosted.org/packages/21/8b/e739cf9066ad5037a2d4b0a403f06da374fdccb9748221661c8b492d3dbc/jupyterlab_widgets-3.0.17.tar.gz", hash = "sha256:6e61fe21ca8a66039180a5cc52a433e07279d2fee79c8be963e00d55193f17a8", size = 213919, upload-time = "2026-08-18T08:52:17.511Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/69/90/f63fb5873511e014207a475e2bb4e8b2e570d655b00ac19a9a0ca0a385ee/jsonschema-4.26.0-py3-none-any.whl", hash = "sha256:d489f15263b8d200f8387e64b4c3a75f06629559fb73deb8fdfb525f2dab50ce", size = 90630, upload-time = "2026-01-07T13:41:05.306Z" }, + { url = "https://files.pythonhosted.org/packages/33/ef/6d27fc118f58cb24886da413545a7efb0853d405fddbfd8b2d9ac09fbed4/jupyterlab_widgets-3.0.17-py3-none-any.whl", hash = "sha256:40ac1e9955acf116c4d995d9bfa082d86ad9ec6d91c4f134827cf5e0a5eb75e0", size = 217292, upload-time = "2026-08-18T08:52:15.47Z" }, ] [[package]] -name = "jsonschema-specifications" -version = "2025.9.1" +name = "lark" +version = "1.3.1" source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "referencing" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/19/74/a633ee74eb36c44aa6d1095e7cc5569bebf04342ee146178e2d36600708b/jsonschema_specifications-2025.9.1.tar.gz", hash = "sha256:b540987f239e745613c7a9176f3edb72b832a4ac465cf02712288397832b5e8d", size = 32855, upload-time = "2025-09-08T01:34:59.186Z" } +sdist = { url = "https://files.pythonhosted.org/packages/da/34/28fff3ab31ccff1fd4f6c7c7b0ceb2b6968d8ea4950663eadcb5720591a0/lark-1.3.1.tar.gz", hash = "sha256:b426a7a6d6d53189d318f2b6236ab5d6429eaf09259f1ca33eb716eed10d2905", size = 382732, upload-time = "2025-10-27T18:25:56.653Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/41/45/1a4ed80516f02155c51f51e8cedb3c1902296743db0bbc66608a0db2814f/jsonschema_specifications-2025.9.1-py3-none-any.whl", hash = "sha256:98802fee3a11ee76ecaca44429fda8a41bff98b00a0f2838151b113f210cc6fe", size = 18437, upload-time = "2025-09-08T01:34:57.871Z" }, + { url = "https://files.pythonhosted.org/packages/82/3d/14ce75ef66813643812f3093ab17e46d3a206942ce7376d31ec2d36229e7/lark-1.3.1-py3-none-any.whl", hash = "sha256:c629b661023a014c37da873b4ff58a817398d12635d3bbb2c5a03be7fe5d1e12", size = 113151, upload-time = "2025-10-27T18:25:54.882Z" }, ] [[package]] @@ -1122,6 +1751,18 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/70/bc/6f1c2f612465f5fa89b95bead1f44dcb607670fd42891d8fdcd5d039f4f4/markupsafe-3.0.3-cp314-cp314t-win_arm64.whl", hash = "sha256:32001d6a8fc98c8cb5c947787c5d08b0a50663d139f1305bac5885d98d9b40fa", size = 14146, upload-time = "2025-09-27T18:37:28.327Z" }, ] +[[package]] +name = "matplotlib-inline" +version = "0.2.2" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "traitlets" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/bd/c0/9f7c9a46090390368a4d7bcb76bb87a4a36c421e4c0792cdb53486ffac7a/matplotlib_inline-0.2.2.tar.gz", hash = "sha256:72f3fe8fce36b70d4a5b612f899090cd0401deddc4ea90e1572b9f4bfb058c79", size = 8150, upload-time = "2026-05-08T17:33:33.49Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/41/09/5b161152e2d90f7b87f781c2e1267494aef9c32498df793f73ad0a0a494a/matplotlib_inline-0.2.2-py3-none-any.whl", hash = "sha256:3c821cf1c209f59fb2d2d64abbf5b23b67bcb2210d663f9918dd851c6da1fcf6", size = 9534, upload-time = "2026-05-08T17:33:32.055Z" }, +] + [[package]] name = "mdit-py-plugins" version = "0.6.1" @@ -1144,21 +1785,21 @@ wheels = [ ] [[package]] -name = "mpmath" -version = "1.3.0" +name = "mistune" +version = "3.3.4" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/e0/47/dd32fa426cc72114383ac549964eecb20ecfd886d1e5ccf5340b55b02f57/mpmath-1.3.0.tar.gz", hash = "sha256:7a28eb2a9774d00c7bc92411c19a89209d5da7c4c9a9e227be8330a23a25b91f", size = 508106, upload-time = "2023-03-07T16:47:11.061Z" } +sdist = { url = "https://files.pythonhosted.org/packages/7b/92/328a294a6de83bacb95bed01f04e0eaff4e3616ee359fc821a5dfc539b02/mistune-3.3.4.tar.gz", hash = "sha256:58b5c96d6fcb61190dfe5fae498d2b2065f99cf61e9649418fd54cf1ada86dfe", size = 121426, upload-time = "2026-07-22T05:22:30.89Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/43/e3/7d92a15f894aa0c9c4b49b8ee9ac9850d6e63b03c9c32c0367a13ae62209/mpmath-1.3.0-py3-none-any.whl", hash = "sha256:a0b2b9fe80bbcd81a6647ff13108738cfb482d481d826cc0e02f5b35e5c88d2c", size = 536198, upload-time = "2023-03-07T16:47:09.197Z" }, + { url = "https://files.pythonhosted.org/packages/77/e4/288365afae98953bc01de09f686f40d8ee84578135aa7767d5d4e60b5278/mistune-3.3.4-py3-none-any.whl", hash = "sha256:ee015381e955e370962968befe1d729ab60fafb6a715ac6751763fbce38c8d4a", size = 66862, upload-time = "2026-07-22T05:22:29.419Z" }, ] [[package]] -name = "mypy-extensions" -version = "1.1.0" +name = "mpmath" +version = "1.3.0" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/a2/6e/371856a3fb9d31ca8dac321cda606860fa4548858c0cc45d9d1d4ca2628b/mypy_extensions-1.1.0.tar.gz", hash = "sha256:52e68efc3284861e772bbcd66823fde5ae21fd2fdb51c62a211403730b916558", size = 6343, upload-time = "2025-04-22T14:54:24.164Z" } +sdist = { url = "https://files.pythonhosted.org/packages/e0/47/dd32fa426cc72114383ac549964eecb20ecfd886d1e5ccf5340b55b02f57/mpmath-1.3.0.tar.gz", hash = "sha256:7a28eb2a9774d00c7bc92411c19a89209d5da7c4c9a9e227be8330a23a25b91f", size = 508106, upload-time = "2023-03-07T16:47:11.061Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/79/7b/2c79738432f5c924bef5071f933bcc9efd0473bac3b4aa584a6f7c1c8df8/mypy_extensions-1.1.0-py3-none-any.whl", hash = "sha256:1be4cccdb0f2482337c4743e60421de3a356cd97508abadd57d47403e94f5505", size = 4963, upload-time = "2025-04-22T14:54:22.983Z" }, + { url = "https://files.pythonhosted.org/packages/43/e3/7d92a15f894aa0c9c4b49b8ee9ac9850d6e63b03c9c32c0367a13ae62209/mpmath-1.3.0-py3-none-any.whl", hash = "sha256:a0b2b9fe80bbcd81a6647ff13108738cfb482d481d826cc0e02f5b35e5c88d2c", size = 536198, upload-time = "2023-03-07T16:47:09.197Z" }, ] [[package]] @@ -1170,6 +1811,99 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/40/b5/1b84b2c784db76d69442334bc8b8748c840f13ca53be086f4f250ad4a0bc/narwhals-2.26.0-py3-none-any.whl", hash = "sha256:29326d74f107c347fd1009bd58e38d9f7c7c5b51e6de97bc93dbc325d9038b54", size = 474034, upload-time = "2026-09-08T13:32:07.159Z" }, ] +[[package]] +name = "nbclient" +version = "0.11.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "jupyter-client" }, + { name = "jupyter-core" }, + { name = "nbformat" }, + { name = "traitlets" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/28/a5/b3bae4b590c0cbcada2c63a34f7580024e834a8ba213e949a2f906705787/nbclient-0.11.0.tar.gz", hash = "sha256:04a134a5b087f2c5887f228aca155db50169b8cd9334dee6942c8e927e56081a", size = 62535, upload-time = "2026-06-05T07:52:41.746Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/36/c9/94d73e5a01c5b926c3fa2496e97d7a8dc28ed5a77c0b2ed712f1a62e6694/nbclient-0.11.0-py3-none-any.whl", hash = "sha256:ef7fa0d59d6e1d41103933d8a445a18d5de860ca6b613b87b8574accdb3c2895", size = 25288, upload-time = "2026-06-05T07:52:40.115Z" }, +] + +[[package]] +name = "nbconvert" +version = "7.17.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "beautifulsoup4" }, + { name = "bleach", extra = ["css"] }, + { name = "defusedxml" }, + { name = "jinja2" }, + { name = "jupyter-core" }, + { name = "jupyterlab-pygments" }, + { name = "markupsafe" }, + { name = "mistune" }, + { name = "nbclient" }, + { name = "nbformat" }, + { name = "packaging" }, + { name = "pandocfilters" }, + { name = "pygments" }, + { name = "traitlets" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/01/b1/708e53fe2e429c103c6e6e159106bcf0357ac41aa4c28772bd8402339051/nbconvert-7.17.1.tar.gz", hash = "sha256:34d0d0a7e73ce3cbab6c5aae8f4f468797280b01fd8bd2ca746da8569eddd7d2", size = 865311, upload-time = "2026-04-08T00:44:14.914Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/67/f8/bb0a9d5f46819c821dc1f004aa2cc29b1d91453297dbf5ff20470f00f193/nbconvert-7.17.1-py3-none-any.whl", hash = "sha256:aa85c087b435e7bf1ffd03319f658e285f2b89eccab33bc1ba7025495ab3e7c8", size = 261927, upload-time = "2026-04-08T00:44:12.845Z" }, +] + +[[package]] +name = "nbformat" +version = "5.11.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "fastjsonschema" }, + { name = "jsonschema" }, + { name = "jupyter-core" }, + { name = "traitlets" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/31/72/b3446efab8756e7df4b8ec587f8e611cb5a7249e4323db480802f1d3be04/nbformat-5.11.1.tar.gz", hash = "sha256:32d4521c68c6e7d5b29c76defaeed9f42ea733142b9b19f88277ce10390b9c4d", size = 147775, upload-time = "2026-08-17T08:10:51.942Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/1a/69/ee613f74085ca7103f79cd08d579c4f3177d1d26e5d3d9528d2d6536a707/nbformat-5.11.1-py3-none-any.whl", hash = "sha256:cc6698fa75f4fab8755ead786317815f13a6fee3b53311c0abb1a8b51d52f7ec", size = 79849, upload-time = "2026-08-17T08:10:50.18Z" }, +] + +[[package]] +name = "nest-asyncio2" +version = "1.7.2" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/b4/73/731debf26e27e0a0323d7bda270dc2f634b398e38f040a09da1f4351d0aa/nest_asyncio2-1.7.2.tar.gz", hash = "sha256:1921d70b92cc4612c374928d081552efb59b83d91b2b789d935c665fa01729a8", size = 14743, upload-time = "2026-02-13T00:34:04.386Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/c5/3c/3179b85b0e1c3659f0369940200cd6d0fa900e6cefcc7ea0bc6dd0e29ffb/nest_asyncio2-1.7.2-py3-none-any.whl", hash = "sha256:f5dfa702f3f81f6a03857e9a19e2ba578c0946a4ad417b4c50a24d7ba641fe01", size = 7843, upload-time = "2026-02-13T00:34:02.691Z" }, +] + +[[package]] +name = "notebook" +version = "7.6.2" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "jupyter-builder" }, + { name = "jupyter-server" }, + { name = "jupyterlab" }, + { name = "jupyterlab-server" }, + { name = "notebook-shim" }, + { name = "tornado" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/31/d9/5c76de84e96e1cf8aae3fce930875e0615e14f3557bbcdb634aab52da9d3/notebook-7.6.2.tar.gz", hash = "sha256:cc02b5f0bb972160cccfe44ad8a1a202036206ba3439469c514f03aefa9ae807", size = 5500147, upload-time = "2026-08-11T13:21:16.632Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/5c/fd/3e552ff5b24dd305c6e9a10e8645e29c03091c317429f326ae10dbae1ac6/notebook-7.6.2-py3-none-any.whl", hash = "sha256:5fe9e09c335cb4b7de21627b860f77210e70e54b1fb1276ad942a4a7e1d858d3", size = 5547102, upload-time = "2026-08-11T13:21:13.302Z" }, +] + +[[package]] +name = "notebook-shim" +version = "0.2.4" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "jupyter-server" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/54/d2/92fa3243712b9a3e8bafaf60aac366da1cada3639ca767ff4b5b3654ec28/notebook_shim-0.2.4.tar.gz", hash = "sha256:b4b2cfa1b65d98307ca24361f5b30fe785b53c3fd07b7a47e89acb5e6ac638cb", size = 13167, upload-time = "2024-02-14T23:35:18.353Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/f9/33/bd5b9137445ea4b680023eb0469b2bb969d61303dedb2aac6560ff3d14a1/notebook_shim-0.2.4-py3-none-any.whl", hash = "sha256:411a5be4e9dc882a074ccbcae671eda64cceb068767e9a3419096986560e1cef", size = 13307, upload-time = "2024-02-14T23:35:16.286Z" }, +] + [[package]] name = "numpy" version = "2.4.6" @@ -1573,6 +2307,15 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/82/56/630c9113ec8996778f1f0304b364b091b9a9db5fef5fdc17cca622f5ea24/orjson-3.12.0-cp315-cp315-win_arm64.whl", hash = "sha256:859fc4196855890150bb08e649b30d2c93b249b3e3edd0d3bb2231abf8aa8adc", size = 126754, upload-time = "2026-08-14T16:13:28.962Z" }, ] +[[package]] +name = "overrides" +version = "7.7.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/36/86/b585f53236dec60aba864e050778b25045f857e17f6e5ea0ae95fe80edd2/overrides-7.7.0.tar.gz", hash = "sha256:55158fa3d93b98cc75299b1e67078ad9003ca27945c76162c1c0766d6f91820a", size = 22812, upload-time = "2024-01-27T21:01:33.423Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/2c/ab/fc8290c6a4c722e5514d80f62b2dc4c4df1a68a41d1364e625c35990fcf3/overrides-7.7.0-py3-none-any.whl", hash = "sha256:c7ed9d062f78b8e4c1a7b70bd8796b35ead4d9f510227ef9c5dc7626c60d7e49", size = 17832, upload-time = "2024-01-27T21:01:31.393Z" }, +] + [[package]] name = "packaging" version = "26.3" @@ -1638,12 +2381,118 @@ wheels = [ ] [[package]] -name = "pathspec" -version = "1.1.1" +name = "pandocfilters" +version = "1.5.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/70/6f/3dd4940bbe001c06a65f88e36bad298bc7a0de5036115639926b0c5c0458/pandocfilters-1.5.1.tar.gz", hash = "sha256:002b4a555ee4ebc03f8b66307e287fa492e4a77b4ea14d3f934328297bb4939e", size = 8454, upload-time = "2024-01-18T20:08:13.726Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/ef/af/4fbc8cab944db5d21b7e2a5b8e9211a03a79852b1157e2c102fcc61ac440/pandocfilters-1.5.1-py2.py3-none-any.whl", hash = "sha256:93be382804a9cdb0a7267585f157e5d1731bbe5545a85b268d6f5fe6232de2bc", size = 8663, upload-time = "2024-01-18T20:08:11.28Z" }, +] + +[[package]] +name = "parso" +version = "0.8.7" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/30/4b/90c937815137d43ce71ba043cd3566221e9df6b9c805f24b5d138c9d40a7/parso-0.8.7.tar.gz", hash = "sha256:eaaac4c9fdd5e9e8852dc778d2d7405897ec510f2a298071453e5e3a07914bb1", size = 401824, upload-time = "2026-05-01T23:13:02.138Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/99/5d/8268b644392ee874ee82a635cd0df1773de230bde356c38de28e298392cc/parso-0.8.7-py2.py3-none-any.whl", hash = "sha256:a8926eb2a1b915486941fdbd31e86a4baf88fe8c210f25f2f35ecec5b574ca1c", size = 107025, upload-time = "2026-05-01T23:12:58.867Z" }, +] + +[[package]] +name = "pexpect" +version = "4.9.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "ptyprocess" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/42/92/cc564bf6381ff43ce1f4d06852fc19a2f11d180f23dc32d9588bee2f149d/pexpect-4.9.0.tar.gz", hash = "sha256:ee7d41123f3c9911050ea2c2dac107568dc43b2d3b0c7557a33212c398ead30f", size = 166450, upload-time = "2023-11-25T09:07:26.339Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/9e/c3/059298687310d527a58bb01f3b1965787ee3b40dce76752eda8b44e9a2c5/pexpect-4.9.0-py2.py3-none-any.whl", hash = "sha256:7236d1e080e4936be2dc3e326cec0af72acf9212a7e1d060210e70a47e253523", size = 63772, upload-time = "2023-11-25T06:56:14.81Z" }, +] + +[[package]] +name = "pillow" +version = "12.3.0" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/5a/82/42f767fc1c1143d6fd36efb827202a2d997a375e160a71eb2888a925aac1/pathspec-1.1.1.tar.gz", hash = "sha256:17db5ecd524104a120e173814c90367a96a98d07c45b2e10c2f3919fff91bf5a", size = 135180, upload-time = "2026-04-27T01:46:08.907Z" } +sdist = { url = "https://files.pythonhosted.org/packages/1c/3d/bb7fca845737cf9d7dbde16ed1843984665ff2e0a518f5db43e77ec540b9/pillow-12.3.0.tar.gz", hash = "sha256:3b8182a766685eaa002637e28b4ec8d6b18819a0c71f579bf0dbaa5830297cce", size = 47025035, upload-time = "2026-07-01T11:56:38.965Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/f1/d9/7fb5aa316bc299258e68c73ba3bddbc499654a07f151cba08f6153988714/pathspec-1.1.1-py3-none-any.whl", hash = "sha256:a00ce642f577bf7f473932318056212bc4f8bfdf53128c78bbd5af0b9b20b189", size = 57328, upload-time = "2026-04-27T01:46:07.06Z" }, + { url = "https://files.pythonhosted.org/packages/fb/c8/0a78b0e02d7ac54bc03e5321c9220da52f0c2ea83b21f7c40e7f3169c502/pillow-12.3.0-cp311-cp311-macosx_10_10_x86_64.whl", hash = "sha256:00808c5e14ef63ac5161091d242999076604ff74b883423a11e5d7bbb38bf756", size = 5392415, upload-time = "2026-07-01T11:53:47.162Z" }, + { url = "https://files.pythonhosted.org/packages/b2/5b/a02d30018abd97ced9f5a6c63d28597694a00d066516b9c1c6de45859fc9/pillow-12.3.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:37d6d0a00072fd2948eb22bce7e1475f34569d90c87c59f7a2ec59541b77f7a6", size = 4785266, upload-time = "2026-07-01T11:53:49.079Z" }, + { url = "https://files.pythonhosted.org/packages/c8/98/766667a4be768150a202836acd9fad19c06824ca86c4286d3cf6b274964e/pillow-12.3.0-cp311-cp311-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:bcb46e2f9feff8d06323983bd83ed00c201fdcab3d74973e7072a889b3979fcd", size = 6263814, upload-time = "2026-07-01T11:53:51.32Z" }, + { url = "https://files.pythonhosted.org/packages/3b/2d/ede717bc1144f63886c21fd349bb95860b0d1a21149ff16f2bb362b612b6/pillow-12.3.0-cp311-cp311-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:23d27a3e0307ec2244cc51e7287b919aa68d097504ebe19df4e76a98a3eea5bd", size = 6934408, upload-time = "2026-07-01T11:53:53.487Z" }, + { url = "https://files.pythonhosted.org/packages/a3/48/9c58b685e69d49c31af6c8eb9012055fab7e665785165c84796e2c73ce72/pillow-12.3.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:4f883547d4b7f0495ebe7056b0cc2aea76094e7a4abc8e933540f3271df27d9c", size = 6337160, upload-time = "2026-07-01T11:53:55.457Z" }, + { url = "https://files.pythonhosted.org/packages/ff/fa/dc2a5c0ba6df93f67c31d34b808b7ce440b40cdbf96f0b81cde1d1e6fa93/pillow-12.3.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:236ff70b9312fb68943c703aa842ca6a758abfa45ac187a5e7c1452e96ef72b5", size = 7045172, upload-time = "2026-07-01T11:53:57.736Z" }, + { url = "https://files.pythonhosted.org/packages/86/a5/444817a4d4c4c2417df00513086ca196f388d8f9ef40c2e4ccd1ad1af54b/pillow-12.3.0-cp311-cp311-win32.whl", hash = "sha256:10e41f0fbf1eec8cfd234b8fe17a4caac7c9d0db4c204d3c173a8f9f6ef3232b", size = 6472232, upload-time = "2026-07-01T11:53:59.767Z" }, + { url = "https://files.pythonhosted.org/packages/63/c6/4bad1b18d132a50b27e1365e1ab163616f7a5bb56d330f66f9d1d9d4f9d4/pillow-12.3.0-cp311-cp311-win_amd64.whl", hash = "sha256:8e95e1385e4998ae9694eeaa4730ba5457ff61185b3a55e2e7bea0880aef452a", size = 7233653, upload-time = "2026-07-01T11:54:02.066Z" }, + { url = "https://files.pythonhosted.org/packages/fd/16/00f91ab7760dc842f5aad55217e80fc4a7067a0604535249bc8a2d6d9870/pillow-12.3.0-cp311-cp311-win_arm64.whl", hash = "sha256:ebaea975e03d3141d9d3a507df75c9b3ec90fa9d2ffd07567b3a978d9d790b26", size = 2568195, upload-time = "2026-07-01T11:54:04.622Z" }, + { url = "https://files.pythonhosted.org/packages/37/bf/fb3ebff8ddcb76aac5a01389251bbbb9519922a9b520d8247c1ca864a25d/pillow-12.3.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:ba09209fbe443b4acccebe845d8a138b89a8f4fbaeedd44953490b5315d5e965", size = 5345969, upload-time = "2026-07-01T11:54:06.397Z" }, + { url = "https://files.pythonhosted.org/packages/d8/66/9a386a92561f402389a4fc70c18838bf6d35eb5eb5c6850b4b2dc64f5048/pillow-12.3.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:ffd0c5368496f41b0944be820fcb7a838aa6e623d250b01acf2643939c3f99d7", size = 4780323, upload-time = "2026-07-01T11:54:09.351Z" }, + { url = "https://files.pythonhosted.org/packages/25/27/ac8f99618ffd3dde21db0f4d4b1d2ab00c0880595bfd17df103f7f39fd0c/pillow-12.3.0-cp312-cp312-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:d9c7f76c0673154f044e9d78c8655fb4213f6ca31a836df48b40fe5d187717b9", size = 6266838, upload-time = "2026-07-01T11:54:11.71Z" }, + { url = "https://files.pythonhosted.org/packages/84/21/a35af28dcc61f37ed850a2d64c65c701321dfbf25085e469d5559360cbbf/pillow-12.3.0-cp312-cp312-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:78cb2c6865a35ab8ff8b75fd122f6033b92a62c82801110e48ddd6c936a45d91", size = 6940830, upload-time = "2026-07-01T11:54:13.732Z" }, + { url = "https://files.pythonhosted.org/packages/eb/51/8b08617af3ad95e33ce6d7dd2c99ed6c8298f7fb131636303956be022e25/pillow-12.3.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:e491916b378fba47242221bb9ead245211b70d504f495d105d17b14a24b4907c", size = 6344383, upload-time = "2026-07-01T11:54:15.756Z" }, + { url = "https://files.pythonhosted.org/packages/1d/72/cf78ac9780bb93c28328f408973845a309d4d145041665f734572ced1b52/pillow-12.3.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:0dd2064cbc55aaec028ef5fbb60fa47bb6c3e7918e07ff17935284b227a9d2df", size = 7052934, upload-time = "2026-07-01T11:54:17.721Z" }, + { url = "https://files.pythonhosted.org/packages/20/20/25e0f4dc178a6bc0696793720055519a0de89e7661dae886992decbd2f81/pillow-12.3.0-cp312-cp312-win32.whl", hash = "sha256:dbce0b29841537a2fa4a214c2bbf14de3587c9680caa9b4e217568472490b28f", size = 6472684, upload-time = "2026-07-01T11:54:19.839Z" }, + { url = "https://files.pythonhosted.org/packages/45/89/da2f7971a317f83d807fdd4065c0af40208e59e692cc43d315a71a0e96d1/pillow-12.3.0-cp312-cp312-win_amd64.whl", hash = "sha256:a2b55dd6b2a4c4b7d87ffa56bdb33fdc5fdb9a462173861a7bc097f17d91cb09", size = 7227137, upload-time = "2026-07-01T11:54:22.025Z" }, + { url = "https://files.pythonhosted.org/packages/de/47/4845a0a6c0dbf1db8456bd9fc791f13c5ced7ced20606d08a0aacfd25b49/pillow-12.3.0-cp312-cp312-win_arm64.whl", hash = "sha256:331b624368d4f1d069149002f25f44bc61c8919ce8ddb3c45bdad8f6e2d89510", size = 2568267, upload-time = "2026-07-01T11:54:24.051Z" }, + { url = "https://files.pythonhosted.org/packages/9d/ac/31fb64e1e7efb5a4b50cd3d92049ba89ac6e4d8d3bb6a74e15048ca3353e/pillow-12.3.0-cp313-cp313-ios_13_0_arm64_iphoneos.whl", hash = "sha256:21900ce7ba264168cd50defae43cd75d25c833ad4ad6e73ffc5596d12e25ac89", size = 4161684, upload-time = "2026-07-01T11:54:25.934Z" }, + { url = "https://files.pythonhosted.org/packages/87/b4/9805e23d2b4d77842b468513841fda254ee42f0289d25088340e4ff46e2d/pillow-12.3.0-cp313-cp313-ios_13_0_arm64_iphonesimulator.whl", hash = "sha256:4e8c2a84d977f50b9daed6eeaf3baef67d00d5d74d932288f02cb94518ee3ace", size = 4255487, upload-time = "2026-07-01T11:54:27.935Z" }, + { url = "https://files.pythonhosted.org/packages/df/39/ecf519435a200c693fe053a6ee4d835b41cf963a4dfc2551c4e637cb2a71/pillow-12.3.0-cp313-cp313-ios_13_0_x86_64_iphonesimulator.whl", hash = "sha256:ae26d61dfa7a47befdc7572b521024e8745f3d809bd95ca9505a7bba9ef849ec", size = 3696433, upload-time = "2026-07-01T11:54:29.813Z" }, + { url = "https://files.pythonhosted.org/packages/42/92/2fc3ffad878ae8dd5469ec1bc8eb83b71f48e13efdf68f02709003982a32/pillow-12.3.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:7a743ff716f746fc19a9557f60dab1600d4613255f8a7aeb3cdde4db7eb15a66", size = 5345889, upload-time = "2026-07-01T11:54:31.97Z" }, + { url = "https://files.pythonhosted.org/packages/10/76/8803c13605b763d33d156c4678fc77f8443389c0c51c8aef707bb02015f4/pillow-12.3.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:d69141514cc30b774ceea5e3ed3a6635c8d8a96edf664689b890f4089111fb35", size = 4780109, upload-time = "2026-07-01T11:54:34.026Z" }, + { url = "https://files.pythonhosted.org/packages/1f/01/e18aff37cb0b4aac47ac90f016d347a49aca667ef97f190b06ac2aabc928/pillow-12.3.0-cp313-cp313-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:f7401aebd7f581d7f83a439d87d474999317ee099218e5ad25d125290990ba65", size = 6263736, upload-time = "2026-07-01T11:54:36.131Z" }, + { url = "https://files.pythonhosted.org/packages/f7/62/de5bdd77d935331f4f802edc11e4d82950f642caad6cb2f949837b8560e2/pillow-12.3.0-cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:0847a763afefb695bc912d7c131e7e0632d4edc1d8698f58ddabec8e46b8b6d3", size = 6937129, upload-time = "2026-07-01T11:54:38.216Z" }, + { url = "https://files.pythonhosted.org/packages/70/4d/105627a13300c5e0df1d174230b32fd1273062c96f7745fd552b945d1e1d/pillow-12.3.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:571b9fcb07b97ef3a492028fb3d2dc0993ca23a06138b0315286566d29ef718a", size = 6339562, upload-time = "2026-07-01T11:54:40.354Z" }, + { url = "https://files.pythonhosted.org/packages/6b/1d/f13de01a553988ab895ba1c722e06cf3144d4f57656fd5b81b6d881f1179/pillow-12.3.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:756c768d0c9c2955feb7a56c37ea24aea2e369f8d36a88da270b6a9f19e62b5e", size = 7049439, upload-time = "2026-07-01T11:54:42.489Z" }, + { url = "https://files.pythonhosted.org/packages/c9/f9/066794cca041b969964f779ee5fa66a9498bbf34248ac39c5d7954e4198f/pillow-12.3.0-cp313-cp313-win32.whl", hash = "sha256:a876864214e136f0eb367788dbd7df045f4806801518e2cfe9e13229cfe06d8f", size = 6473287, upload-time = "2026-07-01T11:54:44.9Z" }, + { url = "https://files.pythonhosted.org/packages/a6/9b/7a58e61d62be561da3a356fe2384d4059a6345fc130e23ef1c36a5b81d24/pillow-12.3.0-cp313-cp313-win_amd64.whl", hash = "sha256:1cca606cd25738df4ed873d5ad46bbdb3d83b5cbca291f6b4ff13a4df6b0bbe8", size = 7239691, upload-time = "2026-07-01T11:54:47.141Z" }, + { url = "https://files.pythonhosted.org/packages/aa/b0/c4ed4f0ef8f8fa5ee8351537db6650bb8189f7e118842978dd6589065692/pillow-12.3.0-cp313-cp313-win_arm64.whl", hash = "sha256:b629de27fda84b42cde7edef0d85f13b958b47f6e9bbcbba9b673c562a89bd8b", size = 2568185, upload-time = "2026-07-01T11:54:49.137Z" }, + { url = "https://files.pythonhosted.org/packages/dc/01/001f65b68192f0228cc1dbbc8d2530ab5d58b61037ba0587f946fea607cd/pillow-12.3.0-cp314-cp314-ios_13_0_arm64_iphoneos.whl", hash = "sha256:9cf95fe4d0f84c82d282745d9bb08ad9f926efa00be4697e767b814ce40d4330", size = 4161736, upload-time = "2026-07-01T11:54:51.156Z" }, + { url = "https://files.pythonhosted.org/packages/1a/d2/0219746d0fd16fc8a84498e79452375be3797d3ce4044596ce565164b84f/pillow-12.3.0-cp314-cp314-ios_13_0_arm64_iphonesimulator.whl", hash = "sha256:8728f216dcdb6e6d555cf971cb34076139ad74b31fc2c14da4fafc741c5f6217", size = 4255435, upload-time = "2026-07-01T11:54:53.414Z" }, + { url = "https://files.pythonhosted.org/packages/c8/02/8d0bc62ef0302318c46ff2a512822d2610e81c7aa46c9b3abe6cbaca5ad0/pillow-12.3.0-cp314-cp314-ios_13_0_x86_64_iphonesimulator.whl", hash = "sha256:a45650e8ce7fafffd731db8550230db6b0d306d181a90b67d3e6bca2f1990930", size = 3696262, upload-time = "2026-07-01T11:54:55.739Z" }, + { url = "https://files.pythonhosted.org/packages/85/e2/73c77d218410b14f5f2d565e8a998d5317b7b9c75368d29985139f7a46f0/pillow-12.3.0-cp314-cp314-macosx_10_15_x86_64.whl", hash = "sha256:ba54cfebe86920a559a7c4d6b9050791c20513650a1952ebe3368c7dc70306f8", size = 5350344, upload-time = "2026-07-01T11:54:57.657Z" }, + { url = "https://files.pythonhosted.org/packages/c7/da/32c752228ae345f489e3a42499d817b6c3996da7e8a3bc7a04fc806b243b/pillow-12.3.0-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:e158cb00350dc278f3b91551101aa7d12415a66ebf2c91d8d5ac14e56ddd3ad0", size = 4780131, upload-time = "2026-07-01T11:54:59.713Z" }, + { url = "https://files.pythonhosted.org/packages/b1/9d/8b2c807dbef61a5197c047afe99823787eb66f63daf9fb2432f91d6f0462/pillow-12.3.0-cp314-cp314-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:e9aeb04d6aef139de265b29683e119b638208f88cf73cdd1658aa07221165321", size = 6263757, upload-time = "2026-07-01T11:55:01.778Z" }, + { url = "https://files.pythonhosted.org/packages/5c/44/c85361f65dbe00eea8576ee467c768d25129989efb76e94f205e9ca9bb46/pillow-12.3.0-cp314-cp314-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:251bf95b67017e27b13d82f5b326234ca62d70f9cf4c2b9032de2358a3b12c7b", size = 6936962, upload-time = "2026-07-01T11:55:03.93Z" }, + { url = "https://files.pythonhosted.org/packages/18/7e/e483414b35800b86b6f08dbbc7803fb5cd52c4d6f897f47d53ea2c7e6f65/pillow-12.3.0-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:fe3cca2e4e8a592be0f269a1ca4835c25199d9f3ce815c8491048f785b0a0198", size = 6339171, upload-time = "2026-07-01T11:55:05.989Z" }, + { url = "https://files.pythonhosted.org/packages/f0/f4/68c491844841ede6bed70189546b3ee9731cf9f2cbad396faff5e1ccba45/pillow-12.3.0-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:23aceaa007d6172b02c277f0cd359c79492bbb14f7072b4ede9fbcaf20648130", size = 7048116, upload-time = "2026-07-01T11:55:08.131Z" }, + { url = "https://files.pythonhosted.org/packages/a3/34/77f3f793fed8efc7d243f21b33c5a3f0d1c97ee70346d3db855587e155ff/pillow-12.3.0-cp314-cp314-win32.whl", hash = "sha256:af8d94b0db561cf68b88a267c5c44b49e134f525d0dc2cb7ed413a66bc23559a", size = 6467209, upload-time = "2026-07-01T11:55:10.408Z" }, + { url = "https://files.pythonhosted.org/packages/f1/e0/492879f69d94f91f60fc8cd05ba03650e9520afebb2fb7aa12777d7c7f38/pillow-12.3.0-cp314-cp314-win_amd64.whl", hash = "sha256:fdafc9cce40277e0f7a0feabce0ee50dd2fa1800f3b38015e51296b5e814048d", size = 7237707, upload-time = "2026-07-01T11:55:12.745Z" }, + { url = "https://files.pythonhosted.org/packages/c9/ac/6b11f2875f1c2ac040d84e1bbf9cf22a88038f901ca1037898b280b38365/pillow-12.3.0-cp314-cp314-win_arm64.whl", hash = "sha256:e91206ee562682b51b98ef4b26a6ef48fd84e15fd4c4bc5ec768eb641d206838", size = 2565995, upload-time = "2026-07-01T11:55:14.736Z" }, + { url = "https://files.pythonhosted.org/packages/52/69/c2208e56af9bfc1913afb24020297a691eb1d4ef688474c8a04913f65e04/pillow-12.3.0-cp314-cp314t-macosx_10_15_x86_64.whl", hash = "sha256:164b31cd1a0490ab6efae01aa5df49da7061be0af1b30e035b6e9a1bfe34ee6e", size = 5352503, upload-time = "2026-07-01T11:55:17.076Z" }, + { url = "https://files.pythonhosted.org/packages/07/70/e5686d753e898a45d778ff1718dba8516ead6ab6b95d85fc8c4b70650cf2/pillow-12.3.0-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:5afb51d599ea772b8365ae807ae557f18bccfe46ab261fd1c2a9ed700fc6eb17", size = 4782956, upload-time = "2026-07-01T11:55:19.448Z" }, + { url = "https://files.pythonhosted.org/packages/d5/37/25c6692f06927ee973ff18c8d9ee98ad0b4d84ee67a09610c2dd1447958e/pillow-12.3.0-cp314-cp314t-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:3edce1d53195db527e0191f84b71d02022de0540bf43a16ed734ed7537b07385", size = 6322855, upload-time = "2026-07-01T11:55:21.613Z" }, + { url = "https://files.pythonhosted.org/packages/cc/91/420637fcb8f1bc11029e403b4538e6694744428d8246118e45719f944556/pillow-12.3.0-cp314-cp314t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:bf16ba1b4d0b6b7c8e534936632270cf70eb00dbe09005bc345b2677b726855c", size = 6989642, upload-time = "2026-07-01T11:55:24.006Z" }, + { url = "https://files.pythonhosted.org/packages/10/08/b94d7811281ccf0d143a1cf768d1c49e1e54af63e7b708ab2ee3eb87face/pillow-12.3.0-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:24870b09b224f7ae3c39ed07d10e819d06f8720bc551847b1d623832b5b0e28d", size = 6391281, upload-time = "2026-07-01T11:55:26.252Z" }, + { url = "https://files.pythonhosted.org/packages/d2/87/24233f785f55474dc02ce3e739c5528a77e3a862e9333d1dd7a25cc31f70/pillow-12.3.0-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:30f2aa603c41533cc25c05acd0da21636e84a315768feb631c937177db558931", size = 7096716, upload-time = "2026-07-01T11:55:28.318Z" }, + { url = "https://files.pythonhosted.org/packages/23/26/fcb2f6e37175b04f53570b59937867e2b80ee1685e744023153028fc14f9/pillow-12.3.0-cp314-cp314t-win32.whl", hash = "sha256:4b0a7fe987b14c31ebda6083f74f22b561fd3739bc0ac51e019622e3d72668c7", size = 6474125, upload-time = "2026-07-01T11:55:30.956Z" }, + { url = "https://files.pythonhosted.org/packages/90/de/3634abee5f1c9e13c56787b7d5517b0ba8d6de51700b95578cf338349c9f/pillow-12.3.0-cp314-cp314t-win_amd64.whl", hash = "sha256:962864dc93511324d51ddbb5b9f8731bf71675b93ca612a07441896f4688fb8c", size = 7242939, upload-time = "2026-07-01T11:55:34.044Z" }, + { url = "https://files.pythonhosted.org/packages/ce/2a/fd13f8eb24de5714a6eb444a3d67e2842c6c576e159a43793adf23051351/pillow-12.3.0-cp314-cp314t-win_arm64.whl", hash = "sha256:0740a512dc522224c77d9aa5a8d70d8b7d73fb91f2c21125d8d025d3b8990e45", size = 2567506, upload-time = "2026-07-01T11:55:35.988Z" }, + { url = "https://files.pythonhosted.org/packages/5d/dc/8fdce34ec725a33c81c6ba122b904d6b9024e50ea9ac7bede62fab54506c/pillow-12.3.0-cp315-cp315-ios_13_0_arm64_iphoneos.whl", hash = "sha256:0feb2e9d6ad6c9e3c06effe9d00f3f1e618a6643273576b016f591e9315a7139", size = 4162063, upload-time = "2026-07-01T11:55:37.941Z" }, + { url = "https://files.pythonhosted.org/packages/76/66/2044b9a63d3b84ff048228dfcb7cd9bf0df983e8470971bf7d4c57b693de/pillow-12.3.0-cp315-cp315-ios_13_0_arm64_iphonesimulator.whl", hash = "sha256:9e881fca225083806662a5c43d627d215f258ff43c890f831966c7d7ba9c7402", size = 4255549, upload-time = "2026-07-01T11:55:40.022Z" }, + { url = "https://files.pythonhosted.org/packages/52/7e/1f67e6f4ece6b582ee4b539decbcc9f848dc245a93ed8cd7338bafef72f1/pillow-12.3.0-cp315-cp315-ios_13_0_x86_64_iphonesimulator.whl", hash = "sha256:4998562bf62a445225f22e07c896bb04b35b1b1f2eb6d760584c9c51d7a5f78c", size = 3696331, upload-time = "2026-07-01T11:55:41.98Z" }, + { url = "https://files.pythonhosted.org/packages/12/40/d306fc2c8e4d45d7f175c77edca7063be7b86fe7fe6e68f4353bf71d808c/pillow-12.3.0-cp315-cp315-macosx_10_15_x86_64.whl", hash = "sha256:dc624f6bc473dacdf7ef7eb8678d0d08edf15cd94fad6ae5c7d6cc67a4e4902f", size = 5350370, upload-time = "2026-07-01T11:55:44.028Z" }, + { url = "https://files.pythonhosted.org/packages/dd/44/668fb1437e8ce420f62d6106eb66e44a5971602a4d794615bdf79315d82d/pillow-12.3.0-cp315-cp315-macosx_11_0_arm64.whl", hash = "sha256:71d6097b330eea8fd15097780c8e89cb1a8ce7838669f48c5bacd6f663dd4701", size = 4780147, upload-time = "2026-07-01T11:55:46.073Z" }, + { url = "https://files.pythonhosted.org/packages/0c/08/93fa2e70e30a2d81547e481b6ee2bb9522117221fb1e0ce4b5df70967677/pillow-12.3.0-cp315-cp315-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:28ce87c5ab450a9dd970b52e5aca5fe63ed432d18a2eaddd1979a00a1ba24ace", size = 6273659, upload-time = "2026-07-01T11:55:48.264Z" }, + { url = "https://files.pythonhosted.org/packages/f8/6d/043e96ff814fc31a33077e4cba86082167db520c93632afdf2042febbb0c/pillow-12.3.0-cp315-cp315-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:6b02afb9b97f65fbca5f31db6a2a3ba21aa93030225f150fa3f249717e938fb4", size = 6947439, upload-time = "2026-07-01T11:55:50.503Z" }, + { url = "https://files.pythonhosted.org/packages/af/92/ba71d2ee2ac0edf3fa33bd9d5ee9ee080da70b1766f3ca3934f9938ddac9/pillow-12.3.0-cp315-cp315-musllinux_1_2_aarch64.whl", hash = "sha256:1182d52bc2d5e5d7d0949503aa7e36d12f42205dc287e4883f407b1988820d39", size = 6353577, upload-time = "2026-07-01T11:55:52.697Z" }, + { url = "https://files.pythonhosted.org/packages/0f/ce/e63064e2122923ff687c8ad792d0d736a7b3920a56a46982e81a7fdd25d6/pillow-12.3.0-cp315-cp315-musllinux_1_2_x86_64.whl", hash = "sha256:e795b7eb908249c4e43c7c99fac7c2c75dab0c43566e37db472a355f63693d71", size = 7060394, upload-time = "2026-07-01T11:55:55.149Z" }, + { url = "https://files.pythonhosted.org/packages/54/76/a09cc3ccc8d773a7283d34c38bec1708f9e3cc932093cbc4c5e71ac4060b/pillow-12.3.0-cp315-cp315-win32.whl", hash = "sha256:57b3d78c95ba9059768b10e28b813002261d3f3dfc55cc48b0c988f625175827", size = 6467375, upload-time = "2026-07-01T11:55:57.769Z" }, + { url = "https://files.pythonhosted.org/packages/3e/03/1846c49ba3b1d5550392a4bbd06d6fb4578e1cd91a803198b5c90f5f7d53/pillow-12.3.0-cp315-cp315-win_amd64.whl", hash = "sha256:fa4ecea169a355be7a3ade2c783e2ed12f0e40d2c5621cda8b3297faf7fbb9f5", size = 7237048, upload-time = "2026-07-01T11:55:59.975Z" }, + { url = "https://files.pythonhosted.org/packages/fb/bb/89f35dcc79610423f9f195504d7def7f0d1416a711541b42867e25fe3412/pillow-12.3.0-cp315-cp315-win_arm64.whl", hash = "sha256:877c3f311ff35410f690861c4409e7ccbf0cd2f878e50628a28e5a0bb689e658", size = 2566006, upload-time = "2026-07-01T11:56:02.143Z" }, + { url = "https://files.pythonhosted.org/packages/30/88/707027ba09942dfa2c28759b5c222d769290a41c6d20ea60ec250801941f/pillow-12.3.0-cp315-cp315t-macosx_10_15_x86_64.whl", hash = "sha256:e9871b1ffbfa9656b60aeee92ed5136a5742696006fa322b29ea3d8da0ecc9cf", size = 5352509, upload-time = "2026-07-01T11:56:04.2Z" }, + { url = "https://files.pythonhosted.org/packages/b0/6d/00352fa25332c2569cd387851f568cc5a4b75a9adbfb37ac4fbce4c02eec/pillow-12.3.0-cp315-cp315t-macosx_11_0_arm64.whl", hash = "sha256:53aa02d20d10c3d814d536aa4e5ac9b84ca0ff5a88377963b085ad6822f93e64", size = 4783167, upload-time = "2026-07-01T11:56:06.631Z" }, + { url = "https://files.pythonhosted.org/packages/13/4f/9e049dfa21af7c22427275720e2490267ba8138120add5c4c574deb69782/pillow-12.3.0-cp315-cp315t-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:446c34dcc4324b084a53b705127dc15717b22c5e140ae0a3c38349d4efec071e", size = 6329237, upload-time = "2026-07-01T11:56:08.868Z" }, + { url = "https://files.pythonhosted.org/packages/36/16/cf6eeaae8d0fce8dd390a33437cf68c5d5bd73834a2bc6e2f14efda0ab45/pillow-12.3.0-cp315-cp315t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:cf1845d02ad822a369a49f2bb9345b1614744267682e7a03527dc3bf6eea1777", size = 6997047, upload-time = "2026-07-01T11:56:11.379Z" }, + { url = "https://files.pythonhosted.org/packages/1e/69/dbf769bdd55f48bf5733cac28edc6364ffaa072ec9ba336266e4fe66be55/pillow-12.3.0-cp315-cp315t-musllinux_1_2_aarch64.whl", hash = "sha256:186941b6aef820ad110fb01fb06eb925374dc3a21b17e37ec9a53b250c6fe2d1", size = 6400440, upload-time = "2026-07-01T11:56:13.908Z" }, + { url = "https://files.pythonhosted.org/packages/a0/e1/ffc9cfc2eea0d178da8018e18e959301ad9d6bc9f3edb7181e748a474b97/pillow-12.3.0-cp315-cp315t-musllinux_1_2_x86_64.whl", hash = "sha256:f13c32a3abd6079a66d9526e18dad9b6d280384d49d7c54040cd57b6424041d9", size = 7105895, upload-time = "2026-07-01T11:56:16.575Z" }, + { url = "https://files.pythonhosted.org/packages/18/f0/a5595c1e8c3ae44b9828cb2f0fa8155e5095ef04d6327b8f61cf44a3df85/pillow-12.3.0-cp315-cp315t-win32.whl", hash = "sha256:1657923d2d45afb66526e5b933e5b3052e6bdea196c90d3abb2424e18c77dae8", size = 6474384, upload-time = "2026-07-01T11:56:18.855Z" }, + { url = "https://files.pythonhosted.org/packages/e4/04/62bcd9f844984c5938d3b05264a61d797a29d3e0812341a8204af70bbdee/pillow-12.3.0-cp315-cp315t-win_amd64.whl", hash = "sha256:8cd2f7bdda092d99c9fc2fb7391354f306d01443d22785d0cbfafa2e2c8bb418", size = 7243537, upload-time = "2026-07-01T11:56:21.214Z" }, + { url = "https://files.pythonhosted.org/packages/3d/68/1f3066acedf37673694a7141381d8f811ae97f30d34413d236abe7d489f1/pillow-12.3.0-cp315-cp315t-win_arm64.whl", hash = "sha256:06ff022112bc9cbf83b60f8e028d94ad87b60621706487e65f673de61610ab59", size = 2567491, upload-time = "2026-07-01T11:56:23.506Z" }, + { url = "https://files.pythonhosted.org/packages/75/18/2e8b40223153ccbc60df07f9e8928dc0c76202aa4e55ae9f53962b6510d6/pillow-12.3.0-pp311-pypy311_pp73-macosx_10_15_x86_64.whl", hash = "sha256:b3c777e849237620b022f7f297dd67705f9f5cf1685f09f02e46f93e92725468", size = 5302510, upload-time = "2026-07-01T11:56:25.736Z" }, + { url = "https://files.pythonhosted.org/packages/46/3e/51fabf59d5ab801ceab709453d3ab6b180083496579549de4c45ced6528a/pillow-12.3.0-pp311-pypy311_pp73-macosx_11_0_arm64.whl", hash = "sha256:b343699e8308bdc51978310e1c959c584e7869cc8c40780058c87da7781a1e94", size = 4736058, upload-time = "2026-07-01T11:56:28.041Z" }, + { url = "https://files.pythonhosted.org/packages/bf/20/22fe9384b7949e25fb1293bcfc84fb82590ff4ea6b37c95b24d26d793d86/pillow-12.3.0-pp311-pypy311_pp73-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:fbd139c8447d25dd750ab79ee274cc5e1fe80fc56340ab10b18a195e1b6eca3e", size = 5237776, upload-time = "2026-07-01T11:56:30.263Z" }, + { url = "https://files.pythonhosted.org/packages/08/14/f6ba68107680ffa74b39985f3f30884e41318fbc4250caa423c79b4788bb/pillow-12.3.0-pp311-pypy311_pp73-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:e7e480451b9fa137494bccd3a7d69adbe8ac65a87d97be61e11f1b1050a5bac3", size = 5860358, upload-time = "2026-07-01T11:56:32.68Z" }, + { url = "https://files.pythonhosted.org/packages/36/54/0169bc772ec491108b62f644f8ecf1fe5d8ae5ebafde2ee2142210166903/pillow-12.3.0-pp311-pypy311_pp73-win_amd64.whl", hash = "sha256:04f01d28a6aaff387bf842a13be313df23ba0597a44f1a976c9feb3c6ff4711a", size = 7231786, upload-time = "2026-07-01T11:56:35.046Z" }, ] [[package]] @@ -1688,32 +2537,6 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/54/20/4d324d65cc6d9205fabedc306948156824eb9f0ee1633355a8f7ec5c66bf/pluggy-1.6.0-py3-none-any.whl", hash = "sha256:e920276dd6813095e9377c0bc5566d94c932c33b27a3e3945d8389c374dd4746", size = 20538, upload-time = "2025-05-15T12:30:06.134Z" }, ] -[[package]] -name = "plum-dispatch" -version = "2.10.1" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "beartype" }, - { name = "rich" }, - { name = "typing-extensions" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/dc/75/807b02f339906867de07baaecd3519fe8704df013a27ae0a57250ed461d3/plum_dispatch-2.10.1.tar.gz", hash = "sha256:93aa1ec5c4683c0777b9d7d1ccc0b31e0e82f38399116345b4ed8d0fb67cc66e", size = 250842, upload-time = "2026-09-07T17:38:44.9Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/8a/1a/3736f28127e6aa0e87eaee3286c0f93bf8fd25382786d8409073fc1a9010/plum_dispatch-2.10.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:143b44537476fcfa644a7b3b00cdfce91cd94c501eb5d4a342d0b1dae6e00269", size = 279045, upload-time = "2026-09-07T17:38:26.368Z" }, - { url = "https://files.pythonhosted.org/packages/67/a7/dfc192aa694244278d66c5251bc415bb23234a8cb12013e46dfae2747091/plum_dispatch-2.10.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:193fa7d9809e6ccf38d0ec423b92c2ce88b1bb5dfa7c769ce7a3b216aeb61eb4", size = 264041, upload-time = "2026-09-07T17:38:27.743Z" }, - { url = "https://files.pythonhosted.org/packages/77/8d/15617a11d26a7dfa9e5f6f36103c4a3e27e5651d9261ca6bd6a099a69abc/plum_dispatch-2.10.1-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:b8909bc8c3b776f116c50986718befeda1de17a3dc61e7ae93f5d3d71de5f98d", size = 328403, upload-time = "2026-09-07T17:38:29.315Z" }, - { url = "https://files.pythonhosted.org/packages/f0/20/7e5a1535a858ae4716083ac15d935394207145f8249fea8f693dd979a7f6/plum_dispatch-2.10.1-cp311-cp311-win_amd64.whl", hash = "sha256:4adc9e9335bee9fffd24abd3be0aa6810e403129697ab767976d70cc3c88405c", size = 244207, upload-time = "2026-09-07T17:38:30.608Z" }, - { url = "https://files.pythonhosted.org/packages/5d/d1/10c40a76f0fc3959d73a245e3e63ab576062e2c7db1fb41a4e035a5f4ee0/plum_dispatch-2.10.1-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:476821e99fe4c747725887021ea09028ff5e013d8732c40c6d44df65815a70ea", size = 285017, upload-time = "2026-09-07T17:38:32.092Z" }, - { url = "https://files.pythonhosted.org/packages/90/91/d0a7d52b1a2e02e883b078e2801cfd544abb05b1a28183e46db43d812667/plum_dispatch-2.10.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:e1a73a06483fffa8f8247bbf6057157075be2f63e76845792eb75d86b11f1188", size = 267393, upload-time = "2026-09-07T17:38:33.461Z" }, - { url = "https://files.pythonhosted.org/packages/b9/c3/d8793642ce7d29ea15cc39c10185ef126a27fcb8ea230154978221deb4b2/plum_dispatch-2.10.1-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:a5b6a2474f53b23cd07254c2ad286fc8371a3c4ed17dee72794eac9c3a6873db", size = 334557, upload-time = "2026-09-07T17:38:34.857Z" }, - { url = "https://files.pythonhosted.org/packages/41/c7/3544b2bf05aa9e1a1b45981d21da5e5d5c135fcc2da0ee1040f73512662f/plum_dispatch-2.10.1-cp312-cp312-win_amd64.whl", hash = "sha256:ae2f76ce97bcbf1d7038e7c352180cbb35c90c23ea0848e2924f35133fb0f223", size = 245830, upload-time = "2026-09-07T17:38:36.228Z" }, - { url = "https://files.pythonhosted.org/packages/16/69/c73f5145dd136158c74295c3f1751062beaf744f508cd04dce61bfe9b059/plum_dispatch-2.10.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:a8cebe7c3380e8cd451008d405fbb3a202626a7da4c140deff36d52dfb05e5aa", size = 283228, upload-time = "2026-09-07T17:38:37.664Z" }, - { url = "https://files.pythonhosted.org/packages/c3/1e/252f11d5443e341cf1a1c4986ec0e5a365bcb605190cfa26410acbe68dc6/plum_dispatch-2.10.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:4e6ffcc378838cffc9f13d67f1ea79585ffea7e04aa00e888941ef63400f175b", size = 265603, upload-time = "2026-09-07T17:38:39.254Z" }, - { url = "https://files.pythonhosted.org/packages/65/11/6cdfa574f1682840b644527a1644e0740ddb3ddc6e759dcbef4a49091df6/plum_dispatch-2.10.1-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:131145651d4fa89ee97a026e49545638380a68f71f530ca57b0efaa04dfad1b6", size = 332929, upload-time = "2026-09-07T17:38:40.715Z" }, - { url = "https://files.pythonhosted.org/packages/52/9a/665b51655fd98196066d042d06af9641d0ac589f9e23ad3e895002c9563b/plum_dispatch-2.10.1-cp313-cp313-win_amd64.whl", hash = "sha256:f75fcfb61c89ca561e3b856d2d9392167d51a283d23c7b9a5d11937a3120cae7", size = 246611, upload-time = "2026-09-07T17:38:42.249Z" }, - { url = "https://files.pythonhosted.org/packages/55/9f/0adfb5a90d65233b764cb1b07244b72ded1db7cfc66955418544d0da2e38/plum_dispatch-2.10.1-py3-none-any.whl", hash = "sha256:dac63fd5ada8ae8045aefed127dacda0ba02db2635876b12f4e1dfaf6db73f39", size = 49430, upload-time = "2026-09-07T17:38:43.589Z" }, -] - [[package]] name = "polars" version = "1.44.1" @@ -1742,6 +2565,15 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/e9/9d/8b17e075aac73c881a50b6c1f690d20df46db2f3bcabc99f600ecdee1290/polars_runtime_32-1.44.1-cp310-abi3-win_arm64.whl", hash = "sha256:3ba28d638d0513e0b4afbcdab5c0059a85021e5f81d62b5f793e7e23badb2cf7", size = 47281050, upload-time = "2026-08-26T07:08:18.43Z" }, ] +[[package]] +name = "prometheus-client" +version = "0.26.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/52/73/f1334c29c2af4cd9dba6c7817e61b611bd0215e2eb5565c6064a4de18802/prometheus_client-0.26.0.tar.gz", hash = "sha256:04a91bcf94e2cf74a44a1a874d651a2e853ed354b6e822f3b7487751465d5c2b", size = 92910, upload-time = "2026-07-24T19:36:41.893Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/eb/a3/b69efbf4143b5b9859b977770bbbabcc2796b702fa69dc40271e45cd5a56/prometheus_client-0.26.0-py3-none-any.whl", hash = "sha256:fa93d06737aa02bacd05794768508bb97d2fbee28cb3bca04eaae92f0ca953d6", size = 64494, upload-time = "2026-07-24T19:36:40.854Z" }, +] + [[package]] name = "prompt-toolkit" version = "3.0.53" @@ -1769,6 +2601,95 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/01/c3/629999e78d46c1115c11886d51c6bd68c17ce4a944f1ea3e153a91316a33/protobuf-7.36.0-py3-none-any.whl", hash = "sha256:53374d53fc29a67f7dbbf0ade47d7526a0f0137bf0f9c90e48d8a60790ef748c", size = 177024, upload-time = "2026-08-20T16:34:00.053Z" }, ] +[[package]] +name = "psutil" +version = "7.2.2" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/aa/c6/d1ddf4abb55e93cebc4f2ed8b5d6dbad109ecb8d63748dd2b20ab5e57ebe/psutil-7.2.2.tar.gz", hash = "sha256:0746f5f8d406af344fd547f1c8daa5f5c33dbc293bb8d6a16d80b4bb88f59372", size = 493740, upload-time = "2026-01-28T18:14:54.428Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/51/08/510cbdb69c25a96f4ae523f733cdc963ae654904e8db864c07585ef99875/psutil-7.2.2-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:2edccc433cbfa046b980b0df0171cd25bcaeb3a68fe9022db0979e7aa74a826b", size = 130595, upload-time = "2026-01-28T18:14:57.293Z" }, + { url = "https://files.pythonhosted.org/packages/d6/f5/97baea3fe7a5a9af7436301f85490905379b1c6f2dd51fe3ecf24b4c5fbf/psutil-7.2.2-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:e78c8603dcd9a04c7364f1a3e670cea95d51ee865e4efb3556a3a63adef958ea", size = 131082, upload-time = "2026-01-28T18:14:59.732Z" }, + { url = "https://files.pythonhosted.org/packages/37/d6/246513fbf9fa174af531f28412297dd05241d97a75911ac8febefa1a53c6/psutil-7.2.2-cp313-cp313t-manylinux2010_x86_64.manylinux_2_12_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:1a571f2330c966c62aeda00dd24620425d4b0cc86881c89861fbc04549e5dc63", size = 181476, upload-time = "2026-01-28T18:15:01.884Z" }, + { url = "https://files.pythonhosted.org/packages/b8/b5/9182c9af3836cca61696dabe4fd1304e17bc56cb62f17439e1154f225dd3/psutil-7.2.2-cp313-cp313t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:917e891983ca3c1887b4ef36447b1e0873e70c933afc831c6b6da078ba474312", size = 184062, upload-time = "2026-01-28T18:15:04.436Z" }, + { url = "https://files.pythonhosted.org/packages/16/ba/0756dca669f5a9300d0cbcbfae9a4c30e446dfc7440ffe43ded5724bfd93/psutil-7.2.2-cp313-cp313t-win_amd64.whl", hash = "sha256:ab486563df44c17f5173621c7b198955bd6b613fb87c71c161f827d3fb149a9b", size = 139893, upload-time = "2026-01-28T18:15:06.378Z" }, + { url = "https://files.pythonhosted.org/packages/1c/61/8fa0e26f33623b49949346de05ec1ddaad02ed8ba64af45f40a147dbfa97/psutil-7.2.2-cp313-cp313t-win_arm64.whl", hash = "sha256:ae0aefdd8796a7737eccea863f80f81e468a1e4cf14d926bd9b6f5f2d5f90ca9", size = 135589, upload-time = "2026-01-28T18:15:08.03Z" }, + { url = "https://files.pythonhosted.org/packages/81/69/ef179ab5ca24f32acc1dac0c247fd6a13b501fd5534dbae0e05a1c48b66d/psutil-7.2.2-cp314-cp314t-macosx_10_15_x86_64.whl", hash = "sha256:eed63d3b4d62449571547b60578c5b2c4bcccc5387148db46e0c2313dad0ee00", size = 130664, upload-time = "2026-01-28T18:15:09.469Z" }, + { url = "https://files.pythonhosted.org/packages/7b/64/665248b557a236d3fa9efc378d60d95ef56dd0a490c2cd37dafc7660d4a9/psutil-7.2.2-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:7b6d09433a10592ce39b13d7be5a54fbac1d1228ed29abc880fb23df7cb694c9", size = 131087, upload-time = "2026-01-28T18:15:11.724Z" }, + { url = "https://files.pythonhosted.org/packages/d5/2e/e6782744700d6759ebce3043dcfa661fb61e2fb752b91cdeae9af12c2178/psutil-7.2.2-cp314-cp314t-manylinux2010_x86_64.manylinux_2_12_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:1fa4ecf83bcdf6e6c8f4449aff98eefb5d0604bf88cb883d7da3d8d2d909546a", size = 182383, upload-time = "2026-01-28T18:15:13.445Z" }, + { url = "https://files.pythonhosted.org/packages/57/49/0a41cefd10cb7505cdc04dab3eacf24c0c2cb158a998b8c7b1d27ee2c1f5/psutil-7.2.2-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:e452c464a02e7dc7822a05d25db4cde564444a67e58539a00f929c51eddda0cf", size = 185210, upload-time = "2026-01-28T18:15:16.002Z" }, + { url = "https://files.pythonhosted.org/packages/dd/2c/ff9bfb544f283ba5f83ba725a3c5fec6d6b10b8f27ac1dc641c473dc390d/psutil-7.2.2-cp314-cp314t-win_amd64.whl", hash = "sha256:c7663d4e37f13e884d13994247449e9f8f574bc4655d509c3b95e9ec9e2b9dc1", size = 141228, upload-time = "2026-01-28T18:15:18.385Z" }, + { url = "https://files.pythonhosted.org/packages/f2/fc/f8d9c31db14fcec13748d373e668bc3bed94d9077dbc17fb0eebc073233c/psutil-7.2.2-cp314-cp314t-win_arm64.whl", hash = "sha256:11fe5a4f613759764e79c65cf11ebdf26e33d6dd34336f8a337aa2996d71c841", size = 136284, upload-time = "2026-01-28T18:15:19.912Z" }, + { url = "https://files.pythonhosted.org/packages/e7/36/5ee6e05c9bd427237b11b3937ad82bb8ad2752d72c6969314590dd0c2f6e/psutil-7.2.2-cp36-abi3-macosx_10_9_x86_64.whl", hash = "sha256:ed0cace939114f62738d808fdcecd4c869222507e266e574799e9c0faa17d486", size = 129090, upload-time = "2026-01-28T18:15:22.168Z" }, + { url = "https://files.pythonhosted.org/packages/80/c4/f5af4c1ca8c1eeb2e92ccca14ce8effdeec651d5ab6053c589b074eda6e1/psutil-7.2.2-cp36-abi3-macosx_11_0_arm64.whl", hash = "sha256:1a7b04c10f32cc88ab39cbf606e117fd74721c831c98a27dc04578deb0c16979", size = 129859, upload-time = "2026-01-28T18:15:23.795Z" }, + { url = "https://files.pythonhosted.org/packages/b5/70/5d8df3b09e25bce090399cf48e452d25c935ab72dad19406c77f4e828045/psutil-7.2.2-cp36-abi3-manylinux2010_x86_64.manylinux_2_12_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:076a2d2f923fd4821644f5ba89f059523da90dc9014e85f8e45a5774ca5bc6f9", size = 155560, upload-time = "2026-01-28T18:15:25.976Z" }, + { url = "https://files.pythonhosted.org/packages/63/65/37648c0c158dc222aba51c089eb3bdfa238e621674dc42d48706e639204f/psutil-7.2.2-cp36-abi3-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:b0726cecd84f9474419d67252add4ac0cd9811b04d61123054b9fb6f57df6e9e", size = 156997, upload-time = "2026-01-28T18:15:27.794Z" }, + { url = "https://files.pythonhosted.org/packages/8e/13/125093eadae863ce03c6ffdbae9929430d116a246ef69866dad94da3bfbc/psutil-7.2.2-cp36-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:fd04ef36b4a6d599bbdb225dd1d3f51e00105f6d48a28f006da7f9822f2606d8", size = 148972, upload-time = "2026-01-28T18:15:29.342Z" }, + { url = "https://files.pythonhosted.org/packages/04/78/0acd37ca84ce3ddffaa92ef0f571e073faa6d8ff1f0559ab1272188ea2be/psutil-7.2.2-cp36-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:b58fabe35e80b264a4e3bb23e6b96f9e45a3df7fb7eed419ac0e5947c61e47cc", size = 148266, upload-time = "2026-01-28T18:15:31.597Z" }, + { url = "https://files.pythonhosted.org/packages/b4/90/e2159492b5426be0c1fef7acba807a03511f97c5f86b3caeda6ad92351a7/psutil-7.2.2-cp37-abi3-win_amd64.whl", hash = "sha256:eb7e81434c8d223ec4a219b5fc1c47d0417b12be7ea866e24fb5ad6e84b3d988", size = 137737, upload-time = "2026-01-28T18:15:33.849Z" }, + { url = "https://files.pythonhosted.org/packages/8c/c7/7bb2e321574b10df20cbde462a94e2b71d05f9bbda251ef27d104668306a/psutil-7.2.2-cp37-abi3-win_arm64.whl", hash = "sha256:8c233660f575a5a89e6d4cb65d9f938126312bca76d8fe087b947b3a1aaac9ee", size = 134617, upload-time = "2026-01-28T18:15:36.514Z" }, +] + +[[package]] +name = "ptyprocess" +version = "0.7.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/20/e5/16ff212c1e452235a90aeb09066144d0c5a6a8c0834397e03f5224495c4e/ptyprocess-0.7.0.tar.gz", hash = "sha256:5c5d0a3b48ceee0b48485e0c26037c0acd7d29765ca3fbb5cb3831d347423220", size = 70762, upload-time = "2020-12-28T15:15:30.155Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/22/a6/858897256d0deac81a172289110f31629fc4cee19b6f01283303e18c8db3/ptyprocess-0.7.0-py2.py3-none-any.whl", hash = "sha256:4b41f3967fce3af57cc7e94b888626c18bf37a083e3651ca8feeb66d492fef35", size = 13993, upload-time = "2020-12-28T15:15:28.35Z" }, +] + +[[package]] +name = "pure-eval" +version = "0.2.4" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/da/9f/abfd2959e9261dd5217ca8551d4de211ca6ab26fe9b72cf44731ff6c4442/pure_eval-0.2.4.tar.gz", hash = "sha256:260c2774686e651b79f8b8e7fc9d80b3599ea6a66334b47d5f4abb69fc2c0ea1", size = 20563, upload-time = "2026-09-10T21:41:22.836Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/6d/18/83376915176eb058cb86470eb7396388a13350b09a8f233a79303bbcbc5b/pure_eval-0.2.4-py3-none-any.whl", hash = "sha256:96cae060a313cfaad51bb761278bfb0e62dc0248d9315a81173752dc546cd37a", size = 11893, upload-time = "2026-09-10T21:41:21.532Z" }, +] + +[[package]] +name = "py-yaml12" +version = "0.2.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/30/9d/d3cd204ed45f4b73e29d6dbe50d8d1fa56099914f36798ae93ad184c7824/py_yaml12-0.2.0.tar.gz", hash = "sha256:b8326c144e26a4ae7e03d13175667d85c580a9f0512fd7b809e5c92b5569f74e", size = 114038, upload-time = "2026-08-25T16:01:25.651Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/62/d7/7f496699fc8062fc010af3f2be9305cfb11713474f9fa5592a1d482c89ef/py_yaml12-0.2.0-cp310-abi3-macosx_10_12_x86_64.whl", hash = "sha256:30badb235d31efaf00e7fcab7659bbc5c827242540b36d628706f9bb88d44703", size = 480417, upload-time = "2026-08-25T16:01:12.129Z" }, + { url = "https://files.pythonhosted.org/packages/f8/ff/2ed711cf932b22d8b0187aa294f74379d08b212039092d5861b5ff81810a/py_yaml12-0.2.0-cp310-abi3-macosx_11_0_arm64.whl", hash = "sha256:cdc50f733128210825eb31667068cb6fa7c55d0dd3e26f127b09d47adada776b", size = 475054, upload-time = "2026-08-25T16:01:09.719Z" }, + { url = "https://files.pythonhosted.org/packages/0e/6d/a12e05e289cecb44d93cbfb67cb40be2e753e9a1253fe95d28f17a2a9a6f/py_yaml12-0.2.0-cp310-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ec6bfc407645c36c4dcd9d7cbb79b033826a5a9f748cf47fd20df6bd3b06c142", size = 515509, upload-time = "2026-08-25T16:00:54.237Z" }, + { url = "https://files.pythonhosted.org/packages/7d/02/480c32d811456c465f1b9fa14a2f85b3502afe287c4a5048c05c57ef31fe/py_yaml12-0.2.0-cp310-abi3-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:39ee4d5dac35db849960d028a322b15d06c65a1aa977beade0faac10964e3c1d", size = 524706, upload-time = "2026-08-25T16:00:57.007Z" }, + { url = "https://files.pythonhosted.org/packages/9c/1f/c0d3cb2a03f555970b79c281c3fa0bc702577fb3b89072175cdcfdec383d/py_yaml12-0.2.0-cp310-abi3-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:9c2587c2a9985285c7488785269ad1ae323ae3a32cb24a0f3eb2c511af2b5ff2", size = 643146, upload-time = "2026-08-25T16:00:59.811Z" }, + { url = "https://files.pythonhosted.org/packages/61/ca/044194b180bb38c3581c52e9aab1b626dcaa11d034fe65119e9b05452336/py_yaml12-0.2.0-cp310-abi3-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:19cf2ba480688efb166a4f728e95fe664a02ac76e95907d822dd340030557e71", size = 534688, upload-time = "2026-08-25T16:01:02.294Z" }, + { url = "https://files.pythonhosted.org/packages/e1/b5/7c46717623a32af07e2d3e18b2e78a3c332479cb68920cd6866e5835647e/py_yaml12-0.2.0-cp310-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:40f471ffcae322669e26208ff81780c1cb3284f089e6e4a254d12b53a7c26be0", size = 527932, upload-time = "2026-08-25T16:01:06.966Z" }, + { url = "https://files.pythonhosted.org/packages/3b/e7/26cc99ba17f810235bc1648bc32a0340eee087f7701ab16f1d9f26a94a1a/py_yaml12-0.2.0-cp310-abi3-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:91490be0890c38d5cab4aa9ad3a3d23b5af498c64174d67a1ee8cb37e8069e5a", size = 564882, upload-time = "2026-08-25T16:01:04.631Z" }, + { url = "https://files.pythonhosted.org/packages/e0/bf/bcbdad4826cf2ba2f621873420ecb2b2e8bd1cf4e59afb8d73243b1e8158/py_yaml12-0.2.0-cp310-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:64df1646ba2b4d8f4a0ed2ddb7cb795e767ed48400c195511a1d50096246a0ce", size = 691828, upload-time = "2026-08-25T16:01:14.568Z" }, + { url = "https://files.pythonhosted.org/packages/30/8d/e4d1f078085683eb572ed6a399b0fb0a9f384f9383464b63b73b9adb9a22/py_yaml12-0.2.0-cp310-abi3-musllinux_1_2_armv7l.whl", hash = "sha256:b75a9f8422883d06f5506cf813c93b8acdf3d4785c525894560c472254f03dbb", size = 800294, upload-time = "2026-08-25T16:01:17.453Z" }, + { url = "https://files.pythonhosted.org/packages/84/01/02adc5cb68fc0f94cf4866b630020413134b0e606270e6e3ba95c9aeb0d7/py_yaml12-0.2.0-cp310-abi3-musllinux_1_2_i686.whl", hash = "sha256:dd525aece33bdd06c3714e85c0a6cc3d53818133ba4cb98e3b0692ea8ab76af9", size = 774035, upload-time = "2026-08-25T16:01:20.63Z" }, + { url = "https://files.pythonhosted.org/packages/4a/b2/0e579fbbfcc47e779b1f547d39d1b0e35a8491fd56d3d2e0243f9a7d903b/py_yaml12-0.2.0-cp310-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:747e2c2f3fe807cd7cd59585e4d3613920c86b0db1adcb299a686dbdc3d2241c", size = 730893, upload-time = "2026-08-25T16:01:23.194Z" }, + { url = "https://files.pythonhosted.org/packages/24/0b/222efe9cd8b911b9bf48b0ea5c4b545702536b8c91ad1ccd1b1d5a2b69e6/py_yaml12-0.2.0-cp310-abi3-win32.whl", hash = "sha256:6d19322c40ee969adb6125a1ecf50752582d353e45ae969f13006bdf5e7a03f2", size = 354395, upload-time = "2026-08-25T16:01:32.159Z" }, + { url = "https://files.pythonhosted.org/packages/64/f8/c0d7a7feff63870bd78810fb79737f3f25c64e29b10257da354f0fad0bf6/py_yaml12-0.2.0-cp310-abi3-win_amd64.whl", hash = "sha256:4f5ed741cf31f672346640b493bf11d16950011f91c8d2587319e0a86b39ba38", size = 372999, upload-time = "2026-08-25T16:01:28.657Z" }, + { url = "https://files.pythonhosted.org/packages/8b/47/c7098392689f2eed60c2ac37077a0bd559b50d867cb07f9a81db15981f21/py_yaml12-0.2.0-cp310-abi3-win_arm64.whl", hash = "sha256:78142b53efc4671d2f2a54a5623ebc870c607e120c4653e67fa0c3c1b67ac648", size = 358473, upload-time = "2026-08-25T16:01:26.57Z" }, + { url = "https://files.pythonhosted.org/packages/9e/76/d5be3cdb8c438d2857cfff01a5c806ace3c5732aa963f0fece050047c395/py_yaml12-0.2.0-cp314-cp314t-macosx_10_12_x86_64.whl", hash = "sha256:4f8d4bf41c2bba74f790670bfd15bdf378ca97e8dd7b39ce5afe91344bb312f2", size = 480058, upload-time = "2026-08-25T16:01:13.358Z" }, + { url = "https://files.pythonhosted.org/packages/30/82/caa97ce17f0de0d81b4ba2ad38bf56cb77c294088b8231e1965da7a2f4d1/py_yaml12-0.2.0-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:5ac1ac4ab63ef74e9cb8af18ba8b58f1b689ed97830ba544ae5e9d1c2d841f53", size = 465005, upload-time = "2026-08-25T16:01:10.902Z" }, + { url = "https://files.pythonhosted.org/packages/fc/2b/4566e7977e523a271c86472aaf20cd086130a8bb418413fb2e98c2064bd0/py_yaml12-0.2.0-cp314-cp314t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:12c84011c9969c5d26f8c04c04c70397de8f52b4564b7409a50e00647338b10f", size = 507340, upload-time = "2026-08-25T16:00:55.585Z" }, + { url = "https://files.pythonhosted.org/packages/be/fc/e3c80f2f50f294b2fbc52e4a37b60b3f952c6bef744539346f32ae640c1e/py_yaml12-0.2.0-cp314-cp314t-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:2f5750ecd0fe489f03fc30ec1c0e07643cf8a50792d55adfaa60f30a0818221a", size = 518508, upload-time = "2026-08-25T16:00:58.491Z" }, + { url = "https://files.pythonhosted.org/packages/28/b4/e013fbb730e7ee5b6f5e5ff1e69e56a89ae45a6d52d1610f4159515400b6/py_yaml12-0.2.0-cp314-cp314t-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ffea2ae8e8ffd402bdc9688af05f8e725890ff330723ebe785b602ad4d48c08f", size = 634168, upload-time = "2026-08-25T16:01:01.014Z" }, + { url = "https://files.pythonhosted.org/packages/44/20/ae612caeaa0083cf865c968d614f10f60df4fea9cdf3cbe0d3c5894af8b5/py_yaml12-0.2.0-cp314-cp314t-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e7e4adba539f2641a762100a5910913f7e18d8911c47009162b338ff008da997", size = 529153, upload-time = "2026-08-25T16:01:03.512Z" }, + { url = "https://files.pythonhosted.org/packages/22/6b/04545527ba9c8bc215cf487f35732c4bd41cfa2486dab19c87c04cba54d8/py_yaml12-0.2.0-cp314-cp314t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8968c9b6bfb4af9f14eea1ed567e0f41adc44b54d3e0b2e2c2fdea111b082fbe", size = 520127, upload-time = "2026-08-25T16:01:08.205Z" }, + { url = "https://files.pythonhosted.org/packages/bb/32/c8afbc2a3970452c20363ea69523dc20193c67c7041c4602556a5385f6ec/py_yaml12-0.2.0-cp314-cp314t-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:392f69601bc6fc25ae0c480b717f9a166e8900e26a3d7f1ccc33b0f51ee3e971", size = 554978, upload-time = "2026-08-25T16:01:05.833Z" }, + { url = "https://files.pythonhosted.org/packages/2d/94/581b660faa2cd33d1255f49d68dd0324c597922ab19a60bb39e7d6041aba/py_yaml12-0.2.0-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:26a4afe7682e8795e0b3eace2abfa2061bf61412aac05f3311bcb0e0a98a1359", size = 684101, upload-time = "2026-08-25T16:01:15.812Z" }, + { url = "https://files.pythonhosted.org/packages/9d/10/4fac6663597120448077f267b6562df0e426fd6e5218c6593aa3b07d7be6/py_yaml12-0.2.0-cp314-cp314t-musllinux_1_2_armv7l.whl", hash = "sha256:9b505d1f2d9c13c75298d0701398120ee135d7fb19874a29ab018c7cf1c9c438", size = 795089, upload-time = "2026-08-25T16:01:19.436Z" }, + { url = "https://files.pythonhosted.org/packages/88/0a/2d1e0d7ca099262f509606bbab329083494fc52716c4e4688f2ff65fc34f/py_yaml12-0.2.0-cp314-cp314t-musllinux_1_2_i686.whl", hash = "sha256:e36ffa4164ae7eab058ede38a360d26fb409f4f290c644c77af43d8f271e6590", size = 764713, upload-time = "2026-08-25T16:01:21.792Z" }, + { url = "https://files.pythonhosted.org/packages/2f/53/f4521cfcf98033501ca2810ec0382ae6605c93e10421afd838080ff1141f/py_yaml12-0.2.0-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:9698c027a8bc4b7df73068776f788b9c5a4d63d1d617f26e5e388fb6a52085fa", size = 722182, upload-time = "2026-08-25T16:01:24.551Z" }, + { url = "https://files.pythonhosted.org/packages/7b/c1/2eff4ec879b73b9488ffcc1c288901a44bb39ddf7bf350967b0deab6b18f/py_yaml12-0.2.0-cp314-cp314t-win32.whl", hash = "sha256:782cdb8242871e00194b27e96dd7d9da1d53bfdbfcefe9b67e3f4e47174a1c7c", size = 349109, upload-time = "2026-08-25T16:01:33.303Z" }, + { url = "https://files.pythonhosted.org/packages/b5/8f/db51721e31b6a6496bfa41bf0a5e70c3ce6068d7bf516e58886a4e1239dc/py_yaml12-0.2.0-cp314-cp314t-win_amd64.whl", hash = "sha256:2378cd2f23579e742b3ef817994eb6c90796db556280bb1401267d2d228aa68a", size = 367926, upload-time = "2026-08-25T16:01:29.787Z" }, + { url = "https://files.pythonhosted.org/packages/84/47/a807a742f936601472f7d254ea45a4391edd32741eeafd9cc78b65448b6f/py_yaml12-0.2.0-cp314-cp314t-win_arm64.whl", hash = "sha256:05b272a46322769059a1ba25b9186ecf46af23ce88c6d3a6687157d7be844114", size = 352849, upload-time = "2026-08-25T16:01:27.644Z" }, + { url = "https://files.pythonhosted.org/packages/ee/c6/e804a821889513b538f104006a0b475d2c9acba96b17e2751f34ac13c8d7/py_yaml12-0.2.0-pp311-pypy311_pp73-macosx_10_12_x86_64.whl", hash = "sha256:57073281fa3b2142d8d85f9ff33d273f73d09737112449ce9f5263e76aa4677c", size = 477392, upload-time = "2026-08-25T16:25:01.718Z" }, + { url = "https://files.pythonhosted.org/packages/00/f7/d18d66ee6ab3f0c28bfe78092c3527d4ed9325c4b7ac6653c6d38e163852/py_yaml12-0.2.0-pp311-pypy311_pp73-macosx_11_0_arm64.whl", hash = "sha256:5ad1ff1e855acea94c1045448916aca8b4b4f3e43b4e5eaef3bdc4eada31ce5b", size = 471842, upload-time = "2026-08-25T16:25:00.119Z" }, + { url = "https://files.pythonhosted.org/packages/70/ed/8da8e30455de46c165d35eeb7d32eaa739d15567076701c8b656154597e4/py_yaml12-0.2.0-pp311-pypy311_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ae5f459f2a8e33875be71f9b90c661dc1c59254b41ded0460160cc38b7ec2468", size = 525897, upload-time = "2026-08-25T16:24:58.224Z" }, + { url = "https://files.pythonhosted.org/packages/cf/68/14c5642476d966007e338703e8f77ee5274880c74d5d97954d505d12398d/py_yaml12-0.2.0-pp311-pypy311_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:6476ca71b8308fa4b7da8fae418ba4095042e410ca790de9e0338a914eb79d36", size = 561831, upload-time = "2026-08-25T16:24:56.591Z" }, + { url = "https://files.pythonhosted.org/packages/65/0d/db52ebb29864802969b53f35674978eda5342401a9ccc49986ea50945f1b/py_yaml12-0.2.0-pp311-pypy311_pp73-win_amd64.whl", hash = "sha256:92ce57fc8ef7adaac280420d837f8a86b45dfccb6d0fa38954fbe053c5a354bf", size = 371311, upload-time = "2026-08-25T16:01:30.929Z" }, +] + [[package]] name = "pyarrow" version = "25.0.1" @@ -1812,6 +2733,15 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/93/c0/37d4a7e8e2f7a6076283673d5298018ca26478b934c6ee369e10505ab32c/pyarrow-25.0.1-cp314-cp314t-win_amd64.whl", hash = "sha256:4288f27577352d608ca08553b0865e4a9b3aa14820c5d95b53337218d609835b", size = 28753071, upload-time = "2026-08-10T12:40:46.623Z" }, ] +[[package]] +name = "pycparser" +version = "3.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/1b/7d/92392ff7815c21062bea51aa7b87d45576f649f16458d78b7cf94b9ab2e6/pycparser-3.0.tar.gz", hash = "sha256:600f49d217304a5902ac3c37e1281c9fe94e4d0489de643a9504c5cdfdfc6b29", size = 103492, upload-time = "2026-01-21T14:26:51.89Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/0c/c3/44f3fbbfa403ea2a7c779186dc20772604442dde72947e7d01069cbe98e3/pycparser-3.0-py3-none-any.whl", hash = "sha256:b727414169a36b7d524c1c3e31839a521725078d7b2ff038656844266160a992", size = 48172, upload-time = "2026-01-21T14:26:50.693Z" }, +] + [[package]] name = "pydantic" version = "2.13.4" @@ -2016,6 +2946,15 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/0d/17/c5c6b53ddc18f297992099b3d9ec16c855c0ccc83263a21fe4d1c625ec6c/python_dotenv-1.2.3-py3-none-any.whl", hash = "sha256:904552145e8bfed22162c09dab1c2b9b54fefa7b23ba780f4f26ca0316b0f0d9", size = 22780, upload-time = "2026-08-16T16:54:52.473Z" }, ] +[[package]] +name = "python-json-logger" +version = "4.2.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/21/25/5473e46b179f8e8b4ad3aeeb36773d1701b7770eaf5e5bc2025c7303b598/python_json_logger-4.2.0.tar.gz", hash = "sha256:e371ebe22ec01e289850102091a2b1f6fc9e655c7f1f5f29073936756c290afa", size = 18211, upload-time = "2026-08-15T11:36:38.232Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/dc/55/6467fde553886cb293e41538f3a8b4e4fd4688c6df242cf982162d8367fb/python_json_logger-4.2.0-py3-none-any.whl", hash = "sha256:158a52126fcd6869e09574d2b66272666f3dc8f468c62637ef9a1fa883719cb9", size = 14988, upload-time = "2026-08-15T11:36:36.821Z" }, +] + [[package]] name = "python-multipart" version = "0.0.32" @@ -2026,37 +2965,23 @@ wheels = [ ] [[package]] -name = "pytokens" -version = "0.4.1" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/b6/34/b4e015b99031667a7b960f888889c5bd34ef585c85e1cb56a594b92836ac/pytokens-0.4.1.tar.gz", hash = "sha256:292052fe80923aae2260c073f822ceba21f3872ced9a68bb7953b348e561179a", size = 23015, upload-time = "2026-01-30T01:03:45.924Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/3d/92/790ebe03f07b57e53b10884c329b9a1a308648fc083a6d4a39a10a28c8fc/pytokens-0.4.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:d70e77c55ae8380c91c0c18dea05951482e263982911fc7410b1ffd1dadd3440", size = 160864, upload-time = "2026-01-30T01:02:57.882Z" }, - { url = "https://files.pythonhosted.org/packages/13/25/a4f555281d975bfdd1eba731450e2fe3a95870274da73fb12c40aeae7625/pytokens-0.4.1-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:4a58d057208cb9075c144950d789511220b07636dd2e4708d5645d24de666bdc", size = 248565, upload-time = "2026-01-30T01:02:59.912Z" }, - { url = "https://files.pythonhosted.org/packages/17/50/bc0394b4ad5b1601be22fa43652173d47e4c9efbf0044c62e9a59b747c56/pytokens-0.4.1-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:b49750419d300e2b5a3813cf229d4e5a4c728dae470bcc89867a9ad6f25a722d", size = 260824, upload-time = "2026-01-30T01:03:01.471Z" }, - { url = "https://files.pythonhosted.org/packages/4e/54/3e04f9d92a4be4fc6c80016bc396b923d2a6933ae94b5f557c939c460ee0/pytokens-0.4.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:d9907d61f15bf7261d7e775bd5d7ee4d2930e04424bab1972591918497623a16", size = 264075, upload-time = "2026-01-30T01:03:04.143Z" }, - { url = "https://files.pythonhosted.org/packages/d1/1b/44b0326cb5470a4375f37988aea5d61b5cc52407143303015ebee94abfd6/pytokens-0.4.1-cp311-cp311-win_amd64.whl", hash = "sha256:ee44d0f85b803321710f9239f335aafe16553b39106384cef8e6de40cb4ef2f6", size = 103323, upload-time = "2026-01-30T01:03:05.412Z" }, - { url = "https://files.pythonhosted.org/packages/41/5d/e44573011401fb82e9d51e97f1290ceb377800fb4eed650b96f4753b499c/pytokens-0.4.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:140709331e846b728475786df8aeb27d24f48cbcf7bcd449f8de75cae7a45083", size = 160663, upload-time = "2026-01-30T01:03:06.473Z" }, - { url = "https://files.pythonhosted.org/packages/f0/e6/5bbc3019f8e6f21d09c41f8b8654536117e5e211a85d89212d59cbdab381/pytokens-0.4.1-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:6d6c4268598f762bc8e91f5dbf2ab2f61f7b95bdc07953b602db879b3c8c18e1", size = 255626, upload-time = "2026-01-30T01:03:08.177Z" }, - { url = "https://files.pythonhosted.org/packages/bf/3c/2d5297d82286f6f3d92770289fd439956b201c0a4fc7e72efb9b2293758e/pytokens-0.4.1-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:24afde1f53d95348b5a0eb19488661147285ca4dd7ed752bbc3e1c6242a304d1", size = 269779, upload-time = "2026-01-30T01:03:09.756Z" }, - { url = "https://files.pythonhosted.org/packages/20/01/7436e9ad693cebda0551203e0bf28f7669976c60ad07d6402098208476de/pytokens-0.4.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:5ad948d085ed6c16413eb5fec6b3e02fa00dc29a2534f088d3302c47eb59adf9", size = 268076, upload-time = "2026-01-30T01:03:10.957Z" }, - { url = "https://files.pythonhosted.org/packages/2e/df/533c82a3c752ba13ae7ef238b7f8cdd272cf1475f03c63ac6cf3fcfb00b6/pytokens-0.4.1-cp312-cp312-win_amd64.whl", hash = "sha256:3f901fe783e06e48e8cbdc82d631fca8f118333798193e026a50ce1b3757ea68", size = 103552, upload-time = "2026-01-30T01:03:12.066Z" }, - { url = "https://files.pythonhosted.org/packages/cb/dc/08b1a080372afda3cceb4f3c0a7ba2bde9d6a5241f1edb02a22a019ee147/pytokens-0.4.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:8bdb9d0ce90cbf99c525e75a2fa415144fd570a1ba987380190e8b786bc6ef9b", size = 160720, upload-time = "2026-01-30T01:03:13.843Z" }, - { url = "https://files.pythonhosted.org/packages/64/0c/41ea22205da480837a700e395507e6a24425151dfb7ead73343d6e2d7ffe/pytokens-0.4.1-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:5502408cab1cb18e128570f8d598981c68a50d0cbd7c61312a90507cd3a1276f", size = 254204, upload-time = "2026-01-30T01:03:14.886Z" }, - { url = "https://files.pythonhosted.org/packages/e0/d2/afe5c7f8607018beb99971489dbb846508f1b8f351fcefc225fcf4b2adc0/pytokens-0.4.1-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:29d1d8fb1030af4d231789959f21821ab6325e463f0503a61d204343c9b355d1", size = 268423, upload-time = "2026-01-30T01:03:15.936Z" }, - { url = "https://files.pythonhosted.org/packages/68/d4/00ffdbd370410c04e9591da9220a68dc1693ef7499173eb3e30d06e05ed1/pytokens-0.4.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:970b08dd6b86058b6dc07efe9e98414f5102974716232d10f32ff39701e841c4", size = 266859, upload-time = "2026-01-30T01:03:17.458Z" }, - { url = "https://files.pythonhosted.org/packages/a7/c9/c3161313b4ca0c601eeefabd3d3b576edaa9afdefd32da97210700e47652/pytokens-0.4.1-cp313-cp313-win_amd64.whl", hash = "sha256:9bd7d7f544d362576be74f9d5901a22f317efc20046efe2034dced238cbbfe78", size = 103520, upload-time = "2026-01-30T01:03:18.652Z" }, - { url = "https://files.pythonhosted.org/packages/8f/a7/b470f672e6fc5fee0a01d9e75005a0e617e162381974213a945fcd274843/pytokens-0.4.1-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:4a14d5f5fc78ce85e426aa159489e2d5961acf0e47575e08f35584009178e321", size = 160821, upload-time = "2026-01-30T01:03:19.684Z" }, - { url = "https://files.pythonhosted.org/packages/80/98/e83a36fe8d170c911f864bfded690d2542bfcfacb9c649d11a9e6eb9dc41/pytokens-0.4.1-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:97f50fd18543be72da51dd505e2ed20d2228c74e0464e4262e4899797803d7fa", size = 254263, upload-time = "2026-01-30T01:03:20.834Z" }, - { url = "https://files.pythonhosted.org/packages/0f/95/70d7041273890f9f97a24234c00b746e8da86df462620194cef1d411ddeb/pytokens-0.4.1-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:dc74c035f9bfca0255c1af77ddd2d6ae8419012805453e4b0e7513e17904545d", size = 268071, upload-time = "2026-01-30T01:03:21.888Z" }, - { url = "https://files.pythonhosted.org/packages/da/79/76e6d09ae19c99404656d7db9c35dfd20f2086f3eb6ecb496b5b31163bad/pytokens-0.4.1-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:f66a6bbe741bd431f6d741e617e0f39ec7257ca1f89089593479347cc4d13324", size = 271716, upload-time = "2026-01-30T01:03:23.633Z" }, - { url = "https://files.pythonhosted.org/packages/79/37/482e55fa1602e0a7ff012661d8c946bafdc05e480ea5a32f4f7e336d4aa9/pytokens-0.4.1-cp314-cp314-win_amd64.whl", hash = "sha256:b35d7e5ad269804f6697727702da3c517bb8a5228afa450ab0fa787732055fc9", size = 104539, upload-time = "2026-01-30T01:03:24.788Z" }, - { url = "https://files.pythonhosted.org/packages/30/e8/20e7db907c23f3d63b0be3b8a4fd1927f6da2395f5bcc7f72242bb963dfe/pytokens-0.4.1-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:8fcb9ba3709ff77e77f1c7022ff11d13553f3c30299a9fe246a166903e9091eb", size = 168474, upload-time = "2026-01-30T01:03:26.428Z" }, - { url = "https://files.pythonhosted.org/packages/d6/81/88a95ee9fafdd8f5f3452107748fd04c24930d500b9aba9738f3ade642cc/pytokens-0.4.1-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:79fc6b8699564e1f9b521582c35435f1bd32dd06822322ec44afdeba666d8cb3", size = 290473, upload-time = "2026-01-30T01:03:27.415Z" }, - { url = "https://files.pythonhosted.org/packages/cf/35/3aa899645e29b6375b4aed9f8d21df219e7c958c4c186b465e42ee0a06bf/pytokens-0.4.1-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:d31b97b3de0f61571a124a00ffe9a81fb9939146c122c11060725bd5aea79975", size = 303485, upload-time = "2026-01-30T01:03:28.558Z" }, - { url = "https://files.pythonhosted.org/packages/52/a0/07907b6ff512674d9b201859f7d212298c44933633c946703a20c25e9d81/pytokens-0.4.1-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:967cf6e3fd4adf7de8fc73cd3043754ae79c36475c1c11d514fc72cf5490094a", size = 306698, upload-time = "2026-01-30T01:03:29.653Z" }, - { url = "https://files.pythonhosted.org/packages/39/2a/cbbf9250020a4a8dd53ba83a46c097b69e5eb49dd14e708f496f548c6612/pytokens-0.4.1-cp314-cp314t-win_amd64.whl", hash = "sha256:584c80c24b078eec1e227079d56dc22ff755e0ba8654d8383b2c549107528918", size = 116287, upload-time = "2026-01-30T01:03:30.912Z" }, - { url = "https://files.pythonhosted.org/packages/c6/78/397db326746f0a342855b81216ae1f0a32965deccfd7c830a2dbc66d2483/pytokens-0.4.1-py3-none-any.whl", hash = "sha256:26cef14744a8385f35d0e095dc8b3a7583f6c953c2e3d269c7f82484bf5ad2de", size = 13729, upload-time = "2026-01-30T01:03:45.029Z" }, +name = "pywinpty" +version = "3.0.5" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/a9/ef/2d27f30c59a67be7025b2d7858c8c2d282b74d66544b2384730b82de74fd/pywinpty-3.0.5.tar.gz", hash = "sha256:61db0db063de9865adbea66db294628f8577f608d9764a4c7d3384eeacc4e81b", size = 16223484, upload-time = "2026-06-11T00:11:58.93Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/b0/5c/31feb3dd82d1b33ae0bd09ca601edb993d9da1b7f0226b3336d4b4c39e1e/pywinpty-3.0.5-cp311-cp311-win_amd64.whl", hash = "sha256:af7a8720c78776ddd6259b71dd567944f766a6cd67f8d2887fbc4973967bacda", size = 2092466, upload-time = "2026-06-10T23:44:24.453Z" }, + { url = "https://files.pythonhosted.org/packages/ee/fe/fe23e2229ffec0c10190cef5964f5c9b2dba179d23b69ae537b7ea90bcab/pywinpty-3.0.5-cp311-cp311-win_arm64.whl", hash = "sha256:c2406f54f699eab75953fb75ce805f2ae55a33a957cd070890abd454fb4b7680", size = 818395, upload-time = "2026-06-10T23:41:56.93Z" }, + { url = "https://files.pythonhosted.org/packages/45/34/942cc95ca4e26489875aa8a95192766247a687379ec29543eebe73ec945f/pywinpty-3.0.5-cp312-cp312-win_amd64.whl", hash = "sha256:d62946adf14b15b54c0b8d785f93fe18b04da23f4ad59e2e8c4612646e9abd23", size = 2090915, upload-time = "2026-06-10T23:43:14.98Z" }, + { url = "https://files.pythonhosted.org/packages/6a/70/5b9053004844139ea8bd86209c57ade12b134b2782f383a095784c8531ec/pywinpty-3.0.5-cp312-cp312-win_arm64.whl", hash = "sha256:e9391c05fbfa7a992a97e831fc6849887b4014a614192e3d984a7ca59592b376", size = 815934, upload-time = "2026-06-10T23:41:42.384Z" }, + { url = "https://files.pythonhosted.org/packages/b9/f4/2a464b9893cceb3b3f416356e94fdc3e1bca9476993927e4e6d99fe95382/pywinpty-3.0.5-cp313-cp313-win_amd64.whl", hash = "sha256:48db1b0ad9d0a1b81dcaaa7163a99a7808deaceb0c1b2344716dc1fc090c3c4c", size = 2090471, upload-time = "2026-06-10T23:42:11.071Z" }, + { url = "https://files.pythonhosted.org/packages/3c/2c/a138491a0afbdb50eb79395577bd326d4b0fbde7209417d1a8087ff2493a/pywinpty-3.0.5-cp313-cp313-win_arm64.whl", hash = "sha256:2c6008fb2d3774b48693b2fcb7f2cc317ade9dc581289a964ffeeaf81307c9b5", size = 815518, upload-time = "2026-06-10T23:42:02.363Z" }, + { url = "https://files.pythonhosted.org/packages/6f/15/54400049a380582acd1282665c70fcf11e0bd3713679aca78e24c3aae738/pywinpty-3.0.5-cp313-cp313t-win_amd64.whl", hash = "sha256:22ce1b780d89821cc52daf6eac0708af22d93d000ce9c7c07e37489db8594598", size = 2089920, upload-time = "2026-06-10T23:44:13.395Z" }, + { url = "https://files.pythonhosted.org/packages/94/0c/6f24f3c0799f502259b24bdf841a99ad2b0d59df5c2525b4e2a286d14be2/pywinpty-3.0.5-cp313-cp313t-win_arm64.whl", hash = "sha256:9c2919a81bc5cfb09b86fc5a002112b2de95ca4304a07413cbeeb746a1307a5c", size = 814520, upload-time = "2026-06-10T23:43:28.588Z" }, + { url = "https://files.pythonhosted.org/packages/e9/23/f3cd1b1e5fc56517f54452c49f92049e7dd9ffc8a63de22a495581f50d04/pywinpty-3.0.5-cp314-cp314-win_amd64.whl", hash = "sha256:03bb3c16d691d9242267201830bcd0e64a9b663170e9042bc84b210da9de15ac", size = 2090663, upload-time = "2026-06-10T23:43:59.845Z" }, + { url = "https://files.pythonhosted.org/packages/9d/dd/96d6cbfc6d9ddab5c1c2f92c26545ae8997446a2ba7ee2024cd43c81f49b/pywinpty-3.0.5-cp314-cp314-win_arm64.whl", hash = "sha256:89c5c6ef08997a3b4b277b214a35fe15cab4dd6d119f0140aa71df5b1168fdbc", size = 815700, upload-time = "2026-06-10T23:40:50.001Z" }, + { url = "https://files.pythonhosted.org/packages/30/36/d98087bce0acaa4cce7f196103cfa7be3f63ce65f52473bb3e38784ae5d9/pywinpty-3.0.5-cp314-cp314t-win_amd64.whl", hash = "sha256:7b566165e0c5fdd6abe167a5ac8b954be6a843eb55a85946576d6bc1dea03d6d", size = 2090093, upload-time = "2026-06-10T23:40:58.933Z" }, + { url = "https://files.pythonhosted.org/packages/57/fd/fe2b0db922ba052ce3976a08f3fc05d0c05047c8b4ebb6102e832b8ef563/pywinpty-3.0.5-cp314-cp314t-win_arm64.whl", hash = "sha256:24366280a8aa677323da87bec729cb3ea3b35367386cece0978bdc6e4695c690", size = 814517, upload-time = "2026-06-10T23:42:34.946Z" }, ] [[package]] @@ -2115,27 +3040,67 @@ wheels = [ ] [[package]] -name = "quartodoc" -version = "0.11.1" +name = "pyzmq" +version = "27.2.0" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "black" }, - { name = "click" }, - { name = "griffe" }, - { name = "importlib-metadata" }, - { name = "importlib-resources" }, - { name = "plum-dispatch" }, - { name = "pydantic" }, - { name = "pyyaml" }, - { name = "requests" }, - { name = "sphobjinv" }, - { name = "tabulate" }, - { name = "typing-extensions" }, - { name = "watchdog" }, + { name = "cffi", marker = "implementation_name == 'pypy'" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/ff/b9/0bb44cc62a5d63728d04fd6b1e14bcb64945fabad4aa8c03b9d70315fb06/quartodoc-0.11.1.tar.gz", hash = "sha256:c121626e1a36392d168631f33c4d3e7fd48d185de178859f8eafbda14fbfe92f", size = 778611, upload-time = "2025-06-10T14:50:08.185Z" } +sdist = { url = "https://files.pythonhosted.org/packages/e7/8d/5b3d5631c2f4b4b8862f64cd0c9eb777b5710eeb5125b4be8dd0a200a4c0/pyzmq-27.2.0.tar.gz", hash = "sha256:54d4259d1bfae24ecdb5ca79f7acc2eac6c286a02d6a0ae617797cb45f0726d3", size = 292316, upload-time = "2026-08-20T19:08:21.19Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/75/d9/0b48d4184f9ca6a996c4fac46897a968698c9d1e0f0e43a6906746201323/quartodoc-0.11.1-py3-none-any.whl", hash = "sha256:0776eb8e53d89385e2c9a8ae0ec08e8c307c1410dd1bd78bb28e8b1823dbb6ad", size = 88053, upload-time = "2025-06-10T14:50:06.443Z" }, + { url = "https://files.pythonhosted.org/packages/1d/2e/8897afa4538707d86645f51cc50e66b2b84900edb1be9dc9af2c2fc04e5d/pyzmq-27.2.0-cp311-cp311-macosx_10_15_universal2.whl", hash = "sha256:9216132843d139a123f243c07fe70f7487dce5041093dd77040f9adb5dc91872", size = 1457109, upload-time = "2026-08-20T19:06:26.022Z" }, + { url = "https://files.pythonhosted.org/packages/d1/bc/dbce7bc1654fa25b1e68b9bad9e547906f581ce919c186a88ed951cb794c/pyzmq-27.2.0-cp311-cp311-manylinux2014_i686.manylinux_2_17_i686.whl", hash = "sha256:d41ebb260b69329b7d4a2936d44c872c86dd785355b51366c8b14e07ed7e9373", size = 985701, upload-time = "2026-08-20T19:06:27.481Z" }, + { url = "https://files.pythonhosted.org/packages/95/cf/6981738b57c83fef33f356141ad83bf51e92f2f70c9d5767affd1a699f07/pyzmq-27.2.0-cp311-cp311-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:468139ddb2e494d06e586bd3a6835077e8b3764560c8db552fe685c5867fc24e", size = 714285, upload-time = "2026-08-20T19:06:28.962Z" }, + { url = "https://files.pythonhosted.org/packages/50/b5/13657961a845e29c28a4e7ac4202999ec90b3bba1890a5469ce2ae90359d/pyzmq-27.2.0-cp311-cp311-manylinux_2_26_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:39755dc4a923021bd0677990ffdbc21cff0e1ee1cf07fe3817acea153ef4cb67", size = 888465, upload-time = "2026-08-20T19:06:30.4Z" }, + { url = "https://files.pythonhosted.org/packages/58/5a/ca7ee7a767413d4ba858e93748b95e30b35b8c139849fba94de4433ea2e5/pyzmq-27.2.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:714f8cbd66c7e405338d668f79d2fe83fe923defe348e843be998603cf92eeff", size = 1705731, upload-time = "2026-08-20T19:06:31.819Z" }, + { url = "https://files.pythonhosted.org/packages/0b/8b/083f6184e4eba566c9a3cc9974b1b0fe327b7093788135ba8133edaa67a6/pyzmq-27.2.0-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:1132805970045adb9f5f05dd57040978286a8e21a5475f2c2ddf1bc983b9a2c7", size = 2074243, upload-time = "2026-08-20T19:06:33.36Z" }, + { url = "https://files.pythonhosted.org/packages/57/f5/249362b664ae725d534c8843214fa9fd7fccd74532a19e24603954a88a7d/pyzmq-27.2.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:b26f2d0493b79ce3c3112c8a12649418915582ba4707b8ed9f44febf2be71f42", size = 1926859, upload-time = "2026-08-20T19:06:34.796Z" }, + { url = "https://files.pythonhosted.org/packages/bf/cc/23c613c15f06d879f13364d14c17e5e4e8304049411e96c1410e6e56c3ea/pyzmq-27.2.0-cp311-cp311-win32.whl", hash = "sha256:44f261eca7dfb9904ea2b56428f59ab693bbe2715c0413a701f17b067ebf877c", size = 570747, upload-time = "2026-08-20T19:06:36.337Z" }, + { url = "https://files.pythonhosted.org/packages/dc/bc/bbbcf89003c93f18e33665c26e3c48d75e3915c3dd22887f3a7aea2c5e26/pyzmq-27.2.0-cp311-cp311-win_amd64.whl", hash = "sha256:8b86e04f55af0f4d8cd8ecf14c0b8b81ebc8fd66fa20126b753514628ecadc7e", size = 644845, upload-time = "2026-08-20T19:06:37.711Z" }, + { url = "https://files.pythonhosted.org/packages/14/c5/4635d0ba2b8493edf6d5541fff0b07fa1d986fdfc29c596a53a21e20f9af/pyzmq-27.2.0-cp311-cp311-win_arm64.whl", hash = "sha256:917d601e9540098f580d2723d0ce6402cdb6f02bc8dc2de74e0dca6e13bffd1b", size = 567495, upload-time = "2026-08-20T19:06:39.246Z" }, + { url = "https://files.pythonhosted.org/packages/57/8a/153532fa53db30e116118164f3af269a1f3966b3e2ba32c89b12fe864bd8/pyzmq-27.2.0-cp312-abi3-macosx_10_15_universal2.whl", hash = "sha256:591c8de5851c5ea372194469fe97587b97c3b641e9a70f31bb3474acbfde0241", size = 1431074, upload-time = "2026-08-20T19:06:40.601Z" }, + { url = "https://files.pythonhosted.org/packages/c8/ef/c08b91248bb90a9efa81fa00ba81b69c157c74d0c5efbb2c319d91babb62/pyzmq-27.2.0-cp312-abi3-manylinux2014_i686.manylinux_2_17_i686.whl", hash = "sha256:00e73942ef12cecbc7951c4a9104bb8ffaed742abb13af2da6833d90dd368cef", size = 973915, upload-time = "2026-08-20T19:06:42.037Z" }, + { url = "https://files.pythonhosted.org/packages/b4/78/a3a3a86c2b00fadb92ece1ca4f8f028d62b2ce9ac3526097239ab2d6fba9/pyzmq-27.2.0-cp312-abi3-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:1f8079d0521fe94bbb401fe9407578b28f3701627c8be2c9f7e0c5b77dcb0109", size = 697722, upload-time = "2026-08-20T19:06:43.325Z" }, + { url = "https://files.pythonhosted.org/packages/62/2c/d5828306f795e8d34676d266823b74e2101e0ad3760d12083de3e02abbb2/pyzmq-27.2.0-cp312-abi3-manylinux_2_26_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:dea74fd65f1fc5f7fe167916a473ebe6ed6174e5e5d9de11ea6583661be6cf43", size = 872258, upload-time = "2026-08-20T19:06:44.627Z" }, + { url = "https://files.pythonhosted.org/packages/09/52/51253b78fd8739293e283407eeecb14215c02c71b6519af21f6eed8e69cd/pyzmq-27.2.0-cp312-abi3-manylinux_2_38_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:dcc99ca132b667a4ed750afd42db4ea73288f18425a9b2e3c0af095665c491f5", size = 739591, upload-time = "2026-08-20T19:06:46.214Z" }, + { url = "https://files.pythonhosted.org/packages/e6/3e/142c85b67a4c9678629b0cf6d5125b29663d75be69bfaa57a3cac344d780/pyzmq-27.2.0-cp312-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:b8d5f66e4a8246cf77f7b8f7902af64f00553368fa0373c89d99b78f0ad79394", size = 1689031, upload-time = "2026-08-20T19:06:47.612Z" }, + { url = "https://files.pythonhosted.org/packages/0e/ee/0776fb0f98ed1eb74d77240087fef0ab045b6ad15cb09555c6c5134c98ad/pyzmq-27.2.0-cp312-abi3-musllinux_1_2_i686.whl", hash = "sha256:d1526b42a2e725b84ed226f37becedc250c6347594e5ed304e4e9aff68c9aec3", size = 2059547, upload-time = "2026-08-20T19:06:49.064Z" }, + { url = "https://files.pythonhosted.org/packages/aa/0e/ec77f691a4aebe29ab6329f996fb0e0270c876a3016086e3ca6ef733bcae/pyzmq-27.2.0-cp312-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:f707bcf2c1d007d14d70531d4dd7b41060881c73efa845580bf6faaf9ea24d42", size = 1910457, upload-time = "2026-08-20T19:06:50.783Z" }, + { url = "https://files.pythonhosted.org/packages/30/97/1f5530ff4fc271b4597048371d5af972c2baab51be132ba15874e0327a6a/pyzmq-27.2.0-cp312-abi3-win32.whl", hash = "sha256:fdaaa4ea3242f6ad298eb5177eb042aea5c73c30e76d20caee7b15af20d24ec2", size = 563450, upload-time = "2026-08-20T19:06:52.307Z" }, + { url = "https://files.pythonhosted.org/packages/02/8b/b83f7780dad22e0878e4c7bd9158ebd24ed12bc3d5e3a471cd0576f77ded/pyzmq-27.2.0-cp312-abi3-win_amd64.whl", hash = "sha256:2c218c6ab8bc447ba62054b581fd30209689d199c6ecb253f79615ca74a38e12", size = 628633, upload-time = "2026-08-20T19:06:53.809Z" }, + { url = "https://files.pythonhosted.org/packages/52/aa/3918b5ac7f9987bd9c421b065074fd7409ded88f856f2c704a24341877ec/pyzmq-27.2.0-cp312-abi3-win_arm64.whl", hash = "sha256:348d6fd3e4b81ae4580622ea8c2ea60224e84b2ac1b3be4482e6edc7de06e7a3", size = 556006, upload-time = "2026-08-20T19:06:55.242Z" }, + { url = "https://files.pythonhosted.org/packages/83/5e/d0541596b48c5a19f85dcbea83d6673d8e91681cdf853eb194c31fc9766e/pyzmq-27.2.0-cp313-cp313-android_24_arm64_v8a.whl", hash = "sha256:c551b9e2f86dc625fcb1a032c0d68042678caf96a8dd7c28796766b673bd5b52", size = 1127193, upload-time = "2026-08-20T19:06:56.545Z" }, + { url = "https://files.pythonhosted.org/packages/50/9f/8c7411bb283982d46e6d56dca6a095678c87eb0398daead12776d9881ac2/pyzmq-27.2.0-cp313-cp313-android_24_x86_64.whl", hash = "sha256:288cc790da0e3064a14a38ddc56ba169dada8c8af4cb86518db2bcbd380eedbb", size = 1166833, upload-time = "2026-08-20T19:06:58.011Z" }, + { url = "https://files.pythonhosted.org/packages/f9/84/a849161ff88b2de9b991cc8ab332218824741122fdc4fdf222a5b822ac8c/pyzmq-27.2.0-cp314-cp314-android_24_arm64_v8a.whl", hash = "sha256:3d45189c0c3c99f817b7fefff0d32eeef684cf33e1e3c0fc4281515357c54702", size = 1134452, upload-time = "2026-08-20T19:06:59.898Z" }, + { url = "https://files.pythonhosted.org/packages/3c/34/ff4aaff0cfba2a4d7ad1a16ffedc52c6deb89fcf673d455085446b23f215/pyzmq-27.2.0-cp314-cp314-android_24_x86_64.whl", hash = "sha256:d61910b52be5b2cd8b248dbcbe3a1b0275556a7d99fb613fc43323b546e273b8", size = 1167520, upload-time = "2026-08-20T19:07:01.283Z" }, + { url = "https://files.pythonhosted.org/packages/b6/07/42111e9dc1041d78b4443d6eb1b82b027f1a58178dc8a38385effbc72ad5/pyzmq-27.2.0-cp314-cp314t-macosx_10_15_universal2.whl", hash = "sha256:3ab6eb88590e510ab16715c32dbba12000da9bee989fdadd9ee19a234c492eb7", size = 1466289, upload-time = "2026-08-20T19:07:02.738Z" }, + { url = "https://files.pythonhosted.org/packages/4b/b4/def7a478458da78665840564161772e7e938600c32a89f28e8b221b54d2d/pyzmq-27.2.0-cp314-cp314t-manylinux2014_i686.manylinux_2_17_i686.whl", hash = "sha256:1ecbdd131b9669f62d3a45afee5527c7ae9f141e4301267f21714c90bd21725f", size = 975868, upload-time = "2026-08-20T19:07:04.155Z" }, + { url = "https://files.pythonhosted.org/packages/38/d5/e3e85f7fea37153097aaff49db9e33093909cc2a7b22c1ac4ebe546600fc/pyzmq-27.2.0-cp314-cp314t-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:3146385b94a760236c5eceff468a66a296a716ca98a2e0f9217b1518118466b1", size = 706054, upload-time = "2026-08-20T19:07:05.623Z" }, + { url = "https://files.pythonhosted.org/packages/1c/ef/3b7d9449b223183222bf517245e1e53d5f1ab8c10be8b45f6a301b2f994a/pyzmq-27.2.0-cp314-cp314t-manylinux_2_26_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:9846e881620dd62566ca76a53e384c3f37490faf4b9240aebc7498810dfca853", size = 878984, upload-time = "2026-08-20T19:07:07.153Z" }, + { url = "https://files.pythonhosted.org/packages/be/a5/8b49dbd494f6dcfda69dc4cade322a4b02706ef4e3d30cc366d4e369899f/pyzmq-27.2.0-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:d9527e3dbaef1edaeeb2446fa7379446814a43ade8adc7c4a5ebe69437815ddd", size = 1697489, upload-time = "2026-08-20T19:07:08.945Z" }, + { url = "https://files.pythonhosted.org/packages/da/5a/4bb8280901130c26ea25f0cbb4a6d39d94250860c6b3dbd912f1cf48fca7/pyzmq-27.2.0-cp314-cp314t-musllinux_1_2_i686.whl", hash = "sha256:56b48fa9d478a3af7254f397697a62f5ad3e1bb677e200b2701f0c290d97e5af", size = 2064236, upload-time = "2026-08-20T19:07:10.384Z" }, + { url = "https://files.pythonhosted.org/packages/de/38/f433af66922554adb2b5f79e897018c8e19a90b9eaeb49c4814f8355ebe4/pyzmq-27.2.0-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:bf0b6e4ce1bb089751c504c5493d6b0557eabd02dd21b76e9086cf964234b103", size = 1917424, upload-time = "2026-08-20T19:07:11.909Z" }, + { url = "https://files.pythonhosted.org/packages/36/81/ea1c1ae3f801d96ba2c269e056761ebcfe023476e651d3af2a7817962051/pyzmq-27.2.0-cp314-cp314t-win32.whl", hash = "sha256:fba8afcf265c6e9fbe1594cb045d4765c6c9a7d607653a8196067ef23566b843", size = 591103, upload-time = "2026-08-20T19:07:13.451Z" }, + { url = "https://files.pythonhosted.org/packages/8a/04/149a627707e780fa9f2c1ede3590c14fa6b18b5576d15744342622299a50/pyzmq-27.2.0-cp314-cp314t-win_amd64.whl", hash = "sha256:d1bc1d380a91d954ed5fc9f12915dba014eed0978d2de05ee7ca688bdaac144a", size = 670215, upload-time = "2026-08-20T19:07:15.069Z" }, + { url = "https://files.pythonhosted.org/packages/30/ba/f9c3c1536c41ef3dbf765ea04218990e2056e558f98184ecd883767fc501/pyzmq-27.2.0-cp314-cp314t-win_arm64.whl", hash = "sha256:c7cfb75caa83f5153c687e9d2107f64b5ef0ef0d6edd260d3ff920baaaa69101", size = 582252, upload-time = "2026-08-20T19:07:16.582Z" }, + { url = "https://files.pythonhosted.org/packages/fa/00/78fe097a304a408275747ce43f20428789130b059c5649956277c20f30cf/pyzmq-27.2.0-cp315-cp315-android_24_arm64_v8a.whl", hash = "sha256:c5129a8fe43ecc49b99eb75616603d483a3c2fcaef504988fafe8ea392aea98b", size = 1134295, upload-time = "2026-08-20T19:07:17.94Z" }, + { url = "https://files.pythonhosted.org/packages/f2/83/1c36270658d2ee56e23a3f9ef5fbcb94cbd2f9fe966a6641f2f38e697162/pyzmq-27.2.0-cp315-cp315-android_24_x86_64.whl", hash = "sha256:baa2ce3485145653194d6c8c5beedd1e9f0bf46a0919c9fa2fe2204fc35b74d9", size = 1167492, upload-time = "2026-08-20T19:07:19.476Z" }, + { url = "https://files.pythonhosted.org/packages/58/b2/f0ae223438d7faa991f6feefdc823815f11cc604f898738376b59fd96515/pyzmq-27.2.0-cp315-cp315t-macosx_10_15_universal2.whl", hash = "sha256:e1ed46048d1920cabc96d952a0d5cfe4127ad8db572c335aae4e3c57b9278d7f", size = 1465992, upload-time = "2026-08-20T19:07:20.941Z" }, + { url = "https://files.pythonhosted.org/packages/59/46/fb56f3f37a6a0937b0e1d2885e808b5eedc171320bac85573cfae78fa9bc/pyzmq-27.2.0-cp315-cp315t-manylinux2014_i686.manylinux_2_17_i686.whl", hash = "sha256:e0fa0bc6b1a184aee59b32efcd1b7f0e6d5b8f9387799e4c16a4cb66a86747d6", size = 976118, upload-time = "2026-08-20T19:07:22.577Z" }, + { url = "https://files.pythonhosted.org/packages/21/82/a2c9bfd7c4d34eea1278493cd041bc000d41acb4463c89ceaad29dc813b6/pyzmq-27.2.0-cp315-cp315t-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:0f4bd6743e8bf854c3bfce892dd6578a514aabf128e37a4b2eafcf01856f7e44", size = 705968, upload-time = "2026-08-20T19:07:24.019Z" }, + { url = "https://files.pythonhosted.org/packages/d6/12/b906b269116b6591dc15c0acc5d04c043957c8a531d336999731f4b1d899/pyzmq-27.2.0-cp315-cp315t-manylinux_2_26_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:95369ed6626afcfe2ac89832fb1b917c077fbeb905fbbe5d918349ce0222b89b", size = 879011, upload-time = "2026-08-20T19:07:25.428Z" }, + { url = "https://files.pythonhosted.org/packages/12/13/f96359534bfb77651c15f1fbfc4bfdd7ec3489d23f434706d39598dd0dcd/pyzmq-27.2.0-cp315-cp315t-musllinux_1_2_aarch64.whl", hash = "sha256:40124779c3a56ad5d91902df1ff89159cb414b6c1a0ee697abcc66cf5e6db62d", size = 1697496, upload-time = "2026-08-20T19:07:26.821Z" }, + { url = "https://files.pythonhosted.org/packages/21/b4/2c007ae5f2fe5eca86cbfbc874ed86b5135f2f7812615dfd78606d3c93f6/pyzmq-27.2.0-cp315-cp315t-musllinux_1_2_i686.whl", hash = "sha256:ec8a318dfc27c7d946651b3d9e8025d5734f30c168a822195601827207bac09b", size = 2064347, upload-time = "2026-08-20T19:07:28.315Z" }, + { url = "https://files.pythonhosted.org/packages/9b/88/767af3a6630c15215f3a66700ec79598a375edd1fdc9d75a3ad522178c01/pyzmq-27.2.0-cp315-cp315t-musllinux_1_2_x86_64.whl", hash = "sha256:88c0fac061bac269076edeb3a209acefc96cd6167c239daf1c2b404ac48d7012", size = 1917360, upload-time = "2026-08-20T19:07:29.693Z" }, + { url = "https://files.pythonhosted.org/packages/35/c1/80dd2d20d6e57bc68e1dce1e84bf3e76c9577c1bf728199985c8b4ea0fd1/pyzmq-27.2.0-cp315-cp315t-win32.whl", hash = "sha256:ac126d48cf18aa955daabef43bf0009ff76ad4deee437d09ecf15388214b5beb", size = 591073, upload-time = "2026-08-20T19:07:31.341Z" }, + { url = "https://files.pythonhosted.org/packages/f8/b5/33b781666f3f52ae834bc9c8e38f4f0483a826c5a91cccc993292007bf10/pyzmq-27.2.0-cp315-cp315t-win_amd64.whl", hash = "sha256:edce90a1e588ec63adbf612cc0ad582de4169cd216c7ae53c15f42a2ee902f35", size = 670701, upload-time = "2026-08-20T19:07:32.895Z" }, + { url = "https://files.pythonhosted.org/packages/6e/97/bc4f0edefb992df4fdebcf9f0cc40f631cd4ed277e1ed59ef2cd99a5c8c5/pyzmq-27.2.0-cp315-cp315t-win_arm64.whl", hash = "sha256:a843094b4d3d633bc3623e47a2ff50742d6af02bc1f7606aa2e67e971e21878d", size = 581985, upload-time = "2026-08-20T19:07:34.19Z" }, + { url = "https://files.pythonhosted.org/packages/93/22/7187a1f0bf2b8bf8dc6b91762438fb9b472f684f2dc4cb74a24bf8957943/pyzmq-27.2.0-pp311-pypy311_pp73-macosx_10_15_x86_64.whl", hash = "sha256:a7c1144dc61777938e932a2c9011b980b89fd8ff3733033b34c44c299187a6e1", size = 875015, upload-time = "2026-08-20T19:08:01.692Z" }, + { url = "https://files.pythonhosted.org/packages/92/71/09b71620ad52bad4eb68b1516978ecaf52ef623c3fa16e0732a03cf3274c/pyzmq-27.2.0-pp311-pypy311_pp73-macosx_11_0_arm64.whl", hash = "sha256:c218b816220d05acf6ab1bafca58926d95cbcc5fec5024724666030466308f0c", size = 774395, upload-time = "2026-08-20T19:08:03.108Z" }, + { url = "https://files.pythonhosted.org/packages/9c/cf/5c8eb9994a14ff5ee5b0cada339421748746c95aee0280c8b656741e8749/pyzmq-27.2.0-pp311-pypy311_pp73-manylinux2014_i686.manylinux_2_17_i686.whl", hash = "sha256:ae6ebbc0bfe5a21ce21e32ba567bf73df2d93888109c65acbd42506cf9395759", size = 877994, upload-time = "2026-08-20T19:08:04.724Z" }, + { url = "https://files.pythonhosted.org/packages/97/64/e22094c5555e550b6450ecfcceb6a1205d893d9a18ae27764c8c45acfb16/pyzmq-27.2.0-pp311-pypy311_pp73-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:679b5b1dde326a921ea2c9ec1f9ea3115bfe1b4735779bbc6eb0473a0ed93f71", size = 614492, upload-time = "2026-08-20T19:08:06.487Z" }, + { url = "https://files.pythonhosted.org/packages/d2/28/5b1042899caed18278c56d54a502f5254d463afe8aea1acbecc98e053391/pyzmq-27.2.0-pp311-pypy311_pp73-manylinux_2_26_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:f5c6d8744d10b5e1eadd90a7c58f8546acf6bf680ee463f7e6ada09ad6c9f802", size = 780574, upload-time = "2026-08-20T19:08:07.987Z" }, + { url = "https://files.pythonhosted.org/packages/77/a3/f134603a671c114c6b56eb912bba890f09e2d43b8a28d243be5a5507cf2f/pyzmq-27.2.0-pp311-pypy311_pp73-win_amd64.whl", hash = "sha256:3ee8dd7031d5e23f632e0e7eee67183ca7d2536e0de35dc1e5d69f3471a791e8", size = 553961, upload-time = "2026-08-20T19:08:09.651Z" }, ] [[package]] @@ -2199,6 +3164,39 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/a0/f4/c67b0b3f1b9245e8d266f0f112c500d50e5b4e83cb6f3b71b6528104182a/requests-2.34.2-py3-none-any.whl", hash = "sha256:2a0d60c172f83ac6ab31e4554906c0f3b3588d37b5cb939b1c061f4907e278e0", size = 73075, upload-time = "2026-05-14T19:25:26.443Z" }, ] +[[package]] +name = "rfc3339-validator" +version = "0.1.4" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "six" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/28/ea/a9387748e2d111c3c2b275ba970b735e04e15cdb1eb30693b6b5708c4dbd/rfc3339_validator-0.1.4.tar.gz", hash = "sha256:138a2abdf93304ad60530167e51d2dfb9549521a836871b88d7f4695d0022f6b", size = 5513, upload-time = "2021-05-12T16:37:54.178Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/7b/44/4e421b96b67b2daff264473f7465db72fbdf36a07e05494f50300cc7b0c6/rfc3339_validator-0.1.4-py2.py3-none-any.whl", hash = "sha256:24f6ec1eda14ef823da9e36ec7113124b39c04d50a4d3d3a3c2859577e7791fa", size = 3490, upload-time = "2021-05-12T16:37:52.536Z" }, +] + +[[package]] +name = "rfc3986-validator" +version = "0.1.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/da/88/f270de456dd7d11dcc808abfa291ecdd3f45ff44e3b549ffa01b126464d0/rfc3986_validator-0.1.1.tar.gz", hash = "sha256:3d44bde7921b3b9ec3ae4e3adca370438eccebc676456449b145d533b240d055", size = 6760, upload-time = "2019-10-28T16:00:19.144Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/9e/51/17023c0f8f1869d8806b979a2bffa3f861f26a3f1a66b094288323fba52f/rfc3986_validator-0.1.1-py2.py3-none-any.whl", hash = "sha256:2f235c432ef459970b4306369336b9d5dbdda31b510ca1e327636e01f528bfa9", size = 4242, upload-time = "2019-10-28T16:00:13.976Z" }, +] + +[[package]] +name = "rfc3987-syntax" +version = "1.1.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "lark" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/2c/06/37c1a5557acf449e8e406a830a05bf885ac47d33270aec454ef78675008d/rfc3987_syntax-1.1.0.tar.gz", hash = "sha256:717a62cbf33cffdd16dfa3a497d81ce48a660ea691b1ddd7be710c22f00b4a0d", size = 14239, upload-time = "2025-07-18T01:05:05.015Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/7e/71/44ce230e1b7fadd372515a97e32a83011f906ddded8d03e3c6aafbdedbb7/rfc3987_syntax-1.1.0-py3-none-any.whl", hash = "sha256:6c3d97604e4c5ce9f714898e05401a0445a641cfa276432b0a648c80856f6a3f", size = 8046, upload-time = "2025-07-18T01:05:03.843Z" }, +] + [[package]] name = "rich" version = "15.0.0" @@ -2360,6 +3358,15 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/0e/fe/da8b9e1347696bb22120b77280ec5ce25d500ca5cb39d5ad6e5c18de19c1/ruff-0.16.4-py3-none-win_arm64.whl", hash = "sha256:a3a61621c9b6f6a89573e938a080e648f1695baa3f58570a3a707bc51ff65a21", size = 10451579, upload-time = "2026-08-20T17:43:57.135Z" }, ] +[[package]] +name = "send2trash" +version = "2.1.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/c5/f0/184b4b5f8d00f2a92cf96eec8967a3d550b52cf94362dad1100df9e48d57/send2trash-2.1.0.tar.gz", hash = "sha256:1c72b39f09457db3c05ce1d19158c2cbef4c32b8bedd02c155e49282b7ea7459", size = 17255, upload-time = "2026-01-14T06:27:36.056Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/1c/78/504fdd027da3b84ff1aecd9f6957e65f35134534ccc6da8628eb71e76d3f/send2trash-2.1.0-py3-none-any.whl", hash = "sha256:0da2f112e6d6bb22de6aa6daa7e144831a4febf2a87261451c4ad849fe9a873c", size = 17610, upload-time = "2026-01-14T06:27:35.218Z" }, +] + [[package]] name = "setuptools" version = "84.0.0" @@ -2443,20 +3450,6 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/eb/dc/ad025c1ee131eba60c69f4dd5779b18fcf1e6b21a343e2162a84d5d133c7/soupsieve-2.9.2-py3-none-any.whl", hash = "sha256:8089a26fd974ca7a1f30276d3d8492ab266ab15af581642dfe8aa162e0c1c823", size = 37370, upload-time = "2026-08-07T00:57:23.524Z" }, ] -[[package]] -name = "sphobjinv" -version = "2.4" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "attrs" }, - { name = "certifi" }, - { name = "jsonschema" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/1f/67/19f33eeb4ffff0e2fd39afd4783a6ee38a6d58bcc1ddade779712a7e2e49/sphobjinv-2.4.tar.gz", hash = "sha256:44d57e7e87e17d8c7b053c853dcc36f80cbf7d1fc152d57634fd7bcae38ca48a", size = 249997, upload-time = "2026-03-23T05:04:54.011Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/2c/97/840be4a99531292f8f41069bfcd0654f68296ef4089bfe828607d63ee0ff/sphobjinv-2.4-py3-none-any.whl", hash = "sha256:35f3239e9a6161c20d60146c16645687d06d43e5875d2bda71010c3ee7fd54bc", size = 51315, upload-time = "2026-03-23T05:04:42.434Z" }, -] - [[package]] name = "sqlalchemy" version = "2.0.52" @@ -2508,6 +3501,20 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/f3/bc/2a07cef49046e6cf5d1a8b1de553aaef8491b4170dbfe254c8687c764408/sqlglot-30.17.0-py3-none-any.whl", hash = "sha256:84435ac283a60173da31b5fd7d11a725037a1c3fd6ed1e21fb065de74ddb579f", size = 741795, upload-time = "2026-08-12T19:36:48.699Z" }, ] +[[package]] +name = "stack-data" +version = "0.6.3" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "asttokens" }, + { name = "executing" }, + { name = "pure-eval" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/28/e3/55dcc2cfbc3ca9c29519eb6884dd1415ecb53b0e934862d3559ddcb7e20b/stack_data-0.6.3.tar.gz", hash = "sha256:836a778de4fec4dcd1dcd89ed8abff8a221f58308462e1c4aa2a3cf30148f0b9", size = 44707, upload-time = "2023-09-30T13:58:05.479Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/f1/7b/ce1eafaf1a76852e2ec9b22edecf1daa58175c090266e9f6c64afcd81d91/stack_data-0.6.3-py3-none-any.whl", hash = "sha256:d5558e0c25a4cb0853cddad3d77da9891a08cb85dd9f9f91b9f8cd66e511e695", size = 24521, upload-time = "2023-09-30T13:58:03.53Z" }, +] + [[package]] name = "starlette" version = "1.6.0" @@ -2534,12 +3541,46 @@ wheels = [ ] [[package]] -name = "tabulate" -version = "0.10.0" +name = "terminado" +version = "0.18.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "ptyprocess", marker = "os_name != 'nt'" }, + { name = "pywinpty", marker = "os_name == 'nt'" }, + { name = "tornado" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/8a/11/965c6fd8e5cc254f1fe142d547387da17a8ebfd75a3455f637c663fb38a0/terminado-0.18.1.tar.gz", hash = "sha256:de09f2c4b85de4765f7714688fff57d3e75bad1f909b589fde880460c753fd2e", size = 32701, upload-time = "2024-03-12T14:34:39.026Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/6a/9e/2064975477fdc887e47ad42157e214526dcad8f317a948dee17e1659a62f/terminado-0.18.1-py3-none-any.whl", hash = "sha256:a4468e1b37bb318f8a86514f65814e1afc977cf29b3992a4500d9dd305dcceb0", size = 14154, upload-time = "2024-03-12T14:34:36.569Z" }, +] + +[[package]] +name = "tinycss2" +version = "1.5.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "webencodings" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/a3/ae/2ca4913e5c0f09781d75482874c3a95db9105462a92ddd303c7d285d3df2/tinycss2-1.5.1.tar.gz", hash = "sha256:d339d2b616ba90ccce58da8495a78f46e55d4d25f9fd71dfd526f07e7d53f957", size = 88195, upload-time = "2025-11-23T10:29:10.082Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/60/45/c7b5c3168458db837e8ceab06dc77824e18202679d0463f0e8f002143a97/tinycss2-1.5.1-py3-none-any.whl", hash = "sha256:3415ba0f5839c062696996998176c4a3751d18b7edaaeeb658c9ce21ec150661", size = 28404, upload-time = "2025-11-23T10:29:08.676Z" }, +] + +[[package]] +name = "tornado" +version = "6.5.8" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/46/58/8c37dea7bbf769b20d58e7ace7e5edfe65b849442b00ffcdd56be88697c6/tabulate-0.10.0.tar.gz", hash = "sha256:e2cfde8f79420f6deeffdeda9aaec3b6bc5abce947655d17ac662b126e48a60d", size = 91754, upload-time = "2026-03-04T18:55:34.402Z" } +sdist = { url = "https://files.pythonhosted.org/packages/10/d3/343e5bb989d6515b1646cf3d40135d73f3d5e45339bded401b56cdac24dd/tornado-6.5.8.tar.gz", hash = "sha256:9452e1b208a8bd771e2cb1f2ff564985b9b214bdebbe622793e1799e0a6bd23f", size = 520493, upload-time = "2026-08-07T02:12:42.971Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/99/55/db07de81b5c630da5cbf5c7df646580ca26dfaefa593667fc6f2fe016d2e/tabulate-0.10.0-py3-none-any.whl", hash = "sha256:f0b0622e567335c8fabaaa659f1b33bcb6ddfe2e496071b743aa113f8774f2d3", size = 39814, upload-time = "2026-03-04T18:55:31.284Z" }, + { url = "https://files.pythonhosted.org/packages/f2/d5/007086fd8df5489338e204f65adce33fd4f21a4999dbb2b9cff2f897b5f4/tornado-6.5.8-cp39-abi3-macosx_10_9_universal2.whl", hash = "sha256:cc6aa787d7cfab7c3d35189dc7a56fbd2399a569624c730c6b55b3d6531d0403", size = 449487, upload-time = "2026-08-07T02:12:28.682Z" }, + { url = "https://files.pythonhosted.org/packages/70/c8/5a24a99495903f594f6a199dd7beead1cbc0a13e2cb9102727bcaaf2a997/tornado-6.5.8-cp39-abi3-macosx_10_9_x86_64.whl", hash = "sha256:9715b5eb79735b2bcd454ce216a9275b7c0470e64ea1bf5742f78b2f72b26eeb", size = 447649, upload-time = "2026-08-07T02:12:30.306Z" }, + { url = "https://files.pythonhosted.org/packages/6e/de/f2e733f386b85962d1b1dc82cd63d169b5b4580062b35397eac9244a41fe/tornado-6.5.8-cp39-abi3-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:547d63f450d570c14fe0e8db2cfb14c9bbd1c2503b4a6612586267955aa47b58", size = 450707, upload-time = "2026-08-07T02:12:31.95Z" }, + { url = "https://files.pythonhosted.org/packages/0b/94/20efeee9a01c141e9ac47c397f81679dfda24b32768fc4fff24e76d36c2c/tornado-6.5.8-cp39-abi3-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:7e2360a0ffbe145eca8af0b19cb7203d79b1a98dd4cccdd6b368f6f49c2e3808", size = 451677, upload-time = "2026-08-07T02:12:33.512Z" }, + { url = "https://files.pythonhosted.org/packages/42/ec/a96ccb8ccf0de2b7bc2c5fa1608a4803735018242e90c4882365a9fd418f/tornado-6.5.8-cp39-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:5d242290bdf7ab3151bc1065fdd75c0dcc21cbc7b49f22a4c56329c2d6566d22", size = 451510, upload-time = "2026-08-07T02:12:35.346Z" }, + { url = "https://files.pythonhosted.org/packages/29/b5/93185859245ad3f00e62175f29607346788b696369347f0146e0421286bb/tornado-6.5.8-cp39-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:7b94ff0e128fe0542f3bd331fb44d06260fc4ac16881545159f34ef08aad4195", size = 450917, upload-time = "2026-08-07T02:12:36.963Z" }, + { url = "https://files.pythonhosted.org/packages/97/cf/fe33cf062834487d34d1559746a4a12521033c22645b6d74d4bca702e018/tornado-6.5.8-cp39-abi3-win32.whl", hash = "sha256:67832909c4779c64942380cb5f044a5c6163d00831472d80e25e115de9917836", size = 451952, upload-time = "2026-08-07T02:12:38.512Z" }, + { url = "https://files.pythonhosted.org/packages/cb/e1/468ad54333e92ccb62627e62cb88e5fc14a2171daa67ed47b1b8542d5b86/tornado-6.5.8-cp39-abi3-win_amd64.whl", hash = "sha256:11881db6b7c168494be2c2d12e65931451bdf7ee718535418ae1d8855dd5a0ee", size = 452391, upload-time = "2026-08-07T02:12:39.971Z" }, + { url = "https://files.pythonhosted.org/packages/ad/3e/cd5e4f06e34cde33b8ef66cf36aa2b5ad46354cc1af7d2136bbe365fee1d/tornado-6.5.8-cp39-abi3-win_arm64.whl", hash = "sha256:68a7468c7e289f8514d7d664101753903217eff1bb6822c6b5994a0b5f5bcb26", size = 451411, upload-time = "2026-08-07T02:12:41.469Z" }, ] [[package]] @@ -2554,6 +3595,15 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/f9/1c/01bfd571a64e7f270e6bab5e33777debe0edc56759233ce84f27dec92d14/tqdm-4.70.0-py3-none-any.whl", hash = "sha256:7f585706bfddbdebf89daac705b2dfcc16890130727d3197ca62c732b4310953", size = 80184, upload-time = "2026-07-27T11:33:13.167Z" }, ] +[[package]] +name = "traitlets" +version = "5.16.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/2c/2e/a7fbfe268c8a3b32546930c0297c101d65a4a14c304ad5790a9f478f0e4e/traitlets-5.16.1.tar.gz", hash = "sha256:ed900c2b631aa3a112811139fa97b8d2c3bad5e989656bba4b7e52c7852c18c1", size = 166137, upload-time = "2026-08-03T08:32:36.848Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/ad/66/0d785f0bc5e4315a96c989bb476d0fc07ea4f85132550c7b156ca2035d52/traitlets-5.16.1-py3-none-any.whl", hash = "sha256:f775618166caa0396c8e337099240f2bd3e5e917d203b2e6fbe21a58d3cb1f6b", size = 86211, upload-time = "2026-08-03T08:32:34.48Z" }, +] + [[package]] name = "truststore" version = "0.10.4" @@ -2593,6 +3643,15 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/e5/6d/b53b99a9f2766d095985947a5782f1702cabb129a34f7a802d7197af832f/tzdata-2026.3-py2.py3-none-any.whl", hash = "sha256:dc096730c87af6cab1b171c9d532be840741ff5d459015e7f6947bd7d7e54931", size = 348168, upload-time = "2026-07-10T08:50:36.46Z" }, ] +[[package]] +name = "uri-template" +version = "1.3.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/31/c7/0336f2bd0bcbada6ccef7aaa25e443c118a704f828a0620c6fa0207c1b64/uri-template-1.3.0.tar.gz", hash = "sha256:0e00f8eb65e18c7de20d595a14336e9f337ead580c70934141624b6d1ffdacc7", size = 21678, upload-time = "2023-06-21T01:49:05.374Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/e7/00/3fca040d7cf8a32776d3d81a00c8ee7457e00f80c649f1e4a863c8321ae9/uri_template-1.3.0-py3-none-any.whl", hash = "sha256:a44a133ea12d44a0c0f06d7d42a52d71282e77e2f937d8abd5655b8d56fc1363", size = 11140, upload-time = "2023-06-21T01:49:03.467Z" }, +] + [[package]] name = "urllib3" version = "2.7.0" @@ -2615,33 +3674,6 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/f1/79/4a20b54ab0491485ccd8c077db2d39187c7f12b3e15485d38a7be37c81b4/uvicorn-0.52.4-py3-none-any.whl", hash = "sha256:f86e41a149d7d05a9969337e3946a9c171c06a5d42680896daaba624aeac8da1", size = 79871, upload-time = "2026-08-19T06:27:40.36Z" }, ] -[[package]] -name = "watchdog" -version = "6.0.0" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/db/7d/7f3d619e951c88ed75c6037b246ddcf2d322812ee8ea189be89511721d54/watchdog-6.0.0.tar.gz", hash = "sha256:9ddf7c82fda3ae8e24decda1338ede66e1c99883db93711d8fb941eaa2d8c282", size = 131220, upload-time = "2024-11-01T14:07:13.037Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/e0/24/d9be5cd6642a6aa68352ded4b4b10fb0d7889cb7f45814fb92cecd35f101/watchdog-6.0.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:6eb11feb5a0d452ee41f824e271ca311a09e250441c262ca2fd7ebcf2461a06c", size = 96393, upload-time = "2024-11-01T14:06:31.756Z" }, - { url = "https://files.pythonhosted.org/packages/63/7a/6013b0d8dbc56adca7fdd4f0beed381c59f6752341b12fa0886fa7afc78b/watchdog-6.0.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:ef810fbf7b781a5a593894e4f439773830bdecb885e6880d957d5b9382a960d2", size = 88392, upload-time = "2024-11-01T14:06:32.99Z" }, - { url = "https://files.pythonhosted.org/packages/d1/40/b75381494851556de56281e053700e46bff5b37bf4c7267e858640af5a7f/watchdog-6.0.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:afd0fe1b2270917c5e23c2a65ce50c2a4abb63daafb0d419fde368e272a76b7c", size = 89019, upload-time = "2024-11-01T14:06:34.963Z" }, - { url = "https://files.pythonhosted.org/packages/39/ea/3930d07dafc9e286ed356a679aa02d777c06e9bfd1164fa7c19c288a5483/watchdog-6.0.0-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:bdd4e6f14b8b18c334febb9c4425a878a2ac20efd1e0b231978e7b150f92a948", size = 96471, upload-time = "2024-11-01T14:06:37.745Z" }, - { url = "https://files.pythonhosted.org/packages/12/87/48361531f70b1f87928b045df868a9fd4e253d9ae087fa4cf3f7113be363/watchdog-6.0.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:c7c15dda13c4eb00d6fb6fc508b3c0ed88b9d5d374056b239c4ad1611125c860", size = 88449, upload-time = "2024-11-01T14:06:39.748Z" }, - { url = "https://files.pythonhosted.org/packages/5b/7e/8f322f5e600812e6f9a31b75d242631068ca8f4ef0582dd3ae6e72daecc8/watchdog-6.0.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:6f10cb2d5902447c7d0da897e2c6768bca89174d0c6e1e30abec5421af97a5b0", size = 89054, upload-time = "2024-11-01T14:06:41.009Z" }, - { url = "https://files.pythonhosted.org/packages/68/98/b0345cabdce2041a01293ba483333582891a3bd5769b08eceb0d406056ef/watchdog-6.0.0-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:490ab2ef84f11129844c23fb14ecf30ef3d8a6abafd3754a6f75ca1e6654136c", size = 96480, upload-time = "2024-11-01T14:06:42.952Z" }, - { url = "https://files.pythonhosted.org/packages/85/83/cdf13902c626b28eedef7ec4f10745c52aad8a8fe7eb04ed7b1f111ca20e/watchdog-6.0.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:76aae96b00ae814b181bb25b1b98076d5fc84e8a53cd8885a318b42b6d3a5134", size = 88451, upload-time = "2024-11-01T14:06:45.084Z" }, - { url = "https://files.pythonhosted.org/packages/fe/c4/225c87bae08c8b9ec99030cd48ae9c4eca050a59bf5c2255853e18c87b50/watchdog-6.0.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:a175f755fc2279e0b7312c0035d52e27211a5bc39719dd529625b1930917345b", size = 89057, upload-time = "2024-11-01T14:06:47.324Z" }, - { url = "https://files.pythonhosted.org/packages/a9/c7/ca4bf3e518cb57a686b2feb4f55a1892fd9a3dd13f470fca14e00f80ea36/watchdog-6.0.0-py3-none-manylinux2014_aarch64.whl", hash = "sha256:7607498efa04a3542ae3e05e64da8202e58159aa1fa4acddf7678d34a35d4f13", size = 79079, upload-time = "2024-11-01T14:06:59.472Z" }, - { url = "https://files.pythonhosted.org/packages/5c/51/d46dc9332f9a647593c947b4b88e2381c8dfc0942d15b8edc0310fa4abb1/watchdog-6.0.0-py3-none-manylinux2014_armv7l.whl", hash = "sha256:9041567ee8953024c83343288ccc458fd0a2d811d6a0fd68c4c22609e3490379", size = 79078, upload-time = "2024-11-01T14:07:01.431Z" }, - { url = "https://files.pythonhosted.org/packages/d4/57/04edbf5e169cd318d5f07b4766fee38e825d64b6913ca157ca32d1a42267/watchdog-6.0.0-py3-none-manylinux2014_i686.whl", hash = "sha256:82dc3e3143c7e38ec49d61af98d6558288c415eac98486a5c581726e0737c00e", size = 79076, upload-time = "2024-11-01T14:07:02.568Z" }, - { url = "https://files.pythonhosted.org/packages/ab/cc/da8422b300e13cb187d2203f20b9253e91058aaf7db65b74142013478e66/watchdog-6.0.0-py3-none-manylinux2014_ppc64.whl", hash = "sha256:212ac9b8bf1161dc91bd09c048048a95ca3a4c4f5e5d4a7d1b1a7d5752a7f96f", size = 79077, upload-time = "2024-11-01T14:07:03.893Z" }, - { url = "https://files.pythonhosted.org/packages/2c/3b/b8964e04ae1a025c44ba8e4291f86e97fac443bca31de8bd98d3263d2fcf/watchdog-6.0.0-py3-none-manylinux2014_ppc64le.whl", hash = "sha256:e3df4cbb9a450c6d49318f6d14f4bbc80d763fa587ba46ec86f99f9e6876bb26", size = 79078, upload-time = "2024-11-01T14:07:05.189Z" }, - { url = "https://files.pythonhosted.org/packages/62/ae/a696eb424bedff7407801c257d4b1afda455fe40821a2be430e173660e81/watchdog-6.0.0-py3-none-manylinux2014_s390x.whl", hash = "sha256:2cce7cfc2008eb51feb6aab51251fd79b85d9894e98ba847408f662b3395ca3c", size = 79077, upload-time = "2024-11-01T14:07:06.376Z" }, - { url = "https://files.pythonhosted.org/packages/b5/e8/dbf020b4d98251a9860752a094d09a65e1b436ad181faf929983f697048f/watchdog-6.0.0-py3-none-manylinux2014_x86_64.whl", hash = "sha256:20ffe5b202af80ab4266dcd3e91aae72bf2da48c0d33bdb15c66658e685e94e2", size = 79078, upload-time = "2024-11-01T14:07:07.547Z" }, - { url = "https://files.pythonhosted.org/packages/07/f6/d0e5b343768e8bcb4cda79f0f2f55051bf26177ecd5651f84c07567461cf/watchdog-6.0.0-py3-none-win32.whl", hash = "sha256:07df1fdd701c5d4c8e55ef6cf55b8f0120fe1aef7ef39a1c6fc6bc2e606d517a", size = 79065, upload-time = "2024-11-01T14:07:09.525Z" }, - { url = "https://files.pythonhosted.org/packages/db/d9/c495884c6e548fce18a8f40568ff120bc3a4b7b99813081c8ac0c936fa64/watchdog-6.0.0-py3-none-win_amd64.whl", hash = "sha256:cbafb470cf848d93b5d013e2ecb245d4aa1c8fd0504e863ccefa32445359d680", size = 79070, upload-time = "2024-11-01T14:07:10.686Z" }, - { url = "https://files.pythonhosted.org/packages/33/e8/e40370e6d74ddba47f002a32919d91310d6074130fe4e17dabcafc15cbf1/watchdog-6.0.0-py3-none-win_ia64.whl", hash = "sha256:a1914259fa9e1454315171103c6a30961236f508b9b623eae470268bbcc6a22f", size = 79067, upload-time = "2024-11-01T14:07:11.845Z" }, -] - [[package]] name = "watchfiles" version = "1.2.0" @@ -2755,6 +3787,33 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/c4/0e/57f6bb3024a597b2e8ec4aee710ffe62ddc95af2e2bb1ee7a7abdc22c68c/wcwidth-0.8.3-py3-none-any.whl", hash = "sha256:d5b73dba6158a595ec9370350e7f2637bcac8d6c5e4fde34f30fcffb6103a5e4", size = 331669, upload-time = "2026-08-28T18:10:04.909Z" }, ] +[[package]] +name = "webcolors" +version = "25.10.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/1d/7a/eb316761ec35664ea5174709a68bbd3389de60d4a1ebab8808bfc264ed67/webcolors-25.10.0.tar.gz", hash = "sha256:62abae86504f66d0f6364c2a8520de4a0c47b80c03fc3a5f1815fedbef7c19bf", size = 53491, upload-time = "2025-10-31T07:51:03.977Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/e2/cc/e097523dd85c9cf5d354f78310927f1656c422bd7b2613b2db3e3f9a0f2c/webcolors-25.10.0-py3-none-any.whl", hash = "sha256:032c727334856fc0b968f63daa252a1ac93d33db2f5267756623c210e57a4f1d", size = 14905, upload-time = "2025-10-31T07:51:01.778Z" }, +] + +[[package]] +name = "webencodings" +version = "0.6.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/d5/a0/8fd707bcb776a7be556bad06a2ea5fb9bd519df78ef8e26f70ccf0f38bff/webencodings-0.6.1.tar.gz", hash = "sha256:565f9ad031c702dae404e27a099e3e09186a3ab1b9520f06d215502b651fd910", size = 15001, upload-time = "2026-08-15T14:22:57.549Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/77/c6/040cbc72480d789a5f40d63fb484d3106554c4dfa2d2b70ad5022057750f/webencodings-0.6.1-py3-none-any.whl", hash = "sha256:7fab6269c8bf237c657876b52058ccb182e861518d1c695c1a9aaa8c1c105d5b", size = 8745, upload-time = "2026-08-15T14:22:56.31Z" }, +] + +[[package]] +name = "websocket-client" +version = "1.9.2" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/d8/cb/a5abcc2891249f393827c650c6296660ce40374ac22d99ab9aea41f9d2a2/websocket_client-1.9.2.tar.gz", hash = "sha256:0fcb57545848be86992e128218fd96dd87a6769ffdb1a968dff79632b85604d0", size = 84110, upload-time = "2026-08-31T14:08:40.964Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/d5/d2/cc4dc1271e464942db7ee278baae2daa99ee77cb2af744025c04da585a3e/websocket_client-1.9.2-py3-none-any.whl", hash = "sha256:e1a673830a9c7bfa47b1cd3d5e4178f4c9651d80a4eab02c9c23a1c3ec6250ce", size = 95786, upload-time = "2026-08-31T14:08:39.899Z" }, +] + [[package]] name = "websockets" version = "17.1" @@ -2910,6 +3969,15 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/41/63/23572870e01836a98346075b9e17a8bc24a6ddd9800a3204ceee58677f3c/websockets-17.1-py3-none-any.whl", hash = "sha256:f221081107b8c48184d99f7019604486376e7ef826037e70aad6b02540732c23", size = 211134, upload-time = "2026-08-26T17:25:31.397Z" }, ] +[[package]] +name = "widgetsnbextension" +version = "4.0.16" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/bf/60/bc7a980fc78837d6ef8f5940cca4cadc433364503a4c4d42e2a7a0de3231/widgetsnbextension-4.0.16.tar.gz", hash = "sha256:adeea0ae78f0856ee4945f413299801b82a0a01416303301f39a704282a37b73", size = 1111094, upload-time = "2026-08-18T08:52:55.859Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/34/95/40e17e20046b7bc820d29d09ae84ec157ec8dd6e6f6cd722626292c31b2e/widgetsnbextension-4.0.16-py3-none-any.whl", hash = "sha256:a31a8774885b96fe825462f5d6496166f0c7cae111195b6465c801d230eb5a4e", size = 2225148, upload-time = "2026-08-18T08:52:53.736Z" }, +] + [[package]] name = "xxhash" version = "4.0.1" From d2ce68f638b616213c62e233ca105fab73b99c52 Mon Sep 17 00:00:00 2001 From: Josh Taillon Date: Mon, 14 Sep 2026 11:18:48 -0600 Subject: [PATCH 03/26] docs(py): carry the site's icons, styles, links and R logo across great-docs has no config key for a custom navbar link, does not merge a project _quarto.yml, and rewrites the generated one every build, so the R cross-link is injected with a script next to its own navbar tools. The empty span is what docs/assets/styles.css already turns into the R logo, so only the markup had to be reproduced. The favicon block stays an include rather than becoming the favicon: key, which takes a single file and would drop the manifest and the other sizes that the R site serves from the same shared /favicon/. The custom stylesheet goes under site.css. A top-level css: key is accepted and silently ignored, which leaves the site unstyled. Relative links had to move with the pages. The narrative pages now render under user-guide/, so the homepage's links into them gained that prefix, and the governance page's hops out to the R site became absolute. Relative cross-site links cannot survive versioning anyway: from /py/v// a ../r/ hop lands in /py/v/r/ rather than at the site root. The stylesheet's R logo url() moved for the same reason the hex image's src did, because great-docs copies docs/ to the user-guide/ prefix and surfaces only the navbar logo at the root. --- pkg-py/docs/assets/styles.css | 10 +++---- pkg-py/docs/favicon.html | 7 ----- pkg-py/docs/governance.qmd | 4 +-- pkg-py/great-docs.yml | 56 +++++++++++++++++++++++++++++++++++ pkg-py/index.qmd | 10 ++++--- 5 files changed, 69 insertions(+), 18 deletions(-) delete mode 100644 pkg-py/docs/favicon.html diff --git a/pkg-py/docs/assets/styles.css b/pkg-py/docs/assets/styles.css index 723b7e20..7ea69a84 100644 --- a/pkg-py/docs/assets/styles.css +++ b/pkg-py/docs/assets/styles.css @@ -45,10 +45,10 @@ h3 { } /* Show the R logo in place of the "R" navbar link text. The url() resolves - relative to this stylesheet, so it works from any page depth (unlike an - img src written into the navbar HTML). Both files live under assets/ - because quarto preview (1.10) fails to copy a CSS url() resource located - at the project root: "Cannot copy ... to a subdirectory of itself". */ + relative to this stylesheet, so it works from any page depth and from any + versioned copy of the site (unlike an img src written into the navbar + HTML). great-docs copies this stylesheet to the site root and the assets + directory under user-guide/, which is what the path below reflects. */ .navbar a[href$="/r/"] { display: flex; align-items: center; @@ -65,7 +65,7 @@ h3 { .navbar a[href$="/r/"] .r-logo { font-size: 0; - background: url("logos/r-logo.svg") no-repeat center / contain; + background: url("user-guide/assets/logos/r-logo.svg") no-repeat center / contain; width: 1.29rem; height: 1rem; /* Optical alignment: the logo's visual weight sits low (the gray oval is diff --git a/pkg-py/docs/favicon.html b/pkg-py/docs/favicon.html deleted file mode 100644 index c3072b26..00000000 --- a/pkg-py/docs/favicon.html +++ /dev/null @@ -1,7 +0,0 @@ - - - - - - diff --git a/pkg-py/docs/governance.qmd b/pkg-py/docs/governance.qmd index ff010930..5456c8c0 100644 --- a/pkg-py/docs/governance.qmd +++ b/pkg-py/docs/governance.qmd @@ -36,7 +36,7 @@ When viewer credentials are not available, it is recommended to use a service ac ## Python code execution -The Python agent currently has no tool that runs code written by the model, but this feature is expected in the near future. Currently, there is no concern for Python `commons` agents executing arbitrary Python code. When the feature is added, it will generally follow the R package's [R code execution](../r/articles/governance.html#r-code-execution) design. +The Python agent currently has no tool that runs code written by the model, but this feature is expected in the near future. Currently, there is no concern for Python `commons` agents executing arbitrary Python code. When the feature is added, it will generally follow the R package's [R code execution](https://posit-dev.github.io/commons/r/articles/governance.html#r-code-execution) design. ## Permissioning facts @@ -46,4 +46,4 @@ Because of this, you should only include facts that you can share with both the ## Telemetry -The Python implementation of `commons` currently does not support telemetry or conversation logging, though this feature is planned to be added in the near future. When it is added, it will generally follow the R package's [Logging trajectories](../r/articles/governance.html#logging-trajectories) design. +The Python implementation of `commons` currently does not support telemetry or conversation logging, though this feature is planned to be added in the near future. When it is added, it will generally follow the R package's [Logging trajectories](https://posit-dev.github.io/commons/r/articles/governance.html#logging-trajectories) design. diff --git a/pkg-py/great-docs.yml b/pkg-py/great-docs.yml index 48fc3d68..53c5490c 100644 --- a/pkg-py/great-docs.yml +++ b/pkg-py/great-docs.yml @@ -28,3 +28,59 @@ reference: - title: Shiny UI and server desc: "Put a commons agent inside of an interactive chat app. Needs the `shiny` extra." contents: [ui.app, ui.server, ui.theme, ui.commons_chat_dependency, ui.asset_base_url] + +# Nested under `site:`, which is the key great-docs reads; a top-level +# `css:` is silently ignored. Paths are relative to the project root. +site: + css: + - docs/assets/styles.css + +# The navbar logo, as the previous Quarto config had it. The hex sticker is +# a homepage image rather than the navbar mark. +logo: + light: docs/assets/logos/python-logo.svg + +authors: + - name: Josh Taillon + role: Maintainer + affiliation: Posit, PBC + +funding: + name: Posit Software, PBC + roles: + - Copyright holder + - funder + homepage: https://posit.co + +include_in_header: + # The icon tags pkgdown writes for the R site, so both serve the same icons + # from the shared /favicon/ at the site root. A leading / is + # project-relative and Quarto rewrites it per page depth. great-docs' + # `favicon:` key takes a single file and would drop the manifest and the + # other sizes. + - text: | + + + + + + # No config key adds a navbar link, and the generated _quarto.yml is + # rewritten on every build, so the R cross-link is injected next to + # great-docs' own navbar tools. The href is absolute so it works from a + # pull request preview and from every /v/ copy, matching the mirror-image + # link in pkg-r/_pkgdown.yml. The empty span is what + # docs/assets/styles.css turns into the R logo. + - text: | + diff --git a/pkg-py/index.qmd b/pkg-py/index.qmd index 671b16dd..c0a8451a 100644 --- a/pkg-py/index.qmd +++ b/pkg-py/index.qmd @@ -3,7 +3,9 @@ title: "commons" --- ```{=html} -The package's hex sticker; a Common Kingfisher drawn in a cartoonish style, sitting on a park bench with a plaque reading 'commons'. Behind the bird is an open green space. + +The package's hex sticker; a Common Kingfisher drawn in a cartoonish style, sitting on a park bench with a plaque reading 'commons'. Behind the bird is an open green space. ``` `commons` helps data scientists build trustworthy data agents. @@ -41,7 +43,7 @@ uv pip install "commons[shiny] @ git+https://github.com/posit-dev/commons#subdir `commons` uses [`chatlas`](https://posit-dev.github.io/chatlas/) to access LLMs, so you will need access to one of chatlas's supported providers. -The [Introduction to commons](get-started.qmd) page explains the structure of a `commons` agent and the creation process. For a complete example application, see [`demo.py`](https://github.com/posit-dev/commons/blob/main/pkg-py/demo.py) in the repository. +The [Introduction to commons](user-guide/get-started.qmd) page explains the structure of a `commons` agent and the creation process. For a complete example application, see [`demo.py`](https://github.com/posit-dev/commons/blob/main/pkg-py/demo.py) in the repository. ## Trusted answers @@ -49,8 +51,8 @@ There are two provenance paths available to a `commons` agent. When a user asks Answers display provenance according to the analysis path followed, so users can determine how much trust to put in a given answer. -For more information, see the [Introduction to `commons`](get-started.qmd) page. +For more information, see the [Introduction to `commons`](user-guide/get-started.qmd) page. ## Evaluation -The [DevRel agent](https://github.com/posit-dev/devrel-agent) is an example `commons` agent (using the R implementation) that answers questions about adoption, engagement, and growth across Posit's open-source projects. Its repository contains an [evaluation](https://github.com/posit-dev/devrel-agent/tree/main/evals) comparing the `commons` agent with Claude Code on the same data; the [R documentation](../r/#evaluation) presents the results. +The [DevRel agent](https://github.com/posit-dev/devrel-agent) is an example `commons` agent (using the R implementation) that answers questions about adoption, engagement, and growth across Posit's open-source projects. Its repository contains an [evaluation](https://github.com/posit-dev/devrel-agent/tree/main/evals) comparing the `commons` agent with Claude Code on the same data; the [R documentation](https://posit-dev.github.io/commons/r/#evaluation) presents the results. From c601c3d0eee4bce5f17ce951492c42ad6e891df8 Mon Sep 17 00:00:00 2001 From: Josh Taillon Date: Mon, 14 Sep 2026 11:23:00 -0600 Subject: [PATCH 04/26] ci: correct the version in the logo tooltip too, and drop the release date With a navbar logo rather than a text title, great-docs puts the version in a Tippy tooltip on the brand link instead of a badge span, so the wrong version reached the page by a second route that the first version of this script did not cover. This repository's config sets a logo, so the tooltip was in fact the only form appearing. The release date is now dropped rather than preserved. It comes from the same GitHub Release as the version, so on the Python site it was the R package's release date, and pyproject.toml carries no date to put in its place. Correcting the version while leaving the date would trade one wrong claim for another. --- .github/scripts/docs-version-badge.py | 34 +++++++++++++------- .github/scripts/test_docs_version_badge.py | 37 +++++++++++++++++++--- 2 files changed, 56 insertions(+), 15 deletions(-) diff --git a/.github/scripts/docs-version-badge.py b/.github/scripts/docs-version-badge.py index 168cea07..d88a5c1b 100644 --- a/.github/scripts/docs-version-badge.py +++ b/.github/scripts/docs-version-badge.py @@ -23,26 +23,38 @@ import re import sys -# Captures the badge's attributes separately from its text, so a release-date -# title survives and an already-correct page can be left alone. The closing -# quote after the class name is what stops a longer class that merely starts -# the same way, such as version-badge-legend, from matching. -BADGE = re.compile(r'(]*>)([^<]*)()') +# The closing quote after the class name is what stops a longer class that +# merely starts the same way, such as version-badge-legend, from matching. The +# release-date title attribute is dropped rather than captured: see below. +BADGE = re.compile(r']*>[^<]*') + +# When the navbar carries a logo rather than a text title, great-docs puts the +# version in a Tippy tooltip on the brand link instead of a badge span, so the +# same wrong version arrives by a second route. Anchoring on the opening +# `v` is what distinguishes it from every other tooltip on the page. The +# optional trailing clause is the release date, dropped with it. +TOOLTIP = re.compile(r'(data-tippy-content=")v[^<]*(?:
[^"]*)?(")') def retag(text: str, version: str) -> str | None: - """Return `text` with every badge reading `v`, or None if unchanged. + """Return `text` with every version reading `v`, or None if unchanged. Returning None for "nothing to do" keeps the caller from rewriting a file it does not need to touch, and makes the function idempotent. """ wanted = f"v{version}" - def replace(match: re.Match[str]) -> str: - return f"{match.group(1)}{wanted}{match.group(3)}" - - patched, count = BADGE.subn(replace, text) - if not count or patched == text: + def replace_tooltip(match: re.Match[str]) -> str: + return f"{match.group(1)}{wanted}{match.group(2)}" + + # Both forms are rebuilt rather than edited in place, because the release + # date great-docs pairs with the version comes from the same wrong GitHub + # Release and pyproject.toml has no date to replace it with. Asserting the + # R package's release date next to the Python version would be a second + # wrong claim, so it is removed. + patched, badges = BADGE.subn(f'{wanted}', text) + patched, tooltips = TOOLTIP.subn(replace_tooltip, patched) + if not (badges or tooltips) or patched == text: return None return patched diff --git a/.github/scripts/test_docs_version_badge.py b/.github/scripts/test_docs_version_badge.py index 918c9ab4..504c962e 100644 --- a/.github/scripts/test_docs_version_badge.py +++ b/.github/scripts/test_docs_version_badge.py @@ -25,13 +25,14 @@ def test_replaces_the_badge_text(self): self.assertIn(">v0.1.0b1<", out) self.assertNotIn("vr-v0.1.0", out) - def test_keeps_the_surrounding_attributes(self): - # The badge carries a release-date title attribute. Replacing the - # whole tag would drop it; only the text node should change. + def test_drops_the_release_date_from_the_badge(self): + # The date comes from the same wrong GitHub Release as the version, and + # pyproject.toml carries no release date to put in its place, so it is + # removed rather than left asserting the R package's release date. page = 'vr-v0.1.0' out = retag(page, "0.1.0b1") assert out is not None - self.assertIn('title="Released 2026-09-11"', out) + self.assertNotIn("Released 2026-09-11", out) self.assertIn(">v0.1.0b1<", out) def test_replaces_every_occurrence(self): @@ -57,6 +58,34 @@ def test_is_idempotent(self): assert once is not None self.assertIsNone(retag(once, "0.1.0b1")) + def test_replaces_the_version_in_the_logo_tooltip(self): + # When the navbar carries a logo instead of a text title, great-docs + # puts the version in a Tippy tooltip on the brand link rather than in + # a badge span, so the same wrong version arrives by another route. + page = ( + 'x' + self.assertIsNone(retag(page, "0.1.0b1")) + + def test_corrects_a_badge_and_a_tooltip_on_the_same_page(self): + page = ( + 'vr-v0.1.0' + 'y' + ) + out = retag(page, "0.1.0b1") + assert out is not None + self.assertNotIn("vr-v0.1.0", out) + def test_leaves_an_unrelated_span_alone(self): # Anchored on the closing quote of the class attribute, so a longer # class name that merely starts with the same text is not a badge. From 0801441f51cfddf27e22c4e2a75191d10378e037 Mon Sep 17 00:00:00 2001 From: Josh Taillon Date: Mon, 14 Sep 2026 11:23:09 -0600 Subject: [PATCH 05/26] docs(py): publish versioned docs and a beta notice The version list is hand-maintained so prerelease, eol and label stay editorial rather than inferred from py-v* tags, which would have had to guess that 0.1.0b1 is a prerelease. Adding an entry becomes a release step. 0.1.0b1 takes the latest slot, so /py/ serves what `pip install commons` resolves to, and the development version sits at /py/v/dev/. `latest` is set explicitly because a prerelease is excluded from latest auto-detection and every entry here is one. The announcement banner carries the beta warning, which reaches readers who land on an API reference page rather than the homepage. It also means the visible version in the navbar comes from the selector, built from this list, rather than from the release-derived badge. --- pkg-py/great-docs.yml | 37 +++++++++++++++++++++++++++++++++++++ 1 file changed, 37 insertions(+) diff --git a/pkg-py/great-docs.yml b/pkg-py/great-docs.yml index 53c5490c..41e68fd2 100644 --- a/pkg-py/great-docs.yml +++ b/pkg-py/great-docs.yml @@ -84,3 +84,40 @@ include_in_header: tools.prepend(link); }); + +# Hand-maintained, newest first. Deriving this from py-v* tags would have to +# guess which releases are prereleases or end of life, and those are +# editorial calls that belong in a reviewable diff. Adding an entry is a step +# in the release runbook. `great-docs api-snapshot ` reads a specific +# git tag, so a version's API snapshot can be backfilled later. +versions: + - label: "0.2.0 (dev)" + tag: dev + version: "0.2.0" + prerelease: true + # A beta, but the only published release, so it holds the latest slot and is + # what /py/ serves: that matches what `pip install commons` resolves to. + # `latest` has to be set explicitly, because a prerelease is excluded from + # latest auto-detection and every entry here is one. The beta warning is + # carried by the announcement banner rather than by a selector badge. + - label: "0.1.0b1" + tag: "0.1.0b1" + version: "0.1.0b1" + prerelease: true + latest: true + +version_selector: + enabled: true + placement: navbar-right + warning_banner: true + +version_aliases: + latest: true + stable: true + dev: true + +announcement: + content: "`commons` for Python is a **beta** and does not yet do everything the R package does." + type: info + url: user-guide/feature-parity.html + dismissable: true From e5b9bcc09d8df67b27a943e46fb35182dd19fdd0 Mon Sep 17 00:00:00 2001 From: Josh Taillon Date: Mon, 14 Sep 2026 11:25:34 -0600 Subject: [PATCH 06/26] ci: build the Python site with great-docs Only the build step changes. The copy into docs/py, the shared gh-pages deploy with clean:false, the noindex pass and the pr- previews are untouched, because those are what let the two sites and the previews share one branch. quarto-actions/setup stays: great-docs shells out to Quarto. The release: published trigger is replaced with the py-v* tag push it was presumably meant to be. Releases are cut by pushing a tag, so the old trigger never fired. Verified by running scripts/preview-docs.sh py and serving the result from a pr-/py/ subpath: the stylesheet, the R logo, the hex image, a reference page and a versioned copy all resolve, so the absolute site_url does not break a preview served from a deeper prefix. --- .github/workflows/quartodoc.yaml | 24 +++++++++++++++--------- pkg-py/.gitignore | 4 +++- scripts/preview-docs.sh | 12 +++++++----- 3 files changed, 25 insertions(+), 15 deletions(-) diff --git a/.github/workflows/quartodoc.yaml b/.github/workflows/quartodoc.yaml index bbf095cc..6f890366 100644 --- a/.github/workflows/quartodoc.yaml +++ b/.github/workflows/quartodoc.yaml @@ -1,11 +1,12 @@ on: push: branches: [main] + # paths does not filter a tag push, so a release rebuilds the site + # whatever it touched, which is what a release should do. + tags: ["py-v*"] paths: [pkg-py/**, docs/**, .github/workflows/quartodoc.yaml] pull_request: paths: [pkg-py/**, docs/**, .github/workflows/quartodoc.yaml] - release: - types: [published] workflow_dispatch: name: quartodoc.yaml @@ -41,13 +42,18 @@ jobs: - name: Install the package and its docs dependencies run: uv sync --extra shiny --group docs - - name: Build the reference pages - working-directory: pkg-py/docs - run: uv run quartodoc build + - name: Build the site + working-directory: pkg-py + run: uv run great-docs build - - name: Render the site - working-directory: pkg-py/docs - run: uv run quarto render + # great-docs takes the version it shows from the newest GitHub Release + # for the whole repository and cannot filter by tag prefix, so in this + # monorepo it shows whichever of the two release series published last. + - name: Correct the version it shows + working-directory: pkg-py + run: | + version="$(uv run python -c 'import tomllib; print(tomllib.load(open("pyproject.toml","rb"))["project"]["version"])')" + python3 ../.github/scripts/docs-version-badge.py great-docs/_site "$version" # The deploy publishes the whole of docs/, so the rendered site has to # sit at the path it is served from. @@ -55,7 +61,7 @@ jobs: working-directory: . run: | rm -rf docs/py - cp -r pkg-py/docs/_site docs/py + cp -r pkg-py/great-docs/_site docs/py # `clean: false` so this and the pkgdown deploy can each own a # subdirectory of the same branch without erasing the other. diff --git a/pkg-py/.gitignore b/pkg-py/.gitignore index ec4eaefe..38afcb59 100644 --- a/pkg-py/.gitignore +++ b/pkg-py/.gitignore @@ -18,5 +18,7 @@ dist/ /.quarto/ **/*.quarto_ipynb -# The site great-docs assembles and renders. +# The site great-docs assembles and renders, plus its working directories. /great-docs/ +/.great-docs/ +/_great_docs_build/ diff --git a/scripts/preview-docs.sh b/scripts/preview-docs.sh index 3961856a..239610a0 100755 --- a/scripts/preview-docs.sh +++ b/scripts/preview-docs.sh @@ -120,13 +120,15 @@ build_py() { return fi echo "==> Building the Python site into docs/py" - # Matches .github/workflows/quartodoc.yaml, including the copy: quarto - # warns and refuses to clean an output directory outside its project, so - # the site renders in place and is copied into position. + # Matches .github/workflows/quartodoc.yaml, including the copy and the + # version correction: great-docs renders in place, because quarto warns and + # refuses to clean an output directory outside its project. (cd "$root/pkg-py" && uv sync --extra shiny --group docs --quiet) - (cd "$root/pkg-py/docs" && uv run quartodoc build && uv run quarto render) + (cd "$root/pkg-py" && uv run great-docs build) + version="$(cd "$root/pkg-py" && uv run python -c 'import tomllib; print(tomllib.load(open("pyproject.toml","rb"))["project"]["version"])')" + python3 "$root/.github/scripts/docs-version-badge.py" "$root/pkg-py/great-docs/_site" "$version" rm -rf "$root/docs/py" - cp -r "$root/pkg-py/docs/_site" "$root/docs/py" + cp -r "$root/pkg-py/great-docs/_site" "$root/docs/py" } for site in $sites; do From d7e744f9d8356295ee13e44aa1ca7c5e8f2729e0 Mon Sep 17 00:00:00 2001 From: Josh Taillon Date: Mon, 14 Sep 2026 11:27:42 -0600 Subject: [PATCH 07/26] docs: describe the Python site's new toolchain AGENTS.md described the published tree without saying what builds the Python half or that it now publishes a copy per release. favicon/README.md pointed at a favicon partial that no longer exists; those tags moved into great-docs.yml, since great-docs' own favicon key takes a single file and would drop the manifest and the other sizes. --- AGENTS.md | 2 +- favicon/README.md | 5 +++-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/AGENTS.md b/AGENTS.md index 33d84003..5f9bf6b1 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -2,7 +2,7 @@ This repository is a monorepo holding two implementations of commons: the R pack Work from the relevant package's directory, not the repository root: `pkg-r/` for R (`devtools::load_all()`, `R CMD check`) and `pkg-py/` for Python (`uv run ruff check`, `uv run pyrefly check src tests`, `uv run pytest`). CI is scoped the same way. Run all of a package's checks before pushing; the pyrefly invocation needs its explicit `src tests` paths, because with none it consults the repo's git ignore files and a worktree checked out under an ignored directory silently type-checks nothing. -The documentation sites are the exception, because they are published as one tree: the landing page at the root, the R site under `r/`, and the Python site under `py/`. `scripts/preview-docs.sh` builds both into that tree and serves it, so a change can be read in place. It skips a site whose toolchain is missing rather than failing. Only the Python site gets a pull request preview; the R site follows the usual R package arrangement, where `r/dev/` tracks the development version and `r/` is redeployed by hand at release. +The documentation sites are the exception, because they are published as one tree: the landing page at the root, the R site under `r/`, and the Python site under `py/`. `scripts/preview-docs.sh` builds both into that tree and serves it, so a change can be read in place. It skips a site whose toolchain is missing rather than failing. Only the Python site gets a pull request preview; the R site follows the usual R package arrangement, where `r/dev/` tracks the development version and `r/` is redeployed by hand at release. The Python site is assembled by [great-docs](https://posit-dev.github.io/great-docs/) from `pkg-py/great-docs.yml`, which wraps Quarto rather than replacing it, and publishes a copy per release: the current one at `py/` and the others under `py/v/`. Adding a release to that list is a step in cutting one, not something the build infers. Neither package has been widely adopted or publicly released; changes can be made without a deprecation cycle (or even reference to the way that it used to work). diff --git a/favicon/README.md b/favicon/README.md index 4ced947f..90de4533 100644 --- a/favicon/README.md +++ b/favicon/README.md @@ -11,5 +11,6 @@ Edit the files here, never a copy. The icon paths in `site.webmanifest` are relative, because each site serves its own copy from a different prefix. The `` tags live with each site: the -pkgdown template writes them for the R site, `pkg-py/docs/favicon.html` for the -Python site, and `docs/index.html` for the landing page. +pkgdown template writes them for the R site, `include_in_header` in +`pkg-py/great-docs.yml` for the Python site, and `docs/index.html` for the +landing page. From 5de980be1f3b27273aefdc6552095c72c3893ad2 Mon Sep 17 00:00:00 2001 From: Josh Taillon Date: Mon, 14 Sep 2026 11:28:43 -0600 Subject: [PATCH 08/26] ci: rebuild the docs when the badge helper changes A fix to docs-version-badge.py would otherwise wait for an unrelated docs change before reaching the deployed site, because the path filters did not mention it. The preview script runs the helper through uv's interpreter rather than the system python3, matching the line above it that reads the version the same way. --- .github/workflows/quartodoc.yaml | 4 ++-- scripts/preview-docs.sh | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/quartodoc.yaml b/.github/workflows/quartodoc.yaml index 6f890366..5c5204a6 100644 --- a/.github/workflows/quartodoc.yaml +++ b/.github/workflows/quartodoc.yaml @@ -4,9 +4,9 @@ on: # paths does not filter a tag push, so a release rebuilds the site # whatever it touched, which is what a release should do. tags: ["py-v*"] - paths: [pkg-py/**, docs/**, .github/workflows/quartodoc.yaml] + paths: [pkg-py/**, docs/**, .github/scripts/docs-version-badge.py, .github/workflows/quartodoc.yaml] pull_request: - paths: [pkg-py/**, docs/**, .github/workflows/quartodoc.yaml] + paths: [pkg-py/**, docs/**, .github/scripts/docs-version-badge.py, .github/workflows/quartodoc.yaml] workflow_dispatch: name: quartodoc.yaml diff --git a/scripts/preview-docs.sh b/scripts/preview-docs.sh index 239610a0..a1bcc60e 100755 --- a/scripts/preview-docs.sh +++ b/scripts/preview-docs.sh @@ -126,7 +126,7 @@ build_py() { (cd "$root/pkg-py" && uv sync --extra shiny --group docs --quiet) (cd "$root/pkg-py" && uv run great-docs build) version="$(cd "$root/pkg-py" && uv run python -c 'import tomllib; print(tomllib.load(open("pyproject.toml","rb"))["project"]["version"])')" - python3 "$root/.github/scripts/docs-version-badge.py" "$root/pkg-py/great-docs/_site" "$version" + (cd "$root/pkg-py" && uv run python "$root/.github/scripts/docs-version-badge.py" great-docs/_site "$version") rm -rf "$root/docs/py" cp -r "$root/pkg-py/great-docs/_site" "$root/docs/py" } From 4681a55f5f52785a6868c438a110eedf7d933199 Mon Sep 17 00:00:00 2001 From: Josh Taillon Date: Mon, 14 Sep 2026 11:40:06 -0600 Subject: [PATCH 09/26] docs(py): fix the navbar link, the logo, the bolding and the banner The R cross-link was injected straight into .quarto-navbar-tools, which is empty in the static HTML: great-docs collects its widgets at runtime into a #gd-navbar-widgets flex container inside it. The link sat outside that container and so missed its alignment and gap, leaving the logo floating above the row. It now waits for that container and joins it, carrying the gd-navbar-icon class so it is drawn like the buttons beside it. The hex sticker becomes the configured logo. It was an inline image in index.qmd, which great-docs rendered underneath its own logo, so the landing page showed the python mark above the hex. Reference entries, navbar links and table links drop to normal weight. great-docs sets them in bold monospace, and on a page that is mostly a list of symbol names the weight on top of an underline reads as shouting. The announcement banner paints a mid-blue background but left its text at the body colour, which is close to unreadable in light mode, and an inline code span kept its own pale pill background and disappeared into it. --- pkg-py/docs/assets/styles.css | 73 ++++++++++++++++------------------- pkg-py/great-docs.yml | 57 ++++++++++++++++----------- pkg-py/index.qmd | 6 --- 3 files changed, 68 insertions(+), 68 deletions(-) diff --git a/pkg-py/docs/assets/styles.css b/pkg-py/docs/assets/styles.css index 7ea69a84..4f83d816 100644 --- a/pkg-py/docs/assets/styles.css +++ b/pkg-py/docs/assets/styles.css @@ -44,50 +44,45 @@ h3 { overflow-wrap: anywhere; } -/* Show the R logo in place of the "R" navbar link text. The url() resolves - relative to this stylesheet, so it works from any page depth and from any - versioned copy of the site (unlike an img src written into the navbar - HTML). great-docs copies this stylesheet to the site root and the assets - directory under user-guide/, which is what the path below reflects. */ -.navbar a[href$="/r/"] { - display: flex; - align-items: center; - /* Fill the stretched nav item, so the centered logo matches the line-box - center of the neighboring icon links. */ - height: 100%; -} - -/* The span carrying the hover title is sized to the logo, so the tooltip - appears anywhere over the image. */ -.navbar a[href$="/r/"] .menu-text { - display: flex; -} - -.navbar a[href$="/r/"] .r-logo { - font-size: 0; - background: url("user-guide/assets/logos/r-logo.svg") no-repeat center / contain; +/* The R cross-link is injected into great-docs' navbar widget container and + carries its gd-navbar-icon class, so the 34px box, the centring and the + spacing all come from there. Only the logo itself is described here. The + url() resolves relative to this stylesheet, so it works from any page depth + and from any versioned copy of the site, unlike an img src written into the + navbar HTML. great-docs copies this stylesheet to the site root and the + assets directory under user-guide/, which is what the path reflects. */ +.commons-r-link .r-logo { + display: block; width: 1.29rem; height: 1rem; - /* Optical alignment: the logo's visual weight sits low (the gray oval is - lighter than the blue R), so nudge it up from the geometric center. */ + background: url("user-guide/assets/logos/r-logo.svg") no-repeat center / contain; + /* Optical alignment: the logo's visual weight sits low, because the gray + oval is lighter than the blue R, so nudge it up from the geometric + centre. */ margin-top: -2px; } -/* The hex sticker on the home page, floated beside the opening prose the way - pkgdown places it on the R site. It drops to full width on a narrow screen, - where a float would leave the text in a column too thin to read. */ -.commons-hex { - float: right; - width: 180px; - max-width: 40%; - margin: 0 0 1rem 1.5rem; +/* great-docs sets its reference entries, its navbar links and its table links + in bold monospace. The monospace is wanted, since these are symbol names, + but the weight on top of an underline reads as shouting on a page that is + mostly a list of them. Normal weight keeps the underline as the affordance. */ +.doc-reference dt a, +.doc-reference section.doc-group > dl a, +.table a, +#navbarCollapse > ul.navbar-nav.navbar-nav-scroll.me-auto > li > a { + font-weight: normal; +} + +/* The announcement banner paints a mid-blue background but leaves the text at + the body colour, which is close to unreadable in light mode, and an inline + code span keeps its own pale pill background and so disappears entirely. */ +.gd-announcement-banner { + color: #fff; } -@media (max-width: 575.98px) { - .commons-hex { - float: none; - display: block; - max-width: 60%; - margin: 0 auto 1.5rem; - } +.gd-announcement-banner code { + background: rgb(255 255 255 / 18%); + color: inherit; + padding: 0.1em 0.3em; + border-radius: 3px; } diff --git a/pkg-py/great-docs.yml b/pkg-py/great-docs.yml index 41e68fd2..267a34a9 100644 --- a/pkg-py/great-docs.yml +++ b/pkg-py/great-docs.yml @@ -35,10 +35,11 @@ site: css: - docs/assets/styles.css -# The navbar logo, as the previous Quarto config had it. The hex sticker is -# a homepage image rather than the navbar mark. +# The hex sticker is the site's mark, shown in the navbar and, larger, on the +# landing page. It used to be an inline image in index.qmd, which great-docs +# would have shown underneath its own logo. logo: - light: docs/assets/logos/python-logo.svg + light: docs/assets/hex/commons-hex.png authors: - name: Josh Taillon @@ -65,31 +66,41 @@ include_in_header: # No config key adds a navbar link, and the generated _quarto.yml is - # rewritten on every build, so the R cross-link is injected next to - # great-docs' own navbar tools. The href is absolute so it works from a + # rewritten on every build, so the R cross-link is injected instead. + # great-docs collects its own widgets into #gd-navbar-widgets, which is + # built by a script that runs after this one, so the container is polled for + # rather than assumed. Joining that container is what gets the shared flex + # alignment and gap; the gd-navbar-icon class is what makes the link look + # like the neighbouring buttons. The href is absolute so it works from a # pull request preview and from every /v/ copy, matching the mirror-image - # link in pkg-r/_pkgdown.yml. The empty span is what - # docs/assets/styles.css turns into the R logo. + # link in pkg-r/_pkgdown.yml. - text: | -# Hand-maintained, newest first. Deriving this from py-v* tags would have to -# guess which releases are prereleases or end of life, and those are -# editorial calls that belong in a reviewable diff. Adding an entry is a step -# in the release runbook. `great-docs api-snapshot ` reads a specific -# git tag, so a version's API snapshot can be backfilled later. versions: - label: "0.2.0 (dev)" tag: dev diff --git a/pkg-py/index.qmd b/pkg-py/index.qmd index c0a8451a..489fa3c3 100644 --- a/pkg-py/index.qmd +++ b/pkg-py/index.qmd @@ -2,12 +2,6 @@ title: "commons" --- -```{=html} - -The package's hex sticker; a Common Kingfisher drawn in a cartoonish style, sitting on a park bench with a plaque reading 'commons'. Behind the bird is an open green space. -``` - `commons` helps data scientists build trustworthy data agents. Data teams typically have trusted code that they use to analyze their data and build reports and apps. `commons` leverages that expertise, situating the information in a series of prompts and tools designed to create an accurate, fast, and cost-effective agent. From 0a16caac677867f3bcdc4037b45024a242751238 Mon Sep 17 00:00:00 2001 From: Josh Taillon Date: Mon, 14 Sep 2026 11:53:22 -0600 Subject: [PATCH 10/26] docs(py): link the author, and fix the favicons The author entry gains its ORCID, Posit page and GitHub account. great-docs renders each as an icon link beside the name, which is how pkgdown presents the same thing on the R site; it does not link the name text itself. The hand-written favicon block was broken. Its paths began with a slash, which the old Quarto project resolved against the Python site root, but great-docs puts the narrative source under user-guide/, so pkg-py/docs/favicon/ landed at user-guide/favicon/ and all five links resolved to nothing. Rather than repoint them at that prefix, great-docs now derives the icon set itself from a favicon: source, so the link tags are generated and there is no hand-maintained HTML to drift. That source is the same shared icon the other two sites serve, so a tab still shows the same image everywhere. It names the PNG rather than the SVG on purpose: great-docs rasterizes an SVG with cairosvg, which needs a system cairo library and which warns and skips the raster sizes when absent. Pillow handles the PNG with nothing extra. Two things go with the hand-written block: the favicon.svg link that modern browsers would have preferred, and the site.webmanifest link. --- favicon/README.md | 8 +++++--- pkg-py/great-docs.yml | 25 ++++++++++++++----------- 2 files changed, 19 insertions(+), 14 deletions(-) diff --git a/favicon/README.md b/favicon/README.md index 90de4533..859e1497 100644 --- a/favicon/README.md +++ b/favicon/README.md @@ -11,6 +11,8 @@ Edit the files here, never a copy. The icon paths in `site.webmanifest` are relative, because each site serves its own copy from a different prefix. The `` tags live with each site: the -pkgdown template writes them for the R site, `include_in_header` in -`pkg-py/great-docs.yml` for the Python site, and `docs/index.html` for the -landing page. +pkgdown template writes them for the R site and `docs/index.html` does it for +the landing page. The Python site's are generated by great-docs, which derives +its own icon set from the `favicon:` source named in `pkg-py/great-docs.yml`; +point that at a PNG rather than the SVG, because great-docs rasterizes an SVG +with cairosvg, which needs a system cairo library. diff --git a/pkg-py/great-docs.yml b/pkg-py/great-docs.yml index 267a34a9..b178f407 100644 --- a/pkg-py/great-docs.yml +++ b/pkg-py/great-docs.yml @@ -41,10 +41,24 @@ site: logo: light: docs/assets/hex/commons-hex.png +# The icon both other sites serve, so all three show the same one in a tab. +# The PNG rather than the SVG source: great-docs rasterizes an SVG with +# cairosvg, which needs a system cairo library, and warns and skips when it +# is missing. Pillow handles the PNG with no extra dependency. +favicon: docs/favicon/favicon-96x96.png + +# Each key renders an icon link beside the name, the way pkgdown does on the R +# site; great-docs does not link the name text itself. +# Each key renders an icon link beside the name, the way pkgdown does on the R +# site; great-docs does not link the name text itself. authors: - name: Josh Taillon role: Maintainer affiliation: Posit, PBC + github: jat255 + homepage: https://opensource.posit.co/people/josh-taillon/ + orcid: 0000-0002-5185-4503 + github: jat255 funding: name: Posit Software, PBC @@ -54,17 +68,6 @@ funding: homepage: https://posit.co include_in_header: - # The icon tags pkgdown writes for the R site, so both serve the same icons - # from the shared /favicon/ at the site root. A leading / is - # project-relative and Quarto rewrites it per page depth. great-docs' - # `favicon:` key takes a single file and would drop the manifest and the - # other sizes. - - text: | - - - - - # No config key adds a navbar link, and the generated _quarto.yml is # rewritten on every build, so the R cross-link is injected instead. # great-docs collects its own widgets into #gd-navbar-widgets, which is From 9d69dd6800679143eac4c15288383f6b28fc46c0 Mon Sep 17 00:00:00 2001 From: Josh Taillon Date: Mon, 14 Sep 2026 11:57:31 -0600 Subject: [PATCH 11/26] docs(py): mark the current page with weight, and calm two more styles The navbar and the section list both marked the current page with a rule under it. The navbar's own bold had been lost to the earlier weight override, which was not scoped to exclude the active item, and the sidebar item was orange with a thick blue underline, two accent colours the site does not otherwise use. Both now use weight alone. Tables were sized to their widest unwrapped line and then scrolled horizontally. That suits a data table, but the feature-parity table is prose, so it ran past the page rather than wrapping inside it. The previous and next page links were drawn as outlined buttons; they are ordinary links. --- pkg-py/docs/assets/styles.css | 38 ++++++++++++++++++++++++++++++++++- 1 file changed, 37 insertions(+), 1 deletion(-) diff --git a/pkg-py/docs/assets/styles.css b/pkg-py/docs/assets/styles.css index 4f83d816..cfd97ef9 100644 --- a/pkg-py/docs/assets/styles.css +++ b/pkg-py/docs/assets/styles.css @@ -69,7 +69,7 @@ h3 { .doc-reference dt a, .doc-reference section.doc-group > dl a, .table a, -#navbarCollapse > ul.navbar-nav.navbar-nav-scroll.me-auto > li > a { +#navbarCollapse > ul.navbar-nav.navbar-nav-scroll.me-auto > li > a:not(.active) { font-weight: normal; } @@ -86,3 +86,39 @@ h3 { padding: 0.1em 0.3em; border-radius: 3px; } + +/* Mark the current page with weight rather than a rule under it, in the navbar + and in the section list. great-docs underlines the navbar item, and gives the + sidebar item orange text with a thick blue underline, which reads as two + unrelated accent colours against a site that has neither. */ +#navbarCollapse > ul.navbar-nav.navbar-nav-scroll.me-auto > li > a.active { + font-weight: bold; + border-bottom-color: transparent; +} + +#quarto-sidebar a.sidebar-item-text.sidebar-link.active { + color: inherit; + font-weight: bold; + text-decoration: none; +} + +/* great-docs sizes every table to its widest unwrapped line and then scrolls + it, which suits a data table but not one of prose: the feature-parity table + ran well past the page instead of wrapping inside it. */ +.gd-table-scroll > table { + width: 100%; +} + +/* The previous/next page links are drawn as outlined buttons. They are + ordinary links, so they are styled as ordinary links. */ +.nav-page.nav-page-previous a, +.nav-page.nav-page-next a { + border-style: none; + border-width: 0; + border-radius: 0; + padding-left: 0; + padding-right: 0; + margin-left: 0; + margin-right: 0; + text-decoration: underline; +} From 71d653220d4b5279cbd97a49eb70e14c26bc9064 Mon Sep 17 00:00:00 2001 From: Josh Taillon Date: Mon, 14 Sep 2026 12:04:13 -0600 Subject: [PATCH 12/26] docs(py): label the navbar entry "API Reference" The label comes from reference.title, which great-docs only reads when reference is a mapping. As a bare list of sections it was ignored and the entry fell back to "Reference", so the sections move under a sections: key. The current-sidebar-item colour moves behind two custom properties. great-docs hardcodes it in its own stylesheet with no config key, so a CSS override is the only lever and this makes it one value to change rather than a rule to rewrite. --- pkg-py/docs/assets/styles.css | 14 ++++++++++++-- pkg-py/great-docs.yml | 24 ++++++++++++++---------- 2 files changed, 26 insertions(+), 12 deletions(-) diff --git a/pkg-py/docs/assets/styles.css b/pkg-py/docs/assets/styles.css index cfd97ef9..21abbd23 100644 --- a/pkg-py/docs/assets/styles.css +++ b/pkg-py/docs/assets/styles.css @@ -96,9 +96,19 @@ h3 { border-bottom-color: transparent; } +/* great-docs hardcodes the current sidebar item as rgb(244, 121, 0) with a + 3px rgba(101, 180, 237, .75) underline, in great-docs.scss, with no config + key to change it. This is the only place to override it. Set the two + properties below to try other treatments: a colour on its own, weight on + its own, or both. `inherit` keeps the body colour. */ +:root { + --commons-active-link-color: inherit; + --commons-active-link-weight: bold; +} + #quarto-sidebar a.sidebar-item-text.sidebar-link.active { - color: inherit; - font-weight: bold; + color: var(--commons-active-link-color); + font-weight: var(--commons-active-link-weight); text-decoration: none; } diff --git a/pkg-py/great-docs.yml b/pkg-py/great-docs.yml index b178f407..54df1376 100644 --- a/pkg-py/great-docs.yml +++ b/pkg-py/great-docs.yml @@ -19,15 +19,19 @@ changelog: # does not export `ui`, so the Shiny entries only appear because they are # listed here. reference: - - title: Main functions - desc: The main agent constructor, plus the building blocks for a commons agent. - contents: [Commons, data_source, semantic_layer, measure, context_layer] - - title: Supporting types - desc: The objects the constructors return, and the values they carry. - contents: [DataSource, SemanticLayer, ContextLayer, Measure, Injected, Tag, list_tables] - - title: Shiny UI and server - desc: "Put a commons agent inside of an interactive chat app. Needs the `shiny` extra." - contents: [ui.app, ui.server, ui.theme, ui.commons_chat_dependency, ui.asset_base_url] + # The dict form, because the navbar label only comes from `title` when + # `reference` is a mapping; as a bare list of sections it is ignored. + title: API Reference + sections: + - title: Main functions + desc: The main agent constructor, plus the building blocks for a commons agent. + contents: [Commons, data_source, semantic_layer, measure, context_layer] + - title: Supporting types + desc: The objects the constructors return, and the values they carry. + contents: [DataSource, SemanticLayer, ContextLayer, Measure, Injected, Tag, list_tables] + - title: Shiny UI and server + desc: "Put a commons agent inside of an interactive chat app. Needs the `shiny` extra." + contents: [ui.app, ui.server, ui.theme, ui.commons_chat_dependency, ui.asset_base_url] # Nested under `site:`, which is the key great-docs reads; a top-level # `css:` is silently ignored. Paths are relative to the project root. @@ -131,7 +135,7 @@ version_aliases: dev: true announcement: - content: "`commons` for Python is a **beta** and does not yet do everything the R package does." + content: "`commons` for Python is still in **beta** and does not yet do everything the R package does. Click on this banner to see feature parity." type: info url: user-guide/feature-parity.html dismissable: true From f407af2474dd9c9647ef12fc5c1cebb2bd4c3efe Mon Sep 17 00:00:00 2001 From: Josh Taillon Date: Mon, 14 Sep 2026 12:27:01 -0600 Subject: [PATCH 13/26] docs(py): take the orange out of the navbar hover Hovering a navbar link filled it with an orange pill and white text. It is a literal in great-docs.scss with a dark-mode twin at a higher specificity, so both selectors are spelled out. A neutral tint matches the hover already used by the icon buttons beside it. The orange reaches four places in all. Two are the --gd-active-link theme variable, now pointed at currentColor so the dark-mode sidebar and on-this-page active items follow; two are literals needing their selectors overridden. --gd-syn-operator is deliberately untouched, being the operator colour inside code blocks rather than site accent. --- pkg-py/docs/assets/styles.css | 55 +++++++++++++++++++++++++++++++---- 1 file changed, 50 insertions(+), 5 deletions(-) diff --git a/pkg-py/docs/assets/styles.css b/pkg-py/docs/assets/styles.css index 21abbd23..62c02035 100644 --- a/pkg-py/docs/assets/styles.css +++ b/pkg-py/docs/assets/styles.css @@ -96,14 +96,37 @@ h3 { border-bottom-color: transparent; } -/* great-docs hardcodes the current sidebar item as rgb(244, 121, 0) with a - 3px rgba(101, 180, 237, .75) underline, in great-docs.scss, with no config - key to change it. This is the only place to override it. Set the two - properties below to try other treatments: a colour on its own, weight on - its own, or both. `inherit` keeps the body colour. */ +/* great-docs paints several things a signature orange that this site does not + otherwise use. Two of them are theme variables and can be redirected from + here; the other two are literals in great-docs.scss and need their own + selectors overridden. There is no configuration key for any of it. + + Left alone deliberately: --gd-syn-operator, the operator colour inside code + blocks, which is syntax highlighting rather than site accent. + + To try other treatments, change the two properties below: a colour on its + own, weight on its own, or both. `inherit` keeps the body colour. */ :root { --commons-active-link-color: inherit; --commons-active-link-weight: bold; + + /* Consumed by the dark-mode sidebar and on-this-page active items. + currentColor makes `color: var(--gd-active-link)` a no-op. */ + --gd-active-link: currentColor; +} + +body.quarto-dark { + --gd-active-link: currentColor; +} + +/* The current page, in the navbar and in the section list: weight rather than + a rule under it. great-docs underlines the navbar item and gives the sidebar + item orange text with a thick blue underline, two accent colours the site + has nowhere else. The sidebar colour is a literal, so the variable above + does not reach it. */ +#navbarCollapse > ul.navbar-nav.navbar-nav-scroll.me-auto > li > a.active { + font-weight: bold; + border-bottom-color: transparent; } #quarto-sidebar a.sidebar-item-text.sidebar-link.active { @@ -112,6 +135,28 @@ h3 { text-decoration: none; } +/* Hovering a navbar link filled it with an orange pill and white text. A + neutral tint matches the hover on the icon buttons beside it. Both themes + are spelled out because great-docs sets the dark one at a higher + specificity than the light one. */ +#navbarCollapse > ul.navbar-nav.navbar-nav-scroll.me-auto > li > a:hover, +body.quarto-dark + #navbarCollapse + > ul.navbar-nav.navbar-nav-scroll.me-auto + > li + > a:hover { + background-color: var(--commons-navbar-hover-bg); + color: inherit; +} + +:root { + --commons-navbar-hover-bg: rgb(0 0 0 / 6%); +} + +body.quarto-dark { + --commons-navbar-hover-bg: rgb(255 255 255 / 12%); +} + /* great-docs sizes every table to its widest unwrapped line and then scrolls it, which suits a data table but not one of prose: the feature-parity table ran well past the page instead of wrapping inside it. */ From 009305880cb013c07f588936eec7cd1bace5d028 Mon Sep 17 00:00:00 2001 From: Josh Taillon Date: Mon, 14 Sep 2026 12:41:39 -0600 Subject: [PATCH 14/26] docs(py): make the navbar hover visible in light mode The light tint was 6% ink, which is what great-docs uses for the resting state of its navbar icon buttons, not their hover, so on a #f0f0f0 navbar it was all but invisible. Both themes now sit at 14%, which lands them a similar distance from their own background: #cecece against light, #3a3a3a against dark. That is a step past the 10% and 12% great-docs hovers its icon buttons at, because those have a border to help them read and a bare text link does not. --- pkg-py/docs/assets/styles.css | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/pkg-py/docs/assets/styles.css b/pkg-py/docs/assets/styles.css index 62c02035..c144483c 100644 --- a/pkg-py/docs/assets/styles.css +++ b/pkg-py/docs/assets/styles.css @@ -149,12 +149,17 @@ body.quarto-dark color: inherit; } +/* Ink over the navbar background, which is #f0f0f0 light and #1a1a1a dark, so + the two alphas land a similar distance from their base: #cecece and #3a3a3a. + great-docs hovers its icon buttons at 10% and 12%, but those carry a border + to help them read and a bare text link does not, so these go a step further. + 6% was the buttons' resting tint and was invisible as a hover. */ :root { - --commons-navbar-hover-bg: rgb(0 0 0 / 6%); + --commons-navbar-hover-bg: rgb(0 0 0 / 14%); } body.quarto-dark { - --commons-navbar-hover-bg: rgb(255 255 255 / 12%); + --commons-navbar-hover-bg: rgb(255 255 255 / 14%); } /* great-docs sizes every table to its widest unwrapped line and then scrolls From 4e99582543bebd854b54eafab179c4336bfe69b3 Mon Sep 17 00:00:00 2001 From: Josh Taillon Date: Mon, 14 Sep 2026 13:15:54 -0600 Subject: [PATCH 15/26] docs(py): fix the navbar hover text and the active underline The hover label was set to `inherit`, which takes the colour of the parent list item rather than the link's own, so on the new hover tint it came out almost white. It now names the navbar text colour, which is already theme-aware. The active navbar item still carried a blue underline. There are two underlines on it: a bottom border from .nav-underline, which was already suppressed, and a text decoration from .nav-link.active in the accent blue, which was not. The override block is also consolidated. An earlier edit in this branch left a duplicate of the current-page rule, and the variable declarations had spread across two :root and two body.quarto-dark blocks. --- pkg-py/docs/assets/styles.css | 80 ++++++++++------------------------- 1 file changed, 23 insertions(+), 57 deletions(-) diff --git a/pkg-py/docs/assets/styles.css b/pkg-py/docs/assets/styles.css index c144483c..ac3aabc8 100644 --- a/pkg-py/docs/assets/styles.css +++ b/pkg-py/docs/assets/styles.css @@ -62,10 +62,11 @@ h3 { margin-top: -2px; } -/* great-docs sets its reference entries, its navbar links and its table links - in bold monospace. The monospace is wanted, since these are symbol names, - but the weight on top of an underline reads as shouting on a page that is - mostly a list of them. Normal weight keeps the underline as the affordance. */ +/* Overrides for great-docs' own stylesheet, which this file loads after. + None of the below has a configuration key. */ + +/* Symbol names stay monospace, but drop the bold: the reference is mostly a + list of them, and weight on top of an underline shouts. */ .doc-reference dt a, .doc-reference section.doc-group > dl a, .table a, @@ -73,9 +74,8 @@ h3 { font-weight: normal; } -/* The announcement banner paints a mid-blue background but leaves the text at - the body colour, which is close to unreadable in light mode, and an inline - code span keeps its own pale pill background and so disappears entirely. */ +/* The banner sets a mid-blue background but no text colour, and a code span + keeps its own pale pill, which vanishes into it. */ .gd-announcement-banner { color: #fff; } @@ -87,46 +87,28 @@ h3 { border-radius: 3px; } -/* Mark the current page with weight rather than a rule under it, in the navbar - and in the section list. great-docs underlines the navbar item, and gives the - sidebar item orange text with a thick blue underline, which reads as two - unrelated accent colours against a site that has neither. */ -#navbarCollapse > ul.navbar-nav.navbar-nav-scroll.me-auto > li > a.active { - font-weight: bold; - border-bottom-color: transparent; -} - -/* great-docs paints several things a signature orange that this site does not - otherwise use. Two of them are theme variables and can be redirected from - here; the other two are literals in great-docs.scss and need their own - selectors overridden. There is no configuration key for any of it. - - Left alone deliberately: --gd-syn-operator, the operator colour inside code - blocks, which is syntax highlighting rather than site accent. - - To try other treatments, change the two properties below: a colour on its - own, weight on its own, or both. `inherit` keeps the body colour. */ :root { --commons-active-link-color: inherit; --commons-active-link-weight: bold; - - /* Consumed by the dark-mode sidebar and on-this-page active items. - currentColor makes `color: var(--gd-active-link)` a no-op. */ + --commons-navbar-hover-bg: rgb(0 0 0 / 14%); + /* Dark-mode sidebar and on-this-page active items read this; currentColor + makes those rules a no-op. */ --gd-active-link: currentColor; } body.quarto-dark { + --commons-navbar-hover-bg: rgb(255 255 255 / 14%); --gd-active-link: currentColor; } -/* The current page, in the navbar and in the section list: weight rather than - a rule under it. great-docs underlines the navbar item and gives the sidebar - item orange text with a thick blue underline, two accent colours the site - has nowhere else. The sidebar colour is a literal, so the variable above - does not reach it. */ +/* Current page: weight, not a coloured rule. The sidebar colour is a literal + upstream, so --gd-active-link above does not reach it. */ #navbarCollapse > ul.navbar-nav.navbar-nav-scroll.me-auto > li > a.active { font-weight: bold; + /* Two underlines: a bottom border from .nav-underline, a text decoration + from .nav-link.active. */ border-bottom-color: transparent; + text-decoration: none; } #quarto-sidebar a.sidebar-item-text.sidebar-link.active { @@ -135,10 +117,8 @@ body.quarto-dark { text-decoration: none; } -/* Hovering a navbar link filled it with an orange pill and white text. A - neutral tint matches the hover on the icon buttons beside it. Both themes - are spelled out because great-docs sets the dark one at a higher - specificity than the light one. */ +/* Hover filled the link with an orange pill. Both themes are spelled out + because great-docs sets the dark one at a higher specificity. */ #navbarCollapse > ul.navbar-nav.navbar-nav-scroll.me-auto > li > a:hover, body.quarto-dark #navbarCollapse @@ -146,31 +126,17 @@ body.quarto-dark > li > a:hover { background-color: var(--commons-navbar-hover-bg); - color: inherit; -} - -/* Ink over the navbar background, which is #f0f0f0 light and #1a1a1a dark, so - the two alphas land a similar distance from their base: #cecece and #3a3a3a. - great-docs hovers its icon buttons at 10% and 12%, but those carry a border - to help them read and a bare text link does not, so these go a step further. - 6% was the buttons' resting tint and was invisible as a hover. */ -:root { - --commons-navbar-hover-bg: rgb(0 0 0 / 14%); -} - -body.quarto-dark { - --commons-navbar-hover-bg: rgb(255 255 255 / 14%); + /* Not `inherit`: that takes the list item's colour, not the link's. */ + color: var(--gd-navbar-text); } -/* great-docs sizes every table to its widest unwrapped line and then scrolls - it, which suits a data table but not one of prose: the feature-parity table - ran well past the page instead of wrapping inside it. */ +/* Tables were sized to their widest unwrapped line and scrolled. Suits a data + table; the feature-parity table is prose. */ .gd-table-scroll > table { width: 100%; } -/* The previous/next page links are drawn as outlined buttons. They are - ordinary links, so they are styled as ordinary links. */ +/* The previous/next page links were drawn as outlined buttons. */ .nav-page.nav-page-previous a, .nav-page.nav-page-next a { border-style: none; From e3bb4c8fe0daa4b12846d5b6ee9409bfe88757c6 Mon Sep 17 00:00:00 2001 From: Josh Taillon Date: Mon, 14 Sep 2026 13:21:53 -0600 Subject: [PATCH 16/26] docs(py): fix the dark sidebar's current item and hover alignment Pointing --gd-active-link at currentColor removed the orange but left the current item inheriting a colour dimmer than its own siblings, so in dark mode it read as the least prominent entry in the list rather than the most. Both the variable and the light-mode override now name --gd-text-primary, which is itself theme-scoped: #e0e0e0 against the #c8c8c8 of the other items, and the darkest text in light mode. The hover pill carries 8px of padding on each side but a -8px left margin, which pulled it flush against the sidebar's left edge while leaving it inset on the right. Dropping the negative margin makes the inset even. --- pkg-py/docs/assets/styles.css | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) diff --git a/pkg-py/docs/assets/styles.css b/pkg-py/docs/assets/styles.css index ac3aabc8..ebf59c84 100644 --- a/pkg-py/docs/assets/styles.css +++ b/pkg-py/docs/assets/styles.css @@ -88,17 +88,20 @@ h3 { } :root { - --commons-active-link-color: inherit; + /* The brightest text in either theme, so the current item reads as more + prominent than its siblings rather than less. --gd-text-primary is itself + theme-scoped, so one value serves both. */ + --commons-active-link-color: var(--gd-text-primary); --commons-active-link-weight: bold; --commons-navbar-hover-bg: rgb(0 0 0 / 14%); - /* Dark-mode sidebar and on-this-page active items read this; currentColor - makes those rules a no-op. */ - --gd-active-link: currentColor; + --gd-active-link: var(--gd-text-primary); } +/* Repeated because great-docs defines both of these under this same selector, + which outranks :root. */ body.quarto-dark { --commons-navbar-hover-bg: rgb(255 255 255 / 14%); - --gd-active-link: currentColor; + --gd-active-link: var(--gd-text-primary); } /* Current page: weight, not a coloured rule. The sidebar colour is a literal @@ -148,3 +151,9 @@ body.quarto-dark margin-right: 0; text-decoration: underline; } + +/* The hover pill carries 8px of padding each side but a -8px left margin, so + it sat flush against the sidebar's left edge while inset on the right. */ +#quarto-sidebar.gd-sidebar-float .sidebar-link[href] { + margin-left: 0; +} From dfd5e862317b90db531ce3644314ef0c400c88f9 Mon Sep 17 00:00:00 2001 From: Josh Taillon Date: Mon, 14 Sep 2026 13:26:51 -0600 Subject: [PATCH 17/26] docs(py): order the user guide, and land on the introduction The guide was ordered alphabetically, so it opened on the feature-parity table and the navbar entry pointed there too. Numeric filename prefixes set the order in auto-discovery mode and great-docs strips them when it copies the pages, so the published URLs are unchanged and the navbar follows the first file. The explicit user_guide list was the other option and was rejected: it only reads the conventional user_guide/ directory, which would have meant moving the pages out of docs/ and repointing the asset paths that the stylesheet and the favicon source depend on, and it requires a section heading the sidebar does not currently have. --- pkg-py/docs/{get-started.qmd => 01-get-started.qmd} | 0 pkg-py/docs/{governance.qmd => 02-governance.qmd} | 0 pkg-py/docs/{feature-parity.qmd => 03-feature-parity.qmd} | 0 3 files changed, 0 insertions(+), 0 deletions(-) rename pkg-py/docs/{get-started.qmd => 01-get-started.qmd} (100%) rename pkg-py/docs/{governance.qmd => 02-governance.qmd} (100%) rename pkg-py/docs/{feature-parity.qmd => 03-feature-parity.qmd} (100%) diff --git a/pkg-py/docs/get-started.qmd b/pkg-py/docs/01-get-started.qmd similarity index 100% rename from pkg-py/docs/get-started.qmd rename to pkg-py/docs/01-get-started.qmd diff --git a/pkg-py/docs/governance.qmd b/pkg-py/docs/02-governance.qmd similarity index 100% rename from pkg-py/docs/governance.qmd rename to pkg-py/docs/02-governance.qmd diff --git a/pkg-py/docs/feature-parity.qmd b/pkg-py/docs/03-feature-parity.qmd similarity index 100% rename from pkg-py/docs/feature-parity.qmd rename to pkg-py/docs/03-feature-parity.qmd From 98ff680835afadad3960cc1fb5f261dba664aea2 Mon Sep 17 00:00:00 2001 From: Josh Taillon Date: Mon, 14 Sep 2026 13:27:12 -0600 Subject: [PATCH 18/26] docs(py): reword the beta banner Josh's wording, taken as written. --- pkg-py/great-docs.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkg-py/great-docs.yml b/pkg-py/great-docs.yml index 54df1376..5bc28f8b 100644 --- a/pkg-py/great-docs.yml +++ b/pkg-py/great-docs.yml @@ -135,7 +135,7 @@ version_aliases: dev: true announcement: - content: "`commons` for Python is still in **beta** and does not yet do everything the R package does. Click on this banner to see feature parity." + content: "Heads up! `commons` for Python is *still in beta* and is not yet equal to the R package in functionality. Click here to see specific feature parity." type: info url: user-guide/feature-parity.html dismissable: true From c5400d0e50c17d8ec9dd4612bfbbf704dfc63ebd Mon Sep 17 00:00:00 2001 From: Josh Taillon Date: Mon, 14 Sep 2026 13:39:13 -0600 Subject: [PATCH 19/26] docs(py): make the beta banner link work off the landing page The banner is built client-side from a meta tag and its url is used verbatim, so Quarto never rewrites it per page depth. A relative link therefore resolved against the current page's directory: from user-guide/ the banner asked for user-guide/user-guide/feature-parity.html. It was broken on 84 of the 90 pages that carry it, everything but the six at the site root. Quarto's own offset meta supplies the prefix, which is how great-docs' version selector and sidebar scripts locate the site root, and it stays correct in a pull request preview and inside a versioned copy. An absolute or root-relative url would have sent preview traffic to the published site instead. The link is found by a class substring rather than by name because great-docs drops every include_in_header entry whose text contains its own "gd-announcement" marker, which removed an earlier version of this script without any warning. --- pkg-py/great-docs.yml | 37 +++++++++++++++++++++++++++++++++++++ 1 file changed, 37 insertions(+) diff --git a/pkg-py/great-docs.yml b/pkg-py/great-docs.yml index 5bc28f8b..5d47e237 100644 --- a/pkg-py/great-docs.yml +++ b/pkg-py/great-docs.yml @@ -108,6 +108,43 @@ include_in_header: })(); + # Selected by class substring on purpose: great-docs drops every + # include_in_header entry whose text contains its own "gd-announcement" + # marker, so naming the class in full removes this script silently. + # The banner is built client-side from a meta tag and its url is used + # verbatim, so Quarto never rewrites it per page depth and a relative link + # resolves against the current page's directory: from user-guide/ it asked + # for user-guide/user-guide/. Quarto's own offset meta gives the prefix back, + # which is what great-docs' version selector and sidebar scripts use, and it + # stays correct in a pull request preview and inside a /v/ copy. + - text: | + + versions: - label: "0.2.0 (dev)" tag: dev From 2975a373e10e9d45bb066d5c71531f82bd041997 Mon Sep 17 00:00:00 2001 From: Josh Taillon Date: Mon, 14 Sep 2026 13:47:07 -0600 Subject: [PATCH 20/26] docs(py): read the banner's path from the meta, not from the link The previous attempt never ran to completion. Assigning to a.href reflects the resolved absolute URL into the content attribute, so by the time the script read getAttribute("href") it saw the already-doubled absolute path, which tripped the guard that skips links needing no prefix. The raw relative path is now read back from the announcement meta, which is the only place it survives unresolved. Verified in Chromium rather than by reasoning about the emitted markup: the banner link is followed from the landing page, two guide pages, the reference index, a reference detail page and a versioned copy, and every one returns 200 on the feature-parity page, with the versioned copy correctly staying inside its own /v/dev/ tree. --- pkg-py/great-docs.yml | 34 +++++++++++++++++++--------------- 1 file changed, 19 insertions(+), 15 deletions(-) diff --git a/pkg-py/great-docs.yml b/pkg-py/great-docs.yml index 5d47e237..50dc1176 100644 --- a/pkg-py/great-docs.yml +++ b/pkg-py/great-docs.yml @@ -108,15 +108,20 @@ include_in_header: })(); - # Selected by class substring on purpose: great-docs drops every - # include_in_header entry whose text contains its own "gd-announcement" - # marker, so naming the class in full removes this script silently. - # The banner is built client-side from a meta tag and its url is used - # verbatim, so Quarto never rewrites it per page depth and a relative link - # resolves against the current page's directory: from user-guide/ it asked - # for user-guide/user-guide/. Quarto's own offset meta gives the prefix back, - # which is what great-docs' version selector and sidebar scripts use, and it - # stays correct in a pull request preview and inside a /v/ copy. + # Selected by class and meta-name substrings on purpose: great-docs drops + # every include_in_header entry whose text contains its own "gd-announcement" + # marker, so naming either in full removes this script silently. + # + # The banner is built client-side and its url is used verbatim, so Quarto + # never rewrites it per page depth and a relative link resolved against the + # current page's directory: from user-guide/ the banner asked for + # user-guide/user-guide/. The prefix comes from Quarto's offset meta, which is + # how great-docs' own version selector and sidebar scripts find the site root, + # and it stays correct in a pull request preview and inside a /v/ copy. + # + # The raw path is read back from the meta, not from the link: assigning to + # a.href reflects the *resolved* absolute URL into the attribute, so reading + # the link would only ever see the already-wrong absolute path. - text: | ' + self.assertIsNone(fix(page, BASE, "../")) + + def test_leaves_a_script_using_the_trailing_slash_form_alone(self): + # Same risk, one character different: only hrefs are rewritten. + page = f'' + self.assertIsNone(fix(page, BASE, "../")) + + def test_rewrites_the_link_but_not_a_neighbouring_script(self): + page = ( + f'' + f'' + ) + out = fix(page, BASE, "../") + assert out is not None + self.assertIn('href="../favicon.ico"', out) + self.assertIn(f'var base="{BASE}";', out) + def test_leaves_an_unrelated_absolute_url_alone(self): page = 'PyPI' self.assertIsNone(fix(page, BASE, "../")) diff --git a/pkg-py/great-docs.yml b/pkg-py/great-docs.yml index 2558d84d..5b855ac0 100644 --- a/pkg-py/great-docs.yml +++ b/pkg-py/great-docs.yml @@ -72,7 +72,6 @@ authors: github: jat255 homepage: https://opensource.posit.co/people/josh-taillon/ orcid: 0000-0002-5185-4503 - github: jat255 funding: name: Posit Software, PBC From 689b30b33b096972df0aa65e340aee46ec3de495 Mon Sep 17 00:00:00 2001 From: Josh Taillon Date: Mon, 14 Sep 2026 14:49:47 -0600 Subject: [PATCH 24/26] docs(py): stop Quarto restoring the banner's un-prefixed link The offset fix held locally and on the published site but not in a pull request preview, where the banner link 404ed again. Quarto's external-link pass runs after it and restores link.dataset.originalHref, which quarto-nav.js had set to the banner's original un-prefixed url, undoing the correction. That pass only treats this link as external when the served prefix differs from site_url, which is true of every preview and of neither localhost nor the published site, so no local check could have caught it. The link now carries Quarto's own .no-external opt-out, which excludes it from that pass, and the stashed original is updated to the corrected path so the restore is harmless if it runs anyway. --- pkg-py/great-docs.yml | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/pkg-py/great-docs.yml b/pkg-py/great-docs.yml index 5b855ac0..88ce61f1 100644 --- a/pkg-py/great-docs.yml +++ b/pkg-py/great-docs.yml @@ -147,7 +147,15 @@ include_in_header: if (!raw || /^([a-z][a-z0-9+.-]*:|\/\/|\/|#)/i.test(raw)) return; var off = document.querySelector('meta[name="quarto:offset"]'); var prefix = (off ? off.getAttribute("content") || "./" : "./"); - link.setAttribute("href", prefix.replace(/\/?$/, "/") + raw); + var fixed = prefix.replace(/\/?$/, "/") + raw; + link.setAttribute("href", fixed); + // Quarto stashes the pre-rewrite href here and its external-link + // pass restores it, which would undo the line above. That pass + // treats this link as external whenever the served prefix differs + // from site_url, which is the case in every pull request preview, + // so both the opt-out class and the stashed value are set. + link.classList.add("no-external"); + link.dataset.originalHref = fixed; link.dataset.commonsOffsetApplied = "1"; } if (document.readyState === "loading") { From 5c6fe51cf22933a960cf00328e38fc1550f642e6 Mon Sep 17 00:00:00 2001 From: Josh Taillon Date: Mon, 14 Sep 2026 14:54:31 -0600 Subject: [PATCH 25/26] docs(py): point the API reference source links inside pkg-py The links are built relative to the package root, which in this monorepo is pkg-py/ rather than the repository root, so every "source" button pointed at a path that does not exist. great-docs has a source.path key for exactly this, and it cannot be used: it replaces the whole path with the file's basename, which is right for a flat layout but flattens commons/_ui/_server.py and the three others like it. The package directory is inserted after rendering instead, which preserves the real layout. Verified against the repository rather than by eye: all nine distinct source paths the reference emits exist under pkg-py, and the generated URL for Commons resolves on both this branch and main. --- .github/scripts/docs-postprocess.py | 35 ++++++++++--- .github/scripts/test_docs_postprocess.py | 64 ++++++++++++++++++------ .github/workflows/quartodoc.yaml | 2 +- scripts/preview-docs.sh | 2 +- 4 files changed, 77 insertions(+), 26 deletions(-) diff --git a/.github/scripts/docs-postprocess.py b/.github/scripts/docs-postprocess.py index edd40962..e08c3097 100644 --- a/.github/scripts/docs-postprocess.py +++ b/.github/scripts/docs-postprocess.py @@ -7,6 +7,10 @@ under `v//`. The generated icons sit at the root of each copy, so Quarto's own per-page offset is the right prefix. +**Source links missing the package directory.** They are built relative to the +package root, which in this monorepo is `pkg-py/` rather than the repository +root, so every "source" button pointed at a path that does not exist. + **The navbar version badge.** great-docs derives it from the newest GitHub Release for the whole repository and cannot filter by tag prefix, so in this monorepo it shows whichever of the two release series published last. The @@ -16,7 +20,7 @@ Remove the corresponding half of this script if great-docs gains relative icon links, or a way to suppress the badge. -Usage: docs-postprocess.py +Usage: docs-postprocess.py """ from __future__ import annotations @@ -37,9 +41,16 @@ # canonical URL on every non-latest version. LINK = re.compile(r"]*>") +# Source links are built relative to the package root, which in a monorepo is +# not the repository root, so they arrive missing the package directory. The +# `source.path` config key cannot do this: it replaces the whole path with the +# file's basename, which flattens nested modules such as commons/_ui/_server.py. +# The non-greedy middle group is the git ref, which may itself contain slashes. +SOURCE = re.compile(r'(https://github\.com/[^"/]+/[^"/]+/blob/)([^"]+?)(/src/)') + -def fix(text: str, site_url: str, offset: str) -> str | None: - """Return `text` with icon links made relative and the badge removed. +def fix(text: str, site_url: str, package_root: str, offset: str) -> str | None: + """Return `text` post-processed, or None when it needs no change. Returns None when the page needs neither, which keeps the caller from rewriting a file it does not have to touch and makes this idempotent. @@ -57,15 +68,23 @@ def relativize(match: re.Match[str]) -> str: icons += n return tag + def relocate(match: re.Match[str]) -> str: + ref = match.group(2) + # Already carries the package directory, so leave it be. + if ref == package_root or ref.endswith("/" + package_root): + return match.group(0) + return f"{match.group(1)}{ref}/{package_root}{match.group(3)}" + patched = LINK.sub(relativize, text) patched, badges = BADGE.subn("", patched) + patched, sources = SOURCE.subn(relocate, patched) - if not (icons or badges) or patched == text: + if not (icons or badges or sources) or patched == text: return None return patched -def main(root: str, site_url: str) -> int: +def main(root: str, site_url: str, package_root: str) -> int: directory = pathlib.Path(root) if not directory.is_dir(): print(f"{root} is not a directory", file=sys.stderr) @@ -78,7 +97,7 @@ def main(root: str, site_url: str) -> int: # makes this correct inside a versioned copy as well as at the top. found = OFFSET.search(text) offset = found.group(1) if found else "./" - patched = fix(text, site_url, offset) + patched = fix(text, site_url, package_root, offset) if patched is None: skipped += 1 continue @@ -90,7 +109,7 @@ def main(root: str, site_url: str) -> int: if __name__ == "__main__": - if len(sys.argv) != 3: + if len(sys.argv) != 4: print(__doc__, file=sys.stderr) raise SystemExit(2) - raise SystemExit(main(sys.argv[1], sys.argv[2])) + raise SystemExit(main(sys.argv[1], sys.argv[2], sys.argv[3])) diff --git a/.github/scripts/test_docs_postprocess.py b/.github/scripts/test_docs_postprocess.py index 260158c7..1686e517 100644 --- a/.github/scripts/test_docs_postprocess.py +++ b/.github/scripts/test_docs_postprocess.py @@ -13,12 +13,14 @@ fix = mod.fix BASE = "https://posit-dev.github.io/commons/py/" +ROOT = "pkg-py" +BLOB = "https://github.com/posit-dev/commons/blob" class StripVersionBadgeTest(unittest.TestCase): def test_removes_the_badge(self): page = 'commons v0.1.0.dev1' - out = fix(page, BASE, "./") + out = fix(page, BASE, ROOT, "./") assert out is not None self.assertNotIn("version-badge", out) self.assertNotIn("v0.1.0.dev1", out) @@ -27,27 +29,27 @@ def test_removes_the_badge(self): def test_removes_the_badge_with_attributes(self): page = 'v0.1.0.dev1' - out = fix(page, BASE, "./") + out = fix(page, BASE, ROOT, "./") assert out is not None self.assertEqual(out.strip(), "") def test_leaves_a_longer_class_alone(self): # Anchored on the closing quote, so version-badge-legend is not a badge. page = 'v1' - self.assertIsNone(fix(page, BASE, "./")) + self.assertIsNone(fix(page, BASE, ROOT, "./")) class RelativizeIconsTest(unittest.TestCase): def test_rewrites_an_absolute_icon_link_at_the_root(self): page = f'' - out = fix(page, BASE, "./") + out = fix(page, BASE, ROOT, "./") assert out is not None self.assertIn('href="./favicon.ico"', out) self.assertNotIn(BASE, out) def test_rewrites_with_a_nested_offset(self): page = f'' - out = fix(page, BASE, "../") + out = fix(page, BASE, ROOT, "../") assert out is not None self.assertIn('href="../apple-touch-icon.png"', out) @@ -56,14 +58,14 @@ def test_rewrites_every_occurrence(self): f'' f'' ) - out = fix(page, BASE, "../") + out = fix(page, BASE, ROOT, "../") assert out is not None self.assertEqual(out.count("../favicon-"), 2) self.assertNotIn(BASE, out) def test_tolerates_a_base_without_a_trailing_slash(self): page = f'' - out = fix(page, BASE.rstrip("/"), "../") + out = fix(page, BASE.rstrip("/"), ROOT, "../") assert out is not None self.assertIn('href="../favicon.ico"', out) @@ -73,49 +75,79 @@ def test_leaves_the_versioned_canonical_script_alone(self): # Rewriting it to a page-relative prefix would produce a bogus # canonical URL on every non-latest version. page = '' - self.assertIsNone(fix(page, BASE, "../")) + self.assertIsNone(fix(page, BASE, ROOT, "../")) def test_leaves_a_script_using_the_trailing_slash_form_alone(self): # Same risk, one character different: only hrefs are rewritten. page = f'' - self.assertIsNone(fix(page, BASE, "../")) + self.assertIsNone(fix(page, BASE, ROOT, "../")) def test_rewrites_the_link_but_not_a_neighbouring_script(self): page = ( f'' f'' ) - out = fix(page, BASE, "../") + out = fix(page, BASE, ROOT, "../") assert out is not None self.assertIn('href="../favicon.ico"', out) self.assertIn(f'var base="{BASE}";', out) def test_leaves_an_unrelated_absolute_url_alone(self): page = 'PyPI' - self.assertIsNone(fix(page, BASE, "../")) + self.assertIsNone(fix(page, BASE, ROOT, "../")) def test_leaves_a_page_needing_nothing(self): - self.assertIsNone(fix("plain", BASE, "./")) + self.assertIsNone(fix("plain", BASE, ROOT, "./")) def test_is_idempotent(self): page = ( f'' 'v1' ) - once = fix(page, BASE, "../") + once = fix(page, BASE, ROOT, "../") assert once is not None - self.assertIsNone(fix(once, BASE, "../")) + self.assertIsNone(fix(once, BASE, ROOT, "../")) def test_does_both_jobs_in_one_pass(self): page = ( f'' 'v0.1.0.dev1' ) - out = fix(page, BASE, "../") + out = fix(page, BASE, ROOT, "../") assert out is not None self.assertIn('href="../favicon.ico"', out) self.assertNotIn("version-badge", out) +class SourceLinkTest(unittest.TestCase): + def test_inserts_the_package_root(self): + page = f'source' + out = fix(page, BASE, ROOT, "./") + assert out is not None + self.assertIn(f"{BLOB}/main/pkg-py/src/commons/_agent.py#L58-L368", out) + + def test_keeps_a_nested_module_path(self): + # source.path would have flattened this to the basename, which is why + # the prefix is inserted here instead of configured there. + page = f'source' + out = fix(page, BASE, ROOT, "./") + assert out is not None + self.assertIn(f"{BLOB}/main/pkg-py/src/commons/_ui/_server.py", out) + + def test_handles_a_ref_containing_slashes(self): + page = f'source' + out = fix(page, BASE, ROOT, "./") + assert out is not None + self.assertIn(f"{BLOB}/jat255/some-branch/pkg-py/src/commons/_agent.py", out) + + def test_is_idempotent_on_source_links(self): + page = f'source' + self.assertIsNone(fix(page, BASE, ROOT, "./")) + + def test_leaves_a_non_source_repo_link_alone(self): + page = f'issue' + self.assertIsNone(fix(page, BASE, ROOT, "./")) + + if __name__ == "__main__": - unittest.main(verbosity=2) + unittest.main(verbosity=2) \ No newline at end of file diff --git a/.github/workflows/quartodoc.yaml b/.github/workflows/quartodoc.yaml index b48f7b58..a1c2d335 100644 --- a/.github/workflows/quartodoc.yaml +++ b/.github/workflows/quartodoc.yaml @@ -52,7 +52,7 @@ jobs: working-directory: pkg-py run: | site_url="$(uv run python -c 'import yaml; print(yaml.safe_load(open("great-docs.yml"))["site_url"])')" - python3 ../.github/scripts/docs-postprocess.py great-docs/_site "$site_url" + python3 ../.github/scripts/docs-postprocess.py great-docs/_site "$site_url" pkg-py # The deploy publishes the whole of docs/, so the rendered site has to # sit at the path it is served from. diff --git a/scripts/preview-docs.sh b/scripts/preview-docs.sh index 24426129..94786cdb 100755 --- a/scripts/preview-docs.sh +++ b/scripts/preview-docs.sh @@ -126,7 +126,7 @@ build_py() { (cd "$root/pkg-py" && uv sync --extra shiny --group docs --quiet) (cd "$root/pkg-py" && uv run great-docs build) site_url="$(cd "$root/pkg-py" && uv run python -c 'import yaml; print(yaml.safe_load(open("great-docs.yml"))["site_url"])')" - (cd "$root/pkg-py" && uv run python "$root/.github/scripts/docs-postprocess.py" great-docs/_site "$site_url") + (cd "$root/pkg-py" && uv run python "$root/.github/scripts/docs-postprocess.py" great-docs/_site "$site_url" pkg-py) rm -rf "$root/docs/py" cp -r "$root/pkg-py/great-docs/_site" "$root/docs/py" } From e03917f53bb899c0612105e915b006fe8f2666b1 Mon Sep 17 00:00:00 2001 From: Josh Taillon Date: Mon, 14 Sep 2026 15:00:16 -0600 Subject: [PATCH 26/26] ci: finish the workflow rename, and scope the source rewrite to this repo The workflow file was renamed to py-docs.yaml, which left its own paths filter naming a file that no longer exists, so a change to the workflow stopped triggering it. The job id and concurrency group still said quartodoc, as did comments in three sibling workflows and in the preview script. main has no branch protection, so renaming the job breaks no required check. The source-link rewrite is now scoped to this repository. It matched any GitHub blob URL with a src/ path, so a documentation link into another project's source tree would have gained a pkg-py/ prefix. The repository URL comes from the same config the site URL does. --- .github/scripts/docs-postprocess.py | 30 ++++++---- .github/scripts/test_docs_postprocess.py | 55 ++++++++++++------- .github/workflows/pkgdown.yaml | 2 +- .github/workflows/preview-cleanup.yml | 2 +- .github/workflows/preview-fork-notice.yml | 2 +- .../{quartodoc.yaml => py-docs.yaml} | 14 ++--- scripts/preview-docs.sh | 6 +- 7 files changed, 66 insertions(+), 45 deletions(-) rename .github/workflows/{quartodoc.yaml => py-docs.yaml} (92%) diff --git a/.github/scripts/docs-postprocess.py b/.github/scripts/docs-postprocess.py index e08c3097..9fb28214 100644 --- a/.github/scripts/docs-postprocess.py +++ b/.github/scripts/docs-postprocess.py @@ -20,7 +20,7 @@ Remove the corresponding half of this script if great-docs gains relative icon links, or a way to suppress the badge. -Usage: docs-postprocess.py +Usage: docs-postprocess.py """ from __future__ import annotations @@ -45,11 +45,17 @@ # not the repository root, so they arrive missing the package directory. The # `source.path` config key cannot do this: it replaces the whole path with the # file's basename, which flattens nested modules such as commons/_ui/_server.py. -# The non-greedy middle group is the git ref, which may itself contain slashes. -SOURCE = re.compile(r'(https://github\.com/[^"/]+/[^"/]+/blob/)([^"]+?)(/src/)') +# Scoped to this repository, so a documentation link into another project's +# src/ tree is left alone. The non-greedy group is the git ref, which may +# itself contain slashes. +def source_pattern(repo_url: str) -> re.Pattern[str]: + repo = repo_url.rstrip("/") + return re.compile(re.escape(repo) + r'/blob/([^"]+?)(/src/)') -def fix(text: str, site_url: str, package_root: str, offset: str) -> str | None: +def fix( + text: str, site_url: str, repo_url: str, package_root: str, offset: str +) -> str | None: """Return `text` post-processed, or None when it needs no change. Returns None when the page needs neither, which keeps the caller from @@ -68,23 +74,25 @@ def relativize(match: re.Match[str]) -> str: icons += n return tag + repo = repo_url.rstrip("/") + def relocate(match: re.Match[str]) -> str: - ref = match.group(2) + ref = match.group(1) # Already carries the package directory, so leave it be. if ref == package_root or ref.endswith("/" + package_root): return match.group(0) - return f"{match.group(1)}{ref}/{package_root}{match.group(3)}" + return f"{repo}/blob/{ref}/{package_root}{match.group(2)}" patched = LINK.sub(relativize, text) patched, badges = BADGE.subn("", patched) - patched, sources = SOURCE.subn(relocate, patched) + patched, sources = source_pattern(repo_url).subn(relocate, patched) if not (icons or badges or sources) or patched == text: return None return patched -def main(root: str, site_url: str, package_root: str) -> int: +def main(root: str, site_url: str, repo_url: str, package_root: str) -> int: directory = pathlib.Path(root) if not directory.is_dir(): print(f"{root} is not a directory", file=sys.stderr) @@ -97,7 +105,7 @@ def main(root: str, site_url: str, package_root: str) -> int: # makes this correct inside a versioned copy as well as at the top. found = OFFSET.search(text) offset = found.group(1) if found else "./" - patched = fix(text, site_url, package_root, offset) + patched = fix(text, site_url, repo_url, package_root, offset) if patched is None: skipped += 1 continue @@ -109,7 +117,7 @@ def main(root: str, site_url: str, package_root: str) -> int: if __name__ == "__main__": - if len(sys.argv) != 4: + if len(sys.argv) != 5: print(__doc__, file=sys.stderr) raise SystemExit(2) - raise SystemExit(main(sys.argv[1], sys.argv[2], sys.argv[3])) + raise SystemExit(main(sys.argv[1], sys.argv[2], sys.argv[3], sys.argv[4])) diff --git a/.github/scripts/test_docs_postprocess.py b/.github/scripts/test_docs_postprocess.py index 1686e517..62321f29 100644 --- a/.github/scripts/test_docs_postprocess.py +++ b/.github/scripts/test_docs_postprocess.py @@ -14,13 +14,14 @@ fix = mod.fix BASE = "https://posit-dev.github.io/commons/py/" ROOT = "pkg-py" -BLOB = "https://github.com/posit-dev/commons/blob" +REPO = "https://github.com/posit-dev/commons" +BLOB = REPO + "/blob" class StripVersionBadgeTest(unittest.TestCase): def test_removes_the_badge(self): page = 'commons v0.1.0.dev1' - out = fix(page, BASE, ROOT, "./") + out = fix(page, BASE, REPO, ROOT, "./") assert out is not None self.assertNotIn("version-badge", out) self.assertNotIn("v0.1.0.dev1", out) @@ -29,27 +30,27 @@ def test_removes_the_badge(self): def test_removes_the_badge_with_attributes(self): page = 'v0.1.0.dev1' - out = fix(page, BASE, ROOT, "./") + out = fix(page, BASE, REPO, ROOT, "./") assert out is not None self.assertEqual(out.strip(), "") def test_leaves_a_longer_class_alone(self): # Anchored on the closing quote, so version-badge-legend is not a badge. page = 'v1' - self.assertIsNone(fix(page, BASE, ROOT, "./")) + self.assertIsNone(fix(page, BASE, REPO, ROOT, "./")) class RelativizeIconsTest(unittest.TestCase): def test_rewrites_an_absolute_icon_link_at_the_root(self): page = f'' - out = fix(page, BASE, ROOT, "./") + out = fix(page, BASE, REPO, ROOT, "./") assert out is not None self.assertIn('href="./favicon.ico"', out) self.assertNotIn(BASE, out) def test_rewrites_with_a_nested_offset(self): page = f'' - out = fix(page, BASE, ROOT, "../") + out = fix(page, BASE, REPO, ROOT, "../") assert out is not None self.assertIn('href="../apple-touch-icon.png"', out) @@ -58,14 +59,14 @@ def test_rewrites_every_occurrence(self): f'' f'' ) - out = fix(page, BASE, ROOT, "../") + out = fix(page, BASE, REPO, ROOT, "../") assert out is not None self.assertEqual(out.count("../favicon-"), 2) self.assertNotIn(BASE, out) def test_tolerates_a_base_without_a_trailing_slash(self): page = f'' - out = fix(page, BASE.rstrip("/"), ROOT, "../") + out = fix(page, BASE.rstrip("/"), REPO, ROOT, "../") assert out is not None self.assertIn('href="../favicon.ico"', out) @@ -75,45 +76,45 @@ def test_leaves_the_versioned_canonical_script_alone(self): # Rewriting it to a page-relative prefix would produce a bogus # canonical URL on every non-latest version. page = '' - self.assertIsNone(fix(page, BASE, ROOT, "../")) + self.assertIsNone(fix(page, BASE, REPO, ROOT, "../")) def test_leaves_a_script_using_the_trailing_slash_form_alone(self): # Same risk, one character different: only hrefs are rewritten. page = f'' - self.assertIsNone(fix(page, BASE, ROOT, "../")) + self.assertIsNone(fix(page, BASE, REPO, ROOT, "../")) def test_rewrites_the_link_but_not_a_neighbouring_script(self): page = ( f'' f'' ) - out = fix(page, BASE, ROOT, "../") + out = fix(page, BASE, REPO, ROOT, "../") assert out is not None self.assertIn('href="../favicon.ico"', out) self.assertIn(f'var base="{BASE}";', out) def test_leaves_an_unrelated_absolute_url_alone(self): page = 'PyPI' - self.assertIsNone(fix(page, BASE, ROOT, "../")) + self.assertIsNone(fix(page, BASE, REPO, ROOT, "../")) def test_leaves_a_page_needing_nothing(self): - self.assertIsNone(fix("plain", BASE, ROOT, "./")) + self.assertIsNone(fix("plain", BASE, REPO, ROOT, "./")) def test_is_idempotent(self): page = ( f'' 'v1' ) - once = fix(page, BASE, ROOT, "../") + once = fix(page, BASE, REPO, ROOT, "../") assert once is not None - self.assertIsNone(fix(once, BASE, ROOT, "../")) + self.assertIsNone(fix(once, BASE, REPO, ROOT, "../")) def test_does_both_jobs_in_one_pass(self): page = ( f'' 'v0.1.0.dev1' ) - out = fix(page, BASE, ROOT, "../") + out = fix(page, BASE, REPO, ROOT, "../") assert out is not None self.assertIn('href="../favicon.ico"', out) self.assertNotIn("version-badge", out) @@ -122,7 +123,7 @@ def test_does_both_jobs_in_one_pass(self): class SourceLinkTest(unittest.TestCase): def test_inserts_the_package_root(self): page = f'source' - out = fix(page, BASE, ROOT, "./") + out = fix(page, BASE, REPO, ROOT, "./") assert out is not None self.assertIn(f"{BLOB}/main/pkg-py/src/commons/_agent.py#L58-L368", out) @@ -130,23 +131,35 @@ def test_keeps_a_nested_module_path(self): # source.path would have flattened this to the basename, which is why # the prefix is inserted here instead of configured there. page = f'source' - out = fix(page, BASE, ROOT, "./") + out = fix(page, BASE, REPO, ROOT, "./") assert out is not None self.assertIn(f"{BLOB}/main/pkg-py/src/commons/_ui/_server.py", out) def test_handles_a_ref_containing_slashes(self): page = f'source' - out = fix(page, BASE, ROOT, "./") + out = fix(page, BASE, REPO, ROOT, "./") assert out is not None self.assertIn(f"{BLOB}/jat255/some-branch/pkg-py/src/commons/_agent.py", out) def test_is_idempotent_on_source_links(self): page = f'source' - self.assertIsNone(fix(page, BASE, ROOT, "./")) + self.assertIsNone(fix(page, BASE, REPO, ROOT, "./")) + + def test_leaves_another_repository_alone(self): + # Only this repository's generated links need the package directory; + # a link into someone else's src/ tree must be untouched. + page = 'x' + self.assertIsNone(fix(page, BASE, REPO, ROOT, "./")) + + def test_tolerates_a_repo_url_with_a_trailing_slash(self): + page = f'source' + out = fix(page, BASE, REPO + "/", ROOT, "./") + assert out is not None + self.assertIn("/main/pkg-py/src/commons/_agent.py", out) def test_leaves_a_non_source_repo_link_alone(self): page = f'issue' - self.assertIsNone(fix(page, BASE, ROOT, "./")) + self.assertIsNone(fix(page, BASE, REPO, ROOT, "./")) if __name__ == "__main__": diff --git a/.github/workflows/pkgdown.yaml b/.github/workflows/pkgdown.yaml index c050dbd8..039a5a5e 100644 --- a/.github/workflows/pkgdown.yaml +++ b/.github/workflows/pkgdown.yaml @@ -21,7 +21,7 @@ jobs: run: working-directory: pkg-r # Only restrict concurrency for non-PR jobs: those share gh-pages, and a - # PR build deploys nothing. Races against quartodoc.yaml's deploy are + # PR build deploys nothing. Races against py-docs.yaml's deploy are # handled at the push instead, by the deploy action's rebase. concurrency: group: pkgdown-${{ github.event_name != 'pull_request' || github.run_id }} diff --git a/.github/workflows/preview-cleanup.yml b/.github/workflows/preview-cleanup.yml index 0598b2f3..c724e346 100644 --- a/.github/workflows/preview-cleanup.yml +++ b/.github/workflows/preview-cleanup.yml @@ -1,4 +1,4 @@ -# Removes the pr-/ preview folders that quartodoc.yaml publishes to +# Removes the pr-/ preview folders that py-docs.yaml publishes to # gh-pages. # # Closing a pull request handles the ordinary case immediately. The schedule diff --git a/.github/workflows/preview-fork-notice.yml b/.github/workflows/preview-fork-notice.yml index eabe5a98..45b2f962 100644 --- a/.github/workflows/preview-fork-notice.yml +++ b/.github/workflows/preview-fork-notice.yml @@ -1,6 +1,6 @@ # Tells a fork's author why their pull request has no documentation preview. # -# quartodoc.yaml skips the preview deploy for forks, and a fork's +# py-docs.yaml skips the preview deploy for forks, and a fork's # GITHUB_TOKEN is read-only, so that workflow cannot post this itself. # pull_request_target runs with the base repository's token, which can. This workflow never checks out the pull request, and asks for no # permission beyond writing the comment, so none of what makes diff --git a/.github/workflows/quartodoc.yaml b/.github/workflows/py-docs.yaml similarity index 92% rename from .github/workflows/quartodoc.yaml rename to .github/workflows/py-docs.yaml index a1c2d335..fcae3228 100644 --- a/.github/workflows/quartodoc.yaml +++ b/.github/workflows/py-docs.yaml @@ -4,17 +4,17 @@ on: # paths does not filter a tag push, so a release rebuilds the site # whatever it touched, which is what a release should do. tags: ["py-v*"] - paths: [pkg-py/**, docs/**, .github/scripts/docs-postprocess.py, .github/workflows/quartodoc.yaml] + paths: [pkg-py/**, docs/**, .github/scripts/docs-postprocess.py, .github/workflows/py-docs.yaml] pull_request: - paths: [pkg-py/**, docs/**, .github/scripts/docs-postprocess.py, .github/workflows/quartodoc.yaml] + paths: [pkg-py/**, docs/**, .github/scripts/docs-postprocess.py, .github/workflows/py-docs.yaml] workflow_dispatch: -name: quartodoc.yaml +name: Python documentation build permissions: read-all jobs: - quartodoc: + py-docs: runs-on: ubuntu-latest defaults: run: @@ -26,7 +26,7 @@ jobs: # Races between the two sites are handled at the push instead, by the # deploy action's rebase. concurrency: - group: quartodoc-${{ github.event.number || github.ref }} + group: py-docs-${{ github.event.number || github.ref }} permissions: contents: write pull-requests: write @@ -51,8 +51,8 @@ jobs: - name: Post-process the built site working-directory: pkg-py run: | - site_url="$(uv run python -c 'import yaml; print(yaml.safe_load(open("great-docs.yml"))["site_url"])')" - python3 ../.github/scripts/docs-postprocess.py great-docs/_site "$site_url" pkg-py + read -r site_url repo_url < <(uv run python -c 'import yaml; c = yaml.safe_load(open("great-docs.yml")); print(c["site_url"], c["repo"])') + python3 ../.github/scripts/docs-postprocess.py great-docs/_site "$site_url" "$repo_url" pkg-py # The deploy publishes the whole of docs/, so the rendered site has to # sit at the path it is served from. diff --git a/scripts/preview-docs.sh b/scripts/preview-docs.sh index 94786cdb..a25122f7 100755 --- a/scripts/preview-docs.sh +++ b/scripts/preview-docs.sh @@ -120,13 +120,13 @@ build_py() { return fi echo "==> Building the Python site into docs/py" - # Matches .github/workflows/quartodoc.yaml, including the copy and the + # Matches .github/workflows/py-docs.yaml, including the copy and the # version correction: great-docs renders in place, because quarto warns and # refuses to clean an output directory outside its project. (cd "$root/pkg-py" && uv sync --extra shiny --group docs --quiet) (cd "$root/pkg-py" && uv run great-docs build) - site_url="$(cd "$root/pkg-py" && uv run python -c 'import yaml; print(yaml.safe_load(open("great-docs.yml"))["site_url"])')" - (cd "$root/pkg-py" && uv run python "$root/.github/scripts/docs-postprocess.py" great-docs/_site "$site_url" pkg-py) + read -r site_url repo_url < <(cd "$root/pkg-py" && uv run python -c 'import yaml; c = yaml.safe_load(open("great-docs.yml")); print(c["site_url"], c["repo"])') + (cd "$root/pkg-py" && uv run python "$root/.github/scripts/docs-postprocess.py" great-docs/_site "$site_url" "$repo_url" pkg-py) rm -rf "$root/docs/py" cp -r "$root/pkg-py/great-docs/_site" "$root/docs/py" }