aury-boot 0.0.4__py3-none-any.whl → 0.0.7__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 (122) hide show
  1. aury/boot/__init__.py +2 -2
  2. aury/boot/_version.py +2 -2
  3. aury/boot/application/__init__.py +60 -36
  4. aury/boot/application/adapter/__init__.py +112 -0
  5. aury/boot/application/adapter/base.py +511 -0
  6. aury/boot/application/adapter/config.py +242 -0
  7. aury/boot/application/adapter/decorators.py +259 -0
  8. aury/boot/application/adapter/exceptions.py +202 -0
  9. aury/boot/application/adapter/http.py +325 -0
  10. aury/boot/application/app/__init__.py +12 -8
  11. aury/boot/application/app/base.py +12 -0
  12. aury/boot/application/app/components.py +137 -44
  13. aury/boot/application/app/middlewares.py +9 -4
  14. aury/boot/application/app/startup.py +249 -0
  15. aury/boot/application/config/__init__.py +36 -1
  16. aury/boot/application/config/multi_instance.py +216 -0
  17. aury/boot/application/config/settings.py +398 -149
  18. aury/boot/application/constants/components.py +6 -0
  19. aury/boot/application/errors/handlers.py +17 -3
  20. aury/boot/application/middleware/logging.py +21 -120
  21. aury/boot/application/rpc/__init__.py +2 -2
  22. aury/boot/commands/__init__.py +30 -10
  23. aury/boot/commands/app.py +131 -1
  24. aury/boot/commands/docs.py +104 -17
  25. aury/boot/commands/generate.py +22 -22
  26. aury/boot/commands/init.py +68 -17
  27. aury/boot/commands/server/app.py +2 -3
  28. aury/boot/commands/templates/project/AGENTS.md.tpl +221 -0
  29. aury/boot/commands/templates/project/README.md.tpl +2 -2
  30. aury/boot/commands/templates/project/aury_docs/00-overview.md.tpl +59 -0
  31. aury/boot/commands/templates/project/aury_docs/01-model.md.tpl +184 -0
  32. aury/boot/commands/templates/project/aury_docs/02-repository.md.tpl +206 -0
  33. aury/boot/commands/templates/project/aury_docs/03-service.md.tpl +398 -0
  34. aury/boot/commands/templates/project/aury_docs/04-schema.md.tpl +95 -0
  35. aury/boot/commands/templates/project/aury_docs/05-api.md.tpl +116 -0
  36. aury/boot/commands/templates/project/aury_docs/06-exception.md.tpl +118 -0
  37. aury/boot/commands/templates/project/aury_docs/07-cache.md.tpl +122 -0
  38. aury/boot/commands/templates/project/aury_docs/08-scheduler.md.tpl +32 -0
  39. aury/boot/commands/templates/project/aury_docs/09-tasks.md.tpl +38 -0
  40. aury/boot/commands/templates/project/aury_docs/10-storage.md.tpl +115 -0
  41. aury/boot/commands/templates/project/aury_docs/11-logging.md.tpl +131 -0
  42. aury/boot/commands/templates/project/aury_docs/12-admin.md.tpl +56 -0
  43. aury/boot/commands/templates/project/aury_docs/13-channel.md.tpl +104 -0
  44. aury/boot/commands/templates/project/aury_docs/14-mq.md.tpl +102 -0
  45. aury/boot/commands/templates/project/aury_docs/15-events.md.tpl +147 -0
  46. aury/boot/commands/templates/project/aury_docs/16-adapter.md.tpl +403 -0
  47. aury/boot/commands/templates/project/{CLI.md.tpl → aury_docs/99-cli.md.tpl} +19 -19
  48. aury/boot/commands/templates/project/config.py.tpl +10 -10
  49. aury/boot/commands/templates/project/env_templates/_header.tpl +10 -0
  50. aury/boot/commands/templates/project/env_templates/admin.tpl +49 -0
  51. aury/boot/commands/templates/project/env_templates/cache.tpl +14 -0
  52. aury/boot/commands/templates/project/env_templates/database.tpl +22 -0
  53. aury/boot/commands/templates/project/env_templates/log.tpl +18 -0
  54. aury/boot/commands/templates/project/env_templates/messaging.tpl +46 -0
  55. aury/boot/commands/templates/project/env_templates/rpc.tpl +28 -0
  56. aury/boot/commands/templates/project/env_templates/scheduler.tpl +18 -0
  57. aury/boot/commands/templates/project/env_templates/service.tpl +18 -0
  58. aury/boot/commands/templates/project/env_templates/storage.tpl +38 -0
  59. aury/boot/commands/templates/project/env_templates/third_party.tpl +43 -0
  60. aury/boot/commands/templates/project/modules/tasks.py.tpl +1 -1
  61. aury/boot/common/logging/__init__.py +26 -674
  62. aury/boot/common/logging/context.py +132 -0
  63. aury/boot/common/logging/decorators.py +118 -0
  64. aury/boot/common/logging/format.py +315 -0
  65. aury/boot/common/logging/setup.py +214 -0
  66. aury/boot/contrib/admin_console/auth.py +2 -3
  67. aury/boot/contrib/admin_console/install.py +1 -1
  68. aury/boot/domain/models/mixins.py +48 -1
  69. aury/boot/domain/pagination/__init__.py +94 -0
  70. aury/boot/domain/repository/impl.py +1 -1
  71. aury/boot/domain/repository/interface.py +1 -1
  72. aury/boot/domain/transaction/__init__.py +8 -9
  73. aury/boot/infrastructure/__init__.py +86 -29
  74. aury/boot/infrastructure/cache/backends.py +102 -18
  75. aury/boot/infrastructure/cache/base.py +12 -0
  76. aury/boot/infrastructure/cache/manager.py +153 -91
  77. aury/boot/infrastructure/channel/__init__.py +24 -0
  78. aury/boot/infrastructure/channel/backends/__init__.py +9 -0
  79. aury/boot/infrastructure/channel/backends/memory.py +83 -0
  80. aury/boot/infrastructure/channel/backends/redis.py +88 -0
  81. aury/boot/infrastructure/channel/base.py +92 -0
  82. aury/boot/infrastructure/channel/manager.py +203 -0
  83. aury/boot/infrastructure/clients/__init__.py +22 -0
  84. aury/boot/infrastructure/clients/rabbitmq/__init__.py +9 -0
  85. aury/boot/infrastructure/clients/rabbitmq/config.py +46 -0
  86. aury/boot/infrastructure/clients/rabbitmq/manager.py +288 -0
  87. aury/boot/infrastructure/clients/redis/__init__.py +28 -0
  88. aury/boot/infrastructure/clients/redis/config.py +51 -0
  89. aury/boot/infrastructure/clients/redis/manager.py +264 -0
  90. aury/boot/infrastructure/database/config.py +7 -16
  91. aury/boot/infrastructure/database/manager.py +16 -38
  92. aury/boot/infrastructure/events/__init__.py +18 -21
  93. aury/boot/infrastructure/events/backends/__init__.py +11 -0
  94. aury/boot/infrastructure/events/backends/memory.py +86 -0
  95. aury/boot/infrastructure/events/backends/rabbitmq.py +193 -0
  96. aury/boot/infrastructure/events/backends/redis.py +162 -0
  97. aury/boot/infrastructure/events/base.py +127 -0
  98. aury/boot/infrastructure/events/manager.py +224 -0
  99. aury/boot/infrastructure/mq/__init__.py +24 -0
  100. aury/boot/infrastructure/mq/backends/__init__.py +9 -0
  101. aury/boot/infrastructure/mq/backends/rabbitmq.py +179 -0
  102. aury/boot/infrastructure/mq/backends/redis.py +167 -0
  103. aury/boot/infrastructure/mq/base.py +143 -0
  104. aury/boot/infrastructure/mq/manager.py +239 -0
  105. aury/boot/infrastructure/scheduler/manager.py +7 -3
  106. aury/boot/infrastructure/storage/__init__.py +9 -9
  107. aury/boot/infrastructure/storage/base.py +17 -5
  108. aury/boot/infrastructure/storage/factory.py +0 -1
  109. aury/boot/infrastructure/tasks/__init__.py +2 -2
  110. aury/boot/infrastructure/tasks/config.py +5 -13
  111. aury/boot/infrastructure/tasks/manager.py +55 -33
  112. {aury_boot-0.0.4.dist-info → aury_boot-0.0.7.dist-info}/METADATA +20 -2
  113. aury_boot-0.0.7.dist-info/RECORD +197 -0
  114. aury/boot/commands/templates/project/DEVELOPMENT.md.tpl +0 -1397
  115. aury/boot/commands/templates/project/env.example.tpl +0 -213
  116. aury/boot/infrastructure/events/bus.py +0 -362
  117. aury/boot/infrastructure/events/config.py +0 -52
  118. aury/boot/infrastructure/events/consumer.py +0 -134
  119. aury/boot/infrastructure/events/models.py +0 -63
  120. aury_boot-0.0.4.dist-info/RECORD +0 -137
  121. {aury_boot-0.0.4.dist-info → aury_boot-0.0.7.dist-info}/WHEEL +0 -0
  122. {aury_boot-0.0.4.dist-info → aury_boot-0.0.7.dist-info}/entry_points.txt +0 -0
