qg-botsdk


Nameqg-botsdk JSON
Version 4.3.3 PyPI version JSON
download
home_pagehttps://github.com/GLGDLY/qg_botsdk
Summaryeasy-to-use SDK for Tencent QQ guild robot
upload_time2025-01-15 12:35:17
maintainerNone
docs_urlNone
authorGDLY
requires_python<4,>=3.7
licenseNone
keywords sample example setuptools
VCS
bugtrack_url
requirements aiohttp setuptools
Travis-CI No Travis.
coveralls test coverage No coveralls.
            .. image:: https://socialify.git.ci/GLGDLY/qg_botsdk/image?description=1&font=Source%20Code%20Pro&forks=1&issues=1&language=1&logo=https%3A%2F%2Fgithub.com%2Ftencent-connect%2Fbot-docs%2Fblob%2Fmain%2Fdocs%2F.vuepress%2Fpublic%2Ffavicon-64px.png%3Fraw%3Dtrue&name=1&owner=1&pattern=Floating%20Cogs&pulls=1&stargazers=1&theme=Light

|

.. image:: https://img.shields.io/badge/language-python-green.svg?style=plastic
   :target: https://www.python.org/
.. image:: https://img.shields.io/badge/license-MIT-orange.svg?style=plastic
   :target: https://github.com/GLGDLY/qg_botsdk/blob/master/LICENSE
.. image:: https://img.shields.io/pypi/dw/qg-botsdk?style=plastic&color=blue
   :target: https://pypi.org/project/qg-botsdk/
.. image:: https://app.codacy.com/project/badge/Grade/f015549b3dba4602be2fe0f5d8b0a8d5
   :target: https://www.codacy.com/gh/GLGDLY/qg_botsdk/dashboard?utm_source=github.com&utm_medium=referral&utm_content=GLGDLY/qg_botsdk&utm_campaign=Badge_Grade
.. image:: https://readthedocs.org/projects/qg-botsdk/badge/?version=latest
   :target: https://qg-botsdk.readthedocs.io/zh_CN/latest/

引言
=====

对于使用python进行频道官方机器人开发而言,市面上确实有不同的sdk可以选用,但其很多只提供异步asyncio+类继承的开发方式,对于不会相关技巧的朋友们,尤其新手,会有开发难度。

为此,qg_botsdk相应提供了另一个选择,这一款sdk虽然同样使用asyncio编写sdk底层,但其同时提供了threading和asyncio封装下的应用层调用,以抽象化封装的库编写方式,极大地降低应用层的开发难度。



亮点
=====

-   已支持Websocket、Webhook、Remote Webhook(wh转ws允许本地调试)三种连接方式

-   已支持SDK层面的沙箱处理,允许沙箱过滤外部消息、外部过滤沙箱消息;已支持频道、频道私信、群、QQ私信四种沙箱过滤模式

-   两种应用层开发方式(threading、asyncio),可根据自己的喜好选择,而底层均为asyncio实现,保持高并发能力

-   灵活的构建方式,即使官方删除或新增字段,SDK也不会规范于原来的数据格式,而会把真实数据反馈给你

-   轻量,简洁,统一的代码结构,通过录入回调函数处理不同事件,10行即可构建一个简单的程序

-   容易入门,无需学会asyncio、类继承等编程技巧也可使用,同时保留较高并发能力

-   保留官方http API中Json数据的结构字段,带你学习官方结构,日后可自行开发适合自己的SDK

-   简单易用的plugins编写与加载,使用例子可参阅 `example_13(装饰器).py <./example/example_13(%E8%A3%85%E9%A5%B0%E5%99%A8).py>`_

-   方便多场景(频道+群等)构建机器人的抽象化封装,使用例子可参阅 `example_16(Q群简单工作流).py <./example/example_16(Q%E7%BE%A4%E7%AE%80%E5%8D%95%E5%B7%A5%E4%BD%9C%E6%B5%81).py>`_

下载方式
==========

-   pip安装(推荐):

.. code-block:: bash

    pip install qg-botsdk

**注意是qg-botsdk(中线),不是qg_botsdk(底线)**

一个简单的工作流
==================

