infomankit 0.3.23__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 (143) hide show
  1. infoman/__init__.py +1 -0
  2. infoman/cli/README.md +378 -0
  3. infoman/cli/__init__.py +7 -0
  4. infoman/cli/commands/__init__.py +3 -0
  5. infoman/cli/commands/init.py +312 -0
  6. infoman/cli/scaffold.py +634 -0
  7. infoman/cli/templates/Makefile.template +132 -0
  8. infoman/cli/templates/app/__init__.py.template +3 -0
  9. infoman/cli/templates/app/app.py.template +4 -0
  10. infoman/cli/templates/app/models_base.py.template +18 -0
  11. infoman/cli/templates/app/models_entity_init.py.template +11 -0
  12. infoman/cli/templates/app/models_schemas_init.py.template +11 -0
  13. infoman/cli/templates/app/repository_init.py.template +11 -0
  14. infoman/cli/templates/app/routers_init.py.template +15 -0
  15. infoman/cli/templates/app/services_init.py.template +11 -0
  16. infoman/cli/templates/app/static_index.html.template +39 -0
  17. infoman/cli/templates/app/static_main.js.template +31 -0
  18. infoman/cli/templates/app/static_style.css.template +111 -0
  19. infoman/cli/templates/app/utils_init.py.template +11 -0
  20. infoman/cli/templates/config/.env.dev.template +43 -0
  21. infoman/cli/templates/config/.env.prod.template +43 -0
  22. infoman/cli/templates/config/README.md.template +28 -0
  23. infoman/cli/templates/docker/.dockerignore.template +60 -0
  24. infoman/cli/templates/docker/Dockerfile.template +47 -0
  25. infoman/cli/templates/docker/README.md.template +240 -0
  26. infoman/cli/templates/docker/docker-compose.yml.template +81 -0
  27. infoman/cli/templates/docker/mysql_custom.cnf.template +42 -0
  28. infoman/cli/templates/docker/mysql_init.sql.template +15 -0
  29. infoman/cli/templates/project/.env.example.template +1 -0
  30. infoman/cli/templates/project/.gitignore.template +60 -0
  31. infoman/cli/templates/project/Makefile.template +38 -0
  32. infoman/cli/templates/project/README.md.template +137 -0
  33. infoman/cli/templates/project/deploy.sh.template +97 -0
  34. infoman/cli/templates/project/main.py.template +10 -0
  35. infoman/cli/templates/project/manage.sh.template +97 -0
  36. infoman/cli/templates/project/pyproject.toml.template +47 -0
  37. infoman/cli/templates/project/service.sh.template +203 -0
  38. infoman/config/__init__.py +25 -0
  39. infoman/config/base.py +67 -0
  40. infoman/config/db_cache.py +237 -0
  41. infoman/config/db_relation.py +181 -0
  42. infoman/config/db_vector.py +39 -0
  43. infoman/config/jwt.py +16 -0
  44. infoman/config/llm.py +16 -0
  45. infoman/config/log.py +627 -0
  46. infoman/config/mq.py +26 -0
  47. infoman/config/settings.py +65 -0
  48. infoman/llm/__init__.py +0 -0
  49. infoman/llm/llm.py +297 -0
  50. infoman/logger/__init__.py +57 -0
  51. infoman/logger/context.py +191 -0
  52. infoman/logger/core.py +358 -0
  53. infoman/logger/filters.py +157 -0
  54. infoman/logger/formatters.py +138 -0
  55. infoman/logger/handlers.py +276 -0
  56. infoman/logger/metrics.py +160 -0
  57. infoman/performance/README.md +583 -0
  58. infoman/performance/__init__.py +19 -0
  59. infoman/performance/cli.py +215 -0
  60. infoman/performance/config.py +166 -0
  61. infoman/performance/reporter.py +519 -0
  62. infoman/performance/runner.py +303 -0
  63. infoman/performance/standards.py +222 -0
  64. infoman/service/__init__.py +8 -0
  65. infoman/service/app.py +67 -0
  66. infoman/service/core/__init__.py +0 -0
  67. infoman/service/core/auth.py +105 -0
  68. infoman/service/core/lifespan.py +132 -0
  69. infoman/service/core/monitor.py +57 -0
  70. infoman/service/core/response.py +37 -0
  71. infoman/service/exception/__init__.py +7 -0
  72. infoman/service/exception/error.py +274 -0
  73. infoman/service/exception/exception.py +25 -0
  74. infoman/service/exception/handler.py +238 -0
  75. infoman/service/infrastructure/__init__.py +8 -0
  76. infoman/service/infrastructure/base.py +212 -0
  77. infoman/service/infrastructure/db_cache/__init__.py +8 -0
  78. infoman/service/infrastructure/db_cache/manager.py +194 -0
  79. infoman/service/infrastructure/db_relation/__init__.py +41 -0
  80. infoman/service/infrastructure/db_relation/manager.py +300 -0
  81. infoman/service/infrastructure/db_relation/manager_pro.py +408 -0
  82. infoman/service/infrastructure/db_relation/mysql.py +52 -0
  83. infoman/service/infrastructure/db_relation/pgsql.py +54 -0
  84. infoman/service/infrastructure/db_relation/sqllite.py +25 -0
  85. infoman/service/infrastructure/db_vector/__init__.py +40 -0
  86. infoman/service/infrastructure/db_vector/manager.py +201 -0
  87. infoman/service/infrastructure/db_vector/qdrant.py +322 -0
  88. infoman/service/infrastructure/mq/__init__.py +15 -0
  89. infoman/service/infrastructure/mq/manager.py +178 -0
  90. infoman/service/infrastructure/mq/nats/__init__.py +0 -0
  91. infoman/service/infrastructure/mq/nats/nats_client.py +57 -0
  92. infoman/service/infrastructure/mq/nats/nats_event_router.py +25 -0
  93. infoman/service/launch.py +284 -0
  94. infoman/service/middleware/__init__.py +7 -0
  95. infoman/service/middleware/base.py +41 -0
  96. infoman/service/middleware/logging.py +51 -0
  97. infoman/service/middleware/rate_limit.py +301 -0
  98. infoman/service/middleware/request_id.py +21 -0
  99. infoman/service/middleware/white_list.py +24 -0
  100. infoman/service/models/__init__.py +8 -0
  101. infoman/service/models/base.py +441 -0
  102. infoman/service/models/type/embed.py +70 -0
  103. infoman/service/routers/__init__.py +18 -0
  104. infoman/service/routers/health_router.py +311 -0
  105. infoman/service/routers/monitor_router.py +44 -0
  106. infoman/service/utils/__init__.py +8 -0
  107. infoman/service/utils/cache/__init__.py +0 -0
  108. infoman/service/utils/cache/cache.py +192 -0
  109. infoman/service/utils/module_loader.py +10 -0
  110. infoman/service/utils/parse.py +10 -0
  111. infoman/service/utils/resolver/__init__.py +8 -0
  112. infoman/service/utils/resolver/base.py +47 -0
  113. infoman/service/utils/resolver/resp.py +102 -0
  114. infoman/service/vector/__init__.py +20 -0
  115. infoman/service/vector/base.py +56 -0
  116. infoman/service/vector/qdrant.py +125 -0
  117. infoman/service/vector/service.py +67 -0
  118. infoman/utils/__init__.py +2 -0
  119. infoman/utils/decorators/__init__.py +8 -0
  120. infoman/utils/decorators/cache.py +137 -0
  121. infoman/utils/decorators/retry.py +99 -0
  122. infoman/utils/decorators/safe_execute.py +99 -0
  123. infoman/utils/decorators/timing.py +99 -0
  124. infoman/utils/encryption/__init__.py +8 -0
  125. infoman/utils/encryption/aes.py +66 -0
  126. infoman/utils/encryption/ecc.py +108 -0
  127. infoman/utils/encryption/rsa.py +112 -0
  128. infoman/utils/file/__init__.py +0 -0
  129. infoman/utils/file/handler.py +22 -0
  130. infoman/utils/hash/__init__.py +0 -0
  131. infoman/utils/hash/hash.py +61 -0
  132. infoman/utils/http/__init__.py +8 -0
  133. infoman/utils/http/client.py +62 -0
  134. infoman/utils/http/info.py +94 -0
  135. infoman/utils/http/result.py +19 -0
  136. infoman/utils/notification/__init__.py +8 -0
  137. infoman/utils/notification/feishu.py +35 -0
  138. infoman/utils/text/__init__.py +8 -0
  139. infoman/utils/text/extractor.py +111 -0
  140. infomankit-0.3.23.dist-info/METADATA +632 -0
  141. infomankit-0.3.23.dist-info/RECORD +143 -0
  142. infomankit-0.3.23.dist-info/WHEEL +4 -0
  143. infomankit-0.3.23.dist-info/entry_points.txt +5 -0