@@ -0,0 +1,403 @@
1
+ # Adapter(第三方接口适配器)
2
+
3
+ ## 16.1 概述
4
+
5
+ Adapter 模块用于封装第三方接口(如支付、短信、微信等外部服务)的调用,支持在不同环境(开发、测试、生产)中灵活切换真实调用与 Mock 实现。
6
+
7
+ **核心特性**:
8
+ - 多模式支持:`real`(真实调用)、`sandbox`(沙箱环境)、`mock`(本地 Mock)、`disabled`(禁用)
9
+ - 方法级模式覆盖:同一 Adapter 的不同方法可以使用不同模式
10
+ - 装饰器式 Mock:使用 `.mock` 链式方法定义 Mock 逻辑
11
+ - 调用记录:测试时可追踪所有调用历史
12
+
13
+ ## 16.2 基础用法
14
+
15
+ **文件**: `{package_name}/adapters/payment_adapter.py`
16
+
17
+ ```python
18
+ """支付适配器。"""
19
+
20
+ from aury.boot.application.adapter import (
21
+ BaseAdapter,
22
+ AdapterSettings,
23
+ adapter_method,
24
+ )
25
+
26
+
27
+ class PaymentAdapter(BaseAdapter):
28
+ """支付第三方适配器。"""
29
+
30
+ @adapter_method("create_order")
31
+ async def create_order(self, amount: int, order_id: str) -> dict:
32
+ """创建支付订单(真实实现)。"""
33
+ # 真实调用第三方 API
34
+ response = await self.http_client.post(
35
+ "https://api.payment.com/orders",
36
+ json={"amount": amount, "order_id": order_id},
37
+ )
38
+ return response.json()
39
+
40
+ @create_order.mock
41
+ async def create_order_mock(self, amount: int, order_id: str) -> dict:
42
+ """创建支付订单(Mock 实现)。"""
43
+ if amount > 100000:
44
+ return {"success": False, "error": "金额超限"}
45
+ return {
46
+ "success": True,
47
+ "transaction_id": f"mock_tx_{order_id}",
48
+ "amount": amount,
49
+ }
50
+
51
+ @adapter_method("query_order")
52
+ async def query_order(self, transaction_id: str) -> dict:
53
+ """查询支付订单。"""
54
+ response = await self.http_client.get(
55
+ f"https://api.payment.com/orders/{transaction_id}"
56
+ )
57
+ return response.json()
58
+
59
+ @query_order.mock
60
+ async def query_order_mock(self, transaction_id: str) -> dict:
61
+ """查询支付订单(Mock)。"""
62
+ return {
63
+ "transaction_id": transaction_id,
64
+ "status": "paid",
65
+ "mock": True,
66
+ }
67
+ ```
68
+
69
+ ## 16.3 Adapter 配置
70
+
71
+ ### 环境变量配置
72
+
73
+ ```bash
74
+ # .env
75
+
76
+ # 全局模式:real / sandbox / mock / disabled
77
+ THIRD_PARTY__GATEWAY_MODE=mock
78
+
79
+ # 方法级模式覆盖(JSON 格式)
80
+ # 例如:query 方法使用 real,其他方法使用全局配置
81
+ THIRD_PARTY__METHOD_MODES={"query_order": "real"}
82
+
83
+ # Mock 策略:decorator(装饰器)/ auto(自动生成)
84
+ THIRD_PARTY__MOCK_STRATEGY=decorator
85
+
86
+ # 调试模式
87
+ THIRD_PARTY__DEBUG=true
88
+ ```
89
+
90
+ ### 代码配置
91
+
92
+ ```python
93
+ from aury.boot.application.adapter import AdapterSettings
94
+
95
+ # 方式 1:从环境变量加载
96
+ settings = AdapterSettings()
97
+
98
+ # 方式 2:代码显式配置
99
+ settings = AdapterSettings(
100
+ mode="mock",
101
+ method_modes={
102
+ "query_order": "real", # query_order 使用真实调用
103
+ "create_order": "mock", # create_order 使用 Mock
104
+ },
105
+ debug=True,
106
+ )
107
+
108
+ # 创建 Adapter 实例
109
+ adapter = PaymentAdapter("payment", settings)
110
+ ```
111
+
112
+ ## 16.4 使用 HttpAdapter
113
+
114
+ 对于 HTTP 类第三方 API,推荐使用 `HttpAdapter`:
115
+
116
+ ```python
117
+ from aury.boot.application.adapter import HttpAdapter, AdapterSettings, adapter_method
118
+
119
+
120
+ class WechatAdapter(HttpAdapter):
121
+ """微信 API 适配器。"""
122
+
123
+ def __init__(self, settings: AdapterSettings | None = None):
124
+ super().__init__(
125
+ name="wechat",
126
+ settings=settings,
127
+ base_url="https://api.weixin.qq.com",
128
+ timeout=30.0,
129
+ )
130
+
131
+ async def _prepare_headers(self, headers: dict | None) -> dict:
132
+ """添加认证头。"""
133
+ headers = await super()._prepare_headers(headers)
134
+ headers["Authorization"] = f"Bearer {await self._get_access_token()}"
135
+ return headers
136
+
137
+ @adapter_method("send_message")
138
+ async def send_message(self, openid: str, content: str) -> dict:
139
+ """发送消息。"""
140
+ return await self._request(
141
+ "POST",
142
+ "/cgi-bin/message/send",
143
+ json={"touser": openid, "content": content},
144
+ )
145
+
146
+ @send_message.mock
147
+ async def send_message_mock(self, openid: str, content: str) -> dict:
148
+ """发送消息(Mock)。"""
149
+ return {"errcode": 0, "errmsg": "ok", "mock": True}
150
+ ```
151
+
152
+ ## 16.5 方法级模式覆盖
153
+
154
+ 同一 Adapter 的不同方法可以使用不同模式:
155
+
156
+ ```python
157
+ settings = AdapterSettings(
158
+ mode="mock", # 默认 Mock
159
+ method_modes={
160
+ "query_order": "real", # 查询走真实接口
161
+ "create_order": "mock", # 创建走 Mock
162
+ "refund": "disabled", # 退款禁用
163
+ },
164
+ )
165
+
166
+ adapter = PaymentAdapter("payment", settings)
167
+
168
+ # query_order 会调用真实 API
169
+ result = await adapter.query_order("tx_123")
170
+
171
+ # create_order 会调用 Mock 方法
172
+ result = await adapter.create_order(100, "order_123")
173
+
174
+ # refund 会抛出 AdapterDisabledError
175
+ result = await adapter.refund("tx_123") # 抛出异常
176
+ ```
177
+
178
+ ## 16.6 测试中使用
179
+
180
+ ### 调用记录追踪
181
+
182
+ ```python
183
+ import pytest
184
+ from {package_name}.adapters.payment_adapter import PaymentAdapter
185
+ from aury.boot.application.adapter import AdapterSettings
186
+
187
+
188
+ @pytest.fixture
189
+ def payment_adapter():
190
+ settings = AdapterSettings(mode="mock")
191
+ return PaymentAdapter("payment", settings)
192
+
193
+
194
+ async def test_create_order(payment_adapter):
195
+ """测试创建订单。"""
196
+ result = await payment_adapter.create_order(100, "order_001")
197
+
198
+ assert result["success"] is True
199
+ assert result["mock"] is True
200
+
201
+ # 检查调用记录
202
+ history = payment_adapter.call_history
203
+ assert len(history) == 1
204
+ assert history[0].method == "create_order"
205
+ assert history[0].args == (100, "order_001")
206
+ assert history[0].result == result
207
+
208
+
209
+ async def test_amount_limit(payment_adapter):
210
+ """测试金额超限。"""
211
+ result = await payment_adapter.create_order(200000, "order_002")
212
+
213
+ assert result["success"] is False
214
+ assert "超限" in result["error"]
215
+
216
+
217
+ async def test_clear_history(payment_adapter):
218
+ """测试清除调用记录。"""
219
+ await payment_adapter.create_order(100, "order_001")
220
+ await payment_adapter.query_order("tx_001")
221
+
222
+ assert len(payment_adapter.call_history) == 2
223
+
224
+ payment_adapter.clear_history()
225
+ assert len(payment_adapter.call_history) == 0
226
+ ```
227
+
228
+ ## 16.7 高级用法
229
+
230
+ ### 钩子方法
231
+
232
+ ```python
233
+ class PaymentAdapter(HttpAdapter):
234
+ """带钩子的支付适配器。"""
235
+
236
+ async def _on_before_call(
237
+ self, method: str, args: tuple, kwargs: dict
238
+ ) -> None:
239
+ """调用前钩子。"""
240
+ logger.info(f"调用 {method},参数: {args}")
241
+
242
+ async def _on_after_call(
243
+ self, method: str, args: tuple, kwargs: dict, result: Any
244
+ ) -> None:
245
+ """调用后钩子。"""
246
+ logger.info(f"{method} 返回: {result}")
247
+
248
+ async def _on_call_error(
249
+ self, method: str, args: tuple, kwargs: dict, error: Exception
250
+ ) -> None:
251
+ """调用异常钩子。"""
252
+ logger.error(f"{method} 异常: {error}")
253
+ # 可以在这里发送告警
254
+ ```
255
+
256
+ ### 复合适配器
257
+
258
+ ```python
259
+ class CompositePaymentAdapter(BaseAdapter):
260
+ """组合多个支付渠道。"""
261
+
262
+ def __init__(self, settings: AdapterSettings | None = None):
263
+ super().__init__("composite_payment", settings)
264
+ self.alipay = AlipayAdapter(settings)
265
+ self.wechat = WechatAdapter(settings)
266
+
267
+ @adapter_method("pay")
268
+ async def pay(self, channel: str, amount: int, order_id: str) -> dict:
269
+ """根据渠道选择支付方式。"""
270
+ if channel == "alipay":
271
+ return await self.alipay.create_order(amount, order_id)
272
+ elif channel == "wechat":
273
+ return await self.wechat.create_order(amount, order_id)
274
+ else:
275
+ raise ValueError(f"不支持的支付渠道: {channel}")
276
+
277
+ @pay.mock
278
+ async def pay_mock(self, channel: str, amount: int, order_id: str) -> dict:
279
+ """统一 Mock 实现。"""
280
+ return {
281
+ "success": True,
282
+ "channel": channel,
283
+ "transaction_id": f"mock_{channel}_{order_id}",
284
+ }
285
+ ```
286
+
287
+ ## 16.8 异常处理
288
+
289
+ ```python
290
+ from aury.boot.application.adapter import (
291
+ AdapterError,
292
+ AdapterDisabledError,
293
+ AdapterTimeoutError,
294
+ AdapterValidationError,
295
+ )
296
+
297
+ try:
298
+ result = await adapter.create_order(100, "order_001")
299
+ except AdapterDisabledError:
300
+ logger.warning("支付适配器已禁用")
301
+ # 降级处理
302
+ except AdapterTimeoutError:
303
+ logger.error("支付适配器超时")
304
+ # 重试或告警
305
+ except AdapterValidationError as e:
306
+ logger.error(f"参数校验失败: {e}")
307
+ except AdapterError as e:
308
+ logger.error(f"适配器错误: {e}")
309
+ ```
310
+
311
+ ## 16.9 最佳实践
312
+
313
+ ### 1. Adapter 放置位置
314
+
315
+ ```
316
+ {package_name}/
317
+ ├── adapters/ # 第三方适配器
318
+ │ ├── __init__.py
319
+ │ ├── payment_adapter.py # 支付适配器
320
+ │ ├── sms_adapter.py # 短信适配器
321
+ │ └── wechat_adapter.py # 微信适配器
322
+ ```
323
+
324
+ ### 2. Mock 逻辑应覆盖边界情况
325
+
326
+ ```python
327
+ @create_order.mock
328
+ async def create_order_mock(self, amount: int, order_id: str) -> dict:
329
+ """Mock 应模拟各种场景。"""
330
+ # 模拟金额校验
331
+ if amount <= 0:
332
+ return {"success": False, "error": "金额必须大于0"}
333
+ if amount > 100000:
334
+ return {"success": False, "error": "金额超限"}
335
+
336
+ # 模拟偶发失败(可选)
337
+ import random
338
+ if random.random() < 0.01:
339
+ return {"success": False, "error": "系统繁忙"}
340
+
341
+ return {"success": True, "transaction_id": f"mock_{order_id}"}
342
+ ```
343
+
344
+ ### 3. 环境配置建议
345
+
346
+ ```bash
347
+ # 开发环境 (.env.development)
348
+ THIRD_PARTY__GATEWAY_MODE=mock
349
+ THIRD_PARTY__DEBUG=true
350
+
351
+ # 测试环境 (.env.testing)
352
+ THIRD_PARTY__GATEWAY_MODE=mock
353
+ THIRD_PARTY__METHOD_MODES={"query": "sandbox"}
354
+
355
+ # 生产环境 (.env.production)
356
+ THIRD_PARTY__GATEWAY_MODE=real
357
+ THIRD_PARTY__DEBUG=false
358
+ ```
359
+
360
+ ### 4. 在 Service 中使用
361
+
362
+ ```python
363
+ from sqlalchemy.ext.asyncio import AsyncSession
364
+
365
+ from aury.boot.domain.service.base import BaseService
366
+ from aury.boot.domain.transaction import transactional
367
+
368
+ from {package_name}.adapters.payment_adapter import PaymentAdapter
369
+ from {package_name}.repositories.order_repository import OrderRepository
370
+
371
+
372
+ class OrderService(BaseService):
373
+ """订单服务。"""
374
+
375
+ def __init__(self, session: AsyncSession, payment: PaymentAdapter):
376
+ super().__init__(session)
377
+ self.order_repo = OrderRepository(session)
378
+ self.payment = payment
379
+
380
+ @transactional
381
+ async def create_order(self, user_id: str, amount: int) -> Order:
382
+ """创建订单并发起支付。"""
383
+ # 1. 创建订单记录
384
+ order = await self.order_repo.create({
385
+ "user_id": user_id,
386
+ "amount": amount,
387
+ "status": "pending",
388
+ })
389
+
390
+ # 2. 调用支付适配器
391
+ pay_result = await self.payment.create_order(amount, str(order.id))
392
+
393
+ if not pay_result["success"]:
394
+ raise PaymentError(pay_result["error"])
395
+
396
+ # 3. 更新订单状态
397
+ await self.order_repo.update(order, {
398
+ "transaction_id": pay_result["transaction_id"],
399
+ "status": "paid",
400
+ })
401
+
402
+ return order
403
+ ```
@@ -36,10 +36,10 @@ aury generate schema user # Pydantic Schema
36
36
  aury generate model user --fields "name:str,email:str,age:int"
