From 4c0a3f9712462fbba32daf971129b3e8855d0b8c Mon Sep 17 00:00:00 2001 From: TheByronHimes Date: Thu, 24 Oct 2024 15:02:29 +0000 Subject: [PATCH 01/15] Update lock files and template files --- .devcontainer/devcontainer.json | 5 +- .pre-commit-config.yaml | 4 +- lock/requirements-dev.txt | 1555 ++++++++++++++++--------------- lock/requirements.txt | 1019 ++++++++++---------- 4 files changed, 1316 insertions(+), 1267 deletions(-) diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json index b9b990e..49098d6 100644 --- a/.devcontainer/devcontainer.json +++ b/.devcontainer/devcontainer.json @@ -52,7 +52,8 @@ "visualstudioexptteam.vscodeintellicode", "ymotongpoo.licenser", "charliermarsh.ruff", - "ms-python.mypy-type-checker" + "ms-python.mypy-type-checker", + "-ms-python.autopep8" ] } }, @@ -71,4 +72,4 @@ // details can be found here: https://github.com/devcontainers/features/tree/main/src/docker-outside-of-docker "ghcr.io/devcontainers/features/docker-outside-of-docker:1": {} } -} \ No newline at end of file +} diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 7f1cf66..b147654 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -45,13 +45,13 @@ repos: - id: no-commit-to-branch args: [--branch, dev, --branch, int, --branch, main] - repo: https://github.com/astral-sh/ruff-pre-commit - rev: v0.6.2 + rev: v0.7.0 hooks: - id: ruff args: [--fix, --exit-non-zero-on-fix] - id: ruff-format - repo: https://github.com/pre-commit/mirrors-mypy - rev: v1.11.1 + rev: v1.13.0 hooks: - id: mypy args: [--no-warn-unused-ignores] diff --git a/lock/requirements-dev.txt b/lock/requirements-dev.txt index 2d8b142..31b17fa 100644 --- a/lock/requirements-dev.txt +++ b/lock/requirements-dev.txt @@ -35,9 +35,9 @@ annotated-types==0.7.0 \ --hash=sha256:1f02e8b43a8fbbc3f3e0d4f0f4bfc8131bcb4eebe8849b8e5c773f3a1c582a53 \ --hash=sha256:aff07c09a53a08bc8cfccb9c85b05f1aa9a2a6f23728d790723543408344ce89 # via pydantic -anyio==4.4.0 \ - --hash=sha256:5aadc6a1bbb7cdb0bede386cac5e2940f5e2ff3aa20277e991cf028e0585ce94 \ - --hash=sha256:c1b2d8f46a8a812513012e1107cb0e68c17159a7a594208005a57dc776e1bdc7 +anyio==4.6.2.post1 \ + --hash=sha256:4c8bc31ccdb51c7f7bd251f51c609e038d63e34219b44aa86e47576389880b4c \ + --hash=sha256:6d170c36fba3bdd840c73d3868c1e777e33676a69c3a72cf0a0d5d6d8009b61d # via # httpx # starlette @@ -52,20 +52,20 @@ attrs==24.2.0 \ # via # jsonschema # referencing -boto3==1.35.4 \ - --hash=sha256:96c39593afb7b55ebb74d08c8e3201041d105b557c8c8536c9054c9f13da5f2a \ - --hash=sha256:d997b82c468bd5c2d5cd29810d47079b66b178d2b5ae021aebe262c4d78d4c94 +boto3==1.35.47 \ + --hash=sha256:0b307f685875e9c7857ce21c0d3050d8d4f3778455a6852d5f98ac75194b400e \ + --hash=sha256:65b808e4cf1af8c2f405382d53656a0d92eee8f85c7388c43d64c7a5571b065f # via hexkit -botocore==1.35.4 \ - --hash=sha256:10195e5ca764745f02b9a51df048b996ddbdc1899a44a2caf35dfb225dfea489 \ - --hash=sha256:4cc51a6a486915aedc140f9d027b7e156646b7a0f7b33b1000762c81aff9a12f +botocore==1.35.47 \ + --hash=sha256:05f4493119a96799ff84d43e78691efac3177e1aec8840cca99511de940e342a \ + --hash=sha256:f8f703463d3cd8b6abe2bedc443a7ab29f0e2ff1588a2e83164b108748645547 # via # boto3 # hexkit # s3transfer -certifi==2024.7.4 \ - --hash=sha256:5a1e7645bc0ec61a09e26c36f6106dd4cf40c6db3a1fb6352b0244e7fb057c7b \ - --hash=sha256:c198e21b1289c2ab85ee4e67bb4b4ef3ead0892059901a8d5b622f24a1101e90 +certifi==2024.8.30 \ + --hash=sha256:922820b53db7a7257ffbda3f597266d435245903d80737e34f8a45ff3e3230d8 \ + --hash=sha256:bec941d2aa8195e248a60b31ff9f0558284cf01a52591ceda73ea9afffd69fd9 # via # httpcore # httpx @@ -74,97 +74,112 @@ cfgv==3.4.0 \ --hash=sha256:b7265b1f29fd3316bfcd2b330d63d024f2bfd8bcb8b0272f8e19a504856c48f9 \ --hash=sha256:e52591d4c5f5dead8e0f673fb16db7949d2cfb3f7da4582893288f0ded8fe560 # via pre-commit -charset-normalizer==3.3.2 \ - --hash=sha256:06435b539f889b1f6f4ac1758871aae42dc3a8c0e24ac9e60c2384973ad73027 \ - --hash=sha256:06a81e93cd441c56a9b65d8e1d043daeb97a3d0856d177d5c90ba85acb3db087 \ - --hash=sha256:0a55554a2fa0d408816b3b5cedf0045f4b8e1a6065aec45849de2d6f3f8e9786 \ - --hash=sha256:0b2b64d2bb6d3fb9112bafa732def486049e63de9618b5843bcdd081d8144cd8 \ - --hash=sha256:10955842570876604d404661fbccbc9c7e684caf432c09c715ec38fbae45ae09 \ - --hash=sha256:122c7fa62b130ed55f8f285bfd56d5f4b4a5b503609d181f9ad85e55c89f4185 \ - --hash=sha256:1ceae2f17a9c33cb48e3263960dc5fc8005351ee19db217e9b1bb15d28c02574 \ - --hash=sha256:1d3193f4a680c64b4b6a9115943538edb896edc190f0b222e73761716519268e \ - --hash=sha256:1f79682fbe303db92bc2b1136016a38a42e835d932bab5b3b1bfcfbf0640e519 \ - --hash=sha256:2127566c664442652f024c837091890cb1942c30937add288223dc895793f898 \ - --hash=sha256:22afcb9f253dac0696b5a4be4a1c0f8762f8239e21b99680099abd9b2b1b2269 \ - --hash=sha256:25baf083bf6f6b341f4121c2f3c548875ee6f5339300e08be3f2b2ba1721cdd3 \ - --hash=sha256:2e81c7b9c8979ce92ed306c249d46894776a909505d8f5a4ba55b14206e3222f \ - --hash=sha256:3287761bc4ee9e33561a7e058c72ac0938c4f57fe49a09eae428fd88aafe7bb6 \ - --hash=sha256:34d1c8da1e78d2e001f363791c98a272bb734000fcef47a491c1e3b0505657a8 \ - --hash=sha256:37e55c8e51c236f95b033f6fb391d7d7970ba5fe7ff453dad675e88cf303377a \ - --hash=sha256:3d47fa203a7bd9c5b6cee4736ee84ca03b8ef23193c0d1ca99b5089f72645c73 \ - --hash=sha256:3e4d1f6587322d2788836a99c69062fbb091331ec940e02d12d179c1d53e25fc \ - --hash=sha256:42cb296636fcc8b0644486d15c12376cb9fa75443e00fb25de0b8602e64c1714 \ - --hash=sha256:45485e01ff4d3630ec0d9617310448a8702f70e9c01906b0d0118bdf9d124cf2 \ - --hash=sha256:4a78b2b446bd7c934f5dcedc588903fb2f5eec172f3d29e52a9096a43722adfc \ - --hash=sha256:4ab2fe47fae9e0f9dee8c04187ce5d09f48eabe611be8259444906793ab7cbce \ - --hash=sha256:4d0d1650369165a14e14e1e47b372cfcb31d6ab44e6e33cb2d4e57265290044d \ - --hash=sha256:549a3a73da901d5bc3ce8d24e0600d1fa85524c10287f6004fbab87672bf3e1e \ - --hash=sha256:55086ee1064215781fff39a1af09518bc9255b50d6333f2e4c74ca09fac6a8f6 \ - --hash=sha256:572c3763a264ba47b3cf708a44ce965d98555f618ca42c926a9c1616d8f34269 \ - --hash=sha256:573f6eac48f4769d667c4442081b1794f52919e7edada77495aaed9236d13a96 \ - --hash=sha256:5b4c145409bef602a690e7cfad0a15a55c13320ff7a3ad7ca59c13bb8ba4d45d \ - --hash=sha256:6463effa3186ea09411d50efc7d85360b38d5f09b870c48e4600f63af490e56a \ - --hash=sha256:65f6f63034100ead094b8744b3b97965785388f308a64cf8d7c34f2f2e5be0c4 \ - --hash=sha256:663946639d296df6a2bb2aa51b60a2454ca1cb29835324c640dafb5ff2131a77 \ - --hash=sha256:6897af51655e3691ff853668779c7bad41579facacf5fd7253b0133308cf000d \ - --hash=sha256:68d1f8a9e9e37c1223b656399be5d6b448dea850bed7d0f87a8311f1ff3dabb0 \ - --hash=sha256:6ac7ffc7ad6d040517be39eb591cac5ff87416c2537df6ba3cba3bae290c0fed \ - --hash=sha256:6b3251890fff30ee142c44144871185dbe13b11bab478a88887a639655be1068 \ - --hash=sha256:6c4caeef8fa63d06bd437cd4bdcf3ffefe6738fb1b25951440d80dc7df8c03ac \ - --hash=sha256:6ef1d82a3af9d3eecdba2321dc1b3c238245d890843e040e41e470ffa64c3e25 \ - --hash=sha256:753f10e867343b4511128c6ed8c82f7bec3bd026875576dfd88483c5c73b2fd8 \ - --hash=sha256:7cd13a2e3ddeed6913a65e66e94b51d80a041145a026c27e6bb76c31a853c6ab \ - --hash=sha256:7ed9e526742851e8d5cc9e6cf41427dfc6068d4f5a3bb03659444b4cabf6bc26 \ - --hash=sha256:7f04c839ed0b6b98b1a7501a002144b76c18fb1c1850c8b98d458ac269e26ed2 \ - --hash=sha256:802fe99cca7457642125a8a88a084cef28ff0cf9407060f7b93dca5aa25480db \ - --hash=sha256:80402cd6ee291dcb72644d6eac93785fe2c8b9cb30893c1af5b8fdd753b9d40f \ - --hash=sha256:8465322196c8b4d7ab6d1e049e4c5cb460d0394da4a27d23cc242fbf0034b6b5 \ - --hash=sha256:86216b5cee4b06df986d214f664305142d9c76df9b6512be2738aa72a2048f99 \ - --hash=sha256:87d1351268731db79e0f8e745d92493ee2841c974128ef629dc518b937d9194c \ - --hash=sha256:8bdb58ff7ba23002a4c5808d608e4e6c687175724f54a5dade5fa8c67b604e4d \ - --hash=sha256:8c622a5fe39a48f78944a87d4fb8a53ee07344641b0562c540d840748571b811 \ - --hash=sha256:8d756e44e94489e49571086ef83b2bb8ce311e730092d2c34ca8f7d925cb20aa \ - --hash=sha256:8f4a014bc36d3c57402e2977dada34f9c12300af536839dc38c0beab8878f38a \ - --hash=sha256:9063e24fdb1e498ab71cb7419e24622516c4a04476b17a2dab57e8baa30d6e03 \ - --hash=sha256:90d558489962fd4918143277a773316e56c72da56ec7aa3dc3dbbe20fdfed15b \ - --hash=sha256:923c0c831b7cfcb071580d3f46c4baf50f174be571576556269530f4bbd79d04 \ - --hash=sha256:95f2a5796329323b8f0512e09dbb7a1860c46a39da62ecb2324f116fa8fdc85c \ - --hash=sha256:96b02a3dc4381e5494fad39be677abcb5e6634bf7b4fa83a6dd3112607547001 \ - --hash=sha256:9f96df6923e21816da7e0ad3fd47dd8f94b2a5ce594e00677c0013018b813458 \ - --hash=sha256:a10af20b82360ab00827f916a6058451b723b4e65030c5a18577c8b2de5b3389 \ - --hash=sha256:a50aebfa173e157099939b17f18600f72f84eed3049e743b68ad15bd69b6bf99 \ - --hash=sha256:a981a536974bbc7a512cf44ed14938cf01030a99e9b3a06dd59578882f06f985 \ - --hash=sha256:a9a8e9031d613fd2009c182b69c7b2c1ef8239a0efb1df3f7c8da66d5dd3d537 \ - --hash=sha256:ae5f4161f18c61806f411a13b0310bea87f987c7d2ecdbdaad0e94eb2e404238 \ - --hash=sha256:aed38f6e4fb3f5d6bf81bfa990a07806be9d83cf7bacef998ab1a9bd660a581f \ - --hash=sha256:b01b88d45a6fcb69667cd6d2f7a9aeb4bf53760d7fc536bf679ec94fe9f3ff3d \ - --hash=sha256:b261ccdec7821281dade748d088bb6e9b69e6d15b30652b74cbbac25e280b796 \ - --hash=sha256:b2b0a0c0517616b6869869f8c581d4eb2dd83a4d79e0ebcb7d373ef9956aeb0a \ - --hash=sha256:b4a23f61ce87adf89be746c8a8974fe1c823c891d8f86eb218bb957c924bb143 \ - --hash=sha256:bd8f7df7d12c2db9fab40bdd87a7c09b1530128315d047a086fa3ae3435cb3a8 \ - --hash=sha256:beb58fe5cdb101e3a055192ac291b7a21e3b7ef4f67fa1d74e331a7f2124341c \ - --hash=sha256:c002b4ffc0be611f0d9da932eb0f704fe2602a9a949d1f738e4c34c75b0863d5 \ - --hash=sha256:c083af607d2515612056a31f0a8d9e0fcb5876b7bfc0abad3ecd275bc4ebc2d5 \ - --hash=sha256:c180f51afb394e165eafe4ac2936a14bee3eb10debc9d9e4db8958fe36afe711 \ - --hash=sha256:c235ebd9baae02f1b77bcea61bce332cb4331dc3617d254df3323aa01ab47bd4 \ - --hash=sha256:cd70574b12bb8a4d2aaa0094515df2463cb429d8536cfb6c7ce983246983e5a6 \ - --hash=sha256:d0eccceffcb53201b5bfebb52600a5fb483a20b61da9dbc885f8b103cbe7598c \ - --hash=sha256:d965bba47ddeec8cd560687584e88cf699fd28f192ceb452d1d7ee807c5597b7 \ - --hash=sha256:db364eca23f876da6f9e16c9da0df51aa4f104a972735574842618b8c6d999d4 \ - --hash=sha256:ddbb2551d7e0102e7252db79ba445cdab71b26640817ab1e3e3648dad515003b \ - --hash=sha256:deb6be0ac38ece9ba87dea880e438f25ca3eddfac8b002a2ec3d9183a454e8ae \ - --hash=sha256:e06ed3eb3218bc64786f7db41917d4e686cc4856944f53d5bdf83a6884432e12 \ - --hash=sha256:e27ad930a842b4c5eb8ac0016b0a54f5aebbe679340c26101df33424142c143c \ - --hash=sha256:e537484df0d8f426ce2afb2d0f8e1c3d0b114b83f8850e5f2fbea0e797bd82ae \ - --hash=sha256:eb00ed941194665c332bf8e078baf037d6c35d7c4f3102ea2d4f16ca94a26dc8 \ - --hash=sha256:eb6904c354526e758fda7167b33005998fb68c46fbc10e013ca97f21ca5c8887 \ - --hash=sha256:eb8821e09e916165e160797a6c17edda0679379a4be5c716c260e836e122f54b \ - --hash=sha256:efcb3f6676480691518c177e3b465bcddf57cea040302f9f4e6e191af91174d4 \ - --hash=sha256:f27273b60488abe721a075bcca6d7f3964f9f6f067c8c4c605743023d7d3944f \ - --hash=sha256:f30c3cb33b24454a82faecaf01b19c18562b1e89558fb6c56de4d9118a032fd5 \ - --hash=sha256:fb69256e180cb6c8a894fee62b3afebae785babc1ee98b81cdf68bbca1987f33 \ - --hash=sha256:fd1abc0d89e30cc4e02e4064dc67fcc51bd941eb395c502aac3ec19fab46b519 \ - --hash=sha256:ff8fa367d09b717b2a17a052544193ad76cd49979c805768879cb63d9ca50561 +charset-normalizer==3.4.0 \ + --hash=sha256:0099d79bdfcf5c1f0c2c72f91516702ebf8b0b8ddd8905f97a8aecf49712c621 \ + --hash=sha256:0713f3adb9d03d49d365b70b84775d0a0d18e4ab08d12bc46baa6132ba78aaf6 \ + --hash=sha256:07afec21bbbbf8a5cc3651aa96b980afe2526e7f048fdfb7f1014d84acc8b6d8 \ + --hash=sha256:0b309d1747110feb25d7ed6b01afdec269c647d382c857ef4663bbe6ad95a912 \ + --hash=sha256:0d99dd8ff461990f12d6e42c7347fd9ab2532fb70e9621ba520f9e8637161d7c \ + --hash=sha256:0de7b687289d3c1b3e8660d0741874abe7888100efe14bd0f9fd7141bcbda92b \ + --hash=sha256:1110e22af8ca26b90bd6364fe4c763329b0ebf1ee213ba32b68c73de5752323d \ + --hash=sha256:130272c698667a982a5d0e626851ceff662565379baf0ff2cc58067b81d4f11d \ + --hash=sha256:136815f06a3ae311fae551c3df1f998a1ebd01ddd424aa5603a4336997629e95 \ + --hash=sha256:14215b71a762336254351b00ec720a8e85cada43b987da5a042e4ce3e82bd68e \ + --hash=sha256:1db4e7fefefd0f548d73e2e2e041f9df5c59e178b4c72fbac4cc6f535cfb1565 \ + --hash=sha256:1ffd9493de4c922f2a38c2bf62b831dcec90ac673ed1ca182fe11b4d8e9f2a64 \ + --hash=sha256:2006769bd1640bdf4d5641c69a3d63b71b81445473cac5ded39740a226fa88ab \ + --hash=sha256:20587d20f557fe189b7947d8e7ec5afa110ccf72a3128d61a2a387c3313f46be \ + --hash=sha256:223217c3d4f82c3ac5e29032b3f1c2eb0fb591b72161f86d93f5719079dae93e \ + --hash=sha256:27623ba66c183eca01bf9ff833875b459cad267aeeb044477fedac35e19ba907 \ + --hash=sha256:285e96d9d53422efc0d7a17c60e59f37fbf3dfa942073f666db4ac71e8d726d0 \ + --hash=sha256:2de62e8801ddfff069cd5c504ce3bc9672b23266597d4e4f50eda28846c322f2 \ + --hash=sha256:2f6c34da58ea9c1a9515621f4d9ac379871a8f21168ba1b5e09d74250de5ad62 \ + --hash=sha256:309a7de0a0ff3040acaebb35ec45d18db4b28232f21998851cfa709eeff49d62 \ + --hash=sha256:35c404d74c2926d0287fbd63ed5d27eb911eb9e4a3bb2c6d294f3cfd4a9e0c23 \ + --hash=sha256:3710a9751938947e6327ea9f3ea6332a09bf0ba0c09cae9cb1f250bd1f1549bc \ + --hash=sha256:3d59d125ffbd6d552765510e3f31ed75ebac2c7470c7274195b9161a32350284 \ + --hash=sha256:40d3ff7fc90b98c637bda91c89d51264a3dcf210cade3a2c6f838c7268d7a4ca \ + --hash=sha256:425c5f215d0eecee9a56cdb703203dda90423247421bf0d67125add85d0c4455 \ + --hash=sha256:43193c5cda5d612f247172016c4bb71251c784d7a4d9314677186a838ad34858 \ + --hash=sha256:44aeb140295a2f0659e113b31cfe92c9061622cadbc9e2a2f7b8ef6b1e29ef4b \ + --hash=sha256:47334db71978b23ebcf3c0f9f5ee98b8d65992b65c9c4f2d34c2eaf5bcaf0594 \ + --hash=sha256:4796efc4faf6b53a18e3d46343535caed491776a22af773f366534056c4e1fbc \ + --hash=sha256:4a51b48f42d9358460b78725283f04bddaf44a9358197b889657deba38f329db \ + --hash=sha256:4b67fdab07fdd3c10bb21edab3cbfe8cf5696f453afce75d815d9d7223fbe88b \ + --hash=sha256:4ec9dd88a5b71abfc74e9df5ebe7921c35cbb3b641181a531ca65cdb5e8e4dea \ + --hash=sha256:4f9fc98dad6c2eaa32fc3af1417d95b5e3d08aff968df0cd320066def971f9a6 \ + --hash=sha256:54b6a92d009cbe2fb11054ba694bc9e284dad30a26757b1e372a1fdddaf21920 \ + --hash=sha256:55f56e2ebd4e3bc50442fbc0888c9d8c94e4e06a933804e2af3e89e2f9c1c749 \ + --hash=sha256:5726cf76c982532c1863fb64d8c6dd0e4c90b6ece9feb06c9f202417a31f7dd7 \ + --hash=sha256:5d447056e2ca60382d460a604b6302d8db69476fd2015c81e7c35417cfabe4cd \ + --hash=sha256:5ed2e36c3e9b4f21dd9422f6893dec0abf2cca553af509b10cd630f878d3eb99 \ + --hash=sha256:5ff2ed8194587faf56555927b3aa10e6fb69d931e33953943bc4f837dfee2242 \ + --hash=sha256:62f60aebecfc7f4b82e3f639a7d1433a20ec32824db2199a11ad4f5e146ef5ee \ + --hash=sha256:63bc5c4ae26e4bc6be6469943b8253c0fd4e4186c43ad46e713ea61a0ba49129 \ + --hash=sha256:6b40e8d38afe634559e398cc32b1472f376a4099c75fe6299ae607e404c033b2 \ + --hash=sha256:6b493a043635eb376e50eedf7818f2f322eabbaa974e948bd8bdd29eb7ef2a51 \ + --hash=sha256:6dba5d19c4dfab08e58d5b36304b3f92f3bd5d42c1a3fa37b5ba5cdf6dfcbcee \ + --hash=sha256:6fd30dc99682dc2c603c2b315bded2799019cea829f8bf57dc6b61efde6611c8 \ + --hash=sha256:707b82d19e65c9bd28b81dde95249b07bf9f5b90ebe1ef17d9b57473f8a64b7b \ + --hash=sha256:7706f5850360ac01d80c89bcef1640683cc12ed87f42579dab6c5d3ed6888613 \ + --hash=sha256:7782afc9b6b42200f7362858f9e73b1f8316afb276d316336c0ec3bd73312742 \ + --hash=sha256:79983512b108e4a164b9c8d34de3992f76d48cadc9554c9e60b43f308988aabe \ + --hash=sha256:7f683ddc7eedd742e2889d2bfb96d69573fde1d92fcb811979cdb7165bb9c7d3 \ + --hash=sha256:82357d85de703176b5587dbe6ade8ff67f9f69a41c0733cf2425378b49954de5 \ + --hash=sha256:84450ba661fb96e9fd67629b93d2941c871ca86fc38d835d19d4225ff946a631 \ + --hash=sha256:86f4e8cca779080f66ff4f191a685ced73d2f72d50216f7112185dc02b90b9b7 \ + --hash=sha256:8cda06946eac330cbe6598f77bb54e690b4ca93f593dee1568ad22b04f347c15 \ + --hash=sha256:8ce7fd6767a1cc5a92a639b391891bf1c268b03ec7e021c7d6d902285259685c \ + --hash=sha256:8ff4e7cdfdb1ab5698e675ca622e72d58a6fa2a8aa58195de0c0061288e6e3ea \ + --hash=sha256:9289fd5dddcf57bab41d044f1756550f9e7cf0c8e373b8cdf0ce8773dc4bd417 \ + --hash=sha256:92a7e36b000bf022ef3dbb9c46bfe2d52c047d5e3f3343f43204263c5addc250 \ + --hash=sha256:92db3c28b5b2a273346bebb24857fda45601aef6ae1c011c0a997106581e8a88 \ + --hash=sha256:95c3c157765b031331dd4db3c775e58deaee050a3042fcad72cbc4189d7c8dca \ + --hash=sha256:980b4f289d1d90ca5efcf07958d3eb38ed9c0b7676bf2831a54d4f66f9c27dfa \ + --hash=sha256:9ae4ef0b3f6b41bad6366fb0ea4fc1d7ed051528e113a60fa2a65a9abb5b1d99 \ + --hash=sha256:9c98230f5042f4945f957d006edccc2af1e03ed5e37ce7c373f00a5a4daa6149 \ + --hash=sha256:9fa2566ca27d67c86569e8c85297aaf413ffab85a8960500f12ea34ff98e4c41 \ + --hash=sha256:a14969b8691f7998e74663b77b4c36c0337cb1df552da83d5c9004a93afdb574 \ + --hash=sha256:a8aacce6e2e1edcb6ac625fb0f8c3a9570ccc7bfba1f63419b3769ccf6a00ed0 \ + --hash=sha256:a8e538f46104c815be19c975572d74afb53f29650ea2025bbfaef359d2de2f7f \ + --hash=sha256:aa41e526a5d4a9dfcfbab0716c7e8a1b215abd3f3df5a45cf18a12721d31cb5d \ + --hash=sha256:aa693779a8b50cd97570e5a0f343538a8dbd3e496fa5dcb87e29406ad0299654 \ + --hash=sha256:ab22fbd9765e6954bc0bcff24c25ff71dcbfdb185fcdaca49e81bac68fe724d3 \ + --hash=sha256:ab2e5bef076f5a235c3774b4f4028a680432cded7cad37bba0fd90d64b187d19 \ + --hash=sha256:ab973df98fc99ab39080bfb0eb3a925181454d7c3ac8a1e695fddfae696d9e90 \ + --hash=sha256:af73657b7a68211996527dbfeffbb0864e043d270580c5aef06dc4b659a4b578 \ + --hash=sha256:b197e7094f232959f8f20541ead1d9862ac5ebea1d58e9849c1bf979255dfac9 \ + --hash=sha256:b295729485b06c1a0683af02a9e42d2caa9db04a373dc38a6a58cdd1e8abddf1 \ + --hash=sha256:b8831399554b92b72af5932cdbbd4ddc55c55f631bb13ff8fe4e6536a06c5c51 \ + --hash=sha256:b8dcd239c743aa2f9c22ce674a145e0a25cb1566c495928440a181ca1ccf6719 \ + --hash=sha256:bcb4f8ea87d03bc51ad04add8ceaf9b0f085ac045ab4d74e73bbc2dc033f0236 \ + --hash=sha256:bd7af3717683bea4c87acd8c0d3d5b44d56120b26fd3f8a692bdd2d5260c620a \ + --hash=sha256:bf4475b82be41b07cc5e5ff94810e6a01f276e37c2d55571e3fe175e467a1a1c \ + --hash=sha256:c3e446d253bd88f6377260d07c895816ebf33ffffd56c1c792b13bff9c3e1ade \ + --hash=sha256:c57516e58fd17d03ebe67e181a4e4e2ccab1168f8c2976c6a334d4f819fe5944 \ + --hash=sha256:c94057af19bc953643a33581844649a7fdab902624d2eb739738a30e2b3e60fc \ + --hash=sha256:cab5d0b79d987c67f3b9e9c53f54a61360422a5a0bc075f43cab5621d530c3b6 \ + --hash=sha256:ce031db0408e487fd2775d745ce30a7cd2923667cf3b69d48d219f1d8f5ddeb6 \ + --hash=sha256:cee4373f4d3ad28f1ab6290684d8e2ebdb9e7a1b74fdc39e4c211995f77bec27 \ + --hash=sha256:d5b054862739d276e09928de37c79ddeec42a6e1bfc55863be96a36ba22926f6 \ + --hash=sha256:dbe03226baf438ac4fda9e2d0715022fd579cb641c4cf639fa40d53b2fe6f3e2 \ + --hash=sha256:dc15e99b2d8a656f8e666854404f1ba54765871104e50c8e9813af8a7db07f12 \ + --hash=sha256:dcaf7c1524c0542ee2fc82cc8ec337f7a9f7edee2532421ab200d2b920fc97cf \ + --hash=sha256:dd4eda173a9fcccb5f2e2bd2a9f423d180194b1bf17cf59e3269899235b2a114 \ + --hash=sha256:dd9a8bd8900e65504a305bf8ae6fa9fbc66de94178c420791d0293702fce2df7 \ + --hash=sha256:de7376c29d95d6719048c194a9cf1a1b0393fbe8488a22008610b0361d834ecf \ + --hash=sha256:e7fdd52961feb4c96507aa649550ec2a0d527c086d284749b2f582f2d40a2e0d \ + --hash=sha256:e91f541a85298cf35433bf66f3fab2a4a2cff05c127eeca4af174f6d497f0d4b \ + --hash=sha256:e9e3c4c9e1ed40ea53acf11e2a386383c3304212c965773704e4603d589343ed \ + --hash=sha256:ee803480535c44e7f5ad00788526da7d85525cfefaf8acf8ab9a310000be4b03 \ + --hash=sha256:f09cb5a7bbe1ecae6e87901a2eb23e0256bb524a79ccc53eb0b7629fbe7677c4 \ + --hash=sha256:f19c1585933c82098c2a520f8ec1227f20e339e33aca8fa6f956f6691b784e67 \ + --hash=sha256:f1a2f519ae173b5b6a2c9d5fa3116ce16e48b3462c8b96dfdded11055e3d6365 \ + --hash=sha256:f28f891ccd15c514a0981f3b9db9aa23d62fe1a99997512b0491d2ed323d229a \ + --hash=sha256:f3e73a4255342d4eb26ef6df01e3962e73aa29baa3124a8e824c5d3364a65748 \ + --hash=sha256:f606a1881d2663630ea5b8ce2efe2111740df4b687bd78b34a8131baa007f79b \ + --hash=sha256:fe9f97feb71aa9896b81973a7bbada8c49501dc73e58a10fcef6663af95e5079 \ + --hash=sha256:ffc519621dce0c767e96b9c53f09c5d215578e10b02c285809f76509a3931482 # via requests click==8.1.7 \ --hash=sha256:ae74fb96c20a0277a1d615f1e4d73c8414f5a98db8b799a7931d1582f3390c28 \ @@ -173,87 +188,77 @@ click==8.1.7 \ # -r lock/requirements-dev-template.in # typer # uvicorn -coverage==7.6.1 \ - --hash=sha256:06a737c882bd26d0d6ee7269b20b12f14a8704807a01056c80bb881a4b2ce6ca \ - --hash=sha256:07e2ca0ad381b91350c0ed49d52699b625aab2b44b65e1b4e02fa9df0e92ad2d \ - --hash=sha256:0c0420b573964c760df9e9e86d1a9a622d0d27f417e1a949a8a66dd7bcee7bc6 \ - --hash=sha256:0dbde0f4aa9a16fa4d754356a8f2e36296ff4d83994b2c9d8398aa32f222f989 \ - --hash=sha256:1125ca0e5fd475cbbba3bb67ae20bd2c23a98fac4e32412883f9bcbaa81c314c \ - --hash=sha256:13b0a73a0896988f053e4fbb7de6d93388e6dd292b0d87ee51d106f2c11b465b \ - --hash=sha256:166811d20dfea725e2e4baa71fffd6c968a958577848d2131f39b60043400223 \ - --hash=sha256:170d444ab405852903b7d04ea9ae9b98f98ab6d7e63e1115e82620807519797f \ - --hash=sha256:1f4aa8219db826ce6be7099d559f8ec311549bfc4046f7f9fe9b5cea5c581c56 \ - --hash=sha256:225667980479a17db1048cb2bf8bfb39b8e5be8f164b8f6628b64f78a72cf9d3 \ - --hash=sha256:260933720fdcd75340e7dbe9060655aff3af1f0c5d20f46b57f262ab6c86a5e8 \ - --hash=sha256:2bdb062ea438f22d99cba0d7829c2ef0af1d768d1e4a4f528087224c90b132cb \ - --hash=sha256:2c09f4ce52cb99dd7505cd0fc8e0e37c77b87f46bc9c1eb03fe3bc9991085388 \ - --hash=sha256:3115a95daa9bdba70aea750db7b96b37259a81a709223c8448fa97727d546fe0 \ - --hash=sha256:3e0cadcf6733c09154b461f1ca72d5416635e5e4ec4e536192180d34ec160f8a \ - --hash=sha256:3f1156e3e8f2872197af3840d8ad307a9dd18e615dc64d9ee41696f287c57ad8 \ - --hash=sha256:4421712dbfc5562150f7554f13dde997a2e932a6b5f352edcce948a815efee6f \ - --hash=sha256:44df346d5215a8c0e360307d46ffaabe0f5d3502c8a1cefd700b34baf31d411a \ - --hash=sha256:502753043567491d3ff6d08629270127e0c31d4184c4c8d98f92c26f65019962 \ - --hash=sha256:547f45fa1a93154bd82050a7f3cddbc1a7a4dd2a9bf5cb7d06f4ae29fe94eaf8 \ - --hash=sha256:5621a9175cf9d0b0c84c2ef2b12e9f5f5071357c4d2ea6ca1cf01814f45d2391 \ - --hash=sha256:609b06f178fe8e9f89ef676532760ec0b4deea15e9969bf754b37f7c40326dbc \ - --hash=sha256:645786266c8f18a931b65bfcefdbf6952dd0dea98feee39bd188607a9d307ed2 \ - --hash=sha256:6878ef48d4227aace338d88c48738a4258213cd7b74fd9a3d4d7582bb1d8a155 \ - --hash=sha256:6a89ecca80709d4076b95f89f308544ec8f7b4727e8a547913a35f16717856cb \ - --hash=sha256:6db04803b6c7291985a761004e9060b2bca08da6d04f26a7f2294b8623a0c1a0 \ - --hash=sha256:6e2cd258d7d927d09493c8df1ce9174ad01b381d4729a9d8d4e38670ca24774c \ - --hash=sha256:6e81d7a3e58882450ec4186ca59a3f20a5d4440f25b1cff6f0902ad890e6748a \ - --hash=sha256:702855feff378050ae4f741045e19a32d57d19f3e0676d589df0575008ea5004 \ - --hash=sha256:78b260de9790fd81e69401c2dc8b17da47c8038176a79092a89cb2b7d945d060 \ - --hash=sha256:7bb65125fcbef8d989fa1dd0e8a060999497629ca5b0efbca209588a73356232 \ - --hash=sha256:7dea0889685db8550f839fa202744652e87c60015029ce3f60e006f8c4462c93 \ - --hash=sha256:8284cf8c0dd272a247bc154eb6c95548722dce90d098c17a883ed36e67cdb129 \ - --hash=sha256:877abb17e6339d96bf08e7a622d05095e72b71f8afd8a9fefc82cf30ed944163 \ - --hash=sha256:8929543a7192c13d177b770008bc4e8119f2e1f881d563fc6b6305d2d0ebe9de \ - --hash=sha256:8ae539519c4c040c5ffd0632784e21b2f03fc1340752af711f33e5be83a9d6c6 \ - --hash=sha256:8f59d57baca39b32db42b83b2a7ba6f47ad9c394ec2076b084c3f029b7afca23 \ - --hash=sha256:9054a0754de38d9dbd01a46621636689124d666bad1936d76c0341f7d71bf569 \ - --hash=sha256:953510dfb7b12ab69d20135a0662397f077c59b1e6379a768e97c59d852ee51d \ - --hash=sha256:95cae0efeb032af8458fc27d191f85d1717b1d4e49f7cb226cf526ff28179778 \ - --hash=sha256:9bc572be474cafb617672c43fe989d6e48d3c83af02ce8de73fff1c6bb3c198d \ - --hash=sha256:9c56863d44bd1c4fe2abb8a4d6f5371d197f1ac0ebdee542f07f35895fc07f36 \ - --hash=sha256:9e0b2df163b8ed01d515807af24f63de04bebcecbd6c3bfeff88385789fdf75a \ - --hash=sha256:a09ece4a69cf399510c8ab25e0950d9cf2b42f7b3cb0374f95d2e2ff594478a6 \ - --hash=sha256:a1ac0ae2b8bd743b88ed0502544847c3053d7171a3cff9228af618a068ed9c34 \ - --hash=sha256:a318d68e92e80af8b00fa99609796fdbcdfef3629c77c6283566c6f02c6d6704 \ - --hash=sha256:a4acd025ecc06185ba2b801f2de85546e0b8ac787cf9d3b06e7e2a69f925b106 \ - --hash=sha256:a6d3adcf24b624a7b778533480e32434a39ad8fa30c315208f6d3e5542aeb6e9 \ - --hash=sha256:a78d169acd38300060b28d600344a803628c3fd585c912cacc9ea8790fe96862 \ - --hash=sha256:a95324a9de9650a729239daea117df21f4b9868ce32e63f8b650ebe6cef5595b \ - --hash=sha256:abd5fd0db5f4dc9289408aaf34908072f805ff7792632250dcb36dc591d24255 \ - --hash=sha256:b06079abebbc0e89e6163b8e8f0e16270124c154dc6e4a47b413dd538859af16 \ - --hash=sha256:b43c03669dc4618ec25270b06ecd3ee4fa94c7f9b3c14bae6571ca00ef98b0d3 \ - --hash=sha256:b48f312cca9621272ae49008c7f613337c53fadca647d6384cc129d2996d1133 \ - --hash=sha256:b5d7b556859dd85f3a541db6a4e0167b86e7273e1cdc973e5b175166bb634fdb \ - --hash=sha256:b9f222de8cded79c49bf184bdbc06630d4c58eec9459b939b4a690c82ed05657 \ - --hash=sha256:c3c02d12f837d9683e5ab2f3d9844dc57655b92c74e286c262e0fc54213c216d \ - --hash=sha256:c44fee9975f04b33331cb8eb272827111efc8930cfd582e0320613263ca849ca \ - --hash=sha256:cf4b19715bccd7ee27b6b120e7e9dd56037b9c0681dcc1adc9ba9db3d417fa36 \ - --hash=sha256:d0c212c49b6c10e6951362f7c6df3329f04c2b1c28499563d4035d964ab8e08c \ - --hash=sha256:d3296782ca4eab572a1a4eca686d8bfb00226300dcefdf43faa25b5242ab8a3e \ - --hash=sha256:d85f5e9a5f8b73e2350097c3756ef7e785f55bd71205defa0bfdaf96c31616ff \ - --hash=sha256:da511e6ad4f7323ee5702e6633085fb76c2f893aaf8ce4c51a0ba4fc07580ea7 \ - --hash=sha256:e05882b70b87a18d937ca6768ff33cc3f72847cbc4de4491c8e73880766718e5 \ - --hash=sha256:e61c0abb4c85b095a784ef23fdd4aede7a2628478e7baba7c5e3deba61070a02 \ - --hash=sha256:e6a08c0be454c3b3beb105c0596ebdc2371fab6bb90c0c0297f4e58fd7e1012c \ - --hash=sha256:e9a6e0eb86070e8ccaedfbd9d38fec54864f3125ab95419970575b42af7541df \ - --hash=sha256:ed37bd3c3b063412f7620464a9ac1314d33100329f39799255fb8d3027da50d3 \ - --hash=sha256:f1adfc8ac319e1a348af294106bc6a8458a0f1633cc62a1446aebc30c5fa186a \ - --hash=sha256:f5796e664fe802da4f57a168c85359a8fbf3eab5e55cd4e4569fbacecc903959 \ - --hash=sha256:fc5a77d0c516700ebad189b587de289a20a78324bc54baee03dd486f0855d234 \ - --hash=sha256:fd21f6ae3f08b41004dfb433fa895d858f3f5979e7762d052b12aef444e29afc +coverage==7.6.4 \ + --hash=sha256:00a1d69c112ff5149cabe60d2e2ee948752c975d95f1e1096742e6077affd376 \ + --hash=sha256:023bf8ee3ec6d35af9c1c6ccc1d18fa69afa1cb29eaac57cb064dbb262a517f9 \ + --hash=sha256:0294ca37f1ba500667b1aef631e48d875ced93ad5e06fa665a3295bdd1d95111 \ + --hash=sha256:06babbb8f4e74b063dbaeb74ad68dfce9186c595a15f11f5d5683f748fa1d172 \ + --hash=sha256:0809082ee480bb8f7416507538243c8863ac74fd8a5d2485c46f0f7499f2b491 \ + --hash=sha256:0b3fb02fe73bed561fa12d279a417b432e5b50fe03e8d663d61b3d5990f29546 \ + --hash=sha256:0b58c672d14f16ed92a48db984612f5ce3836ae7d72cdd161001cc54512571f2 \ + --hash=sha256:0bcd1069e710600e8e4cf27f65c90c7843fa8edfb4520fb0ccb88894cad08b11 \ + --hash=sha256:1032e178b76a4e2b5b32e19d0fd0abbce4b58e77a1ca695820d10e491fa32b08 \ + --hash=sha256:11a223a14e91a4693d2d0755c7a043db43d96a7450b4f356d506c2562c48642c \ + --hash=sha256:12394842a3a8affa3ba62b0d4ab7e9e210c5e366fbac3e8b2a68636fb19892c2 \ + --hash=sha256:182e6cd5c040cec0a1c8d415a87b67ed01193ed9ad458ee427741c7d8513d963 \ + --hash=sha256:1d5b8007f81b88696d06f7df0cb9af0d3b835fe0c8dbf489bad70b45f0e45613 \ + --hash=sha256:1f76846299ba5c54d12c91d776d9605ae33f8ae2b9d1d3c3703cf2db1a67f2c0 \ + --hash=sha256:27fb4a050aaf18772db513091c9c13f6cb94ed40eacdef8dad8411d92d9992db \ + --hash=sha256:29155cd511ee058e260db648b6182c419422a0d2e9a4fa44501898cf918866cf \ + --hash=sha256:29fc0f17b1d3fea332f8001d4558f8214af7f1d87a345f3a133c901d60347c73 \ + --hash=sha256:2b6b4c83d8e8ea79f27ab80778c19bc037759aea298da4b56621f4474ffeb117 \ + --hash=sha256:2fdef0d83a2d08d69b1f2210a93c416d54e14d9eb398f6ab2f0a209433db19e1 \ + --hash=sha256:3c65d37f3a9ebb703e710befdc489a38683a5b152242664b973a7b7b22348a4e \ + --hash=sha256:4f704f0998911abf728a7783799444fcbbe8261c4a6c166f667937ae6a8aa522 \ + --hash=sha256:51b44306032045b383a7a8a2c13878de375117946d68dcb54308111f39775a25 \ + --hash=sha256:53d202fd109416ce011578f321460795abfe10bb901b883cafd9b3ef851bacfc \ + --hash=sha256:58809e238a8a12a625c70450b48e8767cff9eb67c62e6154a642b21ddf79baea \ + --hash=sha256:5915fcdec0e54ee229926868e9b08586376cae1f5faa9bbaf8faf3561b393d52 \ + --hash=sha256:5beb1ee382ad32afe424097de57134175fea3faf847b9af002cc7895be4e2a5a \ + --hash=sha256:5f8ae553cba74085db385d489c7a792ad66f7f9ba2ee85bfa508aeb84cf0ba07 \ + --hash=sha256:5fbd612f8a091954a0c8dd4c0b571b973487277d26476f8480bfa4b2a65b5d06 \ + --hash=sha256:6bd818b7ea14bc6e1f06e241e8234508b21edf1b242d49831831a9450e2f35fa \ + --hash=sha256:6f01ba56b1c0e9d149f9ac85a2f999724895229eb36bd997b61e62999e9b0901 \ + --hash=sha256:73d2b73584446e66ee633eaad1a56aad577c077f46c35ca3283cd687b7715b0b \ + --hash=sha256:7bb92c539a624cf86296dd0c68cd5cc286c9eef2d0c3b8b192b604ce9de20a17 \ + --hash=sha256:8165b796df0bd42e10527a3f493c592ba494f16ef3c8b531288e3d0d72c1f6f0 \ + --hash=sha256:862264b12ebb65ad8d863d51f17758b1684560b66ab02770d4f0baf2ff75da21 \ + --hash=sha256:8902dd6a30173d4ef09954bfcb24b5d7b5190cf14a43170e386979651e09ba19 \ + --hash=sha256:8cf717ee42012be8c0cb205dbbf18ffa9003c4cbf4ad078db47b95e10748eec5 \ + --hash=sha256:8ed9281d1b52628e81393f5eaee24a45cbd64965f41857559c2b7ff19385df51 \ + --hash=sha256:99b41d18e6b2a48ba949418db48159d7a2e81c5cc290fc934b7d2380515bd0e3 \ + --hash=sha256:9cb7fa111d21a6b55cbf633039f7bc2749e74932e3aa7cb7333f675a58a58bf3 \ + --hash=sha256:a181e99301a0ae128493a24cfe5cfb5b488c4e0bf2f8702091473d033494d04f \ + --hash=sha256:a413a096c4cbac202433c850ee43fa326d2e871b24554da8327b01632673a076 \ + --hash=sha256:a6b1e54712ba3474f34b7ef7a41e65bd9037ad47916ccb1cc78769bae324c01a \ + --hash=sha256:ade3ca1e5f0ff46b678b66201f7ff477e8fa11fb537f3b55c3f0568fbfe6e718 \ + --hash=sha256:b0ac3d42cb51c4b12df9c5f0dd2f13a4f24f01943627120ec4d293c9181219ba \ + --hash=sha256:b369ead6527d025a0fe7bd3864e46dbee3aa8f652d48df6174f8d0bac9e26e0e \ + --hash=sha256:b57b768feb866f44eeed9f46975f3d6406380275c5ddfe22f531a2bf187eda27 \ + --hash=sha256:b8d3a03d9bfcaf5b0141d07a88456bb6a4c3ce55c080712fec8418ef3610230e \ + --hash=sha256:bc66f0bf1d7730a17430a50163bb264ba9ded56739112368ba985ddaa9c3bd09 \ + --hash=sha256:bf20494da9653f6410213424f5f8ad0ed885e01f7e8e59811f572bdb20b8972e \ + --hash=sha256:c48167910a8f644671de9f2083a23630fbf7a1cb70ce939440cd3328e0919f70 \ + --hash=sha256:c481b47f6b5845064c65a7bc78bc0860e635a9b055af0df46fdf1c58cebf8e8f \ + --hash=sha256:c7c8b95bf47db6d19096a5e052ffca0a05f335bc63cef281a6e8fe864d450a72 \ + --hash=sha256:c9b8e184898ed014884ca84c70562b4a82cbc63b044d366fedc68bc2b2f3394a \ + --hash=sha256:cc8ff50b50ce532de2fa7a7daae9dd12f0a699bfcd47f20945364e5c31799fef \ + --hash=sha256:d541423cdd416b78626b55f123412fcf979d22a2c39fce251b350de38c15c15b \ + --hash=sha256:dab4d16dfef34b185032580e2f2f89253d302facba093d5fa9dbe04f569c4f4b \ + --hash=sha256:dacbc52de979f2823a819571f2e3a350a7e36b8cb7484cdb1e289bceaf35305f \ + --hash=sha256:df57bdbeffe694e7842092c5e2e0bc80fff7f43379d465f932ef36f027179806 \ + --hash=sha256:ed8fe9189d2beb6edc14d3ad19800626e1d9f2d975e436f84e19efb7fa19469b \ + --hash=sha256:f3ddf056d3ebcf6ce47bdaf56142af51bb7fad09e4af310241e9db7a3a8022e1 \ + --hash=sha256:f8fe4984b431f8621ca53d9380901f62bfb54ff759a1348cd140490ada7b693c \ + --hash=sha256:fe439416eb6380de434886b00c859304338f8b19f6f54811984f3420a2e03858 # via pytest-cov -distlib==0.3.8 \ - --hash=sha256:034db59a0b96f8ca18035f36290806a9a6e6bd9d1ff91e45a7f172eb17e51784 \ - --hash=sha256:1530ea13e350031b6312d8580ddb6b27a104275a31106523b8f123787f494f64 +distlib==0.3.9 \ + --hash=sha256:47f8c22fd27c27e25a65601af709b38e4f0a45ea4fc2e710f65755fa8caaaf87 \ + --hash=sha256:a60f20dea646b8a33f3e7772f74dc0b2d0772d2837ee1342a00645c81edf9403 # via virtualenv -dnspython==2.6.1 \ - --hash=sha256:5ef3b9680161f6fa89daf8ad451b5f1a33b18ae8a1c6778cdf4b43f08c0a6e50 \ - --hash=sha256:e8f0f9c23a7b7cb99ded64e6c3a6f3e701d78f50c55e002b839dea7225cff7cc +dnspython==2.7.0 \ + --hash=sha256:b4c34b7d10b51bcc3a5071e7b8dee77939f1e878477eeecc965e9835f63c6c86 \ + --hash=sha256:ce9c432eda0dc91cf618a5cedf1a4e142651196bbcd2c80e89ed5a907e5cfaf1 # via # email-validator # pymongo @@ -273,9 +278,9 @@ fastapi-cli==0.0.5 \ --hash=sha256:d30e1239c6f46fcb95e606f02cdda59a1e2fa778a54b64686b3ff27f6211ff9f \ --hash=sha256:e94d847524648c748a5350673546bbf9bcaeb086b33c24f2e82e021436866a46 # via fastapi -filelock==3.15.4 \ - --hash=sha256:2207938cbc1844345cb01a5a95524dae30f0ce089eba5b00378295a17e3e90cb \ - --hash=sha256:6ca1fffae96225dab4c6eaf1c4f4f28cd2568d3ec2a44e15a08520504de468e7 +filelock==3.16.1 \ + --hash=sha256:2082e5703d51fbf98ea75855d9d5527e33d8ff23099bec374a134febee6946b0 \ + --hash=sha256:c249fbfcd5db47e5e2d6d62198e565475ee65e4831e2561c8e313fa7eb961435 # via virtualenv ghga-service-commons==3.1.5 \ --hash=sha256:6650167f9fe21d683d7f7bd81320f3301f6624f6c71d7e633fbf5f0a3453d973 \ @@ -287,68 +292,75 @@ h11==0.14.0 \ # via # httpcore # uvicorn -hexkit==3.5.0 \ - --hash=sha256:30a82d170630a615836d6a42116f10a2052a9ae752137419f6abe1286a113a32 \ - --hash=sha256:b27599809b94f24e87153667afd9a72f46c46d267c06cafc595d40cdc6c53f89 +hexkit==3.6.0 \ + --hash=sha256:0f650bf87a95c91ddffa20f1c5c130b2c5aad719cb5031bf6c7ea60fa8f136c1 \ + --hash=sha256:70d8159565b43ce4fa54bb471a0cd873517162fb27a056e30613c4332822500b # via # sms (pyproject.toml) # ghga-service-commons -httpcore==1.0.5 \ - --hash=sha256:34a38e2f9291467ee3b44e89dd52615370e152954ba21721378a87b2960f7a61 \ - --hash=sha256:421f18bac248b25d310f3cacd198d55b8e6125c107797b609ff9b7a6ba7991b5 +httpcore==1.0.6 \ + --hash=sha256:27b59625743b85577a8c0e10e55b50b5368a4f2cfe8cc7bcfa9cf00829c2682f \ + --hash=sha256:73f6dbd6eb8c21bbf7ef8efad555481853f5f6acdeaff1edb0694289269ee17f # via httpx -httptools==0.6.1 \ - --hash=sha256:00d5d4b68a717765b1fabfd9ca755bd12bf44105eeb806c03d1962acd9b8e563 \ - --hash=sha256:0ac5a0ae3d9f4fe004318d64b8a854edd85ab76cffbf7ef5e32920faef62f142 \ - --hash=sha256:0cf2372e98406efb42e93bfe10f2948e467edfd792b015f1b4ecd897903d3e8d \ - --hash=sha256:1ed99a373e327f0107cb513b61820102ee4f3675656a37a50083eda05dc9541b \ - --hash=sha256:3c3b214ce057c54675b00108ac42bacf2ab8f85c58e3f324a4e963bbc46424f4 \ - --hash=sha256:3e802e0b2378ade99cd666b5bffb8b2a7cc8f3d28988685dc300469ea8dd86cb \ - --hash=sha256:3f30d3ce413088a98b9db71c60a6ada2001a08945cb42dd65a9a9fe228627658 \ - --hash=sha256:405784577ba6540fa7d6ff49e37daf104e04f4b4ff2d1ac0469eaa6a20fde084 \ - --hash=sha256:48ed8129cd9a0d62cf4d1575fcf90fb37e3ff7d5654d3a5814eb3d55f36478c2 \ - --hash=sha256:4bd3e488b447046e386a30f07af05f9b38d3d368d1f7b4d8f7e10af85393db97 \ - --hash=sha256:4f0f8271c0a4db459f9dc807acd0eadd4839934a4b9b892f6f160e94da309837 \ - --hash=sha256:5cceac09f164bcba55c0500a18fe3c47df29b62353198e4f37bbcc5d591172c3 \ - --hash=sha256:639dc4f381a870c9ec860ce5c45921db50205a37cc3334e756269736ff0aac58 \ - --hash=sha256:678fcbae74477a17d103b7cae78b74800d795d702083867ce160fc202104d0da \ - --hash=sha256:6a4f5ccead6d18ec072ac0b84420e95d27c1cdf5c9f1bc8fbd8daf86bd94f43d \ - --hash=sha256:6f58e335a1402fb5a650e271e8c2d03cfa7cea46ae124649346d17bd30d59c90 \ - --hash=sha256:75c8022dca7935cba14741a42744eee13ba05db00b27a4b940f0d646bd4d56d0 \ - --hash=sha256:7a7ea483c1a4485c71cb5f38be9db078f8b0e8b4c4dc0210f531cdd2ddac1ef1 \ - --hash=sha256:7d9ceb2c957320def533671fc9c715a80c47025139c8d1f3797477decbc6edd2 \ - --hash=sha256:7ebaec1bf683e4bf5e9fbb49b8cc36da482033596a415b3e4ebab5a4c0d7ec5e \ - --hash=sha256:85ed077c995e942b6f1b07583e4eb0a8d324d418954fc6af913d36db7c05a5a0 \ - --hash=sha256:8ae5b97f690badd2ca27cbf668494ee1b6d34cf1c464271ef7bfa9ca6b83ffaf \ - --hash=sha256:8b0bb634338334385351a1600a73e558ce619af390c2b38386206ac6a27fecfc \ - --hash=sha256:8e216a038d2d52ea13fdd9b9c9c7459fb80d78302b257828285eca1c773b99b3 \ - --hash=sha256:93ad80d7176aa5788902f207a4e79885f0576134695dfb0fefc15b7a4648d503 \ - --hash=sha256:95658c342529bba4e1d3d2b1a874db16c7cca435e8827422154c9da76ac4e13a \ - --hash=sha256:95fb92dd3649f9cb139e9c56604cc2d7c7bf0fc2e7c8d7fbd58f96e35eddd2a3 \ - --hash=sha256:97662ce7fb196c785344d00d638fc9ad69e18ee4bfb4000b35a52efe5adcc949 \ - --hash=sha256:9bb68d3a085c2174c2477eb3ffe84ae9fb4fde8792edb7bcd09a1d8467e30a84 \ - --hash=sha256:b512aa728bc02354e5ac086ce76c3ce635b62f5fbc32ab7082b5e582d27867bb \ - --hash=sha256:c6e26c30455600b95d94b1b836085138e82f177351454ee841c148f93a9bad5a \ - --hash=sha256:d2f6c3c4cb1948d912538217838f6e9960bc4a521d7f9b323b3da579cd14532f \ - --hash=sha256:dcbab042cc3ef272adc11220517278519adf8f53fd3056d0e68f0a6f891ba94e \ - --hash=sha256:e0b281cf5a125c35f7f6722b65d8542d2e57331be573e9e88bc8b0115c4a7a81 \ - --hash=sha256:e57997ac7fb7ee43140cc03664de5f268813a481dff6245e0075925adc6aa185 \ - --hash=sha256:fe467eb086d80217b7584e61313ebadc8d187a4d95bb62031b7bab4b205c3ba3 +httptools==0.6.4 \ + --hash=sha256:0614154d5454c21b6410fdf5262b4a3ddb0f53f1e1721cfd59d55f32138c578a \ + --hash=sha256:0e563e54979e97b6d13f1bbc05a96109923e76b901f786a5eae36e99c01237bd \ + --hash=sha256:16e603a3bff50db08cd578d54f07032ca1631450ceb972c2f834c2b860c28ea2 \ + --hash=sha256:288cd628406cc53f9a541cfaf06041b4c71d751856bab45e3702191f931ccd17 \ + --hash=sha256:28908df1b9bb8187393d5b5db91435ccc9c8e891657f9cbb42a2541b44c82fc8 \ + --hash=sha256:322d20ea9cdd1fa98bd6a74b77e2ec5b818abdc3d36695ab402a0de8ef2865a3 \ + --hash=sha256:342dd6946aa6bda4b8f18c734576106b8a31f2fe31492881a9a160ec84ff4bd5 \ + --hash=sha256:345c288418f0944a6fe67be8e6afa9262b18c7626c3ef3c28adc5eabc06a68da \ + --hash=sha256:3c73ce323711a6ffb0d247dcd5a550b8babf0f757e86a52558fe5b86d6fefcc0 \ + --hash=sha256:40a5ec98d3f49904b9fe36827dcf1aadfef3b89e2bd05b0e35e94f97c2b14721 \ + --hash=sha256:40b0f7fe4fd38e6a507bdb751db0379df1e99120c65fbdc8ee6c1d044897a636 \ + --hash=sha256:40dc6a8e399e15ea525305a2ddba998b0af5caa2566bcd79dcbe8948181eeaff \ + --hash=sha256:4b36913ba52008249223042dca46e69967985fb4051951f94357ea681e1f5dc0 \ + --hash=sha256:4d87b29bd4486c0093fc64dea80231f7c7f7eb4dc70ae394d70a495ab8436071 \ + --hash=sha256:4e93eee4add6493b59a5c514da98c939b244fce4a0d8879cd3f466562f4b7d5c \ + --hash=sha256:59e724f8b332319e2875efd360e61ac07f33b492889284a3e05e6d13746876f4 \ + --hash=sha256:69422b7f458c5af875922cdb5bd586cc1f1033295aa9ff63ee196a87519ac8e1 \ + --hash=sha256:703c346571fa50d2e9856a37d7cd9435a25e7fd15e236c397bf224afaa355fe9 \ + --hash=sha256:85071a1e8c2d051b507161f6c3e26155b5c790e4e28d7f236422dbacc2a9cc44 \ + --hash=sha256:856f4bc0478ae143bad54a4242fccb1f3f86a6e1be5548fecfd4102061b3a083 \ + --hash=sha256:85797e37e8eeaa5439d33e556662cc370e474445d5fab24dcadc65a8ffb04003 \ + --hash=sha256:90d96a385fa941283ebd231464045187a31ad932ebfa541be8edf5b3c2328959 \ + --hash=sha256:94978a49b8f4569ad607cd4946b759d90b285e39c0d4640c6b36ca7a3ddf2efc \ + --hash=sha256:aafe0f1918ed07b67c1e838f950b1c1fabc683030477e60b335649b8020e1076 \ + --hash=sha256:ab9ba8dcf59de5181f6be44a77458e45a578fc99c31510b8c65b7d5acc3cf490 \ + --hash=sha256:ade273d7e767d5fae13fa637f4d53b6e961fb7fd93c7797562663f0171c26660 \ + --hash=sha256:b799de31416ecc589ad79dd85a0b2657a8fe39327944998dea368c1d4c9e55e6 \ + --hash=sha256:c26f313951f6e26147833fc923f78f95604bbec812a43e5ee37f26dc9e5a686c \ + --hash=sha256:ca80b7485c76f768a3bc83ea58373f8db7b015551117375e4918e2aa77ea9b50 \ + --hash=sha256:d1ffd262a73d7c28424252381a5b854c19d9de5f56f075445d33919a637e3547 \ + --hash=sha256:d3f0d369e7ffbe59c4b6116a44d6a8eb4783aae027f2c0b366cf0aa964185dba \ + --hash=sha256:d54efd20338ac52ba31e7da78e4a72570cf729fac82bc31ff9199bedf1dc7440 \ + --hash=sha256:dacdd3d10ea1b4ca9df97a0a303cbacafc04b5cd375fa98732678151643d4988 \ + --hash=sha256:db353d22843cf1028f43c3651581e4bb49374d85692a85f95f7b9a130e1b2cab \ + --hash=sha256:db78cb9ca56b59b016e64b6031eda5653be0589dba2b1b43453f6e8b405a0970 \ + --hash=sha256:deee0e3343f98ee8047e9f4c5bc7cedbf69f5734454a94c38ee829fb2d5fa3c1 \ + --hash=sha256:df017d6c780287d5c80601dafa31f17bddb170232d85c066604d8558683711a2 \ + --hash=sha256:df959752a0c2748a65ab5387d08287abf6779ae9165916fe053e68ae1fbdc47f \ + --hash=sha256:ec4f178901fa1834d4a060320d2f3abc5c9e39766953d038f1458cb885f47e81 \ + --hash=sha256:f47f8ed67cc0ff862b84a1189831d1d33c963fb3ce1ee0c65d3b0cbe7b711069 \ + --hash=sha256:f8787367fbdfccae38e35abf7641dafc5310310a5987b689f4c32cc8cc3ee975 \ + --hash=sha256:f9eb89ecf8b290f2e293325c646a211ff1c2493222798bb80a530c5e7502494f \ + --hash=sha256:fc411e1c0a7dcd2f902c7c48cf079947a7e65b5485dea9decb82b9105ca71a43 # via uvicorn -httpx==0.27.0 \ - --hash=sha256:71d5465162c13681bff01ad59b2cc68dd838ea1f10e51574bac27103f00c91a5 \ - --hash=sha256:a0cb88a46f32dc874e04ee956e4c2764aba2aa228f650b06788ba6bda2962ab5 +httpx==0.27.2 \ + --hash=sha256:7bb2708e112d8fdd7829cd4243970f0c223274051cb35ee80c03301ee29a3df0 \ + --hash=sha256:f7c2be1d2f3c3c3160d441802406b206c2b76f5947b11115e6df10c6c65e66c2 # via # -r lock/requirements-dev-template.in # fastapi # pytest-httpx -identify==2.6.0 \ - --hash=sha256:cb171c685bdc31bcc4c1734698736a7d5b6c8bf2e0c15117f4d469c8640ae5cf \ - --hash=sha256:e79ae4406387a9d300332b5fd366d8994f1525e8414984e1a59e058b2eda2dd0 +identify==2.6.1 \ + --hash=sha256:53863bcac7caf8d2ed85bd20312ea5dcfc22226800f6d6881f232d861db5a8f0 \ + --hash=sha256:91478c5fb7c3aac5ff7bf9b4344f803843dc586832d5f110d672b19aa1984c98 # via pre-commit -idna==3.7 \ - --hash=sha256:028ff3aadf0609c1fd278d8ea3089299412a7a8b9bd005dd08b9f8285bcb5cfc \ - --hash=sha256:82fee1fc78add43492d3a1898bfa6d8a904cc97d8427f683ed8e798d07761aa0 +idna==3.10 \ + --hash=sha256:12f65c9b470abda6dc35cf8e63cc574b1c52b11df2c86030af0ac09b01b13ea9 \ + --hash=sha256:946d195a0d259cbba61165e88e65941f16e9b36ea6ddb97f00452bae8b1287d3 # via # anyio # email-validator @@ -372,9 +384,9 @@ jsonschema==4.23.0 \ --hash=sha256:d71497fef26351a33265337fa77ffeb82423f3ea21283cd9467bb03999266bc4 \ --hash=sha256:fbadb6f8b144a8f8cf9f0b89ba94501d143e50411a1278633f56a7acf7fd5566 # via hexkit -jsonschema-specifications==2023.12.1 \ - --hash=sha256:48a76787b3e70f5ed53f1160d2b81f586e4ca6d1548c5de7085d1682674764cc \ - --hash=sha256:87e4fdf3a94858b8a2ba2778d9ba57d8a9cafca7c7489c46ba0d30a8bc6a9c3c +jsonschema-specifications==2024.10.1 \ + --hash=sha256:0f38b83639958ce1152d02a7f062902c41c8fd20d558b0c34344292d417ae272 \ + --hash=sha256:a09a0680616357d9a0ecf05c12ad234479f549239d0f5b55f3deea67475da9bf # via jsonschema jsonschema2md==1.3.0 \ --hash=sha256:5ee8f6674c9fec7303daa24c79023805caf2f2fefb99834813bd746227d146ea \ @@ -388,104 +400,110 @@ markdown-it-py==3.0.0 \ --hash=sha256:355216845c60bd96232cd8d8c40e8f9765cc86f46880e43a8fd22dc1a1a8cab1 \ --hash=sha256:e3f60a94fa066dc52ec76661e37c851cb232d92f9886b15cb560aaada2df8feb # via rich -markupsafe==2.1.5 \ - --hash=sha256:00e046b6dd71aa03a41079792f8473dc494d564611a8f89bbbd7cb93295ebdcf \ - --hash=sha256:075202fa5b72c86ad32dc7d0b56024ebdbcf2048c0ba09f1cde31bfdd57bcfff \ - --hash=sha256:0e397ac966fdf721b2c528cf028494e86172b4feba51d65f81ffd65c63798f3f \ - --hash=sha256:17b950fccb810b3293638215058e432159d2b71005c74371d784862b7e4683f3 \ - --hash=sha256:1f3fbcb7ef1f16e48246f704ab79d79da8a46891e2da03f8783a5b6fa41a9532 \ - --hash=sha256:2174c595a0d73a3080ca3257b40096db99799265e1c27cc5a610743acd86d62f \ - --hash=sha256:2b7c57a4dfc4f16f7142221afe5ba4e093e09e728ca65c51f5620c9aaeb9a617 \ - --hash=sha256:2d2d793e36e230fd32babe143b04cec8a8b3eb8a3122d2aceb4a371e6b09b8df \ - --hash=sha256:30b600cf0a7ac9234b2638fbc0fb6158ba5bdcdf46aeb631ead21248b9affbc4 \ - --hash=sha256:397081c1a0bfb5124355710fe79478cdbeb39626492b15d399526ae53422b906 \ - --hash=sha256:3a57fdd7ce31c7ff06cdfbf31dafa96cc533c21e443d57f5b1ecc6cdc668ec7f \ - --hash=sha256:3c6b973f22eb18a789b1460b4b91bf04ae3f0c4234a0a6aa6b0a92f6f7b951d4 \ - --hash=sha256:3e53af139f8579a6d5f7b76549125f0d94d7e630761a2111bc431fd820e163b8 \ - --hash=sha256:4096e9de5c6fdf43fb4f04c26fb114f61ef0bf2e5604b6ee3019d51b69e8c371 \ - --hash=sha256:4275d846e41ecefa46e2015117a9f491e57a71ddd59bbead77e904dc02b1bed2 \ - --hash=sha256:4c31f53cdae6ecfa91a77820e8b151dba54ab528ba65dfd235c80b086d68a465 \ - --hash=sha256:4f11aa001c540f62c6166c7726f71f7573b52c68c31f014c25cc7901deea0b52 \ - --hash=sha256:5049256f536511ee3f7e1b3f87d1d1209d327e818e6ae1365e8653d7e3abb6a6 \ - --hash=sha256:58c98fee265677f63a4385256a6d7683ab1832f3ddd1e66fe948d5880c21a169 \ - --hash=sha256:598e3276b64aff0e7b3451b72e94fa3c238d452e7ddcd893c3ab324717456bad \ - --hash=sha256:5b7b716f97b52c5a14bffdf688f971b2d5ef4029127f1ad7a513973cfd818df2 \ - --hash=sha256:5dedb4db619ba5a2787a94d877bc8ffc0566f92a01c0ef214865e54ecc9ee5e0 \ - --hash=sha256:619bc166c4f2de5caa5a633b8b7326fbe98e0ccbfacabd87268a2b15ff73a029 \ - --hash=sha256:629ddd2ca402ae6dbedfceeba9c46d5f7b2a61d9749597d4307f943ef198fc1f \ - --hash=sha256:656f7526c69fac7f600bd1f400991cc282b417d17539a1b228617081106feb4a \ - --hash=sha256:6ec585f69cec0aa07d945b20805be741395e28ac1627333b1c5b0105962ffced \ - --hash=sha256:72b6be590cc35924b02c78ef34b467da4ba07e4e0f0454a2c5907f473fc50ce5 \ - --hash=sha256:7502934a33b54030eaf1194c21c692a534196063db72176b0c4028e140f8f32c \ - --hash=sha256:7a68b554d356a91cce1236aa7682dc01df0edba8d043fd1ce607c49dd3c1edcf \ - --hash=sha256:7b2e5a267c855eea6b4283940daa6e88a285f5f2a67f2220203786dfa59b37e9 \ - --hash=sha256:823b65d8706e32ad2df51ed89496147a42a2a6e01c13cfb6ffb8b1e92bc910bb \ - --hash=sha256:8590b4ae07a35970728874632fed7bd57b26b0102df2d2b233b6d9d82f6c62ad \ - --hash=sha256:8dd717634f5a044f860435c1d8c16a270ddf0ef8588d4887037c5028b859b0c3 \ - --hash=sha256:8dec4936e9c3100156f8a2dc89c4b88d5c435175ff03413b443469c7c8c5f4d1 \ - --hash=sha256:97cafb1f3cbcd3fd2b6fbfb99ae11cdb14deea0736fc2b0952ee177f2b813a46 \ - --hash=sha256:a17a92de5231666cfbe003f0e4b9b3a7ae3afb1ec2845aadc2bacc93ff85febc \ - --hash=sha256:a549b9c31bec33820e885335b451286e2969a2d9e24879f83fe904a5ce59d70a \ - --hash=sha256:ac07bad82163452a6884fe8fa0963fb98c2346ba78d779ec06bd7a6262132aee \ - --hash=sha256:ae2ad8ae6ebee9d2d94b17fb62763125f3f374c25618198f40cbb8b525411900 \ - --hash=sha256:b91c037585eba9095565a3556f611e3cbfaa42ca1e865f7b8015fe5c7336d5a5 \ - --hash=sha256:bc1667f8b83f48511b94671e0e441401371dfd0f0a795c7daa4a3cd1dde55bea \ - --hash=sha256:bec0a414d016ac1a18862a519e54b2fd0fc8bbfd6890376898a6c0891dd82e9f \ - --hash=sha256:bf50cd79a75d181c9181df03572cdce0fbb75cc353bc350712073108cba98de5 \ - --hash=sha256:bff1b4290a66b490a2f4719358c0cdcd9bafb6b8f061e45c7a2460866bf50c2e \ - --hash=sha256:c061bb86a71b42465156a3ee7bd58c8c2ceacdbeb95d05a99893e08b8467359a \ - --hash=sha256:c8b29db45f8fe46ad280a7294f5c3ec36dbac9491f2d1c17345be8e69cc5928f \ - --hash=sha256:ce409136744f6521e39fd8e2a24c53fa18ad67aa5bc7c2cf83645cce5b5c4e50 \ - --hash=sha256:d050b3361367a06d752db6ead6e7edeb0009be66bc3bae0ee9d97fb326badc2a \ - --hash=sha256:d283d37a890ba4c1ae73ffadf8046435c76e7bc2247bbb63c00bd1a709c6544b \ - --hash=sha256:d9fad5155d72433c921b782e58892377c44bd6252b5af2f67f16b194987338a4 \ - --hash=sha256:daa4ee5a243f0f20d528d939d06670a298dd39b1ad5f8a72a4275124a7819eff \ - --hash=sha256:db0b55e0f3cc0be60c1f19efdde9a637c32740486004f20d1cff53c3c0ece4d2 \ - --hash=sha256:e61659ba32cf2cf1481e575d0462554625196a1f2fc06a1c777d3f48e8865d46 \ - --hash=sha256:ea3d8a3d18833cf4304cd2fc9cbb1efe188ca9b5efef2bdac7adc20594a0e46b \ - --hash=sha256:ec6a563cff360b50eed26f13adc43e61bc0c04d94b8be985e6fb24b81f6dcfdf \ - --hash=sha256:f5dfb42c4604dddc8e4305050aa6deb084540643ed5804d7455b5df8fe16f5e5 \ - --hash=sha256:fa173ec60341d6bb97a89f5ea19c85c5643c1e7dedebc22f5181eb73573142c5 \ - --hash=sha256:fa9db3f79de01457b03d4f01b34cf91bc0048eb2c3846ff26f66687c2f6d16ab \ - --hash=sha256:fce659a462a1be54d2ffcacea5e3ba2d74daa74f30f5f143fe0c58636e355fdd \ - --hash=sha256:ffee1f21e5ef0d712f9033568f8344d5da8cc2869dbd08d87c84656e6a2d2f68 +markupsafe==3.0.2 \ + --hash=sha256:0bff5e0ae4ef2e1ae4fdf2dfd5b76c75e5c2fa4132d05fc1b0dabcd20c7e28c4 \ + --hash=sha256:0f4ca02bea9a23221c0182836703cbf8930c5e9454bacce27e767509fa286a30 \ + --hash=sha256:1225beacc926f536dc82e45f8a4d68502949dc67eea90eab715dea3a21c1b5f0 \ + --hash=sha256:131a3c7689c85f5ad20f9f6fb1b866f402c445b220c19fe4308c0b147ccd2ad9 \ + --hash=sha256:15ab75ef81add55874e7ab7055e9c397312385bd9ced94920f2802310c930396 \ + --hash=sha256:1a9d3f5f0901fdec14d8d2f66ef7d035f2157240a433441719ac9a3fba440b13 \ + --hash=sha256:1c99d261bd2d5f6b59325c92c73df481e05e57f19837bdca8413b9eac4bd8028 \ + --hash=sha256:1e084f686b92e5b83186b07e8a17fc09e38fff551f3602b249881fec658d3eca \ + --hash=sha256:2181e67807fc2fa785d0592dc2d6206c019b9502410671cc905d132a92866557 \ + --hash=sha256:2cb8438c3cbb25e220c2ab33bb226559e7afb3baec11c4f218ffa7308603c832 \ + --hash=sha256:3169b1eefae027567d1ce6ee7cae382c57fe26e82775f460f0b2778beaad66c0 \ + --hash=sha256:3809ede931876f5b2ec92eef964286840ed3540dadf803dd570c3b7e13141a3b \ + --hash=sha256:38a9ef736c01fccdd6600705b09dc574584b89bea478200c5fbf112a6b0d5579 \ + --hash=sha256:3d79d162e7be8f996986c064d1c7c817f6df3a77fe3d6859f6f9e7be4b8c213a \ + --hash=sha256:444dcda765c8a838eaae23112db52f1efaf750daddb2d9ca300bcae1039adc5c \ + --hash=sha256:48032821bbdf20f5799ff537c7ac3d1fba0ba032cfc06194faffa8cda8b560ff \ + --hash=sha256:4aa4e5faecf353ed117801a068ebab7b7e09ffb6e1d5e412dc852e0da018126c \ + --hash=sha256:52305740fe773d09cffb16f8ed0427942901f00adedac82ec8b67752f58a1b22 \ + --hash=sha256:569511d3b58c8791ab4c2e1285575265991e6d8f8700c7be0e88f86cb0672094 \ + --hash=sha256:57cb5a3cf367aeb1d316576250f65edec5bb3be939e9247ae594b4bcbc317dfb \ + --hash=sha256:5b02fb34468b6aaa40dfc198d813a641e3a63b98c2b05a16b9f80b7ec314185e \ + --hash=sha256:6381026f158fdb7c72a168278597a5e3a5222e83ea18f543112b2662a9b699c5 \ + --hash=sha256:6af100e168aa82a50e186c82875a5893c5597a0c1ccdb0d8b40240b1f28b969a \ + --hash=sha256:6c89876f41da747c8d3677a2b540fb32ef5715f97b66eeb0c6b66f5e3ef6f59d \ + --hash=sha256:6e296a513ca3d94054c2c881cc913116e90fd030ad1c656b3869762b754f5f8a \ + --hash=sha256:70a87b411535ccad5ef2f1df5136506a10775d267e197e4cf531ced10537bd6b \ + --hash=sha256:7e94c425039cde14257288fd61dcfb01963e658efbc0ff54f5306b06054700f8 \ + --hash=sha256:846ade7b71e3536c4e56b386c2a47adf5741d2d8b94ec9dc3e92e5e1ee1e2225 \ + --hash=sha256:88416bd1e65dcea10bc7569faacb2c20ce071dd1f87539ca2ab364bf6231393c \ + --hash=sha256:88b49a3b9ff31e19998750c38e030fc7bb937398b1f78cfa599aaef92d693144 \ + --hash=sha256:8c4e8c3ce11e1f92f6536ff07154f9d49677ebaaafc32db9db4620bc11ed480f \ + --hash=sha256:8e06879fc22a25ca47312fbe7c8264eb0b662f6db27cb2d3bbbc74b1df4b9b87 \ + --hash=sha256:9025b4018f3a1314059769c7bf15441064b2207cb3f065e6ea1e7359cb46db9d \ + --hash=sha256:93335ca3812df2f366e80509ae119189886b0f3c2b81325d39efdb84a1e2ae93 \ + --hash=sha256:9778bd8ab0a994ebf6f84c2b949e65736d5575320a17ae8984a77fab08db94cf \ + --hash=sha256:9e2d922824181480953426608b81967de705c3cef4d1af983af849d7bd619158 \ + --hash=sha256:a123e330ef0853c6e822384873bef7507557d8e4a082961e1defa947aa59ba84 \ + --hash=sha256:a904af0a6162c73e3edcb969eeeb53a63ceeb5d8cf642fade7d39e7963a22ddb \ + --hash=sha256:ad10d3ded218f1039f11a75f8091880239651b52e9bb592ca27de44eed242a48 \ + --hash=sha256:b424c77b206d63d500bcb69fa55ed8d0e6a3774056bdc4839fc9298a7edca171 \ + --hash=sha256:b5a6b3ada725cea8a5e634536b1b01c30bcdcd7f9c6fff4151548d5bf6b3a36c \ + --hash=sha256:ba8062ed2cf21c07a9e295d5b8a2a5ce678b913b45fdf68c32d95d6c1291e0b6 \ + --hash=sha256:ba9527cdd4c926ed0760bc301f6728ef34d841f405abf9d4f959c478421e4efd \ + --hash=sha256:bbcb445fa71794da8f178f0f6d66789a28d7319071af7a496d4d507ed566270d \ + --hash=sha256:bcf3e58998965654fdaff38e58584d8937aa3096ab5354d493c77d1fdd66d7a1 \ + --hash=sha256:c0ef13eaeee5b615fb07c9a7dadb38eac06a0608b41570d8ade51c56539e509d \ + --hash=sha256:cabc348d87e913db6ab4aa100f01b08f481097838bdddf7c7a84b7575b7309ca \ + --hash=sha256:cdb82a876c47801bb54a690c5ae105a46b392ac6099881cdfb9f6e95e4014c6a \ + --hash=sha256:cfad01eed2c2e0c01fd0ecd2ef42c492f7f93902e39a42fc9ee1692961443a29 \ + --hash=sha256:d16a81a06776313e817c951135cf7340a3e91e8c1ff2fac444cfd75fffa04afe \ + --hash=sha256:d8213e09c917a951de9d09ecee036d5c7d36cb6cb7dbaece4c71a60d79fb9798 \ + --hash=sha256:e07c3764494e3776c602c1e78e298937c3315ccc9043ead7e685b7f2b8d47b3c \ + --hash=sha256:e17c96c14e19278594aa4841ec148115f9c7615a47382ecb6b82bd8fea3ab0c8 \ + --hash=sha256:e444a31f8db13eb18ada366ab3cf45fd4b31e4db1236a4448f68778c1d1a5a2f \ + --hash=sha256:e6a2a455bd412959b57a172ce6328d2dd1f01cb2135efda2e4576e8a23fa3b0f \ + --hash=sha256:eaa0a10b7f72326f1372a713e73c3f739b524b3af41feb43e4921cb529f5929a \ + --hash=sha256:eb7972a85c54febfb25b5c4b4f3af4dcc731994c7da0d8a0b4a6eb0640e1d178 \ + --hash=sha256:ee55d3edf80167e48ea11a923c7386f4669df67d7994554387f84e7d8b0a2bf0 \ + --hash=sha256:f3818cb119498c0678015754eba762e0d61e5b52d34c8b13d770f0719f7b1d79 \ + --hash=sha256:f8b3d067f2e40fe93e1ccdd6b2e1d16c43140e76f02fb1319a05cf2b79d99430 \ + --hash=sha256:fcabf5ff6eea076f859677f5f0b6b5c1a51e70a376b0579e0eadef8db48c6b50 # via jinja2 mdurl==0.1.2 \ --hash=sha256:84008a41e51615a49fc9966191ff91509e3c40b939176e643fd50a5c2196b8f8 \ --hash=sha256:bb413d29f5eea38f31dd4754dd7377d4465116fb207585f97bf925588687c1ba # via markdown-it-py -motor==3.5.1 \ - --hash=sha256:1622bd7b39c3e6375607c14736f6e1d498128eadf6f5f93f8786cf17d37062ac \ - --hash=sha256:f95a9ea0f011464235e0bd72910baa291db3a6009e617ac27b82f57885abafb8 +motor==3.6.0 \ + --hash=sha256:0ef7f520213e852bf0eac306adf631aabe849227d8aec900a2612512fb9c5b8d \ + --hash=sha256:9f07ed96f1754963d4386944e1b52d403a5350c687edc60da487d66f98dbf894 # via hexkit -mypy==1.11.1 \ - --hash=sha256:0624bdb940255d2dd24e829d99a13cfeb72e4e9031f9492148f410ed30bcab54 \ - --hash=sha256:0bc71d1fb27a428139dd78621953effe0d208aed9857cb08d002280b0422003a \ - --hash=sha256:0bd53faf56de9643336aeea1c925012837432b5faf1701ccca7fde70166ccf72 \ - --hash=sha256:11965c2f571ded6239977b14deebd3f4c3abd9a92398712d6da3a772974fad69 \ - --hash=sha256:1a81cf05975fd61aec5ae16501a091cfb9f605dc3e3c878c0da32f250b74760b \ - --hash=sha256:2684d3f693073ab89d76da8e3921883019ea8a3ec20fa5d8ecca6a2db4c54bbe \ - --hash=sha256:2c63350af88f43a66d3dfeeeb8d77af34a4f07d760b9eb3a8697f0386c7590b4 \ - --hash=sha256:45df906e8b6804ef4b666af29a87ad9f5921aad091c79cc38e12198e220beabd \ - --hash=sha256:4c956b49c5d865394d62941b109728c5c596a415e9c5b2be663dd26a1ff07bc0 \ - --hash=sha256:64f4a90e3ea07f590c5bcf9029035cf0efeae5ba8be511a8caada1a4893f5525 \ - --hash=sha256:749fd3213916f1751fff995fccf20c6195cae941dc968f3aaadf9bb4e430e5a2 \ - --hash=sha256:79c07eb282cb457473add5052b63925e5cc97dfab9812ee65a7c7ab5e3cb551c \ - --hash=sha256:7b6343d338390bb946d449677726edf60102a1c96079b4f002dedff375953fc5 \ - --hash=sha256:886c9dbecc87b9516eff294541bf7f3655722bf22bb898ee06985cd7269898de \ - --hash=sha256:a2b43895a0f8154df6519706d9bca8280cda52d3d9d1514b2d9c3e26792a0b74 \ - --hash=sha256:a32fc80b63de4b5b3e65f4be82b4cfa362a46702672aa6a0f443b4689af7008c \ - --hash=sha256:a707ec1527ffcdd1c784d0924bf5cb15cd7f22683b919668a04d2b9c34549d2e \ - --hash=sha256:a831671bad47186603872a3abc19634f3011d7f83b083762c942442d51c58d58 \ - --hash=sha256:b639dce63a0b19085213ec5fdd8cffd1d81988f47a2dec7100e93564f3e8fb3b \ - --hash=sha256:b868d3bcff720dd7217c383474008ddabaf048fad8d78ed948bb4b624870a417 \ - --hash=sha256:c1952f5ea8a5a959b05ed5f16452fddadbaae48b5d39235ab4c3fc444d5fd411 \ - --hash=sha256:d44be7551689d9d47b7abc27c71257adfdb53f03880841a5db15ddb22dc63edb \ - --hash=sha256:e1e30dc3bfa4e157e53c1d17a0dad20f89dc433393e7702b813c10e200843b03 \ - --hash=sha256:e4fe9f4e5e521b458d8feb52547f4bade7ef8c93238dfb5bbc790d9ff2d770ca \ - --hash=sha256:f39918a50f74dc5969807dcfaecafa804fa7f90c9d60506835036cc1bc891dc8 \ - --hash=sha256:f404a0b069709f18bbdb702eb3dcfe51910602995de00bd39cea3050b5772d08 \ - --hash=sha256:fca4a60e1dd9fd0193ae0067eaeeb962f2d79e0d9f0f66223a0682f26ffcc809 +mypy==1.13.0 \ + --hash=sha256:0246bcb1b5de7f08f2826451abd947bf656945209b140d16ed317f65a17dc7dc \ + --hash=sha256:0291a61b6fbf3e6673e3405cfcc0e7650bebc7939659fdca2702958038bd835e \ + --hash=sha256:0730d1c6a2739d4511dc4253f8274cdd140c55c32dfb0a4cf8b7a43f40abfa6f \ + --hash=sha256:07de989f89786f62b937851295ed62e51774722e5444a27cecca993fc3f9cd74 \ + --hash=sha256:100fac22ce82925f676a734af0db922ecfea991e1d7ec0ceb1e115ebe501301a \ + --hash=sha256:164f28cb9d6367439031f4c81e84d3ccaa1e19232d9d05d37cb0bd880d3f93c2 \ + --hash=sha256:20c7ee0bc0d5a9595c46f38beb04201f2620065a93755704e141fcac9f59db2b \ + --hash=sha256:3790ded76f0b34bc9c8ba4def8f919dd6a46db0f5a6610fb994fe8efdd447f73 \ + --hash=sha256:39bb21c69a5d6342f4ce526e4584bc5c197fd20a60d14a8624d8743fffb9472e \ + --hash=sha256:3ddb5b9bf82e05cc9a627e84707b528e5c7caaa1c55c69e175abb15a761cec2d \ + --hash=sha256:3e38b980e5681f28f033f3be86b099a247b13c491f14bb8b1e1e134d23bb599d \ + --hash=sha256:4bde84334fbe19bad704b3f5b78c4abd35ff1026f8ba72b29de70dda0916beb6 \ + --hash=sha256:51f869f4b6b538229c1d1bcc1dd7d119817206e2bc54e8e374b3dfa202defcca \ + --hash=sha256:581665e6f3a8a9078f28d5502f4c334c0c8d802ef55ea0e7276a6e409bc0d82d \ + --hash=sha256:5c7051a3461ae84dfb5dd15eff5094640c61c5f22257c8b766794e6dd85e72d5 \ + --hash=sha256:5d5092efb8516d08440e36626f0153b5006d4088c1d663d88bf79625af3d1d62 \ + --hash=sha256:6607e0f1dd1fb7f0aca14d936d13fd19eba5e17e1cd2a14f808fa5f8f6d8f60a \ + --hash=sha256:7029881ec6ffb8bc233a4fa364736789582c738217b133f1b55967115288a2bc \ + --hash=sha256:7b2353a44d2179846a096e25691d54d59904559f4232519d420d64da6828a3a7 \ + --hash=sha256:7bcb0bb7f42a978bb323a7c88f1081d1b5dee77ca86f4100735a6f541299d8fb \ + --hash=sha256:7bfd8836970d33c2105562650656b6846149374dc8ed77d98424b40b09340ba7 \ + --hash=sha256:7f5b7deae912cf8b77e990b9280f170381fdfbddf61b4ef80927edd813163732 \ + --hash=sha256:8a21be69bd26fa81b1f80a61ee7ab05b076c674d9b18fb56239d72e21d9f4c80 \ + --hash=sha256:9c250883f9fd81d212e0952c92dbfcc96fc237f4b7c92f56ac81fd48460b3e5a \ + --hash=sha256:9f73dba9ec77acb86457a8fc04b5239822df0c14a082564737833d2963677dbc \ + --hash=sha256:a0affb3a79a256b4183ba09811e3577c5163ed06685e4d4b46429a271ba174d2 \ + --hash=sha256:a4c1bfcdbce96ff5d96fc9b08e3831acb30dc44ab02671eca5953eadad07d6d0 \ + --hash=sha256:a6789be98a2017c912ae6ccb77ea553bbaf13d27605d2ca20a76dfbced631b24 \ + --hash=sha256:a7b44178c9760ce1a43f544e595d35ed61ac2c3de306599fa59b38a6048e1aa7 \ + --hash=sha256:bde31fc887c213e223bbfc34328070996061b0833b0a4cfec53745ed61f3519b \ + --hash=sha256:c5fc54dbb712ff5e5a0fca797e6e0aa25726c7e72c6a5850cfd2adbc1eb0a372 \ + --hash=sha256:de2904956dac40ced10931ac967ae63c5089bd498542194b436eb097a9f77bc8 # via -r lock/requirements-dev-template.in mypy-extensions==1.0.0 \ --hash=sha256:4392f6c0eb8a5668a69e23d168ffa70f0be9ccfd32b5cc2d26a34ae5b844552d \ @@ -503,180 +521,189 @@ packaging==24.1 \ # via # aiokafka # pytest -platformdirs==4.2.2 \ - --hash=sha256:2d7a1657e36a80ea911db832a8a6ece5ee53d8de21edd5cc5879af6530b1bfee \ - --hash=sha256:38b7b51f512eed9e84a22788b4bce1de17c0adb134d6becb09836e37d8654cd3 +platformdirs==4.3.6 \ + --hash=sha256:357fb2acbc885b0419afd3ce3ed34564c13c9b95c89360cd9563f73aa5e2b907 \ + --hash=sha256:73e575e1408ab8103900836b97580d5307456908a03e92031bab39e4554cc3fb # via virtualenv pluggy==1.5.0 \ --hash=sha256:2cffa88e94fdc978c4c574f15f9e59b7f4201d439195c3715ca9e2486f1d0cf1 \ --hash=sha256:44e1ad92c8ca002de6377e165f3e0f1be63266ab4d554740532335b9d75ea669 # via pytest -pre-commit==3.8.0 \ - --hash=sha256:8bb6494d4a20423842e198980c9ecf9f96607a07ea29549e180eef9ae80fe7af \ - --hash=sha256:9a90a53bf82fdd8778d58085faf8d83df56e40dfe18f45b19446e26bf1b3a63f +pre-commit==4.0.1 \ + --hash=sha256:80905ac375958c0444c65e9cebebd948b3cdb518f335a091a670a89d652139d2 \ + --hash=sha256:efde913840816312445dc98787724647c65473daefe420785f885e8ed9a06878 # via -r lock/requirements-dev-template.in -pydantic==2.8.2 \ - --hash=sha256:6f62c13d067b0755ad1c21a34bdd06c0c12625a22b0fc09c6b149816604f7c2a \ - --hash=sha256:73ee9fddd406dc318b885c7a2eab8a6472b68b8fb5ba8150949fc3db939f23c8 +pydantic==2.9.2 \ + --hash=sha256:d155cef71265d1e9807ed1c32b4c8deec042a44a50a4188b25ac67ecd81a9c0f \ + --hash=sha256:f048cec7b26778210e28a0459867920654d48e5e62db0958433636cde4254f12 # via # fastapi # ghga-service-commons # hexkit # pydantic-settings -pydantic-core==2.20.1 \ - --hash=sha256:035ede2e16da7281041f0e626459bcae33ed998cca6a0a007a5ebb73414ac72d \ - --hash=sha256:04024d270cf63f586ad41fff13fde4311c4fc13ea74676962c876d9577bcc78f \ - --hash=sha256:0827505a5c87e8aa285dc31e9ec7f4a17c81a813d45f70b1d9164e03a813a686 \ - --hash=sha256:084659fac3c83fd674596612aeff6041a18402f1e1bc19ca39e417d554468482 \ - --hash=sha256:10d4204d8ca33146e761c79f83cc861df20e7ae9f6487ca290a97702daf56006 \ - --hash=sha256:11b71d67b4725e7e2a9f6e9c0ac1239bbc0c48cce3dc59f98635efc57d6dac83 \ - --hash=sha256:150906b40ff188a3260cbee25380e7494ee85048584998c1e66df0c7a11c17a6 \ - --hash=sha256:175873691124f3d0da55aeea1d90660a6ea7a3cfea137c38afa0a5ffabe37b88 \ - --hash=sha256:177f55a886d74f1808763976ac4efd29b7ed15c69f4d838bbd74d9d09cf6fa86 \ - --hash=sha256:19c0fa39fa154e7e0b7f82f88ef85faa2a4c23cc65aae2f5aea625e3c13c735a \ - --hash=sha256:1eedfeb6089ed3fad42e81a67755846ad4dcc14d73698c120a82e4ccf0f1f9f6 \ - --hash=sha256:225b67a1f6d602de0ce7f6c1c3ae89a4aa25d3de9be857999e9124f15dab486a \ - --hash=sha256:242b8feb3c493ab78be289c034a1f659e8826e2233786e36f2893a950a719bb6 \ - --hash=sha256:254ec27fdb5b1ee60684f91683be95e5133c994cc54e86a0b0963afa25c8f8a6 \ - --hash=sha256:25e9185e2d06c16ee438ed39bf62935ec436474a6ac4f9358524220f1b236e43 \ - --hash=sha256:26ab812fa0c845df815e506be30337e2df27e88399b985d0bb4e3ecfe72df31c \ - --hash=sha256:26ca695eeee5f9f1aeeb211ffc12f10bcb6f71e2989988fda61dabd65db878d4 \ - --hash=sha256:26dc97754b57d2fd00ac2b24dfa341abffc380b823211994c4efac7f13b9e90e \ - --hash=sha256:270755f15174fb983890c49881e93f8f1b80f0b5e3a3cc1394a255706cabd203 \ - --hash=sha256:2aafc5a503855ea5885559eae883978c9b6d8c8993d67766ee73d82e841300dd \ - --hash=sha256:2d036c7187b9422ae5b262badb87a20a49eb6c5238b2004e96d4da1231badef1 \ - --hash=sha256:33499e85e739a4b60c9dac710c20a08dc73cb3240c9a0e22325e671b27b70d24 \ - --hash=sha256:37eee5b638f0e0dcd18d21f59b679686bbd18917b87db0193ae36f9c23c355fc \ - --hash=sha256:38cf1c40a921d05c5edc61a785c0ddb4bed67827069f535d794ce6bcded919fc \ - --hash=sha256:3acae97ffd19bf091c72df4d726d552c473f3576409b2a7ca36b2f535ffff4a3 \ - --hash=sha256:3c5ebac750d9d5f2706654c638c041635c385596caf68f81342011ddfa1e5598 \ - --hash=sha256:3d482efec8b7dc6bfaedc0f166b2ce349df0011f5d2f1f25537ced4cfc34fd98 \ - --hash=sha256:407653af5617f0757261ae249d3fba09504d7a71ab36ac057c938572d1bc9331 \ - --hash=sha256:40a783fb7ee353c50bd3853e626f15677ea527ae556429453685ae32280c19c2 \ - --hash=sha256:41e81317dd6a0127cabce83c0c9c3fbecceae981c8391e6f1dec88a77c8a569a \ - --hash=sha256:41f4c96227a67a013e7de5ff8f20fb496ce573893b7f4f2707d065907bffdbd6 \ - --hash=sha256:469f29f9093c9d834432034d33f5fe45699e664f12a13bf38c04967ce233d688 \ - --hash=sha256:4745f4ac52cc6686390c40eaa01d48b18997cb130833154801a442323cc78f91 \ - --hash=sha256:4868f6bd7c9d98904b748a2653031fc9c2f85b6237009d475b1008bfaeb0a5aa \ - --hash=sha256:4aa223cd1e36b642092c326d694d8bf59b71ddddc94cdb752bbbb1c5c91d833b \ - --hash=sha256:4dd484681c15e6b9a977c785a345d3e378d72678fd5f1f3c0509608da24f2ac0 \ - --hash=sha256:4f2790949cf385d985a31984907fecb3896999329103df4e4983a4a41e13e840 \ - --hash=sha256:512ecfbefef6dac7bc5eaaf46177b2de58cdf7acac8793fe033b24ece0b9566c \ - --hash=sha256:516d9227919612425c8ef1c9b869bbbee249bc91912c8aaffb66116c0b447ebd \ - --hash=sha256:53e431da3fc53360db73eedf6f7124d1076e1b4ee4276b36fb25514544ceb4a3 \ - --hash=sha256:595ba5be69b35777474fa07f80fc260ea71255656191adb22a8c53aba4479231 \ - --hash=sha256:5b5ff4911aea936a47d9376fd3ab17e970cc543d1b68921886e7f64bd28308d1 \ - --hash=sha256:5d41e6daee2813ecceea8eda38062d69e280b39df793f5a942fa515b8ed67953 \ - --hash=sha256:5e999ba8dd90e93d57410c5e67ebb67ffcaadcea0ad973240fdfd3a135506250 \ - --hash=sha256:5f239eb799a2081495ea659d8d4a43a8f42cd1fe9ff2e7e436295c38a10c286a \ - --hash=sha256:635fee4e041ab9c479e31edda27fcf966ea9614fff1317e280d99eb3e5ab6fe2 \ - --hash=sha256:65db0f2eefcaad1a3950f498aabb4875c8890438bc80b19362cf633b87a8ab20 \ - --hash=sha256:6b507132dcfc0dea440cce23ee2182c0ce7aba7054576efc65634f080dbe9434 \ - --hash=sha256:6b9d9bb600328a1ce523ab4f454859e9d439150abb0906c5a1983c146580ebab \ - --hash=sha256:70c8daf4faca8da5a6d655f9af86faf6ec2e1768f4b8b9d0226c02f3d6209703 \ - --hash=sha256:77bf3ac639c1ff567ae3b47f8d4cc3dc20f9966a2a6dd2311dcc055d3d04fb8a \ - --hash=sha256:784c1214cb6dd1e3b15dd8b91b9a53852aed16671cc3fbe4786f4f1db07089e2 \ - --hash=sha256:7eb6a0587eded33aeefea9f916899d42b1799b7b14b8f8ff2753c0ac1741edac \ - --hash=sha256:7ed1b0132f24beeec5a78b67d9388656d03e6a7c837394f99257e2d55b461611 \ - --hash=sha256:8ad4aeb3e9a97286573c03df758fc7627aecdd02f1da04516a86dc159bf70121 \ - --hash=sha256:964faa8a861d2664f0c7ab0c181af0bea66098b1919439815ca8803ef136fc4e \ - --hash=sha256:9dc1b507c12eb0481d071f3c1808f0529ad41dc415d0ca11f7ebfc666e66a18b \ - --hash=sha256:9ebfef07dbe1d93efb94b4700f2d278494e9162565a54f124c404a5656d7ff09 \ - --hash=sha256:a45f84b09ac9c3d35dfcf6a27fd0634d30d183205230a0ebe8373a0e8cfa0906 \ - --hash=sha256:a4f55095ad087474999ee28d3398bae183a66be4823f753cd7d67dd0153427c9 \ - --hash=sha256:a6d511cc297ff0883bc3708b465ff82d7560193169a8b93260f74ecb0a5e08a7 \ - --hash=sha256:a8ad4c766d3f33ba8fd692f9aa297c9058970530a32c728a2c4bfd2616d3358b \ - --hash=sha256:aa2f457b4af386254372dfa78a2eda2563680d982422641a85f271c859df1987 \ - --hash=sha256:b03f7941783b4c4a26051846dea594628b38f6940a2fdc0df00b221aed39314c \ - --hash=sha256:b0dae11d8f5ded51699c74d9548dcc5938e0804cc8298ec0aa0da95c21fff57b \ - --hash=sha256:b91ced227c41aa29c672814f50dbb05ec93536abf8f43cd14ec9521ea09afe4e \ - --hash=sha256:bc633a9fe1eb87e250b5c57d389cf28998e4292336926b0b6cdaee353f89a237 \ - --hash=sha256:bebb4d6715c814597f85297c332297c6ce81e29436125ca59d1159b07f423eb1 \ - --hash=sha256:c336a6d235522a62fef872c6295a42ecb0c4e1d0f1a3e500fe949415761b8a19 \ - --hash=sha256:c6514f963b023aeee506678a1cf821fe31159b925c4b76fe2afa94cc70b3222b \ - --hash=sha256:c693e916709c2465b02ca0ad7b387c4f8423d1db7b4649c551f27a529181c5ad \ - --hash=sha256:c81131869240e3e568916ef4c307f8b99583efaa60a8112ef27a366eefba8ef0 \ - --hash=sha256:d02a72df14dfdbaf228424573a07af10637bd490f0901cee872c4f434a735b94 \ - --hash=sha256:d2a8fa9d6d6f891f3deec72f5cc668e6f66b188ab14bb1ab52422fe8e644f312 \ - --hash=sha256:d2b27e6af28f07e2f195552b37d7d66b150adbaa39a6d327766ffd695799780f \ - --hash=sha256:d2fe69c5434391727efa54b47a1e7986bb0186e72a41b203df8f5b0a19a4f669 \ - --hash=sha256:d3f3ed29cd9f978c604708511a1f9c2fdcb6c38b9aae36a51905b8811ee5cbf1 \ - --hash=sha256:d573faf8eb7e6b1cbbcb4f5b247c60ca8be39fe2c674495df0eb4318303137fe \ - --hash=sha256:e0bbdd76ce9aa5d4209d65f2b27fc6e5ef1312ae6c5333c26db3f5ade53a1e99 \ - --hash=sha256:e7c4ea22b6739b162c9ecaaa41d718dfad48a244909fe7ef4b54c0b530effc5a \ - --hash=sha256:e93e1a4b4b33daed65d781a57a522ff153dcf748dee70b40c7258c5861e1768a \ - --hash=sha256:e97fdf088d4b31ff4ba35db26d9cc472ac7ef4a2ff2badeabf8d727b3377fc52 \ - --hash=sha256:e9fa4c9bf273ca41f940bceb86922a7667cd5bf90e95dbb157cbb8441008482c \ - --hash=sha256:eaad4ff2de1c3823fddf82f41121bdf453d922e9a238642b1dedb33c4e4f98ad \ - --hash=sha256:f1f62b2413c3a0e846c3b838b2ecd6c7a19ec6793b2a522745b0869e37ab5bc1 \ - --hash=sha256:f6d6cff3538391e8486a431569b77921adfcdef14eb18fbf19b7c0a5294d4e6a \ - --hash=sha256:f9aa05d09ecf4c75157197f27cdc9cfaeb7c5f15021c6373932bf3e124af029f \ - --hash=sha256:fa2fddcb7107e0d1808086ca306dcade7df60a13a6c347a7acf1ec139aa6789a \ - --hash=sha256:faa6b09ee09433b87992fb5a2859efd1c264ddc37280d2dd5db502126d0e7f27 +pydantic-core==2.23.4 \ + --hash=sha256:0a7df63886be5e270da67e0966cf4afbae86069501d35c8c1b3b6c168f42cb36 \ + --hash=sha256:0cb3da3fd1b6a5d0279a01877713dbda118a2a4fc6f0d821a57da2e464793f05 \ + --hash=sha256:0dbd8dbed2085ed23b5c04afa29d8fd2771674223135dc9bc937f3c09284d071 \ + --hash=sha256:0dff76e0602ca7d4cdaacc1ac4c005e0ce0dcfe095d5b5259163a80d3a10d327 \ + --hash=sha256:1278e0d324f6908e872730c9102b0112477a7f7cf88b308e4fc36ce1bdb6d58c \ + --hash=sha256:128585782e5bfa515c590ccee4b727fb76925dd04a98864182b22e89a4e6ed36 \ + --hash=sha256:1498bec4c05c9c787bde9125cfdcc63a41004ff167f495063191b863399b1a29 \ + --hash=sha256:19442362866a753485ba5e4be408964644dd6a09123d9416c54cd49171f50744 \ + --hash=sha256:1b84d168f6c48fabd1f2027a3d1bdfe62f92cade1fb273a5d68e621da0e44e6d \ + --hash=sha256:1e90d2e3bd2c3863d48525d297cd143fe541be8bbf6f579504b9712cb6b643ec \ + --hash=sha256:20152074317d9bed6b7a95ade3b7d6054845d70584216160860425f4fbd5ee9e \ + --hash=sha256:216f9b2d7713eb98cb83c80b9c794de1f6b7e3145eef40400c62e86cee5f4e1e \ + --hash=sha256:233710f069d251feb12a56da21e14cca67994eab08362207785cf8c598e74577 \ + --hash=sha256:255a8ef062cbf6674450e668482456abac99a5583bbafb73f9ad469540a3a232 \ + --hash=sha256:2584f7cf844ac4d970fba483a717dbe10c1c1c96a969bf65d61ffe94df1b2863 \ + --hash=sha256:2971bb5ffe72cc0f555c13e19b23c85b654dd2a8f7ab493c262071377bfce9f6 \ + --hash=sha256:29d2c342c4bc01b88402d60189f3df065fb0dda3654744d5a165a5288a657368 \ + --hash=sha256:2e203fdf807ac7e12ab59ca2bfcabb38c7cf0b33c41efeb00f8e5da1d86af480 \ + --hash=sha256:33e3d65a85a2a4a0dc3b092b938a4062b1a05f3a9abde65ea93b233bca0e03f2 \ + --hash=sha256:374a5e5049eda9e0a44c696c7ade3ff355f06b1fe0bb945ea3cac2bc336478a2 \ + --hash=sha256:37b0fe330e4a58d3c58b24d91d1eb102aeec675a3db4c292ec3928ecd892a9a6 \ + --hash=sha256:3d5639516376dce1940ea36edf408c554475369f5da2abd45d44621cb616f769 \ + --hash=sha256:42c6dcb030aefb668a2b7009c85b27f90e51e6a3b4d5c9bc4c57631292015b0d \ + --hash=sha256:4a7cd62e831afe623fbb7aabbb4fe583212115b3ef38a9f6b71869ba644624a2 \ + --hash=sha256:4ba762ed58e8d68657fc1281e9bb72e1c3e79cc5d464be146e260c541ec12d84 \ + --hash=sha256:4fc714bdbfb534f94034efaa6eadd74e5b93c8fa6315565a222f7b6f42ca1166 \ + --hash=sha256:4ffa2ebd4c8530079140dd2d7f794a9d9a73cbb8e9d59ffe24c63436efa8f271 \ + --hash=sha256:5a1504ad17ba4210df3a045132a7baeeba5a200e930f57512ee02909fc5c4cb5 \ + --hash=sha256:5c364564d17da23db1106787675fc7af45f2f7b58b4173bfdd105564e132e6fb \ + --hash=sha256:5e11661ce0fd30a6790e8bcdf263b9ec5988e95e63cf901972107efc49218b13 \ + --hash=sha256:5f54b118ce5de9ac21c363d9b3caa6c800341e8c47a508787e5868c6b79c9323 \ + --hash=sha256:5f5ff8d839f4566a474a969508fe1c5e59c31c80d9e140566f9a37bba7b8d556 \ + --hash=sha256:61817945f2fe7d166e75fbfb28004034b48e44878177fc54d81688e7b85a3665 \ + --hash=sha256:624e278a7d29b6445e4e813af92af37820fafb6dcc55c012c834f9e26f9aaaef \ + --hash=sha256:63e46b3169866bd62849936de036f901a9356e36376079b05efa83caeaa02ceb \ + --hash=sha256:6531b7ca5f951d663c339002e91aaebda765ec7d61b7d1e3991051906ddde119 \ + --hash=sha256:68665f4c17edcceecc112dfed5dbe6f92261fb9d6054b47d01bf6371a6196126 \ + --hash=sha256:696dd8d674d6ce621ab9d45b205df149399e4bb9aa34102c970b721554828510 \ + --hash=sha256:6f783e0ec4803c787bcea93e13e9932edab72068f68ecffdf86a99fd5918878b \ + --hash=sha256:723314c1d51722ab28bfcd5240d858512ffd3116449c557a1336cbe3919beb87 \ + --hash=sha256:74b9127ffea03643e998e0c5ad9bd3811d3dac8c676e47db17b0ee7c3c3bf35f \ + --hash=sha256:7530e201d10d7d14abce4fb54cfe5b94a0aefc87da539d0346a484ead376c3cc \ + --hash=sha256:77733e3892bb0a7fa797826361ce8a9184d25c8dffaec60b7ffe928153680ba8 \ + --hash=sha256:78ddaaa81421a29574a682b3179d4cf9e6d405a09b99d93ddcf7e5239c742e21 \ + --hash=sha256:7c9129eb40958b3d4500fa2467e6a83356b3b61bfff1b414c7361d9220f9ae8f \ + --hash=sha256:7d32706badfe136888bdea71c0def994644e09fff0bfe47441deaed8e96fdbc6 \ + --hash=sha256:81965a16b675b35e1d09dd14df53f190f9129c0202356ed44ab2728b1c905658 \ + --hash=sha256:8394d940e5d400d04cad4f75c0598665cbb81aecefaca82ca85bd28264af7f9b \ + --hash=sha256:86d2f57d3e1379a9525c5ab067b27dbb8a0642fb5d454e17a9ac434f9ce523e3 \ + --hash=sha256:883a91b5dd7d26492ff2f04f40fbb652de40fcc0afe07e8129e8ae779c2110eb \ + --hash=sha256:88ad334a15b32a791ea935af224b9de1bf99bcd62fabf745d5f3442199d86d59 \ + --hash=sha256:9261d3ce84fa1d38ed649c3638feefeae23d32ba9182963e465d58d62203bd24 \ + --hash=sha256:97df63000f4fea395b2824da80e169731088656d1818a11b95f3b173747b6cd9 \ + --hash=sha256:98d134c954828488b153d88ba1f34e14259284f256180ce659e8d83e9c05eaa3 \ + --hash=sha256:996a38a83508c54c78a5f41456b0103c30508fed9abcad0a59b876d7398f25fd \ + --hash=sha256:9a5bce9d23aac8f0cf0836ecfc033896aa8443b501c58d0602dbfd5bd5b37753 \ + --hash=sha256:9a6b5099eeec78827553827f4c6b8615978bb4b6a88e5d9b93eddf8bb6790f55 \ + --hash=sha256:9d18368b137c6295db49ce7218b1a9ba15c5bc254c96d7c9f9e924a9bc7825ad \ + --hash=sha256:a4fa4fc04dff799089689f4fd502ce7d59de529fc2f40a2c8836886c03e0175a \ + --hash=sha256:a5c7ba8ffb6d6f8f2ab08743be203654bb1aaa8c9dcb09f82ddd34eadb695605 \ + --hash=sha256:aea443fffa9fbe3af1a9ba721a87f926fe548d32cab71d188a6ede77d0ff244e \ + --hash=sha256:b10bd51f823d891193d4717448fab065733958bdb6a6b351967bd349d48d5c9b \ + --hash=sha256:ba1a0996f6c2773bd83e63f18914c1de3c9dd26d55f4ac302a7efe93fb8e7433 \ + --hash=sha256:bb2802e667b7051a1bebbfe93684841cc9351004e2badbd6411bf357ab8d5ac8 \ + --hash=sha256:cfdd16ab5e59fc31b5e906d1a3f666571abc367598e3e02c83403acabc092e07 \ + --hash=sha256:d06b0c8da4f16d1d1e352134427cb194a0a6e19ad5db9161bf32b2113409e728 \ + --hash=sha256:d0776dea117cf5272382634bd2a5c1b6eb16767c223c6a5317cd3e2a757c61a0 \ + --hash=sha256:d18ca8148bebe1b0a382a27a8ee60350091a6ddaf475fa05ef50dc35b5df6327 \ + --hash=sha256:d4488a93b071c04dc20f5cecc3631fc78b9789dd72483ba15d423b5b3689b555 \ + --hash=sha256:d5f7a395a8cf1621939692dba2a6b6a830efa6b3cee787d82c7de1ad2930de64 \ + --hash=sha256:d7a80d21d613eec45e3d41eb22f8f94ddc758a6c4720842dc74c0581f54993d6 \ + --hash=sha256:d97683ddee4723ae8c95d1eddac7c192e8c552da0c73a925a89fa8649bf13eea \ + --hash=sha256:dcedcd19a557e182628afa1d553c3895a9f825b936415d0dbd3cd0bbcfd29b4b \ + --hash=sha256:de6d1d1b9e5101508cb37ab0d972357cac5235f5c6533d1071964c47139257df \ + --hash=sha256:df49e7a0861a8c36d089c1ed57d308623d60416dab2647a4a17fe050ba85de0e \ + --hash=sha256:df933278128ea1cd77772673c73954e53a1c95a4fdf41eef97c2b779271bd0bd \ + --hash=sha256:e08277a400de01bc72436a0ccd02bdf596631411f592ad985dcee21445bd0068 \ + --hash=sha256:e38e63e6f3d1cec5a27e0afe90a085af8b6806ee208b33030e65b6516353f1a3 \ + --hash=sha256:e55541f756f9b3ee346b840103f32779c695a19826a4c442b7954550a0972040 \ + --hash=sha256:ec4e55f79b1c4ffb2eecd8a0cfba9955a2588497d96851f4c8f99aa4a1d39b12 \ + --hash=sha256:ed1a53de42fbe34853ba90513cea21673481cd81ed1be739f7f2efb931b24916 \ + --hash=sha256:ed541d70698978a20eb63d8c5d72f2cc6d7079d9d90f6b50bad07826f1320f5f \ + --hash=sha256:f09e2ff1f17c2b51f2bc76d1cc33da96298f0a036a137f5440ab3ec5360b624f \ + --hash=sha256:f220b0eea5965dec25480b6333c788fb72ce5f9129e8759ef876a1d805d00801 \ + --hash=sha256:f3e0da4ebaef65158d4dfd7d3678aad692f7666877df0002b8a522cdf088f231 \ + --hash=sha256:f455ee30a9d61d3e1a15abd5068827773d6e4dc513e795f380cdd59932c782d5 \ + --hash=sha256:f5ef8f42bec47f21d07668a043f077d507e5bf4e668d5c6dfe6aaba89de1a5b8 \ + --hash=sha256:f69a8e0b033b747bb3e36a44e7732f0c99f7edd5cea723d45bc0d6e95377ffee \ + --hash=sha256:ff02b6d461a6de369f07ec15e465a88895f3223eb75073ffea56b84d9331f607 # via pydantic -pydantic-settings==2.4.0 \ - --hash=sha256:bb6849dc067f1687574c12a639e231f3a6feeed0a12d710c1382045c5db1c315 \ - --hash=sha256:ed81c3a0f46392b4d7c0a565c05884e6e54b3456e6f0fe4d8814981172dc9a88 +pydantic-settings==2.6.0 \ + --hash=sha256:44a1804abffac9e6a30372bb45f6cafab945ef5af25e66b1c634c01dd39e0188 \ + --hash=sha256:4a819166f119b74d7f8c765196b165f95cc7487ce58ea27dec8a5a26be0970e0 # via hexkit pygments==2.18.0 \ --hash=sha256:786ff802f32e91311bff3889f6e9a86e81505fe99f2735bb6d60ae0c5004f199 \ --hash=sha256:b8e6aca0523f3ab76fee51799c488e38782ac06eafcf95e7ba832985c8e7b13a # via rich -pymongo==4.8.0 \ - --hash=sha256:0fc18b3a093f3db008c5fea0e980dbd3b743449eee29b5718bc2dc15ab5088bb \ - --hash=sha256:16e5019f75f6827bb5354b6fef8dfc9d6c7446894a27346e03134d290eb9e758 \ - --hash=sha256:180d5eb1dc28b62853e2f88017775c4500b07548ed28c0bd9c005c3d7bc52526 \ - --hash=sha256:18c9d8f975dd7194c37193583fd7d1eb9aea0c21ee58955ecf35362239ff31ac \ - --hash=sha256:236bbd7d0aef62e64caf4b24ca200f8c8670d1a6f5ea828c39eccdae423bc2b2 \ - --hash=sha256:284d0717d1a7707744018b0b6ee7801b1b1ff044c42f7be7a01bb013de639470 \ - --hash=sha256:2ecd71b9226bd1d49416dc9f999772038e56f415a713be51bf18d8676a0841c8 \ - --hash=sha256:31e4d21201bdf15064cf47ce7b74722d3e1aea2597c6785882244a3bb58c7eab \ - --hash=sha256:3b5802151fc2b51cd45492c80ed22b441d20090fb76d1fd53cd7760b340ff554 \ - --hash=sha256:3c68fe128a171493018ca5c8020fc08675be130d012b7ab3efe9e22698c612a1 \ - --hash=sha256:3ed1c316718a2836f7efc3d75b4b0ffdd47894090bc697de8385acd13c513a70 \ - --hash=sha256:408b2f8fdbeca3c19e4156f28fff1ab11c3efb0407b60687162d49f68075e63c \ - --hash=sha256:417369ce39af2b7c2a9c7152c1ed2393edfd1cbaf2a356ba31eb8bcbd5c98dd7 \ - --hash=sha256:454f2295875744dc70f1881e4b2eb99cdad008a33574bc8aaf120530f66c0cde \ - --hash=sha256:47ec8c3f0a7b2212dbc9be08d3bf17bc89abd211901093e3ef3f2adea7de7a69 \ - --hash=sha256:4bf58e6825b93da63e499d1a58de7de563c31e575908d4e24876234ccb910eba \ - --hash=sha256:519d1bab2b5e5218c64340b57d555d89c3f6c9d717cecbf826fb9d42415e7750 \ - --hash=sha256:52b4108ac9469febba18cea50db972605cc43978bedaa9fea413378877560ef8 \ - --hash=sha256:658d0170f27984e0d89c09fe5c42296613b711a3ffd847eb373b0dbb5b648d5f \ - --hash=sha256:6b50040d9767197b77ed420ada29b3bf18a638f9552d80f2da817b7c4a4c9c68 \ - --hash=sha256:7148419eedfea9ecb940961cfe465efaba90595568a1fb97585fb535ea63fe2b \ - --hash=sha256:77f53429515d2b3e86dcc83dadecf7ff881e538c168d575f3688698a8707b80a \ - --hash=sha256:87075a1feb1e602e539bdb1ef8f4324a3427eb0d64208c3182e677d2c0718b6f \ - --hash=sha256:8b18c8324809539c79bd6544d00e0607e98ff833ca21953df001510ca25915d1 \ - --hash=sha256:9097c331577cecf8034422956daaba7ec74c26f7b255d718c584faddd7fa2e3c \ - --hash=sha256:920d4f8f157a71b3cb3f39bc09ce070693d6e9648fb0e30d00e2657d1dca4e49 \ - --hash=sha256:9365166aa801c63dff1a3cb96e650be270da06e3464ab106727223123405510f \ - --hash=sha256:940d456774b17814bac5ea7fc28188c7a1338d4a233efbb6ba01de957bded2e8 \ - --hash=sha256:aec2b9088cdbceb87e6ca9c639d0ff9b9d083594dda5ca5d3c4f6774f4c81b33 \ - --hash=sha256:af3e98dd9702b73e4e6fd780f6925352237f5dce8d99405ff1543f3771201704 \ - --hash=sha256:b6564780cafd6abeea49759fe661792bd5a67e4f51bca62b88faab497ab5fe89 \ - --hash=sha256:b747c0e257b9d3e6495a018309b9e0c93b7f0d65271d1d62e572747f4ffafc88 \ - --hash=sha256:bf821bd3befb993a6db17229a2c60c1550e957de02a6ff4dd0af9476637b2e4d \ - --hash=sha256:c6b804bb4f2d9dc389cc9e827d579fa327272cdb0629a99bfe5b83cb3e269ebf \ - --hash=sha256:cc8b8582f4209c2459b04b049ac03c72c618e011d3caa5391ff86d1bda0cc486 \ - --hash=sha256:cd39455b7ee70aabee46f7399b32ab38b86b236c069ae559e22be6b46b2bbfc4 \ - --hash=sha256:d0cf61450feadca81deb1a1489cb1a3ae1e4266efd51adafecec0e503a8dcd84 \ - --hash=sha256:d18d86bc9e103f4d3d4f18b85a0471c0e13ce5b79194e4a0389a224bb70edd53 \ - --hash=sha256:d5428dbcd43d02f6306e1c3c95f692f68b284e6ee5390292242f509004c9e3a8 \ - --hash=sha256:de3a860f037bb51f968de320baef85090ff0bbb42ec4f28ec6a5ddf88be61871 \ - --hash=sha256:e0061af6e8c5e68b13f1ec9ad5251247726653c5af3c0bbdfbca6cf931e99216 \ - --hash=sha256:e5df28f74002e37bcbdfdc5109799f670e4dfef0fb527c391ff84f078050e7b5 \ - --hash=sha256:e6a720a3d22b54183352dc65f08cd1547204d263e0651b213a0a2e577e838526 \ - --hash=sha256:e8400587d594761e5136a3423111f499574be5fd53cf0aefa0d0f05b180710b0 \ - --hash=sha256:e84bc7707492f06fbc37a9f215374d2977d21b72e10a67f1b31893ec5a140ad8 \ - --hash=sha256:ef7225755ed27bfdb18730c68f6cb023d06c28f2b734597480fb4c0e500feb6f \ - --hash=sha256:f2b7bec27e047e84947fbd41c782f07c54c30c76d14f3b8bf0c89f7413fac67a \ - --hash=sha256:f2fbdb87fe5075c8beb17a5c16348a1ea3c8b282a5cb72d173330be2fecf22f5 \ - --hash=sha256:f5bf0eb8b6ef40fa22479f09375468c33bebb7fe49d14d9c96c8fd50355188b0 \ - --hash=sha256:fdc20cd1e1141b04696ffcdb7c71e8a4a665db31fe72e51ec706b3bdd2d09f36 +pymongo==4.9.2 \ + --hash=sha256:0e759ed0459e7264a11b6896016f616341a8e4c6ab7f71ae651bd21ffc7e9524 \ + --hash=sha256:169b85728cc17800344ba17d736375f400ef47c9fbb4c42910c4b3e7c0247382 \ + --hash=sha256:1ad79d6a74f439a068caf9a1e2daeabc20bf895263435484bbd49e90fbea7809 \ + --hash=sha256:1fc70326ae71b3c7b8d6af82f46bb71dafdba3c8f335b29382ae9cf263ef3a5c \ + --hash=sha256:24e7b6887bbfefd05afed26a99a2c69459e2daa351a43a410de0d6c0ee3cce4e \ + --hash=sha256:2c8c861e77527eec5a4b7363c16030dd0374670b620b08a5300f97594bbf5a40 \ + --hash=sha256:3010018f5672e5b7e8d096dea9f1ea6545b05345ff0eb1754f6ee63785550773 \ + --hash=sha256:3039e093d28376d6a54bdaa963ca12230c8a53d7b19c8e6368e19bcfbd004176 \ + --hash=sha256:31c35d3dac5a1b0f65b3da2a19dc7fb88271c86329c75cfea775d5381ade6c06 \ + --hash=sha256:3c3c71337d4c923f719cb56253af9244e90353a2454088ee4f184bfb0dd446a4 \ + --hash=sha256:3e63535946f5df7848307b9031aa921f82bb0cbe45f9b0c3296f2173f9283eb0 \ + --hash=sha256:3f55efe0f77198c055800e605268bfd77a3f0223d1a80b55b771d0c350bc3ade \ + --hash=sha256:410ea165f2f819118eed764c5faa35fa71aeff5ce8b5046af99ed158a5661e9e \ + --hash=sha256:5af264b9a973859123e3129d131d7246f57659304400e3e6b35ed6eaf099854d \ + --hash=sha256:65c6b2e2a6db38f49433021dda0802ad081118224b2264500ef03a2d82ae26a7 \ + --hash=sha256:69394ee9f0ce38ff71266bad01b7e045cd75e58500ebad5d72187cbabf2e652a \ + --hash=sha256:6ab42d9ee93fe6b90020c42cba5bfb43a2b4660951225d137835efc21940da48 \ + --hash=sha256:6c798351666ac97a0ddaa823689061c3af949c2d6acf7fb2d9ab0a7f465ced79 \ + --hash=sha256:6f6834d575ed87edc7dfcab4501d961b6a423b3839edd29ecb1382eee7736777 \ + --hash=sha256:77528a2b928fe3f1f655cefa195e6718ab1ccd1a456aba486d76318e526a7fac \ + --hash=sha256:7a0b2e7fedc5911cd44590b5fd8e3714029f378f37f3c0c2043f67150b588d4a \ + --hash=sha256:7fb10d7069f1e7d7d6a458b1c5e9d1454be6eca2d9885bec25c1202e22c88d2a \ + --hash=sha256:8083bbe8cb10bb33dca4d93f8223dd8d848215250bb73867374650bac5fe69e1 \ + --hash=sha256:80a1ee9b72eebd96619ebe0beb718a5bcf2a70f464edf315f97b9315ed6854a9 \ + --hash=sha256:877699e21703717507cbbea23e75b419f81a513b50b65531e1698df08b2d7094 \ + --hash=sha256:87b18094100f21615d9db99c255dcd9e93e476f10fb03c1d3632cf4b82d201d2 \ + --hash=sha256:8aac5dce28454f47576063fbad31ea9789bba67cab86c95788f97aafd810e65b \ + --hash=sha256:96ad54433a996e2d1985a9cd8fc82538ca8747c95caae2daf453600cc8c317f9 \ + --hash=sha256:98b9cade40f5b13e04492a42ae215c3721099be1014ddfe0fbd23f27e4f62c0c \ + --hash=sha256:99e40f44877b32bf4b3c46ceed2228f08c222cf7dec8a4366dd192a1429143fa \ + --hash=sha256:a1b8c636bf557c7166e3799bbf1120806ca39e3f06615b141c88d9c9ceae4d8c \ + --hash=sha256:a49d9292f22a0395c0fd2822a06e385910f1f902c3a9feafc1d0bfc27cd2df6b \ + --hash=sha256:a663ca60e187a248d370c58961e40f5463077d2b43831eb92120ea28a79ecf96 \ + --hash=sha256:a92c96886048d3ebae62dbcfc775c7f2b965270160e3cb6aab4e06750e030b05 \ + --hash=sha256:aac78b5fdd49ed8cae49adf76befacb02293a23b412676775c4715148e166d85 \ + --hash=sha256:ab8d54529feb6e29035ba8f0570c99ad36424bc26486c238ad7ce28597bc43c8 \ + --hash=sha256:ae227bba43e2e6fc8c3440a70b3b8f9ab2b0eb0906d0d2cf814dd9490c572e2a \ + --hash=sha256:b3254769e708bc4aa634745c262081d13c841a80038eff3afd15631540a1d227 \ + --hash=sha256:b6e7251d59fa3dcbb1399a71a3aec63768cebc6b22180b671601c2195fe1f90a \ + --hash=sha256:ba9d2f6df977fee24437f82f7412460b0628cd6b961c4235c9cff71577a5b61f \ + --hash=sha256:bc9322ce7cf116458a637ac10517b0c5926a8211202be6dbdc51dab4d4a9afc8 \ + --hash=sha256:bf77bf175c315e299a91332c2bbebc097c4d4fcc8713e513a9861684aa39023a \ + --hash=sha256:bf963104dfd7235bebc44cef40b4b12c6638bb03b3a828cb495498e286b6edd0 \ + --hash=sha256:c3f28afd783be3cebef1235a45340589169d7774cd9909ba0249e2f851ff511d \ + --hash=sha256:c42b5aad8971256365bfd0a545fb1c7a199c93db80decd298ea2f987419e2a6d \ + --hash=sha256:cca029f46acf475504eedb33c7839f030c4bc4f946dcba12d9a954cc48850b79 \ + --hash=sha256:cd832de5df92caa68ee66c872708951d7e0c1f7b289b74189f2ccf1832c56dda \ + --hash=sha256:d1d5e7123af1fddf15b2b53e58f20bf5242884e671bcc3860f5e954fe13aeddd \ + --hash=sha256:dde6068ae7c62ea8ee2c5701f78c6a75618cada7e11f03893687df87709558de \ + --hash=sha256:e1ab6cd7cd2d38ffc7ccdc79fdc166c7a91a63f844a96e3e6b2079c054391c68 \ + --hash=sha256:e3ff4201ea707f57bf381f61df0e9cd6e896627a59f98a5d1c4a1bd14a2544cb \ + --hash=sha256:e54e2c6f1dec45c57a587b4c13c16666d5f7c031a642ae177140d1e0551a947e \ + --hash=sha256:ea9c47f86a322280381e9ddba7491e664ea80bf75df247ea2346faf7626e4e4c \ + --hash=sha256:f13330bdf4a57ef70bdd6282721547ec464f773203be47bac1efc4abd74a9190 \ + --hash=sha256:f2f43e5d6e739aa78c7053bdf351453c0e53d7667a3cac73255c2169631e052a \ + --hash=sha256:f3fc60f242191840ccf02b898bc615b5141fbb70064f38f7e60fcaa35d3b5efd \ + --hash=sha256:f928bdc152a995cbd0b563fab201b2df873846d11f7a41d1f8cc8a01b35591ab \ + --hash=sha256:fdbd558d90b55d7c39c096a79f8a725f1f02b658211924ab98dbc03ecad01095 \ + --hash=sha256:fe97c847b56d61e533a7af0334193d6b28375b9189effce93129c7e4733794a9 # via motor -pytest==8.3.2 \ - --hash=sha256:4ba08f9ae7dcf84ded419494d229b48d0903ea6407b030eaec46df5e6a73bba5 \ - --hash=sha256:c132345d12ce551242c87269de812483f5bcc87cdbb4722e48487ba194f9fdce +pytest==8.3.3 \ + --hash=sha256:70b98107bd648308a7952b06e6ca9a50bc660be218d53c257cc1fc94fda10181 \ + --hash=sha256:a6853c7375b2663155079443d2e45de913a911a11d669df02a50814944db57b2 # via # -r lock/requirements-dev-template.in # pytest-asyncio @@ -690,9 +717,9 @@ pytest-cov==5.0.0 \ --hash=sha256:4f0764a1219df53214206bf1feea4633c3b558a2925c8b59f144f682861ce652 \ --hash=sha256:5837b58e9f6ebd335b0f8060eecce69b662415b16dc503883a02f45dfeb14857 # via -r lock/requirements-dev-template.in -pytest-httpx==0.30.0 \ - --hash=sha256:6d47849691faf11d2532565d0c8e0e02b9f4ee730da31687feae315581d7520c \ - --hash=sha256:755b8edca87c974dd4f3605c374fda11db84631de3d163b99c0df5807023a19a +pytest-httpx==0.32.0 \ + --hash=sha256:685d93ce5e5edb5e52310b72342cdc190bebf83aab058328943dd8bd8f6ac790 \ + --hash=sha256:7807647e8254e5cff79bf2041ae272449ce915d3cf1bbecaa581c384163adb87 # via -r lock/requirements-dev-template.in python-dateutil==2.9.0.post0 \ --hash=sha256:37dd54208da7e1cd875388217d5e00ebd4179249f90fb72437e91a35459a0ad3 \ @@ -704,9 +731,9 @@ python-dotenv==1.0.1 \ # via # pydantic-settings # uvicorn -python-multipart==0.0.9 \ - --hash=sha256:03f54688c663f1b7977105f021043b0793151e4cb1c1a9d4a11fc13d622c4026 \ - --hash=sha256:97ca7b8ea7b05f977dc3849c3ba99d51689822fab725c3703af7c866a0c2b215 +python-multipart==0.0.14 \ + --hash=sha256:b8e744731296767cb005e1e9bd7bb985a77aa077de5406dbe59b588559b6f350 \ + --hash=sha256:bf01aea0941cd1173a97b7c53d8b686acd2fa535549b13431d8515467dabb2b4 # via fastapi pyyaml==6.0.2 \ --hash=sha256:01179a4a8559ab5de078078f37e5c1a30d76bb88519906844fd7bdea1b7729ff \ @@ -779,9 +806,9 @@ requests==2.32.3 \ # via # -r lock/requirements-dev-template.in # docker -rich==13.7.1 \ - --hash=sha256:4edbae314f59eb482f54e9e30bf00d33350aaa94f4bfcd4e9e3110e64d0d7222 \ - --hash=sha256:9be308cb1fe2f1f57d67ce99e95af38a1e2bc71ad9813b0e247cf7ffbcc3a432 +rich==13.9.3 \ + --hash=sha256:9836f5096eb2172c9e77df411c1b009bace4193d6a481d534fea75ebba758283 \ + --hash=sha256:bc1e01b899537598cf02579d2b9f4a415104d3fc439313a7a2c165d76557a08e # via typer rpds-py==0.20.0 \ --hash=sha256:06db23d43f26478303e954c34c75182356ca9aa7797d22c5345b16871ab9c45c \ @@ -890,33 +917,33 @@ rpds-py==0.20.0 \ # via # jsonschema # referencing -ruff==0.6.2 \ - --hash=sha256:094600ee88cda325988d3f54e3588c46de5c18dae09d683ace278b11f9d4d534 \ - --hash=sha256:1175d39faadd9a50718f478d23bfc1d4da5743f1ab56af81a2b6caf0a2394f23 \ - --hash=sha256:17002fe241e76544448a8e1e6118abecbe8cd10cf68fde635dad480dba594570 \ - --hash=sha256:239ee6beb9e91feb8e0ec384204a763f36cb53fb895a1a364618c6abb076b3be \ - --hash=sha256:279d5f7d86696df5f9549b56b9b6a7f6c72961b619022b5b7999b15db392a4da \ - --hash=sha256:2aed7e243be68487aa8982e91c6e260982d00da3f38955873aecd5a9204b1d66 \ - --hash=sha256:316d418fe258c036ba05fbf7dfc1f7d3d4096db63431546163b472285668132b \ - --hash=sha256:3dbeac76ed13456f8158b8f4fe087bf87882e645c8e8b606dd17b0b66c2c1158 \ - --hash=sha256:5b939f9c86d51635fe486585389f54582f0d65b8238e08c327c1534844b3bb9a \ - --hash=sha256:5c8cbc6252deb3ea840ad6a20b0f8583caab0c5ef4f9cca21adc5a92b8f79f3c \ - --hash=sha256:7438a7288f9d67ed3c8ce4d059e67f7ed65e9fe3aa2ab6f5b4b3610e57e3cb56 \ - --hash=sha256:7db6880c53c56addb8638fe444818183385ec85eeada1d48fc5abe045301b2f1 \ - --hash=sha256:a8f310d63af08f583363dfb844ba8f9417b558199c58a5999215082036d795a1 \ - --hash=sha256:d0d62ca91219f906caf9b187dea50d17353f15ec9bb15aae4a606cd697b49b4c \ - --hash=sha256:d371f7fc9cec83497fe7cf5eaf5b76e22a8efce463de5f775a1826197feb9df8 \ - --hash=sha256:d72b8b3abf8a2d51b7b9944a41307d2f442558ccb3859bbd87e6ae9be1694a5d \ - --hash=sha256:d9f3469c7dd43cd22eb1c3fc16926fb8258d50cb1b216658a07be95dd117b0f2 \ - --hash=sha256:f28fcd2cd0e02bdf739297516d5643a945cc7caf09bd9bcb4d932540a5ea4fa9 +ruff==0.7.0 \ + --hash=sha256:0cdf20c2b6ff98e37df47b2b0bd3a34aaa155f59a11182c1303cce79be715628 \ + --hash=sha256:10842f69c245e78d6adec7e1db0a7d9ddc2fff0621d730e61657b64fa36f207e \ + --hash=sha256:194d6c46c98c73949a106425ed40a576f52291c12bc21399eb8f13a0f7073495 \ + --hash=sha256:1eb54986f770f49edb14f71d33312d79e00e629a57387382200b1ef12d6a4ef9 \ + --hash=sha256:211d877674e9373d4bb0f1c80f97a0201c61bcd1e9d045b6e9726adc42c156aa \ + --hash=sha256:214b88498684e20b6b2b8852c01d50f0651f3cc6118dfa113b4def9f14faaf06 \ + --hash=sha256:47a86360cf62d9cd53ebfb0b5eb0e882193fc191c6d717e8bef4462bc3b9ea2b \ + --hash=sha256:496494d350c7fdeb36ca4ef1c9f21d80d182423718782222c29b3e72b3512737 \ + --hash=sha256:4b406c2dce5be9bad59f2de26139a86017a517e6bcd2688da515481c05a2cb11 \ + --hash=sha256:630fce3fefe9844e91ea5bbf7ceadab4f9981f42b704fae011bb8efcaf5d84be \ + --hash=sha256:82c2579b82b9973a110fab281860403b397c08c403de92de19568f32f7178598 \ + --hash=sha256:9af971fe85dcd5eaed8f585ddbc6bdbe8c217fb8fcf510ea6bca5bdfff56040e \ + --hash=sha256:ab7d98c7eed355166f367597e513a6c82408df4181a937628dbec79abb2a1fe4 \ + --hash=sha256:b641c7f16939b7d24b7bfc0be4102c56562a18281f84f635604e8a6989948914 \ + --hash=sha256:d71672336e46b34e0c90a790afeac8a31954fd42872c1f6adaea1dff76fd44f9 \ + --hash=sha256:dc452ba6f2bb9cf8726a84aa877061a2462afe9ae0ea1d411c53d226661c601d \ + --hash=sha256:f6c968509f767776f524a8430426539587d5ec5c662f6addb6aa25bc2e8195ec \ + --hash=sha256:ff4aabfbaaba880e85d394603b9e75d32b0693152e16fa659a3064a85df7fce2 # via -r lock/requirements-dev-template.in -s3transfer==0.10.2 \ - --hash=sha256:0711534e9356d3cc692fdde846b4a1e4b0cb6519971860796e6bc4c7aea00ef6 \ - --hash=sha256:eca1c20de70a39daee580aef4986996620f365c4e0fda6a86100231d62f1bf69 +s3transfer==0.10.3 \ + --hash=sha256:263ed587a5803c6c708d3ce44dc4dfedaab4c1a32e8329bab818933d79ddcf5d \ + --hash=sha256:4f50ed74ab84d474ce614475e0b8d5047ff080810aac5d01ea25231cfc944b0c # via boto3 -setuptools==73.0.1 \ - --hash=sha256:b208925fcb9f7af924ed2dc04708ea89791e24bde0d3020b27df0e116088b34e \ - --hash=sha256:d59a3e788ab7e012ab2c4baed1b376da6366883ee20d7a5fc426816e3d7b1193 +setuptools==75.2.0 \ + --hash=sha256:753bb6ebf1f465a1912e19ed1d41f403a79173a9acf66a42e7e6aec45c3c16ec \ + --hash=sha256:a7fcb66f68b4d9e8e66b42f9876150a3371558f98fa32222ffaa5bced76406f8 # via -r lock/requirements-dev-template.in shellingham==1.5.4 \ --hash=sha256:7ecfff8f2fd72616f7481040475a65b2bf8af90a56c89140852d1120324e8686 \ @@ -943,13 +970,13 @@ starlette==0.37.2 \ stringcase==1.2.0 \ --hash=sha256:48a06980661908efe8d9d34eab2b6c13aefa2163b3ced26972902e3bdfd87008 # via -r lock/requirements-dev-template.in -testcontainers==4.8.0 \ - --hash=sha256:0b85d787e5b1f8b32042704d23b6c54787bf6751d2d3cfee2c031349ef2eea30 \ - --hash=sha256:56153bb5938694844f0e6bd0cf82e19dd6a6516bc29881440e273939201a42d5 +testcontainers==4.8.2 \ + --hash=sha256:9e19af077cd96e1957c13ee466f1f32905bc6c5bc1bc98643eb18be1a989bfb0 \ + --hash=sha256:dd4a6a2ea09e3c3ecd39e180b6548105929d0bb78d665ce9919cb3f8c98f9853 # via -r lock/requirements-dev.in -tomli-w==1.0.0 \ - --hash=sha256:9f2a07e8be30a0729e533ec968016807069991ae2fd921a78d42f429ae5f4463 \ - --hash=sha256:f463434305e0336248cac9c2dc8076b707d8a12d019dd349f5c1e382dd1ae1b9 +tomli-w==1.1.0 \ + --hash=sha256:1403179c78193e3184bfaade390ddbd071cba48a32a2e62ba11aae47490c63f7 \ + --hash=sha256:49e847a3a304d516a169a601184932ef0f6b61623fe680f836a2aa7128ed0d33 # via -r lock/requirements-dev-template.in tornado==6.4.1 \ --hash=sha256:163b0aafc8e23d8cdc3c9dfb24c5368af84a81e3364745ccb4427669bf84aec8 \ @@ -964,9 +991,9 @@ tornado==6.4.1 \ --hash=sha256:d9a566c40b89757c9aa8e6f032bcdb8ca8795d7c1a9762910c722b1635c9de4d \ --hash=sha256:e2e20b9113cd7293f164dc46fffb13535266e713cdb87bd2d15ddb336e96cfc4 # via snakeviz -typer==0.12.4 \ - --hash=sha256:819aa03699f438397e876aa12b0d63766864ecba1b579092cc9fe35d886e34b6 \ - --hash=sha256:c9c1613ed6a166162705b3347b8d10b661ccc5d95692654d0fb628118f2c34e6 +typer==0.12.5 \ + --hash=sha256:62fe4e471711b147e3365034133904df3e235698399bc4de2b36c8579298d52b \ + --hash=sha256:f592f089bedcc8ec1b974125d64851029c3b1af145f04aca64d69410f0c9b722 # via # -r lock/requirements-dev-template.in # sms (pyproject.toml) @@ -982,34 +1009,34 @@ typing-extensions==4.12.2 \ # pydantic-core # testcontainers # typer -urllib3==2.2.2 \ - --hash=sha256:a448b2f64d686155468037e1ace9f2d2199776e17f0a46610480d311f73e3472 \ - --hash=sha256:dd505485549a7a552833da5e6063639d0d177c04f23bc3864e41e5dc5f612168 +urllib3==2.2.3 \ + --hash=sha256:ca899ca043dcb1bafa3e262d73aa25c465bfb49e0bd9dd5d59f1d0acba2f8fac \ + --hash=sha256:e7d814a81dad81e6caf2ec9fdedb284ecc9c73076b62654547cc64ccdcae26e9 # via # -r lock/requirements-dev-template.in # botocore # docker # requests # testcontainers -uv==0.3.2 \ - --hash=sha256:087677ea43adf09c09235e005d3b8b4fc7d8e29ca4846295bf9d29d273496fe3 \ - --hash=sha256:36af14c7f7759b15f72176e6937bd0209a18e412909d32bc14461569884a607d \ - --hash=sha256:4fb344ac7216d8b74e5af57ceffab8a22fa7e0f5883472760a58f34dee9197dd \ - --hash=sha256:63926400e5e9d3489442c68c0d0e66646e6b0b1b5eb60006c3a9d943d6306734 \ - --hash=sha256:6940bc8c36468d2c225d9e67bcf6a08a8a98d68226e9e17e89ce597c72225303 \ - --hash=sha256:6a45b55bf161e79b21408ea19a688465e2b1c0bcebb908e3050e9a358e333ed9 \ - --hash=sha256:864071d6b47a99b095dfd04b000db5ffc01d669960ea7bbc25aca2520e507900 \ - --hash=sha256:87d2e44ec5f225250c6b0ead25f4e37952d3b3f7c6f05741d603cf8446a4415e \ - --hash=sha256:8c0fd370d09b6dd7980a2add6eec3438f8a548032752ab9fbb0997d0f26d85d1 \ - --hash=sha256:9f131151d96159b54db358ee2538ceb41ec246d350fde3ad7f5dda2a4978551e \ - --hash=sha256:a037149ef4a26cf688dc2bfef72533c83d8d39579af3912e3c4733a41ead9de1 \ - --hash=sha256:abce3316c020c11b474d916c800615b446fca1cf96c084ec0540f2654d222d3d \ - --hash=sha256:af5d071b9583f16884d150b0bcec5ca3b40dae287aa8c69a83e87ed04f05f3d1 \ - --hash=sha256:b067982aadcad995da4fc647cac801441d781993e327b817da4eb3ac3cbb48f6 \ - --hash=sha256:c2cb5948b4cbd1723ab4ca459416207d7c3b6b6be960134b6a3af0336f982637 \ - --hash=sha256:ca0b247a4d05c097300c36185edf5fde358a3b3e5cc68bea6c15a89307dfab8b \ - --hash=sha256:d550c92ba53767b1046e71473857a2a631c6fde86fdccb689a798683e8ad8fe6 \ - --hash=sha256:e845335c8ec62d32daec97e48a0a1d5961b59e349b4a9a2762f9f70f3407d785 +uv==0.4.26 \ + --hash=sha256:1214caacc6b9f9c72749634c7a82a5d93123a44b70a1fa6a9d13993c126ca33e \ + --hash=sha256:23cee82020b9e973a5feba81c2cf359a5a09020216d98534926f45ee7b74521d \ + --hash=sha256:2ddb60d508b668b8da055651b30ff56c1efb79d57b064c218a7622b5c74b2af8 \ + --hash=sha256:391a6f5e31b212cb72a8f460493bbdf4088e66049666ad064ac8530230031289 \ + --hash=sha256:41f9876c22ad5b4518bffe9e50ec7169e242b64f139cdcaf42a76f70a9bd5c78 \ + --hash=sha256:468f806e841229c0bd6e1cffaaffc064720704623890cee15b42b877cef748c5 \ + --hash=sha256:6091075420eda571b0377d351c393b096514cb036a3199e033e003edaa0ff880 \ + --hash=sha256:6f66f11e088d231b7e305f089dc949b0e6b1d65e0a877b50ba5c3ae26e151144 \ + --hash=sha256:70a108399d6c9e3d1f4a0f105d6d016f97f292dbb6c724e1ed2e6dc9f6872c79 \ + --hash=sha256:9560c2eb234ea92276bbc647854d4a9e75556981c1193c3cc59f6613f7d177f2 \ + --hash=sha256:9a63a6fe6f249a9fff72328204c3e6b457aae5914590e6881b9b39dcc72d24df \ + --hash=sha256:a41bdd09b9a3ddc8f459c73e924485e1caae43e43305cedb65f5feac05cf184a \ + --hash=sha256:acaa25b304db6f1e8064d3280532ecb80a58346e37f4199659269847848c4da0 \ + --hash=sha256:c4c69532cb4d0c1e160883142b8bf0133a5a67e9aed5148e13743ae55c2dfc03 \ + --hash=sha256:d1ca5183afab454f28573a286811019b3552625af2cd1cd3996049d3bbfdb1ca \ + --hash=sha256:e086ebe200e9718e9622af405d45caad9d84b60824306fcb220335fe6fc90966 \ + --hash=sha256:e826b544020ef407387ed734a89850cac011ee4b5daf94b4f616b71eff2c8a94 \ + --hash=sha256:e9f45d8765a037a13ddedebb9e36fdcf06b7957654cfa8055d84f19eba12957e # via -r lock/requirements-dev-template.in uvicorn==0.29.0 \ --hash=sha256:2c2aac7ff4f4365c206fd773a39bf4ebd1047c238f8b8268ad996829323473de \ @@ -1018,219 +1045,221 @@ uvicorn==0.29.0 \ # fastapi # fastapi-cli # ghga-service-commons -uvloop==0.20.0 \ - --hash=sha256:265a99a2ff41a0fd56c19c3838b29bf54d1d177964c300dad388b27e84fd7847 \ - --hash=sha256:2beee18efd33fa6fdb0976e18475a4042cd31c7433c866e8a09ab604c7c22ff2 \ - --hash=sha256:35968fc697b0527a06e134999eef859b4034b37aebca537daeb598b9d45a137b \ - --hash=sha256:36c530d8fa03bfa7085af54a48f2ca16ab74df3ec7108a46ba82fd8b411a2315 \ - --hash=sha256:3a609780e942d43a275a617c0839d85f95c334bad29c4c0918252085113285b5 \ - --hash=sha256:4603ca714a754fc8d9b197e325db25b2ea045385e8a3ad05d3463de725fdf469 \ - --hash=sha256:4b75f2950ddb6feed85336412b9a0c310a2edbcf4cf931aa5cfe29034829676d \ - --hash=sha256:4f44af67bf39af25db4c1ac27e82e9665717f9c26af2369c404be865c8818dcf \ - --hash=sha256:6462c95f48e2d8d4c993a2950cd3d31ab061864d1c226bbf0ee2f1a8f36674b9 \ - --hash=sha256:649c33034979273fa71aa25d0fe120ad1777c551d8c4cd2c0c9851d88fcb13ab \ - --hash=sha256:746242cd703dc2b37f9d8b9f173749c15e9a918ddb021575a0205ec29a38d31e \ - --hash=sha256:77fbc69c287596880ecec2d4c7a62346bef08b6209749bf6ce8c22bbaca0239e \ - --hash=sha256:80dc1b139516be2077b3e57ce1cb65bfed09149e1d175e0478e7a987863b68f0 \ - --hash=sha256:82edbfd3df39fb3d108fc079ebc461330f7c2e33dbd002d146bf7c445ba6e756 \ - --hash=sha256:89e8d33bb88d7263f74dc57d69f0063e06b5a5ce50bb9a6b32f5fcbe655f9e73 \ - --hash=sha256:94707205efbe809dfa3a0d09c08bef1352f5d3d6612a506f10a319933757c006 \ - --hash=sha256:95720bae002ac357202e0d866128eb1ac82545bcf0b549b9abe91b5178d9b541 \ - --hash=sha256:9b04d96188d365151d1af41fa2d23257b674e7ead68cfd61c725a422764062ae \ - --hash=sha256:9d0fba61846f294bce41eb44d60d58136090ea2b5b99efd21cbdf4e21927c56a \ - --hash=sha256:9ebafa0b96c62881d5cafa02d9da2e44c23f9f0cd829f3a32a6aff771449c996 \ - --hash=sha256:a0fac7be202596c7126146660725157d4813aa29a4cc990fe51346f75ff8fde7 \ - --hash=sha256:aea15c78e0d9ad6555ed201344ae36db5c63d428818b4b2a42842b3870127c00 \ - --hash=sha256:b10c2956efcecb981bf9cfb8184d27d5d64b9033f917115a960b83f11bfa0d6b \ - --hash=sha256:b16696f10e59d7580979b420eedf6650010a4a9c3bd8113f24a103dfdb770b10 \ - --hash=sha256:d8c36fdf3e02cec92aed2d44f63565ad1522a499c654f07935c8f9d04db69e95 \ - --hash=sha256:e237f9c1e8a00e7d9ddaa288e535dc337a39bcbf679f290aee9d26df9e72bce9 \ - --hash=sha256:e50289c101495e0d1bb0bfcb4a60adde56e32f4449a67216a1ab2750aa84f037 \ - --hash=sha256:e7d61fe8e8d9335fac1bf8d5d82820b4808dd7a43020c149b63a1ada953d48a6 \ - --hash=sha256:e97152983442b499d7a71e44f29baa75b3b02e65d9c44ba53b10338e98dedb66 \ - --hash=sha256:f0e94b221295b5e69de57a1bd4aeb0b3a29f61be6e1b478bb8a69a73377db7ba \ - --hash=sha256:fee6044b64c965c425b65a4e17719953b96e065c5b7e09b599ff332bb2744bdf +uvloop==0.21.0 \ + --hash=sha256:0878c2640cf341b269b7e128b1a5fed890adc4455513ca710d77d5e93aa6d6a0 \ + --hash=sha256:10d66943def5fcb6e7b37310eb6b5639fd2ccbc38df1177262b0640c3ca68c1f \ + --hash=sha256:10da8046cc4a8f12c91a1c39d1dd1585c41162a15caaef165c2174db9ef18bdc \ + --hash=sha256:17df489689befc72c39a08359efac29bbee8eee5209650d4b9f34df73d22e414 \ + --hash=sha256:183aef7c8730e54c9a3ee3227464daed66e37ba13040bb3f350bc2ddc040f22f \ + --hash=sha256:196274f2adb9689a289ad7d65700d37df0c0930fd8e4e743fa4834e850d7719d \ + --hash=sha256:221f4f2a1f46032b403bf3be628011caf75428ee3cc204a22addf96f586b19fd \ + --hash=sha256:2d1f581393673ce119355d56da84fe1dd9d2bb8b3d13ce792524e1607139feff \ + --hash=sha256:359ec2c888397b9e592a889c4d72ba3d6befba8b2bb01743f72fffbde663b59c \ + --hash=sha256:3bf12b0fda68447806a7ad847bfa591613177275d35b6724b1ee573faa3704e3 \ + --hash=sha256:4509360fcc4c3bd2c70d87573ad472de40c13387f5fda8cb58350a1d7475e58d \ + --hash=sha256:460def4412e473896ef179a1671b40c039c7012184b627898eea5072ef6f017a \ + --hash=sha256:461d9ae6660fbbafedd07559c6a2e57cd553b34b0065b6550685f6653a98c1cb \ + --hash=sha256:46923b0b5ee7fc0020bef24afe7836cb068f5050ca04caf6b487c513dc1a20b2 \ + --hash=sha256:53e420a3afe22cdcf2a0f4846e377d16e718bc70103d7088a4f7623567ba5fb0 \ + --hash=sha256:5ee4d4ef48036ff6e5cfffb09dd192c7a5027153948d85b8da7ff705065bacc6 \ + --hash=sha256:67dd654b8ca23aed0a8e99010b4c34aca62f4b7fce88f39d452ed7622c94845c \ + --hash=sha256:787ae31ad8a2856fc4e7c095341cccc7209bd657d0e71ad0dc2ea83c4a6fa8af \ + --hash=sha256:86975dca1c773a2c9864f4c52c5a55631038e387b47eaf56210f873887b6c8dc \ + --hash=sha256:87c43e0f13022b998eb9b973b5e97200c8b90823454d4bc06ab33829e09fb9bb \ + --hash=sha256:88cb67cdbc0e483da00af0b2c3cdad4b7c61ceb1ee0f33fe00e09c81e3a6cb75 \ + --hash=sha256:8a375441696e2eda1c43c44ccb66e04d61ceeffcd76e4929e527b7fa401b90fb \ + --hash=sha256:a5c39f217ab3c663dc699c04cbd50c13813e31d917642d459fdcec07555cc553 \ + --hash=sha256:b9fb766bb57b7388745d8bcc53a359b116b8a04c83a2288069809d2b3466c37e \ + --hash=sha256:baa0e6291d91649c6ba4ed4b2f982f9fa165b5bbd50a9e203c416a2797bab3c6 \ + --hash=sha256:baa4dcdbd9ae0a372f2167a207cd98c9f9a1ea1188a8a526431eef2f8116cc8d \ + --hash=sha256:bc09f0ff191e61c2d592a752423c767b4ebb2986daa9ed62908e2b1b9a9ae206 \ + --hash=sha256:bd53ecc9a0f3d87ab847503c2e1552b690362e005ab54e8a48ba97da3924c0dc \ + --hash=sha256:bfd55dfcc2a512316e65f16e503e9e450cab148ef11df4e4e679b5e8253a5281 \ + --hash=sha256:c097078b8031190c934ed0ebfee8cc5f9ba9642e6eb88322b9958b649750f72b \ + --hash=sha256:c0f3fa6200b3108919f8bdabb9a7f87f20e7097ea3c543754cabc7d717d95cf8 \ + --hash=sha256:e678ad6fe52af2c58d2ae3c73dc85524ba8abe637f134bf3564ed07f555c5e79 \ + --hash=sha256:ec7e6b09a6fdded42403182ab6b832b71f4edaf7f37a9a0e371a01db5f0cb45f \ + --hash=sha256:f0ce1b49560b1d2d8a2977e3ba4afb2414fb46b86a1b64056bc4ab929efdafbe \ + --hash=sha256:f38b2e090258d051d68a5b14d1da7203a3c3677321cf32a95a6f4db4dd8b6f26 \ + --hash=sha256:f3df876acd7ec037a3d005b3ab85a7e4110422e4d9c1571d4fc89b0fc41b6816 \ + --hash=sha256:f7089d2dc73179ce5ac255bdf37c236a9f914b264825fdaacaded6990a7fb4c2 # via uvicorn -virtualenv==20.26.3 \ - --hash=sha256:4c43a2a236279d9ea36a0d76f98d84bd6ca94ac4e0f4a3b9d46d05e10fea542a \ - --hash=sha256:8cc4a31139e796e9a7de2cd5cf2489de1217193116a8fd42328f1bd65f434589 +virtualenv==20.27.0 \ + --hash=sha256:2ca56a68ed615b8fe4326d11a0dca5dfbe8fd68510fb6c6349163bed3c15f2b2 \ + --hash=sha256:44a72c29cceb0ee08f300b314848c86e57bf8d1f13107a5e671fb9274138d655 # via pre-commit -watchfiles==0.23.0 \ - --hash=sha256:02b7ba9d4557149410747353e7325010d48edcfe9d609a85cb450f17fd50dc3d \ - --hash=sha256:02ff5d7bd066c6a7673b17c8879cd8ee903078d184802a7ee851449c43521bdd \ - --hash=sha256:0e01bcb8d767c58865207a6c2f2792ad763a0fe1119fb0a430f444f5b02a5ea0 \ - --hash=sha256:0eff099a4df36afaa0eea7a913aa64dcf2cbd4e7a4f319a73012210af4d23810 \ - --hash=sha256:109a61763e7318d9f821b878589e71229f97366fa6a5c7720687d367f3ab9eef \ - --hash=sha256:11698bb2ea5e991d10f1f4f83a39a02f91e44e4bd05f01b5c1ec04c9342bf63c \ - --hash=sha256:130a896d53b48a1cecccfa903f37a1d87dbb74295305f865a3e816452f6e49e4 \ - --hash=sha256:1733b9bc2c8098c6bdb0ff7a3d7cb211753fecb7bd99bdd6df995621ee1a574b \ - --hash=sha256:18e2de19801b0eaa4c5292a223effb7cfb43904cb742c5317a0ac686ed604765 \ - --hash=sha256:1cf7f486169986c4b9d34087f08ce56a35126600b6fef3028f19ca16d5889071 \ - --hash=sha256:1d636c8aeb28cdd04a4aa89030c4b48f8b2954d8483e5f989774fa441c0ed57b \ - --hash=sha256:1db691bad0243aed27c8354b12d60e8e266b75216ae99d33e927ff5238d270b5 \ - --hash=sha256:1e5f3ca0ff47940ce0a389457b35d6df601c317c1e1a9615981c474452f98de1 \ - --hash=sha256:1ebaebb53b34690da0936c256c1cdb0914f24fb0e03da76d185806df9328abed \ - --hash=sha256:20b423b58f5fdde704a226b598a2d78165fe29eb5621358fe57ea63f16f165c4 \ - --hash=sha256:2368c5371c17fdcb5a2ea71c5c9d49f9b128821bfee69503cc38eae00feb3220 \ - --hash=sha256:24655e8c1c9c114005c3868a3d432c8aa595a786b8493500071e6a52f3d09217 \ - --hash=sha256:2537ef60596511df79b91613a5bb499b63f46f01a11a81b0a2b0dedf645d0a9c \ - --hash=sha256:296e0b29ab0276ca59d82d2da22cbbdb39a23eed94cca69aed274595fb3dfe42 \ - --hash=sha256:2aec5c29915caf08771d2507da3ac08e8de24a50f746eb1ed295584ba1820330 \ - --hash=sha256:2dddc2487d33e92f8b6222b5fb74ae2cfde5e8e6c44e0248d24ec23befdc5366 \ - --hash=sha256:37fd826dac84c6441615aa3f04077adcc5cac7194a021c9f0d69af20fb9fa788 \ - --hash=sha256:3af1b05361e1cc497bf1be654a664750ae61f5739e4bb094a2be86ec8c6db9b6 \ - --hash=sha256:40cb8fa00028908211eb9f8d47744dca21a4be6766672e1ff3280bee320436f1 \ - --hash=sha256:46f1d8069a95885ca529645cdbb05aea5837d799965676e1b2b1f95a4206313e \ - --hash=sha256:486bda18be5d25ab5d932699ceed918f68eb91f45d018b0343e3502e52866e5e \ - --hash=sha256:48a1b05c0afb2cd2f48c1ed2ae5487b116e34b93b13074ed3c22ad5c743109f0 \ - --hash=sha256:4ccd3011cc7ee2f789af9ebe04745436371d36afe610028921cab9f24bb2987b \ - --hash=sha256:4ea756e425ab2dfc8ef2a0cb87af8aa7ef7dfc6fc46c6f89bcf382121d4fff75 \ - --hash=sha256:524fcb8d59b0dbee2c9b32207084b67b2420f6431ed02c18bd191e6c575f5c48 \ - --hash=sha256:532e1f2c491274d1333a814e4c5c2e8b92345d41b12dc806cf07aaff786beb66 \ - --hash=sha256:556347b0abb4224c5ec688fc58214162e92a500323f50182f994f3ad33385dcb \ - --hash=sha256:62d2b18cb1edaba311fbbfe83fb5e53a858ba37cacb01e69bc20553bb70911b8 \ - --hash=sha256:6991e3a78f642368b8b1b669327eb6751439f9f7eaaa625fae67dd6070ecfa0b \ - --hash=sha256:6a9265cf87a5b70147bfb2fec14770ed5b11a5bb83353f0eee1c25a81af5abfe \ - --hash=sha256:6b1a950ab299a4a78fd6369a97b8763732bfb154fdb433356ec55a5bce9515c1 \ - --hash=sha256:6bb91fa4d0b392f0f7e27c40981e46dda9eb0fbc84162c7fb478fe115944f491 \ - --hash=sha256:6c21a5467f35c61eafb4e394303720893066897fca937bade5b4f5877d350ff8 \ - --hash=sha256:7ca6b71dcc50d320c88fb2d88ecd63924934a8abc1673683a242a7ca7d39e781 \ - --hash=sha256:7cf12ac34c444362f3261fb3ff548f0037ddd4c5bb85f66c4be30d2936beb3c5 \ - --hash=sha256:7f7252f52a09f8fa5435dc82b6af79483118ce6bd51eb74e6269f05ee22a7b9f \ - --hash=sha256:85042ab91814fca99cec4678fc063fb46df4cbb57b4835a1cc2cb7a51e10250e \ - --hash=sha256:857af85d445b9ba9178db95658c219dbd77b71b8264e66836a6eba4fbf49c320 \ - --hash=sha256:87f889f6e58849ddb7c5d2cb19e2e074917ed1c6e3ceca50405775166492cca8 \ - --hash=sha256:8ada449e22198c31fb013ae7e9add887e8d2bd2335401abd3cbc55f8c5083647 \ - --hash=sha256:8e56fbcdd27fce061854ddec99e015dd779cae186eb36b14471fc9ae713b118c \ - --hash=sha256:8f48c917ffd36ff9a5212614c2d0d585fa8b064ca7e66206fb5c095015bc8207 \ - --hash=sha256:9338ade39ff24f8086bb005d16c29f8e9f19e55b18dcb04dfa26fcbc09da497b \ - --hash=sha256:9837edf328b2805346f91209b7e660f65fb0e9ca18b7459d075d58db082bf981 \ - --hash=sha256:9d183e3888ada88185ab17064079c0db8c17e32023f5c278d7bf8014713b1b5b \ - --hash=sha256:9f02a259fcbbb5fcfe7a0805b1097ead5ba7a043e318eef1db59f93067f0b49b \ - --hash=sha256:9f8e6bb5ac007d4a4027b25f09827ed78cbbd5b9700fd6c54429278dacce05d1 \ - --hash=sha256:9ff785af8bacdf0be863ec0c428e3288b817e82f3d0c1d652cd9c6d509020dd0 \ - --hash=sha256:a0b2c25040a3c0ce0e66c7779cc045fdfbbb8d59e5aabfe033000b42fe44b53e \ - --hash=sha256:a753993635eccf1ecb185dedcc69d220dab41804272f45e4aef0a67e790c3eb3 \ - --hash=sha256:a8323daae27ea290ba3350c70c836c0d2b0fb47897fa3b0ca6a5375b952b90d3 \ - --hash=sha256:a8f195338a5a7b50a058522b39517c50238358d9ad8284fd92943643144c0c03 \ - --hash=sha256:a96ac14e184aa86dc43b8a22bb53854760a58b2966c2b41580de938e9bf26ed0 \ - --hash=sha256:aafea64a3ae698695975251f4254df2225e2624185a69534e7fe70581066bc1b \ - --hash=sha256:aba037c1310dd108411d27b3d5815998ef0e83573e47d4219f45753c710f969f \ - --hash=sha256:b1f67312efa3902a8e8496bfa9824d3bec096ff83c4669ea555c6bdd213aa516 \ - --hash=sha256:b4ac73b02ca1824ec0a7351588241fd3953748d3774694aa7ddb5e8e46aef3e3 \ - --hash=sha256:b8d3c5cd327dd6ce0edfc94374fb5883d254fe78a5e9d9dfc237a1897dc73cd1 \ - --hash=sha256:b98732ec893975455708d6fc9a6daab527fc8bbe65be354a3861f8c450a632a4 \ - --hash=sha256:ba31c32f6b4dceeb2be04f717811565159617e28d61a60bb616b6442027fd4b9 \ - --hash=sha256:bd3e2d64500a6cad28bcd710ee6269fbeb2e5320525acd0cfab5f269ade68581 \ - --hash=sha256:bee8ce357a05c20db04f46c22be2d1a2c6a8ed365b325d08af94358e0688eeb4 \ - --hash=sha256:c5e7803a65eb2d563c73230e9d693c6539e3c975ccfe62526cadde69f3fda0cf \ - --hash=sha256:c846884b2e690ba62a51048a097acb6b5cd263d8bd91062cd6137e2880578472 \ - --hash=sha256:d1aa4cc85202956d1a65c88d18c7b687b8319dbe6b1aec8969784ef7a10e7d1a \ - --hash=sha256:d2d42254b189a346249424fb9bb39182a19289a2409051ee432fb2926bad966a \ - --hash=sha256:dccc858372a56080332ea89b78cfb18efb945da858fabeb67f5a44fa0bcb4ebb \ - --hash=sha256:dd41d5c72417b87c00b1b635738f3c283e737d75c5fa5c3e1c60cd03eac3af77 \ - --hash=sha256:e087e8fdf1270d000913c12e6eca44edd02aad3559b3e6b8ef00f0ce76e0636f \ - --hash=sha256:e397b64f7aaf26915bf2ad0f1190f75c855d11eb111cc00f12f97430153c2eab \ - --hash=sha256:e495ed2a7943503766c5d1ff05ae9212dc2ce1c0e30a80d4f0d84889298fa304 \ - --hash=sha256:e75695cc952e825fa3e0684a7f4a302f9128721f13eedd8dbd3af2ba450932b8 \ - --hash=sha256:eb99c954291b2fad0eff98b490aa641e128fbc4a03b11c8a0086de8b7077fb75 \ - --hash=sha256:ecf2be4b9eece4f3da8ba5f244b9e51932ebc441c0867bd6af46a3d97eb068d6 \ - --hash=sha256:ee1f5fcbf5bc33acc0be9dd31130bcba35d6d2302e4eceafafd7d9018c7755ab \ - --hash=sha256:ee7db6e36e7a2c15923072e41ea24d9a0cf39658cb0637ecc9307b09d28827e1 \ - --hash=sha256:efadd40fca3a04063d40c4448c9303ce24dd6151dc162cfae4a2a060232ebdcb \ - --hash=sha256:f18de0f82c62c4197bea5ecf4389288ac755896aac734bd2cc44004c56e4ac47 \ - --hash=sha256:f449afbb971df5c6faeb0a27bca0427d7b600dd8f4a068492faec18023f0dcff \ - --hash=sha256:f46c6f0aec8d02a52d97a583782d9af38c19a29900747eb048af358a9c1d8e5b \ - --hash=sha256:fb02d41c33be667e6135e6686f1bb76104c88a312a18faa0ef0262b5bf7f1a0f \ - --hash=sha256:fd257f98cff9c6cb39eee1a83c7c3183970d8a8d23e8cf4f47d9a21329285cee +watchfiles==0.24.0 \ + --hash=sha256:01550ccf1d0aed6ea375ef259706af76ad009ef5b0203a3a4cce0f6024f9b68a \ + --hash=sha256:01def80eb62bd5db99a798d5e1f5f940ca0a05986dcfae21d833af7a46f7ee22 \ + --hash=sha256:07cdef0c84c03375f4e24642ef8d8178e533596b229d32d2bbd69e5128ede02a \ + --hash=sha256:083dc77dbdeef09fa44bb0f4d1df571d2e12d8a8f985dccde71ac3ac9ac067a0 \ + --hash=sha256:1cf1f6dd7825053f3d98f6d33f6464ebdd9ee95acd74ba2c34e183086900a827 \ + --hash=sha256:21ab23fdc1208086d99ad3f69c231ba265628014d4aed31d4e8746bd59e88cd1 \ + --hash=sha256:2dadf8a8014fde6addfd3c379e6ed1a981c8f0a48292d662e27cabfe4239c83c \ + --hash=sha256:2e28d91ef48eab0afb939fa446d8ebe77e2f7593f5f463fd2bb2b14132f95b6e \ + --hash=sha256:2efec17819b0046dde35d13fb8ac7a3ad877af41ae4640f4109d9154ed30a188 \ + --hash=sha256:30bbd525c3262fd9f4b1865cb8d88e21161366561cd7c9e1194819e0a33ea86b \ + --hash=sha256:316449aefacf40147a9efaf3bd7c9bdd35aaba9ac5d708bd1eb5763c9a02bef5 \ + --hash=sha256:327763da824817b38ad125dcd97595f942d720d32d879f6c4ddf843e3da3fe90 \ + --hash=sha256:32aa53a9a63b7f01ed32e316e354e81e9da0e6267435c7243bf8ae0f10b428ef \ + --hash=sha256:34e19e56d68b0dad5cff62273107cf5d9fbaf9d75c46277aa5d803b3ef8a9e9b \ + --hash=sha256:3770e260b18e7f4e576edca4c0a639f704088602e0bc921c5c2e721e3acb8d15 \ + --hash=sha256:3d2e3ab79a1771c530233cadfd277fcc762656d50836c77abb2e5e72b88e3a48 \ + --hash=sha256:41face41f036fee09eba33a5b53a73e9a43d5cb2c53dad8e61fa6c9f91b5a51e \ + --hash=sha256:43e3e37c15a8b6fe00c1bce2473cfa8eb3484bbeecf3aefbf259227e487a03df \ + --hash=sha256:449f43f49c8ddca87c6b3980c9284cab6bd1f5c9d9a2b00012adaaccd5e7decd \ + --hash=sha256:4933a508d2f78099162da473841c652ad0de892719043d3f07cc83b33dfd9d91 \ + --hash=sha256:49d617df841a63b4445790a254013aea2120357ccacbed00253f9c2b5dc24e2d \ + --hash=sha256:49fb58bcaa343fedc6a9e91f90195b20ccb3135447dc9e4e2570c3a39565853e \ + --hash=sha256:4a7fa2bc0efef3e209a8199fd111b8969fe9db9c711acc46636686331eda7dd4 \ + --hash=sha256:4abf4ad269856618f82dee296ac66b0cd1d71450fc3c98532d93798e73399b7a \ + --hash=sha256:4b8693502d1967b00f2fb82fc1e744df128ba22f530e15b763c8d82baee15370 \ + --hash=sha256:4d28cea3c976499475f5b7a2fec6b3a36208656963c1a856d328aeae056fc5c1 \ + --hash=sha256:5148c2f1ea043db13ce9b0c28456e18ecc8f14f41325aa624314095b6aa2e9ea \ + --hash=sha256:54ca90a9ae6597ae6dc00e7ed0a040ef723f84ec517d3e7ce13e63e4bc82fa04 \ + --hash=sha256:551ec3ee2a3ac9cbcf48a4ec76e42c2ef938a7e905a35b42a1267fa4b1645896 \ + --hash=sha256:5c51749f3e4e269231510da426ce4a44beb98db2dce9097225c338f815b05d4f \ + --hash=sha256:632676574429bee8c26be8af52af20e0c718cc7f5f67f3fb658c71928ccd4f7f \ + --hash=sha256:6509ed3f467b79d95fc62a98229f79b1a60d1b93f101e1c61d10c95a46a84f43 \ + --hash=sha256:6bdcfa3cd6fdbdd1a068a52820f46a815401cbc2cb187dd006cb076675e7b735 \ + --hash=sha256:7138eff8baa883aeaa074359daabb8b6c1e73ffe69d5accdc907d62e50b1c0da \ + --hash=sha256:7211b463695d1e995ca3feb38b69227e46dbd03947172585ecb0588f19b0d87a \ + --hash=sha256:73bde715f940bea845a95247ea3e5eb17769ba1010efdc938ffcb967c634fa61 \ + --hash=sha256:78470906a6be5199524641f538bd2c56bb809cd4bf29a566a75051610bc982c3 \ + --hash=sha256:7ae3e208b31be8ce7f4c2c0034f33406dd24fbce3467f77223d10cd86778471c \ + --hash=sha256:7e4bd963a935aaf40b625c2499f3f4f6bbd0c3776f6d3bc7c853d04824ff1c9f \ + --hash=sha256:82ae557a8c037c42a6ef26c494d0631cacca040934b101d001100ed93d43f361 \ + --hash=sha256:82b2509f08761f29a0fdad35f7e1638b8ab1adfa2666d41b794090361fb8b855 \ + --hash=sha256:8360f7314a070c30e4c976b183d1d8d1585a4a50c5cb603f431cebcbb4f66327 \ + --hash=sha256:85d5f0c7771dcc7a26c7a27145059b6bb0ce06e4e751ed76cdf123d7039b60b5 \ + --hash=sha256:88bcd4d0fe1d8ff43675360a72def210ebad3f3f72cabfeac08d825d2639b4ab \ + --hash=sha256:9301c689051a4857d5b10777da23fafb8e8e921bcf3abe6448a058d27fb67633 \ + --hash=sha256:951088d12d339690a92cef2ec5d3cfd957692834c72ffd570ea76a6790222777 \ + --hash=sha256:95cf3b95ea665ab03f5a54765fa41abf0529dbaf372c3b83d91ad2cfa695779b \ + --hash=sha256:96619302d4374de5e2345b2b622dc481257a99431277662c30f606f3e22f42be \ + --hash=sha256:999928c6434372fde16c8f27143d3e97201160b48a614071261701615a2a156f \ + --hash=sha256:9a60e2bf9dc6afe7f743e7c9b149d1fdd6dbf35153c78fe3a14ae1a9aee3d98b \ + --hash=sha256:9f895d785eb6164678ff4bb5cc60c5996b3ee6df3edb28dcdeba86a13ea0465e \ + --hash=sha256:a2a9891723a735d3e2540651184be6fd5b96880c08ffe1a98bae5017e65b544b \ + --hash=sha256:a974231b4fdd1bb7f62064a0565a6b107d27d21d9acb50c484d2cdba515b9366 \ + --hash=sha256:aa0fd7248cf533c259e59dc593a60973a73e881162b1a2f73360547132742823 \ + --hash=sha256:acbfa31e315a8f14fe33e3542cbcafc55703b8f5dcbb7c1eecd30f141df50db3 \ + --hash=sha256:afb72325b74fa7a428c009c1b8be4b4d7c2afedafb2982827ef2156646df2fe1 \ + --hash=sha256:b3ef2c69c655db63deb96b3c3e587084612f9b1fa983df5e0c3379d41307467f \ + --hash=sha256:b52a65e4ea43c6d149c5f8ddb0bef8d4a1e779b77591a458a893eb416624a418 \ + --hash=sha256:b665caeeda58625c3946ad7308fbd88a086ee51ccb706307e5b1fa91556ac886 \ + --hash=sha256:b74fdffce9dfcf2dc296dec8743e5b0332d15df19ae464f0e249aa871fc1c571 \ + --hash=sha256:b995bfa6bf01a9e09b884077a6d37070464b529d8682d7691c2d3b540d357a0c \ + --hash=sha256:bd82010f8ab451dabe36054a1622870166a67cf3fce894f68895db6f74bbdc94 \ + --hash=sha256:bdcd5538e27f188dd3c804b4a8d5f52a7fc7f87e7fd6b374b8e36a4ca03db428 \ + --hash=sha256:c79d7719d027b7a42817c5d96461a99b6a49979c143839fc37aa5748c322f234 \ + --hash=sha256:cdab9555053399318b953a1fe1f586e945bc8d635ce9d05e617fd9fe3a4687d6 \ + --hash=sha256:ce72dba6a20e39a0c628258b5c308779b8697f7676c254a845715e2a1039b968 \ + --hash=sha256:d337193bbf3e45171c8025e291530fb7548a93c45253897cd764a6a71c937ed9 \ + --hash=sha256:d3dcb774e3568477275cc76554b5a565024b8ba3a0322f77c246bc7111c5bb9c \ + --hash=sha256:d64ba08db72e5dfd5c33be1e1e687d5e4fcce09219e8aee893a4862034081d4e \ + --hash=sha256:d7a2e3b7f5703ffbd500dabdefcbc9eafeff4b9444bbdd5d83d79eedf8428fab \ + --hash=sha256:d831ee0a50946d24a53821819b2327d5751b0c938b12c0653ea5be7dea9c82ec \ + --hash=sha256:d9018153cf57fc302a2a34cb7564870b859ed9a732d16b41a9b5cb2ebed2d444 \ + --hash=sha256:e5171ef898299c657685306d8e1478a45e9303ddcd8ac5fed5bd52ad4ae0b69b \ + --hash=sha256:e94e98c7cb94cfa6e071d401ea3342767f28eb5a06a58fafdc0d2a4974f4f35c \ + --hash=sha256:ec39698c45b11d9694a1b635a70946a5bad066b593af863460a8e600f0dff1ca \ + --hash=sha256:ed9aba6e01ff6f2e8285e5aa4154e2970068fe0fc0998c4380d0e6278222269b \ + --hash=sha256:edf71b01dec9f766fb285b73930f95f730bb0943500ba0566ae234b5c1618c18 \ + --hash=sha256:ee82c98bed9d97cd2f53bdb035e619309a098ea53ce525833e26b93f673bc318 \ + --hash=sha256:f4c96283fca3ee09fb044f02156d9570d156698bc3734252175a38f0e8975f07 \ + --hash=sha256:f7d9b87c4c55e3ea8881dfcbf6d61ea6775fffed1fedffaa60bd047d3c08c430 \ + --hash=sha256:f83df90191d67af5a831da3a33dd7628b02a95450e168785586ed51e6d28943c \ + --hash=sha256:fca9433a45f18b7c779d2bae7beeec4f740d28b788b117a48368d95a3233ed83 \ + --hash=sha256:fd92bbaa2ecdb7864b7600dcdb6f2f1db6e0346ed425fbd01085be04c63f0b05 # via uvicorn -websockets==13.0 \ - --hash=sha256:02cc9bb1a887dac0e08bf657c5d00aa3fac0d03215d35a599130c2034ae6663a \ - --hash=sha256:038e7a0f1bfafc7bf52915ab3506b7a03d1e06381e9f60440c856e8918138151 \ - --hash=sha256:05c25f7b849702950b6fd0e233989bb73a0d2bc83faa3b7233313ca395205f6d \ - --hash=sha256:06b3186e97bf9a33921fa60734d5ed90f2a9b407cce8d23c7333a0984049ef61 \ - --hash=sha256:06df8306c241c235075d2ae77367038e701e53bc8c1bb4f6644f4f53aa6dedd0 \ - --hash=sha256:0a8f7d65358a25172db00c69bcc7df834155ee24229f560d035758fd6613111a \ - --hash=sha256:1f661a4205741bdc88ac9c2b2ec003c72cee97e4acd156eb733662ff004ba429 \ - --hash=sha256:265e1f0d3f788ce8ef99dca591a1aec5263b26083ca0934467ad9a1d1181067c \ - --hash=sha256:2be1382a4daa61e2f3e2be3b3c86932a8db9d1f85297feb6e9df22f391f94452 \ - --hash=sha256:2e1cf4e1eb84b4fd74a47688e8b0940c89a04ad9f6937afa43d468e71128cd68 \ - --hash=sha256:337837ac788d955728b1ab01876d72b73da59819a3388e1c5e8e05c3999f1afa \ - --hash=sha256:358d37c5c431dd050ffb06b4b075505aae3f4f795d7fff9794e5ed96ce99b998 \ - --hash=sha256:35c2221b539b360203f3f9ad168e527bf16d903e385068ae842c186efb13d0ea \ - --hash=sha256:3670def5d3dfd5af6f6e2b3b243ea8f1f72d8da1ef927322f0703f85c90d9603 \ - --hash=sha256:372f46a0096cfda23c88f7e42349a33f8375e10912f712e6b496d3a9a557290f \ - --hash=sha256:376a43a4fd96725f13450d3d2e98f4f36c3525c562ab53d9a98dd2950dca9a8a \ - --hash=sha256:384129ad0490e06bab2b98c1da9b488acb35bb11e2464c728376c6f55f0d45f3 \ - --hash=sha256:3a20cf14ba7b482c4a1924b5e061729afb89c890ca9ed44ac4127c6c5986e424 \ - --hash=sha256:3e6566e79c8c7cbea75ec450f6e1828945fc5c9a4769ceb1c7b6e22470539712 \ - --hash=sha256:4782ec789f059f888c1e8fdf94383d0e64b531cffebbf26dd55afd53ab487ca4 \ - --hash=sha256:4d70c89e3d3b347a7c4d3c33f8d323f0584c9ceb69b82c2ef8a174ca84ea3d4a \ - --hash=sha256:516062a0a8ef5ecbfa4acbaec14b199fc070577834f9fe3d40800a99f92523ca \ - --hash=sha256:5575031472ca87302aeb2ce2c2349f4c6ea978c86a9d1289bc5d16058ad4c10a \ - --hash=sha256:587245f0704d0bb675f919898d7473e8827a6d578e5a122a21756ca44b811ec8 \ - --hash=sha256:602cbd010d8c21c8475f1798b705bb18567eb189c533ab5ef568bc3033fdf417 \ - --hash=sha256:6058b6be92743358885ad6dcdecb378fde4a4c74d4dd16a089d07580c75a0e80 \ - --hash=sha256:63b702fb31e3f058f946ccdfa551f4d57a06f7729c369e8815eb18643099db37 \ - --hash=sha256:6ad684cb7efce227d756bae3e8484f2e56aa128398753b54245efdfbd1108f2c \ - --hash=sha256:6fd757f313c13c34dae9f126d3ba4cf97175859c719e57c6a614b781c86b617e \ - --hash=sha256:7334752052532c156d28b8eaf3558137e115c7871ea82adff69b6d94a7bee273 \ - --hash=sha256:788bc841d250beccff67a20a5a53a15657a60111ef9c0c0a97fbdd614fae0fe2 \ - --hash=sha256:7d14901fdcf212804970c30ab9ee8f3f0212e620c7ea93079d6534863444fb4e \ - --hash=sha256:7ea9c9c7443a97ea4d84d3e4d42d0e8c4235834edae652993abcd2aff94affd7 \ - --hash=sha256:81a11a1ddd5320429db47c04d35119c3e674d215173d87aaeb06ae80f6e9031f \ - --hash=sha256:851fd0afb3bc0b73f7c5b5858975d42769a5fdde5314f4ef2c106aec63100687 \ - --hash=sha256:85a1f92a02f0b8c1bf02699731a70a8a74402bb3f82bee36e7768b19a8ed9709 \ - --hash=sha256:89d795c1802d99a643bf689b277e8604c14b5af1bc0a31dade2cd7a678087212 \ - --hash=sha256:9202c0010c78fad1041e1c5285232b6508d3633f92825687549540a70e9e5901 \ - --hash=sha256:939a16849d71203628157a5e4a495da63967c744e1e32018e9b9e2689aca64d4 \ - --hash=sha256:93b8c2008f372379fb6e5d2b3f7c9ec32f7b80316543fd3a5ace6610c5cde1b0 \ - --hash=sha256:94c1c02721139fe9940b38d28fb15b4b782981d800d5f40f9966264fbf23dcc8 \ - --hash=sha256:9895df6cd0bfe79d09bcd1dbdc03862846f26fbd93797153de954306620c1d00 \ - --hash=sha256:9cc7f35dcb49a4e32db82a849fcc0714c4d4acc9d2273aded2d61f87d7f660b7 \ - --hash=sha256:9ed02c604349068d46d87ef4c2012c112c791f2bec08671903a6bb2bd9c06784 \ - --hash=sha256:a00e1e587c655749afb5b135d8d3edcfe84ec6db864201e40a882e64168610b3 \ - --hash=sha256:a1ab8f0e0cadc5be5f3f9fa11a663957fecbf483d434762c8dfb8aa44948944a \ - --hash=sha256:a4de299c947a54fca9ce1c5fd4a08eb92ffce91961becb13bd9195f7c6e71b47 \ - --hash=sha256:a7fbf2a8fe7556a8f4e68cb3e736884af7bf93653e79f6219f17ebb75e97d8f0 \ - --hash=sha256:ad4fa707ff9e2ffee019e946257b5300a45137a58f41fbd9a4db8e684ab61528 \ - --hash=sha256:ad818cdac37c0ad4c58e51cb4964eae4f18b43c4a83cb37170b0d90c31bd80cf \ - --hash=sha256:addf0a16e4983280efed272d8cb3b2e05f0051755372461e7d966b80a6554e16 \ - --hash=sha256:ae7a519a56a714f64c3445cabde9fc2fc927e7eae44f413eae187cddd9e54178 \ - --hash=sha256:b32f38bc81170fd56d0482d505b556e52bf9078b36819a8ba52624bd6667e39e \ - --hash=sha256:b5407c34776b9b77bd89a5f95eb0a34aaf91889e3f911c63f13035220eb50107 \ - --hash=sha256:b7bf950234a482b7461afdb2ec99eee3548ec4d53f418c7990bb79c620476602 \ - --hash=sha256:b89849171b590107f6724a7b0790736daead40926ddf47eadf998b4ff51d6414 \ - --hash=sha256:bcea3eb58c09c3a31cc83b45c06d5907f02ddaf10920aaa6443975310f699b95 \ - --hash=sha256:bd4ba86513430513e2aa25a441bb538f6f83734dc368a2c5d18afdd39097aa33 \ - --hash=sha256:bf8eb5dca4f484a60f5327b044e842e0d7f7cdbf02ea6dc4a4f811259f1f1f0b \ - --hash=sha256:c026ee729c4ce55708a14b839ba35086dfae265fc12813b62d34ce33f4980c1c \ - --hash=sha256:c210d1460dc8d326ffdef9703c2f83269b7539a1690ad11ae04162bc1878d33d \ - --hash=sha256:c8feb8e19ef65c9994e652c5b0324abd657bedd0abeb946fb4f5163012c1e730 \ - --hash=sha256:cbac2eb7ce0fac755fb983c9247c4a60c4019bcde4c0e4d167aeb17520cc7ef1 \ - --hash=sha256:cbfe82a07596a044de78bb7a62519e71690c5812c26c5f1d4b877e64e4f46309 \ - --hash=sha256:d3f3d2e20c442b58dbac593cb1e02bc02d149a86056cc4126d977ad902472e3b \ - --hash=sha256:d42a818e634f789350cd8fb413a3f5eec1cf0400a53d02062534c41519f5125c \ - --hash=sha256:d4b83cf7354cbbc058e97b3e545dceb75b8d9cf17fd5a19db419c319ddbaaf7a \ - --hash=sha256:d9726d2c9bd6aed8cb994d89b3910ca0079406edce3670886ec828a73e7bdd53 \ - --hash=sha256:da7e501e59857e8e3e9d10586139dc196b80445a591451ca9998aafba1af5278 \ - --hash=sha256:da7e918d82e7bdfc6f66d31febe1b2e28a1ca3387315f918de26f5e367f61572 \ - --hash=sha256:dbbac01e80aee253d44c4f098ab3cc17c822518519e869b284cfbb8cd16cc9de \ - --hash=sha256:df5c0eff91f61b8205a6c9f7b255ff390cdb77b61c7b41f79ca10afcbb22b6cb \ - --hash=sha256:e07e76c49f39c5b45cbd7362b94f001ae209a3ea4905ae9a09cfd53b3c76373d \ - --hash=sha256:e1e10b3fbed7be4a59831d3a939900e50fcd34d93716e433d4193a4d0d1d335d \ - --hash=sha256:e39d393e0ab5b8bd01717cc26f2922026050188947ff54fe6a49dc489f7750b7 \ - --hash=sha256:e5ba5e9b332267d0f2c33ede390061850f1ac3ee6cd1bdcf4c5ea33ead971966 \ - --hash=sha256:e7a1963302947332c3039e3f66209ec73b1626f8a0191649e0713c391e9f5b0d \ - --hash=sha256:e7fcad070dcd9ad37a09d89a4cbc2a5e3e45080b88977c0da87b3090f9f55ead \ - --hash=sha256:eae368cac85adc4c7dc3b0d5f84ffcca609d658db6447387300478e44db70796 \ - --hash=sha256:ede95125a30602b1691a4b1da88946bf27dae283cf30f22cd2cb8ca4b2e0d119 \ - --hash=sha256:f5737c53eb2c8ed8f64b50d3dafd3c1dae739f78aa495a288421ac1b3de82717 \ - --hash=sha256:f5f9d23fbbf96eefde836d9692670bfc89e2d159f456d499c5efcf6a6281c1af \ - --hash=sha256:f66e00e42f25ca7e91076366303e11c82572ca87cc5aae51e6e9c094f315ab41 \ - --hash=sha256:f9af457ed593e35f467140d8b61d425495b127744a9d65d45a366f8678449a23 \ - --hash=sha256:fa0839f35322f7b038d8adcf679e2698c3a483688cc92e3bd15ee4fb06669e9a \ - --hash=sha256:fd038bc9e2c134847f1e0ce3191797fad110756e690c2fdd9702ed34e7a43abb +websockets==13.1 \ + --hash=sha256:004280a140f220c812e65f36944a9ca92d766b6cc4560be652a0a3883a79ed8a \ + --hash=sha256:035233b7531fb92a76beefcbf479504db8c72eb3bff41da55aecce3a0f729e54 \ + --hash=sha256:149e622dc48c10ccc3d2760e5f36753db9cacf3ad7bc7bbbfd7d9c819e286f23 \ + --hash=sha256:163e7277e1a0bd9fb3c8842a71661ad19c6aa7bb3d6678dc7f89b17fbcc4aeb7 \ + --hash=sha256:18503d2c5f3943e93819238bf20df71982d193f73dcecd26c94514f417f6b135 \ + --hash=sha256:1971e62d2caa443e57588e1d82d15f663b29ff9dfe7446d9964a4b6f12c1e700 \ + --hash=sha256:204e5107f43095012b00f1451374693267adbb832d29966a01ecc4ce1db26faf \ + --hash=sha256:2510c09d8e8df777177ee3d40cd35450dc169a81e747455cc4197e63f7e7bfe5 \ + --hash=sha256:25c35bf84bf7c7369d247f0b8cfa157f989862c49104c5cf85cb5436a641d93e \ + --hash=sha256:2f85cf4f2a1ba8f602298a853cec8526c2ca42a9a4b947ec236eaedb8f2dc80c \ + --hash=sha256:308e20f22c2c77f3f39caca508e765f8725020b84aa963474e18c59accbf4c02 \ + --hash=sha256:325b1ccdbf5e5725fdcb1b0e9ad4d2545056479d0eee392c291c1bf76206435a \ + --hash=sha256:327b74e915cf13c5931334c61e1a41040e365d380f812513a255aa804b183418 \ + --hash=sha256:346bee67a65f189e0e33f520f253d5147ab76ae42493804319b5716e46dddf0f \ + --hash=sha256:38377f8b0cdeee97c552d20cf1865695fcd56aba155ad1b4ca8779a5b6ef4ac3 \ + --hash=sha256:3c78383585f47ccb0fcf186dcb8a43f5438bd7d8f47d69e0b56f71bf431a0a68 \ + --hash=sha256:4059f790b6ae8768471cddb65d3c4fe4792b0ab48e154c9f0a04cefaabcd5978 \ + --hash=sha256:459bf774c754c35dbb487360b12c5727adab887f1622b8aed5755880a21c4a20 \ + --hash=sha256:463e1c6ec853202dd3657f156123d6b4dad0c546ea2e2e38be2b3f7c5b8e7295 \ + --hash=sha256:4676df3fe46956fbb0437d8800cd5f2b6d41143b6e7e842e60554398432cf29b \ + --hash=sha256:485307243237328c022bc908b90e4457d0daa8b5cf4b3723fd3c4a8012fce4c6 \ + --hash=sha256:48a2ef1381632a2f0cb4efeff34efa97901c9fbc118e01951ad7cfc10601a9bb \ + --hash=sha256:4b889dbd1342820cc210ba44307cf75ae5f2f96226c0038094455a96e64fb07a \ + --hash=sha256:586a356928692c1fed0eca68b4d1c2cbbd1ca2acf2ac7e7ebd3b9052582deefa \ + --hash=sha256:58cf7e75dbf7e566088b07e36ea2e3e2bd5676e22216e4cad108d4df4a7402a0 \ + --hash=sha256:5993260f483d05a9737073be197371940c01b257cc45ae3f1d5d7adb371b266a \ + --hash=sha256:5dd6da9bec02735931fccec99d97c29f47cc61f644264eb995ad6c0c27667238 \ + --hash=sha256:5f2e75431f8dc4a47f31565a6e1355fb4f2ecaa99d6b89737527ea917066e26c \ + --hash=sha256:5f9fee94ebafbc3117c30be1844ed01a3b177bb6e39088bc6b2fa1dc15572084 \ + --hash=sha256:61fc0dfcda609cda0fc9fe7977694c0c59cf9d749fbb17f4e9483929e3c48a19 \ + --hash=sha256:624459daabeb310d3815b276c1adef475b3e6804abaf2d9d2c061c319f7f187d \ + --hash=sha256:62d516c325e6540e8a57b94abefc3459d7dab8ce52ac75c96cad5549e187e3a7 \ + --hash=sha256:6548f29b0e401eea2b967b2fdc1c7c7b5ebb3eeb470ed23a54cd45ef078a0db9 \ + --hash=sha256:6d2aad13a200e5934f5a6767492fb07151e1de1d6079c003ab31e1823733ae79 \ + --hash=sha256:6d6855bbe70119872c05107e38fbc7f96b1d8cb047d95c2c50869a46c65a8e96 \ + --hash=sha256:70c5be9f416aa72aab7a2a76c90ae0a4fe2755c1816c153c1a2bcc3333ce4ce6 \ + --hash=sha256:730f42125ccb14602f455155084f978bd9e8e57e89b569b4d7f0f0c17a448ffe \ + --hash=sha256:7a43cfdcddd07f4ca2b1afb459824dd3c6d53a51410636a2c7fc97b9a8cf4842 \ + --hash=sha256:7bd6abf1e070a6b72bfeb71049d6ad286852e285f146682bf30d0296f5fbadfa \ + --hash=sha256:7c1e90228c2f5cdde263253fa5db63e6653f1c00e7ec64108065a0b9713fa1b3 \ + --hash=sha256:7c65ffa900e7cc958cd088b9a9157a8141c991f8c53d11087e6fb7277a03f81d \ + --hash=sha256:80c421e07973a89fbdd93e6f2003c17d20b69010458d3a8e37fb47874bd67d51 \ + --hash=sha256:82d0ba76371769d6a4e56f7e83bb8e81846d17a6190971e38b5de108bde9b0d7 \ + --hash=sha256:83f91d8a9bb404b8c2c41a707ac7f7f75b9442a0a876df295de27251a856ad09 \ + --hash=sha256:87c6e35319b46b99e168eb98472d6c7d8634ee37750d7693656dc766395df096 \ + --hash=sha256:8d23b88b9388ed85c6faf0e74d8dec4f4d3baf3ecf20a65a47b836d56260d4b9 \ + --hash=sha256:9156c45750b37337f7b0b00e6248991a047be4aa44554c9886fe6bdd605aab3b \ + --hash=sha256:91a0fa841646320ec0d3accdff5b757b06e2e5c86ba32af2e0815c96c7a603c5 \ + --hash=sha256:95858ca14a9f6fa8413d29e0a585b31b278388aa775b8a81fa24830123874678 \ + --hash=sha256:95df24ca1e1bd93bbca51d94dd049a984609687cb2fb08a7f2c56ac84e9816ea \ + --hash=sha256:9b37c184f8b976f0c0a231a5f3d6efe10807d41ccbe4488df8c74174805eea7d \ + --hash=sha256:9b6f347deb3dcfbfde1c20baa21c2ac0751afaa73e64e5b693bb2b848efeaa49 \ + --hash=sha256:9d75baf00138f80b48f1eac72ad1535aac0b6461265a0bcad391fc5aba875cfc \ + --hash=sha256:9ef8aa8bdbac47f4968a5d66462a2a0935d044bf35c0e5a8af152d58516dbeb5 \ + --hash=sha256:a11e38ad8922c7961447f35c7b17bffa15de4d17c70abd07bfbe12d6faa3e027 \ + --hash=sha256:a1b54689e38d1279a51d11e3467dd2f3a50f5f2e879012ce8f2d6943f00e83f0 \ + --hash=sha256:a3b3366087c1bc0a2795111edcadddb8b3b59509d5db5d7ea3fdd69f954a8878 \ + --hash=sha256:a569eb1b05d72f9bce2ebd28a1ce2054311b66677fcd46cf36204ad23acead8c \ + --hash=sha256:a7affedeb43a70351bb811dadf49493c9cfd1ed94c9c70095fd177e9cc1541fa \ + --hash=sha256:a9a396a6ad26130cdae92ae10c36af09d9bfe6cafe69670fd3b6da9b07b4044f \ + --hash=sha256:a9ab1e71d3d2e54a0aa646ab6d4eebfaa5f416fe78dfe4da2839525dc5d765c6 \ + --hash=sha256:a9cd1af7e18e5221d2878378fbc287a14cd527fdd5939ed56a18df8a31136bb2 \ + --hash=sha256:a9dcaf8b0cc72a392760bb8755922c03e17a5a54e08cca58e8b74f6902b433cf \ + --hash=sha256:b9d7439d7fab4dce00570bb906875734df13d9faa4b48e261c440a5fec6d9708 \ + --hash=sha256:bcc03c8b72267e97b49149e4863d57c2d77f13fae12066622dc78fe322490fe6 \ + --hash=sha256:c11d4d16e133f6df8916cc5b7e3e96ee4c44c936717d684a94f48f82edb7c92f \ + --hash=sha256:c1dca61c6db1166c48b95198c0b7d9c990b30c756fc2923cc66f68d17dc558fd \ + --hash=sha256:c518e84bb59c2baae725accd355c8dc517b4a3ed8db88b4bc93c78dae2974bf2 \ + --hash=sha256:c7934fd0e920e70468e676fe7f1b7261c1efa0d6c037c6722278ca0228ad9d0d \ + --hash=sha256:c7e72ce6bda6fb9409cc1e8164dd41d7c91466fb599eb047cfda72fe758a34a7 \ + --hash=sha256:c90d6dec6be2c7d03378a574de87af9b1efea77d0c52a8301dd831ece938452f \ + --hash=sha256:ceec59f59d092c5007e815def4ebb80c2de330e9588e101cf8bd94c143ec78a5 \ + --hash=sha256:cf1781ef73c073e6b0f90af841aaf98501f975d306bbf6221683dd594ccc52b6 \ + --hash=sha256:d04f13a1d75cb2b8382bdc16ae6fa58c97337253826dfe136195b7f89f661557 \ + --hash=sha256:d6d300f8ec35c24025ceb9b9019ae9040c1ab2f01cddc2bcc0b518af31c75c14 \ + --hash=sha256:d8dbb1bf0c0a4ae8b40bdc9be7f644e2f3fb4e8a9aca7145bfa510d4a374eeb7 \ + --hash=sha256:de58647e3f9c42f13f90ac7e5f58900c80a39019848c5547bc691693098ae1bd \ + --hash=sha256:deeb929efe52bed518f6eb2ddc00cc496366a14c726005726ad62c2dd9017a3c \ + --hash=sha256:df01aea34b6e9e33572c35cd16bae5a47785e7d5c8cb2b54b2acdb9678315a17 \ + --hash=sha256:e2620453c075abeb0daa949a292e19f56de518988e079c36478bacf9546ced23 \ + --hash=sha256:e4450fc83a3df53dec45922b576e91e94f5578d06436871dce3a6be38e40f5db \ + --hash=sha256:e54affdeb21026329fb0744ad187cf812f7d3c2aa702a5edb562b325191fcab6 \ + --hash=sha256:e9875a0143f07d74dc5e1ded1c4581f0d9f7ab86c78994e2ed9e95050073c94d \ + --hash=sha256:f1c3cf67185543730888b20682fb186fc8d0fa6f07ccc3ef4390831ab4b388d9 \ + --hash=sha256:f48c749857f8fb598fb890a75f540e3221d0976ed0bf879cf3c7eef34151acee \ + --hash=sha256:f779498eeec470295a2b1a5d97aa1bc9814ecd25e1eb637bd9d1c73a327387f6 # via uvicorn wrapt==1.16.0 \ --hash=sha256:0d2691979e93d06a95a26257adb7bfd0c93818e89b1406f5a28f36e0d8c1e1fc \ diff --git a/lock/requirements.txt b/lock/requirements.txt index 2ab5a9e..2ad3295 100644 --- a/lock/requirements.txt +++ b/lock/requirements.txt @@ -39,9 +39,9 @@ annotated-types==0.7.0 \ # via # -c lock/requirements-dev.txt # pydantic -anyio==4.4.0 \ - --hash=sha256:5aadc6a1bbb7cdb0bede386cac5e2940f5e2ff3aa20277e991cf028e0585ce94 \ - --hash=sha256:c1b2d8f46a8a812513012e1107cb0e68c17159a7a594208005a57dc776e1bdc7 +anyio==4.6.2.post1 \ + --hash=sha256:4c8bc31ccdb51c7f7bd251f51c609e038d63e34219b44aa86e47576389880b4c \ + --hash=sha256:6d170c36fba3bdd840c73d3868c1e777e33676a69c3a72cf0a0d5d6d8009b61d # via # -c lock/requirements-dev.txt # httpx @@ -60,23 +60,23 @@ attrs==24.2.0 \ # -c lock/requirements-dev.txt # jsonschema # referencing -boto3==1.35.4 \ - --hash=sha256:96c39593afb7b55ebb74d08c8e3201041d105b557c8c8536c9054c9f13da5f2a \ - --hash=sha256:d997b82c468bd5c2d5cd29810d47079b66b178d2b5ae021aebe262c4d78d4c94 +boto3==1.35.47 \ + --hash=sha256:0b307f685875e9c7857ce21c0d3050d8d4f3778455a6852d5f98ac75194b400e \ + --hash=sha256:65b808e4cf1af8c2f405382d53656a0d92eee8f85c7388c43d64c7a5571b065f # via # -c lock/requirements-dev.txt # hexkit -botocore==1.35.4 \ - --hash=sha256:10195e5ca764745f02b9a51df048b996ddbdc1899a44a2caf35dfb225dfea489 \ - --hash=sha256:4cc51a6a486915aedc140f9d027b7e156646b7a0f7b33b1000762c81aff9a12f +botocore==1.35.47 \ + --hash=sha256:05f4493119a96799ff84d43e78691efac3177e1aec8840cca99511de940e342a \ + --hash=sha256:f8f703463d3cd8b6abe2bedc443a7ab29f0e2ff1588a2e83164b108748645547 # via # -c lock/requirements-dev.txt # boto3 # hexkit # s3transfer -certifi==2024.7.4 \ - --hash=sha256:5a1e7645bc0ec61a09e26c36f6106dd4cf40c6db3a1fb6352b0244e7fb057c7b \ - --hash=sha256:c198e21b1289c2ab85ee4e67bb4b4ef3ead0892059901a8d5b622f24a1101e90 +certifi==2024.8.30 \ + --hash=sha256:922820b53db7a7257ffbda3f597266d435245903d80737e34f8a45ff3e3230d8 \ + --hash=sha256:bec941d2aa8195e248a60b31ff9f0558284cf01a52591ceda73ea9afffd69fd9 # via # -c lock/requirements-dev.txt # httpcore @@ -88,9 +88,9 @@ click==8.1.7 \ # -c lock/requirements-dev.txt # typer # uvicorn -dnspython==2.6.1 \ - --hash=sha256:5ef3b9680161f6fa89daf8ad451b5f1a33b18ae8a1c6778cdf4b43f08c0a6e50 \ - --hash=sha256:e8f0f9c23a7b7cb99ded64e6c3a6f3e701d78f50c55e002b839dea7225cff7cc +dnspython==2.7.0 \ + --hash=sha256:b4c34b7d10b51bcc3a5071e7b8dee77939f1e878477eeecc965e9835f63c6c86 \ + --hash=sha256:ce9c432eda0dc91cf618a5cedf1a4e142651196bbcd2c80e89ed5a907e5cfaf1 # via # -c lock/requirements-dev.txt # email-validator @@ -126,68 +126,75 @@ h11==0.14.0 \ # -c lock/requirements-dev.txt # httpcore # uvicorn -hexkit==3.5.0 \ - --hash=sha256:30a82d170630a615836d6a42116f10a2052a9ae752137419f6abe1286a113a32 \ - --hash=sha256:b27599809b94f24e87153667afd9a72f46c46d267c06cafc595d40cdc6c53f89 +hexkit==3.6.0 \ + --hash=sha256:0f650bf87a95c91ddffa20f1c5c130b2c5aad719cb5031bf6c7ea60fa8f136c1 \ + --hash=sha256:70d8159565b43ce4fa54bb471a0cd873517162fb27a056e30613c4332822500b # via # -c lock/requirements-dev.txt # sms (pyproject.toml) # ghga-service-commons -httpcore==1.0.5 \ - --hash=sha256:34a38e2f9291467ee3b44e89dd52615370e152954ba21721378a87b2960f7a61 \ - --hash=sha256:421f18bac248b25d310f3cacd198d55b8e6125c107797b609ff9b7a6ba7991b5 +httpcore==1.0.6 \ + --hash=sha256:27b59625743b85577a8c0e10e55b50b5368a4f2cfe8cc7bcfa9cf00829c2682f \ + --hash=sha256:73f6dbd6eb8c21bbf7ef8efad555481853f5f6acdeaff1edb0694289269ee17f # via # -c lock/requirements-dev.txt # httpx -httptools==0.6.1 \ - --hash=sha256:00d5d4b68a717765b1fabfd9ca755bd12bf44105eeb806c03d1962acd9b8e563 \ - --hash=sha256:0ac5a0ae3d9f4fe004318d64b8a854edd85ab76cffbf7ef5e32920faef62f142 \ - --hash=sha256:0cf2372e98406efb42e93bfe10f2948e467edfd792b015f1b4ecd897903d3e8d \ - --hash=sha256:1ed99a373e327f0107cb513b61820102ee4f3675656a37a50083eda05dc9541b \ - --hash=sha256:3c3b214ce057c54675b00108ac42bacf2ab8f85c58e3f324a4e963bbc46424f4 \ - --hash=sha256:3e802e0b2378ade99cd666b5bffb8b2a7cc8f3d28988685dc300469ea8dd86cb \ - --hash=sha256:3f30d3ce413088a98b9db71c60a6ada2001a08945cb42dd65a9a9fe228627658 \ - --hash=sha256:405784577ba6540fa7d6ff49e37daf104e04f4b4ff2d1ac0469eaa6a20fde084 \ - --hash=sha256:48ed8129cd9a0d62cf4d1575fcf90fb37e3ff7d5654d3a5814eb3d55f36478c2 \ - --hash=sha256:4bd3e488b447046e386a30f07af05f9b38d3d368d1f7b4d8f7e10af85393db97 \ - --hash=sha256:4f0f8271c0a4db459f9dc807acd0eadd4839934a4b9b892f6f160e94da309837 \ - --hash=sha256:5cceac09f164bcba55c0500a18fe3c47df29b62353198e4f37bbcc5d591172c3 \ - --hash=sha256:639dc4f381a870c9ec860ce5c45921db50205a37cc3334e756269736ff0aac58 \ - --hash=sha256:678fcbae74477a17d103b7cae78b74800d795d702083867ce160fc202104d0da \ - --hash=sha256:6a4f5ccead6d18ec072ac0b84420e95d27c1cdf5c9f1bc8fbd8daf86bd94f43d \ - --hash=sha256:6f58e335a1402fb5a650e271e8c2d03cfa7cea46ae124649346d17bd30d59c90 \ - --hash=sha256:75c8022dca7935cba14741a42744eee13ba05db00b27a4b940f0d646bd4d56d0 \ - --hash=sha256:7a7ea483c1a4485c71cb5f38be9db078f8b0e8b4c4dc0210f531cdd2ddac1ef1 \ - --hash=sha256:7d9ceb2c957320def533671fc9c715a80c47025139c8d1f3797477decbc6edd2 \ - --hash=sha256:7ebaec1bf683e4bf5e9fbb49b8cc36da482033596a415b3e4ebab5a4c0d7ec5e \ - --hash=sha256:85ed077c995e942b6f1b07583e4eb0a8d324d418954fc6af913d36db7c05a5a0 \ - --hash=sha256:8ae5b97f690badd2ca27cbf668494ee1b6d34cf1c464271ef7bfa9ca6b83ffaf \ - --hash=sha256:8b0bb634338334385351a1600a73e558ce619af390c2b38386206ac6a27fecfc \ - --hash=sha256:8e216a038d2d52ea13fdd9b9c9c7459fb80d78302b257828285eca1c773b99b3 \ - --hash=sha256:93ad80d7176aa5788902f207a4e79885f0576134695dfb0fefc15b7a4648d503 \ - --hash=sha256:95658c342529bba4e1d3d2b1a874db16c7cca435e8827422154c9da76ac4e13a \ - --hash=sha256:95fb92dd3649f9cb139e9c56604cc2d7c7bf0fc2e7c8d7fbd58f96e35eddd2a3 \ - --hash=sha256:97662ce7fb196c785344d00d638fc9ad69e18ee4bfb4000b35a52efe5adcc949 \ - --hash=sha256:9bb68d3a085c2174c2477eb3ffe84ae9fb4fde8792edb7bcd09a1d8467e30a84 \ - --hash=sha256:b512aa728bc02354e5ac086ce76c3ce635b62f5fbc32ab7082b5e582d27867bb \ - --hash=sha256:c6e26c30455600b95d94b1b836085138e82f177351454ee841c148f93a9bad5a \ - --hash=sha256:d2f6c3c4cb1948d912538217838f6e9960bc4a521d7f9b323b3da579cd14532f \ - --hash=sha256:dcbab042cc3ef272adc11220517278519adf8f53fd3056d0e68f0a6f891ba94e \ - --hash=sha256:e0b281cf5a125c35f7f6722b65d8542d2e57331be573e9e88bc8b0115c4a7a81 \ - --hash=sha256:e57997ac7fb7ee43140cc03664de5f268813a481dff6245e0075925adc6aa185 \ - --hash=sha256:fe467eb086d80217b7584e61313ebadc8d187a4d95bb62031b7bab4b205c3ba3 +httptools==0.6.4 \ + --hash=sha256:0614154d5454c21b6410fdf5262b4a3ddb0f53f1e1721cfd59d55f32138c578a \ + --hash=sha256:0e563e54979e97b6d13f1bbc05a96109923e76b901f786a5eae36e99c01237bd \ + --hash=sha256:16e603a3bff50db08cd578d54f07032ca1631450ceb972c2f834c2b860c28ea2 \ + --hash=sha256:288cd628406cc53f9a541cfaf06041b4c71d751856bab45e3702191f931ccd17 \ + --hash=sha256:28908df1b9bb8187393d5b5db91435ccc9c8e891657f9cbb42a2541b44c82fc8 \ + --hash=sha256:322d20ea9cdd1fa98bd6a74b77e2ec5b818abdc3d36695ab402a0de8ef2865a3 \ + --hash=sha256:342dd6946aa6bda4b8f18c734576106b8a31f2fe31492881a9a160ec84ff4bd5 \ + --hash=sha256:345c288418f0944a6fe67be8e6afa9262b18c7626c3ef3c28adc5eabc06a68da \ + --hash=sha256:3c73ce323711a6ffb0d247dcd5a550b8babf0f757e86a52558fe5b86d6fefcc0 \ + --hash=sha256:40a5ec98d3f49904b9fe36827dcf1aadfef3b89e2bd05b0e35e94f97c2b14721 \ + --hash=sha256:40b0f7fe4fd38e6a507bdb751db0379df1e99120c65fbdc8ee6c1d044897a636 \ + --hash=sha256:40dc6a8e399e15ea525305a2ddba998b0af5caa2566bcd79dcbe8948181eeaff \ + --hash=sha256:4b36913ba52008249223042dca46e69967985fb4051951f94357ea681e1f5dc0 \ + --hash=sha256:4d87b29bd4486c0093fc64dea80231f7c7f7eb4dc70ae394d70a495ab8436071 \ + --hash=sha256:4e93eee4add6493b59a5c514da98c939b244fce4a0d8879cd3f466562f4b7d5c \ + --hash=sha256:59e724f8b332319e2875efd360e61ac07f33b492889284a3e05e6d13746876f4 \ + --hash=sha256:69422b7f458c5af875922cdb5bd586cc1f1033295aa9ff63ee196a87519ac8e1 \ + --hash=sha256:703c346571fa50d2e9856a37d7cd9435a25e7fd15e236c397bf224afaa355fe9 \ + --hash=sha256:85071a1e8c2d051b507161f6c3e26155b5c790e4e28d7f236422dbacc2a9cc44 \ + --hash=sha256:856f4bc0478ae143bad54a4242fccb1f3f86a6e1be5548fecfd4102061b3a083 \ + --hash=sha256:85797e37e8eeaa5439d33e556662cc370e474445d5fab24dcadc65a8ffb04003 \ + --hash=sha256:90d96a385fa941283ebd231464045187a31ad932ebfa541be8edf5b3c2328959 \ + --hash=sha256:94978a49b8f4569ad607cd4946b759d90b285e39c0d4640c6b36ca7a3ddf2efc \ + --hash=sha256:aafe0f1918ed07b67c1e838f950b1c1fabc683030477e60b335649b8020e1076 \ + --hash=sha256:ab9ba8dcf59de5181f6be44a77458e45a578fc99c31510b8c65b7d5acc3cf490 \ + --hash=sha256:ade273d7e767d5fae13fa637f4d53b6e961fb7fd93c7797562663f0171c26660 \ + --hash=sha256:b799de31416ecc589ad79dd85a0b2657a8fe39327944998dea368c1d4c9e55e6 \ + --hash=sha256:c26f313951f6e26147833fc923f78f95604bbec812a43e5ee37f26dc9e5a686c \ + --hash=sha256:ca80b7485c76f768a3bc83ea58373f8db7b015551117375e4918e2aa77ea9b50 \ + --hash=sha256:d1ffd262a73d7c28424252381a5b854c19d9de5f56f075445d33919a637e3547 \ + --hash=sha256:d3f0d369e7ffbe59c4b6116a44d6a8eb4783aae027f2c0b366cf0aa964185dba \ + --hash=sha256:d54efd20338ac52ba31e7da78e4a72570cf729fac82bc31ff9199bedf1dc7440 \ + --hash=sha256:dacdd3d10ea1b4ca9df97a0a303cbacafc04b5cd375fa98732678151643d4988 \ + --hash=sha256:db353d22843cf1028f43c3651581e4bb49374d85692a85f95f7b9a130e1b2cab \ + --hash=sha256:db78cb9ca56b59b016e64b6031eda5653be0589dba2b1b43453f6e8b405a0970 \ + --hash=sha256:deee0e3343f98ee8047e9f4c5bc7cedbf69f5734454a94c38ee829fb2d5fa3c1 \ + --hash=sha256:df017d6c780287d5c80601dafa31f17bddb170232d85c066604d8558683711a2 \ + --hash=sha256:df959752a0c2748a65ab5387d08287abf6779ae9165916fe053e68ae1fbdc47f \ + --hash=sha256:ec4f178901fa1834d4a060320d2f3abc5c9e39766953d038f1458cb885f47e81 \ + --hash=sha256:f47f8ed67cc0ff862b84a1189831d1d33c963fb3ce1ee0c65d3b0cbe7b711069 \ + --hash=sha256:f8787367fbdfccae38e35abf7641dafc5310310a5987b689f4c32cc8cc3ee975 \ + --hash=sha256:f9eb89ecf8b290f2e293325c646a211ff1c2493222798bb80a530c5e7502494f \ + --hash=sha256:fc411e1c0a7dcd2f902c7c48cf079947a7e65b5485dea9decb82b9105ca71a43 # via # -c lock/requirements-dev.txt # uvicorn -httpx==0.27.0 \ - --hash=sha256:71d5465162c13681bff01ad59b2cc68dd838ea1f10e51574bac27103f00c91a5 \ - --hash=sha256:a0cb88a46f32dc874e04ee956e4c2764aba2aa228f650b06788ba6bda2962ab5 +httpx==0.27.2 \ + --hash=sha256:7bb2708e112d8fdd7829cd4243970f0c223274051cb35ee80c03301ee29a3df0 \ + --hash=sha256:f7c2be1d2f3c3c3160d441802406b206c2b76f5947b11115e6df10c6c65e66c2 # via # -c lock/requirements-dev.txt # fastapi -idna==3.7 \ - --hash=sha256:028ff3aadf0609c1fd278d8ea3089299412a7a8b9bd005dd08b9f8285bcb5cfc \ - --hash=sha256:82fee1fc78add43492d3a1898bfa6d8a904cc97d8427f683ed8e798d07761aa0 +idna==3.10 \ + --hash=sha256:12f65c9b470abda6dc35cf8e63cc574b1c52b11df2c86030af0ac09b01b13ea9 \ + --hash=sha256:946d195a0d259cbba61165e88e65941f16e9b36ea6ddb97f00452bae8b1287d3 # via # -c lock/requirements-dev.txt # anyio @@ -212,9 +219,9 @@ jsonschema==4.23.0 \ # via # -c lock/requirements-dev.txt # hexkit -jsonschema-specifications==2023.12.1 \ - --hash=sha256:48a76787b3e70f5ed53f1160d2b81f586e4ca6d1548c5de7085d1682674764cc \ - --hash=sha256:87e4fdf3a94858b8a2ba2778d9ba57d8a9cafca7c7489c46ba0d30a8bc6a9c3c +jsonschema-specifications==2024.10.1 \ + --hash=sha256:0f38b83639958ce1152d02a7f062902c41c8fd20d558b0c34344292d417ae272 \ + --hash=sha256:a09a0680616357d9a0ecf05c12ad234479f549239d0f5b55f3deea67475da9bf # via # -c lock/requirements-dev.txt # jsonschema @@ -224,67 +231,68 @@ markdown-it-py==3.0.0 \ # via # -c lock/requirements-dev.txt # rich -markupsafe==2.1.5 \ - --hash=sha256:00e046b6dd71aa03a41079792f8473dc494d564611a8f89bbbd7cb93295ebdcf \ - --hash=sha256:075202fa5b72c86ad32dc7d0b56024ebdbcf2048c0ba09f1cde31bfdd57bcfff \ - --hash=sha256:0e397ac966fdf721b2c528cf028494e86172b4feba51d65f81ffd65c63798f3f \ - --hash=sha256:17b950fccb810b3293638215058e432159d2b71005c74371d784862b7e4683f3 \ - --hash=sha256:1f3fbcb7ef1f16e48246f704ab79d79da8a46891e2da03f8783a5b6fa41a9532 \ - --hash=sha256:2174c595a0d73a3080ca3257b40096db99799265e1c27cc5a610743acd86d62f \ - --hash=sha256:2b7c57a4dfc4f16f7142221afe5ba4e093e09e728ca65c51f5620c9aaeb9a617 \ - --hash=sha256:2d2d793e36e230fd32babe143b04cec8a8b3eb8a3122d2aceb4a371e6b09b8df \ - --hash=sha256:30b600cf0a7ac9234b2638fbc0fb6158ba5bdcdf46aeb631ead21248b9affbc4 \ - --hash=sha256:397081c1a0bfb5124355710fe79478cdbeb39626492b15d399526ae53422b906 \ - --hash=sha256:3a57fdd7ce31c7ff06cdfbf31dafa96cc533c21e443d57f5b1ecc6cdc668ec7f \ - --hash=sha256:3c6b973f22eb18a789b1460b4b91bf04ae3f0c4234a0a6aa6b0a92f6f7b951d4 \ - --hash=sha256:3e53af139f8579a6d5f7b76549125f0d94d7e630761a2111bc431fd820e163b8 \ - --hash=sha256:4096e9de5c6fdf43fb4f04c26fb114f61ef0bf2e5604b6ee3019d51b69e8c371 \ - --hash=sha256:4275d846e41ecefa46e2015117a9f491e57a71ddd59bbead77e904dc02b1bed2 \ - --hash=sha256:4c31f53cdae6ecfa91a77820e8b151dba54ab528ba65dfd235c80b086d68a465 \ - --hash=sha256:4f11aa001c540f62c6166c7726f71f7573b52c68c31f014c25cc7901deea0b52 \ - --hash=sha256:5049256f536511ee3f7e1b3f87d1d1209d327e818e6ae1365e8653d7e3abb6a6 \ - --hash=sha256:58c98fee265677f63a4385256a6d7683ab1832f3ddd1e66fe948d5880c21a169 \ - --hash=sha256:598e3276b64aff0e7b3451b72e94fa3c238d452e7ddcd893c3ab324717456bad \ - --hash=sha256:5b7b716f97b52c5a14bffdf688f971b2d5ef4029127f1ad7a513973cfd818df2 \ - --hash=sha256:5dedb4db619ba5a2787a94d877bc8ffc0566f92a01c0ef214865e54ecc9ee5e0 \ - --hash=sha256:619bc166c4f2de5caa5a633b8b7326fbe98e0ccbfacabd87268a2b15ff73a029 \ - --hash=sha256:629ddd2ca402ae6dbedfceeba9c46d5f7b2a61d9749597d4307f943ef198fc1f \ - --hash=sha256:656f7526c69fac7f600bd1f400991cc282b417d17539a1b228617081106feb4a \ - --hash=sha256:6ec585f69cec0aa07d945b20805be741395e28ac1627333b1c5b0105962ffced \ - --hash=sha256:72b6be590cc35924b02c78ef34b467da4ba07e4e0f0454a2c5907f473fc50ce5 \ - --hash=sha256:7502934a33b54030eaf1194c21c692a534196063db72176b0c4028e140f8f32c \ - --hash=sha256:7a68b554d356a91cce1236aa7682dc01df0edba8d043fd1ce607c49dd3c1edcf \ - --hash=sha256:7b2e5a267c855eea6b4283940daa6e88a285f5f2a67f2220203786dfa59b37e9 \ - --hash=sha256:823b65d8706e32ad2df51ed89496147a42a2a6e01c13cfb6ffb8b1e92bc910bb \ - --hash=sha256:8590b4ae07a35970728874632fed7bd57b26b0102df2d2b233b6d9d82f6c62ad \ - --hash=sha256:8dd717634f5a044f860435c1d8c16a270ddf0ef8588d4887037c5028b859b0c3 \ - --hash=sha256:8dec4936e9c3100156f8a2dc89c4b88d5c435175ff03413b443469c7c8c5f4d1 \ - --hash=sha256:97cafb1f3cbcd3fd2b6fbfb99ae11cdb14deea0736fc2b0952ee177f2b813a46 \ - --hash=sha256:a17a92de5231666cfbe003f0e4b9b3a7ae3afb1ec2845aadc2bacc93ff85febc \ - --hash=sha256:a549b9c31bec33820e885335b451286e2969a2d9e24879f83fe904a5ce59d70a \ - --hash=sha256:ac07bad82163452a6884fe8fa0963fb98c2346ba78d779ec06bd7a6262132aee \ - --hash=sha256:ae2ad8ae6ebee9d2d94b17fb62763125f3f374c25618198f40cbb8b525411900 \ - --hash=sha256:b91c037585eba9095565a3556f611e3cbfaa42ca1e865f7b8015fe5c7336d5a5 \ - --hash=sha256:bc1667f8b83f48511b94671e0e441401371dfd0f0a795c7daa4a3cd1dde55bea \ - --hash=sha256:bec0a414d016ac1a18862a519e54b2fd0fc8bbfd6890376898a6c0891dd82e9f \ - --hash=sha256:bf50cd79a75d181c9181df03572cdce0fbb75cc353bc350712073108cba98de5 \ - --hash=sha256:bff1b4290a66b490a2f4719358c0cdcd9bafb6b8f061e45c7a2460866bf50c2e \ - --hash=sha256:c061bb86a71b42465156a3ee7bd58c8c2ceacdbeb95d05a99893e08b8467359a \ - --hash=sha256:c8b29db45f8fe46ad280a7294f5c3ec36dbac9491f2d1c17345be8e69cc5928f \ - --hash=sha256:ce409136744f6521e39fd8e2a24c53fa18ad67aa5bc7c2cf83645cce5b5c4e50 \ - --hash=sha256:d050b3361367a06d752db6ead6e7edeb0009be66bc3bae0ee9d97fb326badc2a \ - --hash=sha256:d283d37a890ba4c1ae73ffadf8046435c76e7bc2247bbb63c00bd1a709c6544b \ - --hash=sha256:d9fad5155d72433c921b782e58892377c44bd6252b5af2f67f16b194987338a4 \ - --hash=sha256:daa4ee5a243f0f20d528d939d06670a298dd39b1ad5f8a72a4275124a7819eff \ - --hash=sha256:db0b55e0f3cc0be60c1f19efdde9a637c32740486004f20d1cff53c3c0ece4d2 \ - --hash=sha256:e61659ba32cf2cf1481e575d0462554625196a1f2fc06a1c777d3f48e8865d46 \ - --hash=sha256:ea3d8a3d18833cf4304cd2fc9cbb1efe188ca9b5efef2bdac7adc20594a0e46b \ - --hash=sha256:ec6a563cff360b50eed26f13adc43e61bc0c04d94b8be985e6fb24b81f6dcfdf \ - --hash=sha256:f5dfb42c4604dddc8e4305050aa6deb084540643ed5804d7455b5df8fe16f5e5 \ - --hash=sha256:fa173ec60341d6bb97a89f5ea19c85c5643c1e7dedebc22f5181eb73573142c5 \ - --hash=sha256:fa9db3f79de01457b03d4f01b34cf91bc0048eb2c3846ff26f66687c2f6d16ab \ - --hash=sha256:fce659a462a1be54d2ffcacea5e3ba2d74daa74f30f5f143fe0c58636e355fdd \ - --hash=sha256:ffee1f21e5ef0d712f9033568f8344d5da8cc2869dbd08d87c84656e6a2d2f68 +markupsafe==3.0.2 \ + --hash=sha256:0bff5e0ae4ef2e1ae4fdf2dfd5b76c75e5c2fa4132d05fc1b0dabcd20c7e28c4 \ + --hash=sha256:0f4ca02bea9a23221c0182836703cbf8930c5e9454bacce27e767509fa286a30 \ + --hash=sha256:1225beacc926f536dc82e45f8a4d68502949dc67eea90eab715dea3a21c1b5f0 \ + --hash=sha256:131a3c7689c85f5ad20f9f6fb1b866f402c445b220c19fe4308c0b147ccd2ad9 \ + --hash=sha256:15ab75ef81add55874e7ab7055e9c397312385bd9ced94920f2802310c930396 \ + --hash=sha256:1a9d3f5f0901fdec14d8d2f66ef7d035f2157240a433441719ac9a3fba440b13 \ + --hash=sha256:1c99d261bd2d5f6b59325c92c73df481e05e57f19837bdca8413b9eac4bd8028 \ + --hash=sha256:1e084f686b92e5b83186b07e8a17fc09e38fff551f3602b249881fec658d3eca \ + --hash=sha256:2181e67807fc2fa785d0592dc2d6206c019b9502410671cc905d132a92866557 \ + --hash=sha256:2cb8438c3cbb25e220c2ab33bb226559e7afb3baec11c4f218ffa7308603c832 \ + --hash=sha256:3169b1eefae027567d1ce6ee7cae382c57fe26e82775f460f0b2778beaad66c0 \ + --hash=sha256:3809ede931876f5b2ec92eef964286840ed3540dadf803dd570c3b7e13141a3b \ + --hash=sha256:38a9ef736c01fccdd6600705b09dc574584b89bea478200c5fbf112a6b0d5579 \ + --hash=sha256:3d79d162e7be8f996986c064d1c7c817f6df3a77fe3d6859f6f9e7be4b8c213a \ + --hash=sha256:444dcda765c8a838eaae23112db52f1efaf750daddb2d9ca300bcae1039adc5c \ + --hash=sha256:48032821bbdf20f5799ff537c7ac3d1fba0ba032cfc06194faffa8cda8b560ff \ + --hash=sha256:4aa4e5faecf353ed117801a068ebab7b7e09ffb6e1d5e412dc852e0da018126c \ + --hash=sha256:52305740fe773d09cffb16f8ed0427942901f00adedac82ec8b67752f58a1b22 \ + --hash=sha256:569511d3b58c8791ab4c2e1285575265991e6d8f8700c7be0e88f86cb0672094 \ + --hash=sha256:57cb5a3cf367aeb1d316576250f65edec5bb3be939e9247ae594b4bcbc317dfb \ + --hash=sha256:5b02fb34468b6aaa40dfc198d813a641e3a63b98c2b05a16b9f80b7ec314185e \ + --hash=sha256:6381026f158fdb7c72a168278597a5e3a5222e83ea18f543112b2662a9b699c5 \ + --hash=sha256:6af100e168aa82a50e186c82875a5893c5597a0c1ccdb0d8b40240b1f28b969a \ + --hash=sha256:6c89876f41da747c8d3677a2b540fb32ef5715f97b66eeb0c6b66f5e3ef6f59d \ + --hash=sha256:6e296a513ca3d94054c2c881cc913116e90fd030ad1c656b3869762b754f5f8a \ + --hash=sha256:70a87b411535ccad5ef2f1df5136506a10775d267e197e4cf531ced10537bd6b \ + --hash=sha256:7e94c425039cde14257288fd61dcfb01963e658efbc0ff54f5306b06054700f8 \ + --hash=sha256:846ade7b71e3536c4e56b386c2a47adf5741d2d8b94ec9dc3e92e5e1ee1e2225 \ + --hash=sha256:88416bd1e65dcea10bc7569faacb2c20ce071dd1f87539ca2ab364bf6231393c \ + --hash=sha256:88b49a3b9ff31e19998750c38e030fc7bb937398b1f78cfa599aaef92d693144 \ + --hash=sha256:8c4e8c3ce11e1f92f6536ff07154f9d49677ebaaafc32db9db4620bc11ed480f \ + --hash=sha256:8e06879fc22a25ca47312fbe7c8264eb0b662f6db27cb2d3bbbc74b1df4b9b87 \ + --hash=sha256:9025b4018f3a1314059769c7bf15441064b2207cb3f065e6ea1e7359cb46db9d \ + --hash=sha256:93335ca3812df2f366e80509ae119189886b0f3c2b81325d39efdb84a1e2ae93 \ + --hash=sha256:9778bd8ab0a994ebf6f84c2b949e65736d5575320a17ae8984a77fab08db94cf \ + --hash=sha256:9e2d922824181480953426608b81967de705c3cef4d1af983af849d7bd619158 \ + --hash=sha256:a123e330ef0853c6e822384873bef7507557d8e4a082961e1defa947aa59ba84 \ + --hash=sha256:a904af0a6162c73e3edcb969eeeb53a63ceeb5d8cf642fade7d39e7963a22ddb \ + --hash=sha256:ad10d3ded218f1039f11a75f8091880239651b52e9bb592ca27de44eed242a48 \ + --hash=sha256:b424c77b206d63d500bcb69fa55ed8d0e6a3774056bdc4839fc9298a7edca171 \ + --hash=sha256:b5a6b3ada725cea8a5e634536b1b01c30bcdcd7f9c6fff4151548d5bf6b3a36c \ + --hash=sha256:ba8062ed2cf21c07a9e295d5b8a2a5ce678b913b45fdf68c32d95d6c1291e0b6 \ + --hash=sha256:ba9527cdd4c926ed0760bc301f6728ef34d841f405abf9d4f959c478421e4efd \ + --hash=sha256:bbcb445fa71794da8f178f0f6d66789a28d7319071af7a496d4d507ed566270d \ + --hash=sha256:bcf3e58998965654fdaff38e58584d8937aa3096ab5354d493c77d1fdd66d7a1 \ + --hash=sha256:c0ef13eaeee5b615fb07c9a7dadb38eac06a0608b41570d8ade51c56539e509d \ + --hash=sha256:cabc348d87e913db6ab4aa100f01b08f481097838bdddf7c7a84b7575b7309ca \ + --hash=sha256:cdb82a876c47801bb54a690c5ae105a46b392ac6099881cdfb9f6e95e4014c6a \ + --hash=sha256:cfad01eed2c2e0c01fd0ecd2ef42c492f7f93902e39a42fc9ee1692961443a29 \ + --hash=sha256:d16a81a06776313e817c951135cf7340a3e91e8c1ff2fac444cfd75fffa04afe \ + --hash=sha256:d8213e09c917a951de9d09ecee036d5c7d36cb6cb7dbaece4c71a60d79fb9798 \ + --hash=sha256:e07c3764494e3776c602c1e78e298937c3315ccc9043ead7e685b7f2b8d47b3c \ + --hash=sha256:e17c96c14e19278594aa4841ec148115f9c7615a47382ecb6b82bd8fea3ab0c8 \ + --hash=sha256:e444a31f8db13eb18ada366ab3cf45fd4b31e4db1236a4448f68778c1d1a5a2f \ + --hash=sha256:e6a2a455bd412959b57a172ce6328d2dd1f01cb2135efda2e4576e8a23fa3b0f \ + --hash=sha256:eaa0a10b7f72326f1372a713e73c3f739b524b3af41feb43e4921cb529f5929a \ + --hash=sha256:eb7972a85c54febfb25b5c4b4f3af4dcc731994c7da0d8a0b4a6eb0640e1d178 \ + --hash=sha256:ee55d3edf80167e48ea11a923c7386f4669df67d7994554387f84e7d8b0a2bf0 \ + --hash=sha256:f3818cb119498c0678015754eba762e0d61e5b52d34c8b13d770f0719f7b1d79 \ + --hash=sha256:f8b3d067f2e40fe93e1ccdd6b2e1d16c43140e76f02fb1319a05cf2b79d99430 \ + --hash=sha256:fcabf5ff6eea076f859677f5f0b6b5c1a51e70a376b0579e0eadef8db48c6b50 # via # -c lock/requirements-dev.txt # jinja2 @@ -294,9 +302,9 @@ mdurl==0.1.2 \ # via # -c lock/requirements-dev.txt # markdown-it-py -motor==3.5.1 \ - --hash=sha256:1622bd7b39c3e6375607c14736f6e1d498128eadf6f5f93f8786cf17d37062ac \ - --hash=sha256:f95a9ea0f011464235e0bd72910baa291db3a6009e617ac27b82f57885abafb8 +motor==3.6.0 \ + --hash=sha256:0ef7f520213e852bf0eac306adf631aabe849227d8aec900a2612512fb9c5b8d \ + --hash=sha256:9f07ed96f1754963d4386944e1b52d403a5350c687edc60da487d66f98dbf894 # via # -c lock/requirements-dev.txt # hexkit @@ -306,111 +314,111 @@ packaging==24.1 \ # via # -c lock/requirements-dev.txt # aiokafka -pydantic==2.8.2 \ - --hash=sha256:6f62c13d067b0755ad1c21a34bdd06c0c12625a22b0fc09c6b149816604f7c2a \ - --hash=sha256:73ee9fddd406dc318b885c7a2eab8a6472b68b8fb5ba8150949fc3db939f23c8 +pydantic==2.9.2 \ + --hash=sha256:d155cef71265d1e9807ed1c32b4c8deec042a44a50a4188b25ac67ecd81a9c0f \ + --hash=sha256:f048cec7b26778210e28a0459867920654d48e5e62db0958433636cde4254f12 # via # -c lock/requirements-dev.txt # fastapi # ghga-service-commons # hexkit # pydantic-settings -pydantic-core==2.20.1 \ - --hash=sha256:035ede2e16da7281041f0e626459bcae33ed998cca6a0a007a5ebb73414ac72d \ - --hash=sha256:04024d270cf63f586ad41fff13fde4311c4fc13ea74676962c876d9577bcc78f \ - --hash=sha256:0827505a5c87e8aa285dc31e9ec7f4a17c81a813d45f70b1d9164e03a813a686 \ - --hash=sha256:084659fac3c83fd674596612aeff6041a18402f1e1bc19ca39e417d554468482 \ - --hash=sha256:10d4204d8ca33146e761c79f83cc861df20e7ae9f6487ca290a97702daf56006 \ - --hash=sha256:11b71d67b4725e7e2a9f6e9c0ac1239bbc0c48cce3dc59f98635efc57d6dac83 \ - --hash=sha256:150906b40ff188a3260cbee25380e7494ee85048584998c1e66df0c7a11c17a6 \ - --hash=sha256:175873691124f3d0da55aeea1d90660a6ea7a3cfea137c38afa0a5ffabe37b88 \ - --hash=sha256:177f55a886d74f1808763976ac4efd29b7ed15c69f4d838bbd74d9d09cf6fa86 \ - --hash=sha256:19c0fa39fa154e7e0b7f82f88ef85faa2a4c23cc65aae2f5aea625e3c13c735a \ - --hash=sha256:1eedfeb6089ed3fad42e81a67755846ad4dcc14d73698c120a82e4ccf0f1f9f6 \ - --hash=sha256:225b67a1f6d602de0ce7f6c1c3ae89a4aa25d3de9be857999e9124f15dab486a \ - --hash=sha256:242b8feb3c493ab78be289c034a1f659e8826e2233786e36f2893a950a719bb6 \ - --hash=sha256:254ec27fdb5b1ee60684f91683be95e5133c994cc54e86a0b0963afa25c8f8a6 \ - --hash=sha256:25e9185e2d06c16ee438ed39bf62935ec436474a6ac4f9358524220f1b236e43 \ - --hash=sha256:26ab812fa0c845df815e506be30337e2df27e88399b985d0bb4e3ecfe72df31c \ - --hash=sha256:26ca695eeee5f9f1aeeb211ffc12f10bcb6f71e2989988fda61dabd65db878d4 \ - --hash=sha256:26dc97754b57d2fd00ac2b24dfa341abffc380b823211994c4efac7f13b9e90e \ - --hash=sha256:270755f15174fb983890c49881e93f8f1b80f0b5e3a3cc1394a255706cabd203 \ - --hash=sha256:2aafc5a503855ea5885559eae883978c9b6d8c8993d67766ee73d82e841300dd \ - --hash=sha256:2d036c7187b9422ae5b262badb87a20a49eb6c5238b2004e96d4da1231badef1 \ - --hash=sha256:33499e85e739a4b60c9dac710c20a08dc73cb3240c9a0e22325e671b27b70d24 \ - --hash=sha256:37eee5b638f0e0dcd18d21f59b679686bbd18917b87db0193ae36f9c23c355fc \ - --hash=sha256:38cf1c40a921d05c5edc61a785c0ddb4bed67827069f535d794ce6bcded919fc \ - --hash=sha256:3acae97ffd19bf091c72df4d726d552c473f3576409b2a7ca36b2f535ffff4a3 \ - --hash=sha256:3c5ebac750d9d5f2706654c638c041635c385596caf68f81342011ddfa1e5598 \ - --hash=sha256:3d482efec8b7dc6bfaedc0f166b2ce349df0011f5d2f1f25537ced4cfc34fd98 \ - --hash=sha256:407653af5617f0757261ae249d3fba09504d7a71ab36ac057c938572d1bc9331 \ - --hash=sha256:40a783fb7ee353c50bd3853e626f15677ea527ae556429453685ae32280c19c2 \ - --hash=sha256:41e81317dd6a0127cabce83c0c9c3fbecceae981c8391e6f1dec88a77c8a569a \ - --hash=sha256:41f4c96227a67a013e7de5ff8f20fb496ce573893b7f4f2707d065907bffdbd6 \ - --hash=sha256:469f29f9093c9d834432034d33f5fe45699e664f12a13bf38c04967ce233d688 \ - --hash=sha256:4745f4ac52cc6686390c40eaa01d48b18997cb130833154801a442323cc78f91 \ - --hash=sha256:4868f6bd7c9d98904b748a2653031fc9c2f85b6237009d475b1008bfaeb0a5aa \ - --hash=sha256:4aa223cd1e36b642092c326d694d8bf59b71ddddc94cdb752bbbb1c5c91d833b \ - --hash=sha256:4dd484681c15e6b9a977c785a345d3e378d72678fd5f1f3c0509608da24f2ac0 \ - --hash=sha256:4f2790949cf385d985a31984907fecb3896999329103df4e4983a4a41e13e840 \ - --hash=sha256:512ecfbefef6dac7bc5eaaf46177b2de58cdf7acac8793fe033b24ece0b9566c \ - --hash=sha256:516d9227919612425c8ef1c9b869bbbee249bc91912c8aaffb66116c0b447ebd \ - --hash=sha256:53e431da3fc53360db73eedf6f7124d1076e1b4ee4276b36fb25514544ceb4a3 \ - --hash=sha256:595ba5be69b35777474fa07f80fc260ea71255656191adb22a8c53aba4479231 \ - --hash=sha256:5b5ff4911aea936a47d9376fd3ab17e970cc543d1b68921886e7f64bd28308d1 \ - --hash=sha256:5d41e6daee2813ecceea8eda38062d69e280b39df793f5a942fa515b8ed67953 \ - --hash=sha256:5e999ba8dd90e93d57410c5e67ebb67ffcaadcea0ad973240fdfd3a135506250 \ - --hash=sha256:5f239eb799a2081495ea659d8d4a43a8f42cd1fe9ff2e7e436295c38a10c286a \ - --hash=sha256:635fee4e041ab9c479e31edda27fcf966ea9614fff1317e280d99eb3e5ab6fe2 \ - --hash=sha256:65db0f2eefcaad1a3950f498aabb4875c8890438bc80b19362cf633b87a8ab20 \ - --hash=sha256:6b507132dcfc0dea440cce23ee2182c0ce7aba7054576efc65634f080dbe9434 \ - --hash=sha256:6b9d9bb600328a1ce523ab4f454859e9d439150abb0906c5a1983c146580ebab \ - --hash=sha256:70c8daf4faca8da5a6d655f9af86faf6ec2e1768f4b8b9d0226c02f3d6209703 \ - --hash=sha256:77bf3ac639c1ff567ae3b47f8d4cc3dc20f9966a2a6dd2311dcc055d3d04fb8a \ - --hash=sha256:784c1214cb6dd1e3b15dd8b91b9a53852aed16671cc3fbe4786f4f1db07089e2 \ - --hash=sha256:7eb6a0587eded33aeefea9f916899d42b1799b7b14b8f8ff2753c0ac1741edac \ - --hash=sha256:7ed1b0132f24beeec5a78b67d9388656d03e6a7c837394f99257e2d55b461611 \ - --hash=sha256:8ad4aeb3e9a97286573c03df758fc7627aecdd02f1da04516a86dc159bf70121 \ - --hash=sha256:964faa8a861d2664f0c7ab0c181af0bea66098b1919439815ca8803ef136fc4e \ - --hash=sha256:9dc1b507c12eb0481d071f3c1808f0529ad41dc415d0ca11f7ebfc666e66a18b \ - --hash=sha256:9ebfef07dbe1d93efb94b4700f2d278494e9162565a54f124c404a5656d7ff09 \ - --hash=sha256:a45f84b09ac9c3d35dfcf6a27fd0634d30d183205230a0ebe8373a0e8cfa0906 \ - --hash=sha256:a4f55095ad087474999ee28d3398bae183a66be4823f753cd7d67dd0153427c9 \ - --hash=sha256:a6d511cc297ff0883bc3708b465ff82d7560193169a8b93260f74ecb0a5e08a7 \ - --hash=sha256:a8ad4c766d3f33ba8fd692f9aa297c9058970530a32c728a2c4bfd2616d3358b \ - --hash=sha256:aa2f457b4af386254372dfa78a2eda2563680d982422641a85f271c859df1987 \ - --hash=sha256:b03f7941783b4c4a26051846dea594628b38f6940a2fdc0df00b221aed39314c \ - --hash=sha256:b0dae11d8f5ded51699c74d9548dcc5938e0804cc8298ec0aa0da95c21fff57b \ - --hash=sha256:b91ced227c41aa29c672814f50dbb05ec93536abf8f43cd14ec9521ea09afe4e \ - --hash=sha256:bc633a9fe1eb87e250b5c57d389cf28998e4292336926b0b6cdaee353f89a237 \ - --hash=sha256:bebb4d6715c814597f85297c332297c6ce81e29436125ca59d1159b07f423eb1 \ - --hash=sha256:c336a6d235522a62fef872c6295a42ecb0c4e1d0f1a3e500fe949415761b8a19 \ - --hash=sha256:c6514f963b023aeee506678a1cf821fe31159b925c4b76fe2afa94cc70b3222b \ - --hash=sha256:c693e916709c2465b02ca0ad7b387c4f8423d1db7b4649c551f27a529181c5ad \ - --hash=sha256:c81131869240e3e568916ef4c307f8b99583efaa60a8112ef27a366eefba8ef0 \ - --hash=sha256:d02a72df14dfdbaf228424573a07af10637bd490f0901cee872c4f434a735b94 \ - --hash=sha256:d2a8fa9d6d6f891f3deec72f5cc668e6f66b188ab14bb1ab52422fe8e644f312 \ - --hash=sha256:d2b27e6af28f07e2f195552b37d7d66b150adbaa39a6d327766ffd695799780f \ - --hash=sha256:d2fe69c5434391727efa54b47a1e7986bb0186e72a41b203df8f5b0a19a4f669 \ - --hash=sha256:d3f3ed29cd9f978c604708511a1f9c2fdcb6c38b9aae36a51905b8811ee5cbf1 \ - --hash=sha256:d573faf8eb7e6b1cbbcb4f5b247c60ca8be39fe2c674495df0eb4318303137fe \ - --hash=sha256:e0bbdd76ce9aa5d4209d65f2b27fc6e5ef1312ae6c5333c26db3f5ade53a1e99 \ - --hash=sha256:e7c4ea22b6739b162c9ecaaa41d718dfad48a244909fe7ef4b54c0b530effc5a \ - --hash=sha256:e93e1a4b4b33daed65d781a57a522ff153dcf748dee70b40c7258c5861e1768a \ - --hash=sha256:e97fdf088d4b31ff4ba35db26d9cc472ac7ef4a2ff2badeabf8d727b3377fc52 \ - --hash=sha256:e9fa4c9bf273ca41f940bceb86922a7667cd5bf90e95dbb157cbb8441008482c \ - --hash=sha256:eaad4ff2de1c3823fddf82f41121bdf453d922e9a238642b1dedb33c4e4f98ad \ - --hash=sha256:f1f62b2413c3a0e846c3b838b2ecd6c7a19ec6793b2a522745b0869e37ab5bc1 \ - --hash=sha256:f6d6cff3538391e8486a431569b77921adfcdef14eb18fbf19b7c0a5294d4e6a \ - --hash=sha256:f9aa05d09ecf4c75157197f27cdc9cfaeb7c5f15021c6373932bf3e124af029f \ - --hash=sha256:fa2fddcb7107e0d1808086ca306dcade7df60a13a6c347a7acf1ec139aa6789a \ - --hash=sha256:faa6b09ee09433b87992fb5a2859efd1c264ddc37280d2dd5db502126d0e7f27 +pydantic-core==2.23.4 \ + --hash=sha256:0a7df63886be5e270da67e0966cf4afbae86069501d35c8c1b3b6c168f42cb36 \ + --hash=sha256:0cb3da3fd1b6a5d0279a01877713dbda118a2a4fc6f0d821a57da2e464793f05 \ + --hash=sha256:0dbd8dbed2085ed23b5c04afa29d8fd2771674223135dc9bc937f3c09284d071 \ + --hash=sha256:0dff76e0602ca7d4cdaacc1ac4c005e0ce0dcfe095d5b5259163a80d3a10d327 \ + --hash=sha256:1278e0d324f6908e872730c9102b0112477a7f7cf88b308e4fc36ce1bdb6d58c \ + --hash=sha256:128585782e5bfa515c590ccee4b727fb76925dd04a98864182b22e89a4e6ed36 \ + --hash=sha256:1498bec4c05c9c787bde9125cfdcc63a41004ff167f495063191b863399b1a29 \ + --hash=sha256:19442362866a753485ba5e4be408964644dd6a09123d9416c54cd49171f50744 \ + --hash=sha256:1b84d168f6c48fabd1f2027a3d1bdfe62f92cade1fb273a5d68e621da0e44e6d \ + --hash=sha256:1e90d2e3bd2c3863d48525d297cd143fe541be8bbf6f579504b9712cb6b643ec \ + --hash=sha256:20152074317d9bed6b7a95ade3b7d6054845d70584216160860425f4fbd5ee9e \ + --hash=sha256:216f9b2d7713eb98cb83c80b9c794de1f6b7e3145eef40400c62e86cee5f4e1e \ + --hash=sha256:233710f069d251feb12a56da21e14cca67994eab08362207785cf8c598e74577 \ + --hash=sha256:255a8ef062cbf6674450e668482456abac99a5583bbafb73f9ad469540a3a232 \ + --hash=sha256:2584f7cf844ac4d970fba483a717dbe10c1c1c96a969bf65d61ffe94df1b2863 \ + --hash=sha256:2971bb5ffe72cc0f555c13e19b23c85b654dd2a8f7ab493c262071377bfce9f6 \ + --hash=sha256:29d2c342c4bc01b88402d60189f3df065fb0dda3654744d5a165a5288a657368 \ + --hash=sha256:2e203fdf807ac7e12ab59ca2bfcabb38c7cf0b33c41efeb00f8e5da1d86af480 \ + --hash=sha256:33e3d65a85a2a4a0dc3b092b938a4062b1a05f3a9abde65ea93b233bca0e03f2 \ + --hash=sha256:374a5e5049eda9e0a44c696c7ade3ff355f06b1fe0bb945ea3cac2bc336478a2 \ + --hash=sha256:37b0fe330e4a58d3c58b24d91d1eb102aeec675a3db4c292ec3928ecd892a9a6 \ + --hash=sha256:3d5639516376dce1940ea36edf408c554475369f5da2abd45d44621cb616f769 \ + --hash=sha256:42c6dcb030aefb668a2b7009c85b27f90e51e6a3b4d5c9bc4c57631292015b0d \ + --hash=sha256:4a7cd62e831afe623fbb7aabbb4fe583212115b3ef38a9f6b71869ba644624a2 \ + --hash=sha256:4ba762ed58e8d68657fc1281e9bb72e1c3e79cc5d464be146e260c541ec12d84 \ + --hash=sha256:4fc714bdbfb534f94034efaa6eadd74e5b93c8fa6315565a222f7b6f42ca1166 \ + --hash=sha256:4ffa2ebd4c8530079140dd2d7f794a9d9a73cbb8e9d59ffe24c63436efa8f271 \ + --hash=sha256:5a1504ad17ba4210df3a045132a7baeeba5a200e930f57512ee02909fc5c4cb5 \ + --hash=sha256:5c364564d17da23db1106787675fc7af45f2f7b58b4173bfdd105564e132e6fb \ + --hash=sha256:5e11661ce0fd30a6790e8bcdf263b9ec5988e95e63cf901972107efc49218b13 \ + --hash=sha256:5f54b118ce5de9ac21c363d9b3caa6c800341e8c47a508787e5868c6b79c9323 \ + --hash=sha256:5f5ff8d839f4566a474a969508fe1c5e59c31c80d9e140566f9a37bba7b8d556 \ + --hash=sha256:61817945f2fe7d166e75fbfb28004034b48e44878177fc54d81688e7b85a3665 \ + --hash=sha256:624e278a7d29b6445e4e813af92af37820fafb6dcc55c012c834f9e26f9aaaef \ + --hash=sha256:63e46b3169866bd62849936de036f901a9356e36376079b05efa83caeaa02ceb \ + --hash=sha256:6531b7ca5f951d663c339002e91aaebda765ec7d61b7d1e3991051906ddde119 \ + --hash=sha256:68665f4c17edcceecc112dfed5dbe6f92261fb9d6054b47d01bf6371a6196126 \ + --hash=sha256:696dd8d674d6ce621ab9d45b205df149399e4bb9aa34102c970b721554828510 \ + --hash=sha256:6f783e0ec4803c787bcea93e13e9932edab72068f68ecffdf86a99fd5918878b \ + --hash=sha256:723314c1d51722ab28bfcd5240d858512ffd3116449c557a1336cbe3919beb87 \ + --hash=sha256:74b9127ffea03643e998e0c5ad9bd3811d3dac8c676e47db17b0ee7c3c3bf35f \ + --hash=sha256:7530e201d10d7d14abce4fb54cfe5b94a0aefc87da539d0346a484ead376c3cc \ + --hash=sha256:77733e3892bb0a7fa797826361ce8a9184d25c8dffaec60b7ffe928153680ba8 \ + --hash=sha256:78ddaaa81421a29574a682b3179d4cf9e6d405a09b99d93ddcf7e5239c742e21 \ + --hash=sha256:7c9129eb40958b3d4500fa2467e6a83356b3b61bfff1b414c7361d9220f9ae8f \ + --hash=sha256:7d32706badfe136888bdea71c0def994644e09fff0bfe47441deaed8e96fdbc6 \ + --hash=sha256:81965a16b675b35e1d09dd14df53f190f9129c0202356ed44ab2728b1c905658 \ + --hash=sha256:8394d940e5d400d04cad4f75c0598665cbb81aecefaca82ca85bd28264af7f9b \ + --hash=sha256:86d2f57d3e1379a9525c5ab067b27dbb8a0642fb5d454e17a9ac434f9ce523e3 \ + --hash=sha256:883a91b5dd7d26492ff2f04f40fbb652de40fcc0afe07e8129e8ae779c2110eb \ + --hash=sha256:88ad334a15b32a791ea935af224b9de1bf99bcd62fabf745d5f3442199d86d59 \ + --hash=sha256:9261d3ce84fa1d38ed649c3638feefeae23d32ba9182963e465d58d62203bd24 \ + --hash=sha256:97df63000f4fea395b2824da80e169731088656d1818a11b95f3b173747b6cd9 \ + --hash=sha256:98d134c954828488b153d88ba1f34e14259284f256180ce659e8d83e9c05eaa3 \ + --hash=sha256:996a38a83508c54c78a5f41456b0103c30508fed9abcad0a59b876d7398f25fd \ + --hash=sha256:9a5bce9d23aac8f0cf0836ecfc033896aa8443b501c58d0602dbfd5bd5b37753 \ + --hash=sha256:9a6b5099eeec78827553827f4c6b8615978bb4b6a88e5d9b93eddf8bb6790f55 \ + --hash=sha256:9d18368b137c6295db49ce7218b1a9ba15c5bc254c96d7c9f9e924a9bc7825ad \ + --hash=sha256:a4fa4fc04dff799089689f4fd502ce7d59de529fc2f40a2c8836886c03e0175a \ + --hash=sha256:a5c7ba8ffb6d6f8f2ab08743be203654bb1aaa8c9dcb09f82ddd34eadb695605 \ + --hash=sha256:aea443fffa9fbe3af1a9ba721a87f926fe548d32cab71d188a6ede77d0ff244e \ + --hash=sha256:b10bd51f823d891193d4717448fab065733958bdb6a6b351967bd349d48d5c9b \ + --hash=sha256:ba1a0996f6c2773bd83e63f18914c1de3c9dd26d55f4ac302a7efe93fb8e7433 \ + --hash=sha256:bb2802e667b7051a1bebbfe93684841cc9351004e2badbd6411bf357ab8d5ac8 \ + --hash=sha256:cfdd16ab5e59fc31b5e906d1a3f666571abc367598e3e02c83403acabc092e07 \ + --hash=sha256:d06b0c8da4f16d1d1e352134427cb194a0a6e19ad5db9161bf32b2113409e728 \ + --hash=sha256:d0776dea117cf5272382634bd2a5c1b6eb16767c223c6a5317cd3e2a757c61a0 \ + --hash=sha256:d18ca8148bebe1b0a382a27a8ee60350091a6ddaf475fa05ef50dc35b5df6327 \ + --hash=sha256:d4488a93b071c04dc20f5cecc3631fc78b9789dd72483ba15d423b5b3689b555 \ + --hash=sha256:d5f7a395a8cf1621939692dba2a6b6a830efa6b3cee787d82c7de1ad2930de64 \ + --hash=sha256:d7a80d21d613eec45e3d41eb22f8f94ddc758a6c4720842dc74c0581f54993d6 \ + --hash=sha256:d97683ddee4723ae8c95d1eddac7c192e8c552da0c73a925a89fa8649bf13eea \ + --hash=sha256:dcedcd19a557e182628afa1d553c3895a9f825b936415d0dbd3cd0bbcfd29b4b \ + --hash=sha256:de6d1d1b9e5101508cb37ab0d972357cac5235f5c6533d1071964c47139257df \ + --hash=sha256:df49e7a0861a8c36d089c1ed57d308623d60416dab2647a4a17fe050ba85de0e \ + --hash=sha256:df933278128ea1cd77772673c73954e53a1c95a4fdf41eef97c2b779271bd0bd \ + --hash=sha256:e08277a400de01bc72436a0ccd02bdf596631411f592ad985dcee21445bd0068 \ + --hash=sha256:e38e63e6f3d1cec5a27e0afe90a085af8b6806ee208b33030e65b6516353f1a3 \ + --hash=sha256:e55541f756f9b3ee346b840103f32779c695a19826a4c442b7954550a0972040 \ + --hash=sha256:ec4e55f79b1c4ffb2eecd8a0cfba9955a2588497d96851f4c8f99aa4a1d39b12 \ + --hash=sha256:ed1a53de42fbe34853ba90513cea21673481cd81ed1be739f7f2efb931b24916 \ + --hash=sha256:ed541d70698978a20eb63d8c5d72f2cc6d7079d9d90f6b50bad07826f1320f5f \ + --hash=sha256:f09e2ff1f17c2b51f2bc76d1cc33da96298f0a036a137f5440ab3ec5360b624f \ + --hash=sha256:f220b0eea5965dec25480b6333c788fb72ce5f9129e8759ef876a1d805d00801 \ + --hash=sha256:f3e0da4ebaef65158d4dfd7d3678aad692f7666877df0002b8a522cdf088f231 \ + --hash=sha256:f455ee30a9d61d3e1a15abd5068827773d6e4dc513e795f380cdd59932c782d5 \ + --hash=sha256:f5ef8f42bec47f21d07668a043f077d507e5bf4e668d5c6dfe6aaba89de1a5b8 \ + --hash=sha256:f69a8e0b033b747bb3e36a44e7732f0c99f7edd5cea723d45bc0d6e95377ffee \ + --hash=sha256:ff02b6d461a6de369f07ec15e465a88895f3223eb75073ffea56b84d9331f607 # via # -c lock/requirements-dev.txt # pydantic -pydantic-settings==2.4.0 \ - --hash=sha256:bb6849dc067f1687574c12a639e231f3a6feeed0a12d710c1382045c5db1c315 \ - --hash=sha256:ed81c3a0f46392b4d7c0a565c05884e6e54b3456e6f0fe4d8814981172dc9a88 +pydantic-settings==2.6.0 \ + --hash=sha256:44a1804abffac9e6a30372bb45f6cafab945ef5af25e66b1c634c01dd39e0188 \ + --hash=sha256:4a819166f119b74d7f8c765196b165f95cc7487ce58ea27dec8a5a26be0970e0 # via # -c lock/requirements-dev.txt # hexkit @@ -420,57 +428,66 @@ pygments==2.18.0 \ # via # -c lock/requirements-dev.txt # rich -pymongo==4.8.0 \ - --hash=sha256:0fc18b3a093f3db008c5fea0e980dbd3b743449eee29b5718bc2dc15ab5088bb \ - --hash=sha256:16e5019f75f6827bb5354b6fef8dfc9d6c7446894a27346e03134d290eb9e758 \ - --hash=sha256:180d5eb1dc28b62853e2f88017775c4500b07548ed28c0bd9c005c3d7bc52526 \ - --hash=sha256:18c9d8f975dd7194c37193583fd7d1eb9aea0c21ee58955ecf35362239ff31ac \ - --hash=sha256:236bbd7d0aef62e64caf4b24ca200f8c8670d1a6f5ea828c39eccdae423bc2b2 \ - --hash=sha256:284d0717d1a7707744018b0b6ee7801b1b1ff044c42f7be7a01bb013de639470 \ - --hash=sha256:2ecd71b9226bd1d49416dc9f999772038e56f415a713be51bf18d8676a0841c8 \ - --hash=sha256:31e4d21201bdf15064cf47ce7b74722d3e1aea2597c6785882244a3bb58c7eab \ - --hash=sha256:3b5802151fc2b51cd45492c80ed22b441d20090fb76d1fd53cd7760b340ff554 \ - --hash=sha256:3c68fe128a171493018ca5c8020fc08675be130d012b7ab3efe9e22698c612a1 \ - --hash=sha256:3ed1c316718a2836f7efc3d75b4b0ffdd47894090bc697de8385acd13c513a70 \ - --hash=sha256:408b2f8fdbeca3c19e4156f28fff1ab11c3efb0407b60687162d49f68075e63c \ - --hash=sha256:417369ce39af2b7c2a9c7152c1ed2393edfd1cbaf2a356ba31eb8bcbd5c98dd7 \ - --hash=sha256:454f2295875744dc70f1881e4b2eb99cdad008a33574bc8aaf120530f66c0cde \ - --hash=sha256:47ec8c3f0a7b2212dbc9be08d3bf17bc89abd211901093e3ef3f2adea7de7a69 \ - --hash=sha256:4bf58e6825b93da63e499d1a58de7de563c31e575908d4e24876234ccb910eba \ - --hash=sha256:519d1bab2b5e5218c64340b57d555d89c3f6c9d717cecbf826fb9d42415e7750 \ - --hash=sha256:52b4108ac9469febba18cea50db972605cc43978bedaa9fea413378877560ef8 \ - --hash=sha256:658d0170f27984e0d89c09fe5c42296613b711a3ffd847eb373b0dbb5b648d5f \ - --hash=sha256:6b50040d9767197b77ed420ada29b3bf18a638f9552d80f2da817b7c4a4c9c68 \ - --hash=sha256:7148419eedfea9ecb940961cfe465efaba90595568a1fb97585fb535ea63fe2b \ - --hash=sha256:77f53429515d2b3e86dcc83dadecf7ff881e538c168d575f3688698a8707b80a \ - --hash=sha256:87075a1feb1e602e539bdb1ef8f4324a3427eb0d64208c3182e677d2c0718b6f \ - --hash=sha256:8b18c8324809539c79bd6544d00e0607e98ff833ca21953df001510ca25915d1 \ - --hash=sha256:9097c331577cecf8034422956daaba7ec74c26f7b255d718c584faddd7fa2e3c \ - --hash=sha256:920d4f8f157a71b3cb3f39bc09ce070693d6e9648fb0e30d00e2657d1dca4e49 \ - --hash=sha256:9365166aa801c63dff1a3cb96e650be270da06e3464ab106727223123405510f \ - --hash=sha256:940d456774b17814bac5ea7fc28188c7a1338d4a233efbb6ba01de957bded2e8 \ - --hash=sha256:aec2b9088cdbceb87e6ca9c639d0ff9b9d083594dda5ca5d3c4f6774f4c81b33 \ - --hash=sha256:af3e98dd9702b73e4e6fd780f6925352237f5dce8d99405ff1543f3771201704 \ - --hash=sha256:b6564780cafd6abeea49759fe661792bd5a67e4f51bca62b88faab497ab5fe89 \ - --hash=sha256:b747c0e257b9d3e6495a018309b9e0c93b7f0d65271d1d62e572747f4ffafc88 \ - --hash=sha256:bf821bd3befb993a6db17229a2c60c1550e957de02a6ff4dd0af9476637b2e4d \ - --hash=sha256:c6b804bb4f2d9dc389cc9e827d579fa327272cdb0629a99bfe5b83cb3e269ebf \ - --hash=sha256:cc8b8582f4209c2459b04b049ac03c72c618e011d3caa5391ff86d1bda0cc486 \ - --hash=sha256:cd39455b7ee70aabee46f7399b32ab38b86b236c069ae559e22be6b46b2bbfc4 \ - --hash=sha256:d0cf61450feadca81deb1a1489cb1a3ae1e4266efd51adafecec0e503a8dcd84 \ - --hash=sha256:d18d86bc9e103f4d3d4f18b85a0471c0e13ce5b79194e4a0389a224bb70edd53 \ - --hash=sha256:d5428dbcd43d02f6306e1c3c95f692f68b284e6ee5390292242f509004c9e3a8 \ - --hash=sha256:de3a860f037bb51f968de320baef85090ff0bbb42ec4f28ec6a5ddf88be61871 \ - --hash=sha256:e0061af6e8c5e68b13f1ec9ad5251247726653c5af3c0bbdfbca6cf931e99216 \ - --hash=sha256:e5df28f74002e37bcbdfdc5109799f670e4dfef0fb527c391ff84f078050e7b5 \ - --hash=sha256:e6a720a3d22b54183352dc65f08cd1547204d263e0651b213a0a2e577e838526 \ - --hash=sha256:e8400587d594761e5136a3423111f499574be5fd53cf0aefa0d0f05b180710b0 \ - --hash=sha256:e84bc7707492f06fbc37a9f215374d2977d21b72e10a67f1b31893ec5a140ad8 \ - --hash=sha256:ef7225755ed27bfdb18730c68f6cb023d06c28f2b734597480fb4c0e500feb6f \ - --hash=sha256:f2b7bec27e047e84947fbd41c782f07c54c30c76d14f3b8bf0c89f7413fac67a \ - --hash=sha256:f2fbdb87fe5075c8beb17a5c16348a1ea3c8b282a5cb72d173330be2fecf22f5 \ - --hash=sha256:f5bf0eb8b6ef40fa22479f09375468c33bebb7fe49d14d9c96c8fd50355188b0 \ - --hash=sha256:fdc20cd1e1141b04696ffcdb7c71e8a4a665db31fe72e51ec706b3bdd2d09f36 +pymongo==4.9.2 \ + --hash=sha256:0e759ed0459e7264a11b6896016f616341a8e4c6ab7f71ae651bd21ffc7e9524 \ + --hash=sha256:169b85728cc17800344ba17d736375f400ef47c9fbb4c42910c4b3e7c0247382 \ + --hash=sha256:1ad79d6a74f439a068caf9a1e2daeabc20bf895263435484bbd49e90fbea7809 \ + --hash=sha256:1fc70326ae71b3c7b8d6af82f46bb71dafdba3c8f335b29382ae9cf263ef3a5c \ + --hash=sha256:24e7b6887bbfefd05afed26a99a2c69459e2daa351a43a410de0d6c0ee3cce4e \ + --hash=sha256:2c8c861e77527eec5a4b7363c16030dd0374670b620b08a5300f97594bbf5a40 \ + --hash=sha256:3010018f5672e5b7e8d096dea9f1ea6545b05345ff0eb1754f6ee63785550773 \ + --hash=sha256:3039e093d28376d6a54bdaa963ca12230c8a53d7b19c8e6368e19bcfbd004176 \ + --hash=sha256:31c35d3dac5a1b0f65b3da2a19dc7fb88271c86329c75cfea775d5381ade6c06 \ + --hash=sha256:3c3c71337d4c923f719cb56253af9244e90353a2454088ee4f184bfb0dd446a4 \ + --hash=sha256:3e63535946f5df7848307b9031aa921f82bb0cbe45f9b0c3296f2173f9283eb0 \ + --hash=sha256:3f55efe0f77198c055800e605268bfd77a3f0223d1a80b55b771d0c350bc3ade \ + --hash=sha256:410ea165f2f819118eed764c5faa35fa71aeff5ce8b5046af99ed158a5661e9e \ + --hash=sha256:5af264b9a973859123e3129d131d7246f57659304400e3e6b35ed6eaf099854d \ + --hash=sha256:65c6b2e2a6db38f49433021dda0802ad081118224b2264500ef03a2d82ae26a7 \ + --hash=sha256:69394ee9f0ce38ff71266bad01b7e045cd75e58500ebad5d72187cbabf2e652a \ + --hash=sha256:6ab42d9ee93fe6b90020c42cba5bfb43a2b4660951225d137835efc21940da48 \ + --hash=sha256:6c798351666ac97a0ddaa823689061c3af949c2d6acf7fb2d9ab0a7f465ced79 \ + --hash=sha256:6f6834d575ed87edc7dfcab4501d961b6a423b3839edd29ecb1382eee7736777 \ + --hash=sha256:77528a2b928fe3f1f655cefa195e6718ab1ccd1a456aba486d76318e526a7fac \ + --hash=sha256:7a0b2e7fedc5911cd44590b5fd8e3714029f378f37f3c0c2043f67150b588d4a \ + --hash=sha256:7fb10d7069f1e7d7d6a458b1c5e9d1454be6eca2d9885bec25c1202e22c88d2a \ + --hash=sha256:8083bbe8cb10bb33dca4d93f8223dd8d848215250bb73867374650bac5fe69e1 \ + --hash=sha256:80a1ee9b72eebd96619ebe0beb718a5bcf2a70f464edf315f97b9315ed6854a9 \ + --hash=sha256:877699e21703717507cbbea23e75b419f81a513b50b65531e1698df08b2d7094 \ + --hash=sha256:87b18094100f21615d9db99c255dcd9e93e476f10fb03c1d3632cf4b82d201d2 \ + --hash=sha256:8aac5dce28454f47576063fbad31ea9789bba67cab86c95788f97aafd810e65b \ + --hash=sha256:96ad54433a996e2d1985a9cd8fc82538ca8747c95caae2daf453600cc8c317f9 \ + --hash=sha256:98b9cade40f5b13e04492a42ae215c3721099be1014ddfe0fbd23f27e4f62c0c \ + --hash=sha256:99e40f44877b32bf4b3c46ceed2228f08c222cf7dec8a4366dd192a1429143fa \ + --hash=sha256:a1b8c636bf557c7166e3799bbf1120806ca39e3f06615b141c88d9c9ceae4d8c \ + --hash=sha256:a49d9292f22a0395c0fd2822a06e385910f1f902c3a9feafc1d0bfc27cd2df6b \ + --hash=sha256:a663ca60e187a248d370c58961e40f5463077d2b43831eb92120ea28a79ecf96 \ + --hash=sha256:a92c96886048d3ebae62dbcfc775c7f2b965270160e3cb6aab4e06750e030b05 \ + --hash=sha256:aac78b5fdd49ed8cae49adf76befacb02293a23b412676775c4715148e166d85 \ + --hash=sha256:ab8d54529feb6e29035ba8f0570c99ad36424bc26486c238ad7ce28597bc43c8 \ + --hash=sha256:ae227bba43e2e6fc8c3440a70b3b8f9ab2b0eb0906d0d2cf814dd9490c572e2a \ + --hash=sha256:b3254769e708bc4aa634745c262081d13c841a80038eff3afd15631540a1d227 \ + --hash=sha256:b6e7251d59fa3dcbb1399a71a3aec63768cebc6b22180b671601c2195fe1f90a \ + --hash=sha256:ba9d2f6df977fee24437f82f7412460b0628cd6b961c4235c9cff71577a5b61f \ + --hash=sha256:bc9322ce7cf116458a637ac10517b0c5926a8211202be6dbdc51dab4d4a9afc8 \ + --hash=sha256:bf77bf175c315e299a91332c2bbebc097c4d4fcc8713e513a9861684aa39023a \ + --hash=sha256:bf963104dfd7235bebc44cef40b4b12c6638bb03b3a828cb495498e286b6edd0 \ + --hash=sha256:c3f28afd783be3cebef1235a45340589169d7774cd9909ba0249e2f851ff511d \ + --hash=sha256:c42b5aad8971256365bfd0a545fb1c7a199c93db80decd298ea2f987419e2a6d \ + --hash=sha256:cca029f46acf475504eedb33c7839f030c4bc4f946dcba12d9a954cc48850b79 \ + --hash=sha256:cd832de5df92caa68ee66c872708951d7e0c1f7b289b74189f2ccf1832c56dda \ + --hash=sha256:d1d5e7123af1fddf15b2b53e58f20bf5242884e671bcc3860f5e954fe13aeddd \ + --hash=sha256:dde6068ae7c62ea8ee2c5701f78c6a75618cada7e11f03893687df87709558de \ + --hash=sha256:e1ab6cd7cd2d38ffc7ccdc79fdc166c7a91a63f844a96e3e6b2079c054391c68 \ + --hash=sha256:e3ff4201ea707f57bf381f61df0e9cd6e896627a59f98a5d1c4a1bd14a2544cb \ + --hash=sha256:e54e2c6f1dec45c57a587b4c13c16666d5f7c031a642ae177140d1e0551a947e \ + --hash=sha256:ea9c47f86a322280381e9ddba7491e664ea80bf75df247ea2346faf7626e4e4c \ + --hash=sha256:f13330bdf4a57ef70bdd6282721547ec464f773203be47bac1efc4abd74a9190 \ + --hash=sha256:f2f43e5d6e739aa78c7053bdf351453c0e53d7667a3cac73255c2169631e052a \ + --hash=sha256:f3fc60f242191840ccf02b898bc615b5141fbb70064f38f7e60fcaa35d3b5efd \ + --hash=sha256:f928bdc152a995cbd0b563fab201b2df873846d11f7a41d1f8cc8a01b35591ab \ + --hash=sha256:fdbd558d90b55d7c39c096a79f8a725f1f02b658211924ab98dbc03ecad01095 \ + --hash=sha256:fe97c847b56d61e533a7af0334193d6b28375b9189effce93129c7e4733794a9 # via # -c lock/requirements-dev.txt # motor @@ -487,9 +504,9 @@ python-dotenv==1.0.1 \ # -c lock/requirements-dev.txt # pydantic-settings # uvicorn -python-multipart==0.0.9 \ - --hash=sha256:03f54688c663f1b7977105f021043b0793151e4cb1c1a9d4a11fc13d622c4026 \ - --hash=sha256:97ca7b8ea7b05f977dc3849c3ba99d51689822fab725c3703af7c866a0c2b215 +python-multipart==0.0.14 \ + --hash=sha256:b8e744731296767cb005e1e9bd7bb985a77aa077de5406dbe59b588559b6f350 \ + --hash=sha256:bf01aea0941cd1173a97b7c53d8b686acd2fa535549b13431d8515467dabb2b4 # via # -c lock/requirements-dev.txt # fastapi @@ -558,9 +575,9 @@ referencing==0.35.1 \ # -c lock/requirements-dev.txt # jsonschema # jsonschema-specifications -rich==13.7.1 \ - --hash=sha256:4edbae314f59eb482f54e9e30bf00d33350aaa94f4bfcd4e9e3110e64d0d7222 \ - --hash=sha256:9be308cb1fe2f1f57d67ce99e95af38a1e2bc71ad9813b0e247cf7ffbcc3a432 +rich==13.9.3 \ + --hash=sha256:9836f5096eb2172c9e77df411c1b009bace4193d6a481d534fea75ebba758283 \ + --hash=sha256:bc1e01b899537598cf02579d2b9f4a415104d3fc439313a7a2c165d76557a08e # via # -c lock/requirements-dev.txt # typer @@ -672,9 +689,9 @@ rpds-py==0.20.0 \ # -c lock/requirements-dev.txt # jsonschema # referencing -s3transfer==0.10.2 \ - --hash=sha256:0711534e9356d3cc692fdde846b4a1e4b0cb6519971860796e6bc4c7aea00ef6 \ - --hash=sha256:eca1c20de70a39daee580aef4986996620f365c4e0fda6a86100231d62f1bf69 +s3transfer==0.10.3 \ + --hash=sha256:263ed587a5803c6c708d3ce44dc4dfedaab4c1a32e8329bab818933d79ddcf5d \ + --hash=sha256:4f50ed74ab84d474ce614475e0b8d5047ff080810aac5d01ea25231cfc944b0c # via # -c lock/requirements-dev.txt # boto3 @@ -703,9 +720,9 @@ starlette==0.37.2 \ # via # -c lock/requirements-dev.txt # fastapi -typer==0.12.4 \ - --hash=sha256:819aa03699f438397e876aa12b0d63766864ecba1b579092cc9fe35d886e34b6 \ - --hash=sha256:c9c1613ed6a166162705b3347b8d10b661ccc5d95692654d0fb628118f2c34e6 +typer==0.12.5 \ + --hash=sha256:62fe4e471711b147e3365034133904df3e235698399bc4de2b36c8579298d52b \ + --hash=sha256:f592f089bedcc8ec1b974125d64851029c3b1af145f04aca64d69410f0c9b722 # via # -c lock/requirements-dev.txt # sms (pyproject.toml) @@ -720,9 +737,9 @@ typing-extensions==4.12.2 \ # pydantic # pydantic-core # typer -urllib3==2.2.2 \ - --hash=sha256:a448b2f64d686155468037e1ace9f2d2199776e17f0a46610480d311f73e3472 \ - --hash=sha256:dd505485549a7a552833da5e6063639d0d177c04f23bc3864e41e5dc5f612168 +urllib3==2.2.3 \ + --hash=sha256:ca899ca043dcb1bafa3e262d73aa25c465bfb49e0bd9dd5d59f1d0acba2f8fac \ + --hash=sha256:e7d814a81dad81e6caf2ec9fdedb284ecc9c73076b62654547cc64ccdcae26e9 # via # -c lock/requirements-dev.txt # botocore @@ -734,219 +751,221 @@ uvicorn==0.29.0 \ # fastapi # fastapi-cli # ghga-service-commons -uvloop==0.20.0 \ - --hash=sha256:265a99a2ff41a0fd56c19c3838b29bf54d1d177964c300dad388b27e84fd7847 \ - --hash=sha256:2beee18efd33fa6fdb0976e18475a4042cd31c7433c866e8a09ab604c7c22ff2 \ - --hash=sha256:35968fc697b0527a06e134999eef859b4034b37aebca537daeb598b9d45a137b \ - --hash=sha256:36c530d8fa03bfa7085af54a48f2ca16ab74df3ec7108a46ba82fd8b411a2315 \ - --hash=sha256:3a609780e942d43a275a617c0839d85f95c334bad29c4c0918252085113285b5 \ - --hash=sha256:4603ca714a754fc8d9b197e325db25b2ea045385e8a3ad05d3463de725fdf469 \ - --hash=sha256:4b75f2950ddb6feed85336412b9a0c310a2edbcf4cf931aa5cfe29034829676d \ - --hash=sha256:4f44af67bf39af25db4c1ac27e82e9665717f9c26af2369c404be865c8818dcf \ - --hash=sha256:6462c95f48e2d8d4c993a2950cd3d31ab061864d1c226bbf0ee2f1a8f36674b9 \ - --hash=sha256:649c33034979273fa71aa25d0fe120ad1777c551d8c4cd2c0c9851d88fcb13ab \ - --hash=sha256:746242cd703dc2b37f9d8b9f173749c15e9a918ddb021575a0205ec29a38d31e \ - --hash=sha256:77fbc69c287596880ecec2d4c7a62346bef08b6209749bf6ce8c22bbaca0239e \ - --hash=sha256:80dc1b139516be2077b3e57ce1cb65bfed09149e1d175e0478e7a987863b68f0 \ - --hash=sha256:82edbfd3df39fb3d108fc079ebc461330f7c2e33dbd002d146bf7c445ba6e756 \ - --hash=sha256:89e8d33bb88d7263f74dc57d69f0063e06b5a5ce50bb9a6b32f5fcbe655f9e73 \ - --hash=sha256:94707205efbe809dfa3a0d09c08bef1352f5d3d6612a506f10a319933757c006 \ - --hash=sha256:95720bae002ac357202e0d866128eb1ac82545bcf0b549b9abe91b5178d9b541 \ - --hash=sha256:9b04d96188d365151d1af41fa2d23257b674e7ead68cfd61c725a422764062ae \ - --hash=sha256:9d0fba61846f294bce41eb44d60d58136090ea2b5b99efd21cbdf4e21927c56a \ - --hash=sha256:9ebafa0b96c62881d5cafa02d9da2e44c23f9f0cd829f3a32a6aff771449c996 \ - --hash=sha256:a0fac7be202596c7126146660725157d4813aa29a4cc990fe51346f75ff8fde7 \ - --hash=sha256:aea15c78e0d9ad6555ed201344ae36db5c63d428818b4b2a42842b3870127c00 \ - --hash=sha256:b10c2956efcecb981bf9cfb8184d27d5d64b9033f917115a960b83f11bfa0d6b \ - --hash=sha256:b16696f10e59d7580979b420eedf6650010a4a9c3bd8113f24a103dfdb770b10 \ - --hash=sha256:d8c36fdf3e02cec92aed2d44f63565ad1522a499c654f07935c8f9d04db69e95 \ - --hash=sha256:e237f9c1e8a00e7d9ddaa288e535dc337a39bcbf679f290aee9d26df9e72bce9 \ - --hash=sha256:e50289c101495e0d1bb0bfcb4a60adde56e32f4449a67216a1ab2750aa84f037 \ - --hash=sha256:e7d61fe8e8d9335fac1bf8d5d82820b4808dd7a43020c149b63a1ada953d48a6 \ - --hash=sha256:e97152983442b499d7a71e44f29baa75b3b02e65d9c44ba53b10338e98dedb66 \ - --hash=sha256:f0e94b221295b5e69de57a1bd4aeb0b3a29f61be6e1b478bb8a69a73377db7ba \ - --hash=sha256:fee6044b64c965c425b65a4e17719953b96e065c5b7e09b599ff332bb2744bdf +uvloop==0.21.0 \ + --hash=sha256:0878c2640cf341b269b7e128b1a5fed890adc4455513ca710d77d5e93aa6d6a0 \ + --hash=sha256:10d66943def5fcb6e7b37310eb6b5639fd2ccbc38df1177262b0640c3ca68c1f \ + --hash=sha256:10da8046cc4a8f12c91a1c39d1dd1585c41162a15caaef165c2174db9ef18bdc \ + --hash=sha256:17df489689befc72c39a08359efac29bbee8eee5209650d4b9f34df73d22e414 \ + --hash=sha256:183aef7c8730e54c9a3ee3227464daed66e37ba13040bb3f350bc2ddc040f22f \ + --hash=sha256:196274f2adb9689a289ad7d65700d37df0c0930fd8e4e743fa4834e850d7719d \ + --hash=sha256:221f4f2a1f46032b403bf3be628011caf75428ee3cc204a22addf96f586b19fd \ + --hash=sha256:2d1f581393673ce119355d56da84fe1dd9d2bb8b3d13ce792524e1607139feff \ + --hash=sha256:359ec2c888397b9e592a889c4d72ba3d6befba8b2bb01743f72fffbde663b59c \ + --hash=sha256:3bf12b0fda68447806a7ad847bfa591613177275d35b6724b1ee573faa3704e3 \ + --hash=sha256:4509360fcc4c3bd2c70d87573ad472de40c13387f5fda8cb58350a1d7475e58d \ + --hash=sha256:460def4412e473896ef179a1671b40c039c7012184b627898eea5072ef6f017a \ + --hash=sha256:461d9ae6660fbbafedd07559c6a2e57cd553b34b0065b6550685f6653a98c1cb \ + --hash=sha256:46923b0b5ee7fc0020bef24afe7836cb068f5050ca04caf6b487c513dc1a20b2 \ + --hash=sha256:53e420a3afe22cdcf2a0f4846e377d16e718bc70103d7088a4f7623567ba5fb0 \ + --hash=sha256:5ee4d4ef48036ff6e5cfffb09dd192c7a5027153948d85b8da7ff705065bacc6 \ + --hash=sha256:67dd654b8ca23aed0a8e99010b4c34aca62f4b7fce88f39d452ed7622c94845c \ + --hash=sha256:787ae31ad8a2856fc4e7c095341cccc7209bd657d0e71ad0dc2ea83c4a6fa8af \ + --hash=sha256:86975dca1c773a2c9864f4c52c5a55631038e387b47eaf56210f873887b6c8dc \ + --hash=sha256:87c43e0f13022b998eb9b973b5e97200c8b90823454d4bc06ab33829e09fb9bb \ + --hash=sha256:88cb67cdbc0e483da00af0b2c3cdad4b7c61ceb1ee0f33fe00e09c81e3a6cb75 \ + --hash=sha256:8a375441696e2eda1c43c44ccb66e04d61ceeffcd76e4929e527b7fa401b90fb \ + --hash=sha256:a5c39f217ab3c663dc699c04cbd50c13813e31d917642d459fdcec07555cc553 \ + --hash=sha256:b9fb766bb57b7388745d8bcc53a359b116b8a04c83a2288069809d2b3466c37e \ + --hash=sha256:baa0e6291d91649c6ba4ed4b2f982f9fa165b5bbd50a9e203c416a2797bab3c6 \ + --hash=sha256:baa4dcdbd9ae0a372f2167a207cd98c9f9a1ea1188a8a526431eef2f8116cc8d \ + --hash=sha256:bc09f0ff191e61c2d592a752423c767b4ebb2986daa9ed62908e2b1b9a9ae206 \ + --hash=sha256:bd53ecc9a0f3d87ab847503c2e1552b690362e005ab54e8a48ba97da3924c0dc \ + --hash=sha256:bfd55dfcc2a512316e65f16e503e9e450cab148ef11df4e4e679b5e8253a5281 \ + --hash=sha256:c097078b8031190c934ed0ebfee8cc5f9ba9642e6eb88322b9958b649750f72b \ + --hash=sha256:c0f3fa6200b3108919f8bdabb9a7f87f20e7097ea3c543754cabc7d717d95cf8 \ + --hash=sha256:e678ad6fe52af2c58d2ae3c73dc85524ba8abe637f134bf3564ed07f555c5e79 \ + --hash=sha256:ec7e6b09a6fdded42403182ab6b832b71f4edaf7f37a9a0e371a01db5f0cb45f \ + --hash=sha256:f0ce1b49560b1d2d8a2977e3ba4afb2414fb46b86a1b64056bc4ab929efdafbe \ + --hash=sha256:f38b2e090258d051d68a5b14d1da7203a3c3677321cf32a95a6f4db4dd8b6f26 \ + --hash=sha256:f3df876acd7ec037a3d005b3ab85a7e4110422e4d9c1571d4fc89b0fc41b6816 \ + --hash=sha256:f7089d2dc73179ce5ac255bdf37c236a9f914b264825fdaacaded6990a7fb4c2 # via # -c lock/requirements-dev.txt # uvicorn -watchfiles==0.23.0 \ - --hash=sha256:02b7ba9d4557149410747353e7325010d48edcfe9d609a85cb450f17fd50dc3d \ - --hash=sha256:02ff5d7bd066c6a7673b17c8879cd8ee903078d184802a7ee851449c43521bdd \ - --hash=sha256:0e01bcb8d767c58865207a6c2f2792ad763a0fe1119fb0a430f444f5b02a5ea0 \ - --hash=sha256:0eff099a4df36afaa0eea7a913aa64dcf2cbd4e7a4f319a73012210af4d23810 \ - --hash=sha256:109a61763e7318d9f821b878589e71229f97366fa6a5c7720687d367f3ab9eef \ - --hash=sha256:11698bb2ea5e991d10f1f4f83a39a02f91e44e4bd05f01b5c1ec04c9342bf63c \ - --hash=sha256:130a896d53b48a1cecccfa903f37a1d87dbb74295305f865a3e816452f6e49e4 \ - --hash=sha256:1733b9bc2c8098c6bdb0ff7a3d7cb211753fecb7bd99bdd6df995621ee1a574b \ - --hash=sha256:18e2de19801b0eaa4c5292a223effb7cfb43904cb742c5317a0ac686ed604765 \ - --hash=sha256:1cf7f486169986c4b9d34087f08ce56a35126600b6fef3028f19ca16d5889071 \ - --hash=sha256:1d636c8aeb28cdd04a4aa89030c4b48f8b2954d8483e5f989774fa441c0ed57b \ - --hash=sha256:1db691bad0243aed27c8354b12d60e8e266b75216ae99d33e927ff5238d270b5 \ - --hash=sha256:1e5f3ca0ff47940ce0a389457b35d6df601c317c1e1a9615981c474452f98de1 \ - --hash=sha256:1ebaebb53b34690da0936c256c1cdb0914f24fb0e03da76d185806df9328abed \ - --hash=sha256:20b423b58f5fdde704a226b598a2d78165fe29eb5621358fe57ea63f16f165c4 \ - --hash=sha256:2368c5371c17fdcb5a2ea71c5c9d49f9b128821bfee69503cc38eae00feb3220 \ - --hash=sha256:24655e8c1c9c114005c3868a3d432c8aa595a786b8493500071e6a52f3d09217 \ - --hash=sha256:2537ef60596511df79b91613a5bb499b63f46f01a11a81b0a2b0dedf645d0a9c \ - --hash=sha256:296e0b29ab0276ca59d82d2da22cbbdb39a23eed94cca69aed274595fb3dfe42 \ - --hash=sha256:2aec5c29915caf08771d2507da3ac08e8de24a50f746eb1ed295584ba1820330 \ - --hash=sha256:2dddc2487d33e92f8b6222b5fb74ae2cfde5e8e6c44e0248d24ec23befdc5366 \ - --hash=sha256:37fd826dac84c6441615aa3f04077adcc5cac7194a021c9f0d69af20fb9fa788 \ - --hash=sha256:3af1b05361e1cc497bf1be654a664750ae61f5739e4bb094a2be86ec8c6db9b6 \ - --hash=sha256:40cb8fa00028908211eb9f8d47744dca21a4be6766672e1ff3280bee320436f1 \ - --hash=sha256:46f1d8069a95885ca529645cdbb05aea5837d799965676e1b2b1f95a4206313e \ - --hash=sha256:486bda18be5d25ab5d932699ceed918f68eb91f45d018b0343e3502e52866e5e \ - --hash=sha256:48a1b05c0afb2cd2f48c1ed2ae5487b116e34b93b13074ed3c22ad5c743109f0 \ - --hash=sha256:4ccd3011cc7ee2f789af9ebe04745436371d36afe610028921cab9f24bb2987b \ - --hash=sha256:4ea756e425ab2dfc8ef2a0cb87af8aa7ef7dfc6fc46c6f89bcf382121d4fff75 \ - --hash=sha256:524fcb8d59b0dbee2c9b32207084b67b2420f6431ed02c18bd191e6c575f5c48 \ - --hash=sha256:532e1f2c491274d1333a814e4c5c2e8b92345d41b12dc806cf07aaff786beb66 \ - --hash=sha256:556347b0abb4224c5ec688fc58214162e92a500323f50182f994f3ad33385dcb \ - --hash=sha256:62d2b18cb1edaba311fbbfe83fb5e53a858ba37cacb01e69bc20553bb70911b8 \ - --hash=sha256:6991e3a78f642368b8b1b669327eb6751439f9f7eaaa625fae67dd6070ecfa0b \ - --hash=sha256:6a9265cf87a5b70147bfb2fec14770ed5b11a5bb83353f0eee1c25a81af5abfe \ - --hash=sha256:6b1a950ab299a4a78fd6369a97b8763732bfb154fdb433356ec55a5bce9515c1 \ - --hash=sha256:6bb91fa4d0b392f0f7e27c40981e46dda9eb0fbc84162c7fb478fe115944f491 \ - --hash=sha256:6c21a5467f35c61eafb4e394303720893066897fca937bade5b4f5877d350ff8 \ - --hash=sha256:7ca6b71dcc50d320c88fb2d88ecd63924934a8abc1673683a242a7ca7d39e781 \ - --hash=sha256:7cf12ac34c444362f3261fb3ff548f0037ddd4c5bb85f66c4be30d2936beb3c5 \ - --hash=sha256:7f7252f52a09f8fa5435dc82b6af79483118ce6bd51eb74e6269f05ee22a7b9f \ - --hash=sha256:85042ab91814fca99cec4678fc063fb46df4cbb57b4835a1cc2cb7a51e10250e \ - --hash=sha256:857af85d445b9ba9178db95658c219dbd77b71b8264e66836a6eba4fbf49c320 \ - --hash=sha256:87f889f6e58849ddb7c5d2cb19e2e074917ed1c6e3ceca50405775166492cca8 \ - --hash=sha256:8ada449e22198c31fb013ae7e9add887e8d2bd2335401abd3cbc55f8c5083647 \ - --hash=sha256:8e56fbcdd27fce061854ddec99e015dd779cae186eb36b14471fc9ae713b118c \ - --hash=sha256:8f48c917ffd36ff9a5212614c2d0d585fa8b064ca7e66206fb5c095015bc8207 \ - --hash=sha256:9338ade39ff24f8086bb005d16c29f8e9f19e55b18dcb04dfa26fcbc09da497b \ - --hash=sha256:9837edf328b2805346f91209b7e660f65fb0e9ca18b7459d075d58db082bf981 \ - --hash=sha256:9d183e3888ada88185ab17064079c0db8c17e32023f5c278d7bf8014713b1b5b \ - --hash=sha256:9f02a259fcbbb5fcfe7a0805b1097ead5ba7a043e318eef1db59f93067f0b49b \ - --hash=sha256:9f8e6bb5ac007d4a4027b25f09827ed78cbbd5b9700fd6c54429278dacce05d1 \ - --hash=sha256:9ff785af8bacdf0be863ec0c428e3288b817e82f3d0c1d652cd9c6d509020dd0 \ - --hash=sha256:a0b2c25040a3c0ce0e66c7779cc045fdfbbb8d59e5aabfe033000b42fe44b53e \ - --hash=sha256:a753993635eccf1ecb185dedcc69d220dab41804272f45e4aef0a67e790c3eb3 \ - --hash=sha256:a8323daae27ea290ba3350c70c836c0d2b0fb47897fa3b0ca6a5375b952b90d3 \ - --hash=sha256:a8f195338a5a7b50a058522b39517c50238358d9ad8284fd92943643144c0c03 \ - --hash=sha256:a96ac14e184aa86dc43b8a22bb53854760a58b2966c2b41580de938e9bf26ed0 \ - --hash=sha256:aafea64a3ae698695975251f4254df2225e2624185a69534e7fe70581066bc1b \ - --hash=sha256:aba037c1310dd108411d27b3d5815998ef0e83573e47d4219f45753c710f969f \ - --hash=sha256:b1f67312efa3902a8e8496bfa9824d3bec096ff83c4669ea555c6bdd213aa516 \ - --hash=sha256:b4ac73b02ca1824ec0a7351588241fd3953748d3774694aa7ddb5e8e46aef3e3 \ - --hash=sha256:b8d3c5cd327dd6ce0edfc94374fb5883d254fe78a5e9d9dfc237a1897dc73cd1 \ - --hash=sha256:b98732ec893975455708d6fc9a6daab527fc8bbe65be354a3861f8c450a632a4 \ - --hash=sha256:ba31c32f6b4dceeb2be04f717811565159617e28d61a60bb616b6442027fd4b9 \ - --hash=sha256:bd3e2d64500a6cad28bcd710ee6269fbeb2e5320525acd0cfab5f269ade68581 \ - --hash=sha256:bee8ce357a05c20db04f46c22be2d1a2c6a8ed365b325d08af94358e0688eeb4 \ - --hash=sha256:c5e7803a65eb2d563c73230e9d693c6539e3c975ccfe62526cadde69f3fda0cf \ - --hash=sha256:c846884b2e690ba62a51048a097acb6b5cd263d8bd91062cd6137e2880578472 \ - --hash=sha256:d1aa4cc85202956d1a65c88d18c7b687b8319dbe6b1aec8969784ef7a10e7d1a \ - --hash=sha256:d2d42254b189a346249424fb9bb39182a19289a2409051ee432fb2926bad966a \ - --hash=sha256:dccc858372a56080332ea89b78cfb18efb945da858fabeb67f5a44fa0bcb4ebb \ - --hash=sha256:dd41d5c72417b87c00b1b635738f3c283e737d75c5fa5c3e1c60cd03eac3af77 \ - --hash=sha256:e087e8fdf1270d000913c12e6eca44edd02aad3559b3e6b8ef00f0ce76e0636f \ - --hash=sha256:e397b64f7aaf26915bf2ad0f1190f75c855d11eb111cc00f12f97430153c2eab \ - --hash=sha256:e495ed2a7943503766c5d1ff05ae9212dc2ce1c0e30a80d4f0d84889298fa304 \ - --hash=sha256:e75695cc952e825fa3e0684a7f4a302f9128721f13eedd8dbd3af2ba450932b8 \ - --hash=sha256:eb99c954291b2fad0eff98b490aa641e128fbc4a03b11c8a0086de8b7077fb75 \ - --hash=sha256:ecf2be4b9eece4f3da8ba5f244b9e51932ebc441c0867bd6af46a3d97eb068d6 \ - --hash=sha256:ee1f5fcbf5bc33acc0be9dd31130bcba35d6d2302e4eceafafd7d9018c7755ab \ - --hash=sha256:ee7db6e36e7a2c15923072e41ea24d9a0cf39658cb0637ecc9307b09d28827e1 \ - --hash=sha256:efadd40fca3a04063d40c4448c9303ce24dd6151dc162cfae4a2a060232ebdcb \ - --hash=sha256:f18de0f82c62c4197bea5ecf4389288ac755896aac734bd2cc44004c56e4ac47 \ - --hash=sha256:f449afbb971df5c6faeb0a27bca0427d7b600dd8f4a068492faec18023f0dcff \ - --hash=sha256:f46c6f0aec8d02a52d97a583782d9af38c19a29900747eb048af358a9c1d8e5b \ - --hash=sha256:fb02d41c33be667e6135e6686f1bb76104c88a312a18faa0ef0262b5bf7f1a0f \ - --hash=sha256:fd257f98cff9c6cb39eee1a83c7c3183970d8a8d23e8cf4f47d9a21329285cee +watchfiles==0.24.0 \ + --hash=sha256:01550ccf1d0aed6ea375ef259706af76ad009ef5b0203a3a4cce0f6024f9b68a \ + --hash=sha256:01def80eb62bd5db99a798d5e1f5f940ca0a05986dcfae21d833af7a46f7ee22 \ + --hash=sha256:07cdef0c84c03375f4e24642ef8d8178e533596b229d32d2bbd69e5128ede02a \ + --hash=sha256:083dc77dbdeef09fa44bb0f4d1df571d2e12d8a8f985dccde71ac3ac9ac067a0 \ + --hash=sha256:1cf1f6dd7825053f3d98f6d33f6464ebdd9ee95acd74ba2c34e183086900a827 \ + --hash=sha256:21ab23fdc1208086d99ad3f69c231ba265628014d4aed31d4e8746bd59e88cd1 \ + --hash=sha256:2dadf8a8014fde6addfd3c379e6ed1a981c8f0a48292d662e27cabfe4239c83c \ + --hash=sha256:2e28d91ef48eab0afb939fa446d8ebe77e2f7593f5f463fd2bb2b14132f95b6e \ + --hash=sha256:2efec17819b0046dde35d13fb8ac7a3ad877af41ae4640f4109d9154ed30a188 \ + --hash=sha256:30bbd525c3262fd9f4b1865cb8d88e21161366561cd7c9e1194819e0a33ea86b \ + --hash=sha256:316449aefacf40147a9efaf3bd7c9bdd35aaba9ac5d708bd1eb5763c9a02bef5 \ + --hash=sha256:327763da824817b38ad125dcd97595f942d720d32d879f6c4ddf843e3da3fe90 \ + --hash=sha256:32aa53a9a63b7f01ed32e316e354e81e9da0e6267435c7243bf8ae0f10b428ef \ + --hash=sha256:34e19e56d68b0dad5cff62273107cf5d9fbaf9d75c46277aa5d803b3ef8a9e9b \ + --hash=sha256:3770e260b18e7f4e576edca4c0a639f704088602e0bc921c5c2e721e3acb8d15 \ + --hash=sha256:3d2e3ab79a1771c530233cadfd277fcc762656d50836c77abb2e5e72b88e3a48 \ + --hash=sha256:41face41f036fee09eba33a5b53a73e9a43d5cb2c53dad8e61fa6c9f91b5a51e \ + --hash=sha256:43e3e37c15a8b6fe00c1bce2473cfa8eb3484bbeecf3aefbf259227e487a03df \ + --hash=sha256:449f43f49c8ddca87c6b3980c9284cab6bd1f5c9d9a2b00012adaaccd5e7decd \ + --hash=sha256:4933a508d2f78099162da473841c652ad0de892719043d3f07cc83b33dfd9d91 \ + --hash=sha256:49d617df841a63b4445790a254013aea2120357ccacbed00253f9c2b5dc24e2d \ + --hash=sha256:49fb58bcaa343fedc6a9e91f90195b20ccb3135447dc9e4e2570c3a39565853e \ + --hash=sha256:4a7fa2bc0efef3e209a8199fd111b8969fe9db9c711acc46636686331eda7dd4 \ + --hash=sha256:4abf4ad269856618f82dee296ac66b0cd1d71450fc3c98532d93798e73399b7a \ + --hash=sha256:4b8693502d1967b00f2fb82fc1e744df128ba22f530e15b763c8d82baee15370 \ + --hash=sha256:4d28cea3c976499475f5b7a2fec6b3a36208656963c1a856d328aeae056fc5c1 \ + --hash=sha256:5148c2f1ea043db13ce9b0c28456e18ecc8f14f41325aa624314095b6aa2e9ea \ + --hash=sha256:54ca90a9ae6597ae6dc00e7ed0a040ef723f84ec517d3e7ce13e63e4bc82fa04 \ + --hash=sha256:551ec3ee2a3ac9cbcf48a4ec76e42c2ef938a7e905a35b42a1267fa4b1645896 \ + --hash=sha256:5c51749f3e4e269231510da426ce4a44beb98db2dce9097225c338f815b05d4f \ + --hash=sha256:632676574429bee8c26be8af52af20e0c718cc7f5f67f3fb658c71928ccd4f7f \ + --hash=sha256:6509ed3f467b79d95fc62a98229f79b1a60d1b93f101e1c61d10c95a46a84f43 \ + --hash=sha256:6bdcfa3cd6fdbdd1a068a52820f46a815401cbc2cb187dd006cb076675e7b735 \ + --hash=sha256:7138eff8baa883aeaa074359daabb8b6c1e73ffe69d5accdc907d62e50b1c0da \ + --hash=sha256:7211b463695d1e995ca3feb38b69227e46dbd03947172585ecb0588f19b0d87a \ + --hash=sha256:73bde715f940bea845a95247ea3e5eb17769ba1010efdc938ffcb967c634fa61 \ + --hash=sha256:78470906a6be5199524641f538bd2c56bb809cd4bf29a566a75051610bc982c3 \ + --hash=sha256:7ae3e208b31be8ce7f4c2c0034f33406dd24fbce3467f77223d10cd86778471c \ + --hash=sha256:7e4bd963a935aaf40b625c2499f3f4f6bbd0c3776f6d3bc7c853d04824ff1c9f \ + --hash=sha256:82ae557a8c037c42a6ef26c494d0631cacca040934b101d001100ed93d43f361 \ + --hash=sha256:82b2509f08761f29a0fdad35f7e1638b8ab1adfa2666d41b794090361fb8b855 \ + --hash=sha256:8360f7314a070c30e4c976b183d1d8d1585a4a50c5cb603f431cebcbb4f66327 \ + --hash=sha256:85d5f0c7771dcc7a26c7a27145059b6bb0ce06e4e751ed76cdf123d7039b60b5 \ + --hash=sha256:88bcd4d0fe1d8ff43675360a72def210ebad3f3f72cabfeac08d825d2639b4ab \ + --hash=sha256:9301c689051a4857d5b10777da23fafb8e8e921bcf3abe6448a058d27fb67633 \ + --hash=sha256:951088d12d339690a92cef2ec5d3cfd957692834c72ffd570ea76a6790222777 \ + --hash=sha256:95cf3b95ea665ab03f5a54765fa41abf0529dbaf372c3b83d91ad2cfa695779b \ + --hash=sha256:96619302d4374de5e2345b2b622dc481257a99431277662c30f606f3e22f42be \ + --hash=sha256:999928c6434372fde16c8f27143d3e97201160b48a614071261701615a2a156f \ + --hash=sha256:9a60e2bf9dc6afe7f743e7c9b149d1fdd6dbf35153c78fe3a14ae1a9aee3d98b \ + --hash=sha256:9f895d785eb6164678ff4bb5cc60c5996b3ee6df3edb28dcdeba86a13ea0465e \ + --hash=sha256:a2a9891723a735d3e2540651184be6fd5b96880c08ffe1a98bae5017e65b544b \ + --hash=sha256:a974231b4fdd1bb7f62064a0565a6b107d27d21d9acb50c484d2cdba515b9366 \ + --hash=sha256:aa0fd7248cf533c259e59dc593a60973a73e881162b1a2f73360547132742823 \ + --hash=sha256:acbfa31e315a8f14fe33e3542cbcafc55703b8f5dcbb7c1eecd30f141df50db3 \ + --hash=sha256:afb72325b74fa7a428c009c1b8be4b4d7c2afedafb2982827ef2156646df2fe1 \ + --hash=sha256:b3ef2c69c655db63deb96b3c3e587084612f9b1fa983df5e0c3379d41307467f \ + --hash=sha256:b52a65e4ea43c6d149c5f8ddb0bef8d4a1e779b77591a458a893eb416624a418 \ + --hash=sha256:b665caeeda58625c3946ad7308fbd88a086ee51ccb706307e5b1fa91556ac886 \ + --hash=sha256:b74fdffce9dfcf2dc296dec8743e5b0332d15df19ae464f0e249aa871fc1c571 \ + --hash=sha256:b995bfa6bf01a9e09b884077a6d37070464b529d8682d7691c2d3b540d357a0c \ + --hash=sha256:bd82010f8ab451dabe36054a1622870166a67cf3fce894f68895db6f74bbdc94 \ + --hash=sha256:bdcd5538e27f188dd3c804b4a8d5f52a7fc7f87e7fd6b374b8e36a4ca03db428 \ + --hash=sha256:c79d7719d027b7a42817c5d96461a99b6a49979c143839fc37aa5748c322f234 \ + --hash=sha256:cdab9555053399318b953a1fe1f586e945bc8d635ce9d05e617fd9fe3a4687d6 \ + --hash=sha256:ce72dba6a20e39a0c628258b5c308779b8697f7676c254a845715e2a1039b968 \ + --hash=sha256:d337193bbf3e45171c8025e291530fb7548a93c45253897cd764a6a71c937ed9 \ + --hash=sha256:d3dcb774e3568477275cc76554b5a565024b8ba3a0322f77c246bc7111c5bb9c \ + --hash=sha256:d64ba08db72e5dfd5c33be1e1e687d5e4fcce09219e8aee893a4862034081d4e \ + --hash=sha256:d7a2e3b7f5703ffbd500dabdefcbc9eafeff4b9444bbdd5d83d79eedf8428fab \ + --hash=sha256:d831ee0a50946d24a53821819b2327d5751b0c938b12c0653ea5be7dea9c82ec \ + --hash=sha256:d9018153cf57fc302a2a34cb7564870b859ed9a732d16b41a9b5cb2ebed2d444 \ + --hash=sha256:e5171ef898299c657685306d8e1478a45e9303ddcd8ac5fed5bd52ad4ae0b69b \ + --hash=sha256:e94e98c7cb94cfa6e071d401ea3342767f28eb5a06a58fafdc0d2a4974f4f35c \ + --hash=sha256:ec39698c45b11d9694a1b635a70946a5bad066b593af863460a8e600f0dff1ca \ + --hash=sha256:ed9aba6e01ff6f2e8285e5aa4154e2970068fe0fc0998c4380d0e6278222269b \ + --hash=sha256:edf71b01dec9f766fb285b73930f95f730bb0943500ba0566ae234b5c1618c18 \ + --hash=sha256:ee82c98bed9d97cd2f53bdb035e619309a098ea53ce525833e26b93f673bc318 \ + --hash=sha256:f4c96283fca3ee09fb044f02156d9570d156698bc3734252175a38f0e8975f07 \ + --hash=sha256:f7d9b87c4c55e3ea8881dfcbf6d61ea6775fffed1fedffaa60bd047d3c08c430 \ + --hash=sha256:f83df90191d67af5a831da3a33dd7628b02a95450e168785586ed51e6d28943c \ + --hash=sha256:fca9433a45f18b7c779d2bae7beeec4f740d28b788b117a48368d95a3233ed83 \ + --hash=sha256:fd92bbaa2ecdb7864b7600dcdb6f2f1db6e0346ed425fbd01085be04c63f0b05 # via # -c lock/requirements-dev.txt # uvicorn -websockets==13.0 \ - --hash=sha256:02cc9bb1a887dac0e08bf657c5d00aa3fac0d03215d35a599130c2034ae6663a \ - --hash=sha256:038e7a0f1bfafc7bf52915ab3506b7a03d1e06381e9f60440c856e8918138151 \ - --hash=sha256:05c25f7b849702950b6fd0e233989bb73a0d2bc83faa3b7233313ca395205f6d \ - --hash=sha256:06b3186e97bf9a33921fa60734d5ed90f2a9b407cce8d23c7333a0984049ef61 \ - --hash=sha256:06df8306c241c235075d2ae77367038e701e53bc8c1bb4f6644f4f53aa6dedd0 \ - --hash=sha256:0a8f7d65358a25172db00c69bcc7df834155ee24229f560d035758fd6613111a \ - --hash=sha256:1f661a4205741bdc88ac9c2b2ec003c72cee97e4acd156eb733662ff004ba429 \ - --hash=sha256:265e1f0d3f788ce8ef99dca591a1aec5263b26083ca0934467ad9a1d1181067c \ - --hash=sha256:2be1382a4daa61e2f3e2be3b3c86932a8db9d1f85297feb6e9df22f391f94452 \ - --hash=sha256:2e1cf4e1eb84b4fd74a47688e8b0940c89a04ad9f6937afa43d468e71128cd68 \ - --hash=sha256:337837ac788d955728b1ab01876d72b73da59819a3388e1c5e8e05c3999f1afa \ - --hash=sha256:358d37c5c431dd050ffb06b4b075505aae3f4f795d7fff9794e5ed96ce99b998 \ - --hash=sha256:35c2221b539b360203f3f9ad168e527bf16d903e385068ae842c186efb13d0ea \ - --hash=sha256:3670def5d3dfd5af6f6e2b3b243ea8f1f72d8da1ef927322f0703f85c90d9603 \ - --hash=sha256:372f46a0096cfda23c88f7e42349a33f8375e10912f712e6b496d3a9a557290f \ - --hash=sha256:376a43a4fd96725f13450d3d2e98f4f36c3525c562ab53d9a98dd2950dca9a8a \ - --hash=sha256:384129ad0490e06bab2b98c1da9b488acb35bb11e2464c728376c6f55f0d45f3 \ - --hash=sha256:3a20cf14ba7b482c4a1924b5e061729afb89c890ca9ed44ac4127c6c5986e424 \ - --hash=sha256:3e6566e79c8c7cbea75ec450f6e1828945fc5c9a4769ceb1c7b6e22470539712 \ - --hash=sha256:4782ec789f059f888c1e8fdf94383d0e64b531cffebbf26dd55afd53ab487ca4 \ - --hash=sha256:4d70c89e3d3b347a7c4d3c33f8d323f0584c9ceb69b82c2ef8a174ca84ea3d4a \ - --hash=sha256:516062a0a8ef5ecbfa4acbaec14b199fc070577834f9fe3d40800a99f92523ca \ - --hash=sha256:5575031472ca87302aeb2ce2c2349f4c6ea978c86a9d1289bc5d16058ad4c10a \ - --hash=sha256:587245f0704d0bb675f919898d7473e8827a6d578e5a122a21756ca44b811ec8 \ - --hash=sha256:602cbd010d8c21c8475f1798b705bb18567eb189c533ab5ef568bc3033fdf417 \ - --hash=sha256:6058b6be92743358885ad6dcdecb378fde4a4c74d4dd16a089d07580c75a0e80 \ - --hash=sha256:63b702fb31e3f058f946ccdfa551f4d57a06f7729c369e8815eb18643099db37 \ - --hash=sha256:6ad684cb7efce227d756bae3e8484f2e56aa128398753b54245efdfbd1108f2c \ - --hash=sha256:6fd757f313c13c34dae9f126d3ba4cf97175859c719e57c6a614b781c86b617e \ - --hash=sha256:7334752052532c156d28b8eaf3558137e115c7871ea82adff69b6d94a7bee273 \ - --hash=sha256:788bc841d250beccff67a20a5a53a15657a60111ef9c0c0a97fbdd614fae0fe2 \ - --hash=sha256:7d14901fdcf212804970c30ab9ee8f3f0212e620c7ea93079d6534863444fb4e \ - --hash=sha256:7ea9c9c7443a97ea4d84d3e4d42d0e8c4235834edae652993abcd2aff94affd7 \ - --hash=sha256:81a11a1ddd5320429db47c04d35119c3e674d215173d87aaeb06ae80f6e9031f \ - --hash=sha256:851fd0afb3bc0b73f7c5b5858975d42769a5fdde5314f4ef2c106aec63100687 \ - --hash=sha256:85a1f92a02f0b8c1bf02699731a70a8a74402bb3f82bee36e7768b19a8ed9709 \ - --hash=sha256:89d795c1802d99a643bf689b277e8604c14b5af1bc0a31dade2cd7a678087212 \ - --hash=sha256:9202c0010c78fad1041e1c5285232b6508d3633f92825687549540a70e9e5901 \ - --hash=sha256:939a16849d71203628157a5e4a495da63967c744e1e32018e9b9e2689aca64d4 \ - --hash=sha256:93b8c2008f372379fb6e5d2b3f7c9ec32f7b80316543fd3a5ace6610c5cde1b0 \ - --hash=sha256:94c1c02721139fe9940b38d28fb15b4b782981d800d5f40f9966264fbf23dcc8 \ - --hash=sha256:9895df6cd0bfe79d09bcd1dbdc03862846f26fbd93797153de954306620c1d00 \ - --hash=sha256:9cc7f35dcb49a4e32db82a849fcc0714c4d4acc9d2273aded2d61f87d7f660b7 \ - --hash=sha256:9ed02c604349068d46d87ef4c2012c112c791f2bec08671903a6bb2bd9c06784 \ - --hash=sha256:a00e1e587c655749afb5b135d8d3edcfe84ec6db864201e40a882e64168610b3 \ - --hash=sha256:a1ab8f0e0cadc5be5f3f9fa11a663957fecbf483d434762c8dfb8aa44948944a \ - --hash=sha256:a4de299c947a54fca9ce1c5fd4a08eb92ffce91961becb13bd9195f7c6e71b47 \ - --hash=sha256:a7fbf2a8fe7556a8f4e68cb3e736884af7bf93653e79f6219f17ebb75e97d8f0 \ - --hash=sha256:ad4fa707ff9e2ffee019e946257b5300a45137a58f41fbd9a4db8e684ab61528 \ - --hash=sha256:ad818cdac37c0ad4c58e51cb4964eae4f18b43c4a83cb37170b0d90c31bd80cf \ - --hash=sha256:addf0a16e4983280efed272d8cb3b2e05f0051755372461e7d966b80a6554e16 \ - --hash=sha256:ae7a519a56a714f64c3445cabde9fc2fc927e7eae44f413eae187cddd9e54178 \ - --hash=sha256:b32f38bc81170fd56d0482d505b556e52bf9078b36819a8ba52624bd6667e39e \ - --hash=sha256:b5407c34776b9b77bd89a5f95eb0a34aaf91889e3f911c63f13035220eb50107 \ - --hash=sha256:b7bf950234a482b7461afdb2ec99eee3548ec4d53f418c7990bb79c620476602 \ - --hash=sha256:b89849171b590107f6724a7b0790736daead40926ddf47eadf998b4ff51d6414 \ - --hash=sha256:bcea3eb58c09c3a31cc83b45c06d5907f02ddaf10920aaa6443975310f699b95 \ - --hash=sha256:bd4ba86513430513e2aa25a441bb538f6f83734dc368a2c5d18afdd39097aa33 \ - --hash=sha256:bf8eb5dca4f484a60f5327b044e842e0d7f7cdbf02ea6dc4a4f811259f1f1f0b \ - --hash=sha256:c026ee729c4ce55708a14b839ba35086dfae265fc12813b62d34ce33f4980c1c \ - --hash=sha256:c210d1460dc8d326ffdef9703c2f83269b7539a1690ad11ae04162bc1878d33d \ - --hash=sha256:c8feb8e19ef65c9994e652c5b0324abd657bedd0abeb946fb4f5163012c1e730 \ - --hash=sha256:cbac2eb7ce0fac755fb983c9247c4a60c4019bcde4c0e4d167aeb17520cc7ef1 \ - --hash=sha256:cbfe82a07596a044de78bb7a62519e71690c5812c26c5f1d4b877e64e4f46309 \ - --hash=sha256:d3f3d2e20c442b58dbac593cb1e02bc02d149a86056cc4126d977ad902472e3b \ - --hash=sha256:d42a818e634f789350cd8fb413a3f5eec1cf0400a53d02062534c41519f5125c \ - --hash=sha256:d4b83cf7354cbbc058e97b3e545dceb75b8d9cf17fd5a19db419c319ddbaaf7a \ - --hash=sha256:d9726d2c9bd6aed8cb994d89b3910ca0079406edce3670886ec828a73e7bdd53 \ - --hash=sha256:da7e501e59857e8e3e9d10586139dc196b80445a591451ca9998aafba1af5278 \ - --hash=sha256:da7e918d82e7bdfc6f66d31febe1b2e28a1ca3387315f918de26f5e367f61572 \ - --hash=sha256:dbbac01e80aee253d44c4f098ab3cc17c822518519e869b284cfbb8cd16cc9de \ - --hash=sha256:df5c0eff91f61b8205a6c9f7b255ff390cdb77b61c7b41f79ca10afcbb22b6cb \ - --hash=sha256:e07e76c49f39c5b45cbd7362b94f001ae209a3ea4905ae9a09cfd53b3c76373d \ - --hash=sha256:e1e10b3fbed7be4a59831d3a939900e50fcd34d93716e433d4193a4d0d1d335d \ - --hash=sha256:e39d393e0ab5b8bd01717cc26f2922026050188947ff54fe6a49dc489f7750b7 \ - --hash=sha256:e5ba5e9b332267d0f2c33ede390061850f1ac3ee6cd1bdcf4c5ea33ead971966 \ - --hash=sha256:e7a1963302947332c3039e3f66209ec73b1626f8a0191649e0713c391e9f5b0d \ - --hash=sha256:e7fcad070dcd9ad37a09d89a4cbc2a5e3e45080b88977c0da87b3090f9f55ead \ - --hash=sha256:eae368cac85adc4c7dc3b0d5f84ffcca609d658db6447387300478e44db70796 \ - --hash=sha256:ede95125a30602b1691a4b1da88946bf27dae283cf30f22cd2cb8ca4b2e0d119 \ - --hash=sha256:f5737c53eb2c8ed8f64b50d3dafd3c1dae739f78aa495a288421ac1b3de82717 \ - --hash=sha256:f5f9d23fbbf96eefde836d9692670bfc89e2d159f456d499c5efcf6a6281c1af \ - --hash=sha256:f66e00e42f25ca7e91076366303e11c82572ca87cc5aae51e6e9c094f315ab41 \ - --hash=sha256:f9af457ed593e35f467140d8b61d425495b127744a9d65d45a366f8678449a23 \ - --hash=sha256:fa0839f35322f7b038d8adcf679e2698c3a483688cc92e3bd15ee4fb06669e9a \ - --hash=sha256:fd038bc9e2c134847f1e0ce3191797fad110756e690c2fdd9702ed34e7a43abb +websockets==13.1 \ + --hash=sha256:004280a140f220c812e65f36944a9ca92d766b6cc4560be652a0a3883a79ed8a \ + --hash=sha256:035233b7531fb92a76beefcbf479504db8c72eb3bff41da55aecce3a0f729e54 \ + --hash=sha256:149e622dc48c10ccc3d2760e5f36753db9cacf3ad7bc7bbbfd7d9c819e286f23 \ + --hash=sha256:163e7277e1a0bd9fb3c8842a71661ad19c6aa7bb3d6678dc7f89b17fbcc4aeb7 \ + --hash=sha256:18503d2c5f3943e93819238bf20df71982d193f73dcecd26c94514f417f6b135 \ + --hash=sha256:1971e62d2caa443e57588e1d82d15f663b29ff9dfe7446d9964a4b6f12c1e700 \ + --hash=sha256:204e5107f43095012b00f1451374693267adbb832d29966a01ecc4ce1db26faf \ + --hash=sha256:2510c09d8e8df777177ee3d40cd35450dc169a81e747455cc4197e63f7e7bfe5 \ + --hash=sha256:25c35bf84bf7c7369d247f0b8cfa157f989862c49104c5cf85cb5436a641d93e \ + --hash=sha256:2f85cf4f2a1ba8f602298a853cec8526c2ca42a9a4b947ec236eaedb8f2dc80c \ + --hash=sha256:308e20f22c2c77f3f39caca508e765f8725020b84aa963474e18c59accbf4c02 \ + --hash=sha256:325b1ccdbf5e5725fdcb1b0e9ad4d2545056479d0eee392c291c1bf76206435a \ + --hash=sha256:327b74e915cf13c5931334c61e1a41040e365d380f812513a255aa804b183418 \ + --hash=sha256:346bee67a65f189e0e33f520f253d5147ab76ae42493804319b5716e46dddf0f \ + --hash=sha256:38377f8b0cdeee97c552d20cf1865695fcd56aba155ad1b4ca8779a5b6ef4ac3 \ + --hash=sha256:3c78383585f47ccb0fcf186dcb8a43f5438bd7d8f47d69e0b56f71bf431a0a68 \ + --hash=sha256:4059f790b6ae8768471cddb65d3c4fe4792b0ab48e154c9f0a04cefaabcd5978 \ + --hash=sha256:459bf774c754c35dbb487360b12c5727adab887f1622b8aed5755880a21c4a20 \ + --hash=sha256:463e1c6ec853202dd3657f156123d6b4dad0c546ea2e2e38be2b3f7c5b8e7295 \ + --hash=sha256:4676df3fe46956fbb0437d8800cd5f2b6d41143b6e7e842e60554398432cf29b \ + --hash=sha256:485307243237328c022bc908b90e4457d0daa8b5cf4b3723fd3c4a8012fce4c6 \ + --hash=sha256:48a2ef1381632a2f0cb4efeff34efa97901c9fbc118e01951ad7cfc10601a9bb \ + --hash=sha256:4b889dbd1342820cc210ba44307cf75ae5f2f96226c0038094455a96e64fb07a \ + --hash=sha256:586a356928692c1fed0eca68b4d1c2cbbd1ca2acf2ac7e7ebd3b9052582deefa \ + --hash=sha256:58cf7e75dbf7e566088b07e36ea2e3e2bd5676e22216e4cad108d4df4a7402a0 \ + --hash=sha256:5993260f483d05a9737073be197371940c01b257cc45ae3f1d5d7adb371b266a \ + --hash=sha256:5dd6da9bec02735931fccec99d97c29f47cc61f644264eb995ad6c0c27667238 \ + --hash=sha256:5f2e75431f8dc4a47f31565a6e1355fb4f2ecaa99d6b89737527ea917066e26c \ + --hash=sha256:5f9fee94ebafbc3117c30be1844ed01a3b177bb6e39088bc6b2fa1dc15572084 \ + --hash=sha256:61fc0dfcda609cda0fc9fe7977694c0c59cf9d749fbb17f4e9483929e3c48a19 \ + --hash=sha256:624459daabeb310d3815b276c1adef475b3e6804abaf2d9d2c061c319f7f187d \ + --hash=sha256:62d516c325e6540e8a57b94abefc3459d7dab8ce52ac75c96cad5549e187e3a7 \ + --hash=sha256:6548f29b0e401eea2b967b2fdc1c7c7b5ebb3eeb470ed23a54cd45ef078a0db9 \ + --hash=sha256:6d2aad13a200e5934f5a6767492fb07151e1de1d6079c003ab31e1823733ae79 \ + --hash=sha256:6d6855bbe70119872c05107e38fbc7f96b1d8cb047d95c2c50869a46c65a8e96 \ + --hash=sha256:70c5be9f416aa72aab7a2a76c90ae0a4fe2755c1816c153c1a2bcc3333ce4ce6 \ + --hash=sha256:730f42125ccb14602f455155084f978bd9e8e57e89b569b4d7f0f0c17a448ffe \ + --hash=sha256:7a43cfdcddd07f4ca2b1afb459824dd3c6d53a51410636a2c7fc97b9a8cf4842 \ + --hash=sha256:7bd6abf1e070a6b72bfeb71049d6ad286852e285f146682bf30d0296f5fbadfa \ + --hash=sha256:7c1e90228c2f5cdde263253fa5db63e6653f1c00e7ec64108065a0b9713fa1b3 \ + --hash=sha256:7c65ffa900e7cc958cd088b9a9157a8141c991f8c53d11087e6fb7277a03f81d \ + --hash=sha256:80c421e07973a89fbdd93e6f2003c17d20b69010458d3a8e37fb47874bd67d51 \ + --hash=sha256:82d0ba76371769d6a4e56f7e83bb8e81846d17a6190971e38b5de108bde9b0d7 \ + --hash=sha256:83f91d8a9bb404b8c2c41a707ac7f7f75b9442a0a876df295de27251a856ad09 \ + --hash=sha256:87c6e35319b46b99e168eb98472d6c7d8634ee37750d7693656dc766395df096 \ + --hash=sha256:8d23b88b9388ed85c6faf0e74d8dec4f4d3baf3ecf20a65a47b836d56260d4b9 \ + --hash=sha256:9156c45750b37337f7b0b00e6248991a047be4aa44554c9886fe6bdd605aab3b \ + --hash=sha256:91a0fa841646320ec0d3accdff5b757b06e2e5c86ba32af2e0815c96c7a603c5 \ + --hash=sha256:95858ca14a9f6fa8413d29e0a585b31b278388aa775b8a81fa24830123874678 \ + --hash=sha256:95df24ca1e1bd93bbca51d94dd049a984609687cb2fb08a7f2c56ac84e9816ea \ + --hash=sha256:9b37c184f8b976f0c0a231a5f3d6efe10807d41ccbe4488df8c74174805eea7d \ + --hash=sha256:9b6f347deb3dcfbfde1c20baa21c2ac0751afaa73e64e5b693bb2b848efeaa49 \ + --hash=sha256:9d75baf00138f80b48f1eac72ad1535aac0b6461265a0bcad391fc5aba875cfc \ + --hash=sha256:9ef8aa8bdbac47f4968a5d66462a2a0935d044bf35c0e5a8af152d58516dbeb5 \ + --hash=sha256:a11e38ad8922c7961447f35c7b17bffa15de4d17c70abd07bfbe12d6faa3e027 \ + --hash=sha256:a1b54689e38d1279a51d11e3467dd2f3a50f5f2e879012ce8f2d6943f00e83f0 \ + --hash=sha256:a3b3366087c1bc0a2795111edcadddb8b3b59509d5db5d7ea3fdd69f954a8878 \ + --hash=sha256:a569eb1b05d72f9bce2ebd28a1ce2054311b66677fcd46cf36204ad23acead8c \ + --hash=sha256:a7affedeb43a70351bb811dadf49493c9cfd1ed94c9c70095fd177e9cc1541fa \ + --hash=sha256:a9a396a6ad26130cdae92ae10c36af09d9bfe6cafe69670fd3b6da9b07b4044f \ + --hash=sha256:a9ab1e71d3d2e54a0aa646ab6d4eebfaa5f416fe78dfe4da2839525dc5d765c6 \ + --hash=sha256:a9cd1af7e18e5221d2878378fbc287a14cd527fdd5939ed56a18df8a31136bb2 \ + --hash=sha256:a9dcaf8b0cc72a392760bb8755922c03e17a5a54e08cca58e8b74f6902b433cf \ + --hash=sha256:b9d7439d7fab4dce00570bb906875734df13d9faa4b48e261c440a5fec6d9708 \ + --hash=sha256:bcc03c8b72267e97b49149e4863d57c2d77f13fae12066622dc78fe322490fe6 \ + --hash=sha256:c11d4d16e133f6df8916cc5b7e3e96ee4c44c936717d684a94f48f82edb7c92f \ + --hash=sha256:c1dca61c6db1166c48b95198c0b7d9c990b30c756fc2923cc66f68d17dc558fd \ + --hash=sha256:c518e84bb59c2baae725accd355c8dc517b4a3ed8db88b4bc93c78dae2974bf2 \ + --hash=sha256:c7934fd0e920e70468e676fe7f1b7261c1efa0d6c037c6722278ca0228ad9d0d \ + --hash=sha256:c7e72ce6bda6fb9409cc1e8164dd41d7c91466fb599eb047cfda72fe758a34a7 \ + --hash=sha256:c90d6dec6be2c7d03378a574de87af9b1efea77d0c52a8301dd831ece938452f \ + --hash=sha256:ceec59f59d092c5007e815def4ebb80c2de330e9588e101cf8bd94c143ec78a5 \ + --hash=sha256:cf1781ef73c073e6b0f90af841aaf98501f975d306bbf6221683dd594ccc52b6 \ + --hash=sha256:d04f13a1d75cb2b8382bdc16ae6fa58c97337253826dfe136195b7f89f661557 \ + --hash=sha256:d6d300f8ec35c24025ceb9b9019ae9040c1ab2f01cddc2bcc0b518af31c75c14 \ + --hash=sha256:d8dbb1bf0c0a4ae8b40bdc9be7f644e2f3fb4e8a9aca7145bfa510d4a374eeb7 \ + --hash=sha256:de58647e3f9c42f13f90ac7e5f58900c80a39019848c5547bc691693098ae1bd \ + --hash=sha256:deeb929efe52bed518f6eb2ddc00cc496366a14c726005726ad62c2dd9017a3c \ + --hash=sha256:df01aea34b6e9e33572c35cd16bae5a47785e7d5c8cb2b54b2acdb9678315a17 \ + --hash=sha256:e2620453c075abeb0daa949a292e19f56de518988e079c36478bacf9546ced23 \ + --hash=sha256:e4450fc83a3df53dec45922b576e91e94f5578d06436871dce3a6be38e40f5db \ + --hash=sha256:e54affdeb21026329fb0744ad187cf812f7d3c2aa702a5edb562b325191fcab6 \ + --hash=sha256:e9875a0143f07d74dc5e1ded1c4581f0d9f7ab86c78994e2ed9e95050073c94d \ + --hash=sha256:f1c3cf67185543730888b20682fb186fc8d0fa6f07ccc3ef4390831ab4b388d9 \ + --hash=sha256:f48c749857f8fb598fb890a75f540e3221d0976ed0bf879cf3c7eef34151acee \ + --hash=sha256:f779498eeec470295a2b1a5d97aa1bc9814ecd25e1eb637bd9d1c73a327387f6 # via # -c lock/requirements-dev.txt # uvicorn From b9954fb9385b045bfed679d8fdab3771e0c54bed Mon Sep 17 00:00:00 2001 From: TheByronHimes Date: Mon, 28 Oct 2024 10:09:29 +0000 Subject: [PATCH 02/15] Bump version from 1.3.1 -> 1.4.0 Update lock files, openapi, config, readme Add vault config to sms config --- .devcontainer/.dev_config.yaml | 3 + .pyproject_generation/pyproject_custom.toml | 3 +- README.md | 36 +++++- config_schema.json | 27 +++++ example_config.yaml | 3 + lock/requirements-dev.txt | 5 + lock/requirements.txt | 124 ++++++++++++++++++++ openapi.yaml | 55 ++++++++- pyproject.toml | 3 +- src/sms/config.py | 10 ++ tests/fixtures/test_config.yaml | 3 + 11 files changed, 266 insertions(+), 6 deletions(-) diff --git a/.devcontainer/.dev_config.yaml b/.devcontainer/.dev_config.yaml index 2489b35..ea1a7a1 100644 --- a/.devcontainer/.dev_config.yaml +++ b/.devcontainer/.dev_config.yaml @@ -2,6 +2,9 @@ service_instance_id: "1" token_hashes: # plaintext token: 43fadc91-b98f-4925-bd31-1b054b13dc55 - 7ad83b6b9183c91674eec897935bc154ba9ff9704f8be0840e77f476b5062b6e +vault_token: "dev-token" +vault_url: "http://vault:8200" +vault_path: "ekss" db_connection_str: mongodb://mongodb:27017 db_prefix: "test_" db_permissions: diff --git a/.pyproject_generation/pyproject_custom.toml b/.pyproject_generation/pyproject_custom.toml index 0129bb2..4e68283 100644 --- a/.pyproject_generation/pyproject_custom.toml +++ b/.pyproject_generation/pyproject_custom.toml @@ -1,11 +1,12 @@ [project] name = "sms" -version = "1.3.1" +version = "1.4.0" description = "State Management Service - Provides a REST API for basic infrastructure technology state management." dependencies = [ "typer >= 0.12", "ghga-service-commons[api] >= 3.1", "hexkit[mongodb,s3,akafka] >= 3.5", + "hvac>=2", ] [project.urls] diff --git a/README.md b/README.md index a37c7df..9d045f8 100644 --- a/README.md +++ b/README.md @@ -24,13 +24,13 @@ We recommend using the provided Docker container. A pre-build version is available at [docker hub](https://hub.docker.com/repository/docker/ghga/state-management-service): ```bash -docker pull ghga/state-management-service:1.3.1 +docker pull ghga/state-management-service:1.4.0 ``` Or you can build the container yourself from the [`./Dockerfile`](./Dockerfile): ```bash # Execute in the repo's root dir: -docker build -t ghga/state-management-service:1.3.1 . +docker build -t ghga/state-management-service:1.4.0 . ``` For production-ready deployment, we recommend using Kubernetes, however, @@ -38,7 +38,7 @@ for simple use cases, you could execute the service using docker on a single server: ```bash # The entrypoint is preconfigured: -docker run -p 8080:8080 ghga/state-management-service:1.3.1 --help +docker run -p 8080:8080 ghga/state-management-service:1.4.0 --help ``` If you prefer not to use containers, you may install the service from source: @@ -125,6 +125,36 @@ The service requires the following configuration parameters: - **Additional properties**: Refer to *[#/$defs/S3ObjectStorageNodeConfig](#%24defs/S3ObjectStorageNodeConfig)*. +- **`vault_url`** *(string, required)*: URL for the Vault. + + + Examples: + + ```json + "http://vault:8200" + ``` + + +- **`vault_token`** *(string, required)*: Token for the Vault. + + + Examples: + + ```json + "dev-token" + ``` + + +- **`vault_path`** *(string, required)*: Path for the Vault. + + + Examples: + + ```json + "ekss" + ``` + + - **`token_hashes`** *(array, required)*: List of token hashes corresponding to the tokens that can be used to authenticate calls to this service. Hashes are made with SHA-256. - **Items** *(string)* diff --git a/config_schema.json b/config_schema.json index 0d67e43..0f40b75 100644 --- a/config_schema.json +++ b/config_schema.json @@ -188,6 +188,30 @@ "title": "Object Storages", "type": "object" }, + "vault_url": { + "description": "URL for the Vault", + "examples": [ + "http://vault:8200" + ], + "title": "Vault Url", + "type": "string" + }, + "vault_token": { + "description": "Token for the Vault", + "examples": [ + "dev-token" + ], + "title": "Vault Token", + "type": "string" + }, + "vault_path": { + "description": "Path for the Vault", + "examples": [ + "ekss" + ], + "title": "Vault Path", + "type": "string" + }, "token_hashes": { "description": "List of token hashes corresponding to the tokens that can be used to authenticate calls to this service. Hashes are made with SHA-256.", "examples": [ @@ -411,6 +435,9 @@ "service_instance_id", "kafka_servers", "object_storages", + "vault_url", + "vault_token", + "vault_path", "token_hashes", "db_prefix", "db_connection_str" diff --git a/example_config.yaml b/example_config.yaml index 56b976f..02d8bb5 100644 --- a/example_config.yaml +++ b/example_config.yaml @@ -46,4 +46,7 @@ service_instance_id: '1' service_name: sms token_hashes: - 7ad83b6b9183c91674eec897935bc154ba9ff9704f8be0840e77f476b5062b6e +vault_path: ekss +vault_token: dev-token +vault_url: http://vault:8200 workers: 1 diff --git a/lock/requirements-dev.txt b/lock/requirements-dev.txt index 31b17fa..26385f9 100644 --- a/lock/requirements-dev.txt +++ b/lock/requirements-dev.txt @@ -354,6 +354,10 @@ httpx==0.27.2 \ # -r lock/requirements-dev-template.in # fastapi # pytest-httpx +hvac==2.3.0 \ + --hash=sha256:1b85e3320e8642dd82f234db63253cda169a817589e823713dc5fca83119b1e2 \ + --hash=sha256:a3afc5710760b6ee9b3571769df87a0333da45da05a5f9f963e1d3925a84be7d + # via sms (pyproject.toml) identify==2.6.1 \ --hash=sha256:53863bcac7caf8d2ed85bd20312ea5dcfc22226800f6d6881f232d861db5a8f0 \ --hash=sha256:91478c5fb7c3aac5ff7bf9b4344f803843dc586832d5f110d672b19aa1984c98 @@ -806,6 +810,7 @@ requests==2.32.3 \ # via # -r lock/requirements-dev-template.in # docker + # hvac rich==13.9.3 \ --hash=sha256:9836f5096eb2172c9e77df411c1b009bace4193d6a481d534fea75ebba758283 \ --hash=sha256:bc1e01b899537598cf02579d2b9f4a415104d3fc439313a7a2c165d76557a08e diff --git a/lock/requirements.txt b/lock/requirements.txt index 2ad3295..b19c702 100644 --- a/lock/requirements.txt +++ b/lock/requirements.txt @@ -81,6 +81,116 @@ certifi==2024.8.30 \ # -c lock/requirements-dev.txt # httpcore # httpx + # requests +charset-normalizer==3.4.0 \ + --hash=sha256:0099d79bdfcf5c1f0c2c72f91516702ebf8b0b8ddd8905f97a8aecf49712c621 \ + --hash=sha256:0713f3adb9d03d49d365b70b84775d0a0d18e4ab08d12bc46baa6132ba78aaf6 \ + --hash=sha256:07afec21bbbbf8a5cc3651aa96b980afe2526e7f048fdfb7f1014d84acc8b6d8 \ + --hash=sha256:0b309d1747110feb25d7ed6b01afdec269c647d382c857ef4663bbe6ad95a912 \ + --hash=sha256:0d99dd8ff461990f12d6e42c7347fd9ab2532fb70e9621ba520f9e8637161d7c \ + --hash=sha256:0de7b687289d3c1b3e8660d0741874abe7888100efe14bd0f9fd7141bcbda92b \ + --hash=sha256:1110e22af8ca26b90bd6364fe4c763329b0ebf1ee213ba32b68c73de5752323d \ + --hash=sha256:130272c698667a982a5d0e626851ceff662565379baf0ff2cc58067b81d4f11d \ + --hash=sha256:136815f06a3ae311fae551c3df1f998a1ebd01ddd424aa5603a4336997629e95 \ + --hash=sha256:14215b71a762336254351b00ec720a8e85cada43b987da5a042e4ce3e82bd68e \ + --hash=sha256:1db4e7fefefd0f548d73e2e2e041f9df5c59e178b4c72fbac4cc6f535cfb1565 \ + --hash=sha256:1ffd9493de4c922f2a38c2bf62b831dcec90ac673ed1ca182fe11b4d8e9f2a64 \ + --hash=sha256:2006769bd1640bdf4d5641c69a3d63b71b81445473cac5ded39740a226fa88ab \ + --hash=sha256:20587d20f557fe189b7947d8e7ec5afa110ccf72a3128d61a2a387c3313f46be \ + --hash=sha256:223217c3d4f82c3ac5e29032b3f1c2eb0fb591b72161f86d93f5719079dae93e \ + --hash=sha256:27623ba66c183eca01bf9ff833875b459cad267aeeb044477fedac35e19ba907 \ + --hash=sha256:285e96d9d53422efc0d7a17c60e59f37fbf3dfa942073f666db4ac71e8d726d0 \ + --hash=sha256:2de62e8801ddfff069cd5c504ce3bc9672b23266597d4e4f50eda28846c322f2 \ + --hash=sha256:2f6c34da58ea9c1a9515621f4d9ac379871a8f21168ba1b5e09d74250de5ad62 \ + --hash=sha256:309a7de0a0ff3040acaebb35ec45d18db4b28232f21998851cfa709eeff49d62 \ + --hash=sha256:35c404d74c2926d0287fbd63ed5d27eb911eb9e4a3bb2c6d294f3cfd4a9e0c23 \ + --hash=sha256:3710a9751938947e6327ea9f3ea6332a09bf0ba0c09cae9cb1f250bd1f1549bc \ + --hash=sha256:3d59d125ffbd6d552765510e3f31ed75ebac2c7470c7274195b9161a32350284 \ + --hash=sha256:40d3ff7fc90b98c637bda91c89d51264a3dcf210cade3a2c6f838c7268d7a4ca \ + --hash=sha256:425c5f215d0eecee9a56cdb703203dda90423247421bf0d67125add85d0c4455 \ + --hash=sha256:43193c5cda5d612f247172016c4bb71251c784d7a4d9314677186a838ad34858 \ + --hash=sha256:44aeb140295a2f0659e113b31cfe92c9061622cadbc9e2a2f7b8ef6b1e29ef4b \ + --hash=sha256:47334db71978b23ebcf3c0f9f5ee98b8d65992b65c9c4f2d34c2eaf5bcaf0594 \ + --hash=sha256:4796efc4faf6b53a18e3d46343535caed491776a22af773f366534056c4e1fbc \ + --hash=sha256:4a51b48f42d9358460b78725283f04bddaf44a9358197b889657deba38f329db \ + --hash=sha256:4b67fdab07fdd3c10bb21edab3cbfe8cf5696f453afce75d815d9d7223fbe88b \ + --hash=sha256:4ec9dd88a5b71abfc74e9df5ebe7921c35cbb3b641181a531ca65cdb5e8e4dea \ + --hash=sha256:4f9fc98dad6c2eaa32fc3af1417d95b5e3d08aff968df0cd320066def971f9a6 \ + --hash=sha256:54b6a92d009cbe2fb11054ba694bc9e284dad30a26757b1e372a1fdddaf21920 \ + --hash=sha256:55f56e2ebd4e3bc50442fbc0888c9d8c94e4e06a933804e2af3e89e2f9c1c749 \ + --hash=sha256:5726cf76c982532c1863fb64d8c6dd0e4c90b6ece9feb06c9f202417a31f7dd7 \ + --hash=sha256:5d447056e2ca60382d460a604b6302d8db69476fd2015c81e7c35417cfabe4cd \ + --hash=sha256:5ed2e36c3e9b4f21dd9422f6893dec0abf2cca553af509b10cd630f878d3eb99 \ + --hash=sha256:5ff2ed8194587faf56555927b3aa10e6fb69d931e33953943bc4f837dfee2242 \ + --hash=sha256:62f60aebecfc7f4b82e3f639a7d1433a20ec32824db2199a11ad4f5e146ef5ee \ + --hash=sha256:63bc5c4ae26e4bc6be6469943b8253c0fd4e4186c43ad46e713ea61a0ba49129 \ + --hash=sha256:6b40e8d38afe634559e398cc32b1472f376a4099c75fe6299ae607e404c033b2 \ + --hash=sha256:6b493a043635eb376e50eedf7818f2f322eabbaa974e948bd8bdd29eb7ef2a51 \ + --hash=sha256:6dba5d19c4dfab08e58d5b36304b3f92f3bd5d42c1a3fa37b5ba5cdf6dfcbcee \ + --hash=sha256:6fd30dc99682dc2c603c2b315bded2799019cea829f8bf57dc6b61efde6611c8 \ + --hash=sha256:707b82d19e65c9bd28b81dde95249b07bf9f5b90ebe1ef17d9b57473f8a64b7b \ + --hash=sha256:7706f5850360ac01d80c89bcef1640683cc12ed87f42579dab6c5d3ed6888613 \ + --hash=sha256:7782afc9b6b42200f7362858f9e73b1f8316afb276d316336c0ec3bd73312742 \ + --hash=sha256:79983512b108e4a164b9c8d34de3992f76d48cadc9554c9e60b43f308988aabe \ + --hash=sha256:7f683ddc7eedd742e2889d2bfb96d69573fde1d92fcb811979cdb7165bb9c7d3 \ + --hash=sha256:82357d85de703176b5587dbe6ade8ff67f9f69a41c0733cf2425378b49954de5 \ + --hash=sha256:84450ba661fb96e9fd67629b93d2941c871ca86fc38d835d19d4225ff946a631 \ + --hash=sha256:86f4e8cca779080f66ff4f191a685ced73d2f72d50216f7112185dc02b90b9b7 \ + --hash=sha256:8cda06946eac330cbe6598f77bb54e690b4ca93f593dee1568ad22b04f347c15 \ + --hash=sha256:8ce7fd6767a1cc5a92a639b391891bf1c268b03ec7e021c7d6d902285259685c \ + --hash=sha256:8ff4e7cdfdb1ab5698e675ca622e72d58a6fa2a8aa58195de0c0061288e6e3ea \ + --hash=sha256:9289fd5dddcf57bab41d044f1756550f9e7cf0c8e373b8cdf0ce8773dc4bd417 \ + --hash=sha256:92a7e36b000bf022ef3dbb9c46bfe2d52c047d5e3f3343f43204263c5addc250 \ + --hash=sha256:92db3c28b5b2a273346bebb24857fda45601aef6ae1c011c0a997106581e8a88 \ + --hash=sha256:95c3c157765b031331dd4db3c775e58deaee050a3042fcad72cbc4189d7c8dca \ + --hash=sha256:980b4f289d1d90ca5efcf07958d3eb38ed9c0b7676bf2831a54d4f66f9c27dfa \ + --hash=sha256:9ae4ef0b3f6b41bad6366fb0ea4fc1d7ed051528e113a60fa2a65a9abb5b1d99 \ + --hash=sha256:9c98230f5042f4945f957d006edccc2af1e03ed5e37ce7c373f00a5a4daa6149 \ + --hash=sha256:9fa2566ca27d67c86569e8c85297aaf413ffab85a8960500f12ea34ff98e4c41 \ + --hash=sha256:a14969b8691f7998e74663b77b4c36c0337cb1df552da83d5c9004a93afdb574 \ + --hash=sha256:a8aacce6e2e1edcb6ac625fb0f8c3a9570ccc7bfba1f63419b3769ccf6a00ed0 \ + --hash=sha256:a8e538f46104c815be19c975572d74afb53f29650ea2025bbfaef359d2de2f7f \ + --hash=sha256:aa41e526a5d4a9dfcfbab0716c7e8a1b215abd3f3df5a45cf18a12721d31cb5d \ + --hash=sha256:aa693779a8b50cd97570e5a0f343538a8dbd3e496fa5dcb87e29406ad0299654 \ + --hash=sha256:ab22fbd9765e6954bc0bcff24c25ff71dcbfdb185fcdaca49e81bac68fe724d3 \ + --hash=sha256:ab2e5bef076f5a235c3774b4f4028a680432cded7cad37bba0fd90d64b187d19 \ + --hash=sha256:ab973df98fc99ab39080bfb0eb3a925181454d7c3ac8a1e695fddfae696d9e90 \ + --hash=sha256:af73657b7a68211996527dbfeffbb0864e043d270580c5aef06dc4b659a4b578 \ + --hash=sha256:b197e7094f232959f8f20541ead1d9862ac5ebea1d58e9849c1bf979255dfac9 \ + --hash=sha256:b295729485b06c1a0683af02a9e42d2caa9db04a373dc38a6a58cdd1e8abddf1 \ + --hash=sha256:b8831399554b92b72af5932cdbbd4ddc55c55f631bb13ff8fe4e6536a06c5c51 \ + --hash=sha256:b8dcd239c743aa2f9c22ce674a145e0a25cb1566c495928440a181ca1ccf6719 \ + --hash=sha256:bcb4f8ea87d03bc51ad04add8ceaf9b0f085ac045ab4d74e73bbc2dc033f0236 \ + --hash=sha256:bd7af3717683bea4c87acd8c0d3d5b44d56120b26fd3f8a692bdd2d5260c620a \ + --hash=sha256:bf4475b82be41b07cc5e5ff94810e6a01f276e37c2d55571e3fe175e467a1a1c \ + --hash=sha256:c3e446d253bd88f6377260d07c895816ebf33ffffd56c1c792b13bff9c3e1ade \ + --hash=sha256:c57516e58fd17d03ebe67e181a4e4e2ccab1168f8c2976c6a334d4f819fe5944 \ + --hash=sha256:c94057af19bc953643a33581844649a7fdab902624d2eb739738a30e2b3e60fc \ + --hash=sha256:cab5d0b79d987c67f3b9e9c53f54a61360422a5a0bc075f43cab5621d530c3b6 \ + --hash=sha256:ce031db0408e487fd2775d745ce30a7cd2923667cf3b69d48d219f1d8f5ddeb6 \ + --hash=sha256:cee4373f4d3ad28f1ab6290684d8e2ebdb9e7a1b74fdc39e4c211995f77bec27 \ + --hash=sha256:d5b054862739d276e09928de37c79ddeec42a6e1bfc55863be96a36ba22926f6 \ + --hash=sha256:dbe03226baf438ac4fda9e2d0715022fd579cb641c4cf639fa40d53b2fe6f3e2 \ + --hash=sha256:dc15e99b2d8a656f8e666854404f1ba54765871104e50c8e9813af8a7db07f12 \ + --hash=sha256:dcaf7c1524c0542ee2fc82cc8ec337f7a9f7edee2532421ab200d2b920fc97cf \ + --hash=sha256:dd4eda173a9fcccb5f2e2bd2a9f423d180194b1bf17cf59e3269899235b2a114 \ + --hash=sha256:dd9a8bd8900e65504a305bf8ae6fa9fbc66de94178c420791d0293702fce2df7 \ + --hash=sha256:de7376c29d95d6719048c194a9cf1a1b0393fbe8488a22008610b0361d834ecf \ + --hash=sha256:e7fdd52961feb4c96507aa649550ec2a0d527c086d284749b2f582f2d40a2e0d \ + --hash=sha256:e91f541a85298cf35433bf66f3fab2a4a2cff05c127eeca4af174f6d497f0d4b \ + --hash=sha256:e9e3c4c9e1ed40ea53acf11e2a386383c3304212c965773704e4603d589343ed \ + --hash=sha256:ee803480535c44e7f5ad00788526da7d85525cfefaf8acf8ab9a310000be4b03 \ + --hash=sha256:f09cb5a7bbe1ecae6e87901a2eb23e0256bb524a79ccc53eb0b7629fbe7677c4 \ + --hash=sha256:f19c1585933c82098c2a520f8ec1227f20e339e33aca8fa6f956f6691b784e67 \ + --hash=sha256:f1a2f519ae173b5b6a2c9d5fa3116ce16e48b3462c8b96dfdded11055e3d6365 \ + --hash=sha256:f28f891ccd15c514a0981f3b9db9aa23d62fe1a99997512b0491d2ed323d229a \ + --hash=sha256:f3e73a4255342d4eb26ef6df01e3962e73aa29baa3124a8e824c5d3364a65748 \ + --hash=sha256:f606a1881d2663630ea5b8ce2efe2111740df4b687bd78b34a8131baa007f79b \ + --hash=sha256:fe9f97feb71aa9896b81973a7bbada8c49501dc73e58a10fcef6663af95e5079 \ + --hash=sha256:ffc519621dce0c767e96b9c53f09c5d215578e10b02c285809f76509a3931482 + # via + # -c lock/requirements-dev.txt + # requests click==8.1.7 \ --hash=sha256:ae74fb96c20a0277a1d615f1e4d73c8414f5a98db8b799a7931d1582f3390c28 \ --hash=sha256:ca9853ad459e787e2192211578cc907e7594e294c7ccc834310722b41b9ca6de @@ -192,6 +302,12 @@ httpx==0.27.2 \ # via # -c lock/requirements-dev.txt # fastapi +hvac==2.3.0 \ + --hash=sha256:1b85e3320e8642dd82f234db63253cda169a817589e823713dc5fca83119b1e2 \ + --hash=sha256:a3afc5710760b6ee9b3571769df87a0333da45da05a5f9f963e1d3925a84be7d + # via + # -c lock/requirements-dev.txt + # sms (pyproject.toml) idna==3.10 \ --hash=sha256:12f65c9b470abda6dc35cf8e63cc574b1c52b11df2c86030af0ac09b01b13ea9 \ --hash=sha256:946d195a0d259cbba61165e88e65941f16e9b36ea6ddb97f00452bae8b1287d3 @@ -200,6 +316,7 @@ idna==3.10 \ # anyio # email-validator # httpx + # requests jinja2==3.1.4 \ --hash=sha256:4a3aee7acbbe7303aede8e9648d13b8bf88a429282aa6122a993f0ac800cb369 \ --hash=sha256:bc5dd2abb727a5319567b7a813e6a2e7318c39f4f487cfe6c89c6f9c7d25197d @@ -575,6 +692,12 @@ referencing==0.35.1 \ # -c lock/requirements-dev.txt # jsonschema # jsonschema-specifications +requests==2.32.3 \ + --hash=sha256:55365417734eb18255590a9ff9eb97e9e1da868d4ccd6402399eaf68af20a760 \ + --hash=sha256:70761cfe03c773ceb22aa2f671b4757976145175cdfca038c02654d061d6dcc6 + # via + # -c lock/requirements-dev.txt + # hvac rich==13.9.3 \ --hash=sha256:9836f5096eb2172c9e77df411c1b009bace4193d6a481d534fea75ebba758283 \ --hash=sha256:bc1e01b899537598cf02579d2b9f4a415104d3fc439313a7a2c165d76557a08e @@ -743,6 +866,7 @@ urllib3==2.2.3 \ # via # -c lock/requirements-dev.txt # botocore + # requests uvicorn==0.29.0 \ --hash=sha256:2c2aac7ff4f4365c206fd773a39bf4ebd1047c238f8b8268ad996829323473de \ --hash=sha256:6a69214c0b6a087462412670b3ef21224fa48cae0e452b5883e8e8bdfdd11dd0 diff --git a/openapi.yaml b/openapi.yaml index 0814bae..dd140dd 100644 --- a/openapi.yaml +++ b/openapi.yaml @@ -57,7 +57,7 @@ components: info: description: A service for basic infrastructure technology state management. title: State Management Service - version: 1.3.1 + version: 1.4.0 openapi: 3.1.0 paths: /documents/permissions: @@ -383,5 +383,58 @@ paths: tags: - StateManagementService - sms-s3 + /secrets/: + delete: + description: If secrets_to_delete is omitted, all secrets are deleted. If `secrets_to_delete` + is provided, only the secrets with the matching IDs are deleted. If a provided + secret does not exist, it is ignored. + operationId: delete_secrets + parameters: + - description: List of secrets to delete. + in: query + name: secrets_to_delete + required: false + schema: + anyOf: + - items: + type: string + type: array + - type: 'null' + description: List of secrets to delete. + title: Secrets To Delete + responses: + '204': + description: Successful Response + '422': + content: + application/json: + schema: + $ref: '#/components/schemas/HTTPValidationError' + description: Validation Error + security: + - HTTPBearer: [] + summary: Delete one or more secrets from the vault + tags: + - StateManagementService + - sms-vault + get: + description: Returns a list of secrets in the vault + operationId: get_secrets + responses: + '200': + content: + application/json: + schema: + items: + type: string + title: Response Get Secrets + type: array + description: Successful Response + security: + - HTTPBearer: [] + summary: Returns a list of secrets in the vault + tags: + - StateManagementService + - sms-vault tags: - name: StateManagementService diff --git a/pyproject.toml b/pyproject.toml index e1ad8fd..fe00413 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -21,12 +21,13 @@ classifiers = [ "Intended Audience :: Developers", ] name = "sms" -version = "1.3.1" +version = "1.4.0" description = "State Management Service - Provides a REST API for basic infrastructure technology state management." dependencies = [ "typer >= 0.12", "ghga-service-commons[api] >= 3.1", "hexkit[mongodb,s3,akafka] >= 3.5", + "hvac>=2", ] [project.license] diff --git a/src/sms/config.py b/src/sms/config.py index 55eaf2c..d0da4d2 100644 --- a/src/sms/config.py +++ b/src/sms/config.py @@ -32,6 +32,16 @@ class SmsConfig(BaseSettings): """Configuration specific to the SMS.""" + vault_url: str = Field( + default=..., description="URL for the Vault", examples=["http://vault:8200"] + ) + vault_token: str = Field( + default=..., description="Token for the Vault", examples=["dev-token"] + ) + vault_path: str = Field( + default=..., description="Path for the Vault", examples=["ekss"] + ) + token_hashes: list[str] = Field( default=..., description="List of token hashes corresponding to the tokens that can be used " diff --git a/tests/fixtures/test_config.yaml b/tests/fixtures/test_config.yaml index 8a528af..80d9d15 100644 --- a/tests/fixtures/test_config.yaml +++ b/tests/fixtures/test_config.yaml @@ -2,6 +2,9 @@ service_instance_id: "1" token_hashes: # plaintext token: 43fadc91-b98f-4925-bd31-1b054b13dc55 - 7ad83b6b9183c91674eec897935bc154ba9ff9704f8be0840e77f476b5062b6e +vault_token: "dev-token" +vault_url: "http://vault:8200" +vault_path: "ekss" db_connection_str: mongodb://mongodb:27017 db_prefix: "test_" db_permissions: From d0507c05aa72b70e47448e58ff6106395b1488c1 Mon Sep 17 00:00:00 2001 From: TheByronHimes Date: Mon, 28 Oct 2024 10:09:54 +0000 Subject: [PATCH 03/15] Add secrets handler to sms --- src/sms/adapters/inbound/fastapi_/dummies.py | 3 + .../inbound/fastapi_/routers/secrets.py | 72 +++++++++++++++++ src/sms/adapters/inbound/fastapi_/routes.py | 2 + src/sms/core/secrets_handler.py | 81 +++++++++++++++++++ src/sms/inject.py | 10 +++ src/sms/ports/inbound/secrets_handler.py | 50 ++++++++++++ 6 files changed, 218 insertions(+) create mode 100644 src/sms/adapters/inbound/fastapi_/routers/secrets.py create mode 100644 src/sms/core/secrets_handler.py create mode 100644 src/sms/ports/inbound/secrets_handler.py diff --git a/src/sms/adapters/inbound/fastapi_/dummies.py b/src/sms/adapters/inbound/fastapi_/dummies.py index f5bfb65..f049c39 100644 --- a/src/sms/adapters/inbound/fastapi_/dummies.py +++ b/src/sms/adapters/inbound/fastapi_/dummies.py @@ -25,13 +25,16 @@ from sms.ports.inbound.docs_handler import DocsHandlerPort from sms.ports.inbound.events_handler import EventsHandlerPort from sms.ports.inbound.objects_handler import ObjectsHandlerPort +from sms.ports.inbound.secrets_handler import SecretsHandlerPort config_dummy = DependencyDummy("config_dummy") docs_handler_port = DependencyDummy("docs_handler_port") objects_handler_port = DependencyDummy("objects_handler_port") events_handler_port = DependencyDummy("events_handler_port") +secrets_handler_port = DependencyDummy("secrets_handler_port") ConfigDummy = Annotated[Config, Depends(config_dummy)] DocsHandlerPortDummy = Annotated[DocsHandlerPort, Depends(docs_handler_port)] ObjectsHandlerPortDummy = Annotated[ObjectsHandlerPort, Depends(objects_handler_port)] EventsHandlerPortDummy = Annotated[EventsHandlerPort, Depends(events_handler_port)] +SecretsHandlerPortDummy = Annotated[SecretsHandlerPort, Depends(secrets_handler_port)] diff --git a/src/sms/adapters/inbound/fastapi_/routers/secrets.py b/src/sms/adapters/inbound/fastapi_/routers/secrets.py new file mode 100644 index 0000000..74893e7 --- /dev/null +++ b/src/sms/adapters/inbound/fastapi_/routers/secrets.py @@ -0,0 +1,72 @@ +# Copyright 2021 - 2024 Universität Tübingen, DKFZ, EMBL, and Universität zu Köln +# for the German Human Genome-Phenome Archive (GHGA) +# +# 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. + +"""FastAPI routes for HashiCorp Vault state management.""" + +from typing import Annotated + +from fastapi import APIRouter, HTTPException, Query, status + +from sms.adapters.inbound.fastapi_ import dummies +from sms.adapters.inbound.fastapi_.http_authorization import ( + TokenAuthContext, + require_token, +) + +secrets_router = APIRouter() + + +@secrets_router.get( + "/", + operation_id="get_secrets", + summary="Returns a list of secrets in the vault", + status_code=status.HTTP_200_OK, + response_model=list[str], +) +async def get_secrets( + secrets_handler: dummies.SecretsHandlerPortDummy, + _token: Annotated[TokenAuthContext, require_token], +): + """Returns a list of secrets in the vault""" + try: + return secrets_handler.get_secrets() + except secrets_handler.SecretRetrievalError as exc: + raise HTTPException(status_code=status.HTTP_500_INTERNAL_SERVER_ERROR) from exc + + +@secrets_router.delete( + "/", + operation_id="delete_secrets", + summary="Delete one or more secrets from the vault", + description=( + "If secrets_to_delete is omitted, all secrets are deleted. If" + + " `secrets_to_delete` is provided, only the secrets with the matching IDs are" + + " deleted. If a provided secret does not exist, it is ignored." + ), + status_code=status.HTTP_204_NO_CONTENT, +) +async def delete_secrets( + secrets_handler: dummies.SecretsHandlerPortDummy, + _token: Annotated[TokenAuthContext, require_token], + secrets_to_delete: list[str] | None = Query( + default=None, + description="List of secrets to delete.", + ), +): + """Delete one or more secrets from the vault""" + try: + secrets_handler.delete_secrets(secrets=secrets_to_delete) + except secrets_handler.SecretRetrievalError as exc: + raise HTTPException(status_code=status.HTTP_500_INTERNAL_SERVER_ERROR) from exc diff --git a/src/sms/adapters/inbound/fastapi_/routes.py b/src/sms/adapters/inbound/fastapi_/routes.py index b540dc3..5e94415 100644 --- a/src/sms/adapters/inbound/fastapi_/routes.py +++ b/src/sms/adapters/inbound/fastapi_/routes.py @@ -19,12 +19,14 @@ from sms.adapters.inbound.fastapi_.routers.documents import mongodb_router from sms.adapters.inbound.fastapi_.routers.events import kafka_router from sms.adapters.inbound.fastapi_.routers.objects import s3_router +from sms.adapters.inbound.fastapi_.routers.secrets import secrets_router router = APIRouter(tags=["StateManagementService"]) router.include_router(mongodb_router, prefix="/documents", tags=["sms-mongodb"]) router.include_router(s3_router, prefix="/objects", tags=["sms-s3"]) router.include_router(kafka_router, prefix="/events", tags=["sms-kafka"]) +router.include_router(secrets_router, prefix="/secrets", tags=["sms-vault"]) @router.get( diff --git a/src/sms/core/secrets_handler.py b/src/sms/core/secrets_handler.py new file mode 100644 index 0000000..576b54d --- /dev/null +++ b/src/sms/core/secrets_handler.py @@ -0,0 +1,81 @@ +# Copyright 2021 - 2024 Universität Tübingen, DKFZ, EMBL, and Universität zu Köln +# for the German Human Genome-Phenome Archive (GHGA) +# +# 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. +"""Implementation of the SecretsHandlerPort""" + +import logging + +from hvac import Client as HvacClient +from hvac.exceptions import InvalidPath + +from sms.config import Config +from sms.ports.inbound.secrets_handler import SecretsHandlerPort + +log = logging.getLogger(__name__) + + +class SecretsHandler(SecretsHandlerPort): + """Adapter wrapping hvac.Client""" + + def __init__(self, config: Config): + """Initialized approle based client and login""" + self._config = config + + @property + def client(self) -> HvacClient: + """Return an instance of a vault client""" + return HvacClient(self._config.vault_url, self._config.vault_token) + + def get_secrets(self) -> list[str]: + """Return the IDs of all secrets in the vault. + + Raises + - `SecreteRetrievalError`: If the path is invalid or no secrets exist. + """ + try: + secrets = self.client.secrets.kv.v2.list_secrets( + path=self._config.vault_path + ) + secret_ids = secrets["data"]["keys"] + return secret_ids + except InvalidPath as exc: + msg = ( + "Invalid path error when fetching secrets. The path might be invalid," + + " or no secrets may exist." + ) + retrieval_error = self.SecretRetrievalError(msg) + log.error(retrieval_error, exc) + raise retrieval_error from exc + + def delete_secrets(self, secrets: list[str] | None = None): + """Delete the secrets from the vault. + + If no secrets are provided, all secrets in the vault are deleted. + + Raises + - `SecreteRetrievalError`: If the path is invalid or no secrets exist. This will + only occur if the `secrets` parameter is omitted. + """ + secrets = secrets or self.get_secrets() + + if not secrets: + log.info("No secrets to delete") + return + log.info(f"Deleting secrets: {secrets}") + + for secret in secrets: + self.client.secrets.kv.v2.delete_metadata_and_all_versions( + path=f"{self._config.vault_path}/{secret}" + ) + log.debug(f"Deleted secret with id '{secret}'") diff --git a/src/sms/inject.py b/src/sms/inject.py index fa285e4..8dac9d1 100644 --- a/src/sms/inject.py +++ b/src/sms/inject.py @@ -27,9 +27,11 @@ from sms.core.docs_handler import DocsHandler from sms.core.events_handler import EventsHandler from sms.core.objects_handler import ObjectsHandler, S3ObjectStorages +from sms.core.secrets_handler import SecretsHandler from sms.ports.inbound.docs_handler import DocsHandlerPort from sms.ports.inbound.events_handler import EventsHandlerPort from sms.ports.inbound.objects_handler import ObjectsHandlerPort +from sms.ports.inbound.secrets_handler import SecretsHandlerPort @asynccontextmanager @@ -77,6 +79,7 @@ async def prepare_rest_app( docs_handler_override: DocsHandlerPort | None = None, objects_handler_override: ObjectsHandlerPort | None = None, events_handler_override: EventsHandlerPort | None = None, + secrets_handler_override: SecretsHandlerPort | None = None, ) -> AsyncGenerator[FastAPI, None]: """Construct and initialize a REST API app along with all its dependencies. By default, the core dependencies are automatically prepared but you can also @@ -96,6 +99,13 @@ async def prepare_rest_app( ) app.dependency_overrides[dummies.events_handler_port] = lambda: events_handler + secrets_handler = ( + secrets_handler_override + if secrets_handler_override + else SecretsHandler(config=config) + ) + app.dependency_overrides[dummies.secrets_handler_port] = lambda: secrets_handler + async with prepare_docs_handler_with_override( config=config, docs_handler_override=docs_handler_override ) as docs_handler: diff --git a/src/sms/ports/inbound/secrets_handler.py b/src/sms/ports/inbound/secrets_handler.py new file mode 100644 index 0000000..09feaee --- /dev/null +++ b/src/sms/ports/inbound/secrets_handler.py @@ -0,0 +1,50 @@ +# Copyright 2021 - 2024 Universität Tübingen, DKFZ, EMBL, and Universität zu Köln +# for the German Human Genome-Phenome Archive (GHGA) +# +# 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. +"""Defines the API of a class that handles requests to interact with a Vault.""" + +import logging +from abc import ABC, abstractmethod + +log = logging.getLogger(__name__) + + +class VaultException(RuntimeError): + """Baseclass for for errors encountered when interacting with HashiCorp Vault""" + + +class SecretsHandlerPort(ABC): + """A class to interact with a HashiCorp Vault.""" + + class SecretRetrievalError(VaultException): + """Wrapper for errors encountered on secret retrieval""" + + @abstractmethod + def get_secrets(self) -> list[str]: + """Return the IDs of all secrets in the vault. + + Raises + - `SecreteRetrievalError`: If the path is invalid or no secrets exist. + """ + + @abstractmethod + def delete_secrets(self, secrets: list[str] | None = None): + """Delete the secrets from the vault. + + If no secrets are provided, all secrets in the vault are deleted. + + Raises + - `SecreteRetrievalError`: If the path is invalid or no secrets exist. This will + only occur if the `secrets` parameter is omitted. + """ From d91605fe6f9990a3cd417b3e29f8cff615b05662 Mon Sep 17 00:00:00 2001 From: TheByronHimes Date: Mon, 28 Oct 2024 10:11:17 +0000 Subject: [PATCH 04/15] Add unit tests for sms vault --- tests/fixtures/dummies.py | 36 +++++++ tests/fixtures/utils.py | 11 ++- tests/unit/secrets/__init__.py | 15 +++ tests/unit/secrets/test_rest_secrets.py | 125 ++++++++++++++++++++++++ 4 files changed, 185 insertions(+), 2 deletions(-) create mode 100644 tests/unit/secrets/__init__.py create mode 100644 tests/unit/secrets/test_rest_secrets.py diff --git a/tests/fixtures/dummies.py b/tests/fixtures/dummies.py index ac84c5e..6ace976 100644 --- a/tests/fixtures/dummies.py +++ b/tests/fixtures/dummies.py @@ -21,6 +21,42 @@ from sms.models import Criteria, UpsertionDetails from sms.ports.inbound.docs_handler import DocsHandlerPort from sms.ports.inbound.objects_handler import ObjectsHandlerPort, S3ObjectStoragesPort +from sms.ports.inbound.secrets_handler import SecretsHandlerPort + + +class DummySecretsHandler(SecretsHandlerPort): + """Dummy SecretsHandler implementation for testing. + + It can be set to fail when `get_secrets` is called to mimic an error. + """ + + def __init__( + self, secrets: list[str] | None = None, fail_on_get_secrets: bool = False + ): + self.secrets = secrets if secrets else [] + self.fail_on_get_secrets = fail_on_get_secrets + + def get_secrets(self) -> list[str]: + """Get all secrets currently stored. + + If `fail_on_get_secrets` is set, it will raise a `SecretRetrievalError`. + """ + if self.fail_on_get_secrets: + raise self.SecretRetrievalError() + return self.secrets + + def delete_secrets(self, secrets: list[str] | None = None) -> None: + """Delete stored secrets with the matching IDs. + + If no secrets are provided, all secrets are deleted. + If `secrets` is provided, only the secrets with the matching IDs are deleted. + If a provided secret does not exist, it is ignored. + If `fail_on_get_secrets` is set and no secrets are specified, a + `SecretRetrievalError` will be raised by the call to `get_secrets()`. + """ + self.recent = secrets + secrets_to_delete = secrets or self.get_secrets() + self.secrets = [s for s in self.secrets if s not in secrets_to_delete] @dataclass diff --git a/tests/fixtures/utils.py b/tests/fixtures/utils.py index 02500bd..3ba9206 100644 --- a/tests/fixtures/utils.py +++ b/tests/fixtures/utils.py @@ -26,6 +26,7 @@ from sms.ports.inbound.docs_handler import DocsHandlerPort from sms.ports.inbound.events_handler import EventsHandlerPort from sms.ports.inbound.objects_handler import ObjectsHandlerPort +from sms.ports.inbound.secrets_handler import SecretsHandlerPort BASE_DIR = Path(__file__).parent.resolve() @@ -39,6 +40,7 @@ async def get_rest_client( docs_handler_override: DocsHandlerPort | None = None, objects_handler_override: ObjectsHandlerPort | None = None, events_handler_override: EventsHandlerPort | None = None, + secrets_handler_override: SecretsHandlerPort | None = None, ): """Prepare a REST API client for testing.""" async with prepare_rest_app( @@ -46,6 +48,7 @@ async def get_rest_client( docs_handler_override=docs_handler_override, objects_handler_override=objects_handler_override, events_handler_override=events_handler_override, + secrets_handler_override=secrets_handler_override, ) as app: async with AsyncTestClient(app) as client: yield client @@ -58,17 +61,21 @@ async def get_rest_client_with_mocks( docs_handler_override: DocsHandlerPort | None = None, objects_handler_override: ObjectsHandlerPort | None = None, events_handler_override: EventsHandlerPort | None = None, + secrets_handler_override: SecretsHandlerPort | None = None, ): - """Prepare a REST client with the dependencies mocked by default, negating the need - to mock unused dependencies in each test. + """Prepare a REST client with the dependencies mocked by default + + This negates the need to explicitly mock unused dependencies in each test. """ docs_handler = docs_handler_override or AsyncMock() objects_handler = objects_handler_override or AsyncMock() events_handler = events_handler_override or AsyncMock() + secrets_handler = secrets_handler_override or AsyncMock() async with get_rest_client( config, docs_handler_override=docs_handler, objects_handler_override=objects_handler, events_handler_override=events_handler, + secrets_handler_override=secrets_handler, ) as client: yield client diff --git a/tests/unit/secrets/__init__.py b/tests/unit/secrets/__init__.py new file mode 100644 index 0000000..ef56c94 --- /dev/null +++ b/tests/unit/secrets/__init__.py @@ -0,0 +1,15 @@ +# Copyright 2021 - 2024 Universität Tübingen, DKFZ, EMBL, and Universität zu Köln +# for the German Human Genome-Phenome Archive (GHGA) +# +# 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. +"""Unit tests for the Vault-related parts of the SMS.""" diff --git a/tests/unit/secrets/test_rest_secrets.py b/tests/unit/secrets/test_rest_secrets.py new file mode 100644 index 0000000..d2b8450 --- /dev/null +++ b/tests/unit/secrets/test_rest_secrets.py @@ -0,0 +1,125 @@ +# Copyright 2021 - 2024 Universität Tübingen, DKFZ, EMBL, and Universität zu Köln +# for the German Human Genome-Phenome Archive (GHGA) +# +# 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. +"""Unit tests for the Vault part of the SMS REST API.""" + +from typing import Any + +import pytest + +from tests.fixtures.config import DEFAULT_TEST_CONFIG +from tests.fixtures.dummies import DummySecretsHandler +from tests.fixtures.utils import VALID_BEARER_TOKEN, get_rest_client_with_mocks + +pytestmark = pytest.mark.asyncio() + +TEST_URL = "/secrets/" +HEADERS: dict[str, Any] = {"Authorization": VALID_BEARER_TOKEN} + + +@pytest.mark.parametrize( + "secrets", + [ + [], + ["secret1"], + ["secret1", "secret2"], + ], + ids=[ + "EmptyVault", + "OneSecret", + "TwoSecrets", + ], +) +async def test_get_secrets(secrets: list[str]): + """Test the GET secrets endpoint without errors.""" + secrets_handler = DummySecretsHandler(secrets=secrets) + async with get_rest_client_with_mocks( + config=DEFAULT_TEST_CONFIG, secrets_handler_override=secrets_handler + ) as client: + response = await client.get(TEST_URL, headers=HEADERS) + + assert response.status_code == 200 + assert response.json() == secrets + + +async def test_get_secrets_error(): + """Test the GET secrets endpoint with an error.""" + secrets_handler = DummySecretsHandler(fail_on_get_secrets=True) + async with get_rest_client_with_mocks( + config=DEFAULT_TEST_CONFIG, secrets_handler_override=secrets_handler + ) as client: + response = await client.get(TEST_URL, headers=HEADERS) + + assert response.status_code == 500 + + +@pytest.mark.parametrize( + "secrets_to_delete", + [None, [], ["secret1"], ["secret1", "secret2"]], + ids=[ + "DeleteArgNotProvided", + "DeleteEmptyList", + "DeleteSecret1", + "DeleteSecret1AndSecret2", + ], +) +@pytest.mark.parametrize( + "stored_secrets", + [ + [], + ["secret1", "secret2", "secret3"], + ], + ids=["VaultIsEmpty", "VaultHasThreeSecrets"], +) +async def test_delete_secrets( + stored_secrets: list[str], secrets_to_delete: list[str] | None +): + """Test the DELETE secrets endpoint without errors.""" + secrets_handler = DummySecretsHandler(secrets=stored_secrets) + async with get_rest_client_with_mocks( + config=DEFAULT_TEST_CONFIG, secrets_handler_override=secrets_handler + ) as client: + if secrets_to_delete is None: + response = await client.delete(TEST_URL, headers=HEADERS) + else: + response = await client.delete( + TEST_URL, + headers=HEADERS, + params={"secrets_to_delete": secrets_to_delete}, + ) + + assert response.status_code == 204 + + expected_remaining_secrets = ( + [s for s in stored_secrets if s not in secrets_to_delete] + if secrets_to_delete + else [] + ) + + assert secrets_handler.secrets == expected_remaining_secrets, secrets_handler.recent + + +async def test_delete_secrets_error(): + """Test the DELETE secrets endpoint with an error. + + This is triggered by setting the `fail_on_get_secrets` flag to True and + not providing any secrets to delete. + """ + secrets_handler = DummySecretsHandler(fail_on_get_secrets=True) + async with get_rest_client_with_mocks( + config=DEFAULT_TEST_CONFIG, secrets_handler_override=secrets_handler + ) as client: + response = await client.delete(TEST_URL, headers=HEADERS) + + assert response.status_code == 500 From 416382969d2912c5c5a711f5511f18c9860911d5 Mon Sep 17 00:00:00 2001 From: TheByronHimes Date: Mon, 28 Oct 2024 13:51:05 +0000 Subject: [PATCH 05/15] Log InvalidPath error but don't re-raise Remove custom errors -- are not used --- .../inbound/fastapi_/routers/secrets.py | 4 ++-- src/sms/core/secrets_handler.py | 17 ++++------------- src/sms/ports/inbound/secrets_handler.py | 17 +---------------- 3 files changed, 7 insertions(+), 31 deletions(-) diff --git a/src/sms/adapters/inbound/fastapi_/routers/secrets.py b/src/sms/adapters/inbound/fastapi_/routers/secrets.py index 74893e7..f57c6de 100644 --- a/src/sms/adapters/inbound/fastapi_/routers/secrets.py +++ b/src/sms/adapters/inbound/fastapi_/routers/secrets.py @@ -42,7 +42,7 @@ async def get_secrets( """Returns a list of secrets in the vault""" try: return secrets_handler.get_secrets() - except secrets_handler.SecretRetrievalError as exc: + except Exception as exc: raise HTTPException(status_code=status.HTTP_500_INTERNAL_SERVER_ERROR) from exc @@ -68,5 +68,5 @@ async def delete_secrets( """Delete one or more secrets from the vault""" try: secrets_handler.delete_secrets(secrets=secrets_to_delete) - except secrets_handler.SecretRetrievalError as exc: + except Exception as exc: raise HTTPException(status_code=status.HTTP_500_INTERNAL_SERVER_ERROR) from exc diff --git a/src/sms/core/secrets_handler.py b/src/sms/core/secrets_handler.py index 576b54d..6992497 100644 --- a/src/sms/core/secrets_handler.py +++ b/src/sms/core/secrets_handler.py @@ -38,34 +38,25 @@ def client(self) -> HvacClient: return HvacClient(self._config.vault_url, self._config.vault_token) def get_secrets(self) -> list[str]: - """Return the IDs of all secrets in the vault. - - Raises - - `SecreteRetrievalError`: If the path is invalid or no secrets exist. - """ + """Return the IDs of all secrets in the vault.""" try: secrets = self.client.secrets.kv.v2.list_secrets( path=self._config.vault_path ) secret_ids = secrets["data"]["keys"] return secret_ids - except InvalidPath as exc: + except InvalidPath: msg = ( "Invalid path error when fetching secrets. The path might be invalid," + " or no secrets may exist." ) - retrieval_error = self.SecretRetrievalError(msg) - log.error(retrieval_error, exc) - raise retrieval_error from exc + log.warning(msg) + return [] def delete_secrets(self, secrets: list[str] | None = None): """Delete the secrets from the vault. If no secrets are provided, all secrets in the vault are deleted. - - Raises - - `SecreteRetrievalError`: If the path is invalid or no secrets exist. This will - only occur if the `secrets` parameter is omitted. """ secrets = secrets or self.get_secrets() diff --git a/src/sms/ports/inbound/secrets_handler.py b/src/sms/ports/inbound/secrets_handler.py index 09feaee..cf2d440 100644 --- a/src/sms/ports/inbound/secrets_handler.py +++ b/src/sms/ports/inbound/secrets_handler.py @@ -20,31 +20,16 @@ log = logging.getLogger(__name__) -class VaultException(RuntimeError): - """Baseclass for for errors encountered when interacting with HashiCorp Vault""" - - class SecretsHandlerPort(ABC): """A class to interact with a HashiCorp Vault.""" - class SecretRetrievalError(VaultException): - """Wrapper for errors encountered on secret retrieval""" - @abstractmethod def get_secrets(self) -> list[str]: - """Return the IDs of all secrets in the vault. - - Raises - - `SecreteRetrievalError`: If the path is invalid or no secrets exist. - """ + """Return the IDs of all secrets in the vault.""" @abstractmethod def delete_secrets(self, secrets: list[str] | None = None): """Delete the secrets from the vault. If no secrets are provided, all secrets in the vault are deleted. - - Raises - - `SecreteRetrievalError`: If the path is invalid or no secrets exist. This will - only occur if the `secrets` parameter is omitted. """ From 1fb7ec4b1084ea7752720b1adf880e54d45ecda8 Mon Sep 17 00:00:00 2001 From: TheByronHimes Date: Mon, 28 Oct 2024 13:53:16 +0000 Subject: [PATCH 06/15] Add integration tests and vault fixture --- tests/fixtures/dummies.py | 3 +- tests/fixtures/vault.py | 150 ++++++++++++++++++++++++++++++ tests/integration/test_secrets.py | 96 +++++++++++++++++++ 3 files changed, 248 insertions(+), 1 deletion(-) create mode 100644 tests/fixtures/vault.py create mode 100644 tests/integration/test_secrets.py diff --git a/tests/fixtures/dummies.py b/tests/fixtures/dummies.py index 6ace976..5654bcb 100644 --- a/tests/fixtures/dummies.py +++ b/tests/fixtures/dummies.py @@ -17,6 +17,7 @@ from dataclasses import dataclass from hexkit.custom_types import JsonObject +from hvac.exceptions import InvalidPath from sms.models import Criteria, UpsertionDetails from sms.ports.inbound.docs_handler import DocsHandlerPort @@ -42,7 +43,7 @@ def get_secrets(self) -> list[str]: If `fail_on_get_secrets` is set, it will raise a `SecretRetrievalError`. """ if self.fail_on_get_secrets: - raise self.SecretRetrievalError() + raise InvalidPath("Testing failure") return self.secrets def delete_secrets(self, secrets: list[str] | None = None) -> None: diff --git a/tests/fixtures/vault.py b/tests/fixtures/vault.py new file mode 100644 index 0000000..318750c --- /dev/null +++ b/tests/fixtures/vault.py @@ -0,0 +1,150 @@ +# Copyright 2021 - 2024 Universität Tübingen, DKFZ, EMBL, and Universität zu Köln +# for the German Human Genome-Phenome Archive (GHGA) +# +# 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. +"""HashiCorp vault fixture for texting""" + +import time +from collections.abc import Generator +from typing import Any + +import hvac +import pytest +from pydantic import Field +from pydantic_settings import BaseSettings + +# from testcontainers.vault import DockerContainer +from testcontainers.core.generic import DockerContainer + +VAULT_URL = "http://0.0.0.0:8200" +VAULT_NAMESPACE = "vault" +VAULT_TOKEN = "dev-token" +VAULT_PORT = 8200 + + +class VaultConfig(BaseSettings): + """Configuration for vault container/fixture""" + + vault_url: str = Field( + default="http://0.0.0.0:8200", description="URL of the vault server" + ) + vault_role_id: str = Field(..., description="Role ID for vault authentication") + vault_secret_id: str = Field(..., description="Secret ID for vault authentication") + vault_path: str = Field(default="ekss", description="Path to store secrets") + + +class VaultFixture: + """Contains initialized vault client""" + + def __init__(self, config: VaultConfig): + self.config = config + + def store_secret(self, key: str): + """Store a secret in vault""" + client = hvac.Client(url=self.config.vault_url, token=VAULT_TOKEN) + client.auth.approle.login( + role_id=self.config.vault_role_id, + secret_id=self.config.vault_secret_id, + ) + client.secrets.kv.v2.create_or_update_secret( + path=f"{self.config.vault_path}/{key}", + secret={key: f"secret_for_{key}"}, + ) + + def get_secret(self, key: str) -> Any: + """Retrieve a secret from vault""" + client = hvac.Client(url=self.config.vault_url) + client.auth.approle.login( + role_id=self.config.vault_role_id, + secret_id=self.config.vault_secret_id, + ) + response = client.secrets.kv.v2.read_secret_version( + path=f"{self.config.vault_path}/{key}", + raise_on_deleted_version=True, + ) + return response["data"]["data"][key] + + +@pytest.fixture +def vault_fixture() -> Generator[VaultFixture, None, None]: + """Generate preconfigured test container""" + vault_container = ( + DockerContainer(image="hashicorp/vault:1.12") + .with_exposed_ports(VAULT_PORT) + .with_env("VAULT_ADDR", VAULT_URL) + .with_env("VAULT_DEV_ROOT_TOKEN_ID", VAULT_TOKEN) + ) + with vault_container: + host = vault_container.get_container_host_ip() + port = vault_container.get_exposed_port(VAULT_PORT) + role_id, secret_id = configure_vault(host=host, port=int(port)) + config = VaultConfig( + vault_url=f"http://{host}:{port}", + vault_role_id=role_id, + vault_secret_id=secret_id, + vault_path="ekss", + ) + # client needs some time after creation + time.sleep(2) + yield VaultFixture(config=config) + + +def configure_vault(*, host: str, port: int): + """Configure vault using direct interaction with hvac.Client""" + client = hvac.Client(url=f"http://{host}:{port}", token=VAULT_TOKEN) + # client needs some time after creation + time.sleep(2) + + # enable authentication with role_id/secret_id + client.sys.enable_auth_method( + method_type="approle", + ) + + # create access policy to bind to role + ekss_policy = """ + path "secret/data/ekss/*" { + capabilities = ["read", "create"] + } + path "secret/metadata/ekss/*" { + capabilities = ["delete"] + } + """ + + # inject policy + client.sys.create_or_update_policy( + name="ekss", + policy=ekss_policy, + ) + + role_name = "test_role" + # create role and bind policy + response = client.auth.approle.create_or_update_approle( + role_name=role_name, + token_policies=["ekss"], + token_type="service", + ) + + # retrieve role_id + response = client.auth.approle.read_role_id(role_name=role_name) + role_id = response["data"]["role_id"] + + # retrieve secret_id + response = client.auth.approle.generate_secret_id( + role_name=role_name, + ) + secret_id = response["data"]["secret_id"] + + # log out root token client + client.logout() + + return role_id, secret_id diff --git a/tests/integration/test_secrets.py b/tests/integration/test_secrets.py new file mode 100644 index 0000000..a0dd4f0 --- /dev/null +++ b/tests/integration/test_secrets.py @@ -0,0 +1,96 @@ +# Copyright 2021 - 2024 Universität Tübingen, DKFZ, EMBL, and Universität zu Köln +# for the German Human Genome-Phenome Archive (GHGA) +# +# 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. +"""Integration tests for the /secrets endpoints.""" + +from typing import Any + +import pytest +from ghga_service_commons.api.testing import AsyncTestClient + +from sms.inject import prepare_rest_app +from tests.fixtures.config import get_config +from tests.fixtures.utils import VALID_BEARER_TOKEN +from tests.fixtures.vault import VaultFixture, vault_fixture # noqa: F401 + +TEST_URL = "/secrets/" +pytestmark = pytest.mark.asyncio() +HEADERS: dict[str, Any] = {"Authorization": VALID_BEARER_TOKEN} + + +@pytest.mark.parametrize( + "stored_secrets", + [[], ["key1"], ["key1", "key2"]], + ids=["empty", "single", "multiple"], +) +async def test_happy_get(vault_fixture: VaultFixture, stored_secrets: list[str]): # noqa: F811 + """Test that the GET /secrets endpoint returns the correct response.""" + vault_fixture_config = vault_fixture.config + config = get_config(sources=[vault_fixture_config]) + + for secret in stored_secrets: + vault_fixture.store_secret(secret) + + async with ( + prepare_rest_app(config=config) as app, + AsyncTestClient(app=app) as client, + ): + response = await client.get(TEST_URL, headers=HEADERS) + assert response.status_code == 200 + assert set(response.json()) == set(stored_secrets) + + +@pytest.mark.parametrize( + "secrets_to_delete", + [[], ["key1"], ["key1", "key2"], ["DoesNotExist"]], + ids=["DeleteAll", "DeleteKey1", "DeleteKey1Key2", "DeleteDoesNotExist"], +) +@pytest.mark.parametrize( + "stored_secrets", + [[], ["key1"], ["key1", "key2"]], + ids=["Empty", "OneKey", "TwoKeys"], +) +async def test_happy_delete( + vault_fixture: VaultFixture, # noqa: F811 + stored_secrets: list[str], + secrets_to_delete: list[str], +): + """Test that the DELETE /secrets endpoint returns the correct response.""" + vault_fixture_config = vault_fixture.config + config = get_config(sources=[vault_fixture_config]) + + # Calculate the secrets expected to remain after deletion + expected_secrets_remaining: set[str] = ( + set(stored_secrets) - set(secrets_to_delete) if secrets_to_delete else set() + ) + + # Store the secrets in the vault + for secret in stored_secrets: + vault_fixture.store_secret(secret) + + async with ( + prepare_rest_app(config=config) as app, + AsyncTestClient(app=app) as client, + ): + # Make a DELETE request to delete the secrets + response = await client.delete( + TEST_URL, headers=HEADERS, params={"secrets_to_delete": secrets_to_delete} + ) + print(response.url) + assert response.status_code == 204 + + # Make a GET request to check if the secrets were deleted + response = await client.get(TEST_URL, headers=HEADERS) + assert response.status_code == 200 + assert set(response.json()) == expected_secrets_remaining From 210db82f5c6ab996f41f91b0c72cfc380f481a7d Mon Sep 17 00:00:00 2001 From: TheByronHimes Date: Mon, 28 Oct 2024 13:54:19 +0000 Subject: [PATCH 07/15] Add unit tests for the SecretsHandler --- tests/unit/secrets/test_secrets_handler.py | 149 +++++++++++++++++++++ 1 file changed, 149 insertions(+) create mode 100644 tests/unit/secrets/test_secrets_handler.py diff --git a/tests/unit/secrets/test_secrets_handler.py b/tests/unit/secrets/test_secrets_handler.py new file mode 100644 index 0000000..4d39fed --- /dev/null +++ b/tests/unit/secrets/test_secrets_handler.py @@ -0,0 +1,149 @@ +# Copyright 2021 - 2024 Universität Tübingen, DKFZ, EMBL, and Universität zu Köln +# for the German Human Genome-Phenome Archive (GHGA) +# +# 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. + +"""Unit tests for the SecretsHandler class""" + +from unittest.mock import Mock, call + +import pytest +from hvac.exceptions import InvalidPath + +from sms.core.secrets_handler import SecretsHandler +from tests.fixtures.config import DEFAULT_TEST_CONFIG + + +@pytest.mark.parametrize( + "secrets", + [[], ["key1"], ["key1", "key2"]], + ids=["empty", "single", "multiple"], +) +def test_get_secrets(monkeypatch: pytest.MonkeyPatch, secrets: list[str]): + """Test get_secrets method without errors""" + # patch the hvac client with a mock + mock_client = Mock() + mock_client.secrets.kv.v2.list_secrets.return_value = {"data": {"keys": secrets}} + monkeypatch.setattr(SecretsHandler, "client", mock_client) + secrets_handler = SecretsHandler(config=DEFAULT_TEST_CONFIG) + + assert secrets_handler.get_secrets() == secrets + mock_client.secrets.kv.v2.list_secrets.assert_called_once() + + +def test_get_secrets_error(monkeypatch: pytest.MonkeyPatch, caplog): + """Test get_secrets method with an error""" + # patch the hvac client with a mock + mock_client = Mock() + mock_client.secrets.kv.v2.list_secrets.side_effect = InvalidPath("Invalid path") + monkeypatch.setattr(SecretsHandler, "client", mock_client) + secrets_handler = SecretsHandler(config=DEFAULT_TEST_CONFIG) + + # Make sure the error is logged as a warning but an empty list is still returned + caplog.clear() + secrets = secrets_handler.get_secrets() + assert len(caplog.messages) == 1 + assert caplog.messages[0] == ( + "Invalid path error when fetching secrets. The path might be invalid," + + " or no secrets may exist." + ) + assert caplog.records[0].levelname == "WARNING" + assert secrets == [] + mock_client.secrets.kv.v2.list_secrets.assert_called_once() + + +def test_delete_secrets_error(monkeypatch: pytest.MonkeyPatch): + """Test delete_secrets method on empty vault and without specifying secrets.""" + # patch the hvac client with a mock + mock_client = Mock() + mock_client.secrets.kv.v2.list_secrets.side_effect = InvalidPath("Invalid path") + monkeypatch.setattr(SecretsHandler, "client", mock_client) + secrets_handler = SecretsHandler(config=DEFAULT_TEST_CONFIG) + + # Call delete_secrets() without specifying secrets in order to trigger get_secrets + secrets_handler.delete_secrets() + mock_client.secrets.kv.v2.list_secrets.assert_called_once() + mock_client.secrets.kv.v2.delete_metadata_and_all_versions.assert_not_called() + + +@pytest.mark.parametrize( + "secrets_to_delete", + [ + None, + [], + ["key1"], + ["key2"], + ["key1", "key2"], + ], + ids=[ + "None", + "Empty", + "DeleteKey1", + "DeleteKey2", + "DeleteBoth", + ], +) +@pytest.mark.parametrize( + "stored_secrets", + [[], ["key1"], ["key1", "key2"]], + ids=["Empty", "OneSecret", "TwoSecrets"], +) +def test_delete_successful( + monkeypatch: pytest.MonkeyPatch, + secrets_to_delete: list[str] | None, + stored_secrets: list[str], +): + """Test delete_secrets method. + + Use a variety of combinations of stored secrets and secrets to delete. + """ + # create a mock for the hvac client + list_stored_secrets = {"data": {"keys": stored_secrets}} + mock_client = Mock() + + # list_secrets either returns all keys or raises an InvalidPath error + if stored_secrets: + mock_client.secrets.kv.v2.list_secrets.return_value = list_stored_secrets + else: + mock_client.secrets.kv.v2.list_secrets.side_effect = InvalidPath("Invalid path") + + # apply the mock to the SecretsHandler + monkeypatch.setattr(SecretsHandler, "client", mock_client) + secrets_handler = SecretsHandler(config=DEFAULT_TEST_CONFIG) + + # call delete_secrets() + secrets_handler.delete_secrets(secrets=secrets_to_delete) + + # list_secrets is ONLY called if secrets_to_delete is None or empty list + if not secrets_to_delete: + mock_client.secrets.kv.v2.list_secrets.assert_called_once() + else: + mock_client.secrets.kv.v2.list_secrets.assert_not_called() + + # delete_metadata_and_all_versions is called for each secret in secrets_to_delete + # if that's not supplied, then it is called for each value in list_secrets + calls = ( + [ + call(path=f"{DEFAULT_TEST_CONFIG.vault_path}/{secret}") + for secret in stored_secrets + ] + if not secrets_to_delete + else [ + call(path=f"{DEFAULT_TEST_CONFIG.vault_path}/{secret}") + for secret in secrets_to_delete + ] + ) + mock_client.secrets.kv.v2.delete_metadata_and_all_versions.assert_has_calls( + calls, + any_order=True, + ) From 15df0403c26544bb83258dbc7bc08fc442f03a56 Mon Sep 17 00:00:00 2001 From: TheByronHimes Date: Mon, 28 Oct 2024 13:55:52 +0000 Subject: [PATCH 08/15] Remove VaultFixture.get_secret() --- tests/fixtures/vault.py | 16 +--------------- 1 file changed, 1 insertion(+), 15 deletions(-) diff --git a/tests/fixtures/vault.py b/tests/fixtures/vault.py index 318750c..893b70a 100644 --- a/tests/fixtures/vault.py +++ b/tests/fixtures/vault.py @@ -12,11 +12,10 @@ # 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. -"""HashiCorp vault fixture for texting""" +"""HashiCorp vault fixture for testing""" import time from collections.abc import Generator -from typing import Any import hvac import pytest @@ -61,19 +60,6 @@ def store_secret(self, key: str): secret={key: f"secret_for_{key}"}, ) - def get_secret(self, key: str) -> Any: - """Retrieve a secret from vault""" - client = hvac.Client(url=self.config.vault_url) - client.auth.approle.login( - role_id=self.config.vault_role_id, - secret_id=self.config.vault_secret_id, - ) - response = client.secrets.kv.v2.read_secret_version( - path=f"{self.config.vault_path}/{key}", - raise_on_deleted_version=True, - ) - return response["data"]["data"][key] - @pytest.fixture def vault_fixture() -> Generator[VaultFixture, None, None]: From 2588e667419fc8b443a5d6b429fd2e4e66f807f1 Mon Sep 17 00:00:00 2001 From: TheByronHimes Date: Mon, 28 Oct 2024 15:12:28 +0000 Subject: [PATCH 09/15] Make vault container persistent for tests Compartmentalize VaultConfig --- src/sms/config.py | 14 +-- src/sms/core/secrets_handler.py | 19 +++- tests/fixtures/vault.py | 145 ++++++++++++------------------ tests/integration/test_secrets.py | 6 +- 4 files changed, 80 insertions(+), 104 deletions(-) diff --git a/src/sms/config.py b/src/sms/config.py index d0da4d2..5eceb40 100644 --- a/src/sms/config.py +++ b/src/sms/config.py @@ -24,24 +24,14 @@ from hexkit.log import LoggingConfig from hexkit.providers.akafka import KafkaConfig from pydantic import Field, SecretStr, field_validator, model_validator -from pydantic_settings import BaseSettings +from tests.fixtures.vault import VaultConfig SERVICE_NAME: str = "sms" -class SmsConfig(BaseSettings): +class SmsConfig(VaultConfig): """Configuration specific to the SMS.""" - vault_url: str = Field( - default=..., description="URL for the Vault", examples=["http://vault:8200"] - ) - vault_token: str = Field( - default=..., description="Token for the Vault", examples=["dev-token"] - ) - vault_path: str = Field( - default=..., description="Path for the Vault", examples=["ekss"] - ) - token_hashes: list[str] = Field( default=..., description="List of token hashes corresponding to the tokens that can be used " diff --git a/src/sms/core/secrets_handler.py b/src/sms/core/secrets_handler.py index 6992497..9418ce8 100644 --- a/src/sms/core/secrets_handler.py +++ b/src/sms/core/secrets_handler.py @@ -18,17 +18,32 @@ from hvac import Client as HvacClient from hvac.exceptions import InvalidPath +from pydantic import Field +from pydantic_settings import BaseSettings -from sms.config import Config from sms.ports.inbound.secrets_handler import SecretsHandlerPort log = logging.getLogger(__name__) +class VaultConfig(BaseSettings): + """Configuration for the vault client""" + + vault_url: str = Field( + default=..., description="URL for the Vault", examples=["http://vault:8200"] + ) + vault_token: str = Field( + default=..., description="Token for the Vault", examples=["dev-token"] + ) + vault_path: str = Field( + default=..., description="Path for the Vault", examples=["sms", "ekss"] + ) + + class SecretsHandler(SecretsHandlerPort): """Adapter wrapping hvac.Client""" - def __init__(self, config: Config): + def __init__(self, config: VaultConfig): """Initialized approle based client and login""" self._config = config diff --git a/tests/fixtures/vault.py b/tests/fixtures/vault.py index 893b70a..8fe382a 100644 --- a/tests/fixtures/vault.py +++ b/tests/fixtures/vault.py @@ -16,30 +16,19 @@ import time from collections.abc import Generator +from contextlib import suppress import hvac import pytest -from pydantic import Field -from pydantic_settings import BaseSettings - -# from testcontainers.vault import DockerContainer +from hvac.exceptions import InvalidPath from testcontainers.core.generic import DockerContainer -VAULT_URL = "http://0.0.0.0:8200" -VAULT_NAMESPACE = "vault" -VAULT_TOKEN = "dev-token" -VAULT_PORT = 8200 - - -class VaultConfig(BaseSettings): - """Configuration for vault container/fixture""" +from sms.core.secrets_handler import VaultConfig - vault_url: str = Field( - default="http://0.0.0.0:8200", description="URL of the vault server" - ) - vault_role_id: str = Field(..., description="Role ID for vault authentication") - vault_secret_id: str = Field(..., description="Secret ID for vault authentication") - vault_path: str = Field(default="ekss", description="Path to store secrets") +DEFAULT_IMAGE = "hashicorp/vault:1.12" +DEFAULT_URL = "http://0.0.0.0:8200" +DEFAULT_PORT = 8200 +DEFAULT_TOKEN = "dev-token" class VaultFixture: @@ -50,87 +39,65 @@ def __init__(self, config: VaultConfig): def store_secret(self, key: str): """Store a secret in vault""" - client = hvac.Client(url=self.config.vault_url, token=VAULT_TOKEN) - client.auth.approle.login( - role_id=self.config.vault_role_id, - secret_id=self.config.vault_secret_id, - ) + client = hvac.Client(url=self.config.vault_url, token=DEFAULT_TOKEN) + client.secrets.kv.v2.create_or_update_secret( path=f"{self.config.vault_path}/{key}", secret={key: f"secret_for_{key}"}, ) + def delete_all_secrets(self): + """Remove all secrets from the vault to reset for next test""" + client = hvac.Client(url=self.config.vault_url, token=DEFAULT_TOKEN) + + with suppress(InvalidPath): + secrets = client.secrets.kv.v2.list_secrets(path=self.config.vault_path) + for key in secrets["data"]["keys"]: + client.secrets.kv.v2.delete_metadata_and_all_versions( + path=f"{self.config.vault_path}/{key}" + ) + + +class VaultContainer(DockerContainer): + """A hashi corp vault container for testing.""" + + def __init__(self, image: str = DEFAULT_IMAGE, port: int = DEFAULT_PORT, **kwargs): + """Initialize a vault container with default settings.""" + super().__init__(image, **kwargs) -@pytest.fixture -def vault_fixture() -> Generator[VaultFixture, None, None]: + self.with_exposed_ports(port) + self.with_env("VAULT_ADDR", DEFAULT_URL) + self.with_env("VAULT_DEV_ROOT_TOKEN_ID", DEFAULT_TOKEN) + + +class VaultContainerFixture(VaultContainer): + """Fixture for VaultContainer""" + + config: VaultConfig + + +@pytest.fixture(scope="session", name="vault_container") +def vault_container_fixture() -> Generator[VaultContainerFixture, None, None]: """Generate preconfigured test container""" - vault_container = ( - DockerContainer(image="hashicorp/vault:1.12") - .with_exposed_ports(VAULT_PORT) - .with_env("VAULT_ADDR", VAULT_URL) - .with_env("VAULT_DEV_ROOT_TOKEN_ID", VAULT_TOKEN) - ) - with vault_container: + with VaultContainerFixture() as vault_container: host = vault_container.get_container_host_ip() - port = vault_container.get_exposed_port(VAULT_PORT) - role_id, secret_id = configure_vault(host=host, port=int(port)) - config = VaultConfig( + port = vault_container.get_exposed_port(DEFAULT_PORT) + vault_container.config = VaultConfig( vault_url=f"http://{host}:{port}", - vault_role_id=role_id, - vault_secret_id=secret_id, vault_path="ekss", + vault_token=DEFAULT_TOKEN, ) + # client needs some time after creation time.sleep(2) - yield VaultFixture(config=config) - - -def configure_vault(*, host: str, port: int): - """Configure vault using direct interaction with hvac.Client""" - client = hvac.Client(url=f"http://{host}:{port}", token=VAULT_TOKEN) - # client needs some time after creation - time.sleep(2) - - # enable authentication with role_id/secret_id - client.sys.enable_auth_method( - method_type="approle", - ) - - # create access policy to bind to role - ekss_policy = """ - path "secret/data/ekss/*" { - capabilities = ["read", "create"] - } - path "secret/metadata/ekss/*" { - capabilities = ["delete"] - } - """ - - # inject policy - client.sys.create_or_update_policy( - name="ekss", - policy=ekss_policy, - ) - - role_name = "test_role" - # create role and bind policy - response = client.auth.approle.create_or_update_approle( - role_name=role_name, - token_policies=["ekss"], - token_type="service", - ) - - # retrieve role_id - response = client.auth.approle.read_role_id(role_name=role_name) - role_id = response["data"]["role_id"] - - # retrieve secret_id - response = client.auth.approle.generate_secret_id( - role_name=role_name, - ) - secret_id = response["data"]["secret_id"] - - # log out root token client - client.logout() - - return role_id, secret_id + yield vault_container + + +@pytest.fixture(scope="function") +def vault_fixture( + vault_container: VaultContainerFixture, +) -> Generator[VaultFixture, None, None]: + """Fixture function to produce a VaultFixture""" + vault = VaultFixture(config=vault_container.config) + vault.delete_all_secrets() + yield vault diff --git a/tests/integration/test_secrets.py b/tests/integration/test_secrets.py index a0dd4f0..94ea051 100644 --- a/tests/integration/test_secrets.py +++ b/tests/integration/test_secrets.py @@ -22,7 +22,11 @@ from sms.inject import prepare_rest_app from tests.fixtures.config import get_config from tests.fixtures.utils import VALID_BEARER_TOKEN -from tests.fixtures.vault import VaultFixture, vault_fixture # noqa: F401 +from tests.fixtures.vault import ( # noqa: F401 + VaultFixture, + vault_container_fixture, + vault_fixture, +) TEST_URL = "/secrets/" pytestmark = pytest.mark.asyncio() From 20d6b26236c97682d7b03460a4ce17fb4ac2d330 Mon Sep 17 00:00:00 2001 From: TheByronHimes Date: Mon, 28 Oct 2024 15:19:17 +0000 Subject: [PATCH 10/15] Update config to use sms instead of ekss --- .devcontainer/.dev_config.yaml | 2 +- README.md | 5 +++++ config_schema.json | 1 + example_config.yaml | 2 +- src/sms/config.py | 3 ++- tests/fixtures/test_config.yaml | 2 +- tests/fixtures/vault.py | 2 +- 7 files changed, 12 insertions(+), 5 deletions(-) diff --git a/.devcontainer/.dev_config.yaml b/.devcontainer/.dev_config.yaml index ea1a7a1..be7f2a3 100644 --- a/.devcontainer/.dev_config.yaml +++ b/.devcontainer/.dev_config.yaml @@ -4,7 +4,7 @@ token_hashes: - 7ad83b6b9183c91674eec897935bc154ba9ff9704f8be0840e77f476b5062b6e vault_token: "dev-token" vault_url: "http://vault:8200" -vault_path: "ekss" +vault_path: sms db_connection_str: mongodb://mongodb:27017 db_prefix: "test_" db_permissions: diff --git a/README.md b/README.md index 9d045f8..15c6b74 100644 --- a/README.md +++ b/README.md @@ -150,6 +150,11 @@ The service requires the following configuration parameters: Examples: + ```json + "sms" + ``` + + ```json "ekss" ``` diff --git a/config_schema.json b/config_schema.json index 0f40b75..093cbd2 100644 --- a/config_schema.json +++ b/config_schema.json @@ -207,6 +207,7 @@ "vault_path": { "description": "Path for the Vault", "examples": [ + "sms", "ekss" ], "title": "Vault Path", diff --git a/example_config.yaml b/example_config.yaml index 02d8bb5..a405819 100644 --- a/example_config.yaml +++ b/example_config.yaml @@ -46,7 +46,7 @@ service_instance_id: '1' service_name: sms token_hashes: - 7ad83b6b9183c91674eec897935bc154ba9ff9704f8be0840e77f476b5062b6e -vault_path: ekss +vault_path: sms vault_token: dev-token vault_url: http://vault:8200 workers: 1 diff --git a/src/sms/config.py b/src/sms/config.py index 5eceb40..a1aefd3 100644 --- a/src/sms/config.py +++ b/src/sms/config.py @@ -24,7 +24,8 @@ from hexkit.log import LoggingConfig from hexkit.providers.akafka import KafkaConfig from pydantic import Field, SecretStr, field_validator, model_validator -from tests.fixtures.vault import VaultConfig + +from sms.core.secrets_handler import VaultConfig SERVICE_NAME: str = "sms" diff --git a/tests/fixtures/test_config.yaml b/tests/fixtures/test_config.yaml index 80d9d15..20d056b 100644 --- a/tests/fixtures/test_config.yaml +++ b/tests/fixtures/test_config.yaml @@ -4,7 +4,7 @@ token_hashes: - 7ad83b6b9183c91674eec897935bc154ba9ff9704f8be0840e77f476b5062b6e vault_token: "dev-token" vault_url: "http://vault:8200" -vault_path: "ekss" +vault_path: sms db_connection_str: mongodb://mongodb:27017 db_prefix: "test_" db_permissions: diff --git a/tests/fixtures/vault.py b/tests/fixtures/vault.py index 8fe382a..218a5e3 100644 --- a/tests/fixtures/vault.py +++ b/tests/fixtures/vault.py @@ -84,7 +84,7 @@ def vault_container_fixture() -> Generator[VaultContainerFixture, None, None]: port = vault_container.get_exposed_port(DEFAULT_PORT) vault_container.config = VaultConfig( vault_url=f"http://{host}:{port}", - vault_path="ekss", + vault_path="sms", vault_token=DEFAULT_TOKEN, ) From 16837fa1b4f060e6f7d0d42b3e31ae116c34b1bf Mon Sep 17 00:00:00 2001 From: TheByronHimes Date: Mon, 28 Oct 2024 15:50:07 +0000 Subject: [PATCH 11/15] Only offer mass deletion endpoint --- openapi.yaml | 25 +-------- .../inbound/fastapi_/routers/secrets.py | 15 +---- src/sms/core/secrets_handler.py | 11 +--- src/sms/ports/inbound/secrets_handler.py | 7 +-- tests/fixtures/dummies.py | 17 ++---- tests/integration/test_secrets.py | 18 +----- tests/unit/secrets/test_rest_secrets.py | 39 +++---------- tests/unit/secrets/test_secrets_handler.py | 56 ++++--------------- 8 files changed, 34 insertions(+), 154 deletions(-) diff --git a/openapi.yaml b/openapi.yaml index dd140dd..182872a 100644 --- a/openapi.yaml +++ b/openapi.yaml @@ -385,35 +385,14 @@ paths: - sms-s3 /secrets/: delete: - description: If secrets_to_delete is omitted, all secrets are deleted. If `secrets_to_delete` - is provided, only the secrets with the matching IDs are deleted. If a provided - secret does not exist, it is ignored. + description: Delete one or more secrets from the vault operationId: delete_secrets - parameters: - - description: List of secrets to delete. - in: query - name: secrets_to_delete - required: false - schema: - anyOf: - - items: - type: string - type: array - - type: 'null' - description: List of secrets to delete. - title: Secrets To Delete responses: '204': description: Successful Response - '422': - content: - application/json: - schema: - $ref: '#/components/schemas/HTTPValidationError' - description: Validation Error security: - HTTPBearer: [] - summary: Delete one or more secrets from the vault + summary: Delete all secrets from the vault tags: - StateManagementService - sms-vault diff --git a/src/sms/adapters/inbound/fastapi_/routers/secrets.py b/src/sms/adapters/inbound/fastapi_/routers/secrets.py index f57c6de..994d4c2 100644 --- a/src/sms/adapters/inbound/fastapi_/routers/secrets.py +++ b/src/sms/adapters/inbound/fastapi_/routers/secrets.py @@ -17,7 +17,7 @@ from typing import Annotated -from fastapi import APIRouter, HTTPException, Query, status +from fastapi import APIRouter, HTTPException, status from sms.adapters.inbound.fastapi_ import dummies from sms.adapters.inbound.fastapi_.http_authorization import ( @@ -49,24 +49,15 @@ async def get_secrets( @secrets_router.delete( "/", operation_id="delete_secrets", - summary="Delete one or more secrets from the vault", - description=( - "If secrets_to_delete is omitted, all secrets are deleted. If" - + " `secrets_to_delete` is provided, only the secrets with the matching IDs are" - + " deleted. If a provided secret does not exist, it is ignored." - ), + summary="Delete all secrets from the vault", status_code=status.HTTP_204_NO_CONTENT, ) async def delete_secrets( secrets_handler: dummies.SecretsHandlerPortDummy, _token: Annotated[TokenAuthContext, require_token], - secrets_to_delete: list[str] | None = Query( - default=None, - description="List of secrets to delete.", - ), ): """Delete one or more secrets from the vault""" try: - secrets_handler.delete_secrets(secrets=secrets_to_delete) + secrets_handler.delete_secrets() except Exception as exc: raise HTTPException(status_code=status.HTTP_500_INTERNAL_SERVER_ERROR) from exc diff --git a/src/sms/core/secrets_handler.py b/src/sms/core/secrets_handler.py index 9418ce8..26e7635 100644 --- a/src/sms/core/secrets_handler.py +++ b/src/sms/core/secrets_handler.py @@ -68,20 +68,15 @@ def get_secrets(self) -> list[str]: log.warning(msg) return [] - def delete_secrets(self, secrets: list[str] | None = None): - """Delete the secrets from the vault. - - If no secrets are provided, all secrets in the vault are deleted. - """ - secrets = secrets or self.get_secrets() + def delete_secrets(self): + """Delete all secrets from the vault.""" + secrets = self.get_secrets() if not secrets: log.info("No secrets to delete") return - log.info(f"Deleting secrets: {secrets}") for secret in secrets: self.client.secrets.kv.v2.delete_metadata_and_all_versions( path=f"{self._config.vault_path}/{secret}" ) - log.debug(f"Deleted secret with id '{secret}'") diff --git a/src/sms/ports/inbound/secrets_handler.py b/src/sms/ports/inbound/secrets_handler.py index cf2d440..15b770d 100644 --- a/src/sms/ports/inbound/secrets_handler.py +++ b/src/sms/ports/inbound/secrets_handler.py @@ -28,8 +28,5 @@ def get_secrets(self) -> list[str]: """Return the IDs of all secrets in the vault.""" @abstractmethod - def delete_secrets(self, secrets: list[str] | None = None): - """Delete the secrets from the vault. - - If no secrets are provided, all secrets in the vault are deleted. - """ + def delete_secrets(self): + """Delete all secrets from the vault.""" diff --git a/tests/fixtures/dummies.py b/tests/fixtures/dummies.py index 5654bcb..95e70d0 100644 --- a/tests/fixtures/dummies.py +++ b/tests/fixtures/dummies.py @@ -40,24 +40,15 @@ def __init__( def get_secrets(self) -> list[str]: """Get all secrets currently stored. - If `fail_on_get_secrets` is set, it will raise a `SecretRetrievalError`. + If `fail_on_get_secrets` is set, it will raise an `InvalidPath` error. """ if self.fail_on_get_secrets: raise InvalidPath("Testing failure") return self.secrets - def delete_secrets(self, secrets: list[str] | None = None) -> None: - """Delete stored secrets with the matching IDs. - - If no secrets are provided, all secrets are deleted. - If `secrets` is provided, only the secrets with the matching IDs are deleted. - If a provided secret does not exist, it is ignored. - If `fail_on_get_secrets` is set and no secrets are specified, a - `SecretRetrievalError` will be raised by the call to `get_secrets()`. - """ - self.recent = secrets - secrets_to_delete = secrets or self.get_secrets() - self.secrets = [s for s in self.secrets if s not in secrets_to_delete] + def delete_secrets(self) -> None: + """Delete all secrets stored in the vault.""" + self.secrets = [] @dataclass diff --git a/tests/integration/test_secrets.py b/tests/integration/test_secrets.py index 94ea051..efc6b2a 100644 --- a/tests/integration/test_secrets.py +++ b/tests/integration/test_secrets.py @@ -55,11 +55,6 @@ async def test_happy_get(vault_fixture: VaultFixture, stored_secrets: list[str]) assert set(response.json()) == set(stored_secrets) -@pytest.mark.parametrize( - "secrets_to_delete", - [[], ["key1"], ["key1", "key2"], ["DoesNotExist"]], - ids=["DeleteAll", "DeleteKey1", "DeleteKey1Key2", "DeleteDoesNotExist"], -) @pytest.mark.parametrize( "stored_secrets", [[], ["key1"], ["key1", "key2"]], @@ -68,17 +63,11 @@ async def test_happy_get(vault_fixture: VaultFixture, stored_secrets: list[str]) async def test_happy_delete( vault_fixture: VaultFixture, # noqa: F811 stored_secrets: list[str], - secrets_to_delete: list[str], ): """Test that the DELETE /secrets endpoint returns the correct response.""" vault_fixture_config = vault_fixture.config config = get_config(sources=[vault_fixture_config]) - # Calculate the secrets expected to remain after deletion - expected_secrets_remaining: set[str] = ( - set(stored_secrets) - set(secrets_to_delete) if secrets_to_delete else set() - ) - # Store the secrets in the vault for secret in stored_secrets: vault_fixture.store_secret(secret) @@ -88,13 +77,10 @@ async def test_happy_delete( AsyncTestClient(app=app) as client, ): # Make a DELETE request to delete the secrets - response = await client.delete( - TEST_URL, headers=HEADERS, params={"secrets_to_delete": secrets_to_delete} - ) - print(response.url) + response = await client.delete(TEST_URL, headers=HEADERS) assert response.status_code == 204 # Make a GET request to check if the secrets were deleted response = await client.get(TEST_URL, headers=HEADERS) assert response.status_code == 200 - assert set(response.json()) == expected_secrets_remaining + assert response.json() == [] diff --git a/tests/unit/secrets/test_rest_secrets.py b/tests/unit/secrets/test_rest_secrets.py index d2b8450..248087d 100644 --- a/tests/unit/secrets/test_rest_secrets.py +++ b/tests/unit/secrets/test_rest_secrets.py @@ -64,16 +64,6 @@ async def test_get_secrets_error(): assert response.status_code == 500 -@pytest.mark.parametrize( - "secrets_to_delete", - [None, [], ["secret1"], ["secret1", "secret2"]], - ids=[ - "DeleteArgNotProvided", - "DeleteEmptyList", - "DeleteSecret1", - "DeleteSecret1AndSecret2", - ], -) @pytest.mark.parametrize( "stored_secrets", [ @@ -82,39 +72,24 @@ async def test_get_secrets_error(): ], ids=["VaultIsEmpty", "VaultHasThreeSecrets"], ) -async def test_delete_secrets( - stored_secrets: list[str], secrets_to_delete: list[str] | None -): +async def test_delete_secrets(stored_secrets: list[str]): """Test the DELETE secrets endpoint without errors.""" secrets_handler = DummySecretsHandler(secrets=stored_secrets) async with get_rest_client_with_mocks( config=DEFAULT_TEST_CONFIG, secrets_handler_override=secrets_handler ) as client: - if secrets_to_delete is None: - response = await client.delete(TEST_URL, headers=HEADERS) - else: - response = await client.delete( - TEST_URL, - headers=HEADERS, - params={"secrets_to_delete": secrets_to_delete}, - ) + response = await client.delete(TEST_URL, headers=HEADERS) assert response.status_code == 204 - - expected_remaining_secrets = ( - [s for s in stored_secrets if s not in secrets_to_delete] - if secrets_to_delete - else [] - ) - - assert secrets_handler.secrets == expected_remaining_secrets, secrets_handler.recent + assert secrets_handler.secrets == [] async def test_delete_secrets_error(): """Test the DELETE secrets endpoint with an error. - This is triggered by setting the `fail_on_get_secrets` flag to True and - not providing any secrets to delete. + This is triggered by setting the `fail_on_get_secrets` flag to True. + The `get_secrets` method will raise an exception, but the `delete_secrets` + method should still return a 204 status code. """ secrets_handler = DummySecretsHandler(fail_on_get_secrets=True) async with get_rest_client_with_mocks( @@ -122,4 +97,4 @@ async def test_delete_secrets_error(): ) as client: response = await client.delete(TEST_URL, headers=HEADERS) - assert response.status_code == 500 + assert response.status_code == 204 diff --git a/tests/unit/secrets/test_secrets_handler.py b/tests/unit/secrets/test_secrets_handler.py index 4d39fed..b004ee6 100644 --- a/tests/unit/secrets/test_secrets_handler.py +++ b/tests/unit/secrets/test_secrets_handler.py @@ -63,36 +63,19 @@ def test_get_secrets_error(monkeypatch: pytest.MonkeyPatch, caplog): def test_delete_secrets_error(monkeypatch: pytest.MonkeyPatch): - """Test delete_secrets method on empty vault and without specifying secrets.""" + """Test delete_secrets method on empty vault.""" # patch the hvac client with a mock mock_client = Mock() mock_client.secrets.kv.v2.list_secrets.side_effect = InvalidPath("Invalid path") monkeypatch.setattr(SecretsHandler, "client", mock_client) secrets_handler = SecretsHandler(config=DEFAULT_TEST_CONFIG) - # Call delete_secrets() without specifying secrets in order to trigger get_secrets + # Call delete_secrets() in order to trigger get_secrets secrets_handler.delete_secrets() mock_client.secrets.kv.v2.list_secrets.assert_called_once() mock_client.secrets.kv.v2.delete_metadata_and_all_versions.assert_not_called() -@pytest.mark.parametrize( - "secrets_to_delete", - [ - None, - [], - ["key1"], - ["key2"], - ["key1", "key2"], - ], - ids=[ - "None", - "Empty", - "DeleteKey1", - "DeleteKey2", - "DeleteBoth", - ], -) @pytest.mark.parametrize( "stored_secrets", [[], ["key1"], ["key1", "key2"]], @@ -100,13 +83,9 @@ def test_delete_secrets_error(monkeypatch: pytest.MonkeyPatch): ) def test_delete_successful( monkeypatch: pytest.MonkeyPatch, - secrets_to_delete: list[str] | None, stored_secrets: list[str], ): - """Test delete_secrets method. - - Use a variety of combinations of stored secrets and secrets to delete. - """ + """Test delete_secrets method.""" # create a mock for the hvac client list_stored_secrets = {"data": {"keys": stored_secrets}} mock_client = Mock() @@ -122,28 +101,15 @@ def test_delete_successful( secrets_handler = SecretsHandler(config=DEFAULT_TEST_CONFIG) # call delete_secrets() - secrets_handler.delete_secrets(secrets=secrets_to_delete) + secrets_handler.delete_secrets() + mock_client.secrets.kv.v2.list_secrets.assert_called_once() - # list_secrets is ONLY called if secrets_to_delete is None or empty list - if not secrets_to_delete: - mock_client.secrets.kv.v2.list_secrets.assert_called_once() - else: - mock_client.secrets.kv.v2.list_secrets.assert_not_called() - - # delete_metadata_and_all_versions is called for each secret in secrets_to_delete - # if that's not supplied, then it is called for each value in list_secrets - calls = ( - [ - call(path=f"{DEFAULT_TEST_CONFIG.vault_path}/{secret}") - for secret in stored_secrets - ] - if not secrets_to_delete - else [ - call(path=f"{DEFAULT_TEST_CONFIG.vault_path}/{secret}") - for secret in secrets_to_delete - ] - ) + # delete_metadata_and_all_versions is called for each secret + internal_deletion_calls = [ + call(path=f"{DEFAULT_TEST_CONFIG.vault_path}/{secret}") + for secret in stored_secrets + ] mock_client.secrets.kv.v2.delete_metadata_and_all_versions.assert_has_calls( - calls, + internal_deletion_calls, any_order=True, ) From cb8c906f2765f82ff0687ec3a984a316f7664daa Mon Sep 17 00:00:00 2001 From: TheByronHimes Date: Tue, 29 Oct 2024 15:17:22 +0000 Subject: [PATCH 12/15] Move vault_path from config to API --- .devcontainer/.dev_config.yaml | 2 +- README.md | 15 ------- config_schema.json | 10 ----- example_config.yaml | 1 - openapi.yaml | 42 +++++++++++++++++-- .../inbound/fastapi_/routers/secrets.py | 21 ++++++---- src/sms/core/secrets_handler.py | 27 +++++------- src/sms/ports/inbound/secrets_handler.py | 8 ++-- tests/fixtures/dummies.py | 16 ++++--- tests/fixtures/test_config.yaml | 2 +- tests/fixtures/vault.py | 27 ++++++++---- tests/integration/test_secrets.py | 24 +++++++++-- tests/unit/secrets/test_rest_secrets.py | 28 +++++-------- tests/unit/secrets/test_secrets_handler.py | 16 +++---- 14 files changed, 137 insertions(+), 102 deletions(-) diff --git a/.devcontainer/.dev_config.yaml b/.devcontainer/.dev_config.yaml index be7f2a3..e8a239a 100644 --- a/.devcontainer/.dev_config.yaml +++ b/.devcontainer/.dev_config.yaml @@ -4,7 +4,7 @@ token_hashes: - 7ad83b6b9183c91674eec897935bc154ba9ff9704f8be0840e77f476b5062b6e vault_token: "dev-token" vault_url: "http://vault:8200" -vault_path: sms + db_connection_str: mongodb://mongodb:27017 db_prefix: "test_" db_permissions: diff --git a/README.md b/README.md index 15c6b74..8d35a85 100644 --- a/README.md +++ b/README.md @@ -145,21 +145,6 @@ The service requires the following configuration parameters: ``` -- **`vault_path`** *(string, required)*: Path for the Vault. - - - Examples: - - ```json - "sms" - ``` - - - ```json - "ekss" - ``` - - - **`token_hashes`** *(array, required)*: List of token hashes corresponding to the tokens that can be used to authenticate calls to this service. Hashes are made with SHA-256. - **Items** *(string)* diff --git a/config_schema.json b/config_schema.json index 093cbd2..254b431 100644 --- a/config_schema.json +++ b/config_schema.json @@ -204,15 +204,6 @@ "title": "Vault Token", "type": "string" }, - "vault_path": { - "description": "Path for the Vault", - "examples": [ - "sms", - "ekss" - ], - "title": "Vault Path", - "type": "string" - }, "token_hashes": { "description": "List of token hashes corresponding to the tokens that can be used to authenticate calls to this service. Hashes are made with SHA-256.", "examples": [ @@ -438,7 +429,6 @@ "object_storages", "vault_url", "vault_token", - "vault_path", "token_hashes", "db_prefix", "db_connection_str" diff --git a/example_config.yaml b/example_config.yaml index a405819..542652a 100644 --- a/example_config.yaml +++ b/example_config.yaml @@ -46,7 +46,6 @@ service_instance_id: '1' service_name: sms token_hashes: - 7ad83b6b9183c91674eec897935bc154ba9ff9704f8be0840e77f476b5062b6e -vault_path: sms vault_token: dev-token vault_url: http://vault:8200 workers: 1 diff --git a/openapi.yaml b/openapi.yaml index 182872a..57e999c 100644 --- a/openapi.yaml +++ b/openapi.yaml @@ -383,22 +383,50 @@ paths: tags: - StateManagementService - sms-s3 - /secrets/: + /secrets/{vault_path}: delete: - description: Delete one or more secrets from the vault + description: Delete all secrets from the specified vault. operationId: delete_secrets + parameters: + - in: path + name: vault_path + required: true + schema: + description: The path to the vault + examples: + - ekss + - sms + title: Vault Path + type: string responses: '204': description: Successful Response + '422': + content: + application/json: + schema: + $ref: '#/components/schemas/HTTPValidationError' + description: Validation Error security: - HTTPBearer: [] - summary: Delete all secrets from the vault + summary: Delete all secrets from the specified vault. tags: - StateManagementService - sms-vault get: - description: Returns a list of secrets in the vault + description: Returns a list of secrets in the specified vault operationId: get_secrets + parameters: + - in: path + name: vault_path + required: true + schema: + description: The path to the vault + examples: + - ekss + - sms + title: Vault Path + type: string responses: '200': content: @@ -409,6 +437,12 @@ paths: title: Response Get Secrets type: array description: Successful Response + '422': + content: + application/json: + schema: + $ref: '#/components/schemas/HTTPValidationError' + description: Validation Error security: - HTTPBearer: [] summary: Returns a list of secrets in the vault diff --git a/src/sms/adapters/inbound/fastapi_/routers/secrets.py b/src/sms/adapters/inbound/fastapi_/routers/secrets.py index 994d4c2..2e7fb8e 100644 --- a/src/sms/adapters/inbound/fastapi_/routers/secrets.py +++ b/src/sms/adapters/inbound/fastapi_/routers/secrets.py @@ -18,6 +18,7 @@ from typing import Annotated from fastapi import APIRouter, HTTPException, status +from pydantic import Field from sms.adapters.inbound.fastapi_ import dummies from sms.adapters.inbound.fastapi_.http_authorization import ( @@ -27,9 +28,13 @@ secrets_router = APIRouter() +vault_path_field = Field( + default=..., description="The path to the vault", examples=["ekss", "sms"] +) + @secrets_router.get( - "/", + "/{vault_path}", operation_id="get_secrets", summary="Returns a list of secrets in the vault", status_code=status.HTTP_200_OK, @@ -38,26 +43,28 @@ async def get_secrets( secrets_handler: dummies.SecretsHandlerPortDummy, _token: Annotated[TokenAuthContext, require_token], + vault_path: Annotated[str, vault_path_field], ): - """Returns a list of secrets in the vault""" + """Returns a list of secrets in the specified vault""" try: - return secrets_handler.get_secrets() + return secrets_handler.get_secrets(vault_path) except Exception as exc: raise HTTPException(status_code=status.HTTP_500_INTERNAL_SERVER_ERROR) from exc @secrets_router.delete( - "/", + "/{vault_path}", operation_id="delete_secrets", - summary="Delete all secrets from the vault", + summary="""Delete all secrets from the specified vault.""", status_code=status.HTTP_204_NO_CONTENT, ) async def delete_secrets( secrets_handler: dummies.SecretsHandlerPortDummy, _token: Annotated[TokenAuthContext, require_token], + vault_path: Annotated[str, vault_path_field], ): - """Delete one or more secrets from the vault""" + """Delete all secrets from the specified vault.""" try: - secrets_handler.delete_secrets() + secrets_handler.delete_secrets(vault_path) except Exception as exc: raise HTTPException(status_code=status.HTTP_500_INTERNAL_SERVER_ERROR) from exc diff --git a/src/sms/core/secrets_handler.py b/src/sms/core/secrets_handler.py index 26e7635..5ce880d 100644 --- a/src/sms/core/secrets_handler.py +++ b/src/sms/core/secrets_handler.py @@ -35,9 +35,6 @@ class VaultConfig(BaseSettings): vault_token: str = Field( default=..., description="Token for the Vault", examples=["dev-token"] ) - vault_path: str = Field( - default=..., description="Path for the Vault", examples=["sms", "ekss"] - ) class SecretsHandler(SecretsHandlerPort): @@ -52,31 +49,29 @@ def client(self) -> HvacClient: """Return an instance of a vault client""" return HvacClient(self._config.vault_url, self._config.vault_token) - def get_secrets(self) -> list[str]: - """Return the IDs of all secrets in the vault.""" + def get_secrets(self, vault_path: str) -> list[str]: + """Return the IDs of all secrets in the specified vault.""" try: - secrets = self.client.secrets.kv.v2.list_secrets( - path=self._config.vault_path - ) + secrets = self.client.secrets.kv.v2.list_secrets(path=vault_path) secret_ids = secrets["data"]["keys"] return secret_ids except InvalidPath: msg = ( - "Invalid path error when fetching secrets. The path might be invalid," - + " or no secrets may exist." + "Invalid path error when fetching secrets. The path, '%s', might" + + " be invalid, or no secrets may exist." ) - log.warning(msg) + log.warning(msg, vault_path) return [] - def delete_secrets(self): - """Delete all secrets from the vault.""" - secrets = self.get_secrets() + def delete_secrets(self, vault_path: str): + """Delete all secrets from the specified vault.""" + secrets = self.get_secrets(vault_path) if not secrets: - log.info("No secrets to delete") + log.info("No secrets to delete from vault path '%s'", vault_path) return for secret in secrets: self.client.secrets.kv.v2.delete_metadata_and_all_versions( - path=f"{self._config.vault_path}/{secret}" + path=f"{vault_path}/{secret}" ) diff --git a/src/sms/ports/inbound/secrets_handler.py b/src/sms/ports/inbound/secrets_handler.py index 15b770d..09631af 100644 --- a/src/sms/ports/inbound/secrets_handler.py +++ b/src/sms/ports/inbound/secrets_handler.py @@ -24,9 +24,9 @@ class SecretsHandlerPort(ABC): """A class to interact with a HashiCorp Vault.""" @abstractmethod - def get_secrets(self) -> list[str]: - """Return the IDs of all secrets in the vault.""" + def get_secrets(self, vault_path: str) -> list[str]: + """Returns a list of secrets in the specified vault""" @abstractmethod - def delete_secrets(self): - """Delete all secrets from the vault.""" + def delete_secrets(self, vault_path: str) -> None: + """Delete all secrets from the specified vault.""" diff --git a/tests/fixtures/dummies.py b/tests/fixtures/dummies.py index 95e70d0..5b19dfc 100644 --- a/tests/fixtures/dummies.py +++ b/tests/fixtures/dummies.py @@ -29,26 +29,30 @@ class DummySecretsHandler(SecretsHandlerPort): """Dummy SecretsHandler implementation for testing. It can be set to fail when `get_secrets` is called to mimic an error. + `secrets` is a dictionary that maps vault paths to lists of secrets. """ def __init__( - self, secrets: list[str] | None = None, fail_on_get_secrets: bool = False + self, + secrets: dict[str, list[str]] | None = None, + fail_on_get_secrets: bool = False, ): - self.secrets = secrets if secrets else [] + self.secrets = secrets if secrets else {} self.fail_on_get_secrets = fail_on_get_secrets - def get_secrets(self) -> list[str]: + def get_secrets(self, vault_path: str) -> list[str]: """Get all secrets currently stored. If `fail_on_get_secrets` is set, it will raise an `InvalidPath` error. """ if self.fail_on_get_secrets: raise InvalidPath("Testing failure") - return self.secrets - def delete_secrets(self) -> None: + return self.secrets.get(vault_path, []) + + def delete_secrets(self, vault_path: str) -> None: """Delete all secrets stored in the vault.""" - self.secrets = [] + self.secrets.pop(vault_path, None) @dataclass diff --git a/tests/fixtures/test_config.yaml b/tests/fixtures/test_config.yaml index 20d056b..632a3d4 100644 --- a/tests/fixtures/test_config.yaml +++ b/tests/fixtures/test_config.yaml @@ -4,7 +4,7 @@ token_hashes: - 7ad83b6b9183c91674eec897935bc154ba9ff9704f8be0840e77f476b5062b6e vault_token: "dev-token" vault_url: "http://vault:8200" -vault_path: sms + db_connection_str: mongodb://mongodb:27017 db_prefix: "test_" db_permissions: diff --git a/tests/fixtures/vault.py b/tests/fixtures/vault.py index 218a5e3..651e42b 100644 --- a/tests/fixtures/vault.py +++ b/tests/fixtures/vault.py @@ -29,34 +29,46 @@ DEFAULT_URL = "http://0.0.0.0:8200" DEFAULT_PORT = 8200 DEFAULT_TOKEN = "dev-token" +DEFAULT_VAULT_PATH = "sms" class VaultFixture: - """Contains initialized vault client""" + """Contains initialized vault client. + + When a vault secret is stored, the vault path is stored in vaults_used. + """ def __init__(self, config: VaultConfig): self.config = config + self.vaults_used: set[str] = set() - def store_secret(self, key: str): + def store_secret(self, *, key: str, vault_path: str = DEFAULT_VAULT_PATH): """Store a secret in vault""" client = hvac.Client(url=self.config.vault_url, token=DEFAULT_TOKEN) client.secrets.kv.v2.create_or_update_secret( - path=f"{self.config.vault_path}/{key}", + path=f"{vault_path}/{key}", secret={key: f"secret_for_{key}"}, ) + self.vaults_used.add(vault_path) - def delete_all_secrets(self): + def delete_all_secrets(self, vault_path: str): """Remove all secrets from the vault to reset for next test""" client = hvac.Client(url=self.config.vault_url, token=DEFAULT_TOKEN) with suppress(InvalidPath): - secrets = client.secrets.kv.v2.list_secrets(path=self.config.vault_path) + secrets = client.secrets.kv.v2.list_secrets(path=vault_path) for key in secrets["data"]["keys"]: client.secrets.kv.v2.delete_metadata_and_all_versions( - path=f"{self.config.vault_path}/{key}" + path=f"{vault_path}/{key}" ) + def reset(self): + """Reset the vault for next test""" + for vault_path in self.vaults_used: + self.delete_all_secrets(vault_path) + self.vaults_used.clear() + class VaultContainer(DockerContainer): """A hashi corp vault container for testing.""" @@ -84,7 +96,6 @@ def vault_container_fixture() -> Generator[VaultContainerFixture, None, None]: port = vault_container.get_exposed_port(DEFAULT_PORT) vault_container.config = VaultConfig( vault_url=f"http://{host}:{port}", - vault_path="sms", vault_token=DEFAULT_TOKEN, ) @@ -99,5 +110,5 @@ def vault_fixture( ) -> Generator[VaultFixture, None, None]: """Fixture function to produce a VaultFixture""" vault = VaultFixture(config=vault_container.config) - vault.delete_all_secrets() + vault.reset() yield vault diff --git a/tests/integration/test_secrets.py b/tests/integration/test_secrets.py index efc6b2a..0363940 100644 --- a/tests/integration/test_secrets.py +++ b/tests/integration/test_secrets.py @@ -23,12 +23,13 @@ from tests.fixtures.config import get_config from tests.fixtures.utils import VALID_BEARER_TOKEN from tests.fixtures.vault import ( # noqa: F401 + DEFAULT_VAULT_PATH, VaultFixture, vault_container_fixture, vault_fixture, ) -TEST_URL = "/secrets/" +TEST_URL = f"/secrets/{DEFAULT_VAULT_PATH}" pytestmark = pytest.mark.asyncio() HEADERS: dict[str, Any] = {"Authorization": VALID_BEARER_TOKEN} @@ -44,7 +45,7 @@ async def test_happy_get(vault_fixture: VaultFixture, stored_secrets: list[str]) config = get_config(sources=[vault_fixture_config]) for secret in stored_secrets: - vault_fixture.store_secret(secret) + vault_fixture.store_secret(key=secret) async with ( prepare_rest_app(config=config) as app, @@ -70,7 +71,7 @@ async def test_happy_delete( # Store the secrets in the vault for secret in stored_secrets: - vault_fixture.store_secret(secret) + vault_fixture.store_secret(key=secret) async with ( prepare_rest_app(config=config) as app, @@ -84,3 +85,20 @@ async def test_happy_delete( response = await client.get(TEST_URL, headers=HEADERS) assert response.status_code == 200 assert response.json() == [] + + +async def test_nonexistent_vault_path(vault_fixture: VaultFixture): # noqa: F811 + """Ensure both endpoint return the right response when `vault_path` doesn't exist.""" + vault_fixture_config = vault_fixture.config + config = get_config(sources=[vault_fixture_config]) + + async with ( + prepare_rest_app(config=config) as app, + AsyncTestClient(app=app) as client, + ): + response = await client.get("/secrets/doesnotexist", headers=HEADERS) + assert response.status_code == 200 + assert response.json() == [] + + response = await client.delete("/secrets/doesnotexist", headers=HEADERS) + assert response.status_code == 204 diff --git a/tests/unit/secrets/test_rest_secrets.py b/tests/unit/secrets/test_rest_secrets.py index 248087d..24da66b 100644 --- a/tests/unit/secrets/test_rest_secrets.py +++ b/tests/unit/secrets/test_rest_secrets.py @@ -21,15 +21,16 @@ from tests.fixtures.config import DEFAULT_TEST_CONFIG from tests.fixtures.dummies import DummySecretsHandler from tests.fixtures.utils import VALID_BEARER_TOKEN, get_rest_client_with_mocks +from tests.fixtures.vault import DEFAULT_VAULT_PATH pytestmark = pytest.mark.asyncio() -TEST_URL = "/secrets/" +TEST_URL = f"/secrets/{DEFAULT_VAULT_PATH}" HEADERS: dict[str, Any] = {"Authorization": VALID_BEARER_TOKEN} @pytest.mark.parametrize( - "secrets", + "stored_secrets", [ [], ["secret1"], @@ -41,27 +42,17 @@ "TwoSecrets", ], ) -async def test_get_secrets(secrets: list[str]): +async def test_get_secrets(stored_secrets: list[str]): """Test the GET secrets endpoint without errors.""" - secrets_handler = DummySecretsHandler(secrets=secrets) + vault_path_and_secrets = {DEFAULT_VAULT_PATH: stored_secrets} + secrets_handler = DummySecretsHandler(secrets=vault_path_and_secrets) async with get_rest_client_with_mocks( config=DEFAULT_TEST_CONFIG, secrets_handler_override=secrets_handler ) as client: response = await client.get(TEST_URL, headers=HEADERS) assert response.status_code == 200 - assert response.json() == secrets - - -async def test_get_secrets_error(): - """Test the GET secrets endpoint with an error.""" - secrets_handler = DummySecretsHandler(fail_on_get_secrets=True) - async with get_rest_client_with_mocks( - config=DEFAULT_TEST_CONFIG, secrets_handler_override=secrets_handler - ) as client: - response = await client.get(TEST_URL, headers=HEADERS) - - assert response.status_code == 500 + assert response.json() == stored_secrets @pytest.mark.parametrize( @@ -74,14 +65,15 @@ async def test_get_secrets_error(): ) async def test_delete_secrets(stored_secrets: list[str]): """Test the DELETE secrets endpoint without errors.""" - secrets_handler = DummySecretsHandler(secrets=stored_secrets) + vault_path_and_secrets = {DEFAULT_VAULT_PATH: stored_secrets} + secrets_handler = DummySecretsHandler(secrets=vault_path_and_secrets) async with get_rest_client_with_mocks( config=DEFAULT_TEST_CONFIG, secrets_handler_override=secrets_handler ) as client: response = await client.delete(TEST_URL, headers=HEADERS) assert response.status_code == 204 - assert secrets_handler.secrets == [] + assert secrets_handler.secrets.get(DEFAULT_VAULT_PATH, []) == [] async def test_delete_secrets_error(): diff --git a/tests/unit/secrets/test_secrets_handler.py b/tests/unit/secrets/test_secrets_handler.py index b004ee6..ac0cfeb 100644 --- a/tests/unit/secrets/test_secrets_handler.py +++ b/tests/unit/secrets/test_secrets_handler.py @@ -22,6 +22,7 @@ from sms.core.secrets_handler import SecretsHandler from tests.fixtures.config import DEFAULT_TEST_CONFIG +from tests.fixtures.vault import DEFAULT_VAULT_PATH @pytest.mark.parametrize( @@ -37,7 +38,7 @@ def test_get_secrets(monkeypatch: pytest.MonkeyPatch, secrets: list[str]): monkeypatch.setattr(SecretsHandler, "client", mock_client) secrets_handler = SecretsHandler(config=DEFAULT_TEST_CONFIG) - assert secrets_handler.get_secrets() == secrets + assert secrets_handler.get_secrets(DEFAULT_VAULT_PATH) == secrets mock_client.secrets.kv.v2.list_secrets.assert_called_once() @@ -51,11 +52,11 @@ def test_get_secrets_error(monkeypatch: pytest.MonkeyPatch, caplog): # Make sure the error is logged as a warning but an empty list is still returned caplog.clear() - secrets = secrets_handler.get_secrets() + secrets = secrets_handler.get_secrets(DEFAULT_VAULT_PATH) assert len(caplog.messages) == 1 assert caplog.messages[0] == ( - "Invalid path error when fetching secrets. The path might be invalid," - + " or no secrets may exist." + f"Invalid path error when fetching secrets. The path, '{DEFAULT_VAULT_PATH}'," + + " might be invalid, or no secrets may exist." ) assert caplog.records[0].levelname == "WARNING" assert secrets == [] @@ -71,7 +72,7 @@ def test_delete_secrets_error(monkeypatch: pytest.MonkeyPatch): secrets_handler = SecretsHandler(config=DEFAULT_TEST_CONFIG) # Call delete_secrets() in order to trigger get_secrets - secrets_handler.delete_secrets() + secrets_handler.delete_secrets(DEFAULT_VAULT_PATH) mock_client.secrets.kv.v2.list_secrets.assert_called_once() mock_client.secrets.kv.v2.delete_metadata_and_all_versions.assert_not_called() @@ -101,13 +102,12 @@ def test_delete_successful( secrets_handler = SecretsHandler(config=DEFAULT_TEST_CONFIG) # call delete_secrets() - secrets_handler.delete_secrets() + secrets_handler.delete_secrets(DEFAULT_VAULT_PATH) mock_client.secrets.kv.v2.list_secrets.assert_called_once() # delete_metadata_and_all_versions is called for each secret internal_deletion_calls = [ - call(path=f"{DEFAULT_TEST_CONFIG.vault_path}/{secret}") - for secret in stored_secrets + call(path=f"{DEFAULT_VAULT_PATH}/{secret}") for secret in stored_secrets ] mock_client.secrets.kv.v2.delete_metadata_and_all_versions.assert_has_calls( internal_deletion_calls, From 6639301b8384ae06fa8c3e9a8ec1f1b960eef473 Mon Sep 17 00:00:00 2001 From: TheByronHimes Date: Tue, 29 Oct 2024 15:20:27 +0000 Subject: [PATCH 13/15] Delete unused dummy test functionality and a test --- tests/fixtures/dummies.py | 12 +----------- tests/unit/secrets/test_rest_secrets.py | 16 ---------------- 2 files changed, 1 insertion(+), 27 deletions(-) diff --git a/tests/fixtures/dummies.py b/tests/fixtures/dummies.py index 5b19dfc..63c4c52 100644 --- a/tests/fixtures/dummies.py +++ b/tests/fixtures/dummies.py @@ -17,7 +17,6 @@ from dataclasses import dataclass from hexkit.custom_types import JsonObject -from hvac.exceptions import InvalidPath from sms.models import Criteria, UpsertionDetails from sms.ports.inbound.docs_handler import DocsHandlerPort @@ -28,26 +27,17 @@ class DummySecretsHandler(SecretsHandlerPort): """Dummy SecretsHandler implementation for testing. - It can be set to fail when `get_secrets` is called to mimic an error. `secrets` is a dictionary that maps vault paths to lists of secrets. """ def __init__( self, secrets: dict[str, list[str]] | None = None, - fail_on_get_secrets: bool = False, ): self.secrets = secrets if secrets else {} - self.fail_on_get_secrets = fail_on_get_secrets def get_secrets(self, vault_path: str) -> list[str]: - """Get all secrets currently stored. - - If `fail_on_get_secrets` is set, it will raise an `InvalidPath` error. - """ - if self.fail_on_get_secrets: - raise InvalidPath("Testing failure") - + """Get all secrets currently stored for the specified vault.""" return self.secrets.get(vault_path, []) def delete_secrets(self, vault_path: str) -> None: diff --git a/tests/unit/secrets/test_rest_secrets.py b/tests/unit/secrets/test_rest_secrets.py index 24da66b..a8a0949 100644 --- a/tests/unit/secrets/test_rest_secrets.py +++ b/tests/unit/secrets/test_rest_secrets.py @@ -74,19 +74,3 @@ async def test_delete_secrets(stored_secrets: list[str]): assert response.status_code == 204 assert secrets_handler.secrets.get(DEFAULT_VAULT_PATH, []) == [] - - -async def test_delete_secrets_error(): - """Test the DELETE secrets endpoint with an error. - - This is triggered by setting the `fail_on_get_secrets` flag to True. - The `get_secrets` method will raise an exception, but the `delete_secrets` - method should still return a 204 status code. - """ - secrets_handler = DummySecretsHandler(fail_on_get_secrets=True) - async with get_rest_client_with_mocks( - config=DEFAULT_TEST_CONFIG, secrets_handler_override=secrets_handler - ) as client: - response = await client.delete(TEST_URL, headers=HEADERS) - - assert response.status_code == 204 From 14d37adb27ad2c16b1a520375a0b0791bade58a0 Mon Sep 17 00:00:00 2001 From: TheByronHimes Date: Tue, 29 Oct 2024 15:23:56 +0000 Subject: [PATCH 14/15] Rename vault fixture to remove pragmas --- tests/fixtures/vault.py | 2 +- tests/integration/test_secrets.py | 19 ++++++++----------- 2 files changed, 9 insertions(+), 12 deletions(-) diff --git a/tests/fixtures/vault.py b/tests/fixtures/vault.py index 651e42b..12348be 100644 --- a/tests/fixtures/vault.py +++ b/tests/fixtures/vault.py @@ -104,7 +104,7 @@ def vault_container_fixture() -> Generator[VaultContainerFixture, None, None]: yield vault_container -@pytest.fixture(scope="function") +@pytest.fixture(scope="function", name="vault") def vault_fixture( vault_container: VaultContainerFixture, ) -> Generator[VaultFixture, None, None]: diff --git a/tests/integration/test_secrets.py b/tests/integration/test_secrets.py index 0363940..a888193 100644 --- a/tests/integration/test_secrets.py +++ b/tests/integration/test_secrets.py @@ -39,13 +39,13 @@ [[], ["key1"], ["key1", "key2"]], ids=["empty", "single", "multiple"], ) -async def test_happy_get(vault_fixture: VaultFixture, stored_secrets: list[str]): # noqa: F811 +async def test_happy_get(vault: VaultFixture, stored_secrets: list[str]): """Test that the GET /secrets endpoint returns the correct response.""" - vault_fixture_config = vault_fixture.config + vault_fixture_config = vault.config config = get_config(sources=[vault_fixture_config]) for secret in stored_secrets: - vault_fixture.store_secret(key=secret) + vault.store_secret(key=secret) async with ( prepare_rest_app(config=config) as app, @@ -61,17 +61,14 @@ async def test_happy_get(vault_fixture: VaultFixture, stored_secrets: list[str]) [[], ["key1"], ["key1", "key2"]], ids=["Empty", "OneKey", "TwoKeys"], ) -async def test_happy_delete( - vault_fixture: VaultFixture, # noqa: F811 - stored_secrets: list[str], -): +async def test_happy_delete(vault: VaultFixture, stored_secrets: list[str]): """Test that the DELETE /secrets endpoint returns the correct response.""" - vault_fixture_config = vault_fixture.config + vault_fixture_config = vault.config config = get_config(sources=[vault_fixture_config]) # Store the secrets in the vault for secret in stored_secrets: - vault_fixture.store_secret(key=secret) + vault.store_secret(key=secret) async with ( prepare_rest_app(config=config) as app, @@ -87,9 +84,9 @@ async def test_happy_delete( assert response.json() == [] -async def test_nonexistent_vault_path(vault_fixture: VaultFixture): # noqa: F811 +async def test_nonexistent_vault_path(vault: VaultFixture): """Ensure both endpoint return the right response when `vault_path` doesn't exist.""" - vault_fixture_config = vault_fixture.config + vault_fixture_config = vault.config config = get_config(sources=[vault_fixture_config]) async with ( From 536198b764f08d1500e106d940e449c3d4167389 Mon Sep 17 00:00:00 2001 From: TheByronHimes Date: Wed, 30 Oct 2024 12:18:45 +0000 Subject: [PATCH 15/15] Remove dummy secrets handler, just use mock --- tests/fixtures/dummies.py | 22 ---------------------- tests/unit/secrets/test_rest_secrets.py | 22 +++++++--------------- 2 files changed, 7 insertions(+), 37 deletions(-) diff --git a/tests/fixtures/dummies.py b/tests/fixtures/dummies.py index 63c4c52..ac84c5e 100644 --- a/tests/fixtures/dummies.py +++ b/tests/fixtures/dummies.py @@ -21,28 +21,6 @@ from sms.models import Criteria, UpsertionDetails from sms.ports.inbound.docs_handler import DocsHandlerPort from sms.ports.inbound.objects_handler import ObjectsHandlerPort, S3ObjectStoragesPort -from sms.ports.inbound.secrets_handler import SecretsHandlerPort - - -class DummySecretsHandler(SecretsHandlerPort): - """Dummy SecretsHandler implementation for testing. - - `secrets` is a dictionary that maps vault paths to lists of secrets. - """ - - def __init__( - self, - secrets: dict[str, list[str]] | None = None, - ): - self.secrets = secrets if secrets else {} - - def get_secrets(self, vault_path: str) -> list[str]: - """Get all secrets currently stored for the specified vault.""" - return self.secrets.get(vault_path, []) - - def delete_secrets(self, vault_path: str) -> None: - """Delete all secrets stored in the vault.""" - self.secrets.pop(vault_path, None) @dataclass diff --git a/tests/unit/secrets/test_rest_secrets.py b/tests/unit/secrets/test_rest_secrets.py index a8a0949..8d620b3 100644 --- a/tests/unit/secrets/test_rest_secrets.py +++ b/tests/unit/secrets/test_rest_secrets.py @@ -15,11 +15,11 @@ """Unit tests for the Vault part of the SMS REST API.""" from typing import Any +from unittest.mock import Mock import pytest from tests.fixtures.config import DEFAULT_TEST_CONFIG -from tests.fixtures.dummies import DummySecretsHandler from tests.fixtures.utils import VALID_BEARER_TOKEN, get_rest_client_with_mocks from tests.fixtures.vault import DEFAULT_VAULT_PATH @@ -44,8 +44,8 @@ ) async def test_get_secrets(stored_secrets: list[str]): """Test the GET secrets endpoint without errors.""" - vault_path_and_secrets = {DEFAULT_VAULT_PATH: stored_secrets} - secrets_handler = DummySecretsHandler(secrets=vault_path_and_secrets) + secrets_handler = Mock() + secrets_handler.get_secrets.return_value = stored_secrets async with get_rest_client_with_mocks( config=DEFAULT_TEST_CONFIG, secrets_handler_override=secrets_handler ) as client: @@ -53,24 +53,16 @@ async def test_get_secrets(stored_secrets: list[str]): assert response.status_code == 200 assert response.json() == stored_secrets + secrets_handler.get_secrets.assert_called_once_with(DEFAULT_VAULT_PATH) -@pytest.mark.parametrize( - "stored_secrets", - [ - [], - ["secret1", "secret2", "secret3"], - ], - ids=["VaultIsEmpty", "VaultHasThreeSecrets"], -) -async def test_delete_secrets(stored_secrets: list[str]): +async def test_delete_secrets(): """Test the DELETE secrets endpoint without errors.""" - vault_path_and_secrets = {DEFAULT_VAULT_PATH: stored_secrets} - secrets_handler = DummySecretsHandler(secrets=vault_path_and_secrets) + secrets_handler = Mock() async with get_rest_client_with_mocks( config=DEFAULT_TEST_CONFIG, secrets_handler_override=secrets_handler ) as client: response = await client.delete(TEST_URL, headers=HEADERS) assert response.status_code == 204 - assert secrets_handler.secrets.get(DEFAULT_VAULT_PATH, []) == [] + secrets_handler.delete_secrets.assert_called_once_with(DEFAULT_VAULT_PATH)