sycommon-python-lib 0.1.55a0__py3-none-any.whl → 0.1.55b0__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.
@@ -114,7 +114,7 @@ class KafkaLogger(metaclass=SingletonMeta):
114
114
  trace_id = None
115
115
 
116
116
  if not trace_id:
117
- trace_id = SYLogger.get_trace_id() or Snowflake.next_id()
117
+ trace_id = SYLogger.get_trace_id() or Snowflake.id
118
118
 
119
119
  # 获取线程/协程信息
120
120
  thread_info = SYLogger._get_execution_context()
@@ -173,7 +173,7 @@ class KafkaLogger(metaclass=SingletonMeta):
173
173
  "className": "",
174
174
  "sqlCost": 0,
175
175
  "size": len(str(message)),
176
- "uid": int(Snowflake.next_id()) # 独立新的id
176
+ "uid": int(Snowflake.id) # 独立新的id
177
177
  }
178
178
 
179
179
  # 智能队列管理
@@ -212,7 +212,7 @@ class KafkaLogger(metaclass=SingletonMeta):
212
212
  return
213
213
 
214
214
  # 获取当前的trace_id
215
- trace_id = SYLogger.get_trace_id() or Snowflake.next_id()
215
+ trace_id = SYLogger.get_trace_id() or Snowflake.id
216
216
 
217
217
  # 构建错误日志