37
37
 
38
38
  # 指定模型基类
39
- aury generate model user --base UUIDAuditableStateModel # UUID主键 + 软删除(推荐)
40
- aury generate model user --base UUIDModel # UUID主键 + 时间戳
39
+ aury generate model user --base AuditableStateModel # int主键 + 软删除(推荐)
41
40
  aury generate model user --base Model # int主键 + 时间戳
42
- aury generate model user --base VersionedUUIDModel # UUID + 乐观锁 + 时间戳
41
+ aury generate model user --base FullFeaturedModel # int主键 + 全功能
42
+ aury generate model user --base UUIDAuditableStateModel # UUID主键(如需要)
43
43
  ```
44
44
 
45
45
  ## 数据库迁移
@@ -65,13 +65,13 @@ aury worker # 运行 Dramatiq Worker
65
65
 
66
66
  | 变量 | 说明 | 默认值 |
67
67
  |------|------|--------|
68
- | `DATABASE_URL` | 数据库连接 URL | `sqlite+aiosqlite:///./dev.db` |
69
- | `CACHE_TYPE` | 缓存类型 (memory/redis) | `memory` |
70
- | `CACHE_URL` | Redis URL | - |
71
- | `LOG_LEVEL` | 日志级别 | `INFO` |
72
- | `LOG_DIR` | 日志目录 | `logs` |
73
- | `SCHEDULER_ENABLED` | 启用内嵌调度器 | `true` |
74
- | `TASK_BROKER_URL` | 任务队列 Broker URL | - |
68
+ | `DATABASE__URL` | 数据库连接 URL | `sqlite+aiosqlite:///./dev.db` |
69
+ | `CACHE__CACHE_TYPE` | 缓存类型 (memory/redis) | `memory` |
70
+ | `CACHE__URL` | Redis URL | - |
71
+ | `LOG__LEVEL` | 日志级别 | `INFO` |
72
+ | `LOG__DIR` | 日志目录 | `logs` |
73
+ | `SCHEDULER__ENABLED` | 启用内嵌调度器 | `true` |
74
+ | `TASK__BROKER_URL` | 任务队列 Broker URL | - |
75
75
 
