mdbq 4.1.2__py3-none-any.whl → 4.1.4__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 mdbq might be problematic. Click here for more details.

mdbq/route/monitor.py CHANGED
@@ -21,7 +21,7 @@ from typing import Dict, Any
21
21
  from urllib.parse import urlparse
22
22
  from dbutils.pooled_db import PooledDB # type: ignore
23
23
  from mdbq.myconf import myconf # type: ignore
24
- from mdbq.log import mylogger
24
+ # from mdbq.log import mylogger
25
25
  from flask import request, g
26
26
  import re
27
27
  import ipaddress
@@ -33,17 +33,17 @@ host, port, username, password = parser.get_section_values(
33
33
  keys=['host', 'port', 'username', 'password'],
34
34
  )
35
35
 
36
- logger = mylogger.MyLogger(
37
- logging_mode='file',
38
- log_level='info',
39
- log_format='json',
40
- max_log_size=50,
41
- backup_count=5,
42
- enable_async=False, # 是否启用异步日志
43
- sample_rate=1, # 采样DEBUG/INFO日志
44
- sensitive_fields=[], # 敏感字段过滤
45
- enable_metrics=False, # 是否启用性能指标
46
- )
36
+ # logger = mylogger.MyLogger(
37
+ # logging_mode='file',
38
+ # log_level='info',
39
+ # log_format='json',
40
+ # max_log_size=50,
41
+ # backup_count=5,
42
+ # enable_async=False, # 是否启用异步日志
43
+ # sample_rate=1, # 采样DEBUG/INFO日志
44
+ # sensitive_fields=[], # 敏感字段过滤
45
+ # enable_metrics=False, # 是否启用性能指标
46
+ # )
47
47
 
48
48
 
49
49
  class RouteMonitor:
@@ -83,10 +83,10 @@ class RouteMonitor:
83
83
  connection.close()
84
84
 
85
85
  except Exception as e:
86
- logger.error("数据库连接池初始化失败", {
87
- "错误信息": str(e),
88
- "数据库": self.database
89
- })
86
+ # logger.error("数据库连接池初始化失败", {
87
+ # "错误信息": str(e),
88
+ # "数据库": self.database
89
+ # })
90
90
  raise
91
91
 
92
92
  def ensure_database_context(self, cursor):
@@ -94,22 +94,16 @@ class RouteMonitor:
94
94
  try:
95
95
  cursor.execute(f"USE `{self.database}`")
96
96
  except Exception as e:
97
- logger.warning("切换数据库上下文失败,尝试重新创建", {
98
- "数据库": self.database,
99
- "错误": str(e)
100
- })
97
+ # logger.warning("切换数据库上下文失败,尝试重新创建", {
98
+ # "数据库": self.database,
99
+ # "错误": str(e)
100
+ # })
101
101
  cursor.execute(f"CREATE DATABASE IF NOT EXISTS `{self.database}` DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci")
102
102
  cursor.execute(f"USE `{self.database}`")
103
103
 
104
104
  def init_database_tables(self):
105
105
  """初始化数据库表结构"""
106
106
  try:
107
- logger.debug("🗄️ 开始创建/验证数据库表结构", {
108
- "操作": "表结构初始化",
109
- "预期表数": 4,
110
- "数据库": self.database
111
- })
112
-
113
107
  connection = self.pool.connection()
114
108
  try:
115
109
  with connection.cursor() as cursor:
@@ -244,23 +238,17 @@ class RouteMonitor:
244
238
  COMMENT='系统性能统计表';
