skyplatform-iam 1.0.5__py3-none-any.whl → 1.1.0__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.
@@ -4,28 +4,8 @@ SkyPlatform IAM SDK
4
4
  """
5
5
 
6
6
  from .config import AuthConfig
7
- from .middleware import (
8
- AuthMiddleware,
9
- AuthService,
10
- setup_auth_middleware,
11
- get_current_user,
12
- get_optional_user,
13
- create_auth_middleware
14
- )
7
+ from .middleware import AuthMiddleware, AuthService, setup_auth_middleware, get_current_user, get_optional_user
15
8
  from .connect_agenterra_iam import ConnectAgenterraIam
16
- from .global_manager import GlobalIAMManager, get_global_manager
17
- from .api import (
18
- init_skyplatform_iam,
19
- get_iam_client,
20
- create_lazy_iam_client,
21
- LazyIAMClient,
22
- get_current_user_info,
23
- verify_permission,
24
- get_config,
25
- get_sdk_status,
26
- reset_sdk,
27
- setup_auth # 向后兼容的别名
28
- )
29
9
  from .exceptions import (
30
10
  SkyPlatformAuthException,
31
11
  AuthenticationError,
@@ -37,39 +17,28 @@ from .exceptions import (
37
17
  NetworkError
38
18
  )
39
19
 
40
- __version__ = "2.0.0"
20
+ __version__ = "1.0.0"
41
21
  __author__ = "x9"
42
22
  __description__ = "SkyPlatform IAM认证SDK,提供FastAPI中间件和IAM服务连接功能"
43
23
 
24
+ # 全局IAM客户端实例
25
+ _global_iam_client = None
26
+
44
27
  # 导出主要类和函数
45
28
  __all__ = [
46
29
  # 配置
47
30
  "AuthConfig",
48
31
 
49
- # 新的统一API(推荐使用)
50
- "init_skyplatform_iam",
51
- "get_iam_client",
52
- "create_lazy_iam_client",
53
- "LazyIAMClient",
54
- "get_current_user_info",
55
- "verify_permission",
56
- "get_config",
57
- "get_sdk_status",
58
- "reset_sdk",
59
-
60
- # 全局管理器
61
- "GlobalIAMManager",
62
- "get_global_manager",
63
-
64
32
  # 中间件
65
33
  "AuthMiddleware",
66
34
  "AuthService",
67
- "create_auth_middleware",
35
+ "setup_auth_middleware",
68
36
  "get_current_user",
69
37
  "get_optional_user",
70
38
 
71
39
  # 客户端
72
40
  "ConnectAgenterraIam",
41
+ "get_iam_client",
73
42
 
74
43
  # 异常
75
44
  "SkyPlatformAuthException",
@@ -81,10 +50,6 @@ __all__ = [
81
50
  "IAMServiceError",
82
51
  "NetworkError",
83
52
 
84
- # 向后兼容(已废弃)
85
- "setup_auth_middleware",
86
- "setup_auth",
87
-
88
53
  # 版本信息
89
54
  "__version__",
90
55
  "__author__",
@@ -92,10 +57,9 @@ __all__ = [
92
57
  ]
93
58
 
94
59
 
95
- # 向后兼容的便捷函数(已废弃)
96
- def create_auth_middleware_legacy(config: AuthConfig = None, **kwargs) -> AuthMiddleware:
60
+ def create_auth_middleware(config: AuthConfig = None, **kwargs) -> AuthMiddleware:
97
61
  """
98
- 创建认证中间件的便捷函数(已废弃)
62
+ 创建认证中间件的便捷函数
99
63
 
100
64
  Args:
101
65
  config: 认证配置,如果为None则从环境变量创建
@@ -104,25 +68,19 @@ def create_auth_middleware_legacy(config: AuthConfig = None, **kwargs) -> AuthMi
104
68
  Returns:
105
69
  AuthMiddleware: 认证中间件实例
106
70
 
