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
infoman/__init__.py ADDED
@@ -0,0 +1 @@
1
+
infoman/cli/README.md ADDED
@@ -0,0 +1,378 @@
1
+ # Infoman CLI - 项目脚手架工具
2
+
3
+ 快速生成基于 infomankit 标准架构的项目结构。
4
+
5
+ ## 安装
6
+
7
+ ```bash
8
+ pip install infomankit
9
+ ```
10
+
11
+ ## 使用方法
12
+
13
+ ### 1. 交互式创建项目
14
+
15
+ ```bash
16
+ infomancli init
17
+ # 会提示输入项目名称
18
+ ```
19
+
20
+ ### 2. 直接指定项目名称
21
+
22
+ ```bash
23
+ infomancli init my-awesome-project
24
+ ```
25
+
26
+ ### 3. 指定目标目录
27
+
28
+ ```bash
29
+ # 在指定目录下创建项目
30
+ infomancli init my-project --dir /path/to/workspace
31
+
32
+ # 在临时目录测试
33
+ infomancli init test-project --dir /tmp
34
+ ```
35
+
36
+ ### 4. 查看帮助
37
+
38
+ ```bash
39
+ infomancli --help
40
+ infomancli --version
41
+ ```
42
+
43
+ ## 生成的项目结构
44
+
45
+ 生成的项目遵循 `infoman/service` 的标准架构:
46
+
47
+ ```
48
+ my-project/
49
+ ├── .env.example # 环境变量模板
50
+ ├── .gitignore # Git 忽略文件
51
+ ├── README.md # 项目说明文档
52
+ ├── main.py # 主应用入口
53
+ ├── pyproject.toml # 项目配置文件
54
+
55
+ ├── core/ # 核心业务逻辑
56
+ │ ├── __init__.py
57
+ │ ├── auth.py # 认证授权
58
+ │ └── response.py # 标准响应模型
59
+
60
+ ├── routers/ # API 路由
61
+ │ └── __init__.py # API 路由注册
62
+
63
+ ├── models/ # 数据模型
64
+ │ ├── __init__.py
65
+ │ ├── entity/ # 数据库实体 (ORM 模型)
66
+ │ ├── dto/ # 数据传输对象 (API 模型)
67
+ │ └── schemas/ # Pydantic 验证模式
68
+
69
+ ├── repository/ # 数据访问层
70
+ │ └── __init__.py
71
+
72
+ ├── services/ # 业务逻辑服务
73
+ │ └── __init__.py
74
+
75
+ ├── exception/ # 自定义异常
76
+ │ └── __init__.py
77
+
78
+ ├── middleware/ # 自定义中间件
79
+ │ └── __init__.py
80
+
81
+ ├── infrastructure/ # 基础设施
82
+ │ ├── __init__.py
83
+ │ ├── database/ # 数据库连接
84
+ │ └── cache/ # 缓存管理
85
+
86
+ └── utils/ # 工具函数
87
+ ├── __init__.py
88
+ ├── cache/ # 缓存工具
89
+ └── parse/ # 解析工具
90
+ ```
91
+
92
+ ## 项目初始化步骤
93
+
94
+ 创建项目后,按照以下步骤进行初始化:
95
+
96
+ ```bash
97
+ # 1. 进入项目目录
98
+ cd my-project
99
+
100
+ # 2. 安装依赖
101
+ pip install -e .
102
+
103
+ # 3. 复制环境变量文件
104
+ cp .env.example .env
105
+
106
+ # 4. 编辑 .env 配置你的环境变量
107
+ vim .env
108
+
109
+ # 5. 运行开发服务器
110
+ infoman-serve run main:app --reload
111
+
112
+ # 6. 访问 API 文档
113
+ open http://localhost:8000/docs
114
+ ```
115
+
116
+ ## 架构说明
117
+
118
+ 生成的项目遵循 infomankit 的标准架构,各目录职责如下:
119
+
120
+ ### core/
121
+ 核心业务逻辑和应用生命周期管理
122
+ - `auth.py` - 认证和授权逻辑
123
+ - `response.py` - 标准 API 响应模型
124
+
125
+ ### routers/
126
+ API 端点和路由定义
127
+ - 所有的 API 路由在此定义
128
+ - 使用 FastAPI 的 `APIRouter`
129
+
130
+ ### models/
131
+ 数据模型定义
132
+ - `entity/` - 数据库 ORM 模型 (支持 Tortoise ORM 或 SQLAlchemy)
133
+ - `dto/` - API 请求/响应的数据传输对象
134
+ - `schemas/` - Pydantic 数据验证模式
135
+
136
+ ### repository/
137
+ 数据访问层 (Repository 模式)
138
+ - 封装数据库操作
139
+ - 提供数据访问接口
140
+
141
+ ### services/
142
+ 业务逻辑服务层
143
+ - 处理复杂的业务逻辑
144
+ - 协调多个 repository
145
+
146
+ ### exception/
147
+ 自定义异常
148
+ - 继承自 infomankit 的异常基类
149
+ - 统一的异常处理
150
+
151
+ ### middleware/
152
+ 自定义中间件
153
+ - 可以使用 infomankit 内置的中间件
154
+ - 或实现自定义中间件
155
+
156
+ ### infrastructure/
157
+ 基础设施组件
158
+ - `database/` - 数据库连接和管理
159
+ - `cache/` - 缓存管理
160
+
161
+ ### utils/
162
+ 通用工具函数
163
+ - `cache/` - 缓存装饰器和工具
164
+ - `parse/` - 数据解析工具
165
+
166
+ ## 生成的核心文件说明
167
+
168
+ ### main.py
169
+ 包含 FastAPI 应用的入口点:
170
+ - 使用 `infoman.service.app.create_app` 创建应用
171
+ - 注册路由
172
+ - 提供基础的健康检查端点
173
+
174
+ ### pyproject.toml
175
+ 项目配置文件:
176
+ - 项目元数据
177
+ - 依赖声明 (默认包含 `infomankit[web]`)
178
+ - 开发依赖和工具配置
179
+
180
+ ### .env.example
181
+ 环境变量模板:
182
+ - 应用基础配置 (名称、端口、日志)
183
+ - 数据库配置 (MySQL, PostgreSQL)
184
+ - 缓存配置 (Redis)
185
+ - 向量数据库配置 (Qdrant)
186
+ - 消息队列配置 (NATS)
187
+ - LLM 配置
188
+
189
+ ### README.md
190
+ 项目说明文档:
191
+ - 项目介绍和快速开始
192
+ - 项目结构说明
193
+ - API 开发流程
194
+ - 使用示例
195
+
196
+ ## 开发流程
197
+
198
+ ### 1. 创建数据模型
199
+
200
+ 在 `models/entity/` 创建 ORM 模型:
201
+ ```python
202
+ from infoman.service.models.base import BaseModel
203
+ from sqlalchemy import Column, String, Integer
204
+
205
+ class User(BaseModel):
206
+ __tablename__ = "users"
207
+
208
+ id = Column(Integer, primary_key=True)
209
+ name = Column(String(100), nullable=False)
210
+ email = Column(String(100), unique=True)
211
+ ```
212
+
213
+ ### 2. 定义 DTO
214
+
215
+ 在 `models/dto/` 创建 API 模型:
216
+ ```python
217
+ from pydantic import BaseModel, EmailStr
218
+
219
+ class UserCreateDTO(BaseModel):
220
+ name: str
221
+ email: EmailStr
222
+
223
+ class UserResponseDTO(BaseModel):
224
+ id: int
225
+ name: str
226
+ email: str
227
+ ```
228
+
229
+ ### 3. 实现 Repository
230
+
231
+ 在 `repository/` 创建数据访问层:
232
+ ```python
233
+ from sqlalchemy.ext.asyncio import AsyncSession
234
+ from sqlalchemy import select
235
+ from models.entity import User
236
+
237
+ class UserRepository:
238
+ def __init__(self, session: AsyncSession):
239
+ self.session = session
240
+
241
+ async def get_by_id(self, user_id: int) -> User | None:
242
+ result = await self.session.execute(
243
+ select(User).where(User.id == user_id)
244
+ )
245
+ return result.scalar_one_or_none()
246
+ ```
247
+
248
+ ### 4. 创建 Service
249
+
250
+ 在 `services/` 实现业务逻辑:
251
+ ```python
252
+ from repository.user_repository import UserRepository
253
+ from models.dto import UserCreateDTO, UserResponseDTO
254
+
255
+ class UserService:
256
+ def __init__(self, repo: UserRepository):
257
+ self.repo = repo
258
+
259
+ async def create_user(self, data: UserCreateDTO) -> UserResponseDTO:
260
+ # 业务逻辑
261
+ user = await self.repo.create(data)
262
+ return UserResponseDTO.from_orm(user)
263
+ ```
264
+
265
+ ### 5. 添加 API 端点
266
+
267
+ 在 `routers/` 创建路由:
268
+ ```python
269
+ from fastapi import APIRouter, Depends
270
+ from models.dto import UserCreateDTO, UserResponseDTO
271
+
272
+ router = APIRouter(prefix="/users", tags=["Users"])
273
+
274
+ @router.post("/", response_model=UserResponseDTO)
275
+ async def create_user(data: UserCreateDTO):
276
+ # 处理逻辑
277
+ pass
278
+ ```
279
+
280
+ 在 `routers/__init__.py` 注册路由:
281
+ ```python
282
+ from .user_router import router as user_router
283
+ api_router.include_router(user_router)
284
+ ```
285
+
286
+ ## 扩展项目
287
+
288
+ 根据需求安装额外的依赖:
289
+
290
+ ```bash
291
+ # 添加数据库支持 (SQLAlchemy)
292
+ pip install "infomankit[database-alchemy]"
293
+
294
+ # 添加缓存支持
295
+ pip install "infomankit[cache]"
296
+
297
+ # 添加 LLM 支持
298
+ pip install "infomankit[llm]"
299
+
300
+ # 添加向量数据库支持
301
+ pip install "infomankit[vector]"
302
+
303
+ # 添加消息队列支持
304
+ pip install "infomankit[messaging]"
305
+
306
+ # 完整功能
307
+ pip install "infomankit[full]"
308
+ ```
309
+
310
+ 在 `pyproject.toml` 中更新依赖:
311
+ ```toml
312
+ dependencies = [
313
+ "infomankit[web,database-alchemy,cache]>=0.3.0",
314
+ ]
315
+ ```
316
+
317
+ ## 最佳实践
318
+
319
+ ### 目录使用指南
320
+
321
+ - **core/** - 核心业务逻辑,与技术实现无关
322
+ - **routers/** - API 端点定义,保持精简
323
+ - **models/entity/** - 数据库表结构
324
+ - **models/dto/** - API 输入/输出模型
325
+ - **repository/** - 数据库操作封装
326
+ - **services/** - 复杂业务逻辑编排
327
+ - **exception/** - 自定义异常和错误处理
328
+ - **middleware/** - 请求/响应拦截处理
329
+ - **infrastructure/** - 外部服务连接管理
330
+ - **utils/** - 可复用的工具函数
331
+
332
+ ### 架构原则
333
+
334
+ 1. **分层架构**: Router -> Service -> Repository -> Database
335
+ 2. **依赖注入**: 使用 FastAPI 的依赖注入系统
336
+ 3. **单一职责**: 每个模块只负责一件事
337
+ 4. **异常处理**: 使用 infomankit 提供的异常类
338
+ 5. **日志记录**: 使用 infomankit 的日志系统
339
+ 6. **配置管理**: 使用环境变量和 Pydantic Settings
340
+
341
+ ## 常见问题
342
+
343
+ ### Q: 项目已存在怎么办?
344
+ A: CLI 会检查目录是否存在,如果存在会报错。请选择不同的项目名称或删除现有目录。
345
+
346
+ ### Q: 如何选择 ORM?
347
+ A: 默认支持 SQLAlchemy 2.0。在 `.env` 中设置 `ORM_BACKEND=sqlalchemy` 或 `ORM_BACKEND=tortoise`。
348
+
349
+ ### Q: 如何自定义项目结构?
350
+ A: 生成项目后,可以根据需要添加或删除目录。生成的结构是推荐的最佳实践。
351
+
352
+ ### Q: 可以在现有项目中使用吗?
353
+ A: 建议用于新项目。如果要在现有项目中使用,可以生成到临时目录,然后手动复制需要的部分。
354
+
355
+ ### Q: 与 infoman/service 有什么关系?
356
+ A: 生成的项目结构完全遵循 `infoman/service` 的标准架构,可以无缝使用 infomankit 的所有功能。
357
+
358
+ ## 与 infomankit 的集成
359
+
360
+ 生成的项目自动集成了以下 infomankit 功能:
361
+
362
+ - ✅ FastAPI 应用工厂 (`create_app`)
363
+ - ✅ 异步数据库支持 (Tortoise ORM / SQLAlchemy)
364
+ - ✅ Redis 缓存
365
+ - ✅ 日志系统
366
+ - ✅ 异常处理
367
+ - ✅ 中间件系统
368
+ - ✅ 配置管理
369
+ - ✅ 健康检查端点
370
+
371
+ ## 反馈与贡献
372
+
373
+ - Issue: https://github.com/infoman-lib/infoman-pykit/issues
374
+ - PR: https://github.com/infoman-lib/infoman-pykit/pulls
375
+
376
+ ## 许可证
377
+
378
+ MIT License
@@ -0,0 +1,7 @@
1
+ """
2
+ Infoman CLI - Command Line Interface Tools
3
+
4
+ Provides scaffolding and project generation utilities.
5
+ """
6
+
7
+ __version__ = "0.3.1"
@@ -0,0 +1,3 @@
1
+ """
2
+ CLI commands module
3
+ """
@@ -0,0 +1,312 @@
1
+ """
2
+ Init command - Create a new project structure and generate development files
3
+ """
4
+
5
+ import sys
6
+ from pathlib import Path
7
+ from typing import Optional, Literal
8
+
9
+ from infoman.cli.scaffold import ProjectScaffold
10
+
11
+
12
+ def init_project(project_name: Optional[str] = None, target_dir: Optional[str] = None) -> int:
13
+ """
14
+ Initialize a new project with standard structure
15
+
16
+ Args:
17
+ project_name: Name of the project (optional, will prompt if not provided)
18
+ target_dir: Target directory (optional, defaults to current directory)
19
+
20
+ Returns:
21
+ Exit code (0 for success, 1 for error)
22
+ """
23
+ # Get project name from argument or prompt
24
+ if not project_name:
25
+ try:
26
+ project_name = input("Enter project name: ").strip()
27
+ except (KeyboardInterrupt, EOFError):
28
+ print("\nOperation cancelled.")
29
+ return 1
30
+
31
+ if not project_name:
32
+ print("Error: Project name cannot be empty")
33
+ return 1
34
+
35
+ # Validate project name
36
+ if not project_name.replace("-", "").replace("_", "").isalnum():
37
+ print("Error: Project name can only contain letters, numbers, hyphens, and underscores")
38
+ return 1
39
+
40
+ # Parse target directory
41
+ target_path = Path(target_dir) / project_name if target_dir else None
42
+
43
+ try:
44
+ # Create scaffold generator
45
+ scaffold = ProjectScaffold(project_name, target_path)
46
+
47
+ # Generate project structure
48
+ scaffold.generate()
49
+
50
+ return 0
51
+
52
+ except FileExistsError as e:
53
+ print(f"Error: {e}")
54
+ print("Please choose a different project name or remove the existing directory.")
55
+ return 1
56
+
57
+ except PermissionError as e:
58
+ print(f"Error: Permission denied - {e}")
59
+ return 1
60
+
61
+ except Exception as e:
62
+ print(f"Error: Failed to create project - {e}")
63
+ return 1
64
+
65
+
66
+ def generate_module(
67
+ module_name: str,
68
+ scaffold_type: Literal["basic", "full"] = "basic",
69
+ target_dir: Optional[str] = None
70
+ ) -> int:
71
+ """
72
+ Generate new module in existing project
73
+
74
+ Args:
75
+ module_name: Module name (e.g., 'investor', 'contract')
76
+ scaffold_type: 'basic' or 'full'
77
+ target_dir: Target directory (default: ./app)
78
+
79
+ Returns:
80
+ Exit code (0 for success, 1 for error)
81
+ """
82
+ # Import here to avoid circular dependency
83
+ try:
84
+ # Try to import from command first (temporary during migration)
85
+ import sys
86
+ sys.path.insert(0, str(Path(__file__).parent.parent.parent.parent))
87
+ from command.scaffold import RWAModuleScaffold as ModuleScaffold
88
+ except ImportError:
89
+ try:
90
+ from infoman.cli.module_scaffold import ModuleScaffold
91
+ except ImportError:
92
+ print("Error: Module scaffold not found")
93
+ return 1
94
+
95
+ try:
96
+ target_path = Path(target_dir) if target_dir else Path.cwd() / "app"
97
+
98
+ scaffold = ModuleScaffold(
99
+ module_name=module_name,
100
+ scaffold_type=scaffold_type,
101
+ target_dir=target_path,
102
+ )
103
+ scaffold.generate()
104
+ return 0
105
+ except FileNotFoundError as e:
106
+ print(f"Error: {e}")
107
+ print("Make sure you're in a project directory with an 'app' folder")
108
+ return 1
109
+ except Exception as e:
110
+ print(f"Error: Failed to generate module - {e}")
111
+ import traceback
112
+ traceback.print_exc()
113
+ return 1
114
+
115
+
116
+ def generate_makefile(project_name: Optional[str] = None, force: bool = False) -> int:
117
+ """
118
+ Generate Makefile for existing project
119
+
120
+ Args:
121
+ project_name: Project name (optional, defaults to current directory name)
122
+ force: Overwrite existing Makefile
123
+
124
+ Returns:
125
+ Exit code (0 for success, 1 for error)
126
+ """
127
+ import os
128
+
129
+ # Get project name
130
+ if not project_name:
131
+ project_name = Path.cwd().name
132
+
133
+ # Check if Makefile exists
134
+ makefile_path = Path.cwd() / "Makefile"
135
+ if makefile_path.exists() and not force:
136
+ print(f"Error: Makefile already exists")
137
+ print(f"Use --force to overwrite")
138
+ return 1
139
+
140
+ # Read template
141
+ template_path = Path(__file__).parent.parent / "templates" / "Makefile.template"
142
+ try:
143
+ template_content = template_path.read_text(encoding="utf-8")
144
+ except FileNotFoundError:
145
+ print(f"Error: Template not found at {template_path}")
146
+ return 1
147
+
148
+ # Replace placeholder
149
+ makefile_content = template_content.replace("{{PROJECT_NAME}}", project_name)
150
+
151
+ # Write Makefile
152
+ try:
153
+ makefile_path.write_text(makefile_content, encoding="utf-8")
154
+ print(f"✓ Makefile created successfully!")
155
+ print(f"\nProject: {project_name}")
156
+ print(f"\nRun 'make help' to see available commands.")
157
+ return 0
158
+ except Exception as e:
159
+ print(f"Error: Failed to create Makefile - {e}")
160
+ return 1
161
+
162
+
163
+ def generate_docker(project_name: Optional[str] = None) -> int:
164
+ """
165
+ Generate Docker configuration files for existing project
166
+
167
+ Args:
168
+ project_name: Project name (optional, defaults to current directory name)
169
+
170
+ Returns:
171
+ Exit code (0 for success, 1 for error)
172
+ """
173
+ # Get project name
174
+ if not project_name:
175
+ project_name = Path.cwd().name
176
+
177
+ try:
178
+ # Create scaffold with current directory
179
+ scaffold = ProjectScaffold(project_name, Path.cwd())
180
+
181
+ # Generate Docker files
182
+ scaffold.generate_docker_files()
183
+
184
+ return 0
185
+ except Exception as e:
186
+ print(f"Error: Failed to generate Docker files - {e}")
187
+ import traceback
188
+ traceback.print_exc()
189
+ return 1
190
+
191
+
192
+ def main() -> None:
193
+ """Main entry point for CLI"""
194
+ import argparse
195
+
196
+ parser = argparse.ArgumentParser(
197
+ description="Infoman CLI - Project scaffolding and development tools",
198
+ formatter_class=argparse.RawDescriptionHelpFormatter,
199
+ epilog="""
200
+ Commands:
201
+ init Create a new project with full structure
202
+ makefile Generate Makefile for existing project
203
+ module Generate new module in existing project
204
+ docker Generate Docker configuration files
205
+
206
+ Examples:
207
+ # Project initialization
208
+ infomankit init # Interactive mode
209
+ infomankit init my-project # Create project named 'my-project'
210
+ infomankit init my-app --dir /tmp # Create in specific directory
211
+
212
+ # Makefile generation
213
+ infomankit makefile # Generate Makefile in current directory
214
+ infomankit makefile --force # Overwrite existing Makefile
215
+ infomankit makefile --name my-app # Set project name
216
+
217
+ # Module generation
218
+ infomankit module investor # Generate basic module
219
+ infomankit module token --type full # Generate full module (with utils & tests)
220
+ infomankit module contract --target /path/to/app # Custom target directory
221
+
222
+ # Docker generation
223
+ infomankit docker # Generate Docker files in current project
224
+ infomankit docker --name my-app # Specify project name
225
+
226
+ For more information, visit: https://github.com/infoman-lib/infoman-pykit
227
+ """,
228
+ )
229
+
230
+ parser.add_argument(
231
+ "command",
232
+ choices=["init", "makefile", "module", "docker"],
233
+ help="Command to execute",
234
+ )
235
+
236
+ parser.add_argument(
237
+ "project_name",
238
+ nargs="?",
239
+ help="Name of the project (for init command)",
240
+ )
241
+
242
+ parser.add_argument(
243
+ "--dir",
244
+ "-d",
245
+ dest="target_dir",
246
+ help="Target directory (for init command, default: current directory)",
247
+ )
248
+
249
+ parser.add_argument(
250
+ "--name",
251
+ "-n",
252
+ dest="makefile_name",
253
+ help="Project name (for makefile command, default: current directory name)",
254
+ )
255
+
256
+ parser.add_argument(
257
+ "--type",
258
+ "-t",
259
+ dest="module_type",
260
+ choices=["basic", "full"],
261
+ default="basic",
262
+ help="Module scaffold type (for module command): basic or full",
263
+ )
264
+
265
+ parser.add_argument(
266
+ "--target",
267
+ dest="module_target",
268
+ help="Target directory for module (default: ./app)",
269
+ )
270
+
271
+ parser.add_argument(
272
+ "--force",
273
+ "-f",
274
+ action="store_true",
275
+ help="Force overwrite existing files (for makefile command)",
276
+ )
277
+
278
+ parser.add_argument(
279
+ "--version",
280
+ "-V",
281
+ action="version",
282
+ version="infomankit 0.3.15",
283
+ )
284
+
285
+ args = parser.parse_args()
286
+
287
+ if args.command == "init":
288
+ exit_code = init_project(args.project_name, args.target_dir)
289
+ sys.exit(exit_code)
290
+ elif args.command == "makefile":
291
+ exit_code = generate_makefile(args.makefile_name, args.force)
292
+ sys.exit(exit_code)
293
+ elif args.command == "module":
294
+ if not args.project_name:
295
+ print("Error: Module name is required")
296
+ print("Usage: infomankit module <module_name> [--type basic|full] [--target DIR]")
297
+ sys.exit(1)
298
+ exit_code = generate_module(
299
+ module_name=args.project_name,
300
+ scaffold_type=args.module_type,
301
+ target_dir=args.module_target
302
+ )
303
+ sys.exit(exit_code)
304
+ elif args.command == "docker":
305
+ # For docker command, project_name is optional (uses --name flag or current dir)
306
+ project_name = args.makefile_name or args.project_name
307
+ exit_code = generate_docker(project_name)
308
+ sys.exit(exit_code)
309
+
310
+
311
+ if __name__ == "__main__":
312
+ main()