Merge branch 'main' of git.woni.link:wn0x00/office_xbot_feishu

合并
This commit is contained in:
jianxin committed 2025-10-10 09:38:44 +08:00
commit a6bb166a28
6 files changed
+610 -57

No files matched your search

-1
View File
@@ -6,7 +6,6 @@ WORKDIR /tmp
#
RUN pip install poetry -i https://pypi.tuna.tsinghua.edu.cn/simple
#
COPY ./pyproject.toml ./poetry.lock* /tmp/
+37 -2
View File
@@ -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
+14 -1
View File
@@ -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)
+469
View File
@@ -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))
Generated
+69 -52
View File
@@ -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"
+21 -1
View File
@@ -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