107
- Deprecated:
108
- 请使用 init_skyplatform_iam() + create_auth_middleware() 替代
71
+ Note:
72
+ 此函数用于创建中间件实例,用于请求拦截和鉴权。
73
+ 客户端应用需要自己实现具体的业务接口。
109
74
  """
110
- import warnings
111
- warnings.warn(
112
- "create_auth_middleware_legacy()已废弃,请使用init_skyplatform_iam() + create_auth_middleware()替代",
113
- DeprecationWarning,
114
- stacklevel=2
115
- )
116
-
117
75
  if config is None:
118
76
  config = AuthConfig.from_env()
119
77
 
120
- return AuthMiddleware(config=config, use_global_manager=False, **kwargs)
78
+ return AuthMiddleware(config=config, **kwargs)
121
79
 
122
80
 
123
- def setup_auth_legacy(app, config: AuthConfig = None):
81
+ def init_skyplatform_iam(app, config: AuthConfig = None):
124
82
  """
125
- 一键设置认证中间件的便捷函数(已废弃)
83
+ 一键设置认证中间件的便捷函数
126
84
 
127
85
  Args:
128
86
  app: FastAPI应用实例
@@ -131,16 +89,11 @@ def setup_auth_legacy(app, config: AuthConfig = None):
131
89
  Returns:
132
90
  AuthMiddleware: 认证中间件实例
133
91
 
134
- Deprecated:
135
- 请使用 init_skyplatform_iam() 替代
92
+ Note:
93
+ 此函数只设置认证中间件,不包含预制路由。
94
+ 客户端应用需要根据业务需求自己实现认证相关的API接口。
95
+ 建议传入完整的AuthConfig对象以避免环境变量配置问题。
136
96
  """
137
- import warnings
138
- warnings.warn(
139
- "setup_auth_legacy()已废弃,请使用init_skyplatform_iam()替代",
140
- DeprecationWarning,
141
- stacklevel=2
142
- )
143
-
144
97
  if config is None:
145
98
  config = AuthConfig.from_env()
146
99
 
@@ -151,7 +104,58 @@ def setup_auth_legacy(app, config: AuthConfig = None):
151
104
  setup_auth_middleware(config)
152
105
 
153
106
  # 添加中间件
154
- middleware = AuthMiddleware(app=app, config=config, use_global_manager=False)
155
- app.add_middleware(AuthMiddleware, config=config, use_global_manager=False)
107
+ middleware = AuthMiddleware(app=app, config=config)
108
+ app.add_middleware(AuthMiddleware, config=config)
156
109
 
157
- return middleware
110
+ return middleware
111
+
112
+
113
+ def get_iam_client(config: AuthConfig = None) -> ConnectAgenterraIam:
114
+ """
115
+ 获取全局IAM客户端实例
116
+
117
+ Args:
118
+ config: 认证配置,如果为None则从环境变量创建
119
+
120
+ Returns:
121
+ ConnectAgenterraIam: IAM客户端实例
122
+
123
+ Note:
124
+ 此函数使用单例模式,确保整个应用中只有一个IAM客户端实例。
125
+ 第一次调用时会创建实例,后续调用会返回同一个实例。
126
+ 如果需要更新配置,可以传入新的config参数。
127
+
128
+ Example:
129
+ # 使用默认配置(从环境变量)
130
+ iam_client = get_iam_client()
131
+
132
+ # 使用自定义配置
133
+ config = AuthConfig(
134
+ agenterra_iam_host="https://iam.example.com",
135
+ server_name="my_server",
136
+ access_key="my_access_key"
137
+ )
138
+ iam_client = get_iam_client(config)
139
+
140
+ # 调用IAM服务方法
141
+ result = iam_client.register(
142
+ cred_type="username",
143
+ cred_value="test_user",
144
+ password="password123"
145
+ )
146
+ """
147
+ global _global_iam_client
148
+
149
+ # 如果传入了新的配置,或者实例不存在,则创建/更新实例
150
+ if config is not None:
151
+ if _global_iam_client is None:
152
+ _global_iam_client = ConnectAgenterraIam(config=config)
153
+ else:
154
+ # 重新加载配置
155
+ _global_iam_client.reload_config(config)
156
+ elif _global_iam_client is None:
157
+ # 使用默认配置创建实例
158
+ default_config = AuthConfig.from_env()
159
+ _global_iam_client = ConnectAgenterraIam(config=default_config)
160
+
161
+ return _global_iam_client
skyplatform_iam/config.py CHANGED
@@ -3,21 +3,18 @@ SkyPlatform IAM SDK 配置模块
3
3
  """
4
4
  import os
