From 1513b227b37631e84d599f585b6ed4ac0c522e01 Mon Sep 17 00:00:00 2001 From: Jonathan Sick Date: Tue, 5 Mar 2024 10:26:16 -0500 Subject: [PATCH 1/5] Update dependencies --- requirements/dev.txt | 838 ++++++++++++++++++++---------------------- requirements/main.txt | 342 ++++++++--------- 2 files changed, 567 insertions(+), 613 deletions(-) diff --git a/requirements/dev.txt b/requirements/dev.txt index eec7522..a373492 100644 --- a/requirements/dev.txt +++ b/requirements/dev.txt @@ -4,9 +4,9 @@ # # pip-compile --allow-unsafe --generate-hashes --output-file=requirements/dev.txt requirements/dev.in # -alabaster==0.7.13 \ - --hash=sha256:1ee19aca801bbabb5ba3f5f258e4422dfa86f82f3e9cefb0859b283cdd7f62a3 \ - --hash=sha256:a27a4a084d5e690e16e01e03ad2b2e552c61a65469419b907243193de1a84ae2 +alabaster==0.7.16 \ + --hash=sha256:75a8b99c28a5dad50dd7f8ccdd447a121ddb3892da9e53d1ca5cca3106d58d65 \ + --hash=sha256:b46733c07dce03ae4e150330b975c75737fa60f0a7c591b6c8bf4928a28e2c92 # via sphinx annotated-types==0.6.0 \ --hash=sha256:0641064de18ba7a25dee8f96403ebc39113d0cb953a01429249d5c7564666a43 \ @@ -14,9 +14,9 @@ annotated-types==0.6.0 \ # via # -c requirements/main.txt # pydantic -anyio==4.2.0 \ - --hash=sha256:745843b39e829e108e518c489b31dc757de7d2131d53fac32bd8df268227bfee \ - --hash=sha256:e1875bb4b4e2de1669f4bc7869b6d3f54231cdced71605e6e64c9be77e3be50f +anyio==4.3.0 \ + --hash=sha256:048e05d0f6caeed70d731f3db756d35dcc1f35747c8c403364a8332c630441b8 \ + --hash=sha256:f75253795a87df48568485fd18cdd2a3fa5c4f7c5be8e5e36637733fce06fed6 # via # -c requirements/main.txt # httpx @@ -36,13 +36,13 @@ babel==2.14.0 \ --hash=sha256:6919867db036398ba21eb5c7a0f6b28ab8cbc3ae7a73a44ebe34ae74a4e7d363 \ --hash=sha256:efb1a25b7118e67ce3a259bed20545c29cb68be8ad2c784c83689981b7a57287 # via sphinx -beautifulsoup4==4.12.2 \ - --hash=sha256:492bbc69dca35d12daac71c4db1bfff0c876c00ef4a2ffacce226d4638eb72da \ - --hash=sha256:bd2520ca0d9d7d12694a53d44ac482d181b4ec1888909b035a3dbf40d0f57d4a +beautifulsoup4==4.12.3 \ + --hash=sha256:74e3d1928edc070d21748185c46e3fb33490f22f52a3addee9aee0f4f7781051 \ + --hash=sha256:b80878c9f40111313e55da8ba20bdba06d8fa3969fc68304167741bbf9e082ed # via pydata-sphinx-theme -certifi==2023.11.17 \ - --hash=sha256:9b469f3a900bf28dc19b8cfbf8019bf47f7fdd1a65a1d4ffb98fc14166beb4d1 \ - --hash=sha256:e036ab49d5b79556f99cfc2d9320b34cfbe5be05c5871b51de9329f0603b0474 +certifi==2024.2.2 \ + --hash=sha256:0569859f95fc761b18b45ef421b1290a0f65f147e92a1e5eb3e635f9a5e4e66f \ + --hash=sha256:dc383c07b76109f368f6106eee2b593b04a011ea4d55f652c6ca24a754d1cdd1 # via # -c requirements/main.txt # httpcore @@ -157,59 +157,59 @@ click-log==0.4.0 \ --hash=sha256:3970f8570ac54491237bcdb3d8ab5e3eef6c057df29f8c3d1151a51a9c23b975 \ --hash=sha256:a43e394b528d52112af599f2fc9e4b7cf3c15f94e53581f74fa6867e68c91756 # via scriv -coverage[toml]==7.4.0 \ - --hash=sha256:04387a4a6ecb330c1878907ce0dc04078ea72a869263e53c72a1ba5bbdf380ca \ - --hash=sha256:0676cd0ba581e514b7f726495ea75aba3eb20899d824636c6f59b0ed2f88c471 \ - --hash=sha256:0e8d06778e8fbffccfe96331a3946237f87b1e1d359d7fbe8b06b96c95a5407a \ - --hash=sha256:0eb3c2f32dabe3a4aaf6441dde94f35687224dfd7eb2a7f47f3fd9428e421058 \ - --hash=sha256:109f5985182b6b81fe33323ab4707011875198c41964f014579cf82cebf2bb85 \ - --hash=sha256:13eaf476ec3e883fe3e5fe3707caeb88268a06284484a3daf8250259ef1ba143 \ - --hash=sha256:164fdcc3246c69a6526a59b744b62e303039a81e42cfbbdc171c91a8cc2f9446 \ - --hash=sha256:26776ff6c711d9d835557ee453082025d871e30b3fd6c27fcef14733f67f0590 \ - --hash=sha256:26f66da8695719ccf90e794ed567a1549bb2644a706b41e9f6eae6816b398c4a \ - --hash=sha256:29f3abe810930311c0b5d1a7140f6395369c3db1be68345638c33eec07535105 \ - --hash=sha256:316543f71025a6565677d84bc4df2114e9b6a615aa39fb165d697dba06a54af9 \ - --hash=sha256:36b0ea8ab20d6a7564e89cb6135920bc9188fb5f1f7152e94e8300b7b189441a \ - --hash=sha256:3cc9d4bc55de8003663ec94c2f215d12d42ceea128da8f0f4036235a119c88ac \ - --hash=sha256:485e9f897cf4856a65a57c7f6ea3dc0d4e6c076c87311d4bc003f82cfe199d25 \ - --hash=sha256:5040148f4ec43644702e7b16ca864c5314ccb8ee0751ef617d49aa0e2d6bf4f2 \ - --hash=sha256:51456e6fa099a8d9d91497202d9563a320513fcf59f33991b0661a4a6f2ad450 \ - --hash=sha256:53d7d9158ee03956e0eadac38dfa1ec8068431ef8058fe6447043db1fb40d932 \ - --hash=sha256:5a10a4920def78bbfff4eff8a05c51be03e42f1c3735be42d851f199144897ba \ - --hash=sha256:5b14b4f8760006bfdb6e08667af7bc2d8d9bfdb648351915315ea17645347137 \ - --hash=sha256:5b2ccb7548a0b65974860a78c9ffe1173cfb5877460e5a229238d985565574ae \ - --hash=sha256:697d1317e5290a313ef0d369650cfee1a114abb6021fa239ca12b4849ebbd614 \ - --hash=sha256:6ae8c9d301207e6856865867d762a4b6fd379c714fcc0607a84b92ee63feff70 \ - --hash=sha256:707c0f58cb1712b8809ece32b68996ee1e609f71bd14615bd8f87a1293cb610e \ - --hash=sha256:74775198b702868ec2d058cb92720a3c5a9177296f75bd97317c787daf711505 \ - --hash=sha256:756ded44f47f330666843b5781be126ab57bb57c22adbb07d83f6b519783b870 \ - --hash=sha256:76f03940f9973bfaee8cfba70ac991825611b9aac047e5c80d499a44079ec0bc \ - --hash=sha256:79287fd95585ed36e83182794a57a46aeae0b64ca53929d1176db56aacc83451 \ - --hash=sha256:799c8f873794a08cdf216aa5d0531c6a3747793b70c53f70e98259720a6fe2d7 \ - --hash=sha256:7d360587e64d006402b7116623cebf9d48893329ef035278969fa3bbf75b697e \ - --hash=sha256:80b5ee39b7f0131ebec7968baa9b2309eddb35b8403d1869e08f024efd883566 \ - --hash=sha256:815ac2d0f3398a14286dc2cea223a6f338109f9ecf39a71160cd1628786bc6f5 \ - --hash=sha256:83c2dda2666fe32332f8e87481eed056c8b4d163fe18ecc690b02802d36a4d26 \ - --hash=sha256:846f52f46e212affb5bcf131c952fb4075b55aae6b61adc9856222df89cbe3e2 \ - --hash=sha256:936d38794044b26c99d3dd004d8af0035ac535b92090f7f2bb5aa9c8e2f5cd42 \ - --hash=sha256:9864463c1c2f9cb3b5db2cf1ff475eed2f0b4285c2aaf4d357b69959941aa555 \ - --hash=sha256:995ea5c48c4ebfd898eacb098164b3cc826ba273b3049e4a889658548e321b43 \ - --hash=sha256:a1526d265743fb49363974b7aa8d5899ff64ee07df47dd8d3e37dcc0818f09ed \ - --hash=sha256:a56de34db7b7ff77056a37aedded01b2b98b508227d2d0979d373a9b5d353daa \ - --hash=sha256:a7c97726520f784239f6c62506bc70e48d01ae71e9da128259d61ca5e9788516 \ - --hash=sha256:b8e99f06160602bc64da35158bb76c73522a4010f0649be44a4e167ff8555952 \ - --hash=sha256:bb1de682da0b824411e00a0d4da5a784ec6496b6850fdf8c865c1d68c0e318dd \ - --hash=sha256:bf477c355274a72435ceb140dc42de0dc1e1e0bf6e97195be30487d8eaaf1a09 \ - --hash=sha256:bf635a52fc1ea401baf88843ae8708591aa4adff875e5c23220de43b1ccf575c \ - --hash=sha256:bfd5db349d15c08311702611f3dccbef4b4e2ec148fcc636cf8739519b4a5c0f \ - --hash=sha256:c530833afc4707fe48524a44844493f36d8727f04dcce91fb978c414a8556cc6 \ - --hash=sha256:cc6d65b21c219ec2072c1293c505cf36e4e913a3f936d80028993dd73c7906b1 \ - --hash=sha256:cd3c1e4cb2ff0083758f09be0f77402e1bdf704adb7f89108007300a6da587d0 \ - --hash=sha256:cfd2a8b6b0d8e66e944d47cdec2f47c48fef2ba2f2dff5a9a75757f64172857e \ - --hash=sha256:d0ca5c71a5a1765a0f8f88022c52b6b8be740e512980362f7fdbb03725a0d6b9 \ - --hash=sha256:e7defbb9737274023e2d7af02cac77043c86ce88a907c58f42b580a97d5bcca9 \ - --hash=sha256:e9d1bf53c4c8de58d22e0e956a79a5b37f754ed1ffdbf1a260d9dcfa2d8a325e \ - --hash=sha256:ea81d8f9691bb53f4fb4db603203029643caffc82bf998ab5b59ca05560f4c06 +coverage[toml]==7.4.3 \ + --hash=sha256:0209a6369ccce576b43bb227dc8322d8ef9e323d089c6f3f26a597b09cb4d2aa \ + --hash=sha256:062b0a75d9261e2f9c6d071753f7eef0fc9caf3a2c82d36d76667ba7b6470003 \ + --hash=sha256:0842571634f39016a6c03e9d4aba502be652a6e4455fadb73cd3a3a49173e38f \ + --hash=sha256:16bae383a9cc5abab9bb05c10a3e5a52e0a788325dc9ba8499e821885928968c \ + --hash=sha256:18c7320695c949de11a351742ee001849912fd57e62a706d83dfc1581897fa2e \ + --hash=sha256:18d90523ce7553dd0b7e23cbb28865db23cddfd683a38fb224115f7826de78d0 \ + --hash=sha256:1bf25fbca0c8d121a3e92a2a0555c7e5bc981aee5c3fdaf4bb7809f410f696b9 \ + --hash=sha256:276f6077a5c61447a48d133ed13e759c09e62aff0dc84274a68dc18660104d52 \ + --hash=sha256:280459f0a03cecbe8800786cdc23067a8fc64c0bd51dc614008d9c36e1659d7e \ + --hash=sha256:28ca2098939eabab044ad68850aac8f8db6bf0b29bc7f2887d05889b17346454 \ + --hash=sha256:2c854ce44e1ee31bda4e318af1dbcfc929026d12c5ed030095ad98197eeeaed0 \ + --hash=sha256:35eb581efdacf7b7422af677b92170da4ef34500467381e805944a3201df2079 \ + --hash=sha256:37389611ba54fd6d278fde86eb2c013c8e50232e38f5c68235d09d0a3f8aa352 \ + --hash=sha256:3b253094dbe1b431d3a4ac2f053b6d7ede2664ac559705a704f621742e034f1f \ + --hash=sha256:3b2eccb883368f9e972e216c7b4c7c06cabda925b5f06dde0650281cb7666a30 \ + --hash=sha256:451f433ad901b3bb00184d83fd83d135fb682d780b38af7944c9faeecb1e0bfe \ + --hash=sha256:489763b2d037b164846ebac0cbd368b8a4ca56385c4090807ff9fad817de4113 \ + --hash=sha256:4af154d617c875b52651dd8dd17a31270c495082f3d55f6128e7629658d63765 \ + --hash=sha256:506edb1dd49e13a2d4cac6a5173317b82a23c9d6e8df63efb4f0380de0fbccbc \ + --hash=sha256:6679060424faa9c11808598504c3ab472de4531c571ab2befa32f4971835788e \ + --hash=sha256:69b9f6f66c0af29642e73a520b6fed25ff9fd69a25975ebe6acb297234eda501 \ + --hash=sha256:6c00cdc8fa4e50e1cc1f941a7f2e3e0f26cb2a1233c9696f26963ff58445bac7 \ + --hash=sha256:6c0cdedd3500e0511eac1517bf560149764b7d8e65cb800d8bf1c63ebf39edd2 \ + --hash=sha256:708a3369dcf055c00ddeeaa2b20f0dd1ce664eeabde6623e516c5228b753654f \ + --hash=sha256:718187eeb9849fc6cc23e0d9b092bc2348821c5e1a901c9f8975df0bc785bfd4 \ + --hash=sha256:767b35c3a246bcb55b8044fd3a43b8cd553dd1f9f2c1eeb87a302b1f8daa0524 \ + --hash=sha256:77fbfc5720cceac9c200054b9fab50cb2a7d79660609200ab83f5db96162d20c \ + --hash=sha256:7cbde573904625509a3f37b6fecea974e363460b556a627c60dc2f47e2fffa51 \ + --hash=sha256:8249b1c7334be8f8c3abcaaa996e1e4927b0e5a23b65f5bf6cfe3180d8ca7840 \ + --hash=sha256:8580b827d4746d47294c0e0b92854c85a92c2227927433998f0d3320ae8a71b6 \ + --hash=sha256:8640f1fde5e1b8e3439fe482cdc2b0bb6c329f4bb161927c28d2e8879c6029ee \ + --hash=sha256:9a9babb9466fe1da12417a4aed923e90124a534736de6201794a3aea9d98484e \ + --hash=sha256:a78ed23b08e8ab524551f52953a8a05d61c3a760781762aac49f8de6eede8c45 \ + --hash=sha256:abbbd8093c5229c72d4c2926afaee0e6e3140de69d5dcd918b2921f2f0c8baba \ + --hash=sha256:ae7f19afe0cce50039e2c782bff379c7e347cba335429678450b8fe81c4ef96d \ + --hash=sha256:b3ec74cfef2d985e145baae90d9b1b32f85e1741b04cd967aaf9cfa84c1334f3 \ + --hash=sha256:b51bfc348925e92a9bd9b2e48dad13431b57011fd1038f08316e6bf1df107d10 \ + --hash=sha256:b9a4a8dd3dcf4cbd3165737358e4d7dfbd9d59902ad11e3b15eebb6393b0446e \ + --hash=sha256:ba3a8aaed13770e970b3df46980cb068d1c24af1a1968b7818b69af8c4347efb \ + --hash=sha256:c0524de3ff096e15fcbfe8f056fdb4ea0bf497d584454f344d59fce069d3e6e9 \ + --hash=sha256:c0a120238dd71c68484f02562f6d446d736adcc6ca0993712289b102705a9a3a \ + --hash=sha256:cbbe5e739d45a52f3200a771c6d2c7acf89eb2524890a4a3aa1a7fa0695d2a47 \ + --hash=sha256:ce8c50520f57ec57aa21a63ea4f325c7b657386b3f02ccaedeccf9ebe27686e1 \ + --hash=sha256:cf30900aa1ba595312ae41978b95e256e419d8a823af79ce670835409fc02ad3 \ + --hash=sha256:d25b937a5d9ffa857d41be042b4238dd61db888533b53bc76dc082cb5a15e914 \ + --hash=sha256:d6cdecaedea1ea9e033d8adf6a0ab11107b49571bbb9737175444cea6eb72328 \ + --hash=sha256:dec9de46a33cf2dd87a5254af095a409ea3bf952d85ad339751e7de6d962cde6 \ + --hash=sha256:ebe7c9e67a2d15fa97b77ea6571ce5e1e1f6b0db71d1d5e96f8d2bf134303c1d \ + --hash=sha256:ee866acc0861caebb4f2ab79f0b94dbfbdbfadc19f82e6e9c93930f74e11d7a0 \ + --hash=sha256:f6a09b360d67e589236a44f0c39218a8efba2593b6abdccc300a8862cffc2f94 \ + --hash=sha256:fcc66e222cf4c719fe7722a403888b1f5e1682d1679bd780e2b26c18bb648cdc \ + --hash=sha256:fd6545d97c98a192c5ac995d21c894b581f1fd14cf389be90724d21808b657e2 # via # -r requirements/dev.in # pytest-cov @@ -217,12 +217,10 @@ distlib==0.3.8 \ --hash=sha256:034db59a0b96f8ca18035f36290806a9a6e6bd9d1ff91e45a7f172eb17e51784 \ --hash=sha256:1530ea13e350031b6312d8580ddb6b27a104275a31106523b8f123787f494f64 # via virtualenv -documenteer[guide]==1.0.1 \ - --hash=sha256:0d6bf2947456fd3456d86790874d7aab24c8f33d5b69a1f4d40bfb88a714f900 \ - --hash=sha256:d581fb54b6205daec69b4515b5a71e15781dfff1c2dd1f59fa28de1d2b2d4eb9 - # via - # -r requirements/dev.in - # documenteer +documenteer[guide]==1.1.1 \ + --hash=sha256:398b7aec72dbc5a073b8b83e632384ecbba3dccc3f373ff15a98459f95aa7396 \ + --hash=sha256:547232b01111de8b88afa6347e376b524b08b93c7ef4b4364b09ecd7ab118c8f + # via -r requirements/dev.in docutils==0.20.1 \ --hash=sha256:96f387a2c5562db4476f09f13bbab2192e764cac08ebbf3a34a95d9b1e4a59d6 \ --hash=sha256:f08a4e276c3a1583a86dce3e34aba3fe04d02bba2dd51ed16106244e8a923e3b @@ -243,9 +241,9 @@ gitdb==4.0.11 \ --hash=sha256:81a3407ddd2ee8df444cbacea00e2d038e40150acfa3001696fe0dcf1d3adfa4 \ --hash=sha256:bf5421126136d6d0af55bc1e7c1af1c397a34f5b7bd79e776cd3e89785c2b04b # via gitpython -gitpython==3.1.40 \ - --hash=sha256:22b126e9ffb671fdd0c129796343a02bf67bf2994b35449ffc9321aa755e18a4 \ - --hash=sha256:cf14627d5a8049ffbf49915732e5eddbe8134c3bdb9d476e6182b676fc573f8a +gitpython==3.1.42 \ + --hash=sha256:1bf9cd7c9e7255f77778ea54359e54ac22a72a5b51288c457c881057b7bb9ecd \ + --hash=sha256:2d99869e0fef71a73cbd242528105af1d6c1b108c60dfabd994bf292f76c3ceb # via documenteer h11==0.14.0 \ --hash=sha256:8f19fbbe99e72420ff35c00b27a34cb9937e902a8b810e2c88300c6f0a3b699d \ @@ -254,22 +252,22 @@ h11==0.14.0 \ # -c requirements/main.txt # httpcore # uvicorn -httpcore==1.0.2 \ - --hash=sha256:096cc05bca73b8e459a1fc3dcf585148f63e534eae4339559c9b8a8d6399acc7 \ - --hash=sha256:9fc092e4799b26174648e54b74ed5f683132a464e95643b226e00c2ed2fa6535 +httpcore==1.0.4 \ + --hash=sha256:ac418c1db41bade2ad53ae2f3834a3a0f5ae76b56cf5aa497d2d033384fc7d73 \ + --hash=sha256:cb2839ccfcba0d2d3c1131d3c3e26dfc327326fbe7a5dc0dbfe9f6c9151bb022 # via # -c requirements/main.txt # httpx -httpx==0.26.0 \ - --hash=sha256:451b55c30d5185ea6b23c2c793abf9bb237d2a7dfb901ced6ff69ad37ec1dfaf \ - --hash=sha256:8915f5a3627c4d47b73e8202457cb28f1266982d1159bd5779d86a80c0eab1cd +httpx==0.27.0 \ + --hash=sha256:71d5465162c13681bff01ad59b2cc68dd838ea1f10e51574bac27103f00c91a5 \ + --hash=sha256:a0cb88a46f32dc874e04ee956e4c2764aba2aa228f650b06788ba6bda2962ab5 # via # -c requirements/main.txt # -r requirements/dev.in # respx -identify==2.5.33 \ - --hash=sha256:161558f9fe4559e1557e1bff323e8631f6a0e4837f7497767c1782832f16b62d \ - --hash=sha256:d40ce5fcd762817627670da8a7d8d8e65f24342d14539c59488dc603bf662e34 +identify==2.5.35 \ + --hash=sha256:10a7ca245cfcd756a554a7288159f72ff105ad233c7c4b9c6f0f4d108f5f6791 \ + --hash=sha256:c4de0081837b211594f8e877a6b4fad7ca32bbfc1a9307fdd61c28bfe923f13e # via pre-commit idna==3.6 \ --hash=sha256:9ecdbbd083b06798ae1e86adcbfe8ab1479cf864e4ee30fe4e46a003d12491ca \ @@ -287,18 +285,18 @@ iniconfig==2.0.0 \ --hash=sha256:2d91e135bf72d31a410b17c16da610a82cb55f6b0477d1a902134b24a455b8b3 \ --hash=sha256:b6a85871a79d2e3b22d2d1b94ac2824226a63c6b741c88f7ae975f18b6778374 # via pytest -jinja2==3.1.2 \ - --hash=sha256:31351a702a408a9e7595a8fc6150fc3f43bb6bf7e319770cbc0db9df9437e852 \ - --hash=sha256:6088930bfe239f0e6710546ab9c19c9ef35e29792895fed6e6e31a023a182a61 +jinja2==3.1.3 \ + --hash=sha256:7d6d50dd97d52cbc355597bd845fabfbac3f551e1f99619e39a35ce8c370b5fa \ + --hash=sha256:ac8bd6544d4bb2c9792bf3a159e80bba8fda7f07e81bc3aed565432d5925ba90 # via # myst-parser # scriv # sphinx # sphinx-jinja # sphinxcontrib-redoc -jsonschema==4.20.0 \ - --hash=sha256:4f614fd46d8d61258610998997743ec5492a648b33cf478c1ddc23ed4598a5fa \ - --hash=sha256:ed6231f0429ecf966f5bc8dfef245998220549cbbcf140f913b7464c52c3b6b3 +jsonschema==4.21.1 \ + --hash=sha256:7996507afae316306f9e2290407761157c6f78002dcf7419acb99822143d1c6f \ + --hash=sha256:85727c00279f5fa6bedbe6238d2aa6403bedd8b4864ab11207d07df3cc1b2ee5 # via sphinxcontrib-redoc jsonschema-specifications==2023.12.1 \ --hash=sha256:48a76787b3e70f5ed53f1160d2b81f586e4ca6d1548c5de7085d1682674764cc \ @@ -308,9 +306,9 @@ latexcodec==2.0.1 \ --hash=sha256:2aa2551c373261cefe2ad3a8953a6d6533e68238d180eb4bb91d7964adb3fe9a \ --hash=sha256:c277a193638dc7683c4c30f6684e3db728a06efb0dc9cf346db8bd0aa6c5d271 # via pybtex -linkify-it-py==2.0.2 \ - --hash=sha256:19f3060727842c254c808e99d465c80c49d2c7306788140987a1a7a29b0d6ad2 \ - --hash=sha256:a3a24428f6c96f27370d7fe61d2ac0be09017be5190d68d8658233171f1b6541 +linkify-it-py==2.0.3 \ + --hash=sha256:68cda27e162e9215c17d786649d1da0021a451bdc436ef9e0fa0ba5234b9b048 \ + --hash=sha256:6bcbc417b0ac14323382aef5c5192c0075bf8a9d6b41820a2b66371eac6b6d79 # via markdown-it-py markdown-it-py[linkify]==3.0.0 \ --hash=sha256:355216845c60bd96232cd8d8c40e8f9765cc86f46880e43a8fd22dc1a1a8cab1 \ @@ -320,67 +318,67 @@ markdown-it-py[linkify]==3.0.0 \ # mdit-py-plugins # myst-parser # scriv -markupsafe==2.1.3 \ - --hash=sha256:05fb21170423db021895e1ea1e1f3ab3adb85d1c2333cbc2310f2a26bc77272e \ - --hash=sha256:0a4e4a1aff6c7ac4cd55792abf96c915634c2b97e3cc1c7129578aa68ebd754e \ - --hash=sha256:10bbfe99883db80bdbaff2dcf681dfc6533a614f700da1287707e8a5d78a8431 \ - --hash=sha256:134da1eca9ec0ae528110ccc9e48041e0828d79f24121a1a146161103c76e686 \ - --hash=sha256:14ff806850827afd6b07a5f32bd917fb7f45b046ba40c57abdb636674a8b559c \ - --hash=sha256:1577735524cdad32f9f694208aa75e422adba74f1baee7551620e43a3141f559 \ - --hash=sha256:1b40069d487e7edb2676d3fbdb2b0829ffa2cd63a2ec26c4938b2d34391b4ecc \ - --hash=sha256:1b8dd8c3fd14349433c79fa8abeb573a55fc0fdd769133baac1f5e07abf54aeb \ - --hash=sha256:1f67c7038d560d92149c060157d623c542173016c4babc0c1913cca0564b9939 \ - --hash=sha256:282c2cb35b5b673bbcadb33a585408104df04f14b2d9b01d4c345a3b92861c2c \ - --hash=sha256:2c1b19b3aaacc6e57b7e25710ff571c24d6c3613a45e905b1fde04d691b98ee0 \ - --hash=sha256:2ef12179d3a291be237280175b542c07a36e7f60718296278d8593d21ca937d4 \ - --hash=sha256:338ae27d6b8745585f87218a3f23f1512dbf52c26c28e322dbe54bcede54ccb9 \ - --hash=sha256:3c0fae6c3be832a0a0473ac912810b2877c8cb9d76ca48de1ed31e1c68386575 \ - --hash=sha256:3fd4abcb888d15a94f32b75d8fd18ee162ca0c064f35b11134be77050296d6ba \ - --hash=sha256:42de32b22b6b804f42c5d98be4f7e5e977ecdd9ee9b660fda1a3edf03b11792d \ - --hash=sha256:47d4f1c5f80fc62fdd7777d0d40a2e9dda0a05883ab11374334f6c4de38adffd \ - --hash=sha256:504b320cd4b7eff6f968eddf81127112db685e81f7e36e75f9f84f0df46041c3 \ - --hash=sha256:525808b8019e36eb524b8c68acdd63a37e75714eac50e988180b169d64480a00 \ - --hash=sha256:56d9f2ecac662ca1611d183feb03a3fa4406469dafe241673d521dd5ae92a155 \ - --hash=sha256:5bbe06f8eeafd38e5d0a4894ffec89378b6c6a625ff57e3028921f8ff59318ac \ - --hash=sha256:65c1a9bcdadc6c28eecee2c119465aebff8f7a584dd719facdd9e825ec61ab52 \ - --hash=sha256:68e78619a61ecf91e76aa3e6e8e33fc4894a2bebe93410754bd28fce0a8a4f9f \ - --hash=sha256:69c0f17e9f5a7afdf2cc9fb2d1ce6aabdb3bafb7f38017c0b77862bcec2bbad8 \ - --hash=sha256:6b2b56950d93e41f33b4223ead100ea0fe11f8e6ee5f641eb753ce4b77a7042b \ - --hash=sha256:715d3562f79d540f251b99ebd6d8baa547118974341db04f5ad06d5ea3eb8007 \ - --hash=sha256:787003c0ddb00500e49a10f2844fac87aa6ce977b90b0feaaf9de23c22508b24 \ - --hash=sha256:7ef3cb2ebbf91e330e3bb937efada0edd9003683db6b57bb108c4001f37a02ea \ - --hash=sha256:8023faf4e01efadfa183e863fefde0046de576c6f14659e8782065bcece22198 \ - --hash=sha256:8758846a7e80910096950b67071243da3e5a20ed2546e6392603c096778d48e0 \ - --hash=sha256:8afafd99945ead6e075b973fefa56379c5b5c53fd8937dad92c662da5d8fd5ee \ - --hash=sha256:8c41976a29d078bb235fea9b2ecd3da465df42a562910f9022f1a03107bd02be \ - --hash=sha256:8e254ae696c88d98da6555f5ace2279cf7cd5b3f52be2b5cf97feafe883b58d2 \ - --hash=sha256:8f9293864fe09b8149f0cc42ce56e3f0e54de883a9de90cd427f191c346eb2e1 \ - --hash=sha256:9402b03f1a1b4dc4c19845e5c749e3ab82d5078d16a2a4c2cd2df62d57bb0707 \ - --hash=sha256:962f82a3086483f5e5f64dbad880d31038b698494799b097bc59c2edf392fce6 \ - --hash=sha256:9aad3c1755095ce347e26488214ef77e0485a3c34a50c5a5e2471dff60b9dd9c \ - --hash=sha256:9dcdfd0eaf283af041973bff14a2e143b8bd64e069f4c383416ecd79a81aab58 \ - --hash=sha256:aa57bd9cf8ae831a362185ee444e15a93ecb2e344c8e52e4d721ea3ab6ef1823 \ - --hash=sha256:aa7bd130efab1c280bed0f45501b7c8795f9fdbeb02e965371bbef3523627779 \ - --hash=sha256:ab4a0df41e7c16a1392727727e7998a467472d0ad65f3ad5e6e765015df08636 \ - --hash=sha256:ad9e82fb8f09ade1c3e1b996a6337afac2b8b9e365f926f5a61aacc71adc5b3c \ - --hash=sha256:af598ed32d6ae86f1b747b82783958b1a4ab8f617b06fe68795c7f026abbdcad \ - --hash=sha256:b076b6226fb84157e3f7c971a47ff3a679d837cf338547532ab866c57930dbee \ - --hash=sha256:b7ff0f54cb4ff66dd38bebd335a38e2c22c41a8ee45aa608efc890ac3e3931bc \ - --hash=sha256:bfce63a9e7834b12b87c64d6b155fdd9b3b96191b6bd334bf37db7ff1fe457f2 \ - --hash=sha256:c011a4149cfbcf9f03994ec2edffcb8b1dc2d2aede7ca243746df97a5d41ce48 \ - --hash=sha256:c9c804664ebe8f83a211cace637506669e7890fec1b4195b505c214e50dd4eb7 \ - --hash=sha256:ca379055a47383d02a5400cb0d110cef0a776fc644cda797db0c5696cfd7e18e \ - --hash=sha256:cb0932dc158471523c9637e807d9bfb93e06a95cbf010f1a38b98623b929ef2b \ - --hash=sha256:cd0f502fe016460680cd20aaa5a76d241d6f35a1c3350c474bac1273803893fa \ - --hash=sha256:ceb01949af7121f9fc39f7d27f91be8546f3fb112c608bc4029aef0bab86a2a5 \ - --hash=sha256:d080e0a5eb2529460b30190fcfcc4199bd7f827663f858a226a81bc27beaa97e \ - --hash=sha256:dd15ff04ffd7e05ffcb7fe79f1b98041b8ea30ae9234aed2a9168b5797c3effb \ - --hash=sha256:df0be2b576a7abbf737b1575f048c23fb1d769f267ec4358296f31c2479db8f9 \ - --hash=sha256:e09031c87a1e51556fdcb46e5bd4f59dfb743061cf93c4d6831bf894f125eb57 \ - --hash=sha256:e4dd52d80b8c83fdce44e12478ad2e85c64ea965e75d66dbeafb0a3e77308fcc \ - --hash=sha256:f698de3fd0c4e6972b92290a45bd9b1536bffe8c6759c62471efaa8acb4c37bc \ - --hash=sha256:fec21693218efe39aa7f8599346e90c705afa52c5b31ae019b2e57e8f6542bb2 \ - --hash=sha256:ffcc3f7c66b5f5b7931a5aa68fc9cecc51e685ef90282f4a82f0f5e9b704ad11 +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 # via jinja2 mdit-py-plugins==0.4.0 \ --hash=sha256:b51b3bb70691f57f974e257e367107857a93b36f322a9e6d44ca5bf28ec2def9 \ @@ -439,17 +437,17 @@ packaging==23.2 \ # pydata-sphinx-theme # pytest # sphinx -platformdirs==4.1.0 \ - --hash=sha256:11c8f37bcca40db96d8144522d925583bdb7a31f7b0e37e3ed4318400a8e2380 \ - --hash=sha256:906d548203468492d432bcb294d4bc2fff751bf84971fbb2c10918cc206ee420 +platformdirs==4.2.0 \ + --hash=sha256:0614df2a2f37e1a662acbd8e2b25b92ccf8632929bc6d43467e17fe89c75e068 \ + --hash=sha256:ef0cc731df711022c174543cb70a9b5bd22e5a9337c8624ef2c2ceb8ddad8768 # via virtualenv -pluggy==1.3.0 \ - --hash=sha256:cf61ae8f126ac6f7c451172cf30e3e43d3ca77615509771b3a984a0730651e12 \ - --hash=sha256:d89c696a773f8bd377d18e5ecda92b7a3793cbe66c87060a6fb58c7b6e1061f7 +pluggy==1.4.0 \ + --hash=sha256:7db9f7b503d67d1c5b95f59773ebb58a8c1c288129a88665838012cfb07b8981 \ + --hash=sha256:8c85c2876142a764e5b7548e7d9a0e0ddb46f5185161049a79b7e974454223be # via pytest -pre-commit==3.6.0 \ - --hash=sha256:c255039ef399049a5544b6ce13d135caba8f2c28c3b4033277a788f434308376 \ - --hash=sha256:d30bad9abf165f7785c15a21a1f46da7d0677cb00ee7ff4c579fd38922efe15d +pre-commit==3.6.2 \ + --hash=sha256:ba637c2d7a670c10daedc059f5c49b5bd0aadbccfcd7ec15592cf9665117532c \ + --hash=sha256:c3ef34f463045c88658c5b99f38c1e297abdcc0ff13f98d3370055fbbfabc67e # via -r requirements/dev.in pybtex==0.24.0 \ --hash=sha256:818eae35b61733e5c007c3fcd2cfb75ed1bc8b4173c1f70b56cc4c0802d34755 \ @@ -461,118 +459,92 @@ pybtex-docutils==1.0.3 \ --hash=sha256:3a7ebdf92b593e00e8c1c538aa9a20bca5d92d84231124715acc964d51d93c6b \ --hash=sha256:8fd290d2ae48e32fcb54d86b0efb8d573198653c7e2447d5bec5847095f430b9 # via sphinxcontrib-bibtex -pydantic==2.5.3 \ - --hash=sha256:b3ef57c62535b0941697cce638c08900d87fcb67e29cfa99e8a68f747f393f7a \ - --hash=sha256:d0caf5954bee831b6bfe7e338c32b9e30c85dfe080c843680783ac2b631673b4 +pydantic==2.6.3 \ + --hash=sha256:72c6034df47f46ccdf81869fddb81aade68056003900a8724a4f160700016a2a \ + --hash=sha256:e07805c4c7f5c6826e33a1d4c9d47950d7eaf34868e2690f8594d2e30241f11f # via # -c requirements/main.txt # documenteer -pydantic-core==2.14.6 \ - --hash=sha256:00646784f6cd993b1e1c0e7b0fdcbccc375d539db95555477771c27555e3c556 \ - --hash=sha256:00b1087dabcee0b0ffd104f9f53d7d3eaddfaa314cdd6726143af6bc713aa27e \ - --hash=sha256:0348b1dc6b76041516e8a854ff95b21c55f5a411c3297d2ca52f5528e49d8411 \ - --hash=sha256:036137b5ad0cb0004c75b579445a1efccd072387a36c7f217bb8efd1afbe5245 \ - --hash=sha256:095b707bb287bfd534044166ab767bec70a9bba3175dcdc3371782175c14e43c \ - --hash=sha256:0c08de15d50fa190d577e8591f0329a643eeaed696d7771760295998aca6bc66 \ - --hash=sha256:1302a54f87b5cd8528e4d6d1bf2133b6aa7c6122ff8e9dc5220fbc1e07bffebd \ - --hash=sha256:172de779e2a153d36ee690dbc49c6db568d7b33b18dc56b69a7514aecbcf380d \ - --hash=sha256:1b027c86c66b8627eb90e57aee1f526df77dc6d8b354ec498be9a757d513b92b \ - --hash=sha256:1ce830e480f6774608dedfd4a90c42aac4a7af0a711f1b52f807130c2e434c06 \ - --hash=sha256:1fd0c1d395372843fba13a51c28e3bb9d59bd7aebfeb17358ffaaa1e4dbbe948 \ - --hash=sha256:23598acb8ccaa3d1d875ef3b35cb6376535095e9405d91a3d57a8c7db5d29341 \ - --hash=sha256:24368e31be2c88bd69340fbfe741b405302993242ccb476c5c3ff48aeee1afe0 \ - --hash=sha256:26a92ae76f75d1915806b77cf459811e772d8f71fd1e4339c99750f0e7f6324f \ - --hash=sha256:27e524624eace5c59af499cd97dc18bb201dc6a7a2da24bfc66ef151c69a5f2a \ - --hash=sha256:2b8719037e570639e6b665a4050add43134d80b687288ba3ade18b22bbb29dd2 \ - --hash=sha256:2c5bcf3414367e29f83fd66f7de64509a8fd2368b1edf4351e862910727d3e51 \ - --hash=sha256:2dbe357bc4ddda078f79d2a36fc1dd0494a7f2fad83a0a684465b6f24b46fe80 \ - --hash=sha256:2f5fa187bde8524b1e37ba894db13aadd64faa884657473b03a019f625cee9a8 \ - --hash=sha256:2f6ffc6701a0eb28648c845f4945a194dc7ab3c651f535b81793251e1185ac3d \ - --hash=sha256:314ccc4264ce7d854941231cf71b592e30d8d368a71e50197c905874feacc8a8 \ - --hash=sha256:36026d8f99c58d7044413e1b819a67ca0e0b8ebe0f25e775e6c3d1fabb3c38fb \ - --hash=sha256:36099c69f6b14fc2c49d7996cbf4f87ec4f0e66d1c74aa05228583225a07b590 \ - --hash=sha256:36fa402dcdc8ea7f1b0ddcf0df4254cc6b2e08f8cd80e7010d4c4ae6e86b2a87 \ - --hash=sha256:370ffecb5316ed23b667d99ce4debe53ea664b99cc37bfa2af47bc769056d534 \ - --hash=sha256:3860c62057acd95cc84044e758e47b18dcd8871a328ebc8ccdefd18b0d26a21b \ - --hash=sha256:399ac0891c284fa8eb998bcfa323f2234858f5d2efca3950ae58c8f88830f145 \ - --hash=sha256:3a0b5db001b98e1c649dd55afa928e75aa4087e587b9524a4992316fa23c9fba \ - --hash=sha256:3dcf1978be02153c6a31692d4fbcc2a3f1db9da36039ead23173bc256ee3b91b \ - --hash=sha256:4241204e4b36ab5ae466ecec5c4c16527a054c69f99bba20f6f75232a6a534e2 \ - --hash=sha256:438027a975cc213a47c5d70672e0d29776082155cfae540c4e225716586be75e \ - --hash=sha256:43e166ad47ba900f2542a80d83f9fc65fe99eb63ceec4debec160ae729824052 \ - --hash=sha256:478e9e7b360dfec451daafe286998d4a1eeaecf6d69c427b834ae771cad4b622 \ - --hash=sha256:4ce8299b481bcb68e5c82002b96e411796b844d72b3e92a3fbedfe8e19813eab \ - --hash=sha256:4f86f1f318e56f5cbb282fe61eb84767aee743ebe32c7c0834690ebea50c0a6b \ - --hash=sha256:55a23dcd98c858c0db44fc5c04fc7ed81c4b4d33c653a7c45ddaebf6563a2f66 \ - --hash=sha256:599c87d79cab2a6a2a9df4aefe0455e61e7d2aeede2f8577c1b7c0aec643ee8e \ - --hash=sha256:5aa90562bc079c6c290f0512b21768967f9968e4cfea84ea4ff5af5d917016e4 \ - --hash=sha256:64634ccf9d671c6be242a664a33c4acf12882670b09b3f163cd00a24cffbd74e \ - --hash=sha256:667aa2eac9cd0700af1ddb38b7b1ef246d8cf94c85637cbb03d7757ca4c3fdec \ - --hash=sha256:6a31d98c0d69776c2576dda4b77b8e0c69ad08e8b539c25c7d0ca0dc19a50d6c \ - --hash=sha256:6af4b3f52cc65f8a0bc8b1cd9676f8c21ef3e9132f21fed250f6958bd7223bed \ - --hash=sha256:6c8edaea3089bf908dd27da8f5d9e395c5b4dc092dbcce9b65e7156099b4b937 \ - --hash=sha256:71d72ca5eaaa8d38c8df16b7deb1a2da4f650c41b58bb142f3fb75d5ad4a611f \ - --hash=sha256:72f9a942d739f09cd42fffe5dc759928217649f070056f03c70df14f5770acf9 \ - --hash=sha256:747265448cb57a9f37572a488a57d873fd96bf51e5bb7edb52cfb37124516da4 \ - --hash=sha256:75ec284328b60a4e91010c1acade0c30584f28a1f345bc8f72fe8b9e46ec6a96 \ - --hash=sha256:78d0768ee59baa3de0f4adac9e3748b4b1fffc52143caebddfd5ea2961595277 \ - --hash=sha256:78ee52ecc088c61cce32b2d30a826f929e1708f7b9247dc3b921aec367dc1b23 \ - --hash=sha256:7be719e4d2ae6c314f72844ba9d69e38dff342bc360379f7c8537c48e23034b7 \ - --hash=sha256:7e1f4744eea1501404b20b0ac059ff7e3f96a97d3e3f48ce27a139e053bb370b \ - --hash=sha256:7e90d6cc4aad2cc1f5e16ed56e46cebf4877c62403a311af20459c15da76fd91 \ - --hash=sha256:7ebe3416785f65c28f4f9441e916bfc8a54179c8dea73c23023f7086fa601c5d \ - --hash=sha256:7f41533d7e3cf9520065f610b41ac1c76bc2161415955fbcead4981b22c7611e \ - --hash=sha256:7f5025db12fc6de7bc1104d826d5aee1d172f9ba6ca936bf6474c2148ac336c1 \ - --hash=sha256:86c963186ca5e50d5c8287b1d1c9d3f8f024cbe343d048c5bd282aec2d8641f2 \ - --hash=sha256:86ce5fcfc3accf3a07a729779d0b86c5d0309a4764c897d86c11089be61da160 \ - --hash=sha256:8a14c192c1d724c3acbfb3f10a958c55a2638391319ce8078cb36c02283959b9 \ - --hash=sha256:8b93785eadaef932e4fe9c6e12ba67beb1b3f1e5495631419c784ab87e975670 \ - --hash=sha256:8ed1af8692bd8d2a29d702f1a2e6065416d76897d726e45a1775b1444f5928a7 \ - --hash=sha256:92879bce89f91f4b2416eba4429c7b5ca22c45ef4a499c39f0c5c69257522c7c \ - --hash=sha256:94fc0e6621e07d1e91c44e016cc0b189b48db053061cc22d6298a611de8071bb \ - --hash=sha256:982487f8931067a32e72d40ab6b47b1628a9c5d344be7f1a4e668fb462d2da42 \ - --hash=sha256:9862bf828112e19685b76ca499b379338fd4c5c269d897e218b2ae8fcb80139d \ - --hash=sha256:99b14dbea2fdb563d8b5a57c9badfcd72083f6006caf8e126b491519c7d64ca8 \ - --hash=sha256:9c6a5c79b28003543db3ba67d1df336f253a87d3112dac3a51b94f7d48e4c0e1 \ - --hash=sha256:a19b794f8fe6569472ff77602437ec4430f9b2b9ec7a1105cfd2232f9ba355e6 \ - --hash=sha256:a306cdd2ad3a7d795d8e617a58c3a2ed0f76c8496fb7621b6cd514eb1532cae8 \ - --hash=sha256:a3dde6cac75e0b0902778978d3b1646ca9f438654395a362cb21d9ad34b24acf \ - --hash=sha256:a874f21f87c485310944b2b2734cd6d318765bcbb7515eead33af9641816506e \ - --hash=sha256:a983cca5ed1dd9a35e9e42ebf9f278d344603bfcb174ff99a5815f953925140a \ - --hash=sha256:aca48506a9c20f68ee61c87f2008f81f8ee99f8d7f0104bff3c47e2d148f89d9 \ - --hash=sha256:b2602177668f89b38b9f84b7b3435d0a72511ddef45dc14446811759b82235a1 \ - --hash=sha256:b3e5fe4538001bb82e2295b8d2a39356a84694c97cb73a566dc36328b9f83b40 \ - --hash=sha256:b6ca36c12a5120bad343eef193cc0122928c5c7466121da7c20f41160ba00ba2 \ - --hash=sha256:b89f4477d915ea43b4ceea6756f63f0288941b6443a2b28c69004fe07fde0d0d \ - --hash=sha256:b9a9d92f10772d2a181b5ca339dee066ab7d1c9a34ae2421b2a52556e719756f \ - --hash=sha256:c99462ffc538717b3e60151dfaf91125f637e801f5ab008f81c402f1dff0cd0f \ - --hash=sha256:cb92f9061657287eded380d7dc455bbf115430b3aa4741bdc662d02977e7d0af \ - --hash=sha256:cdee837710ef6b56ebd20245b83799fce40b265b3b406e51e8ccc5b85b9099b7 \ - --hash=sha256:cf10b7d58ae4a1f07fccbf4a0a956d705356fea05fb4c70608bb6fa81d103cda \ - --hash=sha256:d15687d7d7f40333bd8266f3814c591c2e2cd263fa2116e314f60d82086e353a \ - --hash=sha256:d5c28525c19f5bb1e09511669bb57353d22b94cf8b65f3a8d141c389a55dec95 \ - --hash=sha256:d5f916acf8afbcab6bacbb376ba7dc61f845367901ecd5e328fc4d4aef2fcab0 \ - --hash=sha256:dab03ed811ed1c71d700ed08bde8431cf429bbe59e423394f0f4055f1ca0ea60 \ - --hash=sha256:db453f2da3f59a348f514cfbfeb042393b68720787bbef2b4c6068ea362c8149 \ - --hash=sha256:de2a0645a923ba57c5527497daf8ec5df69c6eadf869e9cd46e86349146e5975 \ - --hash=sha256:dea7fcd62915fb150cdc373212141a30037e11b761fbced340e9db3379b892d4 \ - --hash=sha256:dfcbebdb3c4b6f739a91769aea5ed615023f3c88cb70df812849aef634c25fbe \ - --hash=sha256:dfcebb950aa7e667ec226a442722134539e77c575f6cfaa423f24371bb8d2e94 \ - --hash=sha256:e0641b506486f0b4cd1500a2a65740243e8670a2549bb02bc4556a83af84ae03 \ - --hash=sha256:e33b0834f1cf779aa839975f9d8755a7c2420510c0fa1e9fa0497de77cd35d2c \ - --hash=sha256:e4ace1e220b078c8e48e82c081e35002038657e4b37d403ce940fa679e57113b \ - --hash=sha256:e4cf2d5829f6963a5483ec01578ee76d329eb5caf330ecd05b3edd697e7d768a \ - --hash=sha256:e574de99d735b3fc8364cba9912c2bec2da78775eba95cbb225ef7dda6acea24 \ - --hash=sha256:e646c0e282e960345314f42f2cea5e0b5f56938c093541ea6dbf11aec2862391 \ - --hash=sha256:e8a5ac97ea521d7bde7621d86c30e86b798cdecd985723c4ed737a2aa9e77d0c \ - --hash=sha256:eedf97be7bc3dbc8addcef4142f4b4164066df0c6f36397ae4aaed3eb187d8ab \ - --hash=sha256:ef633add81832f4b56d3b4c9408b43d530dfca29e68fb1b797dcb861a2c734cd \ - --hash=sha256:f27207e8ca3e5e021e2402ba942e5b4c629718e665c81b8b306f3c8b1ddbb786 \ - --hash=sha256:f85f3843bdb1fe80e8c206fe6eed7a1caeae897e496542cee499c374a85c6e08 \ - --hash=sha256:f8e81e4b55930e5ffab4a68db1af431629cf2e4066dbdbfef65348b8ab804ea8 \ - --hash=sha256:f96ae96a060a8072ceff4cfde89d261837b4294a4f28b84a28765470d502ccc6 \ - --hash=sha256:fd9e98b408384989ea4ab60206b8e100d8687da18b5c813c11e92fd8212a98e0 \ - --hash=sha256:ffff855100bc066ff2cd3aa4a60bc9534661816b110f0243e59503ec2df38421 +pydantic-core==2.16.3 \ + --hash=sha256:00ee1c97b5364b84cb0bd82e9bbf645d5e2871fb8c58059d158412fee2d33d8a \ + --hash=sha256:0d32576b1de5a30d9a97f300cc6a3f4694c428d956adbc7e6e2f9cad279e45ed \ + --hash=sha256:0df446663464884297c793874573549229f9eca73b59360878f382a0fc085979 \ + --hash=sha256:0f56ae86b60ea987ae8bcd6654a887238fd53d1384f9b222ac457070b7ac4cff \ + --hash=sha256:13dcc4802961b5f843a9385fc821a0b0135e8c07fc3d9949fd49627c1a5e6ae5 \ + --hash=sha256:162e498303d2b1c036b957a1278fa0899d02b2842f1ff901b6395104c5554a45 \ + --hash=sha256:1b662180108c55dfbf1280d865b2d116633d436cfc0bba82323554873967b340 \ + --hash=sha256:1cac689f80a3abab2d3c0048b29eea5751114054f032a941a32de4c852c59cad \ + --hash=sha256:21b888c973e4f26b7a96491c0965a8a312e13be108022ee510248fe379a5fa23 \ + --hash=sha256:287073c66748f624be4cef893ef9174e3eb88fe0b8a78dc22e88eca4bc357ca6 \ + --hash=sha256:2a1ef6a36fdbf71538142ed604ad19b82f67b05749512e47f247a6ddd06afdc7 \ + --hash=sha256:2a72fb9963cba4cd5793854fd12f4cfee731e86df140f59ff52a49b3552db241 \ + --hash=sha256:2acca2be4bb2f2147ada8cac612f8a98fc09f41c89f87add7256ad27332c2fda \ + --hash=sha256:2f583bd01bbfbff4eaee0868e6fc607efdfcc2b03c1c766b06a707abbc856187 \ + --hash=sha256:33809aebac276089b78db106ee692bdc9044710e26f24a9a2eaa35a0f9fa70ba \ + --hash=sha256:36fa178aacbc277bc6b62a2c3da95226520da4f4e9e206fdf076484363895d2c \ + --hash=sha256:4204e773b4b408062960e65468d5346bdfe139247ee5f1ca2a378983e11388a2 \ + --hash=sha256:4384a8f68ddb31a0b0c3deae88765f5868a1b9148939c3f4121233314ad5532c \ + --hash=sha256:456855f57b413f077dff513a5a28ed838dbbb15082ba00f80750377eed23d132 \ + --hash=sha256:49d5d58abd4b83fb8ce763be7794d09b2f50f10aa65c0f0c1696c677edeb7cbf \ + --hash=sha256:4ac6b4ce1e7283d715c4b729d8f9dab9627586dafce81d9eaa009dd7f25dd972 \ + --hash=sha256:4df8a199d9f6afc5ae9a65f8f95ee52cae389a8c6b20163762bde0426275b7db \ + --hash=sha256:500960cb3a0543a724a81ba859da816e8cf01b0e6aaeedf2c3775d12ee49cade \ + --hash=sha256:519ae0312616026bf4cedc0fe459e982734f3ca82ee8c7246c19b650b60a5ee4 \ + --hash=sha256:578114bc803a4c1ff9946d977c221e4376620a46cf78da267d946397dc9514a8 \ + --hash=sha256:5c5cbc703168d1b7a838668998308018a2718c2130595e8e190220238addc96f \ + --hash=sha256:6162f8d2dc27ba21027f261e4fa26f8bcb3cf9784b7f9499466a311ac284b5b9 \ + --hash=sha256:704d35ecc7e9c31d48926150afada60401c55efa3b46cd1ded5a01bdffaf1d48 \ + --hash=sha256:716b542728d4c742353448765aa7cdaa519a7b82f9564130e2b3f6766018c9ec \ + --hash=sha256:72282ad4892a9fb2da25defeac8c2e84352c108705c972db82ab121d15f14e6d \ + --hash=sha256:7233d65d9d651242a68801159763d09e9ec96e8a158dbf118dc090cd77a104c9 \ + --hash=sha256:732da3243e1b8d3eab8c6ae23ae6a58548849d2e4a4e03a1924c8ddf71a387cb \ + --hash=sha256:75b81e678d1c1ede0785c7f46690621e4c6e63ccd9192af1f0bd9d504bbb6bf4 \ + --hash=sha256:75f76ee558751746d6a38f89d60b6228fa174e5172d143886af0f85aa306fd89 \ + --hash=sha256:7ee8d5f878dccb6d499ba4d30d757111847b6849ae07acdd1205fffa1fc1253c \ + --hash=sha256:7f752826b5b8361193df55afcdf8ca6a57d0232653494ba473630a83ba50d8c9 \ + --hash=sha256:86b3d0033580bd6bbe07590152007275bd7af95f98eaa5bd36f3da219dcd93da \ + --hash=sha256:8d62da299c6ecb04df729e4b5c52dc0d53f4f8430b4492b93aa8de1f541c4aac \ + --hash=sha256:8e47755d8152c1ab5b55928ab422a76e2e7b22b5ed8e90a7d584268dd49e9c6b \ + --hash=sha256:9091632a25b8b87b9a605ec0e61f241c456e9248bfdcf7abdf344fdb169c81cf \ + --hash=sha256:936e5db01dd49476fa8f4383c259b8b1303d5dd5fb34c97de194560698cc2c5e \ + --hash=sha256:99b6add4c0b39a513d323d3b93bc173dac663c27b99860dd5bf491b240d26137 \ + --hash=sha256:9c865a7ee6f93783bd5d781af5a4c43dadc37053a5b42f7d18dc019f8c9d2bd1 \ + --hash=sha256:a425479ee40ff021f8216c9d07a6a3b54b31c8267c6e17aa88b70d7ebd0e5e5b \ + --hash=sha256:a4b2bf78342c40b3dc830880106f54328928ff03e357935ad26c7128bbd66ce8 \ + --hash=sha256:a6b1bb0827f56654b4437955555dc3aeeebeddc47c2d7ed575477f082622c49e \ + --hash=sha256:aaf09e615a0bf98d406657e0008e4a8701b11481840be7d31755dc9f97c44053 \ + --hash=sha256:b1f6f5938d63c6139860f044e2538baeee6f0b251a1816e7adb6cbce106a1f01 \ + --hash=sha256:b29eeb887aa931c2fcef5aa515d9d176d25006794610c264ddc114c053bf96fe \ + --hash=sha256:b3992a322a5617ded0a9f23fd06dbc1e4bd7cf39bc4ccf344b10f80af58beacd \ + --hash=sha256:b5b6079cc452a7c53dd378c6f881ac528246b3ac9aae0f8eef98498a75657805 \ + --hash=sha256:b60cc1a081f80a2105a59385b92d82278b15d80ebb3adb200542ae165cd7d183 \ + --hash=sha256:b926dd38db1519ed3043a4de50214e0d600d404099c3392f098a7f9d75029ff8 \ + --hash=sha256:bd87f48924f360e5d1c5f770d6155ce0e7d83f7b4e10c2f9ec001c73cf475c99 \ + --hash=sha256:bda1ee3e08252b8d41fa5537413ffdddd58fa73107171a126d3b9ff001b9b820 \ + --hash=sha256:be0ec334369316fa73448cc8c982c01e5d2a81c95969d58b8f6e272884df0074 \ + --hash=sha256:c6119dc90483a5cb50a1306adb8d52c66e447da88ea44f323e0ae1a5fcb14256 \ + --hash=sha256:c9803edf8e29bd825f43481f19c37f50d2b01899448273b3a7758441b512acf8 \ + --hash=sha256:c9bd22a2a639e26171068f8ebb5400ce2c1bc7d17959f60a3b753ae13c632975 \ + --hash=sha256:cbcc558401de90a746d02ef330c528f2e668c83350f045833543cd57ecead1ad \ + --hash=sha256:cf6204fe865da605285c34cf1172879d0314ff267b1c35ff59de7154f35fdc2e \ + --hash=sha256:d33dd21f572545649f90c38c227cc8631268ba25c460b5569abebdd0ec5974ca \ + --hash=sha256:d89ca19cdd0dd5f31606a9329e309d4fcbb3df860960acec32630297d61820df \ + --hash=sha256:d8f99b147ff3fcf6b3cc60cb0c39ea443884d5559a30b1481e92495f2310ff2b \ + --hash=sha256:d937653a696465677ed583124b94a4b2d79f5e30b2c46115a68e482c6a591c8a \ + --hash=sha256:dcca5d2bf65c6fb591fff92da03f94cd4f315972f97c21975398bd4bd046854a \ + --hash=sha256:ded1c35f15c9dea16ead9bffcde9bb5c7c031bff076355dc58dcb1cb436c4721 \ + --hash=sha256:e3e70c94a0c3841e6aa831edab1619ad5c511199be94d0c11ba75fe06efe107a \ + --hash=sha256:e56f8186d6210ac7ece503193ec84104da7ceb98f68ce18c07282fcc2452e76f \ + --hash=sha256:e7774b570e61cb998490c5235740d475413a1f6de823169b4cf94e2fe9e9f6b2 \ + --hash=sha256:e7c6ed0dc9d8e65f24f5824291550139fe6f37fac03788d4580da0d33bc00c97 \ + --hash=sha256:ec08be75bb268473677edb83ba71e7e74b43c008e4a7b1907c6d57e940bf34b6 \ + --hash=sha256:ecdf6bf5f578615f2e985a5e1f6572e23aa632c4bd1dc67f8f406d445ac115ed \ + --hash=sha256:ed25e1835c00a332cb10c683cd39da96a719ab1dfc08427d476bce41b92531fc \ + --hash=sha256:f4cb85f693044e0f71f394ff76c98ddc1bc0953e48c061725e540396d5c8a2e1 \ + --hash=sha256:f53aace168a2a10582e570b7736cc5bef12cae9cf21775e3eafac597e8551fbe \ + --hash=sha256:f651dd19363c632f4abe3480a7c87a9773be27cfe1341aef06e8759599454120 \ + --hash=sha256:fc4ad7f7ee1a13d9cb49d8198cd7d7e3aa93e425f371a68235f784e99741561f \ + --hash=sha256:fee427241c2d9fb7192b658190f9f5fd6dfe41e02f3c1489d2ec1e6a5ab1e04a # via # -c requirements/main.txt # pydantic @@ -590,16 +562,16 @@ pygments==2.17.2 \ pylatexenc==2.10 \ --hash=sha256:3dd8fd84eb46dc30bee1e23eaab8d8fb5a7f507347b23e5f38ad9675c84f40d3 # via documenteer -pytest==7.4.4 \ - --hash=sha256:2cf0005922c6ace4a3e2ec8b4080eb0d9753fdc93107415332f50ce9e7994280 \ - --hash=sha256:b090cdf5ed60bf4c45261be03239c2c1c22df034fbffe691abe93cd80cea01d8 +pytest==8.0.2 \ + --hash=sha256:d4051d623a2e0b7e51960ba963193b09ce6daeb9759a451844a21e4ddedfc1bd \ + --hash=sha256:edfaaef32ce5172d5466b5127b42e0d6d35ebbe4453f0e3505d96afd93f6b096 # via # -r requirements/dev.in # pytest-asyncio # pytest-cov -pytest-asyncio==0.23.3 \ - --hash=sha256:37a9d912e8338ee7b4a3e917381d1c95bfc8682048cb0fbc35baba316ec1faba \ - --hash=sha256:af313ce900a62fbe2b1aed18e37ad757f1ef9940c6b6a88e2954de38d6b1fb9f +pytest-asyncio==0.23.5 \ + --hash=sha256:3a048872a9c4ba14c3e90cc1aa20cbc2def7d01c7c8db3777ec281ba9c057675 \ + --hash=sha256:4e7093259ba018d58ede7d5315131d21923a60f8a6e9ee266ce1589685c89eac # via -r requirements/dev.in pytest-cov==4.1.0 \ --hash=sha256:3904b13dfbfec47f003b8e77fd5b589cd11904a21ddf1ab38a64f204d6a10ef6 \ @@ -635,6 +607,7 @@ pyyaml==6.0.1 \ --hash=sha256:8d4e9c88387b0f5c7d5f281e55304de64cf7f9c0021a3525bd3b1c542da3b0e4 \ --hash=sha256:9046c58c4395dff28dd494285c82ba00b546adfc7ef001486fbf0324bc174fba \ --hash=sha256:9eb6caa9a297fc2c2fb8862bc5370d0303ddba53ba97e71f08023b6cd73d16a8 \ + --hash=sha256:a08c6f0fe150303c1c6b71ebcd7213c2858041a7e01975da3a99aed1e7a378ef \ --hash=sha256:a0cd17c15d3bb3fa06978b4e8958dcdc6e0174ccea823003a106c7d4d7899ac5 \ --hash=sha256:afd7e57eddb1a54f0f1a974bc4391af8bcce0b444685d936840f125cf046d5bd \ --hash=sha256:b1275ad35a5d18c62a7220633c913e1b42d44b46ee12554e5fd39c70a243d6a3 \ @@ -663,9 +636,9 @@ pyyaml==6.0.1 \ # pre-commit # pybtex # sphinxcontrib-redoc -referencing==0.32.0 \ - --hash=sha256:689e64fe121843dcfd57b71933318ef1f91188ffb45367332700a86ac8fd6161 \ - --hash=sha256:bdcd3efb936f82ff86f993093f6da7435c7de69a3b3a5a06678a6050184bee99 +referencing==0.33.0 \ + --hash=sha256:39240f2ecc770258f28b642dd47fd74bc8b02484de54e1882b74b35ebd779bd5 \ + --hash=sha256:c775fedf74bc0f9189c2a3be1c12fd03e8c23f4d371dce795df44e06c5b412f7 # via # jsonschema # jsonschema-specifications @@ -680,106 +653,106 @@ respx==0.20.2 \ --hash=sha256:07cf4108b1c88b82010f67d3c831dae33a375c7b436e54d87737c7f9f99be643 \ --hash=sha256:ab8e1cf6da28a5b2dd883ea617f8130f77f676736e6e9e4a25817ad116a172c9 # via -r requirements/dev.in -rpds-py==0.16.2 \ - --hash=sha256:0474df4ade9a3b4af96c3d36eb81856cb9462e4c6657d4caecfd840d2a13f3c9 \ - --hash=sha256:071980663c273bf3d388fe5c794c547e6f35ba3335477072c713a3176bf14a60 \ - --hash=sha256:07aab64e2808c3ebac2a44f67e9dc0543812b715126dfd6fe4264df527556cb6 \ - --hash=sha256:088396c7c70e59872f67462fcac3ecbded5233385797021976a09ebd55961dfe \ - --hash=sha256:162d7cd9cd311c1b0ff1c55a024b8f38bd8aad1876b648821da08adc40e95734 \ - --hash=sha256:19f00f57fdd38db4bb5ad09f9ead1b535332dbf624200e9029a45f1f35527ebb \ - --hash=sha256:1bdbc5fcb04a7309074de6b67fa9bc4b418ab3fc435fec1f2779a0eced688d04 \ - --hash=sha256:1be2f033df1b8be8c3167ba3c29d5dca425592ee31e35eac52050623afba5772 \ - --hash=sha256:24f7a2eb3866a9e91f4599851e0c8d39878a470044875c49bd528d2b9b88361c \ - --hash=sha256:290a81cfbe4673285cdf140ec5cd1658ffbf63ab359f2b352ebe172e7cfa5bf0 \ - --hash=sha256:2946b120718eba9af2b4dd103affc1164a87b9e9ebff8c3e4c05d7b7a7e274e2 \ - --hash=sha256:2bd82db36cd70b3628c0c57d81d2438e8dd4b7b32a6a9f25f24ab0e657cb6c4e \ - --hash=sha256:2ddef620e70eaffebed5932ce754d539c0930f676aae6212f8e16cd9743dd365 \ - --hash=sha256:2e53b9b25cac9065328901713a7e9e3b12e4f57ef4280b370fbbf6fef2052eef \ - --hash=sha256:302bd4983bbd47063e452c38be66153760112f6d3635c7eeefc094299fa400a9 \ - --hash=sha256:349cb40897fd529ca15317c22c0eab67f5ac5178b5bd2c6adc86172045210acc \ - --hash=sha256:358dafc89ce3894c7f486c615ba914609f38277ef67f566abc4c854d23b997fa \ - --hash=sha256:35953f4f2b3216421af86fd236b7c0c65935936a94ea83ddbd4904ba60757773 \ - --hash=sha256:35ae5ece284cf36464eb160880018cf6088a9ac5ddc72292a6092b6ef3f4da53 \ - --hash=sha256:3b811d182ad17ea294f2ec63c0621e7be92a1141e1012383461872cead87468f \ - --hash=sha256:3da5a4c56953bdbf6d04447c3410309616c54433146ccdb4a277b9cb499bc10e \ - --hash=sha256:3dc6a7620ba7639a3db6213da61312cb4aa9ac0ca6e00dc1cbbdc21c2aa6eb57 \ - --hash=sha256:3f91df8e6dbb7360e176d1affd5fb0246d2b88d16aa5ebc7db94fd66b68b61da \ - --hash=sha256:4022b9dc620e14f30201a8a73898a873c8e910cb642bcd2f3411123bc527f6ac \ - --hash=sha256:413b9c17388bbd0d87a329d8e30c1a4c6e44e2bb25457f43725a8e6fe4161e9e \ - --hash=sha256:43d4dd5fb16eb3825742bad8339d454054261ab59fed2fbac84e1d84d5aae7ba \ - --hash=sha256:44627b6ca7308680a70766454db5249105fa6344853af6762eaad4158a2feebe \ - --hash=sha256:44a54e99a2b9693a37ebf245937fd6e9228b4cbd64b9cc961e1f3391ec6c7391 \ - --hash=sha256:47713dc4fce213f5c74ca8a1f6a59b622fc1b90868deb8e8e4d993e421b4b39d \ - --hash=sha256:495a14b72bbe217f2695dcd9b5ab14d4f8066a00f5d209ed94f0aca307f85f6e \ - --hash=sha256:4c46ad6356e1561f2a54f08367d1d2e70a0a1bb2db2282d2c1972c1d38eafc3b \ - --hash=sha256:4d6a9f052e72d493efd92a77f861e45bab2f6be63e37fa8ecf0c6fd1a58fedb0 \ - --hash=sha256:509b617ac787cd1149600e731db9274ebbef094503ca25158e6f23edaba1ca8f \ - --hash=sha256:5552f328eaef1a75ff129d4d0c437bf44e43f9436d3996e8eab623ea0f5fcf73 \ - --hash=sha256:5a80e2f83391ad0808b4646732af2a7b67550b98f0cae056cb3b40622a83dbb3 \ - --hash=sha256:5cf6af100ffb5c195beec11ffaa8cf8523057f123afa2944e6571d54da84cdc9 \ - --hash=sha256:5e6caa3809e50690bd92fa490f5c38caa86082c8c3315aa438bce43786d5e90d \ - --hash=sha256:5ef00873303d678aaf8b0627e111fd434925ca01c657dbb2641410f1cdaef261 \ - --hash=sha256:69ac7ea9897ec201ce68b48582f3eb34a3f9924488a5432a93f177bf76a82a7e \ - --hash=sha256:6a61226465bda9283686db8f17d02569a98e4b13c637be5a26d44aa1f1e361c2 \ - --hash=sha256:6d904c5693e08bad240f16d79305edba78276be87061c872a4a15e2c301fa2c0 \ - --hash=sha256:6dace7b26a13353e24613417ce2239491b40a6ad44e5776a18eaff7733488b44 \ - --hash=sha256:6df15846ee3fb2e6397fe25d7ca6624af9f89587f3f259d177b556fed6bebe2c \ - --hash=sha256:703d95c75a72e902544fda08e965885525e297578317989fd15a6ce58414b41d \ - --hash=sha256:726ac36e8a3bb8daef2fd482534cabc5e17334052447008405daca7ca04a3108 \ - --hash=sha256:781ef8bfc091b19960fc0142a23aedadafa826bc32b433fdfe6fd7f964d7ef44 \ - --hash=sha256:80443fe2f7b3ea3934c5d75fb0e04a5dbb4a8e943e5ff2de0dec059202b70a8b \ - --hash=sha256:83640a5d7cd3bff694747d50436b8b541b5b9b9782b0c8c1688931d6ee1a1f2d \ - --hash=sha256:84c5a4d1f9dd7e2d2c44097fb09fffe728629bad31eb56caf97719e55575aa82 \ - --hash=sha256:882ce6e25e585949c3d9f9abd29202367175e0aab3aba0c58c9abbb37d4982ff \ - --hash=sha256:888a97002e986eca10d8546e3c8b97da1d47ad8b69726dcfeb3e56348ebb28a3 \ - --hash=sha256:8aad80645a011abae487d356e0ceb359f4938dfb6f7bcc410027ed7ae4f7bb8b \ - --hash=sha256:8cb6fe8ecdfffa0e711a75c931fb39f4ba382b4b3ccedeca43f18693864fe850 \ - --hash=sha256:8d6b6937ae9eac6d6c0ca3c42774d89fa311f55adff3970fb364b34abde6ed3d \ - --hash=sha256:90123853fc8b1747f80b0d354be3d122b4365a93e50fc3aacc9fb4c2488845d6 \ - --hash=sha256:96f957d6ab25a78b9e7fc9749d754b98eac825a112b4e666525ce89afcbd9ed5 \ - --hash=sha256:981d135c7cdaf6cd8eadae1c950de43b976de8f09d8e800feed307140d3d6d00 \ - --hash=sha256:9b32f742ce5b57201305f19c2ef7a184b52f6f9ba6871cc042c2a61f0d6b49b8 \ - --hash=sha256:9f0350ef2fba5f34eb0c9000ea328e51b9572b403d2f7f3b19f24085f6f598e8 \ - --hash=sha256:a297a4d08cc67c7466c873c78039d87840fb50d05473db0ec1b7b03d179bf322 \ - --hash=sha256:a3d7e2ea25d3517c6d7e5a1cc3702cffa6bd18d9ef8d08d9af6717fc1c700eed \ - --hash=sha256:a4b682c5775d6a3d21e314c10124599976809455ee67020e8e72df1769b87bc3 \ - --hash=sha256:a4ebb8b20bd09c5ce7884c8f0388801100f5e75e7f733b1b6613c713371feefc \ - --hash=sha256:a61f659665a39a4d17d699ab3593d7116d66e1e2e3f03ef3fb8f484e91908808 \ - --hash=sha256:a9880b4656efe36ccad41edc66789e191e5ee19a1ea8811e0aed6f69851a82f4 \ - --hash=sha256:ac08472f41ea77cd6a5dae36ae7d4ed3951d6602833af87532b556c1b4601d63 \ - --hash=sha256:adc0c3d6fc6ae35fee3e4917628983f6ce630d513cbaad575b4517d47e81b4bb \ - --hash=sha256:af27423662f32d7501a00c5e7342f7dbd1e4a718aea7a239781357d15d437133 \ - --hash=sha256:b2e75e17bd0bb66ee34a707da677e47c14ee51ccef78ed6a263a4cc965a072a1 \ - --hash=sha256:b634c5ec0103c5cbebc24ebac4872b045cccb9456fc59efdcf6fe39775365bd2 \ - --hash=sha256:b6f5549d6ed1da9bfe3631ca9483ae906f21410be2445b73443fa9f017601c6f \ - --hash=sha256:bd4b677d929cf1f6bac07ad76e0f2d5de367e6373351c01a9c0a39f6b21b4a8b \ - --hash=sha256:bf721ede3eb7b829e4a9b8142bd55db0bdc82902720548a703f7e601ee13bdc3 \ - --hash=sha256:c647ca87fc0ebe808a41de912e9a1bfef9acb85257e5d63691364ac16b81c1f0 \ - --hash=sha256:ca57468da2d9a660bcf8961637c85f2fbb2aa64d9bc3f9484e30c3f9f67b1dd7 \ - --hash=sha256:cad0f59ee3dc35526039f4bc23642d52d5f6616b5f687d846bfc6d0d6d486db0 \ - --hash=sha256:cc97f0640e91d7776530f06e6836c546c1c752a52de158720c4224c9e8053cad \ - --hash=sha256:ccd4e400309e1f34a5095bf9249d371f0fd60f8a3a5c4a791cad7b99ce1fd38d \ - --hash=sha256:cffa76b385dfe1e38527662a302b19ffb0e7f5cf7dd5e89186d2c94a22dd9d0c \ - --hash=sha256:d0dd7ed2f16df2e129496e7fbe59a34bc2d7fc8db443a606644d069eb69cbd45 \ - --hash=sha256:d452817e0d9c749c431a1121d56a777bd7099b720b3d1c820f1725cb40928f58 \ - --hash=sha256:d8dda2a806dfa4a9b795950c4f5cc56d6d6159f7d68080aedaff3bdc9b5032f5 \ - --hash=sha256:dcbe1f8dd179e4d69b70b1f1d9bb6fd1e7e1bdc9c9aad345cdeb332e29d40748 \ - --hash=sha256:e0441fb4fdd39a230477b2ca9be90868af64425bfe7b122b57e61e45737a653b \ - --hash=sha256:e04e56b4ca7a770593633556e8e9e46579d66ec2ada846b401252a2bdcf70a6d \ - --hash=sha256:e061de3b745fe611e23cd7318aec2c8b0e4153939c25c9202a5811ca911fd733 \ - --hash=sha256:e93ec1b300acf89730cf27975ef574396bc04edecc358e9bd116fb387a123239 \ - --hash=sha256:e9e557db6a177470316c82f023e5d571811c9a4422b5ea084c85da9aa3c035fc \ - --hash=sha256:eab36eae3f3e8e24b05748ec9acc66286662f5d25c52ad70cadab544e034536b \ - --hash=sha256:ec23fcad480e77ede06cf4127a25fc440f7489922e17fc058f426b5256ee0edb \ - --hash=sha256:ec2e1cf025b2c0f48ec17ff3e642661da7ee332d326f2e6619366ce8e221f018 \ - --hash=sha256:ed99b4f7179d2111702020fd7d156e88acd533f5a7d3971353e568b6051d5c97 \ - --hash=sha256:ee94cb58c0ba2c62ee108c2b7c9131b2c66a29e82746e8fa3aa1a1effbd3dcf1 \ - --hash=sha256:f19afcfc0dd0dca35694df441e9b0f95bc231b512f51bded3c3d8ca32153ec19 \ - --hash=sha256:f1b9d9260e06ea017feb7172976ab261e011c1dc2f8883c7c274f6b2aabfe01a \ - --hash=sha256:f28ac0e8e7242d140f99402a903a2c596ab71550272ae9247ad78f9a932b5698 \ - --hash=sha256:f42e25c016927e2a6b1ce748112c3ab134261fc2ddc867e92d02006103e1b1b7 \ - --hash=sha256:f4bd4578e44f26997e9e56c96dedc5f1af43cc9d16c4daa29c771a00b2a26851 \ - --hash=sha256:f811771019f063bbd0aa7bb72c8a934bc13ebacb4672d712fc1639cfd314cccc +rpds-py==0.18.0 \ + --hash=sha256:01e36a39af54a30f28b73096dd39b6802eddd04c90dbe161c1b8dbe22353189f \ + --hash=sha256:044a3e61a7c2dafacae99d1e722cc2d4c05280790ec5a05031b3876809d89a5c \ + --hash=sha256:08231ac30a842bd04daabc4d71fddd7e6d26189406d5a69535638e4dcb88fe76 \ + --hash=sha256:08f9ad53c3f31dfb4baa00da22f1e862900f45908383c062c27628754af2e88e \ + --hash=sha256:0ab39c1ba9023914297dd88ec3b3b3c3f33671baeb6acf82ad7ce883f6e8e157 \ + --hash=sha256:0af039631b6de0397ab2ba16eaf2872e9f8fca391b44d3d8cac317860a700a3f \ + --hash=sha256:0b8612cd233543a3781bc659c731b9d607de65890085098986dfd573fc2befe5 \ + --hash=sha256:11a8c85ef4a07a7638180bf04fe189d12757c696eb41f310d2426895356dcf05 \ + --hash=sha256:1374f4129f9bcca53a1bba0bb86bf78325a0374577cf7e9e4cd046b1e6f20e24 \ + --hash=sha256:1d4acf42190d449d5e89654d5c1ed3a4f17925eec71f05e2a41414689cda02d1 \ + --hash=sha256:1d9a5be316c15ffb2b3c405c4ff14448c36b4435be062a7f578ccd8b01f0c4d8 \ + --hash=sha256:1df3659d26f539ac74fb3b0c481cdf9d725386e3552c6fa2974f4d33d78e544b \ + --hash=sha256:22806714311a69fd0af9b35b7be97c18a0fc2826e6827dbb3a8c94eac6cf7eeb \ + --hash=sha256:2644e47de560eb7bd55c20fc59f6daa04682655c58d08185a9b95c1970fa1e07 \ + --hash=sha256:2e6d75ab12b0bbab7215e5d40f1e5b738aa539598db27ef83b2ec46747df90e1 \ + --hash=sha256:30f43887bbae0d49113cbaab729a112251a940e9b274536613097ab8b4899cf6 \ + --hash=sha256:34b18ba135c687f4dac449aa5157d36e2cbb7c03cbea4ddbd88604e076aa836e \ + --hash=sha256:36b3ee798c58ace201289024b52788161e1ea133e4ac93fba7d49da5fec0ef9e \ + --hash=sha256:39514da80f971362f9267c600b6d459bfbbc549cffc2cef8e47474fddc9b45b1 \ + --hash=sha256:39f5441553f1c2aed4de4377178ad8ff8f9d733723d6c66d983d75341de265ab \ + --hash=sha256:3a96e0c6a41dcdba3a0a581bbf6c44bb863f27c541547fb4b9711fd8cf0ffad4 \ + --hash=sha256:3f26b5bd1079acdb0c7a5645e350fe54d16b17bfc5e71f371c449383d3342e17 \ + --hash=sha256:41ef53e7c58aa4ef281da975f62c258950f54b76ec8e45941e93a3d1d8580594 \ + --hash=sha256:42821446ee7a76f5d9f71f9e33a4fb2ffd724bb3e7f93386150b61a43115788d \ + --hash=sha256:43fbac5f22e25bee1d482c97474f930a353542855f05c1161fd804c9dc74a09d \ + --hash=sha256:4457a94da0d5c53dc4b3e4de1158bdab077db23c53232f37a3cb7afdb053a4e3 \ + --hash=sha256:465a3eb5659338cf2a9243e50ad9b2296fa15061736d6e26240e713522b6235c \ + --hash=sha256:482103aed1dfe2f3b71a58eff35ba105289b8d862551ea576bd15479aba01f66 \ + --hash=sha256:4832d7d380477521a8c1644bbab6588dfedea5e30a7d967b5fb75977c45fd77f \ + --hash=sha256:4901165d170a5fde6f589acb90a6b33629ad1ec976d4529e769c6f3d885e3e80 \ + --hash=sha256:5307def11a35f5ae4581a0b658b0af8178c65c530e94893345bebf41cc139d33 \ + --hash=sha256:5417558f6887e9b6b65b4527232553c139b57ec42c64570569b155262ac0754f \ + --hash=sha256:56a737287efecafc16f6d067c2ea0117abadcd078d58721f967952db329a3e5c \ + --hash=sha256:586f8204935b9ec884500498ccc91aa869fc652c40c093bd9e1471fbcc25c022 \ + --hash=sha256:5b4e7d8d6c9b2e8ee2d55c90b59c707ca59bc30058269b3db7b1f8df5763557e \ + --hash=sha256:5ddcba87675b6d509139d1b521e0c8250e967e63b5909a7e8f8944d0f90ff36f \ + --hash=sha256:618a3d6cae6ef8ec88bb76dd80b83cfe415ad4f1d942ca2a903bf6b6ff97a2da \ + --hash=sha256:635dc434ff724b178cb192c70016cc0ad25a275228f749ee0daf0eddbc8183b1 \ + --hash=sha256:661d25cbffaf8cc42e971dd570d87cb29a665f49f4abe1f9e76be9a5182c4688 \ + --hash=sha256:66e6a3af5a75363d2c9a48b07cb27c4ea542938b1a2e93b15a503cdfa8490795 \ + --hash=sha256:67071a6171e92b6da534b8ae326505f7c18022c6f19072a81dcf40db2638767c \ + --hash=sha256:685537e07897f173abcf67258bee3c05c374fa6fff89d4c7e42fb391b0605e98 \ + --hash=sha256:69e64831e22a6b377772e7fb337533c365085b31619005802a79242fee620bc1 \ + --hash=sha256:6b0817e34942b2ca527b0e9298373e7cc75f429e8da2055607f4931fded23e20 \ + --hash=sha256:6c81e5f372cd0dc5dc4809553d34f832f60a46034a5f187756d9b90586c2c307 \ + --hash=sha256:6d7faa6f14017c0b1e69f5e2c357b998731ea75a442ab3841c0dbbbfe902d2c4 \ + --hash=sha256:6ef0befbb5d79cf32d0266f5cff01545602344eda89480e1dd88aca964260b18 \ + --hash=sha256:6ef687afab047554a2d366e112dd187b62d261d49eb79b77e386f94644363294 \ + --hash=sha256:7223a2a5fe0d217e60a60cdae28d6949140dde9c3bcc714063c5b463065e3d66 \ + --hash=sha256:77f195baa60a54ef9d2de16fbbfd3ff8b04edc0c0140a761b56c267ac11aa467 \ + --hash=sha256:793968759cd0d96cac1e367afd70c235867831983f876a53389ad869b043c948 \ + --hash=sha256:7bd339195d84439cbe5771546fe8a4e8a7a045417d8f9de9a368c434e42a721e \ + --hash=sha256:7cd863afe7336c62ec78d7d1349a2f34c007a3cc6c2369d667c65aeec412a5b1 \ + --hash=sha256:7f2facbd386dd60cbbf1a794181e6aa0bd429bd78bfdf775436020172e2a23f0 \ + --hash=sha256:84ffab12db93b5f6bad84c712c92060a2d321b35c3c9960b43d08d0f639d60d7 \ + --hash=sha256:8c8370641f1a7f0e0669ddccca22f1da893cef7628396431eb445d46d893e5cd \ + --hash=sha256:8db715ebe3bb7d86d77ac1826f7d67ec11a70dbd2376b7cc214199360517b641 \ + --hash=sha256:8e8916ae4c720529e18afa0b879473049e95949bf97042e938530e072fde061d \ + --hash=sha256:8f03bccbd8586e9dd37219bce4d4e0d3ab492e6b3b533e973fa08a112cb2ffc9 \ + --hash=sha256:8f2fc11e8fe034ee3c34d316d0ad8808f45bc3b9ce5857ff29d513f3ff2923a1 \ + --hash=sha256:923d39efa3cfb7279a0327e337a7958bff00cc447fd07a25cddb0a1cc9a6d2da \ + --hash=sha256:93df1de2f7f7239dc9cc5a4a12408ee1598725036bd2dedadc14d94525192fc3 \ + --hash=sha256:998e33ad22dc7ec7e030b3df701c43630b5bc0d8fbc2267653577e3fec279afa \ + --hash=sha256:99f70b740dc04d09e6b2699b675874367885217a2e9f782bdf5395632ac663b7 \ + --hash=sha256:9a00312dea9310d4cb7dbd7787e722d2e86a95c2db92fbd7d0155f97127bcb40 \ + --hash=sha256:9d54553c1136b50fd12cc17e5b11ad07374c316df307e4cfd6441bea5fb68496 \ + --hash=sha256:9dbbeb27f4e70bfd9eec1be5477517365afe05a9b2c441a0b21929ee61048124 \ + --hash=sha256:a1ce3ba137ed54f83e56fb983a5859a27d43a40188ba798993812fed73c70836 \ + --hash=sha256:a34d557a42aa28bd5c48a023c570219ba2593bcbbb8dc1b98d8cf5d529ab1434 \ + --hash=sha256:a5f446dd5055667aabaee78487f2b5ab72e244f9bc0b2ffebfeec79051679984 \ + --hash=sha256:ad36cfb355e24f1bd37cac88c112cd7730873f20fb0bdaf8ba59eedf8216079f \ + --hash=sha256:aec493917dd45e3c69d00a8874e7cbed844efd935595ef78a0f25f14312e33c6 \ + --hash=sha256:b316144e85316da2723f9d8dc75bada12fa58489a527091fa1d5a612643d1a0e \ + --hash=sha256:b34ae4636dfc4e76a438ab826a0d1eed2589ca7d9a1b2d5bb546978ac6485461 \ + --hash=sha256:b34b7aa8b261c1dbf7720b5d6f01f38243e9b9daf7e6b8bc1fd4657000062f2c \ + --hash=sha256:bc362ee4e314870a70f4ae88772d72d877246537d9f8cb8f7eacf10884862432 \ + --hash=sha256:bed88b9a458e354014d662d47e7a5baafd7ff81c780fd91584a10d6ec842cb73 \ + --hash=sha256:c0013fe6b46aa496a6749c77e00a3eb07952832ad6166bd481c74bda0dcb6d58 \ + --hash=sha256:c0b5dcf9193625afd8ecc92312d6ed78781c46ecbf39af9ad4681fc9f464af88 \ + --hash=sha256:c4325ff0442a12113a6379af66978c3fe562f846763287ef66bdc1d57925d337 \ + --hash=sha256:c463ed05f9dfb9baebef68048aed8dcdc94411e4bf3d33a39ba97e271624f8f7 \ + --hash=sha256:c8362467a0fdeccd47935f22c256bec5e6abe543bf0d66e3d3d57a8fb5731863 \ + --hash=sha256:cd5bf1af8efe569654bbef5a3e0a56eca45f87cfcffab31dd8dde70da5982475 \ + --hash=sha256:cf1ea2e34868f6fbf070e1af291c8180480310173de0b0c43fc38a02929fc0e3 \ + --hash=sha256:d62dec4976954a23d7f91f2f4530852b0c7608116c257833922a896101336c51 \ + --hash=sha256:d68c93e381010662ab873fea609bf6c0f428b6d0bb00f2c6939782e0818d37bf \ + --hash=sha256:d7c36232a90d4755b720fbd76739d8891732b18cf240a9c645d75f00639a9024 \ + --hash=sha256:dd18772815d5f008fa03d2b9a681ae38d5ae9f0e599f7dda233c439fcaa00d40 \ + --hash=sha256:ddc2f4dfd396c7bfa18e6ce371cba60e4cf9d2e5cdb71376aa2da264605b60b9 \ + --hash=sha256:e003b002ec72c8d5a3e3da2989c7d6065b47d9eaa70cd8808b5384fbb970f4ec \ + --hash=sha256:e32a92116d4f2a80b629778280103d2a510a5b3f6314ceccd6e38006b5e92dcb \ + --hash=sha256:e4461d0f003a0aa9be2bdd1b798a041f177189c1a0f7619fe8c95ad08d9a45d7 \ + --hash=sha256:e541ec6f2ec456934fd279a3120f856cd0aedd209fc3852eca563f81738f6861 \ + --hash=sha256:e546e768d08ad55b20b11dbb78a745151acbd938f8f00d0cfbabe8b0199b9880 \ + --hash=sha256:ea7d4a99f3b38c37eac212dbd6ec42b7a5ec51e2c74b5d3223e43c811609e65f \ + --hash=sha256:ed4eb745efbff0a8e9587d22a84be94a5eb7d2d99c02dacf7bd0911713ed14dd \ + --hash=sha256:f8a2f084546cc59ea99fda8e070be2fd140c3092dc11524a71aa8f0f3d5a55ca \ + --hash=sha256:fcb25daa9219b4cf3a0ab24b0eb9a5cc8949ed4dc72acb8fa16b7e1681aa3c58 \ + --hash=sha256:fdea4952db2793c4ad0bdccd27c1d8fdd1423a92f04598bc39425bcc2b8ee46e # via # jsonschema # referencing @@ -798,9 +771,9 @@ smmap==5.0.1 \ --hash=sha256:dceeb6c0028fdb6734471eb07c0cd2aae706ccaecab45965ee83f11c8d3b1f62 \ --hash=sha256:e6d8668fa5f93e706934a62d7b4db19c8d9eb8cf2adbb75ef1b675aa332b69da # via gitdb -sniffio==1.3.0 \ - --hash=sha256:e60305c5e5d314f5389259b7f22aaa33d8f7dee49763119234af3755c55b9101 \ - --hash=sha256:eecefdce1e5bbfb7ad2eeaabf7c1eeb404d7757c379bd1f7e5cce9d8bf425384 +sniffio==1.3.1 \ + --hash=sha256:2f6da418d1f1e0fddd844478f41680e794e6051915791a034ff65e5f100525a2 \ + --hash=sha256:f4324edc670a0f49750a81b895f35c3adb843cca46f0530f79fc1babb23789dc # via # -c requirements/main.txt # anyio @@ -827,23 +800,18 @@ sphinx==7.2.6 \ # sphinx-design # sphinx-jinja # sphinx-prompt - # sphinxcontrib-applehelp # sphinxcontrib-bibtex - # sphinxcontrib-devhelp - # sphinxcontrib-htmlhelp # sphinxcontrib-jquery - # sphinxcontrib-qthelp # sphinxcontrib-redoc - # sphinxcontrib-serializinghtml # sphinxext-opengraph # sphinxext-rediraffe -sphinx-autodoc-typehints==1.25.2 \ - --hash=sha256:3cabc2537e17989b2f92e64a399425c4c8bf561ed73f087bc7414a5003616a50 \ - --hash=sha256:5ed05017d23ad4b937eab3bee9fae9ab0dd63f0b42aa360031f1fad47e47f673 +sphinx-autodoc-typehints==2.0.0 \ + --hash=sha256:12c0e161f6fe191c2cdfd8fa3caea271f5387d9fbc67ebcd6f4f1f24ce880993 \ + --hash=sha256:7f2cdac2e70fd9787926b6e9e541cd4ded1e838d2b46fda2a1bb0a75ec5b7f3a # via documenteer -sphinx-automodapi==0.16.0 \ - --hash=sha256:68fc47064804604b90aa27c047016e86aaf970981d90a0082d5b5dd2e9d38afd \ - --hash=sha256:6c673ef93066408e5ad3e2fa3533044d432a47fe6a826212b9ebf5f52a872554 +sphinx-automodapi==0.17.0 \ + --hash=sha256:4d029cb79eef29413e94ab01bb0177ebd2d5ba86e9789b73575afe9c06ae1501 \ + --hash=sha256:7ccdadad57add4aa9149d9f2bb5cf28c8f8b590280b4735b1156ea8355c423a1 # via documenteer sphinx-copybutton==0.5.2 \ --hash=sha256:4cf17c82fb9646d1bc9ca92ac280813a3b605d8c421225fd9913154103ee1fbd \ @@ -861,21 +829,21 @@ sphinx-prompt==1.8.0 \ --hash=sha256:369ecc633f0711886f9b3a078c83264245be1adf46abeeb9b88b5519e4b51007 \ --hash=sha256:47482f86fcec29662fdfd23e7c04ef03582714195d01f5d565403320084372ed # via documenteer -sphinxcontrib-applehelp==1.0.7 \ - --hash=sha256:094c4d56209d1734e7d252f6e0b3ccc090bd52ee56807a5d9315b19c122ab15d \ - --hash=sha256:39fdc8d762d33b01a7d8f026a3b7d71563ea3b72787d5f00ad8465bd9d6dfbfa +sphinxcontrib-applehelp==1.0.8 \ + --hash=sha256:c40a4f96f3776c4393d933412053962fac2b84f4c99a7982ba42e09576a70619 \ + --hash=sha256:cb61eb0ec1b61f349e5cc36b2028e9e7ca765be05e49641c97241274753067b4 # via sphinx -sphinxcontrib-bibtex==2.6.1 \ - --hash=sha256:046b49f070ae5276af34c1b8ddb9bc9562ef6de2f7a52d37a91cb8e53f54b863 \ - --hash=sha256:094c772098fe6b030cda8618c45722b2957cad0c04f328ba2b154aa08dfe720a +sphinxcontrib-bibtex==2.6.2 \ + --hash=sha256:10d45ebbb19207c5665396c9446f8012a79b8a538cb729f895b5910ab2d0b2da \ + --hash=sha256:f487af694336f28bfb7d6a17070953a7d264bec43000a2379724274f5f8d70ae # via documenteer -sphinxcontrib-devhelp==1.0.5 \ - --hash=sha256:63b41e0d38207ca40ebbeabcf4d8e51f76c03e78cd61abe118cf4435c73d4212 \ - --hash=sha256:fe8009aed765188f08fcaadbb3ea0d90ce8ae2d76710b7e29ea7d047177dae2f +sphinxcontrib-devhelp==1.0.6 \ + --hash=sha256:6485d09629944511c893fa11355bda18b742b83a2b181f9a009f7e500595c90f \ + --hash=sha256:9893fd3f90506bc4b97bdb977ceb8fbd823989f4316b28c3841ec128544372d3 # via sphinx -sphinxcontrib-htmlhelp==2.0.4 \ - --hash=sha256:6c26a118a05b76000738429b724a0568dbde5b72391a688577da08f11891092a \ - --hash=sha256:8001661c077a73c29beaf4a79968d0726103c5605e27db92b9ebed8bab1359e9 +sphinxcontrib-htmlhelp==2.0.5 \ + --hash=sha256:0dc87637d5de53dd5eec3a6a01753b1ccf99494bd756aafecd74b4fa9e729015 \ + --hash=sha256:393f04f112b4d2f53d93448d4bce35842f62b307ccdc549ec1585e950bc35e04 # via sphinx sphinxcontrib-jquery==4.1 \ --hash=sha256:1620739f04e36a2c779f1a131a2dfd49b2fd07351bf1968ced074365933abc7a \ @@ -889,16 +857,16 @@ sphinxcontrib-mermaid==0.9.2 \ --hash=sha256:252ef13dd23164b28f16d8b0205cf184b9d8e2b714a302274d9f59eb708e77af \ --hash=sha256:6795a72037ca55e65663d2a2c1a043d636dc3d30d418e56dd6087d1459d98a5d # via documenteer -sphinxcontrib-qthelp==1.0.6 \ - --hash=sha256:62b9d1a186ab7f5ee3356d906f648cacb7a6bdb94d201ee7adf26db55092982d \ - --hash=sha256:bf76886ee7470b934e363da7a954ea2825650013d367728588732c7350f49ea4 +sphinxcontrib-qthelp==1.0.7 \ + --hash=sha256:053dedc38823a80a7209a80860b16b722e9e0209e32fea98c90e4e6624588ed6 \ + --hash=sha256:e2ae3b5c492d58fcbd73281fbd27e34b8393ec34a073c792642cd8e529288182 # via sphinx sphinxcontrib-redoc==1.6.0 \ --hash=sha256:e358edbe23927d36432dde748e978cf897283a331a03e93d3ef02e348dee4561 # via documenteer -sphinxcontrib-serializinghtml==1.1.9 \ - --hash=sha256:0c64ff898339e1fac29abd2bf5f11078f3ec413cfe9c046d3120d7ca65530b54 \ - --hash=sha256:9b36e503703ff04f20e9675771df105e58aa029cfcbc23b8ed716019b7416ae1 +sphinxcontrib-serializinghtml==1.1.10 \ + --hash=sha256:326369b8df80a7d2d8d7f99aa5ac577f51ea51556ed974e7716cfd4fca3f6cb7 \ + --hash=sha256:93f3f5dc458b91b192fe10c397e324f262cf163d79f3282c158e8436a2c4511f # via sphinx sphinxext-opengraph==0.9.1 \ --hash=sha256:b3b230cc6a5b5189139df937f0d9c7b23c7c204493b22646273687969dcb760e \ @@ -908,45 +876,47 @@ sphinxext-rediraffe==0.2.7 \ --hash=sha256:651dcbfae5ffda9ffd534dfb8025f36120e5efb6ea1a33f5420023862b9f725d \ --hash=sha256:9e430a52d4403847f4ffb3a8dd6dfc34a9fe43525305131f52ed899743a5fd8c # via documenteer -tomlkit==0.12.3 \ - --hash=sha256:75baf5012d06501f07bee5bf8e801b9f343e7aac5a92581f20f80ce632e6b5a4 \ - --hash=sha256:b0a645a9156dc7cb5d3a1f0d4bab66db287fcb8e0430bdd4664a095ea16414ba +tomlkit==0.12.4 \ + --hash=sha256:5cd82d48a3dd89dee1f9d64420aa20ae65cfbd00668d6f094d7578a78efbb77b \ + --hash=sha256:7ca1cfc12232806517a8515047ba66a19369e71edf2439d0f5824f91032b6cc3 # via documenteer types-pyyaml==6.0.12.12 \ --hash=sha256:334373d392fde0fdf95af5c3f1661885fa10c52167b14593eb856289e1855062 \ --hash=sha256:c05bc6c158facb0676674b7f11fe3960db4f389718e19e62bd2b84d6205cfd24 # via -r requirements/dev.in -typing-extensions==4.9.0 \ - --hash=sha256:23478f88c37f27d76ac8aee6c905017a143b0b1b886c3c9f66bc2fd94f9f5783 \ - --hash=sha256:af72aea155e91adfc61c3ae9e0e342dbc0cba726d6cba4b6c72c1f34e47291cd +typing-extensions==4.10.0 \ + --hash=sha256:69b1a937c3a517342112fb4c6df7e72fc39a38e7891a5730ed4985b5214b5475 \ + --hash=sha256:b0abd7c89e8fb96f98db18d86106ff1d90ab692004eb746cf6eda2682f91b3cb # via # -c requirements/main.txt # mypy # pydantic # pydantic-core -uc-micro-py==1.0.2 \ - --hash=sha256:30ae2ac9c49f39ac6dce743bd187fcd2b574b16ca095fa74cd9396795c954c54 \ - --hash=sha256:8c9110c309db9d9e87302e2f4ad2c3152770930d88ab385cd544e7a7e75f3de0 +uc-micro-py==1.0.3 \ + --hash=sha256:d321b92cff673ec58027c04015fcaa8bb1e005478643ff4a500882eaab88c48a \ + --hash=sha256:db1dffff340817673d7b466ec86114a9dc0e9d4d9b5ba229d9d60e5c12600cd5 # via linkify-it-py -urllib3==2.1.0 \ - --hash=sha256:55901e917a5896a349ff771be919f8bd99aff50b79fe58fec595eb37bbc56bb3 \ - --hash=sha256:df7aa8afb0148fa78488e7899b2c59b5f4ffcfa82e6c54ccb9dd37c1d7b52d54 +urllib3==2.2.1 \ + --hash=sha256:450b20ec296a467077128bff42b73080516e71b56ff59a60a02bef2232c4fa9d \ + --hash=sha256:d0570876c61ab9e520d776c38acbbb5b05a776d3f9ff98a5c8fd5162a444cf19 # via # documenteer # requests -uvicorn==0.25.0 \ - --hash=sha256:6dddbad1d7ee0f5140aba5ec138ddc9612c5109399903828b4874c9937f009c2 \ - --hash=sha256:ce107f5d9bd02b4636001a77a4e74aab5e1e2b146868ebbad565237145af444c +uvicorn==0.27.1 \ + --hash=sha256:3d9a267296243532db80c83a959a3400502165ade2c1338dea4e67915fd4745a \ + --hash=sha256:5c89da2f3895767472a35556e539fd59f7edbe9b1e9c0e1c99eebeadc61838e4 # via # -c requirements/main.txt # -r requirements/dev.in -virtualenv==20.25.0 \ - --hash=sha256:4238949c5ffe6876362d9c0180fc6c3a824a7b12b80604eeb8085f2ed7460de3 \ - --hash=sha256:bf51c0d9c7dd63ea8e44086fa1e4fb1093a31e963b86959257378aef020e1f1b +virtualenv==20.25.1 \ + --hash=sha256:961c026ac520bac5f69acb8ea063e8a4f071bcc9457b9c1f28f6b085c511583a \ + --hash=sha256:e08e13ecdca7a0bd53798f356d5831434afa5b07b93f0abdf0797b7a06ffe197 # via pre-commit # The following packages are considered to be unsafe in a requirements file: -setuptools==69.0.3 \ - --hash=sha256:385eb4edd9c9d5c17540511303e39a147ce2fc04bc55289c322b9e5904fe2c05 \ - --hash=sha256:be1af57fc409f93647f2e8e4573a142ed38724b8cdd389706a867bb4efcf1e78 - # via nodeenv +setuptools==69.1.1 \ + --hash=sha256:02fa291a0471b3a18b2b2481ed902af520c69e8ae0919c13da936542754b4c56 \ + --hash=sha256:5c0806c7d9af348e6dd3777b4f4dbb42c7ad85b190104837488eab9a7c945cf8 + # via + # documenteer + # nodeenv diff --git a/requirements/main.txt b/requirements/main.txt index 1e5baeb..ed50546 100644 --- a/requirements/main.txt +++ b/requirements/main.txt @@ -16,9 +16,9 @@ annotated-types==0.6.0 \ --hash=sha256:0641064de18ba7a25dee8f96403ebc39113d0cb953a01429249d5c7564666a43 \ --hash=sha256:563339e807e53ffd9c267e99fc6d9ea23eb8443c08f112651963e24e22f84a5d # via pydantic -anyio==4.2.0 \ - --hash=sha256:745843b39e829e108e518c489b31dc757de7d2131d53fac32bd8df268227bfee \ - --hash=sha256:e1875bb4b4e2de1669f4bc7869b6d3f54231cdced71605e6e64c9be77e3be50f +anyio==4.3.0 \ + --hash=sha256:048e05d0f6caeed70d731f3db756d35dcc1f35747c8c403364a8332c630441b8 \ + --hash=sha256:f75253795a87df48568485fd18cdd2a3fa5c4f7c5be8e5e36637733fce06fed6 # via # httpx # starlette @@ -30,14 +30,16 @@ arq==0.25.0 \ async-timeout==4.0.3 \ --hash=sha256:4640d96be84d82d02ed59ea2b7105a0f7b33abe8703703cd0ab0bf87c427522f \ --hash=sha256:7405140ff1230c310e51dc27b3145b9092d659ce68ff733fb0cefe3ee42be028 - # via aioredis + # via + # aioredis + # redis attrs==23.2.0 \ --hash=sha256:935dc3b529c262f6cf76e50877d35a4bd3c1de194fd41f47a2b7ae8f19971f30 \ --hash=sha256:99b87a485a5820b23b879f04c2305b44b951b502fd64be915879d77a7e8fc6f1 # via aioredlock -certifi==2023.11.17 \ - --hash=sha256:9b469f3a900bf28dc19b8cfbf8019bf47f7fdd1a65a1d4ffb98fc14166beb4d1 \ - --hash=sha256:e036ab49d5b79556f99cfc2d9320b34cfbe5be05c5871b51de9329f0603b0474 +certifi==2024.2.2 \ + --hash=sha256:0569859f95fc761b18b45ef421b1290a0f65f147e92a1e5eb3e635f9a5e4e66f \ + --hash=sha256:dc383c07b76109f368f6106eee2b593b04a011ea4d55f652c6ca24a754d1cdd1 # via # httpcore # httpx @@ -102,36 +104,45 @@ click==8.1.7 \ # arq # safir # uvicorn -cryptography==41.0.7 \ - --hash=sha256:079b85658ea2f59c4f43b70f8119a52414cdb7be34da5d019a77bf96d473b960 \ - --hash=sha256:09616eeaef406f99046553b8a40fbf8b1e70795a91885ba4c96a70793de5504a \ - --hash=sha256:13f93ce9bea8016c253b34afc6bd6a75993e5c40672ed5405a9c832f0d4a00bc \ - --hash=sha256:37a138589b12069efb424220bf78eac59ca68b95696fc622b6ccc1c0a197204a \ - --hash=sha256:3c78451b78313fa81607fa1b3f1ae0a5ddd8014c38a02d9db0616133987b9cdf \ - --hash=sha256:43f2552a2378b44869fe8827aa19e69512e3245a219104438692385b0ee119d1 \ - --hash=sha256:48a0476626da912a44cc078f9893f292f0b3e4c739caf289268168d8f4702a39 \ - --hash=sha256:49f0805fc0b2ac8d4882dd52f4a3b935b210935d500b6b805f321addc8177406 \ - --hash=sha256:5429ec739a29df2e29e15d082f1d9ad683701f0ec7709ca479b3ff2708dae65a \ - --hash=sha256:5a1b41bc97f1ad230a41657d9155113c7521953869ae57ac39ac7f1bb471469a \ - --hash=sha256:68a2dec79deebc5d26d617bfdf6e8aab065a4f34934b22d3b5010df3ba36612c \ - --hash=sha256:7a698cb1dac82c35fcf8fe3417a3aaba97de16a01ac914b89a0889d364d2f6be \ - --hash=sha256:841df4caa01008bad253bce2a6f7b47f86dc9f08df4b433c404def869f590a15 \ - --hash=sha256:90452ba79b8788fa380dfb587cca692976ef4e757b194b093d845e8d99f612f2 \ - --hash=sha256:928258ba5d6f8ae644e764d0f996d61a8777559f72dfeb2eea7e2fe0ad6e782d \ - --hash=sha256:af03b32695b24d85a75d40e1ba39ffe7db7ffcb099fe507b39fd41a565f1b157 \ - --hash=sha256:b640981bf64a3e978a56167594a0e97db71c89a479da8e175d8bb5be5178c003 \ - --hash=sha256:c5ca78485a255e03c32b513f8c2bc39fedb7f5c5f8535545bdc223a03b24f248 \ - --hash=sha256:c7f3201ec47d5207841402594f1d7950879ef890c0c495052fa62f58283fde1a \ - --hash=sha256:d5ec85080cce7b0513cfd233914eb8b7bbd0633f1d1703aa28d1dd5a72f678ec \ - --hash=sha256:d6c391c021ab1f7a82da5d8d0b3cee2f4b2c455ec86c8aebbc84837a631ff309 \ - --hash=sha256:e3114da6d7f95d2dee7d3f4eec16dacff819740bbab931aff8648cb13c5ff5e7 \ - --hash=sha256:f983596065a18a2183e7f79ab3fd4c475205b839e02cbc0efbbf9666c4b3083d +cryptography==42.0.5 \ + --hash=sha256:0270572b8bd2c833c3981724b8ee9747b3ec96f699a9665470018594301439ee \ + --hash=sha256:111a0d8553afcf8eb02a4fea6ca4f59d48ddb34497aa8706a6cf536f1a5ec576 \ + --hash=sha256:16a48c23a62a2f4a285699dba2e4ff2d1cff3115b9df052cdd976a18856d8e3d \ + --hash=sha256:1b95b98b0d2af784078fa69f637135e3c317091b615cd0905f8b8a087e86fa30 \ + --hash=sha256:1f71c10d1e88467126f0efd484bd44bca5e14c664ec2ede64c32f20875c0d413 \ + --hash=sha256:2424ff4c4ac7f6b8177b53c17ed5d8fa74ae5955656867f5a8affaca36a27abb \ + --hash=sha256:2bce03af1ce5a5567ab89bd90d11e7bbdff56b8af3acbbec1faded8f44cb06da \ + --hash=sha256:329906dcc7b20ff3cad13c069a78124ed8247adcac44b10bea1130e36caae0b4 \ + --hash=sha256:37dd623507659e08be98eec89323469e8c7b4c1407c85112634ae3dbdb926fdd \ + --hash=sha256:3eaafe47ec0d0ffcc9349e1708be2aaea4c6dd4978d76bf6eb0cb2c13636c6fc \ + --hash=sha256:5e6275c09d2badf57aea3afa80d975444f4be8d3bc58f7f80d2a484c6f9485c8 \ + --hash=sha256:6fe07eec95dfd477eb9530aef5bead34fec819b3aaf6c5bd6d20565da607bfe1 \ + --hash=sha256:7367d7b2eca6513681127ebad53b2582911d1736dc2ffc19f2c3ae49997496bc \ + --hash=sha256:7cde5f38e614f55e28d831754e8a3bacf9ace5d1566235e39d91b35502d6936e \ + --hash=sha256:9481ffe3cf013b71b2428b905c4f7a9a4f76ec03065b05ff499bb5682a8d9ad8 \ + --hash=sha256:98d8dc6d012b82287f2c3d26ce1d2dd130ec200c8679b6213b3c73c08b2b7940 \ + --hash=sha256:a011a644f6d7d03736214d38832e030d8268bcff4a41f728e6030325fea3e400 \ + --hash=sha256:a2913c5375154b6ef2e91c10b5720ea6e21007412f6437504ffea2109b5a33d7 \ + --hash=sha256:a30596bae9403a342c978fb47d9b0ee277699fa53bbafad14706af51fe543d16 \ + --hash=sha256:b03c2ae5d2f0fc05f9a2c0c997e1bc18c8229f392234e8a0194f202169ccd278 \ + --hash=sha256:b6cd2203306b63e41acdf39aa93b86fb566049aeb6dc489b70e34bcd07adca74 \ + --hash=sha256:b7ffe927ee6531c78f81aa17e684e2ff617daeba7f189f911065b2ea2d526dec \ + --hash=sha256:b8cac287fafc4ad485b8a9b67d0ee80c66bf3574f655d3b97ef2e1082360faf1 \ + --hash=sha256:ba334e6e4b1d92442b75ddacc615c5476d4ad55cc29b15d590cc6b86efa487e2 \ + --hash=sha256:ba3e4a42397c25b7ff88cdec6e2a16c2be18720f317506ee25210f6d31925f9c \ + --hash=sha256:c41fb5e6a5fe9ebcd58ca3abfeb51dffb5d83d6775405305bfa8715b76521922 \ + --hash=sha256:cd2030f6650c089aeb304cf093f3244d34745ce0cfcc39f20c6fbfe030102e2a \ + --hash=sha256:cd65d75953847815962c84a4654a84850b2bb4aed3f26fadcc1c13892e1e29f6 \ + --hash=sha256:e4985a790f921508f36f81831817cbc03b102d643b5fcb81cd33df3fa291a1a1 \ + --hash=sha256:e807b3188f9eb0eaa7bbb579b462c5ace579f1cedb28107ce8b48a9f7ad3679e \ + --hash=sha256:f12764b8fffc7a123f641d7d049d382b73f96a34117e0b637b80643169cec8ac \ + --hash=sha256:f8837fe1d6ac4a8052a9a8ddab256bc006242696f03368a4009be7ee3075cdb7 # via # pyjwt # safir -fastapi==0.108.0 \ - --hash=sha256:5056e504ac6395bf68493d71fcfc5352fdbd5fda6f88c21f6420d80d81163296 \ - --hash=sha256:8c7bc6d315da963ee4cdb605557827071a9a7f95aeb8fcdd3bde48cdc8764dd7 +fastapi==0.110.0 \ + --hash=sha256:266775f0dcc95af9d3ef39bad55cff525329a931d5fd51930aadd4f428bf7ff3 \ + --hash=sha256:87a1f6fb632a218222c5984be540055346a8f5d8a68e8f6fb647b1dc9934de4b # via # -r requirements/main.in # safir @@ -262,9 +273,9 @@ hiredis==2.3.2 \ # via # aioredis # redis -httpcore==1.0.2 \ - --hash=sha256:096cc05bca73b8e459a1fc3dcf585148f63e534eae4339559c9b8a8d6399acc7 \ - --hash=sha256:9fc092e4799b26174648e54b74ed5f683132a464e95643b226e00c2ed2fa6535 +httpcore==1.0.4 \ + --hash=sha256:ac418c1db41bade2ad53ae2f3834a3a0f5ae76b56cf5aa497d2d033384fc7d73 \ + --hash=sha256:cb2839ccfcba0d2d3c1131d3c3e26dfc327326fbe7a5dc0dbfe9f6c9151bb022 # via httpx httptools==0.6.1 \ --hash=sha256:00d5d4b68a717765b1fabfd9ca755bd12bf44105eeb806c03d1962acd9b8e563 \ @@ -304,9 +315,9 @@ httptools==0.6.1 \ --hash=sha256:e57997ac7fb7ee43140cc03664de5f268813a481dff6245e0075925adc6aa185 \ --hash=sha256:fe467eb086d80217b7584e61313ebadc8d187a4d95bb62031b7bab4b205c3ba3 # via uvicorn -httpx==0.26.0 \ - --hash=sha256:451b55c30d5185ea6b23c2c793abf9bb237d2a7dfb901ced6ff69ad37ec1dfaf \ - --hash=sha256:8915f5a3627c4d47b73e8202457cb28f1266982d1159bd5779d86a80c0eab1cd +httpx==0.27.0 \ + --hash=sha256:71d5465162c13681bff01ad59b2cc68dd838ea1f10e51574bac27103f00c91a5 \ + --hash=sha256:a0cb88a46f32dc874e04ee956e4c2764aba2aa228f650b06788ba6bda2962ab5 # via # -r requirements/main.in # safir @@ -324,124 +335,98 @@ pycparser==2.21 \ --hash=sha256:8ee45429555515e1f6b185e78100aea234072576aa43ab53aefcae078162fca9 \ --hash=sha256:e644fdec12f7872f86c58ff790da456218b10f863970249516d60a5eaca77206 # via cffi -pydantic==2.5.3 \ - --hash=sha256:b3ef57c62535b0941697cce638c08900d87fcb67e29cfa99e8a68f747f393f7a \ - --hash=sha256:d0caf5954bee831b6bfe7e338c32b9e30c85dfe080c843680783ac2b631673b4 +pydantic==2.6.3 \ + --hash=sha256:72c6034df47f46ccdf81869fddb81aade68056003900a8724a4f160700016a2a \ + --hash=sha256:e07805c4c7f5c6826e33a1d4c9d47950d7eaf34868e2690f8594d2e30241f11f # via # -r requirements/main.in # fastapi # pydantic-settings # safir -pydantic-core==2.14.6 \ - --hash=sha256:00646784f6cd993b1e1c0e7b0fdcbccc375d539db95555477771c27555e3c556 \ - --hash=sha256:00b1087dabcee0b0ffd104f9f53d7d3eaddfaa314cdd6726143af6bc713aa27e \ - --hash=sha256:0348b1dc6b76041516e8a854ff95b21c55f5a411c3297d2ca52f5528e49d8411 \ - --hash=sha256:036137b5ad0cb0004c75b579445a1efccd072387a36c7f217bb8efd1afbe5245 \ - --hash=sha256:095b707bb287bfd534044166ab767bec70a9bba3175dcdc3371782175c14e43c \ - --hash=sha256:0c08de15d50fa190d577e8591f0329a643eeaed696d7771760295998aca6bc66 \ - --hash=sha256:1302a54f87b5cd8528e4d6d1bf2133b6aa7c6122ff8e9dc5220fbc1e07bffebd \ - --hash=sha256:172de779e2a153d36ee690dbc49c6db568d7b33b18dc56b69a7514aecbcf380d \ - --hash=sha256:1b027c86c66b8627eb90e57aee1f526df77dc6d8b354ec498be9a757d513b92b \ - --hash=sha256:1ce830e480f6774608dedfd4a90c42aac4a7af0a711f1b52f807130c2e434c06 \ - --hash=sha256:1fd0c1d395372843fba13a51c28e3bb9d59bd7aebfeb17358ffaaa1e4dbbe948 \ - --hash=sha256:23598acb8ccaa3d1d875ef3b35cb6376535095e9405d91a3d57a8c7db5d29341 \ - --hash=sha256:24368e31be2c88bd69340fbfe741b405302993242ccb476c5c3ff48aeee1afe0 \ - --hash=sha256:26a92ae76f75d1915806b77cf459811e772d8f71fd1e4339c99750f0e7f6324f \ - --hash=sha256:27e524624eace5c59af499cd97dc18bb201dc6a7a2da24bfc66ef151c69a5f2a \ - --hash=sha256:2b8719037e570639e6b665a4050add43134d80b687288ba3ade18b22bbb29dd2 \ - --hash=sha256:2c5bcf3414367e29f83fd66f7de64509a8fd2368b1edf4351e862910727d3e51 \ - --hash=sha256:2dbe357bc4ddda078f79d2a36fc1dd0494a7f2fad83a0a684465b6f24b46fe80 \ - --hash=sha256:2f5fa187bde8524b1e37ba894db13aadd64faa884657473b03a019f625cee9a8 \ - --hash=sha256:2f6ffc6701a0eb28648c845f4945a194dc7ab3c651f535b81793251e1185ac3d \ - --hash=sha256:314ccc4264ce7d854941231cf71b592e30d8d368a71e50197c905874feacc8a8 \ - --hash=sha256:36026d8f99c58d7044413e1b819a67ca0e0b8ebe0f25e775e6c3d1fabb3c38fb \ - --hash=sha256:36099c69f6b14fc2c49d7996cbf4f87ec4f0e66d1c74aa05228583225a07b590 \ - --hash=sha256:36fa402dcdc8ea7f1b0ddcf0df4254cc6b2e08f8cd80e7010d4c4ae6e86b2a87 \ - --hash=sha256:370ffecb5316ed23b667d99ce4debe53ea664b99cc37bfa2af47bc769056d534 \ - --hash=sha256:3860c62057acd95cc84044e758e47b18dcd8871a328ebc8ccdefd18b0d26a21b \ - --hash=sha256:399ac0891c284fa8eb998bcfa323f2234858f5d2efca3950ae58c8f88830f145 \ - --hash=sha256:3a0b5db001b98e1c649dd55afa928e75aa4087e587b9524a4992316fa23c9fba \ - --hash=sha256:3dcf1978be02153c6a31692d4fbcc2a3f1db9da36039ead23173bc256ee3b91b \ - --hash=sha256:4241204e4b36ab5ae466ecec5c4c16527a054c69f99bba20f6f75232a6a534e2 \ - --hash=sha256:438027a975cc213a47c5d70672e0d29776082155cfae540c4e225716586be75e \ - --hash=sha256:43e166ad47ba900f2542a80d83f9fc65fe99eb63ceec4debec160ae729824052 \ - --hash=sha256:478e9e7b360dfec451daafe286998d4a1eeaecf6d69c427b834ae771cad4b622 \ - --hash=sha256:4ce8299b481bcb68e5c82002b96e411796b844d72b3e92a3fbedfe8e19813eab \ - --hash=sha256:4f86f1f318e56f5cbb282fe61eb84767aee743ebe32c7c0834690ebea50c0a6b \ - --hash=sha256:55a23dcd98c858c0db44fc5c04fc7ed81c4b4d33c653a7c45ddaebf6563a2f66 \ - --hash=sha256:599c87d79cab2a6a2a9df4aefe0455e61e7d2aeede2f8577c1b7c0aec643ee8e \ - --hash=sha256:5aa90562bc079c6c290f0512b21768967f9968e4cfea84ea4ff5af5d917016e4 \ - --hash=sha256:64634ccf9d671c6be242a664a33c4acf12882670b09b3f163cd00a24cffbd74e \ - --hash=sha256:667aa2eac9cd0700af1ddb38b7b1ef246d8cf94c85637cbb03d7757ca4c3fdec \ - --hash=sha256:6a31d98c0d69776c2576dda4b77b8e0c69ad08e8b539c25c7d0ca0dc19a50d6c \ - --hash=sha256:6af4b3f52cc65f8a0bc8b1cd9676f8c21ef3e9132f21fed250f6958bd7223bed \ - --hash=sha256:6c8edaea3089bf908dd27da8f5d9e395c5b4dc092dbcce9b65e7156099b4b937 \ - --hash=sha256:71d72ca5eaaa8d38c8df16b7deb1a2da4f650c41b58bb142f3fb75d5ad4a611f \ - --hash=sha256:72f9a942d739f09cd42fffe5dc759928217649f070056f03c70df14f5770acf9 \ - --hash=sha256:747265448cb57a9f37572a488a57d873fd96bf51e5bb7edb52cfb37124516da4 \ - --hash=sha256:75ec284328b60a4e91010c1acade0c30584f28a1f345bc8f72fe8b9e46ec6a96 \ - --hash=sha256:78d0768ee59baa3de0f4adac9e3748b4b1fffc52143caebddfd5ea2961595277 \ - --hash=sha256:78ee52ecc088c61cce32b2d30a826f929e1708f7b9247dc3b921aec367dc1b23 \ - --hash=sha256:7be719e4d2ae6c314f72844ba9d69e38dff342bc360379f7c8537c48e23034b7 \ - --hash=sha256:7e1f4744eea1501404b20b0ac059ff7e3f96a97d3e3f48ce27a139e053bb370b \ - --hash=sha256:7e90d6cc4aad2cc1f5e16ed56e46cebf4877c62403a311af20459c15da76fd91 \ - --hash=sha256:7ebe3416785f65c28f4f9441e916bfc8a54179c8dea73c23023f7086fa601c5d \ - --hash=sha256:7f41533d7e3cf9520065f610b41ac1c76bc2161415955fbcead4981b22c7611e \ - --hash=sha256:7f5025db12fc6de7bc1104d826d5aee1d172f9ba6ca936bf6474c2148ac336c1 \ - --hash=sha256:86c963186ca5e50d5c8287b1d1c9d3f8f024cbe343d048c5bd282aec2d8641f2 \ - --hash=sha256:86ce5fcfc3accf3a07a729779d0b86c5d0309a4764c897d86c11089be61da160 \ - --hash=sha256:8a14c192c1d724c3acbfb3f10a958c55a2638391319ce8078cb36c02283959b9 \ - --hash=sha256:8b93785eadaef932e4fe9c6e12ba67beb1b3f1e5495631419c784ab87e975670 \ - --hash=sha256:8ed1af8692bd8d2a29d702f1a2e6065416d76897d726e45a1775b1444f5928a7 \ - --hash=sha256:92879bce89f91f4b2416eba4429c7b5ca22c45ef4a499c39f0c5c69257522c7c \ - --hash=sha256:94fc0e6621e07d1e91c44e016cc0b189b48db053061cc22d6298a611de8071bb \ - --hash=sha256:982487f8931067a32e72d40ab6b47b1628a9c5d344be7f1a4e668fb462d2da42 \ - --hash=sha256:9862bf828112e19685b76ca499b379338fd4c5c269d897e218b2ae8fcb80139d \ - --hash=sha256:99b14dbea2fdb563d8b5a57c9badfcd72083f6006caf8e126b491519c7d64ca8 \ - --hash=sha256:9c6a5c79b28003543db3ba67d1df336f253a87d3112dac3a51b94f7d48e4c0e1 \ - --hash=sha256:a19b794f8fe6569472ff77602437ec4430f9b2b9ec7a1105cfd2232f9ba355e6 \ - --hash=sha256:a306cdd2ad3a7d795d8e617a58c3a2ed0f76c8496fb7621b6cd514eb1532cae8 \ - --hash=sha256:a3dde6cac75e0b0902778978d3b1646ca9f438654395a362cb21d9ad34b24acf \ - --hash=sha256:a874f21f87c485310944b2b2734cd6d318765bcbb7515eead33af9641816506e \ - --hash=sha256:a983cca5ed1dd9a35e9e42ebf9f278d344603bfcb174ff99a5815f953925140a \ - --hash=sha256:aca48506a9c20f68ee61c87f2008f81f8ee99f8d7f0104bff3c47e2d148f89d9 \ - --hash=sha256:b2602177668f89b38b9f84b7b3435d0a72511ddef45dc14446811759b82235a1 \ - --hash=sha256:b3e5fe4538001bb82e2295b8d2a39356a84694c97cb73a566dc36328b9f83b40 \ - --hash=sha256:b6ca36c12a5120bad343eef193cc0122928c5c7466121da7c20f41160ba00ba2 \ - --hash=sha256:b89f4477d915ea43b4ceea6756f63f0288941b6443a2b28c69004fe07fde0d0d \ - --hash=sha256:b9a9d92f10772d2a181b5ca339dee066ab7d1c9a34ae2421b2a52556e719756f \ - --hash=sha256:c99462ffc538717b3e60151dfaf91125f637e801f5ab008f81c402f1dff0cd0f \ - --hash=sha256:cb92f9061657287eded380d7dc455bbf115430b3aa4741bdc662d02977e7d0af \ - --hash=sha256:cdee837710ef6b56ebd20245b83799fce40b265b3b406e51e8ccc5b85b9099b7 \ - --hash=sha256:cf10b7d58ae4a1f07fccbf4a0a956d705356fea05fb4c70608bb6fa81d103cda \ - --hash=sha256:d15687d7d7f40333bd8266f3814c591c2e2cd263fa2116e314f60d82086e353a \ - --hash=sha256:d5c28525c19f5bb1e09511669bb57353d22b94cf8b65f3a8d141c389a55dec95 \ - --hash=sha256:d5f916acf8afbcab6bacbb376ba7dc61f845367901ecd5e328fc4d4aef2fcab0 \ - --hash=sha256:dab03ed811ed1c71d700ed08bde8431cf429bbe59e423394f0f4055f1ca0ea60 \ - --hash=sha256:db453f2da3f59a348f514cfbfeb042393b68720787bbef2b4c6068ea362c8149 \ - --hash=sha256:de2a0645a923ba57c5527497daf8ec5df69c6eadf869e9cd46e86349146e5975 \ - --hash=sha256:dea7fcd62915fb150cdc373212141a30037e11b761fbced340e9db3379b892d4 \ - --hash=sha256:dfcbebdb3c4b6f739a91769aea5ed615023f3c88cb70df812849aef634c25fbe \ - --hash=sha256:dfcebb950aa7e667ec226a442722134539e77c575f6cfaa423f24371bb8d2e94 \ - --hash=sha256:e0641b506486f0b4cd1500a2a65740243e8670a2549bb02bc4556a83af84ae03 \ - --hash=sha256:e33b0834f1cf779aa839975f9d8755a7c2420510c0fa1e9fa0497de77cd35d2c \ - --hash=sha256:e4ace1e220b078c8e48e82c081e35002038657e4b37d403ce940fa679e57113b \ - --hash=sha256:e4cf2d5829f6963a5483ec01578ee76d329eb5caf330ecd05b3edd697e7d768a \ - --hash=sha256:e574de99d735b3fc8364cba9912c2bec2da78775eba95cbb225ef7dda6acea24 \ - --hash=sha256:e646c0e282e960345314f42f2cea5e0b5f56938c093541ea6dbf11aec2862391 \ - --hash=sha256:e8a5ac97ea521d7bde7621d86c30e86b798cdecd985723c4ed737a2aa9e77d0c \ - --hash=sha256:eedf97be7bc3dbc8addcef4142f4b4164066df0c6f36397ae4aaed3eb187d8ab \ - --hash=sha256:ef633add81832f4b56d3b4c9408b43d530dfca29e68fb1b797dcb861a2c734cd \ - --hash=sha256:f27207e8ca3e5e021e2402ba942e5b4c629718e665c81b8b306f3c8b1ddbb786 \ - --hash=sha256:f85f3843bdb1fe80e8c206fe6eed7a1caeae897e496542cee499c374a85c6e08 \ - --hash=sha256:f8e81e4b55930e5ffab4a68db1af431629cf2e4066dbdbfef65348b8ab804ea8 \ - --hash=sha256:f96ae96a060a8072ceff4cfde89d261837b4294a4f28b84a28765470d502ccc6 \ - --hash=sha256:fd9e98b408384989ea4ab60206b8e100d8687da18b5c813c11e92fd8212a98e0 \ - --hash=sha256:ffff855100bc066ff2cd3aa4a60bc9534661816b110f0243e59503ec2df38421 +pydantic-core==2.16.3 \ + --hash=sha256:00ee1c97b5364b84cb0bd82e9bbf645d5e2871fb8c58059d158412fee2d33d8a \ + --hash=sha256:0d32576b1de5a30d9a97f300cc6a3f4694c428d956adbc7e6e2f9cad279e45ed \ + --hash=sha256:0df446663464884297c793874573549229f9eca73b59360878f382a0fc085979 \ + --hash=sha256:0f56ae86b60ea987ae8bcd6654a887238fd53d1384f9b222ac457070b7ac4cff \ + --hash=sha256:13dcc4802961b5f843a9385fc821a0b0135e8c07fc3d9949fd49627c1a5e6ae5 \ + --hash=sha256:162e498303d2b1c036b957a1278fa0899d02b2842f1ff901b6395104c5554a45 \ + --hash=sha256:1b662180108c55dfbf1280d865b2d116633d436cfc0bba82323554873967b340 \ + --hash=sha256:1cac689f80a3abab2d3c0048b29eea5751114054f032a941a32de4c852c59cad \ + --hash=sha256:21b888c973e4f26b7a96491c0965a8a312e13be108022ee510248fe379a5fa23 \ + --hash=sha256:287073c66748f624be4cef893ef9174e3eb88fe0b8a78dc22e88eca4bc357ca6 \ + --hash=sha256:2a1ef6a36fdbf71538142ed604ad19b82f67b05749512e47f247a6ddd06afdc7 \ + --hash=sha256:2a72fb9963cba4cd5793854fd12f4cfee731e86df140f59ff52a49b3552db241 \ + --hash=sha256:2acca2be4bb2f2147ada8cac612f8a98fc09f41c89f87add7256ad27332c2fda \ + --hash=sha256:2f583bd01bbfbff4eaee0868e6fc607efdfcc2b03c1c766b06a707abbc856187 \ + --hash=sha256:33809aebac276089b78db106ee692bdc9044710e26f24a9a2eaa35a0f9fa70ba \ + --hash=sha256:36fa178aacbc277bc6b62a2c3da95226520da4f4e9e206fdf076484363895d2c \ + --hash=sha256:4204e773b4b408062960e65468d5346bdfe139247ee5f1ca2a378983e11388a2 \ + --hash=sha256:4384a8f68ddb31a0b0c3deae88765f5868a1b9148939c3f4121233314ad5532c \ + --hash=sha256:456855f57b413f077dff513a5a28ed838dbbb15082ba00f80750377eed23d132 \ + --hash=sha256:49d5d58abd4b83fb8ce763be7794d09b2f50f10aa65c0f0c1696c677edeb7cbf \ + --hash=sha256:4ac6b4ce1e7283d715c4b729d8f9dab9627586dafce81d9eaa009dd7f25dd972 \ + --hash=sha256:4df8a199d9f6afc5ae9a65f8f95ee52cae389a8c6b20163762bde0426275b7db \ + --hash=sha256:500960cb3a0543a724a81ba859da816e8cf01b0e6aaeedf2c3775d12ee49cade \ + --hash=sha256:519ae0312616026bf4cedc0fe459e982734f3ca82ee8c7246c19b650b60a5ee4 \ + --hash=sha256:578114bc803a4c1ff9946d977c221e4376620a46cf78da267d946397dc9514a8 \ + --hash=sha256:5c5cbc703168d1b7a838668998308018a2718c2130595e8e190220238addc96f \ + --hash=sha256:6162f8d2dc27ba21027f261e4fa26f8bcb3cf9784b7f9499466a311ac284b5b9 \ + --hash=sha256:704d35ecc7e9c31d48926150afada60401c55efa3b46cd1ded5a01bdffaf1d48 \ + --hash=sha256:716b542728d4c742353448765aa7cdaa519a7b82f9564130e2b3f6766018c9ec \ + --hash=sha256:72282ad4892a9fb2da25defeac8c2e84352c108705c972db82ab121d15f14e6d \ + --hash=sha256:7233d65d9d651242a68801159763d09e9ec96e8a158dbf118dc090cd77a104c9 \ + --hash=sha256:732da3243e1b8d3eab8c6ae23ae6a58548849d2e4a4e03a1924c8ddf71a387cb \ + --hash=sha256:75b81e678d1c1ede0785c7f46690621e4c6e63ccd9192af1f0bd9d504bbb6bf4 \ + --hash=sha256:75f76ee558751746d6a38f89d60b6228fa174e5172d143886af0f85aa306fd89 \ + --hash=sha256:7ee8d5f878dccb6d499ba4d30d757111847b6849ae07acdd1205fffa1fc1253c \ + --hash=sha256:7f752826b5b8361193df55afcdf8ca6a57d0232653494ba473630a83ba50d8c9 \ + --hash=sha256:86b3d0033580bd6bbe07590152007275bd7af95f98eaa5bd36f3da219dcd93da \ + --hash=sha256:8d62da299c6ecb04df729e4b5c52dc0d53f4f8430b4492b93aa8de1f541c4aac \ + --hash=sha256:8e47755d8152c1ab5b55928ab422a76e2e7b22b5ed8e90a7d584268dd49e9c6b \ + --hash=sha256:9091632a25b8b87b9a605ec0e61f241c456e9248bfdcf7abdf344fdb169c81cf \ + --hash=sha256:936e5db01dd49476fa8f4383c259b8b1303d5dd5fb34c97de194560698cc2c5e \ + --hash=sha256:99b6add4c0b39a513d323d3b93bc173dac663c27b99860dd5bf491b240d26137 \ + --hash=sha256:9c865a7ee6f93783bd5d781af5a4c43dadc37053a5b42f7d18dc019f8c9d2bd1 \ + --hash=sha256:a425479ee40ff021f8216c9d07a6a3b54b31c8267c6e17aa88b70d7ebd0e5e5b \ + --hash=sha256:a4b2bf78342c40b3dc830880106f54328928ff03e357935ad26c7128bbd66ce8 \ + --hash=sha256:a6b1bb0827f56654b4437955555dc3aeeebeddc47c2d7ed575477f082622c49e \ + --hash=sha256:aaf09e615a0bf98d406657e0008e4a8701b11481840be7d31755dc9f97c44053 \ + --hash=sha256:b1f6f5938d63c6139860f044e2538baeee6f0b251a1816e7adb6cbce106a1f01 \ + --hash=sha256:b29eeb887aa931c2fcef5aa515d9d176d25006794610c264ddc114c053bf96fe \ + --hash=sha256:b3992a322a5617ded0a9f23fd06dbc1e4bd7cf39bc4ccf344b10f80af58beacd \ + --hash=sha256:b5b6079cc452a7c53dd378c6f881ac528246b3ac9aae0f8eef98498a75657805 \ + --hash=sha256:b60cc1a081f80a2105a59385b92d82278b15d80ebb3adb200542ae165cd7d183 \ + --hash=sha256:b926dd38db1519ed3043a4de50214e0d600d404099c3392f098a7f9d75029ff8 \ + --hash=sha256:bd87f48924f360e5d1c5f770d6155ce0e7d83f7b4e10c2f9ec001c73cf475c99 \ + --hash=sha256:bda1ee3e08252b8d41fa5537413ffdddd58fa73107171a126d3b9ff001b9b820 \ + --hash=sha256:be0ec334369316fa73448cc8c982c01e5d2a81c95969d58b8f6e272884df0074 \ + --hash=sha256:c6119dc90483a5cb50a1306adb8d52c66e447da88ea44f323e0ae1a5fcb14256 \ + --hash=sha256:c9803edf8e29bd825f43481f19c37f50d2b01899448273b3a7758441b512acf8 \ + --hash=sha256:c9bd22a2a639e26171068f8ebb5400ce2c1bc7d17959f60a3b753ae13c632975 \ + --hash=sha256:cbcc558401de90a746d02ef330c528f2e668c83350f045833543cd57ecead1ad \ + --hash=sha256:cf6204fe865da605285c34cf1172879d0314ff267b1c35ff59de7154f35fdc2e \ + --hash=sha256:d33dd21f572545649f90c38c227cc8631268ba25c460b5569abebdd0ec5974ca \ + --hash=sha256:d89ca19cdd0dd5f31606a9329e309d4fcbb3df860960acec32630297d61820df \ + --hash=sha256:d8f99b147ff3fcf6b3cc60cb0c39ea443884d5559a30b1481e92495f2310ff2b \ + --hash=sha256:d937653a696465677ed583124b94a4b2d79f5e30b2c46115a68e482c6a591c8a \ + --hash=sha256:dcca5d2bf65c6fb591fff92da03f94cd4f315972f97c21975398bd4bd046854a \ + --hash=sha256:ded1c35f15c9dea16ead9bffcde9bb5c7c031bff076355dc58dcb1cb436c4721 \ + --hash=sha256:e3e70c94a0c3841e6aa831edab1619ad5c511199be94d0c11ba75fe06efe107a \ + --hash=sha256:e56f8186d6210ac7ece503193ec84104da7ceb98f68ce18c07282fcc2452e76f \ + --hash=sha256:e7774b570e61cb998490c5235740d475413a1f6de823169b4cf94e2fe9e9f6b2 \ + --hash=sha256:e7c6ed0dc9d8e65f24f5824291550139fe6f37fac03788d4580da0d33bc00c97 \ + --hash=sha256:ec08be75bb268473677edb83ba71e7e74b43c008e4a7b1907c6d57e940bf34b6 \ + --hash=sha256:ecdf6bf5f578615f2e985a5e1f6572e23aa632c4bd1dc67f8f406d445ac115ed \ + --hash=sha256:ed25e1835c00a332cb10c683cd39da96a719ab1dfc08427d476bce41b92531fc \ + --hash=sha256:f4cb85f693044e0f71f394ff76c98ddc1bc0953e48c061725e540396d5c8a2e1 \ + --hash=sha256:f53aace168a2a10582e570b7736cc5bef12cae9cf21775e3eafac597e8551fbe \ + --hash=sha256:f651dd19363c632f4abe3480a7c87a9773be27cfe1341aef06e8759599454120 \ + --hash=sha256:fc4ad7f7ee1a13d9cb49d8198cd7d7e3aa93e425f371a68235f784e99741561f \ + --hash=sha256:fee427241c2d9fb7192b658190f9f5fd6dfe41e02f3c1489d2ec1e6a5ab1e04a # via pydantic -pydantic-settings==2.1.0 \ - --hash=sha256:26b1492e0a24755626ac5e6d715e9077ab7ad4fb5f19a8b7ed7011d52f36141c \ - --hash=sha256:7621c0cb5d90d1140d2f0ef557bdf03573aac7035948109adf2574770b77605a +pydantic-settings==2.2.1 \ + --hash=sha256:00b9f6a5e95553590434c0fa01ead0b216c3e10bc54ae02e37f359948643c5ed \ + --hash=sha256:0235391d26db4d2190cb9b31051c4b46882d28a51533f97440867f012d4da091 # via -r requirements/main.in pyjwt[crypto]==2.8.0 \ --hash=sha256:57e28d156e3d5c10088e0c68abb90bfac3df82b40a71bd0daa20c65ccd5c23de \ @@ -449,9 +434,9 @@ pyjwt[crypto]==2.8.0 \ # via # gidgethub # pyjwt -python-dotenv==1.0.0 \ - --hash=sha256:a8df96034aae6d2d50a4ebe8216326c61c3eb64836776504fcca410e5937a3ba \ - --hash=sha256:f5971a9226b701070a4bf2c38c89e5a3f0d64de8debda981d1db98583009122a +python-dotenv==1.0.1 \ + --hash=sha256:e324ee90a023d808f1959c46bcbc04446a10ced277783dc6ee09987c37ec10ca \ + --hash=sha256:f7b63ef50f1b690dddf550d03497b66d609393b40b564ed0d674909a68ebf16a # via # pydantic-settings # uvicorn @@ -485,6 +470,7 @@ pyyaml==6.0.1 \ --hash=sha256:8d4e9c88387b0f5c7d5f281e55304de64cf7f9c0021a3525bd3b1c542da3b0e4 \ --hash=sha256:9046c58c4395dff28dd494285c82ba00b546adfc7ef001486fbf0324bc174fba \ --hash=sha256:9eb6caa9a297fc2c2fb8862bc5370d0303ddba53ba97e71f08023b6cd73d16a8 \ + --hash=sha256:a08c6f0fe150303c1c6b71ebcd7213c2858041a7e01975da3a99aed1e7a378ef \ --hash=sha256:a0cd17c15d3bb3fa06978b4e8958dcdc6e0174ccea823003a106c7d4d7899ac5 \ --hash=sha256:afd7e57eddb1a54f0f1a974bc4391af8bcce0b444685d936840f125cf046d5bd \ --hash=sha256:b1275ad35a5d18c62a7220633c913e1b42d44b46ee12554e5fd39c70a243d6a3 \ @@ -509,36 +495,34 @@ pyyaml==6.0.1 \ # via # -r requirements/main.in # uvicorn -redis[hiredis]==5.0.1 \ - --hash=sha256:0dab495cd5753069d3bc650a0dde8a8f9edde16fc5691b689a566eda58100d0f \ - --hash=sha256:ed4802971884ae19d640775ba3b03aa2e7bd5e8fb8dfaed2decce4d0fc48391f - # via - # arq - # redis -safir[arq]==5.1.0 \ - --hash=sha256:0e4162b3b1fca558b037c06d7221b96996d7a55c92108e2e28e744d224c0076d \ - --hash=sha256:e04019e7e914aefc5ce1a9ca73c227eb3a84255d952bcd4cf3746e11cf7b1a15 +redis[hiredis]==5.0.2 \ + --hash=sha256:3f82cc80d350e93042c8e6e7a5d0596e4dd68715babffba79492733e1f367037 \ + --hash=sha256:4caa8e1fcb6f3c0ef28dba99535101d80934b7d4cd541bbb47f4a3826ee472d1 + # via arq +safir[arq]==5.2.1 \ + --hash=sha256:1b61cc72881ddfb66e1f84b6c34ca7e062f27b5669b9d1d07377ebd117ce3ebf \ + --hash=sha256:e39e2260e87303de9aaac157b45743ec9f82d2e84065d10b21008fceaa8aa407 # via -r requirements/main.in -sniffio==1.3.0 \ - --hash=sha256:e60305c5e5d314f5389259b7f22aaa33d8f7dee49763119234af3755c55b9101 \ - --hash=sha256:eecefdce1e5bbfb7ad2eeaabf7c1eeb404d7757c379bd1f7e5cce9d8bf425384 +sniffio==1.3.1 \ + --hash=sha256:2f6da418d1f1e0fddd844478f41680e794e6051915791a034ff65e5f100525a2 \ + --hash=sha256:f4324edc670a0f49750a81b895f35c3adb843cca46f0530f79fc1babb23789dc # via # anyio # httpx -starlette==0.32.0.post1 \ - --hash=sha256:cd0cb10ddb49313f609cedfac62c8c12e56c7314b66d89bb077ba228bada1b09 \ - --hash=sha256:e54e2b7e2fb06dff9eac40133583f10dfa05913f5a85bf26f427c7a40a9a3d02 +starlette==0.36.3 \ + --hash=sha256:13d429aa93a61dc40bf503e8c801db1f1bca3dc706b10ef2434a36123568f044 \ + --hash=sha256:90a671733cfb35771d8cc605e0b679d23b992f8dcfad48cc60b38cb29aeb7080 # via # -r requirements/main.in # fastapi # safir -structlog==23.3.0 \ - --hash=sha256:24b42b914ac6bc4a4e6f716e82ac70d7fb1e8c3b1035a765591953bfc37101a5 \ - --hash=sha256:d6922a88ceabef5b13b9eda9c4043624924f60edbb00397f4d193bd754cde60a +structlog==24.1.0 \ + --hash=sha256:3f6efe7d25fab6e86f277713c218044669906537bb717c1807a09d46bca0714d \ + --hash=sha256:41a09886e4d55df25bdcb9b5c9674bccfab723ff43e0a86a1b7b236be8e57b16 # via safir -typing-extensions==4.9.0 \ - --hash=sha256:23478f88c37f27d76ac8aee6c905017a143b0b1b886c3c9f66bc2fd94f9f5783 \ - --hash=sha256:af72aea155e91adfc61c3ae9e0e342dbc0cba726d6cba4b6c72c1f34e47291cd +typing-extensions==4.10.0 \ + --hash=sha256:69b1a937c3a517342112fb4c6df7e72fc39a38e7891a5730ed4985b5214b5475 \ + --hash=sha256:b0abd7c89e8fb96f98db18d86106ff1d90ab692004eb746cf6eda2682f91b3cb # via # arq # fastapi @@ -548,9 +532,9 @@ uritemplate==4.1.1 \ --hash=sha256:4346edfc5c3b79f694bccd6d6099a322bbeb628dbf2cd86eea55a456ce5124f0 \ --hash=sha256:830c08b8d99bdd312ea4ead05994a38e8936266f84b9a7878232db50b044e02e # via gidgethub -uvicorn[standard]==0.25.0 \ - --hash=sha256:6dddbad1d7ee0f5140aba5ec138ddc9612c5109399903828b4874c9937f009c2 \ - --hash=sha256:ce107f5d9bd02b4636001a77a4e74aab5e1e2b146868ebbad565237145af444c +uvicorn[standard]==0.27.1 \ + --hash=sha256:3d9a267296243532db80c83a959a3400502165ade2c1338dea4e67915fd4745a \ + --hash=sha256:5c89da2f3895767472a35556e539fd59f7edbe9b1e9c0e1c99eebeadc61838e4 # via -r requirements/main.in uvloop==0.19.0 \ --hash=sha256:0246f4fd1bf2bf702e06b0d45ee91677ee5c31242f39aab4ea6fe0c51aedd0fd \ From af787fc9323cb344f4726b97723a3a691a363ea6 Mon Sep 17 00:00:00 2001 From: Jonathan Sick Date: Tue, 5 Mar 2024 10:35:33 -0500 Subject: [PATCH 2/5] Switch to ruff - Drop flake8, black, and isort to use ruff - ruff configuration is from the fastapi_safir_app template --- .flake8 | 7 --- .pre-commit-config.yaml | 21 ++----- pyproject.toml | 133 +++++++++++++++++++++++++++++++++------- requirements/dev.in | 1 + requirements/dev.txt | 19 ++++++ 5 files changed, 136 insertions(+), 45 deletions(-) delete mode 100644 .flake8 diff --git a/.flake8 b/.flake8 deleted file mode 100644 index 01ee522..0000000 --- a/.flake8 +++ /dev/null @@ -1,7 +0,0 @@ -[flake8] -max-line-length = 79 -# E203: whitespace before :, flake8 disagrees with PEP-8 -# W503: line break after binary operator, flake8 disagrees with PEP-8 -ignore = E203, W503 -exclude = - docs/conf.py diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 4469818..f1861ab 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -4,20 +4,11 @@ repos: hooks: - id: check-yaml - id: check-toml + - id: trailing-whitespace - - repo: https://github.com/pycqa/isort - rev: 5.13.2 + - repo: https://github.com/astral-sh/ruff-pre-commit + rev: v0.2.1 hooks: - - id: isort - additional_dependencies: - - toml - - - repo: https://github.com/psf/black - rev: 24.2.0 - hooks: - - id: black - - - repo: https://github.com/pycqa/flake8 - rev: 7.0.0 - hooks: - - id: flake8 + - id: ruff + args: [--fix, --exit-non-zero-on-fix] + - id: ruff-format diff --git a/pyproject.toml b/pyproject.toml index ce4a6ff..978a7be 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -57,29 +57,6 @@ exclude_lines = [ "if TYPE_CHECKING:", ] -[tool.black] -line-length = 79 -target-version = ['py311'] -exclude = ''' -/( - \.eggs - | \.git - | \.mypy_cache - | \.tox - | \.venv - | _build - | build - | dist -)/ -''' -# Use single-quoted strings so TOML treats the string like a Python r-string -# Multi-line strings are implicitly treated by black as regular expressions - -[tool.isort] -profile = "black" -line_length = 79 -known_first_party = ["noteburst", "tests"] -skip = ["docs/conf.py"] [tool.pytest.ini_options] asyncio_mode = "strict" @@ -110,3 +87,113 @@ format = "md" md_header_level = "2" new_fragment_template = "file:changelog.d/_template.md.jinja" skip_fragments = "_template.md.jinja" + +# The rule used with Ruff configuration is to disable every lint that has +# legitimate exceptions that are not dodgy code, rather than cluttering code +# with noqa markers. This is therefore a reiatively relaxed configuration that +# errs on the side of disabling legitimate lints. +# +# Reference for settings: https://beta.ruff.rs/docs/settings/ +# Reference for rules: https://beta.ruff.rs/docs/rules/ +[tool.ruff] +exclude = [ + "docs/**", +] +line-length = 79 +target-version = "py312" + +[tool.ruff.lint] +ignore = [ + "ANN101", # self should not have a type annotation + "ANN102", # cls should not have a type annotation + "ANN401", # sometimes Any is the right type + "ARG001", # unused function arguments are often legitimate + "ARG002", # unused method arguments are often legitimate + "ARG005", # unused lambda arguments are often legitimate + "BLE001", # we want to catch and report Exception in background tasks + "C414", # nested sorted is how you sort by multiple keys with reverse + "D102", # sometimes we use docstring inheritence + "D104", # don't see the point of documenting every package + "D105", # our style doesn't require docstrings for magic methods + "D106", # Pydantic uses a nested Config class that doesn't warrant docs + "D205", # our documentation style allows a folded first line + "EM101", # justification (duplicate string in traceback) is silly + "EM102", # justification (duplicate string in traceback) is silly + "FBT003", # positional booleans are normal for Pydantic field defaults + "FIX002", # point of a TODO comment is that we're not ready to fix it + "G004", # forbidding logging f-strings is appealing, but not our style + "RET505", # disagree that omitting else always makes code more readable + "PLR0911", # often many returns is clearer and simpler style + "PLR0913", # factory pattern uses constructors with many arguments + "PLR2004", # too aggressive about magic values + "PLW0603", # yes global is discouraged but if needed, it's needed + "S105", # good idea but too many false positives on non-passwords + "S106", # good idea but too many false positives on non-passwords + "S107", # good idea but too many false positives on non-passwords + "S603", # not going to manually mark every subprocess call as reviewed + "S607", # using PATH is not a security vulnerability + "SIM102", # sometimes the formatting of nested if statements is clearer + "SIM117", # sometimes nested with contexts are clearer + "TCH001", # we decided to not maintain separate TYPE_CHECKING blocks + "TCH002", # we decided to not maintain separate TYPE_CHECKING blocks + "TCH003", # we decided to not maintain separate TYPE_CHECKING blocks + "TID252", # if we're going to use relative imports, use them always + "TRY003", # good general advice but lint is way too aggressive + "TRY301", # sometimes raising exceptions inside try is the best flow + + # The following settings should be disabled when using ruff format + # per https://docs.astral.sh/ruff/formatter/#conflicting-lint-rules + "W191", + "E111", + "E114", + "E117", + "D206", + "D300", + "Q000", + "Q001", + "Q002", + "Q003", + "COM812", + "COM819", + "ISC001", + "ISC002", +] +select = ["ALL"] + +[tool.ruff.lint.per-file-ignores] +"src/example/handlers/**" = [ + "D103", # FastAPI handlers should not have docstrings +] +"tests/**" = [ + "C901", # tests are allowed to be complex, sometimes that's convenient + "D101", # tests don't need docstrings + "D103", # tests don't need docstrings + "PLR0915", # tests are allowed to be long, sometimes that's convenient + "PT012", # way too aggressive about limiting pytest.raises blocks + "S101", # tests should use assert + "S106", # tests are allowed to hard-code dummy passwords + "SLF001", # tests are allowed to access private members +] + +[tool.ruff.lint.isort] +known-first-party = ["noteburst", "tests"] +split-on-trailing-comma = false + +# These are too useful as attributes or methods to allow the conflict with the +# built-in to rule out their use. +[tool.ruff.lint.flake8-builtins] +builtins-ignorelist = [ + "all", + "any", + "help", + "id", + "list", + "type", +] + +[tool.ruff.lint.flake8-pytest-style] +fixture-parentheses = false +mark-parentheses = false + +[tool.ruff.lint.pydocstyle] +convention = "numpy" diff --git a/requirements/dev.in b/requirements/dev.in index 09656e8..0612090 100644 --- a/requirements/dev.in +++ b/requirements/dev.in @@ -18,6 +18,7 @@ pytest-cov uvicorn respx types-PyYAML +ruff # Documentation documenteer[guide]>=1.0.0 diff --git a/requirements/dev.txt b/requirements/dev.txt index a373492..2df5a91 100644 --- a/requirements/dev.txt +++ b/requirements/dev.txt @@ -756,6 +756,25 @@ rpds-py==0.18.0 \ # via # jsonschema # referencing +ruff==0.3.0 \ + --hash=sha256:0886184ba2618d815067cf43e005388967b67ab9c80df52b32ec1152ab49f53a \ + --hash=sha256:128265876c1d703e5f5e5a4543bd8be47c73a9ba223fd3989d4aa87dd06f312f \ + --hash=sha256:19eacceb4c9406f6c41af806418a26fdb23120dfe53583df76d1401c92b7c14b \ + --hash=sha256:23dbb808e2f1d68eeadd5f655485e235c102ac6f12ad31505804edced2a5ae77 \ + --hash=sha256:2f7dbba46e2827dfcb0f0cc55fba8e96ba7c8700e0a866eb8cef7d1d66c25dcb \ + --hash=sha256:3ef655c51f41d5fa879f98e40c90072b567c666a7114fa2d9fe004dffba00932 \ + --hash=sha256:5da894a29ec018a8293d3d17c797e73b374773943e8369cfc50495573d396933 \ + --hash=sha256:755c22536d7f1889be25f2baf6fedd019d0c51d079e8417d4441159f3bcd30c2 \ + --hash=sha256:7deb528029bacf845bdbb3dbb2927d8ef9b4356a5e731b10eef171e3f0a85944 \ + --hash=sha256:9343690f95710f8cf251bee1013bf43030072b9f8d012fbed6ad702ef70d360a \ + --hash=sha256:a1f3ed501a42f60f4dedb7805fa8d4534e78b4e196f536bac926f805f0743d49 \ + --hash=sha256:b08b356d06a792e49a12074b62222f9d4ea2a11dca9da9f68163b28c71bf1dd4 \ + --hash=sha256:cc30a9053ff2f1ffb505a585797c23434d5f6c838bacfe206c0e6cf38c921a1e \ + --hash=sha256:d0d3d7ef3d4f06433d592e5f7d813314a34601e6c5be8481cccb7fa760aa243e \ + --hash=sha256:dd73fe7f4c28d317855da6a7bc4aa29a1500320818dd8f27df95f70a01b8171f \ + --hash=sha256:e1e0d4381ca88fb2b73ea0766008e703f33f460295de658f5467f6f229658c19 \ + --hash=sha256:e3a4a6d46aef0a84b74fcd201a4401ea9a6cd85614f6a9435f2d33dd8cefbf83 + # via -r requirements/dev.in scriv==1.5.1 \ --hash=sha256:30ae9ff8d144f8e0cf394c4e1d379542f1b3823767642955b54ec40dc00b32b6 \ --hash=sha256:a3adc657733b4124fcb54527a5f3daab0d3c300de82d0fd2b9b297b243151b78 From a77f96041a7e7939bf157e0210b56b080844482f Mon Sep 17 00:00:00 2001 From: Jonathan Sick Date: Tue, 5 Mar 2024 12:23:17 -0500 Subject: [PATCH 3/5] Format codebase for ruff This applies changes made both automatically by ruff, and based on ruff linting. --- changelog.d/20240305_122219_jsick_DM_43173.md | 17 +++++ docs/_rst_epilog.rst | 2 +- docs/user-guide/environment-variables.rst | 2 +- pyproject.toml | 4 +- src/noteburst/config.py | 10 +-- src/noteburst/exceptions.py | 2 +- src/noteburst/handlers/external.py | 4 +- src/noteburst/handlers/v1/handlers.py | 24 ++++--- src/noteburst/handlers/v1/models.py | 21 +++--- src/noteburst/jupyterclient/jupyterlab.py | 70 +++++++++---------- src/noteburst/jupyterclient/labcontroller.py | 20 +++--- src/noteburst/jupyterclient/user.py | 7 +- src/noteburst/main.py | 2 +- src/noteburst/worker/functions/keepalive.py | 4 +- src/noteburst/worker/functions/nbexec.py | 14 ++-- src/noteburst/worker/functions/ping.py | 1 + src/noteburst/worker/functions/runpython.py | 2 + src/noteburst/worker/identity.py | 46 ++++++------ src/noteburst/worker/main.py | 17 ++--- tests/conftest.py | 5 +- tests/handlers/external_test.py | 2 +- tests/handlers/internal_test.py | 2 +- tests/handlers/v1_test.py | 4 +- tests/jupyterclient/jupyterclient_test.py | 4 +- tests/support/arq.py | 3 +- tests/support/gafaelfawr.py | 15 ++-- tests/support/jupyter.py | 31 ++++---- tests/worker/__init__.py | 0 28 files changed, 177 insertions(+), 158 deletions(-) create mode 100644 changelog.d/20240305_122219_jsick_DM_43173.md create mode 100644 tests/worker/__init__.py diff --git a/changelog.d/20240305_122219_jsick_DM_43173.md b/changelog.d/20240305_122219_jsick_DM_43173.md new file mode 100644 index 0000000..e9b2c6c --- /dev/null +++ b/changelog.d/20240305_122219_jsick_DM_43173.md @@ -0,0 +1,17 @@ + + +### Backwards-incompatible changes + +- + +### New features + +- + +### Bug fixes + +- + +### Other changes + +- The code base now uses Ruff for linting and formatting, replacing black, isort, and flake8. This change is part of the ongoing effort to standardize SQuaRE code bases and improve the developer experience. diff --git a/docs/_rst_epilog.rst b/docs/_rst_epilog.rst index e0de42e..2c76083 100644 --- a/docs/_rst_epilog.rst +++ b/docs/_rst_epilog.rst @@ -3,4 +3,4 @@ .. _pytest: https://docs.pytest.org/en/latest/ .. _tox: https://tox.readthedocs.io/en/latest/ .. _httpie: https://httpie.io/cli -.. _`Rubin Science Platform environment`: +.. _`Rubin Science Platform environment`: diff --git a/docs/user-guide/environment-variables.rst b/docs/user-guide/environment-variables.rst index 7458d20..0d4b542 100644 --- a/docs/user-guide/environment-variables.rst +++ b/docs/user-guide/environment-variables.rst @@ -21,7 +21,7 @@ See the `Phalanx documentation for Noteburst RedisSettings: """Create a Redis settings instance for arq.""" - # url_parts = urlparse(self.redis_url) - redis_settings = RedisSettings( + return RedisSettings( host=self.redis_url.host or "localhost", port=self.redis_url.port or 6379, database=( @@ -108,10 +107,11 @@ def arq_redis_settings(self) -> RedisSettings: else 0 ), ) - return redis_settings class WorkerConfig(Config): + """Configuration superset for arq worker processes.""" + identities_path: Path = Field( ..., alias="NOTEBURST_WORKER_IDENTITIES_PATH" ) @@ -156,7 +156,7 @@ class WorkerConfig(Config): description="Method for selecting a Jupyter image to run.", ) - image_reference: Optional[str] = Field( + image_reference: str | None = Field( None, alias="NOTEBURST_WORKER_IMAGE_REFERENCE", description=( diff --git a/src/noteburst/exceptions.py b/src/noteburst/exceptions.py index c552a00..d7d6716 100644 --- a/src/noteburst/exceptions.py +++ b/src/noteburst/exceptions.py @@ -20,7 +20,7 @@ class TaskError(Exception): @classmethod def from_exception(cls, exc: Exception) -> Self: - return cls(f"{cls.task_name} task error\n\n{str(exc)}") + return cls(f"{cls.task_name} task error\n\n{exc!s}") class NbexecTaskError(TaskError): diff --git a/src/noteburst/handlers/external.py b/src/noteburst/handlers/external.py index aadf577..a5115da 100644 --- a/src/noteburst/handlers/external.py +++ b/src/noteburst/handlers/external.py @@ -1,5 +1,7 @@ """Handlers for the app's external root, ``/noteburst/``.""" +from typing import Annotated + from fastapi import APIRouter, Depends from pydantic import BaseModel, Field from safir.dependencies.gafaelfawr import auth_logger_dependency @@ -29,7 +31,7 @@ class Index(BaseModel): summary="Application metadata", ) async def get_index( - logger: BoundLogger = Depends(auth_logger_dependency), + logger: Annotated[BoundLogger, Depends(auth_logger_dependency)], ) -> Index: """GET ``/noteburst/`` (the app's external root). diff --git a/src/noteburst/handlers/v1/handlers.py b/src/noteburst/handlers/v1/handlers.py index bbacee7..3f97f76 100644 --- a/src/noteburst/handlers/v1/handlers.py +++ b/src/noteburst/handlers/v1/handlers.py @@ -1,5 +1,7 @@ """V1 REST API handlers.""" +from typing import Annotated + import structlog from arq.jobs import JobStatus from fastapi import APIRouter, Depends, Query, Request, Response @@ -25,8 +27,8 @@ async def post_nbexec( *, request: Request, response: Response, - logger: structlog.BoundLogger = Depends(auth_logger_dependency), - arq_queue: ArqQueue = Depends(arq_dependency), + logger: Annotated[structlog.BoundLogger, Depends(auth_logger_dependency)], + arq_queue: Annotated[ArqQueue, Depends(arq_dependency)], ) -> NotebookResponse: """Submits a notebook for execution. The notebook is executed asynchronously via a pool of JupyterLab (Nublado) instances. @@ -94,8 +96,8 @@ async def get_nbexec_job( "includes the executed notebook and metadata about the run." ), ), - logger: structlog.BoundLogger = Depends(auth_logger_dependency), - arq_queue: ArqQueue = Depends(arq_dependency), + logger: Annotated[structlog.BoundLogger, Depends(auth_logger_dependency)], + arq_queue: Annotated[ArqQueue, Depends(arq_dependency)], ) -> NotebookResponse: """Provides information about a notebook execution job, and the result (if available). @@ -121,9 +123,10 @@ async def get_nbexec_job( """ try: job_metadata = await arq_queue.get_job_metadata(job_id) - except Exception as e: - logger.error( - "Error getting nbexec job metadata", job_id=job_id, exc_info=e + except Exception: + logger.exception( + "Error getting nbexec job metadata", + job_id=job_id, ) raise logger.debug( @@ -136,9 +139,10 @@ async def get_nbexec_job( if result and job_metadata.status == JobStatus.complete: try: job_result = await arq_queue.get_job_result(job_id) - except Exception as e: - logger.error( - "Error getting nbexec job result", job_id=job_id, exc_info=e + except Exception: + logger.exception( + "Error getting nbexec job result", + job_id=job_id, ) raise logger.debug( diff --git a/src/noteburst/handlers/v1/models.py b/src/noteburst/handlers/v1/models.py index 020aad0..83f664b 100644 --- a/src/noteburst/handlers/v1/models.py +++ b/src/noteburst/handlers/v1/models.py @@ -4,7 +4,7 @@ import json from datetime import datetime -from typing import Any, Optional, Union +from typing import Any from arq.jobs import JobStatus from fastapi import Request @@ -66,38 +66,38 @@ class NotebookResponse(BaseModel): self_url: AnyHttpUrl = Field(title="The URL of this resource") - source: Optional[str] = Field( + source: str | None = Field( None, title="The content of the source ipynb file (JSON-encoded string)", description="This field is null unless the source is requested.", ) - start_time: Optional[datetime] = Field( + start_time: datetime | None = Field( None, title="Time when the notebook execution started (UTC)", description="This field is present if the result is available.", ) - finish_time: Optional[datetime] = Field( + finish_time: datetime | None = Field( None, title="Time when the notebook execution completed (UTC)", description="This field is present only if the result is available.", ) - success: Optional[bool] = Field( + success: bool | None = Field( None, title="Whether the execution was successful or not", description="This field is present if the result is available.", ) - ipynb: Optional[str] = Field( + ipynb: str | None = Field( None, title="The contents of the executed Jupyter notebook", description="The ipynb is a JSON-encoded string. This field is " "present if the result is available.", ) - ipynb_error: Optional[NotebookError] = Field( + ipynb_error: NotebookError | None = Field( None, title="The error that occurred during notebook execution", description="This field is null if an exeception did not occur.", @@ -110,12 +110,9 @@ async def from_job_metadata( job: JobMetadata, request: Request, include_source: bool = False, - job_result: Optional[JobResult] = None, + job_result: JobResult | None = None, ) -> NotebookResponse: if job_result is not None and job_result.success: - print("job_result.result") - print(type(job_result.result)) - print(job_result.result) nbexec_result = NotebookExecutionResult.model_validate_json( job_result.result ) @@ -146,7 +143,7 @@ async def from_job_metadata( class PostNotebookRequest(BaseModel): """The ``POST /notebooks/`` request body.""" - ipynb: Union[str, dict[str, Any]] = Field( + ipynb: str | dict[str, Any] = Field( ..., title="The contents of a Jupyter notebook", description="If a string, the content is parsed as JSON. " diff --git a/src/noteburst/jupyterclient/jupyterlab.py b/src/noteburst/jupyterclient/jupyterlab.py index 7d0a5f0..37a782a 100644 --- a/src/noteburst/jupyterclient/jupyterlab.py +++ b/src/noteburst/jupyterclient/jupyterlab.py @@ -6,10 +6,11 @@ import contextlib import datetime import json -import random import string +from collections.abc import AsyncGenerator, AsyncIterator from dataclasses import dataclass -from typing import Any, AsyncGenerator, AsyncIterator, Optional +from random import SystemRandom +from typing import Any, Self from urllib.parse import urljoin, urlparse from uuid import uuid4 @@ -62,7 +63,7 @@ class JupyterSpawnProgress: def __init__(self, response: httpx.Response, logger: BoundLogger) -> None: self._response = response self._logger = logger - self._start = datetime.datetime.now(tz=datetime.timezone.utc) + self._start = datetime.datetime.now(tz=datetime.UTC) async def __aiter__(self) -> AsyncIterator[SpawnProgressMessage]: """Iterate over spawn progress events.""" @@ -83,19 +84,16 @@ async def __aiter__(self) -> AsyncIterator[SpawnProgressMessage]: ready=event_dict.get("ready", False), ) except Exception as e: - msg = f"Ignoring invalid progress event: {raw_event}: {str(e)}" + msg = f"Ignoring invalid progress event: {raw_event}: {e!s}" self._logger.warning( msg, raw_event=raw_event, exception=str(e) ) continue # Log and yield the event - now = datetime.datetime.now(tz=datetime.timezone.utc) + now = datetime.datetime.now(tz=datetime.UTC) elapsed = int((now - self._start).total_seconds()) - if event.ready: - status = "complete" - else: - status = "in progress" + status = "complete" if event.ready else "in progress" self._logger.info( "Spawning", status=status, @@ -239,7 +237,7 @@ class JupyterConfig: url_prefix: str = "/nb/" """URL path prefix for the JupyterHub service.""" - image_reference: Optional[str] = None + image_reference: str | None = None """Docker reference to the JupyterLab image to spawn. May be null if ``image_selector`` is is not @@ -288,9 +286,9 @@ def __init__( url: str, username: str, status: int, - reason: Optional[str], + reason: str | None, method: str, - body: Optional[str] = None, + body: str | None = None, ) -> None: self.url = url self.status = status @@ -298,15 +296,14 @@ def __init__( self.method = method self.body = body self.username = username - self.timestamp = datetime.datetime.now(tz=datetime.timezone.utc) + self.timestamp = datetime.datetime.now(tz=datetime.UTC) super().__init__(f"Status {status} from {method} {url}") def __str__(self) -> str: - result = ( + return ( f"{self.username}: status {self.status} ({self.reason}) from" f" {self.method} {self.url}" ) - return result class JupyterLabSessionError(Exception): @@ -332,9 +329,9 @@ def __init__( username: str, code: str, code_type: str = "code", - error: Optional[str] = None, - status: Optional[str] = None, - result: Optional[str] = None, + error: str | None = None, + status: str | None = None, + result: str | None = None, ) -> None: self.username = username self.code = code @@ -420,8 +417,8 @@ def __init__( str(noteburst_config.environment_url), self.config.url_prefix ) - self._http_client: Optional[httpx.AsyncClient] = None - self._lab_controller_client: Optional[LabControllerClient] = None + self._http_client: httpx.AsyncClient | None = None + self._lab_controller_client: LabControllerClient | None = None self._common_headers: dict[str, str] # set and reset in the context @property @@ -429,7 +426,8 @@ def http_client(self) -> httpx.AsyncClient: """The HTTPX client instance associated with the Jupyter session..""" if self._http_client is None: self._open_clients() - assert self._http_client is not None + if self._http_client is None: + raise RuntimeError("http_client is not set") return self._http_client @property @@ -439,10 +437,11 @@ def lab_controller(self) -> LabControllerClient: """ if self._lab_controller_client is None: self._open_clients() - assert self._lab_controller_client is not None + if self._lab_controller_client is None: + raise RuntimeError("LabControllerClient is not set set up") return self._lab_controller_client - async def __aenter__(self) -> JupyterClient: + async def __aenter__(self) -> Self: self._open_clients() return self @@ -455,9 +454,8 @@ def _open_clients(self) -> None: "re-opening?" ) - xsrf_token = "".join( - random.choices(string.ascii_uppercase + string.digits, k=16) - ) + alphabet = string.ascii_uppercase + string.digits + xsrf_token = "".join(SystemRandom().choices(alphabet, k=16)) headers = { "x-xsrftoken": xsrf_token, "Authorization": f"Bearer {self.user.token}", @@ -475,14 +473,13 @@ def _open_clients(self) -> None: # Create a LabController client # We also send the XSRF token to Lab Controller because of how we're # sharing the session, but that shouldn't matter. - assert noteburst_config.gafaelfawr_token self._lab_controller_client = LabControllerClient( http_client=self.http_client, token=noteburst_config.gafaelfawr_token.get_secret_value(), url_prefix=noteburst_config.nublado_controller_path_prefix, ) - async def __aexit__(self, *exc_info: Any) -> None: + async def __aexit__(self, *exc_info: object) -> None: await self.close() async def close(self) -> None: @@ -591,7 +588,11 @@ async def _get_spawn_image(self) -> JupyterImage: elif self.config.image_selector == JupyterImageSelector.weekly: image = await self.lab_controller.get_latest_weekly() elif self.config.image_selector == JupyterImageSelector.reference: - assert self.config.image_reference + if self.config.image_reference is None: + raise ValueError( + "No image reference provided using " + "JupyterImageSelector.reference." + ) image = await self.lab_controller.get_by_reference( self.config.image_reference ) @@ -624,7 +625,7 @@ async def stop_lab(self) -> None: if r.status_code not in [200, 202, 204]: raise JupyterError.from_response(self.user.username, r) - async def is_lab_stopped(self, final: bool = False) -> bool: + async def is_lab_stopped(self, *, final: bool = False) -> bool: """Determine if the lab is fully stopped. Parameters @@ -648,7 +649,7 @@ async def is_lab_stopped(self, final: bool = False) -> bool: @contextlib.asynccontextmanager async def open_lab_session( - self, notebook_name: Optional[str] = None, *, kernel_name: str = "LSST" + self, notebook_name: str | None = None, *, kernel_name: str = "LSST" ) -> AsyncGenerator[JupyterLabSession, None]: """Open a JupyterLab session. @@ -684,7 +685,7 @@ async def open_lab_session( header: mock_request.headers[header] for header in copied_headers } - session_id: Optional[str] = None # will be set if a session is opened + session_id: str | None = None # will be set if a session is opened self.logger.debug("Trying to create websocket connection") try: # An alternative to the async context it to use connect in an @@ -708,7 +709,7 @@ async def open_lab_session( except WebSocketException as e: raise JupyterLabSessionError.from_exception( username=self.user.username, exception=e - ) + ) from e finally: if session_id: session_id_url = self.url_for( @@ -762,5 +763,4 @@ async def get_jupyterlab_env(self) -> dict[str, Any]: r = await self.http_client.get(environment_url) if r.status_code != 200: raise JupyterError.from_response(self.user.username, r) - env_data = r.json() - return env_data + return r.json() diff --git a/src/noteburst/jupyterclient/labcontroller.py b/src/noteburst/jupyterclient/labcontroller.py index 4cd6bfb..c074c5c 100644 --- a/src/noteburst/jupyterclient/labcontroller.py +++ b/src/noteburst/jupyterclient/labcontroller.py @@ -2,7 +2,6 @@ from __future__ import annotations -from typing import Optional from urllib.parse import urljoin import httpx @@ -27,7 +26,7 @@ class JupyterImage(BaseModel): title="Human-readable version of image tag", ) - digest: Optional[str] = Field( + digest: str | None = Field( None, examples=[ "sha256:e693782192ecef4f7846ad2b21" @@ -40,7 +39,7 @@ class JupyterImage(BaseModel): title="Image tag", ) - size: Optional[int] = Field( + size: int | None = Field( None, examples=[8675309], title="Size in bytes of image. None if image size is unknown", @@ -53,31 +52,32 @@ class JupyterImage(BaseModel): def underscore_to_dash(x: str) -> str: + """Convert underscores to dashes in a string.""" return x.replace("_", "-") class LabControllerImages(BaseModel): """A model for the ``GET /nublado/spawner/v1/images`` response.""" - recommended: Optional[JupyterImage] = Field( + recommended: JupyterImage | None = Field( None, title="The recommended image" ) - latest_weekly: Optional[JupyterImage] = Field( + latest_weekly: JupyterImage | None = Field( None, title="The latest weekly release image" ) - latest_daily: Optional[JupyterImage] = Field( + latest_daily: JupyterImage | None = Field( None, title="The latest daily release image" ) - latest_release: Optional[JupyterImage] = Field( + latest_release: JupyterImage | None = Field( None, title="The latest release image" ) all: list[JupyterImage] = Field(default_factory=list, title="All images") - def get_by_reference(self, reference: str) -> Optional[JupyterImage]: + def get_by_reference(self, reference: str) -> JupyterImage | None: """Get the JupyterImage with a corresponding reference. Parameters @@ -204,5 +204,5 @@ async def _get_images(self) -> LabControllerImages: data = r.json() return LabControllerImages.model_validate(data) except Exception as e: - msg = f"Invalid response from JupyterLab Controller: {str(e)}" - raise LabControllerError(msg) + msg = f"Invalid response from JupyterLab Controller: {e!s}" + raise LabControllerError(msg) from e diff --git a/src/noteburst/jupyterclient/user.py b/src/noteburst/jupyterclient/user.py index eaa14f7..a275f36 100644 --- a/src/noteburst/jupyterclient/user.py +++ b/src/noteburst/jupyterclient/user.py @@ -4,7 +4,6 @@ import time from dataclasses import dataclass -from typing import Optional from urllib.parse import urljoin import httpx @@ -25,7 +24,7 @@ class User: username: str """The user's username.""" - uid: Optional[str] + uid: str | None """The user's UID. This can be set as `None` if the authentication services provides the UID. @@ -62,7 +61,7 @@ async def create( cls, *, username: str, - uid: Optional[str], + uid: str | None, scopes: list[str], http_client: httpx.AsyncClient, lifetime: int, @@ -88,7 +87,7 @@ async def create( "username": username, "name": "Noteburst", "token_type": "user", - "token_name": f"noteburst {str(float(time.time()))}", + "token_name": f"noteburst {float(time.time())!s}", "scopes": scopes, "expires": int(time.time() + lifetime), } diff --git a/src/noteburst/main.py b/src/noteburst/main.py index e211c02..d562c5e 100644 --- a/src/noteburst/main.py +++ b/src/noteburst/main.py @@ -8,10 +8,10 @@ """ import json +from collections.abc import AsyncIterator from contextlib import asynccontextmanager from importlib.metadata import version from pathlib import Path -from typing import AsyncIterator from fastapi import FastAPI from fastapi.openapi.utils import get_openapi diff --git a/src/noteburst/worker/functions/keepalive.py b/src/noteburst/worker/functions/keepalive.py index 1d12402..01bc560 100644 --- a/src/noteburst/worker/functions/keepalive.py +++ b/src/noteburst/worker/functions/keepalive.py @@ -31,9 +31,9 @@ async def keep_alive(ctx: dict[Any, Any]) -> str: ) as session: await session.run_python("print('alive')") except JupyterError as e: - logger.error("keep_alive error", jupyter_status=e.status) + logger.exception("keep_alive error", jupyter_status=e.status) if e.status >= 400 and e.status < 500: - logger.error( + logger.exception( "Authentication error to Jupyter. Forcing worker shutdown", jupyter_status=e.status, ) diff --git a/src/noteburst/worker/functions/nbexec.py b/src/noteburst/worker/functions/nbexec.py index a947097..b4a38fd 100644 --- a/src/noteburst/worker/functions/nbexec.py +++ b/src/noteburst/worker/functions/nbexec.py @@ -58,19 +58,17 @@ async def nbexec( ) logger.info("nbexec finished", error=execution_result.error) except JupyterError as e: - logger.error("nbexec error", jupyter_status=e.status) + logger.exception("nbexec error", jupyter_status=e.status) if e.status >= 400 and e.status < 500: - logger.error( + logger.exception( "Authentication error to Jupyter. Forcing worker shutdown", jupyter_status=e.status, ) sys.exit("400 class error from Jupyter") + elif enable_retry: + logger.warning("nbexec triggering retry") + raise Retry(defer=ctx["job_try"] * 5) from None else: - # trigger re-try with increasing back-off - if enable_retry: - logger.warning("nbexec triggering retry") - raise Retry(defer=ctx["job_try"] * 5) - else: - raise NbexecTaskError.from_exception(e) + raise NbexecTaskError.from_exception(e) from e return execution_result.model_dump_json() diff --git a/src/noteburst/worker/functions/ping.py b/src/noteburst/worker/functions/ping.py index dab176e..b4e8868 100644 --- a/src/noteburst/worker/functions/ping.py +++ b/src/noteburst/worker/functions/ping.py @@ -6,6 +6,7 @@ async def ping(ctx: dict[Any, Any]) -> str: + """Log a ping message and return a string.""" logger = ctx["logger"].bind(task="ping") logger.info("Running ping") diff --git a/src/noteburst/worker/functions/runpython.py b/src/noteburst/worker/functions/runpython.py index ee05707..6bb6b51 100644 --- a/src/noteburst/worker/functions/runpython.py +++ b/src/noteburst/worker/functions/runpython.py @@ -1,3 +1,5 @@ +"""An Arq worker function to execute Python code in a JupyterLab pod.""" + from __future__ import annotations from typing import Any diff --git a/src/noteburst/worker/identity.py b/src/noteburst/worker/identity.py index 77d2731..770591b 100644 --- a/src/noteburst/worker/identity.py +++ b/src/noteburst/worker/identity.py @@ -8,7 +8,6 @@ from dataclasses import dataclass from pathlib import Path -from typing import Optional import structlog import yaml @@ -26,7 +25,7 @@ class IdentityModel(BaseModel): username: str """The username of the user account.""" - uid: Optional[str] = None + uid: str | None = None """The UID of the user account. This can be `None` if the authentication system assigns the UID. @@ -34,6 +33,8 @@ class IdentityModel(BaseModel): class IdentityConfigModel(RootModel): + """Model for the IdentityConfigModel-based configuration file.""" + root: list[IdentityModel] @classmethod @@ -49,7 +50,7 @@ class IdentityClaim: username: str """The username of the user account.""" - uid: Optional[str] + uid: str | None """The UID of the user account.""" lock: Lock @@ -92,7 +93,7 @@ def __init__( ) -> None: self.lock_manager = lock_manager self.identities = identities - self._current_identity: Optional[IdentityClaim] = None + self._current_identity: IdentityClaim | None = None self._logger = structlog.get_logger(__name__) @classmethod @@ -111,12 +112,9 @@ def from_config(cls, config: WorkerConfig) -> IdentityManager: """ lock_manager = Aioredlock(config.aioredlock_redis_config) - identities = [ - identity - for identity in IdentityConfigModel.from_yaml( - config.identities_path - ).root - ] + identities = list( + IdentityConfigModel.from_yaml(config.identities_path).root + ) return cls(lock_manager=lock_manager, identities=identities) @@ -133,7 +131,7 @@ async def _release_identity(self) -> None: self._logger.info("Released worker user identity") async def get_identity( - self, _identities: Optional[list[IdentityModel]] = None + self, _identities: list[IdentityModel] | None = None ) -> IdentityClaim: """Get a unique identity (either claiming a new identity or providing the already-claimed identity). @@ -145,10 +143,7 @@ async def get_identity( IdentityClaim Information about the Science Platform identity. """ - if _identities: - identities = _identities - else: - identities = self.identities + identities = _identities if _identities else self.identities if self._current_identity: if self._current_identity.valid: @@ -192,13 +187,20 @@ async def get_next_identity( await self._release_identity() for i, identity in enumerate(self.identities): - if identity.username == prev_identity.username: - break + # Find the same identity as before to then get the next one + if identity.username != prev_identity.username: + continue + + if i + 1 >= len(self.identities): + raise IdentityClaimError( + "Could not claim an Science Platform identity (none " + "available)." + ) - if i + 1 >= len(self.identities): - raise IdentityClaimError( - "Could not claim an Science Platform identity (none " - "available)." + return await self.get_identity( + _identities=self.identities[i + 1 :] ) - return await self.get_identity(_identities=self.identities[i + 1 :]) + raise IdentityClaimError( + "Could not claim an Science Platform identity (none available)." + ) diff --git a/src/noteburst/worker/main.py b/src/noteburst/worker/main.py index d1b130f..163da59 100644 --- a/src/noteburst/worker/main.py +++ b/src/noteburst/worker/main.py @@ -2,7 +2,7 @@ from __future__ import annotations -from typing import Any +from typing import Any, ClassVar import httpx import structlog @@ -24,8 +24,7 @@ async def startup(ctx: dict[Any, Any]) -> None: - """Runs during working start-up to set up the JupyterLab client and - populate the worker context. + """Set up worker context on startup. Notes ----- @@ -74,7 +73,7 @@ async def startup(ctx: dict[Any, Any]) -> None: try: image_info = await jupyter_client.spawn_lab() logger = logger.bind(image_ref=image_info.reference) - async for progress in jupyter_client.spawn_progress(): + async for _ in jupyter_client.spawn_progress(): continue await jupyter_client.log_into_lab() break @@ -90,10 +89,8 @@ async def startup(ctx: dict[Any, Any]) -> None: async def shutdown(ctx: dict[Any, Any]) -> None: - """Runs during worker shut-down to release the JupyterLab resources - and identity claim. - """ - if "logger" in ctx.keys(): + """Clean up the worker context on shutdown.""" + if "logger" in ctx: logger = ctx["logger"] else: logger = structlog.get_logger(__name__) @@ -144,7 +141,7 @@ async def shutdown(ctx: dict[Any, Any]) -> None: # For info on ignoring the type checking here, see # https://github.com/samuelcolvin/arq/issues/249 -cron_jobs: list[cron] = [] # type: ignore +cron_jobs: list[cron] = [] # type: ignore [valid-type] if config.worker_keepalive == WorkerKeepAliveSetting.fast: f = cron(keep_alive, second={0, 30}, unique=False) cron_jobs.append(f) @@ -163,7 +160,7 @@ class WorkerSettings: See `arq.worker.Worker` for details on these attributes. """ - functions = [ping, nbexec, run_python] + functions: ClassVar = [ping, nbexec, run_python] cron_jobs = cron_jobs diff --git a/tests/conftest.py b/tests/conftest.py index 7e4dfa0..746e4ff 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -3,7 +3,8 @@ from __future__ import annotations import contextlib -from typing import Any, AsyncGenerator, AsyncIterator +from collections.abc import AsyncGenerator, AsyncIterator +from typing import Any import pytest import pytest_asyncio @@ -71,7 +72,7 @@ async def mock_websocket_connect( @pytest.fixture def worker_context() -> dict[Any, Any]: - """A mock ctx (context) fixture for arq workers.""" + """Mock the ctx (context) for arq workers.""" ctx: dict[Any, Any] = {} # Prep identity_manager diff --git a/tests/handlers/external_test.py b/tests/handlers/external_test.py index 2d9062f..26e475d 100644 --- a/tests/handlers/external_test.py +++ b/tests/handlers/external_test.py @@ -10,7 +10,7 @@ @pytest.mark.asyncio async def test_get_index(client: AsyncClient) -> None: - """Test ``GET /noteburst/``""" + """Test ``GET /noteburst/``.""" response = await client.get("/noteburst/") assert response.status_code == 200 data = response.json() diff --git a/tests/handlers/internal_test.py b/tests/handlers/internal_test.py index 7ef89c9..1eabfb2 100644 --- a/tests/handlers/internal_test.py +++ b/tests/handlers/internal_test.py @@ -10,7 +10,7 @@ @pytest.mark.asyncio async def test_get_index(client: AsyncClient) -> None: - """Test ``GET /``""" + """Test ``GET /``.""" response = await client.get("/") assert response.status_code == 200 data = response.json() diff --git a/tests/handlers/v1_test.py b/tests/handlers/v1_test.py index 4b51b1f..3b21bb3 100644 --- a/tests/handlers/v1_test.py +++ b/tests/handlers/v1_test.py @@ -50,8 +50,8 @@ async def test_post_nbexec( data2 = response.json() assert data == data2 - assert "source" not in data2.keys() - assert "ipynb" not in data2.keys() + assert "source" not in data2 + assert "ipynb" not in data2 # Request the job with the source ipynb included response = await client.get(job_url, params={"source": "true"}) diff --git a/tests/jupyterclient/jupyterclient_test.py b/tests/jupyterclient/jupyterclient_test.py index 7469f55..34b0ca2 100644 --- a/tests/jupyterclient/jupyterclient_test.py +++ b/tests/jupyterclient/jupyterclient_test.py @@ -50,8 +50,6 @@ async def test_jupyterclient( await jupyter_client.log_into_lab() - # FIXME the test code for this isn't full set up yet - # async with jupyter_client.open_lab_session() as lab_session: - # print(lab_session.kernel_id) + # Note: the test code for running open_lab_session isn't available await jupyter_client.stop_lab() diff --git a/tests/support/arq.py b/tests/support/arq.py index 11aca1f..4d61635 100644 --- a/tests/support/arq.py +++ b/tests/support/arq.py @@ -3,7 +3,6 @@ from __future__ import annotations from dataclasses import dataclass -from typing import Optional from noteburst.worker.identity import IdentityClaimError @@ -35,7 +34,7 @@ class MockIdentityManager: """ def __init__(self) -> None: - self._current_identity: Optional[MockIdentityClaim] = None + self._current_identity: MockIdentityClaim | None = None async def get_identity(self) -> MockIdentityClaim: if self._current_identity: diff --git a/tests/support/gafaelfawr.py b/tests/support/gafaelfawr.py index 8a5fc80..9b5a0f1 100644 --- a/tests/support/gafaelfawr.py +++ b/tests/support/gafaelfawr.py @@ -6,7 +6,6 @@ import json import os import time -from typing import Optional from unittest.mock import ANY from urllib.parse import urljoin @@ -18,7 +17,7 @@ __all__ = ["make_gafaelfawr_token", "mock_gafaelfawr"] -def make_gafaelfawr_token(username: Optional[str] = None) -> str: +def make_gafaelfawr_token(username: str | None = None) -> str: """Create a random or user Gafaelfawr token. If a username is given, embed the username in the key portion of the token @@ -36,8 +35,8 @@ def make_gafaelfawr_token(username: Optional[str] = None) -> str: def mock_gafaelfawr( respx_mock: respx.Router, - username: Optional[str] = None, - uid: Optional[str] = None, + username: str | None = None, + uid: str | None = None, ) -> None: """Mock out the call to Gafaelfawr ``/auth/api/v1/tokens`` endpoint to create a user token. @@ -51,12 +50,8 @@ def mock_gafaelfawr( def handler(request: httpx.Request) -> httpx.Response: request_json = json.loads(request.content.decode("utf-8")) - # Skipping this assert that originally came from - # mobu/aiohttp/aioresponses because httpx.Request seems to obfuscate - # the authorization header after it's created; we'd need to figure - # out how to work around that. - # request_headers = request.headers - # assert request_headers["authorization"] == f"Bearer {admin_token}" + # Note httpx.Request seems to obfuscate the authorization header + # so we can't check it here. assert request_json == { "username": ANY, "token_type": "user", diff --git a/tests/support/jupyter.py b/tests/support/jupyter.py index 63b8443..ad1add7 100644 --- a/tests/support/jupyter.py +++ b/tests/support/jupyter.py @@ -6,12 +6,14 @@ import json import re from base64 import urlsafe_b64decode +from collections.abc import AsyncIterator from contextlib import redirect_stdout -from datetime import datetime, timedelta, timezone +from datetime import UTC, datetime, timedelta from enum import Enum from io import StringIO from traceback import format_exc -from typing import Any, AsyncIterator, Optional +from types import TracebackType +from typing import Any, Self from unittest.mock import ANY, AsyncMock, Mock from uuid import uuid4 @@ -80,7 +82,7 @@ def __init__(self) -> None: self.state: dict[str, JupyterState] = {} self.delete_immediate = True self.spawn_timeout = False - self._delete_at: dict[str, Optional[datetime]] = {} + self._delete_at: dict[str, datetime | None] = {} self._fail: dict[str, dict[JupyterAction, bool]] = {} def fail(self, user: str, action: JupyterAction) -> None: @@ -110,7 +112,7 @@ def user(self, request: httpx.Request) -> httpx.Response: body = {"name": user, "servers": {"": server}} elif state == JupyterState.LAB_RUNNING: delete_at = self._delete_at.get(user) - if delete_at and (datetime.now(tz=timezone.utc)) > delete_at: + if delete_at and (datetime.now(tz=UTC)) > delete_at: del self._delete_at[user] self.state[user] = JupyterState.LOGGED_IN if delete_at: @@ -203,7 +205,7 @@ def delete_lab(self, request: httpx.Request) -> httpx.Response: if self.delete_immediate: self.state[user] = JupyterState.LOGGED_IN else: - now = datetime.now(tz=timezone.utc) + now = datetime.now(tz=UTC) self._delete_at[user] = now + timedelta(seconds=5) return httpx.Response(202, request=request) @@ -320,18 +322,21 @@ def __init__(self, user: str, session_id: str) -> None: super().__init__(spec=WebSocketClientProtocol) self.user = user self.session_id = session_id - self._header: Optional[dict[str, Any]] = None - self._code: Optional[str] = None + self._header: dict[str, Any] | None = None + self._code: str | None = None self._state: dict[str, Any] = {} def __await__(self) -> MockJupyterWebSocket: return self - async def __aenter__(self) -> MockJupyterWebSocket: + async def __aenter__(self) -> Self: return await self async def __aexit__( - self, exc_type: Any, exc_value: Any, traceback: Any + self, + exc_type: type[BaseException] | None, + exc_value: BaseException | None, + traceback: TracebackType | None, ) -> None: pass @@ -391,7 +396,7 @@ async def __aiter__(self) -> AsyncIterator[str]: try: output = StringIO() with redirect_stdout(output): - exec(self._code, self._state) + exec(self._code, self._state) # noqa: S102 self._code = None yield json.dumps( { @@ -401,9 +406,9 @@ async def __aiter__(self) -> AsyncIterator[str]: } ) except Exception: - result = { + result: dict[str, str | dict[str, Any]] = { "msg_type": "error", - "parent_header": self._header, + "parent_header": self._header or {}, "content": {"traceback": format_exc()}, } self._header = None @@ -411,7 +416,7 @@ async def __aiter__(self) -> AsyncIterator[str]: else: result = { "msg_type": "execute_reply", - "parent_header": self._header, # type: ignore + "parent_header": self._header or {}, "content": {"status": "ok"}, } self._header = None diff --git a/tests/worker/__init__.py b/tests/worker/__init__.py new file mode 100644 index 0000000..e69de29 From e113c69ca346e8d1d54d679bfa8ec0a780b4e82a Mon Sep 17 00:00:00 2001 From: Jonathan Sick Date: Wed, 6 Mar 2024 12:55:10 -0500 Subject: [PATCH 4/5] Adopt Annotated for Config model fields --- src/noteburst/config.py | 273 ++++++++++++++++++++++++++-------------- 1 file changed, 176 insertions(+), 97 deletions(-) diff --git a/src/noteburst/config.py b/src/noteburst/config.py index 4a8f159..3345e50 100644 --- a/src/noteburst/config.py +++ b/src/noteburst/config.py @@ -4,7 +4,7 @@ from enum import Enum from pathlib import Path -from typing import Self +from typing import Annotated, Self from arq.connections import RedisSettings from pydantic import Field, HttpUrl, RedisDsn, SecretStr, model_validator @@ -49,51 +49,94 @@ class WorkerKeepAliveSetting(str, Enum): class Config(BaseSettings): """Noteburst app configuration.""" - name: str = Field("Noteburst", alias="SAFIR_NAME") + name: Annotated[str, Field(alias="SAFIR_NAME")] = "Noteburst" - profile: Profile = Field(Profile.production, alias="SAFIR_PROFILE") + profile: Annotated[ + Profile, Field(alias="SAFIR_PROFILE") + ] = Profile.production - log_level: LogLevel = Field(LogLevel.INFO, alias="SAFIR_LOG_LEVEL") + log_level: Annotated[ + LogLevel, Field(alias="SAFIR_LOG_LEVEL") + ] = LogLevel.INFO - logger_name: str = "noteburst" - """The root name of the Python logger, which is also the name of the - root Python module. - """ - - path_prefix: str = Field("/noteburst", alias="NOTEBURST_PATH_PREFIX") - """The URL path prefix where noteburst is hosted.""" - - environment_url: HttpUrl = Field(alias="NOTEBURST_ENVIRONMENT_URL") - """The base URL of the Rubin Science Platform environment. - - This is used for creating URLs to services, such as JupyterHub. - """ - - jupyterhub_path_prefix: str = Field( - "/nb/", - alias="NOTEBURST_JUPYTERHUB_PATH_PREFIX", - description="The path prefix for the JupyterHub service.", - ) - - nublado_controller_path_prefix: str = Field( - "/nublado", - alias="NOTEBURST_NUBLADO_CONTROLLER_PATH_PREFIX", - description="The path prefix for the Nublado controller service.", - ) - - gafaelfawr_token: SecretStr = Field(alias="NOTEBURST_GAFAELFAWR_TOKEN") - """This token is used to make an admin API call to Gafaelfawr to get a - token for the user. - """ + logger_name: Annotated[ + str, + Field( + description=( + "The root name of the Python logger, which is also the name " + "of the root Python module" + ) + ), + ] = "noteburst" + + path_prefix: Annotated[ + str, + Field( + "/noteburst", + alias="NOTEBURST_PATH_PREFIX", + description="The URL path prefix where noteburst is hosted.", + ), + ] = "/noteburst" + + environment_url: Annotated[ + HttpUrl, + Field( + alias="NOTEBURST_ENVIRONMENT_URL", + description=( + "The base URL of the Rubin Science Platform environment. This " + "is used for creating URLs to services, such as JupyterHub." + ), + ), + ] - redis_url: RedisDsn = Field( - alias="NOTEBURST_REDIS_URL", - # Preferred by mypy over a string default - default_factory=lambda: RedisDsn("redis://localhost:6379/1"), - ) - """URL for the redis instance, used by the worker queue.""" + jupyterhub_path_prefix: Annotated[ + str, + Field( + alias="NOTEBURST_JUPYTERHUB_PATH_PREFIX", + description="The path prefix for the JupyterHub service.", + ), + ] = "/nb/" - arq_mode: ArqMode = Field(ArqMode.production, alias="NOTEBURST_ARQ_MODE") + nublado_controller_path_prefix: Annotated[ + str, + Field( + alias="NOTEBURST_NUBLADO_CONTROLLER_PATH_PREFIX", + description="The path prefix for the Nublado controller service.", + ), + ] = "/nublado" + + gafaelfawr_token: Annotated[ + SecretStr, + Field( + alias="NOTEBURST_GAFAELFAWR_TOKEN", + description=( + "This token is used to make an admin API call to Gafaelfawr " + "to get a token for the user." + ), + ), + ] + + redis_url: Annotated[ + RedisDsn, + Field( + alias="NOTEBURST_REDIS_URL", + # Preferred by mypy over a string default + default_factory=lambda: RedisDsn("redis://localhost:6379/1"), + description=( + "URL for the redis instance, used by the worker queue.", + ), + ), + ] + + arq_mode: Annotated[ + ArqMode, + Field( + alias="NOTEBURST_ARQ_MODE", + description=( + "The Arq mode. Use 'test' to mock arq/redis for testing." + ), + ), + ] = ArqMode.production @property def arq_redis_settings(self) -> RedisSettings: @@ -112,62 +155,98 @@ def arq_redis_settings(self) -> RedisSettings: class WorkerConfig(Config): """Configuration superset for arq worker processes.""" - identities_path: Path = Field( - ..., alias="NOTEBURST_WORKER_IDENTITIES_PATH" - ) - """Path to the configuration file with the pool of Science Platform - identities available to workers. - """ - - queue_name: str = Field("arq:queue", alias="NOTEBURST_WORKER_QUEUE_NAME") - """Name of the arq queue that the worker processes from.""" - - identity_lock_redis_url: RedisDsn = Field( - alias="NOTEBURST_WORKER_LOCK_REDIS_URL", - # Preferred by mypy over a string default - default_factory=lambda: RedisDsn("redis://localhost:6379/1"), - ) - - job_timeout: int = Field( - 300, - alias="NOTEBURST_WORKER_JOB_TIMEOUT", - description=( - "The timeout, in seconds, for a job until it is timed out." - ), - ) - - worker_token_lifetime: int = Field( - 2419200, - alias="NOTEBURST_WORKER_TOKEN_LIFETIME", - description="Worker auth token lifetime in seconds.", - ) - - worker_token_scopes: str = Field( - "exec:notebook", - alias="NOTEBURST_WORKER_TOKEN_SCOPES", - description=( - "Worker (nublado2 pod) token scopes as a comma-separated string." - ), - ) - - image_selector: JupyterImageSelector = Field( - JupyterImageSelector.recommended, - alias="NOTEBURST_WORKER_IMAGE_SELECTOR", - description="Method for selecting a Jupyter image to run.", - ) - - image_reference: str | None = Field( - None, - alias="NOTEBURST_WORKER_IMAGE_REFERENCE", - description=( - "Docker image reference, if NOTEBURST_WORKER_IMAGE_SELECTOR is " - "``reference``." - ), - ) - - worker_keepalive: WorkerKeepAliveSetting = Field( - WorkerKeepAliveSetting.normal, alias="NOTEBURST_WORKER_KEEPALIVE" - ) + identities_path: Annotated[ + Path, + Field( + alias="NOTEBURST_WORKER_IDENTITIES_PATH", + description=( + "Path to the configuration file with the pool of Science " + "Platform identities available to workers." + ), + ), + ] + + queue_name: Annotated[ + str, + Field( + alias="NOTEBURST_WORKER_QUEUE_NAME", + description=( + "Name of the arq queue that the worker processes from." + ), + ), + ] = "arq:queue" + + identity_lock_redis_url: Annotated[ + RedisDsn, + Field( + alias="NOTEBURST_WORKER_LOCK_REDIS_URL", + # Preferred by mypy over a string default + default_factory=lambda: RedisDsn("redis://localhost:6379/1"), + description=( + "URL for the redis instance, used by the worker to lock " + "JupyterLab user identities to a worker instance." + ), + ), + ] + + job_timeout: Annotated[ + int, + Field( + alias="NOTEBURST_WORKER_JOB_TIMEOUT", + description=( + "The timeout, in seconds, for a job until it is timed out." + ), + ), + ] = 300 + + worker_token_lifetime: Annotated[ + int, + Field( + alias="NOTEBURST_WORKER_TOKEN_LIFETIME", + description="Worker auth token lifetime in seconds.", + ), + ] = 2419200 + + worker_token_scopes: Annotated[ + str, + Field( + alias="NOTEBURST_WORKER_TOKEN_SCOPES", + description=( + "Worker (nublado pod) token scopes as a comma-separated " + "string." + ), + ), + ] = "exec:notebook" + + image_selector: Annotated[ + JupyterImageSelector, + Field( + alias="NOTEBURST_WORKER_IMAGE_SELECTOR", + description="Method for selecting a Jupyter image to run.", + ), + ] = JupyterImageSelector.recommended + + image_reference: Annotated[ + str | None, + Field( + alias="NOTEBURST_WORKER_IMAGE_REFERENCE", + description=( + "Docker image reference, if NOTEBURST_WORKER_IMAGE_SELECTOR " + "is ``reference``." + ), + ), + ] = None + + worker_keepalive: Annotated[ + WorkerKeepAliveSetting, + Field( + alias="NOTEBURST_WORKER_KEEPALIVE", + description=( + "Keep-alive setting for the worker process. This setting " + "must be fast enough to defeat the Nublado pod culler." + ), + ), + ] = WorkerKeepAliveSetting.normal @property def aioredlock_redis_config(self) -> list[str]: From 0a44b519c98e58a0476fe434165ebbda2ef95bc2 Mon Sep 17 00:00:00 2001 From: Jonathan Sick Date: Wed, 6 Mar 2024 13:32:08 -0500 Subject: [PATCH 5/5] Convert all models to use Annotated --- src/noteburst/handlers/external.py | 2 +- src/noteburst/handlers/v1/models.py | 170 +++++++++++-------- src/noteburst/jupyterclient/jupyterlab.py | 39 +++-- src/noteburst/jupyterclient/labcontroller.py | 122 +++++++------ src/noteburst/worker/identity.py | 22 ++- 5 files changed, 201 insertions(+), 154 deletions(-) diff --git a/src/noteburst/handlers/external.py b/src/noteburst/handlers/external.py index a5115da..a8ed096 100644 --- a/src/noteburst/handlers/external.py +++ b/src/noteburst/handlers/external.py @@ -20,7 +20,7 @@ class Index(BaseModel): """Metadata about the application.""" - metadata: SafirMetadata = Field(..., title="Package metadata") + metadata: Annotated[SafirMetadata, Field(title="Package metadata")] @external_router.get( diff --git a/src/noteburst/handlers/v1/models.py b/src/noteburst/handlers/v1/models.py index 83f664b..fd3b211 100644 --- a/src/noteburst/handlers/v1/models.py +++ b/src/noteburst/handlers/v1/models.py @@ -4,7 +4,7 @@ import json from datetime import datetime -from typing import Any +from typing import Annotated, Any from arq.jobs import JobStatus from fastapi import Request @@ -31,8 +31,8 @@ class NotebookError(BaseModel): """Information about an exception that occurred during notebook exec.""" - name: str = Field(description="The name of the exception.") - message: str = Field(description="The exception's message.") + name: Annotated[str, Field(description="The name of the exception.")] + message: Annotated[str, Field(description="The exception's message.")] @classmethod def from_nbexec_error( @@ -52,56 +52,72 @@ class NotebookResponse(BaseModel): result and source notebooks. """ - job_id: str = Field(title="The job ID") - - kernel_name: str = kernel_name_field - - enqueue_time: datetime = Field( - title="Time when the job was added to the queue (UTC)" - ) - - status: JobStatus = Field( - title="The current status of the notebook execution job" - ) - - self_url: AnyHttpUrl = Field(title="The URL of this resource") - - source: str | None = Field( - None, - title="The content of the source ipynb file (JSON-encoded string)", - description="This field is null unless the source is requested.", - ) - - start_time: datetime | None = Field( - None, - title="Time when the notebook execution started (UTC)", - description="This field is present if the result is available.", - ) - - finish_time: datetime | None = Field( - None, - title="Time when the notebook execution completed (UTC)", - description="This field is present only if the result is available.", - ) - - success: bool | None = Field( - None, - title="Whether the execution was successful or not", - description="This field is present if the result is available.", - ) - - ipynb: str | None = Field( - None, - title="The contents of the executed Jupyter notebook", - description="The ipynb is a JSON-encoded string. This field is " - "present if the result is available.", - ) - - ipynb_error: NotebookError | None = Field( - None, - title="The error that occurred during notebook execution", - description="This field is null if an exeception did not occur.", - ) + job_id: Annotated[str, Field(title="The job ID")] + + kernel_name: Annotated[str, kernel_name_field] + + enqueue_time: Annotated[ + datetime, Field(title="Time when the job was added to the queue (UTC)") + ] + + status: Annotated[ + JobStatus, + Field(title="The current status of the notebook execution job"), + ] + + self_url: Annotated[AnyHttpUrl, Field(title="The URL of this resource")] + + source: Annotated[ + str | None, + Field( + title="The content of the source ipynb file (JSON-encoded string)", + description="This field is null unless the source is requested.", + ), + ] = None + + start_time: Annotated[ + datetime | None, + Field( + title="Time when the notebook execution started (UTC)", + description="This field is present if the result is available.", + ), + ] = None + + finish_time: Annotated[ + datetime | None, + Field( + title="Time when the notebook execution completed (UTC)", + description=( + "This field is present only if the result is available." + ), + ), + ] = None + + success: Annotated[ + bool | None, + Field( + title="Whether the execution was successful or not", + description="This field is present if the result is available.", + ), + ] = None + + ipynb: Annotated[ + str | None, + Field( + title="The contents of the executed Jupyter notebook", + description="The ipynb is a JSON-encoded string. This field is " + "present if the result is available.", + ), + ] = None + + ipynb_error: Annotated[ + NotebookError | None, + Field( + None, + title="The error that occurred during notebook execution", + description="This field is null if an exeception did not occur.", + ), + ] = None @classmethod async def from_job_metadata( @@ -112,6 +128,7 @@ async def from_job_metadata( include_source: bool = False, job_result: JobResult | None = None, ) -> NotebookResponse: + """Create a NotebookResponse from a job.""" if job_result is not None and job_result.success: nbexec_result = NotebookExecutionResult.model_validate_json( job_result.result @@ -143,30 +160,35 @@ async def from_job_metadata( class PostNotebookRequest(BaseModel): """The ``POST /notebooks/`` request body.""" - ipynb: str | dict[str, Any] = Field( - ..., - title="The contents of a Jupyter notebook", - description="If a string, the content is parsed as JSON. " - "Alternatively, the content can be submitted pre-parsed as " - "an object.", - ) - - kernel_name: str = kernel_name_field - - enable_retry: bool = Field( - True, - title="Enable retries on failures", - description=( - "If true (default), noteburst will retry notebook " - "execution if the notebook fails, with an increasing back-off " - "time between tries. This is useful for dealing with transient " - "issues. However, if you are using Noteburst for continuous " - "integration of notebooks, disabling retries provides faster " - "feedback." + ipynb: Annotated[ + str | dict[str, Any], + Field( + title="The contents of a Jupyter notebook", + description="If a string, the content is parsed as JSON. " + "Alternatively, the content can be submitted pre-parsed as " + "an object.", + ), + ] + + kernel_name: Annotated[str, kernel_name_field] + + enable_retry: Annotated[ + bool, + Field( + title="Enable retries on failures", + description=( + "If true (default), noteburst will retry notebook " + "execution if the notebook fails, with an increasing back-off " + "time between tries. This is useful for dealing with " + "transient issues. However, if you are using Noteburst for " + "continuous integration of notebooks, disabling retries " + "provides faster feedback." + ), ), - ) + ] = True def get_ipynb_as_str(self) -> str: + """Get the ipynb as a JSON-encoded string.""" if isinstance(self.ipynb, str): return self.ipynb else: diff --git a/src/noteburst/jupyterclient/jupyterlab.py b/src/noteburst/jupyterclient/jupyterlab.py index 37a782a..fa9ea83 100644 --- a/src/noteburst/jupyterclient/jupyterlab.py +++ b/src/noteburst/jupyterclient/jupyterlab.py @@ -10,7 +10,7 @@ from collections.abc import AsyncGenerator, AsyncIterator from dataclasses import dataclass from random import SystemRandom -from typing import Any, Self +from typing import Annotated, Any, Self from urllib.parse import urljoin, urlparse from uuid import uuid4 @@ -356,33 +356,38 @@ def __str__(self) -> str: class NotebookExecutionErrorModel(BaseModel): - """The error from the /user/:username/rubin/execute endpoint.""" + """The error from the ``/user/:username/rubin/execute`` endpoint.""" - traceback: str = Field(description="The exeception traceback.") + traceback: Annotated[str, Field(description="The exeception traceback.")] - ename: str = Field(description="The exception name.") + ename: Annotated[str, Field(description="The exception name.")] - evalue: str = Field(description="The exception value.") + evalue: Annotated[str, Field(description="The exception value.")] - err_msg: str = Field(description="The exception message.") + err_msg: Annotated[str, Field(description="The exception message.")] class NotebookExecutionResult(BaseModel): """The result of the /user/:username/rubin/execute endpoint.""" - notebook: str = Field( - description="The notebook that was executed, as a JSON string." - ) + notebook: Annotated[ + str, + Field(description="The notebook that was executed, as a JSON string."), + ] - resources: dict[str, Any] = Field( - description=( - "The resources used to execute the notebook, as a JSON string." - ) - ) + resources: Annotated[ + dict[str, Any], + Field( + description=( + "The resources used to execute the notebook, as a JSON string." + ) + ), + ] - error: NotebookExecutionErrorModel | None = Field( - None, description="The error that occurred during execution." - ) + error: Annotated[ + NotebookExecutionErrorModel | None, + Field(description="The error that occurred during execution."), + ] = None class JupyterClient: diff --git a/src/noteburst/jupyterclient/labcontroller.py b/src/noteburst/jupyterclient/labcontroller.py index c074c5c..faa5984 100644 --- a/src/noteburst/jupyterclient/labcontroller.py +++ b/src/noteburst/jupyterclient/labcontroller.py @@ -2,10 +2,11 @@ from __future__ import annotations +from typing import Annotated from urllib.parse import urljoin import httpx -from pydantic import BaseModel, Field +from pydantic import BaseModel, ConfigDict, Field from noteburst.config import config @@ -13,42 +14,51 @@ class JupyterImage(BaseModel): """A model for a JupyterLab image in a `LabControllerImages` resource.""" - reference: str = Field( - ..., - examples=["lighthouse.ceres/library/sketchbook:latest_daily"], - title="Full Docker registry path for lab image", - description="cf. https://docs.docker.com/registry/introduction/", - ) - - name: str = Field( - ..., - examples=["Latest Daily (Daily 2077_10_23)"], - title="Human-readable version of image tag", - ) - - digest: str | None = Field( - None, - examples=[ - "sha256:e693782192ecef4f7846ad2b21" - "b1574682e700747f94c5a256b5731331a2eec2" - ], - title="unique digest of image contents", - ) - - tag: str = Field( - title="Image tag", - ) - - size: int | None = Field( - None, - examples=[8675309], - title="Size in bytes of image. None if image size is unknown", - ) - prepulled: bool = Field( - False, - examples=[False], - title="Whether image is prepulled to all eligible nodes", - ) + reference: Annotated[ + str, + Field( + examples=["lighthouse.ceres/library/sketchbook:latest_daily"], + title="Full Docker registry path for lab image", + description="cf. https://docs.docker.com/registry/introduction/", + ), + ] + + name: Annotated[ + str, + Field( + examples=["Latest Daily (Daily 2077_10_23)"], + title="Human-readable version of image tag", + ), + ] + + digest: Annotated[ + str | None, + Field( + examples=[ + "sha256:e693782192ecef4f7846ad2b21" + "b1574682e700747f94c5a256b5731331a2eec2" + ], + title="unique digest of image contents", + ), + ] = None + + tag: Annotated[str, Field(title="Image tag")] + + size: Annotated[ + int | None, + Field( + examples=[8675309], + title="Size in bytes of image. None if image size is unknown", + ), + ] = None + + prepulled: Annotated[ + bool, + Field( + examples=[False], + title="Whether image is prepulled to all eligible nodes", + ), + ] = False def underscore_to_dash(x: str) -> str: @@ -59,23 +69,31 @@ def underscore_to_dash(x: str) -> str: class LabControllerImages(BaseModel): """A model for the ``GET /nublado/spawner/v1/images`` response.""" - recommended: JupyterImage | None = Field( - None, title="The recommended image" - ) + recommended: Annotated[ + JupyterImage | None, Field(title="The recommended image") + ] = None - latest_weekly: JupyterImage | None = Field( - None, title="The latest weekly release image" - ) + latest_weekly: Annotated[ + JupyterImage | None, Field(title="The latest weekly release image") + ] = None - latest_daily: JupyterImage | None = Field( - None, title="The latest daily release image" - ) + latest_daily: Annotated[ + JupyterImage | None, Field(title="The latest daily release image") + ] = None - latest_release: JupyterImage | None = Field( - None, title="The latest release image" - ) + latest_release: Annotated[ + JupyterImage | None, Field(title="The latest release image") + ] = None + + all: Annotated[ + list[JupyterImage], Field(default_factory=list, title="All images") + ] - all: list[JupyterImage] = Field(default_factory=list, title="All images") + model_config = ConfigDict( + populate_by_name=True, + alias_generator=underscore_to_dash, + ) + """Pydantic model configuration.""" def get_by_reference(self, reference: str) -> JupyterImage | None: """Get the JupyterImage with a corresponding reference. @@ -96,10 +114,6 @@ def get_by_reference(self, reference: str) -> JupyterImage | None: return None - class Config: - allow_population_by_field_name = True - alias_generator = underscore_to_dash - class LabControllerError(Exception): """Unable to get image information from the JupyterLab Controller.""" diff --git a/src/noteburst/worker/identity.py b/src/noteburst/worker/identity.py index 770591b..ea4227a 100644 --- a/src/noteburst/worker/identity.py +++ b/src/noteburst/worker/identity.py @@ -8,11 +8,12 @@ from dataclasses import dataclass from pathlib import Path +from typing import Annotated import structlog import yaml from aioredlock import Aioredlock, Lock, LockError -from pydantic import BaseModel, RootModel +from pydantic import BaseModel, Field, RootModel from noteburst.config import WorkerConfig @@ -22,14 +23,19 @@ class IdentityModel(BaseModel): configuration file. """ - username: str - """The username of the user account.""" - - uid: str | None = None - """The UID of the user account. + username: Annotated[ + str, Field(description="The username of the user account.") + ] - This can be `None` if the authentication system assigns the UID. - """ + uid: Annotated[ + str | None, + Field( + description=( + "The UID of the user account. This can be `None` if the " + "authentication system assigns the UID." + ) + ), + ] = None class IdentityConfigModel(RootModel):