fastapi-augment 0.1.0__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 (70) hide show
  1. fastapi_augment-0.1.0/PKG-INFO +654 -0
  2. fastapi_augment-0.1.0/README.md +620 -0
  3. fastapi_augment-0.1.0/VERSION +1 -0
  4. fastapi_augment-0.1.0/pyproject.toml +85 -0
  5. fastapi_augment-0.1.0/setup.cfg +4 -0
  6. fastapi_augment-0.1.0/src/fastapi_augment/__init__.py +24 -0
  7. fastapi_augment-0.1.0/src/fastapi_augment/common/__init__.py +61 -0
  8. fastapi_augment-0.1.0/src/fastapi_augment/common/constants.py +26 -0
  9. fastapi_augment-0.1.0/src/fastapi_augment/common/exception_handlers.py +178 -0
  10. fastapi_augment-0.1.0/src/fastapi_augment/common/exceptions.py +162 -0
  11. fastapi_augment-0.1.0/src/fastapi_augment/common/utils/__init__.py +5 -0
  12. fastapi_augment-0.1.0/src/fastapi_augment/common/utils/strings.py +175 -0
  13. fastapi_augment-0.1.0/src/fastapi_augment/config/__init__.py +8 -0
  14. fastapi_augment-0.1.0/src/fastapi_augment/config/settings.py +104 -0
  15. fastapi_augment-0.1.0/src/fastapi_augment/db/__init__.py +5 -0
  16. fastapi_augment-0.1.0/src/fastapi_augment/db/sqlalchemy/__init__.py +20 -0
  17. fastapi_augment-0.1.0/src/fastapi_augment/db/sqlalchemy/alembic/__init__.py +5 -0
  18. fastapi_augment-0.1.0/src/fastapi_augment/db/sqlalchemy/alembic/env.py +141 -0
  19. fastapi_augment-0.1.0/src/fastapi_augment/db/sqlalchemy/base.py +9 -0
  20. fastapi_augment-0.1.0/src/fastapi_augment/db/sqlalchemy/crud_base.py +426 -0
  21. fastapi_augment-0.1.0/src/fastapi_augment/db/sqlalchemy/engine.py +238 -0
  22. fastapi_augment-0.1.0/src/fastapi_augment/db/sqlalchemy/migrate.py +356 -0
  23. fastapi_augment-0.1.0/src/fastapi_augment/db/sqlalchemy/mixins/__init__.py +18 -0
  24. fastapi_augment-0.1.0/src/fastapi_augment/db/sqlalchemy/mixins/audit.py +61 -0
  25. fastapi_augment-0.1.0/src/fastapi_augment/db/sqlalchemy/mixins/soft_delete.py +80 -0
  26. fastapi_augment-0.1.0/src/fastapi_augment/db/sqlalchemy/mixins/timestamp.py +48 -0
  27. fastapi_augment-0.1.0/src/fastapi_augment/db/sqlalchemy/model_base.py +47 -0
  28. fastapi_augment-0.1.0/src/fastapi_augment/db/sqlalchemy/session.py +160 -0
  29. fastapi_augment-0.1.0/src/fastapi_augment/factory.py +238 -0
  30. fastapi_augment-0.1.0/src/fastapi_augment/health/__init__.py +34 -0
  31. fastapi_augment-0.1.0/src/fastapi_augment/health/checker.py +101 -0
  32. fastapi_augment-0.1.0/src/fastapi_augment/health/checkers.py +109 -0
  33. fastapi_augment-0.1.0/src/fastapi_augment/health/router.py +87 -0
  34. fastapi_augment-0.1.0/src/fastapi_augment/lifespan.py +450 -0
  35. fastapi_augment-0.1.0/src/fastapi_augment/log/__init__.py +26 -0
  36. fastapi_augment-0.1.0/src/fastapi_augment/log/config.py +201 -0
  37. fastapi_augment-0.1.0/src/fastapi_augment/log/factory.py +32 -0
  38. fastapi_augment-0.1.0/src/fastapi_augment/log/filters.py +23 -0
  39. fastapi_augment-0.1.0/src/fastapi_augment/log/handlers.py +81 -0
  40. fastapi_augment-0.1.0/src/fastapi_augment/middlewares/__init__.py +20 -0
  41. fastapi_augment-0.1.0/src/fastapi_augment/middlewares/base.py +79 -0
  42. fastapi_augment-0.1.0/src/fastapi_augment/middlewares/request_id.py +82 -0
  43. fastapi_augment-0.1.0/src/fastapi_augment/openapi.py +110 -0
  44. fastapi_augment-0.1.0/src/fastapi_augment/py.typed +0 -0
  45. fastapi_augment-0.1.0/src/fastapi_augment/schemas/__init__.py +29 -0
  46. fastapi_augment-0.1.0/src/fastapi_augment/schemas/base.py +32 -0
  47. fastapi_augment-0.1.0/src/fastapi_augment/schemas/pagination.py +46 -0
  48. fastapi_augment-0.1.0/src/fastapi_augment/schemas/request.py +28 -0
  49. fastapi_augment-0.1.0/src/fastapi_augment/schemas/response.py +139 -0
  50. fastapi_augment-0.1.0/src/fastapi_augment/schemas/types.py +11 -0
  51. fastapi_augment-0.1.0/src/fastapi_augment.egg-info/PKG-INFO +654 -0
  52. fastapi_augment-0.1.0/src/fastapi_augment.egg-info/SOURCES.txt +68 -0
  53. fastapi_augment-0.1.0/src/fastapi_augment.egg-info/dependency_links.txt +1 -0
  54. fastapi_augment-0.1.0/src/fastapi_augment.egg-info/entry_points.txt +2 -0
  55. fastapi_augment-0.1.0/src/fastapi_augment.egg-info/requires.txt +18 -0
  56. fastapi_augment-0.1.0/src/fastapi_augment.egg-info/top_level.txt +1 -0
  57. fastapi_augment-0.1.0/tests/test_config.py +229 -0
  58. fastapi_augment-0.1.0/tests/test_constants.py +41 -0
  59. fastapi_augment-0.1.0/tests/test_db_crud.py +348 -0
  60. fastapi_augment-0.1.0/tests/test_db_engine.py +218 -0
  61. fastapi_augment-0.1.0/tests/test_db_session_models.py +182 -0
  62. fastapi_augment-0.1.0/tests/test_exception_handlers.py +315 -0
  63. fastapi_augment-0.1.0/tests/test_exceptions.py +133 -0
  64. fastapi_augment-0.1.0/tests/test_factory.py +239 -0
  65. fastapi_augment-0.1.0/tests/test_health.py +211 -0
  66. fastapi_augment-0.1.0/tests/test_lifespan.py +337 -0
  67. fastapi_augment-0.1.0/tests/test_log.py +343 -0
  68. fastapi_augment-0.1.0/tests/test_middlewares.py +211 -0
  69. fastapi_augment-0.1.0/tests/test_openapi.py +131 -0
  70. fastapi_augment-0.1.0/tests/test_schemas.py +268 -0
