service-forge 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.
- service_forge-0.1.0/.gitignore +42 -0
- service_forge-0.1.0/.gitmodules +3 -0
- service_forge-0.1.0/.python-version +1 -0
- service_forge-0.1.0/PKG-INFO +93 -0
- service_forge-0.1.0/README.md +59 -0
- service_forge-0.1.0/backend/env.example +2 -0
- service_forge-0.1.0/backend/main.py +35 -0
- service_forge-0.1.0/backend/models/__init__.py +1 -0
- service_forge-0.1.0/backend/models/workflow_model.py +81 -0
- service_forge-0.1.0/backend/routers/__init__.py +1 -0
- service_forge-0.1.0/backend/routers/workflow.py +41 -0
- service_forge-0.1.0/backend/run.py +10 -0
- service_forge-0.1.0/backend/utils/__init__.py +1 -0
- service_forge-0.1.0/build-and-push-base.sh +49 -0
- service_forge-0.1.0/config_format.md +589 -0
- service_forge-0.1.0/configs/service/test_service.yaml +9 -0
- service_forge-0.1.0/configs/service/test_service_websocket.yaml +10 -0
- service_forge-0.1.0/configs/workflow/test_fastapi_node.yaml +12 -0
- service_forge-0.1.0/configs/workflow/test_if.yaml +31 -0
- service_forge-0.1.0/configs/workflow/test_if_console_input.yaml +29 -0
- service_forge-0.1.0/configs/workflow/test_kafka_api_node.yaml +15 -0
- service_forge-0.1.0/configs/workflow/test_query_llm.yaml +15 -0
- service_forge-0.1.0/configs/workflow/test_sub_workflow.yaml +45 -0
- service_forge-0.1.0/configs/workflow/test_websocket.yaml +37 -0
- service_forge-0.1.0/dockerfile.base +30 -0
- service_forge-0.1.0/dockerfile.service.example +15 -0
- service_forge-0.1.0/docs/WebSocket_API.md +528 -0
- service_forge-0.1.0/docs/javascript_client_example.js +184 -0
- service_forge-0.1.0/example/tag-service/.env.example +46 -0
- service_forge-0.1.0/example/tag-service/.sftignore +1 -0
- service_forge-0.1.0/example/tag-service/Dockerfile +17 -0
- service_forge-0.1.0/example/tag-service/README.md +0 -0
- service_forge-0.1.0/example/tag-service/alembic/README +1 -0
- service_forge-0.1.0/example/tag-service/alembic/env.py +110 -0
- service_forge-0.1.0/example/tag-service/alembic/script.py.mako +28 -0
- service_forge-0.1.0/example/tag-service/alembic/versions/483c59e9a5e1_add_type.py +28 -0
- service_forge-0.1.0/example/tag-service/alembic/versions/5fbbb21acc92_add_description_and_example.py +30 -0
- service_forge-0.1.0/example/tag-service/alembic/versions/78e0ab93b1e5_add_user_id.py +28 -0
- service_forge-0.1.0/example/tag-service/alembic/versions/8ff25e2b3fd9_create_database.py +37 -0
- service_forge-0.1.0/example/tag-service/alembic.ini +147 -0
- service_forge-0.1.0/example/tag-service/config.py +102 -0
- service_forge-0.1.0/example/tag-service/configs/service.yaml +32 -0
- service_forge-0.1.0/example/tag-service/configs/workflow/create_tag_workflow.yaml +21 -0
- service_forge-0.1.0/example/tag-service/configs/workflow/delete_tag_workflow.yaml +21 -0
- service_forge-0.1.0/example/tag-service/configs/workflow/get_tags_from_record.yaml +22 -0
- service_forge-0.1.0/example/tag-service/configs/workflow/kafka_workflow.yaml +27 -0
- service_forge-0.1.0/example/tag-service/configs/workflow/query_tags_workflow.yaml +22 -0
- service_forge-0.1.0/example/tag-service/configs/workflow/update_tag_workflow.yaml +21 -0
- service_forge-0.1.0/example/tag-service/deployment.yaml +38 -0
- service_forge-0.1.0/example/tag-service/main.py +38 -0
- service_forge-0.1.0/example/tag-service/migrate.py +119 -0
- service_forge-0.1.0/example/tag-service/model/db/tag_base.py +19 -0
- service_forge-0.1.0/example/tag-service/model/http/create_tag_model.py +6 -0
- service_forge-0.1.0/example/tag-service/model/http/delete_tag_model.py +4 -0
- service_forge-0.1.0/example/tag-service/model/http/query_tags_model.py +8 -0
- service_forge-0.1.0/example/tag-service/model/http/update_tag_model.py +7 -0
- service_forge-0.1.0/example/tag-service/nodes/__init__.py +5 -0
- service_forge-0.1.0/example/tag-service/nodes/get_tags_node.py +79 -0
- service_forge-0.1.0/example/tag-service/nodes/http_create_tag_node.py +31 -0
- service_forge-0.1.0/example/tag-service/nodes/http_delete_tag_node.py +35 -0
- service_forge-0.1.0/example/tag-service/nodes/http_query_tags_node.py +55 -0
- service_forge-0.1.0/example/tag-service/nodes/http_update_tag_node.py +39 -0
- service_forge-0.1.0/example/tag-service/prompt/default_tag.json +24 -0
- service_forge-0.1.0/example/tag-service/prompt/get_tags.md +39 -0
- service_forge-0.1.0/example/tag-service/proto/.git +1 -0
- service_forge-0.1.0/example/tag-service/proto/.github/workflows/update_template.yml +38 -0
- service_forge-0.1.0/example/tag-service/proto/.gitignore +48 -0
- service_forge-0.1.0/example/tag-service/proto/Makefile +55 -0
- service_forge-0.1.0/example/tag-service/proto/README.md +109 -0
- service_forge-0.1.0/example/tag-service/proto/__init__.py +1 -0
- service_forge-0.1.0/example/tag-service/proto/entryService/chat_message.pb.go +243 -0
- service_forge-0.1.0/example/tag-service/proto/entryService/chat_message_pb2.py +39 -0
- service_forge-0.1.0/example/tag-service/proto/entryService/chat_message_pb2.pyi +35 -0
- service_forge-0.1.0/example/tag-service/proto/entryService/record.pb.go +271 -0
- service_forge-0.1.0/example/tag-service/proto/entryService/record_pb2.py +37 -0
- service_forge-0.1.0/example/tag-service/proto/entryService/record_pb2.pyi +45 -0
- service_forge-0.1.0/example/tag-service/proto/intentService/intent.pb.go +59 -0
- service_forge-0.1.0/example/tag-service/proto/intentService/intent_pb2.py +35 -0
- service_forge-0.1.0/example/tag-service/proto/intentService/intent_pb2.pyi +4 -0
- service_forge-0.1.0/example/tag-service/proto/intentService/intent_response.pb.go +299 -0
- service_forge-0.1.0/example/tag-service/proto/intentService/intent_response_pb2.py +39 -0
- service_forge-0.1.0/example/tag-service/proto/intentService/intent_response_pb2.pyi +51 -0
- service_forge-0.1.0/example/tag-service/proto/intentService/record_group.pb.go +158 -0
- service_forge-0.1.0/example/tag-service/proto/intentService/record_group_pb2.py +37 -0
- service_forge-0.1.0/example/tag-service/proto/intentService/record_group_pb2.pyi +19 -0
- service_forge-0.1.0/example/tag-service/proto/parse_topics.py +235 -0
- service_forge-0.1.0/example/tag-service/proto/proto/entryService/chat_message.proto +21 -0
- service_forge-0.1.0/example/tag-service/proto/proto/entryService/record.proto +25 -0
- service_forge-0.1.0/example/tag-service/proto/proto/intentService/intent.proto +21 -0
- service_forge-0.1.0/example/tag-service/proto/proto/intentService/intent_response.proto +30 -0
- service_forge-0.1.0/example/tag-service/proto/proto/intentService/record_group.proto +13 -0
- service_forge-0.1.0/example/tag-service/proto/proto/scheduleService/schedule.proto +12 -0
- service_forge-0.1.0/example/tag-service/proto/proto/tagService/tag.proto +12 -0
- service_forge-0.1.0/example/tag-service/proto/pyproject.toml +10 -0
- service_forge-0.1.0/example/tag-service/proto/scheduleService/schedule.pb.go +149 -0
- service_forge-0.1.0/example/tag-service/proto/scheduleService/schedule_pb2.py +37 -0
- service_forge-0.1.0/example/tag-service/proto/scheduleService/schedule_pb2.pyi +17 -0
- service_forge-0.1.0/example/tag-service/proto/tagService/tag.pb.go +150 -0
- service_forge-0.1.0/example/tag-service/proto/tagService/tag_pb2.py +37 -0
- service_forge-0.1.0/example/tag-service/proto/tagService/tag_pb2.pyi +19 -0
- service_forge-0.1.0/example/tag-service/proto/topics.go +17 -0
- service_forge-0.1.0/example/tag-service/proto/topics.py +16 -0
- service_forge-0.1.0/example/tag-service/proto/topics.yaml +102 -0
- service_forge-0.1.0/example/tag-service/proto/uv.lock +58 -0
- service_forge-0.1.0/example/tag-service/pyproject.toml +14 -0
- service_forge-0.1.0/example/tag-service/sf-meta.yaml +26 -0
- service_forge-0.1.0/example/tag-service/start.sh +10 -0
- service_forge-0.1.0/frontend/.gitignore +24 -0
- service_forge-0.1.0/frontend/LICENSE +21 -0
- service_forge-0.1.0/frontend/README.md +62 -0
- service_forge-0.1.0/frontend/biome.json +11 -0
- service_forge-0.1.0/frontend/data_sample.npy +0 -0
- service_forge-0.1.0/frontend/index.html +13 -0
- service_forge-0.1.0/frontend/lefthook.yml +2 -0
- service_forge-0.1.0/frontend/package-lock.json +3340 -0
- service_forge-0.1.0/frontend/package.json +38 -0
- service_forge-0.1.0/frontend/pnpm-lock.yaml +2282 -0
- service_forge-0.1.0/frontend/public/vite.svg +1 -0
- service_forge-0.1.0/frontend/src/App.tsx +161 -0
- service_forge-0.1.0/frontend/src/components/WorkflowSidebar.css +82 -0
- service_forge-0.1.0/frontend/src/components/WorkflowSidebar.tsx +79 -0
- service_forge-0.1.0/frontend/src/index.css +17 -0
- service_forge-0.1.0/frontend/src/main.tsx +11 -0
- service_forge-0.1.0/frontend/src/services/api.ts +65 -0
- service_forge-0.1.0/frontend/src/vite-env.d.ts +1 -0
- service_forge-0.1.0/frontend/src/workflow/components/ControlPanel.tsx +129 -0
- service_forge-0.1.0/frontend/src/workflow/components/Edges/BaseEdge/index.tsx +124 -0
- service_forge-0.1.0/frontend/src/workflow/components/Edges/BaseEdge/useRebuildEdge.tsx +10 -0
- service_forge-0.1.0/frontend/src/workflow/components/Edges/EdgeController/index.tsx +109 -0
- service_forge-0.1.0/frontend/src/workflow/components/Edges/EdgeController/smart-edge.ts +570 -0
- service_forge-0.1.0/frontend/src/workflow/components/Edges/EdgeController/useEdgeDraggable.tsx +147 -0
- service_forge-0.1.0/frontend/src/workflow/components/Edges/Marker.tsx +55 -0
- service_forge-0.1.0/frontend/src/workflow/components/Edges/index.tsx +7 -0
- service_forge-0.1.0/frontend/src/workflow/components/Nodes/BaseNode/index.tsx +56 -0
- service_forge-0.1.0/frontend/src/workflow/components/Nodes/BaseNode/styles.css +73 -0
- service_forge-0.1.0/frontend/src/workflow/components/Nodes/index.tsx +7 -0
- service_forge-0.1.0/frontend/src/workflow/components/ReactflowInstance.tsx +16 -0
- service_forge-0.1.0/frontend/src/workflow/components/WorkflowRunner.tsx +97 -0
- service_forge-0.1.0/frontend/src/workflow/data/convert.ts +97 -0
- service_forge-0.1.0/frontend/src/workflow/data/data.json +83 -0
- service_forge-0.1.0/frontend/src/workflow/data/types.ts +100 -0
- service_forge-0.1.0/frontend/src/workflow/layout/edge/algorithms/a-star.ts +219 -0
- service_forge-0.1.0/frontend/src/workflow/layout/edge/algorithms/index.ts +127 -0
- service_forge-0.1.0/frontend/src/workflow/layout/edge/algorithms/simple.ts +113 -0
- service_forge-0.1.0/frontend/src/workflow/layout/edge/edge.ts +267 -0
- service_forge-0.1.0/frontend/src/workflow/layout/edge/index.ts +73 -0
- service_forge-0.1.0/frontend/src/workflow/layout/edge/point.ts +396 -0
- service_forge-0.1.0/frontend/src/workflow/layout/edge/style.ts +200 -0
- service_forge-0.1.0/frontend/src/workflow/layout/metadata.ts +101 -0
- service_forge-0.1.0/frontend/src/workflow/layout/node/algorithms/d3-dag.ts +125 -0
- service_forge-0.1.0/frontend/src/workflow/layout/node/algorithms/d3-hierarchy.ts +93 -0
- service_forge-0.1.0/frontend/src/workflow/layout/node/algorithms/dagre-tree.ts +65 -0
- service_forge-0.1.0/frontend/src/workflow/layout/node/algorithms/elk.ts +134 -0
- service_forge-0.1.0/frontend/src/workflow/layout/node/algorithms/origin.ts +20 -0
- service_forge-0.1.0/frontend/src/workflow/layout/node/index.ts +85 -0
- service_forge-0.1.0/frontend/src/workflow/layout/useAutoLayout.ts +60 -0
- service_forge-0.1.0/frontend/src/workflow/states/reactflow.ts +24 -0
- service_forge-0.1.0/frontend/tsconfig.app.json +32 -0
- service_forge-0.1.0/frontend/tsconfig.json +7 -0
- service_forge-0.1.0/frontend/tsconfig.node.json +26 -0
- service_forge-0.1.0/frontend/vite.config.ts +11 -0
- service_forge-0.1.0/main.py +24 -0
- service_forge-0.1.0/prompt/test_query_llm_prompt.txt +1 -0
- service_forge-0.1.0/prompt/test_query_llm_system_prompt.txt +1 -0
- service_forge-0.1.0/pyproject.toml +58 -0
- service_forge-0.1.0/scripts/kafka_consumer.py +132 -0
- service_forge-0.1.0/scripts/tag_kafka_producer.py +51 -0
- service_forge-0.1.0/scripts/tag_kafka_producer_json.py +42 -0
- service_forge-0.1.0/scripts/test_kafka.py +16 -0
- service_forge-0.1.0/src/service_forge/api/http_api.py +138 -0
- service_forge-0.1.0/src/service_forge/api/kafka_api.py +126 -0
- service_forge-0.1.0/src/service_forge/api/task_manager.py +141 -0
- service_forge-0.1.0/src/service_forge/api/websocket_api.py +86 -0
- service_forge-0.1.0/src/service_forge/api/websocket_manager.py +425 -0
- service_forge-0.1.0/src/service_forge/db/__init__.py +1 -0
- service_forge-0.1.0/src/service_forge/db/database.py +119 -0
- service_forge-0.1.0/src/service_forge/llm/__init__.py +62 -0
- service_forge-0.1.0/src/service_forge/llm/llm.py +56 -0
- service_forge-0.1.0/src/service_forge/main.py +121 -0
- service_forge-0.1.0/src/service_forge/model/__init__.py +0 -0
- service_forge-0.1.0/src/service_forge/model/websocket.py +13 -0
- service_forge-0.1.0/src/service_forge/proto/foo_input.py +5 -0
- service_forge-0.1.0/src/service_forge/service.py +111 -0
- service_forge-0.1.0/src/service_forge/service_config.py +115 -0
- service_forge-0.1.0/src/service_forge/sft/cli.py +91 -0
- service_forge-0.1.0/src/service_forge/sft/cmd/config_command.py +67 -0
- service_forge-0.1.0/src/service_forge/sft/cmd/deploy_service.py +124 -0
- service_forge-0.1.0/src/service_forge/sft/cmd/list_tars.py +41 -0
- service_forge-0.1.0/src/service_forge/sft/cmd/service_command.py +149 -0
- service_forge-0.1.0/src/service_forge/sft/cmd/upload_service.py +36 -0
- service_forge-0.1.0/src/service_forge/sft/config/injector.py +87 -0
- service_forge-0.1.0/src/service_forge/sft/config/injector_default_files.py +97 -0
- service_forge-0.1.0/src/service_forge/sft/config/sf_metadata.py +30 -0
- service_forge-0.1.0/src/service_forge/sft/config/sft_config.py +125 -0
- service_forge-0.1.0/src/service_forge/sft/file/__init__.py +0 -0
- service_forge-0.1.0/src/service_forge/sft/file/ignore_pattern.py +80 -0
- service_forge-0.1.0/src/service_forge/sft/file/sft_file_manager.py +107 -0
- service_forge-0.1.0/src/service_forge/sft/kubernetes/kubernetes_manager.py +257 -0
- service_forge-0.1.0/src/service_forge/sft/util/assert_util.py +25 -0
- service_forge-0.1.0/src/service_forge/sft/util/logger.py +16 -0
- service_forge-0.1.0/src/service_forge/sft/util/name_util.py +2 -0
- service_forge-0.1.0/src/service_forge/utils/__init__.py +0 -0
- service_forge-0.1.0/src/service_forge/utils/default_type_converter.py +12 -0
- service_forge-0.1.0/src/service_forge/utils/register.py +39 -0
- service_forge-0.1.0/src/service_forge/utils/type_converter.py +74 -0
- service_forge-0.1.0/src/service_forge/workflow/__init__.py +1 -0
- service_forge-0.1.0/src/service_forge/workflow/context.py +13 -0
- service_forge-0.1.0/src/service_forge/workflow/edge.py +31 -0
- service_forge-0.1.0/src/service_forge/workflow/node.py +179 -0
- service_forge-0.1.0/src/service_forge/workflow/nodes/__init__.py +7 -0
- service_forge-0.1.0/src/service_forge/workflow/nodes/control/if_node.py +29 -0
- service_forge-0.1.0/src/service_forge/workflow/nodes/input/console_input_node.py +26 -0
- service_forge-0.1.0/src/service_forge/workflow/nodes/llm/query_llm_node.py +41 -0
- service_forge-0.1.0/src/service_forge/workflow/nodes/nested/workflow_node.py +28 -0
- service_forge-0.1.0/src/service_forge/workflow/nodes/output/kafka_output_node.py +27 -0
- service_forge-0.1.0/src/service_forge/workflow/nodes/output/print_node.py +29 -0
- service_forge-0.1.0/src/service_forge/workflow/nodes/test/if_console_input_node.py +33 -0
- service_forge-0.1.0/src/service_forge/workflow/nodes/test/time_consuming_node.py +61 -0
- service_forge-0.1.0/src/service_forge/workflow/port.py +86 -0
- service_forge-0.1.0/src/service_forge/workflow/trigger.py +20 -0
- service_forge-0.1.0/src/service_forge/workflow/triggers/__init__.py +4 -0
- service_forge-0.1.0/src/service_forge/workflow/triggers/fast_api_trigger.py +125 -0
- service_forge-0.1.0/src/service_forge/workflow/triggers/kafka_api_trigger.py +44 -0
- service_forge-0.1.0/src/service_forge/workflow/triggers/once_trigger.py +20 -0
- service_forge-0.1.0/src/service_forge/workflow/triggers/period_trigger.py +26 -0
- service_forge-0.1.0/src/service_forge/workflow/workflow.py +251 -0
- service_forge-0.1.0/src/service_forge/workflow/workflow_factory.py +227 -0
- service_forge-0.1.0/src/service_forge/workflow/workflow_group.py +23 -0
- service_forge-0.1.0/src/service_forge/workflow/workflow_type.py +52 -0
- service_forge-0.1.0/tests/__init__.py +2 -0
- service_forge-0.1.0/tests/test_workflow.py +71 -0
- service_forge-0.1.0/tests/test_workflow_config.py +9 -0
- service_forge-0.1.0/tests/websocket_client_test 9000.py +256 -0
- service_forge-0.1.0/tests/websocket_client_test.py +256 -0
- service_forge-0.1.0/uv.lock +1375 -0
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
# Python-generated files
|
|
2
|
+
__pycache__/
|
|
3
|
+
*.py[oc]
|
|
4
|
+
build/
|
|
5
|
+
dist/
|
|
6
|
+
wheels/
|
|
7
|
+
*.egg-info
|
|
8
|
+
|
|
9
|
+
# Virtual environments
|
|
10
|
+
.venv
|
|
11
|
+
|
|
12
|
+
# General
|
|
13
|
+
.DS_Store
|
|
14
|
+
__MACOSX/
|
|
15
|
+
.AppleDouble
|
|
16
|
+
.LSOverride
|
|
17
|
+
Icon[]
|
|
18
|
+
|
|
19
|
+
# Thumbnails
|
|
20
|
+
._*
|
|
21
|
+
|
|
22
|
+
# Files that might appear in the root of a volume
|
|
23
|
+
.DocumentRevisions-V100
|
|
24
|
+
.fseventsd
|
|
25
|
+
.Spotlight-V100
|
|
26
|
+
.TemporaryItems
|
|
27
|
+
.Trashes
|
|
28
|
+
.VolumeIcon.icns
|
|
29
|
+
.com.apple.timemachine.donotpresent
|
|
30
|
+
|
|
31
|
+
# Directories potentially created on remote AFP share
|
|
32
|
+
.AppleDB
|
|
33
|
+
.AppleDesktop
|
|
34
|
+
Network Trash Folder
|
|
35
|
+
Temporary Items
|
|
36
|
+
.apdisk
|
|
37
|
+
|
|
38
|
+
.env
|
|
39
|
+
.vscode/settings.json
|
|
40
|
+
.vscode/launch.json
|
|
41
|
+
example/tag-service/.vscode/settings.json
|
|
42
|
+
client_id.txt
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
3.11
|
|
@@ -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,59 @@
|
|
|
1
|
+
# Service Forge
|
|
2
|
+
|
|
3
|
+
Automated service creation and maintenance tool.
|
|
4
|
+
|
|
5
|
+
## Install
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
pip install -e .
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
## CLI Usage (sft)
|
|
12
|
+
|
|
13
|
+
Service Forge 提供了命令行工具 `sft` 用于服务管理。
|
|
14
|
+
|
|
15
|
+
### 服务上传和部署
|
|
16
|
+
|
|
17
|
+
```bash
|
|
18
|
+
# 上传服务(打包并上传到服务器)
|
|
19
|
+
sft upload [project_path]
|
|
20
|
+
|
|
21
|
+
# 列出本地已打包的服务包
|
|
22
|
+
sft list
|
|
23
|
+
|
|
24
|
+
# 部署服务(只在服务器上使用)
|
|
25
|
+
sft deploy <name> <version>
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
### 配置管理
|
|
29
|
+
|
|
30
|
+
```bash
|
|
31
|
+
# 列出所有配置项
|
|
32
|
+
sft config list
|
|
33
|
+
|
|
34
|
+
# 获取指定配置项的值
|
|
35
|
+
sft config get <key>
|
|
36
|
+
|
|
37
|
+
# 设置配置项的值
|
|
38
|
+
sft config set <key> <value>
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
### 服务管理
|
|
42
|
+
|
|
43
|
+
```bash
|
|
44
|
+
# 列出所有服务
|
|
45
|
+
sft service list
|
|
46
|
+
|
|
47
|
+
# 删除服务(只在服务器上使用)
|
|
48
|
+
sft service delete <service_name> [--force, -f]
|
|
49
|
+
|
|
50
|
+
# 查看服务日志(只在服务器上使用)
|
|
51
|
+
sft service logs <service_name> [--container, -c] [--tail, -n] [--follow, -f] [--previous, -p]
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
## TODO
|
|
55
|
+
|
|
56
|
+
- [x] 多次 trigger 并行执行
|
|
57
|
+
- [x] 支持 websocket 来做 trigger、输入和输出
|
|
58
|
+
- [x] 优化 websocket 客户端映射和重连支持
|
|
59
|
+
- [ ] 节点和 workflow 运行情况的回调函数
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import uvicorn
|
|
2
|
+
from fastapi import FastAPI
|
|
3
|
+
from fastapi.middleware.cors import CORSMiddleware
|
|
4
|
+
from routers import workflow
|
|
5
|
+
|
|
6
|
+
app = FastAPI(
|
|
7
|
+
title="Service Forge API",
|
|
8
|
+
description="A modern service management API",
|
|
9
|
+
version="1.0.0"
|
|
10
|
+
)
|
|
11
|
+
|
|
12
|
+
# Configure CORS
|
|
13
|
+
app.add_middleware(
|
|
14
|
+
CORSMiddleware,
|
|
15
|
+
allow_origins=["http://localhost:5173"], # React dev server
|
|
16
|
+
allow_credentials=True,
|
|
17
|
+
allow_methods=["*"],
|
|
18
|
+
allow_headers=["*"],
|
|
19
|
+
)
|
|
20
|
+
|
|
21
|
+
# Include routers
|
|
22
|
+
app.include_router(workflow.router, prefix="/api/v1/workflow", tags=["workflow"])
|
|
23
|
+
|
|
24
|
+
@app.get("/")
|
|
25
|
+
async def root():
|
|
26
|
+
return {"message": "Welcome to Service Forge API"}
|
|
27
|
+
|
|
28
|
+
if __name__ == "__main__":
|
|
29
|
+
uvicorn.run(
|
|
30
|
+
"main:app",
|
|
31
|
+
host="0.0.0.0",
|
|
32
|
+
port=8001,
|
|
33
|
+
reload=True,
|
|
34
|
+
log_level="info"
|
|
35
|
+
)
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
# Models package
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
import os
|
|
2
|
+
import uuid
|
|
3
|
+
from pydantic import BaseModel
|
|
4
|
+
import omegaconf
|
|
5
|
+
|
|
6
|
+
config_folders = [
|
|
7
|
+
os.path.join("configs", "workflow"),
|
|
8
|
+
os.path.join("example", "tag-service", "configs", "workflow"),
|
|
9
|
+
]
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
class NodeModel(BaseModel):
|
|
13
|
+
id: str
|
|
14
|
+
type: str
|
|
15
|
+
|
|
16
|
+
class EdgeModel(BaseModel):
|
|
17
|
+
id: str
|
|
18
|
+
source: str
|
|
19
|
+
target: str
|
|
20
|
+
sourceHandle: str
|
|
21
|
+
targetHandle: str
|
|
22
|
+
|
|
23
|
+
class WorkflowModel(BaseModel):
|
|
24
|
+
id: str
|
|
25
|
+
name: str
|
|
26
|
+
path: str
|
|
27
|
+
nodes: list[NodeModel]
|
|
28
|
+
edges: list[EdgeModel]
|
|
29
|
+
|
|
30
|
+
def get_workflow_path(workflow_id: str) -> str:
|
|
31
|
+
for workflow in workflows:
|
|
32
|
+
if workflow.id == workflow_id:
|
|
33
|
+
return workflow.path
|
|
34
|
+
return None
|
|
35
|
+
|
|
36
|
+
def load_workflow(workflow_path: str) -> WorkflowModel:
|
|
37
|
+
config = omegaconf.OmegaConf.load(workflow_path)
|
|
38
|
+
if 'workflows' in config:
|
|
39
|
+
return None # sub workflow is not supported yet
|
|
40
|
+
nodes = []
|
|
41
|
+
edges = []
|
|
42
|
+
print(workflow_path)
|
|
43
|
+
if 'nodes' in config:
|
|
44
|
+
for node in config['nodes']:
|
|
45
|
+
nodes.append(NodeModel(id=node['name'], type='base'))
|
|
46
|
+
for node in config['nodes']:
|
|
47
|
+
if outputs := node.get('outputs', None):
|
|
48
|
+
for port, value in outputs.items():
|
|
49
|
+
if value is None:
|
|
50
|
+
continue
|
|
51
|
+
source_node_name, source_port_name = node['name'], port
|
|
52
|
+
if type(value) == str:
|
|
53
|
+
value = [value]
|
|
54
|
+
for edge_value in list(value):
|
|
55
|
+
target_node_name, target_port_name = edge_value.split('|')
|
|
56
|
+
edges.append(EdgeModel(
|
|
57
|
+
id=str(uuid.uuid4()),
|
|
58
|
+
source=node['name'],
|
|
59
|
+
target=target_node_name,
|
|
60
|
+
sourceHandle=f"{source_node_name}#source#{source_port_name}",
|
|
61
|
+
targetHandle=f"{target_node_name}#target#{target_port_name}"
|
|
62
|
+
))
|
|
63
|
+
return WorkflowModel(
|
|
64
|
+
id=str(uuid.uuid4()),
|
|
65
|
+
name=config.get('name', 'Unknown Workflow'),
|
|
66
|
+
path=workflow_path,
|
|
67
|
+
nodes=nodes,
|
|
68
|
+
edges=edges
|
|
69
|
+
)
|
|
70
|
+
|
|
71
|
+
def load_workflows() -> list[WorkflowModel]:
|
|
72
|
+
workflows = []
|
|
73
|
+
|
|
74
|
+
for config_folder in config_folders:
|
|
75
|
+
for config_path in os.listdir(config_folder):
|
|
76
|
+
if config_path.endswith(".yaml"):
|
|
77
|
+
if workflow := load_workflow(os.path.join(config_folder, config_path)):
|
|
78
|
+
workflows.append(workflow)
|
|
79
|
+
return workflows
|
|
80
|
+
|
|
81
|
+
workflows = load_workflows()
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
# Routers package
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
from fastapi import APIRouter, HTTPException
|
|
2
|
+
from typing import List, Dict, Any
|
|
3
|
+
from pydantic import BaseModel
|
|
4
|
+
from models.workflow_model import workflows, WorkflowModel, load_workflow, get_workflow_path
|
|
5
|
+
from service_forge.workflow.workflow_factory import create_workflow
|
|
6
|
+
|
|
7
|
+
router = APIRouter()
|
|
8
|
+
|
|
9
|
+
@router.get("/", response_model=List[WorkflowModel])
|
|
10
|
+
async def get_workflows():
|
|
11
|
+
return workflows
|
|
12
|
+
|
|
13
|
+
@router.get("/{workflow_id}", response_model=WorkflowModel)
|
|
14
|
+
async def get_workflow(workflow_id: str):
|
|
15
|
+
return load_workflow(get_workflow_path(workflow_id))
|
|
16
|
+
|
|
17
|
+
@router.post("/{workflow_id}")
|
|
18
|
+
async def run_workflow(workflow_id: str):
|
|
19
|
+
result = ""
|
|
20
|
+
|
|
21
|
+
async def _handle_stream_output(node_name: str, stream):
|
|
22
|
+
nonlocal result
|
|
23
|
+
result += f"[{node_name}] Starting stream output:\n"
|
|
24
|
+
buffer = []
|
|
25
|
+
async for char in stream:
|
|
26
|
+
buffer.append(char)
|
|
27
|
+
result += f"[{node_name}] Received char: '{char}'\n"
|
|
28
|
+
|
|
29
|
+
complete_message = ''.join(buffer)
|
|
30
|
+
result += f"[{node_name}] Complete message: '{complete_message}'\n"
|
|
31
|
+
|
|
32
|
+
workflow = create_workflow(
|
|
33
|
+
config_path=get_workflow_path(workflow_id),
|
|
34
|
+
_handle_stream_output=_handle_stream_output,
|
|
35
|
+
)
|
|
36
|
+
if workflow is None:
|
|
37
|
+
raise HTTPException(status_code=404, detail="Workflow not found")
|
|
38
|
+
|
|
39
|
+
await workflow.run()
|
|
40
|
+
|
|
41
|
+
return {"message": result}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
# Utils package
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
# 一键 Docker 构建和上传 service-forge 基础镜像脚本
|
|
3
|
+
# 配置参数
|
|
4
|
+
IMAGE_NAME="service-forge"
|
|
5
|
+
REGISTRY_ADDRESS="crpi-cev6qq28wwgwwj0y.cn-beijing.personal.cr.aliyuncs.com"
|
|
6
|
+
REPOSITORY_NAMESPACE="nexthci"
|
|
7
|
+
REPOSITORY_NAME="service-forge"
|
|
8
|
+
VERSION="latest"
|
|
9
|
+
DOCKERFILE="dockerfile.base"
|
|
10
|
+
|
|
11
|
+
echo "=== 开始构建 service-forge 基础镜像 ==="
|
|
12
|
+
|
|
13
|
+
if [ ! -f "$DOCKERFILE" ]; then
|
|
14
|
+
echo "错误: 找不到基础镜像 Dockerfile $DOCKERFILE!"
|
|
15
|
+
exit 1
|
|
16
|
+
fi
|
|
17
|
+
|
|
18
|
+
# 1. 构建 Docker 镜像
|
|
19
|
+
echo "步骤 1/3: 构建 Docker 基础镜像..."
|
|
20
|
+
docker build -f $DOCKERFILE -t $IMAGE_NAME:latest .
|
|
21
|
+
if [ $? -ne 0 ]; then
|
|
22
|
+
echo "错误: Docker 基础镜像构建失败!"
|
|
23
|
+
exit 1
|
|
24
|
+
fi
|
|
25
|
+
echo "✓ 基础镜像构建成功"
|
|
26
|
+
|
|
27
|
+
# 2. 获取镜像ID并标记
|
|
28
|
+
echo "步骤 2/3: 标记基础镜像..."
|
|
29
|
+
IMAGE_ID=$(docker images -q $IMAGE_NAME:latest)
|
|
30
|
+
if [ -z "$IMAGE_ID" ]; then
|
|
31
|
+
echo "错误: 找不到 $IMAGE_NAME:latest 镜像!"
|
|
32
|
+
exit 1
|
|
33
|
+
fi
|
|
34
|
+
TARGET_IMAGE="$REGISTRY_ADDRESS/$REPOSITORY_NAMESPACE/$REPOSITORY_NAME:$VERSION"
|
|
35
|
+
docker tag $IMAGE_ID $TARGET_IMAGE
|
|
36
|
+
echo "✓ 基础镜像标记完成: $TARGET_IMAGE"
|
|
37
|
+
|
|
38
|
+
# 3. 推送镜像
|
|
39
|
+
echo "步骤 3/3: 推送基础镜像到仓库..."
|
|
40
|
+
docker push $TARGET_IMAGE
|
|
41
|
+
if [ $? -ne 0 ]; then
|
|
42
|
+
echo "错误: 基础镜像推送失败!"
|
|
43
|
+
exit 1
|
|
44
|
+
fi
|
|
45
|
+
echo "✓ 基础镜像推送成功"
|
|
46
|
+
|
|
47
|
+
|
|
48
|
+
echo "=== 基础镜像构建完成 ==="
|
|
49
|
+
echo "基础镜像地址: $TARGET_IMAGE"
|