diff --git a/Dockerfile b/Dockerfile index f1e8aa6..6cc5f41 100644 --- a/Dockerfile +++ b/Dockerfile @@ -6,7 +6,6 @@ WORKDIR /tmp # RUN pip install poetry -i https://pypi.tuna.tsinghua.edu.cn/simple - # COPY ./pyproject.toml ./poetry.lock* /tmp/ diff --git a/app/__init__.py b/app/__init__.py index 47c8280..e6ab8c5 100644 --- a/app/__init__.py +++ b/app/__init__.py @@ -15,6 +15,11 @@ from lark_oapi.adapter.flask import * from lark_oapi.api.im.v1 import * from lark_oapi.api.bitable.v1 import * +from lark_oapi.event.callback.model.p2_card_action_trigger import ( + P2CardActionTrigger, + P2CardActionTriggerResponse, +) + from app.task import * from app.utils.utils import * from app.task import * @@ -131,8 +136,9 @@ def do_bitable_record_add(data) -> None: if field.get("field_id") == "fldaxMbywh": # 有可能值为空 if field.get("field_value"): - action_data["deal_person"] = json.loads(field.get("field_value")).get("users")[0].get("name") - + action_data["deal_person"] = ( + json.loads(field.get("field_value")).get("users")[0].get("name") + ) print(f"table_id: {table_id}") print(f"record_id: {record_id}") @@ -158,10 +164,25 @@ def do_bitable_record_add(data) -> None: return +def do_card_action_trigger(data: P2CardActionTrigger) -> P2CardActionTriggerResponse: + lark.logger.info("==================卡片回调====================") + lark.logger.info(lark.JSON.marshal(data)) + lark.logger.info("==================数据解密====================") + # data = json.loads(lark.JSON.marshal(data)) + open_id = data.event.operator.open_id + activity_name = data.event.action.form_value.get("select_activity") + open_message_id = data.event.context.open_message_id + + process_push_xbot_activity_bot.delay(activity_name, open_id, open_message_id) + resp = {"toast": {"type": "info", "content": "提交成功, 机器人即将推送"}} + return P2CardActionTriggerResponse(resp) + + handler = ( lark.EventDispatcherHandler.builder( encrypt_key, verification_token, lark.LogLevel.DEBUG ) + .register_p2_card_action_trigger(do_card_action_trigger) .register_p2_im_message_receive_v1(do_p2_im_message_receive_v1) .register_p2_customized_event( "drive.file.bitable_record_changed_v1", do_bitable_record_add @@ -196,6 +217,20 @@ def create_app() -> Flask: def index(): return {"test": "ok"} + @app.route("/webhook", methods=["GET", "POST"]) + def push_xbot_activity_bot(): + # 解析请求体中的json数据 + data = json.loads(request.data) + print(f"webhook receive data: {data}") + open_id = data.get("open_id") + activity_code = data.get("activity_code") + if not open_id or not activity_code: + return {"status": "error", "msg": "open_id or activity_code is not exist"} + + process_push_xbot_activity_bot.delay(activity_code, open_id) + + return {"status": "ok"} + return app diff --git a/app/task.py b/app/task.py index 92a36a1..eedaebb 100644 --- a/app/task.py +++ b/app/task.py @@ -17,6 +17,8 @@ from app.utils.feishu import ( ) from app.utils.utils import update_record, add_record from app.utils.yd_utils import new_blank_robot, new_blank_activity +from app.utils.xbot_utils import push_xbot_activity_bot +from app.utils.xbot_utils import send_select_activity_card_message def parse_history_message(data): @@ -147,11 +149,17 @@ def process_message_callback( content = json.loads(message_data.get("content")) content_text = content.get("text") - if "记录问题" not in content_text: + if "记录问题" not in content_text and "下载指令" not in content_text: # 忽略非记录问题的消息 lark.logger.info("忽略非记录问题的消息") return + # 根据消息内容走不同的逻辑 + if "下载指令" in content_text: + # 发送一个卡片消息 + send_select_activity_card_message(message_id) + return + record_category = "官方指令" if "指令" in content_text else "官方应用" record = {} @@ -400,3 +408,8 @@ def process_new_robot(app_id, app_secret, action_data): table_id = "tbl2GcBvkvMtOBnl" add_record(client, bitable_token, table_id, catagory_table_record) + + +@shared_task(include_result=False) +def process_push_xbot_activity_bot(activity_code, open_id, open_message_id): + push_xbot_activity_bot(activity_code, open_id, open_message_id) diff --git a/app/utils/xbot_utils.py b/app/utils/xbot_utils.py new file mode 100644 index 0000000..ce1ac0f --- /dev/null +++ b/app/utils/xbot_utils.py @@ -0,0 +1,469 @@ +# import requests +import logging +import os +import re +import requests +import zipfile +import shutil +import uuid + +import os +import json + +from urllib import parse + +APPS_COUNT = 0 +SDKS_COUNT = 0 + +import json +import os +import lark_oapi as lark +from lark_oapi.api.im.v1 import * + +sdk_external_dependencies = [] + + +class CustomFormatter(logging.Formatter): + grey = "\x1b[38;20m" + yellow = "\x1b[33;20m" + red = "\x1b[31;20m" + bold_red = "\x1b[31;1m" + reset = "\x1b[0m" + green = "\x1b[32m" + + format = "%(asctime)s: %(message)s" + + FORMATS = { + logging.DEBUG: grey + format + reset, + logging.INFO: green + format + reset, + logging.WARNING: yellow + format + reset, + logging.ERROR: red + format + reset, + logging.CRITICAL: bold_red + format + reset, + } + date_format = "%Y-%m-%d %H:%M:%S" + + def format(self, record): + log_fmt = self.FORMATS.get(record.levelno) + formatter = logging.Formatter(log_fmt, self.date_format) + return formatter.format(record) + + +# 初始化日志 +logger = logging.getLogger("App") +logger.setLevel(logging.DEBUG) +ch = logging.StreamHandler() +ch.setFormatter(CustomFormatter()) +logger.addHandler(ch) + + +def sanitize_filename(filename, replace_char="_"): + """ + 去除 Windows 文件名中的非法字符 + + 参数: + filename (str): 要处理的原始文件名 + replace_char (str): 替换非法字符的字符,默认为下划线 + + 返回: + str: 处理后的合法文件名 + """ + # Windows 文件系统不允许的字符 + illegal_chars = r'[<>:"/\\|?*\x00-\x1f]' + + # 替换非法字符 + sanitized = re.sub(illegal_chars, replace_char, filename) + + # 同时去除文件名开头和结尾的空格和点 + sanitized = sanitized.strip(" .") + + # 保留文件扩展名中的点 + return sanitized + + +def get_token(username, password): + """ + 利用网页端获取 token + :param username: 用户名 + :param password: 密码 + :return: token + """ + + url = "https://api.winrobot360.com/oauth/token" + data = { + "username": username, + "password": password, + "grant_type": "password", + "scope": "all", + } + + payload = parse.urlencode(data) + headers = { + "accept": "application/json", + "authorization": "Basic Y29uc29sZTpzVVdpeTZzTmlYZDBlNUxo", + "content-type": "application/x-www-form-urlencoded;charset=UTF-8", + } + response = requests.request("POST", url, headers=headers, data=payload).json() + + if response.get("success") == "false": + raise ValueError(response.get("msg")) + return response.get("access_token") + + +def get_client_version(token): + """获取当期登录账号客户端的版本""" + url = "https://api.winrobot360.com/api/v1/user/info/rich" + + payload = {} + headers = { + "Authorization": f"bearer {token}", + "Accept": "application/json, text/json, text/x-json, text/javascript, application/xml, text/xml", + } + + response = requests.request("GET", url, headers=headers, data=payload) + return response.json().get("data").get("clientVersion") + + +def get_activity_detail(token, sdk_uuid): + """ + 获取自定义指令的相关信息 + :param token: token + :param sdk: 自定义指令 + :return: package_name, package_url + """ + name, version = sdk_uuid.split("==") + url = f"https://api.winrobot360.com/api/v1/robot/use/activity/package/detail?packageName={name}&version={version}" + payload = {} + headers = { + "Host": "api.winrobot360.com", + "Authorization": f"bearer {token}", + "Accept": "application/json, text/json, text/x-json, text/javascript, application/xml, text/xml", + "User-Agent": "RestSharp/107.3.0.0", + "Accept-Encoding": "json", + } + + response = requests.request("GET", url, headers=headers, data=payload) + return response.json().get("data") + + +def download_file(url, save_path, filename): + """ + 根据链接下载文件 + :param url: 链接 + :param save_path: 保存路径 + :param filename: 保存文件名 + :return: 保存文件文件名 + """ + res = requests.get(url) + with open(os.path.join(save_path, filename), "wb") as f: + f.write(res.content) + + return os.path.join(save_path, filename) + + +def zip_file(startdir, file_news=None): + """ + 压缩文件 + :param startdir: 要压缩的文件夹路径 + :param file_news: 压缩后文件名 + """ + file_news = file_news if file_news else startdir + ".bot" + z = zipfile.ZipFile(file_news, "w", zipfile.ZIP_DEFLATED) + for dirpath, dirnames, filenames in os.walk(startdir): + fpath = dirpath.replace(startdir, "") + fpath = fpath and fpath + os.sep or "" + for filename in filenames: + z.write(os.path.join(dirpath, filename), fpath + filename) + z.close() + return file_news + + +def unzip_file(zip_file_path, unzip_path): + """ + 解压文件 + :param zip_file_path: 解压的文件路径 + :param unzip_path: 解压(输出)的路径 + :return: + """ + zip_file = zipfile.ZipFile(zip_file_path) + for file in zip_file.namelist(): + zip_file.extract(file, unzip_path) + zip_file.close() + + +def modify_package_version(package_dirctory: str, version: str): + """ + 修改 package.json 文件中的版本号 + """ + package_json_path = os.path.join(package_dirctory, "package.json") + with open(package_json_path, encoding="utf8") as f: + package_json = json.load(f) + package_json["version"] = version + with open(package_json_path, "w") as f: + json.dump(package_json, f, indent=4, ensure_ascii=False) + + +def package_activity(token, robot_uuid, basedir): + """ + 根据 uuid 将应用打包成 bot 文件, 并存到指定的文件中 + :param token: + :param roobt_uuid: + :param basedir: 文件存放路径 + """ + # 1. 根据机器人 uuid 获取机器人详细信息 + activity_detail = get_activity_detail(token=token, sdk_uuid=robot_uuid) + activity_name = activity_detail.get("name") + version = activity_detail.get("releaseVersion") + packageUrl = activity_detail.get("packageUrl") + internal_dependencies = activity_detail.get("flatInternalDependencies") + + logger.info(f"打包指令: {activity_name}") + + # 去除不能作为windows文件名的字符 + activity_name = sanitize_filename(activity_name, "") + + # 2. 下载 activity 文件 + activity_path = os.path.join(basedir, activity_name) + os.makedirs(activity_path) + download_name = download_file(packageUrl, activity_path, "xbot_robot.zip") + xbot_robot_path = os.path.join(activity_path, "xbot_robot") + os.makedirs(xbot_robot_path) + unzip_file(download_name, xbot_robot_path) + os.remove(download_name) + modify_package_version(xbot_robot_path, version) + + # 3. 下载 activity 的 internal dependence + xbot_extensions_path = os.path.join(activity_path, "xbot_extensions") + os.makedirs(xbot_extensions_path) + + with open(os.path.join(xbot_extensions_path, "requirement.txt"), "w") as f: + f.write("\n".join(internal_dependencies)) + + with open(os.path.join(xbot_extensions_path, "__init__.py"), "w") as f: + f.write("\n".join([f"from . import {item}" for item in internal_dependencies])) + + for dependence in internal_dependencies: + dependence_detail = get_activity_detail(token, dependence) + name = dependence_detail.get("packageName") + version = dependence_detail.get("releaseVersion") + package_url = dependence_detail.get("packageUrl") + dependence_save_path = os.path.join(xbot_extensions_path, name) + os.makedirs(dependence_save_path) + download_name = download_file(package_url, xbot_extensions_path, "package.zip") + unzip_file(download_name, dependence_save_path) + modify_package_version(dependence_save_path, version) + os.remove(download_name) + + activity_save_path = zip_file(activity_path) + + shutil.rmtree(activity_path) + return activity_save_path + + +def send_message(file_path, open_id, open_message_id): + """发送指令文件到指定用户""" + # 创建client + + YOUR_APP_ID = "cli_a5110cd1da70900b" + YOUR_APP_SECRET = "XwTUlUq7dGK1XexUS7ljShJJ7t1MIwXF" + + client = ( + lark.Client.builder() + .app_id(YOUR_APP_ID) + .app_secret(YOUR_APP_SECRET) + .log_level(lark.LogLevel.DEBUG) + .build() + ) + + # 构造请求对象 + file = open(file_path, "rb") + _, filename = os.path.split(file_path) + request: CreateFileRequest = ( + CreateFileRequest.builder() + .request_body( + CreateFileRequestBody.builder() + .file_type("stream") + .file_name(filename) + .file(file) + .build() + ) + .build() + ) + + # 发起请求 + response: CreateFileResponse = client.im.v1.file.create(request) + + # 处理失败返回 + if not response.success(): + lark.logger.error( + f"client.im.v1.file.create failed, code: {response.code}, msg: {response.msg}, log_id: {response.get_log_id()}, resp: \n{json.dumps(json.loads(response.raw.content), indent=4, ensure_ascii=False)}" + ) + + content = {"file_key": response.data.file_key} + + uuid_str = str(uuid.uuid4()) + + request: CreateMessageRequest = ( + CreateMessageRequest.builder() + .receive_id_type("open_id") + .request_body( + CreateMessageRequestBody.builder() + .receive_id(open_id) + .msg_type("file") + .content(json.dumps(content)) + .build() + ) + .build() + ) + # 发起请求 + response: CreateMessageResponse = client.im.v1.message.create(request) + + # 处理失败返回 + if not response.success(): + lark.logger.error( + f"client.im.v1.message.create failed, code: {response.code}, msg: {response.msg}, log_id: {response.get_log_id()}, resp: \n{json.dumps(json.loads(response.raw.content), indent=4, ensure_ascii=False)}" + ) + return + + # 处理业务结果 + lark.logger.info(lark.JSON.marshal(response.data, indent=4)) + + # 推送下载成功 + content = {"text": "指令包已推送,请通过应用机器人下载"} + request: ReplyMessageRequest = ( + ReplyMessageRequest.builder() + .message_id(open_message_id) + .request_body( + ReplyMessageRequestBody.builder() + .content(content=json.dumps(content)) + .msg_type("text") + .reply_in_thread(True) + .build() + ) + .build() + ) + + # 发起请求 + response: CreateMessageResponse = client.im.v1.message.create(request) + + # 处理失败返回 + if not response.success(): + lark.logger.error( + f"client.im.v1.message.create failed, code: {response.code}, msg: {response.msg}, log_id: {response.get_log_id()}, resp: \n{json.dumps(json.loads(response.raw.content), indent=4, ensure_ascii=False)}" + ) + return + + # 处理业务结果 + lark.logger.info(lark.JSON.marshal(response.data, indent=4)) + + +def push_xbot_activity_bot(activity_code, open_id, open_message_id): + """自动推送官方指令bot包到指定用户 + :param activity_code: 指令代码带版本号 + :param open_id: 接收者open_id + """ + username = "剑心@fckj" + password = "320753691love" + # open_id = "ou_d542891996bf1961f9a94563e6bd4d49" + token = get_token(username=username, password=password) + + logger.error(f"使用 {username} 账号登陆") + version = get_client_version(token=token) + + logger.error(f"当前账号客户端版本号为: {version}") + + base_dir = os.path.dirname(os.path.realpath(__file__)) + + activity_path = package_activity( + token=token, robot_uuid=activity_code, basedir=base_dir + ) + send_message(activity_path, open_id, open_message_id) + + +def get_office_activity_names_with_viewname(token): + """ + 获取自定义指令的名称及版本 + :return: list, 返回自定义指令 名_版本号 + """ + page = 1 + uuid = [] + url = "https://api.winrobot360.com/api/v1/robot/activity/package/list?source=market&page=%s&size=100&uiaType=uiatype" + + payload = {} + headers = { + "Authorization": f"bearer {token}", + } + activity_data = [] + response = requests.request("GET", url % page, headers=headers, data=payload) + + page_info = response.json().get("page").get("pages") + for page in range(1, page_info + 1): + response = requests.request("GET", url % page, headers=headers, data=payload) + for item in response.json().get("data"): + uuid.append(item.get("packageName") + "==" + item.get("packageVersion")) + # activity_data[item.get("packageViewName")] = item.get("packageName") + "==" + item.get("packageVersion") + + # activity_data.append({"activity_name": item.get("packageViewName"), "activity_code": item.get("packageName") + "==" + item.get("packageVersion")}) + + activity_data.append( + { + "text": item.get("packageViewName"), + "value": f'{item.get("packageName")}=={item.get("packageVersion")}', + } + ) + + return activity_data + + +def send_select_activity_card_message(message_id): + username = "剑心@fckj" + password = "320753691love" + # open_id = "ou_d542891996bf1961f9a94563e6bd4d49" + token = get_token(username=username, password=password) + activity_data = get_office_activity_names_with_viewname(token) + + content = { + "type": "template", + "data": { + "template_id": "AAqR6hyJFojEs", + "template_version_name": "1.0.6", + "template_variable": {"activity_list": activity_data}, + }, + } + APP_ID = "cli_a5110cd1da70900b" + APP_SECRET = "XwTUlUq7dGK1XexUS7ljShJJ7t1MIwXF" + + client = ( + lark.Client.builder() + .app_id(APP_ID) + .app_secret(APP_SECRET) + .log_level(lark.LogLevel.DEBUG) + .build() + ) + + # 构造请求对象 + + request: ReplyMessageRequest = ( + ReplyMessageRequest.builder() + .message_id(message_id) + .request_body( + ReplyMessageRequestBody.builder() + .content(content=json.dumps(content)) + .msg_type("interactive") + .reply_in_thread(True) + .build() + ) + .build() + ) + + # 发起请求 + response: CreateMessageResponse = client.im.v1.message.create(request) + + # 处理失败返回 + if not response.success(): + lark.logger.error( + f"client.im.v1.message.create failed, code: {response.code}, msg: {response.msg}, log_id: {response.get_log_id()}, resp: \n{json.dumps(json.loads(response.raw.content), indent=4, ensure_ascii=False)}" + ) + return + + # 处理业务结果 + lark.logger.info(lark.JSON.marshal(response.data, indent=4)) diff --git a/poetry.lock b/poetry.lock index 9267fa8..0decc29 100644 --- a/poetry.lock +++ b/poetry.lock @@ -1,4 +1,4 @@ -# This file is automatically @generated by Poetry 1.5.0 and should not be changed by hand. +# This file is automatically @generated by Poetry 2.1.1 and should not be changed by hand. [[package]] name = "amqp" @@ -6,6 +6,7 @@ version = "5.2.0" description = "Low-level AMQP client for Python (fork of amqplib)." optional = false python-versions = ">=3.6" +groups = ["main"] files = [ {file = "amqp-5.2.0-py3-none-any.whl", hash = "sha256:827cb12fb0baa892aad844fd95258143bce4027fdac4fccddbc43330fd281637"}, {file = "amqp-5.2.0.tar.gz", hash = "sha256:a1ecff425ad063ad42a486c902807d1482311481c8ad95a72694b2975e75f7fd"}, @@ -20,6 +21,7 @@ version = "4.2.0" description = "High level compatibility layer for multiple asynchronous event loop implementations" optional = false python-versions = ">=3.8" +groups = ["main"] files = [ {file = "anyio-4.2.0-py3-none-any.whl", hash = "sha256:745843b39e829e108e518c489b31dc757de7d2131d53fac32bd8df268227bfee"}, {file = "anyio-4.2.0.tar.gz", hash = "sha256:e1875bb4b4e2de1669f4bc7869b6d3f54231cdced71605e6e64c9be77e3be50f"}, @@ -33,7 +35,7 @@ typing-extensions = {version = ">=4.1", markers = "python_version < \"3.11\""} [package.extras] doc = ["Sphinx (>=7)", "packaging", "sphinx-autodoc-typehints (>=1.2.0)", "sphinx-rtd-theme"] -test = ["anyio[trio]", "coverage[toml] (>=7)", "exceptiongroup (>=1.2.0)", "hypothesis (>=4.0)", "psutil (>=5.9)", "pytest (>=7.0)", "pytest-mock (>=3.6.1)", "trustme", "uvloop (>=0.17)"] +test = ["anyio[trio]", "coverage[toml] (>=7)", "exceptiongroup (>=1.2.0)", "hypothesis (>=4.0)", "psutil (>=5.9)", "pytest (>=7.0)", "pytest-mock (>=3.6.1)", "trustme", "uvloop (>=0.17) ; platform_python_implementation == \"CPython\" and platform_system != \"Windows\""] trio = ["trio (>=0.23)"] [[package]] @@ -42,6 +44,8 @@ version = "4.0.3" description = "Timeout context manager for asyncio programs" optional = false python-versions = ">=3.7" +groups = ["main"] +markers = "python_full_version <= \"3.11.2\"" files = [ {file = "async-timeout-4.0.3.tar.gz", hash = "sha256:4640d96be84d82d02ed59ea2b7105a0f7b33abe8703703cd0ab0bf87c427522f"}, {file = "async_timeout-4.0.3-py3-none-any.whl", hash = "sha256:7405140ff1230c310e51dc27b3145b9092d659ce68ff733fb0cefe3ee42be028"}, @@ -53,6 +57,7 @@ version = "4.2.0" description = "Python multiprocessing fork with improvements and bugfixes" optional = false python-versions = ">=3.7" +groups = ["main"] files = [ {file = "billiard-4.2.0-py3-none-any.whl", hash = "sha256:07aa978b308f334ff8282bd4a746e681b3513db5c9a514cbdd810cbbdc19714d"}, {file = "billiard-4.2.0.tar.gz", hash = "sha256:9a3c3184cb275aa17a732f93f65b20c525d3d9f253722d26a82194803ade5a2c"}, @@ -64,6 +69,7 @@ version = "1.7.0" description = "Fast, simple object-to-object and broadcast signaling" optional = false python-versions = ">=3.8" +groups = ["main"] files = [ {file = "blinker-1.7.0-py3-none-any.whl", hash = "sha256:c3f865d4d54db7abc53758a01601cf343fe55b84c1de4e3fa910e420b438d5b9"}, {file = "blinker-1.7.0.tar.gz", hash = "sha256:e6820ff6fa4e4d1d8e2747c2283749c3f547e4fee112b98555cdcdae32996182"}, @@ -75,6 +81,7 @@ version = "5.3.6" description = "Distributed Task Queue." optional = false python-versions = ">=3.8" +groups = ["main"] files = [ {file = "celery-5.3.6-py3-none-any.whl", hash = "sha256:9da4ea0118d232ce97dff5ed4974587fb1c0ff5c10042eb15278487cdd27d1af"}, {file = "celery-5.3.6.tar.gz", hash = "sha256:870cc71d737c0200c397290d730344cc991d13a057534353d124c9380267aab9"}, @@ -95,31 +102,31 @@ vine = ">=5.1.0,<6.0" arangodb = ["pyArango (>=2.0.2)"] auth = ["cryptography (==41.0.5)"] azureblockblob = ["azure-storage-blob (>=12.15.0)"] -brotli = ["brotli (>=1.0.0)", "brotlipy (>=0.7.0)"] +brotli = ["brotli (>=1.0.0) ; platform_python_implementation == \"CPython\"", "brotlipy (>=0.7.0) ; platform_python_implementation == \"PyPy\""] cassandra = ["cassandra-driver (>=3.25.0,<4)"] consul = ["python-consul2 (==0.1.5)"] cosmosdbsql = ["pydocumentdb (==2.3.5)"] -couchbase = ["couchbase (>=3.0.0)"] +couchbase = ["couchbase (>=3.0.0) ; platform_python_implementation != \"PyPy\" and (platform_system != \"Windows\" or python_version < \"3.10\")"] couchdb = ["pycouchdb (==1.14.2)"] django = ["Django (>=2.2.28)"] dynamodb = ["boto3 (>=1.26.143)"] elasticsearch = ["elastic-transport (<=8.10.0)", "elasticsearch (<=8.11.0)"] -eventlet = ["eventlet (>=0.32.0)"] +eventlet = ["eventlet (>=0.32.0) ; python_version < \"3.10\""] gevent = ["gevent (>=1.5.0)"] -librabbitmq = ["librabbitmq (>=2.0.0)"] -memcache = ["pylibmc (==1.6.3)"] +librabbitmq = ["librabbitmq (>=2.0.0) ; python_version < \"3.11\""] +memcache = ["pylibmc (==1.6.3) ; platform_system != \"Windows\""] mongodb = ["pymongo[srv] (>=4.0.2)"] msgpack = ["msgpack (==1.0.7)"] pymemcache = ["python-memcached (==1.59)"] -pyro = ["pyro4 (==4.82)"] +pyro = ["pyro4 (==4.82) ; python_version < \"3.11\""] pytest = ["pytest-celery (==0.0.0)"] redis = ["redis (>=4.5.2,!=4.5.5,<6.0.0)"] s3 = ["boto3 (>=1.26.143)"] slmq = ["softlayer-messaging (>=1.0.3)"] -solar = ["ephem (==4.1.5)"] +solar = ["ephem (==4.1.5) ; platform_python_implementation != \"PyPy\""] sqlalchemy = ["sqlalchemy (>=1.4.48,<2.1)"] -sqs = ["boto3 (>=1.26.143)", "kombu[sqs] (>=5.3.0)", "pycurl (>=7.43.0.5)", "urllib3 (>=1.26.16)"] -tblib = ["tblib (>=1.3.0)", "tblib (>=1.5.0)"] +sqs = ["boto3 (>=1.26.143)", "kombu[sqs] (>=5.3.0)", "pycurl (>=7.43.0.5) ; sys_platform != \"win32\" and platform_python_implementation == \"CPython\"", "urllib3 (>=1.26.16)"] +tblib = ["tblib (>=1.3.0) ; python_version < \"3.8.0\"", "tblib (>=1.5.0) ; python_version >= \"3.8.0\""] yaml = ["PyYAML (>=3.10)"] zookeeper = ["kazoo (>=1.3.1)"] zstd = ["zstandard (==0.22.0)"] @@ -130,6 +137,7 @@ version = "2023.11.17" description = "Python package for providing Mozilla's CA Bundle." optional = false python-versions = ">=3.6" +groups = ["main"] files = [ {file = "certifi-2023.11.17-py3-none-any.whl", hash = "sha256:e036ab49d5b79556f99cfc2d9320b34cfbe5be05c5871b51de9329f0603b0474"}, {file = "certifi-2023.11.17.tar.gz", hash = "sha256:9b469f3a900bf28dc19b8cfbf8019bf47f7fdd1a65a1d4ffb98fc14166beb4d1"}, @@ -141,6 +149,7 @@ version = "3.3.2" description = "The Real First Universal Charset Detector. Open, modern and actively maintained alternative to Chardet." optional = false python-versions = ">=3.7.0" +groups = ["main"] files = [ {file = "charset-normalizer-3.3.2.tar.gz", hash = "sha256:f30c3cb33b24454a82faecaf01b19c18562b1e89558fb6c56de4d9118a032fd5"}, {file = "charset_normalizer-3.3.2-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:25baf083bf6f6b341f4121c2f3c548875ee6f5339300e08be3f2b2ba1721cdd3"}, @@ -240,6 +249,7 @@ version = "8.1.7" description = "Composable command line interface toolkit" optional = false python-versions = ">=3.7" +groups = ["main"] files = [ {file = "click-8.1.7-py3-none-any.whl", hash = "sha256:ae74fb96c20a0277a1d615f1e4d73c8414f5a98db8b799a7931d1582f3390c28"}, {file = "click-8.1.7.tar.gz", hash = "sha256:ca9853ad459e787e2192211578cc907e7594e294c7ccc834310722b41b9ca6de"}, @@ -254,6 +264,7 @@ version = "0.3.0" description = "Enables git-like *did-you-mean* feature in click" optional = false python-versions = ">=3.6.2,<4.0.0" +groups = ["main"] files = [ {file = "click-didyoumean-0.3.0.tar.gz", hash = "sha256:f184f0d851d96b6d29297354ed981b7dd71df7ff500d82fa6d11f0856bee8035"}, {file = "click_didyoumean-0.3.0-py3-none-any.whl", hash = "sha256:a0713dc7a1de3f06bc0df5a9567ad19ead2d3d5689b434768a6145bff77c0667"}, @@ -268,6 +279,7 @@ version = "1.1.1" description = "An extension module for click to enable registering CLI commands via setuptools entry-points." optional = false python-versions = "*" +groups = ["main"] files = [ {file = "click-plugins-1.1.1.tar.gz", hash = "sha256:46ab999744a9d831159c3411bb0c79346d94a444df9a3a3742e9ed63645f264b"}, {file = "click_plugins-1.1.1-py2.py3-none-any.whl", hash = "sha256:5d262006d3222f5057fd81e1623d4443e41dcda5dc815c06b442aa3c02889fc8"}, @@ -285,6 +297,7 @@ version = "0.3.0" description = "REPL plugin for Click" optional = false python-versions = ">=3.6" +groups = ["main"] files = [ {file = "click-repl-0.3.0.tar.gz", hash = "sha256:17849c23dba3d667247dc4defe1757fff98694e90fe37474f3feebb69ced26a9"}, {file = "click_repl-0.3.0-py3-none-any.whl", hash = "sha256:fb7e06deb8da8de86180a33a9da97ac316751c094c6899382da7feeeeb51b812"}, @@ -303,6 +316,8 @@ version = "0.4.6" description = "Cross-platform colored terminal text." optional = false python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,!=3.6.*,>=2.7" +groups = ["main"] +markers = "platform_system == \"Windows\"" files = [ {file = "colorama-0.4.6-py2.py3-none-any.whl", hash = "sha256:4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6"}, {file = "colorama-0.4.6.tar.gz", hash = "sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44"}, @@ -314,6 +329,8 @@ version = "1.2.0" description = "Backport of PEP 654 (exception groups)" optional = false python-versions = ">=3.7" +groups = ["main"] +markers = "python_version < \"3.11\"" files = [ {file = "exceptiongroup-1.2.0-py3-none-any.whl", hash = "sha256:4bfd3996ac73b41e9b9628b04e079f193850720ea5945fc96a08633c66912f14"}, {file = "exceptiongroup-1.2.0.tar.gz", hash = "sha256:91f5c769735f051a4290d52edd0858999b57e5876e9f85937691bd4c9fa3ed68"}, @@ -328,6 +345,7 @@ version = "3.0.0" description = "A simple framework for building complex web applications." optional = false python-versions = ">=3.8" +groups = ["main"] files = [ {file = "flask-3.0.0-py3-none-any.whl", hash = "sha256:21128f47e4e3b9d597a3e8521a329bf56909b690fcc3fa3e477725aa81367638"}, {file = "flask-3.0.0.tar.gz", hash = "sha256:cfadcdb638b609361d29ec22360d6070a77d7463dcb3ab08d2c2f2f168845f58"}, @@ -350,6 +368,7 @@ version = "2.0.1" description = "Celery Flower" optional = false python-versions = ">=3.7" +groups = ["main"] files = [ {file = "flower-2.0.1-py2.py3-none-any.whl", hash = "sha256:9db2c621eeefbc844c8dd88be64aef61e84e2deb29b271e02ab2b5b9f01068e2"}, {file = "flower-2.0.1.tar.gz", hash = "sha256:5ab717b979530770c16afb48b50d2a98d23c3e9fe39851dcf6bc4d01845a02a0"}, @@ -368,6 +387,7 @@ version = "0.14.0" description = "A pure-Python, bring-your-own-I/O implementation of HTTP/1.1" optional = false python-versions = ">=3.7" +groups = ["main"] files = [ {file = "h11-0.14.0-py3-none-any.whl", hash = "sha256:e3fe4ac4b851c468cc8363d500db52c2ead036020723024a109d37346efaa761"}, {file = "h11-0.14.0.tar.gz", hash = "sha256:8f19fbbe99e72420ff35c00b27a34cb9937e902a8b810e2c88300c6f0a3b699d"}, @@ -379,6 +399,7 @@ version = "1.0.3" description = "A minimal low-level HTTP client." optional = false python-versions = ">=3.8" +groups = ["main"] files = [ {file = "httpcore-1.0.3-py3-none-any.whl", hash = "sha256:9a6a501c3099307d9fd76ac244e08503427679b1e81ceb1d922485e2f2462ad2"}, {file = "httpcore-1.0.3.tar.gz", hash = "sha256:5c0f9546ad17dac4d0772b0808856eb616eb8b48ce94f49ed819fd6982a8a544"}, @@ -400,6 +421,7 @@ version = "0.26.0" description = "The next generation HTTP client." optional = false python-versions = ">=3.8" +groups = ["main"] files = [ {file = "httpx-0.26.0-py3-none-any.whl", hash = "sha256:8915f5a3627c4d47b73e8202457cb28f1266982d1159bd5779d86a80c0eab1cd"}, {file = "httpx-0.26.0.tar.gz", hash = "sha256:451b55c30d5185ea6b23c2c793abf9bb237d2a7dfb901ced6ff69ad37ec1dfaf"}, @@ -413,7 +435,7 @@ idna = "*" sniffio = "*" [package.extras] -brotli = ["brotli", "brotlicffi"] +brotli = ["brotli ; platform_python_implementation == \"CPython\"", "brotlicffi ; platform_python_implementation != \"CPython\""] cli = ["click (==8.*)", "pygments (==2.*)", "rich (>=10,<14)"] http2 = ["h2 (>=3,<5)"] socks = ["socksio (==1.*)"] @@ -424,6 +446,7 @@ version = "4.9.0" description = "Python humanize utilities" optional = false python-versions = ">=3.8" +groups = ["main"] files = [ {file = "humanize-4.9.0-py3-none-any.whl", hash = "sha256:ce284a76d5b1377fd8836733b983bfb0b76f1aa1c090de2566fcf008d7f6ab16"}, {file = "humanize-4.9.0.tar.gz", hash = "sha256:582a265c931c683a7e9b8ed9559089dea7edcf6cc95be39a3cbc2c5d5ac2bcfa"}, @@ -438,6 +461,7 @@ version = "3.6" description = "Internationalized Domain Names in Applications (IDNA)" optional = false python-versions = ">=3.5" +groups = ["main"] files = [ {file = "idna-3.6-py3-none-any.whl", hash = "sha256:c05567e9c24a6b9faaa835c4821bad0590fbb9d5779e7caa6e1cc4978e7eb24f"}, {file = "idna-3.6.tar.gz", hash = "sha256:9ecdbbd083b06798ae1e86adcbfe8ab1479cf864e4ee30fe4e46a003d12491ca"}, @@ -449,6 +473,7 @@ version = "2.1.2" description = "Safely pass data to untrusted environments and back." optional = false python-versions = ">=3.7" +groups = ["main"] files = [ {file = "itsdangerous-2.1.2-py3-none-any.whl", hash = "sha256:2c2349112351b88699d8d4b6b075022c0808887cb7ad10069318a8b0bc88db44"}, {file = "itsdangerous-2.1.2.tar.gz", hash = "sha256:5dbbc68b317e5e42f327f9021763545dc3fc3bfe22e6deb96aaf1fc38874156a"}, @@ -460,6 +485,7 @@ version = "3.1.3" description = "A very fast and expressive template engine." optional = false python-versions = ">=3.7" +groups = ["main"] files = [ {file = "Jinja2-3.1.3-py3-none-any.whl", hash = "sha256:7d6d50dd97d52cbc355597bd845fabfbac3f551e1f99619e39a35ce8c370b5fa"}, {file = "Jinja2-3.1.3.tar.gz", hash = "sha256:ac8bd6544d4bb2c9792bf3a159e80bba8fda7f07e81bc3aed565432d5925ba90"}, @@ -477,6 +503,7 @@ version = "5.3.5" description = "Messaging library for Python." optional = false python-versions = ">=3.8" +groups = ["main"] files = [ {file = "kombu-5.3.5-py3-none-any.whl", hash = "sha256:0eac1bbb464afe6fb0924b21bf79460416d25d8abc52546d4f16cad94f789488"}, {file = "kombu-5.3.5.tar.gz", hash = "sha256:30e470f1a6b49c70dc6f6d13c3e4cc4e178aa6c469ceb6bcd55645385fc84b93"}, @@ -491,7 +518,7 @@ azureservicebus = ["azure-servicebus (>=7.10.0)"] azurestoragequeues = ["azure-identity (>=1.12.0)", "azure-storage-queue (>=12.6.0)"] confluentkafka = ["confluent-kafka (>=2.2.0)"] consul = ["python-consul2"] -librabbitmq = ["librabbitmq (>=2.0.0)"] +librabbitmq = ["librabbitmq (>=2.0.0) ; python_version < \"3.11\""] mongodb = ["pymongo (>=4.1.1)"] msgpack = ["msgpack"] pyro = ["pyro4"] @@ -499,27 +526,27 @@ qpid = ["qpid-python (>=0.26)", "qpid-tools (>=0.26)"] redis = ["redis (>=4.5.2,!=4.5.5,<6.0.0)"] slmq = ["softlayer-messaging (>=1.0.3)"] sqlalchemy = ["sqlalchemy (>=1.4.48,<2.1)"] -sqs = ["boto3 (>=1.26.143)", "pycurl (>=7.43.0.5)", "urllib3 (>=1.26.16)"] +sqs = ["boto3 (>=1.26.143)", "pycurl (>=7.43.0.5) ; sys_platform != \"win32\" and platform_python_implementation == \"CPython\"", "urllib3 (>=1.26.16)"] yaml = ["PyYAML (>=3.10)"] zookeeper = ["kazoo (>=2.8.0)"] [[package]] name = "lark-oapi" -version = "1.2.4" +version = "1.4.12" description = "Lark OpenAPI SDK for Python" optional = false python-versions = ">=3.7" +groups = ["main"] files = [ - {file = "lark-oapi-1.2.4.tar.gz", hash = "sha256:8633928479ccdb5b1f8adfd93b61815d4cd64a63cf2adf75de079a591ce73d5c"}, - {file = "lark_oapi-1.2.4-py3-none-any.whl", hash = "sha256:71fe28eda9776b3387a8d01723a845d6368dd7e617609c4f05a33062eb8dcf21"}, + {file = "lark_oapi-1.4.12-py3-none-any.whl", hash = "sha256:1fd3fb56e552de92aeab9374c7f4ad6d96fa13995c05d209b676c72efa296bcf"}, + {file = "lark_oapi-1.4.12.tar.gz", hash = "sha256:38e728e893a08219e39f60c95bb86832a415d472385f3454bc94f9aeb804f558"}, ] [package.dependencies] httpx = "*" -protobuf = ">3,<4" pycryptodome = "*" requests = "*" -requests-toolbelt = "*" +requests_toolbelt = "*" websockets = "*" [package.extras] @@ -531,6 +558,7 @@ version = "2.1.3" description = "Safely add untrusted strings to HTML/XML markup." optional = false python-versions = ">=3.7" +groups = ["main"] files = [ {file = "MarkupSafe-2.1.3-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:cd0f502fe016460680cd20aaa5a76d241d6f35a1c3350c474bac1273803893fa"}, {file = "MarkupSafe-2.1.3-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:e09031c87a1e51556fdcb46e5bd4f59dfb743061cf93c4d6831bf894f125eb57"}, @@ -600,6 +628,7 @@ version = "0.19.0" description = "Python client for the Prometheus monitoring system." optional = false python-versions = ">=3.8" +groups = ["main"] files = [ {file = "prometheus_client-0.19.0-py3-none-any.whl", hash = "sha256:c88b1e6ecf6b41cd8fb5731c7ae919bf66df6ec6fafa555cd6c0e16ca169ae92"}, {file = "prometheus_client-0.19.0.tar.gz", hash = "sha256:4585b0d1223148c27a225b10dbec5ae9bc4c81a99a3fa80774fa6209935324e1"}, @@ -614,6 +643,7 @@ version = "3.0.43" description = "Library for building powerful interactive command lines in Python" optional = false python-versions = ">=3.7.0" +groups = ["main"] files = [ {file = "prompt_toolkit-3.0.43-py3-none-any.whl", hash = "sha256:a11a29cb3bf0a28a387fe5122cdb649816a957cd9261dcedf8c9f1fef33eacf6"}, {file = "prompt_toolkit-3.0.43.tar.gz", hash = "sha256:3527b7af26106cbc65a040bcc84839a3566ec1b051bb0bfe953631e704b0ff7d"}, @@ -622,43 +652,13 @@ files = [ [package.dependencies] wcwidth = "*" -[[package]] -name = "protobuf" -version = "3.20.3" -description = "Protocol Buffers" -optional = false -python-versions = ">=3.7" -files = [ - {file = "protobuf-3.20.3-cp310-cp310-manylinux2014_aarch64.whl", hash = "sha256:f4bd856d702e5b0d96a00ec6b307b0f51c1982c2bf9c0052cf9019e9a544ba99"}, - {file = "protobuf-3.20.3-cp310-cp310-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:9aae4406ea63d825636cc11ffb34ad3379335803216ee3a856787bcf5ccc751e"}, - {file = "protobuf-3.20.3-cp310-cp310-win32.whl", hash = "sha256:28545383d61f55b57cf4df63eebd9827754fd2dc25f80c5253f9184235db242c"}, - {file = "protobuf-3.20.3-cp310-cp310-win_amd64.whl", hash = "sha256:67a3598f0a2dcbc58d02dd1928544e7d88f764b47d4a286202913f0b2801c2e7"}, - {file = "protobuf-3.20.3-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:899dc660cd599d7352d6f10d83c95df430a38b410c1b66b407a6b29265d66469"}, - {file = "protobuf-3.20.3-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:e64857f395505ebf3d2569935506ae0dfc4a15cb80dc25261176c784662cdcc4"}, - {file = "protobuf-3.20.3-cp37-cp37m-manylinux2014_aarch64.whl", hash = "sha256:d9e4432ff660d67d775c66ac42a67cf2453c27cb4d738fc22cb53b5d84c135d4"}, - {file = "protobuf-3.20.3-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:74480f79a023f90dc6e18febbf7b8bac7508420f2006fabd512013c0c238f454"}, - {file = "protobuf-3.20.3-cp37-cp37m-win32.whl", hash = "sha256:b6cc7ba72a8850621bfec987cb72623e703b7fe2b9127a161ce61e61558ad905"}, - {file = "protobuf-3.20.3-cp37-cp37m-win_amd64.whl", hash = "sha256:8c0c984a1b8fef4086329ff8dd19ac77576b384079247c770f29cc8ce3afa06c"}, - {file = "protobuf-3.20.3-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:de78575669dddf6099a8a0f46a27e82a1783c557ccc38ee620ed8cc96d3be7d7"}, - {file = "protobuf-3.20.3-cp38-cp38-manylinux2014_aarch64.whl", hash = "sha256:f4c42102bc82a51108e449cbb32b19b180022941c727bac0cfd50170341f16ee"}, - {file = "protobuf-3.20.3-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:44246bab5dd4b7fbd3c0c80b6f16686808fab0e4aca819ade6e8d294a29c7050"}, - {file = "protobuf-3.20.3-cp38-cp38-win32.whl", hash = "sha256:c02ce36ec760252242a33967d51c289fd0e1c0e6e5cc9397e2279177716add86"}, - {file = "protobuf-3.20.3-cp38-cp38-win_amd64.whl", hash = "sha256:447d43819997825d4e71bf5769d869b968ce96848b6479397e29fc24c4a5dfe9"}, - {file = "protobuf-3.20.3-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:398a9e0c3eaceb34ec1aee71894ca3299605fa8e761544934378bbc6c97de23b"}, - {file = "protobuf-3.20.3-cp39-cp39-manylinux2014_aarch64.whl", hash = "sha256:bf01b5720be110540be4286e791db73f84a2b721072a3711efff6c324cdf074b"}, - {file = "protobuf-3.20.3-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:daa564862dd0d39c00f8086f88700fdbe8bc717e993a21e90711acfed02f2402"}, - {file = "protobuf-3.20.3-cp39-cp39-win32.whl", hash = "sha256:819559cafa1a373b7096a482b504ae8a857c89593cf3a25af743ac9ecbd23480"}, - {file = "protobuf-3.20.3-cp39-cp39-win_amd64.whl", hash = "sha256:03038ac1cfbc41aa21f6afcbcd357281d7521b4157926f30ebecc8d4ea59dcb7"}, - {file = "protobuf-3.20.3-py2.py3-none-any.whl", hash = "sha256:a7ca6d488aa8ff7f329d4c545b2dbad8ac31464f1d8b1c87ad1346717731e4db"}, - {file = "protobuf-3.20.3.tar.gz", hash = "sha256:2e3427429c9cffebf259491be0af70189607f365c2f41c7c3764af6f337105f2"}, -] - [[package]] name = "pycryptodome" version = "3.20.0" description = "Cryptographic library for Python" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" +groups = ["main"] files = [ {file = "pycryptodome-3.20.0-cp27-cp27m-macosx_10_9_x86_64.whl", hash = "sha256:f0e6d631bae3f231d3634f91ae4da7a960f7ff87f2865b2d2b831af1dfb04e9a"}, {file = "pycryptodome-3.20.0-cp27-cp27m-manylinux2010_i686.whl", hash = "sha256:baee115a9ba6c5d2709a1e88ffe62b73ecc044852a925dcb67713a288c4ec70f"}, @@ -700,6 +700,7 @@ version = "2.8.2" description = "Extensions to the standard Python datetime module" optional = false python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,>=2.7" +groups = ["main"] files = [ {file = "python-dateutil-2.8.2.tar.gz", hash = "sha256:0123cacc1627ae19ddf3c27a5de5bd67ee4586fbdd6440d9748f8abb483d3e86"}, {file = "python_dateutil-2.8.2-py2.py3-none-any.whl", hash = "sha256:961d03dc3453ebbc59dbdea9e4e11c5651520a876d0f4db161e8674aae935da9"}, @@ -714,6 +715,7 @@ version = "1.0.0" description = "Read key-value pairs from a .env file and set them as environment variables" optional = false python-versions = ">=3.8" +groups = ["main"] files = [ {file = "python-dotenv-1.0.0.tar.gz", hash = "sha256:a8df96034aae6d2d50a4ebe8216326c61c3eb64836776504fcca410e5937a3ba"}, {file = "python_dotenv-1.0.0-py3-none-any.whl", hash = "sha256:f5971a9226b701070a4bf2c38c89e5a3f0d64de8debda981d1db98583009122a"}, @@ -728,6 +730,7 @@ version = "2024.1" description = "World timezone definitions, modern and historical" optional = false python-versions = "*" +groups = ["main"] files = [ {file = "pytz-2024.1-py2.py3-none-any.whl", hash = "sha256:328171f4e3623139da4983451950b28e95ac706e13f3f2630a879749e7a8b319"}, {file = "pytz-2024.1.tar.gz", hash = "sha256:2a29735ea9c18baf14b448846bde5a48030ed267578472d8955cd0e7443a9812"}, @@ -739,6 +742,7 @@ version = "5.0.1" description = "Python client for Redis database and key-value store" optional = false python-versions = ">=3.7" +groups = ["main"] files = [ {file = "redis-5.0.1-py3-none-any.whl", hash = "sha256:ed4802971884ae19d640775ba3b03aa2e7bd5e8fb8dfaed2decce4d0fc48391f"}, {file = "redis-5.0.1.tar.gz", hash = "sha256:0dab495cd5753069d3bc650a0dde8a8f9edde16fc5691b689a566eda58100d0f"}, @@ -757,6 +761,7 @@ version = "2.31.0" description = "Python HTTP for Humans." optional = false python-versions = ">=3.7" +groups = ["main"] files = [ {file = "requests-2.31.0-py3-none-any.whl", hash = "sha256:58cd2187c01e70e6e26505bca751777aa9f2ee0b7f4300988b709f44e013003f"}, {file = "requests-2.31.0.tar.gz", hash = "sha256:942c5a758f98d790eaed1a29cb6eefc7ffb0d1cf7af05c3d2791656dbd6ad1e1"}, @@ -778,6 +783,7 @@ version = "1.0.0" description = "A utility belt for advanced users of python-requests" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" +groups = ["main"] files = [ {file = "requests-toolbelt-1.0.0.tar.gz", hash = "sha256:7681a0a3d047012b5bdc0ee37d7f8f07ebe76ab08caeccfc3921ce23c88d5bc6"}, {file = "requests_toolbelt-1.0.0-py2.py3-none-any.whl", hash = "sha256:cccfdd665f0a24fcf4726e690f65639d272bb0637b9b92dfd91a5568ccf6bd06"}, @@ -792,6 +798,7 @@ version = "1.16.0" description = "Python 2 and 3 compatibility utilities" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*" +groups = ["main"] files = [ {file = "six-1.16.0-py2.py3-none-any.whl", hash = "sha256:8abb2f1d86890a2dfb989f9a77cfcfd3e47c2a354b01111771326f8aa26e0254"}, {file = "six-1.16.0.tar.gz", hash = "sha256:1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926"}, @@ -803,6 +810,7 @@ version = "1.3.0" description = "Sniff out which async library your code is running under" optional = false python-versions = ">=3.7" +groups = ["main"] files = [ {file = "sniffio-1.3.0-py3-none-any.whl", hash = "sha256:eecefdce1e5bbfb7ad2eeaabf7c1eeb404d7757c379bd1f7e5cce9d8bf425384"}, {file = "sniffio-1.3.0.tar.gz", hash = "sha256:e60305c5e5d314f5389259b7f22aaa33d8f7dee49763119234af3755c55b9101"}, @@ -814,6 +822,7 @@ version = "6.4" description = "Tornado is a Python web framework and asynchronous networking library, originally developed at FriendFeed." optional = false python-versions = ">= 3.8" +groups = ["main"] files = [ {file = "tornado-6.4-cp38-abi3-macosx_10_9_universal2.whl", hash = "sha256:02ccefc7d8211e5a7f9e8bc3f9e5b0ad6262ba2fbb683a6443ecc804e5224ce0"}, {file = "tornado-6.4-cp38-abi3-macosx_10_9_x86_64.whl", hash = "sha256:27787de946a9cffd63ce5814c33f734c627a87072ec7eed71f7fc4417bb16263"}, @@ -834,6 +843,8 @@ version = "4.9.0" description = "Backported and Experimental Type Hints for Python 3.8+" optional = false python-versions = ">=3.8" +groups = ["main"] +markers = "python_version < \"3.11\"" files = [ {file = "typing_extensions-4.9.0-py3-none-any.whl", hash = "sha256:af72aea155e91adfc61c3ae9e0e342dbc0cba726d6cba4b6c72c1f34e47291cd"}, {file = "typing_extensions-4.9.0.tar.gz", hash = "sha256:23478f88c37f27d76ac8aee6c905017a143b0b1b886c3c9f66bc2fd94f9f5783"}, @@ -845,6 +856,7 @@ version = "2023.4" description = "Provider of IANA time zone data" optional = false python-versions = ">=2" +groups = ["main"] files = [ {file = "tzdata-2023.4-py2.py3-none-any.whl", hash = "sha256:aa3ace4329eeacda5b7beb7ea08ece826c28d761cda36e747cfbf97996d39bf3"}, {file = "tzdata-2023.4.tar.gz", hash = "sha256:dd54c94f294765522c77399649b4fefd95522479a664a0cec87f41bebc6148c9"}, @@ -856,13 +868,14 @@ version = "2.1.0" description = "HTTP library with thread-safe connection pooling, file post, and more." optional = false python-versions = ">=3.8" +groups = ["main"] files = [ {file = "urllib3-2.1.0-py3-none-any.whl", hash = "sha256:55901e917a5896a349ff771be919f8bd99aff50b79fe58fec595eb37bbc56bb3"}, {file = "urllib3-2.1.0.tar.gz", hash = "sha256:df7aa8afb0148fa78488e7899b2c59b5f4ffcfa82e6c54ccb9dd37c1d7b52d54"}, ] [package.extras] -brotli = ["brotli (>=1.0.9)", "brotlicffi (>=0.8.0)"] +brotli = ["brotli (>=1.0.9) ; platform_python_implementation == \"CPython\"", "brotlicffi (>=0.8.0) ; platform_python_implementation != \"CPython\""] socks = ["pysocks (>=1.5.6,!=1.5.7,<2.0)"] zstd = ["zstandard (>=0.18.0)"] @@ -872,6 +885,7 @@ version = "5.1.0" description = "Python promises." optional = false python-versions = ">=3.6" +groups = ["main"] files = [ {file = "vine-5.1.0-py3-none-any.whl", hash = "sha256:40fdf3c48b2cfe1c38a49e9ae2da6fda88e4794c810050a728bd7413811fb1dc"}, {file = "vine-5.1.0.tar.gz", hash = "sha256:8b62e981d35c41049211cf62a0a1242d8c1ee9bd15bb196ce38aefd6799e61e0"}, @@ -883,6 +897,7 @@ version = "0.2.13" description = "Measures the displayed width of unicode strings in a terminal" optional = false python-versions = "*" +groups = ["main"] files = [ {file = "wcwidth-0.2.13-py2.py3-none-any.whl", hash = "sha256:3da69048e4540d84af32131829ff948f1e022c1c6bdb8d6102117aac784f6859"}, {file = "wcwidth-0.2.13.tar.gz", hash = "sha256:72ea0c06399eb286d978fdedb6923a9eb47e1c486ce63e9b4e64fc18303972b5"}, @@ -894,6 +909,7 @@ version = "12.0" description = "An implementation of the WebSocket Protocol (RFC 6455 & 7692)" optional = false python-versions = ">=3.8" +groups = ["main"] files = [ {file = "websockets-12.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:d554236b2a2006e0ce16315c16eaa0d628dab009c33b63ea03f41c6107958374"}, {file = "websockets-12.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:2d225bb6886591b1746b17c0573e29804619c8f755b5598d875bb4235ea639be"}, @@ -975,6 +991,7 @@ version = "3.0.1" description = "The comprehensive WSGI web application library." optional = false python-versions = ">=3.8" +groups = ["main"] files = [ {file = "werkzeug-3.0.1-py3-none-any.whl", hash = "sha256:90a285dc0e42ad56b34e696398b8122ee4c681833fb35b8334a095d82c56da10"}, {file = "werkzeug-3.0.1.tar.gz", hash = "sha256:507e811ecea72b18a404947aded4b3390e1db8f826b494d76550ef45bb3b1dcc"}, @@ -987,6 +1004,6 @@ MarkupSafe = ">=2.1.1" watchdog = ["watchdog (>=2.3)"] [metadata] -lock-version = "2.0" +lock-version = "2.1" python-versions = "^3.10" content-hash = "6207bf180859ab22563c428c0746b17f8826819777b210fd363b807209f4b2b2" diff --git a/requirements.txt b/requirements.txt index 0f4a513..70ec9ab 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,16 +1,36 @@ +amqp==5.3.1 +anyio==4.9.0 +billiard==4.2.1 blinker==1.7.0 +celery==5.4.0 certifi==2023.11.17 charset-normalizer==3.3.2 click==8.1.7 +click-didyoumean==0.3.1 +click-plugins==1.1.1 +click-repl==0.3.0 +colorama==0.4.6 Flask==3.0.0 +h11==0.14.0 +httpcore==1.0.7 +httpx==0.28.1 idna==3.6 itsdangerous==2.1.2 Jinja2==3.1.3 -lark-oapi==1.0.28 +kombu==5.5.1 +lark-oapi==1.4.12 MarkupSafe==2.1.3 +prompt_toolkit==3.0.50 pycryptodome==3.20.0 +python-dateutil==2.9.0.post0 python-dotenv==1.0.0 requests==2.31.0 requests-toolbelt==1.0.0 +six==1.17.0 +sniffio==1.3.1 +tzdata==2025.1 urllib3==2.1.0 +vine==5.1.0 +wcwidth==0.2.13 +websockets==15.0.1 Werkzeug==3.0.1