mcsmapi 0.1.6__py3-none-any.whl → 0.1.8b1__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- mcsmapi/__init__.py +3 -4
- mcsmapi/apis/daemon.py +33 -38
- mcsmapi/apis/file.py +122 -135
- mcsmapi/apis/image.py +28 -29
- mcsmapi/apis/instance.py +107 -126
- mcsmapi/apis/overview.py +12 -8
- mcsmapi/apis/user.py +37 -37
- mcsmapi/models/common.py +30 -0
- mcsmapi/models/daemon.py +60 -96
- mcsmapi/models/file.py +89 -78
- mcsmapi/models/image.py +93 -85
- mcsmapi/models/instance.py +155 -133
- mcsmapi/models/overview.py +148 -57
- mcsmapi/models/user.py +80 -57
- mcsmapi/pool.py +1 -0
- mcsmapi/request.py +20 -14
- {mcsmapi-0.1.6.dist-info → mcsmapi-0.1.8b1.dist-info}/METADATA +6 -3
- mcsmapi-0.1.8b1.dist-info/RECORD +24 -0
- mcsmapi-0.1.6.dist-info/RECORD +0 -23
- {mcsmapi-0.1.6.dist-info → mcsmapi-0.1.8b1.dist-info}/WHEEL +0 -0
- {mcsmapi-0.1.6.dist-info → mcsmapi-0.1.8b1.dist-info}/licenses/LICENSE +0 -0
- {mcsmapi-0.1.6.dist-info → mcsmapi-0.1.8b1.dist-info}/top_level.txt +0 -0
mcsmapi/models/common.py
ADDED
@@ -0,0 +1,30 @@
|
|
1
|
+
from pydantic import BaseModel
|
2
|
+
|
3
|
+
|
4
|
+
class CpuMemChart(BaseModel):
|
5
|
+
"""资源使用率信息"""
|
6
|
+
|
7
|
+
cpu: float
|
8
|
+
"""cpu使用率"""
|
9
|
+
mem: float
|
10
|
+
"""内存使用率"""
|
11
|
+
|
12
|
+
|
13
|
+
class ProcessInfo(BaseModel):
|
14
|
+
"""进程详细信息"""
|
15
|
+
|
16
|
+
cpu: int
|
17
|
+
"""CPU 使用率(百分比)"""
|
18
|
+
memory: int
|
19
|
+
"""内存使用量(MB)"""
|
20
|
+
cwd: str
|
21
|
+
"""工作路径"""
|
22
|
+
|
23
|
+
|
24
|
+
class InstanceInfo(BaseModel):
|
25
|
+
"""实例统计信息"""
|
26
|
+
|
27
|
+
running: int
|
28
|
+
"""运行中实例数量"""
|
29
|
+
total: int
|
30
|
+
"""全部实例数量"""
|
mcsmapi/models/daemon.py
CHANGED
@@ -1,182 +1,146 @@
|
|
1
|
-
from typing import Any
|
1
|
+
from typing import Any
|
2
2
|
from pydantic import BaseModel
|
3
3
|
from mcsmapi.models.instance import InstanceCreateResult
|
4
|
+
from mcsmapi.models.common import ProcessInfo, InstanceInfo, CpuMemChart
|
4
5
|
|
5
6
|
|
6
|
-
class
|
7
|
-
"""节点资源使用率信息"""
|
8
|
-
|
9
|
-
"""cpu使用率"""
|
10
|
-
cpu: float = 0
|
11
|
-
"""内存使用率"""
|
12
|
-
mem: float = 0
|
13
|
-
|
14
|
-
|
15
|
-
class ProcessInfo(BaseModel):
|
16
|
-
"""节点进程详细信息"""
|
17
|
-
|
18
|
-
"""远程节点使用的cpu资源(单位: byte)"""
|
19
|
-
cpu: int = 0
|
20
|
-
"""远程节点使用的内存资源(单位: byte)"""
|
21
|
-
memory: int = 0
|
22
|
-
"""远程节点的工作路径"""
|
23
|
-
cwd: str = ""
|
24
|
-
|
25
|
-
|
26
|
-
class InstanceInfo(BaseModel):
|
27
|
-
"""实例统计信息"""
|
28
|
-
|
29
|
-
"""运行中实例数量"""
|
30
|
-
running: int = 0
|
31
|
-
"""全部实例数量"""
|
32
|
-
total: int = 0
|
33
|
-
|
34
|
-
|
35
|
-
class SystemInfo(BaseModel):
|
7
|
+
class DaemonSystemInfo(BaseModel):
|
36
8
|
"""节点系统信息"""
|
37
9
|
|
10
|
+
type: str
|
38
11
|
"""系统类型"""
|
39
|
-
|
12
|
+
hostname: str
|
40
13
|
"""主机名"""
|
41
|
-
|
14
|
+
platform: str
|
42
15
|
"""平台架构"""
|
43
|
-
|
16
|
+
release: str
|
44
17
|
"""系统版本"""
|
45
|
-
|
18
|
+
uptime: float
|
46
19
|
"""系统运行时间(单位: sec)"""
|
47
|
-
|
20
|
+
cwd: str
|
48
21
|
"""远程节点运行路径"""
|
49
|
-
|
22
|
+
loadavg: tuple[float, float, float]
|
50
23
|
"""系统负载平均值(仅适用于 Linux 和 macOS),表示过去 **1 分钟、5 分钟、15 分钟** 内的 CPU 负载情况"""
|
51
|
-
|
24
|
+
freemem: int
|
52
25
|
"""可用内存(单位: byte)"""
|
53
|
-
|
26
|
+
cpuUsage: float
|
54
27
|
"""cpu使用率"""
|
55
|
-
|
28
|
+
memUsage: float
|
56
29
|
"""内存使用率"""
|
57
|
-
|
30
|
+
totalmem: int
|
58
31
|
"""内存总量(单位: byte)"""
|
59
|
-
|
60
|
-
"""
|
61
|
-
|
62
|
-
"""
|
63
|
-
processMem: int = 0
|
32
|
+
processCpu: int
|
33
|
+
"""未知"""
|
34
|
+
processMem: int
|
35
|
+
"""未知"""
|
64
36
|
|
65
37
|
|
66
38
|
class DaemonModel(BaseModel):
|
67
39
|
"""节点详细信息"""
|
68
40
|
|
41
|
+
version: str
|
69
42
|
"""远程节点版本"""
|
70
|
-
|
43
|
+
process: ProcessInfo
|
71
44
|
"""远程节点的基本信息"""
|
72
|
-
|
45
|
+
instance: InstanceInfo
|
73
46
|
"""远程节点实例基本信息"""
|
74
|
-
|
47
|
+
system: DaemonSystemInfo
|
75
48
|
"""远程节点系统信息"""
|
76
|
-
|
49
|
+
cpuMemChart: list[CpuMemChart]
|
77
50
|
"""cpu和内存使用趋势"""
|
78
|
-
|
51
|
+
uuid: str
|
79
52
|
"""远程节点的uuid"""
|
80
|
-
|
53
|
+
ip: str
|
81
54
|
"""远程节点的ip"""
|
82
|
-
|
55
|
+
port: int
|
83
56
|
"""远程节点的端口"""
|
84
|
-
|
57
|
+
prefix: str
|
85
58
|
"""远程节点的路径前缀"""
|
86
|
-
|
59
|
+
available: bool
|
87
60
|
"""远程节点的可用状态"""
|
88
|
-
|
89
|
-
"""
|
90
|
-
remarks: str = ""
|
61
|
+
remarks: str
|
62
|
+
"""远程节点的名称"""
|
91
63
|
|
92
|
-
def delete(self)
|
64
|
+
def delete(self):
|
93
65
|
"""
|
94
|
-
|
66
|
+
删除该节点
|
95
67
|
|
96
|
-
|
97
|
-
- bool: 删除成功后返回True
|
68
|
+
:returns: 删除成功后返回True
|
98
69
|
"""
|
99
70
|
from mcsmapi.apis.daemon import Daemon
|
100
71
|
|
101
|
-
return Daemon
|
72
|
+
return Daemon.delete(self.uuid)
|
102
73
|
|
103
|
-
def link(self)
|
74
|
+
def link(self):
|
104
75
|
"""
|
105
|
-
|
76
|
+
尝试连接该节点
|
106
77
|
|
107
|
-
|
108
|
-
- bool: 链接成功后返回True
|
78
|
+
:returns: 连接成功后返回True
|
109
79
|
"""
|
110
80
|
from mcsmapi.apis.daemon import Daemon
|
111
81
|
|
112
|
-
return Daemon
|
82
|
+
return Daemon.link(self.uuid)
|
113
83
|
|
114
84
|
def updateConfig(self, config: dict[str, Any]) -> bool:
|
115
85
|
"""
|
116
|
-
|
86
|
+
更新该节点的配置
|
117
87
|
|
118
|
-
|
119
|
-
- config (dict[str, Any]): 节点的配置信息,以字典形式提供,缺失内容使用原节点配置填充。
|
88
|
+
:params config: 节点的配置信息,以字典形式提供,缺失内容使用原节点配置填充
|
120
89
|
|
121
|
-
|
122
|
-
- bool: 更新成功后返回True
|
90
|
+
:returns: 更新成功后返回True
|
123
91
|
"""
|
124
92
|
from mcsmapi.apis.daemon import Daemon
|
125
93
|
|
126
|
-
updated_config = self.
|
94
|
+
updated_config = self.model_dump()
|
127
95
|
updated_config.update(config)
|
128
96
|
# 过滤节点配置中不需要的字段
|
129
97
|
daemon_config_dict = {
|
130
98
|
key: updated_config[key]
|
131
|
-
for key in DaemonConfig.
|
99
|
+
for key in DaemonConfig.model_fields.keys()
|
132
100
|
if key in updated_config
|
133
101
|
}
|
134
102
|
|
135
|
-
daemon_config = DaemonConfig(**daemon_config_dict).
|
103
|
+
daemon_config = DaemonConfig(**daemon_config_dict).model_dump()
|
136
104
|
|
137
|
-
return Daemon
|
105
|
+
return Daemon.update(self.uuid, daemon_config)
|
138
106
|
|
139
|
-
def createInstance(self, config: dict[str, Any]) ->
|
107
|
+
def createInstance(self, config: dict[str, Any]) -> InstanceCreateResult:
|
140
108
|
"""
|
141
|
-
|
109
|
+
在当前节点创建一个实例
|
142
110
|
|
143
|
-
|
144
|
-
- config (dict[str, Any]): 实例的配置信息,以字典形式提供,缺失内容由InstanceConfig模型补全。
|
111
|
+
:params config: 实例的配置信息,以字典形式提供,缺失内容由InstanceConfig模型补全
|
145
112
|
|
146
|
-
|
147
|
-
- InstanceCreateResult: 一个包含新创建实例信息的结果对象,内容由InstanceCreateResult模型定义。
|
113
|
+
:returns: 一个包含新创建实例信息的结果对象
|
148
114
|
"""
|
149
115
|
from mcsmapi.apis.instance import Instance
|
150
116
|
from .instance import InstanceConfig
|
151
117
|
|
152
|
-
return Instance
|
118
|
+
return Instance.create(self.uuid, InstanceConfig(**config).model_dump())
|
153
119
|
|
154
120
|
def deleteInstance(self, uuids: list[str], deleteFile=False) -> list[str]:
|
155
121
|
"""
|
156
|
-
|
122
|
+
删除当前节点的一个或多个实例
|
157
123
|
|
158
|
-
|
159
|
-
|
160
|
-
- deleteFile (bool, optional): 是否删除关联的文件,默认为False。
|
124
|
+
:params uuids: 要删除的实例UUID列表
|
125
|
+
:params deleteFile: 是否删除关联的文件
|
161
126
|
|
162
|
-
|
163
|
-
- list[str]: 删除操作后返回的UUID列表。
|
127
|
+
:returns: 删除操作后返回的UUID列表
|
164
128
|
"""
|
165
129
|
from mcsmapi.apis.instance import Instance
|
166
130
|
|
167
|
-
return Instance
|
131
|
+
return Instance.delete(self.uuid, uuids, deleteFile)
|
168
132
|
|
169
133
|
|
170
134
|
class DaemonConfig(BaseModel):
|
171
135
|
"""节点配置信息"""
|
172
136
|
|
173
|
-
"""远程节点的ip"""
|
174
137
|
ip: str = "localhost"
|
175
|
-
"""
|
138
|
+
"""远程节点的ip"""
|
176
139
|
port: int = 24444
|
177
|
-
"""
|
140
|
+
"""远程节点的端口"""
|
178
141
|
prefix: str = ""
|
179
|
-
"""
|
142
|
+
"""远程节点的路径前缀"""
|
180
143
|
remarks: str = "New Daemon"
|
181
|
-
"""
|
144
|
+
"""远程节点的备注"""
|
182
145
|
available: bool = True
|
146
|
+
"""远程节点的可用状态"""
|
mcsmapi/models/file.py
CHANGED
@@ -1,151 +1,161 @@
|
|
1
|
+
from enum import IntEnum
|
2
|
+
from typing import Literal
|
1
3
|
from pydantic import BaseModel
|
2
|
-
from typing import List
|
3
4
|
import os
|
4
5
|
|
5
6
|
|
7
|
+
class FileType(IntEnum):
|
8
|
+
FOLDER = 0
|
9
|
+
FILE = 1
|
10
|
+
|
11
|
+
|
6
12
|
class FileItem(BaseModel):
|
7
13
|
"""文件信息"""
|
8
14
|
|
15
|
+
name: str
|
9
16
|
"""文件名称"""
|
10
|
-
|
17
|
+
size: int
|
11
18
|
"""文件大小(单位: byte)"""
|
12
|
-
|
19
|
+
time: str
|
13
20
|
"""文件修改时间"""
|
14
|
-
|
21
|
+
mode: int
|
15
22
|
"""文件操作权限(仅适用于Linux)"""
|
16
|
-
|
17
|
-
"""
|
18
|
-
type: int = 0 # 0 = Folder, 1 = File
|
19
|
-
"""远程节点uuid"""
|
23
|
+
type: FileType
|
24
|
+
"""文件类型"""
|
20
25
|
daemonId: str = ""
|
21
|
-
"""
|
26
|
+
"""远程节点uuid"""
|
22
27
|
uuid: str = ""
|
23
|
-
"""
|
28
|
+
"""实例的uiid"""
|
24
29
|
target: str = ""
|
30
|
+
"""文件所在路径"""
|
31
|
+
file_name: str
|
25
32
|
"""当前文件列表过滤条件"""
|
26
|
-
file_name: str = ""
|
27
33
|
|
28
|
-
def rename(self, newName: str)
|
34
|
+
def rename(self, newName: str):
|
29
35
|
"""
|
30
|
-
|
36
|
+
重命名该文件或文件夹
|
31
37
|
|
32
|
-
|
33
|
-
- new_name (str): 源文件或文件夹的新名字。
|
38
|
+
:params new_name: 源文件或文件夹的新名字
|
34
39
|
|
35
|
-
|
36
|
-
- bool: 重命名成功后返回True。
|
40
|
+
:returns: 重命名成功后返回True
|
37
41
|
"""
|
38
42
|
from mcsmapi.apis.file import File
|
39
43
|
|
40
|
-
return File
|
44
|
+
return File.rename(
|
41
45
|
self.daemonId, self.uuid, os.path.join(self.target, self.name), newName
|
42
46
|
)
|
43
47
|
|
44
|
-
def delete(self)
|
48
|
+
def delete(self):
|
45
49
|
"""
|
46
|
-
|
50
|
+
删除该文件或文件夹
|
47
51
|
|
48
|
-
|
49
|
-
- bool: 重命名成功后返回True。
|
52
|
+
:returns: 重命名成功后返回True
|
50
53
|
"""
|
51
54
|
from mcsmapi.apis.file import File
|
52
55
|
|
53
|
-
return File
|
56
|
+
return File.delete(
|
54
57
|
self.daemonId, self.uuid, [os.path.join(self.target, self.name)]
|
55
58
|
)
|
56
59
|
|
57
|
-
def copy(self, target: str)
|
60
|
+
def copy(self, target: str):
|
61
|
+
"""
|
62
|
+
复制该文件或文件夹到目标路径
|
63
|
+
|
64
|
+
:param target: 目标路径
|
65
|
+
|
66
|
+
:returns: 复制成功后返回True
|
67
|
+
"""
|
58
68
|
from mcsmapi.apis.file import File
|
59
69
|
|
60
|
-
return File
|
70
|
+
return File.copyOne(
|
61
71
|
self.daemonId, self.uuid, os.path.join(self.target, self.name), target
|
62
72
|
)
|
63
73
|
|
64
|
-
def move(self, target: str)
|
74
|
+
def move(self, target: str):
|
65
75
|
"""
|
66
|
-
|
76
|
+
移动该文件或文件夹到目标路径
|
67
77
|
|
68
|
-
|
69
|
-
- target (str): 目标文件或文件夹的路径。
|
78
|
+
:params target: 目标文件或文件夹的路径
|
70
79
|
|
71
|
-
|
72
|
-
- bool: 移动成功后返回True。
|
80
|
+
:returns: 移动成功后返回True
|
73
81
|
"""
|
74
82
|
from mcsmapi.apis.file import File
|
75
83
|
|
76
|
-
return File
|
84
|
+
return File.moveOne(
|
77
85
|
self.daemonId, self.uuid, os.path.join(self.target, self.name), target
|
78
86
|
)
|
79
87
|
|
80
88
|
def content(self):
|
81
89
|
"""
|
82
|
-
|
83
|
-
|
84
|
-
|
90
|
+
获取文件内容
|
91
|
+
|
92
|
+
:returns: 文件内容
|
85
93
|
"""
|
86
94
|
from mcsmapi.apis.file import File
|
87
95
|
|
88
|
-
return File
|
96
|
+
return File.content(
|
89
97
|
self.daemonId, self.uuid, os.path.join(self.target, self.name)
|
90
98
|
)
|
91
99
|
|
92
|
-
def zip(self, targets: list[str])
|
100
|
+
def zip(self, targets: list[str]):
|
93
101
|
"""
|
94
|
-
|
102
|
+
压缩多个文件或文件夹到指定位置
|
95
103
|
|
96
104
|
**参数:**
|
97
|
-
- targets (list):
|
105
|
+
- targets (list): 要压缩到的目标文件的路径
|
98
106
|
|
99
107
|
**返回:**
|
100
|
-
- bool: 压缩成功后返回True
|
108
|
+
- bool: 压缩成功后返回True
|
101
109
|
"""
|
102
110
|
from mcsmapi.apis.file import File
|
103
111
|
|
104
|
-
return File
|
112
|
+
return File.zip(
|
105
113
|
self.daemonId, self.uuid, os.path.join(self.target, self.name), targets
|
106
114
|
)
|
107
115
|
|
108
|
-
def unzip(
|
116
|
+
def unzip(
|
117
|
+
self, target: str, code: Literal["utf-8", "gbk", "big5"] = "utf-8"
|
118
|
+
) -> bool:
|
109
119
|
"""
|
110
|
-
解压缩该 zip
|
120
|
+
解压缩该 zip 文件到目标位置
|
111
121
|
|
112
122
|
**参数:**
|
113
|
-
- target (str):
|
114
|
-
- code (str, optional): 压缩文件的编码方式,默认为"utf-8"
|
123
|
+
- target (str): 解压到的目标路径
|
124
|
+
- code (str, optional): 压缩文件的编码方式,默认为"utf-8"
|
115
125
|
可选值: utf-8, gbk, big5
|
116
126
|
|
117
127
|
**返回:**
|
118
|
-
- bool: 解压成功后返回True
|
128
|
+
- bool: 解压成功后返回True
|
119
129
|
"""
|
120
130
|
from mcsmapi.apis.file import File
|
121
131
|
|
122
|
-
return File
|
132
|
+
return File.unzip(
|
123
133
|
self.daemonId, self.uuid, os.path.join(self.target, self.name), target, code
|
124
134
|
)
|
125
135
|
|
126
136
|
def update(self, text: str) -> bool:
|
127
137
|
"""
|
128
|
-
|
138
|
+
更新该文件内容
|
129
139
|
**参数:**
|
130
|
-
- text (str):
|
140
|
+
- text (str): 文件内容
|
131
141
|
**返回:**
|
132
|
-
- bool: 更新成功后返回True
|
142
|
+
- bool: 更新成功后返回True
|
133
143
|
"""
|
134
144
|
from mcsmapi.apis.file import File
|
135
145
|
|
136
|
-
return File
|
146
|
+
return File.update(
|
137
147
|
self.daemonId, self.uuid, os.path.join(self.target, self.name), text
|
138
148
|
)
|
139
149
|
|
140
150
|
def download(self) -> str:
|
141
151
|
"""
|
142
|
-
|
152
|
+
下载该文件
|
143
153
|
**返回:**
|
144
|
-
- str: 文件下载的URL
|
154
|
+
- str: 文件下载的URL
|
145
155
|
"""
|
146
156
|
from mcsmapi.apis.file import File
|
147
157
|
|
148
|
-
return File
|
158
|
+
return File.download(
|
149
159
|
self.daemonId, self.uuid, os.path.join(self.target, self.name)
|
150
160
|
)
|
151
161
|
|
@@ -153,22 +163,22 @@ class FileItem(BaseModel):
|
|
153
163
|
class FileList(BaseModel):
|
154
164
|
"""文件列表"""
|
155
165
|
|
166
|
+
items: list[FileItem]
|
156
167
|
"""文件信息列表"""
|
157
|
-
|
168
|
+
page: int
|
158
169
|
"""当前页数"""
|
159
|
-
|
170
|
+
pageSize: int
|
160
171
|
"""文件列表单页大小"""
|
161
|
-
|
172
|
+
total: int
|
162
173
|
"""总页数"""
|
163
|
-
|
174
|
+
absolutePath: str
|
164
175
|
"""当前路径在远程节点的绝对路径"""
|
165
|
-
|
176
|
+
daemonId: str
|
166
177
|
"""远程节点uuid"""
|
167
|
-
|
178
|
+
uuid: str
|
168
179
|
"""实例uuid"""
|
169
|
-
|
180
|
+
target: str
|
170
181
|
"""文件(名称或目录)路径"""
|
171
|
-
target: str = ""
|
172
182
|
|
173
183
|
def __init__(self, **data: str):
|
174
184
|
super().__init__(**data)
|
@@ -179,50 +189,51 @@ class FileList(BaseModel):
|
|
179
189
|
|
180
190
|
async def upload(self, file: bytes, upload_dir: str) -> bool:
|
181
191
|
"""
|
182
|
-
|
192
|
+
上传文件到实例
|
183
193
|
|
184
194
|
**参数:**
|
185
|
-
- file (bytes):
|
186
|
-
- upload_dir (str): 上传文件的目标目录(包含文件名)
|
195
|
+
- file (bytes): 要上传的文件内容
|
196
|
+
- upload_dir (str): 上传文件的目标目录(包含文件名)
|
187
197
|
|
188
198
|
**返回:**
|
189
|
-
- bool:
|
199
|
+
- bool: 操作成功返回True
|
190
200
|
"""
|
191
201
|
from mcsmapi.apis.file import File
|
192
202
|
|
193
|
-
return await File
|
203
|
+
return await File.upload(self.daemonId, self.uuid, file, upload_dir)
|
194
204
|
|
195
205
|
def createFile(self, target: str) -> bool:
|
196
206
|
"""
|
197
|
-
|
207
|
+
创建文件
|
198
208
|
|
199
209
|
**参数:**
|
200
|
-
- target (str):
|
210
|
+
- target (str): 目标文件的路径,包含文件名
|
201
211
|
|
202
212
|
**返回:**
|
203
|
-
- bool: 创建成功后返回True
|
213
|
+
- bool: 创建成功后返回True
|
204
214
|
"""
|
205
215
|
from mcsmapi.apis.file import File
|
206
216
|
|
207
|
-
return File
|
217
|
+
return File.createFile(self.daemonId, self.uuid, target)
|
208
218
|
|
209
|
-
def
|
219
|
+
def createFolder(self, target: str) -> bool:
|
210
220
|
"""
|
211
221
|
创建文件夹
|
212
222
|
|
213
223
|
**参数:**
|
214
|
-
- target (str):
|
224
|
+
- target (str): 目标文件夹的路径
|
215
225
|
|
216
226
|
**返回:**
|
217
|
-
- bool: 创建成功后返回True
|
227
|
+
- bool: 创建成功后返回True
|
218
228
|
"""
|
219
229
|
from mcsmapi.apis.file import File
|
220
230
|
|
221
|
-
return File
|
231
|
+
return File.createFolder(self.daemonId, self.uuid, target)
|
232
|
+
|
222
233
|
|
234
|
+
class FileDownloadConfig(BaseModel):
|
223
235
|
|
224
|
-
|
236
|
+
password: str
|
225
237
|
"""文件下载密码"""
|
226
|
-
|
238
|
+
addr: str
|
227
239
|
"""文件下载地址"""
|
228
|
-
addr: str = ""
|