76
76
  ## 管理后台(Admin Console)
77
77
 
@@ -81,12 +81,12 @@ aury worker # 运行 Dramatiq Worker
81
81
 
82
82
  | 变量 | 说明 | 默认值 |
83
83
  |------|------|--------|
84
- | `ADMIN_ENABLED` | 是否启用管理后台 | `false` |
85
- | `ADMIN_PATH` | 管理后台路径 | `/api/admin-console` |
86
- | `ADMIN_DATABASE_URL` | 管理后台同步数据库 URL(可覆盖自动推导) | - |
87
- | `ADMIN_AUTH_MODE` | 认证模式(basic/bearer/none/custom/jwt) | `basic` |
88
- | `ADMIN_AUTH_SECRET_KEY` | session 签名密钥(生产必配) | - |
89
- | `ADMIN_AUTH_BASIC_USERNAME` | basic 用户名 | - |
90
- | `ADMIN_AUTH_BASIC_PASSWORD` | basic 密码 | - |
91
- | `ADMIN_AUTH_BEARER_TOKENS` | bearer token 白名单 | `[]` |
92
- | `ADMIN_AUTH_BACKEND` | 自定义认证后端导入路径(module:attr) | - |
84
+ | `ADMIN__ENABLED` | 是否启用管理后台 | `false` |
85
+ | `ADMIN__PATH` | 管理后台路径 | `/api/admin-console` |
86
+ | `ADMIN__DATABASE_URL` | 管理后台同步数据库 URL(可覆盖自动推导) | - |
87
+ | `ADMIN__AUTH_MODE` | 认证模式(basic/bearer/none/custom/jwt) | `basic` |
88
+ | `ADMIN__AUTH_SECRET_KEY` | session 签名密钥(生产必配) | - |
89
+ | `ADMIN__AUTH_BASIC_USERNAME` | basic 用户名 | - |
90
+ | `ADMIN__AUTH_BASIC_PASSWORD` | basic 密码 | - |
91
+ | `ADMIN__AUTH_BEARER_TOKENS` | bearer token 白名单 | `[]` |
92
+ | `ADMIN__AUTH_BACKEND` | 自定义认证后端导入路径(module:attr) | - |
@@ -2,11 +2,11 @@
2
2
 