245
239
  """)
246
240
  connection.commit()
247
- logger.debug("🎯 所有数据库表结构初始化完成", {
248
- "创建表数": 4,
249
- "操作状态": "成功",
250
- "数据库": self.database,
251
- "数据库引擎": "InnoDB"
252
- })
253
241
 
254
242
  finally:
255
243
  connection.close()
256
244
 
257
245
  except Exception as e:
258
- logger.error("数据库表结构初始化失败", {
259
- "错误信息": str(e),
260
- "错误类型": type(e).__name__,
261
- "数据库": self.database,
262
- "影响": "监控系统可能无法正常工作"
263
- })
246
+ # logger.error("数据库表结构初始化失败", {
247
+ # "错误信息": str(e),
248
+ # "错误类型": type(e).__name__,
249
+ # "数据库": self.database,
250
+ # "影响": "监控系统可能无法正常工作"
251
+ # })
264
252
  # 静默处理初始化错误,避免影响主应用
265
253
  pass
266
254
 
@@ -434,25 +422,9 @@ class RouteMonitor:
434
422
 
435
423
  # 设置请求ID到全局变量中,供后续使用
436
424
  g.request_id = request_id
437
-
438
- logger.debug("📋 开始收集请求数据", {
439
- "请求ID": request_id,
440
- "请求方法": request.method,
441
- "端点": request.endpoint or request.path,
442
- "客户端IP": request.remote_addr
443
- })
444
-
445
425
  # 获取真实IP
446
426
  real_ip, forwarded_ips = self.get_real_ip(request)
447
427
 
448
- if real_ip != request.remote_addr:
449
- logger.debug("🔍 检测到IP转发", {
450
- "请求ID": request_id,
451
- "原始IP": request.remote_addr,
452
- "真实IP": real_ip,
453
- "转发链长度": len(forwarded_ips) if forwarded_ips else 0
454
- })
455
-
456
428
  # 获取请求头信息
457
429
  headers = dict(request.headers)
458
430
  sanitized_headers = self.sanitize_data(headers)
@@ -479,25 +451,15 @@ class RouteMonitor:
479
451
  request_body = body_data.decode('utf-8')
480
452
  except UnicodeDecodeError:
481
453
  request_body = f"[BINARY_DATA:{len(body_data)}_bytes]"
482
- logger.debug("📁 检测到二进制数据", {
483
- "请求ID": request_id,
484
- "数据大小": len(body_data),
485
- "处理方式": "标记为二进制"
486
- })
487
454
 
488
455
  if request_body:
489
456
  request_size = len(str(request_body).encode('utf-8'))
490
- logger.debug("📊 请求体信息", {
491
- "请求ID": request_id,
492
- "数据类型": "JSON" if request.is_json else "表单" if request.form else "文本",
493
- "大小": f"{request_size} bytes"
494
- })
495
457
  except Exception as e:
496
458
  request_body = "[ERROR_READING_BODY]"
497
- logger.warning("⚠️ 读取请求体失败", {
498
- "请求ID": request_id,
499
- "错误": str(e)
500
- })
459
+ # logger.warning("读取请求体失败", {
460
+ # "请求ID": request_id,
461
+ # "错误": str(e)
462
+ # })
501
463
 
502
464
  # 清理敏感数据
503
465
  sanitized_body = self.sanitize_data(request_body)
@@ -506,21 +468,6 @@ class RouteMonitor:
506
468
  # 设备信息提取
507
469
  user_agent = request.headers.get('User-Agent', '')
508
470
  device_info = self.extract_device_info(user_agent)
509
-
510
- if device_info['is_bot']:
511
- logger.debug("🤖 检测到机器人请求", {
512
- "请求ID": request_id,
513
- "用户代理": user_agent[:100] + "..." if len(user_agent) > 100 else user_agent,
514
- "IP": real_ip
515
- })
516
-
517
- if device_info['is_mobile']:
518
- logger.debug("📱 检测到移动设备请求", {
519
- "请求ID": request_id,
520
- "操作系统": device_info['os_name'],
521
- "浏览器": device_info['browser_name']
522
- })
523
-
524
471
  # URL解析
525
472
  parsed_url = urlparse(request.url)
526
473
 
@@ -559,14 +506,6 @@ class RouteMonitor:
559
506
  'os_version': device_info['os_version'],
560
507
  }
561
508
 
562
- logger.debug("✅ 请求数据收集完成", {
563
- "请求ID": request_id,
564
- "数据字段数": len(request_data),
565
- "请求大小": f"{request_size} bytes",
566
- "设备类型": "移动" if device_info['is_mobile'] else "桌面",
567
- "是否机器人": device_info['is_bot']
568
- })
569
-
570
509
  return request_data
571
510
 
572
511
  def mask_token(self, token: str) -> str:
@@ -591,13 +530,6 @@ class RouteMonitor:
591
530
  if response_data:
592
531
  request_data.update(response_data)
593
532
 
594
- logger.debug("💾 保存请求日志到数据库", {
595
- "请求ID": request_id,
596
- "端点": request_data.get('endpoint', ''),
597
- "状态码": request_data.get('response_status', '未知'),
598
- "处理时间": f"{request_data.get('process_time', 0)}ms"
599
- })
600
-
601
533
  connection = self.pool.connection()
602
534
  try:
603
535
  with connection.cursor() as cursor:
@@ -616,39 +548,26 @@ class RouteMonitor:
616
548
  cursor.execute(sql, list(request_data.values()))
617
549
  connection.commit()
618
550
 
619
- logger.debug("✅ 请求日志保存成功", {
620
- "请求ID": request_id,
621
- "写入状态": "成功",
622
- "数据库表": "api_request_logs"
623
- })
624
-
625
551
  finally:
626
552
  connection.close()
627
553
 
628
554
  except Exception as e:
629
- logger.error("保存请求日志失败", {
630
- "请求ID": request_id,
631
- "错误信息": str(e),
632
- "错误类型": type(e).__name__,
633
- "影响": "日志丢失,但不影响主业务"
634
- })
555
+ # logger.error("保存请求日志失败", {
556
+ # "请求ID": request_id,
557
+ # "错误信息": str(e),
558
+ # "错误类型": type(e).__name__,
559
+ # "影响": "日志丢失,但不影响主业务"
560
+ # })
635
561
  # 静默处理错误,不影响主业务
636
562
  pass
637
563
 
638
564
  def update_statistics(self, request_data: Dict[str, Any]):
639
565
  """更新统计数据"""
640
566
  request_id = request_data.get('request_id', 'unknown')
641
- endpoint = request_data.get('endpoint', '')
642
- status_code = request_data.get('response_status', 500)
567
+ # endpoint = request_data.get('endpoint', '')
568
+ # status_code = request_data.get('response_status', 500)
643
569
 
644
570
  try:
645
- logger.debug("📈 更新统计数据", {
646
- "请求ID": request_id,
647
- "端点": endpoint,
648
- "状态码": status_code,
649
- "统计类型": "API访问统计和IP统计"
650
- })
651
-
652
571
  connection = self.pool.connection()
653
572
  try:
654
573
  with connection.cursor() as cursor:
@@ -705,23 +624,16 @@ class RouteMonitor:
705
624
 
706
625
  connection.commit()
707
626
 
708
- logger.debug("✅ 统计数据更新成功", {
709
- "请求ID": request_id,
710
- "更新表": "api_access_statistics, ip_access_statistics",
711
- "日期": str(date),
712
- "小时": hour
713
- })
714
-
715
627
  finally:
716
628
  connection.close()
717
629
 
718
630
  except Exception as e:
719
- logger.error("更新统计数据失败", {
720
- "请求ID": request_id,
721
- "错误信息": str(e),
722
- "错误类型": type(e).__name__,
723
- "影响": "统计数据缺失,但不影响主业务"
724
- })
631
+ # logger.error("更新统计数据失败", {
632
+ # "请求ID": request_id,
633
+ # "错误信息": str(e),
634
+ # "错误类型": type(e).__name__,
635
+ # "影响": "统计数据缺失,但不影响主业务"
636
+ # })
725
637
  # 静默处理错误
726
638
  pass
727
639
 
@@ -737,14 +649,6 @@ class RouteMonitor:
737
649
  request_data = self.collect_request_data(request)
738
650
  request_id = request_data.get('request_id', 'unknown')
739
651
 
740
- logger.debug("🎯 开始监控请求", {
741
- "请求ID": request_id,
742
- "函数名": func.__name__,
743
- "端点": request_data.get('endpoint', ''),
744
- "方法": request_data.get('method', ''),
745
- "来源IP": request_data.get('real_ip', request_data.get('client_ip'))
746
- })
747
-
748
652
  try:
749
653
  # 执行原函数
750
654
  response = func(*args, **kwargs)
@@ -774,16 +678,6 @@ class RouteMonitor:
774
678
  'process_time': process_time,
775
679
  'response_size': response_size
776
680
  }
777
-
778
- logger.debug("✅ 请求处理完成", {
779
- "请求ID": request_id,
780
- "函数名": func.__name__,
781
- "状态码": response_status,
782
- "处理时间": f"{process_time}ms",
783
- "响应大小": f"{response_size} bytes",
784
- "结果": "成功"
785
- })
786
-
787
681
  # 保存日志
788
682
  self.save_request_log(request_data, response_data)
789
683
 
@@ -805,14 +699,14 @@ class RouteMonitor:
805
699
  'response_size': 0
806
700
  }
807
701
 
808
- logger.error("请求处理异常", {
809
- "请求ID": request_id,
810
- "函数名": func.__name__,
811
- "错误信息": str(e),
812
- "错误类型": type(e).__name__,
813
- "处理时间": f"{process_time}ms",
814
- "结果": "异常"
815
- })
702
+ # logger.error("请求处理异常", {
703
+ # "请求ID": request_id,
704
+ # "函数名": func.__name__,
705
+ # "错误信息": str(e),
706
+ # "错误类型": type(e).__name__,
707
+ # "处理时间": f"{process_time}ms",
708
+ # "结果": "异常"
709
+ # })
816
710
 
817
711
  # 保存错误日志
818
712
  self.save_request_log(request_data, error_data)
@@ -829,11 +723,6 @@ class RouteMonitor:
829
723
  def get_statistics_summary(self, days: int = 7) -> Dict[str, Any]:
830
724
  """获取统计摘要"""
831
725
  try:
832
- logger.debug("📊 开始获取统计摘要", {
833
- "查询天数": days,
834
- "操作": "统计数据查询"
835
- })
836
-
837
726
  connection = self.pool.connection()
838
727
  try:
839
728
  with connection.cursor() as cursor:
@@ -843,12 +732,6 @@ class RouteMonitor:
843
732
  end_date = datetime.now().date()
844
733
  start_date = end_date - timedelta(days=days)
845
734
 
846
- logger.debug("📅 统计查询时间范围", {
847
- "开始日期": str(start_date),
848
- "结束日期": str(end_date),
849
- "查询天数": days
850
- })
851
-
852
735
  # 总体统计
853
736
  cursor.execute("""
