fiuai-sdk-python 0.6.9__py3-none-any.whl → 0.7.1__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.
@@ -1,7 +1,7 @@
1
1
  from .header import parse_auth_headers, extract_auth_from_request
2
2
  from .type import AuthData, AuthHeader
3
3
  from .helper import (
4
- get_auth_data as get_auth_data_from_request,
4
+ get_auth_data,
5
5
  get_current_user_id,
6
6
  get_current_tenant_id,
7
7
  get_current_company,
@@ -14,19 +14,23 @@ from .context_mgr import (
14
14
  init_context,
15
15
  WorldData,
16
16
  get_auth_data_from_context,
17
- get_auth_data,
18
17
  set_auth_data,
19
18
  update_auth_data,
20
19
  get_world_data,
20
+ set_user_profile_info,
21
+ get_user_profile_info,
21
22
  )
22
23
 
24
+ # 兼容旧用法:从 request 取 auth 时可用 get_auth_data(request) 或 get_auth_data_from_request(request)
25
+ get_auth_data_from_request = get_auth_data
26
+
23
27
  __all__ = [
24
28
  "parse_auth_headers",
25
29
  "extract_auth_from_request",
26
30
  "AuthData",
27
31
  "AuthHeader",
28
- "get_auth_data_from_request",
29
32
  "get_auth_data",
33
+ "get_auth_data_from_request",
30
34
  "get_auth_data_from_context",
31
35
  "get_current_user_id",
32
36
  "get_current_tenant_id",
@@ -40,4 +44,6 @@ __all__ = [
40
44
  "set_auth_data",
41
45
  "update_auth_data",
42
46
  "get_world_data",
47
+ "set_user_profile_info",
48
+ "get_user_profile_info",
43
49
  ]
@@ -8,8 +8,10 @@
8
8
  """
9
9
  上下文管理:ContextManager、init_context、WorldData,
10
10
  以及从当前上下文获取/设置认证数据的 get_auth_data_from_context、set_auth_data、update_auth_data、get_world_data。
11
+ 可选:user_profile_info 的 set_user_profile_info / get_user_profile_info(请求级存储,不影响未使用的调用方)。
11
12
  """
12
13
 
14
+ import contextvars
13
15
  import uuid
14
16
  import logging
15
17
  from typing import Dict, Any, Optional
@@ -24,6 +26,11 @@ logger = logging.getLogger(__name__)
24
26
 
25
27
  _current_context_manager: Optional["ContextManager"] = None
26
28
 
29
+ # 可选:请求级 UserProfileInfo,仅当调用方 set 时存在,不 set 则 get 为 None
30
+ _user_profile_info: contextvars.ContextVar[Optional[Any]] = contextvars.ContextVar(
31
+ "user_profile_info", default=None
32
+ )
33
+
27
34
 
28
35
  class WorldData(BaseModel):
29
36
  """World 上下文数据模型"""
@@ -49,6 +56,7 @@ class ContextManager:
49
56
  world_data: Optional[WorldData] = None,
50
57
  event_id: Optional[str] = None,
51
58
  task_id: Optional[str] = None,
59
+ user_profile_info: Optional[Any] = None,
52
60
  ):
53
61
  if auth_data and headers:
54
62
  raise ValueError("不能同时提供 auth_data 和 headers,请只提供其中一个")
@@ -60,6 +68,9 @@ class ContextManager:
60
68
  else:
61
69
  self.world_data = WorldData()
62
70
 
71
+ self._user_profile_info = user_profile_info
72
+ self._user_profile_info_token: Optional[contextvars.Token] = None
73
+
63
74
  if auth_data:
64
75
  self._context = self._create_context_from_auth_data(auth_data)
65
76
  elif headers:
@@ -87,10 +98,15 @@ class ContextManager:
87
98
  global _current_context_manager
88
99
  _current_context_manager = self
89
100
  self._context.__enter__()
101
+ if self._user_profile_info is not None:
102
+ self._user_profile_info_token = _user_profile_info.set(self._user_profile_info)
90
103
  logger.debug("Context initialized")
91
104
  return self
92
105
 
93
106
  def __exit__(self, exc_type, exc_val, exc_tb):
107
+ if self._user_profile_info_token is not None:
108
+ _user_profile_info.reset(self._user_profile_info_token)
109
+ self._user_profile_info_token = None
94
110
  self._context.__exit__(exc_type, exc_val, exc_tb)
95
111
  global _current_context_manager
96
112
  _current_context_manager = None
@@ -124,17 +140,32 @@ def init_context(
124
140
  world_data: Optional[WorldData] = None,
125
141
  event_id: Optional[str] = None,
126
142
  task_id: Optional[str] = None,
143
+ user_profile_info: Optional[Any] = None,
127
144
  **kwargs: Any,
128
145
  ) -> ContextManager:
129
146
  """
130
147
  初始化上下文,用于后台任务。返回的 ContextManager 必须在 `with` 语句中使用。
131
148
 
132
149
  支持三种方式:1) auth_data 对象 2) headers 字典 3) user_id, auth_tenant_id, current_company。
150
+ trace_id 可从 auth_data.trace_id 或 kwargs["trace_id"](仅方式 3)传入。
151
+ 可选 user_profile_info:在 with 块内 get_user_profile_info() 可读。
133
152
  """
134
153
  if auth_data:
135
- return ContextManager(auth_data=auth_data, world_data=world_data, event_id=event_id, task_id=task_id)
154
+ return ContextManager(
155
+ auth_data=auth_data,
156
+ world_data=world_data,
157
+ event_id=event_id,
158
+ task_id=task_id,
159
+ user_profile_info=user_profile_info,
160
+ )
136
161
  if headers:
137
- return ContextManager(headers=headers, world_data=world_data, event_id=event_id, task_id=task_id)
162
+ return ContextManager(
163
+ headers=headers,
164
+ world_data=world_data,
165
+ event_id=event_id,
166
+ task_id=task_id,
167
+ user_profile_info=user_profile_info,
168
+ )
138
169
  if user_id and auth_tenant_id and current_company:
139
170
  auth_data = AuthData(
140
171
  user_id=user_id,
@@ -146,7 +177,13 @@ def init_context(
146
177
  client=kwargs.get("client", "unknown"),
147
178
  channel=kwargs.get("channel", "default"),
148
179
  )
149
- return ContextManager(auth_data=auth_data, world_data=world_data, event_id=event_id, task_id=task_id)
180
+ return ContextManager(
181
+ auth_data=auth_data,
182
+ world_data=world_data,
183
+ event_id=event_id,
184
+ task_id=task_id,
185
+ user_profile_info=user_profile_info,
186
+ )
150
187
  raise ValueError(
151
188
  "必须提供以下之一:"
152
189
  "1. auth_data 对象 "
@@ -235,3 +272,20 @@ def get_world_data() -> Optional[WorldData]:
235
272
  except Exception as e:
236
273
  logger.warning("Failed to get world data: %s", e)
237
274
  return None
275
+
276
+
277
+ def set_user_profile_info(profile: Optional[Any]) -> None:
278
+ """
279
+ 设置当前请求/上下文内的可选 UserProfileInfo。
280
+ 仅当需要 profile 时调用;不调用则 get_user_profile_info() 为 None,不影响其他使用者。
281
+ 在 HTTP 请求内由业务在 set_user_context 等入口调用;在 with init_context(...) 内也可通过 init_context(..., user_profile_info=...) 传入。
282
+ """
283
+ _user_profile_info.set(profile)
284
+
285
+
286
+ def get_user_profile_info() -> Optional[Any]:
287
+ """
288
+ 获取当前请求/上下文内的可选 UserProfileInfo。
289
+ 未设置时返回 None;类型由调用方约定(如 profile.UserProfileInfo 或 dict)。
290
+ """
291
+ return _user_profile_info.get()
@@ -8,172 +8,122 @@
8
8
  from fastapi import Request, HTTPException
9
9
  from typing import Optional, Union, Dict, Literal
10
10
  from .type import AuthData
11
+ from .context_mgr import get_auth_data as get_auth_data_from_context
11
12
 
12
13
 
13
14
  def get_auth_data(
14
- request: Union[Request, Dict[str, str]],
15
- engine: Literal["fastapi", "dict"] = "fastapi"
16
- ) -> AuthData:
17
- """
18
- 从请求中获取认证数据
19
-
20
- Args:
21
- request: FastAPI Request 对象或包含认证数据的字典
22
- engine: 请求引擎类型,默认为 "fastapi"
23
-
24
- Returns:
25
- AuthData: 认证数据
26
-
27
- Raises:
28
- HTTPException: 当认证数据不存在时抛出 401 错误(仅限 FastAPI)
29
- ValueError: 当使用 dict 引擎且认证数据不存在时
15
+ request: Optional[Union[Request, Dict[str, str]]] = None,
16
+ engine: Literal["fastapi", "dict"] = "fastapi",
17
+ ) -> Optional[AuthData]:
30
18
  """
19
+ 从请求或当前上下文中获取认证数据。
20
+ request 为 None 时从当前 RequestContext 解析(FiuaiContextMiddleware + AuthMiddleware 或 init_context 内可用),无上下文时返回 None。
21
+ 传入 request 时从 request 取,不存在时抛 HTTPException/ValueError。
22
+ """
23
+ if request is None:
24
+ return get_auth_data_from_context()
31
25
  if engine == "fastapi":
32
26
  if not isinstance(request, Request):
33
- raise TypeError("request must be a FastAPI Request object when engine='fastapi'")
34
- auth_data = getattr(request.state, 'auth_data', None)
27
+ raise TypeError(
28
+ "request must be a FastAPI Request object when engine='fastapi'"
29
+ )
30
+ auth_data = getattr(request.state, "auth_data", None)
35
31
  if not auth_data:
36
32
  raise HTTPException(
37
33
  status_code=401,
38
34
  detail={
39
35
  "error": "Unauthorized",
40
36
  "message": "Authentication data not found",
41
- "code": "AUTH_NOT_FOUND"
42
- }
37
+ "code": "AUTH_NOT_FOUND",
38
+ },
43
39
  )
44
40
  return auth_data
45
- elif engine == "dict":
41
+ if engine == "dict":
46
42
  if not isinstance(request, dict):
47
43
  raise TypeError("request must be a dict when engine='dict'")
48
- auth_data = request.get('auth_data')
44
+ auth_data = request.get("auth_data")
49
45
  if not auth_data:
50
46
  raise ValueError("Authentication data not found in request dict")
51
47
  return auth_data
52
- else:
53
- raise ValueError("engine must be either 'fastapi' or 'dict'")
48
+ raise ValueError("engine must be either 'fastapi' or 'dict'")
54
49
 
55
50
 
56
51
  def get_current_user_id(
57
- request: Union[Request, Dict[str, str]],
58
- engine: Literal["fastapi", "dict"] = "fastapi"
59
- ) -> str:
60
- """
61
- 获取当前用户ID
62
-
63
- Args:
64
- request: FastAPI Request 对象或包含认证数据的字典
65
- engine: 请求引擎类型,默认为 "fastapi"
66
-
67
- Returns:
68
- str: 用户ID
52
+ request: Optional[Union[Request, Dict[str, str]]] = None,
53
+ engine: Literal["fastapi", "dict"] = "fastapi",
54
+ ) -> Optional[str]:
55
+ """
56
+ 获取当前用户ID。request 为 None 时从当前上下文取;无上下文或未认证时返回 None。
69
57
  """
70
58
  auth_data = get_auth_data(request, engine)
71
- return auth_data.user_id
59
+ return auth_data.user_id if auth_data else None
72
60
 
73
61
 
74
62
  def get_current_tenant_id(
75
- request: Union[Request, Dict[str, str]],
76
- engine: Literal["fastapi", "dict"] = "fastapi"
77
- ) -> str:
78
- """
79
- 获取当前租户ID
80
-
81
- Args:
82
- request: FastAPI Request 对象或包含认证数据的字典
83
- engine: 请求引擎类型,默认为 "fastapi"
84
-
85
- Returns:
86
- str: 租户ID
63
+ request: Optional[Union[Request, Dict[str, str]]] = None,
64
+ engine: Literal["fastapi", "dict"] = "fastapi",
65
+ ) -> Optional[str]:
66
+ """
67
+ 获取当前租户ID。request 为 None 时从当前上下文取;无上下文或未认证时返回 None。
87
68
  """
88
69
  auth_data = get_auth_data(request, engine)
89
- return auth_data.auth_tenant_id
70
+ return auth_data.auth_tenant_id if auth_data else None
90
71
 
91
72
 
92
73
  def get_current_company(
93
- request: Union[Request, Dict[str, str]],
94
- engine: Literal["fastapi", "dict"] = "fastapi"
95
- ) -> str:
96
- """
97
- 获取当前公司ID
98
-
99
- Args:
100
- request: FastAPI Request 对象或包含认证数据的字典
101
- engine: 请求引擎类型,默认为 "fastapi"
102
-
103
- Returns:
104
- str: 公司ID
74
+ request: Optional[Union[Request, Dict[str, str]]] = None,
75
+ engine: Literal["fastapi", "dict"] = "fastapi",
76
+ ) -> Optional[str]:
77
+ """
78
+ 获取当前公司ID。request 为 None 时从当前上下文取;无上下文或未认证时返回 None。
105
79
  """
106
80
  auth_data = get_auth_data(request, engine)
107
- return auth_data.current_company
81
+ return auth_data.current_company if auth_data else None
108
82
 
109
83
 
110
84
  def get_company_unique_no(
111
- request: Union[Request, Dict[str, str]],
112
- engine: Literal["fastapi", "dict"] = "fastapi"
113
- ) -> str:
114
- """
115
- 获取当前公司唯一编号
116
-
117
- Args:
118
- request: FastAPI Request 对象或包含认证数据的字典
119
- engine: 请求引擎类型,默认为 "fastapi"
120
-
121
- Returns:
122
- str: 公司唯一编号
85
+ request: Optional[Union[Request, Dict[str, str]]] = None,
86
+ engine: Literal["fastapi", "dict"] = "fastapi",
87
+ ) -> Optional[str]:
88
+ """
89
+ 获取当前公司唯一编号。request 为 None 时从当前上下文取;无上下文或未认证时返回 None。
123
90
  """
124
91
  auth_data = get_auth_data(request, engine)
125
- return auth_data.company_unique_no
92
+ return auth_data.company_unique_no if auth_data else None
126
93
 
127
94
 
128
95
  def get_impersonation(
129
- request: Union[Request, Dict[str, str]],
130
- engine: Literal["fastapi", "dict"] = "fastapi"
131
- ) -> str:
132
- """
133
- 获取当前代表的租户ID
134
-
135
- Args:
136
- request: FastAPI Request 对象或包含认证数据的字典
137
- engine: 请求引擎类型,默认为 "fastapi"
138
-
139
- Returns:
140
- str: 代表的租户ID
96
+ request: Optional[Union[Request, Dict[str, str]]] = None,
97
+ engine: Literal["fastapi", "dict"] = "fastapi",
98
+ ) -> Optional[str]:
99
+ """
100
+ 获取当前代表的租户ID。request 为 None 时从当前上下文取;无上下文或未认证时返回 None。
141
101
  """
