From 03e98c2cf6ac92a4de4a3a6c1a93b74816966e09 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Thu, 24 Oct 2024 19:47:51 +0200 Subject: [PATCH 01/61] Update dependencies (#46) Co-authored-by: github-actions --- pdm.lock | 130 +++++++++++++++++++++++------------------------ requirements.txt | 6 +-- 2 files changed, 68 insertions(+), 68 deletions(-) diff --git a/pdm.lock b/pdm.lock index 31d0785..6962d6b 100644 --- a/pdm.lock +++ b/pdm.lock @@ -409,22 +409,22 @@ files = [ [[package]] name = "markupsafe" -version = "3.0.1" +version = "3.0.2" requires_python = ">=3.9" summary = "Safely add untrusted strings to HTML/XML markup." groups = ["default"] files = [ - {file = "MarkupSafe-3.0.1-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:26627785a54a947f6d7336ce5963569b5d75614619e75193bdb4e06e21d447ad"}, - {file = "MarkupSafe-3.0.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:b954093679d5750495725ea6f88409946d69cfb25ea7b4c846eef5044194f583"}, - {file = "MarkupSafe-3.0.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:973a371a55ce9ed333a3a0f8e0bcfae9e0d637711534bcb11e130af2ab9334e7"}, - {file = "MarkupSafe-3.0.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:244dbe463d5fb6d7ce161301a03a6fe744dac9072328ba9fc82289238582697b"}, - {file = "MarkupSafe-3.0.1-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d98e66a24497637dd31ccab090b34392dddb1f2f811c4b4cd80c230205c074a3"}, - {file = "MarkupSafe-3.0.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:ad91738f14eb8da0ff82f2acd0098b6257621410dcbd4df20aaa5b4233d75a50"}, - {file = "MarkupSafe-3.0.1-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:7044312a928a66a4c2a22644147bc61a199c1709712069a344a3fb5cfcf16915"}, - {file = "MarkupSafe-3.0.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:a4792d3b3a6dfafefdf8e937f14906a51bd27025a36f4b188728a73382231d91"}, - {file = "MarkupSafe-3.0.1-cp311-cp311-win32.whl", hash = "sha256:fa7d686ed9883f3d664d39d5a8e74d3c5f63e603c2e3ff0abcba23eac6542635"}, - {file = "MarkupSafe-3.0.1-cp311-cp311-win_amd64.whl", hash = "sha256:9ba25a71ebf05b9bb0e2ae99f8bc08a07ee8e98c612175087112656ca0f5c8bf"}, - {file = "markupsafe-3.0.1.tar.gz", hash = "sha256:3e683ee4f5d0fa2dde4db77ed8dd8a876686e3fc417655c2ece9a90576905344"}, + {file = "MarkupSafe-3.0.2-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:9025b4018f3a1314059769c7bf15441064b2207cb3f065e6ea1e7359cb46db9d"}, + {file = "MarkupSafe-3.0.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:93335ca3812df2f366e80509ae119189886b0f3c2b81325d39efdb84a1e2ae93"}, + {file = "MarkupSafe-3.0.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2cb8438c3cbb25e220c2ab33bb226559e7afb3baec11c4f218ffa7308603c832"}, + {file = "MarkupSafe-3.0.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a123e330ef0853c6e822384873bef7507557d8e4a082961e1defa947aa59ba84"}, + {file = "MarkupSafe-3.0.2-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1e084f686b92e5b83186b07e8a17fc09e38fff551f3602b249881fec658d3eca"}, + {file = "MarkupSafe-3.0.2-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:d8213e09c917a951de9d09ecee036d5c7d36cb6cb7dbaece4c71a60d79fb9798"}, + {file = "MarkupSafe-3.0.2-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:5b02fb34468b6aaa40dfc198d813a641e3a63b98c2b05a16b9f80b7ec314185e"}, + {file = "MarkupSafe-3.0.2-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:0bff5e0ae4ef2e1ae4fdf2dfd5b76c75e5c2fa4132d05fc1b0dabcd20c7e28c4"}, + {file = "MarkupSafe-3.0.2-cp311-cp311-win32.whl", hash = "sha256:6c89876f41da747c8d3677a2b540fb32ef5715f97b66eeb0c6b66f5e3ef6f59d"}, + {file = "MarkupSafe-3.0.2-cp311-cp311-win_amd64.whl", hash = "sha256:70a87b411535ccad5ef2f1df5136506a10775d267e197e4cf531ced10537bd6b"}, + {file = "markupsafe-3.0.2.tar.gz", hash = "sha256:ee55d3edf80167e48ea11a923c7386f4669df67d7994554387f84e7d8b0a2bf0"}, ] [[package]] @@ -501,22 +501,22 @@ files = [ [[package]] name = "orjson" -version = "3.10.7" +version = "3.10.9" requires_python = ">=3.8" summary = "Fast, correct Python JSON library supporting dataclasses, datetimes, and numpy" groups = ["default"] files = [ - {file = "orjson-3.10.7-cp311-cp311-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:7db8539039698ddfb9a524b4dd19508256107568cdad24f3682d5773e60504a2"}, - {file = "orjson-3.10.7-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:480f455222cb7a1dea35c57a67578848537d2602b46c464472c995297117fa09"}, - {file = "orjson-3.10.7-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:8a9c9b168b3a19e37fe2778c0003359f07822c90fdff8f98d9d2a91b3144d8e0"}, - {file = "orjson-3.10.7-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:8de062de550f63185e4c1c54151bdddfc5625e37daf0aa1e75d2a1293e3b7d9a"}, - {file = "orjson-3.10.7-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:6b0dd04483499d1de9c8f6203f8975caf17a6000b9c0c54630cef02e44ee624e"}, - {file = "orjson-3.10.7-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b58d3795dafa334fc8fd46f7c5dc013e6ad06fd5b9a4cc98cb1456e7d3558bd6"}, - {file = "orjson-3.10.7-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:33cfb96c24034a878d83d1a9415799a73dc77480e6c40417e5dda0710d559ee6"}, - {file = "orjson-3.10.7-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:e724cebe1fadc2b23c6f7415bad5ee6239e00a69f30ee423f319c6af70e2a5c0"}, - {file = "orjson-3.10.7-cp311-none-win32.whl", hash = "sha256:82763b46053727a7168d29c772ed5c870fdae2f61aa8a25994c7984a19b1021f"}, - {file = "orjson-3.10.7-cp311-none-win_amd64.whl", hash = "sha256:eb8d384a24778abf29afb8e41d68fdd9a156cf6e5390c04cc07bbc24b89e98b5"}, - {file = "orjson-3.10.7.tar.gz", hash = "sha256:75ef0640403f945f3a1f9f6400686560dbfb0fb5b16589ad62cd477043c4eee3"}, + {file = "orjson-3.10.9-cp311-cp311-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:f3bd9df47385b8fabb3b2ee1e83f9960b8accc1905be971a1c257f16c32b491e"}, + {file = "orjson-3.10.9-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a4948961b6bce1e2086b2cf0b56cc454cdab589d40c7f85be71fb5a5556c51d3"}, + {file = "orjson-3.10.9-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:0a9fc7a6cf2b229ddc323e136df13b3fb4466c50d84ed600cd0898223dd2fea3"}, + {file = "orjson-3.10.9-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:2314846e1029a2d2b899140f350eaaf3a73281df43ba84ac44d94ca861b5b269"}, + {file = "orjson-3.10.9-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f52d993504827503411df2d60e60acf52885561458d6273f99ecd172f31c4352"}, + {file = "orjson-3.10.9-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e29bbf08d907756c145a3a3a1f7ce2f11f15e3edbd3342842589d6030981b76f"}, + {file = "orjson-3.10.9-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:7ae82992c00b480c3cc7dac6739324554be8c5d8e858a90044928506a3333ef4"}, + {file = "orjson-3.10.9-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:6fdf8d32b6d94019dc15163542d345e9ce4c4661f56b318608aa3088a1a3a23b"}, + {file = "orjson-3.10.9-cp311-none-win32.whl", hash = "sha256:01f5fef452b4d7615f2e94153479370a4b59e0c964efb32dd902978f807a45cd"}, + {file = "orjson-3.10.9-cp311-none-win_amd64.whl", hash = "sha256:95361c4197c7ce9afdf56255de6f4e2474c39d16a277cce31d1b99a2520486d8"}, + {file = "orjson-3.10.9.tar.gz", hash = "sha256:c378074e0c46035dc66e57006993233ec66bf8487d501bab41649b4b7289ed4d"}, ] [[package]] @@ -733,29 +733,29 @@ files = [ [[package]] name = "ruff" -version = "0.6.9" +version = "0.7.0" requires_python = ">=3.7" summary = "An extremely fast Python linter and code formatter, written in Rust." groups = ["dev"] files = [ - {file = "ruff-0.6.9-py3-none-linux_armv6l.whl", hash = "sha256:064df58d84ccc0ac0fcd63bc3090b251d90e2a372558c0f057c3f75ed73e1ccd"}, - {file = "ruff-0.6.9-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:140d4b5c9f5fc7a7b074908a78ab8d384dd7f6510402267bc76c37195c02a7ec"}, - {file = "ruff-0.6.9-py3-none-macosx_11_0_arm64.whl", hash = "sha256:53fd8ca5e82bdee8da7f506d7b03a261f24cd43d090ea9db9a1dc59d9313914c"}, - {file = "ruff-0.6.9-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:645d7d8761f915e48a00d4ecc3686969761df69fb561dd914a773c1a8266e14e"}, - {file = "ruff-0.6.9-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:eae02b700763e3847595b9d2891488989cac00214da7f845f4bcf2989007d577"}, - {file = "ruff-0.6.9-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:7d5ccc9e58112441de8ad4b29dcb7a86dc25c5f770e3c06a9d57e0e5eba48829"}, - {file = "ruff-0.6.9-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:417b81aa1c9b60b2f8edc463c58363075412866ae4e2b9ab0f690dc1e87ac1b5"}, - {file = "ruff-0.6.9-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:3c866b631f5fbce896a74a6e4383407ba7507b815ccc52bcedabb6810fdb3ef7"}, - {file = "ruff-0.6.9-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:7b118afbb3202f5911486ad52da86d1d52305b59e7ef2031cea3425142b97d6f"}, - {file = "ruff-0.6.9-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a67267654edc23c97335586774790cde402fb6bbdb3c2314f1fc087dee320bfa"}, - {file = "ruff-0.6.9-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:3ef0cc774b00fec123f635ce5c547dac263f6ee9fb9cc83437c5904183b55ceb"}, - {file = "ruff-0.6.9-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:12edd2af0c60fa61ff31cefb90aef4288ac4d372b4962c2864aeea3a1a2460c0"}, - {file = "ruff-0.6.9-py3-none-musllinux_1_2_i686.whl", hash = "sha256:55bb01caeaf3a60b2b2bba07308a02fca6ab56233302406ed5245180a05c5625"}, - {file = "ruff-0.6.9-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:925d26471fa24b0ce5a6cdfab1bb526fb4159952385f386bdcc643813d472039"}, - {file = "ruff-0.6.9-py3-none-win32.whl", hash = "sha256:eb61ec9bdb2506cffd492e05ac40e5bc6284873aceb605503d8494180d6fc84d"}, - {file = "ruff-0.6.9-py3-none-win_amd64.whl", hash = "sha256:785d31851c1ae91f45b3d8fe23b8ae4b5170089021fbb42402d811135f0b7117"}, - {file = "ruff-0.6.9-py3-none-win_arm64.whl", hash = "sha256:a9641e31476d601f83cd602608739a0840e348bda93fec9f1ee816f8b6798b93"}, - {file = "ruff-0.6.9.tar.gz", hash = "sha256:b076ef717a8e5bc819514ee1d602bbdca5b4420ae13a9cf61a0c0a4f53a2baa2"}, + {file = "ruff-0.7.0-py3-none-linux_armv6l.whl", hash = "sha256:0cdf20c2b6ff98e37df47b2b0bd3a34aaa155f59a11182c1303cce79be715628"}, + {file = "ruff-0.7.0-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:496494d350c7fdeb36ca4ef1c9f21d80d182423718782222c29b3e72b3512737"}, + {file = "ruff-0.7.0-py3-none-macosx_11_0_arm64.whl", hash = "sha256:214b88498684e20b6b2b8852c01d50f0651f3cc6118dfa113b4def9f14faaf06"}, + {file = "ruff-0.7.0-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:630fce3fefe9844e91ea5bbf7ceadab4f9981f42b704fae011bb8efcaf5d84be"}, + {file = "ruff-0.7.0-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:211d877674e9373d4bb0f1c80f97a0201c61bcd1e9d045b6e9726adc42c156aa"}, + {file = "ruff-0.7.0-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:194d6c46c98c73949a106425ed40a576f52291c12bc21399eb8f13a0f7073495"}, + {file = "ruff-0.7.0-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:82c2579b82b9973a110fab281860403b397c08c403de92de19568f32f7178598"}, + {file = "ruff-0.7.0-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:9af971fe85dcd5eaed8f585ddbc6bdbe8c217fb8fcf510ea6bca5bdfff56040e"}, + {file = "ruff-0.7.0-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b641c7f16939b7d24b7bfc0be4102c56562a18281f84f635604e8a6989948914"}, + {file = "ruff-0.7.0-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d71672336e46b34e0c90a790afeac8a31954fd42872c1f6adaea1dff76fd44f9"}, + {file = "ruff-0.7.0-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:ab7d98c7eed355166f367597e513a6c82408df4181a937628dbec79abb2a1fe4"}, + {file = "ruff-0.7.0-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:1eb54986f770f49edb14f71d33312d79e00e629a57387382200b1ef12d6a4ef9"}, + {file = "ruff-0.7.0-py3-none-musllinux_1_2_i686.whl", hash = "sha256:dc452ba6f2bb9cf8726a84aa877061a2462afe9ae0ea1d411c53d226661c601d"}, + {file = "ruff-0.7.0-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:4b406c2dce5be9bad59f2de26139a86017a517e6bcd2688da515481c05a2cb11"}, + {file = "ruff-0.7.0-py3-none-win32.whl", hash = "sha256:f6c968509f767776f524a8430426539587d5ec5c662f6addb6aa25bc2e8195ec"}, + {file = "ruff-0.7.0-py3-none-win_amd64.whl", hash = "sha256:ff4aabfbaaba880e85d394603b9e75d32b0693152e16fa659a3064a85df7fce2"}, + {file = "ruff-0.7.0-py3-none-win_arm64.whl", hash = "sha256:10842f69c245e78d6adec7e1db0a7d9ddc2fff0621d730e61657b64fa36f207e"}, + {file = "ruff-0.7.0.tar.gz", hash = "sha256:47a86360cf62d9cd53ebfb0b5eb0e882193fc191c6d717e8bef4462bc3b9ea2b"}, ] [[package]] @@ -773,7 +773,7 @@ files = [ [[package]] name = "sentry-sdk" -version = "2.16.0" +version = "2.17.0" requires_python = ">=3.6" summary = "Python client for Sentry (https://sentry.io)" groups = ["sentry"] @@ -782,8 +782,8 @@ dependencies = [ "urllib3>=1.26.11", ] files = [ - {file = "sentry_sdk-2.16.0-py2.py3-none-any.whl", hash = "sha256:49139c31ebcd398f4f6396b18910610a0c1602f6e67083240c33019d1f6aa30c"}, - {file = "sentry_sdk-2.16.0.tar.gz", hash = "sha256:90f733b32e15dfc1999e6b7aca67a38688a567329de4d6e184154a73f96c6892"}, + {file = "sentry_sdk-2.17.0-py2.py3-none-any.whl", hash = "sha256:625955884b862cc58748920f9e21efdfb8e0d4f98cca4ab0d3918576d5b606ad"}, + {file = "sentry_sdk-2.17.0.tar.gz", hash = "sha256:dd0a05352b78ffeacced73a94e86f38b32e2eae15fff5f30ca5abb568a72eacf"}, ] [[package]] @@ -903,7 +903,7 @@ files = [ [[package]] name = "yarl" -version = "1.15.4" +version = "1.15.5" requires_python = ">=3.9" summary = "Yet another URL library" groups = ["default"] @@ -913,22 +913,22 @@ dependencies = [ "propcache>=0.2.0", ] files = [ - {file = "yarl-1.15.4-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:76259901cf1ac3db65e7e6dff04775b626d0715f9b51d92b447351144c756a82"}, - {file = "yarl-1.15.4-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:98d8dc1e8133f86d916125deca9780d791b22645f0d62bafe1452d1cd5eac631"}, - {file = "yarl-1.15.4-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:0d0f16c87c62b7a94b389ddf6a8c9d081265d788875c39f3a80108c4856eea7b"}, - {file = "yarl-1.15.4-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8de5328d91859b461899497980d4cc8269e84e2d18640f6ac643886fda9000bf"}, - {file = "yarl-1.15.4-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:84937d00e2ea03616c40977de20189fa13a9213e5744a3c6afa0e7dd9141d69c"}, - {file = "yarl-1.15.4-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:691a3b498fdebef63308e8967bb598cfd326c56d628da82b799dd181bace4503"}, - {file = "yarl-1.15.4-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4a706db0c3b7e4578ff34ed2b1d2507b08fd491346ffc64468786fdf1151d938"}, - {file = "yarl-1.15.4-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:adb6b5d07d17c32f9d34c9dd4a693637a72323cfcb1f8a52d57033ab2dd21e99"}, - {file = "yarl-1.15.4-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:6e100c6c7d9e9d469009fd55cc4d7ad168d67d40758865c50da713f7ada491e5"}, - {file = "yarl-1.15.4-cp311-cp311-musllinux_1_2_armv7l.whl", hash = "sha256:df6b254e55c8ac2362afaa651e3e53453aa19a095570792346245773b434176e"}, - {file = "yarl-1.15.4-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:8721f8bedaa722c3c483cc06a1399cbfdb280eadf443aa5d324b0203cef2a75f"}, - {file = "yarl-1.15.4-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:1005921b30f4f39bf893946df6173567ff650307babb5ec04bbf64342a1f62c1"}, - {file = "yarl-1.15.4-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:ab79cc13307065a0b3ef087f09f0509996fc605d35d6642bb28e5d85b2648e1e"}, - {file = "yarl-1.15.4-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:f337486742c700b102d640830aab3faf2848bed966b479a39e6783edd4ab1c6c"}, - {file = "yarl-1.15.4-cp311-cp311-win32.whl", hash = "sha256:20acf84bd1ce530065f8e957e4a5878fda4bc5f18cb02659828210e1519de54e"}, - {file = "yarl-1.15.4-cp311-cp311-win_amd64.whl", hash = "sha256:ab9ccf26cb3fa32747ba2a637a189d2d42386a2fc4afc10dbc7f85922dd23b0f"}, - {file = "yarl-1.15.4-py3-none-any.whl", hash = "sha256:e5cc288111c450c0a54a74475591b206d3b1cb47dc71bb6200f6be8b1337184c"}, - {file = "yarl-1.15.4.tar.gz", hash = "sha256:a0c5e271058d148d730219ca4f33c5d841c6bd46e05b0da60fea7b516906ccd3"}, + {file = "yarl-1.15.5-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:e652aa9f8dfa808bc5b2da4d1f4e286cf1d640570fdfa72ffc0c1d16ba114651"}, + {file = "yarl-1.15.5-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:21050b6cd569980fe20ceeab4baeb900d3f7247270475e42bafe117416a5496c"}, + {file = "yarl-1.15.5-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:18940191ec9a83bbfe63eea61c3e9d12474bb910d5613bce8fa46e84a80b75b2"}, + {file = "yarl-1.15.5-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a082dc948045606f62dca0228ab24f13737180b253378d6443f5b2b9ef8beefe"}, + {file = "yarl-1.15.5-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:0a843e692f9d5402b3455653f4607dc521de2385f01c5cad7ba4a87c46e2ea8d"}, + {file = "yarl-1.15.5-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5093a453176a4fad4f9c3006f507cf300546190bb3e27944275a37cfd6323a65"}, + {file = "yarl-1.15.5-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2597a589859b94d0a5e2f5d30fee95081867926e57cb751f8b44a7dd92da4e79"}, + {file = "yarl-1.15.5-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1f5a1ca6eaabfe62718b87eac06d9a47b30cf92ffa065fee9196d3ecd24a3cf1"}, + {file = "yarl-1.15.5-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:4ac83b307cc4b8907345b52994055c6c3c2601ceb6fcb94c5ed6a93c6b4e8257"}, + {file = "yarl-1.15.5-cp311-cp311-musllinux_1_2_armv7l.whl", hash = "sha256:325e2beb2cd8654b276e7686a3cd203628dd3fe32d5c616e632bc35a2901fb16"}, + {file = "yarl-1.15.5-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:75d04ba8ed335042328086e643e01165e0c24598216f72da709b375930ae3bdb"}, + {file = "yarl-1.15.5-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:7abd7d15aedb3961a967cc65f8144dbbca42e3626a21c5f4f29919cf43eeafb9"}, + {file = "yarl-1.15.5-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:294c742a273f44511f14b03a9e06b66094dcdf4bbb75a5e23fead548fd5310ae"}, + {file = "yarl-1.15.5-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:63d46606b20f80a6476f1044bab78e1a69c2e0747f174583e2f12fc70bad2170"}, + {file = "yarl-1.15.5-cp311-cp311-win32.whl", hash = "sha256:b1217102a455e3ac9ac293081093f21f0183e978c7692171ff669fee5296fa28"}, + {file = "yarl-1.15.5-cp311-cp311-win_amd64.whl", hash = "sha256:5848500b6a01497560969e8c3a7eb1b2570853c74a0ca6f67ebaf6064106c49b"}, + {file = "yarl-1.15.5-py3-none-any.whl", hash = "sha256:625f31d6650829fba4030b4e7bdb2d69e41510dddfa29a1da27076c199521757"}, + {file = "yarl-1.15.5.tar.gz", hash = "sha256:8249147ee81c1cf4d1dc6f26ba28a1b9d92751529f83c308ad02164bb93abd0d"}, ] diff --git a/requirements.txt b/requirements.txt index 0ca58ac..22e579a 100644 --- a/requirements.txt +++ b/requirements.txt @@ -22,9 +22,9 @@ hyperframe==6.0.1 idna==3.10 itsdangerous==2.2.0 jinja2==3.1.4 -markupsafe==3.0.1 +markupsafe==3.0.2 multidict==6.1.0 -orjson==3.10.7 +orjson==3.10.9 priority==2.0.0 propcache==0.2.0 py-cord==2.6.1 @@ -39,4 +39,4 @@ schema==0.7.7 typing-extensions==4.12.2 werkzeug==3.0.4 wsproto==1.2.0 -yarl==1.15.2 +yarl==1.15.5 From a4fba4e5fd1fb94b1330a8b3d36f6b19dfb989e7 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Tue, 29 Oct 2024 16:12:52 +0100 Subject: [PATCH 02/61] Update dependencies (#47) Co-authored-by: github-actions --- pdm.lock | 154 +++++++++++++++++++++++------------------------ requirements.txt | 10 +-- 2 files changed, 82 insertions(+), 82 deletions(-) diff --git a/pdm.lock b/pdm.lock index 6962d6b..2ab0c40 100644 --- a/pdm.lock +++ b/pdm.lock @@ -110,7 +110,7 @@ files = [ [[package]] name = "basedpyright" -version = "1.19.0" +version = "1.19.1" requires_python = ">=3.8" summary = "static type checking for Python (but based)" groups = ["dev"] @@ -118,8 +118,8 @@ dependencies = [ "nodejs-wheel-binaries>=20.13.1", ] files = [ - {file = "basedpyright-1.19.0-py3-none-any.whl", hash = "sha256:78f2fc2e5d3f2cc1c4dfae351f9d45aa52917bfb0e9a103579a4bb005f097bec"}, - {file = "basedpyright-1.19.0.tar.gz", hash = "sha256:847d9c75ca691c9ff0661c800e830c23b32c65793b97a4386db9cbf52c1a168a"}, + {file = "basedpyright-1.19.1-py3-none-any.whl", hash = "sha256:976744146fcecb7413a726fbb8e52f4606738e02820a7dfbe310199f8915311e"}, + {file = "basedpyright-1.19.1.tar.gz", hash = "sha256:2863e619296ddd7f9f566c44e4fa8f781d727a83fa2da6ef62951e0b657655f6"}, ] [[package]] @@ -234,28 +234,28 @@ files = [ [[package]] name = "frozenlist" -version = "1.4.1" +version = "1.5.0" requires_python = ">=3.8" summary = "A list-like structure which implements collections.abc.MutableSequence" groups = ["default"] files = [ - {file = "frozenlist-1.4.1-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:a0cb6f11204443f27a1628b0e460f37fb30f624be6051d490fa7d7e26d4af3d0"}, - {file = "frozenlist-1.4.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:b46c8ae3a8f1f41a0d2ef350c0b6e65822d80772fe46b653ab6b6274f61d4a49"}, - {file = "frozenlist-1.4.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:fde5bd59ab5357e3853313127f4d3565fc7dad314a74d7b5d43c22c6a5ed2ced"}, - {file = "frozenlist-1.4.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:722e1124aec435320ae01ee3ac7bec11a5d47f25d0ed6328f2273d287bc3abb0"}, - {file = "frozenlist-1.4.1-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:2471c201b70d58a0f0c1f91261542a03d9a5e088ed3dc6c160d614c01649c106"}, - {file = "frozenlist-1.4.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:c757a9dd70d72b076d6f68efdbb9bc943665ae954dad2801b874c8c69e185068"}, - {file = "frozenlist-1.4.1-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f146e0911cb2f1da549fc58fc7bcd2b836a44b79ef871980d605ec392ff6b0d2"}, - {file = "frozenlist-1.4.1-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4f9c515e7914626b2a2e1e311794b4c35720a0be87af52b79ff8e1429fc25f19"}, - {file = "frozenlist-1.4.1-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:c302220494f5c1ebeb0912ea782bcd5e2f8308037b3c7553fad0e48ebad6ad82"}, - {file = "frozenlist-1.4.1-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:442acde1e068288a4ba7acfe05f5f343e19fac87bfc96d89eb886b0363e977ec"}, - {file = "frozenlist-1.4.1-cp311-cp311-musllinux_1_1_ppc64le.whl", hash = "sha256:1b280e6507ea8a4fa0c0a7150b4e526a8d113989e28eaaef946cc77ffd7efc0a"}, - {file = "frozenlist-1.4.1-cp311-cp311-musllinux_1_1_s390x.whl", hash = "sha256:fe1a06da377e3a1062ae5fe0926e12b84eceb8a50b350ddca72dc85015873f74"}, - {file = "frozenlist-1.4.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:db9e724bebd621d9beca794f2a4ff1d26eed5965b004a97f1f1685a173b869c2"}, - {file = "frozenlist-1.4.1-cp311-cp311-win32.whl", hash = "sha256:e774d53b1a477a67838a904131c4b0eef6b3d8a651f8b138b04f748fccfefe17"}, - {file = "frozenlist-1.4.1-cp311-cp311-win_amd64.whl", hash = "sha256:fb3c2db03683b5767dedb5769b8a40ebb47d6f7f45b1b3e3b4b51ec8ad9d9825"}, - {file = "frozenlist-1.4.1-py3-none-any.whl", hash = "sha256:04ced3e6a46b4cfffe20f9ae482818e34eba9b5fb0ce4056e4cc9b6e212d09b7"}, - {file = "frozenlist-1.4.1.tar.gz", hash = "sha256:c037a86e8513059a2613aaba4d817bb90b9d9b6b69aace3ce9c877e8c8ed402b"}, + {file = "frozenlist-1.5.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:fd74520371c3c4175142d02a976aee0b4cb4a7cc912a60586ffd8d5929979b30"}, + {file = "frozenlist-1.5.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:2f3f7a0fbc219fb4455264cae4d9f01ad41ae6ee8524500f381de64ffaa077d5"}, + {file = "frozenlist-1.5.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:f47c9c9028f55a04ac254346e92977bf0f166c483c74b4232bee19a6697e4778"}, + {file = "frozenlist-1.5.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0996c66760924da6e88922756d99b47512a71cfd45215f3570bf1e0b694c206a"}, + {file = "frozenlist-1.5.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a2fe128eb4edeabe11896cb6af88fca5346059f6c8d807e3b910069f39157869"}, + {file = "frozenlist-1.5.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:1a8ea951bbb6cacd492e3948b8da8c502a3f814f5d20935aae74b5df2b19cf3d"}, + {file = "frozenlist-1.5.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:de537c11e4aa01d37db0d403b57bd6f0546e71a82347a97c6a9f0dcc532b3a45"}, + {file = "frozenlist-1.5.0-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9c2623347b933fcb9095841f1cc5d4ff0b278addd743e0e966cb3d460278840d"}, + {file = "frozenlist-1.5.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:cee6798eaf8b1416ef6909b06f7dc04b60755206bddc599f52232606e18179d3"}, + {file = "frozenlist-1.5.0-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:f5f9da7f5dbc00a604fe74aa02ae7c98bcede8a3b8b9666f9f86fc13993bc71a"}, + {file = "frozenlist-1.5.0-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:90646abbc7a5d5c7c19461d2e3eeb76eb0b204919e6ece342feb6032c9325ae9"}, + {file = "frozenlist-1.5.0-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:bdac3c7d9b705d253b2ce370fde941836a5f8b3c5c2b8fd70940a3ea3af7f4f2"}, + {file = "frozenlist-1.5.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:03d33c2ddbc1816237a67f66336616416e2bbb6beb306e5f890f2eb22b959cdf"}, + {file = "frozenlist-1.5.0-cp311-cp311-win32.whl", hash = "sha256:237f6b23ee0f44066219dae14c70ae38a63f0440ce6750f868ee08775073f942"}, + {file = "frozenlist-1.5.0-cp311-cp311-win_amd64.whl", hash = "sha256:0cc974cc93d32c42e7b0f6cf242a6bd941c57c61b618e78b6c0a96cb72788c1d"}, + {file = "frozenlist-1.5.0-py3-none-any.whl", hash = "sha256:d994863bba198a4a518b467bb971c56e1db3f180a25c6cf7bb1949c267f748c3"}, + {file = "frozenlist-1.5.0.tar.gz", hash = "sha256:81d5af29e61b9c8348e876d442253723928dce6433e0e76cd925cd83f1b4b817"}, ] [[package]] @@ -501,22 +501,22 @@ files = [ [[package]] name = "orjson" -version = "3.10.9" +version = "3.10.10" requires_python = ">=3.8" summary = "Fast, correct Python JSON library supporting dataclasses, datetimes, and numpy" groups = ["default"] files = [ - {file = "orjson-3.10.9-cp311-cp311-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:f3bd9df47385b8fabb3b2ee1e83f9960b8accc1905be971a1c257f16c32b491e"}, - {file = "orjson-3.10.9-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a4948961b6bce1e2086b2cf0b56cc454cdab589d40c7f85be71fb5a5556c51d3"}, - {file = "orjson-3.10.9-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:0a9fc7a6cf2b229ddc323e136df13b3fb4466c50d84ed600cd0898223dd2fea3"}, - {file = "orjson-3.10.9-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:2314846e1029a2d2b899140f350eaaf3a73281df43ba84ac44d94ca861b5b269"}, - {file = "orjson-3.10.9-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f52d993504827503411df2d60e60acf52885561458d6273f99ecd172f31c4352"}, - {file = "orjson-3.10.9-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e29bbf08d907756c145a3a3a1f7ce2f11f15e3edbd3342842589d6030981b76f"}, - {file = "orjson-3.10.9-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:7ae82992c00b480c3cc7dac6739324554be8c5d8e858a90044928506a3333ef4"}, - {file = "orjson-3.10.9-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:6fdf8d32b6d94019dc15163542d345e9ce4c4661f56b318608aa3088a1a3a23b"}, - {file = "orjson-3.10.9-cp311-none-win32.whl", hash = "sha256:01f5fef452b4d7615f2e94153479370a4b59e0c964efb32dd902978f807a45cd"}, - {file = "orjson-3.10.9-cp311-none-win_amd64.whl", hash = "sha256:95361c4197c7ce9afdf56255de6f4e2474c39d16a277cce31d1b99a2520486d8"}, - {file = "orjson-3.10.9.tar.gz", hash = "sha256:c378074e0c46035dc66e57006993233ec66bf8487d501bab41649b4b7289ed4d"}, + {file = "orjson-3.10.10-cp311-cp311-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:879e99486c0fbb256266c7c6a67ff84f46035e4f8749ac6317cc83dacd7f993a"}, + {file = "orjson-3.10.10-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:019481fa9ea5ff13b5d5d95e6fd5ab25ded0810c80b150c2c7b1cc8660b662a7"}, + {file = "orjson-3.10.10-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:0dd57eff09894938b4c86d4b871a479260f9e156fa7f12f8cad4b39ea8028bb5"}, + {file = "orjson-3.10.10-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:dbde6d70cd95ab4d11ea8ac5e738e30764e510fc54d777336eec09bb93b8576c"}, + {file = "orjson-3.10.10-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3b2625cb37b8fb42e2147404e5ff7ef08712099197a9cd38895006d7053e69d6"}, + {file = "orjson-3.10.10-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dbf3c20c6a7db69df58672a0d5815647ecf78c8e62a4d9bd284e8621c1fe5ccb"}, + {file = "orjson-3.10.10-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:75c38f5647e02d423807d252ce4528bf6a95bd776af999cb1fb48867ed01d1f6"}, + {file = "orjson-3.10.10-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:23458d31fa50ec18e0ec4b0b4343730928296b11111df5f547c75913714116b2"}, + {file = "orjson-3.10.10-cp311-none-win32.whl", hash = "sha256:2787cd9dedc591c989f3facd7e3e86508eafdc9536a26ec277699c0aa63c685b"}, + {file = "orjson-3.10.10-cp311-none-win_amd64.whl", hash = "sha256:6514449d2c202a75183f807bc755167713297c69f1db57a89a1ef4a0170ee269"}, + {file = "orjson-3.10.10.tar.gz", hash = "sha256:37949383c4df7b4337ce82ee35b6d7471e55195efa7dcb45ab8226ceadb0fe3b"}, ] [[package]] @@ -709,7 +709,7 @@ files = [ [[package]] name = "quart" -version = "0.19.6" +version = "0.19.8" requires_python = ">=3.8" summary = "A Python ASGI web microframework with the same API as Flask" groups = ["default"] @@ -727,35 +727,35 @@ dependencies = [ "werkzeug>=3.0.0", ] files = [ - {file = "quart-0.19.6-py3-none-any.whl", hash = "sha256:f9092310f4eb120903da692a5e4354f05d48c28ca7ec3054d3d94dd862412c58"}, - {file = "quart-0.19.6.tar.gz", hash = "sha256:89ddda6da24300a5ea4f21e4582d5e89bc8ea678e724e0b747767143401e4558"}, + {file = "quart-0.19.8-py3-none-any.whl", hash = "sha256:34eeb559014f4e72e093d034cfe203b1a6262e9d3504f826f293090e230609f2"}, + {file = "quart-0.19.8.tar.gz", hash = "sha256:ef567d0be7677c99890d5c6ff30e679699fe7e5fca1a90fa3b6974edd8421794"}, ] [[package]] name = "ruff" -version = "0.7.0" +version = "0.7.1" requires_python = ">=3.7" summary = "An extremely fast Python linter and code formatter, written in Rust." groups = ["dev"] files = [ - {file = "ruff-0.7.0-py3-none-linux_armv6l.whl", hash = "sha256:0cdf20c2b6ff98e37df47b2b0bd3a34aaa155f59a11182c1303cce79be715628"}, - {file = "ruff-0.7.0-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:496494d350c7fdeb36ca4ef1c9f21d80d182423718782222c29b3e72b3512737"}, - {file = "ruff-0.7.0-py3-none-macosx_11_0_arm64.whl", hash = "sha256:214b88498684e20b6b2b8852c01d50f0651f3cc6118dfa113b4def9f14faaf06"}, - {file = "ruff-0.7.0-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:630fce3fefe9844e91ea5bbf7ceadab4f9981f42b704fae011bb8efcaf5d84be"}, - {file = "ruff-0.7.0-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:211d877674e9373d4bb0f1c80f97a0201c61bcd1e9d045b6e9726adc42c156aa"}, - {file = "ruff-0.7.0-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:194d6c46c98c73949a106425ed40a576f52291c12bc21399eb8f13a0f7073495"}, - {file = "ruff-0.7.0-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:82c2579b82b9973a110fab281860403b397c08c403de92de19568f32f7178598"}, - {file = "ruff-0.7.0-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:9af971fe85dcd5eaed8f585ddbc6bdbe8c217fb8fcf510ea6bca5bdfff56040e"}, - {file = "ruff-0.7.0-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b641c7f16939b7d24b7bfc0be4102c56562a18281f84f635604e8a6989948914"}, - {file = "ruff-0.7.0-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d71672336e46b34e0c90a790afeac8a31954fd42872c1f6adaea1dff76fd44f9"}, - {file = "ruff-0.7.0-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:ab7d98c7eed355166f367597e513a6c82408df4181a937628dbec79abb2a1fe4"}, - {file = "ruff-0.7.0-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:1eb54986f770f49edb14f71d33312d79e00e629a57387382200b1ef12d6a4ef9"}, - {file = "ruff-0.7.0-py3-none-musllinux_1_2_i686.whl", hash = "sha256:dc452ba6f2bb9cf8726a84aa877061a2462afe9ae0ea1d411c53d226661c601d"}, - {file = "ruff-0.7.0-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:4b406c2dce5be9bad59f2de26139a86017a517e6bcd2688da515481c05a2cb11"}, - {file = "ruff-0.7.0-py3-none-win32.whl", hash = "sha256:f6c968509f767776f524a8430426539587d5ec5c662f6addb6aa25bc2e8195ec"}, - {file = "ruff-0.7.0-py3-none-win_amd64.whl", hash = "sha256:ff4aabfbaaba880e85d394603b9e75d32b0693152e16fa659a3064a85df7fce2"}, - {file = "ruff-0.7.0-py3-none-win_arm64.whl", hash = "sha256:10842f69c245e78d6adec7e1db0a7d9ddc2fff0621d730e61657b64fa36f207e"}, - {file = "ruff-0.7.0.tar.gz", hash = "sha256:47a86360cf62d9cd53ebfb0b5eb0e882193fc191c6d717e8bef4462bc3b9ea2b"}, + {file = "ruff-0.7.1-py3-none-linux_armv6l.whl", hash = "sha256:cb1bc5ed9403daa7da05475d615739cc0212e861b7306f314379d958592aaa89"}, + {file = "ruff-0.7.1-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:27c1c52a8d199a257ff1e5582d078eab7145129aa02721815ca8fa4f9612dc35"}, + {file = "ruff-0.7.1-py3-none-macosx_11_0_arm64.whl", hash = "sha256:588a34e1ef2ea55b4ddfec26bbe76bc866e92523d8c6cdec5e8aceefeff02d99"}, + {file = "ruff-0.7.1-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:94fc32f9cdf72dc75c451e5f072758b118ab8100727168a3df58502b43a599ca"}, + {file = "ruff-0.7.1-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:985818742b833bffa543a84d1cc11b5e6871de1b4e0ac3060a59a2bae3969250"}, + {file = "ruff-0.7.1-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:32f1e8a192e261366c702c5fb2ece9f68d26625f198a25c408861c16dc2dea9c"}, + {file = "ruff-0.7.1-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:699085bf05819588551b11751eff33e9ca58b1b86a6843e1b082a7de40da1565"}, + {file = "ruff-0.7.1-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:344cc2b0814047dc8c3a8ff2cd1f3d808bb23c6658db830d25147339d9bf9ea7"}, + {file = "ruff-0.7.1-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:4316bbf69d5a859cc937890c7ac7a6551252b6a01b1d2c97e8fc96e45a7c8b4a"}, + {file = "ruff-0.7.1-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:79d3af9dca4c56043e738a4d6dd1e9444b6d6c10598ac52d146e331eb155a8ad"}, + {file = "ruff-0.7.1-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:c5c121b46abde94a505175524e51891f829414e093cd8326d6e741ecfc0a9112"}, + {file = "ruff-0.7.1-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:8422104078324ea250886954e48f1373a8fe7de59283d747c3a7eca050b4e378"}, + {file = "ruff-0.7.1-py3-none-musllinux_1_2_i686.whl", hash = "sha256:56aad830af8a9db644e80098fe4984a948e2b6fc2e73891538f43bbe478461b8"}, + {file = "ruff-0.7.1-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:658304f02f68d3a83c998ad8bf91f9b4f53e93e5412b8f2388359d55869727fd"}, + {file = "ruff-0.7.1-py3-none-win32.whl", hash = "sha256:b517a2011333eb7ce2d402652ecaa0ac1a30c114fbbd55c6b8ee466a7f600ee9"}, + {file = "ruff-0.7.1-py3-none-win_amd64.whl", hash = "sha256:f38c41fcde1728736b4eb2b18850f6d1e3eedd9678c914dede554a70d5241307"}, + {file = "ruff-0.7.1-py3-none-win_arm64.whl", hash = "sha256:19aa200ec824c0f36d0c9114c8ec0087082021732979a359d6f3c390a6ff2a37"}, + {file = "ruff-0.7.1.tar.gz", hash = "sha256:9d8a41d4aa2dad1575adb98a82870cf5db5f76b2938cf2206c22c940034a36f4"}, ] [[package]] @@ -854,7 +854,7 @@ files = [ [[package]] name = "werkzeug" -version = "3.0.4" +version = "3.0.6" requires_python = ">=3.8" summary = "The comprehensive WSGI web application library." groups = ["default"] @@ -862,8 +862,8 @@ dependencies = [ "MarkupSafe>=2.1.1", ] files = [ - {file = "werkzeug-3.0.4-py3-none-any.whl", hash = "sha256:02c9eb92b7d6c06f31a782811505d2157837cea66aaede3e217c7c27c039476c"}, - {file = "werkzeug-3.0.4.tar.gz", hash = "sha256:34f2371506b250df4d4f84bfe7b0921e4762525762bbd936614909fe25cd7306"}, + {file = "werkzeug-3.0.6-py3-none-any.whl", hash = "sha256:1bc0c2310d2fbb07b1dd1105eba2f7af72f322e1e455f2f93c993bee8c8a5f17"}, + {file = "werkzeug-3.0.6.tar.gz", hash = "sha256:a8dd59d4de28ca70471a34cba79bed5f7ef2e036a76b3ab0835474246eb41f8d"}, ] [[package]] @@ -903,7 +903,7 @@ files = [ [[package]] name = "yarl" -version = "1.15.5" +version = "1.16.0" requires_python = ">=3.9" summary = "Yet another URL library" groups = ["default"] @@ -913,22 +913,22 @@ dependencies = [ "propcache>=0.2.0", ] files = [ - {file = "yarl-1.15.5-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:e652aa9f8dfa808bc5b2da4d1f4e286cf1d640570fdfa72ffc0c1d16ba114651"}, - {file = "yarl-1.15.5-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:21050b6cd569980fe20ceeab4baeb900d3f7247270475e42bafe117416a5496c"}, - {file = "yarl-1.15.5-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:18940191ec9a83bbfe63eea61c3e9d12474bb910d5613bce8fa46e84a80b75b2"}, - {file = "yarl-1.15.5-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a082dc948045606f62dca0228ab24f13737180b253378d6443f5b2b9ef8beefe"}, - {file = "yarl-1.15.5-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:0a843e692f9d5402b3455653f4607dc521de2385f01c5cad7ba4a87c46e2ea8d"}, - {file = "yarl-1.15.5-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5093a453176a4fad4f9c3006f507cf300546190bb3e27944275a37cfd6323a65"}, - {file = "yarl-1.15.5-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2597a589859b94d0a5e2f5d30fee95081867926e57cb751f8b44a7dd92da4e79"}, - {file = "yarl-1.15.5-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1f5a1ca6eaabfe62718b87eac06d9a47b30cf92ffa065fee9196d3ecd24a3cf1"}, - {file = "yarl-1.15.5-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:4ac83b307cc4b8907345b52994055c6c3c2601ceb6fcb94c5ed6a93c6b4e8257"}, - {file = "yarl-1.15.5-cp311-cp311-musllinux_1_2_armv7l.whl", hash = "sha256:325e2beb2cd8654b276e7686a3cd203628dd3fe32d5c616e632bc35a2901fb16"}, - {file = "yarl-1.15.5-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:75d04ba8ed335042328086e643e01165e0c24598216f72da709b375930ae3bdb"}, - {file = "yarl-1.15.5-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:7abd7d15aedb3961a967cc65f8144dbbca42e3626a21c5f4f29919cf43eeafb9"}, - {file = "yarl-1.15.5-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:294c742a273f44511f14b03a9e06b66094dcdf4bbb75a5e23fead548fd5310ae"}, - {file = "yarl-1.15.5-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:63d46606b20f80a6476f1044bab78e1a69c2e0747f174583e2f12fc70bad2170"}, - {file = "yarl-1.15.5-cp311-cp311-win32.whl", hash = "sha256:b1217102a455e3ac9ac293081093f21f0183e978c7692171ff669fee5296fa28"}, - {file = "yarl-1.15.5-cp311-cp311-win_amd64.whl", hash = "sha256:5848500b6a01497560969e8c3a7eb1b2570853c74a0ca6f67ebaf6064106c49b"}, - {file = "yarl-1.15.5-py3-none-any.whl", hash = "sha256:625f31d6650829fba4030b4e7bdb2d69e41510dddfa29a1da27076c199521757"}, - {file = "yarl-1.15.5.tar.gz", hash = "sha256:8249147ee81c1cf4d1dc6f26ba28a1b9d92751529f83c308ad02164bb93abd0d"}, + {file = "yarl-1.16.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:d8643975a0080f361639787415a038bfc32d29208a4bf6b783ab3075a20b1ef3"}, + {file = "yarl-1.16.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:676d96bafc8c2d0039cea0cd3fd44cee7aa88b8185551a2bb93354668e8315c2"}, + {file = "yarl-1.16.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:d9525f03269e64310416dbe6c68d3b23e5d34aaa8f47193a1c45ac568cecbc49"}, + {file = "yarl-1.16.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8b37d5ec034e668b22cf0ce1074d6c21fd2a08b90d11b1b73139b750a8b0dd97"}, + {file = "yarl-1.16.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:4f32c4cb7386b41936894685f6e093c8dfaf0960124d91fe0ec29fe439e201d0"}, + {file = "yarl-1.16.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5b8e265a0545637492a7e12fd7038370d66c9375a61d88c5567d0e044ded9202"}, + {file = "yarl-1.16.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:789a3423f28a5fff46fbd04e339863c169ece97c827b44de16e1a7a42bc915d2"}, + {file = "yarl-1.16.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f1d1f45e3e8d37c804dca99ab3cf4ab3ed2e7a62cd82542924b14c0a4f46d243"}, + {file = "yarl-1.16.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:621280719c4c5dad4c1391160a9b88925bb8b0ff6a7d5af3224643024871675f"}, + {file = "yarl-1.16.0-cp311-cp311-musllinux_1_2_armv7l.whl", hash = "sha256:ed097b26f18a1f5ff05f661dc36528c5f6735ba4ce8c9645e83b064665131349"}, + {file = "yarl-1.16.0-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:2f1fe2b2e3ee418862f5ebc0c0083c97f6f6625781382f828f6d4e9b614eba9b"}, + {file = "yarl-1.16.0-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:87dd10bc0618991c66cee0cc65fa74a45f4ecb13bceec3c62d78ad2e42b27a16"}, + {file = "yarl-1.16.0-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:4199db024b58a8abb2cfcedac7b1292c3ad421684571aeb622a02f242280e8d6"}, + {file = "yarl-1.16.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:99a9dcd4b71dd5f5f949737ab3f356cfc058c709b4f49833aeffedc2652dac56"}, + {file = "yarl-1.16.0-cp311-cp311-win32.whl", hash = "sha256:a9394c65ae0ed95679717d391c862dece9afacd8fa311683fc8b4362ce8a410c"}, + {file = "yarl-1.16.0-cp311-cp311-win_amd64.whl", hash = "sha256:5b9101f528ae0f8f65ac9d64dda2bb0627de8a50344b2f582779f32fda747c1d"}, + {file = "yarl-1.16.0-py3-none-any.whl", hash = "sha256:e6980a558d8461230c457218bd6c92dfc1d10205548215c2c21d79dc8d0a96f3"}, + {file = "yarl-1.16.0.tar.gz", hash = "sha256:b6f687ced5510a9a2474bbae96a4352e5ace5fa34dc44a217b0537fec1db00b4"}, ] diff --git a/requirements.txt b/requirements.txt index 22e579a..e677024 100644 --- a/requirements.txt +++ b/requirements.txt @@ -12,7 +12,7 @@ click==8.1.7 colorama==0.4.6; sys_platform == "win32" or platform_system == "Windows" coloredlogs==15.0.1 flask==3.0.3 -frozenlist==1.4.1 +frozenlist==1.5.0 h11==0.14.0 h2==4.1.0 hpack==4.0.0 @@ -24,7 +24,7 @@ itsdangerous==2.2.0 jinja2==3.1.4 markupsafe==3.0.2 multidict==6.1.0 -orjson==3.10.9 +orjson==3.10.10 priority==2.0.0 propcache==0.2.0 py-cord==2.6.1 @@ -34,9 +34,9 @@ pyreadline3==3.5.4; sys_platform == "win32" and python_version >= "3.8" python-dotenv==1.0.1 pytz==2024.2 pyyaml==6.0.2 -quart==0.19.6 +quart==0.19.8 schema==0.7.7 typing-extensions==4.12.2 -werkzeug==3.0.4 +werkzeug==3.0.6 wsproto==1.2.0 -yarl==1.15.5 +yarl==1.16.0 From 55a6f6df7368a2f1b789ae35918081897dd0698c Mon Sep 17 00:00:00 2001 From: Paillat Date: Tue, 5 Nov 2024 16:40:36 +0100 Subject: [PATCH 03/61] :rotating_light: Add stricter linter rules --- pdm.lock | 165 ++++++++++-------- pyproject.toml | 48 ++++- requirements.txt | 8 +- scripts/check_listings/__main__.py | 43 +++-- .../listings/DiscordAppDirectory.py | 5 +- .../listings/DiscordBotListCom.py | 9 +- .../check_listings/listings/DiscordBotsGg.py | 9 +- scripts/check_listings/listings/DiscordMe.py | 9 +- .../check_listings/listings/DiscordsCom.py | 5 +- .../check_listings/listings/DisforgeCom.py | 11 +- scripts/check_listings/listings/Listing.py | 24 +-- scripts/check_listings/listings/TopGg.py | 9 +- .../check_listings/listings/WumpusStore.py | 5 +- scripts/check_listings/listings/__init__.py | 10 +- scripts/check_listings/main.py | 46 ++--- src/__main__.py | 21 +-- src/config/bot_config.py | 19 +- src/custom/__init__.py | 48 +++-- src/extensions/add-dm/__init__.py | 2 +- src/extensions/add-dm/main.py | 13 +- src/extensions/branding/__init__.py | 2 +- src/extensions/branding/branding.py | 74 ++++---- src/extensions/listings/__init__.py | 2 +- src/extensions/listings/main.py | 45 ++--- src/extensions/nice-errors/__init__.py | 2 +- src/extensions/nice-errors/handler.py | 48 +++-- src/extensions/nice-errors/main.py | 17 +- src/extensions/nice-errors/patch.py | 7 +- src/extensions/ping/__init__.py | 2 +- src/extensions/ping/ping.py | 73 +++----- src/extensions/status-post/__init__.py | 2 +- src/extensions/status-post/main.py | 33 ++-- src/i18n/__init__.py | 2 +- src/i18n/classes.py | 27 ++- src/i18n/utils.py | 84 ++++----- src/log/logger.py | 14 +- src/start.py | 86 +++++---- src/utils/__init__.py | 2 +- src/utils/extensions.py | 68 ++++---- src/utils/iterator.py | 2 +- src/utils/setup_func.py | 9 +- tests/schema_test.py | 7 +- 42 files changed, 550 insertions(+), 567 deletions(-) diff --git a/pdm.lock b/pdm.lock index 2ab0c40..149e458 100644 --- a/pdm.lock +++ b/pdm.lock @@ -5,11 +5,25 @@ groups = ["default", "dev", "sentry"] strategy = ["cross_platform", "inherit_metadata"] lock_version = "4.5.0" -content_hash = "sha256:491e4bbe6437101ad444040932efea4d74a7703ecb311148451f26b0c2a53410" +content_hash = "sha256:b06e1d1395ab9f1209cf4735fd34ecdd527665c735dbdfe5f6cb6a9541afa138" [[metadata.targets]] requires_python = "==3.11.*" +[[package]] +name = "aiofile" +version = "3.9.0" +requires_python = "<4,>=3.8" +summary = "Asynchronous file operations." +groups = ["default"] +dependencies = [ + "caio<0.10.0,>=0.9.0", +] +files = [ + {file = "aiofile-3.9.0-py3-none-any.whl", hash = "sha256:ce2f6c1571538cbdfa0143b04e16b208ecb0e9cb4148e528af8a640ed51cc8aa"}, + {file = "aiofile-3.9.0.tar.gz", hash = "sha256:e5ad718bb148b265b6df1b3752c4d1d83024b93da9bd599df74b9d9ffcf7919b"}, +] + [[package]] name = "aiofiles" version = "24.1.0" @@ -110,7 +124,7 @@ files = [ [[package]] name = "basedpyright" -version = "1.19.1" +version = "1.20.0" requires_python = ">=3.8" summary = "static type checking for Python (but based)" groups = ["dev"] @@ -118,8 +132,8 @@ dependencies = [ "nodejs-wheel-binaries>=20.13.1", ] files = [ - {file = "basedpyright-1.19.1-py3-none-any.whl", hash = "sha256:976744146fcecb7413a726fbb8e52f4606738e02820a7dfbe310199f8915311e"}, - {file = "basedpyright-1.19.1.tar.gz", hash = "sha256:2863e619296ddd7f9f566c44e4fa8f781d727a83fa2da6ef62951e0b657655f6"}, + {file = "basedpyright-1.20.0-py3-none-any.whl", hash = "sha256:65de9f930ca327e74f2281da8e9b51d56a04efb25a1ba8ec5767c21751cdb2c3"}, + {file = "basedpyright-1.20.0.tar.gz", hash = "sha256:0a9573b3947927dad915b13db520f48810676b9b0b894128743d5f442134b361"}, ] [[package]] @@ -147,6 +161,19 @@ files = [ {file = "blinker-1.8.2.tar.gz", hash = "sha256:8f77b09d3bf7c795e969e9486f39c2c5e9c39d4ee07424be2bc594ece9642d83"}, ] +[[package]] +name = "caio" +version = "0.9.17" +requires_python = "<4,>=3.7" +summary = "Asynchronous file IO for Linux MacOS or Windows." +groups = ["default"] +files = [ + {file = "caio-0.9.17-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:079730a353bbde03796fab681e969472eace09ffbe5000e584868a7fe389ba6f"}, + {file = "caio-0.9.17-cp311-cp311-manylinux_2_12_x86_64.manylinux2010_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:549caa51b475877fe32856a26fe937366ae7a1c23a9727005b441db9abb12bcc"}, + {file = "caio-0.9.17-py3-none-any.whl", hash = "sha256:c55d4dc6b3a36f93237ecd6360e1c131c3808bc47d4191a130148a99b80bb311"}, + {file = "caio-0.9.17.tar.gz", hash = "sha256:8f30511526814d961aeef389ea6885273abe6c655f1e08abbadb95d12fdd9b4f"}, +] + [[package]] name = "certifi" version = "2024.8.30" @@ -469,18 +496,18 @@ files = [ [[package]] name = "nodejs-wheel-binaries" -version = "20.18.0" +version = "22.11.0" requires_python = ">=3.7" summary = "unoffical Node.js package" groups = ["dev"] files = [ - {file = "nodejs_wheel_binaries-20.18.0-py2.py3-none-macosx_10_15_x86_64.whl", hash = "sha256:74273eab1c2423c04d034d3f707f517da32d3a2b20ca244b5667f3a4e38003ac"}, - {file = "nodejs_wheel_binaries-20.18.0-py2.py3-none-macosx_11_0_arm64.whl", hash = "sha256:f95fb0989dfc54fd6932850e589000a8d6fc902527cebe7afd747696561d94b8"}, - {file = "nodejs_wheel_binaries-20.18.0-py2.py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f62e38288d3a129b962dcba61b911d72b3d691935b8a2facfc0fa9433d9260b5"}, - {file = "nodejs_wheel_binaries-20.18.0-py2.py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:33b138288dbeb9aafc6d54f43fbca6545b37e8fd9cbb8f68275ff2a47d4fed07"}, - {file = "nodejs_wheel_binaries-20.18.0-py2.py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:bb4009d4d6abfb6765fabb62f322efdc520b6930d041af1d7f64d58445ce3e91"}, - {file = "nodejs_wheel_binaries-20.18.0-py2.py3-none-win_amd64.whl", hash = "sha256:51c0cecb429a111351a54346909e672a57b96233a363c79cc0a2bbdbfa397304"}, - {file = "nodejs_wheel_binaries-20.18.0.tar.gz", hash = "sha256:1d574a3d0e503b42414e80b4529da9fc71104b0d5e1d75606b3fb5802960fb6f"}, + {file = "nodejs_wheel_binaries-22.11.0-py2.py3-none-macosx_11_0_arm64.whl", hash = "sha256:00afada277fd6e945a74f881831aaf1bb7f853a15e15e8c998238ab88d327f6a"}, + {file = "nodejs_wheel_binaries-22.11.0-py2.py3-none-macosx_11_0_x86_64.whl", hash = "sha256:f29471263d65a66520a04a0e74ff641a775df1135283f0b4d1826048932b289d"}, + {file = "nodejs_wheel_binaries-22.11.0-py2.py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bd2ff0e20389f22927e311ccab69c1ecb34c3431fa809d1548e7000dc8248680"}, + {file = "nodejs_wheel_binaries-22.11.0-py2.py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a9545cc43f1ba2c9f467f3444e9cd7f8db059933be1a5215135610dee5b38bf3"}, + {file = "nodejs_wheel_binaries-22.11.0-py2.py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:43a277cbabf4b68e0a4798578a4f17e5f518ada1f79a174bfde06eb2bb47e730"}, + {file = "nodejs_wheel_binaries-22.11.0-py2.py3-none-win_amd64.whl", hash = "sha256:8310ab182ee159141e08c85bc07f11e67ac3044922e6e4958f4a8f3ba6860185"}, + {file = "nodejs_wheel_binaries-22.11.0.tar.gz", hash = "sha256:e67f4e4a646bba24baa2150460c9cfbde0f75169ba37e58a2341930a5c1456ee"}, ] [[package]] @@ -501,22 +528,22 @@ files = [ [[package]] name = "orjson" -version = "3.10.10" +version = "3.10.11" requires_python = ">=3.8" summary = "Fast, correct Python JSON library supporting dataclasses, datetimes, and numpy" groups = ["default"] files = [ - {file = "orjson-3.10.10-cp311-cp311-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:879e99486c0fbb256266c7c6a67ff84f46035e4f8749ac6317cc83dacd7f993a"}, - {file = "orjson-3.10.10-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:019481fa9ea5ff13b5d5d95e6fd5ab25ded0810c80b150c2c7b1cc8660b662a7"}, - {file = "orjson-3.10.10-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:0dd57eff09894938b4c86d4b871a479260f9e156fa7f12f8cad4b39ea8028bb5"}, - {file = "orjson-3.10.10-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:dbde6d70cd95ab4d11ea8ac5e738e30764e510fc54d777336eec09bb93b8576c"}, - {file = "orjson-3.10.10-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3b2625cb37b8fb42e2147404e5ff7ef08712099197a9cd38895006d7053e69d6"}, - {file = "orjson-3.10.10-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dbf3c20c6a7db69df58672a0d5815647ecf78c8e62a4d9bd284e8621c1fe5ccb"}, - {file = "orjson-3.10.10-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:75c38f5647e02d423807d252ce4528bf6a95bd776af999cb1fb48867ed01d1f6"}, - {file = "orjson-3.10.10-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:23458d31fa50ec18e0ec4b0b4343730928296b11111df5f547c75913714116b2"}, - {file = "orjson-3.10.10-cp311-none-win32.whl", hash = "sha256:2787cd9dedc591c989f3facd7e3e86508eafdc9536a26ec277699c0aa63c685b"}, - {file = "orjson-3.10.10-cp311-none-win_amd64.whl", hash = "sha256:6514449d2c202a75183f807bc755167713297c69f1db57a89a1ef4a0170ee269"}, - {file = "orjson-3.10.10.tar.gz", hash = "sha256:37949383c4df7b4337ce82ee35b6d7471e55195efa7dcb45ab8226ceadb0fe3b"}, + {file = "orjson-3.10.11-cp311-cp311-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:1444f9cb7c14055d595de1036f74ecd6ce15f04a715e73f33bb6326c9cef01b6"}, + {file = "orjson-3.10.11-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:cdec57fe3b4bdebcc08a946db3365630332dbe575125ff3d80a3272ebd0ddafe"}, + {file = "orjson-3.10.11-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:4eed32f33a0ea6ef36ccc1d37f8d17f28a1d6e8eefae5928f76aff8f1df85e67"}, + {file = "orjson-3.10.11-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:80df27dd8697242b904f4ea54820e2d98d3f51f91e97e358fc13359721233e4b"}, + {file = "orjson-3.10.11-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:705f03cee0cb797256d54de6695ef219e5bc8c8120b6654dd460848d57a9af3d"}, + {file = "orjson-3.10.11-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:03246774131701de8e7059b2e382597da43144a9a7400f178b2a32feafc54bd5"}, + {file = "orjson-3.10.11-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:8b5759063a6c940a69c728ea70d7c33583991c6982915a839c8da5f957e0103a"}, + {file = "orjson-3.10.11-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:677f23e32491520eebb19c99bb34675daf5410c449c13416f7f0d93e2cf5f981"}, + {file = "orjson-3.10.11-cp311-none-win32.whl", hash = "sha256:a11225d7b30468dcb099498296ffac36b4673a8398ca30fdaec1e6c20df6aa55"}, + {file = "orjson-3.10.11-cp311-none-win_amd64.whl", hash = "sha256:df8c677df2f9f385fcc85ab859704045fa88d4668bc9991a527c86e710392bec"}, + {file = "orjson-3.10.11.tar.gz", hash = "sha256:e35b6d730de6384d5b2dab5fd23f0d76fae8bbc8c353c2f78210aa5fa4beb3ef"}, ] [[package]] @@ -733,29 +760,29 @@ files = [ [[package]] name = "ruff" -version = "0.7.1" +version = "0.7.2" requires_python = ">=3.7" summary = "An extremely fast Python linter and code formatter, written in Rust." groups = ["dev"] files = [ - {file = "ruff-0.7.1-py3-none-linux_armv6l.whl", hash = "sha256:cb1bc5ed9403daa7da05475d615739cc0212e861b7306f314379d958592aaa89"}, - {file = "ruff-0.7.1-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:27c1c52a8d199a257ff1e5582d078eab7145129aa02721815ca8fa4f9612dc35"}, - {file = "ruff-0.7.1-py3-none-macosx_11_0_arm64.whl", hash = "sha256:588a34e1ef2ea55b4ddfec26bbe76bc866e92523d8c6cdec5e8aceefeff02d99"}, - {file = "ruff-0.7.1-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:94fc32f9cdf72dc75c451e5f072758b118ab8100727168a3df58502b43a599ca"}, - {file = "ruff-0.7.1-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:985818742b833bffa543a84d1cc11b5e6871de1b4e0ac3060a59a2bae3969250"}, - {file = "ruff-0.7.1-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:32f1e8a192e261366c702c5fb2ece9f68d26625f198a25c408861c16dc2dea9c"}, - {file = "ruff-0.7.1-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:699085bf05819588551b11751eff33e9ca58b1b86a6843e1b082a7de40da1565"}, - {file = "ruff-0.7.1-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:344cc2b0814047dc8c3a8ff2cd1f3d808bb23c6658db830d25147339d9bf9ea7"}, - {file = "ruff-0.7.1-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:4316bbf69d5a859cc937890c7ac7a6551252b6a01b1d2c97e8fc96e45a7c8b4a"}, - {file = "ruff-0.7.1-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:79d3af9dca4c56043e738a4d6dd1e9444b6d6c10598ac52d146e331eb155a8ad"}, - {file = "ruff-0.7.1-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:c5c121b46abde94a505175524e51891f829414e093cd8326d6e741ecfc0a9112"}, - {file = "ruff-0.7.1-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:8422104078324ea250886954e48f1373a8fe7de59283d747c3a7eca050b4e378"}, - {file = "ruff-0.7.1-py3-none-musllinux_1_2_i686.whl", hash = "sha256:56aad830af8a9db644e80098fe4984a948e2b6fc2e73891538f43bbe478461b8"}, - {file = "ruff-0.7.1-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:658304f02f68d3a83c998ad8bf91f9b4f53e93e5412b8f2388359d55869727fd"}, - {file = "ruff-0.7.1-py3-none-win32.whl", hash = "sha256:b517a2011333eb7ce2d402652ecaa0ac1a30c114fbbd55c6b8ee466a7f600ee9"}, - {file = "ruff-0.7.1-py3-none-win_amd64.whl", hash = "sha256:f38c41fcde1728736b4eb2b18850f6d1e3eedd9678c914dede554a70d5241307"}, - {file = "ruff-0.7.1-py3-none-win_arm64.whl", hash = "sha256:19aa200ec824c0f36d0c9114c8ec0087082021732979a359d6f3c390a6ff2a37"}, - {file = "ruff-0.7.1.tar.gz", hash = "sha256:9d8a41d4aa2dad1575adb98a82870cf5db5f76b2938cf2206c22c940034a36f4"}, + {file = "ruff-0.7.2-py3-none-linux_armv6l.whl", hash = "sha256:b73f873b5f52092e63ed540adefc3c36f1f803790ecf2590e1df8bf0a9f72cb8"}, + {file = "ruff-0.7.2-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:5b813ef26db1015953daf476202585512afd6a6862a02cde63f3bafb53d0b2d4"}, + {file = "ruff-0.7.2-py3-none-macosx_11_0_arm64.whl", hash = "sha256:853277dbd9675810c6826dad7a428d52a11760744508340e66bf46f8be9701d9"}, + {file = "ruff-0.7.2-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:21aae53ab1490a52bf4e3bf520c10ce120987b047c494cacf4edad0ba0888da2"}, + {file = "ruff-0.7.2-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:ccc7e0fc6e0cb3168443eeadb6445285abaae75142ee22b2b72c27d790ab60ba"}, + {file = "ruff-0.7.2-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:fd77877a4e43b3a98e5ef4715ba3862105e299af0c48942cc6d51ba3d97dc859"}, + {file = "ruff-0.7.2-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:e00163fb897d35523c70d71a46fbaa43bf7bf9af0f4534c53ea5b96b2e03397b"}, + {file = "ruff-0.7.2-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f3c54b538633482dc342e9b634d91168fe8cc56b30a4b4f99287f4e339103e88"}, + {file = "ruff-0.7.2-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:7b792468e9804a204be221b14257566669d1db5c00d6bb335996e5cd7004ba80"}, + {file = "ruff-0.7.2-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dba53ed84ac19ae4bfb4ea4bf0172550a2285fa27fbb13e3746f04c80f7fa088"}, + {file = "ruff-0.7.2-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:b19fafe261bf741bca2764c14cbb4ee1819b67adb63ebc2db6401dcd652e3748"}, + {file = "ruff-0.7.2-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:28bd8220f4d8f79d590db9e2f6a0674f75ddbc3847277dd44ac1f8d30684b828"}, + {file = "ruff-0.7.2-py3-none-musllinux_1_2_i686.whl", hash = "sha256:9fd67094e77efbea932e62b5d2483006154794040abb3a5072e659096415ae1e"}, + {file = "ruff-0.7.2-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:576305393998b7bd6c46018f8104ea3a9cb3fa7908c21d8580e3274a3b04b691"}, + {file = "ruff-0.7.2-py3-none-win32.whl", hash = "sha256:fa993cfc9f0ff11187e82de874dfc3611df80852540331bc85c75809c93253a8"}, + {file = "ruff-0.7.2-py3-none-win_amd64.whl", hash = "sha256:dd8800cbe0254e06b8fec585e97554047fb82c894973f7ff18558eee33d1cb88"}, + {file = "ruff-0.7.2-py3-none-win_arm64.whl", hash = "sha256:bb8368cd45bba3f57bb29cbb8d64b4a33f8415d0149d2655c5c8539452ce7760"}, + {file = "ruff-0.7.2.tar.gz", hash = "sha256:2b14e77293380e475b4e3a7a368e14549288ed2931fce259a6f99978669e844f"}, ] [[package]] @@ -773,7 +800,7 @@ files = [ [[package]] name = "sentry-sdk" -version = "2.17.0" +version = "2.18.0" requires_python = ">=3.6" summary = "Python client for Sentry (https://sentry.io)" groups = ["sentry"] @@ -782,8 +809,8 @@ dependencies = [ "urllib3>=1.26.11", ] files = [ - {file = "sentry_sdk-2.17.0-py2.py3-none-any.whl", hash = "sha256:625955884b862cc58748920f9e21efdfb8e0d4f98cca4ab0d3918576d5b606ad"}, - {file = "sentry_sdk-2.17.0.tar.gz", hash = "sha256:dd0a05352b78ffeacced73a94e86f38b32e2eae15fff5f30ca5abb568a72eacf"}, + {file = "sentry_sdk-2.18.0-py2.py3-none-any.whl", hash = "sha256:ee70e27d1bbe4cd52a38e1bd28a5fadb9b17bc29d91b5f2b97ae29c0a7610442"}, + {file = "sentry_sdk-2.18.0.tar.gz", hash = "sha256:0dc21febd1ab35c648391c664df96f5f79fb0d92d7d4225cd9832e53a617cafd"}, ] [[package]] @@ -854,16 +881,16 @@ files = [ [[package]] name = "werkzeug" -version = "3.0.6" -requires_python = ">=3.8" +version = "3.1.2" +requires_python = ">=3.9" summary = "The comprehensive WSGI web application library." groups = ["default"] dependencies = [ "MarkupSafe>=2.1.1", ] files = [ - {file = "werkzeug-3.0.6-py3-none-any.whl", hash = "sha256:1bc0c2310d2fbb07b1dd1105eba2f7af72f322e1e455f2f93c993bee8c8a5f17"}, - {file = "werkzeug-3.0.6.tar.gz", hash = "sha256:a8dd59d4de28ca70471a34cba79bed5f7ef2e036a76b3ab0835474246eb41f8d"}, + {file = "werkzeug-3.1.2-py3-none-any.whl", hash = "sha256:4f7d1a5de312c810a8a2c6f0b47e9f6a7cffb7c8322def35e4d4d9841ff85597"}, + {file = "werkzeug-3.1.2.tar.gz", hash = "sha256:f471a4cd167233077e9d2a8190c3471c5bc520c636a9e3c1e9300c33bced03bc"}, ] [[package]] @@ -903,7 +930,7 @@ files = [ [[package]] name = "yarl" -version = "1.16.0" +version = "1.17.1" requires_python = ">=3.9" summary = "Yet another URL library" groups = ["default"] @@ -913,22 +940,22 @@ dependencies = [ "propcache>=0.2.0", ] files = [ - {file = "yarl-1.16.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:d8643975a0080f361639787415a038bfc32d29208a4bf6b783ab3075a20b1ef3"}, - {file = "yarl-1.16.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:676d96bafc8c2d0039cea0cd3fd44cee7aa88b8185551a2bb93354668e8315c2"}, - {file = "yarl-1.16.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:d9525f03269e64310416dbe6c68d3b23e5d34aaa8f47193a1c45ac568cecbc49"}, - {file = "yarl-1.16.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8b37d5ec034e668b22cf0ce1074d6c21fd2a08b90d11b1b73139b750a8b0dd97"}, - {file = "yarl-1.16.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:4f32c4cb7386b41936894685f6e093c8dfaf0960124d91fe0ec29fe439e201d0"}, - {file = "yarl-1.16.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5b8e265a0545637492a7e12fd7038370d66c9375a61d88c5567d0e044ded9202"}, - {file = "yarl-1.16.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:789a3423f28a5fff46fbd04e339863c169ece97c827b44de16e1a7a42bc915d2"}, - {file = "yarl-1.16.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f1d1f45e3e8d37c804dca99ab3cf4ab3ed2e7a62cd82542924b14c0a4f46d243"}, - {file = "yarl-1.16.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:621280719c4c5dad4c1391160a9b88925bb8b0ff6a7d5af3224643024871675f"}, - {file = "yarl-1.16.0-cp311-cp311-musllinux_1_2_armv7l.whl", hash = "sha256:ed097b26f18a1f5ff05f661dc36528c5f6735ba4ce8c9645e83b064665131349"}, - {file = "yarl-1.16.0-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:2f1fe2b2e3ee418862f5ebc0c0083c97f6f6625781382f828f6d4e9b614eba9b"}, - {file = "yarl-1.16.0-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:87dd10bc0618991c66cee0cc65fa74a45f4ecb13bceec3c62d78ad2e42b27a16"}, - {file = "yarl-1.16.0-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:4199db024b58a8abb2cfcedac7b1292c3ad421684571aeb622a02f242280e8d6"}, - {file = "yarl-1.16.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:99a9dcd4b71dd5f5f949737ab3f356cfc058c709b4f49833aeffedc2652dac56"}, - {file = "yarl-1.16.0-cp311-cp311-win32.whl", hash = "sha256:a9394c65ae0ed95679717d391c862dece9afacd8fa311683fc8b4362ce8a410c"}, - {file = "yarl-1.16.0-cp311-cp311-win_amd64.whl", hash = "sha256:5b9101f528ae0f8f65ac9d64dda2bb0627de8a50344b2f582779f32fda747c1d"}, - {file = "yarl-1.16.0-py3-none-any.whl", hash = "sha256:e6980a558d8461230c457218bd6c92dfc1d10205548215c2c21d79dc8d0a96f3"}, - {file = "yarl-1.16.0.tar.gz", hash = "sha256:b6f687ced5510a9a2474bbae96a4352e5ace5fa34dc44a217b0537fec1db00b4"}, + {file = "yarl-1.17.1-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:cbad927ea8ed814622305d842c93412cb47bd39a496ed0f96bfd42b922b4a217"}, + {file = "yarl-1.17.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:fca4b4307ebe9c3ec77a084da3a9d1999d164693d16492ca2b64594340999988"}, + {file = "yarl-1.17.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:ff5c6771c7e3511a06555afa317879b7db8d640137ba55d6ab0d0c50425cab75"}, + {file = "yarl-1.17.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5b29beab10211a746f9846baa39275e80034e065460d99eb51e45c9a9495bcca"}, + {file = "yarl-1.17.1-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1a52a1ffdd824fb1835272e125385c32fd8b17fbdefeedcb4d543cc23b332d74"}, + {file = "yarl-1.17.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:58c8e9620eb82a189c6c40cb6b59b4e35b2ee68b1f2afa6597732a2b467d7e8f"}, + {file = "yarl-1.17.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d216e5d9b8749563c7f2c6f7a0831057ec844c68b4c11cb10fc62d4fd373c26d"}, + {file = "yarl-1.17.1-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:881764d610e3269964fc4bb3c19bb6fce55422828e152b885609ec176b41cf11"}, + {file = "yarl-1.17.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:8c79e9d7e3d8a32d4824250a9c6401194fb4c2ad9a0cec8f6a96e09a582c2cc0"}, + {file = "yarl-1.17.1-cp311-cp311-musllinux_1_2_armv7l.whl", hash = "sha256:299f11b44d8d3a588234adbe01112126010bd96d9139c3ba7b3badd9829261c3"}, + {file = "yarl-1.17.1-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:cc7d768260f4ba4ea01741c1b5fe3d3a6c70eb91c87f4c8761bbcce5181beafe"}, + {file = "yarl-1.17.1-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:de599af166970d6a61accde358ec9ded821234cbbc8c6413acfec06056b8e860"}, + {file = "yarl-1.17.1-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:2b24ec55fad43e476905eceaf14f41f6478780b870eda5d08b4d6de9a60b65b4"}, + {file = "yarl-1.17.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:9fb815155aac6bfa8d86184079652c9715c812d506b22cfa369196ef4e99d1b4"}, + {file = "yarl-1.17.1-cp311-cp311-win32.whl", hash = "sha256:7615058aabad54416ddac99ade09a5510cf77039a3b903e94e8922f25ed203d7"}, + {file = "yarl-1.17.1-cp311-cp311-win_amd64.whl", hash = "sha256:14bc88baa44e1f84164a392827b5defb4fa8e56b93fecac3d15315e7c8e5d8b3"}, + {file = "yarl-1.17.1-py3-none-any.whl", hash = "sha256:f1790a4b1e8e8e028c391175433b9c8122c39b46e1663228158e61e6f915bf06"}, + {file = "yarl-1.17.1.tar.gz", hash = "sha256:067a63fcfda82da6b198fa73079b1ca40b7c9b7994995b6ee38acda728b64d47"}, ] diff --git a/pyproject.toml b/pyproject.toml index 369b524..b4434b2 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -10,7 +10,7 @@ dependencies = [ "aiohttp>=3.9.5", "pyyaml>=6.0.1", "python-dotenv>=1.0.1", - "orjson>=3.10.5", + "orjson>=3.10.7", "pytz>=2024.1", "typing-extensions>=4.12.2", "schema>=0.7.7", @@ -18,6 +18,7 @@ dependencies = [ "quart>=0.19.6", "pydantic>=2.9.2", "coloredlogs>=15.0.1", + "aiofile>=3.9.0", ] requires-python = "==3.11.*" readme = "README.md" @@ -54,3 +55,48 @@ reportAny = false reportUnusedCallResult = false reportUnknownMemberType = false pythonVersion = "3.11" + +[tool.ruff] +target-version = "py311" +line-length = 120 +indent-width = 4 + +[tool.ruff.format] +quote-style = "double" + +indent-style = "space" + +skip-magic-trailing-comma = false + +line-ending = "auto" + +docstring-code-format = false + +docstring-code-line-length = "dynamic" + +[tool.ruff.lint] +select = ["ALL"] +extend-ignore = ["N999", + "D104", + "D100", + "D103", + "D102", + "D101", + "D107", + "D105", + "D106", + "ANN401", + "ANN101", + "TRY003", + "EM101", + "EM102", + "G004", + "PTH", + "D211", + "D213", + "COM812", + "ISC001", + "D203", + "FBT001", + "FBT002" +] \ No newline at end of file diff --git a/requirements.txt b/requirements.txt index e677024..d41fbbc 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,6 +1,7 @@ # This file is @generated by PDM. # Please do not edit it manually. +aiofile==3.9.0 aiofiles==24.1.0 aiohappyeyeballs==2.4.3 aiohttp==3.10.10 @@ -8,6 +9,7 @@ aiosignal==1.3.1 annotated-types==0.7.0 attrs==24.2.0 blinker==1.8.2 +caio==0.9.17 click==8.1.7 colorama==0.4.6; sys_platform == "win32" or platform_system == "Windows" coloredlogs==15.0.1 @@ -24,7 +26,7 @@ itsdangerous==2.2.0 jinja2==3.1.4 markupsafe==3.0.2 multidict==6.1.0 -orjson==3.10.10 +orjson==3.10.11 priority==2.0.0 propcache==0.2.0 py-cord==2.6.1 @@ -37,6 +39,6 @@ pyyaml==6.0.2 quart==0.19.8 schema==0.7.7 typing-extensions==4.12.2 -werkzeug==3.0.6 +werkzeug==3.1.2 wsproto==1.2.0 -yarl==1.16.0 +yarl==1.17.1 diff --git a/scripts/check_listings/__main__.py b/scripts/check_listings/__main__.py index d429f9a..497e45b 100644 --- a/scripts/check_listings/__main__.py +++ b/scripts/check_listings/__main__.py @@ -1,39 +1,38 @@ # Copyright (c) NiceBots.xyz # SPDX-License-Identifier: MIT +import argparse import asyncio -import nodriver as uc + import markdown -import argparse +import nodriver as uc import yaml - -from termcolor import cprint +from aiofile import async_open as open # noqa: A001 from bs4 import BeautifulSoup +from termcolor import cprint from .listings import ( - normalize_soup, - TopGg, - DiscordsCom, - WumpusStore, DiscordAppDirectory, DiscordBotListCom, - DisforgeCom, DiscordBotsGg, DiscordMe, + DiscordsCom, + DisforgeCom, NotFoundError, + TopGg, + WumpusStore, + normalize_soup, ) -COMPLETED = False +completed = False -async def async_main(args): - with open("description.md", "r", encoding="utf-8") as f: +async def async_main(args: argparse.Namespace) -> None: + with open("description.md", encoding="utf-8") as f: description: str = f.read() - with open(args.config, "r", encoding="utf-8") as f: + with open(args.config, encoding="utf-8") as f: config: dict = yaml.safe_load(f) - application_id = ( - args.application_id if args.application_id else config["application_id"] - ) + application_id = args.application_id if args.application_id else config["application_id"] description = markdown.markdown(description) description = normalize_soup(BeautifulSoup(description, "html.parser")) @@ -62,18 +61,18 @@ async def async_main(args): except NotFoundError: cprint(f"{listing.name} not published", "black", "on_light_red") continue - except asyncio.TimeoutError: + except TimeoutError: cprint(f"{listing.name} timed out") continue if description == its_description: cprint(f"{listing.name} matches", "black", "on_green") else: cprint(f"{listing.name} does not match", "black", "on_yellow") - global COMPLETED - COMPLETED = True + global completed # noqa: PLW0603 + completed = True -def main(): +def main() -> None: parser = argparse.ArgumentParser( prog="Listings checker", description="Check the published status of your discord listings", @@ -84,8 +83,8 @@ def main(): args = parser.parse_args() try: asyncio.get_event_loop().run_until_complete(async_main(args)) - except Exception as e: # noqa - if not COMPLETED: + except Exception: + if not completed: raise diff --git a/scripts/check_listings/listings/DiscordAppDirectory.py b/scripts/check_listings/listings/DiscordAppDirectory.py index 3736bc8..771c83d 100644 --- a/scripts/check_listings/listings/DiscordAppDirectory.py +++ b/scripts/check_listings/listings/DiscordAppDirectory.py @@ -2,7 +2,6 @@ # SPDX-License-Identifier: MIT import nodriver as uc - from bs4 import BeautifulSoup from .Listing import Listing @@ -11,11 +10,11 @@ class DiscordAppDirectory(Listing): name: str = "Discord App Directory" - def __init__(self, browser: uc.Browser, application_id: int): + def __init__(self, browser: uc.Browser, application_id: int) -> None: super().__init__(browser) self.application_id = application_id - async def fetch_raw_description(self): + async def fetch_raw_description(self) -> str: url = f"https://discord.com/application-directory/{self.application_id}" page = await self.browser.get(url) description = await page.select(".detailedDescription_a1eac2", timeout=25) diff --git a/scripts/check_listings/listings/DiscordBotListCom.py b/scripts/check_listings/listings/DiscordBotListCom.py index 1de1474..7263d45 100644 --- a/scripts/check_listings/listings/DiscordBotListCom.py +++ b/scripts/check_listings/listings/DiscordBotListCom.py @@ -1,9 +1,8 @@ # Copyright (c) NiceBots.xyz # SPDX-License-Identifier: MIT -import nodriver as uc -import asyncio +import nodriver as uc from bs4 import BeautifulSoup from .Listing import Listing, NotFoundError @@ -12,16 +11,16 @@ class DiscordBotListCom(Listing): name: str = "DiscordBotList.com" - def __init__(self, browser: uc.Browser, url: str): + def __init__(self, browser: uc.Browser, url: str) -> None: super().__init__(browser) self.url = url - async def fetch_raw_description(self): + async def fetch_raw_description(self) -> str: page = await self.browser.get(self.url) try: await page.find("Page not found") raise NotFoundError("Listing not found") - except asyncio.TimeoutError: + except TimeoutError: pass description = await page.select("article > .markdown") html = await description.get_html() diff --git a/scripts/check_listings/listings/DiscordBotsGg.py b/scripts/check_listings/listings/DiscordBotsGg.py index 8d4c081..19bc813 100644 --- a/scripts/check_listings/listings/DiscordBotsGg.py +++ b/scripts/check_listings/listings/DiscordBotsGg.py @@ -2,7 +2,6 @@ # SPDX-License-Identifier: MIT import nodriver as uc - from bs4 import BeautifulSoup from .Listing import Listing, NotFoundError @@ -11,18 +10,18 @@ class DiscordBotsGg(Listing): name: str = "Discord.bots.gg" - def __init__(self, browser: uc.Browser, application_id: int): + def __init__(self, browser: uc.Browser, application_id: int) -> None: super().__init__(browser) self.application_id = application_id - async def fetch_raw_description(self): + async def fetch_raw_description(self) -> str: url = f"https://discord.bots.gg/bots/{self.application_id}" page = await self.browser.get(url) if ( len( await page.query_selector_all( ".error__title", - ) + ), ) != 0 ): @@ -30,4 +29,4 @@ async def fetch_raw_description(self): description = await page.select(".bot__description") html = await description.get_html() soup = BeautifulSoup(html, "html.parser") - return self.normalize_soup(soup).replace("’", "'") + return self.normalize_soup(soup).replace("’", "'") # noqa: RUF001 diff --git a/scripts/check_listings/listings/DiscordMe.py b/scripts/check_listings/listings/DiscordMe.py index 61869fb..9dea539 100644 --- a/scripts/check_listings/listings/DiscordMe.py +++ b/scripts/check_listings/listings/DiscordMe.py @@ -1,9 +1,8 @@ # Copyright (c) NiceBots.xyz # SPDX-License-Identifier: MIT -import nodriver as uc -import asyncio +import nodriver as uc from bs4 import BeautifulSoup from .Listing import Listing, NotFoundError @@ -12,16 +11,16 @@ class DiscordMe(Listing): name: str = "Discord.me" - def __init__(self, browser: uc.Browser, url: str): + def __init__(self, browser: uc.Browser, url: str) -> None: super().__init__(browser) self.url = url - async def fetch_raw_description(self): + async def fetch_raw_description(self) -> str: page = await self.browser.get(self.url) try: await page.find("Sorry, the page you are looking for could not be found.") raise NotFoundError("Listing not found") - except asyncio.TimeoutError: + except TimeoutError: pass description = await page.select(".server-sidebar > p") html = await description.get_html() diff --git a/scripts/check_listings/listings/DiscordsCom.py b/scripts/check_listings/listings/DiscordsCom.py index be38049..65d7cb1 100644 --- a/scripts/check_listings/listings/DiscordsCom.py +++ b/scripts/check_listings/listings/DiscordsCom.py @@ -2,7 +2,6 @@ # SPDX-License-Identifier: MIT import nodriver as uc - from bs4 import BeautifulSoup from .Listing import Listing, NotFoundError @@ -11,11 +10,11 @@ class DiscordsCom(Listing): name: str = "Discords.com" - def __init__(self, browser: uc.Browser, application_id: int): + def __init__(self, browser: uc.Browser, application_id: int) -> None: super().__init__(browser) self.application_id = application_id - async def fetch_raw_description(self): + async def fetch_raw_description(self) -> str: url = f"https://discords.com/bots/bot/{self.application_id}" page = await self.browser.get(url) description = await page.select("app-bot-page-description") diff --git a/scripts/check_listings/listings/DisforgeCom.py b/scripts/check_listings/listings/DisforgeCom.py index dbbd805..4db5984 100644 --- a/scripts/check_listings/listings/DisforgeCom.py +++ b/scripts/check_listings/listings/DisforgeCom.py @@ -2,27 +2,24 @@ # SPDX-License-Identifier: MIT import nodriver as uc - from bs4 import BeautifulSoup from markdown import markdown + from .Listing import Listing, NotFoundError class DisforgeCom(Listing): name: str = "Disforge.com" - def __init__(self, browser: uc.Browser, url: str): + def __init__(self, browser: uc.Browser, url: str) -> None: super().__init__(browser) self.url = url - async def fetch_raw_description(self): + async def fetch_raw_description(self) -> str: page = await self.browser.get(self.url) await page.wait(4) # if the window location is homepage, then the bot is not found - if ( - len(await page.find_elements_by_text("Vote for this bot", tag_hint="a")) - == 0 - ): + if len(await page.find_elements_by_text("Vote for this bot", tag_hint="a")) == 0: raise NotFoundError("Listing not found") description = await page.select(".card-body") html = await description.get_html() diff --git a/scripts/check_listings/listings/Listing.py b/scripts/check_listings/listings/Listing.py index 37c2f9c..ac47e3c 100644 --- a/scripts/check_listings/listings/Listing.py +++ b/scripts/check_listings/listings/Listing.py @@ -1,9 +1,9 @@ # Copyright (c) NiceBots.xyz # SPDX-License-Identifier: MIT -import nodriver as uc - from abc import ABC, abstractmethod + +import nodriver as uc from bs4 import BeautifulSoup @@ -16,32 +16,24 @@ class NotFoundError(BaseError): def normalize_soup(soup: BeautifulSoup) -> str: - """ - Normalize the text from a BeautifulSoup object - """ - return soup.get_text().strip().replace("’", "'").replace("\n", "") + """Normalize the text from a BeautifulSoup object.""" + return soup.get_text().strip().replace("’", "'").replace("\n", "") # noqa: RUF001 class Listing(ABC): - """ - Represents a Discord Bot listing website - """ + """Represents a Discord Bot listing website.""" - def __init__(self, browser: uc.Browser, *args, **kwargs): + def __init__(self, browser: uc.Browser) -> None: self.browser = browser def normalize_soup(self, soup: BeautifulSoup) -> str: - """ - Normalize the text from a BeautifulSoup object - """ + """Normalize the text from a BeautifulSoup object.""" return normalize_soup(soup) @abstractmethod async def fetch_raw_description(self) -> str: - """ - Fetch the raw description of the bot from the website + """Fetch the raw description of the bot from the website. :raises NotFoundError: If the bot is not found :return: The raw description of the bot """ - pass diff --git a/scripts/check_listings/listings/TopGg.py b/scripts/check_listings/listings/TopGg.py index 269b448..f1454c4 100644 --- a/scripts/check_listings/listings/TopGg.py +++ b/scripts/check_listings/listings/TopGg.py @@ -2,7 +2,6 @@ # SPDX-License-Identifier: MIT import nodriver as uc - from bs4 import BeautifulSoup from .Listing import Listing, NotFoundError @@ -11,19 +10,19 @@ class TopGg(Listing): name: str = "Top.gg" - def __init__(self, browser: uc.Browser, application_id: int): + def __init__(self, browser: uc.Browser, application_id: int) -> None: super().__init__(browser) self.application_id = application_id - async def fetch_raw_description(self): + async def fetch_raw_description(self) -> str: url = f"https://top.gg/bot/{self.application_id}" page = await self.browser.get(url) if ( len( await page.find_elements_by_text( - "Oops! We can’t seem to find the page you’re looking for.", + "Oops! We can’t seem to find the page you’re looking for.", # noqa: RUF001 tag_hint="p", - ) + ), ) != 0 ): diff --git a/scripts/check_listings/listings/WumpusStore.py b/scripts/check_listings/listings/WumpusStore.py index 344d732..41cbe96 100644 --- a/scripts/check_listings/listings/WumpusStore.py +++ b/scripts/check_listings/listings/WumpusStore.py @@ -2,7 +2,6 @@ # SPDX-License-Identifier: MIT import nodriver as uc - from bs4 import BeautifulSoup from .Listing import Listing @@ -11,11 +10,11 @@ class WumpusStore(Listing): name: str = "Wumpus.store" - def __init__(self, browser: uc.Browser, application_id: int): + def __init__(self, browser: uc.Browser, application_id: int) -> None: super().__init__(browser) self.application_id = application_id - async def fetch_raw_description(self): + async def fetch_raw_description(self) -> str: url = f"https://wumpus.store/bot/{self.application_id}" page = await self.browser.get(url) description = await page.select(".css-2yutdr") diff --git a/scripts/check_listings/listings/__init__.py b/scripts/check_listings/listings/__init__.py index c1ccfd8..eb661cd 100644 --- a/scripts/check_listings/listings/__init__.py +++ b/scripts/check_listings/listings/__init__.py @@ -1,15 +1,15 @@ # Copyright (c) NiceBots # SPDX-License-Identifier: MIT -from .TopGg import TopGg -from .DiscordsCom import DiscordsCom -from .Listing import BaseError, NotFoundError, normalize_soup -from .WumpusStore import WumpusStore from .DiscordAppDirectory import DiscordAppDirectory from .DiscordBotListCom import DiscordBotListCom -from .DisforgeCom import DisforgeCom from .DiscordBotsGg import DiscordBotsGg from .DiscordMe import DiscordMe +from .DiscordsCom import DiscordsCom +from .DisforgeCom import DisforgeCom +from .Listing import BaseError, NotFoundError, normalize_soup +from .TopGg import TopGg +from .WumpusStore import WumpusStore __all__ = [ "TopGg", diff --git a/scripts/check_listings/main.py b/scripts/check_listings/main.py index d429f9a..7b1670c 100644 --- a/scripts/check_listings/main.py +++ b/scripts/check_listings/main.py @@ -1,45 +1,45 @@ # Copyright (c) NiceBots.xyz # SPDX-License-Identifier: MIT +import argparse import asyncio -import nodriver as uc + import markdown -import argparse +import nodriver as uc import yaml - -from termcolor import cprint +from aiofile import async_open as open # noqa: A001 from bs4 import BeautifulSoup +from termcolor import cprint from .listings import ( - normalize_soup, - TopGg, - DiscordsCom, - WumpusStore, DiscordAppDirectory, DiscordBotListCom, - DisforgeCom, DiscordBotsGg, DiscordMe, + DiscordsCom, + DisforgeCom, + Listing, NotFoundError, + TopGg, + WumpusStore, + normalize_soup, ) -COMPLETED = False +completed = False -async def async_main(args): - with open("description.md", "r", encoding="utf-8") as f: +async def async_main(args: argparse.Namespace) -> None: + with open("description.md", encoding="utf-8") as f: description: str = f.read() - with open(args.config, "r", encoding="utf-8") as f: + with open(args.config, encoding="utf-8") as f: config: dict = yaml.safe_load(f) - application_id = ( - args.application_id if args.application_id else config["application_id"] - ) + application_id = args.application_id if args.application_id else config["application_id"] description = markdown.markdown(description) description = normalize_soup(BeautifulSoup(description, "html.parser")) browser = await uc.start() - listings = [ + listings: list[Listing] = [ DiscordsCom(browser, application_id), WumpusStore(browser, application_id), DiscordAppDirectory(browser, application_id), @@ -62,18 +62,18 @@ async def async_main(args): except NotFoundError: cprint(f"{listing.name} not published", "black", "on_light_red") continue - except asyncio.TimeoutError: + except TimeoutError: cprint(f"{listing.name} timed out") continue if description == its_description: cprint(f"{listing.name} matches", "black", "on_green") else: cprint(f"{listing.name} does not match", "black", "on_yellow") - global COMPLETED - COMPLETED = True + global completed # noqa: PLW0603 + completed = True -def main(): +def main() -> None: parser = argparse.ArgumentParser( prog="Listings checker", description="Check the published status of your discord listings", @@ -84,8 +84,8 @@ def main(): args = parser.parse_args() try: asyncio.get_event_loop().run_until_complete(async_main(args)) - except Exception as e: # noqa - if not COMPLETED: + except Exception: + if not completed: raise diff --git a/src/__main__.py b/src/__main__.py index 1762534..7a959c3 100644 --- a/src/__main__.py +++ b/src/__main__.py @@ -1,38 +1,35 @@ # Copyright (c) NiceBots.xyz # SPDX-License-Identifier: MIT -import sys import os +import sys -sys.path.insert(0, os.path.abspath(os.path.join(os.path.dirname(__file__), ".."))) # noqa: E702 +sys.path.insert(0, os.path.abspath(os.path.join(os.path.dirname(__file__), ".."))) # the above line allows us to import from src without any issues whilst using src/__main__.py -from src.config import config -import importlib.util import asyncio +import importlib.util from glob import iglob + +from src.config import config from src.log import logger from src.utils.setup_func import setup_func -async def load_and_run_patches(): +async def load_and_run_patches() -> None: for patch_file in iglob("src/extensions/*/patch.py"): extension = os.path.basename(os.path.dirname(patch_file)) if config["extensions"].get(extension, {}).get("enabled", False): logger.info(f"Loading patch for extension {extension}") - spec = importlib.util.spec_from_file_location( - f"src.extensions.{extension}.patch", patch_file - ) + spec = importlib.util.spec_from_file_location(f"src.extensions.{extension}.patch", patch_file) if not spec or not spec.loader: continue patch_module = importlib.util.module_from_spec(spec) spec.loader.exec_module(patch_module) if hasattr(patch_module, "patch") and callable(patch_module.patch): - await setup_func( - patch_module.patch, config=config["extensions"][extension] - ) + await setup_func(patch_module.patch, config=config["extensions"][extension]) -async def pre_main(): +async def pre_main() -> None: await load_and_run_patches() # we import main here to apply patches before importing the most things we can # and allow the patches to be applied to later imported modules diff --git a/src/config/bot_config.py b/src/config/bot_config.py index 00e2e59..ae682d4 100644 --- a/src/config/bot_config.py +++ b/src/config/bot_config.py @@ -1,12 +1,13 @@ # Copyright (c) NiceBots.xyz # SPDX-License-Identifier: MIT -import yaml +import contextlib import os -import orjson +from typing import Any +import orjson +import yaml from dotenv import load_dotenv -from typing import Any load_dotenv() @@ -14,13 +15,13 @@ def load_from_env() -> dict[str, dict[str, Any]]: - _config = {} + _config: dict[str, Any] = {} values = {k: v for k, v in os.environ.items() if k.startswith(f"BOTKIT{SPLIT}")} values = {k[len(f"BOTKIT{SPLIT}") :]: v for k, v in values.items()} - current: dict = {} + current: dict[str, Any] = {} for key, value in values.items(): for i, part in enumerate(key.split(SPLIT)): - part = part.lower() + part = part.lower() # noqa: PLW2901 if i == 0: if part not in _config: _config[part] = {} @@ -47,10 +48,8 @@ def load_json_recursive(data: dict[str, Any]) -> dict[str, Any]: elif value.lower() == "false": data[key] = False else: - try: + with contextlib.suppress(orjson.JSONDecodeError): data[key] = orjson.loads(value) - except orjson.JSONDecodeError: - pass return data @@ -63,7 +62,7 @@ def load_json_recursive(data: dict[str, Any]) -> dict[str, Any]: config: dict[str, dict[str, Any]] if path: # noinspection PyArgumentEqualDefault - with open(path, "r", encoding="utf-8") as f: + with open(path, encoding="utf-8") as f: config = yaml.safe_load(f) else: config = load_from_env() diff --git a/src/custom/__init__.py b/src/custom/__init__.py index 400b420..28e15c6 100644 --- a/src/custom/__init__.py +++ b/src/custom/__init__.py @@ -1,44 +1,43 @@ # Copyright (c) NiceBots.xyz # SPDX-License-Identifier: MIT +from logging import getLogger +from typing import Any # pyright: ignore[reportDeprecated] + +import discord from discord import Message -from discord.ext.bridge import BridgeExtContext # pyright: ignore [reportMissingTypeStubs] +from discord.ext import bridge +from discord.ext.bridge import ( + BridgeExtContext, # pyright: ignore [reportMissingTypeStubs] +) from typing_extensions import override -import discord + from src.i18n.classes import ExtensionTranslation, TranslationWrapper, apply_locale -from typing import Any, Union # pyright: ignore[reportDeprecated] -from discord.ext import bridge -from logging import getLogger logger = getLogger("bot") class ApplicationContext(bridge.BridgeApplicationContext): - def __init__(self, bot: discord.Bot, interaction: discord.Interaction): - self.translations: TranslationWrapper = TranslationWrapper( - {}, "en-US" - ) # empty placeholder + def __init__(self, bot: discord.Bot, interaction: discord.Interaction) -> None: + self.translations: TranslationWrapper = TranslationWrapper({}, "en-US") # empty placeholder super().__init__(bot=bot, interaction=interaction) # pyright: ignore[reportUnknownMemberType] @override - def __setattr__(self, key: Any, value: Any): - if key == "command": - if hasattr(value, "translations"): - self.translations = apply_locale( - value.translations, - self.locale, - ) + def __setattr__(self, key: Any, value: Any) -> None: + if key == "command" and hasattr(value, "translations"): + self.translations = apply_locale( + value.translations, + self.locale, + ) super().__setattr__(key, value) class ExtContext(bridge.BridgeExtContext): - def __init__(self, **kwargs: Any): - self.translations: TranslationWrapper = TranslationWrapper( - {}, "en-US" - ) # empty placeholder + def __init__(self, **kwargs: Any) -> None: + self.translations: TranslationWrapper = TranslationWrapper({}, "en-US") # empty placeholder super().__init__(**kwargs) # pyright: ignore[reportUnknownMemberType] - def load_translations(self): + def load_translations(self) -> None: if hasattr(self.command, "translations") and self.command.translations: # pyright: ignore[reportUnknownMemberType,reportUnknownArgumentType,reportOptionalMemberAccess,reportAttributeAccessIssue] locale: str | None = None if guild := self.guild: # pyright: ignore[reportUnnecessaryComparison] # for some reason pyright thinks guild is function @@ -50,12 +49,12 @@ def load_translations(self): class Bot(bridge.Bot): - def __init__(self, *args: Any, **options: Any): + def __init__(self, *args: Any, **options: Any) -> None: self.translations: list[ExtensionTranslation] = options.pop("translations", []) super().__init__(*args, **options) # pyright: ignore[reportUnknownMemberType] @self.listen(name="on_ready", once=True) - async def on_ready(): # pyright: ignore[reportUnusedFunction] + async def on_ready() -> None: # pyright: ignore[reportUnusedFunction] logger.success("Bot started successfully") # pyright: ignore[reportAttributeAccessIssue] @override @@ -80,7 +79,6 @@ async def get_context( return ctx -# if we used | we would sometimes need to use 'Context' instead of Context when type hinting bc else the interpreter will crash -Context = Union[ExtContext, ApplicationContext] # pyright: ignore[reportDeprecated] +Context = ExtContext | ApplicationContext __all__ = ["Bot", "Context", "ExtContext", "ApplicationContext"] diff --git a/src/extensions/add-dm/__init__.py b/src/extensions/add-dm/__init__.py index 9c44609..d137c6f 100644 --- a/src/extensions/add-dm/__init__.py +++ b/src/extensions/add-dm/__init__.py @@ -1,6 +1,6 @@ # Copyright (c) NiceBots.xyz # SPDX-License-Identifier: MIT -from .main import setup, default, schema +from .main import default, schema, setup __all__ = ["setup", "default", "schema"] diff --git a/src/extensions/add-dm/main.py b/src/extensions/add-dm/main.py index 195e7f0..5a37ed5 100644 --- a/src/extensions/add-dm/main.py +++ b/src/extensions/add-dm/main.py @@ -2,11 +2,10 @@ # SPDX-License-Identifier: MIT import discord - from discord.ext import commands from schema import Schema -from src.log import logger +from src.log import logger default = { "enabled": True, @@ -17,23 +16,21 @@ { "enabled": bool, "message": str, - } + }, ) class AddDM(commands.Cog): - def __init__(self, bot: discord.Bot, config: dict): + def __init__(self, bot: discord.Bot, config: dict) -> None: self.bot = bot self.config = config @discord.Cog.listener("on_guild_join") - async def on_join(self, guild: discord.Guild): + async def on_join(self, guild: discord.Guild) -> None: if not guild.me.guild_permissions.view_audit_log: return - entry = await guild.audit_logs( - limit=1, action=discord.AuditLogAction.bot_add - ).flatten() + entry = await guild.audit_logs(limit=1, action=discord.AuditLogAction.bot_add).flatten() user = entry[0].user try: await user.send(self.config["message"].format(user=user)) diff --git a/src/extensions/branding/__init__.py b/src/extensions/branding/__init__.py index 6694e6e..883f743 100644 --- a/src/extensions/branding/__init__.py +++ b/src/extensions/branding/__init__.py @@ -1,6 +1,6 @@ # Copyright (c) NiceBots.xyz # SPDX-License-Identifier: MIT -from .branding import setup, default, schema +from .branding import default, schema, setup __all__ = ["setup", "default", "schema"] diff --git a/src/extensions/branding/branding.py b/src/extensions/branding/branding.py index 3b19c53..7a5505d 100644 --- a/src/extensions/branding/branding.py +++ b/src/extensions/branding/branding.py @@ -2,14 +2,16 @@ # SPDX-License-Identifier: MIT import logging -import discord -import pytz import random from datetime import datetime +from typing import Any -from typing_extensions import TypedDict +import discord +import pytz from discord.ext import commands, tasks -from schema import Schema, And, Optional, Or +from schema import And, Optional, Or, Schema +from typing_extensions import TypedDict + from src.log import logger BASE_URL = "https://top.gg/api" @@ -41,7 +43,7 @@ Optional("listening"): Or(str, list[str]), Optional("streaming"): Or(str, list[str]), Optional("every"): And(int, lambda n: n > 0), - } + }, ) embed_config_schema = Schema( @@ -52,12 +54,12 @@ Optional("time"): bool, Optional("tz"): And(str, lambda s: s in pytz.all_timezones), Optional("separator"): str, - } + }, ), Optional("color"): Or(str, int), Optional("author_url"): str, Optional("author"): str, - } + }, ) schema = Schema( @@ -66,11 +68,9 @@ Optional("embed"): embed_config_schema, Optional("status"): And( status_schema, - lambda s: any( - k in ["playing", "watching", "listening", "streaming"] for k in s.keys() - ), + lambda s: any(k in ["playing", "watching", "listening", "streaming"] for k in s), ), - } + }, ) @@ -104,39 +104,36 @@ class Config(TypedDict): class Branding(commands.Cog): - def __init__(self, bot: discord.Bot, config: Config): + def __init__(self, bot: discord.Bot, config: Config) -> None: self.bot = bot self.config = config - if self.config.get("status"): - status: StatusConfig = self.config["status"] + if status := self.config.get("status"): if not status.get("every"): status["every"] = 60 * 5 - assert isinstance(status["every"], int), "status.every must be an integer" + if not isinstance(status["every"], int): + raise AssertionError("status.every must be an integer") - @tasks.loop(seconds=status["every"]) - async def update_status_loop(): - try: - await self.update_status() - except Exception as e: - logger.error(f"Error updating status: {e}") + @tasks.loop(seconds=status["every"], reconnect=True) + async def update_status_loop() -> None: + await self.update_status() self.update_status_loop = update_status_loop @commands.Cog.listener() - async def on_ready(self): + async def on_ready(self) -> None: if self.config.get("status"): self.update_status_loop.start() - def cog_unload(self): + def cog_unload(self) -> None: if self.config.get("status"): self.update_status_loop.cancel() - async def update_status(self): - status_types = list(self.config["status"].keys()) + async def update_status(self) -> None: + status_types = list(self.config["status"].keys()) # pyright: ignore [reportOptionalMemberAccess] status_types.remove("every") - status_type: str = random.choice(status_types) - status: str = random.choice(self.config["status"][status_type]) + status_type: str = random.choice(status_types) # noqa: S311 + status: str = random.choice(self.config["status"][status_type]) # noqa: S311 # pyright: ignore [reportOptionalSubscript, reportUnknownArgumentType] activity = discord.Activity( name=status, type=getattr(discord.ActivityType, status_type), @@ -144,11 +141,11 @@ async def update_status(self): await self.bot.change_presence(activity=activity) -def setup(bot: discord.Bot, config: dict): +def setup(bot: discord.Bot, config: dict[Any, Any]) -> None: # noqa: C901 if not config.get("embed") and not config.get("status"): logger.warning( "Branding extension is enabled but no configuration is provided for embed or status. You can disable this " - "extension or provide a configuration in the config.yaml file." + "extension or provide a configuration in the config.yaml file.", ) if config.get("embed"): embed: EmbedConfig = config["embed"] @@ -161,26 +158,23 @@ def setup(bot: discord.Bot, config: dict): footer["value"]: list[str] = [] if not footer.get("separator"): footer["separator"] = "|" - if color := embed.get("color"): - if isinstance(color, str): - embed["color"]: str = color.lstrip("#") - embed["color"]: int = int(embed["color"], 16) + if (color := embed.get("color")) and isinstance(color, str): + embed["color"]: str = color.lstrip("#") + embed["color"]: int = int(embed["color"], 16) class Embed(discord.Embed): - def __init__(self, **kwargs): + def __init__(self, **kwargs: Any) -> None: super().__init__(**kwargs) if footer: value: list[str] = footer["value"].copy() if footer.get("time"): - time: str = datetime.now( - pytz.timezone(footer.get("tz", "UTC")) - ).strftime(f"%d %B %Y at %H:%M ({footer.get('tz', 'UTC')})") + time: str = datetime.now(pytz.timezone(footer.get("tz", "UTC"))).strftime( + f"%d %B %Y at %H:%M ({footer.get('tz', 'UTC')})", + ) value.append(time) self.set_footer(text=f" {footer['separator']} ".join(value)) if embed.get("author"): - self.set_author( - name=embed["author"], icon_url=embed.get("author_url") - ) + self.set_author(name=embed["author"], icon_url=embed.get("author_url")) if embed.get("color") and not kwargs.get("color"): self.color = discord.Color(embed["color"]) diff --git a/src/extensions/listings/__init__.py b/src/extensions/listings/__init__.py index 9c44609..d137c6f 100644 --- a/src/extensions/listings/__init__.py +++ b/src/extensions/listings/__init__.py @@ -1,6 +1,6 @@ # Copyright (c) NiceBots.xyz # SPDX-License-Identifier: MIT -from .main import setup, default, schema +from .main import default, schema, setup __all__ = ["setup", "default", "schema"] diff --git a/src/extensions/listings/main.py b/src/extensions/listings/main.py index 727fd45..9f9aac5 100644 --- a/src/extensions/listings/main.py +++ b/src/extensions/listings/main.py @@ -1,11 +1,14 @@ # Copyright (c) NiceBots.xyz # SPDX-License-Identifier: MIT -import discord -import aiohttp +from typing import Any +import aiohttp +import discord from discord.ext import commands, tasks -from schema import Schema, Optional +from schema import Optional, Schema +from typing_extensions import override + from src.log import logger TOPGG_BASE_URL = "https://top.gg/api" @@ -20,54 +23,54 @@ Optional("topgg_token"): str, Optional("discordscom_token"): str, "enabled": bool, - } + }, ) -async def post_request(url: str, headers: dict, payload: dict): - async with aiohttp.ClientSession() as session: - async with session.post(url, headers=headers, json=payload) as resp: - # raise the eventual status code - resp.raise_for_status() +async def post_request(url: str, headers: dict[Any, Any], payload: dict[Any, Any]) -> None: + async with aiohttp.ClientSession() as session, session.post(url, headers=headers, json=payload) as resp: + # raise the eventual status code + resp.raise_for_status() -async def try_post_request(url: str, headers: dict, payload: dict): +async def try_post_request(url: str, headers: dict[Any, Any], payload: dict[Any, Any]) -> None: try: await post_request(url, headers, payload) except aiohttp.ClientResponseError as e: - if e.status == 401: + if e.status == 401: # noqa: PLR2004 logger.error("Invalid token") else: logger.error(e) - except Exception as e: - logger.error(e) + except Exception: # noqa: BLE001 + logger.exception(f"Failed to post request to {url}") class Listings(commands.Cog): - def __init__(self, bot: discord.Bot, config: dict): + def __init__(self, bot: discord.Bot, config: dict[Any, Any]) -> None: self.bot: discord.Bot = bot self.config: dict = config self.topgg = bool(config.get("topgg_token")) self.discordscom = bool(config.get("discordscom_token")) @commands.Cog.listener("on_ready") - async def on_ready(self): + async def on_ready(self) -> None: self.update_count_loop.start() + @override def cog_unload(self) -> None: self.update_count_loop.cancel() @tasks.loop(minutes=30) - async def update_count_loop(self): + async def update_count_loop(self) -> None: try: if self.topgg: await self.update_count_topgg() if self.discordscom: await self.update_count_discordscom() - except Exception as e: - print(e) + except Exception: # noqa: BLE001 + logger.exception("Failed to update count") - async def update_count_discordscom(self): + async def update_count_discordscom(self) -> None: headers = { "Authorization": self.config["discordscom_token"], "Content-Type": "application/json", @@ -77,7 +80,7 @@ async def update_count_discordscom(self): await try_post_request(url, headers, payload) logger.info("Updated discords.com count") - async def update_count_topgg(self): + async def update_count_topgg(self) -> None: headers = {"Authorization": self.config["topgg_token"]} payload = {"server_count": len(self.bot.guilds)} url = f"{TOPGG_BASE_URL}/bots/{self.bot.user.id}/stats" @@ -85,7 +88,7 @@ async def update_count_topgg(self): logger.info("Updated top.gg count") -def setup(bot: discord.Bot, config: dict): +def setup(bot: discord.Bot, config: dict) -> None: if not config.get("topgg_token") and not config.get("discordscom_token"): logger.error("Top.gg or Discords.com token not found") return diff --git a/src/extensions/nice-errors/__init__.py b/src/extensions/nice-errors/__init__.py index 9c44609..d137c6f 100644 --- a/src/extensions/nice-errors/__init__.py +++ b/src/extensions/nice-errors/__init__.py @@ -1,6 +1,6 @@ # Copyright (c) NiceBots.xyz # SPDX-License-Identifier: MIT -from .main import setup, default, schema +from .main import default, schema, setup __all__ = ["setup", "default", "schema"] diff --git a/src/extensions/nice-errors/handler.py b/src/extensions/nice-errors/handler.py index c1a8098..b5f4c6e 100644 --- a/src/extensions/nice-errors/handler.py +++ b/src/extensions/nice-errors/handler.py @@ -1,22 +1,23 @@ # Copyright (c) NiceBots.xyz # SPDX-License-Identifier: MIT +import contextlib +import difflib from typing import Any -from typing_extensions import override + import discord +from discord.ext import bridge, commands from discord.interactions import Interaction -from src.i18n.classes import RawTranslation -from src.i18n import apply_locale +from typing_extensions import override + from src import custom -import difflib -from discord.ext import commands, bridge +from src.i18n import apply_locale +from src.i18n.classes import RawTranslation sentry_sdk = None -try: +with contextlib.suppress(ImportError): import sentry_sdk -except ImportError: - pass class RunInsteadButton(discord.ui.Button[discord.ui.View]): @@ -26,27 +27,25 @@ def __init__( *, ctx: custom.ExtContext, instead: bridge.BridgeExtCommand | commands.Command[Any, Any, Any], - ): + ) -> None: self.ctx = ctx self.instead = instead super().__init__(style=discord.ButtonStyle.green, label=label) @override - async def callback(self, interaction: Interaction): + async def callback(self, interaction: Interaction) -> None: if ( not interaction.user or not self.ctx.author # pyright: ignore[reportUnnecessaryComparison] - or not interaction.user.id == self.ctx.author.id # pyright: ignore[reportFunctionMemberAccess] + or interaction.user.id != self.ctx.author.id # pyright: ignore[reportFunctionMemberAccess] ): await interaction.respond(":x: Nope", ephemeral=True) return await self.instead.invoke(self.ctx) await interaction.response.defer() if interaction.message: - try: + with contextlib.suppress(discord.HTTPException): await interaction.message.delete() - except discord.HTTPException: - pass def find_most_similar(word: str, word_list: list[str]) -> str | None: @@ -63,9 +62,9 @@ def find_similar_command( return None if not isinstance(ctx.bot, custom.Bot): return None - command_list: dict[ - str, bridge.BridgeExtCommand | commands.Command[Any, Any, Any] - ] = {cmd.name: cmd for cmd in ctx.bot.commands} # pyright: ignore[reportUnknownVariableType] + command_list: dict[str, bridge.BridgeExtCommand | commands.Command[Any, Any, Any]] = { + cmd.name: cmd for cmd in ctx.bot.commands + } # pyright: ignore[reportUnknownVariableType] similar_command: str | None = find_most_similar(command, list(command_list.keys())) if similar_command: return command_list.get(similar_command) @@ -90,20 +89,16 @@ async def handle_error( /, raw_translations: dict[str, RawTranslation], use_sentry_sdk: bool = False, -): +) -> None: original_error = error report: bool = True sendargs: dict[str, Any] = {} translations = apply_locale(raw_translations, get_locale(ctx)) if isinstance(error, discord.ApplicationCommandInvokeError): original_error = error.original - if isinstance(error, commands.CommandNotFound) and isinstance( - ctx, custom.ExtContext - ): + if isinstance(error, commands.CommandNotFound) and isinstance(ctx, custom.ExtContext): if similar_command := find_similar_command(ctx): - message = translations.error_command_not_found.format( - similar_command=similar_command.name - ) + message = translations.error_command_not_found.format(similar_command=similar_command.name) view = discord.ui.View( RunInsteadButton( translations.run_x_instead.format(command=similar_command.name), @@ -118,10 +113,7 @@ async def handle_error( else: return # this is not an error in the program elif isinstance(error, discord.Forbidden): - message = ( - translations.error_missing_permissions - + f"\n`{original_error.args[0].split(':')[-1].strip()}`" - ) + message = translations.error_missing_permissions + f"\n`{original_error.args[0].split(':')[-1].strip()}`" else: message = translations.error_generic if report and use_sentry_sdk and sentry_sdk: diff --git a/src/extensions/nice-errors/main.py b/src/extensions/nice-errors/main.py index 1bc0c71..256ee49 100644 --- a/src/extensions/nice-errors/main.py +++ b/src/extensions/nice-errors/main.py @@ -1,14 +1,15 @@ # Copyright (c) NiceBots.xyz # SPDX-License-Identifier: MIT -import discord +from typing import Any +import discord from discord.ext import commands -from schema import Schema, Optional +from schema import Optional, Schema from src import custom + from .handler import handle_error -from typing import Any default = { "enabled": True, @@ -18,12 +19,12 @@ { "enabled": bool, Optional("sentry"): {"dsn": str}, - } + }, ) class NiceErrors(commands.Cog): - def __init__(self, bot: discord.Bot, sentry_sdk: bool, config: dict[str, Any]): + def __init__(self, bot: discord.Bot, sentry_sdk: bool, config: dict[str, Any]) -> None: self.bot = bot self.sentry_sdk = sentry_sdk self.config = config @@ -33,7 +34,7 @@ async def on_error( self, ctx: custom.ApplicationContext, error: discord.ApplicationCommandInvokeError, - ): + ) -> None: await handle_error( error, ctx, @@ -42,9 +43,7 @@ async def on_error( ) @discord.Cog.listener("on_command_error") - async def on_command_error( - self, ctx: custom.ExtContext, error: commands.CommandError - ): + async def on_command_error(self, ctx: custom.ExtContext, error: commands.CommandError) -> None: await handle_error( error, ctx, diff --git a/src/extensions/nice-errors/patch.py b/src/extensions/nice-errors/patch.py index 9c8c3b9..93e43b9 100644 --- a/src/extensions/nice-errors/patch.py +++ b/src/extensions/nice-errors/patch.py @@ -2,19 +2,20 @@ # SPDX-License-Identifier: MIT from typing import Any + from .handler import handle_error -async def patch(config: dict[str, Any]): +async def patch(config: dict[str, Any]) -> None: sentry_sdk = None if config.get("sentry", {}).get("dsn"): import sentry_sdk - from sentry_sdk.integrations.logging import LoggingIntegration from sentry_sdk.integrations.asyncio import AsyncioIntegration + from sentry_sdk.integrations.logging import LoggingIntegration from sentry_sdk.scrubber import ( - EventScrubber, DEFAULT_DENYLIST, DEFAULT_PII_DENYLIST, + EventScrubber, ) sentry_sdk.init( diff --git a/src/extensions/ping/__init__.py b/src/extensions/ping/__init__.py index 2d6ba31..034634f 100644 --- a/src/extensions/ping/__init__.py +++ b/src/extensions/ping/__init__.py @@ -1,6 +1,6 @@ # Copyright (c) NiceBots.xyz # SPDX-License-Identifier: MIT -from .ping import setup, setup_webserver, on_startup, default, schema +from .ping import default, on_startup, schema, setup, setup_webserver __all__ = ["setup", "setup_webserver", "on_startup", "default", "schema"] diff --git a/src/extensions/ping/ping.py b/src/extensions/ping/ping.py index 31b2633..c0ccd5e 100644 --- a/src/extensions/ping/ping.py +++ b/src/extensions/ping/ping.py @@ -1,15 +1,14 @@ # Copyright (c) NiceBots.xyz # SPDX-License-Identifier: MIT -import discord import aiohttp - +import discord +from discord.ext import bridge, commands from quart import Quart -from discord.ext import commands from schema import Schema -from src.log import logger + from src import custom -from discord.ext import bridge +from src.log import logger default = { "enabled": True, @@ -18,76 +17,48 @@ schema = Schema( { "enabled": bool, - } + }, ) -class Ping(commands.Cog): - def __init__(self, bot: custom.Bot): - self.bot = bot - - @discord.slash_command(name="ping") - async def ping( - self, - ctx: custom.ApplicationContext, - ephemeral: bool = False, - use_embed: bool = False, - ): - await ctx.defer(ephemeral=ephemeral) - if use_embed: - embed = discord.Embed( - title="Pong!", - description=ctx.translations.response.format( - latency=round(self.bot.latency * 1000) - ), - color=discord.Colour.blurple(), - ) - return await ctx.respond(embed=embed, ephemeral=ephemeral) - return await ctx.respond( - f"Pong! {round(self.bot.latency * 1000)}ms", ephemeral=ephemeral - ) - - class BridgePing(commands.Cog): - def __init__(self, bot: custom.Bot): + def __init__(self, bot: custom.Bot) -> None: self.bot = bot @bridge.bridge_command() async def ping( self, - ctx: "custom.Context", + ctx: custom.Context, + *, ephemeral: bool = False, use_embed: bool = False, - ): + ) -> None: await ctx.defer(ephemeral=ephemeral) if use_embed: embed = discord.Embed( title="Pong!", - description=ctx.translations.response.format( - latency=round(self.bot.latency * 1000) - ), + description=ctx.translations.response.format(latency=round(self.bot.latency * 1000)), color=discord.Colour.blurple(), ) - return await ctx.respond(embed=embed, ephemeral=ephemeral) - return await ctx.respond( - f"Pong! {round(self.bot.latency * 1000)}ms", ephemeral=ephemeral - ) + await ctx.respond(embed=embed, ephemeral=ephemeral) + return + await ctx.respond(f"Pong! {round(self.bot.latency * 1000)}ms", ephemeral=ephemeral) -def setup(bot: custom.Bot): - # bot.add_cog(Ping(bot)) +def setup(bot: custom.Bot) -> None: bot.add_cog(BridgePing(bot)) -def setup_webserver(app: Quart, bot: discord.Bot): +def setup_webserver(app: Quart, bot: discord.Bot) -> None: @app.route("/ping") - async def ping(): + async def ping() -> dict[str, str]: # pyright: ignore[reportUnusedFunction] + if not bot.user: + return {"message": "Bot is offline"} bot_name = bot.user.name return {"message": f"{bot_name} is online"} -async def on_startup(config: dict): - async with aiohttp.ClientSession() as session: - async with session.get("https://httpbin.org/user-agent") as resp: - logger.info(f"HTTPBin user-agent: {await resp.text()}") - logger.info(f"Ping extension config: {config}") +async def on_startup(config: dict[str, bool]) -> None: + async with aiohttp.ClientSession() as session, session.get("https://httpbin.org/user-agent") as resp: + logger.info(f"HTTPBin user-agent: {await resp.text()}") + logger.info(f"Ping extension config: {config}") diff --git a/src/extensions/status-post/__init__.py b/src/extensions/status-post/__init__.py index 9c44609..d137c6f 100644 --- a/src/extensions/status-post/__init__.py +++ b/src/extensions/status-post/__init__.py @@ -1,6 +1,6 @@ # Copyright (c) NiceBots.xyz # SPDX-License-Identifier: MIT -from .main import setup, default, schema +from .main import default, schema, setup __all__ = ["setup", "default", "schema"] diff --git a/src/extensions/status-post/main.py b/src/extensions/status-post/main.py index 64748e4..8b22e36 100644 --- a/src/extensions/status-post/main.py +++ b/src/extensions/status-post/main.py @@ -1,14 +1,12 @@ # Copyright (c) NiceBots.xyz # SPDX-License-Identifier: MIT -import discord import aiohttp - -from discord.ext import commands +import discord +from discord.ext import commands, tasks from schema import Schema -from src.log import logger -from discord.ext import tasks +from src.log import logger default = { "enabled": False, @@ -21,35 +19,32 @@ "enabled": bool, "url": str, "every": int, - } + }, ) class Status(commands.Cog): - def __init__(self, bot: discord.Bot, config: dict): + def __init__(self, bot: discord.Bot, config: dict) -> None: self.bot = bot self.config = config - self.push_status_loop = tasks.loop(seconds=self.config["every"])( - self.push_status_loop - ) + self.push_status_loop = tasks.loop(seconds=self.config["every"])(self.push_status_loop) @commands.Cog.listener(once=True) - async def on_ready(self): + async def on_ready(self) -> None: self.push_status_loop.start() - async def push_status_loop(self): + async def push_status_loop(self) -> None: try: await self.push_status() logger.info("Pushed status.") - except Exception as e: - logger.error(f"Failed to push status: {e}") + except Exception: # noqa: BLE001 + logger.exception("Failed to push status.") - async def push_status(self): + async def push_status(self) -> None: ping = str(round(self.bot.latency * 1000)) - async with aiohttp.ClientSession() as session: - async with session.get(self.config["url"] + ping) as resp: - resp.raise_for_status() + async with aiohttp.ClientSession() as session, session.get(self.config["url"] + ping) as resp: + resp.raise_for_status() -def setup(bot: discord.Bot, config: dict): +def setup(bot: discord.Bot, config: dict) -> None: bot.add_cog(Status(bot, config)) diff --git a/src/i18n/__init__.py b/src/i18n/__init__.py index fa34828..87c8b6e 100644 --- a/src/i18n/__init__.py +++ b/src/i18n/__init__.py @@ -1,7 +1,7 @@ # Copyright (c) NiceBots.xyz # SPDX-License-Identifier: MIT -from .utils import apply, load_translation from .classes import apply_locale +from .utils import apply, load_translation __all__ = ["apply", "load_translation", "apply_locale"] diff --git a/src/i18n/classes.py b/src/i18n/classes.py index 099c1ab..d3b0f1b 100644 --- a/src/i18n/classes.py +++ b/src/i18n/classes.py @@ -2,8 +2,9 @@ # SPDX-License-Identifier: MIT from typing import Any -from typing_extensions import override + from pydantic import BaseModel, Field +from typing_extensions import override LOCALES = ( "en-US", @@ -42,11 +43,11 @@ class RawTranslation(BaseModel): - en_US: str | None = Field(None, alias="en-US") - en_GB: str | None = Field(None, alias="en-GB") + en_US: str | None = Field(None, alias="en-US") # noqa: N815 + en_GB: str | None = Field(None, alias="en-GB") # noqa: N815 bg: str | None = None - zh_CN: str | None = Field(None, alias="zh-CN") - zh_TW: str | None = Field(None, alias="zh-TW") + zh_CN: str | None = Field(None, alias="zh-CN") # noqa: N815 + zh_TW: str | None = Field(None, alias="zh-TW") # noqa: N815 hr: str | None = None cs: str | None = None da: str | None = None @@ -63,12 +64,12 @@ class RawTranslation(BaseModel): lt: str | None = None no: str | None = None pl: str | None = None - pt_BR: str | None = Field(None, alias="pt-BR") + pt_BR: str | None = Field(None, alias="pt-BR") # noqa: N815 ro: str | None = None ru: str | None = None - es_ES: str | None = Field(None, alias="es-ES") + es_ES: str | None = Field(None, alias="es-ES") # noqa: N815 es_419: str | None = Field(None, alias="es-419") - sv_SE: str | None = Field(None, alias="sv-SE") + sv_SE: str | None = Field(None, alias="sv-SE") # noqa: N815 th: str | None = None tr: str | None = None uk: str | None = None @@ -84,7 +85,7 @@ def get_for_locale(self, locale: str) -> "TranslationWrapper": class TranslationWrapper: - def __init__(self, model: "Translatable", locale: str, default: str = DEFAULT): + def __init__(self, model: "Translatable", locale: str, default: str = DEFAULT) -> None: self._model = model self._default: str self.default = default.replace("-", "_") @@ -100,9 +101,7 @@ def __getattr__(self, key: str) -> Any: applicable = getattr(self._model, key) if isinstance(applicable, RawTranslation): try: - return getattr(applicable, self._locale) or getattr( - applicable, self._default - ) + return getattr(applicable, self._locale) or getattr(applicable, self._default) except AttributeError: return getattr(applicable, self._default) return apply_locale(applicable, self._locale) @@ -162,9 +161,7 @@ class Deg1CommandTranslation(CommandTranslation): commands: dict[str, Deg2CommandTranslation] | None = None -AnyCommandTranslation = ( - Deg1CommandTranslation | Deg2CommandTranslation | Deg3CommandTranslation -) +AnyCommandTranslation = Deg1CommandTranslation | Deg2CommandTranslation | Deg3CommandTranslation class ExtensionTranslation(Translation): diff --git a/src/i18n/utils.py b/src/i18n/utils.py index 1efa633..fba7023 100644 --- a/src/i18n/utils.py +++ b/src/i18n/utils.py @@ -1,17 +1,19 @@ # Copyright (c) NiceBots.xyz # SPDX-License-Identifier: MIT -from typing import TypeVar, TYPE_CHECKING +from typing import TYPE_CHECKING, TypeVar + import discord +import yaml +from discord.ext import commands as prefixed + +from src.log import logger as main_logger from .classes import ( - ExtensionTranslation, Deg1CommandTranslation, Deg2CommandTranslation, + ExtensionTranslation, ) -from src.log import logger as main_logger -import yaml -from discord.ext import commands as prefixed if TYPE_CHECKING: from src import custom @@ -30,6 +32,7 @@ def remove_none(d: dict[T, V]) -> dict[T, V]: Returns: dict[T, V]: The dictionary without None values. + """ return {k: v for k, v in d.items() if v is not None} @@ -47,10 +50,9 @@ def merge_command_translations( Raises: None + """ - command_translations: list[dict[str, Deg1CommandTranslation]] = [ - t.commands for t in translations if t.commands - ] + command_translations: list[dict[str, Deg1CommandTranslation]] = [t.commands for t in translations if t.commands] if not command_translations: return None result: dict[str, Deg1CommandTranslation] = {} @@ -72,62 +74,52 @@ def merge_command_translations( ) -def localize_commands( +def localize_commands( # noqa: C901, PLR0912 commands: list[CommandT], translations: ExtensionTranslation | Deg1CommandTranslation | Deg2CommandTranslation | dict[str, Deg1CommandTranslation], - DEFAULT_LOCALE: str = "en-US", + default_locale: str = "en-US", ) -> tuple[int, int]: """Recursively localize commands and their subcommands. Args: commands: List of commands to localize. translations: Translations for the commands. - DEFAULT_LOCALE: The default locale to use. + default_locale: The default locale to use. Returns: None + """ logger.info("Localizing commands...") err = 0 tot = 0 for command in commands: - if isinstance( - command, (discord.SlashCommand, discord.SlashCommandGroup, prefixed.Command) - ): + if isinstance(command, discord.SlashCommand | discord.SlashCommandGroup | prefixed.Command): tot += 1 try: try: - if isinstance(translations, dict): - translatable = translations - else: - translatable = translations.commands + translatable = translations if isinstance(translations, dict) else translations.commands if translatable: translation = translatable.get(command.name) if not translation: - raise AttributeError + raise AttributeError # noqa: TRY301 else: - raise AttributeError + raise AttributeError # noqa: TRY301 except AttributeError: - logger.warning( - f"Command /{command.qualified_name} is not defined in translations, continuing..." - ) + logger.warning(f"Command /{command.qualified_name} is not defined in translations, continuing...") err += 1 continue if translation.name: name = remove_none(translation.name.model_dump(by_alias=True)) - command.name = name.get(DEFAULT_LOCALE, command.name) + command.name = name.get(default_locale, command.name) if not isinstance(command, prefixed.Command): command.name_localizations = name if translation.description: - description = remove_none( - translation.description.model_dump(by_alias=True) - ) - command.description = description.get( - DEFAULT_LOCALE, command.description - ) + description = remove_none(translation.description.model_dump(by_alias=True)) + command.description = description.get(default_locale, command.description) if not isinstance(command, prefixed.Command): command.description_localizations = description if translation.strings: @@ -138,26 +130,23 @@ def localize_commands( opt = translation.options[option.name] if opt.name: name = remove_none(opt.name.model_dump(by_alias=True)) - option.name = name.get(DEFAULT_LOCALE, option.name) + option.name = name.get(default_locale, option.name) option.name_localizations = name if opt.description: - description = remove_none( - opt.description.model_dump(by_alias=True) - ) - option.description = description.get( - DEFAULT_LOCALE, option.description - ) + description = remove_none(opt.description.model_dump(by_alias=True)) + option.description = description.get(default_locale, option.description) option.description_localizations = description else: logger.warning( - f"Option {option.name} of command /{command.qualified_name} is not defined in translations, continuing..." + f"Option {option.name} of command /{command.qualified_name} is not defined in translations, continuing...", # noqa: E501 ) if isinstance(command, discord.SlashCommandGroup) and isinstance( - translation, (Deg1CommandTranslation, Deg2CommandTranslation) + translation, + Deg1CommandTranslation | Deg2CommandTranslation, ): - localize_commands(command.subcommands, translation, DEFAULT_LOCALE) - except Exception as e: - logger.error(f"Error localizing command /{command.name}: {e}") + localize_commands(command.subcommands, translation, default_locale) + except Exception: + logger.exception(f"Error localizing command /{command.name}") err += 1 return err, tot @@ -173,9 +162,9 @@ def load_translation(path: str) -> ExtensionTranslation: Raises: yaml.YAMLError: If the file is not a valid YAML file. - """ - with open(path, "r", encoding="utf-8") as f: + """ + with open(path, encoding="utf-8") as f: data = yaml.safe_load(f) return ExtensionTranslation(**data) @@ -183,17 +172,18 @@ def load_translation(path: str) -> ExtensionTranslation: def apply( bot: "custom.Bot", translations: list[ExtensionTranslation], - DEFAULT_LOCALE: str = "en-US", + default_locale: str = "en-US", ) -> None: """Apply translations to the bot. Args: bot: The bot to apply translations to. translations: The translations to apply. - DEFAULT_LOCALE: The default locale to use. + default_locale: The default locale to use. Returns: None + """ logger.info("Applying translations") command_translations = merge_command_translations(translations) @@ -204,7 +194,7 @@ def apply( err, tot = localize_commands( [*bot.pending_application_commands, *bot.commands], # pyright: ignore[reportUnknownMemberType,reportUnknownArgumentType] command_translations, - DEFAULT_LOCALE, + default_locale, ) if tot == err: logger.error(f"Localized {tot - err}/{tot} commands.") diff --git a/src/log/logger.py b/src/log/logger.py index 8f590e5..da6678d 100644 --- a/src/log/logger.py +++ b/src/log/logger.py @@ -4,6 +4,8 @@ import logging import os import time +from typing import Any + import coloredlogs from src.config import config @@ -14,7 +16,7 @@ class CustomLogger(logging.Logger): - def success(self, msg, *args, **kwargs) -> None: # pyright: ignore[reportUnknownParameterType,reportMissingParameterType] + def success(self, msg: str, *args: Any, **kwargs: Any) -> None: # pyright: ignore[reportUnknownParameterType,reportMissingParameterType] if self.isEnabledFor(SUCCESS): self._log(SUCCESS, msg, args, **kwargs) # pyright: ignore[reportUnknownArgumentType] @@ -22,18 +24,12 @@ def success(self, msg, *args, **kwargs) -> None: # pyright: ignore[reportUnknow # Register the custom logger class logging.setLoggerClass(CustomLogger) -level: int = getattr( - logging, config.get("logging", {}).get("level", "").upper() or "INFO" -) +level: int = getattr(logging, config.get("logging", {}).get("level", "").upper() or "INFO") logging.basicConfig(level=level, handlers=[]) os.makedirs("logs", exist_ok=True) file_handler = logging.FileHandler(f"logs/{time.time()}.log", encoding="utf-8") -file_handler.setFormatter( - logging.Formatter( - "%(levelname)-8s at %(asctime)s: %(message)s\n\t%(pathname)s:%(lineno)d" - ) -) +file_handler.setFormatter(logging.Formatter("%(levelname)-8s at %(asctime)s: %(message)s\n\t%(pathname)s:%(lineno)d")) file_handler.setLevel("DEBUG") # More stylish coloredlogs format diff --git a/src/start.py b/src/start.py index 7d4b02c..273a415 100644 --- a/src/start.py +++ b/src/start.py @@ -1,46 +1,49 @@ # Copyright (c) NiceBots.xyz # SPDX-License-Identifier: MIT -import discord +import asyncio import importlib import importlib.util -import asyncio +from glob import iglob +from os.path import basename, splitext +from typing import TYPE_CHECKING, Any, TypedDict -from discord.ext import commands +import discord import yaml +from discord.ext import commands from quart import Quart -from glob import iglob -from src.i18n.classes import ExtensionTranslation + +from src import custom, i18n from src.config import config, store_config +from src.i18n.classes import ExtensionTranslation from src.log import logger, patch -from os.path import splitext, basename -from types import ModuleType -from typing import Any, Callable, TypedDict, TYPE_CHECKING -from collections.abc import Coroutine -from src.utils import validate_module, unzip_extensions, setup_func -from src import i18n +from src.utils import setup_func, unzip_extensions, validate_module from src.utils.iterator import next_default -from src import custom if TYPE_CHECKING: - FunctionConfig = TypedDict("FunctionConfig", {"enabled": bool}) + from collections.abc import Callable, Coroutine + from types import ModuleType + + class FunctionConfig(TypedDict): + enabled: bool + FunctionlistType = list[tuple[Callable[..., Any], FunctionConfig]] -async def start_bot(bot: custom.Bot, token: str): +async def start_bot(bot: custom.Bot, token: str) -> None: await bot.start(token) -async def start_backend(app: Quart, bot: discord.Bot, token: str): +async def start_backend(app: Quart, bot: discord.Bot, token: str) -> None: + from hypercorn.asyncio import serve # pyright: ignore [reportUnknownVariableType] from hypercorn.config import Config from hypercorn.logging import Logger as HypercornLogger - from hypercorn.asyncio import serve # pyright: ignore [reportUnknownVariableType] class CustomLogger(HypercornLogger): def __init__( self, - *args, # pyright: ignore [reportUnknownParameterType,reportMissingParameterType] - **kwargs, # pyright: ignore [reportUnknownParameterType,reportMissingParameterType] + *args, # pyright: ignore [reportUnknownParameterType,reportMissingParameterType] # noqa: ANN002 + **kwargs, # pyright: ignore [reportUnknownParameterType,reportMissingParameterType] # noqa: ANN003 ) -> None: super().__init__( *args, # pyright: ignore [reportUnknownArgumentType] @@ -69,9 +72,9 @@ def load_extensions() -> ( "list[ExtensionTranslation]", ] ): - bot_functions: "FunctionlistType" = [] - back_functions: "FunctionlistType" = [] - startup_functions: "FunctionlistType" = [] + bot_functions: FunctionlistType = [] + back_functions: FunctionlistType = [] + startup_functions: FunctionlistType = [] translations: list[ExtensionTranslation] = [] for extension in iglob("src/extensions/*"): name = splitext(basename(extension))[0] @@ -112,16 +115,14 @@ async def setup_and_start_bot( bot_functions: "FunctionlistType", translations: list[ExtensionTranslation], config: dict[str, Any], -): +) -> None: intents = discord.Intents.default() if config.get("prefix"): intents.message_content = True bot = custom.Bot( intents=intents, help_command=None, - command_prefix=( - config.get("prefix", {}).get("prefix") or commands.when_mentioned - ), + command_prefix=(config.get("prefix", {}).get("prefix") or commands.when_mentioned), ) for function, its_config in bot_functions: setup_func(function, bot=bot, config=its_config) @@ -129,13 +130,13 @@ async def setup_and_start_bot( if not config.get("prefix", {}).get("enabled", True): bot.prefixed_commands = {} if not config.get("slash", {}).get("enabled", True): - bot._pending_application_commands = [] # pyright: ignore[reportPrivateUsage] + bot._pending_application_commands = [] # pyright: ignore[reportPrivateUsage] # noqa: SLF001 await start_bot(bot, config["token"]) async def setup_and_start_backend( back_functions: "FunctionlistType", -): +) -> None: back_bot = discord.Bot(intents=discord.Intents.default()) app = Quart("backend") for function, its_config in back_functions: @@ -147,42 +148,35 @@ async def run_startup_functions( startup_functions: "FunctionlistType", app: Quart | None, back_bot: discord.Bot | None, -): +) -> None: startup_coros = [ - setup_func(function, app=app, bot=back_bot, config=its_config) - for function, its_config in startup_functions + setup_func(function, app=app, bot=back_bot, config=its_config) for function, its_config in startup_functions ] await asyncio.gather(*startup_coros) -async def main(run_bot: bool | None = None, run_backend: bool | None = None): - assert config.get("bot", {}).get("token"), "No bot token provided in config" +async def main(run_bot: bool | None = None, run_backend: bool | None = None) -> None: + if not config.get("bot", {}).get("token"): + logger.critical("No bot token provided in config, exiting...") + return unzip_extensions() run_bot = run_bot if run_bot is not None else config.get("use", {}).get("bot", True) - run_backend = ( - run_backend - if run_backend is not None - else config.get("use", {}).get("backend", True) - ) + run_backend = run_backend if run_backend is not None else config.get("use", {}).get("backend", True) bot_functions, back_functions, startup_functions, translations = load_extensions() coros: list[Coroutine[Any, Any, Any]] = [] if bot_functions and run_bot: - coros.append( - setup_and_start_bot(bot_functions, translations, config.get("bot", {})) - ) + coros.append(setup_and_start_bot(bot_functions, translations, config.get("bot", {}))) if back_functions and run_backend: coros.append(setup_and_start_backend(back_functions)) - assert coros, "No extensions to run" + if not coros: + logger.error("No extensions to run, exiting...") + return if startup_functions: app = Quart("backend") if (back_functions and run_backend) else None - back_bot = ( - discord.Bot(intents=discord.Intents.default()) - if (back_functions and run_backend) - else None - ) + back_bot = discord.Bot(intents=discord.Intents.default()) if (back_functions and run_backend) else None await run_startup_functions(startup_functions, app, back_bot) await asyncio.gather(*coros) diff --git a/src/utils/__init__.py b/src/utils/__init__.py index 75bfb55..c76ea72 100644 --- a/src/utils/__init__.py +++ b/src/utils/__init__.py @@ -1,7 +1,7 @@ # Copyright (c) NiceBots.xyz # SPDX-License-Identifier: MIT -from .extensions import validate_module, unzip_extensions +from .extensions import unzip_extensions, validate_module from .misc import mention_command from .setup_func import setup_func diff --git a/src/utils/extensions.py b/src/utils/extensions.py index bec9262..2e2bcd3 100644 --- a/src/utils/extensions.py +++ b/src/utils/extensions.py @@ -1,54 +1,51 @@ # Copyright (c) NiceBots.xyz # SPDX-License-Identifier: MIT - +# ruff: noqa: S101 import inspect import os -import zipfile -import discord import warnings - -from types import ModuleType -from typing import Any, Callable +import zipfile +from collections.abc import Callable from glob import iglob -from schema import Schema +from types import ModuleType +from typing import Any + +import discord from quart import Quart +from schema import Schema, SchemaError from src.log import logger -def check_typing(module: ModuleType, func: Callable, types: dict[str, Any]): +def check_typing(module: ModuleType, func: Callable, types: dict[str, Any]) -> None: signature = inspect.signature(func) for name, parameter in signature.parameters.items(): - if name in types and not parameter.annotation == types[name]: + if name in types and parameter.annotation != types[name]: warnings.warn( - f"Parameter {name} of function {func.__name__} of module {module.__name__} does not have the correct type annotation (is {parameter.annotation} should be {types[name]})" + f"Parameter {name} of function {func.__name__} of module {module.__name__} does not have the correct type annotation (is {parameter.annotation} should be {types[name]})", # noqa: E501 + stacklevel=1, ) -def check_func( - module: ModuleType, func: Callable, max_args: int, types: dict[str, Any] -): - assert callable( - func - ), f"Function {func.__name__} of module {module.__name__} is not callable" +def check_func(module: ModuleType, func: Callable, max_args: int, types: dict[str, Any]) -> None: + assert callable(func), f"Function {func.__name__} of module {module.__name__} is not callable" signature = inspect.signature(func) assert ( len(signature.parameters) <= max_args ), f"Function {func.__name__} of module {module.__name__} has too many arguments" assert all( - param in types for param in signature.parameters.keys() - ), f"Function {func.__name__} of module {module.__name__} does not accept the correct arguments ({', '.join(types.keys())})" - # check_typing(module, func, types) # temporarily disabled due to unwanted behavior + param in types for param in signature.parameters + ), f"Function {func.__name__} of module {module.__name__} does not accept the correct arguments ({', '.join(types.keys())})" # noqa: E501 + # check_typing(module, func, types) # temporarily disabled due to unwanted behavior # noqa: ERA001 # noinspection DuplicatedCode def validate_module(module: ModuleType, config: dict[str, Any] | None = None) -> None: - """ - Validate the module to ensure it has the required functions and attributes to be loaded as an extension + """Validate the module to ensure it has the required functions and attributes to be loaded as an extension. + :param module: The module to validate - :param config: The configuration to validate against + :param config: The configuration to validate against. """ - if hasattr(module, "setup"): check_func(module, module.setup, 2, {"bot": discord.Bot, "config": dict}) @@ -60,7 +57,8 @@ def validate_module(module: ModuleType, config: dict[str, Any] | None = None) -> {"app": Quart, "bot": discord.Bot, "config": dict}, ) assert hasattr(module, "setup_webserver") or hasattr( - module, "setup" + module, + "setup", ), f"Extension {module.__name__} does not have a setup or setup_webserver function" if hasattr(module, "on_startup"): check_func( @@ -70,15 +68,18 @@ def validate_module(module: ModuleType, config: dict[str, Any] | None = None) -> {"app": Quart, "bot": discord.Bot, "config": dict}, ) - assert hasattr(module, "default") and isinstance( - module.default, dict - ), f"Extension {module.__name__} does not have a default configuration" + assert hasattr(module, "default"), f"Extension {module.__name__} does not have a default configuration" + assert isinstance( + module.default, + dict, + ), f"Extension {module.__name__} has a default configuration of type {type(module.default)} instead of dict" assert ( "enabled" in module.default ), f"Extension {module.__name__} does not have an enabled key in its default configuration" if hasattr(module, "schema"): - assert ( - isinstance(module.schema, Schema) or isinstance(module.schema, dict) + assert isinstance( + module.schema, + Schema | dict, ), f"Extension {module.__name__} has a schema of type {type(module.schema)} instead of Schema or dict" if isinstance(module.schema, dict): @@ -88,15 +89,16 @@ def validate_module(module: ModuleType, config: dict[str, Any] | None = None) -> else: try: module.schema.validate(module.default) - except Exception as e: + except SchemaError as e: warnings.warn( - f"Default configuration for extension {module.__name__} does not match schema: {e}" + f"Default configuration for extension {module.__name__} does not match schema: {e}", + stacklevel=1, ) else: - warnings.warn(f"Extension {module.__name__} does not have a schema") + warnings.warn(f"Extension {module.__name__} does not have a schema", stacklevel=1) -def unzip_extensions(): +def unzip_extensions() -> None: for file in iglob("src/extensions/*.zip"): with zipfile.ZipFile(file, "r") as zip_ref: zip_ref.extractall("src/extensions") diff --git a/src/utils/iterator.py b/src/utils/iterator.py index ac43772..f5e9bad 100644 --- a/src/utils/iterator.py +++ b/src/utils/iterator.py @@ -1,8 +1,8 @@ # Copyright (c) NiceBots.xyz # SPDX-License-Identifier: MIT -from typing import TypeVar from collections.abc import Iterator +from typing import TypeVar T = TypeVar("T") V = TypeVar("V") diff --git a/src/utils/setup_func.py b/src/utils/setup_func.py index 0aa0e94..b3d6d3c 100644 --- a/src/utils/setup_func.py +++ b/src/utils/setup_func.py @@ -1,16 +1,17 @@ # Copyright (c) NiceBots.xyz # SPDX-License-Identifier: MIT +from collections.abc import Callable from inspect import signature -from typing import Any, Callable +from typing import Any def setup_func(func: Callable[..., Any], **kwargs: Any) -> Any: - """ - Setup a Coroutine function with the required arguments from the kwargs + """Set up a Coroutine function with the required arguments from the kwargs. + :param func: The function to setup :param kwargs: The arguments that may be passed to the function if the function requires them - :return: The result of the function + :return: The result of the function. """ parameters = signature(func).parameters func_kwargs = {} diff --git a/tests/schema_test.py b/tests/schema_test.py index fba1359..3cd9bf6 100644 --- a/tests/schema_test.py +++ b/tests/schema_test.py @@ -1,14 +1,15 @@ # Copyright (c) NiceBots.xyz # SPDX-License-Identifier: MIT -from glob import iglob -from os.path import splitext, basename import importlib +from glob import iglob +from os.path import basename, splitext from src.utils import validate_module -def test_ext_schemas(): +def test_ext_schemas() -> None: + """Test the schemas of all extensions.""" for ext in iglob("src/extensions/*"): name = splitext(basename(ext))[0] module = importlib.import_module(f"src.extensions.{name}") From 1752535c5096facadde426ea6d985b923b4f5bc9 Mon Sep 17 00:00:00 2001 From: Paillat Date: Tue, 5 Nov 2024 17:05:39 +0100 Subject: [PATCH 04/61] :rotating_light: Add stricter linter rules --- scripts/check_listings/__main__.py | 9 +++++---- scripts/check_listings/listings/__init__.py | 3 ++- scripts/check_listings/main.py | 8 ++++---- 3 files changed, 11 insertions(+), 9 deletions(-) diff --git a/scripts/check_listings/__main__.py b/scripts/check_listings/__main__.py index 497e45b..e5e64d3 100644 --- a/scripts/check_listings/__main__.py +++ b/scripts/check_listings/__main__.py @@ -3,6 +3,7 @@ import argparse import asyncio +from typing import Any import markdown import nodriver as uc @@ -28,10 +29,10 @@ async def async_main(args: argparse.Namespace) -> None: - with open("description.md", encoding="utf-8") as f: - description: str = f.read() - with open(args.config, encoding="utf-8") as f: - config: dict = yaml.safe_load(f) + async with open("description.md", encoding="utf-8") as f: + description: str = await f.read() + async with open(args.config, encoding="utf-8") as f: + config: dict[Any, Any] = yaml.safe_load(await f.read()) application_id = args.application_id if args.application_id else config["application_id"] description = markdown.markdown(description) diff --git a/scripts/check_listings/listings/__init__.py b/scripts/check_listings/listings/__init__.py index eb661cd..2a038af 100644 --- a/scripts/check_listings/listings/__init__.py +++ b/scripts/check_listings/listings/__init__.py @@ -7,7 +7,7 @@ from .DiscordMe import DiscordMe from .DiscordsCom import DiscordsCom from .DisforgeCom import DisforgeCom -from .Listing import BaseError, NotFoundError, normalize_soup +from .Listing import BaseError, Listing, NotFoundError, normalize_soup from .TopGg import TopGg from .WumpusStore import WumpusStore @@ -23,4 +23,5 @@ "DisforgeCom", "DiscordBotsGg", "DiscordMe", + "Listing", ] diff --git a/scripts/check_listings/main.py b/scripts/check_listings/main.py index 7b1670c..11f69cc 100644 --- a/scripts/check_listings/main.py +++ b/scripts/check_listings/main.py @@ -29,10 +29,10 @@ async def async_main(args: argparse.Namespace) -> None: - with open("description.md", encoding="utf-8") as f: - description: str = f.read() - with open(args.config, encoding="utf-8") as f: - config: dict = yaml.safe_load(f) + async with open("description.md", encoding="utf-8") as f: + description: str = await f.read() + async with open(args.config, encoding="utf-8") as f: + config: dict[str, str] = yaml.safe_load(await f.read()) application_id = args.application_id if args.application_id else config["application_id"] description = markdown.markdown(description) From c872dc6342484a27d7fd0e142d3c7b451cf22e44 Mon Sep 17 00:00:00 2001 From: Paillat Date: Fri, 8 Nov 2024 11:58:37 +0100 Subject: [PATCH 05/61] :bug: Small fixes and improvements --- pdm.lock | 6 +- pyproject.toml | 3 +- src/custom/__init__.py | 7 +- src/extensions/nice-errors/handler.py | 154 ++++++++++++++++++-------- src/extensions/nice-errors/main.py | 8 +- src/extensions/nice-errors/patch.py | 4 +- 6 files changed, 124 insertions(+), 58 deletions(-) diff --git a/pdm.lock b/pdm.lock index 149e458..55be70c 100644 --- a/pdm.lock +++ b/pdm.lock @@ -124,7 +124,7 @@ files = [ [[package]] name = "basedpyright" -version = "1.20.0" +version = "1.21.0" requires_python = ">=3.8" summary = "static type checking for Python (but based)" groups = ["dev"] @@ -132,8 +132,8 @@ dependencies = [ "nodejs-wheel-binaries>=20.13.1", ] files = [ - {file = "basedpyright-1.20.0-py3-none-any.whl", hash = "sha256:65de9f930ca327e74f2281da8e9b51d56a04efb25a1ba8ec5767c21751cdb2c3"}, - {file = "basedpyright-1.20.0.tar.gz", hash = "sha256:0a9573b3947927dad915b13db520f48810676b9b0b894128743d5f442134b361"}, + {file = "basedpyright-1.21.0-py3-none-any.whl", hash = "sha256:48902c476d6301c556df6eeae9acf1e34b176b14f8702ad5c770f4e6a747018a"}, + {file = "basedpyright-1.21.0.tar.gz", hash = "sha256:e3a9f5b89acc7f23d5a10d95ea6056b2247fcd15b8b248ad44c560c85c39d5e3"}, ] [[package]] diff --git a/pyproject.toml b/pyproject.toml index b4434b2..b02a78e 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -76,7 +76,8 @@ docstring-code-line-length = "dynamic" [tool.ruff.lint] select = ["ALL"] -extend-ignore = ["N999", +extend-ignore = [ + "N999", "D104", "D100", "D103", diff --git a/src/custom/__init__.py b/src/custom/__init__.py index 28e15c6..a50f680 100644 --- a/src/custom/__init__.py +++ b/src/custom/__init__.py @@ -2,7 +2,7 @@ # SPDX-License-Identifier: MIT from logging import getLogger -from typing import Any # pyright: ignore[reportDeprecated] +from typing import TYPE_CHECKING, Any, TypeAlias # pyright: ignore[reportDeprecated] import discord from discord import Message @@ -79,6 +79,9 @@ async def get_context( return ctx -Context = ExtContext | ApplicationContext +Context: ApplicationContext = ApplicationContext # pyright: ignore [reportRedeclaration] + +if TYPE_CHECKING: # temp fix for https://github.com/Pycord-Development/pycord/pull/2611 + Context: TypeAlias = ExtContext | ApplicationContext __all__ = ["Bot", "Context", "ExtContext", "ApplicationContext"] diff --git a/src/extensions/nice-errors/handler.py b/src/extensions/nice-errors/handler.py index b5f4c6e..5ad4558 100644 --- a/src/extensions/nice-errors/handler.py +++ b/src/extensions/nice-errors/handler.py @@ -3,16 +3,16 @@ import contextlib import difflib -from typing import Any +from collections.abc import Callable, Coroutine +from typing import Any, TypeAlias, TypeVar, final import discord from discord.ext import bridge, commands -from discord.interactions import Interaction from typing_extensions import override from src import custom from src.i18n import apply_locale -from src.i18n.classes import RawTranslation +from src.i18n.classes import RawTranslation, TranslationWrapper sentry_sdk = None @@ -33,7 +33,7 @@ def __init__( super().__init__(style=discord.ButtonStyle.green, label=label) @override - async def callback(self, interaction: Interaction) -> None: + async def callback(self, interaction: discord.Interaction) -> None: if ( not interaction.user or not self.ctx.author # pyright: ignore[reportUnnecessaryComparison] @@ -63,63 +63,125 @@ def find_similar_command( if not isinstance(ctx.bot, custom.Bot): return None command_list: dict[str, bridge.BridgeExtCommand | commands.Command[Any, Any, Any]] = { - cmd.name: cmd for cmd in ctx.bot.commands - } # pyright: ignore[reportUnknownVariableType] + cmd.name: cmd + for cmd in ctx.bot.commands # pyright: ignore[reportUnknownVariableType] + } similar_command: str | None = find_most_similar(command, list(command_list.keys())) if similar_command: return command_list.get(similar_command) return None -def get_locale(ctx: custom.Context | Interaction) -> str | None: +def get_locale(ctx: custom.Context | discord.Interaction) -> str | None: locale: str | None = None if isinstance(ctx, custom.ApplicationContext): locale = ctx.locale or ctx.guild_locale elif isinstance(ctx, custom.ExtContext): if ctx.guild: # pyright: ignore[reportUnnecessaryComparison] # for some reason pyright thinks guild is function locale = ctx.guild.preferred_locale # pyright: ignore[reportFunctionMemberAccess] - elif isinstance(ctx, Interaction): # pyright: ignore[reportUnnecessaryIsInstance] # we want to really make sure + elif isinstance(ctx, discord.Interaction): # pyright: ignore[reportUnnecessaryIsInstance] locale = ctx.locale or ctx.guild_locale return locale -async def handle_error( - error: Exception | discord.ApplicationCommandInvokeError, - ctx: discord.Interaction | custom.Context, - /, - raw_translations: dict[str, RawTranslation], - use_sentry_sdk: bool = False, -) -> None: - original_error = error - report: bool = True - sendargs: dict[str, Any] = {} - translations = apply_locale(raw_translations, get_locale(ctx)) - if isinstance(error, discord.ApplicationCommandInvokeError): - original_error = error.original - if isinstance(error, commands.CommandNotFound) and isinstance(ctx, custom.ExtContext): - if similar_command := find_similar_command(ctx): - message = translations.error_command_not_found.format(similar_command=similar_command.name) - view = discord.ui.View( - RunInsteadButton( - translations.run_x_instead.format(command=similar_command.name), - ctx=ctx, - instead=similar_command, - ), - disable_on_timeout=True, - timeout=60, # 1 minute +T = TypeVar("T", bound=Coroutine[Any, Any, Any]) +ErrorHandlersIType: TypeAlias = Callable[ + [Exception, discord.Interaction | custom.Context, TranslationWrapper, dict[str, Any], str, bool], T +] +ErrorHandlerRType: TypeAlias = tuple[bool, bool, str, dict[str, Any]] +ErrorHandlerType: TypeAlias = ErrorHandlersIType[Coroutine[Any, Any, ErrorHandlerRType]] +ErrorHandlersType: TypeAlias = dict[ + type[Exception], + ErrorHandlerType, +] + + +async def handle_command_not_found( # noqa: PLR0913 + error: Exception, # noqa: ARG001 + ctx: custom.Context | discord.Interaction, + translations: TranslationWrapper, + sendargs: dict[str, Any], + message: str, + report: bool, +) -> ErrorHandlerRType: + if not isinstance(ctx, custom.ExtContext): + return False, report, message, sendargs + if similar_command := find_similar_command(ctx): + message = translations.error_command_not_found.format(similar_command=similar_command.name) + view = discord.ui.View( + RunInsteadButton( + translations.run_x_instead.format(command=similar_command.name), + ctx=ctx, + instead=similar_command, + ), + disable_on_timeout=True, + timeout=60, # 1 minute + ) + sendargs["view"] = view + return False, False, message, sendargs + return True, False, message, sendargs + + +DEFAULT_ERROR_HANDLERS: ErrorHandlersType = { + commands.CommandNotFound: handle_command_not_found, +} + + +@final +class ErrorHandler: + def __init__(self, error_handlers: ErrorHandlersType | None = None) -> None: + if error_handlers: + self.error_handlers = DEFAULT_ERROR_HANDLERS | error_handlers + else: + self.error_handlers = DEFAULT_ERROR_HANDLERS + + def _get_handler(self, error: Exception) -> ErrorHandlerType | None: + if handler := self.error_handlers.get(type(error)): # faster but might miss subclasses + return handler + for error_type, handler in self.error_handlers.items(): # slower but catches subclasses + if issubclass(type(error), error_type): + return handler + return None + + async def handle_error( + self, + error: Exception | discord.ApplicationCommandInvokeError, + ctx: discord.Interaction | custom.Context, + /, + raw_translations: dict[str, RawTranslation], + use_sentry_sdk: bool = False, + ) -> None: + original_error = error + report: bool = True + sendargs: dict[str, Any] = {} + translations = apply_locale(raw_translations, get_locale(ctx)) + message: str = "" + if isinstance(error, discord.ApplicationCommandInvokeError): + original_error = error.original + + if handler := self._get_handler(original_error): + handled, report, message, sendargs = await handler( + original_error, + ctx, + translations, + sendargs, + str(error), + report, ) - sendargs["view"] = view - report = False # this is not an error in the program + if handled: + return + elif isinstance(error, discord.Forbidden): + message = translations.error_missing_permissions + f"\n`{original_error.args[0].split(':')[-1].strip()}`" else: - return # this is not an error in the program - elif isinstance(error, discord.Forbidden): - message = translations.error_missing_permissions + f"\n`{original_error.args[0].split(':')[-1].strip()}`" - else: - message = translations.error_generic - if report and use_sentry_sdk and sentry_sdk: - out = sentry_sdk.capture_exception(error) - message += f"\n\n-# {translations.reported_to_devs} - `{out}`" - # capture the error *before* sending the message to avoid errors in the error handlers - await ctx.respond(message, ephemeral=True, **sendargs) - if report: - raise error + message = translations.error_generic + if report and use_sentry_sdk and sentry_sdk: + out = sentry_sdk.capture_exception(error) + message += f"\n\n-# {translations.reported_to_devs} - `{out}`" + await ctx.respond(message, ephemeral=True, **sendargs) + if report: + raise error + + def add_error_handler(self, error: type[Exception], handler: ErrorHandlerType) -> None: + self.error_handlers[error] = handler + +error_handler = ErrorHandler() diff --git a/src/extensions/nice-errors/main.py b/src/extensions/nice-errors/main.py index 256ee49..3103c6e 100644 --- a/src/extensions/nice-errors/main.py +++ b/src/extensions/nice-errors/main.py @@ -5,11 +5,11 @@ import discord from discord.ext import commands -from schema import Optional, Schema +from schema import Optional, Schema # pyright: ignore [reportMissingTypeStubs] from src import custom -from .handler import handle_error +from .handler import error_handler default = { "enabled": True, @@ -35,7 +35,7 @@ async def on_error( ctx: custom.ApplicationContext, error: discord.ApplicationCommandInvokeError, ) -> None: - await handle_error( + await error_handler.handle_error( error, ctx, raw_translations=self.config["translations"], @@ -44,7 +44,7 @@ async def on_error( @discord.Cog.listener("on_command_error") async def on_command_error(self, ctx: custom.ExtContext, error: commands.CommandError) -> None: - await handle_error( + await error_handler.handle_error( error, ctx, raw_translations=self.config["translations"], diff --git a/src/extensions/nice-errors/patch.py b/src/extensions/nice-errors/patch.py index 93e43b9..13d8eed 100644 --- a/src/extensions/nice-errors/patch.py +++ b/src/extensions/nice-errors/patch.py @@ -3,7 +3,7 @@ from typing import Any -from .handler import handle_error +from .handler import error_handler async def patch(config: dict[str, Any]) -> None: @@ -43,7 +43,7 @@ async def on_error( item: Item, # pyright: ignore[reportMissingTypeArgument,reportUnknownParameterType] interaction: Interaction, ) -> None: - await handle_error( + await error_handler.handle_error( error, interaction, raw_translations=config["translations"], From 2bbf7dec940bce9693a437202243920685ed8158 Mon Sep 17 00:00:00 2001 From: Paillat Date: Fri, 8 Nov 2024 13:53:35 +0100 Subject: [PATCH 06/61] Add error handler helper method --- src/extensions/nice-errors/handler.py | 5 +++-- src/extensions/nice-errors/main.py | 3 +++ 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/src/extensions/nice-errors/handler.py b/src/extensions/nice-errors/handler.py index 5ad4558..da31bab 100644 --- a/src/extensions/nice-errors/handler.py +++ b/src/extensions/nice-errors/handler.py @@ -136,9 +136,9 @@ def __init__(self, error_handlers: ErrorHandlersType | None = None) -> None: self.error_handlers = DEFAULT_ERROR_HANDLERS def _get_handler(self, error: Exception) -> ErrorHandlerType | None: - if handler := self.error_handlers.get(type(error)): # faster but might miss subclasses + if handler := self.error_handlers.get(type(error)): # faster but might miss subclasses return handler - for error_type, handler in self.error_handlers.items(): # slower but catches subclasses + for error_type, handler in self.error_handlers.items(): # slower but catches subclasses if issubclass(type(error), error_type): return handler return None @@ -184,4 +184,5 @@ async def handle_error( def add_error_handler(self, error: type[Exception], handler: ErrorHandlerType) -> None: self.error_handlers[error] = handler + error_handler = ErrorHandler() diff --git a/src/extensions/nice-errors/main.py b/src/extensions/nice-errors/main.py index 3103c6e..d482b40 100644 --- a/src/extensions/nice-errors/main.py +++ b/src/extensions/nice-errors/main.py @@ -51,6 +51,9 @@ async def on_command_error(self, ctx: custom.ExtContext, error: commands.Command use_sentry_sdk=self.sentry_sdk, ) + def add_error_handler(self, *args: Any, **kwargs: Any) -> None: + error_handler.add_error_handler(*args, **kwargs) + def setup(bot: custom.Bot, config: dict[str, Any]) -> None: bot.add_cog(NiceErrors(bot, bool(config.get("sentry", {}).get("dsn")), config)) From 3e81d427edf96631b13098beb008d848f3947d11 Mon Sep 17 00:00:00 2001 From: Paillat Date: Fri, 8 Nov 2024 15:48:57 +0100 Subject: [PATCH 07/61] :construction_worker: Boring docker stuff --- .dockerignore | 2 - Dockerfile | 38 +++--- pdm.lock | 340 +++++++++++++++++++++++------------------------ pyproject.toml | 14 +- requirements.txt | 279 ++++++++++++++++++++++++++++++++------ 5 files changed, 434 insertions(+), 239 deletions(-) diff --git a/.dockerignore b/.dockerignore index f6a9c4e..c55a48f 100644 --- a/.dockerignore +++ b/.dockerignore @@ -1,7 +1,5 @@ .github/ .gitignore config.example.yaml -poetry.lock -pyproject.toml readme.md renovate.json diff --git a/Dockerfile b/Dockerfile index 875398b..78d6950 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,33 +1,35 @@ # Copyright (c) NiceBots.xyz # SPDX-License-Identifier: MIT -# For more information, please refer to https://aka.ms/vscode-docker-python -FROM python:3.12-slim-bookworm +ARG PYTHON_VERSION=3.12 +ARG NODE_VERSION=20 +FROM python:${PYTHON_VERSION}-slim-bookworm AS python-base -# Keeps Python from generating .pyc files in the container ENV PYTHONDONTWRITEBYTECODE=1 - -# Turns off buffering for easier container logging ENV PYTHONUNBUFFERED=1 -# we move to the app folder and run the pip install command +RUN pip install -U pdm +ENV PDM_CHECK_UPDATE=false + WORKDIR /app +COPY src pyproject.toml pdm.lock ./ -ENV PYTHONUNBUFFERED 1 -ENV PYTHONDONTWRITEBYTECODE 1 +RUN pdm export --prod -o requirements.txt -# we copy just the requirements.txt first to leverage Docker cache -COPY requirements.txt . +FROM python:${PYTHON_VERSION}-slim-bookworm AS app -# Install pip requirements -RUN pip install -r requirements.txt +ENV PYTHONDONTWRITEBYTECODE=1 +ENV PYTHONUNBUFFERED=1 + +WORKDIR /app -# Creates a non-root user with an explicit UID and adds permission to access the /app folder RUN adduser -u 6392 --disabled-password --gecos "" appuser && chown -R appuser /app -USER appuser -# We copy the rest of the codebase into the image -COPY ./ /app/ +COPY --from=python-base --chown=appuser /app/requirements.txt ./ +COPY src/ ./src +COPY LICENSE ./ + +RUN pip install -r requirements.txt --require-hashes +USER appuser -# We run the application -CMD ["python", "src"] \ No newline at end of file +CMD ["python", "src"] diff --git a/pdm.lock b/pdm.lock index 55be70c..9661a8f 100644 --- a/pdm.lock +++ b/pdm.lock @@ -2,13 +2,13 @@ # It is not intended for manual editing. [metadata] -groups = ["default", "dev", "sentry"] -strategy = ["cross_platform", "inherit_metadata"] +groups = ["default", "dev"] +strategy = ["inherit_metadata"] lock_version = "4.5.0" -content_hash = "sha256:b06e1d1395ab9f1209cf4735fd34ecdd527665c735dbdfe5f6cb6a9541afa138" +content_hash = "sha256:0086468197db366b92490df6cb4904829351f850ccd9e2c898421d5a70317afc" [[metadata.targets]] -requires_python = "==3.11.*" +requires_python = "==3.12.*" [[package]] name = "aiofile" @@ -62,21 +62,21 @@ dependencies = [ "yarl<2.0,>=1.12.0", ] files = [ - {file = "aiohttp-3.10.10-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:c30a0eafc89d28e7f959281b58198a9fa5e99405f716c0289b7892ca345fe45f"}, - {file = "aiohttp-3.10.10-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:258c5dd01afc10015866114e210fb7365f0d02d9d059c3c3415382ab633fcbcb"}, - {file = "aiohttp-3.10.10-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:15ecd889a709b0080f02721255b3f80bb261c2293d3c748151274dfea93ac871"}, - {file = "aiohttp-3.10.10-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f3935f82f6f4a3820270842e90456ebad3af15810cf65932bd24da4463bc0a4c"}, - {file = "aiohttp-3.10.10-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:413251f6fcf552a33c981c4709a6bba37b12710982fec8e558ae944bfb2abd38"}, - {file = "aiohttp-3.10.10-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:d1720b4f14c78a3089562b8875b53e36b51c97c51adc53325a69b79b4b48ebcb"}, - {file = "aiohttp-3.10.10-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:679abe5d3858b33c2cf74faec299fda60ea9de62916e8b67e625d65bf069a3b7"}, - {file = "aiohttp-3.10.10-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:79019094f87c9fb44f8d769e41dbb664d6e8fcfd62f665ccce36762deaa0e911"}, - {file = "aiohttp-3.10.10-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:fe2fb38c2ed905a2582948e2de560675e9dfbee94c6d5ccdb1301c6d0a5bf092"}, - {file = "aiohttp-3.10.10-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:a3f00003de6eba42d6e94fabb4125600d6e484846dbf90ea8e48a800430cc142"}, - {file = "aiohttp-3.10.10-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:1bbb122c557a16fafc10354b9d99ebf2f2808a660d78202f10ba9d50786384b9"}, - {file = "aiohttp-3.10.10-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:30ca7c3b94708a9d7ae76ff281b2f47d8eaf2579cd05971b5dc681db8caac6e1"}, - {file = "aiohttp-3.10.10-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:df9270660711670e68803107d55c2b5949c2e0f2e4896da176e1ecfc068b974a"}, - {file = "aiohttp-3.10.10-cp311-cp311-win32.whl", hash = "sha256:aafc8ee9b742ce75044ae9a4d3e60e3d918d15a4c2e08a6c3c3e38fa59b92d94"}, - {file = "aiohttp-3.10.10-cp311-cp311-win_amd64.whl", hash = "sha256:362f641f9071e5f3ee6f8e7d37d5ed0d95aae656adf4ef578313ee585b585959"}, + {file = "aiohttp-3.10.10-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:9294bbb581f92770e6ed5c19559e1e99255e4ca604a22c5c6397b2f9dd3ee42c"}, + {file = "aiohttp-3.10.10-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:a8fa23fe62c436ccf23ff930149c047f060c7126eae3ccea005f0483f27b2e28"}, + {file = "aiohttp-3.10.10-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:5c6a5b8c7926ba5d8545c7dd22961a107526562da31a7a32fa2456baf040939f"}, + {file = "aiohttp-3.10.10-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:007ec22fbc573e5eb2fb7dec4198ef8f6bf2fe4ce20020798b2eb5d0abda6138"}, + {file = "aiohttp-3.10.10-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:9627cc1a10c8c409b5822a92d57a77f383b554463d1884008e051c32ab1b3742"}, + {file = "aiohttp-3.10.10-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:50edbcad60d8f0e3eccc68da67f37268b5144ecc34d59f27a02f9611c1d4eec7"}, + {file = "aiohttp-3.10.10-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a45d85cf20b5e0d0aa5a8dca27cce8eddef3292bc29d72dcad1641f4ed50aa16"}, + {file = "aiohttp-3.10.10-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0b00807e2605f16e1e198f33a53ce3c4523114059b0c09c337209ae55e3823a8"}, + {file = "aiohttp-3.10.10-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:f2d4324a98062be0525d16f768a03e0bbb3b9fe301ceee99611dc9a7953124e6"}, + {file = "aiohttp-3.10.10-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:438cd072f75bb6612f2aca29f8bd7cdf6e35e8f160bc312e49fbecab77c99e3a"}, + {file = "aiohttp-3.10.10-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:baa42524a82f75303f714108fea528ccacf0386af429b69fff141ffef1c534f9"}, + {file = "aiohttp-3.10.10-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:a7d8d14fe962153fc681f6366bdec33d4356f98a3e3567782aac1b6e0e40109a"}, + {file = "aiohttp-3.10.10-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:c1277cd707c465cd09572a774559a3cc7c7a28802eb3a2a9472588f062097205"}, + {file = "aiohttp-3.10.10-cp312-cp312-win32.whl", hash = "sha256:59bb3c54aa420521dc4ce3cc2c3fe2ad82adf7b09403fa1f48ae45c0cbde6628"}, + {file = "aiohttp-3.10.10-cp312-cp312-win_amd64.whl", hash = "sha256:0e1b370d8007c4ae31ee6db7f9a2fe801a42b146cec80a86766e7ad5c4a259cf"}, {file = "aiohttp-3.10.10.tar.gz", hash = "sha256:0631dd7c9f0822cc61c88586ca76d5b5ada26538097d0f1df510b082bad3411a"}, ] @@ -168,8 +168,8 @@ requires_python = "<4,>=3.7" summary = "Asynchronous file IO for Linux MacOS or Windows." groups = ["default"] files = [ - {file = "caio-0.9.17-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:079730a353bbde03796fab681e969472eace09ffbe5000e584868a7fe389ba6f"}, - {file = "caio-0.9.17-cp311-cp311-manylinux_2_12_x86_64.manylinux2010_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:549caa51b475877fe32856a26fe937366ae7a1c23a9727005b441db9abb12bcc"}, + {file = "caio-0.9.17-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:0ddb253b145a53ecca76381677ce465bc5efeaecb6aaf493fac43ae79659f0fb"}, + {file = "caio-0.9.17-cp312-cp312-manylinux_2_12_x86_64.manylinux2010_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b3e320b0ea371c810359934f8e8fe81777c493cc5fb4d41de44277cbe7336e74"}, {file = "caio-0.9.17-py3-none-any.whl", hash = "sha256:c55d4dc6b3a36f93237ecd6360e1c131c3808bc47d4191a130148a99b80bb311"}, {file = "caio-0.9.17.tar.gz", hash = "sha256:8f30511526814d961aeef389ea6885273abe6c655f1e08abbadb95d12fdd9b4f"}, ] @@ -179,7 +179,7 @@ name = "certifi" version = "2024.8.30" requires_python = ">=3.6" summary = "Python package for providing Mozilla's CA Bundle." -groups = ["sentry"] +groups = ["default"] files = [ {file = "certifi-2024.8.30-py3-none-any.whl", hash = "sha256:922820b53db7a7257ffbda3f597266d435245903d80737e34f8a45ff3e3230d8"}, {file = "certifi-2024.8.30.tar.gz", hash = "sha256:bec941d2aa8195e248a60b31ff9f0558284cf01a52591ceda73ea9afffd69fd9"}, @@ -266,21 +266,21 @@ requires_python = ">=3.8" summary = "A list-like structure which implements collections.abc.MutableSequence" groups = ["default"] files = [ - {file = "frozenlist-1.5.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:fd74520371c3c4175142d02a976aee0b4cb4a7cc912a60586ffd8d5929979b30"}, - {file = "frozenlist-1.5.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:2f3f7a0fbc219fb4455264cae4d9f01ad41ae6ee8524500f381de64ffaa077d5"}, - {file = "frozenlist-1.5.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:f47c9c9028f55a04ac254346e92977bf0f166c483c74b4232bee19a6697e4778"}, - {file = "frozenlist-1.5.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0996c66760924da6e88922756d99b47512a71cfd45215f3570bf1e0b694c206a"}, - {file = "frozenlist-1.5.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a2fe128eb4edeabe11896cb6af88fca5346059f6c8d807e3b910069f39157869"}, - {file = "frozenlist-1.5.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:1a8ea951bbb6cacd492e3948b8da8c502a3f814f5d20935aae74b5df2b19cf3d"}, - {file = "frozenlist-1.5.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:de537c11e4aa01d37db0d403b57bd6f0546e71a82347a97c6a9f0dcc532b3a45"}, - {file = "frozenlist-1.5.0-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9c2623347b933fcb9095841f1cc5d4ff0b278addd743e0e966cb3d460278840d"}, - {file = "frozenlist-1.5.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:cee6798eaf8b1416ef6909b06f7dc04b60755206bddc599f52232606e18179d3"}, - {file = "frozenlist-1.5.0-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:f5f9da7f5dbc00a604fe74aa02ae7c98bcede8a3b8b9666f9f86fc13993bc71a"}, - {file = "frozenlist-1.5.0-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:90646abbc7a5d5c7c19461d2e3eeb76eb0b204919e6ece342feb6032c9325ae9"}, - {file = "frozenlist-1.5.0-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:bdac3c7d9b705d253b2ce370fde941836a5f8b3c5c2b8fd70940a3ea3af7f4f2"}, - {file = "frozenlist-1.5.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:03d33c2ddbc1816237a67f66336616416e2bbb6beb306e5f890f2eb22b959cdf"}, - {file = "frozenlist-1.5.0-cp311-cp311-win32.whl", hash = "sha256:237f6b23ee0f44066219dae14c70ae38a63f0440ce6750f868ee08775073f942"}, - {file = "frozenlist-1.5.0-cp311-cp311-win_amd64.whl", hash = "sha256:0cc974cc93d32c42e7b0f6cf242a6bd941c57c61b618e78b6c0a96cb72788c1d"}, + {file = "frozenlist-1.5.0-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:31115ba75889723431aa9a4e77d5f398f5cf976eea3bdf61749731f62d4a4a21"}, + {file = "frozenlist-1.5.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:7437601c4d89d070eac8323f121fcf25f88674627505334654fd027b091db09d"}, + {file = "frozenlist-1.5.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:7948140d9f8ece1745be806f2bfdf390127cf1a763b925c4a805c603df5e697e"}, + {file = "frozenlist-1.5.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:feeb64bc9bcc6b45c6311c9e9b99406660a9c05ca8a5b30d14a78555088b0b3a"}, + {file = "frozenlist-1.5.0-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:683173d371daad49cffb8309779e886e59c2f369430ad28fe715f66d08d4ab1a"}, + {file = "frozenlist-1.5.0-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:7d57d8f702221405a9d9b40f9da8ac2e4a1a8b5285aac6100f3393675f0a85ee"}, + {file = "frozenlist-1.5.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:30c72000fbcc35b129cb09956836c7d7abf78ab5416595e4857d1cae8d6251a6"}, + {file = "frozenlist-1.5.0-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:000a77d6034fbad9b6bb880f7ec073027908f1b40254b5d6f26210d2dab1240e"}, + {file = "frozenlist-1.5.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:5d7f5a50342475962eb18b740f3beecc685a15b52c91f7d975257e13e029eca9"}, + {file = "frozenlist-1.5.0-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:87f724d055eb4785d9be84e9ebf0f24e392ddfad00b3fe036e43f489fafc9039"}, + {file = "frozenlist-1.5.0-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:6e9080bb2fb195a046e5177f10d9d82b8a204c0736a97a153c2466127de87784"}, + {file = "frozenlist-1.5.0-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:9b93d7aaa36c966fa42efcaf716e6b3900438632a626fb09c049f6a2f09fc631"}, + {file = "frozenlist-1.5.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:52ef692a4bc60a6dd57f507429636c2af8b6046db8b31b18dac02cbc8f507f7f"}, + {file = "frozenlist-1.5.0-cp312-cp312-win32.whl", hash = "sha256:29d94c256679247b33a3dc96cce0f93cbc69c23bf75ff715919332fdbb6a32b8"}, + {file = "frozenlist-1.5.0-cp312-cp312-win_amd64.whl", hash = "sha256:8969190d709e7c48ea386db202d708eb94bdb29207a1f269bab1196ce0dcca1f"}, {file = "frozenlist-1.5.0-py3-none-any.whl", hash = "sha256:d994863bba198a4a518b467bb971c56e1db3f180a25c6cf7bb1949c267f748c3"}, {file = "frozenlist-1.5.0.tar.gz", hash = "sha256:81d5af29e61b9c8348e876d442253723928dce6433e0e76cd925cd83f1b4b817"}, ] @@ -441,16 +441,16 @@ requires_python = ">=3.9" summary = "Safely add untrusted strings to HTML/XML markup." groups = ["default"] files = [ - {file = "MarkupSafe-3.0.2-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:9025b4018f3a1314059769c7bf15441064b2207cb3f065e6ea1e7359cb46db9d"}, - {file = "MarkupSafe-3.0.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:93335ca3812df2f366e80509ae119189886b0f3c2b81325d39efdb84a1e2ae93"}, - {file = "MarkupSafe-3.0.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2cb8438c3cbb25e220c2ab33bb226559e7afb3baec11c4f218ffa7308603c832"}, - {file = "MarkupSafe-3.0.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a123e330ef0853c6e822384873bef7507557d8e4a082961e1defa947aa59ba84"}, - {file = "MarkupSafe-3.0.2-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1e084f686b92e5b83186b07e8a17fc09e38fff551f3602b249881fec658d3eca"}, - {file = "MarkupSafe-3.0.2-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:d8213e09c917a951de9d09ecee036d5c7d36cb6cb7dbaece4c71a60d79fb9798"}, - {file = "MarkupSafe-3.0.2-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:5b02fb34468b6aaa40dfc198d813a641e3a63b98c2b05a16b9f80b7ec314185e"}, - {file = "MarkupSafe-3.0.2-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:0bff5e0ae4ef2e1ae4fdf2dfd5b76c75e5c2fa4132d05fc1b0dabcd20c7e28c4"}, - {file = "MarkupSafe-3.0.2-cp311-cp311-win32.whl", hash = "sha256:6c89876f41da747c8d3677a2b540fb32ef5715f97b66eeb0c6b66f5e3ef6f59d"}, - {file = "MarkupSafe-3.0.2-cp311-cp311-win_amd64.whl", hash = "sha256:70a87b411535ccad5ef2f1df5136506a10775d267e197e4cf531ced10537bd6b"}, + {file = "MarkupSafe-3.0.2-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:9778bd8ab0a994ebf6f84c2b949e65736d5575320a17ae8984a77fab08db94cf"}, + {file = "MarkupSafe-3.0.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:846ade7b71e3536c4e56b386c2a47adf5741d2d8b94ec9dc3e92e5e1ee1e2225"}, + {file = "MarkupSafe-3.0.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1c99d261bd2d5f6b59325c92c73df481e05e57f19837bdca8413b9eac4bd8028"}, + {file = "MarkupSafe-3.0.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e17c96c14e19278594aa4841ec148115f9c7615a47382ecb6b82bd8fea3ab0c8"}, + {file = "MarkupSafe-3.0.2-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:88416bd1e65dcea10bc7569faacb2c20ce071dd1f87539ca2ab364bf6231393c"}, + {file = "MarkupSafe-3.0.2-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:2181e67807fc2fa785d0592dc2d6206c019b9502410671cc905d132a92866557"}, + {file = "MarkupSafe-3.0.2-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:52305740fe773d09cffb16f8ed0427942901f00adedac82ec8b67752f58a1b22"}, + {file = "MarkupSafe-3.0.2-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:ad10d3ded218f1039f11a75f8091880239651b52e9bb592ca27de44eed242a48"}, + {file = "MarkupSafe-3.0.2-cp312-cp312-win32.whl", hash = "sha256:0f4ca02bea9a23221c0182836703cbf8930c5e9454bacce27e767509fa286a30"}, + {file = "MarkupSafe-3.0.2-cp312-cp312-win_amd64.whl", hash = "sha256:8e06879fc22a25ca47312fbe7c8264eb0b662f6db27cb2d3bbbc74b1df4b9b87"}, {file = "markupsafe-3.0.2.tar.gz", hash = "sha256:ee55d3edf80167e48ea11a923c7386f4669df67d7994554387f84e7d8b0a2bf0"}, ] @@ -475,21 +475,21 @@ dependencies = [ "typing-extensions>=4.1.0; python_version < \"3.11\"", ] files = [ - {file = "multidict-6.1.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:3efe2c2cb5763f2f1b275ad2bf7a287d3f7ebbef35648a9726e3b69284a4f3d6"}, - {file = "multidict-6.1.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:c7053d3b0353a8b9de430a4f4b4268ac9a4fb3481af37dfe49825bf45ca24156"}, - {file = "multidict-6.1.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:27e5fc84ccef8dfaabb09d82b7d179c7cf1a3fbc8a966f8274fcb4ab2eb4cadb"}, - {file = "multidict-6.1.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0e2b90b43e696f25c62656389d32236e049568b39320e2735d51f08fd362761b"}, - {file = "multidict-6.1.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d83a047959d38a7ff552ff94be767b7fd79b831ad1cd9920662db05fec24fe72"}, - {file = "multidict-6.1.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:d1a9dd711d0877a1ece3d2e4fea11a8e75741ca21954c919406b44e7cf971304"}, - {file = "multidict-6.1.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ec2abea24d98246b94913b76a125e855eb5c434f7c46546046372fe60f666351"}, - {file = "multidict-6.1.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4867cafcbc6585e4b678876c489b9273b13e9fff9f6d6d66add5e15d11d926cb"}, - {file = "multidict-6.1.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:5b48204e8d955c47c55b72779802b219a39acc3ee3d0116d5080c388970b76e3"}, - {file = "multidict-6.1.0-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:d8fff389528cad1618fb4b26b95550327495462cd745d879a8c7c2115248e399"}, - {file = "multidict-6.1.0-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:a7a9541cd308eed5e30318430a9c74d2132e9a8cb46b901326272d780bf2d423"}, - {file = "multidict-6.1.0-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:da1758c76f50c39a2efd5e9859ce7d776317eb1dd34317c8152ac9251fc574a3"}, - {file = "multidict-6.1.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:c943a53e9186688b45b323602298ab727d8865d8c9ee0b17f8d62d14b56f0753"}, - {file = "multidict-6.1.0-cp311-cp311-win32.whl", hash = "sha256:90f8717cb649eea3504091e640a1b8568faad18bd4b9fcd692853a04475a4b80"}, - {file = "multidict-6.1.0-cp311-cp311-win_amd64.whl", hash = "sha256:82176036e65644a6cc5bd619f65f6f19781e8ec2e5330f51aa9ada7504cc1926"}, + {file = "multidict-6.1.0-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:b04772ed465fa3cc947db808fa306d79b43e896beb677a56fb2347ca1a49c1fa"}, + {file = "multidict-6.1.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:6180c0ae073bddeb5a97a38c03f30c233e0a4d39cd86166251617d1bbd0af436"}, + {file = "multidict-6.1.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:071120490b47aa997cca00666923a83f02c7fbb44f71cf7f136df753f7fa8761"}, + {file = "multidict-6.1.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:50b3a2710631848991d0bf7de077502e8994c804bb805aeb2925a981de58ec2e"}, + {file = "multidict-6.1.0-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b58c621844d55e71c1b7f7c498ce5aa6985d743a1a59034c57a905b3f153c1ef"}, + {file = "multidict-6.1.0-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:55b6d90641869892caa9ca42ff913f7ff1c5ece06474fbd32fb2cf6834726c95"}, + {file = "multidict-6.1.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4b820514bfc0b98a30e3d85462084779900347e4d49267f747ff54060cc33925"}, + {file = "multidict-6.1.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:10a9b09aba0c5b48c53761b7c720aaaf7cf236d5fe394cd399c7ba662d5f9966"}, + {file = "multidict-6.1.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:1e16bf3e5fc9f44632affb159d30a437bfe286ce9e02754759be5536b169b305"}, + {file = "multidict-6.1.0-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:76f364861c3bfc98cbbcbd402d83454ed9e01a5224bb3a28bf70002a230f73e2"}, + {file = "multidict-6.1.0-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:820c661588bd01a0aa62a1283f20d2be4281b086f80dad9e955e690c75fb54a2"}, + {file = "multidict-6.1.0-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:0e5f362e895bc5b9e67fe6e4ded2492d8124bdf817827f33c5b46c2fe3ffaca6"}, + {file = "multidict-6.1.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:3ec660d19bbc671e3a6443325f07263be452c453ac9e512f5eb935e7d4ac28b3"}, + {file = "multidict-6.1.0-cp312-cp312-win32.whl", hash = "sha256:58130ecf8f7b8112cdb841486404f1282b9c86ccb30d3519faf301b2e5659133"}, + {file = "multidict-6.1.0-cp312-cp312-win_amd64.whl", hash = "sha256:188215fc0aafb8e03341995e7c4797860181562380f81ed0a87ff455b70bf1f1"}, {file = "multidict-6.1.0-py3-none-any.whl", hash = "sha256:48e171e52d1c4d33888e529b999e5900356b9ae588c2f09a52dcefb158b27506"}, {file = "multidict-6.1.0.tar.gz", hash = "sha256:22ae2ebf9b0c69d206c003e2f6a914ea33f0a932d4aa16f236afc049d9958f4a"}, ] @@ -533,28 +533,28 @@ requires_python = ">=3.8" summary = "Fast, correct Python JSON library supporting dataclasses, datetimes, and numpy" groups = ["default"] files = [ - {file = "orjson-3.10.11-cp311-cp311-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:1444f9cb7c14055d595de1036f74ecd6ce15f04a715e73f33bb6326c9cef01b6"}, - {file = "orjson-3.10.11-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:cdec57fe3b4bdebcc08a946db3365630332dbe575125ff3d80a3272ebd0ddafe"}, - {file = "orjson-3.10.11-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:4eed32f33a0ea6ef36ccc1d37f8d17f28a1d6e8eefae5928f76aff8f1df85e67"}, - {file = "orjson-3.10.11-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:80df27dd8697242b904f4ea54820e2d98d3f51f91e97e358fc13359721233e4b"}, - {file = "orjson-3.10.11-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:705f03cee0cb797256d54de6695ef219e5bc8c8120b6654dd460848d57a9af3d"}, - {file = "orjson-3.10.11-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:03246774131701de8e7059b2e382597da43144a9a7400f178b2a32feafc54bd5"}, - {file = "orjson-3.10.11-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:8b5759063a6c940a69c728ea70d7c33583991c6982915a839c8da5f957e0103a"}, - {file = "orjson-3.10.11-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:677f23e32491520eebb19c99bb34675daf5410c449c13416f7f0d93e2cf5f981"}, - {file = "orjson-3.10.11-cp311-none-win32.whl", hash = "sha256:a11225d7b30468dcb099498296ffac36b4673a8398ca30fdaec1e6c20df6aa55"}, - {file = "orjson-3.10.11-cp311-none-win_amd64.whl", hash = "sha256:df8c677df2f9f385fcc85ab859704045fa88d4668bc9991a527c86e710392bec"}, + {file = "orjson-3.10.11-cp312-cp312-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:360a4e2c0943da7c21505e47cf6bd725588962ff1d739b99b14e2f7f3545ba51"}, + {file = "orjson-3.10.11-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:496e2cb45de21c369079ef2d662670a4892c81573bcc143c4205cae98282ba97"}, + {file = "orjson-3.10.11-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:7dfa8db55c9792d53c5952900c6a919cfa377b4f4534c7a786484a6a4a350c19"}, + {file = "orjson-3.10.11-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:51f3382415747e0dbda9dade6f1e1a01a9d37f630d8c9049a8ed0e385b7a90c0"}, + {file = "orjson-3.10.11-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f35a1b9f50a219f470e0e497ca30b285c9f34948d3c8160d5ad3a755d9299433"}, + {file = "orjson-3.10.11-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e2f3b7c5803138e67028dde33450e054c87e0703afbe730c105f1fcd873496d5"}, + {file = "orjson-3.10.11-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:f91d9eb554310472bd09f5347950b24442600594c2edc1421403d7610a0998fd"}, + {file = "orjson-3.10.11-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:dfbb2d460a855c9744bbc8e36f9c3a997c4b27d842f3d5559ed54326e6911f9b"}, + {file = "orjson-3.10.11-cp312-none-win32.whl", hash = "sha256:d4a62c49c506d4d73f59514986cadebb7e8d186ad510c518f439176cf8d5359d"}, + {file = "orjson-3.10.11-cp312-none-win_amd64.whl", hash = "sha256:f1eec3421a558ff7a9b010a6c7effcfa0ade65327a71bb9b02a1c3b77a247284"}, {file = "orjson-3.10.11.tar.gz", hash = "sha256:e35b6d730de6384d5b2dab5fd23f0d76fae8bbc8c353c2f78210aa5fa4beb3ef"}, ] [[package]] name = "packaging" -version = "24.1" +version = "24.2" requires_python = ">=3.8" summary = "Core utilities for Python packages" groups = ["dev"] files = [ - {file = "packaging-24.1-py3-none-any.whl", hash = "sha256:5b8f2217dbdbd2f7f384c41c628544e6d52f2d0f53c6d0c3ea61aa5d1d7ff124"}, - {file = "packaging-24.1.tar.gz", hash = "sha256:026ed72c8ed3fcce5bf8950572258698927fd1dbda10a5e981cdf0ac37f4f002"}, + {file = "packaging-24.2-py3-none-any.whl", hash = "sha256:09abb1bccd265c01f4a3aa3f7a7db064b36514d2cba19a2f694fe6150451a759"}, + {file = "packaging-24.2.tar.gz", hash = "sha256:c228a6dc5e932d346bc5739379109d49e8853dd8223571c7c5b55260edc0b97f"}, ] [[package]] @@ -586,22 +586,22 @@ requires_python = ">=3.8" summary = "Accelerated property cache" groups = ["default"] files = [ - {file = "propcache-0.2.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:63f13bf09cc3336eb04a837490b8f332e0db41da66995c9fd1ba04552e516354"}, - {file = "propcache-0.2.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:608cce1da6f2672a56b24a015b42db4ac612ee709f3d29f27a00c943d9e851de"}, - {file = "propcache-0.2.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:466c219deee4536fbc83c08d09115249db301550625c7fef1c5563a584c9bc87"}, - {file = "propcache-0.2.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:fc2db02409338bf36590aa985a461b2c96fce91f8e7e0f14c50c5fcc4f229016"}, - {file = "propcache-0.2.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a6ed8db0a556343d566a5c124ee483ae113acc9a557a807d439bcecc44e7dfbb"}, - {file = "propcache-0.2.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:91997d9cb4a325b60d4e3f20967f8eb08dfcb32b22554d5ef78e6fd1dda743a2"}, - {file = "propcache-0.2.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4c7dde9e533c0a49d802b4f3f218fa9ad0a1ce21f2c2eb80d5216565202acab4"}, - {file = "propcache-0.2.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ffcad6c564fe6b9b8916c1aefbb37a362deebf9394bd2974e9d84232e3e08504"}, - {file = "propcache-0.2.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:97a58a28bcf63284e8b4d7b460cbee1edaab24634e82059c7b8c09e65284f178"}, - {file = "propcache-0.2.0-cp311-cp311-musllinux_1_2_armv7l.whl", hash = "sha256:945db8ee295d3af9dbdbb698cce9bbc5c59b5c3fe328bbc4387f59a8a35f998d"}, - {file = "propcache-0.2.0-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:39e104da444a34830751715f45ef9fc537475ba21b7f1f5b0f4d71a3b60d7fe2"}, - {file = "propcache-0.2.0-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:c5ecca8f9bab618340c8e848d340baf68bcd8ad90a8ecd7a4524a81c1764b3db"}, - {file = "propcache-0.2.0-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:c436130cc779806bdf5d5fae0d848713105472b8566b75ff70048c47d3961c5b"}, - {file = "propcache-0.2.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:191db28dc6dcd29d1a3e063c3be0b40688ed76434622c53a284e5427565bbd9b"}, - {file = "propcache-0.2.0-cp311-cp311-win32.whl", hash = "sha256:5f2564ec89058ee7c7989a7b719115bdfe2a2fb8e7a4543b8d1c0cc4cf6478c1"}, - {file = "propcache-0.2.0-cp311-cp311-win_amd64.whl", hash = "sha256:6e2e54267980349b723cff366d1e29b138b9a60fa376664a157a342689553f71"}, + {file = "propcache-0.2.0-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:2ee7606193fb267be4b2e3b32714f2d58cad27217638db98a60f9efb5efeccc2"}, + {file = "propcache-0.2.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:91ee8fc02ca52e24bcb77b234f22afc03288e1dafbb1f88fe24db308910c4ac7"}, + {file = "propcache-0.2.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:2e900bad2a8456d00a113cad8c13343f3b1f327534e3589acc2219729237a2e8"}, + {file = "propcache-0.2.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f52a68c21363c45297aca15561812d542f8fc683c85201df0bebe209e349f793"}, + {file = "propcache-0.2.0-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1e41d67757ff4fbc8ef2af99b338bfb955010444b92929e9e55a6d4dcc3c4f09"}, + {file = "propcache-0.2.0-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a64e32f8bd94c105cc27f42d3b658902b5bcc947ece3c8fe7bc1b05982f60e89"}, + {file = "propcache-0.2.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:55346705687dbd7ef0d77883ab4f6fabc48232f587925bdaf95219bae072491e"}, + {file = "propcache-0.2.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:00181262b17e517df2cd85656fcd6b4e70946fe62cd625b9d74ac9977b64d8d9"}, + {file = "propcache-0.2.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:6994984550eaf25dd7fc7bd1b700ff45c894149341725bb4edc67f0ffa94efa4"}, + {file = "propcache-0.2.0-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:56295eb1e5f3aecd516d91b00cfd8bf3a13991de5a479df9e27dd569ea23959c"}, + {file = "propcache-0.2.0-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:439e76255daa0f8151d3cb325f6dd4a3e93043e6403e6491813bcaaaa8733887"}, + {file = "propcache-0.2.0-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:f6475a1b2ecb310c98c28d271a30df74f9dd436ee46d09236a6b750a7599ce57"}, + {file = "propcache-0.2.0-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:3444cdba6628accf384e349014084b1cacd866fbb88433cd9d279d90a54e0b23"}, + {file = "propcache-0.2.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:4a9d9b4d0a9b38d1c391bb4ad24aa65f306c6f01b512e10a8a34a2dc5675d348"}, + {file = "propcache-0.2.0-cp312-cp312-win32.whl", hash = "sha256:69d3a98eebae99a420d4b28756c8ce6ea5a29291baf2dc9ff9414b42676f61d5"}, + {file = "propcache-0.2.0-cp312-cp312-win_amd64.whl", hash = "sha256:ad9c9b99b05f163109466638bd30ada1722abb01bbb85c739c50b6dc11f92dc3"}, {file = "propcache-0.2.0-py3-none-any.whl", hash = "sha256:2ccc28197af5313706511fab3a8b66dcd6da067a1331372c82ea1cb74285e036"}, {file = "propcache-0.2.0.tar.gz", hash = "sha256:df81779732feb9d01e5d513fad0122efb3d53bbc75f61b2a4f29a020bc985e70"}, ] @@ -648,18 +648,18 @@ dependencies = [ "typing-extensions!=4.7.0,>=4.6.0", ] files = [ - {file = "pydantic_core-2.23.4-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:77733e3892bb0a7fa797826361ce8a9184d25c8dffaec60b7ffe928153680ba8"}, - {file = "pydantic_core-2.23.4-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:1b84d168f6c48fabd1f2027a3d1bdfe62f92cade1fb273a5d68e621da0e44e6d"}, - {file = "pydantic_core-2.23.4-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:df49e7a0861a8c36d089c1ed57d308623d60416dab2647a4a17fe050ba85de0e"}, - {file = "pydantic_core-2.23.4-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:ff02b6d461a6de369f07ec15e465a88895f3223eb75073ffea56b84d9331f607"}, - {file = "pydantic_core-2.23.4-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:996a38a83508c54c78a5f41456b0103c30508fed9abcad0a59b876d7398f25fd"}, - {file = "pydantic_core-2.23.4-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:d97683ddee4723ae8c95d1eddac7c192e8c552da0c73a925a89fa8649bf13eea"}, - {file = "pydantic_core-2.23.4-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:216f9b2d7713eb98cb83c80b9c794de1f6b7e3145eef40400c62e86cee5f4e1e"}, - {file = "pydantic_core-2.23.4-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:6f783e0ec4803c787bcea93e13e9932edab72068f68ecffdf86a99fd5918878b"}, - {file = "pydantic_core-2.23.4-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:d0776dea117cf5272382634bd2a5c1b6eb16767c223c6a5317cd3e2a757c61a0"}, - {file = "pydantic_core-2.23.4-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:d5f7a395a8cf1621939692dba2a6b6a830efa6b3cee787d82c7de1ad2930de64"}, - {file = "pydantic_core-2.23.4-cp311-none-win32.whl", hash = "sha256:74b9127ffea03643e998e0c5ad9bd3811d3dac8c676e47db17b0ee7c3c3bf35f"}, - {file = "pydantic_core-2.23.4-cp311-none-win_amd64.whl", hash = "sha256:98d134c954828488b153d88ba1f34e14259284f256180ce659e8d83e9c05eaa3"}, + {file = "pydantic_core-2.23.4-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:f3e0da4ebaef65158d4dfd7d3678aad692f7666877df0002b8a522cdf088f231"}, + {file = "pydantic_core-2.23.4-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:f69a8e0b033b747bb3e36a44e7732f0c99f7edd5cea723d45bc0d6e95377ffee"}, + {file = "pydantic_core-2.23.4-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:723314c1d51722ab28bfcd5240d858512ffd3116449c557a1336cbe3919beb87"}, + {file = "pydantic_core-2.23.4-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:bb2802e667b7051a1bebbfe93684841cc9351004e2badbd6411bf357ab8d5ac8"}, + {file = "pydantic_core-2.23.4-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d18ca8148bebe1b0a382a27a8ee60350091a6ddaf475fa05ef50dc35b5df6327"}, + {file = "pydantic_core-2.23.4-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:33e3d65a85a2a4a0dc3b092b938a4062b1a05f3a9abde65ea93b233bca0e03f2"}, + {file = "pydantic_core-2.23.4-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:128585782e5bfa515c590ccee4b727fb76925dd04a98864182b22e89a4e6ed36"}, + {file = "pydantic_core-2.23.4-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:68665f4c17edcceecc112dfed5dbe6f92261fb9d6054b47d01bf6371a6196126"}, + {file = "pydantic_core-2.23.4-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:20152074317d9bed6b7a95ade3b7d6054845d70584216160860425f4fbd5ee9e"}, + {file = "pydantic_core-2.23.4-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:9261d3ce84fa1d38ed649c3638feefeae23d32ba9182963e465d58d62203bd24"}, + {file = "pydantic_core-2.23.4-cp312-none-win32.whl", hash = "sha256:4ba762ed58e8d68657fc1281e9bb72e1c3e79cc5d464be146e260c541ec12d84"}, + {file = "pydantic_core-2.23.4-cp312-none-win_amd64.whl", hash = "sha256:97df63000f4fea395b2824da80e169731088656d1818a11b95f3b173747b6cd9"}, {file = "pydantic_core-2.23.4.tar.gz", hash = "sha256:2584f7cf844ac4d970fba483a717dbe10c1c1c96a969bf65d61ffe94df1b2863"}, ] @@ -722,15 +722,15 @@ requires_python = ">=3.8" summary = "YAML parser and emitter for Python" groups = ["default"] files = [ - {file = "PyYAML-6.0.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:cc1c1159b3d456576af7a3e4d1ba7e6924cb39de8f67111c735f6fc832082774"}, - {file = "PyYAML-6.0.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:1e2120ef853f59c7419231f3bf4e7021f1b936f6ebd222406c3b60212205d2ee"}, - {file = "PyYAML-6.0.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5d225db5a45f21e78dd9358e58a98702a0302f2659a3c6cd320564b75b86f47c"}, - {file = "PyYAML-6.0.2-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5ac9328ec4831237bec75defaf839f7d4564be1e6b25ac710bd1a96321cc8317"}, - {file = "PyYAML-6.0.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3ad2a3decf9aaba3d29c8f537ac4b243e36bef957511b4766cb0057d32b0be85"}, - {file = "PyYAML-6.0.2-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:ff3824dc5261f50c9b0dfb3be22b4567a6f938ccce4587b38952d85fd9e9afe4"}, - {file = "PyYAML-6.0.2-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:797b4f722ffa07cc8d62053e4cff1486fa6dc094105d13fea7b1de7d8bf71c9e"}, - {file = "PyYAML-6.0.2-cp311-cp311-win32.whl", hash = "sha256:11d8f3dd2b9c1207dcaf2ee0bbbfd5991f571186ec9cc78427ba5bd32afae4b5"}, - {file = "PyYAML-6.0.2-cp311-cp311-win_amd64.whl", hash = "sha256:e10ce637b18caea04431ce14fabcf5c64a1c61ec9c56b071a4b7ca131ca52d44"}, + {file = "PyYAML-6.0.2-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:c70c95198c015b85feafc136515252a261a84561b7b1d51e3384e0655ddf25ab"}, + {file = "PyYAML-6.0.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:ce826d6ef20b1bc864f0a68340c8b3287705cae2f8b4b1d932177dcc76721725"}, + {file = "PyYAML-6.0.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1f71ea527786de97d1a0cc0eacd1defc0985dcf6b3f17bb77dcfc8c34bec4dc5"}, + {file = "PyYAML-6.0.2-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:9b22676e8097e9e22e36d6b7bda33190d0d400f345f23d4065d48f4ca7ae0425"}, + {file = "PyYAML-6.0.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:80bab7bfc629882493af4aa31a4cfa43a4c57c83813253626916b8c7ada83476"}, + {file = "PyYAML-6.0.2-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:0833f8694549e586547b576dcfaba4a6b55b9e96098b36cdc7ebefe667dfed48"}, + {file = "PyYAML-6.0.2-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:8b9c7197f7cb2738065c481a0461e50ad02f18c78cd75775628afb4d7137fb3b"}, + {file = "PyYAML-6.0.2-cp312-cp312-win32.whl", hash = "sha256:ef6107725bd54b262d6dedcc2af448a266975032bc85ef0172c5f059da6325b4"}, + {file = "PyYAML-6.0.2-cp312-cp312-win_amd64.whl", hash = "sha256:7e7401d0de89a9a855c839bc697c079a4af81cf878373abd7dc625847d25cbd8"}, {file = "pyyaml-6.0.2.tar.gz", hash = "sha256:d584d9ec91ad65861cc08d42e834324ef890a082e591037abe114850ff7bbc3e"}, ] @@ -760,29 +760,29 @@ files = [ [[package]] name = "ruff" -version = "0.7.2" +version = "0.7.3" requires_python = ">=3.7" summary = "An extremely fast Python linter and code formatter, written in Rust." groups = ["dev"] files = [ - {file = "ruff-0.7.2-py3-none-linux_armv6l.whl", hash = "sha256:b73f873b5f52092e63ed540adefc3c36f1f803790ecf2590e1df8bf0a9f72cb8"}, - {file = "ruff-0.7.2-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:5b813ef26db1015953daf476202585512afd6a6862a02cde63f3bafb53d0b2d4"}, - {file = "ruff-0.7.2-py3-none-macosx_11_0_arm64.whl", hash = "sha256:853277dbd9675810c6826dad7a428d52a11760744508340e66bf46f8be9701d9"}, - {file = "ruff-0.7.2-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:21aae53ab1490a52bf4e3bf520c10ce120987b047c494cacf4edad0ba0888da2"}, - {file = "ruff-0.7.2-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:ccc7e0fc6e0cb3168443eeadb6445285abaae75142ee22b2b72c27d790ab60ba"}, - {file = "ruff-0.7.2-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:fd77877a4e43b3a98e5ef4715ba3862105e299af0c48942cc6d51ba3d97dc859"}, - {file = "ruff-0.7.2-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:e00163fb897d35523c70d71a46fbaa43bf7bf9af0f4534c53ea5b96b2e03397b"}, - {file = "ruff-0.7.2-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f3c54b538633482dc342e9b634d91168fe8cc56b30a4b4f99287f4e339103e88"}, - {file = "ruff-0.7.2-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:7b792468e9804a204be221b14257566669d1db5c00d6bb335996e5cd7004ba80"}, - {file = "ruff-0.7.2-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dba53ed84ac19ae4bfb4ea4bf0172550a2285fa27fbb13e3746f04c80f7fa088"}, - {file = "ruff-0.7.2-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:b19fafe261bf741bca2764c14cbb4ee1819b67adb63ebc2db6401dcd652e3748"}, - {file = "ruff-0.7.2-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:28bd8220f4d8f79d590db9e2f6a0674f75ddbc3847277dd44ac1f8d30684b828"}, - {file = "ruff-0.7.2-py3-none-musllinux_1_2_i686.whl", hash = "sha256:9fd67094e77efbea932e62b5d2483006154794040abb3a5072e659096415ae1e"}, - {file = "ruff-0.7.2-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:576305393998b7bd6c46018f8104ea3a9cb3fa7908c21d8580e3274a3b04b691"}, - {file = "ruff-0.7.2-py3-none-win32.whl", hash = "sha256:fa993cfc9f0ff11187e82de874dfc3611df80852540331bc85c75809c93253a8"}, - {file = "ruff-0.7.2-py3-none-win_amd64.whl", hash = "sha256:dd8800cbe0254e06b8fec585e97554047fb82c894973f7ff18558eee33d1cb88"}, - {file = "ruff-0.7.2-py3-none-win_arm64.whl", hash = "sha256:bb8368cd45bba3f57bb29cbb8d64b4a33f8415d0149d2655c5c8539452ce7760"}, - {file = "ruff-0.7.2.tar.gz", hash = "sha256:2b14e77293380e475b4e3a7a368e14549288ed2931fce259a6f99978669e844f"}, + {file = "ruff-0.7.3-py3-none-linux_armv6l.whl", hash = "sha256:34f2339dc22687ec7e7002792d1f50712bf84a13d5152e75712ac08be565d344"}, + {file = "ruff-0.7.3-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:fb397332a1879b9764a3455a0bb1087bda876c2db8aca3a3cbb67b3dbce8cda0"}, + {file = "ruff-0.7.3-py3-none-macosx_11_0_arm64.whl", hash = "sha256:37d0b619546103274e7f62643d14e1adcbccb242efda4e4bdb9544d7764782e9"}, + {file = "ruff-0.7.3-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5d59f0c3ee4d1a6787614e7135b72e21024875266101142a09a61439cb6e38a5"}, + {file = "ruff-0.7.3-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:44eb93c2499a169d49fafd07bc62ac89b1bc800b197e50ff4633aed212569299"}, + {file = "ruff-0.7.3-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6d0242ce53f3a576c35ee32d907475a8d569944c0407f91d207c8af5be5dae4e"}, + {file = "ruff-0.7.3-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:6b6224af8b5e09772c2ecb8dc9f3f344c1aa48201c7f07e7315367f6dd90ac29"}, + {file = "ruff-0.7.3-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:c50f95a82b94421c964fae4c27c0242890a20fe67d203d127e84fbb8013855f5"}, + {file = "ruff-0.7.3-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:7f3eff9961b5d2644bcf1616c606e93baa2d6b349e8aa8b035f654df252c8c67"}, + {file = "ruff-0.7.3-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b8963cab06d130c4df2fd52c84e9f10d297826d2e8169ae0c798b6221be1d1d2"}, + {file = "ruff-0.7.3-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:61b46049d6edc0e4317fb14b33bd693245281a3007288b68a3f5b74a22a0746d"}, + {file = "ruff-0.7.3-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:10ebce7696afe4644e8c1a23b3cf8c0f2193a310c18387c06e583ae9ef284de2"}, + {file = "ruff-0.7.3-py3-none-musllinux_1_2_i686.whl", hash = "sha256:3f36d56326b3aef8eeee150b700e519880d1aab92f471eefdef656fd57492aa2"}, + {file = "ruff-0.7.3-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:5d024301109a0007b78d57ab0ba190087b43dce852e552734ebf0b0b85e4fb16"}, + {file = "ruff-0.7.3-py3-none-win32.whl", hash = "sha256:4ba81a5f0c5478aa61674c5a2194de8b02652f17addf8dfc40c8937e6e7d79fc"}, + {file = "ruff-0.7.3-py3-none-win_amd64.whl", hash = "sha256:588a9ff2fecf01025ed065fe28809cd5a53b43505f48b69a1ac7707b1b7e4088"}, + {file = "ruff-0.7.3-py3-none-win_arm64.whl", hash = "sha256:1713e2c5545863cdbfe2cbce21f69ffaf37b813bfd1fb3b90dc9a6f1963f5a8c"}, + {file = "ruff-0.7.3.tar.gz", hash = "sha256:e1d1ba2e40b6e71a61b063354d04be669ab0d39c352461f3d789cac68b54a313"}, ] [[package]] @@ -803,7 +803,7 @@ name = "sentry-sdk" version = "2.18.0" requires_python = ">=3.6" summary = "Python client for Sentry (https://sentry.io)" -groups = ["sentry"] +groups = ["default"] dependencies = [ "certifi", "urllib3>=1.26.11", @@ -851,7 +851,7 @@ name = "urllib3" version = "2.2.3" requires_python = ">=3.8" summary = "HTTP library with thread-safe connection pooling, file post, and more." -groups = ["sentry"] +groups = ["default"] files = [ {file = "urllib3-2.2.3-py3-none-any.whl", hash = "sha256:ca899ca043dcb1bafa3e262d73aa25c465bfb49e0bd9dd5d59f1d0acba2f8fac"}, {file = "urllib3-2.2.3.tar.gz", hash = "sha256:e7d814a81dad81e6caf2ec9fdedb284ecc9c73076b62654547cc64ccdcae26e9"}, @@ -864,17 +864,17 @@ requires_python = ">=3.8" summary = "An implementation of the WebSocket Protocol (RFC 6455 & 7692)" groups = ["dev"] files = [ - {file = "websockets-13.1-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:61fc0dfcda609cda0fc9fe7977694c0c59cf9d749fbb17f4e9483929e3c48a19"}, - {file = "websockets-13.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:ceec59f59d092c5007e815def4ebb80c2de330e9588e101cf8bd94c143ec78a5"}, - {file = "websockets-13.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:c1dca61c6db1166c48b95198c0b7d9c990b30c756fc2923cc66f68d17dc558fd"}, - {file = "websockets-13.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:308e20f22c2c77f3f39caca508e765f8725020b84aa963474e18c59accbf4c02"}, - {file = "websockets-13.1-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:62d516c325e6540e8a57b94abefc3459d7dab8ce52ac75c96cad5549e187e3a7"}, - {file = "websockets-13.1-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:87c6e35319b46b99e168eb98472d6c7d8634ee37750d7693656dc766395df096"}, - {file = "websockets-13.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:5f9fee94ebafbc3117c30be1844ed01a3b177bb6e39088bc6b2fa1dc15572084"}, - {file = "websockets-13.1-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:7c1e90228c2f5cdde263253fa5db63e6653f1c00e7ec64108065a0b9713fa1b3"}, - {file = "websockets-13.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:6548f29b0e401eea2b967b2fdc1c7c7b5ebb3eeb470ed23a54cd45ef078a0db9"}, - {file = "websockets-13.1-cp311-cp311-win32.whl", hash = "sha256:c11d4d16e133f6df8916cc5b7e3e96ee4c44c936717d684a94f48f82edb7c92f"}, - {file = "websockets-13.1-cp311-cp311-win_amd64.whl", hash = "sha256:d04f13a1d75cb2b8382bdc16ae6fa58c97337253826dfe136195b7f89f661557"}, + {file = "websockets-13.1-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:9d75baf00138f80b48f1eac72ad1535aac0b6461265a0bcad391fc5aba875cfc"}, + {file = "websockets-13.1-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:9b6f347deb3dcfbfde1c20baa21c2ac0751afaa73e64e5b693bb2b848efeaa49"}, + {file = "websockets-13.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:de58647e3f9c42f13f90ac7e5f58900c80a39019848c5547bc691693098ae1bd"}, + {file = "websockets-13.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a1b54689e38d1279a51d11e3467dd2f3a50f5f2e879012ce8f2d6943f00e83f0"}, + {file = "websockets-13.1-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:cf1781ef73c073e6b0f90af841aaf98501f975d306bbf6221683dd594ccc52b6"}, + {file = "websockets-13.1-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8d23b88b9388ed85c6faf0e74d8dec4f4d3baf3ecf20a65a47b836d56260d4b9"}, + {file = "websockets-13.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:3c78383585f47ccb0fcf186dcb8a43f5438bd7d8f47d69e0b56f71bf431a0a68"}, + {file = "websockets-13.1-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:d6d300f8ec35c24025ceb9b9019ae9040c1ab2f01cddc2bcc0b518af31c75c14"}, + {file = "websockets-13.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:a9dcaf8b0cc72a392760bb8755922c03e17a5a54e08cca58e8b74f6902b433cf"}, + {file = "websockets-13.1-cp312-cp312-win32.whl", hash = "sha256:2f85cf4f2a1ba8f602298a853cec8526c2ca42a9a4b947ec236eaedb8f2dc80c"}, + {file = "websockets-13.1-cp312-cp312-win_amd64.whl", hash = "sha256:38377f8b0cdeee97c552d20cf1865695fcd56aba155ad1b4ca8779a5b6ef4ac3"}, {file = "websockets-13.1-py3-none-any.whl", hash = "sha256:a9a396a6ad26130cdae92ae10c36af09d9bfe6cafe69670fd3b6da9b07b4044f"}, {file = "websockets-13.1.tar.gz", hash = "sha256:a3b3366087c1bc0a2795111edcadddb8b3b59509d5db5d7ea3fdd69f954a8878"}, ] @@ -900,16 +900,16 @@ requires_python = ">=3.6" summary = "Module for decorators, wrappers and monkey patching." groups = ["dev"] files = [ - {file = "wrapt-1.16.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:1a5db485fe2de4403f13fafdc231b0dbae5eca4359232d2efc79025527375b09"}, - {file = "wrapt-1.16.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:75ea7d0ee2a15733684badb16de6794894ed9c55aa5e9903260922f0482e687d"}, - {file = "wrapt-1.16.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a452f9ca3e3267cd4d0fcf2edd0d035b1934ac2bd7e0e57ac91ad6b95c0c6389"}, - {file = "wrapt-1.16.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:43aa59eadec7890d9958748db829df269f0368521ba6dc68cc172d5d03ed8060"}, - {file = "wrapt-1.16.0-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:72554a23c78a8e7aa02abbd699d129eead8b147a23c56e08d08dfc29cfdddca1"}, - {file = "wrapt-1.16.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:d2efee35b4b0a347e0d99d28e884dfd82797852d62fcd7ebdeee26f3ceb72cf3"}, - {file = "wrapt-1.16.0-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:6dcfcffe73710be01d90cae08c3e548d90932d37b39ef83969ae135d36ef3956"}, - {file = "wrapt-1.16.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:eb6e651000a19c96f452c85132811d25e9264d836951022d6e81df2fff38337d"}, - {file = "wrapt-1.16.0-cp311-cp311-win32.whl", hash = "sha256:66027d667efe95cc4fa945af59f92c5a02c6f5bb6012bff9e60542c74c75c362"}, - {file = "wrapt-1.16.0-cp311-cp311-win_amd64.whl", hash = "sha256:aefbc4cb0a54f91af643660a0a150ce2c090d3652cf4052a5397fb2de549cd89"}, + {file = "wrapt-1.16.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:5eb404d89131ec9b4f748fa5cfb5346802e5ee8836f57d516576e61f304f3b7b"}, + {file = "wrapt-1.16.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:9090c9e676d5236a6948330e83cb89969f433b1943a558968f659ead07cb3b36"}, + {file = "wrapt-1.16.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:94265b00870aa407bd0cbcfd536f17ecde43b94fb8d228560a1e9d3041462d73"}, + {file = "wrapt-1.16.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f2058f813d4f2b5e3a9eb2eb3faf8f1d99b81c3e51aeda4b168406443e8ba809"}, + {file = "wrapt-1.16.0-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:98b5e1f498a8ca1858a1cdbffb023bfd954da4e3fa2c0cb5853d40014557248b"}, + {file = "wrapt-1.16.0-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:14d7dc606219cdd7405133c713f2c218d4252f2a469003f8c46bb92d5d095d81"}, + {file = "wrapt-1.16.0-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:49aac49dc4782cb04f58986e81ea0b4768e4ff197b57324dcbd7699c5dfb40b9"}, + {file = "wrapt-1.16.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:418abb18146475c310d7a6dc71143d6f7adec5b004ac9ce08dc7a34e2babdc5c"}, + {file = "wrapt-1.16.0-cp312-cp312-win32.whl", hash = "sha256:685f568fa5e627e93f3b52fda002c7ed2fa1800b50ce51f6ed1d572d8ab3e7fc"}, + {file = "wrapt-1.16.0-cp312-cp312-win_amd64.whl", hash = "sha256:dcdba5c86e368442528f7060039eda390cc4091bfd1dca41e8046af7c910dda8"}, {file = "wrapt-1.16.0-py3-none-any.whl", hash = "sha256:6906c4100a8fcbf2fa735f6059214bb13b97f75b1a61777fcf6432121ef12ef1"}, {file = "wrapt-1.16.0.tar.gz", hash = "sha256:5f370f952971e7d17c7d1ead40e49f32345a7f7a5373571ef44d800d06b1899d"}, ] @@ -940,22 +940,22 @@ dependencies = [ "propcache>=0.2.0", ] files = [ - {file = "yarl-1.17.1-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:cbad927ea8ed814622305d842c93412cb47bd39a496ed0f96bfd42b922b4a217"}, - {file = "yarl-1.17.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:fca4b4307ebe9c3ec77a084da3a9d1999d164693d16492ca2b64594340999988"}, - {file = "yarl-1.17.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:ff5c6771c7e3511a06555afa317879b7db8d640137ba55d6ab0d0c50425cab75"}, - {file = "yarl-1.17.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5b29beab10211a746f9846baa39275e80034e065460d99eb51e45c9a9495bcca"}, - {file = "yarl-1.17.1-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1a52a1ffdd824fb1835272e125385c32fd8b17fbdefeedcb4d543cc23b332d74"}, - {file = "yarl-1.17.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:58c8e9620eb82a189c6c40cb6b59b4e35b2ee68b1f2afa6597732a2b467d7e8f"}, - {file = "yarl-1.17.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d216e5d9b8749563c7f2c6f7a0831057ec844c68b4c11cb10fc62d4fd373c26d"}, - {file = "yarl-1.17.1-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:881764d610e3269964fc4bb3c19bb6fce55422828e152b885609ec176b41cf11"}, - {file = "yarl-1.17.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:8c79e9d7e3d8a32d4824250a9c6401194fb4c2ad9a0cec8f6a96e09a582c2cc0"}, - {file = "yarl-1.17.1-cp311-cp311-musllinux_1_2_armv7l.whl", hash = "sha256:299f11b44d8d3a588234adbe01112126010bd96d9139c3ba7b3badd9829261c3"}, - {file = "yarl-1.17.1-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:cc7d768260f4ba4ea01741c1b5fe3d3a6c70eb91c87f4c8761bbcce5181beafe"}, - {file = "yarl-1.17.1-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:de599af166970d6a61accde358ec9ded821234cbbc8c6413acfec06056b8e860"}, - {file = "yarl-1.17.1-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:2b24ec55fad43e476905eceaf14f41f6478780b870eda5d08b4d6de9a60b65b4"}, - {file = "yarl-1.17.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:9fb815155aac6bfa8d86184079652c9715c812d506b22cfa369196ef4e99d1b4"}, - {file = "yarl-1.17.1-cp311-cp311-win32.whl", hash = "sha256:7615058aabad54416ddac99ade09a5510cf77039a3b903e94e8922f25ed203d7"}, - {file = "yarl-1.17.1-cp311-cp311-win_amd64.whl", hash = "sha256:14bc88baa44e1f84164a392827b5defb4fa8e56b93fecac3d15315e7c8e5d8b3"}, + {file = "yarl-1.17.1-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:327828786da2006085a4d1feb2594de6f6d26f8af48b81eb1ae950c788d97f61"}, + {file = "yarl-1.17.1-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:cc353841428d56b683a123a813e6a686e07026d6b1c5757970a877195f880c2d"}, + {file = "yarl-1.17.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:c73df5b6e8fabe2ddb74876fb82d9dd44cbace0ca12e8861ce9155ad3c886139"}, + {file = "yarl-1.17.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0bdff5e0995522706c53078f531fb586f56de9c4c81c243865dd5c66c132c3b5"}, + {file = "yarl-1.17.1-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:06157fb3c58f2736a5e47c8fcbe1afc8b5de6fb28b14d25574af9e62150fcaac"}, + {file = "yarl-1.17.1-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:1654ec814b18be1af2c857aa9000de7a601400bd4c9ca24629b18486c2e35463"}, + {file = "yarl-1.17.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7f6595c852ca544aaeeb32d357e62c9c780eac69dcd34e40cae7b55bc4fb1147"}, + {file = "yarl-1.17.1-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:459e81c2fb920b5f5df744262d1498ec2c8081acdcfe18181da44c50f51312f7"}, + {file = "yarl-1.17.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:7e48cdb8226644e2fbd0bdb0a0f87906a3db07087f4de77a1b1b1ccfd9e93685"}, + {file = "yarl-1.17.1-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:d9b6b28a57feb51605d6ae5e61a9044a31742db557a3b851a74c13bc61de5172"}, + {file = "yarl-1.17.1-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:e594b22688d5747b06e957f1ef822060cb5cb35b493066e33ceac0cf882188b7"}, + {file = "yarl-1.17.1-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:5f236cb5999ccd23a0ab1bd219cfe0ee3e1c1b65aaf6dd3320e972f7ec3a39da"}, + {file = "yarl-1.17.1-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:a2a64e62c7a0edd07c1c917b0586655f3362d2c2d37d474db1a509efb96fea1c"}, + {file = "yarl-1.17.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:d0eea830b591dbc68e030c86a9569826145df485b2b4554874b07fea1275a199"}, + {file = "yarl-1.17.1-cp312-cp312-win32.whl", hash = "sha256:46ddf6e0b975cd680eb83318aa1d321cb2bf8d288d50f1754526230fcf59ba96"}, + {file = "yarl-1.17.1-cp312-cp312-win_amd64.whl", hash = "sha256:117ed8b3732528a1e41af3aa6d4e08483c2f0f2e3d3d7dca7cf538b3516d93df"}, {file = "yarl-1.17.1-py3-none-any.whl", hash = "sha256:f1790a4b1e8e8e028c391175433b9c8122c39b46e1663228158e61e6f915bf06"}, {file = "yarl-1.17.1.tar.gz", hash = "sha256:067a63fcfda82da6b198fa73079b1ca40b7c9b7994995b6ee38acda728b64d47"}, ] diff --git a/pyproject.toml b/pyproject.toml index b02a78e..cb106ea 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -19,19 +19,17 @@ dependencies = [ "pydantic>=2.9.2", "coloredlogs>=15.0.1", "aiofile>=3.9.0", + "sentry-sdk>=2.18.0", ] -requires-python = "==3.11.*" +requires-python = "==3.12.*" readme = "README.md" license = {text = "MIT"} -[project.optional-dependencies] -sentry = [ - "sentry-sdk>=2.15.0", -] + [tool.pdm.scripts] format = "ruff format ." lint = "ruff check --fix ." -export = "pdm export -o requirements.txt --without-hashes --prod" +export = "pdm export -o requirements.txt --prod" tests = "pytest tests" start = "python src" check-listings = {call = "scripts:check_listings.main"} @@ -54,10 +52,10 @@ dev = [ reportAny = false reportUnusedCallResult = false reportUnknownMemberType = false -pythonVersion = "3.11" +pythonVersion = "3.12" [tool.ruff] -target-version = "py311" +target-version = "py312" line-length = 120 indent-width = 4 diff --git a/requirements.txt b/requirements.txt index d41fbbc..fad9f92 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,44 +1,241 @@ # This file is @generated by PDM. # Please do not edit it manually. -aiofile==3.9.0 -aiofiles==24.1.0 -aiohappyeyeballs==2.4.3 -aiohttp==3.10.10 -aiosignal==1.3.1 -annotated-types==0.7.0 -attrs==24.2.0 -blinker==1.8.2 -caio==0.9.17 -click==8.1.7 -colorama==0.4.6; sys_platform == "win32" or platform_system == "Windows" -coloredlogs==15.0.1 -flask==3.0.3 -frozenlist==1.5.0 -h11==0.14.0 -h2==4.1.0 -hpack==4.0.0 -humanfriendly==10.0 -hypercorn==0.17.3 -hyperframe==6.0.1 -idna==3.10 -itsdangerous==2.2.0 -jinja2==3.1.4 -markupsafe==3.0.2 -multidict==6.1.0 -orjson==3.10.11 -priority==2.0.0 -propcache==0.2.0 -py-cord==2.6.1 -pydantic==2.9.2 -pydantic-core==2.23.4 -pyreadline3==3.5.4; sys_platform == "win32" and python_version >= "3.8" -python-dotenv==1.0.1 -pytz==2024.2 -pyyaml==6.0.2 -quart==0.19.8 -schema==0.7.7 -typing-extensions==4.12.2 -werkzeug==3.1.2 -wsproto==1.2.0 -yarl==1.17.1 +aiofile==3.9.0 \ + --hash=sha256:ce2f6c1571538cbdfa0143b04e16b208ecb0e9cb4148e528af8a640ed51cc8aa \ + --hash=sha256:e5ad718bb148b265b6df1b3752c4d1d83024b93da9bd599df74b9d9ffcf7919b +aiofiles==24.1.0 \ + --hash=sha256:22a075c9e5a3810f0c2e48f3008c94d68c65d763b9b03857924c99e57355166c \ + --hash=sha256:b4ec55f4195e3eb5d7abd1bf7e061763e864dd4954231fb8539a0ef8bb8260e5 +aiohappyeyeballs==2.4.3 \ + --hash=sha256:75cf88a15106a5002a8eb1dab212525c00d1f4c0fa96e551c9fbe6f09a621586 \ + --hash=sha256:8a7a83727b2756f394ab2895ea0765a0a8c475e3c71e98d43d76f22b4b435572 +aiohttp==3.10.10 \ + --hash=sha256:007ec22fbc573e5eb2fb7dec4198ef8f6bf2fe4ce20020798b2eb5d0abda6138 \ + --hash=sha256:0631dd7c9f0822cc61c88586ca76d5b5ada26538097d0f1df510b082bad3411a \ + --hash=sha256:0b00807e2605f16e1e198f33a53ce3c4523114059b0c09c337209ae55e3823a8 \ + --hash=sha256:0e1b370d8007c4ae31ee6db7f9a2fe801a42b146cec80a86766e7ad5c4a259cf \ + --hash=sha256:438cd072f75bb6612f2aca29f8bd7cdf6e35e8f160bc312e49fbecab77c99e3a \ + --hash=sha256:50edbcad60d8f0e3eccc68da67f37268b5144ecc34d59f27a02f9611c1d4eec7 \ + --hash=sha256:59bb3c54aa420521dc4ce3cc2c3fe2ad82adf7b09403fa1f48ae45c0cbde6628 \ + --hash=sha256:5c6a5b8c7926ba5d8545c7dd22961a107526562da31a7a32fa2456baf040939f \ + --hash=sha256:9294bbb581f92770e6ed5c19559e1e99255e4ca604a22c5c6397b2f9dd3ee42c \ + --hash=sha256:9627cc1a10c8c409b5822a92d57a77f383b554463d1884008e051c32ab1b3742 \ + --hash=sha256:a45d85cf20b5e0d0aa5a8dca27cce8eddef3292bc29d72dcad1641f4ed50aa16 \ + --hash=sha256:a7d8d14fe962153fc681f6366bdec33d4356f98a3e3567782aac1b6e0e40109a \ + --hash=sha256:a8fa23fe62c436ccf23ff930149c047f060c7126eae3ccea005f0483f27b2e28 \ + --hash=sha256:baa42524a82f75303f714108fea528ccacf0386af429b69fff141ffef1c534f9 \ + --hash=sha256:c1277cd707c465cd09572a774559a3cc7c7a28802eb3a2a9472588f062097205 \ + --hash=sha256:f2d4324a98062be0525d16f768a03e0bbb3b9fe301ceee99611dc9a7953124e6 +aiosignal==1.3.1 \ + --hash=sha256:54cd96e15e1649b75d6c87526a6ff0b6c1b0dd3459f43d9ca11d48c339b68cfc \ + --hash=sha256:f8376fb07dd1e86a584e4fcdec80b36b7f81aac666ebc724e2c090300dd83b17 +annotated-types==0.7.0 \ + --hash=sha256:1f02e8b43a8fbbc3f3e0d4f0f4bfc8131bcb4eebe8849b8e5c773f3a1c582a53 \ + --hash=sha256:aff07c09a53a08bc8cfccb9c85b05f1aa9a2a6f23728d790723543408344ce89 +attrs==24.2.0 \ + --hash=sha256:5cfb1b9148b5b086569baec03f20d7b6bf3bcacc9a42bebf87ffaaca362f6346 \ + --hash=sha256:81921eb96de3191c8258c199618104dd27ac608d9366f5e35d011eae1867ede2 +blinker==1.8.2 \ + --hash=sha256:1779309f71bf239144b9399d06ae925637cf6634cf6bd131104184531bf67c01 \ + --hash=sha256:8f77b09d3bf7c795e969e9486f39c2c5e9c39d4ee07424be2bc594ece9642d83 +caio==0.9.17 \ + --hash=sha256:0ddb253b145a53ecca76381677ce465bc5efeaecb6aaf493fac43ae79659f0fb \ + --hash=sha256:8f30511526814d961aeef389ea6885273abe6c655f1e08abbadb95d12fdd9b4f \ + --hash=sha256:b3e320b0ea371c810359934f8e8fe81777c493cc5fb4d41de44277cbe7336e74 \ + --hash=sha256:c55d4dc6b3a36f93237ecd6360e1c131c3808bc47d4191a130148a99b80bb311 +click==8.1.7 \ + --hash=sha256:ae74fb96c20a0277a1d615f1e4d73c8414f5a98db8b799a7931d1582f3390c28 \ + --hash=sha256:ca9853ad459e787e2192211578cc907e7594e294c7ccc834310722b41b9ca6de +colorama==0.4.6; sys_platform == "win32" or platform_system == "Windows" \ + --hash=sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44 \ + --hash=sha256:4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6 +coloredlogs==15.0.1 \ + --hash=sha256:612ee75c546f53e92e70049c9dbfcc18c935a2b9a53b66085ce9ef6a6e5c0934 \ + --hash=sha256:7c991aa71a4577af2f82600d8f8f3a89f936baeaf9b50a9c197da014e5bf16b0 +flask==3.0.3 \ + --hash=sha256:34e815dfaa43340d1d15a5c3a02b8476004037eb4840b34910c6e21679d288f3 \ + --hash=sha256:ceb27b0af3823ea2737928a4d99d125a06175b8512c445cbd9a9ce200ef76842 +frozenlist==1.5.0 \ + --hash=sha256:000a77d6034fbad9b6bb880f7ec073027908f1b40254b5d6f26210d2dab1240e \ + --hash=sha256:29d94c256679247b33a3dc96cce0f93cbc69c23bf75ff715919332fdbb6a32b8 \ + --hash=sha256:30c72000fbcc35b129cb09956836c7d7abf78ab5416595e4857d1cae8d6251a6 \ + --hash=sha256:31115ba75889723431aa9a4e77d5f398f5cf976eea3bdf61749731f62d4a4a21 \ + --hash=sha256:52ef692a4bc60a6dd57f507429636c2af8b6046db8b31b18dac02cbc8f507f7f \ + --hash=sha256:5d7f5a50342475962eb18b740f3beecc685a15b52c91f7d975257e13e029eca9 \ + --hash=sha256:683173d371daad49cffb8309779e886e59c2f369430ad28fe715f66d08d4ab1a \ + --hash=sha256:6e9080bb2fb195a046e5177f10d9d82b8a204c0736a97a153c2466127de87784 \ + --hash=sha256:7437601c4d89d070eac8323f121fcf25f88674627505334654fd027b091db09d \ + --hash=sha256:7948140d9f8ece1745be806f2bfdf390127cf1a763b925c4a805c603df5e697e \ + --hash=sha256:7d57d8f702221405a9d9b40f9da8ac2e4a1a8b5285aac6100f3393675f0a85ee \ + --hash=sha256:81d5af29e61b9c8348e876d442253723928dce6433e0e76cd925cd83f1b4b817 \ + --hash=sha256:87f724d055eb4785d9be84e9ebf0f24e392ddfad00b3fe036e43f489fafc9039 \ + --hash=sha256:8969190d709e7c48ea386db202d708eb94bdb29207a1f269bab1196ce0dcca1f \ + --hash=sha256:9b93d7aaa36c966fa42efcaf716e6b3900438632a626fb09c049f6a2f09fc631 \ + --hash=sha256:d994863bba198a4a518b467bb971c56e1db3f180a25c6cf7bb1949c267f748c3 \ + --hash=sha256:feeb64bc9bcc6b45c6311c9e9b99406660a9c05ca8a5b30d14a78555088b0b3a +h11==0.14.0 \ + --hash=sha256:8f19fbbe99e72420ff35c00b27a34cb9937e902a8b810e2c88300c6f0a3b699d \ + --hash=sha256:e3fe4ac4b851c468cc8363d500db52c2ead036020723024a109d37346efaa761 +h2==4.1.0 \ + --hash=sha256:03a46bcf682256c95b5fd9e9a99c1323584c3eec6440d379b9903d709476bc6d \ + --hash=sha256:a83aca08fbe7aacb79fec788c9c0bac936343560ed9ec18b82a13a12c28d2abb +hpack==4.0.0 \ + --hash=sha256:84a076fad3dc9a9f8063ccb8041ef100867b1878b25ef0ee63847a5d53818a6c \ + --hash=sha256:fc41de0c63e687ebffde81187a948221294896f6bdc0ae2312708df339430095 +humanfriendly==10.0 \ + --hash=sha256:1697e1a8a8f550fd43c2865cd84542fc175a61dcb779b6fee18cf6b6ccba1477 \ + --hash=sha256:6b0b831ce8f15f7300721aa49829fc4e83921a9a301cc7f606be6686a2288ddc +hypercorn==0.17.3 \ + --hash=sha256:059215dec34537f9d40a69258d323f56344805efb462959e727152b0aa504547 \ + --hash=sha256:1b37802ee3ac52d2d85270700d565787ab16cf19e1462ccfa9f089ca17574165 +hyperframe==6.0.1 \ + --hash=sha256:0ec6bafd80d8ad2195c4f03aacba3a8265e57bc4cff261e802bf39970ed02a15 \ + --hash=sha256:ae510046231dc8e9ecb1a6586f63d2347bf4c8905914aa84ba585ae85f28a914 +idna==3.10 \ + --hash=sha256:12f65c9b470abda6dc35cf8e63cc574b1c52b11df2c86030af0ac09b01b13ea9 \ + --hash=sha256:946d195a0d259cbba61165e88e65941f16e9b36ea6ddb97f00452bae8b1287d3 +itsdangerous==2.2.0 \ + --hash=sha256:c6242fc49e35958c8b15141343aa660db5fc54d4f13a1db01a3f5891b98700ef \ + --hash=sha256:e0050c0b7da1eea53ffaf149c0cfbb5c6e2e2b69c4bef22c81fa6eb73e5f6173 +jinja2==3.1.4 \ + --hash=sha256:4a3aee7acbbe7303aede8e9648d13b8bf88a429282aa6122a993f0ac800cb369 \ + --hash=sha256:bc5dd2abb727a5319567b7a813e6a2e7318c39f4f487cfe6c89c6f9c7d25197d +markupsafe==3.0.2 \ + --hash=sha256:0f4ca02bea9a23221c0182836703cbf8930c5e9454bacce27e767509fa286a30 \ + --hash=sha256:1c99d261bd2d5f6b59325c92c73df481e05e57f19837bdca8413b9eac4bd8028 \ + --hash=sha256:2181e67807fc2fa785d0592dc2d6206c019b9502410671cc905d132a92866557 \ + --hash=sha256:52305740fe773d09cffb16f8ed0427942901f00adedac82ec8b67752f58a1b22 \ + --hash=sha256:846ade7b71e3536c4e56b386c2a47adf5741d2d8b94ec9dc3e92e5e1ee1e2225 \ + --hash=sha256:88416bd1e65dcea10bc7569faacb2c20ce071dd1f87539ca2ab364bf6231393c \ + --hash=sha256:8e06879fc22a25ca47312fbe7c8264eb0b662f6db27cb2d3bbbc74b1df4b9b87 \ + --hash=sha256:9778bd8ab0a994ebf6f84c2b949e65736d5575320a17ae8984a77fab08db94cf \ + --hash=sha256:ad10d3ded218f1039f11a75f8091880239651b52e9bb592ca27de44eed242a48 \ + --hash=sha256:e17c96c14e19278594aa4841ec148115f9c7615a47382ecb6b82bd8fea3ab0c8 \ + --hash=sha256:ee55d3edf80167e48ea11a923c7386f4669df67d7994554387f84e7d8b0a2bf0 +multidict==6.1.0 \ + --hash=sha256:071120490b47aa997cca00666923a83f02c7fbb44f71cf7f136df753f7fa8761 \ + --hash=sha256:0e5f362e895bc5b9e67fe6e4ded2492d8124bdf817827f33c5b46c2fe3ffaca6 \ + --hash=sha256:10a9b09aba0c5b48c53761b7c720aaaf7cf236d5fe394cd399c7ba662d5f9966 \ + --hash=sha256:188215fc0aafb8e03341995e7c4797860181562380f81ed0a87ff455b70bf1f1 \ + --hash=sha256:1e16bf3e5fc9f44632affb159d30a437bfe286ce9e02754759be5536b169b305 \ + --hash=sha256:22ae2ebf9b0c69d206c003e2f6a914ea33f0a932d4aa16f236afc049d9958f4a \ + --hash=sha256:3ec660d19bbc671e3a6443325f07263be452c453ac9e512f5eb935e7d4ac28b3 \ + --hash=sha256:48e171e52d1c4d33888e529b999e5900356b9ae588c2f09a52dcefb158b27506 \ + --hash=sha256:4b820514bfc0b98a30e3d85462084779900347e4d49267f747ff54060cc33925 \ + --hash=sha256:50b3a2710631848991d0bf7de077502e8994c804bb805aeb2925a981de58ec2e \ + --hash=sha256:55b6d90641869892caa9ca42ff913f7ff1c5ece06474fbd32fb2cf6834726c95 \ + --hash=sha256:58130ecf8f7b8112cdb841486404f1282b9c86ccb30d3519faf301b2e5659133 \ + --hash=sha256:6180c0ae073bddeb5a97a38c03f30c233e0a4d39cd86166251617d1bbd0af436 \ + --hash=sha256:76f364861c3bfc98cbbcbd402d83454ed9e01a5224bb3a28bf70002a230f73e2 \ + --hash=sha256:820c661588bd01a0aa62a1283f20d2be4281b086f80dad9e955e690c75fb54a2 \ + --hash=sha256:b04772ed465fa3cc947db808fa306d79b43e896beb677a56fb2347ca1a49c1fa \ + --hash=sha256:b58c621844d55e71c1b7f7c498ce5aa6985d743a1a59034c57a905b3f153c1ef +orjson==3.10.11 \ + --hash=sha256:360a4e2c0943da7c21505e47cf6bd725588962ff1d739b99b14e2f7f3545ba51 \ + --hash=sha256:496e2cb45de21c369079ef2d662670a4892c81573bcc143c4205cae98282ba97 \ + --hash=sha256:51f3382415747e0dbda9dade6f1e1a01a9d37f630d8c9049a8ed0e385b7a90c0 \ + --hash=sha256:7dfa8db55c9792d53c5952900c6a919cfa377b4f4534c7a786484a6a4a350c19 \ + --hash=sha256:d4a62c49c506d4d73f59514986cadebb7e8d186ad510c518f439176cf8d5359d \ + --hash=sha256:dfbb2d460a855c9744bbc8e36f9c3a997c4b27d842f3d5559ed54326e6911f9b \ + --hash=sha256:e2f3b7c5803138e67028dde33450e054c87e0703afbe730c105f1fcd873496d5 \ + --hash=sha256:e35b6d730de6384d5b2dab5fd23f0d76fae8bbc8c353c2f78210aa5fa4beb3ef \ + --hash=sha256:f1eec3421a558ff7a9b010a6c7effcfa0ade65327a71bb9b02a1c3b77a247284 \ + --hash=sha256:f35a1b9f50a219f470e0e497ca30b285c9f34948d3c8160d5ad3a755d9299433 \ + --hash=sha256:f91d9eb554310472bd09f5347950b24442600594c2edc1421403d7610a0998fd +priority==2.0.0 \ + --hash=sha256:6f8eefce5f3ad59baf2c080a664037bb4725cd0a790d53d59ab4059288faf6aa \ + --hash=sha256:c965d54f1b8d0d0b19479db3924c7c36cf672dbf2aec92d43fbdaf4492ba18c0 +propcache==0.2.0 \ + --hash=sha256:00181262b17e517df2cd85656fcd6b4e70946fe62cd625b9d74ac9977b64d8d9 \ + --hash=sha256:1e41d67757ff4fbc8ef2af99b338bfb955010444b92929e9e55a6d4dcc3c4f09 \ + --hash=sha256:2ccc28197af5313706511fab3a8b66dcd6da067a1331372c82ea1cb74285e036 \ + --hash=sha256:2e900bad2a8456d00a113cad8c13343f3b1f327534e3589acc2219729237a2e8 \ + --hash=sha256:2ee7606193fb267be4b2e3b32714f2d58cad27217638db98a60f9efb5efeccc2 \ + --hash=sha256:3444cdba6628accf384e349014084b1cacd866fbb88433cd9d279d90a54e0b23 \ + --hash=sha256:439e76255daa0f8151d3cb325f6dd4a3e93043e6403e6491813bcaaaa8733887 \ + --hash=sha256:4a9d9b4d0a9b38d1c391bb4ad24aa65f306c6f01b512e10a8a34a2dc5675d348 \ + --hash=sha256:55346705687dbd7ef0d77883ab4f6fabc48232f587925bdaf95219bae072491e \ + --hash=sha256:56295eb1e5f3aecd516d91b00cfd8bf3a13991de5a479df9e27dd569ea23959c \ + --hash=sha256:6994984550eaf25dd7fc7bd1b700ff45c894149341725bb4edc67f0ffa94efa4 \ + --hash=sha256:69d3a98eebae99a420d4b28756c8ce6ea5a29291baf2dc9ff9414b42676f61d5 \ + --hash=sha256:91ee8fc02ca52e24bcb77b234f22afc03288e1dafbb1f88fe24db308910c4ac7 \ + --hash=sha256:a64e32f8bd94c105cc27f42d3b658902b5bcc947ece3c8fe7bc1b05982f60e89 \ + --hash=sha256:ad9c9b99b05f163109466638bd30ada1722abb01bbb85c739c50b6dc11f92dc3 \ + --hash=sha256:df81779732feb9d01e5d513fad0122efb3d53bbc75f61b2a4f29a020bc985e70 \ + --hash=sha256:f52a68c21363c45297aca15561812d542f8fc683c85201df0bebe209e349f793 \ + --hash=sha256:f6475a1b2ecb310c98c28d271a30df74f9dd436ee46d09236a6b750a7599ce57 +py-cord==2.6.1 \ + --hash=sha256:36064f225f2c7bbddfe542d5ed581f2a5744f618e039093cf7cd2659a58bc79b \ + --hash=sha256:e3d3b528c5e37b0e0825f5b884cbb9267860976c1e4878e28b55da8fd3af834b +pydantic==2.9.2 \ + --hash=sha256:d155cef71265d1e9807ed1c32b4c8deec042a44a50a4188b25ac67ecd81a9c0f \ + --hash=sha256:f048cec7b26778210e28a0459867920654d48e5e62db0958433636cde4254f12 +pydantic-core==2.23.4 \ + --hash=sha256:128585782e5bfa515c590ccee4b727fb76925dd04a98864182b22e89a4e6ed36 \ + --hash=sha256:20152074317d9bed6b7a95ade3b7d6054845d70584216160860425f4fbd5ee9e \ + --hash=sha256:2584f7cf844ac4d970fba483a717dbe10c1c1c96a969bf65d61ffe94df1b2863 \ + --hash=sha256:33e3d65a85a2a4a0dc3b092b938a4062b1a05f3a9abde65ea93b233bca0e03f2 \ + --hash=sha256:4ba762ed58e8d68657fc1281e9bb72e1c3e79cc5d464be146e260c541ec12d84 \ + --hash=sha256:68665f4c17edcceecc112dfed5dbe6f92261fb9d6054b47d01bf6371a6196126 \ + --hash=sha256:723314c1d51722ab28bfcd5240d858512ffd3116449c557a1336cbe3919beb87 \ + --hash=sha256:9261d3ce84fa1d38ed649c3638feefeae23d32ba9182963e465d58d62203bd24 \ + --hash=sha256:97df63000f4fea395b2824da80e169731088656d1818a11b95f3b173747b6cd9 \ + --hash=sha256:bb2802e667b7051a1bebbfe93684841cc9351004e2badbd6411bf357ab8d5ac8 \ + --hash=sha256:d18ca8148bebe1b0a382a27a8ee60350091a6ddaf475fa05ef50dc35b5df6327 \ + --hash=sha256:f3e0da4ebaef65158d4dfd7d3678aad692f7666877df0002b8a522cdf088f231 \ + --hash=sha256:f69a8e0b033b747bb3e36a44e7732f0c99f7edd5cea723d45bc0d6e95377ffee +pyreadline3==3.5.4; sys_platform == "win32" and python_version >= "3.8" \ + --hash=sha256:8d57d53039a1c75adba8e50dd3d992b28143480816187ea5efbd5c78e6c885b7 \ + --hash=sha256:eaf8e6cc3c49bcccf145fc6067ba8643d1df34d604a1ec0eccbf7a18e6d3fae6 +python-dotenv==1.0.1 \ + --hash=sha256:e324ee90a023d808f1959c46bcbc04446a10ced277783dc6ee09987c37ec10ca \ + --hash=sha256:f7b63ef50f1b690dddf550d03497b66d609393b40b564ed0d674909a68ebf16a +pytz==2024.2 \ + --hash=sha256:2aa355083c50a0f93fa581709deac0c9ad65cca8a9e9beac660adcbd493c798a \ + --hash=sha256:31c7c1817eb7fae7ca4b8c7ee50c72f93aa2dd863de768e1ef4245d426aa0725 +pyyaml==6.0.2 \ + --hash=sha256:0833f8694549e586547b576dcfaba4a6b55b9e96098b36cdc7ebefe667dfed48 \ + --hash=sha256:1f71ea527786de97d1a0cc0eacd1defc0985dcf6b3f17bb77dcfc8c34bec4dc5 \ + --hash=sha256:7e7401d0de89a9a855c839bc697c079a4af81cf878373abd7dc625847d25cbd8 \ + --hash=sha256:80bab7bfc629882493af4aa31a4cfa43a4c57c83813253626916b8c7ada83476 \ + --hash=sha256:8b9c7197f7cb2738065c481a0461e50ad02f18c78cd75775628afb4d7137fb3b \ + --hash=sha256:9b22676e8097e9e22e36d6b7bda33190d0d400f345f23d4065d48f4ca7ae0425 \ + --hash=sha256:c70c95198c015b85feafc136515252a261a84561b7b1d51e3384e0655ddf25ab \ + --hash=sha256:ce826d6ef20b1bc864f0a68340c8b3287705cae2f8b4b1d932177dcc76721725 \ + --hash=sha256:d584d9ec91ad65861cc08d42e834324ef890a082e591037abe114850ff7bbc3e \ + --hash=sha256:ef6107725bd54b262d6dedcc2af448a266975032bc85ef0172c5f059da6325b4 +quart==0.19.8 \ + --hash=sha256:34eeb559014f4e72e093d034cfe203b1a6262e9d3504f826f293090e230609f2 \ + --hash=sha256:ef567d0be7677c99890d5c6ff30e679699fe7e5fca1a90fa3b6974edd8421794 +schema==0.7.7 \ + --hash=sha256:5d976a5b50f36e74e2157b47097b60002bd4d42e65425fcc9c9befadb4255dde \ + --hash=sha256:7da553abd2958a19dc2547c388cde53398b39196175a9be59ea1caf5ab0a1807 +typing-extensions==4.12.2 \ + --hash=sha256:04e5ca0351e0f3f85c6853954072df659d0d13fac324d0072316b67d7794700d \ + --hash=sha256:1a7ead55c7e559dd4dee8856e3a88b41225abfe1ce8df57b7c13915fe121ffb8 +werkzeug==3.1.2 \ + --hash=sha256:4f7d1a5de312c810a8a2c6f0b47e9f6a7cffb7c8322def35e4d4d9841ff85597 \ + --hash=sha256:f471a4cd167233077e9d2a8190c3471c5bc520c636a9e3c1e9300c33bced03bc +wsproto==1.2.0 \ + --hash=sha256:ad565f26ecb92588a3e43bc3d96164de84cd9902482b130d0ddbaa9664a85065 \ + --hash=sha256:b9acddd652b585d75b20477888c56642fdade28bdfd3579aa24a4d2c037dd736 +yarl==1.17.1 \ + --hash=sha256:06157fb3c58f2736a5e47c8fcbe1afc8b5de6fb28b14d25574af9e62150fcaac \ + --hash=sha256:067a63fcfda82da6b198fa73079b1ca40b7c9b7994995b6ee38acda728b64d47 \ + --hash=sha256:0bdff5e0995522706c53078f531fb586f56de9c4c81c243865dd5c66c132c3b5 \ + --hash=sha256:117ed8b3732528a1e41af3aa6d4e08483c2f0f2e3d3d7dca7cf538b3516d93df \ + --hash=sha256:1654ec814b18be1af2c857aa9000de7a601400bd4c9ca24629b18486c2e35463 \ + --hash=sha256:327828786da2006085a4d1feb2594de6f6d26f8af48b81eb1ae950c788d97f61 \ + --hash=sha256:459e81c2fb920b5f5df744262d1498ec2c8081acdcfe18181da44c50f51312f7 \ + --hash=sha256:46ddf6e0b975cd680eb83318aa1d321cb2bf8d288d50f1754526230fcf59ba96 \ + --hash=sha256:5f236cb5999ccd23a0ab1bd219cfe0ee3e1c1b65aaf6dd3320e972f7ec3a39da \ + --hash=sha256:7e48cdb8226644e2fbd0bdb0a0f87906a3db07087f4de77a1b1b1ccfd9e93685 \ + --hash=sha256:7f6595c852ca544aaeeb32d357e62c9c780eac69dcd34e40cae7b55bc4fb1147 \ + --hash=sha256:a2a64e62c7a0edd07c1c917b0586655f3362d2c2d37d474db1a509efb96fea1c \ + --hash=sha256:c73df5b6e8fabe2ddb74876fb82d9dd44cbace0ca12e8861ce9155ad3c886139 \ + --hash=sha256:cc353841428d56b683a123a813e6a686e07026d6b1c5757970a877195f880c2d \ + --hash=sha256:d0eea830b591dbc68e030c86a9569826145df485b2b4554874b07fea1275a199 \ + --hash=sha256:d9b6b28a57feb51605d6ae5e61a9044a31742db557a3b851a74c13bc61de5172 \ + --hash=sha256:e594b22688d5747b06e957f1ef822060cb5cb35b493066e33ceac0cf882188b7 \ + --hash=sha256:f1790a4b1e8e8e028c391175433b9c8122c39b46e1663228158e61e6f915bf06 From cd35c16d6bccd1569641d57d9b8f8f9f1ce592fb Mon Sep 17 00:00:00 2001 From: Paillat Date: Sat, 9 Nov 2024 21:10:06 +0100 Subject: [PATCH 08/61] :art: Format code and add pre-commit --- .pre-commit-config.yaml | 31 +++ guides/getting-started.md | 130 +++++++------ pyproject.toml | 5 +- readme.md | 259 ++++++++++++++++++-------- renovate.json | 27 +-- src/custom/__init__.py | 23 ++- src/extensions/add-dm/readme.md | 31 ++- src/extensions/branding/readme.md | 27 ++- src/extensions/listings/main.py | 15 +- src/extensions/listings/readme.md | 26 ++- src/extensions/nice-errors/handler.py | 11 +- src/extensions/nice-errors/patch.py | 3 +- src/extensions/nice-errors/readme.md | 31 ++- src/extensions/ping/readme.md | 24 ++- src/extensions/status-post/readme.md | 16 +- src/i18n/classes.py | 3 +- tests/__init__.py | 1 - 17 files changed, 433 insertions(+), 230 deletions(-) create mode 100644 .pre-commit-config.yaml diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml new file mode 100644 index 0000000..b9e55be --- /dev/null +++ b/.pre-commit-config.yaml @@ -0,0 +1,31 @@ +ci: + autoupdate_commit_msg: "chore(pre-commit): pre-commit autoupdate" + autofix_commit_msg: "style(pre-commit): auto fixes from pre-commit.com hooks" + +repos: + - repo: https://github.com/pre-commit/pre-commit-hooks + rev: v5.0.0 + hooks: + - id: trailing-whitespace + exclude: \.(po|pot|yml|yaml)$ + - id: end-of-file-fixer + exclude: \.(po|pot|yml|yaml)$ + - repo: https://github.com/pre-commit/mirrors-prettier + rev: v4.0.0-alpha.8 + hooks: + - id: prettier + args: [--prose-wrap=always, --print-width=88] + exclude: \.(po|pot|yml|yaml)$ + - repo: https://github.com/astral-sh/ruff-pre-commit + # Ruff version. + rev: v0.7.3 + hooks: + # Run the linter. + - id: ruff + args: [ --fix ] + # Run the formatter. + - id: ruff-format + - repo: https://github.com/DetachHead/basedpyright-pre-commit-mirror + rev: v1.13.0 # or whatever the latest version is at the time + hooks: + - id: basedpyright diff --git a/guides/getting-started.md b/guides/getting-started.md index 58827e2..45d108f 100644 --- a/guides/getting-started.md +++ b/guides/getting-started.md @@ -1,6 +1,8 @@ # Getting Started with Botkit and Pycord: Creating Your First Bot Extension -This comprehensive tutorial will guide you through the process of setting up Botkit, creating your first bot extension using Pycord, and understanding the core concepts of Discord bot development. +This comprehensive tutorial will guide you through the process of setting up Botkit, +creating your first bot extension using Pycord, and understanding the core concepts of +Discord bot development. ## Prerequisites @@ -10,18 +12,21 @@ Before we begin, ensure you have the following: 2. Basic understanding of Python and Discord concepts 3. A Discord account and access to the Discord Developer Portal -> [!IMPORTANT] -> If you haven't already, create a Discord application and bot user in the [Discord Developer Portal](https://discord.com/developers/applications). You'll need the bot token for later steps. +> [!IMPORTANT] If you haven't already, create a Discord application and bot user in the +> [Discord Developer Portal](https://discord.com/developers/applications). You'll need +> the bot token for later steps. ## Step 1: Install Git -If you don't have Git installed, you'll need to install it to clone the Botkit repository. +If you don't have Git installed, you'll need to install it to clone the Botkit +repository. -1. Visit the [Git website](https://git-scm.com/downloads) and download the appropriate version for your operating system. +1. Visit the [Git website](https://git-scm.com/downloads) and download the appropriate + version for your operating system. 2. Follow the installation instructions for your OS. -> [!TIP] -> On Windows, you can use the Git Bash terminal that comes with Git for a Unix-like command-line experience. +> [!TIP] On Windows, you can use the Git Bash terminal that comes with Git for a +> Unix-like command-line experience. To verify Git is installed correctly, open a terminal or command prompt and run: @@ -49,12 +54,13 @@ git clone https://github.com/nicebots-xyz/botkit cd botkit ``` -> [!NOTE] -> Cloning the repository creates a local copy of Botkit on your machine, allowing you to build your bot using the Botkit framework. +> [!NOTE] Cloning the repository creates a local copy of Botkit on your machine, +> allowing you to build your bot using the Botkit framework. ## Step 3: Set Up a Virtual Environment (Optional but Recommended) -It's a good practice to use a virtual environment for your Python projects. This keeps your project dependencies isolated from your system-wide Python installation. +It's a good practice to use a virtual environment for your Python projects. This keeps +your project dependencies isolated from your system-wide Python installation. 1. Create a virtual environment: @@ -63,17 +69,17 @@ python -m venv venv ``` 2. Activate the virtual environment: - - On Windows: - ``` - venv\Scripts\activate - ``` - - On macOS and Linux: - ``` - source venv/bin/activate - ``` - -> [!TIP] -> You'll know the virtual environment is active when you see `(venv)` at the beginning of your terminal prompt. + - On Windows: + ``` + venv\Scripts\activate + ``` + - On macOS and Linux: + ``` + source venv/bin/activate + ``` + +> [!TIP] You'll know the virtual environment is active when you see `(venv)` at the +> beginning of your terminal prompt. ## Step 4: Install Dependencies @@ -91,8 +97,8 @@ pip install pdm pdm install ``` -> [!NOTE] -> PDM will read the `pyproject.toml` file and install all necessary dependencies for Botkit. +> [!NOTE] PDM will read the `pyproject.toml` file and install all necessary dependencies +> for Botkit. ## Step 5: Configure Your Bot @@ -106,8 +112,8 @@ bot: Replace `YOUR_BOT_TOKEN_HERE` with the actual token of your Discord bot. -> [!CAUTION] -> Never share your bot token publicly or commit it to version control. Treat it like a password. +> [!CAUTION] Never share your bot token publicly or commit it to version control. Treat +> it like a password. ## Step 6: Create a New Extension Folder @@ -138,8 +144,9 @@ from .main import setup, default, schema __all__ = ["setup", "default", "schema"] ``` -> [!NOTE] -> This file imports and exposes the necessary components from our `main.py` file (which we'll create next). It allows Botkit to access these components when loading the extension. +> [!NOTE] This file imports and exposes the necessary components from our `main.py` file +> (which we'll create next). It allows Botkit to access these components when loading +> the extension. ## Step 8: Create the `main.py` File @@ -177,17 +184,20 @@ schema = { Let's break down what we've done here: - We import the necessary modules from discord and discord.ext. -- We use `typing` to add type hints, which improves code readability and helps catch errors early. -- We define a `MyFirstExtension` class that inherits from `commands.Cog`. This class will contain our commands and listeners. +- We use `typing` to add type hints, which improves code readability and helps catch + errors early. +- We define a `MyFirstExtension` class that inherits from `commands.Cog`. This class + will contain our commands and listeners. - The `setup` function is required by Botkit to add our cog to the bot. - We define `default` and `schema` dictionaries for the extension's configuration. -> [!TIP] -> Using type hints (like `bot: discord.Bot`) helps catch errors early and improves code readability. It's a good practice to use them consistently in your code. +> [!TIP] Using type hints (like `bot: discord.Bot`) helps catch errors early and +> improves code readability. It's a good practice to use them consistently in your code. ## Step 9: Adding Commands -Now, let's add some commands to our extension. We'll create a simple "hello" command and a more complex "userinfo" command. +Now, let's add some commands to our extension. We'll create a simple "hello" command and +a more complex "userinfo" command. Add the following methods to your `MyFirstExtension` class in `main.py`: @@ -215,22 +225,27 @@ async def userinfo( Let's explain these commands: 1. The `hello` command: - - Uses the `@discord.slash_command` decorator to create a slash command. - - Takes only the `ctx` (context) parameter, which is automatically provided by Discord. - - Responds with a greeting using the author's name. + + - Uses the `@discord.slash_command` decorator to create a slash command. + - Takes only the `ctx` (context) parameter, which is automatically provided by + Discord. + - Responds with a greeting using the author's name. 2. The `userinfo` command: - - Also uses `@discord.slash_command` to create a slash command. - - Takes an optional `user` parameter, which defaults to the command author if not provided. - - Creates an embed with various pieces of information about the user. - - Responds with the created embed. + - Also uses `@discord.slash_command` to create a slash command. + - Takes an optional `user` parameter, which defaults to the command author if not + provided. + - Creates an embed with various pieces of information about the user. + - Responds with the created embed. -> [!NOTE] -> Slash commands are the modern way to create Discord bot commands. They provide better user experience and are easier to discover than traditional prefix-based commands. +> [!NOTE] Slash commands are the modern way to create Discord bot commands. They provide +> better user experience and are easier to discover than traditional prefix-based +> commands. ## Step 10: Adding an Event Listener -Let's add an event listener to our extension to demonstrate how to respond to Discord events. We'll add a simple listener that logs when the bot is ready. +Let's add an event listener to our extension to demonstrate how to respond to Discord +events. We'll add a simple listener that logs when the bot is ready. Add the following method to your `MyFirstExtension` class in `main.py`: @@ -240,10 +255,11 @@ async def on_ready(self): print(f"Bot is ready! Logged in as {self.bot.user}") ``` -This listener will print a message to the console when the bot has successfully connected to Discord. +This listener will print a message to the console when the bot has successfully +connected to Discord. -> [!TIP] -> Event listeners are great for performing actions based on Discord events, such as when a member joins a server or when a message is deleted. +> [!TIP] Event listeners are great for performing actions based on Discord events, such +> as when a member joins a server or when a message is deleted. ## Step 11: Final `main.py` File @@ -304,25 +320,29 @@ Now that we've created our extension, let's run the bot: pdm run start ``` -> [!IMPORTANT] -> Ensure your bot token is correctly set in the `config.yml` file before running the bot. +> [!IMPORTANT] Ensure your bot token is correctly set in the `config.yml` file before +> running the bot. -If everything is set up correctly, you should see the "Bot is ready!" message in your console, indicating that your bot is now online and ready to respond to commands. +If everything is set up correctly, you should see the "Bot is ready!" message in your +console, indicating that your bot is now online and ready to respond to commands. ## Conclusion -Congratulations! You've now created your first bot extension using Botkit and Pycord. This extension includes: +Congratulations! You've now created your first bot extension using Botkit and Pycord. +This extension includes: 1. A simple "hello" slash command 2. A more complex "userinfo" slash command that creates an embed 3. An event listener for the "on_ready" event -> [!TIP] -> To continue improving your bot, consider adding more commands, implementing additional event listeners, or integrating with external APIs or databases. +> [!TIP] To continue improving your bot, consider adding more commands, implementing +> additional event listeners, or integrating with external APIs or databases. -> [!WARNING] -> Always be cautious when handling user data and permissions in your bot. Ensure you're following Discord's Terms of Service and Developer Policy. +> [!WARNING] Always be cautious when handling user data and permissions in your bot. +> Ensure you're following Discord's Terms of Service and Developer Policy. -Remember to always use type hinting in your code. It helps with code readability, catches potential errors early, and provides better autocomplete suggestions in many IDEs. +Remember to always use type hinting in your code. It helps with code readability, +catches potential errors early, and provides better autocomplete suggestions in many +IDEs. -Happy coding, and enjoy building your Discord bot! \ No newline at end of file +Happy coding, and enjoy building your Discord bot! diff --git a/pyproject.toml b/pyproject.toml index cb106ea..277abf9 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -49,9 +49,12 @@ dev = [ ] [tool.pyright] +venvPath = "." +venv = ".venv" reportAny = false reportUnusedCallResult = false reportUnknownMemberType = false +reportMissingTypeStubs = false pythonVersion = "3.12" [tool.ruff] @@ -98,4 +101,4 @@ extend-ignore = [ "D203", "FBT001", "FBT002" -] \ No newline at end of file +] diff --git a/readme.md b/readme.md index 4ba6541..aee888e 100644 --- a/readme.md +++ b/readme.md @@ -2,36 +2,59 @@ ## What is Botkit? -Botkit is a comprehensive framework designed for developing feature-rich, production-ready Discord bots. It goes beyond basic bot creation by offering a suite of advanced tools and integrations that empower developers to build sophisticated, scalable, and maintainable bots. +Botkit is a comprehensive framework designed for developing feature-rich, +production-ready Discord bots. It goes beyond basic bot creation by offering a suite of +advanced tools and integrations that empower developers to build sophisticated, +scalable, and maintainable bots. Key features include: -- **Robust Internationalization (i18n)**: Built-in support for multi-language bots, allowing seamless localization across diverse Discord communities. -- **Bot Listing Integration**: Streamlined processes for managing your bot's presence on popular bot listing websites, enhancing discoverability. -- **Advanced Error Handling**: Sentry-compatible error tracking, enabling real-time monitoring and debugging of your bot in production environments. (Sentry is an application monitoring platform that helps developers identify and fix crashes in real time.) -- **Uptime Status Posting**: Automated systems for reporting your bot's operational status, crucial for maintaining user trust and meeting service level agreements. -- **Modular Architecture**: A flexible, extension-based structure that facilitates easy feature addition and management. - -While Botkit provides a rich set of advanced features, it maintains a balance between functionality and efficiency, offering a powerful yet not overly cumbersome development experience. +- **Robust Internationalization (i18n)**: Built-in support for multi-language bots, + allowing seamless localization across diverse Discord communities. +- **Bot Listing Integration**: Streamlined processes for managing your bot's presence on + popular bot listing websites, enhancing discoverability. +- **Advanced Error Handling**: Sentry-compatible error tracking, enabling real-time + monitoring and debugging of your bot in production environments. (Sentry is an + application monitoring platform that helps developers identify and fix crashes in real + time.) +- **Uptime Status Posting**: Automated systems for reporting your bot's operational + status, crucial for maintaining user trust and meeting service level agreements. +- **Modular Architecture**: A flexible, extension-based structure that facilitates easy + feature addition and management. + +While Botkit provides a rich set of advanced features, it maintains a balance between +functionality and efficiency, offering a powerful yet not overly cumbersome development +experience. ## What Botkit is NOT -Botkit is not a pre-built, out-of-the-box Discord bot solution. It's a sophisticated framework and starting point for developers looking to create advanced, custom Discord bots. Botkit is designed for those who need more than basic functionality and are ready to leverage its powerful features to create truly unique and capable bots. +Botkit is not a pre-built, out-of-the-box Discord bot solution. It's a sophisticated +framework and starting point for developers looking to create advanced, custom Discord +bots. Botkit is designed for those who need more than basic functionality and are ready +to leverage its powerful features to create truly unique and capable bots. ## Features -- **Modular Design**: The bot is designed with a modular architecture, allowing you to easily enable or disable specific extensions or features. -- **Extensible**: The bot is built around the extensions located in the `src/extensions` directory. There you can find useful and example extensions to get you started. -- **Configurable**: The bot's configuration, including enabled extensions and bot token, is managed through a `config.yml` file. -- **Easy Setup**: Botkit simplifies the setup process by providing a well-structured project template and configuration management. -- **Integrated Backend**: Botkit provides an easy way of having a Quart (flask-like) webserver running alongside your bot, with the ability to add routes and endpoints. -- **Useful Scripts**: Botkit includes useful scripts for managing your bot's listing on top.gg and other bot lists, such as discord's app directory. +- **Modular Design**: The bot is designed with a modular architecture, allowing you to + easily enable or disable specific extensions or features. +- **Extensible**: The bot is built around the extensions located in the `src/extensions` + directory. There you can find useful and example extensions to get you started. +- **Configurable**: The bot's configuration, including enabled extensions and bot token, + is managed through a `config.yml` file. +- **Easy Setup**: Botkit simplifies the setup process by providing a well-structured + project template and configuration management. +- **Integrated Backend**: Botkit provides an easy way of having a Quart (flask-like) + webserver running alongside your bot, with the ability to add routes and endpoints. +- **Useful Scripts**: Botkit includes useful scripts for managing your bot's listing on + top.gg and other bot lists, such as discord's app directory. ## Requirements -- [pdm](https://pdm-project.org/en/latest/) - A modern Python packaging and dependency management tool. +- [pdm](https://pdm-project.org/en/latest/) - A modern Python packaging and dependency + management tool. - Python 3.11 -- A Discord bot. You can create a new bot and get a token from the [Discord Developer Portal](https://discord.com/developers/applications). +- A Discord bot. You can create a new bot and get a token from the + [Discord Developer Portal](https://discord.com/developers/applications). ## Installation @@ -43,19 +66,27 @@ pdm install ``` ## Getting Started -When creating your own features, you’re supposed to create a new extension in the `src/extensions` directory for each feature you want to add. -To get started, you can follow the guide available [here](guides/getting-started.md). + +When creating your own features, you’re supposed to create a new extension in the +`src/extensions` directory for each feature you want to add. To get started, you can +follow the guide available [here](guides/getting-started.md). + ## Setup ### Automatic Extensions Configuration -Every extension in the `src/extensions` directory will automatically be loaded, -and if its default config is set to `enabled: true`, it will be enabled by default. -This allows you to add an extension that you found online simply by adding the file to the `src/extensions` directory. -The settings are automatically added to the `config.yml` file if you didn't provide them, after running the bot. + +Every extension in the `src/extensions` directory will automatically be loaded, and if +its default config is set to `enabled: true`, it will be enabled by default. This allows +you to add an extension that you found online simply by adding the file to the +`src/extensions` directory. The settings are automatically added to the `config.yml` +file if you didn't provide them, after running the bot. ### Yaml Configuration -You can set up the `config.yml` file with your bot token and desired extensions. There, or trough environment variables, you can enable or disable extensions, set up the bot token, and configure other options. -You’re required to at least provide the bot token. Here's an example configuration: + +You can set up the `config.yml` file with your bot token and desired extensions. There, +or trough environment variables, you can enable or disable extensions, set up the bot +token, and configure other options. You’re required to at least provide the bot token. +Here's an example configuration: ```yaml extensions: @@ -71,7 +102,12 @@ logging: ``` ### Environment Variables -Alternatively, you can set the bot token and other configuration options using environment variables. You can set any variable as you would in the `config.yml` file, but with the `BOTKIT__` prefix, and `__` to separate nested keys. To set lists, use regular json syntax. + +Alternatively, you can set the bot token and other configuration options using +environment variables. You can set any variable as you would in the `config.yml` file, +but with the `BOTKIT__` prefix, and `__` to separate nested keys. To set lists, use +regular json syntax. + ```env BOTKIT__bot__token=your_bot_token BOTKIT__extensions__listings__enabled=false @@ -82,35 +118,56 @@ BOTKIT__logging__level=INFO ## Creating Extensions -Extensions are in truth just python located in the `src/extensions` directory. -When creating an extension, it is crucial to follow the following guidelines: +Extensions are in truth just python located in the `src/extensions` directory. When +creating an extension, it is crucial to follow the following guidelines: + - You should keep only one feature per extension. - Creating multiple files and submodules is allowed. - Use the provided `logger` (`from src.logging import logger`) for logging messages. - - You have five log levels available: `DEBUG`, `INFO`, `WARNING`, `ERROR`, and `CRITICAL`, use them accordingly. + - You have five log levels available: `DEBUG`, `INFO`, `WARNING`, `ERROR`, and + `CRITICAL`, use them accordingly. -Moreover, each extension is required to export different objects and functions to work properly. These are: -- `setup`: A function that sets up the extension. It CAN accept any of the following arguments, in the order you prefer, and you can safely omit any of them if you don't need them: - - `bot`: The Discord bot instance. - - `config`: The configuration dictionary for the extension. All config keys will always be lowercased for compatibility with environment variables. +Moreover, each extension is required to export different objects and functions to work +properly. These are: +- `setup`: A function that sets up the extension. It CAN accept any of the following + arguments, in the order you prefer, and you can safely omit any of them if you don't + need them: -- `setup_webserver`: A function for adding webserver routes. It CAN accept any of the following arguments, in the order you prefer, and you can safely omit any of them if you don't need them: + - `bot`: The Discord bot instance. + - `config`: The configuration dictionary for the extension. All config keys will + always be lowercased for compatibility with environment variables. + +- `setup_webserver`: A function for adding webserver routes. It CAN accept any of the + following arguments, in the order you prefer, and you can safely omit any of them if + you don't need them: - `app`: The Quart app instance. - `bot`: The Discord bot instance. - `config`: The configuration dictionary for the extension. -> [!NOTE] -> Either `setup` or `setup_webserver` is required for the extension to work properly. You can also provide both. +> [!NOTE] Either `setup` or `setup_webserver` is required for the extension to work +> properly. You can also provide both. + +- `on_startup` (optional): An asynchronous function that is called when the bot starts. + It CAN accept any of the following arguments, in the order you prefer, and you can + safely omit any of them if you don't need them: -- `on_startup` (optional): An asynchronous function that is called when the bot starts. It CAN accept any of the following arguments, in the order you prefer, and you can safely omit any of them if you don't need them: - `app`: The Quart app instance. - - `bot`: The Discord bot instance. :warning: The bot is not yet logged in, so you won't be able to send messages or interact with the Discord API. + - `bot`: The Discord bot instance. :warning: The bot is not yet logged in, so you + won't be able to send messages or interact with the Discord API. - `config`: The configuration dictionary for the extension. +- `default`: A dictionary containing the default configuration for the extension. This + is used to populate the `config.yml` file with the default values if they aren’t + already present. It is required to have AT MINIMAL the `enabled` key set to `False` or + `True` (you generally want to prefer `True` for a more intuitive experience to new + users, but it is not required, especially if you code just for yourself). +- `schema`: A dictionary (or a `schema.Schema`, if you want more granular control) + containing the schema for the extension's configuration. This is used to validate the + configuration in the `config.yml` file. The schema should be a dictionary where the + keys are the configuration keys, and the values are the types of the values. For + example: -- `default`: A dictionary containing the default configuration for the extension. This is used to populate the `config.yml` file with the default values if they aren’t already present. It is required to have AT MINIMAL the `enabled` key set to `False` or `True` (you generally want to prefer `True` for a more intuitive experience to new users, but it is not required, especially if you code just for yourself). -- `schema`: A dictionary (or a `schema.Schema`, if you want more granular control) containing the schema for the extension's configuration. This is used to validate the configuration in the `config.yml` file. The schema should be a dictionary where the keys are the configuration keys, and the values are the types of the values. For example: ```python schema = { "enabled": bool, @@ -122,15 +179,20 @@ schema = { "options": dict, } ``` -We really encourage you to follow these instructions, even if you’re coding privately, as it will make your code more readable and maintainable in the long run. + +We really encourage you to follow these instructions, even if you’re coding privately, +as it will make your code more readable and maintainable in the long run. ## Internationalization (i18n) -Botkit provides robust support for internationalization, allowing you to create multi-language Discord bots with ease. Here's how to implement and use translations in your extensions: +Botkit provides robust support for internationalization, allowing you to create +multi-language Discord bots with ease. Here's how to implement and use translations in +your extensions: ### Translation File Structure -Each extension can have its own `translations.yml` file located at `src/extensions/EXT_NAME/translations.yml`. This file follows a specific structure: +Each extension can have its own `translations.yml` file located at +`src/extensions/EXT_NAME/translations.yml`. This file follows a specific structure: ```yaml commands: @@ -166,12 +228,14 @@ strings: # ... other general strings ``` -> [!NOTE] -> The top-level `strings` section (outside of `commands`) is what gets mapped to `config["translations"]`. This section is for general strings not directly tied to specific commands. +> [!NOTE] The top-level `strings` section (outside of `commands`) is what gets mapped to +> `config["translations"]`. This section is for general strings not directly tied to +> specific commands. ### Nested Commands and Sub-commands -For command groups and sub-commands, you can nest the structure using the `commands` key: +For command groups and sub-commands, you can nest the structure using the `commands` +key: ```yaml commands: @@ -197,7 +261,8 @@ This structure can be nested further for sub-sub-commands if needed. ### Accessing Translations in Code -1. For slash commands, options, and their descriptions, Botkit automatically applies the correct translations based on the guild's preferred locale. +1. For slash commands, options, and their descriptions, Botkit automatically applies the + correct translations based on the guild's preferred locale. 2. For other strings, you can access translations using the `apply_locale` function: @@ -222,31 +287,39 @@ async def ping(self, ctx: custom.ApplicationContext): response = ctx.translations.response.format(latency=round(self.bot.latency * 1000)) await ctx.respond(response) ``` -> [!NOTE] -> The translations available under `ctx.translations` are the ones set under `strings` in the command's translation. + +> [!NOTE] The translations available under `ctx.translations` are the ones set under +> `strings` in the command's translation. ### Best Practices - Provide translations for all supported languages in your `translations.yml` file. - Use meaningful keys for your strings to make the code more readable. -- Consider using placeholders (e.g., `{latency}`) in your translated strings for dynamic content. +- Consider using placeholders (e.g., `{latency}`) in your translated strings for dynamic + content. - Always provide at least an English (en-US) translation as a fallback. -By following these guidelines, you can create a bot that seamlessly adapts to different languages, providing a localized experience for users across various Discord servers. +By following these guidelines, you can create a bot that seamlessly adapts to different +languages, providing a localized experience for users across various Discord servers. ## Using Patch Files -Botkit supports the use of patch files to modify or extend the functionality of the bot or its dependencies before the main extension code runs. This is particularly useful for applying global changes or monkey-patching existing classes. +Botkit supports the use of patch files to modify or extend the functionality of the bot +or its dependencies before the main extension code runs. This is particularly useful for +applying global changes or monkey-patching existing classes. ### How It Works 1. Create a file named `patch.py` in your extension's directory. -2. Define a `patch()` function in this file. This function will be called before the extension is loaded. -3. The `patch()` function can modify global state, patch classes, or perform any other setup needed. +2. Define a `patch()` function in this file. This function will be called before the + extension is loaded. +3. The `patch()` function can modify global state, patch classes, or perform any other + setup needed. ### Example: Error Handling Patch -Here's an example from the `nice-errors` extension that demonstrates how to use a patch file to enhance error handling: +Here's an example from the `nice-errors` extension that demonstrates how to use a patch +file to enhance error handling: ```python # nice-errors/patch.py @@ -271,7 +344,9 @@ def patch(): ``` -This patch modifies the `discord.ui.View` class to provide more user-friendly error messages. It catches exceptions and responds to the user with an appropriate message, enhancing the overall user experience. +This patch modifies the `discord.ui.View` class to provide more user-friendly error +messages. It catches exceptions and responds to the user with an appropriate message, +enhancing the overall user experience. ### When to Use Patch Files @@ -281,18 +356,24 @@ Patch files are powerful but should be used judiciously. They are best suited fo 2. Modifying third-party libraries when you can't or don't want to fork them. 3. Implementing cross-cutting concerns like logging or error handling. -Remember that patches are applied early in the bot's lifecycle, so they can affect all subsequent code. Use them carefully and document their effects clearly. +Remember that patches are applied early in the bot's lifecycle, so they can affect all +subsequent code. Use them carefully and document their effects clearly. ## Using scripts ### `check-listings` -This script checks the publishing status of your bot on various bot listing websites, as well as if its description is up-to-date with one provided. -To use it: + +This script checks the publishing status of your bot on various bot listing websites, as +well as if its description is up-to-date with one provided. To use it: 0. Have Google Chrome installed. This is required web scraping. 1. Install the development dependencies using `pdm install -d`. -2. Create a file called `description.md` in the root directory of the project, containing your bot's description. -3. Create a file called `listings.yml` in the root directory of the project, containing your bot's application id and url for *some* listing websites, if you want to check them. Here's an example: +2. Create a file called `description.md` in the root directory of the project, + containing your bot's description. +3. Create a file called `listings.yml` in the root directory of the project, containing + your bot's application id and url for _some_ listing websites, if you want to check + them. Here's an example: + ```yaml application_id: 1234567891011121314 @@ -305,23 +386,35 @@ DisforgeCom: # add this section if you want to check disforge.com DiscordMe: # add this section if you want to check discord.me url: https://discord.me/my-bot` ``` + 4. Run the script using `pdm run check-listings`. ## Provided Extensions -We provide multiple extensions directly within this project to get you started. These are: - -- [`ping`](src/extensions/ping/readme.md): A simple ping command and an http endpoint to test whether the bot is online. -- [`listings`](src/extensions/listings/readme.md): An extension to post server count to various bot listing websites. -- [`branding`](src/extensions/branding/readme.md): An extension to customize the bot's presence and status, and embed aesthetics. -- [`add-dm`](src/extensions/add-dm/readme.md): An extension to send a direct message to the user who adds the bot to a guild. -- [`nice-errors`](src/extensions/nice-errors/readme.md): An extension to provide user-friendly error messages during command execution. -- [`status-post`](src/extensions/status-post/readme.md): An extension to post the bot's status to a specified URL. -Read the provided documentation for each extension to learn more about their features and how to configure them. +We provide multiple extensions directly within this project to get you started. These +are: + +- [`ping`](src/extensions/ping/readme.md): A simple ping command and an http endpoint to + test whether the bot is online. +- [`listings`](src/extensions/listings/readme.md): An extension to post server count to + various bot listing websites. +- [`branding`](src/extensions/branding/readme.md): An extension to customize the bot's + presence and status, and embed aesthetics. +- [`add-dm`](src/extensions/add-dm/readme.md): An extension to send a direct message to + the user who adds the bot to a guild. +- [`nice-errors`](src/extensions/nice-errors/readme.md): An extension to provide + user-friendly error messages during command execution. +- [`status-post`](src/extensions/status-post/readme.md): An extension to post the bot's + status to a specified URL. + +Read the provided documentation for each extension to learn more about their features +and how to configure them. ## Contributing -We welcome contributions to this project! Please follow the [gitmoji.dev](https://gitmoji.dev) convention for commit messages and submit pull requests with descriptive commit messages. +We welcome contributions to this project! Please follow the +[gitmoji.dev](https://gitmoji.dev) convention for commit messages and submit pull +requests with descriptive commit messages. ## Built With @@ -332,19 +425,29 @@ We welcome contributions to this project! Please follow the [gitmoji.dev](https: ## Code Style and Linting -This project follows the [PEP 8](https://www.python.org/dev/peps/pep-0008/) style guide for Python code. We recommend using a linter like [black](https://github.com/psf/black) to ensure your code adheres to the style guidelines. -We provide a command to lint the code using `pdm run lint`. For this to work you have to install the development dependencies using `pdm install -d` if you haven't already. +This project follows the [PEP 8](https://www.python.org/dev/peps/pep-0008/) style guide +for Python code. We recommend using a linter like [black](https://github.com/psf/black) +to ensure your code adheres to the style guidelines. We provide a command to lint the +code using `pdm run lint`. For this to work you have to install the development +dependencies using `pdm install -d` if you haven't already. ## Deployment -Botkit is designed to be deployed on various platforms, including cloud services like [Heroku](https://www.heroku.com/) or [DigitalOcean](https://www.digitalocean.com/). Refer to the documentation of your preferred hosting platform for deployment instructions. -A `Dockerfile` is included in the project for containerized deployments, as well as a GitHub action including tests and linting. -You can export the requirements to a `requirements.txt` file using `pdm run export`, run the tests using `pdm run tests` and lint the code using `pdm run lint`. -In order for the GitHub tests to pass, you need to make sure you linted your code, that the tests pass and that you exported the requirements if you made changes to the dependencies. +Botkit is designed to be deployed on various platforms, including cloud services like +[Heroku](https://www.heroku.com/) or [DigitalOcean](https://www.digitalocean.com/). +Refer to the documentation of your preferred hosting platform for deployment +instructions. A `Dockerfile` is included in the project for containerized deployments, +as well as a GitHub action including tests and linting. You can export the requirements +to a `requirements.txt` file using `pdm run export`, run the tests using `pdm run tests` +and lint the code using `pdm run lint`. In order for the GitHub tests to pass, you need +to make sure you linted your code, that the tests pass and that you exported the +requirements if you made changes to the dependencies. ## Support and Resources -If you encounter any issues or have questions about Botkit, feel free to open an issue on the [GitHub repository](https://github.com/nicebots-xyz/botkit). You can also join the [official Discord server](https://paill.at/OjTuQ) for support and discussions. +If you encounter any issues or have questions about Botkit, feel free to open an issue +on the [GitHub repository](https://github.com/nicebots-xyz/botkit). You can also join +the [official Discord server](https://paill.at/OjTuQ) for support and discussions. ## License diff --git a/renovate.json b/renovate.json index 9da65f3..58f3302 100644 --- a/renovate.json +++ b/renovate.json @@ -1,31 +1,19 @@ { "$schema": "https://docs.renovatebot.com/renovate-schema.json", - "extends": [ - "config:recommended" - ], - "baseBranches": [ - "dev" - ], - "labels": [ - "deps" - ], - "ignorePaths": [ - "requirements.txt" - ], + "extends": ["config:recommended"], + "baseBranches": ["dev"], + "labels": ["deps"], + "ignorePaths": ["requirements.txt"], "commitMessagePrefix": "⬆️", "commitMessageAction": "Upgrade", "packageRules": [ { - "updateTypes": [ - "pin" - ], + "updateTypes": ["pin"], "commitMessagePrefix": "📌", "commitMessageAction": "Pin" }, { - "updateTypes": [ - "rollback" - ], + "updateTypes": ["rollback"], "commitMessagePrefix": "⬇️", "commitMessageAction": "Downgrade" }, @@ -35,6 +23,3 @@ } ] } - - - diff --git a/src/custom/__init__.py b/src/custom/__init__.py index a50f680..9eeeff4 100644 --- a/src/custom/__init__.py +++ b/src/custom/__init__.py @@ -2,15 +2,14 @@ # SPDX-License-Identifier: MIT from logging import getLogger -from typing import TYPE_CHECKING, Any, TypeAlias # pyright: ignore[reportDeprecated] +from typing import TYPE_CHECKING, Any, override import discord from discord import Message from discord.ext import bridge from discord.ext.bridge import ( - BridgeExtContext, # pyright: ignore [reportMissingTypeStubs] + BridgeExtContext, ) -from typing_extensions import override from src.i18n.classes import ExtensionTranslation, TranslationWrapper, apply_locale @@ -20,7 +19,7 @@ class ApplicationContext(bridge.BridgeApplicationContext): def __init__(self, bot: discord.Bot, interaction: discord.Interaction) -> None: self.translations: TranslationWrapper = TranslationWrapper({}, "en-US") # empty placeholder - super().__init__(bot=bot, interaction=interaction) # pyright: ignore[reportUnknownMemberType] + super().__init__(bot=bot, interaction=interaction) @override def __setattr__(self, key: Any, value: Any) -> None: @@ -35,15 +34,15 @@ def __setattr__(self, key: Any, value: Any) -> None: class ExtContext(bridge.BridgeExtContext): def __init__(self, **kwargs: Any) -> None: self.translations: TranslationWrapper = TranslationWrapper({}, "en-US") # empty placeholder - super().__init__(**kwargs) # pyright: ignore[reportUnknownMemberType] + super().__init__(**kwargs) def load_translations(self) -> None: - if hasattr(self.command, "translations") and self.command.translations: # pyright: ignore[reportUnknownMemberType,reportUnknownArgumentType,reportOptionalMemberAccess,reportAttributeAccessIssue] + if hasattr(self.command, "translations") and self.command.translations: # pyright: ignore[reportUnknownArgumentType,reportOptionalMemberAccess,reportAttributeAccessIssue] locale: str | None = None - if guild := self.guild: # pyright: ignore[reportUnnecessaryComparison] # for some reason pyright thinks guild is function + if guild := self.guild: # pyright: ignore[reportUnnecessaryComparison] locale = guild.preferred_locale # pyright: ignore[reportFunctionMemberAccess] self.translations = apply_locale( - self.command.translations, # pyright: ignore[reportUnknownMemberType,reportUnknownArgumentType,reportAttributeAccessIssue,reportOptionalMemberAccess] + self.command.translations, # pyright: ignore[reportUnknownArgumentType,reportAttributeAccessIssue,reportOptionalMemberAccess] locale, ) @@ -51,7 +50,7 @@ def load_translations(self) -> None: class Bot(bridge.Bot): def __init__(self, *args: Any, **options: Any) -> None: self.translations: list[ExtensionTranslation] = options.pop("translations", []) - super().__init__(*args, **options) # pyright: ignore[reportUnknownMemberType] + super().__init__(*args, **options) @self.listen(name="on_ready", once=True) async def on_ready() -> None: # pyright: ignore[reportUnusedFunction] @@ -64,7 +63,7 @@ async def get_application_context( cls: None | type[bridge.BridgeApplicationContext] = None, ) -> bridge.BridgeApplicationContext: cls = cls if cls is not None else ApplicationContext - return await super().get_application_context(interaction, cls=cls) # pyright: ignore [reportUnknownMemberType] + return await super().get_application_context(interaction, cls=cls) @override async def get_context( @@ -73,7 +72,7 @@ async def get_context( cls: None | type[bridge.BridgeExtContext] = None, ) -> BridgeExtContext: cls = cls if cls is not None else ExtContext - ctx = await super().get_context(message, cls=cls) # pyright: ignore [reportUnknownMemberType] + ctx = await super().get_context(message, cls=cls) if isinstance(ctx, ExtContext): ctx.load_translations() return ctx @@ -82,6 +81,6 @@ async def get_context( Context: ApplicationContext = ApplicationContext # pyright: ignore [reportRedeclaration] if TYPE_CHECKING: # temp fix for https://github.com/Pycord-Development/pycord/pull/2611 - Context: TypeAlias = ExtContext | ApplicationContext + type Context = ExtContext | ApplicationContext __all__ = ["Bot", "Context", "ExtContext", "ApplicationContext"] diff --git a/src/extensions/add-dm/readme.md b/src/extensions/add-dm/readme.md index 8130c25..41ded5a 100644 --- a/src/extensions/add-dm/readme.md +++ b/src/extensions/add-dm/readme.md @@ -1,30 +1,45 @@ # Add-DM Extension -The Add-DM extension is a valuable addition to your Botkit, designed to automatically send a direct message (DM) to the user who adds the bot to a guild. This feature enhances user engagement by providing immediate acknowledgment and guidance upon installation. +The Add-DM extension is a valuable addition to your Botkit, designed to automatically +send a direct message (DM) to the user who adds the bot to a guild. This feature +enhances user engagement by providing immediate acknowledgment and guidance upon +installation. ## Features -The Add-DM extension automatically triggers a DM to the user who adds the bot to a server. This message can be customized to include instructions, a welcome message, or any other information deemed necessary by the bot owner. It's an excellent way for bot developers to start engaging with new users right away. +The Add-DM extension automatically triggers a DM to the user who adds the bot to a +server. This message can be customized to include instructions, a welcome message, or +any other information deemed necessary by the bot owner. It's an excellent way for bot +developers to start engaging with new users right away. ## Usage -Upon the bot being added to a guild, it checks for the necessary permissions and identifies the user who added the bot. It then sends a predefined message to this user. The message can be customized in the bot's configuration file. +Upon the bot being added to a guild, it checks for the necessary permissions and +identifies the user who added the bot. It then sends a predefined message to this user. +The message can be customized in the bot's configuration file. ## Configuration -The Add-DM extension requires minimal configuration, allowing for the customization of the message sent to the user. Here's a basic outline of the configurable options: +The Add-DM extension requires minimal configuration, allowing for the customization of +the message sent to the user. Here's a basic outline of the configurable options: - `enabled`: Determines whether the Add-DM feature is active. Set to `True` by default. -- `message`: The message template sent to the user. Supports placeholders for dynamic content such as `{user.mention}` to mention the user. +- `message`: The message template sent to the user. Supports placeholders for dynamic + content such as `{user.mention}` to mention the user. -To customize the message, edit the `config.yml` file or set the appropriate environment variables. For example: +To customize the message, edit the `config.yml` file or set the appropriate environment +variables. For example: ```yaml add_dm: enabled: True - message: "Hello, {user.mention}! Thank you for adding me to your server. Type `/help` to see what I can do!" + message: + "Hello, {user.mention}! Thank you for adding me to your server. Type `/help` to see + what I can do!" ``` ## Contributing -Contributions to the Add-DM extension are welcome. If you have ideas on how to improve this extension or want to add new features, please submit a pull request. Your contributions are valuable in making this extension more useful for everyone. +Contributions to the Add-DM extension are welcome. If you have ideas on how to improve +this extension or want to add new features, please submit a pull request. Your +contributions are valuable in making this extension more useful for everyone. diff --git a/src/extensions/branding/readme.md b/src/extensions/branding/readme.md index 51edb8d..118077f 100644 --- a/src/extensions/branding/readme.md +++ b/src/extensions/branding/readme.md @@ -1,24 +1,33 @@ # Branding Extension -The Branding extension is a versatile tool that allows you to customize your bot's presence and embeds. It is **enabled** by default. +The Branding extension is a versatile tool that allows you to customize your bot's +presence and embeds. It is **enabled** by default. ## Features The Branding extension performs the following tasks: -- It updates the bot's status every 5 minutes by default. The status can be set to playing, watching, listening, or streaming. +- It updates the bot's status every 5 minutes by default. The status can be set to + playing, watching, listening, or streaming. - It allows customization of the embed's footer, color, and author. ## Usage -The Branding extension is a background task and does not provide any commands for interaction. Once properly configured, it will automatically perform its tasks without any further intervention. +The Branding extension is a background task and does not provide any commands for +interaction. Once properly configured, it will automatically perform its tasks without +any further intervention. ## Configuration The Branding extension requires the following configuration: -- `status`: A dictionary that defines the bot's status. It can contain keys for playing, watching, listening, and streaming, each with a list of possible statuses. It also contains an `every` key that defines the interval (in seconds) at which the status is updated. -- `embed`: A dictionary that defines the embed's footer, color, and author. The footer can contain a value (a string or a list of strings), a boolean for whether to include the time, a timezone, and a separator. +- `status`: A dictionary that defines the bot's status. It can contain keys for playing, + watching, listening, and streaming, each with a list of possible statuses. It also + contains an `every` key that defines the interval (in seconds) at which the status is + updated. +- `embed`: A dictionary that defines the embed's footer, color, and author. The footer + can contain a value (a string or a list of strings), a boolean for whether to include + the time, a timezone, and a separator. Here is an example of how to configure the Branding extension in your `config.yml` file: @@ -27,7 +36,7 @@ extensions: branding: enabled: true status: - watching: ["you", "/help"] # in conjunction, you can also use streaming, playing, and listening + watching: ["you", "/help"] # in conjunction, you can also use streaming, playing, and listening every: 300 embed: footer: @@ -42,8 +51,10 @@ extensions: ## Important -Please note that the Branding extension will not load if both the `status` or `embed` configurations are not set up. The extension will log an error message and return. +Please note that the Branding extension will not load if both the `status` or `embed` +configurations are not set up. The extension will log an error message and return. ## Contributing -If you wish to contribute to the development of the Branding extension, please feel free to submit a pull request. We appreciate your help in making this extension better. +If you wish to contribute to the development of the Branding extension, please feel free +to submit a pull request. We appreciate your help in making this extension better. diff --git a/src/extensions/listings/main.py b/src/extensions/listings/main.py index 9f9aac5..105cc75 100644 --- a/src/extensions/listings/main.py +++ b/src/extensions/listings/main.py @@ -1,13 +1,12 @@ # Copyright (c) NiceBots.xyz # SPDX-License-Identifier: MIT -from typing import Any +from typing import Any, override import aiohttp import discord from discord.ext import commands, tasks from schema import Optional, Schema -from typing_extensions import override from src.log import logger @@ -48,7 +47,7 @@ async def try_post_request(url: str, headers: dict[Any, Any], payload: dict[Any, class Listings(commands.Cog): def __init__(self, bot: discord.Bot, config: dict[Any, Any]) -> None: self.bot: discord.Bot = bot - self.config: dict = config + self.config: dict[Any, Any] = config self.topgg = bool(config.get("topgg_token")) self.discordscom = bool(config.get("discordscom_token")) @@ -71,24 +70,28 @@ async def update_count_loop(self) -> None: logger.exception("Failed to update count") async def update_count_discordscom(self) -> None: - headers = { + headers: dict[str, str] = { "Authorization": self.config["discordscom_token"], "Content-Type": "application/json", } payload = {"server_count": len(self.bot.guilds)} + if not self.bot.user: + return url = f"{DISCORDSCOM_BASE_URL}/{self.bot.user.id}/setservers" await try_post_request(url, headers, payload) logger.info("Updated discords.com count") async def update_count_topgg(self) -> None: - headers = {"Authorization": self.config["topgg_token"]} + headers: dict[str, str] = {"Authorization": self.config["topgg_token"]} payload = {"server_count": len(self.bot.guilds)} + if not self.bot.user: + return url = f"{TOPGG_BASE_URL}/bots/{self.bot.user.id}/stats" await try_post_request(url, headers, payload) logger.info("Updated top.gg count") -def setup(bot: discord.Bot, config: dict) -> None: +def setup(bot: discord.Bot, config: dict[Any, Any]) -> None: if not config.get("topgg_token") and not config.get("discordscom_token"): logger.error("Top.gg or Discords.com token not found") return diff --git a/src/extensions/listings/readme.md b/src/extensions/listings/readme.md index 0b38379..c336fea 100644 --- a/src/extensions/listings/readme.md +++ b/src/extensions/listings/readme.md @@ -1,6 +1,8 @@ # Listings Extension -The Listings extension is a powerful tool that allows your bot to interact with various bot listing websites. It requires valid tokens for each listing website and is **disabled** by default. +The Listings extension is a powerful tool that allows your bot to interact with various +bot listing websites. It requires valid tokens for each listing website and is +**disabled** by default. ## Features @@ -11,15 +13,20 @@ The Listings extension performs the following tasks: ## Usage -The Listings extension is a background task and does not provide any commands for interaction. Once enabled and properly configured, it will automatically perform its tasks without any further intervention. +The Listings extension is a background task and does not provide any commands for +interaction. Once enabled and properly configured, it will automatically perform its +tasks without any further intervention. ## Configuration The Listings extension requires the following configuration: -- `topgg_token`: Your Top.gg token. This is a string, and it is required for the Top.gg listing to work. -- `discordscom_token`: Your Discords.com token. This is a string, and it is required for the Discords.com listing to work. -- `enabled`: A boolean value that determines whether the extension is enabled or not. By default, this is set to `false`. +- `topgg_token`: Your Top.gg token. This is a string, and it is required for the Top.gg + listing to work. +- `discordscom_token`: Your Discords.com token. This is a string, and it is required for + the Discords.com listing to work. +- `enabled`: A boolean value that determines whether the extension is enabled or not. By + default, this is set to `false`. Here is an example of how to configure the Listings extension in your `config.yml` file: @@ -31,12 +38,15 @@ extensions: enabled: true ``` -Please replace `"your-topgg-token"` and `"your-discordscom-token"` with your actual tokens. +Please replace `"your-topgg-token"` and `"your-discordscom-token"` with your actual +tokens. ## Important -Please note that the Listings extension will not load if the `topgg_token` or `discordscom_token` is not set up. The extension will log an error message and return. +Please note that the Listings extension will not load if the `topgg_token` or +`discordscom_token` is not set up. The extension will log an error message and return. ## Contributing -If you wish to contribute to the development of the Listings extension, please feel free to submit a pull request. We appreciate your help in making this extension better. \ No newline at end of file +If you wish to contribute to the development of the Listings extension, please feel free +to submit a pull request. We appreciate your help in making this extension better. diff --git a/src/extensions/nice-errors/handler.py b/src/extensions/nice-errors/handler.py index da31bab..9e18e3c 100644 --- a/src/extensions/nice-errors/handler.py +++ b/src/extensions/nice-errors/handler.py @@ -4,11 +4,10 @@ import contextlib import difflib from collections.abc import Callable, Coroutine -from typing import Any, TypeAlias, TypeVar, final +from typing import Any, TypeVar, final, override import discord from discord.ext import bridge, commands -from typing_extensions import override from src import custom from src.i18n import apply_locale @@ -85,12 +84,12 @@ def get_locale(ctx: custom.Context | discord.Interaction) -> str | None: T = TypeVar("T", bound=Coroutine[Any, Any, Any]) -ErrorHandlersIType: TypeAlias = Callable[ +type ErrorHandlersIType[T] = Callable[ [Exception, discord.Interaction | custom.Context, TranslationWrapper, dict[str, Any], str, bool], T ] -ErrorHandlerRType: TypeAlias = tuple[bool, bool, str, dict[str, Any]] -ErrorHandlerType: TypeAlias = ErrorHandlersIType[Coroutine[Any, Any, ErrorHandlerRType]] -ErrorHandlersType: TypeAlias = dict[ +type ErrorHandlerRType = tuple[bool, bool, str, dict[str, Any]] +type ErrorHandlerType = ErrorHandlersIType[Coroutine[Any, Any, ErrorHandlerRType]] +type ErrorHandlersType = dict[ type[Exception], ErrorHandlerType, ] diff --git a/src/extensions/nice-errors/patch.py b/src/extensions/nice-errors/patch.py index 13d8eed..1bebcff 100644 --- a/src/extensions/nice-errors/patch.py +++ b/src/extensions/nice-errors/patch.py @@ -30,10 +30,11 @@ async def patch(config: dict[str, Any]) -> None: ), ) + from typing import override + import discord from discord import Interaction from discord.ui import Item - from typing_extensions import override class PatchedView(discord.ui.View): @override diff --git a/src/extensions/nice-errors/readme.md b/src/extensions/nice-errors/readme.md index 48732d3..8eea030 100644 --- a/src/extensions/nice-errors/readme.md +++ b/src/extensions/nice-errors/readme.md @@ -1,22 +1,36 @@ # Nice-Errors Extension -The Nice-Errors extension is an essential tool for your Botkit, designed to enhance error handling by providing user-friendly error messages during command execution. This feature improves the user experience by ensuring that errors are communicated effectively and clearly. +The Nice-Errors extension is an essential tool for your Botkit, designed to enhance +error handling by providing user-friendly error messages during command execution. This +feature improves the user experience by ensuring that errors are communicated +effectively and clearly. ## Features -The Nice-Errors extension intercepts errors that occur during the execution of application commands. Instead of displaying raw error messages, it formats them into more understandable text and provides guidance or feedback to the user. This can significantly improve the interaction between the bot and its users by making error messages less intimidating and more informative. +The Nice-Errors extension intercepts errors that occur during the execution of +application commands. Instead of displaying raw error messages, it formats them into +more understandable text and provides guidance or feedback to the user. This can +significantly improve the interaction between the bot and its users by making error +messages less intimidating and more informative. ## Usage -When a command execution leads to an error, the Nice-Errors extension automatically catches this error. It then checks the type of error and responds with a customized, user-friendly message. This process is entirely automated, requiring no manual intervention from the user or developer. +When a command execution leads to an error, the Nice-Errors extension automatically +catches this error. It then checks the type of error and responds with a customized, +user-friendly message. This process is entirely automated, requiring no manual +intervention from the user or developer. ## Configuration -The Nice-Errors extension can be enabled or disabled as needed. By default, it is enabled to ensure that your bot always provides helpful feedback to users during errors. Here's how you can configure it: +The Nice-Errors extension can be enabled or disabled as needed. By default, it is +enabled to ensure that your bot always provides helpful feedback to users during errors. +Here's how you can configure it: -- `enabled`: A boolean value that determines whether the Nice-Errors feature is active. Set to `True` by default. +- `enabled`: A boolean value that determines whether the Nice-Errors feature is active. + Set to `True` by default. -To adjust this setting, you can modify the `config.yml` file or use environment variables. For example: +To adjust this setting, you can modify the `config.yml` file or use environment +variables. For example: ```yaml nice_errors: @@ -25,4 +39,7 @@ nice_errors: ## Contributing -Contributions to the Nice-Errors extension are highly encouraged. If you have suggestions for improving the error messages or adding support for more types of errors, please submit a pull request. Your input is invaluable in making this extension more effective for all users. +Contributions to the Nice-Errors extension are highly encouraged. If you have +suggestions for improving the error messages or adding support for more types of errors, +please submit a pull request. Your input is invaluable in making this extension more +effective for all users. diff --git a/src/extensions/ping/readme.md b/src/extensions/ping/readme.md index 6016bef..247a67d 100644 --- a/src/extensions/ping/readme.md +++ b/src/extensions/ping/readme.md @@ -1,19 +1,20 @@ # Ping Extension -The Ping extension is a straightforward, yet essential part of your Botkit. -It doesn't require any configuration and is **enabled** by default. +The Ping extension is a straightforward, yet essential part of your Botkit. It doesn't +require any configuration and is **enabled** by default. ## Features -The Ping extension adds a `/ping` command to your bot. -When this command is invoked, the bot responds with a message indicating that it is online and operational. -This can be useful for quickly checking if your bot is responsive. -The Ping extension also serves an http endpoint at `/ping` that responds with a `200 OK` status code and the bot's name. +The Ping extension adds a `/ping` command to your bot. When this command is invoked, the +bot responds with a message indicating that it is online and operational. This can be +useful for quickly checking if your bot is responsive. The Ping extension also serves an +http endpoint at `/ping` that responds with a `200 OK` status code and the bot's name. ## Usage -To use the Ping extension type the `/ping` command. The bot should respond with a message, confirming its online status. -You can also send a `GET` request to the `/ping` endpoint to check if the bot is online. +To use the Ping extension type the `/ping` command. The bot should respond with a +message, confirming its online status. You can also send a `GET` request to the `/ping` +endpoint to check if the bot is online. ```bash curl http://localhost:5000/ping @@ -21,8 +22,11 @@ curl http://localhost:5000/ping ## Configuration -The Ping extension does not require any configuration. It is enabled by default. If you wish to disable it, you can do so by setting its `enabled` key to `false` in the `config.yml` file or through environment variables. +The Ping extension does not require any configuration. It is enabled by default. If you +wish to disable it, you can do so by setting its `enabled` key to `false` in the +`config.yml` file or through environment variables. ## Contributing -If you wish to contribute to the development of the Ping extension, please feel free to submit a pull request. We appreciate your help in making this extension better. +If you wish to contribute to the development of the Ping extension, please feel free to +submit a pull request. We appreciate your help in making this extension better. diff --git a/src/extensions/status-post/readme.md b/src/extensions/status-post/readme.md index f8c5706..12183c2 100644 --- a/src/extensions/status-post/readme.md +++ b/src/extensions/status-post/readme.md @@ -1,16 +1,18 @@ # Status Extension -The Status extension is a straightforward, yet essential part of your Botkit. -It requires minimal configuration and can be enabled or disabled as needed. +The Status extension is a straightforward, yet essential part of your Botkit. It +requires minimal configuration and can be enabled or disabled as needed. ## Features -The Status extension periodically pushes the bot's status to a specified URL. -This can be useful for monitoring the bot's health and responsiveness. +The Status extension periodically pushes the bot's status to a specified URL. This can +be useful for monitoring the bot's health and responsiveness. ## Usage -To use the Status extension, configure the `url` and `every` keys in the `config.yml` file or through environment variables. The bot will push its status to the specified URL at the configured interval. +To use the Status extension, configure the `url` and `every` keys in the `config.yml` +file or through environment variables. The bot will push its status to the specified URL +at the configured interval. ## Configuration @@ -30,4 +32,6 @@ status: ``` ## Contributing -If you wish to contribute to the development of the Status extension, please feel free to submit a pull request. We appreciate your help in making this extension better. \ No newline at end of file + +If you wish to contribute to the development of the Status extension, please feel free +to submit a pull request. We appreciate your help in making this extension better. diff --git a/src/i18n/classes.py b/src/i18n/classes.py index d3b0f1b..a779298 100644 --- a/src/i18n/classes.py +++ b/src/i18n/classes.py @@ -1,10 +1,9 @@ # Copyright (c) NiceBots.xyz # SPDX-License-Identifier: MIT -from typing import Any +from typing import Any, override from pydantic import BaseModel, Field -from typing_extensions import override LOCALES = ( "en-US", diff --git a/tests/__init__.py b/tests/__init__.py index 3fb26ca..8b45425 100644 --- a/tests/__init__.py +++ b/tests/__init__.py @@ -1,3 +1,2 @@ # Copyright (c) NiceBots.xyz # SPDX-License-Identifier: MIT - From 52e24981cb0de961a1330fe1055128c9596f5bd5 Mon Sep 17 00:00:00 2001 From: Paillat Date: Sat, 9 Nov 2024 22:21:20 +0100 Subject: [PATCH 09/61] :bug: Remove basedpyright from pre-commit and add copywrite --- .pre-commit-config.yaml | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index b9e55be..d4ef2b9 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -1,3 +1,6 @@ +# Copyright (c) NiceBots +# SPDX-License-Identifier: MIT + ci: autoupdate_commit_msg: "chore(pre-commit): pre-commit autoupdate" autofix_commit_msg: "style(pre-commit): auto fixes from pre-commit.com hooks" @@ -25,7 +28,10 @@ repos: args: [ --fix ] # Run the formatter. - id: ruff-format - - repo: https://github.com/DetachHead/basedpyright-pre-commit-mirror - rev: v1.13.0 # or whatever the latest version is at the time - hooks: - - id: basedpyright + - repo: local + hooks: + - id: copywrite + name: copywrite + entry: copywrite headers + language: system + files: . \ No newline at end of file From 3a73e3acf93baab00294ddcf5f38228abf687171 Mon Sep 17 00:00:00 2001 From: Paillat Date: Sun, 10 Nov 2024 00:29:19 +0100 Subject: [PATCH 10/61] :sparkles: Cooldown --- pdm.lock | 41 +++++++++++++++++- pyproject.toml | 4 +- src/custom/__init__.py | 7 ++- src/extensions/branding/branding.py | 2 +- src/extensions/ping/ping.py | 7 +++ src/i18n/utils.py | 2 +- src/utils/cooldown.py | 67 +++++++++++++++++++++++++++++ 7 files changed, 125 insertions(+), 5 deletions(-) create mode 100644 src/utils/cooldown.py diff --git a/pdm.lock b/pdm.lock index 9661a8f..47b4406 100644 --- a/pdm.lock +++ b/pdm.lock @@ -5,11 +5,36 @@ groups = ["default", "dev"] strategy = ["inherit_metadata"] lock_version = "4.5.0" -content_hash = "sha256:0086468197db366b92490df6cb4904829351f850ccd9e2c898421d5a70317afc" +content_hash = "sha256:53fa6d7cfe418243bec2cfedc2d29ee7f5a9268c607190745da713992a9b21a0" [[metadata.targets]] requires_python = "==3.12.*" +[[package]] +name = "aiocache" +version = "0.12.3" +summary = "multi backend asyncio cache" +groups = ["default"] +files = [ + {file = "aiocache-0.12.3-py2.py3-none-any.whl", hash = "sha256:889086fc24710f431937b87ad3720a289f7fc31c4fd8b68e9f918b9bacd8270d"}, + {file = "aiocache-0.12.3.tar.gz", hash = "sha256:f528b27bf4d436b497a1d0d1a8f59a542c153ab1e37c3621713cb376d44c4713"}, +] + +[[package]] +name = "aiocache" +version = "0.12.3" +extras = ["redis"] +summary = "multi backend asyncio cache" +groups = ["default"] +dependencies = [ + "aiocache==0.12.3", + "redis>=4.2.0", +] +files = [ + {file = "aiocache-0.12.3-py2.py3-none-any.whl", hash = "sha256:889086fc24710f431937b87ad3720a289f7fc31c4fd8b68e9f918b9bacd8270d"}, + {file = "aiocache-0.12.3.tar.gz", hash = "sha256:f528b27bf4d436b497a1d0d1a8f59a542c153ab1e37c3621713cb376d44c4713"}, +] + [[package]] name = "aiofile" version = "3.9.0" @@ -758,6 +783,20 @@ files = [ {file = "quart-0.19.8.tar.gz", hash = "sha256:ef567d0be7677c99890d5c6ff30e679699fe7e5fca1a90fa3b6974edd8421794"}, ] +[[package]] +name = "redis" +version = "5.2.0" +requires_python = ">=3.8" +summary = "Python client for Redis database and key-value store" +groups = ["default"] +dependencies = [ + "async-timeout>=4.0.3; python_full_version < \"3.11.3\"", +] +files = [ + {file = "redis-5.2.0-py3-none-any.whl", hash = "sha256:ae174f2bb3b1bf2b09d54bf3e51fbc1469cf6c10aa03e21141f51969801a7897"}, + {file = "redis-5.2.0.tar.gz", hash = "sha256:0b1087665a771b1ff2e003aa5bdd354f15a70c9e25d5a7dbf9c722c16528a7b0"}, +] + [[package]] name = "ruff" version = "0.7.3" diff --git a/pyproject.toml b/pyproject.toml index 277abf9..4d6343b 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -20,6 +20,7 @@ dependencies = [ "coloredlogs>=15.0.1", "aiofile>=3.9.0", "sentry-sdk>=2.18.0", + "aiocache[redis]>=0.12.3", ] requires-python = "==3.12.*" readme = "README.md" @@ -100,5 +101,6 @@ extend-ignore = [ "ISC001", "D203", "FBT001", - "FBT002" + "FBT002", + "C901" ] diff --git a/src/custom/__init__.py b/src/custom/__init__.py index 9eeeff4..18cb15f 100644 --- a/src/custom/__init__.py +++ b/src/custom/__init__.py @@ -4,6 +4,7 @@ from logging import getLogger from typing import TYPE_CHECKING, Any, override +import aiocache import discord from discord import Message from discord.ext import bridge @@ -17,9 +18,10 @@ class ApplicationContext(bridge.BridgeApplicationContext): - def __init__(self, bot: discord.Bot, interaction: discord.Interaction) -> None: + def __init__(self, bot: "Bot", interaction: discord.Interaction) -> None: self.translations: TranslationWrapper = TranslationWrapper({}, "en-US") # empty placeholder super().__init__(bot=bot, interaction=interaction) + self.bot: Bot @override def __setattr__(self, key: Any, value: Any) -> None: @@ -35,6 +37,7 @@ class ExtContext(bridge.BridgeExtContext): def __init__(self, **kwargs: Any) -> None: self.translations: TranslationWrapper = TranslationWrapper({}, "en-US") # empty placeholder super().__init__(**kwargs) + self.bot: Bot def load_translations(self) -> None: if hasattr(self.command, "translations") and self.command.translations: # pyright: ignore[reportUnknownArgumentType,reportOptionalMemberAccess,reportAttributeAccessIssue] @@ -50,6 +53,7 @@ def load_translations(self) -> None: class Bot(bridge.Bot): def __init__(self, *args: Any, **options: Any) -> None: self.translations: list[ExtensionTranslation] = options.pop("translations", []) + self.cache: aiocache.SimpleMemoryCache | aiocache.RedisCache = aiocache.SimpleMemoryCache() super().__init__(*args, **options) @self.listen(name="on_ready", once=True) @@ -82,5 +86,6 @@ async def get_context( if TYPE_CHECKING: # temp fix for https://github.com/Pycord-Development/pycord/pull/2611 type Context = ExtContext | ApplicationContext + ... # for some reason, this makes pycharm happy __all__ = ["Bot", "Context", "ExtContext", "ApplicationContext"] diff --git a/src/extensions/branding/branding.py b/src/extensions/branding/branding.py index 7a5505d..686c4b4 100644 --- a/src/extensions/branding/branding.py +++ b/src/extensions/branding/branding.py @@ -141,7 +141,7 @@ async def update_status(self) -> None: await self.bot.change_presence(activity=activity) -def setup(bot: discord.Bot, config: dict[Any, Any]) -> None: # noqa: C901 +def setup(bot: discord.Bot, config: dict[Any, Any]) -> None: if not config.get("embed") and not config.get("status"): logger.warning( "Branding extension is enabled but no configuration is provided for embed or status. You can disable this " diff --git a/src/extensions/ping/ping.py b/src/extensions/ping/ping.py index c0ccd5e..215ed5a 100644 --- a/src/extensions/ping/ping.py +++ b/src/extensions/ping/ping.py @@ -9,6 +9,7 @@ from src import custom from src.log import logger +from src.utils.cooldown import cooldown default = { "enabled": True, @@ -26,6 +27,12 @@ def __init__(self, bot: custom.Bot) -> None: self.bot = bot @bridge.bridge_command() + @cooldown( + key="ping", + limit=1, + per=5, + strong=True, + ) async def ping( self, ctx: custom.Context, diff --git a/src/i18n/utils.py b/src/i18n/utils.py index fba7023..bab67db 100644 --- a/src/i18n/utils.py +++ b/src/i18n/utils.py @@ -74,7 +74,7 @@ def merge_command_translations( ) -def localize_commands( # noqa: C901, PLR0912 +def localize_commands( # noqa: PLR0912 commands: list[CommandT], translations: ExtensionTranslation | Deg1CommandTranslation diff --git a/src/utils/cooldown.py b/src/utils/cooldown.py new file mode 100644 index 0000000..f5f1caf --- /dev/null +++ b/src/utils/cooldown.py @@ -0,0 +1,67 @@ +# Copyright (c) NiceBots +# SPDX-License-Identifier: MIT + +import time +from collections.abc import Awaitable, Callable, Coroutine +from functools import wraps +from inspect import isawaitable +from typing import Any, Concatenate, cast + +from discord.ext import commands + +import custom +from src.custom import Bot, Context + +type ReactiveCooldownSetting[T] = T | Callable[[Bot, Context], T | Coroutine[Any, Any, T]] +type CogCommandFunction[T: commands.Cog, **P] = Callable[Concatenate[T, custom.ApplicationContext, P], Awaitable[None]] + + +async def parse_reactive_setting[T](value: ReactiveCooldownSetting[T], bot: Bot, ctx: Context) -> T: + if callable(value): + value = value(bot, ctx) # pyright: ignore [reportAssignmentType] + if isawaitable(value): + value = await value + return value # pyright: ignore [reportReturnType] + + +class CooldownExceeded(commands.CheckFailure): + def __init__(self, retry_after: float) -> None: + self.retry_after: float = retry_after + super().__init__("You are on cooldown") + + +# inspired by https://github.com/ItsDrike/code-jam-2024/blob/main/src/utils/ratelimit.py + + +def cooldown[C: commands.Cog, **P]( + key: ReactiveCooldownSetting[str], + *, + limit: ReactiveCooldownSetting[int], + per: ReactiveCooldownSetting[int], + strong: ReactiveCooldownSetting[bool] = False, +) -> Callable[[CogCommandFunction[C, P]], CogCommandFunction[C, P]]: + def inner(func: CogCommandFunction[C, P]) -> CogCommandFunction[C, P]: + @wraps(func) + async def wrapper(self: C, ctx: custom.ApplicationContext, *args: P.args, **kwargs: P.kwargs) -> None: + cache = ctx.bot.cache + key_value = await parse_reactive_setting(key, ctx.bot, ctx) + limit_value = await parse_reactive_setting(limit, ctx.bot, ctx) + per_value = await parse_reactive_setting(per, ctx.bot, ctx) + strong_value = await parse_reactive_setting(strong, ctx.bot, ctx) + + now = time.time() + time_stamps = cast(tuple[float, ...], await cache.get(key, default=(), namespace="cooldown")) + time_stamps = tuple(filter(lambda x: x > now - per_value, time_stamps)) + time_stamps = time_stamps[-limit_value:] + if len(time_stamps) < limit_value or strong_value: + time_stamps = (*time_stamps, now) + await cache.set(key_value, time_stamps, namespace="cooldown") + limit_value += 1 # to account for the current command + + if len(time_stamps) >= limit_value: + raise CooldownExceeded(min(time_stamps) - now + per_value) + await func(self, ctx, *args, **kwargs) + + return wrapper + + return inner From 405a6968d8f55de48d692754b406bcc6f5718bc9 Mon Sep 17 00:00:00 2001 From: Paillat Date: Sun, 10 Nov 2024 00:35:28 +0100 Subject: [PATCH 11/61] :sparkles: Allow custom Cooldown errors --- src/utils/cooldown.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/utils/cooldown.py b/src/utils/cooldown.py index f5f1caf..772ade5 100644 --- a/src/utils/cooldown.py +++ b/src/utils/cooldown.py @@ -39,6 +39,7 @@ def cooldown[C: commands.Cog, **P]( limit: ReactiveCooldownSetting[int], per: ReactiveCooldownSetting[int], strong: ReactiveCooldownSetting[bool] = False, + cls: type[CooldownExceeded] = CooldownExceeded, ) -> Callable[[CogCommandFunction[C, P]], CogCommandFunction[C, P]]: def inner(func: CogCommandFunction[C, P]) -> CogCommandFunction[C, P]: @wraps(func) @@ -59,7 +60,7 @@ async def wrapper(self: C, ctx: custom.ApplicationContext, *args: P.args, **kwar limit_value += 1 # to account for the current command if len(time_stamps) >= limit_value: - raise CooldownExceeded(min(time_stamps) - now + per_value) + raise cls(min(time_stamps) - now + per_value) await func(self, ctx, *args, **kwargs) return wrapper From aefc625c3443569fdff764b371affa62966120f3 Mon Sep 17 00:00:00 2001 From: Paillat Date: Sun, 10 Nov 2024 15:21:43 +0100 Subject: [PATCH 12/61] :sparkles: Better error handling --- readme.md | 2 +- src/custom/__init__.py | 6 +- src/extensions/nice-errors/handler.py | 187 ------------------ .../{nice-errors => nice_errors}/__init__.py | 0 .../nice_errors/handlers/__init__.py | 6 + src/extensions/nice_errors/handlers/base.py | 127 ++++++++++++ .../nice_errors/handlers/forbidden.py | 33 ++++ .../nice_errors/handlers/generic.py | 33 ++++ .../nice_errors/handlers/not_found.py | 94 +++++++++ .../{nice-errors => nice_errors}/main.py | 13 +- .../{nice-errors => nice_errors}/patch.py | 2 +- .../{nice-errors => nice_errors}/readme.md | 0 .../translations.yml | 0 src/utils/cooldown.py | 9 +- 14 files changed, 312 insertions(+), 200 deletions(-) delete mode 100644 src/extensions/nice-errors/handler.py rename src/extensions/{nice-errors => nice_errors}/__init__.py (100%) create mode 100644 src/extensions/nice_errors/handlers/__init__.py create mode 100644 src/extensions/nice_errors/handlers/base.py create mode 100644 src/extensions/nice_errors/handlers/forbidden.py create mode 100644 src/extensions/nice_errors/handlers/generic.py create mode 100644 src/extensions/nice_errors/handlers/not_found.py rename src/extensions/{nice-errors => nice_errors}/main.py (72%) rename src/extensions/{nice-errors => nice_errors}/patch.py (97%) rename src/extensions/{nice-errors => nice_errors}/readme.md (100%) rename src/extensions/{nice-errors => nice_errors}/translations.yml (100%) diff --git a/readme.md b/readme.md index aee888e..2952ec4 100644 --- a/readme.md +++ b/readme.md @@ -402,7 +402,7 @@ are: presence and status, and embed aesthetics. - [`add-dm`](src/extensions/add-dm/readme.md): An extension to send a direct message to the user who adds the bot to a guild. -- [`nice-errors`](src/extensions/nice-errors/readme.md): An extension to provide +- [`nice-errors`](src/extensions/nice_errors/readme.md): An extension to provide user-friendly error messages during command execution. - [`status-post`](src/extensions/status-post/readme.md): An extension to post the bot's status to a specified URL. diff --git a/src/custom/__init__.py b/src/custom/__init__.py index 18cb15f..5ac2bdd 100644 --- a/src/custom/__init__.py +++ b/src/custom/__init__.py @@ -42,10 +42,10 @@ def __init__(self, **kwargs: Any) -> None: def load_translations(self) -> None: if hasattr(self.command, "translations") and self.command.translations: # pyright: ignore[reportUnknownArgumentType,reportOptionalMemberAccess,reportAttributeAccessIssue] locale: str | None = None - if guild := self.guild: # pyright: ignore[reportUnnecessaryComparison] - locale = guild.preferred_locale # pyright: ignore[reportFunctionMemberAccess] + if guild := self.guild: + locale = guild.preferred_locale self.translations = apply_locale( - self.command.translations, # pyright: ignore[reportUnknownArgumentType,reportAttributeAccessIssue,reportOptionalMemberAccess] + self.command.translations, locale, ) diff --git a/src/extensions/nice-errors/handler.py b/src/extensions/nice-errors/handler.py deleted file mode 100644 index 9e18e3c..0000000 --- a/src/extensions/nice-errors/handler.py +++ /dev/null @@ -1,187 +0,0 @@ -# Copyright (c) NiceBots.xyz -# SPDX-License-Identifier: MIT - -import contextlib -import difflib -from collections.abc import Callable, Coroutine -from typing import Any, TypeVar, final, override - -import discord -from discord.ext import bridge, commands - -from src import custom -from src.i18n import apply_locale -from src.i18n.classes import RawTranslation, TranslationWrapper - -sentry_sdk = None - -with contextlib.suppress(ImportError): - import sentry_sdk - - -class RunInsteadButton(discord.ui.Button[discord.ui.View]): - def __init__( - self, - label: str, - *, - ctx: custom.ExtContext, - instead: bridge.BridgeExtCommand | commands.Command[Any, Any, Any], - ) -> None: - self.ctx = ctx - self.instead = instead - super().__init__(style=discord.ButtonStyle.green, label=label) - - @override - async def callback(self, interaction: discord.Interaction) -> None: - if ( - not interaction.user - or not self.ctx.author # pyright: ignore[reportUnnecessaryComparison] - or interaction.user.id != self.ctx.author.id # pyright: ignore[reportFunctionMemberAccess] - ): - await interaction.respond(":x: Nope", ephemeral=True) - return - await self.instead.invoke(self.ctx) - await interaction.response.defer() - if interaction.message: - with contextlib.suppress(discord.HTTPException): - await interaction.message.delete() - - -def find_most_similar(word: str, word_list: list[str]) -> str | None: - if result := difflib.get_close_matches(word, word_list, n=1, cutoff=0.6): - return result[0] - return None - - -def find_similar_command( - ctx: custom.ExtContext, -) -> bridge.BridgeExtCommand | commands.Command[Any, Any, Any] | None: - command: str | None = ctx.invoked_with - if not command: - return None - if not isinstance(ctx.bot, custom.Bot): - return None - command_list: dict[str, bridge.BridgeExtCommand | commands.Command[Any, Any, Any]] = { - cmd.name: cmd - for cmd in ctx.bot.commands # pyright: ignore[reportUnknownVariableType] - } - similar_command: str | None = find_most_similar(command, list(command_list.keys())) - if similar_command: - return command_list.get(similar_command) - return None - - -def get_locale(ctx: custom.Context | discord.Interaction) -> str | None: - locale: str | None = None - if isinstance(ctx, custom.ApplicationContext): - locale = ctx.locale or ctx.guild_locale - elif isinstance(ctx, custom.ExtContext): - if ctx.guild: # pyright: ignore[reportUnnecessaryComparison] # for some reason pyright thinks guild is function - locale = ctx.guild.preferred_locale # pyright: ignore[reportFunctionMemberAccess] - elif isinstance(ctx, discord.Interaction): # pyright: ignore[reportUnnecessaryIsInstance] - locale = ctx.locale or ctx.guild_locale - return locale - - -T = TypeVar("T", bound=Coroutine[Any, Any, Any]) -type ErrorHandlersIType[T] = Callable[ - [Exception, discord.Interaction | custom.Context, TranslationWrapper, dict[str, Any], str, bool], T -] -type ErrorHandlerRType = tuple[bool, bool, str, dict[str, Any]] -type ErrorHandlerType = ErrorHandlersIType[Coroutine[Any, Any, ErrorHandlerRType]] -type ErrorHandlersType = dict[ - type[Exception], - ErrorHandlerType, -] - - -async def handle_command_not_found( # noqa: PLR0913 - error: Exception, # noqa: ARG001 - ctx: custom.Context | discord.Interaction, - translations: TranslationWrapper, - sendargs: dict[str, Any], - message: str, - report: bool, -) -> ErrorHandlerRType: - if not isinstance(ctx, custom.ExtContext): - return False, report, message, sendargs - if similar_command := find_similar_command(ctx): - message = translations.error_command_not_found.format(similar_command=similar_command.name) - view = discord.ui.View( - RunInsteadButton( - translations.run_x_instead.format(command=similar_command.name), - ctx=ctx, - instead=similar_command, - ), - disable_on_timeout=True, - timeout=60, # 1 minute - ) - sendargs["view"] = view - return False, False, message, sendargs - return True, False, message, sendargs - - -DEFAULT_ERROR_HANDLERS: ErrorHandlersType = { - commands.CommandNotFound: handle_command_not_found, -} - - -@final -class ErrorHandler: - def __init__(self, error_handlers: ErrorHandlersType | None = None) -> None: - if error_handlers: - self.error_handlers = DEFAULT_ERROR_HANDLERS | error_handlers - else: - self.error_handlers = DEFAULT_ERROR_HANDLERS - - def _get_handler(self, error: Exception) -> ErrorHandlerType | None: - if handler := self.error_handlers.get(type(error)): # faster but might miss subclasses - return handler - for error_type, handler in self.error_handlers.items(): # slower but catches subclasses - if issubclass(type(error), error_type): - return handler - return None - - async def handle_error( - self, - error: Exception | discord.ApplicationCommandInvokeError, - ctx: discord.Interaction | custom.Context, - /, - raw_translations: dict[str, RawTranslation], - use_sentry_sdk: bool = False, - ) -> None: - original_error = error - report: bool = True - sendargs: dict[str, Any] = {} - translations = apply_locale(raw_translations, get_locale(ctx)) - message: str = "" - if isinstance(error, discord.ApplicationCommandInvokeError): - original_error = error.original - - if handler := self._get_handler(original_error): - handled, report, message, sendargs = await handler( - original_error, - ctx, - translations, - sendargs, - str(error), - report, - ) - if handled: - return - elif isinstance(error, discord.Forbidden): - message = translations.error_missing_permissions + f"\n`{original_error.args[0].split(':')[-1].strip()}`" - else: - message = translations.error_generic - if report and use_sentry_sdk and sentry_sdk: - out = sentry_sdk.capture_exception(error) - message += f"\n\n-# {translations.reported_to_devs} - `{out}`" - await ctx.respond(message, ephemeral=True, **sendargs) - if report: - raise error - - def add_error_handler(self, error: type[Exception], handler: ErrorHandlerType) -> None: - self.error_handlers[error] = handler - - -error_handler = ErrorHandler() diff --git a/src/extensions/nice-errors/__init__.py b/src/extensions/nice_errors/__init__.py similarity index 100% rename from src/extensions/nice-errors/__init__.py rename to src/extensions/nice_errors/__init__.py diff --git a/src/extensions/nice_errors/handlers/__init__.py b/src/extensions/nice_errors/handlers/__init__.py new file mode 100644 index 0000000..c9114c5 --- /dev/null +++ b/src/extensions/nice_errors/handlers/__init__.py @@ -0,0 +1,6 @@ +# Copyright (c) NiceBots +# SPDX-License-Identifier: MIT + +from .base import ErrorHandlerManager + +error_handler = ErrorHandlerManager() diff --git a/src/extensions/nice_errors/handlers/base.py b/src/extensions/nice_errors/handlers/base.py new file mode 100644 index 0000000..b3f77a0 --- /dev/null +++ b/src/extensions/nice_errors/handlers/base.py @@ -0,0 +1,127 @@ +# Copyright (c) NiceBots.xyz +# SPDX-License-Identifier: MIT + +import contextlib +import logging +from abc import ABC, abstractmethod +from typing import Any, final, overload + +import discord + +from src import custom +from src.i18n.classes import RawTranslation, apply_locale + +logger = logging.getLogger("bot").getChild("nice_errors").getChild("handlers") +sentry_sdk = None + +with contextlib.suppress(ImportError): + import sentry_sdk + + +def _get_locale(ctx: custom.Context | discord.Interaction) -> str | None: + locale: str | None = None + if isinstance(ctx, custom.ApplicationContext): + locale = ctx.locale or ctx.guild_locale + elif isinstance(ctx, custom.ExtContext): + if ctx.guild: + locale = ctx.guild.preferred_locale + elif isinstance(ctx, discord.Interaction): # pyright: ignore[reportUnnecessaryIsInstance] + locale = ctx.locale or ctx.guild_locale + return locale + + +class BaseErrorHandler[E: Exception](ABC): + def __init__(self, error_cls: type[E]) -> None: + self.error_cls: type[E] = error_cls + + @abstractmethod + async def __call__( + self, + error: E, + ctx: custom.Context | discord.Interaction, + sendargs: dict[str, Any], + message: str, + report: bool, + ) -> "ErrorHandlerRType": ... + + @staticmethod + def _get_locale(ctx: custom.Context | discord.Interaction) -> str | None: + return _get_locale(ctx) + + +type ErrorHandlerRType = tuple[bool, bool, str, dict[str, Any]] +type ErrorHandlerType[E: Exception] = BaseErrorHandler[E] +type ErrorHandlersType[E: Exception] = dict[ + type[E] | None, + ErrorHandlerType[E], +] + + +@final +class ErrorHandlerManager: + def __init__(self, error_handlers: ErrorHandlersType[Exception] | None = None) -> None: + self.error_handlers: ErrorHandlersType[Exception] = error_handlers or {} + + def _get_handler(self, error: Exception) -> BaseErrorHandler[Exception] | None: + if handler := self.error_handlers.get(type(error)): + return handler + with contextlib.suppress(StopIteration): + return next( + filter(lambda x: x[0] is not None and issubclass(type(error), x[0]), self.error_handlers.items()) + )[1] + return None + + async def handle_error( + self, + error: Exception | discord.ApplicationCommandInvokeError, + ctx: discord.Interaction | custom.Context, + /, + raw_translations: dict[str, RawTranslation], + use_sentry_sdk: bool = False, + ) -> None: + original_error = error + report: bool = True + sendargs: dict[str, Any] = { + "ephemeral": True, + } + message: str = "" + translations = apply_locale(raw_translations, _get_locale(ctx)) + if isinstance(error, discord.ApplicationCommandInvokeError): + original_error = error.original + + handler = self._get_handler(original_error) or self.error_handlers.get(None) + if handler: + handled, report, message, sendargs = await handler( + original_error, + ctx, + sendargs, + str(error), + report, + ) + if handled: + return + if report and use_sentry_sdk and sentry_sdk: + out = sentry_sdk.capture_exception(error) + message += f"\n\n-# {translations.reported_to_devs} - `{out}`" + await ctx.respond(message, **sendargs) + if report: + raise error + + @overload + def add_error_handler[E: Exception](self, error: None, handler: ErrorHandlerType[Exception]) -> None: ... + + @overload + def add_error_handler[E: Exception](self, error: type[E], handler: ErrorHandlerType[E]) -> None: ... + + def add_error_handler[E: Exception](self, error: type[E] | None, handler: ErrorHandlerType[E | Exception]) -> None: + logger.info(f"Adding error handler {handler} for {error if error is not None else 'Generic'}") + self.error_handlers[error] = handler + + +__all__ = ( + "BaseErrorHandler", + "ErrorHandlerManager", + "ErrorHandlerRType", + "ErrorHandlerType", + "ErrorHandlersType", +) diff --git a/src/extensions/nice_errors/handlers/forbidden.py b/src/extensions/nice_errors/handlers/forbidden.py new file mode 100644 index 0000000..d041d57 --- /dev/null +++ b/src/extensions/nice_errors/handlers/forbidden.py @@ -0,0 +1,33 @@ +# Copyright (c) NiceBots +# SPDX-License-Identifier: MIT + +from typing import Any, final, override + +import discord + +from src import custom +from src.i18n.classes import RawTranslation, apply_locale + +from .base import BaseErrorHandler, ErrorHandlerRType + + +@final +class ForbiddenErrorHandler(BaseErrorHandler[discord.Forbidden]): + def __init__(self, translations: dict[str, RawTranslation]) -> None: + self.translations = translations + super().__init__(discord.Forbidden) + + @override + async def __call__( + self, + error: discord.Forbidden, + ctx: custom.Context | discord.Interaction, + sendargs: dict[str, Any], + message: str, + report: bool, + ) -> ErrorHandlerRType: + translations = apply_locale(self.translations, self._get_locale(ctx)) + + message = translations.error_missing_permissions + f"\n`{error.args[0].split(':')[-1].strip()}`" + + return False, report, message, sendargs diff --git a/src/extensions/nice_errors/handlers/generic.py b/src/extensions/nice_errors/handlers/generic.py new file mode 100644 index 0000000..79636c3 --- /dev/null +++ b/src/extensions/nice_errors/handlers/generic.py @@ -0,0 +1,33 @@ +# Copyright (c) NiceBots +# SPDX-License-Identifier: MIT + +from typing import Any, final, override + +import discord + +from src import custom +from src.i18n.classes import RawTranslation, apply_locale + +from .base import BaseErrorHandler, ErrorHandlerRType + + +@final +class GenericErrorHandler(BaseErrorHandler[Exception]): + def __init__(self, translations: dict[str, RawTranslation]) -> None: + self.translations = translations + super().__init__(Exception) + + @override + async def __call__( + self, + error: Exception, + ctx: custom.Context | discord.Interaction, + sendargs: dict[str, Any], + message: str, + report: bool, + ) -> ErrorHandlerRType: + translations = apply_locale(self.translations, self._get_locale(ctx)) + + message = translations.error_generic + + return False, report, message, sendargs diff --git a/src/extensions/nice_errors/handlers/not_found.py b/src/extensions/nice_errors/handlers/not_found.py new file mode 100644 index 0000000..e021455 --- /dev/null +++ b/src/extensions/nice_errors/handlers/not_found.py @@ -0,0 +1,94 @@ +# Copyright (c) NiceBots +# SPDX-License-Identifier: MIT + +import contextlib +import difflib +from typing import Any, final, override + +import discord +from discord.ext import bridge, commands + +from src import custom +from src.i18n.classes import RawTranslation, apply_locale + +from .base import BaseErrorHandler, ErrorHandlerRType + + +def find_most_similar(word: str, word_list: list[str]) -> str | None: + if result := difflib.get_close_matches(word, word_list, n=1, cutoff=0.6): + return result[0] + return None + + +def find_similar_command( + ctx: custom.ExtContext, +) -> bridge.BridgeExtCommand | commands.Command[Any, Any, Any] | None: + command: str | None = ctx.invoked_with + if not command: + return None + command_list: dict[str, bridge.BridgeExtCommand | commands.Command[Any, Any, Any]] = { + cmd.name: cmd + for cmd in ctx.bot.commands # pyright: ignore[reportUnknownVariableType] + } + similar_command: str | None = find_most_similar(command, list(command_list.keys())) + if similar_command: + return command_list.get(similar_command) + return None + + +class RunInsteadButton(discord.ui.Button[discord.ui.View]): + def __init__( + self, + label: str, + *, + ctx: custom.ExtContext, + instead: bridge.BridgeExtCommand | commands.Command[Any, Any, Any], + ) -> None: + self.ctx: custom.ExtContext = ctx + self.instead: bridge.BridgeExtCommand | commands.Command[Any, Any, Any] = instead + super().__init__(style=discord.ButtonStyle.green, label=label) + + @override + async def callback(self, interaction: discord.Interaction) -> None: + if not interaction.user or not self.ctx.author or interaction.user.id != self.ctx.author.id: + await interaction.respond(":x: Nope", ephemeral=True) + return + await self.instead.invoke(self.ctx) + await interaction.response.defer() + if interaction.message: + with contextlib.suppress(discord.HTTPException): + await interaction.message.delete() + + +@final +class NotFoundErrorHandler(BaseErrorHandler[commands.CommandNotFound]): + def __init__(self, translations: dict[str, RawTranslation]) -> None: + self.translations = translations + super().__init__(commands.CommandNotFound) + + @override + async def __call__( + self, + error: commands.CommandNotFound, + ctx: custom.Context | discord.Interaction, + sendargs: dict[str, Any], + message: str, + report: bool, + ) -> ErrorHandlerRType: + if not isinstance(ctx, custom.ExtContext): + return False, report, message, sendargs + translations = apply_locale(self.translations, self._get_locale(ctx)) + if similar_command := find_similar_command(ctx): + message = translations.error_command_not_found.format(similar_command=similar_command.name) + view = discord.ui.View( + RunInsteadButton( + translations.run_x_instead.format(command=similar_command.name), + ctx=ctx, + instead=similar_command, + ), + disable_on_timeout=True, + timeout=60, # 1 minute + ) + sendargs["view"] = view + return False, False, message, sendargs + return True, False, message, sendargs diff --git a/src/extensions/nice-errors/main.py b/src/extensions/nice_errors/main.py similarity index 72% rename from src/extensions/nice-errors/main.py rename to src/extensions/nice_errors/main.py index d482b40..0169315 100644 --- a/src/extensions/nice-errors/main.py +++ b/src/extensions/nice_errors/main.py @@ -1,15 +1,18 @@ # Copyright (c) NiceBots.xyz # SPDX-License-Identifier: MIT -from typing import Any +from typing import Any, final import discord from discord.ext import commands -from schema import Optional, Schema # pyright: ignore [reportMissingTypeStubs] +from schema import Optional, Schema from src import custom -from .handler import error_handler +from .handlers import error_handler +from .handlers.forbidden import ForbiddenErrorHandler +from .handlers.generic import GenericErrorHandler +from .handlers.not_found import NotFoundErrorHandler default = { "enabled": True, @@ -23,6 +26,7 @@ ) +@final class NiceErrors(commands.Cog): def __init__(self, bot: discord.Bot, sentry_sdk: bool, config: dict[str, Any]) -> None: self.bot = bot @@ -57,3 +61,6 @@ def add_error_handler(self, *args: Any, **kwargs: Any) -> None: def setup(bot: custom.Bot, config: dict[str, Any]) -> None: bot.add_cog(NiceErrors(bot, bool(config.get("sentry", {}).get("dsn")), config)) + error_handler.add_error_handler(None, GenericErrorHandler(config["translations"])) + error_handler.add_error_handler(commands.CommandNotFound, NotFoundErrorHandler(config["translations"])) + error_handler.add_error_handler(discord.Forbidden, ForbiddenErrorHandler(config["translations"])) diff --git a/src/extensions/nice-errors/patch.py b/src/extensions/nice_errors/patch.py similarity index 97% rename from src/extensions/nice-errors/patch.py rename to src/extensions/nice_errors/patch.py index 1bebcff..e744649 100644 --- a/src/extensions/nice-errors/patch.py +++ b/src/extensions/nice_errors/patch.py @@ -3,7 +3,7 @@ from typing import Any -from .handler import error_handler +from .handlers import error_handler async def patch(config: dict[str, Any]) -> None: diff --git a/src/extensions/nice-errors/readme.md b/src/extensions/nice_errors/readme.md similarity index 100% rename from src/extensions/nice-errors/readme.md rename to src/extensions/nice_errors/readme.md diff --git a/src/extensions/nice-errors/translations.yml b/src/extensions/nice_errors/translations.yml similarity index 100% rename from src/extensions/nice-errors/translations.yml rename to src/extensions/nice_errors/translations.yml diff --git a/src/utils/cooldown.py b/src/utils/cooldown.py index 772ade5..16cc2d5 100644 --- a/src/utils/cooldown.py +++ b/src/utils/cooldown.py @@ -9,14 +9,13 @@ from discord.ext import commands -import custom -from src.custom import Bot, Context +from src import custom -type ReactiveCooldownSetting[T] = T | Callable[[Bot, Context], T | Coroutine[Any, Any, T]] +type ReactiveCooldownSetting[T] = T | Callable[[custom.Bot, custom.Context], T | Coroutine[Any, Any, T]] type CogCommandFunction[T: commands.Cog, **P] = Callable[Concatenate[T, custom.ApplicationContext, P], Awaitable[None]] -async def parse_reactive_setting[T](value: ReactiveCooldownSetting[T], bot: Bot, ctx: Context) -> T: +async def parse_reactive_setting[T](value: ReactiveCooldownSetting[T], bot: custom.Bot, ctx: custom.Context) -> T: if callable(value): value = value(bot, ctx) # pyright: ignore [reportAssignmentType] if isawaitable(value): @@ -56,7 +55,7 @@ async def wrapper(self: C, ctx: custom.ApplicationContext, *args: P.args, **kwar time_stamps = time_stamps[-limit_value:] if len(time_stamps) < limit_value or strong_value: time_stamps = (*time_stamps, now) - await cache.set(key_value, time_stamps, namespace="cooldown") + await cache.set(key_value, time_stamps, namespace="cooldown", ttl=per_value) limit_value += 1 # to account for the current command if len(time_stamps) >= limit_value: From 80c03e52ec3385bfb902257e3a6e7d74f76a517b Mon Sep 17 00:00:00 2001 From: Paillat Date: Wed, 13 Nov 2024 10:25:09 +0100 Subject: [PATCH 13/61] :adhesive_bandage: Small bugfix --- src/__init__.py | 1 + src/extensions/__init__.py | 1 + src/start.py | 4 +++- 3 files changed, 5 insertions(+), 1 deletion(-) create mode 100644 src/__init__.py create mode 100644 src/extensions/__init__.py diff --git a/src/__init__.py b/src/__init__.py new file mode 100644 index 0000000..8e05d9a --- /dev/null +++ b/src/__init__.py @@ -0,0 +1 @@ +# Copyright (c) NiceBots all rights reserved diff --git a/src/extensions/__init__.py b/src/extensions/__init__.py new file mode 100644 index 0000000..8e05d9a --- /dev/null +++ b/src/extensions/__init__.py @@ -0,0 +1 @@ +# Copyright (c) NiceBots all rights reserved diff --git a/src/start.py b/src/start.py index 273a415..78840a6 100644 --- a/src/start.py +++ b/src/start.py @@ -78,8 +78,10 @@ def load_extensions() -> ( translations: list[ExtensionTranslation] = [] for extension in iglob("src/extensions/*"): name = splitext(basename(extension))[0] + if name.endswith(("_", "_/", ".py")): + continue - its_config = config["extensions"].get(name, {}) + its_config = config["extensions"].get(name, config["extensions"].get(name.replace("_", "-"), {})) module: ModuleType = importlib.import_module(f"src.extensions.{name}") if not its_config: its_config = module.default From cae833ddc8a1f670faf535e82a825e76e09b2967 Mon Sep 17 00:00:00 2001 From: Paillat Date: Fri, 15 Nov 2024 09:18:44 +0100 Subject: [PATCH 14/61] :adhesive_bandage: Now it works better --- src/__main__.py | 6 ++- src/extensions/nice_errors/handlers/base.py | 5 +-- src/extensions/nice_errors/patch.py | 44 ++++++++++----------- tests/schema_test.py | 2 + 4 files changed, 29 insertions(+), 28 deletions(-) diff --git a/src/__main__.py b/src/__main__.py index 7a959c3..e315ba6 100644 --- a/src/__main__.py +++ b/src/__main__.py @@ -18,7 +18,11 @@ async def load_and_run_patches() -> None: for patch_file in iglob("src/extensions/*/patch.py"): extension = os.path.basename(os.path.dirname(patch_file)) - if config["extensions"].get(extension, {}).get("enabled", False): + if ( + config["extensions"] + .get(extension, config["extensions"].get(extension.replace("_", "-"))) + .get("enabled", False) + ): logger.info(f"Loading patch for extension {extension}") spec = importlib.util.spec_from_file_location(f"src.extensions.{extension}.patch", patch_file) if not spec or not spec.loader: diff --git a/src/extensions/nice_errors/handlers/base.py b/src/extensions/nice_errors/handlers/base.py index b3f77a0..5ce7384 100644 --- a/src/extensions/nice_errors/handlers/base.py +++ b/src/extensions/nice_errors/handlers/base.py @@ -7,15 +7,12 @@ from typing import Any, final, overload import discord +import sentry_sdk from src import custom from src.i18n.classes import RawTranslation, apply_locale logger = logging.getLogger("bot").getChild("nice_errors").getChild("handlers") -sentry_sdk = None - -with contextlib.suppress(ImportError): - import sentry_sdk def _get_locale(ctx: custom.Context | discord.Interaction) -> str | None: diff --git a/src/extensions/nice_errors/patch.py b/src/extensions/nice_errors/patch.py index e744649..5a8663b 100644 --- a/src/extensions/nice_errors/patch.py +++ b/src/extensions/nice_errors/patch.py @@ -1,7 +1,7 @@ # Copyright (c) NiceBots.xyz # SPDX-License-Identifier: MIT -from typing import Any +from typing import TYPE_CHECKING, Any from .handlers import error_handler @@ -30,25 +30,23 @@ async def patch(config: dict[str, Any]) -> None: ), ) - from typing import override - - import discord - from discord import Interaction - from discord.ui import Item - - class PatchedView(discord.ui.View): - @override - async def on_error( - self, - error: Exception, - item: Item, # pyright: ignore[reportMissingTypeArgument,reportUnknownParameterType] - interaction: Interaction, - ) -> None: - await error_handler.handle_error( - error, - interaction, - raw_translations=config["translations"], - use_sentry_sdk=bool(sentry_sdk), - ) - - discord.ui.View = PatchedView + from discord.ui import View + + if TYPE_CHECKING: + from discord import Interaction + from discord.ui import Item + + async def on_error( + self: View, # noqa: ARG001 + error: Exception, + item: "Item[View]", # noqa: ARG001 + interaction: "Interaction", + ) -> None: + await error_handler.handle_error( + error, + interaction, + raw_translations=config["translations"], + use_sentry_sdk=bool(sentry_sdk), + ) + + View.on_error = on_error diff --git a/tests/schema_test.py b/tests/schema_test.py index 3cd9bf6..2bff7ff 100644 --- a/tests/schema_test.py +++ b/tests/schema_test.py @@ -12,6 +12,8 @@ def test_ext_schemas() -> None: """Test the schemas of all extensions.""" for ext in iglob("src/extensions/*"): name = splitext(basename(ext))[0] + if name.endswith(("_", "_/", ".py")): + continue module = importlib.import_module(f"src.extensions.{name}") validate_module(module) del module From 5af5350f0f677d41754a2f23e50a33a9c99d5eb1 Mon Sep 17 00:00:00 2001 From: Paillat Date: Fri, 15 Nov 2024 14:09:51 +0100 Subject: [PATCH 15/61] :adhesive_bandage: Very small minor fix --- pyproject.toml | 1 + src/extensions/listings/main.py | 2 +- src/utils/cooldown.py | 2 +- 3 files changed, 3 insertions(+), 2 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index 4d6343b..6ce0b7a 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -102,5 +102,6 @@ extend-ignore = [ "D203", "FBT001", "FBT002", + "PLR2004", "C901" ] diff --git a/src/extensions/listings/main.py b/src/extensions/listings/main.py index 105cc75..875ce76 100644 --- a/src/extensions/listings/main.py +++ b/src/extensions/listings/main.py @@ -36,7 +36,7 @@ async def try_post_request(url: str, headers: dict[Any, Any], payload: dict[Any, try: await post_request(url, headers, payload) except aiohttp.ClientResponseError as e: - if e.status == 401: # noqa: PLR2004 + if e.status == 401: logger.error("Invalid token") else: logger.error(e) diff --git a/src/utils/cooldown.py b/src/utils/cooldown.py index 16cc2d5..dbb4273 100644 --- a/src/utils/cooldown.py +++ b/src/utils/cooldown.py @@ -50,7 +50,7 @@ async def wrapper(self: C, ctx: custom.ApplicationContext, *args: P.args, **kwar strong_value = await parse_reactive_setting(strong, ctx.bot, ctx) now = time.time() - time_stamps = cast(tuple[float, ...], await cache.get(key, default=(), namespace="cooldown")) + time_stamps = cast(tuple[float, ...], await cache.get(key_value, default=(), namespace="cooldown")) time_stamps = tuple(filter(lambda x: x > now - per_value, time_stamps)) time_stamps = time_stamps[-limit_value:] if len(time_stamps) < limit_value or strong_value: From 129b15c61ca4ec200ab38d8936ef1839f73d3599 Mon Sep 17 00:00:00 2001 From: Paillat Date: Fri, 15 Nov 2024 14:22:51 +0100 Subject: [PATCH 16/61] :adhesive_bandage: Cooldown reactive cls --- src/utils/cooldown.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/utils/cooldown.py b/src/utils/cooldown.py index dbb4273..ffe985d 100644 --- a/src/utils/cooldown.py +++ b/src/utils/cooldown.py @@ -38,7 +38,7 @@ def cooldown[C: commands.Cog, **P]( limit: ReactiveCooldownSetting[int], per: ReactiveCooldownSetting[int], strong: ReactiveCooldownSetting[bool] = False, - cls: type[CooldownExceeded] = CooldownExceeded, + cls: ReactiveCooldownSetting[type[CooldownExceeded]] = CooldownExceeded, ) -> Callable[[CogCommandFunction[C, P]], CogCommandFunction[C, P]]: def inner(func: CogCommandFunction[C, P]) -> CogCommandFunction[C, P]: @wraps(func) @@ -48,6 +48,7 @@ async def wrapper(self: C, ctx: custom.ApplicationContext, *args: P.args, **kwar limit_value = await parse_reactive_setting(limit, ctx.bot, ctx) per_value = await parse_reactive_setting(per, ctx.bot, ctx) strong_value = await parse_reactive_setting(strong, ctx.bot, ctx) + cls_value = await parse_reactive_setting(cls, ctx.bot, ctx) now = time.time() time_stamps = cast(tuple[float, ...], await cache.get(key_value, default=(), namespace="cooldown")) @@ -59,7 +60,7 @@ async def wrapper(self: C, ctx: custom.ApplicationContext, *args: P.args, **kwar limit_value += 1 # to account for the current command if len(time_stamps) >= limit_value: - raise cls(min(time_stamps) - now + per_value) + raise cls_value(min(time_stamps) - now + per_value) await func(self, ctx, *args, **kwargs) return wrapper From c87347e81ed28eae41a2ec6da630b679bc966200 Mon Sep 17 00:00:00 2001 From: Paillat Date: Fri, 15 Nov 2024 15:42:37 +0100 Subject: [PATCH 17/61] :bug: Cooldown reactive cls fix --- src/utils/cooldown.py | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/src/utils/cooldown.py b/src/utils/cooldown.py index ffe985d..69beae7 100644 --- a/src/utils/cooldown.py +++ b/src/utils/cooldown.py @@ -11,11 +11,13 @@ from src import custom -type ReactiveCooldownSetting[T] = T | Callable[[custom.Bot, custom.Context], T | Coroutine[Any, Any, T]] +type ReactiveCooldownSetting[T: Any] = T | Callable[[custom.Bot, custom.Context], T | Coroutine[Any, Any, T]] type CogCommandFunction[T: commands.Cog, **P] = Callable[Concatenate[T, custom.ApplicationContext, P], Awaitable[None]] async def parse_reactive_setting[T](value: ReactiveCooldownSetting[T], bot: custom.Bot, ctx: custom.Context) -> T: + if isinstance(value, type): + return value # pyright: ignore [reportReturnType] if callable(value): value = value(bot, ctx) # pyright: ignore [reportAssignmentType] if isawaitable(value): @@ -44,12 +46,11 @@ def inner(func: CogCommandFunction[C, P]) -> CogCommandFunction[C, P]: @wraps(func) async def wrapper(self: C, ctx: custom.ApplicationContext, *args: P.args, **kwargs: P.kwargs) -> None: cache = ctx.bot.cache - key_value = await parse_reactive_setting(key, ctx.bot, ctx) - limit_value = await parse_reactive_setting(limit, ctx.bot, ctx) - per_value = await parse_reactive_setting(per, ctx.bot, ctx) - strong_value = await parse_reactive_setting(strong, ctx.bot, ctx) - cls_value = await parse_reactive_setting(cls, ctx.bot, ctx) - + key_value: str = await parse_reactive_setting(key, ctx.bot, ctx) + limit_value: int = await parse_reactive_setting(limit, ctx.bot, ctx) + per_value: int = await parse_reactive_setting(per, ctx.bot, ctx) + strong_value: bool = await parse_reactive_setting(strong, ctx.bot, ctx) + cls_value: type[CooldownExceeded] = await parse_reactive_setting(cls, ctx.bot, ctx) now = time.time() time_stamps = cast(tuple[float, ...], await cache.get(key_value, default=(), namespace="cooldown")) time_stamps = tuple(filter(lambda x: x > now - per_value, time_stamps)) From 0cfd2fee3434e91e0961da3a87a0f9727cf9e3a3 Mon Sep 17 00:00:00 2001 From: Paillat Date: Mon, 18 Nov 2024 10:03:29 +0100 Subject: [PATCH 18/61] :goal_net: Better error handling of status push --- src/extensions/status-post/main.py | 21 ++++++++++++++------- 1 file changed, 14 insertions(+), 7 deletions(-) diff --git a/src/extensions/status-post/main.py b/src/extensions/status-post/main.py index 8b22e36..77fd518 100644 --- a/src/extensions/status-post/main.py +++ b/src/extensions/status-post/main.py @@ -1,6 +1,9 @@ # Copyright (c) NiceBots.xyz # SPDX-License-Identifier: MIT +import math +from typing import Any + import aiohttp import discord from discord.ext import commands, tasks @@ -24,16 +27,16 @@ class Status(commands.Cog): - def __init__(self, bot: discord.Bot, config: dict) -> None: - self.bot = bot - self.config = config - self.push_status_loop = tasks.loop(seconds=self.config["every"])(self.push_status_loop) + def __init__(self, bot: discord.Bot, config: dict[Any, Any]) -> None: + self.bot: discord.Bot = bot + self.config: dict[Any, Any] = config + self.push_status_loop: tasks.Loop = tasks.loop(seconds=self.config["every"])(self.push_status_loop_meth) # pyright: ignore [reportMissingTypeArgument] @commands.Cog.listener(once=True) async def on_ready(self) -> None: self.push_status_loop.start() - async def push_status_loop(self) -> None: + async def push_status_loop_meth(self) -> None: try: await self.push_status() logger.info("Pushed status.") @@ -41,10 +44,14 @@ async def push_status_loop(self) -> None: logger.exception("Failed to push status.") async def push_status(self) -> None: - ping = str(round(self.bot.latency * 1000)) + latency = self.bot.latency + if latency == float("inf") or math.isnan(latency): + logger.warning("Latency is infinite or NaN, skipping status push.") + return + ping = str(round(latency * 1000)) async with aiohttp.ClientSession() as session, session.get(self.config["url"] + ping) as resp: resp.raise_for_status() -def setup(bot: discord.Bot, config: dict) -> None: +def setup(bot: discord.Bot, config: dict[Any, Any]) -> None: bot.add_cog(Status(bot, config)) From bfd96207816c54b1731b13f9744124d3e94d6cb8 Mon Sep 17 00:00:00 2001 From: Paillat Date: Sat, 30 Nov 2024 11:17:06 +0100 Subject: [PATCH 19/61] :construction_worker: Better actions --- .github/workflows/CI-CD.yaml | 2 ++ .github/workflows/sync_template.yaml | 21 +++++++++++++++++++++ 2 files changed, 23 insertions(+) create mode 100644 .github/workflows/sync_template.yaml diff --git a/.github/workflows/CI-CD.yaml b/.github/workflows/CI-CD.yaml index c96b6ef..2dc759b 100644 --- a/.github/workflows/CI-CD.yaml +++ b/.github/workflows/CI-CD.yaml @@ -1,4 +1,6 @@ #file: noinspection SpellCheckingInspection +name: CI/CD + on: push: branches: [ "main", "dev" ] diff --git a/.github/workflows/sync_template.yaml b/.github/workflows/sync_template.yaml new file mode 100644 index 0000000..f36a1cc --- /dev/null +++ b/.github/workflows/sync_template.yaml @@ -0,0 +1,21 @@ +name: Sync Template + +on: + schedule: + - cron: "0 0 1 * *" + workflow_dispatch: +jobs: + repo-sync: + runs-on: ubuntu-latest + if: github.repository != 'nicebots-xyz/botkit' + steps: + - name: Checkout + uses: actions/checkout@v3 + - name: actions-template-sync + uses: AndreasAugustin/actions-template-sync@v0.4.2-draft + with: + github_token: ${{ secrets.GITHUB_TOKEN }} + source_repo_path: nicebots-xyz/botkit + upstream_branch: dev + commit_message: "core: :twisted_rightwards_arrows: Merge remote template" + pr_title: "core: :twisted_rightwards_arrows: Merge remote template" \ No newline at end of file From f1cfeee82698a5922406514a4c5de41ecafdf50d Mon Sep 17 00:00:00 2001 From: Paillat Date: Sat, 30 Nov 2024 11:23:01 +0100 Subject: [PATCH 20/61] :construction_worker: Even better actions --- .github/workflows/sync_template.yaml | 23 ++++++++++++++++++----- 1 file changed, 18 insertions(+), 5 deletions(-) diff --git a/.github/workflows/sync_template.yaml b/.github/workflows/sync_template.yaml index f36a1cc..b05f053 100644 --- a/.github/workflows/sync_template.yaml +++ b/.github/workflows/sync_template.yaml @@ -1,21 +1,34 @@ -name: Sync Template +# File: .github/workflows/template-sync.yml on: + # cronjob trigger schedule: - - cron: "0 0 1 * *" + - cron: "0 0 1 * *" + # manual trigger workflow_dispatch: jobs: repo-sync: runs-on: ubuntu-latest + # https://docs.github.com/en/actions/using-jobs/assigning-permissions-to-jobs + permissions: + contents: write + pull-requests: write if: github.repository != 'nicebots-xyz/botkit' + steps: + # To use this repository's private action, you must check out the repository - name: Checkout - uses: actions/checkout@v3 + uses: actions/checkout@v4 + # https://github.com/actions/checkout#usage + # uncomment if you use submodules within the repository + # with: + # submodules: true + - name: actions-template-sync - uses: AndreasAugustin/actions-template-sync@v0.4.2-draft + uses: AndreasAugustin/actions-template-sync@v2 with: github_token: ${{ secrets.GITHUB_TOKEN }} source_repo_path: nicebots-xyz/botkit upstream_branch: dev - commit_message: "core: :twisted_rightwards_arrows: Merge remote template" + pr_commit_msg: "core: :twisted_rightwards_arrows: Merge remote template" pr_title: "core: :twisted_rightwards_arrows: Merge remote template" \ No newline at end of file From 47c01abf33ee113cf45a0482f277b7c1f4e1dc23 Mon Sep 17 00:00:00 2001 From: Paillat Date: Sat, 30 Nov 2024 11:25:11 +0100 Subject: [PATCH 21/61] :construction_worker: Add name to "sync_template" --- .github/workflows/sync_template.yaml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/sync_template.yaml b/.github/workflows/sync_template.yaml index b05f053..6967f5b 100644 --- a/.github/workflows/sync_template.yaml +++ b/.github/workflows/sync_template.yaml @@ -1,4 +1,5 @@ # File: .github/workflows/template-sync.yml +name: Template Sync on: # cronjob trigger From 3392bafc595c5c988cdce21b1a48d4ad3e86a710 Mon Sep 17 00:00:00 2001 From: Paillat Date: Sat, 30 Nov 2024 11:56:57 +0100 Subject: [PATCH 22/61] :construction_worker: Incredible actions" --- .github/workflows/sync_template.yaml | 25 ++++++----- .github/workflows/update_dependencies.yaml | 52 +++++++++++++++++----- .templatesyncignore | 3 ++ 3 files changed, 59 insertions(+), 21 deletions(-) create mode 100644 .templatesyncignore diff --git a/.github/workflows/sync_template.yaml b/.github/workflows/sync_template.yaml index 6967f5b..b7d985a 100644 --- a/.github/workflows/sync_template.yaml +++ b/.github/workflows/sync_template.yaml @@ -1,35 +1,38 @@ -# File: .github/workflows/template-sync.yml name: Template Sync on: - # cronjob trigger schedule: - cron: "0 0 1 * *" - # manual trigger workflow_dispatch: + jobs: repo-sync: runs-on: ubuntu-latest - # https://docs.github.com/en/actions/using-jobs/assigning-permissions-to-jobs permissions: contents: write pull-requests: write if: github.repository != 'nicebots-xyz/botkit' steps: - # To use this repository's private action, you must check out the repository - name: Checkout uses: actions/checkout@v4 - # https://github.com/actions/checkout#usage - # uncomment if you use submodules within the repository - # with: - # submodules: true - - name: actions-template-sync + - name: Template Sync + id: template-sync uses: AndreasAugustin/actions-template-sync@v2 with: github_token: ${{ secrets.GITHUB_TOKEN }} source_repo_path: nicebots-xyz/botkit upstream_branch: dev pr_commit_msg: "core: :twisted_rightwards_arrows: Merge remote template" - pr_title: "core: :twisted_rightwards_arrows: Merge remote template" \ No newline at end of file + pr_title: "core: :twisted_rightwards_arrows: Merge remote template" + + update-deps: + needs: repo-sync + if: needs.repo-sync.outputs.pr_branch + uses: ./.github/workflows/update-dependencies.yml + with: + pr_branch: ${{ needs.repo-sync.outputs.pr_branch }} + permissions: + contents: write + pull-requests: write diff --git a/.github/workflows/update_dependencies.yaml b/.github/workflows/update_dependencies.yaml index aaffd60..32bf14f 100644 --- a/.github/workflows/update_dependencies.yaml +++ b/.github/workflows/update_dependencies.yaml @@ -1,39 +1,71 @@ -name: Update Dependencies - +name: Update dependencies on: schedule: - cron: '0 0 * * 0' # Runs at 00:00 every Sunday - workflow_dispatch: # Allows manual triggering + workflow_dispatch: + inputs: + pr_branch: + description: 'Branch to push changes to (optional)' + required: false + type: string + workflow_call: + inputs: + pr_branch: + description: 'Branch to push changes to' + required: true + type: string jobs: - update-dependencies: + update-deps: runs-on: ubuntu-latest permissions: contents: write pull-requests: write steps: - uses: actions/checkout@v4 + - name: Setup PDM uses: pdm-project/setup-pdm@v4 with: cache: true + - name: Lock dependencies run: pdm lock + - name: Export requirements run: pdm run export + - name: Check for changes id: git-check run: | git diff --exit-code --quiet requirements.txt || echo "changed=true" >> $GITHUB_OUTPUT - - name: Create Pull Request + + - name: Handle dependency updates if: steps.git-check.outputs.changed == 'true' run: | git config user.name github-actions git config user.email github-actions@github.com - git checkout -b update-dependencies-${{ github.run_id }} - git add requirements.txt pyproject.toml pdm.lock - git commit -m "Update dependencies" - git push origin update-dependencies-${{ github.run_id }} - gh pr create --title "Update dependencies" --body "This PR updates the project dependencies. Please review the changes and merge if everything looks good." --base ${{ github.ref_name }} --head update-dependencies-${{ github.run_id }} + + if [ -n "${{ inputs.pr_branch }}" ]; then + # Push to existing branch + BRANCH_NAME=$(echo ${{ inputs.pr_branch }} | cut -d'/' -f 3) + git checkout $BRANCH_NAME + git add requirements.txt pyproject.toml pdm.lock + git commit -m "Update dependencies" + git push origin $BRANCH_NAME + else + # Create new branch and PR + NEW_BRANCH="update-dependencies-${{ github.run_id }}" + git checkout -b $NEW_BRANCH + git add requirements.txt pyproject.toml pdm.lock + git commit -m "Update dependencies" + git push origin $NEW_BRANCH + + gh pr create \ + --title "Update dependencies" \ + --body "This PR updates the project dependencies. Please review the changes and merge if everything looks good." \ + --base ${{ github.ref_name }} \ + --head $NEW_BRANCH + fi env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} \ No newline at end of file diff --git a/.templatesyncignore b/.templatesyncignore new file mode 100644 index 0000000..2a0b916 --- /dev/null +++ b/.templatesyncignore @@ -0,0 +1,3 @@ +.copywrite.hcl +requirements.txt +pdm.lock From 3cc4f85920e1d828797cfd2a0ccea8e6214cc418 Mon Sep 17 00:00:00 2001 From: Paillat Date: Sat, 30 Nov 2024 12:00:14 +0100 Subject: [PATCH 23/61] :pencil2: typo --- .github/workflows/sync_template.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/sync_template.yaml b/.github/workflows/sync_template.yaml index b7d985a..7d77e51 100644 --- a/.github/workflows/sync_template.yaml +++ b/.github/workflows/sync_template.yaml @@ -30,7 +30,7 @@ jobs: update-deps: needs: repo-sync if: needs.repo-sync.outputs.pr_branch - uses: ./.github/workflows/update-dependencies.yml + uses: ./.github/workflows/update_dependencies.yaml with: pr_branch: ${{ needs.repo-sync.outputs.pr_branch }} permissions: From f5e9dbdd27718e1133ef16d3ac96208552205c82 Mon Sep 17 00:00:00 2001 From: Paillat Date: Sat, 30 Nov 2024 12:15:32 +0100 Subject: [PATCH 24/61] aeeee --- .github/workflows/update_dependencies.yaml | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/.github/workflows/update_dependencies.yaml b/.github/workflows/update_dependencies.yaml index 32bf14f..1d1b850 100644 --- a/.github/workflows/update_dependencies.yaml +++ b/.github/workflows/update_dependencies.yaml @@ -23,7 +23,12 @@ jobs: pull-requests: write steps: - uses: actions/checkout@v4 - + name: Checkout repository + - name: Checkout target branch + if: inputs.pr_branch + run: | + BRANCH_NAME=$(echo ${{ inputs.pr_branch }} | cut -d'/' -f 3) + git checkout $BRANCH_NAME - name: Setup PDM uses: pdm-project/setup-pdm@v4 with: From 053178ba525c1acbe4e9ecdf006863f1947346d0 Mon Sep 17 00:00:00 2001 From: Paillat Date: Sat, 30 Nov 2024 12:19:51 +0100 Subject: [PATCH 25/61] aeeee2 --- .github/workflows/sync_template.yaml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.github/workflows/sync_template.yaml b/.github/workflows/sync_template.yaml index 7d77e51..eadb1a0 100644 --- a/.github/workflows/sync_template.yaml +++ b/.github/workflows/sync_template.yaml @@ -12,11 +12,12 @@ jobs: contents: write pull-requests: write if: github.repository != 'nicebots-xyz/botkit' + outputs: + pr_branch: ${{ steps.template-sync.outputs.pr_branch }} steps: - name: Checkout uses: actions/checkout@v4 - - name: Template Sync id: template-sync uses: AndreasAugustin/actions-template-sync@v2 From af7fcb3fc59c99a83efdc2ea5465720d27e61ee2 Mon Sep 17 00:00:00 2001 From: Paillat Date: Sat, 30 Nov 2024 19:58:24 +0100 Subject: [PATCH 26/61] :art: format & lint --- .pre-commit-config.yaml | 2 +- pdm.lock | 173 ++++++++++---------- pyproject.toml | 1 - scripts/check_listings/__main__.py | 2 +- scripts/check_listings/listings/__init__.py | 12 +- scripts/check_listings/main.py | 2 +- src/custom/__init__.py | 2 +- src/extensions/add-dm/__init__.py | 2 +- src/extensions/branding/__init__.py | 2 +- src/extensions/listings/__init__.py | 2 +- src/extensions/nice_errors/__init__.py | 2 +- src/extensions/ping/__init__.py | 2 +- src/extensions/status-post/__init__.py | 2 +- src/i18n/__init__.py | 2 +- src/utils/__init__.py | 2 +- 15 files changed, 107 insertions(+), 103 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index d4ef2b9..6f2b1ad 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -21,7 +21,7 @@ repos: exclude: \.(po|pot|yml|yaml)$ - repo: https://github.com/astral-sh/ruff-pre-commit # Ruff version. - rev: v0.7.3 + rev: v0.8.1 hooks: # Run the linter. - id: ruff diff --git a/pdm.lock b/pdm.lock index 47b4406..f332501 100644 --- a/pdm.lock +++ b/pdm.lock @@ -73,36 +73,37 @@ files = [ [[package]] name = "aiohttp" -version = "3.10.10" -requires_python = ">=3.8" +version = "3.11.8" +requires_python = ">=3.9" summary = "Async http client/server framework (asyncio)" groups = ["default"] dependencies = [ "aiohappyeyeballs>=2.3.0", "aiosignal>=1.1.2", - "async-timeout<5.0,>=4.0; python_version < \"3.11\"", + "async-timeout<6.0,>=4.0; python_version < \"3.11\"", "attrs>=17.3.0", "frozenlist>=1.1.1", "multidict<7.0,>=4.5", - "yarl<2.0,>=1.12.0", + "propcache>=0.2.0", + "yarl<2.0,>=1.17.0", ] files = [ - {file = "aiohttp-3.10.10-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:9294bbb581f92770e6ed5c19559e1e99255e4ca604a22c5c6397b2f9dd3ee42c"}, - {file = "aiohttp-3.10.10-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:a8fa23fe62c436ccf23ff930149c047f060c7126eae3ccea005f0483f27b2e28"}, - {file = "aiohttp-3.10.10-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:5c6a5b8c7926ba5d8545c7dd22961a107526562da31a7a32fa2456baf040939f"}, - {file = "aiohttp-3.10.10-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:007ec22fbc573e5eb2fb7dec4198ef8f6bf2fe4ce20020798b2eb5d0abda6138"}, - {file = "aiohttp-3.10.10-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:9627cc1a10c8c409b5822a92d57a77f383b554463d1884008e051c32ab1b3742"}, - {file = "aiohttp-3.10.10-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:50edbcad60d8f0e3eccc68da67f37268b5144ecc34d59f27a02f9611c1d4eec7"}, - {file = "aiohttp-3.10.10-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a45d85cf20b5e0d0aa5a8dca27cce8eddef3292bc29d72dcad1641f4ed50aa16"}, - {file = "aiohttp-3.10.10-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0b00807e2605f16e1e198f33a53ce3c4523114059b0c09c337209ae55e3823a8"}, - {file = "aiohttp-3.10.10-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:f2d4324a98062be0525d16f768a03e0bbb3b9fe301ceee99611dc9a7953124e6"}, - {file = "aiohttp-3.10.10-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:438cd072f75bb6612f2aca29f8bd7cdf6e35e8f160bc312e49fbecab77c99e3a"}, - {file = "aiohttp-3.10.10-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:baa42524a82f75303f714108fea528ccacf0386af429b69fff141ffef1c534f9"}, - {file = "aiohttp-3.10.10-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:a7d8d14fe962153fc681f6366bdec33d4356f98a3e3567782aac1b6e0e40109a"}, - {file = "aiohttp-3.10.10-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:c1277cd707c465cd09572a774559a3cc7c7a28802eb3a2a9472588f062097205"}, - {file = "aiohttp-3.10.10-cp312-cp312-win32.whl", hash = "sha256:59bb3c54aa420521dc4ce3cc2c3fe2ad82adf7b09403fa1f48ae45c0cbde6628"}, - {file = "aiohttp-3.10.10-cp312-cp312-win_amd64.whl", hash = "sha256:0e1b370d8007c4ae31ee6db7f9a2fe801a42b146cec80a86766e7ad5c4a259cf"}, - {file = "aiohttp-3.10.10.tar.gz", hash = "sha256:0631dd7c9f0822cc61c88586ca76d5b5ada26538097d0f1df510b082bad3411a"}, + {file = "aiohttp-3.11.8-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:0e3b5bfef913d6be270c81976fbc0cbf66625cd92663bbb7e03b3adbd6aa4ac6"}, + {file = "aiohttp-3.11.8-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:cb51a81cb637b9a072c9cfae1839e35c6579638861eb3479eb5d6e6ce8bc6782"}, + {file = "aiohttp-3.11.8-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:dd2ca84e5f7a35f313a62eb7d6a50bac6760b60bafce34586750712731c0aeff"}, + {file = "aiohttp-3.11.8-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:47c6663df9446aa848b478413219600da4b54bc0409e1ac4bc80fb1a81501363"}, + {file = "aiohttp-3.11.8-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:c665ed4b52256614858b20711bbbd2755b0e19ec86870f8ff1645acf9ae9e760"}, + {file = "aiohttp-3.11.8-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:35d4545e7684da7a954ffc2dce495462cb16a902dffdebe98572408f6aaaee83"}, + {file = "aiohttp-3.11.8-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:85be3899e6860dd2cd3f4370ded6708e939d00d5ec922a8eb328d114db605a47"}, + {file = "aiohttp-3.11.8-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a0ed9f1f2697713c48efc9ec483ad5d062e4aa91854f090a3eba0b19c002851d"}, + {file = "aiohttp-3.11.8-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:c0dbae99737badf3f5e862088a118e28d3b36f03eb608a6382eddfd68178e05b"}, + {file = "aiohttp-3.11.8-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:beae08f900b2980af4353a0200eb162b39f276fd8a6e43079a540f83964671f4"}, + {file = "aiohttp-3.11.8-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:d6f9e5fd1b3ecbaca3e04a15a02d1fa213248608caee99fd5bdddd4759959cf7"}, + {file = "aiohttp-3.11.8-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:a7def89a41fe32120d89cd4577f5efbab3c52234c5890066ced8a2f7202dff88"}, + {file = "aiohttp-3.11.8-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:98f596cf59292e779bc387f22378a3d2c5e052c9fe2bf822ac4f547c6fe57758"}, + {file = "aiohttp-3.11.8-cp312-cp312-win32.whl", hash = "sha256:b64fa6b76b35b695cd3e5c42a4e568cbea8d41c9e59165e2a43da00976e2027e"}, + {file = "aiohttp-3.11.8-cp312-cp312-win_amd64.whl", hash = "sha256:afba47981ff73b1794c00dce774334dcfe62664b3b4f78f278b77d21ce9daf43"}, + {file = "aiohttp-3.11.8.tar.gz", hash = "sha256:7bc9d64a2350cbb29a9732334e1a0743cbb6844de1731cbdf5949b235653f3fd"}, ] [[package]] @@ -149,7 +150,7 @@ files = [ [[package]] name = "basedpyright" -version = "1.21.0" +version = "1.22.0" requires_python = ">=3.8" summary = "static type checking for Python (but based)" groups = ["dev"] @@ -157,8 +158,8 @@ dependencies = [ "nodejs-wheel-binaries>=20.13.1", ] files = [ - {file = "basedpyright-1.21.0-py3-none-any.whl", hash = "sha256:48902c476d6301c556df6eeae9acf1e34b176b14f8702ad5c770f4e6a747018a"}, - {file = "basedpyright-1.21.0.tar.gz", hash = "sha256:e3a9f5b89acc7f23d5a10d95ea6056b2247fcd15b8b248ad44c560c85c39d5e3"}, + {file = "basedpyright-1.22.0-py3-none-any.whl", hash = "sha256:6376107086ad25525429b8a94a2ffdb67c6dd2b1a6be38bf3c6ea9b5c3d1f688"}, + {file = "basedpyright-1.22.0.tar.gz", hash = "sha256:457e97ac4c3f694b900453d3f8824af36d17b9cef3d76c623e665dd4c7872d9c"}, ] [[package]] @@ -537,38 +538,41 @@ files = [ [[package]] name = "nodriver" -version = "0.37" +version = "0.38.post1" requires_python = ">=3.9" summary = "[Docs here](https://ultrafunkamsterdam.github.io/nodriver)" groups = ["dev"] dependencies = [ "deprecated", "mss", - "websockets>=11", + "websockets<=13.1", ] files = [ - {file = "nodriver-0.37-py3-none-any.whl", hash = "sha256:1a9ecd89b9834d228a260eebb61ea4ee763b34479879113d080251bc29bdcca5"}, - {file = "nodriver-0.37.tar.gz", hash = "sha256:145fc4d21359be8dba52bb60c3e9c11f946693b5026aa02c72408b0ccb822b40"}, + {file = "nodriver-0.38.post1-py3-none-any.whl", hash = "sha256:ce82832fb2b2c8610f05c6d8f264a6c40664c31d9ca9d1595eed11da7208151b"}, + {file = "nodriver-0.38.post1.tar.gz", hash = "sha256:7df680e309b0c0f087d4ac0103556794b7fadc081b63182e44e0fa274f28ff8a"}, ] [[package]] name = "orjson" -version = "3.10.11" +version = "3.10.12" requires_python = ">=3.8" summary = "Fast, correct Python JSON library supporting dataclasses, datetimes, and numpy" groups = ["default"] files = [ - {file = "orjson-3.10.11-cp312-cp312-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:360a4e2c0943da7c21505e47cf6bd725588962ff1d739b99b14e2f7f3545ba51"}, - {file = "orjson-3.10.11-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:496e2cb45de21c369079ef2d662670a4892c81573bcc143c4205cae98282ba97"}, - {file = "orjson-3.10.11-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:7dfa8db55c9792d53c5952900c6a919cfa377b4f4534c7a786484a6a4a350c19"}, - {file = "orjson-3.10.11-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:51f3382415747e0dbda9dade6f1e1a01a9d37f630d8c9049a8ed0e385b7a90c0"}, - {file = "orjson-3.10.11-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f35a1b9f50a219f470e0e497ca30b285c9f34948d3c8160d5ad3a755d9299433"}, - {file = "orjson-3.10.11-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e2f3b7c5803138e67028dde33450e054c87e0703afbe730c105f1fcd873496d5"}, - {file = "orjson-3.10.11-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:f91d9eb554310472bd09f5347950b24442600594c2edc1421403d7610a0998fd"}, - {file = "orjson-3.10.11-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:dfbb2d460a855c9744bbc8e36f9c3a997c4b27d842f3d5559ed54326e6911f9b"}, - {file = "orjson-3.10.11-cp312-none-win32.whl", hash = "sha256:d4a62c49c506d4d73f59514986cadebb7e8d186ad510c518f439176cf8d5359d"}, - {file = "orjson-3.10.11-cp312-none-win_amd64.whl", hash = "sha256:f1eec3421a558ff7a9b010a6c7effcfa0ade65327a71bb9b02a1c3b77a247284"}, - {file = "orjson-3.10.11.tar.gz", hash = "sha256:e35b6d730de6384d5b2dab5fd23f0d76fae8bbc8c353c2f78210aa5fa4beb3ef"}, + {file = "orjson-3.10.12-cp312-cp312-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:53206d72eb656ca5ac7d3a7141e83c5bbd3ac30d5eccfe019409177a57634b0d"}, + {file = "orjson-3.10.12-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ac8010afc2150d417ebda810e8df08dd3f544e0dd2acab5370cfa6bcc0662f8f"}, + {file = "orjson-3.10.12-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:ed459b46012ae950dd2e17150e838ab08215421487371fa79d0eced8d1461d70"}, + {file = "orjson-3.10.12-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:8dcb9673f108a93c1b52bfc51b0af422c2d08d4fc710ce9c839faad25020bb69"}, + {file = "orjson-3.10.12-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:22a51ae77680c5c4652ebc63a83d5255ac7d65582891d9424b566fb3b5375ee9"}, + {file = "orjson-3.10.12-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:910fdf2ac0637b9a77d1aad65f803bac414f0b06f720073438a7bd8906298192"}, + {file = "orjson-3.10.12-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:24ce85f7100160936bc2116c09d1a8492639418633119a2224114f67f63a4559"}, + {file = "orjson-3.10.12-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:8a76ba5fc8dd9c913640292df27bff80a685bed3a3c990d59aa6ce24c352f8fc"}, + {file = "orjson-3.10.12-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:ff70ef093895fd53f4055ca75f93f047e088d1430888ca1229393a7c0521100f"}, + {file = "orjson-3.10.12-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:f4244b7018b5753ecd10a6d324ec1f347da130c953a9c88432c7fbc8875d13be"}, + {file = "orjson-3.10.12-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:16135ccca03445f37921fa4b585cff9a58aa8d81ebcb27622e69bfadd220b32c"}, + {file = "orjson-3.10.12-cp312-none-win32.whl", hash = "sha256:2d879c81172d583e34153d524fcba5d4adafbab8349a7b9f16ae511c2cee8708"}, + {file = "orjson-3.10.12-cp312-none-win_amd64.whl", hash = "sha256:fc23f691fa0f5c140576b8c365bc942d577d861a9ee1142e4db468e4e17094fb"}, + {file = "orjson-3.10.12.tar.gz", hash = "sha256:0a78bbda3aea0f9f079057ee1ee8a1ecf790d4f1af88dd67493c6b8ee52506ff"}, ] [[package]] @@ -648,24 +652,23 @@ files = [ [[package]] name = "pydantic" -version = "2.9.2" +version = "2.10.2" requires_python = ">=3.8" summary = "Data validation using Python type hints" groups = ["default"] dependencies = [ "annotated-types>=0.6.0", - "pydantic-core==2.23.4", - "typing-extensions>=4.12.2; python_version >= \"3.13\"", - "typing-extensions>=4.6.1; python_version < \"3.13\"", + "pydantic-core==2.27.1", + "typing-extensions>=4.12.2", ] files = [ - {file = "pydantic-2.9.2-py3-none-any.whl", hash = "sha256:f048cec7b26778210e28a0459867920654d48e5e62db0958433636cde4254f12"}, - {file = "pydantic-2.9.2.tar.gz", hash = "sha256:d155cef71265d1e9807ed1c32b4c8deec042a44a50a4188b25ac67ecd81a9c0f"}, + {file = "pydantic-2.10.2-py3-none-any.whl", hash = "sha256:cfb96e45951117c3024e6b67b25cdc33a3cb7b2fa62e239f7af1378358a1d99e"}, + {file = "pydantic-2.10.2.tar.gz", hash = "sha256:2bc2d7f17232e0841cbba4641e65ba1eb6fafb3a08de3a091ff3ce14a197c4fa"}, ] [[package]] name = "pydantic-core" -version = "2.23.4" +version = "2.27.1" requires_python = ">=3.8" summary = "Core functionality for Pydantic validation and serialization" groups = ["default"] @@ -673,19 +676,21 @@ dependencies = [ "typing-extensions!=4.7.0,>=4.6.0", ] files = [ - {file = "pydantic_core-2.23.4-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:f3e0da4ebaef65158d4dfd7d3678aad692f7666877df0002b8a522cdf088f231"}, - {file = "pydantic_core-2.23.4-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:f69a8e0b033b747bb3e36a44e7732f0c99f7edd5cea723d45bc0d6e95377ffee"}, - {file = "pydantic_core-2.23.4-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:723314c1d51722ab28bfcd5240d858512ffd3116449c557a1336cbe3919beb87"}, - {file = "pydantic_core-2.23.4-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:bb2802e667b7051a1bebbfe93684841cc9351004e2badbd6411bf357ab8d5ac8"}, - {file = "pydantic_core-2.23.4-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d18ca8148bebe1b0a382a27a8ee60350091a6ddaf475fa05ef50dc35b5df6327"}, - {file = "pydantic_core-2.23.4-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:33e3d65a85a2a4a0dc3b092b938a4062b1a05f3a9abde65ea93b233bca0e03f2"}, - {file = "pydantic_core-2.23.4-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:128585782e5bfa515c590ccee4b727fb76925dd04a98864182b22e89a4e6ed36"}, - {file = "pydantic_core-2.23.4-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:68665f4c17edcceecc112dfed5dbe6f92261fb9d6054b47d01bf6371a6196126"}, - {file = "pydantic_core-2.23.4-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:20152074317d9bed6b7a95ade3b7d6054845d70584216160860425f4fbd5ee9e"}, - {file = "pydantic_core-2.23.4-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:9261d3ce84fa1d38ed649c3638feefeae23d32ba9182963e465d58d62203bd24"}, - {file = "pydantic_core-2.23.4-cp312-none-win32.whl", hash = "sha256:4ba762ed58e8d68657fc1281e9bb72e1c3e79cc5d464be146e260c541ec12d84"}, - {file = "pydantic_core-2.23.4-cp312-none-win_amd64.whl", hash = "sha256:97df63000f4fea395b2824da80e169731088656d1818a11b95f3b173747b6cd9"}, - {file = "pydantic_core-2.23.4.tar.gz", hash = "sha256:2584f7cf844ac4d970fba483a717dbe10c1c1c96a969bf65d61ffe94df1b2863"}, + {file = "pydantic_core-2.27.1-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:9cbd94fc661d2bab2bc702cddd2d3370bbdcc4cd0f8f57488a81bcce90c7a54f"}, + {file = "pydantic_core-2.27.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:5f8c4718cd44ec1580e180cb739713ecda2bdee1341084c1467802a417fe0f02"}, + {file = "pydantic_core-2.27.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:15aae984e46de8d376df515f00450d1522077254ef6b7ce189b38ecee7c9677c"}, + {file = "pydantic_core-2.27.1-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:1ba5e3963344ff25fc8c40da90f44b0afca8cfd89d12964feb79ac1411a260ac"}, + {file = "pydantic_core-2.27.1-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:992cea5f4f3b29d6b4f7f1726ed8ee46c8331c6b4eed6db5b40134c6fe1768bb"}, + {file = "pydantic_core-2.27.1-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:0325336f348dbee6550d129b1627cb8f5351a9dc91aad141ffb96d4937bd9529"}, + {file = "pydantic_core-2.27.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7597c07fbd11515f654d6ece3d0e4e5093edc30a436c63142d9a4b8e22f19c35"}, + {file = "pydantic_core-2.27.1-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:3bbd5d8cc692616d5ef6fbbbd50dbec142c7e6ad9beb66b78a96e9c16729b089"}, + {file = "pydantic_core-2.27.1-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:dc61505e73298a84a2f317255fcc72b710b72980f3a1f670447a21efc88f8381"}, + {file = "pydantic_core-2.27.1-cp312-cp312-musllinux_1_1_armv7l.whl", hash = "sha256:e1f735dc43da318cad19b4173dd1ffce1d84aafd6c9b782b3abc04a0d5a6f5bb"}, + {file = "pydantic_core-2.27.1-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:f4e5658dbffe8843a0f12366a4c2d1c316dbe09bb4dfbdc9d2d9cd6031de8aae"}, + {file = "pydantic_core-2.27.1-cp312-none-win32.whl", hash = "sha256:672ebbe820bb37988c4d136eca2652ee114992d5d41c7e4858cdd90ea94ffe5c"}, + {file = "pydantic_core-2.27.1-cp312-none-win_amd64.whl", hash = "sha256:66ff044fd0bb1768688aecbe28b6190f6e799349221fb0de0e6f4048eca14c16"}, + {file = "pydantic_core-2.27.1-cp312-none-win_arm64.whl", hash = "sha256:9a3b0793b1bbfd4146304e23d90045f2a9b5fd5823aa682665fbdaf2a6c28f3e"}, + {file = "pydantic_core-2.27.1.tar.gz", hash = "sha256:62a763352879b84aa31058fc931884055fd75089cccbd9d58bb6afd01141b235"}, ] [[package]] @@ -761,7 +766,7 @@ files = [ [[package]] name = "quart" -version = "0.19.8" +version = "0.19.9" requires_python = ">=3.8" summary = "A Python ASGI web microframework with the same API as Flask" groups = ["default"] @@ -779,8 +784,8 @@ dependencies = [ "werkzeug>=3.0.0", ] files = [ - {file = "quart-0.19.8-py3-none-any.whl", hash = "sha256:34eeb559014f4e72e093d034cfe203b1a6262e9d3504f826f293090e230609f2"}, - {file = "quart-0.19.8.tar.gz", hash = "sha256:ef567d0be7677c99890d5c6ff30e679699fe7e5fca1a90fa3b6974edd8421794"}, + {file = "quart-0.19.9-py3-none-any.whl", hash = "sha256:8acb8b299c72b66ee9e506ae141498bbbfcc250b5298fbdb712e97f3d7e4082f"}, + {file = "quart-0.19.9.tar.gz", hash = "sha256:30a61a0d7bae1ee13e6e99dc14c929b3c945e372b9445d92d21db053e91e95a5"}, ] [[package]] @@ -799,29 +804,29 @@ files = [ [[package]] name = "ruff" -version = "0.7.3" +version = "0.8.1" requires_python = ">=3.7" summary = "An extremely fast Python linter and code formatter, written in Rust." groups = ["dev"] files = [ - {file = "ruff-0.7.3-py3-none-linux_armv6l.whl", hash = "sha256:34f2339dc22687ec7e7002792d1f50712bf84a13d5152e75712ac08be565d344"}, - {file = "ruff-0.7.3-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:fb397332a1879b9764a3455a0bb1087bda876c2db8aca3a3cbb67b3dbce8cda0"}, - {file = "ruff-0.7.3-py3-none-macosx_11_0_arm64.whl", hash = "sha256:37d0b619546103274e7f62643d14e1adcbccb242efda4e4bdb9544d7764782e9"}, - {file = "ruff-0.7.3-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5d59f0c3ee4d1a6787614e7135b72e21024875266101142a09a61439cb6e38a5"}, - {file = "ruff-0.7.3-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:44eb93c2499a169d49fafd07bc62ac89b1bc800b197e50ff4633aed212569299"}, - {file = "ruff-0.7.3-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6d0242ce53f3a576c35ee32d907475a8d569944c0407f91d207c8af5be5dae4e"}, - {file = "ruff-0.7.3-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:6b6224af8b5e09772c2ecb8dc9f3f344c1aa48201c7f07e7315367f6dd90ac29"}, - {file = "ruff-0.7.3-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:c50f95a82b94421c964fae4c27c0242890a20fe67d203d127e84fbb8013855f5"}, - {file = "ruff-0.7.3-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:7f3eff9961b5d2644bcf1616c606e93baa2d6b349e8aa8b035f654df252c8c67"}, - {file = "ruff-0.7.3-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b8963cab06d130c4df2fd52c84e9f10d297826d2e8169ae0c798b6221be1d1d2"}, - {file = "ruff-0.7.3-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:61b46049d6edc0e4317fb14b33bd693245281a3007288b68a3f5b74a22a0746d"}, - {file = "ruff-0.7.3-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:10ebce7696afe4644e8c1a23b3cf8c0f2193a310c18387c06e583ae9ef284de2"}, - {file = "ruff-0.7.3-py3-none-musllinux_1_2_i686.whl", hash = "sha256:3f36d56326b3aef8eeee150b700e519880d1aab92f471eefdef656fd57492aa2"}, - {file = "ruff-0.7.3-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:5d024301109a0007b78d57ab0ba190087b43dce852e552734ebf0b0b85e4fb16"}, - {file = "ruff-0.7.3-py3-none-win32.whl", hash = "sha256:4ba81a5f0c5478aa61674c5a2194de8b02652f17addf8dfc40c8937e6e7d79fc"}, - {file = "ruff-0.7.3-py3-none-win_amd64.whl", hash = "sha256:588a9ff2fecf01025ed065fe28809cd5a53b43505f48b69a1ac7707b1b7e4088"}, - {file = "ruff-0.7.3-py3-none-win_arm64.whl", hash = "sha256:1713e2c5545863cdbfe2cbce21f69ffaf37b813bfd1fb3b90dc9a6f1963f5a8c"}, - {file = "ruff-0.7.3.tar.gz", hash = "sha256:e1d1ba2e40b6e71a61b063354d04be669ab0d39c352461f3d789cac68b54a313"}, + {file = "ruff-0.8.1-py3-none-linux_armv6l.whl", hash = "sha256:fae0805bd514066f20309f6742f6ee7904a773eb9e6c17c45d6b1600ca65c9b5"}, + {file = "ruff-0.8.1-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:b8a4f7385c2285c30f34b200ca5511fcc865f17578383db154e098150ce0a087"}, + {file = "ruff-0.8.1-py3-none-macosx_11_0_arm64.whl", hash = "sha256:cd054486da0c53e41e0086e1730eb77d1f698154f910e0cd9e0d64274979a209"}, + {file = "ruff-0.8.1-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2029b8c22da147c50ae577e621a5bfbc5d1fed75d86af53643d7a7aee1d23871"}, + {file = "ruff-0.8.1-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:2666520828dee7dfc7e47ee4ea0d928f40de72056d929a7c5292d95071d881d1"}, + {file = "ruff-0.8.1-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:333c57013ef8c97a53892aa56042831c372e0bb1785ab7026187b7abd0135ad5"}, + {file = "ruff-0.8.1-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:288326162804f34088ac007139488dcb43de590a5ccfec3166396530b58fb89d"}, + {file = "ruff-0.8.1-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b12c39b9448632284561cbf4191aa1b005882acbc81900ffa9f9f471c8ff7e26"}, + {file = "ruff-0.8.1-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:364e6674450cbac8e998f7b30639040c99d81dfb5bbc6dfad69bc7a8f916b3d1"}, + {file = "ruff-0.8.1-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b22346f845fec132aa39cd29acb94451d030c10874408dbf776af3aaeb53284c"}, + {file = "ruff-0.8.1-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:b2f2f7a7e7648a2bfe6ead4e0a16745db956da0e3a231ad443d2a66a105c04fa"}, + {file = "ruff-0.8.1-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:adf314fc458374c25c5c4a4a9270c3e8a6a807b1bec018cfa2813d6546215540"}, + {file = "ruff-0.8.1-py3-none-musllinux_1_2_i686.whl", hash = "sha256:a885d68342a231b5ba4d30b8c6e1b1ee3a65cf37e3d29b3c74069cdf1ee1e3c9"}, + {file = "ruff-0.8.1-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:d2c16e3508c8cc73e96aa5127d0df8913d2290098f776416a4b157657bee44c5"}, + {file = "ruff-0.8.1-py3-none-win32.whl", hash = "sha256:93335cd7c0eaedb44882d75a7acb7df4b77cd7cd0d2255c93b28791716e81790"}, + {file = "ruff-0.8.1-py3-none-win_amd64.whl", hash = "sha256:2954cdbe8dfd8ab359d4a30cd971b589d335a44d444b6ca2cb3d1da21b75e4b6"}, + {file = "ruff-0.8.1-py3-none-win_arm64.whl", hash = "sha256:55873cc1a473e5ac129d15eccb3c008c096b94809d693fc7053f588b67822737"}, + {file = "ruff-0.8.1.tar.gz", hash = "sha256:3583db9a6450364ed5ca3f3b4225958b24f78178908d5c4bc0f46251ccca898f"}, ] [[package]] @@ -839,7 +844,7 @@ files = [ [[package]] name = "sentry-sdk" -version = "2.18.0" +version = "2.19.0" requires_python = ">=3.6" summary = "Python client for Sentry (https://sentry.io)" groups = ["default"] @@ -848,8 +853,8 @@ dependencies = [ "urllib3>=1.26.11", ] files = [ - {file = "sentry_sdk-2.18.0-py2.py3-none-any.whl", hash = "sha256:ee70e27d1bbe4cd52a38e1bd28a5fadb9b17bc29d91b5f2b97ae29c0a7610442"}, - {file = "sentry_sdk-2.18.0.tar.gz", hash = "sha256:0dc21febd1ab35c648391c664df96f5f79fb0d92d7d4225cd9832e53a617cafd"}, + {file = "sentry_sdk-2.19.0-py2.py3-none-any.whl", hash = "sha256:7b0b3b709dee051337244a09a30dbf6e95afe0d34a1f8b430d45e0982a7c125b"}, + {file = "sentry_sdk-2.19.0.tar.gz", hash = "sha256:ee4a4d2ae8bfe3cac012dcf3e4607975904c137e1738116549fc3dbbb6ff0e36"}, ] [[package]] diff --git a/pyproject.toml b/pyproject.toml index 6ce0b7a..67628ae 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -89,7 +89,6 @@ extend-ignore = [ "D105", "D106", "ANN401", - "ANN101", "TRY003", "EM101", "EM102", diff --git a/scripts/check_listings/__main__.py b/scripts/check_listings/__main__.py index e5e64d3..a65a5d9 100644 --- a/scripts/check_listings/__main__.py +++ b/scripts/check_listings/__main__.py @@ -8,7 +8,7 @@ import markdown import nodriver as uc import yaml -from aiofile import async_open as open # noqa: A001 +from aiofile import async_open as open # noqa: A004 from bs4 import BeautifulSoup from termcolor import cprint diff --git a/scripts/check_listings/listings/__init__.py b/scripts/check_listings/listings/__init__.py index 2a038af..6cf16e9 100644 --- a/scripts/check_listings/listings/__init__.py +++ b/scripts/check_listings/listings/__init__.py @@ -12,16 +12,16 @@ from .WumpusStore import WumpusStore __all__ = [ - "TopGg", - "DiscordsCom", "BaseError", - "NotFoundError", - "normalize_soup", - "WumpusStore", "DiscordAppDirectory", "DiscordBotListCom", - "DisforgeCom", "DiscordBotsGg", "DiscordMe", + "DiscordsCom", + "DisforgeCom", "Listing", + "NotFoundError", + "TopGg", + "WumpusStore", + "normalize_soup", ] diff --git a/scripts/check_listings/main.py b/scripts/check_listings/main.py index 11f69cc..392c5ac 100644 --- a/scripts/check_listings/main.py +++ b/scripts/check_listings/main.py @@ -7,7 +7,7 @@ import markdown import nodriver as uc import yaml -from aiofile import async_open as open # noqa: A001 +from aiofile import async_open as open # noqa: A004 from bs4 import BeautifulSoup from termcolor import cprint diff --git a/src/custom/__init__.py b/src/custom/__init__.py index 5ac2bdd..dbf8023 100644 --- a/src/custom/__init__.py +++ b/src/custom/__init__.py @@ -88,4 +88,4 @@ async def get_context( type Context = ExtContext | ApplicationContext ... # for some reason, this makes pycharm happy -__all__ = ["Bot", "Context", "ExtContext", "ApplicationContext"] +__all__ = ["ApplicationContext", "Bot", "Context", "ExtContext"] diff --git a/src/extensions/add-dm/__init__.py b/src/extensions/add-dm/__init__.py index d137c6f..191ddd8 100644 --- a/src/extensions/add-dm/__init__.py +++ b/src/extensions/add-dm/__init__.py @@ -3,4 +3,4 @@ from .main import default, schema, setup -__all__ = ["setup", "default", "schema"] +__all__ = ["default", "schema", "setup"] diff --git a/src/extensions/branding/__init__.py b/src/extensions/branding/__init__.py index 883f743..05b0b4b 100644 --- a/src/extensions/branding/__init__.py +++ b/src/extensions/branding/__init__.py @@ -3,4 +3,4 @@ from .branding import default, schema, setup -__all__ = ["setup", "default", "schema"] +__all__ = ["default", "schema", "setup"] diff --git a/src/extensions/listings/__init__.py b/src/extensions/listings/__init__.py index d137c6f..191ddd8 100644 --- a/src/extensions/listings/__init__.py +++ b/src/extensions/listings/__init__.py @@ -3,4 +3,4 @@ from .main import default, schema, setup -__all__ = ["setup", "default", "schema"] +__all__ = ["default", "schema", "setup"] diff --git a/src/extensions/nice_errors/__init__.py b/src/extensions/nice_errors/__init__.py index d137c6f..191ddd8 100644 --- a/src/extensions/nice_errors/__init__.py +++ b/src/extensions/nice_errors/__init__.py @@ -3,4 +3,4 @@ from .main import default, schema, setup -__all__ = ["setup", "default", "schema"] +__all__ = ["default", "schema", "setup"] diff --git a/src/extensions/ping/__init__.py b/src/extensions/ping/__init__.py index 034634f..62965a7 100644 --- a/src/extensions/ping/__init__.py +++ b/src/extensions/ping/__init__.py @@ -3,4 +3,4 @@ from .ping import default, on_startup, schema, setup, setup_webserver -__all__ = ["setup", "setup_webserver", "on_startup", "default", "schema"] +__all__ = ["default", "on_startup", "schema", "setup", "setup_webserver"] diff --git a/src/extensions/status-post/__init__.py b/src/extensions/status-post/__init__.py index d137c6f..191ddd8 100644 --- a/src/extensions/status-post/__init__.py +++ b/src/extensions/status-post/__init__.py @@ -3,4 +3,4 @@ from .main import default, schema, setup -__all__ = ["setup", "default", "schema"] +__all__ = ["default", "schema", "setup"] diff --git a/src/i18n/__init__.py b/src/i18n/__init__.py index 87c8b6e..f52ffb7 100644 --- a/src/i18n/__init__.py +++ b/src/i18n/__init__.py @@ -4,4 +4,4 @@ from .classes import apply_locale from .utils import apply, load_translation -__all__ = ["apply", "load_translation", "apply_locale"] +__all__ = ["apply", "apply_locale", "load_translation"] diff --git a/src/utils/__init__.py b/src/utils/__init__.py index c76ea72..67d0d26 100644 --- a/src/utils/__init__.py +++ b/src/utils/__init__.py @@ -5,4 +5,4 @@ from .misc import mention_command from .setup_func import setup_func -__all__ = ["validate_module", "unzip_extensions", "mention_command", "setup_func"] +__all__ = ["mention_command", "setup_func", "unzip_extensions", "validate_module"] From d7107315856f75410ed9e68d9b942ec63561f22e Mon Sep 17 00:00:00 2001 From: Paillat Date: Sat, 30 Nov 2024 20:03:56 +0100 Subject: [PATCH 27/61] :green_heart: Export all deps --- .github/workflows/update_dependencies.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/update_dependencies.yaml b/.github/workflows/update_dependencies.yaml index 1d1b850..29cf6ef 100644 --- a/.github/workflows/update_dependencies.yaml +++ b/.github/workflows/update_dependencies.yaml @@ -35,7 +35,7 @@ jobs: cache: true - name: Lock dependencies - run: pdm lock + run: pdm lock -G :all - name: Export requirements run: pdm run export From 8de67b2b4a72c2151780ff0f8fea6ca00c2848a0 Mon Sep 17 00:00:00 2001 From: Paillat Date: Sat, 30 Nov 2024 20:57:00 +0100 Subject: [PATCH 28/61] :green_heart: Fix ci again --- .github/workflows/update_dependencies.yaml | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/.github/workflows/update_dependencies.yaml b/.github/workflows/update_dependencies.yaml index 29cf6ef..5005470 100644 --- a/.github/workflows/update_dependencies.yaml +++ b/.github/workflows/update_dependencies.yaml @@ -24,11 +24,16 @@ jobs: steps: - uses: actions/checkout@v4 name: Checkout repository + with: + fetch-depth: 0 # Fetch all history for all branches - name: Checkout target branch if: inputs.pr_branch run: | - BRANCH_NAME=$(echo ${{ inputs.pr_branch }} | cut -d'/' -f 3) + BRANCH_NAME=$(echo ${{ inputs.pr_branch }} | sed 's|refs/heads/||') + git fetch origin $BRANCH_NAME git checkout $BRANCH_NAME + git pull origin $BRANCH_NAME + - name: Setup PDM uses: pdm-project/setup-pdm@v4 with: From 8841437f29ce09c9af172448bb89e1ddd1bb7d10 Mon Sep 17 00:00:00 2001 From: Paillat Date: Sat, 30 Nov 2024 21:07:28 +0100 Subject: [PATCH 29/61] :green_heart: Fix lock --- pdm.lock | 117 +++++++++++++++++++++++++++---------------------------- 1 file changed, 58 insertions(+), 59 deletions(-) diff --git a/pdm.lock b/pdm.lock index f332501..42ef5a3 100644 --- a/pdm.lock +++ b/pdm.lock @@ -62,13 +62,13 @@ files = [ [[package]] name = "aiohappyeyeballs" -version = "2.4.3" +version = "2.4.4" requires_python = ">=3.8" summary = "Happy Eyeballs for asyncio" groups = ["default"] files = [ - {file = "aiohappyeyeballs-2.4.3-py3-none-any.whl", hash = "sha256:8a7a83727b2756f394ab2895ea0765a0a8c475e3c71e98d43d76f22b4b435572"}, - {file = "aiohappyeyeballs-2.4.3.tar.gz", hash = "sha256:75cf88a15106a5002a8eb1dab212525c00d1f4c0fa96e551c9fbe6f09a621586"}, + {file = "aiohappyeyeballs-2.4.4-py3-none-any.whl", hash = "sha256:a980909d50efcd44795c4afeca523296716d50cd756ddca6af8c65b996e27de8"}, + {file = "aiohappyeyeballs-2.4.4.tar.gz", hash = "sha256:5fdd7d87889c63183afc18ce9271f9b0a7d32c2303e394468dd45d514a757745"}, ] [[package]] @@ -178,13 +178,13 @@ files = [ [[package]] name = "blinker" -version = "1.8.2" -requires_python = ">=3.8" +version = "1.9.0" +requires_python = ">=3.9" summary = "Fast, simple object-to-object and broadcast signaling" groups = ["default"] files = [ - {file = "blinker-1.8.2-py3-none-any.whl", hash = "sha256:1779309f71bf239144b9399d06ae925637cf6634cf6bd131104184531bf67c01"}, - {file = "blinker-1.8.2.tar.gz", hash = "sha256:8f77b09d3bf7c795e969e9486f39c2c5e9c39d4ee07424be2bc594ece9642d83"}, + {file = "blinker-1.9.0-py3-none-any.whl", hash = "sha256:ba0efaa9080b619ff2f3459d1d500c57bddea4a6b424b60a91141db6fd2f08bc"}, + {file = "blinker-1.9.0.tar.gz", hash = "sha256:b4ce2265a7abece45e7cc896e98dbebe6cead56bcf805a3d23136d145f5445bf"}, ] [[package]] @@ -254,35 +254,35 @@ files = [ [[package]] name = "deprecated" -version = "1.2.14" -requires_python = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" +version = "1.2.15" +requires_python = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,>=2.7" summary = "Python @deprecated decorator to deprecate old python classes, functions or methods." groups = ["dev"] dependencies = [ "wrapt<2,>=1.10", ] files = [ - {file = "Deprecated-1.2.14-py2.py3-none-any.whl", hash = "sha256:6fac8b097794a90302bdbb17b9b815e732d3c4720583ff1b198499d78470466c"}, - {file = "Deprecated-1.2.14.tar.gz", hash = "sha256:e5323eb936458dccc2582dc6f9c322c852a775a27065ff2b0c4970b9d53d01b3"}, + {file = "Deprecated-1.2.15-py2.py3-none-any.whl", hash = "sha256:353bc4a8ac4bfc96800ddab349d89c25dec1079f65fd53acdcc1e0b975b21320"}, + {file = "deprecated-1.2.15.tar.gz", hash = "sha256:683e561a90de76239796e6b6feac66b99030d2dd3fcf61ef996330f14bbb9b0d"}, ] [[package]] name = "flask" -version = "3.0.3" -requires_python = ">=3.8" +version = "3.1.0" +requires_python = ">=3.9" summary = "A simple framework for building complex web applications." groups = ["default"] dependencies = [ "Jinja2>=3.1.2", - "Werkzeug>=3.0.0", - "blinker>=1.6.2", + "Werkzeug>=3.1", + "blinker>=1.9", "click>=8.1.3", - "importlib-metadata>=3.6.0; python_version < \"3.10\"", - "itsdangerous>=2.1.2", + "importlib-metadata>=3.6; python_version < \"3.10\"", + "itsdangerous>=2.2", ] files = [ - {file = "flask-3.0.3-py3-none-any.whl", hash = "sha256:34e815dfaa43340d1d15a5c3a02b8476004037eb4840b34910c6e21679d288f3"}, - {file = "flask-3.0.3.tar.gz", hash = "sha256:ceb27b0af3823ea2737928a4d99d125a06175b8512c445cbd9a9ce200ef76842"}, + {file = "flask-3.1.0-py3-none-any.whl", hash = "sha256:d667207822eb83f1c4b50949b1623c8fc8d51f2341d65f72e1a1815397551136"}, + {file = "flask-3.1.0.tar.gz", hash = "sha256:5f873c5184c897c8d9d1b05df1e3d01b14910ce69607a117bd3277098a5836ac"}, ] [[package]] @@ -482,13 +482,13 @@ files = [ [[package]] name = "mss" -version = "9.0.2" -requires_python = ">=3.8" +version = "10.0.0" +requires_python = ">=3.9" summary = "An ultra fast cross-platform multiple screenshots module in pure python using ctypes." groups = ["dev"] files = [ - {file = "mss-9.0.2-py3-none-any.whl", hash = "sha256:685fa442cc96d8d88b4eb7aadbcccca7b858e789c9259b603e1ef0e435b60425"}, - {file = "mss-9.0.2.tar.gz", hash = "sha256:c96a4ec73224da7db22bc07ef3cfaa18f8b86900d1872e29113bbcef0093a21e"}, + {file = "mss-10.0.0-py3-none-any.whl", hash = "sha256:82cf6460a53d09e79b7b6d871163c982e6c7e9649c426e7b7591b74956d5cb64"}, + {file = "mss-10.0.0.tar.gz", hash = "sha256:d903e0d51262bf0f8782841cf16eaa6d7e3e1f12eae35ab41c2e318837c6637f"}, ] [[package]] @@ -925,7 +925,7 @@ files = [ [[package]] name = "werkzeug" -version = "3.1.2" +version = "3.1.3" requires_python = ">=3.9" summary = "The comprehensive WSGI web application library." groups = ["default"] @@ -933,29 +933,28 @@ dependencies = [ "MarkupSafe>=2.1.1", ] files = [ - {file = "werkzeug-3.1.2-py3-none-any.whl", hash = "sha256:4f7d1a5de312c810a8a2c6f0b47e9f6a7cffb7c8322def35e4d4d9841ff85597"}, - {file = "werkzeug-3.1.2.tar.gz", hash = "sha256:f471a4cd167233077e9d2a8190c3471c5bc520c636a9e3c1e9300c33bced03bc"}, + {file = "werkzeug-3.1.3-py3-none-any.whl", hash = "sha256:54b78bf3716d19a65be4fceccc0d1d7b89e608834989dfae50ea87564639213e"}, + {file = "werkzeug-3.1.3.tar.gz", hash = "sha256:60723ce945c19328679790e3282cc758aa4a6040e4bb330f53d30fa546d44746"}, ] [[package]] name = "wrapt" -version = "1.16.0" -requires_python = ">=3.6" +version = "1.17.0" +requires_python = ">=3.8" summary = "Module for decorators, wrappers and monkey patching." groups = ["dev"] files = [ - {file = "wrapt-1.16.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:5eb404d89131ec9b4f748fa5cfb5346802e5ee8836f57d516576e61f304f3b7b"}, - {file = "wrapt-1.16.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:9090c9e676d5236a6948330e83cb89969f433b1943a558968f659ead07cb3b36"}, - {file = "wrapt-1.16.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:94265b00870aa407bd0cbcfd536f17ecde43b94fb8d228560a1e9d3041462d73"}, - {file = "wrapt-1.16.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f2058f813d4f2b5e3a9eb2eb3faf8f1d99b81c3e51aeda4b168406443e8ba809"}, - {file = "wrapt-1.16.0-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:98b5e1f498a8ca1858a1cdbffb023bfd954da4e3fa2c0cb5853d40014557248b"}, - {file = "wrapt-1.16.0-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:14d7dc606219cdd7405133c713f2c218d4252f2a469003f8c46bb92d5d095d81"}, - {file = "wrapt-1.16.0-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:49aac49dc4782cb04f58986e81ea0b4768e4ff197b57324dcbd7699c5dfb40b9"}, - {file = "wrapt-1.16.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:418abb18146475c310d7a6dc71143d6f7adec5b004ac9ce08dc7a34e2babdc5c"}, - {file = "wrapt-1.16.0-cp312-cp312-win32.whl", hash = "sha256:685f568fa5e627e93f3b52fda002c7ed2fa1800b50ce51f6ed1d572d8ab3e7fc"}, - {file = "wrapt-1.16.0-cp312-cp312-win_amd64.whl", hash = "sha256:dcdba5c86e368442528f7060039eda390cc4091bfd1dca41e8046af7c910dda8"}, - {file = "wrapt-1.16.0-py3-none-any.whl", hash = "sha256:6906c4100a8fcbf2fa735f6059214bb13b97f75b1a61777fcf6432121ef12ef1"}, - {file = "wrapt-1.16.0.tar.gz", hash = "sha256:5f370f952971e7d17c7d1ead40e49f32345a7f7a5373571ef44d800d06b1899d"}, + {file = "wrapt-1.17.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:89fc28495896097622c3fc238915c79365dd0ede02f9a82ce436b13bd0ab7569"}, + {file = "wrapt-1.17.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:875d240fdbdbe9e11f9831901fb8719da0bd4e6131f83aa9f69b96d18fae7504"}, + {file = "wrapt-1.17.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e5ed16d95fd142e9c72b6c10b06514ad30e846a0d0917ab406186541fe68b451"}, + {file = "wrapt-1.17.0-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:18b956061b8db634120b58f668592a772e87e2e78bc1f6a906cfcaa0cc7991c1"}, + {file = "wrapt-1.17.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:daba396199399ccabafbfc509037ac635a6bc18510ad1add8fd16d4739cdd106"}, + {file = "wrapt-1.17.0-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:4d63f4d446e10ad19ed01188d6c1e1bb134cde8c18b0aa2acfd973d41fcc5ada"}, + {file = "wrapt-1.17.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:8a5e7cc39a45fc430af1aefc4d77ee6bad72c5bcdb1322cfde852c15192b8bd4"}, + {file = "wrapt-1.17.0-cp312-cp312-win32.whl", hash = "sha256:0a0a1a1ec28b641f2a3a2c35cbe86c00051c04fffcfcc577ffcdd707df3f8635"}, + {file = "wrapt-1.17.0-cp312-cp312-win_amd64.whl", hash = "sha256:3c34f6896a01b84bab196f7119770fd8466c8ae3dfa73c59c0bb281e7b588ce7"}, + {file = "wrapt-1.17.0-py3-none-any.whl", hash = "sha256:d2c63b93548eda58abf5188e505ffed0229bf675f7c3090f8e36ad55b8cbc371"}, + {file = "wrapt-1.17.0.tar.gz", hash = "sha256:16187aa2317c731170a88ef35e8937ae0f533c402872c1ee5e6d079fcf320801"}, ] [[package]] @@ -974,7 +973,7 @@ files = [ [[package]] name = "yarl" -version = "1.17.1" +version = "1.18.0" requires_python = ">=3.9" summary = "Yet another URL library" groups = ["default"] @@ -984,22 +983,22 @@ dependencies = [ "propcache>=0.2.0", ] files = [ - {file = "yarl-1.17.1-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:327828786da2006085a4d1feb2594de6f6d26f8af48b81eb1ae950c788d97f61"}, - {file = "yarl-1.17.1-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:cc353841428d56b683a123a813e6a686e07026d6b1c5757970a877195f880c2d"}, - {file = "yarl-1.17.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:c73df5b6e8fabe2ddb74876fb82d9dd44cbace0ca12e8861ce9155ad3c886139"}, - {file = "yarl-1.17.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0bdff5e0995522706c53078f531fb586f56de9c4c81c243865dd5c66c132c3b5"}, - {file = "yarl-1.17.1-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:06157fb3c58f2736a5e47c8fcbe1afc8b5de6fb28b14d25574af9e62150fcaac"}, - {file = "yarl-1.17.1-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:1654ec814b18be1af2c857aa9000de7a601400bd4c9ca24629b18486c2e35463"}, - {file = "yarl-1.17.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7f6595c852ca544aaeeb32d357e62c9c780eac69dcd34e40cae7b55bc4fb1147"}, - {file = "yarl-1.17.1-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:459e81c2fb920b5f5df744262d1498ec2c8081acdcfe18181da44c50f51312f7"}, - {file = "yarl-1.17.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:7e48cdb8226644e2fbd0bdb0a0f87906a3db07087f4de77a1b1b1ccfd9e93685"}, - {file = "yarl-1.17.1-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:d9b6b28a57feb51605d6ae5e61a9044a31742db557a3b851a74c13bc61de5172"}, - {file = "yarl-1.17.1-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:e594b22688d5747b06e957f1ef822060cb5cb35b493066e33ceac0cf882188b7"}, - {file = "yarl-1.17.1-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:5f236cb5999ccd23a0ab1bd219cfe0ee3e1c1b65aaf6dd3320e972f7ec3a39da"}, - {file = "yarl-1.17.1-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:a2a64e62c7a0edd07c1c917b0586655f3362d2c2d37d474db1a509efb96fea1c"}, - {file = "yarl-1.17.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:d0eea830b591dbc68e030c86a9569826145df485b2b4554874b07fea1275a199"}, - {file = "yarl-1.17.1-cp312-cp312-win32.whl", hash = "sha256:46ddf6e0b975cd680eb83318aa1d321cb2bf8d288d50f1754526230fcf59ba96"}, - {file = "yarl-1.17.1-cp312-cp312-win_amd64.whl", hash = "sha256:117ed8b3732528a1e41af3aa6d4e08483c2f0f2e3d3d7dca7cf538b3516d93df"}, - {file = "yarl-1.17.1-py3-none-any.whl", hash = "sha256:f1790a4b1e8e8e028c391175433b9c8122c39b46e1663228158e61e6f915bf06"}, - {file = "yarl-1.17.1.tar.gz", hash = "sha256:067a63fcfda82da6b198fa73079b1ca40b7c9b7994995b6ee38acda728b64d47"}, + {file = "yarl-1.18.0-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:1ece25e2251c28bab737bdf0519c88189b3dd9492dc086a1d77336d940c28ced"}, + {file = "yarl-1.18.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:454902dc1830d935c90b5b53c863ba2a98dcde0fbaa31ca2ed1ad33b2a7171c6"}, + {file = "yarl-1.18.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:01be8688fc211dc237e628fcc209dda412d35de7642453059a0553747018d075"}, + {file = "yarl-1.18.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4d26f1fa9fa2167bb238f6f4b20218eb4e88dd3ef21bb8f97439fa6b5313e30d"}, + {file = "yarl-1.18.0-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b234a4a9248a9f000b7a5dfe84b8cb6210ee5120ae70eb72a4dcbdb4c528f72f"}, + {file = "yarl-1.18.0-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:fe94d1de77c4cd8caff1bd5480e22342dbd54c93929f5943495d9c1e8abe9f42"}, + {file = "yarl-1.18.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9b4c90c5363c6b0a54188122b61edb919c2cd1119684999d08cd5e538813a28e"}, + {file = "yarl-1.18.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:49a98ecadc5a241c9ba06de08127ee4796e1009555efd791bac514207862b43d"}, + {file = "yarl-1.18.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:9106025c7f261f9f5144f9aa7681d43867eed06349a7cfb297a1bc804de2f0d1"}, + {file = "yarl-1.18.0-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:f275ede6199d0f1ed4ea5d55a7b7573ccd40d97aee7808559e1298fe6efc8dbd"}, + {file = "yarl-1.18.0-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:f7edeb1dcc7f50a2c8e08b9dc13a413903b7817e72273f00878cb70e766bdb3b"}, + {file = "yarl-1.18.0-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:c083f6dd6951b86e484ebfc9c3524b49bcaa9c420cb4b2a78ef9f7a512bfcc85"}, + {file = "yarl-1.18.0-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:80741ec5b471fbdfb997821b2842c59660a1c930ceb42f8a84ba8ca0f25a66aa"}, + {file = "yarl-1.18.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:b1a3297b9cad594e1ff0c040d2881d7d3a74124a3c73e00c3c71526a1234a9f7"}, + {file = "yarl-1.18.0-cp312-cp312-win32.whl", hash = "sha256:cd6ab7d6776c186f544f893b45ee0c883542b35e8a493db74665d2e594d3ca75"}, + {file = "yarl-1.18.0-cp312-cp312-win_amd64.whl", hash = "sha256:039c299a0864d1f43c3e31570045635034ea7021db41bf4842693a72aca8df3a"}, + {file = "yarl-1.18.0-py3-none-any.whl", hash = "sha256:dbf53db46f7cf176ee01d8d98c39381440776fcda13779d269a8ba664f69bec0"}, + {file = "yarl-1.18.0.tar.gz", hash = "sha256:20d95535e7d833889982bfe7cc321b7f63bf8879788fee982c76ae2b24cfb715"}, ] From 4b7e77c95c5d124454cef99dc42cb0c017edbb6b Mon Sep 17 00:00:00 2001 From: Paillat Date: Sat, 30 Nov 2024 22:07:58 +0100 Subject: [PATCH 30/61] :technologist: Dev. experience improvements --- src/__main__.py | 40 +++++---------------- src/config/__init__.py | 4 +-- src/config/bot_config.py | 7 ---- src/extensions/nice_errors/handlers/base.py | 4 ++- src/patcher.py | 32 +++++++++++++++++ src/start.py | 20 ++++++++--- 6 files changed, 61 insertions(+), 46 deletions(-) create mode 100644 src/patcher.py diff --git a/src/__main__.py b/src/__main__.py index e315ba6..f845f62 100644 --- a/src/__main__.py +++ b/src/__main__.py @@ -7,40 +7,18 @@ sys.path.insert(0, os.path.abspath(os.path.join(os.path.dirname(__file__), ".."))) # the above line allows us to import from src without any issues whilst using src/__main__.py import asyncio -import importlib.util -from glob import iglob - -from src.config import config -from src.log import logger -from src.utils.setup_func import setup_func - - -async def load_and_run_patches() -> None: - for patch_file in iglob("src/extensions/*/patch.py"): - extension = os.path.basename(os.path.dirname(patch_file)) - if ( - config["extensions"] - .get(extension, config["extensions"].get(extension.replace("_", "-"))) - .get("enabled", False) - ): - logger.info(f"Loading patch for extension {extension}") - spec = importlib.util.spec_from_file_location(f"src.extensions.{extension}.patch", patch_file) - if not spec or not spec.loader: - continue - patch_module = importlib.util.module_from_spec(spec) - spec.loader.exec_module(patch_module) - if hasattr(patch_module, "patch") and callable(patch_module.patch): - await setup_func(patch_module.patch, config=config["extensions"][extension]) - - -async def pre_main() -> None: + +from src.patcher import load_and_run_patches + + +async def main() -> None: await load_and_run_patches() - # we import main here to apply patches before importing the most things we can + # we import main here to apply patches before importing as many things we can # and allow the patches to be applied to later imported modules - from src.start import main + from src.start import start - await main() + await start() if __name__ == "__main__": - asyncio.run(pre_main()) + asyncio.run(main()) diff --git a/src/config/__init__.py b/src/config/__init__.py index 89b40d8..3085e44 100644 --- a/src/config/__init__.py +++ b/src/config/__init__.py @@ -1,6 +1,6 @@ # Copyright (c) NiceBots.xyz # SPDX-License-Identifier: MIT -from .bot_config import config, store_config +from .bot_config import config -__all__ = ["config", "store_config"] +__all__ = ["config"] diff --git a/src/config/bot_config.py b/src/config/bot_config.py index ae682d4..f1aabe1 100644 --- a/src/config/bot_config.py +++ b/src/config/bot_config.py @@ -66,10 +66,3 @@ def load_json_recursive(data: dict[str, Any]) -> dict[str, Any]: config = yaml.safe_load(f) else: config = load_from_env() - - -def store_config() -> None: - if path: - # noinspection PyShadowingNames - with open(path, "w", encoding="utf-8") as f: - yaml.dump(config, f) diff --git a/src/extensions/nice_errors/handlers/base.py b/src/extensions/nice_errors/handlers/base.py index 5ce7384..e5881a6 100644 --- a/src/extensions/nice_errors/handlers/base.py +++ b/src/extensions/nice_errors/handlers/base.py @@ -111,7 +111,9 @@ def add_error_handler[E: Exception](self, error: None, handler: ErrorHandlerType def add_error_handler[E: Exception](self, error: type[E], handler: ErrorHandlerType[E]) -> None: ... def add_error_handler[E: Exception](self, error: type[E] | None, handler: ErrorHandlerType[E | Exception]) -> None: - logger.info(f"Adding error handler {handler} for {error if error is not None else 'Generic'}") + logger.info( + f"Adding error handler {handler.__class__.__qualname__} for {error.__qualname__ if error is not None else 'Generic'}" # noqa: E501 + ) self.error_handlers[error] = handler diff --git a/src/patcher.py b/src/patcher.py new file mode 100644 index 0000000..93ca504 --- /dev/null +++ b/src/patcher.py @@ -0,0 +1,32 @@ +# Copyright (c) NiceBots.xyz +# SPDX-License-Identifier: MIT + +import os +import sys +from typing import Any + +sys.path.insert(0, os.path.abspath(os.path.join(os.path.dirname(__file__), ".."))) +# the above line allows us to import from src without any issues whilst using src/__main__.py +import importlib.util +from glob import iglob + +from src.config import config +from src.log import logger +from src.utils.setup_func import setup_func + + +async def load_and_run_patches() -> None: + for patch_file in iglob("src/extensions/*/patch.py"): + extension = os.path.basename(os.path.dirname(patch_file)) + its_config: dict[Any, Any] = {} + if its_config := ( + config["extensions"].get(extension, config["extensions"].get(extension.replace("_", "-"), {})) + ) and its_config.get("enabled", False): + logger.info(f"Loading patch for extension {extension}") + spec = importlib.util.spec_from_file_location(f"src.extensions.{extension}.patch", patch_file) + if not spec or not spec.loader: + continue + patch_module = importlib.util.module_from_spec(spec) + spec.loader.exec_module(patch_module) + if hasattr(patch_module, "patch") and callable(patch_module.patch): + await setup_func(patch_module.patch, config=its_config) diff --git a/src/start.py b/src/start.py index 78840a6..6c69e2c 100644 --- a/src/start.py +++ b/src/start.py @@ -10,11 +10,12 @@ import discord import yaml +from discord.errors import LoginFailure from discord.ext import commands from quart import Quart from src import custom, i18n -from src.config import config, store_config +from src.config import config from src.i18n.classes import ExtensionTranslation from src.log import logger, patch from src.utils import setup_func, unzip_extensions, validate_module @@ -31,7 +32,11 @@ class FunctionConfig(TypedDict): async def start_bot(bot: custom.Bot, token: str) -> None: - await bot.start(token) + try: + await bot.start(token) + except LoginFailure as e: + logger.critical("Failed to log in, is the bot token valid?") + logger.debug("", exc_info=e) async def start_backend(app: Quart, bot: discord.Bot, token: str) -> None: @@ -72,6 +77,13 @@ def load_extensions() -> ( "list[ExtensionTranslation]", ] ): + """Load extensions from the extensions directory. + + Returns: + tuple[FunctionlistType, FunctionlistType, FunctionlistType, list[ExtensionTranslation]]: A tuple containing + the bot functions, backend functions, startup functions, and translations. + + """ bot_functions: FunctionlistType = [] back_functions: FunctionlistType = [] startup_functions: FunctionlistType = [] @@ -157,7 +169,7 @@ async def run_startup_functions( await asyncio.gather(*startup_coros) -async def main(run_bot: bool | None = None, run_backend: bool | None = None) -> None: +async def start(run_bot: bool | None = None, run_backend: bool | None = None) -> None: if not config.get("bot", {}).get("token"): logger.critical("No bot token provided in config, exiting...") return @@ -182,5 +194,3 @@ async def main(run_bot: bool | None = None, run_backend: bool | None = None) -> await run_startup_functions(startup_functions, app, back_bot) await asyncio.gather(*coros) - - store_config() From 45eb20d273b530f4ea079d610051455f9a694656 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Sun, 1 Dec 2024 12:22:39 +0100 Subject: [PATCH 31/61] Update dependencies (#55) Co-authored-by: github-actions --- requirements.txt | 180 ++++++++++++++++++++++++++--------------------- 1 file changed, 100 insertions(+), 80 deletions(-) diff --git a/requirements.txt b/requirements.txt index fad9f92..76fe6c2 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,32 +1,35 @@ # This file is @generated by PDM. # Please do not edit it manually. +aiocache[redis]==0.12.3 \ + --hash=sha256:889086fc24710f431937b87ad3720a289f7fc31c4fd8b68e9f918b9bacd8270d \ + --hash=sha256:f528b27bf4d436b497a1d0d1a8f59a542c153ab1e37c3621713cb376d44c4713 aiofile==3.9.0 \ --hash=sha256:ce2f6c1571538cbdfa0143b04e16b208ecb0e9cb4148e528af8a640ed51cc8aa \ --hash=sha256:e5ad718bb148b265b6df1b3752c4d1d83024b93da9bd599df74b9d9ffcf7919b aiofiles==24.1.0 \ --hash=sha256:22a075c9e5a3810f0c2e48f3008c94d68c65d763b9b03857924c99e57355166c \ --hash=sha256:b4ec55f4195e3eb5d7abd1bf7e061763e864dd4954231fb8539a0ef8bb8260e5 -aiohappyeyeballs==2.4.3 \ - --hash=sha256:75cf88a15106a5002a8eb1dab212525c00d1f4c0fa96e551c9fbe6f09a621586 \ - --hash=sha256:8a7a83727b2756f394ab2895ea0765a0a8c475e3c71e98d43d76f22b4b435572 -aiohttp==3.10.10 \ - --hash=sha256:007ec22fbc573e5eb2fb7dec4198ef8f6bf2fe4ce20020798b2eb5d0abda6138 \ - --hash=sha256:0631dd7c9f0822cc61c88586ca76d5b5ada26538097d0f1df510b082bad3411a \ - --hash=sha256:0b00807e2605f16e1e198f33a53ce3c4523114059b0c09c337209ae55e3823a8 \ - --hash=sha256:0e1b370d8007c4ae31ee6db7f9a2fe801a42b146cec80a86766e7ad5c4a259cf \ - --hash=sha256:438cd072f75bb6612f2aca29f8bd7cdf6e35e8f160bc312e49fbecab77c99e3a \ - --hash=sha256:50edbcad60d8f0e3eccc68da67f37268b5144ecc34d59f27a02f9611c1d4eec7 \ - --hash=sha256:59bb3c54aa420521dc4ce3cc2c3fe2ad82adf7b09403fa1f48ae45c0cbde6628 \ - --hash=sha256:5c6a5b8c7926ba5d8545c7dd22961a107526562da31a7a32fa2456baf040939f \ - --hash=sha256:9294bbb581f92770e6ed5c19559e1e99255e4ca604a22c5c6397b2f9dd3ee42c \ - --hash=sha256:9627cc1a10c8c409b5822a92d57a77f383b554463d1884008e051c32ab1b3742 \ - --hash=sha256:a45d85cf20b5e0d0aa5a8dca27cce8eddef3292bc29d72dcad1641f4ed50aa16 \ - --hash=sha256:a7d8d14fe962153fc681f6366bdec33d4356f98a3e3567782aac1b6e0e40109a \ - --hash=sha256:a8fa23fe62c436ccf23ff930149c047f060c7126eae3ccea005f0483f27b2e28 \ - --hash=sha256:baa42524a82f75303f714108fea528ccacf0386af429b69fff141ffef1c534f9 \ - --hash=sha256:c1277cd707c465cd09572a774559a3cc7c7a28802eb3a2a9472588f062097205 \ - --hash=sha256:f2d4324a98062be0525d16f768a03e0bbb3b9fe301ceee99611dc9a7953124e6 +aiohappyeyeballs==2.4.4 \ + --hash=sha256:5fdd7d87889c63183afc18ce9271f9b0a7d32c2303e394468dd45d514a757745 \ + --hash=sha256:a980909d50efcd44795c4afeca523296716d50cd756ddca6af8c65b996e27de8 +aiohttp==3.11.8 \ + --hash=sha256:0e3b5bfef913d6be270c81976fbc0cbf66625cd92663bbb7e03b3adbd6aa4ac6 \ + --hash=sha256:35d4545e7684da7a954ffc2dce495462cb16a902dffdebe98572408f6aaaee83 \ + --hash=sha256:47c6663df9446aa848b478413219600da4b54bc0409e1ac4bc80fb1a81501363 \ + --hash=sha256:7bc9d64a2350cbb29a9732334e1a0743cbb6844de1731cbdf5949b235653f3fd \ + --hash=sha256:85be3899e6860dd2cd3f4370ded6708e939d00d5ec922a8eb328d114db605a47 \ + --hash=sha256:98f596cf59292e779bc387f22378a3d2c5e052c9fe2bf822ac4f547c6fe57758 \ + --hash=sha256:a0ed9f1f2697713c48efc9ec483ad5d062e4aa91854f090a3eba0b19c002851d \ + --hash=sha256:a7def89a41fe32120d89cd4577f5efbab3c52234c5890066ced8a2f7202dff88 \ + --hash=sha256:afba47981ff73b1794c00dce774334dcfe62664b3b4f78f278b77d21ce9daf43 \ + --hash=sha256:b64fa6b76b35b695cd3e5c42a4e568cbea8d41c9e59165e2a43da00976e2027e \ + --hash=sha256:beae08f900b2980af4353a0200eb162b39f276fd8a6e43079a540f83964671f4 \ + --hash=sha256:c0dbae99737badf3f5e862088a118e28d3b36f03eb608a6382eddfd68178e05b \ + --hash=sha256:c665ed4b52256614858b20711bbbd2755b0e19ec86870f8ff1645acf9ae9e760 \ + --hash=sha256:cb51a81cb637b9a072c9cfae1839e35c6579638861eb3479eb5d6e6ce8bc6782 \ + --hash=sha256:d6f9e5fd1b3ecbaca3e04a15a02d1fa213248608caee99fd5bdddd4759959cf7 \ + --hash=sha256:dd2ca84e5f7a35f313a62eb7d6a50bac6760b60bafce34586750712731c0aeff aiosignal==1.3.1 \ --hash=sha256:54cd96e15e1649b75d6c87526a6ff0b6c1b0dd3459f43d9ca11d48c339b68cfc \ --hash=sha256:f8376fb07dd1e86a584e4fcdec80b36b7f81aac666ebc724e2c090300dd83b17 @@ -36,14 +39,17 @@ annotated-types==0.7.0 \ attrs==24.2.0 \ --hash=sha256:5cfb1b9148b5b086569baec03f20d7b6bf3bcacc9a42bebf87ffaaca362f6346 \ --hash=sha256:81921eb96de3191c8258c199618104dd27ac608d9366f5e35d011eae1867ede2 -blinker==1.8.2 \ - --hash=sha256:1779309f71bf239144b9399d06ae925637cf6634cf6bd131104184531bf67c01 \ - --hash=sha256:8f77b09d3bf7c795e969e9486f39c2c5e9c39d4ee07424be2bc594ece9642d83 +blinker==1.9.0 \ + --hash=sha256:b4ce2265a7abece45e7cc896e98dbebe6cead56bcf805a3d23136d145f5445bf \ + --hash=sha256:ba0efaa9080b619ff2f3459d1d500c57bddea4a6b424b60a91141db6fd2f08bc caio==0.9.17 \ --hash=sha256:0ddb253b145a53ecca76381677ce465bc5efeaecb6aaf493fac43ae79659f0fb \ --hash=sha256:8f30511526814d961aeef389ea6885273abe6c655f1e08abbadb95d12fdd9b4f \ --hash=sha256:b3e320b0ea371c810359934f8e8fe81777c493cc5fb4d41de44277cbe7336e74 \ --hash=sha256:c55d4dc6b3a36f93237ecd6360e1c131c3808bc47d4191a130148a99b80bb311 +certifi==2024.8.30 \ + --hash=sha256:922820b53db7a7257ffbda3f597266d435245903d80737e34f8a45ff3e3230d8 \ + --hash=sha256:bec941d2aa8195e248a60b31ff9f0558284cf01a52591ceda73ea9afffd69fd9 click==8.1.7 \ --hash=sha256:ae74fb96c20a0277a1d615f1e4d73c8414f5a98db8b799a7931d1582f3390c28 \ --hash=sha256:ca9853ad459e787e2192211578cc907e7594e294c7ccc834310722b41b9ca6de @@ -53,9 +59,9 @@ colorama==0.4.6; sys_platform == "win32" or platform_system == "Windows" \ coloredlogs==15.0.1 \ --hash=sha256:612ee75c546f53e92e70049c9dbfcc18c935a2b9a53b66085ce9ef6a6e5c0934 \ --hash=sha256:7c991aa71a4577af2f82600d8f8f3a89f936baeaf9b50a9c197da014e5bf16b0 -flask==3.0.3 \ - --hash=sha256:34e815dfaa43340d1d15a5c3a02b8476004037eb4840b34910c6e21679d288f3 \ - --hash=sha256:ceb27b0af3823ea2737928a4d99d125a06175b8512c445cbd9a9ce200ef76842 +flask==3.1.0 \ + --hash=sha256:5f873c5184c897c8d9d1b05df1e3d01b14910ce69607a117bd3277098a5836ac \ + --hash=sha256:d667207822eb83f1c4b50949b1623c8fc8d51f2341d65f72e1a1815397551136 frozenlist==1.5.0 \ --hash=sha256:000a77d6034fbad9b6bb880f7ec073027908f1b40254b5d6f26210d2dab1240e \ --hash=sha256:29d94c256679247b33a3dc96cce0f93cbc69c23bf75ff715919332fdbb6a32b8 \ @@ -131,18 +137,21 @@ multidict==6.1.0 \ --hash=sha256:820c661588bd01a0aa62a1283f20d2be4281b086f80dad9e955e690c75fb54a2 \ --hash=sha256:b04772ed465fa3cc947db808fa306d79b43e896beb677a56fb2347ca1a49c1fa \ --hash=sha256:b58c621844d55e71c1b7f7c498ce5aa6985d743a1a59034c57a905b3f153c1ef -orjson==3.10.11 \ - --hash=sha256:360a4e2c0943da7c21505e47cf6bd725588962ff1d739b99b14e2f7f3545ba51 \ - --hash=sha256:496e2cb45de21c369079ef2d662670a4892c81573bcc143c4205cae98282ba97 \ - --hash=sha256:51f3382415747e0dbda9dade6f1e1a01a9d37f630d8c9049a8ed0e385b7a90c0 \ - --hash=sha256:7dfa8db55c9792d53c5952900c6a919cfa377b4f4534c7a786484a6a4a350c19 \ - --hash=sha256:d4a62c49c506d4d73f59514986cadebb7e8d186ad510c518f439176cf8d5359d \ - --hash=sha256:dfbb2d460a855c9744bbc8e36f9c3a997c4b27d842f3d5559ed54326e6911f9b \ - --hash=sha256:e2f3b7c5803138e67028dde33450e054c87e0703afbe730c105f1fcd873496d5 \ - --hash=sha256:e35b6d730de6384d5b2dab5fd23f0d76fae8bbc8c353c2f78210aa5fa4beb3ef \ - --hash=sha256:f1eec3421a558ff7a9b010a6c7effcfa0ade65327a71bb9b02a1c3b77a247284 \ - --hash=sha256:f35a1b9f50a219f470e0e497ca30b285c9f34948d3c8160d5ad3a755d9299433 \ - --hash=sha256:f91d9eb554310472bd09f5347950b24442600594c2edc1421403d7610a0998fd +orjson==3.10.12 \ + --hash=sha256:0a78bbda3aea0f9f079057ee1ee8a1ecf790d4f1af88dd67493c6b8ee52506ff \ + --hash=sha256:16135ccca03445f37921fa4b585cff9a58aa8d81ebcb27622e69bfadd220b32c \ + --hash=sha256:22a51ae77680c5c4652ebc63a83d5255ac7d65582891d9424b566fb3b5375ee9 \ + --hash=sha256:24ce85f7100160936bc2116c09d1a8492639418633119a2224114f67f63a4559 \ + --hash=sha256:2d879c81172d583e34153d524fcba5d4adafbab8349a7b9f16ae511c2cee8708 \ + --hash=sha256:53206d72eb656ca5ac7d3a7141e83c5bbd3ac30d5eccfe019409177a57634b0d \ + --hash=sha256:8a76ba5fc8dd9c913640292df27bff80a685bed3a3c990d59aa6ce24c352f8fc \ + --hash=sha256:8dcb9673f108a93c1b52bfc51b0af422c2d08d4fc710ce9c839faad25020bb69 \ + --hash=sha256:910fdf2ac0637b9a77d1aad65f803bac414f0b06f720073438a7bd8906298192 \ + --hash=sha256:ac8010afc2150d417ebda810e8df08dd3f544e0dd2acab5370cfa6bcc0662f8f \ + --hash=sha256:ed459b46012ae950dd2e17150e838ab08215421487371fa79d0eced8d1461d70 \ + --hash=sha256:f4244b7018b5753ecd10a6d324ec1f347da130c953a9c88432c7fbc8875d13be \ + --hash=sha256:fc23f691fa0f5c140576b8c365bc942d577d861a9ee1142e4db468e4e17094fb \ + --hash=sha256:ff70ef093895fd53f4055ca75f93f047e088d1430888ca1229393a7c0521100f priority==2.0.0 \ --hash=sha256:6f8eefce5f3ad59baf2c080a664037bb4725cd0a790d53d59ab4059288faf6aa \ --hash=sha256:c965d54f1b8d0d0b19479db3924c7c36cf672dbf2aec92d43fbdaf4492ba18c0 @@ -168,23 +177,25 @@ propcache==0.2.0 \ py-cord==2.6.1 \ --hash=sha256:36064f225f2c7bbddfe542d5ed581f2a5744f618e039093cf7cd2659a58bc79b \ --hash=sha256:e3d3b528c5e37b0e0825f5b884cbb9267860976c1e4878e28b55da8fd3af834b -pydantic==2.9.2 \ - --hash=sha256:d155cef71265d1e9807ed1c32b4c8deec042a44a50a4188b25ac67ecd81a9c0f \ - --hash=sha256:f048cec7b26778210e28a0459867920654d48e5e62db0958433636cde4254f12 -pydantic-core==2.23.4 \ - --hash=sha256:128585782e5bfa515c590ccee4b727fb76925dd04a98864182b22e89a4e6ed36 \ - --hash=sha256:20152074317d9bed6b7a95ade3b7d6054845d70584216160860425f4fbd5ee9e \ - --hash=sha256:2584f7cf844ac4d970fba483a717dbe10c1c1c96a969bf65d61ffe94df1b2863 \ - --hash=sha256:33e3d65a85a2a4a0dc3b092b938a4062b1a05f3a9abde65ea93b233bca0e03f2 \ - --hash=sha256:4ba762ed58e8d68657fc1281e9bb72e1c3e79cc5d464be146e260c541ec12d84 \ - --hash=sha256:68665f4c17edcceecc112dfed5dbe6f92261fb9d6054b47d01bf6371a6196126 \ - --hash=sha256:723314c1d51722ab28bfcd5240d858512ffd3116449c557a1336cbe3919beb87 \ - --hash=sha256:9261d3ce84fa1d38ed649c3638feefeae23d32ba9182963e465d58d62203bd24 \ - --hash=sha256:97df63000f4fea395b2824da80e169731088656d1818a11b95f3b173747b6cd9 \ - --hash=sha256:bb2802e667b7051a1bebbfe93684841cc9351004e2badbd6411bf357ab8d5ac8 \ - --hash=sha256:d18ca8148bebe1b0a382a27a8ee60350091a6ddaf475fa05ef50dc35b5df6327 \ - --hash=sha256:f3e0da4ebaef65158d4dfd7d3678aad692f7666877df0002b8a522cdf088f231 \ - --hash=sha256:f69a8e0b033b747bb3e36a44e7732f0c99f7edd5cea723d45bc0d6e95377ffee +pydantic==2.10.2 \ + --hash=sha256:2bc2d7f17232e0841cbba4641e65ba1eb6fafb3a08de3a091ff3ce14a197c4fa \ + --hash=sha256:cfb96e45951117c3024e6b67b25cdc33a3cb7b2fa62e239f7af1378358a1d99e +pydantic-core==2.27.1 \ + --hash=sha256:0325336f348dbee6550d129b1627cb8f5351a9dc91aad141ffb96d4937bd9529 \ + --hash=sha256:15aae984e46de8d376df515f00450d1522077254ef6b7ce189b38ecee7c9677c \ + --hash=sha256:1ba5e3963344ff25fc8c40da90f44b0afca8cfd89d12964feb79ac1411a260ac \ + --hash=sha256:3bbd5d8cc692616d5ef6fbbbd50dbec142c7e6ad9beb66b78a96e9c16729b089 \ + --hash=sha256:5f8c4718cd44ec1580e180cb739713ecda2bdee1341084c1467802a417fe0f02 \ + --hash=sha256:62a763352879b84aa31058fc931884055fd75089cccbd9d58bb6afd01141b235 \ + --hash=sha256:66ff044fd0bb1768688aecbe28b6190f6e799349221fb0de0e6f4048eca14c16 \ + --hash=sha256:672ebbe820bb37988c4d136eca2652ee114992d5d41c7e4858cdd90ea94ffe5c \ + --hash=sha256:7597c07fbd11515f654d6ece3d0e4e5093edc30a436c63142d9a4b8e22f19c35 \ + --hash=sha256:992cea5f4f3b29d6b4f7f1726ed8ee46c8331c6b4eed6db5b40134c6fe1768bb \ + --hash=sha256:9a3b0793b1bbfd4146304e23d90045f2a9b5fd5823aa682665fbdaf2a6c28f3e \ + --hash=sha256:9cbd94fc661d2bab2bc702cddd2d3370bbdcc4cd0f8f57488a81bcce90c7a54f \ + --hash=sha256:dc61505e73298a84a2f317255fcc72b710b72980f3a1f670447a21efc88f8381 \ + --hash=sha256:e1f735dc43da318cad19b4173dd1ffce1d84aafd6c9b782b3abc04a0d5a6f5bb \ + --hash=sha256:f4e5658dbffe8843a0f12366a4c2d1c316dbe09bb4dfbdc9d2d9cd6031de8aae pyreadline3==3.5.4; sys_platform == "win32" and python_version >= "3.8" \ --hash=sha256:8d57d53039a1c75adba8e50dd3d992b28143480816187ea5efbd5c78e6c885b7 \ --hash=sha256:eaf8e6cc3c49bcccf145fc6067ba8643d1df34d604a1ec0eccbf7a18e6d3fae6 @@ -205,37 +216,46 @@ pyyaml==6.0.2 \ --hash=sha256:ce826d6ef20b1bc864f0a68340c8b3287705cae2f8b4b1d932177dcc76721725 \ --hash=sha256:d584d9ec91ad65861cc08d42e834324ef890a082e591037abe114850ff7bbc3e \ --hash=sha256:ef6107725bd54b262d6dedcc2af448a266975032bc85ef0172c5f059da6325b4 -quart==0.19.8 \ - --hash=sha256:34eeb559014f4e72e093d034cfe203b1a6262e9d3504f826f293090e230609f2 \ - --hash=sha256:ef567d0be7677c99890d5c6ff30e679699fe7e5fca1a90fa3b6974edd8421794 +quart==0.19.9 \ + --hash=sha256:30a61a0d7bae1ee13e6e99dc14c929b3c945e372b9445d92d21db053e91e95a5 \ + --hash=sha256:8acb8b299c72b66ee9e506ae141498bbbfcc250b5298fbdb712e97f3d7e4082f +redis==5.2.0 \ + --hash=sha256:0b1087665a771b1ff2e003aa5bdd354f15a70c9e25d5a7dbf9c722c16528a7b0 \ + --hash=sha256:ae174f2bb3b1bf2b09d54bf3e51fbc1469cf6c10aa03e21141f51969801a7897 schema==0.7.7 \ --hash=sha256:5d976a5b50f36e74e2157b47097b60002bd4d42e65425fcc9c9befadb4255dde \ --hash=sha256:7da553abd2958a19dc2547c388cde53398b39196175a9be59ea1caf5ab0a1807 +sentry-sdk==2.19.0 \ + --hash=sha256:7b0b3b709dee051337244a09a30dbf6e95afe0d34a1f8b430d45e0982a7c125b \ + --hash=sha256:ee4a4d2ae8bfe3cac012dcf3e4607975904c137e1738116549fc3dbbb6ff0e36 typing-extensions==4.12.2 \ --hash=sha256:04e5ca0351e0f3f85c6853954072df659d0d13fac324d0072316b67d7794700d \ --hash=sha256:1a7ead55c7e559dd4dee8856e3a88b41225abfe1ce8df57b7c13915fe121ffb8 -werkzeug==3.1.2 \ - --hash=sha256:4f7d1a5de312c810a8a2c6f0b47e9f6a7cffb7c8322def35e4d4d9841ff85597 \ - --hash=sha256:f471a4cd167233077e9d2a8190c3471c5bc520c636a9e3c1e9300c33bced03bc +urllib3==2.2.3 \ + --hash=sha256:ca899ca043dcb1bafa3e262d73aa25c465bfb49e0bd9dd5d59f1d0acba2f8fac \ + --hash=sha256:e7d814a81dad81e6caf2ec9fdedb284ecc9c73076b62654547cc64ccdcae26e9 +werkzeug==3.1.3 \ + --hash=sha256:54b78bf3716d19a65be4fceccc0d1d7b89e608834989dfae50ea87564639213e \ + --hash=sha256:60723ce945c19328679790e3282cc758aa4a6040e4bb330f53d30fa546d44746 wsproto==1.2.0 \ --hash=sha256:ad565f26ecb92588a3e43bc3d96164de84cd9902482b130d0ddbaa9664a85065 \ --hash=sha256:b9acddd652b585d75b20477888c56642fdade28bdfd3579aa24a4d2c037dd736 -yarl==1.17.1 \ - --hash=sha256:06157fb3c58f2736a5e47c8fcbe1afc8b5de6fb28b14d25574af9e62150fcaac \ - --hash=sha256:067a63fcfda82da6b198fa73079b1ca40b7c9b7994995b6ee38acda728b64d47 \ - --hash=sha256:0bdff5e0995522706c53078f531fb586f56de9c4c81c243865dd5c66c132c3b5 \ - --hash=sha256:117ed8b3732528a1e41af3aa6d4e08483c2f0f2e3d3d7dca7cf538b3516d93df \ - --hash=sha256:1654ec814b18be1af2c857aa9000de7a601400bd4c9ca24629b18486c2e35463 \ - --hash=sha256:327828786da2006085a4d1feb2594de6f6d26f8af48b81eb1ae950c788d97f61 \ - --hash=sha256:459e81c2fb920b5f5df744262d1498ec2c8081acdcfe18181da44c50f51312f7 \ - --hash=sha256:46ddf6e0b975cd680eb83318aa1d321cb2bf8d288d50f1754526230fcf59ba96 \ - --hash=sha256:5f236cb5999ccd23a0ab1bd219cfe0ee3e1c1b65aaf6dd3320e972f7ec3a39da \ - --hash=sha256:7e48cdb8226644e2fbd0bdb0a0f87906a3db07087f4de77a1b1b1ccfd9e93685 \ - --hash=sha256:7f6595c852ca544aaeeb32d357e62c9c780eac69dcd34e40cae7b55bc4fb1147 \ - --hash=sha256:a2a64e62c7a0edd07c1c917b0586655f3362d2c2d37d474db1a509efb96fea1c \ - --hash=sha256:c73df5b6e8fabe2ddb74876fb82d9dd44cbace0ca12e8861ce9155ad3c886139 \ - --hash=sha256:cc353841428d56b683a123a813e6a686e07026d6b1c5757970a877195f880c2d \ - --hash=sha256:d0eea830b591dbc68e030c86a9569826145df485b2b4554874b07fea1275a199 \ - --hash=sha256:d9b6b28a57feb51605d6ae5e61a9044a31742db557a3b851a74c13bc61de5172 \ - --hash=sha256:e594b22688d5747b06e957f1ef822060cb5cb35b493066e33ceac0cf882188b7 \ - --hash=sha256:f1790a4b1e8e8e028c391175433b9c8122c39b46e1663228158e61e6f915bf06 +yarl==1.18.0 \ + --hash=sha256:01be8688fc211dc237e628fcc209dda412d35de7642453059a0553747018d075 \ + --hash=sha256:039c299a0864d1f43c3e31570045635034ea7021db41bf4842693a72aca8df3a \ + --hash=sha256:1ece25e2251c28bab737bdf0519c88189b3dd9492dc086a1d77336d940c28ced \ + --hash=sha256:20d95535e7d833889982bfe7cc321b7f63bf8879788fee982c76ae2b24cfb715 \ + --hash=sha256:454902dc1830d935c90b5b53c863ba2a98dcde0fbaa31ca2ed1ad33b2a7171c6 \ + --hash=sha256:49a98ecadc5a241c9ba06de08127ee4796e1009555efd791bac514207862b43d \ + --hash=sha256:4d26f1fa9fa2167bb238f6f4b20218eb4e88dd3ef21bb8f97439fa6b5313e30d \ + --hash=sha256:80741ec5b471fbdfb997821b2842c59660a1c930ceb42f8a84ba8ca0f25a66aa \ + --hash=sha256:9106025c7f261f9f5144f9aa7681d43867eed06349a7cfb297a1bc804de2f0d1 \ + --hash=sha256:9b4c90c5363c6b0a54188122b61edb919c2cd1119684999d08cd5e538813a28e \ + --hash=sha256:b1a3297b9cad594e1ff0c040d2881d7d3a74124a3c73e00c3c71526a1234a9f7 \ + --hash=sha256:b234a4a9248a9f000b7a5dfe84b8cb6210ee5120ae70eb72a4dcbdb4c528f72f \ + --hash=sha256:c083f6dd6951b86e484ebfc9c3524b49bcaa9c420cb4b2a78ef9f7a512bfcc85 \ + --hash=sha256:cd6ab7d6776c186f544f893b45ee0c883542b35e8a493db74665d2e594d3ca75 \ + --hash=sha256:dbf53db46f7cf176ee01d8d98c39381440776fcda13779d269a8ba664f69bec0 \ + --hash=sha256:f275ede6199d0f1ed4ea5d55a7b7573ccd40d97aee7808559e1298fe6efc8dbd \ + --hash=sha256:f7edeb1dcc7f50a2c8e08b9dc13a413903b7817e72273f00878cb70e766bdb3b \ + --hash=sha256:fe94d1de77c4cd8caff1bd5480e22342dbd54c93929f5943495d9c1e8abe9f42 From 8d6a19fc960ab406061354c674cac8d47a07b2f0 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Sun, 1 Dec 2024 12:25:39 +0100 Subject: [PATCH 32/61] =?UTF-8?q?=E2=AC=86=EF=B8=8F=20Upgrade=20docker/met?= =?UTF-8?q?adata-action=20action=20to=20v5.6.1=20(#51)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- .github/workflows/docker.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/docker.yaml b/.github/workflows/docker.yaml index 7ddd9d5..1208eb6 100644 --- a/.github/workflows/docker.yaml +++ b/.github/workflows/docker.yaml @@ -29,7 +29,7 @@ jobs: - name: Extract Docker metadata id: meta - uses: docker/metadata-action@v5.5.1 + uses: docker/metadata-action@v5.6.1 with: images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }} tags: | From ac1abf0c7c7d52cbd25e2ad3fbdfd89851d302a5 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Sun, 1 Dec 2024 12:26:00 +0100 Subject: [PATCH 33/61] =?UTF-8?q?=E2=AC=86=EF=B8=8F=20Upgrade=20docker/bui?= =?UTF-8?q?ld-push-action=20action=20to=20v6.10.0=20(#53)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- .github/workflows/docker.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/docker.yaml b/.github/workflows/docker.yaml index 1208eb6..e553fb3 100644 --- a/.github/workflows/docker.yaml +++ b/.github/workflows/docker.yaml @@ -39,7 +39,7 @@ jobs: type=sha - name: Build and push Docker image - uses: docker/build-push-action@v6.9.0 + uses: docker/build-push-action@v6.10.0 with: context: . push: true From eecc0c3fdef96809df89a2e127fc276a343f2d4e Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Wed, 11 Dec 2024 11:46:04 +0100 Subject: [PATCH 34/61] Update dependencies (#56) Co-authored-by: github-actions --- pdm.lock | 200 ++++++++++++++++++++++++----------------------- requirements.txt | 128 +++++++++++++++--------------- 2 files changed, 166 insertions(+), 162 deletions(-) diff --git a/pdm.lock b/pdm.lock index 42ef5a3..1a00220 100644 --- a/pdm.lock +++ b/pdm.lock @@ -73,7 +73,7 @@ files = [ [[package]] name = "aiohttp" -version = "3.11.8" +version = "3.11.10" requires_python = ">=3.9" summary = "Async http client/server framework (asyncio)" groups = ["default"] @@ -88,22 +88,22 @@ dependencies = [ "yarl<2.0,>=1.17.0", ] files = [ - {file = "aiohttp-3.11.8-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:0e3b5bfef913d6be270c81976fbc0cbf66625cd92663bbb7e03b3adbd6aa4ac6"}, - {file = "aiohttp-3.11.8-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:cb51a81cb637b9a072c9cfae1839e35c6579638861eb3479eb5d6e6ce8bc6782"}, - {file = "aiohttp-3.11.8-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:dd2ca84e5f7a35f313a62eb7d6a50bac6760b60bafce34586750712731c0aeff"}, - {file = "aiohttp-3.11.8-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:47c6663df9446aa848b478413219600da4b54bc0409e1ac4bc80fb1a81501363"}, - {file = "aiohttp-3.11.8-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:c665ed4b52256614858b20711bbbd2755b0e19ec86870f8ff1645acf9ae9e760"}, - {file = "aiohttp-3.11.8-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:35d4545e7684da7a954ffc2dce495462cb16a902dffdebe98572408f6aaaee83"}, - {file = "aiohttp-3.11.8-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:85be3899e6860dd2cd3f4370ded6708e939d00d5ec922a8eb328d114db605a47"}, - {file = "aiohttp-3.11.8-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a0ed9f1f2697713c48efc9ec483ad5d062e4aa91854f090a3eba0b19c002851d"}, - {file = "aiohttp-3.11.8-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:c0dbae99737badf3f5e862088a118e28d3b36f03eb608a6382eddfd68178e05b"}, - {file = "aiohttp-3.11.8-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:beae08f900b2980af4353a0200eb162b39f276fd8a6e43079a540f83964671f4"}, - {file = "aiohttp-3.11.8-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:d6f9e5fd1b3ecbaca3e04a15a02d1fa213248608caee99fd5bdddd4759959cf7"}, - {file = "aiohttp-3.11.8-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:a7def89a41fe32120d89cd4577f5efbab3c52234c5890066ced8a2f7202dff88"}, - {file = "aiohttp-3.11.8-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:98f596cf59292e779bc387f22378a3d2c5e052c9fe2bf822ac4f547c6fe57758"}, - {file = "aiohttp-3.11.8-cp312-cp312-win32.whl", hash = "sha256:b64fa6b76b35b695cd3e5c42a4e568cbea8d41c9e59165e2a43da00976e2027e"}, - {file = "aiohttp-3.11.8-cp312-cp312-win_amd64.whl", hash = "sha256:afba47981ff73b1794c00dce774334dcfe62664b3b4f78f278b77d21ce9daf43"}, - {file = "aiohttp-3.11.8.tar.gz", hash = "sha256:7bc9d64a2350cbb29a9732334e1a0743cbb6844de1731cbdf5949b235653f3fd"}, + {file = "aiohttp-3.11.10-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:b78f053a7ecfc35f0451d961dacdc671f4bcbc2f58241a7c820e9d82559844cf"}, + {file = "aiohttp-3.11.10-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:ab7485222db0959a87fbe8125e233b5a6f01f4400785b36e8a7878170d8c3138"}, + {file = "aiohttp-3.11.10-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:cf14627232dfa8730453752e9cdc210966490992234d77ff90bc8dc0dce361d5"}, + {file = "aiohttp-3.11.10-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:076bc454a7e6fd646bc82ea7f98296be0b1219b5e3ef8a488afbdd8e81fbac50"}, + {file = "aiohttp-3.11.10-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:482cafb7dc886bebeb6c9ba7925e03591a62ab34298ee70d3dd47ba966370d2c"}, + {file = "aiohttp-3.11.10-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:bf3d1a519a324af764a46da4115bdbd566b3c73fb793ffb97f9111dbc684fc4d"}, + {file = "aiohttp-3.11.10-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:24213ba85a419103e641e55c27dc7ff03536c4873470c2478cce3311ba1eee7b"}, + {file = "aiohttp-3.11.10-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b99acd4730ad1b196bfb03ee0803e4adac371ae8efa7e1cbc820200fc5ded109"}, + {file = "aiohttp-3.11.10-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:14cdb5a9570be5a04eec2ace174a48ae85833c2aadc86de68f55541f66ce42ab"}, + {file = "aiohttp-3.11.10-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:7e97d622cb083e86f18317282084bc9fbf261801b0192c34fe4b1febd9f7ae69"}, + {file = "aiohttp-3.11.10-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:012f176945af138abc10c4a48743327a92b4ca9adc7a0e078077cdb5dbab7be0"}, + {file = "aiohttp-3.11.10-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:44224d815853962f48fe124748227773acd9686eba6dc102578defd6fc99e8d9"}, + {file = "aiohttp-3.11.10-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:c87bf31b7fdab94ae3adbe4a48e711bfc5f89d21cf4c197e75561def39e223bc"}, + {file = "aiohttp-3.11.10-cp312-cp312-win32.whl", hash = "sha256:06a8e2ee1cbac16fe61e51e0b0c269400e781b13bcfc33f5425912391a542985"}, + {file = "aiohttp-3.11.10-cp312-cp312-win_amd64.whl", hash = "sha256:be2b516f56ea883a3e14dda17059716593526e10fb6303189aaf5503937db408"}, + {file = "aiohttp-3.11.10.tar.gz", hash = "sha256:b1fc6b45010a8d0ff9e88f9f2418c6fd408c99c211257334aff41597ebece42e"}, ] [[package]] @@ -150,7 +150,7 @@ files = [ [[package]] name = "basedpyright" -version = "1.22.0" +version = "1.22.1" requires_python = ">=3.8" summary = "static type checking for Python (but based)" groups = ["dev"] @@ -158,8 +158,8 @@ dependencies = [ "nodejs-wheel-binaries>=20.13.1", ] files = [ - {file = "basedpyright-1.22.0-py3-none-any.whl", hash = "sha256:6376107086ad25525429b8a94a2ffdb67c6dd2b1a6be38bf3c6ea9b5c3d1f688"}, - {file = "basedpyright-1.22.0.tar.gz", hash = "sha256:457e97ac4c3f694b900453d3f8824af36d17b9cef3d76c623e665dd4c7872d9c"}, + {file = "basedpyright-1.22.1-py3-none-any.whl", hash = "sha256:b25597757400ec082b1099eb99f0fc74857ff4dcd7caa198bf1e236d17214ebf"}, + {file = "basedpyright-1.22.1.tar.gz", hash = "sha256:f7a2d0e49c7d375ce9e02a7c235536e824833c9df89c2ca7e605ab1a2995808f"}, ] [[package]] @@ -522,18 +522,22 @@ files = [ [[package]] name = "nodejs-wheel-binaries" -version = "22.11.0" +version = "22.12.0" requires_python = ">=3.7" summary = "unoffical Node.js package" groups = ["dev"] +dependencies = [ + "typing-extensions; python_version < \"3.8\"", +] files = [ - {file = "nodejs_wheel_binaries-22.11.0-py2.py3-none-macosx_11_0_arm64.whl", hash = "sha256:00afada277fd6e945a74f881831aaf1bb7f853a15e15e8c998238ab88d327f6a"}, - {file = "nodejs_wheel_binaries-22.11.0-py2.py3-none-macosx_11_0_x86_64.whl", hash = "sha256:f29471263d65a66520a04a0e74ff641a775df1135283f0b4d1826048932b289d"}, - {file = "nodejs_wheel_binaries-22.11.0-py2.py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bd2ff0e20389f22927e311ccab69c1ecb34c3431fa809d1548e7000dc8248680"}, - {file = "nodejs_wheel_binaries-22.11.0-py2.py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a9545cc43f1ba2c9f467f3444e9cd7f8db059933be1a5215135610dee5b38bf3"}, - {file = "nodejs_wheel_binaries-22.11.0-py2.py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:43a277cbabf4b68e0a4798578a4f17e5f518ada1f79a174bfde06eb2bb47e730"}, - {file = "nodejs_wheel_binaries-22.11.0-py2.py3-none-win_amd64.whl", hash = "sha256:8310ab182ee159141e08c85bc07f11e67ac3044922e6e4958f4a8f3ba6860185"}, - {file = "nodejs_wheel_binaries-22.11.0.tar.gz", hash = "sha256:e67f4e4a646bba24baa2150460c9cfbde0f75169ba37e58a2341930a5c1456ee"}, + {file = "nodejs_wheel_binaries-22.12.0-py2.py3-none-macosx_11_0_arm64.whl", hash = "sha256:8ed26eac5a96f3bfcd36f1eb9c397f07392e8b166895e0a65eb6033baefa0217"}, + {file = "nodejs_wheel_binaries-22.12.0-py2.py3-none-macosx_11_0_x86_64.whl", hash = "sha256:ca853c919e18860eb75ac3563985391d07eb50f6ab0aadcb48842bcc0ee8dd45"}, + {file = "nodejs_wheel_binaries-22.12.0-py2.py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e6df3f2606e26d3334de1fc15c4e6a833980a02ed2eae528d90ddaacaaab2dd1"}, + {file = "nodejs_wheel_binaries-22.12.0-py2.py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:335176ffa5f753c4d447af83f70987f5f82becdf84fadf56d5c0036379826cff"}, + {file = "nodejs_wheel_binaries-22.12.0-py2.py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:44f0b372a9ea218be885d14b370e774366d09697ae193b741b83cf04c6753884"}, + {file = "nodejs_wheel_binaries-22.12.0-py2.py3-none-win_amd64.whl", hash = "sha256:d1a63fc84b0a5a94b19f428ecc1eb1bf4d09c9fc26390db52231c01c3667fe82"}, + {file = "nodejs_wheel_binaries-22.12.0-py2.py3-none-win_arm64.whl", hash = "sha256:cc363752be784bf6496329060c53c4d8a993dca73815bb179b37dba5c6d6db1c"}, + {file = "nodejs_wheel_binaries-22.12.0.tar.gz", hash = "sha256:e9b707766498322bb2b79fb4f6f425ef86904feccc72cc426f8d96f75488518e"}, ] [[package]] @@ -610,29 +614,29 @@ files = [ [[package]] name = "propcache" -version = "0.2.0" -requires_python = ">=3.8" +version = "0.2.1" +requires_python = ">=3.9" summary = "Accelerated property cache" groups = ["default"] files = [ - {file = "propcache-0.2.0-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:2ee7606193fb267be4b2e3b32714f2d58cad27217638db98a60f9efb5efeccc2"}, - {file = "propcache-0.2.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:91ee8fc02ca52e24bcb77b234f22afc03288e1dafbb1f88fe24db308910c4ac7"}, - {file = "propcache-0.2.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:2e900bad2a8456d00a113cad8c13343f3b1f327534e3589acc2219729237a2e8"}, - {file = "propcache-0.2.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f52a68c21363c45297aca15561812d542f8fc683c85201df0bebe209e349f793"}, - {file = "propcache-0.2.0-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1e41d67757ff4fbc8ef2af99b338bfb955010444b92929e9e55a6d4dcc3c4f09"}, - {file = "propcache-0.2.0-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a64e32f8bd94c105cc27f42d3b658902b5bcc947ece3c8fe7bc1b05982f60e89"}, - {file = "propcache-0.2.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:55346705687dbd7ef0d77883ab4f6fabc48232f587925bdaf95219bae072491e"}, - {file = "propcache-0.2.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:00181262b17e517df2cd85656fcd6b4e70946fe62cd625b9d74ac9977b64d8d9"}, - {file = "propcache-0.2.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:6994984550eaf25dd7fc7bd1b700ff45c894149341725bb4edc67f0ffa94efa4"}, - {file = "propcache-0.2.0-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:56295eb1e5f3aecd516d91b00cfd8bf3a13991de5a479df9e27dd569ea23959c"}, - {file = "propcache-0.2.0-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:439e76255daa0f8151d3cb325f6dd4a3e93043e6403e6491813bcaaaa8733887"}, - {file = "propcache-0.2.0-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:f6475a1b2ecb310c98c28d271a30df74f9dd436ee46d09236a6b750a7599ce57"}, - {file = "propcache-0.2.0-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:3444cdba6628accf384e349014084b1cacd866fbb88433cd9d279d90a54e0b23"}, - {file = "propcache-0.2.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:4a9d9b4d0a9b38d1c391bb4ad24aa65f306c6f01b512e10a8a34a2dc5675d348"}, - {file = "propcache-0.2.0-cp312-cp312-win32.whl", hash = "sha256:69d3a98eebae99a420d4b28756c8ce6ea5a29291baf2dc9ff9414b42676f61d5"}, - {file = "propcache-0.2.0-cp312-cp312-win_amd64.whl", hash = "sha256:ad9c9b99b05f163109466638bd30ada1722abb01bbb85c739c50b6dc11f92dc3"}, - {file = "propcache-0.2.0-py3-none-any.whl", hash = "sha256:2ccc28197af5313706511fab3a8b66dcd6da067a1331372c82ea1cb74285e036"}, - {file = "propcache-0.2.0.tar.gz", hash = "sha256:df81779732feb9d01e5d513fad0122efb3d53bbc75f61b2a4f29a020bc985e70"}, + {file = "propcache-0.2.1-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:081a430aa8d5e8876c6909b67bd2d937bfd531b0382d3fdedb82612c618bc41a"}, + {file = "propcache-0.2.1-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:d2ccec9ac47cf4e04897619c0e0c1a48c54a71bdf045117d3a26f80d38ab1fb0"}, + {file = "propcache-0.2.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:14d86fe14b7e04fa306e0c43cdbeebe6b2c2156a0c9ce56b815faacc193e320d"}, + {file = "propcache-0.2.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:049324ee97bb67285b49632132db351b41e77833678432be52bdd0289c0e05e4"}, + {file = "propcache-0.2.1-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1cd9a1d071158de1cc1c71a26014dcdfa7dd3d5f4f88c298c7f90ad6f27bb46d"}, + {file = "propcache-0.2.1-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:98110aa363f1bb4c073e8dcfaefd3a5cea0f0834c2aab23dda657e4dab2f53b5"}, + {file = "propcache-0.2.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:647894f5ae99c4cf6bb82a1bb3a796f6e06af3caa3d32e26d2350d0e3e3faf24"}, + {file = "propcache-0.2.1-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:bfd3223c15bebe26518d58ccf9a39b93948d3dcb3e57a20480dfdd315356baff"}, + {file = "propcache-0.2.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:d71264a80f3fcf512eb4f18f59423fe82d6e346ee97b90625f283df56aee103f"}, + {file = "propcache-0.2.1-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:e73091191e4280403bde6c9a52a6999d69cdfde498f1fdf629105247599b57ec"}, + {file = "propcache-0.2.1-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:3935bfa5fede35fb202c4b569bb9c042f337ca4ff7bd540a0aa5e37131659348"}, + {file = "propcache-0.2.1-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:f508b0491767bb1f2b87fdfacaba5f7eddc2f867740ec69ece6d1946d29029a6"}, + {file = "propcache-0.2.1-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:1672137af7c46662a1c2be1e8dc78cb6d224319aaa40271c9257d886be4363a6"}, + {file = "propcache-0.2.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:b74c261802d3d2b85c9df2dfb2fa81b6f90deeef63c2db9f0e029a3cac50b518"}, + {file = "propcache-0.2.1-cp312-cp312-win32.whl", hash = "sha256:d09c333d36c1409d56a9d29b3a1b800a42c76a57a5a8907eacdbce3f18768246"}, + {file = "propcache-0.2.1-cp312-cp312-win_amd64.whl", hash = "sha256:c214999039d4f2a5b2073ac506bba279945233da8c786e490d411dfc30f855c1"}, + {file = "propcache-0.2.1-py3-none-any.whl", hash = "sha256:52277518d6aae65536e9cea52d4e7fd2f7a66f4aa2d30ed3f2fcea620ace3c54"}, + {file = "propcache-0.2.1.tar.gz", hash = "sha256:3f77ce728b19cb537714499928fe800c3dda29e8d9428778fc7c186da4c09a64"}, ] [[package]] @@ -652,7 +656,7 @@ files = [ [[package]] name = "pydantic" -version = "2.10.2" +version = "2.10.3" requires_python = ">=3.8" summary = "Data validation using Python type hints" groups = ["default"] @@ -662,8 +666,8 @@ dependencies = [ "typing-extensions>=4.12.2", ] files = [ - {file = "pydantic-2.10.2-py3-none-any.whl", hash = "sha256:cfb96e45951117c3024e6b67b25cdc33a3cb7b2fa62e239f7af1378358a1d99e"}, - {file = "pydantic-2.10.2.tar.gz", hash = "sha256:2bc2d7f17232e0841cbba4641e65ba1eb6fafb3a08de3a091ff3ce14a197c4fa"}, + {file = "pydantic-2.10.3-py3-none-any.whl", hash = "sha256:be04d85bbc7b65651c5f8e6b9976ed9c6f41782a55524cef079a34a0bb82144d"}, + {file = "pydantic-2.10.3.tar.gz", hash = "sha256:cb5ac360ce894ceacd69c403187900a02c4b20b693a9dd1d643e1effab9eadf9"}, ] [[package]] @@ -707,7 +711,7 @@ files = [ [[package]] name = "pytest" -version = "8.3.3" +version = "8.3.4" requires_python = ">=3.8" summary = "pytest: simple powerful testing with Python" groups = ["dev"] @@ -720,8 +724,8 @@ dependencies = [ "tomli>=1; python_version < \"3.11\"", ] files = [ - {file = "pytest-8.3.3-py3-none-any.whl", hash = "sha256:a6853c7375b2663155079443d2e45de913a911a11d669df02a50814944db57b2"}, - {file = "pytest-8.3.3.tar.gz", hash = "sha256:70b98107bd648308a7952b06e6ca9a50bc660be218d53c257cc1fc94fda10181"}, + {file = "pytest-8.3.4-py3-none-any.whl", hash = "sha256:50e16d954148559c9a74109af1eaf0c945ba2d8f30f0a3d3335edde19788b6f6"}, + {file = "pytest-8.3.4.tar.gz", hash = "sha256:965370d062bce11e73868e0335abac31b4d3de0e82f4007408d242b4f8610761"}, ] [[package]] @@ -790,7 +794,7 @@ files = [ [[package]] name = "redis" -version = "5.2.0" +version = "5.2.1" requires_python = ">=3.8" summary = "Python client for Redis database and key-value store" groups = ["default"] @@ -798,35 +802,35 @@ dependencies = [ "async-timeout>=4.0.3; python_full_version < \"3.11.3\"", ] files = [ - {file = "redis-5.2.0-py3-none-any.whl", hash = "sha256:ae174f2bb3b1bf2b09d54bf3e51fbc1469cf6c10aa03e21141f51969801a7897"}, - {file = "redis-5.2.0.tar.gz", hash = "sha256:0b1087665a771b1ff2e003aa5bdd354f15a70c9e25d5a7dbf9c722c16528a7b0"}, + {file = "redis-5.2.1-py3-none-any.whl", hash = "sha256:ee7e1056b9aea0f04c6c2ed59452947f34c4940ee025f5dd83e6a6418b6989e4"}, + {file = "redis-5.2.1.tar.gz", hash = "sha256:16f2e22dff21d5125e8481515e386711a34cbec50f0e44413dd7d9c060a54e0f"}, ] [[package]] name = "ruff" -version = "0.8.1" +version = "0.8.2" requires_python = ">=3.7" summary = "An extremely fast Python linter and code formatter, written in Rust." groups = ["dev"] files = [ - {file = "ruff-0.8.1-py3-none-linux_armv6l.whl", hash = "sha256:fae0805bd514066f20309f6742f6ee7904a773eb9e6c17c45d6b1600ca65c9b5"}, - {file = "ruff-0.8.1-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:b8a4f7385c2285c30f34b200ca5511fcc865f17578383db154e098150ce0a087"}, - {file = "ruff-0.8.1-py3-none-macosx_11_0_arm64.whl", hash = "sha256:cd054486da0c53e41e0086e1730eb77d1f698154f910e0cd9e0d64274979a209"}, - {file = "ruff-0.8.1-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2029b8c22da147c50ae577e621a5bfbc5d1fed75d86af53643d7a7aee1d23871"}, - {file = "ruff-0.8.1-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:2666520828dee7dfc7e47ee4ea0d928f40de72056d929a7c5292d95071d881d1"}, - {file = "ruff-0.8.1-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:333c57013ef8c97a53892aa56042831c372e0bb1785ab7026187b7abd0135ad5"}, - {file = "ruff-0.8.1-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:288326162804f34088ac007139488dcb43de590a5ccfec3166396530b58fb89d"}, - {file = "ruff-0.8.1-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b12c39b9448632284561cbf4191aa1b005882acbc81900ffa9f9f471c8ff7e26"}, - {file = "ruff-0.8.1-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:364e6674450cbac8e998f7b30639040c99d81dfb5bbc6dfad69bc7a8f916b3d1"}, - {file = "ruff-0.8.1-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b22346f845fec132aa39cd29acb94451d030c10874408dbf776af3aaeb53284c"}, - {file = "ruff-0.8.1-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:b2f2f7a7e7648a2bfe6ead4e0a16745db956da0e3a231ad443d2a66a105c04fa"}, - {file = "ruff-0.8.1-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:adf314fc458374c25c5c4a4a9270c3e8a6a807b1bec018cfa2813d6546215540"}, - {file = "ruff-0.8.1-py3-none-musllinux_1_2_i686.whl", hash = "sha256:a885d68342a231b5ba4d30b8c6e1b1ee3a65cf37e3d29b3c74069cdf1ee1e3c9"}, - {file = "ruff-0.8.1-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:d2c16e3508c8cc73e96aa5127d0df8913d2290098f776416a4b157657bee44c5"}, - {file = "ruff-0.8.1-py3-none-win32.whl", hash = "sha256:93335cd7c0eaedb44882d75a7acb7df4b77cd7cd0d2255c93b28791716e81790"}, - {file = "ruff-0.8.1-py3-none-win_amd64.whl", hash = "sha256:2954cdbe8dfd8ab359d4a30cd971b589d335a44d444b6ca2cb3d1da21b75e4b6"}, - {file = "ruff-0.8.1-py3-none-win_arm64.whl", hash = "sha256:55873cc1a473e5ac129d15eccb3c008c096b94809d693fc7053f588b67822737"}, - {file = "ruff-0.8.1.tar.gz", hash = "sha256:3583db9a6450364ed5ca3f3b4225958b24f78178908d5c4bc0f46251ccca898f"}, + {file = "ruff-0.8.2-py3-none-linux_armv6l.whl", hash = "sha256:c49ab4da37e7c457105aadfd2725e24305ff9bc908487a9bf8d548c6dad8bb3d"}, + {file = "ruff-0.8.2-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:ec016beb69ac16be416c435828be702ee694c0d722505f9c1f35e1b9c0cc1bf5"}, + {file = "ruff-0.8.2-py3-none-macosx_11_0_arm64.whl", hash = "sha256:f05cdf8d050b30e2ba55c9b09330b51f9f97d36d4673213679b965d25a785f3c"}, + {file = "ruff-0.8.2-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:60f578c11feb1d3d257b2fb043ddb47501ab4816e7e221fbb0077f0d5d4e7b6f"}, + {file = "ruff-0.8.2-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:cbd5cf9b0ae8f30eebc7b360171bd50f59ab29d39f06a670b3e4501a36ba5897"}, + {file = "ruff-0.8.2-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b402ddee3d777683de60ff76da801fa7e5e8a71038f57ee53e903afbcefdaa58"}, + {file = "ruff-0.8.2-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:705832cd7d85605cb7858d8a13d75993c8f3ef1397b0831289109e953d833d29"}, + {file = "ruff-0.8.2-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:32096b41aaf7a5cc095fa45b4167b890e4c8d3fd217603f3634c92a541de7248"}, + {file = "ruff-0.8.2-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e769083da9439508833cfc7c23e351e1809e67f47c50248250ce1ac52c21fb93"}, + {file = "ruff-0.8.2-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5fe716592ae8a376c2673fdfc1f5c0c193a6d0411f90a496863c99cd9e2ae25d"}, + {file = "ruff-0.8.2-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:81c148825277e737493242b44c5388a300584d73d5774defa9245aaef55448b0"}, + {file = "ruff-0.8.2-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:d261d7850c8367704874847d95febc698a950bf061c9475d4a8b7689adc4f7fa"}, + {file = "ruff-0.8.2-py3-none-musllinux_1_2_i686.whl", hash = "sha256:1ca4e3a87496dc07d2427b7dd7ffa88a1e597c28dad65ae6433ecb9f2e4f022f"}, + {file = "ruff-0.8.2-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:729850feed82ef2440aa27946ab39c18cb4a8889c1128a6d589ffa028ddcfc22"}, + {file = "ruff-0.8.2-py3-none-win32.whl", hash = "sha256:ac42caaa0411d6a7d9594363294416e0e48fc1279e1b0e948391695db2b3d5b1"}, + {file = "ruff-0.8.2-py3-none-win_amd64.whl", hash = "sha256:2aae99ec70abf43372612a838d97bfe77d45146254568d94926e8ed5bbb409ea"}, + {file = "ruff-0.8.2-py3-none-win_arm64.whl", hash = "sha256:fb88e2a506b70cfbc2de6fae6681c4f944f7dd5f2fe87233a7233d888bad73e8"}, + {file = "ruff-0.8.2.tar.gz", hash = "sha256:b84f4f414dda8ac7f75075c1fa0b905ac0ff25361f42e6d5da681a465e0f78e5"}, ] [[package]] @@ -844,7 +848,7 @@ files = [ [[package]] name = "sentry-sdk" -version = "2.19.0" +version = "2.19.2" requires_python = ">=3.6" summary = "Python client for Sentry (https://sentry.io)" groups = ["default"] @@ -853,8 +857,8 @@ dependencies = [ "urllib3>=1.26.11", ] files = [ - {file = "sentry_sdk-2.19.0-py2.py3-none-any.whl", hash = "sha256:7b0b3b709dee051337244a09a30dbf6e95afe0d34a1f8b430d45e0982a7c125b"}, - {file = "sentry_sdk-2.19.0.tar.gz", hash = "sha256:ee4a4d2ae8bfe3cac012dcf3e4607975904c137e1738116549fc3dbbb6ff0e36"}, + {file = "sentry_sdk-2.19.2-py2.py3-none-any.whl", hash = "sha256:ebdc08228b4d131128e568d696c210d846e5b9d70aa0327dec6b1272d9d40b84"}, + {file = "sentry_sdk-2.19.2.tar.gz", hash = "sha256:467df6e126ba242d39952375dd816fbee0f217d119bf454a8ce74cf1e7909e8d"}, ] [[package]] @@ -973,7 +977,7 @@ files = [ [[package]] name = "yarl" -version = "1.18.0" +version = "1.18.3" requires_python = ">=3.9" summary = "Yet another URL library" groups = ["default"] @@ -983,22 +987,22 @@ dependencies = [ "propcache>=0.2.0", ] files = [ - {file = "yarl-1.18.0-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:1ece25e2251c28bab737bdf0519c88189b3dd9492dc086a1d77336d940c28ced"}, - {file = "yarl-1.18.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:454902dc1830d935c90b5b53c863ba2a98dcde0fbaa31ca2ed1ad33b2a7171c6"}, - {file = "yarl-1.18.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:01be8688fc211dc237e628fcc209dda412d35de7642453059a0553747018d075"}, - {file = "yarl-1.18.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4d26f1fa9fa2167bb238f6f4b20218eb4e88dd3ef21bb8f97439fa6b5313e30d"}, - {file = "yarl-1.18.0-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b234a4a9248a9f000b7a5dfe84b8cb6210ee5120ae70eb72a4dcbdb4c528f72f"}, - {file = "yarl-1.18.0-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:fe94d1de77c4cd8caff1bd5480e22342dbd54c93929f5943495d9c1e8abe9f42"}, - {file = "yarl-1.18.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9b4c90c5363c6b0a54188122b61edb919c2cd1119684999d08cd5e538813a28e"}, - {file = "yarl-1.18.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:49a98ecadc5a241c9ba06de08127ee4796e1009555efd791bac514207862b43d"}, - {file = "yarl-1.18.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:9106025c7f261f9f5144f9aa7681d43867eed06349a7cfb297a1bc804de2f0d1"}, - {file = "yarl-1.18.0-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:f275ede6199d0f1ed4ea5d55a7b7573ccd40d97aee7808559e1298fe6efc8dbd"}, - {file = "yarl-1.18.0-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:f7edeb1dcc7f50a2c8e08b9dc13a413903b7817e72273f00878cb70e766bdb3b"}, - {file = "yarl-1.18.0-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:c083f6dd6951b86e484ebfc9c3524b49bcaa9c420cb4b2a78ef9f7a512bfcc85"}, - {file = "yarl-1.18.0-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:80741ec5b471fbdfb997821b2842c59660a1c930ceb42f8a84ba8ca0f25a66aa"}, - {file = "yarl-1.18.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:b1a3297b9cad594e1ff0c040d2881d7d3a74124a3c73e00c3c71526a1234a9f7"}, - {file = "yarl-1.18.0-cp312-cp312-win32.whl", hash = "sha256:cd6ab7d6776c186f544f893b45ee0c883542b35e8a493db74665d2e594d3ca75"}, - {file = "yarl-1.18.0-cp312-cp312-win_amd64.whl", hash = "sha256:039c299a0864d1f43c3e31570045635034ea7021db41bf4842693a72aca8df3a"}, - {file = "yarl-1.18.0-py3-none-any.whl", hash = "sha256:dbf53db46f7cf176ee01d8d98c39381440776fcda13779d269a8ba664f69bec0"}, - {file = "yarl-1.18.0.tar.gz", hash = "sha256:20d95535e7d833889982bfe7cc321b7f63bf8879788fee982c76ae2b24cfb715"}, + {file = "yarl-1.18.3-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:1dd4bdd05407ced96fed3d7f25dbbf88d2ffb045a0db60dbc247f5b3c5c25d50"}, + {file = "yarl-1.18.3-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:7c33dd1931a95e5d9a772d0ac5e44cac8957eaf58e3c8da8c1414de7dd27c576"}, + {file = "yarl-1.18.3-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:25b411eddcfd56a2f0cd6a384e9f4f7aa3efee14b188de13048c25b5e91f1640"}, + {file = "yarl-1.18.3-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:436c4fc0a4d66b2badc6c5fc5ef4e47bb10e4fd9bf0c79524ac719a01f3607c2"}, + {file = "yarl-1.18.3-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e35ef8683211db69ffe129a25d5634319a677570ab6b2eba4afa860f54eeaf75"}, + {file = "yarl-1.18.3-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:84b2deecba4a3f1a398df819151eb72d29bfeb3b69abb145a00ddc8d30094512"}, + {file = "yarl-1.18.3-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:00e5a1fea0fd4f5bfa7440a47eff01d9822a65b4488f7cff83155a0f31a2ecba"}, + {file = "yarl-1.18.3-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d0e883008013c0e4aef84dcfe2a0b172c4d23c2669412cf5b3371003941f72bb"}, + {file = "yarl-1.18.3-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:5a3f356548e34a70b0172d8890006c37be92995f62d95a07b4a42e90fba54272"}, + {file = "yarl-1.18.3-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:ccd17349166b1bee6e529b4add61727d3f55edb7babbe4069b5764c9587a8cc6"}, + {file = "yarl-1.18.3-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:b958ddd075ddba5b09bb0be8a6d9906d2ce933aee81100db289badbeb966f54e"}, + {file = "yarl-1.18.3-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:c7d79f7d9aabd6011004e33b22bc13056a3e3fb54794d138af57f5ee9d9032cb"}, + {file = "yarl-1.18.3-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:4891ed92157e5430874dad17b15eb1fda57627710756c27422200c52d8a4e393"}, + {file = "yarl-1.18.3-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:ce1af883b94304f493698b00d0f006d56aea98aeb49d75ec7d98cd4a777e9285"}, + {file = "yarl-1.18.3-cp312-cp312-win32.whl", hash = "sha256:f91c4803173928a25e1a55b943c81f55b8872f0018be83e3ad4938adffb77dd2"}, + {file = "yarl-1.18.3-cp312-cp312-win_amd64.whl", hash = "sha256:7e2ee16578af3b52ac2f334c3b1f92262f47e02cc6193c598502bd46f5cd1477"}, + {file = "yarl-1.18.3-py3-none-any.whl", hash = "sha256:b57f4f58099328dfb26c6a771d09fb20dbbae81d20cfb66141251ea063bd101b"}, + {file = "yarl-1.18.3.tar.gz", hash = "sha256:ac1801c45cbf77b6c99242eeff4fffb5e4e73a800b5c4ad4fc0be5def634d2e1"}, ] diff --git a/requirements.txt b/requirements.txt index 76fe6c2..e8f3d8d 100644 --- a/requirements.txt +++ b/requirements.txt @@ -13,23 +13,23 @@ aiofiles==24.1.0 \ aiohappyeyeballs==2.4.4 \ --hash=sha256:5fdd7d87889c63183afc18ce9271f9b0a7d32c2303e394468dd45d514a757745 \ --hash=sha256:a980909d50efcd44795c4afeca523296716d50cd756ddca6af8c65b996e27de8 -aiohttp==3.11.8 \ - --hash=sha256:0e3b5bfef913d6be270c81976fbc0cbf66625cd92663bbb7e03b3adbd6aa4ac6 \ - --hash=sha256:35d4545e7684da7a954ffc2dce495462cb16a902dffdebe98572408f6aaaee83 \ - --hash=sha256:47c6663df9446aa848b478413219600da4b54bc0409e1ac4bc80fb1a81501363 \ - --hash=sha256:7bc9d64a2350cbb29a9732334e1a0743cbb6844de1731cbdf5949b235653f3fd \ - --hash=sha256:85be3899e6860dd2cd3f4370ded6708e939d00d5ec922a8eb328d114db605a47 \ - --hash=sha256:98f596cf59292e779bc387f22378a3d2c5e052c9fe2bf822ac4f547c6fe57758 \ - --hash=sha256:a0ed9f1f2697713c48efc9ec483ad5d062e4aa91854f090a3eba0b19c002851d \ - --hash=sha256:a7def89a41fe32120d89cd4577f5efbab3c52234c5890066ced8a2f7202dff88 \ - --hash=sha256:afba47981ff73b1794c00dce774334dcfe62664b3b4f78f278b77d21ce9daf43 \ - --hash=sha256:b64fa6b76b35b695cd3e5c42a4e568cbea8d41c9e59165e2a43da00976e2027e \ - --hash=sha256:beae08f900b2980af4353a0200eb162b39f276fd8a6e43079a540f83964671f4 \ - --hash=sha256:c0dbae99737badf3f5e862088a118e28d3b36f03eb608a6382eddfd68178e05b \ - --hash=sha256:c665ed4b52256614858b20711bbbd2755b0e19ec86870f8ff1645acf9ae9e760 \ - --hash=sha256:cb51a81cb637b9a072c9cfae1839e35c6579638861eb3479eb5d6e6ce8bc6782 \ - --hash=sha256:d6f9e5fd1b3ecbaca3e04a15a02d1fa213248608caee99fd5bdddd4759959cf7 \ - --hash=sha256:dd2ca84e5f7a35f313a62eb7d6a50bac6760b60bafce34586750712731c0aeff +aiohttp==3.11.10 \ + --hash=sha256:012f176945af138abc10c4a48743327a92b4ca9adc7a0e078077cdb5dbab7be0 \ + --hash=sha256:06a8e2ee1cbac16fe61e51e0b0c269400e781b13bcfc33f5425912391a542985 \ + --hash=sha256:076bc454a7e6fd646bc82ea7f98296be0b1219b5e3ef8a488afbdd8e81fbac50 \ + --hash=sha256:14cdb5a9570be5a04eec2ace174a48ae85833c2aadc86de68f55541f66ce42ab \ + --hash=sha256:24213ba85a419103e641e55c27dc7ff03536c4873470c2478cce3311ba1eee7b \ + --hash=sha256:44224d815853962f48fe124748227773acd9686eba6dc102578defd6fc99e8d9 \ + --hash=sha256:482cafb7dc886bebeb6c9ba7925e03591a62ab34298ee70d3dd47ba966370d2c \ + --hash=sha256:7e97d622cb083e86f18317282084bc9fbf261801b0192c34fe4b1febd9f7ae69 \ + --hash=sha256:ab7485222db0959a87fbe8125e233b5a6f01f4400785b36e8a7878170d8c3138 \ + --hash=sha256:b1fc6b45010a8d0ff9e88f9f2418c6fd408c99c211257334aff41597ebece42e \ + --hash=sha256:b78f053a7ecfc35f0451d961dacdc671f4bcbc2f58241a7c820e9d82559844cf \ + --hash=sha256:b99acd4730ad1b196bfb03ee0803e4adac371ae8efa7e1cbc820200fc5ded109 \ + --hash=sha256:be2b516f56ea883a3e14dda17059716593526e10fb6303189aaf5503937db408 \ + --hash=sha256:bf3d1a519a324af764a46da4115bdbd566b3c73fb793ffb97f9111dbc684fc4d \ + --hash=sha256:c87bf31b7fdab94ae3adbe4a48e711bfc5f89d21cf4c197e75561def39e223bc \ + --hash=sha256:cf14627232dfa8730453752e9cdc210966490992234d77ff90bc8dc0dce361d5 aiosignal==1.3.1 \ --hash=sha256:54cd96e15e1649b75d6c87526a6ff0b6c1b0dd3459f43d9ca11d48c339b68cfc \ --hash=sha256:f8376fb07dd1e86a584e4fcdec80b36b7f81aac666ebc724e2c090300dd83b17 @@ -155,31 +155,31 @@ orjson==3.10.12 \ priority==2.0.0 \ --hash=sha256:6f8eefce5f3ad59baf2c080a664037bb4725cd0a790d53d59ab4059288faf6aa \ --hash=sha256:c965d54f1b8d0d0b19479db3924c7c36cf672dbf2aec92d43fbdaf4492ba18c0 -propcache==0.2.0 \ - --hash=sha256:00181262b17e517df2cd85656fcd6b4e70946fe62cd625b9d74ac9977b64d8d9 \ - --hash=sha256:1e41d67757ff4fbc8ef2af99b338bfb955010444b92929e9e55a6d4dcc3c4f09 \ - --hash=sha256:2ccc28197af5313706511fab3a8b66dcd6da067a1331372c82ea1cb74285e036 \ - --hash=sha256:2e900bad2a8456d00a113cad8c13343f3b1f327534e3589acc2219729237a2e8 \ - --hash=sha256:2ee7606193fb267be4b2e3b32714f2d58cad27217638db98a60f9efb5efeccc2 \ - --hash=sha256:3444cdba6628accf384e349014084b1cacd866fbb88433cd9d279d90a54e0b23 \ - --hash=sha256:439e76255daa0f8151d3cb325f6dd4a3e93043e6403e6491813bcaaaa8733887 \ - --hash=sha256:4a9d9b4d0a9b38d1c391bb4ad24aa65f306c6f01b512e10a8a34a2dc5675d348 \ - --hash=sha256:55346705687dbd7ef0d77883ab4f6fabc48232f587925bdaf95219bae072491e \ - --hash=sha256:56295eb1e5f3aecd516d91b00cfd8bf3a13991de5a479df9e27dd569ea23959c \ - --hash=sha256:6994984550eaf25dd7fc7bd1b700ff45c894149341725bb4edc67f0ffa94efa4 \ - --hash=sha256:69d3a98eebae99a420d4b28756c8ce6ea5a29291baf2dc9ff9414b42676f61d5 \ - --hash=sha256:91ee8fc02ca52e24bcb77b234f22afc03288e1dafbb1f88fe24db308910c4ac7 \ - --hash=sha256:a64e32f8bd94c105cc27f42d3b658902b5bcc947ece3c8fe7bc1b05982f60e89 \ - --hash=sha256:ad9c9b99b05f163109466638bd30ada1722abb01bbb85c739c50b6dc11f92dc3 \ - --hash=sha256:df81779732feb9d01e5d513fad0122efb3d53bbc75f61b2a4f29a020bc985e70 \ - --hash=sha256:f52a68c21363c45297aca15561812d542f8fc683c85201df0bebe209e349f793 \ - --hash=sha256:f6475a1b2ecb310c98c28d271a30df74f9dd436ee46d09236a6b750a7599ce57 +propcache==0.2.1 \ + --hash=sha256:049324ee97bb67285b49632132db351b41e77833678432be52bdd0289c0e05e4 \ + --hash=sha256:081a430aa8d5e8876c6909b67bd2d937bfd531b0382d3fdedb82612c618bc41a \ + --hash=sha256:14d86fe14b7e04fa306e0c43cdbeebe6b2c2156a0c9ce56b815faacc193e320d \ + --hash=sha256:1672137af7c46662a1c2be1e8dc78cb6d224319aaa40271c9257d886be4363a6 \ + --hash=sha256:1cd9a1d071158de1cc1c71a26014dcdfa7dd3d5f4f88c298c7f90ad6f27bb46d \ + --hash=sha256:3935bfa5fede35fb202c4b569bb9c042f337ca4ff7bd540a0aa5e37131659348 \ + --hash=sha256:3f77ce728b19cb537714499928fe800c3dda29e8d9428778fc7c186da4c09a64 \ + --hash=sha256:52277518d6aae65536e9cea52d4e7fd2f7a66f4aa2d30ed3f2fcea620ace3c54 \ + --hash=sha256:647894f5ae99c4cf6bb82a1bb3a796f6e06af3caa3d32e26d2350d0e3e3faf24 \ + --hash=sha256:98110aa363f1bb4c073e8dcfaefd3a5cea0f0834c2aab23dda657e4dab2f53b5 \ + --hash=sha256:b74c261802d3d2b85c9df2dfb2fa81b6f90deeef63c2db9f0e029a3cac50b518 \ + --hash=sha256:bfd3223c15bebe26518d58ccf9a39b93948d3dcb3e57a20480dfdd315356baff \ + --hash=sha256:c214999039d4f2a5b2073ac506bba279945233da8c786e490d411dfc30f855c1 \ + --hash=sha256:d09c333d36c1409d56a9d29b3a1b800a42c76a57a5a8907eacdbce3f18768246 \ + --hash=sha256:d2ccec9ac47cf4e04897619c0e0c1a48c54a71bdf045117d3a26f80d38ab1fb0 \ + --hash=sha256:d71264a80f3fcf512eb4f18f59423fe82d6e346ee97b90625f283df56aee103f \ + --hash=sha256:e73091191e4280403bde6c9a52a6999d69cdfde498f1fdf629105247599b57ec \ + --hash=sha256:f508b0491767bb1f2b87fdfacaba5f7eddc2f867740ec69ece6d1946d29029a6 py-cord==2.6.1 \ --hash=sha256:36064f225f2c7bbddfe542d5ed581f2a5744f618e039093cf7cd2659a58bc79b \ --hash=sha256:e3d3b528c5e37b0e0825f5b884cbb9267860976c1e4878e28b55da8fd3af834b -pydantic==2.10.2 \ - --hash=sha256:2bc2d7f17232e0841cbba4641e65ba1eb6fafb3a08de3a091ff3ce14a197c4fa \ - --hash=sha256:cfb96e45951117c3024e6b67b25cdc33a3cb7b2fa62e239f7af1378358a1d99e +pydantic==2.10.3 \ + --hash=sha256:be04d85bbc7b65651c5f8e6b9976ed9c6f41782a55524cef079a34a0bb82144d \ + --hash=sha256:cb5ac360ce894ceacd69c403187900a02c4b20b693a9dd1d643e1effab9eadf9 pydantic-core==2.27.1 \ --hash=sha256:0325336f348dbee6550d129b1627cb8f5351a9dc91aad141ffb96d4937bd9529 \ --hash=sha256:15aae984e46de8d376df515f00450d1522077254ef6b7ce189b38ecee7c9677c \ @@ -219,15 +219,15 @@ pyyaml==6.0.2 \ quart==0.19.9 \ --hash=sha256:30a61a0d7bae1ee13e6e99dc14c929b3c945e372b9445d92d21db053e91e95a5 \ --hash=sha256:8acb8b299c72b66ee9e506ae141498bbbfcc250b5298fbdb712e97f3d7e4082f -redis==5.2.0 \ - --hash=sha256:0b1087665a771b1ff2e003aa5bdd354f15a70c9e25d5a7dbf9c722c16528a7b0 \ - --hash=sha256:ae174f2bb3b1bf2b09d54bf3e51fbc1469cf6c10aa03e21141f51969801a7897 +redis==5.2.1 \ + --hash=sha256:16f2e22dff21d5125e8481515e386711a34cbec50f0e44413dd7d9c060a54e0f \ + --hash=sha256:ee7e1056b9aea0f04c6c2ed59452947f34c4940ee025f5dd83e6a6418b6989e4 schema==0.7.7 \ --hash=sha256:5d976a5b50f36e74e2157b47097b60002bd4d42e65425fcc9c9befadb4255dde \ --hash=sha256:7da553abd2958a19dc2547c388cde53398b39196175a9be59ea1caf5ab0a1807 -sentry-sdk==2.19.0 \ - --hash=sha256:7b0b3b709dee051337244a09a30dbf6e95afe0d34a1f8b430d45e0982a7c125b \ - --hash=sha256:ee4a4d2ae8bfe3cac012dcf3e4607975904c137e1738116549fc3dbbb6ff0e36 +sentry-sdk==2.19.2 \ + --hash=sha256:467df6e126ba242d39952375dd816fbee0f217d119bf454a8ce74cf1e7909e8d \ + --hash=sha256:ebdc08228b4d131128e568d696c210d846e5b9d70aa0327dec6b1272d9d40b84 typing-extensions==4.12.2 \ --hash=sha256:04e5ca0351e0f3f85c6853954072df659d0d13fac324d0072316b67d7794700d \ --hash=sha256:1a7ead55c7e559dd4dee8856e3a88b41225abfe1ce8df57b7c13915fe121ffb8 @@ -240,22 +240,22 @@ werkzeug==3.1.3 \ wsproto==1.2.0 \ --hash=sha256:ad565f26ecb92588a3e43bc3d96164de84cd9902482b130d0ddbaa9664a85065 \ --hash=sha256:b9acddd652b585d75b20477888c56642fdade28bdfd3579aa24a4d2c037dd736 -yarl==1.18.0 \ - --hash=sha256:01be8688fc211dc237e628fcc209dda412d35de7642453059a0553747018d075 \ - --hash=sha256:039c299a0864d1f43c3e31570045635034ea7021db41bf4842693a72aca8df3a \ - --hash=sha256:1ece25e2251c28bab737bdf0519c88189b3dd9492dc086a1d77336d940c28ced \ - --hash=sha256:20d95535e7d833889982bfe7cc321b7f63bf8879788fee982c76ae2b24cfb715 \ - --hash=sha256:454902dc1830d935c90b5b53c863ba2a98dcde0fbaa31ca2ed1ad33b2a7171c6 \ - --hash=sha256:49a98ecadc5a241c9ba06de08127ee4796e1009555efd791bac514207862b43d \ - --hash=sha256:4d26f1fa9fa2167bb238f6f4b20218eb4e88dd3ef21bb8f97439fa6b5313e30d \ - --hash=sha256:80741ec5b471fbdfb997821b2842c59660a1c930ceb42f8a84ba8ca0f25a66aa \ - --hash=sha256:9106025c7f261f9f5144f9aa7681d43867eed06349a7cfb297a1bc804de2f0d1 \ - --hash=sha256:9b4c90c5363c6b0a54188122b61edb919c2cd1119684999d08cd5e538813a28e \ - --hash=sha256:b1a3297b9cad594e1ff0c040d2881d7d3a74124a3c73e00c3c71526a1234a9f7 \ - --hash=sha256:b234a4a9248a9f000b7a5dfe84b8cb6210ee5120ae70eb72a4dcbdb4c528f72f \ - --hash=sha256:c083f6dd6951b86e484ebfc9c3524b49bcaa9c420cb4b2a78ef9f7a512bfcc85 \ - --hash=sha256:cd6ab7d6776c186f544f893b45ee0c883542b35e8a493db74665d2e594d3ca75 \ - --hash=sha256:dbf53db46f7cf176ee01d8d98c39381440776fcda13779d269a8ba664f69bec0 \ - --hash=sha256:f275ede6199d0f1ed4ea5d55a7b7573ccd40d97aee7808559e1298fe6efc8dbd \ - --hash=sha256:f7edeb1dcc7f50a2c8e08b9dc13a413903b7817e72273f00878cb70e766bdb3b \ - --hash=sha256:fe94d1de77c4cd8caff1bd5480e22342dbd54c93929f5943495d9c1e8abe9f42 +yarl==1.18.3 \ + --hash=sha256:00e5a1fea0fd4f5bfa7440a47eff01d9822a65b4488f7cff83155a0f31a2ecba \ + --hash=sha256:1dd4bdd05407ced96fed3d7f25dbbf88d2ffb045a0db60dbc247f5b3c5c25d50 \ + --hash=sha256:25b411eddcfd56a2f0cd6a384e9f4f7aa3efee14b188de13048c25b5e91f1640 \ + --hash=sha256:436c4fc0a4d66b2badc6c5fc5ef4e47bb10e4fd9bf0c79524ac719a01f3607c2 \ + --hash=sha256:4891ed92157e5430874dad17b15eb1fda57627710756c27422200c52d8a4e393 \ + --hash=sha256:5a3f356548e34a70b0172d8890006c37be92995f62d95a07b4a42e90fba54272 \ + --hash=sha256:7c33dd1931a95e5d9a772d0ac5e44cac8957eaf58e3c8da8c1414de7dd27c576 \ + --hash=sha256:7e2ee16578af3b52ac2f334c3b1f92262f47e02cc6193c598502bd46f5cd1477 \ + --hash=sha256:84b2deecba4a3f1a398df819151eb72d29bfeb3b69abb145a00ddc8d30094512 \ + --hash=sha256:ac1801c45cbf77b6c99242eeff4fffb5e4e73a800b5c4ad4fc0be5def634d2e1 \ + --hash=sha256:b57f4f58099328dfb26c6a771d09fb20dbbae81d20cfb66141251ea063bd101b \ + --hash=sha256:b958ddd075ddba5b09bb0be8a6d9906d2ce933aee81100db289badbeb966f54e \ + --hash=sha256:c7d79f7d9aabd6011004e33b22bc13056a3e3fb54794d138af57f5ee9d9032cb \ + --hash=sha256:ccd17349166b1bee6e529b4add61727d3f55edb7babbe4069b5764c9587a8cc6 \ + --hash=sha256:ce1af883b94304f493698b00d0f006d56aea98aeb49d75ec7d98cd4a777e9285 \ + --hash=sha256:d0e883008013c0e4aef84dcfe2a0b172c4d23c2669412cf5b3371003941f72bb \ + --hash=sha256:e35ef8683211db69ffe129a25d5634319a677570ab6b2eba4afa860f54eeaf75 \ + --hash=sha256:f91c4803173928a25e1a55b943c81f55b8872f0018be83e3ad4938adffb77dd2 From 125de62a67f798eea4ae09874380a6be77ff98d2 Mon Sep 17 00:00:00 2001 From: Paillat Date: Sun, 22 Dec 2024 21:39:24 +0100 Subject: [PATCH 35/61] =?UTF-8?q?=E2=9C=A8=20Enhanced=20cooldown=20system?= =?UTF-8?q?=20with=20bucket=20types=20(#57)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: openhands Co-authored-by: nicebots-xyz-bot --- .../nice_errors/handlers/cooldown.py | 36 ++++++++++ src/extensions/nice_errors/main.py | 3 + src/extensions/nice_errors/translations.yml | 8 +++ src/extensions/ping/ping.py | 3 +- src/utils/cooldown.py | 68 +++++++++++++++++-- 5 files changed, 110 insertions(+), 8 deletions(-) create mode 100644 src/extensions/nice_errors/handlers/cooldown.py diff --git a/src/extensions/nice_errors/handlers/cooldown.py b/src/extensions/nice_errors/handlers/cooldown.py new file mode 100644 index 0000000..d1b4fe7 --- /dev/null +++ b/src/extensions/nice_errors/handlers/cooldown.py @@ -0,0 +1,36 @@ +# Copyright (c) NiceBots +# SPDX-License-Identifier: MIT + +from typing import Any, final, override + +import discord + +from src import custom +from src.i18n.classes import RawTranslation, apply_locale +from src.utils.cooldown import CooldownExceeded + +from .base import BaseErrorHandler, ErrorHandlerRType + + +@final +class CooldownErrorHandler(BaseErrorHandler[CooldownExceeded]): + def __init__(self, translations: dict[str, RawTranslation]) -> None: + self.translations = translations + super().__init__(CooldownExceeded) + + @override + async def __call__( + self, + error: CooldownExceeded, + ctx: custom.Context | discord.Interaction, + sendargs: dict[str, Any], + message: str, + report: bool, + ) -> ErrorHandlerRType: + translations = apply_locale(self.translations, self._get_locale(ctx)) + + message = translations.error_cooldown_exceeded + + sendargs["ephemeral"] = True + + return False, False, message, sendargs diff --git a/src/extensions/nice_errors/main.py b/src/extensions/nice_errors/main.py index 0169315..67ed994 100644 --- a/src/extensions/nice_errors/main.py +++ b/src/extensions/nice_errors/main.py @@ -8,8 +8,10 @@ from schema import Optional, Schema from src import custom +from src.utils.cooldown import CooldownExceeded from .handlers import error_handler +from .handlers.cooldown import CooldownErrorHandler from .handlers.forbidden import ForbiddenErrorHandler from .handlers.generic import GenericErrorHandler from .handlers.not_found import NotFoundErrorHandler @@ -64,3 +66,4 @@ def setup(bot: custom.Bot, config: dict[str, Any]) -> None: error_handler.add_error_handler(None, GenericErrorHandler(config["translations"])) error_handler.add_error_handler(commands.CommandNotFound, NotFoundErrorHandler(config["translations"])) error_handler.add_error_handler(discord.Forbidden, ForbiddenErrorHandler(config["translations"])) + error_handler.add_error_handler(CooldownExceeded, CooldownErrorHandler(config["translations"])) diff --git a/src/extensions/nice_errors/translations.yml b/src/extensions/nice_errors/translations.yml index 7c14820..5ac630a 100644 --- a/src/extensions/nice_errors/translations.yml +++ b/src/extensions/nice_errors/translations.yml @@ -26,6 +26,14 @@ strings: it: Ops! Non ho i permessi necessari per farlo. es-ES: ¡Ups! No tengo el permiso necesario para hacer eso. ru: Упс! У меня нет необходимых прав для выполнения этого действия. + error_cooldown_exceeded: + en-US: Whoops! You're doing that too fast. Please wait before trying again. + de: Hoppla! Du machst das zu schnell. Bitte warte, bevor du es erneut versuchst. + nl: Oeps! Je doet dat te snel. Wacht even voordat je het opnieuw probeert. + fr: Oups ! Vous faites cela trop vite. Veuillez attendre avant de réessayer. + it: Ops! Stai facendo troppo in fretta. Attendi prima di riprovare. + es-ES: ¡Ups! Estás haciendo eso demasiado rápido. Por favor, espera antes de intentarlo de nuevo. + ru: Упс! Вы делаете это слишком быстро. Пожалуйста, подождите, прежде чем попробовать снова. error_generic: en-US: Whoops! An error occurred while executing this command. de: Hoppla! Bei der Ausführung dieses Kommandos ist ein Fehler aufgetreten. diff --git a/src/extensions/ping/ping.py b/src/extensions/ping/ping.py index 215ed5a..d6bb05a 100644 --- a/src/extensions/ping/ping.py +++ b/src/extensions/ping/ping.py @@ -9,7 +9,7 @@ from src import custom from src.log import logger -from src.utils.cooldown import cooldown +from src.utils.cooldown import BucketType, cooldown default = { "enabled": True, @@ -32,6 +32,7 @@ def __init__(self, bot: custom.Bot) -> None: limit=1, per=5, strong=True, + bucket_type=BucketType.USER, ) async def ping( self, diff --git a/src/utils/cooldown.py b/src/utils/cooldown.py index 69beae7..474c4dc 100644 --- a/src/utils/cooldown.py +++ b/src/utils/cooldown.py @@ -3,6 +3,7 @@ import time from collections.abc import Awaitable, Callable, Coroutine +from enum import Enum from functools import wraps from inspect import isawaitable from typing import Any, Concatenate, cast @@ -15,6 +16,16 @@ type CogCommandFunction[T: commands.Cog, **P] = Callable[Concatenate[T, custom.ApplicationContext, P], Awaitable[None]] +class BucketType(Enum): + DEFAULT = "default" # Uses provided key as is + USER = "user" # Per-user cooldown + MEMBER = "member" # Per-member (user+guild) cooldown + GUILD = "guild" # Per-guild cooldown + CHANNEL = "channel" # Per-channel cooldown + CATEGORY = "category" # Per-category cooldown + ROLE = "role" # Per-role cooldown (uses highest role) + + async def parse_reactive_setting[T](value: ReactiveCooldownSetting[T], bot: custom.Bot, ctx: custom.Context) -> T: if isinstance(value, type): return value # pyright: ignore [reportReturnType] @@ -26,22 +37,58 @@ async def parse_reactive_setting[T](value: ReactiveCooldownSetting[T], bot: cust class CooldownExceeded(commands.CheckFailure): - def __init__(self, retry_after: float) -> None: + def __init__(self, retry_after: float, bucket_type: BucketType) -> None: self.retry_after: float = retry_after - super().__init__("You are on cooldown") + self.bucket_type: BucketType = bucket_type + super().__init__(f"You are on {bucket_type.value} cooldown") -# inspired by https://github.com/ItsDrike/code-jam-2024/blob/main/src/utils/ratelimit.py +def get_bucket_key(ctx: custom.ApplicationContext, base_key: str, bucket_type: BucketType) -> str: # noqa: PLR0911 + """Generate a cooldown key based on the bucket type.""" + match bucket_type: + case BucketType.USER: + return f"{base_key}:user:{ctx.author.id}" + case BucketType.MEMBER: + return ( + f"{base_key}:member:{ctx.guild_id}:{ctx.author.id}" if ctx.guild else f"{base_key}:user:{ctx.author.id}" + ) + case BucketType.GUILD: + return f"{base_key}:guild:{ctx.guild_id}" if ctx.guild else base_key + case BucketType.CHANNEL: + return f"{base_key}:channel:{ctx.channel.id}" + case BucketType.CATEGORY: + category_id = ctx.channel.category_id if hasattr(ctx.channel, "category_id") else None + return f"{base_key}:category:{category_id}" if category_id else f"{base_key}:channel:{ctx.channel.id}" + case BucketType.ROLE: + if ctx.guild and hasattr(ctx.author, "roles"): + top_role_id = max((role.id for role in ctx.author.roles), default=0) + return f"{base_key}:role:{top_role_id}" + return f"{base_key}:user:{ctx.author.id}" + case _: # BucketType.DEFAULT + return base_key -def cooldown[C: commands.Cog, **P]( +def cooldown[C: commands.Cog, **P]( # noqa: PLR0913 key: ReactiveCooldownSetting[str], *, limit: ReactiveCooldownSetting[int], per: ReactiveCooldownSetting[int], + bucket_type: ReactiveCooldownSetting[BucketType] = BucketType.DEFAULT, strong: ReactiveCooldownSetting[bool] = False, cls: ReactiveCooldownSetting[type[CooldownExceeded]] = CooldownExceeded, ) -> Callable[[CogCommandFunction[C, P]], CogCommandFunction[C, P]]: + """Enhanced cooldown decorator that supports different bucket types. + + Args: + key: Base key for the cooldown + limit: Number of uses allowed + per: Time period in seconds + bucket_type: Type of bucket to use for the cooldown + strong: If True, adds current timestamp even if limit is reached + cls: Custom exception class to raise + + """ + def inner(func: CogCommandFunction[C, P]) -> CogCommandFunction[C, P]: @wraps(func) async def wrapper(self: C, ctx: custom.ApplicationContext, *args: P.args, **kwargs: P.kwargs) -> None: @@ -51,17 +98,24 @@ async def wrapper(self: C, ctx: custom.ApplicationContext, *args: P.args, **kwar per_value: int = await parse_reactive_setting(per, ctx.bot, ctx) strong_value: bool = await parse_reactive_setting(strong, ctx.bot, ctx) cls_value: type[CooldownExceeded] = await parse_reactive_setting(cls, ctx.bot, ctx) + bucket_type_value: BucketType = await parse_reactive_setting(bucket_type, ctx.bot, ctx) + + # Generate the full cooldown key based on bucket type + full_key = get_bucket_key(ctx, key_value, bucket_type_value) + now = time.time() - time_stamps = cast(tuple[float, ...], await cache.get(key_value, default=(), namespace="cooldown")) + time_stamps = cast(tuple[float, ...], await cache.get(full_key, default=(), namespace="cooldown")) time_stamps = tuple(filter(lambda x: x > now - per_value, time_stamps)) time_stamps = time_stamps[-limit_value:] + if len(time_stamps) < limit_value or strong_value: time_stamps = (*time_stamps, now) - await cache.set(key_value, time_stamps, namespace="cooldown", ttl=per_value) + await cache.set(full_key, time_stamps, namespace="cooldown", ttl=per_value) limit_value += 1 # to account for the current command if len(time_stamps) >= limit_value: - raise cls_value(min(time_stamps) - now + per_value) + raise cls_value(min(time_stamps) - now + per_value, bucket_type_value) + await func(self, ctx, *args, **kwargs) return wrapper From 3fb12ae03d631530ed6613383c4649b7e0c3e962 Mon Sep 17 00:00:00 2001 From: Paillat Date: Sun, 22 Dec 2024 21:44:51 +0100 Subject: [PATCH 36/61] Enhance error handling in start.py (#61) Co-authored-by: openhands Co-authored-by: nicebots-xyz-bot --- src/start.py | 20 ++++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) diff --git a/src/start.py b/src/start.py index 6c69e2c..e592696 100644 --- a/src/start.py +++ b/src/start.py @@ -37,6 +37,9 @@ async def start_bot(bot: custom.Bot, token: str) -> None: except LoginFailure as e: logger.critical("Failed to log in, is the bot token valid?") logger.debug("", exc_info=e) + except Exception as e: # noqa: BLE001 + logger.critical("An unexpected error occurred while starting the bot.") + logger.debug("", exc_info=e) async def start_backend(app: Quart, bot: discord.Bot, token: str) -> None: @@ -64,9 +67,13 @@ def __init__( app_config.logger_class = CustomLogger app_config.include_server_header = False # security app_config.bind = ["0.0.0.0:5000"] - await bot.login(token) - await serve(app, app_config) - patch("hypercorn.error") + try: + await bot.login(token) + await serve(app, app_config) + patch("hypercorn.error") + except Exception as e: # noqa: BLE001 + logger.critical("An error occurred while starting the backend server.") + logger.debug("", exc_info=e) def load_extensions() -> ( @@ -94,7 +101,12 @@ def load_extensions() -> ( continue its_config = config["extensions"].get(name, config["extensions"].get(name.replace("_", "-"), {})) - module: ModuleType = importlib.import_module(f"src.extensions.{name}") + try: + module: ModuleType = importlib.import_module(f"src.extensions.{name}") + except ImportError as e: + logger.error(f"Failed to import extension {name}") + logger.debug("", exc_info=e) + continue if not its_config: its_config = module.default config["extensions"][name] = its_config From ab7c545905ccc2b14287215981197b8c79626d77 Mon Sep 17 00:00:00 2001 From: Paillat Date: Sun, 22 Dec 2024 22:18:02 +0100 Subject: [PATCH 37/61] =?UTF-8?q?=E2=9C=A8=20Add=20Redis=20cache=20support?= =?UTF-8?q?=20(#58)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: openhands --- compose.yaml | 9 +++++++++ config.example.yaml | 10 ++++++++-- readme.md | 27 +++++++++++++++++++++++++++ src/custom/__init__.py | 28 ++++++++++++++++++++++++++-- src/start.py | 4 ++++ src/utils/cooldown.py | 2 +- 6 files changed, 75 insertions(+), 5 deletions(-) create mode 100644 compose.yaml diff --git a/compose.yaml b/compose.yaml new file mode 100644 index 0000000..0977c21 --- /dev/null +++ b/compose.yaml @@ -0,0 +1,9 @@ +# Copyright (c) NiceBots +# SPDX-License-Identifier: MIT + +services: + redis: + image: redis:alpine + ports: + - "6379:6379" + command: --loglevel debug \ No newline at end of file diff --git a/config.example.yaml b/config.example.yaml index 115e952..97db981 100644 --- a/config.example.yaml +++ b/config.example.yaml @@ -36,10 +36,16 @@ extensions: every: 300 # 300 seconds = 5 minutes bot: token: "bot token here" # Your bot token + cache: + type: "memory" # Cache type. Possible values: "memory" or "redis" + redis: # Redis configuration (only used if type is "redis") + host: "localhost" # Redis server host + port: 6379 # Redis server port + db: 0 # Redis database number + password: null # Redis password (optional) + ssl: false # Whether to use SSL for Redis connection logging: level: "INFO" # The logging level. Possible values: DEBUG, INFO, WARNING, ERROR, CRITICAL use: bot: true # Whether to run the bot backend: false # Whether to run the backend - - diff --git a/readme.md b/readme.md index 2952ec4..2512ee7 100644 --- a/readme.md +++ b/readme.md @@ -114,8 +114,35 @@ BOTKIT__extensions__listings__enabled=false BOTKIT__extensions__listings__topgg_token=your_top.gg_token BOTKIT__extensions__ping__enabled=true BOTKIT__logging__level=INFO +BOTKIT__cache__type=redis +BOTKIT__cache__redis__host=redis.example.com +BOTKIT__cache__redis__port=6379 ``` +### Cache Configuration + +Botkit supports two types of caching: + +- **Memory Cache**: Simple in-memory cache (default) +- **Redis Cache**: Distributed cache using Redis + +To configure the cache, use the `cache` section under the `bot` in your config: + +```yaml +bot: + cache: + type: "redis" # Use "memory" for in-memory cache + redis: # Redis configuration (only needed when type is "redis") + host: "localhost" + port: 6379 + db: 0 + password: "optional" # Optional Redis password + ssl: false # Whether to use SSL +``` + +If Redis cache is requested but no configuration is provided, Botkit will fall back to +memory cache with a warning. + ## Creating Extensions Extensions are in truth just python located in the `src/extensions` directory. When diff --git a/src/custom/__init__.py b/src/custom/__init__.py index dbf8023..ca750d4 100644 --- a/src/custom/__init__.py +++ b/src/custom/__init__.py @@ -51,9 +51,33 @@ def load_translations(self) -> None: class Bot(bridge.Bot): - def __init__(self, *args: Any, **options: Any) -> None: + def __init__( + self, *args: Any, cache_type: str = "memory", cache_config: dict[str, Any] | None = None, **options: Any + ) -> None: self.translations: list[ExtensionTranslation] = options.pop("translations", []) - self.cache: aiocache.SimpleMemoryCache | aiocache.RedisCache = aiocache.SimpleMemoryCache() + + self.botkit_cache: aiocache.BaseCache + # Initialize cache based on type and config + if cache_type == "redis": + if cache_config: + logger.info("Using Redis cache") + self.botkit_cache = aiocache.RedisCache( + endpoint=cache_config.get("host", "localhost"), + port=cache_config.get("port", 6379), + db=cache_config.get("db", 0), + password=cache_config.get("password"), + ssl=cache_config.get("ssl", False), + namespace="botkit", + ) + else: + logger.warning( + "Redis cache type specified but no configuration provided. Falling back to memory cache." + ) + self.botkit_cache = aiocache.SimpleMemoryCache(namespace="botkit") + else: + logger.info("Using memory cache") + self.botkit_cache = aiocache.SimpleMemoryCache(namespace="botkit") + super().__init__(*args, **options) @self.listen(name="on_ready", once=True) diff --git a/src/start.py b/src/start.py index e592696..b519d31 100644 --- a/src/start.py +++ b/src/start.py @@ -145,10 +145,14 @@ async def setup_and_start_bot( intents = discord.Intents.default() if config.get("prefix"): intents.message_content = True + # Get cache configuration + cache_config = config.get("cache", {}) bot = custom.Bot( intents=intents, help_command=None, command_prefix=(config.get("prefix", {}).get("prefix") or commands.when_mentioned), + cache_type=cache_config.get("type", "memory"), + cache_config=cache_config.get("redis"), ) for function, its_config in bot_functions: setup_func(function, bot=bot, config=its_config) diff --git a/src/utils/cooldown.py b/src/utils/cooldown.py index 474c4dc..93f841d 100644 --- a/src/utils/cooldown.py +++ b/src/utils/cooldown.py @@ -92,7 +92,7 @@ def cooldown[C: commands.Cog, **P]( # noqa: PLR0913 def inner(func: CogCommandFunction[C, P]) -> CogCommandFunction[C, P]: @wraps(func) async def wrapper(self: C, ctx: custom.ApplicationContext, *args: P.args, **kwargs: P.kwargs) -> None: - cache = ctx.bot.cache + cache = ctx.bot.botkit_cache key_value: str = await parse_reactive_setting(key, ctx.bot, ctx) limit_value: int = await parse_reactive_setting(limit, ctx.bot, ctx) per_value: int = await parse_reactive_setting(per, ctx.bot, ctx) From 2278d52abe95ad2c29ceeb3de449039ff943a722 Mon Sep 17 00:00:00 2001 From: Paillat Date: Tue, 24 Dec 2024 17:05:22 +0100 Subject: [PATCH 38/61] :sparkles: Add db system --- pdm.lock | 175 +++++++++++++++++- pyproject.toml | 8 + src/custom/__init__.py | 30 ++- src/database/__init__.py | 1 + src/database/config/__init__.py | 40 ++++ .../models/0_20241224165004_init.py | 27 +++ src/database/models/__init__.py | 10 + src/database/models/guild.py | 24 +++ src/database/models/user.py | 24 +++ src/database/utils/__init__.py | 1 + src/database/utils/preload.py | 86 +++++++++ src/start.py | 6 + 12 files changed, 429 insertions(+), 3 deletions(-) create mode 100644 src/database/__init__.py create mode 100644 src/database/config/__init__.py create mode 100644 src/database/migrations/models/0_20241224165004_init.py create mode 100644 src/database/models/__init__.py create mode 100644 src/database/models/guild.py create mode 100644 src/database/models/user.py create mode 100644 src/database/utils/__init__.py create mode 100644 src/database/utils/preload.py diff --git a/pdm.lock b/pdm.lock index 1a00220..cc183f8 100644 --- a/pdm.lock +++ b/pdm.lock @@ -5,11 +5,29 @@ groups = ["default", "dev"] strategy = ["inherit_metadata"] lock_version = "4.5.0" -content_hash = "sha256:53fa6d7cfe418243bec2cfedc2d29ee7f5a9268c607190745da713992a9b21a0" +content_hash = "sha256:23204c88ab6fbbe2c1488e7dec46de84dafd15d9e0d0c538c3cd0facdfe9dff3" [[metadata.targets]] requires_python = "==3.12.*" +[[package]] +name = "aerich" +version = "0.8.0" +requires_python = "<4.0,>=3.8" +summary = "A database migrations tool for Tortoise ORM." +groups = ["default"] +dependencies = [ + "asyncclick<9.0.0.0,>=8.1.7.2", + "dictdiffer", + "pydantic<3.0,>=2.0", + "tomlkit", + "tortoise-orm", +] +files = [ + {file = "aerich-0.8.0-py3-none-any.whl", hash = "sha256:a0afb70027e539cf37d27fb06bb2cbb0dfe01ef2170dae0adc816fe4da0e502d"}, + {file = "aerich-0.8.0.tar.gz", hash = "sha256:13786a91469626c025a2e2c5e524cac2b82b900de063b317f402710ee4c11ccb"}, +] + [[package]] name = "aiocache" version = "0.12.3" @@ -120,6 +138,20 @@ files = [ {file = "aiosignal-1.3.1.tar.gz", hash = "sha256:54cd96e15e1649b75d6c87526a6ff0b6c1b0dd3459f43d9ca11d48c339b68cfc"}, ] +[[package]] +name = "aiosqlite" +version = "0.20.0" +requires_python = ">=3.8" +summary = "asyncio bridge to the standard sqlite3 module" +groups = ["default"] +dependencies = [ + "typing-extensions>=4.0", +] +files = [ + {file = "aiosqlite-0.20.0-py3-none-any.whl", hash = "sha256:36a1deaca0cac40ebe32aac9977a6e2bbc7f5189f23f4a54d5908986729e5bd6"}, + {file = "aiosqlite-0.20.0.tar.gz", hash = "sha256:6d35c8c256637f4672f843c31021464090805bf925385ac39473fb16eaaca3d7"}, +] + [[package]] name = "annotated-types" version = "0.7.0" @@ -134,6 +166,60 @@ files = [ {file = "annotated_types-0.7.0.tar.gz", hash = "sha256:aff07c09a53a08bc8cfccb9c85b05f1aa9a2a6f23728d790723543408344ce89"}, ] +[[package]] +name = "anyio" +version = "4.7.0" +requires_python = ">=3.9" +summary = "High level compatibility layer for multiple asynchronous event loop implementations" +groups = ["default"] +dependencies = [ + "exceptiongroup>=1.0.2; python_version < \"3.11\"", + "idna>=2.8", + "sniffio>=1.1", + "typing-extensions>=4.5; python_version < \"3.13\"", +] +files = [ + {file = "anyio-4.7.0-py3-none-any.whl", hash = "sha256:ea60c3723ab42ba6fff7e8ccb0488c898ec538ff4df1f1d5e642c3601d07e352"}, + {file = "anyio-4.7.0.tar.gz", hash = "sha256:2f834749c602966b7d456a7567cafcb309f96482b5081d14ac93ccd457f9dd48"}, +] + +[[package]] +name = "asyncclick" +version = "8.1.7.2" +requires_python = ">=3.7" +summary = "Composable command line interface toolkit, async version" +groups = ["default"] +dependencies = [ + "anyio", + "colorama; platform_system == \"Windows\"", + "importlib-metadata; python_version < \"3.8\"", +] +files = [ + {file = "asyncclick-8.1.7.2-py3-none-any.whl", hash = "sha256:1ab940b04b22cb89b5b400725132b069d01b0c3472a9702c7a2c9d5d007ded02"}, + {file = "asyncclick-8.1.7.2.tar.gz", hash = "sha256:219ea0f29ccdc1bb4ff43bcab7ce0769ac6d48a04f997b43ec6bee99a222daa0"}, +] + +[[package]] +name = "asyncpg" +version = "0.30.0" +requires_python = ">=3.8.0" +summary = "An asyncio PostgreSQL driver" +groups = ["default"] +dependencies = [ + "async-timeout>=4.0.3; python_version < \"3.11.0\"", +] +files = [ + {file = "asyncpg-0.30.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:c902a60b52e506d38d7e80e0dd5399f657220f24635fee368117b8b5fce1142e"}, + {file = "asyncpg-0.30.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:aca1548e43bbb9f0f627a04666fedaca23db0a31a84136ad1f868cb15deb6e3a"}, + {file = "asyncpg-0.30.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6c2a2ef565400234a633da0eafdce27e843836256d40705d83ab7ec42074efb3"}, + {file = "asyncpg-0.30.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1292b84ee06ac8a2ad8e51c7475aa309245874b61333d97411aab835c4a2f737"}, + {file = "asyncpg-0.30.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:0f5712350388d0cd0615caec629ad53c81e506b1abaaf8d14c93f54b35e3595a"}, + {file = "asyncpg-0.30.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:db9891e2d76e6f425746c5d2da01921e9a16b5a71a1c905b13f30e12a257c4af"}, + {file = "asyncpg-0.30.0-cp312-cp312-win32.whl", hash = "sha256:68d71a1be3d83d0570049cd1654a9bdfe506e794ecc98ad0873304a9f35e411e"}, + {file = "asyncpg-0.30.0-cp312-cp312-win_amd64.whl", hash = "sha256:9a0292c6af5c500523949155ec17b7fe01a00ace33b68a476d6b5059f9630305"}, + {file = "asyncpg-0.30.0.tar.gz", hash = "sha256:c551e9928ab6707602f44811817f82ba3c446e018bfe1d3abecc8ba5f3eac851"}, +] + [[package]] name = "attrs" version = "24.2.0" @@ -266,6 +352,16 @@ files = [ {file = "deprecated-1.2.15.tar.gz", hash = "sha256:683e561a90de76239796e6b6feac66b99030d2dd3fcf61ef996330f14bbb9b0d"}, ] +[[package]] +name = "dictdiffer" +version = "0.9.0" +summary = "Dictdiffer is a library that helps you to diff and patch dictionaries." +groups = ["default"] +files = [ + {file = "dictdiffer-0.9.0-py2.py3-none-any.whl", hash = "sha256:442bfc693cfcadaf46674575d2eba1c53b42f5e404218ca2c2ff549f2df56595"}, + {file = "dictdiffer-0.9.0.tar.gz", hash = "sha256:17bacf5fbfe613ccf1b6d512bd766e6b21fb798822a133aa86098b8ac9997578"}, +] + [[package]] name = "flask" version = "3.1.0" @@ -421,6 +517,17 @@ files = [ {file = "iniconfig-2.0.0.tar.gz", hash = "sha256:2d91e135bf72d31a410b17c16da610a82cb55f6b0477d1a902134b24a455b8b3"}, ] +[[package]] +name = "iso8601" +version = "2.1.0" +requires_python = ">=3.7,<4.0" +summary = "Simple module to parse ISO 8601 dates" +groups = ["default"] +files = [ + {file = "iso8601-2.1.0-py3-none-any.whl", hash = "sha256:aac4145c4dcb66ad8b648a02830f5e2ff6c24af20f4f482689be402db2429242"}, + {file = "iso8601-2.1.0.tar.gz", hash = "sha256:6b1d3829ee8921c4301998c909f7829fa9ed3cbdac0d3b16af2d743aed1ba8df"}, +] + [[package]] name = "itsdangerous" version = "2.2.0" @@ -697,6 +804,17 @@ files = [ {file = "pydantic_core-2.27.1.tar.gz", hash = "sha256:62a763352879b84aa31058fc931884055fd75089cccbd9d58bb6afd01141b235"}, ] +[[package]] +name = "pypika-tortoise" +version = "0.3.2" +requires_python = "<4.0,>=3.8" +summary = "Forked from pypika and streamline just for tortoise-orm" +groups = ["default"] +files = [ + {file = "pypika_tortoise-0.3.2-py3-none-any.whl", hash = "sha256:c5c52bc4473fe6f3db36cf659340750246ec5dd0f980d04ae7811430e299c3a2"}, + {file = "pypika_tortoise-0.3.2.tar.gz", hash = "sha256:f5d508e2ef00255e52ec6ac79ef889e10dbab328f218c55cd134c4d02ff9f6f4"}, +] + [[package]] name = "pyreadline3" version = "3.5.4" @@ -861,6 +979,17 @@ files = [ {file = "sentry_sdk-2.19.2.tar.gz", hash = "sha256:467df6e126ba242d39952375dd816fbee0f217d119bf454a8ce74cf1e7909e8d"}, ] +[[package]] +name = "sniffio" +version = "1.3.1" +requires_python = ">=3.7" +summary = "Sniff out which async library your code is running under" +groups = ["default"] +files = [ + {file = "sniffio-1.3.1-py3-none-any.whl", hash = "sha256:2f6da418d1f1e0fddd844478f41680e794e6051915791a034ff65e5f100525a2"}, + {file = "sniffio-1.3.1.tar.gz", hash = "sha256:f4324edc670a0f49750a81b895f35c3adb843cca46f0530f79fc1babb23789dc"}, +] + [[package]] name = "soupsieve" version = "2.6" @@ -883,6 +1012,50 @@ files = [ {file = "termcolor-2.5.0.tar.gz", hash = "sha256:998d8d27da6d48442e8e1f016119076b690d962507531df4890fcd2db2ef8a6f"}, ] +[[package]] +name = "tomlkit" +version = "0.13.2" +requires_python = ">=3.8" +summary = "Style preserving TOML library" +groups = ["default"] +files = [ + {file = "tomlkit-0.13.2-py3-none-any.whl", hash = "sha256:7a974427f6e119197f670fbbbeae7bef749a6c14e793db934baefc1b5f03efde"}, + {file = "tomlkit-0.13.2.tar.gz", hash = "sha256:fff5fe59a87295b278abd31bec92c15d9bc4a06885ab12bcea52c71119392e79"}, +] + +[[package]] +name = "tortoise-orm" +version = "0.23.0" +requires_python = "<4.0,>=3.8" +summary = "Easy async ORM for python, built with relations in mind" +groups = ["default"] +dependencies = [ + "aiosqlite<0.21.0,>=0.16.0", + "iso8601<3.0.0,>=2.1.0", + "pypika-tortoise<0.4.0,>=0.3.2", + "pytz", +] +files = [ + {file = "tortoise_orm-0.23.0-py3-none-any.whl", hash = "sha256:deaabed1619ea8aab6213508dff025571a701b7f34ee534473d7bb7661aa9f4f"}, + {file = "tortoise_orm-0.23.0.tar.gz", hash = "sha256:f25d431ef4fb521a84edad582f4b9c53dccc5abf6cfbc6f228cbece5a13952fa"}, +] + +[[package]] +name = "tortoise-orm" +version = "0.23.0" +extras = ["asyncpg"] +requires_python = "<4.0,>=3.8" +summary = "Easy async ORM for python, built with relations in mind" +groups = ["default"] +dependencies = [ + "asyncpg", + "tortoise-orm==0.23.0", +] +files = [ + {file = "tortoise_orm-0.23.0-py3-none-any.whl", hash = "sha256:deaabed1619ea8aab6213508dff025571a701b7f34ee534473d7bb7661aa9f4f"}, + {file = "tortoise_orm-0.23.0.tar.gz", hash = "sha256:f25d431ef4fb521a84edad582f4b9c53dccc5abf6cfbc6f228cbece5a13952fa"}, +] + [[package]] name = "typing-extensions" version = "4.12.2" diff --git a/pyproject.toml b/pyproject.toml index 67628ae..bddf8c1 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -21,6 +21,8 @@ dependencies = [ "aiofile>=3.9.0", "sentry-sdk>=2.18.0", "aiocache[redis]>=0.12.3", + "tortoise-orm[asyncpg]>=0.23.0", + "aerich>=0.8.0", ] requires-python = "==3.12.*" readme = "README.md" @@ -78,6 +80,7 @@ docstring-code-line-length = "dynamic" [tool.ruff.lint] select = ["ALL"] +per-file-ignores = { "src/database/migrations/*"= ["INP001", "ARG001"] } extend-ignore = [ "N999", "D104", @@ -104,3 +107,8 @@ extend-ignore = [ "PLR2004", "C901" ] + +[tool.aerich] +tortoise_orm = "src.database.config.TORTOISE_ORM" +location = "./src/database/migrations" +src_folder = "./." diff --git a/src/custom/__init__.py b/src/custom/__init__.py index ca750d4..ae970ec 100644 --- a/src/custom/__init__.py +++ b/src/custom/__init__.py @@ -1,12 +1,13 @@ # Copyright (c) NiceBots.xyz # SPDX-License-Identifier: MIT +import contextlib from logging import getLogger from typing import TYPE_CHECKING, Any, override import aiocache import discord -from discord import Message +from discord import Interaction, Message, WebhookMessage from discord.ext import bridge from discord.ext.bridge import ( BridgeExtContext, @@ -14,6 +15,9 @@ from src.i18n.classes import ExtensionTranslation, TranslationWrapper, apply_locale +if TYPE_CHECKING: + from src.database.models import Guild, User + logger = getLogger("bot") @@ -22,6 +26,8 @@ def __init__(self, bot: "Bot", interaction: discord.Interaction) -> None: self.translations: TranslationWrapper = TranslationWrapper({}, "en-US") # empty placeholder super().__init__(bot=bot, interaction=interaction) self.bot: Bot + self.user_obj: User | None = None + self.guild_obj: Guild | None = None @override def __setattr__(self, key: Any, value: Any) -> None: @@ -33,11 +39,17 @@ def __setattr__(self, key: Any, value: Any) -> None: super().__setattr__(key, value) +async def remove_reaction(user: discord.User, message: discord.Message, emoji: str) -> None: + await message.remove_reaction(emoji, user) + + class ExtContext(bridge.BridgeExtContext): def __init__(self, **kwargs: Any) -> None: self.translations: TranslationWrapper = TranslationWrapper({}, "en-US") # empty placeholder super().__init__(**kwargs) self.bot: Bot + self.user_obj: User | None = None + self.guild_obj: Guild | None = None def load_translations(self) -> None: if hasattr(self.command, "translations") and self.command.translations: # pyright: ignore[reportUnknownArgumentType,reportOptionalMemberAccess,reportAttributeAccessIssue] @@ -45,10 +57,24 @@ def load_translations(self) -> None: if guild := self.guild: locale = guild.preferred_locale self.translations = apply_locale( - self.command.translations, + self.command.translations, # pyright: ignore [reportAttributeAccessIssue, reportOptionalMemberAccess, reportUnknownArgumentType] locale, ) + @override + async def defer(self, *args: Any, **kwargs: Any) -> None: + await super().defer(*args, **kwargs) + with contextlib.suppress(Exception): + await self.message.add_reaction("🔄") + + @override + async def respond(self, *args: Any, **kwargs: Any) -> "Interaction | WebhookMessage | Message": + r = await super().respond(*args, **kwargs) + with contextlib.suppress(Exception): + if self.me: + await remove_reaction(self.me, self.message, "🔄") + return r + class Bot(bridge.Bot): def __init__( diff --git a/src/database/__init__.py b/src/database/__init__.py new file mode 100644 index 0000000..12d97d2 --- /dev/null +++ b/src/database/__init__.py @@ -0,0 +1 @@ +# Copyright (c) NiceBots diff --git a/src/database/config/__init__.py b/src/database/config/__init__.py new file mode 100644 index 0000000..2728099 --- /dev/null +++ b/src/database/config/__init__.py @@ -0,0 +1,40 @@ +# Copyright (c) NiceBots +# SPDX-License-Identifier: MIT + +from logging import getLogger + +import aerich +from tortoise import Tortoise + +from src.config import config + +logger = getLogger("bot").getChild("database") + +TORTOISE_ORM = { + "connections": {"default": config["db"]["url"]}, + "apps": { + "models": { + "models": ["src.database.models", "aerich.models"], + "default_connection": "default", + } + }, +} + + +async def init() -> None: + command = aerich.Command( + TORTOISE_ORM, + app="models", + location="./src/database/migrations/", + ) + await command.init() + migrated = await command.upgrade(run_in_transaction=True) # pyright: ignore[reportUnknownVariableType] + logger.success(f"Successfully migrated {migrated} migrations") # pyright: ignore [reportAttributeAccessIssue] + await Tortoise.init(config=TORTOISE_ORM) + + +async def shutdown() -> None: + await Tortoise.close_connections() + + +__all__ = ["init", "shutdown"] diff --git a/src/database/migrations/models/0_20241224165004_init.py b/src/database/migrations/models/0_20241224165004_init.py new file mode 100644 index 0000000..0bb447d --- /dev/null +++ b/src/database/migrations/models/0_20241224165004_init.py @@ -0,0 +1,27 @@ +# Copyright (c) NiceBots +# SPDX-License-Identifier: MIT + +from tortoise import BaseDBAsyncClient + + +async def upgrade(db: BaseDBAsyncClient) -> str: + return """ + CREATE TABLE IF NOT EXISTS "guild" ( + "id" BIGSERIAL NOT NULL PRIMARY KEY +); +COMMENT ON TABLE "guild" IS 'User model.'; +CREATE TABLE IF NOT EXISTS "user" ( + "id" BIGSERIAL NOT NULL PRIMARY KEY +); +COMMENT ON TABLE "user" IS 'User model.'; +CREATE TABLE IF NOT EXISTS "aerich" ( + "id" SERIAL NOT NULL PRIMARY KEY, + "version" VARCHAR(255) NOT NULL, + "app" VARCHAR(100) NOT NULL, + "content" JSONB NOT NULL +);""" + + +async def downgrade(db: BaseDBAsyncClient) -> str: + return """ + """ diff --git a/src/database/models/__init__.py b/src/database/models/__init__.py new file mode 100644 index 0000000..e30c1dd --- /dev/null +++ b/src/database/models/__init__.py @@ -0,0 +1,10 @@ +# Copyright (c) NiceBots +# SPDX-License-Identifier: MIT + +from .guild import Guild +from .user import User + +__all__ = [ + "Guild", + "User", +] diff --git a/src/database/models/guild.py b/src/database/models/guild.py new file mode 100644 index 0000000..beab722 --- /dev/null +++ b/src/database/models/guild.py @@ -0,0 +1,24 @@ +# Copyright (c) NiceBots +# SPDX-License-Identifier: MIT + +from tortoise import fields +from tortoise.models import Model + + +class Guild(Model): + """User model. + + Represents a user in the database. + + Attributes + ---------- + id (int): Discord user ID. + free_credits (int): Amount of free credits the user has. + premium_credits (int): Amount of premium credits the user has. + + """ + + id: fields.Field[int] = fields.BigIntField(pk=True) + + +__all__ = ["Guild"] diff --git a/src/database/models/user.py b/src/database/models/user.py new file mode 100644 index 0000000..92a5c2e --- /dev/null +++ b/src/database/models/user.py @@ -0,0 +1,24 @@ +# Copyright (c) NiceBots +# SPDX-License-Identifier: MIT + +from tortoise import fields +from tortoise.models import Model + + +class User(Model): + """User model. + + Represents a user in the database. + + Attributes + ---------- + id (int): Discord user ID. + free_credits (int): Amount of free credits the user has. + premium_credits (int): Amount of premium credits the user has. + + """ + + id: fields.Field[int] = fields.BigIntField(pk=True) + + +__all__ = ["User"] diff --git a/src/database/utils/__init__.py b/src/database/utils/__init__.py new file mode 100644 index 0000000..8e05d9a --- /dev/null +++ b/src/database/utils/__init__.py @@ -0,0 +1 @@ +# Copyright (c) NiceBots all rights reserved diff --git a/src/database/utils/preload.py b/src/database/utils/preload.py new file mode 100644 index 0000000..e867c51 --- /dev/null +++ b/src/database/utils/preload.py @@ -0,0 +1,86 @@ +# Copyright (c) NiceBots +# SPDX-License-Identifier: MIT + +from discord.ext import commands + +from src import custom +from src.database.models import Guild, User + + +async def _preload_user(ctx: custom.Context) -> bool: + """Preload the user object into the context object. + + Args: + ---- + ctx: The context object to preload the user object into. + + Returns: + ------- + bool: (True) always. + + """ + if isinstance(ctx, custom.ExtContext): + ctx.user_obj = await User.get_or_none(id=ctx.author.id) if ctx.author else None + else: + ctx.user_obj = await User.get_or_none(id=ctx.user.id) if ctx.user else None + return True + + +preload_user = commands.check(_preload_user) # pyright: ignore [reportArgumentType] + + +async def _preload_guild(ctx: custom.Context) -> bool: + """Preload the guild object into the context object. + + Args: + ---- + ctx: The context object to preload the guild object into. + + Returns: + ------- + bool: (True) always. + + """ + ctx.guild_obj = await Guild.get_or_none(id=ctx.guild.id) if ctx.guild else None + return True + + +preload_guild = commands.check(_preload_guild) # pyright: ignore [reportArgumentType] + + +async def _preload_or_create_user(ctx: custom.Context) -> bool: + """Preload or create the user object into the context object. If the user object does not exist, create it. + + Args: + ---- + ctx: The context object to preload or create the user object into. + + Returns: + ------- + bool: (True) always. + + """ + ctx.user_obj, _ = await User.get_or_create(id=ctx.author.id) if ctx.author else (None, None) + return True + + +preload_or_create_user = commands.check(_preload_or_create_user) + + +async def _preload_or_create_guild(ctx: custom.Context) -> bool: + """Preload or create the guild object into the context object. If the guild object does not exist, create it. + + Args: + ---- + ctx: The context object to preload or create the guild object into. + + Returns: + ------- + bool: (True) always. + + """ + ctx.guild_obj, _ = await Guild.get_or_create(id=ctx.guild.id) if ctx.guild else (None, None) + return True + + +preload_or_create_guild = commands.check(_preload_or_create_guild) # pyright: ignore [reportArgumentType] diff --git a/src/start.py b/src/start.py index b519d31..71b6c02 100644 --- a/src/start.py +++ b/src/start.py @@ -189,6 +189,12 @@ async def start(run_bot: bool | None = None, run_backend: bool | None = None) -> if not config.get("bot", {}).get("token"): logger.critical("No bot token provided in config, exiting...") return + if config.get("db", {}).get("enabled", False): + from src.database.config import init + + logger.info("Initializing database...") + await init() + unzip_extensions() run_bot = run_bot if run_bot is not None else config.get("use", {}).get("bot", True) run_backend = run_backend if run_backend is not None else config.get("use", {}).get("backend", True) From 4ffa8265380913d7b7f148b1544193f500dbe40d Mon Sep 17 00:00:00 2001 From: Paillat Date: Wed, 25 Dec 2024 22:22:09 +0100 Subject: [PATCH 39/61] :sparkles: Add `custom_attrs` dict to custom context --- src/custom/__init__.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/custom/__init__.py b/src/custom/__init__.py index ae970ec..4691c1c 100644 --- a/src/custom/__init__.py +++ b/src/custom/__init__.py @@ -28,6 +28,7 @@ def __init__(self, bot: "Bot", interaction: discord.Interaction) -> None: self.bot: Bot self.user_obj: User | None = None self.guild_obj: Guild | None = None + self.custom_attrs: dict[str, Any] = {} @override def __setattr__(self, key: Any, value: Any) -> None: @@ -50,6 +51,7 @@ def __init__(self, **kwargs: Any) -> None: self.bot: Bot self.user_obj: User | None = None self.guild_obj: Guild | None = None + self.custom_attrs: dict[str, Any] = {} def load_translations(self) -> None: if hasattr(self.command, "translations") and self.command.translations: # pyright: ignore[reportUnknownArgumentType,reportOptionalMemberAccess,reportAttributeAccessIssue] @@ -132,7 +134,8 @@ async def get_context( return ctx -Context: ApplicationContext = ApplicationContext # pyright: ignore [reportRedeclaration] +if not TYPE_CHECKING: + Context: ApplicationContext = ApplicationContext # pyright: ignore [reportRedeclaration] if TYPE_CHECKING: # temp fix for https://github.com/Pycord-Development/pycord/pull/2611 type Context = ExtContext | ApplicationContext From e34dd92a87a1640bb879ba4a675b43e38f0b7e00 Mon Sep 17 00:00:00 2001 From: Paillat Date: Wed, 25 Dec 2024 22:24:34 +0100 Subject: [PATCH 40/61] :sparkles: Translations to message commands. --- src/i18n/utils.py | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) diff --git a/src/i18n/utils.py b/src/i18n/utils.py index bab67db..15630e8 100644 --- a/src/i18n/utils.py +++ b/src/i18n/utils.py @@ -28,9 +28,11 @@ def remove_none(d: dict[T, V]) -> dict[T, V]: """Remove None values from a dictionary. Args: + ---- d (dict[T, V]): The dictionary to remove None values from. Returns: + ------- dict[T, V]: The dictionary without None values. """ @@ -43,12 +45,15 @@ def merge_command_translations( """Merge command translations into a single dictionary. Args: + ---- translations (list[ExtensionTranslation]): A list of translations. Returns: + ------- dict[str, Deg1CommandTranslation] | None: A dictionary of command translations. Raises: + ------ None """ @@ -71,6 +76,7 @@ def merge_command_translations( discord.SlashCommand, discord.SlashCommandGroup, prefixed.Command, # pyright: ignore[reportMissingTypeArgument] + discord.MessageCommand, ) @@ -85,11 +91,13 @@ def localize_commands( # noqa: PLR0912 """Recursively localize commands and their subcommands. Args: + ---- commands: List of commands to localize. translations: Translations for the commands. default_locale: The default locale to use. Returns: + ------- None """ @@ -97,7 +105,9 @@ def localize_commands( # noqa: PLR0912 err = 0 tot = 0 for command in commands: - if isinstance(command, discord.SlashCommand | discord.SlashCommandGroup | prefixed.Command): + if isinstance( + command, discord.SlashCommand | discord.SlashCommandGroup | prefixed.Command | discord.MessageCommand + ): tot += 1 try: try: @@ -121,7 +131,7 @@ def localize_commands( # noqa: PLR0912 description = remove_none(translation.description.model_dump(by_alias=True)) command.description = description.get(default_locale, command.description) if not isinstance(command, prefixed.Command): - command.description_localizations = description + command.description_localizations = description # pyright: ignore [reportAttributeAccessIssue] if translation.strings: command.translations = translation.strings # pyright: ignore[reportAttributeAccessIssue] if isinstance(command, discord.SlashCommand) and translation.options: @@ -155,12 +165,15 @@ def load_translation(path: str) -> ExtensionTranslation: """Load a translation from a file. Args: + ---- path (str): The path to the translation file. Returns: + ------- ExtensionTranslation: The loaded translation. Raises: + ------ yaml.YAMLError: If the file is not a valid YAML file. """ @@ -177,11 +190,13 @@ def apply( """Apply translations to the bot. Args: + ---- bot: The bot to apply translations to. translations: The translations to apply. default_locale: The default locale to use. Returns: + ------- None """ From add4c161c80f0b9955ede104ee611c1a3329796d Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Sun, 29 Dec 2024 13:02:17 +0100 Subject: [PATCH 41/61] =?UTF-8?q?=E2=AC=86=EF=B8=8F=20Upgrade=20docker/set?= =?UTF-8?q?up-buildx-action=20action=20to=20v3.8.0=20(#63)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- .github/workflows/docker.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/docker.yaml b/.github/workflows/docker.yaml index e553fb3..0be543b 100644 --- a/.github/workflows/docker.yaml +++ b/.github/workflows/docker.yaml @@ -18,7 +18,7 @@ jobs: uses: actions/checkout@v4 - name: Set up Docker Buildx - uses: docker/setup-buildx-action@v3.7.1 + uses: docker/setup-buildx-action@v3.8.0 - name: Log into registry ${{ env.REGISTRY }} uses: docker/login-action@v3.3.0 From 3ee084435331bb670fe6693f7ef8559ca333d12d Mon Sep 17 00:00:00 2001 From: Paillat Date: Thu, 2 Jan 2025 21:15:28 +0100 Subject: [PATCH 42/61] :sparkles: Better typing in cooldown.py --- pyproject.toml | 1 + src/utils/cooldown.py | 20 ++++++++++---------- 2 files changed, 11 insertions(+), 10 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index bddf8c1..f4f7773 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -105,6 +105,7 @@ extend-ignore = [ "FBT001", "FBT002", "PLR2004", + "PLR0913", "C901" ] diff --git a/src/utils/cooldown.py b/src/utils/cooldown.py index 93f841d..dc8779e 100644 --- a/src/utils/cooldown.py +++ b/src/utils/cooldown.py @@ -8,12 +8,13 @@ from inspect import isawaitable from typing import Any, Concatenate, cast +import discord from discord.ext import commands from src import custom type ReactiveCooldownSetting[T: Any] = T | Callable[[custom.Bot, custom.Context], T | Coroutine[Any, Any, T]] -type CogCommandFunction[T: commands.Cog, **P] = Callable[Concatenate[T, custom.ApplicationContext, P], Awaitable[None]] +type CogCommandFunction[T: commands.Cog, **P] = Callable[Concatenate[T, P], Awaitable[None]] class BucketType(Enum): @@ -43,24 +44,22 @@ def __init__(self, retry_after: float, bucket_type: BucketType) -> None: super().__init__(f"You are on {bucket_type.value} cooldown") -def get_bucket_key(ctx: custom.ApplicationContext, base_key: str, bucket_type: BucketType) -> str: # noqa: PLR0911 +def get_bucket_key(ctx: custom.Context, base_key: str, bucket_type: BucketType) -> str: # noqa: PLR0911 """Generate a cooldown key based on the bucket type.""" match bucket_type: case BucketType.USER: return f"{base_key}:user:{ctx.author.id}" case BucketType.MEMBER: - return ( - f"{base_key}:member:{ctx.guild_id}:{ctx.author.id}" if ctx.guild else f"{base_key}:user:{ctx.author.id}" - ) + return f"{base_key}:member:{ctx.guild}:{ctx.author.id}" if ctx.guild else f"{base_key}:user:{ctx.author.id}" case BucketType.GUILD: - return f"{base_key}:guild:{ctx.guild_id}" if ctx.guild else base_key + return f"{base_key}:guild:{ctx.guild.id}" if ctx.guild else base_key case BucketType.CHANNEL: return f"{base_key}:channel:{ctx.channel.id}" case BucketType.CATEGORY: category_id = ctx.channel.category_id if hasattr(ctx.channel, "category_id") else None return f"{base_key}:category:{category_id}" if category_id else f"{base_key}:channel:{ctx.channel.id}" case BucketType.ROLE: - if ctx.guild and hasattr(ctx.author, "roles"): + if ctx.guild and hasattr(ctx.author, "roles") and isinstance(ctx.author, discord.Member): top_role_id = max((role.id for role in ctx.author.roles), default=0) return f"{base_key}:role:{top_role_id}" return f"{base_key}:user:{ctx.author.id}" @@ -68,7 +67,7 @@ def get_bucket_key(ctx: custom.ApplicationContext, base_key: str, bucket_type: B return base_key -def cooldown[C: commands.Cog, **P]( # noqa: PLR0913 +def cooldown[C: commands.Cog, **P]( key: ReactiveCooldownSetting[str], *, limit: ReactiveCooldownSetting[int], @@ -91,7 +90,8 @@ def cooldown[C: commands.Cog, **P]( # noqa: PLR0913 def inner(func: CogCommandFunction[C, P]) -> CogCommandFunction[C, P]: @wraps(func) - async def wrapper(self: C, ctx: custom.ApplicationContext, *args: P.args, **kwargs: P.kwargs) -> None: + async def wrapper(self: C, *args: P.args, **kwargs: P.kwargs) -> None: + ctx: custom.Context = args[0] # pyright: ignore [reportAssignmentType] cache = ctx.bot.botkit_cache key_value: str = await parse_reactive_setting(key, ctx.bot, ctx) limit_value: int = await parse_reactive_setting(limit, ctx.bot, ctx) @@ -116,7 +116,7 @@ async def wrapper(self: C, ctx: custom.ApplicationContext, *args: P.args, **kwar if len(time_stamps) >= limit_value: raise cls_value(min(time_stamps) - now + per_value, bucket_type_value) - await func(self, ctx, *args, **kwargs) + await func(self, *args, **kwargs) return wrapper From 26096534854ea5e721a11414ec369f62dbd75130 Mon Sep 17 00:00:00 2001 From: Paillat Date: Thu, 2 Jan 2025 21:23:09 +0100 Subject: [PATCH 43/61] :heavy_plus_sign: Add `aerich[toml]` Fixes #66 --- pdm.lock | 43 ++++++++++++++++++++++++++++++------------- pyproject.toml | 2 +- 2 files changed, 31 insertions(+), 14 deletions(-) diff --git a/pdm.lock b/pdm.lock index cc183f8..5f5360e 100644 --- a/pdm.lock +++ b/pdm.lock @@ -5,27 +5,43 @@ groups = ["default", "dev"] strategy = ["inherit_metadata"] lock_version = "4.5.0" -content_hash = "sha256:23204c88ab6fbbe2c1488e7dec46de84dafd15d9e0d0c538c3cd0facdfe9dff3" +content_hash = "sha256:13f22a28cd70a54bb6f462eff7949cc8648fc3ed9d9eef127b842033831b0a0e" [[metadata.targets]] requires_python = "==3.12.*" [[package]] name = "aerich" -version = "0.8.0" +version = "0.8.1" requires_python = "<4.0,>=3.8" summary = "A database migrations tool for Tortoise ORM." groups = ["default"] dependencies = [ "asyncclick<9.0.0.0,>=8.1.7.2", "dictdiffer", - "pydantic<3.0,>=2.0", - "tomlkit", - "tortoise-orm", + "pydantic!=2.7.0,<3.0,>=2.0", + "tortoise-orm>=0.21", ] files = [ - {file = "aerich-0.8.0-py3-none-any.whl", hash = "sha256:a0afb70027e539cf37d27fb06bb2cbb0dfe01ef2170dae0adc816fe4da0e502d"}, - {file = "aerich-0.8.0.tar.gz", hash = "sha256:13786a91469626c025a2e2c5e524cac2b82b900de063b317f402710ee4c11ccb"}, + {file = "aerich-0.8.1-py3-none-any.whl", hash = "sha256:2743cf85bd9957ea173055dad07ee5a3219067e4f117d5402a44204c27e83c9f"}, + {file = "aerich-0.8.1.tar.gz", hash = "sha256:1e95b1c04dfc0c634dd43b0123933038c820140e17a4b27885a63b7461eb0632"}, +] + +[[package]] +name = "aerich" +version = "0.8.1" +extras = ["toml"] +requires_python = "<4.0,>=3.8" +summary = "A database migrations tool for Tortoise ORM." +groups = ["default"] +dependencies = [ + "aerich==0.8.1", + "tomli-w<2.0.0,>=1.1.0; python_version >= \"3.11\"", + "tomlkit; python_version < \"3.11\"", +] +files = [ + {file = "aerich-0.8.1-py3-none-any.whl", hash = "sha256:2743cf85bd9957ea173055dad07ee5a3219067e4f117d5402a44204c27e83c9f"}, + {file = "aerich-0.8.1.tar.gz", hash = "sha256:1e95b1c04dfc0c634dd43b0123933038c820140e17a4b27885a63b7461eb0632"}, ] [[package]] @@ -1013,14 +1029,15 @@ files = [ ] [[package]] -name = "tomlkit" -version = "0.13.2" -requires_python = ">=3.8" -summary = "Style preserving TOML library" +name = "tomli-w" +version = "1.1.0" +requires_python = ">=3.9" +summary = "A lil' TOML writer" groups = ["default"] +marker = "python_version >= \"3.11\"" files = [ - {file = "tomlkit-0.13.2-py3-none-any.whl", hash = "sha256:7a974427f6e119197f670fbbbeae7bef749a6c14e793db934baefc1b5f03efde"}, - {file = "tomlkit-0.13.2.tar.gz", hash = "sha256:fff5fe59a87295b278abd31bec92c15d9bc4a06885ab12bcea52c71119392e79"}, + {file = "tomli_w-1.1.0-py3-none-any.whl", hash = "sha256:1403179c78193e3184bfaade390ddbd071cba48a32a2e62ba11aae47490c63f7"}, + {file = "tomli_w-1.1.0.tar.gz", hash = "sha256:49e847a3a304d516a169a601184932ef0f6b61623fe680f836a2aa7128ed0d33"}, ] [[package]] diff --git a/pyproject.toml b/pyproject.toml index f4f7773..3d06b28 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -22,7 +22,7 @@ dependencies = [ "sentry-sdk>=2.18.0", "aiocache[redis]>=0.12.3", "tortoise-orm[asyncpg]>=0.23.0", - "aerich>=0.8.0", + "aerich[toml]>=0.8.1", ] requires-python = "==3.12.*" readme = "README.md" From fcfe5f5f32698c5d962ca85cff454f652c54d973 Mon Sep 17 00:00:00 2001 From: Paillat Date: Thu, 2 Jan 2025 22:54:43 +0100 Subject: [PATCH 44/61] :bug: Fix patches not loading --- src/extensions/nice_errors/handlers/base.py | 2 +- src/extensions/nice_errors/patch.py | 5 +++++ src/patcher.py | 4 +++- 3 files changed, 9 insertions(+), 2 deletions(-) diff --git a/src/extensions/nice_errors/handlers/base.py b/src/extensions/nice_errors/handlers/base.py index e5881a6..2c8787b 100644 --- a/src/extensions/nice_errors/handlers/base.py +++ b/src/extensions/nice_errors/handlers/base.py @@ -97,7 +97,7 @@ async def handle_error( ) if handled: return - if report and use_sentry_sdk and sentry_sdk: + if report and use_sentry_sdk: out = sentry_sdk.capture_exception(error) message += f"\n\n-# {translations.reported_to_devs} - `{out}`" await ctx.respond(message, **sendargs) diff --git a/src/extensions/nice_errors/patch.py b/src/extensions/nice_errors/patch.py index 5a8663b..12bf81e 100644 --- a/src/extensions/nice_errors/patch.py +++ b/src/extensions/nice_errors/patch.py @@ -3,8 +3,12 @@ from typing import TYPE_CHECKING, Any +from src.log import logger as base_logger + from .handlers import error_handler +logger = base_logger.getChild("nice_errors") + async def patch(config: dict[str, Any]) -> None: sentry_sdk = None @@ -29,6 +33,7 @@ async def patch(config: dict[str, Any]) -> None: pii_denylist=[*DEFAULT_PII_DENYLIST, "headers", "kwargs"], ), ) + logger.success("Sentry SDK initialized") from discord.ui import View diff --git a/src/patcher.py b/src/patcher.py index 93ca504..1571c63 100644 --- a/src/patcher.py +++ b/src/patcher.py @@ -21,7 +21,9 @@ async def load_and_run_patches() -> None: its_config: dict[Any, Any] = {} if its_config := ( config["extensions"].get(extension, config["extensions"].get(extension.replace("_", "-"), {})) - ) and its_config.get("enabled", False): + ): + if not its_config.get("enabled", False): + continue logger.info(f"Loading patch for extension {extension}") spec = importlib.util.spec_from_file_location(f"src.extensions.{extension}.patch", patch_file) if not spec or not spec.loader: From a7c774420bf5e83eaf88333c0af1cdcd90c753a6 Mon Sep 17 00:00:00 2001 From: Paillat Date: Fri, 10 Jan 2025 12:47:10 +0100 Subject: [PATCH 45/61] :sparkles: Add help extension --- src/custom/__init__.py | 6 +- src/extensions/help/__init__.py | 202 ++++++++++++++++++++++++++ src/extensions/help/pages/__init__.py | 21 +++ src/extensions/help/pages/classes.py | 24 +++ src/extensions/help/translations.yml | 25 ++++ src/i18n/classes.py | 93 +++++++++--- 6 files changed, 352 insertions(+), 19 deletions(-) create mode 100644 src/extensions/help/__init__.py create mode 100644 src/extensions/help/pages/__init__.py create mode 100644 src/extensions/help/pages/classes.py create mode 100644 src/extensions/help/translations.yml diff --git a/src/custom/__init__.py b/src/custom/__init__.py index 4691c1c..61fec82 100644 --- a/src/custom/__init__.py +++ b/src/custom/__init__.py @@ -13,7 +13,7 @@ BridgeExtContext, ) -from src.i18n.classes import ExtensionTranslation, TranslationWrapper, apply_locale +from src.i18n.classes import ExtensionTranslation, RawTranslation, TranslationWrapper, apply_locale if TYPE_CHECKING: from src.database.models import Guild, User @@ -23,7 +23,9 @@ class ApplicationContext(bridge.BridgeApplicationContext): def __init__(self, bot: "Bot", interaction: discord.Interaction) -> None: - self.translations: TranslationWrapper = TranslationWrapper({}, "en-US") # empty placeholder + self.translations: TranslationWrapper[dict[str, RawTranslation]] = TranslationWrapper( + {}, "en-US" + ) # empty placeholder super().__init__(bot=bot, interaction=interaction) self.bot: Bot self.user_obj: User | None = None diff --git a/src/extensions/help/__init__.py b/src/extensions/help/__init__.py new file mode 100644 index 0000000..d5cca4f --- /dev/null +++ b/src/extensions/help/__init__.py @@ -0,0 +1,202 @@ +# Copyright (c) NiceBots all rights reserved +from collections import defaultdict +from functools import cached_property +from typing import Any, Final, final, override + +import discord +from discord.ext import commands +from discord.ext import pages as paginator + +from src import custom +from src.extensions.help.pages.classes import ( + HelpCategoryTranslation, +) +from src.i18n.classes import RawTranslation, TranslationWrapper, apply_locale + +from .pages import help_translation + + +def get_gradient_color(shade_index: int, color_index: int, max_shade: int = 50, max_color: int = 10) -> int: + """Generate a color from a two-dimensional gradient system using bright pastel colors. + + Args: + ---- + shade_index (int): Index for shade selection (0 to max_shade) + color_index (int): Index for base color selection (0 to max_color) + max_shade (int): Maximum value for shade_index (default 50) + max_color (int): Maximum value for color_index (default 10) + + Returns: + ------- + int: Color as a 24-bit integer + + """ + # Normalize indices to 0-1 range + shade_factor = max(0, min(1, shade_index / max_shade)) + color_factor = max(0, min(1, color_index / max_color)) + + # Bright pastel base colors + base_colors = [ + (179, 229, 252), # Bright light blue + (225, 190, 231), # Bright lilac + (255, 209, 220), # Bright pink + (255, 224, 178), # Bright peach + (255, 255, 198), # Bright yellow + (200, 230, 201), # Bright mint + (178, 255, 255), # Bright turquoise + (187, 222, 251), # Bright baby blue + (225, 190, 231), # Bright lavender + (255, 236, 179), # Bright cream + (200, 230, 255), # Bright sky blue + ] + + # Interpolate between colors based on color_factor + color_index_float = color_factor * (len(base_colors) - 1) + color_index_low = int(color_index_float) + color_index_high = min(color_index_low + 1, len(base_colors) - 1) + color_blend = color_index_float - color_index_low + + c1 = base_colors[color_index_low] + c2 = base_colors[color_index_high] + + # Interpolate between the two closest base colors + base_color = tuple(int(c1[i] * (1 - color_blend) + c2[i] * color_blend) for i in range(3)) + + # Modified shading approach for brighter colors + if shade_factor < 0.5: + # Darker shades: interpolate towards a very light gray instead of black + shade_factor_adjusted = shade_factor * 2 + # Increase minimum brightness (was 120, now 180) + darker_tone = tuple(max(c * 0.8, 180) for c in base_color) + final_color = tuple( + int(darker_tone[i] + (base_color[i] - darker_tone[i]) * shade_factor_adjusted) for i in range(3) + ) + else: + # Lighter shades: interpolate towards white + shade_factor_adjusted = (shade_factor - 0.5) * 2 + final_color = tuple( + int(base_color[i] * (1 - shade_factor_adjusted) + 255 * shade_factor_adjusted) for i in range(3) + ) + + # Convert to 24-bit integer + return (final_color[0] << 16) | (final_color[1] << 8) | final_color[2] + + +class PageIndicatorButton(paginator.PaginatorButton): + def __init__(self) -> None: + super().__init__(button_type="page_indicator", disabled=True, label="", style=discord.ButtonStyle.gray) + + +@final +class HelpView(paginator.Paginator): + def __init__( + self, + embeds: dict[str, list[discord.Embed]], + ui_translations: TranslationWrapper[dict[str, RawTranslation]], + bot: custom.Bot, + ) -> None: + self.bot = bot + + the_pages: list[paginator.PageGroup] = [ + paginator.PageGroup( + [paginator.Page(embeds=[embed]) for embed in data[1]], + label=data[0], + default=i == 0, + ) + for i, data in enumerate(embeds.items()) + ] + + self.embeds = embeds + self.ui_translations = ui_translations + self.page_indicator = PageIndicatorButton() + super().__init__( + the_pages, + show_menu=True, + menu_placeholder=ui_translations.select_category, + custom_buttons=[ + paginator.PaginatorButton("first", emoji="⏮️", style=discord.ButtonStyle.blurple), + paginator.PaginatorButton("prev", emoji="◀️", style=discord.ButtonStyle.red), + self.page_indicator, + paginator.PaginatorButton("next", emoji="▶️", style=discord.ButtonStyle.green), + paginator.PaginatorButton("last", emoji="⏭️", style=discord.ButtonStyle.blurple), + ], + use_default_buttons=False, + ) + + @override + def update_buttons(self) -> dict: # pyright: ignore [reportMissingTypeArgument, reportUnknownParameterType] + r = super().update_buttons() # pyright: ignore [reportUnknownVariableType] + if self.show_indicator: + self.buttons["page_indicator"]["object"].label = self.ui_translations.page_indicator.format( + current=self.current_page + 1, total=self.page_count + 1 + ) + return r # pyright: ignore [reportUnknownVariableType] + + +def get_categories_embeds( + ui_translations: TranslationWrapper[dict[str, RawTranslation]], + categories: dict[str, TranslationWrapper[HelpCategoryTranslation]], + bot: custom.Bot, +) -> dict[str, list[discord.Embed]]: + embeds: defaultdict[str, list[discord.Embed]] = defaultdict(list) + for i, category in enumerate(categories): + for j, page in enumerate(category.pages.values()): # pyright: ignore [reportUnknownArgumentType, reportUnknownVariableType, reportAttributeAccessIssue] + embed = discord.Embed( + title=f"{category.name} - {page.title}", # pyright: ignore [reportAttributeAccessIssue] + description=page.description, # pyright: ignore [reportUnknownArgumentType] + color=discord.Color(get_gradient_color(i, j)), + ) + if page.quick_tips: + embed.add_field(name=ui_translations.quick_tips_title, value="- " + "\n- ".join(page.quick_tips)) # pyright: ignore [reportUnknownArgumentType] + if page.examples: + embed.add_field(name=ui_translations.examples_title, value="- " + "\n- ".join(page.examples)) # pyright: ignore [reportUnknownArgumentType] + if page.related_commands: + embed.add_field( + name=ui_translations.related_commands_title, + value="- " + + "\n- ".join(bot.get_application_command(name).mention for name in page.related_commands), # pyright: ignore [reportUnknownArgumentType, reportUnknownVariableType, reportAttributeAccessIssue, reportOptionalMemberAccess] + ) + embeds[category.name].append(embed) # pyright: ignore [reportAttributeAccessIssue] + return dict(embeds) + + +@final +class Help(commands.Cog): + def __init__(self, bot: custom.Bot, ui_translations: dict[str, RawTranslation], locales: set[str]) -> None: + self.bot = bot + self.ui_translations = ui_translations + self.locales = locales + + @cached_property + async def embeds(self) -> dict[str, dict[str, list[discord.Embed]]]: + embeds: defaultdict[str, dict[str, list[discord.Embed]]] = defaultdict(dict) + for locale in self.locales: + t = help_translation.get_for_locale(locale) + ui = apply_locale(self.ui_translations, locale) + embeds[locale] = get_categories_embeds(ui, t.categories, self.bot) + return dict(embeds) + + @discord.slash_command( + name="help", + integration_types={discord.IntegrationType.user_install, discord.IntegrationType.guild_install}, + contexts={ + discord.InteractionContextType.guild, + discord.InteractionContextType.private_channel, + discord.InteractionContextType.bot_dm, + }, + ) + async def help_slash(self, ctx: custom.ApplicationContext) -> None: + paginator = HelpView( + embeds=self.embeds[ctx.locale], + ui_translations=apply_locale(self.ui_translations, ctx.locale), + bot=self.bot, + ) + await paginator.respond(ctx.interaction, ephemeral=True) + + +def setup(bot: custom.Bot, config: dict[str, Any]) -> None: # pyright: ignore [reportExplicitAny] + bot.add_cog(Help(bot, config["translations"], set(config["locales"]))) + + +default: Final = {"enabled": False} +__all__ = ["default", "setup"] diff --git a/src/extensions/help/pages/__init__.py b/src/extensions/help/pages/__init__.py new file mode 100644 index 0000000..01ff1c8 --- /dev/null +++ b/src/extensions/help/pages/__init__.py @@ -0,0 +1,21 @@ +# Copyright (c) NiceBots +# SPDX-License-Identifier: MIT + +from itertools import chain +from pathlib import Path + +import yaml + +from .classes import HelpCategoryTranslation, HelpTranslation + +# iterate over .y[a]ml files in the same directory as this file +categories: list[HelpCategoryTranslation] = [] + +for file in chain(Path(__file__).parent.glob("*.yaml"), Path(__file__).parent.glob("*.yml")): + with open(file, encoding="utf-8") as f: + data = yaml.safe_load(f) + categories.append(HelpCategoryTranslation(**data)) + +categories.sort(key=lambda item: item.order) + +help_translation = HelpTranslation(categories=categories) diff --git a/src/extensions/help/pages/classes.py b/src/extensions/help/pages/classes.py new file mode 100644 index 0000000..49b063c --- /dev/null +++ b/src/extensions/help/pages/classes.py @@ -0,0 +1,24 @@ +# Copyright (c) NiceBots +# SPDX-License-Identifier: MIT + +from src.i18n.classes import RawTranslation, Translation + + +class HelpPageTranslation(Translation): + title: RawTranslation + description: RawTranslation + category: RawTranslation + quick_tips: list[RawTranslation] | None = None + examples: list[RawTranslation] | None = None + related_commands: list[str] | None = None + + +class HelpCategoryTranslation(Translation): + name: RawTranslation + description: RawTranslation + pages: dict[str, HelpPageTranslation] + order: int # For sorting categories in the dropdown + + +class HelpTranslation(Translation): + categories: list[HelpCategoryTranslation] diff --git a/src/extensions/help/translations.yml b/src/extensions/help/translations.yml new file mode 100644 index 0000000..62c5864 --- /dev/null +++ b/src/extensions/help/translations.yml @@ -0,0 +1,25 @@ +# Copyright (c) NiceBots all rights reserved +strings: + quick_tips_title: + en-US: Tips & Tricks + es-ES: Consejos y Trucos + examples_title: + en-US: Usage Examples + es-ES: Ejemplos de Uso + related_commands_title: + en-US: Available Commands + es-ES: Comandos Disponibles + select_category: + en-US: Select a category + es-ES: Selecciona una categoría + page_indicator: + en-US: Page {current} of {total} + es-ES: Página {current} de {total} +commands: + help: + name: + en-US: help + es-ES: ayuda + description: + en-US: Get help with using the bot + es-ES: Obtén ayuda para usar el bot diff --git a/src/i18n/classes.py b/src/i18n/classes.py index a779298..32bbf85 100644 --- a/src/i18n/classes.py +++ b/src/i18n/classes.py @@ -1,7 +1,8 @@ # Copyright (c) NiceBots.xyz # SPDX-License-Identifier: MIT -from typing import Any, override +from collections.abc import Generator, Iterator +from typing import Any, Self, override from pydantic import BaseModel, Field @@ -79,31 +80,89 @@ class Config: class Translation(BaseModel): - def get_for_locale(self, locale: str) -> "TranslationWrapper": + def get_for_locale(self, locale: str) -> "TranslationWrapper[Self]": return apply_locale(self, locale) -class TranslationWrapper: +class TranslationWrapper[T: "Translatable"]: def __init__(self, model: "Translatable", locale: str, default: str = DEFAULT) -> None: - self._model = model + self._model: T = model self._default: str self.default = default.replace("-", "_") self._locale: str self.locale = locale.replace("-", "_") + def _wrap_value(self, value: Any) -> Any: + """Consistently wrap values in TranslationWrapper if needed.""" + if value is None: + return None + if isinstance(value, str | int | float | bool): + return value + if isinstance(value, RawTranslation): + try: + return getattr(value, self._locale) or getattr(value, self._default) + except AttributeError: + return getattr(value, self._default) + if isinstance(value, list | tuple): + return [self._wrap_value(item) for item in value] + + # For any other type (including Pydantic models), apply locale + return apply_locale(value, self._locale) + def __getattr__(self, key: str) -> Any: if isinstance(self._model, dict): - applicable = self._model.get(key) - if not applicable: + if key not in self._model: raise AttributeError(f'Key "{key}" not found in {self._model}') + value = self._model[key] else: - applicable = getattr(self._model, key) - if isinstance(applicable, RawTranslation): - try: - return getattr(applicable, self._locale) or getattr(applicable, self._default) - except AttributeError: - return getattr(applicable, self._default) - return apply_locale(applicable, self._locale) + value = getattr(self._model, key) + return self._wrap_value(value) + + def __getitem__(self, item: Any) -> Any: + if isinstance(self._model, dict): + if not isinstance(item, str): + raise TypeError(f"Key must be a string, not {type(item).__name__}") + return self.__getattr__(item) + if isinstance(self._model, list): + if not isinstance(item, int): + raise TypeError(f"Index must be an integer, not {type(item).__name__}") + return self._wrap_value(self._model[item]) + return self.__getattr__(item) + + def keys(self) -> Generator[str, None, None]: + if not isinstance(self._model, dict): + raise TypeError(f"Cannot get keys from {type(self._model).__name__}") + yield from self._model.keys() + + def items(self) -> Generator[tuple[str, Any], None, None]: + if isinstance(self._model, dict): + for key, value in self._model.items(): + yield key, self._wrap_value(value) + else: + for key in self.keys(): + yield key, self._wrap_value(getattr(self._model, key)) + + def values(self) -> Generator[Any, None, None]: + if isinstance(self._model, dict): + for value in self._model.values(): + yield self._wrap_value(value) + else: + for key in self.keys(): + yield self._wrap_value(getattr(self._model, key)) + + def __iter__(self) -> Iterator[Any]: + if isinstance(self._model, list): + for item in self._model: + yield self._wrap_value(item) + else: + yield from self.keys() + + def __len__(self) -> int: + if isinstance(self._model, dict): + return len(self._model) + if isinstance(self._model, list): + return len(self._model) + return len(self._model.__dict__) @property def locale(self) -> str: @@ -129,7 +188,7 @@ def default(self, value: str) -> None: @override def __repr__(self) -> str: - return repr(self._model) + return f"TranslationWrapper({self._model!r}, locale={self._locale!r}, default={self._default!r})" @override def __str__(self) -> str: @@ -168,11 +227,11 @@ class ExtensionTranslation(Translation): strings: dict[str, RawTranslation] | None = None -def apply_locale( - model: "Translatable | TranslationWrapper", +def apply_locale[T: "Translatable"]( + model: T, locale: str | None, default: str | None = DEFAULT, -) -> TranslationWrapper: +) -> TranslationWrapper[T]: default = default if default is not None else DEFAULT if locale is None: locale = DEFAULT From 7be7f0580cbd7d129cebcaf91824d69a25123def Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Sat, 11 Jan 2025 12:21:12 +0100 Subject: [PATCH 46/61] =?UTF-8?q?=E2=AC=86=EF=B8=8F=20Upgrade=20docker/bui?= =?UTF-8?q?ld-push-action=20action=20to=20v6.11.0=20(#69)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- .github/workflows/docker.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/docker.yaml b/.github/workflows/docker.yaml index 0be543b..424bc8d 100644 --- a/.github/workflows/docker.yaml +++ b/.github/workflows/docker.yaml @@ -39,7 +39,7 @@ jobs: type=sha - name: Build and push Docker image - uses: docker/build-push-action@v6.10.0 + uses: docker/build-push-action@v6.11.0 with: context: . push: true From acf1cc5af0635eee17cc092949c8549373cf4f5c Mon Sep 17 00:00:00 2001 From: Paillat Date: Sat, 11 Jan 2025 12:26:51 +0100 Subject: [PATCH 47/61] :construction_worker: Reuse branch in update_dependencies.yaml (#71) --- .github/workflows/update_dependencies.yaml | 38 ++++++++++++++-------- 1 file changed, 25 insertions(+), 13 deletions(-) diff --git a/.github/workflows/update_dependencies.yaml b/.github/workflows/update_dependencies.yaml index 5005470..084585b 100644 --- a/.github/workflows/update_dependencies.yaml +++ b/.github/workflows/update_dependencies.yaml @@ -55,7 +55,7 @@ jobs: run: | git config user.name github-actions git config user.email github-actions@github.com - + if [ -n "${{ inputs.pr_branch }}" ]; then # Push to existing branch BRANCH_NAME=$(echo ${{ inputs.pr_branch }} | cut -d'/' -f 3) @@ -64,18 +64,30 @@ jobs: git commit -m "Update dependencies" git push origin $BRANCH_NAME else - # Create new branch and PR - NEW_BRANCH="update-dependencies-${{ github.run_id }}" - git checkout -b $NEW_BRANCH - git add requirements.txt pyproject.toml pdm.lock - git commit -m "Update dependencies" - git push origin $NEW_BRANCH - - gh pr create \ - --title "Update dependencies" \ - --body "This PR updates the project dependencies. Please review the changes and merge if everything looks good." \ - --base ${{ github.ref_name }} \ - --head $NEW_BRANCH + # Check for existing PR + EXISTING_PR=$(gh pr list --search "Update dependencies in:title is:open" --json headRefName,number -q '.[0]') + + if [ -n "$EXISTING_PR" ]; then + # Update existing PR + BRANCH_NAME=$(echo $EXISTING_PR | jq -r .headRefName) + git checkout -B $BRANCH_NAME + git add requirements.txt pyproject.toml pdm.lock + git commit -m "Update dependencies" + git push -f origin $BRANCH_NAME + else + # Create new branch and PR + NEW_BRANCH="update-dependencies-${{ github.run_id }}" + git checkout -b $NEW_BRANCH + git add requirements.txt pyproject.toml pdm.lock + git commit -m "Update dependencies" + git push origin $NEW_BRANCH + + gh pr create \ + --title "Update dependencies" \ + --body "This PR updates the project dependencies. Please review the changes and merge if everything looks good." \ + --base ${{ github.ref_name }} \ + --head $NEW_BRANCH + fi fi env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} \ No newline at end of file From e062c8fa4c650ac05b8f4a7f339abe0b42ab5233 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Sat, 11 Jan 2025 12:30:12 +0100 Subject: [PATCH 48/61] Update dependencies (#68) Co-authored-by: github-actions --- pdm.lock | 320 +++++++++++++++++++++++------------------------ requirements.txt | 195 +++++++++++++++++------------ 2 files changed, 277 insertions(+), 238 deletions(-) diff --git a/pdm.lock b/pdm.lock index 5f5360e..8740112 100644 --- a/pdm.lock +++ b/pdm.lock @@ -107,7 +107,7 @@ files = [ [[package]] name = "aiohttp" -version = "3.11.10" +version = "3.11.11" requires_python = ">=3.9" summary = "Async http client/server framework (asyncio)" groups = ["default"] @@ -122,36 +122,36 @@ dependencies = [ "yarl<2.0,>=1.17.0", ] files = [ - {file = "aiohttp-3.11.10-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:b78f053a7ecfc35f0451d961dacdc671f4bcbc2f58241a7c820e9d82559844cf"}, - {file = "aiohttp-3.11.10-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:ab7485222db0959a87fbe8125e233b5a6f01f4400785b36e8a7878170d8c3138"}, - {file = "aiohttp-3.11.10-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:cf14627232dfa8730453752e9cdc210966490992234d77ff90bc8dc0dce361d5"}, - {file = "aiohttp-3.11.10-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:076bc454a7e6fd646bc82ea7f98296be0b1219b5e3ef8a488afbdd8e81fbac50"}, - {file = "aiohttp-3.11.10-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:482cafb7dc886bebeb6c9ba7925e03591a62ab34298ee70d3dd47ba966370d2c"}, - {file = "aiohttp-3.11.10-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:bf3d1a519a324af764a46da4115bdbd566b3c73fb793ffb97f9111dbc684fc4d"}, - {file = "aiohttp-3.11.10-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:24213ba85a419103e641e55c27dc7ff03536c4873470c2478cce3311ba1eee7b"}, - {file = "aiohttp-3.11.10-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b99acd4730ad1b196bfb03ee0803e4adac371ae8efa7e1cbc820200fc5ded109"}, - {file = "aiohttp-3.11.10-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:14cdb5a9570be5a04eec2ace174a48ae85833c2aadc86de68f55541f66ce42ab"}, - {file = "aiohttp-3.11.10-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:7e97d622cb083e86f18317282084bc9fbf261801b0192c34fe4b1febd9f7ae69"}, - {file = "aiohttp-3.11.10-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:012f176945af138abc10c4a48743327a92b4ca9adc7a0e078077cdb5dbab7be0"}, - {file = "aiohttp-3.11.10-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:44224d815853962f48fe124748227773acd9686eba6dc102578defd6fc99e8d9"}, - {file = "aiohttp-3.11.10-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:c87bf31b7fdab94ae3adbe4a48e711bfc5f89d21cf4c197e75561def39e223bc"}, - {file = "aiohttp-3.11.10-cp312-cp312-win32.whl", hash = "sha256:06a8e2ee1cbac16fe61e51e0b0c269400e781b13bcfc33f5425912391a542985"}, - {file = "aiohttp-3.11.10-cp312-cp312-win_amd64.whl", hash = "sha256:be2b516f56ea883a3e14dda17059716593526e10fb6303189aaf5503937db408"}, - {file = "aiohttp-3.11.10.tar.gz", hash = "sha256:b1fc6b45010a8d0ff9e88f9f2418c6fd408c99c211257334aff41597ebece42e"}, + {file = "aiohttp-3.11.11-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:e595c591a48bbc295ebf47cb91aebf9bd32f3ff76749ecf282ea7f9f6bb73886"}, + {file = "aiohttp-3.11.11-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:3ea1b59dc06396b0b424740a10a0a63974c725b1c64736ff788a3689d36c02d2"}, + {file = "aiohttp-3.11.11-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:8811f3f098a78ffa16e0ea36dffd577eb031aea797cbdba81be039a4169e242c"}, + {file = "aiohttp-3.11.11-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bd7227b87a355ce1f4bf83bfae4399b1f5bb42e0259cb9405824bd03d2f4336a"}, + {file = "aiohttp-3.11.11-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d40f9da8cabbf295d3a9dae1295c69975b86d941bc20f0a087f0477fa0a66231"}, + {file = "aiohttp-3.11.11-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:ffb3dc385f6bb1568aa974fe65da84723210e5d9707e360e9ecb51f59406cd2e"}, + {file = "aiohttp-3.11.11-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a8f5f7515f3552d899c61202d99dcb17d6e3b0de777900405611cd747cecd1b8"}, + {file = "aiohttp-3.11.11-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:3499c7ffbfd9c6a3d8d6a2b01c26639da7e43d47c7b4f788016226b1e711caa8"}, + {file = "aiohttp-3.11.11-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:8e2bf8029dbf0810c7bfbc3e594b51c4cc9101fbffb583a3923aea184724203c"}, + {file = "aiohttp-3.11.11-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:b6212a60e5c482ef90f2d788835387070a88d52cf6241d3916733c9176d39eab"}, + {file = "aiohttp-3.11.11-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:d119fafe7b634dbfa25a8c597718e69a930e4847f0b88e172744be24515140da"}, + {file = "aiohttp-3.11.11-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:6fba278063559acc730abf49845d0e9a9e1ba74f85f0ee6efd5803f08b285853"}, + {file = "aiohttp-3.11.11-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:92fc484e34b733704ad77210c7957679c5c3877bd1e6b6d74b185e9320cc716e"}, + {file = "aiohttp-3.11.11-cp312-cp312-win32.whl", hash = "sha256:9f5b3c1ed63c8fa937a920b6c1bec78b74ee09593b3f5b979ab2ae5ef60d7600"}, + {file = "aiohttp-3.11.11-cp312-cp312-win_amd64.whl", hash = "sha256:1e69966ea6ef0c14ee53ef7a3d68b564cc408121ea56c0caa2dc918c1b2f553d"}, + {file = "aiohttp-3.11.11.tar.gz", hash = "sha256:bb49c7f1e6ebf3821a42d81d494f538107610c3a705987f53068546b0e90303e"}, ] [[package]] name = "aiosignal" -version = "1.3.1" -requires_python = ">=3.7" +version = "1.3.2" +requires_python = ">=3.9" summary = "aiosignal: a list of registered asynchronous callbacks" groups = ["default"] dependencies = [ "frozenlist>=1.1.0", ] files = [ - {file = "aiosignal-1.3.1-py3-none-any.whl", hash = "sha256:f8376fb07dd1e86a584e4fcdec80b36b7f81aac666ebc724e2c090300dd83b17"}, - {file = "aiosignal-1.3.1.tar.gz", hash = "sha256:54cd96e15e1649b75d6c87526a6ff0b6c1b0dd3459f43d9ca11d48c339b68cfc"}, + {file = "aiosignal-1.3.2-py2.py3-none-any.whl", hash = "sha256:45cde58e409a301715980c2b01d0c28bdde3770d8290b5eb2173759d9acb31a5"}, + {file = "aiosignal-1.3.2.tar.gz", hash = "sha256:a8c255c66fafb1e499c9351d0bf32ff2d8a0321595ebac3b93713656d2436f54"}, ] [[package]] @@ -184,7 +184,7 @@ files = [ [[package]] name = "anyio" -version = "4.7.0" +version = "4.8.0" requires_python = ">=3.9" summary = "High level compatibility layer for multiple asynchronous event loop implementations" groups = ["default"] @@ -195,24 +195,24 @@ dependencies = [ "typing-extensions>=4.5; python_version < \"3.13\"", ] files = [ - {file = "anyio-4.7.0-py3-none-any.whl", hash = "sha256:ea60c3723ab42ba6fff7e8ccb0488c898ec538ff4df1f1d5e642c3601d07e352"}, - {file = "anyio-4.7.0.tar.gz", hash = "sha256:2f834749c602966b7d456a7567cafcb309f96482b5081d14ac93ccd457f9dd48"}, + {file = "anyio-4.8.0-py3-none-any.whl", hash = "sha256:b5011f270ab5eb0abf13385f851315585cc37ef330dd88e27ec3d34d651fd47a"}, + {file = "anyio-4.8.0.tar.gz", hash = "sha256:1d9fe889df5212298c0c0723fa20479d1b94883a2df44bd3897aa91083316f7a"}, ] [[package]] name = "asyncclick" -version = "8.1.7.2" -requires_python = ">=3.7" -summary = "Composable command line interface toolkit, async version" +version = "8.1.8" +requires_python = ">=3.9" +summary = "Composable command line interface toolkit, " groups = ["default"] dependencies = [ - "anyio", + "anyio~=4.0", "colorama; platform_system == \"Windows\"", - "importlib-metadata; python_version < \"3.8\"", ] files = [ - {file = "asyncclick-8.1.7.2-py3-none-any.whl", hash = "sha256:1ab940b04b22cb89b5b400725132b069d01b0c3472a9702c7a2c9d5d007ded02"}, - {file = "asyncclick-8.1.7.2.tar.gz", hash = "sha256:219ea0f29ccdc1bb4ff43bcab7ce0769ac6d48a04f997b43ec6bee99a222daa0"}, + {file = "asyncclick-8.1.8-py3-none-any.whl", hash = "sha256:eb1ccb44bc767f8f0695d592c7806fdf5bd575605b4ee246ffd5fadbcfdbd7c6"}, + {file = "asyncclick-8.1.8.0-py3-none-any.whl", hash = "sha256:be146a2d8075d4fe372ff4e877f23c8b5af269d16705c1948123b9415f6fd678"}, + {file = "asyncclick-8.1.8.tar.gz", hash = "sha256:0f0eb0f280e04919d67cf71b9fcdfb4db2d9ff7203669c40284485c149578e4c"}, ] [[package]] @@ -238,21 +238,18 @@ files = [ [[package]] name = "attrs" -version = "24.2.0" -requires_python = ">=3.7" +version = "24.3.0" +requires_python = ">=3.8" summary = "Classes Without Boilerplate" groups = ["default"] -dependencies = [ - "importlib-metadata; python_version < \"3.8\"", -] files = [ - {file = "attrs-24.2.0-py3-none-any.whl", hash = "sha256:81921eb96de3191c8258c199618104dd27ac608d9366f5e35d011eae1867ede2"}, - {file = "attrs-24.2.0.tar.gz", hash = "sha256:5cfb1b9148b5b086569baec03f20d7b6bf3bcacc9a42bebf87ffaaca362f6346"}, + {file = "attrs-24.3.0-py3-none-any.whl", hash = "sha256:ac96cd038792094f438ad1f6ff80837353805ac950cd2aa0e0625ef19850c308"}, + {file = "attrs-24.3.0.tar.gz", hash = "sha256:8f5c07333d543103541ba7be0e2ce16eeee8130cb0b3f9238ab904ce1e85baff"}, ] [[package]] name = "basedpyright" -version = "1.22.1" +version = "1.23.2" requires_python = ">=3.8" summary = "static type checking for Python (but based)" groups = ["dev"] @@ -260,8 +257,8 @@ dependencies = [ "nodejs-wheel-binaries>=20.13.1", ] files = [ - {file = "basedpyright-1.22.1-py3-none-any.whl", hash = "sha256:b25597757400ec082b1099eb99f0fc74857ff4dcd7caa198bf1e236d17214ebf"}, - {file = "basedpyright-1.22.1.tar.gz", hash = "sha256:f7a2d0e49c7d375ce9e02a7c235536e824833c9df89c2ca7e605ab1a2995808f"}, + {file = "basedpyright-1.23.2-py3-none-any.whl", hash = "sha256:a859f035f031e6ce1d1bc43d73b4e364238c39811f9b6fcd31e886183097ea22"}, + {file = "basedpyright-1.23.2.tar.gz", hash = "sha256:367c3bef9edff8d3ba35ccfc467f2e680a4b5936697eff3d42219e58febfe3c8"}, ] [[package]] @@ -291,31 +288,31 @@ files = [ [[package]] name = "caio" -version = "0.9.17" +version = "0.9.19" requires_python = "<4,>=3.7" summary = "Asynchronous file IO for Linux MacOS or Windows." groups = ["default"] files = [ - {file = "caio-0.9.17-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:0ddb253b145a53ecca76381677ce465bc5efeaecb6aaf493fac43ae79659f0fb"}, - {file = "caio-0.9.17-cp312-cp312-manylinux_2_12_x86_64.manylinux2010_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b3e320b0ea371c810359934f8e8fe81777c493cc5fb4d41de44277cbe7336e74"}, - {file = "caio-0.9.17-py3-none-any.whl", hash = "sha256:c55d4dc6b3a36f93237ecd6360e1c131c3808bc47d4191a130148a99b80bb311"}, - {file = "caio-0.9.17.tar.gz", hash = "sha256:8f30511526814d961aeef389ea6885273abe6c655f1e08abbadb95d12fdd9b4f"}, + {file = "caio-0.9.19-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:6d426f2e9fcec7b1a767b187861bd0aecae9f88bc36227331d2fb978722bed90"}, + {file = "caio-0.9.19-cp312-cp312-manylinux_2_12_x86_64.manylinux2010_x86_64.manylinux_2_34_x86_64.whl", hash = "sha256:a743fda13e194b21df922ea0cee404e2bcac72a722c469eed6bd893a0cdec1c0"}, + {file = "caio-0.9.19-cp312-cp312-manylinux_2_34_aarch64.whl", hash = "sha256:f2bc23784f50ac8a2b5a3a0625ff181a92cbb8f4ce532d23a6be441c38deb7c8"}, + {file = "caio-0.9.19.tar.gz", hash = "sha256:bdcb529330730c4c364b79789620f33bafad8c2c854c1205ecc2d16511c0b690"}, ] [[package]] name = "certifi" -version = "2024.8.30" +version = "2024.12.14" requires_python = ">=3.6" summary = "Python package for providing Mozilla's CA Bundle." groups = ["default"] files = [ - {file = "certifi-2024.8.30-py3-none-any.whl", hash = "sha256:922820b53db7a7257ffbda3f597266d435245903d80737e34f8a45ff3e3230d8"}, - {file = "certifi-2024.8.30.tar.gz", hash = "sha256:bec941d2aa8195e248a60b31ff9f0558284cf01a52591ceda73ea9afffd69fd9"}, + {file = "certifi-2024.12.14-py3-none-any.whl", hash = "sha256:1275f7a45be9464efc1173084eaa30f866fe2e47d389406136d332ed4967ec56"}, + {file = "certifi-2024.12.14.tar.gz", hash = "sha256:b650d30f370c2b724812bee08008be0c4163b163ddaec3f2546c1caf65f191db"}, ] [[package]] name = "click" -version = "8.1.7" +version = "8.1.8" requires_python = ">=3.7" summary = "Composable command line interface toolkit" groups = ["default"] @@ -324,8 +321,8 @@ dependencies = [ "importlib-metadata; python_version < \"3.8\"", ] files = [ - {file = "click-8.1.7-py3-none-any.whl", hash = "sha256:ae74fb96c20a0277a1d615f1e4d73c8414f5a98db8b799a7931d1582f3390c28"}, - {file = "click-8.1.7.tar.gz", hash = "sha256:ca9853ad459e787e2192211578cc907e7594e294c7ccc834310722b41b9ca6de"}, + {file = "click-8.1.8-py3-none-any.whl", hash = "sha256:63c132bbbed01578a06712a2d1f497bb62d9c1c0d329b7903a866228027263b2"}, + {file = "click-8.1.8.tar.gz", hash = "sha256:ed53c9d8990d83c2a27deae68e4ee337473f6330c040a31d4225c9574d16096a"}, ] [[package]] @@ -557,7 +554,7 @@ files = [ [[package]] name = "jinja2" -version = "3.1.4" +version = "3.1.5" requires_python = ">=3.7" summary = "A very fast and expressive template engine." groups = ["default"] @@ -565,8 +562,8 @@ dependencies = [ "MarkupSafe>=2.0", ] files = [ - {file = "jinja2-3.1.4-py3-none-any.whl", hash = "sha256:bc5dd2abb727a5319567b7a813e6a2e7318c39f4f487cfe6c89c6f9c7d25197d"}, - {file = "jinja2-3.1.4.tar.gz", hash = "sha256:4a3aee7acbbe7303aede8e9648d13b8bf88a429282aa6122a993f0ac800cb369"}, + {file = "jinja2-3.1.5-py3-none-any.whl", hash = "sha256:aba0f4dc9ed8013c424088f68a5c226f7d6097ed89b246d7749c2ec4175c6adb"}, + {file = "jinja2-3.1.5.tar.gz", hash = "sha256:8fefff8dc3034e27bb80d67c671eb8a9bc424c0ef4c0826edbff304cceff43bb"}, ] [[package]] @@ -645,7 +642,7 @@ files = [ [[package]] name = "nodejs-wheel-binaries" -version = "22.12.0" +version = "22.13.0" requires_python = ">=3.7" summary = "unoffical Node.js package" groups = ["dev"] @@ -653,53 +650,53 @@ dependencies = [ "typing-extensions; python_version < \"3.8\"", ] files = [ - {file = "nodejs_wheel_binaries-22.12.0-py2.py3-none-macosx_11_0_arm64.whl", hash = "sha256:8ed26eac5a96f3bfcd36f1eb9c397f07392e8b166895e0a65eb6033baefa0217"}, - {file = "nodejs_wheel_binaries-22.12.0-py2.py3-none-macosx_11_0_x86_64.whl", hash = "sha256:ca853c919e18860eb75ac3563985391d07eb50f6ab0aadcb48842bcc0ee8dd45"}, - {file = "nodejs_wheel_binaries-22.12.0-py2.py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e6df3f2606e26d3334de1fc15c4e6a833980a02ed2eae528d90ddaacaaab2dd1"}, - {file = "nodejs_wheel_binaries-22.12.0-py2.py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:335176ffa5f753c4d447af83f70987f5f82becdf84fadf56d5c0036379826cff"}, - {file = "nodejs_wheel_binaries-22.12.0-py2.py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:44f0b372a9ea218be885d14b370e774366d09697ae193b741b83cf04c6753884"}, - {file = "nodejs_wheel_binaries-22.12.0-py2.py3-none-win_amd64.whl", hash = "sha256:d1a63fc84b0a5a94b19f428ecc1eb1bf4d09c9fc26390db52231c01c3667fe82"}, - {file = "nodejs_wheel_binaries-22.12.0-py2.py3-none-win_arm64.whl", hash = "sha256:cc363752be784bf6496329060c53c4d8a993dca73815bb179b37dba5c6d6db1c"}, - {file = "nodejs_wheel_binaries-22.12.0.tar.gz", hash = "sha256:e9b707766498322bb2b79fb4f6f425ef86904feccc72cc426f8d96f75488518e"}, + {file = "nodejs_wheel_binaries-22.13.0-py2.py3-none-macosx_11_0_arm64.whl", hash = "sha256:646ab3e65296de9c578db9a1dcfbca26386d2ead70a49008f75d02e960593b2f"}, + {file = "nodejs_wheel_binaries-22.13.0-py2.py3-none-macosx_11_0_x86_64.whl", hash = "sha256:38c689d556f428415a77655f70d2046ddbe11604039489f029b12f317042eaf4"}, + {file = "nodejs_wheel_binaries-22.13.0-py2.py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:61885cbcfff0a6d40353c8ea3d861ccb65dba7ce4b19f22427719aeeb35d42f1"}, + {file = "nodejs_wheel_binaries-22.13.0-py2.py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e358439ff830db766006e6eeb85ababb94b8c41c7325c9eb1f873a52d3df3016"}, + {file = "nodejs_wheel_binaries-22.13.0-py2.py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:1e26d39448cbb2969da10f5e62e53101591e4d6c6a6ae8d623c65f56bf28ce6b"}, + {file = "nodejs_wheel_binaries-22.13.0-py2.py3-none-win_amd64.whl", hash = "sha256:cd9c6cdfd00ec48c55cbcd21a98af1fc9c2a18f039aede729de319346ed8675d"}, + {file = "nodejs_wheel_binaries-22.13.0-py2.py3-none-win_arm64.whl", hash = "sha256:aa8af75d30c3132bc4e998126a78b11c269abc3060f1c7c697907299b21ae0e1"}, + {file = "nodejs_wheel_binaries-22.13.0.tar.gz", hash = "sha256:dd811e3e5b92f2e5d4eb236cdf1ff814c91d3d3533d90d63b4af41d07a8bb2fc"}, ] [[package]] name = "nodriver" -version = "0.38.post1" +version = "0.39" requires_python = ">=3.9" summary = "[Docs here](https://ultrafunkamsterdam.github.io/nodriver)" groups = ["dev"] dependencies = [ "deprecated", "mss", - "websockets<=13.1", + "websockets>=14", ] files = [ - {file = "nodriver-0.38.post1-py3-none-any.whl", hash = "sha256:ce82832fb2b2c8610f05c6d8f264a6c40664c31d9ca9d1595eed11da7208151b"}, - {file = "nodriver-0.38.post1.tar.gz", hash = "sha256:7df680e309b0c0f087d4ac0103556794b7fadc081b63182e44e0fa274f28ff8a"}, + {file = "nodriver-0.39-py3-none-any.whl", hash = "sha256:f245be52e6328393ece340a6dcbc8d5754fd7cf0838f0e1e40076944617178fc"}, + {file = "nodriver-0.39.tar.gz", hash = "sha256:af84f76215877c74166f95c8e7615268e31f6118f4c7291d201f29003f2248ef"}, ] [[package]] name = "orjson" -version = "3.10.12" +version = "3.10.14" requires_python = ">=3.8" summary = "Fast, correct Python JSON library supporting dataclasses, datetimes, and numpy" groups = ["default"] files = [ - {file = "orjson-3.10.12-cp312-cp312-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:53206d72eb656ca5ac7d3a7141e83c5bbd3ac30d5eccfe019409177a57634b0d"}, - {file = "orjson-3.10.12-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ac8010afc2150d417ebda810e8df08dd3f544e0dd2acab5370cfa6bcc0662f8f"}, - {file = "orjson-3.10.12-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:ed459b46012ae950dd2e17150e838ab08215421487371fa79d0eced8d1461d70"}, - {file = "orjson-3.10.12-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:8dcb9673f108a93c1b52bfc51b0af422c2d08d4fc710ce9c839faad25020bb69"}, - {file = "orjson-3.10.12-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:22a51ae77680c5c4652ebc63a83d5255ac7d65582891d9424b566fb3b5375ee9"}, - {file = "orjson-3.10.12-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:910fdf2ac0637b9a77d1aad65f803bac414f0b06f720073438a7bd8906298192"}, - {file = "orjson-3.10.12-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:24ce85f7100160936bc2116c09d1a8492639418633119a2224114f67f63a4559"}, - {file = "orjson-3.10.12-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:8a76ba5fc8dd9c913640292df27bff80a685bed3a3c990d59aa6ce24c352f8fc"}, - {file = "orjson-3.10.12-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:ff70ef093895fd53f4055ca75f93f047e088d1430888ca1229393a7c0521100f"}, - {file = "orjson-3.10.12-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:f4244b7018b5753ecd10a6d324ec1f347da130c953a9c88432c7fbc8875d13be"}, - {file = "orjson-3.10.12-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:16135ccca03445f37921fa4b585cff9a58aa8d81ebcb27622e69bfadd220b32c"}, - {file = "orjson-3.10.12-cp312-none-win32.whl", hash = "sha256:2d879c81172d583e34153d524fcba5d4adafbab8349a7b9f16ae511c2cee8708"}, - {file = "orjson-3.10.12-cp312-none-win_amd64.whl", hash = "sha256:fc23f691fa0f5c140576b8c365bc942d577d861a9ee1142e4db468e4e17094fb"}, - {file = "orjson-3.10.12.tar.gz", hash = "sha256:0a78bbda3aea0f9f079057ee1ee8a1ecf790d4f1af88dd67493c6b8ee52506ff"}, + {file = "orjson-3.10.14-cp312-cp312-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:2ad4b7e367efba6dc3f119c9a0fcd41908b7ec0399a696f3cdea7ec477441b09"}, + {file = "orjson-3.10.14-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f496286fc85e93ce0f71cc84fc1c42de2decf1bf494094e188e27a53694777a7"}, + {file = "orjson-3.10.14-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:c7f189bbfcded40e41a6969c1068ba305850ba016665be71a217918931416fbf"}, + {file = "orjson-3.10.14-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:8cc8204f0b75606869c707da331058ddf085de29558b516fc43c73ee5ee2aadb"}, + {file = "orjson-3.10.14-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:deaa2899dff7f03ab667e2ec25842d233e2a6a9e333efa484dfe666403f3501c"}, + {file = "orjson-3.10.14-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f1c3ea52642c9714dc6e56de8a451a066f6d2707d273e07fe8a9cc1ba073813d"}, + {file = "orjson-3.10.14-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:9d3f9ed72e7458ded9a1fb1b4d4ed4c4fdbaf82030ce3f9274b4dc1bff7ace2b"}, + {file = "orjson-3.10.14-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:07520685d408a2aba514c17ccc16199ff2934f9f9e28501e676c557f454a37fe"}, + {file = "orjson-3.10.14-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:76344269b550ea01488d19a2a369ab572c1ac4449a72e9f6ac0d70eb1cbfb953"}, + {file = "orjson-3.10.14-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:e2979d0f2959990620f7e62da6cd954e4620ee815539bc57a8ae46e2dacf90e3"}, + {file = "orjson-3.10.14-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:03f61ca3674555adcb1aa717b9fc87ae936aa7a63f6aba90a474a88701278780"}, + {file = "orjson-3.10.14-cp312-cp312-win32.whl", hash = "sha256:d5075c54edf1d6ad81d4c6523ce54a748ba1208b542e54b97d8a882ecd810fd1"}, + {file = "orjson-3.10.14-cp312-cp312-win_amd64.whl", hash = "sha256:175cafd322e458603e8ce73510a068d16b6e6f389c13f69bf16de0e843d7d406"}, + {file = "orjson-3.10.14.tar.gz", hash = "sha256:cf31f6f071a6b8e7aa1ead1fa27b935b48d00fbfa6a28ce856cfff2d5dd68eed"}, ] [[package]] @@ -779,23 +776,23 @@ files = [ [[package]] name = "pydantic" -version = "2.10.3" +version = "2.10.5" requires_python = ">=3.8" summary = "Data validation using Python type hints" groups = ["default"] dependencies = [ "annotated-types>=0.6.0", - "pydantic-core==2.27.1", + "pydantic-core==2.27.2", "typing-extensions>=4.12.2", ] files = [ - {file = "pydantic-2.10.3-py3-none-any.whl", hash = "sha256:be04d85bbc7b65651c5f8e6b9976ed9c6f41782a55524cef079a34a0bb82144d"}, - {file = "pydantic-2.10.3.tar.gz", hash = "sha256:cb5ac360ce894ceacd69c403187900a02c4b20b693a9dd1d643e1effab9eadf9"}, + {file = "pydantic-2.10.5-py3-none-any.whl", hash = "sha256:4dd4e322dbe55472cb7ca7e73f4b63574eecccf2835ffa2af9021ce113c83c53"}, + {file = "pydantic-2.10.5.tar.gz", hash = "sha256:278b38dbbaec562011d659ee05f63346951b3a248a6f3642e1bc68894ea2b4ff"}, ] [[package]] name = "pydantic-core" -version = "2.27.1" +version = "2.27.2" requires_python = ">=3.8" summary = "Core functionality for Pydantic validation and serialization" groups = ["default"] @@ -803,21 +800,21 @@ dependencies = [ "typing-extensions!=4.7.0,>=4.6.0", ] files = [ - {file = "pydantic_core-2.27.1-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:9cbd94fc661d2bab2bc702cddd2d3370bbdcc4cd0f8f57488a81bcce90c7a54f"}, - {file = "pydantic_core-2.27.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:5f8c4718cd44ec1580e180cb739713ecda2bdee1341084c1467802a417fe0f02"}, - {file = "pydantic_core-2.27.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:15aae984e46de8d376df515f00450d1522077254ef6b7ce189b38ecee7c9677c"}, - {file = "pydantic_core-2.27.1-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:1ba5e3963344ff25fc8c40da90f44b0afca8cfd89d12964feb79ac1411a260ac"}, - {file = "pydantic_core-2.27.1-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:992cea5f4f3b29d6b4f7f1726ed8ee46c8331c6b4eed6db5b40134c6fe1768bb"}, - {file = "pydantic_core-2.27.1-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:0325336f348dbee6550d129b1627cb8f5351a9dc91aad141ffb96d4937bd9529"}, - {file = "pydantic_core-2.27.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7597c07fbd11515f654d6ece3d0e4e5093edc30a436c63142d9a4b8e22f19c35"}, - {file = "pydantic_core-2.27.1-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:3bbd5d8cc692616d5ef6fbbbd50dbec142c7e6ad9beb66b78a96e9c16729b089"}, - {file = "pydantic_core-2.27.1-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:dc61505e73298a84a2f317255fcc72b710b72980f3a1f670447a21efc88f8381"}, - {file = "pydantic_core-2.27.1-cp312-cp312-musllinux_1_1_armv7l.whl", hash = "sha256:e1f735dc43da318cad19b4173dd1ffce1d84aafd6c9b782b3abc04a0d5a6f5bb"}, - {file = "pydantic_core-2.27.1-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:f4e5658dbffe8843a0f12366a4c2d1c316dbe09bb4dfbdc9d2d9cd6031de8aae"}, - {file = "pydantic_core-2.27.1-cp312-none-win32.whl", hash = "sha256:672ebbe820bb37988c4d136eca2652ee114992d5d41c7e4858cdd90ea94ffe5c"}, - {file = "pydantic_core-2.27.1-cp312-none-win_amd64.whl", hash = "sha256:66ff044fd0bb1768688aecbe28b6190f6e799349221fb0de0e6f4048eca14c16"}, - {file = "pydantic_core-2.27.1-cp312-none-win_arm64.whl", hash = "sha256:9a3b0793b1bbfd4146304e23d90045f2a9b5fd5823aa682665fbdaf2a6c28f3e"}, - {file = "pydantic_core-2.27.1.tar.gz", hash = "sha256:62a763352879b84aa31058fc931884055fd75089cccbd9d58bb6afd01141b235"}, + {file = "pydantic_core-2.27.2-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:9e0c8cfefa0ef83b4da9588448b6d8d2a2bf1a53c3f1ae5fca39eb3061e2f0b0"}, + {file = "pydantic_core-2.27.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:83097677b8e3bd7eaa6775720ec8e0405f1575015a463285a92bfdfe254529ef"}, + {file = "pydantic_core-2.27.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:172fce187655fece0c90d90a678424b013f8fbb0ca8b036ac266749c09438cb7"}, + {file = "pydantic_core-2.27.2-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:519f29f5213271eeeeb3093f662ba2fd512b91c5f188f3bb7b27bc5973816934"}, + {file = "pydantic_core-2.27.2-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:05e3a55d124407fffba0dd6b0c0cd056d10e983ceb4e5dbd10dda135c31071d6"}, + {file = "pydantic_core-2.27.2-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:9c3ed807c7b91de05e63930188f19e921d1fe90de6b4f5cd43ee7fcc3525cb8c"}, + {file = "pydantic_core-2.27.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6fb4aadc0b9a0c063206846d603b92030eb6f03069151a625667f982887153e2"}, + {file = "pydantic_core-2.27.2-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:28ccb213807e037460326424ceb8b5245acb88f32f3d2777427476e1b32c48c4"}, + {file = "pydantic_core-2.27.2-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:de3cd1899e2c279b140adde9357c4495ed9d47131b4a4eaff9052f23398076b3"}, + {file = "pydantic_core-2.27.2-cp312-cp312-musllinux_1_1_armv7l.whl", hash = "sha256:220f892729375e2d736b97d0e51466252ad84c51857d4d15f5e9692f9ef12be4"}, + {file = "pydantic_core-2.27.2-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:a0fcd29cd6b4e74fe8ddd2c90330fd8edf2e30cb52acda47f06dd615ae72da57"}, + {file = "pydantic_core-2.27.2-cp312-cp312-win32.whl", hash = "sha256:1e2cb691ed9834cd6a8be61228471d0a503731abfb42f82458ff27be7b2186fc"}, + {file = "pydantic_core-2.27.2-cp312-cp312-win_amd64.whl", hash = "sha256:cc3f1a99a4f4f9dd1de4fe0312c114e740b5ddead65bb4102884b384c15d8bc9"}, + {file = "pydantic_core-2.27.2-cp312-cp312-win_arm64.whl", hash = "sha256:3911ac9284cd8a1792d3cb26a2da18f3ca26c6908cc434a18f730dc0db7bfa3b"}, + {file = "pydantic_core-2.27.2.tar.gz", hash = "sha256:eb026e5a4c1fee05726072337ff51d1efb6f59090b7da90d30ea58625b1ffb39"}, ] [[package]] @@ -904,26 +901,26 @@ files = [ [[package]] name = "quart" -version = "0.19.9" -requires_python = ">=3.8" -summary = "A Python ASGI web microframework with the same API as Flask" +version = "0.20.0" +requires_python = ">=3.9" +summary = "A Python ASGI web framework with the same API as Flask" groups = ["default"] dependencies = [ "aiofiles", "blinker>=1.6", - "click>=8.0.0", - "flask>=3.0.0", + "click>=8.0", + "flask>=3.0", "hypercorn>=0.11.2", "importlib-metadata; python_version < \"3.10\"", "itsdangerous", "jinja2", "markupsafe", "typing-extensions; python_version < \"3.10\"", - "werkzeug>=3.0.0", + "werkzeug>=3.0", ] files = [ - {file = "quart-0.19.9-py3-none-any.whl", hash = "sha256:8acb8b299c72b66ee9e506ae141498bbbfcc250b5298fbdb712e97f3d7e4082f"}, - {file = "quart-0.19.9.tar.gz", hash = "sha256:30a61a0d7bae1ee13e6e99dc14c929b3c945e372b9445d92d21db053e91e95a5"}, + {file = "quart-0.20.0-py3-none-any.whl", hash = "sha256:003c08f551746710acb757de49d9b768986fd431517d0eb127380b656b98b8f1"}, + {file = "quart-0.20.0.tar.gz", hash = "sha256:08793c206ff832483586f5ae47018c7e40bdd75d886fee3fabbdaa70c2cf505d"}, ] [[package]] @@ -942,29 +939,29 @@ files = [ [[package]] name = "ruff" -version = "0.8.2" +version = "0.9.1" requires_python = ">=3.7" summary = "An extremely fast Python linter and code formatter, written in Rust." groups = ["dev"] files = [ - {file = "ruff-0.8.2-py3-none-linux_armv6l.whl", hash = "sha256:c49ab4da37e7c457105aadfd2725e24305ff9bc908487a9bf8d548c6dad8bb3d"}, - {file = "ruff-0.8.2-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:ec016beb69ac16be416c435828be702ee694c0d722505f9c1f35e1b9c0cc1bf5"}, - {file = "ruff-0.8.2-py3-none-macosx_11_0_arm64.whl", hash = "sha256:f05cdf8d050b30e2ba55c9b09330b51f9f97d36d4673213679b965d25a785f3c"}, - {file = "ruff-0.8.2-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:60f578c11feb1d3d257b2fb043ddb47501ab4816e7e221fbb0077f0d5d4e7b6f"}, - {file = "ruff-0.8.2-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:cbd5cf9b0ae8f30eebc7b360171bd50f59ab29d39f06a670b3e4501a36ba5897"}, - {file = "ruff-0.8.2-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b402ddee3d777683de60ff76da801fa7e5e8a71038f57ee53e903afbcefdaa58"}, - {file = "ruff-0.8.2-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:705832cd7d85605cb7858d8a13d75993c8f3ef1397b0831289109e953d833d29"}, - {file = "ruff-0.8.2-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:32096b41aaf7a5cc095fa45b4167b890e4c8d3fd217603f3634c92a541de7248"}, - {file = "ruff-0.8.2-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e769083da9439508833cfc7c23e351e1809e67f47c50248250ce1ac52c21fb93"}, - {file = "ruff-0.8.2-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5fe716592ae8a376c2673fdfc1f5c0c193a6d0411f90a496863c99cd9e2ae25d"}, - {file = "ruff-0.8.2-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:81c148825277e737493242b44c5388a300584d73d5774defa9245aaef55448b0"}, - {file = "ruff-0.8.2-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:d261d7850c8367704874847d95febc698a950bf061c9475d4a8b7689adc4f7fa"}, - {file = "ruff-0.8.2-py3-none-musllinux_1_2_i686.whl", hash = "sha256:1ca4e3a87496dc07d2427b7dd7ffa88a1e597c28dad65ae6433ecb9f2e4f022f"}, - {file = "ruff-0.8.2-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:729850feed82ef2440aa27946ab39c18cb4a8889c1128a6d589ffa028ddcfc22"}, - {file = "ruff-0.8.2-py3-none-win32.whl", hash = "sha256:ac42caaa0411d6a7d9594363294416e0e48fc1279e1b0e948391695db2b3d5b1"}, - {file = "ruff-0.8.2-py3-none-win_amd64.whl", hash = "sha256:2aae99ec70abf43372612a838d97bfe77d45146254568d94926e8ed5bbb409ea"}, - {file = "ruff-0.8.2-py3-none-win_arm64.whl", hash = "sha256:fb88e2a506b70cfbc2de6fae6681c4f944f7dd5f2fe87233a7233d888bad73e8"}, - {file = "ruff-0.8.2.tar.gz", hash = "sha256:b84f4f414dda8ac7f75075c1fa0b905ac0ff25361f42e6d5da681a465e0f78e5"}, + {file = "ruff-0.9.1-py3-none-linux_armv6l.whl", hash = "sha256:84330dda7abcc270e6055551aca93fdde1b0685fc4fd358f26410f9349cf1743"}, + {file = "ruff-0.9.1-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:3cae39ba5d137054b0e5b472aee3b78a7c884e61591b100aeb544bcd1fc38d4f"}, + {file = "ruff-0.9.1-py3-none-macosx_11_0_arm64.whl", hash = "sha256:50c647ff96f4ba288db0ad87048257753733763b409b2faf2ea78b45c8bb7fcb"}, + {file = "ruff-0.9.1-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f0c8b149e9c7353cace7d698e1656ffcf1e36e50f8ea3b5d5f7f87ff9986a7ca"}, + {file = "ruff-0.9.1-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:beb3298604540c884d8b282fe7625651378e1986c25df51dec5b2f60cafc31ce"}, + {file = "ruff-0.9.1-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:39d0174ccc45c439093971cc06ed3ac4dc545f5e8bdacf9f067adf879544d969"}, + {file = "ruff-0.9.1-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:69572926c0f0c9912288915214ca9b2809525ea263603370b9e00bed2ba56dbd"}, + {file = "ruff-0.9.1-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:937267afce0c9170d6d29f01fcd1f4378172dec6760a9f4dface48cdabf9610a"}, + {file = "ruff-0.9.1-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:186c2313de946f2c22bdf5954b8dd083e124bcfb685732cfb0beae0c47233d9b"}, + {file = "ruff-0.9.1-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3f94942a3bb767675d9a051867c036655fe9f6c8a491539156a6f7e6b5f31831"}, + {file = "ruff-0.9.1-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:728d791b769cc28c05f12c280f99e8896932e9833fef1dd8756a6af2261fd1ab"}, + {file = "ruff-0.9.1-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:2f312c86fb40c5c02b44a29a750ee3b21002bd813b5233facdaf63a51d9a85e1"}, + {file = "ruff-0.9.1-py3-none-musllinux_1_2_i686.whl", hash = "sha256:ae017c3a29bee341ba584f3823f805abbe5fe9cd97f87ed07ecbf533c4c88366"}, + {file = "ruff-0.9.1-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:5dc40a378a0e21b4cfe2b8a0f1812a6572fc7b230ef12cd9fac9161aa91d807f"}, + {file = "ruff-0.9.1-py3-none-win32.whl", hash = "sha256:46ebf5cc106cf7e7378ca3c28ce4293b61b449cd121b98699be727d40b79ba72"}, + {file = "ruff-0.9.1-py3-none-win_amd64.whl", hash = "sha256:342a824b46ddbcdddd3abfbb332fa7fcaac5488bf18073e841236aadf4ad5c19"}, + {file = "ruff-0.9.1-py3-none-win_arm64.whl", hash = "sha256:1cd76c7f9c679e6e8f2af8f778367dca82b95009bc7b1a85a47f1521ae524fa7"}, + {file = "ruff-0.9.1.tar.gz", hash = "sha256:fd2b25ecaf907d6458fa842675382c8597b3c746a2dde6717fe3415425df0c17"}, ] [[package]] @@ -1086,35 +1083,35 @@ files = [ [[package]] name = "urllib3" -version = "2.2.3" -requires_python = ">=3.8" +version = "2.3.0" +requires_python = ">=3.9" summary = "HTTP library with thread-safe connection pooling, file post, and more." groups = ["default"] files = [ - {file = "urllib3-2.2.3-py3-none-any.whl", hash = "sha256:ca899ca043dcb1bafa3e262d73aa25c465bfb49e0bd9dd5d59f1d0acba2f8fac"}, - {file = "urllib3-2.2.3.tar.gz", hash = "sha256:e7d814a81dad81e6caf2ec9fdedb284ecc9c73076b62654547cc64ccdcae26e9"}, + {file = "urllib3-2.3.0-py3-none-any.whl", hash = "sha256:1cee9ad369867bfdbbb48b7dd50374c0967a0bb7710050facf0dd6911440e3df"}, + {file = "urllib3-2.3.0.tar.gz", hash = "sha256:f8c5449b3cf0861679ce7e0503c7b44b5ec981bec0d1d3795a07f1ba96f0204d"}, ] [[package]] name = "websockets" -version = "13.1" -requires_python = ">=3.8" +version = "14.1" +requires_python = ">=3.9" summary = "An implementation of the WebSocket Protocol (RFC 6455 & 7692)" groups = ["dev"] files = [ - {file = "websockets-13.1-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:9d75baf00138f80b48f1eac72ad1535aac0b6461265a0bcad391fc5aba875cfc"}, - {file = "websockets-13.1-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:9b6f347deb3dcfbfde1c20baa21c2ac0751afaa73e64e5b693bb2b848efeaa49"}, - {file = "websockets-13.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:de58647e3f9c42f13f90ac7e5f58900c80a39019848c5547bc691693098ae1bd"}, - {file = "websockets-13.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a1b54689e38d1279a51d11e3467dd2f3a50f5f2e879012ce8f2d6943f00e83f0"}, - {file = "websockets-13.1-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:cf1781ef73c073e6b0f90af841aaf98501f975d306bbf6221683dd594ccc52b6"}, - {file = "websockets-13.1-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8d23b88b9388ed85c6faf0e74d8dec4f4d3baf3ecf20a65a47b836d56260d4b9"}, - {file = "websockets-13.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:3c78383585f47ccb0fcf186dcb8a43f5438bd7d8f47d69e0b56f71bf431a0a68"}, - {file = "websockets-13.1-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:d6d300f8ec35c24025ceb9b9019ae9040c1ab2f01cddc2bcc0b518af31c75c14"}, - {file = "websockets-13.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:a9dcaf8b0cc72a392760bb8755922c03e17a5a54e08cca58e8b74f6902b433cf"}, - {file = "websockets-13.1-cp312-cp312-win32.whl", hash = "sha256:2f85cf4f2a1ba8f602298a853cec8526c2ca42a9a4b947ec236eaedb8f2dc80c"}, - {file = "websockets-13.1-cp312-cp312-win_amd64.whl", hash = "sha256:38377f8b0cdeee97c552d20cf1865695fcd56aba155ad1b4ca8779a5b6ef4ac3"}, - {file = "websockets-13.1-py3-none-any.whl", hash = "sha256:a9a396a6ad26130cdae92ae10c36af09d9bfe6cafe69670fd3b6da9b07b4044f"}, - {file = "websockets-13.1.tar.gz", hash = "sha256:a3b3366087c1bc0a2795111edcadddb8b3b59509d5db5d7ea3fdd69f954a8878"}, + {file = "websockets-14.1-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:ed907449fe5e021933e46a3e65d651f641975a768d0649fee59f10c2985529ed"}, + {file = "websockets-14.1-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:87e31011b5c14a33b29f17eb48932e63e1dcd3fa31d72209848652310d3d1f0d"}, + {file = "websockets-14.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:bc6ccf7d54c02ae47a48ddf9414c54d48af9c01076a2e1023e3b486b6e72c707"}, + {file = "websockets-14.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9777564c0a72a1d457f0848977a1cbe15cfa75fa2f67ce267441e465717dcf1a"}, + {file = "websockets-14.1-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a655bde548ca98f55b43711b0ceefd2a88a71af6350b0c168aa77562104f3f45"}, + {file = "websockets-14.1-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a3dfff83ca578cada2d19e665e9c8368e1598d4e787422a460ec70e531dbdd58"}, + {file = "websockets-14.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:6a6c9bcf7cdc0fd41cc7b7944447982e8acfd9f0d560ea6d6845428ed0562058"}, + {file = "websockets-14.1-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:4b6caec8576e760f2c7dd878ba817653144d5f369200b6ddf9771d64385b84d4"}, + {file = "websockets-14.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:eb6d38971c800ff02e4a6afd791bbe3b923a9a57ca9aeab7314c21c84bf9ff05"}, + {file = "websockets-14.1-cp312-cp312-win32.whl", hash = "sha256:1d045cbe1358d76b24d5e20e7b1878efe578d9897a25c24e6006eef788c0fdf0"}, + {file = "websockets-14.1-cp312-cp312-win_amd64.whl", hash = "sha256:90f4c7a069c733d95c308380aae314f2cb45bd8a904fb03eb36d1a4983a4993f"}, + {file = "websockets-14.1-py3-none-any.whl", hash = "sha256:4d4fc827a20abe6d544a119896f6b78ee13fe81cbfef416f3f2ddf09a03f0e2e"}, + {file = "websockets-14.1.tar.gz", hash = "sha256:398b10c77d471c0aab20a845e7a60076b6390bfdaac7a6d2edb0d2c59d75e8d8"}, ] [[package]] @@ -1133,22 +1130,23 @@ files = [ [[package]] name = "wrapt" -version = "1.17.0" +version = "1.17.1" requires_python = ">=3.8" summary = "Module for decorators, wrappers and monkey patching." groups = ["dev"] files = [ - {file = "wrapt-1.17.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:89fc28495896097622c3fc238915c79365dd0ede02f9a82ce436b13bd0ab7569"}, - {file = "wrapt-1.17.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:875d240fdbdbe9e11f9831901fb8719da0bd4e6131f83aa9f69b96d18fae7504"}, - {file = "wrapt-1.17.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e5ed16d95fd142e9c72b6c10b06514ad30e846a0d0917ab406186541fe68b451"}, - {file = "wrapt-1.17.0-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:18b956061b8db634120b58f668592a772e87e2e78bc1f6a906cfcaa0cc7991c1"}, - {file = "wrapt-1.17.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:daba396199399ccabafbfc509037ac635a6bc18510ad1add8fd16d4739cdd106"}, - {file = "wrapt-1.17.0-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:4d63f4d446e10ad19ed01188d6c1e1bb134cde8c18b0aa2acfd973d41fcc5ada"}, - {file = "wrapt-1.17.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:8a5e7cc39a45fc430af1aefc4d77ee6bad72c5bcdb1322cfde852c15192b8bd4"}, - {file = "wrapt-1.17.0-cp312-cp312-win32.whl", hash = "sha256:0a0a1a1ec28b641f2a3a2c35cbe86c00051c04fffcfcc577ffcdd707df3f8635"}, - {file = "wrapt-1.17.0-cp312-cp312-win_amd64.whl", hash = "sha256:3c34f6896a01b84bab196f7119770fd8466c8ae3dfa73c59c0bb281e7b588ce7"}, - {file = "wrapt-1.17.0-py3-none-any.whl", hash = "sha256:d2c63b93548eda58abf5188e505ffed0229bf675f7c3090f8e36ad55b8cbc371"}, - {file = "wrapt-1.17.0.tar.gz", hash = "sha256:16187aa2317c731170a88ef35e8937ae0f533c402872c1ee5e6d079fcf320801"}, + {file = "wrapt-1.17.1-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:b1a4c8edd038fee0ce67bf119b16eaa45d22a52bbaf7d0a17d2312eb0003b1bb"}, + {file = "wrapt-1.17.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:181a844005c9818792212a32e004cb4c6bd8e35cae8e97b1a39a1918d95cef58"}, + {file = "wrapt-1.17.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:21ffcf16f5c243a626b0f8da637948e3d5984e3bc0c1bc500ad990e88e974e3b"}, + {file = "wrapt-1.17.1-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0eb33799b7582bb73787b9903b70595f8eff67eecc9455f668ed01adf53f9eea"}, + {file = "wrapt-1.17.1-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:57e932ad1908b53e9ad67a746432f02bc8473a9ee16e26a47645a2b224fba5fd"}, + {file = "wrapt-1.17.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:b8bd35c15bc82c5cbe397e8196fa57a17ce5d3f30e925a6fd39e4c5bb02fdcff"}, + {file = "wrapt-1.17.1-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:93018dbb956e0ad99ea2fa2c3c22f033549dcb1f56ad9f4555dfe25e49688c5d"}, + {file = "wrapt-1.17.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:e5bd9186d52cf3d36bf1823be0e85297e4dbad909bc6dd495ce0d272806d84a7"}, + {file = "wrapt-1.17.1-cp312-cp312-win32.whl", hash = "sha256:d609f0ab0603bbcbf2de906b366b9f9bec75c32b4493550a940de658cc2ce512"}, + {file = "wrapt-1.17.1-cp312-cp312-win_amd64.whl", hash = "sha256:2c160bb8815787646b27a0c8575a26a4d6bf6abd7c5eb250ad3f2d38b29cb2cb"}, + {file = "wrapt-1.17.1-py3-none-any.whl", hash = "sha256:f3117feb1fc479eaf84b549d3f229d5d2abdb823f003bc2a1c6dd70072912fa0"}, + {file = "wrapt-1.17.1.tar.gz", hash = "sha256:16b2fdfa09a74a3930175b6d9d7d008022aa72a4f02de2b3eecafcc1adfd3cfe"}, ] [[package]] diff --git a/requirements.txt b/requirements.txt index e8f3d8d..b82fbd6 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,6 +1,9 @@ # This file is @generated by PDM. # Please do not edit it manually. +aerich[toml]==0.8.1 \ + --hash=sha256:1e95b1c04dfc0c634dd43b0123933038c820140e17a4b27885a63b7461eb0632 \ + --hash=sha256:2743cf85bd9957ea173055dad07ee5a3219067e4f117d5402a44204c27e83c9f aiocache[redis]==0.12.3 \ --hash=sha256:889086fc24710f431937b87ad3720a289f7fc31c4fd8b68e9f918b9bacd8270d \ --hash=sha256:f528b27bf4d436b497a1d0d1a8f59a542c153ab1e37c3621713cb376d44c4713 @@ -13,52 +16,75 @@ aiofiles==24.1.0 \ aiohappyeyeballs==2.4.4 \ --hash=sha256:5fdd7d87889c63183afc18ce9271f9b0a7d32c2303e394468dd45d514a757745 \ --hash=sha256:a980909d50efcd44795c4afeca523296716d50cd756ddca6af8c65b996e27de8 -aiohttp==3.11.10 \ - --hash=sha256:012f176945af138abc10c4a48743327a92b4ca9adc7a0e078077cdb5dbab7be0 \ - --hash=sha256:06a8e2ee1cbac16fe61e51e0b0c269400e781b13bcfc33f5425912391a542985 \ - --hash=sha256:076bc454a7e6fd646bc82ea7f98296be0b1219b5e3ef8a488afbdd8e81fbac50 \ - --hash=sha256:14cdb5a9570be5a04eec2ace174a48ae85833c2aadc86de68f55541f66ce42ab \ - --hash=sha256:24213ba85a419103e641e55c27dc7ff03536c4873470c2478cce3311ba1eee7b \ - --hash=sha256:44224d815853962f48fe124748227773acd9686eba6dc102578defd6fc99e8d9 \ - --hash=sha256:482cafb7dc886bebeb6c9ba7925e03591a62ab34298ee70d3dd47ba966370d2c \ - --hash=sha256:7e97d622cb083e86f18317282084bc9fbf261801b0192c34fe4b1febd9f7ae69 \ - --hash=sha256:ab7485222db0959a87fbe8125e233b5a6f01f4400785b36e8a7878170d8c3138 \ - --hash=sha256:b1fc6b45010a8d0ff9e88f9f2418c6fd408c99c211257334aff41597ebece42e \ - --hash=sha256:b78f053a7ecfc35f0451d961dacdc671f4bcbc2f58241a7c820e9d82559844cf \ - --hash=sha256:b99acd4730ad1b196bfb03ee0803e4adac371ae8efa7e1cbc820200fc5ded109 \ - --hash=sha256:be2b516f56ea883a3e14dda17059716593526e10fb6303189aaf5503937db408 \ - --hash=sha256:bf3d1a519a324af764a46da4115bdbd566b3c73fb793ffb97f9111dbc684fc4d \ - --hash=sha256:c87bf31b7fdab94ae3adbe4a48e711bfc5f89d21cf4c197e75561def39e223bc \ - --hash=sha256:cf14627232dfa8730453752e9cdc210966490992234d77ff90bc8dc0dce361d5 -aiosignal==1.3.1 \ - --hash=sha256:54cd96e15e1649b75d6c87526a6ff0b6c1b0dd3459f43d9ca11d48c339b68cfc \ - --hash=sha256:f8376fb07dd1e86a584e4fcdec80b36b7f81aac666ebc724e2c090300dd83b17 +aiohttp==3.11.11 \ + --hash=sha256:1e69966ea6ef0c14ee53ef7a3d68b564cc408121ea56c0caa2dc918c1b2f553d \ + --hash=sha256:3499c7ffbfd9c6a3d8d6a2b01c26639da7e43d47c7b4f788016226b1e711caa8 \ + --hash=sha256:3ea1b59dc06396b0b424740a10a0a63974c725b1c64736ff788a3689d36c02d2 \ + --hash=sha256:6fba278063559acc730abf49845d0e9a9e1ba74f85f0ee6efd5803f08b285853 \ + --hash=sha256:8811f3f098a78ffa16e0ea36dffd577eb031aea797cbdba81be039a4169e242c \ + --hash=sha256:8e2bf8029dbf0810c7bfbc3e594b51c4cc9101fbffb583a3923aea184724203c \ + --hash=sha256:92fc484e34b733704ad77210c7957679c5c3877bd1e6b6d74b185e9320cc716e \ + --hash=sha256:9f5b3c1ed63c8fa937a920b6c1bec78b74ee09593b3f5b979ab2ae5ef60d7600 \ + --hash=sha256:a8f5f7515f3552d899c61202d99dcb17d6e3b0de777900405611cd747cecd1b8 \ + --hash=sha256:b6212a60e5c482ef90f2d788835387070a88d52cf6241d3916733c9176d39eab \ + --hash=sha256:bb49c7f1e6ebf3821a42d81d494f538107610c3a705987f53068546b0e90303e \ + --hash=sha256:bd7227b87a355ce1f4bf83bfae4399b1f5bb42e0259cb9405824bd03d2f4336a \ + --hash=sha256:d119fafe7b634dbfa25a8c597718e69a930e4847f0b88e172744be24515140da \ + --hash=sha256:d40f9da8cabbf295d3a9dae1295c69975b86d941bc20f0a087f0477fa0a66231 \ + --hash=sha256:e595c591a48bbc295ebf47cb91aebf9bd32f3ff76749ecf282ea7f9f6bb73886 \ + --hash=sha256:ffb3dc385f6bb1568aa974fe65da84723210e5d9707e360e9ecb51f59406cd2e +aiosignal==1.3.2 \ + --hash=sha256:45cde58e409a301715980c2b01d0c28bdde3770d8290b5eb2173759d9acb31a5 \ + --hash=sha256:a8c255c66fafb1e499c9351d0bf32ff2d8a0321595ebac3b93713656d2436f54 +aiosqlite==0.20.0 \ + --hash=sha256:36a1deaca0cac40ebe32aac9977a6e2bbc7f5189f23f4a54d5908986729e5bd6 \ + --hash=sha256:6d35c8c256637f4672f843c31021464090805bf925385ac39473fb16eaaca3d7 annotated-types==0.7.0 \ --hash=sha256:1f02e8b43a8fbbc3f3e0d4f0f4bfc8131bcb4eebe8849b8e5c773f3a1c582a53 \ --hash=sha256:aff07c09a53a08bc8cfccb9c85b05f1aa9a2a6f23728d790723543408344ce89 -attrs==24.2.0 \ - --hash=sha256:5cfb1b9148b5b086569baec03f20d7b6bf3bcacc9a42bebf87ffaaca362f6346 \ - --hash=sha256:81921eb96de3191c8258c199618104dd27ac608d9366f5e35d011eae1867ede2 +anyio==4.8.0 \ + --hash=sha256:1d9fe889df5212298c0c0723fa20479d1b94883a2df44bd3897aa91083316f7a \ + --hash=sha256:b5011f270ab5eb0abf13385f851315585cc37ef330dd88e27ec3d34d651fd47a +asyncclick==8.1.8 \ + --hash=sha256:0f0eb0f280e04919d67cf71b9fcdfb4db2d9ff7203669c40284485c149578e4c \ + --hash=sha256:be146a2d8075d4fe372ff4e877f23c8b5af269d16705c1948123b9415f6fd678 \ + --hash=sha256:eb1ccb44bc767f8f0695d592c7806fdf5bd575605b4ee246ffd5fadbcfdbd7c6 +asyncpg==0.30.0 \ + --hash=sha256:0f5712350388d0cd0615caec629ad53c81e506b1abaaf8d14c93f54b35e3595a \ + --hash=sha256:1292b84ee06ac8a2ad8e51c7475aa309245874b61333d97411aab835c4a2f737 \ + --hash=sha256:68d71a1be3d83d0570049cd1654a9bdfe506e794ecc98ad0873304a9f35e411e \ + --hash=sha256:6c2a2ef565400234a633da0eafdce27e843836256d40705d83ab7ec42074efb3 \ + --hash=sha256:9a0292c6af5c500523949155ec17b7fe01a00ace33b68a476d6b5059f9630305 \ + --hash=sha256:aca1548e43bbb9f0f627a04666fedaca23db0a31a84136ad1f868cb15deb6e3a \ + --hash=sha256:c551e9928ab6707602f44811817f82ba3c446e018bfe1d3abecc8ba5f3eac851 \ + --hash=sha256:c902a60b52e506d38d7e80e0dd5399f657220f24635fee368117b8b5fce1142e \ + --hash=sha256:db9891e2d76e6f425746c5d2da01921e9a16b5a71a1c905b13f30e12a257c4af +attrs==24.3.0 \ + --hash=sha256:8f5c07333d543103541ba7be0e2ce16eeee8130cb0b3f9238ab904ce1e85baff \ + --hash=sha256:ac96cd038792094f438ad1f6ff80837353805ac950cd2aa0e0625ef19850c308 blinker==1.9.0 \ --hash=sha256:b4ce2265a7abece45e7cc896e98dbebe6cead56bcf805a3d23136d145f5445bf \ --hash=sha256:ba0efaa9080b619ff2f3459d1d500c57bddea4a6b424b60a91141db6fd2f08bc -caio==0.9.17 \ - --hash=sha256:0ddb253b145a53ecca76381677ce465bc5efeaecb6aaf493fac43ae79659f0fb \ - --hash=sha256:8f30511526814d961aeef389ea6885273abe6c655f1e08abbadb95d12fdd9b4f \ - --hash=sha256:b3e320b0ea371c810359934f8e8fe81777c493cc5fb4d41de44277cbe7336e74 \ - --hash=sha256:c55d4dc6b3a36f93237ecd6360e1c131c3808bc47d4191a130148a99b80bb311 -certifi==2024.8.30 \ - --hash=sha256:922820b53db7a7257ffbda3f597266d435245903d80737e34f8a45ff3e3230d8 \ - --hash=sha256:bec941d2aa8195e248a60b31ff9f0558284cf01a52591ceda73ea9afffd69fd9 -click==8.1.7 \ - --hash=sha256:ae74fb96c20a0277a1d615f1e4d73c8414f5a98db8b799a7931d1582f3390c28 \ - --hash=sha256:ca9853ad459e787e2192211578cc907e7594e294c7ccc834310722b41b9ca6de +caio==0.9.19 \ + --hash=sha256:6d426f2e9fcec7b1a767b187861bd0aecae9f88bc36227331d2fb978722bed90 \ + --hash=sha256:a743fda13e194b21df922ea0cee404e2bcac72a722c469eed6bd893a0cdec1c0 \ + --hash=sha256:bdcb529330730c4c364b79789620f33bafad8c2c854c1205ecc2d16511c0b690 \ + --hash=sha256:f2bc23784f50ac8a2b5a3a0625ff181a92cbb8f4ce532d23a6be441c38deb7c8 +certifi==2024.12.14 \ + --hash=sha256:1275f7a45be9464efc1173084eaa30f866fe2e47d389406136d332ed4967ec56 \ + --hash=sha256:b650d30f370c2b724812bee08008be0c4163b163ddaec3f2546c1caf65f191db +click==8.1.8 \ + --hash=sha256:63c132bbbed01578a06712a2d1f497bb62d9c1c0d329b7903a866228027263b2 \ + --hash=sha256:ed53c9d8990d83c2a27deae68e4ee337473f6330c040a31d4225c9574d16096a colorama==0.4.6; sys_platform == "win32" or platform_system == "Windows" \ --hash=sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44 \ --hash=sha256:4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6 coloredlogs==15.0.1 \ --hash=sha256:612ee75c546f53e92e70049c9dbfcc18c935a2b9a53b66085ce9ef6a6e5c0934 \ --hash=sha256:7c991aa71a4577af2f82600d8f8f3a89f936baeaf9b50a9c197da014e5bf16b0 +dictdiffer==0.9.0 \ + --hash=sha256:17bacf5fbfe613ccf1b6d512bd766e6b21fb798822a133aa86098b8ac9997578 \ + --hash=sha256:442bfc693cfcadaf46674575d2eba1c53b42f5e404218ca2c2ff549f2df56595 flask==3.1.0 \ --hash=sha256:5f873c5184c897c8d9d1b05df1e3d01b14910ce69607a117bd3277098a5836ac \ --hash=sha256:d667207822eb83f1c4b50949b1623c8fc8d51f2341d65f72e1a1815397551136 @@ -101,12 +127,15 @@ hyperframe==6.0.1 \ idna==3.10 \ --hash=sha256:12f65c9b470abda6dc35cf8e63cc574b1c52b11df2c86030af0ac09b01b13ea9 \ --hash=sha256:946d195a0d259cbba61165e88e65941f16e9b36ea6ddb97f00452bae8b1287d3 +iso8601==2.1.0 \ + --hash=sha256:6b1d3829ee8921c4301998c909f7829fa9ed3cbdac0d3b16af2d743aed1ba8df \ + --hash=sha256:aac4145c4dcb66ad8b648a02830f5e2ff6c24af20f4f482689be402db2429242 itsdangerous==2.2.0 \ --hash=sha256:c6242fc49e35958c8b15141343aa660db5fc54d4f13a1db01a3f5891b98700ef \ --hash=sha256:e0050c0b7da1eea53ffaf149c0cfbb5c6e2e2b69c4bef22c81fa6eb73e5f6173 -jinja2==3.1.4 \ - --hash=sha256:4a3aee7acbbe7303aede8e9648d13b8bf88a429282aa6122a993f0ac800cb369 \ - --hash=sha256:bc5dd2abb727a5319567b7a813e6a2e7318c39f4f487cfe6c89c6f9c7d25197d +jinja2==3.1.5 \ + --hash=sha256:8fefff8dc3034e27bb80d67c671eb8a9bc424c0ef4c0826edbff304cceff43bb \ + --hash=sha256:aba0f4dc9ed8013c424088f68a5c226f7d6097ed89b246d7749c2ec4175c6adb markupsafe==3.0.2 \ --hash=sha256:0f4ca02bea9a23221c0182836703cbf8930c5e9454bacce27e767509fa286a30 \ --hash=sha256:1c99d261bd2d5f6b59325c92c73df481e05e57f19837bdca8413b9eac4bd8028 \ @@ -137,21 +166,21 @@ multidict==6.1.0 \ --hash=sha256:820c661588bd01a0aa62a1283f20d2be4281b086f80dad9e955e690c75fb54a2 \ --hash=sha256:b04772ed465fa3cc947db808fa306d79b43e896beb677a56fb2347ca1a49c1fa \ --hash=sha256:b58c621844d55e71c1b7f7c498ce5aa6985d743a1a59034c57a905b3f153c1ef -orjson==3.10.12 \ - --hash=sha256:0a78bbda3aea0f9f079057ee1ee8a1ecf790d4f1af88dd67493c6b8ee52506ff \ - --hash=sha256:16135ccca03445f37921fa4b585cff9a58aa8d81ebcb27622e69bfadd220b32c \ - --hash=sha256:22a51ae77680c5c4652ebc63a83d5255ac7d65582891d9424b566fb3b5375ee9 \ - --hash=sha256:24ce85f7100160936bc2116c09d1a8492639418633119a2224114f67f63a4559 \ - --hash=sha256:2d879c81172d583e34153d524fcba5d4adafbab8349a7b9f16ae511c2cee8708 \ - --hash=sha256:53206d72eb656ca5ac7d3a7141e83c5bbd3ac30d5eccfe019409177a57634b0d \ - --hash=sha256:8a76ba5fc8dd9c913640292df27bff80a685bed3a3c990d59aa6ce24c352f8fc \ - --hash=sha256:8dcb9673f108a93c1b52bfc51b0af422c2d08d4fc710ce9c839faad25020bb69 \ - --hash=sha256:910fdf2ac0637b9a77d1aad65f803bac414f0b06f720073438a7bd8906298192 \ - --hash=sha256:ac8010afc2150d417ebda810e8df08dd3f544e0dd2acab5370cfa6bcc0662f8f \ - --hash=sha256:ed459b46012ae950dd2e17150e838ab08215421487371fa79d0eced8d1461d70 \ - --hash=sha256:f4244b7018b5753ecd10a6d324ec1f347da130c953a9c88432c7fbc8875d13be \ - --hash=sha256:fc23f691fa0f5c140576b8c365bc942d577d861a9ee1142e4db468e4e17094fb \ - --hash=sha256:ff70ef093895fd53f4055ca75f93f047e088d1430888ca1229393a7c0521100f +orjson==3.10.14 \ + --hash=sha256:03f61ca3674555adcb1aa717b9fc87ae936aa7a63f6aba90a474a88701278780 \ + --hash=sha256:07520685d408a2aba514c17ccc16199ff2934f9f9e28501e676c557f454a37fe \ + --hash=sha256:175cafd322e458603e8ce73510a068d16b6e6f389c13f69bf16de0e843d7d406 \ + --hash=sha256:2ad4b7e367efba6dc3f119c9a0fcd41908b7ec0399a696f3cdea7ec477441b09 \ + --hash=sha256:76344269b550ea01488d19a2a369ab572c1ac4449a72e9f6ac0d70eb1cbfb953 \ + --hash=sha256:8cc8204f0b75606869c707da331058ddf085de29558b516fc43c73ee5ee2aadb \ + --hash=sha256:9d3f9ed72e7458ded9a1fb1b4d4ed4c4fdbaf82030ce3f9274b4dc1bff7ace2b \ + --hash=sha256:c7f189bbfcded40e41a6969c1068ba305850ba016665be71a217918931416fbf \ + --hash=sha256:cf31f6f071a6b8e7aa1ead1fa27b935b48d00fbfa6a28ce856cfff2d5dd68eed \ + --hash=sha256:d5075c54edf1d6ad81d4c6523ce54a748ba1208b542e54b97d8a882ecd810fd1 \ + --hash=sha256:deaa2899dff7f03ab667e2ec25842d233e2a6a9e333efa484dfe666403f3501c \ + --hash=sha256:e2979d0f2959990620f7e62da6cd954e4620ee815539bc57a8ae46e2dacf90e3 \ + --hash=sha256:f1c3ea52642c9714dc6e56de8a451a066f6d2707d273e07fe8a9cc1ba073813d \ + --hash=sha256:f496286fc85e93ce0f71cc84fc1c42de2decf1bf494094e188e27a53694777a7 priority==2.0.0 \ --hash=sha256:6f8eefce5f3ad59baf2c080a664037bb4725cd0a790d53d59ab4059288faf6aa \ --hash=sha256:c965d54f1b8d0d0b19479db3924c7c36cf672dbf2aec92d43fbdaf4492ba18c0 @@ -177,25 +206,28 @@ propcache==0.2.1 \ py-cord==2.6.1 \ --hash=sha256:36064f225f2c7bbddfe542d5ed581f2a5744f618e039093cf7cd2659a58bc79b \ --hash=sha256:e3d3b528c5e37b0e0825f5b884cbb9267860976c1e4878e28b55da8fd3af834b -pydantic==2.10.3 \ - --hash=sha256:be04d85bbc7b65651c5f8e6b9976ed9c6f41782a55524cef079a34a0bb82144d \ - --hash=sha256:cb5ac360ce894ceacd69c403187900a02c4b20b693a9dd1d643e1effab9eadf9 -pydantic-core==2.27.1 \ - --hash=sha256:0325336f348dbee6550d129b1627cb8f5351a9dc91aad141ffb96d4937bd9529 \ - --hash=sha256:15aae984e46de8d376df515f00450d1522077254ef6b7ce189b38ecee7c9677c \ - --hash=sha256:1ba5e3963344ff25fc8c40da90f44b0afca8cfd89d12964feb79ac1411a260ac \ - --hash=sha256:3bbd5d8cc692616d5ef6fbbbd50dbec142c7e6ad9beb66b78a96e9c16729b089 \ - --hash=sha256:5f8c4718cd44ec1580e180cb739713ecda2bdee1341084c1467802a417fe0f02 \ - --hash=sha256:62a763352879b84aa31058fc931884055fd75089cccbd9d58bb6afd01141b235 \ - --hash=sha256:66ff044fd0bb1768688aecbe28b6190f6e799349221fb0de0e6f4048eca14c16 \ - --hash=sha256:672ebbe820bb37988c4d136eca2652ee114992d5d41c7e4858cdd90ea94ffe5c \ - --hash=sha256:7597c07fbd11515f654d6ece3d0e4e5093edc30a436c63142d9a4b8e22f19c35 \ - --hash=sha256:992cea5f4f3b29d6b4f7f1726ed8ee46c8331c6b4eed6db5b40134c6fe1768bb \ - --hash=sha256:9a3b0793b1bbfd4146304e23d90045f2a9b5fd5823aa682665fbdaf2a6c28f3e \ - --hash=sha256:9cbd94fc661d2bab2bc702cddd2d3370bbdcc4cd0f8f57488a81bcce90c7a54f \ - --hash=sha256:dc61505e73298a84a2f317255fcc72b710b72980f3a1f670447a21efc88f8381 \ - --hash=sha256:e1f735dc43da318cad19b4173dd1ffce1d84aafd6c9b782b3abc04a0d5a6f5bb \ - --hash=sha256:f4e5658dbffe8843a0f12366a4c2d1c316dbe09bb4dfbdc9d2d9cd6031de8aae +pydantic==2.10.5 \ + --hash=sha256:278b38dbbaec562011d659ee05f63346951b3a248a6f3642e1bc68894ea2b4ff \ + --hash=sha256:4dd4e322dbe55472cb7ca7e73f4b63574eecccf2835ffa2af9021ce113c83c53 +pydantic-core==2.27.2 \ + --hash=sha256:05e3a55d124407fffba0dd6b0c0cd056d10e983ceb4e5dbd10dda135c31071d6 \ + --hash=sha256:172fce187655fece0c90d90a678424b013f8fbb0ca8b036ac266749c09438cb7 \ + --hash=sha256:1e2cb691ed9834cd6a8be61228471d0a503731abfb42f82458ff27be7b2186fc \ + --hash=sha256:220f892729375e2d736b97d0e51466252ad84c51857d4d15f5e9692f9ef12be4 \ + --hash=sha256:28ccb213807e037460326424ceb8b5245acb88f32f3d2777427476e1b32c48c4 \ + --hash=sha256:3911ac9284cd8a1792d3cb26a2da18f3ca26c6908cc434a18f730dc0db7bfa3b \ + --hash=sha256:519f29f5213271eeeeb3093f662ba2fd512b91c5f188f3bb7b27bc5973816934 \ + --hash=sha256:6fb4aadc0b9a0c063206846d603b92030eb6f03069151a625667f982887153e2 \ + --hash=sha256:83097677b8e3bd7eaa6775720ec8e0405f1575015a463285a92bfdfe254529ef \ + --hash=sha256:9c3ed807c7b91de05e63930188f19e921d1fe90de6b4f5cd43ee7fcc3525cb8c \ + --hash=sha256:9e0c8cfefa0ef83b4da9588448b6d8d2a2bf1a53c3f1ae5fca39eb3061e2f0b0 \ + --hash=sha256:a0fcd29cd6b4e74fe8ddd2c90330fd8edf2e30cb52acda47f06dd615ae72da57 \ + --hash=sha256:cc3f1a99a4f4f9dd1de4fe0312c114e740b5ddead65bb4102884b384c15d8bc9 \ + --hash=sha256:de3cd1899e2c279b140adde9357c4495ed9d47131b4a4eaff9052f23398076b3 \ + --hash=sha256:eb026e5a4c1fee05726072337ff51d1efb6f59090b7da90d30ea58625b1ffb39 +pypika-tortoise==0.3.2 \ + --hash=sha256:c5c52bc4473fe6f3db36cf659340750246ec5dd0f980d04ae7811430e299c3a2 \ + --hash=sha256:f5d508e2ef00255e52ec6ac79ef889e10dbab328f218c55cd134c4d02ff9f6f4 pyreadline3==3.5.4; sys_platform == "win32" and python_version >= "3.8" \ --hash=sha256:8d57d53039a1c75adba8e50dd3d992b28143480816187ea5efbd5c78e6c885b7 \ --hash=sha256:eaf8e6cc3c49bcccf145fc6067ba8643d1df34d604a1ec0eccbf7a18e6d3fae6 @@ -216,9 +248,9 @@ pyyaml==6.0.2 \ --hash=sha256:ce826d6ef20b1bc864f0a68340c8b3287705cae2f8b4b1d932177dcc76721725 \ --hash=sha256:d584d9ec91ad65861cc08d42e834324ef890a082e591037abe114850ff7bbc3e \ --hash=sha256:ef6107725bd54b262d6dedcc2af448a266975032bc85ef0172c5f059da6325b4 -quart==0.19.9 \ - --hash=sha256:30a61a0d7bae1ee13e6e99dc14c929b3c945e372b9445d92d21db053e91e95a5 \ - --hash=sha256:8acb8b299c72b66ee9e506ae141498bbbfcc250b5298fbdb712e97f3d7e4082f +quart==0.20.0 \ + --hash=sha256:003c08f551746710acb757de49d9b768986fd431517d0eb127380b656b98b8f1 \ + --hash=sha256:08793c206ff832483586f5ae47018c7e40bdd75d886fee3fabbdaa70c2cf505d redis==5.2.1 \ --hash=sha256:16f2e22dff21d5125e8481515e386711a34cbec50f0e44413dd7d9c060a54e0f \ --hash=sha256:ee7e1056b9aea0f04c6c2ed59452947f34c4940ee025f5dd83e6a6418b6989e4 @@ -228,12 +260,21 @@ schema==0.7.7 \ sentry-sdk==2.19.2 \ --hash=sha256:467df6e126ba242d39952375dd816fbee0f217d119bf454a8ce74cf1e7909e8d \ --hash=sha256:ebdc08228b4d131128e568d696c210d846e5b9d70aa0327dec6b1272d9d40b84 +sniffio==1.3.1 \ + --hash=sha256:2f6da418d1f1e0fddd844478f41680e794e6051915791a034ff65e5f100525a2 \ + --hash=sha256:f4324edc670a0f49750a81b895f35c3adb843cca46f0530f79fc1babb23789dc +tomli-w==1.1.0; python_version >= "3.11" \ + --hash=sha256:1403179c78193e3184bfaade390ddbd071cba48a32a2e62ba11aae47490c63f7 \ + --hash=sha256:49e847a3a304d516a169a601184932ef0f6b61623fe680f836a2aa7128ed0d33 +tortoise-orm[asyncpg]==0.23.0 \ + --hash=sha256:deaabed1619ea8aab6213508dff025571a701b7f34ee534473d7bb7661aa9f4f \ + --hash=sha256:f25d431ef4fb521a84edad582f4b9c53dccc5abf6cfbc6f228cbece5a13952fa typing-extensions==4.12.2 \ --hash=sha256:04e5ca0351e0f3f85c6853954072df659d0d13fac324d0072316b67d7794700d \ --hash=sha256:1a7ead55c7e559dd4dee8856e3a88b41225abfe1ce8df57b7c13915fe121ffb8 -urllib3==2.2.3 \ - --hash=sha256:ca899ca043dcb1bafa3e262d73aa25c465bfb49e0bd9dd5d59f1d0acba2f8fac \ - --hash=sha256:e7d814a81dad81e6caf2ec9fdedb284ecc9c73076b62654547cc64ccdcae26e9 +urllib3==2.3.0 \ + --hash=sha256:1cee9ad369867bfdbbb48b7dd50374c0967a0bb7710050facf0dd6911440e3df \ + --hash=sha256:f8c5449b3cf0861679ce7e0503c7b44b5ec981bec0d1d3795a07f1ba96f0204d werkzeug==3.1.3 \ --hash=sha256:54b78bf3716d19a65be4fceccc0d1d7b89e608834989dfae50ea87564639213e \ --hash=sha256:60723ce945c19328679790e3282cc758aa4a6040e4bb330f53d30fa546d44746 From 1fa54efeb40c637b099d9d725b2f55b5c155b8d1 Mon Sep 17 00:00:00 2001 From: Paillat Date: Tue, 28 Jan 2025 19:22:02 +0100 Subject: [PATCH 49/61] =?UTF-8?q?=E2=9C=8F=20Python=203.12=20not=203.11?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- readme.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/readme.md b/readme.md index 2512ee7..1044ac4 100644 --- a/readme.md +++ b/readme.md @@ -52,7 +52,7 @@ to leverage its powerful features to create truly unique and capable bots. - [pdm](https://pdm-project.org/en/latest/) - A modern Python packaging and dependency management tool. -- Python 3.11 +- Python 3.12 - A Discord bot. You can create a new bot and get a token from the [Discord Developer Portal](https://discord.com/developers/applications). From 56504776e1848dd47926327023e37bf001c7782e Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Tue, 28 Jan 2025 19:26:25 +0100 Subject: [PATCH 50/61] Update dependencies (#73) Co-authored-by: github-actions --- pdm.lock | 234 ++++++++++++++++++++++++----------------------- requirements.txt | 88 +++++++++--------- 2 files changed, 162 insertions(+), 160 deletions(-) diff --git a/pdm.lock b/pdm.lock index 8740112..5cc9e57 100644 --- a/pdm.lock +++ b/pdm.lock @@ -238,18 +238,18 @@ files = [ [[package]] name = "attrs" -version = "24.3.0" +version = "25.1.0" requires_python = ">=3.8" summary = "Classes Without Boilerplate" groups = ["default"] files = [ - {file = "attrs-24.3.0-py3-none-any.whl", hash = "sha256:ac96cd038792094f438ad1f6ff80837353805ac950cd2aa0e0625ef19850c308"}, - {file = "attrs-24.3.0.tar.gz", hash = "sha256:8f5c07333d543103541ba7be0e2ce16eeee8130cb0b3f9238ab904ce1e85baff"}, + {file = "attrs-25.1.0-py3-none-any.whl", hash = "sha256:c75a69e28a550a7e93789579c22aa26b0f5b83b75dc4e08fe092980051e1090a"}, + {file = "attrs-25.1.0.tar.gz", hash = "sha256:1c97078a80c814273a76b2a298a932eb681c87415c11dee0a6921de7f1b02c3e"}, ] [[package]] name = "basedpyright" -version = "1.23.2" +version = "1.24.0" requires_python = ">=3.8" summary = "static type checking for Python (but based)" groups = ["dev"] @@ -257,8 +257,8 @@ dependencies = [ "nodejs-wheel-binaries>=20.13.1", ] files = [ - {file = "basedpyright-1.23.2-py3-none-any.whl", hash = "sha256:a859f035f031e6ce1d1bc43d73b4e364238c39811f9b6fcd31e886183097ea22"}, - {file = "basedpyright-1.23.2.tar.gz", hash = "sha256:367c3bef9edff8d3ba35ccfc467f2e680a4b5936697eff3d42219e58febfe3c8"}, + {file = "basedpyright-1.24.0-py3-none-any.whl", hash = "sha256:32ae77b2334dc9737c9220bcbc1aee98f76884be033bd5f4f50e5940fa16391d"}, + {file = "basedpyright-1.24.0.tar.gz", hash = "sha256:425919327db8662f1be718dafe06b1e168781f9728e59a9cf717cbb3380acec9"}, ] [[package]] @@ -288,15 +288,15 @@ files = [ [[package]] name = "caio" -version = "0.9.19" +version = "0.9.21" requires_python = "<4,>=3.7" summary = "Asynchronous file IO for Linux MacOS or Windows." groups = ["default"] files = [ - {file = "caio-0.9.19-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:6d426f2e9fcec7b1a767b187861bd0aecae9f88bc36227331d2fb978722bed90"}, - {file = "caio-0.9.19-cp312-cp312-manylinux_2_12_x86_64.manylinux2010_x86_64.manylinux_2_34_x86_64.whl", hash = "sha256:a743fda13e194b21df922ea0cee404e2bcac72a722c469eed6bd893a0cdec1c0"}, - {file = "caio-0.9.19-cp312-cp312-manylinux_2_34_aarch64.whl", hash = "sha256:f2bc23784f50ac8a2b5a3a0625ff181a92cbb8f4ce532d23a6be441c38deb7c8"}, - {file = "caio-0.9.19.tar.gz", hash = "sha256:bdcb529330730c4c364b79789620f33bafad8c2c854c1205ecc2d16511c0b690"}, + {file = "caio-0.9.21-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:e7314a28d69a0397d1d0ac6c7bfe7973f27f4f7216cf42b0358d7d9ba27bc4cd"}, + {file = "caio-0.9.21-cp312-cp312-manylinux_2_34_aarch64.whl", hash = "sha256:1f4241e2b89f31e1fea342c8da9a987fef71d093df7ba1169f469d0be7592608"}, + {file = "caio-0.9.21-cp312-cp312-manylinux_2_34_x86_64.whl", hash = "sha256:fdab8c817b6835d997db1532ce7d9f5cbe186265bf0ee9a9840b378aa4a1cba7"}, + {file = "caio-0.9.21.tar.gz", hash = "sha256:4f1d30ad0f975de07b4a3ae1cd2e9275fa574f2ca0b49ba5ab16208575650a92"}, ] [[package]] @@ -353,7 +353,7 @@ files = [ [[package]] name = "deprecated" -version = "1.2.15" +version = "1.2.17" requires_python = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,>=2.7" summary = "Python @deprecated decorator to deprecate old python classes, functions or methods." groups = ["dev"] @@ -361,8 +361,8 @@ dependencies = [ "wrapt<2,>=1.10", ] files = [ - {file = "Deprecated-1.2.15-py2.py3-none-any.whl", hash = "sha256:353bc4a8ac4bfc96800ddab349d89c25dec1079f65fd53acdcc1e0b975b21320"}, - {file = "deprecated-1.2.15.tar.gz", hash = "sha256:683e561a90de76239796e6b6feac66b99030d2dd3fcf61ef996330f14bbb9b0d"}, + {file = "Deprecated-1.2.17-py2.py3-none-any.whl", hash = "sha256:69cdc0a751671183f569495e2efb14baee4344b0236342eec29f1fde25d61818"}, + {file = "deprecated-1.2.17.tar.gz", hash = "sha256:0114a10f0bbb750b90b2c2296c90cf7e9eaeb0abb5cf06c80de2c60138de0a82"}, ] [[package]] @@ -451,13 +451,13 @@ files = [ [[package]] name = "hpack" -version = "4.0.0" -requires_python = ">=3.6.1" -summary = "Pure-Python HPACK header compression" +version = "4.1.0" +requires_python = ">=3.9" +summary = "Pure-Python HPACK header encoding" groups = ["default"] files = [ - {file = "hpack-4.0.0-py3-none-any.whl", hash = "sha256:84a076fad3dc9a9f8063ccb8041ef100867b1878b25ef0ee63847a5d53818a6c"}, - {file = "hpack-4.0.0.tar.gz", hash = "sha256:fc41de0c63e687ebffde81187a948221294896f6bdc0ae2312708df339430095"}, + {file = "hpack-4.1.0-py3-none-any.whl", hash = "sha256:157ac792668d995c657d93111f46b4535ed114f0c9c8d672271bbec7eae1b496"}, + {file = "hpack-4.1.0.tar.gz", hash = "sha256:ec5eca154f7056aa06f196a557655c5b009b382873ac8d1e66e79e87535f1dca"}, ] [[package]] @@ -499,13 +499,13 @@ files = [ [[package]] name = "hyperframe" -version = "6.0.1" -requires_python = ">=3.6.1" -summary = "HTTP/2 framing layer for Python" +version = "6.1.0" +requires_python = ">=3.9" +summary = "Pure-Python HTTP/2 framing" groups = ["default"] files = [ - {file = "hyperframe-6.0.1-py3-none-any.whl", hash = "sha256:0ec6bafd80d8ad2195c4f03aacba3a8265e57bc4cff261e802bf39970ed02a15"}, - {file = "hyperframe-6.0.1.tar.gz", hash = "sha256:ae510046231dc8e9ecb1a6586f63d2347bf4c8905914aa84ba585ae85f28a914"}, + {file = "hyperframe-6.1.0-py3-none-any.whl", hash = "sha256:b03380493a519fce58ea5af42e4a42317bf9bd425596f7a0835ffce80f1a42e5"}, + {file = "hyperframe-6.1.0.tar.gz", hash = "sha256:f630908a00854a7adeabd6382b43923a4c4cd4b821fcb527e6ab9e15382a3b08"}, ] [[package]] @@ -642,7 +642,7 @@ files = [ [[package]] name = "nodejs-wheel-binaries" -version = "22.13.0" +version = "22.13.1" requires_python = ">=3.7" summary = "unoffical Node.js package" groups = ["dev"] @@ -650,14 +650,15 @@ dependencies = [ "typing-extensions; python_version < \"3.8\"", ] files = [ - {file = "nodejs_wheel_binaries-22.13.0-py2.py3-none-macosx_11_0_arm64.whl", hash = "sha256:646ab3e65296de9c578db9a1dcfbca26386d2ead70a49008f75d02e960593b2f"}, - {file = "nodejs_wheel_binaries-22.13.0-py2.py3-none-macosx_11_0_x86_64.whl", hash = "sha256:38c689d556f428415a77655f70d2046ddbe11604039489f029b12f317042eaf4"}, - {file = "nodejs_wheel_binaries-22.13.0-py2.py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:61885cbcfff0a6d40353c8ea3d861ccb65dba7ce4b19f22427719aeeb35d42f1"}, - {file = "nodejs_wheel_binaries-22.13.0-py2.py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e358439ff830db766006e6eeb85ababb94b8c41c7325c9eb1f873a52d3df3016"}, - {file = "nodejs_wheel_binaries-22.13.0-py2.py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:1e26d39448cbb2969da10f5e62e53101591e4d6c6a6ae8d623c65f56bf28ce6b"}, - {file = "nodejs_wheel_binaries-22.13.0-py2.py3-none-win_amd64.whl", hash = "sha256:cd9c6cdfd00ec48c55cbcd21a98af1fc9c2a18f039aede729de319346ed8675d"}, - {file = "nodejs_wheel_binaries-22.13.0-py2.py3-none-win_arm64.whl", hash = "sha256:aa8af75d30c3132bc4e998126a78b11c269abc3060f1c7c697907299b21ae0e1"}, - {file = "nodejs_wheel_binaries-22.13.0.tar.gz", hash = "sha256:dd811e3e5b92f2e5d4eb236cdf1ff814c91d3d3533d90d63b4af41d07a8bb2fc"}, + {file = "nodejs_wheel_binaries-22.13.1-py2.py3-none-macosx_11_0_arm64.whl", hash = "sha256:e4f64d0e26600d51cbdd98a6718a19c2d1b8c7538e9e353e95a634a06a8e1a58"}, + {file = "nodejs_wheel_binaries-22.13.1-py2.py3-none-macosx_11_0_x86_64.whl", hash = "sha256:afcb40484bb02f23137f838014724604ae183fd767b30da95b0be1510a40c06d"}, + {file = "nodejs_wheel_binaries-22.13.1-py2.py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4fc88c98eebabfc36b5270a4ab974a2682746931567ca76a5ca49c54482bbb51"}, + {file = "nodejs_wheel_binaries-22.13.1-py2.py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8b9f75ea8f5e3e5416256fcb00a98cbe14c8d3b6dcaf17da29c4ade5723026d8"}, + {file = "nodejs_wheel_binaries-22.13.1-py2.py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:94608702ef6c389d32e89ff3b7a925cb5dedaf55b5d98bd0c4fb3450a8b6d1c1"}, + {file = "nodejs_wheel_binaries-22.13.1-py2.py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:53a40d0269689aa2eaf2e261cbe5ec256644bc56aae0201ef344b7d8f40ccc79"}, + {file = "nodejs_wheel_binaries-22.13.1-py2.py3-none-win_amd64.whl", hash = "sha256:549371a929a29fbce8d0ab8f1b5410549946d4f1b0376a5ce635b45f6d05298f"}, + {file = "nodejs_wheel_binaries-22.13.1-py2.py3-none-win_arm64.whl", hash = "sha256:cf72d50d755f4e5c0709b0449de01768d96b3b1ec7aa531561415b88f179ad8b"}, + {file = "nodejs_wheel_binaries-22.13.1.tar.gz", hash = "sha256:a0c15213c9c3383541be4400a30959883868ce5da9cebb3d63ddc7fe61459308"}, ] [[package]] @@ -678,25 +679,25 @@ files = [ [[package]] name = "orjson" -version = "3.10.14" +version = "3.10.15" requires_python = ">=3.8" summary = "Fast, correct Python JSON library supporting dataclasses, datetimes, and numpy" groups = ["default"] files = [ - {file = "orjson-3.10.14-cp312-cp312-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:2ad4b7e367efba6dc3f119c9a0fcd41908b7ec0399a696f3cdea7ec477441b09"}, - {file = "orjson-3.10.14-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f496286fc85e93ce0f71cc84fc1c42de2decf1bf494094e188e27a53694777a7"}, - {file = "orjson-3.10.14-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:c7f189bbfcded40e41a6969c1068ba305850ba016665be71a217918931416fbf"}, - {file = "orjson-3.10.14-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:8cc8204f0b75606869c707da331058ddf085de29558b516fc43c73ee5ee2aadb"}, - {file = "orjson-3.10.14-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:deaa2899dff7f03ab667e2ec25842d233e2a6a9e333efa484dfe666403f3501c"}, - {file = "orjson-3.10.14-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f1c3ea52642c9714dc6e56de8a451a066f6d2707d273e07fe8a9cc1ba073813d"}, - {file = "orjson-3.10.14-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:9d3f9ed72e7458ded9a1fb1b4d4ed4c4fdbaf82030ce3f9274b4dc1bff7ace2b"}, - {file = "orjson-3.10.14-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:07520685d408a2aba514c17ccc16199ff2934f9f9e28501e676c557f454a37fe"}, - {file = "orjson-3.10.14-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:76344269b550ea01488d19a2a369ab572c1ac4449a72e9f6ac0d70eb1cbfb953"}, - {file = "orjson-3.10.14-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:e2979d0f2959990620f7e62da6cd954e4620ee815539bc57a8ae46e2dacf90e3"}, - {file = "orjson-3.10.14-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:03f61ca3674555adcb1aa717b9fc87ae936aa7a63f6aba90a474a88701278780"}, - {file = "orjson-3.10.14-cp312-cp312-win32.whl", hash = "sha256:d5075c54edf1d6ad81d4c6523ce54a748ba1208b542e54b97d8a882ecd810fd1"}, - {file = "orjson-3.10.14-cp312-cp312-win_amd64.whl", hash = "sha256:175cafd322e458603e8ce73510a068d16b6e6f389c13f69bf16de0e843d7d406"}, - {file = "orjson-3.10.14.tar.gz", hash = "sha256:cf31f6f071a6b8e7aa1ead1fa27b935b48d00fbfa6a28ce856cfff2d5dd68eed"}, + {file = "orjson-3.10.15-cp312-cp312-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:9d11c0714fc85bfcf36ada1179400862da3288fc785c30e8297844c867d7505a"}, + {file = "orjson-3.10.15-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:dba5a1e85d554e3897fa9fe6fbcff2ed32d55008973ec9a2b992bd9a65d2352d"}, + {file = "orjson-3.10.15-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:7723ad949a0ea502df656948ddd8b392780a5beaa4c3b5f97e525191b102fff0"}, + {file = "orjson-3.10.15-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:6fd9bc64421e9fe9bd88039e7ce8e58d4fead67ca88e3a4014b143cec7684fd4"}, + {file = "orjson-3.10.15-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:dadba0e7b6594216c214ef7894c4bd5f08d7c0135f4dd0145600be4fbcc16767"}, + {file = "orjson-3.10.15-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b48f59114fe318f33bbaee8ebeda696d8ccc94c9e90bc27dbe72153094e26f41"}, + {file = "orjson-3.10.15-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:035fb83585e0f15e076759b6fedaf0abb460d1765b6a36f48018a52858443514"}, + {file = "orjson-3.10.15-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:d13b7fe322d75bf84464b075eafd8e7dd9eae05649aa2a5354cfa32f43c59f17"}, + {file = "orjson-3.10.15-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:7066b74f9f259849629e0d04db6609db4cf5b973248f455ba5d3bd58a4daaa5b"}, + {file = "orjson-3.10.15-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:88dc3f65a026bd3175eb157fea994fca6ac7c4c8579fc5a86fc2114ad05705b7"}, + {file = "orjson-3.10.15-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:b342567e5465bd99faa559507fe45e33fc76b9fb868a63f1642c6bc0735ad02a"}, + {file = "orjson-3.10.15-cp312-cp312-win32.whl", hash = "sha256:0a4f27ea5617828e6b58922fdbec67b0aa4bb844e2d363b9244c47fa2180e665"}, + {file = "orjson-3.10.15-cp312-cp312-win_amd64.whl", hash = "sha256:ef5b87e7aa9545ddadd2309efe6824bd3dd64ac101c15dae0f2f597911d46eaa"}, + {file = "orjson-3.10.15.tar.gz", hash = "sha256:05ca7fe452a2e9d8d9d706a2984c95b9c2ebc5db417ce0b7a49b91d50642a23e"}, ] [[package]] @@ -776,7 +777,7 @@ files = [ [[package]] name = "pydantic" -version = "2.10.5" +version = "2.10.6" requires_python = ">=3.8" summary = "Data validation using Python type hints" groups = ["default"] @@ -786,8 +787,8 @@ dependencies = [ "typing-extensions>=4.12.2", ] files = [ - {file = "pydantic-2.10.5-py3-none-any.whl", hash = "sha256:4dd4e322dbe55472cb7ca7e73f4b63574eecccf2835ffa2af9021ce113c83c53"}, - {file = "pydantic-2.10.5.tar.gz", hash = "sha256:278b38dbbaec562011d659ee05f63346951b3a248a6f3642e1bc68894ea2b4ff"}, + {file = "pydantic-2.10.6-py3-none-any.whl", hash = "sha256:427d664bf0b8a2b34ff5dd0f5a18df00591adcee7198fbd71981054cef37b584"}, + {file = "pydantic-2.10.6.tar.gz", hash = "sha256:ca5daa827cce33de7a42be142548b0096bf05a7e7b365aebfa5f8eeec7128236"}, ] [[package]] @@ -819,13 +820,13 @@ files = [ [[package]] name = "pypika-tortoise" -version = "0.3.2" +version = "0.5.0" requires_python = "<4.0,>=3.8" summary = "Forked from pypika and streamline just for tortoise-orm" groups = ["default"] files = [ - {file = "pypika_tortoise-0.3.2-py3-none-any.whl", hash = "sha256:c5c52bc4473fe6f3db36cf659340750246ec5dd0f980d04ae7811430e299c3a2"}, - {file = "pypika_tortoise-0.3.2.tar.gz", hash = "sha256:f5d508e2ef00255e52ec6ac79ef889e10dbab328f218c55cd134c4d02ff9f6f4"}, + {file = "pypika_tortoise-0.5.0-py3-none-any.whl", hash = "sha256:dbdc47eb52ce17407b05ce9f8560ce93b856d7b28beb01971d956b017846691f"}, + {file = "pypika_tortoise-0.5.0.tar.gz", hash = "sha256:ed0f56761868dc222c03e477578638590b972280b03c7c45cd93345b18b61f58"}, ] [[package]] @@ -939,29 +940,29 @@ files = [ [[package]] name = "ruff" -version = "0.9.1" +version = "0.9.3" requires_python = ">=3.7" summary = "An extremely fast Python linter and code formatter, written in Rust." groups = ["dev"] files = [ - {file = "ruff-0.9.1-py3-none-linux_armv6l.whl", hash = "sha256:84330dda7abcc270e6055551aca93fdde1b0685fc4fd358f26410f9349cf1743"}, - {file = "ruff-0.9.1-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:3cae39ba5d137054b0e5b472aee3b78a7c884e61591b100aeb544bcd1fc38d4f"}, - {file = "ruff-0.9.1-py3-none-macosx_11_0_arm64.whl", hash = "sha256:50c647ff96f4ba288db0ad87048257753733763b409b2faf2ea78b45c8bb7fcb"}, - {file = "ruff-0.9.1-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f0c8b149e9c7353cace7d698e1656ffcf1e36e50f8ea3b5d5f7f87ff9986a7ca"}, - {file = "ruff-0.9.1-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:beb3298604540c884d8b282fe7625651378e1986c25df51dec5b2f60cafc31ce"}, - {file = "ruff-0.9.1-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:39d0174ccc45c439093971cc06ed3ac4dc545f5e8bdacf9f067adf879544d969"}, - {file = "ruff-0.9.1-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:69572926c0f0c9912288915214ca9b2809525ea263603370b9e00bed2ba56dbd"}, - {file = "ruff-0.9.1-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:937267afce0c9170d6d29f01fcd1f4378172dec6760a9f4dface48cdabf9610a"}, - {file = "ruff-0.9.1-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:186c2313de946f2c22bdf5954b8dd083e124bcfb685732cfb0beae0c47233d9b"}, - {file = "ruff-0.9.1-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3f94942a3bb767675d9a051867c036655fe9f6c8a491539156a6f7e6b5f31831"}, - {file = "ruff-0.9.1-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:728d791b769cc28c05f12c280f99e8896932e9833fef1dd8756a6af2261fd1ab"}, - {file = "ruff-0.9.1-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:2f312c86fb40c5c02b44a29a750ee3b21002bd813b5233facdaf63a51d9a85e1"}, - {file = "ruff-0.9.1-py3-none-musllinux_1_2_i686.whl", hash = "sha256:ae017c3a29bee341ba584f3823f805abbe5fe9cd97f87ed07ecbf533c4c88366"}, - {file = "ruff-0.9.1-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:5dc40a378a0e21b4cfe2b8a0f1812a6572fc7b230ef12cd9fac9161aa91d807f"}, - {file = "ruff-0.9.1-py3-none-win32.whl", hash = "sha256:46ebf5cc106cf7e7378ca3c28ce4293b61b449cd121b98699be727d40b79ba72"}, - {file = "ruff-0.9.1-py3-none-win_amd64.whl", hash = "sha256:342a824b46ddbcdddd3abfbb332fa7fcaac5488bf18073e841236aadf4ad5c19"}, - {file = "ruff-0.9.1-py3-none-win_arm64.whl", hash = "sha256:1cd76c7f9c679e6e8f2af8f778367dca82b95009bc7b1a85a47f1521ae524fa7"}, - {file = "ruff-0.9.1.tar.gz", hash = "sha256:fd2b25ecaf907d6458fa842675382c8597b3c746a2dde6717fe3415425df0c17"}, + {file = "ruff-0.9.3-py3-none-linux_armv6l.whl", hash = "sha256:7f39b879064c7d9670197d91124a75d118d00b0990586549949aae80cdc16624"}, + {file = "ruff-0.9.3-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:a187171e7c09efa4b4cc30ee5d0d55a8d6c5311b3e1b74ac5cb96cc89bafc43c"}, + {file = "ruff-0.9.3-py3-none-macosx_11_0_arm64.whl", hash = "sha256:c59ab92f8e92d6725b7ded9d4a31be3ef42688a115c6d3da9457a5bda140e2b4"}, + {file = "ruff-0.9.3-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2dc153c25e715be41bb228bc651c1e9b1a88d5c6e5ed0194fa0dfea02b026439"}, + {file = "ruff-0.9.3-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:646909a1e25e0dc28fbc529eab8eb7bb583079628e8cbe738192853dbbe43af5"}, + {file = "ruff-0.9.3-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:5a5a46e09355695fbdbb30ed9889d6cf1c61b77b700a9fafc21b41f097bfbba4"}, + {file = "ruff-0.9.3-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:c4bb09d2bbb394e3730d0918c00276e79b2de70ec2a5231cd4ebb51a57df9ba1"}, + {file = "ruff-0.9.3-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:96a87ec31dc1044d8c2da2ebbed1c456d9b561e7d087734336518181b26b3aa5"}, + {file = "ruff-0.9.3-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:9bb7554aca6f842645022fe2d301c264e6925baa708b392867b7a62645304df4"}, + {file = "ruff-0.9.3-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:cabc332b7075a914ecea912cd1f3d4370489c8018f2c945a30bcc934e3bc06a6"}, + {file = "ruff-0.9.3-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:33866c3cc2a575cbd546f2cd02bdd466fed65118e4365ee538a3deffd6fcb730"}, + {file = "ruff-0.9.3-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:006e5de2621304c8810bcd2ee101587712fa93b4f955ed0985907a36c427e0c2"}, + {file = "ruff-0.9.3-py3-none-musllinux_1_2_i686.whl", hash = "sha256:ba6eea4459dbd6b1be4e6bfc766079fb9b8dd2e5a35aff6baee4d9b1514ea519"}, + {file = "ruff-0.9.3-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:90230a6b8055ad47d3325e9ee8f8a9ae7e273078a66401ac66df68943ced029b"}, + {file = "ruff-0.9.3-py3-none-win32.whl", hash = "sha256:eabe5eb2c19a42f4808c03b82bd313fc84d4e395133fb3fc1b1516170a31213c"}, + {file = "ruff-0.9.3-py3-none-win_amd64.whl", hash = "sha256:040ceb7f20791dfa0e78b4230ee9dce23da3b64dd5848e40e3bf3ab76468dcf4"}, + {file = "ruff-0.9.3-py3-none-win_arm64.whl", hash = "sha256:800d773f6d4d33b0a3c60e2c6ae8f4c202ea2de056365acfa519aa48acf28e0b"}, + {file = "ruff-0.9.3.tar.gz", hash = "sha256:8293f89985a090ebc3ed1064df31f3b4b56320cdfcec8b60d3295bddb955c22a"}, ] [[package]] @@ -979,7 +980,7 @@ files = [ [[package]] name = "sentry-sdk" -version = "2.19.2" +version = "2.20.0" requires_python = ">=3.6" summary = "Python client for Sentry (https://sentry.io)" groups = ["default"] @@ -988,8 +989,8 @@ dependencies = [ "urllib3>=1.26.11", ] files = [ - {file = "sentry_sdk-2.19.2-py2.py3-none-any.whl", hash = "sha256:ebdc08228b4d131128e568d696c210d846e5b9d70aa0327dec6b1272d9d40b84"}, - {file = "sentry_sdk-2.19.2.tar.gz", hash = "sha256:467df6e126ba242d39952375dd816fbee0f217d119bf454a8ce74cf1e7909e8d"}, + {file = "sentry_sdk-2.20.0-py2.py3-none-any.whl", hash = "sha256:c359a1edf950eb5e80cffd7d9111f3dbeef57994cb4415df37d39fda2cf22364"}, + {file = "sentry_sdk-2.20.0.tar.gz", hash = "sha256:afa82713a92facf847df3c6f63cec71eb488d826a50965def3d7722aa6f0fdab"}, ] [[package]] @@ -1027,47 +1028,47 @@ files = [ [[package]] name = "tomli-w" -version = "1.1.0" +version = "1.2.0" requires_python = ">=3.9" summary = "A lil' TOML writer" groups = ["default"] marker = "python_version >= \"3.11\"" files = [ - {file = "tomli_w-1.1.0-py3-none-any.whl", hash = "sha256:1403179c78193e3184bfaade390ddbd071cba48a32a2e62ba11aae47490c63f7"}, - {file = "tomli_w-1.1.0.tar.gz", hash = "sha256:49e847a3a304d516a169a601184932ef0f6b61623fe680f836a2aa7128ed0d33"}, + {file = "tomli_w-1.2.0-py3-none-any.whl", hash = "sha256:188306098d013b691fcadc011abd66727d3c414c571bb01b1a174ba8c983cf90"}, + {file = "tomli_w-1.2.0.tar.gz", hash = "sha256:2dd14fac5a47c27be9cd4c976af5a12d87fb1f0b4512f81d69cce3b35ae25021"}, ] [[package]] name = "tortoise-orm" -version = "0.23.0" -requires_python = "<4.0,>=3.8" +version = "0.24.0" +requires_python = "<4.0,>=3.9" summary = "Easy async ORM for python, built with relations in mind" groups = ["default"] dependencies = [ "aiosqlite<0.21.0,>=0.16.0", "iso8601<3.0.0,>=2.1.0", - "pypika-tortoise<0.4.0,>=0.3.2", + "pypika-tortoise<0.6.0,>=0.5.0", "pytz", ] files = [ - {file = "tortoise_orm-0.23.0-py3-none-any.whl", hash = "sha256:deaabed1619ea8aab6213508dff025571a701b7f34ee534473d7bb7661aa9f4f"}, - {file = "tortoise_orm-0.23.0.tar.gz", hash = "sha256:f25d431ef4fb521a84edad582f4b9c53dccc5abf6cfbc6f228cbece5a13952fa"}, + {file = "tortoise_orm-0.24.0-py3-none-any.whl", hash = "sha256:ee3b72b226767293b24c5c4906ae5f027d7cc84496cd503352c918564b4fd687"}, + {file = "tortoise_orm-0.24.0.tar.gz", hash = "sha256:ae0704a93ea27931724fc899e57268c8081afce3b32b110b00037ec206553e7d"}, ] [[package]] name = "tortoise-orm" -version = "0.23.0" +version = "0.24.0" extras = ["asyncpg"] -requires_python = "<4.0,>=3.8" +requires_python = "<4.0,>=3.9" summary = "Easy async ORM for python, built with relations in mind" groups = ["default"] dependencies = [ "asyncpg", - "tortoise-orm==0.23.0", + "tortoise-orm==0.24.0", ] files = [ - {file = "tortoise_orm-0.23.0-py3-none-any.whl", hash = "sha256:deaabed1619ea8aab6213508dff025571a701b7f34ee534473d7bb7661aa9f4f"}, - {file = "tortoise_orm-0.23.0.tar.gz", hash = "sha256:f25d431ef4fb521a84edad582f4b9c53dccc5abf6cfbc6f228cbece5a13952fa"}, + {file = "tortoise_orm-0.24.0-py3-none-any.whl", hash = "sha256:ee3b72b226767293b24c5c4906ae5f027d7cc84496cd503352c918564b4fd687"}, + {file = "tortoise_orm-0.24.0.tar.gz", hash = "sha256:ae0704a93ea27931724fc899e57268c8081afce3b32b110b00037ec206553e7d"}, ] [[package]] @@ -1094,24 +1095,24 @@ files = [ [[package]] name = "websockets" -version = "14.1" +version = "14.2" requires_python = ">=3.9" summary = "An implementation of the WebSocket Protocol (RFC 6455 & 7692)" groups = ["dev"] files = [ - {file = "websockets-14.1-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:ed907449fe5e021933e46a3e65d651f641975a768d0649fee59f10c2985529ed"}, - {file = "websockets-14.1-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:87e31011b5c14a33b29f17eb48932e63e1dcd3fa31d72209848652310d3d1f0d"}, - {file = "websockets-14.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:bc6ccf7d54c02ae47a48ddf9414c54d48af9c01076a2e1023e3b486b6e72c707"}, - {file = "websockets-14.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9777564c0a72a1d457f0848977a1cbe15cfa75fa2f67ce267441e465717dcf1a"}, - {file = "websockets-14.1-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a655bde548ca98f55b43711b0ceefd2a88a71af6350b0c168aa77562104f3f45"}, - {file = "websockets-14.1-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a3dfff83ca578cada2d19e665e9c8368e1598d4e787422a460ec70e531dbdd58"}, - {file = "websockets-14.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:6a6c9bcf7cdc0fd41cc7b7944447982e8acfd9f0d560ea6d6845428ed0562058"}, - {file = "websockets-14.1-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:4b6caec8576e760f2c7dd878ba817653144d5f369200b6ddf9771d64385b84d4"}, - {file = "websockets-14.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:eb6d38971c800ff02e4a6afd791bbe3b923a9a57ca9aeab7314c21c84bf9ff05"}, - {file = "websockets-14.1-cp312-cp312-win32.whl", hash = "sha256:1d045cbe1358d76b24d5e20e7b1878efe578d9897a25c24e6006eef788c0fdf0"}, - {file = "websockets-14.1-cp312-cp312-win_amd64.whl", hash = "sha256:90f4c7a069c733d95c308380aae314f2cb45bd8a904fb03eb36d1a4983a4993f"}, - {file = "websockets-14.1-py3-none-any.whl", hash = "sha256:4d4fc827a20abe6d544a119896f6b78ee13fe81cbfef416f3f2ddf09a03f0e2e"}, - {file = "websockets-14.1.tar.gz", hash = "sha256:398b10c77d471c0aab20a845e7a60076b6390bfdaac7a6d2edb0d2c59d75e8d8"}, + {file = "websockets-14.2-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:1f20522e624d7ffbdbe259c6b6a65d73c895045f76a93719aa10cd93b3de100c"}, + {file = "websockets-14.2-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:647b573f7d3ada919fd60e64d533409a79dcf1ea21daeb4542d1d996519ca967"}, + {file = "websockets-14.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:6af99a38e49f66be5a64b1e890208ad026cda49355661549c507152113049990"}, + {file = "websockets-14.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:091ab63dfc8cea748cc22c1db2814eadb77ccbf82829bac6b2fbe3401d548eda"}, + {file = "websockets-14.2-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b374e8953ad477d17e4851cdc66d83fdc2db88d9e73abf755c94510ebddceb95"}, + {file = "websockets-14.2-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a39d7eceeea35db85b85e1169011bb4321c32e673920ae9c1b6e0978590012a3"}, + {file = "websockets-14.2-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:0a6f3efd47ffd0d12080594f434faf1cd2549b31e54870b8470b28cc1d3817d9"}, + {file = "websockets-14.2-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:065ce275e7c4ffb42cb738dd6b20726ac26ac9ad0a2a48e33ca632351a737267"}, + {file = "websockets-14.2-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:e9d0e53530ba7b8b5e389c02282f9d2aa47581514bd6049d3a7cffe1385cf5fe"}, + {file = "websockets-14.2-cp312-cp312-win32.whl", hash = "sha256:20e6dd0984d7ca3037afcb4494e48c74ffb51e8013cac71cf607fffe11df7205"}, + {file = "websockets-14.2-cp312-cp312-win_amd64.whl", hash = "sha256:44bba1a956c2c9d268bdcdf234d5e5ff4c9b6dc3e300545cbe99af59dda9dcce"}, + {file = "websockets-14.2-py3-none-any.whl", hash = "sha256:7a6ceec4ea84469f15cf15807a747e9efe57e369c384fa86e022b3bea679b79b"}, + {file = "websockets-14.2.tar.gz", hash = "sha256:5059ed9c54945efb321f097084b4c7e52c246f2c869815876a69d1efc4ad6eb5"}, ] [[package]] @@ -1130,23 +1131,24 @@ files = [ [[package]] name = "wrapt" -version = "1.17.1" +version = "1.17.2" requires_python = ">=3.8" summary = "Module for decorators, wrappers and monkey patching." groups = ["dev"] files = [ - {file = "wrapt-1.17.1-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:b1a4c8edd038fee0ce67bf119b16eaa45d22a52bbaf7d0a17d2312eb0003b1bb"}, - {file = "wrapt-1.17.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:181a844005c9818792212a32e004cb4c6bd8e35cae8e97b1a39a1918d95cef58"}, - {file = "wrapt-1.17.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:21ffcf16f5c243a626b0f8da637948e3d5984e3bc0c1bc500ad990e88e974e3b"}, - {file = "wrapt-1.17.1-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0eb33799b7582bb73787b9903b70595f8eff67eecc9455f668ed01adf53f9eea"}, - {file = "wrapt-1.17.1-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:57e932ad1908b53e9ad67a746432f02bc8473a9ee16e26a47645a2b224fba5fd"}, - {file = "wrapt-1.17.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:b8bd35c15bc82c5cbe397e8196fa57a17ce5d3f30e925a6fd39e4c5bb02fdcff"}, - {file = "wrapt-1.17.1-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:93018dbb956e0ad99ea2fa2c3c22f033549dcb1f56ad9f4555dfe25e49688c5d"}, - {file = "wrapt-1.17.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:e5bd9186d52cf3d36bf1823be0e85297e4dbad909bc6dd495ce0d272806d84a7"}, - {file = "wrapt-1.17.1-cp312-cp312-win32.whl", hash = "sha256:d609f0ab0603bbcbf2de906b366b9f9bec75c32b4493550a940de658cc2ce512"}, - {file = "wrapt-1.17.1-cp312-cp312-win_amd64.whl", hash = "sha256:2c160bb8815787646b27a0c8575a26a4d6bf6abd7c5eb250ad3f2d38b29cb2cb"}, - {file = "wrapt-1.17.1-py3-none-any.whl", hash = "sha256:f3117feb1fc479eaf84b549d3f229d5d2abdb823f003bc2a1c6dd70072912fa0"}, - {file = "wrapt-1.17.1.tar.gz", hash = "sha256:16b2fdfa09a74a3930175b6d9d7d008022aa72a4f02de2b3eecafcc1adfd3cfe"}, + {file = "wrapt-1.17.2-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:d5e2439eecc762cd85e7bd37161d4714aa03a33c5ba884e26c81559817ca0925"}, + {file = "wrapt-1.17.2-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:3fc7cb4c1c744f8c05cd5f9438a3caa6ab94ce8344e952d7c45a8ed59dd88392"}, + {file = "wrapt-1.17.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:8fdbdb757d5390f7c675e558fd3186d590973244fab0c5fe63d373ade3e99d40"}, + {file = "wrapt-1.17.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5bb1d0dbf99411f3d871deb6faa9aabb9d4e744d67dcaaa05399af89d847a91d"}, + {file = "wrapt-1.17.2-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d18a4865f46b8579d44e4fe1e2bcbc6472ad83d98e22a26c963d46e4c125ef0b"}, + {file = "wrapt-1.17.2-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bc570b5f14a79734437cb7b0500376b6b791153314986074486e0b0fa8d71d98"}, + {file = "wrapt-1.17.2-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:6d9187b01bebc3875bac9b087948a2bccefe464a7d8f627cf6e48b1bbae30f82"}, + {file = "wrapt-1.17.2-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:9e8659775f1adf02eb1e6f109751268e493c73716ca5761f8acb695e52a756ae"}, + {file = "wrapt-1.17.2-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:e8b2816ebef96d83657b56306152a93909a83f23994f4b30ad4573b00bd11bb9"}, + {file = "wrapt-1.17.2-cp312-cp312-win32.whl", hash = "sha256:468090021f391fe0056ad3e807e3d9034e0fd01adcd3bdfba977b6fdf4213ea9"}, + {file = "wrapt-1.17.2-cp312-cp312-win_amd64.whl", hash = "sha256:ec89ed91f2fa8e3f52ae53cd3cf640d6feff92ba90d62236a81e4e563ac0e991"}, + {file = "wrapt-1.17.2-py3-none-any.whl", hash = "sha256:b18f2d1533a71f069c7f82d524a52599053d4c7166e9dd374ae2136b7f40f7c8"}, + {file = "wrapt-1.17.2.tar.gz", hash = "sha256:41388e9d4d1522446fe79d3213196bd9e3b301a336965b9e27ca2788ebd122f3"}, ] [[package]] diff --git a/requirements.txt b/requirements.txt index b82fbd6..5a81c98 100644 --- a/requirements.txt +++ b/requirements.txt @@ -59,17 +59,17 @@ asyncpg==0.30.0 \ --hash=sha256:c551e9928ab6707602f44811817f82ba3c446e018bfe1d3abecc8ba5f3eac851 \ --hash=sha256:c902a60b52e506d38d7e80e0dd5399f657220f24635fee368117b8b5fce1142e \ --hash=sha256:db9891e2d76e6f425746c5d2da01921e9a16b5a71a1c905b13f30e12a257c4af -attrs==24.3.0 \ - --hash=sha256:8f5c07333d543103541ba7be0e2ce16eeee8130cb0b3f9238ab904ce1e85baff \ - --hash=sha256:ac96cd038792094f438ad1f6ff80837353805ac950cd2aa0e0625ef19850c308 +attrs==25.1.0 \ + --hash=sha256:1c97078a80c814273a76b2a298a932eb681c87415c11dee0a6921de7f1b02c3e \ + --hash=sha256:c75a69e28a550a7e93789579c22aa26b0f5b83b75dc4e08fe092980051e1090a blinker==1.9.0 \ --hash=sha256:b4ce2265a7abece45e7cc896e98dbebe6cead56bcf805a3d23136d145f5445bf \ --hash=sha256:ba0efaa9080b619ff2f3459d1d500c57bddea4a6b424b60a91141db6fd2f08bc -caio==0.9.19 \ - --hash=sha256:6d426f2e9fcec7b1a767b187861bd0aecae9f88bc36227331d2fb978722bed90 \ - --hash=sha256:a743fda13e194b21df922ea0cee404e2bcac72a722c469eed6bd893a0cdec1c0 \ - --hash=sha256:bdcb529330730c4c364b79789620f33bafad8c2c854c1205ecc2d16511c0b690 \ - --hash=sha256:f2bc23784f50ac8a2b5a3a0625ff181a92cbb8f4ce532d23a6be441c38deb7c8 +caio==0.9.21 \ + --hash=sha256:1f4241e2b89f31e1fea342c8da9a987fef71d093df7ba1169f469d0be7592608 \ + --hash=sha256:4f1d30ad0f975de07b4a3ae1cd2e9275fa574f2ca0b49ba5ab16208575650a92 \ + --hash=sha256:e7314a28d69a0397d1d0ac6c7bfe7973f27f4f7216cf42b0358d7d9ba27bc4cd \ + --hash=sha256:fdab8c817b6835d997db1532ce7d9f5cbe186265bf0ee9a9840b378aa4a1cba7 certifi==2024.12.14 \ --hash=sha256:1275f7a45be9464efc1173084eaa30f866fe2e47d389406136d332ed4967ec56 \ --hash=sha256:b650d30f370c2b724812bee08008be0c4163b163ddaec3f2546c1caf65f191db @@ -112,18 +112,18 @@ h11==0.14.0 \ h2==4.1.0 \ --hash=sha256:03a46bcf682256c95b5fd9e9a99c1323584c3eec6440d379b9903d709476bc6d \ --hash=sha256:a83aca08fbe7aacb79fec788c9c0bac936343560ed9ec18b82a13a12c28d2abb -hpack==4.0.0 \ - --hash=sha256:84a076fad3dc9a9f8063ccb8041ef100867b1878b25ef0ee63847a5d53818a6c \ - --hash=sha256:fc41de0c63e687ebffde81187a948221294896f6bdc0ae2312708df339430095 +hpack==4.1.0 \ + --hash=sha256:157ac792668d995c657d93111f46b4535ed114f0c9c8d672271bbec7eae1b496 \ + --hash=sha256:ec5eca154f7056aa06f196a557655c5b009b382873ac8d1e66e79e87535f1dca humanfriendly==10.0 \ --hash=sha256:1697e1a8a8f550fd43c2865cd84542fc175a61dcb779b6fee18cf6b6ccba1477 \ --hash=sha256:6b0b831ce8f15f7300721aa49829fc4e83921a9a301cc7f606be6686a2288ddc hypercorn==0.17.3 \ --hash=sha256:059215dec34537f9d40a69258d323f56344805efb462959e727152b0aa504547 \ --hash=sha256:1b37802ee3ac52d2d85270700d565787ab16cf19e1462ccfa9f089ca17574165 -hyperframe==6.0.1 \ - --hash=sha256:0ec6bafd80d8ad2195c4f03aacba3a8265e57bc4cff261e802bf39970ed02a15 \ - --hash=sha256:ae510046231dc8e9ecb1a6586f63d2347bf4c8905914aa84ba585ae85f28a914 +hyperframe==6.1.0 \ + --hash=sha256:b03380493a519fce58ea5af42e4a42317bf9bd425596f7a0835ffce80f1a42e5 \ + --hash=sha256:f630908a00854a7adeabd6382b43923a4c4cd4b821fcb527e6ab9e15382a3b08 idna==3.10 \ --hash=sha256:12f65c9b470abda6dc35cf8e63cc574b1c52b11df2c86030af0ac09b01b13ea9 \ --hash=sha256:946d195a0d259cbba61165e88e65941f16e9b36ea6ddb97f00452bae8b1287d3 @@ -166,21 +166,21 @@ multidict==6.1.0 \ --hash=sha256:820c661588bd01a0aa62a1283f20d2be4281b086f80dad9e955e690c75fb54a2 \ --hash=sha256:b04772ed465fa3cc947db808fa306d79b43e896beb677a56fb2347ca1a49c1fa \ --hash=sha256:b58c621844d55e71c1b7f7c498ce5aa6985d743a1a59034c57a905b3f153c1ef -orjson==3.10.14 \ - --hash=sha256:03f61ca3674555adcb1aa717b9fc87ae936aa7a63f6aba90a474a88701278780 \ - --hash=sha256:07520685d408a2aba514c17ccc16199ff2934f9f9e28501e676c557f454a37fe \ - --hash=sha256:175cafd322e458603e8ce73510a068d16b6e6f389c13f69bf16de0e843d7d406 \ - --hash=sha256:2ad4b7e367efba6dc3f119c9a0fcd41908b7ec0399a696f3cdea7ec477441b09 \ - --hash=sha256:76344269b550ea01488d19a2a369ab572c1ac4449a72e9f6ac0d70eb1cbfb953 \ - --hash=sha256:8cc8204f0b75606869c707da331058ddf085de29558b516fc43c73ee5ee2aadb \ - --hash=sha256:9d3f9ed72e7458ded9a1fb1b4d4ed4c4fdbaf82030ce3f9274b4dc1bff7ace2b \ - --hash=sha256:c7f189bbfcded40e41a6969c1068ba305850ba016665be71a217918931416fbf \ - --hash=sha256:cf31f6f071a6b8e7aa1ead1fa27b935b48d00fbfa6a28ce856cfff2d5dd68eed \ - --hash=sha256:d5075c54edf1d6ad81d4c6523ce54a748ba1208b542e54b97d8a882ecd810fd1 \ - --hash=sha256:deaa2899dff7f03ab667e2ec25842d233e2a6a9e333efa484dfe666403f3501c \ - --hash=sha256:e2979d0f2959990620f7e62da6cd954e4620ee815539bc57a8ae46e2dacf90e3 \ - --hash=sha256:f1c3ea52642c9714dc6e56de8a451a066f6d2707d273e07fe8a9cc1ba073813d \ - --hash=sha256:f496286fc85e93ce0f71cc84fc1c42de2decf1bf494094e188e27a53694777a7 +orjson==3.10.15 \ + --hash=sha256:035fb83585e0f15e076759b6fedaf0abb460d1765b6a36f48018a52858443514 \ + --hash=sha256:05ca7fe452a2e9d8d9d706a2984c95b9c2ebc5db417ce0b7a49b91d50642a23e \ + --hash=sha256:0a4f27ea5617828e6b58922fdbec67b0aa4bb844e2d363b9244c47fa2180e665 \ + --hash=sha256:6fd9bc64421e9fe9bd88039e7ce8e58d4fead67ca88e3a4014b143cec7684fd4 \ + --hash=sha256:7066b74f9f259849629e0d04db6609db4cf5b973248f455ba5d3bd58a4daaa5b \ + --hash=sha256:7723ad949a0ea502df656948ddd8b392780a5beaa4c3b5f97e525191b102fff0 \ + --hash=sha256:88dc3f65a026bd3175eb157fea994fca6ac7c4c8579fc5a86fc2114ad05705b7 \ + --hash=sha256:9d11c0714fc85bfcf36ada1179400862da3288fc785c30e8297844c867d7505a \ + --hash=sha256:b342567e5465bd99faa559507fe45e33fc76b9fb868a63f1642c6bc0735ad02a \ + --hash=sha256:b48f59114fe318f33bbaee8ebeda696d8ccc94c9e90bc27dbe72153094e26f41 \ + --hash=sha256:d13b7fe322d75bf84464b075eafd8e7dd9eae05649aa2a5354cfa32f43c59f17 \ + --hash=sha256:dadba0e7b6594216c214ef7894c4bd5f08d7c0135f4dd0145600be4fbcc16767 \ + --hash=sha256:dba5a1e85d554e3897fa9fe6fbcff2ed32d55008973ec9a2b992bd9a65d2352d \ + --hash=sha256:ef5b87e7aa9545ddadd2309efe6824bd3dd64ac101c15dae0f2f597911d46eaa priority==2.0.0 \ --hash=sha256:6f8eefce5f3ad59baf2c080a664037bb4725cd0a790d53d59ab4059288faf6aa \ --hash=sha256:c965d54f1b8d0d0b19479db3924c7c36cf672dbf2aec92d43fbdaf4492ba18c0 @@ -206,9 +206,9 @@ propcache==0.2.1 \ py-cord==2.6.1 \ --hash=sha256:36064f225f2c7bbddfe542d5ed581f2a5744f618e039093cf7cd2659a58bc79b \ --hash=sha256:e3d3b528c5e37b0e0825f5b884cbb9267860976c1e4878e28b55da8fd3af834b -pydantic==2.10.5 \ - --hash=sha256:278b38dbbaec562011d659ee05f63346951b3a248a6f3642e1bc68894ea2b4ff \ - --hash=sha256:4dd4e322dbe55472cb7ca7e73f4b63574eecccf2835ffa2af9021ce113c83c53 +pydantic==2.10.6 \ + --hash=sha256:427d664bf0b8a2b34ff5dd0f5a18df00591adcee7198fbd71981054cef37b584 \ + --hash=sha256:ca5daa827cce33de7a42be142548b0096bf05a7e7b365aebfa5f8eeec7128236 pydantic-core==2.27.2 \ --hash=sha256:05e3a55d124407fffba0dd6b0c0cd056d10e983ceb4e5dbd10dda135c31071d6 \ --hash=sha256:172fce187655fece0c90d90a678424b013f8fbb0ca8b036ac266749c09438cb7 \ @@ -225,9 +225,9 @@ pydantic-core==2.27.2 \ --hash=sha256:cc3f1a99a4f4f9dd1de4fe0312c114e740b5ddead65bb4102884b384c15d8bc9 \ --hash=sha256:de3cd1899e2c279b140adde9357c4495ed9d47131b4a4eaff9052f23398076b3 \ --hash=sha256:eb026e5a4c1fee05726072337ff51d1efb6f59090b7da90d30ea58625b1ffb39 -pypika-tortoise==0.3.2 \ - --hash=sha256:c5c52bc4473fe6f3db36cf659340750246ec5dd0f980d04ae7811430e299c3a2 \ - --hash=sha256:f5d508e2ef00255e52ec6ac79ef889e10dbab328f218c55cd134c4d02ff9f6f4 +pypika-tortoise==0.5.0 \ + --hash=sha256:dbdc47eb52ce17407b05ce9f8560ce93b856d7b28beb01971d956b017846691f \ + --hash=sha256:ed0f56761868dc222c03e477578638590b972280b03c7c45cd93345b18b61f58 pyreadline3==3.5.4; sys_platform == "win32" and python_version >= "3.8" \ --hash=sha256:8d57d53039a1c75adba8e50dd3d992b28143480816187ea5efbd5c78e6c885b7 \ --hash=sha256:eaf8e6cc3c49bcccf145fc6067ba8643d1df34d604a1ec0eccbf7a18e6d3fae6 @@ -257,18 +257,18 @@ redis==5.2.1 \ schema==0.7.7 \ --hash=sha256:5d976a5b50f36e74e2157b47097b60002bd4d42e65425fcc9c9befadb4255dde \ --hash=sha256:7da553abd2958a19dc2547c388cde53398b39196175a9be59ea1caf5ab0a1807 -sentry-sdk==2.19.2 \ - --hash=sha256:467df6e126ba242d39952375dd816fbee0f217d119bf454a8ce74cf1e7909e8d \ - --hash=sha256:ebdc08228b4d131128e568d696c210d846e5b9d70aa0327dec6b1272d9d40b84 +sentry-sdk==2.20.0 \ + --hash=sha256:afa82713a92facf847df3c6f63cec71eb488d826a50965def3d7722aa6f0fdab \ + --hash=sha256:c359a1edf950eb5e80cffd7d9111f3dbeef57994cb4415df37d39fda2cf22364 sniffio==1.3.1 \ --hash=sha256:2f6da418d1f1e0fddd844478f41680e794e6051915791a034ff65e5f100525a2 \ --hash=sha256:f4324edc670a0f49750a81b895f35c3adb843cca46f0530f79fc1babb23789dc -tomli-w==1.1.0; python_version >= "3.11" \ - --hash=sha256:1403179c78193e3184bfaade390ddbd071cba48a32a2e62ba11aae47490c63f7 \ - --hash=sha256:49e847a3a304d516a169a601184932ef0f6b61623fe680f836a2aa7128ed0d33 -tortoise-orm[asyncpg]==0.23.0 \ - --hash=sha256:deaabed1619ea8aab6213508dff025571a701b7f34ee534473d7bb7661aa9f4f \ - --hash=sha256:f25d431ef4fb521a84edad582f4b9c53dccc5abf6cfbc6f228cbece5a13952fa +tomli-w==1.2.0; python_version >= "3.11" \ + --hash=sha256:188306098d013b691fcadc011abd66727d3c414c571bb01b1a174ba8c983cf90 \ + --hash=sha256:2dd14fac5a47c27be9cd4c976af5a12d87fb1f0b4512f81d69cce3b35ae25021 +tortoise-orm[asyncpg]==0.24.0 \ + --hash=sha256:ae0704a93ea27931724fc899e57268c8081afce3b32b110b00037ec206553e7d \ + --hash=sha256:ee3b72b226767293b24c5c4906ae5f027d7cc84496cd503352c918564b4fd687 typing-extensions==4.12.2 \ --hash=sha256:04e5ca0351e0f3f85c6853954072df659d0d13fac324d0072316b67d7794700d \ --hash=sha256:1a7ead55c7e559dd4dee8856e3a88b41225abfe1ce8df57b7c13915fe121ffb8 From ba5d0f6d213a89e02859078a3a24dcc9a15a2148 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 28 Jan 2025 19:27:09 +0100 Subject: [PATCH 51/61] =?UTF-8?q?=E2=AC=86=EF=B8=8F=20Upgrade=20docker/bui?= =?UTF-8?q?ld-push-action=20action=20to=20v6.13.0=20(#74)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- .github/workflows/docker.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/docker.yaml b/.github/workflows/docker.yaml index 424bc8d..10d9382 100644 --- a/.github/workflows/docker.yaml +++ b/.github/workflows/docker.yaml @@ -39,7 +39,7 @@ jobs: type=sha - name: Build and push Docker image - uses: docker/build-push-action@v6.11.0 + uses: docker/build-push-action@v6.13.0 with: context: . push: true From 43d0676e33da4f7b88b2e6efc4ae44d20be090e7 Mon Sep 17 00:00:00 2001 From: Paillat Date: Sat, 1 Feb 2025 18:09:03 +0100 Subject: [PATCH 52/61] :technologist: Fix linter warnings and improve pre-commit --- .pre-commit-config.yaml | 5 +-- pdm.lock | 75 ++++++++++++++++++++--------------------- src/start.py | 14 ++++---- src/utils/extensions.py | 19 ++++++----- 4 files changed, 56 insertions(+), 57 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 6f2b1ad..01edbcf 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -21,7 +21,7 @@ repos: exclude: \.(po|pot|yml|yaml)$ - repo: https://github.com/astral-sh/ruff-pre-commit # Ruff version. - rev: v0.8.1 + rev: v0.9.4 hooks: # Run the linter. - id: ruff @@ -34,4 +34,5 @@ repos: name: copywrite entry: copywrite headers language: system - files: . \ No newline at end of file + pass_filenames: false + files: . diff --git a/pdm.lock b/pdm.lock index 5cc9e57..d5e6179 100644 --- a/pdm.lock +++ b/pdm.lock @@ -249,7 +249,7 @@ files = [ [[package]] name = "basedpyright" -version = "1.24.0" +version = "1.26.0" requires_python = ">=3.8" summary = "static type checking for Python (but based)" groups = ["dev"] @@ -257,8 +257,8 @@ dependencies = [ "nodejs-wheel-binaries>=20.13.1", ] files = [ - {file = "basedpyright-1.24.0-py3-none-any.whl", hash = "sha256:32ae77b2334dc9737c9220bcbc1aee98f76884be033bd5f4f50e5940fa16391d"}, - {file = "basedpyright-1.24.0.tar.gz", hash = "sha256:425919327db8662f1be718dafe06b1e168781f9728e59a9cf717cbb3380acec9"}, + {file = "basedpyright-1.26.0-py3-none-any.whl", hash = "sha256:5a6a17f2c389ec313dd2c3644f40e8221bc90252164802e626055341c0a37381"}, + {file = "basedpyright-1.26.0.tar.gz", hash = "sha256:5e01f6eb9290a09ef39672106cf1a02924fdc8970e521838bc502ccf0676f32f"}, ] [[package]] @@ -301,13 +301,13 @@ files = [ [[package]] name = "certifi" -version = "2024.12.14" +version = "2025.1.31" requires_python = ">=3.6" summary = "Python package for providing Mozilla's CA Bundle." groups = ["default"] files = [ - {file = "certifi-2024.12.14-py3-none-any.whl", hash = "sha256:1275f7a45be9464efc1173084eaa30f866fe2e47d389406136d332ed4967ec56"}, - {file = "certifi-2024.12.14.tar.gz", hash = "sha256:b650d30f370c2b724812bee08008be0c4163b163ddaec3f2546c1caf65f191db"}, + {file = "certifi-2025.1.31-py3-none-any.whl", hash = "sha256:ca78db4565a652026a4db2bcdf68f2fb589ea80d0be70e03929ed730746b84fe"}, + {file = "certifi-2025.1.31.tar.gz", hash = "sha256:3d5da6925056f6f18f119200434a4780a94263f10d1c21d032a6f6b2baa20651"}, ] [[package]] @@ -353,7 +353,7 @@ files = [ [[package]] name = "deprecated" -version = "1.2.17" +version = "1.2.18" requires_python = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,>=2.7" summary = "Python @deprecated decorator to deprecate old python classes, functions or methods." groups = ["dev"] @@ -361,8 +361,8 @@ dependencies = [ "wrapt<2,>=1.10", ] files = [ - {file = "Deprecated-1.2.17-py2.py3-none-any.whl", hash = "sha256:69cdc0a751671183f569495e2efb14baee4344b0236342eec29f1fde25d61818"}, - {file = "deprecated-1.2.17.tar.gz", hash = "sha256:0114a10f0bbb750b90b2c2296c90cf7e9eaeb0abb5cf06c80de2c60138de0a82"}, + {file = "Deprecated-1.2.18-py2.py3-none-any.whl", hash = "sha256:bd5011788200372a32418f888e326a09ff80d0214bd961147cfed01b5c018eec"}, + {file = "deprecated-1.2.18.tar.gz", hash = "sha256:422b6f6d859da6f2ef57857761bfb392480502a64c3028ca9bbe86085d72115d"}, ] [[package]] @@ -436,17 +436,16 @@ files = [ [[package]] name = "h2" -version = "4.1.0" -requires_python = ">=3.6.1" -summary = "HTTP/2 State-Machine based protocol implementation" +version = "4.2.0" +requires_python = ">=3.9" +summary = "Pure-Python HTTP/2 protocol implementation" groups = ["default"] dependencies = [ - "hpack<5,>=4.0", - "hyperframe<7,>=6.0", + "hpack<5,>=4.1", + "hyperframe<7,>=6.1", ] files = [ - {file = "h2-4.1.0-py3-none-any.whl", hash = "sha256:03a46bcf682256c95b5fd9e9a99c1323584c3eec6440d379b9903d709476bc6d"}, - {file = "h2-4.1.0.tar.gz", hash = "sha256:a83aca08fbe7aacb79fec788c9c0bac936343560ed9ec18b82a13a12c28d2abb"}, + {file = "h2-4.2.0-py3-none-any.whl", hash = "sha256:479a53ad425bb29af087f3458a61d30780bc818e4ebcf01f0b536ba916462ed0"}, ] [[package]] @@ -873,12 +872,12 @@ files = [ [[package]] name = "pytz" -version = "2024.2" +version = "2025.1" summary = "World timezone definitions, modern and historical" groups = ["default"] files = [ - {file = "pytz-2024.2-py2.py3-none-any.whl", hash = "sha256:31c7c1817eb7fae7ca4b8c7ee50c72f93aa2dd863de768e1ef4245d426aa0725"}, - {file = "pytz-2024.2.tar.gz", hash = "sha256:2aa355083c50a0f93fa581709deac0c9ad65cca8a9e9beac660adcbd493c798a"}, + {file = "pytz-2025.1-py2.py3-none-any.whl", hash = "sha256:89dd22dca55b46eac6eda23b2d72721bf1bdfef212645d81513ef5d03038de57"}, + {file = "pytz-2025.1.tar.gz", hash = "sha256:c2db42be2a2518b28e65f9207c4d05e6ff547d1efa4086469ef855e4ab70178e"}, ] [[package]] @@ -940,29 +939,29 @@ files = [ [[package]] name = "ruff" -version = "0.9.3" +version = "0.9.4" requires_python = ">=3.7" summary = "An extremely fast Python linter and code formatter, written in Rust." groups = ["dev"] files = [ - {file = "ruff-0.9.3-py3-none-linux_armv6l.whl", hash = "sha256:7f39b879064c7d9670197d91124a75d118d00b0990586549949aae80cdc16624"}, - {file = "ruff-0.9.3-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:a187171e7c09efa4b4cc30ee5d0d55a8d6c5311b3e1b74ac5cb96cc89bafc43c"}, - {file = "ruff-0.9.3-py3-none-macosx_11_0_arm64.whl", hash = "sha256:c59ab92f8e92d6725b7ded9d4a31be3ef42688a115c6d3da9457a5bda140e2b4"}, - {file = "ruff-0.9.3-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2dc153c25e715be41bb228bc651c1e9b1a88d5c6e5ed0194fa0dfea02b026439"}, - {file = "ruff-0.9.3-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:646909a1e25e0dc28fbc529eab8eb7bb583079628e8cbe738192853dbbe43af5"}, - {file = "ruff-0.9.3-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:5a5a46e09355695fbdbb30ed9889d6cf1c61b77b700a9fafc21b41f097bfbba4"}, - {file = "ruff-0.9.3-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:c4bb09d2bbb394e3730d0918c00276e79b2de70ec2a5231cd4ebb51a57df9ba1"}, - {file = "ruff-0.9.3-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:96a87ec31dc1044d8c2da2ebbed1c456d9b561e7d087734336518181b26b3aa5"}, - {file = "ruff-0.9.3-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:9bb7554aca6f842645022fe2d301c264e6925baa708b392867b7a62645304df4"}, - {file = "ruff-0.9.3-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:cabc332b7075a914ecea912cd1f3d4370489c8018f2c945a30bcc934e3bc06a6"}, - {file = "ruff-0.9.3-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:33866c3cc2a575cbd546f2cd02bdd466fed65118e4365ee538a3deffd6fcb730"}, - {file = "ruff-0.9.3-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:006e5de2621304c8810bcd2ee101587712fa93b4f955ed0985907a36c427e0c2"}, - {file = "ruff-0.9.3-py3-none-musllinux_1_2_i686.whl", hash = "sha256:ba6eea4459dbd6b1be4e6bfc766079fb9b8dd2e5a35aff6baee4d9b1514ea519"}, - {file = "ruff-0.9.3-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:90230a6b8055ad47d3325e9ee8f8a9ae7e273078a66401ac66df68943ced029b"}, - {file = "ruff-0.9.3-py3-none-win32.whl", hash = "sha256:eabe5eb2c19a42f4808c03b82bd313fc84d4e395133fb3fc1b1516170a31213c"}, - {file = "ruff-0.9.3-py3-none-win_amd64.whl", hash = "sha256:040ceb7f20791dfa0e78b4230ee9dce23da3b64dd5848e40e3bf3ab76468dcf4"}, - {file = "ruff-0.9.3-py3-none-win_arm64.whl", hash = "sha256:800d773f6d4d33b0a3c60e2c6ae8f4c202ea2de056365acfa519aa48acf28e0b"}, - {file = "ruff-0.9.3.tar.gz", hash = "sha256:8293f89985a090ebc3ed1064df31f3b4b56320cdfcec8b60d3295bddb955c22a"}, + {file = "ruff-0.9.4-py3-none-linux_armv6l.whl", hash = "sha256:64e73d25b954f71ff100bb70f39f1ee09e880728efb4250c632ceed4e4cdf706"}, + {file = "ruff-0.9.4-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:6ce6743ed64d9afab4fafeaea70d3631b4d4b28b592db21a5c2d1f0ef52934bf"}, + {file = "ruff-0.9.4-py3-none-macosx_11_0_arm64.whl", hash = "sha256:54499fb08408e32b57360f6f9de7157a5fec24ad79cb3f42ef2c3f3f728dfe2b"}, + {file = "ruff-0.9.4-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:37c892540108314a6f01f105040b5106aeb829fa5fb0561d2dcaf71485021137"}, + {file = "ruff-0.9.4-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:de9edf2ce4b9ddf43fd93e20ef635a900e25f622f87ed6e3047a664d0e8f810e"}, + {file = "ruff-0.9.4-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:87c90c32357c74f11deb7fbb065126d91771b207bf9bfaaee01277ca59b574ec"}, + {file = "ruff-0.9.4-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:56acd6c694da3695a7461cc55775f3a409c3815ac467279dfa126061d84b314b"}, + {file = "ruff-0.9.4-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e0c93e7d47ed951b9394cf352d6695b31498e68fd5782d6cbc282425655f687a"}, + {file = "ruff-0.9.4-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:1d4c8772670aecf037d1bf7a07c39106574d143b26cfe5ed1787d2f31e800214"}, + {file = "ruff-0.9.4-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bfc5f1d7afeda8d5d37660eeca6d389b142d7f2b5a1ab659d9214ebd0e025231"}, + {file = "ruff-0.9.4-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:faa935fc00ae854d8b638c16a5f1ce881bc3f67446957dd6f2af440a5fc8526b"}, + {file = "ruff-0.9.4-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:a6c634fc6f5a0ceae1ab3e13c58183978185d131a29c425e4eaa9f40afe1e6d6"}, + {file = "ruff-0.9.4-py3-none-musllinux_1_2_i686.whl", hash = "sha256:433dedf6ddfdec7f1ac7575ec1eb9844fa60c4c8c2f8887a070672b8d353d34c"}, + {file = "ruff-0.9.4-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:d612dbd0f3a919a8cc1d12037168bfa536862066808960e0cc901404b77968f0"}, + {file = "ruff-0.9.4-py3-none-win32.whl", hash = "sha256:db1192ddda2200671f9ef61d9597fcef89d934f5d1705e571a93a67fb13a4402"}, + {file = "ruff-0.9.4-py3-none-win_amd64.whl", hash = "sha256:05bebf4cdbe3ef75430d26c375773978950bbf4ee3c95ccb5448940dc092408e"}, + {file = "ruff-0.9.4-py3-none-win_arm64.whl", hash = "sha256:585792f1e81509e38ac5123492f8875fbc36f3ede8185af0a26df348e5154f41"}, + {file = "ruff-0.9.4.tar.gz", hash = "sha256:6907ee3529244bb0ed066683e075f09285b38dd5b4039370df6ff06041ca19e7"}, ] [[package]] diff --git a/src/start.py b/src/start.py index 71b6c02..9c9bfda 100644 --- a/src/start.py +++ b/src/start.py @@ -76,14 +76,12 @@ def __init__( logger.debug("", exc_info=e) -def load_extensions() -> ( - tuple[ - "FunctionlistType", - "FunctionlistType", - "FunctionlistType", - "list[ExtensionTranslation]", - ] -): +def load_extensions() -> tuple[ + "FunctionlistType", + "FunctionlistType", + "FunctionlistType", + "list[ExtensionTranslation]", +]: """Load extensions from the extensions directory. Returns: diff --git a/src/utils/extensions.py b/src/utils/extensions.py index 2e2bcd3..acd5688 100644 --- a/src/utils/extensions.py +++ b/src/utils/extensions.py @@ -30,12 +30,13 @@ def check_typing(module: ModuleType, func: Callable, types: dict[str, Any]) -> N def check_func(module: ModuleType, func: Callable, max_args: int, types: dict[str, Any]) -> None: assert callable(func), f"Function {func.__name__} of module {module.__name__} is not callable" signature = inspect.signature(func) - assert ( - len(signature.parameters) <= max_args - ), f"Function {func.__name__} of module {module.__name__} has too many arguments" - assert all( - param in types for param in signature.parameters - ), f"Function {func.__name__} of module {module.__name__} does not accept the correct arguments ({', '.join(types.keys())})" # noqa: E501 + assert len(signature.parameters) <= max_args, ( + f"Function {func.__name__} of module {module.__name__} has too many arguments" + ) + assert all(param in types for param in signature.parameters), ( + f"Function {func.__name__} of module {module.__name__} does not accept the correct arguments" + "({', '.join(types.keys())})" + ) # check_typing(module, func, types) # temporarily disabled due to unwanted behavior # noqa: ERA001 @@ -73,9 +74,9 @@ def validate_module(module: ModuleType, config: dict[str, Any] | None = None) -> module.default, dict, ), f"Extension {module.__name__} has a default configuration of type {type(module.default)} instead of dict" - assert ( - "enabled" in module.default - ), f"Extension {module.__name__} does not have an enabled key in its default configuration" + assert "enabled" in module.default, ( + f"Extension {module.__name__} does not have an enabled key in its default configuration" + ) if hasattr(module, "schema"): assert isinstance( module.schema, From f93dbbdddde69f8e0c93c38541d46fadbe03dba3 Mon Sep 17 00:00:00 2001 From: Paillat Date: Sun, 2 Feb 2025 12:59:19 +0100 Subject: [PATCH 53/61] =?UTF-8?q?=F0=9F=94=92=20Fix=20update=20dependencie?= =?UTF-8?q?s=20workflow=20to=20prevent=20force-pushing=20to=20unrelated=20?= =?UTF-8?q?branches=20(#78)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: openhands --- .github/workflows/update_dependencies.yaml | 58 +++++++++++++++------- 1 file changed, 40 insertions(+), 18 deletions(-) diff --git a/.github/workflows/update_dependencies.yaml b/.github/workflows/update_dependencies.yaml index 084585b..e3d7724 100644 --- a/.github/workflows/update_dependencies.yaml +++ b/.github/workflows/update_dependencies.yaml @@ -56,38 +56,60 @@ jobs: git config user.name github-actions git config user.email github-actions@github.com + # Function to commit changes + commit_changes() { + git add requirements.txt pyproject.toml pdm.lock + git commit -m "Update dependencies" + } + + # Function to create PR + create_pr() { + local BRANCH=$1 + gh pr create \ + --title "Update dependencies" \ + --body "This PR updates the project dependencies. Please review the changes and merge if everything looks good." \ + --base ${{ github.ref_name }} \ + --head $BRANCH \ + --label "automated-dependencies-update" + } + if [ -n "${{ inputs.pr_branch }}" ]; then # Push to existing branch BRANCH_NAME=$(echo ${{ inputs.pr_branch }} | cut -d'/' -f 3) git checkout $BRANCH_NAME - git add requirements.txt pyproject.toml pdm.lock - git commit -m "Update dependencies" + commit_changes git push origin $BRANCH_NAME else - # Check for existing PR - EXISTING_PR=$(gh pr list --search "Update dependencies in:title is:open" --json headRefName,number -q '.[0]') + # Check for existing PR - strict search for exact title and our specific branch pattern + EXISTING_PR=$(gh pr list --search "in:title Update dependencies is:open label:automated-dependencies-update" --json headRefName,number,author -q '.[0]') if [ -n "$EXISTING_PR" ]; then - # Update existing PR + # Multiple validation checks before using an existing branch BRANCH_NAME=$(echo $EXISTING_PR | jq -r .headRefName) - git checkout -B $BRANCH_NAME - git add requirements.txt pyproject.toml pdm.lock - git commit -m "Update dependencies" - git push -f origin $BRANCH_NAME + PR_AUTHOR=$(echo $EXISTING_PR | jq -r .author.login) + + if [[ "$PR_AUTHOR" == "github-actions[bot]" && "$BRANCH_NAME" == update-dependencies-* ]]; then + echo "Found valid PR with branch $BRANCH_NAME by github-actions[bot]. Updating it." + git checkout -B $BRANCH_NAME + commit_changes + git push -f origin $BRANCH_NAME + else + echo "Found PR but it's not from our bot or wrong branch pattern. Creating new branch." + NEW_BRANCH="update-dependencies-${{ github.run_id }}" + git checkout -b $NEW_BRANCH + commit_changes + git push origin $NEW_BRANCH + create_pr $NEW_BRANCH + fi else - # Create new branch and PR + echo "No existing PR found. Creating new branch and PR." NEW_BRANCH="update-dependencies-${{ github.run_id }}" git checkout -b $NEW_BRANCH - git add requirements.txt pyproject.toml pdm.lock - git commit -m "Update dependencies" + commit_changes git push origin $NEW_BRANCH - - gh pr create \ - --title "Update dependencies" \ - --body "This PR updates the project dependencies. Please review the changes and merge if everything looks good." \ - --base ${{ github.ref_name }} \ - --head $NEW_BRANCH + create_pr $NEW_BRANCH fi fi + fi env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} \ No newline at end of file From 1cddf10b84aa3d71d896491c77d6f679ca99a1e3 Mon Sep 17 00:00:00 2001 From: Paillat Date: Sun, 2 Feb 2025 13:02:33 +0100 Subject: [PATCH 54/61] =?UTF-8?q?=E2=9C=A8=20Add=20automatic=20creation=20?= =?UTF-8?q?of=20dependencies=20update=20label=20(#79)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: openhands --- .github/workflows/update_dependencies.yaml | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/.github/workflows/update_dependencies.yaml b/.github/workflows/update_dependencies.yaml index e3d7724..94a2b7b 100644 --- a/.github/workflows/update_dependencies.yaml +++ b/.github/workflows/update_dependencies.yaml @@ -50,6 +50,19 @@ jobs: run: | git diff --exit-code --quiet requirements.txt || echo "changed=true" >> $GITHUB_OUTPUT + - name: Create required label if not exists + run: | + # Check if label exists + LABEL_EXISTS=$(gh label list | grep "automated-dependencies-update" || true) + if [ -z "$LABEL_EXISTS" ]; then + echo "Creating automated-dependencies-update label..." + gh label create "automated-dependencies-update" \ + --color "2DA44E" \ + --description "Automated PR for updating project dependencies" + fi + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + - name: Handle dependency updates if: steps.git-check.outputs.changed == 'true' run: | From 458753ef0b7c5cd9aa5ce40b35a1f91a9f292e3f Mon Sep 17 00:00:00 2001 From: Paillat Date: Sun, 2 Feb 2025 13:08:03 +0100 Subject: [PATCH 55/61] =?UTF-8?q?=F0=9F=90=9B=20Remove=20extra=20fi=20in?= =?UTF-8?q?=20update=20dependencies=20workflow=20(#82)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: openhands --- .github/workflows/update_dependencies.yaml | 1 - 1 file changed, 1 deletion(-) diff --git a/.github/workflows/update_dependencies.yaml b/.github/workflows/update_dependencies.yaml index 94a2b7b..e080a69 100644 --- a/.github/workflows/update_dependencies.yaml +++ b/.github/workflows/update_dependencies.yaml @@ -123,6 +123,5 @@ jobs: create_pr $NEW_BRANCH fi fi - fi env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} \ No newline at end of file From 1909e950943d2f8cb58ebf3e24374fb951afff13 Mon Sep 17 00:00:00 2001 From: Paillat Date: Sun, 2 Feb 2025 13:22:49 +0100 Subject: [PATCH 56/61] =?UTF-8?q?=E2=99=BB=EF=B8=8F=20Simplify=20update=20?= =?UTF-8?q?dependencies=20workflow=20checks=20(#85)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: openhands --- .github/workflows/update_dependencies.yaml | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/.github/workflows/update_dependencies.yaml b/.github/workflows/update_dependencies.yaml index e080a69..8c9c96d 100644 --- a/.github/workflows/update_dependencies.yaml +++ b/.github/workflows/update_dependencies.yaml @@ -97,17 +97,16 @@ jobs: EXISTING_PR=$(gh pr list --search "in:title Update dependencies is:open label:automated-dependencies-update" --json headRefName,number,author -q '.[0]') if [ -n "$EXISTING_PR" ]; then - # Multiple validation checks before using an existing branch + # Check if PR has our automation label BRANCH_NAME=$(echo $EXISTING_PR | jq -r .headRefName) - PR_AUTHOR=$(echo $EXISTING_PR | jq -r .author.login) - if [[ "$PR_AUTHOR" == "github-actions[bot]" && "$BRANCH_NAME" == update-dependencies-* ]]; then - echo "Found valid PR with branch $BRANCH_NAME by github-actions[bot]. Updating it." + if [[ "$BRANCH_NAME" == update-dependencies-* ]]; then + echo "Found valid automated PR with branch $BRANCH_NAME. Updating it." git checkout -B $BRANCH_NAME commit_changes git push -f origin $BRANCH_NAME else - echo "Found PR but it's not from our bot or wrong branch pattern. Creating new branch." + echo "Found PR but wrong branch pattern. Creating new branch." NEW_BRANCH="update-dependencies-${{ github.run_id }}" git checkout -b $NEW_BRANCH commit_changes From dcd20e82cf49e644879950fd380408e6782e58aa Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Sun, 2 Feb 2025 13:25:01 +0100 Subject: [PATCH 57/61] Update dependencies (#83) Co-authored-by: github-actions --- pdm.lock | 1 + requirements.txt | 18 +++++++++--------- 2 files changed, 10 insertions(+), 9 deletions(-) diff --git a/pdm.lock b/pdm.lock index d5e6179..42ce45a 100644 --- a/pdm.lock +++ b/pdm.lock @@ -446,6 +446,7 @@ dependencies = [ ] files = [ {file = "h2-4.2.0-py3-none-any.whl", hash = "sha256:479a53ad425bb29af087f3458a61d30780bc818e4ebcf01f0b536ba916462ed0"}, + {file = "h2-4.2.0.tar.gz", hash = "sha256:c8a52129695e88b1a0578d8d2cc6842bbd79128ac685463b887ee278126ad01f"}, ] [[package]] diff --git a/requirements.txt b/requirements.txt index 5a81c98..1912ec9 100644 --- a/requirements.txt +++ b/requirements.txt @@ -70,9 +70,9 @@ caio==0.9.21 \ --hash=sha256:4f1d30ad0f975de07b4a3ae1cd2e9275fa574f2ca0b49ba5ab16208575650a92 \ --hash=sha256:e7314a28d69a0397d1d0ac6c7bfe7973f27f4f7216cf42b0358d7d9ba27bc4cd \ --hash=sha256:fdab8c817b6835d997db1532ce7d9f5cbe186265bf0ee9a9840b378aa4a1cba7 -certifi==2024.12.14 \ - --hash=sha256:1275f7a45be9464efc1173084eaa30f866fe2e47d389406136d332ed4967ec56 \ - --hash=sha256:b650d30f370c2b724812bee08008be0c4163b163ddaec3f2546c1caf65f191db +certifi==2025.1.31 \ + --hash=sha256:3d5da6925056f6f18f119200434a4780a94263f10d1c21d032a6f6b2baa20651 \ + --hash=sha256:ca78db4565a652026a4db2bcdf68f2fb589ea80d0be70e03929ed730746b84fe click==8.1.8 \ --hash=sha256:63c132bbbed01578a06712a2d1f497bb62d9c1c0d329b7903a866228027263b2 \ --hash=sha256:ed53c9d8990d83c2a27deae68e4ee337473f6330c040a31d4225c9574d16096a @@ -109,9 +109,9 @@ frozenlist==1.5.0 \ h11==0.14.0 \ --hash=sha256:8f19fbbe99e72420ff35c00b27a34cb9937e902a8b810e2c88300c6f0a3b699d \ --hash=sha256:e3fe4ac4b851c468cc8363d500db52c2ead036020723024a109d37346efaa761 -h2==4.1.0 \ - --hash=sha256:03a46bcf682256c95b5fd9e9a99c1323584c3eec6440d379b9903d709476bc6d \ - --hash=sha256:a83aca08fbe7aacb79fec788c9c0bac936343560ed9ec18b82a13a12c28d2abb +h2==4.2.0 \ + --hash=sha256:479a53ad425bb29af087f3458a61d30780bc818e4ebcf01f0b536ba916462ed0 \ + --hash=sha256:c8a52129695e88b1a0578d8d2cc6842bbd79128ac685463b887ee278126ad01f hpack==4.1.0 \ --hash=sha256:157ac792668d995c657d93111f46b4535ed114f0c9c8d672271bbec7eae1b496 \ --hash=sha256:ec5eca154f7056aa06f196a557655c5b009b382873ac8d1e66e79e87535f1dca @@ -234,9 +234,9 @@ pyreadline3==3.5.4; sys_platform == "win32" and python_version >= "3.8" \ python-dotenv==1.0.1 \ --hash=sha256:e324ee90a023d808f1959c46bcbc04446a10ced277783dc6ee09987c37ec10ca \ --hash=sha256:f7b63ef50f1b690dddf550d03497b66d609393b40b564ed0d674909a68ebf16a -pytz==2024.2 \ - --hash=sha256:2aa355083c50a0f93fa581709deac0c9ad65cca8a9e9beac660adcbd493c798a \ - --hash=sha256:31c7c1817eb7fae7ca4b8c7ee50c72f93aa2dd863de768e1ef4245d426aa0725 +pytz==2025.1 \ + --hash=sha256:89dd22dca55b46eac6eda23b2d72721bf1bdfef212645d81513ef5d03038de57 \ + --hash=sha256:c2db42be2a2518b28e65f9207c4d05e6ff547d1efa4086469ef855e4ab70178e pyyaml==6.0.2 \ --hash=sha256:0833f8694549e586547b576dcfaba4a6b55b9e96098b36cdc7ebefe667dfed48 \ --hash=sha256:1f71ea527786de97d1a0cc0eacd1defc0985dcf6b3f17bb77dcfc8c34bec4dc5 \ From b628bc2771860e46f211e0295b64a6ff1c59d7fc Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 20 Feb 2025 20:22:07 +0100 Subject: [PATCH 58/61] =?UTF-8?q?=E2=AC=86=EF=B8=8F=20Upgrade=20docker/bui?= =?UTF-8?q?ld-push-action=20action=20to=20v6.14.0=20(#88)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- .github/workflows/docker.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/docker.yaml b/.github/workflows/docker.yaml index 10d9382..a8887a7 100644 --- a/.github/workflows/docker.yaml +++ b/.github/workflows/docker.yaml @@ -39,7 +39,7 @@ jobs: type=sha - name: Build and push Docker image - uses: docker/build-push-action@v6.13.0 + uses: docker/build-push-action@v6.14.0 with: context: . push: true From 13ffcb5a31afebfa2af03d4922f090b797bf9904 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 20 Feb 2025 20:22:21 +0100 Subject: [PATCH 59/61] =?UTF-8?q?=E2=AC=86=EF=B8=8F=20Upgrade=20docker/set?= =?UTF-8?q?up-buildx-action=20action=20to=20v3.9.0=20(#86)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- .github/workflows/docker.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/docker.yaml b/.github/workflows/docker.yaml index a8887a7..1cbcd1e 100644 --- a/.github/workflows/docker.yaml +++ b/.github/workflows/docker.yaml @@ -18,7 +18,7 @@ jobs: uses: actions/checkout@v4 - name: Set up Docker Buildx - uses: docker/setup-buildx-action@v3.8.0 + uses: docker/setup-buildx-action@v3.9.0 - name: Log into registry ${{ env.REGISTRY }} uses: docker/login-action@v3.3.0 From 636d07a222fc7c486df29d099abb61611f0d6dd0 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Thu, 20 Feb 2025 20:22:34 +0100 Subject: [PATCH 60/61] Update dependencies (#87) Co-authored-by: github-actions --- pdm.lock | 124 ++++++++++++++++++++++++----------------------- requirements.txt | 47 +++++++++--------- 2 files changed, 87 insertions(+), 84 deletions(-) diff --git a/pdm.lock b/pdm.lock index 42ce45a..729510e 100644 --- a/pdm.lock +++ b/pdm.lock @@ -96,18 +96,18 @@ files = [ [[package]] name = "aiohappyeyeballs" -version = "2.4.4" -requires_python = ">=3.8" +version = "2.4.6" +requires_python = ">=3.9" summary = "Happy Eyeballs for asyncio" groups = ["default"] files = [ - {file = "aiohappyeyeballs-2.4.4-py3-none-any.whl", hash = "sha256:a980909d50efcd44795c4afeca523296716d50cd756ddca6af8c65b996e27de8"}, - {file = "aiohappyeyeballs-2.4.4.tar.gz", hash = "sha256:5fdd7d87889c63183afc18ce9271f9b0a7d32c2303e394468dd45d514a757745"}, + {file = "aiohappyeyeballs-2.4.6-py3-none-any.whl", hash = "sha256:147ec992cf873d74f5062644332c539fcd42956dc69453fe5204195e560517e1"}, + {file = "aiohappyeyeballs-2.4.6.tar.gz", hash = "sha256:9b05052f9042985d32ecbe4b59a77ae19c006a78f1344d7fdad69d28ded3d0b0"}, ] [[package]] name = "aiohttp" -version = "3.11.11" +version = "3.11.12" requires_python = ">=3.9" summary = "Async http client/server framework (asyncio)" groups = ["default"] @@ -122,22 +122,23 @@ dependencies = [ "yarl<2.0,>=1.17.0", ] files = [ - {file = "aiohttp-3.11.11-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:e595c591a48bbc295ebf47cb91aebf9bd32f3ff76749ecf282ea7f9f6bb73886"}, - {file = "aiohttp-3.11.11-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:3ea1b59dc06396b0b424740a10a0a63974c725b1c64736ff788a3689d36c02d2"}, - {file = "aiohttp-3.11.11-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:8811f3f098a78ffa16e0ea36dffd577eb031aea797cbdba81be039a4169e242c"}, - {file = "aiohttp-3.11.11-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bd7227b87a355ce1f4bf83bfae4399b1f5bb42e0259cb9405824bd03d2f4336a"}, - {file = "aiohttp-3.11.11-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d40f9da8cabbf295d3a9dae1295c69975b86d941bc20f0a087f0477fa0a66231"}, - {file = "aiohttp-3.11.11-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:ffb3dc385f6bb1568aa974fe65da84723210e5d9707e360e9ecb51f59406cd2e"}, - {file = "aiohttp-3.11.11-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a8f5f7515f3552d899c61202d99dcb17d6e3b0de777900405611cd747cecd1b8"}, - {file = "aiohttp-3.11.11-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:3499c7ffbfd9c6a3d8d6a2b01c26639da7e43d47c7b4f788016226b1e711caa8"}, - {file = "aiohttp-3.11.11-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:8e2bf8029dbf0810c7bfbc3e594b51c4cc9101fbffb583a3923aea184724203c"}, - {file = "aiohttp-3.11.11-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:b6212a60e5c482ef90f2d788835387070a88d52cf6241d3916733c9176d39eab"}, - {file = "aiohttp-3.11.11-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:d119fafe7b634dbfa25a8c597718e69a930e4847f0b88e172744be24515140da"}, - {file = "aiohttp-3.11.11-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:6fba278063559acc730abf49845d0e9a9e1ba74f85f0ee6efd5803f08b285853"}, - {file = "aiohttp-3.11.11-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:92fc484e34b733704ad77210c7957679c5c3877bd1e6b6d74b185e9320cc716e"}, - {file = "aiohttp-3.11.11-cp312-cp312-win32.whl", hash = "sha256:9f5b3c1ed63c8fa937a920b6c1bec78b74ee09593b3f5b979ab2ae5ef60d7600"}, - {file = "aiohttp-3.11.11-cp312-cp312-win_amd64.whl", hash = "sha256:1e69966ea6ef0c14ee53ef7a3d68b564cc408121ea56c0caa2dc918c1b2f553d"}, - {file = "aiohttp-3.11.11.tar.gz", hash = "sha256:bb49c7f1e6ebf3821a42d81d494f538107610c3a705987f53068546b0e90303e"}, + {file = "aiohttp-3.11.12-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:e392804a38353900c3fd8b7cacbea5132888f7129f8e241915e90b85f00e3250"}, + {file = "aiohttp-3.11.12-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:8fa1510b96c08aaad49303ab11f8803787c99222288f310a62f493faf883ede1"}, + {file = "aiohttp-3.11.12-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:dc065a4285307607df3f3686363e7f8bdd0d8ab35f12226362a847731516e42c"}, + {file = "aiohttp-3.11.12-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:cddb31f8474695cd61fc9455c644fc1606c164b93bff2490390d90464b4655df"}, + {file = "aiohttp-3.11.12-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:9dec0000d2d8621d8015c293e24589d46fa218637d820894cb7356c77eca3259"}, + {file = "aiohttp-3.11.12-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e3552fe98e90fdf5918c04769f338a87fa4f00f3b28830ea9b78b1bdc6140e0d"}, + {file = "aiohttp-3.11.12-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6dfe7f984f28a8ae94ff3a7953cd9678550dbd2a1f9bda5dd9c5ae627744c78e"}, + {file = "aiohttp-3.11.12-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a481a574af914b6e84624412666cbfbe531a05667ca197804ecc19c97b8ab1b0"}, + {file = "aiohttp-3.11.12-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:1987770fb4887560363b0e1a9b75aa303e447433c41284d3af2840a2f226d6e0"}, + {file = "aiohttp-3.11.12-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:a4ac6a0f0f6402854adca4e3259a623f5c82ec3f0c049374133bcb243132baf9"}, + {file = "aiohttp-3.11.12-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:c96a43822f1f9f69cc5c3706af33239489a6294be486a0447fb71380070d4d5f"}, + {file = "aiohttp-3.11.12-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:a5e69046f83c0d3cb8f0d5bd9b8838271b1bc898e01562a04398e160953e8eb9"}, + {file = "aiohttp-3.11.12-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:68d54234c8d76d8ef74744f9f9fc6324f1508129e23da8883771cdbb5818cbef"}, + {file = "aiohttp-3.11.12-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:c9fd9dcf9c91affe71654ef77426f5cf8489305e1c66ed4816f5a21874b094b9"}, + {file = "aiohttp-3.11.12-cp312-cp312-win32.whl", hash = "sha256:0ed49efcd0dc1611378beadbd97beb5d9ca8fe48579fc04a6ed0844072261b6a"}, + {file = "aiohttp-3.11.12-cp312-cp312-win_amd64.whl", hash = "sha256:54775858c7f2f214476773ce785a19ee81d1294a6bedc5cc17225355aab74802"}, + {file = "aiohttp-3.11.12.tar.gz", hash = "sha256:7603ca26d75b1b86160ce1bbe2787a0b706e592af5b2504e12caa88a217767b0"}, ] [[package]] @@ -249,7 +250,7 @@ files = [ [[package]] name = "basedpyright" -version = "1.26.0" +version = "1.27.1" requires_python = ">=3.8" summary = "static type checking for Python (but based)" groups = ["dev"] @@ -257,22 +258,23 @@ dependencies = [ "nodejs-wheel-binaries>=20.13.1", ] files = [ - {file = "basedpyright-1.26.0-py3-none-any.whl", hash = "sha256:5a6a17f2c389ec313dd2c3644f40e8221bc90252164802e626055341c0a37381"}, - {file = "basedpyright-1.26.0.tar.gz", hash = "sha256:5e01f6eb9290a09ef39672106cf1a02924fdc8970e521838bc502ccf0676f32f"}, + {file = "basedpyright-1.27.1-py3-none-any.whl", hash = "sha256:9f3647c1c8a0fc3d0a08b2156768ff717322f1e78d1b45686597093824a8f0d3"}, + {file = "basedpyright-1.27.1.tar.gz", hash = "sha256:ddbe226c154c973a954626ce9ecb3b3a59df9d68bbab0e3f82a6c2c7b29616df"}, ] [[package]] name = "beautifulsoup4" -version = "4.12.3" -requires_python = ">=3.6.0" +version = "4.13.3" +requires_python = ">=3.7.0" summary = "Screen-scraping library" groups = ["dev"] dependencies = [ "soupsieve>1.2", + "typing-extensions>=4.0.0", ] files = [ - {file = "beautifulsoup4-4.12.3-py3-none-any.whl", hash = "sha256:b80878c9f40111313e55da8ba20bdba06d8fa3969fc68304167741bbf9e082ed"}, - {file = "beautifulsoup4-4.12.3.tar.gz", hash = "sha256:74e3d1928edc070d21748185c46e3fb33490f22f52a3addee9aee0f4f7781051"}, + {file = "beautifulsoup4-4.13.3-py3-none-any.whl", hash = "sha256:99045d7d3f08f91f0d656bc9b7efbae189426cd913d830294a15eefa0ea4df16"}, + {file = "beautifulsoup4-4.13.3.tar.gz", hash = "sha256:1bd32405dacc920b42b83ba01644747ed77456a65760e285fbc47633ceddaf8b"}, ] [[package]] @@ -642,7 +644,7 @@ files = [ [[package]] name = "nodejs-wheel-binaries" -version = "22.13.1" +version = "22.14.0" requires_python = ">=3.7" summary = "unoffical Node.js package" groups = ["dev"] @@ -650,15 +652,15 @@ dependencies = [ "typing-extensions; python_version < \"3.8\"", ] files = [ - {file = "nodejs_wheel_binaries-22.13.1-py2.py3-none-macosx_11_0_arm64.whl", hash = "sha256:e4f64d0e26600d51cbdd98a6718a19c2d1b8c7538e9e353e95a634a06a8e1a58"}, - {file = "nodejs_wheel_binaries-22.13.1-py2.py3-none-macosx_11_0_x86_64.whl", hash = "sha256:afcb40484bb02f23137f838014724604ae183fd767b30da95b0be1510a40c06d"}, - {file = "nodejs_wheel_binaries-22.13.1-py2.py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4fc88c98eebabfc36b5270a4ab974a2682746931567ca76a5ca49c54482bbb51"}, - {file = "nodejs_wheel_binaries-22.13.1-py2.py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8b9f75ea8f5e3e5416256fcb00a98cbe14c8d3b6dcaf17da29c4ade5723026d8"}, - {file = "nodejs_wheel_binaries-22.13.1-py2.py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:94608702ef6c389d32e89ff3b7a925cb5dedaf55b5d98bd0c4fb3450a8b6d1c1"}, - {file = "nodejs_wheel_binaries-22.13.1-py2.py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:53a40d0269689aa2eaf2e261cbe5ec256644bc56aae0201ef344b7d8f40ccc79"}, - {file = "nodejs_wheel_binaries-22.13.1-py2.py3-none-win_amd64.whl", hash = "sha256:549371a929a29fbce8d0ab8f1b5410549946d4f1b0376a5ce635b45f6d05298f"}, - {file = "nodejs_wheel_binaries-22.13.1-py2.py3-none-win_arm64.whl", hash = "sha256:cf72d50d755f4e5c0709b0449de01768d96b3b1ec7aa531561415b88f179ad8b"}, - {file = "nodejs_wheel_binaries-22.13.1.tar.gz", hash = "sha256:a0c15213c9c3383541be4400a30959883868ce5da9cebb3d63ddc7fe61459308"}, + {file = "nodejs_wheel_binaries-22.14.0-py2.py3-none-macosx_11_0_arm64.whl", hash = "sha256:d8ab8690516a3e98458041286e3f0d6458de176d15c14f205c3ea2972131420d"}, + {file = "nodejs_wheel_binaries-22.14.0-py2.py3-none-macosx_11_0_x86_64.whl", hash = "sha256:b2f200f23b3610bdbee01cf136279e005ffdf8ee74557aa46c0940a7867956f6"}, + {file = "nodejs_wheel_binaries-22.14.0-py2.py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d0877832abd7a9c75c8c5caafa37f986c9341ee025043c2771213d70c4c1defa"}, + {file = "nodejs_wheel_binaries-22.14.0-py2.py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8fded5a70a8a55c2135e67bd580d8b7f2e94fcbafcc679b6a2d5b92f88373d69"}, + {file = "nodejs_wheel_binaries-22.14.0-py2.py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:c1ade6f3ece458b40c02e89c91d5103792a9f18aaad5026da533eb0dcb87090e"}, + {file = "nodejs_wheel_binaries-22.14.0-py2.py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:34fa5ed4cf3f65cbfbe9b45c407ffc2fc7d97a06cd8993e6162191ff81f29f48"}, + {file = "nodejs_wheel_binaries-22.14.0-py2.py3-none-win_amd64.whl", hash = "sha256:ca7023276327455988b81390fa6bbfa5191c1da7fc45bc57c7abc281ba9967e9"}, + {file = "nodejs_wheel_binaries-22.14.0-py2.py3-none-win_arm64.whl", hash = "sha256:fd59c8e9a202221e316febe1624a1ae3b42775b7fb27737bf12ec79565983eaf"}, + {file = "nodejs_wheel_binaries-22.14.0.tar.gz", hash = "sha256:c1dc43713598c7310d53795c764beead861b8c5021fe4b1366cb912ce1a4c8bf"}, ] [[package]] @@ -940,29 +942,29 @@ files = [ [[package]] name = "ruff" -version = "0.9.4" +version = "0.9.6" requires_python = ">=3.7" summary = "An extremely fast Python linter and code formatter, written in Rust." groups = ["dev"] files = [ - {file = "ruff-0.9.4-py3-none-linux_armv6l.whl", hash = "sha256:64e73d25b954f71ff100bb70f39f1ee09e880728efb4250c632ceed4e4cdf706"}, - {file = "ruff-0.9.4-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:6ce6743ed64d9afab4fafeaea70d3631b4d4b28b592db21a5c2d1f0ef52934bf"}, - {file = "ruff-0.9.4-py3-none-macosx_11_0_arm64.whl", hash = "sha256:54499fb08408e32b57360f6f9de7157a5fec24ad79cb3f42ef2c3f3f728dfe2b"}, - {file = "ruff-0.9.4-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:37c892540108314a6f01f105040b5106aeb829fa5fb0561d2dcaf71485021137"}, - {file = "ruff-0.9.4-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:de9edf2ce4b9ddf43fd93e20ef635a900e25f622f87ed6e3047a664d0e8f810e"}, - {file = "ruff-0.9.4-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:87c90c32357c74f11deb7fbb065126d91771b207bf9bfaaee01277ca59b574ec"}, - {file = "ruff-0.9.4-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:56acd6c694da3695a7461cc55775f3a409c3815ac467279dfa126061d84b314b"}, - {file = "ruff-0.9.4-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e0c93e7d47ed951b9394cf352d6695b31498e68fd5782d6cbc282425655f687a"}, - {file = "ruff-0.9.4-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:1d4c8772670aecf037d1bf7a07c39106574d143b26cfe5ed1787d2f31e800214"}, - {file = "ruff-0.9.4-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bfc5f1d7afeda8d5d37660eeca6d389b142d7f2b5a1ab659d9214ebd0e025231"}, - {file = "ruff-0.9.4-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:faa935fc00ae854d8b638c16a5f1ce881bc3f67446957dd6f2af440a5fc8526b"}, - {file = "ruff-0.9.4-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:a6c634fc6f5a0ceae1ab3e13c58183978185d131a29c425e4eaa9f40afe1e6d6"}, - {file = "ruff-0.9.4-py3-none-musllinux_1_2_i686.whl", hash = "sha256:433dedf6ddfdec7f1ac7575ec1eb9844fa60c4c8c2f8887a070672b8d353d34c"}, - {file = "ruff-0.9.4-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:d612dbd0f3a919a8cc1d12037168bfa536862066808960e0cc901404b77968f0"}, - {file = "ruff-0.9.4-py3-none-win32.whl", hash = "sha256:db1192ddda2200671f9ef61d9597fcef89d934f5d1705e571a93a67fb13a4402"}, - {file = "ruff-0.9.4-py3-none-win_amd64.whl", hash = "sha256:05bebf4cdbe3ef75430d26c375773978950bbf4ee3c95ccb5448940dc092408e"}, - {file = "ruff-0.9.4-py3-none-win_arm64.whl", hash = "sha256:585792f1e81509e38ac5123492f8875fbc36f3ede8185af0a26df348e5154f41"}, - {file = "ruff-0.9.4.tar.gz", hash = "sha256:6907ee3529244bb0ed066683e075f09285b38dd5b4039370df6ff06041ca19e7"}, + {file = "ruff-0.9.6-py3-none-linux_armv6l.whl", hash = "sha256:2f218f356dd2d995839f1941322ff021c72a492c470f0b26a34f844c29cdf5ba"}, + {file = "ruff-0.9.6-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:b908ff4df65dad7b251c9968a2e4560836d8f5487c2f0cc238321ed951ea0504"}, + {file = "ruff-0.9.6-py3-none-macosx_11_0_arm64.whl", hash = "sha256:b109c0ad2ececf42e75fa99dc4043ff72a357436bb171900714a9ea581ddef83"}, + {file = "ruff-0.9.6-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1de4367cca3dac99bcbd15c161404e849bb0bfd543664db39232648dc00112dc"}, + {file = "ruff-0.9.6-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:ac3ee4d7c2c92ddfdaedf0bf31b2b176fa7aa8950efc454628d477394d35638b"}, + {file = "ruff-0.9.6-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:5dc1edd1775270e6aa2386119aea692039781429f0be1e0949ea5884e011aa8e"}, + {file = "ruff-0.9.6-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:4a091729086dffa4bd070aa5dab7e39cc6b9d62eb2bef8f3d91172d30d599666"}, + {file = "ruff-0.9.6-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d1bbc6808bf7b15796cef0815e1dfb796fbd383e7dbd4334709642649625e7c5"}, + {file = "ruff-0.9.6-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:589d1d9f25b5754ff230dce914a174a7c951a85a4e9270613a2b74231fdac2f5"}, + {file = "ruff-0.9.6-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dc61dd5131742e21103fbbdcad683a8813be0e3c204472d520d9a5021ca8b217"}, + {file = "ruff-0.9.6-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:5e2d9126161d0357e5c8f30b0bd6168d2c3872372f14481136d13de9937f79b6"}, + {file = "ruff-0.9.6-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:68660eab1a8e65babb5229a1f97b46e3120923757a68b5413d8561f8a85d4897"}, + {file = "ruff-0.9.6-py3-none-musllinux_1_2_i686.whl", hash = "sha256:c4cae6c4cc7b9b4017c71114115db0445b00a16de3bcde0946273e8392856f08"}, + {file = "ruff-0.9.6-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:19f505b643228b417c1111a2a536424ddde0db4ef9023b9e04a46ed8a1cb4656"}, + {file = "ruff-0.9.6-py3-none-win32.whl", hash = "sha256:194d8402bceef1b31164909540a597e0d913c0e4952015a5b40e28c146121b5d"}, + {file = "ruff-0.9.6-py3-none-win_amd64.whl", hash = "sha256:03482d5c09d90d4ee3f40d97578423698ad895c87314c4de39ed2af945633caa"}, + {file = "ruff-0.9.6-py3-none-win_arm64.whl", hash = "sha256:0e2bb706a2be7ddfea4a4af918562fdc1bcb16df255e5fa595bbd800ce322a5a"}, + {file = "ruff-0.9.6.tar.gz", hash = "sha256:81761592f72b620ec8fa1068a6fd00e98a5ebee342a3642efd84454f3031dca9"}, ] [[package]] @@ -980,7 +982,7 @@ files = [ [[package]] name = "sentry-sdk" -version = "2.20.0" +version = "2.21.0" requires_python = ">=3.6" summary = "Python client for Sentry (https://sentry.io)" groups = ["default"] @@ -989,8 +991,8 @@ dependencies = [ "urllib3>=1.26.11", ] files = [ - {file = "sentry_sdk-2.20.0-py2.py3-none-any.whl", hash = "sha256:c359a1edf950eb5e80cffd7d9111f3dbeef57994cb4415df37d39fda2cf22364"}, - {file = "sentry_sdk-2.20.0.tar.gz", hash = "sha256:afa82713a92facf847df3c6f63cec71eb488d826a50965def3d7722aa6f0fdab"}, + {file = "sentry_sdk-2.21.0-py2.py3-none-any.whl", hash = "sha256:7623cfa9e2c8150948a81ca253b8e2bfe4ce0b96ab12f8cd78e3ac9c490fd92f"}, + {file = "sentry_sdk-2.21.0.tar.gz", hash = "sha256:a6d38e0fb35edda191acf80b188ec713c863aaa5ad8d5798decb8671d02077b6"}, ] [[package]] @@ -1076,7 +1078,7 @@ name = "typing-extensions" version = "4.12.2" requires_python = ">=3.8" summary = "Backported and Experimental Type Hints for Python 3.8+" -groups = ["default"] +groups = ["default", "dev"] files = [ {file = "typing_extensions-4.12.2-py3-none-any.whl", hash = "sha256:04e5ca0351e0f3f85c6853954072df659d0d13fac324d0072316b67d7794700d"}, {file = "typing_extensions-4.12.2.tar.gz", hash = "sha256:1a7ead55c7e559dd4dee8856e3a88b41225abfe1ce8df57b7c13915fe121ffb8"}, diff --git a/requirements.txt b/requirements.txt index 1912ec9..72f1af8 100644 --- a/requirements.txt +++ b/requirements.txt @@ -13,26 +13,27 @@ aiofile==3.9.0 \ aiofiles==24.1.0 \ --hash=sha256:22a075c9e5a3810f0c2e48f3008c94d68c65d763b9b03857924c99e57355166c \ --hash=sha256:b4ec55f4195e3eb5d7abd1bf7e061763e864dd4954231fb8539a0ef8bb8260e5 -aiohappyeyeballs==2.4.4 \ - --hash=sha256:5fdd7d87889c63183afc18ce9271f9b0a7d32c2303e394468dd45d514a757745 \ - --hash=sha256:a980909d50efcd44795c4afeca523296716d50cd756ddca6af8c65b996e27de8 -aiohttp==3.11.11 \ - --hash=sha256:1e69966ea6ef0c14ee53ef7a3d68b564cc408121ea56c0caa2dc918c1b2f553d \ - --hash=sha256:3499c7ffbfd9c6a3d8d6a2b01c26639da7e43d47c7b4f788016226b1e711caa8 \ - --hash=sha256:3ea1b59dc06396b0b424740a10a0a63974c725b1c64736ff788a3689d36c02d2 \ - --hash=sha256:6fba278063559acc730abf49845d0e9a9e1ba74f85f0ee6efd5803f08b285853 \ - --hash=sha256:8811f3f098a78ffa16e0ea36dffd577eb031aea797cbdba81be039a4169e242c \ - --hash=sha256:8e2bf8029dbf0810c7bfbc3e594b51c4cc9101fbffb583a3923aea184724203c \ - --hash=sha256:92fc484e34b733704ad77210c7957679c5c3877bd1e6b6d74b185e9320cc716e \ - --hash=sha256:9f5b3c1ed63c8fa937a920b6c1bec78b74ee09593b3f5b979ab2ae5ef60d7600 \ - --hash=sha256:a8f5f7515f3552d899c61202d99dcb17d6e3b0de777900405611cd747cecd1b8 \ - --hash=sha256:b6212a60e5c482ef90f2d788835387070a88d52cf6241d3916733c9176d39eab \ - --hash=sha256:bb49c7f1e6ebf3821a42d81d494f538107610c3a705987f53068546b0e90303e \ - --hash=sha256:bd7227b87a355ce1f4bf83bfae4399b1f5bb42e0259cb9405824bd03d2f4336a \ - --hash=sha256:d119fafe7b634dbfa25a8c597718e69a930e4847f0b88e172744be24515140da \ - --hash=sha256:d40f9da8cabbf295d3a9dae1295c69975b86d941bc20f0a087f0477fa0a66231 \ - --hash=sha256:e595c591a48bbc295ebf47cb91aebf9bd32f3ff76749ecf282ea7f9f6bb73886 \ - --hash=sha256:ffb3dc385f6bb1568aa974fe65da84723210e5d9707e360e9ecb51f59406cd2e +aiohappyeyeballs==2.4.6 \ + --hash=sha256:147ec992cf873d74f5062644332c539fcd42956dc69453fe5204195e560517e1 \ + --hash=sha256:9b05052f9042985d32ecbe4b59a77ae19c006a78f1344d7fdad69d28ded3d0b0 +aiohttp==3.11.12 \ + --hash=sha256:0ed49efcd0dc1611378beadbd97beb5d9ca8fe48579fc04a6ed0844072261b6a \ + --hash=sha256:1987770fb4887560363b0e1a9b75aa303e447433c41284d3af2840a2f226d6e0 \ + --hash=sha256:54775858c7f2f214476773ce785a19ee81d1294a6bedc5cc17225355aab74802 \ + --hash=sha256:68d54234c8d76d8ef74744f9f9fc6324f1508129e23da8883771cdbb5818cbef \ + --hash=sha256:6dfe7f984f28a8ae94ff3a7953cd9678550dbd2a1f9bda5dd9c5ae627744c78e \ + --hash=sha256:7603ca26d75b1b86160ce1bbe2787a0b706e592af5b2504e12caa88a217767b0 \ + --hash=sha256:8fa1510b96c08aaad49303ab11f8803787c99222288f310a62f493faf883ede1 \ + --hash=sha256:9dec0000d2d8621d8015c293e24589d46fa218637d820894cb7356c77eca3259 \ + --hash=sha256:a481a574af914b6e84624412666cbfbe531a05667ca197804ecc19c97b8ab1b0 \ + --hash=sha256:a4ac6a0f0f6402854adca4e3259a623f5c82ec3f0c049374133bcb243132baf9 \ + --hash=sha256:a5e69046f83c0d3cb8f0d5bd9b8838271b1bc898e01562a04398e160953e8eb9 \ + --hash=sha256:c96a43822f1f9f69cc5c3706af33239489a6294be486a0447fb71380070d4d5f \ + --hash=sha256:c9fd9dcf9c91affe71654ef77426f5cf8489305e1c66ed4816f5a21874b094b9 \ + --hash=sha256:cddb31f8474695cd61fc9455c644fc1606c164b93bff2490390d90464b4655df \ + --hash=sha256:dc065a4285307607df3f3686363e7f8bdd0d8ab35f12226362a847731516e42c \ + --hash=sha256:e3552fe98e90fdf5918c04769f338a87fa4f00f3b28830ea9b78b1bdc6140e0d \ + --hash=sha256:e392804a38353900c3fd8b7cacbea5132888f7129f8e241915e90b85f00e3250 aiosignal==1.3.2 \ --hash=sha256:45cde58e409a301715980c2b01d0c28bdde3770d8290b5eb2173759d9acb31a5 \ --hash=sha256:a8c255c66fafb1e499c9351d0bf32ff2d8a0321595ebac3b93713656d2436f54 @@ -257,9 +258,9 @@ redis==5.2.1 \ schema==0.7.7 \ --hash=sha256:5d976a5b50f36e74e2157b47097b60002bd4d42e65425fcc9c9befadb4255dde \ --hash=sha256:7da553abd2958a19dc2547c388cde53398b39196175a9be59ea1caf5ab0a1807 -sentry-sdk==2.20.0 \ - --hash=sha256:afa82713a92facf847df3c6f63cec71eb488d826a50965def3d7722aa6f0fdab \ - --hash=sha256:c359a1edf950eb5e80cffd7d9111f3dbeef57994cb4415df37d39fda2cf22364 +sentry-sdk==2.21.0 \ + --hash=sha256:7623cfa9e2c8150948a81ca253b8e2bfe4ce0b96ab12f8cd78e3ac9c490fd92f \ + --hash=sha256:a6d38e0fb35edda191acf80b188ec713c863aaa5ad8d5798decb8671d02077b6 sniffio==1.3.1 \ --hash=sha256:2f6da418d1f1e0fddd844478f41680e794e6051915791a034ff65e5f100525a2 \ --hash=sha256:f4324edc670a0f49750a81b895f35c3adb843cca46f0530f79fc1babb23789dc From 2d829aa0e452a6d2fa21fc490031a2be5fc09db7 Mon Sep 17 00:00:00 2001 From: Paillat Date: Thu, 20 Feb 2025 20:30:42 +0100 Subject: [PATCH 61/61] :sparkles: Make intents writable while the connection is not established (#70) --- src/custom/__init__.py | 43 +++++++++++++++++++++++++++++++++++++++++- 1 file changed, 42 insertions(+), 1 deletion(-) diff --git a/src/custom/__init__.py b/src/custom/__init__.py index 61fec82..0e61d8c 100644 --- a/src/custom/__init__.py +++ b/src/custom/__init__.py @@ -135,9 +135,50 @@ async def get_context( ctx.load_translations() return ctx + @property + @override + def intents(self) -> discord.Intents: + """The intents configured for this connection or a copy of the intents if the bot is connected. + + Returns + ------- + :class:`Intents` + The intents configured for this Client. + + """ + # _connection._intents returns the intents themselves, _connection.intents returns a copy + # so if the bot is connected, we return a copy so that changes don't affect the connection + # if the bot is not connected, we return the actual intents so that the user can make changes + if self.ws is None: # pyright: ignore [reportUnnecessaryComparison] + return self._connection._intents # noqa: SLF001 # pyright: ignore [reportPrivateUsage] + return self._connection.intents + + @intents.setter + def intents(self, value: Any) -> None: # pyright: ignore [reportExplicitAny] + """Set the intents for this Client. + + Parameters + ---------- + value: :class:`Intents` + The intents to set for this Client. + + Raises + ------ + TypeError + The value is not an instance of Intents. + AttributeError + The intents cannot be changed after the connection is established. + + """ + if not isinstance(value, discord.Intents): + raise TypeError(f"Intents must be an instance of Intents not {value.__class__!r}") + if self.ws is not None: # pyright: ignore [reportUnnecessaryComparison] + raise AttributeError("Cannot change intents after the connection is established.") + self._connection._intents.value = value.value # noqa: SLF001 # pyright: ignore [reportPrivateUsage] + if not TYPE_CHECKING: - Context: ApplicationContext = ApplicationContext # pyright: ignore [reportRedeclaration] + Context: ApplicationContext = ApplicationContext if TYPE_CHECKING: # temp fix for https://github.com/Pycord-Development/pycord/pull/2611 type Context = ExtContext | ApplicationContext