854
737
  SELECT
@@ -862,15 +745,6 @@ class RouteMonitor:
862
745
  """, (start_date, end_date))
863
746
 
864
747
  summary = cursor.fetchone() or {}
865
-
866
- logger.debug("📈 总体统计查询完成", {
867
- "总请求数": summary.get('total_requests', 0) or 0,
868
- "成功请求数": summary.get('success_requests', 0) or 0,
869
- "错误请求数": summary.get('error_requests', 0) or 0,
870
- "平均响应时间": f"{(summary.get('avg_response_time', 0) or 0):.2f}ms",
871
- "唯一端点数": summary.get('unique_endpoints', 0) or 0
872
- })
873
-
874
748
  # 热门端点
875
749
  cursor.execute("""
876
750
  SELECT endpoint, SUM(total_requests) as requests
@@ -883,12 +757,6 @@ class RouteMonitor:
883
757
 
884
758
  top_endpoints = cursor.fetchall()
885
759
 
886
- logger.debug("🔥 热门端点查询完成", {
887
- "查询结果数": len(top_endpoints),
888
- "最热门端点": top_endpoints[0]['endpoint'] if top_endpoints else "无数据",
889
- "最高请求数": top_endpoints[0]['requests'] if top_endpoints else 0
890
- })
891
-
892
760
  # 活跃IP统计