142
102
  auth_data = get_auth_data(request, engine)
143
- return auth_data.impersonation
103
+ return auth_data.impersonation if auth_data else None
144
104
 
145
105
 
146
106
  def get_current_client(
147
- request: Union[Request, Dict[str, str]],
148
- engine: Literal["fastapi", "dict"] = "fastapi"
149
- ) -> str:
150
- """
151
- 获取当前客户端标识
152
-
153
- Args:
154
- request: FastAPI Request 对象或包含认证数据的字典
155
- engine: 请求引擎类型,默认为 "fastapi"
156
-
157
- Returns:
158
- str: 客户端标识
107
+ request: Optional[Union[Request, Dict[str, str]]] = None,
108
+ engine: Literal["fastapi", "dict"] = "fastapi",
109
+ ) -> Optional[str]:
110
+ """
111
+ 获取当前客户端标识。request 为 None 时从当前上下文取;无上下文或未认证时返回 None。
159
112
  """
160
113
  auth_data = get_auth_data(request, engine)
161
- return auth_data.client
114
+ return auth_data.client if auth_data else None
162
115
 
163
116
 
164
117
  def is_impersonating(
165
- request: Union[Request, Dict[str, str]],
166
- engine: Literal["fastapi", "dict"] = "fastapi"
118
+ request: Optional[Union[Request, Dict[str, str]]] = None,
119
+ engine: Literal["fastapi", "dict"] = "fastapi",
167
120
  ) -> bool:
168
121
  """
