codosdk 1.0.50__tar.gz → 1.0.51__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.
Files changed (54) hide show
  1. {codosdk-1.0.50 → codosdk-1.0.51}/PKG-INFO +1 -1
  2. {codosdk-1.0.50 → codosdk-1.0.51}/codosdk.egg-info/PKG-INFO +1 -1
  3. {codosdk-1.0.50 → codosdk-1.0.51}/setup.py +1 -1
  4. codosdk-1.0.51/websdk2/db_context.py +157 -0
  5. {codosdk-1.0.50 → codosdk-1.0.51}/websdk2/mqhelper.py +1 -1
  6. {codosdk-1.0.50 → codosdk-1.0.51}/websdk2/utils/pydantic_utils.py +7 -2
  7. codosdk-1.0.50/websdk2/db_context.py +0 -150
  8. {codosdk-1.0.50 → codosdk-1.0.51}/LICENSE +0 -0
  9. {codosdk-1.0.50 → codosdk-1.0.51}/README.md +0 -0
  10. {codosdk-1.0.50 → codosdk-1.0.51}/codosdk.egg-info/SOURCES.txt +0 -0
  11. {codosdk-1.0.50 → codosdk-1.0.51}/codosdk.egg-info/dependency_links.txt +0 -0
  12. {codosdk-1.0.50 → codosdk-1.0.51}/codosdk.egg-info/requires.txt +0 -0
  13. {codosdk-1.0.50 → codosdk-1.0.51}/codosdk.egg-info/top_level.txt +0 -0
  14. {codosdk-1.0.50 → codosdk-1.0.51}/opssdk/__init__.py +0 -0
  15. {codosdk-1.0.50 → codosdk-1.0.51}/opssdk/utils/__init__.py +0 -0
  16. {codosdk-1.0.50 → codosdk-1.0.51}/pyproject.toml +0 -0
  17. {codosdk-1.0.50 → codosdk-1.0.51}/setup.cfg +0 -0
  18. {codosdk-1.0.50 → codosdk-1.0.51}/websdk2/__init__.py +0 -0
  19. {codosdk-1.0.50 → codosdk-1.0.51}/websdk2/api_set.py +0 -0
  20. {codosdk-1.0.50 → codosdk-1.0.51}/websdk2/apis/__init__.py +0 -0
  21. {codosdk-1.0.50 → codosdk-1.0.51}/websdk2/apis/admin_apis.py +0 -0
  22. {codosdk-1.0.50 → codosdk-1.0.51}/websdk2/apis/agent_apis.py +0 -0
  23. {codosdk-1.0.50 → codosdk-1.0.51}/websdk2/apis/cmdb_apis.py +0 -0
  24. {codosdk-1.0.50 → codosdk-1.0.51}/websdk2/apis/kerrigan_apis.py +0 -0
  25. {codosdk-1.0.50 → codosdk-1.0.51}/websdk2/apis/mgv4_apis.py +0 -0
  26. {codosdk-1.0.50 → codosdk-1.0.51}/websdk2/apis/notice_apis.py +0 -0
  27. {codosdk-1.0.50 → codosdk-1.0.51}/websdk2/apis/task_apis.py +0 -0
  28. {codosdk-1.0.50 → codosdk-1.0.51}/websdk2/application.py +0 -0
  29. {codosdk-1.0.50 → codosdk-1.0.51}/websdk2/base_handler.py +0 -0
  30. {codosdk-1.0.50 → codosdk-1.0.51}/websdk2/cache.py +0 -0
  31. {codosdk-1.0.50 → codosdk-1.0.51}/websdk2/cache_context.py +0 -0
  32. {codosdk-1.0.50 → codosdk-1.0.51}/websdk2/client.py +0 -0
  33. {codosdk-1.0.50 → codosdk-1.0.51}/websdk2/cloud/__init__.py +0 -0
  34. {codosdk-1.0.50 → codosdk-1.0.51}/websdk2/cloud/qcloud_api.py +0 -0
  35. {codosdk-1.0.50 → codosdk-1.0.51}/websdk2/cloud/ucloud_api.py +0 -0
  36. {codosdk-1.0.50 → codosdk-1.0.51}/websdk2/cloud_utils.py +0 -0
  37. {codosdk-1.0.50 → codosdk-1.0.51}/websdk2/configs.py +0 -0
  38. {codosdk-1.0.50 → codosdk-1.0.51}/websdk2/consts.py +0 -0
  39. {codosdk-1.0.50 → codosdk-1.0.51}/websdk2/crud_utils.py +0 -0
  40. {codosdk-1.0.50 → codosdk-1.0.51}/websdk2/error.py +0 -0
  41. {codosdk-1.0.50 → codosdk-1.0.51}/websdk2/fetch_coroutine.py +0 -0
  42. {codosdk-1.0.50 → codosdk-1.0.51}/websdk2/jwt_token.py +0 -0
  43. {codosdk-1.0.50 → codosdk-1.0.51}/websdk2/ldap.py +0 -0
  44. {codosdk-1.0.50 → codosdk-1.0.51}/websdk2/logger.py +0 -0
  45. {codosdk-1.0.50 → codosdk-1.0.51}/websdk2/model_utils.py +0 -0
  46. {codosdk-1.0.50 → codosdk-1.0.51}/websdk2/program.py +0 -0
  47. {codosdk-1.0.50 → codosdk-1.0.51}/websdk2/salt_api.py +0 -0
  48. {codosdk-1.0.50 → codosdk-1.0.51}/websdk2/sqlalchemy_pagination.py +0 -0
  49. {codosdk-1.0.50 → codosdk-1.0.51}/websdk2/tools.py +0 -0
  50. {codosdk-1.0.50 → codosdk-1.0.51}/websdk2/utils/__init__.py +0 -0
  51. {codosdk-1.0.50 → codosdk-1.0.51}/websdk2/utils/cc_crypto.py +0 -0
  52. {codosdk-1.0.50 → codosdk-1.0.51}/websdk2/utils/date_format.py +0 -0
  53. {codosdk-1.0.50 → codosdk-1.0.51}/websdk2/utils/pydantic_utils_v2.py +0 -0
  54. {codosdk-1.0.50 → codosdk-1.0.51}/websdk2/web_logs.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: codosdk
