From 6ffeade9d090c7481b41f07bc64c9fc5a575d87a Mon Sep 17 00:00:00 2001 From: Marek Skrobacki Date: Wed, 21 Aug 2024 14:56:36 +0100 Subject: [PATCH 01/14] create basic package --- python/ironic-understack/poetry.lock | 2655 +++++++++++++++++++++++ python/ironic-understack/pyproject.toml | 19 + 2 files changed, 2674 insertions(+) create mode 100644 python/ironic-understack/poetry.lock create mode 100644 python/ironic-understack/pyproject.toml diff --git a/python/ironic-understack/poetry.lock b/python/ironic-understack/poetry.lock new file mode 100644 index 00000000..36265ce5 --- /dev/null +++ b/python/ironic-understack/poetry.lock @@ -0,0 +1,2655 @@ +# This file is automatically @generated by Poetry 1.8.3 and should not be changed by hand. + +[[package]] +name = "alembic" +version = "1.13.2" +description = "A database migration tool for SQLAlchemy." +optional = false +python-versions = ">=3.8" +files = [ + {file = "alembic-1.13.2-py3-none-any.whl", hash = "sha256:6b8733129a6224a9a711e17c99b08462dbf7cc9670ba8f2e2ae9af860ceb1953"}, + {file = "alembic-1.13.2.tar.gz", hash = "sha256:1ff0ae32975f4fd96028c39ed9bb3c867fe3af956bd7bb37343b54c9fe7445ef"}, +] + +[package.dependencies] +Mako = "*" +SQLAlchemy = ">=1.3.0" +typing-extensions = ">=4" + +[package.extras] +tz = ["backports.zoneinfo"] + +[[package]] +name = "amqp" +version = "5.2.0" +description = "Low-level AMQP client for Python (fork of amqplib)." +optional = false +python-versions = ">=3.6" +files = [ + {file = "amqp-5.2.0-py3-none-any.whl", hash = "sha256:827cb12fb0baa892aad844fd95258143bce4027fdac4fccddbc43330fd281637"}, + {file = "amqp-5.2.0.tar.gz", hash = "sha256:a1ecff425ad063ad42a486c902807d1482311481c8ad95a72694b2975e75f7fd"}, +] + +[package.dependencies] +vine = ">=5.0.0,<6.0.0" + +[[package]] +name = "attrs" +version = "24.2.0" +description = "Classes Without Boilerplate" +optional = false +python-versions = ">=3.7" +files = [ + {file = "attrs-24.2.0-py3-none-any.whl", hash = "sha256:81921eb96de3191c8258c199618104dd27ac608d9366f5e35d011eae1867ede2"}, + {file = "attrs-24.2.0.tar.gz", hash = "sha256:5cfb1b9148b5b086569baec03f20d7b6bf3bcacc9a42bebf87ffaaca362f6346"}, +] + +[package.extras] +benchmark = ["cloudpickle", "hypothesis", "mypy (>=1.11.1)", "pympler", "pytest (>=4.3.0)", "pytest-codspeed", "pytest-mypy-plugins", "pytest-xdist[psutil]"] +cov = ["cloudpickle", "coverage[toml] (>=5.3)", "hypothesis", "mypy (>=1.11.1)", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "pytest-xdist[psutil]"] +dev = ["cloudpickle", "hypothesis", "mypy (>=1.11.1)", "pre-commit", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "pytest-xdist[psutil]"] +docs = ["cogapp", "furo", "myst-parser", "sphinx", "sphinx-notfound-page", "sphinxcontrib-towncrier", "towncrier (<24.7)"] +tests = ["cloudpickle", "hypothesis", "mypy (>=1.11.1)", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "pytest-xdist[psutil]"] +tests-mypy = ["mypy (>=1.11.1)", "pytest-mypy-plugins"] + +[[package]] +name = "automaton" +version = "3.2.0" +description = "Friendly state machines for python." +optional = false +python-versions = ">=3.8" +files = [ + {file = "automaton-3.2.0-py3-none-any.whl", hash = "sha256:4de0902b214d9e2070fdc1816856251737f007340cffd3c89474be0efda15ee1"}, + {file = "automaton-3.2.0.tar.gz", hash = "sha256:047670886e9bc316e3915c23b092cde501d49cae0d37a93ac6dde34b5044b2cc"}, +] + +[package.dependencies] +pbr = ">=2.0.0,<2.1.0 || >2.1.0" +PrettyTable = ">=0.7.2" + +[[package]] +name = "bcrypt" +version = "4.2.0" +description = "Modern password hashing for your software and your servers" +optional = false +python-versions = ">=3.7" +files = [ + {file = "bcrypt-4.2.0-cp37-abi3-macosx_10_12_universal2.whl", hash = "sha256:096a15d26ed6ce37a14c1ac1e48119660f21b24cba457f160a4b830f3fe6b5cb"}, + {file = "bcrypt-4.2.0-cp37-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c02d944ca89d9b1922ceb8a46460dd17df1ba37ab66feac4870f6862a1533c00"}, + {file = "bcrypt-4.2.0-cp37-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1d84cf6d877918620b687b8fd1bf7781d11e8a0998f576c7aa939776b512b98d"}, + {file = "bcrypt-4.2.0-cp37-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:1bb429fedbe0249465cdd85a58e8376f31bb315e484f16e68ca4c786dcc04291"}, + {file = "bcrypt-4.2.0-cp37-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:655ea221910bcac76ea08aaa76df427ef8625f92e55a8ee44fbf7753dbabb328"}, + {file = "bcrypt-4.2.0-cp37-abi3-musllinux_1_1_aarch64.whl", hash = "sha256:1ee38e858bf5d0287c39b7a1fc59eec64bbf880c7d504d3a06a96c16e14058e7"}, + {file = "bcrypt-4.2.0-cp37-abi3-musllinux_1_1_x86_64.whl", hash = "sha256:0da52759f7f30e83f1e30a888d9163a81353ef224d82dc58eb5bb52efcabc399"}, + {file = "bcrypt-4.2.0-cp37-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:3698393a1b1f1fd5714524193849d0c6d524d33523acca37cd28f02899285060"}, + {file = "bcrypt-4.2.0-cp37-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:762a2c5fb35f89606a9fde5e51392dad0cd1ab7ae64149a8b935fe8d79dd5ed7"}, + {file = "bcrypt-4.2.0-cp37-abi3-win32.whl", hash = "sha256:5a1e8aa9b28ae28020a3ac4b053117fb51c57a010b9f969603ed885f23841458"}, + {file = "bcrypt-4.2.0-cp37-abi3-win_amd64.whl", hash = "sha256:8f6ede91359e5df88d1f5c1ef47428a4420136f3ce97763e31b86dd8280fbdf5"}, + {file = "bcrypt-4.2.0-cp39-abi3-macosx_10_12_universal2.whl", hash = "sha256:c52aac18ea1f4a4f65963ea4f9530c306b56ccd0c6f8c8da0c06976e34a6e841"}, + {file = "bcrypt-4.2.0-cp39-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3bbbfb2734f0e4f37c5136130405332640a1e46e6b23e000eeff2ba8d005da68"}, + {file = "bcrypt-4.2.0-cp39-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3413bd60460f76097ee2e0a493ccebe4a7601918219c02f503984f0a7ee0aebe"}, + {file = "bcrypt-4.2.0-cp39-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:8d7bb9c42801035e61c109c345a28ed7e84426ae4865511eb82e913df18f58c2"}, + {file = "bcrypt-4.2.0-cp39-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:3d3a6d28cb2305b43feac298774b997e372e56c7c7afd90a12b3dc49b189151c"}, + {file = "bcrypt-4.2.0-cp39-abi3-musllinux_1_1_aarch64.whl", hash = "sha256:9c1c4ad86351339c5f320ca372dfba6cb6beb25e8efc659bedd918d921956bae"}, + {file = "bcrypt-4.2.0-cp39-abi3-musllinux_1_1_x86_64.whl", hash = "sha256:27fe0f57bb5573104b5a6de5e4153c60814c711b29364c10a75a54bb6d7ff48d"}, + {file = "bcrypt-4.2.0-cp39-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:8ac68872c82f1add6a20bd489870c71b00ebacd2e9134a8aa3f98a0052ab4b0e"}, + {file = "bcrypt-4.2.0-cp39-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:cb2a8ec2bc07d3553ccebf0746bbf3d19426d1c6d1adbd4fa48925f66af7b9e8"}, + {file = "bcrypt-4.2.0-cp39-abi3-win32.whl", hash = "sha256:77800b7147c9dc905db1cba26abe31e504d8247ac73580b4aa179f98e6608f34"}, + {file = "bcrypt-4.2.0-cp39-abi3-win_amd64.whl", hash = "sha256:61ed14326ee023917ecd093ee6ef422a72f3aec6f07e21ea5f10622b735538a9"}, + {file = "bcrypt-4.2.0-pp310-pypy310_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:39e1d30c7233cfc54f5c3f2c825156fe044efdd3e0b9d309512cc514a263ec2a"}, + {file = "bcrypt-4.2.0-pp310-pypy310_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:f4f4acf526fcd1c34e7ce851147deedd4e26e6402369304220250598b26448db"}, + {file = "bcrypt-4.2.0-pp39-pypy39_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:1ff39b78a52cf03fdf902635e4c81e544714861ba3f0efc56558979dd4f09170"}, + {file = "bcrypt-4.2.0-pp39-pypy39_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:373db9abe198e8e2c70d12b479464e0d5092cc122b20ec504097b5f2297ed184"}, + {file = "bcrypt-4.2.0.tar.gz", hash = "sha256:cf69eaf5185fd58f268f805b505ce31f9b9fc2d64b376642164e9244540c1221"}, +] + +[package.extras] +tests = ["pytest (>=3.2.1,!=3.3.0)"] +typecheck = ["mypy"] + +[[package]] +name = "cachetools" +version = "5.5.0" +description = "Extensible memoizing collections and decorators" +optional = false +python-versions = ">=3.7" +files = [ + {file = "cachetools-5.5.0-py3-none-any.whl", hash = "sha256:02134e8439cdc2ffb62023ce1debca2944c3f289d66bb17ead3ab3dede74b292"}, + {file = "cachetools-5.5.0.tar.gz", hash = "sha256:2cc24fb4cbe39633fb7badd9db9ca6295d766d9c2995f245725a46715d050f2a"}, +] + +[[package]] +name = "certifi" +version = "2024.7.4" +description = "Python package for providing Mozilla's CA Bundle." +optional = false +python-versions = ">=3.6" +files = [ + {file = "certifi-2024.7.4-py3-none-any.whl", hash = "sha256:c198e21b1289c2ab85ee4e67bb4b4ef3ead0892059901a8d5b622f24a1101e90"}, + {file = "certifi-2024.7.4.tar.gz", hash = "sha256:5a1e7645bc0ec61a09e26c36f6106dd4cf40c6db3a1fb6352b0244e7fb057c7b"}, +] + +[[package]] +name = "cffi" +version = "1.17.0" +description = "Foreign Function Interface for Python calling C code." +optional = false +python-versions = ">=3.8" +files = [ + {file = "cffi-1.17.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:f9338cc05451f1942d0d8203ec2c346c830f8e86469903d5126c1f0a13a2bcbb"}, + {file = "cffi-1.17.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:a0ce71725cacc9ebf839630772b07eeec220cbb5f03be1399e0457a1464f8e1a"}, + {file = "cffi-1.17.0-cp310-cp310-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c815270206f983309915a6844fe994b2fa47e5d05c4c4cef267c3b30e34dbe42"}, + {file = "cffi-1.17.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d6bdcd415ba87846fd317bee0774e412e8792832e7805938987e4ede1d13046d"}, + {file = "cffi-1.17.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:8a98748ed1a1df4ee1d6f927e151ed6c1a09d5ec21684de879c7ea6aa96f58f2"}, + {file = "cffi-1.17.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:0a048d4f6630113e54bb4b77e315e1ba32a5a31512c31a273807d0027a7e69ab"}, + {file = "cffi-1.17.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:24aa705a5f5bd3a8bcfa4d123f03413de5d86e497435693b638cbffb7d5d8a1b"}, + {file = "cffi-1.17.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:856bf0924d24e7f93b8aee12a3a1095c34085600aa805693fb7f5d1962393206"}, + {file = "cffi-1.17.0-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:4304d4416ff032ed50ad6bb87416d802e67139e31c0bde4628f36a47a3164bfa"}, + {file = "cffi-1.17.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:331ad15c39c9fe9186ceaf87203a9ecf5ae0ba2538c9e898e3a6967e8ad3db6f"}, + {file = "cffi-1.17.0-cp310-cp310-win32.whl", hash = "sha256:669b29a9eca6146465cc574659058ed949748f0809a2582d1f1a324eb91054dc"}, + {file = "cffi-1.17.0-cp310-cp310-win_amd64.whl", hash = "sha256:48b389b1fd5144603d61d752afd7167dfd205973a43151ae5045b35793232aa2"}, + {file = "cffi-1.17.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:c5d97162c196ce54af6700949ddf9409e9833ef1003b4741c2b39ef46f1d9720"}, + {file = "cffi-1.17.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:5ba5c243f4004c750836f81606a9fcb7841f8874ad8f3bf204ff5e56332b72b9"}, + {file = "cffi-1.17.0-cp311-cp311-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:bb9333f58fc3a2296fb1d54576138d4cf5d496a2cc118422bd77835e6ae0b9cb"}, + {file = "cffi-1.17.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:435a22d00ec7d7ea533db494da8581b05977f9c37338c80bc86314bec2619424"}, + {file = "cffi-1.17.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d1df34588123fcc88c872f5acb6f74ae59e9d182a2707097f9e28275ec26a12d"}, + {file = "cffi-1.17.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:df8bb0010fdd0a743b7542589223a2816bdde4d94bb5ad67884348fa2c1c67e8"}, + {file = "cffi-1.17.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a8b5b9712783415695663bd463990e2f00c6750562e6ad1d28e072a611c5f2a6"}, + {file = "cffi-1.17.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:ffef8fd58a36fb5f1196919638f73dd3ae0db1a878982b27a9a5a176ede4ba91"}, + {file = "cffi-1.17.0-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:4e67d26532bfd8b7f7c05d5a766d6f437b362c1bf203a3a5ce3593a645e870b8"}, + {file = "cffi-1.17.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:45f7cd36186db767d803b1473b3c659d57a23b5fa491ad83c6d40f2af58e4dbb"}, + {file = "cffi-1.17.0-cp311-cp311-win32.whl", hash = "sha256:a9015f5b8af1bb6837a3fcb0cdf3b874fe3385ff6274e8b7925d81ccaec3c5c9"}, + {file = "cffi-1.17.0-cp311-cp311-win_amd64.whl", hash = "sha256:b50aaac7d05c2c26dfd50c3321199f019ba76bb650e346a6ef3616306eed67b0"}, + {file = "cffi-1.17.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:aec510255ce690d240f7cb23d7114f6b351c733a74c279a84def763660a2c3bc"}, + {file = "cffi-1.17.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:2770bb0d5e3cc0e31e7318db06efcbcdb7b31bcb1a70086d3177692a02256f59"}, + {file = "cffi-1.17.0-cp312-cp312-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:db9a30ec064129d605d0f1aedc93e00894b9334ec74ba9c6bdd08147434b33eb"}, + {file = "cffi-1.17.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a47eef975d2b8b721775a0fa286f50eab535b9d56c70a6e62842134cf7841195"}, + {file = "cffi-1.17.0-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f3e0992f23bbb0be00a921eae5363329253c3b86287db27092461c887b791e5e"}, + {file = "cffi-1.17.0-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:6107e445faf057c118d5050560695e46d272e5301feffda3c41849641222a828"}, + {file = "cffi-1.17.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:eb862356ee9391dc5a0b3cbc00f416b48c1b9a52d252d898e5b7696a5f9fe150"}, + {file = "cffi-1.17.0-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:c1c13185b90bbd3f8b5963cd8ce7ad4ff441924c31e23c975cb150e27c2bf67a"}, + {file = "cffi-1.17.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:17c6d6d3260c7f2d94f657e6872591fe8733872a86ed1345bda872cfc8c74885"}, + {file = "cffi-1.17.0-cp312-cp312-win32.whl", hash = "sha256:c3b8bd3133cd50f6b637bb4322822c94c5ce4bf0d724ed5ae70afce62187c492"}, + {file = "cffi-1.17.0-cp312-cp312-win_amd64.whl", hash = "sha256:dca802c8db0720ce1c49cce1149ff7b06e91ba15fa84b1d59144fef1a1bc7ac2"}, + {file = "cffi-1.17.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:6ce01337d23884b21c03869d2f68c5523d43174d4fc405490eb0091057943118"}, + {file = "cffi-1.17.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:cab2eba3830bf4f6d91e2d6718e0e1c14a2f5ad1af68a89d24ace0c6b17cced7"}, + {file = "cffi-1.17.0-cp313-cp313-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:14b9cbc8f7ac98a739558eb86fabc283d4d564dafed50216e7f7ee62d0d25377"}, + {file = "cffi-1.17.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b00e7bcd71caa0282cbe3c90966f738e2db91e64092a877c3ff7f19a1628fdcb"}, + {file = "cffi-1.17.0-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:41f4915e09218744d8bae14759f983e466ab69b178de38066f7579892ff2a555"}, + {file = "cffi-1.17.0-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e4760a68cab57bfaa628938e9c2971137e05ce48e762a9cb53b76c9b569f1204"}, + {file = "cffi-1.17.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:011aff3524d578a9412c8b3cfaa50f2c0bd78e03eb7af7aa5e0df59b158efb2f"}, + {file = "cffi-1.17.0-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:a003ac9edc22d99ae1286b0875c460351f4e101f8c9d9d2576e78d7e048f64e0"}, + {file = "cffi-1.17.0-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:ef9528915df81b8f4c7612b19b8628214c65c9b7f74db2e34a646a0a2a0da2d4"}, + {file = "cffi-1.17.0-cp313-cp313-win32.whl", hash = "sha256:70d2aa9fb00cf52034feac4b913181a6e10356019b18ef89bc7c12a283bf5f5a"}, + {file = "cffi-1.17.0-cp313-cp313-win_amd64.whl", hash = "sha256:b7b6ea9e36d32582cda3465f54c4b454f62f23cb083ebc7a94e2ca6ef011c3a7"}, + {file = "cffi-1.17.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:964823b2fc77b55355999ade496c54dde161c621cb1f6eac61dc30ed1b63cd4c"}, + {file = "cffi-1.17.0-cp38-cp38-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:516a405f174fd3b88829eabfe4bb296ac602d6a0f68e0d64d5ac9456194a5b7e"}, + {file = "cffi-1.17.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:dec6b307ce928e8e112a6bb9921a1cb00a0e14979bf28b98e084a4b8a742bd9b"}, + {file = "cffi-1.17.0-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e4094c7b464cf0a858e75cd14b03509e84789abf7b79f8537e6a72152109c76e"}, + {file = "cffi-1.17.0-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2404f3de742f47cb62d023f0ba7c5a916c9c653d5b368cc966382ae4e57da401"}, + {file = "cffi-1.17.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3aa9d43b02a0c681f0bfbc12d476d47b2b2b6a3f9287f11ee42989a268a1833c"}, + {file = "cffi-1.17.0-cp38-cp38-win32.whl", hash = "sha256:0bb15e7acf8ab35ca8b24b90af52c8b391690ef5c4aec3d31f38f0d37d2cc499"}, + {file = "cffi-1.17.0-cp38-cp38-win_amd64.whl", hash = "sha256:93a7350f6706b31f457c1457d3a3259ff9071a66f312ae64dc024f049055f72c"}, + {file = "cffi-1.17.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:1a2ddbac59dc3716bc79f27906c010406155031a1c801410f1bafff17ea304d2"}, + {file = "cffi-1.17.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:6327b572f5770293fc062a7ec04160e89741e8552bf1c358d1a23eba68166759"}, + {file = "cffi-1.17.0-cp39-cp39-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:dbc183e7bef690c9abe5ea67b7b60fdbca81aa8da43468287dae7b5c046107d4"}, + {file = "cffi-1.17.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5bdc0f1f610d067c70aa3737ed06e2726fd9d6f7bfee4a351f4c40b6831f4e82"}, + {file = "cffi-1.17.0-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:6d872186c1617d143969defeadac5a904e6e374183e07977eedef9c07c8953bf"}, + {file = "cffi-1.17.0-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:0d46ee4764b88b91f16661a8befc6bfb24806d885e27436fdc292ed7e6f6d058"}, + {file = "cffi-1.17.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6f76a90c345796c01d85e6332e81cab6d70de83b829cf1d9762d0a3da59c7932"}, + {file = "cffi-1.17.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:0e60821d312f99d3e1569202518dddf10ae547e799d75aef3bca3a2d9e8ee693"}, + {file = "cffi-1.17.0-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:eb09b82377233b902d4c3fbeeb7ad731cdab579c6c6fda1f763cd779139e47c3"}, + {file = "cffi-1.17.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:24658baf6224d8f280e827f0a50c46ad819ec8ba380a42448e24459daf809cf4"}, + {file = "cffi-1.17.0-cp39-cp39-win32.whl", hash = "sha256:0fdacad9e0d9fc23e519efd5ea24a70348305e8d7d85ecbb1a5fa66dc834e7fb"}, + {file = "cffi-1.17.0-cp39-cp39-win_amd64.whl", hash = "sha256:7cbc78dc018596315d4e7841c8c3a7ae31cc4d638c9b627f87d52e8abaaf2d29"}, + {file = "cffi-1.17.0.tar.gz", hash = "sha256:f3157624b7558b914cb039fd1af735e5e8049a87c817cc215109ad1c8779df76"}, +] + +[package.dependencies] +pycparser = "*" + +[[package]] +name = "charset-normalizer" +version = "3.3.2" +description = "The Real First Universal Charset Detector. Open, modern and actively maintained alternative to Chardet." +optional = false +python-versions = ">=3.7.0" +files = [ + {file = "charset-normalizer-3.3.2.tar.gz", hash = "sha256:f30c3cb33b24454a82faecaf01b19c18562b1e89558fb6c56de4d9118a032fd5"}, + {file = "charset_normalizer-3.3.2-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:25baf083bf6f6b341f4121c2f3c548875ee6f5339300e08be3f2b2ba1721cdd3"}, + {file = "charset_normalizer-3.3.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:06435b539f889b1f6f4ac1758871aae42dc3a8c0e24ac9e60c2384973ad73027"}, + {file = "charset_normalizer-3.3.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:9063e24fdb1e498ab71cb7419e24622516c4a04476b17a2dab57e8baa30d6e03"}, + {file = "charset_normalizer-3.3.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6897af51655e3691ff853668779c7bad41579facacf5fd7253b0133308cf000d"}, + {file = "charset_normalizer-3.3.2-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1d3193f4a680c64b4b6a9115943538edb896edc190f0b222e73761716519268e"}, + {file = "charset_normalizer-3.3.2-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:cd70574b12bb8a4d2aaa0094515df2463cb429d8536cfb6c7ce983246983e5a6"}, + {file = "charset_normalizer-3.3.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8465322196c8b4d7ab6d1e049e4c5cb460d0394da4a27d23cc242fbf0034b6b5"}, + {file = "charset_normalizer-3.3.2-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a9a8e9031d613fd2009c182b69c7b2c1ef8239a0efb1df3f7c8da66d5dd3d537"}, + {file = "charset_normalizer-3.3.2-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:beb58fe5cdb101e3a055192ac291b7a21e3b7ef4f67fa1d74e331a7f2124341c"}, + {file = "charset_normalizer-3.3.2-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:e06ed3eb3218bc64786f7db41917d4e686cc4856944f53d5bdf83a6884432e12"}, + {file = "charset_normalizer-3.3.2-cp310-cp310-musllinux_1_1_ppc64le.whl", hash = "sha256:2e81c7b9c8979ce92ed306c249d46894776a909505d8f5a4ba55b14206e3222f"}, + {file = "charset_normalizer-3.3.2-cp310-cp310-musllinux_1_1_s390x.whl", hash = "sha256:572c3763a264ba47b3cf708a44ce965d98555f618ca42c926a9c1616d8f34269"}, + {file = "charset_normalizer-3.3.2-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:fd1abc0d89e30cc4e02e4064dc67fcc51bd941eb395c502aac3ec19fab46b519"}, + {file = "charset_normalizer-3.3.2-cp310-cp310-win32.whl", hash = "sha256:3d47fa203a7bd9c5b6cee4736ee84ca03b8ef23193c0d1ca99b5089f72645c73"}, + {file = "charset_normalizer-3.3.2-cp310-cp310-win_amd64.whl", hash = "sha256:10955842570876604d404661fbccbc9c7e684caf432c09c715ec38fbae45ae09"}, + {file = "charset_normalizer-3.3.2-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:802fe99cca7457642125a8a88a084cef28ff0cf9407060f7b93dca5aa25480db"}, + {file = "charset_normalizer-3.3.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:573f6eac48f4769d667c4442081b1794f52919e7edada77495aaed9236d13a96"}, + {file = "charset_normalizer-3.3.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:549a3a73da901d5bc3ce8d24e0600d1fa85524c10287f6004fbab87672bf3e1e"}, + {file = "charset_normalizer-3.3.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f27273b60488abe721a075bcca6d7f3964f9f6f067c8c4c605743023d7d3944f"}, + {file = "charset_normalizer-3.3.2-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1ceae2f17a9c33cb48e3263960dc5fc8005351ee19db217e9b1bb15d28c02574"}, + {file = "charset_normalizer-3.3.2-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:65f6f63034100ead094b8744b3b97965785388f308a64cf8d7c34f2f2e5be0c4"}, + {file = "charset_normalizer-3.3.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:753f10e867343b4511128c6ed8c82f7bec3bd026875576dfd88483c5c73b2fd8"}, + {file = "charset_normalizer-3.3.2-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4a78b2b446bd7c934f5dcedc588903fb2f5eec172f3d29e52a9096a43722adfc"}, + {file = "charset_normalizer-3.3.2-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:e537484df0d8f426ce2afb2d0f8e1c3d0b114b83f8850e5f2fbea0e797bd82ae"}, + {file = "charset_normalizer-3.3.2-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:eb6904c354526e758fda7167b33005998fb68c46fbc10e013ca97f21ca5c8887"}, + {file = "charset_normalizer-3.3.2-cp311-cp311-musllinux_1_1_ppc64le.whl", hash = "sha256:deb6be0ac38ece9ba87dea880e438f25ca3eddfac8b002a2ec3d9183a454e8ae"}, + {file = "charset_normalizer-3.3.2-cp311-cp311-musllinux_1_1_s390x.whl", hash = "sha256:4ab2fe47fae9e0f9dee8c04187ce5d09f48eabe611be8259444906793ab7cbce"}, + {file = "charset_normalizer-3.3.2-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:80402cd6ee291dcb72644d6eac93785fe2c8b9cb30893c1af5b8fdd753b9d40f"}, + {file = "charset_normalizer-3.3.2-cp311-cp311-win32.whl", hash = "sha256:7cd13a2e3ddeed6913a65e66e94b51d80a041145a026c27e6bb76c31a853c6ab"}, + {file = "charset_normalizer-3.3.2-cp311-cp311-win_amd64.whl", hash = "sha256:663946639d296df6a2bb2aa51b60a2454ca1cb29835324c640dafb5ff2131a77"}, + {file = "charset_normalizer-3.3.2-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:0b2b64d2bb6d3fb9112bafa732def486049e63de9618b5843bcdd081d8144cd8"}, + {file = "charset_normalizer-3.3.2-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:ddbb2551d7e0102e7252db79ba445cdab71b26640817ab1e3e3648dad515003b"}, + {file = "charset_normalizer-3.3.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:55086ee1064215781fff39a1af09518bc9255b50d6333f2e4c74ca09fac6a8f6"}, + {file = "charset_normalizer-3.3.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8f4a014bc36d3c57402e2977dada34f9c12300af536839dc38c0beab8878f38a"}, + {file = "charset_normalizer-3.3.2-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a10af20b82360ab00827f916a6058451b723b4e65030c5a18577c8b2de5b3389"}, + {file = "charset_normalizer-3.3.2-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:8d756e44e94489e49571086ef83b2bb8ce311e730092d2c34ca8f7d925cb20aa"}, + {file = "charset_normalizer-3.3.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:90d558489962fd4918143277a773316e56c72da56ec7aa3dc3dbbe20fdfed15b"}, + {file = "charset_normalizer-3.3.2-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6ac7ffc7ad6d040517be39eb591cac5ff87416c2537df6ba3cba3bae290c0fed"}, + {file = "charset_normalizer-3.3.2-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:7ed9e526742851e8d5cc9e6cf41427dfc6068d4f5a3bb03659444b4cabf6bc26"}, + {file = "charset_normalizer-3.3.2-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:8bdb58ff7ba23002a4c5808d608e4e6c687175724f54a5dade5fa8c67b604e4d"}, + {file = "charset_normalizer-3.3.2-cp312-cp312-musllinux_1_1_ppc64le.whl", hash = "sha256:6b3251890fff30ee142c44144871185dbe13b11bab478a88887a639655be1068"}, + {file = "charset_normalizer-3.3.2-cp312-cp312-musllinux_1_1_s390x.whl", hash = "sha256:b4a23f61ce87adf89be746c8a8974fe1c823c891d8f86eb218bb957c924bb143"}, + {file = "charset_normalizer-3.3.2-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:efcb3f6676480691518c177e3b465bcddf57cea040302f9f4e6e191af91174d4"}, + {file = "charset_normalizer-3.3.2-cp312-cp312-win32.whl", hash = "sha256:d965bba47ddeec8cd560687584e88cf699fd28f192ceb452d1d7ee807c5597b7"}, + {file = "charset_normalizer-3.3.2-cp312-cp312-win_amd64.whl", hash = "sha256:96b02a3dc4381e5494fad39be677abcb5e6634bf7b4fa83a6dd3112607547001"}, + {file = "charset_normalizer-3.3.2-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:95f2a5796329323b8f0512e09dbb7a1860c46a39da62ecb2324f116fa8fdc85c"}, + {file = "charset_normalizer-3.3.2-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c002b4ffc0be611f0d9da932eb0f704fe2602a9a949d1f738e4c34c75b0863d5"}, + {file = "charset_normalizer-3.3.2-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a981a536974bbc7a512cf44ed14938cf01030a99e9b3a06dd59578882f06f985"}, + {file = "charset_normalizer-3.3.2-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3287761bc4ee9e33561a7e058c72ac0938c4f57fe49a09eae428fd88aafe7bb6"}, + {file = "charset_normalizer-3.3.2-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:42cb296636fcc8b0644486d15c12376cb9fa75443e00fb25de0b8602e64c1714"}, + {file = "charset_normalizer-3.3.2-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0a55554a2fa0d408816b3b5cedf0045f4b8e1a6065aec45849de2d6f3f8e9786"}, + {file = "charset_normalizer-3.3.2-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:c083af607d2515612056a31f0a8d9e0fcb5876b7bfc0abad3ecd275bc4ebc2d5"}, + {file = "charset_normalizer-3.3.2-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:87d1351268731db79e0f8e745d92493ee2841c974128ef629dc518b937d9194c"}, + {file = "charset_normalizer-3.3.2-cp37-cp37m-musllinux_1_1_ppc64le.whl", hash = "sha256:bd8f7df7d12c2db9fab40bdd87a7c09b1530128315d047a086fa3ae3435cb3a8"}, + {file = "charset_normalizer-3.3.2-cp37-cp37m-musllinux_1_1_s390x.whl", hash = "sha256:c180f51afb394e165eafe4ac2936a14bee3eb10debc9d9e4db8958fe36afe711"}, + {file = "charset_normalizer-3.3.2-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:8c622a5fe39a48f78944a87d4fb8a53ee07344641b0562c540d840748571b811"}, + {file = "charset_normalizer-3.3.2-cp37-cp37m-win32.whl", hash = "sha256:db364eca23f876da6f9e16c9da0df51aa4f104a972735574842618b8c6d999d4"}, + {file = "charset_normalizer-3.3.2-cp37-cp37m-win_amd64.whl", hash = "sha256:86216b5cee4b06df986d214f664305142d9c76df9b6512be2738aa72a2048f99"}, + {file = "charset_normalizer-3.3.2-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:6463effa3186ea09411d50efc7d85360b38d5f09b870c48e4600f63af490e56a"}, + {file = "charset_normalizer-3.3.2-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:6c4caeef8fa63d06bd437cd4bdcf3ffefe6738fb1b25951440d80dc7df8c03ac"}, + {file = "charset_normalizer-3.3.2-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:37e55c8e51c236f95b033f6fb391d7d7970ba5fe7ff453dad675e88cf303377a"}, + {file = "charset_normalizer-3.3.2-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:fb69256e180cb6c8a894fee62b3afebae785babc1ee98b81cdf68bbca1987f33"}, + {file = "charset_normalizer-3.3.2-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ae5f4161f18c61806f411a13b0310bea87f987c7d2ecdbdaad0e94eb2e404238"}, + {file = "charset_normalizer-3.3.2-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b2b0a0c0517616b6869869f8c581d4eb2dd83a4d79e0ebcb7d373ef9956aeb0a"}, + {file = "charset_normalizer-3.3.2-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:45485e01ff4d3630ec0d9617310448a8702f70e9c01906b0d0118bdf9d124cf2"}, + {file = "charset_normalizer-3.3.2-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:eb00ed941194665c332bf8e078baf037d6c35d7c4f3102ea2d4f16ca94a26dc8"}, + {file = "charset_normalizer-3.3.2-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:2127566c664442652f024c837091890cb1942c30937add288223dc895793f898"}, + {file = "charset_normalizer-3.3.2-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:a50aebfa173e157099939b17f18600f72f84eed3049e743b68ad15bd69b6bf99"}, + {file = "charset_normalizer-3.3.2-cp38-cp38-musllinux_1_1_ppc64le.whl", hash = "sha256:4d0d1650369165a14e14e1e47b372cfcb31d6ab44e6e33cb2d4e57265290044d"}, + {file = "charset_normalizer-3.3.2-cp38-cp38-musllinux_1_1_s390x.whl", hash = "sha256:923c0c831b7cfcb071580d3f46c4baf50f174be571576556269530f4bbd79d04"}, + {file = "charset_normalizer-3.3.2-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:06a81e93cd441c56a9b65d8e1d043daeb97a3d0856d177d5c90ba85acb3db087"}, + {file = "charset_normalizer-3.3.2-cp38-cp38-win32.whl", hash = "sha256:6ef1d82a3af9d3eecdba2321dc1b3c238245d890843e040e41e470ffa64c3e25"}, + {file = "charset_normalizer-3.3.2-cp38-cp38-win_amd64.whl", hash = "sha256:eb8821e09e916165e160797a6c17edda0679379a4be5c716c260e836e122f54b"}, + {file = "charset_normalizer-3.3.2-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:c235ebd9baae02f1b77bcea61bce332cb4331dc3617d254df3323aa01ab47bd4"}, + {file = "charset_normalizer-3.3.2-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:5b4c145409bef602a690e7cfad0a15a55c13320ff7a3ad7ca59c13bb8ba4d45d"}, + {file = "charset_normalizer-3.3.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:68d1f8a9e9e37c1223b656399be5d6b448dea850bed7d0f87a8311f1ff3dabb0"}, + {file = "charset_normalizer-3.3.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:22afcb9f253dac0696b5a4be4a1c0f8762f8239e21b99680099abd9b2b1b2269"}, + {file = "charset_normalizer-3.3.2-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e27ad930a842b4c5eb8ac0016b0a54f5aebbe679340c26101df33424142c143c"}, + {file = "charset_normalizer-3.3.2-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:1f79682fbe303db92bc2b1136016a38a42e835d932bab5b3b1bfcfbf0640e519"}, + {file = "charset_normalizer-3.3.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b261ccdec7821281dade748d088bb6e9b69e6d15b30652b74cbbac25e280b796"}, + {file = "charset_normalizer-3.3.2-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:122c7fa62b130ed55f8f285bfd56d5f4b4a5b503609d181f9ad85e55c89f4185"}, + {file = "charset_normalizer-3.3.2-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:d0eccceffcb53201b5bfebb52600a5fb483a20b61da9dbc885f8b103cbe7598c"}, + {file = "charset_normalizer-3.3.2-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:9f96df6923e21816da7e0ad3fd47dd8f94b2a5ce594e00677c0013018b813458"}, + {file = "charset_normalizer-3.3.2-cp39-cp39-musllinux_1_1_ppc64le.whl", hash = "sha256:7f04c839ed0b6b98b1a7501a002144b76c18fb1c1850c8b98d458ac269e26ed2"}, + {file = "charset_normalizer-3.3.2-cp39-cp39-musllinux_1_1_s390x.whl", hash = "sha256:34d1c8da1e78d2e001f363791c98a272bb734000fcef47a491c1e3b0505657a8"}, + {file = "charset_normalizer-3.3.2-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:ff8fa367d09b717b2a17a052544193ad76cd49979c805768879cb63d9ca50561"}, + {file = "charset_normalizer-3.3.2-cp39-cp39-win32.whl", hash = "sha256:aed38f6e4fb3f5d6bf81bfa990a07806be9d83cf7bacef998ab1a9bd660a581f"}, + {file = "charset_normalizer-3.3.2-cp39-cp39-win_amd64.whl", hash = "sha256:b01b88d45a6fcb69667cd6d2f7a9aeb4bf53760d7fc536bf679ec94fe9f3ff3d"}, + {file = "charset_normalizer-3.3.2-py3-none-any.whl", hash = "sha256:3e4d1f6587322d2788836a99c69062fbb091331ec940e02d12d179c1d53e25fc"}, +] + +[[package]] +name = "colorama" +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" +files = [ + {file = "colorama-0.4.6-py2.py3-none-any.whl", hash = "sha256:4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6"}, + {file = "colorama-0.4.6.tar.gz", hash = "sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44"}, +] + +[[package]] +name = "construct" +version = "2.10.70" +description = "A powerful declarative symmetric parser/builder for binary data" +optional = false +python-versions = ">=3.6" +files = [ + {file = "construct-2.10.70-py3-none-any.whl", hash = "sha256:c80be81ef595a1a821ec69dc16099550ed22197615f4320b57cc9ce2a672cb30"}, + {file = "construct-2.10.70.tar.gz", hash = "sha256:4d2472f9684731e58cc9c56c463be63baa1447d674e0d66aeb5627b22f512c29"}, +] + +[package.extras] +extras = ["arrow", "cloudpickle", "cryptography", "lz4", "numpy", "ruamel.yaml"] + +[[package]] +name = "cryptography" +version = "43.0.0" +description = "cryptography is a package which provides cryptographic recipes and primitives to Python developers." +optional = false +python-versions = ">=3.7" +files = [ + {file = "cryptography-43.0.0-cp37-abi3-macosx_10_9_universal2.whl", hash = "sha256:64c3f16e2a4fc51c0d06af28441881f98c5d91009b8caaff40cf3548089e9c74"}, + {file = "cryptography-43.0.0-cp37-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3dcdedae5c7710b9f97ac6bba7e1052b95c7083c9d0e9df96e02a1932e777895"}, + {file = "cryptography-43.0.0-cp37-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3d9a1eca329405219b605fac09ecfc09ac09e595d6def650a437523fcd08dd22"}, + {file = "cryptography-43.0.0-cp37-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:ea9e57f8ea880eeea38ab5abf9fbe39f923544d7884228ec67d666abd60f5a47"}, + {file = "cryptography-43.0.0-cp37-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:9a8d6802e0825767476f62aafed40532bd435e8a5f7d23bd8b4f5fd04cc80ecf"}, + {file = "cryptography-43.0.0-cp37-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:cc70b4b581f28d0a254d006f26949245e3657d40d8857066c2ae22a61222ef55"}, + {file = "cryptography-43.0.0-cp37-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:4a997df8c1c2aae1e1e5ac49c2e4f610ad037fc5a3aadc7b64e39dea42249431"}, + {file = "cryptography-43.0.0-cp37-abi3-win32.whl", hash = "sha256:6e2b11c55d260d03a8cf29ac9b5e0608d35f08077d8c087be96287f43af3ccdc"}, + {file = "cryptography-43.0.0-cp37-abi3-win_amd64.whl", hash = "sha256:31e44a986ceccec3d0498e16f3d27b2ee5fdf69ce2ab89b52eaad1d2f33d8778"}, + {file = "cryptography-43.0.0-cp39-abi3-macosx_10_9_universal2.whl", hash = "sha256:7b3f5fe74a5ca32d4d0f302ffe6680fcc5c28f8ef0dc0ae8f40c0f3a1b4fca66"}, + {file = "cryptography-43.0.0-cp39-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ac1955ce000cb29ab40def14fd1bbfa7af2017cca696ee696925615cafd0dce5"}, + {file = "cryptography-43.0.0-cp39-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:299d3da8e00b7e2b54bb02ef58d73cd5f55fb31f33ebbf33bd00d9aa6807df7e"}, + {file = "cryptography-43.0.0-cp39-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:ee0c405832ade84d4de74b9029bedb7b31200600fa524d218fc29bfa371e97f5"}, + {file = "cryptography-43.0.0-cp39-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:cb013933d4c127349b3948aa8aaf2f12c0353ad0eccd715ca789c8a0f671646f"}, + {file = "cryptography-43.0.0-cp39-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:fdcb265de28585de5b859ae13e3846a8e805268a823a12a4da2597f1f5afc9f0"}, + {file = "cryptography-43.0.0-cp39-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:2905ccf93a8a2a416f3ec01b1a7911c3fe4073ef35640e7ee5296754e30b762b"}, + {file = "cryptography-43.0.0-cp39-abi3-win32.whl", hash = "sha256:47ca71115e545954e6c1d207dd13461ab81f4eccfcb1345eac874828b5e3eaaf"}, + {file = "cryptography-43.0.0-cp39-abi3-win_amd64.whl", hash = "sha256:0663585d02f76929792470451a5ba64424acc3cd5227b03921dab0e2f27b1709"}, + {file = "cryptography-43.0.0-pp310-pypy310_pp73-macosx_10_9_x86_64.whl", hash = "sha256:2c6d112bf61c5ef44042c253e4859b3cbbb50df2f78fa8fae6747a7814484a70"}, + {file = "cryptography-43.0.0-pp310-pypy310_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:844b6d608374e7d08f4f6e6f9f7b951f9256db41421917dfb2d003dde4cd6b66"}, + {file = "cryptography-43.0.0-pp310-pypy310_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:51956cf8730665e2bdf8ddb8da0056f699c1a5715648c1b0144670c1ba00b48f"}, + {file = "cryptography-43.0.0-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:aae4d918f6b180a8ab8bf6511a419473d107df4dbb4225c7b48c5c9602c38c7f"}, + {file = "cryptography-43.0.0-pp39-pypy39_pp73-macosx_10_9_x86_64.whl", hash = "sha256:232ce02943a579095a339ac4b390fbbe97f5b5d5d107f8a08260ea2768be8cc2"}, + {file = "cryptography-43.0.0-pp39-pypy39_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:5bcb8a5620008a8034d39bce21dc3e23735dfdb6a33a06974739bfa04f853947"}, + {file = "cryptography-43.0.0-pp39-pypy39_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:08a24a7070b2b6804c1940ff0f910ff728932a9d0e80e7814234269f9d46d069"}, + {file = "cryptography-43.0.0-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:e9c5266c432a1e23738d178e51c2c7a5e2ddf790f248be939448c0ba2021f9d1"}, + {file = "cryptography-43.0.0.tar.gz", hash = "sha256:b88075ada2d51aa9f18283532c9f60e72170041bba88d7f37e49cbb10275299e"}, +] + +[package.dependencies] +cffi = {version = ">=1.12", markers = "platform_python_implementation != \"PyPy\""} + +[package.extras] +docs = ["sphinx (>=5.3.0)", "sphinx-rtd-theme (>=1.1.1)"] +docstest = ["pyenchant (>=1.6.11)", "readme-renderer", "sphinxcontrib-spelling (>=4.0.1)"] +nox = ["nox"] +pep8test = ["check-sdist", "click", "mypy", "ruff"] +sdist = ["build"] +ssh = ["bcrypt (>=3.1.5)"] +test = ["certifi", "cryptography-vectors (==43.0.0)", "pretend", "pytest (>=6.2.0)", "pytest-benchmark", "pytest-cov", "pytest-xdist"] +test-randomorder = ["pytest-randomly"] + +[[package]] +name = "debtcollector" +version = "3.0.0" +description = "A collection of Python deprecation patterns and strategies that help you collect your technical debt in a non-destructive manner." +optional = false +python-versions = ">=3.8" +files = [ + {file = "debtcollector-3.0.0-py3-none-any.whl", hash = "sha256:46f9dacbe8ce49c47ebf2bf2ec878d50c9443dfae97cc7b8054be684e54c3e91"}, + {file = "debtcollector-3.0.0.tar.gz", hash = "sha256:2a8917d25b0e1f1d0d365d3c1c6ecfc7a522b1e9716e8a1a4a915126f7ccea6f"}, +] + +[package.dependencies] +wrapt = ">=1.7.0" + +[[package]] +name = "decorator" +version = "5.1.1" +description = "Decorators for Humans" +optional = false +python-versions = ">=3.5" +files = [ + {file = "decorator-5.1.1-py3-none-any.whl", hash = "sha256:b8c3f85900b9dc423225913c5aace94729fe1fa9763b38939a95226f02d37186"}, + {file = "decorator-5.1.1.tar.gz", hash = "sha256:637996211036b6385ef91435e4fae22989472f9d571faba8927ba8253acbc330"}, +] + +[[package]] +name = "dnspython" +version = "2.6.1" +description = "DNS toolkit" +optional = false +python-versions = ">=3.8" +files = [ + {file = "dnspython-2.6.1-py3-none-any.whl", hash = "sha256:5ef3b9680161f6fa89daf8ad451b5f1a33b18ae8a1c6778cdf4b43f08c0a6e50"}, + {file = "dnspython-2.6.1.tar.gz", hash = "sha256:e8f0f9c23a7b7cb99ded64e6c3a6f3e701d78f50c55e002b839dea7225cff7cc"}, +] + +[package.extras] +dev = ["black (>=23.1.0)", "coverage (>=7.0)", "flake8 (>=7)", "mypy (>=1.8)", "pylint (>=3)", "pytest (>=7.4)", "pytest-cov (>=4.1.0)", "sphinx (>=7.2.0)", "twine (>=4.0.0)", "wheel (>=0.42.0)"] +dnssec = ["cryptography (>=41)"] +doh = ["h2 (>=4.1.0)", "httpcore (>=1.0.0)", "httpx (>=0.26.0)"] +doq = ["aioquic (>=0.9.25)"] +idna = ["idna (>=3.6)"] +trio = ["trio (>=0.23)"] +wmi = ["wmi (>=1.5.1)"] + +[[package]] +name = "dogpile-cache" +version = "1.3.3" +description = "A caching front-end based on the Dogpile lock." +optional = false +python-versions = ">=3.8" +files = [ + {file = "dogpile.cache-1.3.3-py3-none-any.whl", hash = "sha256:5e211c4902ebdf88c678d268e22454b41e68071632daa9402d8ee24e825ed8ca"}, + {file = "dogpile.cache-1.3.3.tar.gz", hash = "sha256:f84b8ed0b0fb297d151055447fa8dcaf7bae566d4dbdefecdcc1f37662ab588b"}, +] + +[package.dependencies] +decorator = ">=4.0.0" +stevedore = ">=3.0.0" + +[package.extras] +pifpaf = ["pifpaf (>=2.5.0)", "setuptools"] + +[[package]] +name = "eventlet" +version = "0.36.1" +description = "Highly concurrent networking library" +optional = false +python-versions = ">=3.7" +files = [ + {file = "eventlet-0.36.1-py3-none-any.whl", hash = "sha256:e42d0f73b718e654c223a033b8692d1a94d778a6c1deb6c3d21442746f3f727f"}, + {file = "eventlet-0.36.1.tar.gz", hash = "sha256:d227fe76a63d9e6a6cef53beb8ad0b2dc40a5e7737c801f4b474cfae1db07bc5"}, +] + +[package.dependencies] +dnspython = ">=1.15.0" +greenlet = ">=1.0" + +[package.extras] +dev = ["black", "build", "commitizen", "isort", "pip-tools", "pre-commit", "twine"] + +[[package]] +name = "fasteners" +version = "0.19" +description = "A python package that provides useful locks" +optional = false +python-versions = ">=3.6" +files = [ + {file = "fasteners-0.19-py3-none-any.whl", hash = "sha256:758819cb5d94cdedf4e836988b74de396ceacb8e2794d21f82d131fd9ee77237"}, + {file = "fasteners-0.19.tar.gz", hash = "sha256:b4f37c3ac52d8a445af3a66bce57b33b5e90b97c696b7b984f530cf8f0ded09c"}, +] + +[[package]] +name = "futurist" +version = "3.0.0" +description = "Useful additions to futures, from the future." +optional = false +python-versions = ">=3.8" +files = [ + {file = "futurist-3.0.0-py3-none-any.whl", hash = "sha256:645565803423c907557d59f82b2e7f33d87fd483316414466d059a0fa5aa5fc9"}, + {file = "futurist-3.0.0.tar.gz", hash = "sha256:6422011792414c39228e114bec5494303aaf06dcd335e4f8dd4f907f78a41f79"}, +] + +[[package]] +name = "greenlet" +version = "3.0.3" +description = "Lightweight in-process concurrent programming" +optional = false +python-versions = ">=3.7" +files = [ + {file = "greenlet-3.0.3-cp310-cp310-macosx_11_0_universal2.whl", hash = "sha256:9da2bd29ed9e4f15955dd1595ad7bc9320308a3b766ef7f837e23ad4b4aac31a"}, + {file = "greenlet-3.0.3-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d353cadd6083fdb056bb46ed07e4340b0869c305c8ca54ef9da3421acbdf6881"}, + {file = "greenlet-3.0.3-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:dca1e2f3ca00b84a396bc1bce13dd21f680f035314d2379c4160c98153b2059b"}, + {file = "greenlet-3.0.3-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3ed7fb269f15dc662787f4119ec300ad0702fa1b19d2135a37c2c4de6fadfd4a"}, + {file = "greenlet-3.0.3-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dd4f49ae60e10adbc94b45c0b5e6a179acc1736cf7a90160b404076ee283cf83"}, + {file = "greenlet-3.0.3-cp310-cp310-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:73a411ef564e0e097dbe7e866bb2dda0f027e072b04da387282b02c308807405"}, + {file = "greenlet-3.0.3-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:7f362975f2d179f9e26928c5b517524e89dd48530a0202570d55ad6ca5d8a56f"}, + {file = "greenlet-3.0.3-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:649dde7de1a5eceb258f9cb00bdf50e978c9db1b996964cd80703614c86495eb"}, + {file = "greenlet-3.0.3-cp310-cp310-win_amd64.whl", hash = "sha256:68834da854554926fbedd38c76e60c4a2e3198c6fbed520b106a8986445caaf9"}, + {file = "greenlet-3.0.3-cp311-cp311-macosx_11_0_universal2.whl", hash = "sha256:b1b5667cced97081bf57b8fa1d6bfca67814b0afd38208d52538316e9422fc61"}, + {file = "greenlet-3.0.3-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:52f59dd9c96ad2fc0d5724107444f76eb20aaccb675bf825df6435acb7703559"}, + {file = "greenlet-3.0.3-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:afaff6cf5200befd5cec055b07d1c0a5a06c040fe5ad148abcd11ba6ab9b114e"}, + {file = "greenlet-3.0.3-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:fe754d231288e1e64323cfad462fcee8f0288654c10bdf4f603a39ed923bef33"}, + {file = "greenlet-3.0.3-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2797aa5aedac23af156bbb5a6aa2cd3427ada2972c828244eb7d1b9255846379"}, + {file = "greenlet-3.0.3-cp311-cp311-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:b7f009caad047246ed379e1c4dbcb8b020f0a390667ea74d2387be2998f58a22"}, + {file = "greenlet-3.0.3-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:c5e1536de2aad7bf62e27baf79225d0d64360d4168cf2e6becb91baf1ed074f3"}, + {file = "greenlet-3.0.3-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:894393ce10ceac937e56ec00bb71c4c2f8209ad516e96033e4b3b1de270e200d"}, + {file = "greenlet-3.0.3-cp311-cp311-win_amd64.whl", hash = "sha256:1ea188d4f49089fc6fb283845ab18a2518d279c7cd9da1065d7a84e991748728"}, + {file = "greenlet-3.0.3-cp312-cp312-macosx_11_0_universal2.whl", hash = "sha256:70fb482fdf2c707765ab5f0b6655e9cfcf3780d8d87355a063547b41177599be"}, + {file = "greenlet-3.0.3-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d4d1ac74f5c0c0524e4a24335350edad7e5f03b9532da7ea4d3c54d527784f2e"}, + {file = "greenlet-3.0.3-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:149e94a2dd82d19838fe4b2259f1b6b9957d5ba1b25640d2380bea9c5df37676"}, + {file = "greenlet-3.0.3-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:15d79dd26056573940fcb8c7413d84118086f2ec1a8acdfa854631084393efcc"}, + {file = "greenlet-3.0.3-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:881b7db1ebff4ba09aaaeae6aa491daeb226c8150fc20e836ad00041bcb11230"}, + {file = "greenlet-3.0.3-cp312-cp312-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:fcd2469d6a2cf298f198f0487e0a5b1a47a42ca0fa4dfd1b6862c999f018ebbf"}, + {file = "greenlet-3.0.3-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:1f672519db1796ca0d8753f9e78ec02355e862d0998193038c7073045899f305"}, + {file = "greenlet-3.0.3-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:2516a9957eed41dd8f1ec0c604f1cdc86758b587d964668b5b196a9db5bfcde6"}, + {file = "greenlet-3.0.3-cp312-cp312-win_amd64.whl", hash = "sha256:bba5387a6975598857d86de9eac14210a49d554a77eb8261cc68b7d082f78ce2"}, + {file = "greenlet-3.0.3-cp37-cp37m-macosx_11_0_universal2.whl", hash = "sha256:5b51e85cb5ceda94e79d019ed36b35386e8c37d22f07d6a751cb659b180d5274"}, + {file = "greenlet-3.0.3-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:daf3cb43b7cf2ba96d614252ce1684c1bccee6b2183a01328c98d36fcd7d5cb0"}, + {file = "greenlet-3.0.3-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:99bf650dc5d69546e076f413a87481ee1d2d09aaaaaca058c9251b6d8c14783f"}, + {file = "greenlet-3.0.3-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2dd6e660effd852586b6a8478a1d244b8dc90ab5b1321751d2ea15deb49ed414"}, + {file = "greenlet-3.0.3-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e3391d1e16e2a5a1507d83e4a8b100f4ee626e8eca43cf2cadb543de69827c4c"}, + {file = "greenlet-3.0.3-cp37-cp37m-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:e1f145462f1fa6e4a4ae3c0f782e580ce44d57c8f2c7aae1b6fa88c0b2efdb41"}, + {file = "greenlet-3.0.3-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:1a7191e42732df52cb5f39d3527217e7ab73cae2cb3694d241e18f53d84ea9a7"}, + {file = "greenlet-3.0.3-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:0448abc479fab28b00cb472d278828b3ccca164531daab4e970a0458786055d6"}, + {file = "greenlet-3.0.3-cp37-cp37m-win32.whl", hash = "sha256:b542be2440edc2d48547b5923c408cbe0fc94afb9f18741faa6ae970dbcb9b6d"}, + {file = "greenlet-3.0.3-cp37-cp37m-win_amd64.whl", hash = "sha256:01bc7ea167cf943b4c802068e178bbf70ae2e8c080467070d01bfa02f337ee67"}, + {file = "greenlet-3.0.3-cp38-cp38-macosx_11_0_universal2.whl", hash = "sha256:1996cb9306c8595335bb157d133daf5cf9f693ef413e7673cb07e3e5871379ca"}, + {file = "greenlet-3.0.3-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3ddc0f794e6ad661e321caa8d2f0a55ce01213c74722587256fb6566049a8b04"}, + {file = "greenlet-3.0.3-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:c9db1c18f0eaad2f804728c67d6c610778456e3e1cc4ab4bbd5eeb8e6053c6fc"}, + {file = "greenlet-3.0.3-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:7170375bcc99f1a2fbd9c306f5be8764eaf3ac6b5cb968862cad4c7057756506"}, + {file = "greenlet-3.0.3-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6b66c9c1e7ccabad3a7d037b2bcb740122a7b17a53734b7d72a344ce39882a1b"}, + {file = "greenlet-3.0.3-cp38-cp38-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:098d86f528c855ead3479afe84b49242e174ed262456c342d70fc7f972bc13c4"}, + {file = "greenlet-3.0.3-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:81bb9c6d52e8321f09c3d165b2a78c680506d9af285bfccbad9fb7ad5a5da3e5"}, + {file = "greenlet-3.0.3-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:fd096eb7ffef17c456cfa587523c5f92321ae02427ff955bebe9e3c63bc9f0da"}, + {file = "greenlet-3.0.3-cp38-cp38-win32.whl", hash = "sha256:d46677c85c5ba00a9cb6f7a00b2bfa6f812192d2c9f7d9c4f6a55b60216712f3"}, + {file = "greenlet-3.0.3-cp38-cp38-win_amd64.whl", hash = "sha256:419b386f84949bf0e7c73e6032e3457b82a787c1ab4a0e43732898a761cc9dbf"}, + {file = "greenlet-3.0.3-cp39-cp39-macosx_11_0_universal2.whl", hash = "sha256:da70d4d51c8b306bb7a031d5cff6cc25ad253affe89b70352af5f1cb68e74b53"}, + {file = "greenlet-3.0.3-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:086152f8fbc5955df88382e8a75984e2bb1c892ad2e3c80a2508954e52295257"}, + {file = "greenlet-3.0.3-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d73a9fe764d77f87f8ec26a0c85144d6a951a6c438dfe50487df5595c6373eac"}, + {file = "greenlet-3.0.3-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b7dcbe92cc99f08c8dd11f930de4d99ef756c3591a5377d1d9cd7dd5e896da71"}, + {file = "greenlet-3.0.3-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1551a8195c0d4a68fac7a4325efac0d541b48def35feb49d803674ac32582f61"}, + {file = "greenlet-3.0.3-cp39-cp39-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:64d7675ad83578e3fc149b617a444fab8efdafc9385471f868eb5ff83e446b8b"}, + {file = "greenlet-3.0.3-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:b37eef18ea55f2ffd8f00ff8fe7c8d3818abd3e25fb73fae2ca3b672e333a7a6"}, + {file = "greenlet-3.0.3-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:77457465d89b8263bca14759d7c1684df840b6811b2499838cc5b040a8b5b113"}, + {file = "greenlet-3.0.3-cp39-cp39-win32.whl", hash = "sha256:57e8974f23e47dac22b83436bdcf23080ade568ce77df33159e019d161ce1d1e"}, + {file = "greenlet-3.0.3-cp39-cp39-win_amd64.whl", hash = "sha256:c5ee858cfe08f34712f548c3c363e807e7186f03ad7a5039ebadb29e8c6be067"}, + {file = "greenlet-3.0.3.tar.gz", hash = "sha256:43374442353259554ce33599da8b692d5aa96f8976d567d4badf263371fbe491"}, +] + +[package.extras] +docs = ["Sphinx", "furo"] +test = ["objgraph", "psutil"] + +[[package]] +name = "idna" +version = "3.7" +description = "Internationalized Domain Names in Applications (IDNA)" +optional = false +python-versions = ">=3.5" +files = [ + {file = "idna-3.7-py3-none-any.whl", hash = "sha256:82fee1fc78add43492d3a1898bfa6d8a904cc97d8427f683ed8e798d07761aa0"}, + {file = "idna-3.7.tar.gz", hash = "sha256:028ff3aadf0609c1fd278d8ea3089299412a7a8b9bd005dd08b9f8285bcb5cfc"}, +] + +[[package]] +name = "ifaddr" +version = "0.2.0" +description = "Cross-platform network interface and IP address enumeration library" +optional = false +python-versions = "*" +files = [ + {file = "ifaddr-0.2.0-py3-none-any.whl", hash = "sha256:085e0305cfe6f16ab12d72e2024030f5d52674afad6911bb1eee207177b8a748"}, + {file = "ifaddr-0.2.0.tar.gz", hash = "sha256:cc0cbfcaabf765d44595825fb96a99bb12c79716b73b44330ea38ee2b0c4aed4"}, +] + +[[package]] +name = "iniconfig" +version = "2.0.0" +description = "brain-dead simple config-ini parsing" +optional = false +python-versions = ">=3.7" +files = [ + {file = "iniconfig-2.0.0-py3-none-any.whl", hash = "sha256:b6a85871a79d2e3b22d2d1b94ac2824226a63c6b741c88f7ae975f18b6778374"}, + {file = "iniconfig-2.0.0.tar.gz", hash = "sha256:2d91e135bf72d31a410b17c16da610a82cb55f6b0477d1a902134b24a455b8b3"}, +] + +[[package]] +name = "ironic" +version = "26.0.0" +description = "OpenStack Bare Metal Provisioning" +optional = false +python-versions = ">=3.8" +files = [ + {file = "ironic-26.0.0-py3-none-any.whl", hash = "sha256:2506bec6dd46af01d872b75ae80a34b663ea34b8993664e72aedc81449946a54"}, + {file = "ironic-26.0.0.tar.gz", hash = "sha256:2e3b9f59452c6be7bcc5c9e1dea737695193ddd7560f3607cf9c44c6a8a6a907"}, +] + +[package.dependencies] +alembic = ">=1.4.2" +automaton = ">=1.9.0" +construct = ">=2.9.39" +eventlet = ">=0.30.1" +futurist = ">=1.2.0" +ironic-lib = ">=6.0.0" +Jinja2 = ">=3.0.0" +jsonpatch = ">=1.16" +jsonschema = ">=4.0.0" +keystoneauth1 = ">=4.2.0" +keystonemiddleware = ">=9.5.0" +microversion-parse = ">=1.0.1" +netaddr = ">=0.9.0" +openstacksdk = ">=0.99.0" +os-traits = ">=0.4.0" +"oslo.concurrency" = ">=4.2.0" +"oslo.config" = ">=6.8.0" +"oslo.context" = ">=2.22.0" +"oslo.db" = ">=9.1.0" +"oslo.log" = ">=4.3.0" +"oslo.messaging" = ">=14.1.0" +"oslo.middleware" = ">=3.31.0" +"oslo.policy" = ">=3.7.0" +"oslo.rootwrap" = ">=5.8.0" +"oslo.serialization" = ">=2.25.0" +"oslo.service" = ">=1.24.0" +"oslo.upgradecheck" = ">=1.3.0" +"oslo.utils" = ">=4.5.0" +"oslo.versionedobjects" = ">=1.31.2" +osprofiler = ">=1.5.0" +pbr = ">=3.1.1" +pecan = ">=1.0.0" +psutil = ">=3.2.2" +pycdlib = ">=1.11.0" +requests = ">=2.18.0" +rfc3986 = ">=1.2.0" +SQLAlchemy = ">=1.4.0" +stevedore = ">=1.29.0" +sushy = ">=4.8.0" +tenacity = ">=6.3.1" +tooz = ">=2.7.0" +WebOb = ">=1.7.1" + +[package.extras] +devstack = ["virtualbmc (>=1.4.0)"] +guru-meditation-reports = ["oslo.reports (>=1.18.0)"] +i18n = ["oslo.i18n (>=3.20.0)"] +test = ["PyMySQL (>=0.8.0)", "WebTest (>=2.0.27)", "bandit (>=1.1.0,<2.0.0)", "coverage (>=4.0)", "ddt (>=1.2.1)", "fixtures (>=3.0.0)", "iso8601 (>=0.1.11)", "oslo.reports (>=1.18.0)", "oslotest (>=3.2.0)", "psycopg2 (>=2.8.5)", "pyasn1 (>=0.5.1)", "pyasn1-modules (>=0.3.0)", "pysnmp-lextudio (>=5.0.0)", "stestr (>=2.0.0)", "testtools (>=2.5.0)"] + +[[package]] +name = "ironic-lib" +version = "6.1.0" +description = "Ironic common library" +optional = false +python-versions = ">=3.8" +files = [ + {file = "ironic-lib-6.1.0.tar.gz", hash = "sha256:6c41150bdd3124920138770c626fe8a2dde50c08c1eee645dbfd4d8b717f5a7a"}, + {file = "ironic_lib-6.1.0-py3-none-any.whl", hash = "sha256:1ecd32dab2ca0cb68da190d2f30383775a9b374f040b664dc21dcb80e0a88dbe"}, +] + +[package.dependencies] +bcrypt = ">=3.1.3" +"oslo.concurrency" = ">=3.26.0" +"oslo.config" = ">=5.2.0" +"oslo.i18n" = ">=3.15.3" +"oslo.utils" = ">=3.34.0" +pbr = ">=2.0.0" +tenacity = ">=6.2.0" +WebOb = ">=1.7.1" +zeroconf = ">=0.24.0" + +[[package]] +name = "iso8601" +version = "2.1.0" +description = "Simple module to parse ISO 8601 dates" +optional = false +python-versions = ">=3.7,<4.0" +files = [ + {file = "iso8601-2.1.0-py3-none-any.whl", hash = "sha256:aac4145c4dcb66ad8b648a02830f5e2ff6c24af20f4f482689be402db2429242"}, + {file = "iso8601-2.1.0.tar.gz", hash = "sha256:6b1d3829ee8921c4301998c909f7829fa9ed3cbdac0d3b16af2d743aed1ba8df"}, +] + +[[package]] +name = "jinja2" +version = "3.1.4" +description = "A very fast and expressive template engine." +optional = false +python-versions = ">=3.7" +files = [ + {file = "jinja2-3.1.4-py3-none-any.whl", hash = "sha256:bc5dd2abb727a5319567b7a813e6a2e7318c39f4f487cfe6c89c6f9c7d25197d"}, + {file = "jinja2-3.1.4.tar.gz", hash = "sha256:4a3aee7acbbe7303aede8e9648d13b8bf88a429282aa6122a993f0ac800cb369"}, +] + +[package.dependencies] +MarkupSafe = ">=2.0" + +[package.extras] +i18n = ["Babel (>=2.7)"] + +[[package]] +name = "jmespath" +version = "1.0.1" +description = "JSON Matching Expressions" +optional = false +python-versions = ">=3.7" +files = [ + {file = "jmespath-1.0.1-py3-none-any.whl", hash = "sha256:02e2e4cc71b5bcab88332eebf907519190dd9e6e82107fa7f83b1003a6252980"}, + {file = "jmespath-1.0.1.tar.gz", hash = "sha256:90261b206d6defd58fdd5e85f478bf633a2901798906be2ad389150c5c60edbe"}, +] + +[[package]] +name = "jsonpatch" +version = "1.33" +description = "Apply JSON-Patches (RFC 6902)" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*, !=3.5.*, !=3.6.*" +files = [ + {file = "jsonpatch-1.33-py2.py3-none-any.whl", hash = "sha256:0ae28c0cd062bbd8b8ecc26d7d164fbbea9652a1a3693f3b956c1eae5145dade"}, + {file = "jsonpatch-1.33.tar.gz", hash = "sha256:9fcd4009c41e6d12348b4a0ff2563ba56a2923a7dfee731d004e212e1ee5030c"}, +] + +[package.dependencies] +jsonpointer = ">=1.9" + +[[package]] +name = "jsonpointer" +version = "3.0.0" +description = "Identify specific nodes in a JSON document (RFC 6901)" +optional = false +python-versions = ">=3.7" +files = [ + {file = "jsonpointer-3.0.0-py2.py3-none-any.whl", hash = "sha256:13e088adc14fca8b6aa8177c044e12701e6ad4b28ff10e65f2267a90109c9942"}, + {file = "jsonpointer-3.0.0.tar.gz", hash = "sha256:2b2d729f2091522d61c3b31f82e11870f60b68f43fbc705cb76bf4b832af59ef"}, +] + +[[package]] +name = "jsonschema" +version = "4.23.0" +description = "An implementation of JSON Schema validation for Python" +optional = false +python-versions = ">=3.8" +files = [ + {file = "jsonschema-4.23.0-py3-none-any.whl", hash = "sha256:fbadb6f8b144a8f8cf9f0b89ba94501d143e50411a1278633f56a7acf7fd5566"}, + {file = "jsonschema-4.23.0.tar.gz", hash = "sha256:d71497fef26351a33265337fa77ffeb82423f3ea21283cd9467bb03999266bc4"}, +] + +[package.dependencies] +attrs = ">=22.2.0" +jsonschema-specifications = ">=2023.03.6" +referencing = ">=0.28.4" +rpds-py = ">=0.7.1" + +[package.extras] +format = ["fqdn", "idna", "isoduration", "jsonpointer (>1.13)", "rfc3339-validator", "rfc3987", "uri-template", "webcolors (>=1.11)"] +format-nongpl = ["fqdn", "idna", "isoduration", "jsonpointer (>1.13)", "rfc3339-validator", "rfc3986-validator (>0.1.0)", "uri-template", "webcolors (>=24.6.0)"] + +[[package]] +name = "jsonschema-specifications" +version = "2023.12.1" +description = "The JSON Schema meta-schemas and vocabularies, exposed as a Registry" +optional = false +python-versions = ">=3.8" +files = [ + {file = "jsonschema_specifications-2023.12.1-py3-none-any.whl", hash = "sha256:87e4fdf3a94858b8a2ba2778d9ba57d8a9cafca7c7489c46ba0d30a8bc6a9c3c"}, + {file = "jsonschema_specifications-2023.12.1.tar.gz", hash = "sha256:48a76787b3e70f5ed53f1160d2b81f586e4ca6d1548c5de7085d1682674764cc"}, +] + +[package.dependencies] +referencing = ">=0.31.0" + +[[package]] +name = "keystoneauth1" +version = "5.7.0" +description = "Authentication Library for OpenStack Identity" +optional = false +python-versions = ">=3.8" +files = [ + {file = "keystoneauth1-5.7.0-py3-none-any.whl", hash = "sha256:a3623bd03ed9a8cf1866d3eba113423e3cd898f74b79dd95598152b473a2cecc"}, + {file = "keystoneauth1-5.7.0.tar.gz", hash = "sha256:b2cc2d68d1a48e9c2c6d9b1b1fd00d7c7bdfe086e8040b51e70938a8ba3adfd1"}, +] + +[package.dependencies] +iso8601 = ">=0.1.11" +os-service-types = ">=1.2.0" +pbr = ">=2.0.0,<2.1.0 || >2.1.0" +requests = ">=2.14.2" +stevedore = ">=1.20.0" + +[package.extras] +betamax = ["betamax (>=0.7.0)", "fixtures (>=3.0.0)", "mock (>=2.0.0)"] +kerberos = ["requests-kerberos (>=0.8.0)"] +oauth1 = ["oauthlib (>=0.6.2)"] +saml2 = ["lxml (>=4.2.0)"] +test = ["PyYAML (>=3.12)", "bandit (>=1.7.6,<1.8.0)", "betamax (>=0.7.0)", "coverage (>=4.0,!=4.4)", "fixtures (>=3.0.0)", "flake8-docstrings (>=1.7.0,<1.8.0)", "flake8-import-order (>=0.18.2,<0.19.0)", "hacking (>=6.1.0,<6.2.0)", "lxml (>=4.2.0)", "oauthlib (>=0.6.2)", "oslo.config (>=5.2.0)", "oslo.utils (>=3.33.0)", "oslotest (>=3.2.0)", "requests-kerberos (>=0.8.0)", "requests-mock (>=1.2.0)", "stestr (>=1.0.0)", "testresources (>=2.0.0)", "testtools (>=2.2.0)"] + +[[package]] +name = "keystonemiddleware" +version = "10.7.0" +description = "Middleware for OpenStack Identity" +optional = false +python-versions = ">=3.8" +files = [ + {file = "keystonemiddleware-10.7.0-py3-none-any.whl", hash = "sha256:11f74dcf90433dfcbde525910bc9429301ed8b80357439fc469497e9d00b3543"}, + {file = "keystonemiddleware-10.7.0.tar.gz", hash = "sha256:fc43f0101a888927c3fd36d95b94b6d69b01afafe51f6e1c3780391e7b031605"}, +] + +[package.dependencies] +keystoneauth1 = ">=3.12.0" +"oslo.cache" = ">=1.26.0" +"oslo.config" = ">=5.2.0" +"oslo.context" = ">=2.19.2" +"oslo.i18n" = ">=3.15.3" +"oslo.log" = ">=3.36.0" +"oslo.serialization" = ">=2.18.0,<2.19.1 || >2.19.1" +"oslo.utils" = ">=3.33.0" +pbr = ">=2.0.0,<2.1.0 || >2.1.0" +pycadf = ">=1.1.0,<2.0.0 || >2.0.0" +PyJWT = ">=2.4.0" +python-keystoneclient = ">=3.20.0" +requests = ">=2.14.2" +WebOb = ">=1.7.1" + +[package.extras] +audit-notifications = ["oslo.messaging (>=5.29.0)"] +test = ["PyJWT (>=2.4.0)", "WebTest (>=2.0.27)", "bandit (>=1.1.0,!=1.6.0)", "coverage (>=4.0,!=4.4)", "cryptography (>=3.0)", "fixtures (>=3.0.0)", "flake8-docstrings (>=1.7.0,<1.8.0)", "hacking (>=6.0.1,<6.1.0)", "oslo.messaging (>=5.29.0)", "oslotest (>=3.2.0)", "python-memcached (>=1.59)", "requests-mock (>=1.2.0)", "stestr (>=2.0.0)", "stevedore (>=1.20.0)", "testresources (>=2.0.0)", "testtools (>=2.2.0)"] + +[[package]] +name = "kombu" +version = "5.4.0" +description = "Messaging library for Python." +optional = false +python-versions = ">=3.8" +files = [ + {file = "kombu-5.4.0-py3-none-any.whl", hash = "sha256:c8dd99820467610b4febbc7a9e8a0d3d7da2d35116b67184418b51cc520ea6b6"}, + {file = "kombu-5.4.0.tar.gz", hash = "sha256:ad200a8dbdaaa2bbc5f26d2ee7d707d9a1fded353a0f4bd751ce8c7d9f449c60"}, +] + +[package.dependencies] +amqp = ">=5.1.1,<6.0.0" +vine = "5.1.0" + +[package.extras] +azureservicebus = ["azure-servicebus (>=7.10.0)"] +azurestoragequeues = ["azure-identity (>=1.12.0)", "azure-storage-queue (>=12.6.0)"] +confluentkafka = ["confluent-kafka (>=2.2.0)"] +consul = ["python-consul2 (==0.1.5)"] +librabbitmq = ["librabbitmq (>=2.0.0)"] +mongodb = ["pymongo (>=4.1.1)"] +msgpack = ["msgpack (==1.0.8)"] +pyro = ["pyro4 (==4.82)"] +qpid = ["qpid-python (>=0.26)", "qpid-tools (>=0.26)"] +redis = ["redis (>=4.5.2,!=4.5.5,!=5.0.2)"] +slmq = ["softlayer-messaging (>=1.0.3)"] +sqlalchemy = ["sqlalchemy (>=1.4.48,<2.1)"] +sqs = ["boto3 (>=1.26.143)", "pycurl (>=7.43.0.5)", "urllib3 (>=1.26.16)"] +yaml = ["PyYAML (>=3.10)"] +zookeeper = ["kazoo (>=2.8.0)"] + +[[package]] +name = "logutils" +version = "0.3.5" +description = "Logging utilities" +optional = false +python-versions = "*" +files = [ + {file = "logutils-0.3.5.tar.gz", hash = "sha256:bc058a25d5c209461f134e1f03cab637d66a7a5ccc12e593db56fbb279899a82"}, +] + +[[package]] +name = "mako" +version = "1.3.5" +description = "A super-fast templating language that borrows the best ideas from the existing templating languages." +optional = false +python-versions = ">=3.8" +files = [ + {file = "Mako-1.3.5-py3-none-any.whl", hash = "sha256:260f1dbc3a519453a9c856dedfe4beb4e50bd5a26d96386cb6c80856556bb91a"}, + {file = "Mako-1.3.5.tar.gz", hash = "sha256:48dbc20568c1d276a2698b36d968fa76161bf127194907ea6fc594fa81f943bc"}, +] + +[package.dependencies] +MarkupSafe = ">=0.9.2" + +[package.extras] +babel = ["Babel"] +lingua = ["lingua"] +testing = ["pytest"] + +[[package]] +name = "markupsafe" +version = "2.1.5" +description = "Safely add untrusted strings to HTML/XML markup." +optional = false +python-versions = ">=3.7" +files = [ + {file = "MarkupSafe-2.1.5-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:a17a92de5231666cfbe003f0e4b9b3a7ae3afb1ec2845aadc2bacc93ff85febc"}, + {file = "MarkupSafe-2.1.5-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:72b6be590cc35924b02c78ef34b467da4ba07e4e0f0454a2c5907f473fc50ce5"}, + {file = "MarkupSafe-2.1.5-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e61659ba32cf2cf1481e575d0462554625196a1f2fc06a1c777d3f48e8865d46"}, + {file = "MarkupSafe-2.1.5-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2174c595a0d73a3080ca3257b40096db99799265e1c27cc5a610743acd86d62f"}, + {file = "MarkupSafe-2.1.5-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ae2ad8ae6ebee9d2d94b17fb62763125f3f374c25618198f40cbb8b525411900"}, + {file = "MarkupSafe-2.1.5-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:075202fa5b72c86ad32dc7d0b56024ebdbcf2048c0ba09f1cde31bfdd57bcfff"}, + {file = "MarkupSafe-2.1.5-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:598e3276b64aff0e7b3451b72e94fa3c238d452e7ddcd893c3ab324717456bad"}, + {file = "MarkupSafe-2.1.5-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:fce659a462a1be54d2ffcacea5e3ba2d74daa74f30f5f143fe0c58636e355fdd"}, + {file = "MarkupSafe-2.1.5-cp310-cp310-win32.whl", hash = "sha256:d9fad5155d72433c921b782e58892377c44bd6252b5af2f67f16b194987338a4"}, + {file = "MarkupSafe-2.1.5-cp310-cp310-win_amd64.whl", hash = "sha256:bf50cd79a75d181c9181df03572cdce0fbb75cc353bc350712073108cba98de5"}, + {file = "MarkupSafe-2.1.5-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:629ddd2ca402ae6dbedfceeba9c46d5f7b2a61d9749597d4307f943ef198fc1f"}, + {file = "MarkupSafe-2.1.5-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:5b7b716f97b52c5a14bffdf688f971b2d5ef4029127f1ad7a513973cfd818df2"}, + {file = "MarkupSafe-2.1.5-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6ec585f69cec0aa07d945b20805be741395e28ac1627333b1c5b0105962ffced"}, + {file = "MarkupSafe-2.1.5-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b91c037585eba9095565a3556f611e3cbfaa42ca1e865f7b8015fe5c7336d5a5"}, + {file = "MarkupSafe-2.1.5-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:7502934a33b54030eaf1194c21c692a534196063db72176b0c4028e140f8f32c"}, + {file = "MarkupSafe-2.1.5-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:0e397ac966fdf721b2c528cf028494e86172b4feba51d65f81ffd65c63798f3f"}, + {file = "MarkupSafe-2.1.5-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:c061bb86a71b42465156a3ee7bd58c8c2ceacdbeb95d05a99893e08b8467359a"}, + {file = "MarkupSafe-2.1.5-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:3a57fdd7ce31c7ff06cdfbf31dafa96cc533c21e443d57f5b1ecc6cdc668ec7f"}, + {file = "MarkupSafe-2.1.5-cp311-cp311-win32.whl", hash = "sha256:397081c1a0bfb5124355710fe79478cdbeb39626492b15d399526ae53422b906"}, + {file = "MarkupSafe-2.1.5-cp311-cp311-win_amd64.whl", hash = "sha256:2b7c57a4dfc4f16f7142221afe5ba4e093e09e728ca65c51f5620c9aaeb9a617"}, + {file = "MarkupSafe-2.1.5-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:8dec4936e9c3100156f8a2dc89c4b88d5c435175ff03413b443469c7c8c5f4d1"}, + {file = "MarkupSafe-2.1.5-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:3c6b973f22eb18a789b1460b4b91bf04ae3f0c4234a0a6aa6b0a92f6f7b951d4"}, + {file = "MarkupSafe-2.1.5-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ac07bad82163452a6884fe8fa0963fb98c2346ba78d779ec06bd7a6262132aee"}, + {file = "MarkupSafe-2.1.5-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f5dfb42c4604dddc8e4305050aa6deb084540643ed5804d7455b5df8fe16f5e5"}, + {file = "MarkupSafe-2.1.5-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ea3d8a3d18833cf4304cd2fc9cbb1efe188ca9b5efef2bdac7adc20594a0e46b"}, + {file = "MarkupSafe-2.1.5-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:d050b3361367a06d752db6ead6e7edeb0009be66bc3bae0ee9d97fb326badc2a"}, + {file = "MarkupSafe-2.1.5-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:bec0a414d016ac1a18862a519e54b2fd0fc8bbfd6890376898a6c0891dd82e9f"}, + {file = "MarkupSafe-2.1.5-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:58c98fee265677f63a4385256a6d7683ab1832f3ddd1e66fe948d5880c21a169"}, + {file = "MarkupSafe-2.1.5-cp312-cp312-win32.whl", hash = "sha256:8590b4ae07a35970728874632fed7bd57b26b0102df2d2b233b6d9d82f6c62ad"}, + {file = "MarkupSafe-2.1.5-cp312-cp312-win_amd64.whl", hash = "sha256:823b65d8706e32ad2df51ed89496147a42a2a6e01c13cfb6ffb8b1e92bc910bb"}, + {file = "MarkupSafe-2.1.5-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:c8b29db45f8fe46ad280a7294f5c3ec36dbac9491f2d1c17345be8e69cc5928f"}, + {file = "MarkupSafe-2.1.5-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ec6a563cff360b50eed26f13adc43e61bc0c04d94b8be985e6fb24b81f6dcfdf"}, + {file = "MarkupSafe-2.1.5-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a549b9c31bec33820e885335b451286e2969a2d9e24879f83fe904a5ce59d70a"}, + {file = "MarkupSafe-2.1.5-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4f11aa001c540f62c6166c7726f71f7573b52c68c31f014c25cc7901deea0b52"}, + {file = "MarkupSafe-2.1.5-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:7b2e5a267c855eea6b4283940daa6e88a285f5f2a67f2220203786dfa59b37e9"}, + {file = "MarkupSafe-2.1.5-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:2d2d793e36e230fd32babe143b04cec8a8b3eb8a3122d2aceb4a371e6b09b8df"}, + {file = "MarkupSafe-2.1.5-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:ce409136744f6521e39fd8e2a24c53fa18ad67aa5bc7c2cf83645cce5b5c4e50"}, + {file = "MarkupSafe-2.1.5-cp37-cp37m-win32.whl", hash = "sha256:4096e9de5c6fdf43fb4f04c26fb114f61ef0bf2e5604b6ee3019d51b69e8c371"}, + {file = "MarkupSafe-2.1.5-cp37-cp37m-win_amd64.whl", hash = "sha256:4275d846e41ecefa46e2015117a9f491e57a71ddd59bbead77e904dc02b1bed2"}, + {file = "MarkupSafe-2.1.5-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:656f7526c69fac7f600bd1f400991cc282b417d17539a1b228617081106feb4a"}, + {file = "MarkupSafe-2.1.5-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:97cafb1f3cbcd3fd2b6fbfb99ae11cdb14deea0736fc2b0952ee177f2b813a46"}, + {file = "MarkupSafe-2.1.5-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1f3fbcb7ef1f16e48246f704ab79d79da8a46891e2da03f8783a5b6fa41a9532"}, + {file = "MarkupSafe-2.1.5-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fa9db3f79de01457b03d4f01b34cf91bc0048eb2c3846ff26f66687c2f6d16ab"}, + {file = "MarkupSafe-2.1.5-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ffee1f21e5ef0d712f9033568f8344d5da8cc2869dbd08d87c84656e6a2d2f68"}, + {file = "MarkupSafe-2.1.5-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:5dedb4db619ba5a2787a94d877bc8ffc0566f92a01c0ef214865e54ecc9ee5e0"}, + {file = "MarkupSafe-2.1.5-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:30b600cf0a7ac9234b2638fbc0fb6158ba5bdcdf46aeb631ead21248b9affbc4"}, + {file = "MarkupSafe-2.1.5-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:8dd717634f5a044f860435c1d8c16a270ddf0ef8588d4887037c5028b859b0c3"}, + {file = "MarkupSafe-2.1.5-cp38-cp38-win32.whl", hash = "sha256:daa4ee5a243f0f20d528d939d06670a298dd39b1ad5f8a72a4275124a7819eff"}, + {file = "MarkupSafe-2.1.5-cp38-cp38-win_amd64.whl", hash = "sha256:619bc166c4f2de5caa5a633b8b7326fbe98e0ccbfacabd87268a2b15ff73a029"}, + {file = "MarkupSafe-2.1.5-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:7a68b554d356a91cce1236aa7682dc01df0edba8d043fd1ce607c49dd3c1edcf"}, + {file = "MarkupSafe-2.1.5-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:db0b55e0f3cc0be60c1f19efdde9a637c32740486004f20d1cff53c3c0ece4d2"}, + {file = "MarkupSafe-2.1.5-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3e53af139f8579a6d5f7b76549125f0d94d7e630761a2111bc431fd820e163b8"}, + {file = "MarkupSafe-2.1.5-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:17b950fccb810b3293638215058e432159d2b71005c74371d784862b7e4683f3"}, + {file = "MarkupSafe-2.1.5-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4c31f53cdae6ecfa91a77820e8b151dba54ab528ba65dfd235c80b086d68a465"}, + {file = "MarkupSafe-2.1.5-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:bff1b4290a66b490a2f4719358c0cdcd9bafb6b8f061e45c7a2460866bf50c2e"}, + {file = "MarkupSafe-2.1.5-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:bc1667f8b83f48511b94671e0e441401371dfd0f0a795c7daa4a3cd1dde55bea"}, + {file = "MarkupSafe-2.1.5-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:5049256f536511ee3f7e1b3f87d1d1209d327e818e6ae1365e8653d7e3abb6a6"}, + {file = "MarkupSafe-2.1.5-cp39-cp39-win32.whl", hash = "sha256:00e046b6dd71aa03a41079792f8473dc494d564611a8f89bbbd7cb93295ebdcf"}, + {file = "MarkupSafe-2.1.5-cp39-cp39-win_amd64.whl", hash = "sha256:fa173ec60341d6bb97a89f5ea19c85c5643c1e7dedebc22f5181eb73573142c5"}, + {file = "MarkupSafe-2.1.5.tar.gz", hash = "sha256:d283d37a890ba4c1ae73ffadf8046435c76e7bc2247bbb63c00bd1a709c6544b"}, +] + +[[package]] +name = "microversion-parse" +version = "1.0.1" +description = "OpenStack microversion header parser" +optional = false +python-versions = ">=3.6" +files = [ + {file = "microversion_parse-1.0.1-py3-none-any.whl", hash = "sha256:aab3ab98028923e778920ba6a837ea3b190d8827b08b3d1e845d9c44c9dfc221"}, + {file = "microversion_parse-1.0.1.tar.gz", hash = "sha256:ec6bc0711019f620d6690087b958f934634a242e49a7c1c60c1688363cbe102d"}, +] + +[package.dependencies] +WebOb = ">=1.2.3" + +[[package]] +name = "msgpack" +version = "1.0.8" +description = "MessagePack serializer" +optional = false +python-versions = ">=3.8" +files = [ + {file = "msgpack-1.0.8-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:505fe3d03856ac7d215dbe005414bc28505d26f0c128906037e66d98c4e95868"}, + {file = "msgpack-1.0.8-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:e6b7842518a63a9f17107eb176320960ec095a8ee3b4420b5f688e24bf50c53c"}, + {file = "msgpack-1.0.8-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:376081f471a2ef24828b83a641a02c575d6103a3ad7fd7dade5486cad10ea659"}, + {file = "msgpack-1.0.8-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5e390971d082dba073c05dbd56322427d3280b7cc8b53484c9377adfbae67dc2"}, + {file = "msgpack-1.0.8-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:00e073efcba9ea99db5acef3959efa45b52bc67b61b00823d2a1a6944bf45982"}, + {file = "msgpack-1.0.8-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:82d92c773fbc6942a7a8b520d22c11cfc8fd83bba86116bfcf962c2f5c2ecdaa"}, + {file = "msgpack-1.0.8-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:9ee32dcb8e531adae1f1ca568822e9b3a738369b3b686d1477cbc643c4a9c128"}, + {file = "msgpack-1.0.8-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:e3aa7e51d738e0ec0afbed661261513b38b3014754c9459508399baf14ae0c9d"}, + {file = "msgpack-1.0.8-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:69284049d07fce531c17404fcba2bb1df472bc2dcdac642ae71a2d079d950653"}, + {file = "msgpack-1.0.8-cp310-cp310-win32.whl", hash = "sha256:13577ec9e247f8741c84d06b9ece5f654920d8365a4b636ce0e44f15e07ec693"}, + {file = "msgpack-1.0.8-cp310-cp310-win_amd64.whl", hash = "sha256:e532dbd6ddfe13946de050d7474e3f5fb6ec774fbb1a188aaf469b08cf04189a"}, + {file = "msgpack-1.0.8-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:9517004e21664f2b5a5fd6333b0731b9cf0817403a941b393d89a2f1dc2bd836"}, + {file = "msgpack-1.0.8-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:d16a786905034e7e34098634b184a7d81f91d4c3d246edc6bd7aefb2fd8ea6ad"}, + {file = "msgpack-1.0.8-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:e2872993e209f7ed04d963e4b4fbae72d034844ec66bc4ca403329db2074377b"}, + {file = "msgpack-1.0.8-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5c330eace3dd100bdb54b5653b966de7f51c26ec4a7d4e87132d9b4f738220ba"}, + {file = "msgpack-1.0.8-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:83b5c044f3eff2a6534768ccfd50425939e7a8b5cf9a7261c385de1e20dcfc85"}, + {file = "msgpack-1.0.8-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1876b0b653a808fcd50123b953af170c535027bf1d053b59790eebb0aeb38950"}, + {file = "msgpack-1.0.8-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:dfe1f0f0ed5785c187144c46a292b8c34c1295c01da12e10ccddfc16def4448a"}, + {file = "msgpack-1.0.8-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:3528807cbbb7f315bb81959d5961855e7ba52aa60a3097151cb21956fbc7502b"}, + {file = "msgpack-1.0.8-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:e2f879ab92ce502a1e65fce390eab619774dda6a6ff719718069ac94084098ce"}, + {file = "msgpack-1.0.8-cp311-cp311-win32.whl", hash = "sha256:26ee97a8261e6e35885c2ecd2fd4a6d38252246f94a2aec23665a4e66d066305"}, + {file = "msgpack-1.0.8-cp311-cp311-win_amd64.whl", hash = "sha256:eadb9f826c138e6cf3c49d6f8de88225a3c0ab181a9b4ba792e006e5292d150e"}, + {file = "msgpack-1.0.8-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:114be227f5213ef8b215c22dde19532f5da9652e56e8ce969bf0a26d7c419fee"}, + {file = "msgpack-1.0.8-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:d661dc4785affa9d0edfdd1e59ec056a58b3dbb9f196fa43587f3ddac654ac7b"}, + {file = "msgpack-1.0.8-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:d56fd9f1f1cdc8227d7b7918f55091349741904d9520c65f0139a9755952c9e8"}, + {file = "msgpack-1.0.8-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0726c282d188e204281ebd8de31724b7d749adebc086873a59efb8cf7ae27df3"}, + {file = "msgpack-1.0.8-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8db8e423192303ed77cff4dce3a4b88dbfaf43979d280181558af5e2c3c71afc"}, + {file = "msgpack-1.0.8-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:99881222f4a8c2f641f25703963a5cefb076adffd959e0558dc9f803a52d6a58"}, + {file = "msgpack-1.0.8-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:b5505774ea2a73a86ea176e8a9a4a7c8bf5d521050f0f6f8426afe798689243f"}, + {file = "msgpack-1.0.8-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:ef254a06bcea461e65ff0373d8a0dd1ed3aa004af48839f002a0c994a6f72d04"}, + {file = "msgpack-1.0.8-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:e1dd7839443592d00e96db831eddb4111a2a81a46b028f0facd60a09ebbdd543"}, + {file = "msgpack-1.0.8-cp312-cp312-win32.whl", hash = "sha256:64d0fcd436c5683fdd7c907eeae5e2cbb5eb872fafbc03a43609d7941840995c"}, + {file = "msgpack-1.0.8-cp312-cp312-win_amd64.whl", hash = "sha256:74398a4cf19de42e1498368c36eed45d9528f5fd0155241e82c4082b7e16cffd"}, + {file = "msgpack-1.0.8-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:0ceea77719d45c839fd73abcb190b8390412a890df2f83fb8cf49b2a4b5c2f40"}, + {file = "msgpack-1.0.8-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:1ab0bbcd4d1f7b6991ee7c753655b481c50084294218de69365f8f1970d4c151"}, + {file = "msgpack-1.0.8-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:1cce488457370ffd1f953846f82323cb6b2ad2190987cd4d70b2713e17268d24"}, + {file = "msgpack-1.0.8-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3923a1778f7e5ef31865893fdca12a8d7dc03a44b33e2a5f3295416314c09f5d"}, + {file = "msgpack-1.0.8-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a22e47578b30a3e199ab067a4d43d790249b3c0587d9a771921f86250c8435db"}, + {file = "msgpack-1.0.8-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:bd739c9251d01e0279ce729e37b39d49a08c0420d3fee7f2a4968c0576678f77"}, + {file = "msgpack-1.0.8-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:d3420522057ebab1728b21ad473aa950026d07cb09da41103f8e597dfbfaeb13"}, + {file = "msgpack-1.0.8-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:5845fdf5e5d5b78a49b826fcdc0eb2e2aa7191980e3d2cfd2a30303a74f212e2"}, + {file = "msgpack-1.0.8-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:6a0e76621f6e1f908ae52860bdcb58e1ca85231a9b0545e64509c931dd34275a"}, + {file = "msgpack-1.0.8-cp38-cp38-win32.whl", hash = "sha256:374a8e88ddab84b9ada695d255679fb99c53513c0a51778796fcf0944d6c789c"}, + {file = "msgpack-1.0.8-cp38-cp38-win_amd64.whl", hash = "sha256:f3709997b228685fe53e8c433e2df9f0cdb5f4542bd5114ed17ac3c0129b0480"}, + {file = "msgpack-1.0.8-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:f51bab98d52739c50c56658cc303f190785f9a2cd97b823357e7aeae54c8f68a"}, + {file = "msgpack-1.0.8-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:73ee792784d48aa338bba28063e19a27e8d989344f34aad14ea6e1b9bd83f596"}, + {file = "msgpack-1.0.8-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:f9904e24646570539a8950400602d66d2b2c492b9010ea7e965025cb71d0c86d"}, + {file = "msgpack-1.0.8-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e75753aeda0ddc4c28dce4c32ba2f6ec30b1b02f6c0b14e547841ba5b24f753f"}, + {file = "msgpack-1.0.8-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5dbf059fb4b7c240c873c1245ee112505be27497e90f7c6591261c7d3c3a8228"}, + {file = "msgpack-1.0.8-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4916727e31c28be8beaf11cf117d6f6f188dcc36daae4e851fee88646f5b6b18"}, + {file = "msgpack-1.0.8-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:7938111ed1358f536daf311be244f34df7bf3cdedb3ed883787aca97778b28d8"}, + {file = "msgpack-1.0.8-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:493c5c5e44b06d6c9268ce21b302c9ca055c1fd3484c25ba41d34476c76ee746"}, + {file = "msgpack-1.0.8-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:5fbb160554e319f7b22ecf530a80a3ff496d38e8e07ae763b9e82fadfe96f273"}, + {file = "msgpack-1.0.8-cp39-cp39-win32.whl", hash = "sha256:f9af38a89b6a5c04b7d18c492c8ccf2aee7048aff1ce8437c4683bb5a1df893d"}, + {file = "msgpack-1.0.8-cp39-cp39-win_amd64.whl", hash = "sha256:ed59dd52075f8fc91da6053b12e8c89e37aa043f8986efd89e61fae69dc1b011"}, + {file = "msgpack-1.0.8.tar.gz", hash = "sha256:95c02b0e27e706e48d0e5426d1710ca78e0f0628d6e89d5b5a5b91a5f12274f3"}, +] + +[[package]] +name = "netaddr" +version = "1.3.0" +description = "A network address manipulation library for Python" +optional = false +python-versions = ">=3.7" +files = [ + {file = "netaddr-1.3.0-py3-none-any.whl", hash = "sha256:c2c6a8ebe5554ce33b7d5b3a306b71bbb373e000bbbf2350dd5213cc56e3dbbe"}, + {file = "netaddr-1.3.0.tar.gz", hash = "sha256:5c3c3d9895b551b763779ba7db7a03487dc1f8e3b385af819af341ae9ef6e48a"}, +] + +[package.extras] +nicer-shell = ["ipython"] + +[[package]] +name = "netifaces" +version = "0.11.0" +description = "Portable network interface information." +optional = false +python-versions = "*" +files = [ + {file = "netifaces-0.11.0-cp27-cp27m-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:eb4813b77d5df99903af4757ce980a98c4d702bbcb81f32a0b305a1537bdf0b1"}, + {file = "netifaces-0.11.0-cp27-cp27m-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:5f9ca13babe4d845e400921973f6165a4c2f9f3379c7abfc7478160e25d196a4"}, + {file = "netifaces-0.11.0-cp27-cp27m-win32.whl", hash = "sha256:7dbb71ea26d304e78ccccf6faccef71bb27ea35e259fb883cfd7fd7b4f17ecb1"}, + {file = "netifaces-0.11.0-cp27-cp27m-win_amd64.whl", hash = "sha256:0f6133ac02521270d9f7c490f0c8c60638ff4aec8338efeff10a1b51506abe85"}, + {file = "netifaces-0.11.0-cp27-cp27mu-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:08e3f102a59f9eaef70948340aeb6c89bd09734e0dca0f3b82720305729f63ea"}, + {file = "netifaces-0.11.0-cp27-cp27mu-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:c03fb2d4ef4e393f2e6ffc6376410a22a3544f164b336b3a355226653e5efd89"}, + {file = "netifaces-0.11.0-cp34-cp34m-win32.whl", hash = "sha256:73ff21559675150d31deea8f1f8d7e9a9a7e4688732a94d71327082f517fc6b4"}, + {file = "netifaces-0.11.0-cp35-cp35m-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:815eafdf8b8f2e61370afc6add6194bd5a7252ae44c667e96c4c1ecf418811e4"}, + {file = "netifaces-0.11.0-cp35-cp35m-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:50721858c935a76b83dd0dd1ab472cad0a3ef540a1408057624604002fcfb45b"}, + {file = "netifaces-0.11.0-cp35-cp35m-win32.whl", hash = "sha256:c9a3a47cd3aaeb71e93e681d9816c56406ed755b9442e981b07e3618fb71d2ac"}, + {file = "netifaces-0.11.0-cp36-cp36m-macosx_10_15_x86_64.whl", hash = "sha256:aab1dbfdc55086c789f0eb37affccf47b895b98d490738b81f3b2360100426be"}, + {file = "netifaces-0.11.0-cp36-cp36m-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:c37a1ca83825bc6f54dddf5277e9c65dec2f1b4d0ba44b8fd42bc30c91aa6ea1"}, + {file = "netifaces-0.11.0-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:28f4bf3a1361ab3ed93c5ef360c8b7d4a4ae060176a3529e72e5e4ffc4afd8b0"}, + {file = "netifaces-0.11.0-cp36-cp36m-win32.whl", hash = "sha256:2650beee182fed66617e18474b943e72e52f10a24dc8cac1db36c41ee9c041b7"}, + {file = "netifaces-0.11.0-cp36-cp36m-win_amd64.whl", hash = "sha256:cb925e1ca024d6f9b4f9b01d83215fd00fe69d095d0255ff3f64bffda74025c8"}, + {file = "netifaces-0.11.0-cp37-cp37m-macosx_10_15_x86_64.whl", hash = "sha256:84e4d2e6973eccc52778735befc01638498781ce0e39aa2044ccfd2385c03246"}, + {file = "netifaces-0.11.0-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:18917fbbdcb2d4f897153c5ddbb56b31fa6dd7c3fa9608b7e3c3a663df8206b5"}, + {file = "netifaces-0.11.0-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:48324183af7f1bc44f5f197f3dad54a809ad1ef0c78baee2c88f16a5de02c4c9"}, + {file = "netifaces-0.11.0-cp37-cp37m-win32.whl", hash = "sha256:8f7da24eab0d4184715d96208b38d373fd15c37b0dafb74756c638bd619ba150"}, + {file = "netifaces-0.11.0-cp37-cp37m-win_amd64.whl", hash = "sha256:2479bb4bb50968089a7c045f24d120f37026d7e802ec134c4490eae994c729b5"}, + {file = "netifaces-0.11.0-cp38-cp38-macosx_10_15_x86_64.whl", hash = "sha256:3ecb3f37c31d5d51d2a4d935cfa81c9bc956687c6f5237021b36d6fdc2815b2c"}, + {file = "netifaces-0.11.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:96c0fe9696398253f93482c84814f0e7290eee0bfec11563bd07d80d701280c3"}, + {file = "netifaces-0.11.0-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:c92ff9ac7c2282009fe0dcb67ee3cd17978cffbe0c8f4b471c00fe4325c9b4d4"}, + {file = "netifaces-0.11.0-cp38-cp38-win32.whl", hash = "sha256:d07b01c51b0b6ceb0f09fc48ec58debd99d2c8430b09e56651addeaf5de48048"}, + {file = "netifaces-0.11.0-cp38-cp38-win_amd64.whl", hash = "sha256:469fc61034f3daf095e02f9f1bbac07927b826c76b745207287bc594884cfd05"}, + {file = "netifaces-0.11.0-cp39-cp39-macosx_10_15_x86_64.whl", hash = "sha256:5be83986100ed1fdfa78f11ccff9e4757297735ac17391b95e17e74335c2047d"}, + {file = "netifaces-0.11.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:54ff6624eb95b8a07e79aa8817288659af174e954cca24cdb0daeeddfc03c4ff"}, + {file = "netifaces-0.11.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:841aa21110a20dc1621e3dd9f922c64ca64dd1eb213c47267a2c324d823f6c8f"}, + {file = "netifaces-0.11.0-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:e76c7f351e0444721e85f975ae92718e21c1f361bda946d60a214061de1f00a1"}, + {file = "netifaces-0.11.0.tar.gz", hash = "sha256:043a79146eb2907edf439899f262b3dfe41717d34124298ed281139a8b93ca32"}, +] + +[[package]] +name = "openstacksdk" +version = "3.3.0" +description = "An SDK for building applications to work with OpenStack" +optional = false +python-versions = ">=3.7" +files = [ + {file = "openstacksdk-3.3.0-py3-none-any.whl", hash = "sha256:e6d4121b87354984caf0e3c032e2ebf4d4440374f86c81c27ec52ca5df359157"}, + {file = "openstacksdk-3.3.0.tar.gz", hash = "sha256:0608690ca37ca73327b0fa3761d17e65395be37ff200b8735d8f24277b4f4980"}, +] + +[package.dependencies] +cryptography = ">=2.7" +decorator = ">=4.4.1" +"dogpile.cache" = ">=0.6.5" +iso8601 = ">=0.1.11" +jmespath = ">=0.9.0" +jsonpatch = ">=1.16,<1.20 || >1.20" +keystoneauth1 = ">=3.18.0" +netifaces = ">=0.10.4" +os-service-types = ">=1.7.0" +pbr = ">=2.0.0,<2.1.0 || >2.1.0" +platformdirs = ">=3" +PyYAML = ">=3.13" +requestsexceptions = ">=1.2.0" + +[[package]] +name = "os-service-types" +version = "1.7.0" +description = "Python library for consuming OpenStack sevice-types-authority data" +optional = false +python-versions = "*" +files = [ + {file = "os-service-types-1.7.0.tar.gz", hash = "sha256:31800299a82239363995b91f1ebf9106ac7758542a1e4ef6dc737a5932878c6c"}, + {file = "os_service_types-1.7.0-py2.py3-none-any.whl", hash = "sha256:0505c72205690910077fb72b88f2a1f07533c8d39f2fe75b29583481764965d6"}, +] + +[package.dependencies] +pbr = ">=2.0.0,<2.1.0 || >2.1.0" + +[[package]] +name = "os-traits" +version = "3.1.0" +description = "A library containing standardized trait strings" +optional = false +python-versions = ">=3.8" +files = [ + {file = "os-traits-3.1.0.tar.gz", hash = "sha256:e174276f9faad6139474ce3294b956927de4c9cb1f7e779ec7bafafc1f22ae54"}, + {file = "os_traits-3.1.0-py3-none-any.whl", hash = "sha256:0428b21e1f4c66f47118e031d5c7cdb1ef8f1f92f4e05d8ff48e469d08538111"}, +] + +[package.dependencies] +pbr = ">=3.0.0" + +[[package]] +name = "oslo-cache" +version = "3.8.0" +description = "Cache storage for OpenStack projects." +optional = false +python-versions = ">=3.8" +files = [ + {file = "oslo.cache-3.8.0-py3-none-any.whl", hash = "sha256:59bc9fb97abb38235119c1e03787b879b25ced156cd70a4c311173d2c6822c61"}, + {file = "oslo.cache-3.8.0.tar.gz", hash = "sha256:f084343b71de599e46d836d28f386217efe69fdab4fea245fc0211c3579af44a"}, +] + +[package.dependencies] +"dogpile.cache" = ">=1.3.1" +"oslo.config" = ">=8.1.0" +"oslo.i18n" = ">=5.0.0" +"oslo.log" = ">=4.2.1" +"oslo.utils" = ">=4.2.0" + +[package.extras] +dogpile = ["pymemcache (>=3.5.0)", "python-binary-memcached (>=0.29.0)", "python-memcached (>=1.56)", "redis (>=3.0.0)"] +etcd3gw = ["etcd3gw (>=0.2.0)"] +mongo = ["pymongo (>=3.0.2)"] +test = ["etcd3gw (>=0.2.0)", "oslotest (>=3.2.0)", "pifpaf (>=0.10.0)", "pymemcache (>=3.5.0)", "pymongo (>=3.0.2)", "python-binary-memcached (>=0.29.0)", "python-memcached (>=1.56)", "redis (>=3.0.0)", "stestr (>=2.0.0)"] + +[[package]] +name = "oslo-concurrency" +version = "6.0.0" +description = "Oslo Concurrency library" +optional = false +python-versions = ">=3.8" +files = [ + {file = "oslo.concurrency-6.0.0-py3-none-any.whl", hash = "sha256:50caec55f8a122935dacb0fd73b424f6cba6994f5e2342e2676dd45d743ebf88"}, + {file = "oslo.concurrency-6.0.0.tar.gz", hash = "sha256:b52f02b4e46f5f274b91fb8e1bfc5cbf9a418dfcd4a83be080345495e3d26e8a"}, +] + +[package.dependencies] +fasteners = ">=0.7.0" +"oslo.config" = ">=5.2.0" +"oslo.i18n" = ">=3.15.3" +"oslo.utils" = ">=3.33.0" +pbr = ">=2.0.0,<2.1.0 || >2.1.0" + +[[package]] +name = "oslo-config" +version = "9.5.0" +description = "Oslo Configuration API" +optional = false +python-versions = ">=3.8" +files = [ + {file = "oslo.config-9.5.0-py3-none-any.whl", hash = "sha256:f5e9a6848c35a1c8975677d623ffcf31bbb7177d14cb8f43505b2a4c679dcdd0"}, + {file = "oslo.config-9.5.0.tar.gz", hash = "sha256:aa500044886b6c55f76577cb5a93492a4596c5f9283376760ea7852cc49c99a3"}, +] + +[package.dependencies] +debtcollector = ">=1.2.0" +netaddr = ">=0.7.18" +"oslo.i18n" = ">=3.15.3" +PyYAML = ">=5.1" +requests = ">=2.18.0" +rfc3986 = ">=1.2.0" +stevedore = ">=1.20.0" + +[package.extras] +rst-generator = ["rst2txt (>=1.1.0)", "sphinx (>=1.8.0)"] +test = ["bandit (>=1.7.0,<1.8.0)", "coverage (>=4.0)", "fixtures (>=3.0.0)", "hacking (>=6.1.0,<6.2.0)", "mypy (>=0.720)", "oslo.log (>=3.36.0)", "oslotest (>=3.2.0)", "pre-commit (>=2.6.0)", "requests-mock (>=1.5.0)", "stestr (>=2.1.0)", "testscenarios (>=0.4)", "testtools (>=2.2.0)"] + +[[package]] +name = "oslo-context" +version = "5.5.0" +description = "Oslo Context library" +optional = false +python-versions = ">=3.8" +files = [ + {file = "oslo.context-5.5.0-py3-none-any.whl", hash = "sha256:aa858a42aac9858bf259bc0804513a8f9bf36916f9cfc8937708f6c90ad68259"}, + {file = "oslo.context-5.5.0.tar.gz", hash = "sha256:eae0317b29928f1934df4c60b860fe8625247cb297c5cc62fef8eb5827b12fac"}, +] + +[package.dependencies] +debtcollector = ">=1.2.0" +pbr = ">=2.0.0,<2.1.0 || >2.1.0" + +[[package]] +name = "oslo-db" +version = "16.0.0" +description = "Oslo Database library" +optional = false +python-versions = ">=3.8" +files = [ + {file = "oslo.db-16.0.0-py3-none-any.whl", hash = "sha256:58da949090fa9040fac197cc75e22ed9a35ed6a48e86b89eeda2a4cce2a38a7a"}, + {file = "oslo.db-16.0.0.tar.gz", hash = "sha256:f1b3548d1f1e11f2d81197c1c178b1d253b6038ef888361d310a7601aec17e81"}, +] + +[package.dependencies] +alembic = ">=0.9.6" +debtcollector = ">=1.2.0" +"oslo.config" = ">=5.2.0" +"oslo.i18n" = ">=3.15.3" +"oslo.utils" = ">=3.33.0" +pbr = ">=2.0.0" +SQLAlchemy = ">=1.4.0" +stevedore = ">=1.20.0" +testresources = ">=2.0.0" +testscenarios = ">=0.4" + +[package.extras] +mysql = ["PyMySQL (>=0.7.6)"] +postgresql = ["psycopg2 (>=2.8.0)"] +test = ["PyMySQL (>=0.7.6)", "bandit (>=1.7.0,<1.8.0)", "coverage (>=4.0)", "eventlet (>=0.18.2)", "fixtures (>=3.0.0)", "hacking (>=6.1.0,<6.2.0)", "oslo.context (>=2.19.2)", "oslotest (>=3.2.0)", "pifpaf (>=0.10.0)", "pre-commit (>=2.6.0)", "psycopg2 (>=2.8.0)", "python-subunit (>=1.0.0)", "stestr (>=2.0.0)", "testtools (>=2.2.0)"] + +[[package]] +name = "oslo-i18n" +version = "6.3.0" +description = "Oslo i18n library" +optional = false +python-versions = ">=3.8" +files = [ + {file = "oslo.i18n-6.3.0-py3-none-any.whl", hash = "sha256:698eb5c63a01359ed6d91031d6331098190d38be0bdda7d270264d6f86bc79e7"}, + {file = "oslo.i18n-6.3.0.tar.gz", hash = "sha256:64a251edef8bf1bb1d4e6f78d377e149d4f15c1a9245de77f172016da6267444"}, +] + +[package.dependencies] +pbr = ">=2.0.0,<2.1.0 || >2.1.0" + +[[package]] +name = "oslo-log" +version = "6.1.1" +description = "oslo.log library" +optional = false +python-versions = ">=3.8" +files = [ + {file = "oslo.log-6.1.1-py3-none-any.whl", hash = "sha256:f7f162ab03dc3f0728d8abee2806677146a2704aa22d4b3d7a9e4d1c1c68a26e"}, + {file = "oslo.log-6.1.1.tar.gz", hash = "sha256:e35a12cfe4cad13ffb0aeda99fcca20a705d0f694a84c2ef7b07b45960f88fb4"}, +] + +[package.dependencies] +"oslo.config" = ">=5.2.0" +"oslo.context" = ">=2.21.0" +"oslo.i18n" = ">=3.20.0" +"oslo.serialization" = ">=2.25.0" +"oslo.utils" = ">=3.36.0" +pbr = ">=3.1.1" +python-dateutil = ">=2.7.0" + +[package.extras] +fixtures = ["fixtures (>=3.0.0)"] +systemd = ["systemd-python (>=234)"] +test = ["coverage (>=4.5.1)", "eventlet (>=0.30.1)", "fixtures (>=3.0.0)", "oslotest (>=3.3.0)", "stestr (>=2.0.0)", "testtools (>=2.3.0)"] + +[[package]] +name = "oslo-messaging" +version = "14.8.1" +description = "Oslo Messaging API" +optional = false +python-versions = ">=3.8" +files = [ + {file = "oslo.messaging-14.8.1-py3-none-any.whl", hash = "sha256:022813f3426f01aaf53166546aa5704786da8eed0bc69b30daa5b4a5c37cb862"}, + {file = "oslo.messaging-14.8.1.tar.gz", hash = "sha256:1ae35f71f8fb2bbd859bdb9c46f4468a451278d15e4c88c114b4fbe10b7d87f4"}, +] + +[package.dependencies] +amqp = ">=2.5.2" +cachetools = ">=2.0.0" +debtcollector = ">=1.2.0" +futurist = ">=1.2.0" +kombu = ">=4.6.6" +"oslo.config" = ">=5.2.0" +"oslo.context" = ">=5.3.0" +"oslo.log" = ">=3.36.0" +"oslo.metrics" = ">=0.2.1" +"oslo.middleware" = ">=3.31.0" +"oslo.serialization" = ">=2.18.0" +"oslo.service" = ">=1.24.0" +"oslo.utils" = ">=3.37.0" +pbr = ">=2.0.0" +PyYAML = ">=3.13" +stevedore = ">=1.20.0" +WebOb = ">=1.7.1" + +[package.extras] +amqp1 = ["pyngus (>=2.2.0)"] +kafka = ["confluent-kafka (>=1.3.0)"] +test = ["bandit (>=1.7.0,<1.8.0)", "confluent-kafka (>=1.3.0)", "coverage (>=4.0)", "eventlet (>=0.23.0)", "fixtures (>=3.0.0)", "greenlet (>=0.4.15)", "hacking (>=6.1.0,<=6.2.0)", "oslotest (>=3.2.0)", "pifpaf (>=2.2.0)", "pre-commit (>=2.6.0)", "pyngus (>=2.2.0)", "stestr (>=2.0.0)", "testscenarios (>=0.4)", "testtools (>=2.2.0)"] + +[[package]] +name = "oslo-metrics" +version = "0.8.0" +description = "Oslo Metrics API" +optional = false +python-versions = ">=3.8" +files = [ + {file = "oslo.metrics-0.8.0-py3-none-any.whl", hash = "sha256:ef4785ae5387cf2013565927eefb87237cdf10d28352338434d2bac3ef71ab25"}, + {file = "oslo.metrics-0.8.0.tar.gz", hash = "sha256:ea31fd3b2ac76dcbe25d935e0616ad1893e3cbc53746e9fb9d5f5e1df04f943c"}, +] + +[package.dependencies] +"oslo.config" = ">=6.9.0" +"oslo.log" = ">=3.44.0" +"oslo.utils" = ">=3.41.0" +pbr = ">=3.1.1" +prometheus-client = ">=0.6.0" + +[[package]] +name = "oslo-middleware" +version = "6.1.0" +description = "Oslo Middleware library" +optional = false +python-versions = ">=3.8" +files = [ + {file = "oslo.middleware-6.1.0-py3-none-any.whl", hash = "sha256:72ddec614f0f67f888b18d4e801d8e2146fbb49e03ada9e8e78b06d9dba718f4"}, + {file = "oslo.middleware-6.1.0.tar.gz", hash = "sha256:431c601199b728b7a7c6d63dc8cdc89969fd959f730fbbe0022f07ba437e8d0c"}, +] + +[package.dependencies] +bcrypt = ">=3.1.3" +debtcollector = ">=1.2.0" +Jinja2 = ">=2.10" +"oslo.config" = ">=5.2.0" +"oslo.context" = ">=2.19.2" +"oslo.i18n" = ">=3.15.3" +"oslo.utils" = ">=3.33.0" +pbr = ">=2.0.0,<2.1.0 || >2.1.0" +statsd = ">=3.2.1" +stevedore = ">=1.20.0" +WebOb = ">=1.8.0" + +[[package]] +name = "oslo-policy" +version = "4.4.0" +description = "Oslo Policy library" +optional = false +python-versions = ">=3.8" +files = [ + {file = "oslo.policy-4.4.0-py3-none-any.whl", hash = "sha256:8d83d0febd5ff8274940432537ab4de068e818adcdefb0c467efcff8674c2c04"}, + {file = "oslo.policy-4.4.0.tar.gz", hash = "sha256:2d5f50c8babcbcb80e1ee40b2affb7cb464650fdfb1d9654a14ddf5b193699c5"}, +] + +[package.dependencies] +"oslo.config" = ">=6.0.0" +"oslo.context" = ">=2.22.0" +"oslo.i18n" = ">=3.15.3" +"oslo.serialization" = ">=2.18.0" +"oslo.utils" = ">=3.40.0" +PyYAML = ">=5.1" +requests = ">=2.14.2" +stevedore = ">=1.20.0" + +[[package]] +name = "oslo-rootwrap" +version = "7.2.0" +description = "Oslo Rootwrap" +optional = false +python-versions = ">=3.8" +files = [ + {file = "oslo.rootwrap-7.2.0-py3-none-any.whl", hash = "sha256:2f2c119c4c11d73160c956fb75851d2723b62fc0b6af04ebda72e626d9c4caea"}, + {file = "oslo.rootwrap-7.2.0.tar.gz", hash = "sha256:5102b057f6e9749adc692d32c4673778bdc8da178a6c99e0f438c5c33858786a"}, +] + +[[package]] +name = "oslo-serialization" +version = "5.5.0" +description = "Oslo Serialization library" +optional = false +python-versions = ">=3.8" +files = [ + {file = "oslo.serialization-5.5.0-py3-none-any.whl", hash = "sha256:cd2297c2006be104298843c4d176fb659eba0c6b618a3e3760d650dc771a6df5"}, + {file = "oslo.serialization-5.5.0.tar.gz", hash = "sha256:9e752fc5d8a975956728dd96a82186783b3fefcacbb3553acd933058861e15a6"}, +] + +[package.dependencies] +msgpack = ">=0.5.2" +"oslo.utils" = ">=3.33.0" +pbr = ">=2.0.0" +tzdata = {version = ">=2022.4", markers = "python_version >= \"3.9\""} + +[[package]] +name = "oslo-service" +version = "3.5.0" +description = "oslo.service library" +optional = false +python-versions = ">=3.8" +files = [ + {file = "oslo.service-3.5.0-py3-none-any.whl", hash = "sha256:fcc5795492534db16c410ff113c1d17890908e4fbe815b10abab031674a908ac"}, + {file = "oslo.service-3.5.0.tar.gz", hash = "sha256:7b48ba4df043a4c58a30035ee3967816518b06b4ceb16c23c6b27673b137d09a"}, +] + +[package.dependencies] +debtcollector = ">=1.2.0" +eventlet = ">=0.25.2" +greenlet = ">=0.4.15" +"oslo.concurrency" = ">=3.25.0" +"oslo.config" = ">=5.1.0" +"oslo.i18n" = ">=3.15.3" +"oslo.log" = ">=3.36.0" +"oslo.utils" = ">=3.40.2" +Paste = ">=2.0.2" +PasteDeploy = ">=1.5.0" +Routes = ">=2.3.1" +WebOb = ">=1.7.1" +Yappi = ">=1.0" + +[[package]] +name = "oslo-upgradecheck" +version = "2.3.0" +description = "Common code for writing OpenStack upgrade checks" +optional = false +python-versions = ">=3.8" +files = [ + {file = "oslo.upgradecheck-2.3.0-py3-none-any.whl", hash = "sha256:e7460104c763d23f5c4d0b3eb709a925f26f4f273005612583ea52518b47d323"}, + {file = "oslo.upgradecheck-2.3.0.tar.gz", hash = "sha256:46ea5330f0fcd8310d8d63a3b2643813026b7d7fbd6f35cf60409117ba105eb2"}, +] + +[package.dependencies] +"oslo.config" = ">=5.2.0" +"oslo.i18n" = ">=3.15.3" +"oslo.policy" = ">=2.0.0" +"oslo.utils" = ">=4.5.0" +PrettyTable = ">=0.7.1" + +[[package]] +name = "oslo-utils" +version = "7.2.0" +description = "Oslo Utility library" +optional = false +python-versions = ">=3.8" +files = [ + {file = "oslo.utils-7.2.0-py3-none-any.whl", hash = "sha256:53ce2d88fd1e9035e6be18c53447353d3e92ea0473d88272f43dc334ea9295af"}, + {file = "oslo.utils-7.2.0.tar.gz", hash = "sha256:94f8053391a33502dab4d84465403262ca19ffd8cfd29a1a5ea3c8aa620ef610"}, +] + +[package.dependencies] +debtcollector = ">=1.2.0" +iso8601 = ">=0.1.11" +netaddr = ">=0.10.0" +netifaces = ">=0.10.4" +"oslo.i18n" = ">=3.15.3" +packaging = ">=20.4" +pyparsing = ">=2.1.0" +PyYAML = ">=3.13" +tzdata = {version = ">=2022.4", markers = "python_version >= \"3.9\""} + +[[package]] +name = "oslo-versionedobjects" +version = "3.4.0" +description = "Oslo Versioned Objects library" +optional = false +python-versions = ">=3.8" +files = [ + {file = "oslo.versionedobjects-3.4.0-py3-none-any.whl", hash = "sha256:a0b1cf9a1b8ef937ee11ccbaba34bc317498836b27a5482293c0c4e4f8bc4959"}, + {file = "oslo.versionedobjects-3.4.0.tar.gz", hash = "sha256:e2a01588e590a63c589ca48afc78d02fdc707aa0b8141a42956bd129d8072c26"}, +] + +[package.dependencies] +iso8601 = ">=0.1.11" +netaddr = ">=0.7.18" +"oslo.concurrency" = ">=3.26.0" +"oslo.config" = ">=5.2.0" +"oslo.context" = ">=2.19.2" +"oslo.i18n" = ">=3.15.3" +"oslo.log" = ">=3.36.0" +"oslo.messaging" = ">=5.29.0" +"oslo.serialization" = ">=2.18.0" +"oslo.utils" = ">=4.7.0" +WebOb = ">=1.7.1" + +[[package]] +name = "osprofiler" +version = "4.1.0" +description = "OpenStack Profiler Library" +optional = false +python-versions = ">=3.8" +files = [ + {file = "osprofiler-4.1.0-py3-none-any.whl", hash = "sha256:7db027e12033fa72fefaa107a1a69e05c730acaabcc74117a9c87840526686b4"}, + {file = "osprofiler-4.1.0.tar.gz", hash = "sha256:57837b620581b13444a2e20564775d4fc73eff67c7888af99947ed582fe514b0"}, +] + +[package.dependencies] +netaddr = ">=0.7.18" +"oslo.concurrency" = ">=3.26.0" +"oslo.serialization" = ">=2.18.0" +"oslo.utils" = ">=3.33.0" +PrettyTable = ">=0.7.2" +requests = ">=2.14.2" +WebOb = ">=1.7.1" + +[package.extras] +oslo-config = ["oslo.config (>=5.2.0)"] +test = ["bandit (>=1.6.0,<1.7.0)", "coverage (>=4.0)", "ddt (>=1.0.1)", "docutils (>=0.14)", "elasticsearch (>=2.0.0,<3.0.0)", "flake8-import-order (==0.18.1)", "hacking (>=3.1.0,<3.2.0)", "jaeger-client (>=3.8.0)", "opentelemetry-exporter-otlp (>=1.16.0)", "opentelemetry-sdk (>=1.16.0)", "pre-commit (>=2.6.0)", "pymongo (>=3.0.2,!=3.1)", "redis (>=2.10.0)", "stestr (>=2.0.0)", "testtools (>=2.2.0)"] + +[[package]] +name = "packaging" +version = "24.1" +description = "Core utilities for Python packages" +optional = false +python-versions = ">=3.8" +files = [ + {file = "packaging-24.1-py3-none-any.whl", hash = "sha256:5b8f2217dbdbd2f7f384c41c628544e6d52f2d0f53c6d0c3ea61aa5d1d7ff124"}, + {file = "packaging-24.1.tar.gz", hash = "sha256:026ed72c8ed3fcce5bf8950572258698927fd1dbda10a5e981cdf0ac37f4f002"}, +] + +[[package]] +name = "paste" +version = "3.10.1" +description = "Tools for using a Web Server Gateway Interface stack" +optional = false +python-versions = ">=3" +files = [ + {file = "Paste-3.10.1-py3-none-any.whl", hash = "sha256:995e9994b6a94a2bdd8bd9654fb70ca3946ffab75442468bacf31b4d06481c3d"}, + {file = "paste-3.10.1.tar.gz", hash = "sha256:1c3d12065a5e8a7a18c0c7be1653a97cf38cc3e9a5a0c8334a9dd992d3a05e4a"}, +] + +[package.dependencies] +setuptools = "*" + +[package.extras] +flup = ["flup"] +openid = ["python-openid"] + +[[package]] +name = "pastedeploy" +version = "3.1.0" +description = "Load, configure, and compose WSGI applications and servers" +optional = false +python-versions = ">=3.7" +files = [ + {file = "PasteDeploy-3.1.0-py3-none-any.whl", hash = "sha256:76388ad53a661448d436df28c798063108f70e994ddc749540d733cdbd1b38cf"}, + {file = "PasteDeploy-3.1.0.tar.gz", hash = "sha256:9ddbaf152f8095438a9fe81f82c78a6714b92ae8e066bed418b6a7ff6a095a95"}, +] + +[package.extras] +docs = ["Sphinx (>=1.7.5)", "pylons-sphinx-themes"] +paste = ["Paste"] +testing = ["Paste", "pytest", "pytest-cov"] + +[[package]] +name = "pbr" +version = "6.0.0" +description = "Python Build Reasonableness" +optional = false +python-versions = ">=2.6" +files = [ + {file = "pbr-6.0.0-py2.py3-none-any.whl", hash = "sha256:4a7317d5e3b17a3dccb6a8cfe67dab65b20551404c52c8ed41279fa4f0cb4cda"}, + {file = "pbr-6.0.0.tar.gz", hash = "sha256:d1377122a5a00e2f940ee482999518efe16d745d423a670c27773dfbc3c9a7d9"}, +] + +[[package]] +name = "pecan" +version = "1.5.1" +description = "A WSGI object-dispatching web framework, designed to be lean and fast, with few dependencies." +optional = false +python-versions = "*" +files = [ + {file = "pecan-1.5.1-py3-none-any.whl", hash = "sha256:042c385edcba30a5e885ad2171af35418cda5e2af9b236386f4c72ba80a377f3"}, + {file = "pecan-1.5.1.tar.gz", hash = "sha256:6063272d5f860773fbb4b4b2ae1b09da8c954062ef871150c06cfdb2391d9355"}, +] + +[package.dependencies] +logutils = ">=0.3" +Mako = ">=0.4.0" +setuptools = "*" +WebOb = ">=1.8" + +[[package]] +name = "platformdirs" +version = "4.2.2" +description = "A small Python package for determining appropriate platform-specific dirs, e.g. a `user data dir`." +optional = false +python-versions = ">=3.8" +files = [ + {file = "platformdirs-4.2.2-py3-none-any.whl", hash = "sha256:2d7a1657e36a80ea911db832a8a6ece5ee53d8de21edd5cc5879af6530b1bfee"}, + {file = "platformdirs-4.2.2.tar.gz", hash = "sha256:38b7b51f512eed9e84a22788b4bce1de17c0adb134d6becb09836e37d8654cd3"}, +] + +[package.extras] +docs = ["furo (>=2023.9.10)", "proselint (>=0.13)", "sphinx (>=7.2.6)", "sphinx-autodoc-typehints (>=1.25.2)"] +test = ["appdirs (==1.4.4)", "covdefaults (>=2.3)", "pytest (>=7.4.3)", "pytest-cov (>=4.1)", "pytest-mock (>=3.12)"] +type = ["mypy (>=1.8)"] + +[[package]] +name = "pluggy" +version = "1.5.0" +description = "plugin and hook calling mechanisms for python" +optional = false +python-versions = ">=3.8" +files = [ + {file = "pluggy-1.5.0-py3-none-any.whl", hash = "sha256:44e1ad92c8ca002de6377e165f3e0f1be63266ab4d554740532335b9d75ea669"}, + {file = "pluggy-1.5.0.tar.gz", hash = "sha256:2cffa88e94fdc978c4c574f15f9e59b7f4201d439195c3715ca9e2486f1d0cf1"}, +] + +[package.extras] +dev = ["pre-commit", "tox"] +testing = ["pytest", "pytest-benchmark"] + +[[package]] +name = "prettytable" +version = "3.11.0" +description = "A simple Python library for easily displaying tabular data in a visually appealing ASCII table format" +optional = false +python-versions = ">=3.8" +files = [ + {file = "prettytable-3.11.0-py3-none-any.whl", hash = "sha256:aa17083feb6c71da11a68b2c213b04675c4af4ce9c541762632ca3f2cb3546dd"}, + {file = "prettytable-3.11.0.tar.gz", hash = "sha256:7e23ca1e68bbfd06ba8de98bf553bf3493264c96d5e8a615c0471025deeba722"}, +] + +[package.dependencies] +wcwidth = "*" + +[package.extras] +tests = ["pytest", "pytest-cov", "pytest-lazy-fixtures"] + +[[package]] +name = "prometheus-client" +version = "0.20.0" +description = "Python client for the Prometheus monitoring system." +optional = false +python-versions = ">=3.8" +files = [ + {file = "prometheus_client-0.20.0-py3-none-any.whl", hash = "sha256:cde524a85bce83ca359cc837f28b8c0db5cac7aa653a588fd7e84ba061c329e7"}, + {file = "prometheus_client-0.20.0.tar.gz", hash = "sha256:287629d00b147a32dcb2be0b9df905da599b2d82f80377083ec8463309a4bb89"}, +] + +[package.extras] +twisted = ["twisted"] + +[[package]] +name = "psutil" +version = "6.0.0" +description = "Cross-platform lib for process and system monitoring in Python." +optional = false +python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,>=2.7" +files = [ + {file = "psutil-6.0.0-cp27-cp27m-macosx_10_9_x86_64.whl", hash = "sha256:a021da3e881cd935e64a3d0a20983bda0bb4cf80e4f74fa9bfcb1bc5785360c6"}, + {file = "psutil-6.0.0-cp27-cp27m-manylinux2010_i686.whl", hash = "sha256:1287c2b95f1c0a364d23bc6f2ea2365a8d4d9b726a3be7294296ff7ba97c17f0"}, + {file = "psutil-6.0.0-cp27-cp27m-manylinux2010_x86_64.whl", hash = "sha256:a9a3dbfb4de4f18174528d87cc352d1f788b7496991cca33c6996f40c9e3c92c"}, + {file = "psutil-6.0.0-cp27-cp27mu-manylinux2010_i686.whl", hash = "sha256:6ec7588fb3ddaec7344a825afe298db83fe01bfaaab39155fa84cf1c0d6b13c3"}, + {file = "psutil-6.0.0-cp27-cp27mu-manylinux2010_x86_64.whl", hash = "sha256:1e7c870afcb7d91fdea2b37c24aeb08f98b6d67257a5cb0a8bc3ac68d0f1a68c"}, + {file = "psutil-6.0.0-cp27-none-win32.whl", hash = "sha256:02b69001f44cc73c1c5279d02b30a817e339ceb258ad75997325e0e6169d8b35"}, + {file = "psutil-6.0.0-cp27-none-win_amd64.whl", hash = "sha256:21f1fb635deccd510f69f485b87433460a603919b45e2a324ad65b0cc74f8fb1"}, + {file = "psutil-6.0.0-cp36-abi3-macosx_10_9_x86_64.whl", hash = "sha256:c588a7e9b1173b6e866756dde596fd4cad94f9399daf99ad8c3258b3cb2b47a0"}, + {file = "psutil-6.0.0-cp36-abi3-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6ed2440ada7ef7d0d608f20ad89a04ec47d2d3ab7190896cd62ca5fc4fe08bf0"}, + {file = "psutil-6.0.0-cp36-abi3-manylinux_2_12_x86_64.manylinux2010_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5fd9a97c8e94059b0ef54a7d4baf13b405011176c3b6ff257c247cae0d560ecd"}, + {file = "psutil-6.0.0-cp36-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e2e8d0054fc88153ca0544f5c4d554d42e33df2e009c4ff42284ac9ebdef4132"}, + {file = "psutil-6.0.0-cp36-cp36m-win32.whl", hash = "sha256:fc8c9510cde0146432bbdb433322861ee8c3efbf8589865c8bf8d21cb30c4d14"}, + {file = "psutil-6.0.0-cp36-cp36m-win_amd64.whl", hash = "sha256:34859b8d8f423b86e4385ff3665d3f4d94be3cdf48221fbe476e883514fdb71c"}, + {file = "psutil-6.0.0-cp37-abi3-win32.whl", hash = "sha256:a495580d6bae27291324fe60cea0b5a7c23fa36a7cd35035a16d93bdcf076b9d"}, + {file = "psutil-6.0.0-cp37-abi3-win_amd64.whl", hash = "sha256:33ea5e1c975250a720b3a6609c490db40dae5d83a4eb315170c4fe0d8b1f34b3"}, + {file = "psutil-6.0.0-cp38-abi3-macosx_11_0_arm64.whl", hash = "sha256:ffe7fc9b6b36beadc8c322f84e1caff51e8703b88eee1da46d1e3a6ae11b4fd0"}, + {file = "psutil-6.0.0.tar.gz", hash = "sha256:8faae4f310b6d969fa26ca0545338b21f73c6b15db7c4a8d934a5482faa818f2"}, +] + +[package.extras] +test = ["enum34", "ipaddress", "mock", "pywin32", "wmi"] + +[[package]] +name = "pycadf" +version = "3.1.1" +description = "CADF Library" +optional = false +python-versions = ">=3.6" +files = [ + {file = "pycadf-3.1.1-py3-none-any.whl", hash = "sha256:b1fa1dea7638c0f685fec9fceb94ae6409c42022c1b251d8a0d46a7ff9895f9c"}, + {file = "pycadf-3.1.1.tar.gz", hash = "sha256:2be491143d21fa3dd1f842ce8dd4973e95f580893887960faa5c11a6190081e8"}, +] + +[package.dependencies] +debtcollector = ">=1.2.0" +"oslo.config" = ">=5.2.0" +"oslo.serialization" = ">=2.18.0,<2.19.1 || >2.19.1" +pytz = ">=2013.6" +six = ">=1.10.0" + +[[package]] +name = "pycdlib" +version = "1.14.0" +description = "Pure python ISO manipulation library" +optional = false +python-versions = "*" +files = [ + {file = "pycdlib-1.14.0-py2.py3-none-any.whl", hash = "sha256:a905827335f0066af3fd416c5cf9b1f29dffaf4d0914b714555213d1809f38d4"}, + {file = "pycdlib-1.14.0.tar.gz", hash = "sha256:8ec306b31d9c850f28c5fda52438d904edd1e8fcf862c5ffd756272efac9f422"}, +] + +[[package]] +name = "pycparser" +version = "2.22" +description = "C parser in Python" +optional = false +python-versions = ">=3.8" +files = [ + {file = "pycparser-2.22-py3-none-any.whl", hash = "sha256:c3702b6d3dd8c7abc1afa565d7e63d53a1d0bd86cdc24edd75470f4de499cfcc"}, + {file = "pycparser-2.22.tar.gz", hash = "sha256:491c8be9c040f5390f5bf44a5b07752bd07f56edf992381b05c701439eec10f6"}, +] + +[[package]] +name = "pyjwt" +version = "2.9.0" +description = "JSON Web Token implementation in Python" +optional = false +python-versions = ">=3.8" +files = [ + {file = "PyJWT-2.9.0-py3-none-any.whl", hash = "sha256:3b02fb0f44517787776cf48f2ae25d8e14f300e6d7545a4315cee571a415e850"}, + {file = "pyjwt-2.9.0.tar.gz", hash = "sha256:7e1e5b56cc735432a7369cbfa0efe50fa113ebecdc04ae6922deba8b84582d0c"}, +] + +[package.extras] +crypto = ["cryptography (>=3.4.0)"] +dev = ["coverage[toml] (==5.0.4)", "cryptography (>=3.4.0)", "pre-commit", "pytest (>=6.0.0,<7.0.0)", "sphinx", "sphinx-rtd-theme", "zope.interface"] +docs = ["sphinx", "sphinx-rtd-theme", "zope.interface"] +tests = ["coverage[toml] (==5.0.4)", "pytest (>=6.0.0,<7.0.0)"] + +[[package]] +name = "pyparsing" +version = "3.1.2" +description = "pyparsing module - Classes and methods to define and execute parsing grammars" +optional = false +python-versions = ">=3.6.8" +files = [ + {file = "pyparsing-3.1.2-py3-none-any.whl", hash = "sha256:f9db75911801ed778fe61bb643079ff86601aca99fcae6345aa67292038fb742"}, + {file = "pyparsing-3.1.2.tar.gz", hash = "sha256:a1bac0ce561155ecc3ed78ca94d3c9378656ad4c94c1270de543f621420f94ad"}, +] + +[package.extras] +diagrams = ["jinja2", "railroad-diagrams"] + +[[package]] +name = "pytest" +version = "8.3.2" +description = "pytest: simple powerful testing with Python" +optional = false +python-versions = ">=3.8" +files = [ + {file = "pytest-8.3.2-py3-none-any.whl", hash = "sha256:4ba08f9ae7dcf84ded419494d229b48d0903ea6407b030eaec46df5e6a73bba5"}, + {file = "pytest-8.3.2.tar.gz", hash = "sha256:c132345d12ce551242c87269de812483f5bcc87cdbb4722e48487ba194f9fdce"}, +] + +[package.dependencies] +colorama = {version = "*", markers = "sys_platform == \"win32\""} +iniconfig = "*" +packaging = "*" +pluggy = ">=1.5,<2" + +[package.extras] +dev = ["argcomplete", "attrs (>=19.2)", "hypothesis (>=3.56)", "mock", "pygments (>=2.7.2)", "requests", "setuptools", "xmlschema"] + +[[package]] +name = "python-dateutil" +version = "2.9.0.post0" +description = "Extensions to the standard Python datetime module" +optional = false +python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,>=2.7" +files = [ + {file = "python-dateutil-2.9.0.post0.tar.gz", hash = "sha256:37dd54208da7e1cd875388217d5e00ebd4179249f90fb72437e91a35459a0ad3"}, + {file = "python_dateutil-2.9.0.post0-py2.py3-none-any.whl", hash = "sha256:a8b2bc7bffae282281c8140a97d3aa9c14da0b136dfe83f850eea9a5f7470427"}, +] + +[package.dependencies] +six = ">=1.5" + +[[package]] +name = "python-keystoneclient" +version = "5.4.0" +description = "Client Library for OpenStack Identity" +optional = false +python-versions = ">=3.8" +files = [ + {file = "python-keystoneclient-5.4.0.tar.gz", hash = "sha256:b2b4bdbe9daf7b0b353b8807672eeed01f87dd03b4f8b42d0d061b09b8931f41"}, + {file = "python_keystoneclient-5.4.0-py3-none-any.whl", hash = "sha256:9918043849032f387a0000104c553aac5ace02918a6b7afcdb99690164029867"}, +] + +[package.dependencies] +debtcollector = ">=1.2.0" +keystoneauth1 = ">=3.4.0" +"oslo.config" = ">=5.2.0" +"oslo.i18n" = ">=3.15.3" +"oslo.serialization" = ">=2.18.0,<2.19.1 || >2.19.1" +"oslo.utils" = ">=3.33.0" +packaging = ">=20.4" +pbr = ">=2.0.0,<2.1.0 || >2.1.0" +requests = ">=2.14.2" +stevedore = ">=1.20.0" + +[[package]] +name = "pytz" +version = "2024.1" +description = "World timezone definitions, modern and historical" +optional = false +python-versions = "*" +files = [ + {file = "pytz-2024.1-py2.py3-none-any.whl", hash = "sha256:328171f4e3623139da4983451950b28e95ac706e13f3f2630a879749e7a8b319"}, + {file = "pytz-2024.1.tar.gz", hash = "sha256:2a29735ea9c18baf14b448846bde5a48030ed267578472d8955cd0e7443a9812"}, +] + +[[package]] +name = "pyyaml" +version = "6.0.2" +description = "YAML parser and emitter for Python" +optional = false +python-versions = ">=3.8" +files = [ + {file = "PyYAML-6.0.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:0a9a2848a5b7feac301353437eb7d5957887edbf81d56e903999a75a3d743086"}, + {file = "PyYAML-6.0.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:29717114e51c84ddfba879543fb232a6ed60086602313ca38cce623c1d62cfbf"}, + {file = "PyYAML-6.0.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8824b5a04a04a047e72eea5cec3bc266db09e35de6bdfe34c9436ac5ee27d237"}, + {file = "PyYAML-6.0.2-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:7c36280e6fb8385e520936c3cb3b8042851904eba0e58d277dca80a5cfed590b"}, + {file = "PyYAML-6.0.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ec031d5d2feb36d1d1a24380e4db6d43695f3748343d99434e6f5f9156aaa2ed"}, + {file = "PyYAML-6.0.2-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:936d68689298c36b53b29f23c6dbb74de12b4ac12ca6cfe0e047bedceea56180"}, + {file = "PyYAML-6.0.2-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:23502f431948090f597378482b4812b0caae32c22213aecf3b55325e049a6c68"}, + {file = "PyYAML-6.0.2-cp310-cp310-win32.whl", hash = "sha256:2e99c6826ffa974fe6e27cdb5ed0021786b03fc98e5ee3c5bfe1fd5015f42b99"}, + {file = "PyYAML-6.0.2-cp310-cp310-win_amd64.whl", hash = "sha256:a4d3091415f010369ae4ed1fc6b79def9416358877534caf6a0fdd2146c87a3e"}, + {file = "PyYAML-6.0.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:cc1c1159b3d456576af7a3e4d1ba7e6924cb39de8f67111c735f6fc832082774"}, + {file = "PyYAML-6.0.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:1e2120ef853f59c7419231f3bf4e7021f1b936f6ebd222406c3b60212205d2ee"}, + {file = "PyYAML-6.0.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5d225db5a45f21e78dd9358e58a98702a0302f2659a3c6cd320564b75b86f47c"}, + {file = "PyYAML-6.0.2-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5ac9328ec4831237bec75defaf839f7d4564be1e6b25ac710bd1a96321cc8317"}, + {file = "PyYAML-6.0.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3ad2a3decf9aaba3d29c8f537ac4b243e36bef957511b4766cb0057d32b0be85"}, + {file = "PyYAML-6.0.2-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:ff3824dc5261f50c9b0dfb3be22b4567a6f938ccce4587b38952d85fd9e9afe4"}, + {file = "PyYAML-6.0.2-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:797b4f722ffa07cc8d62053e4cff1486fa6dc094105d13fea7b1de7d8bf71c9e"}, + {file = "PyYAML-6.0.2-cp311-cp311-win32.whl", hash = "sha256:11d8f3dd2b9c1207dcaf2ee0bbbfd5991f571186ec9cc78427ba5bd32afae4b5"}, + {file = "PyYAML-6.0.2-cp311-cp311-win_amd64.whl", hash = "sha256:e10ce637b18caea04431ce14fabcf5c64a1c61ec9c56b071a4b7ca131ca52d44"}, + {file = "PyYAML-6.0.2-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:c70c95198c015b85feafc136515252a261a84561b7b1d51e3384e0655ddf25ab"}, + {file = "PyYAML-6.0.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:ce826d6ef20b1bc864f0a68340c8b3287705cae2f8b4b1d932177dcc76721725"}, + {file = "PyYAML-6.0.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1f71ea527786de97d1a0cc0eacd1defc0985dcf6b3f17bb77dcfc8c34bec4dc5"}, + {file = "PyYAML-6.0.2-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:9b22676e8097e9e22e36d6b7bda33190d0d400f345f23d4065d48f4ca7ae0425"}, + {file = "PyYAML-6.0.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:80bab7bfc629882493af4aa31a4cfa43a4c57c83813253626916b8c7ada83476"}, + {file = "PyYAML-6.0.2-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:0833f8694549e586547b576dcfaba4a6b55b9e96098b36cdc7ebefe667dfed48"}, + {file = "PyYAML-6.0.2-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:8b9c7197f7cb2738065c481a0461e50ad02f18c78cd75775628afb4d7137fb3b"}, + {file = "PyYAML-6.0.2-cp312-cp312-win32.whl", hash = "sha256:ef6107725bd54b262d6dedcc2af448a266975032bc85ef0172c5f059da6325b4"}, + {file = "PyYAML-6.0.2-cp312-cp312-win_amd64.whl", hash = "sha256:7e7401d0de89a9a855c839bc697c079a4af81cf878373abd7dc625847d25cbd8"}, + {file = "PyYAML-6.0.2-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:efdca5630322a10774e8e98e1af481aad470dd62c3170801852d752aa7a783ba"}, + {file = "PyYAML-6.0.2-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:50187695423ffe49e2deacb8cd10510bc361faac997de9efef88badc3bb9e2d1"}, + {file = "PyYAML-6.0.2-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0ffe8360bab4910ef1b9e87fb812d8bc0a308b0d0eef8c8f44e0254ab3b07133"}, + {file = "PyYAML-6.0.2-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:17e311b6c678207928d649faa7cb0d7b4c26a0ba73d41e99c4fff6b6c3276484"}, + {file = "PyYAML-6.0.2-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:70b189594dbe54f75ab3a1acec5f1e3faa7e8cf2f1e08d9b561cb41b845f69d5"}, + {file = "PyYAML-6.0.2-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:41e4e3953a79407c794916fa277a82531dd93aad34e29c2a514c2c0c5fe971cc"}, + {file = "PyYAML-6.0.2-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:68ccc6023a3400877818152ad9a1033e3db8625d899c72eacb5a668902e4d652"}, + {file = "PyYAML-6.0.2-cp313-cp313-win32.whl", hash = "sha256:bc2fa7c6b47d6bc618dd7fb02ef6fdedb1090ec036abab80d4681424b84c1183"}, + {file = "PyYAML-6.0.2-cp313-cp313-win_amd64.whl", hash = "sha256:8388ee1976c416731879ac16da0aff3f63b286ffdd57cdeb95f3f2e085687563"}, + {file = "PyYAML-6.0.2-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:24471b829b3bf607e04e88d79542a9d48bb037c2267d7927a874e6c205ca7e9a"}, + {file = "PyYAML-6.0.2-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d7fded462629cfa4b685c5416b949ebad6cec74af5e2d42905d41e257e0869f5"}, + {file = "PyYAML-6.0.2-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:d84a1718ee396f54f3a086ea0a66d8e552b2ab2017ef8b420e92edbc841c352d"}, + {file = "PyYAML-6.0.2-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9056c1ecd25795207ad294bcf39f2db3d845767be0ea6e6a34d856f006006083"}, + {file = "PyYAML-6.0.2-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:82d09873e40955485746739bcb8b4586983670466c23382c19cffecbf1fd8706"}, + {file = "PyYAML-6.0.2-cp38-cp38-win32.whl", hash = "sha256:43fa96a3ca0d6b1812e01ced1044a003533c47f6ee8aca31724f78e93ccc089a"}, + {file = "PyYAML-6.0.2-cp38-cp38-win_amd64.whl", hash = "sha256:01179a4a8559ab5de078078f37e5c1a30d76bb88519906844fd7bdea1b7729ff"}, + {file = "PyYAML-6.0.2-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:688ba32a1cffef67fd2e9398a2efebaea461578b0923624778664cc1c914db5d"}, + {file = "PyYAML-6.0.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:a8786accb172bd8afb8be14490a16625cbc387036876ab6ba70912730faf8e1f"}, + {file = "PyYAML-6.0.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d8e03406cac8513435335dbab54c0d385e4a49e4945d2909a581c83647ca0290"}, + {file = "PyYAML-6.0.2-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f753120cb8181e736c57ef7636e83f31b9c0d1722c516f7e86cf15b7aa57ff12"}, + {file = "PyYAML-6.0.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3b1fdb9dc17f5a7677423d508ab4f243a726dea51fa5e70992e59a7411c89d19"}, + {file = "PyYAML-6.0.2-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:0b69e4ce7a131fe56b7e4d770c67429700908fc0752af059838b1cfb41960e4e"}, + {file = "PyYAML-6.0.2-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:a9f8c2e67970f13b16084e04f134610fd1d374bf477b17ec1599185cf611d725"}, + {file = "PyYAML-6.0.2-cp39-cp39-win32.whl", hash = "sha256:6395c297d42274772abc367baaa79683958044e5d3835486c16da75d2a694631"}, + {file = "PyYAML-6.0.2-cp39-cp39-win_amd64.whl", hash = "sha256:39693e1f8320ae4f43943590b49779ffb98acb81f788220ea932a6b6c51004d8"}, + {file = "pyyaml-6.0.2.tar.gz", hash = "sha256:d584d9ec91ad65861cc08d42e834324ef890a082e591037abe114850ff7bbc3e"}, +] + +[[package]] +name = "referencing" +version = "0.35.1" +description = "JSON Referencing + Python" +optional = false +python-versions = ">=3.8" +files = [ + {file = "referencing-0.35.1-py3-none-any.whl", hash = "sha256:eda6d3234d62814d1c64e305c1331c9a3a6132da475ab6382eaa997b21ee75de"}, + {file = "referencing-0.35.1.tar.gz", hash = "sha256:25b42124a6c8b632a425174f24087783efb348a6f1e0008e63cd4466fedf703c"}, +] + +[package.dependencies] +attrs = ">=22.2.0" +rpds-py = ">=0.7.0" + +[[package]] +name = "repoze-lru" +version = "0.7" +description = "A tiny LRU cache implementation and decorator" +optional = false +python-versions = "*" +files = [ + {file = "repoze.lru-0.7-py3-none-any.whl", hash = "sha256:f77bf0e1096ea445beadd35f3479c5cff2aa1efe604a133e67150bc8630a62ea"}, + {file = "repoze.lru-0.7.tar.gz", hash = "sha256:0429a75e19380e4ed50c0694e26ac8819b4ea7851ee1fc7583c8572db80aff77"}, +] + +[package.extras] +docs = ["Sphinx"] +testing = ["coverage", "nose"] + +[[package]] +name = "requests" +version = "2.32.3" +description = "Python HTTP for Humans." +optional = false +python-versions = ">=3.8" +files = [ + {file = "requests-2.32.3-py3-none-any.whl", hash = "sha256:70761cfe03c773ceb22aa2f671b4757976145175cdfca038c02654d061d6dcc6"}, + {file = "requests-2.32.3.tar.gz", hash = "sha256:55365417734eb18255590a9ff9eb97e9e1da868d4ccd6402399eaf68af20a760"}, +] + +[package.dependencies] +certifi = ">=2017.4.17" +charset-normalizer = ">=2,<4" +idna = ">=2.5,<4" +urllib3 = ">=1.21.1,<3" + +[package.extras] +socks = ["PySocks (>=1.5.6,!=1.5.7)"] +use-chardet-on-py3 = ["chardet (>=3.0.2,<6)"] + +[[package]] +name = "requestsexceptions" +version = "1.4.0" +description = "Import exceptions from potentially bundled packages in requests." +optional = false +python-versions = "*" +files = [ + {file = "requestsexceptions-1.4.0-py2.py3-none-any.whl", hash = "sha256:3083d872b6e07dc5c323563ef37671d992214ad9a32b0ca4a3d7f5500bf38ce3"}, + {file = "requestsexceptions-1.4.0.tar.gz", hash = "sha256:b095cbc77618f066d459a02b137b020c37da9f46d9b057704019c9f77dba3065"}, +] + +[[package]] +name = "rfc3986" +version = "2.0.0" +description = "Validating URI References per RFC 3986" +optional = false +python-versions = ">=3.7" +files = [ + {file = "rfc3986-2.0.0-py2.py3-none-any.whl", hash = "sha256:50b1502b60e289cb37883f3dfd34532b8873c7de9f49bb546641ce9cbd256ebd"}, + {file = "rfc3986-2.0.0.tar.gz", hash = "sha256:97aacf9dbd4bfd829baad6e6309fa6573aaf1be3f6fa735c8ab05e46cecb261c"}, +] + +[package.extras] +idna2008 = ["idna"] + +[[package]] +name = "routes" +version = "2.5.1" +description = "Routing Recognition and Generation Tools" +optional = false +python-versions = "*" +files = [ + {file = "Routes-2.5.1-py2.py3-none-any.whl", hash = "sha256:fab5a042a3a87778eb271d053ca2723cadf43c95b471532a191a48539cb606ea"}, + {file = "Routes-2.5.1.tar.gz", hash = "sha256:b6346459a15f0cbab01a45a90c3d25caf980d4733d628b4cc1952b865125d053"}, +] + +[package.dependencies] +"repoze.lru" = ">=0.3" +six = "*" + +[package.extras] +docs = ["Sphinx", "webob"] +middleware = ["webob"] + +[[package]] +name = "rpds-py" +version = "0.20.0" +description = "Python bindings to Rust's persistent data structures (rpds)" +optional = false +python-versions = ">=3.8" +files = [ + {file = "rpds_py-0.20.0-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:3ad0fda1635f8439cde85c700f964b23ed5fc2d28016b32b9ee5fe30da5c84e2"}, + {file = "rpds_py-0.20.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:9bb4a0d90fdb03437c109a17eade42dfbf6190408f29b2744114d11586611d6f"}, + {file = "rpds_py-0.20.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c6377e647bbfd0a0b159fe557f2c6c602c159fc752fa316572f012fc0bf67150"}, + {file = "rpds_py-0.20.0-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:eb851b7df9dda52dc1415ebee12362047ce771fc36914586b2e9fcbd7d293b3e"}, + {file = "rpds_py-0.20.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1e0f80b739e5a8f54837be5d5c924483996b603d5502bfff79bf33da06164ee2"}, + {file = "rpds_py-0.20.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5a8c94dad2e45324fc74dce25e1645d4d14df9a4e54a30fa0ae8bad9a63928e3"}, + {file = "rpds_py-0.20.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f8e604fe73ba048c06085beaf51147eaec7df856824bfe7b98657cf436623daf"}, + {file = "rpds_py-0.20.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:df3de6b7726b52966edf29663e57306b23ef775faf0ac01a3e9f4012a24a4140"}, + {file = "rpds_py-0.20.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:cf258ede5bc22a45c8e726b29835b9303c285ab46fc7c3a4cc770736b5304c9f"}, + {file = "rpds_py-0.20.0-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:55fea87029cded5df854ca7e192ec7bdb7ecd1d9a3f63d5c4eb09148acf4a7ce"}, + {file = "rpds_py-0.20.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:ae94bd0b2f02c28e199e9bc51485d0c5601f58780636185660f86bf80c89af94"}, + {file = "rpds_py-0.20.0-cp310-none-win32.whl", hash = "sha256:28527c685f237c05445efec62426d285e47a58fb05ba0090a4340b73ecda6dee"}, + {file = "rpds_py-0.20.0-cp310-none-win_amd64.whl", hash = "sha256:238a2d5b1cad28cdc6ed15faf93a998336eb041c4e440dd7f902528b8891b399"}, + {file = "rpds_py-0.20.0-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:ac2f4f7a98934c2ed6505aead07b979e6f999389f16b714448fb39bbaa86a489"}, + {file = "rpds_py-0.20.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:220002c1b846db9afd83371d08d239fdc865e8f8c5795bbaec20916a76db3318"}, + {file = "rpds_py-0.20.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8d7919548df3f25374a1f5d01fbcd38dacab338ef5f33e044744b5c36729c8db"}, + {file = "rpds_py-0.20.0-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:758406267907b3781beee0f0edfe4a179fbd97c0be2e9b1154d7f0a1279cf8e5"}, + {file = "rpds_py-0.20.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:3d61339e9f84a3f0767b1995adfb171a0d00a1185192718a17af6e124728e0f5"}, + {file = "rpds_py-0.20.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:1259c7b3705ac0a0bd38197565a5d603218591d3f6cee6e614e380b6ba61c6f6"}, + {file = "rpds_py-0.20.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5c1dc0f53856b9cc9a0ccca0a7cc61d3d20a7088201c0937f3f4048c1718a209"}, + {file = "rpds_py-0.20.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:7e60cb630f674a31f0368ed32b2a6b4331b8350d67de53c0359992444b116dd3"}, + {file = "rpds_py-0.20.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:dbe982f38565bb50cb7fb061ebf762c2f254ca3d8c20d4006878766e84266272"}, + {file = "rpds_py-0.20.0-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:514b3293b64187172bc77c8fb0cdae26981618021053b30d8371c3a902d4d5ad"}, + {file = "rpds_py-0.20.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:d0a26ffe9d4dd35e4dfdd1e71f46401cff0181c75ac174711ccff0459135fa58"}, + {file = "rpds_py-0.20.0-cp311-none-win32.whl", hash = "sha256:89c19a494bf3ad08c1da49445cc5d13d8fefc265f48ee7e7556839acdacf69d0"}, + {file = "rpds_py-0.20.0-cp311-none-win_amd64.whl", hash = "sha256:c638144ce971df84650d3ed0096e2ae7af8e62ecbbb7b201c8935c370df00a2c"}, + {file = "rpds_py-0.20.0-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:a84ab91cbe7aab97f7446652d0ed37d35b68a465aeef8fc41932a9d7eee2c1a6"}, + {file = "rpds_py-0.20.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:56e27147a5a4c2c21633ff8475d185734c0e4befd1c989b5b95a5d0db699b21b"}, + {file = "rpds_py-0.20.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2580b0c34583b85efec8c5c5ec9edf2dfe817330cc882ee972ae650e7b5ef739"}, + {file = "rpds_py-0.20.0-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:b80d4a7900cf6b66bb9cee5c352b2d708e29e5a37fe9bf784fa97fc11504bf6c"}, + {file = "rpds_py-0.20.0-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:50eccbf054e62a7b2209b28dc7a22d6254860209d6753e6b78cfaeb0075d7bee"}, + {file = "rpds_py-0.20.0-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:49a8063ea4296b3a7e81a5dfb8f7b2d73f0b1c20c2af401fb0cdf22e14711a96"}, + {file = "rpds_py-0.20.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ea438162a9fcbee3ecf36c23e6c68237479f89f962f82dae83dc15feeceb37e4"}, + {file = "rpds_py-0.20.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:18d7585c463087bddcfa74c2ba267339f14f2515158ac4db30b1f9cbdb62c8ef"}, + {file = "rpds_py-0.20.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:d4c7d1a051eeb39f5c9547e82ea27cbcc28338482242e3e0b7768033cb083821"}, + {file = "rpds_py-0.20.0-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:e4df1e3b3bec320790f699890d41c59d250f6beda159ea3c44c3f5bac1976940"}, + {file = "rpds_py-0.20.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:2cf126d33a91ee6eedc7f3197b53e87a2acdac63602c0f03a02dd69e4b138174"}, + {file = "rpds_py-0.20.0-cp312-none-win32.whl", hash = "sha256:8bc7690f7caee50b04a79bf017a8d020c1f48c2a1077ffe172abec59870f1139"}, + {file = "rpds_py-0.20.0-cp312-none-win_amd64.whl", hash = "sha256:0e13e6952ef264c40587d510ad676a988df19adea20444c2b295e536457bc585"}, + {file = "rpds_py-0.20.0-cp313-cp313-macosx_10_12_x86_64.whl", hash = "sha256:aa9a0521aeca7d4941499a73ad7d4f8ffa3d1affc50b9ea11d992cd7eff18a29"}, + {file = "rpds_py-0.20.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:4a1f1d51eccb7e6c32ae89243cb352389228ea62f89cd80823ea7dd1b98e0b91"}, + {file = "rpds_py-0.20.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8a86a9b96070674fc88b6f9f71a97d2c1d3e5165574615d1f9168ecba4cecb24"}, + {file = "rpds_py-0.20.0-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:6c8ef2ebf76df43f5750b46851ed1cdf8f109d7787ca40035fe19fbdc1acc5a7"}, + {file = "rpds_py-0.20.0-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b74b25f024b421d5859d156750ea9a65651793d51b76a2e9238c05c9d5f203a9"}, + {file = "rpds_py-0.20.0-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:57eb94a8c16ab08fef6404301c38318e2c5a32216bf5de453e2714c964c125c8"}, + {file = "rpds_py-0.20.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e1940dae14e715e2e02dfd5b0f64a52e8374a517a1e531ad9412319dc3ac7879"}, + {file = "rpds_py-0.20.0-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:d20277fd62e1b992a50c43f13fbe13277a31f8c9f70d59759c88f644d66c619f"}, + {file = "rpds_py-0.20.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:06db23d43f26478303e954c34c75182356ca9aa7797d22c5345b16871ab9c45c"}, + {file = "rpds_py-0.20.0-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:b2a5db5397d82fa847e4c624b0c98fe59d2d9b7cf0ce6de09e4d2e80f8f5b3f2"}, + {file = "rpds_py-0.20.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:5a35df9f5548fd79cb2f52d27182108c3e6641a4feb0f39067911bf2adaa3e57"}, + {file = "rpds_py-0.20.0-cp313-none-win32.whl", hash = "sha256:fd2d84f40633bc475ef2d5490b9c19543fbf18596dcb1b291e3a12ea5d722f7a"}, + {file = "rpds_py-0.20.0-cp313-none-win_amd64.whl", hash = "sha256:9bc2d153989e3216b0559251b0c260cfd168ec78b1fac33dd485750a228db5a2"}, + {file = "rpds_py-0.20.0-cp38-cp38-macosx_10_12_x86_64.whl", hash = "sha256:f2fbf7db2012d4876fb0d66b5b9ba6591197b0f165db8d99371d976546472a24"}, + {file = "rpds_py-0.20.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:1e5f3cd7397c8f86c8cc72d5a791071431c108edd79872cdd96e00abd8497d29"}, + {file = "rpds_py-0.20.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ce9845054c13696f7af7f2b353e6b4f676dab1b4b215d7fe5e05c6f8bb06f965"}, + {file = "rpds_py-0.20.0-cp38-cp38-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:c3e130fd0ec56cb76eb49ef52faead8ff09d13f4527e9b0c400307ff72b408e1"}, + {file = "rpds_py-0.20.0-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:4b16aa0107ecb512b568244ef461f27697164d9a68d8b35090e9b0c1c8b27752"}, + {file = "rpds_py-0.20.0-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:aa7f429242aae2947246587d2964fad750b79e8c233a2367f71b554e9447949c"}, + {file = "rpds_py-0.20.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:af0fc424a5842a11e28956e69395fbbeab2c97c42253169d87e90aac2886d751"}, + {file = "rpds_py-0.20.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:b8c00a3b1e70c1d3891f0db1b05292747f0dbcfb49c43f9244d04c70fbc40eb8"}, + {file = "rpds_py-0.20.0-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:40ce74fc86ee4645d0a225498d091d8bc61f39b709ebef8204cb8b5a464d3c0e"}, + {file = "rpds_py-0.20.0-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:4fe84294c7019456e56d93e8ababdad5a329cd25975be749c3f5f558abb48253"}, + {file = "rpds_py-0.20.0-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:338ca4539aad4ce70a656e5187a3a31c5204f261aef9f6ab50e50bcdffaf050a"}, + {file = "rpds_py-0.20.0-cp38-none-win32.whl", hash = "sha256:54b43a2b07db18314669092bb2de584524d1ef414588780261e31e85846c26a5"}, + {file = "rpds_py-0.20.0-cp38-none-win_amd64.whl", hash = "sha256:a1862d2d7ce1674cffa6d186d53ca95c6e17ed2b06b3f4c476173565c862d232"}, + {file = "rpds_py-0.20.0-cp39-cp39-macosx_10_12_x86_64.whl", hash = "sha256:3fde368e9140312b6e8b6c09fb9f8c8c2f00999d1823403ae90cc00480221b22"}, + {file = "rpds_py-0.20.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:9824fb430c9cf9af743cf7aaf6707bf14323fb51ee74425c380f4c846ea70789"}, + {file = "rpds_py-0.20.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:11ef6ce74616342888b69878d45e9f779b95d4bd48b382a229fe624a409b72c5"}, + {file = "rpds_py-0.20.0-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:c52d3f2f82b763a24ef52f5d24358553e8403ce05f893b5347098014f2d9eff2"}, + {file = "rpds_py-0.20.0-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:9d35cef91e59ebbeaa45214861874bc6f19eb35de96db73e467a8358d701a96c"}, + {file = "rpds_py-0.20.0-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:d72278a30111e5b5525c1dd96120d9e958464316f55adb030433ea905866f4de"}, + {file = "rpds_py-0.20.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b4c29cbbba378759ac5786730d1c3cb4ec6f8ababf5c42a9ce303dc4b3d08cda"}, + {file = "rpds_py-0.20.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:6632f2d04f15d1bd6fe0eedd3b86d9061b836ddca4c03d5cf5c7e9e6b7c14580"}, + {file = "rpds_py-0.20.0-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:d0b67d87bb45ed1cd020e8fbf2307d449b68abc45402fe1a4ac9e46c3c8b192b"}, + {file = "rpds_py-0.20.0-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:ec31a99ca63bf3cd7f1a5ac9fe95c5e2d060d3c768a09bc1d16e235840861420"}, + {file = "rpds_py-0.20.0-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:22e6c9976e38f4d8c4a63bd8a8edac5307dffd3ee7e6026d97f3cc3a2dc02a0b"}, + {file = "rpds_py-0.20.0-cp39-none-win32.whl", hash = "sha256:569b3ea770c2717b730b61998b6c54996adee3cef69fc28d444f3e7920313cf7"}, + {file = "rpds_py-0.20.0-cp39-none-win_amd64.whl", hash = "sha256:e6900ecdd50ce0facf703f7a00df12374b74bbc8ad9fe0f6559947fb20f82364"}, + {file = "rpds_py-0.20.0-pp310-pypy310_pp73-macosx_10_12_x86_64.whl", hash = "sha256:617c7357272c67696fd052811e352ac54ed1d9b49ab370261a80d3b6ce385045"}, + {file = "rpds_py-0.20.0-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:9426133526f69fcaba6e42146b4e12d6bc6c839b8b555097020e2b78ce908dcc"}, + {file = "rpds_py-0.20.0-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:deb62214c42a261cb3eb04d474f7155279c1a8a8c30ac89b7dcb1721d92c3c02"}, + {file = "rpds_py-0.20.0-pp310-pypy310_pp73-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:fcaeb7b57f1a1e071ebd748984359fef83ecb026325b9d4ca847c95bc7311c92"}, + {file = "rpds_py-0.20.0-pp310-pypy310_pp73-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d454b8749b4bd70dd0a79f428731ee263fa6995f83ccb8bada706e8d1d3ff89d"}, + {file = "rpds_py-0.20.0-pp310-pypy310_pp73-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:d807dc2051abe041b6649681dce568f8e10668e3c1c6543ebae58f2d7e617855"}, + {file = "rpds_py-0.20.0-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c3c20f0ddeb6e29126d45f89206b8291352b8c5b44384e78a6499d68b52ae511"}, + {file = "rpds_py-0.20.0-pp310-pypy310_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:b7f19250ceef892adf27f0399b9e5afad019288e9be756d6919cb58892129f51"}, + {file = "rpds_py-0.20.0-pp310-pypy310_pp73-musllinux_1_2_aarch64.whl", hash = "sha256:4f1ed4749a08379555cebf4650453f14452eaa9c43d0a95c49db50c18b7da075"}, + {file = "rpds_py-0.20.0-pp310-pypy310_pp73-musllinux_1_2_i686.whl", hash = "sha256:dcedf0b42bcb4cfff4101d7771a10532415a6106062f005ab97d1d0ab5681c60"}, + {file = "rpds_py-0.20.0-pp310-pypy310_pp73-musllinux_1_2_x86_64.whl", hash = "sha256:39ed0d010457a78f54090fafb5d108501b5aa5604cc22408fc1c0c77eac14344"}, + {file = "rpds_py-0.20.0-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:bb273176be34a746bdac0b0d7e4e2c467323d13640b736c4c477881a3220a989"}, + {file = "rpds_py-0.20.0-pp39-pypy39_pp73-macosx_10_12_x86_64.whl", hash = "sha256:f918a1a130a6dfe1d7fe0f105064141342e7dd1611f2e6a21cd2f5c8cb1cfb3e"}, + {file = "rpds_py-0.20.0-pp39-pypy39_pp73-macosx_11_0_arm64.whl", hash = "sha256:f60012a73aa396be721558caa3a6fd49b3dd0033d1675c6d59c4502e870fcf0c"}, + {file = "rpds_py-0.20.0-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3d2b1ad682a3dfda2a4e8ad8572f3100f95fad98cb99faf37ff0ddfe9cbf9d03"}, + {file = "rpds_py-0.20.0-pp39-pypy39_pp73-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:614fdafe9f5f19c63ea02817fa4861c606a59a604a77c8cdef5aa01d28b97921"}, + {file = "rpds_py-0.20.0-pp39-pypy39_pp73-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:fa518bcd7600c584bf42e6617ee8132869e877db2f76bcdc281ec6a4113a53ab"}, + {file = "rpds_py-0.20.0-pp39-pypy39_pp73-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f0475242f447cc6cb8a9dd486d68b2ef7fbee84427124c232bff5f63b1fe11e5"}, + {file = "rpds_py-0.20.0-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f90a4cd061914a60bd51c68bcb4357086991bd0bb93d8aa66a6da7701370708f"}, + {file = "rpds_py-0.20.0-pp39-pypy39_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:def7400461c3a3f26e49078302e1c1b38f6752342c77e3cf72ce91ca69fb1bc1"}, + {file = "rpds_py-0.20.0-pp39-pypy39_pp73-musllinux_1_2_aarch64.whl", hash = "sha256:65794e4048ee837494aea3c21a28ad5fc080994dfba5b036cf84de37f7ad5074"}, + {file = "rpds_py-0.20.0-pp39-pypy39_pp73-musllinux_1_2_i686.whl", hash = "sha256:faefcc78f53a88f3076b7f8be0a8f8d35133a3ecf7f3770895c25f8813460f08"}, + {file = "rpds_py-0.20.0-pp39-pypy39_pp73-musllinux_1_2_x86_64.whl", hash = "sha256:5b4f105deeffa28bbcdff6c49b34e74903139afa690e35d2d9e3c2c2fba18cec"}, + {file = "rpds_py-0.20.0-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:fdfc3a892927458d98f3d55428ae46b921d1f7543b89382fdb483f5640daaec8"}, + {file = "rpds_py-0.20.0.tar.gz", hash = "sha256:d72a210824facfdaf8768cf2d7ca25a042c30320b3020de2fa04640920d4e121"}, +] + +[[package]] +name = "setuptools" +version = "73.0.1" +description = "Easily download, build, install, upgrade, and uninstall Python packages" +optional = false +python-versions = ">=3.8" +files = [ + {file = "setuptools-73.0.1-py3-none-any.whl", hash = "sha256:b208925fcb9f7af924ed2dc04708ea89791e24bde0d3020b27df0e116088b34e"}, + {file = "setuptools-73.0.1.tar.gz", hash = "sha256:d59a3e788ab7e012ab2c4baed1b376da6366883ee20d7a5fc426816e3d7b1193"}, +] + +[package.extras] +core = ["importlib-metadata (>=6)", "importlib-resources (>=5.10.2)", "jaraco.text (>=3.7)", "more-itertools (>=8.8)", "packaging (>=24)", "platformdirs (>=2.6.2)", "tomli (>=2.0.1)", "wheel (>=0.43.0)"] +doc = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "pygments-github-lexers (==0.0.5)", "pyproject-hooks (!=1.1)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-favicon", "sphinx-inline-tabs", "sphinx-lint", "sphinx-notfound-page (>=1,<2)", "sphinx-reredirects", "sphinxcontrib-towncrier", "towncrier (<24.7)"] +test = ["build[virtualenv] (>=1.0.3)", "filelock (>=3.4.0)", "importlib-metadata", "ini2toml[lite] (>=0.14)", "jaraco.develop (>=7.21)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "jaraco.test", "mypy (==1.11.*)", "packaging (>=23.2)", "pip (>=19.1)", "pyproject-hooks (!=1.1)", "pytest (>=6,!=8.1.*)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=2.2)", "pytest-home (>=0.5)", "pytest-mypy", "pytest-perf", "pytest-ruff (<0.4)", "pytest-ruff (>=0.2.1)", "pytest-ruff (>=0.3.2)", "pytest-subprocess", "pytest-timeout", "pytest-xdist (>=3)", "tomli", "tomli-w (>=1.0.0)", "virtualenv (>=13.0.0)", "wheel (>=0.44.0)"] + +[[package]] +name = "six" +version = "1.16.0" +description = "Python 2 and 3 compatibility utilities" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*" +files = [ + {file = "six-1.16.0-py2.py3-none-any.whl", hash = "sha256:8abb2f1d86890a2dfb989f9a77cfcfd3e47c2a354b01111771326f8aa26e0254"}, + {file = "six-1.16.0.tar.gz", hash = "sha256:1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926"}, +] + +[[package]] +name = "sqlalchemy" +version = "2.0.32" +description = "Database Abstraction Library" +optional = false +python-versions = ">=3.7" +files = [ + {file = "SQLAlchemy-2.0.32-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:0c9045ecc2e4db59bfc97b20516dfdf8e41d910ac6fb667ebd3a79ea54084619"}, + {file = "SQLAlchemy-2.0.32-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:1467940318e4a860afd546ef61fefb98a14d935cd6817ed07a228c7f7c62f389"}, + {file = "SQLAlchemy-2.0.32-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5954463675cb15db8d4b521f3566a017c8789222b8316b1e6934c811018ee08b"}, + {file = "SQLAlchemy-2.0.32-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:167e7497035c303ae50651b351c28dc22a40bb98fbdb8468cdc971821b1ae533"}, + {file = "SQLAlchemy-2.0.32-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:b27dfb676ac02529fb6e343b3a482303f16e6bc3a4d868b73935b8792edb52d0"}, + {file = "SQLAlchemy-2.0.32-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:bf2360a5e0f7bd75fa80431bf8ebcfb920c9f885e7956c7efde89031695cafb8"}, + {file = "SQLAlchemy-2.0.32-cp310-cp310-win32.whl", hash = "sha256:306fe44e754a91cd9d600a6b070c1f2fadbb4a1a257b8781ccf33c7067fd3e4d"}, + {file = "SQLAlchemy-2.0.32-cp310-cp310-win_amd64.whl", hash = "sha256:99db65e6f3ab42e06c318f15c98f59a436f1c78179e6a6f40f529c8cc7100b22"}, + {file = "SQLAlchemy-2.0.32-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:21b053be28a8a414f2ddd401f1be8361e41032d2ef5884b2f31d31cb723e559f"}, + {file = "SQLAlchemy-2.0.32-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:b178e875a7a25b5938b53b006598ee7645172fccafe1c291a706e93f48499ff5"}, + {file = "SQLAlchemy-2.0.32-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:723a40ee2cc7ea653645bd4cf024326dea2076673fc9d3d33f20f6c81db83e1d"}, + {file = "SQLAlchemy-2.0.32-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:295ff8689544f7ee7e819529633d058bd458c1fd7f7e3eebd0f9268ebc56c2a0"}, + {file = "SQLAlchemy-2.0.32-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:49496b68cd190a147118af585173ee624114dfb2e0297558c460ad7495f9dfe2"}, + {file = "SQLAlchemy-2.0.32-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:acd9b73c5c15f0ec5ce18128b1fe9157ddd0044abc373e6ecd5ba376a7e5d961"}, + {file = "SQLAlchemy-2.0.32-cp311-cp311-win32.whl", hash = "sha256:9365a3da32dabd3e69e06b972b1ffb0c89668994c7e8e75ce21d3e5e69ddef28"}, + {file = "SQLAlchemy-2.0.32-cp311-cp311-win_amd64.whl", hash = "sha256:8bd63d051f4f313b102a2af1cbc8b80f061bf78f3d5bd0843ff70b5859e27924"}, + {file = "SQLAlchemy-2.0.32-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:6bab3db192a0c35e3c9d1560eb8332463e29e5507dbd822e29a0a3c48c0a8d92"}, + {file = "SQLAlchemy-2.0.32-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:19d98f4f58b13900d8dec4ed09dd09ef292208ee44cc9c2fe01c1f0a2fe440e9"}, + {file = "SQLAlchemy-2.0.32-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3cd33c61513cb1b7371fd40cf221256456d26a56284e7d19d1f0b9f1eb7dd7e8"}, + {file = "SQLAlchemy-2.0.32-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7d6ba0497c1d066dd004e0f02a92426ca2df20fac08728d03f67f6960271feec"}, + {file = "SQLAlchemy-2.0.32-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:2b6be53e4fde0065524f1a0a7929b10e9280987b320716c1509478b712a7688c"}, + {file = "SQLAlchemy-2.0.32-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:916a798f62f410c0b80b63683c8061f5ebe237b0f4ad778739304253353bc1cb"}, + {file = "SQLAlchemy-2.0.32-cp312-cp312-win32.whl", hash = "sha256:31983018b74908ebc6c996a16ad3690301a23befb643093fcfe85efd292e384d"}, + {file = "SQLAlchemy-2.0.32-cp312-cp312-win_amd64.whl", hash = "sha256:4363ed245a6231f2e2957cccdda3c776265a75851f4753c60f3004b90e69bfeb"}, + {file = "SQLAlchemy-2.0.32-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:b8afd5b26570bf41c35c0121801479958b4446751a3971fb9a480c1afd85558e"}, + {file = "SQLAlchemy-2.0.32-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c750987fc876813f27b60d619b987b057eb4896b81117f73bb8d9918c14f1cad"}, + {file = "SQLAlchemy-2.0.32-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ada0102afff4890f651ed91120c1120065663506b760da4e7823913ebd3258be"}, + {file = "SQLAlchemy-2.0.32-cp37-cp37m-musllinux_1_2_aarch64.whl", hash = "sha256:78c03d0f8a5ab4f3034c0e8482cfcc415a3ec6193491cfa1c643ed707d476f16"}, + {file = "SQLAlchemy-2.0.32-cp37-cp37m-musllinux_1_2_x86_64.whl", hash = "sha256:3bd1cae7519283ff525e64645ebd7a3e0283f3c038f461ecc1c7b040a0c932a1"}, + {file = "SQLAlchemy-2.0.32-cp37-cp37m-win32.whl", hash = "sha256:01438ebcdc566d58c93af0171c74ec28efe6a29184b773e378a385e6215389da"}, + {file = "SQLAlchemy-2.0.32-cp37-cp37m-win_amd64.whl", hash = "sha256:4979dc80fbbc9d2ef569e71e0896990bc94df2b9fdbd878290bd129b65ab579c"}, + {file = "SQLAlchemy-2.0.32-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:6c742be912f57586ac43af38b3848f7688863a403dfb220193a882ea60e1ec3a"}, + {file = "SQLAlchemy-2.0.32-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:62e23d0ac103bcf1c5555b6c88c114089587bc64d048fef5bbdb58dfd26f96da"}, + {file = "SQLAlchemy-2.0.32-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:251f0d1108aab8ea7b9aadbd07fb47fb8e3a5838dde34aa95a3349876b5a1f1d"}, + {file = "SQLAlchemy-2.0.32-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0ef18a84e5116340e38eca3e7f9eeaaef62738891422e7c2a0b80feab165905f"}, + {file = "SQLAlchemy-2.0.32-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:3eb6a97a1d39976f360b10ff208c73afb6a4de86dd2a6212ddf65c4a6a2347d5"}, + {file = "SQLAlchemy-2.0.32-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:0c1c9b673d21477cec17ab10bc4decb1322843ba35b481585facd88203754fc5"}, + {file = "SQLAlchemy-2.0.32-cp38-cp38-win32.whl", hash = "sha256:c41a2b9ca80ee555decc605bd3c4520cc6fef9abde8fd66b1cf65126a6922d65"}, + {file = "SQLAlchemy-2.0.32-cp38-cp38-win_amd64.whl", hash = "sha256:8a37e4d265033c897892279e8adf505c8b6b4075f2b40d77afb31f7185cd6ecd"}, + {file = "SQLAlchemy-2.0.32-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:52fec964fba2ef46476312a03ec8c425956b05c20220a1a03703537824b5e8e1"}, + {file = "SQLAlchemy-2.0.32-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:328429aecaba2aee3d71e11f2477c14eec5990fb6d0e884107935f7fb6001632"}, + {file = "SQLAlchemy-2.0.32-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:85a01b5599e790e76ac3fe3aa2f26e1feba56270023d6afd5550ed63c68552b3"}, + {file = "SQLAlchemy-2.0.32-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:aaf04784797dcdf4c0aa952c8d234fa01974c4729db55c45732520ce12dd95b4"}, + {file = "SQLAlchemy-2.0.32-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:4488120becf9b71b3ac718f4138269a6be99a42fe023ec457896ba4f80749525"}, + {file = "SQLAlchemy-2.0.32-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:14e09e083a5796d513918a66f3d6aedbc131e39e80875afe81d98a03312889e6"}, + {file = "SQLAlchemy-2.0.32-cp39-cp39-win32.whl", hash = "sha256:0d322cc9c9b2154ba7e82f7bf25ecc7c36fbe2d82e2933b3642fc095a52cfc78"}, + {file = "SQLAlchemy-2.0.32-cp39-cp39-win_amd64.whl", hash = "sha256:7dd8583df2f98dea28b5cd53a1beac963f4f9d087888d75f22fcc93a07cf8d84"}, + {file = "SQLAlchemy-2.0.32-py3-none-any.whl", hash = "sha256:e567a8793a692451f706b363ccf3c45e056b67d90ead58c3bc9471af5d212202"}, + {file = "SQLAlchemy-2.0.32.tar.gz", hash = "sha256:c1b88cc8b02b6a5f0efb0345a03672d4c897dc7d92585176f88c67346f565ea8"}, +] + +[package.dependencies] +greenlet = {version = "!=0.4.17", markers = "python_version < \"3.13\" and (platform_machine == \"aarch64\" or platform_machine == \"ppc64le\" or platform_machine == \"x86_64\" or platform_machine == \"amd64\" or platform_machine == \"AMD64\" or platform_machine == \"win32\" or platform_machine == \"WIN32\")"} +typing-extensions = ">=4.6.0" + +[package.extras] +aiomysql = ["aiomysql (>=0.2.0)", "greenlet (!=0.4.17)"] +aioodbc = ["aioodbc", "greenlet (!=0.4.17)"] +aiosqlite = ["aiosqlite", "greenlet (!=0.4.17)", "typing_extensions (!=3.10.0.1)"] +asyncio = ["greenlet (!=0.4.17)"] +asyncmy = ["asyncmy (>=0.2.3,!=0.2.4,!=0.2.6)", "greenlet (!=0.4.17)"] +mariadb-connector = ["mariadb (>=1.0.1,!=1.1.2,!=1.1.5)"] +mssql = ["pyodbc"] +mssql-pymssql = ["pymssql"] +mssql-pyodbc = ["pyodbc"] +mypy = ["mypy (>=0.910)"] +mysql = ["mysqlclient (>=1.4.0)"] +mysql-connector = ["mysql-connector-python"] +oracle = ["cx_oracle (>=8)"] +oracle-oracledb = ["oracledb (>=1.0.1)"] +postgresql = ["psycopg2 (>=2.7)"] +postgresql-asyncpg = ["asyncpg", "greenlet (!=0.4.17)"] +postgresql-pg8000 = ["pg8000 (>=1.29.1)"] +postgresql-psycopg = ["psycopg (>=3.0.7)"] +postgresql-psycopg2binary = ["psycopg2-binary"] +postgresql-psycopg2cffi = ["psycopg2cffi"] +postgresql-psycopgbinary = ["psycopg[binary] (>=3.0.7)"] +pymysql = ["pymysql"] +sqlcipher = ["sqlcipher3_binary"] + +[[package]] +name = "statsd" +version = "4.0.1" +description = "A simple statsd client." +optional = false +python-versions = "*" +files = [ + {file = "statsd-4.0.1-py2.py3-none-any.whl", hash = "sha256:c2676519927f7afade3723aca9ca8ea986ef5b059556a980a867721ca69df093"}, + {file = "statsd-4.0.1.tar.gz", hash = "sha256:99763da81bfea8daf6b3d22d11aaccb01a8d0f52ea521daab37e758a4ca7d128"}, +] + +[[package]] +name = "stevedore" +version = "5.2.0" +description = "Manage dynamic plugins for Python applications" +optional = false +python-versions = ">=3.8" +files = [ + {file = "stevedore-5.2.0-py3-none-any.whl", hash = "sha256:1c15d95766ca0569cad14cb6272d4d31dae66b011a929d7c18219c176ea1b5c9"}, + {file = "stevedore-5.2.0.tar.gz", hash = "sha256:46b93ca40e1114cea93d738a6c1e365396981bb6bb78c27045b7587c9473544d"}, +] + +[package.dependencies] +pbr = ">=2.0.0,<2.1.0 || >2.1.0" + +[[package]] +name = "sushy" +version = "5.1.1" +description = "Sushy is a small Python library to communicate with Redfish based systems" +optional = false +python-versions = ">=3.8" +files = [ + {file = "sushy-5.1.1-py3-none-any.whl", hash = "sha256:44876009e648b0ab43679b50a4a56de71dc574912ad2e378cd03de62249e839e"}, + {file = "sushy-5.1.1.tar.gz", hash = "sha256:2a8335f18b03ce44d2be4af83ddaed770b94884239d5d18abc7cbb3347e27bae"}, +] + +[package.dependencies] +pbr = ">=2.0.0,<2.1.0 || >2.1.0" +python-dateutil = ">=2.7.0" +requests = ">=2.14.2" +stevedore = ">=1.29.0" + +[[package]] +name = "tenacity" +version = "9.0.0" +description = "Retry code until it succeeds" +optional = false +python-versions = ">=3.8" +files = [ + {file = "tenacity-9.0.0-py3-none-any.whl", hash = "sha256:93de0c98785b27fcf659856aa9f54bfbd399e29969b0621bc7f762bd441b4539"}, + {file = "tenacity-9.0.0.tar.gz", hash = "sha256:807f37ca97d62aa361264d497b0e31e92b8027044942bfa756160d908320d73b"}, +] + +[package.extras] +doc = ["reno", "sphinx"] +test = ["pytest", "tornado (>=4.5)", "typeguard"] + +[[package]] +name = "testresources" +version = "2.0.1" +description = "Testresources, a pyunit extension for managing expensive test resources" +optional = false +python-versions = "*" +files = [ + {file = "testresources-2.0.1-py2.py3-none-any.whl", hash = "sha256:67a361c3a2412231963b91ab04192209aa91a1aa052f0ab87245dbea889d1282"}, + {file = "testresources-2.0.1.tar.gz", hash = "sha256:ee9d1982154a1e212d4e4bac6b610800bfb558e4fb853572a827bc14a96e4417"}, +] + +[package.dependencies] +pbr = ">=1.8" + +[package.extras] +test = ["docutils", "fixtures", "testtools"] + +[[package]] +name = "testscenarios" +version = "0.5.0" +description = "Testscenarios, a pyunit extension for dependency injection" +optional = false +python-versions = "*" +files = [ + {file = "testscenarios-0.5.0-py2.py3-none-any.whl", hash = "sha256:480263fa5d6e618125bdf092aab129a3aeed5996b1e668428f12cc56d6d01d28"}, + {file = "testscenarios-0.5.0.tar.gz", hash = "sha256:c257cb6b90ea7e6f8fef3158121d430543412c9a87df30b5dde6ec8b9b57a2b6"}, +] + +[package.dependencies] +pbr = ">=0.11" +testtools = "*" + +[[package]] +name = "testtools" +version = "2.7.2" +description = "Extensions to the Python standard library unit testing framework" +optional = false +python-versions = ">=3.8" +files = [ + {file = "testtools-2.7.2-py3-none-any.whl", hash = "sha256:11712e29cebbe92187c3ad47ace5c32f91e1bb7a9f1ac5e8684c2b01eaa6fd2d"}, + {file = "testtools-2.7.2.tar.gz", hash = "sha256:5be5bbc1f0fa0f8b60aca6ceec07845d41d0c475cf445bfadb4d2c45ec397ea3"}, +] + +[package.dependencies] +setuptools = {version = "*", markers = "python_version >= \"3.12\""} + +[package.extras] +dev = ["ruff (==0.4.8)"] +test = ["testresources", "testscenarios"] +twisted = ["fixtures", "twisted"] + +[[package]] +name = "tooz" +version = "6.2.0" +description = "Coordination library for distributed systems." +optional = false +python-versions = ">=3.8" +files = [ + {file = "tooz-6.2.0-py3-none-any.whl", hash = "sha256:cebdc29a59f0151d20c005b539d723e4ee58215dd00b41a74eaa655edcce1258"}, + {file = "tooz-6.2.0.tar.gz", hash = "sha256:90565627ecb8aa793f9fe6eccc178f57cda751eca03dbb2cb31995e9b1e589b5"}, +] + +[package.dependencies] +fasteners = ">=0.7" +futurist = ">=1.2.0" +msgpack = ">=0.4.0" +"oslo.serialization" = ">=1.10.0" +"oslo.utils" = ">=4.7.0" +stevedore = ">=1.16.0" +tenacity = ">=5.0.0" +voluptuous = ">=0.8.9" + +[package.extras] +consul = ["python-consul2 (>=0.0.16)"] +etcd = ["requests (>=2.10.0)"] +etcd3gw = ["etcd3gw (>=2.3.0)"] +ipc = ["sysv-ipc (>=0.6.8)"] +memcached = ["pymemcache (>=1.2.9)"] +mysql = ["PyMySQL (>=0.6.2)"] +postgresql = ["psycopg2 (>=2.5)"] +redis = ["packaging (>=20.4.0)", "redis (>=4.0.0)"] +test = ["coverage (>=3.6)", "ddt (>=1.2.1)", "fixtures (>=3.0.0)", "pifpaf (>=0.10.0)", "stestr (>=2.0.0)", "testtools (>=1.4.0)"] +zake = ["zake (>=0.1.6)"] +zookeeper = ["kazoo (>=2.6)"] + +[[package]] +name = "typing-extensions" +version = "4.12.2" +description = "Backported and Experimental Type Hints for Python 3.8+" +optional = false +python-versions = ">=3.8" +files = [ + {file = "typing_extensions-4.12.2-py3-none-any.whl", hash = "sha256:04e5ca0351e0f3f85c6853954072df659d0d13fac324d0072316b67d7794700d"}, + {file = "typing_extensions-4.12.2.tar.gz", hash = "sha256:1a7ead55c7e559dd4dee8856e3a88b41225abfe1ce8df57b7c13915fe121ffb8"}, +] + +[[package]] +name = "tzdata" +version = "2024.1" +description = "Provider of IANA time zone data" +optional = false +python-versions = ">=2" +files = [ + {file = "tzdata-2024.1-py2.py3-none-any.whl", hash = "sha256:9068bc196136463f5245e51efda838afa15aaeca9903f49050dfa2679db4d252"}, + {file = "tzdata-2024.1.tar.gz", hash = "sha256:2674120f8d891909751c38abcdfd386ac0a5a1127954fbc332af6b5ceae07efd"}, +] + +[[package]] +name = "urllib3" +version = "2.2.2" +description = "HTTP library with thread-safe connection pooling, file post, and more." +optional = false +python-versions = ">=3.8" +files = [ + {file = "urllib3-2.2.2-py3-none-any.whl", hash = "sha256:a448b2f64d686155468037e1ace9f2d2199776e17f0a46610480d311f73e3472"}, + {file = "urllib3-2.2.2.tar.gz", hash = "sha256:dd505485549a7a552833da5e6063639d0d177c04f23bc3864e41e5dc5f612168"}, +] + +[package.extras] +brotli = ["brotli (>=1.0.9)", "brotlicffi (>=0.8.0)"] +h2 = ["h2 (>=4,<5)"] +socks = ["pysocks (>=1.5.6,!=1.5.7,<2.0)"] +zstd = ["zstandard (>=0.18.0)"] + +[[package]] +name = "vine" +version = "5.1.0" +description = "Python promises." +optional = false +python-versions = ">=3.6" +files = [ + {file = "vine-5.1.0-py3-none-any.whl", hash = "sha256:40fdf3c48b2cfe1c38a49e9ae2da6fda88e4794c810050a728bd7413811fb1dc"}, + {file = "vine-5.1.0.tar.gz", hash = "sha256:8b62e981d35c41049211cf62a0a1242d8c1ee9bd15bb196ce38aefd6799e61e0"}, +] + +[[package]] +name = "voluptuous" +version = "0.15.2" +description = "Python data validation library" +optional = false +python-versions = ">=3.9" +files = [ + {file = "voluptuous-0.15.2-py3-none-any.whl", hash = "sha256:016348bc7788a9af9520b1764ebd4de0df41fe2138ebe9e06fa036bf86a65566"}, + {file = "voluptuous-0.15.2.tar.gz", hash = "sha256:6ffcab32c4d3230b4d2af3a577c87e1908a714a11f6f95570456b1849b0279aa"}, +] + +[[package]] +name = "wcwidth" +version = "0.2.13" +description = "Measures the displayed width of unicode strings in a terminal" +optional = false +python-versions = "*" +files = [ + {file = "wcwidth-0.2.13-py2.py3-none-any.whl", hash = "sha256:3da69048e4540d84af32131829ff948f1e022c1c6bdb8d6102117aac784f6859"}, + {file = "wcwidth-0.2.13.tar.gz", hash = "sha256:72ea0c06399eb286d978fdedb6923a9eb47e1c486ce63e9b4e64fc18303972b5"}, +] + +[[package]] +name = "webob" +version = "1.8.8" +description = "WSGI request and response object" +optional = false +python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,>=2.7" +files = [ + {file = "WebOb-1.8.8-py2.py3-none-any.whl", hash = "sha256:b60ba63f05c0cf61e086a10c3781a41fcfe30027753a8ae6d819c77592ce83ea"}, + {file = "webob-1.8.8.tar.gz", hash = "sha256:2abc1555e118fc251e705fc6dc66c7f5353bb9fbfab6d20e22f1c02b4b71bcee"}, +] + +[package.extras] +docs = ["Sphinx (>=1.7.5)", "pylons-sphinx-themes"] +testing = ["coverage", "pytest (>=3.1.0)", "pytest-cov", "pytest-xdist"] + +[[package]] +name = "wrapt" +version = "1.16.0" +description = "Module for decorators, wrappers and monkey patching." +optional = false +python-versions = ">=3.6" +files = [ + {file = "wrapt-1.16.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:ffa565331890b90056c01db69c0fe634a776f8019c143a5ae265f9c6bc4bd6d4"}, + {file = "wrapt-1.16.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:e4fdb9275308292e880dcbeb12546df7f3e0f96c6b41197e0cf37d2826359020"}, + {file = "wrapt-1.16.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bb2dee3874a500de01c93d5c71415fcaef1d858370d405824783e7a8ef5db440"}, + {file = "wrapt-1.16.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2a88e6010048489cda82b1326889ec075a8c856c2e6a256072b28eaee3ccf487"}, + {file = "wrapt-1.16.0-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ac83a914ebaf589b69f7d0a1277602ff494e21f4c2f743313414378f8f50a4cf"}, + {file = "wrapt-1.16.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:73aa7d98215d39b8455f103de64391cb79dfcad601701a3aa0dddacf74911d72"}, + {file = "wrapt-1.16.0-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:807cc8543a477ab7422f1120a217054f958a66ef7314f76dd9e77d3f02cdccd0"}, + {file = "wrapt-1.16.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:bf5703fdeb350e36885f2875d853ce13172ae281c56e509f4e6eca049bdfb136"}, + {file = "wrapt-1.16.0-cp310-cp310-win32.whl", hash = "sha256:f6b2d0c6703c988d334f297aa5df18c45e97b0af3679bb75059e0e0bd8b1069d"}, + {file = "wrapt-1.16.0-cp310-cp310-win_amd64.whl", hash = "sha256:decbfa2f618fa8ed81c95ee18a387ff973143c656ef800c9f24fb7e9c16054e2"}, + {file = "wrapt-1.16.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:1a5db485fe2de4403f13fafdc231b0dbae5eca4359232d2efc79025527375b09"}, + {file = "wrapt-1.16.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:75ea7d0ee2a15733684badb16de6794894ed9c55aa5e9903260922f0482e687d"}, + {file = "wrapt-1.16.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a452f9ca3e3267cd4d0fcf2edd0d035b1934ac2bd7e0e57ac91ad6b95c0c6389"}, + {file = "wrapt-1.16.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:43aa59eadec7890d9958748db829df269f0368521ba6dc68cc172d5d03ed8060"}, + {file = "wrapt-1.16.0-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:72554a23c78a8e7aa02abbd699d129eead8b147a23c56e08d08dfc29cfdddca1"}, + {file = "wrapt-1.16.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:d2efee35b4b0a347e0d99d28e884dfd82797852d62fcd7ebdeee26f3ceb72cf3"}, + {file = "wrapt-1.16.0-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:6dcfcffe73710be01d90cae08c3e548d90932d37b39ef83969ae135d36ef3956"}, + {file = "wrapt-1.16.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:eb6e651000a19c96f452c85132811d25e9264d836951022d6e81df2fff38337d"}, + {file = "wrapt-1.16.0-cp311-cp311-win32.whl", hash = "sha256:66027d667efe95cc4fa945af59f92c5a02c6f5bb6012bff9e60542c74c75c362"}, + {file = "wrapt-1.16.0-cp311-cp311-win_amd64.whl", hash = "sha256:aefbc4cb0a54f91af643660a0a150ce2c090d3652cf4052a5397fb2de549cd89"}, + {file = "wrapt-1.16.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:5eb404d89131ec9b4f748fa5cfb5346802e5ee8836f57d516576e61f304f3b7b"}, + {file = "wrapt-1.16.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:9090c9e676d5236a6948330e83cb89969f433b1943a558968f659ead07cb3b36"}, + {file = "wrapt-1.16.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:94265b00870aa407bd0cbcfd536f17ecde43b94fb8d228560a1e9d3041462d73"}, + {file = "wrapt-1.16.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f2058f813d4f2b5e3a9eb2eb3faf8f1d99b81c3e51aeda4b168406443e8ba809"}, + {file = "wrapt-1.16.0-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:98b5e1f498a8ca1858a1cdbffb023bfd954da4e3fa2c0cb5853d40014557248b"}, + {file = "wrapt-1.16.0-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:14d7dc606219cdd7405133c713f2c218d4252f2a469003f8c46bb92d5d095d81"}, + {file = "wrapt-1.16.0-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:49aac49dc4782cb04f58986e81ea0b4768e4ff197b57324dcbd7699c5dfb40b9"}, + {file = "wrapt-1.16.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:418abb18146475c310d7a6dc71143d6f7adec5b004ac9ce08dc7a34e2babdc5c"}, + {file = "wrapt-1.16.0-cp312-cp312-win32.whl", hash = "sha256:685f568fa5e627e93f3b52fda002c7ed2fa1800b50ce51f6ed1d572d8ab3e7fc"}, + {file = "wrapt-1.16.0-cp312-cp312-win_amd64.whl", hash = "sha256:dcdba5c86e368442528f7060039eda390cc4091bfd1dca41e8046af7c910dda8"}, + {file = "wrapt-1.16.0-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:d462f28826f4657968ae51d2181a074dfe03c200d6131690b7d65d55b0f360f8"}, + {file = "wrapt-1.16.0-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a33a747400b94b6d6b8a165e4480264a64a78c8a4c734b62136062e9a248dd39"}, + {file = "wrapt-1.16.0-cp36-cp36m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b3646eefa23daeba62643a58aac816945cadc0afaf21800a1421eeba5f6cfb9c"}, + {file = "wrapt-1.16.0-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3ebf019be5c09d400cf7b024aa52b1f3aeebeff51550d007e92c3c1c4afc2a40"}, + {file = "wrapt-1.16.0-cp36-cp36m-musllinux_1_1_aarch64.whl", hash = "sha256:0d2691979e93d06a95a26257adb7bfd0c93818e89b1406f5a28f36e0d8c1e1fc"}, + {file = "wrapt-1.16.0-cp36-cp36m-musllinux_1_1_i686.whl", hash = "sha256:1acd723ee2a8826f3d53910255643e33673e1d11db84ce5880675954183ec47e"}, + {file = "wrapt-1.16.0-cp36-cp36m-musllinux_1_1_x86_64.whl", hash = "sha256:bc57efac2da352a51cc4658878a68d2b1b67dbe9d33c36cb826ca449d80a8465"}, + {file = "wrapt-1.16.0-cp36-cp36m-win32.whl", hash = "sha256:da4813f751142436b075ed7aa012a8778aa43a99f7b36afe9b742d3ed8bdc95e"}, + {file = "wrapt-1.16.0-cp36-cp36m-win_amd64.whl", hash = "sha256:6f6eac2360f2d543cc875a0e5efd413b6cbd483cb3ad7ebf888884a6e0d2e966"}, + {file = "wrapt-1.16.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:a0ea261ce52b5952bf669684a251a66df239ec6d441ccb59ec7afa882265d593"}, + {file = "wrapt-1.16.0-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7bd2d7ff69a2cac767fbf7a2b206add2e9a210e57947dd7ce03e25d03d2de292"}, + {file = "wrapt-1.16.0-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:9159485323798c8dc530a224bd3ffcf76659319ccc7bbd52e01e73bd0241a0c5"}, + {file = "wrapt-1.16.0-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a86373cf37cd7764f2201b76496aba58a52e76dedfaa698ef9e9688bfd9e41cf"}, + {file = "wrapt-1.16.0-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:73870c364c11f03ed072dda68ff7aea6d2a3a5c3fe250d917a429c7432e15228"}, + {file = "wrapt-1.16.0-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:b935ae30c6e7400022b50f8d359c03ed233d45b725cfdd299462f41ee5ffba6f"}, + {file = "wrapt-1.16.0-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:db98ad84a55eb09b3c32a96c576476777e87c520a34e2519d3e59c44710c002c"}, + {file = "wrapt-1.16.0-cp37-cp37m-win32.whl", hash = "sha256:9153ed35fc5e4fa3b2fe97bddaa7cbec0ed22412b85bcdaf54aeba92ea37428c"}, + {file = "wrapt-1.16.0-cp37-cp37m-win_amd64.whl", hash = "sha256:66dfbaa7cfa3eb707bbfcd46dab2bc6207b005cbc9caa2199bcbc81d95071a00"}, + {file = "wrapt-1.16.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:1dd50a2696ff89f57bd8847647a1c363b687d3d796dc30d4dd4a9d1689a706f0"}, + {file = "wrapt-1.16.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:44a2754372e32ab315734c6c73b24351d06e77ffff6ae27d2ecf14cf3d229202"}, + {file = "wrapt-1.16.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8e9723528b9f787dc59168369e42ae1c3b0d3fadb2f1a71de14531d321ee05b0"}, + {file = "wrapt-1.16.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:dbed418ba5c3dce92619656802cc5355cb679e58d0d89b50f116e4a9d5a9603e"}, + {file = "wrapt-1.16.0-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:941988b89b4fd6b41c3f0bfb20e92bd23746579736b7343283297c4c8cbae68f"}, + {file = "wrapt-1.16.0-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:6a42cd0cfa8ffc1915aef79cb4284f6383d8a3e9dcca70c445dcfdd639d51267"}, + {file = "wrapt-1.16.0-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:1ca9b6085e4f866bd584fb135a041bfc32cab916e69f714a7d1d397f8c4891ca"}, + {file = "wrapt-1.16.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:d5e49454f19ef621089e204f862388d29e6e8d8b162efce05208913dde5b9ad6"}, + {file = "wrapt-1.16.0-cp38-cp38-win32.whl", hash = "sha256:c31f72b1b6624c9d863fc095da460802f43a7c6868c5dda140f51da24fd47d7b"}, + {file = "wrapt-1.16.0-cp38-cp38-win_amd64.whl", hash = "sha256:490b0ee15c1a55be9c1bd8609b8cecd60e325f0575fc98f50058eae366e01f41"}, + {file = "wrapt-1.16.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:9b201ae332c3637a42f02d1045e1d0cccfdc41f1f2f801dafbaa7e9b4797bfc2"}, + {file = "wrapt-1.16.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:2076fad65c6736184e77d7d4729b63a6d1ae0b70da4868adeec40989858eb3fb"}, + {file = "wrapt-1.16.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c5cd603b575ebceca7da5a3a251e69561bec509e0b46e4993e1cac402b7247b8"}, + {file = "wrapt-1.16.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b47cfad9e9bbbed2339081f4e346c93ecd7ab504299403320bf85f7f85c7d46c"}, + {file = "wrapt-1.16.0-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f8212564d49c50eb4565e502814f694e240c55551a5f1bc841d4fcaabb0a9b8a"}, + {file = "wrapt-1.16.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:5f15814a33e42b04e3de432e573aa557f9f0f56458745c2074952f564c50e664"}, + {file = "wrapt-1.16.0-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:db2e408d983b0e61e238cf579c09ef7020560441906ca990fe8412153e3b291f"}, + {file = "wrapt-1.16.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:edfad1d29c73f9b863ebe7082ae9321374ccb10879eeabc84ba3b69f2579d537"}, + {file = "wrapt-1.16.0-cp39-cp39-win32.whl", hash = "sha256:ed867c42c268f876097248e05b6117a65bcd1e63b779e916fe2e33cd6fd0d3c3"}, + {file = "wrapt-1.16.0-cp39-cp39-win_amd64.whl", hash = "sha256:eb1b046be06b0fce7249f1d025cd359b4b80fc1c3e24ad9eca33e0dcdb2e4a35"}, + {file = "wrapt-1.16.0-py3-none-any.whl", hash = "sha256:6906c4100a8fcbf2fa735f6059214bb13b97f75b1a61777fcf6432121ef12ef1"}, + {file = "wrapt-1.16.0.tar.gz", hash = "sha256:5f370f952971e7d17c7d1ead40e49f32345a7f7a5373571ef44d800d06b1899d"}, +] + +[[package]] +name = "yappi" +version = "1.6.0" +description = "Yet Another Python Profiler" +optional = false +python-versions = ">=3.6" +files = [ + {file = "yappi-1.6.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:c7c22bb39d3f2f294766f4940848d11b8ad1c43f9cf0a594ed695b07016007fc"}, + {file = "yappi-1.6.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:084688828c0a8c181ebe59bbf15dcd5a5db2f689eada59d5c277b997c4dccf43"}, + {file = "yappi-1.6.0-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:23c668e9ce87d70b126f73970cff997a2ab1964b947859ee50580af23964a096"}, + {file = "yappi-1.6.0-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:d4c7c5de3ae439c53c6c6c98d30d4b063c6fc353428ba3d81b57d91f1c41f654"}, + {file = "yappi-1.6.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:830ffb677b7a9f9886bc7789e9cb75d5b3ad9af5f43d56d48e56431f92f04bcc"}, + {file = "yappi-1.6.0-cp310-cp310-win32.whl", hash = "sha256:b42f7934fe96fd330488f9def51dd8e2fecc5cc9a71dceab8a27a41406b31332"}, + {file = "yappi-1.6.0-cp310-cp310-win_amd64.whl", hash = "sha256:1cd7453e99ebf56491254b0f4c28ae95c5e0ce55043eb17d1ab02c974cbd7416"}, + {file = "yappi-1.6.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:e9bc33b8ec9bce8b2575a4c3878b3cd223d08eb728669924699e5ac937e7b515"}, + {file = "yappi-1.6.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a1cb70d46827a137350fb84b8fddecd7acec0a11834c763209875788b738f873"}, + {file = "yappi-1.6.0-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a2cefe387bc747afcf0b26c9548e242113e17fac3de2674d900e97eb58a328f6"}, + {file = "yappi-1.6.0-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:acfbf4c80b6ee0513ad35a6e4a1f633aa2f93357517f9701aed6ad8cd56544d4"}, + {file = "yappi-1.6.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:e4959c1dcfb6da8441d05915bfbb9c697e9f11655568f65b87c341e543bd65d5"}, + {file = "yappi-1.6.0-cp311-cp311-win32.whl", hash = "sha256:88dee431bba79866692f444110695133181efb2a6969ab63752f4424787f79c8"}, + {file = "yappi-1.6.0-cp311-cp311-win_amd64.whl", hash = "sha256:8ddbe1475964f145b028f8bf120a58903d8f6c7bdd1be0a16c1471ba2d8646ca"}, + {file = "yappi-1.6.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:1ba7d12c18bc0d092463ad126a95a1b2b8c261c47b0e3bd4cb2fd7479469141c"}, + {file = "yappi-1.6.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:fb5bbb4c6b996736554cb8f41e7fb6d5ee6096b7c4f54112cce8cf953a92c0a4"}, + {file = "yappi-1.6.0-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c12da5f310d81779056566259fef644a9c14ac1ec9a2b1b8a3fc62beb4ca6980"}, + {file = "yappi-1.6.0-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:677d992c41b239441eee399ac39ea7601010ddb5acb92bf997de7589f9ee2cc1"}, + {file = "yappi-1.6.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:d58e60aac43041d109f0931917204ef02ac01004b9579fe173f2847fbc69655b"}, + {file = "yappi-1.6.0-cp312-cp312-win32.whl", hash = "sha256:a6797f189b7b89154d6c7c53ac769a22f0adb7bd88ea5b8f6c65106a286afad6"}, + {file = "yappi-1.6.0-cp312-cp312-win_amd64.whl", hash = "sha256:cdaa263ba667aac9bf7bdc0d96fd10e2761a287f01fe87dc136f064ab7696af3"}, + {file = "yappi-1.6.0-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:819c43539f55a9f40118ab8b3ce7cb743d66f3af63c7ce984c114533f750b263"}, + {file = "yappi-1.6.0-cp36-cp36m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d1a8be1f55875e2120d7cddcb7e98c77a79ed87715d6292874c782fcd7da2c50"}, + {file = "yappi-1.6.0-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f0f82e4895d04d6fd7bed2bea0abcc84271bdd990371cb053132753b6f5afb73"}, + {file = "yappi-1.6.0-cp36-cp36m-musllinux_1_1_i686.whl", hash = "sha256:1fd7d2da3e32f3d029220356e9b5b24754a7cd708d6e3830405e3dc04ec74153"}, + {file = "yappi-1.6.0-cp36-cp36m-musllinux_1_1_x86_64.whl", hash = "sha256:2c7c2c9048b2f9fbd5da9cc65bdad73571023a30b5c34f62d97d9a7d47cbe9f5"}, + {file = "yappi-1.6.0-cp36-cp36m-win32.whl", hash = "sha256:d9f6ac7cd8797850bb6fb4cef8364ed34051be6f47d7da74be3a9261eef4bbfb"}, + {file = "yappi-1.6.0-cp36-cp36m-win_amd64.whl", hash = "sha256:6a16dd3fb61cfa7ffeb287312ddfe2a5c61a53693b009d3a7a3f1b8affb9568a"}, + {file = "yappi-1.6.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:638bd2458a6dfaa278e8977a8fdf44c8626003c12d8c94d82338ef8aa6ac245f"}, + {file = "yappi-1.6.0-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:30d294a88baffc3cb13a66fe408ecf8973c927fb3498f327df5af7cc657cdc80"}, + {file = "yappi-1.6.0-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d49f972a8901972b104a2b65953ae8cbe005d5c09e0974422195bb780b2c5001"}, + {file = "yappi-1.6.0-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:e40a872d146ddddae337181f8808aa6c3b37ffa66bd38a18f009b9e2f2c08b99"}, + {file = "yappi-1.6.0-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:31050972159a026876a06b5eec97f2dbaaaa291ebf3cf07a0d5506cce37ef339"}, + {file = "yappi-1.6.0-cp37-cp37m-win32.whl", hash = "sha256:36278de1ecf3a781322fb5f9511abc0b66bff327ca87a9e868dc2e376ad1b11a"}, + {file = "yappi-1.6.0-cp37-cp37m-win_amd64.whl", hash = "sha256:ef61f5fed7c19dddad5b7565df5b7bdfa861d51c15b01a90d283c4d3c97c42e2"}, + {file = "yappi-1.6.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:e33c097402e101a51f9963654108e7625853ddc979b562e8381f761cce99ae13"}, + {file = "yappi-1.6.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a9ea8dada24af41c11059f70741d8fce707aaf6862a9306f2ab63bde35f0ce9e"}, + {file = "yappi-1.6.0-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e37817722a052632de21674ec8acf59645c08df786920362879a76493037c99e"}, + {file = "yappi-1.6.0-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:72aff63e74b87ffbf121211246922df9ac5dffc8deabdc6964f5b7f399799d0a"}, + {file = "yappi-1.6.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:8a3c970f43f6d9bbc7159b535fbef492cb21576c094e77a673362ad827d9e00a"}, + {file = "yappi-1.6.0-cp38-cp38-win32.whl", hash = "sha256:69a4aced8c86bcc91fbecc3924ca9bd0a91ed715531c8a039199ef325ebb7046"}, + {file = "yappi-1.6.0-cp38-cp38-win_amd64.whl", hash = "sha256:93352217bf560bea09b1cb43a17361bd2d41864698fa7ae46ce1066266c1af76"}, + {file = "yappi-1.6.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:6678f046e6bffc68ef2d7781f9fc90b932ca6e90ea966371318ed904c4c38b8d"}, + {file = "yappi-1.6.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b2f8f0877e3b85b6d2074d2fb541085cd519481f3df9c7e7011fc3867c364c7e"}, + {file = "yappi-1.6.0-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4ae77cfe71682beec6f15ddd6dfb5912436c489b38eb2c3355f4481c07b9c4bf"}, + {file = "yappi-1.6.0-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:237b1ac310ef364db6d2a1817de93a346d1ed98abfa3053810dbbdcab9ca9300"}, + {file = "yappi-1.6.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:474e9f3ba9394c19dd2f7dc257123e3918c178638597d507ee2094f19d938a39"}, + {file = "yappi-1.6.0-cp39-cp39-win32.whl", hash = "sha256:a69ce9d7acc71419092f158ab4851d982e90ecbffbe6abf7d95516f3f741b57f"}, + {file = "yappi-1.6.0-cp39-cp39-win_amd64.whl", hash = "sha256:e6ec9eabc974f9df868faa67461a9d167e9612083f59338f755f4aa61a2552b7"}, + {file = "yappi-1.6.0.tar.gz", hash = "sha256:a9aaf72009d8c03067294151ee0470ac7a6dfa7b33baab40b198d6c1ef00430a"}, +] + +[package.extras] +test = ["gevent (>=20.6.2)"] + +[[package]] +name = "zeroconf" +version = "0.132.2" +description = "A pure python implementation of multicast DNS service discovery" +optional = false +python-versions = "<4.0,>=3.8" +files = [ + {file = "zeroconf-0.132.2-cp310-cp310-macosx_11_0_x86_64.whl", hash = "sha256:31c8406f62251aa62f5b67d865007ffd1dd929eae9027166ffa6bccca69253bd"}, + {file = "zeroconf-0.132.2-cp310-cp310-manylinux_2_17_i686.manylinux_2_5_i686.manylinux1_i686.manylinux2014_i686.whl", hash = "sha256:d4bc5e43d02e0848c3174914595dfcebed9b74e65cbdfb1011c5082db7916605"}, + {file = "zeroconf-0.132.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:59953e8445e69e5fee53381c437d3494f7fac8d7b51f0169d59b69eba8f95063"}, + {file = "zeroconf-0.132.2-cp310-cp310-manylinux_2_31_x86_64.whl", hash = "sha256:ddae9592604fe04ec065cc53a321844c3592c812988346136d8ee548127f3d12"}, + {file = "zeroconf-0.132.2-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:b20036ab22df2fb663f797b110fa82d4798084fcc56c8a264af50989581062be"}, + {file = "zeroconf-0.132.2-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:82678a77e471dd3b0ad5ed47a4a42474af3150819718eff7e36dca32ae591949"}, + {file = "zeroconf-0.132.2-cp310-cp310-win32.whl", hash = "sha256:390feb3e7fccdffbf66c9bcd895b1db92e501aa2789d6a8b44e6e027ab80ec14"}, + {file = "zeroconf-0.132.2-cp310-cp310-win_amd64.whl", hash = "sha256:779d81aac693e57090343ce5b18f477fec993f969aa87660a33e7ce81880ccdf"}, + {file = "zeroconf-0.132.2-cp311-cp311-macosx_11_0_x86_64.whl", hash = "sha256:76d12185c335c14b04b8706b4dd0badc16f4185caeb635419c84e575cef7c980"}, + {file = "zeroconf-0.132.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:700bae69eb7c45037deef4a729586f32205d391de38802e2ab89151a7a87d1fc"}, + {file = "zeroconf-0.132.2-cp311-cp311-manylinux_2_17_i686.manylinux_2_5_i686.manylinux1_i686.manylinux2014_i686.whl", hash = "sha256:9d364a929121df5b96af53ac62abdd61fa3a931e74c7a4c80204c961c01a8667"}, + {file = "zeroconf-0.132.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e7e2c398679c863e810a9af2c5d14542a32d438e3bf5ba0b9d8e119326c33303"}, + {file = "zeroconf-0.132.2-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:28b1721617ddc9bf3d2ba3e2b96234f7539e1dbdcacaf6e94ec31ff7b5ebe620"}, + {file = "zeroconf-0.132.2-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:f2b26c23efeded0e7fcfd0fb4d638ec4a83d120e1d455267d353090e36479528"}, + {file = "zeroconf-0.132.2-cp311-cp311-win32.whl", hash = "sha256:4754dfba1af63545dfd0ab26c834c907e1dd3f94c8ee190c3041a6444313aaed"}, + {file = "zeroconf-0.132.2-cp311-cp311-win_amd64.whl", hash = "sha256:db8607a32347da1fd4519cfea441d8b36b44df0c53198ae0471c76fc932a86e0"}, + {file = "zeroconf-0.132.2-cp312-cp312-macosx_11_0_x86_64.whl", hash = "sha256:5354c1cf83d36b2d03ee5774923d30fe838f9371963b42ca46ecba45d3507ff4"}, + {file = "zeroconf-0.132.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:48275e3db89a8d90ff983c3f7b0c6eee2ede3c4e5e75eaf2aa571ea8cb956d95"}, + {file = "zeroconf-0.132.2-cp312-cp312-manylinux_2_17_i686.manylinux_2_5_i686.manylinux1_i686.manylinux2014_i686.whl", hash = "sha256:3eb0e57654e139c3ef5b6421053236be4a0add9f0301b01545b11a0552c7c123"}, + {file = "zeroconf-0.132.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b3dd7143dfc37a20f7d1ccf32f916ac78c11d3c8bae61438ee06376b1bc535fc"}, + {file = "zeroconf-0.132.2-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:f9a28b0416a36ec32273ee1ac80cc72ff9b06d1cb15a9481dcd5c92bd2bc8f03"}, + {file = "zeroconf-0.132.2-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:06203c23a82b69aca9e961da675600dff19026bb22b5d042f18f9e0ff1139ed3"}, + {file = "zeroconf-0.132.2-cp312-cp312-win32.whl", hash = "sha256:5c8c2eeb838538fffaa421f9b3f9c671778886595b5aa0d4ef4d000531e721d2"}, + {file = "zeroconf-0.132.2-cp312-cp312-win_amd64.whl", hash = "sha256:a37fe4f302edb8d931a4c386d0944f996e3f54717495636113880c4492ab479f"}, + {file = "zeroconf-0.132.2-cp38-cp38-macosx_11_0_x86_64.whl", hash = "sha256:6732b224be7e69f7c77798e50205f8e92646ab59724151d66d8dc97f92e99a77"}, + {file = "zeroconf-0.132.2-cp38-cp38-manylinux_2_17_i686.manylinux_2_5_i686.manylinux1_i686.manylinux2014_i686.whl", hash = "sha256:3ad2fe0cbfebe20612c9a5390075a2b3a258a78928f5b7b5163be1699cc528f0"}, + {file = "zeroconf-0.132.2-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:56146e66774c30e238088f67be47740ffd4f669c08e76f2e470bd611d7bdae46"}, + {file = "zeroconf-0.132.2-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:4dd7d8fdee36cc6bde0bcb08b79375009de7a76d935d1401b6ae4b62505b9ee0"}, + {file = "zeroconf-0.132.2-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:a49b13ec79edff347b1e7af65f5843719ca151ef071ac6b2ff564bb69d164331"}, + {file = "zeroconf-0.132.2-cp38-cp38-win32.whl", hash = "sha256:ca46637fcc0386fdbe6bde447184ed981499c8c1b5b5fcaa0f35c3b15528162a"}, + {file = "zeroconf-0.132.2-cp38-cp38-win_amd64.whl", hash = "sha256:f56ec955f43f944985f857c9d23030362df52e14a7c53c64bf8b29cfadebd601"}, + {file = "zeroconf-0.132.2-cp39-cp39-macosx_11_0_x86_64.whl", hash = "sha256:5586bc773d6cee4f9a14692f5e6bc6387ddb54b2bfae0db01c0695aac20c420a"}, + {file = "zeroconf-0.132.2-cp39-cp39-manylinux_2_17_i686.manylinux_2_5_i686.manylinux1_i686.manylinux2014_i686.whl", hash = "sha256:1f09b692219abf9b1ca28364d6f4eb283a4c676e30c905933d1694cbd321bc4b"}, + {file = "zeroconf-0.132.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e1031c7c5f8516108e7c24190179e6a522183de218a954681a341ee818f8079a"}, + {file = "zeroconf-0.132.2-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:87b6e92a869932f4aac3076816a1b987c581b01e49a08e495bef7165be049dfd"}, + {file = "zeroconf-0.132.2-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:13beed15eed7e569fd56dbe16c7cb758f81c661d53ec253fbf9cfe7a20e28b7c"}, + {file = "zeroconf-0.132.2-cp39-cp39-win32.whl", hash = "sha256:4e83e18722d0bdc2e603f7ca104adf276d5728a664b9e94c99e2d8c02001429c"}, + {file = "zeroconf-0.132.2-cp39-cp39-win_amd64.whl", hash = "sha256:a2fa3a89f6a0cf03a56141dad158634a009a22fbe645c7c01e85edc12a0a239f"}, + {file = "zeroconf-0.132.2-pp310-pypy310_pp73-macosx_11_0_x86_64.whl", hash = "sha256:1a95025f0949ed0e873e141d482fbbefa223ef90646443e4a1d6d47f50eb89d7"}, + {file = "zeroconf-0.132.2-pp310-pypy310_pp73-manylinux_2_17_i686.manylinux_2_5_i686.manylinux1_i686.manylinux2014_i686.whl", hash = "sha256:1c932b15848ae6b8e4b2b50c65368e396d000fea95acd473611693dbe5a00096"}, + {file = "zeroconf-0.132.2-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9c295b424a271ce5022da83a1274b4cd0f696c5b8e0c190e6a28efde8b36e82d"}, + {file = "zeroconf-0.132.2-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:c50ee0df6b0b06f1dad6261670b5be53c909b9a2b1985bcf65ea5b0d766fd10e"}, + {file = "zeroconf-0.132.2-pp38-pypy38_pp73-macosx_11_0_x86_64.whl", hash = "sha256:5b6cfc2b62e6282eabbcb6c7223b0a8c05ed3a326e7b467d06b85a3eeda1bfc8"}, + {file = "zeroconf-0.132.2-pp38-pypy38_pp73-manylinux_2_17_i686.manylinux_2_5_i686.manylinux1_i686.manylinux2014_i686.whl", hash = "sha256:d6c05af8b49c442422ce49565ab41a094b23e0f5692abe1533428cbe35a78f8e"}, + {file = "zeroconf-0.132.2-pp38-pypy38_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0b0d2ffc4bafbcc4152067bfbc1a67074d23e6100e356424bd985ca8067a2bfd"}, + {file = "zeroconf-0.132.2-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:b60b260c70bb77d7f3b666bdd2a2a74cead5e36814f8b4295778bcdd08f65c7e"}, + {file = "zeroconf-0.132.2-pp39-pypy39_pp73-macosx_11_0_x86_64.whl", hash = "sha256:9228c512334905338f65825102e47778e5ce034bb4249c3deb22991826ed061f"}, + {file = "zeroconf-0.132.2-pp39-pypy39_pp73-manylinux_2_17_i686.manylinux_2_5_i686.manylinux1_i686.manylinux2014_i686.whl", hash = "sha256:e36f50a963d149bb7152543db9bdbd73f7997e66b57b7956fc17751f55e59625"}, + {file = "zeroconf-0.132.2-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3bd0cd9435dced8c31491b3ed7c15707acedd11f00451f7fbb57ba3868dd5724"}, + {file = "zeroconf-0.132.2-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:d80bde641349198c8c17684692a8cc40a36a93c0cebd8f1d7c42db7ceeaa17be"}, + {file = "zeroconf-0.132.2.tar.gz", hash = "sha256:9ad8bc6e3f168fe8c164634c762d3265c775643defff10e26273623a12d73ae1"}, +] + +[package.dependencies] +ifaddr = ">=0.1.7" + +[metadata] +lock-version = "2.0" +python-versions = "^3.11" +content-hash = "5abb2d92bb5c73d1b4ff413213884650d95d1af3713a20eeb8b57dce0e0193bb" diff --git a/python/ironic-understack/pyproject.toml b/python/ironic-understack/pyproject.toml new file mode 100644 index 00000000..0eb69a47 --- /dev/null +++ b/python/ironic-understack/pyproject.toml @@ -0,0 +1,19 @@ +[tool.poetry] +name = "ironic-understack" +version = "0.0.0" +description = "Ironic hooks for Understack" +authors = ["Marek Skrobacki "] +license = "MIT" +readme = "README.md" + +[tool.poetry.dependencies] +python = "^3.11" +pyyaml = "^6.0.2" +pytest = "^8.3.2" + +[tool.poetry.group.dev.dependencies] +ironic = "^26.0.0" + +[build-system] +requires = ["poetry-core"] +build-backend = "poetry.core.masonry.api" From 2ba93951ea7ed876338da288ddf2b9d349427bcc Mon Sep 17 00:00:00 2001 From: Marek Skrobacki Date: Wed, 21 Aug 2024 14:57:15 +0100 Subject: [PATCH 02/14] add FlavorSpec --- python/ironic-understack/__init__.py | 0 python/ironic-understack/flavor_spec.py | 43 +++++++++ python/ironic-understack/tests/__init__.py | 0 .../tests/test_flavor_spec.py | 91 +++++++++++++++++++ 4 files changed, 134 insertions(+) create mode 100644 python/ironic-understack/__init__.py create mode 100644 python/ironic-understack/flavor_spec.py create mode 100644 python/ironic-understack/tests/__init__.py create mode 100644 python/ironic-understack/tests/test_flavor_spec.py diff --git a/python/ironic-understack/__init__.py b/python/ironic-understack/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/python/ironic-understack/flavor_spec.py b/python/ironic-understack/flavor_spec.py new file mode 100644 index 00000000..1bba9540 --- /dev/null +++ b/python/ironic-understack/flavor_spec.py @@ -0,0 +1,43 @@ +import os +from dataclasses import dataclass + +import yaml + + +@dataclass +class FlavorSpec: + name: str + memory_gb: int + cpu_cores: int + cpu_models: list[str] + drives: list[int] + devices: list[str] + + @staticmethod + def from_yaml(yaml_str: str) -> "FlavorSpec": + data = yaml.safe_load(yaml_str) + return FlavorSpec( + name=data["name"], + memory_gb=data["memory_gb"], + cpu_cores=data["cpu_cores"], + cpu_models=data["cpu_models"], + drives=data["drives"], + devices=data["devices"], + ) + + @staticmethod + def from_directory(directory: str = "/etc/flavors/") -> list["FlavorSpec"]: + flavor_specs = [] + for filename in os.listdir(directory): + if filename.endswith(".yaml") or filename.endswith(".yml"): + filepath = os.path.join(directory, filename) + try: + with open(filepath, "r") as file: + yaml_content = file.read() + flavor_spec = FlavorSpec.from_yaml(yaml_content) + flavor_specs.append(flavor_spec) + except yaml.YAMLError as e: + print(f"Error parsing YAML file {filename}: {e}") + except Exception as e: + print(f"Error processing file {filename}: {e}") + return flavor_specs diff --git a/python/ironic-understack/tests/__init__.py b/python/ironic-understack/tests/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/python/ironic-understack/tests/test_flavor_spec.py b/python/ironic-understack/tests/test_flavor_spec.py new file mode 100644 index 00000000..c99a1378 --- /dev/null +++ b/python/ironic-understack/tests/test_flavor_spec.py @@ -0,0 +1,91 @@ +from unittest.mock import mock_open, patch + +import pytest +from ironic_understack.flavor_spec import FlavorSpec + + +@pytest.fixture +def valid_yaml(): + return """ +--- +name: gp2.ultramedium +memory_gb: 7777 +cpu_cores: 245 +cpu_models: + - AMD EPYC 9254 245-Core Processor +drives: + - 960 + - 960 +devices: + - PowerEdge R7515 + - PowerEdge R7615 +""" + + +@pytest.fixture +def invalid_yaml(): + return """ +--- +name: gp2.ultramedium +x: abcd +malformed_field: 123: invalid +""" + + +@pytest.fixture +def yaml_directory(tmp_path, valid_yaml, invalid_yaml): + valid_file = tmp_path / "valid.yaml" + invalid_file = tmp_path / "invalid.yaml" + + valid_file.write_text(valid_yaml) + invalid_file.write_text(invalid_yaml) + + return tmp_path + + +def test_from_yaml(valid_yaml): + spec = FlavorSpec.from_yaml(valid_yaml) + assert spec.name == "gp2.ultramedium" + assert spec.memory_gb == 7777 + assert spec.cpu_cores == 245 + assert spec.cpu_models == ["AMD EPYC 9254 245-Core Processor"] + assert spec.drives == [960, 960] + assert spec.devices == ["PowerEdge R7515", "PowerEdge R7615"] + + +def test_from_yaml_invalid(invalid_yaml): + with pytest.raises(Exception): + FlavorSpec.from_yaml(invalid_yaml) + + +@patch("os.listdir") +@patch("builtins.open", new_callable=mock_open) +def test_from_directory(mocked_open, mock_listdir, valid_yaml, invalid_yaml): + mock_listdir.return_value = ["valid.yaml", "invalid.yaml"] + mock_file_handles = [ + mock_open(read_data=valid_yaml).return_value, + mock_open(read_data=invalid_yaml).return_value, + ] + + mocked_open.side_effect = mock_file_handles + + specs = FlavorSpec.from_directory("/etc/flavors/") + + assert len(specs) == 1 + assert specs[0].name == "gp2.ultramedium" + assert specs[0].memory_gb == 7777 + assert specs[0].cpu_cores == 245 + + +def test_from_directory_with_real_files(yaml_directory): + specs = FlavorSpec.from_directory(str(yaml_directory)) + + assert len(specs) == 1 + assert specs[0].name == "gp2.ultramedium" + assert specs[0].memory_gb == 7777 + assert specs[0].cpu_cores == 245 + + +def test_empty_directory(tmp_path): + specs = FlavorSpec.from_directory(str(tmp_path)) + assert len(specs) == 0 From 214192d3b8073e90127e086093bb768bdea6c307 Mon Sep 17 00:00:00 2001 From: Marek Skrobacki Date: Wed, 21 Aug 2024 14:57:41 +0100 Subject: [PATCH 03/14] add Matcher --- python/ironic-understack/README.md | 1 + .../{ => ironic_understack}/__init__.py | 0 .../{ => ironic_understack}/flavor_spec.py | 0 .../ironic_understack/machine.py | 13 ++ .../ironic_understack/matcher.py | 84 ++++++++++ .../ironic_understack/resource_class.py | 104 ++++++++++++ .../{ => ironic_understack}/tests/__init__.py | 0 .../tests/test_flavor_spec.py | 0 .../ironic_understack/tests/test_matcher.py | 149 ++++++++++++++++++ python/ironic-understack/pyproject.toml | 6 + 10 files changed, 357 insertions(+) create mode 100644 python/ironic-understack/README.md rename python/ironic-understack/{ => ironic_understack}/__init__.py (100%) rename python/ironic-understack/{ => ironic_understack}/flavor_spec.py (100%) create mode 100644 python/ironic-understack/ironic_understack/machine.py create mode 100644 python/ironic-understack/ironic_understack/matcher.py create mode 100644 python/ironic-understack/ironic_understack/resource_class.py rename python/ironic-understack/{ => ironic_understack}/tests/__init__.py (100%) rename python/ironic-understack/{ => ironic_understack}/tests/test_flavor_spec.py (100%) create mode 100644 python/ironic-understack/ironic_understack/tests/test_matcher.py diff --git a/python/ironic-understack/README.md b/python/ironic-understack/README.md new file mode 100644 index 00000000..8fe3904e --- /dev/null +++ b/python/ironic-understack/README.md @@ -0,0 +1 @@ +Understack Ironic plugin diff --git a/python/ironic-understack/__init__.py b/python/ironic-understack/ironic_understack/__init__.py similarity index 100% rename from python/ironic-understack/__init__.py rename to python/ironic-understack/ironic_understack/__init__.py diff --git a/python/ironic-understack/flavor_spec.py b/python/ironic-understack/ironic_understack/flavor_spec.py similarity index 100% rename from python/ironic-understack/flavor_spec.py rename to python/ironic-understack/ironic_understack/flavor_spec.py diff --git a/python/ironic-understack/ironic_understack/machine.py b/python/ironic-understack/ironic_understack/machine.py new file mode 100644 index 00000000..019ff976 --- /dev/null +++ b/python/ironic-understack/ironic_understack/machine.py @@ -0,0 +1,13 @@ +from dataclasses import dataclass + + +@dataclass +class Machine: + memory_mb: int + cpu: str + disk_gb: int + + @property + def memory_gb(self) -> int: + return self.memory_mb // 1024 + diff --git a/python/ironic-understack/ironic_understack/matcher.py b/python/ironic-understack/ironic_understack/matcher.py new file mode 100644 index 00000000..65a61f69 --- /dev/null +++ b/python/ironic-understack/ironic_understack/matcher.py @@ -0,0 +1,84 @@ +from ironic_understack.machine import Machine +from ironic_understack.flavor_spec import FlavorSpec + + +class Matcher: + def __init__(self, machines: list[Machine], flavors: list[FlavorSpec]): + self.machines = machines + self.flavors = flavors + + def score_machine_to_flavor(self, machine: Machine, flavor: FlavorSpec) -> int: + # Scoring Rules: + # + # 1. 100% match gets highest priority, no further evaluation needed + # 2. If the machine has less memory size than specified in the flavor, + # it cannot be used - the score should be 0. + # 3. If the machine has smaller disk size than specified in the flavor, + # it cannot be used - the score should be 0. + # 4. Machine must match the flavor on one of the CPU models exactly. + # 5. If the machine has exact amount memory as specified in flavor, but + # more disk space it is less desirable than the machine that matches + # exactly on both disk and memory. + # 6. If the machine has exact amount of disk as specified in flavor, + # but more memory space it is less desirable than the machine that + # matches exactly on both disk and memory. + + + # Rule 1: 100% match gets the highest priority + if ( + machine.memory_gb == flavor.memory_gb and + machine.disk_gb in flavor.drives and + machine.cpu in flavor.cpu_models + ): + return 100 + + # Rule 2: If machine has less memory than specified in the flavor, it cannot be used + if machine.memory_gb < flavor.memory_gb: + return 0 + + # Rule 3: If machine has smaller disk than specified in the flavor, it cannot be used + if any(machine.disk_gb < drive for drive in flavor.drives): + return 0 + + # Rule 4: Machine must match the flavor on one of the CPU models exactly + if machine.cpu not in flavor.cpu_models: + return 0 + + # Rule 5 and 6: Rank based on exact matches or excess capacity + score = 0 + + # Exact memory match gives preference + if machine.memory_gb == flavor.memory_gb: + score += 10 + elif machine.memory_gb > flavor.memory_gb: + score += 5 # Less desirable but still usable + + # Exact disk match gives preference + if machine.disk_gb in flavor.drives: + score += 10 + elif all(machine.disk_gb > drive for drive in flavor.drives): + score += 5 # Less desirable but still usable + + return score + + def get_eligible_machines_for_flavor(self, flavor: FlavorSpec) -> list[Machine]: + scored_machines = [] + + for machine in self.machines: + score = self.score_machine_to_flavor(machine, flavor) + if score > 0: + scored_machines.append((machine, score)) + + # Sort machines by score, highest first + scored_machines.sort(key=lambda x: x[1], reverse=True) + + # Return the machine objects, sorted by desirability + return [machine for machine, _ in scored_machines] + + def match(self) -> dict[str, list[Machine]]: + results = {} + for flavor in self.flavors: + eligible_machines = self.get_eligible_machines_for_flavor(flavor) + results[flavor.name] = eligible_machines + return results + diff --git a/python/ironic-understack/ironic_understack/resource_class.py b/python/ironic-understack/ironic_understack/resource_class.py new file mode 100644 index 00000000..24654aaa --- /dev/null +++ b/python/ironic-understack/ironic_understack/resource_class.py @@ -0,0 +1,104 @@ +# from ironic.drivers.modules.inspector.hooks import base +from ironic_understack.flavor_spec import FlavorSpec +from ironic.common import exception +from ironic.drivers.modules.inspector.hooks import base +from ironic_understack.machine import Machine +from ironic_understack.matcher import Matcher +from oslo_log import log as logging + +LOG = logging.getLogger(__name__) + +# temporary until we have a code automatically loading these files +FLAVORS = [ + FlavorSpec( + name="gp2.tiny", + memory_gb=32, + cpu_cores=8, + cpu_models=["AMD EPYC 9124 16-Core Processor"], + drives=[200, 200], + devices=["PowerEdge R7515", "PowerEdge R7615", "PowerEdge R740xd"], + ), + FlavorSpec( + name="gp2.small", + memory_gb=192, + cpu_cores=16, + cpu_models=["AMD EPYC 9124 16-Core Processor"], + drives=[960, 960], + devices=["PowerEdge R7515", "PowerEdge R7615", "PowerEdge R740xd"], + ), + FlavorSpec( + name="gp2.medium", + memory_gb=384, + cpu_cores=24, + cpu_models=["AMD EPYC 9254 24-Core Processor"], + drives=[960, 960], + devices=["PowerEdge R7515", "PowerEdge R7615"], + ), + FlavorSpec( + name="gp2.large", + memory_gb=768, + cpu_cores=48, + cpu_models=["AMD EPYC 9454 48-Core Processor"], + drives=[960, 960], + devices=["PowerEdge R7615"], + ), +] + +class NoMatchError(Exception): + pass + +class UndercloudResourceClassHook(base.InspectionHook): + """Hook to set the node's resource_class based on the inventory.""" + + def __call__(self, task, inventory, plugin_data): + """Update node resource_class with deducted flavor.""" + + try: + memory_mb = inventory["memory"]["physical_mb"] + disk_size_gb = int(int(inventory["disks"][0]["size"]) / 10**9) + cpu_model_name = inventory["cpu"]["model_name"] + + machine = Machine( + memory_mb=memory_mb, cpu=cpu_model_name, disk_gb=disk_size_gb + ) + + resource_class_name = self.classify(machine) + + LOG.info( + "Discovered resources_class: %s for node %s", + resource_class_name, + task.node.uuid, + ) + task.node.resource_class = resource_class_name + task.node.save() + except (KeyError, ValueError, TypeError): + msg = ( + f"Inventory has missing hardware information for node {task.node.uuid}." + ) + LOG.error(msg) + raise exception.InvalidNodeInventory(node=task.node.uuid, reason=msg) + except NoMatchError: + msg = ( + f"No matching flavor found for {task.node.uuid}" + ) + + def classify(self, machine): + # TODO: read the device types repo later + matcher = Matcher([machine], FLAVORS) + possible_flavors_for_machine = { + k: v for (k, v) in matcher.match().items() if len(v) > 0 + } + try: + return self._pick_best_flavor(FLAVORS, possible_flavors_for_machine) + except IndexError as e: + raise NoMatchError(e) + + def _pick_best_flavor(self, all_flavors, matched_flavors): + all_specs = {f.name: f for f in all_flavors} + + # For now choose "best" by memory, but this likely needs to be revisisted. + sorted_flavors = sorted( + matched_flavors.keys(), key=lambda mf: all_specs[mf].memory_gb, reverse=True + ) + best_flavor = sorted_flavors[0] + return best_flavor diff --git a/python/ironic-understack/tests/__init__.py b/python/ironic-understack/ironic_understack/tests/__init__.py similarity index 100% rename from python/ironic-understack/tests/__init__.py rename to python/ironic-understack/ironic_understack/tests/__init__.py diff --git a/python/ironic-understack/tests/test_flavor_spec.py b/python/ironic-understack/ironic_understack/tests/test_flavor_spec.py similarity index 100% rename from python/ironic-understack/tests/test_flavor_spec.py rename to python/ironic-understack/ironic_understack/tests/test_flavor_spec.py diff --git a/python/ironic-understack/ironic_understack/tests/test_matcher.py b/python/ironic-understack/ironic_understack/tests/test_matcher.py new file mode 100644 index 00000000..b55e2ee5 --- /dev/null +++ b/python/ironic-understack/ironic_understack/tests/test_matcher.py @@ -0,0 +1,149 @@ +import pytest +from ironic_understack.flavor_spec import FlavorSpec +from ironic_understack.machine import Machine +from ironic_understack.matcher import Matcher + + +@pytest.fixture +def machines(): + return [ + # 1024 GB, exact CPU, medium + Machine( + memory_mb=1024000, cpu="AMD EPYC 9254 245-Core Processor", disk_gb=1000 + ), + # 800 GB, non-matching CPU + Machine(memory_mb=800000, cpu="Intel Xeon E5-2676 v3", disk_gb=500), + # 200 GB, exact CPU, medium + Machine(memory_mb=200000, cpu="AMD EPYC 9254 245-Core Processor", disk_gb=1500), + # 300 GB, non-matching CPU + Machine(memory_mb=300000, cpu="Intel Xeon E5-2676 v3", disk_gb=500), + # 409 GB, exact CPU, large + Machine(memory_mb=409600, cpu="AMD EPYC 9254 245-Core Processor", disk_gb=2000), + ] + + +@pytest.fixture +def flavors(): + return [ + FlavorSpec( + name="small", + memory_gb=100, + cpu_cores=13, + cpu_models=["AMD EPYC 9254 245-Core Processor", "Pentium 60"], + drives=[500, 500], + devices=[], + ), + FlavorSpec( + name="medium", + memory_gb=200, + cpu_cores=15, + cpu_models=["AMD EPYC 9254 245-Core Processor", "Intel 80386DX"], + drives=[1500, 1500], + devices=[], + ), + FlavorSpec( + name="large", + memory_gb=400, + cpu_cores=27, + cpu_models=["AMD EPYC 9254 245-Core Processor"], + drives=[1800, 1800], + devices=[], + ), + ] + + +def test_exact_match(machines, flavors): + matcher = Matcher(machines, flavors) + results = matcher.match() + + # Check for the 'small' flavor + small_eligible_machines = results["small"] + assert ( + len(small_eligible_machines) == 3 + ) # All machines meet the small flavor specs exactly + # But exact match should be listed first. + assert small_eligible_machines[0].memory_gb == 1024 + assert small_eligible_machines[0].disk_gb == 1000 + assert small_eligible_machines[0].cpu == "AMD EPYC 9254 245-Core Processor" + + +def test_no_match_due_to_memory(machines): + high_memory_flavor = FlavorSpec( + name="high_memory", + memory_gb=1500, + cpu_cores=32, + cpu_models=["AMD EPYC 9254 245-Core Processor"], + drives=[1000], + devices=[], + ) + + matcher = Matcher(machines, [high_memory_flavor]) + results = matcher.match() + + assert len(results["high_memory"]) == 0 # No machine has >= 1500 GB of memory + + +def test_no_match_due_to_disk(machines): + high_disk_flavor = FlavorSpec( + name="high_disk", + memory_gb=400, + cpu_cores=27, + cpu_models=["AMD EPYC 9254 245-Core Processor"], + drives=[3000], + devices=[], + ) + + matcher = Matcher(machines, [high_disk_flavor]) + results = matcher.match() + + assert len(results["high_disk"]) == 0 # No machine has >= 3000 GB of disk + + +def test_partial_match(machines, flavors): + matcher = Matcher(machines, flavors) + results = matcher.match() + + medium_eligible_machines = results["medium"] + # Two machines are good enough to be medium + assert len(medium_eligible_machines) == 2 + # But we should select one with smaller memory + best_machine = medium_eligible_machines[0] + assert all( + best_machine.memory_gb <= machine.memory_gb + for machine in medium_eligible_machines + ) + assert all( + best_machine.disk_gb <= machine.disk_gb + for machine in medium_eligible_machines + ) + # ...so that machine: + assert best_machine == machines[2] + + +def test_higher_memory_and_disk(machines, flavors): + matcher = Matcher(machines, flavors) + results = matcher.match() + + large_eligible_machines = results["large"] + # Only one machine meets large flavor specs exactly + assert len(large_eligible_machines) == 1 + best_machine = large_eligible_machines[0] + assert best_machine.memory_gb == 409 # Memory matches exactly + assert best_machine.disk_gb == 2000 # Disk matches exactly + assert best_machine.cpu == "AMD EPYC 9254 245-Core Processor" + + +def test_cpu_mismatch(machines): + different_cpu_flavor = FlavorSpec( + name="different_cpu", + memory_gb=100, + cpu_cores=13, + cpu_models=["Intel Xeon Gold 6258R"], + drives=[500, 500], + devices=[], + ) + + matcher = Matcher(machines, [different_cpu_flavor]) + results = matcher.match() + + assert len(results["different_cpu"]) == 0 diff --git a/python/ironic-understack/pyproject.toml b/python/ironic-understack/pyproject.toml index 0eb69a47..74200152 100644 --- a/python/ironic-understack/pyproject.toml +++ b/python/ironic-understack/pyproject.toml @@ -5,6 +5,9 @@ description = "Ironic hooks for Understack" authors = ["Marek Skrobacki "] license = "MIT" readme = "README.md" +packages = [ + { include = "ironic_understack" } +] [tool.poetry.dependencies] python = "^3.11" @@ -17,3 +20,6 @@ ironic = "^26.0.0" [build-system] requires = ["poetry-core"] build-backend = "poetry.core.masonry.api" + +[tool.poetry.plugins."ironic.inspection.hooks"] +"resource-class" = "ironic_understack.resource_class:UndercloudResourceClassHook" From f06219e9b8cceb9929399f29ad50b470552e7327 Mon Sep 17 00:00:00 2001 From: Marek Skrobacki Date: Thu, 22 Aug 2024 16:54:29 +0100 Subject: [PATCH 04/14] ironic_understack: lower the requirements so that it can be installed along with sushy-oem package --- python/ironic-understack/pyproject.toml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/python/ironic-understack/pyproject.toml b/python/ironic-understack/pyproject.toml index 74200152..b5003c00 100644 --- a/python/ironic-understack/pyproject.toml +++ b/python/ironic-understack/pyproject.toml @@ -10,12 +10,12 @@ packages = [ ] [tool.poetry.dependencies] -python = "^3.11" -pyyaml = "^6.0.2" -pytest = "^8.3.2" +ironic = "^24.1" +python = "^3.8" +pyyaml = "^6.0" [tool.poetry.group.dev.dependencies] -ironic = "^26.0.0" +pytest = "^8.3.2" [build-system] requires = ["poetry-core"] From 86302308e45dd88957c7814984c0ac04f4fbd972 Mon Sep 17 00:00:00 2001 From: Marek Skrobacki Date: Thu, 29 Aug 2024 14:13:17 +0100 Subject: [PATCH 05/14] ironic: include our package when building container --- containers/Dockerfile.ironic | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/containers/Dockerfile.ironic b/containers/Dockerfile.ironic index 16197e29..f4636368 100644 --- a/containers/Dockerfile.ironic +++ b/containers/Dockerfile.ironic @@ -8,4 +8,6 @@ RUN apt-get update && \ genisoimage \ isolinux \ && apt-get clean && rm -rf /var/lib/apt/lists/* -RUN /var/lib/openstack/bin/python -m pip install --no-cache sushy-oem-idrac==5.0.0 + +COPY python/ironic-understack /tmp/ironic-understack +RUN /var/lib/openstack/bin/python -m pip install --no-cache --no-cache-dir /tmp/ironic-understack sushy-oem-idrac==5.0.0 From 14923641937ec2dbe818b9c41890fa14e6348b1b Mon Sep 17 00:00:00 2001 From: Marek Skrobacki Date: Wed, 28 Aug 2024 11:29:37 +0100 Subject: [PATCH 06/14] refactor Matcher to match only a single machine After giving this some thought, matching multiple machines in one go is YAGNI. --- .../ironic_understack/matcher.py | 36 +-- .../ironic_understack/resource_class.py | 24 +- .../ironic_understack/tests/test_matcher.py | 214 ++++++++++-------- 3 files changed, 142 insertions(+), 132 deletions(-) diff --git a/python/ironic-understack/ironic_understack/matcher.py b/python/ironic-understack/ironic_understack/matcher.py index 65a61f69..025458a3 100644 --- a/python/ironic-understack/ironic_understack/matcher.py +++ b/python/ironic-understack/ironic_understack/matcher.py @@ -3,8 +3,7 @@ class Matcher: - def __init__(self, machines: list[Machine], flavors: list[FlavorSpec]): - self.machines = machines + def __init__(self, flavors: list[FlavorSpec]): self.flavors = flavors def score_machine_to_flavor(self, machine: Machine, flavor: FlavorSpec) -> int: @@ -61,24 +60,25 @@ def score_machine_to_flavor(self, machine: Machine, flavor: FlavorSpec) -> int: return score - def get_eligible_machines_for_flavor(self, flavor: FlavorSpec) -> list[Machine]: - scored_machines = [] - - for machine in self.machines: + def match(self, machine: Machine) -> list[FlavorSpec]: + """ + Find list of all flavors that the machine is eligible for. + """ + results = [] + for flavor in self.flavors: score = self.score_machine_to_flavor(machine, flavor) if score > 0: - scored_machines.append((machine, score)) - - # Sort machines by score, highest first - scored_machines.sort(key=lambda x: x[1], reverse=True) + results.append(flavor) + return results - # Return the machine objects, sorted by desirability - return [machine for machine, _ in scored_machines] + def pick_best_flavor(self, machine: Machine) -> FlavorSpec | None: + """ + Obtains list of all flavors that particular machine can be classified + as, then tries to select "the best" one. + """ - def match(self) -> dict[str, list[Machine]]: - results = {} - for flavor in self.flavors: - eligible_machines = self.get_eligible_machines_for_flavor(flavor) - results[flavor.name] = eligible_machines - return results + possible = self.match(machine) + if len(possible) == 0: + return None + return max(possible, key=lambda flv: flv.memory_gb) diff --git a/python/ironic-understack/ironic_understack/resource_class.py b/python/ironic-understack/ironic_understack/resource_class.py index 24654aaa..08819ccf 100644 --- a/python/ironic-understack/ironic_understack/resource_class.py +++ b/python/ironic-understack/ironic_understack/resource_class.py @@ -84,21 +84,9 @@ def __call__(self, task, inventory, plugin_data): def classify(self, machine): # TODO: read the device types repo later - matcher = Matcher([machine], FLAVORS) - possible_flavors_for_machine = { - k: v for (k, v) in matcher.match().items() if len(v) > 0 - } - try: - return self._pick_best_flavor(FLAVORS, possible_flavors_for_machine) - except IndexError as e: - raise NoMatchError(e) - - def _pick_best_flavor(self, all_flavors, matched_flavors): - all_specs = {f.name: f for f in all_flavors} - - # For now choose "best" by memory, but this likely needs to be revisisted. - sorted_flavors = sorted( - matched_flavors.keys(), key=lambda mf: all_specs[mf].memory_gb, reverse=True - ) - best_flavor = sorted_flavors[0] - return best_flavor + matcher = Matcher(FLAVORS) + flavor = matcher.pick_best_flavor(machine) + if not flavor: + raise NoMatchError(f"No flavor found for {machine}") + else: + return flavor diff --git a/python/ironic-understack/ironic_understack/tests/test_matcher.py b/python/ironic-understack/ironic_understack/tests/test_matcher.py index b55e2ee5..3c338417 100644 --- a/python/ironic-understack/ironic_understack/tests/test_matcher.py +++ b/python/ironic-understack/ironic_understack/tests/test_matcher.py @@ -9,7 +9,7 @@ def machines(): return [ # 1024 GB, exact CPU, medium Machine( - memory_mb=1024000, cpu="AMD EPYC 9254 245-Core Processor", disk_gb=1000 + memory_mb=102400, cpu="AMD EPYC 9254 245-Core Processor", disk_gb=1000 ), # 800 GB, non-matching CPU Machine(memory_mb=800000, cpu="Intel Xeon E5-2676 v3", disk_gb=500), @@ -51,99 +51,121 @@ def flavors(): ), ] +def test_exact_match(flavors): + machine = Machine(memory_mb=102400, cpu="AMD EPYC 9254 245-Core Processor", disk_gb=500) + matcher = Matcher(flavors) + matched_flavors = matcher.match(machine) + assert len(matched_flavors) == 1 + assert matched_flavors[0].name == "small" -def test_exact_match(machines, flavors): - matcher = Matcher(machines, flavors) - results = matcher.match() - - # Check for the 'small' flavor - small_eligible_machines = results["small"] - assert ( - len(small_eligible_machines) == 3 - ) # All machines meet the small flavor specs exactly - # But exact match should be listed first. - assert small_eligible_machines[0].memory_gb == 1024 - assert small_eligible_machines[0].disk_gb == 1000 - assert small_eligible_machines[0].cpu == "AMD EPYC 9254 245-Core Processor" - - -def test_no_match_due_to_memory(machines): - high_memory_flavor = FlavorSpec( - name="high_memory", - memory_gb=1500, - cpu_cores=32, - cpu_models=["AMD EPYC 9254 245-Core Processor"], - drives=[1000], - devices=[], - ) - - matcher = Matcher(machines, [high_memory_flavor]) - results = matcher.match() - - assert len(results["high_memory"]) == 0 # No machine has >= 1500 GB of memory - - -def test_no_match_due_to_disk(machines): - high_disk_flavor = FlavorSpec( - name="high_disk", - memory_gb=400, - cpu_cores=27, - cpu_models=["AMD EPYC 9254 245-Core Processor"], - drives=[3000], - devices=[], - ) - - matcher = Matcher(machines, [high_disk_flavor]) - results = matcher.match() - - assert len(results["high_disk"]) == 0 # No machine has >= 3000 GB of disk - - -def test_partial_match(machines, flavors): - matcher = Matcher(machines, flavors) - results = matcher.match() - - medium_eligible_machines = results["medium"] - # Two machines are good enough to be medium - assert len(medium_eligible_machines) == 2 - # But we should select one with smaller memory - best_machine = medium_eligible_machines[0] - assert all( - best_machine.memory_gb <= machine.memory_gb - for machine in medium_eligible_machines - ) - assert all( - best_machine.disk_gb <= machine.disk_gb - for machine in medium_eligible_machines - ) - # ...so that machine: - assert best_machine == machines[2] - - -def test_higher_memory_and_disk(machines, flavors): - matcher = Matcher(machines, flavors) - results = matcher.match() - - large_eligible_machines = results["large"] - # Only one machine meets large flavor specs exactly - assert len(large_eligible_machines) == 1 - best_machine = large_eligible_machines[0] - assert best_machine.memory_gb == 409 # Memory matches exactly - assert best_machine.disk_gb == 2000 # Disk matches exactly - assert best_machine.cpu == "AMD EPYC 9254 245-Core Processor" - - -def test_cpu_mismatch(machines): - different_cpu_flavor = FlavorSpec( - name="different_cpu", - memory_gb=100, - cpu_cores=13, - cpu_models=["Intel Xeon Gold 6258R"], - drives=[500, 500], - devices=[], - ) - - matcher = Matcher(machines, [different_cpu_flavor]) - results = matcher.match() - - assert len(results["different_cpu"]) == 0 + +def test_memory_too_small(flavors): + machine = Machine(memory_mb=51200, cpu="AMD EPYC 9254 245-Core Processor", disk_gb=500) + matcher = Matcher(flavors) + matched_flavors = matcher.match(machine) + assert len(matched_flavors) == 0 + + +def test_disk_too_small(flavors): + machine = Machine(memory_mb=204800, cpu="AMD EPYC 9254 245-Core Processor", disk_gb=100) + matcher = Matcher(flavors) + matched_flavors = matcher.match(machine) + assert len(matched_flavors) == 0 + + +def test_cpu_model_not_matching(flavors): + machine = Machine(memory_mb=102400, cpu="Non-Existent CPU Model", disk_gb=500) + matcher = Matcher(flavors) + matched_flavors = matcher.match(machine) + assert len(matched_flavors) == 0 + + +def test_memory_match_but_more_disk(flavors): + machine = Machine(memory_mb=102400, cpu="AMD EPYC 9254 245-Core Processor", disk_gb=1000) + matcher = Matcher(flavors) + matched_flavors = matcher.match(machine) + assert len(matched_flavors) == 1 + assert matched_flavors[0].name == "small" + + +def test_disk_match_but_more_memory(flavors): + machine = Machine(memory_mb=204800, cpu="AMD EPYC 9254 245-Core Processor", disk_gb=500) + matcher = Matcher(flavors) + matched_flavors = matcher.match(machine) + assert len(matched_flavors) == 1 + assert matched_flavors[0].name == "small" + + +def test_pick_best_flavor(flavors): + machine = Machine(memory_mb=204800, cpu="AMD EPYC 9254 245-Core Processor", disk_gb=1500) + matcher = Matcher(flavors) + best_flavor = matcher.pick_best_flavor(machine) + assert best_flavor is not None + assert best_flavor.name == "medium" + + +def test_no_matching_flavor(flavors): + machine = Machine(memory_mb=51200, cpu="Non-Existent CPU Model", disk_gb=250) + matcher = Matcher(flavors) + best_flavor = matcher.pick_best_flavor(machine) + assert best_flavor is None + + +def test_multiple_flavors_available(flavors): + machine = Machine(memory_mb=204800, cpu="AMD EPYC 9254 245-Core Processor", disk_gb=2000) + matcher = Matcher(flavors) + matched_flavors = matcher.match(machine) + assert len(matched_flavors) == 2 # small and medium should be available + best_flavor = matcher.pick_best_flavor(machine) + assert best_flavor.name == "medium" # medium has more memory, so it should be selected + + +# Edge cases +def test_memory_slightly_less(flavors): + # Machine with slightly less memory than required by the smallest flavor + machine = Machine(memory_mb=102300, cpu="AMD EPYC 9254 245-Core Processor", disk_gb=500) + matcher = Matcher(flavors) + matched_flavors = matcher.match(machine) + assert len(matched_flavors) == 0 # Should not match because memory is slightly less + + +def test_disk_slightly_less(flavors): + # Machine with slightly less disk space than required by the smallest flavor + machine = Machine(memory_mb=102400, cpu="AMD EPYC 9254 245-Core Processor", disk_gb=499) + matcher = Matcher(flavors) + matched_flavors = matcher.match(machine) + assert len(matched_flavors) == 0 # Should not match because disk space is slightly less + + +def test_memory_exact_disk_slightly_more(flavors): + # Machine with exact memory but slightly more disk space than required + machine = Machine(memory_mb=102400, cpu="AMD EPYC 9254 245-Core Processor", disk_gb=501) + matcher = Matcher(flavors) + matched_flavors = matcher.match(machine) + assert len(matched_flavors) == 1 + assert matched_flavors[0].name == "small" # Should match but with a lower score due to extra disk space + + +def test_disk_exact_memory_slightly_more(flavors): + # Machine with exact disk space but slightly more memory than required + machine = Machine(memory_mb=102500, cpu="AMD EPYC 9254 245-Core Processor", disk_gb=500) + matcher = Matcher(flavors) + matched_flavors = matcher.match(machine) + assert len(matched_flavors) == 1 + assert matched_flavors[0].name == "small" # Should match but with a lower score due to extra memory + + +def test_cpu_model_not_exact_but_memory_and_disk_match(flavors): + # Machine with exact memory and disk space but CPU model is close but not exact + machine = Machine(memory_mb=102400, cpu="AMD EPYC 9254 245-Core Processor v2", disk_gb=500) + matcher = Matcher(flavors) + matched_flavors = matcher.match(machine) + assert len(matched_flavors) == 0 # Should not match because CPU model is not exactly listed + + +def test_large_flavor_memory_slightly_less_disk_exact(flavors): + # Machine with slightly less memory than required for the medium flavor, exact disk space + machine = Machine(memory_mb=204600, cpu="Intel 80386DX", disk_gb=1800) + matcher = Matcher(flavors) + matched_flavors = matcher.match(machine) + assert len(matched_flavors) == 0 # Should not match because memory is slightly less than required From 67c818613548a6b6b878ecdfcd9dc8acfd98bd7c Mon Sep 17 00:00:00 2001 From: Marek Skrobacki Date: Wed, 28 Aug 2024 11:30:21 +0100 Subject: [PATCH 07/14] update poetry.lock with deps --- python/ironic-understack/poetry.lock | 558 +++++++++++++++++++-------- 1 file changed, 399 insertions(+), 159 deletions(-) diff --git a/python/ironic-understack/poetry.lock b/python/ironic-understack/poetry.lock index 36265ce5..1071fb83 100644 --- a/python/ironic-understack/poetry.lock +++ b/python/ironic-understack/poetry.lock @@ -12,6 +12,8 @@ files = [ ] [package.dependencies] +importlib-metadata = {version = "*", markers = "python_version < \"3.9\""} +importlib-resources = {version = "*", markers = "python_version < \"3.9\""} Mako = "*" SQLAlchemy = ">=1.3.0" typing-extensions = ">=4" @@ -33,6 +35,17 @@ files = [ [package.dependencies] vine = ">=5.0.0,<6.0.0" +[[package]] +name = "async-timeout" +version = "4.0.3" +description = "Timeout context manager for asyncio programs" +optional = false +python-versions = ">=3.7" +files = [ + {file = "async-timeout-4.0.3.tar.gz", hash = "sha256:4640d96be84d82d02ed59ea2b7105a0f7b33abe8703703cd0ab0bf87c427522f"}, + {file = "async_timeout-4.0.3-py3-none-any.whl", hash = "sha256:7405140ff1230c310e51dc27b3145b9092d659ce68ff733fb0cefe3ee42be028"}, +] + [[package]] name = "attrs" version = "24.2.0" @@ -67,6 +80,37 @@ files = [ pbr = ">=2.0.0,<2.1.0 || >2.1.0" PrettyTable = ">=0.7.2" +[[package]] +name = "backports-zoneinfo" +version = "0.2.1" +description = "Backport of the standard library zoneinfo module" +optional = false +python-versions = ">=3.6" +files = [ + {file = "backports.zoneinfo-0.2.1-cp36-cp36m-macosx_10_14_x86_64.whl", hash = "sha256:da6013fd84a690242c310d77ddb8441a559e9cb3d3d59ebac9aca1a57b2e18bc"}, + {file = "backports.zoneinfo-0.2.1-cp36-cp36m-manylinux1_i686.whl", hash = "sha256:89a48c0d158a3cc3f654da4c2de1ceba85263fafb861b98b59040a5086259722"}, + {file = "backports.zoneinfo-0.2.1-cp36-cp36m-manylinux1_x86_64.whl", hash = "sha256:1c5742112073a563c81f786e77514969acb58649bcdf6cdf0b4ed31a348d4546"}, + {file = "backports.zoneinfo-0.2.1-cp36-cp36m-win32.whl", hash = "sha256:e8236383a20872c0cdf5a62b554b27538db7fa1bbec52429d8d106effbaeca08"}, + {file = "backports.zoneinfo-0.2.1-cp36-cp36m-win_amd64.whl", hash = "sha256:8439c030a11780786a2002261569bdf362264f605dfa4d65090b64b05c9f79a7"}, + {file = "backports.zoneinfo-0.2.1-cp37-cp37m-macosx_10_14_x86_64.whl", hash = "sha256:f04e857b59d9d1ccc39ce2da1021d196e47234873820cbeaad210724b1ee28ac"}, + {file = "backports.zoneinfo-0.2.1-cp37-cp37m-manylinux1_i686.whl", hash = "sha256:17746bd546106fa389c51dbea67c8b7c8f0d14b5526a579ca6ccf5ed72c526cf"}, + {file = "backports.zoneinfo-0.2.1-cp37-cp37m-manylinux1_x86_64.whl", hash = "sha256:5c144945a7752ca544b4b78c8c41544cdfaf9786f25fe5ffb10e838e19a27570"}, + {file = "backports.zoneinfo-0.2.1-cp37-cp37m-win32.whl", hash = "sha256:e55b384612d93be96506932a786bbcde5a2db7a9e6a4bb4bffe8b733f5b9036b"}, + {file = "backports.zoneinfo-0.2.1-cp37-cp37m-win_amd64.whl", hash = "sha256:a76b38c52400b762e48131494ba26be363491ac4f9a04c1b7e92483d169f6582"}, + {file = "backports.zoneinfo-0.2.1-cp38-cp38-macosx_10_14_x86_64.whl", hash = "sha256:8961c0f32cd0336fb8e8ead11a1f8cd99ec07145ec2931122faaac1c8f7fd987"}, + {file = "backports.zoneinfo-0.2.1-cp38-cp38-manylinux1_i686.whl", hash = "sha256:e81b76cace8eda1fca50e345242ba977f9be6ae3945af8d46326d776b4cf78d1"}, + {file = "backports.zoneinfo-0.2.1-cp38-cp38-manylinux1_x86_64.whl", hash = "sha256:7b0a64cda4145548fed9efc10322770f929b944ce5cee6c0dfe0c87bf4c0c8c9"}, + {file = "backports.zoneinfo-0.2.1-cp38-cp38-win32.whl", hash = "sha256:1b13e654a55cd45672cb54ed12148cd33628f672548f373963b0bff67b217328"}, + {file = "backports.zoneinfo-0.2.1-cp38-cp38-win_amd64.whl", hash = "sha256:4a0f800587060bf8880f954dbef70de6c11bbe59c673c3d818921f042f9954a6"}, + {file = "backports.zoneinfo-0.2.1.tar.gz", hash = "sha256:fadbfe37f74051d024037f223b8e001611eac868b5c5b06144ef4d8b799862f2"}, +] + +[package.dependencies] +tzdata = {version = "*", optional = true, markers = "extra == \"tzdata\""} + +[package.extras] +tzdata = ["tzdata"] + [[package]] name = "bcrypt" version = "4.2.0" @@ -440,6 +484,7 @@ files = [ [package.dependencies] decorator = ">=4.0.0" stevedore = ">=3.0.0" +typing_extensions = {version = ">=4.0.1", markers = "python_version < \"3.11\""} [package.extras] pifpaf = ["pifpaf (>=2.5.0)", "setuptools"] @@ -462,6 +507,20 @@ greenlet = ">=1.0" [package.extras] dev = ["black", "build", "commitizen", "isort", "pip-tools", "pre-commit", "twine"] +[[package]] +name = "exceptiongroup" +version = "1.2.2" +description = "Backport of PEP 654 (exception groups)" +optional = false +python-versions = ">=3.7" +files = [ + {file = "exceptiongroup-1.2.2-py3-none-any.whl", hash = "sha256:3111b9d131c238bec2f8f516e123e14ba243563fb135d3fe885990585aa7795b"}, + {file = "exceptiongroup-1.2.2.tar.gz", hash = "sha256:47c2edf7c6738fafb49fd34290706d1a1a2f4d1c6df275526b62cbb4aa5393cc"}, +] + +[package.extras] +test = ["pytest (>=6)"] + [[package]] name = "fasteners" version = "0.19" @@ -557,13 +616,13 @@ test = ["objgraph", "psutil"] [[package]] name = "idna" -version = "3.7" +version = "3.8" description = "Internationalized Domain Names in Applications (IDNA)" optional = false -python-versions = ">=3.5" +python-versions = ">=3.6" files = [ - {file = "idna-3.7-py3-none-any.whl", hash = "sha256:82fee1fc78add43492d3a1898bfa6d8a904cc97d8427f683ed8e798d07761aa0"}, - {file = "idna-3.7.tar.gz", hash = "sha256:028ff3aadf0609c1fd278d8ea3089299412a7a8b9bd005dd08b9f8285bcb5cfc"}, + {file = "idna-3.8-py3-none-any.whl", hash = "sha256:050b4e5baadcd44d760cedbd2b8e639f2ff89bbc7a5730fcc662954303377aac"}, + {file = "idna-3.8.tar.gz", hash = "sha256:d838c2c0ed6fced7693d5e8ab8e734d5f8fda53a039c0164afb0b82e771e3603"}, ] [[package]] @@ -577,6 +636,47 @@ files = [ {file = "ifaddr-0.2.0.tar.gz", hash = "sha256:cc0cbfcaabf765d44595825fb96a99bb12c79716b73b44330ea38ee2b0c4aed4"}, ] +[[package]] +name = "importlib-metadata" +version = "8.4.0" +description = "Read metadata from Python packages" +optional = false +python-versions = ">=3.8" +files = [ + {file = "importlib_metadata-8.4.0-py3-none-any.whl", hash = "sha256:66f342cc6ac9818fc6ff340576acd24d65ba0b3efabb2b4ac08b598965a4a2f1"}, + {file = "importlib_metadata-8.4.0.tar.gz", hash = "sha256:9a547d3bc3608b025f93d403fdd1aae741c24fbb8314df4b155675742ce303c5"}, +] + +[package.dependencies] +zipp = ">=0.5" + +[package.extras] +doc = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-lint"] +perf = ["ipython"] +test = ["flufl.flake8", "importlib-resources (>=1.3)", "jaraco.test (>=5.4)", "packaging", "pyfakefs", "pytest (>=6,!=8.1.*)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=2.2)", "pytest-mypy", "pytest-perf (>=0.9.2)", "pytest-ruff (>=0.2.1)"] + +[[package]] +name = "importlib-resources" +version = "6.4.4" +description = "Read resources from Python packages" +optional = false +python-versions = ">=3.8" +files = [ + {file = "importlib_resources-6.4.4-py3-none-any.whl", hash = "sha256:dda242603d1c9cd836c3368b1174ed74cb4049ecd209e7a1a0104620c18c5c11"}, + {file = "importlib_resources-6.4.4.tar.gz", hash = "sha256:20600c8b7361938dc0bb2d5ec0297802e575df486f5a544fa414da65e13721f7"}, +] + +[package.dependencies] +zipp = {version = ">=3.1.0", markers = "python_version < \"3.10\""} + +[package.extras] +check = ["pytest-checkdocs (>=2.4)", "pytest-ruff (>=0.2.1)"] +cover = ["pytest-cov"] +doc = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-lint"] +enabler = ["pytest-enabler (>=2.2)"] +test = ["jaraco.test (>=5.4)", "pytest (>=6,!=8.1.*)", "zipp (>=3.17)"] +type = ["pytest-mypy"] + [[package]] name = "iniconfig" version = "2.0.0" @@ -590,13 +690,13 @@ files = [ [[package]] name = "ironic" -version = "26.0.0" +version = "24.1.1" description = "OpenStack Bare Metal Provisioning" optional = false python-versions = ">=3.8" files = [ - {file = "ironic-26.0.0-py3-none-any.whl", hash = "sha256:2506bec6dd46af01d872b75ae80a34b663ea34b8993664e72aedc81449946a54"}, - {file = "ironic-26.0.0.tar.gz", hash = "sha256:2e3b9f59452c6be7bcc5c9e1dea737695193ddd7560f3607cf9c44c6a8a6a907"}, + {file = "ironic-24.1.1-py3-none-any.whl", hash = "sha256:3f465c20e0ac55f00dcca8bbfbd9cf8c318074282ca429088483e5c024a5fe41"}, + {file = "ironic-24.1.1.tar.gz", hash = "sha256:4a090bbd21b440b3cb435a9b9df63d77d80dc5e061e838b1117915a4b817f529"}, ] [package.dependencies] @@ -607,13 +707,12 @@ eventlet = ">=0.30.1" futurist = ">=1.2.0" ironic-lib = ">=6.0.0" Jinja2 = ">=3.0.0" -jsonpatch = ">=1.16" +jsonpatch = ">=1.16,<1.20 || >1.20" jsonschema = ">=4.0.0" keystoneauth1 = ">=4.2.0" keystonemiddleware = ">=9.5.0" -microversion-parse = ">=1.0.1" netaddr = ">=0.9.0" -openstacksdk = ">=0.99.0" +openstacksdk = ">=0.48.0" os-traits = ">=0.4.0" "oslo.concurrency" = ">=4.2.0" "oslo.config" = ">=6.8.0" @@ -625,15 +724,17 @@ os-traits = ">=0.4.0" "oslo.policy" = ">=3.7.0" "oslo.rootwrap" = ">=5.8.0" "oslo.serialization" = ">=2.25.0" -"oslo.service" = ">=1.24.0" +"oslo.service" = ">=1.24.0,<1.28.1 || >1.28.1" "oslo.upgradecheck" = ">=1.3.0" "oslo.utils" = ">=4.5.0" "oslo.versionedobjects" = ">=1.31.2" osprofiler = ">=1.5.0" pbr = ">=3.1.1" -pecan = ">=1.0.0" +pecan = ">=1.0.0,<1.0.2 || >1.0.2,<1.0.3 || >1.0.3,<1.0.4 || >1.0.4,<1.2 || >1.2" psutil = ">=3.2.2" pycdlib = ">=1.11.0" +python-cinderclient = ">=3.3.0,<4.0.0 || >4.0.0" +python-glanceclient = ">=2.8.0" requests = ">=2.18.0" rfc3986 = ">=1.2.0" SQLAlchemy = ">=1.4.0" @@ -647,17 +748,17 @@ WebOb = ">=1.7.1" devstack = ["virtualbmc (>=1.4.0)"] guru-meditation-reports = ["oslo.reports (>=1.18.0)"] i18n = ["oslo.i18n (>=3.20.0)"] -test = ["PyMySQL (>=0.8.0)", "WebTest (>=2.0.27)", "bandit (>=1.1.0,<2.0.0)", "coverage (>=4.0)", "ddt (>=1.2.1)", "fixtures (>=3.0.0)", "iso8601 (>=0.1.11)", "oslo.reports (>=1.18.0)", "oslotest (>=3.2.0)", "psycopg2 (>=2.8.5)", "pyasn1 (>=0.5.1)", "pyasn1-modules (>=0.3.0)", "pysnmp-lextudio (>=5.0.0)", "stestr (>=2.0.0)", "testtools (>=2.5.0)"] +test = ["PyMySQL (>=0.8.0)", "WebTest (>=2.0.27)", "bandit (>=1.1.0,!=1.6.0,<2.0.0)", "coverage (>=4.0,!=4.4)", "ddt (>=1.2.1)", "fixtures (>=3.0.0)", "iso8601 (>=0.1.11)", "oslo.reports (>=1.18.0)", "oslotest (>=3.2.0)", "psycopg2 (>=2.8.5)", "pyasn1 (>=0.5.1)", "pyasn1-modules (>=0.3.0)", "pysnmp-lextudio (>=5.0.0)", "stestr (>=2.0.0)", "testtools (>=2.5.0)"] [[package]] name = "ironic-lib" -version = "6.1.0" +version = "6.2.0" description = "Ironic common library" optional = false python-versions = ">=3.8" files = [ - {file = "ironic-lib-6.1.0.tar.gz", hash = "sha256:6c41150bdd3124920138770c626fe8a2dde50c08c1eee645dbfd4d8b717f5a7a"}, - {file = "ironic_lib-6.1.0-py3-none-any.whl", hash = "sha256:1ecd32dab2ca0cb68da190d2f30383775a9b374f040b664dc21dcb80e0a88dbe"}, + {file = "ironic-lib-6.2.0.tar.gz", hash = "sha256:a8dca60f79b5b53c0f61e74a92fb8a3ab8144086ea37d72700e08701c018ef11"}, + {file = "ironic_lib-6.2.0-py3-none-any.whl", hash = "sha256:9946e332d552e2a49a97059b5cb063a2216e84fff9bc01541ac2a72428a5e6d1"}, ] [package.dependencies] @@ -748,7 +849,9 @@ files = [ [package.dependencies] attrs = ">=22.2.0" +importlib-resources = {version = ">=1.4.0", markers = "python_version < \"3.9\""} jsonschema-specifications = ">=2023.03.6" +pkgutil-resolve-name = {version = ">=1.3.10", markers = "python_version < \"3.9\""} referencing = ">=0.28.4" rpds-py = ">=0.7.1" @@ -768,23 +871,24 @@ files = [ ] [package.dependencies] +importlib-resources = {version = ">=1.4.0", markers = "python_version < \"3.9\""} referencing = ">=0.31.0" [[package]] name = "keystoneauth1" -version = "5.7.0" +version = "5.8.0" description = "Authentication Library for OpenStack Identity" optional = false python-versions = ">=3.8" files = [ - {file = "keystoneauth1-5.7.0-py3-none-any.whl", hash = "sha256:a3623bd03ed9a8cf1866d3eba113423e3cd898f74b79dd95598152b473a2cecc"}, - {file = "keystoneauth1-5.7.0.tar.gz", hash = "sha256:b2cc2d68d1a48e9c2c6d9b1b1fd00d7c7bdfe086e8040b51e70938a8ba3adfd1"}, + {file = "keystoneauth1-5.8.0-py3-none-any.whl", hash = "sha256:e69dff80c509ab64d4de4494658d914e81f26af720828dc584ceee74ecd666d9"}, + {file = "keystoneauth1-5.8.0.tar.gz", hash = "sha256:3157c212e121164de64d63e5ef7e1daad2bd3649a68de1e971b76877019ef1c4"}, ] [package.dependencies] iso8601 = ">=0.1.11" os-service-types = ">=1.2.0" -pbr = ">=2.0.0,<2.1.0 || >2.1.0" +pbr = ">=2.0.0" requests = ">=2.14.2" stevedore = ">=1.20.0" @@ -793,7 +897,7 @@ betamax = ["betamax (>=0.7.0)", "fixtures (>=3.0.0)", "mock (>=2.0.0)"] kerberos = ["requests-kerberos (>=0.8.0)"] oauth1 = ["oauthlib (>=0.6.2)"] saml2 = ["lxml (>=4.2.0)"] -test = ["PyYAML (>=3.12)", "bandit (>=1.7.6,<1.8.0)", "betamax (>=0.7.0)", "coverage (>=4.0,!=4.4)", "fixtures (>=3.0.0)", "flake8-docstrings (>=1.7.0,<1.8.0)", "flake8-import-order (>=0.18.2,<0.19.0)", "hacking (>=6.1.0,<6.2.0)", "lxml (>=4.2.0)", "oauthlib (>=0.6.2)", "oslo.config (>=5.2.0)", "oslo.utils (>=3.33.0)", "oslotest (>=3.2.0)", "requests-kerberos (>=0.8.0)", "requests-mock (>=1.2.0)", "stestr (>=1.0.0)", "testresources (>=2.0.0)", "testtools (>=2.2.0)"] +test = ["PyYAML (>=3.12)", "bandit (>=1.7.6,<1.8.0)", "betamax (>=0.7.0)", "coverage (>=4.0)", "fixtures (>=3.0.0)", "flake8-docstrings (>=1.7.0,<1.8.0)", "flake8-import-order (>=0.18.2,<0.19.0)", "hacking (>=6.1.0,<6.2.0)", "lxml (>=4.2.0)", "oauthlib (>=0.6.2)", "oslo.config (>=5.2.0)", "oslo.utils (>=3.33.0)", "oslotest (>=3.2.0)", "requests-kerberos (>=0.8.0)", "requests-mock (>=1.2.0)", "stestr (>=1.0.0)", "testresources (>=2.0.0)", "testtools (>=2.2.0)"] [[package]] name = "keystonemiddleware" @@ -839,6 +943,8 @@ files = [ [package.dependencies] amqp = ">=5.1.1,<6.0.0" +"backports.zoneinfo" = {version = ">=0.2.1", extras = ["tzdata"], markers = "python_version < \"3.9\""} +typing-extensions = {version = "4.12.2", markers = "python_version < \"3.10\""} vine = "5.1.0" [package.extras] @@ -956,20 +1062,6 @@ files = [ {file = "MarkupSafe-2.1.5.tar.gz", hash = "sha256:d283d37a890ba4c1ae73ffadf8046435c76e7bc2247bbb63c00bd1a709c6544b"}, ] -[[package]] -name = "microversion-parse" -version = "1.0.1" -description = "OpenStack microversion header parser" -optional = false -python-versions = ">=3.6" -files = [ - {file = "microversion_parse-1.0.1-py3-none-any.whl", hash = "sha256:aab3ab98028923e778920ba6a837ea3b190d8827b08b3d1e845d9c44c9dfc221"}, - {file = "microversion_parse-1.0.1.tar.gz", hash = "sha256:ec6bc0711019f620d6690087b958f934634a242e49a7c1c60c1688363cbe102d"}, -] - -[package.dependencies] -WebOb = ">=1.2.3" - [[package]] name = "msgpack" version = "1.0.8" @@ -1168,13 +1260,13 @@ test = ["etcd3gw (>=0.2.0)", "oslotest (>=3.2.0)", "pifpaf (>=0.10.0)", "pymemca [[package]] name = "oslo-concurrency" -version = "6.0.0" +version = "6.1.0" description = "Oslo Concurrency library" optional = false python-versions = ">=3.8" files = [ - {file = "oslo.concurrency-6.0.0-py3-none-any.whl", hash = "sha256:50caec55f8a122935dacb0fd73b424f6cba6994f5e2342e2676dd45d743ebf88"}, - {file = "oslo.concurrency-6.0.0.tar.gz", hash = "sha256:b52f02b4e46f5f274b91fb8e1bfc5cbf9a418dfcd4a83be080345495e3d26e8a"}, + {file = "oslo.concurrency-6.1.0-py3-none-any.whl", hash = "sha256:9941de3a2dee50fe8413bd60dae6ac61b7c2e69febe1b6907bd82588da49f7e0"}, + {file = "oslo.concurrency-6.1.0.tar.gz", hash = "sha256:b564ae0af2ee5770f3b6e630df26a4b8676c7fe42287f1883e259a51aaddf097"}, ] [package.dependencies] @@ -1182,17 +1274,17 @@ fasteners = ">=0.7.0" "oslo.config" = ">=5.2.0" "oslo.i18n" = ">=3.15.3" "oslo.utils" = ">=3.33.0" -pbr = ">=2.0.0,<2.1.0 || >2.1.0" +pbr = ">=2.0.0" [[package]] name = "oslo-config" -version = "9.5.0" +version = "9.6.0" description = "Oslo Configuration API" optional = false python-versions = ">=3.8" files = [ - {file = "oslo.config-9.5.0-py3-none-any.whl", hash = "sha256:f5e9a6848c35a1c8975677d623ffcf31bbb7177d14cb8f43505b2a4c679dcdd0"}, - {file = "oslo.config-9.5.0.tar.gz", hash = "sha256:aa500044886b6c55f76577cb5a93492a4596c5f9283376760ea7852cc49c99a3"}, + {file = "oslo.config-9.6.0-py3-none-any.whl", hash = "sha256:7bcd6c3d9dbdd6e4d49a9a6dc3d10ae96073ebe3175280031adc0cbc76500967"}, + {file = "oslo.config-9.6.0.tar.gz", hash = "sha256:9f05ef70e48d9a61a8d0c9bed389da24f2ef5a89df5b6e8deb7c741d6113667e"}, ] [package.dependencies] @@ -1210,18 +1302,18 @@ test = ["bandit (>=1.7.0,<1.8.0)", "coverage (>=4.0)", "fixtures (>=3.0.0)", "ha [[package]] name = "oslo-context" -version = "5.5.0" +version = "5.6.0" description = "Oslo Context library" optional = false python-versions = ">=3.8" files = [ - {file = "oslo.context-5.5.0-py3-none-any.whl", hash = "sha256:aa858a42aac9858bf259bc0804513a8f9bf36916f9cfc8937708f6c90ad68259"}, - {file = "oslo.context-5.5.0.tar.gz", hash = "sha256:eae0317b29928f1934df4c60b860fe8625247cb297c5cc62fef8eb5827b12fac"}, + {file = "oslo.context-5.6.0-py3-none-any.whl", hash = "sha256:51bfab0a3915dcea3823612fdd0737e839d33c8551168ae8e1bcfdd07ba60985"}, + {file = "oslo.context-5.6.0.tar.gz", hash = "sha256:5222c32636be070a230df9d3141a0b27a95f0a3b6978f4c1485bcada47a4c3cb"}, ] [package.dependencies] debtcollector = ">=1.2.0" -pbr = ">=2.0.0,<2.1.0 || >2.1.0" +pbr = ">=2.0.0" [[package]] name = "oslo-db" @@ -1253,27 +1345,27 @@ test = ["PyMySQL (>=0.7.6)", "bandit (>=1.7.0,<1.8.0)", "coverage (>=4.0)", "eve [[package]] name = "oslo-i18n" -version = "6.3.0" +version = "6.4.0" description = "Oslo i18n library" optional = false python-versions = ">=3.8" files = [ - {file = "oslo.i18n-6.3.0-py3-none-any.whl", hash = "sha256:698eb5c63a01359ed6d91031d6331098190d38be0bdda7d270264d6f86bc79e7"}, - {file = "oslo.i18n-6.3.0.tar.gz", hash = "sha256:64a251edef8bf1bb1d4e6f78d377e149d4f15c1a9245de77f172016da6267444"}, + {file = "oslo.i18n-6.4.0-py3-none-any.whl", hash = "sha256:5417778ba3b1920b70b99859d730ac9bf37f18050dc28af890c66345ba855bc0"}, + {file = "oslo.i18n-6.4.0.tar.gz", hash = "sha256:66e04c041e9ff17d07e13ec7f48295fbc36169143c72ca2352a3efcc98e7b608"}, ] [package.dependencies] -pbr = ">=2.0.0,<2.1.0 || >2.1.0" +pbr = ">=2.0.0" [[package]] name = "oslo-log" -version = "6.1.1" +version = "6.1.2" description = "oslo.log library" optional = false python-versions = ">=3.8" files = [ - {file = "oslo.log-6.1.1-py3-none-any.whl", hash = "sha256:f7f162ab03dc3f0728d8abee2806677146a2704aa22d4b3d7a9e4d1c1c68a26e"}, - {file = "oslo.log-6.1.1.tar.gz", hash = "sha256:e35a12cfe4cad13ffb0aeda99fcca20a705d0f694a84c2ef7b07b45960f88fb4"}, + {file = "oslo.log-6.1.2-py3-none-any.whl", hash = "sha256:8e6f47800a40271a7d6e40948a6717d76fadb28ef54d27b93a3a587aed2f8981"}, + {file = "oslo.log-6.1.2.tar.gz", hash = "sha256:f768047df9d706c484dd6665dcbbea289021d48cb7ce5abf7a1f69a09491f5fe"}, ] [package.dependencies] @@ -1292,13 +1384,13 @@ test = ["coverage (>=4.5.1)", "eventlet (>=0.30.1)", "fixtures (>=3.0.0)", "oslo [[package]] name = "oslo-messaging" -version = "14.8.1" +version = "14.9.0" description = "Oslo Messaging API" optional = false python-versions = ">=3.8" files = [ - {file = "oslo.messaging-14.8.1-py3-none-any.whl", hash = "sha256:022813f3426f01aaf53166546aa5704786da8eed0bc69b30daa5b4a5c37cb862"}, - {file = "oslo.messaging-14.8.1.tar.gz", hash = "sha256:1ae35f71f8fb2bbd859bdb9c46f4468a451278d15e4c88c114b4fbe10b7d87f4"}, + {file = "oslo.messaging-14.9.0-py3-none-any.whl", hash = "sha256:16e0fb02fd5105aed329c12fc48285e34e543d803b8b6bcb97983b4206fb600c"}, + {file = "oslo.messaging-14.9.0.tar.gz", hash = "sha256:3c317c3835adc160e348b8f21885145205f6fd28200f5a4c2f96d728030274e4"}, ] [package.dependencies] @@ -1327,13 +1419,13 @@ test = ["bandit (>=1.7.0,<1.8.0)", "confluent-kafka (>=1.3.0)", "coverage (>=4.0 [[package]] name = "oslo-metrics" -version = "0.8.0" +version = "0.9.0" description = "Oslo Metrics API" optional = false python-versions = ">=3.8" files = [ - {file = "oslo.metrics-0.8.0-py3-none-any.whl", hash = "sha256:ef4785ae5387cf2013565927eefb87237cdf10d28352338434d2bac3ef71ab25"}, - {file = "oslo.metrics-0.8.0.tar.gz", hash = "sha256:ea31fd3b2ac76dcbe25d935e0616ad1893e3cbc53746e9fb9d5f5e1df04f943c"}, + {file = "oslo.metrics-0.9.0-py3-none-any.whl", hash = "sha256:2782ec80742a439ee6339c5ec98416613bd816e64f93c3e8e579bad5e4ac33f1"}, + {file = "oslo.metrics-0.9.0.tar.gz", hash = "sha256:0c8818757c9ad33a93c1edb1e14296f9bf4686bfe1e0e68413276941afeea0a5"}, ] [package.dependencies] @@ -1345,13 +1437,13 @@ prometheus-client = ">=0.6.0" [[package]] name = "oslo-middleware" -version = "6.1.0" +version = "6.2.0" description = "Oslo Middleware library" optional = false python-versions = ">=3.8" files = [ - {file = "oslo.middleware-6.1.0-py3-none-any.whl", hash = "sha256:72ddec614f0f67f888b18d4e801d8e2146fbb49e03ada9e8e78b06d9dba718f4"}, - {file = "oslo.middleware-6.1.0.tar.gz", hash = "sha256:431c601199b728b7a7c6d63dc8cdc89969fd959f730fbbe0022f07ba437e8d0c"}, + {file = "oslo.middleware-6.2.0-py3-none-any.whl", hash = "sha256:bba853aa9f6629a9f3db941b6fc78feb45e212583f4069f4fe8ee0493897eb8e"}, + {file = "oslo.middleware-6.2.0.tar.gz", hash = "sha256:99959abe5baa6d6372730d1e67a57b429fb77c737e1c03dc8b000ccaf2394cd4"}, ] [package.dependencies] @@ -1362,7 +1454,7 @@ Jinja2 = ">=2.10" "oslo.context" = ">=2.19.2" "oslo.i18n" = ">=3.15.3" "oslo.utils" = ">=3.33.0" -pbr = ">=2.0.0,<2.1.0 || >2.1.0" +pbr = ">=2.0.0" statsd = ">=3.2.1" stevedore = ">=1.20.0" WebOb = ">=1.8.0" @@ -1390,13 +1482,13 @@ stevedore = ">=1.20.0" [[package]] name = "oslo-rootwrap" -version = "7.2.0" +version = "7.3.0" description = "Oslo Rootwrap" optional = false python-versions = ">=3.8" files = [ - {file = "oslo.rootwrap-7.2.0-py3-none-any.whl", hash = "sha256:2f2c119c4c11d73160c956fb75851d2723b62fc0b6af04ebda72e626d9c4caea"}, - {file = "oslo.rootwrap-7.2.0.tar.gz", hash = "sha256:5102b057f6e9749adc692d32c4673778bdc8da178a6c99e0f438c5c33858786a"}, + {file = "oslo.rootwrap-7.3.0-py3-none-any.whl", hash = "sha256:69a365ac649e4da308f45cca7f4623cef8bd3240ec8e6f5376f97d02f5d6fafb"}, + {file = "oslo.rootwrap-7.3.0.tar.gz", hash = "sha256:d761d8e71cc7285ea455dc7c94d6c2f8dfbf34bb9180c8276ef1c2485528df67"}, ] [[package]] @@ -1414,6 +1506,7 @@ files = [ msgpack = ">=0.5.2" "oslo.utils" = ">=3.33.0" pbr = ">=2.0.0" +pytz = {version = ">=2013.6", markers = "python_version < \"3.9\""} tzdata = {version = ">=2022.4", markers = "python_version >= \"3.9\""} [[package]] @@ -1444,13 +1537,13 @@ Yappi = ">=1.0" [[package]] name = "oslo-upgradecheck" -version = "2.3.0" +version = "2.4.0" description = "Common code for writing OpenStack upgrade checks" optional = false python-versions = ">=3.8" files = [ - {file = "oslo.upgradecheck-2.3.0-py3-none-any.whl", hash = "sha256:e7460104c763d23f5c4d0b3eb709a925f26f4f273005612583ea52518b47d323"}, - {file = "oslo.upgradecheck-2.3.0.tar.gz", hash = "sha256:46ea5330f0fcd8310d8d63a3b2643813026b7d7fbd6f35cf60409117ba105eb2"}, + {file = "oslo.upgradecheck-2.4.0-py3-none-any.whl", hash = "sha256:8689efb3b2d3f4df1c1b233de6f6cea8f89d22c611f9f083d9b59f88aa051173"}, + {file = "oslo.upgradecheck-2.4.0.tar.gz", hash = "sha256:ab79191e74b2ae86c3b8a8f49ab49fc0e4989ecde4ad4ef4d4d5e24e956b7993"}, ] [package.dependencies] @@ -1462,13 +1555,13 @@ PrettyTable = ">=0.7.1" [[package]] name = "oslo-utils" -version = "7.2.0" +version = "7.3.0" description = "Oslo Utility library" optional = false python-versions = ">=3.8" files = [ - {file = "oslo.utils-7.2.0-py3-none-any.whl", hash = "sha256:53ce2d88fd1e9035e6be18c53447353d3e92ea0473d88272f43dc334ea9295af"}, - {file = "oslo.utils-7.2.0.tar.gz", hash = "sha256:94f8053391a33502dab4d84465403262ca19ffd8cfd29a1a5ea3c8aa620ef610"}, + {file = "oslo.utils-7.3.0-py3-none-any.whl", hash = "sha256:a25c0a3270f71fcfa822a72c3f74bd61fe41e97240812986695cd32d4a171fb1"}, + {file = "oslo.utils-7.3.0.tar.gz", hash = "sha256:59a5d3e4e7bbc78d801ccebc2b823e429b624c12bb6e3b6e76f71c29f2bf21df"}, ] [package.dependencies] @@ -1479,6 +1572,7 @@ netifaces = ">=0.10.4" "oslo.i18n" = ">=3.15.3" packaging = ">=20.4" pyparsing = ">=2.1.0" +pytz = {version = ">=2013.6", markers = "python_version < \"3.9\""} PyYAML = ">=3.13" tzdata = {version = ">=2022.4", markers = "python_version >= \"3.9\""} @@ -1508,18 +1602,19 @@ WebOb = ">=1.7.1" [[package]] name = "osprofiler" -version = "4.1.0" +version = "4.2.0" description = "OpenStack Profiler Library" optional = false python-versions = ">=3.8" files = [ - {file = "osprofiler-4.1.0-py3-none-any.whl", hash = "sha256:7db027e12033fa72fefaa107a1a69e05c730acaabcc74117a9c87840526686b4"}, - {file = "osprofiler-4.1.0.tar.gz", hash = "sha256:57837b620581b13444a2e20564775d4fc73eff67c7888af99947ed582fe514b0"}, + {file = "osprofiler-4.2.0-py3-none-any.whl", hash = "sha256:870bac80dc00bce17be7344dc2cc4c843eab6adcca28beff61c1b0d9d1d1ab5b"}, + {file = "osprofiler-4.2.0.tar.gz", hash = "sha256:6dd1c4be2645a8f24121055da5bb461688dcafc7e6b4d4babc0ef1ba66902781"}, ] [package.dependencies] netaddr = ">=0.7.18" "oslo.concurrency" = ">=3.26.0" +"oslo.config" = ">=5.2.0" "oslo.serialization" = ">=2.18.0" "oslo.utils" = ">=3.33.0" PrettyTable = ">=0.7.2" @@ -1527,7 +1622,13 @@ requests = ">=2.14.2" WebOb = ">=1.7.1" [package.extras] -oslo-config = ["oslo.config (>=5.2.0)"] +elasticsearch = ["elasticsearch (>=2.0.0,<3.0.0)"] +jaeger = ["jaeger-client (>=3.8.0)"] +messaging = ["oslo.messaging (>=14.1.0)"] +mongo = ["pymongo (>=3.0.2,!=3.1)"] +otlp = ["opentelemetry-exporter-otlp (>=1.16.0)", "opentelemetry-sdk (>=1.16.0)"] +redis = ["redis (>=2.10.0)"] +sqlalchemy = ["SQLAlchemy (>=1.4.0)"] test = ["bandit (>=1.6.0,<1.7.0)", "coverage (>=4.0)", "ddt (>=1.0.1)", "docutils (>=0.14)", "elasticsearch (>=2.0.0,<3.0.0)", "flake8-import-order (==0.18.1)", "hacking (>=3.1.0,<3.2.0)", "jaeger-client (>=3.8.0)", "opentelemetry-exporter-otlp (>=1.16.0)", "opentelemetry-sdk (>=1.16.0)", "pre-commit (>=2.6.0)", "pymongo (>=3.0.2,!=3.1)", "redis (>=2.10.0)", "stestr (>=2.0.0)", "testtools (>=2.2.0)"] [[package]] @@ -1577,13 +1678,13 @@ testing = ["Paste", "pytest", "pytest-cov"] [[package]] name = "pbr" -version = "6.0.0" +version = "6.1.0" description = "Python Build Reasonableness" optional = false python-versions = ">=2.6" files = [ - {file = "pbr-6.0.0-py2.py3-none-any.whl", hash = "sha256:4a7317d5e3b17a3dccb6a8cfe67dab65b20551404c52c8ed41279fa4f0cb4cda"}, - {file = "pbr-6.0.0.tar.gz", hash = "sha256:d1377122a5a00e2f940ee482999518efe16d745d423a670c27773dfbc3c9a7d9"}, + {file = "pbr-6.1.0-py2.py3-none-any.whl", hash = "sha256:a776ae228892d8013649c0aeccbb3d5f99ee15e005a4cbb7e61d55a067b28a2a"}, + {file = "pbr-6.1.0.tar.gz", hash = "sha256:788183e382e3d1d7707db08978239965e8b9e4e5ed42669bf4758186734d5f24"}, ] [[package]] @@ -1603,6 +1704,17 @@ Mako = ">=0.4.0" setuptools = "*" WebOb = ">=1.8" +[[package]] +name = "pkgutil-resolve-name" +version = "1.3.10" +description = "Resolve a name to an object." +optional = false +python-versions = ">=3.6" +files = [ + {file = "pkgutil_resolve_name-1.3.10-py3-none-any.whl", hash = "sha256:ca27cc078d25c5ad71a9de0a7a330146c4e014c2462d9af19c6b828280649c5e"}, + {file = "pkgutil_resolve_name-1.3.10.tar.gz", hash = "sha256:357d6c9e6a755653cfd78893817c0853af365dd51ec97f3d358a819373bbd174"}, +] + [[package]] name = "platformdirs" version = "4.2.2" @@ -1751,15 +1863,33 @@ dev = ["coverage[toml] (==5.0.4)", "cryptography (>=3.4.0)", "pre-commit", "pyte docs = ["sphinx", "sphinx-rtd-theme", "zope.interface"] tests = ["coverage[toml] (==5.0.4)", "pytest (>=6.0.0,<7.0.0)"] +[[package]] +name = "pyopenssl" +version = "24.2.1" +description = "Python wrapper module around the OpenSSL library" +optional = false +python-versions = ">=3.7" +files = [ + {file = "pyOpenSSL-24.2.1-py3-none-any.whl", hash = "sha256:967d5719b12b243588573f39b0c677637145c7a1ffedcd495a487e58177fbb8d"}, + {file = "pyopenssl-24.2.1.tar.gz", hash = "sha256:4247f0dbe3748d560dcbb2ff3ea01af0f9a1a001ef5f7c4c647956ed8cbf0e95"}, +] + +[package.dependencies] +cryptography = ">=41.0.5,<44" + +[package.extras] +docs = ["sphinx (!=5.2.0,!=5.2.0.post0,!=7.2.5)", "sphinx-rtd-theme"] +test = ["pretend", "pytest (>=3.0.1)", "pytest-rerunfailures"] + [[package]] name = "pyparsing" -version = "3.1.2" +version = "3.1.4" description = "pyparsing module - Classes and methods to define and execute parsing grammars" optional = false python-versions = ">=3.6.8" files = [ - {file = "pyparsing-3.1.2-py3-none-any.whl", hash = "sha256:f9db75911801ed778fe61bb643079ff86601aca99fcae6345aa67292038fb742"}, - {file = "pyparsing-3.1.2.tar.gz", hash = "sha256:a1bac0ce561155ecc3ed78ca94d3c9378656ad4c94c1270de543f621420f94ad"}, + {file = "pyparsing-3.1.4-py3-none-any.whl", hash = "sha256:a6a7ee4235a3f944aa1fa2249307708f893fe5717dc603503c6c7969c070fb7c"}, + {file = "pyparsing-3.1.4.tar.gz", hash = "sha256:f86ec8d1a83f11977c9a6ea7598e8c27fc5cddfa5b07ea2241edbbde1d7bc032"}, ] [package.extras] @@ -1778,13 +1908,35 @@ files = [ [package.dependencies] colorama = {version = "*", markers = "sys_platform == \"win32\""} +exceptiongroup = {version = ">=1.0.0rc8", markers = "python_version < \"3.11\""} iniconfig = "*" packaging = "*" pluggy = ">=1.5,<2" +tomli = {version = ">=1", markers = "python_version < \"3.11\""} [package.extras] dev = ["argcomplete", "attrs (>=19.2)", "hypothesis (>=3.56)", "mock", "pygments (>=2.7.2)", "requests", "setuptools", "xmlschema"] +[[package]] +name = "python-cinderclient" +version = "9.5.0" +description = "OpenStack Block Storage API Client Library" +optional = false +python-versions = ">=3.8" +files = [ + {file = "python-cinderclient-9.5.0.tar.gz", hash = "sha256:1b9d717aff93cad420045fb6c52f6376ab72f085f8193130892020ec46c93555"}, + {file = "python_cinderclient-9.5.0-py3-none-any.whl", hash = "sha256:b2ee2681c1f9785957f89be10e7e41fee130729b5c6b2f7c5fa6b542fb27eaaa"}, +] + +[package.dependencies] +keystoneauth1 = ">=5.0.0" +"oslo.i18n" = ">=5.0.1" +"oslo.utils" = ">=4.8.0" +pbr = ">=5.5.0" +PrettyTable = ">=0.7.2" +requests = ">=2.25.1" +stevedore = ">=3.3.0" + [[package]] name = "python-dateutil" version = "2.9.0.post0" @@ -1799,15 +1951,37 @@ files = [ [package.dependencies] six = ">=1.5" +[[package]] +name = "python-glanceclient" +version = "4.7.0" +description = "OpenStack Image API Client Library" +optional = false +python-versions = ">=3.8" +files = [ + {file = "python-glanceclient-4.7.0.tar.gz", hash = "sha256:c19452ef12da3c484b69d22a888ce7a74910bdb8783bbe91248c60efa5378810"}, + {file = "python_glanceclient-4.7.0-py3-none-any.whl", hash = "sha256:b8d32e5c5d488d02a8d89a2017cfe9c008244429620e49563d3b9aca8be2f3e8"}, +] + +[package.dependencies] +keystoneauth1 = ">=3.6.2" +"oslo.i18n" = ">=3.15.3" +"oslo.utils" = ">=3.33.0" +pbr = ">=2.0.0,<2.1.0 || >2.1.0" +PrettyTable = ">=0.7.1" +pyOpenSSL = ">=17.1.0" +requests = ">=2.14.2" +warlock = ">=1.2.0" +wrapt = ">=1.7.0" + [[package]] name = "python-keystoneclient" -version = "5.4.0" +version = "5.5.0" description = "Client Library for OpenStack Identity" optional = false python-versions = ">=3.8" files = [ - {file = "python-keystoneclient-5.4.0.tar.gz", hash = "sha256:b2b4bdbe9daf7b0b353b8807672eeed01f87dd03b4f8b42d0d061b09b8931f41"}, - {file = "python_keystoneclient-5.4.0-py3-none-any.whl", hash = "sha256:9918043849032f387a0000104c553aac5ace02918a6b7afcdb99690164029867"}, + {file = "python-keystoneclient-5.5.0.tar.gz", hash = "sha256:c2f5934f95576936c98e45bf599ad48bcb0ac451593e5f8344ebf52cb0f411f5"}, + {file = "python_keystoneclient-5.5.0-py3-none-any.whl", hash = "sha256:52fe7eb35c7345387c2488eb0b95f28a1d73edcad1ac3d8d80cf8ce6a7c9a8ee"}, ] [package.dependencies] @@ -1815,10 +1989,10 @@ debtcollector = ">=1.2.0" keystoneauth1 = ">=3.4.0" "oslo.config" = ">=5.2.0" "oslo.i18n" = ">=3.15.3" -"oslo.serialization" = ">=2.18.0,<2.19.1 || >2.19.1" +"oslo.serialization" = ">=2.18.0" "oslo.utils" = ">=3.33.0" packaging = ">=20.4" -pbr = ">=2.0.0,<2.1.0 || >2.1.0" +pbr = ">=2.0.0" requests = ">=2.14.2" stevedore = ">=1.20.0" @@ -2104,19 +2278,23 @@ files = [ [[package]] name = "setuptools" -version = "73.0.1" +version = "74.0.0" description = "Easily download, build, install, upgrade, and uninstall Python packages" optional = false python-versions = ">=3.8" files = [ - {file = "setuptools-73.0.1-py3-none-any.whl", hash = "sha256:b208925fcb9f7af924ed2dc04708ea89791e24bde0d3020b27df0e116088b34e"}, - {file = "setuptools-73.0.1.tar.gz", hash = "sha256:d59a3e788ab7e012ab2c4baed1b376da6366883ee20d7a5fc426816e3d7b1193"}, + {file = "setuptools-74.0.0-py3-none-any.whl", hash = "sha256:0274581a0037b638b9fc1c6883cc71c0210865aaa76073f7882376b641b84e8f"}, + {file = "setuptools-74.0.0.tar.gz", hash = "sha256:a85e96b8be2b906f3e3e789adec6a9323abf79758ecfa3065bd740d81158b11e"}, ] [package.extras] +check = ["pytest-checkdocs (>=2.4)", "pytest-ruff (>=0.2.1)", "ruff (>=0.5.2)"] core = ["importlib-metadata (>=6)", "importlib-resources (>=5.10.2)", "jaraco.text (>=3.7)", "more-itertools (>=8.8)", "packaging (>=24)", "platformdirs (>=2.6.2)", "tomli (>=2.0.1)", "wheel (>=0.43.0)"] +cover = ["pytest-cov"] doc = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "pygments-github-lexers (==0.0.5)", "pyproject-hooks (!=1.1)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-favicon", "sphinx-inline-tabs", "sphinx-lint", "sphinx-notfound-page (>=1,<2)", "sphinx-reredirects", "sphinxcontrib-towncrier", "towncrier (<24.7)"] -test = ["build[virtualenv] (>=1.0.3)", "filelock (>=3.4.0)", "importlib-metadata", "ini2toml[lite] (>=0.14)", "jaraco.develop (>=7.21)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "jaraco.test", "mypy (==1.11.*)", "packaging (>=23.2)", "pip (>=19.1)", "pyproject-hooks (!=1.1)", "pytest (>=6,!=8.1.*)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=2.2)", "pytest-home (>=0.5)", "pytest-mypy", "pytest-perf", "pytest-ruff (<0.4)", "pytest-ruff (>=0.2.1)", "pytest-ruff (>=0.3.2)", "pytest-subprocess", "pytest-timeout", "pytest-xdist (>=3)", "tomli", "tomli-w (>=1.0.0)", "virtualenv (>=13.0.0)", "wheel (>=0.44.0)"] +enabler = ["pytest-enabler (>=2.2)"] +test = ["build[virtualenv] (>=1.0.3)", "filelock (>=3.4.0)", "ini2toml[lite] (>=0.14)", "jaraco.develop (>=7.21)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "jaraco.test", "packaging (>=23.2)", "pip (>=19.1)", "pyproject-hooks (!=1.1)", "pytest (>=6,!=8.1.*)", "pytest-home (>=0.5)", "pytest-perf", "pytest-subprocess", "pytest-timeout", "pytest-xdist (>=3)", "tomli-w (>=1.0.0)", "virtualenv (>=13.0.0)", "wheel (>=0.44.0)"] +type = ["importlib-metadata (>=7.0.2)", "jaraco.develop (>=7.21)", "mypy (==1.11.*)", "pytest-mypy"] [[package]] name = "six" @@ -2229,27 +2407,27 @@ files = [ [[package]] name = "stevedore" -version = "5.2.0" +version = "5.3.0" description = "Manage dynamic plugins for Python applications" optional = false python-versions = ">=3.8" files = [ - {file = "stevedore-5.2.0-py3-none-any.whl", hash = "sha256:1c15d95766ca0569cad14cb6272d4d31dae66b011a929d7c18219c176ea1b5c9"}, - {file = "stevedore-5.2.0.tar.gz", hash = "sha256:46b93ca40e1114cea93d738a6c1e365396981bb6bb78c27045b7587c9473544d"}, + {file = "stevedore-5.3.0-py3-none-any.whl", hash = "sha256:1efd34ca08f474dad08d9b19e934a22c68bb6fe416926479ba29e5013bcc8f78"}, + {file = "stevedore-5.3.0.tar.gz", hash = "sha256:9a64265f4060312828151c204efbe9b7a9852a0d9228756344dbc7e4023e375a"}, ] [package.dependencies] -pbr = ">=2.0.0,<2.1.0 || >2.1.0" +pbr = ">=2.0.0" [[package]] name = "sushy" -version = "5.1.1" +version = "5.2.0" description = "Sushy is a small Python library to communicate with Redfish based systems" optional = false python-versions = ">=3.8" files = [ - {file = "sushy-5.1.1-py3-none-any.whl", hash = "sha256:44876009e648b0ab43679b50a4a56de71dc574912ad2e378cd03de62249e839e"}, - {file = "sushy-5.1.1.tar.gz", hash = "sha256:2a8335f18b03ce44d2be4af83ddaed770b94884239d5d18abc7cbb3347e27bae"}, + {file = "sushy-5.2.0-py3-none-any.whl", hash = "sha256:503896341615761d81cd95dd5281ee4c8c02932c5048332d0000d2460209b8a0"}, + {file = "sushy-5.2.0.tar.gz", hash = "sha256:d90a696fef42c522892179138f4ceae347d11676efdbe18fdeda0cf81154c1e4"}, ] [package.dependencies] @@ -2324,15 +2502,26 @@ dev = ["ruff (==0.4.8)"] test = ["testresources", "testscenarios"] twisted = ["fixtures", "twisted"] +[[package]] +name = "tomli" +version = "2.0.1" +description = "A lil' TOML parser" +optional = false +python-versions = ">=3.7" +files = [ + {file = "tomli-2.0.1-py3-none-any.whl", hash = "sha256:939de3e7a6161af0c887ef91b7d41a53e7c5a1ca976325f429cb46ea9bc30ecc"}, + {file = "tomli-2.0.1.tar.gz", hash = "sha256:de526c12914f0c550d15924c62d72abc48d6fe7364aa87328337a31007fe8a4f"}, +] + [[package]] name = "tooz" -version = "6.2.0" +version = "6.3.0" description = "Coordination library for distributed systems." optional = false python-versions = ">=3.8" files = [ - {file = "tooz-6.2.0-py3-none-any.whl", hash = "sha256:cebdc29a59f0151d20c005b539d723e4ee58215dd00b41a74eaa655edcce1258"}, - {file = "tooz-6.2.0.tar.gz", hash = "sha256:90565627ecb8aa793f9fe6eccc178f57cda751eca03dbb2cb31995e9b1e589b5"}, + {file = "tooz-6.3.0-py3-none-any.whl", hash = "sha256:fe798812a4a7fdd1f725da71a1f7b92e2c4ea4a1cc75328449af718a919f1121"}, + {file = "tooz-6.3.0.tar.gz", hash = "sha256:95303f5d6fb96d64c4ab4b80368e8c9198044784b4ff090301da4355add259c9"}, ] [package.dependencies] @@ -2410,15 +2599,30 @@ files = [ [[package]] name = "voluptuous" -version = "0.15.2" +version = "0.14.2" description = "Python data validation library" optional = false -python-versions = ">=3.9" +python-versions = ">=3.8" files = [ - {file = "voluptuous-0.15.2-py3-none-any.whl", hash = "sha256:016348bc7788a9af9520b1764ebd4de0df41fe2138ebe9e06fa036bf86a65566"}, - {file = "voluptuous-0.15.2.tar.gz", hash = "sha256:6ffcab32c4d3230b4d2af3a577c87e1908a714a11f6f95570456b1849b0279aa"}, + {file = "voluptuous-0.14.2-py3-none-any.whl", hash = "sha256:efc1dadc9ae32a30cc622602c1400a17b7bf8ee2770d64f70418144860739c3b"}, + {file = "voluptuous-0.14.2.tar.gz", hash = "sha256:533e36175967a310f1b73170d091232bf881403e4ebe52a9b4ade8404d151f5d"}, ] +[[package]] +name = "warlock" +version = "2.0.1" +description = "Python object model built on JSON schema and JSON patch." +optional = false +python-versions = ">=3.7,<4.0" +files = [ + {file = "warlock-2.0.1-py3-none-any.whl", hash = "sha256:448df959cec31904f686ac8c6b1dfab80f0cdabce3d303be517dd433eeebf012"}, + {file = "warlock-2.0.1.tar.gz", hash = "sha256:99abbf9525b2a77f2cde896d3a9f18a5b4590db063db65e08207694d2e0137fc"}, +] + +[package.dependencies] +jsonpatch = ">=1,<2" +jsonschema = ">=4,<5" + [[package]] name = "wcwidth" version = "0.2.13" @@ -2588,68 +2792,104 @@ test = ["gevent (>=20.6.2)"] [[package]] name = "zeroconf" -version = "0.132.2" +version = "0.133.0" description = "A pure python implementation of multicast DNS service discovery" optional = false python-versions = "<4.0,>=3.8" files = [ - {file = "zeroconf-0.132.2-cp310-cp310-macosx_11_0_x86_64.whl", hash = "sha256:31c8406f62251aa62f5b67d865007ffd1dd929eae9027166ffa6bccca69253bd"}, - {file = "zeroconf-0.132.2-cp310-cp310-manylinux_2_17_i686.manylinux_2_5_i686.manylinux1_i686.manylinux2014_i686.whl", hash = "sha256:d4bc5e43d02e0848c3174914595dfcebed9b74e65cbdfb1011c5082db7916605"}, - {file = "zeroconf-0.132.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:59953e8445e69e5fee53381c437d3494f7fac8d7b51f0169d59b69eba8f95063"}, - {file = "zeroconf-0.132.2-cp310-cp310-manylinux_2_31_x86_64.whl", hash = "sha256:ddae9592604fe04ec065cc53a321844c3592c812988346136d8ee548127f3d12"}, - {file = "zeroconf-0.132.2-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:b20036ab22df2fb663f797b110fa82d4798084fcc56c8a264af50989581062be"}, - {file = "zeroconf-0.132.2-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:82678a77e471dd3b0ad5ed47a4a42474af3150819718eff7e36dca32ae591949"}, - {file = "zeroconf-0.132.2-cp310-cp310-win32.whl", hash = "sha256:390feb3e7fccdffbf66c9bcd895b1db92e501aa2789d6a8b44e6e027ab80ec14"}, - {file = "zeroconf-0.132.2-cp310-cp310-win_amd64.whl", hash = "sha256:779d81aac693e57090343ce5b18f477fec993f969aa87660a33e7ce81880ccdf"}, - {file = "zeroconf-0.132.2-cp311-cp311-macosx_11_0_x86_64.whl", hash = "sha256:76d12185c335c14b04b8706b4dd0badc16f4185caeb635419c84e575cef7c980"}, - {file = "zeroconf-0.132.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:700bae69eb7c45037deef4a729586f32205d391de38802e2ab89151a7a87d1fc"}, - {file = "zeroconf-0.132.2-cp311-cp311-manylinux_2_17_i686.manylinux_2_5_i686.manylinux1_i686.manylinux2014_i686.whl", hash = "sha256:9d364a929121df5b96af53ac62abdd61fa3a931e74c7a4c80204c961c01a8667"}, - {file = "zeroconf-0.132.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e7e2c398679c863e810a9af2c5d14542a32d438e3bf5ba0b9d8e119326c33303"}, - {file = "zeroconf-0.132.2-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:28b1721617ddc9bf3d2ba3e2b96234f7539e1dbdcacaf6e94ec31ff7b5ebe620"}, - {file = "zeroconf-0.132.2-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:f2b26c23efeded0e7fcfd0fb4d638ec4a83d120e1d455267d353090e36479528"}, - {file = "zeroconf-0.132.2-cp311-cp311-win32.whl", hash = "sha256:4754dfba1af63545dfd0ab26c834c907e1dd3f94c8ee190c3041a6444313aaed"}, - {file = "zeroconf-0.132.2-cp311-cp311-win_amd64.whl", hash = "sha256:db8607a32347da1fd4519cfea441d8b36b44df0c53198ae0471c76fc932a86e0"}, - {file = "zeroconf-0.132.2-cp312-cp312-macosx_11_0_x86_64.whl", hash = "sha256:5354c1cf83d36b2d03ee5774923d30fe838f9371963b42ca46ecba45d3507ff4"}, - {file = "zeroconf-0.132.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:48275e3db89a8d90ff983c3f7b0c6eee2ede3c4e5e75eaf2aa571ea8cb956d95"}, - {file = "zeroconf-0.132.2-cp312-cp312-manylinux_2_17_i686.manylinux_2_5_i686.manylinux1_i686.manylinux2014_i686.whl", hash = "sha256:3eb0e57654e139c3ef5b6421053236be4a0add9f0301b01545b11a0552c7c123"}, - {file = "zeroconf-0.132.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b3dd7143dfc37a20f7d1ccf32f916ac78c11d3c8bae61438ee06376b1bc535fc"}, - {file = "zeroconf-0.132.2-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:f9a28b0416a36ec32273ee1ac80cc72ff9b06d1cb15a9481dcd5c92bd2bc8f03"}, - {file = "zeroconf-0.132.2-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:06203c23a82b69aca9e961da675600dff19026bb22b5d042f18f9e0ff1139ed3"}, - {file = "zeroconf-0.132.2-cp312-cp312-win32.whl", hash = "sha256:5c8c2eeb838538fffaa421f9b3f9c671778886595b5aa0d4ef4d000531e721d2"}, - {file = "zeroconf-0.132.2-cp312-cp312-win_amd64.whl", hash = "sha256:a37fe4f302edb8d931a4c386d0944f996e3f54717495636113880c4492ab479f"}, - {file = "zeroconf-0.132.2-cp38-cp38-macosx_11_0_x86_64.whl", hash = "sha256:6732b224be7e69f7c77798e50205f8e92646ab59724151d66d8dc97f92e99a77"}, - {file = "zeroconf-0.132.2-cp38-cp38-manylinux_2_17_i686.manylinux_2_5_i686.manylinux1_i686.manylinux2014_i686.whl", hash = "sha256:3ad2fe0cbfebe20612c9a5390075a2b3a258a78928f5b7b5163be1699cc528f0"}, - {file = "zeroconf-0.132.2-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:56146e66774c30e238088f67be47740ffd4f669c08e76f2e470bd611d7bdae46"}, - {file = "zeroconf-0.132.2-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:4dd7d8fdee36cc6bde0bcb08b79375009de7a76d935d1401b6ae4b62505b9ee0"}, - {file = "zeroconf-0.132.2-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:a49b13ec79edff347b1e7af65f5843719ca151ef071ac6b2ff564bb69d164331"}, - {file = "zeroconf-0.132.2-cp38-cp38-win32.whl", hash = "sha256:ca46637fcc0386fdbe6bde447184ed981499c8c1b5b5fcaa0f35c3b15528162a"}, - {file = "zeroconf-0.132.2-cp38-cp38-win_amd64.whl", hash = "sha256:f56ec955f43f944985f857c9d23030362df52e14a7c53c64bf8b29cfadebd601"}, - {file = "zeroconf-0.132.2-cp39-cp39-macosx_11_0_x86_64.whl", hash = "sha256:5586bc773d6cee4f9a14692f5e6bc6387ddb54b2bfae0db01c0695aac20c420a"}, - {file = "zeroconf-0.132.2-cp39-cp39-manylinux_2_17_i686.manylinux_2_5_i686.manylinux1_i686.manylinux2014_i686.whl", hash = "sha256:1f09b692219abf9b1ca28364d6f4eb283a4c676e30c905933d1694cbd321bc4b"}, - {file = "zeroconf-0.132.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e1031c7c5f8516108e7c24190179e6a522183de218a954681a341ee818f8079a"}, - {file = "zeroconf-0.132.2-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:87b6e92a869932f4aac3076816a1b987c581b01e49a08e495bef7165be049dfd"}, - {file = "zeroconf-0.132.2-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:13beed15eed7e569fd56dbe16c7cb758f81c661d53ec253fbf9cfe7a20e28b7c"}, - {file = "zeroconf-0.132.2-cp39-cp39-win32.whl", hash = "sha256:4e83e18722d0bdc2e603f7ca104adf276d5728a664b9e94c99e2d8c02001429c"}, - {file = "zeroconf-0.132.2-cp39-cp39-win_amd64.whl", hash = "sha256:a2fa3a89f6a0cf03a56141dad158634a009a22fbe645c7c01e85edc12a0a239f"}, - {file = "zeroconf-0.132.2-pp310-pypy310_pp73-macosx_11_0_x86_64.whl", hash = "sha256:1a95025f0949ed0e873e141d482fbbefa223ef90646443e4a1d6d47f50eb89d7"}, - {file = "zeroconf-0.132.2-pp310-pypy310_pp73-manylinux_2_17_i686.manylinux_2_5_i686.manylinux1_i686.manylinux2014_i686.whl", hash = "sha256:1c932b15848ae6b8e4b2b50c65368e396d000fea95acd473611693dbe5a00096"}, - {file = "zeroconf-0.132.2-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9c295b424a271ce5022da83a1274b4cd0f696c5b8e0c190e6a28efde8b36e82d"}, - {file = "zeroconf-0.132.2-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:c50ee0df6b0b06f1dad6261670b5be53c909b9a2b1985bcf65ea5b0d766fd10e"}, - {file = "zeroconf-0.132.2-pp38-pypy38_pp73-macosx_11_0_x86_64.whl", hash = "sha256:5b6cfc2b62e6282eabbcb6c7223b0a8c05ed3a326e7b467d06b85a3eeda1bfc8"}, - {file = "zeroconf-0.132.2-pp38-pypy38_pp73-manylinux_2_17_i686.manylinux_2_5_i686.manylinux1_i686.manylinux2014_i686.whl", hash = "sha256:d6c05af8b49c442422ce49565ab41a094b23e0f5692abe1533428cbe35a78f8e"}, - {file = "zeroconf-0.132.2-pp38-pypy38_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0b0d2ffc4bafbcc4152067bfbc1a67074d23e6100e356424bd985ca8067a2bfd"}, - {file = "zeroconf-0.132.2-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:b60b260c70bb77d7f3b666bdd2a2a74cead5e36814f8b4295778bcdd08f65c7e"}, - {file = "zeroconf-0.132.2-pp39-pypy39_pp73-macosx_11_0_x86_64.whl", hash = "sha256:9228c512334905338f65825102e47778e5ce034bb4249c3deb22991826ed061f"}, - {file = "zeroconf-0.132.2-pp39-pypy39_pp73-manylinux_2_17_i686.manylinux_2_5_i686.manylinux1_i686.manylinux2014_i686.whl", hash = "sha256:e36f50a963d149bb7152543db9bdbd73f7997e66b57b7956fc17751f55e59625"}, - {file = "zeroconf-0.132.2-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3bd0cd9435dced8c31491b3ed7c15707acedd11f00451f7fbb57ba3868dd5724"}, - {file = "zeroconf-0.132.2-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:d80bde641349198c8c17684692a8cc40a36a93c0cebd8f1d7c42db7ceeaa17be"}, - {file = "zeroconf-0.132.2.tar.gz", hash = "sha256:9ad8bc6e3f168fe8c164634c762d3265c775643defff10e26273623a12d73ae1"}, + {file = "zeroconf-0.133.0-cp310-cp310-macosx_12_0_x86_64.whl", hash = "sha256:6a0239bc2fd440264b97d3d00120060676493b17591700c50a6d00fd8dbf6e10"}, + {file = "zeroconf-0.133.0-cp310-cp310-macosx_14_0_arm64.whl", hash = "sha256:7fce1bdd16530d7de7d1197fd4f6f2150b552c3b2ef947d08dbb7476fa3506dc"}, + {file = "zeroconf-0.133.0-cp310-cp310-manylinux_2_17_i686.manylinux_2_5_i686.manylinux1_i686.manylinux2014_i686.whl", hash = "sha256:aa2d29c6c743db3d5056c9c016914fa561099669f44cda441d1081f274be6de2"}, + {file = "zeroconf-0.133.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:073028e09fee39c74c342f6367a7c9c34eb7c26a03c9d93b366b5e2f7b04ea6c"}, + {file = "zeroconf-0.133.0-cp310-cp310-manylinux_2_31_x86_64.whl", hash = "sha256:36acdee76831aedf40d9ae09e57b8b3d9fc452ff17bb98f9d22a163dfa704200"}, + {file = "zeroconf-0.133.0-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:fe71c44532af06b09a2cacb91447f86e701702817d245553d41bfbdca908550f"}, + {file = "zeroconf-0.133.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:5d120222d363cf3a9fcc0fedaf734571e99e73531559af3c3186aa6794aa7570"}, + {file = "zeroconf-0.133.0-cp310-cp310-win32.whl", hash = "sha256:f34423bea75d770631b708ee2868d31ed44e3f7aca395dc14c66118b2bf15e34"}, + {file = "zeroconf-0.133.0-cp310-cp310-win_amd64.whl", hash = "sha256:685e90d64ec1471b32495b94000657fb1ac3495df2571237a0bb45c0ce6b1829"}, + {file = "zeroconf-0.133.0-cp311-cp311-macosx_12_0_x86_64.whl", hash = "sha256:beec5ec1faf6cc014fc74e1fd8608ac5fa4b36422dea9e5e4246db3c39021c6d"}, + {file = "zeroconf-0.133.0-cp311-cp311-macosx_14_0_arm64.whl", hash = "sha256:4ff13025b6aaa476a84c009ad9f23e960f375d4b8ed0ffb57d657dc10135da34"}, + {file = "zeroconf-0.133.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4563dccc320d36bbb41764624f32077b26f65088234a934678c20351a2a9637c"}, + {file = "zeroconf-0.133.0-cp311-cp311-manylinux_2_17_i686.manylinux_2_5_i686.manylinux1_i686.manylinux2014_i686.whl", hash = "sha256:b11099f1c60c34086abcd2bd61359008be71cfb69e69074d76f05f413294ff3e"}, + {file = "zeroconf-0.133.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:78025ae5caed6ee1606a47b3493c58db7b30038d5a2e5572f409d088f9c1e7e2"}, + {file = "zeroconf-0.133.0-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:ff4b603e7243049e9e7b34b1a8479091d98e576d334199b1db5ff3b6777b700b"}, + {file = "zeroconf-0.133.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:1298d845163952fe3692cb3e5febaa278427ccab00df4a2c92b83ef5219dd013"}, + {file = "zeroconf-0.133.0-cp311-cp311-win32.whl", hash = "sha256:0dc54a1b4f284687f33175f9fda7a639ae2db8630bb70426997a34931bfeae0d"}, + {file = "zeroconf-0.133.0-cp311-cp311-win_amd64.whl", hash = "sha256:038530c8215d36a4a45e6a98382f00b30af2833b007865494fee46a208cd5bf2"}, + {file = "zeroconf-0.133.0-cp312-cp312-macosx_12_0_x86_64.whl", hash = "sha256:e8a57617ac9b973d64f2dadbc53beeb1c1d81403435ca7a0619e01a9d4f83e28"}, + {file = "zeroconf-0.133.0-cp312-cp312-macosx_14_0_arm64.whl", hash = "sha256:92c05af80c764a4380651c0c2947720ee5a3c4ada3529c54d3acfa5a25c54812"}, + {file = "zeroconf-0.133.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c0ef28cb0253c39faa98d8b265516bd3ee0fb6621298b878a678a85198c95639"}, + {file = "zeroconf-0.133.0-cp312-cp312-manylinux_2_17_i686.manylinux_2_5_i686.manylinux1_i686.manylinux2014_i686.whl", hash = "sha256:1b243754410f693542d0d7dce0ec8731f189cf76d883c82fe614c4255f92a12f"}, + {file = "zeroconf-0.133.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:83421aab6ef36c97215135594b52d82913f3a573ceb89cead010fee2c8d1f04e"}, + {file = "zeroconf-0.133.0-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:fb52f31874af53b029b1ba0a98a9cdcd7b80be554bc6ae8de3fc0c73b67d3972"}, + {file = "zeroconf-0.133.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:e921bce78935676f8a693bd5c361d25db378d3122b5fe8f41f3ae0d7ad1eff9b"}, + {file = "zeroconf-0.133.0-cp312-cp312-win32.whl", hash = "sha256:befcb059885ae152bedad34a56ca9e2aa48724ac1c366af01417d9830eb2d2fe"}, + {file = "zeroconf-0.133.0-cp312-cp312-win_amd64.whl", hash = "sha256:686626df48798926c9ad229675cc737eba680913a7b9225fb88e8ce224c766a4"}, + {file = "zeroconf-0.133.0-cp313-cp313-macosx_12_0_x86_64.whl", hash = "sha256:0bd29d2c269d9bf8e3c4b9debbb68ffbe14ecbc6e072c9ff3cae21694660e83d"}, + {file = "zeroconf-0.133.0-cp313-cp313-macosx_14_0_arm64.whl", hash = "sha256:a9f001b896c190d75c01ea7042e1add4d3c271fb4e634db32fb623cd4c52dc6e"}, + {file = "zeroconf-0.133.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:dcb526a07ecd26630c8a6a3a0c4ab79d2892400840b9aa8af7b2dbf6252cada6"}, + {file = "zeroconf-0.133.0-cp313-cp313-manylinux_2_17_i686.manylinux_2_5_i686.manylinux1_i686.manylinux2014_i686.whl", hash = "sha256:811fb55e5b5a643556242ecbf26d6fd317a1b0517af6a09f8215cfa3b1676f4f"}, + {file = "zeroconf-0.133.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a7705f9b678cd33f8c3f9bfe59e25ddff090d0c91ea00b7133d25116304fb613"}, + {file = "zeroconf-0.133.0-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:02b14e9b3f6c432475ec85e2fa54b9b1161d400d455f245160ace8a08f83086e"}, + {file = "zeroconf-0.133.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:a912515d3025140f7e3a6bcfd7fbb25477d531e216abcd662089dbfef0f6bdd1"}, + {file = "zeroconf-0.133.0-cp313-cp313-win32.whl", hash = "sha256:ce00adb90ace385560705c61afb4f510c22c5db2a937eaf2af1f0d55a91551ac"}, + {file = "zeroconf-0.133.0-cp313-cp313-win_amd64.whl", hash = "sha256:127326682a358fd91b9ac8e02c050aabd6bd191b71247c5f014c8dfd1e4fb9dc"}, + {file = "zeroconf-0.133.0-cp38-cp38-macosx_12_0_x86_64.whl", hash = "sha256:c49eb0f4d0c3da762147234537ce0c48cea68848e0d7c55cfd9aeaf8d2c19623"}, + {file = "zeroconf-0.133.0-cp38-cp38-manylinux_2_17_i686.manylinux_2_5_i686.manylinux1_i686.manylinux2014_i686.whl", hash = "sha256:19de0328ad3ca1629b670f9d3354088045c6c934572470178be2b193da0fbdcd"}, + {file = "zeroconf-0.133.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ecd3957d61e9a44d630cb54ca0e62902326154e53a8846f85739d07667765148"}, + {file = "zeroconf-0.133.0-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:3caaa3e1dd600594b175f37408e8bb5812729045c45235008775d3703268602b"}, + {file = "zeroconf-0.133.0-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:b8182255b49fff1a5ffd454f4b21b4d5bda9903f08b01b75e0f95d51cab6eba1"}, + {file = "zeroconf-0.133.0-cp38-cp38-win32.whl", hash = "sha256:576ad6c32b6e747f493021c02daf823367261f4b7d3391fef6c7e6936606821b"}, + {file = "zeroconf-0.133.0-cp38-cp38-win_amd64.whl", hash = "sha256:2c90092c8727ef29a57c59f6db1309d7e3de49879c21c1d67e03ff8ee8048973"}, + {file = "zeroconf-0.133.0-cp39-cp39-macosx_12_0_x86_64.whl", hash = "sha256:2594802113aed1fc7d5c3fb3fb92fa48c04b78a8ea24f68cb29030bd7dc62dc5"}, + {file = "zeroconf-0.133.0-cp39-cp39-macosx_14_0_arm64.whl", hash = "sha256:97d2fea9a70d3df918d6c6d38a3739254f6d093254d70ffdbf73f435e9ef65ba"}, + {file = "zeroconf-0.133.0-cp39-cp39-manylinux_2_17_i686.manylinux_2_5_i686.manylinux1_i686.manylinux2014_i686.whl", hash = "sha256:6d57052ac4eb28d0f8a63ce7adcf176e1db527ee383991f536aa4fa95b5f6066"}, + {file = "zeroconf-0.133.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b720ae968872f7ecc15bde1de0efd2b3657240f7842c349ba19c44210d5314d7"}, + {file = "zeroconf-0.133.0-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:c9f3ac428aa2f56c7d57149f3009d97071ef055680af9b113dab21e536ee8b69"}, + {file = "zeroconf-0.133.0-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:a0e9fe6439cb45d4e00b451ff1384a86be37f8d81f32a2d6de0b911a0948de36"}, + {file = "zeroconf-0.133.0-cp39-cp39-win32.whl", hash = "sha256:4a5c8b46084d7543ff671ff498a4e033eefd811608b3a5c341c09d061f825a77"}, + {file = "zeroconf-0.133.0-cp39-cp39-win_amd64.whl", hash = "sha256:5fb19173d8f41305d2f784ed1d262cb5e1fd994decaa89ede092cd10b4cd65c0"}, + {file = "zeroconf-0.133.0-pp310-pypy310_pp73-macosx_12_0_x86_64.whl", hash = "sha256:fdfa54b134b053a0700623fe064b207eab2534f29f6d9c21a6374f02a6918bc0"}, + {file = "zeroconf-0.133.0-pp310-pypy310_pp73-macosx_14_0_arm64.whl", hash = "sha256:5cba6264e7dc40d5fe39f4513f4bbc6bda38232c15bca433b5608e67b33d5918"}, + {file = "zeroconf-0.133.0-pp310-pypy310_pp73-manylinux_2_17_i686.manylinux_2_5_i686.manylinux1_i686.manylinux2014_i686.whl", hash = "sha256:55826ca3b76f24cf1a5d9f520abea28059a921c636e473f06cc090179c4e748d"}, + {file = "zeroconf-0.133.0-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:38e847572ee08b0f3ad92a26a102e9c457ce6f51b2c89eb1db5ac12a440db631"}, + {file = "zeroconf-0.133.0-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:35c8a6c2547c6905ee283d22d35ee72dce60ad02d6f5c19b93bef5b8f14f3004"}, + {file = "zeroconf-0.133.0-pp38-pypy38_pp73-macosx_12_0_x86_64.whl", hash = "sha256:dccec0292f88307a7f150656ecdc6bb11569d2142b5a4c35f361ff706a7e707f"}, + {file = "zeroconf-0.133.0-pp38-pypy38_pp73-macosx_14_0_arm64.whl", hash = "sha256:eff1ae3ae62b12134aafbd7b5b6f15aca6c1e7f1413777bd89468823f2f58be2"}, + {file = "zeroconf-0.133.0-pp38-pypy38_pp73-manylinux_2_17_i686.manylinux_2_5_i686.manylinux1_i686.manylinux2014_i686.whl", hash = "sha256:c1699707618349d788bfa1017195fbec11a0604b2d043bb0cd6e80e7aaa1794b"}, + {file = "zeroconf-0.133.0-pp38-pypy38_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:29e5d7352c015ade5a0c56dfb665280ec501f59c27f4391055e9378209a66fd1"}, + {file = "zeroconf-0.133.0-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:f2871c4d8bb38c6f809ea7aa06678a2e1e94712b494ba74490287fe06b313516"}, + {file = "zeroconf-0.133.0-pp39-pypy39_pp73-macosx_12_0_x86_64.whl", hash = "sha256:73625ad082e5fa3f106d6114cc0162107f8c4018f155711ed334e242a53260dd"}, + {file = "zeroconf-0.133.0-pp39-pypy39_pp73-macosx_14_0_arm64.whl", hash = "sha256:9ef7672413f3c037971541ae8be7b1cf015fabf98a2fdb34be3c6109705f9e41"}, + {file = "zeroconf-0.133.0-pp39-pypy39_pp73-manylinux_2_17_i686.manylinux_2_5_i686.manylinux1_i686.manylinux2014_i686.whl", hash = "sha256:cd4eb5ea118994ffd61f39e9fff917797ad6a5a83493703c7e85bb5ca8de237b"}, + {file = "zeroconf-0.133.0-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:951cd26ed47d768bfba070a2da91c814f95b6962fe681595f062dd6470999e01"}, + {file = "zeroconf-0.133.0-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:561ae1de25ef27ec36062b9943036668c7a095884dad1309080015004bd0e54a"}, + {file = "zeroconf-0.133.0.tar.gz", hash = "sha256:0bd9dec747284c55a58e98733b90ce0c4434f0e24a4f46cf7c22341f80aab212"}, ] [package.dependencies] +async-timeout = {version = ">=3.0.0", markers = "python_version < \"3.11\""} ifaddr = ">=0.1.7" +[[package]] +name = "zipp" +version = "3.20.1" +description = "Backport of pathlib-compatible object wrapper for zip files" +optional = false +python-versions = ">=3.8" +files = [ + {file = "zipp-3.20.1-py3-none-any.whl", hash = "sha256:9960cd8967c8f85a56f920d5d507274e74f9ff813a0ab8889a5b5be2daf44064"}, + {file = "zipp-3.20.1.tar.gz", hash = "sha256:c22b14cc4763c5a5b04134207736c107db42e9d3ef2d9779d465f5f1bcba572b"}, +] + +[package.extras] +check = ["pytest-checkdocs (>=2.4)", "pytest-ruff (>=0.2.1)"] +cover = ["pytest-cov"] +doc = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-lint"] +enabler = ["pytest-enabler (>=2.2)"] +test = ["big-O", "importlib-resources", "jaraco.functools", "jaraco.itertools", "jaraco.test", "more-itertools", "pytest (>=6,!=8.1.*)", "pytest-ignore-flaky"] +type = ["pytest-mypy"] + [metadata] lock-version = "2.0" -python-versions = "^3.11" -content-hash = "5abb2d92bb5c73d1b4ff413213884650d95d1af3713a20eeb8b57dce0e0193bb" +python-versions = "^3.8" +content-hash = "f889f05f48bf03a5701d4bc80bd0b81c71ea86c1c407cad0ac0c1ac2d1f78568" From 25427beee82352a16d6365e6e1da08db3102a96d Mon Sep 17 00:00:00 2001 From: Marek Skrobacki Date: Wed, 28 Aug 2024 14:27:33 +0100 Subject: [PATCH 08/14] add out-of-band inspection for flavors --- .../redfish_inspect_understack.py | 181 ++++++++++++++++++ python/ironic-understack/pyproject.toml | 4 + 2 files changed, 185 insertions(+) create mode 100644 python/ironic-understack/ironic_understack/redfish_inspect_understack.py diff --git a/python/ironic-understack/ironic_understack/redfish_inspect_understack.py b/python/ironic-understack/ironic_understack/redfish_inspect_understack.py new file mode 100644 index 00000000..cced12ac --- /dev/null +++ b/python/ironic-understack/ironic_understack/redfish_inspect_understack.py @@ -0,0 +1,181 @@ +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. +""" +Redfish Inspect Interface modified for Understack +""" + +from oslo_utils import units +from ironic.drivers.drac import IDRACHardware +from ironic.drivers.modules.drac.inspect import DracRedfishInspect +from ironic.drivers.modules.inspect_utils import get_inspection_data +from ironic.drivers.modules.redfish import utils as redfish_utils +from ironic.drivers.modules.redfish.inspect import RedfishInspect +from ironic_understack.machine import Machine +from ironic_understack.flavor_spec import FlavorSpec +from ironic_understack.matcher import Matcher +from oslo_log import log + +LOG = log.getLogger(__name__) + +# temporary until we have a code automatically loading these files +FLAVORS = [ + FlavorSpec( + name="gp2.tiny", + memory_gb=32, + cpu_cores=8, + cpu_models=["AMD EPYC 9124 16-Core Processor"], + drives=[200, 200], + devices=["PowerEdge R7515", "PowerEdge R7615", "PowerEdge R740xd"], + ), + FlavorSpec( + name="gp2.small", + memory_gb=192, + cpu_cores=16, + cpu_models=["AMD EPYC 9124 16-Core Processor"], + drives=[960, 960], + devices=["PowerEdge R7515", "PowerEdge R7615", "PowerEdge R740xd"], + ), + FlavorSpec( + name="gp2.medium", + memory_gb=384, + cpu_cores=24, + cpu_models=["AMD EPYC 9254 24-Core Processor"], + drives=[960, 960], + devices=["PowerEdge R7515", "PowerEdge R7615"], + ), + FlavorSpec( + name="gp2.large", + memory_gb=768, + cpu_cores=48, + cpu_models=["AMD EPYC 9454 48-Core Processor"], + drives=[960, 960], + devices=["PowerEdge R7615"], + ), +] + + +class UnderstackRedfishInspect(RedfishInspect): + def __init__(self, *args, **kwargs) -> None: + super(UnderstackRedfishInspect, self).__init__(*args, **kwargs) + + + def inspect_hardware(self, task): + """Inspect hardware to get the hardware properties. + + Inspects hardware to get the essential properties. + It fails if any of the essential properties + are not received from the node. + + :param task: a TaskManager instance. + :raises: HardwareInspectionFailure if essential properties + could not be retrieved successfully. + :returns: The resulting state of inspection. + + """ + upstream_state = super().inspect_hardware(task) + properties = task.node.properties + + if not properties["memory_mb"]: + LOG.debug("No memory_mb property detected, skipping flavor setting.") + return upstream_state + + if not properties["disks"]: + LOG.debug("No disks detected, skipping flavor setting.") + return upstream_state + + if not properties["cpus"]: + LOG.debug("No cpus detected, skipping flavor setting.") + return upstream_state + + smallest_disk = min([disk["size"] for disk in properties["disks"]]) + machine = Machine( + memory_mb=properties["memory_mb"], + disk_gb=smallest_disk, + cpu=properties["cpus"][0]["model_name"], + ) + + matcher = Matcher(FLAVORS) + best_flavor = matcher.pick_best_flavor(machine) + if not best_flavor: + LOG.warn(f"No flavor matched for {task.node.uuid}") + return upstream_state + else: + # TODO: actually set the class + LOG.info(f"Matched {task.node.uuid} to flavor {best_flavor} ") + return upstream_state + +class UnderstackDracRedfishInspect(DracRedfishInspect): + + def __init__(self, *args, **kwargs) -> None: + super(UnderstackDracRedfishInspect, self).__init__(*args, **kwargs) + patched_ifaces = IDRACHardware().supported_inspect_interfaces + patched_ifaces.append(UnderstackDracRedfishInspect) + setattr(IDRACHardware, "supported_inspect_interfaces", property(lambda _: patched_ifaces)) + + + def inspect_hardware(self, task): + """Inspect hardware to get the hardware properties. + + Inspects hardware to get the essential properties. + It fails if any of the essential properties + are not received from the node. + + :param task: a TaskManager instance. + :raises: HardwareInspectionFailure if essential properties + could not be retrieved successfully. + :returns: The resulting state of inspection. + + """ + upstream_state = super().inspect_hardware(task) + # properties = task.node.inventory + + inspection_data = get_inspection_data(task.node, task.context) + + properties = inspection_data or {} + if not properties: + LOG.warn(f"No inventory found for node {task.node}") + + properties = properties["inventory"] + LOG.debug(f"Retrieved {inspection_data=}") + + if not (properties.get("memory") and "physical_mb" in properties["memory"]): + LOG.warn("No memory_mb property detected, skipping flavor setting.") + return upstream_state + + if not (properties.get("disks") and properties["disks"][0].get("size")): + LOG.warn("No disks detected, skipping flavor setting.") + return upstream_state + + if not (properties.get("cpu") and properties["cpu"]["model_name"]): + LOG.warn("No CPUS detected, skipping flavor setting.") + return upstream_state + + smallest_disk_gb = min([disk["size"] / units.Gi for disk in properties["disks"]]) + machine = Machine( + memory_mb=properties["memory"]["physical_mb"], + disk_gb=smallest_disk_gb, + cpu=properties["cpu"]["model_name"], + ) + + matcher = Matcher(FLAVORS) + best_flavor = matcher.pick_best_flavor(machine) + if not best_flavor: + LOG.warn(f"No flavor matched for {task.node.uuid}") + print(f"No flavor matched for {task.node.uuid}") + return upstream_state + LOG.info(f"Matched {task.node.uuid} to flavor {best_flavor}") + print(f"Matched {task.node.uuid} to flavor {best_flavor}") + + task.node.resource_class = f"baremetal.{best_flavor.name}" + task.node.save() + + return upstream_state diff --git a/python/ironic-understack/pyproject.toml b/python/ironic-understack/pyproject.toml index b5003c00..f75e7b65 100644 --- a/python/ironic-understack/pyproject.toml +++ b/python/ironic-understack/pyproject.toml @@ -23,3 +23,7 @@ build-backend = "poetry.core.masonry.api" [tool.poetry.plugins."ironic.inspection.hooks"] "resource-class" = "ironic_understack.resource_class:UndercloudResourceClassHook" + +[tool.poetry.plugins."ironic.hardware.interfaces.inspect"] +"redfish-understack" = "ironic_understack.redfish_inspect_understack:UnderstackRedfishInspect" +"idrac-redfish-understack" = "ironic_understack.redfish_inspect_understack:UnderstackDracRedfishInspect" From f1b42915ac92ddd2a48844d6a10a681b69ec1b21 Mon Sep 17 00:00:00 2001 From: Marek Skrobacki Date: Wed, 28 Aug 2024 17:29:17 +0100 Subject: [PATCH 09/14] flavors: walk the directories recursively --- .../ironic_understack/flavor_spec.py | 25 ++++++++++--------- .../tests/test_flavor_spec.py | 8 +++--- 2 files changed, 18 insertions(+), 15 deletions(-) diff --git a/python/ironic-understack/ironic_understack/flavor_spec.py b/python/ironic-understack/ironic_understack/flavor_spec.py index 1bba9540..c3939e10 100644 --- a/python/ironic-understack/ironic_understack/flavor_spec.py +++ b/python/ironic-understack/ironic_understack/flavor_spec.py @@ -28,16 +28,17 @@ def from_yaml(yaml_str: str) -> "FlavorSpec": @staticmethod def from_directory(directory: str = "/etc/flavors/") -> list["FlavorSpec"]: flavor_specs = [] - for filename in os.listdir(directory): - if filename.endswith(".yaml") or filename.endswith(".yml"): - filepath = os.path.join(directory, filename) - try: - with open(filepath, "r") as file: - yaml_content = file.read() - flavor_spec = FlavorSpec.from_yaml(yaml_content) - flavor_specs.append(flavor_spec) - except yaml.YAMLError as e: - print(f"Error parsing YAML file {filename}: {e}") - except Exception as e: - print(f"Error processing file {filename}: {e}") + for root, _, files in os.walk(directory): + for filename in files: + if filename.endswith(".yaml") or filename.endswith(".yml"): + filepath = os.path.join(root, filename) + try: + with open(filepath, "r") as file: + yaml_content = file.read() + flavor_spec = FlavorSpec.from_yaml(yaml_content) + flavor_specs.append(flavor_spec) + except yaml.YAMLError as e: + print(f"Error parsing YAML file {filename}: {e}") + except Exception as e: + print(f"Error processing file {filename}: {e}") return flavor_specs diff --git a/python/ironic-understack/ironic_understack/tests/test_flavor_spec.py b/python/ironic-understack/ironic_understack/tests/test_flavor_spec.py index c99a1378..8a3ae058 100644 --- a/python/ironic-understack/ironic_understack/tests/test_flavor_spec.py +++ b/python/ironic-understack/ironic_understack/tests/test_flavor_spec.py @@ -58,10 +58,12 @@ def test_from_yaml_invalid(invalid_yaml): FlavorSpec.from_yaml(invalid_yaml) -@patch("os.listdir") +@patch("os.walk") @patch("builtins.open", new_callable=mock_open) -def test_from_directory(mocked_open, mock_listdir, valid_yaml, invalid_yaml): - mock_listdir.return_value = ["valid.yaml", "invalid.yaml"] +def test_from_directory(mocked_open, mock_walk, valid_yaml, invalid_yaml): + mock_walk.return_value = [ + ("/etc/flavors", [], ["valid.yaml", "invalid.yaml"]), + ] mock_file_handles = [ mock_open(read_data=valid_yaml).return_value, mock_open(read_data=invalid_yaml).return_value, From 57d3d364eeb7be44d50ff51cd171af84e21ef7c6 Mon Sep 17 00:00:00 2001 From: Marek Skrobacki Date: Wed, 28 Aug 2024 17:31:22 +0100 Subject: [PATCH 10/14] switch to loading flavors from a directory --- .../redfish_inspect_understack.py | 64 ++++++------------- .../ironic_understack/resource_class.py | 50 +++------------ 2 files changed, 28 insertions(+), 86 deletions(-) diff --git a/python/ironic-understack/ironic_understack/redfish_inspect_understack.py b/python/ironic-understack/ironic_understack/redfish_inspect_understack.py index cced12ac..371abb3c 100644 --- a/python/ironic-understack/ironic_understack/redfish_inspect_understack.py +++ b/python/ironic-understack/ironic_understack/redfish_inspect_understack.py @@ -13,61 +13,29 @@ Redfish Inspect Interface modified for Understack """ -from oslo_utils import units from ironic.drivers.drac import IDRACHardware from ironic.drivers.modules.drac.inspect import DracRedfishInspect from ironic.drivers.modules.inspect_utils import get_inspection_data -from ironic.drivers.modules.redfish import utils as redfish_utils from ironic.drivers.modules.redfish.inspect import RedfishInspect -from ironic_understack.machine import Machine from ironic_understack.flavor_spec import FlavorSpec +from ironic_understack.machine import Machine from ironic_understack.matcher import Matcher from oslo_log import log +from oslo_utils import units LOG = log.getLogger(__name__) -# temporary until we have a code automatically loading these files -FLAVORS = [ - FlavorSpec( - name="gp2.tiny", - memory_gb=32, - cpu_cores=8, - cpu_models=["AMD EPYC 9124 16-Core Processor"], - drives=[200, 200], - devices=["PowerEdge R7515", "PowerEdge R7615", "PowerEdge R740xd"], - ), - FlavorSpec( - name="gp2.small", - memory_gb=192, - cpu_cores=16, - cpu_models=["AMD EPYC 9124 16-Core Processor"], - drives=[960, 960], - devices=["PowerEdge R7515", "PowerEdge R7615", "PowerEdge R740xd"], - ), - FlavorSpec( - name="gp2.medium", - memory_gb=384, - cpu_cores=24, - cpu_models=["AMD EPYC 9254 24-Core Processor"], - drives=[960, 960], - devices=["PowerEdge R7515", "PowerEdge R7615"], - ), - FlavorSpec( - name="gp2.large", - memory_gb=768, - cpu_cores=48, - cpu_models=["AMD EPYC 9454 48-Core Processor"], - drives=[960, 960], - devices=["PowerEdge R7615"], - ), -] +FLAVORS_SYNC_PATH = ( + "/var/lib/understack/flavors/undercloud-nautobot-device-types.git/flavors" +) +FLAVORS = FlavorSpec.from_directory(FLAVORS_SYNC_PATH) +LOG.info(f"Loaded {len(FLAVORS)} flavor specifications.") class UnderstackRedfishInspect(RedfishInspect): def __init__(self, *args, **kwargs) -> None: super(UnderstackRedfishInspect, self).__init__(*args, **kwargs) - def inspect_hardware(self, task): """Inspect hardware to get the hardware properties. @@ -109,18 +77,22 @@ def inspect_hardware(self, task): LOG.warn(f"No flavor matched for {task.node.uuid}") return upstream_state else: - # TODO: actually set the class LOG.info(f"Matched {task.node.uuid} to flavor {best_flavor} ") + task.node.resource_class = f"baremetal.{best_flavor.name}" + task.node.save() return upstream_state -class UnderstackDracRedfishInspect(DracRedfishInspect): +class UnderstackDracRedfishInspect(DracRedfishInspect): def __init__(self, *args, **kwargs) -> None: super(UnderstackDracRedfishInspect, self).__init__(*args, **kwargs) patched_ifaces = IDRACHardware().supported_inspect_interfaces patched_ifaces.append(UnderstackDracRedfishInspect) - setattr(IDRACHardware, "supported_inspect_interfaces", property(lambda _: patched_ifaces)) - + setattr( + IDRACHardware, + "supported_inspect_interfaces", + property(lambda _: patched_ifaces), + ) def inspect_hardware(self, task): """Inspect hardware to get the hardware properties. @@ -159,7 +131,9 @@ def inspect_hardware(self, task): LOG.warn("No CPUS detected, skipping flavor setting.") return upstream_state - smallest_disk_gb = min([disk["size"] / units.Gi for disk in properties["disks"]]) + smallest_disk_gb = min( + [disk["size"] / units.Gi for disk in properties["disks"]] + ) machine = Machine( memory_mb=properties["memory"]["physical_mb"], disk_gb=smallest_disk_gb, @@ -170,10 +144,8 @@ def inspect_hardware(self, task): best_flavor = matcher.pick_best_flavor(machine) if not best_flavor: LOG.warn(f"No flavor matched for {task.node.uuid}") - print(f"No flavor matched for {task.node.uuid}") return upstream_state LOG.info(f"Matched {task.node.uuid} to flavor {best_flavor}") - print(f"Matched {task.node.uuid} to flavor {best_flavor}") task.node.resource_class = f"baremetal.{best_flavor.name}" task.node.save() diff --git a/python/ironic-understack/ironic_understack/resource_class.py b/python/ironic-understack/ironic_understack/resource_class.py index 08819ccf..de4c925d 100644 --- a/python/ironic-understack/ironic_understack/resource_class.py +++ b/python/ironic-understack/ironic_understack/resource_class.py @@ -1,52 +1,24 @@ # from ironic.drivers.modules.inspector.hooks import base -from ironic_understack.flavor_spec import FlavorSpec from ironic.common import exception from ironic.drivers.modules.inspector.hooks import base +from ironic_understack.flavor_spec import FlavorSpec from ironic_understack.machine import Machine from ironic_understack.matcher import Matcher from oslo_log import log as logging LOG = logging.getLogger(__name__) -# temporary until we have a code automatically loading these files -FLAVORS = [ - FlavorSpec( - name="gp2.tiny", - memory_gb=32, - cpu_cores=8, - cpu_models=["AMD EPYC 9124 16-Core Processor"], - drives=[200, 200], - devices=["PowerEdge R7515", "PowerEdge R7615", "PowerEdge R740xd"], - ), - FlavorSpec( - name="gp2.small", - memory_gb=192, - cpu_cores=16, - cpu_models=["AMD EPYC 9124 16-Core Processor"], - drives=[960, 960], - devices=["PowerEdge R7515", "PowerEdge R7615", "PowerEdge R740xd"], - ), - FlavorSpec( - name="gp2.medium", - memory_gb=384, - cpu_cores=24, - cpu_models=["AMD EPYC 9254 24-Core Processor"], - drives=[960, 960], - devices=["PowerEdge R7515", "PowerEdge R7615"], - ), - FlavorSpec( - name="gp2.large", - memory_gb=768, - cpu_cores=48, - cpu_models=["AMD EPYC 9454 48-Core Processor"], - drives=[960, 960], - devices=["PowerEdge R7615"], - ), -] +FLAVORS_SYNC_PATH = ( + "/var/lib/understack/flavors/undercloud-nautobot-device-types.git/flavors" +) +FLAVORS = FlavorSpec.from_directory(FLAVORS_SYNC_PATH) +LOG.info(f"Loaded {len(FLAVORS)} flavor specifications.") + class NoMatchError(Exception): pass + class UndercloudResourceClassHook(base.InspectionHook): """Hook to set the node's resource_class based on the inventory.""" @@ -78,12 +50,10 @@ def __call__(self, task, inventory, plugin_data): LOG.error(msg) raise exception.InvalidNodeInventory(node=task.node.uuid, reason=msg) except NoMatchError: - msg = ( - f"No matching flavor found for {task.node.uuid}" - ) + msg = f"No matching flavor found for {task.node.uuid}" + LOG.error(msg) def classify(self, machine): - # TODO: read the device types repo later matcher = Matcher(FLAVORS) flavor = matcher.pick_best_flavor(machine) if not flavor: From 0db4919f73deceed341b17fe05b96871e199cad9 Mon Sep 17 00:00:00 2001 From: Marek Skrobacki Date: Thu, 29 Aug 2024 10:28:26 +0100 Subject: [PATCH 11/14] refactor duplicate code to a FlavorInspectMixin Both traditional redfish and idrac rely on the same elements of inventory, so extract the common code and use the inventory everywhere. Prior to this, the redfish driver relied on properties instead, but they were just a copies that also exist in inventory. --- .../redfish_inspect_understack.py | 108 ++++++------------ 1 file changed, 37 insertions(+), 71 deletions(-) diff --git a/python/ironic-understack/ironic_understack/redfish_inspect_understack.py b/python/ironic-understack/ironic_understack/redfish_inspect_understack.py index 371abb3c..7750ec25 100644 --- a/python/ironic-understack/ironic_understack/redfish_inspect_understack.py +++ b/python/ironic-understack/ironic_understack/redfish_inspect_understack.py @@ -17,6 +17,7 @@ from ironic.drivers.modules.drac.inspect import DracRedfishInspect from ironic.drivers.modules.inspect_utils import get_inspection_data from ironic.drivers.modules.redfish.inspect import RedfishInspect +from ironic.drivers.redfish import RedfishHardware from ironic_understack.flavor_spec import FlavorSpec from ironic_understack.machine import Machine from ironic_understack.matcher import Matcher @@ -31,69 +32,13 @@ FLAVORS = FlavorSpec.from_directory(FLAVORS_SYNC_PATH) LOG.info(f"Loaded {len(FLAVORS)} flavor specifications.") - -class UnderstackRedfishInspect(RedfishInspect): - def __init__(self, *args, **kwargs) -> None: - super(UnderstackRedfishInspect, self).__init__(*args, **kwargs) - - def inspect_hardware(self, task): - """Inspect hardware to get the hardware properties. - - Inspects hardware to get the essential properties. - It fails if any of the essential properties - are not received from the node. - - :param task: a TaskManager instance. - :raises: HardwareInspectionFailure if essential properties - could not be retrieved successfully. - :returns: The resulting state of inspection. - - """ - upstream_state = super().inspect_hardware(task) - properties = task.node.properties - - if not properties["memory_mb"]: - LOG.debug("No memory_mb property detected, skipping flavor setting.") - return upstream_state - - if not properties["disks"]: - LOG.debug("No disks detected, skipping flavor setting.") - return upstream_state - - if not properties["cpus"]: - LOG.debug("No cpus detected, skipping flavor setting.") - return upstream_state - - smallest_disk = min([disk["size"] for disk in properties["disks"]]) - machine = Machine( - memory_mb=properties["memory_mb"], - disk_gb=smallest_disk, - cpu=properties["cpus"][0]["model_name"], ) - matcher = Matcher(FLAVORS) - best_flavor = matcher.pick_best_flavor(machine) - if not best_flavor: - LOG.warn(f"No flavor matched for {task.node.uuid}") - return upstream_state - else: - LOG.info(f"Matched {task.node.uuid} to flavor {best_flavor} ") - task.node.resource_class = f"baremetal.{best_flavor.name}" - task.node.save() - return upstream_state -class UnderstackDracRedfishInspect(DracRedfishInspect): - def __init__(self, *args, **kwargs) -> None: - super(UnderstackDracRedfishInspect, self).__init__(*args, **kwargs) - patched_ifaces = IDRACHardware().supported_inspect_interfaces - patched_ifaces.append(UnderstackDracRedfishInspect) - setattr( - IDRACHardware, - "supported_inspect_interfaces", - property(lambda _: patched_ifaces), - ) + +class FlavorInspectMixin: def inspect_hardware(self, task): """Inspect hardware to get the hardware properties. @@ -107,37 +52,34 @@ def inspect_hardware(self, task): :returns: The resulting state of inspection. """ - upstream_state = super().inspect_hardware(task) - # properties = task.node.inventory + upstream_state = super().inspect_hardware(task) # pyright: ignore reportAttributeAccessIssue inspection_data = get_inspection_data(task.node, task.context) - properties = inspection_data or {} - if not properties: + inventory = inspection_data or {} + if not inventory: LOG.warn(f"No inventory found for node {task.node}") - properties = properties["inventory"] + inventory = inventory["inventory"] LOG.debug(f"Retrieved {inspection_data=}") - if not (properties.get("memory") and "physical_mb" in properties["memory"]): + if not (inventory.get("memory") and "physical_mb" in inventory["memory"]): LOG.warn("No memory_mb property detected, skipping flavor setting.") return upstream_state - if not (properties.get("disks") and properties["disks"][0].get("size")): + if not (inventory.get("disks") and inventory["disks"][0].get("size")): LOG.warn("No disks detected, skipping flavor setting.") return upstream_state - if not (properties.get("cpu") and properties["cpu"]["model_name"]): + if not (inventory.get("cpu") and inventory["cpu"]["model_name"]): LOG.warn("No CPUS detected, skipping flavor setting.") return upstream_state - smallest_disk_gb = min( - [disk["size"] / units.Gi for disk in properties["disks"]] - ) + smallest_disk_gb = min([disk["size"] / units.Gi for disk in inventory["disks"]]) machine = Machine( - memory_mb=properties["memory"]["physical_mb"], + memory_mb=inventory["memory"]["physical_mb"], disk_gb=smallest_disk_gb, - cpu=properties["cpu"]["model_name"], + cpu=inventory["cpu"]["model_name"], ) matcher = Matcher(FLAVORS) @@ -151,3 +93,27 @@ def inspect_hardware(self, task): task.node.save() return upstream_state + + +class UnderstackRedfishInspect(FlavorInspectMixin, RedfishInspect): + def __init__(self, *args, **kwargs) -> None: + super().__init__(*args, **kwargs) + patched_ifaces = RedfishHardware().supported_inspect_interfaces + patched_ifaces.append(UnderstackDracRedfishInspect) + setattr( + RedfishHardware, + "supported_inspect_interfaces", + property(lambda _: patched_ifaces), + ) + + +class UnderstackDracRedfishInspect(FlavorInspectMixin, DracRedfishInspect): + def __init__(self, *args, **kwargs) -> None: + super().__init__(*args, **kwargs) + patched_ifaces = IDRACHardware().supported_inspect_interfaces + patched_ifaces.append(UnderstackDracRedfishInspect) + setattr( + IDRACHardware, + "supported_inspect_interfaces", + property(lambda _: patched_ifaces), + ) From 11983b51dbcf97cc9fe4908fb4673ddb04f07d45 Mon Sep 17 00:00:00 2001 From: Marek Skrobacki Date: Thu, 29 Aug 2024 14:22:45 +0100 Subject: [PATCH 12/14] imake FLAVORS_SYNC_PATH configurable --- .../ironic_understack/conf.py | 18 ++++++++++++++++++ .../redfish_inspect_understack.py | 12 ++---------- .../ironic_understack/resource_class.py | 5 +---- 3 files changed, 21 insertions(+), 14 deletions(-) create mode 100644 python/ironic-understack/ironic_understack/conf.py diff --git a/python/ironic-understack/ironic_understack/conf.py b/python/ironic-understack/ironic_understack/conf.py new file mode 100644 index 00000000..c6ff909f --- /dev/null +++ b/python/ironic-understack/ironic_understack/conf.py @@ -0,0 +1,18 @@ +from oslo_config import cfg +CONF = cfg.CONF + + +def setup_conf(): + grp = cfg.OptGroup("ironic_understack") + opts = [ + cfg.StrOpt( + "flavors_dir", + help="directory storing Flavor description YAML files", + default="/var/lib/understack/flavors/undercloud-nautobot-device-types.git/flavors", + ) + ] + cfg.CONF.register_group(grp) + cfg.CONF.register_opts(opts, group=grp) + + +setup_conf() diff --git a/python/ironic-understack/ironic_understack/redfish_inspect_understack.py b/python/ironic-understack/ironic_understack/redfish_inspect_understack.py index 7750ec25..06d8db6a 100644 --- a/python/ironic-understack/ironic_understack/redfish_inspect_understack.py +++ b/python/ironic-understack/ironic_understack/redfish_inspect_understack.py @@ -21,22 +21,14 @@ from ironic_understack.flavor_spec import FlavorSpec from ironic_understack.machine import Machine from ironic_understack.matcher import Matcher +from ironic_understack.conf import CONF from oslo_log import log from oslo_utils import units LOG = log.getLogger(__name__) - -FLAVORS_SYNC_PATH = ( - "/var/lib/understack/flavors/undercloud-nautobot-device-types.git/flavors" -) -FLAVORS = FlavorSpec.from_directory(FLAVORS_SYNC_PATH) +FLAVORS = FlavorSpec.from_directory(CONF.ironic_understack.flavors_dir) LOG.info(f"Loaded {len(FLAVORS)} flavor specifications.") - ) - - - - class FlavorInspectMixin: def inspect_hardware(self, task): diff --git a/python/ironic-understack/ironic_understack/resource_class.py b/python/ironic-understack/ironic_understack/resource_class.py index de4c925d..0e72afca 100644 --- a/python/ironic-understack/ironic_understack/resource_class.py +++ b/python/ironic-understack/ironic_understack/resource_class.py @@ -8,10 +8,7 @@ LOG = logging.getLogger(__name__) -FLAVORS_SYNC_PATH = ( - "/var/lib/understack/flavors/undercloud-nautobot-device-types.git/flavors" -) -FLAVORS = FlavorSpec.from_directory(FLAVORS_SYNC_PATH) +FLAVORS = FlavorSpec.from_directory(CONF.ironic_understack.flavors_dir) LOG.info(f"Loaded {len(FLAVORS)} flavor specifications.") From 05a4d63e7beeeae8e4ed0c024dfa50bd6e4b2483 Mon Sep 17 00:00:00 2001 From: Marek Skrobacki Date: Thu, 29 Aug 2024 12:33:53 +0100 Subject: [PATCH 13/14] refactor Matcher and FlavorSpec Scoring logic should live in the FlavorSpec and provide an easy way to obtain score for a given Machine. This reduces Matcher functionality to simply interacting with a collection of flavors and matching them against Machine. --- .../ironic_understack/flavor_spec.py | 56 ++++++ .../ironic_understack/matcher.py | 56 +----- .../tests/test_flavor_spec.py | 125 ++++++++++++ .../ironic_understack/tests/test_machine.py | 19 ++ .../ironic_understack/tests/test_matcher.py | 182 +++--------------- 5 files changed, 229 insertions(+), 209 deletions(-) create mode 100644 python/ironic-understack/ironic_understack/tests/test_machine.py diff --git a/python/ironic-understack/ironic_understack/flavor_spec.py b/python/ironic-understack/ironic_understack/flavor_spec.py index c3939e10..d5277a13 100644 --- a/python/ironic-understack/ironic_understack/flavor_spec.py +++ b/python/ironic-understack/ironic_understack/flavor_spec.py @@ -3,6 +3,8 @@ import yaml +from ironic_understack.machine import Machine + @dataclass class FlavorSpec: @@ -42,3 +44,57 @@ def from_directory(directory: str = "/etc/flavors/") -> list["FlavorSpec"]: except Exception as e: print(f"Error processing file {filename}: {e}") return flavor_specs + + def score_machine(self, machine: Machine): + # Scoring Rules: + # + # 1. 100% match gets highest priority, no further evaluation needed + # 2. If the machine has less memory size than specified in the flavor, + # it cannot be used - the score should be 0. + # 3. If the machine has smaller disk size than specified in the flavor, + # it cannot be used - the score should be 0. + # 4. Machine must match the flavor on one of the CPU models exactly. + # 5. If the machine has exact amount memory as specified in flavor, but + # more disk space it is less desirable than the machine that matches + # exactly on both disk and memory. + # 6. If the machine has exact amount of disk as specified in flavor, + # but more memory space it is less desirable than the machine that + # matches exactly on both disk and memory. + + + # Rule 1: 100% match gets the highest priority + if ( + machine.memory_gb == self.memory_gb and + machine.disk_gb in self.drives and + machine.cpu in self.cpu_models + ): + return 100 + + # Rule 2: If machine has less memory than specified in the flavor, it cannot be used + if machine.memory_gb < self.memory_gb: + return 0 + + # Rule 3: If machine has smaller disk than specified in the flavor, it cannot be used + if any(machine.disk_gb < drive for drive in self.drives): + return 0 + + # Rule 4: Machine must match the flavor on one of the CPU models exactly + if machine.cpu not in self.cpu_models: + return 0 + + # Rule 5 and 6: Rank based on exact matches or excess capacity + score = 0 + + # Exact memory match gives preference + if machine.memory_gb == self.memory_gb: + score += 10 + elif machine.memory_gb > self.memory_gb: + score += 5 # Less desirable but still usable + + # Exact disk match gives preference + if machine.disk_gb in self.drives: + score += 10 + elif all(machine.disk_gb > drive for drive in self.drives): + score += 5 # Less desirable but still usable + + return score diff --git a/python/ironic-understack/ironic_understack/matcher.py b/python/ironic-understack/ironic_understack/matcher.py index 025458a3..8d9f59cf 100644 --- a/python/ironic-understack/ironic_understack/matcher.py +++ b/python/ironic-understack/ironic_understack/matcher.py @@ -6,67 +6,13 @@ class Matcher: def __init__(self, flavors: list[FlavorSpec]): self.flavors = flavors - def score_machine_to_flavor(self, machine: Machine, flavor: FlavorSpec) -> int: - # Scoring Rules: - # - # 1. 100% match gets highest priority, no further evaluation needed - # 2. If the machine has less memory size than specified in the flavor, - # it cannot be used - the score should be 0. - # 3. If the machine has smaller disk size than specified in the flavor, - # it cannot be used - the score should be 0. - # 4. Machine must match the flavor on one of the CPU models exactly. - # 5. If the machine has exact amount memory as specified in flavor, but - # more disk space it is less desirable than the machine that matches - # exactly on both disk and memory. - # 6. If the machine has exact amount of disk as specified in flavor, - # but more memory space it is less desirable than the machine that - # matches exactly on both disk and memory. - - - # Rule 1: 100% match gets the highest priority - if ( - machine.memory_gb == flavor.memory_gb and - machine.disk_gb in flavor.drives and - machine.cpu in flavor.cpu_models - ): - return 100 - - # Rule 2: If machine has less memory than specified in the flavor, it cannot be used - if machine.memory_gb < flavor.memory_gb: - return 0 - - # Rule 3: If machine has smaller disk than specified in the flavor, it cannot be used - if any(machine.disk_gb < drive for drive in flavor.drives): - return 0 - - # Rule 4: Machine must match the flavor on one of the CPU models exactly - if machine.cpu not in flavor.cpu_models: - return 0 - - # Rule 5 and 6: Rank based on exact matches or excess capacity - score = 0 - - # Exact memory match gives preference - if machine.memory_gb == flavor.memory_gb: - score += 10 - elif machine.memory_gb > flavor.memory_gb: - score += 5 # Less desirable but still usable - - # Exact disk match gives preference - if machine.disk_gb in flavor.drives: - score += 10 - elif all(machine.disk_gb > drive for drive in flavor.drives): - score += 5 # Less desirable but still usable - - return score - def match(self, machine: Machine) -> list[FlavorSpec]: """ Find list of all flavors that the machine is eligible for. """ results = [] for flavor in self.flavors: - score = self.score_machine_to_flavor(machine, flavor) + score = flavor.score_machine(machine) if score > 0: results.append(flavor) return results diff --git a/python/ironic-understack/ironic_understack/tests/test_flavor_spec.py b/python/ironic-understack/ironic_understack/tests/test_flavor_spec.py index 8a3ae058..a3e7e70a 100644 --- a/python/ironic-understack/ironic_understack/tests/test_flavor_spec.py +++ b/python/ironic-understack/ironic_understack/tests/test_flavor_spec.py @@ -2,6 +2,7 @@ import pytest from ironic_understack.flavor_spec import FlavorSpec +from ironic_understack.machine import Machine @pytest.fixture @@ -91,3 +92,127 @@ def test_from_directory_with_real_files(yaml_directory): def test_empty_directory(tmp_path): specs = FlavorSpec.from_directory(str(tmp_path)) assert len(specs) == 0 + +@pytest.fixture +def machines(): + return [ + # 1024 GB, exact CPU, medium + Machine( + memory_mb=102400, cpu="AMD EPYC 9254 245-Core Processor", disk_gb=1000 + ), + # 800 GB, non-matching CPU + Machine(memory_mb=800000, cpu="Intel Xeon E5-2676 v3", disk_gb=500), + # 200 GB, exact CPU, medium + Machine(memory_mb=200000, cpu="AMD EPYC 9254 245-Core Processor", disk_gb=1500), + # 300 GB, non-matching CPU + Machine(memory_mb=300000, cpu="Intel Xeon E5-2676 v3", disk_gb=500), + # 409 GB, exact CPU, large + Machine(memory_mb=409600, cpu="AMD EPYC 9254 245-Core Processor", disk_gb=2000), + ] + + +@pytest.fixture +def flavors(): + return [ + FlavorSpec( + name="small", + memory_gb=100, + cpu_cores=13, + cpu_models=["AMD EPYC 9254 245-Core Processor", "Pentium 60"], + drives=[500, 500], + devices=[], + ), + FlavorSpec( + name="medium", + memory_gb=200, + cpu_cores=15, + cpu_models=["AMD EPYC 9254 245-Core Processor", "Intel 80386DX"], + drives=[1500, 1500], + devices=[], + ), + FlavorSpec( + name="large", + memory_gb=400, + cpu_cores=27, + cpu_models=["AMD EPYC 9254 245-Core Processor"], + drives=[1800, 1800], + devices=[], + ), + ] + +def test_exact_match(flavors): + machine = Machine(memory_mb=102400, cpu="AMD EPYC 9254 245-Core Processor", disk_gb=500) + assert flavors[0].score_machine(machine) == 100 + assert flavors[1].score_machine(machine) == 0 + + +def test_memory_too_small(flavors): + machine = Machine(memory_mb=51200, cpu="AMD EPYC 9254 245-Core Processor", disk_gb=500) + assert all(flavor.score_machine(machine) for flavor in flavors) == 0 + + +def test_disk_too_small(flavors): + machine = Machine(memory_mb=204800, cpu="AMD EPYC 9254 245-Core Processor", disk_gb=100) + assert all(flavor.score_machine(machine) for flavor in flavors) == 0 + + +def test_cpu_model_not_matching(flavors): + machine = Machine(memory_mb=102400, cpu="Non-Existent CPU Model", disk_gb=500) + assert all(flavor.score_machine(machine) for flavor in flavors) == 0 + + +def test_memory_match_but_more_disk(flavors): + machine = Machine(memory_mb=102400, cpu="AMD EPYC 9254 245-Core Processor", disk_gb=1000) + assert flavors[0].score_machine(machine) > 0 + + +def test_disk_match_but_more_memory(flavors): + machine = Machine(memory_mb=204800, cpu="AMD EPYC 9254 245-Core Processor", disk_gb=500) + + assert flavors[0].score_machine(machine) > 0 + assert flavors[1].score_machine(machine) == 0 + assert flavors[2].score_machine(machine) == 0 + +# Edge cases +def test_memory_slightly_less(flavors): + # Machine with slightly less memory than required by the smallest flavor + machine = Machine(memory_mb=102300, cpu="AMD EPYC 9254 245-Core Processor", disk_gb=500) + # Should not match because memory is slightly less + assert all(flavor.score_machine(machine) for flavor in flavors) == 0 + + +def test_disk_slightly_less(flavors): + # Machine with slightly less disk space than required by the smallest flavor + machine = Machine(memory_mb=102400, cpu="AMD EPYC 9254 245-Core Processor", disk_gb=499) + # Should not match because disk space is slightly less + assert all(flavor.score_machine(machine) for flavor in flavors) == 0 + + +def test_memory_exact_disk_slightly_more(flavors): + # Machine with exact memory but slightly more disk space than required + machine = Machine(memory_mb=102400, cpu="AMD EPYC 9254 245-Core Processor", disk_gb=501) + assert flavors[0].score_machine(machine) > 0 + assert flavors[1].score_machine(machine) == 0 + assert flavors[2].score_machine(machine) == 0 + + +def test_disk_exact_memory_slightly_more(flavors): + # Machine with exact disk space but slightly more memory than required + machine = Machine(memory_mb=102500, cpu="AMD EPYC 9254 245-Core Processor", disk_gb=500) + assert flavors[0].score_machine(machine) > 0 + assert flavors[1].score_machine(machine) == 0 + assert flavors[2].score_machine(machine) == 0 + + +def test_cpu_model_not_exact_but_memory_and_disk_match(flavors): + # Machine with exact memory and disk space but CPU model is close but not exact + machine = Machine(memory_mb=102400, cpu="AMD EPYC 9254 245-Core Processor v2", disk_gb=500) + # Should not match because CPU model is not exactly listed + assert all(flavor.score_machine(machine) for flavor in flavors) == 0 + + +def test_large_flavor_memory_slightly_less_disk_exact(flavors): + # Machine with slightly less memory than required for the medium flavor, exact disk space + machine = Machine(memory_mb=204600, cpu="Intel 80386DX", disk_gb=1800) + # Should not match because memory is slightly less than required + assert all(flavor.score_machine(machine) for flavor in flavors) == 0 diff --git a/python/ironic-understack/ironic_understack/tests/test_machine.py b/python/ironic-understack/ironic_understack/tests/test_machine.py new file mode 100644 index 00000000..a17bb6b4 --- /dev/null +++ b/python/ironic-understack/ironic_understack/tests/test_machine.py @@ -0,0 +1,19 @@ +import pytest +from ironic_understack.machine import Machine + +def test_memory_gb_property(): + # Test a machine with exactly 1 GB of memory + machine = Machine(memory_mb=1024, cpu="x86", disk_gb=50) + assert machine.memory_gb == 1 + + # Test a machine with 2 GB of memory + machine = Machine(memory_mb=2048, cpu="x86", disk_gb=50) + assert machine.memory_gb == 2 + + # Test a machine with non-exact GB memory (should floor the value) + machine = Machine(memory_mb=3072, cpu="x86", disk_gb=50) + assert machine.memory_gb == 3 + + # Test a machine with less than 1 GB of memory + machine = Machine(memory_mb=512, cpu="x86", disk_gb=50) + assert machine.memory_gb == 0 diff --git a/python/ironic-understack/ironic_understack/tests/test_matcher.py b/python/ironic-understack/ironic_understack/tests/test_matcher.py index 3c338417..fbc7558f 100644 --- a/python/ironic-understack/ironic_understack/tests/test_matcher.py +++ b/python/ironic-understack/ironic_understack/tests/test_matcher.py @@ -3,169 +3,43 @@ from ironic_understack.machine import Machine from ironic_understack.matcher import Matcher - @pytest.fixture -def machines(): +def sample_flavors(): return [ - # 1024 GB, exact CPU, medium - Machine( - memory_mb=102400, cpu="AMD EPYC 9254 245-Core Processor", disk_gb=1000 - ), - # 800 GB, non-matching CPU - Machine(memory_mb=800000, cpu="Intel Xeon E5-2676 v3", disk_gb=500), - # 200 GB, exact CPU, medium - Machine(memory_mb=200000, cpu="AMD EPYC 9254 245-Core Processor", disk_gb=1500), - # 300 GB, non-matching CPU - Machine(memory_mb=300000, cpu="Intel Xeon E5-2676 v3", disk_gb=500), - # 409 GB, exact CPU, large - Machine(memory_mb=409600, cpu="AMD EPYC 9254 245-Core Processor", disk_gb=2000), + FlavorSpec(name="small", memory_gb=4, cpu_cores=2, cpu_models=["x86", "ARM"], drives=[20], devices=[]), + FlavorSpec(name="medium", memory_gb=8, cpu_cores=4, cpu_models=["x86"], drives=[40], devices=[]), + FlavorSpec(name="large", memory_gb=16, cpu_cores=8, cpu_models=["x86"], drives=[80], devices=[]), ] - @pytest.fixture -def flavors(): - return [ - FlavorSpec( - name="small", - memory_gb=100, - cpu_cores=13, - cpu_models=["AMD EPYC 9254 245-Core Processor", "Pentium 60"], - drives=[500, 500], - devices=[], - ), - FlavorSpec( - name="medium", - memory_gb=200, - cpu_cores=15, - cpu_models=["AMD EPYC 9254 245-Core Processor", "Intel 80386DX"], - drives=[1500, 1500], - devices=[], - ), - FlavorSpec( - name="large", - memory_gb=400, - cpu_cores=27, - cpu_models=["AMD EPYC 9254 245-Core Processor"], - drives=[1800, 1800], - devices=[], - ), - ] - -def test_exact_match(flavors): - machine = Machine(memory_mb=102400, cpu="AMD EPYC 9254 245-Core Processor", disk_gb=500) - matcher = Matcher(flavors) - matched_flavors = matcher.match(machine) - assert len(matched_flavors) == 1 - assert matched_flavors[0].name == "small" - - -def test_memory_too_small(flavors): - machine = Machine(memory_mb=51200, cpu="AMD EPYC 9254 245-Core Processor", disk_gb=500) - matcher = Matcher(flavors) - matched_flavors = matcher.match(machine) - assert len(matched_flavors) == 0 - - -def test_disk_too_small(flavors): - machine = Machine(memory_mb=204800, cpu="AMD EPYC 9254 245-Core Processor", disk_gb=100) - matcher = Matcher(flavors) - matched_flavors = matcher.match(machine) - assert len(matched_flavors) == 0 +def matcher(sample_flavors): + return Matcher(flavors=sample_flavors) - -def test_cpu_model_not_matching(flavors): - machine = Machine(memory_mb=102400, cpu="Non-Existent CPU Model", disk_gb=500) - matcher = Matcher(flavors) - matched_flavors = matcher.match(machine) - assert len(matched_flavors) == 0 - - -def test_memory_match_but_more_disk(flavors): - machine = Machine(memory_mb=102400, cpu="AMD EPYC 9254 245-Core Processor", disk_gb=1000) - matcher = Matcher(flavors) - matched_flavors = matcher.match(machine) - assert len(matched_flavors) == 1 - assert matched_flavors[0].name == "small" - - -def test_disk_match_but_more_memory(flavors): - machine = Machine(memory_mb=204800, cpu="AMD EPYC 9254 245-Core Processor", disk_gb=500) - matcher = Matcher(flavors) - matched_flavors = matcher.match(machine) - assert len(matched_flavors) == 1 - assert matched_flavors[0].name == "small" - - -def test_pick_best_flavor(flavors): - machine = Machine(memory_mb=204800, cpu="AMD EPYC 9254 245-Core Processor", disk_gb=1500) - matcher = Matcher(flavors) +@pytest.fixture +def machine(): + return Machine(memory_mb=8192, cpu="x86", disk_gb=50) + +def test_match(matcher, machine): + # This machine should match the small and medium flavors + results = matcher.match(machine) + assert len(results) == 2 + assert results[0].name == "small" + assert results[1].name == "medium" + +def test_match_no_flavor(matcher): + # A machine that does not meet any flavor specs + machine = Machine(memory_mb=2048, cpu="x86", disk_gb=10) + results = matcher.match(machine) + assert len(results) == 0 + +def test_pick_best_flavor2(matcher, machine): + # This machine should pick the medium flavor as the best best_flavor = matcher.pick_best_flavor(machine) assert best_flavor is not None assert best_flavor.name == "medium" - -def test_no_matching_flavor(flavors): - machine = Machine(memory_mb=51200, cpu="Non-Existent CPU Model", disk_gb=250) - matcher = Matcher(flavors) +def test_pick_best_flavor_no_match(matcher): + # A machine that does not meet any flavor specs + machine = Machine(memory_mb=1024, cpu="ARM", disk_gb=10) best_flavor = matcher.pick_best_flavor(machine) assert best_flavor is None - - -def test_multiple_flavors_available(flavors): - machine = Machine(memory_mb=204800, cpu="AMD EPYC 9254 245-Core Processor", disk_gb=2000) - matcher = Matcher(flavors) - matched_flavors = matcher.match(machine) - assert len(matched_flavors) == 2 # small and medium should be available - best_flavor = matcher.pick_best_flavor(machine) - assert best_flavor.name == "medium" # medium has more memory, so it should be selected - - -# Edge cases -def test_memory_slightly_less(flavors): - # Machine with slightly less memory than required by the smallest flavor - machine = Machine(memory_mb=102300, cpu="AMD EPYC 9254 245-Core Processor", disk_gb=500) - matcher = Matcher(flavors) - matched_flavors = matcher.match(machine) - assert len(matched_flavors) == 0 # Should not match because memory is slightly less - - -def test_disk_slightly_less(flavors): - # Machine with slightly less disk space than required by the smallest flavor - machine = Machine(memory_mb=102400, cpu="AMD EPYC 9254 245-Core Processor", disk_gb=499) - matcher = Matcher(flavors) - matched_flavors = matcher.match(machine) - assert len(matched_flavors) == 0 # Should not match because disk space is slightly less - - -def test_memory_exact_disk_slightly_more(flavors): - # Machine with exact memory but slightly more disk space than required - machine = Machine(memory_mb=102400, cpu="AMD EPYC 9254 245-Core Processor", disk_gb=501) - matcher = Matcher(flavors) - matched_flavors = matcher.match(machine) - assert len(matched_flavors) == 1 - assert matched_flavors[0].name == "small" # Should match but with a lower score due to extra disk space - - -def test_disk_exact_memory_slightly_more(flavors): - # Machine with exact disk space but slightly more memory than required - machine = Machine(memory_mb=102500, cpu="AMD EPYC 9254 245-Core Processor", disk_gb=500) - matcher = Matcher(flavors) - matched_flavors = matcher.match(machine) - assert len(matched_flavors) == 1 - assert matched_flavors[0].name == "small" # Should match but with a lower score due to extra memory - - -def test_cpu_model_not_exact_but_memory_and_disk_match(flavors): - # Machine with exact memory and disk space but CPU model is close but not exact - machine = Machine(memory_mb=102400, cpu="AMD EPYC 9254 245-Core Processor v2", disk_gb=500) - matcher = Matcher(flavors) - matched_flavors = matcher.match(machine) - assert len(matched_flavors) == 0 # Should not match because CPU model is not exactly listed - - -def test_large_flavor_memory_slightly_less_disk_exact(flavors): - # Machine with slightly less memory than required for the medium flavor, exact disk space - machine = Machine(memory_mb=204600, cpu="Intel 80386DX", disk_gb=1800) - matcher = Matcher(flavors) - matched_flavors = matcher.match(machine) - assert len(matched_flavors) == 0 # Should not match because memory is slightly less than required From 3c434b5646f017a51b061d5fa0988239dac399e5 Mon Sep 17 00:00:00 2001 From: Marek Skrobacki Date: Thu, 29 Aug 2024 15:17:38 +0100 Subject: [PATCH 14/14] gh workflows: run tests on python/ironic-understack too --- .github/workflows/code-test.yaml | 26 ++++- python/ironic-understack/poetry.lock | 127 +++++++++++++++++++++++- python/ironic-understack/pyproject.toml | 11 +- 3 files changed, 157 insertions(+), 7 deletions(-) diff --git a/.github/workflows/code-test.yaml b/.github/workflows/code-test.yaml index b94949f7..cb200819 100644 --- a/.github/workflows/code-test.yaml +++ b/.github/workflows/code-test.yaml @@ -5,11 +5,13 @@ on: branches: - main paths: - - "python/**" + - "python/ironic-understack/**" + - "python/understack-workflows/**" - ".github/workflows/code-test.yaml" pull_request: paths: - - "python/**" + - "python/ironic-understack/**" + - "python/understack-workflows/**" - ".github/workflows/code-test.yaml" workflow_dispatch: @@ -34,3 +36,23 @@ jobs: with: coverageFile: python/understack-workflows/coverage.xml token: ${{ secrets.GITHUB_TOKEN }} + ironic-understack: + runs-on: ubuntu-latest + defaults: + run: + working-directory: ./python/ironic-understack + + steps: + - uses: actions/checkout@v4 + - run: pipx install poetry==1.7.1 && poetry self add 'poetry-dynamic-versioning[plugin]' + - uses: actions/setup-python@v5 + with: + python-version-file: python/ironic-understack/pyproject.toml + cache: "poetry" + - run: poetry install --sync --with test + - run: poetry build + - run: "poetry run pytest --cov-report xml:coverage.xml" + - uses: orgoro/coverage@v3.2 + with: + coverageFile: python/ironic-understack/coverage.xml + token: ${{ secrets.GITHUB_TOKEN }} diff --git a/python/ironic-understack/poetry.lock b/python/ironic-understack/poetry.lock index 1071fb83..4e932ac1 100644 --- a/python/ironic-understack/poetry.lock +++ b/python/ironic-understack/poetry.lock @@ -376,6 +376,93 @@ files = [ [package.extras] extras = ["arrow", "cloudpickle", "cryptography", "lz4", "numpy", "ruamel.yaml"] +[[package]] +name = "coverage" +version = "7.6.1" +description = "Code coverage measurement for Python" +optional = false +python-versions = ">=3.8" +files = [ + {file = "coverage-7.6.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:b06079abebbc0e89e6163b8e8f0e16270124c154dc6e4a47b413dd538859af16"}, + {file = "coverage-7.6.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:cf4b19715bccd7ee27b6b120e7e9dd56037b9c0681dcc1adc9ba9db3d417fa36"}, + {file = "coverage-7.6.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e61c0abb4c85b095a784ef23fdd4aede7a2628478e7baba7c5e3deba61070a02"}, + {file = "coverage-7.6.1-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:fd21f6ae3f08b41004dfb433fa895d858f3f5979e7762d052b12aef444e29afc"}, + {file = "coverage-7.6.1-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8f59d57baca39b32db42b83b2a7ba6f47ad9c394ec2076b084c3f029b7afca23"}, + {file = "coverage-7.6.1-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:a1ac0ae2b8bd743b88ed0502544847c3053d7171a3cff9228af618a068ed9c34"}, + {file = "coverage-7.6.1-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:e6a08c0be454c3b3beb105c0596ebdc2371fab6bb90c0c0297f4e58fd7e1012c"}, + {file = "coverage-7.6.1-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:f5796e664fe802da4f57a168c85359a8fbf3eab5e55cd4e4569fbacecc903959"}, + {file = "coverage-7.6.1-cp310-cp310-win32.whl", hash = "sha256:7bb65125fcbef8d989fa1dd0e8a060999497629ca5b0efbca209588a73356232"}, + {file = "coverage-7.6.1-cp310-cp310-win_amd64.whl", hash = "sha256:3115a95daa9bdba70aea750db7b96b37259a81a709223c8448fa97727d546fe0"}, + {file = "coverage-7.6.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:7dea0889685db8550f839fa202744652e87c60015029ce3f60e006f8c4462c93"}, + {file = "coverage-7.6.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:ed37bd3c3b063412f7620464a9ac1314d33100329f39799255fb8d3027da50d3"}, + {file = "coverage-7.6.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d85f5e9a5f8b73e2350097c3756ef7e785f55bd71205defa0bfdaf96c31616ff"}, + {file = "coverage-7.6.1-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:9bc572be474cafb617672c43fe989d6e48d3c83af02ce8de73fff1c6bb3c198d"}, + {file = "coverage-7.6.1-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0c0420b573964c760df9e9e86d1a9a622d0d27f417e1a949a8a66dd7bcee7bc6"}, + {file = "coverage-7.6.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:1f4aa8219db826ce6be7099d559f8ec311549bfc4046f7f9fe9b5cea5c581c56"}, + {file = "coverage-7.6.1-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:fc5a77d0c516700ebad189b587de289a20a78324bc54baee03dd486f0855d234"}, + {file = "coverage-7.6.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:b48f312cca9621272ae49008c7f613337c53fadca647d6384cc129d2996d1133"}, + {file = "coverage-7.6.1-cp311-cp311-win32.whl", hash = "sha256:1125ca0e5fd475cbbba3bb67ae20bd2c23a98fac4e32412883f9bcbaa81c314c"}, + {file = "coverage-7.6.1-cp311-cp311-win_amd64.whl", hash = "sha256:8ae539519c4c040c5ffd0632784e21b2f03fc1340752af711f33e5be83a9d6c6"}, + {file = "coverage-7.6.1-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:95cae0efeb032af8458fc27d191f85d1717b1d4e49f7cb226cf526ff28179778"}, + {file = "coverage-7.6.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:5621a9175cf9d0b0c84c2ef2b12e9f5f5071357c4d2ea6ca1cf01814f45d2391"}, + {file = "coverage-7.6.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:260933720fdcd75340e7dbe9060655aff3af1f0c5d20f46b57f262ab6c86a5e8"}, + {file = "coverage-7.6.1-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:07e2ca0ad381b91350c0ed49d52699b625aab2b44b65e1b4e02fa9df0e92ad2d"}, + {file = "coverage-7.6.1-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c44fee9975f04b33331cb8eb272827111efc8930cfd582e0320613263ca849ca"}, + {file = "coverage-7.6.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:877abb17e6339d96bf08e7a622d05095e72b71f8afd8a9fefc82cf30ed944163"}, + {file = "coverage-7.6.1-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:3e0cadcf6733c09154b461f1ca72d5416635e5e4ec4e536192180d34ec160f8a"}, + {file = "coverage-7.6.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:c3c02d12f837d9683e5ab2f3d9844dc57655b92c74e286c262e0fc54213c216d"}, + {file = "coverage-7.6.1-cp312-cp312-win32.whl", hash = "sha256:e05882b70b87a18d937ca6768ff33cc3f72847cbc4de4491c8e73880766718e5"}, + {file = "coverage-7.6.1-cp312-cp312-win_amd64.whl", hash = "sha256:b5d7b556859dd85f3a541db6a4e0167b86e7273e1cdc973e5b175166bb634fdb"}, + {file = "coverage-7.6.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:a4acd025ecc06185ba2b801f2de85546e0b8ac787cf9d3b06e7e2a69f925b106"}, + {file = "coverage-7.6.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:a6d3adcf24b624a7b778533480e32434a39ad8fa30c315208f6d3e5542aeb6e9"}, + {file = "coverage-7.6.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d0c212c49b6c10e6951362f7c6df3329f04c2b1c28499563d4035d964ab8e08c"}, + {file = "coverage-7.6.1-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6e81d7a3e58882450ec4186ca59a3f20a5d4440f25b1cff6f0902ad890e6748a"}, + {file = "coverage-7.6.1-cp313-cp313-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:78b260de9790fd81e69401c2dc8b17da47c8038176a79092a89cb2b7d945d060"}, + {file = "coverage-7.6.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:a78d169acd38300060b28d600344a803628c3fd585c912cacc9ea8790fe96862"}, + {file = "coverage-7.6.1-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:2c09f4ce52cb99dd7505cd0fc8e0e37c77b87f46bc9c1eb03fe3bc9991085388"}, + {file = "coverage-7.6.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:6878ef48d4227aace338d88c48738a4258213cd7b74fd9a3d4d7582bb1d8a155"}, + {file = "coverage-7.6.1-cp313-cp313-win32.whl", hash = "sha256:44df346d5215a8c0e360307d46ffaabe0f5d3502c8a1cefd700b34baf31d411a"}, + {file = "coverage-7.6.1-cp313-cp313-win_amd64.whl", hash = "sha256:8284cf8c0dd272a247bc154eb6c95548722dce90d098c17a883ed36e67cdb129"}, + {file = "coverage-7.6.1-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:d3296782ca4eab572a1a4eca686d8bfb00226300dcefdf43faa25b5242ab8a3e"}, + {file = "coverage-7.6.1-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:502753043567491d3ff6d08629270127e0c31d4184c4c8d98f92c26f65019962"}, + {file = "coverage-7.6.1-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6a89ecca80709d4076b95f89f308544ec8f7b4727e8a547913a35f16717856cb"}, + {file = "coverage-7.6.1-cp313-cp313t-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a318d68e92e80af8b00fa99609796fdbcdfef3629c77c6283566c6f02c6d6704"}, + {file = "coverage-7.6.1-cp313-cp313t-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:13b0a73a0896988f053e4fbb7de6d93388e6dd292b0d87ee51d106f2c11b465b"}, + {file = "coverage-7.6.1-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:4421712dbfc5562150f7554f13dde997a2e932a6b5f352edcce948a815efee6f"}, + {file = "coverage-7.6.1-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:166811d20dfea725e2e4baa71fffd6c968a958577848d2131f39b60043400223"}, + {file = "coverage-7.6.1-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:225667980479a17db1048cb2bf8bfb39b8e5be8f164b8f6628b64f78a72cf9d3"}, + {file = "coverage-7.6.1-cp313-cp313t-win32.whl", hash = "sha256:170d444ab405852903b7d04ea9ae9b98f98ab6d7e63e1115e82620807519797f"}, + {file = "coverage-7.6.1-cp313-cp313t-win_amd64.whl", hash = "sha256:b9f222de8cded79c49bf184bdbc06630d4c58eec9459b939b4a690c82ed05657"}, + {file = "coverage-7.6.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:6db04803b6c7291985a761004e9060b2bca08da6d04f26a7f2294b8623a0c1a0"}, + {file = "coverage-7.6.1-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:f1adfc8ac319e1a348af294106bc6a8458a0f1633cc62a1446aebc30c5fa186a"}, + {file = "coverage-7.6.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a95324a9de9650a729239daea117df21f4b9868ce32e63f8b650ebe6cef5595b"}, + {file = "coverage-7.6.1-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b43c03669dc4618ec25270b06ecd3ee4fa94c7f9b3c14bae6571ca00ef98b0d3"}, + {file = "coverage-7.6.1-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8929543a7192c13d177b770008bc4e8119f2e1f881d563fc6b6305d2d0ebe9de"}, + {file = "coverage-7.6.1-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:a09ece4a69cf399510c8ab25e0950d9cf2b42f7b3cb0374f95d2e2ff594478a6"}, + {file = "coverage-7.6.1-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:9054a0754de38d9dbd01a46621636689124d666bad1936d76c0341f7d71bf569"}, + {file = "coverage-7.6.1-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:0dbde0f4aa9a16fa4d754356a8f2e36296ff4d83994b2c9d8398aa32f222f989"}, + {file = "coverage-7.6.1-cp38-cp38-win32.whl", hash = "sha256:da511e6ad4f7323ee5702e6633085fb76c2f893aaf8ce4c51a0ba4fc07580ea7"}, + {file = "coverage-7.6.1-cp38-cp38-win_amd64.whl", hash = "sha256:3f1156e3e8f2872197af3840d8ad307a9dd18e615dc64d9ee41696f287c57ad8"}, + {file = "coverage-7.6.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:abd5fd0db5f4dc9289408aaf34908072f805ff7792632250dcb36dc591d24255"}, + {file = "coverage-7.6.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:547f45fa1a93154bd82050a7f3cddbc1a7a4dd2a9bf5cb7d06f4ae29fe94eaf8"}, + {file = "coverage-7.6.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:645786266c8f18a931b65bfcefdbf6952dd0dea98feee39bd188607a9d307ed2"}, + {file = "coverage-7.6.1-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:9e0b2df163b8ed01d515807af24f63de04bebcecbd6c3bfeff88385789fdf75a"}, + {file = "coverage-7.6.1-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:609b06f178fe8e9f89ef676532760ec0b4deea15e9969bf754b37f7c40326dbc"}, + {file = "coverage-7.6.1-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:702855feff378050ae4f741045e19a32d57d19f3e0676d589df0575008ea5004"}, + {file = "coverage-7.6.1-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:2bdb062ea438f22d99cba0d7829c2ef0af1d768d1e4a4f528087224c90b132cb"}, + {file = "coverage-7.6.1-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:9c56863d44bd1c4fe2abb8a4d6f5371d197f1ac0ebdee542f07f35895fc07f36"}, + {file = "coverage-7.6.1-cp39-cp39-win32.whl", hash = "sha256:6e2cd258d7d927d09493c8df1ce9174ad01b381d4729a9d8d4e38670ca24774c"}, + {file = "coverage-7.6.1-cp39-cp39-win_amd64.whl", hash = "sha256:06a737c882bd26d0d6ee7269b20b12f14a8704807a01056c80bb881a4b2ce6ca"}, + {file = "coverage-7.6.1-pp38.pp39.pp310-none-any.whl", hash = "sha256:e9a6e0eb86070e8ccaedfbd9d38fec54864f3125ab95419970575b42af7541df"}, + {file = "coverage-7.6.1.tar.gz", hash = "sha256:953510dfb7b12ab69d20135a0662397f077c59b1e6379a768e97c59d852ee51d"}, +] + +[package.dependencies] +tomli = {version = "*", optional = true, markers = "python_full_version <= \"3.11.0a6\" and extra == \"toml\""} + +[package.extras] +toml = ["tomli"] + [[package]] name = "cryptography" version = "43.0.0" @@ -1917,15 +2004,47 @@ tomli = {version = ">=1", markers = "python_version < \"3.11\""} [package.extras] dev = ["argcomplete", "attrs (>=19.2)", "hypothesis (>=3.56)", "mock", "pygments (>=2.7.2)", "requests", "setuptools", "xmlschema"] +[[package]] +name = "pytest-cov" +version = "5.0.0" +description = "Pytest plugin for measuring coverage." +optional = false +python-versions = ">=3.8" +files = [ + {file = "pytest-cov-5.0.0.tar.gz", hash = "sha256:5837b58e9f6ebd335b0f8060eecce69b662415b16dc503883a02f45dfeb14857"}, + {file = "pytest_cov-5.0.0-py3-none-any.whl", hash = "sha256:4f0764a1219df53214206bf1feea4633c3b558a2925c8b59f144f682861ce652"}, +] + +[package.dependencies] +coverage = {version = ">=5.2.1", extras = ["toml"]} +pytest = ">=4.6" + +[package.extras] +testing = ["fields", "hunter", "process-tests", "pytest-xdist", "virtualenv"] + +[[package]] +name = "pytest-github-actions-annotate-failures" +version = "0.2.0" +description = "pytest plugin to annotate failed tests with a workflow command for GitHub Actions" +optional = false +python-versions = ">=3.7" +files = [ + {file = "pytest-github-actions-annotate-failures-0.2.0.tar.gz", hash = "sha256:844ab626d389496e44f960b42f0a72cce29ae06d363426d17ea9ae1b4bef2288"}, + {file = "pytest_github_actions_annotate_failures-0.2.0-py3-none-any.whl", hash = "sha256:8bcef65fed503faaa0524b59cfeccc8995130972dd7b008d64193cc41b9cde85"}, +] + +[package.dependencies] +pytest = ">=4.0.0" + [[package]] name = "python-cinderclient" -version = "9.5.0" +version = "9.6.0" description = "OpenStack Block Storage API Client Library" optional = false python-versions = ">=3.8" files = [ - {file = "python-cinderclient-9.5.0.tar.gz", hash = "sha256:1b9d717aff93cad420045fb6c52f6376ab72f085f8193130892020ec46c93555"}, - {file = "python_cinderclient-9.5.0-py3-none-any.whl", hash = "sha256:b2ee2681c1f9785957f89be10e7e41fee130729b5c6b2f7c5fa6b542fb27eaaa"}, + {file = "python-cinderclient-9.6.0.tar.gz", hash = "sha256:3fefde268252e52e30fe2773f658227a78c6dee378fcb132d31c86e6ec9ba238"}, + {file = "python_cinderclient-9.6.0-py3-none-any.whl", hash = "sha256:3a8a3a3eded306fd3051797398556ca174c8ddb51f6f8c6d8d14fc83fa2f8d54"}, ] [package.dependencies] @@ -2892,4 +3011,4 @@ type = ["pytest-mypy"] [metadata] lock-version = "2.0" python-versions = "^3.8" -content-hash = "f889f05f48bf03a5701d4bc80bd0b81c71ea86c1c407cad0ac0c1ac2d1f78568" +content-hash = "f36858215b98079fa603ccbbc1580e6d298c142d70562ab36f5096ead6485f88" diff --git a/python/ironic-understack/pyproject.toml b/python/ironic-understack/pyproject.toml index f75e7b65..02c11ce4 100644 --- a/python/ironic-understack/pyproject.toml +++ b/python/ironic-understack/pyproject.toml @@ -14,8 +14,10 @@ ironic = "^24.1" python = "^3.8" pyyaml = "^6.0" -[tool.poetry.group.dev.dependencies] +[tool.poetry.group.test.dependencies] pytest = "^8.3.2" +pytest-github-actions-annotate-failures = "*" +pytest-cov = "^5.0.0" [build-system] requires = ["poetry-core"] @@ -27,3 +29,10 @@ build-backend = "poetry.core.masonry.api" [tool.poetry.plugins."ironic.hardware.interfaces.inspect"] "redfish-understack" = "ironic_understack.redfish_inspect_understack:UnderstackRedfishInspect" "idrac-redfish-understack" = "ironic_understack.redfish_inspect_understack:UnderstackDracRedfishInspect" + +[tool.pytest.ini_options] +minversion = "6.0" +addopts = "-ra --cov=ironic_understack" +testpaths = [ + "tests", +]