diff --git a/.gitignore b/.gitignore
index 59de4e0..be5b80f 100644
--- a/.gitignore
+++ b/.gitignore
@@ -28,3 +28,12 @@ coverage.xml
# AI Tools
.claude/
+
+# Sphinx
+sphinx/_build/
+sphinx/autoapi/
+
+# Only the page JSON is committed. Everything else Sphinx writes there is not.
+sphinx/json/*
+!sphinx/json/autoapi
+!sphinx/json/index.fjson
diff --git a/poetry.lock b/poetry.lock
index eef710d..6dcbf08 100644
--- a/poetry.lock
+++ b/poetry.lock
@@ -1,4 +1,4 @@
-# This file is automatically @generated by Poetry 2.4.1 and should not be changed by hand.
+# This file is automatically @generated by Poetry 2.3.4 and should not be changed by hand.
[[package]]
name = "ada-url"
@@ -120,6 +120,19 @@ files = [
[package.dependencies]
cffi = "*"
+[[package]]
+name = "alabaster"
+version = "1.0.0"
+description = "A light, configurable Sphinx theme"
+optional = false
+python-versions = ">=3.10"
+groups = ["docs"]
+markers = "python_version >= \"3.10\""
+files = [
+ {file = "alabaster-1.0.0-py3-none-any.whl", hash = "sha256:fc6786402dc3fcb2de3cabd5fe455a2db534b371124f1f21de8731783dec828b"},
+ {file = "alabaster-1.0.0.tar.gz", hash = "sha256:c00dca57bca26fa62a6d7d0a9fcce65f3e026e9bfe33e9c538fd3fbb2144fd9e"},
+]
+
[[package]]
name = "anyio"
version = "4.12.1"
@@ -162,6 +175,22 @@ typing_extensions = {version = ">=4.5", markers = "python_version < \"3.13\""}
[package.extras]
trio = ["trio (>=0.32.0)"]
+[[package]]
+name = "astroid"
+version = "4.3.4"
+description = "An abstract syntax tree for Python with inference support."
+optional = false
+python-versions = ">=3.10.0"
+groups = ["docs"]
+markers = "python_version >= \"3.10\""
+files = [
+ {file = "astroid-4.3.4-py3-none-any.whl", hash = "sha256:2bcd0d02648a443a4b818c952c3550091989daefac3c12d3b83b2289482e0818"},
+ {file = "astroid-4.3.4.tar.gz", hash = "sha256:d515a105722b72098bbe82d430d65e635f742b6cbac3bdfaf8b7c188b87c5e39"},
+]
+
+[package.dependencies]
+typing-extensions = {version = ">=4", markers = "python_version < \"3.11\""}
+
[[package]]
name = "authlib"
version = "1.6.12"
@@ -195,17 +224,34 @@ files = [
cryptography = "*"
joserfc = ">=1.6.0"
+[[package]]
+name = "babel"
+version = "2.18.0"
+description = "Internationalization utilities"
+optional = false
+python-versions = ">=3.8"
+groups = ["docs"]
+markers = "python_version >= \"3.10\""
+files = [
+ {file = "babel-2.18.0-py3-none-any.whl", hash = "sha256:e2b422b277c2b9a9630c1d7903c2a00d0830c409c59ac8cae9081c92f1aeba35"},
+ {file = "babel-2.18.0.tar.gz", hash = "sha256:b80b99a14bd085fcacfa15c9165f651fbb3406e66cc603abf11c5750937c992d"},
+]
+
+[package.extras]
+dev = ["backports.zoneinfo ; python_version < \"3.9\"", "freezegun (>=1.0,<2.0)", "jinja2 (>=3.0)", "pytest (>=6.0)", "pytest-cov", "pytz", "setuptools", "tzdata ; sys_platform == \"win32\""]
+
[[package]]
name = "certifi"
version = "2026.10.23"
description = "Python package for providing Mozilla's CA Bundle."
optional = false
python-versions = ">=3.7"
-groups = ["main", "dev"]
+groups = ["main", "dev", "docs"]
files = [
{file = "certifi-2026.10.23-py3-none-any.whl", hash = "sha256:e9b54de76e530bb6cf0ccd036787103acb58fd42ba930ea8bf948ddbaa2f61d1"},
{file = "certifi-2026.10.23.tar.gz", hash = "sha256:a9895e6e2758b371e0545e321a3a8fd1fcfd9829ada8824a936dfb16aaaf36cd"},
]
+markers = {docs = "python_version >= \"3.10\""}
[[package]]
name = "cffi"
@@ -425,7 +471,7 @@ version = "3.4.9"
description = "The Real First Universal Charset Detector. Open, modern and actively maintained alternative to Chardet."
optional = false
python-versions = ">=3.7"
-groups = ["main"]
+groups = ["main", "docs"]
files = [
{file = "charset_normalizer-3.4.9-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:cd6280cf040f233bd7d3407b743b4b4c74f70e8e1c4199cb112a62c941c0772a"},
{file = "charset_normalizer-3.4.9-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:aa99adc8f081b475a12843953db36831eaf83ec33eb46a90629ca6a5de45a616"},
@@ -521,6 +567,7 @@ files = [
{file = "charset_normalizer-3.4.9-py3-none-any.whl", hash = "sha256:68e5f26a1ad57ded6d1cfb85331d1c1a195314756471d97758c48498bb4dcdf5"},
{file = "charset_normalizer-3.4.9.tar.gz", hash = "sha256:673611bbd43f0810bec0b0f028ddeaaa501190339cac411f347ac76917c3ae7b"},
]
+markers = {docs = "python_version >= \"3.10\""}
[[package]]
name = "colorama"
@@ -528,12 +575,12 @@ version = "0.4.6"
description = "Cross-platform colored terminal text."
optional = false
python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,!=3.6.*,>=2.7"
-groups = ["dev"]
-markers = "sys_platform == \"win32\""
+groups = ["dev", "docs"]
files = [
{file = "colorama-0.4.6-py2.py3-none-any.whl", hash = "sha256:4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6"},
{file = "colorama-0.4.6.tar.gz", hash = "sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44"},
]
+markers = {dev = "sys_platform == \"win32\"", docs = "python_version >= \"3.10\" and sys_platform == \"win32\""}
[[package]]
name = "coverage"
@@ -840,6 +887,19 @@ typing-extensions = {version = ">=4.13.2", markers = "python_full_version < \"3.
[package.extras]
ssh = ["bcrypt (>=3.1.5)"]
+[[package]]
+name = "docutils"
+version = "0.21.2"
+description = "Docutils -- Python Documentation Utilities"
+optional = false
+python-versions = ">=3.9"
+groups = ["docs"]
+markers = "python_version >= \"3.10\""
+files = [
+ {file = "docutils-0.21.2-py3-none-any.whl", hash = "sha256:dafca5b9e384f0e419294eb4d2ff9fa826435bf15f15b7bd45723e8ad76811b2"},
+ {file = "docutils-0.21.2.tar.gz", hash = "sha256:3a6b18732edf182daa3cd12775bbb338cf5691468f91eeeb109deff6ebfa986f"},
+]
+
[[package]]
name = "exceptiongroup"
version = "1.3.1"
@@ -939,15 +999,29 @@ version = "3.18"
description = "Internationalized Domain Names in Applications (IDNA)"
optional = false
python-versions = ">=3.9"
-groups = ["main", "dev"]
+groups = ["main", "dev", "docs"]
files = [
{file = "idna-3.18-py3-none-any.whl", hash = "sha256:7f952cbe720b688055e3f87de14f5c3e5fdaa8bc3928985c4077ca689de849a2"},
{file = "idna-3.18.tar.gz", hash = "sha256:ffb385a7e039654cef1ab9ef32c6fafe283c0c0467bba1d9029738ce4a14a848"},
]
+markers = {docs = "python_version >= \"3.10\""}
[package.extras]
all = ["mypy (>=1.11.2)", "pytest (>=8.3.2)", "ruff (>=0.6.2)"]
+[[package]]
+name = "imagesize"
+version = "2.0.1"
+description = "Get image size from headers (BMP/PNG/JPEG/JPEG2000/GIF/TIFF/SVG/Netpbm/WebP/AVIF/HEIC/HEIF)"
+optional = false
+python-versions = ">=3.10"
+groups = ["docs"]
+markers = "python_version >= \"3.10\""
+files = [
+ {file = "imagesize-2.0.1-py3-none-any.whl", hash = "sha256:ea0c9a0384df69ed86a943a15cde37d0360b82491b3910dc2215e202e62b5b02"},
+ {file = "imagesize-2.0.1.tar.gz", hash = "sha256:b2ba6a4dea487a7ebcd53248d3476aca449d30db12a2dde5e0c5ca9624fd77e5"},
+]
+
[[package]]
name = "iniconfig"
version = "2.1.0"
@@ -974,6 +1048,25 @@ files = [
{file = "iniconfig-2.3.0.tar.gz", hash = "sha256:c76315c77db068650d49c5b56314774a7804df16fee4402c1f19d6d15d8c4730"},
]
+[[package]]
+name = "jinja2"
+version = "3.1.6"
+description = "A very fast and expressive template engine."
+optional = false
+python-versions = ">=3.7"
+groups = ["docs"]
+markers = "python_version >= \"3.10\""
+files = [
+ {file = "jinja2-3.1.6-py3-none-any.whl", hash = "sha256:85ece4451f492d0c13c5dd7c13a64681a86afae63a5f347908daf103ce6d2f67"},
+ {file = "jinja2-3.1.6.tar.gz", hash = "sha256:0137fb05990d35f1275a587e9aee6d56da821fc83491a0fb838183be43f66d6d"},
+]
+
+[package.dependencies]
+MarkupSafe = ">=2.0"
+
+[package.extras]
+i18n = ["Babel (>=2.7)"]
+
[[package]]
name = "joserfc"
version = "1.7.4"
@@ -1009,17 +1102,180 @@ files = [
cryptography = ">=49.0.0"
typing_extensions = ">=4.5.0"
+[[package]]
+name = "markupsafe"
+version = "3.0.4"
+description = "Safely add untrusted strings to HTML/XML markup."
+optional = false
+python-versions = ">=3.9"
+groups = ["docs"]
+markers = "python_version >= \"3.10\""
+files = [
+ {file = "markupsafe-3.0.4-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:dd8ea6ebee7aedbf7c749fa80521d9ccf1ba473e0d1e14805caafbaad281c889"},
+ {file = "markupsafe-3.0.4-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:dff05cb7016dff1e9fd68f4122c127b65dfc59de5306cfb7ad92f956f230bee2"},
+ {file = "markupsafe-3.0.4-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:cf63c214fe879a65e69a386f915e36104fc84254ab141240f8854602d8e0be2a"},
+ {file = "markupsafe-3.0.4-cp310-cp310-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:2a6ef68ae94aed8721934072b27a3b654ea2100b97e4ab864cf1489c90926fbc"},
+ {file = "markupsafe-3.0.4-cp310-cp310-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:fd9f8797427910198f95bced71ddfed61130d7e349213bfb8466c9c99e2c46a8"},
+ {file = "markupsafe-3.0.4-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:d1aca03ede943eb80ab3d63bb082c84b7aab85ea83bd0fd0c200260945fb49d9"},
+ {file = "markupsafe-3.0.4-cp310-cp310-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:0764a13d34cae40db7bbf3a09b7e9b491bf4603e20b263a7a9d6b8e324975d0a"},
+ {file = "markupsafe-3.0.4-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:9388003072b95f2f1e3fd908604194d653ba21330d811961a78b7da1a77e9e36"},
+ {file = "markupsafe-3.0.4-cp310-cp310-musllinux_1_2_armv7l.whl", hash = "sha256:8698d70a8081ee8c090dbb394768b5789a1da8b131b5499f89d071dd3cfaf6be"},
+ {file = "markupsafe-3.0.4-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:bf053da3c97a4bc5ecfbb218cdd2983febd91c617be8367d139882aa11e490aa"},
+ {file = "markupsafe-3.0.4-cp310-cp310-musllinux_1_2_riscv64.whl", hash = "sha256:9438a2648b2195980cb2dd8e53ed7b8df91319e2d0b70ae61a9e1d1bc8d3bec9"},
+ {file = "markupsafe-3.0.4-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:88d59b473bfb03259722600839af9bbd7fa13a2eb514beefeedb95997882f69a"},
+ {file = "markupsafe-3.0.4-cp310-cp310-win32.whl", hash = "sha256:4a540e2d3192792fc84eced57bef37851ccb2b41f73291bb17408eea77bcd278"},
+ {file = "markupsafe-3.0.4-cp310-cp310-win_amd64.whl", hash = "sha256:5c22873ad1f0532ba40fa1727f3c0fc1bbbaab6d373d4cbe3f0dc74b2e2521c7"},
+ {file = "markupsafe-3.0.4-cp310-cp310-win_arm64.whl", hash = "sha256:3d23795802fc8bd72534836d64489bbf0f67c088959091bdb22e10735a5107bf"},
+ {file = "markupsafe-3.0.4-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:9e25feb9e330b63edb0278a0acdf85e50d0cb0fbf49c3084abbe4e24ae195346"},
+ {file = "markupsafe-3.0.4-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:7d3391b2188d18737cb2fa147028b1096236eaa7e156446c650a489fa2cadc91"},
+ {file = "markupsafe-3.0.4-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:849dd2bb0e5e4ab2b71c7191726a4a8d5aa8a610daa584728cbee0b710ddc4ef"},
+ {file = "markupsafe-3.0.4-cp311-cp311-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:befb4158af32106b9a93db8d6d1d1cbbd418c0d5aca0cabb7b1780abf0c89169"},
+ {file = "markupsafe-3.0.4-cp311-cp311-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:71f88e749ea29f67f21f3b36433c1dc54c7729ed2a6d9e2da2e0d9e0d7b224eb"},
+ {file = "markupsafe-3.0.4-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:6da83a088f8ef93b2d483a8232a4dbf4d69d3d8496b568a03c56becac43e1808"},
+ {file = "markupsafe-3.0.4-cp311-cp311-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:8f0fac8b13d14bb06c68195f849371924ae53dd7b1c00fed24650f704383b692"},
+ {file = "markupsafe-3.0.4-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:4a7cdc2a420ca01058182da4253329764d4bfa055564d1eced90e6ba1e8b1d3d"},
+ {file = "markupsafe-3.0.4-cp311-cp311-musllinux_1_2_armv7l.whl", hash = "sha256:83b3944fea42a8400edf92fd1770fb8d0d4f7de651353bd2d8525a92dba69a21"},
+ {file = "markupsafe-3.0.4-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:8138eb83940ec7299024d92d4dee45f601b9e6c5ffde9d25f4e35e326203c707"},
+ {file = "markupsafe-3.0.4-cp311-cp311-musllinux_1_2_riscv64.whl", hash = "sha256:811d02d5122171c1941357efd8f9bf4ffe907b7f0a1a4e729a880e4be3f46e3e"},
+ {file = "markupsafe-3.0.4-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:50b5bedc9ed8a94fc8857a42ef4f84a81ea88f8d4f05dc8705fb23ee6d8dcca7"},
+ {file = "markupsafe-3.0.4-cp311-cp311-win32.whl", hash = "sha256:2e5a7cd7fdd14fcb1ae5d7d8bf23d24fbd1daefd1fbca2580132e1ea75f098b5"},
+ {file = "markupsafe-3.0.4-cp311-cp311-win_amd64.whl", hash = "sha256:fdb4ca07ab75ffadab4a8b135ad59cdbb3156b99310f3d565370da74a15d6bd3"},
+ {file = "markupsafe-3.0.4-cp311-cp311-win_arm64.whl", hash = "sha256:569d65055d367e3dcdf30c3f41119467b73d9ee9faf332bdf40402644f5ac08e"},
+ {file = "markupsafe-3.0.4-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:61631e08084be9e21a8967ec3139c7616ed7c5e9368e05c86d1b39562c8a57b6"},
+ {file = "markupsafe-3.0.4-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:0930db9bdc62d22944e10b066448bb65dc9abe9112880c7cab8da54db4284d5f"},
+ {file = "markupsafe-3.0.4-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:6a45c3d514f2436064db00d7fc8778d888f0236ebfed649b53d13a59e69ad51b"},
+ {file = "markupsafe-3.0.4-cp312-cp312-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:1e1451fab512d1bcc3dc26988ec1edb0b82c2db909132872cd9356070a6b63df"},
+ {file = "markupsafe-3.0.4-cp312-cp312-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:bd3ce56ae2cbae3ba82b683bc425cd7e48d2ed8b10f3e818186b6f5646d9271c"},
+ {file = "markupsafe-3.0.4-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:8e124f974786f831d6043728e38296969d3579db8896fe004682f5758e613581"},
+ {file = "markupsafe-3.0.4-cp312-cp312-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:c02e8f18bdedba082cef725942ac823b9b60656db07f7e265cb31618dfd00d77"},
+ {file = "markupsafe-3.0.4-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:9f098115c247e11d138ab83a28fa0323c77015007ea2df73ba5fd714dfefd67c"},
+ {file = "markupsafe-3.0.4-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:d5f93ebbeb8032d47e349328ec8662d973d9b05a70b3c35df1f91fe419b84749"},
+ {file = "markupsafe-3.0.4-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:64511c54db4e4987aef4c41923235927428729e8174c5dba488429be70a998ed"},
+ {file = "markupsafe-3.0.4-cp312-cp312-musllinux_1_2_riscv64.whl", hash = "sha256:e1a622f13970d81f95d0c72f9dc090dce9085fccfa4c9f2174377ee32bd15786"},
+ {file = "markupsafe-3.0.4-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:c9a7f43c0b202b334cc9184af09bb8f21d3a209e038efaf106936fb69e6b026e"},
+ {file = "markupsafe-3.0.4-cp312-cp312-win32.whl", hash = "sha256:f0ec3b750b59375eab5b0fb2b9254810c00a3375be6d789899f1055a1d556237"},
+ {file = "markupsafe-3.0.4-cp312-cp312-win_amd64.whl", hash = "sha256:11935df9bf455ed0c04eb87bcd720f02b1fe5e02128a9430f23aed6f93336fc7"},
+ {file = "markupsafe-3.0.4-cp312-cp312-win_arm64.whl", hash = "sha256:a4bbd2d87dd233b9fc5812160c3d0ffbe42edc22a26ce0469f58479ede633fe9"},
+ {file = "markupsafe-3.0.4-cp313-cp313-android_24_arm64_v8a.whl", hash = "sha256:de8b364c423ef0a4bad9069657d617f9a5d2b2062457a89b1fa16ee199c399c1"},
+ {file = "markupsafe-3.0.4-cp313-cp313-android_24_x86_64.whl", hash = "sha256:34bdde374c5932765d7dc685c4a1d191a3207852d67e8e0a9eb6ea85156181f1"},
+ {file = "markupsafe-3.0.4-cp313-cp313-ios_13_0_arm64_iphoneos.whl", hash = "sha256:6bd9e1788e15bfcf6a9082de42e30387e7b85d211ab21e57a939bb8cfaaf8d96"},
+ {file = "markupsafe-3.0.4-cp313-cp313-ios_13_0_arm64_iphonesimulator.whl", hash = "sha256:5066b244f576f91afc8ee3ba029a89f99d39c79b1853fe9d39bea9f0afbec148"},
+ {file = "markupsafe-3.0.4-cp313-cp313-ios_13_0_x86_64_iphonesimulator.whl", hash = "sha256:7a83aa6e4805df46fed18e989d3d16f86ef60cb50bbc8d9ce3a6be89165fbf6e"},
+ {file = "markupsafe-3.0.4-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:2d1b7d9308288661f56672b1b157d75fc536714d3638487bbea17b6318a78248"},
+ {file = "markupsafe-3.0.4-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:73e77980c7207854f00fc4e71fb1626868d5740ab4012623d55c7a99ad122a72"},
+ {file = "markupsafe-3.0.4-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:7018d4af1cd272e847aa5917983ab5e83e4f6579f9dbfecd4a79c0ca80b144c2"},
+ {file = "markupsafe-3.0.4-cp313-cp313-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:c90d5b3d4e944e065a301d741b3c1d784f6bd1f503aa68b4967e32b2ba313d85"},
+ {file = "markupsafe-3.0.4-cp313-cp313-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:18a801868a884f216e784d7d14db2a4077143ce7610440aee2ce8f734e7cfcde"},
+ {file = "markupsafe-3.0.4-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:434139499bb20b502ed3baa1f169e618f924a97e7a777fea1a49446d80106cf6"},
+ {file = "markupsafe-3.0.4-cp313-cp313-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:9e227f3dbe6bde7491cf0a9965d00b88c6b1a4a95d11480ddf88bb96d397c19f"},
+ {file = "markupsafe-3.0.4-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:b8cd1f918b26fd7b1832ece557cc18f2d8747309ff8b3f0ef9d4250c5ad67a39"},
+ {file = "markupsafe-3.0.4-cp313-cp313-musllinux_1_2_armv7l.whl", hash = "sha256:a5fcffb37e602b0b3c1638a97746b9b96125caa9bcf6fa41d337a9261de231ee"},
+ {file = "markupsafe-3.0.4-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:5989cb26b2e1efc6a42216a9f6b5ee495ce5ace2e5b352a9af489976b32d1ee2"},
+ {file = "markupsafe-3.0.4-cp313-cp313-musllinux_1_2_riscv64.whl", hash = "sha256:add96447a86d205ab616665d53b2950ee81083757f56e6ea833c8b2917646b46"},
+ {file = "markupsafe-3.0.4-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:2628d3a8cb648ecebb3c5d6b0a1052d400e4d8b7ac0fb786be8d285b50040d17"},
+ {file = "markupsafe-3.0.4-cp313-cp313-win32.whl", hash = "sha256:672d207103e6b16ca098611b0f9efad6bc00afd47c03d6ef62186495ca677dc0"},
+ {file = "markupsafe-3.0.4-cp313-cp313-win_amd64.whl", hash = "sha256:1f1f9477e174582b0a1b583d60b66e1f2cf5d3fe12cee985e4aedf44766600e5"},
+ {file = "markupsafe-3.0.4-cp313-cp313-win_arm64.whl", hash = "sha256:06de8ef6331f6e822c28d577dc8bf43fe398800477c49498f38fc38b67ff33fc"},
+ {file = "markupsafe-3.0.4-cp314-cp314-android_24_arm64_v8a.whl", hash = "sha256:4ed644d75aa94a2baf7ec3a96eaa160ea58c742eb9d27c6506053c5c40fc84ed"},
+ {file = "markupsafe-3.0.4-cp314-cp314-android_24_x86_64.whl", hash = "sha256:6d2a9efe686f9de00d0d1ea32a4a5a86d558a2277501bd78d964214eab625e59"},
+ {file = "markupsafe-3.0.4-cp314-cp314-ios_13_0_arm64_iphoneos.whl", hash = "sha256:8781a792a070cf2bd1b86d3aa943894115faaba6e88122a7bf32d62072742453"},
+ {file = "markupsafe-3.0.4-cp314-cp314-ios_13_0_arm64_iphonesimulator.whl", hash = "sha256:971a3bbb75d97ae4e2e8f7d4834236f86f85f0c85e04ab2e191db1123b04f80b"},
+ {file = "markupsafe-3.0.4-cp314-cp314-ios_13_0_x86_64_iphonesimulator.whl", hash = "sha256:8909c2f1c6dd65e054ac4b573a91c8384d1492281e55d82d159d653f7a13adf6"},
+ {file = "markupsafe-3.0.4-cp314-cp314-macosx_10_15_x86_64.whl", hash = "sha256:4cf3468d5ec187ffffcaca8e61929a37448f215dafc1386a12c750a72fe53634"},
+ {file = "markupsafe-3.0.4-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:52704c5d36eb6dda8866493decd61111fff86244c9b1ad225ca01b9e91e5970f"},
+ {file = "markupsafe-3.0.4-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:1caa2fa5a6184fb233153b35f654e6687bd555476f6170f29d8ee9be1a8b0af9"},
+ {file = "markupsafe-3.0.4-cp314-cp314-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:387d8cd30e69b3f0a72877b9ae717033396404e19095b17fe89753a981fda44f"},
+ {file = "markupsafe-3.0.4-cp314-cp314-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:051417f74bcaaefa316276e0ff723f541616ca51043d070da00249d9bddd3e3c"},
+ {file = "markupsafe-3.0.4-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:a8e9f292fcda89b324f2f5c91d13f1424a153e40fc2756f38ee23b15835ff300"},
+ {file = "markupsafe-3.0.4-cp314-cp314-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:df1ae86ff54725a01fa1a0510b914ca53a161b7050be74f6204e24aded5971d0"},
+ {file = "markupsafe-3.0.4-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:8965520ac587c94a4ac48b729be3d8b8de00af39699b17585dfb599babe77977"},
+ {file = "markupsafe-3.0.4-cp314-cp314-musllinux_1_2_armv7l.whl", hash = "sha256:340cbb1957ba99929cbf19a75626d36ba1ae21d1730b287d1cf7f824a20c4fc7"},
+ {file = "markupsafe-3.0.4-cp314-cp314-musllinux_1_2_ppc64le.whl", hash = "sha256:3a93d9616ddecfb393727a0041a562cf0b15a244e20f2bd25efc7949be4c4f17"},
+ {file = "markupsafe-3.0.4-cp314-cp314-musllinux_1_2_riscv64.whl", hash = "sha256:d2e56fd3b00222722abfb3f5f0759ddbae4b90811b5ad4343c64030ad1bde70c"},
+ {file = "markupsafe-3.0.4-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:0d9c47709875fdb321452056622e930c52afbc07a7d780762fbb8b4d91ce6fa4"},
+ {file = "markupsafe-3.0.4-cp314-cp314-win32.whl", hash = "sha256:38fc55594dab834470b6733dead2ee9e3f657fb0608c769dcafa0ba5ab52f45c"},
+ {file = "markupsafe-3.0.4-cp314-cp314-win_amd64.whl", hash = "sha256:c1bc67752d5f21013cfe430df4062441714eab79f65a6a05e01505957e9c35fe"},
+ {file = "markupsafe-3.0.4-cp314-cp314-win_arm64.whl", hash = "sha256:7e1636da3d8dfc220b6dd10264db5f2b165e4888c4518594898fbe381049af8a"},
+ {file = "markupsafe-3.0.4-cp314-cp314t-macosx_10_15_x86_64.whl", hash = "sha256:805c8b84534fa10891890f0e4be39f3a99e94615d93e8836bf9fa1fdca2feeb2"},
+ {file = "markupsafe-3.0.4-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:fa95848c929b6a75f6848d3c9793e59db365ee436776e57db835cdbfa79ba977"},
+ {file = "markupsafe-3.0.4-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:e916035e3e9930cbdfdd10abf48861340221857f45509565898e012263f7b289"},
+ {file = "markupsafe-3.0.4-cp314-cp314t-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:b4d12837e0203bbace818ff4a7461afdcd78bcd782351cea148139180d7bcffe"},
+ {file = "markupsafe-3.0.4-cp314-cp314t-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:5086f9975abb1ab531ee6afca1761e4b59a19b446f3f6522ed776963228cfe5a"},
+ {file = "markupsafe-3.0.4-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:b4a635a0487774f841cb1fb62e907e7195cc95bc761e053184b8acc3ceb20733"},
+ {file = "markupsafe-3.0.4-cp314-cp314t-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:cb96e6e088d6cf71c1ea977510948320234824cf226e32f6f6e044f7a9c82b34"},
+ {file = "markupsafe-3.0.4-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:8b5d563170ff8ba3181caa967c99a3c804d1dedb702c7cb93a6a7c32247da978"},
+ {file = "markupsafe-3.0.4-cp314-cp314t-musllinux_1_2_armv7l.whl", hash = "sha256:396ec4e65cc889f69786b3b89478b471cee5a3bcf468b9d9bb03e1a30fb291fc"},
+ {file = "markupsafe-3.0.4-cp314-cp314t-musllinux_1_2_ppc64le.whl", hash = "sha256:15ba9e28640feef770374b116a6f019c21f52404aeabe516aa7f800587b98cfc"},
+ {file = "markupsafe-3.0.4-cp314-cp314t-musllinux_1_2_riscv64.whl", hash = "sha256:d920abdfa61279ba1a2ef9484aab07bf03331f8c08a10120fa332353d06e6932"},
+ {file = "markupsafe-3.0.4-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:a9f54054101545a9a9cccefddf54316aa6e4491611fcbef9e91b3b6bebec04f6"},
+ {file = "markupsafe-3.0.4-cp314-cp314t-win32.whl", hash = "sha256:12a606a492de952afcb43b59a14aaaaad120e708d3663dd0fdf2d738d427a691"},
+ {file = "markupsafe-3.0.4-cp314-cp314t-win_amd64.whl", hash = "sha256:a18f38cafc329bac5e3c2b96c765b4c96d3d103421ed22ab7988c1e3fce27464"},
+ {file = "markupsafe-3.0.4-cp314-cp314t-win_arm64.whl", hash = "sha256:eba154571c16e032112afac0dc2dfe9e63c2ceb7aedd07bb7eecf2ce26d4dd4c"},
+ {file = "markupsafe-3.0.4-cp315-cp315-android_24_arm64_v8a.whl", hash = "sha256:737c9c3981998eba27f11786f84fddcbabc74068b72a4a1f454ea02094b57b65"},
+ {file = "markupsafe-3.0.4-cp315-cp315-android_24_x86_64.whl", hash = "sha256:489505b03f692c3f376394e49194fa7a7f9e8558d6e293a7056a0032b0c38163"},
+ {file = "markupsafe-3.0.4-cp315-cp315-ios_13_0_arm64_iphoneos.whl", hash = "sha256:077293e425f28ec737dbcad442a71752e28f8ae27cde3d68acd1fb212091cd92"},
+ {file = "markupsafe-3.0.4-cp315-cp315-ios_13_0_arm64_iphonesimulator.whl", hash = "sha256:9348cbb300d224fe3b89793262cb093504d4ae927004468463f745188a193e4a"},
+ {file = "markupsafe-3.0.4-cp315-cp315-ios_13_0_x86_64_iphonesimulator.whl", hash = "sha256:b807e598953730f82e4eae3bd30f6a122cf6b31c398c6b504c0e04c13c170429"},
+ {file = "markupsafe-3.0.4-cp315-cp315-macosx_10_15_x86_64.whl", hash = "sha256:799c39bdf5e2f1292fedd3009f7b3c9e760f10b2420cb9638d56920840ff6db8"},
+ {file = "markupsafe-3.0.4-cp315-cp315-macosx_11_0_arm64.whl", hash = "sha256:ae9dcb8fbe244cb82f8a6458b455b927a03685e383d9bacf1ea5ce180b96dc97"},
+ {file = "markupsafe-3.0.4-cp315-cp315-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:4bced6e2a6dba6a28f7dd3c6ce14df1b2dd495923f16ea484cad03decd463b2b"},
+ {file = "markupsafe-3.0.4-cp315-cp315-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:3882fb412298575bae3b9c46868251f15cc69307359f87bb1b382e53d6e5a2c9"},
+ {file = "markupsafe-3.0.4-cp315-cp315-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:04e7902ba80ee4bac1d50a549606527a1dcf0476cd81403db41099d3b60ec653"},
+ {file = "markupsafe-3.0.4-cp315-cp315-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:925f929d6b59a8b3f8b8c6ac363cd0af7eecc81efb3071770b3c6717c450a369"},
+ {file = "markupsafe-3.0.4-cp315-cp315-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:f68edfc67aabac33708941f26f22a7b8e9f81429bc0cf249fcf7d66b23af8d19"},
+ {file = "markupsafe-3.0.4-cp315-cp315-musllinux_1_2_aarch64.whl", hash = "sha256:e5c802729725bd07e2bc3ab7b76dc7e0bbfc53129d8f1eb1c002c24cf774717e"},
+ {file = "markupsafe-3.0.4-cp315-cp315-musllinux_1_2_armv7l.whl", hash = "sha256:55ffd6ce583d97dc71dc92e930324c8c0d25aea7e3ade6ae54ef77cedb096811"},
+ {file = "markupsafe-3.0.4-cp315-cp315-musllinux_1_2_ppc64le.whl", hash = "sha256:2cb3dd71fc6be918ad4264346a8ed69485f9b7ed7bf35495d8e22807cd6b8bea"},
+ {file = "markupsafe-3.0.4-cp315-cp315-musllinux_1_2_riscv64.whl", hash = "sha256:94f5407f7bc64fa6463906b896f9904beeeb7dd8dc116ee8e9056c8714ff9916"},
+ {file = "markupsafe-3.0.4-cp315-cp315-musllinux_1_2_x86_64.whl", hash = "sha256:2dad610540cb2e6272855c178f08ae9a1c7ac258a7fb71660553a5f104b42741"},
+ {file = "markupsafe-3.0.4-cp315-cp315-win32.whl", hash = "sha256:03470d1a8268e692ecf79ecd565593e59d44219377a7ead61f1f1b94c1f7ff6b"},
+ {file = "markupsafe-3.0.4-cp315-cp315-win_amd64.whl", hash = "sha256:d882a373d8093c2941e01291b7ced96e9cbe4781da9a7751ca7e6c70385e5214"},
+ {file = "markupsafe-3.0.4-cp315-cp315-win_arm64.whl", hash = "sha256:353bd63081912ab8cfa6a0c7d185934cdf8426f04c618bba6bc4b394f2069b67"},
+ {file = "markupsafe-3.0.4-cp315-cp315t-macosx_10_15_x86_64.whl", hash = "sha256:c61750fadcd119d0825bcb7d7d675dd264dcc89cc05292aab5be68ebdbb374ad"},
+ {file = "markupsafe-3.0.4-cp315-cp315t-macosx_11_0_arm64.whl", hash = "sha256:1c0df495a977d10460a94941799c72d5b5ab03d3858d949b55b5a66c8f371c99"},
+ {file = "markupsafe-3.0.4-cp315-cp315t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:02fa4acbc6a3fc5c693c34d4dd8c1130b7fe99cc915181b0ddd6f72aeb296002"},
+ {file = "markupsafe-3.0.4-cp315-cp315t-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:05295589e619b9bed252a86b532b8e27350abc372d18ba89b59375325e91ec1e"},
+ {file = "markupsafe-3.0.4-cp315-cp315t-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:be6cb0c799abb0e2ba3e618e6d28ddddf7e485f6c2ce938dfa237daf3905072c"},
+ {file = "markupsafe-3.0.4-cp315-cp315t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:26e9867520db70d37f7fb421a7f0d8adb40171011fb84ce869afa1a83370dfa8"},
+ {file = "markupsafe-3.0.4-cp315-cp315t-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:f03460ff076f70ab595bb45a0205ccea1971443575b6920c52e755dec2b3fbfe"},
+ {file = "markupsafe-3.0.4-cp315-cp315t-musllinux_1_2_aarch64.whl", hash = "sha256:436e3ffc6310d3c41878c601db29098102fe5d8a467c49da4a4125254e0980f2"},
+ {file = "markupsafe-3.0.4-cp315-cp315t-musllinux_1_2_armv7l.whl", hash = "sha256:4e2c4809c14559aa7ef426f27fb35afbb38104c349a903bf8f3600456764bb38"},
+ {file = "markupsafe-3.0.4-cp315-cp315t-musllinux_1_2_ppc64le.whl", hash = "sha256:da2af0d7aebfc2074080d72efa6ab8317c62481ef1f896f65d9999c1c01f4494"},
+ {file = "markupsafe-3.0.4-cp315-cp315t-musllinux_1_2_riscv64.whl", hash = "sha256:aa2c838cc024642cc04c6854232f32b43e5e22833dd11119c1766c7873b8370d"},
+ {file = "markupsafe-3.0.4-cp315-cp315t-musllinux_1_2_x86_64.whl", hash = "sha256:b91cc9d336957239ff200f30097e6fea2dc6d6fb3c81e853eaa09eac904fd894"},
+ {file = "markupsafe-3.0.4-cp315-cp315t-win32.whl", hash = "sha256:e49fb0d1ce92cfa0cb198cc5b1b11cdf9d0638658e2a2db2687e39db7c87fc78"},
+ {file = "markupsafe-3.0.4-cp315-cp315t-win_amd64.whl", hash = "sha256:4f6e0852a0283b1b1fd776eeb7b766a5f440b3e2bd31ab51af3b400585f3965c"},
+ {file = "markupsafe-3.0.4-cp315-cp315t-win_arm64.whl", hash = "sha256:39dbacefc411633db5b4378b066a9aca70a3d7e2922c9e578d825f844026eeba"},
+ {file = "markupsafe-3.0.4-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:f291bcf42ae98eb5107edb162c3c998b4a89648fd8e99ed4cbd12705292788cd"},
+ {file = "markupsafe-3.0.4-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:ac0c7c9f1609b0c4c114feb1d7a3409564c7fb77e360bed9e97e5d25dfeaf868"},
+ {file = "markupsafe-3.0.4-cp39-cp39-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:6768d67d1bce64270e0fdc2e69309d68b9b18ae56ddf6c711d168e9d051c2cac"},
+ {file = "markupsafe-3.0.4-cp39-cp39-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:14bd2d845d62ab678eaf81da89d7b621b51756c72346745c1a594c09d49207a2"},
+ {file = "markupsafe-3.0.4-cp39-cp39-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:007e1ffd9bf65bb6ee96df7b258fc632a4868dd5566037986c64781f35a36e98"},
+ {file = "markupsafe-3.0.4-cp39-cp39-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:5e8b3d0b18fd623afa12ecb2ce8d8becef69f9b5440c6330c7972200e0bb84b0"},
+ {file = "markupsafe-3.0.4-cp39-cp39-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:57f9947a7e57a081c1e3e0a2dd0d2dcf290a4531450e6f611e30084c222a7295"},
+ {file = "markupsafe-3.0.4-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:b61687d0828e72bf5cda24a2690188f37170bd31c9359ac97e4e66569f120a16"},
+ {file = "markupsafe-3.0.4-cp39-cp39-musllinux_1_2_armv7l.whl", hash = "sha256:0cee7cb0f9a1b6892ea482237d9403b3d1b4603aee057d0ff01f0fac2d019a97"},
+ {file = "markupsafe-3.0.4-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:94e4c421742086aeee4c32a506eec8859d7634aad943f7e6aacf70f813478768"},
+ {file = "markupsafe-3.0.4-cp39-cp39-musllinux_1_2_riscv64.whl", hash = "sha256:9240187afb63d2f9ddc3e032c670356fe941f6e20662ea168a5dc3f1f317e1b3"},
+ {file = "markupsafe-3.0.4-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:e841068dc0be4cb6dfb5c890eb88cbdcff2f4a332393c7ec94e8e618bd32c1a8"},
+ {file = "markupsafe-3.0.4-cp39-cp39-win32.whl", hash = "sha256:f61efe1d2fe0de16158a5fe1d1cf3c14bdb6aecd54d8938fd26512c525c1f624"},
+ {file = "markupsafe-3.0.4-cp39-cp39-win_amd64.whl", hash = "sha256:2b2b1e18af909b448bb3cf9e3433366f7a8726271fc214e8b10e0f62a78c724b"},
+ {file = "markupsafe-3.0.4-cp39-cp39-win_arm64.whl", hash = "sha256:6669c1bf34080161ce49c589cc512ef24d4c704ac9d2b2d3667f519c60418378"},
+ {file = "markupsafe-3.0.4.tar.gz", hash = "sha256:2e9ad7dd851bf45fab9f75cbff4cb493fee9979e8d8c7c9c3ee119022518edd6"},
+]
+
[[package]]
name = "packaging"
version = "26.2"
description = "Core utilities for Python packages"
optional = false
python-versions = ">=3.8"
-groups = ["dev"]
+groups = ["dev", "docs"]
files = [
{file = "packaging-26.2-py3-none-any.whl", hash = "sha256:5fc45236b9446107ff2415ce77c807cee2862cb6fac22b8a73826d0693b0980e"},
{file = "packaging-26.2.tar.gz", hash = "sha256:ff452ff5a3e828ce110190feff1178bb1f2ea2281fa2075aadb987c2fb221661"},
]
+markers = {docs = "python_version >= \"3.10\""}
[[package]]
name = "pluggy"
@@ -1069,11 +1325,12 @@ version = "2.20.0"
description = "Pygments is a syntax highlighting package written in Python."
optional = false
python-versions = ">=3.9"
-groups = ["dev"]
+groups = ["dev", "docs"]
files = [
{file = "pygments-2.20.0-py3-none-any.whl", hash = "sha256:81a9e26dd42fd28a23a2d169d86d7ac03b46e2f8b59ed4698fb4785f946d0176"},
{file = "pygments-2.20.0.tar.gz", hash = "sha256:6757cd03768053ff99f3039c1a36d6c0aa0b263438fcab17520b30a303a82b5f"},
]
+markers = {docs = "python_version >= \"3.10\""}
[package.extras]
windows-terminal = ["colorama (>=0.4.6)"]
@@ -1192,6 +1449,90 @@ files = [
[package.dependencies]
six = ">=1.5"
+[[package]]
+name = "pyyaml"
+version = "6.0.3"
+description = "YAML parser and emitter for Python"
+optional = false
+python-versions = ">=3.8"
+groups = ["docs"]
+markers = "python_version >= \"3.10\""
+files = [
+ {file = "PyYAML-6.0.3-cp38-cp38-macosx_10_13_x86_64.whl", hash = "sha256:c2514fceb77bc5e7a2f7adfaa1feb2fb311607c9cb518dbc378688ec73d8292f"},
+ {file = "PyYAML-6.0.3-cp38-cp38-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:9c57bb8c96f6d1808c030b1687b9b5fb476abaa47f0db9c0101f5e9f394e97f4"},
+ {file = "PyYAML-6.0.3-cp38-cp38-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:efd7b85f94a6f21e4932043973a7ba2613b059c4a000551892ac9f1d11f5baf3"},
+ {file = "PyYAML-6.0.3-cp38-cp38-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:22ba7cfcad58ef3ecddc7ed1db3409af68d023b7f940da23c6c2a1890976eda6"},
+ {file = "PyYAML-6.0.3-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:6344df0d5755a2c9a276d4473ae6b90647e216ab4757f8426893b5dd2ac3f369"},
+ {file = "PyYAML-6.0.3-cp38-cp38-win32.whl", hash = "sha256:3ff07ec89bae51176c0549bc4c63aa6202991da2d9a6129d7aef7f1407d3f295"},
+ {file = "PyYAML-6.0.3-cp38-cp38-win_amd64.whl", hash = "sha256:5cf4e27da7e3fbed4d6c3d8e797387aaad68102272f8f9752883bc32d61cb87b"},
+ {file = "pyyaml-6.0.3-cp310-cp310-macosx_10_13_x86_64.whl", hash = "sha256:214ed4befebe12df36bcc8bc2b64b396ca31be9304b8f59e25c11cf94a4c033b"},
+ {file = "pyyaml-6.0.3-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:02ea2dfa234451bbb8772601d7b8e426c2bfa197136796224e50e35a78777956"},
+ {file = "pyyaml-6.0.3-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:b30236e45cf30d2b8e7b3e85881719e98507abed1011bf463a8fa23e9c3e98a8"},
+ {file = "pyyaml-6.0.3-cp310-cp310-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:66291b10affd76d76f54fad28e22e51719ef9ba22b29e1d7d03d6777a9174198"},
+ {file = "pyyaml-6.0.3-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:9c7708761fccb9397fe64bbc0395abcae8c4bf7b0eac081e12b809bf47700d0b"},
+ {file = "pyyaml-6.0.3-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:418cf3f2111bc80e0933b2cd8cd04f286338bb88bdc7bc8e6dd775ebde60b5e0"},
+ {file = "pyyaml-6.0.3-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:5e0b74767e5f8c593e8c9b5912019159ed0533c70051e9cce3e8b6aa699fcd69"},
+ {file = "pyyaml-6.0.3-cp310-cp310-win32.whl", hash = "sha256:28c8d926f98f432f88adc23edf2e6d4921ac26fb084b028c733d01868d19007e"},
+ {file = "pyyaml-6.0.3-cp310-cp310-win_amd64.whl", hash = "sha256:bdb2c67c6c1390b63c6ff89f210c8fd09d9a1217a465701eac7316313c915e4c"},
+ {file = "pyyaml-6.0.3-cp311-cp311-macosx_10_13_x86_64.whl", hash = "sha256:44edc647873928551a01e7a563d7452ccdebee747728c1080d881d68af7b997e"},
+ {file = "pyyaml-6.0.3-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:652cb6edd41e718550aad172851962662ff2681490a8a711af6a4d288dd96824"},
+ {file = "pyyaml-6.0.3-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:10892704fc220243f5305762e276552a0395f7beb4dbf9b14ec8fd43b57f126c"},
+ {file = "pyyaml-6.0.3-cp311-cp311-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:850774a7879607d3a6f50d36d04f00ee69e7fc816450e5f7e58d7f17f1ae5c00"},
+ {file = "pyyaml-6.0.3-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:b8bb0864c5a28024fac8a632c443c87c5aa6f215c0b126c449ae1a150412f31d"},
+ {file = "pyyaml-6.0.3-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:1d37d57ad971609cf3c53ba6a7e365e40660e3be0e5175fa9f2365a379d6095a"},
+ {file = "pyyaml-6.0.3-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:37503bfbfc9d2c40b344d06b2199cf0e96e97957ab1c1b546fd4f87e53e5d3e4"},
+ {file = "pyyaml-6.0.3-cp311-cp311-win32.whl", hash = "sha256:8098f252adfa6c80ab48096053f512f2321f0b998f98150cea9bd23d83e1467b"},
+ {file = "pyyaml-6.0.3-cp311-cp311-win_amd64.whl", hash = "sha256:9f3bfb4965eb874431221a3ff3fdcddc7e74e3b07799e0e84ca4a0f867d449bf"},
+ {file = "pyyaml-6.0.3-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:7f047e29dcae44602496db43be01ad42fc6f1cc0d8cd6c83d342306c32270196"},
+ {file = "pyyaml-6.0.3-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:fc09d0aa354569bc501d4e787133afc08552722d3ab34836a80547331bb5d4a0"},
+ {file = "pyyaml-6.0.3-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:9149cad251584d5fb4981be1ecde53a1ca46c891a79788c0df828d2f166bda28"},
+ {file = "pyyaml-6.0.3-cp312-cp312-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:5fdec68f91a0c6739b380c83b951e2c72ac0197ace422360e6d5a959d8d97b2c"},
+ {file = "pyyaml-6.0.3-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:ba1cc08a7ccde2d2ec775841541641e4548226580ab850948cbfda66a1befcdc"},
+ {file = "pyyaml-6.0.3-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:8dc52c23056b9ddd46818a57b78404882310fb473d63f17b07d5c40421e47f8e"},
+ {file = "pyyaml-6.0.3-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:41715c910c881bc081f1e8872880d3c650acf13dfa8214bad49ed4cede7c34ea"},
+ {file = "pyyaml-6.0.3-cp312-cp312-win32.whl", hash = "sha256:96b533f0e99f6579b3d4d4995707cf36df9100d67e0c8303a0c55b27b5f99bc5"},
+ {file = "pyyaml-6.0.3-cp312-cp312-win_amd64.whl", hash = "sha256:5fcd34e47f6e0b794d17de1b4ff496c00986e1c83f7ab2fb8fcfe9616ff7477b"},
+ {file = "pyyaml-6.0.3-cp312-cp312-win_arm64.whl", hash = "sha256:64386e5e707d03a7e172c0701abfb7e10f0fb753ee1d773128192742712a98fd"},
+ {file = "pyyaml-6.0.3-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:8da9669d359f02c0b91ccc01cac4a67f16afec0dac22c2ad09f46bee0697eba8"},
+ {file = "pyyaml-6.0.3-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:2283a07e2c21a2aa78d9c4442724ec1eb15f5e42a723b99cb3d822d48f5f7ad1"},
+ {file = "pyyaml-6.0.3-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:ee2922902c45ae8ccada2c5b501ab86c36525b883eff4255313a253a3160861c"},
+ {file = "pyyaml-6.0.3-cp313-cp313-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:a33284e20b78bd4a18c8c2282d549d10bc8408a2a7ff57653c0cf0b9be0afce5"},
+ {file = "pyyaml-6.0.3-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:0f29edc409a6392443abf94b9cf89ce99889a1dd5376d94316ae5145dfedd5d6"},
+ {file = "pyyaml-6.0.3-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:f7057c9a337546edc7973c0d3ba84ddcdf0daa14533c2065749c9075001090e6"},
+ {file = "pyyaml-6.0.3-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:eda16858a3cab07b80edaf74336ece1f986ba330fdb8ee0d6c0d68fe82bc96be"},
+ {file = "pyyaml-6.0.3-cp313-cp313-win32.whl", hash = "sha256:d0eae10f8159e8fdad514efdc92d74fd8d682c933a6dd088030f3834bc8e6b26"},
+ {file = "pyyaml-6.0.3-cp313-cp313-win_amd64.whl", hash = "sha256:79005a0d97d5ddabfeeea4cf676af11e647e41d81c9a7722a193022accdb6b7c"},
+ {file = "pyyaml-6.0.3-cp313-cp313-win_arm64.whl", hash = "sha256:5498cd1645aa724a7c71c8f378eb29ebe23da2fc0d7a08071d89469bf1d2defb"},
+ {file = "pyyaml-6.0.3-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:8d1fab6bb153a416f9aeb4b8763bc0f22a5586065f86f7664fc23339fc1c1fac"},
+ {file = "pyyaml-6.0.3-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:34d5fcd24b8445fadc33f9cf348c1047101756fd760b4dacb5c3e99755703310"},
+ {file = "pyyaml-6.0.3-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:501a031947e3a9025ed4405a168e6ef5ae3126c59f90ce0cd6f2bfc477be31b7"},
+ {file = "pyyaml-6.0.3-cp314-cp314-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:b3bc83488de33889877a0f2543ade9f70c67d66d9ebb4ac959502e12de895788"},
+ {file = "pyyaml-6.0.3-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:c458b6d084f9b935061bc36216e8a69a7e293a2f1e68bf956dcd9e6cbcd143f5"},
+ {file = "pyyaml-6.0.3-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:7c6610def4f163542a622a73fb39f534f8c101d690126992300bf3207eab9764"},
+ {file = "pyyaml-6.0.3-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:5190d403f121660ce8d1d2c1bb2ef1bd05b5f68533fc5c2ea899bd15f4399b35"},
+ {file = "pyyaml-6.0.3-cp314-cp314-win_amd64.whl", hash = "sha256:4a2e8cebe2ff6ab7d1050ecd59c25d4c8bd7e6f400f5f82b96557ac0abafd0ac"},
+ {file = "pyyaml-6.0.3-cp314-cp314-win_arm64.whl", hash = "sha256:93dda82c9c22deb0a405ea4dc5f2d0cda384168e466364dec6255b293923b2f3"},
+ {file = "pyyaml-6.0.3-cp314-cp314t-macosx_10_13_x86_64.whl", hash = "sha256:02893d100e99e03eda1c8fd5c441d8c60103fd175728e23e431db1b589cf5ab3"},
+ {file = "pyyaml-6.0.3-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:c1ff362665ae507275af2853520967820d9124984e0f7466736aea23d8611fba"},
+ {file = "pyyaml-6.0.3-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:6adc77889b628398debc7b65c073bcb99c4a0237b248cacaf3fe8a557563ef6c"},
+ {file = "pyyaml-6.0.3-cp314-cp314t-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:a80cb027f6b349846a3bf6d73b5e95e782175e52f22108cfa17876aaeff93702"},
+ {file = "pyyaml-6.0.3-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:00c4bdeba853cc34e7dd471f16b4114f4162dc03e6b7afcc2128711f0eca823c"},
+ {file = "pyyaml-6.0.3-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:66e1674c3ef6f541c35191caae2d429b967b99e02040f5ba928632d9a7f0f065"},
+ {file = "pyyaml-6.0.3-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:16249ee61e95f858e83976573de0f5b2893b3677ba71c9dd36b9cf8be9ac6d65"},
+ {file = "pyyaml-6.0.3-cp314-cp314t-win_amd64.whl", hash = "sha256:4ad1906908f2f5ae4e5a8ddfce73c320c2a1429ec52eafd27138b7f1cbe341c9"},
+ {file = "pyyaml-6.0.3-cp314-cp314t-win_arm64.whl", hash = "sha256:ebc55a14a21cb14062aa4162f906cd962b28e2e9ea38f9b4391244cd8de4ae0b"},
+ {file = "pyyaml-6.0.3-cp39-cp39-macosx_10_13_x86_64.whl", hash = "sha256:b865addae83924361678b652338317d1bd7e79b1f4596f96b96c77a5a34b34da"},
+ {file = "pyyaml-6.0.3-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:c3355370a2c156cffb25e876646f149d5d68f5e0a3ce86a5084dd0b64a994917"},
+ {file = "pyyaml-6.0.3-cp39-cp39-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:3c5677e12444c15717b902a5798264fa7909e41153cdf9ef7ad571b704a63dd9"},
+ {file = "pyyaml-6.0.3-cp39-cp39-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:5ed875a24292240029e4483f9d4a4b8a1ae08843b9c54f43fcc11e404532a8a5"},
+ {file = "pyyaml-6.0.3-cp39-cp39-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:0150219816b6a1fa26fb4699fb7daa9caf09eb1999f3b70fb6e786805e80375a"},
+ {file = "pyyaml-6.0.3-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:fa160448684b4e94d80416c0fa4aac48967a969efe22931448d853ada8baf926"},
+ {file = "pyyaml-6.0.3-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:27c0abcb4a5dac13684a37f76e701e054692a9b2d3064b70f5e4eb54810553d7"},
+ {file = "pyyaml-6.0.3-cp39-cp39-win32.whl", hash = "sha256:1ebe39cb5fc479422b83de611d14e2c0d3bb2a18bbcb01f229ab3cfbd8fee7a0"},
+ {file = "pyyaml-6.0.3-cp39-cp39-win_amd64.whl", hash = "sha256:2e71d11abed7344e42a8849600193d15b6def118602c4c176f748e4583246007"},
+ {file = "pyyaml-6.0.3.tar.gz", hash = "sha256:d76623373421df22fb4cf8817020cbb7ef15c725b9d5e45f17e189bfc384190f"},
+]
+
[[package]]
name = "requests"
version = "2.32.5"
@@ -1221,7 +1562,7 @@ version = "2.34.2"
description = "Python HTTP for Humans."
optional = false
python-versions = ">=3.10"
-groups = ["main"]
+groups = ["main", "docs"]
markers = "python_version >= \"3.10\""
files = [
{file = "requests-2.34.2-py3-none-any.whl", hash = "sha256:2a0d60c172f83ac6ab31e4554906c0f3b3588d37b5cb939b1c061f4907e278e0"},
@@ -1278,14 +1619,190 @@ files = [
{file = "six-1.17.0.tar.gz", hash = "sha256:ff70335d468e7eb6ec65b95b99d3a2836546063f63acc5171de367e834932a81"},
]
+[[package]]
+name = "snowballstemmer"
+version = "3.1.1"
+description = "This package provides 36 stemmers for 34 languages generated from Snowball algorithms."
+optional = false
+python-versions = ">=3.3"
+groups = ["docs"]
+markers = "python_version >= \"3.10\""
+files = [
+ {file = "snowballstemmer-3.1.1-py3-none-any.whl", hash = "sha256:7e207fa178741da09cdee59d3ecec3827ad5f92b1fc5c9ff3755b639f71f5752"},
+ {file = "snowballstemmer-3.1.1.tar.gz", hash = "sha256:e07bbc54a0d798fe6010a12398422e62a8bfbba95c394fd0956ef58cb4d3e260"},
+]
+
+[[package]]
+name = "sphinx"
+version = "8.1.3"
+description = "Python documentation generator"
+optional = false
+python-versions = ">=3.10"
+groups = ["docs"]
+markers = "python_version >= \"3.10\""
+files = [
+ {file = "sphinx-8.1.3-py3-none-any.whl", hash = "sha256:09719015511837b76bf6e03e42eb7595ac8c2e41eeb9c29c5b755c6b677992a2"},
+ {file = "sphinx-8.1.3.tar.gz", hash = "sha256:43c1911eecb0d3e161ad78611bc905d1ad0e523e4ddc202a58a821773dc4c927"},
+]
+
+[package.dependencies]
+alabaster = ">=0.7.14"
+babel = ">=2.13"
+colorama = {version = ">=0.4.6", markers = "sys_platform == \"win32\""}
+docutils = ">=0.20,<0.22"
+imagesize = ">=1.3"
+Jinja2 = ">=3.1"
+packaging = ">=23.0"
+Pygments = ">=2.17"
+requests = ">=2.30.0"
+snowballstemmer = ">=2.2"
+sphinxcontrib-applehelp = ">=1.0.7"
+sphinxcontrib-devhelp = ">=1.0.6"
+sphinxcontrib-htmlhelp = ">=2.0.6"
+sphinxcontrib-jsmath = ">=1.0.1"
+sphinxcontrib-qthelp = ">=1.0.6"
+sphinxcontrib-serializinghtml = ">=1.1.9"
+tomli = {version = ">=2", markers = "python_version < \"3.11\""}
+
+[package.extras]
+docs = ["sphinxcontrib-websupport"]
+lint = ["flake8 (>=6.0)", "mypy (==1.11.1)", "pyright (==1.1.384)", "pytest (>=6.0)", "ruff (==0.6.9)", "sphinx-lint (>=0.9)", "tomli (>=2)", "types-Pillow (==10.2.0.20240822)", "types-Pygments (==2.18.0.20240506)", "types-colorama (==0.4.15.20240311)", "types-defusedxml (==0.7.0.20240218)", "types-docutils (==0.21.0.20241005)", "types-requests (==2.32.0.20240914)", "types-urllib3 (==1.26.25.14)"]
+test = ["cython (>=3.0)", "defusedxml (>=0.7.1)", "pytest (>=8.0)", "setuptools (>=70.0)", "typing_extensions (>=4.9)"]
+
+[[package]]
+name = "sphinx-autoapi"
+version = "3.8.1"
+description = "Sphinx API documentation generator"
+optional = false
+python-versions = ">=3.10"
+groups = ["docs"]
+markers = "python_version >= \"3.10\""
+files = [
+ {file = "sphinx_autoapi-3.8.1-py3-none-any.whl", hash = "sha256:9a3bd3ee1ba82d537f1620a3922292d43ee8b9ff9c69bc198965ac4bcd5a6775"},
+ {file = "sphinx_autoapi-3.8.1.tar.gz", hash = "sha256:04643fc50485039294ace8b660d0d1b821a1686824a975725a5106e8cf1fb30b"},
+]
+
+[package.dependencies]
+astroid = ">=3.0"
+Jinja2 = "*"
+PyYAML = "*"
+sphinx = ">=7.4.0"
+
+[[package]]
+name = "sphinxcontrib-applehelp"
+version = "2.0.0"
+description = "sphinxcontrib-applehelp is a Sphinx extension which outputs Apple help books"
+optional = false
+python-versions = ">=3.9"
+groups = ["docs"]
+markers = "python_version >= \"3.10\""
+files = [
+ {file = "sphinxcontrib_applehelp-2.0.0-py3-none-any.whl", hash = "sha256:4cd3f0ec4ac5dd9c17ec65e9ab272c9b867ea77425228e68ecf08d6b28ddbdb5"},
+ {file = "sphinxcontrib_applehelp-2.0.0.tar.gz", hash = "sha256:2f29ef331735ce958efa4734873f084941970894c6090408b079c61b2e1c06d1"},
+]
+
+[package.extras]
+lint = ["mypy", "ruff (==0.5.5)", "types-docutils"]
+standalone = ["Sphinx (>=5)"]
+test = ["pytest"]
+
+[[package]]
+name = "sphinxcontrib-devhelp"
+version = "2.0.0"
+description = "sphinxcontrib-devhelp is a sphinx extension which outputs Devhelp documents"
+optional = false
+python-versions = ">=3.9"
+groups = ["docs"]
+markers = "python_version >= \"3.10\""
+files = [
+ {file = "sphinxcontrib_devhelp-2.0.0-py3-none-any.whl", hash = "sha256:aefb8b83854e4b0998877524d1029fd3e6879210422ee3780459e28a1f03a8a2"},
+ {file = "sphinxcontrib_devhelp-2.0.0.tar.gz", hash = "sha256:411f5d96d445d1d73bb5d52133377b4248ec79db5c793ce7dbe59e074b4dd1ad"},
+]
+
+[package.extras]
+lint = ["mypy", "ruff (==0.5.5)", "types-docutils"]
+standalone = ["Sphinx (>=5)"]
+test = ["pytest"]
+
+[[package]]
+name = "sphinxcontrib-htmlhelp"
+version = "2.1.0"
+description = "sphinxcontrib-htmlhelp is a sphinx extension which renders HTML help files"
+optional = false
+python-versions = ">=3.9"
+groups = ["docs"]
+markers = "python_version >= \"3.10\""
+files = [
+ {file = "sphinxcontrib_htmlhelp-2.1.0-py3-none-any.whl", hash = "sha256:166759820b47002d22914d64a075ce08f4c46818e17cfc9470a9786b759b19f8"},
+ {file = "sphinxcontrib_htmlhelp-2.1.0.tar.gz", hash = "sha256:c9e2916ace8aad64cc13a0d233ee22317f2b9025b9cf3295249fa985cc7082e9"},
+]
+
+[package.extras]
+lint = ["mypy", "ruff (==0.5.5)", "types-docutils"]
+standalone = ["Sphinx (>=5)"]
+test = ["html5lib", "pytest"]
+
+[[package]]
+name = "sphinxcontrib-jsmath"
+version = "2.0.0"
+description = "sphinxcontrib-jsmath is a sphinx extension which renders displayed maths in HTML via JavaScript"
+optional = false
+python-versions = ">=3.9"
+groups = ["docs"]
+markers = "python_version >= \"3.10\""
+files = [
+ {file = "sphinxcontrib_jsmath-2.0.0-py3-none-any.whl", hash = "sha256:15ca92fe0eec82f0baf91a7efcc51ffacdb605924be6327683a52ebdacb6744c"},
+ {file = "sphinxcontrib_jsmath-2.0.0.tar.gz", hash = "sha256:551f780cf9687f9c3c74f0cf9f18aca06e0d6958853453f3803fe4d357c5b924"},
+]
+
+[package.extras]
+lint = ["mypy", "ruff (==0.5.5)", "types-docutils"]
+standalone = ["Sphinx (>=5)"]
+test = ["pytest"]
+
+[[package]]
+name = "sphinxcontrib-qthelp"
+version = "2.0.0"
+description = "sphinxcontrib-qthelp is a sphinx extension which outputs QtHelp documents"
+optional = false
+python-versions = ">=3.9"
+groups = ["docs"]
+markers = "python_version >= \"3.10\""
+files = [
+ {file = "sphinxcontrib_qthelp-2.0.0-py3-none-any.whl", hash = "sha256:b18a828cdba941ccd6ee8445dbe72ffa3ef8cbe7505d8cd1fa0d42d3f2d5f3eb"},
+ {file = "sphinxcontrib_qthelp-2.0.0.tar.gz", hash = "sha256:4fe7d0ac8fc171045be623aba3e2a8f613f8682731f9153bb2e40ece16b9bbab"},
+]
+
+[package.extras]
+lint = ["mypy", "ruff (==0.5.5)", "types-docutils"]
+standalone = ["Sphinx (>=5)"]
+test = ["defusedxml (>=0.7.1)", "pytest"]
+
+[[package]]
+name = "sphinxcontrib-serializinghtml"
+version = "2.0.0"
+description = "sphinxcontrib-serializinghtml is a sphinx extension which outputs \"serialized\" HTML files (json and pickle)"
+optional = false
+python-versions = ">=3.9"
+groups = ["docs"]
+markers = "python_version >= \"3.10\""
+files = [
+ {file = "sphinxcontrib_serializinghtml-2.0.0-py3-none-any.whl", hash = "sha256:6e2cb0eef194e10c27ec0023bfeb25badbbb5868244cf5bc5bdc04e4464bf331"},
+ {file = "sphinxcontrib_serializinghtml-2.0.0.tar.gz", hash = "sha256:e9d912827f872c029017a53f0ef2180b327c3f7fd23c87229f7a8e8b70031d4d"},
+]
+
+[package.extras]
+lint = ["mypy", "ruff (==0.5.5)", "types-docutils"]
+standalone = ["Sphinx (>=5)"]
+test = ["pytest"]
+
[[package]]
name = "tomli"
version = "2.4.1"
description = "A lil' TOML parser"
optional = false
python-versions = ">=3.8"
-groups = ["dev"]
-markers = "python_full_version <= \"3.11.0a6\""
+groups = ["dev", "docs"]
files = [
{file = "tomli-2.4.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:f8f0fc26ec2cc2b965b7a3b87cd19c5c6b8c5e5f436b984e85f486d652285c30"},
{file = "tomli-2.4.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:4ab97e64ccda8756376892c53a72bd1f964e519c77236368527f758fbc36a53a"},
@@ -1335,6 +1852,7 @@ files = [
{file = "tomli-2.4.1-py3-none-any.whl", hash = "sha256:0d85819802132122da43cb86656f8d1f8c6587d54ae7dcaf30e90533028b49fe"},
{file = "tomli-2.4.1.tar.gz", hash = "sha256:7c7e1a961a0b2f2472c1ac5b69affa0ae1132c39adcb67aba98568702b9cc23f"},
]
+markers = {dev = "python_full_version <= \"3.11.0a6\"", docs = "python_version == \"3.10\""}
[[package]]
name = "typing-extensions"
@@ -1342,12 +1860,12 @@ version = "4.16.0"
description = "Backported and Experimental Type Hints for Python 3.9+"
optional = false
python-versions = ">=3.9"
-groups = ["main", "dev"]
+groups = ["main", "dev", "docs"]
files = [
{file = "typing_extensions-4.16.0-py3-none-any.whl", hash = "sha256:481caa481374e813c1b176ada14e97f1f67a4539ce9cfeb3f350d78d6370c2e8"},
{file = "typing_extensions-4.16.0.tar.gz", hash = "sha256:dc983d19a509c94dba722ee6abd33940f7c05a89e243c47e907eb4db6f1a43e5"},
]
-markers = {dev = "python_version < \"3.13\""}
+markers = {dev = "python_version < \"3.13\"", docs = "python_version == \"3.10\""}
[[package]]
name = "urllib3"
@@ -1374,7 +1892,7 @@ version = "2.7.0"
description = "HTTP library with thread-safe connection pooling, file post, and more."
optional = false
python-versions = ">=3.10"
-groups = ["main"]
+groups = ["main", "docs"]
markers = "python_version >= \"3.10\""
files = [
{file = "urllib3-2.7.0-py3-none-any.whl", hash = "sha256:9fb4c81ebbb1ce9531cce37674bbc6f1360472bc18ca9a553ede278ef7276897"},
@@ -1390,4 +1908,4 @@ zstd = ["backports-zstd (>=1.0.0) ; python_version < \"3.14\""]
[metadata]
lock-version = "2.1"
python-versions = ">=3.9.2"
-content-hash = "f78b7a13854c1a3aedd7ae7d4c4d0685dbeb549a5d847abd08bb98561f043b9d"
+content-hash = "d06a4ce6dedfbf4c3fba422f05c41c5e92365cee2b843431fe350280458f4c3a"
diff --git a/pyproject.toml b/pyproject.toml
index 75b7fb8..7a736b3 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -31,6 +31,13 @@ pytest-httpx = "^0.35.0"
ruff = ">=0.1"
freezegun = "^1.5.5"
+[tool.poetry.group.docs]
+optional = true
+
+[tool.poetry.group.docs.dependencies]
+sphinx = { version = "8.1.3", python = ">=3.10" }
+sphinx-autoapi = { version = ">=3.4,<4", python = ">=3.10" }
+
[tool.pytest.ini_options]
addopts = "--cov=src --cov-report=term-missing:skip-covered --cov-report=xml"
diff --git a/sphinx/Makefile b/sphinx/Makefile
new file mode 100644
index 0000000..37f4f59
--- /dev/null
+++ b/sphinx/Makefile
@@ -0,0 +1,20 @@
+SPHINXOPTS ?=
+SPHINXBUILD ?= sphinx-build
+SOURCEDIR = $(dir $(abspath $(lastword $(MAKEFILE_LIST))))
+BUILDDIR = $(SOURCEDIR)_build
+JSONDIR = $(SOURCEDIR)json
+
+.PHONY: help html json clean
+
+help:
+ @$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)
+
+html:
+ @$(SPHINXBUILD) -M html "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)
+
+json:
+ @$(SPHINXBUILD) -b json "$(SOURCEDIR)" "$(JSONDIR)" $(SPHINXOPTS) $(O)
+
+clean:
+ @$(SPHINXBUILD) -M clean "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)
+ rm -rf "$(SOURCEDIR)autoapi"
diff --git a/sphinx/conf.py b/sphinx/conf.py
new file mode 100644
index 0000000..00bb35e
--- /dev/null
+++ b/sphinx/conf.py
@@ -0,0 +1,10 @@
+import os
+
+project = "auth0-api-python"
+with open(os.path.join(os.path.dirname(os.path.abspath(__file__)), "..", ".version")) as _version_file:
+ release = _version_file.read().strip()
+
+extensions = ["autoapi.extension", "sphinx.ext.napoleon"]
+
+autoapi_dirs = ["../src"]
+autoapi_options = ["members", "undoc-members", "show-inheritance", "show-module-summary"]
diff --git a/sphinx/index.rst b/sphinx/index.rst
new file mode 100644
index 0000000..bef34c6
--- /dev/null
+++ b/sphinx/index.rst
@@ -0,0 +1,5 @@
+auth0-api-python
+================
+
+.. toctree::
+ :hidden:
diff --git a/sphinx/json/autoapi/auth0_api_python/act/index.fjson b/sphinx/json/autoapi/auth0_api_python/act/index.fjson
new file mode 100644
index 0000000..040d046
--- /dev/null
+++ b/sphinx/json/autoapi/auth0_api_python/act/index.fjson
@@ -0,0 +1 @@
+{"parents": [{"link": "../../", "title": "API Reference"}, {"link": "../", "title": "auth0_api_python"}], "prev": {"link": "../", "title": "auth0_api_python"}, "next": {"link": "../api_client/", "title": "auth0_api_python.api_client"}, "title": "auth0_api_python.act", "meta": null, "body": " Helpers for working with the act claim on verified access token claims. Return the current actor from the outermost act.sub, if present. Return the delegation chain from newest actor to oldest actor. Return the current actor from the outermost act.sub, if present. Only the outermost act.sub should be used for authorization decisions.\nNested act values represent prior actors and are informational. Return the delegation chain from newest actor to oldest actor. The first entry is the current actor (outermost act.sub). Later entries are\nprior actors from nested act values and are typically most useful for audit\nand attribution.auth0_api_python.act\u00b6
\nAttributes\u00b6
\n\n\n
\n \n\n\n \n Functions\u00b6
\n\n\n
\n \n \nget_current_actor(\u2192\u00a0Optional[str]) \n \n\n \nget_delegation_chain(\u2192\u00a0list[str]) \nModule Contents\u00b6
\n\n
\n\n\n
\n\n\n
\n\n
| \n | \n |
| \n | \n |
| \n | \n |
| \n | \n |
| \n | \n |
| \n | The main class for discovering OIDC metadata (issuer, jwks_uri) and verifying | \n
The main class for discovering OIDC metadata (issuer, jwks_uri) and verifying\nAuth0-issued JWT access tokens in an async environment.
\nCheck if DPoP authentication is required.
\nIf scheme is \u2018DPoP\u2019, verifies both access token and DPoP proof
If scheme is \u2018Bearer\u2019, verifies only the access token
Note
\nAuthorization header parsing uses split(None, 1) to correctly handle\ntabs and multiple spaces per HTTP specs. Malformed headers with multiple\nspaces now raise VerifyAccessTokenError during JWT parsing (previously\nraised InvalidAuthSchemeError).
\nheaders \u2013 HTTP headers dict containing (header keys should be lowercase):\n- \u201cauthorization\u201d: The Authorization header value (required)\n- \u201cdpop\u201d: The DPoP proof header value (required for DPoP)
http_method \u2013 The HTTP method (required for DPoP)
http_url \u2013 The HTTP URL (required for DPoP, also used for MCD resolver context)
The decoded access token claims, including act when present.
\nMissingRequiredArgumentError \u2013 If required args are missing
InvalidAuthSchemeError \u2013 If an unsupported scheme is provided
InvalidDpopProofError \u2013 If DPoP verification fails
VerifyAccessTokenError \u2013 If access token verification fails
AuthServerUnavailableError \u2013 If the OIDC discovery document or JWKS cannot be reached
Asynchronously verifies the provided JWT access token.
\nFetches OIDC metadata and JWKS if not already cached.
Decodes and validates signature (RS256) with the correct key.
Checks standard claims: \u2018iss\u2019, \u2018aud\u2019, \u2018exp\u2019, \u2018nbf\u2019, \u2018iat\u2019
Checks extra required claims if \u2018required_claims\u2019 is provided.
Enforces organization_policy: requires \u2018org_id\u2019 when set to \u201crequired\u201d,\nand checks it against organization_id when an allowlist is configured.
access_token \u2013 The JWT access token to verify
request_url \u2013 Optional request URL for dynamic domain resolvers
request_headers \u2013 Optional request headers dict for dynamic domain resolvers
required_claims \u2013 Optional list of additional claim names that must be present
The decoded token claims if valid, including act when present.
\nMissingRequiredArgumentError \u2013 If no token is provided.
VerifyAccessTokenError \u2013 If verification fails (signature, claims mismatch, etc.).
DomainsResolverError \u2013 If domains resolver function fails.
MissingOrganizationError \u2013 If organization_policy is \u201crequired\u201d and the token has no org_id claim.
OrganizationNotAllowedError \u2013 If the token\u2019s org_id is not in the organization_id allowlist.
AuthServerUnavailableError \u2013 If the OIDC discovery document or JWKS cannot be reached.
Single well-formed compact JWS
typ=\u201ddpop+jwt\u201d, alg\u2208allowed, alg\u2260none
jwk header present & public only
Signature verifies with jwk
5. Validates all required claims\nRaises InvalidDpopProofError on any failure.
\nRetrieves a token for a connection.
\noptions \u2013 Options for retrieving an access token for a connection.\nMust include \u2018connection\u2019 and \u2018access_token\u2019 keys.\nMay optionally include \u2018login_hint\u2019.
verified \u2013 The already-verified token, supplied by a caller that has verified it (for\nexample an MCP server). When omitted and a token_store is configured, the\ntoken is verified here before any cache lookup.
GetAccessTokenForConnectionError \u2013 If there was an issue requesting the access token.
ApiError \u2013 If the token exchange endpoint returns an error.
VerifyAccessTokenError \u2013 If a store is configured and either verified is omitted and the token fails verification, or verified is supplied but does not match the access token being exchanged.
MissingOrganizationError \u2013 If a store is configured, verified is omitted, organization_policy is \u201crequired\u201d and the token has no org_id claim.
OrganizationNotAllowedError \u2013 If a store is configured, verified is omitted and the token\u2019s org_id is not in the organization_id allowlist.
AuthServerUnavailableError \u2013 If a store is configured, verified is omitted and the OIDC discovery document or JWKS cannot be reached.
Dictionary containing the token response with access_token, expires_in, and scope.
\nExchange a subject token for an Auth0 token using RFC 8693.
\nThe matching Token Exchange Profile is selected by subject_token_type.\nThis method requires a confidential client (client_id and client_secret must be configured).
\nsubject_token \u2013 The token to be exchanged
subject_token_type \u2013 URI identifying the token type (must match a Token Exchange Profile)
audience \u2013 Optional target API identifier for the exchanged tokens
scope \u2013 Optional space-separated OAuth 2.0 scopes to request
requested_token_type \u2013 Optional type of token to issue (defaults to access token)
extra \u2013 Optional additional parameters sent as form fields to Auth0.\nAll values are converted to strings before sending.\nArrays are limited to 20 values per key for DoS protection.\nCannot override reserved OAuth parameters (case-insensitive check).
access_token (str): The Auth0 access token
expires_in (int): Token lifetime in seconds
expires_at (int): Absolute expiration time as a Unix timestamp in seconds, calculated by the SDK from expires_in
id_token (str, optional): OpenID Connect ID token
refresh_token (str, optional): Refresh token
scope (str, optional): Granted scopes
token_type (str, optional): Token type (typically \u201cBearer\u201d)
issued_token_type (str, optional): RFC 8693 issued token type identifier
Dictionary containing
\nMissingRequiredArgumentError \u2013 If required parameters are missing
GetTokenByExchangeProfileError \u2013 If client credentials not configured, validation fails,\nor reserved parameters are supplied in extra
ApiError \u2013 If the token endpoint returns an error
Example
\nsubject_token=token,\nsubject_token_type=\u201durn:example:subject-token\u201d,\naudience=\u201dhttps://api.backend.com\u201d
\n)
\nReferences
\nCustom Token Exchange: https://auth0.com/docs/authenticate/custom-token-exchange
Related SDK: https://github.com/auth0/auth0-auth-js
Exchange an Auth0 access token for another Auth0 access token targeting a downstream API\nwhile acting on behalf of the same end user (OBO).
\nThis is a convenience wrapper around get_token_by_exchange_profile() that fixes the\nRFC 8693 token types for Auth0 access-token-to-access-token exchange.
\naccess_token \u2013 The Auth0 access token to exchange
audience \u2013 Target API identifier for the exchanged access token
scope \u2013 Optional space-separated OAuth 2.0 scopes to request
verified \u2013 The already-verified token, supplied by a caller that has verified it (for\nexample an MCP server). When omitted and a token_store is configured, the\ntoken is verified here before any cache lookup. Its claims must carry sub\nand iss, otherwise caching is skipped with a warning.
access_token (str): The exchanged Auth0 access token
expires_in (int): Token lifetime in seconds
expires_at (int): Absolute expiration time as a Unix timestamp in seconds, calculated by the SDK from expires_in
scope (str, optional): Granted scopes
token_type (str, optional): Token type (typically \u201cBearer\u201d)
issued_token_type (str, optional): RFC 8693 issued token type identifier
Dictionary containing
\nCaching is enabled only when a token_store is configured on the client. Without a store\nevery call performs a fresh exchange and nothing is cached. The scope_matching option\ncontrols whether a cached token is reused only on an exact scope match (\u201cstrict\u201d) or\nwhenever its granted scopes cover the request (\u201cnon_strict\u201d).
\nMissingRequiredArgumentError \u2013 If required parameters are missing
VerifyAccessTokenError \u2013 If a store is configured and either verified is omitted and the token fails verification, or verified is supplied but does not match the access token being exchanged
MissingOrganizationError \u2013 If a store is configured, verified is omitted, organization_policy is \u201crequired\u201d and the token has no org_id claim
OrganizationNotAllowedError \u2013 If a store is configured, verified is omitted and the token\u2019s org_id is not in the organization_id allowlist
AuthServerUnavailableError \u2013 If a store is configured, verified is omitted and the OIDC discovery document or JWKS cannot be reached
GetTokenByExchangeProfileError \u2013 If client credentials are not configured or validation fails
ApiError \u2013 If the token endpoint returns an error
Obtain a client credentials (M2M) access token for a server-to-server call.
\naudience \u2013 Target API identifier for the access token
scope \u2013 Optional space-separated OAuth 2.0 scopes to request
access_token (str): The access token
expires_in (int): Token lifetime in seconds
expires_at (int): Absolute expiration time as a Unix timestamp in seconds, calculated by the SDK from expires_in
scope (str, optional): Granted scopes, if returned by Auth0
token_type (str, optional): Token type, if returned by Auth0
Dictionary containing
\nMissingRequiredArgumentError \u2013 If audience is not provided
GetClientCredentialsTokenError \u2013 If client credentials are not configured or token endpoint is missing
ApiError \u2013 If the token endpoint returns an error or a malformed response
loggerTOKEN_EXCHANGE_GRANT_TYPEOBO_ACCESS_TOKEN_TYPEMAX_ARRAY_VALUES_PER_KEYRESERVED_PARAMSApiClientApiClient.optionsApiClient.is_dpop_required()ApiClient.verify_request()ApiClient.verify_access_token()ApiClient.verify_dpop_proof()ApiClient.get_access_token_for_connection()ApiClient.get_token_by_exchange_profile()ApiClient.get_token_on_behalf_of()ApiClient.get_client_credentials_token()| \n | Abstract base class for cache implementations. | \n
| \n | Default in-memory cache implementation with LRU eviction. | \n
Bases: abc.ABC
Abstract base class for cache implementations.
\nAllows custom cache backends (Redis, Memcached, etc.) to be plugged into\nthe ApiClient for caching OIDC discovery metadata and JWKS.
\nExample
\nself.redis = redis_client
\nvalue = self.redis.get(key)\nreturn json.loads(value) if value else None
\nself.redis.set(key, json.dumps(value), ex=ttl_seconds)
\nself.redis.delete(key)
\nself.redis.flushdb()
\nGet value from cache by key.
\nkey \u2013 Cache key to retrieve
\nCached value if found and not expired, None otherwise
\nSet value in cache with optional TTL.
\nkey \u2013 Cache key to store
value \u2013 Value to cache
ttl_seconds \u2013 Time-to-live in seconds. None means no expiration.
Delete value from cache.
\nkey \u2013 Cache key to delete
\nClear all cache entries.
\nBases: CacheAdapter
Default in-memory cache implementation with LRU eviction.
\nDesigned for asyncio (single-threaded).\nFor multi-threaded environments, implement a custom CacheAdapter\nwith appropriate locking.
\nFeatures:\n- TTL (time-to-live) support per entry using monotonic clock\n- LRU (Least Recently Used) eviction when max_entries reached\n- No external dependencies
\nmax_entries \u2013 Maximum number of entries to cache. When exceeded,\nleast recently used entry is evicted. Default: 100.
\nExample
\ncache = InMemoryCache(max_entries=50)\ncache.set(\u201ckey1\u201d, {\u201cdata\u201d: \u201cvalue\u201d}, ttl_seconds=600)\nvalue = cache.get(\u201ckey1\u201d) # Returns {\u201cdata\u201d: \u201cvalue\u201d}
\nGet value from cache by key.
\nUpdates access order for LRU tracking.
\nkey \u2013 Cache key to retrieve
\nCached value if found and not expired, None otherwise
\nSet value in cache with optional TTL.
\nIf cache is at max capacity, evicts least recently used entry.
\nkey \u2013 Cache key to store
value \u2013 Value to cache
ttl_seconds \u2013 Time-to-live in seconds. None means no expiration.
Delete value from cache.
\nkey \u2013 Cache key to delete
\nClear all cache entries.
\nConfiguration classes and utilities for auth0-api-python.
\n| \n | Configuration for the ApiClient. | \n
Configuration for the ApiClient.
\ndomain \u2013 The Auth0 domain for single-domain mode and client flows,\ne.g., \u201cmy-tenant.us.auth0.com\u201d. Optional if domains is provided.
domains \u2013 List of allowed domains or a resolver function for multi-domain mode.\nCan be a static list of domain strings or a callable that returns\nallowed domains dynamically. Optional if domain is provided.
audience \u2013 The expected \u2018aud\u2019 claim in the token.
custom_fetch \u2013 Optional callable that replaces the default HTTP fetch for discovery and JWKS requests. It is called with the URL only and receives no telemetry headers.
cache_adapter \u2013 Custom cache implementation. If not provided, uses default InMemoryCache.
token_store \u2013 Custom token storage for token caching. If not provided, caching is disabled and every exchange makes a fresh network call.
cache_ttl_seconds \u2013 Time-to-live for cache entries in seconds (default: 600 = 10 minutes).
cache_max_entries \u2013 Maximum number of cache entries before LRU eviction (default: 100).
dpop_enabled \u2013 Whether DPoP is enabled (default: True for backward compatibility).
dpop_required \u2013 Whether DPoP is required (default: False, allows both Bearer and DPoP).
dpop_iat_leeway \u2013 Leeway in seconds for DPoP proof iat claim (default: 30).
dpop_iat_offset \u2013 Maximum age in seconds for DPoP proof iat claim (default: 300).
client_id \u2013 Required for get_access_token_for_connection, get_token_by_exchange_profile,\nand get_token_on_behalf_of.
client_secret \u2013 Required for get_access_token_for_connection, get_token_by_exchange_profile,\nand get_token_on_behalf_of.
timeout \u2013 HTTP timeout in seconds for token endpoint requests (default: 10.0).
organization_policy \u2013 Whether the incoming token must carry an org_id claim.\n\u201callow\u201d (default) uses org_id when present but does not require it,\nmatching the pre-existing behavior of verify_access_token.\n\u201crequired\u201d rejects any token without an org_id claim.
organization_id \u2013 Optional allowlist of org_id claim values (a non-empty string or a non-empty\nlist of non-empty strings). Only valid when organization_policy is\n\u201crequired\u201d - passing it with \u201callow\u201d raises ConfigurationError at\nconstruction time, as does an empty or non-string value.
scope_matching \u2013 OBO cache scope-matching mode, applied only when token_store is set.\n\u201cstrict\u201d (default) reuses a cached token only on an exact granted-scope\nmatch. \u201cnon_strict\u201d reuses any cached token whose granted scopes cover\nthe request, and requires a token_store subclassing IndexedTokenStore\n(raises ConfigurationError at construction without one).
client_info \u2013 Name, version and optional env of a wrapper SDK built on this one, as a dict with non-empty string \u201cname\u201d and \u201cversion\u201d keys and an optional \u201cenv\u201d dict of string keys and values. Sent in the Auth0-Client header. An invalid value raises ConfigurationError at construction, and the \u201cpython\u201d and \u201cauth0-api-python\u201d entries in env are set by this SDK.
ApiClientOptionsApiClientOptions.domainApiClientOptions.domainsApiClientOptions.audienceApiClientOptions.custom_fetchApiClientOptions.cache_adapterApiClientOptions.token_storeApiClientOptions.cache_ttl_secondsApiClientOptions.cache_max_entriesApiClientOptions.dpop_enabledApiClientOptions.dpop_requiredApiClientOptions.dpop_iat_leewayApiClientOptions.dpop_iat_offsetApiClientOptions.client_idApiClientOptions.client_secretApiClientOptions.timeoutApiClientOptions.organization_policyApiClientOptions.organization_idApiClientOptions.scope_matchingApiClientOptions.client_infoJWE encryption helpers for token store implementations.
\n
| \nEncrypt a dict to a compact JWE string. A fresh random kid is generated per call. | \n
| \nDecrypt a compact JWE string back to a dict. | \n
Encrypt a dict to a compact JWE string. A fresh random kid is generated per call.
\nDecrypt a compact JWE string back to a dict.
\nCustom exceptions for auth0-api-python SDK with HTTP response metadata
\n| \n | Base class for all auth errors with HTTP response metadata. | \n
| \n | Error raised when a required argument is missing. | \n
| \n | Error raised when verifying the access token fails. | \n
| \n | Error raised when the OIDC discovery document or JWKS cannot be reached. | \n
| \n | Error raised when organization_policy is 'required' but the token has no org_id claim. | \n
| \n | Error raised when the token's org_id claim is not in the organization_id allowlist. | \n
| \n | Error raised when the provided authentication scheme is unsupported. | \n
| \n | Error raised when validating a DPoP proof fails. | \n
| \n | Authorization header is missing, empty, or malformed. | \n
| \n | Error raised when getting a token for a connection fails. | \n
| \n | Error raised when getting a token via exchange profile fails. | \n
| \n | Error raised when a client credentials token request fails before the network call. | \n
| \n | Error raised when an API request to Auth0 fails. | \n
| \n | Error raised when SDK configuration is invalid. | \n
| \n | Error raised when domains resolver function fails. | \n
Bases: Exception
Base class for all auth errors with HTTP response metadata.
\nReturn the HTTP status code for this error.
\nReturn the OAuth/DPoP error code.
\nReturn the error description.
\nReturn HTTP headers (including WWW-Authenticate if set).
\nBases: BaseAuthError
Error raised when a required argument is missing.
\nReturn the HTTP status code for this error.
\nReturn the OAuth/DPoP error code.
\nBases: BaseAuthError
Error raised when verifying the access token fails.
\nReturn the HTTP status code for this error.
\nReturn the OAuth/DPoP error code.
\nBases: VerifyAccessTokenError
Error raised when the OIDC discovery document or JWKS cannot be reached.
\nReturn the HTTP status code for this error.
\nReturn the OAuth/DPoP error code.
\nBases: VerifyAccessTokenError
Error raised when organization_policy is \u2018required\u2019 but the token has no org_id claim.
\nBases: VerifyAccessTokenError
Error raised when the token\u2019s org_id claim is not in the organization_id allowlist.
\nBases: BaseAuthError
Error raised when the provided authentication scheme is unsupported.
\nReturn the HTTP status code for this error.
\nReturn the OAuth/DPoP error code.
\nBases: BaseAuthError
Error raised when validating a DPoP proof fails.
\nReturn the HTTP status code for this error.
\nReturn the OAuth/DPoP error code.
\nBases: BaseAuthError
Authorization header is missing, empty, or malformed.
\nReturn the HTTP status code for this error.
\nReturn the OAuth/DPoP error code.
\nBases: BaseAuthError
Error raised when getting a token for a connection fails.
\nReturn the HTTP status code for this error.
\nReturn the OAuth/DPoP error code.
\nBases: BaseAuthError
Error raised when getting a token via exchange profile fails.
\nReturn the HTTP status code for this error.
\nReturn the OAuth/DPoP error code.
\nBases: BaseAuthError
Error raised when a client credentials token request fails before the network call.
\nReturn the HTTP status code for this error.
\nReturn the OAuth/DPoP error code.
\nBases: BaseAuthError
Error raised when an API request to Auth0 fails.\nContains details about the original error from Auth0.
\nReturn the HTTP status code for this error.
\nReturn the OAuth/DPoP error code.
\nBases: BaseAuthError
Error raised when SDK configuration is invalid.
\nReturn the HTTP status code for this error.
\nReturn the OAuth/DPoP error code.
\nBases: BaseAuthError
Error raised when domains resolver function fails.
\nReturn the HTTP status code for this error.
\nReturn the OAuth/DPoP error code.
\nBaseAuthError\nMissingRequiredArgumentError\nVerifyAccessTokenError\nAuthServerUnavailableError\nMissingOrganizationErrorOrganizationNotAllowedErrorInvalidAuthSchemeError\nInvalidDpopProofError\nMissingAuthorizationError\nGetAccessTokenForConnectionError\nGetTokenByExchangeProfileError\nGetClientCredentialsTokenError\nApiError\nConfigurationError\nDomainsResolverError\nauth0-api-python
\nA lightweight Python SDK for verifying Auth0-issued access tokens\nin server-side APIs, using Authlib for OIDC discovery and JWKS fetching.
\nClient telemetry headers sent on requests this SDK makes to Auth0 with its default HTTP client.
\n
| \nCheck the shape of a wrapper's client_info. | \n
| \nBuild the Auth0-Client and User-Agent headers. | \n
Check the shape of a wrapper\u2019s client_info.
\nValueError \u2013 If client_info is not a dict with non-empty string name and version, and an optional env dict of strings.
\nBuild the Auth0-Client and User-Agent headers.
\nclient_info \u2013 Name, version and optional env of a wrapper SDK built on this one.
\nHeaders to attach to each HTTP request.
\nToken storage for SDK-minted tokens (OBO, M2M, Token Vault), distinct from CacheAdapter.
\n| \n | A minted access token and its absolute expiration, as stored by a TokenStore. | \n
| \n | Access token with verified claims from verify_access_token, trusted to build the cache key. | \n
| \n | Base class for external token stores with built-in JWE encrypt and decrypt helpers. | \n
| \n | One cached token listed in an index, with the scopes it was granted and when it expires. | \n
| \n | Token store variant that maintains a scope index with atomic member writes to avoid concurrent-add races. | \n
Bases: _TokenSetRequired
A minted access token and its absolute expiration, as stored by a TokenStore.
\nAccess token with verified claims from verify_access_token, trusted to build the cache key.
\nBases: abc.ABC
Base class for external token stores with built-in JWE encrypt and decrypt helpers.
\nReturn the stored token or None if absent.
\nStore a token under key.
\nDelete a stored token by key.
\nEncrypt a TokenSet to a JWE string, keyed to this specific cache entry.
\nDecrypt a JWE string back to a TokenSet.
\nBases: TypedDict
One cached token listed in an index, with the scopes it was granted and when it expires.
\nBases: AbstractTokenStore
Token store variant that maintains a scope index with atomic member writes to avoid concurrent-add races.
\nAtomically add member to the index, replacing any member with the same token_key.
\nReturn the index members, possibly including expired ones, or [] if the index is absent.
\nTokenSet\nVerifiedToken\nAbstractTokenStore\nTokenIndexMember\nIndexedTokenStore\n| \n | \n |
| \n | \n |
| \nGenerates a real RS256-signed JWT using the private key above. | \n
| \nGenerates a real ES256-signed DPoP proof JWT using the EC private key above. | \n
| \nGenerates an access token with cnf (confirmation) claim for DPoP binding. | \n
Generates a real RS256-signed JWT using the private key above.
\ndomain \u2013 The Auth0 domain (used if issuer is not False).
user_id \u2013 The \u2018sub\u2019 claim in the token.
audience \u2013 The \u2018aud\u2019 claim in the token. If omitted, \u2018aud\u2019 won\u2019t be included.
issuer \u2013
If a string, it\u2019s placed in \u2018iss\u2019 claim.
If None, default is f\u201dhttps://{domain}/\u201d.
If False, skip \u2018iss\u2019 claim entirely.
iat \u2013 Whether to set the \u2018iat\u2019 (issued at) claim. If False, skip it.
exp \u2013 Whether to set the \u2018exp\u2019 claim. If False, skip it.
claims \u2013 Additional custom claims to merge into the token.
expiration_time \u2013 If exp is True, how many seconds from now until expiration.
A RS256-signed JWT string.
\ndomain=\u201dexample.us.auth0.com\u201d,\nuser_id=\u201duser123\u201d,\naudience=\u201dmy-api\u201d,\nissuer=False,\niat=False,\nexp=False,\nclaims={\u201cscope\u201d: \u201cread:stuff\u201d}
\n)
\nGenerates a real ES256-signed DPoP proof JWT using the EC private key above.
\naccess_token \u2013 The access token to create proof for (used for ath claim).
http_method \u2013 The HTTP method (e.g., \u201cGET\u201d, \u201cPOST\u201d) for htm claim.
http_url \u2013 The HTTP URL for htu claim.
jti \u2013 The unique identifier for the proof. If omitted, generates random UUID.
iat \u2013 Whether to set the \u2018iat\u2019 (issued at) claim. If False, skip it.
claims \u2013 Additional custom claims to merge into the proof.
header_overrides \u2013 Override header parameters (e.g., for testing invalid headers).
iat_time \u2013 Fixed time for iat claim (for testing). If None, uses current time.
include_jti \u2013 Whether to include the \u2018jti\u2019 claim. If False, jti is completely omitted.
An ES256-signed DPoP proof JWT string.
\naccess_token=\u201deyJ\u2026\u201d,\nhttp_method=\u201dGET\u201d,\nhttp_url=\u201dhttps://api.example.com/resource\u201d,\niat=False, # Skip iat for testing\nclaims={\u201ccustom\u201d: \u201cclaim\u201d}
\n)
\nGenerates an access token with cnf (confirmation) claim for DPoP binding.\nExtends the existing generate_token() function with DPoP support.
\ndomain \u2013 The Auth0 domain (used if issuer is not False).
user_id \u2013 The \u2018sub\u2019 claim in the token.
audience \u2013 The \u2018aud\u2019 claim in the token.
jkt_thumbprint \u2013 JWK thumbprint to include in cnf claim. If None, calculates from PRIVATE_EC_JWK.
**kwargs \u2013 Additional arguments passed to generate_token().
A RS256-signed JWT string with cnf claim.
\ndomain=\u201dauth0.local\u201d,\nuser_id=\u201duser123\u201d,\naudience=\u201dmy-api\u201d,\njkt_thumbprint=\u201dcustom_thumbprint\u201d
\n)
\nType definitions for auth0-api-python SDK
\n| \n | Type alias for domains resolver function. | \n
| \n | Actor claim carried by access tokens issued through delegation. | \n
| \n | Context passed to domains resolver functions. | \n
| \n | Result returned from an On Behalf Of token exchange. | \n
| \n | Result returned from a client credentials (M2M) token request. | \n
Bases: TypedDict
Actor claim carried by access tokens issued through delegation.
\nThe current actor for this step of the delegation chain.
\nThe prior actor in the delegation chain, if present.
\nBases: TypedDict
Context passed to domains resolver functions.
\nThe URL the API request was made to (optional)
\nRequest headers dict (e.g., Host, X-Forwarded-Host) (optional)
\nThe issuer claim from the unverified token
\nBases: TypedDict
Result returned from an On Behalf Of token exchange.
\nThe access token issued for the downstream API.
\nToken lifetime in seconds.
\nAbsolute expiration time as a Unix timestamp in seconds, calculated by the SDK from expires_in.
\nGranted scopes, if returned by Auth0.
\nToken type, if returned by Auth0.
\nRFC 8693 issued token type, if returned by Auth0.
\nBases: TypedDict
Result returned from a client credentials (M2M) token request.
\nThe access token issued for the target API.
\nToken lifetime in seconds.
\nAbsolute expiration time as a Unix timestamp in seconds, calculated by the SDK from expires_in.
\nGranted scopes, if returned by Auth0.
\nToken type, if returned by Auth0.
\nType alias for domains resolver function.
\nA DomainsResolver is a sync or async function that receives a DomainsResolverContext\nand returns a list of allowed domain strings.
\ncontext (DomainsResolverContext) \u2013 Dictionary containing:\n- \u2018request_url\u2019 (str | None): The URL the API request was made to\n- \u2018request_headers\u2019 (dict | None): Request headers (e.g., Host, X-Forwarded-Host)\n- \u2018unverified_iss\u2019 (str): The issuer claim from the unverified token
\nList of allowed domain strings (e.g., [\u2018tenant.auth0.com\u2019])
\nlist[str]
\nfrom auth0_api_python import DomainsResolverContext
\nhost = (context.get(\u2018request_headers\u2019) or {}).get(\u2018host\u2019)\nif host == \u2018api.brand.com\u2019:
\n\n\nreturn [\u2018brand.custom-domain.com\u2019]
\n
return [\u2018tenant.auth0.com\u2019]
\ndomains = await db.lookup_domains(context[\u2018unverified_iss\u2019])\nreturn domains
\nActClaim\nDomainsResolverContext\nOnBehalfOfTokenResultOnBehalfOfTokenResult.access_tokenOnBehalfOfTokenResult.expires_inOnBehalfOfTokenResult.expires_atOnBehalfOfTokenResult.scopeOnBehalfOfTokenResult.token_typeOnBehalfOfTokenResult.issued_token_typeOnBehalfOfTokenResult.access_tokenOnBehalfOfTokenResult.expires_inOnBehalfOfTokenResult.expires_atOnBehalfOfTokenResult.scopeOnBehalfOfTokenResult.token_typeOnBehalfOfTokenResult.issued_token_typeClientCredentialsTokenResultClientCredentialsTokenResult.access_tokenClientCredentialsTokenResult.expires_inClientCredentialsTokenResult.expires_atClientCredentialsTokenResult.scopeClientCredentialsTokenResult.token_typeClientCredentialsTokenResult.access_tokenClientCredentialsTokenResult.expires_inClientCredentialsTokenResult.expires_atClientCredentialsTokenResult.scopeClientCredentialsTokenResult.token_typeDomainsResolverUtility functions for OIDC discovery and JWKS fetching (asynchronously)\nusing httpx or a custom fetch approach.
\n
| \nParse the max-age directive from a Cache-Control HTTP header. | \n
| \nNormalize a domain string to a standard issuer URL format. | \n
| \nCheck whether a discovery or JWKS fetch error means the auth server is down or overloaded. | \n
| \nAsynchronously fetch the OIDC config from https://{domain}/.well-known/openid-configuration. | \n
| \nAsynchronously fetch the JSON Web Key Set from jwks_uri. | \n
| \nParse the JWT header without verifying signature. | \n
| \nParse the JWT payload without verifying signature. | \n
| \nIf segment's length is not a multiple of 4, add '=' padding | \n
| \nIf the string looks like b'eyJh...', remove the leading b' and trailing '. | \n
| \nNormalize URL for DPoP htu comparison . | \n
| \nCompute SHA-256 digest of the input string and return a | \n
| \nCompute the RFC 7638 JWK thumbprint for a public JWK. | \n
Parse the max-age directive from a Cache-Control HTTP header.
\nheaders \u2013 HTTP response headers (dict-like, supports case-insensitive\naccess for httpx Headers objects)
\nmax-age value in seconds, or None if not present or unparseable
\nNormalize a domain string to a standard issuer URL format.
\ndomain \u2013 Domain string in any format (e.g., \u201ctenant.auth0.com\u201d,\n\u201chttps://tenant.auth0.com/\u201d, \u201cTENANT.AUTH0.COM\u201d)
\n//tenant.auth0.com/\u201d)
\nNormalized issuer URL (e.g., \u201chttps
\nCheck whether a discovery or JWKS fetch error means the auth server is down or overloaded.
\nerror \u2013 The exception raised while fetching.
\nTrue for connection errors, timeouts, HTTP 5xx and HTTP 429. False for anything else.
\nAsynchronously fetch the OIDC config from https://{domain}/.well-known/openid-configuration.
\ndomain \u2013 The Auth0 domain.
custom_fetch \u2013 Optional callable that replaces the default HTTP fetch.
headers \u2013 Headers for the default HTTP client. Not applied when custom_fetch is set.
Tuple of (metadata_dict, max_age_or_none). max_age is parsed from\nthe Cache-Control response header if present.
\nAsynchronously fetch the JSON Web Key Set from jwks_uri.
\njwks_uri \u2013 The JWKS endpoint URL.
custom_fetch \u2013 Optional callable that replaces the default HTTP fetch.
headers \u2013 Headers for the default HTTP client. Not applied when custom_fetch is set.
Tuple of (jwks_dict, max_age_or_none). max_age is parsed from\nthe Cache-Control response header if present.
\nParse the JWT header without verifying signature.
\ntoken \u2013 The JWT token
\nDecoded header as dictionary
\nValueError \u2013 If the token is malformed or its header is not a JSON object or is nested too deeply
\nParse the JWT payload without verifying signature.
\ntoken \u2013 The JWT token
\nDecoded payload (claims) as dictionary
\nValueError \u2013 If the token is malformed or its payload is not a JSON object or is nested too deeply
\nIf segment\u2019s length is not a multiple of 4, add \u2018=\u2019 padding\nso that base64.urlsafe_b64decode won\u2019t produce nonsense bytes.\nNo extra \u2018=\u2019 added if length is already a multiple of 4.
\nIf the string looks like b\u2019eyJh\u2026\u2019, remove the leading b\u2019 and trailing \u2018.
\nNormalize URL for DPoP htu comparison .
\nraw_url \u2013 The raw URL string to normalize
\nThe normalized URL string
\nValueError \u2013 If the URL is invalid or cannot be parsed
\nCompute SHA-256 digest of the input string and return a\nBase64URL-encoded string without padding.
\nCompute the RFC 7638 JWK thumbprint for a public JWK.
\nFor EC keys, includes only: crv, kty, x, y
Serializes with no whitespace, keys sorted lexicographically
Hashes with SHA-256 and returns base64url-encoded string without padding
This page contains auto-generated API reference documentation [1].
\n