3
- Version: 1.0.50
3
+ Version: 1.0.51
4
4
  Summary: CODO项目的Python SDK
5
5
  Home-page: https://github.com/ss1917/codo_sdk/
6
6
  Author: shenshuo
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: codosdk
3
- Version: 1.0.50
3
+ Version: 1.0.51
4
4
  Summary: CODO项目的Python SDK
5
5
  Home-page: https://github.com/ss1917/codo_sdk/
6
6
  Author: shenshuo
@@ -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.50'
12
+ VERSION = '1.0.51'
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.')
@@ -0,0 +1,157 @@
1
+ #!/usr/bin/env python
2
+ # -*- coding: utf-8 -*-
3
+ """
4
+ Author : shenshuo
5
+ date : 2017年10月17日17:23:19
6
+ role : 数据库连接
7
+ """
8
+
9
+ import pymysql
10
+ from urllib.parse import quote_plus
11
+ from sqlalchemy import create_engine
12
+ from sqlalchemy.pool import NullPool
13
+ from sqlalchemy.orm import sessionmaker
14
+ from .consts import const
15
+ from .configs import configs
16
+
17
+ engines = {}
18
+ scheduler_engines = {}
19
+
20
+
21
+ class DBConfigError(Exception):
22
+ pass
23
+
24
+
25
+ # 调度器专用引擎池
26
+
27
+ def init_scheduler_engine(**settings):
28
+ databases = settings.get(const.DB_CONFIG_ITEM) or configs[const.DB_CONFIG_ITEM]
29
+
30
+ for dbkey, db_conf in databases.items():
31
+ # 获取配置
32
+ dbuser = db_conf.get(const.DBUSER_KEY)
33
+ dbpwd = db_conf.get(const.DBPWD_KEY)
34
+ dbhost = db_conf.get(const.DBHOST_KEY)
35
+ dbport = db_conf.get(const.DBPORT_KEY)
36
+ dbname = db_conf.get(const.DBNAME_KEY)
37
+
38
+ # 验证配置完整性
39
+ if None in (dbuser, dbpwd, dbhost, dbname):
40
+ raise DBConfigError(f"Incomplete database configuration for '{dbkey}'")
41
+
42
+ # 创建调度器专用引擎(小规格连接池)
43
+ engine = create_engine(
44
+ f'mysql+pymysql://{dbuser}:{quote_plus(dbpwd)}@{dbhost}:{dbport}/{dbname}?charset=utf8mb4',
45
+ logging_name=dbkey,
46
+ poolclass=None, # QueuePool
47
+ pool_size=10, # 10个常驻连接(调度器用)
48
+ max_overflow=30, # 30个溢出连接
49
+ pool_recycle=1800, # 30分钟回收
50
+ pool_pre_ping=True, # 启用连接检查
51
+ pool_timeout=10, # 5秒超时
52
+ echo_pool=False # 关闭连接池日志
53
+ )
54
+
55
+ scheduler_engines[dbkey] = engine
56
+
57
+
58
+ def get_scheduler_engine(dbkey='default', **settings):
59
+ if not scheduler_engines:
60
+ init_scheduler_engine(**settings)
61
+ return scheduler_engines[dbkey]
62
+
63
+
64
+ def _build_db_url(db_conf, const) -> str:
65
+ """构建数据库连接URL"""
66
+ return 'mysql+pymysql://{user}:{pwd}@{host}:{port}/{dbname}?charset=utf8mb4'.format(
67
+ user=db_conf[const.DBUSER_KEY],
68
+ pwd=quote_plus(db_conf[const.DBPWD_KEY]),
69
+ host=db_conf[const.DBHOST_KEY],
70
+ port=db_conf[const.DBPORT_KEY],
71
+ dbname=db_conf[const.DBNAME_KEY]
72
+ )
73
+
74
+
75
+ def init_engine(use_pool=False, pool_config=None, **settings):
76
+ databases = settings.get(const.DB_CONFIG_ITEM) or configs[const.DB_CONFIG_ITEM]
77
+
78
+ # 默认连接池配置 - 优化后的推荐值
79
+ default_pool_config = {
80
+ 'pool_size': 20, # 常驻连接: 20 (原10)
81
+ 'max_overflow': 30, # 溢出连接: 30 (原50, 过大)
82
+ 'pool_recycle': 3600, # 回收时间: 1小时
83
+ 'pool_pre_ping': True, # 预检查: 启用 (避免僵尸连接)
84
+ 'pool_timeout': 20, # 获取超时: 20秒 (原60秒, 过长)
85
+ 'echo_pool': False, # 连接池日志: 关闭 (生产环境)
86
+ }
87
+
88
+ # 合并用户自定义配置
89
+ if pool_config:
90
+ default_pool_config.update(pool_config)
91
+
92
+ for dbkey, db_conf in databases.items():
93
+ db_url = _build_db_url(db_conf, const)
94
+
95
+ if use_pool:
96
+ # 使用连接池配置
97
+ engine = create_engine(
98
+ db_url,
99
+ logging_name=dbkey,
100
+ poolclass=None, # 默认 QueuePool
101
+ **default_pool_config
102
+ )
103
+ else:
104
+ # 不使用连接池 (每次新建连接)
105
+ engine = create_engine(db_url, logging_name=dbkey, poolclass=NullPool)
106
+
107
+ engines[dbkey] = engine
108
+
109
+
110
+ def get_db_url(dbkey):
111
+ """获取数据库连接URL"""
112
+ db_conf = configs[const.DB_CONFIG_ITEM][dbkey]
113
+ return _build_db_url(db_conf, const)
114
+
115
+
116
+ class DBContext:
117
+ def __init__(self, rw='r', db_key=None, need_commit=False, use_pool=False, pool_config=None, **settings):
118
+ self.__db_key = db_key or (const.DEFAULT_DB_KEY if rw == 'w' else const.READONLY_DB_KEY)
119
+ self.__engine = self.__get_db_engine(self.__db_key, use_pool, pool_config, **settings)
120
+ self.need_commit = need_commit
121
+ self.__session = None
122
+
123
+ @staticmethod
124
+ def __get_db_engine(db_key, use_pool, pool_config, **settings):
125
+ """获取数据库引擎"""
126
+ if not engines:
127
+ init_engine(use_pool=use_pool, pool_config=pool_config, **settings)
128
+ return engines[db_key]
129
+
130
+ @property
131
+ def session(self):
132
+ """获取session"""
133
+ return self.__session
134
+
135
+ def __enter__(self):
136
+ """进入上下文"""
137
+ self.__session = sessionmaker(bind=self.__engine)()
138
+ return self.__session
139
+
140
+ def __exit__(self, exc_type, exc_val, exc_tb):
141
+ """退出上下文"""
142
+ if self.need_commit:
143
+ if exc_type:
144
+ self.__session.rollback()
145
+ else:
146
+ self.__session.commit()
147
+ self.__session.close()
148
+
149
+ def get_session(self):
150
+ """获取session(向后兼容)"""
151
+ return self.__session
152
+
153
+
154
+ # ==================== 向后兼容 ====================
155
+
156
+ # DBContextV2 别名(完全兼容旧代码)
157
+ DBContextV2 = DBContext
@@ -621,4 +621,4 @@ if __name__ == "__main__":
621
621
  # 示例3:向后兼容的使用方式
