springbootAI 1.8.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.
Files changed (175) hide show
  1. spring/__init__.py +66 -0
  2. spring/ai/__init__.py +78 -0
  3. spring/ai/advisors.py +139 -0
  4. spring/ai/annotations.py +74 -0
  5. spring/ai/autoconfig.py +481 -0
  6. spring/ai/core.py +391 -0
  7. spring/ai/etl.py +188 -0
  8. spring/ai/memory.py +109 -0
  9. spring/ai/observability.py +129 -0
  10. spring/ai/providers.py +789 -0
  11. spring/ai/resilience.py +258 -0
  12. spring/ai/tools.py +106 -0
  13. spring/ai/vectorstore.py +303 -0
  14. spring/annotations/__init__.py +188 -0
  15. spring/annotations/cache.py +126 -0
  16. spring/annotations/cloud.py +207 -0
  17. spring/annotations/conditional.py +272 -0
  18. spring/annotations/core.py +864 -0
  19. spring/annotations/messaging.py +107 -0
  20. spring/aop/__init__.py +4 -0
  21. spring/aop/cloud_aop.py +404 -0
  22. spring/aop/comprehensive_aop.py +1015 -0
  23. spring/aop/method_interceptor.py +19 -0
  24. spring/aop/proxy_factory.py +55 -0
  25. spring/cloud/__init__.py +76 -0
  26. spring/cloud/discovery.py +364 -0
  27. spring/cloud/feign.py +469 -0
  28. spring/cloud/gateway.py +452 -0
  29. spring/cloud/load_balancer.py +149 -0
  30. spring/cloud/seata.py +557 -0
  31. spring/cloud/sentinel.py +525 -0
  32. spring/cloud/tracer.py +337 -0
  33. spring/config/__init__.py +21 -0
  34. spring/config/binding.py +206 -0
  35. spring/config/config_loader.py +405 -0
  36. spring/context/__init__.py +13 -0
  37. spring/context/application_context.py +589 -0
  38. spring/context/bean_definition.py +70 -0
  39. spring/context/bean_factory.py +1052 -0
  40. spring/context/registry.py +58 -0
  41. spring/context/scanner.py +106 -0
  42. spring/core/__init__.py +3 -0
  43. spring/core/graceful_shutdown.py +196 -0
  44. spring/core/typing_utils.py +50 -0
  45. spring/csv/__init__.py +52 -0
  46. spring/csv/annotations.py +402 -0
  47. spring/csv/converters.py +69 -0
  48. spring/csv/easy_csv.py +95 -0
  49. spring/csv/exceptions.py +27 -0
  50. spring/csv/reader.py +195 -0
  51. spring/csv/writer.py +155 -0
  52. spring/data/__init__.py +54 -0
  53. spring/data/page.py +181 -0
  54. spring/data/repository.py +274 -0
  55. spring/data/specification.py +228 -0
  56. spring/datasource/__init__.py +66 -0
  57. spring/datasource/annotations.py +133 -0
  58. spring/datasource/context.py +69 -0
  59. spring/datasource/dynamic.py +148 -0
  60. spring/event/__init__.py +7 -0
  61. spring/event/publisher.py +69 -0
  62. spring/excel/__init__.py +51 -0
  63. spring/excel/annotations.py +405 -0
  64. spring/excel/converters.py +231 -0
  65. spring/excel/easy_excel.py +94 -0
  66. spring/excel/exceptions.py +31 -0
  67. spring/excel/reader.py +254 -0
  68. spring/excel/style.py +95 -0
  69. spring/excel/writer.py +197 -0
  70. spring/i18n/__init__.py +97 -0
  71. spring/i18n/accessor.py +94 -0
  72. spring/i18n/auto_config.py +177 -0
  73. spring/i18n/holder.py +106 -0
  74. spring/i18n/locale.py +152 -0
  75. spring/i18n/locale_resolver.py +367 -0
  76. spring/i18n/message_source.py +250 -0
  77. spring/i18n/middleware.py +79 -0
  78. spring/i18n/properties.py +168 -0
  79. spring/i18n/sources.py +255 -0
  80. spring/logging/__init__.py +1 -0
  81. spring/logging/loguru_logger.py +228 -0
  82. spring/main.py +378 -0
  83. spring/messaging/__init__.py +1 -0
  84. spring/messaging/rabbitmq.py +302 -0
  85. spring/monitoring/__init__.py +1 -0
  86. spring/monitoring/prometheus.py +199 -0
  87. spring/orm/__init__.py +258 -0
  88. spring/orm/database.py +222 -0
  89. spring/orm/ddl_auto.py +1217 -0
  90. spring/orm/migration.py +419 -0
  91. spring/orm/mybatis_integration.py +400 -0
  92. spring/orm/pymybatis/__init__.py +86 -0
  93. spring/orm/pymybatis/annotations/__init__.py +30 -0
  94. spring/orm/pymybatis/annotations/annotations.py +332 -0
  95. spring/orm/pymybatis/cache/__init__.py +47 -0
  96. spring/orm/pymybatis/cache/cache.py +371 -0
  97. spring/orm/pymybatis/cache/redis_cache.py +434 -0
  98. spring/orm/pymybatis/circuit_breaker/__init__.py +21 -0
  99. spring/orm/pymybatis/circuit_breaker/circuit_breaker.py +424 -0
  100. spring/orm/pymybatis/configuration.py +525 -0
  101. spring/orm/pymybatis/core/__init__.py +10 -0
  102. spring/orm/pymybatis/core/sql_session.py +1382 -0
  103. spring/orm/pymybatis/core/sql_session_factory.py +76 -0
  104. spring/orm/pymybatis/dialect/__init__.py +9 -0
  105. spring/orm/pymybatis/dialect/dialect.py +445 -0
  106. spring/orm/pymybatis/dynamic_sql/__init__.py +9 -0
  107. spring/orm/pymybatis/dynamic_sql/dynamic_sql.py +900 -0
  108. spring/orm/pymybatis/interceptor/__init__.py +31 -0
  109. spring/orm/pymybatis/interceptor/interceptor.py +427 -0
  110. spring/orm/pymybatis/mapper/__init__.py +9 -0
  111. spring/orm/pymybatis/mapper/mapper.py +540 -0
  112. spring/orm/pymybatis/metrics/__init__.py +41 -0
  113. spring/orm/pymybatis/metrics/metrics.py +595 -0
  114. spring/orm/pymybatis/pool/__init__.py +9 -0
  115. spring/orm/pymybatis/pool/connection_pool.py +711 -0
  116. spring/orm/pymybatis/security/__init__.py +19 -0
  117. spring/orm/pymybatis/security/access_control.py +415 -0
  118. spring/orm/pymybatis/security/password_encoder.py +293 -0
  119. spring/orm/pymybatis/security/sensitive_data_masker.py +326 -0
  120. spring/orm/pymybatis/security/sql_injection_detector.py +675 -0
  121. spring/orm/pymybatis/transaction/__init__.py +9 -0
  122. spring/orm/pymybatis/transaction/transaction.py +288 -0
  123. spring/orm/pymybatis/type_handler/__init__.py +37 -0
  124. spring/orm/pymybatis/type_handler/type_handler.py +473 -0
  125. spring/orm/pymybatis/version.py +9 -0
  126. spring/orm/pymybatis/xml_parser/__init__.py +9 -0
  127. spring/orm/pymybatis/xml_parser/xml_parser.py +761 -0
  128. spring/retry/__init__.py +12 -0
  129. spring/retry/retry_annotations.py +71 -0
  130. spring/retry/retry_decorator.py +155 -0
  131. spring/scheduling/__init__.py +3 -0
  132. spring/scheduling/scheduler.py +389 -0
  133. spring/security/__init__.py +39 -0
  134. spring/security/jwt_utils.py +281 -0
  135. spring/security/replay_protection.py +206 -0
  136. spring/security/secret_manager.py +226 -0
  137. spring/security/security_aop.py +248 -0
  138. spring/security/security_context.py +172 -0
  139. spring/test/__init__.py +45 -0
  140. spring/test/slicing.py +341 -0
  141. spring/tracing/__init__.py +11 -0
  142. spring/tracing/skywalking.py +229 -0
  143. spring/tx/__init__.py +52 -0
  144. spring/tx/events.py +172 -0
  145. spring/tx/synchronization.py +143 -0
  146. spring/utils/__init__.py +5 -0
  147. spring/utils/banner.py +32 -0
  148. spring/utils/logger.py +73 -0
  149. spring/utils/redis_client.py +526 -0
  150. spring/validation/__init__.py +55 -0
  151. spring/validation/aop.py +141 -0
  152. spring/validation/constraints.py +357 -0
  153. spring/validation/exceptions.py +55 -0
  154. spring/validation/validator.py +139 -0
  155. spring/web/__init__.py +12 -0
  156. spring/web/actuator.py +319 -0
  157. spring/web/exception_handler.py +61 -0
  158. spring/web/health.py +399 -0
  159. spring/web/interceptor.py +91 -0
  160. spring/web/result.py +44 -0
  161. spring/web/swagger.py +601 -0
  162. spring/web/web_context.py +755 -0
  163. spring/websocket/__init__.py +86 -0
  164. spring/websocket/annotations.py +169 -0
  165. spring/websocket/broker.py +238 -0
  166. spring/websocket/exceptions.py +26 -0
  167. spring/websocket/handler.py +243 -0
  168. spring/websocket/router.py +526 -0
  169. spring/websocket/session.py +216 -0
  170. springbootai-1.8.0.dist-info/METADATA +2796 -0
  171. springbootai-1.8.0.dist-info/RECORD +175 -0
  172. springbootai-1.8.0.dist-info/WHEEL +5 -0
  173. springbootai-1.8.0.dist-info/entry_points.txt +2 -0
  174. springbootai-1.8.0.dist-info/licenses/LICENSE +7 -0
  175. springbootai-1.8.0.dist-info/top_level.txt +1 -0
