service-forge 0.1.0__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 (64) hide show
  1. service_forge/api/http_api.py +138 -0
  2. service_forge/api/kafka_api.py +126 -0
  3. service_forge/api/task_manager.py +141 -0
  4. service_forge/api/websocket_api.py +86 -0
  5. service_forge/api/websocket_manager.py +425 -0
  6. service_forge/db/__init__.py +1 -0
  7. service_forge/db/database.py +119 -0
  8. service_forge/llm/__init__.py +62 -0
  9. service_forge/llm/llm.py +56 -0
  10. service_forge/main.py +121 -0
  11. service_forge/model/__init__.py +0 -0
  12. service_forge/model/websocket.py +13 -0
  13. service_forge/proto/foo_input.py +5 -0
  14. service_forge/service.py +111 -0
  15. service_forge/service_config.py +115 -0
  16. service_forge/sft/cli.py +91 -0
  17. service_forge/sft/cmd/config_command.py +67 -0
  18. service_forge/sft/cmd/deploy_service.py +124 -0
  19. service_forge/sft/cmd/list_tars.py +41 -0
  20. service_forge/sft/cmd/service_command.py +149 -0
  21. service_forge/sft/cmd/upload_service.py +36 -0
  22. service_forge/sft/config/injector.py +87 -0
  23. service_forge/sft/config/injector_default_files.py +97 -0
  24. service_forge/sft/config/sf_metadata.py +30 -0
  25. service_forge/sft/config/sft_config.py +125 -0
  26. service_forge/sft/file/__init__.py +0 -0
  27. service_forge/sft/file/ignore_pattern.py +80 -0
  28. service_forge/sft/file/sft_file_manager.py +107 -0
  29. service_forge/sft/kubernetes/kubernetes_manager.py +257 -0
  30. service_forge/sft/util/assert_util.py +25 -0
  31. service_forge/sft/util/logger.py +16 -0
  32. service_forge/sft/util/name_util.py +2 -0
  33. service_forge/utils/__init__.py +0 -0
  34. service_forge/utils/default_type_converter.py +12 -0
  35. service_forge/utils/register.py +39 -0
  36. service_forge/utils/type_converter.py +74 -0
  37. service_forge/workflow/__init__.py +1 -0
  38. service_forge/workflow/context.py +13 -0
  39. service_forge/workflow/edge.py +31 -0
  40. service_forge/workflow/node.py +179 -0
  41. service_forge/workflow/nodes/__init__.py +7 -0
  42. service_forge/workflow/nodes/control/if_node.py +29 -0
  43. service_forge/workflow/nodes/input/console_input_node.py +26 -0
  44. service_forge/workflow/nodes/llm/query_llm_node.py +41 -0
  45. service_forge/workflow/nodes/nested/workflow_node.py +28 -0
  46. service_forge/workflow/nodes/output/kafka_output_node.py +27 -0
  47. service_forge/workflow/nodes/output/print_node.py +29 -0
  48. service_forge/workflow/nodes/test/if_console_input_node.py +33 -0
  49. service_forge/workflow/nodes/test/time_consuming_node.py +61 -0
  50. service_forge/workflow/port.py +86 -0
  51. service_forge/workflow/trigger.py +20 -0
  52. service_forge/workflow/triggers/__init__.py +4 -0
  53. service_forge/workflow/triggers/fast_api_trigger.py +125 -0
  54. service_forge/workflow/triggers/kafka_api_trigger.py +44 -0
  55. service_forge/workflow/triggers/once_trigger.py +20 -0
  56. service_forge/workflow/triggers/period_trigger.py +26 -0
  57. service_forge/workflow/workflow.py +251 -0
  58. service_forge/workflow/workflow_factory.py +227 -0
  59. service_forge/workflow/workflow_group.py +23 -0
  60. service_forge/workflow/workflow_type.py +52 -0
  61. service_forge-0.1.0.dist-info/METADATA +93 -0
  62. service_forge-0.1.0.dist-info/RECORD +64 -0
  63. service_forge-0.1.0.dist-info/WHEEL +4 -0
  64. service_forge-0.1.0.dist-info/entry_points.txt +2 -0