169
- 检查是否正在代表其他租户
170
-
171
- Args:
172
- request: FastAPI Request 对象或包含认证数据的字典
173
- engine: 请求引擎类型,默认为 "fastapi"
174
-
175
- Returns:
176
- bool: 是否正在代表其他租户
122
+ 检查是否正在代表其他租户。request 为 None 时从当前上下文取;无上下文或未认证时返回 False。
177
123
  """
178
124
  auth_data = get_auth_data(request, engine)
179
- return bool(auth_data.impersonation and auth_data.impersonation != auth_data.auth_tenant_id)
125
+ if not auth_data:
126
+ return False
127
+ return bool(
128
+ auth_data.impersonation and auth_data.impersonation != auth_data.auth_tenant_id
129
+ )
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: fiuai_sdk_python
3
- Version: 0.6.9
3
+ Version: 0.7.1
4
4
  Summary: FiuAI Python SDK - 企业级AI服务集成开发工具包
5
5
  Project-URL: Homepage, https://github.com/fiuai/fiuai-sdk-python
6
6
  Project-URL: Documentation, https://github.com/fiuai/fiuai-sdk-python#readme
@@ -15,28 +15,21 @@ fiuai_sdk_python/resp.py,sha256=4twCxmwqe2e1vlhfFnu-5_FR8PwQiveB9njY3exaQ88,1018
15
15
  fiuai_sdk_python/setup.py,sha256=ER0IPAouHhrVSzG0Iu87Ky0R5c4kCgOF77kRAOO-1MI,8025
16
16
  fiuai_sdk_python/type.py,sha256=vinZKflNvmQNhqO5mDARAE6O133k0LiR1s1ZvexN_q4,28940
17
17
  fiuai_sdk_python/util.py,sha256=x3TkNsC8_nzA-8x6ndIGrIpE9sRKpn3vlxnj2Hqpxwo,2326
18
- fiuai_sdk_python/auth/__init__.py,sha256=AK1OQQJvX7tdzjOybt2UOcGABdXJzddWc49PHZeqxLY,1004
19
- fiuai_sdk_python/auth/context_mgr.py,sha256=Wl7Q0YCw0VKiPrYkPZXoBHJM6d0t8kkPOCFxxJv1O_A,9179
18
+ fiuai_sdk_python/auth/__init__.py,sha256=bPLrLT2wDPURVXJ6a0Hi-AhwCCCj1PISY2Gn_Jv427o,1225
19
+ fiuai_sdk_python/auth/context_mgr.py,sha256=cw7A9xfrJMPdRIwOWMr11HI8XEwTNTUYa9AzCObytB0,11296
20
20
  fiuai_sdk_python/auth/header.py,sha256=JoMT6OJQUU7laGP6235kolfG-Qy_AP6ZQQQ9Ca8U88c,3606
21
- fiuai_sdk_python/auth/helper.py,sha256=GeuRwOZivtIsAo4_XBt0PDDbOLntF2uxSrO9mPvVMBs,5014
21
+ fiuai_sdk_python/auth/helper.py,sha256=DUKYe-Y0O-uRVeBqbmsayzF2EfogLNyXf05o4a8iAJc,4726
22
22
  fiuai_sdk_python/auth/type.py,sha256=lPUgbSOW-mQfOZpxPGhwDmpbKr5UfjznEuSKGwDosxY,2233
23
23
  fiuai_sdk_python/examples/fastapi_integration.py,sha256=6VonD8xkpwUFh3qwQh6mdHGbITscX-MMJF2k3Gj2bJc,1701
24
24
  fiuai_sdk_python/http/__init__.py,sha256=RMtrf0O-iuAGMIqfpQg6sQHj_O9Lo4Lhn7KejcapZzo,692
25
25
  fiuai_sdk_python/http/client.py,sha256=omcM8R8NGSszZlKBPikZr-NJXHgwpNYu7qDa_9H1Jug,14321
26
26
  fiuai_sdk_python/pkg/cache/__init__.py,sha256=7mVRUKkAxCAHIWVZrIslel_kr0S5Je_l0I9Fy_iZjzI,112
27
27
  fiuai_sdk_python/pkg/cache/redis_manager.py,sha256=APSRRmsJKRWfDvzIJiwNMtIqjzbheOdULskj5mI55Fk,6114
28
- fiuai_sdk_python/pkg/db/__init__.py,sha256=IK-zw5tTiSpVMtT3zdVGMaqup08TACIWcEYWpe1htkc,709
29
- fiuai_sdk_python/pkg/db/config.py,sha256=tId1db3209oZGVQKDwm-cvKu_GCbpbPerR8rgdeD3xE,645
30
- fiuai_sdk_python/pkg/db/errors.py,sha256=JJwfM_sHXYAOfP5peg9rg8n2BsCMnPXIKVLrOFMPHOs,489
31
- fiuai_sdk_python/pkg/db/manager.py,sha256=HapTkFOfCzQLCXWBAOlGHsjGCWVBNBLEMCDH7Kty7tI,14855
32
- fiuai_sdk_python/pkg/db/utils.py,sha256=qqZ14eV7fy9x_mwcEDKJDz1W54xPndpJ1QfM_D0E3FI,2419
33
- fiuai_sdk_python/pkg/vector/__init__.py,sha256=fvbetFxbHiFeojnTfKT3roA1hOcoNHF_eCRuG6HwMpI,404
34
- fiuai_sdk_python/pkg/vector/vector.py,sha256=gC8CQTZm56zXbhM3g_hFa7SGtAo9D1atNs3HwuEbJHQ,28994
35
28
  fiuai_sdk_python/utils/__init__.py,sha256=UwwsvqBsaRCHbWdx-wvM48szT3j50h95k9MZdbfawRQ,72
36
29
  fiuai_sdk_python/utils/ids.py,sha256=ZDtEqt_Woth8ytPB2tdnnTIv7noWr8XYhSsUvkZ7Hc0,6448
37
30
  fiuai_sdk_python/utils/logger.py,sha256=RuKn9TFmV1IfsRTV3ZdtXLZkM44GkHs32ehbJdrdu-8,3657
38
31
  fiuai_sdk_python/utils/text.py,sha256=bnob_W0nj_Vj8Hp93B0cYmFOY8IhUWF0C8UedOYCNvs,1667
39
- fiuai_sdk_python-0.6.9.dist-info/METADATA,sha256=ZKbU-s_9nobP_2kNJVR2e6vZfVJ9wKbCROabQfDdojQ,1523
40
- fiuai_sdk_python-0.6.9.dist-info/WHEEL,sha256=WLgqFyCfm_KASv4WHyYy0P3pM_m7J5L9k2skdKLirC8,87
41
- fiuai_sdk_python-0.6.9.dist-info/licenses/LICENSE,sha256=PFMF0dFErrBFqU-rryEby0yW8GBagYqrdbyZQHMUCJg,1062
42
- fiuai_sdk_python-0.6.9.dist-info/RECORD,,
32
+ fiuai_sdk_python-0.7.1.dist-info/METADATA,sha256=9zuPOwRytT_wRjNeyutOdtkpDHv7UlOA9FRPTJsDgcc,1523
33
+ fiuai_sdk_python-0.7.1.dist-info/WHEEL,sha256=WLgqFyCfm_KASv4WHyYy0P3pM_m7J5L9k2skdKLirC8,87
34
+ fiuai_sdk_python-0.7.1.dist-info/licenses/LICENSE,sha256=PFMF0dFErrBFqU-rryEby0yW8GBagYqrdbyZQHMUCJg,1062
35
+ fiuai_sdk_python-0.7.1.dist-info/RECORD,,
@@ -1,35 +0,0 @@
1
- # -- coding: utf-8 --
2
- # Project: fiuai-world
3
- # Created Date: 2025-01-27
4
- # Author: liming
5
- # Email: lmlala@aliyun.com
6
- # Copyright (c) 2025 FiuAI
7
-
8
- from pkg.db.errors import (
9
- PostgresError,
10
- PostgresConnectionError,
11
- PostgresQueryError,
12
- PostgresPoolError,
13
- )
14
- from pkg.db.config import PostgresConfig
15
- from pkg.db.manager import (
16
- PostgresManager,
17
- postgres_manager,
18
- )
19
- from pkg.db.utils import (
20
- escape_table_name,
21
- build_frappe_table_name,
22
- )
23
-
24
- __all__ = [
25
- 'PostgresManager',
26
- 'PostgresConfig',
27
- 'PostgresError',
28
- 'PostgresConnectionError',
29
- 'PostgresQueryError',
30
- 'PostgresPoolError',
31
- 'postgres_manager',
32
- 'escape_table_name',
33
- 'build_frappe_table_name',
34
- ]
35
-
@@ -1,25 +0,0 @@
1
- # -- coding: utf-8 --
2
- # Project: fiuai-world
3
- # Created Date: 2025-01-27
4
- # Author: liming
5
- # Email: lmlala@aliyun.com
6
- # Copyright (c) 2025 FiuAI
7
-
8
- from dataclasses import dataclass
9
-
10
-
11
- @dataclass
12
- class PostgresConfig:
13
- """PostgreSQL 配置"""
14
- host: str
15
- port: int
16
- user: str
17
- password: str
18
- database: str
19
- pool_minconn: int = 1 # 连接池最小连接数
20
- pool_maxconn: int = 10 # 连接池最大连接数
21
- pool_timeout: int = 30 # 获取连接超时时间(秒)
22
- connect_timeout: int = 10 # 连接超时时间(秒)
23
- retry_count: int = 3 # 重试次数
24
- retry_delay: int = 1 # 重试延迟(秒)
25
-
@@ -1,27 +0,0 @@
1
- # -- coding: utf-8 --
2
- # Project: fiuai-world
3
- # Created Date: 2025-01-27
4
- # Author: liming
5
- # Email: lmlala@aliyun.com
6
- # Copyright (c) 2025 FiuAI
7
-
8
-
9
- class PostgresError(Exception):
10
- """PostgreSQL 基础错误类"""
11
- pass
12
-
13
-
14
- class PostgresConnectionError(PostgresError):
15
- """PostgreSQL 连接错误"""
16
- pass
17
-
18
-
19
- class PostgresQueryError(PostgresError):
20
- """PostgreSQL 查询错误"""
21
- pass
22
-
23
-
24
- class PostgresPoolError(PostgresError):
25
- """PostgreSQL 连接池错误"""
26
- pass
27
-