ezKit 1.9.4__py3-none-any.whl → 1.9.5__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.
- ezKit/cls.py +21 -11
- ezKit/sendemail.py +0 -18
- ezKit/stock.py +55 -23
- ezKit/utils.py +76 -53
- {ezKit-1.9.4.dist-info → ezKit-1.9.5.dist-info}/METADATA +1 -1
- {ezKit-1.9.4.dist-info → ezKit-1.9.5.dist-info}/RECORD +9 -9
- {ezKit-1.9.4.dist-info → ezKit-1.9.5.dist-info}/LICENSE +0 -0
- {ezKit-1.9.4.dist-info → ezKit-1.9.5.dist-info}/WHEEL +0 -0
- {ezKit-1.9.4.dist-info → ezKit-1.9.5.dist-info}/top_level.txt +0 -0
ezKit/cls.py
CHANGED
@@ -14,9 +14,13 @@ def up_down_analysis(
|
|
14
14
|
) -> list | pd.DataFrame | None:
|
15
15
|
"""涨停跌停数据"""
|
16
16
|
|
17
|
-
|
18
|
-
|
19
|
-
|
17
|
+
# 判断参数是否正确
|
18
|
+
match True:
|
19
|
+
case True if not utils.isTrue(target, str):
|
20
|
+
logger.error("argument error: target")
|
21
|
+
return None
|
22
|
+
case _:
|
23
|
+
pass
|
20
24
|
|
21
25
|
info: str = "获取涨停池股票"
|
22
26
|
match True:
|
@@ -113,11 +117,11 @@ def latest_data(
|
|
113
117
|
|
114
118
|
# 判断参数类型
|
115
119
|
match True:
|
116
|
-
case True if
|
117
|
-
logger.error("
|
120
|
+
case True if not utils.isTrue(payload, (str, dict)):
|
121
|
+
logger.error("argument error: payload")
|
118
122
|
return None
|
119
|
-
case True if
|
120
|
-
logger.error("
|
123
|
+
case True if not utils.isTrue(data_type, str):
|
124
|
+
logger.error("argument error: data_type")
|
121
125
|
return None
|
122
126
|
case _:
|
123
127
|
pass
|
@@ -273,12 +277,18 @@ def latest_data(
|
|
273
277
|
# --------------------------------------------------------------------------------------------------
|
274
278
|
|
275
279
|
|
276
|
-
def plate_codes(
|
280
|
+
def plate_codes(
|
281
|
+
plate: str
|
282
|
+
) -> list | None:
|
277
283
|
"""获取板块成分股代码"""
|
278
284
|
|
279
|
-
|
280
|
-
|
281
|
-
|
285
|
+
# 判断参数是否正确
|
286
|
+
match True:
|
287
|
+
case True if not utils.isTrue(plate, str):
|
288
|
+
logger.error("argument error: plate")
|
289
|
+
return None
|
290
|
+
case _:
|
291
|
+
pass
|
282
292
|
|
283
293
|
info: str = "获取板块成分股代码"
|
284
294
|
|
ezKit/sendemail.py
CHANGED
@@ -70,24 +70,6 @@ def sendemail(
|
|
70
70
|
path 图片路径
|
71
71
|
"""
|
72
72
|
|
73
|
-
# 参数判断
|
74
|
-
# match True:
|
75
|
-
# case True if utils.vTrue(smtp, dict) == False:
|
76
|
-
# logger.error('ERROR!! {} is not dictionary or none'.format('smtp'))
|
77
|
-
# return False
|
78
|
-
# case True if utils.vTrue(sender, dict) == False:
|
79
|
-
# logger.error('ERROR!! {} is not dictionary or none'.format('sender'))
|
80
|
-
# return False
|
81
|
-
# case True if (utils.vTrue(recipients, str) == False) and (utils.vTrue(recipients, list) == False):
|
82
|
-
# logger.error('ERROR!! {} is not list or none'.format('recipients'))
|
83
|
-
# return False
|
84
|
-
# case True if utils.vTrue(subject, str) == False:
|
85
|
-
# logger.error('ERROR!! {} is not string or none'.format('subject'))
|
86
|
-
# return False
|
87
|
-
# case True if utils.vTrue(html_file, str) == False:
|
88
|
-
# logger.error('ERROR!! {} is not string or none'.format('html_file'))
|
89
|
-
# return False
|
90
|
-
|
91
73
|
logger.success("sendemail start")
|
92
74
|
|
93
75
|
try:
|
ezKit/stock.py
CHANGED
@@ -12,7 +12,10 @@ from sqlalchemy.engine import Engine
|
|
12
12
|
from . import utils
|
13
13
|
|
14
14
|
|
15
|
-
def coderename(
|
15
|
+
def coderename(
|
16
|
+
target: str | dict,
|
17
|
+
restore: bool = False
|
18
|
+
) -> str | dict | None:
|
16
19
|
"""代码重命名"""
|
17
20
|
|
18
21
|
# 正向:
|
@@ -22,18 +25,10 @@ def coderename(target: str | dict, restore: bool = False) -> str | dict | None:
|
|
22
25
|
# coderename('sz000001', restore=True) => '000001'
|
23
26
|
# coderename({'code': 'sz000001', 'name': '平安银行'}) => {'code': '000001', 'name': '平安银行'}
|
24
27
|
|
25
|
-
#
|
28
|
+
# 判断参数是否正确
|
26
29
|
match True:
|
27
|
-
case True if
|
28
|
-
logger.error("argument
|
29
|
-
return None
|
30
|
-
case _:
|
31
|
-
pass
|
32
|
-
|
33
|
-
# 判断参数数据
|
34
|
-
match True:
|
35
|
-
case True if True not in [utils.isTrue(target, str), utils.isTrue(target, dict)]:
|
36
|
-
logger.error("argument data error: data")
|
30
|
+
case True if not utils.isTrue(target, (str, dict)):
|
31
|
+
logger.error("argument error: target")
|
37
32
|
return None
|
38
33
|
case _:
|
39
34
|
pass
|
@@ -85,7 +80,10 @@ def coderename(target: str | dict, restore: bool = False) -> str | dict | None:
|
|
85
80
|
# --------------------------------------------------------------------------------------------------
|
86
81
|
|
87
82
|
|
88
|
-
def kdj_vector(
|
83
|
+
def kdj_vector(
|
84
|
+
df: DataFrame,
|
85
|
+
kdj_options: tuple[int, int, int] = (9, 3, 3)
|
86
|
+
) -> DataFrame | None:
|
89
87
|
"""KDJ计算器"""
|
90
88
|
|
91
89
|
# 计算周期:Calculation Period, 也可使用 Lookback Period 表示回溯周期, 指用于计算指标值的时间周期.
|
@@ -96,20 +94,23 @@ def kdj_vector(df: DataFrame, cp: int = 9, sp1: int = 3, sp2: int = 3) -> DataFr
|
|
96
94
|
# 有采用 ewm 使用 com=2 的, 但是如果使用 com=2 在默认值的情况下KDJ值是正确的.
|
97
95
|
# 但是非默认值, 比如调整参数, 尝试慢速 KDJ 时就不对了, 最终采用 alpha = 1/m 的情况, 对比同花顺数据, 是正确的.
|
98
96
|
|
99
|
-
#
|
97
|
+
# 判断参数是否正确
|
100
98
|
match True:
|
101
|
-
case True if not
|
102
|
-
logger.error("argument
|
99
|
+
case True if not utils.isTrue(df, DataFrame):
|
100
|
+
logger.error("argument error: df")
|
101
|
+
return None
|
102
|
+
case True if True not in [utils.isTrue(kdj_options, tuple), all(utils.isTrue(item, int) for item in kdj_options)]:
|
103
|
+
logger.error("argument error: kdj_options")
|
103
104
|
return None
|
104
105
|
case _:
|
105
106
|
pass
|
106
107
|
|
107
108
|
try:
|
108
|
-
low_list = df['low'].rolling(
|
109
|
-
high_list = df['high'].rolling(
|
109
|
+
low_list = df['low'].rolling(kdj_options[0]).min()
|
110
|
+
high_list = df['high'].rolling(kdj_options[0]).max()
|
110
111
|
rsv = (df['close'] - low_list) / (high_list - low_list) * 100
|
111
|
-
df['K'] = rsv.ewm(alpha=1 /
|
112
|
-
df['D'] = df['K'].ewm(alpha=1 /
|
112
|
+
df['K'] = rsv.ewm(alpha=1 / kdj_options[1], adjust=False).mean()
|
113
|
+
df['D'] = df['K'].ewm(alpha=1 / kdj_options[2], adjust=False).mean()
|
113
114
|
df['J'] = (3 * df['K']) - (2 * df['D'])
|
114
115
|
return df
|
115
116
|
except Exception as e:
|
@@ -127,6 +128,20 @@ def data_vector(
|
|
127
128
|
) -> DataFrame | None:
|
128
129
|
"""数据运算"""
|
129
130
|
|
131
|
+
# 判断参数是否正确
|
132
|
+
match True:
|
133
|
+
case True if not utils.isTrue(df, DataFrame):
|
134
|
+
logger.error("argument error: df")
|
135
|
+
return None
|
136
|
+
case True if True not in [utils.isTrue(macd_options, tuple), all(utils.isTrue(item, int) for item in macd_options)]:
|
137
|
+
logger.error("argument error: macd_options")
|
138
|
+
return None
|
139
|
+
case True if True not in [utils.isTrue(kdj_options, tuple), all(utils.isTrue(item, int) for item in kdj_options)]:
|
140
|
+
logger.error("argument error: kdj_options")
|
141
|
+
return None
|
142
|
+
case _:
|
143
|
+
pass
|
144
|
+
|
130
145
|
try:
|
131
146
|
|
132
147
|
# 数据为空
|
@@ -176,7 +191,7 @@ def data_vector(
|
|
176
191
|
# ------------------------------------------------------------------------------------------
|
177
192
|
|
178
193
|
# 计算 KDJ: : 默认参数 9 3 3
|
179
|
-
kdj_data = kdj_vector(df, kdj_options
|
194
|
+
kdj_data = kdj_vector(df, kdj_options)
|
180
195
|
|
181
196
|
if kdj_data is not None:
|
182
197
|
|
@@ -226,12 +241,29 @@ def get_code_name_from_akshare() -> DataFrame | None:
|
|
226
241
|
# --------------------------------------------------------------------------------------------------
|
227
242
|
|
228
243
|
|
229
|
-
def get_stock_data_from_akshare(
|
244
|
+
def get_stock_data_from_akshare(
|
245
|
+
code: str,
|
246
|
+
adjust: str = "qfq",
|
247
|
+
period: str = "daily",
|
248
|
+
start_date: str = "19700101",
|
249
|
+
end_date: str = "20500101",
|
250
|
+
timeout: float = 10
|
251
|
+
) -> DataFrame | None:
|
230
252
|
"""从 akshare 获取数据"""
|
231
253
|
info = f"获取股票所有数据: {code}"
|
232
254
|
try:
|
233
255
|
logger.info(f"{info} ......")
|
234
|
-
|
256
|
+
# https://akshare.akfamily.xyz/data/stock/stock.html#id22
|
257
|
+
df: DataFrame = ak.stock_zh_a_hist(symbol=code, adjust=adjust, period=period, start_date=start_date, end_date=end_date, timeout=timeout)
|
258
|
+
df = df.rename(columns={
|
259
|
+
"日期": "date",
|
260
|
+
"开盘": "open",
|
261
|
+
"收盘": "close",
|
262
|
+
"最高": "high",
|
263
|
+
"最低": "low",
|
264
|
+
"成交量": "volume",
|
265
|
+
"成交额": "turnover"
|
266
|
+
})
|
235
267
|
df = df.round({'turnover': 4})
|
236
268
|
logger.success(f"{info} [成功]")
|
237
269
|
return df[['date', 'open', 'close', 'high', 'low', 'volume', 'turnover']].copy()
|
ezKit/utils.py
CHANGED
@@ -50,6 +50,11 @@ def isTrue(
|
|
50
50
|
# 判断变量类型: isinstance(x, str)
|
51
51
|
#
|
52
52
|
# 函数使用 callable(func) 判断
|
53
|
+
#
|
54
|
+
# 判断多个类型:
|
55
|
+
#
|
56
|
+
# isTrue("abc", (str, int))
|
57
|
+
# isTrue("abc", (str | int))
|
53
58
|
|
54
59
|
try:
|
55
60
|
|
@@ -100,33 +105,39 @@ def os_environ(
|
|
100
105
|
name: str,
|
101
106
|
value: Any = None
|
102
107
|
) -> Any:
|
103
|
-
"""
|
104
|
-
|
108
|
+
"""系统变量"""
|
109
|
+
|
110
|
+
# 伪全局变量
|
111
|
+
# Python 没有全局变量, 多个文件无法调用同一个变量.
|
112
|
+
# 为了解决这个问题, 将变量设置为系统变量, 从而实现多个文件调用同一个变量.
|
113
|
+
|
114
|
+
# 判断参数是否正确
|
115
|
+
match True:
|
116
|
+
case True if not isTrue(name, str):
|
117
|
+
logger.error("argument error: name")
|
118
|
+
return None
|
119
|
+
case _:
|
120
|
+
pass
|
105
121
|
|
106
|
-
伪全局变量
|
107
|
-
Python 没有全局变量, 多个文件无法调用同一个变量.
|
108
|
-
为了解决这个问题, 将变量设置为系统变量, 从而实现多个文件调用同一个变量.
|
109
|
-
"""
|
110
122
|
try:
|
111
123
|
|
112
124
|
# 变量名添加一个前缀, 防止和系统中其它变量名冲突
|
113
125
|
_variable_name = f'PYTHON_VARIABLE_{name}'
|
114
126
|
|
127
|
+
# 如果 value 的值是 None, 则从系统环境获取变量数据
|
115
128
|
if value is None:
|
116
129
|
|
117
130
|
_data = os.environ.get(_variable_name)
|
118
131
|
|
119
132
|
# 判断是否有数据
|
120
|
-
if _data:
|
121
|
-
try:
|
122
|
-
# 如果环境变量有值, 使用 json.loads() 解析
|
123
|
-
parsed_data = json.loads(_data)
|
124
|
-
return parsed_data
|
125
|
-
except json.JSONDecodeError:
|
126
|
-
return None
|
127
|
-
else:
|
133
|
+
if _data is None or not isTrue(_data, str):
|
128
134
|
return None
|
129
135
|
|
136
|
+
# 使用 json.loads() 解析数据
|
137
|
+
parsed_data = json.loads(_data)
|
138
|
+
return parsed_data
|
139
|
+
|
140
|
+
# 如果 value 的值不是 None, 则保存数据到系统环境变量
|
130
141
|
_data = json.dumps(value)
|
131
142
|
os.environ[_variable_name] = _data
|
132
143
|
|
@@ -143,29 +154,52 @@ def os_environ(
|
|
143
154
|
def mam_of_numbers(
|
144
155
|
numbers: list | tuple,
|
145
156
|
dest_type: str | None = None
|
146
|
-
) -> tuple
|
147
|
-
"""
|
148
|
-
(maximum, average, minimum)
|
157
|
+
) -> tuple | None:
|
158
|
+
"""返回一组数字中的 最大值(maximum), 平均值(average), 最小值(minimum)"""
|
149
159
|
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
|
160
|
+
# numbers 数字列表 (仅支持 list 和 tuple, 不支 set)
|
161
|
+
# dest_type 目标类型 (将数字列表中的数字转换成统一的类型)
|
162
|
+
|
163
|
+
# 判断参数是否正确
|
164
|
+
match True:
|
165
|
+
case True if not isTrue(numbers, (list, tuple)):
|
166
|
+
logger.error("argument error: numbers")
|
167
|
+
return None
|
168
|
+
case True if True not in [isTrue(dest_type, str), dest_type is None]:
|
169
|
+
logger.error("argument error: dest_type")
|
170
|
+
return None
|
171
|
+
case _:
|
172
|
+
pass
|
154
173
|
|
155
174
|
try:
|
175
|
+
|
156
176
|
_numbers = deepcopy(numbers)
|
177
|
+
|
178
|
+
# 转换数据类型
|
157
179
|
match True:
|
158
|
-
case True if dest_type ==
|
180
|
+
case True if dest_type == "float":
|
159
181
|
_numbers = [float(i) for i in numbers]
|
160
|
-
case True if dest_type ==
|
182
|
+
case True if dest_type == "int":
|
161
183
|
_numbers = [int(i) for i in numbers]
|
184
|
+
case _:
|
185
|
+
pass
|
186
|
+
|
187
|
+
# 提取数据
|
162
188
|
_num_max = max(_numbers)
|
163
|
-
_num_avg = sum(_numbers) / len(_numbers)
|
189
|
+
_num_avg = f"{sum(_numbers) / len(_numbers):.2f}"
|
164
190
|
_num_min = min(_numbers)
|
191
|
+
|
192
|
+
if dest_type == int:
|
193
|
+
_num_avg = int(_num_avg)
|
194
|
+
else:
|
195
|
+
_num_avg = float(_num_avg)
|
196
|
+
|
197
|
+
# 返回数据
|
165
198
|
return _num_max, _num_avg, _num_min
|
199
|
+
|
166
200
|
except Exception as e:
|
167
201
|
logger.exception(e)
|
168
|
-
return None
|
202
|
+
return None
|
169
203
|
|
170
204
|
|
171
205
|
# --------------------------------------------------------------------------------------------------
|
@@ -187,10 +221,10 @@ def step_number_for_split_equally(
|
|
187
221
|
|
188
222
|
[1, 2, 3, 4, 5, 6, 7, 8, 9]
|
189
223
|
|
190
|
-
分成 2 份 -> [[1, 2, 3, 4, 5], [6, 7, 8, 9]]
|
191
|
-
分成 3 份 -> [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
|
192
|
-
分成 4 份 -> [[1, 2, 3], [4, 5], [6, 7], [8, 9]]
|
193
|
-
分成 5 份 -> [[1, 2], [3, 4], [5, 6], [7, 8], [9]]
|
224
|
+
分成 2 份 -> [[1, 2, 3, 4, 5], [6, 7, 8, 9]] -> 返回 5
|
225
|
+
分成 3 份 -> [[1, 2, 3], [4, 5, 6], [7, 8, 9]] -> 返回 3
|
226
|
+
分成 4 份 -> [[1, 2, 3], [4, 5], [6, 7], [8, 9]] -> 返回 3
|
227
|
+
分成 5 份 -> [[1, 2], [3, 4], [5, 6], [7, 8], [9]] -> 返回 2
|
194
228
|
"""
|
195
229
|
try:
|
196
230
|
if integer % split_equally_number == 0:
|
@@ -411,27 +445,16 @@ def list_print_by_step(
|
|
411
445
|
) -> bool:
|
412
446
|
"""根据 步长 和 分隔符 有规律的打印列表中的数据"""
|
413
447
|
|
414
|
-
#
|
415
|
-
match True:
|
416
|
-
case True if not isinstance(data, list):
|
417
|
-
logger.error("argument type error: data")
|
418
|
-
return False
|
419
|
-
case True if not isinstance(step, int):
|
420
|
-
logger.error("argument type error: step")
|
421
|
-
return False
|
422
|
-
case True if not isinstance(separator, str):
|
423
|
-
logger.error("argument type error: separator")
|
424
|
-
return False
|
425
|
-
case _:
|
426
|
-
pass
|
427
|
-
|
428
|
-
# 判断参数数据
|
448
|
+
# 判断参数是否正确
|
429
449
|
match True:
|
430
450
|
case True if not isTrue(data, list):
|
431
|
-
logger.error("argument
|
451
|
+
logger.error("argument error: data")
|
432
452
|
return False
|
433
453
|
case True if not isTrue(step, int):
|
434
|
-
logger.error("argument
|
454
|
+
logger.error("argument error: step")
|
455
|
+
return False
|
456
|
+
case True if not isTrue(separator, str):
|
457
|
+
logger.error("argument error: separator")
|
435
458
|
return False
|
436
459
|
case _:
|
437
460
|
pass
|
@@ -943,7 +966,7 @@ def datetime_local_to_timezone(
|
|
943
966
|
tz: datetime.timezone = datetime.timezone.utc
|
944
967
|
) -> datetime.datetime | None:
|
945
968
|
"""
|
946
|
-
Local datetime to TimeZone datetime
|
969
|
+
Local datetime to TimeZone datetime(默认转换为 UTC datetime)
|
947
970
|
replace(tzinfo=None) 移除结尾的时区信息
|
948
971
|
"""
|
949
972
|
try:
|
@@ -960,7 +983,7 @@ def datetime_utc_to_timezone(
|
|
960
983
|
tz: Any = datetime.datetime.now(datetime.timezone.utc).astimezone().tzinfo
|
961
984
|
) -> datetime.datetime | None:
|
962
985
|
"""
|
963
|
-
UTC datetime to TimeZone datetime
|
986
|
+
UTC datetime to TimeZone datetime(默认转换为 Local datetime)
|
964
987
|
replace(tzinfo=None) 移除结尾的时区信息
|
965
988
|
"""
|
966
989
|
try:
|
@@ -1173,25 +1196,25 @@ def delete_directory(
|
|
1173
1196
|
"""
|
1174
1197
|
delete directory
|
1175
1198
|
|
1176
|
-
https
|
1199
|
+
https: // docs.python.org / 3 / library / os.html # os.rmdir
|
1177
1200
|
|
1178
1201
|
os.rmdir(path, *, dir_fd=None)
|
1179
1202
|
|
1180
|
-
Remove
|
1203
|
+
Remove(delete) the directory path.
|
1181
1204
|
|
1182
1205
|
If the directory does not exist or is not empty, an FileNotFoundError or an OSError is raised respectively.
|
1183
1206
|
|
1184
1207
|
In order to remove whole directory trees, shutil.rmtree() can be used.
|
1185
1208
|
|
1186
|
-
https
|
1209
|
+
https: // docs.python.org / 3 / library / shutil.html # shutil.rmtree
|
1187
1210
|
|
1188
1211
|
shutil.rmtree(path, ignore_errors=False, onerror=None)
|
1189
1212
|
|
1190
|
-
Delete an entire directory tree; path must point to a directory
|
1213
|
+
Delete an entire directory tree; path must point to a directory(but not a symbolic link to a directory).
|
1191
1214
|
|
1192
1215
|
If ignore_errors is true, errors resulting from failed removals will be ignored;
|
1193
1216
|
|
1194
|
-
if false or omitted, such errors are handled by calling a handler specified by onerror or, if that is omitted, they raise an exception.
|
1217
|
+
if false or omitted, such errors are handled by calling a handler specified by onerror or , if that is omitted, they raise an exception.
|
1195
1218
|
"""
|
1196
1219
|
try:
|
1197
1220
|
|
@@ -2,19 +2,19 @@ ezKit/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
2
2
|
ezKit/bottle.py,sha256=usKK1wVaZw4_D-4VwMYmOIc8jtz4TrpM30nck59HMFw,180178
|
3
3
|
ezKit/bottle_extensions.py,sha256=3reEQVZuHklXTl6r7F8kiBFFPb0RaAGc3mYJJnrMDjQ,1129
|
4
4
|
ezKit/cipher.py,sha256=0T_StbjiNI4zgrjVgcfU-ffKgu1waBA9UDudAnqFcNM,2896
|
5
|
-
ezKit/cls.py,sha256=
|
5
|
+
ezKit/cls.py,sha256=e7_72kv0Q_o023xcjKNtrkfKg7frABQvCF_JjoHV94U,10800
|
6
6
|
ezKit/database.py,sha256=cmFsZ88Ah7LCBAhEcjN_aI_pEuu682wUgi-TJN8a9Wc,6921
|
7
7
|
ezKit/http.py,sha256=i3Kn5AMAMicDMcDjxKKZU7zqEKTU88Ec9_LwCuBJy-0,1801
|
8
8
|
ezKit/mongo.py,sha256=dOm_1wXEPp_e8Ml5Qq78M7FDNrQUAZaThzVIiiLJJwk,2393
|
9
9
|
ezKit/qywx.py,sha256=X_H4fzP-iEqeDEbumr7D1bXi6dxczaxfO8iyutzy02s,7171
|
10
10
|
ezKit/redis.py,sha256=g2_V4jvq0djRc20jLZkgeAeF_bYrq-Rbl_kHcCUPZcA,1965
|
11
|
-
ezKit/sendemail.py,sha256=
|
12
|
-
ezKit/stock.py,sha256=
|
11
|
+
ezKit/sendemail.py,sha256=tRXCsJm_RfTJ9xEWe_lTQ5kOs2JxHGPXvq0oWA7prq0,7263
|
12
|
+
ezKit/stock.py,sha256=W3XxIAkZEy5pVDHmLqBV0lWbLZ-wTNyFGR3iIu8JLo4,11098
|
13
13
|
ezKit/token.py,sha256=HKREyZj_T2S8-aFoFIrBXTaCKExQq4zE66OHXhGHqQg,1750
|
14
|
-
ezKit/utils.py,sha256=
|
14
|
+
ezKit/utils.py,sha256=BGTW1_Q1YvNuars4ynqETT6VrC03cxTV6duA_jJos0Q,43435
|
15
15
|
ezKit/xftp.py,sha256=XyIdr_2rxRVLqPofG6fIYWhAMVsFwTyp46dg5P9FLW4,7774
|
16
|
-
ezKit-1.9.
|
17
|
-
ezKit-1.9.
|
18
|
-
ezKit-1.9.
|
19
|
-
ezKit-1.9.
|
20
|
-
ezKit-1.9.
|
16
|
+
ezKit-1.9.5.dist-info/LICENSE,sha256=OXLcl0T2SZ8Pmy2_dmlvKuetivmyPd5m1q-Gyd-zaYY,35149
|
17
|
+
ezKit-1.9.5.dist-info/METADATA,sha256=Kiu2B2RNaDCysLuepQZKhFQglyqsu41eAX9uIiP7_dA,190
|
18
|
+
ezKit-1.9.5.dist-info/WHEEL,sha256=PZUExdf71Ui_so67QXpySuHtCi3-J3wvF4ORK6k_S8U,91
|
19
|
+
ezKit-1.9.5.dist-info/top_level.txt,sha256=aYLB_1WODsqNTsTFWcKP-BN0KCTKcV-HZJ4zlHkCFw8,6
|
20
|
+
ezKit-1.9.5.dist-info/RECORD,,
|
File without changes
|
File without changes
|
File without changes
|