@@ -0,0 +1,23 @@
1
+ from service_forge.workflow.workflow import Workflow
2
+
3
+ class WorkflowGroup:
4
+ def __init__(self, workflows: list[Workflow], main_workflow_name: str = "main") -> None:
5
+ self.workflows = workflows
6
+ self.main_workflow_name = main_workflow_name
7
+
8
+ def add_workflow(self, workflow: Workflow) -> None:
9
+ self.workflows.append(workflow)
10
+
11
+ def get_workflow(self, name: str) -> Workflow | None:
12
+ for workflow in self.workflows:
13
+ if workflow.name == name:
14
+ return workflow
15
+ return None
16
+
17
+ async def run(self, name: str = None) -> None:
18
+ if name is None:
19
+ name = self.main_workflow_name
20
+ workflow = self.get_workflow(name)
21
+ if workflow is None:
22
+ raise ValueError(f"Workflow with name {name} not found in workflow group.")
23
+ await workflow.run()
@@ -0,0 +1,52 @@
1
+ from __future__ import annotations
2
+ import os
3
+ import importlib
4
+ import inspect
5
+ from pathlib import Path
6
+ from typing import Type, Any
7
+
8
+ from service_forge.utils.register import Register
9
+
10
+ class WorkflowType:
11
+ CLASS_NOT_REQUIRED_TO_REGISTER = ['WorkflowType']
12
+
13
+ def __init__(self, name: str, type: type) -> None:
14
+ self.name = name
15
+ self.type = type
16
+
17
+ def __init_subclass__(cls) -> None:
18
+ if cls.__name__ not in WorkflowType.CLASS_NOT_REQUIRED_TO_REGISTER:
19
+ workflow_type_register.register(cls.__name__, cls)
20
+ return super().__init_subclass__()
21
+
22
+ workflow_type_register = Register[WorkflowType]()
23
+
24
+ def _load_proto_classes():
25
+ # TODO: load from config
26
+ proto_dir = Path(__file__).parent.parent / "proto"
27
+
28
+ if not proto_dir.exists():
29
+ return
30
+
31
+ for py_file in proto_dir.glob("*.py"):
32
+ if py_file.name == "__init__.py":
33
+ continue
34
+
35
+ module_name = py_file.stem
36
+ module_path = f"service_forge.proto.{module_name}"
37
+
38
+ try:
39
+ module = importlib.import_module(module_path)
40
+
41
+ for name, obj in inspect.getmembers(module, inspect.isclass):
42
+ if (not name.startswith('_') and
43
+ obj.__module__ == module_path and
44
+ hasattr(obj, '__bases__')):
45
+
46
+ workflow_type = WorkflowType(name, obj)
47
+ workflow_type_register.register(name, workflow_type)
48
+
49
+ except Exception as e:
50
+ print(f"Failed to load module {module_path}: {e}")
51
+
52
+ _load_proto_classes()
@@ -0,0 +1,93 @@
1
+ Metadata-Version: 2.4
2
+ Name: service-forge
3
+ Version: 0.1.0
4
+ Summary: Add your description here
5
+ Author-email: euxcet <zcc.qwer@gmail.com>
6
+ Requires-Python: >=3.11
7
+ Requires-Dist: aiokafka>=0.12.0
8
+ Requires-Dist: alembic>=1.17.0
9
+ Requires-Dist: asyncpg>=0.30.0
10
+ Requires-Dist: dotenv>=0.9.9
11
+ Requires-Dist: fastapi>=0.119.1
12
+ Requires-Dist: greenlet>=3.2.4
13
+ Requires-Dist: jinja2>=3.1.6
14
+ Requires-Dist: kubernetes>=28.0.0
15
+ Requires-Dist: loguru>=0.7.3
16
+ Requires-Dist: omegaconf>=2.3.0
17
+ Requires-Dist: openai>=2.3.0
18
+ Requires-Dist: protobuf>=6.33.1
19
+ Requires-Dist: psycopg2-binary>=2.9.11
20
+ Requires-Dist: pydantic>=2.12.0
21
+ Requires-Dist: pytest-asyncio>=1.2.0
22
+ Requires-Dist: pytest>=8.4.2
23
+ Requires-Dist: python-dotenv>=1.1.1
24
+ Requires-Dist: python-jose>=3.5.0
25
+ Requires-Dist: python-multipart>=0.0.20
26
+ Requires-Dist: requests>=2.32.5
27
+ Requires-Dist: restrictedpython>=8.0
28
+ Requires-Dist: rich>=13.0.0
29
+ Requires-Dist: sqlalchemy>=2.0.44
30
+ Requires-Dist: typer>=0.12.0
31
+ Requires-Dist: uvicorn>=0.38.0
32
+ Requires-Dist: websockets>=15.0.1
33
+ Description-Content-Type: text/markdown
34
+
35
+ # Service Forge
36
+
37
+ Automated service creation and maintenance tool.
38
+
39
+ ## Install
40
+
41
+ ```bash
42
+ pip install -e .
43
+ ```
44
+
45
+ ## CLI Usage (sft)
46
+
47
+ Service Forge 提供了命令行工具 `sft` 用于服务管理。
48
+
49
+ ### 服务上传和部署
50
+
51
+ ```bash
52
+ # 上传服务(打包并上传到服务器)
53
+ sft upload [project_path]
54
+
55
+ # 列出本地已打包的服务包
56
+ sft list
57
+
58
+ # 部署服务(只在服务器上使用)
59
+ sft deploy <name> <version>
60
+ ```
61
+
62
+ ### 配置管理
63
+
64
+ ```bash
65
+ # 列出所有配置项
66
+ sft config list
67
+
68
+ # 获取指定配置项的值
69
+ sft config get <key>
70
+
71
+ # 设置配置项的值
72
+ sft config set <key> <value>
73
+ ```
74
+
75
+ ### 服务管理
76
+
77
+ ```bash
78
+ # 列出所有服务
79
+ sft service list
80
+
81
+ # 删除服务(只在服务器上使用)
82
+ sft service delete <service_name> [--force, -f]
83
+
84
+ # 查看服务日志(只在服务器上使用)
85
+ sft service logs <service_name> [--container, -c] [--tail, -n] [--follow, -f] [--previous, -p]
86
+ ```
87
+
88
+ ## TODO
89
+
90
+ - [x] 多次 trigger 并行执行
91
+ - [x] 支持 websocket 来做 trigger、输入和输出
92
+ - [x] 优化 websocket 客户端映射和重连支持
93
+ - [ ] 节点和 workflow 运行情况的回调函数
@@ -0,0 +1,64 @@
1
+ service_forge/main.py,sha256=IrYMcwwG9Y9kS7kTH9TS2e6DCiWQ2GeOoGoJAwftEtQ,3343
2
+ service_forge/service.py,sha256=xmQhtbYYsNb6yMYsZLlFkmWrNYB7rP5NWAwR_MKvHRs,4428
3
+ service_forge/service_config.py,sha256=wDZCldx6LIu5arq7kHnpVDHZbErCJlcHaiIrT3V2eRE,3620
4
+ service_forge/api/http_api.py,sha256=t2qXX7Zb5ZEI6LHiApT9XD0z5Dak1JZJJaD3CrYt_Xg,4899
5
+ service_forge/api/kafka_api.py,sha256=PInx2ZzKJRON7EaJFWroXkiOt_UeZY7WE6qK03gq4ak,4599
6
+ service_forge/api/task_manager.py,sha256=9Lk-NV4cBnuv9b8V6GVLWJJ4MCiAwCp5TVAwmYgqXbs,5269
7
+ service_forge/api/websocket_api.py,sha256=E36-fpUPxzMJ2YGlCPeqwRbryk2FMMbQD_pbb8k1FYI,3343
8
+ service_forge/api/websocket_manager.py,sha256=Xiwg3zwXRVi63sXmVH-TgbpL2XH_djyLeo96STm4cNM,16757
9
+ service_forge/db/__init__.py,sha256=vky6ZjFgPvBfLfwpwzm00rz6P86IOttKP0_UsbchBUw,47
10
+ service_forge/db/database.py,sha256=4xL-uuXXjLzvvcZ3NPQdQ1BEYMjz9PWD4S_mzWPEf-0,4489
11
+ service_forge/llm/__init__.py,sha256=9sB5uqp2F8AboYV4jAvOQfMkVMWM811sUxBahJJ-_fE,2868
12
+ service_forge/llm/llm.py,sha256=Sar99FkTPBJqkB6dwX81ww_hJp8cPYxlg7Go-zXPyg0,1865
13
+ service_forge/model/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
14
+ service_forge/model/websocket.py,sha256=YIUCW32sbHIEFPHjk5FiDM_rDe2aVD6OpzBQul2R5IM,267
15
+ service_forge/proto/foo_input.py,sha256=-POJZSIFrGdBGz7FqZZ03r5uztpc5Apin9A0Yxbk6YI,90
16
+ service_forge/sft/cli.py,sha256=stB_YPhZ7gAQeOxIq03-tLyl5VfU-gnRacAT05GSMis,2904
17
+ service_forge/sft/cmd/config_command.py,sha256=I9t2HG28S6lCXpExHyZUc47b_1yB3i51tCFVk5J6TTU,2382
18
+ service_forge/sft/cmd/deploy_service.py,sha256=riV5eSsNgcELgq1Wq53FX_lR8eLKPnQ94_Dyq7EP42w,4681
19
+ service_forge/sft/cmd/list_tars.py,sha256=Z3zvu2JLb_wNbTwi5TZXL5cZ8PxYrKks9AxkOzoUd_Q,1380
20
+ service_forge/sft/cmd/service_command.py,sha256=69GMMN61KtuoEFuYzFJ74ivNt8RX8q0I6rbePfJfEwQ,5538
21
+ service_forge/sft/cmd/upload_service.py,sha256=86PvvJSXCZKH4BU6rLytuc45grX-sRnQnOHCo9zUaPY,1232
22
+ service_forge/sft/config/injector.py,sha256=V4CcoGHinUW6ExTZKdy-gb4uOq3wXpc472k3aZtp19M,3555
23
+ service_forge/sft/config/injector_default_files.py,sha256=6CwuhqJHjfwz_V88CwHfE7jy13BFdhJaZBbN6cEI6UI,1849
24
+ service_forge/sft/config/sf_metadata.py,sha256=Y9akhSCgOd11-oqRs3LIs8FL9pvWNw6hyy57fuFcBhc,866
25
+ service_forge/sft/config/sft_config.py,sha256=zqZKNZMHNKaIbeKwUhHEYu0O4T6JA1z-4RURLX9jKa0,4539
26
+ service_forge/sft/file/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
27
+ service_forge/sft/file/ignore_pattern.py,sha256=UrVmR83wOx51XHFcZDTPp15dGYcvMTE5W1m07-SvHpw,2521
28
+ service_forge/sft/file/sft_file_manager.py,sha256=poIM77tZZg7vfwBdCsdQctBbCczVLQePdTwVINEABvE,4337
29
+ service_forge/sft/kubernetes/kubernetes_manager.py,sha256=IF2_X9U-k5Dx7EZuGrJ9lZ85ltbilrrZDfsl8qFyTu4,11339
30
+ service_forge/sft/util/assert_util.py,sha256=8HreVkOzs9_ClKiFqG4qsFn_yyDLo5uXYhYUPXlmDjM,828
31
+ service_forge/sft/util/logger.py,sha256=0Hi74IoxshE-wBgvBa2EZPXYj37tTrUYwlOBd9UMMMs,502
32
+ service_forge/sft/util/name_util.py,sha256=jQ4L6chyfESfsZI3z38gZcF79AE2Fn0-kUjG9ezobWQ,106
33
+ service_forge/utils/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
34
+ service_forge/utils/default_type_converter.py,sha256=CuUZpMATdTwgcV1M3lbK64znwmEG85Zt3y_QGXr9tYQ,625
35
+ service_forge/utils/register.py,sha256=nxiGQBCX238FoZZhsDoDdBMv_2QzeIZpM367HPNfaqM,874
36
+ service_forge/utils/type_converter.py,sha256=zqkffSt-27eWcaxJGHxLnexqtXyzehTtPmITUfYT7-c,2402
37
+ service_forge/workflow/__init__.py,sha256=9oh4qPyA33RugrUYRAlLmFtmQPUN2wxruFQE3omTJF8,49
38
+ service_forge/workflow/context.py,sha256=E3z9nJZmrTqXy-9hswyHNmQyTEuGygryOBg_yfdH5xI,307
39
+ service_forge/workflow/edge.py,sha256=XPYSUGX_Cc0Rlamu1tuTFKjvySZa5IHVCeZN0uc9aYc,951
40
+ service_forge/workflow/node.py,sha256=WOCh75rDDrsoWqOEgguAnBfjvS15sXbai07GMsTvxHg,6413
41
+ service_forge/workflow/port.py,sha256=dMNSUTaOqB7u4lfJB6kQDUIUjXSA0tzwmKxnWCk0kgA,2659
42
+ service_forge/workflow/trigger.py,sha256=s7H4uD72jiX3ATh132FqGg8YK4bcekVPfXG0ELLhu1g,562
43
+ service_forge/workflow/workflow.py,sha256=G8p9MW96LHfEZKHbx9p2Pv82WiisKahx9XiB5FKkRGA,10479
44
+ service_forge/workflow/workflow_factory.py,sha256=OsfOwsE-TxWmVNCNhdmwTEgnSLosFe8Q7j8L9QX8xBM,9580
45
+ service_forge/workflow/workflow_group.py,sha256=7KyqMRblpt40zKWBmYq4IUmcFRKRywcB1tSwRz0oirE,850
46
+ service_forge/workflow/workflow_type.py,sha256=zRc-gL2LBE-gOgTUCU5-VDWeGUzuQahkHIg98ipEvQg,1629
47
+ service_forge/workflow/nodes/__init__.py,sha256=o0Ks5F8vP5CTd4rBDLHoYjohkzFh8-fSLM69qVGGBGM,337
48
+ service_forge/workflow/nodes/control/if_node.py,sha256=c58beptuUgxWBDHjYylrc1cph9GLMI9WN1Qv9cQB5Nw,703
49
+ service_forge/workflow/nodes/input/console_input_node.py,sha256=GhQjWRgYy3aRfYUfaEql-_Xi10cca75oz-vmSZkR54w,683
50
+ service_forge/workflow/nodes/llm/query_llm_node.py,sha256=uwcWO6Q-qAG16yJqEGLJau8YxcJBGsBJoGVUBQTBWZk,1155
51
+ service_forge/workflow/nodes/nested/workflow_node.py,sha256=h5NXhRCUGaoNmqMV2PXR6JNwTCM8MCRVA6ocOjoDzhs,747
52
+ service_forge/workflow/nodes/output/kafka_output_node.py,sha256=mC6qRMGsuwU6qXAfXA-0ZFZudrlwmgRYOJRULUrtH40,682
53
+ service_forge/workflow/nodes/output/print_node.py,sha256=OSgeRQOd3dq88a1plx30g9-VB793RbXnIa5X8MF9fCo,656
54
+ service_forge/workflow/nodes/test/if_console_input_node.py,sha256=CtKHkFqr8PN974_iGP2VSBmNpXZ-KumRHCpoRR5RyF8,956
55
+ service_forge/workflow/nodes/test/time_consuming_node.py,sha256=uFThKZkWOIWKcGqQuzxftZS7IlWFBbQk0YNgViXFlSg,1759
56
+ service_forge/workflow/triggers/__init__.py,sha256=-wfqu6qK-8N8LNw3AgyXAR-nBk_RbckfM1fWRJ9YW3Q,171
57
+ service_forge/workflow/triggers/fast_api_trigger.py,sha256=Aw22r6tHHi5SZLxN4xG_YtVVDeRSdwdtH16-mKx_waI,4234
58
+ service_forge/workflow/triggers/kafka_api_trigger.py,sha256=jGnb4dkvh01Jy3CIOvgcQQ3RjsCZCGyXp2NxzCUrd6Y,1498
59
+ service_forge/workflow/triggers/once_trigger.py,sha256=X0MidqEDNATzYEQY_MwpwKEqgzBFn1lc9q8ci14Mpt8,508
60
+ service_forge/workflow/triggers/period_trigger.py,sha256=WE55k5ZpCmu666MPPQC5XSP_L_OzGlwt7v8mAnw4Qas,703
61
+ service_forge-0.1.0.dist-info/METADATA,sha256=SBORW-NCgm28-2P_kwdauOf9DP9LYXzXDsVgkrVRssU,2166
62
+ service_forge-0.1.0.dist-info/WHEEL,sha256=WLgqFyCfm_KASv4WHyYy0P3pM_m7J5L9k2skdKLirC8,87
63
+ service_forge-0.1.0.dist-info/entry_points.txt,sha256=WHntHW7GAyKQUEeMcMvHDZ7_xAb0-cZeAK4iJeu9lm8,51
64
+ service_forge-0.1.0.dist-info/RECORD,,
@@ -0,0 +1,4 @@
1
+ Wheel-Version: 1.0
2
+ Generator: hatchling 1.28.0
3
+ Root-Is-Purelib: true
4
+ Tag: py3-none-any
@@ -0,0 +1,2 @@
1
+ [console_scripts]
2
+ sft = service_forge.sft.cli:main