@@ -0,0 +1,654 @@
1
+ Metadata-Version: 2.4
2
+ Name: fastapi-augment
3
+ Version: 0.1.0
4
+ Summary: FastAPI 通用代码工具包,跨项目复用
5
+ Author-email: zarkhan <hanguangzheng@qq.com>
6
+ License-Expression: MIT
7
+ Keywords: fastapi,fastapi-augment,augment,web,framework,async
8
+ Classifier: Development Status :: 3 - Alpha
9
+ Classifier: Framework :: FastAPI
10
+ Classifier: Intended Audience :: Developers
11
+ Classifier: Programming Language :: Python :: 3
12
+ Classifier: Programming Language :: Python :: 3.11
13
+ Classifier: Programming Language :: Python :: 3.12
14
+ Classifier: Programming Language :: Python :: 3.13
15
+ Classifier: Programming Language :: Python :: 3.14
16
+ Classifier: Topic :: Internet :: WWW/HTTP
17
+ Classifier: Topic :: Software Development :: Libraries :: Application Frameworks
18
+ Classifier: Typing :: Typed
19
+ Requires-Python: >=3.11
20
+ Description-Content-Type: text/markdown
21
+ Requires-Dist: fastapi>=0.141.1
22
+ Provides-Extra: uvicorn
23
+ Requires-Dist: uvicorn[standard]>=0.24.0; extra == "uvicorn"
24
+ Provides-Extra: sqlalchemy
25
+ Requires-Dist: sqlalchemy[asyncio]>=2.0.52; extra == "sqlalchemy"
26
+ Requires-Dist: python-ulid>=4.0.1; extra == "sqlalchemy"
27
+ Requires-Dist: alembic>=1.19.2; extra == "sqlalchemy"
28
+ Provides-Extra: orjson
29
+ Requires-Dist: orjson>=3.10.0; extra == "orjson"
30
+ Provides-Extra: config
31
+ Requires-Dist: pydantic-settings>=2.15.0; extra == "config"
32
+ Provides-Extra: standard
33
+ Requires-Dist: fastapi-augment[config,orjson,sqlalchemy,uvicorn]; extra == "standard"
34
+
35
+ # fastapi-augment
36
+
37
+ 跨项目复用的 FastAPI 通用代码工具包,将多个项目中反复用到的应用工厂、生命周期管理、读写分离数据库层、通用 Mixin、统一响应模型与 HTTP 异常体系统一封装,开箱即用。
38
+
39
+ ## 特性
40
+
41
+ - **应用工厂** — 一行代码创建 FastAPI 实例,自动装配中间件、路由、生命周期与数据库
42
+ - **生命周期管理** — 多注册表、优先级、超时控制、异常策略的启动/关闭钩子
43
+ - **读写分离** — 单库 / 主从 / 集群拓扑的异步引擎管理,Session 自动路由
44
+ - **泛型 CRUD** — 类型安全的异步 CRUD 仓库,支持关键字过滤与原生表达式
45
+ - **可组合 Mixin** — 时间戳、审计、软删除等列混入,自由组合
46
+ - **统一响应** — 全局 `APIResponse` 格式,自动追踪 `request_id`
47
+ - **HTTP 异常** — 完整的 4xx 异常子类,内置默认文案
48
+ - **OpenAPI 优化** — 自动清理 422 响应、可选 Bearer 认证
49
+ - **日志管理** — request_id 自动注入、uvicorn 接管、多进程安全轮转、一键配置
50
+ - **健康检查** — 可扩展的检查器模式,内置应用状态与数据库连通性检查,一行开关
51
+ - **配置管理** — 基于 pydantic-settings,支持 `.env` 文件、环境变量前缀、嵌套配置
52
+ - **数据库迁移 CLI** — 一行命令生成/执行迁移,自动发现用户模型
53
+
54
+ ## 安装
55
+
56
+ ```bash
57
+ pip install fastapi-augment
58
+
59
+ # 推荐:安装全部可选依赖
60
+ pip install fastapi-augment[standard]
61
+
62
+ # 或按需单独安装
63
+ pip install fastapi-augment[sqlalchemy]
64
+ pip install fastapi-augment[uvicorn]
65
+ pip install fastapi-augment[orjson]
66
+ pip install fastapi-augment[config] # pydantic-settings 配置管理
67
+ ```
68
+
69
+ **要求:** Python >= 3.11
70
+
71
+ ## 快速开始
72
+
73
+ ```python
74
+ from fastapi import APIRouter
75
+ from fastapi_augment import create_app
76
+ from fastapi_augment.db.sqlalchemy import (
77
+ ClusterTopology, NodeConfig, EngineManager, SessionFactory,
78
+ ModelBase, CrudBase, TimestampMixin,
79
+ )
80
+ from fastapi_augment.schemas import response_success
81
+
82
+ # ── 1. 数据库拓扑 ──────────────────────────────────────
83
+ topology = ClusterTopology(
84
+ primary=NodeConfig(url='postgresql+asyncpg://user:pass@host/db'),
85
+ )
86
+ manager = EngineManager(topology).start()
87
+ sessions = SessionFactory(manager)
88
+
89
+
90
+ # ── 2. 定义模型 ────────────────────────────────────────
91
+ class User(TimestampMixin, ModelBase):
92
+ __tablename__ = 'users'
93
+ name: str
94
+
95
+
96
+ # ── 3. 路由 ────────────────────────────────────────────
97
+ router = APIRouter()
98
+ user_crud = CrudBase(User)
99
+
100
+
101
+ @router.get('/users')
102
+ async def list_users():
103
+ async with sessions.read_session() as session:
104
+ users = await user_crud.list(session, is_active=True, limit=10)
105
+ return response_success(data=users)
106
+
107
+
108
+ # ── 4. 创建应用 ────────────────────────────────────────
109
+ app = create_app(
110
+ title='My Service',
111
+ version='1.0.0',
112
+ engine_manager=manager,
113
+ session_factory=sessions,
114
+ routers=[router],
115
+ )
116
+ ```
117
+
118
+ ## 核心模块
119
+
120
+ ### 应用工厂 — `create_app()`
121
+
122
+ 统一创建 FastAPI 实例,自动装配以下组件:
123
+
124
+ | 组件 | 说明 |
125
+ |---|---|
126
+ | 生命周期 | 接入 `fastapi_lifespan`,合并用户注册表与 `core_registry` |
127
+ | 中间件 | 自动添加 `RequestIdMiddleware`,可选 CORS |
128
+ | 路由 | 支持 `APIRouter` 列表或 `(router, kwargs)` 元组 |
129
+ | OpenAPI | 自动清理 422 响应、可选 Bearer 认证 |
130
+ | 数据库 | 可选挂载 `EngineManager` / `SessionFactory` 到 `app.state` |
131
+ | 健康检查 | `health_check=True` 一键启用 `/health` 端点 |
132
+
133
+ ```python
134
+ from fastapi_augment import create_app, HookRegistry
135
+
136
+ registry = HookRegistry()
137
+
138
+ @registry.on_startup
139
+ async def init_cache() -> None:
140
+ ...
141
+
142
+ app = create_app(
143
+ title='My Service',
144
+ registries=[registry],
145
+ cors_allow_origins=['*'],
146
+ openapi_enable_bearer_auth=True,
147
+ health_check=True, # 启用健康检查
148
+ )
149
+ ```
150
+
151
+ ### 生命周期 — `HookRegistry`
152
+
153
+ 多注册表、优先级驱动的启动/关闭钩子管理:
154
+
155
+ ```python
156
+ from fastapi_augment import HookRegistry
157
+
158
+ registry = HookRegistry()
159
+
160
+ # 装饰器语法
161
+ @registry.on_startup(priority=100)
162
+ async def early_init() -> None: ...
163
+
164
+ @registry.on_shutdown
165
+ async def cleanup() -> None: ...
166
+
167
+ # 直接注册
168
+ registry.register_startup(func, priority=50, timeout=10, abort_on_exception=True)
169
+ ```
170
+
171
+ - **优先级** — 数值越大越先执行(启动降序,关闭升序)
172
+ - **超时控制** — 可设置单个钩子的超时秒数
173
+ - **异常策略** — `abort_on_exception` 控制异常时是否终止流程
174
+
175
+ ### 数据库层 — `db.sqlalchemy`
176
+
177
+ #### 引擎管理 — `EngineManager`
178
+
179
+ 支持三种部署拓扑:
180
+
181
+ ```python
182
+ from fastapi_augment.db.sqlalchemy import ClusterTopology, NodeConfig, EngineManager
183
+
184
+ # 单库
185
+ topology = ClusterTopology(
186
+ primary=NodeConfig(url='postgresql+asyncpg://user:pass@host/db'),
187
+ )
188
+
189
+ # 主从
190
+ topology = ClusterTopology(
191
+ primary=NodeConfig(url='postgresql+asyncpg://primary/db'),
192
+ replicas=[NodeConfig(url='postgresql+asyncpg://replica-1/db')],
193
+ )
194
+
195
+ # 集群(主从 + 独立只读节点)
196
+ topology = ClusterTopology(
197
+ primary=NodeConfig(url='postgresql+asyncpg://primary/db'),
198
+ replicas=[NodeConfig(url='postgresql+asyncpg://replica-1/db')],
199
+ readonly=[NodeConfig(url='postgresql+asyncpg://readonly-1/db')],
200
+ )
201
+
202
+ manager = EngineManager(topology).start()
203
+ # 读引擎轮询(round-robin)
204
+ read_engine = manager.next_read_engine()
205
+ ```
206
+
207
+ #### 会话工厂 — `SessionFactory`
208
+
209
+ 读写分离的异步 Session 工厂,支持 FastAPI `Depends()` 注入:
210
+
211
+ ```python
212
+ from fastapi_augment.db.sqlalchemy import SessionFactory
213
+
214
+ sessions = SessionFactory(manager)
215
+
216
+ # 写会话(自动 commit/rollback)
217
+ async with sessions.transaction() as session:
218
+ session.add(obj)
219
+ # 自动 commit
220
+
221
+ # 读会话(轮询读引擎)
222
+ async with sessions.read_session() as session:
223
+ result = await session.execute(select(User))
224
+
225
+ # FastAPI 依赖注入
226
+ from fastapi import Depends
227
+ from sqlalchemy.ext.asyncio import AsyncSession
228
+
229
+ @router.get('/users')
230
+ async def list_users(session: AsyncSession = Depends(sessions.depends_read)):
231
+ ...
232
+ ```
233
+
234
+ #### 模型基类 — `ModelBase`
235
+
236
+ 基于 ULID 主键的声明式模型基类:
237
+
238
+ ```python
239
+ from fastapi_augment.db.sqlalchemy import ModelBase, TimestampMixin
240
+
241
+ class User(TimestampMixin, ModelBase):
242
+ __tablename__ = 'users'
243
+ name: str
244
+ ```
245
+
246
+ #### 泛型 CRUD — `CrudBase`
247
+
248
+ 类型安全的异步 CRUD 仓库,CRUD 方法只 **flush**,不 commit,事务边界由调用方控制:
249
+
250
+ ```python
251
+ from fastapi_augment.db.sqlalchemy import CrudBase
252
+
253
+ user_crud = CrudBase(User)
254
+
255
+ # Create(静态方法)
256
+ async with sessions.transaction() as session:
257
+ await user_crud.create(session, User(name='alice'))
258
+ await user_crud.create_many(session, [User(name='bob'), User(name='carol')])
259
+
260
+ # Read(实例方法)
261
+ async with sessions.read_session() as session:
262
+ user = await user_crud.get(session, id_='01HXK...')
263
+ user = await user_crud.get_one(session, name='alice')
264
+ users = await user_crud.list(session, role='admin', order_by=['-created_at'], limit=10)
265
+ total = await user_crud.count(session, is_active=True)
266
+ has_admin = await user_crud.exists(session, role='admin')
267
+
268
+ # 分页查询(返回 dict:items / page / size / total / pages)
269
+ result = await user_crud.paginate(session, page=1, size=10, role='admin', order_by=['-created_at'])
270
+ # result = {'items': [...], 'page': 1, 'size': 10, 'total': 100, 'pages': 10}
271
+
272
+ # Update
273
+ async with sessions.transaction() as session:
274
+ await user_crud.update(session, user, name='new_name')
275
+ affected = await user_crud.update_by_id(session, id_='01HXK...', name='new_name')
276
+
277
+ # Delete
278
+ async with sessions.transaction() as session:
279
+ await user_crud.delete(session, user)
280
+ deleted = await user_crud.delete_by_id(session, id_='01HXK...')
281
+ count = await user_crud.delete_where(session, is_active=False)
282
+ ```
283
+
284
+ **过滤语法:**
285
+
286
+ ```python
287
+ # 关键字过滤 — 等值匹配
288
+ await user_crud.list(session, name='alice')
289
+
290
+ # 序列 — 自动转为 IN 查询
291
+ await user_crud.list(session, id_=['01HXK...', '01HXL...'])
292
+
293
+ # None — 自动转为 IS NULL
294
+ await user_crud.list(session, deleted_at=None)
295
+
296
+ # 原生 SQLAlchemy 表达式
297
+ await user_crud.list(session, expressions=(User.age > 18,))
298
+
299
+ # 排序:字段名前缀 - 表示降序
300
+ await user_crud.list(session, order_by=['-created_at', 'name'])
301
+ ```
302
+
303
+ ### 数据库迁移 CLI — `fastapi-augment-migrate`
304
+
305
+ 内置 Alembic 迁移工具,提供 `init` / `generate` / `upgrade` 三个子命令,开箱即用。
306
+
307
+ #### 快速开始
308
+
309
+ ```bash
310
+ # 1. 初始化(一次性操作,生成 alembic.ini + migrations/versions/)
311
+ fastapi-augment-migrate init --db-url "sqlite:///test.db"
312
+
313
+ # 2. 生成迁移
314
+ fastapi-augment-migrate generate \
315
+ --message "add_user_table" \
316
+ --models "models,apps.ai.models"
317
+
318
+ # 3. 执行迁移
319
+ fastapi-augment-migrate upgrade
320
+ ```
321
+
322
+ #### 初始化 — `init`
323
+
324
+ 在项目根目录生成 `alembic.ini` 和 `migrations/versions/` 目录。
325
+ 若 `alembic.ini` 已存在则跳过,不会覆盖。
326
+
327
+ ```bash
328
+ # 初始化
329
+ fastapi-augment-migrate init --db-url "sqlite:///test.db"
330
+
331
+ # 指定项目根目录
332
+ fastapi-augment-migrate init --db-url "postgresql+asyncpg://user:pass@host/db" --project-dir /path/to/project
333
+ ```
334
+
335
+ `alembic.ini` 中的 `script_location` 指向库内的 `env.py`,`version_locations` 指向本地 `migrations/versions/`。
336
+ `env.py` 通过环境变量 `FASTAPI_AUGMENT_MODELS` 动态导入用户模型,无需手动修改。
337
+
338
+ #### 生成迁移 — `generate`
339
+
340
+ 通过 `--models` 指定模型模块(逗号分隔),调用 `alembic revision --autogenerate` 生成迁移脚本。
341
+ 需要先执行 `init` 初始化。
342
+
343
+ ```bash
344
+ # 生成迁移
345
+ fastapi-augment-migrate generate \
346
+ --message "add_user_table" \
347
+ --models "models,apps.ai.models"
348
+
349
+ # 指定项目根目录
350
+ fastapi-augment-migrate generate \
351
+ --message "add_item" \
352
+ --models "apps.ai.models" \
353
+ --project-dir /path/to/project
354
+ ```
355
+
356
+ 迁移文件生成在 `<项目根>/migrations/versions/` 目录下。
357
+
358
+ #### 升级 / 降级 — `upgrade`
359
+
360
+ `--db-url` 为可选参数,不传时直接从 `alembic.ini` 读取 `sqlalchemy.url`。
361
+
362
+ ```bash
363
+ # 升级到最新版本(从 alembic.ini 读取数据库 URL)
364
+ fastapi-augment-migrate upgrade
365
+
366
+ # 指定数据库 URL(覆盖 alembic.ini 中的配置)
367
+ fastapi-augment-migrate upgrade --db-url "sqlite:///test.db"
368
+
369
+ # 升级到指定版本
370
+ fastapi-augment-migrate upgrade --revision abc123
371
+
372
+ # 降级一个版本
373
+ fastapi-augment-migrate upgrade --downgrade
374
+
375
+ # 降级到指定版本
376
+ fastapi-augment-migrate upgrade --downgrade --revision abc123
377
+
378
+ # 指定项目根目录
379
+ fastapi-augment-migrate upgrade --project-dir /path/to/project
380
+ ```
381
+
382
+ #### CLI 参数一览
383
+
384
+ | 子命令 | 参数 | 说明 |
385
+ |---|---|---|
386
+ | `init` | `--db-url` | 数据库 URL(默认 `sqlite:///app.db`) |
387
+ | | `--project-dir` | 项目根目录(默认当前目录) |
388
+ | `generate` | `--message` | **必填**,迁移描述 |
389
+ | | `--models` | **必填**,模型模块路径,逗号分隔 |
390
+ | | `--project-dir` | 项目根目录(默认当前目录) |
391
+ | `upgrade` | `--db-url` | 数据库 URL(不传则从 alembic.ini 读取) |
392
+ | | `--revision` | 目标版本(默认 `head`) |
393
+ | | `--downgrade` | 降级模式 |
394
+ | | `--project-dir` | 项目根目录(默认当前目录) |
395
+
396
+ ### 模型 Mixin — `db.sqlalchemy.mixins`
397
+
398
+ 可组合的列混入,按需叠加:
399
+
400
+ | Mixin | 提供的列 |
401
+ |---|---|
402
+ | `CreatedAtMixin` | `created_at` |
403
+ | `TimestampMixin` | `created_at` + `updated_at` |
404
+ | `CreatedByMixin` | `created_by` |
405
+ | `UpdatedByMixin` | `updated_by` |
406
+ | `AuditMixin` | `created_by` + `updated_by` |
407
+ | `SoftDeleteMixin` | `is_deleted` + `deleted_at` |
408
+ | `SoftDeleteAuditMixin` | `is_deleted` + `deleted_at` + `deleted_by` |
409
+
410
+ ```python
411
+ from fastapi_augment.db.sqlalchemy import ModelBase, TimestampMixin, SoftDeleteMixin
412
+
413
+ class User(TimestampMixin, SoftDeleteMixin, ModelBase):
414
+ __tablename__ = 'users'
415
+ name: str
416
+ ```
417
+
418
+ ### 统一响应 — `schemas`
419
+
420
+ #### `APIResponse` — 全局返回格式
421
+
422
+ ```json
423
+ {
424
+ "request_id": "019xxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
425
+ "code": 0,
426
+ "message": "操作成功",
427
+ "data": { ... },
428
+ "extra": null
429
+ }
430
+ ```
431
+
432
+ `request_id` 自动从 `ContextVar` 获取,无需手动传递。
433
+
434
+ #### 工厂函数
435
+
436
+ ```python
437
+ from fastapi_augment.schemas import response_success, response_fail
438
+
439
+ # 成功响应
440
+ return response_success(data=user)
441
+ return response_success(data=users, extra={'total': 100})
442
+
443
+ # 失败响应
444
+ return response_fail(code=40001, message='用户名已存在')
445
+ ```
446
+
447
+ #### 请求参数模型
448
+
449
+ ```python
450
+ from fastapi_augment.schemas import PageParams, TimeRangeParams, KeywordParams
451
+
452
+ # 分页参数
453
+ @router.get('/users')
454
+ async def list_users(params: PageParams = Depends()):
455
+ ...
456
+
457
+ # 时间范围 + 关键词搜索
458
+ @router.get('/orders')
459
+ async def list_orders(
460
+ time_range: TimeRangeParams = Depends(),
461
+ keyword: KeywordParams = Depends(),
462
+ ):
463
+ ...
464
+ ```
465
+
466
+ ### HTTP 异常 — `common.exceptions`
467
+
468
+ 完整的 4xx 异常子类,内置默认文案。子类只需声明 `_status_code` 类变量,无需重写 `__init__`:
469
+
470
+ ```python
471
+ from fastapi_augment.common.exceptions import (
472
+ BadRequestError, # 400
473
+ UnauthorizedError, # 401
474
+ ForbiddenError, # 403
475
+ NotFoundError, # 404
476
+ ConflictError, # 409
477
+ TooManyRequestsError, # 429(支持 retry_after 参数)
478
+ # ... 更多异常
479
+ )
480
+
481
+ # 使用默认文案
482
+ raise NotFoundError()
483
+
484
+ # 自定义提示
485
+ raise BadRequestError(detail='用户名不能为空')
486
+
487
+ # 限流场景
488
+ raise TooManyRequestsError(retry_after=60)
489
+ ```
490
+
491
+ ### 日志管理 — `log`
492
+
493
+ 导入即生效:自动注入 `request_id` 到每条日志、接管 uvicorn/fastapi 日志输出。
494
+
495
+ ```python
496
+ from fastapi_augment.log import setup_logger, set_log_level
497
+
498
+ # 一键配置:控制台 + 按天轮转文件日志
499
+ setup_logger(log_dir='./logs', rotation='day', backup_count=30)
500
+
501
+ # 动态调整日志级别
502
+ set_log_level('info')
503
+ ```
504
+
505
+ **支持的轮转粒度:**
506
+
507
+ | 粒度 | 说明 |
508
+ |---|---|
509
+ | `'second'` / `'minute'` / `'hour'` | 每整秒/分/点 |
510
+ | `'day'`(默认) | 每天 00:00 |
511
+ | `'week'` | 每周一 00:00 |
512
+ | `'month'` | 每月 1 日 00:00 |
513
+ | `'year'` | 每年 1 月 1 日 00:00 |
514
+
515
+ **核心能力:**
516
+
517
+ - **request_id 注入** — 每条日志自动携带当前请求的 `request_id`,方便链路追踪
518
+ - **uvicorn 接管** — 统一 `uvicorn.error` / `uvicorn.access` 的日志名称为 `uvicorn`,屏蔽第三方库 DEBUG 噪声
519
+ - **多进程安全** — 日志轮转时捕获 `PermissionError`,兼容多进程部署(如 `uvicorn --workers N`)
520
+ - **控制台开关** — `enable_console=False` 可关闭控制台输出,仅保留文件日志
521
+
522
+ ### 健康检查 — `health`
523
+
524
+ 可扩展的检查器模式,内置应用状态与数据库连通性检查。
525
+
526
+ #### 一行启用
527
+
528
+ ```python
529
+ app = create_app(
530
+ title='My Service',
531
+ engine_manager=manager,
532
+ health_check=True, # 自动注册 /health 端点
533
+ )
534
+ ```
535
+
536
+ `GET /health` 响应示例:
537
+
538
+ ```json
539
+ {
540
+ "status": "healthy",
541
+ "checks": [
542
+ {"name": "app", "status": "healthy", "latencyMs": 0, "details": {"status": "running", "version": "1.0.0", "uptimeSeconds": 3600}},
543
+ {"name": "database", "status": "healthy", "latencyMs": 2.3}
544
+ ]
545
+ }
546
+ ```
547
+
548
+ - 总体状态取所有检查项中**最差**的(healthy < degraded < unhealthy)
549
+ - 任一检查项 unhealthy 时 HTTP 返回 **503**,便于负载均衡器/探针识别
550
+ - 传入 `engine_manager` 时自动包含数据库检查,否则仅检查应用状态
551
+
552
+ #### 自定义检查器
553
+
554
+ ```python
555
+ from fastapi_augment.health import BaseChecker, CheckResult, create_health_router
556
+
557
+ class RedisChecker(BaseChecker):
558
+ @property
559
+ def name(self) -> str:
560
+ return 'redis'
561
+
562
+ async def check(self, app) -> CheckResult:
563
+ # 检查 Redis 连通性
564
+ ...
565
+
566
+ # 手动注册(适合需要自定义路径或额外检查器的场景)
567
+ app.include_router(create_health_router(
568
+ path='/health',
569
+ extra_checkers=[RedisChecker()],
570
+ ))
571
+ ```
572
+
573
+ ### 配置管理 — `config`
574
+
575
+ 基于 `pydantic-settings`,通过 `from_env()` 直接传参,无需手动导入 `SettingsConfigDict`:
576
+
577
+ ```python
578
+ from fastapi_augment.config import EnvSettings
579
+
580
+ class Settings(EnvSettings):
581
+ database_url: str
582
+ redis_url: str = ''
583
+ debug: bool = False
584
+ secret_key: str = 'change-me'
585
+
586
+ # 直接传入 .env 路径、前缀等
587
+ settings = Settings.from_env(
588
+ env_file='config/.env',
589
+ env_prefix='APP_',
590
+ env_nested_delimiter='__',
591
+ )
592
+ ```
593
+
594
+ 支持 `SettingsConfigDict` 的所有参数(`env_file`、`env_prefix`、`secrets_dir`、`yaml_file` 等),
595
+ 与模型字段值自动区分,无需关心分类。
596
+
597
+ ### 中间件 — `middlewares`
598
+
599
+ #### `RequestIdMiddleware`
600
+
601
+ 自动为每个请求生成/传递 `request_id`(ULID 格式),通过 `ContextVar` 在全链路中可用:
602
+
603
+ ```python
604
+ from fastapi_augment.middlewares import get_request_id
605
+
606
+ request_id = get_request_id()
607
+ ```
608
+
609
+ ## 项目结构
610
+
611
+ ```
612
+ fastapi_augment/
613
+ ├── common/
614
+ │ ├── constants.py # 全局常量与默认错误文案
615
+ │ ├── exceptions.py # 4xx HTTP 异常体系
616
+ │ ├── exception_handlers.py # 全局异常处理器
617
+ │ └── utils/
618
+ │ └── strings.py # 字符串工具 / JSON 序列化
619
+ ├── config/
620
+ │ └── settings.py # EnvSettings 配置管理
621
+ ├── db/
622
+ │ └── sqlalchemy/
623
+ │ ├── engine.py # EngineManager / NodeConfig / ClusterTopology
624
+ │ ├── session.py # SessionFactory(读写分离)
625
+ │ ├── model_base.py # ModelBase(ULID 主键)
626
+ │ ├── crud_base.py # CrudBase(泛型 CRUD + paginate)
627
+ │ ├── migrate.py # 数据库迁移 CLI
628
+ │ ├── migrations/ # Alembic 迁移环境(env.py / script.py.mako)
629
+ │ └── mixins/ # Timestamp / Audit / SoftDelete
630
+ ├── health/
631
+ │ ├── checker.py # BaseChecker / CheckResult / HealthResponse
632
+ │ ├── checkers.py # AppChecker / DatabaseChecker
633
+ │ └── router.py # create_health_router()
634
+ ├── log/
635
+ │ ├── factory.py # request_id 注入工厂
636
+ │ ├── filters.py # UvicornNameRewriteFilter
637
+ │ ├── handlers.py # 多进程安全轮转处理器
638
+ │ └── config.py # setup_logger / set_log_level / set_log_format
639
+ ├── middlewares/
640
+ │ ├── base.py # BaseASGIMiddleware
641
+ │ └── request_id.py # RequestId 中间件
642
+ ├── schemas/
643
+ │ ├── base.py # SchemaBase / ORMSchemaBase
644
+ │ ├── request.py # PageParams / TimeRangeParams / KeywordParams
645
+ │ ├── response.py # APIResponse / response_success / response_fail
646
+ │ └── pagination.py # PageData 分页模型
647
+ ├── factory.py # create_app 应用工厂
648
+ ├── lifespan.py # HookRegistry 生命周期管理
649
+ └── openapi.py # OpenAPI schema 优化
650
+ ```
651
+
652
+ ## 许可证
653
+
654
+ MIT