toms-fast 0.2.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.
Files changed (60) hide show
  1. toms_fast-0.2.1.dist-info/METADATA +467 -0
  2. toms_fast-0.2.1.dist-info/RECORD +60 -0
  3. toms_fast-0.2.1.dist-info/WHEEL +4 -0
  4. toms_fast-0.2.1.dist-info/entry_points.txt +2 -0
  5. tomskit/__init__.py +0 -0
  6. tomskit/celery/README.md +693 -0
  7. tomskit/celery/__init__.py +4 -0
  8. tomskit/celery/celery.py +306 -0
  9. tomskit/celery/config.py +377 -0
  10. tomskit/cli/__init__.py +207 -0
  11. tomskit/cli/__main__.py +8 -0
  12. tomskit/cli/scaffold.py +123 -0
  13. tomskit/cli/templates/__init__.py +42 -0
  14. tomskit/cli/templates/base.py +348 -0
  15. tomskit/cli/templates/celery.py +101 -0
  16. tomskit/cli/templates/extensions.py +213 -0
  17. tomskit/cli/templates/fastapi.py +400 -0
  18. tomskit/cli/templates/migrations.py +281 -0
  19. tomskit/cli/templates_config.py +122 -0
  20. tomskit/logger/README.md +466 -0
  21. tomskit/logger/__init__.py +4 -0
  22. tomskit/logger/config.py +106 -0
  23. tomskit/logger/logger.py +290 -0
  24. tomskit/py.typed +0 -0
  25. tomskit/redis/README.md +462 -0
  26. tomskit/redis/__init__.py +6 -0
  27. tomskit/redis/config.py +85 -0
  28. tomskit/redis/redis_pool.py +87 -0
  29. tomskit/redis/redis_sync.py +66 -0
  30. tomskit/server/__init__.py +47 -0
  31. tomskit/server/config.py +117 -0
  32. tomskit/server/exceptions.py +412 -0
  33. tomskit/server/middleware.py +371 -0
  34. tomskit/server/parser.py +312 -0
  35. tomskit/server/resource.py +464 -0
  36. tomskit/server/server.py +276 -0
  37. tomskit/server/type.py +263 -0
  38. tomskit/sqlalchemy/README.md +590 -0
  39. tomskit/sqlalchemy/__init__.py +20 -0
  40. tomskit/sqlalchemy/config.py +125 -0
  41. tomskit/sqlalchemy/database.py +125 -0
  42. tomskit/sqlalchemy/pagination.py +359 -0
  43. tomskit/sqlalchemy/property.py +19 -0
  44. tomskit/sqlalchemy/sqlalchemy.py +131 -0
  45. tomskit/sqlalchemy/types.py +32 -0
  46. tomskit/task/README.md +67 -0
  47. tomskit/task/__init__.py +4 -0
  48. tomskit/task/task_manager.py +124 -0
  49. tomskit/tools/README.md +63 -0
  50. tomskit/tools/__init__.py +18 -0
  51. tomskit/tools/config.py +70 -0
  52. tomskit/tools/warnings.py +37 -0
  53. tomskit/tools/woker.py +81 -0
  54. tomskit/utils/README.md +666 -0
  55. tomskit/utils/README_SERIALIZER.md +644 -0
  56. tomskit/utils/__init__.py +35 -0
  57. tomskit/utils/fields.py +434 -0
  58. tomskit/utils/marshal_utils.py +137 -0
  59. tomskit/utils/response_utils.py +13 -0
  60. tomskit/utils/serializers.py +447 -0