| -   注册BOT实例,录入机器人平台获取的ID(BotAppId开发者ID)和token(机器人令牌)
| -   编写接收事件的函数->下方例子:``def deliver(data)``,并可借助model库检查数据格式(``data: Model.MESSAGE``)
| -   绑定接收事件的函数(bind_msg、bind_dm、bind_msg_delete、bind_guild_event、bind_guild_member、bind_reaction、bind_interaction、bind_audit、bind_forum、bind_audio)
| -   开始运行机器人:bot.start()

.. code-block:: python

    from qg_botsdk import BOT, Model   # 导入SDK核心类(BOT)、所有数据模型(Model)

    bot = BOT(bot_id='xxx', bot_token='xxx', is_private=True, is_sandbox=True)   # 实例化SDK核心类


    @bot.bind_msg()   # 绑定接收消息事件的函数
    def deliver(data: Model.MESSAGE):   # 创建接收消息事件的函数
        if '你好' in data.treated_msg:   # 判断消息是否存在特定内容
            data.reply('你好,世界')   # 发送被动回复(带message_id直接reply回复)
            # 如需使用如 Embed 等消息模板,可传入相应结构体, 如:
            # data.reply(ApiModel.MessageEmbed(title="你好", content="世界"))


    if __name__ == '__main__':
        bot.start()   # 开始运行机器人

指令装饰器
==================

SDK同时已经在内部实现指令装饰器:

.. code-block:: python

    from qg_botsdk import BOT, Model 

    bot = BOT(bot_id='xxx', bot_token='xxx', is_private=True, is_sandbox=True)

    # before_command代表预处理器,将在检查所有commands前执行(要求SDK版本>=2.5.2)
    @bot.before_command()
    def preprocessor(data: Model.MESSAGE):
        bot.logger.info(f"收到来自{data.author.username}的消息:{data.treated_msg}")


    @bot.on_command(
        regex=r"你好(?:机器人)?",  # 正则表达式,匹配用户消息
        is_short_circuit=True,    # is_short_circuit代表短路机制,根据注册顺序,匹配到即停止匹配,但不影响bind_msg()
        is_require_at=True,       # is_require_at代表是否要求检测到用户@了机器人才可触发指令
        is_require_admin=True,    # is_require_admin代表是否要求检测到用户是频道主或频道管理才可触发指令
        admin_error_msg="抱歉,你的权限不足(非频道主或管理员),不能使用此指令",
    )
    def command(data: Model.MESSAGE):
        data.reply("你好,世界")


    if __name__ == '__main__':
        bot.start()


相关链接
========

-   更多完整例程:
     * `example <https://github.com/GLGDLY/qg_botsdk/tree/master/example>`_
-   文档:
     * `readthedocs <https://qg-botsdk.readthedocs.io/zh_CN/latest/>`_
-   官方注册机器人:https://q.qq.com/#/
-   官方API文档:https://bot.q.qq.com/wiki/develop/api/
-   SDK QQ交流群:https://jq.qq.com/?_wv=1027&k=3NnWvGpz

            

