diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index f929a2bd..9297cd26 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -1,6 +1,6 @@ repos: - repo: https://github.com/pre-commit/pre-commit-hooks - rev: v4.1.0 + rev: v4.3.0 hooks: - id: check-yaml - id: check-toml @@ -13,11 +13,11 @@ repos: - toml - repo: https://github.com/psf/black - rev: 22.3.0 + rev: 22.6.0 hooks: - id: black - - repo: https://gitlab.com/pycqa/flake8 - rev: 4.0.1 + - repo: https://github.com/pycqa/flake8 + rev: 5.0.3 hooks: - id: flake8 diff --git a/CHANGELOG.rst b/CHANGELOG.rst index 510054a9..131338ee 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -1,6 +1,16 @@ Change log ========== +0.6.0 (2022-08-18) +------------------ + +Times Square now exposes information about pages created during GitHub PR check runs: + +- ``GET /times-square/api/v1/github-pr/:org/:repo/:sha`` provides metadata for a repository's check run in general, such as the contents in the check run and the GitHub pull request or check run. +- ``GET /times-square/api/v1/github-pr/:org/:repo/:sha/:path`` provides metadata about a specific notebook. + +Times Square check runs also link to the pull request preview pages published through Times Square's interface in Squareone. + 0.5.0 (2022-07-04) ------------------ diff --git a/requirements/dev.txt b/requirements/dev.txt index 8a6a0247..d634d186 100644 --- a/requirements/dev.txt +++ b/requirements/dev.txt @@ -2,545 +2,168 @@ # This file is autogenerated by pip-compile with python 3.10 # To update, run: # -# pip-compile --generate-hashes --output-file=requirements/dev.txt requirements/dev.in +# pip-compile --allow-unsafe --output-file=requirements/dev.txt requirements/dev.in # -anyio==3.6.1 \ - --hash=sha256:413adf95f93886e442aea925f3ee43baa5a765a64a0f52c6081894f9992fdd0b \ - --hash=sha256:cb29b9c70620506a9a8f87a309591713446953302d7d995344d0d7c6c0c9a7be +anyio==3.6.1 # via # -c requirements/main.txt # httpcore # watchfiles -asgi-lifespan==1.0.1 \ - --hash=sha256:9a33e7da2073c4764bc79bd6136501d6c42f60e3d2168ba71235e84122eadb7f \ - --hash=sha256:9ea969dc5eb5cf08e52c08dce6f61afcadd28112e72d81c972b1d8eb8691ab53 +asgi-lifespan==1.0.1 # via -r requirements/dev.in -attrs==21.4.0 \ - --hash=sha256:2d27e3784d7a565d36ab851fe94887c5eccd6a463168875832a1be79c82828b4 \ - --hash=sha256:626ba8234211db98e869df76230a137c4c40a12d72445c45d5f5b716f076e2fd +attrs==22.1.0 # via # -c requirements/main.txt # pytest -certifi==2022.6.15 \ - --hash=sha256:84c85a9078b11105f04f3036a9482ae10e4621616db313fe045dd24743a0820d \ - --hash=sha256:fe86415d55e84719d75f8b69414f6438ac3547d2078ab91b67e779ef69378412 +certifi==2022.6.15 # via # -c requirements/main.txt # httpcore # httpx -cfgv==3.3.1 \ - --hash=sha256:c6a0883f3917a037485059700b9e75da2464e6c27051014ad85ba6aaa5884426 \ - --hash=sha256:f5a830efb9ce7a445376bb66ec94c638a9787422f96264c98edc6bdeed8ab736 +cfgv==3.3.1 # via pre-commit -click==8.1.3 \ - --hash=sha256:7682dc8afb30297001674575ea00d1814d808d6a36af415a82bd481d37ba7b8e \ - --hash=sha256:bb4d8133cb15a609f44e8213d9b391b0809795062913b383c62be0ee95b1db48 +click==8.1.3 # via # -c requirements/main.txt # uvicorn -coverage[toml]==6.4.1 \ - --hash=sha256:01c5615d13f3dd3aa8543afc069e5319cfa0c7d712f6e04b920431e5c564a749 \ - --hash=sha256:106c16dfe494de3193ec55cac9640dd039b66e196e4641fa8ac396181578b982 \ - --hash=sha256:129cd05ba6f0d08a766d942a9ed4b29283aff7b2cccf5b7ce279d50796860bb3 \ - --hash=sha256:145f296d00441ca703a659e8f3eb48ae39fb083baba2d7ce4482fb2723e050d9 \ - --hash=sha256:1480ff858b4113db2718848d7b2d1b75bc79895a9c22e76a221b9d8d62496428 \ - --hash=sha256:269eaa2c20a13a5bf17558d4dc91a8d078c4fa1872f25303dddcbba3a813085e \ - --hash=sha256:26dff09fb0d82693ba9e6231248641d60ba606150d02ed45110f9ec26404ed1c \ - --hash=sha256:2bd9a6fc18aab8d2e18f89b7ff91c0f34ff4d5e0ba0b33e989b3cd4194c81fd9 \ - --hash=sha256:309ce4a522ed5fca432af4ebe0f32b21d6d7ccbb0f5fcc99290e71feba67c264 \ - --hash=sha256:3384f2a3652cef289e38100f2d037956194a837221edd520a7ee5b42d00cc605 \ - --hash=sha256:342d4aefd1c3e7f620a13f4fe563154d808b69cccef415415aece4c786665397 \ - --hash=sha256:39ee53946bf009788108b4dd2894bf1349b4e0ca18c2016ffa7d26ce46b8f10d \ - --hash=sha256:4321f075095a096e70aff1d002030ee612b65a205a0a0f5b815280d5dc58100c \ - --hash=sha256:4803e7ccf93230accb928f3a68f00ffa80a88213af98ed338a57ad021ef06815 \ - --hash=sha256:4ce1b258493cbf8aec43e9b50d89982346b98e9ffdfaae8ae5793bc112fb0068 \ - --hash=sha256:664a47ce62fe4bef9e2d2c430306e1428ecea207ffd68649e3b942fa8ea83b0b \ - --hash=sha256:75ab269400706fab15981fd4bd5080c56bd5cc07c3bccb86aab5e1d5a88dc8f4 \ - --hash=sha256:83c4e737f60c6936460c5be330d296dd5b48b3963f48634c53b3f7deb0f34ec4 \ - --hash=sha256:84631e81dd053e8a0d4967cedab6db94345f1c36107c71698f746cb2636c63e3 \ - --hash=sha256:84e65ef149028516c6d64461b95a8dbcfce95cfd5b9eb634320596173332ea84 \ - --hash=sha256:865d69ae811a392f4d06bde506d531f6a28a00af36f5c8649684a9e5e4a85c83 \ - --hash=sha256:87f4f3df85aa39da00fd3ec4b5abeb7407e82b68c7c5ad181308b0e2526da5d4 \ - --hash=sha256:8c08da0bd238f2970230c2a0d28ff0e99961598cb2e810245d7fc5afcf1254e8 \ - --hash=sha256:961e2fb0680b4f5ad63234e0bf55dfb90d302740ae9c7ed0120677a94a1590cb \ - --hash=sha256:9b3e07152b4563722be523e8cd0b209e0d1a373022cfbde395ebb6575bf6790d \ - --hash=sha256:a7f3049243783df2e6cc6deafc49ea123522b59f464831476d3d1448e30d72df \ - --hash=sha256:bf5601c33213d3cb19d17a796f8a14a9eaa5e87629a53979a5981e3e3ae166f6 \ - --hash=sha256:cec3a0f75c8f1031825e19cd86ee787e87cf03e4fd2865c79c057092e69e3a3b \ - --hash=sha256:d42c549a8f41dc103a8004b9f0c433e2086add8a719da00e246e17cbe4056f72 \ - --hash=sha256:d67d44996140af8b84284e5e7d398e589574b376fb4de8ccd28d82ad8e3bea13 \ - --hash=sha256:d9c80df769f5ec05ad21ea34be7458d1dc51ff1fb4b2219e77fe24edf462d6df \ - --hash=sha256:e57816f8ffe46b1df8f12e1b348f06d164fd5219beba7d9433ba79608ef011cc \ - --hash=sha256:ee2ddcac99b2d2aec413e36d7a429ae9ebcadf912946b13ffa88e7d4c9b712d6 \ - --hash=sha256:f02cbbf8119db68455b9d763f2f8737bb7db7e43720afa07d8eb1604e5c5ae28 \ - --hash=sha256:f1d5aa2703e1dab4ae6cf416eb0095304f49d004c39e9db1d86f57924f43006b \ - --hash=sha256:f5b66caa62922531059bc5ac04f836860412f7f88d38a476eda0a6f11d4724f4 \ - --hash=sha256:f69718750eaae75efe506406c490d6fc5a6161d047206cc63ce25527e8a3adad \ - --hash=sha256:fb73e0011b8793c053bfa85e53129ba5f0250fdc0392c1591fd35d915ec75c46 \ - --hash=sha256:fd180ed867e289964404051a958f7cccabdeed423f91a899829264bb7974d3d3 \ - --hash=sha256:fdb6f7bd51c2d1714cea40718f6149ad9be6a2ee7d93b19e9f00934c0f2a74d9 \ - --hash=sha256:ffa9297c3a453fba4717d06df579af42ab9a28022444cae7fa605af4df612d54 +coverage[toml]==6.4.3 # via # -r requirements/dev.in # pytest-cov -distlib==0.3.4 \ - --hash=sha256:6564fe0a8f51e734df6333d08b8b94d4ea8ee6b99b5ed50613f731fd4089f34b \ - --hash=sha256:e4b58818180336dc9c529bfb9a0b58728ffc09ad92027a3f30b7cd91e3458579 +distlib==0.3.5 # via virtualenv -filelock==3.7.1 \ - --hash=sha256:37def7b658813cda163b56fc564cdc75e86d338246458c4c28ae84cabefa2404 \ - --hash=sha256:3a0fd85166ad9dbab54c9aec96737b744106dc5f15c0b09a6744a445299fcf04 +filelock==3.8.0 # via virtualenv -greenlet==1.1.2 \ - --hash=sha256:0051c6f1f27cb756ffc0ffbac7d2cd48cb0362ac1736871399a739b2885134d3 \ - --hash=sha256:00e44c8afdbe5467e4f7b5851be223be68adb4272f44696ee71fe46b7036a711 \ - --hash=sha256:013d61294b6cd8fe3242932c1c5e36e5d1db2c8afb58606c5a67efce62c1f5fd \ - --hash=sha256:049fe7579230e44daef03a259faa24511d10ebfa44f69411d99e6a184fe68073 \ - --hash=sha256:14d4f3cd4e8b524ae9b8aa567858beed70c392fdec26dbdb0a8a418392e71708 \ - --hash=sha256:166eac03e48784a6a6e0e5f041cfebb1ab400b394db188c48b3a84737f505b67 \ - --hash=sha256:17ff94e7a83aa8671a25bf5b59326ec26da379ace2ebc4411d690d80a7fbcf23 \ - --hash=sha256:1e12bdc622676ce47ae9abbf455c189e442afdde8818d9da983085df6312e7a1 \ - --hash=sha256:21915eb821a6b3d9d8eefdaf57d6c345b970ad722f856cd71739493ce003ad08 \ - --hash=sha256:288c6a76705dc54fba69fbcb59904ae4ad768b4c768839b8ca5fdadec6dd8cfd \ - --hash=sha256:2bde6792f313f4e918caabc46532aa64aa27a0db05d75b20edfc5c6f46479de2 \ - --hash=sha256:32ca72bbc673adbcfecb935bb3fb1b74e663d10a4b241aaa2f5a75fe1d1f90aa \ - --hash=sha256:356b3576ad078c89a6107caa9c50cc14e98e3a6c4874a37c3e0273e4baf33de8 \ - --hash=sha256:40b951f601af999a8bf2ce8c71e8aaa4e8c6f78ff8afae7b808aae2dc50d4c40 \ - --hash=sha256:572e1787d1460da79590bf44304abbc0a2da944ea64ec549188fa84d89bba7ab \ - --hash=sha256:58df5c2a0e293bf665a51f8a100d3e9956febfbf1d9aaf8c0677cf70218910c6 \ - --hash=sha256:64e6175c2e53195278d7388c454e0b30997573f3f4bd63697f88d855f7a6a1fc \ - --hash=sha256:7227b47e73dedaa513cdebb98469705ef0d66eb5a1250144468e9c3097d6b59b \ - --hash=sha256:7418b6bfc7fe3331541b84bb2141c9baf1ec7132a7ecd9f375912eca810e714e \ - --hash=sha256:7cbd7574ce8e138bda9df4efc6bf2ab8572c9aff640d8ecfece1b006b68da963 \ - --hash=sha256:7ff61ff178250f9bb3cd89752df0f1dd0e27316a8bd1465351652b1b4a4cdfd3 \ - --hash=sha256:833e1551925ed51e6b44c800e71e77dacd7e49181fdc9ac9a0bf3714d515785d \ - --hash=sha256:8639cadfda96737427330a094476d4c7a56ac03de7265622fcf4cfe57c8ae18d \ - --hash=sha256:8c5d5b35f789a030ebb95bff352f1d27a93d81069f2adb3182d99882e095cefe \ - --hash=sha256:8c790abda465726cfb8bb08bd4ca9a5d0a7bd77c7ac1ca1b839ad823b948ea28 \ - --hash=sha256:8d2f1fb53a421b410751887eb4ff21386d119ef9cde3797bf5e7ed49fb51a3b3 \ - --hash=sha256:903bbd302a2378f984aef528f76d4c9b1748f318fe1294961c072bdc7f2ffa3e \ - --hash=sha256:93f81b134a165cc17123626ab8da2e30c0455441d4ab5576eed73a64c025b25c \ - --hash=sha256:95e69877983ea39b7303570fa6760f81a3eec23d0e3ab2021b7144b94d06202d \ - --hash=sha256:9633b3034d3d901f0a46b7939f8c4d64427dfba6bbc5a36b1a67364cf148a1b0 \ - --hash=sha256:97e5306482182170ade15c4b0d8386ded995a07d7cc2ca8f27958d34d6736497 \ - --hash=sha256:9f3cba480d3deb69f6ee2c1825060177a22c7826431458c697df88e6aeb3caee \ - --hash=sha256:aa5b467f15e78b82257319aebc78dd2915e4c1436c3c0d1ad6f53e47ba6e2713 \ - --hash=sha256:abb7a75ed8b968f3061327c433a0fbd17b729947b400747c334a9c29a9af6c58 \ - --hash=sha256:aec52725173bd3a7b56fe91bc56eccb26fbdff1386ef123abb63c84c5b43b63a \ - --hash=sha256:b11548073a2213d950c3f671aa88e6f83cda6e2fb97a8b6317b1b5b33d850e06 \ - --hash=sha256:b1692f7d6bc45e3200844be0dba153612103db241691088626a33ff1f24a0d88 \ - --hash=sha256:b336501a05e13b616ef81ce329c0e09ac5ed8c732d9ba7e3e983fcc1a9e86965 \ - --hash=sha256:b8c008de9d0daba7b6666aa5bbfdc23dcd78cafc33997c9b7741ff6353bafb7f \ - --hash=sha256:b92e29e58bef6d9cfd340c72b04d74c4b4e9f70c9fa7c78b674d1fec18896dc4 \ - --hash=sha256:be5f425ff1f5f4b3c1e33ad64ab994eed12fc284a6ea71c5243fd564502ecbe5 \ - --hash=sha256:dd0b1e9e891f69e7675ba5c92e28b90eaa045f6ab134ffe70b52e948aa175b3c \ - --hash=sha256:e30f5ea4ae2346e62cedde8794a56858a67b878dd79f7df76a0767e356b1744a \ - --hash=sha256:e6a36bb9474218c7a5b27ae476035497a6990e21d04c279884eb10d9b290f1b1 \ - --hash=sha256:e859fcb4cbe93504ea18008d1df98dee4f7766db66c435e4882ab35cf70cac43 \ - --hash=sha256:eb6ea6da4c787111adf40f697b4e58732ee0942b5d3bd8f435277643329ba627 \ - --hash=sha256:ec8c433b3ab0419100bd45b47c9c8551248a5aee30ca5e9d399a0b57ac04651b \ - --hash=sha256:eff9d20417ff9dcb0d25e2defc2574d10b491bf2e693b4e491914738b7908168 \ - --hash=sha256:f0214eb2a23b85528310dad848ad2ac58e735612929c8072f6093f3585fd342d \ - --hash=sha256:f276df9830dba7a333544bd41070e8175762a7ac20350786b322b714b0e654f5 \ - --hash=sha256:f3acda1924472472ddd60c29e5b9db0cec629fbe3c5c5accb74d6d6d14773478 \ - --hash=sha256:f70a9e237bb792c7cc7e44c531fd48f5897961701cdaa06cf22fc14965c496cf \ - --hash=sha256:f9d29ca8a77117315101425ec7ec2a47a22ccf59f5593378fc4077ac5b754fce \ - --hash=sha256:fa877ca7f6b48054f847b61d6fa7bed5cebb663ebc55e018fda12db09dcc664c \ - --hash=sha256:fdcec0b8399108577ec290f55551d926d9a1fa6cad45882093a7a07ac5ec147b +greenlet==1.1.2 # via # -c requirements/main.txt # sqlalchemy -h11==0.12.0 \ - --hash=sha256:36a3cb8c0a032f56e2da7084577878a035d3b61d104230d4bd49c0c6b555a9c6 \ - --hash=sha256:47222cb6067e4a307d535814917cd98fd0a57b6788ce715755fa2b6c28b56042 +h11==0.12.0 # via # -c requirements/main.txt # httpcore # uvicorn -holdup==3.0.0 \ - --hash=sha256:4a6a43862d3710a27be563c6c91a733de6e59e7c36e94ca701d077d7cb6afda5 \ - --hash=sha256:64b7ab29078c48d284914bb5b15b0ebdbff64cb272bbc8493ba1b149650cfdc5 +holdup==3.0.0 # via -r requirements/dev.in -httpcore==0.15.0 \ - --hash=sha256:1105b8b73c025f23ff7c36468e4432226cbb959176eab66864b8e31c4ee27fa6 \ - --hash=sha256:18b68ab86a3ccf3e7dc0f43598eaddcf472b602aba29f9aa6ab85fe2ada3980b +httpcore==0.15.0 # via # -c requirements/main.txt # httpx -httptools==0.4.0 \ - --hash=sha256:1a99346ebcb801b213c591540837340bdf6fd060a8687518d01c607d338b7424 \ - --hash=sha256:1ee0b459257e222b878a6c09ccf233957d3a4dcb883b0847640af98d2d9aac23 \ - --hash=sha256:20a45bcf22452a10fa8d58b7dbdb474381f6946bf5b8933e3662d572bc61bae4 \ - --hash=sha256:29bf97a5c532da9c7a04de2c7a9c31d1d54f3abd65a464119b680206bbbb1055 \ - --hash=sha256:2c9a930c378b3d15d6b695fb95ebcff81a7395b4f9775c4f10a076beb0b2c1ff \ - --hash=sha256:2db44a0b294d317199e9f80123e72c6b005c55b625b57fae36de68670090fa48 \ - --hash=sha256:3194f6d6443befa8d4db16c1946b2fc428a3ceb8ab32eb6f09a59f86104dc1a0 \ - --hash=sha256:34d2903dd2a3dd85d33705b6fde40bf91fc44411661283763fd0746723963c83 \ - --hash=sha256:48e48530d9b995a84d1d89ae6b3ec4e59ea7d494b150ac3bbc5e2ac4acce92cd \ - --hash=sha256:54bbd295f031b866b9799dd39cb45deee81aca036c9bff9f58ca06726f6494f1 \ - --hash=sha256:5d1fe6b6661022fd6cac541f54a4237496b246e6f1c0a6b41998ee08a1135afe \ - --hash=sha256:645373c070080e632480a3d251d892cb795be3d3a15f86975d0f1aca56fd230d \ - --hash=sha256:6a1a7dfc1f9c78a833e2c4904757a0f47ce25d08634dd2a52af394eefe5f9777 \ - --hash=sha256:701e66b59dd21a32a274771238025d58db7e2b6ecebbab64ceff51b8e31527ae \ - --hash=sha256:72aa3fbe636b16d22e04b5a9d24711b043495e0ecfe58080addf23a1a37f3409 \ - --hash=sha256:7af6bdbd21a2a25d6784f6d67f44f5df33ef39b6159543b9f9064d365c01f919 \ - --hash=sha256:7ee9f226acab9085037582c059d66769862706e8e8cd2340470ceb8b3850873d \ - --hash=sha256:7f7bfb74718f52d5ed47d608d507bf66d3bc01d4a8b3e6dd7134daaae129357b \ - --hash=sha256:8e2eb957787cbb614a0f006bfc5798ff1d90ac7c4dd24854c84edbdc8c02369e \ - --hash=sha256:903f739c9fb78dab8970b0f3ea51f21955b24b45afa77b22ff0e172fc11ef111 \ - --hash=sha256:98993805f1e3cdb53de4eed02b55dcc953cdf017ba7bbb2fd89226c086a6d855 \ - --hash=sha256:9967d9758df505975913304c434cb9ab21e2c609ad859eb921f2f615a038c8de \ - --hash=sha256:a113789e53ac1fa26edf99856a61e4c493868e125ae0dd6354cf518948fbbd5c \ - --hash=sha256:a522d12e2ddbc2e91842ffb454a1aeb0d47607972c7d8fc88bd0838d97fb8a2a \ - --hash=sha256:abe829275cdd4174b4c4e65ad718715d449e308d59793bf3a931ee1bf7e7b86c \ - --hash=sha256:c286985b5e194ca0ebb2908d71464b9be8f17cc66d6d3e330e8d5407248f56ad \ - --hash=sha256:cd1295f52971097f757edfbfce827b6dbbfb0f7a74901ee7d4933dff5ad4c9af \ - --hash=sha256:ceafd5e960b39c7e0d160a1936b68eb87c5e79b3979d66e774f0c77d4d8faaed \ - --hash=sha256:d1f27bb0f75bef722d6e22dc609612bfa2f994541621cd2163f8c943b6463dfe \ - --hash=sha256:d3a4e165ca6204f34856b765d515d558dc84f1352033b8721e8d06c3e44930c3 \ - --hash=sha256:d9b90bf58f3ba04e60321a23a8723a1ff2a9377502535e70495e5ada8e6e6722 \ - --hash=sha256:f72b5d24d6730035128b238decdc4c0f2104b7056a7ca55cf047c106842ec890 \ - --hash=sha256:fcddfe70553be717d9745990dfdb194e22ee0f60eb8f48c0794e7bfeda30d2d5 \ - --hash=sha256:fdb9f9ed79bc6f46b021b3319184699ba1a22410a82204e6e89c774530069683 +httptools==0.4.0 # via # -c requirements/main.txt # uvicorn -httpx==0.23.0 \ - --hash=sha256:42974f577483e1e932c3cdc3cd2303e883cbfba17fe228b0f63589764d7b9c4b \ - --hash=sha256:f28eac771ec9eb4866d3fb4ab65abd42d38c424739e80c08d8d20570de60b0ef +httpx==0.23.0 # via # -c requirements/main.txt # -r requirements/dev.in # respx -identify==2.5.1 \ - --hash=sha256:0dca2ea3e4381c435ef9c33ba100a78a9b40c0bab11189c7cf121f75815efeaa \ - --hash=sha256:3d11b16f3fe19f52039fb7e39c9c884b21cb1b586988114fbe42671f03de3e82 +identify==2.5.3 # via pre-commit -idna==3.3 \ - --hash=sha256:84d9dd047ffa80596e0f246e2eab0b391788b0503584e8945f2368256d2735ff \ - --hash=sha256:9d643ff0a55b762d5cdb124b8eaa99c66322e2157b69160bc32796e824360e6d +idna==3.3 # via # -c requirements/main.txt # anyio # rfc3986 -iniconfig==1.1.1 \ - --hash=sha256:011e24c64b7f47f6ebd835bb12a743f2fbe9a26d4cecaa7f53bc4f35ee9da8b3 \ - --hash=sha256:bc3af051d7d14b2ee5ef9969666def0cd1a000e121eaea580d4a313df4b37f32 +iniconfig==1.1.1 # via pytest -mypy==0.961 \ - --hash=sha256:006be38474216b833eca29ff6b73e143386f352e10e9c2fbe76aa8549e5554f5 \ - --hash=sha256:03c6cc893e7563e7b2949b969e63f02c000b32502a1b4d1314cabe391aa87d66 \ - --hash=sha256:0e9f70df36405c25cc530a86eeda1e0867863d9471fe76d1273c783df3d35c2e \ - --hash=sha256:1ece702f29270ec6af25db8cf6185c04c02311c6bb21a69f423d40e527b75c56 \ - --hash=sha256:3e09f1f983a71d0672bbc97ae33ee3709d10c779beb613febc36805a6e28bb4e \ - --hash=sha256:439c726a3b3da7ca84a0199a8ab444cd8896d95012c4a6c4a0d808e3147abf5d \ - --hash=sha256:5a0b53747f713f490affdceef835d8f0cb7285187a6a44c33821b6d1f46ed813 \ - --hash=sha256:5f1332964963d4832a94bebc10f13d3279be3ce8f6c64da563d6ee6e2eeda932 \ - --hash=sha256:63e85a03770ebf403291ec50097954cc5caf2a9205c888ce3a61bd3f82e17569 \ - --hash=sha256:64759a273d590040a592e0f4186539858c948302c653c2eac840c7a3cd29e51b \ - --hash=sha256:697540876638ce349b01b6786bc6094ccdaba88af446a9abb967293ce6eaa2b0 \ - --hash=sha256:9940e6916ed9371809b35b2154baf1f684acba935cd09928952310fbddaba648 \ - --hash=sha256:9f5f5a74085d9a81a1f9c78081d60a0040c3efb3f28e5c9912b900adf59a16e6 \ - --hash=sha256:a5ea0875a049de1b63b972456542f04643daf320d27dc592d7c3d9cd5d9bf950 \ - --hash=sha256:b117650592e1782819829605a193360a08aa99f1fc23d1d71e1a75a142dc7e15 \ - --hash=sha256:b24be97351084b11582fef18d79004b3e4db572219deee0212078f7cf6352723 \ - --hash=sha256:b88f784e9e35dcaa075519096dc947a388319cb86811b6af621e3523980f1c8a \ - --hash=sha256:bdd5ca340beffb8c44cb9dc26697628d1b88c6bddf5c2f6eb308c46f269bb6f3 \ - --hash=sha256:d5aaf1edaa7692490f72bdb9fbd941fbf2e201713523bdb3f4038be0af8846c6 \ - --hash=sha256:e999229b9f3198c0c880d5e269f9f8129c8862451ce53a011326cad38b9ccd24 \ - --hash=sha256:f4a21d01fc0ba4e31d82f0fff195682e29f9401a8bdb7173891070eb260aeb3b \ - --hash=sha256:f4b794db44168a4fc886e3450201365c9526a522c46ba089b55e1f11c163750d \ - --hash=sha256:f730d56cb924d371c26b8eaddeea3cc07d78ff51c521c6d04899ac6904b75492 +mypy==0.971 # via # -r requirements/dev.in # sqlalchemy -mypy-extensions==0.4.3 \ - --hash=sha256:090fedd75945a69ae91ce1303b5824f428daf5a028d2f6ab8a299250a846f15d \ - --hash=sha256:2d82818f5bb3e369420cb3c4060a7970edba416647068eb4c5343488a6c604a8 +mypy-extensions==0.4.3 # via mypy -nodeenv==1.7.0 \ - --hash=sha256:27083a7b96a25f2f5e1d8cb4b6317ee8aeda3bdd121394e5ac54e498028a042e \ - --hash=sha256:e0e7f7dfb85fc5394c6fe1e8fa98131a2473e04311a45afb6508f7cf1836fa2b +nodeenv==1.7.0 # via pre-commit -packaging==21.3 \ - --hash=sha256:dd47c42927d89ab911e606518907cc2d3a1f38bbd026385970643f9c5b8ecfeb \ - --hash=sha256:ef103e05f519cdc783ae24ea4e2e0f508a9c99b2d4969652eed6a2e1ea5bd522 +packaging==21.3 # via # -c requirements/main.txt # pytest -platformdirs==2.5.2 \ - --hash=sha256:027d8e83a2d7de06bbac4e5ef7e023c02b863d7ea5d079477e722bb41ab25788 \ - --hash=sha256:58c8abb07dcb441e6ee4b11d8df0ac856038f944ab98b7be6b27b2a3c7feef19 +platformdirs==2.5.2 # via virtualenv -pluggy==1.0.0 \ - --hash=sha256:4224373bacce55f955a878bf9cfa763c1e360858e330072059e10bad68531159 \ - --hash=sha256:74134bbf457f031a36d68416e1509f34bd5ccc019f0bcc952c7b909d06b37bd3 +pluggy==1.0.0 # via pytest -pre-commit==2.19.0 \ - --hash=sha256:10c62741aa5704faea2ad69cb550ca78082efe5697d6f04e5710c3c229afdd10 \ - --hash=sha256:4233a1e38621c87d9dda9808c6606d7e7ba0e087cd56d3fe03202a01d2919615 +pre-commit==2.20.0 # via -r requirements/dev.in -py==1.11.0 \ - --hash=sha256:51c75c4126074b472f746a24399ad32f6053d1b34b68d2fa41e558e6f4a98719 \ - --hash=sha256:607c53218732647dff4acdfcd50cb62615cedf612e72d1724fb1a0cc6405b378 +py==1.11.0 # via pytest -pyparsing==3.0.9 \ - --hash=sha256:2b020ecf7d21b687f219b71ecad3631f644a47f01403fa1d1036b0c6416d70fb \ - --hash=sha256:5026bae9a10eeaefb61dab2f09052b9f4307d44aee4eda64b309723d8d206bbc +pyparsing==3.0.9 # via # -c requirements/main.txt # packaging -pytest==7.1.2 \ - --hash=sha256:13d0e3ccfc2b6e26be000cb6568c832ba67ba32e719443bfe725814d3c42433c \ - --hash=sha256:a06a0425453864a270bc45e71f783330a7428defb4230fb5e6a731fde06ecd45 +pytest==7.1.2 # via # -r requirements/dev.in # pytest-asyncio # pytest-cov -pytest-asyncio==0.18.3 \ - --hash=sha256:16cf40bdf2b4fb7fc8e4b82bd05ce3fbcd454cbf7b92afc445fe299dabb88213 \ - --hash=sha256:7659bdb0a9eb9c6e3ef992eef11a2b3e69697800ad02fb06374a210d85b29f91 \ - --hash=sha256:8fafa6c52161addfd41ee7ab35f11836c5a16ec208f93ee388f752bea3493a84 +pytest-asyncio==0.19.0 # via -r requirements/dev.in -pytest-cov==3.0.0 \ - --hash=sha256:578d5d15ac4a25e5f961c938b85a05b09fdaae9deef3bb6de9a6e766622ca7a6 \ - --hash=sha256:e7f0f5b1617d2210a2cabc266dfe2f4c75a8d32fb89eafb7ad9d06f6d076d470 +pytest-cov==3.0.0 # via -r requirements/dev.in -python-dotenv==0.20.0 \ - --hash=sha256:b7e3b04a59693c42c36f9ab1cc2acc46fa5df8c78e178fc33a8d4cd05c8d498f \ - --hash=sha256:d92a187be61fe482e4fd675b6d52200e7be63a12b724abbf931a40ce4fa92938 +python-dotenv==0.20.0 # via # -c requirements/main.txt # uvicorn -pyyaml==6.0 \ - --hash=sha256:0283c35a6a9fbf047493e3a0ce8d79ef5030852c51e9d911a27badfde0605293 \ - --hash=sha256:055d937d65826939cb044fc8c9b08889e8c743fdc6a32b33e2390f66013e449b \ - --hash=sha256:07751360502caac1c067a8132d150cf3d61339af5691fe9e87803040dbc5db57 \ - --hash=sha256:0b4624f379dab24d3725ffde76559cff63d9ec94e1736b556dacdfebe5ab6d4b \ - --hash=sha256:0ce82d761c532fe4ec3f87fc45688bdd3a4c1dc5e0b4a19814b9009a29baefd4 \ - --hash=sha256:1e4747bc279b4f613a09eb64bba2ba602d8a6664c6ce6396a4d0cd413a50ce07 \ - --hash=sha256:213c60cd50106436cc818accf5baa1aba61c0189ff610f64f4a3e8c6726218ba \ - --hash=sha256:231710d57adfd809ef5d34183b8ed1eeae3f76459c18fb4a0b373ad56bedcdd9 \ - --hash=sha256:277a0ef2981ca40581a47093e9e2d13b3f1fbbeffae064c1d21bfceba2030287 \ - --hash=sha256:2cd5df3de48857ed0544b34e2d40e9fac445930039f3cfe4bcc592a1f836d513 \ - --hash=sha256:40527857252b61eacd1d9af500c3337ba8deb8fc298940291486c465c8b46ec0 \ - --hash=sha256:473f9edb243cb1935ab5a084eb238d842fb8f404ed2193a915d1784b5a6b5fc0 \ - --hash=sha256:48c346915c114f5fdb3ead70312bd042a953a8ce5c7106d5bfb1a5254e47da92 \ - --hash=sha256:50602afada6d6cbfad699b0c7bb50d5ccffa7e46a3d738092afddc1f9758427f \ - --hash=sha256:68fb519c14306fec9720a2a5b45bc9f0c8d1b9c72adf45c37baedfcd949c35a2 \ - --hash=sha256:77f396e6ef4c73fdc33a9157446466f1cff553d979bd00ecb64385760c6babdc \ - --hash=sha256:819b3830a1543db06c4d4b865e70ded25be52a2e0631ccd2f6a47a2822f2fd7c \ - --hash=sha256:897b80890765f037df3403d22bab41627ca8811ae55e9a722fd0392850ec4d86 \ - --hash=sha256:98c4d36e99714e55cfbaaee6dd5badbc9a1ec339ebfc3b1f52e293aee6bb71a4 \ - --hash=sha256:9df7ed3b3d2e0ecfe09e14741b857df43adb5a3ddadc919a2d94fbdf78fea53c \ - --hash=sha256:9fa600030013c4de8165339db93d182b9431076eb98eb40ee068700c9c813e34 \ - --hash=sha256:a80a78046a72361de73f8f395f1f1e49f956c6be882eed58505a15f3e430962b \ - --hash=sha256:b3d267842bf12586ba6c734f89d1f5b871df0273157918b0ccefa29deb05c21c \ - --hash=sha256:b5b9eccad747aabaaffbc6064800670f0c297e52c12754eb1d976c57e4f74dcb \ - --hash=sha256:c5687b8d43cf58545ade1fe3e055f70eac7a5a1a0bf42824308d868289a95737 \ - --hash=sha256:cba8c411ef271aa037d7357a2bc8f9ee8b58b9965831d9e51baf703280dc73d3 \ - --hash=sha256:d15a181d1ecd0d4270dc32edb46f7cb7733c7c508857278d3d378d14d606db2d \ - --hash=sha256:d4db7c7aef085872ef65a8fd7d6d09a14ae91f691dec3e87ee5ee0539d516f53 \ - --hash=sha256:d4eccecf9adf6fbcc6861a38015c2a64f38b9d94838ac1810a9023a0609e1b78 \ - --hash=sha256:d67d839ede4ed1b28a4e8909735fc992a923cdb84e618544973d7dfc71540803 \ - --hash=sha256:daf496c58a8c52083df09b80c860005194014c3698698d1a57cbcfa182142a3a \ - --hash=sha256:e61ceaab6f49fb8bdfaa0f92c4b57bcfbea54c09277b1b4f7ac376bfb7a7c174 \ - --hash=sha256:f84fbc98b019fef2ee9a1cb3ce93e3187a6df0b2538a651bfb890254ba9f90b5 +pyyaml==6.0 # via # -c requirements/main.txt # pre-commit # uvicorn -respx==0.19.2 \ - --hash=sha256:417f986fec599b9cc6531e93e494b7a75d1cb7bccff9dde5b53edc51f7954494 \ - --hash=sha256:f3d210bb4de0ccc4c5afabeb87c3c1b03b3765a9c1a73eb042a07bb18ac33705 +respx==0.19.2 # via -r requirements/dev.in -rfc3986[idna2008]==1.5.0 \ - --hash=sha256:270aaf10d87d0d4e095063c65bf3ddbc6ee3d0b226328ce21e036f946e421835 \ - --hash=sha256:a86d6e1f5b1dc238b218b012df0aa79409667bb209e58da56d0b94704e712a97 +rfc3986[idna2008]==1.5.0 # via # -c requirements/main.txt # httpx -six==1.16.0 \ - --hash=sha256:1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926 \ - --hash=sha256:8abb2f1d86890a2dfb989f9a77cfcfd3e47c2a354b01111771326f8aa26e0254 - # via - # -c requirements/main.txt - # virtualenv -sniffio==1.2.0 \ - --hash=sha256:471b71698eac1c2112a40ce2752bb2f4a4814c22a54a3eed3676bc0f5ca9f663 \ - --hash=sha256:c4666eecec1d3f50960c6bdf61ab7bc350648da6c126e3cf6898d8cd4ddcd3de +sniffio==1.2.0 # via # -c requirements/main.txt # anyio # asgi-lifespan # httpcore # httpx -sqlalchemy[asyncio,mypy]==1.4.39 \ - --hash=sha256:047ef5ccd8860f6147b8ac6c45a4bc573d4e030267b45d9a1c47b55962ff0e6f \ - --hash=sha256:05a05771617bfa723ba4cef58d5b25ac028b0d68f28f403edebed5b8243b3a87 \ - --hash=sha256:0ec54460475f0c42512895c99c63d90dd2d9cbd0c13491a184182e85074b04c5 \ - --hash=sha256:107df519eb33d7f8e0d0d052128af2f25066c1a0f6b648fd1a9612ab66800b86 \ - --hash=sha256:14ea8ff2d33c48f8e6c3c472111d893b9e356284d1482102da9678195e5a8eac \ - --hash=sha256:1745987ada1890b0e7978abdb22c133eca2e89ab98dc17939042240063e1ef21 \ - --hash=sha256:1962dfee37b7fb17d3d4889bf84c4ea08b1c36707194c578f61e6e06d12ab90f \ - --hash=sha256:20bf65bcce65c538e68d5df27402b39341fabeecf01de7e0e72b9d9836c13c52 \ - --hash=sha256:26146c59576dfe9c546c9f45397a7c7c4a90c25679492ff610a7500afc7d03a6 \ - --hash=sha256:365b75938049ae31cf2176efd3d598213ddb9eb883fbc82086efa019a5f649df \ - --hash=sha256:4770eb3ba69ec5fa41c681a75e53e0e342ac24c1f9220d883458b5596888e43a \ - --hash=sha256:50e7569637e2e02253295527ff34666706dbb2bc5f6c61a5a7f44b9610c9bb09 \ - --hash=sha256:5c2d19bfb33262bf987ef0062345efd0f54c4189c2d95159c72995457bf4a359 \ - --hash=sha256:621f050e72cc7dfd9ad4594ff0abeaad954d6e4a2891545e8f1a53dcdfbef445 \ - --hash=sha256:6d81de54e45f1d756785405c9d06cd17918c2eecc2d4262dc2d276ca612c2f61 \ - --hash=sha256:6f95706da857e6e79b54c33c1214f5467aab10600aa508ddd1239d5df271986e \ - --hash=sha256:752ef2e8dbaa3c5d419f322e3632f00ba6b1c3230f65bc97c2ff5c5c6c08f441 \ - --hash=sha256:7b2785dd2a0c044a36836857ac27310dc7a99166253551ee8f5408930958cc60 \ - --hash=sha256:7f13644b15665f7322f9e0635129e0ef2098409484df67fcd225d954c5861559 \ - --hash=sha256:8194896038753b46b08a0b0ae89a5d80c897fb601dd51e243ed5720f1f155d27 \ - --hash=sha256:864d4f89f054819cb95e93100b7d251e4d114d1c60bc7576db07b046432af280 \ - --hash=sha256:8b773c9974c272aae0fa7e95b576d98d17ee65f69d8644f9b6ffc90ee96b4d19 \ - --hash=sha256:8f901be74f00a13bf375241a778455ee864c2c21c79154aad196b7a994e1144f \ - --hash=sha256:91d2b89bb0c302f89e753bea008936acfa4e18c156fb264fe41eb6bbb2bbcdeb \ - --hash=sha256:b0538b66f959771c56ff996d828081908a6a52a47c5548faed4a3d0a027a5368 \ - --hash=sha256:b30e70f1594ee3c8902978fd71900d7312453922827c4ce0012fa6a8278d6df4 \ - --hash=sha256:b71be98ef6e180217d1797185c75507060a57ab9cd835653e0112db16a710f0d \ - --hash=sha256:c6d00cb9da8d0cbfaba18cad046e94b06de6d4d0ffd9d4095a3ad1838af22528 \ - --hash=sha256:d1f665e50592caf4cad3caed3ed86f93227bffe0680218ccbb293bd5a6734ca8 \ - --hash=sha256:e6e2c8581c6620136b9530137954a8376efffd57fe19802182c7561b0ab48b48 \ - --hash=sha256:e7a7667d928ba6ee361a3176e1bef6847c1062b37726b33505cc84136f657e0d \ - --hash=sha256:ec3985c883d6d217cf2013028afc6e3c82b8907192ba6195d6e49885bfc4b19d \ - --hash=sha256:ede13a472caa85a13abe5095e71676af985d7690eaa8461aeac5c74f6600b6c0 \ - --hash=sha256:f24d4d6ec301688c59b0c4bb1c1c94c5d0bff4ecad33bb8f5d9efdfb8d8bc925 \ - --hash=sha256:f2a42acc01568b9701665e85562bbff78ec3e21981c7d51d56717c22e5d3d58b \ - --hash=sha256:fbc076f79d830ae4c9d49926180a1140b49fa675d0f0d555b44c9a15b29f4c80 +sqlalchemy[asyncio,mypy]==1.4.40 # via # -c requirements/main.txt # -r requirements/dev.in -sqlalchemy2-stubs==0.0.2a24 \ - --hash=sha256:e15c45302eafe196ed516f979ef017135fd619d2c62d02de9a5c5f2e59a600c4 \ - --hash=sha256:f2399251d3d8f00a88659d711a449c855a0d4e977c7a9134e414f1459b9acc11 +sqlalchemy2-stubs==0.0.2a25 # via sqlalchemy -toml==0.10.2 \ - --hash=sha256:806143ae5bfb6a3c6e736a764057db0e6a0e05e338b5630894a5f779cabb4f9b \ - --hash=sha256:b3bda1d108d5dd99f4a20d24d9c348e91c4db7ab1b749200bded2f839ccbe68f +toml==0.10.2 # via pre-commit -tomli==2.0.1 \ - --hash=sha256:939de3e7a6161af0c887ef91b7d41a53e7c5a1ca976325f429cb46ea9bc30ecc \ - --hash=sha256:de526c12914f0c550d15924c62d72abc48d6fe7364aa87328337a31007fe8a4f +tomli==2.0.1 # via # -c requirements/main.txt # coverage # mypy # pytest -types-pyyaml==6.0.9 \ - --hash=sha256:33ae75c84b8f61fddf0c63e9c7e557db9db1694ad3c2ee8628ec5efebb5a5e9b \ - --hash=sha256:b738e9ef120da0af8c235ba49d3b72510f56ef9bcc308fc8e7357100ff122284 +types-pyyaml==6.0.11 # via -r requirements/dev.in -typing-extensions==4.2.0 \ - --hash=sha256:6657594ee297170d19f67d55c05852a874e7eb634f4f753dbd667855e07c1708 \ - --hash=sha256:f1c24655a0da0d1b67f07e17a5e6b2a105894e6824b92096378bb3668ef02376 +typing-extensions==4.3.0 # via # -c requirements/main.txt # mypy # sqlalchemy2-stubs -uvicorn[standard]==0.18.1 \ - --hash=sha256:013c4ea0787cc2dc456ef4368e18c01982e6be57903e4d3183218e543eb889b7 \ - --hash=sha256:35703e6518105cfe53f16a5a9435db3e2e227d0784f1fd8fbc1214b1fdc108df +uvicorn[standard]==0.18.2 # via # -c requirements/main.txt # -r requirements/dev.in -uvloop==0.16.0 \ - --hash=sha256:04ff57aa137230d8cc968f03481176041ae789308b4d5079118331ab01112450 \ - --hash=sha256:089b4834fd299d82d83a25e3335372f12117a7d38525217c2258e9b9f4578897 \ - --hash=sha256:1e5f2e2ff51aefe6c19ee98af12b4ae61f5be456cd24396953244a30880ad861 \ - --hash=sha256:30ba9dcbd0965f5c812b7c2112a1ddf60cf904c1c160f398e7eed3a6b82dcd9c \ - --hash=sha256:3a19828c4f15687675ea912cc28bbcb48e9bb907c801873bd1519b96b04fb805 \ - --hash=sha256:6224f1401025b748ffecb7a6e2652b17768f30b1a6a3f7b44660e5b5b690b12d \ - --hash=sha256:647e481940379eebd314c00440314c81ea547aa636056f554d491e40503c8464 \ - --hash=sha256:6ccd57ae8db17d677e9e06192e9c9ec4bd2066b77790f9aa7dede2cc4008ee8f \ - --hash=sha256:772206116b9b57cd625c8a88f2413df2fcfd0b496eb188b82a43bed7af2c2ec9 \ - --hash=sha256:8e0d26fa5875d43ddbb0d9d79a447d2ace4180d9e3239788208527c4784f7cab \ - --hash=sha256:98d117332cc9e5ea8dfdc2b28b0a23f60370d02e1395f88f40d1effd2cb86c4f \ - --hash=sha256:b572256409f194521a9895aef274cea88731d14732343da3ecdb175228881638 \ - --hash=sha256:bd53f7f5db562f37cd64a3af5012df8cac2c464c97e732ed556800129505bd64 \ - --hash=sha256:bd8f42ea1ea8f4e84d265769089964ddda95eb2bb38b5cbe26712b0616c3edee \ - --hash=sha256:e814ac2c6f9daf4c36eb8e85266859f42174a4ff0d71b99405ed559257750382 \ - --hash=sha256:f74bc20c7b67d1c27c72601c78cf95be99d5c2cdd4514502b4f3eb0933ff1228 +uvloop==0.16.0 # via # -c requirements/main.txt # uvicorn -virtualenv==20.15.0 \ - --hash=sha256:4c44b1d77ca81f8368e2d7414f9b20c428ad16b343ac6d226206c5b84e2b4fcc \ - --hash=sha256:804cce4de5b8a322f099897e308eecc8f6e2951f1a8e7e2b3598dff865f01336 +virtualenv==20.16.3 # via pre-commit -watchfiles==0.15.0 \ - --hash=sha256:56abed43e645d1f2d6def83e35999cc5758b051aff54ca1065cbfcaea15b3389 \ - --hash=sha256:65ca99a94fcab29d00aa406526eb29cf198c0661854d59a315596064fed02141 \ - --hash=sha256:67d4c66e46a564059df4aeedab78f09cba0b697bf36cc77566b0a7015dfb7f5d \ - --hash=sha256:6e0e8829d32b05151e6009570449f44f891e05f518e495d25f960e0d0b2d0064 \ - --hash=sha256:715733c2ac9da67b2790788657ff6f8b3797eb31565bfc592289b523ae907ca2 \ - --hash=sha256:7b81c6e404b2aa62482a719eb778e4a16d01728302dce1f1512c1e5354a73fda \ - --hash=sha256:82238d08d8a49f1a1ba254278cd4329a154f6100b028393059722ebeddd2ff3d \ - --hash=sha256:955e8f840e1996a8a41be57de4c03af7b1515a685b7fb6abe222f859e413a907 \ - --hash=sha256:cab62510f990d195986302aa6a48ed636d685b099927049120d520c96069fa49 \ - --hash=sha256:d1f9de6b776b3aff17898a4cf5ac5a2d0a16212ea7aad2bbe0ef6aa3e79a96af \ - --hash=sha256:d4f45acd1143db6d3ee77a4ff12d3239bc8083108133e6174e9dcce59c1f9902 \ - --hash=sha256:f7f71012e096e11256fae3b37617a9777980f281e18deb2e789e85cd5b113935 +watchfiles==0.16.1 # via # -c requirements/main.txt # uvicorn -websockets==10.3 \ - --hash=sha256:07cdc0a5b2549bcfbadb585ad8471ebdc7bdf91e32e34ae3889001c1c106a6af \ - --hash=sha256:210aad7fdd381c52e58777560860c7e6110b6174488ef1d4b681c08b68bf7f8c \ - --hash=sha256:28dd20b938a57c3124028680dc1600c197294da5db4292c76a0b48efb3ed7f76 \ - --hash=sha256:2f94fa3ae454a63ea3a19f73b95deeebc9f02ba2d5617ca16f0bbdae375cda47 \ - --hash=sha256:31564a67c3e4005f27815634343df688b25705cccb22bc1db621c781ddc64c69 \ - --hash=sha256:347974105bbd4ea068106ec65e8e8ebd86f28c19e529d115d89bd8cc5cda3079 \ - --hash=sha256:379e03422178436af4f3abe0aa8f401aa77ae2487843738542a75faf44a31f0c \ - --hash=sha256:3eda1cb7e9da1b22588cefff09f0951771d6ee9fa8dbe66f5ae04cc5f26b2b55 \ - --hash=sha256:51695d3b199cd03098ae5b42833006a0f43dc5418d3102972addc593a783bc02 \ - --hash=sha256:54c000abeaff6d8771a4e2cef40900919908ea7b6b6a30eae72752607c6db559 \ - --hash=sha256:5b936bf552e4f6357f5727579072ff1e1324717902127ffe60c92d29b67b7be3 \ - --hash=sha256:6075fd24df23133c1b078e08a9b04a3bc40b31a8def4ee0b9f2c8865acce913e \ - --hash=sha256:661f641b44ed315556a2fa630239adfd77bd1b11cb0b9d96ed8ad90b0b1e4978 \ - --hash=sha256:6ea6b300a6bdd782e49922d690e11c3669828fe36fc2471408c58b93b5535a98 \ - --hash=sha256:6ed1d6f791eabfd9808afea1e068f5e59418e55721db8b7f3bfc39dc831c42ae \ - --hash=sha256:7934e055fd5cd9dee60f11d16c8d79c4567315824bacb1246d0208a47eca9755 \ - --hash=sha256:7ab36e17af592eec5747c68ef2722a74c1a4a70f3772bc661079baf4ae30e40d \ - --hash=sha256:7f6d96fdb0975044fdd7953b35d003b03f9e2bcf85f2d2cf86285ece53e9f991 \ - --hash=sha256:83e5ca0d5b743cde3d29fda74ccab37bdd0911f25bd4cdf09ff8b51b7b4f2fa1 \ - --hash=sha256:85506b3328a9e083cc0a0fb3ba27e33c8db78341b3eb12eb72e8afd166c36680 \ - --hash=sha256:8af75085b4bc0b5c40c4a3c0e113fa95e84c60f4ed6786cbb675aeb1ee128247 \ - --hash=sha256:8b1359aba0ff810d5830d5ab8e2c4a02bebf98a60aa0124fb29aa78cfdb8031f \ - --hash=sha256:8fbd7d77f8aba46d43245e86dd91a8970eac4fb74c473f8e30e9c07581f852b2 \ - --hash=sha256:907e8247480f287aa9bbc9391bd6de23c906d48af54c8c421df84655eef66af7 \ - --hash=sha256:93d5ea0b5da8d66d868b32c614d2b52d14304444e39e13a59566d4acb8d6e2e4 \ - --hash=sha256:97bc9d41e69a7521a358f9b8e44871f6cdeb42af31815c17aed36372d4eec667 \ - --hash=sha256:994cdb1942a7a4c2e10098d9162948c9e7b235df755de91ca33f6e0481366fdb \ - --hash=sha256:a141de3d5a92188234afa61653ed0bbd2dde46ad47b15c3042ffb89548e77094 \ - --hash=sha256:a1e15b230c3613e8ea82c9fc6941b2093e8eb939dd794c02754d33980ba81e36 \ - --hash=sha256:aad5e300ab32036eb3fdc350ad30877210e2f51bceaca83fb7fef4d2b6c72b79 \ - --hash=sha256:b529fdfa881b69fe563dbd98acce84f3e5a67df13de415e143ef053ff006d500 \ - --hash=sha256:b9c77f0d1436ea4b4dc089ed8335fa141e6a251a92f75f675056dac4ab47a71e \ - --hash=sha256:bb621ec2dbbbe8df78a27dbd9dd7919f9b7d32a73fafcb4d9252fc4637343582 \ - --hash=sha256:c7250848ce69559756ad0086a37b82c986cd33c2d344ab87fea596c5ac6d9442 \ - --hash=sha256:c8d1d14aa0f600b5be363077b621b1b4d1eb3fbf90af83f9281cda668e6ff7fd \ - --hash=sha256:d1655a6fc7aecd333b079d00fb3c8132d18988e47f19740c69303bf02e9883c6 \ - --hash=sha256:d6353ba89cfc657a3f5beabb3b69be226adbb5c6c7a66398e17809b0ce3c4731 \ - --hash=sha256:da4377904a3379f0c1b75a965fff23b28315bcd516d27f99a803720dfebd94d4 \ - --hash=sha256:e49ea4c1a9543d2bd8a747ff24411509c29e4bdcde05b5b0895e2120cb1a761d \ - --hash=sha256:e4e08305bfd76ba8edab08dcc6496f40674f44eb9d5e23153efa0a35750337e8 \ - --hash=sha256:e6fa05a680e35d0fcc1470cb070b10e6fe247af54768f488ed93542e71339d6f \ - --hash=sha256:e7e6f2d6fd48422071cc8a6f8542016f350b79cc782752de531577d35e9bd677 \ - --hash=sha256:e904c0381c014b914136c492c8fa711ca4cced4e9b3d110e5e7d436d0fc289e8 \ - --hash=sha256:ec2b0ab7edc8cd4b0eb428b38ed89079bdc20c6bdb5f889d353011038caac2f9 \ - --hash=sha256:ef5ce841e102278c1c2e98f043db99d6755b1c58bde475516aef3a008ed7f28e \ - --hash=sha256:f351c7d7d92f67c0609329ab2735eee0426a03022771b00102816a72715bb00b \ - --hash=sha256:fab7c640815812ed5f10fbee7abbf58788d602046b7bb3af9b1ac753a6d5e916 \ - --hash=sha256:fc06cc8073c8e87072138ba1e431300e2d408f054b27047d047b549455066ff4 +websockets==10.3 # via # -c requirements/main.txt # uvicorn -# WARNING: The following packages were not pinned, but pip requires them to be -# pinned when the requirements file includes hashes. Consider using the --allow-unsafe flag. -# setuptools +# The following packages are considered to be unsafe in a requirements file: +setuptools==65.0.0 + # via + # -c requirements/main.txt + # nodeenv diff --git a/requirements/main.txt b/requirements/main.txt index 7894e573..d038bbf4 100644 --- a/requirements/main.txt +++ b/requirements/main.txt @@ -2,950 +2,236 @@ # This file is autogenerated by pip-compile with python 3.10 # To update, run: # -# pip-compile --generate-hashes --output-file=requirements/main.txt requirements/main.in +# pip-compile --allow-unsafe --output-file=requirements/main.txt requirements/main.in # -aioredis==2.0.1 \ - --hash=sha256:9ac0d0b3b485d293b8ca1987e6de8658d7dafcca1cddfcd1d506cae8cdebfdd6 \ - --hash=sha256:eaa51aaf993f2d71f54b70527c440437ba65340588afeb786cd87c55c89cd98e +aioredis==2.0.1 # via -r requirements/main.in -anyio==3.6.1 \ - --hash=sha256:413adf95f93886e442aea925f3ee43baa5a765a64a0f52c6081894f9992fdd0b \ - --hash=sha256:cb29b9c70620506a9a8f87a309591713446953302d7d995344d0d7c6c0c9a7be +anyio==3.6.1 # via # httpcore # starlette # watchfiles -arq==0.23a1 \ - --hash=sha256:7cec3b9584f7ac735f4ee93e88c27a8eb4552d379ea8d76f84b60f52fc404f03 \ - --hash=sha256:b60a347be3865ab058284320c5309a3303f8466d0843de44de9633e74871194f +arq==0.23a1 # via safir -async-timeout==4.0.2 \ - --hash=sha256:2163e1640ddb52b7a8c80d0a67a08587e5d245cc9c553a74a847056bc2976b15 \ - --hash=sha256:8ca1e4fcf50d07413d66d1a5e416e42cfdf5851c981d679a09851a6853383b3c +async-timeout==4.0.2 # via # aioredis # redis -asyncpg==0.25.0 \ - --hash=sha256:0a61fb196ce4dae2f2fa26eb20a778db21bbee484d2e798cb3cc988de13bdd1b \ - --hash=sha256:18d49e2d93a7139a2fdbd113e320cc47075049997268a61bfbe0dde680c55471 \ - --hash=sha256:191fe6341385b7fdea7dbdcf47fd6db3fd198827dcc1f2b228476d13c05a03c6 \ - --hash=sha256:1a70783f6ffa34cc7dd2de20a873181414a34fd35a4a208a1f1a7f9f695e4ec4 \ - --hash=sha256:2633331cbc8429030b4f20f712f8d0fbba57fa8555ee9b2f45f981b81328b256 \ - --hash=sha256:2bc197fc4aca2fd24f60241057998124012469d2e414aed3f992579db0c88e3a \ - --hash=sha256:4327f691b1bdb222df27841938b3e04c14068166b3a97491bec2cb982f49f03e \ - --hash=sha256:43cde84e996a3afe75f325a68300093425c2f47d340c0fc8912765cf24a1c095 \ - --hash=sha256:52fab7f1b2c29e187dd8781fce896249500cf055b63471ad66332e537e9b5f7e \ - --hash=sha256:56d88d7ef4341412cd9c68efba323a4519c916979ba91b95d4c08799d2ff0c09 \ - --hash=sha256:5e4105f57ad1e8fbc8b1e535d8fcefa6ce6c71081228f08680c6dea24384ff0e \ - --hash=sha256:63f8e6a69733b285497c2855464a34de657f2cccd25aeaeeb5071872e9382540 \ - --hash=sha256:649e2966d98cc48d0646d9a4e29abecd8b59d38d55c256d5c857f6b27b7407ac \ - --hash=sha256:6f8f5fc975246eda83da8031a14004b9197f510c41511018e7b1bedde6968e92 \ - --hash=sha256:72a1e12ea0cf7c1e02794b697e3ca967b2360eaa2ce5d4bfdd8604ec2d6b774b \ - --hash=sha256:739bbd7f89a2b2f6bc44cb8bf967dab12c5bc714fcbe96e68d512be45ecdf962 \ - --hash=sha256:863d36eba4a7caa853fd7d83fad5fd5306f050cc2fe6e54fbe10cdb30420e5e9 \ - --hash=sha256:a738f1b2876f30d710d3dc1e7858160a0afe1603ba16bf5f391f5316eb0ed855 \ - --hash=sha256:a84d30e6f850bac0876990bcd207362778e2208df0bee8be8da9f1558255e634 \ - --hash=sha256:acb311722352152936e58a8ee3c5b8e791b24e84cd7d777c414ff05b3530ca68 \ - --hash=sha256:beaecc52ad39614f6ca2e48c3ca15d56e24a2c15cbfdcb764a4320cc45f02fd5 \ - --hash=sha256:bf5e3408a14a17d480f36ebaf0401a12ff6ae5457fdf45e4e2775c51cc9517d3 \ - --hash=sha256:bf6dc9b55b9113f39eaa2057337ce3f9ef7de99a053b8a16360395ce588925cd \ - --hash=sha256:ddb4c3263a8d63dcde3d2c4ac1c25206bfeb31fa83bd70fd539e10f87739dee4 \ - --hash=sha256:f55918ded7b85723a5eaeb34e86e7b9280d4474be67df853ab5a7fa0cc7c6bf2 \ - --hash=sha256:fe471ccd915b739ca65e2e4dbd92a11b44a5b37f2e38f70827a1c147dafe0fa8 +asyncpg==0.26.0 # via safir -attrs==21.4.0 \ - --hash=sha256:2d27e3784d7a565d36ab851fe94887c5eccd6a463168875832a1be79c82828b4 \ - --hash=sha256:626ba8234211db98e869df76230a137c4c40a12d72445c45d5f5b716f076e2fd +attrs==22.1.0 # via jsonschema -beautifulsoup4==4.11.1 \ - --hash=sha256:58d5c3d29f5a36ffeb94f02f0d786cd53014cf9b3b3951d42e0080d8a9498d30 \ - --hash=sha256:ad9aa55b65ef2808eb405f46cf74df7fcb7044d5cbc26487f96eb2ef2e436693 +beautifulsoup4==4.11.1 # via nbconvert -bleach==5.0.0 \ - --hash=sha256:08a1fe86d253b5c88c92cc3d810fd8048a16d15762e1e5b74d502256e5926aa1 \ - --hash=sha256:c6d6cc054bdc9c83b48b8083e236e5f00f238428666d2ce2e083eaa5fd568565 +bleach==5.0.1 # via nbconvert -certifi==2022.6.15 \ - --hash=sha256:84c85a9078b11105f04f3036a9482ae10e4621616db313fe045dd24743a0820d \ - --hash=sha256:fe86415d55e84719d75f8b69414f6438ac3547d2078ab91b67e779ef69378412 +certifi==2022.6.15 # via # httpcore # httpx -cffi==1.15.0 \ - --hash=sha256:00c878c90cb53ccfaae6b8bc18ad05d2036553e6d9d1d9dbcf323bbe83854ca3 \ - --hash=sha256:0104fb5ae2391d46a4cb082abdd5c69ea4eab79d8d44eaaf79f1b1fd806ee4c2 \ - --hash=sha256:06c48159c1abed75c2e721b1715c379fa3200c7784271b3c46df01383b593636 \ - --hash=sha256:0808014eb713677ec1292301ea4c81ad277b6cdf2fdd90fd540af98c0b101d20 \ - --hash=sha256:10dffb601ccfb65262a27233ac273d552ddc4d8ae1bf93b21c94b8511bffe728 \ - --hash=sha256:14cd121ea63ecdae71efa69c15c5543a4b5fbcd0bbe2aad864baca0063cecf27 \ - --hash=sha256:17771976e82e9f94976180f76468546834d22a7cc404b17c22df2a2c81db0c66 \ - --hash=sha256:181dee03b1170ff1969489acf1c26533710231c58f95534e3edac87fff06c443 \ - --hash=sha256:23cfe892bd5dd8941608f93348c0737e369e51c100d03718f108bf1add7bd6d0 \ - --hash=sha256:263cc3d821c4ab2213cbe8cd8b355a7f72a8324577dc865ef98487c1aeee2bc7 \ - --hash=sha256:2756c88cbb94231c7a147402476be2c4df2f6078099a6f4a480d239a8817ae39 \ - --hash=sha256:27c219baf94952ae9d50ec19651a687b826792055353d07648a5695413e0c605 \ - --hash=sha256:2a23af14f408d53d5e6cd4e3d9a24ff9e05906ad574822a10563efcef137979a \ - --hash=sha256:31fb708d9d7c3f49a60f04cf5b119aeefe5644daba1cd2a0fe389b674fd1de37 \ - --hash=sha256:3415c89f9204ee60cd09b235810be700e993e343a408693e80ce7f6a40108029 \ - --hash=sha256:3773c4d81e6e818df2efbc7dd77325ca0dcb688116050fb2b3011218eda36139 \ - --hash=sha256:3b96a311ac60a3f6be21d2572e46ce67f09abcf4d09344c49274eb9e0bf345fc \ - --hash=sha256:3f7d084648d77af029acb79a0ff49a0ad7e9d09057a9bf46596dac9514dc07df \ - --hash=sha256:41d45de54cd277a7878919867c0f08b0cf817605e4eb94093e7516505d3c8d14 \ - --hash=sha256:4238e6dab5d6a8ba812de994bbb0a79bddbdf80994e4ce802b6f6f3142fcc880 \ - --hash=sha256:45db3a33139e9c8f7c09234b5784a5e33d31fd6907800b316decad50af323ff2 \ - --hash=sha256:45e8636704eacc432a206ac7345a5d3d2c62d95a507ec70d62f23cd91770482a \ - --hash=sha256:4958391dbd6249d7ad855b9ca88fae690783a6be9e86df65865058ed81fc860e \ - --hash=sha256:4a306fa632e8f0928956a41fa8e1d6243c71e7eb59ffbd165fc0b41e316b2474 \ - --hash=sha256:57e9ac9ccc3101fac9d6014fba037473e4358ef4e89f8e181f8951a2c0162024 \ - --hash=sha256:59888172256cac5629e60e72e86598027aca6bf01fa2465bdb676d37636573e8 \ - --hash=sha256:5e069f72d497312b24fcc02073d70cb989045d1c91cbd53979366077959933e0 \ - --hash=sha256:64d4ec9f448dfe041705426000cc13e34e6e5bb13736e9fd62e34a0b0c41566e \ - --hash=sha256:6dc2737a3674b3e344847c8686cf29e500584ccad76204efea14f451d4cc669a \ - --hash=sha256:74fdfdbfdc48d3f47148976f49fab3251e550a8720bebc99bf1483f5bfb5db3e \ - --hash=sha256:75e4024375654472cc27e91cbe9eaa08567f7fbdf822638be2814ce059f58032 \ - --hash=sha256:786902fb9ba7433aae840e0ed609f45c7bcd4e225ebb9c753aa39725bb3e6ad6 \ - --hash=sha256:8b6c2ea03845c9f501ed1313e78de148cd3f6cad741a75d43a29b43da27f2e1e \ - --hash=sha256:91d77d2a782be4274da750752bb1650a97bfd8f291022b379bb8e01c66b4e96b \ - --hash=sha256:91ec59c33514b7c7559a6acda53bbfe1b283949c34fe7440bcf917f96ac0723e \ - --hash=sha256:920f0d66a896c2d99f0adbb391f990a84091179542c205fa53ce5787aff87954 \ - --hash=sha256:a5263e363c27b653a90078143adb3d076c1a748ec9ecc78ea2fb916f9b861962 \ - --hash=sha256:abb9a20a72ac4e0fdb50dae135ba5e77880518e742077ced47eb1499e29a443c \ - --hash=sha256:c2051981a968d7de9dd2d7b87bcb9c939c74a34626a6e2f8181455dd49ed69e4 \ - --hash=sha256:c21c9e3896c23007803a875460fb786118f0cdd4434359577ea25eb556e34c55 \ - --hash=sha256:c2502a1a03b6312837279c8c1bd3ebedf6c12c4228ddbad40912d671ccc8a962 \ - --hash=sha256:d4d692a89c5cf08a8557fdeb329b82e7bf609aadfaed6c0d79f5a449a3c7c023 \ - --hash=sha256:da5db4e883f1ce37f55c667e5c0de439df76ac4cb55964655906306918e7363c \ - --hash=sha256:e7022a66d9b55e93e1a845d8c9eba2a1bebd4966cd8bfc25d9cd07d515b33fa6 \ - --hash=sha256:ef1f279350da2c586a69d32fc8733092fd32cc8ac95139a00377841f59a3f8d8 \ - --hash=sha256:f54a64f8b0c8ff0b64d18aa76675262e1700f3995182267998c31ae974fbc382 \ - --hash=sha256:f5c7150ad32ba43a07c4479f40241756145a1f03b43480e058cfd862bf5041c7 \ - --hash=sha256:f6f824dc3bce0edab5f427efcfb1d63ee75b6fcb7282900ccaf925be84efb0fc \ - --hash=sha256:fd8a250edc26254fe5b33be00402e6d287f562b6a5b2152dec302fa15bb3e997 \ - --hash=sha256:ffaa5c925128e29efbde7301d8ecaf35c8c60ffbcd6a1ffd3a552177c8e5e796 +cffi==1.15.1 # via cryptography -click==8.1.3 \ - --hash=sha256:7682dc8afb30297001674575ea00d1814d808d6a36af415a82bd481d37ba7b8e \ - --hash=sha256:bb4d8133cb15a609f44e8213d9b391b0809795062913b383c62be0ee95b1db48 +click==8.1.3 # via # -r requirements/main.in # arq # uvicorn -cryptography==37.0.2 \ - --hash=sha256:093cb351031656d3ee2f4fa1be579a8c69c754cf874206be1d4cf3b542042804 \ - --hash=sha256:0cc20f655157d4cfc7bada909dc5cc228211b075ba8407c46467f63597c78178 \ - --hash=sha256:1b9362d34363f2c71b7853f6251219298124aa4cc2075ae2932e64c91a3e2717 \ - --hash=sha256:1f3bfbd611db5cb58ca82f3deb35e83af34bb8cf06043fa61500157d50a70982 \ - --hash=sha256:2bd1096476aaac820426239ab534b636c77d71af66c547b9ddcd76eb9c79e004 \ - --hash=sha256:31fe38d14d2e5f787e0aecef831457da6cec68e0bb09a35835b0b44ae8b988fe \ - --hash=sha256:3b8398b3d0efc420e777c40c16764d6870bcef2eb383df9c6dbb9ffe12c64452 \ - --hash=sha256:3c81599befb4d4f3d7648ed3217e00d21a9341a9a688ecdd615ff72ffbed7336 \ - --hash=sha256:419c57d7b63f5ec38b1199a9521d77d7d1754eb97827bbb773162073ccd8c8d4 \ - --hash=sha256:46f4c544f6557a2fefa7ac8ac7d1b17bf9b647bd20b16decc8fbcab7117fbc15 \ - --hash=sha256:471e0d70201c069f74c837983189949aa0d24bb2d751b57e26e3761f2f782b8d \ - --hash=sha256:59b281eab51e1b6b6afa525af2bd93c16d49358404f814fe2c2410058623928c \ - --hash=sha256:731c8abd27693323b348518ed0e0705713a36d79fdbd969ad968fbef0979a7e0 \ - --hash=sha256:95e590dd70642eb2079d280420a888190aa040ad20f19ec8c6e097e38aa29e06 \ - --hash=sha256:a68254dd88021f24a68b613d8c51d5c5e74d735878b9e32cc0adf19d1f10aaf9 \ - --hash=sha256:a7d5137e556cc0ea418dca6186deabe9129cee318618eb1ffecbd35bee55ddc1 \ - --hash=sha256:aeaba7b5e756ea52c8861c133c596afe93dd716cbcacae23b80bc238202dc023 \ - --hash=sha256:dc26bb134452081859aa21d4990474ddb7e863aa39e60d1592800a8865a702de \ - --hash=sha256:e53258e69874a306fcecb88b7534d61820db8a98655662a3dd2ec7f1afd9132f \ - --hash=sha256:ef15c2df7656763b4ff20a9bc4381d8352e6640cfeb95c2972c38ef508e75181 \ - --hash=sha256:f224ad253cc9cea7568f49077007d2263efa57396a2f2f78114066fd54b5c68e \ - --hash=sha256:f8ec91983e638a9bcd75b39f1396e5c0dc2330cbd9ce4accefe68717e6779e0a +cryptography==37.0.4 # via pyjwt -defusedxml==0.7.1 \ - --hash=sha256:1bb3032db185915b62d7c6209c5a8792be6a32ab2fedacc84e01b52c51aa3e69 \ - --hash=sha256:a352e7e428770286cc899e2542b6cdaedb2b4953ff269a210103ec58f6198a61 +defusedxml==0.7.1 # via nbconvert -deprecated==1.2.13 \ - --hash=sha256:43ac5335da90c31c24ba028af536a91d41d53f9e6901ddb021bcc572ce44e38d \ - --hash=sha256:64756e3e14c8c5eea9795d93c524551432a0be75629f8f29e67ab8caf076c76d +deprecated==1.2.13 # via redis -dnspython==2.2.1 \ - --hash=sha256:0f7569a4a6ff151958b64304071d370daa3243d15941a7beedf0c9fe5105603e \ - --hash=sha256:a851e51367fb93e9e1361732c1d60dab63eff98712e503ea7d92e6eccb109b4f +dnspython==2.2.1 # via email-validator -email-validator==1.2.1 \ - --hash=sha256:6757aea012d40516357c0ac2b1a4c31219ab2f899d26831334c5d069e8b6c3d8 \ - --hash=sha256:c8589e691cf73eb99eed8d10ce0e9cbb05a0886ba920c8bcb7c82873f4c5789c +email-validator==1.2.1 # via pydantic -entrypoints==0.4 \ - --hash=sha256:b706eddaa9218a19ebcd67b56818f05bb27589b1ca9e8d797b74affad4ccacd4 \ - --hash=sha256:f174b5ff827504fd3cd97cc3f8649f3693f51538c7e4bdf3ef002c8429d42f9f +entrypoints==0.4 # via # jupyter-client # nbconvert -fastapi==0.78.0 \ - --hash=sha256:15fcabd5c78c266fa7ae7d8de9b384bfc2375ee0503463a6febbe3bab69d6f65 \ - --hash=sha256:3233d4a789ba018578658e2af1a4bb5e38bdd122ff722b313666a9b2c6786a83 +fastapi==0.79.0 # via # -r requirements/main.in # safir -fastjsonschema==2.15.3 \ - --hash=sha256:0a572f0836962d844c1fc435e200b2e4f4677e4e6611a2e3bdd01ba697c275ec \ - --hash=sha256:ddb0b1d8243e6e3abb822bd14e447a89f4ab7439342912d590444831fa00b6a0 +fastjsonschema==2.16.1 # via nbformat -gidgethub==5.2.0 \ - --hash=sha256:390caafb3e9c6125bb9c8c9865a78d09e028f19592352d5b88e0ed881b8dea18 \ - --hash=sha256:c359b769194e72f984d2e328de0ee8eb81b702342b0a44dc5cebac92104ecf4b +gidgethub==5.2.0 # via -r requirements/main.in -greenlet==1.1.2 \ - --hash=sha256:0051c6f1f27cb756ffc0ffbac7d2cd48cb0362ac1736871399a739b2885134d3 \ - --hash=sha256:00e44c8afdbe5467e4f7b5851be223be68adb4272f44696ee71fe46b7036a711 \ - --hash=sha256:013d61294b6cd8fe3242932c1c5e36e5d1db2c8afb58606c5a67efce62c1f5fd \ - --hash=sha256:049fe7579230e44daef03a259faa24511d10ebfa44f69411d99e6a184fe68073 \ - --hash=sha256:14d4f3cd4e8b524ae9b8aa567858beed70c392fdec26dbdb0a8a418392e71708 \ - --hash=sha256:166eac03e48784a6a6e0e5f041cfebb1ab400b394db188c48b3a84737f505b67 \ - --hash=sha256:17ff94e7a83aa8671a25bf5b59326ec26da379ace2ebc4411d690d80a7fbcf23 \ - --hash=sha256:1e12bdc622676ce47ae9abbf455c189e442afdde8818d9da983085df6312e7a1 \ - --hash=sha256:21915eb821a6b3d9d8eefdaf57d6c345b970ad722f856cd71739493ce003ad08 \ - --hash=sha256:288c6a76705dc54fba69fbcb59904ae4ad768b4c768839b8ca5fdadec6dd8cfd \ - --hash=sha256:2bde6792f313f4e918caabc46532aa64aa27a0db05d75b20edfc5c6f46479de2 \ - --hash=sha256:32ca72bbc673adbcfecb935bb3fb1b74e663d10a4b241aaa2f5a75fe1d1f90aa \ - --hash=sha256:356b3576ad078c89a6107caa9c50cc14e98e3a6c4874a37c3e0273e4baf33de8 \ - --hash=sha256:40b951f601af999a8bf2ce8c71e8aaa4e8c6f78ff8afae7b808aae2dc50d4c40 \ - --hash=sha256:572e1787d1460da79590bf44304abbc0a2da944ea64ec549188fa84d89bba7ab \ - --hash=sha256:58df5c2a0e293bf665a51f8a100d3e9956febfbf1d9aaf8c0677cf70218910c6 \ - --hash=sha256:64e6175c2e53195278d7388c454e0b30997573f3f4bd63697f88d855f7a6a1fc \ - --hash=sha256:7227b47e73dedaa513cdebb98469705ef0d66eb5a1250144468e9c3097d6b59b \ - --hash=sha256:7418b6bfc7fe3331541b84bb2141c9baf1ec7132a7ecd9f375912eca810e714e \ - --hash=sha256:7cbd7574ce8e138bda9df4efc6bf2ab8572c9aff640d8ecfece1b006b68da963 \ - --hash=sha256:7ff61ff178250f9bb3cd89752df0f1dd0e27316a8bd1465351652b1b4a4cdfd3 \ - --hash=sha256:833e1551925ed51e6b44c800e71e77dacd7e49181fdc9ac9a0bf3714d515785d \ - --hash=sha256:8639cadfda96737427330a094476d4c7a56ac03de7265622fcf4cfe57c8ae18d \ - --hash=sha256:8c5d5b35f789a030ebb95bff352f1d27a93d81069f2adb3182d99882e095cefe \ - --hash=sha256:8c790abda465726cfb8bb08bd4ca9a5d0a7bd77c7ac1ca1b839ad823b948ea28 \ - --hash=sha256:8d2f1fb53a421b410751887eb4ff21386d119ef9cde3797bf5e7ed49fb51a3b3 \ - --hash=sha256:903bbd302a2378f984aef528f76d4c9b1748f318fe1294961c072bdc7f2ffa3e \ - --hash=sha256:93f81b134a165cc17123626ab8da2e30c0455441d4ab5576eed73a64c025b25c \ - --hash=sha256:95e69877983ea39b7303570fa6760f81a3eec23d0e3ab2021b7144b94d06202d \ - --hash=sha256:9633b3034d3d901f0a46b7939f8c4d64427dfba6bbc5a36b1a67364cf148a1b0 \ - --hash=sha256:97e5306482182170ade15c4b0d8386ded995a07d7cc2ca8f27958d34d6736497 \ - --hash=sha256:9f3cba480d3deb69f6ee2c1825060177a22c7826431458c697df88e6aeb3caee \ - --hash=sha256:aa5b467f15e78b82257319aebc78dd2915e4c1436c3c0d1ad6f53e47ba6e2713 \ - --hash=sha256:abb7a75ed8b968f3061327c433a0fbd17b729947b400747c334a9c29a9af6c58 \ - --hash=sha256:aec52725173bd3a7b56fe91bc56eccb26fbdff1386ef123abb63c84c5b43b63a \ - --hash=sha256:b11548073a2213d950c3f671aa88e6f83cda6e2fb97a8b6317b1b5b33d850e06 \ - --hash=sha256:b1692f7d6bc45e3200844be0dba153612103db241691088626a33ff1f24a0d88 \ - --hash=sha256:b336501a05e13b616ef81ce329c0e09ac5ed8c732d9ba7e3e983fcc1a9e86965 \ - --hash=sha256:b8c008de9d0daba7b6666aa5bbfdc23dcd78cafc33997c9b7741ff6353bafb7f \ - --hash=sha256:b92e29e58bef6d9cfd340c72b04d74c4b4e9f70c9fa7c78b674d1fec18896dc4 \ - --hash=sha256:be5f425ff1f5f4b3c1e33ad64ab994eed12fc284a6ea71c5243fd564502ecbe5 \ - --hash=sha256:dd0b1e9e891f69e7675ba5c92e28b90eaa045f6ab134ffe70b52e948aa175b3c \ - --hash=sha256:e30f5ea4ae2346e62cedde8794a56858a67b878dd79f7df76a0767e356b1744a \ - --hash=sha256:e6a36bb9474218c7a5b27ae476035497a6990e21d04c279884eb10d9b290f1b1 \ - --hash=sha256:e859fcb4cbe93504ea18008d1df98dee4f7766db66c435e4882ab35cf70cac43 \ - --hash=sha256:eb6ea6da4c787111adf40f697b4e58732ee0942b5d3bd8f435277643329ba627 \ - --hash=sha256:ec8c433b3ab0419100bd45b47c9c8551248a5aee30ca5e9d399a0b57ac04651b \ - --hash=sha256:eff9d20417ff9dcb0d25e2defc2574d10b491bf2e693b4e491914738b7908168 \ - --hash=sha256:f0214eb2a23b85528310dad848ad2ac58e735612929c8072f6093f3585fd342d \ - --hash=sha256:f276df9830dba7a333544bd41070e8175762a7ac20350786b322b714b0e654f5 \ - --hash=sha256:f3acda1924472472ddd60c29e5b9db0cec629fbe3c5c5accb74d6d6d14773478 \ - --hash=sha256:f70a9e237bb792c7cc7e44c531fd48f5897961701cdaa06cf22fc14965c496cf \ - --hash=sha256:f9d29ca8a77117315101425ec7ec2a47a22ccf59f5593378fc4077ac5b754fce \ - --hash=sha256:fa877ca7f6b48054f847b61d6fa7bed5cebb663ebc55e018fda12db09dcc664c \ - --hash=sha256:fdcec0b8399108577ec290f55551d926d9a1fa6cad45882093a7a07ac5ec147b +greenlet==1.1.2 # via sqlalchemy -gunicorn==20.1.0 \ - --hash=sha256:9dcc4547dbb1cb284accfb15ab5667a0e5d1881cc443e0677b4882a4067a807e \ - --hash=sha256:e0a968b5ba15f8a328fdfd7ab1fcb5af4470c28aaf7e55df02a99bc13138e6e8 +gunicorn==20.1.0 # via -r requirements/main.in -h11==0.12.0 \ - --hash=sha256:36a3cb8c0a032f56e2da7084577878a035d3b61d104230d4bd49c0c6b555a9c6 \ - --hash=sha256:47222cb6067e4a307d535814917cd98fd0a57b6788ce715755fa2b6c28b56042 +h11==0.12.0 # via # httpcore # uvicorn -httpcore==0.15.0 \ - --hash=sha256:1105b8b73c025f23ff7c36468e4432226cbb959176eab66864b8e31c4ee27fa6 \ - --hash=sha256:18b68ab86a3ccf3e7dc0f43598eaddcf472b602aba29f9aa6ab85fe2ada3980b +httpcore==0.15.0 # via httpx -httptools==0.4.0 \ - --hash=sha256:1a99346ebcb801b213c591540837340bdf6fd060a8687518d01c607d338b7424 \ - --hash=sha256:1ee0b459257e222b878a6c09ccf233957d3a4dcb883b0847640af98d2d9aac23 \ - --hash=sha256:20a45bcf22452a10fa8d58b7dbdb474381f6946bf5b8933e3662d572bc61bae4 \ - --hash=sha256:29bf97a5c532da9c7a04de2c7a9c31d1d54f3abd65a464119b680206bbbb1055 \ - --hash=sha256:2c9a930c378b3d15d6b695fb95ebcff81a7395b4f9775c4f10a076beb0b2c1ff \ - --hash=sha256:2db44a0b294d317199e9f80123e72c6b005c55b625b57fae36de68670090fa48 \ - --hash=sha256:3194f6d6443befa8d4db16c1946b2fc428a3ceb8ab32eb6f09a59f86104dc1a0 \ - --hash=sha256:34d2903dd2a3dd85d33705b6fde40bf91fc44411661283763fd0746723963c83 \ - --hash=sha256:48e48530d9b995a84d1d89ae6b3ec4e59ea7d494b150ac3bbc5e2ac4acce92cd \ - --hash=sha256:54bbd295f031b866b9799dd39cb45deee81aca036c9bff9f58ca06726f6494f1 \ - --hash=sha256:5d1fe6b6661022fd6cac541f54a4237496b246e6f1c0a6b41998ee08a1135afe \ - --hash=sha256:645373c070080e632480a3d251d892cb795be3d3a15f86975d0f1aca56fd230d \ - --hash=sha256:6a1a7dfc1f9c78a833e2c4904757a0f47ce25d08634dd2a52af394eefe5f9777 \ - --hash=sha256:701e66b59dd21a32a274771238025d58db7e2b6ecebbab64ceff51b8e31527ae \ - --hash=sha256:72aa3fbe636b16d22e04b5a9d24711b043495e0ecfe58080addf23a1a37f3409 \ - --hash=sha256:7af6bdbd21a2a25d6784f6d67f44f5df33ef39b6159543b9f9064d365c01f919 \ - --hash=sha256:7ee9f226acab9085037582c059d66769862706e8e8cd2340470ceb8b3850873d \ - --hash=sha256:7f7bfb74718f52d5ed47d608d507bf66d3bc01d4a8b3e6dd7134daaae129357b \ - --hash=sha256:8e2eb957787cbb614a0f006bfc5798ff1d90ac7c4dd24854c84edbdc8c02369e \ - --hash=sha256:903f739c9fb78dab8970b0f3ea51f21955b24b45afa77b22ff0e172fc11ef111 \ - --hash=sha256:98993805f1e3cdb53de4eed02b55dcc953cdf017ba7bbb2fd89226c086a6d855 \ - --hash=sha256:9967d9758df505975913304c434cb9ab21e2c609ad859eb921f2f615a038c8de \ - --hash=sha256:a113789e53ac1fa26edf99856a61e4c493868e125ae0dd6354cf518948fbbd5c \ - --hash=sha256:a522d12e2ddbc2e91842ffb454a1aeb0d47607972c7d8fc88bd0838d97fb8a2a \ - --hash=sha256:abe829275cdd4174b4c4e65ad718715d449e308d59793bf3a931ee1bf7e7b86c \ - --hash=sha256:c286985b5e194ca0ebb2908d71464b9be8f17cc66d6d3e330e8d5407248f56ad \ - --hash=sha256:cd1295f52971097f757edfbfce827b6dbbfb0f7a74901ee7d4933dff5ad4c9af \ - --hash=sha256:ceafd5e960b39c7e0d160a1936b68eb87c5e79b3979d66e774f0c77d4d8faaed \ - --hash=sha256:d1f27bb0f75bef722d6e22dc609612bfa2f994541621cd2163f8c943b6463dfe \ - --hash=sha256:d3a4e165ca6204f34856b765d515d558dc84f1352033b8721e8d06c3e44930c3 \ - --hash=sha256:d9b90bf58f3ba04e60321a23a8723a1ff2a9377502535e70495e5ada8e6e6722 \ - --hash=sha256:f72b5d24d6730035128b238decdc4c0f2104b7056a7ca55cf047c106842ec890 \ - --hash=sha256:fcddfe70553be717d9745990dfdb194e22ee0f60eb8f48c0794e7bfeda30d2d5 \ - --hash=sha256:fdb9f9ed79bc6f46b021b3319184699ba1a22410a82204e6e89c774530069683 +httptools==0.4.0 # via uvicorn -httpx==0.23.0 \ - --hash=sha256:42974f577483e1e932c3cdc3cd2303e883cbfba17fe228b0f63589764d7b9c4b \ - --hash=sha256:f28eac771ec9eb4866d3fb4ab65abd42d38c424739e80c08d8d20570de60b0ef +httpx==0.23.0 # via safir -idna==3.3 \ - --hash=sha256:84d9dd047ffa80596e0f246e2eab0b391788b0503584e8945f2368256d2735ff \ - --hash=sha256:9d643ff0a55b762d5cdb124b8eaa99c66322e2157b69160bc32796e824360e6d +idna==3.3 # via # anyio # email-validator # rfc3986 -jinja2==3.1.2 \ - --hash=sha256:31351a702a408a9e7595a8fc6150fc3f43bb6bf7e319770cbc0db9df9437e852 \ - --hash=sha256:6088930bfe239f0e6710546ab9c19c9ef35e29792895fed6e6e31a023a182a61 +jinja2==3.1.2 # via # -r requirements/main.in # nbconvert -jsonschema==4.6.0 \ - --hash=sha256:1c92d2db1900b668201f1797887d66453ab1fbfea51df8e4b46236689c427baf \ - --hash=sha256:9d6397ba4a6c0bf0300736057f649e3e12ecbc07d3e81a0dacb72de4e9801957 +jsonschema==4.9.1 # via # -r requirements/main.in # nbformat -jupyter-client==7.3.4 \ - --hash=sha256:17d74b0d0a7b24f1c8c527b24fcf4607c56bee542ffe8e3418e50b21e514b621 \ - --hash=sha256:aa9a6c32054b290374f95f73bb0cae91455c58dfb84f65c8591912b8f65e6d56 +jupyter-client==7.3.4 # via nbclient -jupyter-core==4.10.0 \ - --hash=sha256:a6de44b16b7b31d7271130c71a6792c4040f077011961138afed5e5e73181aec \ - --hash=sha256:e7f5212177af7ab34179690140f188aa9bf3d322d8155ed972cbded19f55b6f3 +jupyter-core==4.11.1 # via # jupyter-client # nbconvert # nbformat -jupyterlab-pygments==0.2.2 \ - --hash=sha256:2405800db07c9f770863bcf8049a529c3dd4d3e28536638bd7c1c01d2748309f \ - --hash=sha256:7405d7fde60819d905a9fa8ce89e4cd830e318cdad22a0030f7a901da705585d +jupyterlab-pygments==0.2.2 # via nbconvert -linkify-it-py==1.0.3 \ - --hash=sha256:11e29f00150cddaa8f434153f103c14716e7e097a8fd372d9eb1ed06ed91524d \ - --hash=sha256:2b3f168d5ce75e3a425e34b341a6b73e116b5d9ed8dbbbf5dc7456843b7ce2ee +linkify-it-py==1.0.3 # via markdown-it-py -markdown-it-py[linkify,plugins]==2.1.0 \ - --hash=sha256:93de681e5c021a432c63147656fe21790bc01231e0cd2da73626f1aa3ac0fe27 \ - --hash=sha256:cf7e59fed14b5ae17c0006eff14a2d9a00ed5f3a846148153899a0224e2c07da +lxml==4.9.1 + # via nbconvert +markdown-it-py[linkify,plugins]==2.1.0 # via # -r requirements/main.in # mdformat # mdformat-gfm # mdit-py-plugins -markupsafe==2.1.1 \ - --hash=sha256:0212a68688482dc52b2d45013df70d169f542b7394fc744c02a57374a4207003 \ - --hash=sha256:089cf3dbf0cd6c100f02945abeb18484bd1ee57a079aefd52cffd17fba910b88 \ - --hash=sha256:10c1bfff05d95783da83491be968e8fe789263689c02724e0c691933c52994f5 \ - --hash=sha256:33b74d289bd2f5e527beadcaa3f401e0df0a89927c1559c8566c066fa4248ab7 \ - --hash=sha256:3799351e2336dc91ea70b034983ee71cf2f9533cdff7c14c90ea126bfd95d65a \ - --hash=sha256:3ce11ee3f23f79dbd06fb3d63e2f6af7b12db1d46932fe7bd8afa259a5996603 \ - --hash=sha256:421be9fbf0ffe9ffd7a378aafebbf6f4602d564d34be190fc19a193232fd12b1 \ - --hash=sha256:43093fb83d8343aac0b1baa75516da6092f58f41200907ef92448ecab8825135 \ - --hash=sha256:46d00d6cfecdde84d40e572d63735ef81423ad31184100411e6e3388d405e247 \ - --hash=sha256:4a33dea2b688b3190ee12bd7cfa29d39c9ed176bda40bfa11099a3ce5d3a7ac6 \ - --hash=sha256:4b9fe39a2ccc108a4accc2676e77da025ce383c108593d65cc909add5c3bd601 \ - --hash=sha256:56442863ed2b06d19c37f94d999035e15ee982988920e12a5b4ba29b62ad1f77 \ - --hash=sha256:671cd1187ed5e62818414afe79ed29da836dde67166a9fac6d435873c44fdd02 \ - --hash=sha256:694deca8d702d5db21ec83983ce0bb4b26a578e71fbdbd4fdcd387daa90e4d5e \ - --hash=sha256:6a074d34ee7a5ce3effbc526b7083ec9731bb3cbf921bbe1d3005d4d2bdb3a63 \ - --hash=sha256:6d0072fea50feec76a4c418096652f2c3238eaa014b2f94aeb1d56a66b41403f \ - --hash=sha256:6fbf47b5d3728c6aea2abb0589b5d30459e369baa772e0f37a0320185e87c980 \ - --hash=sha256:7f91197cc9e48f989d12e4e6fbc46495c446636dfc81b9ccf50bb0ec74b91d4b \ - --hash=sha256:86b1f75c4e7c2ac2ccdaec2b9022845dbb81880ca318bb7a0a01fbf7813e3812 \ - --hash=sha256:8dc1c72a69aa7e082593c4a203dcf94ddb74bb5c8a731e4e1eb68d031e8498ff \ - --hash=sha256:8e3dcf21f367459434c18e71b2a9532d96547aef8a871872a5bd69a715c15f96 \ - --hash=sha256:8e576a51ad59e4bfaac456023a78f6b5e6e7651dcd383bcc3e18d06f9b55d6d1 \ - --hash=sha256:96e37a3dc86e80bf81758c152fe66dbf60ed5eca3d26305edf01892257049925 \ - --hash=sha256:97a68e6ada378df82bc9f16b800ab77cbf4b2fada0081794318520138c088e4a \ - --hash=sha256:99a2a507ed3ac881b975a2976d59f38c19386d128e7a9a18b7df6fff1fd4c1d6 \ - --hash=sha256:a49907dd8420c5685cfa064a1335b6754b74541bbb3706c259c02ed65b644b3e \ - --hash=sha256:b09bf97215625a311f669476f44b8b318b075847b49316d3e28c08e41a7a573f \ - --hash=sha256:b7bd98b796e2b6553da7225aeb61f447f80a1ca64f41d83612e6139ca5213aa4 \ - --hash=sha256:b87db4360013327109564f0e591bd2a3b318547bcef31b468a92ee504d07ae4f \ - --hash=sha256:bcb3ed405ed3222f9904899563d6fc492ff75cce56cba05e32eff40e6acbeaa3 \ - --hash=sha256:d4306c36ca495956b6d568d276ac11fdd9c30a36f1b6eb928070dc5360b22e1c \ - --hash=sha256:d5ee4f386140395a2c818d149221149c54849dfcfcb9f1debfe07a8b8bd63f9a \ - --hash=sha256:dda30ba7e87fbbb7eab1ec9f58678558fd9a6b8b853530e176eabd064da81417 \ - --hash=sha256:e04e26803c9c3851c931eac40c695602c6295b8d432cbe78609649ad9bd2da8a \ - --hash=sha256:e1c0b87e09fa55a220f058d1d49d3fb8df88fbfab58558f1198e08c1e1de842a \ - --hash=sha256:e72591e9ecd94d7feb70c1cbd7be7b3ebea3f548870aa91e2732960fa4d57a37 \ - --hash=sha256:e8c843bbcda3a2f1e3c2ab25913c80a3c5376cd00c6e8c4a86a89a28c8dc5452 \ - --hash=sha256:efc1913fd2ca4f334418481c7e595c00aad186563bbc1ec76067848c7ca0a933 \ - --hash=sha256:f121a1420d4e173a5d96e47e9a0c0dcff965afdf1626d28de1460815f7c4ee7a \ - --hash=sha256:fc7b548b17d238737688817ab67deebb30e8073c95749d55538ed473130ec0c7 +markupsafe==2.1.1 # via # jinja2 # nbconvert -mdformat==0.7.14 \ - --hash=sha256:530eabe496726bd5f4dec5635c37c2496f4c8abc4c15fafa606919b48d92a9d9 \ - --hash=sha256:60c457955f795e5a030e24bc96be30a29eee7836ba98b32e02581688da7670c5 +mdformat==0.7.14 # via # -r requirements/main.in # mdformat-gfm # mdformat-tables -mdformat-gfm==0.3.5 \ - --hash=sha256:1e627edc7665b59e008b3b9e5decc18c40cbd625c196d77e5ea3bc624e80ac8a \ - --hash=sha256:5ee5f0de1d3b56d5edfced023bfff0aeed958be328e5460dac3221ac1b61ce7c +mdformat-gfm==0.3.5 # via -r requirements/main.in -mdformat-tables==0.4.1 \ - --hash=sha256:3024e88e9d29d7b8bb07fd6b59c9d5dcf14d2060122be29e30e72d27b65d7da9 \ - --hash=sha256:981f3dc7350027f78e3fd6a5fe8a16e123eec423af2d140e588d855751501019 +mdformat-tables==0.4.1 # via mdformat-gfm -mdit-py-plugins==0.3.0 \ - --hash=sha256:b1279701cee2dbf50e188d3da5f51fee8d78d038cdf99be57c6b9d1aa93b4073 \ - --hash=sha256:ecc24f51eeec6ab7eecc2f9724e8272c2fb191c2e93cf98109120c2cace69750 +mdit-py-plugins==0.3.0 # via # markdown-it-py # mdformat-gfm -mdurl==0.1.1 \ - --hash=sha256:6a8f6804087b7128040b2fb2ebe242bdc2affaeaa034d5fc9feeed30b443651b \ - --hash=sha256:f79c9709944df218a4cdb0fcc0b0c7ead2f44594e3e84dc566606f04ad749c20 +mdurl==0.1.2 # via markdown-it-py -mistune==0.8.4 \ - --hash=sha256:59a3429db53c50b5c6bcc8a07f8848cb00d7dc8bdb431a4ab41920d201d4756e \ - --hash=sha256:88a1051873018da288eee8538d476dffe1262495144b33ecb586c4ab266bb8d4 +mistune==0.8.4 # via nbconvert -nbclient==0.6.4 \ - --hash=sha256:cdef7757cead1735d2c70cc66095b072dced8a1e6d1c7639ef90cd3e04a11f2e \ - --hash=sha256:f251bba200a2b401a061dfd700a7a70b5772f664fb49d4a2d3e5536ec0e98c76 +nbclient==0.6.6 # via nbconvert -nbconvert==6.5.0 \ - --hash=sha256:223e46e27abe8596b8aed54301fadbba433b7ffea8196a68fd7b1ff509eee99d \ - --hash=sha256:c56dd0b8978a1811a5654f74c727ff16ca87dd5a43abd435a1c49b840fcd8360 +nbconvert==6.5.3 # via -r requirements/main.in -nbformat==5.4.0 \ - --hash=sha256:0d6072aaec95dddc39735c144ee8bbc6589c383fb462e4058abc855348152dad \ - --hash=sha256:44ba5ca6acb80c5d5a500f1e5b83ede8cbe364d5a495c4c8cf60aaf1ba656501 +nbformat==5.4.0 # via # -r requirements/main.in # nbclient # nbconvert -nest-asyncio==1.5.5 \ - --hash=sha256:b98e3ec1b246135e4642eceffa5a6c23a3ab12c82ff816a92c612d68205813b2 \ - --hash=sha256:e442291cd942698be619823a17a86a5759eabe1f8613084790de189fe9e16d65 +nest-asyncio==1.5.5 # via # jupyter-client # nbclient -packaging==21.3 \ - --hash=sha256:dd47c42927d89ab911e606518907cc2d3a1f38bbd026385970643f9c5b8ecfeb \ - --hash=sha256:ef103e05f519cdc783ae24ea4e2e0f508a9c99b2d4969652eed6a2e1ea5bd522 +packaging==21.3 # via # nbconvert # redis -pandocfilters==1.5.0 \ - --hash=sha256:0b679503337d233b4339a817bfc8c50064e2eff681314376a47cb582305a7a38 \ - --hash=sha256:33aae3f25fd1a026079f5d27bdd52496f0e0803b3469282162bafdcbdf6ef14f +pandocfilters==1.5.0 # via nbconvert -pycparser==2.21 \ - --hash=sha256:8ee45429555515e1f6b185e78100aea234072576aa43ab53aefcae078162fca9 \ - --hash=sha256:e644fdec12f7872f86c58ff790da456218b10f863970249516d60a5eaca77206 +pycparser==2.21 # via cffi -pydantic[email]==1.9.1 \ - --hash=sha256:02eefd7087268b711a3ff4db528e9916ac9aa18616da7bca69c1871d0b7a091f \ - --hash=sha256:059b6c1795170809103a1538255883e1983e5b831faea6558ef873d4955b4a74 \ - --hash=sha256:0bf07cab5b279859c253d26a9194a8906e6f4a210063b84b433cf90a569de0c1 \ - --hash=sha256:1542636a39c4892c4f4fa6270696902acb186a9aaeac6f6cf92ce6ae2e88564b \ - --hash=sha256:177071dfc0df6248fd22b43036f936cfe2508077a72af0933d0c1fa269b18537 \ - --hash=sha256:18f3e912f9ad1bdec27fb06b8198a2ccc32f201e24174cec1b3424dda605a310 \ - --hash=sha256:1dd8fecbad028cd89d04a46688d2fcc14423e8a196d5b0a5c65105664901f810 \ - --hash=sha256:1ed987c3ff29fff7fd8c3ea3a3ea877ad310aae2ef9889a119e22d3f2db0691a \ - --hash=sha256:447d5521575f18e18240906beadc58551e97ec98142266e521c34968c76c8761 \ - --hash=sha256:494f7c8537f0c02b740c229af4cb47c0d39840b829ecdcfc93d91dcbb0779892 \ - --hash=sha256:4988c0f13c42bfa9ddd2fe2f569c9d54646ce84adc5de84228cfe83396f3bd58 \ - --hash=sha256:4ce9ae9e91f46c344bec3b03d6ee9612802682c1551aaf627ad24045ce090761 \ - --hash=sha256:5d93d4e95eacd313d2c765ebe40d49ca9dd2ed90e5b37d0d421c597af830c195 \ - --hash=sha256:61b6760b08b7c395975d893e0b814a11cf011ebb24f7d869e7118f5a339a82e1 \ - --hash=sha256:72ccb318bf0c9ab97fc04c10c37683d9eea952ed526707fabf9ac5ae59b701fd \ - --hash=sha256:79b485767c13788ee314669008d01f9ef3bc05db9ea3298f6a50d3ef596a154b \ - --hash=sha256:7eb57ba90929bac0b6cc2af2373893d80ac559adda6933e562dcfb375029acee \ - --hash=sha256:8bc541a405423ce0e51c19f637050acdbdf8feca34150e0d17f675e72d119580 \ - --hash=sha256:969dd06110cb780da01336b281f53e2e7eb3a482831df441fb65dd30403f4608 \ - --hash=sha256:985ceb5d0a86fcaa61e45781e567a59baa0da292d5ed2e490d612d0de5796918 \ - --hash=sha256:9bcf8b6e011be08fb729d110f3e22e654a50f8a826b0575c7196616780683380 \ - --hash=sha256:9ce157d979f742a915b75f792dbd6aa63b8eccaf46a1005ba03aa8a986bde34a \ - --hash=sha256:9f659a5ee95c8baa2436d392267988fd0f43eb774e5eb8739252e5a7e9cf07e0 \ - --hash=sha256:a4a88dcd6ff8fd47c18b3a3709a89adb39a6373f4482e04c1b765045c7e282fd \ - --hash=sha256:a955260d47f03df08acf45689bd163ed9df82c0e0124beb4251b1290fa7ae728 \ - --hash=sha256:a9af62e9b5b9bc67b2a195ebc2c2662fdf498a822d62f902bf27cccb52dbbf49 \ - --hash=sha256:ae72f8098acb368d877b210ebe02ba12585e77bd0db78ac04a1ee9b9f5dd2166 \ - --hash=sha256:b83ba3825bc91dfa989d4eed76865e71aea3a6ca1388b59fc801ee04c4d8d0d6 \ - --hash=sha256:c11951b404e08b01b151222a1cb1a9f0a860a8153ce8334149ab9199cd198131 \ - --hash=sha256:c320c64dd876e45254bdd350f0179da737463eea41c43bacbee9d8c9d1021f11 \ - --hash=sha256:c8098a724c2784bf03e8070993f6d46aa2eeca031f8d8a048dff277703e6e193 \ - --hash=sha256:d12f96b5b64bec3f43c8e82b4aab7599d0157f11c798c9f9c528a72b9e0b339a \ - --hash=sha256:e565a785233c2d03724c4dc55464559639b1ba9ecf091288dd47ad9c629433bd \ - --hash=sha256:f0f047e11febe5c3198ed346b507e1d010330d56ad615a7e0a89fae604065a0e \ - --hash=sha256:fe4670cb32ea98ffbf5a1262f14c3e102cccd92b1869df3bb09538158ba90fe6 +pydantic[email]==1.9.2 # via # -r requirements/main.in # arq # fastapi # safir -pygments==2.12.0 \ - --hash=sha256:5eb116118f9612ff1ee89ac96437bb6b49e8f04d8a13b514ba26f620208e26eb \ - --hash=sha256:dc9c10fb40944260f6ed4c688ece0cd2048414940f1cea51b8b226318411c519 +pygments==2.13.0 # via nbconvert -pyjwt[crypto]==2.4.0 \ - --hash=sha256:72d1d253f32dbd4f5c88eaf1fdc62f3a19f676ccbadb9dbc5d07e951b2b26daf \ - --hash=sha256:d42908208c699b3b973cbeb01a969ba6a96c821eefb1c5bfe4c390c01d67abba +pyjwt[crypto]==2.4.0 # via gidgethub -pyparsing==3.0.9 \ - --hash=sha256:2b020ecf7d21b687f219b71ecad3631f644a47f01403fa1d1036b0c6416d70fb \ - --hash=sha256:5026bae9a10eeaefb61dab2f09052b9f4307d44aee4eda64b309723d8d206bbc +pyparsing==3.0.9 # via packaging -pyrsistent==0.18.1 \ - --hash=sha256:0e3e1fcc45199df76053026a51cc59ab2ea3fc7c094c6627e93b7b44cdae2c8c \ - --hash=sha256:1b34eedd6812bf4d33814fca1b66005805d3640ce53140ab8bbb1e2651b0d9bc \ - --hash=sha256:4ed6784ceac462a7d6fcb7e9b663e93b9a6fb373b7f43594f9ff68875788e01e \ - --hash=sha256:5d45866ececf4a5fff8742c25722da6d4c9e180daa7b405dc0a2a2790d668c26 \ - --hash=sha256:636ce2dc235046ccd3d8c56a7ad54e99d5c1cd0ef07d9ae847306c91d11b5fec \ - --hash=sha256:6455fc599df93d1f60e1c5c4fe471499f08d190d57eca040c0ea182301321286 \ - --hash=sha256:6bc66318fb7ee012071b2792024564973ecc80e9522842eb4e17743604b5e045 \ - --hash=sha256:7bfe2388663fd18bd8ce7db2c91c7400bf3e1a9e8bd7d63bf7e77d39051b85ec \ - --hash=sha256:7ec335fc998faa4febe75cc5268a9eac0478b3f681602c1f27befaf2a1abe1d8 \ - --hash=sha256:914474c9f1d93080338ace89cb2acee74f4f666fb0424896fcfb8d86058bf17c \ - --hash=sha256:b568f35ad53a7b07ed9b1b2bae09eb15cdd671a5ba5d2c66caee40dbf91c68ca \ - --hash=sha256:cdfd2c361b8a8e5d9499b9082b501c452ade8bbf42aef97ea04854f4a3f43b22 \ - --hash=sha256:d1b96547410f76078eaf66d282ddca2e4baae8964364abb4f4dcdde855cd123a \ - --hash=sha256:d4d61f8b993a7255ba714df3aca52700f8125289f84f704cf80916517c46eb96 \ - --hash=sha256:d7a096646eab884bf8bed965bad63ea327e0d0c38989fc83c5ea7b8a87037bfc \ - --hash=sha256:df46c854f490f81210870e509818b729db4488e1f30f2a1ce1698b2295a878d1 \ - --hash=sha256:e24a828f57e0c337c8d8bb9f6b12f09dfdf0273da25fda9e314f0b684b415a07 \ - --hash=sha256:e4f3149fd5eb9b285d6bfb54d2e5173f6a116fe19172686797c056672689daf6 \ - --hash=sha256:e92a52c166426efbe0d1ec1332ee9119b6d32fc1f0bbfd55d5c1088070e7fc1b \ - --hash=sha256:f87cc2863ef33c709e237d4b5f4502a62a00fab450c9e020892e8e2ede5847f5 \ - --hash=sha256:fd8da6d0124efa2f67d86fa70c851022f87c98e205f0594e1fae044e7119a5a6 +pyrsistent==0.18.1 # via jsonschema -python-dateutil==2.8.2 \ - --hash=sha256:0123cacc1627ae19ddf3c27a5de5bd67ee4586fbdd6440d9748f8abb483d3e86 \ - --hash=sha256:961d03dc3453ebbc59dbdea9e4e11c5651520a876d0f4db161e8674aae935da9 +python-dateutil==2.8.2 # via jupyter-client -python-dotenv==0.20.0 \ - --hash=sha256:b7e3b04a59693c42c36f9ab1cc2acc46fa5df8c78e178fc33a8d4cd05c8d498f \ - --hash=sha256:d92a187be61fe482e4fd675b6d52200e7be63a12b724abbf931a40ce4fa92938 +python-dotenv==0.20.0 # via uvicorn -pyyaml==6.0 \ - --hash=sha256:0283c35a6a9fbf047493e3a0ce8d79ef5030852c51e9d911a27badfde0605293 \ - --hash=sha256:055d937d65826939cb044fc8c9b08889e8c743fdc6a32b33e2390f66013e449b \ - --hash=sha256:07751360502caac1c067a8132d150cf3d61339af5691fe9e87803040dbc5db57 \ - --hash=sha256:0b4624f379dab24d3725ffde76559cff63d9ec94e1736b556dacdfebe5ab6d4b \ - --hash=sha256:0ce82d761c532fe4ec3f87fc45688bdd3a4c1dc5e0b4a19814b9009a29baefd4 \ - --hash=sha256:1e4747bc279b4f613a09eb64bba2ba602d8a6664c6ce6396a4d0cd413a50ce07 \ - --hash=sha256:213c60cd50106436cc818accf5baa1aba61c0189ff610f64f4a3e8c6726218ba \ - --hash=sha256:231710d57adfd809ef5d34183b8ed1eeae3f76459c18fb4a0b373ad56bedcdd9 \ - --hash=sha256:277a0ef2981ca40581a47093e9e2d13b3f1fbbeffae064c1d21bfceba2030287 \ - --hash=sha256:2cd5df3de48857ed0544b34e2d40e9fac445930039f3cfe4bcc592a1f836d513 \ - --hash=sha256:40527857252b61eacd1d9af500c3337ba8deb8fc298940291486c465c8b46ec0 \ - --hash=sha256:473f9edb243cb1935ab5a084eb238d842fb8f404ed2193a915d1784b5a6b5fc0 \ - --hash=sha256:48c346915c114f5fdb3ead70312bd042a953a8ce5c7106d5bfb1a5254e47da92 \ - --hash=sha256:50602afada6d6cbfad699b0c7bb50d5ccffa7e46a3d738092afddc1f9758427f \ - --hash=sha256:68fb519c14306fec9720a2a5b45bc9f0c8d1b9c72adf45c37baedfcd949c35a2 \ - --hash=sha256:77f396e6ef4c73fdc33a9157446466f1cff553d979bd00ecb64385760c6babdc \ - --hash=sha256:819b3830a1543db06c4d4b865e70ded25be52a2e0631ccd2f6a47a2822f2fd7c \ - --hash=sha256:897b80890765f037df3403d22bab41627ca8811ae55e9a722fd0392850ec4d86 \ - --hash=sha256:98c4d36e99714e55cfbaaee6dd5badbc9a1ec339ebfc3b1f52e293aee6bb71a4 \ - --hash=sha256:9df7ed3b3d2e0ecfe09e14741b857df43adb5a3ddadc919a2d94fbdf78fea53c \ - --hash=sha256:9fa600030013c4de8165339db93d182b9431076eb98eb40ee068700c9c813e34 \ - --hash=sha256:a80a78046a72361de73f8f395f1f1e49f956c6be882eed58505a15f3e430962b \ - --hash=sha256:b3d267842bf12586ba6c734f89d1f5b871df0273157918b0ccefa29deb05c21c \ - --hash=sha256:b5b9eccad747aabaaffbc6064800670f0c297e52c12754eb1d976c57e4f74dcb \ - --hash=sha256:c5687b8d43cf58545ade1fe3e055f70eac7a5a1a0bf42824308d868289a95737 \ - --hash=sha256:cba8c411ef271aa037d7357a2bc8f9ee8b58b9965831d9e51baf703280dc73d3 \ - --hash=sha256:d15a181d1ecd0d4270dc32edb46f7cb7733c7c508857278d3d378d14d606db2d \ - --hash=sha256:d4db7c7aef085872ef65a8fd7d6d09a14ae91f691dec3e87ee5ee0539d516f53 \ - --hash=sha256:d4eccecf9adf6fbcc6861a38015c2a64f38b9d94838ac1810a9023a0609e1b78 \ - --hash=sha256:d67d839ede4ed1b28a4e8909735fc992a923cdb84e618544973d7dfc71540803 \ - --hash=sha256:daf496c58a8c52083df09b80c860005194014c3698698d1a57cbcfa182142a3a \ - --hash=sha256:e61ceaab6f49fb8bdfaa0f92c4b57bcfbea54c09277b1b4f7ac376bfb7a7c174 \ - --hash=sha256:f84fbc98b019fef2ee9a1cb3ce93e3187a6df0b2538a651bfb890254ba9f90b5 +pyyaml==6.0 # via # -r requirements/main.in # uvicorn -pyzmq==23.2.0 \ - --hash=sha256:004a431dfa0459123e6f4660d7e3c4ac19217d134ca38bacfffb2e78716fe944 \ - --hash=sha256:057b154471e096e2dda147f7b057041acc303bb7ca4aa24c3b88c6cecdd78717 \ - --hash=sha256:0e08671dc202a1880fa522f921f35ca5925ba30da8bc96228d74a8f0643ead9c \ - --hash=sha256:1b2a21f595f8cc549abd6c8de1fcd34c83441e35fb24b8a59bf161889c62a486 \ - --hash=sha256:21552624ce69e69f7924f413b802b1fb554f4c0497f837810e429faa1cd4f163 \ - --hash=sha256:22ac0243a41798e3eb5d5714b28c2f28e3d10792dffbc8a5fca092f975fdeceb \ - --hash=sha256:2b054525c9f7e240562185bf21671ca16d56bde92e9bd0f822c07dec7626b704 \ - --hash=sha256:30c365e60c39c53f8eea042b37ea28304ffa6558fb7241cf278745095a5757da \ - --hash=sha256:3a4d87342c2737fbb9eee5c33c792db27b36b04957b4e6b7edd73a5b239a2a13 \ - --hash=sha256:420b9abd1a7330687a095373b8280a20cdee04342fbc8ccb3b56d9ec8efd4e62 \ - --hash=sha256:444f7d615d5f686d0ef508b9edfa8a286e6d89f449a1ba37b60ef69d869220a3 \ - --hash=sha256:558f5f636e3e65f261b64925e8b190e8689e334911595394572cc7523879006d \ - --hash=sha256:5592fb4316f895922b1cacb91b04a0fa09d6f6f19bbab4442b4d0a0825177b93 \ - --hash=sha256:59928dfebe93cf1e203e3cb0fd5d5dd384da56b99c8305f2e1b0a933751710f6 \ - --hash=sha256:5cb642e94337b0c76c9c8cb9bfb0f8a78654575847d080d3e1504f312d691fc3 \ - --hash=sha256:5d57542429df6acff02ff022067aa75b677603cee70e3abb9742787545eec966 \ - --hash=sha256:5d92e7cbeab7f70b08cc0f27255b0bb2500afc30f31075bca0b1cb87735d186c \ - --hash=sha256:602835e5672ca9ca1d78e6c148fb28c4f91b748ebc41fbd2f479d8763d58bc9b \ - --hash=sha256:60746a7e8558655420a69441c0a1d47ed225ed3ac355920b96a96d0554ef7e6b \ - --hash=sha256:61b97f624da42813f74977425a3a6144d604ea21cf065616d36ea3a866d92c1c \ - --hash=sha256:693c96ae4d975eb8efa1639670e9b1fac0c3f98b7845b65c0f369141fb4bb21f \ - --hash=sha256:814e5aaf0c3be9991a59066eafb2d6e117aed6b413e3e7e9be45d4e55f5e2748 \ - --hash=sha256:83005d8928f8a5cebcfb33af3bfb84b1ad65d882b899141a331cc5d07d89f093 \ - --hash=sha256:831da96ba3f36cc892f0afbb4fb89b28b61b387261676e55d55a682addbd29f7 \ - --hash=sha256:8355744fdbdeac5cfadfa4f38b82029b5f2b8cab7472a33453a217a7f3a9dce2 \ - --hash=sha256:8496a2a5efd055c61ac2c6a18116c768a25c644b6747dcfde43e91620ab3453c \ - --hash=sha256:859059caf564f0c9398c9005278055ed3d37af4d73de6b1597821193b04ca09b \ - --hash=sha256:8c0f4d6f8c985bab83792be26ff3233940ba42e22237610ac50cbcfc10a5c235 \ - --hash=sha256:8c2d8b69a2bf239ae3d987537bf3fbc2b044a405394cf4c258fc684971dd48b2 \ - --hash=sha256:984b232802eddf9f0be264a4d57a10b3a1fd7319df14ee6fc7b41c6d155a3e6c \ - --hash=sha256:99cedf38eaddf263cf7e2a50e405f12c02cedf6d9df00a0d9c5d7b9417b57f76 \ - --hash=sha256:a3dc339f7bc185d5fd0fd976242a5baf35de404d467e056484def8a4dd95868b \ - --hash=sha256:a51f12a8719aad9dcfb55d456022f16b90abc8dde7d3ca93ce3120b40e3fa169 \ - --hash=sha256:bbabd1df23bf63ae829e81200034c0e433499275a6ed29ca1a912ea7629426d9 \ - --hash=sha256:bcc6953e47bcfc9028ddf9ab2a321a3c51d7cc969db65edec092019bb837959f \ - --hash=sha256:c0a5f987d73fd9b46c3d180891f829afda714ab6bab30a1218724d4a0a63afd8 \ - --hash=sha256:c223a13555444707a0a7ebc6f9ee63053147c8c082bd1a31fd1207a03e8b0500 \ - --hash=sha256:c616893a577e9d6773a3836732fd7e2a729157a108b8fccd31c87512fa01671a \ - --hash=sha256:c882f1d4f96fbd807e92c334251d8ebd159a1ef89059ccd386ddea83fdb91bd8 \ - --hash=sha256:c8dec8a2f3f0bb462e6439df436cd8c7ec37968e90b4209ac621e7fbc0ed3b00 \ - --hash=sha256:c9638e0057e3f1a8b7c5ce33c7575349d9183a033a19b5676ad55096ae36820b \ - --hash=sha256:ce4f71e17fa849de41a06109030d3f6815fcc33338bf98dd0dde6d456d33c929 \ - --hash=sha256:ced12075cdf3c7332ecc1960f77f7439d5ebb8ea20bbd3c34c8299e694f1b0a1 \ - --hash=sha256:d11628212fd731b8986f1561d9bb3f8c38d9c15b330c3d8a88963519fbcd553b \ - --hash=sha256:d1610260cc672975723fcf7705c69a95f3b88802a594c9867781bedd9b13422c \ - --hash=sha256:d4651de7316ec8560afe430fb042c0782ed8ac54c0be43a515944d7c78fddac8 \ - --hash=sha256:da338e2728410d74ddeb1479ec67cfba73311607037455a40f92b6f5c62bf11d \ - --hash=sha256:de727ea906033b30527b4a99498f19aca3f4d1073230a958679a5b726e2784e0 \ - --hash=sha256:e2e2db5c6ef376e97c912733dfc24406f5949474d03e800d5f07b6aca4d870af \ - --hash=sha256:e669913cb2179507628419ec4f0e453e48ce6f924de5884d396f18c31836089c \ - --hash=sha256:eb4a573a8499685d62545e806d8fd143c84ac8b3439f925cd92c8763f0ed9bd7 \ - --hash=sha256:f146648941cadaaaf01254a75651a23c08159d009d36c5af42a7cc200a5e53ec \ - --hash=sha256:f3ff6abde52e702397949054cb5b06c1c75b5d6542f6a2ce029e46f71ffbbbf2 \ - --hash=sha256:f5aa9da520e4bb8cee8189f2f541701405e7690745094ded7a37b425d60527ea \ - --hash=sha256:f5fdb00d65ec44b10cc6b9b6318ef1363b81647a4aa3270ca39565eadb2d1201 \ - --hash=sha256:f685003d836ad0e5d4f08d1e024ee3ac7816eb2f873b2266306eef858f058133 \ - --hash=sha256:fee86542dc4ee8229e023003e3939b4d58cc2453922cf127778b69505fc9064b +pyzmq==23.2.1 # via jupyter-client -redis==4.3.3 \ - --hash=sha256:2f7a57cf4af15cd543c4394bcbe2b9148db2606a37edba755368836e3a1d053e \ - --hash=sha256:f57f8df5d238a8ecf92f499b6b21467bfee6c13d89953c27edf1e2bc673622e7 +redis==4.3.4 # via arq -rfc3986[idna2008]==1.5.0 \ - --hash=sha256:270aaf10d87d0d4e095063c65bf3ddbc6ee3d0b226328ce21e036f946e421835 \ - --hash=sha256:a86d6e1f5b1dc238b218b012df0aa79409667bb209e58da56d0b94704e712a97 +rfc3986[idna2008]==1.5.0 # via httpx -safir[arq,db]==3.2.0 \ - --hash=sha256:3573c6f24043004591e5c070a7b7f2445fdf575e1114f2cecfb34164dc33e5a0 \ - --hash=sha256:c0b51c0d0a0fd05549329122aa6ebb9affdedc56861691cea1cc98939bfd9621 +safir[arq,db]==3.2.0 # via -r requirements/main.in -six==1.16.0 \ - --hash=sha256:1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926 \ - --hash=sha256:8abb2f1d86890a2dfb989f9a77cfcfd3e47c2a354b01111771326f8aa26e0254 +six==1.16.0 # via # bleach # python-dateutil -sniffio==1.2.0 \ - --hash=sha256:471b71698eac1c2112a40ce2752bb2f4a4814c22a54a3eed3676bc0f5ca9f663 \ - --hash=sha256:c4666eecec1d3f50960c6bdf61ab7bc350648da6c126e3cf6898d8cd4ddcd3de +sniffio==1.2.0 # via # anyio # httpcore # httpx -soupsieve==2.3.2.post1 \ - --hash=sha256:3b2503d3c7084a42b1ebd08116e5f81aadfaea95863628c80a3b774a11b7c759 \ - --hash=sha256:fc53893b3da2c33de295667a0e19f078c14bf86544af307354de5fcf12a3f30d +soupsieve==2.3.2.post1 # via beautifulsoup4 -sqlalchemy[asyncio]==1.4.39 \ - --hash=sha256:047ef5ccd8860f6147b8ac6c45a4bc573d4e030267b45d9a1c47b55962ff0e6f \ - --hash=sha256:05a05771617bfa723ba4cef58d5b25ac028b0d68f28f403edebed5b8243b3a87 \ - --hash=sha256:0ec54460475f0c42512895c99c63d90dd2d9cbd0c13491a184182e85074b04c5 \ - --hash=sha256:107df519eb33d7f8e0d0d052128af2f25066c1a0f6b648fd1a9612ab66800b86 \ - --hash=sha256:14ea8ff2d33c48f8e6c3c472111d893b9e356284d1482102da9678195e5a8eac \ - --hash=sha256:1745987ada1890b0e7978abdb22c133eca2e89ab98dc17939042240063e1ef21 \ - --hash=sha256:1962dfee37b7fb17d3d4889bf84c4ea08b1c36707194c578f61e6e06d12ab90f \ - --hash=sha256:20bf65bcce65c538e68d5df27402b39341fabeecf01de7e0e72b9d9836c13c52 \ - --hash=sha256:26146c59576dfe9c546c9f45397a7c7c4a90c25679492ff610a7500afc7d03a6 \ - --hash=sha256:365b75938049ae31cf2176efd3d598213ddb9eb883fbc82086efa019a5f649df \ - --hash=sha256:4770eb3ba69ec5fa41c681a75e53e0e342ac24c1f9220d883458b5596888e43a \ - --hash=sha256:50e7569637e2e02253295527ff34666706dbb2bc5f6c61a5a7f44b9610c9bb09 \ - --hash=sha256:5c2d19bfb33262bf987ef0062345efd0f54c4189c2d95159c72995457bf4a359 \ - --hash=sha256:621f050e72cc7dfd9ad4594ff0abeaad954d6e4a2891545e8f1a53dcdfbef445 \ - --hash=sha256:6d81de54e45f1d756785405c9d06cd17918c2eecc2d4262dc2d276ca612c2f61 \ - --hash=sha256:6f95706da857e6e79b54c33c1214f5467aab10600aa508ddd1239d5df271986e \ - --hash=sha256:752ef2e8dbaa3c5d419f322e3632f00ba6b1c3230f65bc97c2ff5c5c6c08f441 \ - --hash=sha256:7b2785dd2a0c044a36836857ac27310dc7a99166253551ee8f5408930958cc60 \ - --hash=sha256:7f13644b15665f7322f9e0635129e0ef2098409484df67fcd225d954c5861559 \ - --hash=sha256:8194896038753b46b08a0b0ae89a5d80c897fb601dd51e243ed5720f1f155d27 \ - --hash=sha256:864d4f89f054819cb95e93100b7d251e4d114d1c60bc7576db07b046432af280 \ - --hash=sha256:8b773c9974c272aae0fa7e95b576d98d17ee65f69d8644f9b6ffc90ee96b4d19 \ - --hash=sha256:8f901be74f00a13bf375241a778455ee864c2c21c79154aad196b7a994e1144f \ - --hash=sha256:91d2b89bb0c302f89e753bea008936acfa4e18c156fb264fe41eb6bbb2bbcdeb \ - --hash=sha256:b0538b66f959771c56ff996d828081908a6a52a47c5548faed4a3d0a027a5368 \ - --hash=sha256:b30e70f1594ee3c8902978fd71900d7312453922827c4ce0012fa6a8278d6df4 \ - --hash=sha256:b71be98ef6e180217d1797185c75507060a57ab9cd835653e0112db16a710f0d \ - --hash=sha256:c6d00cb9da8d0cbfaba18cad046e94b06de6d4d0ffd9d4095a3ad1838af22528 \ - --hash=sha256:d1f665e50592caf4cad3caed3ed86f93227bffe0680218ccbb293bd5a6734ca8 \ - --hash=sha256:e6e2c8581c6620136b9530137954a8376efffd57fe19802182c7561b0ab48b48 \ - --hash=sha256:e7a7667d928ba6ee361a3176e1bef6847c1062b37726b33505cc84136f657e0d \ - --hash=sha256:ec3985c883d6d217cf2013028afc6e3c82b8907192ba6195d6e49885bfc4b19d \ - --hash=sha256:ede13a472caa85a13abe5095e71676af985d7690eaa8461aeac5c74f6600b6c0 \ - --hash=sha256:f24d4d6ec301688c59b0c4bb1c1c94c5d0bff4ecad33bb8f5d9efdfb8d8bc925 \ - --hash=sha256:f2a42acc01568b9701665e85562bbff78ec3e21981c7d51d56717c22e5d3d58b \ - --hash=sha256:fbc076f79d830ae4c9d49926180a1140b49fa675d0f0d555b44c9a15b29f4c80 +sqlalchemy[asyncio]==1.4.40 # via safir -starlette==0.19.1 \ - --hash=sha256:5a60c5c2d051f3a8eb546136aa0c9399773a689595e099e0877704d5888279bf \ - --hash=sha256:c6d21096774ecb9639acad41b86b7706e52ba3bf1dc13ea4ed9ad593d47e24c7 +starlette==0.19.1 # via # -r requirements/main.in # fastapi # safir -structlog==21.5.0 \ - --hash=sha256:68c4c29c003714fe86834f347cb107452847ba52414390a7ee583472bde00fc9 \ - --hash=sha256:fd7922e195262b337da85c2a91c84be94ccab1f8fd1957bd6986f6904e3761c8 +structlog==22.1.0 # via safir -tinycss2==1.1.1 \ - --hash=sha256:b2e44dd8883c360c35dd0d1b5aad0b610e5156c2cb3b33434634e539ead9d8bf \ - --hash=sha256:fe794ceaadfe3cf3e686b22155d0da5780dd0e273471a51846d0a02bc204fec8 +tinycss2==1.1.1 # via nbconvert -tomli==2.0.1 \ - --hash=sha256:939de3e7a6161af0c887ef91b7d41a53e7c5a1ca976325f429cb46ea9bc30ecc \ - --hash=sha256:de526c12914f0c550d15924c62d72abc48d6fe7364aa87328337a31007fe8a4f +tomli==2.0.1 # via mdformat -tornado==6.1 \ - --hash=sha256:0a00ff4561e2929a2c37ce706cb8233b7907e0cdc22eab98888aca5dd3775feb \ - --hash=sha256:0d321a39c36e5f2c4ff12b4ed58d41390460f798422c4504e09eb5678e09998c \ - --hash=sha256:1e8225a1070cd8eec59a996c43229fe8f95689cb16e552d130b9793cb570a288 \ - --hash=sha256:20241b3cb4f425e971cb0a8e4ffc9b0a861530ae3c52f2b0434e6c1b57e9fd95 \ - --hash=sha256:25ad220258349a12ae87ede08a7b04aca51237721f63b1808d39bdb4b2164558 \ - --hash=sha256:33892118b165401f291070100d6d09359ca74addda679b60390b09f8ef325ffe \ - --hash=sha256:33c6e81d7bd55b468d2e793517c909b139960b6c790a60b7991b9b6b76fb9791 \ - --hash=sha256:3447475585bae2e77ecb832fc0300c3695516a47d46cefa0528181a34c5b9d3d \ - --hash=sha256:34ca2dac9e4d7afb0bed4677512e36a52f09caa6fded70b4e3e1c89dbd92c326 \ - --hash=sha256:3e63498f680547ed24d2c71e6497f24bca791aca2fe116dbc2bd0ac7f191691b \ - --hash=sha256:548430be2740e327b3fe0201abe471f314741efcb0067ec4f2d7dcfb4825f3e4 \ - --hash=sha256:6196a5c39286cc37c024cd78834fb9345e464525d8991c21e908cc046d1cc02c \ - --hash=sha256:61b32d06ae8a036a6607805e6720ef00a3c98207038444ba7fd3d169cd998910 \ - --hash=sha256:6286efab1ed6e74b7028327365cf7346b1d777d63ab30e21a0f4d5b275fc17d5 \ - --hash=sha256:65d98939f1a2e74b58839f8c4dab3b6b3c1ce84972ae712be02845e65391ac7c \ - --hash=sha256:66324e4e1beede9ac79e60f88de548da58b1f8ab4b2f1354d8375774f997e6c0 \ - --hash=sha256:6c77c9937962577a6a76917845d06af6ab9197702a42e1346d8ae2e76b5e3675 \ - --hash=sha256:70dec29e8ac485dbf57481baee40781c63e381bebea080991893cd297742b8fd \ - --hash=sha256:7250a3fa399f08ec9cb3f7b1b987955d17e044f1ade821b32e5f435130250d7f \ - --hash=sha256:748290bf9112b581c525e6e6d3820621ff020ed95af6f17fedef416b27ed564c \ - --hash=sha256:7da13da6f985aab7f6f28debab00c67ff9cbacd588e8477034c0652ac141feea \ - --hash=sha256:8f959b26f2634a091bb42241c3ed8d3cedb506e7c27b8dd5c7b9f745318ddbb6 \ - --hash=sha256:9de9e5188a782be6b1ce866e8a51bc76a0fbaa0e16613823fc38e4fc2556ad05 \ - --hash=sha256:a48900ecea1cbb71b8c71c620dee15b62f85f7c14189bdeee54966fbd9a0c5bd \ - --hash=sha256:b87936fd2c317b6ee08a5741ea06b9d11a6074ef4cc42e031bc6403f82a32575 \ - --hash=sha256:c77da1263aa361938476f04c4b6c8916001b90b2c2fdd92d8d535e1af48fba5a \ - --hash=sha256:cb5ec8eead331e3bb4ce8066cf06d2dfef1bfb1b2a73082dfe8a161301b76e37 \ - --hash=sha256:cc0ee35043162abbf717b7df924597ade8e5395e7b66d18270116f8745ceb795 \ - --hash=sha256:d14d30e7f46a0476efb0deb5b61343b1526f73ebb5ed84f23dc794bdb88f9d9f \ - --hash=sha256:d371e811d6b156d82aa5f9a4e08b58debf97c302a35714f6f45e35139c332e32 \ - --hash=sha256:d3d20ea5782ba63ed13bc2b8c291a053c8d807a8fa927d941bd718468f7b950c \ - --hash=sha256:d3f7594930c423fd9f5d1a76bee85a2c36fd8b4b16921cae7e965f22575e9c01 \ - --hash=sha256:dcef026f608f678c118779cd6591c8af6e9b4155c44e0d1bc0c87c036fb8c8c4 \ - --hash=sha256:e0791ac58d91ac58f694d8d2957884df8e4e2f6687cdf367ef7eb7497f79eaa2 \ - --hash=sha256:e385b637ac3acaae8022e7e47dfa7b83d3620e432e3ecb9a3f7f58f150e50921 \ - --hash=sha256:e519d64089b0876c7b467274468709dadf11e41d65f63bba207e04217f47c085 \ - --hash=sha256:e7229e60ac41a1202444497ddde70a48d33909e484f96eb0da9baf8dc68541df \ - --hash=sha256:ed3ad863b1b40cd1d4bd21e7498329ccaece75db5a5bf58cd3c9f130843e7102 \ - --hash=sha256:f0ba29bafd8e7e22920567ce0d232c26d4d47c8b5cf4ed7b562b5db39fa199c5 \ - --hash=sha256:fa2ba70284fa42c2a5ecb35e322e68823288a4251f9ba9cc77be04ae15eada68 \ - --hash=sha256:fba85b6cd9c39be262fcd23865652920832b61583de2a2ca907dbd8e8a8c81e5 +tornado==6.2 # via jupyter-client -traitlets==5.3.0 \ - --hash=sha256:0bb9f1f9f017aa8ec187d8b1b2a7a6626a2a1d877116baba52a129bfa124f8e2 \ - --hash=sha256:65fa18961659635933100db8ca120ef6220555286949774b9cfc106f941d1c7a +traitlets==5.3.0 # via # jupyter-client # jupyter-core # nbclient # nbconvert # nbformat -typing-extensions==4.2.0 \ - --hash=sha256:6657594ee297170d19f67d55c05852a874e7eb634f4f753dbd667855e07c1708 \ - --hash=sha256:f1c24655a0da0d1b67f07e17a5e6b2a105894e6824b92096378bb3668ef02376 +typing-extensions==4.3.0 # via # aioredis # pydantic -uc-micro-py==1.0.1 \ - --hash=sha256:316cfb8b6862a0f1d03540f0ae6e7b033ff1fa0ddbe60c12cbe0d4cec846a69f \ - --hash=sha256:b7cdf4ea79433043ddfe2c82210208f26f7962c0cfbe3bacb05ee879a7fdb596 +uc-micro-py==1.0.1 # via linkify-it-py -uritemplate==4.1.1 \ - --hash=sha256:4346edfc5c3b79f694bccd6d6099a322bbeb628dbf2cd86eea55a456ce5124f0 \ - --hash=sha256:830c08b8d99bdd312ea4ead05994a38e8936266f84b9a7878232db50b044e02e +uritemplate==4.1.1 # via gidgethub -uvicorn[standard]==0.18.1 \ - --hash=sha256:013c4ea0787cc2dc456ef4368e18c01982e6be57903e4d3183218e543eb889b7 \ - --hash=sha256:35703e6518105cfe53f16a5a9435db3e2e227d0784f1fd8fbc1214b1fdc108df +uvicorn[standard]==0.18.2 # via -r requirements/main.in -uvloop==0.16.0 \ - --hash=sha256:04ff57aa137230d8cc968f03481176041ae789308b4d5079118331ab01112450 \ - --hash=sha256:089b4834fd299d82d83a25e3335372f12117a7d38525217c2258e9b9f4578897 \ - --hash=sha256:1e5f2e2ff51aefe6c19ee98af12b4ae61f5be456cd24396953244a30880ad861 \ - --hash=sha256:30ba9dcbd0965f5c812b7c2112a1ddf60cf904c1c160f398e7eed3a6b82dcd9c \ - --hash=sha256:3a19828c4f15687675ea912cc28bbcb48e9bb907c801873bd1519b96b04fb805 \ - --hash=sha256:6224f1401025b748ffecb7a6e2652b17768f30b1a6a3f7b44660e5b5b690b12d \ - --hash=sha256:647e481940379eebd314c00440314c81ea547aa636056f554d491e40503c8464 \ - --hash=sha256:6ccd57ae8db17d677e9e06192e9c9ec4bd2066b77790f9aa7dede2cc4008ee8f \ - --hash=sha256:772206116b9b57cd625c8a88f2413df2fcfd0b496eb188b82a43bed7af2c2ec9 \ - --hash=sha256:8e0d26fa5875d43ddbb0d9d79a447d2ace4180d9e3239788208527c4784f7cab \ - --hash=sha256:98d117332cc9e5ea8dfdc2b28b0a23f60370d02e1395f88f40d1effd2cb86c4f \ - --hash=sha256:b572256409f194521a9895aef274cea88731d14732343da3ecdb175228881638 \ - --hash=sha256:bd53f7f5db562f37cd64a3af5012df8cac2c464c97e732ed556800129505bd64 \ - --hash=sha256:bd8f42ea1ea8f4e84d265769089964ddda95eb2bb38b5cbe26712b0616c3edee \ - --hash=sha256:e814ac2c6f9daf4c36eb8e85266859f42174a4ff0d71b99405ed559257750382 \ - --hash=sha256:f74bc20c7b67d1c27c72601c78cf95be99d5c2cdd4514502b4f3eb0933ff1228 +uvloop==0.16.0 # via uvicorn -watchfiles==0.15.0 \ - --hash=sha256:56abed43e645d1f2d6def83e35999cc5758b051aff54ca1065cbfcaea15b3389 \ - --hash=sha256:65ca99a94fcab29d00aa406526eb29cf198c0661854d59a315596064fed02141 \ - --hash=sha256:67d4c66e46a564059df4aeedab78f09cba0b697bf36cc77566b0a7015dfb7f5d \ - --hash=sha256:6e0e8829d32b05151e6009570449f44f891e05f518e495d25f960e0d0b2d0064 \ - --hash=sha256:715733c2ac9da67b2790788657ff6f8b3797eb31565bfc592289b523ae907ca2 \ - --hash=sha256:7b81c6e404b2aa62482a719eb778e4a16d01728302dce1f1512c1e5354a73fda \ - --hash=sha256:82238d08d8a49f1a1ba254278cd4329a154f6100b028393059722ebeddd2ff3d \ - --hash=sha256:955e8f840e1996a8a41be57de4c03af7b1515a685b7fb6abe222f859e413a907 \ - --hash=sha256:cab62510f990d195986302aa6a48ed636d685b099927049120d520c96069fa49 \ - --hash=sha256:d1f9de6b776b3aff17898a4cf5ac5a2d0a16212ea7aad2bbe0ef6aa3e79a96af \ - --hash=sha256:d4f45acd1143db6d3ee77a4ff12d3239bc8083108133e6174e9dcce59c1f9902 \ - --hash=sha256:f7f71012e096e11256fae3b37617a9777980f281e18deb2e789e85cd5b113935 +watchfiles==0.16.1 # via uvicorn -webencodings==0.5.1 \ - --hash=sha256:a0af1213f3c2226497a97e2b3aa01a7e4bee4f403f95be16fc9acd2947514a78 \ - --hash=sha256:b36a1c245f2d304965eb4e0a82848379241dc04b865afcc4aab16748587e1923 +webencodings==0.5.1 # via # bleach # tinycss2 -websockets==10.3 \ - --hash=sha256:07cdc0a5b2549bcfbadb585ad8471ebdc7bdf91e32e34ae3889001c1c106a6af \ - --hash=sha256:210aad7fdd381c52e58777560860c7e6110b6174488ef1d4b681c08b68bf7f8c \ - --hash=sha256:28dd20b938a57c3124028680dc1600c197294da5db4292c76a0b48efb3ed7f76 \ - --hash=sha256:2f94fa3ae454a63ea3a19f73b95deeebc9f02ba2d5617ca16f0bbdae375cda47 \ - --hash=sha256:31564a67c3e4005f27815634343df688b25705cccb22bc1db621c781ddc64c69 \ - --hash=sha256:347974105bbd4ea068106ec65e8e8ebd86f28c19e529d115d89bd8cc5cda3079 \ - --hash=sha256:379e03422178436af4f3abe0aa8f401aa77ae2487843738542a75faf44a31f0c \ - --hash=sha256:3eda1cb7e9da1b22588cefff09f0951771d6ee9fa8dbe66f5ae04cc5f26b2b55 \ - --hash=sha256:51695d3b199cd03098ae5b42833006a0f43dc5418d3102972addc593a783bc02 \ - --hash=sha256:54c000abeaff6d8771a4e2cef40900919908ea7b6b6a30eae72752607c6db559 \ - --hash=sha256:5b936bf552e4f6357f5727579072ff1e1324717902127ffe60c92d29b67b7be3 \ - --hash=sha256:6075fd24df23133c1b078e08a9b04a3bc40b31a8def4ee0b9f2c8865acce913e \ - --hash=sha256:661f641b44ed315556a2fa630239adfd77bd1b11cb0b9d96ed8ad90b0b1e4978 \ - --hash=sha256:6ea6b300a6bdd782e49922d690e11c3669828fe36fc2471408c58b93b5535a98 \ - --hash=sha256:6ed1d6f791eabfd9808afea1e068f5e59418e55721db8b7f3bfc39dc831c42ae \ - --hash=sha256:7934e055fd5cd9dee60f11d16c8d79c4567315824bacb1246d0208a47eca9755 \ - --hash=sha256:7ab36e17af592eec5747c68ef2722a74c1a4a70f3772bc661079baf4ae30e40d \ - --hash=sha256:7f6d96fdb0975044fdd7953b35d003b03f9e2bcf85f2d2cf86285ece53e9f991 \ - --hash=sha256:83e5ca0d5b743cde3d29fda74ccab37bdd0911f25bd4cdf09ff8b51b7b4f2fa1 \ - --hash=sha256:85506b3328a9e083cc0a0fb3ba27e33c8db78341b3eb12eb72e8afd166c36680 \ - --hash=sha256:8af75085b4bc0b5c40c4a3c0e113fa95e84c60f4ed6786cbb675aeb1ee128247 \ - --hash=sha256:8b1359aba0ff810d5830d5ab8e2c4a02bebf98a60aa0124fb29aa78cfdb8031f \ - --hash=sha256:8fbd7d77f8aba46d43245e86dd91a8970eac4fb74c473f8e30e9c07581f852b2 \ - --hash=sha256:907e8247480f287aa9bbc9391bd6de23c906d48af54c8c421df84655eef66af7 \ - --hash=sha256:93d5ea0b5da8d66d868b32c614d2b52d14304444e39e13a59566d4acb8d6e2e4 \ - --hash=sha256:97bc9d41e69a7521a358f9b8e44871f6cdeb42af31815c17aed36372d4eec667 \ - --hash=sha256:994cdb1942a7a4c2e10098d9162948c9e7b235df755de91ca33f6e0481366fdb \ - --hash=sha256:a141de3d5a92188234afa61653ed0bbd2dde46ad47b15c3042ffb89548e77094 \ - --hash=sha256:a1e15b230c3613e8ea82c9fc6941b2093e8eb939dd794c02754d33980ba81e36 \ - --hash=sha256:aad5e300ab32036eb3fdc350ad30877210e2f51bceaca83fb7fef4d2b6c72b79 \ - --hash=sha256:b529fdfa881b69fe563dbd98acce84f3e5a67df13de415e143ef053ff006d500 \ - --hash=sha256:b9c77f0d1436ea4b4dc089ed8335fa141e6a251a92f75f675056dac4ab47a71e \ - --hash=sha256:bb621ec2dbbbe8df78a27dbd9dd7919f9b7d32a73fafcb4d9252fc4637343582 \ - --hash=sha256:c7250848ce69559756ad0086a37b82c986cd33c2d344ab87fea596c5ac6d9442 \ - --hash=sha256:c8d1d14aa0f600b5be363077b621b1b4d1eb3fbf90af83f9281cda668e6ff7fd \ - --hash=sha256:d1655a6fc7aecd333b079d00fb3c8132d18988e47f19740c69303bf02e9883c6 \ - --hash=sha256:d6353ba89cfc657a3f5beabb3b69be226adbb5c6c7a66398e17809b0ce3c4731 \ - --hash=sha256:da4377904a3379f0c1b75a965fff23b28315bcd516d27f99a803720dfebd94d4 \ - --hash=sha256:e49ea4c1a9543d2bd8a747ff24411509c29e4bdcde05b5b0895e2120cb1a761d \ - --hash=sha256:e4e08305bfd76ba8edab08dcc6496f40674f44eb9d5e23153efa0a35750337e8 \ - --hash=sha256:e6fa05a680e35d0fcc1470cb070b10e6fe247af54768f488ed93542e71339d6f \ - --hash=sha256:e7e6f2d6fd48422071cc8a6f8542016f350b79cc782752de531577d35e9bd677 \ - --hash=sha256:e904c0381c014b914136c492c8fa711ca4cced4e9b3d110e5e7d436d0fc289e8 \ - --hash=sha256:ec2b0ab7edc8cd4b0eb428b38ed89079bdc20c6bdb5f889d353011038caac2f9 \ - --hash=sha256:ef5ce841e102278c1c2e98f043db99d6755b1c58bde475516aef3a008ed7f28e \ - --hash=sha256:f351c7d7d92f67c0609329ab2735eee0426a03022771b00102816a72715bb00b \ - --hash=sha256:fab7c640815812ed5f10fbee7abbf58788d602046b7bb3af9b1ac753a6d5e916 \ - --hash=sha256:fc06cc8073c8e87072138ba1e431300e2d408f054b27047d047b549455066ff4 +websockets==10.3 # via uvicorn -wrapt==1.14.1 \ - --hash=sha256:00b6d4ea20a906c0ca56d84f93065b398ab74b927a7a3dbd470f6fc503f95dc3 \ - --hash=sha256:01c205616a89d09827986bc4e859bcabd64f5a0662a7fe95e0d359424e0e071b \ - --hash=sha256:02b41b633c6261feff8ddd8d11c711df6842aba629fdd3da10249a53211a72c4 \ - --hash=sha256:07f7a7d0f388028b2df1d916e94bbb40624c59b48ecc6cbc232546706fac74c2 \ - --hash=sha256:11871514607b15cfeb87c547a49bca19fde402f32e2b1c24a632506c0a756656 \ - --hash=sha256:1b376b3f4896e7930f1f772ac4b064ac12598d1c38d04907e696cc4d794b43d3 \ - --hash=sha256:21ac0156c4b089b330b7666db40feee30a5d52634cc4560e1905d6529a3897ff \ - --hash=sha256:257fd78c513e0fb5cdbe058c27a0624c9884e735bbd131935fd49e9fe719d310 \ - --hash=sha256:2b39d38039a1fdad98c87279b48bc5dce2c0ca0d73483b12cb72aa9609278e8a \ - --hash=sha256:2cf71233a0ed05ccdabe209c606fe0bac7379fdcf687f39b944420d2a09fdb57 \ - --hash=sha256:2fe803deacd09a233e4762a1adcea5db5d31e6be577a43352936179d14d90069 \ - --hash=sha256:3232822c7d98d23895ccc443bbdf57c7412c5a65996c30442ebe6ed3df335383 \ - --hash=sha256:34aa51c45f28ba7f12accd624225e2b1e5a3a45206aa191f6f9aac931d9d56fe \ - --hash=sha256:36f582d0c6bc99d5f39cd3ac2a9062e57f3cf606ade29a0a0d6b323462f4dd87 \ - --hash=sha256:380a85cf89e0e69b7cfbe2ea9f765f004ff419f34194018a6827ac0e3edfed4d \ - --hash=sha256:40e7bc81c9e2b2734ea4bc1aceb8a8f0ceaac7c5299bc5d69e37c44d9081d43b \ - --hash=sha256:43ca3bbbe97af00f49efb06e352eae40434ca9d915906f77def219b88e85d907 \ - --hash=sha256:4fcc4649dc762cddacd193e6b55bc02edca674067f5f98166d7713b193932b7f \ - --hash=sha256:5a0f54ce2c092aaf439813735584b9537cad479575a09892b8352fea5e988dc0 \ - --hash=sha256:5a9a0d155deafd9448baff28c08e150d9b24ff010e899311ddd63c45c2445e28 \ - --hash=sha256:5b02d65b9ccf0ef6c34cba6cf5bf2aab1bb2f49c6090bafeecc9cd81ad4ea1c1 \ - --hash=sha256:60db23fa423575eeb65ea430cee741acb7c26a1365d103f7b0f6ec412b893853 \ - --hash=sha256:642c2e7a804fcf18c222e1060df25fc210b9c58db7c91416fb055897fc27e8cc \ - --hash=sha256:6a9a25751acb379b466ff6be78a315e2b439d4c94c1e99cb7266d40a537995d3 \ - --hash=sha256:6b1a564e6cb69922c7fe3a678b9f9a3c54e72b469875aa8018f18b4d1dd1adf3 \ - --hash=sha256:6d323e1554b3d22cfc03cd3243b5bb815a51f5249fdcbb86fda4bf62bab9e164 \ - --hash=sha256:6e743de5e9c3d1b7185870f480587b75b1cb604832e380d64f9504a0535912d1 \ - --hash=sha256:709fe01086a55cf79d20f741f39325018f4df051ef39fe921b1ebe780a66184c \ - --hash=sha256:7b7c050ae976e286906dd3f26009e117eb000fb2cf3533398c5ad9ccc86867b1 \ - --hash=sha256:7d2872609603cb35ca513d7404a94d6d608fc13211563571117046c9d2bcc3d7 \ - --hash=sha256:7ef58fb89674095bfc57c4069e95d7a31cfdc0939e2a579882ac7d55aadfd2a1 \ - --hash=sha256:80bb5c256f1415f747011dc3604b59bc1f91c6e7150bd7db03b19170ee06b320 \ - --hash=sha256:81b19725065dcb43df02b37e03278c011a09e49757287dca60c5aecdd5a0b8ed \ - --hash=sha256:833b58d5d0b7e5b9832869f039203389ac7cbf01765639c7309fd50ef619e0b1 \ - --hash=sha256:88bd7b6bd70a5b6803c1abf6bca012f7ed963e58c68d76ee20b9d751c74a3248 \ - --hash=sha256:8ad85f7f4e20964db4daadcab70b47ab05c7c1cf2a7c1e51087bfaa83831854c \ - --hash=sha256:8c0ce1e99116d5ab21355d8ebe53d9460366704ea38ae4d9f6933188f327b456 \ - --hash=sha256:8d649d616e5c6a678b26d15ece345354f7c2286acd6db868e65fcc5ff7c24a77 \ - --hash=sha256:903500616422a40a98a5a3c4ff4ed9d0066f3b4c951fa286018ecdf0750194ef \ - --hash=sha256:9736af4641846491aedb3c3f56b9bc5568d92b0692303b5a305301a95dfd38b1 \ - --hash=sha256:988635d122aaf2bdcef9e795435662bcd65b02f4f4c1ae37fbee7401c440b3a7 \ - --hash=sha256:9cca3c2cdadb362116235fdbd411735de4328c61425b0aa9f872fd76d02c4e86 \ - --hash=sha256:9e0fd32e0148dd5dea6af5fee42beb949098564cc23211a88d799e434255a1f4 \ - --hash=sha256:9f3e6f9e05148ff90002b884fbc2a86bd303ae847e472f44ecc06c2cd2fcdb2d \ - --hash=sha256:a85d2b46be66a71bedde836d9e41859879cc54a2a04fad1191eb50c2066f6e9d \ - --hash=sha256:a9a52172be0b5aae932bef82a79ec0a0ce87288c7d132946d645eba03f0ad8a8 \ - --hash=sha256:aa31fdcc33fef9eb2552cbcbfee7773d5a6792c137b359e82879c101e98584c5 \ - --hash=sha256:b014c23646a467558be7da3d6b9fa409b2c567d2110599b7cf9a0c5992b3b471 \ - --hash=sha256:b21bb4c09ffabfa0e85e3a6b623e19b80e7acd709b9f91452b8297ace2a8ab00 \ - --hash=sha256:b5901a312f4d14c59918c221323068fad0540e34324925c8475263841dbdfe68 \ - --hash=sha256:b9b7a708dd92306328117d8c4b62e2194d00c365f18eff11a9b53c6f923b01e3 \ - --hash=sha256:d1967f46ea8f2db647c786e78d8cc7e4313dbd1b0aca360592d8027b8508e24d \ - --hash=sha256:d52a25136894c63de15a35bc0bdc5adb4b0e173b9c0d07a2be9d3ca64a332735 \ - --hash=sha256:d77c85fedff92cf788face9bfa3ebaa364448ebb1d765302e9af11bf449ca36d \ - --hash=sha256:d79d7d5dc8a32b7093e81e97dad755127ff77bcc899e845f41bf71747af0c569 \ - --hash=sha256:dbcda74c67263139358f4d188ae5faae95c30929281bc6866d00573783c422b7 \ - --hash=sha256:ddaea91abf8b0d13443f6dac52e89051a5063c7d014710dcb4d4abb2ff811a59 \ - --hash=sha256:dee0ce50c6a2dd9056c20db781e9c1cfd33e77d2d569f5d1d9321c641bb903d5 \ - --hash=sha256:dee60e1de1898bde3b238f18340eec6148986da0455d8ba7848d50470a7a32fb \ - --hash=sha256:e2f83e18fe2f4c9e7db597e988f72712c0c3676d337d8b101f6758107c42425b \ - --hash=sha256:e3fb1677c720409d5f671e39bac6c9e0e422584e5f518bfd50aa4cbbea02433f \ - --hash=sha256:ee2b1b1769f6707a8a445162ea16dddf74285c3964f605877a20e38545c3c462 \ - --hash=sha256:ee6acae74a2b91865910eef5e7de37dc6895ad96fa23603d1d27ea69df545015 \ - --hash=sha256:ef3f72c9666bba2bab70d2a8b79f2c6d2c1a42a7f7e2b0ec83bb2f9e383950af +wrapt==1.14.1 # via deprecated -# WARNING: The following packages were not pinned, but pip requires them to be -# pinned when the requirements file includes hashes. Consider using the --allow-unsafe flag. -# setuptools +# The following packages are considered to be unsafe in a requirements file: +setuptools==65.0.0 + # via gunicorn diff --git a/src/timessquare/dependencies/requestcontext.py b/src/timessquare/dependencies/requestcontext.py index c979296b..b06a7c23 100644 --- a/src/timessquare/dependencies/requestcontext.py +++ b/src/timessquare/dependencies/requestcontext.py @@ -14,6 +14,7 @@ from timessquare.config import Config, config from timessquare.dependencies.redis import redis_dependency +from timessquare.services.github.repo import GitHubRepoService from timessquare.services.page import PageService from timessquare.storage.nbhtmlcache import NbHtmlCacheStore from timessquare.storage.noteburstjobstore import NoteburstJobStore @@ -55,6 +56,7 @@ class RequestContext: @property def page_service(self) -> PageService: + """An instance of the page service.""" return PageService( page_store=PageStore(self.session), html_cache=NbHtmlCacheStore(self.redis), @@ -63,6 +65,20 @@ def page_service(self) -> PageService: logger=self.logger, ) + async def create_github_repo_service( + self, owner: str, repo: str + ) -> GitHubRepoService: + """An instance of the GitHub repository service for manging + GitHub-backed pages and accessing GitHub's API. + """ + return await GitHubRepoService.create_for_repo( + owner=owner, + repo=repo, + http_client=self.http_client, + page_service=self.page_service, + logger=self.logger, + ) + def get_request_username(self) -> Optional[str]: """Get the username who made the request diff --git a/src/timessquare/domain/githubapi.py b/src/timessquare/domain/githubapi.py index e7dd5849..855edd8f 100644 --- a/src/timessquare/domain/githubapi.py +++ b/src/timessquare/domain/githubapi.py @@ -4,7 +4,7 @@ from base64 import b64decode from enum import Enum -from typing import Optional +from typing import List, Optional from pydantic import BaseModel, Field, HttpUrl @@ -20,6 +20,23 @@ class GitHubRepoOwnerModel(BaseModel): ) +class GitHubUserModel(BaseModel): + """A Pydantic model for the "user" field found in GitHub API resources. + + This contains brief (public) info about a user. + """ + + login: str = Field(title="Login name", description="GitHub username") + + html_url: HttpUrl = Field(description="Homepage for the user on GitHub") + + url: HttpUrl = Field( + description="URL for the user's resource in the GitHub API" + ) + + avatar_url: HttpUrl = Field(description="URL to the user's avatar") + + class GitHubRepositoryModel(BaseModel): """A Pydantic model for the "repository" field, often found in webhook payloads. @@ -77,6 +94,16 @@ class GitHubRepositoryModel(BaseModel): ) +class GitHubPullState(str, Enum): + """The state of a GitHub PR. + + https://docs.github.com/en/rest/pulls/pulls#get-a-pull-request + """ + + open = "open" + closed = "closed" + + class GitHubPullRequestModel(BaseModel): """A Pydantic model for a GitHub Pull Request. @@ -92,7 +119,15 @@ class GitHubPullRequestModel(BaseModel): title: str = Field(title="Title") - # TODO a lot more data is available. Expand this model as needed. + state: GitHubPullState = Field( + description="Whether the PR is opened or closed" + ) + + draft: bool = Field(description="True if the PR is a draft") + + merged: bool = Field(description="True if the PR is merged") + + user: GitHubUserModel = Field(description="The user that opened the PR") class GitHubBranchCommitModel(BaseModel): @@ -226,6 +261,28 @@ class GitHubCheckSuiteId(BaseModel): id: str = Field(description="Check suite ID") +class GitHubCheckRunOutput(BaseModel): + """Check run output report.""" + + title: Optional[str] = Field(None, description="Title of the report") + + summary: Optional[str] = Field( + None, description="Summary information (markdown formatted" + ) + + text: Optional[str] = Field(None, description="Extended report (markdown)") + + +class GitHubCheckRunPrInfoModel(BaseModel): + """A Pydantic model of the "pull_requsts[]" items in a check run + GitHub API model. + + https://docs.github.com/en/rest/checks/runs#get-a-check-run + """ + + url: HttpUrl = Field(description="GitHub API URL for this pull request") + + class GitHubCheckRunModel(BaseModel): """A Pydantic model for the "check_run" field in a check_run webhook payload (`GitHubCheckRunPayloadModel`). @@ -257,3 +314,11 @@ class GitHubCheckRunModel(BaseModel): html_url: HttpUrl = Field(description="URL of the check run webpage.") check_suite: GitHubCheckSuiteId + + output: Optional[GitHubCheckRunOutput] = Field( + None, title="Output", description="Check run output, if available." + ) + + pull_requests: List[GitHubCheckRunPrInfoModel] = Field( + default_factory=list + ) diff --git a/src/timessquare/domain/githubcheckrun.py b/src/timessquare/domain/githubcheckrun.py index 903e9310..82327eb1 100644 --- a/src/timessquare/domain/githubcheckrun.py +++ b/src/timessquare/domain/githubcheckrun.py @@ -2,6 +2,7 @@ from __future__ import annotations +import os.path from abc import ABCMeta, abstractproperty from dataclasses import dataclass from typing import Any, Dict, List, Optional, Sequence, Union @@ -9,6 +10,8 @@ from gidgethub.httpx import GitHubAPI from pydantic import ValidationError +from timessquare.config import config + from .githubapi import ( GitHubBlobModel, GitHubCheckRunAnnotationLevel, @@ -99,8 +102,11 @@ class GitHubCheck(metaclass=ABCMeta): share the same external ID. """ - def __init__(self, check_run: GitHubCheckRunModel) -> None: + def __init__( + self, *, check_run: GitHubCheckRunModel, repo: GitHubRepositoryModel + ) -> None: self.check_run = check_run + self.repo = repo self.annotations: List[Annotation] = [] @property @@ -125,6 +131,25 @@ def text(self) -> str: """The text body of the check's message.""" raise NotImplementedError + @property + def squareone_pr_url_root(self) -> str: + """Root URL for this check run in Squareone. + + Formatted as ``{host}/times-square/github-pr/{owner}/{repo}/{commit}`` + """ + if config.environment_url.endswith("/"): + squareone_url = str(config.environment_url) + else: + squareone_url = f"{str(config.environment_url)}/" + return ( + f"{squareone_url}/times-square/github-pr/{self.repo.owner.login}" + f"/{self.repo.name}/{self.check_run.head_sha}" + ) + + def get_preview_url(self, notebook_path: str) -> str: + display_path = os.path.splitext(notebook_path)[0] + return f"{self.squareone_pr_url_root}/{display_path}" + def export_truncated_annotations(self) -> List[Dict[str, Any]]: """Export the first 50 annotations to objects serializable to GitHub. @@ -155,6 +180,7 @@ async def submit_conclusion( data={ "status": GitHubCheckRunStatus.completed, "conclusion": self.conclusion, + "details_url": self.squareone_pr_url_root, "output": { "title": self.title, "summary": self.summary, @@ -175,14 +201,16 @@ class GitHubConfigsCheck(GitHubCheck): share the same external ID. """ - def __init__(self, check_run: GitHubCheckRunModel) -> None: + def __init__( + self, check_run: GitHubCheckRunModel, repo: GitHubRepositoryModel + ) -> None: self.sidecar_files_checked: List[str] = [] # Optional caching for data reuse self.checkout: Optional[GitHubRepositoryCheckout] = None self.tree: Optional[RecursiveGitTreeModel] = None - super().__init__(check_run=check_run) + super().__init__(check_run=check_run, repo=repo) @classmethod async def create_check_run_and_validate( @@ -225,7 +253,7 @@ async def validate_repo( repository containing Times Square notebooks given a check run already registered with GitHub. """ - check = cls(check_run) + check = cls(check_run, repo) await check.submit_in_progress(github_client) try: @@ -365,9 +393,11 @@ class NotebookExecutionsCheck(GitHubCheck): share the same external ID. """ - def __init__(self, check_run: GitHubCheckRunModel) -> None: + def __init__( + self, check_run: GitHubCheckRunModel, repo: GitHubRepositoryModel + ) -> None: self.notebook_paths_checked: List[str] = [] - super().__init__(check_run=check_run) + super().__init__(check_run=check_run, repo=repo) def report_noteburst_failure( self, page_execution: PageExecutionInfo @@ -432,10 +462,12 @@ def text(self) -> str: notebook_paths = list(set(self.notebook_paths_checked)) notebook_paths.sort() for notebook_path in notebook_paths: + preview_url = self.get_preview_url(notebook_path) + linked_notebook = f"[{notebook_path}]({preview_url})" if self._is_file_ok(notebook_path): - text = f"{text}| {notebook_path} | ✅ |\n" + text = f"{text}| {linked_notebook} | ✅ |\n" else: - text = f"{text}| {notebook_path} | ❌ |\n" + text = f"{text}| {linked_notebook} | ❌ |\n" return text diff --git a/src/timessquare/domain/githubtree.py b/src/timessquare/domain/githubtree.py index 0aa604e9..bc6fefe5 100644 --- a/src/timessquare/domain/githubtree.py +++ b/src/timessquare/domain/githubtree.py @@ -2,11 +2,9 @@ from __future__ import annotations -from dataclasses import dataclass +from dataclasses import dataclass, field from enum import Enum -from typing import List - -from pydantic import BaseModel, Field +from typing import List, Optional class GitHubNodeType(str, Enum): @@ -25,103 +23,222 @@ class GitHubNodeType(str, Enum): """Page inside a GitHub repository.""" -class GitHubNode(BaseModel): +@dataclass +class GitHubNode: """A node in the GitHub contents tree.""" - node_type: GitHubNodeType = Field( - title="Node type", - description=( - "Indicates whether this a GitHub owner (user or organization), " - "repository, directory in a repositiory, or a page itself." - ), - ) - - title: str = Field(title="Display title") - - path: str = Field( - title="Hierarchical path", - description=( - "The page is POSIX-path formatted without a preceeding or " - "trailing slash. The first path element is always the owner, " - "followed by the repository name, directory, and page name as " - "necessary." - ), - example="lsst-sqre/times-square-demo/matplotlib/gaussian2d", - ) - - contents: List[GitHubNode] = Field( - title="Nodes contained within this node.", - description="For 'page' nodes, this is an empty list.", - default_factory=list, - ) + node_type: GitHubNodeType + """The type of path object in the node.""" + + path_segments: List[str] + """The segments in the path (i.e. the name of this page, or + this directory) up to this point. + + Path segments are always ordered: + + 1. owner + 2. repo + 3. directory or directories, as necessary + 4. page file stem (i.e. filename without extension) + """ + + title: str + """Presentational title for this node.""" + + github_commit: Optional[str] = None + """The commit SHA if this tree is for a specific commit (a PR preview) + instead of corresponding to the default branch of the repository. + """ + + contents: List[GitHubNode] = field(default_factory=list) @property - def path_segments(self) -> List[str]: - return self.path.split("/") + def squareone_path(self) -> str: + """Path to the node in Squareone. + + - If `github_commit` is None, the URL path is relative to + ``/times-square/github/`` (not included. + - If the node contains a non-None `github_commit`, + the path is relative to ``/times-square/github-pr/`` (not included). + """ + if self.github_commit is None: + # a path corresponding to the default branch (i.e. the "live view + # github-backed pages) + return "/".join(self.path_segments) + else: + # a path corresponding to the commit view of a repository, + # for PR previews. + # formatted as owner/repo/commit/dirname/filestem + return ( + f"{self.path_segments[0]}/{self.path_segments[1]}/" + f"{self.github_commit}/{'/'.join(self.path_segments[2:])}" + ) + + @classmethod + def create_with_repo_root( + cls, results: List[GitHubTreeQueryResult] + ) -> GitHubNode: + """Create a tree with this root-node being the first repository in + the results. + + This is appropriate for creating trees for GitHub PR previews. + """ + root_path_segment = [results[0].github_owner, results[0].github_repo] + root = cls( + node_type=GitHubNodeType.repo, + path_segments=root_path_segment, + github_commit=results[0].github_commit, + title=results[0].github_repo, + contents=[], + ) + for result in results: + root.insert_node(result) + return root - def insert_input(self, tree_input: GitHubTreeInput) -> None: - n = len(self.path_segments) - if n == len(tree_input.path_segments): - # input is a direct child of this node - self.contents.append(tree_input.to_node()) + @classmethod + def create_with_owner_root( + cls, results: List[GitHubTreeQueryResult] + ) -> GitHubNode: + """Create a tree with the root-node being the first GitHub owner in + the results. + + This is appropriate for creating trees for the default branch views + of GitHub-backed pages. + """ + root_path_segment = [results[0].github_owner] + root = cls( + node_type=GitHubNodeType.owner, + path_segments=root_path_segment, + title=results[0].github_owner, + github_commit=results[0].github_commit, + contents=[], + ) + for result in results: + root.insert_node(result) + return root + + def insert_node(self, result: GitHubTreeQueryResult) -> None: + """Insert an SQL page result as a child (direct, or not) of the + current node. + """ + if self.node_type == GitHubNodeType.owner: + self._insert_node_from_owner(result) + elif self.node_type == GitHubNodeType.repo: + self._insert_node_from_repo(result) + elif self.node_type == GitHubNodeType.directory: + self._insert_node_from_directory(result) + else: + raise ValueError("Cannot insert a node into a page") + + def _insert_node_from_owner(self, result: GitHubTreeQueryResult) -> None: + # Try to insert node into an existing repository node + for repo_node in self.contents: + if repo_node.path_segments[1] == result.github_repo: + repo_node.insert_node(result) + return + + # Create a repo node since one doesn't already exist + repo_node = GitHubNode( + node_type=GitHubNodeType.repo, + path_segments=result.path_segments[:2], + title=result.path_segments[1], + github_commit=result.github_commit, + contents=[], + ) + self.contents.append(repo_node) + repo_node.insert_node(result) + + def _insert_node_from_repo(self, result: GitHubTreeQueryResult) -> None: + if len(result.path_segments) == 3: + # direct child of this node + self.contents.append( + GitHubNode( + node_type=GitHubNodeType.page, + path_segments=result.path_segments, + title=result.title, + github_commit=result.github_commit, + contents=[], + ) + ) + return else: - # find child that contains input - for child in self.contents: - if (len(child.path_segments) >= n + 1) and ( - child.path_segments[n] == tree_input.path_segments[n] + # Find existing directory containing this page + for child_node in self.contents: + n = len(child_node.path_segments) + if ( + child_node.node_type == GitHubNodeType.directory + and child_node.path_segments == result.path_segments[:n] ): - child.insert_input(tree_input) + child_node.insert_node(result) return - # Create a new child node because the necessary one doesn't - # exist - if n == 1: - node_type = GitHubNodeType.repo - else: - node_type = GitHubNodeType.directory - child = GitHubNode( - node_type=node_type, - title=tree_input.path_segments[n], - path="/".join(tree_input.path_segments[: n + 1]), + # Create a directory node + dir_node = GitHubNode( + node_type=GitHubNodeType.directory, + path_segments=result.path_segments[ + : len(self.path_segments) + 1 + ], + title=result.path_segments[len(self.path_segments)], + github_commit=result.github_commit, contents=[], ) - child.insert_input(tree_input) - self.contents.append(child) + self.contents.append(dir_node) + dir_node.insert_node(result) + + def _insert_node_from_directory( + self, result: GitHubTreeQueryResult + ) -> None: + self_segment_count = len(self.path_segments) + input_segment_count = len(result.path_segments) + + if input_segment_count == self_segment_count + 1: + # a direct child of this directory + self.contents.append( + GitHubNode( + node_type=GitHubNodeType.page, + path_segments=result.path_segments, + title=result.title, + github_commit=result.github_commit, + contents=[], + ) + ) + else: + # Create a directory node + dir_node = GitHubNode( + node_type=GitHubNodeType.directory, + path_segments=result.path_segments[: self_segment_count + 1], + title=result.path_segments[self_segment_count], + github_commit=result.github_commit, + contents=[], + ) + self.contents.append(dir_node) + dir_node.insert_node(result) @dataclass -class GitHubTreeInput: +class GitHubTreeQueryResult: """A domain class used to aid construction of the GitHub contents tree from the original SQL storage of pages. - - This class is used by `PageStore.get_github_tree`; `GitHubNode` is the - public product. """ - path_segments: List[str] + # The order of these attributes matches the order of the sql query + # in timessquare.storage.page. + + github_owner: str + + github_repo: str - stem: str + github_commit: Optional[str] + + path_prefix: str title: str - @classmethod - def from_sql_row( - cls, - github_owner: str, - github_repo: str, - path_prefix: str, - title: str, - path_stem: str, - ) -> GitHubTreeInput: - path_segments = [github_owner, github_repo] - if path_prefix: - path_segments.extend(path_prefix.split("/")) - - return cls(path_segments=path_segments, stem=path_stem, title=title) - - def to_node(self) -> GitHubNode: - return GitHubNode( - node_type=GitHubNodeType.page, - title=self.title, - path="/".join(self.path_segments + [self.stem]), - contents=[], - ) + path_stem: str + + @property + def path_segments(self) -> List[str]: + segments: List[str] = [self.github_owner, self.github_repo] + if len(self.path_prefix) > 0: + segments.extend(self.path_prefix.split("/")) + segments.append(self.path_stem) + return segments diff --git a/src/timessquare/handlers/v1/handlers.py b/src/timessquare/handlers/v1/handlers.py index 050dbabc..8dd547c9 100644 --- a/src/timessquare/handlers/v1/handlers.py +++ b/src/timessquare/handlers/v1/handlers.py @@ -2,7 +2,7 @@ from typing import List -from fastapi import APIRouter, Depends, HTTPException, Request +from fastapi import APIRouter, Depends, HTTPException, Path, Request from fastapi.responses import HTMLResponse, PlainTextResponse from safir.metadata import get_metadata @@ -13,7 +13,8 @@ ) from .models import ( - GitHubTreeRoot, + GitHubContentsRoot, + GitHubPrContents, HtmlStatus, Index, Page, @@ -26,6 +27,47 @@ v1_router = APIRouter(tags=["v1"]) """FastAPI router for all external handlers.""" +display_path_parameter = Path( + title="Page display path", + description=( + "A display path is a POSIX-like '/'-separated path consisting " + "of components:\n" + "\n" + "- GitHub owner (organization or username)\n" + "- Github repository\n" + "- Directory name or names (as appropriate)\n" + "- Page filename stem\n" + ), + example="lsst-sqre/times-square-demo/matplotlib/gaussian2d", +) + +github_owner_parameter = Path( + title="GitHub owner (organization or username)", example="lsst-sqre" +) + +github_repo_parameter = Path( + title="GitHub repository", example="times-square-demo" +) + +page_path_parameter = Path( + title="Page name", + description=( + "An opaque identifier for a page. This is often the 'name' field for " + "a page's resource model." + ), + example="3d5a140634c34e249b7531667469b816", +) + +path_parameter = Path( + title="Notebook path in repository (without extension)", + example="matplotlib/gaussian2d", +) + +pr_commit_parameter = Path( + title="Git commit for pull request check run", + example="878092649b8bc1d8ef1436cc623bcecb923ece39", +) + @v1_router.get( "/", @@ -53,7 +95,8 @@ async def get_index( name="get_page", ) async def get_page( - page: str, context: RequestContext = Depends(context_dependency) + page: str = page_path_parameter, + context: RequestContext = Depends(context_dependency), ) -> Page: """Get metadata about a page resource, which models a webpage that is rendered from a parameterized Jupyter Notebook. @@ -186,7 +229,7 @@ async def post_page( name="get_page_source", ) async def get_page_source( - page: str, + page: str = page_path_parameter, context: RequestContext = Depends(context_dependency), ) -> PlainTextResponse: """Get the content of the source ipynb file, which is unexecuted and has @@ -215,7 +258,7 @@ async def get_page_source( name="get_rendered_notebook", ) async def get_rendered_notebook( - page: str, + page: str = page_path_parameter, context: RequestContext = Depends(context_dependency), ) -> PlainTextResponse: """Get a Jupyter Notebook with the parameter values filled in. The @@ -236,7 +279,7 @@ async def get_rendered_notebook( name="get_page_html", ) async def get_page_html( - page: str, + page: str = page_path_parameter, context: RequestContext = Depends(context_dependency), ) -> HTMLResponse: """Get the rendered HTML of a notebook.""" @@ -261,7 +304,7 @@ async def get_page_html( response_model=HtmlStatus, ) async def get_page_html_status( - page: str, + page: str = page_path_parameter, context: RequestContext = Depends(context_dependency), ) -> HtmlStatus: page_service = context.page_service @@ -277,11 +320,11 @@ async def get_page_html_status( "/github", summary="Get a tree of GitHub-backed pages", name="get_github_tree", - response_model=GitHubTreeRoot, + response_model=GitHubContentsRoot, ) async def get_github_tree( context: RequestContext = Depends(context_dependency), -) -> GitHubTreeRoot: +) -> GitHubContentsRoot: """Get the tree of GitHub-backed pages. This endpoint is primarily intended to be used by Squareone to power @@ -292,7 +335,7 @@ async def get_github_tree( page_service = context.page_service async with context.session.begin(): github_tree = await page_service.get_github_tree() - return GitHubTreeRoot.from_tree(tree=github_tree) + return GitHubContentsRoot.from_tree(tree=github_tree) @v1_router.get( @@ -302,19 +345,14 @@ async def get_github_tree( name="get_github_page", ) async def get_github_page( - display_path: str, context: RequestContext = Depends(context_dependency) + display_path: str = display_path_parameter, + context: RequestContext = Depends(context_dependency), ) -> Page: """Get the metadata for a GitHub-backed page. This endpoint provides the same data as ``GET /v1/pages/:page``, but is queried via the page's GitHub "display path" rather than the opaque - page slug. A display path is a POSIX-like "/"-separated path consisting - of components: - - - GitHub owner (organization or username) - - Github repository - - Directory name or names (as appropriate) - - Page filename stem + page name. """ page_service = context.page_service async with context.session.begin(): @@ -324,3 +362,82 @@ async def get_github_page( "get_page", page=page_domain.name ) return Page.from_domain(page=page_domain, request=context.request) + + +@v1_router.get( + "/github-pr/{owner}/{repo}/{commit}", + summary="Get a tree of GitHub PR preview pages", + name="get_github_pr_tree", + response_model=GitHubPrContents, +) +async def get_github_pr_tree( + owner: str = github_owner_parameter, + repo: str = github_repo_parameter, + commit: str = pr_commit_parameter, + context: RequestContext = Depends(context_dependency), +) -> GitHubPrContents: + """Get the tree of GitHub-backed pages for a pull request. + + This endpoint is primarily intended to be used by Squareone to power + its navigational view of GitHub pages for a specific pull request + (actually a commit SHA) of a repository. + """ + repo_service = await context.create_github_repo_service( + owner=owner, repo=repo + ) # TODO handle response where the app is not installed + page_service = repo_service.page_service + + async with context.session.begin(): + github_tree = await page_service.get_github_pr_tree( + owner=owner, repo=repo, commit=commit + ) + + check_runs = await repo_service.get_check_runs( + owner=owner, repo=repo, head_sha=commit + ) + context.logger.debug( + "Check runs", check_runs=[run.dict() for run in check_runs] + ) + + pull_requests = await repo_service.get_pulls_for_check_runs(check_runs) + context.logger.debug( + "Pull requests", prs=[pr.dict() for pr in pull_requests] + ) + + return GitHubPrContents.create( + tree=github_tree, + owner=owner, + repo=repo, + commit=commit, + check_runs=check_runs, + pull_requests=pull_requests, + ) + + +@v1_router.get( + "/github-pr/{owner}/{repo}/{commit}/{path:path}", + response_model=Page, + summary="Metadata for GitHub-backed page", + name="get_github_pr_page", +) +async def get_github_pr_page( + owner: str = github_owner_parameter, + repo: str = github_repo_parameter, + commit: str = pr_commit_parameter, + path: str = path_parameter, + context: RequestContext = Depends(context_dependency), +) -> Page: + """Get the metadata for a pull request preview of a GitHub-backed page.""" + page_service = context.page_service + async with context.session.begin(): + page_domain = await page_service.get_github_pr_page( + owner=owner, + repo=repo, + commit=commit, + path=path, + ) + + context.response.headers["location"] = context.request.url_for( + "get_page", page=page_domain.name + ) + return Page.from_domain(page=page_domain, request=context.request) diff --git a/src/timessquare/handlers/v1/models.py b/src/timessquare/handlers/v1/models.py index cd96b424..1fcdf9e6 100644 --- a/src/timessquare/handlers/v1/models.py +++ b/src/timessquare/handlers/v1/models.py @@ -3,15 +3,23 @@ from __future__ import annotations from datetime import datetime +from enum import Enum from typing import Any, Dict, List, Optional from urllib.parse import urlencode from fastapi import Request from markdown_it import MarkdownIt -from pydantic import AnyHttpUrl, BaseModel, EmailStr, Field +from pydantic import AnyHttpUrl, BaseModel, EmailStr, Field, HttpUrl from safir.metadata import Metadata as SafirMetadata -from timessquare.domain.githubtree import GitHubNode +from timessquare.domain.githubapi import ( + GitHubCheckRunConclusion, + GitHubCheckRunModel, + GitHubCheckRunStatus, + GitHubPullRequestModel, + GitHubPullState, +) +from timessquare.domain.githubtree import GitHubNode, GitHubNodeType from timessquare.domain.nbhtml import NbHtmlModel from timessquare.domain.page import PageModel, PageSummaryModel, PersonModel @@ -21,7 +29,7 @@ class Index(BaseModel): metadata: SafirMetadata = Field(..., title="Package metadata") - api_docs: AnyHttpUrl = Field(..., tile="Browsable API documentation") + api_docs: AnyHttpUrl = Field(..., title="Browsable API documentation") page_name_field = Field( @@ -409,11 +417,266 @@ class PostPageRequest(BaseModel): cache_ttl: Optional[int] = page_cache_ttl_field -class GitHubTreeRoot(BaseModel): - """The GitHub-backed pages, organized hierarchically.""" +class GitHubContentsNode(BaseModel): + """Information about a node in a GitHub contents tree.""" + + node_type: GitHubNodeType = Field( + ..., + title="Node type", + description="Type of node in the GitHub contents tree.", + example="page", + ) + + path: str = Field( + ..., + title="Path", + description="Squareone URL path", + example="lsst-sqre/times-square-demo/demo", + ) + + title: str = Field( + ..., + title="Title", + description="Presentation title of the node.", + example="Demo", + ) + + contents: List[GitHubContentsNode] = Field( + ..., title="Contents", description="Children of this node" + ) + + @classmethod + def from_domain_model(cls, node: GitHubNode) -> GitHubContentsNode: + return cls( + node_type=node.node_type, + path=node.squareone_path, + title=node.title, + contents=[cls.from_domain_model(n) for n in node.contents], + ) + + +class GitHubContentsRoot(BaseModel): + """The tree of GitHub contents.""" + + contents: List[GitHubContentsNode] = Field( + title="Contents", description="Content nodes" + ) + + @classmethod + def from_tree( + cls, + *, + tree: List[GitHubNode], + ) -> GitHubContentsRoot: + return cls( + contents=[GitHubContentsNode.from_domain_model(n) for n in tree], + ) + + +class GitHubContributor(BaseModel): + """A GitHub contributor.""" + + username: str = Field(..., title="Username", description="GitHub username") + + html_url: HttpUrl = Field( + ..., title="HTML URL", description="The user's homepage on GitHub." + ) + + avatar_url: HttpUrl = Field(..., title="Avatar image URL") + + +class GitHubPrState(str, Enum): + """The state of a GitHub PR.""" + + draft = "draft" + open = "open" + merged = "merged" + closed = "closed" + + +class GitHubPr(BaseModel): + """Information about a pull request.""" + + number: int = Field( + title="PR number", description="The pull request number." + ) + + title: str = Field(title="Title of the pull request") + + conversation_url: HttpUrl = Field( + title="URL for the PR's conversation page on GitHub." + ) + + contributor: GitHubContributor + + state: GitHubPrState + + @classmethod + def from_github_pr(cls, pull_request: GitHubPullRequestModel) -> GitHubPr: + # Consolidate github state information + if pull_request.merged: + state = GitHubPrState.merged + elif pull_request.draft: + state = GitHubPrState.draft + elif pull_request.state == GitHubPullState.closed: + state = GitHubPrState.closed + else: + state = GitHubPrState.open + + return cls( + number=pull_request.number, + title=pull_request.title, + conversation_url=pull_request.html_url, + state=state, + contributor=GitHubContributor( + username=pull_request.user.login, + html_url=pull_request.user.html_url, + avatar_url=pull_request.user.avatar_url, + ), + ) + + +class GitHubCheckRunSummary(BaseModel): + """Summary info about a check run.""" + + status: GitHubCheckRunStatus + + conclusion: Optional[GitHubCheckRunConclusion] + + external_id: Optional[str] = Field( + description="Identifier set by the check runner." + ) + + head_sha: str = Field( + title="Head sha", + description="The SHA of the most recent commit for this check suite.", + ) + + name: str = Field(description="Name of the check run.") + + html_url: HttpUrl = Field( + description="URL of the check run webpage on GitHub." + ) + + report_title: Optional[str] = Field( + None, + title="Report title", + ) + + report_summary: Optional[FormattedText] = Field( + None, + title="Report summary", + ) + + report_text: Optional[FormattedText] = Field( + None, + title="Report body text", + ) + + @classmethod + def from_checkrun( + cls, check_run: GitHubCheckRunModel + ) -> GitHubCheckRunSummary: + """Create a check run summary API model from the GitHub API + model. + """ + report_title: Optional[str] = None + report_summary: Optional[FormattedText] = None + report_text: Optional[FormattedText] = None + + if check_run.output: + output = check_run.output + if output.title: + report_title = output.title + if output.summary: + report_summary = FormattedText.from_gfm(output.summary) + if output.text: + report_text = FormattedText.from_gfm(output.text) + + instance = cls( + status=check_run.status, + conclusion=check_run.conclusion, + external_id=check_run.external_id, + head_sha=check_run.head_sha, + name=check_run.name, + html_url=check_run.html_url, + report_title=report_title, + report_summary=report_summary, + report_text=report_text, + ) + return instance + + +class GitHubPrContents(GitHubContentsRoot): + """The contents of a GitHub pull request, along with information + about the check run and pull request. + """ - contents: List[GitHubNode] + owner: str = Field( + ..., + title="GitHub owner", + description=( + "The GitHub owner for this tree, if this tree applies to a single " + "GitHub owner." + ), + ) + + repo: str = Field( + ..., + title="GitHub repo", + description=( + "The GitHub repo for this tree, if this tree applies to a single " + "GitHub repo." + ), + ) + + commit: str = Field( + ..., + title="GitHub commit", + description=( + "The GitHub commit for this tree, if this tree is specific to a " + "commit, such as for a PR preview." + ), + ) + + yaml_check: Optional[GitHubCheckRunSummary] = Field( + ..., description="Summary of notebook execution check run." + ) + + nbexec_check: Optional[GitHubCheckRunSummary] = Field( + ..., description="Summary of notebook execution check run." + ) + + pull_requests: List[GitHubPr] = Field( + ..., + title="Pull Requests", + ) @classmethod - def from_tree(cls, *, tree: List[GitHubNode]) -> GitHubTreeRoot: - return cls(contents=tree) + def create( + cls, + *, + tree: List[GitHubNode], + owner: str, + repo: str, + commit: str, + check_runs: List[GitHubCheckRunModel], + pull_requests: List[GitHubPullRequestModel], + ) -> GitHubPrContents: + yaml_check: Optional[GitHubCheckRunSummary] = None + nbexec_check: Optional[GitHubCheckRunSummary] = None + for check_run in check_runs: + if check_run.external_id == "times-square/nbexec": + nbexec_check = GitHubCheckRunSummary.from_checkrun(check_run) + elif check_run.external_id == "times-square/yaml-check": + yaml_check = GitHubCheckRunSummary.from_checkrun(check_run) + + return cls( + contents=[GitHubContentsNode.from_domain_model(n) for n in tree], + owner=owner, + repo=repo, + commit=commit, + yaml_check=yaml_check, + nbexec_check=nbexec_check, + pull_requests=[GitHubPr.from_github_pr(p) for p in pull_requests], + ) diff --git a/src/timessquare/services/github/repo.py b/src/timessquare/services/github/repo.py index 39df2429..835b6fa1 100644 --- a/src/timessquare/services/github/repo.py +++ b/src/timessquare/services/github/repo.py @@ -41,6 +41,11 @@ from timessquare.domain.page import PageExecutionInfo, PageModel from ..page import PageService +from .client import ( + create_github_client, + create_github_installation_client, + get_app_jwt, +) class GitHubRepoService: @@ -73,6 +78,60 @@ def __init__( self._page_service = page_service self._logger = logger + @classmethod + async def create_for_repo( + cls, + *, + owner: str, + repo: str, + http_client: AsyncClient, + page_service: PageService, + logger: BoundLogger, + ) -> GitHubRepoService: + """Create a github repo service for a specific repository (requires + that the Times Square GitHub App is installed for that repository). + + Parameters + ---------- + owner : `str` + The GitHub repo's owner. + repo : `str` + The GitHub repo's name. + http_client : `AsyncClient` + An httpx client. + github_client : `GitHubAPI` + A GidgetHub API client that is authenticated as a GitHub app + installation. + page_service : `PageService` + The Page service. This GitHubRepoService acts as a layer on top of + the regular page service to handle domain models from the github + domain. + logger : `BoundLogger` + A logger, ideally with request/worker job context already bound. + """ + app_jwt = get_app_jwt() + app_client = create_github_client(http_client=http_client) + installation_data = await app_client.getitem( + "/repos/{owner}/{repo}/installation", + url_vars={"owner": owner, "repo": repo}, + jwt=app_jwt, + ) + installation_id = installation_data["id"] + installation_client = await create_github_installation_client( + http_client=http_client, installation_id=installation_id + ) + return cls( + http_client=http_client, + github_client=installation_client, + page_service=page_service, + logger=logger, + ) + + @property + def page_service(self) -> PageService: + """The page service used by the repo service.""" + return self._page_service + async def sync_from_repo_installation( self, owner: str, @@ -383,7 +442,7 @@ async def run_notebook_check_run( This check actually creates/updates Page resources, hence it is run at the service layer, rather than in a domain model. """ - check = NotebookExecutionsCheck(check_run) + check = NotebookExecutionsCheck(check_run, repo) await check.submit_in_progress(self._github_client) self._logger.debug("Notebook executions check in progress") @@ -505,3 +564,43 @@ async def run_notebook_check_run( ) await check.submit_conclusion(github_client=self._github_client) + + async def get_check_runs( + self, owner: str, repo: str, head_sha: str + ) -> List[GitHubCheckRunModel]: + """Get the check runs from GitHub corresponding to a commit. + + https://docs.github.com/en/rest/checks/runs#list-check-runs-for-a-git-reference + """ + check_runs: List[GitHubCheckRunModel] = [] + async for item in self._github_client.getiter( + "/repos/{owner}/{repo}/commits/{ref}/check-runs", + url_vars={"owner": owner, "repo": repo, "ref": head_sha}, + iterable_key="check_runs", + ): + check_runs.append(GitHubCheckRunModel.parse_obj(item)) + return check_runs + + async def get_pulls_for_check_runs( + self, check_runs: List[GitHubCheckRunModel] + ) -> List[GitHubPullRequestModel]: + """Get the pull requests from GitHub covered by the provided check + runs. + + Normally we'll look up the check runs first with `get_check_runs` + and then use this method to get information about the corresponding + pull requests. + """ + # reduce the unique pull request urls + pr_urls: List[str] = [] + for check_run in check_runs: + for pr in check_run.pull_requests: + pr_urls.append(pr.url) + pr_urls = sorted(list(set(pr_urls))) + + pull_requests: List[GitHubPullRequestModel] = [] + for pr_url in pr_urls: + data = await self._github_client.getitem(pr_url) + pull_requests.append(GitHubPullRequestModel.parse_obj(data)) + + return pull_requests diff --git a/src/timessquare/services/page.py b/src/timessquare/services/page.py index 506442e8..6f95c64a 100644 --- a/src/timessquare/services/page.py +++ b/src/timessquare/services/page.py @@ -130,6 +130,48 @@ async def get_github_backed_page(self, display_path: str) -> PageModel: raise PageNotFoundError(display_path) return page + async def get_github_pr_page( + self, + *, + owner: str, + repo: str, + commit: str, + path: str, + ) -> PageModel: + """Get a page for a specific commit, corresponding to a GitHub PR's + check run. + + Parameters + ---------- + owner : `str` + GitHub repository owner (username or organization). + repo : `str` + GitHub repository name. + commit : `str` + The SHA of the Git commit corresponding to the check run. + path : `str` + The page's path within the repository (without the file extension). + + Returns + ------- + page : `PageModel` + The domain model for a page. For PRs, this page is creating while + processing the GitHub check suite. + + Raises + ------ + PageNotFoundError + Raised if the page is not found in the PageStore. + """ + display_path = f"{owner}/{repo}/{path}" + page = await self._page_store.get_github_backed_page( + display_path, commit=commit + ) + if page is None: + # FIXME add a commit attribute to the exception + raise PageNotFoundError(display_path) + return page + async def get_page_summaries(self) -> List[PageSummaryModel]: """Get page summaries.""" return await self._page_store.list_page_summaries() @@ -146,6 +188,18 @@ async def get_github_tree(self) -> List[GitHubNode]: """Get the tree of GitHub-backed pages.""" return await self._page_store.get_github_tree() + async def get_github_pr_tree( + self, + *, + owner: str, + repo: str, + commit: str, + ) -> List[GitHubNode]: + """Get the tree of GitHub-backed pages for a specific pull request.""" + return await self._page_store.get_github_pr_tree( + owner=owner, repo=repo, commit=commit + ) + async def update_page_in_store(self, page: PageModel) -> None: """Update the page in the database.""" await self._page_store.update_page(page) diff --git a/src/timessquare/storage/page.py b/src/timessquare/storage/page.py index 2124b68c..fbafa830 100644 --- a/src/timessquare/storage/page.py +++ b/src/timessquare/storage/page.py @@ -12,7 +12,7 @@ from timessquare.domain.githubtree import ( GitHubNode, GitHubNodeType, - GitHubTreeInput, + GitHubTreeQueryResult, ) from timessquare.domain.page import ( PageModel, @@ -273,9 +273,10 @@ async def get_github_tree(self) -> List[GitHubNode]: async def _generate_node_for_owner(self, owner_name: str) -> GitHubNode: statement = ( - select( + select( # order matches GitHubTreeQueryResult SqlPage.github_owner, SqlPage.github_repo, + SqlPage.github_commit, SqlPage.repository_display_path_prefix, SqlPage.title, SqlPage.repository_path_stem, @@ -293,16 +294,76 @@ async def _generate_node_for_owner(self, owner_name: str) -> GitHubNode: result = await self._session.execute(statement) tree_inputs = [ - GitHubTreeInput.from_sql_row(*row) for row in result.all() + GitHubTreeQueryResult( + github_owner=row[0], + github_repo=row[1], + github_commit=row[2], + path_prefix=row[3], + title=row[4], + path_stem=row[5], + ) + for row in result.all() ] owner_node = GitHubNode( node_type=GitHubNodeType.owner, title=owner_name, - path=owner_name, + path_segments=[owner_name], + github_commit=None, contents=[], ) for tree_input in tree_inputs: - owner_node.insert_input(tree_input) + owner_node.insert_node(tree_input) return owner_node + + async def get_github_pr_tree( + self, *, owner: str, repo: str, commit: str + ) -> List[GitHubNode]: + """Get the tree of GitHub-backed pages for a pull request commit.""" + statement = ( + select( # order matches GitHubTreeQueryResult + SqlPage.github_owner, + SqlPage.github_repo, + SqlPage.github_commit, + SqlPage.repository_display_path_prefix, + SqlPage.title, + SqlPage.repository_path_stem, + ) + .where(SqlPage.date_deleted == None) # noqa: E711 + .where(SqlPage.github_commit == commit) + .where(SqlPage.github_owner == owner) + .order_by( + SqlPage.repository_display_path_prefix, + SqlPage.title, + ) + ) + result = await self._session.execute(statement) + + tree_inputs = [ + GitHubTreeQueryResult( + github_owner=row[0], + github_repo=row[1], + github_commit=row[2], + path_prefix=row[3], + title=row[4], + path_stem=row[5], + ) + for row in result.all() + ] + if len(tree_inputs) == 0: + return [] + + # Create a root node for the repo to use its insert_input method + # for sorting the tree and creating directories as needed + repo_node = GitHubNode( + node_type=GitHubNodeType.repo, + path_segments=[owner, repo], + github_commit=commit, + title=repo, + contents=[], + ) + for tree_input in tree_inputs: + repo_node.insert_node(tree_input) + + return repo_node.contents diff --git a/tests/domain/githubtree_test.py b/tests/domain/githubtree_test.py new file mode 100644 index 00000000..5117fffd --- /dev/null +++ b/tests/domain/githubtree_test.py @@ -0,0 +1,151 @@ +"""Tests for the githubtree domain models.""" + +from __future__ import annotations + +from timessquare.domain.githubtree import ( + GitHubNode, + GitHubNodeType, + GitHubTreeQueryResult, +) + + +def test_githubtreenode() -> None: + """Test the construction of a GitHubNode from mock GitHubTreeInputs with + a null GitHub commit. + """ + mock_sql_results = [ + [ + "lsst-sqre", + "times-square-demo", + None, + "", + "Alpha", + "alpha", + ], + [ + "lsst-sqre", + "times-square-demo", + None, + "", + "Beta", + "beta", + ], + [ + "lsst-sqre", + "times-square-demo", + None, + "subdir", + "Gamma", + "gamma", + ], + ] + tree_inputs = [ + GitHubTreeQueryResult( + github_owner=str(row[0]), + github_repo=str(row[1]), + github_commit=row[2], + path_prefix=str(row[3]), + title=str(row[4]), + path_stem=str(row[5]), + ) + for row in mock_sql_results + ] + + owner_node = GitHubNode( + node_type=GitHubNodeType.owner, + title="lsst-sqre", + path_segments=["lsst-sqre"], + github_commit=None, + contents=[], + ) + for tree_input in tree_inputs: + owner_node.insert_node(tree_input) + + assert owner_node.title == "lsst-sqre" + assert owner_node.contents[0].title == "times-square-demo" + repo_node = owner_node.contents[0] + assert repo_node.node_type == GitHubNodeType.repo + print(owner_node) + + assert repo_node.contents[0].title == "Alpha" + assert repo_node.contents[0].squareone_path == ( + "lsst-sqre/times-square-demo/alpha" + ) + + assert repo_node.contents[1].title == "Beta" + + assert repo_node.contents[2].title == "subdir" + dir_node = repo_node.contents[2] + assert dir_node.contents[0].title == "Gamma" + assert dir_node.contents[0].squareone_path == ( + "lsst-sqre/times-square-demo/subdir/gamma" + ) + + +def test_githubprtreenode() -> None: + """Test the construction of a GitHubPrNode from mock inputs.""" + mock_sql_results = [ + [ + "lsst-sqre", + "times-square-demo", + "e35e1d5c485531ba9e99081c52dbdc5579e00556", + "", + "Alpha", + "alpha", + ], + [ + "lsst-sqre", + "times-square-demo", + "e35e1d5c485531ba9e99081c52dbdc5579e00556", + "", + "Beta", + "beta", + ], + [ + "lsst-sqre", + "times-square-demo", + "e35e1d5c485531ba9e99081c52dbdc5579e00556", + "subdir", + "Gamma", + "gamma", + ], + ] + tree_inputs = [ + GitHubTreeQueryResult( + github_owner=str(row[0]), + github_repo=str(row[1]), + github_commit=row[2], + path_prefix=str(row[3]), + title=str(row[4]), + path_stem=str(row[5]), + ) + for row in mock_sql_results + ] + + repo_node = GitHubNode( + node_type=GitHubNodeType.repo, + title="times-square-demo", + path_segments=["lsst-sqre", "times-square-demo"], + github_commit="e35e1d5c485531ba9e99081c52dbdc5579e00556", + contents=[], + ) + for tree_input in tree_inputs: + repo_node.insert_node(tree_input) + + assert repo_node.contents[0].title == "Alpha" + assert repo_node.contents[0].squareone_path == ( + "lsst-sqre/times-square-demo/e35e1d5c485531ba9e99081c52dbdc5579e00556" + "/alpha" + ) + assert repo_node.contents[1].title == "Beta" + assert repo_node.contents[1].squareone_path == ( + "lsst-sqre/times-square-demo/e35e1d5c485531ba9e99081c52dbdc5579e00556" + "/beta" + ) + assert repo_node.contents[2].title == "subdir" + dir_node = repo_node.contents[2] + assert dir_node.contents[0].title == "Gamma" + assert dir_node.contents[0].squareone_path == ( + "lsst-sqre/times-square-demo/e35e1d5c485531ba9e99081c52dbdc5579e00556" + "/subdir/gamma" + )