@@ -0,0 +1,348 @@
1
+ """
2
+ 基础模板模块
3
+ 包含所有项目类型都需要的基础文件模板
4
+ """
5
+
6
+ from typing import Callable
7
+
8
+
9
+ def _get_readme_content(project_name: str, project_type: str) -> str:
10
+ """根据项目类型生成 README 内容"""
11
+ project_type_names = {
12
+ "fastapi": "FastAPI",
13
+ "celery": "Celery",
14
+ "full": "FastAPI + Celery"
15
+ }
16
+ project_desc = project_type_names.get(project_type, project_type)
17
+
18
+ # 基础内容
19
+ content = f'''# {project_name}
20
+
21
+ 基于 [toms-fast](https://github.com/tomszhou/toms-fast) 的 {project_desc} 项目脚手架。
22
+
23
+ ## 🚀 快速开始
24
+
25
+ ### 前置要求
26
+
27
+ - Python >= 3.11
28
+ - [uv](https://github.com/astral-sh/uv) (推荐使用 uv 管理依赖)
29
+
30
+ ### 1. 安装依赖
31
+
32
+ 使用 uv 安装项目依赖:
33
+
34
+ ```bash
35
+ # 安装 uv (如果还没有安装)
36
+ # macOS/Linux:
37
+ curl -LsSf https://astral.sh/uv/install.sh | sh
38
+
39
+ # 或使用 pip:
40
+ pip install uv
41
+
42
+ # 安装项目依赖
43
+ uv sync
44
+
45
+ # 或安装开发依赖
46
+ uv sync --group dev
47
+ ```
48
+
49
+ ### 2. 配置环境变量
50
+
51
+ ```bash
52
+ cd backend
53
+ cp .env.example .env
54
+ # 编辑 .env 文件,配置数据库和 Redis 连接信息
55
+ ```
56
+
57
+ '''
58
+
59
+ # 根据项目类型添加运行说明
60
+ if project_type in ("fastapi", "full"):
61
+ content += '''### 3. 运行 FastAPI 应用
62
+
63
+ ```bash
64
+ # 确保在 backend 目录下
65
+ cd backend
66
+
67
+ # 使用 uv 运行(推荐)
68
+ uv run uvicorn main:app --reload
69
+
70
+ # 或激活虚拟环境后运行
71
+ source .venv/bin/activate # Windows: .venv\\Scripts\\activate
72
+ uvicorn main:app --reload
73
+
74
+ # 或直接运行
75
+ python main.py
76
+ ```
77
+
78
+ ### 4. 访问 API
79
+
80
+ - API 文档: http://localhost:8000/docs (如果启用了文档)
81
+ - 健康检查: http://localhost:8000/health
82
+ - 用户 API: http://localhost:8000/api/v1/users
83
+
84
+ '''
85
+
86
+ if project_type in ("celery", "full"):
87
+ content += '''### 3. 运行 Celery Worker
88
+
89
+ ```bash
90
+ # 确保在 backend 目录下
91
+ cd backend
92
+
93
+ # 使用 uv 运行(推荐)
94
+ uv run celery -A celery_app worker --loglevel=info
95
+
96
+ # 或激活虚拟环境后运行
97
+ source .venv/bin/activate # Windows: .venv\\Scripts\\activate
98
+ celery -A celery_app worker --loglevel=info
99
+ ```
100
+
101
+ ### 4. 运行 Celery Beat(定时任务,可选)
102
+
103
+ ```bash
104
+ cd backend
105
+ uv run celery -A celery_app beat --loglevel=info
106
+ ```
107
+
108
+ '''
109
+
110
+ # 项目结构
111
+ content += f'''## 📁 项目结构
112
+
113
+ ```
114
+ {project_name}/
115
+ ├── backend/ # 后端代码目录
116
+ '''
117
+
118
+ if project_type in ("fastapi", "full"):
119
+ content += '''│ ├── app/
120
+ │ │ ├── controllers/ # 控制器层(API 路由)
121
+ │ │ │ └── users/ # 用户控制器示例
122
+ │ │ ├── models/ # 数据库模型
123
+ │ │ ├── schemas/ # Pydantic 模型(请求/响应)
124
+ │ │ ├── services/ # 业务逻辑层
125
+ │ │ ├── middleware/ # 中间件目录
126
+ │ │ │ ├── request_id.py # 请求 ID 追踪
127
+ │ │ │ └── resource_cleanup.py # 资源清理
128
+ │ │ └── utils/ # 工具函数
129
+ │ ├── main.py # FastAPI 应用入口
130
+ '''
131
+
132
+ if project_type in ("celery", "full"):
133
+ content += '''│ ├── celery_app.py # Celery 应用入口
134
+ │ ├── tasks/ # Celery 任务
135
+ │ │ └── example_task.py # 示例任务
136
+ '''
137
+
138
+ content += '''│ ├── tests/ # 测试文件
139
+ │ ├── logs/ # 日志目录
140
+ │ ├── migrations/ # 数据库迁移目录
141
+ │ ├── pyproject.toml # 项目配置和依赖(使用 uv 管理)
142
+ │ └── .env # 环境变量配置
143
+ ├── web/ # 前端代码目录
144
+ └── README.md # 项目说明文档
145
+ ```
146
+
147
+ '''
148
+
149
+ # 使用指南
150
+ if project_type in ("fastapi", "full"):
151
+ content += '''## 📖 使用指南
152
+
153
+ ### 添加新控制器
154
+
155
+ 1. 在 `app/controllers/` 下创建新控制器目录
156
+ 2. 创建 `resources.py` 定义 Resource
157
+ 3. 在 `app/schemas/` 中创建对应的数据模型(请求/响应)
158
+ 4. 创建 `module.py` 定义控制器初始化函数
159
+ 5. 在 `main.py` 中调用初始化函数
160
+
161
+ ### 定义 Resource
162
+
163
+ ```python
164
+ from tomskit.server import Resource, api_doc, register_resource
165
+
166
+ @register_resource(module="users", path="/users", tags=["用户管理"])
167
+ class UserResource(Resource):
168
+ @api_doc(
169
+ summary="获取用户列表",
170
+ response_model=list[UserResponse]
171
+ )
172
+ async def get(self, request: Request):
173
+ return []
174
+ ```
175
+
176
+ '''
177
+
178
+ if project_type in ("celery", "full"):
179
+ content += '''### 定义 Celery 任务
180
+
181
+ ```python
182
+ from celery import shared_task
183
+ from tomskit.celery import AsyncTaskRunner
184
+
185
+ @shared_task(name="my_task", queue="default")
186
+ def my_task(message: str):
187
+ runner = AsyncTaskRunner(async_my_task)
188
+ return runner.run(message)
189
+
190
+ async def async_my_task(message: str):
191
+ # 实现异步任务逻辑
192
+ return f"处理完成: {message}"
193
+ ```
194
+
195
+ '''
196
+
197
+ content += '''## 🔗 相关链接
198
+
199
+ - [toms-fast 文档](https://github.com/tomszhou/toms-fast)
200
+ - [FastAPI 文档](https://fastapi.tiangolo.com/)
201
+ - [Celery 文档](https://docs.celeryq.dev/)
202
+ '''
203
+
204
+ return content
205
+
206
+
207
+ def get_base_templates(project_name: str, project_type: str = "full") -> dict[str, Callable[[], str]]:
208
+ """获取基础模板"""
209
+ return {
210
+ "env_example": lambda: '''# 应用配置
211
+ APP_NAME=my-fastapi-app
212
+ APP_ENV=development
213
+
214
+ # Gunicorn 配置(生产环境)
215
+ workers=4
216
+ bind=0.0.0.0:8000
217
+ daemon=False
218
+
219
+ # Redis 配置
220
+ REDIS_HOST=localhost
221
+ REDIS_PORT=6379
222
+ REDIS_DB=0
223
+ REDIS_PASSWORD=
224
+
225
+ # 日志配置
226
+ LOG_PREFIX=[MyApp]
227
+ LOG_LEVEL=INFO
228
+ LOG_DIR=logs
229
+ LOG_NAME=apps
230
+ LOG_USE_UTC=False
231
+
232
+ # 数据库配置
233
+ DB_HOST=localhost
234
+ DB_PORT=3306
235
+ DB_USERNAME=root
236
+ DB_PASSWORD=password
237
+ DB_DATABASE=mydb
238
+ DB_CHARSET=utf8mb4
239
+ DB_EXTRAS=
240
+
241
+ # SQLAlchemy 配置
242
+ SQLALCHEMY_DATABASE_URI_SCHEME=mysql+aiomysql
243
+ SQLALCHEMY_DATABASE_SYNC_URI_SCHEME=mysql+pymysql
244
+ SQLALCHEMY_POOL_SIZE=300
245
+ SQLALCHEMY_MAX_OVERFLOW=10
246
+ SQLALCHEMY_POOL_RECYCLE=3600
247
+ SQLALCHEMY_POOL_PRE_PING=False
248
+ SQLALCHEMY_ECHO=False
249
+ ''',
250
+
251
+ "gitignore": lambda: '''# Python
252
+ __pycache__/
253
+ *.py[cod]
254
+ *$py.class
255
+ *.so
256
+ .Python
257
+ build/
258
+ develop-eggs/
259
+ dist/
260
+ downloads/
261
+ eggs/
262
+ .eggs/
263
+ lib/
264
+ lib64/
265
+ parts/
266
+ sdist/
267
+ var/
268
+ wheels/
269
+ *.egg-info/
270
+ .installed.cfg
271
+ *.egg
272
+
273
+ # Virtual Environment
274
+ venv/
275
+ env/
276
+ ENV/
277
+ .venv
278
+
279
+ # IDE
280
+ .vscode/
281
+ .idea/
282
+ *.swp
283
+ *.swo
284
+ *~
285
+
286
+ # Environment
287
+ .env
288
+ .env.local
289
+
290
+ # Logs
291
+ logs/
292
+ *.log
293
+
294
+ # Database
295
+ *.db
296
+ *.sqlite
297
+
298
+ # OS
299
+ .DS_Store
300
+ Thumbs.db
301
+
302
+ # Project specific
303
+ run/
304
+ *.pid
305
+ ''',
306
+
307
+ "pyproject_toml": lambda: f'''[project]
308
+ name = "{project_name}"
309
+ version = "0.1.0"
310
+ description = "基于 toms-fast 的 FastAPI 应用"
311
+ requires-python = ">=3.11"
312
+ dependencies = [
313
+ "toms-fast>=0.1.1",
314
+ "python-dotenv>=1.0.0",
315
+ "uvicorn[standard]>=0.27.0",
316
+ ]
317
+
318
+ [build-system]
319
+ requires = ["hatchling"]
320
+ build-backend = "hatchling.build"
321
+
322
+ [tool.uv]
323
+ index-url = "https://pypi.tuna.tsinghua.edu.cn/simple"
324
+
325
+ [dependency-groups]
326
+ dev = [
327
+ "pytest>=8.3.5",
328
+ "pytest-asyncio>=0.26.0",
329
+ "httpx>=0.27.0",
330
+ ]
331
+
332
+ [tool.ruff]
333
+ line-length = 120
334
+ target-version = "py311"
335
+
336
+ [tool.mypy]
337
+ python_version = "3.11"
338
+ ignore_missing_imports = true
339
+
340
+ [tool.pytest.ini_options]
341
+ asyncio_mode = "auto"
342
+ asyncio_default_fixture_loop_scope = "function"
343
+ ''',
344
+
345
+ "readme_md": lambda: _get_readme_content(project_name, project_type),
346
+
347
+ "tests_init_py": lambda: "",
348
+ }
@@ -0,0 +1,101 @@
1
+ """
2
+ Celery 模板模块
3
+ 包含所有 Celery 相关的文件模板
4
+ """
5
+
6
+ from typing import Callable
7
+
8
+
9
+ def get_celery_templates(project_name: str) -> dict[str, Callable[[], str]]:
10
+ """获取 Celery 模板"""
11
+ return {
12
+ "celery_app_py": lambda: f'''"""
13
+ {project_name} Celery 应用入口
14
+ """
15
+
16
+ from pathlib import Path
17
+ from dotenv import load_dotenv
18
+ from celery.signals import worker_process_init
19
+
20
+ from extensions.ext_celery import init_app, get_celery_app
21
+ from extensions import init_all_extensions
22
+
23
+ # 加载环境变量
24
+ env_path = Path(__file__).parent / ".env"
25
+ if env_path.exists():
26
+ load_dotenv(env_path)
27
+ else:
28
+ print("⚠️ 警告: .env 文件不存在,请从 .env.example 复制并配置")
29
+
30
+ # 初始化 Celery 应用(通过扩展)
31
+ celery_app = init_app()
32
+
33
+ # 统一初始化所有扩展(logger, database, redis 等)
34
+ # 注意:celery_app 已经初始化,ext_celery 会检测到并跳过重复初始化
35
+ init_all_extensions(celery_app)
36
+
37
+ # Worker 启动时的初始化(如果需要额外的 worker 初始化逻辑)
38
+ @worker_process_init.connect
39
+ def init_worker(sender=None, **kwargs):
40
+ """Worker 进程启动时的初始化"""
41
+ # 扩展已经在 init_all_extensions 中初始化了
42
+ pass
43
+
44
+ # 导入任务(确保任务被注册)
45
+ from tasks import example_task # noqa: E402, F401
46
+
47
+ # 导出 celery_app 供其他地方使用
48
+ __all__ = ["celery_app"]
49
+ ''',
50
+
51
+ "tasks_init_py": lambda: '''"""
52
+ Celery 任务模块
53
+ """
54
+
55
+ # 导入所有任务,确保它们被注册到 Celery 应用
56
+ from . import example_task # noqa: F401
57
+
58
+ __all__ = ["example_task"]
59
+ ''',
60
+
61
+ "example_task_py": lambda: f'''"""
62
+ 示例 Celery 任务
63
+ """
64
+
65
+ from celery import shared_task
66
+ from tomskit.celery import AsyncTaskRunner
67
+
68
+
69
+ @shared_task(name="{project_name}.example_task", queue="default")
70
+ def example_task(message: str):
71
+ """
72
+ 示例异步任务
73
+
74
+ Args:
75
+ message: 要处理的消息
76
+
77
+ Returns:
78
+ str: 处理结果
79
+ """
80
+ runner = AsyncTaskRunner(async_example_task)
81
+ return runner.run(message)
82
+
83
+
84
+ async def async_example_task(message: str):
85
+ """
86
+ 异步任务函数
87
+
88
+ Args:
89
+ message: 要处理的消息
90
+
91
+ Returns:
92
+ str: 处理结果
93
+ """
94
+ # TODO: 实现你的异步任务逻辑
95
+ # 可以使用 db.session 进行数据库操作
96
+ # 可以使用 redis_client 进行 Redis 操作
97
+
98
+ print(f"处理消息: {{message}}")
99
+ return f"任务完成: {{message}}"
100
+ ''',
101
+ }
@@ -0,0 +1,213 @@
1
+ """
2
+ 扩展模板模块
3
+ 包含所有扩展相关的文件模板
4
+ """
5
+
6
+ from typing import Callable
7
+
8
+
9
+ def get_extension_templates(project_name: str, project_type: str = "full") -> dict[str, Callable[[], str]]:
10
+ """获取扩展模板"""
11
+ # 根据项目类型决定是否包含 ext_celery
12
+ def _get_extensions_init_py():
13
+ celery_import = ""
14
+ celery_in_list = ""
15
+ if project_type in ("celery", "full"):
16
+ celery_import = " ext_celery,\n"
17
+ celery_in_list = " ext_celery,\n"
18
+
19
+ return f'''"""
20
+ 扩展功能统一初始化
21
+ """
22
+
23
+ import time
24
+ from typing import Any
25
+
26
+ from extensions import (
27
+ ext_logger,
28
+ ext_database,
29
+ ext_redis,
30
+ {celery_import} # 在这里导入更多扩展
31
+ # ext_mail,
32
+ # ext_storage,
33
+ )
34
+
35
+ # 扩展初始化顺序列表
36
+ extensions = [
37
+ ext_logger,
38
+ ext_database,
39
+ ext_redis,
40
+ {celery_in_list} # 在这里添加更多扩展,按初始化顺序排列
41
+ # ext_mail,
42
+ # ext_storage,
43
+ ]
44
+
45
+
46
+ def init_all_extensions(app: Any = None):
47
+ """
48
+ 统一初始化所有扩展功能
49
+
50
+ 按 extensions 列表顺序初始化每个扩展,支持:
51
+ - is_enabled() 检查扩展是否启用
52
+ - init_app(app) 初始化扩展
53
+ - 记录初始化时间
54
+
55
+ Args:
56
+ app: 应用实例(FastApp 或 AsyncCelery),可选
57
+ """
58
+ for ext in extensions:
59
+ short_name = ext.__name__.split(".")[-1]
60
+
61
+ # 检查扩展是否启用
62
+ is_enabled = ext.is_enabled() if hasattr(ext, "is_enabled") else True
63
+ if not is_enabled:
64
+ print(f"⏭️ 跳过 {{short_name}}(未启用)")
65
+ continue
66
+
67
+ # 初始化扩展
68
+ try:
69
+ start_time = time.perf_counter()
70
+ ext.init_app(app)
71
+ end_time = time.perf_counter()
72
+ elapsed_ms = round((end_time - start_time) * 1000, 2)
73
+ print(f"✅ {{short_name}} 初始化成功 ({{elapsed_ms}} ms)")
74
+ except Exception as e:
75
+ print(f"❌ {{short_name}} 初始化失败: {{e}}")
76
+ raise
77
+ '''
78
+
79
+ return {
80
+ "extensions_init_py": _get_extensions_init_py,
81
+
82
+ "extensions_logger_py": lambda: '''"""
83
+ 日志扩展初始化
84
+ """
85
+
86
+ from tomskit.logger import setup_logging, LoggerConfig
87
+ from typing import Any
88
+
89
+
90
+ def is_enabled() -> bool:
91
+ """检查扩展是否启用"""
92
+ return True
93
+
94
+
95
+ def init_app(app: Any = None):
96
+ """初始化日志系统"""
97
+ config = LoggerConfig()
98
+ setup_logging(config)
99
+ ''',
100
+
101
+ "extensions_database_py": lambda: '''"""
102
+ 数据库扩展初始化
103
+ """
104
+
105
+ from tomskit.sqlalchemy import db, DatabaseConfig
106
+ from typing import Any
107
+
108
+
109
+ def is_enabled() -> bool:
110
+ """检查扩展是否启用"""
111
+ return True
112
+
113
+
114
+ def init_app(app: Any = None):
115
+ """初始化数据库连接池"""
116
+ config = DatabaseConfig()
117
+ db.initialize_session_pool(
118
+ config.SQLALCHEMY_DATABASE_URI,
119
+ config.SQLALCHEMY_ENGINE_OPTIONS
120
+ )
121
+ ''',
122
+
123
+ "extensions_redis_py": lambda: '''"""
124
+ Redis 扩展初始化
125
+ """
126
+
127
+ from tomskit.redis import RedisClientWrapper, RedisConfig
128
+ from typing import Any
129
+
130
+
131
+ def is_enabled() -> bool:
132
+ """检查扩展是否启用"""
133
+ return True
134
+
135
+
136
+ def init_app(app: Any = None):
137
+ """初始化 Redis 连接"""
138
+ config = RedisConfig()
139
+ RedisClientWrapper.initialize(config.model_dump())
140
+ ''',
141
+
142
+ "extensions_celery_py": lambda: f'''"""
143
+ Celery 扩展初始化
144
+ """
145
+
146
+ from pathlib import Path
147
+ from typing import Any
148
+ from dotenv import load_dotenv
149
+
150
+ from tomskit.celery import AsyncCelery, CeleryConfig
151
+
152
+ # 全局 Celery 应用实例
153
+ celery_app: AsyncCelery | None = None
154
+
155
+
156
+ def is_enabled() -> bool:
157
+ """检查扩展是否启用"""
158
+ return True
159
+
160
+
161
+ def init_app(app: Any = None) -> AsyncCelery:
162
+ """
163
+ 初始化 Celery 应用
164
+
165
+ Args:
166
+ app: 应用实例(FastApp 或 AsyncCelery),可选
167
+
168
+ Returns:
169
+ AsyncCelery: Celery 应用实例
170
+ """
171
+ global celery_app
172
+
173
+ # 如果已经初始化,直接返回
174
+ if celery_app is not None:
175
+ return celery_app
176
+
177
+ # 如果传入的是 AsyncCelery 实例,说明已经在 celery_app.py 中创建了
178
+ # 这种情况下只需要保存引用,不需要重新创建
179
+ if isinstance(app, AsyncCelery):
180
+ celery_app = app
181
+ return celery_app
182
+
183
+ # 加载环境变量
184
+ env_path = Path(__file__).parent.parent / ".env"
185
+ if env_path.exists():
186
+ load_dotenv(env_path)
187
+
188
+ # 创建 Celery 配置
189
+ celery_config = CeleryConfig()
190
+
191
+ # 创建 Celery 应用
192
+ celery_app = AsyncCelery(
193
+ '{project_name}',
194
+ broker=celery_config.CELERY_BROKER_URL,
195
+ backend=celery_config.CELERY_RESULT_BACKEND
196
+ )
197
+
198
+ # 应用配置
199
+ celery_app.from_mapping(celery_config.get_celery_config_dict())
200
+
201
+ # 设置应用根路径
202
+ celery_app.set_app_root_path(Path(__file__).parent.parent)
203
+
204
+ return celery_app
205
+
206
+
207
+ def get_celery_app() -> AsyncCelery:
208
+ """获取 Celery 应用实例"""
209
+ if celery_app is None:
210
+ raise RuntimeError("Celery app is not initialized. Call init_app() first.")
211
+ return celery_app
212
+ ''',
213
+ }