sycommon-python-lib 0.1.29__py3-none-any.whl → 0.1.40__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.
- sycommon/models/mqlistener_config.py +1 -0
- sycommon/rabbitmq/rabbitmq_client.py +205 -588
- sycommon/rabbitmq/rabbitmq_pool.py +141 -65
- sycommon/rabbitmq/rabbitmq_service.py +269 -145
- sycommon/services.py +64 -22
- sycommon/synacos/example.py +153 -0
- sycommon/synacos/example2.py +129 -0
- sycommon/synacos/feign.py +51 -436
- sycommon/synacos/feign_client.py +317 -0
- sycommon/synacos/nacos_service.py +1 -1
- sycommon/synacos/param.py +75 -0
- {sycommon_python_lib-0.1.29.dist-info → sycommon_python_lib-0.1.40.dist-info}/METADATA +1 -1
- {sycommon_python_lib-0.1.29.dist-info → sycommon_python_lib-0.1.40.dist-info}/RECORD +16 -12
- {sycommon_python_lib-0.1.29.dist-info → sycommon_python_lib-0.1.40.dist-info}/WHEEL +0 -0
- {sycommon_python_lib-0.1.29.dist-info → sycommon_python_lib-0.1.40.dist-info}/entry_points.txt +0 -0
- {sycommon_python_lib-0.1.29.dist-info → sycommon_python_lib-0.1.40.dist-info}/top_level.txt +0 -0
|
@@ -0,0 +1,317 @@
|
|
|
1
|
+
import io
|
|
2
|
+
import os
|
|
3
|
+
import time
|
|
4
|
+
import inspect
|
|
5
|
+
from typing import Any, Dict, Optional, Literal, Type, TypeVar
|
|
6
|
+
from urllib.parse import urljoin
|
|
7
|
+
|
|
8
|
+
import aiohttp
|
|
9
|
+
from pydantic import BaseModel
|
|
10
|
+
from sycommon.synacos.param import Body, Cookie, File, Form, Header, Param, Path, Query
|
|
11
|
+
from sycommon.logging.kafka_log import SYLogger
|
|
12
|
+
from sycommon.synacos.nacos_service import NacosService
|
|
13
|
+
|
|
14
|
+
# 定义 Pydantic 模型泛型(用于响应解析)
|
|
15
|
+
T = TypeVar('T', bound=BaseModel)
|
|
16
|
+
|
|
17
|
+
# ------------------------------
|
|
18
|
+
# Feign客户端装饰器(支持Pydantic)
|
|
19
|
+
# ------------------------------
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
def feign_client(
|
|
23
|
+
service_name: str,
|
|
24
|
+
path_prefix: str = "",
|
|
25
|
+
default_timeout: Optional[float] = None,
|
|
26
|
+
default_headers: Optional[Dict[str, str]] = None
|
|
27
|
+
):
|
|
28
|
+
default_headers = default_headers or {}
|
|
29
|
+
|
|
30
|
+
def decorator(cls):
|
|
31
|
+
class FeignClient:
|
|
32
|
+
def __init__(self):
|
|
33
|
+
self.service_name = service_name
|
|
34
|
+
self.path_prefix = path_prefix
|
|
35
|
+
self.default_timeout = default_timeout
|
|
36
|
+
self.default_headers = default_headers.copy()
|
|
37
|
+
self.nacos_manager: Optional[NacosService] = None
|
|
38
|
+
self.session: Optional[aiohttp.ClientSession] = None
|
|
39
|
+
|
|
40
|
+
def __getattr__(self, name: str):
|
|
41
|
+
if not hasattr(cls, name):
|
|
42
|
+
raise AttributeError(f"类 {cls.__name__} 不存在方法 {name}")
|
|
43
|
+
|
|
44
|
+
func = getattr(cls, name)
|
|
45
|
+
sig = inspect.signature(func)
|
|
46
|
+
param_meta = self._parse_param_meta(sig)
|
|
47
|
+
# 获取响应模型(从返回类型注解中提取 Pydantic 模型)
|
|
48
|
+
resp_model = self._get_response_model(sig)
|
|
49
|
+
|
|
50
|
+
async def wrapper(*args, **kwargs) -> Any:
|
|
51
|
+
if not self.session:
|
|
52
|
+
self.session = aiohttp.ClientSession()
|
|
53
|
+
if not self.nacos_manager:
|
|
54
|
+
self.nacos_manager = NacosService(None)
|
|
55
|
+
|
|
56
|
+
try:
|
|
57
|
+
bound_args = self._bind_arguments(
|
|
58
|
+
func, sig, args, kwargs)
|
|
59
|
+
self._validate_required_params(param_meta, bound_args)
|
|
60
|
+
|
|
61
|
+
request_meta = getattr(func, "_feign_meta", {})
|
|
62
|
+
method = request_meta.get("method", "GET").upper()
|
|
63
|
+
path = request_meta.get("path", "")
|
|
64
|
+
is_upload = request_meta.get("is_upload", False)
|
|
65
|
+
method_headers = request_meta.get("headers", {})
|
|
66
|
+
timeout = request_meta.get(
|
|
67
|
+
"timeout", self.default_timeout)
|
|
68
|
+
|
|
69
|
+
headers = self._build_headers(
|
|
70
|
+
param_meta, bound_args, method_headers)
|
|
71
|
+
full_path = f"{self.path_prefix}{path}"
|
|
72
|
+
full_path = self._replace_path_params(
|
|
73
|
+
full_path, param_meta, bound_args)
|
|
74
|
+
|
|
75
|
+
base_url = await self._get_service_base_url(headers)
|
|
76
|
+
url = urljoin(base_url, full_path)
|
|
77
|
+
SYLogger.info(f"请求: {method} {url}")
|
|
78
|
+
|
|
79
|
+
query_params = self._get_query_params(
|
|
80
|
+
param_meta, bound_args)
|
|
81
|
+
cookies = self._get_cookies(param_meta, bound_args)
|
|
82
|
+
# 处理请求数据(支持 Pydantic 模型转字典)
|
|
83
|
+
request_data = await self._get_request_data(
|
|
84
|
+
method, param_meta, bound_args, is_upload, method_headers
|
|
85
|
+
)
|
|
86
|
+
|
|
87
|
+
async with self.session.request(
|
|
88
|
+
method=method,
|
|
89
|
+
url=url,
|
|
90
|
+
headers=headers,
|
|
91
|
+
params=query_params,
|
|
92
|
+
cookies=cookies,
|
|
93
|
+
json=request_data if not (is_upload or isinstance(
|
|
94
|
+
request_data, aiohttp.FormData)) else None,
|
|
95
|
+
data=request_data if is_upload or isinstance(
|
|
96
|
+
request_data, aiohttp.FormData) else None,
|
|
97
|
+
timeout=timeout
|
|
98
|
+
) as response:
|
|
99
|
+
# 处理响应(支持 Pydantic 模型解析)
|
|
100
|
+
return await self._handle_response(response, resp_model)
|
|
101
|
+
|
|
102
|
+
finally:
|
|
103
|
+
if self.session:
|
|
104
|
+
await self.session.close()
|
|
105
|
+
self.session = None
|
|
106
|
+
|
|
107
|
+
return wrapper
|
|
108
|
+
|
|
109
|
+
def _parse_param_meta(self, sig: inspect.Signature) -> Dict[str, Param]:
|
|
110
|
+
param_meta = {}
|
|
111
|
+
for param in sig.parameters.values():
|
|
112
|
+
if param.name == "self":
|
|
113
|
+
continue
|
|
114
|
+
if isinstance(param.default, Param):
|
|
115
|
+
param_meta[param.name] = param.default
|
|
116
|
+
else:
|
|
117
|
+
if param.default == inspect.Parameter.empty:
|
|
118
|
+
param_meta[param.name] = Query(..., description="")
|
|
119
|
+
else:
|
|
120
|
+
param_meta[param.name] = Query(
|
|
121
|
+
param.default, description="")
|
|
122
|
+
return param_meta
|
|
123
|
+
|
|
124
|
+
def _get_response_model(self, sig: inspect.Signature) -> Optional[Type[BaseModel]]:
|
|
125
|
+
"""从函数返回类型注解中提取 Pydantic 模型"""
|
|
126
|
+
return_annotation = sig.return_annotation
|
|
127
|
+
# 支持直接注解(如 -> ProductResp)或 Optional(如 -> Optional[ProductResp])
|
|
128
|
+
if hasattr(return_annotation, '__origin__') and return_annotation.__origin__ is Optional:
|
|
129
|
+
return_annotation = return_annotation.__args__[0]
|
|
130
|
+
# 检查是否为 Pydantic 模型
|
|
131
|
+
if inspect.isclass(return_annotation) and issubclass(return_annotation, BaseModel):
|
|
132
|
+
return return_annotation
|
|
133
|
+
return None
|
|
134
|
+
|
|
135
|
+
def _bind_arguments(self, func, sig: inspect.Signature, args, kwargs) -> Dict[str, Any]:
|
|
136
|
+
try:
|
|
137
|
+
bound_args = sig.bind(*args, **kwargs)
|
|
138
|
+
bound_args.apply_defaults()
|
|
139
|
+
return {k: v for k, v in bound_args.arguments.items() if k != "self"}
|
|
140
|
+
except TypeError as e:
|
|
141
|
+
SYLogger.error(f"参数绑定失败 [{func.__name__}]: {str(e)}")
|
|
142
|
+
raise
|
|
143
|
+
|
|
144
|
+
def _validate_required_params(self, param_meta: Dict[str, Param], bound_args: Dict[str, Any]):
|
|
145
|
+
missing = [
|
|
146
|
+
meta.get_key(name) for name, meta in param_meta.items()
|
|
147
|
+
if meta.is_required() and name not in bound_args
|
|
148
|
+
]
|
|
149
|
+
if missing:
|
|
150
|
+
raise ValueError(f"缺少必填参数: {', '.join(missing)}")
|
|
151
|
+
|
|
152
|
+
def _build_headers(self, param_meta: Dict[str, Param], bound_args: Dict[str, Any], method_headers: Dict[str, str]) -> Dict[str, str]:
|
|
153
|
+
headers = self.default_headers.copy()
|
|
154
|
+
headers.update(method_headers)
|
|
155
|
+
for name, meta in param_meta.items():
|
|
156
|
+
if isinstance(meta, Header) and name in bound_args:
|
|
157
|
+
value = bound_args[name]
|
|
158
|
+
if value is not None:
|
|
159
|
+
headers[meta.get_key(name)] = str(value)
|
|
160
|
+
return headers
|
|
161
|
+
|
|
162
|
+
def _replace_path_params(self, path: str, param_meta: Dict[str, Param], bound_args: Dict[str, Any]) -> str:
|
|
163
|
+
for name, meta in param_meta.items():
|
|
164
|
+
if isinstance(meta, Path) and name in bound_args:
|
|
165
|
+
path = path.replace(
|
|
166
|
+
f"{{{meta.get_key(name)}}}", str(bound_args[name]))
|
|
167
|
+
return path
|
|
168
|
+
|
|
169
|
+
def _get_query_params(self, param_meta: Dict[str, Param], bound_args: Dict[str, Any]) -> Dict[str, str]:
|
|
170
|
+
return {
|
|
171
|
+
param_meta[name].get_key(name): str(value)
|
|
172
|
+
for name, value in bound_args.items()
|
|
173
|
+
if isinstance(param_meta.get(name), Query) and value is not None
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
def _get_cookies(self, param_meta: Dict[str, Param], bound_args: Dict[str, Any]) -> Dict[str, str]:
|
|
177
|
+
return {
|
|
178
|
+
param_meta[name].get_key(name): str(value)
|
|
179
|
+
for name, value in bound_args.items()
|
|
180
|
+
if isinstance(param_meta.get(name), Cookie) and value is not None
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
async def _get_request_data(
|
|
184
|
+
self,
|
|
185
|
+
method: str,
|
|
186
|
+
param_meta: Dict[str, Param],
|
|
187
|
+
bound_args: Dict[str, Any],
|
|
188
|
+
is_upload: bool,
|
|
189
|
+
method_headers: Dict[str, str]
|
|
190
|
+
) -> Any:
|
|
191
|
+
"""处理请求数据(支持 Pydantic 模型转字典)"""
|
|
192
|
+
if is_upload:
|
|
193
|
+
form_data = aiohttp.FormData()
|
|
194
|
+
# 处理文件
|
|
195
|
+
file_params = {
|
|
196
|
+
n: m for n, m in param_meta.items() if isinstance(m, File)}
|
|
197
|
+
for name, meta in file_params.items():
|
|
198
|
+
if name not in bound_args:
|
|
199
|
+
continue
|
|
200
|
+
file_paths = bound_args[name]
|
|
201
|
+
file_paths = [file_paths] if isinstance(
|
|
202
|
+
file_paths, str) else file_paths
|
|
203
|
+
for path in file_paths:
|
|
204
|
+
if not os.path.exists(path):
|
|
205
|
+
raise FileNotFoundError(f"文件不存在: {path}")
|
|
206
|
+
with open(path, "rb") as f:
|
|
207
|
+
form_data.add_field(
|
|
208
|
+
meta.field_name, f.read(), filename=os.path.basename(path)
|
|
209
|
+
)
|
|
210
|
+
# 处理表单字段(支持 Pydantic 模型)
|
|
211
|
+
form_params = {
|
|
212
|
+
n: m for n, m in param_meta.items() if isinstance(m, Form)}
|
|
213
|
+
for name, meta in form_params.items():
|
|
214
|
+
if name not in bound_args or bound_args[name] is None:
|
|
215
|
+
continue
|
|
216
|
+
value = bound_args[name]
|
|
217
|
+
# 若为 Pydantic 模型,转为字典
|
|
218
|
+
if isinstance(value, BaseModel):
|
|
219
|
+
value = value.dict()
|
|
220
|
+
form_data.add_field(meta.get_key(name), str(
|
|
221
|
+
value) if not isinstance(value, dict) else value)
|
|
222
|
+
return form_data
|
|
223
|
+
|
|
224
|
+
# 处理表单提交(x-www-form-urlencoded)
|
|
225
|
+
content_type = self.default_headers.get(
|
|
226
|
+
"Content-Type") or method_headers.get("Content-Type", "")
|
|
227
|
+
if "application/x-www-form-urlencoded" in content_type:
|
|
228
|
+
form_data = {}
|
|
229
|
+
for name, value in bound_args.items():
|
|
230
|
+
meta = param_meta.get(name)
|
|
231
|
+
if isinstance(meta, Form) and value is not None:
|
|
232
|
+
# Pydantic 模型转字典
|
|
233
|
+
if isinstance(value, BaseModel):
|
|
234
|
+
value = value.dict()
|
|
235
|
+
form_data[meta.get_key(name)] = str(
|
|
236
|
+
value) if not isinstance(value, dict) else value
|
|
237
|
+
return form_data
|
|
238
|
+
|
|
239
|
+
# 处理 JSON 请求体(支持 Pydantic 模型)
|
|
240
|
+
if method in ["POST", "PUT", "PATCH", "DELETE"]:
|
|
241
|
+
body_params = [
|
|
242
|
+
name for name, meta in param_meta.items() if isinstance(meta, Body)]
|
|
243
|
+
if body_params:
|
|
244
|
+
body_data = {}
|
|
245
|
+
for name in body_params:
|
|
246
|
+
meta = param_meta[name]
|
|
247
|
+
value = bound_args.get(name)
|
|
248
|
+
if value is None:
|
|
249
|
+
continue
|
|
250
|
+
# 若为 Pydantic 模型,转为字典
|
|
251
|
+
if isinstance(value, BaseModel):
|
|
252
|
+
value = value.dict()
|
|
253
|
+
if meta.embed:
|
|
254
|
+
body_data[meta.get_key(name)] = value
|
|
255
|
+
else:
|
|
256
|
+
body_data = value if not isinstance(value, dict) else {
|
|
257
|
+
** body_data, **value}
|
|
258
|
+
return body_data
|
|
259
|
+
return None
|
|
260
|
+
|
|
261
|
+
async def _get_service_base_url(self, headers: Dict[str, str]) -> str:
|
|
262
|
+
version = headers.get("s-y-version")
|
|
263
|
+
instances = self.nacos_manager.get_service_instances(
|
|
264
|
+
self.service_name, target_version=version)
|
|
265
|
+
if not instances:
|
|
266
|
+
raise RuntimeError(f"服务 [{self.service_name}] 无可用实例")
|
|
267
|
+
return f"http://{instances[int(time.time()) % len(instances)]['ip']}:{instances[0]['port']}"
|
|
268
|
+
|
|
269
|
+
async def _handle_response(self, response: aiohttp.ClientResponse, resp_model: Optional[Type[BaseModel]]) -> Any:
|
|
270
|
+
"""处理响应(支持 Pydantic 模型解析)"""
|
|
271
|
+
status = response.status
|
|
272
|
+
if 200 <= status < 300:
|
|
273
|
+
content_type = response.headers.get("Content-Type", "")
|
|
274
|
+
if "application/json" in content_type:
|
|
275
|
+
json_data = await response.json()
|
|
276
|
+
# 若指定了 Pydantic 响应模型,自动解析
|
|
277
|
+
if resp_model is not None:
|
|
278
|
+
return resp_model(** json_data) # 用响应数据初始化模型
|
|
279
|
+
return json_data
|
|
280
|
+
else:
|
|
281
|
+
return io.BytesIO(await response.read())
|
|
282
|
+
else:
|
|
283
|
+
error_msg = await response.text()
|
|
284
|
+
SYLogger.error(f"请求失败 [{status}]: {error_msg}")
|
|
285
|
+
raise RuntimeError(f"HTTP {status}: {error_msg}")
|
|
286
|
+
|
|
287
|
+
return FeignClient
|
|
288
|
+
|
|
289
|
+
return decorator
|
|
290
|
+
|
|
291
|
+
|
|
292
|
+
def feign_request(
|
|
293
|
+
method: Literal["GET", "POST", "PUT", "DELETE", "PATCH"],
|
|
294
|
+
path: str,
|
|
295
|
+
headers: Optional[Dict[str, str]] = None,
|
|
296
|
+
timeout: Optional[float] = None
|
|
297
|
+
):
|
|
298
|
+
def decorator(func):
|
|
299
|
+
func._feign_meta = {
|
|
300
|
+
"method": method.upper(),
|
|
301
|
+
"path": path,
|
|
302
|
+
"headers": headers.copy() if headers else {},
|
|
303
|
+
"is_upload": False,
|
|
304
|
+
"timeout": timeout
|
|
305
|
+
}
|
|
306
|
+
return func
|
|
307
|
+
return decorator
|
|
308
|
+
|
|
309
|
+
|
|
310
|
+
def feign_upload(field_name: str = "file"):
|
|
311
|
+
def decorator(func):
|
|
312
|
+
if not hasattr(func, "_feign_meta"):
|
|
313
|
+
raise ValueError("feign_upload必须与feign_request一起使用")
|
|
314
|
+
func._feign_meta["is_upload"] = True
|
|
315
|
+
func._feign_meta["upload_field"] = field_name
|
|
316
|
+
return func
|
|
317
|
+
return decorator
|
|
@@ -47,7 +47,7 @@ class NacosService(metaclass=SingletonMeta):
|
|
|
47
47
|
self.retry_backoff = self.nacos_config.get('retryBackoff', 1.5)
|
|
48
48
|
self.max_retry_delay = self.nacos_config.get('maxRetryDelay', 30)
|
|
49
49
|
self.heartbeat_interval = self.nacos_config.get(
|
|
50
|
-
'heartbeatInterval',
|
|
50
|
+
'heartbeatInterval', 15)
|
|
51
51
|
self.register_retry_interval = self.nacos_config.get(
|
|
52
52
|
'registerRetryInterval', 5) # 注册重试间隔
|
|
53
53
|
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
from typing import Any, Optional
|
|
2
|
+
|
|
3
|
+
# ------------------------------
|
|
4
|
+
# 参数类型标记类(兼容 Pydantic)
|
|
5
|
+
# ------------------------------
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
class Param:
|
|
9
|
+
"""基础参数元信息类"""
|
|
10
|
+
|
|
11
|
+
def __init__(
|
|
12
|
+
self,
|
|
13
|
+
default: Any = ...,
|
|
14
|
+
description: str = "",
|
|
15
|
+
alias: Optional[str] = None,
|
|
16
|
+
deprecated: bool = False
|
|
17
|
+
):
|
|
18
|
+
self.default = default # ... 表示必填
|
|
19
|
+
self.description = description
|
|
20
|
+
self.alias = alias
|
|
21
|
+
self.deprecated = deprecated
|
|
22
|
+
|
|
23
|
+
def is_required(self) -> bool:
|
|
24
|
+
return self.default is ...
|
|
25
|
+
|
|
26
|
+
def get_key(self, param_name: str) -> str:
|
|
27
|
+
return self.alias if self.alias is not None else param_name
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
class Path(Param):
|
|
31
|
+
"""路径参数"""
|
|
32
|
+
pass
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
class Query(Param):
|
|
36
|
+
"""查询参数"""
|
|
37
|
+
pass
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
class Header(Param):
|
|
41
|
+
"""请求头参数"""
|
|
42
|
+
|
|
43
|
+
def __init__(self, *args, convert_underscores: bool = True, **kwargs):
|
|
44
|
+
super().__init__(*args, **kwargs)
|
|
45
|
+
self.convert_underscores = convert_underscores
|
|
46
|
+
|
|
47
|
+
def get_key(self, param_name: str) -> str:
|
|
48
|
+
key = super().get_key(param_name)
|
|
49
|
+
return key.replace("_", "-") if self.convert_underscores else key
|
|
50
|
+
|
|
51
|
+
|
|
52
|
+
class Cookie(Param):
|
|
53
|
+
"""Cookie参数"""
|
|
54
|
+
pass
|
|
55
|
+
|
|
56
|
+
|
|
57
|
+
class Body(Param):
|
|
58
|
+
"""JSON请求体参数(支持Pydantic模型)"""
|
|
59
|
+
|
|
60
|
+
def __init__(self, *args, embed: bool = False, ** kwargs):
|
|
61
|
+
super().__init__(*args, **kwargs)
|
|
62
|
+
self.embed = embed # 是否包装在键中
|
|
63
|
+
|
|
64
|
+
|
|
65
|
+
class Form(Param):
|
|
66
|
+
"""表单参数(支持Pydantic模型)"""
|
|
67
|
+
pass
|
|
68
|
+
|
|
69
|
+
|
|
70
|
+
class File(Param):
|
|
71
|
+
"""文件上传参数"""
|
|
72
|
+
|
|
73
|
+
def __init__(self, *args, field_name: str = "file", ** kwargs):
|
|
74
|
+
super().__init__(*args, **kwargs)
|
|
75
|
+
self.field_name = field_name
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
command/cli.py,sha256=bP2LCLkRvfETIwWkVD70q5xFxMI4D3BpH09Ws1f-ENc,5849
|
|
2
2
|
sycommon/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
3
|
-
sycommon/services.py,sha256=
|
|
3
|
+
sycommon/services.py,sha256=e9odPBLUoAAUkFU4s8ITIQUbr1GH7dqb9qSHyUhN4A8,11258
|
|
4
4
|
sycommon/config/Config.py,sha256=9yO5b8WfvEDvkyrGrlwrLFasgh_-MjcEvGF20Gz5Xo4,3041
|
|
5
5
|
sycommon/config/DatabaseConfig.py,sha256=ILiUuYT9_xJZE2W-RYuC3JCt_YLKc1sbH13-MHIOPhg,804
|
|
6
6
|
sycommon/config/EmbeddingConfig.py,sha256=gPKwiDYbeu1GpdIZXMmgqM7JqBIzCXi0yYuGRLZooMI,362
|
|
@@ -31,25 +31,29 @@ sycommon/middleware/traceid.py,sha256=oGTJ2jtdea_3NgaAwXLpUug5dGUYRQeM4r1n2icuvC
|
|
|
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
|
|
34
|
-
sycommon/models/mqlistener_config.py,sha256=
|
|
34
|
+
sycommon/models/mqlistener_config.py,sha256=vXp2uMmd0XQ5B9noSRXWHewTy-juQ2y7IsWtISJD5aI,1661
|
|
35
35
|
sycommon/models/mqmsg_model.py,sha256=cxn0M5b0utQK6crMYmL-1waeGYHvK3AlGaRy23clqTE,277
|
|
36
36
|
sycommon/models/mqsend_config.py,sha256=NQX9dc8PpuquMG36GCVhJe8omAW1KVXXqr6lSRU6D7I,268
|
|
37
37
|
sycommon/models/sso_user.py,sha256=i1WAN6k5sPcPApQEdtjpWDy7VrzWLpOrOQewGLGoGIw,2702
|
|
38
|
-
sycommon/rabbitmq/rabbitmq_client.py,sha256=
|
|
39
|
-
sycommon/rabbitmq/rabbitmq_pool.py,sha256=
|
|
40
|
-
sycommon/rabbitmq/rabbitmq_service.py,sha256=
|
|
38
|
+
sycommon/rabbitmq/rabbitmq_client.py,sha256=vyyfIWJ0b7tXZSK1m8fKERW6D-LQCrDvmjKmsPvOG6M,12141
|
|
39
|
+
sycommon/rabbitmq/rabbitmq_pool.py,sha256=YmvvFO8xP2pNnwuyZ0vp28XnfTzPScIPnBMih34f7Wc,7390
|
|
40
|
+
sycommon/rabbitmq/rabbitmq_service.py,sha256=LXoL7zm-1_iTts6S9CreEMJ66ExwRm9y4zUmcOqI1YM,36597
|
|
41
41
|
sycommon/sse/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
42
42
|
sycommon/sse/event.py,sha256=k_rBJy23R7crtzQeetT0Q73D8o5-5p-eESGSs_BPOj0,2797
|
|
43
43
|
sycommon/sse/sse.py,sha256=__CfWEcYxOxQ-HpLor4LTZ5hLWqw9-2X7CngqbVHsfw,10128
|
|
44
44
|
sycommon/synacos/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
45
|
-
sycommon/synacos/
|
|
46
|
-
sycommon/synacos/
|
|
45
|
+
sycommon/synacos/example.py,sha256=61XL03tU8WTNOo3FUduf93F2fAwah1S0lbH1ufhRhRk,5739
|
|
46
|
+
sycommon/synacos/example2.py,sha256=adUaru3Hy482KrOA17DfaC4nwvLj8etIDS_KrWLWmCU,4811
|
|
47
|
+
sycommon/synacos/feign.py,sha256=0cmnyExXcr1qIV0B_POdQ-_u4-t5K3LjJD_8rDaXwSE,7467
|
|
48
|
+
sycommon/synacos/feign_client.py,sha256=JxzxohrsscQNlAjRVo_3ZQrMQSfVHFOtRYyEnP6sDGk,15205
|
|
49
|
+
sycommon/synacos/nacos_service.py,sha256=QG1lShrVZNKbExYV_IUwGXTHDnU09RYXooVy_llhW6c,34661
|
|
50
|
+
sycommon/synacos/param.py,sha256=KcfSkxnXOa0TGmCjY8hdzU9pzUsA8-4PeyBKWI2-568,1765
|
|
47
51
|
sycommon/tools/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
48
52
|
sycommon/tools/docs.py,sha256=OPj2ETheuWjXLyaXtaZPbwmJKfJaYXV5s4XMVAUNrms,1607
|
|
49
53
|
sycommon/tools/snowflake.py,sha256=DdEj3T5r5OEvikp3puxqmmmz6BrggxomoSlnsRFb5dM,1174
|
|
50
54
|
sycommon/tools/timing.py,sha256=OiiE7P07lRoMzX9kzb8sZU9cDb0zNnqIlY5pWqHcnkY,2064
|
|
51
|
-
sycommon_python_lib-0.1.
|
|
52
|
-
sycommon_python_lib-0.1.
|
|
53
|
-
sycommon_python_lib-0.1.
|
|
54
|
-
sycommon_python_lib-0.1.
|
|
55
|
-
sycommon_python_lib-0.1.
|
|
55
|
+
sycommon_python_lib-0.1.40.dist-info/METADATA,sha256=-9GpbSobbSHJj66au2M-0ThPFN5ynZEALO69lvLOClY,7037
|
|
56
|
+
sycommon_python_lib-0.1.40.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
|
57
|
+
sycommon_python_lib-0.1.40.dist-info/entry_points.txt,sha256=q_h2nbvhhmdnsOUZEIwpuoDjaNfBF9XqppDEmQn9d_A,46
|
|
58
|
+
sycommon_python_lib-0.1.40.dist-info/top_level.txt,sha256=98CJ-cyM2WIKxLz-Pf0AitWLhJyrfXvyY8slwjTXNuc,17
|
|
59
|
+
sycommon_python_lib-0.1.40.dist-info/RECORD,,
|
|
File without changes
|
{sycommon_python_lib-0.1.29.dist-info → sycommon_python_lib-0.1.40.dist-info}/entry_points.txt
RENAMED
|
File without changes
|
|
File without changes
|