5
5
  import fnmatch
6
- import logging
7
- from typing import Optional, List, Dict, Any
8
- from pydantic import BaseModel, Field, validator
6
+ from typing import Optional, List
7
+ from pydantic import BaseModel, Field
9
8
  from dotenv import load_dotenv
10
9
 
11
10
  # 加载环境变量
12
11
  load_dotenv()
13
12
 
14
- logger = logging.getLogger(__name__)
15
-
16
13
 
17
14
  class AuthConfig(BaseModel):
18
15
  """
19
16
  认证配置类
20
- 支持环境变量和代码配置,增强配置验证和管理功能
17
+ 支持环境变量和代码配置
21
18
  """
22
19
  # IAM服务配置
23
20
  agenterra_iam_host: str
@@ -33,184 +30,32 @@ class AuthConfig(BaseModel):
33
30
 
34
31
  # 白名单路径配置(实例变量)
35
32
  whitelist_paths: List[str] = Field(default_factory=list)
36
-
37
- # 连接配置
38
- timeout: int = 30
39
- max_retries: int = 3
40
-
41
- # 缓存配置
42
- enable_cache: bool = True
43
- cache_ttl: int = 300 # 5分钟
44
33
 
45
34
  class Config:
46
- env_prefix = "SKYPLATFORM_"
47
- validate_assignment = True
48
-
49
- @validator('agenterra_iam_host')
50
- def validate_iam_host(cls, v):
51
- """验证IAM主机地址"""
52
- if not v:
53
- raise ValueError("agenterra_iam_host不能为空")
54
- if not (v.startswith('http://') or v.startswith('https://')):
55
- raise ValueError("agenterra_iam_host必须以http://或https://开头")
56
- return v.rstrip('/') # 移除末尾的斜杠
57
-
58
- @validator('server_name')
59
- def validate_server_name(cls, v):
60
- """验证服务名称"""
61
- if not v or not v.strip():
62
- raise ValueError("server_name不能为空")
63
- return v.strip()
64
-
65
- @validator('access_key')
66
- def validate_access_key(cls, v):
67
- """验证访问密钥"""
68
- if not v or not v.strip():
69
- raise ValueError("access_key不能为空")
70
- if len(v.strip()) < 8:
71
- raise ValueError("access_key长度不能少于8个字符")
72
- return v.strip()
73
-
74
- @validator('timeout')
75
- def validate_timeout(cls, v):
76
- """验证超时时间"""
77
- if v <= 0:
78
- raise ValueError("timeout必须大于0")
79
- return v
80
-
81
- @validator('max_retries')
82
- def validate_max_retries(cls, v):
83
- """验证最大重试次数"""
84
- if v < 0:
85
- raise ValueError("max_retries不能小于0")
86
- return v
87
-
88
- @validator('cache_ttl')
89
- def validate_cache_ttl(cls, v):
90
- """验证缓存TTL"""
91
- if v <= 0:
92
- raise ValueError("cache_ttl必须大于0")
93
- return v
35
+ env_prefix = "AGENTERRA_"
94
36
 
95
37
  @classmethod
96
- def from_env(cls, prefix: str = "SKYPLATFORM_") -> "AuthConfig":
38
+ def from_env(cls) -> "AuthConfig":
97
39
  """
98
40
  从环境变量创建配置
99
-
100
- Args:
101
- prefix: 环境变量前缀,默认为SKYPLATFORM_
102
-
103
- Returns:
104
- AuthConfig: 配置实例
105
-
106
- Raises:
107
- ValueError: 配置验证失败
108
41
  """
