diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index e7e4562ac..7ea3acf11 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -35,6 +35,7 @@ jobs: MYSQL_PASS: password MYSQL_DB: bangumi REDIS_URI: redis://127.0.0.1:6379/0 + TESTING: "true" - run: coverage xml diff --git a/poetry.lock b/poetry.lock index 946c25bb1..2eb17c0e5 100644 --- a/poetry.lock +++ b/poetry.lock @@ -1,23 +1,3 @@ -[[package]] -name = "aiohttp" -version = "3.8.1" -description = "Async http client/server framework (asyncio)" -category = "dev" -optional = false -python-versions = ">=3.6" - -[package.dependencies] -aiosignal = ">=1.1.2" -async-timeout = ">=4.0.0a3,<5.0" -attrs = ">=17.3.0" -charset-normalizer = ">=2.0,<3.0" -frozenlist = ">=1.1.1" -multidict = ">=4.5,<7.0" -yarl = ">=1.0,<2.0" - -[package.extras] -speedups = ["aiodns", "brotli", "cchardet"] - [[package]] name = "aiomysql" version = "0.0.22" @@ -32,28 +12,6 @@ PyMySQL = ">=0.9,<=0.9.3" [package.extras] sa = ["sqlalchemy (>=1.0)"] -[[package]] -name = "aioresponses" -version = "0.7.2" -description = "Mock out requests made by ClientSession from aiohttp package" -category = "dev" -optional = false -python-versions = "*" - -[package.dependencies] -aiohttp = ">=2.0.0,<4.0.0" - -[[package]] -name = "aiosignal" -version = "1.2.0" -description = "aiosignal: a list of registered asynchronous callbacks" -category = "dev" -optional = false -python-versions = ">=3.6" - -[package.dependencies] -frozenlist = ">=1.1.0" - [[package]] name = "anyio" version = "3.4.0" @@ -82,25 +40,6 @@ python-versions = ">=3.6" [package.extras] tests = ["pytest", "pytest-asyncio", "mypy (>=0.800)"] -[[package]] -name = "async-timeout" -version = "4.0.1" -description = "Timeout context manager for asyncio programs" -category = "dev" -optional = false -python-versions = ">=3.6" - -[package.dependencies] -typing-extensions = ">=3.6.5" - -[[package]] -name = "asynctest" -version = "0.13.0" -description = "Enhance the standard unittest package with features for testing asyncio libraries" -category = "dev" -optional = false -python-versions = ">=3.5" - [[package]] name = "atomicwrites" version = "1.4.0" @@ -342,14 +281,6 @@ python-versions = ">=3.6,<4.0" [package.dependencies] flake8-plugin-utils = ">=1.3.2,<2.0.0" -[[package]] -name = "frozenlist" -version = "1.2.0" -description = "A list-like structure which implements collections.abc.MutableSequence" -category = "dev" -optional = false -python-versions = ">=3.6" - [[package]] name = "greenlet" version = "1.1.2" @@ -456,14 +387,6 @@ category = "dev" optional = false python-versions = "*" -[[package]] -name = "multidict" -version = "5.2.0" -description = "multidict implementation" -category = "dev" -optional = false -python-versions = ">=3.6" - [[package]] name = "mypy" version = "0.910" @@ -639,29 +562,26 @@ toml = "*" testing = ["argcomplete", "hypothesis (>=3.56)", "mock", "nose", "requests", "xmlschema"] [[package]] -name = "pytest-asyncio" -version = "0.16.0" -description = "Pytest support for asyncio." +name = "pytest-env" +version = "0.6.2" +description = "py.test plugin that allows you to add environment variables." category = "dev" optional = false -python-versions = ">= 3.6" +python-versions = "*" [package.dependencies] -pytest = ">=5.4.0" - -[package.extras] -testing = ["coverage", "hypothesis (>=5.7.1)"] +pytest = ">=2.6.0" [[package]] -name = "pytest-rerunfailures" -version = "10.2" -description = "pytest plugin to re-run tests to eliminate flaky failures" +name = "pytest-github-actions-annotate-failures" +version = "0.1.6" +description = "pytest plugin to annotate failed tests with a workflow command for GitHub Actions" category = "dev" optional = false -python-versions = ">= 3.6" +python-versions = "*" [package.dependencies] -pytest = ">=5.3" +pytest = ">=4.0.0" [[package]] name = "python-dateutil" @@ -947,110 +867,16 @@ python-versions = ">=3.5" [package.extras] dev = ["pytest (>=4.6.2)", "black (>=19.3b0)"] -[[package]] -name = "yarl" -version = "1.7.2" -description = "Yet another URL library" -category = "dev" -optional = false -python-versions = ">=3.6" - -[package.dependencies] -idna = ">=2.0" -multidict = ">=4.0" - [metadata] lock-version = "1.1" python-versions = "3.8.*" -content-hash = "f243721db882b242bdcc210d84fdbe0f9f815df83d5d2d77280b44378fe47bda" +content-hash = "648548a7bf18b64bcaee4e33eb30abb510de6107b58502c4615b6cedec31806b" [metadata.files] -aiohttp = [ - {file = "aiohttp-3.8.1-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:1ed0b6477896559f17b9eaeb6d38e07f7f9ffe40b9f0f9627ae8b9926ae260a8"}, - {file = "aiohttp-3.8.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:7dadf3c307b31e0e61689cbf9e06be7a867c563d5a63ce9dca578f956609abf8"}, - {file = "aiohttp-3.8.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:a79004bb58748f31ae1cbe9fa891054baaa46fb106c2dc7af9f8e3304dc30316"}, - {file = "aiohttp-3.8.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:12de6add4038df8f72fac606dff775791a60f113a725c960f2bab01d8b8e6b15"}, - {file = "aiohttp-3.8.1-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:6f0d5f33feb5f69ddd57a4a4bd3d56c719a141080b445cbf18f238973c5c9923"}, - {file = "aiohttp-3.8.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:eaba923151d9deea315be1f3e2b31cc39a6d1d2f682f942905951f4e40200922"}, - {file = "aiohttp-3.8.1-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:099ebd2c37ac74cce10a3527d2b49af80243e2a4fa39e7bce41617fbc35fa3c1"}, - {file = "aiohttp-3.8.1-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:2e5d962cf7e1d426aa0e528a7e198658cdc8aa4fe87f781d039ad75dcd52c516"}, - {file = "aiohttp-3.8.1-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:fa0ffcace9b3aa34d205d8130f7873fcfefcb6a4dd3dd705b0dab69af6712642"}, - {file = "aiohttp-3.8.1-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:61bfc23df345d8c9716d03717c2ed5e27374e0fe6f659ea64edcd27b4b044cf7"}, - {file = "aiohttp-3.8.1-cp310-cp310-musllinux_1_1_ppc64le.whl", hash = "sha256:31560d268ff62143e92423ef183680b9829b1b482c011713ae941997921eebc8"}, - {file = "aiohttp-3.8.1-cp310-cp310-musllinux_1_1_s390x.whl", hash = "sha256:01d7bdb774a9acc838e6b8f1d114f45303841b89b95984cbb7d80ea41172a9e3"}, - {file = "aiohttp-3.8.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:97ef77eb6b044134c0b3a96e16abcb05ecce892965a2124c566af0fd60f717e2"}, - {file = "aiohttp-3.8.1-cp310-cp310-win32.whl", hash = "sha256:c2aef4703f1f2ddc6df17519885dbfa3514929149d3ff900b73f45998f2532fa"}, - {file = "aiohttp-3.8.1-cp310-cp310-win_amd64.whl", hash = "sha256:713ac174a629d39b7c6a3aa757b337599798da4c1157114a314e4e391cd28e32"}, - {file = "aiohttp-3.8.1-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:473d93d4450880fe278696549f2e7aed8cd23708c3c1997981464475f32137db"}, - {file = "aiohttp-3.8.1-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:99b5eeae8e019e7aad8af8bb314fb908dd2e028b3cdaad87ec05095394cce632"}, - {file = "aiohttp-3.8.1-cp36-cp36m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:3af642b43ce56c24d063325dd2cf20ee012d2b9ba4c3c008755a301aaea720ad"}, - {file = "aiohttp-3.8.1-cp36-cp36m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:c3630c3ef435c0a7c549ba170a0633a56e92629aeed0e707fec832dee313fb7a"}, - {file = "aiohttp-3.8.1-cp36-cp36m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:4a4a4e30bf1edcad13fb0804300557aedd07a92cabc74382fdd0ba6ca2661091"}, - {file = "aiohttp-3.8.1-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:6f8b01295e26c68b3a1b90efb7a89029110d3a4139270b24fda961893216c440"}, - {file = "aiohttp-3.8.1-cp36-cp36m-musllinux_1_1_aarch64.whl", hash = "sha256:a25fa703a527158aaf10dafd956f7d42ac6d30ec80e9a70846253dd13e2f067b"}, - {file = "aiohttp-3.8.1-cp36-cp36m-musllinux_1_1_i686.whl", hash = "sha256:5bfde62d1d2641a1f5173b8c8c2d96ceb4854f54a44c23102e2ccc7e02f003ec"}, - {file = "aiohttp-3.8.1-cp36-cp36m-musllinux_1_1_ppc64le.whl", hash = "sha256:51467000f3647d519272392f484126aa716f747859794ac9924a7aafa86cd411"}, - {file = "aiohttp-3.8.1-cp36-cp36m-musllinux_1_1_s390x.whl", hash = "sha256:03a6d5349c9ee8f79ab3ff3694d6ce1cfc3ced1c9d36200cb8f08ba06bd3b782"}, - {file = "aiohttp-3.8.1-cp36-cp36m-musllinux_1_1_x86_64.whl", hash = "sha256:102e487eeb82afac440581e5d7f8f44560b36cf0bdd11abc51a46c1cd88914d4"}, - {file = "aiohttp-3.8.1-cp36-cp36m-win32.whl", hash = "sha256:4aed991a28ea3ce320dc8ce655875e1e00a11bdd29fe9444dd4f88c30d558602"}, - {file = "aiohttp-3.8.1-cp36-cp36m-win_amd64.whl", hash = "sha256:b0e20cddbd676ab8a64c774fefa0ad787cc506afd844de95da56060348021e96"}, - {file = "aiohttp-3.8.1-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:37951ad2f4a6df6506750a23f7cbabad24c73c65f23f72e95897bb2cecbae676"}, - {file = "aiohttp-3.8.1-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5c23b1ad869653bc818e972b7a3a79852d0e494e9ab7e1a701a3decc49c20d51"}, - {file = "aiohttp-3.8.1-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:15b09b06dae900777833fe7fc4b4aa426556ce95847a3e8d7548e2d19e34edb8"}, - {file = "aiohttp-3.8.1-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:477c3ea0ba410b2b56b7efb072c36fa91b1e6fc331761798fa3f28bb224830dd"}, - {file = "aiohttp-3.8.1-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:2f2f69dca064926e79997f45b2f34e202b320fd3782f17a91941f7eb85502ee2"}, - {file = "aiohttp-3.8.1-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:ef9612483cb35171d51d9173647eed5d0069eaa2ee812793a75373447d487aa4"}, - {file = "aiohttp-3.8.1-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:6d69f36d445c45cda7b3b26afef2fc34ef5ac0cdc75584a87ef307ee3c8c6d00"}, - {file = "aiohttp-3.8.1-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:55c3d1072704d27401c92339144d199d9de7b52627f724a949fc7d5fc56d8b93"}, - {file = "aiohttp-3.8.1-cp37-cp37m-musllinux_1_1_ppc64le.whl", hash = "sha256:b9d00268fcb9f66fbcc7cd9fe423741d90c75ee029a1d15c09b22d23253c0a44"}, - {file = "aiohttp-3.8.1-cp37-cp37m-musllinux_1_1_s390x.whl", hash = "sha256:07b05cd3305e8a73112103c834e91cd27ce5b4bd07850c4b4dbd1877d3f45be7"}, - {file = "aiohttp-3.8.1-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:c34dc4958b232ef6188c4318cb7b2c2d80521c9a56c52449f8f93ab7bc2a8a1c"}, - {file = "aiohttp-3.8.1-cp37-cp37m-win32.whl", hash = "sha256:d2f9b69293c33aaa53d923032fe227feac867f81682f002ce33ffae978f0a9a9"}, - {file = "aiohttp-3.8.1-cp37-cp37m-win_amd64.whl", hash = "sha256:6ae828d3a003f03ae31915c31fa684b9890ea44c9c989056fea96e3d12a9fa17"}, - {file = "aiohttp-3.8.1-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:0c7ebbbde809ff4e970824b2b6cb7e4222be6b95a296e46c03cf050878fc1785"}, - {file = "aiohttp-3.8.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:8b7ef7cbd4fec9a1e811a5de813311ed4f7ac7d93e0fda233c9b3e1428f7dd7b"}, - {file = "aiohttp-3.8.1-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:c3d6a4d0619e09dcd61021debf7059955c2004fa29f48788a3dfaf9c9901a7cd"}, - {file = "aiohttp-3.8.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:718626a174e7e467f0558954f94af117b7d4695d48eb980146016afa4b580b2e"}, - {file = "aiohttp-3.8.1-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:589c72667a5febd36f1315aa6e5f56dd4aa4862df295cb51c769d16142ddd7cd"}, - {file = "aiohttp-3.8.1-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2ed076098b171573161eb146afcb9129b5ff63308960aeca4b676d9d3c35e700"}, - {file = "aiohttp-3.8.1-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:086f92daf51a032d062ec5f58af5ca6a44d082c35299c96376a41cbb33034675"}, - {file = "aiohttp-3.8.1-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:11691cf4dc5b94236ccc609b70fec991234e7ef8d4c02dd0c9668d1e486f5abf"}, - {file = "aiohttp-3.8.1-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:31d1e1c0dbf19ebccbfd62eff461518dcb1e307b195e93bba60c965a4dcf1ba0"}, - {file = "aiohttp-3.8.1-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:11a67c0d562e07067c4e86bffc1553f2cf5b664d6111c894671b2b8712f3aba5"}, - {file = "aiohttp-3.8.1-cp38-cp38-musllinux_1_1_ppc64le.whl", hash = "sha256:bb01ba6b0d3f6c68b89fce7305080145d4877ad3acaed424bae4d4ee75faa950"}, - {file = "aiohttp-3.8.1-cp38-cp38-musllinux_1_1_s390x.whl", hash = "sha256:44db35a9e15d6fe5c40d74952e803b1d96e964f683b5a78c3cc64eb177878155"}, - {file = "aiohttp-3.8.1-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:844a9b460871ee0a0b0b68a64890dae9c415e513db0f4a7e3cab41a0f2fedf33"}, - {file = "aiohttp-3.8.1-cp38-cp38-win32.whl", hash = "sha256:7d08744e9bae2ca9c382581f7dce1273fe3c9bae94ff572c3626e8da5b193c6a"}, - {file = "aiohttp-3.8.1-cp38-cp38-win_amd64.whl", hash = "sha256:04d48b8ce6ab3cf2097b1855e1505181bdd05586ca275f2505514a6e274e8e75"}, - {file = "aiohttp-3.8.1-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:f5315a2eb0239185af1bddb1abf472d877fede3cc8d143c6cddad37678293237"}, - {file = "aiohttp-3.8.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:a996d01ca39b8dfe77440f3cd600825d05841088fd6bc0144cc6c2ec14cc5f74"}, - {file = "aiohttp-3.8.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:13487abd2f761d4be7c8ff9080de2671e53fff69711d46de703c310c4c9317ca"}, - {file = "aiohttp-3.8.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ea302f34477fda3f85560a06d9ebdc7fa41e82420e892fc50b577e35fc6a50b2"}, - {file = "aiohttp-3.8.1-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a2f635ce61a89c5732537a7896b6319a8fcfa23ba09bec36e1b1ac0ab31270d2"}, - {file = "aiohttp-3.8.1-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e999f2d0e12eea01caeecb17b653f3713d758f6dcc770417cf29ef08d3931421"}, - {file = "aiohttp-3.8.1-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:0770e2806a30e744b4e21c9d73b7bee18a1cfa3c47991ee2e5a65b887c49d5cf"}, - {file = "aiohttp-3.8.1-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:d15367ce87c8e9e09b0f989bfd72dc641bcd04ba091c68cd305312d00962addd"}, - {file = "aiohttp-3.8.1-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:6c7cefb4b0640703eb1069835c02486669312bf2f12b48a748e0a7756d0de33d"}, - {file = "aiohttp-3.8.1-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:71927042ed6365a09a98a6377501af5c9f0a4d38083652bcd2281a06a5976724"}, - {file = "aiohttp-3.8.1-cp39-cp39-musllinux_1_1_ppc64le.whl", hash = "sha256:28d490af82bc6b7ce53ff31337a18a10498303fe66f701ab65ef27e143c3b0ef"}, - {file = "aiohttp-3.8.1-cp39-cp39-musllinux_1_1_s390x.whl", hash = "sha256:b6613280ccedf24354406caf785db748bebbddcf31408b20c0b48cb86af76866"}, - {file = "aiohttp-3.8.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:81e3d8c34c623ca4e36c46524a3530e99c0bc95ed068fd6e9b55cb721d408fb2"}, - {file = "aiohttp-3.8.1-cp39-cp39-win32.whl", hash = "sha256:7187a76598bdb895af0adbd2fb7474d7f6025d170bc0a1130242da817ce9e7d1"}, - {file = "aiohttp-3.8.1-cp39-cp39-win_amd64.whl", hash = "sha256:1c182cb873bc91b411e184dab7a2b664d4fea2743df0e4d57402f7f3fa644bac"}, - {file = "aiohttp-3.8.1.tar.gz", hash = "sha256:fc5471e1a54de15ef71c1bc6ebe80d4dc681ea600e68bfd1cbce40427f0b7578"}, -] aiomysql = [ {file = "aiomysql-0.0.22-py3-none-any.whl", hash = "sha256:4e4a65914daacc40e70f992ddbeef32457561efbad8de41393e8ac5a84126a5a"}, {file = "aiomysql-0.0.22.tar.gz", hash = "sha256:9bcf8f26d22e550f75cabd635fa19a55c45f835eea008275960cb37acadd622a"}, ] -aioresponses = [ - {file = "aioresponses-0.7.2-py2.py3-none-any.whl", hash = "sha256:2f8ff624543066eb465b0238de68d29231e8488f41dc4b5a9dae190982cdae50"}, - {file = "aioresponses-0.7.2.tar.gz", hash = "sha256:82e495d118b74896aa5b4d47e17effb5e2cc783e510ae395ceade5e87cabe89a"}, -] -aiosignal = [ - {file = "aiosignal-1.2.0-py3-none-any.whl", hash = "sha256:26e62109036cd181df6e6ad646f91f0dcfd05fe16d0cb924138ff2ab75d64e3a"}, - {file = "aiosignal-1.2.0.tar.gz", hash = "sha256:78ed67db6c7b7ced4f98e495e572106d5c432a93e1ddd1bf475e1dc05f5b7df2"}, -] anyio = [ {file = "anyio-3.4.0-py3-none-any.whl", hash = "sha256:2855a9423524abcdd652d942f8932fda1735210f77a6b392eafd9ff34d3fe020"}, {file = "anyio-3.4.0.tar.gz", hash = "sha256:24adc69309fb5779bc1e06158e143e0b6d2c56b302a3ac3de3083c705a6ed39d"}, @@ -1059,14 +885,6 @@ asgiref = [ {file = "asgiref-3.4.1-py3-none-any.whl", hash = "sha256:ffc141aa908e6f175673e7b1b3b7af4fdb0ecb738fc5c8b88f69f055c2415214"}, {file = "asgiref-3.4.1.tar.gz", hash = "sha256:4ef1ab46b484e3c706329cedeff284a5d40824200638503f5768edb6de7d58e9"}, ] -async-timeout = [ - {file = "async-timeout-4.0.1.tar.gz", hash = "sha256:b930cb161a39042f9222f6efb7301399c87eeab394727ec5437924a36d6eef51"}, - {file = "async_timeout-4.0.1-py3-none-any.whl", hash = "sha256:a22c0b311af23337eb05fcf05a8b51c3ea53729d46fb5460af62bee033cec690"}, -] -asynctest = [ - {file = "asynctest-0.13.0-py3-none-any.whl", hash = "sha256:5da6118a7e6d6b54d83a8f7197769d046922a44d2a99c21382f0a6e4fadae676"}, - {file = "asynctest-0.13.0.tar.gz", hash = "sha256:c27862842d15d83e6a34eb0b2866c323880eb3a75e4485b079ea11748fd77fac"}, -] atomicwrites = [ {file = "atomicwrites-1.4.0-py2.py3-none-any.whl", hash = "sha256:6d1784dea7c0c8d4a5172b6c620f40b6e4cbfdf96d783691f2e1302a7b88e197"}, {file = "atomicwrites-1.4.0.tar.gz", hash = "sha256:ae70396ad1a434f9c7046fd2dd196fc04b12f9e91ffb859164193be8b6168a7a"}, @@ -1196,80 +1014,6 @@ flake8-pytest-style = [ {file = "flake8-pytest-style-1.5.1.tar.gz", hash = "sha256:56af62da468a547560a9f455c7f205449ed03e8f8a42f85373180e91c1031c40"}, {file = "flake8_pytest_style-1.5.1-py3-none-any.whl", hash = "sha256:ae62f8db8ad0ea7d90695deb6dbbacfc67d45cb83a7c360388b34a9705786114"}, ] -frozenlist = [ - {file = "frozenlist-1.2.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:977a1438d0e0d96573fd679d291a1542097ea9f4918a8b6494b06610dfeefbf9"}, - {file = "frozenlist-1.2.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:a8d86547a5e98d9edd47c432f7a14b0c5592624b496ae9880fb6332f34af1edc"}, - {file = "frozenlist-1.2.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:181754275d5d32487431a0a29add4f897968b7157204bc1eaaf0a0ce80c5ba7d"}, - {file = "frozenlist-1.2.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5df31bb2b974f379d230a25943d9bf0d3bc666b4b0807394b131a28fca2b0e5f"}, - {file = "frozenlist-1.2.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:4766632cd8a68e4f10f156a12c9acd7b1609941525569dd3636d859d79279ed3"}, - {file = "frozenlist-1.2.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:16eef427c51cb1203a7c0ab59d1b8abccaba9a4f58c4bfca6ed278fc896dc193"}, - {file = "frozenlist-1.2.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:01d79515ed5aa3d699b05f6bdcf1fe9087d61d6b53882aa599a10853f0479c6c"}, - {file = "frozenlist-1.2.0-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:28e164722ea0df0cf6d48c4d5bdf3d19e87aaa6dfb39b0ba91153f224b912020"}, - {file = "frozenlist-1.2.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:e63ad0beef6ece06475d29f47d1f2f29727805376e09850ebf64f90777962792"}, - {file = "frozenlist-1.2.0-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:41de4db9b9501679cf7cddc16d07ac0f10ef7eb58c525a1c8cbff43022bddca4"}, - {file = "frozenlist-1.2.0-cp310-cp310-musllinux_1_1_ppc64le.whl", hash = "sha256:c6a9d84ee6427b65a81fc24e6ef589cb794009f5ca4150151251c062773e7ed2"}, - {file = "frozenlist-1.2.0-cp310-cp310-musllinux_1_1_s390x.whl", hash = "sha256:f5f3b2942c3b8b9bfe76b408bbaba3d3bb305ee3693e8b1d631fe0a0d4f93673"}, - {file = "frozenlist-1.2.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:c98d3c04701773ad60d9545cd96df94d955329efc7743fdb96422c4b669c633b"}, - {file = "frozenlist-1.2.0-cp310-cp310-win32.whl", hash = "sha256:72cfbeab7a920ea9e74b19aa0afe3b4ad9c89471e3badc985d08756efa9b813b"}, - {file = "frozenlist-1.2.0-cp310-cp310-win_amd64.whl", hash = "sha256:11ff401951b5ac8c0701a804f503d72c048173208490c54ebb8d7bb7c07a6d00"}, - {file = "frozenlist-1.2.0-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:b46f997d5ed6d222a863b02cdc9c299101ee27974d9bbb2fd1b3c8441311c408"}, - {file = "frozenlist-1.2.0-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:351686ca020d1bcd238596b1fa5c8efcbc21bffda9d0efe237aaa60348421e2a"}, - {file = "frozenlist-1.2.0-cp36-cp36m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:bfbaa08cf1452acad9cb1c1d7b89394a41e712f88df522cea1a0f296b57782a0"}, - {file = "frozenlist-1.2.0-cp36-cp36m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b2ae2f5e9fa10805fb1c9adbfefaaecedd9e31849434be462c3960a0139ed729"}, - {file = "frozenlist-1.2.0-cp36-cp36m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:6790b8d96bbb74b7a6f4594b6f131bd23056c25f2aa5d816bd177d95245a30e3"}, - {file = "frozenlist-1.2.0-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:41f62468af1bd4e4b42b5508a3fe8cc46a693f0cdd0ca2f443f51f207893d837"}, - {file = "frozenlist-1.2.0-cp36-cp36m-musllinux_1_1_aarch64.whl", hash = "sha256:ec6cf345771cdb00791d271af9a0a6fbfc2b6dd44cb753f1eeaa256e21622adb"}, - {file = "frozenlist-1.2.0-cp36-cp36m-musllinux_1_1_i686.whl", hash = "sha256:14a5cef795ae3e28fb504b73e797c1800e9249f950e1c964bb6bdc8d77871161"}, - {file = "frozenlist-1.2.0-cp36-cp36m-musllinux_1_1_ppc64le.whl", hash = "sha256:8b54cdd2fda15467b9b0bfa78cee2ddf6dbb4585ef23a16e14926f4b076dfae4"}, - {file = "frozenlist-1.2.0-cp36-cp36m-musllinux_1_1_s390x.whl", hash = "sha256:f025f1d6825725b09c0038775acab9ae94264453a696cc797ce20c0769a7b367"}, - {file = "frozenlist-1.2.0-cp36-cp36m-musllinux_1_1_x86_64.whl", hash = "sha256:84e97f59211b5b9083a2e7a45abf91cfb441369e8bb6d1f5287382c1c526def3"}, - {file = "frozenlist-1.2.0-cp36-cp36m-win32.whl", hash = "sha256:c5328ed53fdb0a73c8a50105306a3bc013e5ca36cca714ec4f7bd31d38d8a97f"}, - {file = "frozenlist-1.2.0-cp36-cp36m-win_amd64.whl", hash = "sha256:9ade70aea559ca98f4b1b1e5650c45678052e76a8ab2f76d90f2ac64180215a2"}, - {file = "frozenlist-1.2.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:a0d3ffa8772464441b52489b985d46001e2853a3b082c655ec5fad9fb6a3d618"}, - {file = "frozenlist-1.2.0-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3457f8cf86deb6ce1ba67e120f1b0128fcba1332a180722756597253c465fc1d"}, - {file = "frozenlist-1.2.0-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:5a72eecf37eface331636951249d878750db84034927c997d47f7f78a573b72b"}, - {file = "frozenlist-1.2.0-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:acc4614e8d1feb9f46dd829a8e771b8f5c4b1051365d02efb27a3229048ade8a"}, - {file = "frozenlist-1.2.0-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:87521e32e18a2223311afc2492ef2d99946337da0779ddcda77b82ee7319df59"}, - {file = "frozenlist-1.2.0-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:8b4c7665a17c3a5430edb663e4ad4e1ad457614d1b2f2b7f87052e2ef4fa45ca"}, - {file = "frozenlist-1.2.0-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:ed58803563a8c87cf4c0771366cf0ad1aa265b6b0ae54cbbb53013480c7ad74d"}, - {file = "frozenlist-1.2.0-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:aa44c4740b4e23fcfa259e9dd52315d2b1770064cde9507457e4c4a65a04c397"}, - {file = "frozenlist-1.2.0-cp37-cp37m-musllinux_1_1_ppc64le.whl", hash = "sha256:2de5b931701257d50771a032bba4e448ff958076380b049fd36ed8738fdb375b"}, - {file = "frozenlist-1.2.0-cp37-cp37m-musllinux_1_1_s390x.whl", hash = "sha256:6e105013fa84623c057a4381dc8ea0361f4d682c11f3816cc80f49a1f3bc17c6"}, - {file = "frozenlist-1.2.0-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:705c184b77565955a99dc360f359e8249580c6b7eaa4dc0227caa861ef46b27a"}, - {file = "frozenlist-1.2.0-cp37-cp37m-win32.whl", hash = "sha256:a37594ad6356e50073fe4f60aa4187b97d15329f2138124d252a5a19c8553ea4"}, - {file = "frozenlist-1.2.0-cp37-cp37m-win_amd64.whl", hash = "sha256:25b358aaa7dba5891b05968dd539f5856d69f522b6de0bf34e61f133e077c1a4"}, - {file = "frozenlist-1.2.0-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:af2a51c8a381d76eabb76f228f565ed4c3701441ecec101dd18be70ebd483cfd"}, - {file = "frozenlist-1.2.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:82d22f6e6f2916e837c91c860140ef9947e31194c82aaeda843d6551cec92f19"}, - {file = "frozenlist-1.2.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:1cfe6fef507f8bac40f009c85c7eddfed88c1c0d38c75e72fe10476cef94e10f"}, - {file = "frozenlist-1.2.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:26f602e380a5132880fa245c92030abb0fc6ff34e0c5500600366cedc6adb06a"}, - {file = "frozenlist-1.2.0-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:4ad065b2ebd09f32511ff2be35c5dfafee6192978b5a1e9d279a5c6e121e3b03"}, - {file = "frozenlist-1.2.0-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:bc93f5f62df3bdc1f677066327fc81f92b83644852a31c6aa9b32c2dde86ea7d"}, - {file = "frozenlist-1.2.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:89fdfc84c6bf0bff2ff3170bb34ecba8a6911b260d318d377171429c4be18c73"}, - {file = "frozenlist-1.2.0-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:47b2848e464883d0bbdcd9493c67443e5e695a84694efff0476f9059b4cb6257"}, - {file = "frozenlist-1.2.0-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:4f52d0732e56906f8ddea4bd856192984650282424049c956857fed43697ea43"}, - {file = "frozenlist-1.2.0-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:16ef7dd5b7d17495404a2e7a49bac1bc13d6d20c16d11f4133c757dd94c4144c"}, - {file = "frozenlist-1.2.0-cp38-cp38-musllinux_1_1_ppc64le.whl", hash = "sha256:1cf63243bc5f5c19762943b0aa9e0d3fb3723d0c514d820a18a9b9a5ef864315"}, - {file = "frozenlist-1.2.0-cp38-cp38-musllinux_1_1_s390x.whl", hash = "sha256:54a1e09ab7a69f843cd28fefd2bcaf23edb9e3a8d7680032c8968b8ac934587d"}, - {file = "frozenlist-1.2.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:954b154a4533ef28bd3e83ffdf4eadf39deeda9e38fb8feaf066d6069885e034"}, - {file = "frozenlist-1.2.0-cp38-cp38-win32.whl", hash = "sha256:cb3957c39668d10e2b486acc85f94153520a23263b6401e8f59422ef65b9520d"}, - {file = "frozenlist-1.2.0-cp38-cp38-win_amd64.whl", hash = "sha256:0a7c7cce70e41bc13d7d50f0e5dd175f14a4f1837a8549b0936ed0cbe6170bf9"}, - {file = "frozenlist-1.2.0-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:4c457220468d734e3077580a3642b7f682f5fd9507f17ddf1029452450912cdc"}, - {file = "frozenlist-1.2.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:e74f8b4d8677ebb4015ac01fcaf05f34e8a1f22775db1f304f497f2f88fdc697"}, - {file = "frozenlist-1.2.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:fbd4844ff111449f3bbe20ba24fbb906b5b1c2384d0f3287c9f7da2354ce6d23"}, - {file = "frozenlist-1.2.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f0081a623c886197ff8de9e635528fd7e6a387dccef432149e25c13946cb0cd0"}, - {file = "frozenlist-1.2.0-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:9b6e21e5770df2dea06cb7b6323fbc008b13c4a4e3b52cb54685276479ee7676"}, - {file = "frozenlist-1.2.0-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:406aeb340613b4b559db78d86864485f68919b7141dec82aba24d1477fd2976f"}, - {file = "frozenlist-1.2.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:878ebe074839d649a1cdb03a61077d05760624f36d196884a5cafb12290e187b"}, - {file = "frozenlist-1.2.0-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:1fef737fd1388f9b93bba8808c5f63058113c10f4e3c0763ced68431773f72f9"}, - {file = "frozenlist-1.2.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:4a495c3d513573b0b3f935bfa887a85d9ae09f0627cf47cad17d0cc9b9ba5c38"}, - {file = "frozenlist-1.2.0-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:e7d0dd3e727c70c2680f5f09a0775525229809f1a35d8552b92ff10b2b14f2c2"}, - {file = "frozenlist-1.2.0-cp39-cp39-musllinux_1_1_ppc64le.whl", hash = "sha256:66a518731a21a55b7d3e087b430f1956a36793acc15912e2878431c7aec54210"}, - {file = "frozenlist-1.2.0-cp39-cp39-musllinux_1_1_s390x.whl", hash = "sha256:94728f97ddf603d23c8c3dd5cae2644fa12d33116e69f49b1644a71bb77b89ae"}, - {file = "frozenlist-1.2.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:c1e8e9033d34c2c9e186e58279879d78c94dd365068a3607af33f2bc99357a53"}, - {file = "frozenlist-1.2.0-cp39-cp39-win32.whl", hash = "sha256:83334e84a290a158c0c4cc4d22e8c7cfe0bba5b76d37f1c2509dabd22acafe15"}, - {file = "frozenlist-1.2.0-cp39-cp39-win_amd64.whl", hash = "sha256:735f386ec522e384f511614c01d2ef9cf799f051353876b4c6fb93ef67a6d1ee"}, - {file = "frozenlist-1.2.0.tar.gz", hash = "sha256:68201be60ac56aff972dc18085800b6ee07973c49103a8aba669dee3d71079de"}, -] greenlet = [ {file = "greenlet-1.1.2-cp27-cp27m-macosx_10_14_x86_64.whl", hash = "sha256:58df5c2a0e293bf665a51f8a100d3e9956febfbf1d9aaf8c0677cf70218910c6"}, {file = "greenlet-1.1.2-cp27-cp27m-manylinux1_x86_64.whl", hash = "sha256:aec52725173bd3a7b56fe91bc56eccb26fbdff1386ef123abb63c84c5b43b63a"}, @@ -1371,80 +1115,6 @@ mccabe = [ {file = "mccabe-0.6.1-py2.py3-none-any.whl", hash = "sha256:ab8a6258860da4b6677da4bd2fe5dc2c659cff31b3ee4f7f5d64e79735b80d42"}, {file = "mccabe-0.6.1.tar.gz", hash = "sha256:dd8d182285a0fe56bace7f45b5e7d1a6ebcbf524e8f3bd87eb0f125271b8831f"}, ] -multidict = [ - {file = "multidict-5.2.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:3822c5894c72e3b35aae9909bef66ec83e44522faf767c0ad39e0e2de11d3b55"}, - {file = "multidict-5.2.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:28e6d883acd8674887d7edc896b91751dc2d8e87fbdca8359591a13872799e4e"}, - {file = "multidict-5.2.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:b61f85101ef08cbbc37846ac0e43f027f7844f3fade9b7f6dd087178caedeee7"}, - {file = "multidict-5.2.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d9b668c065968c5979fe6b6fa6760bb6ab9aeb94b75b73c0a9c1acf6393ac3bf"}, - {file = "multidict-5.2.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:517d75522b7b18a3385726b54a081afd425d4f41144a5399e5abd97ccafdf36b"}, - {file = "multidict-5.2.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:1b4ac3ba7a97b35a5ccf34f41b5a8642a01d1e55454b699e5e8e7a99b5a3acf5"}, - {file = "multidict-5.2.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:df23c83398715b26ab09574217ca21e14694917a0c857e356fd39e1c64f8283f"}, - {file = "multidict-5.2.0-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:e58a9b5cc96e014ddf93c2227cbdeca94b56a7eb77300205d6e4001805391747"}, - {file = "multidict-5.2.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:f76440e480c3b2ca7f843ff8a48dc82446b86ed4930552d736c0bac507498a52"}, - {file = "multidict-5.2.0-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:cfde464ca4af42a629648c0b0d79b8f295cf5b695412451716531d6916461628"}, - {file = "multidict-5.2.0-cp310-cp310-musllinux_1_1_ppc64le.whl", hash = "sha256:0fed465af2e0eb6357ba95795d003ac0bdb546305cc2366b1fc8f0ad67cc3fda"}, - {file = "multidict-5.2.0-cp310-cp310-musllinux_1_1_s390x.whl", hash = "sha256:b70913cbf2e14275013be98a06ef4b412329fe7b4f83d64eb70dce8269ed1e1a"}, - {file = "multidict-5.2.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:a5635bcf1b75f0f6ef3c8a1ad07b500104a971e38d3683167b9454cb6465ac86"}, - {file = "multidict-5.2.0-cp310-cp310-win32.whl", hash = "sha256:77f0fb7200cc7dedda7a60912f2059086e29ff67cefbc58d2506638c1a9132d7"}, - {file = "multidict-5.2.0-cp310-cp310-win_amd64.whl", hash = "sha256:9416cf11bcd73c861267e88aea71e9fcc35302b3943e45e1dbb4317f91a4b34f"}, - {file = "multidict-5.2.0-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:fd77c8f3cba815aa69cb97ee2b2ef385c7c12ada9c734b0f3b32e26bb88bbf1d"}, - {file = "multidict-5.2.0-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:98ec9aea6223adf46999f22e2c0ab6cf33f5914be604a404f658386a8f1fba37"}, - {file = "multidict-5.2.0-cp36-cp36m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e5283c0a00f48e8cafcecadebfa0ed1dac8b39e295c7248c44c665c16dc1138b"}, - {file = "multidict-5.2.0-cp36-cp36m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5f79c19c6420962eb17c7e48878a03053b7ccd7b69f389d5831c0a4a7f1ac0a1"}, - {file = "multidict-5.2.0-cp36-cp36m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:e4a67f1080123de76e4e97a18d10350df6a7182e243312426d508712e99988d4"}, - {file = "multidict-5.2.0-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:94b117e27efd8e08b4046c57461d5a114d26b40824995a2eb58372b94f9fca02"}, - {file = "multidict-5.2.0-cp36-cp36m-musllinux_1_1_aarch64.whl", hash = "sha256:2e77282fd1d677c313ffcaddfec236bf23f273c4fba7cdf198108f5940ae10f5"}, - {file = "multidict-5.2.0-cp36-cp36m-musllinux_1_1_i686.whl", hash = "sha256:116347c63ba049c1ea56e157fa8aa6edaf5e92925c9b64f3da7769bdfa012858"}, - {file = "multidict-5.2.0-cp36-cp36m-musllinux_1_1_ppc64le.whl", hash = "sha256:dc3a866cf6c13d59a01878cd806f219340f3e82eed514485e094321f24900677"}, - {file = "multidict-5.2.0-cp36-cp36m-musllinux_1_1_s390x.whl", hash = "sha256:ac42181292099d91217a82e3fa3ce0e0ddf3a74fd891b7c2b347a7f5aa0edded"}, - {file = "multidict-5.2.0-cp36-cp36m-musllinux_1_1_x86_64.whl", hash = "sha256:f0bb0973f42ffcb5e3537548e0767079420aefd94ba990b61cf7bb8d47f4916d"}, - {file = "multidict-5.2.0-cp36-cp36m-win32.whl", hash = "sha256:ea21d4d5104b4f840b91d9dc8cbc832aba9612121eaba503e54eaab1ad140eb9"}, - {file = "multidict-5.2.0-cp36-cp36m-win_amd64.whl", hash = "sha256:e6453f3cbeb78440747096f239d282cc57a2997a16b5197c9bc839099e1633d0"}, - {file = "multidict-5.2.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:d3def943bfd5f1c47d51fd324df1e806d8da1f8e105cc7f1c76a1daf0f7e17b0"}, - {file = "multidict-5.2.0-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:35591729668a303a02b06e8dba0eb8140c4a1bfd4c4b3209a436a02a5ac1de11"}, - {file = "multidict-5.2.0-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ce8cacda0b679ebc25624d5de66c705bc53dcc7c6f02a7fb0f3ca5e227d80422"}, - {file = "multidict-5.2.0-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:baf1856fab8212bf35230c019cde7c641887e3fc08cadd39d32a421a30151ea3"}, - {file = "multidict-5.2.0-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:a43616aec0f0d53c411582c451f5d3e1123a68cc7b3475d6f7d97a626f8ff90d"}, - {file = "multidict-5.2.0-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:25cbd39a9029b409167aa0a20d8a17f502d43f2efebfe9e3ac019fe6796c59ac"}, - {file = "multidict-5.2.0-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:0a2cbcfbea6dc776782a444db819c8b78afe4db597211298dd8b2222f73e9cd0"}, - {file = "multidict-5.2.0-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:3d2d7d1fff8e09d99354c04c3fd5b560fb04639fd45926b34e27cfdec678a704"}, - {file = "multidict-5.2.0-cp37-cp37m-musllinux_1_1_ppc64le.whl", hash = "sha256:a37e9a68349f6abe24130846e2f1d2e38f7ddab30b81b754e5a1fde32f782b23"}, - {file = "multidict-5.2.0-cp37-cp37m-musllinux_1_1_s390x.whl", hash = "sha256:637c1896497ff19e1ee27c1c2c2ddaa9f2d134bbb5e0c52254361ea20486418d"}, - {file = "multidict-5.2.0-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:9815765f9dcda04921ba467957be543423e5ec6a1136135d84f2ae092c50d87b"}, - {file = "multidict-5.2.0-cp37-cp37m-win32.whl", hash = "sha256:8b911d74acdc1fe2941e59b4f1a278a330e9c34c6c8ca1ee21264c51ec9b67ef"}, - {file = "multidict-5.2.0-cp37-cp37m-win_amd64.whl", hash = "sha256:380b868f55f63d048a25931a1632818f90e4be71d2081c2338fcf656d299949a"}, - {file = "multidict-5.2.0-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:e7d81ce5744757d2f05fc41896e3b2ae0458464b14b5a2c1e87a6a9d69aefaa8"}, - {file = "multidict-5.2.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:2d1d55cdf706ddc62822d394d1df53573d32a7a07d4f099470d3cb9323b721b6"}, - {file = "multidict-5.2.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:a4771d0d0ac9d9fe9e24e33bed482a13dfc1256d008d101485fe460359476065"}, - {file = "multidict-5.2.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:da7d57ea65744d249427793c042094c4016789eb2562576fb831870f9c878d9e"}, - {file = "multidict-5.2.0-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:cdd68778f96216596218b4e8882944d24a634d984ee1a5a049b300377878fa7c"}, - {file = "multidict-5.2.0-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:ecc99bce8ee42dcad15848c7885197d26841cb24fa2ee6e89d23b8993c871c64"}, - {file = "multidict-5.2.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:067150fad08e6f2dd91a650c7a49ba65085303fcc3decbd64a57dc13a2733031"}, - {file = "multidict-5.2.0-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:78c106b2b506b4d895ddc801ff509f941119394b89c9115580014127414e6c2d"}, - {file = "multidict-5.2.0-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:e6c4fa1ec16e01e292315ba76eb1d012c025b99d22896bd14a66628b245e3e01"}, - {file = "multidict-5.2.0-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:b227345e4186809d31f22087d0265655114af7cda442ecaf72246275865bebe4"}, - {file = "multidict-5.2.0-cp38-cp38-musllinux_1_1_ppc64le.whl", hash = "sha256:06560fbdcf22c9387100979e65b26fba0816c162b888cb65b845d3def7a54c9b"}, - {file = "multidict-5.2.0-cp38-cp38-musllinux_1_1_s390x.whl", hash = "sha256:7878b61c867fb2df7a95e44b316f88d5a3742390c99dfba6c557a21b30180cac"}, - {file = "multidict-5.2.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:246145bff76cc4b19310f0ad28bd0769b940c2a49fc601b86bfd150cbd72bb22"}, - {file = "multidict-5.2.0-cp38-cp38-win32.whl", hash = "sha256:c30ac9f562106cd9e8071c23949a067b10211917fdcb75b4718cf5775356a940"}, - {file = "multidict-5.2.0-cp38-cp38-win_amd64.whl", hash = "sha256:f19001e790013ed580abfde2a4465388950728861b52f0da73e8e8a9418533c0"}, - {file = "multidict-5.2.0-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:c1ff762e2ee126e6f1258650ac641e2b8e1f3d927a925aafcfde943b77a36d24"}, - {file = "multidict-5.2.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:bd6c9c50bf2ad3f0448edaa1a3b55b2e6866ef8feca5d8dbec10ec7c94371d21"}, - {file = "multidict-5.2.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:fc66d4016f6e50ed36fb39cd287a3878ffcebfa90008535c62e0e90a7ab713ae"}, - {file = "multidict-5.2.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a9acb76d5f3dd9421874923da2ed1e76041cb51b9337fd7f507edde1d86535d6"}, - {file = "multidict-5.2.0-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:dfc924a7e946dd3c6360e50e8f750d51e3ef5395c95dc054bc9eab0f70df4f9c"}, - {file = "multidict-5.2.0-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:32fdba7333eb2351fee2596b756d730d62b5827d5e1ab2f84e6cbb287cc67fe0"}, - {file = "multidict-5.2.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:b9aad49466b8d828b96b9e3630006234879c8d3e2b0a9d99219b3121bc5cdb17"}, - {file = "multidict-5.2.0-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:93de39267c4c676c9ebb2057e98a8138bade0d806aad4d864322eee0803140a0"}, - {file = "multidict-5.2.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:f9bef5cff994ca3026fcc90680e326d1a19df9841c5e3d224076407cc21471a1"}, - {file = "multidict-5.2.0-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:5f841c4f14331fd1e36cbf3336ed7be2cb2a8f110ce40ea253e5573387db7621"}, - {file = "multidict-5.2.0-cp39-cp39-musllinux_1_1_ppc64le.whl", hash = "sha256:38ba256ee9b310da6a1a0f013ef4e422fca30a685bcbec86a969bd520504e341"}, - {file = "multidict-5.2.0-cp39-cp39-musllinux_1_1_s390x.whl", hash = "sha256:3bc3b1621b979621cee9f7b09f024ec76ec03cc365e638126a056317470bde1b"}, - {file = "multidict-5.2.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:6ee908c070020d682e9b42c8f621e8bb10c767d04416e2ebe44e37d0f44d9ad5"}, - {file = "multidict-5.2.0-cp39-cp39-win32.whl", hash = "sha256:1c7976cd1c157fa7ba5456ae5d31ccdf1479680dc9b8d8aa28afabc370df42b8"}, - {file = "multidict-5.2.0-cp39-cp39-win_amd64.whl", hash = "sha256:c9631c642e08b9fff1c6255487e62971d8b8e821808ddd013d8ac058087591ac"}, - {file = "multidict-5.2.0.tar.gz", hash = "sha256:0dd1c93edb444b33ba2274b66f63def8a327d607c6c790772f448a53b6ea59ce"}, -] mypy = [ {file = "mypy-0.910-cp35-cp35m-macosx_10_9_x86_64.whl", hash = "sha256:a155d80ea6cee511a3694b108c4494a39f42de11ee4e61e72bc424c490e46457"}, {file = "mypy-0.910-cp35-cp35m-manylinux1_x86_64.whl", hash = "sha256:b94e4b785e304a04ea0828759172a15add27088520dc7e49ceade7834275bedb"}, @@ -1568,13 +1238,12 @@ pytest = [ {file = "pytest-6.2.5-py3-none-any.whl", hash = "sha256:7310f8d27bc79ced999e760ca304d69f6ba6c6649c0b60fb0e04a4a77cacc134"}, {file = "pytest-6.2.5.tar.gz", hash = "sha256:131b36680866a76e6781d13f101efb86cf674ebb9762eb70d3082b6f29889e89"}, ] -pytest-asyncio = [ - {file = "pytest-asyncio-0.16.0.tar.gz", hash = "sha256:7496c5977ce88c34379df64a66459fe395cd05543f0a2f837016e7144391fcfb"}, - {file = "pytest_asyncio-0.16.0-py3-none-any.whl", hash = "sha256:5f2a21273c47b331ae6aa5b36087047b4899e40f03f18397c0e65fa5cca54e9b"}, +pytest-env = [ + {file = "pytest-env-0.6.2.tar.gz", hash = "sha256:7e94956aef7f2764f3c147d216ce066bf6c42948bb9e293169b1b1c880a580c2"}, ] -pytest-rerunfailures = [ - {file = "pytest-rerunfailures-10.2.tar.gz", hash = "sha256:9e1e1bad51e07642c5bbab809fc1d4ec8eebcb7de86f90f1a26e6ef9de446697"}, - {file = "pytest_rerunfailures-10.2-py3-none-any.whl", hash = "sha256:d31d8e828dfd39363ad99cd390187bf506c7a433a89f15c3126c7d16ab723fe2"}, +pytest-github-actions-annotate-failures = [ + {file = "pytest-github-actions-annotate-failures-0.1.6.tar.gz", hash = "sha256:162e2fe18b8ab24716c4c3a8d88c29aa67126dc75b4e54be54b58e6fa04653c2"}, + {file = "pytest_github_actions_annotate_failures-0.1.6-py2.py3-none-any.whl", hash = "sha256:5222dfa315c49d705912826335488ac1c75946c4b06782ab9a99379a7ee3af66"}, ] python-dateutil = [ {file = "python-dateutil-2.8.2.tar.gz", hash = "sha256:0123cacc1627ae19ddf3c27a5de5bd67ee4586fbdd6440d9748f8abb483d3e86"}, @@ -1792,77 +1461,3 @@ win32-setctime = [ {file = "win32_setctime-1.0.4-py3-none-any.whl", hash = "sha256:7964234073ad9bc7a689ef2ebe6ce931976b644fe73fd50cf7729c996b7d8385"}, {file = "win32_setctime-1.0.4.tar.gz", hash = "sha256:2b72b798fdc1d909fb3cc0d25e0be52a42f4848857e3588dd3947c6a18b42609"}, ] -yarl = [ - {file = "yarl-1.7.2-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:f2a8508f7350512434e41065684076f640ecce176d262a7d54f0da41d99c5a95"}, - {file = "yarl-1.7.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:da6df107b9ccfe52d3a48165e48d72db0eca3e3029b5b8cb4fe6ee3cb870ba8b"}, - {file = "yarl-1.7.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:a1d0894f238763717bdcfea74558c94e3bc34aeacd3351d769460c1a586a8b05"}, - {file = "yarl-1.7.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:dfe4b95b7e00c6635a72e2d00b478e8a28bfb122dc76349a06e20792eb53a523"}, - {file = "yarl-1.7.2-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:c145ab54702334c42237a6c6c4cc08703b6aa9b94e2f227ceb3d477d20c36c63"}, - {file = "yarl-1.7.2-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:1ca56f002eaf7998b5fcf73b2421790da9d2586331805f38acd9997743114e98"}, - {file = "yarl-1.7.2-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:1d3d5ad8ea96bd6d643d80c7b8d5977b4e2fb1bab6c9da7322616fd26203d125"}, - {file = "yarl-1.7.2-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:167ab7f64e409e9bdd99333fe8c67b5574a1f0495dcfd905bc7454e766729b9e"}, - {file = "yarl-1.7.2-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:95a1873b6c0dd1c437fb3bb4a4aaa699a48c218ac7ca1e74b0bee0ab16c7d60d"}, - {file = "yarl-1.7.2-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:6152224d0a1eb254f97df3997d79dadd8bb2c1a02ef283dbb34b97d4f8492d23"}, - {file = "yarl-1.7.2-cp310-cp310-musllinux_1_1_ppc64le.whl", hash = "sha256:5bb7d54b8f61ba6eee541fba4b83d22b8a046b4ef4d8eb7f15a7e35db2e1e245"}, - {file = "yarl-1.7.2-cp310-cp310-musllinux_1_1_s390x.whl", hash = "sha256:9c1f083e7e71b2dd01f7cd7434a5f88c15213194df38bc29b388ccdf1492b739"}, - {file = "yarl-1.7.2-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:f44477ae29025d8ea87ec308539f95963ffdc31a82f42ca9deecf2d505242e72"}, - {file = "yarl-1.7.2-cp310-cp310-win32.whl", hash = "sha256:cff3ba513db55cc6a35076f32c4cdc27032bd075c9faef31fec749e64b45d26c"}, - {file = "yarl-1.7.2-cp310-cp310-win_amd64.whl", hash = "sha256:c9c6d927e098c2d360695f2e9d38870b2e92e0919be07dbe339aefa32a090265"}, - {file = "yarl-1.7.2-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:9b4c77d92d56a4c5027572752aa35082e40c561eec776048330d2907aead891d"}, - {file = "yarl-1.7.2-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c01a89a44bb672c38f42b49cdb0ad667b116d731b3f4c896f72302ff77d71656"}, - {file = "yarl-1.7.2-cp36-cp36m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:c19324a1c5399b602f3b6e7db9478e5b1adf5cf58901996fc973fe4fccd73eed"}, - {file = "yarl-1.7.2-cp36-cp36m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3abddf0b8e41445426d29f955b24aeecc83fa1072be1be4e0d194134a7d9baee"}, - {file = "yarl-1.7.2-cp36-cp36m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:6a1a9fe17621af43e9b9fcea8bd088ba682c8192d744b386ee3c47b56eaabb2c"}, - {file = "yarl-1.7.2-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:8b0915ee85150963a9504c10de4e4729ae700af11df0dc5550e6587ed7891e92"}, - {file = "yarl-1.7.2-cp36-cp36m-musllinux_1_1_aarch64.whl", hash = "sha256:29e0656d5497733dcddc21797da5a2ab990c0cb9719f1f969e58a4abac66234d"}, - {file = "yarl-1.7.2-cp36-cp36m-musllinux_1_1_i686.whl", hash = "sha256:bf19725fec28452474d9887a128e98dd67eee7b7d52e932e6949c532d820dc3b"}, - {file = "yarl-1.7.2-cp36-cp36m-musllinux_1_1_ppc64le.whl", hash = "sha256:d6f3d62e16c10e88d2168ba2d065aa374e3c538998ed04996cd373ff2036d64c"}, - {file = "yarl-1.7.2-cp36-cp36m-musllinux_1_1_s390x.whl", hash = "sha256:ac10bbac36cd89eac19f4e51c032ba6b412b3892b685076f4acd2de18ca990aa"}, - {file = "yarl-1.7.2-cp36-cp36m-musllinux_1_1_x86_64.whl", hash = "sha256:aa32aaa97d8b2ed4e54dc65d241a0da1c627454950f7d7b1f95b13985afd6c5d"}, - {file = "yarl-1.7.2-cp36-cp36m-win32.whl", hash = "sha256:87f6e082bce21464857ba58b569370e7b547d239ca22248be68ea5d6b51464a1"}, - {file = "yarl-1.7.2-cp36-cp36m-win_amd64.whl", hash = "sha256:ac35ccde589ab6a1870a484ed136d49a26bcd06b6a1c6397b1967ca13ceb3913"}, - {file = "yarl-1.7.2-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:a467a431a0817a292121c13cbe637348b546e6ef47ca14a790aa2fa8cc93df63"}, - {file = "yarl-1.7.2-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6ab0c3274d0a846840bf6c27d2c60ba771a12e4d7586bf550eefc2df0b56b3b4"}, - {file = "yarl-1.7.2-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d260d4dc495c05d6600264a197d9d6f7fc9347f21d2594926202fd08cf89a8ba"}, - {file = "yarl-1.7.2-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:fc4dd8b01a8112809e6b636b00f487846956402834a7fd59d46d4f4267181c41"}, - {file = "yarl-1.7.2-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:c1164a2eac148d85bbdd23e07dfcc930f2e633220f3eb3c3e2a25f6148c2819e"}, - {file = "yarl-1.7.2-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:67e94028817defe5e705079b10a8438b8cb56e7115fa01640e9c0bb3edf67332"}, - {file = "yarl-1.7.2-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:89ccbf58e6a0ab89d487c92a490cb5660d06c3a47ca08872859672f9c511fc52"}, - {file = "yarl-1.7.2-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:8cce6f9fa3df25f55521fbb5c7e4a736683148bcc0c75b21863789e5185f9185"}, - {file = "yarl-1.7.2-cp37-cp37m-musllinux_1_1_ppc64le.whl", hash = "sha256:211fcd65c58bf250fb994b53bc45a442ddc9f441f6fec53e65de8cba48ded986"}, - {file = "yarl-1.7.2-cp37-cp37m-musllinux_1_1_s390x.whl", hash = "sha256:c10ea1e80a697cf7d80d1ed414b5cb8f1eec07d618f54637067ae3c0334133c4"}, - {file = "yarl-1.7.2-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:52690eb521d690ab041c3919666bea13ab9fbff80d615ec16fa81a297131276b"}, - {file = "yarl-1.7.2-cp37-cp37m-win32.whl", hash = "sha256:695ba021a9e04418507fa930d5f0704edbce47076bdcfeeaba1c83683e5649d1"}, - {file = "yarl-1.7.2-cp37-cp37m-win_amd64.whl", hash = "sha256:c17965ff3706beedafd458c452bf15bac693ecd146a60a06a214614dc097a271"}, - {file = "yarl-1.7.2-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:fce78593346c014d0d986b7ebc80d782b7f5e19843ca798ed62f8e3ba8728576"}, - {file = "yarl-1.7.2-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:c2a1ac41a6aa980db03d098a5531f13985edcb451bcd9d00670b03129922cd0d"}, - {file = "yarl-1.7.2-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:39d5493c5ecd75c8093fa7700a2fb5c94fe28c839c8e40144b7ab7ccba6938c8"}, - {file = "yarl-1.7.2-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1eb6480ef366d75b54c68164094a6a560c247370a68c02dddb11f20c4c6d3c9d"}, - {file = "yarl-1.7.2-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:5ba63585a89c9885f18331a55d25fe81dc2d82b71311ff8bd378fc8004202ff6"}, - {file = "yarl-1.7.2-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e39378894ee6ae9f555ae2de332d513a5763276a9265f8e7cbaeb1b1ee74623a"}, - {file = "yarl-1.7.2-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:c0910c6b6c31359d2f6184828888c983d54d09d581a4a23547a35f1d0b9484b1"}, - {file = "yarl-1.7.2-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:6feca8b6bfb9eef6ee057628e71e1734caf520a907b6ec0d62839e8293e945c0"}, - {file = "yarl-1.7.2-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:8300401dc88cad23f5b4e4c1226f44a5aa696436a4026e456fe0e5d2f7f486e6"}, - {file = "yarl-1.7.2-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:788713c2896f426a4e166b11f4ec538b5736294ebf7d5f654ae445fd44270832"}, - {file = "yarl-1.7.2-cp38-cp38-musllinux_1_1_ppc64le.whl", hash = "sha256:fd547ec596d90c8676e369dd8a581a21227fe9b4ad37d0dc7feb4ccf544c2d59"}, - {file = "yarl-1.7.2-cp38-cp38-musllinux_1_1_s390x.whl", hash = "sha256:737e401cd0c493f7e3dd4db72aca11cfe069531c9761b8ea474926936b3c57c8"}, - {file = "yarl-1.7.2-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:baf81561f2972fb895e7844882898bda1eef4b07b5b385bcd308d2098f1a767b"}, - {file = "yarl-1.7.2-cp38-cp38-win32.whl", hash = "sha256:ede3b46cdb719c794427dcce9d8beb4abe8b9aa1e97526cc20de9bd6583ad1ef"}, - {file = "yarl-1.7.2-cp38-cp38-win_amd64.whl", hash = "sha256:cc8b7a7254c0fc3187d43d6cb54b5032d2365efd1df0cd1749c0c4df5f0ad45f"}, - {file = "yarl-1.7.2-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:580c1f15500e137a8c37053e4cbf6058944d4c114701fa59944607505c2fe3a0"}, - {file = "yarl-1.7.2-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:3ec1d9a0d7780416e657f1e405ba35ec1ba453a4f1511eb8b9fbab81cb8b3ce1"}, - {file = "yarl-1.7.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:3bf8cfe8856708ede6a73907bf0501f2dc4e104085e070a41f5d88e7faf237f3"}, - {file = "yarl-1.7.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1be4bbb3d27a4e9aa5f3df2ab61e3701ce8fcbd3e9846dbce7c033a7e8136746"}, - {file = "yarl-1.7.2-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:534b047277a9a19d858cde163aba93f3e1677d5acd92f7d10ace419d478540de"}, - {file = "yarl-1.7.2-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:c6ddcd80d79c96eb19c354d9dca95291589c5954099836b7c8d29278a7ec0bda"}, - {file = "yarl-1.7.2-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:9bfcd43c65fbb339dc7086b5315750efa42a34eefad0256ba114cd8ad3896f4b"}, - {file = "yarl-1.7.2-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:f64394bd7ceef1237cc604b5a89bf748c95982a84bcd3c4bbeb40f685c810794"}, - {file = "yarl-1.7.2-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:044daf3012e43d4b3538562da94a88fb12a6490652dbc29fb19adfa02cf72eac"}, - {file = "yarl-1.7.2-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:368bcf400247318382cc150aaa632582d0780b28ee6053cd80268c7e72796dec"}, - {file = "yarl-1.7.2-cp39-cp39-musllinux_1_1_ppc64le.whl", hash = "sha256:bab827163113177aee910adb1f48ff7af31ee0289f434f7e22d10baf624a6dfe"}, - {file = "yarl-1.7.2-cp39-cp39-musllinux_1_1_s390x.whl", hash = "sha256:0cba38120db72123db7c58322fa69e3c0efa933040ffb586c3a87c063ec7cae8"}, - {file = "yarl-1.7.2-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:59218fef177296451b23214c91ea3aba7858b4ae3306dde120224cfe0f7a6ee8"}, - {file = "yarl-1.7.2-cp39-cp39-win32.whl", hash = "sha256:1edc172dcca3f11b38a9d5c7505c83c1913c0addc99cd28e993efeaafdfaa18d"}, - {file = "yarl-1.7.2-cp39-cp39-win_amd64.whl", hash = "sha256:797c2c412b04403d2da075fb93c123df35239cd7b4cc4e0cd9e5839b73f52c58"}, - {file = "yarl-1.7.2.tar.gz", hash = "sha256:45399b46d60c253327a460e99856752009fcee5f5d3c80b2f7c0cae1c38d56dd"}, -] diff --git a/pol/api/v0/models.py b/pol/api/v0/models.py index a54d9dd41..9714a65c3 100644 --- a/pol/api/v0/models.py +++ b/pol/api/v0/models.py @@ -1,27 +1,81 @@ -from typing import Any, Dict, Optional +import enum +import datetime +from typing import Any, Dict, List, Optional from pydantic import Field, BaseModel +from pol.db.const import BloodType, PersonType -class PersonRole(BaseModel): - producer: bool - mangaka: bool - artist: bool - seiyu: bool - writer: bool - illustrator: bool - actor: bool +class PersonCareer(str, enum.Enum): + producer = "producer" + mangaka = "mangaka" + artist = "artist" + seiyu = "seiyu" + writer = "writer" + illustrator = "illustrator" + actor = "actor" -class Person(BaseModel): + +class SubjectInfo(BaseModel): + id: int = Field(..., alias="subject_id") + staff: str + name: Optional[str] = Field(None, alias="subject_name") + name_cn: str = Field(..., alias="subject_name_cn") + image: Optional[str] = Field(alias="subject_image") + + +class Stat(BaseModel): + comments: int + collects: int + + +class BasePerson(BaseModel): id: int name: str - type: int - infobox: str - wiki: Optional[Dict[str, Any]] = Field( + type: PersonType + career: List[PersonCareer] + locked: bool + + img: Optional[str] = None + + +class Person(BasePerson): + short_summary: str + + +class PagedPerson(BaseModel): + total: int + limit: int + offset: int + data: List[Person] + + +class PersonDetail(BasePerson): + career: List[PersonCareer] + summary: str + locked: bool + last_modified: datetime.datetime + + infobox: Optional[List[Dict[str, Any]]] = Field( None, - description="server parsed infobox, a map from key to string or tuple", + description=( + "server parsed infobox, a map from key to string or tuple\n" + "null if server infobox is not valid" + ), ) - role: PersonRole - summary: str - img: Optional[str] + + img: Optional[str] = None + + gender: Optional[str] = Field(None, description="parsed from wiki, maybe null") + blood_type: Optional[BloodType] = Field( + description="parsed from wiki, maybe null, `1, 2, 3, 4` for `A, B, CD, O`" + ) + birth_year: Optional[int] = Field(None, description="parsed from wiki, maybe null") + birth_mon: Optional[int] = Field(None, description="parsed from wiki, maybe null") + birth_day: Optional[int] = Field(None, description="parsed from wiki, maybe null") + + stat: Stat + + # class Config: + # use_enum_values = True diff --git a/pol/api/v0/person.py b/pol/api/v0/person.py index e9f185b53..255f7affd 100644 --- a/pol/api/v0/person.py +++ b/pol/api/v0/person.py @@ -1,50 +1,290 @@ -from fastapi import Depends, APIRouter, HTTPException +import enum +from typing import Dict, List, Optional + +import pydantic +from fastapi import Path, Query, Depends, Request, APIRouter +from pydantic import Field from databases import Database +from fastapi.exceptions import RequestValidationError from starlette.responses import RedirectResponse +from pydantic.error_wrappers import ErrorWrapper from pol import res, curd, wiki -from pol.utils import imgUrl +from pol.utils import person_img_url, subject_img_url from pol.api.v0 import models from pol.models import ErrorDetail from pol.depends import get_db -from pol.db.tables import ChiiPerson +from pol.db.const import Gender, StaffMap, BloodType, PersonType, get_staff +from pol.db.tables import ChiiPerson, ChiiSubject, ChiiPersonField, ChiiPersonCsIndex +from pol.db_models import sa +from pol.api.v0.models import PersonCareer from pol.curd.exceptions import NotFoundError -router = APIRouter() +router = APIRouter(tags=["人物"]) + +api_base = "/api/v0/persons" + + +async def basic_person( + request: Request, + person_id: int = Path(..., gt=0), + db: Database = Depends(get_db), +) -> ChiiPerson: + try: + return await curd.get_one( + db, + ChiiPerson, + ChiiPerson.prsn_id == person_id, + ChiiPerson.prsn_ban != 1, + ) + except NotFoundError: + raise res.HTTPException( + status_code=404, + title="Not Found", + description="resource you resource can't be found in the database", + detail={"person_id": request.path_params.get("person_id")}, + ) + + +class Pager(pydantic.BaseModel): + limit: int = Field(30, gt=0, le=50) + offset: int = Field(0, ge=0) + + +class Sort(str, enum.Enum): + id = "id" + name = "name" + last_modified = "update" + + +class Order(enum.IntEnum): + asc = 1 + desc = -1 + + +@router.get( + "/persons", + response_model=models.PagedPerson, +) +async def get_persons( + db: Database = Depends(get_db), + page: Pager = Depends(), + name: Optional[str] = None, + type: Optional[PersonType] = Query(None, description="1为个人,2为公司,3为组合"), + career: Optional[List[PersonCareer]] = Query( + None, example="?career=mangaka&career=producer" + ), + sort: Sort = Sort.id, + order: Order = Order.desc, +): + query = sa.select(sa.func.count(ChiiPerson.prsn_id)).where( + ChiiPerson.prsn_ban == 0, ChiiPerson.prsn_redirect == 0 + ) + if name is not None: + query = query.where(ChiiPerson.prsn_name.contains(name)) + + if type: + query = query.where(ChiiPerson.prsn_type == type) + + career_filter = None + if career: + q = [] + for c in career: + q.append(getattr(ChiiPerson, f"prsn_{c}") == 1) + career_filter = sa.or_(*q) + query = query.where(career_filter) + + count = await db.fetch_val(query) + if page.offset > count: + raise RequestValidationError( + [ + ErrorWrapper( + ValueError(f"offset is too big, must be less than {count}"), + loc=("query", "offset"), + ) + ] + ) + + query = ( + sa.select( + ChiiPerson.prsn_id, + ChiiPerson.prsn_name, + ChiiPerson.prsn_type, + ChiiPerson.prsn_img, + ChiiPerson.prsn_summary, + ChiiPerson.prsn_producer, + ChiiPerson.prsn_mangaka, + ChiiPerson.prsn_actor, + ChiiPerson.prsn_lock, + ChiiPerson.prsn_artist, + ChiiPerson.prsn_seiyu, + ChiiPerson.prsn_writer, + ChiiPerson.prsn_illustrator, + ) + .where(ChiiPerson.prsn_ban == 0, ChiiPerson.prsn_redirect == 0) + .limit(page.limit) + .offset(page.offset) + ) + + if name is not None: + query = query.where(ChiiPerson.prsn_name.contains(name)) + + if career_filter is not None: + query = query.where(career_filter) + + sort_field = ChiiPerson.prsn_id + + if sort == Sort.name: + sort_field = ChiiPerson.prsn_name + if sort == Sort.last_modified: + sort_field = ChiiPerson.prsn_lastpost + + if order > 0: + sort_field = sort_field.asc() + else: + sort_field = sort_field.desc() + + query = query.order_by(sort_field) + + persons = [ + { + "id": r["prsn_id"], + "name": r["prsn_name"], + "type": r["prsn_type"], + "career": get_career(r), + "short_summary": r["prsn_summary"][:80] + "...", + "locked": r["prsn_lock"], + "img": person_img_url(r["prsn_img"]), + } + for r in await db.fetch_all(query) + ] + + return {"limit": page.limit, "offset": page.offset, "total": count, "data": persons} @router.get( - "/person/{person_id}", - response_model=models.Person, + "/persons/{person_id}", + response_model=models.PersonDetail, + response_model_by_alias=False, responses={ 404: res.response(model=ErrorDetail), }, ) -async def bgm_ip_map( - person_id: int, +async def get_person( db: Database = Depends(get_db), + person: ChiiPerson = Depends(basic_person), ): + if person.prsn_redirect: + return RedirectResponse(f"{api_base}/{person.prsn_redirect}") + + data = { + "id": person.prsn_id, + "name": person.prsn_name, + "type": person.prsn_type, + "career": get_career(person), + "summary": person.prsn_summary, + "img": person_img_url(person.prsn_img), + "locked": person.prsn_lock, + "last_modified": person.prsn_lastpost, + "stat": { + "comments": person.prsn_comment, + "collects": person.prsn_collects, + }, + } + try: - person = await curd.get_one(db, ChiiPerson, ChiiPerson.prsn_id == person_id) + field = await curd.get_one( + db, + ChiiPersonField, + ChiiPersonField.prsn_id == person.prsn_id, + ChiiPersonField.prsn_cat == "prsn", + ) + data["gender"] = Gender.to_view(field.gender) + data["blood_type"] = BloodType.to_view(field.bloodtype) + data["birth_year"] = field.birth_year or None + data["birth_mon"] = field.birth_mon or None + data["birth_day"] = field.birth_day or None except NotFoundError: - raise HTTPException(status_code=404, detail="person not found") - - if person.prsn_redirect: - return RedirectResponse(str(person.prsn_redirect)) - - m = models.Person( - id=person.prsn_id, - name=person.prsn_name, - type=person.prsn_type, - infobox=person.prsn_infobox, - role=person.role(), - summary=person.prsn_summary, - img=imgUrl(person.prsn_img), - ) + pass try: - m.wiki = wiki.parse(person.prsn_infobox).info + data["infobox"] = wiki.parse(person.prsn_infobox).info except wiki.WikiSyntaxError: pass - return m + return data + + +@router.get( + "/persons/{person_id}/subjects", + summary="get person related subjects", + response_model=List[models.SubjectInfo], + response_model_by_alias=False, + responses={ + 404: res.response(model=ErrorDetail), + }, +) +async def get_person_subjects( + db: Database = Depends(get_db), + person: ChiiPerson = Depends(basic_person), +): + if person.prsn_redirect: + return RedirectResponse(f"{api_base}/{person.prsn_redirect}/subjects") + + query = ( + sa.select( + ChiiPersonCsIndex.subject_id, + ChiiPersonCsIndex.prsn_position, + ChiiPersonCsIndex.subject_type_id, + ) + .where(ChiiPersonCsIndex.prsn_id == person.prsn_id) + .distinct() + .order_by(ChiiPersonCsIndex.subject_id) + ) + + result: Dict[int, ChiiPersonCsIndex] = { + r["subject_id"]: ChiiPersonCsIndex(**r) for r in await db.fetch_all(query) + } + + if not result: + res.HTTPException( + status_code=404, + title="Not Found", + description="person doesn't relative to any subjects", + detail={"person_id": person.prsn_id}, + ) + + query = sa.select( + ChiiSubject.subject_id, + ChiiSubject.subject_name, + ChiiSubject.subject_name_cn, + ChiiSubject.subject_image, + ).where(ChiiSubject.subject_id.in_(result.keys())) + + subjects = [dict(r) for r in await db.fetch_all(query)] + + for s in subjects: + s["subject_image"] = subject_img_url(s["subject_image"]) + rel = result[s["subject_id"]] + s["staff"] = get_staff(StaffMap[rel.subject_type_id][rel.prsn_position]) + + return subjects + + +def get_career(p: ChiiPerson) -> List[str]: + s = [] + if p.prsn_producer: + s.append("producer") + if p.prsn_mangaka: + s.append("mangaka") + if p.prsn_artist: + s.append("artist") + if p.prsn_seiyu: + s.append("seiyu") + if p.prsn_writer: + s.append("writer") + if p.prsn_illustrator: + s.append("illustrator") + if p.prsn_actor: + s.append("actor") + return s diff --git a/pol/curd/__init__.py b/pol/curd/__init__.py index 3273abab8..49dd1ded3 100644 --- a/pol/curd/__init__.py +++ b/pol/curd/__init__.py @@ -3,15 +3,14 @@ from databases import Database from sqlalchemy.orm import DeclarativeMeta -from . import person from ..db_models import sa from .exceptions import NotFoundError T = TypeVar("T", bound=DeclarativeMeta) -async def get_one(db: Database, t: Type[T], where) -> T: - query = sa.select(t).where(where).limit(1) +async def get_one(db: Database, t: Type[T], *where) -> T: + query = sa.select(t).where(*where).limit(1) r = await db.fetch_one(query) if r: @@ -20,4 +19,4 @@ async def get_one(db: Database, t: Type[T], where) -> T: raise NotFoundError() -__all__ = ["person", "get_one"] +__all__ = ["get_one"] diff --git a/pol/curd/person.py b/pol/curd/person.py deleted file mode 100644 index 3cae4c3d2..000000000 --- a/pol/curd/person.py +++ /dev/null @@ -1,15 +0,0 @@ -from databases import Database - -from pol.db import tables -from pol.db_models import sa -from pol.curd.exceptions import NotFoundError - - -async def get_by_id(db: Database, id: int) -> tables.ChiiPerson: - query = sa.select(tables.ChiiPerson).where(tables.ChiiPerson.prsn_id == id).limit(1) - r = await db.fetch_one(query) - - if r: - return tables.ChiiPerson(**r) - - raise NotFoundError() diff --git a/pol/db/_const.py b/pol/db/_const.py new file mode 100644 index 000000000..314884694 --- /dev/null +++ b/pol/db/_const.py @@ -0,0 +1,168 @@ +from typing import Optional, NamedTuple + + +class Staff(NamedTuple): + cn: str + jp: str + en: str + rdf: Optional[str] = None + + +staff_job_real = { + 4001: Staff(cn="原作", jp="", en="creator"), + 4002: Staff(cn="导演", jp="", en="director"), + 4013: Staff(cn="创意总监", jp="", en="creative director"), + 4003: Staff(cn="编剧", jp="", en="writer"), + 4004: Staff(cn="音乐", jp="", en="composer"), + 4005: Staff(cn="执行制片人", jp="製作総指揮", en="executive producer"), + 4006: Staff(cn="共同执行制作", jp="", en="co exec "), + 4007: Staff(cn="制片人/制作人", jp="プロデューサー", en="producer"), + 4008: Staff(cn="监制", jp="", en="supervising producer"), + 4009: Staff(cn="副制作人/制作顾问", jp="", en="consulting producer"), + 4010: Staff(cn="故事", jp="", en="story"), + 4011: Staff(cn="编审", jp="", en="story editor"), + 4012: Staff(cn="剪辑", jp="", en="editor"), + 4014: Staff(cn="摄影", jp="", en="cinematography"), + 4015: Staff(cn="主题歌演出", jp="", en="Theme Song Performance"), + 4016: Staff(cn="主演", jp="", en="Actor"), + 4017: Staff(cn="配角", jp="", en="Supporting Actor"), + 4018: Staff(cn="制作", jp="製作 製作スタジオ", en="Production"), +} + +staff_job_music = { + 3001: Staff(cn="艺术家", jp="", en=""), + 3002: Staff(cn="制作人", jp="", en=""), + 3003: Staff(cn="作曲", jp="", en=""), + 3006: Staff(cn="作词", jp="", en="Lyric"), + 3008: Staff(cn="编曲", jp="", en="Arrange"), + 3009: Staff(cn="插图", jp="", en=""), + 3007: Staff(cn="录音", jp="", en=""), + 3004: Staff(cn="厂牌", jp="", en="Label"), + 3005: Staff(cn="原作", jp="", en="Original Creator/Original Work"), + 3010: Staff(cn="脚本", jp="シナリオ", en="Scenario"), +} + +staff_job_book = { + 2007: Staff(cn="原作", jp="", en="Original Creator/Original Work"), + 2001: Staff(cn="作者", jp="", en=""), + 2002: Staff(cn="", jp="作画", en=""), + 2003: Staff(cn="插图", jp="イラスト", en=""), + 2004: Staff(cn="", jp="出版社", en=""), + 2005: Staff(cn="连载杂志", jp="掲載誌", en=""), + 2006: Staff(cn="译者", jp="", en=""), + 2008: Staff(cn="客串", jp="ゲスト", en="guest"), + 2009: Staff(cn="人物原案", jp="キャラクター原案", en="Original Character Design"), +} + +staff_job_game = { + 1001: Staff(cn="开发", jp="開発元", en="developer"), + 1002: Staff(cn="发行", jp="発売元", en="publisher"), + 1003: Staff(cn="遊戲設計師", jp="ゲームクリエイター", en="game designer"), + 1015: Staff(cn="原作", jp="", en=""), + 1016: Staff(cn="导演", jp="監督 演出 シリーズ監督", en="Director/Direction"), + 1032: Staff(cn="制作人", jp="プロデューサー", en="Producer"), + 1028: Staff(cn="企画", jp="", en=""), + 1026: Staff(cn="监修", jp="監修", en=""), + 1004: Staff(cn="剧本", jp="腳本", en=""), + 1027: Staff(cn="系列构成", jp="シリーズ構成", en=""), + 1031: Staff(cn="作画监督", jp="作画監督", en=""), + 1013: Staff(cn="原画", jp="", en=""), + 1008: Staff(cn="人物设定", jp="キャラ設定 キャラクターデザイン", en="Character Design"), + 1029: Staff(cn="机械设定", jp="メカニック設定", en="Mechanical Design"), + 1005: Staff(cn="美工", jp="美術", en=""), + 1023: Staff(cn="CG监修", jp="CG監修", en=""), + 1024: Staff(cn="SD原画", jp="", en=""), + 1025: Staff(cn="背景", jp="", en=""), + 1030: Staff(cn="音响监督", jp="", en="Sound Director"), + 1006: Staff(cn="音乐", jp="音楽", en=""), + 1021: Staff(cn="程序", jp="プログラム", en="Program"), + 1014: Staff(cn="动画制作", jp="アニメーション制作 アニメ制作 アニメーション", en="Animation Work"), + 1017: Staff(cn="动画监督", jp="アニメーション監督", en=""), + 1020: Staff(cn="动画剧本", jp="アニメーション脚本", en=""), + 1018: Staff(cn="制作总指挥", jp="", en=""), + 1019: Staff(cn="QC", jp="", en="QC"), + 1007: Staff(cn="关卡设计", jp="", en=""), + 1009: Staff(cn="主题歌作曲", jp="", en="Theme Song Composition"), + 1010: Staff(cn="主题歌作词", jp="", en="Theme Song Lyrics"), + 1011: Staff(cn="主题歌演出", jp="", en="Theme Song Performance"), + 1012: Staff(cn="插入歌演出", jp="", en="Inserted Song Performance"), + 1022: Staff(cn="协力", jp="協力", en=""), +} + +staff_job_anime = { + 1: Staff(cn="原作", jp="", en="Original Creator/Original Work"), + 74: Staff(cn="总导演", jp="総監督", en="Chief Director"), + 2: Staff(cn="导演", jp="監督 シリーズ監督", en="Director/Direction", rdf="directedBy"), + 3: Staff(cn="脚本", jp="シナリオ", en="Script/Screenplay"), + 4: Staff(cn="分镜", jp="コンテ ストーリーボード 画コンテ 絵コンテ", en="Storyboard"), + 5: Staff(cn="演出", jp="", en="Episode Director"), + 6: Staff(cn="音乐", jp="楽曲 音楽", en="Music"), + 7: Staff(cn="人物原案", jp="キャラ原案", en="Original Character Design"), + 8: Staff(cn="人物设定", jp="キャラ設定", en="Character Design"), + 9: Staff(cn="分镜构图", jp="レイアウト", en="Layout"), + 10: Staff(cn="系列构成", jp="シナリオディレクター 構成 シリーズ構成 脚本構成", en="Series Composition"), + 72: Staff(cn="副导演", jp="助監督", en="Assistant director"), + 11: Staff(cn="美术监督", jp="アートディレクション 背景監督", en="Art Direction"), + 71: Staff(cn="美术设计", jp="美術設定", en="Art Design"), + 13: Staff(cn="色彩设计", jp="色彩設定", en="Color Design"), + 14: Staff(cn="总作画监督", jp="チーフ作画監督", en="Chief Animation Director"), + 15: Staff(cn="作画监督", jp="作監 アニメーション演出", en="Animation Direction"), + 70: Staff(cn="机械作画监督", jp="メカニック作監", en="Mechanical Animation Direction"), + 77: Staff(cn="动作作画监督", jp="アクション作画監督", en="Action Animation Direction"), + 16: Staff(cn="机械设定", jp="メカニック設定", en="Mechanical Design"), + 17: Staff(cn="摄影监督", jp="撮影監督", en="Director of Photography"), + 69: Staff(cn="CG 导演", jp="CG 監督", en="CG Director"), + 18: Staff(cn="监修", jp="シリーズ監修 スーパーバイザー", en="Supervision/Supervisor"), + 19: Staff(cn="道具设计", jp="プロップデザイン", en="Prop Design"), + 20: Staff(cn="原画", jp="作画 原画", en="Key Animation"), + 21: Staff(cn="第二原画", jp="原画協力", en="2nd Key Animation"), + 22: Staff(cn="动画检查", jp="動画チェック", en="Animation Check"), + 63: Staff(cn="制作", jp="製作 製作スタジオ", en="Production"), + 67: Staff(cn="动画制作", jp="アニメーション制作 アニメ制作 アニメーション", en="Animation Work"), + 73: Staff(cn="OP・ED 分镜", jp="OP・ED 分鏡", en="OP ED"), + 65: Staff(cn="音乐制作", jp="楽曲制作 音楽制作", en="Music Work"), + 23: Staff(cn="助理制片人", jp="協力プロデューサー", en="Assistant Producer"), + 24: Staff(cn="", jp="アソシエイトプロデューサー", en="Associate Producer"), + 25: Staff(cn="背景美术", jp="背景", en="Background Art"), + 26: Staff(cn="色彩指定", jp="", en="Color Setting"), + 27: Staff(cn="数码绘图", jp="", en="Digital Paint"), + 75: Staff(cn="3DCG", jp="", en="3DCG"), + 37: Staff(cn="制作管理", jp="制作マネージャー 制作担当 制作班長", en="Production Manager"), + 28: Staff(cn="剪辑", jp="編集", en="Editing"), + 29: Staff(cn="原案", jp="", en="Original Plan"), + 30: Staff(cn="主题歌编曲", jp="", en="Theme Song Arrangement"), + 31: Staff(cn="主题歌作曲", jp="", en="Theme Song Composition"), + 32: Staff(cn="主题歌作词", jp="", en="Theme Song Lyrics"), + 33: Staff(cn="主题歌演出", jp="", en="Theme Song Performance"), + 34: Staff(cn="插入歌演出", jp="", en="Inserted Song Performance"), + 35: Staff(cn="企画", jp="プランニング 企画開発", en="Planning"), + 36: Staff(cn="", jp="企画プロデューサー 企画営業プロデューサー", en="Planning Producer"), + 38: Staff(cn="宣传", jp="パブリシティ 宣伝 広告宣伝 番組宣伝 製作宣伝", en="Publicity"), + 39: Staff(cn="录音", jp="録音", en="Recording"), + 40: Staff(cn="录音助理", jp="録音アシスタント 録音助手", en="Recording Assistant"), + 41: Staff(cn="系列监督", jp="", en="Series Production Director"), + 42: Staff(cn="製作", jp="", en="Production"), + 43: Staff(cn="设定", jp="設定", en="Setting"), + 44: Staff(cn="音响监督", jp="", en="Sound Director"), + 45: Staff(cn="音响", jp="音響", en="Sound"), + 46: Staff(cn="音效", jp="音響効果", en="Sound Effects"), + 47: Staff(cn="特效", jp="視覚効果", en="Special Effects"), + 48: Staff(cn="配音监督", jp="", en="ADR Director"), + 49: Staff(cn="联合导演", jp="", en="Co-Director"), + 50: Staff(cn="背景设定", jp="基本設定 場面設定 場面設計 設定", en="Setting"), + 51: Staff(cn="补间动画", jp="動画", en="In-Between Animation"), + 52: Staff(cn="执行制片人", jp="製作総指揮", en="Executive Producer"), + 53: Staff(cn="助理制片人", jp="協力プロデューサー", en="Assistant Producer"), + 54: Staff(cn="制片人", jp="プロデュース プロデューサー", en="Producer"), + 55: Staff(cn="助理录音师", jp="", en="Assistant Engineer"), + 56: Staff(cn="助理制片协调", jp="", en="Assistant Production Coordinat"), + 57: Staff(cn="演员监督", jp="キャスティングコーディネーター監督", en="Casting Director"), + 58: Staff(cn="总制片", jp="チーフプロデューサー チーフ制作 総合プロデューサー", en="Chief Producer"), + 59: Staff(cn="联合制片人", jp="", en="Co-Producer"), + 60: Staff(cn="台词编辑", jp="台詞編集", en="Dialogue Editing"), + 61: Staff(cn="后期制片协调", jp="ポストプロダクション協力", en="Post-Production Assistant"), + 62: Staff(cn="制作助手", jp="制作アシスタント 制作補佐 製作補", en="Production Assistant"), + 64: Staff(cn="制作协调", jp="制作コーディネーター", en="Production Coordination"), + 76: Staff(cn="制作协力", jp="制作協力 / 作品協力", en="Work Assistance"), + 66: Staff(cn="友情協力", jp="特别鸣谢", en="Special Thanks"), +} diff --git a/pol/db/const.py b/pol/db/const.py new file mode 100644 index 000000000..aee9e1268 --- /dev/null +++ b/pol/db/const.py @@ -0,0 +1,82 @@ +import enum +from typing import TYPE_CHECKING, Optional + +from pol.db._const import ( + Staff, + staff_job_book, + staff_job_game, + staff_job_real, + staff_job_anime, + staff_job_music, +) + + +class ViewMixin: + if TYPE_CHECKING: + + def __init__(self, v): + pass + + @classmethod + def to_view(cls, v: Optional[int]) -> Optional[str]: + if not v: + return None + return str(cls(v)) + + +class BloodType(int, ViewMixin, enum.Enum): + a = 1 + b = 2 + ab = 3 + o = 4 + + def __str__(self): + try: + return {1: "A", 2: "B", 3: "AB", 4: "O"}[self.value] + except KeyError: + raise ValueError(f"{self.value} is not valid blood type") + + +class PersonType(int, ViewMixin, enum.Enum): + person = 1 + company = 2 + band = 3 + + def __str__(self): + try: + return {1: "个人", 2: "公司", 3: "组合"}[self.value] + except KeyError: + raise ValueError(f"{self.value} is not valid person record type") + + +class Gender(int, ViewMixin, enum.Enum): + male = 1 + female = 2 + + def __str__(self): + try: + return {1: "male", 2: "female"}[self.value] + except KeyError: + raise ValueError(f"{self.value} is not valid gender") + + +class SubjectType(int, enum.Enum): + book = 1 + anime = 2 + music = 3 + game = 4 + real = 6 + + +StaffMap = { + SubjectType.book: staff_job_book, + SubjectType.anime: staff_job_anime, + SubjectType.music: staff_job_music, + SubjectType.game: staff_job_game, + SubjectType.real: staff_job_real, +} + + +def get_staff(o: Staff) -> str: + v: str = o.cn or o.jp or o.en or o.rdf + return v diff --git a/pol/db/const_test.py b/pol/db/const_test.py new file mode 100644 index 000000000..a68e35288 --- /dev/null +++ b/pol/db/const_test.py @@ -0,0 +1,12 @@ +from pol.db.const import StaffMap + + +def test_valid_type(): + keys = [] + for staff_job in StaffMap.values(): + for key, value in staff_job.items(): + keys.append(key) + assert isinstance(key, int) + assert value.cn or value.jp or value.en or value.rdf + + assert len(keys) == len(set(keys)) diff --git a/pol/db/mysql.py b/pol/db/mysql.py index a2571fe14..ca3d9543d 100644 --- a/pol/db/mysql.py +++ b/pol/db/mysql.py @@ -1,12 +1,5 @@ -from databases import Database, DatabaseURL -from sqlalchemy import create_engine -from sqlalchemy.orm import sessionmaker +from databases import Database from pol import config database = Database(config.MYSQL_URI, force_rollback=config.TESTING) - -engine = create_engine( - str(DatabaseURL(config.MYSQL_URI).replace(dialect="mysql+pymysql")) -) -Session = sessionmaker(bind=engine) diff --git a/pol/db/readme.md b/pol/db/readme.md new file mode 100644 index 000000000..7a5c8970f --- /dev/null +++ b/pol/db/readme.md @@ -0,0 +1 @@ +Tables are generated by [sqlacodegen](https://github.com/agronholm/sqlacodegen) from database. diff --git a/pol/db/tables.py b/pol/db/tables.py index a3e98ff6b..fa49a3d4c 100644 --- a/pol/db/tables.py +++ b/pol/db/tables.py @@ -1,9 +1,4 @@ -""" -this file is mostly generated by sqlacodegen from database -""" -from typing import Type - -from sqlalchemy import Enum, Index, Table, Column, String, text +from sqlalchemy import Date, Enum, Index, Table, Column, String, text from sqlalchemy.dialects.mysql import ( ENUM, YEAR, @@ -14,17 +9,17 @@ MEDIUMINT, MEDIUMTEXT, ) -from sqlalchemy.ext.declarative import DeclarativeMeta, declarative_base +from sqlalchemy.ext.declarative import declarative_base -Base: Type[DeclarativeMeta] = declarative_base() +Base = declarative_base() metadata = Base.metadata -class Character(Base): +class ChiiCharacter(Base): __tablename__ = "chii_characters" - id = Column("crt_id", MEDIUMINT(8), primary_key=True) - name = Column("crt_name", String(255, "utf8_unicode_ci"), nullable=False) + crt_id = Column(MEDIUMINT(8), primary_key=True) + crt_name = Column(String(255, "utf8_unicode_ci"), nullable=False) crt_role = Column(TINYINT(4), nullable=False, index=True, comment="角色,机体,组织。。") crt_infobox = Column(MEDIUMTEXT, nullable=False) crt_summary = Column(MEDIUMTEXT, nullable=False) @@ -121,7 +116,6 @@ class ChiiPersonField(Base): birth_day = Column(TINYINT(2), nullable=False) -# deprecated table t_chii_person_relationship = Table( "chii_person_relationship", metadata, @@ -167,13 +161,150 @@ class ChiiPerson(Base): prsn_redirect = Column(INTEGER(10), nullable=False, server_default=text("'0'")) prsn_nsfw = Column(TINYINT(1), nullable=False) - def role(self): - return { - "producer": self.prsn_producer, - "mangaka": self.prsn_mangaka, - "artist": self.prsn_artist, - "seiyu": self.prsn_seiyu, - "writer": self.prsn_writer, - "illustrator": self.prsn_illustrator, - "actor": self.prsn_actor, - } + +t_chii_subject_alias = Table( + "chii_subject_alias", + metadata, + Column("subject_id", INTEGER(10), nullable=False, index=True), + Column("alias_name", String(255), nullable=False), + Column( + "subject_type_id", + TINYINT(3), + nullable=False, + server_default=text("'0'"), + comment="所属条目的类型", + ), + Column( + "alias_type", + TINYINT(3), + nullable=False, + server_default=text("'0'"), + comment="是别名还是条目名", + ), + Column("alias_key", VARCHAR(10), nullable=False), +) + + +class ChiiSubjectField(Base): + __tablename__ = "chii_subject_fields" + __table_args__ = ( + Index("query_date", "field_sid", "field_date"), + Index("field_year_mon", "field_year", "field_mon"), + ) + + field_sid = Column(MEDIUMINT(8), primary_key=True) + field_tid = Column( + SMALLINT(6), nullable=False, index=True, server_default=text("'0'") + ) + field_tags = Column(MEDIUMTEXT, nullable=False) + field_rate_1 = Column(MEDIUMINT(8), nullable=False, server_default=text("'0'")) + field_rate_2 = Column(MEDIUMINT(8), nullable=False, server_default=text("'0'")) + field_rate_3 = Column(MEDIUMINT(8), nullable=False, server_default=text("'0'")) + field_rate_4 = Column(MEDIUMINT(8), nullable=False, server_default=text("'0'")) + field_rate_5 = Column(MEDIUMINT(8), nullable=False, server_default=text("'0'")) + field_rate_6 = Column(MEDIUMINT(8), nullable=False, server_default=text("'0'")) + field_rate_7 = Column(MEDIUMINT(8), nullable=False, server_default=text("'0'")) + field_rate_8 = Column(MEDIUMINT(8), nullable=False, server_default=text("'0'")) + field_rate_9 = Column(MEDIUMINT(8), nullable=False, server_default=text("'0'")) + field_rate_10 = Column(MEDIUMINT(8), nullable=False, server_default=text("'0'")) + field_airtime = Column(TINYINT(1), nullable=False, index=True) + field_rank = Column( + INTEGER(10), nullable=False, index=True, server_default=text("'0'") + ) + field_year = Column(YEAR(4), nullable=False, index=True, comment="放送年份") + field_mon = Column(TINYINT(2), nullable=False, comment="放送月份") + field_week_day = Column(TINYINT(1), nullable=False, comment="放送日(星期X)") + field_date = Column(Date, nullable=False, index=True, comment="放送日期") + field_redirect = Column(MEDIUMINT(8), nullable=False, server_default=text("'0'")) + + +t_chii_subject_relations = Table( + "chii_subject_relations", + metadata, + Column("rlt_subject_id", MEDIUMINT(8), nullable=False, comment="关联主 ID"), + Column("rlt_subject_type_id", TINYINT(3), nullable=False, index=True), + Column("rlt_relation_type", SMALLINT(5), nullable=False, comment="关联类型"), + Column("rlt_related_subject_id", MEDIUMINT(8), nullable=False, comment="关联目标 ID"), + Column("rlt_related_subject_type_id", TINYINT(3), nullable=False, comment="关联目标类型"), + Column("rlt_vice_versa", TINYINT(1), nullable=False), + Column("rlt_order", TINYINT(3), nullable=False, comment="关联排序"), + Index( + "rlt_relation_type", + "rlt_relation_type", + "rlt_subject_id", + "rlt_related_subject_id", + ), + Index( + "rlt_subject_id", + "rlt_subject_id", + "rlt_related_subject_id", + "rlt_vice_versa", + unique=True, + ), + Index("rlt_related_subject_type_id", "rlt_related_subject_type_id", "rlt_order"), + comment="条目关联表", +) + + +class ChiiSubject(Base): + __tablename__ = "chii_subjects" + __table_args__ = ( + Index( + "order_by_name", + "subject_ban", + "subject_type_id", + "subject_series", + "subject_platform", + "subject_name", + ), + Index( + "browser", + "subject_ban", + "subject_type_id", + "subject_series", + "subject_platform", + ), + Index("subject_idx_cn", "subject_idx_cn", "subject_type_id"), + ) + + subject_id = Column(MEDIUMINT(8), primary_key=True) + subject_type_id = Column( + SMALLINT(6), nullable=False, index=True, server_default=text("'0'") + ) + subject_name = Column(String(80), nullable=False, index=True) + subject_name_cn = Column(String(80), nullable=False, index=True) + subject_uid = Column(String(20), nullable=False, comment="isbn / imdb") + subject_creator = Column(MEDIUMINT(8), nullable=False, index=True) + subject_dateline = Column(INTEGER(10), nullable=False, server_default=text("'0'")) + subject_image = Column(String(255), nullable=False) + subject_platform = Column( + SMALLINT(6), nullable=False, index=True, server_default=text("'0'") + ) + field_infobox = Column(MEDIUMTEXT, nullable=False) + field_summary = Column(MEDIUMTEXT, nullable=False, comment="summary") + field_5 = Column(MEDIUMTEXT, nullable=False, comment="author summary") + field_volumes = Column( + MEDIUMINT(8), nullable=False, server_default=text("'0'"), comment="卷数" + ) + field_eps = Column(MEDIUMINT(8), nullable=False, server_default=text("'0'")) + subject_wish = Column(MEDIUMINT(8), nullable=False, server_default=text("'0'")) + subject_collect = Column(MEDIUMINT(8), nullable=False, server_default=text("'0'")) + subject_doing = Column(MEDIUMINT(8), nullable=False, server_default=text("'0'")) + subject_on_hold = Column( + MEDIUMINT(8), nullable=False, server_default=text("'0'"), comment="搁置人数" + ) + subject_dropped = Column( + MEDIUMINT(8), nullable=False, server_default=text("'0'"), comment="抛弃人数" + ) + subject_series = Column( + TINYINT(1), nullable=False, index=True, server_default=text("'0'") + ) + subject_series_entry = Column( + MEDIUMINT(8), nullable=False, index=True, server_default=text("'0'") + ) + subject_idx_cn = Column(String(1), nullable=False) + subject_airtime = Column(TINYINT(1), nullable=False, index=True) + subject_nsfw = Column(TINYINT(1), nullable=False, index=True) + subject_ban = Column( + TINYINT(1), nullable=False, index=True, server_default=text("'0'") + ) diff --git a/pol/db_models/sa.py b/pol/db_models/sa.py index da868fe05..dcde7dc39 100644 --- a/pol/db_models/sa.py +++ b/pol/db_models/sa.py @@ -4,6 +4,8 @@ Column, String, DateTime, + or_, + and_, func, join, text, @@ -24,4 +26,7 @@ "select", "update", "insert", + "and_", + "func", + "or_", ] diff --git a/pol/log/__init__.py b/pol/log/__init__.py deleted file mode 100644 index d5d27fb7c..000000000 --- a/pol/log/__init__.py +++ /dev/null @@ -1,18 +0,0 @@ -import platform - -from aiologger.loggers.json import JsonLogger - -from pol import config - - -async def setup_logger(): - logger = JsonLogger( - name="pol", - extra={ - "@metadata": {"beat": "py_logging", "version": config.COMMIT_REF}, - "version": config.COMMIT_REF, - "platform": platform.platform(), - }, - ) - - return logger diff --git a/pol/models/__init__.py b/pol/models/__init__.py index d609bb560..0ad388f08 100644 --- a/pol/models/__init__.py +++ b/pol/models/__init__.py @@ -1,5 +1,9 @@ -from pydantic import BaseModel +from typing import Any + +from pydantic import Field, BaseModel class ErrorDetail(BaseModel): - detail: str + title: str + description: str + detail: Any = Field(..., description="can be anything") diff --git a/pol/res.py b/pol/res.py index 5772360cc..a7f3c1273 100644 --- a/pol/res.py +++ b/pol/res.py @@ -1,6 +1,7 @@ -from typing import Any, Dict, Type +from typing import Any, Dict, Type, Optional import orjson +from fastapi import HTTPException as _HTTPException from starlette.responses import Response, JSONResponse @@ -15,6 +16,21 @@ def render(self, content: Any) -> bytes: return orjson.dumps(content) +class HTTPException(_HTTPException): + def __init__( + self, + status_code: int, + title: str, + description: str, + detail: Any = None, + headers: Optional[Dict[str, Any]] = None, + ) -> None: + super().__init__(status_code=status_code, detail=detail) + self.headers = headers + self.title = title + self.description = description + + def response( model: Type = None, description: str = None, headers=None, cls: Type = None ) -> Dict[str, Any]: diff --git a/pol/server.py b/pol/server.py index b62de06b9..a833a68a4 100644 --- a/pol/server.py +++ b/pol/server.py @@ -4,9 +4,10 @@ from loguru import logger from fastapi import FastAPI from fastapi.responses import HTMLResponse +from fastapi.exceptions import RequestValidationError from starlette.middleware import cors -from pol import api, config +from pol import api, res, config from pol.res import ORJSONResponse from pol.db.mysql import database from pol.middlewares.http import setup_http_middleware @@ -27,6 +28,31 @@ app.include_router(api.router, prefix="/api") +@app.exception_handler(res.HTTPException) +async def http_exception_handler(request, exc: res.HTTPException): + return ORJSONResponse( + { + "title": exc.title, + "description": exc.description, + "detail": exc.detail, + }, + headers=exc.headers, + status_code=exc.status_code, + ) + + +@app.exception_handler(RequestValidationError) +async def validation_exception_handler(request, exc: RequestValidationError): + return ORJSONResponse( + { + "title": "Invalid Request", + "description": "One or more parameters to your request was invalid.", + "detail": exc.errors(), + }, + status_code=422, + ) + + @app.on_event("startup") async def startup() -> None: await database.connect() @@ -52,7 +78,7 @@ async def doc():
- +