pytbox 0.1.5__py3-none-any.whl → 0.1.6__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.
Potentially problematic release.
This version of pytbox might be problematic. Click here for more details.
- pytbox/alicloud/sls.py +9 -6
- pytbox/base.py +23 -1
- pytbox/database/victoriametrics.py +71 -4
- pytbox/log/logger.py +22 -6
- {pytbox-0.1.5.dist-info → pytbox-0.1.6.dist-info}/METADATA +1 -1
- {pytbox-0.1.5.dist-info → pytbox-0.1.6.dist-info}/RECORD +9 -9
- {pytbox-0.1.5.dist-info → pytbox-0.1.6.dist-info}/WHEEL +0 -0
- {pytbox-0.1.5.dist-info → pytbox-0.1.6.dist-info}/entry_points.txt +0 -0
- {pytbox-0.1.5.dist-info → pytbox-0.1.6.dist-info}/top_level.txt +0 -0
pytbox/alicloud/sls.py
CHANGED
|
@@ -5,19 +5,21 @@ from typing import Literal
|
|
|
5
5
|
from aliyun.log import GetLogsRequest, LogItem, PutLogsRequest
|
|
6
6
|
from aliyun.log import LogClient as SlsLogClient
|
|
7
7
|
from aliyun.log.auth import AUTH_VERSION_4
|
|
8
|
-
from ..utils.env import check_env
|
|
9
8
|
|
|
10
9
|
|
|
11
10
|
|
|
12
11
|
class AliCloudSls:
|
|
13
|
-
|
|
14
|
-
|
|
12
|
+
'''
|
|
13
|
+
pip install -U aliyun-log-python-sdk
|
|
14
|
+
'''
|
|
15
|
+
def __init__(self, access_key_id: str=None, access_key_secret: str=None, project: str=None, logstore: str=None, env: str='prod'):
|
|
15
16
|
# 日志服务的服务接入点
|
|
16
17
|
self.endpoint = "cn-shanghai.log.aliyuncs.com"
|
|
17
18
|
# 创建 LogClient 实例,使用 V4 签名,根据实际情况填写 region,这里以杭州为例
|
|
18
19
|
self.client = SlsLogClient(self.endpoint, access_key_id, access_key_secret, auth_version=AUTH_VERSION_4, region='cn-shanghai')
|
|
19
20
|
self.project = project
|
|
20
21
|
self.logstore = logstore
|
|
22
|
+
self.env = env
|
|
21
23
|
|
|
22
24
|
def get_logs(self, project_name, logstore_name, query, from_time, to_time):
|
|
23
25
|
logstore_index = {'line': {
|
|
@@ -57,7 +59,7 @@ class AliCloudSls:
|
|
|
57
59
|
log_group = []
|
|
58
60
|
log_item = LogItem()
|
|
59
61
|
contents = [
|
|
60
|
-
('env',
|
|
62
|
+
('env', self.env),
|
|
61
63
|
('level', level),
|
|
62
64
|
('app', app),
|
|
63
65
|
('msg', msg),
|
|
@@ -69,8 +71,9 @@ class AliCloudSls:
|
|
|
69
71
|
log_item.set_contents(contents)
|
|
70
72
|
log_group.append(log_item)
|
|
71
73
|
request = PutLogsRequest(self.project, self.logstore, topic, "", log_group, compress=False)
|
|
72
|
-
self.client.put_logs(request)
|
|
73
|
-
|
|
74
|
+
r = self.client.put_logs(request)
|
|
75
|
+
return r
|
|
76
|
+
|
|
74
77
|
def put_logs_for_meraki(self, alert):
|
|
75
78
|
log_group = []
|
|
76
79
|
log_item = LogItem()
|
pytbox/base.py
CHANGED
|
@@ -15,6 +15,8 @@ from pytbox.vmware import VMwareClient
|
|
|
15
15
|
from pytbox.pyjira import PyJira
|
|
16
16
|
from pytbox.mail.client import MailClient
|
|
17
17
|
from pytbox.mail.alimail import AliMail
|
|
18
|
+
from pytbox.alicloud.sls import AliCloudSls
|
|
19
|
+
|
|
18
20
|
|
|
19
21
|
config = load_config_by_file(path='/workspaces/pytbox/tests/alert/config_dev.toml', oc_vault_id=os.environ.get('oc_vault_id'))
|
|
20
22
|
|
|
@@ -53,6 +55,19 @@ def get_logger(app):
|
|
|
53
55
|
mongo=get_mongo('alert_program')
|
|
54
56
|
)
|
|
55
57
|
|
|
58
|
+
def get_logger_sls(app):
|
|
59
|
+
return AppLogger(
|
|
60
|
+
app_name=app,
|
|
61
|
+
enable_sls=True,
|
|
62
|
+
feishu=feishu,
|
|
63
|
+
dida=dida,
|
|
64
|
+
mongo=get_mongo('alert_program'),
|
|
65
|
+
sls_access_key_id=config['alicloud']['account1']['access_key_id'],
|
|
66
|
+
sls_access_key_secret=config['alicloud']['account1']['access_key_secret'],
|
|
67
|
+
sls_project=config['alicloud']['account1']['project'],
|
|
68
|
+
sls_logstore=config['alicloud']['account1']['logstore']
|
|
69
|
+
)
|
|
70
|
+
|
|
56
71
|
# ad_dev = ADClient(
|
|
57
72
|
# server=config['ad']['dev']['AD_SERVER'],
|
|
58
73
|
# base_dn=config['ad']['dev']['BASE_DN'],
|
|
@@ -85,4 +100,11 @@ pyjira = PyJira(
|
|
|
85
100
|
|
|
86
101
|
mail_163 = MailClient(mail_address=config['mail']['163']['mail_address'], password=config['mail']['163']['password'])
|
|
87
102
|
mail_qq = MailClient(mail_address=config['mail']['qq']['mail_address'], password=config['mail']['qq']['password'])
|
|
88
|
-
ali_mail = AliMail(mail_address=config['mail']['aliyun']['mail_address'], client_id=config['mail']['aliyun']['client_id'], client_secret=config['mail']['aliyun']['client_secret'])
|
|
103
|
+
ali_mail = AliMail(mail_address=config['mail']['aliyun']['mail_address'], client_id=config['mail']['aliyun']['client_id'], client_secret=config['mail']['aliyun']['client_secret'])
|
|
104
|
+
|
|
105
|
+
sls = AliCloudSls(
|
|
106
|
+
access_key_id=config['alicloud']['account1']['access_key_id'],
|
|
107
|
+
access_key_secret=config['alicloud']['account1']['access_key_secret'],
|
|
108
|
+
project=config['alicloud']['account1']['project'],
|
|
109
|
+
logstore=config['alicloud']['account1']['logstore']
|
|
110
|
+
)
|
|
@@ -18,7 +18,7 @@ class VictoriaMetrics:
|
|
|
18
18
|
'Accept': 'application/json'
|
|
19
19
|
})
|
|
20
20
|
|
|
21
|
-
def query(self, query: str, output_format: Literal['json']=None) -> ReturnResponse:
|
|
21
|
+
def query(self, query: str=None, output_format: Literal['json']=None) -> ReturnResponse:
|
|
22
22
|
'''
|
|
23
23
|
查询指标数据
|
|
24
24
|
|
|
@@ -61,6 +61,52 @@ class VictoriaMetrics:
|
|
|
61
61
|
else:
|
|
62
62
|
return resp
|
|
63
63
|
|
|
64
|
+
def query_range(self, query):
|
|
65
|
+
'''
|
|
66
|
+
查询指标数据
|
|
67
|
+
|
|
68
|
+
Args:
|
|
69
|
+
query (str): 查询语句
|
|
70
|
+
|
|
71
|
+
Returns:
|
|
72
|
+
dict: 查询结果
|
|
73
|
+
'''
|
|
74
|
+
url = f"{self.url}/prometheus/api/v1/query_range"
|
|
75
|
+
|
|
76
|
+
data = {
|
|
77
|
+
'query': query,
|
|
78
|
+
'start': '-1d',
|
|
79
|
+
'step': '1h'
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
r = requests.post(url, data=data, timeout=self.timeout)
|
|
83
|
+
res_json = r.json()
|
|
84
|
+
print(res_json)
|
|
85
|
+
# status = res_json.get("status")
|
|
86
|
+
# result = res_json.get("data", {}).get("result", [])
|
|
87
|
+
# is_json = output_format == 'json'
|
|
88
|
+
|
|
89
|
+
# if status == "success":
|
|
90
|
+
# if result:
|
|
91
|
+
# code = 0
|
|
92
|
+
# msg = f"[{query}] 查询成功!"
|
|
93
|
+
# data = result
|
|
94
|
+
# else:
|
|
95
|
+
# code = 2
|
|
96
|
+
# msg = f"[{query}] 没有查询到结果"
|
|
97
|
+
# data = res_json
|
|
98
|
+
# else:
|
|
99
|
+
# code = 1
|
|
100
|
+
# msg = f"[{query}] 查询失败: {res_json.get('error')}"
|
|
101
|
+
# data = res_json
|
|
102
|
+
|
|
103
|
+
# resp = ReturnResponse(code=code, msg=msg, data=data)
|
|
104
|
+
|
|
105
|
+
# if is_json:
|
|
106
|
+
# json_result = json.dumps(resp.__dict__, ensure_ascii=False)
|
|
107
|
+
# return json_result
|
|
108
|
+
# else:
|
|
109
|
+
# return resp
|
|
64
110
|
def get_labels(self, metric_name: str) -> ReturnResponse:
|
|
65
111
|
url = f"{self.url}/api/v1/series?match[]={metric_name}"
|
|
66
112
|
response = requests.get(url, timeout=self.timeout)
|
|
@@ -104,7 +150,6 @@ class VictoriaMetrics:
|
|
|
104
150
|
code = 0
|
|
105
151
|
msg = f"已检查 {target} 最近 {last_minute} 分钟是正常的!"
|
|
106
152
|
else:
|
|
107
|
-
|
|
108
153
|
if all(str(item[1]) == "1" for item in values):
|
|
109
154
|
code = 1
|
|
110
155
|
msg = f"已检查 {target} 最近 {last_minute} 分钟是异常的!"
|
|
@@ -114,7 +159,6 @@ class VictoriaMetrics:
|
|
|
114
159
|
elif r.code == 2:
|
|
115
160
|
code = 2
|
|
116
161
|
msg = f"没有查询到 {target} 最近 {last_minute} 分钟的ping结果!"
|
|
117
|
-
|
|
118
162
|
try:
|
|
119
163
|
data = r.data[0]
|
|
120
164
|
except KeyError:
|
|
@@ -146,4 +190,27 @@ class VictoriaMetrics:
|
|
|
146
190
|
query = f'(rate(snmp_interface_ifHCOutOctets{{sysName="{sysName}", ifName="{ifName}"}}[{last_minutes}m])) * 8 / 1000000'
|
|
147
191
|
r = self.query(query)
|
|
148
192
|
rate = r.data[0]['value'][1]
|
|
149
|
-
return int(float(rate))
|
|
193
|
+
return int(float(rate))
|
|
194
|
+
|
|
195
|
+
def check_snmp_port_status(self, sysname: str=None, if_name: str=None, last_minute: int=5) -> ReturnResponse:
|
|
196
|
+
'''
|
|
197
|
+
查询端口状态
|
|
198
|
+
status code 可参考 SNMP 文件 https://mibbrowser.online/mibdb_search.php?mib=IF-MIB
|
|
199
|
+
|
|
200
|
+
Args:
|
|
201
|
+
sysname (_type_): 设备名称
|
|
202
|
+
if_name (_type_): _description_
|
|
203
|
+
last_minute (_type_): _description_
|
|
204
|
+
|
|
205
|
+
Returns:
|
|
206
|
+
ReturnResponse:
|
|
207
|
+
code: 0, msg: , data: up,down
|
|
208
|
+
'''
|
|
209
|
+
q = f"""avg_over_time(snmp_interface_ifOperStatus{{sysName="{sysname}", ifName="{if_name}"}}[{last_minute}m])"""
|
|
210
|
+
r = self.query(query=q)
|
|
211
|
+
status_code = r.data[0]['value'][1]
|
|
212
|
+
if status_code == 1:
|
|
213
|
+
status = 'up'
|
|
214
|
+
else:
|
|
215
|
+
status = 'down'
|
|
216
|
+
return ReturnResponse(code=0, msg=f"{sysname} {if_name} 最近 {last_minute} 分钟端口状态为 {status}", data=status)
|
pytbox/log/logger.py
CHANGED
|
@@ -9,7 +9,7 @@ from ..database.mongo import Mongo
|
|
|
9
9
|
from ..feishu.client import Client as FeishuClient
|
|
10
10
|
from ..utils.timeutils import TimeUtils
|
|
11
11
|
from ..dida365 import Dida365
|
|
12
|
-
|
|
12
|
+
from ..alicloud.sls import AliCloudSls
|
|
13
13
|
|
|
14
14
|
logger.remove()
|
|
15
15
|
logger.add(sys.stdout, colorize=True, format="<green>{time:YYYY-MM-DD HH:mm:ss.SSS}</green> | <level>{level: <8}</level> | <level>{message}</level>")
|
|
@@ -31,7 +31,6 @@ class AppLogger:
|
|
|
31
31
|
feishu: FeishuClient=None,
|
|
32
32
|
dida: Dida365=None,
|
|
33
33
|
enable_sls: bool=False,
|
|
34
|
-
sls_url: str=None,
|
|
35
34
|
sls_access_key_id: str=None,
|
|
36
35
|
sls_access_key_secret: str=None,
|
|
37
36
|
sls_project: str=None,
|
|
@@ -49,10 +48,17 @@ class AppLogger:
|
|
|
49
48
|
self.stream = stream
|
|
50
49
|
self.victorialog = Victorialog(url=victorialog_url)
|
|
51
50
|
self.enable_victorialog = enable_victorialog
|
|
51
|
+
self.enable_sls = enable_sls
|
|
52
52
|
self.mongo = mongo
|
|
53
53
|
self.feishu = feishu
|
|
54
54
|
self.dida = dida
|
|
55
|
-
|
|
55
|
+
self.sls = AliCloudSls(
|
|
56
|
+
access_key_id=sls_access_key_id,
|
|
57
|
+
access_key_secret=sls_access_key_secret,
|
|
58
|
+
project=sls_project,
|
|
59
|
+
logstore=sls_logstore
|
|
60
|
+
)
|
|
61
|
+
|
|
56
62
|
def _get_caller_info(self) -> tuple[str, int, str]:
|
|
57
63
|
"""
|
|
58
64
|
获取调用者信息
|
|
@@ -78,6 +84,9 @@ class AppLogger:
|
|
|
78
84
|
logger.debug(f"[{caller_filename}:{caller_lineno}:{caller_function}] {message}")
|
|
79
85
|
if self.enable_victorialog:
|
|
80
86
|
self.victorialog.send_program_log(stream=self.stream, level="DEBUG", message=message, app_name=self.app_name, file_name=call_full_filename, line_number=caller_lineno, function_name=caller_function)
|
|
87
|
+
if self.enable_sls:
|
|
88
|
+
self.sls.put_logs(level="DEBUG", msg=message, app=self.app_name, caller_filename=caller_filename, caller_lineno=caller_lineno, caller_function=caller_function, call_full_filename=call_full_filename)
|
|
89
|
+
|
|
81
90
|
|
|
82
91
|
def info(self, message: str='', feishu_notify: bool=False):
|
|
83
92
|
"""记录信息级别日志"""
|
|
@@ -85,22 +94,28 @@ class AppLogger:
|
|
|
85
94
|
logger.info(f"[{caller_filename}:{caller_lineno}:{caller_function}] {message}")
|
|
86
95
|
if self.enable_victorialog:
|
|
87
96
|
r = self.victorialog.send_program_log(stream=self.stream, level="INFO", message=message, app_name=self.app_name, file_name=call_full_filename, line_number=caller_lineno, function_name=caller_function)
|
|
97
|
+
if self.enable_sls:
|
|
98
|
+
self.sls.put_logs(level="INFO", msg=message, app=self.app_name, caller_filename=caller_filename, caller_lineno=caller_lineno, caller_function=caller_function, call_full_filename=call_full_filename)
|
|
88
99
|
if feishu_notify:
|
|
89
100
|
self.feishu(message)
|
|
90
|
-
|
|
101
|
+
|
|
91
102
|
def warning(self, message: str):
|
|
92
103
|
"""记录警告级别日志"""
|
|
93
104
|
caller_filename, caller_lineno, caller_function, call_full_filename = self._get_caller_info()
|
|
94
105
|
logger.warning(f"[{caller_filename}:{caller_lineno}:{caller_function}] {message}")
|
|
95
106
|
if self.enable_victorialog:
|
|
96
107
|
self.victorialog.send_program_log(stream=self.stream, level="WARN", message=message, app_name=self.app_name, file_name=call_full_filename, line_number=caller_lineno, function_name=caller_function)
|
|
97
|
-
|
|
108
|
+
if self.enable_sls:
|
|
109
|
+
self.sls.put_logs(level="WARN", msg=message, app=self.app_name, caller_filename=caller_filename, caller_lineno=caller_lineno, caller_function=caller_function, call_full_filename=call_full_filename)
|
|
110
|
+
|
|
98
111
|
def error(self, message: str):
|
|
99
112
|
"""记录错误级别日志"""
|
|
100
113
|
caller_filename, caller_lineno, caller_function, call_full_filename = self._get_caller_info()
|
|
101
114
|
logger.error(f"[{caller_filename}:{caller_lineno}:{caller_function}] {message}")
|
|
102
115
|
if self.enable_victorialog:
|
|
103
116
|
self.victorialog.send_program_log(stream=self.stream, level="ERROR", message=message, app_name=self.app_name, file_name=call_full_filename, line_number=caller_lineno, function_name=caller_function)
|
|
117
|
+
if self.enable_sls:
|
|
118
|
+
self.sls.put_logs(level="ERROR", msg=message, app=self.app_name, caller_filename=caller_filename, caller_lineno=caller_lineno, caller_function=caller_function, call_full_filename=call_full_filename)
|
|
104
119
|
|
|
105
120
|
if self.feishu:
|
|
106
121
|
existing_message = self.mongo.collection.find_one({"message": message}, sort=[("time", -1)])
|
|
@@ -150,7 +165,8 @@ class AppLogger:
|
|
|
150
165
|
logger.critical(f"[{caller_filename}:{caller_lineno}:{caller_function}] {message}")
|
|
151
166
|
if self.enable_victorialog:
|
|
152
167
|
self.victorialog.send_program_log(stream=self.stream, level="CRITICAL", message=message, app_name=self.app_name, file_name=call_full_filename, line_number=caller_lineno, function_name=caller_function)
|
|
153
|
-
|
|
168
|
+
if self.enable_sls:
|
|
169
|
+
self.sls.put_logs(level="CRITICAL", msg=message, app=self.app_name, caller_filename=caller_filename, caller_lineno=caller_lineno, caller_function=caller_function, call_full_filename=call_full_filename)
|
|
154
170
|
|
|
155
171
|
# 使用示例
|
|
156
172
|
if __name__ == "__main__":
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
pytbox/base.py,sha256=
|
|
1
|
+
pytbox/base.py,sha256=7wUhNSX8sbZ5hlgWG7BhFYtNOhVB6b-k3ULNA0vPchU,3948
|
|
2
2
|
pytbox/cli.py,sha256=N775a0GK80IT2lQC2KRYtkZpIiu9UjavZmaxgNUgJhQ,160
|
|
3
3
|
pytbox/dida365.py,sha256=pUMPB9AyLZpTTbaz2LbtzdEpyjvuGf4YlRrCvM5sbJo,10545
|
|
4
4
|
pytbox/excel.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
@@ -8,7 +8,7 @@ pytbox/pyjira.py,sha256=TMy34Rtu7OXRA8wpUuLsFeyIQfRNUn2ed2no00L8YSE,22470
|
|
|
8
8
|
pytbox/vmware.py,sha256=WiH67_3-VCBjXJuh3UueOc31BdZDItiZhkeuPzoRhw4,3975
|
|
9
9
|
pytbox/alert/alert_handler.py,sha256=FePPQS4LyGphSJ0QMv0_pLWaXxEqsRlcTKMfUjtsNfk,5048
|
|
10
10
|
pytbox/alert/ping.py,sha256=g36X0U3U8ndZqfpVIcuoxJJ0X5gST3I_IwjTQC1roHA,779
|
|
11
|
-
pytbox/alicloud/sls.py,sha256
|
|
11
|
+
pytbox/alicloud/sls.py,sha256=-r6rbCwDUQ4jwAgSVSNu7B2h1MNg20CrRIKnlXVeY9w,4159
|
|
12
12
|
pytbox/categraf/build_config.py,sha256=9G85rLqkz3lchpH7ef0LbvckYHl0nRA6mHVLeUfs9Mw,6308
|
|
13
13
|
pytbox/categraf/instances.toml,sha256=jcJyEaqhohUcECczWArxUK4t0-rdk4vmrX21kxZlSLA,1254
|
|
14
14
|
pytbox/categraf/jinja2/__init__.py,sha256=Epm01j8Oujeg4Sk5GgHMvgKIZ6h3BTx-MGmuMgIjUMo,150
|
|
@@ -43,13 +43,13 @@ pytbox/cli/formatters/__init__.py,sha256=4o85w4j-A-O1oBLvuE9q8AFiJ2C9rvB3MIKsy5V
|
|
|
43
43
|
pytbox/cli/formatters/output.py,sha256=h5WhZlQk1rjmxEj88Jy5ODLcv6L5zfGUhks_3AWIkKU,5455
|
|
44
44
|
pytbox/common/__init__.py,sha256=3JWfgCQZKZuSH5NCE7OCzKwq82pkyop9l7sH5YSNyfU,122
|
|
45
45
|
pytbox/database/mongo.py,sha256=CSpHC7iR-M0BaVxXz5j6iXjMKPgXJX_G7MrjCj5Gm8Q,3478
|
|
46
|
-
pytbox/database/victoriametrics.py,sha256=
|
|
46
|
+
pytbox/database/victoriametrics.py,sha256=0QXkrnqL0rV7dGaHmtZus-MdEW3uX9ZPm0D-sS4L1DU,7606
|
|
47
47
|
pytbox/feishu/client.py,sha256=kwGLseGT_iQUFmSqpuS2_77WmxtHstD64nXvktuQ3B4,5865
|
|
48
48
|
pytbox/feishu/endpoints.py,sha256=z3nPOZPC2JGDJlO7SusWBpRA33hZZ4Z-GBhI6F8L_u4,40240
|
|
49
49
|
pytbox/feishu/errors.py,sha256=79qFAHZw7jDj3gnWAjI1-W4tB0q1_aSfdjee4xzXeuI,1179
|
|
50
50
|
pytbox/feishu/helpers.py,sha256=jhSkHiUw4822QBXx2Jw8AksogZdakZ-3QqvC3lB3qEI,201
|
|
51
51
|
pytbox/feishu/typing.py,sha256=3hWkJgOi-v2bt9viMxkyvNHsPgrbAa0aZOxsZYg2vdM,122
|
|
52
|
-
pytbox/log/logger.py,sha256=
|
|
52
|
+
pytbox/log/logger.py,sha256=tfqRc7VcDyI_U-NiiK4euFe8O2ro9yeXVohPmzAC_hY,8867
|
|
53
53
|
pytbox/log/victorialog.py,sha256=gffEiq38adv9sC5oZeMcyKghd3SGfRuqtZOFuqHQF6E,4139
|
|
54
54
|
pytbox/mail/alimail.py,sha256=njKA3PUbIaiKFaxKvUObmklmEEHg2YA-O5rpgsgT5_w,5147
|
|
55
55
|
pytbox/mail/client.py,sha256=6HeKpChHGjTCYGBgQcfAhWlU_wh9wtO-bjP6TU38pGM,6120
|
|
@@ -63,8 +63,8 @@ pytbox/utils/response.py,sha256=kXjlwt0WVmLRam2eu1shzX2cQ7ux4cCQryaPGYwle5g,1247
|
|
|
63
63
|
pytbox/utils/richutils.py,sha256=OT9_q2Q1bthzB0g1GlhZVvM4ZAepJRKL6a_Vsr6vEqo,487
|
|
64
64
|
pytbox/utils/timeutils.py,sha256=uSKgwt20mVcgIGKLsH2tNum8v3rcpzgmBibPvyPQFgM,20433
|
|
65
65
|
pytbox/win/ad.py,sha256=-3pWfL3dElz-XoO4j4M9lrgu3KJtlhrS9gCWJBpafAU,1147
|
|
66
|
-
pytbox-0.1.
|
|
67
|
-
pytbox-0.1.
|
|
68
|
-
pytbox-0.1.
|
|
69
|
-
pytbox-0.1.
|
|
70
|
-
pytbox-0.1.
|
|
66
|
+
pytbox-0.1.6.dist-info/METADATA,sha256=mxB7SNMpc2yyjOXg9nVuF9DdryE6gDfe54RIoGN4jWI,6319
|
|
67
|
+
pytbox-0.1.6.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
|
68
|
+
pytbox-0.1.6.dist-info/entry_points.txt,sha256=YaTOJ2oPjOiv2SZwY0UC-UA9QS2phRH1oMvxGnxO0Js,43
|
|
69
|
+
pytbox-0.1.6.dist-info/top_level.txt,sha256=YADgWue-Oe128ptN3J2hS3GB0Ncc5uZaSUM3e1rwswE,7
|
|
70
|
+
pytbox-0.1.6.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|