codosdk 1.0.41__tar.gz → 1.0.42__tar.gz
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.
- {codosdk-1.0.41 → codosdk-1.0.42}/PKG-INFO +2 -2
- {codosdk-1.0.41 → codosdk-1.0.42}/codosdk.egg-info/PKG-INFO +2 -2
- {codosdk-1.0.41 → codosdk-1.0.42}/codosdk.egg-info/requires.txt +1 -1
- {codosdk-1.0.41 → codosdk-1.0.42}/setup.py +2 -2
- {codosdk-1.0.41 → codosdk-1.0.42}/websdk2/mqhelper.py +87 -15
- {codosdk-1.0.41 → codosdk-1.0.42}/LICENSE +0 -0
- {codosdk-1.0.41 → codosdk-1.0.42}/README.md +0 -0
- {codosdk-1.0.41 → codosdk-1.0.42}/codosdk.egg-info/SOURCES.txt +0 -0
- {codosdk-1.0.41 → codosdk-1.0.42}/codosdk.egg-info/dependency_links.txt +0 -0
- {codosdk-1.0.41 → codosdk-1.0.42}/codosdk.egg-info/top_level.txt +0 -0
- {codosdk-1.0.41 → codosdk-1.0.42}/opssdk/__init__.py +0 -0
- {codosdk-1.0.41 → codosdk-1.0.42}/opssdk/utils/__init__.py +0 -0
- {codosdk-1.0.41 → codosdk-1.0.42}/pyproject.toml +0 -0
- {codosdk-1.0.41 → codosdk-1.0.42}/setup.cfg +0 -0
- {codosdk-1.0.41 → codosdk-1.0.42}/websdk2/__init__.py +0 -0
- {codosdk-1.0.41 → codosdk-1.0.42}/websdk2/api_set.py +0 -0
- {codosdk-1.0.41 → codosdk-1.0.42}/websdk2/apis/__init__.py +0 -0
- {codosdk-1.0.41 → codosdk-1.0.42}/websdk2/apis/admin_apis.py +0 -0
- {codosdk-1.0.41 → codosdk-1.0.42}/websdk2/apis/agent_apis.py +0 -0
- {codosdk-1.0.41 → codosdk-1.0.42}/websdk2/apis/cmdb_apis.py +0 -0
- {codosdk-1.0.41 → codosdk-1.0.42}/websdk2/apis/kerrigan_apis.py +0 -0
- {codosdk-1.0.41 → codosdk-1.0.42}/websdk2/apis/mgv4_apis.py +0 -0
- {codosdk-1.0.41 → codosdk-1.0.42}/websdk2/apis/notice_apis.py +0 -0
- {codosdk-1.0.41 → codosdk-1.0.42}/websdk2/apis/task_apis.py +0 -0
- {codosdk-1.0.41 → codosdk-1.0.42}/websdk2/application.py +0 -0
- {codosdk-1.0.41 → codosdk-1.0.42}/websdk2/base_handler.py +0 -0
- {codosdk-1.0.41 → codosdk-1.0.42}/websdk2/cache.py +0 -0
- {codosdk-1.0.41 → codosdk-1.0.42}/websdk2/cache_context.py +0 -0
- {codosdk-1.0.41 → codosdk-1.0.42}/websdk2/client.py +0 -0
- {codosdk-1.0.41 → codosdk-1.0.42}/websdk2/cloud/__init__.py +0 -0
- {codosdk-1.0.41 → codosdk-1.0.42}/websdk2/cloud/qcloud_api.py +0 -0
- {codosdk-1.0.41 → codosdk-1.0.42}/websdk2/cloud/ucloud_api.py +0 -0
- {codosdk-1.0.41 → codosdk-1.0.42}/websdk2/cloud_utils.py +0 -0
- {codosdk-1.0.41 → codosdk-1.0.42}/websdk2/configs.py +0 -0
- {codosdk-1.0.41 → codosdk-1.0.42}/websdk2/consts.py +0 -0
- {codosdk-1.0.41 → codosdk-1.0.42}/websdk2/crud_utils.py +0 -0
- {codosdk-1.0.41 → codosdk-1.0.42}/websdk2/db_context.py +0 -0
- {codosdk-1.0.41 → codosdk-1.0.42}/websdk2/error.py +0 -0
- {codosdk-1.0.41 → codosdk-1.0.42}/websdk2/fetch_coroutine.py +0 -0
- {codosdk-1.0.41 → codosdk-1.0.42}/websdk2/jwt_token.py +0 -0
- {codosdk-1.0.41 → codosdk-1.0.42}/websdk2/ldap.py +0 -0
- {codosdk-1.0.41 → codosdk-1.0.42}/websdk2/logger.py +0 -0
- {codosdk-1.0.41 → codosdk-1.0.42}/websdk2/model_utils.py +0 -0
- {codosdk-1.0.41 → codosdk-1.0.42}/websdk2/program.py +0 -0
- {codosdk-1.0.41 → codosdk-1.0.42}/websdk2/salt_api.py +0 -0
- {codosdk-1.0.41 → codosdk-1.0.42}/websdk2/sqlalchemy_pagination.py +0 -0
- {codosdk-1.0.41 → codosdk-1.0.42}/websdk2/tools.py +0 -0
- {codosdk-1.0.41 → codosdk-1.0.42}/websdk2/utils/__init__.py +0 -0
- {codosdk-1.0.41 → codosdk-1.0.42}/websdk2/utils/cc_crypto.py +0 -0
- {codosdk-1.0.41 → codosdk-1.0.42}/websdk2/utils/date_format.py +0 -0
- {codosdk-1.0.41 → codosdk-1.0.42}/websdk2/utils/pydantic_utils.py +0 -0
- {codosdk-1.0.41 → codosdk-1.0.42}/websdk2/web_logs.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: codosdk
|
|
3
|
-
Version: 1.0.
|
|
3
|
+
Version: 1.0.42
|
|
4
4
|
Summary: CODO项目的Python SDK
|
|
5
5
|
Home-page: https://github.com/ss1917/codo_sdk/
|
|
6
6
|
Author: shenshuo
|
|
@@ -23,7 +23,7 @@ Requires-Dist: fire==0.5.0
|
|
|
23
23
|
Requires-Dist: shortuuid==1.0.11
|
|
24
24
|
Requires-Dist: pymysql==0.9.3
|
|
25
25
|
Requires-Dist: sqlalchemy==1.3.23
|
|
26
|
-
Requires-Dist: pika==1.3.
|
|
26
|
+
Requires-Dist: pika==1.3.2
|
|
27
27
|
Requires-Dist: PyJWT==2.0.1
|
|
28
28
|
Requires-Dist: requests==2.28.2
|
|
29
29
|
Requires-Dist: redis==4.5.1
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: codosdk
|
|
3
|
-
Version: 1.0.
|
|
3
|
+
Version: 1.0.42
|
|
4
4
|
Summary: CODO项目的Python SDK
|
|
5
5
|
Home-page: https://github.com/ss1917/codo_sdk/
|
|
6
6
|
Author: shenshuo
|
|
@@ -23,7 +23,7 @@ Requires-Dist: fire==0.5.0
|
|
|
23
23
|
Requires-Dist: shortuuid==1.0.11
|
|
24
24
|
Requires-Dist: pymysql==0.9.3
|
|
25
25
|
Requires-Dist: sqlalchemy==1.3.23
|
|
26
|
-
Requires-Dist: pika==1.3.
|
|
26
|
+
Requires-Dist: pika==1.3.2
|
|
27
27
|
Requires-Dist: PyJWT==2.0.1
|
|
28
28
|
Requires-Dist: requests==2.28.2
|
|
29
29
|
Requires-Dist: redis==4.5.1
|
|
@@ -9,7 +9,7 @@ desc : CODO SDK
|
|
|
9
9
|
import sys
|
|
10
10
|
from setuptools import setup, find_packages
|
|
11
11
|
|
|
12
|
-
VERSION = '1.0.
|
|
12
|
+
VERSION = '1.0.42'
|
|
13
13
|
|
|
14
14
|
if sys.version_info < (2, 7) or (3, 0) <= sys.version_info < (3, 6):
|
|
15
15
|
print('This program requires at least Python 2.7 or 3.6 to run.')
|
|
@@ -24,7 +24,7 @@ def get_data_files():
|
|
|
24
24
|
|
|
25
25
|
|
|
26
26
|
def get_install_requires():
|
|
27
|
-
requires = ['fire==0.5.0', 'shortuuid==1.0.11', 'pymysql==0.9.3', 'sqlalchemy==1.3.23', 'pika==1.3.
|
|
27
|
+
requires = ['fire==0.5.0', 'shortuuid==1.0.11', 'pymysql==0.9.3', 'sqlalchemy==1.3.23', 'pika==1.3.2',
|
|
28
28
|
'PyJWT==2.0.1', 'requests==2.28.2', 'redis==4.5.1', 'tornado>=6.0', 'loguru>=0.6.0',
|
|
29
29
|
'cryptography==42.0.4', 'ldap3==2.9', 'pydantic>=1.10.5']
|
|
30
30
|
return requires
|
|
@@ -120,6 +120,7 @@ logger.setLevel(logging.WARNING)
|
|
|
120
120
|
# else:
|
|
121
121
|
# self.__channel.basic_publish(exchange=self.__exchange, routing_key=self.__routing_key, body=body)
|
|
122
122
|
# logging.info('Publish message %s sucessfuled.' % body)
|
|
123
|
+
|
|
123
124
|
class RabbitMQConnectionPool:
|
|
124
125
|
"""RabbitMQ连接池管理器 - 实现一个应用一个连接的最佳实践"""
|
|
125
126
|
|
|
@@ -148,22 +149,37 @@ class RabbitMQConnectionPool:
|
|
|
148
149
|
mq_config = configs[const.MQ_CONFIG_ITEM][mq_key]
|
|
149
150
|
cls._validate_config(mq_config)
|
|
150
151
|
|
|
151
|
-
#
|
|
152
|
+
# 创建连接参数,优化超时和重试设置
|
|
152
153
|
credentials = pika.PlainCredentials(
|
|
153
154
|
mq_config[const.MQ_USER],
|
|
154
155
|
mq_config[const.MQ_PWD]
|
|
155
156
|
)
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
157
|
+
|
|
158
|
+
connection_params = pika.ConnectionParameters(
|
|
159
|
+
host=mq_config[const.MQ_ADDR],
|
|
160
|
+
port=int(mq_config[const.MQ_PORT]),
|
|
161
|
+
virtual_host=mq_config[const.MQ_VHOST],
|
|
162
|
+
credentials=credentials,
|
|
163
|
+
heartbeat=300, # 减少心跳间隔
|
|
164
|
+
blocked_connection_timeout=60, # 减少阻塞超时
|
|
165
|
+
socket_timeout=30, # 添加socket超时
|
|
166
|
+
connection_attempts=3, # 连接重试次数
|
|
167
|
+
retry_delay=1, # 重试延迟
|
|
168
|
+
stack_timeout=30, # 栈超时
|
|
169
|
+
# 添加TCP连接参数 某些系统上可能不被支持 删除
|
|
170
|
+
# tcp_options={
|
|
171
|
+
# 'TCP_KEEPIDLE': 60,
|
|
172
|
+
# 'TCP_KEEPINTVL': 30,
|
|
173
|
+
# 'TCP_KEEPCNT': 3
|
|
174
|
+
# }
|
|
165
175
|
)
|
|
166
176
|
|
|
177
|
+
connection = pika.BlockingConnection(connection_params)
|
|
178
|
+
|
|
179
|
+
# 验证连接状态
|
|
180
|
+
if not connection.is_open:
|
|
181
|
+
raise Exception("Connection failed to open properly")
|
|
182
|
+
|
|
167
183
|
cls._connections[mq_key] = connection
|
|
168
184
|
logging.info(f"Created new RabbitMQ connection for key: {mq_key}")
|
|
169
185
|
|
|
@@ -254,10 +270,49 @@ class MessageQueueBase:
|
|
|
254
270
|
f"you must provide a queue_name to avoid anonymous queues."
|
|
255
271
|
)
|
|
256
272
|
|
|
273
|
+
# def _get_channel(self) -> Any:
|
|
274
|
+
# """获取新的通道"""
|
|
275
|
+
# connection = RabbitMQConnectionPool.get_connection(self._mq_key)
|
|
276
|
+
# return connection.channel()
|
|
277
|
+
|
|
257
278
|
def _get_channel(self) -> Any:
|
|
258
279
|
"""获取新的通道"""
|
|
259
|
-
|
|
260
|
-
|
|
280
|
+
max_attempts = 3
|
|
281
|
+
for attempt in range(max_attempts):
|
|
282
|
+
try:
|
|
283
|
+
connection = RabbitMQConnectionPool.get_connection(self._mq_key)
|
|
284
|
+
if not connection or not connection.is_open:
|
|
285
|
+
raise Exception("Connection is not available or not open")
|
|
286
|
+
|
|
287
|
+
# 添加连接状态检查
|
|
288
|
+
try:
|
|
289
|
+
# 尝试发送心跳检查连接状态
|
|
290
|
+
connection.process_data_events(time_limit=0)
|
|
291
|
+
except:
|
|
292
|
+
raise Exception("Connection heartbeat failed")
|
|
293
|
+
|
|
294
|
+
channel = connection.channel()
|
|
295
|
+
if not channel or not channel.is_open:
|
|
296
|
+
raise Exception("Channel is not available or not open")
|
|
297
|
+
return channel
|
|
298
|
+
|
|
299
|
+
except Exception as e:
|
|
300
|
+
self.logger.warning(f"Failed to get healthy channel (attempt {attempt + 1}): {e}")
|
|
301
|
+
if attempt < max_attempts - 1:
|
|
302
|
+
# 清理并重建连接
|
|
303
|
+
with RabbitMQConnectionPool._connection_lock:
|
|
304
|
+
try:
|
|
305
|
+
RabbitMQConnectionPool._cleanup_connection(self._mq_key)
|
|
306
|
+
RabbitMQConnectionPool._connections[self._mq_key] = None
|
|
307
|
+
except Exception as cleanup_e:
|
|
308
|
+
self.logger.warning(f"Error during connection cleanup: {cleanup_e}")
|
|
309
|
+
|
|
310
|
+
# 短暂等待后重试
|
|
311
|
+
import time
|
|
312
|
+
time.sleep(0.1 * (attempt + 1))
|
|
313
|
+
else:
|
|
314
|
+
# 最后一次尝试失败,抛出异常
|
|
315
|
+
raise Exception(f"Failed to get channel after {max_attempts} attempts: {e}")
|
|
261
316
|
|
|
262
317
|
def _with_retry(self, operation: Callable, *args, **kwargs) -> Any:
|
|
263
318
|
"""带重试机制执行操作"""
|
|
@@ -273,8 +328,25 @@ class MessageQueueBase:
|
|
|
273
328
|
break
|
|
274
329
|
else:
|
|
275
330
|
self.logger.warning(f"Attempt {attempt + 1} failed: {e}. Retrying...")
|
|
276
|
-
|
|
277
|
-
|
|
331
|
+
|
|
332
|
+
# 只在特定错误类型时清理连接
|
|
333
|
+
error_str = str(e).lower()
|
|
334
|
+
if any(keyword in error_str for keyword in [
|
|
335
|
+
'connection', 'channel', 'socket', 'transport',
|
|
336
|
+
'callback', 'deque', 'abort', 'closed'
|
|
337
|
+
]):
|
|
338
|
+
# 安全地清理连接
|
|
339
|
+
with RabbitMQConnectionPool._connection_lock:
|
|
340
|
+
try:
|
|
341
|
+
if self._mq_key in RabbitMQConnectionPool._connections:
|
|
342
|
+
RabbitMQConnectionPool._cleanup_connection(self._mq_key)
|
|
343
|
+
RabbitMQConnectionPool._connections[self._mq_key] = None
|
|
344
|
+
except Exception as cleanup_e:
|
|
345
|
+
self.logger.debug(f"Error during connection cleanup: {cleanup_e}")
|
|
346
|
+
|
|
347
|
+
# 递增延迟重试
|
|
348
|
+
import time
|
|
349
|
+
time.sleep(0.1 * (2 ** attempt))
|
|
278
350
|
|
|
279
351
|
raise last_exception
|
|
280
352
|
|
|
@@ -498,5 +570,5 @@ if __name__ == "__main__":
|
|
|
498
570
|
|
|
499
571
|
# 示例3:向后兼容的使用方式
|
|
500
572
|
print("=== 向后兼容使用 ===")
|
|
501
|
-
with MessageQueueBase('test_exchange', 'direct', routing_key='test.key') as old_mq:
|
|
573
|
+
with MessageQueueBase('test_exchange', 'direct', routing_key='test.key', queue_name='task_test_queue') as old_mq:
|
|
502
574
|
old_mq.publish_message("Hello from old interface!")
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|