@@ -0,0 +1,243 @@
1
+ """WebSocket Handler 接口与 ``@ServerEndpoint`` 类级注解(对齐 Spring
2
+ ``WebSocketHandler`` + JSR-356 ``@ServerEndpoint``)。
3
+
4
+ 两种使用范式:
5
+
6
+ 1. **接口风格**(对齐 Spring ``WebSocketHandler``)::
7
+
8
+ class EchoHandler(WebSocketHandler):
9
+ async def after_connection_established(self, session):
10
+ await session.send_text("welcome")
11
+ async def handle_message(self, session, message):
12
+ await session.send_text("echo: " + message)
13
+
14
+ 或更便捷的 ``TextWebSocketHandler`` / ``BinaryWebSocketHandler``。
15
+
16
+ 2. **JSR-356 注解风格**(``@ServerEndpoint``)::
17
+
18
+ @ServerEndpoint("/ws/echo")
19
+ class EchoEndpoint:
20
+ async def on_open(self, session): ...
21
+ async def on_message(self, session, message): ...
22
+ async def on_close(self, session, reason): ...
23
+ async def on_error(self, session, error): ...
24
+
25
+ ``@ServerEndpoint`` 只注册元数据(路径 + 生命周期方法名),实际方法包装由
26
+ ``AnnotatedEndpointHandler`` 完成(适配到 ``WebSocketHandler`` 接口)。
27
+ ``discover_server_endpoints`` 扫描模块/类列表,返回 ``{path: endpoint_cls}`` 字典,
28
+ 供 ``WebSocketRouter`` 挂载路由。
29
+ """
30
+ from __future__ import annotations
31
+
32
+ import inspect
33
+ import logging
34
+ from typing import Any, Awaitable, Callable, Dict, Iterable, List, Optional, Type, Union
35
+
36
+ from spring.annotations.core import SpringAnnotation
37
+
38
+ from .exceptions import WebSocketHandlerException
39
+ from .session import WebSocketSession, global_session_registry
40
+
41
+ logger = logging.getLogger("Spring.WebSocket.Handler")
42
+
43
+
44
+ # ==================== WebSocketHandler 接口 ====================
45
+
46
+ class WebSocketHandler:
47
+ """WebSocket 处理器接口(对齐 Spring ``WebSocketHandler``)。
48
+
49
+ 子类覆盖以下方法:
50
+ - ``after_connection_established(session)``:连接建立后调用。
51
+ - ``handle_text_message(session, message)``:处理文本消息(默认调用 ``handle_message``)。
52
+ - ``handle_binary_message(session, data)``:处理二进制消息(默认调用 ``handle_message``)。
53
+ - ``handle_message(session, message)``:通用消息处理(默认 no-op)。
54
+ - ``handle_transport_error(session, exception)``:传输错误。
55
+ - ``after_connection_closed(session, reason)``:连接关闭后调用。
56
+ - ``supports_partial_messages()``:是否支持分片消息,默认 False。
57
+ """
58
+
59
+ async def after_connection_established(self, session: WebSocketSession) -> None:
60
+ """连接建立后调用(默认 no-op)。"""
61
+ pass
62
+
63
+ async def handle_text_message(self, session: WebSocketSession, message: str) -> None:
64
+ await self.handle_message(session, message)
65
+
66
+ async def handle_binary_message(self, session: WebSocketSession, data: bytes) -> None:
67
+ await self.handle_message(session, data)
68
+
69
+ async def handle_message(self, session: WebSocketSession, message: Any) -> None:
70
+ """通用消息处理(默认 no-op,子类覆盖)。"""
71
+ pass
72
+
73
+ async def handle_transport_error(self, session: WebSocketSession, exception: Exception) -> None:
74
+ logger.warning("WebSocket transport error on session %s: %s", session.id, exception)
75
+
76
+ async def after_connection_closed(self, session: WebSocketSession, reason: str) -> None:
77
+ """连接关闭后调用(默认 no-op)。"""
78
+ pass
79
+
80
+ def supports_partial_messages(self) -> bool:
81
+ return False
82
+
83
+
84
+ class TextWebSocketHandler(WebSocketHandler):
85
+ """文本消息便捷基类(对齐 Spring ``TextWebSocketHandler``)。
86
+
87
+ 子类只需覆盖 ``handle_text_message`` 即可处理文本消息。
88
+ 二进制消息默认拒绝(抛 ``WebSocketHandlerException``)。
89
+ """
90
+
91
+ async def handle_binary_message(self, session: WebSocketSession, data: bytes) -> None:
92
+ raise WebSocketHandlerException(
93
+ f"{type(self).__name__} 不支持二进制消息(覆盖 handle_binary_message 以启用)"
94
+ )
95
+
96
+
97
+ class BinaryWebSocketHandler(WebSocketHandler):
98
+ """二进制消息便捷基类(对齐 Spring ``BinaryWebSocketHandler``)。
99
+
100
+ 子类只需覆盖 ``handle_binary_message`` 即可处理二进制消息。
101
+ 文本消息默认拒绝。
102
+ """
103
+
104
+ async def handle_text_message(self, session: WebSocketSession, message: str) -> None:
105
+ raise WebSocketHandlerException(
106
+ f"{type(self).__name__} 不支持文本消息(覆盖 handle_text_message 以启用)"
107
+ )
108
+
109
+
110
+ # ==================== @ServerEndpoint 注解 ====================
111
+
112
+ class ServerEndpoint(SpringAnnotation):
113
+ """``@ServerEndpoint("/ws/echo")`` 类级注解(JSR-356 风格)。
114
+
115
+ 标注的类作为 WebSocket 端点,可定义以下生命周期方法(均为 ``async``):
116
+ - ``on_open(session)``:连接建立后调用。
117
+ - ``on_message(session, message)``:收到消息时调用(文本/二进制备用同名方法)。
118
+ - ``on_close(session, reason)``:连接关闭后调用。
119
+ - ``on_error(session, error)``:异常时调用。
120
+
121
+ 用法::
122
+
123
+ @ServerEndpoint("/ws/echo")
124
+ class EchoEndpoint:
125
+ async def on_open(self, session):
126
+ await session.send_text("welcome")
127
+ async def on_message(self, session, message):
128
+ await session.send_text("echo: " + message)
129
+ """
130
+
131
+ _annotation_type = "server_endpoint"
132
+
133
+ def __init__(self, value: str = "", subprotocols: Optional[List[str]] = None):
134
+ super().__init__(value=value, subprotocols=subprotocols or [])
135
+
136
+
137
+ # ==================== AnnotatedEndpointHandler ====================
138
+
139
+ class AnnotatedEndpointHandler(WebSocketHandler):
140
+ """把 ``@ServerEndpoint`` 标注的类适配到 ``WebSocketHandler`` 接口。
141
+
142
+ Args:
143
+ endpoint_cls: ``@ServerEndpoint`` 标注的类。
144
+ instance: 可选的预构造实例(用于 IoC 注入依赖);为 None 时用 ``endpoint_cls()``。
145
+ """
146
+
147
+ def __init__(self, endpoint_cls: Type, instance: Optional[Any] = None):
148
+ self._endpoint_cls = endpoint_cls
149
+ self._instance = instance # 延迟构造,按需创建
150
+
151
+ def _get_instance(self) -> Any:
152
+ if self._instance is None:
153
+ self._instance = self._endpoint_cls()
154
+ return self._instance
155
+
156
+ async def after_connection_established(self, session: WebSocketSession) -> None:
157
+ await self._call_lifecycle("on_open", session)
158
+
159
+ async def handle_text_message(self, session: WebSocketSession, message: str) -> None:
160
+ await self._call_lifecycle("on_message", session, message)
161
+
162
+ async def handle_binary_message(self, session: WebSocketSession, data: bytes) -> None:
163
+ # 优先 on_bytes,否则复用 on_message
164
+ instance = self._get_instance()
165
+ on_bytes = getattr(instance, "on_bytes", None)
166
+ if callable(on_bytes):
167
+ await self._invoke(on_bytes, session, data)
168
+ else:
169
+ await self._call_lifecycle("on_message", session, data)
170
+
171
+ async def handle_transport_error(self, session: WebSocketSession, exception: Exception) -> None:
172
+ await self._call_lifecycle("on_error", session, exception)
173
+
174
+ async def after_connection_closed(self, session: WebSocketSession, reason: str) -> None:
175
+ await self._call_lifecycle("on_close", session, reason)
176
+
177
+ async def _call_lifecycle(self, method_name: str, *args) -> None:
178
+ instance = self._get_instance()
179
+ method = getattr(instance, method_name, None)
180
+ if not callable(method):
181
+ return # 钩子未定义,跳过
182
+ await self._invoke(method, *args)
183
+
184
+ async def _invoke(self, method: Callable, *args) -> None:
185
+ try:
186
+ result = method(*args)
187
+ if inspect.isawaitable(result):
188
+ await result
189
+ except Exception as exc:
190
+ logger.warning(
191
+ "ServerEndpoint %s.%s 抛异常: %s",
192
+ self._endpoint_cls.__name__, method.__name__, exc
193
+ )
194
+ raise WebSocketHandlerException(str(exc)) from exc
195
+
196
+
197
+ # ==================== 端点发现 ====================
198
+
199
+ def discover_server_endpoints(
200
+ classes: Optional[Iterable[Type]] = None,
201
+ modules: Optional[Iterable[Any]] = None,
202
+ ) -> Dict[str, Type]:
203
+ """扫描 ``@ServerEndpoint`` 标注的类,返回 ``{path: endpoint_cls}``。
204
+
205
+ Args:
206
+ classes: 显式传入的类列表。
207
+ modules: 模块对象列表,扫描其 ``__dict__`` 中的类。
208
+
209
+ Returns:
210
+ ``{path: endpoint_cls}``;路径冲突时后者覆盖前者(最后声明者胜出)。
211
+ """
212
+ result: Dict[str, Type] = {}
213
+ candidates: List[Type] = []
214
+ if classes:
215
+ candidates.extend(classes)
216
+ if modules:
217
+ for mod in modules:
218
+ if mod is None:
219
+ continue
220
+ for attr in vars(mod).values():
221
+ if isinstance(attr, type) and getattr(attr, "__module__", "") == mod.__name__:
222
+ candidates.append(attr)
223
+ seen_ids = set()
224
+ for cls in candidates:
225
+ if id(cls) in seen_ids:
226
+ continue
227
+ seen_ids.add(id(cls))
228
+ annotations = getattr(cls, "__spring_annotations__", []) or []
229
+ for ann in annotations:
230
+ if isinstance(ann, ServerEndpoint) and ann.value:
231
+ result[ann.value] = cls
232
+ break
233
+ return result
234
+
235
+
236
+ __all__ = [
237
+ "WebSocketHandler",
238
+ "TextWebSocketHandler",
239
+ "BinaryWebSocketHandler",
240
+ "ServerEndpoint",
241
+ "AnnotatedEndpointHandler",
242
+ "discover_server_endpoints",
243
+ ]