Raw data

            {
    "_id": null,
    "home_page": "https://github.com/GLGDLY/qg_botsdk",
    "name": "qg-botsdk",
    "maintainer": null,
    "docs_url": null,
    "requires_python": "<4,>=3.7",
    "maintainer_email": null,
    "keywords": "sample, example, setuptools",
    "author": "GDLY",
    "author_email": "tzlgdly@gmail.com",
    "download_url": null,
    "platform": null,
    "description": ".. image:: https://socialify.git.ci/GLGDLY/qg_botsdk/image?description=1&font=Source%20Code%20Pro&forks=1&issues=1&language=1&logo=https%3A%2F%2Fgithub.com%2Ftencent-connect%2Fbot-docs%2Fblob%2Fmain%2Fdocs%2F.vuepress%2Fpublic%2Ffavicon-64px.png%3Fraw%3Dtrue&name=1&owner=1&pattern=Floating%20Cogs&pulls=1&stargazers=1&theme=Light\r\n\r\n|\r\n\r\n.. image:: https://img.shields.io/badge/language-python-green.svg?style=plastic\r\n   :target: https://www.python.org/\r\n.. image:: https://img.shields.io/badge/license-MIT-orange.svg?style=plastic\r\n   :target: https://github.com/GLGDLY/qg_botsdk/blob/master/LICENSE\r\n.. image:: https://img.shields.io/pypi/dw/qg-botsdk?style=plastic&color=blue\r\n   :target: https://pypi.org/project/qg-botsdk/\r\n.. image:: https://app.codacy.com/project/badge/Grade/f015549b3dba4602be2fe0f5d8b0a8d5\r\n   :target: https://www.codacy.com/gh/GLGDLY/qg_botsdk/dashboard?utm_source=github.com&utm_medium=referral&utm_content=GLGDLY/qg_botsdk&utm_campaign=Badge_Grade\r\n.. image:: https://readthedocs.org/projects/qg-botsdk/badge/?version=latest\r\n   :target: https://qg-botsdk.readthedocs.io/zh_CN/latest/\r\n\r\n\u5f15\u8a00\r\n=====\r\n\r\n\u5bf9\u4e8e\u4f7f\u7528python\u8fdb\u884c\u9891\u9053\u5b98\u65b9\u673a\u5668\u4eba\u5f00\u53d1\u800c\u8a00\uff0c\u5e02\u9762\u4e0a\u786e\u5b9e\u6709\u4e0d\u540c\u7684sdk\u53ef\u4ee5\u9009\u7528\uff0c\u4f46\u5176\u5f88\u591a\u53ea\u63d0\u4f9b\u5f02\u6b65asyncio+\u7c7b\u7ee7\u627f\u7684\u5f00\u53d1\u65b9\u5f0f\uff0c\u5bf9\u4e8e\u4e0d\u4f1a\u76f8\u5173\u6280\u5de7\u7684\u670b\u53cb\u4eec\uff0c\u5c24\u5176\u65b0\u624b\uff0c\u4f1a\u6709\u5f00\u53d1\u96be\u5ea6\u3002\r\n\r\n\u4e3a\u6b64\uff0cqg_botsdk\u76f8\u5e94\u63d0\u4f9b\u4e86\u53e6\u4e00\u4e2a\u9009\u62e9\uff0c\u8fd9\u4e00\u6b3esdk\u867d\u7136\u540c\u6837\u4f7f\u7528asyncio\u7f16\u5199sdk\u5e95\u5c42\uff0c\u4f46\u5176\u540c\u65f6\u63d0\u4f9b\u4e86threading\u548casyncio\u5c01\u88c5\u4e0b\u7684\u5e94\u7528\u5c42\u8c03\u7528\uff0c\u4ee5\u62bd\u8c61\u5316\u5c01\u88c5\u7684\u5e93\u7f16\u5199\u65b9\u5f0f\uff0c\u6781\u5927\u5730\u964d\u4f4e\u5e94\u7528\u5c42\u7684\u5f00\u53d1\u96be\u5ea6\u3002\r\n\r\n\r\n\r\n\u4eae\u70b9\r\n=====\r\n\r\n-   \u5df2\u652f\u6301Websocket\u3001Webhook\u3001Remote Webhook\uff08wh\u8f6cws\u5141\u8bb8\u672c\u5730\u8c03\u8bd5\uff09\u4e09\u79cd\u8fde\u63a5\u65b9\u5f0f\r\n\r\n-   \u5df2\u652f\u6301SDK\u5c42\u9762\u7684\u6c99\u7bb1\u5904\u7406\uff0c\u5141\u8bb8\u6c99\u7bb1\u8fc7\u6ee4\u5916\u90e8\u6d88\u606f\u3001\u5916\u90e8\u8fc7\u6ee4\u6c99\u7bb1\u6d88\u606f\uff1b\u5df2\u652f\u6301\u9891\u9053\u3001\u9891\u9053\u79c1\u4fe1\u3001\u7fa4\u3001QQ\u79c1\u4fe1\u56db\u79cd\u6c99\u7bb1\u8fc7\u6ee4\u6a21\u5f0f\r\n\r\n-   \u4e24\u79cd\u5e94\u7528\u5c42\u5f00\u53d1\u65b9\u5f0f\uff08threading\u3001asyncio\uff09\uff0c\u53ef\u6839\u636e\u81ea\u5df1\u7684\u559c\u597d\u9009\u62e9\uff0c\u800c\u5e95\u5c42\u5747\u4e3aasyncio\u5b9e\u73b0\uff0c\u4fdd\u6301\u9ad8\u5e76\u53d1\u80fd\u529b\r\n\r\n-   \u7075\u6d3b\u7684\u6784\u5efa\u65b9\u5f0f\uff0c\u5373\u4f7f\u5b98\u65b9\u5220\u9664\u6216\u65b0\u589e\u5b57\u6bb5\uff0cSDK\u4e5f\u4e0d\u4f1a\u89c4\u8303\u4e8e\u539f\u6765\u7684\u6570\u636e\u683c\u5f0f\uff0c\u800c\u4f1a\u628a\u771f\u5b9e\u6570\u636e\u53cd\u9988\u7ed9\u4f60\r\n\r\n-   \u8f7b\u91cf\uff0c\u7b80\u6d01\uff0c\u7edf\u4e00\u7684\u4ee3\u7801\u7ed3\u6784\uff0c\u901a\u8fc7\u5f55\u5165\u56de\u8c03\u51fd\u6570\u5904\u7406\u4e0d\u540c\u4e8b\u4ef6\uff0c10\u884c\u5373\u53ef\u6784\u5efa\u4e00\u4e2a\u7b80\u5355\u7684\u7a0b\u5e8f\r\n\r\n-   \u5bb9\u6613\u5165\u95e8\uff0c\u65e0\u9700\u5b66\u4f1aasyncio\u3001\u7c7b\u7ee7\u627f\u7b49\u7f16\u7a0b\u6280\u5de7\u4e5f\u53ef\u4f7f\u7528\uff0c\u540c\u65f6\u4fdd\u7559\u8f83\u9ad8\u5e76\u53d1\u80fd\u529b\r\n\r\n-   \u4fdd\u7559\u5b98\u65b9http API\u4e2dJson\u6570\u636e\u7684\u7ed3\u6784\u5b57\u6bb5\uff0c\u5e26\u4f60\u5b66\u4e60\u5b98\u65b9\u7ed3\u6784\uff0c\u65e5\u540e\u53ef\u81ea\u884c\u5f00\u53d1\u9002\u5408\u81ea\u5df1\u7684SDK\r\n\r\n-   \u7b80\u5355\u6613\u7528\u7684plugins\u7f16\u5199\u4e0e\u52a0\u8f7d\uff0c\u4f7f\u7528\u4f8b\u5b50\u53ef\u53c2\u9605 `example_13(\u88c5\u9970\u5668).py <./example/example_13(%E8%A3%85%E9%A5%B0%E5%99%A8).py>`_\r\n\r\n-   \u65b9\u4fbf\u591a\u573a\u666f\uff08\u9891\u9053+\u7fa4\u7b49\uff09\u6784\u5efa\u673a\u5668\u4eba\u7684\u62bd\u8c61\u5316\u5c01\u88c5\uff0c\u4f7f\u7528\u4f8b\u5b50\u53ef\u53c2\u9605 `example_16(Q\u7fa4\u7b80\u5355\u5de5\u4f5c\u6d41).py <./example/example_16(Q%E7%BE%A4%E7%AE%80%E5%8D%95%E5%B7%A5%E4%BD%9C%E6%B5%81).py>`_\r\n\r\n\u4e0b\u8f7d\u65b9\u5f0f\r\n==========\r\n\r\n-   pip\u5b89\u88c5\uff08\u63a8\u8350\uff09\uff1a\r\n\r\n.. code-block:: bash\r\n\r\n    pip install qg-botsdk\r\n\r\n**\u6ce8\u610f\u662fqg-botsdk\uff08\u4e2d\u7ebf\uff09\uff0c\u4e0d\u662fqg_botsdk\uff08\u5e95\u7ebf\uff09**\r\n\r\n\u4e00\u4e2a\u7b80\u5355\u7684\u5de5\u4f5c\u6d41\r\n==================\r\n\r\n| -   \u6ce8\u518cBOT\u5b9e\u4f8b\uff0c\u5f55\u5165\u673a\u5668\u4eba\u5e73\u53f0\u83b7\u53d6\u7684ID\uff08BotAppId\u5f00\u53d1\u8005ID\uff09\u548ctoken\uff08\u673a\u5668\u4eba\u4ee4\u724c\uff09\r\n| -   \u7f16\u5199\u63a5\u6536\u4e8b\u4ef6\u7684\u51fd\u6570->\u4e0b\u65b9\u4f8b\u5b50\uff1a``def deliver(data)``\uff0c\u5e76\u53ef\u501f\u52a9model\u5e93\u68c0\u67e5\u6570\u636e\u683c\u5f0f\uff08``data: Model.MESSAGE``\uff09\r\n| -   \u7ed1\u5b9a\u63a5\u6536\u4e8b\u4ef6\u7684\u51fd\u6570\uff08bind_msg\u3001bind_dm\u3001bind_msg_delete\u3001bind_guild_event\u3001bind_guild_member\u3001bind_reaction\u3001bind_interaction\u3001bind_audit\u3001bind_forum\u3001bind_audio\uff09\r\n| -   \u5f00\u59cb\u8fd0\u884c\u673a\u5668\u4eba\uff1abot.start()\r\n\r\n.. code-block:: python\r\n\r\n    from qg_botsdk import BOT, Model   # \u5bfc\u5165SDK\u6838\u5fc3\u7c7b\uff08BOT\uff09\u3001\u6240\u6709\u6570\u636e\u6a21\u578b\uff08Model\uff09\r\n\r\n    bot = BOT(bot_id='xxx', bot_token='xxx', is_private=True, is_sandbox=True)   # \u5b9e\u4f8b\u5316SDK\u6838\u5fc3\u7c7b\r\n\r\n\r\n    @bot.bind_msg()   # \u7ed1\u5b9a\u63a5\u6536\u6d88\u606f\u4e8b\u4ef6\u7684\u51fd\u6570\r\n    def deliver(data: Model.MESSAGE):   # \u521b\u5efa\u63a5\u6536\u6d88\u606f\u4e8b\u4ef6\u7684\u51fd\u6570\r\n        if '\u4f60\u597d' in data.treated_msg:   # \u5224\u65ad\u6d88\u606f\u662f\u5426\u5b58\u5728\u7279\u5b9a\u5185\u5bb9\r\n            data.reply('\u4f60\u597d\uff0c\u4e16\u754c')   # \u53d1\u9001\u88ab\u52a8\u56de\u590d\uff08\u5e26message_id\u76f4\u63a5reply\u56de\u590d\uff09\r\n            # \u5982\u9700\u4f7f\u7528\u5982 Embed \u7b49\u6d88\u606f\u6a21\u677f\uff0c\u53ef\u4f20\u5165\u76f8\u5e94\u7ed3\u6784\u4f53\uff0c \u5982\uff1a\r\n            # data.reply(ApiModel.MessageEmbed(title=\"\u4f60\u597d\", content=\"\u4e16\u754c\"))\r\n\r\n\r\n    if __name__ == '__main__':\r\n        bot.start()   # \u5f00\u59cb\u8fd0\u884c\u673a\u5668\u4eba\r\n\r\n\u6307\u4ee4\u88c5\u9970\u5668\r\n==================\r\n\r\nSDK\u540c\u65f6\u5df2\u7ecf\u5728\u5185\u90e8\u5b9e\u73b0\u6307\u4ee4\u88c5\u9970\u5668\uff1a\r\n\r\n.. code-block:: python\r\n\r\n    from qg_botsdk import BOT, Model \r\n\r\n    bot = BOT(bot_id='xxx', bot_token='xxx', is_private=True, is_sandbox=True)\r\n\r\n    # before_command\u4ee3\u8868\u9884\u5904\u7406\u5668\uff0c\u5c06\u5728\u68c0\u67e5\u6240\u6709commands\u524d\u6267\u884c\uff08\u8981\u6c42SDK\u7248\u672c>=2.5.2\uff09\r\n    @bot.before_command()\r\n    def preprocessor(data: Model.MESSAGE):\r\n        bot.logger.info(f\"\u6536\u5230\u6765\u81ea{data.author.username}\u7684\u6d88\u606f\uff1a{data.treated_msg}\")\r\n\r\n\r\n    @bot.on_command(\r\n        regex=r\"\u4f60\u597d(?:\u673a\u5668\u4eba)?\",  # \u6b63\u5219\u8868\u8fbe\u5f0f\uff0c\u5339\u914d\u7528\u6237\u6d88\u606f\r\n        is_short_circuit=True,    # is_short_circuit\u4ee3\u8868\u77ed\u8def\u673a\u5236\uff0c\u6839\u636e\u6ce8\u518c\u987a\u5e8f\uff0c\u5339\u914d\u5230\u5373\u505c\u6b62\u5339\u914d\uff0c\u4f46\u4e0d\u5f71\u54cdbind_msg()\r\n        is_require_at=True,       # is_require_at\u4ee3\u8868\u662f\u5426\u8981\u6c42\u68c0\u6d4b\u5230\u7528\u6237@\u4e86\u673a\u5668\u4eba\u624d\u53ef\u89e6\u53d1\u6307\u4ee4\r\n        is_require_admin=True,    # is_require_admin\u4ee3\u8868\u662f\u5426\u8981\u6c42\u68c0\u6d4b\u5230\u7528\u6237\u662f\u9891\u9053\u4e3b\u6216\u9891\u9053\u7ba1\u7406\u624d\u53ef\u89e6\u53d1\u6307\u4ee4\r\n        admin_error_msg=\"\u62b1\u6b49\uff0c\u4f60\u7684\u6743\u9650\u4e0d\u8db3\uff08\u975e\u9891\u9053\u4e3b\u6216\u7ba1\u7406\u5458\uff09\uff0c\u4e0d\u80fd\u4f7f\u7528\u6b64\u6307\u4ee4\",\r\n    )\r\n    def command(data: Model.MESSAGE):\r\n        data.reply(\"\u4f60\u597d\uff0c\u4e16\u754c\")\r\n\r\n\r\n    if __name__ == '__main__':\r\n        bot.start()\r\n\r\n\r\n\u76f8\u5173\u94fe\u63a5\r\n========\r\n\r\n-   \u66f4\u591a\u5b8c\u6574\u4f8b\u7a0b\uff1a\r\n     * `example <https://github.com/GLGDLY/qg_botsdk/tree/master/example>`_\r\n-   \u6587\u6863\uff1a\r\n     * `readthedocs <https://qg-botsdk.readthedocs.io/zh_CN/latest/>`_\r\n-   \u5b98\u65b9\u6ce8\u518c\u673a\u5668\u4eba\uff1ahttps://q.qq.com/#/\r\n-   \u5b98\u65b9API\u6587\u6863\uff1ahttps://bot.q.qq.com/wiki/develop/api/\r\n-   SDK QQ\u4ea4\u6d41\u7fa4\uff1ahttps://jq.qq.com/?_wv=1027&k=3NnWvGpz\r\n",
    "bugtrack_url": null,
    "license": null,
    "summary": "easy-to-use SDK for Tencent QQ guild robot",
    "version": "4.3.3",
    "project_urls": {
        "Homepage": "https://github.com/GLGDLY/qg_botsdk"
    },
    "split_keywords": [
        "sample",
        " example",
        " setuptools"
    ],
    "urls": [
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "5df6380c77d25461e67a7ec85b3ffc56175e4220ab0513f3f701a0e3b949d2a8",
                "md5": "dc3a7bab721d4932fdcaed59352c9394",
                "sha256": "daa3037e9b01056f4a9a022a8f6162f0b4b1c267cd47ff4f81299dfa8bb795df"
            },
            "downloads": -1,
            "filename": "qg_botsdk-4.3.3-py3-none-any.whl",
            "has_sig": false,
            "md5_digest": "dc3a7bab721d4932fdcaed59352c9394",
            "packagetype": "bdist_wheel",
            "python_version": "py3",
            "requires_python": "<4,>=3.7",
            "size": 108853,
            "upload_time": "2025-01-15T12:35:17",
            "upload_time_iso_8601": "2025-01-15T12:35:17.811434Z",
            "url": "https://files.pythonhosted.org/packages/5d/f6/380c77d25461e67a7ec85b3ffc56175e4220ab0513f3f701a0e3b949d2a8/qg_botsdk-4.3.3-py3-none-any.whl",
            "yanked": false,
            "yanked_reason": null
        }
    ],
    "upload_time": "2025-01-15 12:35:17",
    "github": true,
    "gitlab": false,
    "bitbucket": false,
    "codeberg": false,
    "github_user": "GLGDLY",
    "github_project": "qg_botsdk",
    "travis_ci": false,
    "coveralls": false,
    "github_actions": true,
    "requirements": [
        {
            "name": "aiohttp",
            "specs": [
                [
                    ">=",
                    "3.8.2"
                ]
            ]
        },
        {
            "name": "setuptools",
            "specs": [
                [
                    ">=",
                    "75.6.0"
                ]
            ]
        }
    ],
    "lcname": "qg-botsdk"
}
        
Elapsed time: 0.46649s