109
- logger.info(f"从环境变量加载配置,前缀: {prefix}")
110
-
111
- # 支持多种环境变量前缀(向后兼容)
112
- def get_env_value(key: str, default: str = '') -> str:
113
- # 优先使用新前缀
114
- value = os.environ.get(f"{prefix}{key}", '')
115
- if not value:
116
- # 回退到旧前缀
117
- value = os.environ.get(f"AGENTERRA_{key}", default)
118
- return value
119
-
120
- # 解析白名单路径
121
- whitelist_paths_str = get_env_value('WHITELIST_PATHS', '')
122
- whitelist_paths = []
123
- if whitelist_paths_str:
124
- whitelist_paths = [path.strip() for path in whitelist_paths_str.split(',') if path.strip()]
125
-
126
- config = cls(
127
- agenterra_iam_host=get_env_value('IAM_HOST'),
128
- server_name=get_env_value('SERVER_NAME'),
129
- access_key=get_env_value('ACCESS_KEY'),
130
- enable_debug=get_env_value('ENABLE_DEBUG', 'false').lower() == 'true',
131
- whitelist_paths=whitelist_paths,
132
- timeout=int(get_env_value('TIMEOUT', '30')),
133
- max_retries=int(get_env_value('MAX_RETRIES', '3')),
134
- enable_cache=get_env_value('ENABLE_CACHE', 'true').lower() == 'true',
135
- cache_ttl=int(get_env_value('CACHE_TTL', '300'))
42
+ return cls(
43
+ agenterra_iam_host=os.environ.get('AGENTERRA_IAM_HOST', ''),
44
+ server_name=os.environ.get('AGENTERRA_SERVER_NAME', ''),
45
+ access_key=os.environ.get('AGENTERRA_ACCESS_KEY', ''),
46
+ enable_debug=os.environ.get('AGENTERRA_ENABLE_DEBUG', 'false').lower() == 'true',
47
+ whitelist_paths=[] # 初始化空的白名单路径列表
136
48
  )
137
-
138
- logger.info(f"配置加载完成: server_name={config.server_name}, "
139
- f"iam_host={config.agenterra_iam_host}, "
140
- f"whitelist_paths_count={len(config.whitelist_paths)}")
141
-
142
- return config
143
-
144
- def validate_config(self) -> None:
145
- """
146
- 验证配置完整性
147
-
148
- Raises:
149
- ValueError: 配置验证失败
150
- """
151
- logger.debug("开始验证配置完整性")
152
-
153
- # Pydantic会自动调用validator,这里只需要检查业务逻辑
154
- if not self.agenterra_iam_host:
155
- raise ValueError("agenterra_iam_host不能为空")
156
- if not self.server_name:
157
- raise ValueError("server_name不能为空")
158
- if not self.access_key:
159
- raise ValueError("access_key不能为空")
160
-
161
- logger.info("配置验证通过")
162
49
 
163
- def merge_config(self, other: "AuthConfig") -> "AuthConfig":
164
- """
165
- 合并配置,other的非空值会覆盖当前配置
166
-
167
- Args:
168
- other: 要合并的配置
169
-
170
- Returns:
171
- AuthConfig: 合并后的新配置实例
50
+ def validate_config(self) -> bool:
172
51
  """
173
- logger.debug("开始合并配置")
174
-
175
- # 获取当前配置的字典表示
176
- current_dict = self.dict()
177
- other_dict = other.dict()
178
-
179
- # 合并配置
180
- merged_dict = current_dict.copy()
181
- for key, value in other_dict.items():
182
- if key == 'whitelist_paths':
183
- # 白名单路径需要合并而不是覆盖
184
- merged_paths = list(set(current_dict[key] + value))
185
- merged_dict[key] = merged_paths
186
- elif value: # 只有非空值才覆盖
187
- merged_dict[key] = value
188
-
189
- logger.debug(f"配置合并完成,合并后的配置: {merged_dict}")
190
- return AuthConfig(**merged_dict)
191
-
192
- def to_dict(self) -> Dict[str, Any]:
193
- """
194
- 转换为字典格式
195
-
196
- Returns:
197
- Dict: 配置字典
198
- """
199
- return self.dict()
200
-
201
- def copy_with_updates(self, **updates) -> "AuthConfig":
202
- """
203
- 创建配置副本并更新指定字段
204
-
205
- Args:
206
- **updates: 要更新的字段
207
-
208
- Returns:
209
- AuthConfig: 更新后的配置副本
52
+ 验证配置是否完整
210
53
  """
211
- config_dict = self.dict()
212
- config_dict.update(updates)
213
- return AuthConfig(**config_dict)
54
+ required_fields = ['agenterra_iam_host', 'server_name', 'access_key']
55
+ for field in required_fields:
56
+ if not getattr(self, field):
57
+ raise ValueError(f"配置项 {field} 不能为空")
58
+ return True
214
59
 
215
60
  def _normalize_path(self, path: str) -> str:
216
61
  """