3
3
  配置优先级:命令行参数 > 环境变量 > .env 文件 > 默认值
4
4
 
5
- 环境变量示例:
6
- DATABASE_URL=postgresql+asyncpg://user:pass@localhost:5432/mydb
7
- CACHE_TYPE=redis
8
- CACHE_REDIS_URL=redis://localhost:6379/0
9
- LOG_LEVEL=INFO
5
+ 环境变量格式(使用双下划线分层):
6
+ DATABASE__URL=postgresql+asyncpg://user:pass@localhost:5432/mydb
7
+ CACHE__CACHE_TYPE=redis
8
+ CACHE__URL=redis://localhost:6379/0
9
+ LOG__LEVEL=INFO
10
10
  """
11
11
 
12
12
  from aury.boot.application.config import BaseConfig
@@ -16,11 +16,11 @@ class AppConfig(BaseConfig):
16
16
  """{project_name} 配置。
17
17
 
18
18
  继承 BaseConfig 获得所有默认配置项:
19
- - server: 服务器配置
20
- - database: 数据库配置
21
- - cache: 缓存配置
22
- - log: 日志配置
23
- - migration: 迁移配置
19
+ - server: 服务器配置 (SERVER__*)
20
+ - database: 数据库配置 (DATABASE__*)
21
+ - cache: 缓存配置 (CACHE__*)
22
+ - log: 日志配置 (LOG__*)
23
+ - migration: 迁移配置 (MIGRATION__*)
24
24
 
