From 3f6b983a259575c04d942cb42fb2693b09e9e34f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=A4=9A=E7=BE=85=E7=8B=BC?= Date: Fri, 3 Jan 2025 19:06:16 +0800 Subject: [PATCH] updatea and fix --- bot.py | 23 +++--- bots/api/bot.py | 45 +++++++--- console.py | 1 + core/scripts/config_generate.py | 2 +- poetry.lock | 140 +++++++++++++++++++++++++++++++- pyproject.toml | 1 + requirements.txt | 4 + 7 files changed, 189 insertions(+), 27 deletions(-) diff --git a/bot.py b/bot.py index 521c2364b8..09493229b6 100644 --- a/bot.py +++ b/bot.py @@ -41,8 +41,7 @@ class RestartBot(Exception): def init_bot(): - import core.scripts.config_generate # noqa - from core.config import Config, CFGManager # noqa + from core.config import Config # noqa from core.constants.default import base_superuser_default # noqa from core.database import BotDBUtil, session, DBVersion # noqa from core.logger import Logger # noqa @@ -75,13 +74,6 @@ def init_bot(): "The base superuser is not found, please setup it in the config file." ) - disabled_bots.clear() - for t in CFGManager.values: - if t.startswith("bot_") and not t.endswith("_secret"): - if "enable" in CFGManager.values[t][t]: - if not CFGManager.values[t][t]["enable"]: - disabled_bots.append(t[4:]) - def multiprocess_run_until_complete(func): p = multiprocessing.Process( @@ -117,7 +109,7 @@ def go(bot_name: str, subprocess: bool = False, binary_mode: bool = False): def run_bot(): from core.constants.path import cache_path # noqa - from core.config import Config # noqa + from core.config import Config, CFGManager # noqa from core.logger import Logger # noqa def restart_process(bot_name: str): @@ -155,6 +147,14 @@ def restart_process(bot_name: str): envs["PYTHONPATH"] = os.path.abspath(".") lst = bots_and_required_configs.keys() + for t in CFGManager.values: + if t.startswith("bot_") and not t.endswith("_secret"): + if "enable" in CFGManager.values[t][t]: + if not CFGManager.values[t][t]["enable"]: + disabled_bots.append(t[4:]) + else: + Logger.warning(f"Bot {t} cannot found config \"enable\".") + for bl in lst: if bl in disabled_bots: continue @@ -163,7 +163,7 @@ def restart_process(bot_name: str): for c in bots_and_required_configs[bl]: if not Config(c, _global=True): Logger.error( - f"Bot {bl} requires config {c} but not found, abort to launch." + f"Bot {bl} requires config \"{c}\" but not found, abort to launch." ) abort = True break @@ -200,6 +200,7 @@ def restart_process(bot_name: str): if __name__ == "__main__": + import core.scripts.config_generate # noqa try: while True: try: diff --git a/bots/api/bot.py b/bots/api/bot.py index 4c35b7199a..434aa987ef 100644 --- a/bots/api/bot.py +++ b/bots/api/bot.py @@ -22,6 +22,8 @@ from fastapi.middleware.cors import CORSMiddleware from fastapi.responses import FileResponse from fastapi.staticfiles import StaticFiles +from slowapi import Limiter +from slowapi.util import get_remote_address from bots.api.info import client_name from core.constants import config_filename, config_path, logs_path @@ -70,7 +72,7 @@ def save_csrf_tokens(tokens): def verify_csrf_token(request: Request): - csrf_token = request.cookies.get("csrfToken") + csrf_token = request.cookies.get("XSRF-TOKEN") if not csrf_token: raise HTTPException(status_code=403, detail="Missing CSRF token") @@ -106,6 +108,7 @@ def verify_jwt(request: Request): app = FastAPI() +limiter = Limiter(key_func=get_remote_address) ph = PasswordHasher() @@ -130,18 +133,21 @@ async def startup_event(): @app.get("/favicon.ico", response_class=FileResponse) -async def favicon(): +@limiter.limit("2/second") +async def favicon(request: Request): favicon_path = os.path.join(assets_path, "favicon.ico") return FileResponse(favicon_path) @app.get("/api/verify-token") +@limiter.limit("2/second") async def verify_token(request: Request): verify_jwt(request) @app.get("/api/get-csrf-token") -async def set_csrf_token(response: Response): +@limiter.limit("2/second") +async def set_csrf_token(request: Request, response: Response): current_time = time.time() token_entries = load_csrf_tokens() @@ -160,7 +166,7 @@ async def set_csrf_token(response: Response): save_csrf_tokens(token_entries) response.set_cookie( - key="csrfToken", + key="XSRF-TOKEN", value=csrf_token, httponly=True, secure=True, @@ -172,6 +178,7 @@ async def set_csrf_token(response: Response): @app.post("/api/auth") +@limiter.limit("10/minute") async def auth(request: Request, response: Response): try: payload = { @@ -232,6 +239,7 @@ async def auth(request: Request, response: Response): @app.post("/api/change-password") +@limiter.limit("10/minute") async def change_password(request: Request): try: verify_jwt(request) @@ -271,6 +279,7 @@ async def change_password(request: Request): @app.get("/api/server-info") +@limiter.limit("10/minute") async def server_info(request: Request): verify_jwt(request) return { @@ -306,6 +315,7 @@ async def server_info(request: Request): @app.get("/api/config") +@limiter.limit("2/second") async def get_config_list(request: Request): verify_jwt(request) try: @@ -325,7 +335,8 @@ async def get_config_list(request: Request): @app.get("/api/config/{cfg_filename}") -async def get_config_file(cfg_filename: str, request: Request): +@limiter.limit("2/second") +async def get_config_file(request: Request, cfg_filename: str): verify_jwt(request) if not os.path.exists(config_path): raise HTTPException(status_code=404, detail="Not found") @@ -347,7 +358,8 @@ async def get_config_file(cfg_filename: str, request: Request): @app.post("/api/config/{cfg_filename}") -async def edit_config_file(cfg_filename: str, request: Request): +@limiter.limit("10/minute") +async def edit_config_file(request: Request, cfg_filename: str): verify_jwt(request) verify_csrf_token(request) if not os.path.exists(config_path): @@ -370,7 +382,8 @@ async def edit_config_file(cfg_filename: str, request: Request): @app.get("/api/target/{target_id}") -async def get_target(target_id: str): +@limiter.limit("2/second") +async def get_target(request: Request, target_id: str): target = BotDBUtil.TargetInfo(target_id) if not target.query: return HTTPException(status_code=404, detail="Not found") @@ -401,7 +414,8 @@ async def get_target(target_id: str): @app.get("/api/sender/{sender_id}") -async def get_sender(sender_id: str): +@limiter.limit("2/second") +async def get_sender(request: Request, sender_id: str): sender = BotDBUtil.SenderInfo(sender_id) if not sender.query: return HTTPException(status_code=404, detail="Not found") @@ -418,12 +432,14 @@ async def get_sender(sender_id: str): @app.get("/api/modules") -async def get_module_list(): +@limiter.limit("2/second") +async def get_module_list(request: Request): return {"modules": ModulesManager.return_modules_list()} @app.get("/api/modules/{target_id}") -async def get_target_modules(target_id: str): +@limiter.limit("2/second") +async def get_target_modules(request: Request, target_id: str): target_data = BotDBUtil.TargetInfo(target_id) if not target_data.query: return HTTPException(status_code=404, detail="Not found") @@ -437,7 +453,8 @@ async def get_target_modules(target_id: str): @app.post("/api/modules/{target_id}/enable") -async def enable_modules(target_id: str, request: Request): +@limiter.limit("10/minute") +async def enable_modules(request: Request, target_id: str): try: target_data = BotDBUtil.TargetInfo(target_id) if not target_data.query: @@ -462,7 +479,8 @@ async def enable_modules(target_id: str, request: Request): @app.post("/api/modules/{target_id}/disable") -async def disable_modules(target_id: str, request: Request): +@limiter.limit("10/minute") +async def disable_modules(request: Request, target_id: str): try: target_data = BotDBUtil.TargetInfo(target_id) if not target_data.query: @@ -487,7 +505,8 @@ async def disable_modules(target_id: str, request: Request): @app.get("/api/locale/{locale}/{string}") -async def get_locale(locale: str, string: str): +@limiter.limit("2/second") +async def get_locale(request: Request, locale: str, string: str): try: return { "locale": locale, diff --git a/console.py b/console.py index bbe6726430..bfd8fe1d5e 100644 --- a/console.py +++ b/console.py @@ -96,6 +96,7 @@ async def send_command(msg): if __name__ == "__main__": + import core.scripts.config_generate # noqa init_bot() Info.client_name = client_name loop = asyncio.new_event_loop() diff --git a/core/scripts/config_generate.py b/core/scripts/config_generate.py index 3d60bd0ec9..58bdefb29e 100644 --- a/core/scripts/config_generate.py +++ b/core/scripts/config_generate.py @@ -2,7 +2,6 @@ import re import shutil import sys -import traceback # noqa from time import sleep if __name__ == '__main__': @@ -42,6 +41,7 @@ def generate_config(dir_path, language): 'config.comments.config_version', fallback_failed_prompt=False)}\n') f.write('initialized = false\n') + f.close() from core.config import Config, CFGManager # noqa diff --git a/poetry.lock b/poetry.lock index 1919048ad1..9a2654dcc1 100644 --- a/poetry.lock +++ b/poetry.lock @@ -1,4 +1,4 @@ -# This file is automatically @generated by Poetry 1.8.5 and should not be changed by hand. +# This file is automatically @generated by Poetry 1.8.3 and should not be changed by hand. [[package]] name = "aiocqhttp" @@ -900,6 +900,23 @@ files = [ docs = ["ipython", "matplotlib", "numpydoc", "sphinx"] tests = ["pytest", "pytest-cov", "pytest-xdist"] +[[package]] +name = "deprecated" +version = "1.2.15" +description = "Python @deprecated decorator to deprecate old python classes, functions or methods." +optional = false +python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,>=2.7" +files = [ + {file = "Deprecated-1.2.15-py2.py3-none-any.whl", hash = "sha256:353bc4a8ac4bfc96800ddab349d89c25dec1079f65fd53acdcc1e0b975b21320"}, + {file = "deprecated-1.2.15.tar.gz", hash = "sha256:683e561a90de76239796e6b6feac66b99030d2dd3fcf61ef996330f14bbb9b0d"}, +] + +[package.dependencies] +wrapt = ">=1.10,<2" + +[package.extras] +dev = ["PyTest", "PyTest-Cov", "bump2version (<1)", "jinja2 (>=3.0.3,<3.1.0)", "setuptools", "sphinx (<2)", "tox"] + [[package]] name = "distlib" version = "0.3.9" @@ -2081,6 +2098,34 @@ pydantic = [ requests = ">=2,<3" requests-toolbelt = ">=1.0.0,<2.0.0" +[[package]] +name = "limits" +version = "3.14.1" +description = "Rate limiting utilities" +optional = false +python-versions = ">=3.9" +files = [ + {file = "limits-3.14.1-py3-none-any.whl", hash = "sha256:051aca02da56e6932599a25cb8e70543959294f5d587d57bcd7e38df234e697b"}, + {file = "limits-3.14.1.tar.gz", hash = "sha256:cad16a9b3cf3924e27da48e78bdab33ef312ecb7194fdb50e509cc8111c8d0bb"}, +] + +[package.dependencies] +deprecated = ">=1.2" +packaging = ">=21,<25" +typing-extensions = "*" + +[package.extras] +all = ["aetcd", "coredis (>=3.4.0,<5)", "emcache (>=0.6.1)", "emcache (>=1)", "etcd3", "motor (>=3,<4)", "pymemcache (>3,<5.0.0)", "pymongo (>4.1,<5)", "redis (>3,!=4.5.2,!=4.5.3,<6.0.0)", "redis (>=4.2.0,!=4.5.2,!=4.5.3)"] +async-etcd = ["aetcd"] +async-memcached = ["emcache (>=0.6.1)", "emcache (>=1)"] +async-mongodb = ["motor (>=3,<4)"] +async-redis = ["coredis (>=3.4.0,<5)"] +etcd = ["etcd3"] +memcached = ["pymemcache (>3,<5.0.0)"] +mongodb = ["pymongo (>4.1,<5)"] +redis = ["redis (>3,!=4.5.2,!=4.5.3,<6.0.0)"] +rediscluster = ["redis (>=4.2.0,!=4.5.2,!=4.5.3)"] + [[package]] name = "loguru" version = "0.7.2" @@ -3796,6 +3841,23 @@ files = [ {file = "six-1.16.0.tar.gz", hash = "sha256:1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926"}, ] +[[package]] +name = "slowapi" +version = "0.1.9" +description = "A rate limiting extension for Starlette and Fastapi" +optional = false +python-versions = ">=3.7,<4.0" +files = [ + {file = "slowapi-0.1.9-py3-none-any.whl", hash = "sha256:cfad116cfb84ad9d763ee155c1e5c5cbf00b0d47399a769b227865f5df576e36"}, + {file = "slowapi-0.1.9.tar.gz", hash = "sha256:639192d0f1ca01b1c6d95bf6c71d794c3a9ee189855337b4821f7f457dddad77"}, +] + +[package.dependencies] +limits = ">=2.3" + +[package.extras] +redis = ["redis (>=3.4.1,<4.0.0)"] + [[package]] name = "sniffio" version = "1.3.1" @@ -4469,6 +4531,80 @@ xmltodict = "*" doc = ["furo", "jaraco.packaging (>=9.3)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-lint"] test = ["keyring", "pmxbot", "pytest (>=6,!=8.1.*)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=2.2)", "pytest-mypy", "pytest-ruff (>=0.2.1)"] +[[package]] +name = "wrapt" +version = "1.17.0" +description = "Module for decorators, wrappers and monkey patching." +optional = false +python-versions = ">=3.8" +files = [ + {file = "wrapt-1.17.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:2a0c23b8319848426f305f9cb0c98a6e32ee68a36264f45948ccf8e7d2b941f8"}, + {file = "wrapt-1.17.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b1ca5f060e205f72bec57faae5bd817a1560fcfc4af03f414b08fa29106b7e2d"}, + {file = "wrapt-1.17.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e185ec6060e301a7e5f8461c86fb3640a7beb1a0f0208ffde7a65ec4074931df"}, + {file = "wrapt-1.17.0-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bb90765dd91aed05b53cd7a87bd7f5c188fcd95960914bae0d32c5e7f899719d"}, + {file = "wrapt-1.17.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:879591c2b5ab0a7184258274c42a126b74a2c3d5a329df16d69f9cee07bba6ea"}, + {file = "wrapt-1.17.0-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:fce6fee67c318fdfb7f285c29a82d84782ae2579c0e1b385b7f36c6e8074fffb"}, + {file = "wrapt-1.17.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:0698d3a86f68abc894d537887b9bbf84d29bcfbc759e23f4644be27acf6da301"}, + {file = "wrapt-1.17.0-cp310-cp310-win32.whl", hash = "sha256:69d093792dc34a9c4c8a70e4973a3361c7a7578e9cd86961b2bbf38ca71e4e22"}, + {file = "wrapt-1.17.0-cp310-cp310-win_amd64.whl", hash = "sha256:f28b29dc158ca5d6ac396c8e0a2ef45c4e97bb7e65522bfc04c989e6fe814575"}, + {file = "wrapt-1.17.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:74bf625b1b4caaa7bad51d9003f8b07a468a704e0644a700e936c357c17dd45a"}, + {file = "wrapt-1.17.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0f2a28eb35cf99d5f5bd12f5dd44a0f41d206db226535b37b0c60e9da162c3ed"}, + {file = "wrapt-1.17.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:81b1289e99cf4bad07c23393ab447e5e96db0ab50974a280f7954b071d41b489"}, + {file = "wrapt-1.17.0-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9f2939cd4a2a52ca32bc0b359015718472d7f6de870760342e7ba295be9ebaf9"}, + {file = "wrapt-1.17.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:6a9653131bda68a1f029c52157fd81e11f07d485df55410401f745007bd6d339"}, + {file = "wrapt-1.17.0-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:4e4b4385363de9052dac1a67bfb535c376f3d19c238b5f36bddc95efae15e12d"}, + {file = "wrapt-1.17.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:bdf62d25234290db1837875d4dceb2151e4ea7f9fff2ed41c0fde23ed542eb5b"}, + {file = "wrapt-1.17.0-cp311-cp311-win32.whl", hash = "sha256:5d8fd17635b262448ab8f99230fe4dac991af1dabdbb92f7a70a6afac8a7e346"}, + {file = "wrapt-1.17.0-cp311-cp311-win_amd64.whl", hash = "sha256:92a3d214d5e53cb1db8b015f30d544bc9d3f7179a05feb8f16df713cecc2620a"}, + {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-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:714c12485aa52efbc0fc0ade1e9ab3a70343db82627f90f2ecbc898fdf0bb181"}, + {file = "wrapt-1.17.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:da427d311782324a376cacb47c1a4adc43f99fd9d996ffc1b3e8529c4074d393"}, + {file = "wrapt-1.17.0-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ba1739fb38441a27a676f4de4123d3e858e494fac05868b7a281c0a383c098f4"}, + {file = "wrapt-1.17.0-cp313-cp313-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e711fc1acc7468463bc084d1b68561e40d1eaa135d8c509a65dd534403d83d7b"}, + {file = "wrapt-1.17.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:140ea00c87fafc42739bd74a94a5a9003f8e72c27c47cd4f61d8e05e6dec8721"}, + {file = "wrapt-1.17.0-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:73a96fd11d2b2e77d623a7f26e004cc31f131a365add1ce1ce9a19e55a1eef90"}, + {file = "wrapt-1.17.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:0b48554952f0f387984da81ccfa73b62e52817a4386d070c75e4db7d43a28c4a"}, + {file = "wrapt-1.17.0-cp313-cp313-win32.whl", hash = "sha256:498fec8da10e3e62edd1e7368f4b24aa362ac0ad931e678332d1b209aec93045"}, + {file = "wrapt-1.17.0-cp313-cp313-win_amd64.whl", hash = "sha256:fd136bb85f4568fffca995bd3c8d52080b1e5b225dbf1c2b17b66b4c5fa02838"}, + {file = "wrapt-1.17.0-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:17fcf043d0b4724858f25b8826c36e08f9fb2e475410bece0ec44a22d533da9b"}, + {file = "wrapt-1.17.0-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e4a557d97f12813dc5e18dad9fa765ae44ddd56a672bb5de4825527c847d6379"}, + {file = "wrapt-1.17.0-cp313-cp313t-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0229b247b0fc7dee0d36176cbb79dbaf2a9eb7ecc50ec3121f40ef443155fb1d"}, + {file = "wrapt-1.17.0-cp313-cp313t-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8425cfce27b8b20c9b89d77fb50e368d8306a90bf2b6eef2cdf5cd5083adf83f"}, + {file = "wrapt-1.17.0-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:9c900108df470060174108012de06d45f514aa4ec21a191e7ab42988ff42a86c"}, + {file = "wrapt-1.17.0-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:4e547b447073fc0dbfcbff15154c1be8823d10dab4ad401bdb1575e3fdedff1b"}, + {file = "wrapt-1.17.0-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:914f66f3b6fc7b915d46c1cc424bc2441841083de01b90f9e81109c9759e43ab"}, + {file = "wrapt-1.17.0-cp313-cp313t-win32.whl", hash = "sha256:a4192b45dff127c7d69b3bdfb4d3e47b64179a0b9900b6351859f3001397dabf"}, + {file = "wrapt-1.17.0-cp313-cp313t-win_amd64.whl", hash = "sha256:4f643df3d4419ea3f856c5c3f40fec1d65ea2e89ec812c83f7767c8730f9827a"}, + {file = "wrapt-1.17.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:69c40d4655e078ede067a7095544bcec5a963566e17503e75a3a3e0fe2803b13"}, + {file = "wrapt-1.17.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2f495b6754358979379f84534f8dd7a43ff8cff2558dcdea4a148a6e713a758f"}, + {file = "wrapt-1.17.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:baa7ef4e0886a6f482e00d1d5bcd37c201b383f1d314643dfb0367169f94f04c"}, + {file = "wrapt-1.17.0-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a8fc931382e56627ec4acb01e09ce66e5c03c384ca52606111cee50d931a342d"}, + {file = "wrapt-1.17.0-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:8f8909cdb9f1b237786c09a810e24ee5e15ef17019f7cecb207ce205b9b5fcce"}, + {file = "wrapt-1.17.0-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:ad47b095f0bdc5585bced35bd088cbfe4177236c7df9984b3cc46b391cc60627"}, + {file = "wrapt-1.17.0-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:948a9bd0fb2c5120457b07e59c8d7210cbc8703243225dbd78f4dfc13c8d2d1f"}, + {file = "wrapt-1.17.0-cp38-cp38-win32.whl", hash = "sha256:5ae271862b2142f4bc687bdbfcc942e2473a89999a54231aa1c2c676e28f29ea"}, + {file = "wrapt-1.17.0-cp38-cp38-win_amd64.whl", hash = "sha256:f335579a1b485c834849e9075191c9898e0731af45705c2ebf70e0cd5d58beed"}, + {file = "wrapt-1.17.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:d751300b94e35b6016d4b1e7d0e7bbc3b5e1751e2405ef908316c2a9024008a1"}, + {file = "wrapt-1.17.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7264cbb4a18dc4acfd73b63e4bcfec9c9802614572025bdd44d0721983fc1d9c"}, + {file = "wrapt-1.17.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:33539c6f5b96cf0b1105a0ff4cf5db9332e773bb521cc804a90e58dc49b10578"}, + {file = "wrapt-1.17.0-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c30970bdee1cad6a8da2044febd824ef6dc4cc0b19e39af3085c763fdec7de33"}, + {file = "wrapt-1.17.0-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:bc7f729a72b16ee21795a943f85c6244971724819819a41ddbaeb691b2dd85ad"}, + {file = "wrapt-1.17.0-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:6ff02a91c4fc9b6a94e1c9c20f62ea06a7e375f42fe57587f004d1078ac86ca9"}, + {file = "wrapt-1.17.0-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:2dfb7cff84e72e7bf975b06b4989477873dcf160b2fd89959c629535df53d4e0"}, + {file = "wrapt-1.17.0-cp39-cp39-win32.whl", hash = "sha256:2399408ac33ffd5b200480ee858baa58d77dd30e0dd0cab6a8a9547135f30a88"}, + {file = "wrapt-1.17.0-cp39-cp39-win_amd64.whl", hash = "sha256:4f763a29ee6a20c529496a20a7bcb16a73de27f5da6a843249c7047daf135977"}, + {file = "wrapt-1.17.0-py3-none-any.whl", hash = "sha256:d2c63b93548eda58abf5188e505ffed0229bf675f7c3090f8e36ad55b8cbc371"}, + {file = "wrapt-1.17.0.tar.gz", hash = "sha256:16187aa2317c731170a88ef35e8937ae0f533c402872c1ee5e6d079fcf320801"}, +] + [[package]] name = "wsproto" version = "1.2.0" @@ -4593,4 +4729,4 @@ propcache = ">=0.2.0" [metadata] lock-version = "2.0" python-versions = "^3.12.0" -content-hash = "a4693a4a3853282a78998786d6d55f5b426f364d86b7baa789f1b98957cd78d4" +content-hash = "dc983cb9c3ca873632b7630399f4292277382aea60c750d70139fecf5c30d753" diff --git a/pyproject.toml b/pyproject.toml index a3bd40f050..acc3aba3ef 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -71,6 +71,7 @@ botpy = {git = "https://github.com/Teahouse-Studios/botpy.git"} tomlkit = "^0.13.2" cattrs = "^24.1.2" argon2-cffi = "^23.1.0" +slowapi = "^0.1.9" [tool.poetry.group.dev.dependencies] diff --git a/requirements.txt b/requirements.txt index 6458fe518b..b6ffbbc7b6 100644 --- a/requirements.txt +++ b/requirements.txt @@ -29,6 +29,7 @@ colorama==0.4.6 ; python_full_version >= "3.12.0" and python_full_version < "4.0 contourpy==1.3.0 ; python_full_version >= "3.12.0" and python_full_version < "4.0.0" cryptography==43.0.3 ; python_full_version >= "3.12.0" and python_full_version < "4.0.0" cycler==0.12.1 ; python_full_version >= "3.12.0" and python_full_version < "4.0.0" +deprecated==1.2.15 ; python_full_version >= "3.12.0" and python_version < "4.0" distlib==0.3.9 ; python_version >= "3.12" and python_version < "4.0" distro==1.9.0 ; python_full_version >= "3.12.0" and python_full_version < "4.0.0" dnspython==2.7.0 ; python_full_version >= "3.12.0" and python_version < "4" @@ -77,6 +78,7 @@ langchain-text-splitters==0.3.2 ; python_full_version >= "3.12.0" and python_ver langchain==0.3.7 ; python_full_version >= "3.12.0" and python_version < "4.0" langconv @ git+https://github.com/OasisAkari/langconv.py.git@975ee0896096b63148f0930db762607a5a2113df ; python_full_version >= "3.12.0" and python_full_version < "4.0.0" langsmith==0.1.139 ; python_full_version >= "3.12.0" and python_version < "4.0" +limits==3.14.1 ; python_full_version >= "3.12.0" and python_version < "4.0" loguru==0.7.2 ; python_full_version >= "3.12.0" and python_full_version < "4.0.0" magic-filter==1.0.12 ; python_full_version >= "3.12.0" and python_full_version < "4.0.0" markupsafe==3.0.2 ; python_full_version >= "3.12.0" and python_full_version < "4.0.0" @@ -128,6 +130,7 @@ setuptools==75.3.0 ; python_full_version >= "3.12.0" and python_version < "4" sgmllib3k==1.0.0 ; python_full_version >= "3.12.0" and python_full_version < "4.0.0" simpleeval==1.0.3 ; python_full_version >= "3.12.0" and python_full_version < "4.0.0" six==1.16.0 ; python_version >= "3.12" and python_version < "4.0" +slowapi==0.1.9 ; python_full_version >= "3.12.0" and python_version < "4.0" sniffio==1.3.1 ; python_full_version >= "3.12.0" and python_version < "4.0" soupsieve==2.6 ; python_full_version >= "3.12.0" and python_full_version < "4.0.0" sqlalchemy==2.0.36 ; python_full_version >= "3.12.0" and python_version < "4.0" @@ -152,6 +155,7 @@ websockets==13.1 ; python_full_version >= "3.12.0" and python_full_version < "4. werkzeug==3.1.2 ; python_full_version >= "3.12.0" and python_full_version < "4.0.0" win32-setctime==1.1.0 ; python_full_version >= "3.12.0" and python_full_version < "4.0.0" and sys_platform == "win32" wolframalpha==5.1.3 ; python_full_version >= "3.12.0" and python_full_version < "4.0.0" +wrapt==1.17.0 ; python_full_version >= "3.12.0" and python_version < "4.0" wsproto==1.2.0 ; python_full_version >= "3.12.0" and python_full_version < "4.0.0" xmltodict==0.14.2 ; python_full_version >= "3.12.0" and python_full_version < "4.0.0" yarl==1.17.1 ; python_version >= "3.12" and python_version < "4.0"