@@ -0,0 +1,634 @@
1
+ """
2
+ Project scaffolding generator
3
+
4
+ Generates standard project structure based on infoman/service architecture.
5
+ """
6
+
7
+ import os
8
+ from pathlib import Path
9
+ from typing import Optional, Dict, Any
10
+
11
+
12
+ class ProjectScaffold:
13
+ """Project structure generator based on infoman/service standard"""
14
+
15
+ @staticmethod
16
+ def _get_templates_dir() -> Path:
17
+ """Get the templates directory path"""
18
+ return Path(__file__).parent / "templates"
19
+
20
+ @staticmethod
21
+ def _load_template(template_path: str) -> str:
22
+ """
23
+ Load a template file from the templates directory
24
+
25
+ Args:
26
+ template_path: Relative path to template file (e.g., "app/app.py.template")
27
+
28
+ Returns:
29
+ Template content as string
30
+ """
31
+ templates_dir = ProjectScaffold._get_templates_dir()
32
+ full_path = templates_dir / template_path
33
+
34
+ if not full_path.exists():
35
+ raise FileNotFoundError(f"Template file not found: {full_path}")
36
+
37
+ return full_path.read_text(encoding="utf-8")
38
+
39
+ @staticmethod
40
+ def _build_structure_from_templates() -> Dict[str, Any]:
41
+ """
42
+ Build STRUCTURE dictionary by loading from template files
43
+
44
+ Returns:
45
+ Dictionary representing the app/ directory structure
46
+ """
47
+ return {
48
+ "__init__.py": ProjectScaffold._load_template("app/__init__.py.template"),
49
+ "app.py": ProjectScaffold._load_template("app/app.py.template"),
50
+ "models": {
51
+ "__init__.py": '"""\nData models\n"""\n',
52
+ "base.py": ProjectScaffold._load_template("app/models_base.py.template"),
53
+ "entity": {
54
+ "__init__.py": ProjectScaffold._load_template("app/models_entity_init.py.template"),
55
+ },
56
+ "schemas": {
57
+ "__init__.py": ProjectScaffold._load_template("app/models_schemas_init.py.template"),
58
+ },
59
+ },
60
+ "routers": {
61
+ "__init__.py": ProjectScaffold._load_template("app/routers_init.py.template"),
62
+ },
63
+ "services": {
64
+ "__init__.py": ProjectScaffold._load_template("app/services_init.py.template"),
65
+ },
66
+ "repository": {
67
+ "__init__.py": ProjectScaffold._load_template("app/repository_init.py.template"),
68
+ },
69
+ "utils": {
70
+ "__init__.py": ProjectScaffold._load_template("app/utils_init.py.template"),
71
+ },
72
+ "static": {
73
+ "css": {
74
+ "style.css": ProjectScaffold._load_template("app/static_style.css.template"),
75
+ },
76
+ "js": {
77
+ "main.js": ProjectScaffold._load_template("app/static_main.js.template"),
78
+ },
79
+ "images": {},
80
+ "index.html": ProjectScaffold._load_template("app/static_index.html.template"),
81
+ },
82
+ "template": {},
83
+ }
84
+
85
+ @staticmethod
86
+ def _build_config_structure_from_templates() -> Dict[str, str]:
87
+ """
88
+ Build CONFIG_STRUCTURE dictionary by loading from template files
89
+
90
+ Returns:
91
+ Dictionary representing the config/ directory structure
92
+ """
93
+ return {
94
+ ".env.dev": ProjectScaffold._load_template("config/.env.dev.template"),
95
+ ".env.prod": ProjectScaffold._load_template("config/.env.prod.template"),
96
+ "README.md": ProjectScaffold._load_template("config/README.md.template"),
97
+ }
98
+
99
+ # 标准项目目录结构(基于用户需求的 app 结构)
100
+ # STRUCTURE is built dynamically from template files
101
+ STRUCTURE = None # Will be initialized in __init__
102
+
103
+ # Add config directory structure
104
+ CONFIG_STRUCTURE = None # Will be initialized in __init__
105
+
106
+ # Old CONFIG_STRUCTURE (kept for reference, will be removed)
107
+ _OLD_CONFIG_STRUCTURE = {
108
+ ".env.dev": """# Application Settings
109
+ APP_NAME={project_name}
110
+ APP_ENV=dev
111
+ APP_PORT=8000
112
+ APP_DEBUG=true
113
+
114
+ LOG_DIR=logs
115
+ LOG_LEVEL=DEBUG
116
+ LOG_FORMAT=simple
117
+
118
+ USE_TEMPLATES=1
119
+ USE_PRO_ORM=1
120
+ TEMPLATE_DIR=./app/template
121
+ #USE_STATIC=1
122
+
123
+ # Database Configuration (infomankit format)
124
+ MYSQL_ENABLED=true
125
+ MYSQL_HOST=127.0.0.1
126
+ MYSQL_PORT=3306
127
+ MYSQL_DB=XXX
128
+ MYSQL_USER=XXX
129
+ MYSQL_PASSWORD=XXX
130
+ MYSQL_CHARSET=utf8mb4
131
+ MYSQL_POOL_MAX_SIZE=10
132
+ MYSQL_POOL_RECYCLE=3600
133
+ MYSQL_ECHO=false
134
+ MYSQL_MODELS_PATH=app.models
135
+ MYSQL_MODELS=entity
136
+
137
+
138
+ # JWT Configuration
139
+ JWT_SECRET_KEY=your-secret-key-change-this-in-production
140
+ JWT_ALGORITHM=HS256
141
+ JWT_ACCESS_TOKEN_EXPIRE_MINUTES=30
142
+
143
+ # CORS Configuration (comma-separated origins)
144
+ CORS_ORIGINS=http://localhost:3000,http://localhost:8000
145
+
146
+ # Redis Configuration (Optional)
147
+ REDIS_HOST=localhost
148
+ REDIS_PORT=6379
149
+ REDIS_DB=0
150
+ REDIS_PASSWORD=
151
+ """,
152
+ ".env.prod": """# Application Settings
153
+ APP_NAME={project_name}
154
+ APP_ENV=prod
155
+ APP_PORT=8000
156
+ APP_DEBUG=false
157
+
158
+ LOG_DIR=logs
159
+ LOG_LEVEL=INFO
160
+ LOG_FORMAT=json
161
+
162
+ USE_TEMPLATES=1
163
+ USE_PRO_ORM=1
164
+ TEMPLATE_DIR=./app/template
165
+ #USE_STATIC=1
166
+
167
+ # Database Configuration (infomankit format)
168
+ MYSQL_ENABLED=true
169
+ MYSQL_HOST=127.0.0.1
170
+ MYSQL_PORT=3306
171
+ MYSQL_DB=XXX
172
+ MYSQL_USER=XXX
173
+ MYSQL_PASSWORD=XXX
174
+ MYSQL_CHARSET=utf8mb4
175
+ MYSQL_POOL_MAX_SIZE=20
176
+ MYSQL_POOL_RECYCLE=3600
177
+ MYSQL_ECHO=false
178
+ MYSQL_MODELS_PATH=app.models
179
+ MYSQL_MODELS=entity
180
+
181
+
182
+ # JWT Configuration
183
+ JWT_SECRET_KEY=your-secret-key-change-this-in-production
184
+ JWT_ALGORITHM=HS256
185
+ JWT_ACCESS_TOKEN_EXPIRE_MINUTES=30
186
+
187
+ # CORS Configuration (comma-separated origins)
188
+ CORS_ORIGINS=https://your-domain.com
189
+
190
+ # Redis Configuration (Optional)
191
+ REDIS_HOST=localhost
192
+ REDIS_PORT=6379
193
+ REDIS_DB=0
194
+ REDIS_PASSWORD=
195
+ """,
196
+ "README.md": """# Configuration Files
197
+
198
+ Environment-specific configuration files for {project_name}.
199
+
200
+ ## Available Configurations
201
+
202
+ - `.env.dev` - Development environment configuration
203
+ - `.env.prod` - Production environment configuration
204
+
205
+ ## Usage
206
+
207
+ Copy the appropriate config file to your project root as `.env`:
208
+
209
+ ```bash
210
+ # For development
211
+ cp config/.env.dev .env
212
+
213
+ # For production
214
+ cp config/.env.prod .env
215
+ ```
216
+
217
+ Then edit `.env` with your actual values.
218
+
219
+ ## Configuration Variables
220
+
221
+ - **APP_NAME**: Application name
222
+ - **APP_ENV**: Environment (dev/prod)
223
+ - **APP_PORT**: Server port
224
+ - **APP_DEBUG**: Debug mode (true/false)
225
+ - **LOG_LEVEL**: Logging level (DEBUG/INFO/WARNING/ERROR)
226
+ - **MYSQL_***: MySQL database configuration
227
+ - **JWT_***: JWT authentication settings
228
+ - **CORS_ORIGINS**: Allowed CORS origins
229
+ - **REDIS_***: Redis configuration (optional)
230
+ """,
231
+ }
232
+
233
+ def __init__(self, project_name: str, target_dir: Optional[Path] = None):
234
+ """
235
+ 初始化项目脚手架
236
+
237
+ Args:
238
+ project_name: 项目名称
239
+ target_dir: 目标目录,默认为当前目录下的项目名称目录
240
+ """
241
+ self.project_name = project_name
242
+ self.target_dir = target_dir or Path.cwd() / project_name
243
+
244
+ # Initialize structures from templates
245
+ if ProjectScaffold.STRUCTURE is None:
246
+ ProjectScaffold.STRUCTURE = ProjectScaffold._build_structure_from_templates()
247
+ if ProjectScaffold.CONFIG_STRUCTURE is None:
248
+ ProjectScaffold.CONFIG_STRUCTURE = ProjectScaffold._build_config_structure_from_templates()
249
+
250
+ def create_structure(self, structure: dict, parent_path: Path) -> None:
251
+ """
252
+ 递归创建目录结构
253
+
254
+ Args:
255
+ structure: 目录结构字典
256
+ parent_path: 父目录路径
257
+ """
258
+ for name, content in structure.items():
259
+ current_path = parent_path / name
260
+
261
+ if isinstance(content, dict):
262
+ # 创建目录
263
+ current_path.mkdir(parents=True, exist_ok=True)
264
+ # 递归创建子结构
265
+ self.create_structure(content, current_path)
266
+ else:
267
+ # 创建文件
268
+ current_path.parent.mkdir(parents=True, exist_ok=True)
269
+ # Format content with project name
270
+ formatted_content = content.format(project_name=self.project_name)
271
+ with open(current_path, "w", encoding="utf-8") as f:
272
+ f.write(formatted_content)
273
+
274
+ def create_config_files(self) -> None:
275
+ """创建配置文件"""
276
+ # .env
277
+ env_template = self._load_template("project/.env.example.template")
278
+ (self.target_dir / ".env").write_text(
279
+ env_template.format(project_name=self.project_name),
280
+ encoding="utf-8"
281
+ )
282
+
283
+ # pyproject.toml
284
+ pyproject_template = self._load_template("project/pyproject.toml.template")
285
+ (self.target_dir / "pyproject.toml").write_text(
286
+ pyproject_template.format(project_name=self.project_name),
287
+ encoding="utf-8"
288
+ )
289
+
290
+ # README.md
291
+ readme_template = self._load_template("project/README.md.template")
292
+ (self.target_dir / "README.md").write_text(
293
+ readme_template.format(project_name=self.project_name),
294
+ encoding="utf-8"
295
+ )
296
+
297
+ # Create doc directory structure
298
+ doc_dir = self.target_dir / "doc"
299
+ doc_dir.mkdir(exist_ok=True)
300
+
301
+ # Create API documentation template
302
+ api_doc = """# API 开发指南
303
+
304
+ ## 快速开始
305
+
306
+ 本文档介绍如何使用 {project_name} 开发 API。
307
+
308
+ ## 数据流程
309
+
310
+ 1. **定义数据模型** (`models/entity/`) - 数据库 ORM 模型
311
+ 2. **创建 DTO** (`models/dto/`) - API 请求/响应模型
312
+ 3. **实现 Repository** (`repository/`) - 数据访问层
313
+ 4. **编写 Service** (`services/`) - 业务逻辑
314
+ 5. **添加 Router** (`routers/`) - API 端点
315
+
316
+ ## 示例:用户管理 API
317
+
318
+ ### 1. 定义 Entity (models/entity/user.py)
319
+
320
+ ```python
321
+ from infoman.service.models.base import BaseModel
322
+ from sqlalchemy import Column, String, Integer
323
+
324
+ class User(BaseModel):
325
+ __tablename__ = "users"
326
+
327
+ id = Column(Integer, primary_key=True)
328
+ name = Column(String(100), nullable=False)
329
+ email = Column(String(100), unique=True)
330
+ ```
331
+
332
+ ### 2. 创建 DTO (models/dto/user.py)
333
+
334
+ ```python
335
+ from pydantic import BaseModel, EmailStr
336
+
337
+ class UserCreateDTO(BaseModel):
338
+ name: str
339
+ email: EmailStr
340
+
341
+ class UserResponseDTO(BaseModel):
342
+ id: int
343
+ name: str
344
+ email: str
345
+ ```
346
+
347
+ ### 3. 实现 Repository (repository/user_repository.py)
348
+
349
+ ```python
350
+ from sqlalchemy.ext.asyncio import AsyncSession
351
+ from models.entity.user import User
352
+ from models.dto.user import UserCreateDTO
353
+
354
+ class UserRepository:
355
+ def __init__(self, session: AsyncSession):
356
+ self.session = session
357
+
358
+ async def create(self, data: UserCreateDTO) -> User:
359
+ user = User(**data.model_dump())
360
+ self.session.add(user)
361
+ await self.session.commit()
362
+ return user
363
+ ```
364
+
365
+ ### 4. 创建 Service (services/user_service.py)
366
+
367
+ ```python
368
+ from repository.user_repository import UserRepository
369
+ from models.dto.user import UserCreateDTO, UserResponseDTO
370
+
371
+ class UserService:
372
+ def __init__(self, repo: UserRepository):
373
+ self.repo = repo
374
+
375
+ async def create_user(self, data: UserCreateDTO) -> UserResponseDTO:
376
+ user = await self.repo.create(data)
377
+ return UserResponseDTO(
378
+ id=user.id,
379
+ name=user.name,
380
+ email=user.email
381
+ )
382
+ ```
383
+
384
+ ### 5. 添加 Router (routers/user_router.py)
385
+
386
+ ```python
387
+ from fastapi import APIRouter, Depends
388
+ from models.dto.user import UserCreateDTO, UserResponseDTO
389
+ from services.user_service import UserService
390
+
391
+ router = APIRouter(prefix="/users", tags=["Users"])
392
+
393
+ @router.post("/", response_model=UserResponseDTO)
394
+ async def create_user(
395
+ data: UserCreateDTO,
396
+ service: UserService = Depends()
397
+ ):
398
+ return await service.create_user(data)
399
+ ```
400
+
401
+ ### 6. 注册 Router (routers/__init__.py)
402
+
403
+ ```python
404
+ from .user_router import router as user_router
405
+
406
+ api_router.include_router(user_router)
407
+ ```
408
+
409
+ ## 更多信息
410
+
411
+ 查看 infomankit 文档:https://github.com/infoman-lib/infoman-pykit
412
+ """.format(project_name=self.project_name)
413
+
414
+ (doc_dir / "1-API-GUIDE.md").write_text(api_doc, encoding="utf-8")
415
+
416
+ # Create deployment guide
417
+ deploy_doc = """# 部署指南
418
+
419
+ ## Docker 部署(推荐)
420
+
421
+ ### 1. 构建镜像
422
+
423
+ ```bash
424
+ make docker-build
425
+ ```
426
+
427
+ ### 2. 启动服务
428
+
429
+ ```bash
430
+ make docker-up
431
+ ```
432
+
433
+ ### 3. 查看日志
434
+
435
+ ```bash
436
+ make docker-logs
437
+ ```
438
+
439
+ ### 4. 停止服务
440
+
441
+ ```bash
442
+ make docker-down
443
+ ```
444
+
445
+ ## 本地部署
446
+
447
+ ### 1. 安装依赖
448
+
449
+ ```bash
450
+ make install
451
+ ```
452
+
453
+ ### 2. 配置环境
454
+
455
+ ```bash
456
+ make init-env
457
+ # 编辑 .env 文件
458
+ ```
459
+
460
+ ### 3. 运行服务
461
+
462
+ ```bash
463
+ # 开发模式
464
+ make dev
465
+
466
+ # 生产模式
467
+ make run
468
+ ```
469
+
470
+ ## 生产环境建议
471
+
472
+ - 使用环境变量管理配置
473
+ - 配置反向代理(Nginx/Caddy)
474
+ - 启用 HTTPS
475
+ - 设置日志轮转
476
+ - 配置健康检查
477
+ - 使用进程管理器(systemd/supervisor)
478
+
479
+ ## 监控
480
+
481
+ 访问以下端点检查服务状态:
482
+
483
+ - `/health` - 健康检查
484
+ - `/api/docs` - API 文档
485
+ - `/metrics` - Prometheus 指标(如已启用)
486
+ """
487
+
488
+ (doc_dir / "2-DEPLOYMENT.md").write_text(deploy_doc, encoding="utf-8")
489
+
490
+ # main.py
491
+ main_py_template = self._load_template("project/main.py.template")
492
+ (self.target_dir / "main.py").write_text(
493
+ main_py_template.format(project_name=self.project_name),
494
+ encoding="utf-8"
495
+ )
496
+
497
+ # .gitignore
498
+ gitignore_template = self._load_template("project/.gitignore.template")
499
+ (self.target_dir / ".gitignore").write_text(
500
+ gitignore_template.format(project_name=self.project_name),
501
+ encoding="utf-8"
502
+ )
503
+
504
+ def create_makefile(self) -> None:
505
+ """创建 Makefile"""
506
+ makefile_template = self._load_template("project/Makefile.template")
507
+ (self.target_dir / "Makefile").write_text(
508
+ makefile_template.format(project_name=self.project_name),
509
+ encoding="utf-8"
510
+ )
511
+
512
+ def create_service_script(self) -> None:
513
+ """创建 service.sh 服务管理脚本"""
514
+ service_sh_template = self._load_template("project/service.sh.template")
515
+ service_path = self.target_dir / "service.sh"
516
+ service_path.write_text(
517
+ service_sh_template.format(project_name=self.project_name),
518
+ encoding="utf-8"
519
+ )
520
+ # Make executable
521
+ import os
522
+ os.chmod(service_path, 0o755)
523
+
524
+ def generate_docker_files(self) -> None:
525
+ """生成 Docker 相关文件到 /docker 目录"""
526
+ docker_dir = self.target_dir / "docker"
527
+ docker_dir.mkdir(parents=True, exist_ok=True)
528
+
529
+ # Dockerfile
530
+ dockerfile_template = self._load_template("docker/Dockerfile.template")
531
+ (docker_dir / "Dockerfile").write_text(
532
+ dockerfile_template.format(project_name=self.project_name),
533
+ encoding="utf-8"
534
+ )
535
+
536
+ # docker-compose.yml
537
+ docker_compose_template = self._load_template("docker/docker-compose.yml.template")
538
+ (docker_dir / "docker-compose.yml").write_text(
539
+ docker_compose_template.format(project_name=self.project_name),
540
+ encoding="utf-8"
541
+ )
542
+
543
+ # .dockerignore
544
+ dockerignore_template = self._load_template("docker/.dockerignore.template")
545
+ (docker_dir / ".dockerignore").write_text(
546
+ dockerignore_template.format(project_name=self.project_name),
547
+ encoding="utf-8"
548
+ )
549
+
550
+ # MySQL configuration
551
+ mysql_conf_dir = docker_dir / "mysql" / "conf.d"
552
+ mysql_conf_dir.mkdir(parents=True, exist_ok=True)
553
+
554
+ mysql_config_template = self._load_template("docker/mysql_custom.cnf.template")
555
+ (mysql_conf_dir / "custom.cnf").write_text(
556
+ mysql_config_template.format(project_name=self.project_name),
557
+ encoding="utf-8"
558
+ )
559
+
560
+ # MySQL init script
561
+ mysql_init_dir = docker_dir / "mysql" / "init"
562
+ mysql_init_dir.mkdir(parents=True, exist_ok=True)
563
+
564
+ mysql_init_template = self._load_template("docker/mysql_init.sql.template")
565
+ (mysql_init_dir / "01-init.sql").write_text(
566
+ mysql_init_template.format(project_name=self.project_name),
567
+ encoding="utf-8"
568
+ )
569
+
570
+ # README
571
+ readme_template = self._load_template("docker/README.md.template")
572
+ (docker_dir / "README.md").write_text(
573
+ readme_template.format(project_name=self.project_name),
574
+ encoding="utf-8"
575
+ )
576
+
577
+ print(f"✓ Docker files generated in '{self.project_name}/docker/' directory")
578
+ print(f"\n📦 Generated Docker files:")
579
+ print(f" • docker/Dockerfile")
580
+ print(f" • docker/docker-compose.yml")
581
+ print(f" • docker/.dockerignore")
582
+ print(f" • docker/mysql/conf.d/custom.cnf")
583
+ print(f" • docker/mysql/init/01-init.sql")
584
+ print(f" • docker/README.md")
585
+ print(f"\n🚀 Quick start:")
586
+ print(f" cd {self.project_name}/docker")
587
+ print(f" docker-compose up -d")
588
+
589
+ def generate(self) -> None:
590
+ """生成完整的项目结构"""
591
+ if self.target_dir.exists():
592
+ raise FileExistsError(f"Directory '{self.target_dir}' already exists")
593
+
594
+ # 创建项目根目录
595
+ self.target_dir.mkdir(parents=True, exist_ok=True)
596
+
597
+ # 创建 app 目录结构
598
+ app_dir = self.target_dir / "app"
599
+ app_dir.mkdir(parents=True, exist_ok=True)
600
+ self.create_structure(self.STRUCTURE, app_dir)
601
+
602
+ # 创建 config 目录结构
603
+ config_dir = self.target_dir / "config"
604
+ config_dir.mkdir(parents=True, exist_ok=True)
605
+ self.create_structure(self.CONFIG_STRUCTURE, config_dir)
606
+
607
+ # 创建配置文件
608
+ self.create_config_files()
609
+
610
+ # 创建 Makefile
611
+ self.create_makefile()
612
+
613
+ # 创建 service.sh
614
+ self.create_service_script()
615
+
616
+ print(f"✓ Project '{self.project_name}' created successfully!")
617
+ print(f"\nGenerated structure:")
618
+ print(f" 📁 Application code (app/)")
619
+ print(f" 📁 Configuration (config/)")
620
+ print(f" 📄 Environment (.env)")
621
+ print(f" 🔧 Development tools (Makefile)")
622
+ print(f" 🚀 Service management (service.sh)")
623
+ print(f"\nNext steps:")
624
+ print(f" cd {self.project_name}")
625
+ print(f" make help # See all commands")
626
+ print(f"\n Quick start (local):")
627
+ print(f" make init-env && make install && make dev")
628
+ print(f"\n Quick start (Docker):")
629
+ print(f" make docker-build && make docker-up")
630
+ print(f"\n📚 Documentation:")
631
+ print(f" README.md - Project overview")
632
+ print(f" doc/1-API-GUIDE.md - API development guide")
633
+ print(f" doc/2-DEPLOYMENT.md - Deployment instructions")
634
+ print(f"\n🌐 After starting: http://localhost:8000/docs")