218
218
  error_log = {
@@ -459,7 +459,7 @@ class SYLogger:
459
459
 
460
460
  @staticmethod
461
461
  def _log(msg: any, level: str = "INFO"):
462
- trace_id = SYLogger.get_trace_id() or Snowflake.next_id()
462
+ trace_id = SYLogger.get_trace_id() or Snowflake.id
463
463
 
464
464
  if isinstance(msg, dict) or isinstance(msg, list):
465
465
  msg_str = json.dumps(msg, ensure_ascii=False)
@@ -473,7 +473,7 @@ class SYLogger:
473
473
  request_log = {}
474
474
  if level == "ERROR":
475
475
  request_log = {
476
- "trace_id": str(trace_id) if trace_id else Snowflake.next_id(),
476
+ "trace_id": str(trace_id) if trace_id else Snowflake.id,
477
477
  "message": msg_str,
478
478
  "traceback": traceback.format_exc(),
479
479
  "level": level,
@@ -481,7 +481,7 @@ class SYLogger:
481
481
  }
482
482
  else:
483
483
  request_log = {
484
- "trace_id": str(trace_id) if trace_id else Snowflake.next_id(),
484
+ "trace_id": str(trace_id) if trace_id else Snowflake.id,
485
485
  "message": msg_str,
486
486
  "level": level,
487
487
  "threadName": thread_info
@@ -521,7 +521,7 @@ class SYLogger:
521
521
  @staticmethod
522
522
  def exception(msg: any, *args, **kwargs):
523
523
  """记录异常信息,包括完整堆栈"""
524
- trace_id = SYLogger.get_trace_id() or Snowflake.next_id()
524
+ trace_id = SYLogger.get_trace_id() or Snowflake.id
525
525
 
526
526
  if isinstance(msg, dict) or isinstance(msg, list):
527
527
  msg_str = json.dumps(msg, ensure_ascii=False)
@@ -533,7 +533,7 @@ class SYLogger:
533
533
 
534
534
  # 构建包含异常堆栈的日志
535
535
  request_log = {
536
- "trace_id": str(trace_id) if trace_id else Snowflake.next_id(),
536
+ "trace_id": str(trace_id) if trace_id else Snowflake.id,
537
537
  "message": msg_str,
538
538
  "level": "ERROR",
539
539
  "threadName": thread_info
@@ -12,7 +12,7 @@ def setup_trace_id_handler(app):
12
12
  # 生成或获取 traceId
13
13
  trace_id = request.headers.get("x-traceId-header")
14
14
  if not trace_id:
15
- trace_id = Snowflake.next_id()
15
+ trace_id = Snowflake.id
16
16
 
17
17
  # 设置 trace_id 上下文
18
18
  token = SYLogger.set_trace_id(trace_id)
@@ -101,9 +101,11 @@ def setup_trace_id_handler(app):
101
101
  if "application/json" in content_type and not content_disposition.startswith("attachment"):
102
102
  try:
103
103
  data = json.loads(response_body)
104
- data["traceId"] = trace_id
105
- new_body = json.dumps(
106
- data, ensure_ascii=False).encode()
104
+ new_body = response_body
105
+ if data:
106
+ data["traceId"] = trace_id
107
+ new_body = json.dumps(
108
+ data, ensure_ascii=False).encode()
107
109
 
108
110
  # 创建新响应,确保Content-Length正确
109
111
  response = Response(
sycommon/synacos/feign.py CHANGED
@@ -25,7 +25,7 @@ async def feign(service_name, api_path, method='GET', params=None, headers=None,
25
25
  # 初始化headers,确保是可修改的字典
26
26
  headers = headers.copy() if headers else {}
27
27
  if "x-traceId-header" not in headers:
28
- headers["x-traceId-header"] = SYLogger.get_trace_id() or Snowflake.next_id()
28
+ headers["x-traceId-header"] = SYLogger.get_trace_id() or Snowflake.id
29
29
 
30
30
  # 处理JSON请求的Content-Type
31
31
  is_json_request = method.upper() in ["POST", "PUT", "PATCH"] and not (
@@ -28,7 +28,7 @@ def feign_client(
28
28
  default_headers: Optional[Dict[str, str]] = None
29
29
  ):
30
30
  default_headers = default_headers or {}
31
- default_headers["x-traceId-header"] = SYLogger.get_trace_id() or Snowflake.next_id()
31
+ default_headers["x-traceId-header"] = SYLogger.get_trace_id() or Snowflake.id
32
32
 
33
33
  def decorator(cls):
34
34
  class FeignClient:
@@ -155,7 +155,7 @@ def feign_client(
155
155
  def _build_headers(self, param_meta: Dict[str, Param], bound_args: Dict[str, Any], method_headers: Dict[str, str]) -> Dict[str, str]:
156
156
  headers = self.default_headers.copy()
157
157
  headers.update(method_headers)
158
- headers["x-traceId-header"] = SYLogger.get_trace_id() or Snowflake.next_id()
158
+ headers["x-traceId-header"] = SYLogger.get_trace_id() or Snowflake.id
159
159
  for name, meta in param_meta.items():
160
160
  if isinstance(meta, Header) and name in bound_args:
161
161
  value = bound_args[name]
@@ -3,11 +3,25 @@ import threading
3
3
  import socket
4
4
  import hashlib
5
5
  import random
6
- from typing import Optional
6
+ from typing import Optional, Type, Any
7
7
  from os import environ
8
8
  import netifaces
9
9
 
10
10
 
11
+ class ClassProperty:
12
+ """
13
+ 自定义类属性描述符,替代 @classmethod + @property 的废弃写法
14
+ 支持通过 类.属性 的方式访问,无需实例化
15
+ """
16
+
17
+ def __init__(self, func):
18
+ self.func = func
19
+
20
+ def __get__(self, instance: Any, cls: Type) -> str:
21
+ # 调用传入的函数,并传入类本身作为第一个参数
22
+ return self.func(cls)
23
+
24
+
11
25
  class Snowflake:
12
26
  """雪花算法生成器(无公网依赖,适配内网环境)"""
13
27
  START_TIMESTAMP = 1388534400000 # 2014-01-01 00:00:00
@@ -59,23 +73,16 @@ class Snowflake:
59
73
  local_ip = self._get_local_internal_ip()
60
74
  if local_ip:
61
75
  return self._hash_to_machine_id(local_ip)
62
- else:
63
- # logger.warning("读取网卡信息成功,但未找到非回环内网IP")
64
- pass
65
- except Exception as e:
66
- # logger.warning(f"读取本机网卡IP失败: {e},尝试使用主机名")
76
+ except Exception:
67
77
  pass
68
78
 
69
79
  # 4. 兜底2:获取容器主机名(K8s中默认等于Pod名称,保证唯一)
70
80
  hostname = socket.gethostname()
71
81
  if hostname:
72
- # logger.info(
73
- # f"未读取到POD_NAME/POD_IP/内网IP,使用主机名: {hostname}生成machine_id")
74
82
  return self._hash_to_machine_id(hostname)
75
83
 
76
- # 5. 最终兜底:生成随机数(仅极端情况使用,日志告警)
84
+ # 5. 最终兜底:生成随机数(仅极端情况使用)
77
85
  random_id = random.randint(0, self.MAX_MACHINE_ID)
78
- # logger.warning(f"所有方式均失败,使用随机数生成machine_id: {random_id}(可能重复!)")
79
86
  return random_id
80
87
 
81
88
  def _get_local_internal_ip(self) -> Optional[str]:
@@ -92,15 +99,12 @@ class Snowflake:
92
99
  if netifaces.AF_INET in addrs:
93
100
  for addr in addrs[netifaces.AF_INET]:
94
101
  ip = addr.get('addr')
95
- # 过滤回环地址(127.0.0.1)和docker虚拟地址(172.17.0.0/16可选过滤)
102
+ # 过滤回环地址(127.0.0.1
96
103
  if ip and not ip.startswith('127.'):
97
- # 可选:过滤docker0的默认地址段(根据实际内网段调整)
98
- # if not ip.startswith('172.17.'):
99
104
  return ip
100
105
  return None
101
106
  except ImportError:
102
- # 若未安装netifaces,降级为socket方式(仅尝试本地解析,无公网连接)
103
- # logger.warning("未安装netifaces库,尝试降级方式获取IP")
107
+ # 若未安装netifaces,降级为socket方式
104
108
  return self._get_local_ip_fallback()
105
109
 
106
110
  def _get_local_ip_fallback(self) -> Optional[str]:
@@ -110,7 +114,6 @@ class Snowflake:
110
114
  try:
111
115
  # 创建socket但不连接任何地址,仅绑定到本地
112
116
  s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
113
- # 绑定到0.0.0.0:0(仅用于获取本机IP,不发送数据)
114
117
  s.bind(('', 0))
115
118
  local_ip = s.getsockname()[0]
116
119
  s.close()
@@ -194,28 +197,39 @@ class Snowflake:
194
197
  # 生成ID并转为字符串返回
195
198
  return str(cls._instance.generate_id())
196
199
 
200
+ @ClassProperty
201
+ def id(cls) -> str:
202
+ """
203
+ 直接通过 `Snowflake.id` 属性生成雪花ID(兼容Python 3.11+)
204
+ :return: 雪花ID字符串
205
+ """
206
+ return cls.next_id()
207
+
197
208
 
198
209
  if __name__ == "__main__":
199
- # 生成1000个ID并验证
200
- id_set = set() # 用于检测重复ID
210
+ print("=== 兼容Python 3.11+的属性方式生成雪花ID ===")
211
+ # 直接访问 Snowflake.id 即可生成,无废弃警告
212
+ id1 = Snowflake.id
213
+ id2 = Snowflake.id
214
+ id3 = Snowflake.id
215
+ print(f"生成ID1: {id1}")
216
+ print(f"生成ID2: {id2}")
217
+ print(f"生成ID3: {id3}")
218
+ print(f"ID是否唯一: {len({id1, id2, id3}) == 3}")
219
+
220
+ # 原有方式仍可正常使用
221
+ print("\n=== 原有方法方式生成 ===")
222
+ id4 = Snowflake.next_id()
223
+ print(f"生成ID4: {id4}")
224
+
225
+ # 批量验证(1000个唯一ID)
226
+ id_set = set()
201
227
  _MAX_JAVA_LONG = 9223372036854775807
202
-
203
228
  for i in range(1000):
204
- id_str = Snowflake.next_id()
205
- id_num = int(id_str)
206
-
207
- # 验证ID不超过Java long最大值
229
+ snow_id = Snowflake.id # 全程使用兼容版属性方式
230
+ id_num = int(snow_id)
208
231
  assert id_num <= _MAX_JAVA_LONG, f"ID超过Java long最大值: {id_num}"
232
+ assert snow_id not in id_set, f"重复生成ID: {snow_id}"
233
+ id_set.add(snow_id)
209
234
 
210
- # 验证ID不重复
211
- assert id_str not in id_set, f"重复生成ID: {id_str}"
212
- id_set.add(id_str)
213
-
214
- # 每100个ID打印一次解析结果
215
- if i % 100 == 0:
216
- parse_result = Snowflake.parse_id(id_num)
217
- print(f"生成ID: {id_str}")
218
- print(f"解析结果: {parse_result}")
219
- print("-" * 50)
220
-
221
- print(f"成功生成{len(id_set)}个唯一雪花ID,验证通过!")
235
+ print(f"\n成功生成{len(id_set)}个唯一雪花ID,兼容版属性访问方式验证通过!")
@@ -1,25 +1,24 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: sycommon-python-lib
3
- Version: 0.1.55a0
3
+ Version: 0.1.55b0
4
4
  Summary: Add your description here
5
5
  Requires-Python: >=3.10
6
6
  Description-Content-Type: text/markdown
7
7
  Requires-Dist: aio-pika>=9.5.8
8
8
  Requires-Dist: aiohttp>=3.13.2
9
9
  Requires-Dist: decorator>=5.2.1
10
- Requires-Dist: fastapi>=0.121.2
11
- Requires-Dist: kafka-python>=2.2.16
10
+ Requires-Dist: fastapi>=0.127.0
11
+ Requires-Dist: kafka-python>=2.3.0
12
12
  Requires-Dist: loguru>=0.7.3
13
13
  Requires-Dist: mysql-connector-python>=9.5.0
14
14
  Requires-Dist: nacos-sdk-python<3.0,>=2.0.9
15
15
  Requires-Dist: netifaces>=0.11.0
16
- Requires-Dist: pydantic>=2.12.4
16
+ Requires-Dist: pydantic>=2.12.5
17
17
  Requires-Dist: python-dotenv>=1.2.1
18
18
  Requires-Dist: pyyaml>=6.0.3
19
- Requires-Dist: sqlalchemy>=2.0.44
20
- Requires-Dist: starlette>=0.49.3
21
- Requires-Dist: uuid>=1.30
22
- Requires-Dist: uvicorn>=0.38.0
19
+ Requires-Dist: sqlalchemy>=2.0.45
20
+ Requires-Dist: starlette>=0.50.0
21
+ Requires-Dist: uvicorn>=0.40.0
23
22
 
24
23
  # sycommon-python-lib
25
24
 
@@ -15,7 +15,7 @@ sycommon/health/health_check.py,sha256=EhfbhspRpQiKJaxdtE-PzpKQO_ucaFKtQxIm16F5M
15
15
  sycommon/health/metrics.py,sha256=fHqO73JuhoZkNPR-xIlxieXiTCvttq-kG-tvxag1s1s,268
16
16
  sycommon/health/ping.py,sha256=FTlnIKk5y1mPfS1ZGOeT5IM_2udF5aqVLubEtuBp18M,250
17
17
  sycommon/logging/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
18
- sycommon/logging/kafka_log.py,sha256=Ctjpch9clULhRcSKFVlAjXDmEZ63KVHqch4xzXAQZdQ,21174
18
+ sycommon/logging/kafka_log.py,sha256=viqJ2hDqnyX5eUKkhIhU__kytIwe6nLuHIAFGcaRpUI,21118
19
19
  sycommon/logging/logger_wrapper.py,sha256=TiHsrIIHiQMzXgXK12-0KIpU9GhwQJOoHslakzmq2zc,357
20
20
  sycommon/logging/sql_logger.py,sha256=aEU3OGnI_51Tjyuuf4FpUi9KPTceFRuKAOyQbPzGhzM,2021
21
21
  sycommon/middleware/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
@@ -27,7 +27,7 @@ sycommon/middleware/middleware.py,sha256=SzZ4wufSNdwC4Ppw99TE7a6AVGkrZRc55NHSrA3
27
27
  sycommon/middleware/monitor_memory.py,sha256=pYRK-wRuDd6enSg9Pf8tQxPdYQS6S0AyjyXeKFRLKEs,628
28
28
  sycommon/middleware/mq.py,sha256=4wBqiT5wJGcrfjk2GSr0_U3TStBxoNpHTzcRxVlMEHE,183
29
29
  sycommon/middleware/timeout.py,sha256=fImlAPLm4Oa8N9goXtT_0os1GZPCi9F92OgXU81DgDU,656
30
- sycommon/middleware/traceid.py,sha256=ugqPgHdUydj7m481rM_RH-yrIK9hAdkLemdPSSOnQvw,6821
30
+ sycommon/middleware/traceid.py,sha256=FLZTxVAIboZvqK_S69eReeIzZGUDIVy6KTA1kZBoRyI,6908
31
31
  sycommon/models/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
32
32
  sycommon/models/base_http.py,sha256=EICAAibx3xhjBsLqm35Mi3DCqxp0FME4rD_3iQVjT_E,3051
33
33
  sycommon/models/log.py,sha256=rZpj6VkDRxK3B6H7XSeWdYZshU8F0Sks8bq1p6pPlDw,500
@@ -44,16 +44,16 @@ sycommon/sse/sse.py,sha256=__CfWEcYxOxQ-HpLor4LTZ5hLWqw9-2X7CngqbVHsfw,10128
44
44
  sycommon/synacos/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
45
45
  sycommon/synacos/example.py,sha256=61XL03tU8WTNOo3FUduf93F2fAwah1S0lbH1ufhRhRk,5739
46
46
  sycommon/synacos/example2.py,sha256=adUaru3Hy482KrOA17DfaC4nwvLj8etIDS_KrWLWmCU,4811
47
- sycommon/synacos/feign.py,sha256=U7RJFV8qPgWyFDpeIgmYpYnpXPrWj01kkigDf1k8sBY,8023
48
- sycommon/synacos/feign_client.py,sha256=qEJNQFX5irDnD6VwN79im42h9FKzoELPmdEAXzgwPT0,15435
47
+ sycommon/synacos/feign.py,sha256=xvyH_1no6gsggO3YYB0_88NWNA26odbQ_G-2MjApif0,8016
48
+ sycommon/synacos/feign_client.py,sha256=PYjTrnqMc_Jl6Wnpiz8-PFozCjPk6VGnPWv29JefL14,15421
49
49
  sycommon/synacos/nacos_service.py,sha256=tyh_JOjjoCGiKCr1xfU7MAmu7dDQCZmTzmYsSqNjiQY,35465
50
50
  sycommon/synacos/param.py,sha256=KcfSkxnXOa0TGmCjY8hdzU9pzUsA8-4PeyBKWI2-568,1765
51
51
  sycommon/tools/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
52
52
  sycommon/tools/docs.py,sha256=OPj2ETheuWjXLyaXtaZPbwmJKfJaYXV5s4XMVAUNrms,1607
53
- sycommon/tools/snowflake.py,sha256=S3KWKFUKhgZ9QnzLvvaGTt2MavF9RvjDQqeUM99u6Kk,8589
53
+ sycommon/tools/snowflake.py,sha256=wSATJzWGb6HcaZ1u_fdzF6I5seRviQQm2KS3Jf45nm4,8520
54
54
  sycommon/tools/timing.py,sha256=OiiE7P07lRoMzX9kzb8sZU9cDb0zNnqIlY5pWqHcnkY,2064
55
- sycommon_python_lib-0.1.55a0.dist-info/METADATA,sha256=hlbD-d9IAS0lnH_ZdWhyA3c0ewXabuEFjcxeFetwBJw,7077
56
- sycommon_python_lib-0.1.55a0.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
57
- sycommon_python_lib-0.1.55a0.dist-info/entry_points.txt,sha256=q_h2nbvhhmdnsOUZEIwpuoDjaNfBF9XqppDEmQn9d_A,46
58
- sycommon_python_lib-0.1.55a0.dist-info/top_level.txt,sha256=98CJ-cyM2WIKxLz-Pf0AitWLhJyrfXvyY8slwjTXNuc,17
59
- sycommon_python_lib-0.1.55a0.dist-info/RECORD,,
55
+ sycommon_python_lib-0.1.55b0.dist-info/METADATA,sha256=9K3VD62twbBtlxjoty9K0h96O74lp2NFfqtviimdqGM,7050
56
+ sycommon_python_lib-0.1.55b0.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
57
+ sycommon_python_lib-0.1.55b0.dist-info/entry_points.txt,sha256=q_h2nbvhhmdnsOUZEIwpuoDjaNfBF9XqppDEmQn9d_A,46
58
+ sycommon_python_lib-0.1.55b0.dist-info/top_level.txt,sha256=98CJ-cyM2WIKxLz-Pf0AitWLhJyrfXvyY8slwjTXNuc,17
59
+ sycommon_python_lib-0.1.55b0.dist-info/RECORD,,