25
25
  可以在这里添加自定义配置项。
26
26
  """
@@ -0,0 +1,10 @@
1
+ # =============================================================================
2
+ # {project_name} 环境变量配置
3
+ # =============================================================================
4
+ # 复制此文件为 .env 并根据实际情况修改
5
+ # 所有配置项均有默认值,只需取消注释并修改需要覆盖的项
6
+ #
7
+ # 环境变量格式说明:
8
+ # - 使用双下划线 (__) 作为层级分隔符
9
+ # - 单实例: {{SECTION}}__{{FIELD}}=value
10
+ # - 多实例: {{SECTION}}__{{INSTANCE}}__{{FIELD}}=value
@@ -0,0 +1,49 @@
1
+
2
+ # =============================================================================
3
+ # 健康检查配置 (HEALTH_CHECK__)
4
+ # =============================================================================
5
+ # 健康检查端点路径
6
+ # HEALTH_CHECK__PATH=/api/health
7
+ # 是否启用健康检查端点
8
+ # HEALTH_CHECK__ENABLED=true
9
+
10
+ # =============================================================================
11
+ # CORS 配置 (CORS__)
12
+ # =============================================================================
13
+ # 允许的 CORS 源(生产环境应设置具体域名)
14
+ # CORS__ORIGINS=["*"]
15
+ # 是否允许 CORS 凭据
16
+ # CORS__ALLOW_CREDENTIALS=true
17
+ # 允许的 CORS 方法
18
+ # CORS__ALLOW_METHODS=["*"]
19
+ # 允许的 CORS 头
20
+ # CORS__ALLOW_HEADERS=["*"]
21
+
22
+ # =============================================================================
23
+ # 管理后台配置 (ADMIN__) - SQLAdmin Admin Console
24
+ # =============================================================================
25
+ # 是否启用管理后台(生产建议仅内网或配合反向代理)
26
+ # ADMIN__ENABLED=false
27
+ # 管理后台路径(默认 /api/admin-console,避免与业务 URL 冲突)
28
+ # ADMIN__PATH=/api/admin-console
29
+ #
30
+ # SQLAdmin 通常要求同步 SQLAlchemy Engine:
31
+ # - 若 DATABASE__URL 使用的是异步驱动(如 postgresql+asyncpg),建议显式提供同步 URL 覆盖
32
+ # ADMIN__DATABASE_URL=postgresql+psycopg://user:pass@localhost:5432/{project_name_snake}
33
+ #
34
+ # 可选:显式指定项目侧模块(用于注册 views/auth)
35
+ # ADMIN__VIEWS_MODULE={project_name_snake}.admin_console
36
+ #
37
+ # 认证配置 (嵌套格式: ADMIN__AUTH__{{FIELD}})
38
+ # ADMIN__AUTH__MODE=basic
39
+ # ADMIN__AUTH__SECRET_KEY=CHANGE_ME_TO_A_RANDOM_SECRET
40
+ #
41
+ # basic:登录页用户名/密码
42
+ # ADMIN__AUTH__BASIC_USERNAME=admin
43
+ # ADMIN__AUTH__BASIC_PASSWORD=change_me
44
+ #
45
+ # bearer:token 白名单(也支持在登录页输入 token)
46
+ # ADMIN__AUTH__BEARER_TOKENS=["change_me_token"]
47
+ #
48
+ # custom/jwt:自定义认证后端(动态导入)
49
+ # ADMIN__AUTH__BACKEND=yourpkg.admin_auth:backend
@@ -0,0 +1,14 @@
1
+
2
+ # =============================================================================
3
+ # 缓存配置 (CACHE__)
4
+ # =============================================================================
5
+ # 单实例配置:
6
+ # CACHE__CACHE_TYPE=memory
7
+ # CACHE__URL=redis://localhost:6379/0
8
+ # CACHE__MAX_SIZE=1000
9
+
10
+ # 多实例配置 (格式: CACHE__{{INSTANCE}}__{{FIELD}}):
11
+ # CACHE__DEFAULT__BACKEND=memory
12
+ # CACHE__DEFAULT__MAX_SIZE=1000
13
+ # CACHE__SESSION__BACKEND=redis
14
+ # CACHE__SESSION__URL=redis://localhost:6379/2
@@ -0,0 +1,22 @@
1
+
2
+ # =============================================================================
3
+ # 数据库配置 (DATABASE__)
4
+ # =============================================================================
5
+ # 单实例配置:
6
+ # DATABASE__URL=sqlite+aiosqlite:///./dev.db
7
+ # PostgreSQL: postgresql+asyncpg://user:pass@localhost:5432/{project_name_snake}
8
+ # MySQL: mysql+aiomysql://user:pass@localhost:3306/{project_name_snake}
9
+
10
+ # 连接池配置
11
+ # DATABASE__POOL_SIZE=5
12
+ # DATABASE__MAX_OVERFLOW=10
13
+ # DATABASE__POOL_RECYCLE=3600
14
+ # DATABASE__POOL_TIMEOUT=30
15
+ # DATABASE__POOL_PRE_PING=true
16
+ # DATABASE__ECHO=false
17
+
18
+ # 多实例配置 (格式: DATABASE__{{INSTANCE}}__{{FIELD}}):
19
+ # DATABASE__DEFAULT__URL=postgresql+asyncpg://user:pass@localhost:5432/{project_name_snake}
20
+ # DATABASE__DEFAULT__POOL_SIZE=5
21
+ # DATABASE__READONLY__URL=postgresql+asyncpg://user:pass@replica:5432/{project_name_snake}
22
+ # DATABASE__READONLY__POOL_SIZE=10
@@ -0,0 +1,18 @@
1
+
2
+ # =============================================================================
3
+ # 日志配置 (LOG__)
4
+ # =============================================================================
5
+ # 日志级别: DEBUG / INFO / WARNING / ERROR / CRITICAL
6
+ # LOG__LEVEL=INFO
7
+ # 日志文件目录
8
+ # LOG__DIR=logs
9
+ # 日志文件轮转时间 (HH:MM 格式)
10
+ # LOG__ROTATION_TIME=00:00
11
+ # 日志文件轮转大小阈值
12
+ # LOG__ROTATION_SIZE=100 MB
13
+ # 日志文件保留天数
14
+ # LOG__RETENTION_DAYS=7
15
+ # 是否启用日志文件轮转
16
+ # LOG__ENABLE_FILE_ROTATION=true
17
+ # 是否输出日志到控制台
18
+ # LOG__ENABLE_CONSOLE=true
@@ -0,0 +1,46 @@
1
+
2
+ # =============================================================================
3
+ # 流式通道配置 (CHANNEL__) - SSE/实时通信
4
+ # =============================================================================
5
+ # 多实例配置 (格式: CHANNEL__{{INSTANCE}}__{{FIELD}}):
6
+ # CHANNEL__DEFAULT__BACKEND=memory
7
+ # CHANNEL__SHARED__BACKEND=redis
8
+ # CHANNEL__SHARED__URL=redis://localhost:6379/3
9
+ # CHANNEL__SHARED__KEY_PREFIX=channel:
10
+ # CHANNEL__SHARED__TTL=86400
11
+
12
+ # =============================================================================
13
+ # 消息队列配置 (MQ__)
14
+ # =============================================================================
15
+ # 单实例配置:
16
+ # MQ__ENABLED=false
17
+ # MQ__BROKER_URL=redis://localhost:6379/4
18
+
19
+ # 多实例配置 (格式: MQ__{{INSTANCE}}__{{FIELD}}):
20
+ # MQ__DEFAULT__BACKEND=redis
21
+ # MQ__DEFAULT__URL=redis://localhost:6379/4
22
+ # MQ__DEFAULT__MAX_CONNECTIONS=10
23
+ #
24
+ # RabbitMQ 后端:
25
+ # MQ__ORDERS__BACKEND=rabbitmq
26
+ # MQ__ORDERS__URL=amqp://guest:guest@localhost:5672/orders
27
+ # MQ__ORDERS__PREFETCH_COUNT=10
28
+
29
+ # =============================================================================
30
+ # 事件总线配置 (EVENT__)
31
+ # =============================================================================
32
+ # 单实例配置:
33
+ # EVENT__BROKER_URL=
34
+ # EVENT__EXCHANGE_NAME=aury.events
35
+
36
+ # 多实例配置 (格式: EVENT__{{INSTANCE}}__{{FIELD}}):
37
+ # EVENT__DEFAULT__BACKEND=memory
38
+ # EVENT__DISTRIBUTED__BACKEND=redis
39
+ # EVENT__DISTRIBUTED__URL=redis://localhost:6379/5
40
+ # EVENT__DISTRIBUTED__KEY_PREFIX=events:
41
+ #
42
+ # RabbitMQ 后端:
43
+ # EVENT__DOMAIN__BACKEND=rabbitmq
44
+ # EVENT__DOMAIN__URL=amqp://guest:guest@localhost:5672/
45
+ # EVENT__DOMAIN__EXCHANGE_NAME=domain.events
46
+ # EVENT__DOMAIN__EXCHANGE_TYPE=topic
@@ -0,0 +1,28 @@
1
+
2
+ # =============================================================================
3
+ # RPC 客户端配置 (RPC_CLIENT__)
4
+ # =============================================================================
5
+ # 服务地址映射 {service_name: url}
6
+ # RPC_CLIENT__SERVICES={"user-service": "http://localhost:8001"}
7
+ # 默认超时时间(秒)
8
+ # RPC_CLIENT__DEFAULT_TIMEOUT=30
9
+ # 默认重试次数
10
+ # RPC_CLIENT__DEFAULT_RETRY_TIMES=3
11
+ # DNS 解析使用的协议
12
+ # RPC_CLIENT__DNS_SCHEME=http
13
+ # DNS 解析默认端口
14
+ # RPC_CLIENT__DNS_PORT=80
15
+ # 是否使用 DNS 回退(K8s/Docker Compose 自动 DNS)
16
+ # RPC_CLIENT__USE_DNS_FALLBACK=true
17
+
18
+ # =============================================================================
19
+ # RPC 服务注册配置 (RPC_SERVICE__)
20
+ # =============================================================================
21
+ # 服务名称(用于注册)
22
+ # RPC_SERVICE__NAME={project_name_snake}
23
+ # 服务地址(用于注册)
24
+ # RPC_SERVICE__URL=http://localhost:8000
25
+ # 健康检查 URL(用于注册)
26
+ # RPC_SERVICE__HEALTH_CHECK_URL=http://localhost:8000/api/health
27
+ # 是否自动注册到服务注册中心
28
+ # RPC_SERVICE__AUTO_REGISTER=false