#### 1、介绍
本项目是对通用文件导出任务的抽象组件提取,通过使用本项目,可以简化通用文件导相关业务的开发。
#### 2、使用方式
数据库表:
```sql
CREATE TABLE `download_task_main` (
`id` bigint unsigned NOT NULL AUTO_INCREMENT,
`org_id` bigint unsigned NOT NULL,
`task_name` varchar(64) DEFAULT NULL COMMENT '任务名称',
`platform` int NOT NULL COMMENT ' 生成平台 , 1 :cfg , 2:cti , 3 : open , 4: crm ',
`type` int NOT NULL COMMENT '导出类型 1: 导出联系人 , 2 :公司对账单导出 3 : 导出 计划item 4 :导出 通话记录统计分析 5 : 录音下载 6 :信修下载 7 .通话记录加录音下载',
`sub_type` int NOT NULL COMMENT '导出子类型 导出类型下 分出来的子类型 ',
`description` varchar(255) DEFAULT NULL COMMENT '描述',
`status` int DEFAULT '0' COMMENT ' 0 :任务创建中 , 1 : 文件上传中 ,2 :文件上传完成 ,-1 :文件上传失败 3 : 任务失效 4:取消任务',
`top` int DEFAULT '0' COMMENT '是否置顶 0:否 1:是',
`data` varchar(1024) DEFAULT NULL COMMENT '序列化字段',
`notify` tinyint DEFAULT '0' COMMENT '是否通知 0:否 1:是',
`remark` varchar(256) DEFAULT NULL COMMENT '备注',
`created_by` bigint DEFAULT '0' COMMENT '创建人 , agent org id ',
`created_time` timestamp(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3) COMMENT '创建时间',
`last_updated_time` timestamp(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3) ON UPDATE CURRENT_TIMESTAMP(3) COMMENT '最后更新时间',
PRIMARY KEY (`id`) USING BTREE,
KEY `index_created_time` (`created_time`),
KEY `index_org_id_created_time` (`org_id`,`created_time`),
KEY `index_type` (`type`),
KEY `index_type_org_id` (`type`,`org_id`),
KEY `index_org_id_platform` (`org_id`,`platform`),
KEY `index_task_name_org_id` (`task_name`,`org_id`),
KEY `index_sub_type_status` (`sub_type`,`status`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='下载任务表';
CREATE TABLE `download_item` (
`id` bigint unsigned NOT NULL AUTO_INCREMENT COMMENT '主键 ',
`task_id` bigint NOT NULL COMMENT '主任务id',
`org_id` bigint unsigned NOT NULL COMMENT ' 公司ID ',
`type` int DEFAULT NULL COMMENT '下载类型。一般跟 task的 子类型相同 ',
`file_name` varchar(256) DEFAULT NULL COMMENT '文件名称',
`target_id` bigint DEFAULT NULL COMMENT '关联id',
`expire_time` timestamp NULL DEFAULT NULL COMMENT '过期时间',
`download_times` int DEFAULT NULL COMMENT '下载次数',
`url` varchar(1024) DEFAULT NULL COMMENT '文件下载地址',
`status` int DEFAULT '0' COMMENT '0 :未开始 , 1: 进行中 ,2:已完成 ,3 :失效(针对下载次数超限) -1 :任务失败 4:取消任务',
`data` varchar(1024) DEFAULT NULL COMMENT '序列化字段',
`remark` varchar(256) DEFAULT NULL COMMENT '备注',
`md5_value` varchar(45) DEFAULT NULL COMMENT '文件MD5',
`created_time` timestamp(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3) COMMENT '创建时间',
`last_updated_time` timestamp(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3) ON UPDATE CURRENT_TIMESTAMP(3) COMMENT '最后更新时间',
PRIMARY KEY (`id`) USING BTREE,
KEY `index_created_time` (`created_time`),
KEY `index_task_id` (`task_id`),
KEY `index_task_id_org_id` (`task_id`,`org_id`),
KEY `index_org_id_target_id` (`org_id`,`target_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='下载任务明细';
```
示例:
1、配置文件
```ini
[download_task]
dbHost=localhost
dbPort=3306
dbUser=root
dbPassword=12345678
dbName=cti
redisHost=localhost
redisPort=6379
redisDb=0
```
2、任务分发调度及状态管理
```python
from duyan_download_task import DownloadTaskScheduler
def test_scheduler():
scheduler = DownloadTaskScheduler('config.ini', 'download_task_scheduler')
scheduler.start()
if __name__ == '__main__':
test_scheduler()
```
3、自定义导出业务逻辑-单个子任务
```python
import json
from duyan_download_task import DownloadTaskBase, SubTypeInfo
from duyan_download_task.model import DownloadTaskMain, DownloadItem
class DemoTask(DownloadTaskBase):
def __init__(self, task_info: SubTypeInfo, config_path: str, logger_name: str):
super().__init__(task_info, config_path, logger_name)
def get_validated_data_params(self, task_item_id: int, data: str) -> dict or None:
self._logger.info(f"校验数据:[ID:{task_item_id}],data:{data}")
return json.loads(data)
def export(self, task_item: DownloadItem, data_obj: dict) -> tuple:
self._logger.info(f"校验导出:[item:{data_obj}],data:{data_obj}")
return None, None, None
def split_task(self, task: DownloadTaskMain) -> list:
pass
def task_test():
info = SubTypeInfo(task_name='DemoTask', type=10, sub_type=15, queue_key='demo_task_queue', is_multi_task=False)
task = DemoTask(info, 'config.ini', 'demo_task')
task.start()
if __name__ == '__main__':
task_test()
```
4、自定义导出业务逻辑-多个子任务
```python
import json
import datetime
from duyan_download_task import DownloadTaskBase, SubTypeInfo
from duyan_download_task.model import DownloadTaskMain, DownloadItem
from duyan_download_task.constants import ItemStatus
class DemoMultiItemTask(DownloadTaskBase):
task_info = SubTypeInfo(task_name='DemoMultiItemTask', type=11, sub_type=11, queue_key='demo_multi_item_task_queue',
is_multi_task=True)
def __init__(self, config_path: str, logger_name: str):
super().__init__(self.task_info, config_path, logger_name)
def get_validated_data_params(self, task_item_id: int, data: str) -> dict or None:
self._logger.info(f"校验数据:[ID:{task_item_id}],data:{data}")
return json.loads(data)
def export(self, task_item: DownloadItem, data_obj: dict) -> tuple:
self._logger.info(f"校验导出:[item:{data_obj}],data:{data_obj}")
url = 'http://duyan-record-download.oss-cn-hangzhou.aliyuncs.com/100757218773722020-04-27.zip?OSSAccessKeyId=LTAI4GFAeToJVw9E8eoLK8Wu&Expires=1968908476&Signature=KugYlSKBX6d6ExiDWcJKk4KoA1Y%3D'
md5 = 'f9d991b4a0522dfa77da67d68c675261'
file_name = '100757218773722020-04-27.zip'
return url, md5, file_name
def split_task(self, task: DownloadTaskMain) -> list:
items = []
now = datetime.datetime.now()
for i in range(2):
item = DownloadItem()
item.org_id = task.org_id
item.task_id = task.id
item.type = self.task_info.sub_type
item.data = task.data
item.status = ItemStatus.READY.value
item.created_time = now
item.last_updated_time = now
items.append(item)
return items
def multi_item_task_test():
task = DemoMultiItemTask('config.ini', 'demo_task')
task.start()
if __name__ == '__main__':
multi_item_task_test()
```
任务参数
```python
class DownloadTaskBase:
def __init__(self, task_info: SubTypeInfo, config_path: str, logger_name: str, max_job=1,
cron="0 0-59/2 * * * *"):
"""
init task
:param task_info:
SubTypeInfo 任务级别信息包括 名称、类型、子任务类型、任务队列、是否是多任务定义
task_name 名称 type 类型 sub_type 子任务类型 queue_key 任务队列 is_multi_task 是否是多任务定义
任务队列维护在redis中
:param config_path:
配置文件所在路径 如 ./config.ini
:param logger_name:
日志文件名称, 日志文件默认在./log目录下
:param max_job:
最大支持并发数量
:param cron:
任务执行周期cron表达式
秒 分 时 日 月 年
* 表示所有值
*/a 表示每隔a时间
a-b 表示a-b之间任何一个时间
a-b/c 表示a-b之间每隔c时间
取值范围:
秒 0-59
分 0-59
时 0-23
日 1-31
月 1-12
年 四位数字
示例:
0 */2 * * * * 每2分钟执行一次
*/1 * * * * * 每2秒执行一次
"""
```
Raw data
{
"_id": null,
"home_page": "https://github.com/pypa/sampleproject",
"name": "duyan-download-task",
"maintainer": "",
"docs_url": null,
"requires_python": ">=3.6",
"maintainer_email": "",
"keywords": "",
"author": "WuMenghao",
"author_email": "menghao.wu@duyansoft.com",
"download_url": "https://files.pythonhosted.org/packages/f8/9d/492f8ff033204705571b047adbb3a8b89ab26e0a2db63d6adc36ecbc1378/duyan-download-task-0.0.10.tar.gz",
"platform": null,
"description": "#### 1\u3001\u4ecb\u7ecd\n\n\u672c\u9879\u76ee\u662f\u5bf9\u901a\u7528\u6587\u4ef6\u5bfc\u51fa\u4efb\u52a1\u7684\u62bd\u8c61\u7ec4\u4ef6\u63d0\u53d6\uff0c\u901a\u8fc7\u4f7f\u7528\u672c\u9879\u76ee\uff0c\u53ef\u4ee5\u7b80\u5316\u901a\u7528\u6587\u4ef6\u5bfc\u76f8\u5173\u4e1a\u52a1\u7684\u5f00\u53d1\u3002\n\n#### 2\u3001\u4f7f\u7528\u65b9\u5f0f\n\n\u6570\u636e\u5e93\u8868:\n```sql\nCREATE TABLE `download_task_main` (\n `id` bigint unsigned NOT NULL AUTO_INCREMENT,\n `org_id` bigint unsigned NOT NULL,\n `task_name` varchar(64) DEFAULT NULL COMMENT '\u4efb\u52a1\u540d\u79f0',\n `platform` int NOT NULL COMMENT ' \u751f\u6210\u5e73\u53f0 \uff0c 1 \uff1acfg , 2:cti , 3 : open , 4: crm ',\n `type` int NOT NULL COMMENT '\u5bfc\u51fa\u7c7b\u578b 1: \u5bfc\u51fa\u8054\u7cfb\u4eba \uff0c 2 \uff1a\u516c\u53f8\u5bf9\u8d26\u5355\u5bfc\u51fa 3 \uff1a \u5bfc\u51fa \u8ba1\u5212item 4 \uff1a\u5bfc\u51fa \u901a\u8bdd\u8bb0\u5f55\u7edf\u8ba1\u5206\u6790 5 \uff1a \u5f55\u97f3\u4e0b\u8f7d 6 \uff1a\u4fe1\u4fee\u4e0b\u8f7d 7 .\u901a\u8bdd\u8bb0\u5f55\u52a0\u5f55\u97f3\u4e0b\u8f7d',\n `sub_type` int NOT NULL COMMENT '\u5bfc\u51fa\u5b50\u7c7b\u578b \u5bfc\u51fa\u7c7b\u578b\u4e0b \u5206\u51fa\u6765\u7684\u5b50\u7c7b\u578b ',\n `description` varchar(255) DEFAULT NULL COMMENT '\u63cf\u8ff0',\n `status` int DEFAULT '0' COMMENT ' 0 :\u4efb\u52a1\u521b\u5efa\u4e2d , 1 : \u6587\u4ef6\u4e0a\u4f20\u4e2d \uff0c2 \uff1a\u6587\u4ef6\u4e0a\u4f20\u5b8c\u6210 ,-1 :\u6587\u4ef6\u4e0a\u4f20\u5931\u8d25 3 : \u4efb\u52a1\u5931\u6548 4\uff1a\u53d6\u6d88\u4efb\u52a1',\n `top` int DEFAULT '0' COMMENT '\u662f\u5426\u7f6e\u9876 0\uff1a\u5426 1\uff1a\u662f',\n `data` varchar(1024) DEFAULT NULL COMMENT '\u5e8f\u5217\u5316\u5b57\u6bb5',\n `notify` tinyint DEFAULT '0' COMMENT '\u662f\u5426\u901a\u77e5 0\uff1a\u5426 1\uff1a\u662f',\n `remark` varchar(256) DEFAULT NULL COMMENT '\u5907\u6ce8',\n `created_by` bigint DEFAULT '0' COMMENT '\u521b\u5efa\u4eba , agent org id ',\n `created_time` timestamp(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3) COMMENT '\u521b\u5efa\u65f6\u95f4',\n `last_updated_time` timestamp(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3) ON UPDATE CURRENT_TIMESTAMP(3) COMMENT '\u6700\u540e\u66f4\u65b0\u65f6\u95f4',\n PRIMARY KEY (`id`) USING BTREE,\n KEY `index_created_time` (`created_time`),\n KEY `index_org_id_created_time` (`org_id`,`created_time`),\n KEY `index_type` (`type`),\n KEY `index_type_org_id` (`type`,`org_id`),\n KEY `index_org_id_platform` (`org_id`,`platform`),\n KEY `index_task_name_org_id` (`task_name`,`org_id`),\n KEY `index_sub_type_status` (`sub_type`,`status`)\n) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='\u4e0b\u8f7d\u4efb\u52a1\u8868';\n\nCREATE TABLE `download_item` (\n `id` bigint unsigned NOT NULL AUTO_INCREMENT COMMENT '\u4e3b\u952e ',\n `task_id` bigint NOT NULL COMMENT '\u4e3b\u4efb\u52a1id',\n `org_id` bigint unsigned NOT NULL COMMENT ' \u516c\u53f8ID ',\n `type` int DEFAULT NULL COMMENT '\u4e0b\u8f7d\u7c7b\u578b\u3002\u4e00\u822c\u8ddf task\u7684 \u5b50\u7c7b\u578b\u76f8\u540c ',\n `file_name` varchar(256) DEFAULT NULL COMMENT '\u6587\u4ef6\u540d\u79f0',\n `target_id` bigint DEFAULT NULL COMMENT '\u5173\u8054id',\n `expire_time` timestamp NULL DEFAULT NULL COMMENT '\u8fc7\u671f\u65f6\u95f4',\n `download_times` int DEFAULT NULL COMMENT '\u4e0b\u8f7d\u6b21\u6570',\n `url` varchar(1024) DEFAULT NULL COMMENT '\u6587\u4ef6\u4e0b\u8f7d\u5730\u5740',\n `status` int DEFAULT '0' COMMENT '0 :\u672a\u5f00\u59cb \uff0c 1: \u8fdb\u884c\u4e2d \uff0c2:\u5df2\u5b8c\u6210 \uff0c3 \uff1a\u5931\u6548(\u9488\u5bf9\u4e0b\u8f7d\u6b21\u6570\u8d85\u9650) -1 :\u4efb\u52a1\u5931\u8d25 4\uff1a\u53d6\u6d88\u4efb\u52a1',\n `data` varchar(1024) DEFAULT NULL COMMENT '\u5e8f\u5217\u5316\u5b57\u6bb5',\n `remark` varchar(256) DEFAULT NULL COMMENT '\u5907\u6ce8',\n `md5_value` varchar(45) DEFAULT NULL COMMENT '\u6587\u4ef6MD5',\n `created_time` timestamp(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3) COMMENT '\u521b\u5efa\u65f6\u95f4',\n `last_updated_time` timestamp(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3) ON UPDATE CURRENT_TIMESTAMP(3) COMMENT '\u6700\u540e\u66f4\u65b0\u65f6\u95f4',\n PRIMARY KEY (`id`) USING BTREE,\n KEY `index_created_time` (`created_time`),\n KEY `index_task_id` (`task_id`),\n KEY `index_task_id_org_id` (`task_id`,`org_id`),\n KEY `index_org_id_target_id` (`org_id`,`target_id`)\n) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='\u4e0b\u8f7d\u4efb\u52a1\u660e\u7ec6';\n```\n\n\u793a\u4f8b\uff1a\n\n1\u3001\u914d\u7f6e\u6587\u4ef6\n\n```ini\n[download_task]\ndbHost=localhost\ndbPort=3306\ndbUser=root\ndbPassword=12345678\ndbName=cti\nredisHost=localhost\nredisPort=6379\nredisDb=0\n```\n\n2\u3001\u4efb\u52a1\u5206\u53d1\u8c03\u5ea6\u53ca\u72b6\u6001\u7ba1\u7406\n\n```python\nfrom duyan_download_task import DownloadTaskScheduler\n\n\ndef test_scheduler():\n scheduler = DownloadTaskScheduler('config.ini', 'download_task_scheduler')\n scheduler.start()\n\n\nif __name__ == '__main__':\n test_scheduler()\n\n```\n\n3\u3001\u81ea\u5b9a\u4e49\u5bfc\u51fa\u4e1a\u52a1\u903b\u8f91-\u5355\u4e2a\u5b50\u4efb\u52a1\n\n```python\nimport json\n\nfrom duyan_download_task import DownloadTaskBase, SubTypeInfo\nfrom duyan_download_task.model import DownloadTaskMain, DownloadItem\n\n\nclass DemoTask(DownloadTaskBase):\n\n def __init__(self, task_info: SubTypeInfo, config_path: str, logger_name: str):\n super().__init__(task_info, config_path, logger_name)\n\n def get_validated_data_params(self, task_item_id: int, data: str) -> dict or None:\n self._logger.info(f\"\u6821\u9a8c\u6570\u636e:[ID:{task_item_id}],data:{data}\")\n return json.loads(data)\n\n def export(self, task_item: DownloadItem, data_obj: dict) -> tuple:\n self._logger.info(f\"\u6821\u9a8c\u5bfc\u51fa:[item:{data_obj}],data:{data_obj}\")\n return None, None, None\n\n def split_task(self, task: DownloadTaskMain) -> list:\n pass\n\n\ndef task_test():\n info = SubTypeInfo(task_name='DemoTask', type=10, sub_type=15, queue_key='demo_task_queue', is_multi_task=False)\n task = DemoTask(info, 'config.ini', 'demo_task')\n task.start()\n\n\nif __name__ == '__main__':\n task_test()\n\n```\n\n4\u3001\u81ea\u5b9a\u4e49\u5bfc\u51fa\u4e1a\u52a1\u903b\u8f91-\u591a\u4e2a\u5b50\u4efb\u52a1\n\n```python\nimport json\nimport datetime\n\nfrom duyan_download_task import DownloadTaskBase, SubTypeInfo\nfrom duyan_download_task.model import DownloadTaskMain, DownloadItem\nfrom duyan_download_task.constants import ItemStatus\n\nclass DemoMultiItemTask(DownloadTaskBase):\n task_info = SubTypeInfo(task_name='DemoMultiItemTask', type=11, sub_type=11, queue_key='demo_multi_item_task_queue',\n is_multi_task=True)\n\n def __init__(self, config_path: str, logger_name: str):\n super().__init__(self.task_info, config_path, logger_name)\n\n def get_validated_data_params(self, task_item_id: int, data: str) -> dict or None:\n self._logger.info(f\"\u6821\u9a8c\u6570\u636e:[ID:{task_item_id}],data:{data}\")\n return json.loads(data)\n\n def export(self, task_item: DownloadItem, data_obj: dict) -> tuple:\n self._logger.info(f\"\u6821\u9a8c\u5bfc\u51fa:[item:{data_obj}],data:{data_obj}\")\n url = 'http://duyan-record-download.oss-cn-hangzhou.aliyuncs.com/100757218773722020-04-27.zip?OSSAccessKeyId=LTAI4GFAeToJVw9E8eoLK8Wu&Expires=1968908476&Signature=KugYlSKBX6d6ExiDWcJKk4KoA1Y%3D'\n md5 = 'f9d991b4a0522dfa77da67d68c675261'\n file_name = '100757218773722020-04-27.zip'\n return url, md5, file_name\n\n def split_task(self, task: DownloadTaskMain) -> list:\n items = []\n now = datetime.datetime.now()\n for i in range(2):\n item = DownloadItem()\n item.org_id = task.org_id\n item.task_id = task.id\n item.type = self.task_info.sub_type\n item.data = task.data\n item.status = ItemStatus.READY.value\n item.created_time = now\n item.last_updated_time = now\n items.append(item)\n return items\n\ndef multi_item_task_test():\n task = DemoMultiItemTask('config.ini', 'demo_task')\n task.start()\n\n\nif __name__ == '__main__':\n multi_item_task_test()\n```\n\n\u4efb\u52a1\u53c2\u6570\n\n```python\nclass DownloadTaskBase:\n\n def __init__(self, task_info: SubTypeInfo, config_path: str, logger_name: str, max_job=1,\n cron=\"0 0-59/2 * * * *\"):\n \"\"\"\n init task\n :param task_info:\n SubTypeInfo \u4efb\u52a1\u7ea7\u522b\u4fe1\u606f\u5305\u62ec \u540d\u79f0\u3001\u7c7b\u578b\u3001\u5b50\u4efb\u52a1\u7c7b\u578b\u3001\u4efb\u52a1\u961f\u5217\u3001\u662f\u5426\u662f\u591a\u4efb\u52a1\u5b9a\u4e49\n task_name \u540d\u79f0 type \u7c7b\u578b sub_type \u5b50\u4efb\u52a1\u7c7b\u578b queue_key \u4efb\u52a1\u961f\u5217 is_multi_task \u662f\u5426\u662f\u591a\u4efb\u52a1\u5b9a\u4e49\n \u4efb\u52a1\u961f\u5217\u7ef4\u62a4\u5728redis\u4e2d\n :param config_path:\n \u914d\u7f6e\u6587\u4ef6\u6240\u5728\u8def\u5f84 \u5982 ./config.ini\n :param logger_name:\n \u65e5\u5fd7\u6587\u4ef6\u540d\u79f0\uff0c \u65e5\u5fd7\u6587\u4ef6\u9ed8\u8ba4\u5728./log\u76ee\u5f55\u4e0b\n :param max_job:\n \u6700\u5927\u652f\u6301\u5e76\u53d1\u6570\u91cf\n :param cron:\n \u4efb\u52a1\u6267\u884c\u5468\u671fcron\u8868\u8fbe\u5f0f\n \u79d2 \u5206 \u65f6 \u65e5 \u6708 \u5e74\n * \u8868\u793a\u6240\u6709\u503c\n */a \u8868\u793a\u6bcf\u9694a\u65f6\u95f4\n a-b \u8868\u793aa-b\u4e4b\u95f4\u4efb\u4f55\u4e00\u4e2a\u65f6\u95f4\n a-b/c \u8868\u793aa-b\u4e4b\u95f4\u6bcf\u9694c\u65f6\u95f4\n \n \u53d6\u503c\u8303\u56f4\uff1a\n \u79d2 0-59\n \u5206 0-59\n \u65f6 0-23\n \u65e5 1-31\n \u6708 1-12\n \u5e74 \u56db\u4f4d\u6570\u5b57\n \n \u793a\u4f8b\uff1a\n 0 */2 * * * * \u6bcf2\u5206\u949f\u6267\u884c\u4e00\u6b21\n */1 * * * * * \u6bcf2\u79d2\u6267\u884c\u4e00\u6b21\n \"\"\"\n```\n\n",
"bugtrack_url": null,
"license": "",
"summary": "Using for Debug, finding problem",
"version": "0.0.10",
"project_urls": {
"Bug Tracker": "https://github.com/pypa/sampleproject/issues",
"Homepage": "https://github.com/pypa/sampleproject"
},
"split_keywords": [],
"urls": [
{
"comment_text": "",
"digests": {
"blake2b_256": "edf58b13fd7153de4cbec02912cf0d78c6649b17a8d3b379f8c5dff38148cd75",
"md5": "658b5e0e6e89d23daf60075aa8c4ad8b",
"sha256": "9503152d7832d90dec8af6c485ea5f29b390db3c90730d05edf264e599a25d84"
},
"downloads": -1,
"filename": "duyan_download_task-0.0.10-py3-none-any.whl",
"has_sig": false,
"md5_digest": "658b5e0e6e89d23daf60075aa8c4ad8b",
"packagetype": "bdist_wheel",
"python_version": "py3",
"requires_python": ">=3.6",
"size": 21605,
"upload_time": "2023-08-22T09:05:19",
"upload_time_iso_8601": "2023-08-22T09:05:19.991295Z",
"url": "https://files.pythonhosted.org/packages/ed/f5/8b13fd7153de4cbec02912cf0d78c6649b17a8d3b379f8c5dff38148cd75/duyan_download_task-0.0.10-py3-none-any.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": "",
"digests": {
"blake2b_256": "f89d492f8ff033204705571b047adbb3a8b89ab26e0a2db63d6adc36ecbc1378",
"md5": "d1aad70341450fd0f748623e9819bfd8",
"sha256": "650527fd096e742e8b58fafe94a23e06ca53398280ba544d8ae7bef0659bc21f"
},
"downloads": -1,
"filename": "duyan-download-task-0.0.10.tar.gz",
"has_sig": false,
"md5_digest": "d1aad70341450fd0f748623e9819bfd8",
"packagetype": "sdist",
"python_version": "source",
"requires_python": ">=3.6",
"size": 19704,
"upload_time": "2023-08-22T09:05:21",
"upload_time_iso_8601": "2023-08-22T09:05:21.631978Z",
"url": "https://files.pythonhosted.org/packages/f8/9d/492f8ff033204705571b047adbb3a8b89ab26e0a2db63d6adc36ecbc1378/duyan-download-task-0.0.10.tar.gz",
"yanked": false,
"yanked_reason": null
}
],
"upload_time": "2023-08-22 09:05:21",
"github": true,
"gitlab": false,
"bitbucket": false,
"codeberg": false,
"github_user": "pypa",
"github_project": "sampleproject",
"travis_ci": false,
"coveralls": false,
"github_actions": true,
"tox": true,
"lcname": "duyan-download-task"
}