893
761
  cursor.execute("""
894
762
  SELECT COUNT(DISTINCT ip_address) as unique_ips,
@@ -899,11 +767,6 @@ class RouteMonitor:
899
767
 
900
768
  ip_stats = cursor.fetchone() or {}
901
769
 
902
- logger.debug("🌐 IP统计查询完成", {
903
- "唯一IP数": ip_stats.get('unique_ips', 0),
904
- "IP总请求数": ip_stats.get('total_ip_requests', 0)
905
- })
906
-
907
770
  result = {
908
771
  'period': f'{start_date} to {end_date}',
909
772
  'summary': summary,
@@ -911,24 +774,18 @@ class RouteMonitor:
911
774
  'ip_statistics': ip_stats
912
775
  }
913
776
 
914
- logger.debug("✅ 统计摘要获取成功", {
915
- "查询天数": days,
916
- "数据完整性": "完整",
917
- "结果状态": "成功"
918
- })
919
-
920
777
  return result
921
778
 
922
779
  finally:
923
780
  connection.close()
924
781
 
925
782
  except Exception as e:
926
- logger.error("获取统计摘要失败", {
927
- "查询天数": days,
928
- "错误信息": str(e),
929
- "错误类型": type(e).__name__,
930
- "影响": "统计摘要不可用"
931
- })
783
+ # logger.error("获取统计摘要失败", {
784
+ # "查询天数": days,
785
+ # "错误信息": str(e),
786
+ # "错误类型": type(e).__name__,
787
+ # "影响": "统计摘要不可用"
788
+ # })
932
789
  return {'error': str(e)}
933
790
 
934
791
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: mdbq
3
- Version: 4.1.2
3
+ Version: 4.1.4
4
4
  Home-page: https://pypi.org/project/mdbq
5
5
  Author: xigua,
6
6
  Author-email: 2587125111@qq.com
@@ -1,7 +1,7 @@
1
1
  mdbq/__init__.py,sha256=Il5Q9ATdX8yXqVxtP_nYqUhExzxPC_qk_WXQ_4h0exg,16
2
- mdbq/__version__.py,sha256=t0Fz3FVzbu8dTQm35pWtvOg5K2EJnfXWvbSU90YalwU,17
2
+ mdbq/__version__.py,sha256=ZNFR_vu5YnSszK7eMVwk6sv88YcFsQoQV-r-GjB7F3Y,17
3
3
  mdbq/auth/__init__.py,sha256=pnPMAt63sh1B6kEvmutUuro46zVf2v2YDAG7q-jV_To,24
4
- mdbq/auth/auth_backend.py,sha256=u8qwMNjAdDliaaFzfulVqQIoFrIJhe980OdYwTIVKJg,99750
4
+ mdbq/auth/auth_backend.py,sha256=jdoULwfYsvv8YJqp3y62i78wBm42-9HnzaxqTw3J71w,116833
5
5
  mdbq/auth/crypto.py,sha256=fcZRFCnrKVVdWDUx_zds51ynFYwS9DBvJOrRQVldrfM,15931
6
6
  mdbq/auth/rate_limiter.py,sha256=1m_Paxp8pDNpmyoFGRpFMVOJpbmeIvfVcfiQ2oH72qM,32850
7
7
  mdbq/js/__init__.py,sha256=hpMi3_ZKwIWkzc0LnKL-SY9AS-7PYFHq0izYTgEvxjc,30
@@ -9,11 +9,11 @@ mdbq/js/jc.py,sha256=6Rgf1WqaJJ1oevpn-pt08gXKbX5hjoQaV6uZGCAGbYw,13177
9
9
  mdbq/log/__init__.py,sha256=Mpbrav0s0ifLL7lVDAuePEi1hJKiSHhxcv1byBKDl5E,15
10
10
  mdbq/log/mylogger.py,sha256=DyBftCMNLe1pTTXsa830pUtDISJxpJHFIradYtE3lFA,26418
11
11
  mdbq/myconf/__init__.py,sha256=jso1oHcy6cJEfa7udS_9uO5X6kZLoPBF8l3wCYmr5dM,18
12
- mdbq/myconf/myconf.py,sha256=rHvQCnQRKhQ49AZBke-Z4v28hyOLmHt4MylIuB0H6yA,33516
12
+ mdbq/myconf/myconf.py,sha256=x_9mS6wOfKVjCVElbruxj2yjzitbyKiTkf59quG-5Zg,32529
13
13
  mdbq/mysql/__init__.py,sha256=A_DPJyAoEvTSFojiI2e94zP0FKtCkkwKP1kYUCSyQzo,11
14
14
  mdbq/mysql/deduplicator.py,sha256=2fugLyKs_xkvYvoG0C0hRYbJ_w8-4oa1FJ_vavoD7Qo,73084
15
15
  mdbq/mysql/mysql.py,sha256=pDg771xBugCMSTWeskIFTi3pFLgaqgyG3smzf-86Wn8,56772
16
- mdbq/mysql/s_query.py,sha256=nwhyqbxq-V0sGUJbdjiUDEwjpDxiKrzG0PjV6wkrWU4,50474
16
+ mdbq/mysql/s_query.py,sha256=N2xHJf2CiUXjXIVBemdst-wamIP3908EGAJOFG13fCU,50475
17
17
  mdbq/mysql/unique_.py,sha256=MaztT-WIyEQUs-OOYY4pFulgHVcXR1BfCy3QUz0XM_U,21127
18
18
  mdbq/mysql/uploader.py,sha256=FG_4btNwTjbCqZFeIigCfar7r-OOA7VkyuJsOOC9WLw,111539
19
19
  mdbq/other/__init__.py,sha256=jso1oHcy6cJEfa7udS_9uO5X6kZLoPBF8l3wCYmr5dM,18
@@ -26,16 +26,16 @@ mdbq/pbix/__init__.py,sha256=Trtfaynu9RjoTyLLYBN2xdRxTvm_zhCniUkVTAYwcjo,24
26
26
  mdbq/pbix/pbix_refresh.py,sha256=JUjKW3bNEyoMVfVfo77UhguvS5AWkixvVhDbw4_MHco,2396
27
27
  mdbq/pbix/refresh_all.py,sha256=OBT9EewSZ0aRS9vL_FflVn74d4l2G00wzHiikCC4TC0,5926
28
28
  mdbq/redis/__init__.py,sha256=YtgBlVSMDphtpwYX248wGge1x-Ex_mMufz4-8W0XRmA,12
29
- mdbq/redis/getredis.py,sha256=vpBuNc22uj9Vr-_Dh25_wpwWM1e-072EAAIBdB_IpL0,23494
30
- mdbq/redis/redis_cache.py,sha256=2uhAmG9FYHjzByZEg7o8fFFxuF6AnOASVvjdAM4Gx5E,35719
29
+ mdbq/redis/getredis.py,sha256=vdg7YQEjhoMp5QzxygNGx5DQKRnePrcwPYgUrDypA6g,23672
30
+ mdbq/redis/redis_cache.py,sha256=hjl-oh1r0ONdMeWN28cTMsdkcjc7HG71NmGZ9H6jWUE,34559
31
31
  mdbq/route/__init__.py,sha256=BT_dAY7V-U2o72bevq1B9Mq9QA7GodwtkxyLNdGaoE8,22
32
32
  mdbq/route/analytics.py,sha256=dngj5hVwKddEUy59nSYbOoJ9C7OVrtCmCkvW6Uj9RYM,28097
33
- mdbq/route/monitor.py,sha256=8uscuoJF4eMr5o8cAqywQv868m1yIGCuK1l4ZWN6KPE,42954
33
+ mdbq/route/monitor.py,sha256=lyowGUU8c2GykeZLrdxd7nXpNMqXWcOsuQsbS8l0pwU,36595
34
34
  mdbq/route/routes.py,sha256=QVGfTvDgu0CpcKCvk1ra74H8uojgqTLUav1fnVAqLEA,29433
35
35
  mdbq/selenium/__init__.py,sha256=AKzeEceqZyvqn2dEDoJSzDQnbuENkJSHAlbHAD0u0ZI,10
36
36
  mdbq/selenium/get_driver.py,sha256=1NTlVUE6QsyjTrVVVqTO2LOnYf578ccFWlWnvIXGtic,20903
37
37
  mdbq/spider/__init__.py,sha256=RBMFXGy_jd1HXZhngB2T2XTvJqki8P_Fr-pBcwijnew,18
38
- mdbq-4.1.2.dist-info/METADATA,sha256=PsddxgvUrLRPSZGLVd4b64UA19gU-LjiHkK2FV1_OVM,363
39
- mdbq-4.1.2.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
40
- mdbq-4.1.2.dist-info/top_level.txt,sha256=2FQ-uLnCSB-OwFiWntzmwosW3X2Xqsg0ewh1axsaylA,5
41
- mdbq-4.1.2.dist-info/RECORD,,
38
+ mdbq-4.1.4.dist-info/METADATA,sha256=aIvkurYSfu5zyLUo52EximutjyeBzoteIgHxNPBRlc8,363
39
+ mdbq-4.1.4.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
40
+ mdbq-4.1.4.dist-info/top_level.txt,sha256=2FQ-uLnCSB-OwFiWntzmwosW3X2Xqsg0ewh1axsaylA,5
41
+ mdbq-4.1.4.dist-info/RECORD,,
File without changes