622
622
  print("=== 向后兼容使用 ===")
623
623
  with MessageQueueBase('test_exchange', 'direct', routing_key='test.key', queue_name='task_test_queue') as old_mq:
624
- old_mq.publish_message("Hello from old interface!")
624
+ old_mq.publish_message("Hello from old interface!")
@@ -15,16 +15,21 @@ from sqlalchemy.inspection import inspect
15
15
  from sqlalchemy.orm.properties import ColumnProperty
16
16
 
17
17
 
18
- ### 删除的时候一般只有id
18
+ # 删除的时候一般只有id
19
19
  class PydanticDel(BaseModel):
20
20
  id: int
21
21
 
22
+
22
23
  class PydanticDelList(BaseModel):
23
24
  id_list: list[int]
24
25
 
25
26
 
26
27
  class OrmConfig(BaseConfig):
27
- orm_mode = True
28
+ # Pydantic V1/V2 自动兼容, TODO 后续移除V1兼容
29
+ try:
30
+ from_attributes = True # Pydantic V2
31
+ except Exception:
32
+ orm_mode = True # Pydantic V1
28
33
 
29
34
 
30
35
  def sqlalchemy_to_pydantic(db_model: Type, *, config: Type = OrmConfig, exclude: Container[str] = []) -> Type[
@@ -1,150 +0,0 @@
1
- # -*-coding:utf-8-*-
2
- """
3
- Author : shenshuo
4
- date : 2017年10月17日17:23:19
5
- role : 数据库连接
6
- """
7
-
8
- import pymysql
9
- from urllib.parse import quote_plus
10
- from sqlalchemy import create_engine
11
- from sqlalchemy.pool import NullPool
12
- from sqlalchemy.orm import sessionmaker
13
- from .consts import const
14
- from .configs import configs
15
-
16
- engines = {}
17
-
18
-
19
- def init_engine(**settings):
20
- if settings:
21
- databases = settings[const.DB_CONFIG_ITEM]
22
- else:
23
- databases = configs[const.DB_CONFIG_ITEM]
24
- for dbkey, db_conf in databases.items():
25
- dbuser = db_conf[const.DBUSER_KEY]
26
- dbpwd = db_conf[const.DBPWD_KEY]
27
- dbhost = db_conf[const.DBHOST_KEY]
28
- dbport = db_conf[const.DBPORT_KEY]
29
- dbname = db_conf[const.DBNAME_KEY]
30
- engine = create_engine('mysql+pymysql://{user}:{pwd}@{host}:{port}/{dbname}?charset=utf8mb4'
31
- .format(user=dbuser, pwd=quote_plus(dbpwd), host=dbhost, port=dbport, dbname=dbname),
32
- # logging_name=dbkey)
33
- logging_name=dbkey, poolclass=NullPool)
34
- engines[dbkey] = engine
35
-
36
-
37
- def get_db_url(dbkey):
38
- databases = configs[const.DB_CONFIG_ITEM]
39
- db_conf = databases[dbkey]
40
- dbuser = db_conf['user']
41
- dbpwd = db_conf['pwd']
42
- dbhost = db_conf['host']
43
- dbport = db_conf.get('port', 3306)
44
- dbname = db_conf['name']
45
-
46
- return 'mysql+pymysql://{user}:{pwd}@{host}:{port}/{dbname}?charset=utf8mb4'.format(user=dbuser, pwd=quote_plus(dbpwd),
47
- host=dbhost, port=dbport,
48
- dbname=dbname, poolclass=NullPool)
49
-
50
-
51
- class DBContext(object):
52
- def __init__(self, rw='r', db_key=None, need_commit=False, **settings):
53
- self.__db_key = db_key
54
- if not self.__db_key:
55
- if rw == 'w':
56
- self.__db_key = const.DEFAULT_DB_KEY
57
- elif rw == 'r':
58
- self.__db_key = const.READONLY_DB_KEY
59
- engine = self.__get_db_engine(self.__db_key, **settings)
60
- self.__engine = engine
61
- self.need_commit = need_commit
62
-
63
- # @property
64
- # def db_key(self):
65
- # return self.__db_key
66
-
67
- @staticmethod
68
- def __get_db_engine(db_key, **settings):
69
- if len(engines) == 0:
70
- init_engine(**settings)
71
- return engines[db_key]
72
-
73
- @property
74
- def session(self):
75
- return self.__session
76
-
77
- def __enter__(self):
78
- self.__session = sessionmaker(bind=self.__engine)()
79
- return self.__session
80
-
81
- def __exit__(self, exc_type, exc_val, exc_tb):
82
- if self.need_commit:
83
- if exc_type:
84
- self.__session.rollback()
85
- else:
86
- self.__session.commit()
87
- self.__session.close()
88
-
89
- def get_session(self):
90
- return self.__session
91
-
92
-
93
- def init_engine_v2(**settings):
94
- if settings:
95
- databases = settings[const.DB_CONFIG_ITEM]
96
- else:
97
- databases = configs[const.DB_CONFIG_ITEM]
98
- for dbkey, db_conf in databases.items():
99
- dbuser = db_conf[const.DBUSER_KEY]
100
- dbpwd = db_conf[const.DBPWD_KEY]
101
- dbhost = db_conf[const.DBHOST_KEY]
102
- dbport = db_conf[const.DBPORT_KEY]
103
- dbname = db_conf[const.DBNAME_KEY]
104
- engine = create_engine('mysql+pymysql://{user}:{pwd}@{host}:{port}/{dbname}?charset=utf8mb4'
105
- .format(user=dbuser, pwd=quote_plus(dbpwd), host=dbhost, port=dbport, dbname=dbname),
106
- logging_name=dbkey, poolclass=None, pool_size=10, max_overflow=50, pool_recycle=3600,
107
- pool_pre_ping=True, pool_timeout=60)
108
- engines[dbkey] = engine
109
-
110
-
111
- class DBContextV2(object):
112
- def __init__(self, rw='r', db_key=None, need_commit=False, **settings):
113
- self.__db_key = db_key
114
- if not self.__db_key:
115
- if rw == 'w':
116
- self.__db_key = const.DEFAULT_DB_KEY
117
- elif rw == 'r':
118
- self.__db_key = const.READONLY_DB_KEY
119
- engine = self.__get_db_engine(self.__db_key, **settings)
120
- self.__engine = engine
121
- self.need_commit = need_commit
122
-
123
- # @property
124
- # def db_key(self):
125
- # return self.__db_key
126
-
127
- @staticmethod
128
- def __get_db_engine(db_key, **settings):
129
- if len(engines) == 0:
130
- init_engine_v2(**settings)
131
- return engines[db_key]
132
-
133
- @property
134
- def session(self):
135
- return self.__session
136
-
137
- def __enter__(self):
138
- self.__session = sessionmaker(bind=self.__engine)()
139
- return self.__session
140
-
141
- def __exit__(self, exc_type, exc_val, exc_tb):
142
- if self.need_commit:
143
- if exc_type:
144
- self.__session.rollback()
145
- else:
146
- self.__session.commit()
147
- self.__session.close()
148
-
149
- def get_session(self):
150
- return self.__session
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