feat: support workflow parameter as JSON object, local filename, or URL in /oneapi/v1/execute API, with local file path resolution
This commit is contained in:
@@ -34,3 +34,5 @@ Thumbs.db
|
||||
|
||||
# Cursor
|
||||
.cursorrules
|
||||
|
||||
*.log
|
||||
|
||||
@@ -12,7 +12,7 @@ ComfyUI-OneAPI is a plugin that provides simple REST API interfaces for ComfyUI,
|
||||
curl -X POST "http://localhost:8188/oneapi/v1/execute" \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{
|
||||
"workflow": {...} # Replace with your workflow JSON
|
||||
"workflow": {...} # Supports JSON object, local filename, or URL
|
||||
}'
|
||||
```
|
||||
|
||||
@@ -20,7 +20,7 @@ curl -X POST "http://localhost:8188/oneapi/v1/execute" \
|
||||
|
||||
```json
|
||||
{
|
||||
"workflow": {...} // API version of workflow JSON
|
||||
"workflow": {...} # Supports JSON object, local filename, or URL
|
||||
}
|
||||
```
|
||||
|
||||
@@ -87,7 +87,7 @@ POST /oneapi/v1/execute
|
||||
|
||||
Request Body:
|
||||
{
|
||||
"workflow": {...}, // API version of workflow JSON
|
||||
"workflow": {...}, // Supports JSON object, local filename, or URL
|
||||
"params": {...}, // Optional: Parameter mapping
|
||||
"wait_for_result": true/false, // Optional: Wait for results (default true)
|
||||
"timeout": 300 // Optional: Timeout in seconds
|
||||
@@ -119,7 +119,7 @@ Add markers to SaveImage node titles:
|
||||
curl -X POST "http://localhost:8188/oneapi/v1/execute" \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{
|
||||
"workflow": '"$(cat workflows/example_workflow.json)"',
|
||||
"workflow": "$(cat workflows/example_workflow.json)", # Supports JSON object, local filename, or URL
|
||||
"params": {
|
||||
"prompt": "a cute dog with a red hat"
|
||||
}
|
||||
@@ -132,7 +132,7 @@ curl -X POST "http://localhost:8188/oneapi/v1/execute" \
|
||||
curl -X POST "http://localhost:8188/oneapi/v1/execute" \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{
|
||||
"workflow": '"$(cat workflows/example_img2img_workflow.json)"',
|
||||
"workflow": "$(cat workflows/example_img2img_workflow.json)", # Supports JSON object, local filename, or URL
|
||||
"params": {
|
||||
"prompt": "a cute dog with a red hat",
|
||||
"image": "https://example.com/input.jpg"
|
||||
@@ -144,4 +144,30 @@ curl -X POST "http://localhost:8188/oneapi/v1/execute" \
|
||||
|
||||
- 🔄 This plugin uses HTTP polling to get results, does not provide WebSocket real-time progress
|
||||
- ⏱️ Long-running workflows may cause request timeouts, consider setting appropriate timeout values
|
||||
- 🏷️ Parameter mapping and output marking depend on special markers in node titles
|
||||
- 🏷️ Parameter mapping and output marking depend on special markers in node titles
|
||||
|
||||
## /oneapi/v1/execute API - workflow parameter supports three forms
|
||||
|
||||
### Supported forms for the workflow parameter
|
||||
|
||||
- 1. Pass workflow as a JSON object (original logic).
|
||||
- 2. Pass a local workflow filename (e.g. `1.json`), which will be loaded from `user/default/workflows/1.json`.
|
||||
- 3. Pass a workflow URL (e.g. `http://xxx/1.json`), which will be downloaded and parsed automatically.
|
||||
|
||||
How to distinguish:
|
||||
- If workflow is a dict, use it directly.
|
||||
- If workflow is a string starting with `http://` or `https://`, treat as URL and download.
|
||||
- Otherwise, treat as a local filename and load from `user/default/workflows` directory.
|
||||
|
||||
**Examples:**
|
||||
```json
|
||||
// 1. Pass JSON directly
|
||||
{"workflow": {"node1": {...}, ...}}
|
||||
|
||||
// 2. Pass local filename
|
||||
// 1.json corresponds to <ComfyUI root>/user/default/workflows/1.json
|
||||
{"workflow": "1.json"}
|
||||
|
||||
// 3. Pass URL
|
||||
{"workflow": "https://example.com/1.json"}
|
||||
```
|
||||
+31
-5
@@ -12,7 +12,7 @@ ComfyUI-OneAPI 是一个为 ComfyUI 提供简单REST API接口的插件,只需
|
||||
curl -X POST "http://localhost:8188/oneapi/v1/execute" \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{
|
||||
"workflow": {...} # 替换为您的工作流JSON
|
||||
"workflow": {...} # 支持JSON对象、本地文件名或URL
|
||||
}'
|
||||
```
|
||||
|
||||
@@ -87,7 +87,7 @@ POST /oneapi/v1/execute
|
||||
|
||||
请求体:
|
||||
{
|
||||
"workflow": {...}, // 工作流的API版JSON
|
||||
"workflow": {...}, // 支持JSON对象、本地文件名或URL
|
||||
"params": {...}, // 可选:参数映射
|
||||
"wait_for_result": true/false, // 可选:是否等待结果(默认true)
|
||||
"timeout": 300 // 可选:超时时间(秒)
|
||||
@@ -119,7 +119,7 @@ POST /oneapi/v1/execute
|
||||
curl -X POST "http://localhost:8188/oneapi/v1/execute" \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{
|
||||
"workflow": '"$(cat workflows/example_workflow.json)"',
|
||||
"workflow": "$(cat workflows/example_workflow.json)", # 支持JSON对象、本地文件名或URL
|
||||
"params": {
|
||||
"prompt": "a cute dog with a red hat"
|
||||
}
|
||||
@@ -132,7 +132,7 @@ curl -X POST "http://localhost:8188/oneapi/v1/execute" \
|
||||
curl -X POST "http://localhost:8188/oneapi/v1/execute" \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{
|
||||
"workflow": '"$(cat workflows/example_img2img_workflow.json)"',
|
||||
"workflow": "$(cat workflows/example_img2img_workflow.json)", # 支持JSON对象、本地文件名或URL
|
||||
"params": {
|
||||
"prompt": "a cute dog with a red hat",
|
||||
"image": "https://example.com/input.jpg"
|
||||
@@ -144,4 +144,30 @@ curl -X POST "http://localhost:8188/oneapi/v1/execute" \
|
||||
|
||||
- 🔄 此插件使用HTTP轮询获取结果,不提供WebSocket实时进度
|
||||
- ⏱️ 长时间运行的工作流可能导致超时,请设置合适的timeout值
|
||||
- 🏷️ 参数映射和输出标记依赖于节点标题中的特殊标记
|
||||
- 🏷️ 参数映射和输出标记依赖于节点标题中的特殊标记
|
||||
|
||||
## /oneapi/v1/execute 接口说明
|
||||
|
||||
### workflow 参数支持三种形式
|
||||
|
||||
- 1. 直接传递 workflow 的 JSON 对象(原有逻辑)。
|
||||
- 2. 传递本地 workflow 文件名(如 `1.json`),会自动从 `user/default/workflows/1.json` 读取。
|
||||
- 3. 传递 workflow 的 URL(如 `http://xxx/1.json`),会自动下载并解析。
|
||||
|
||||
区分方式:
|
||||
- 如果 workflow 是 dict,则直接用。
|
||||
- 如果 workflow 是字符串且以 `http://` 或 `https://` 开头,则当作 URL 下载。
|
||||
- 否则当作本地文件名,从 `user/default/workflows` 目录加载。
|
||||
|
||||
**示例:**
|
||||
```json
|
||||
// 1. 直接传 JSON
|
||||
{"workflow": {"node1": {...}, ...}}
|
||||
|
||||
// 2. 传本地文件名
|
||||
// 1.json 对应的是 <ComfyUI根目录>/user/default/workflows/1.json
|
||||
{"workflow": "1.json"}
|
||||
|
||||
// 3. 传 URL
|
||||
{"workflow": "https://example.com/1.json"}
|
||||
```
|
||||
@@ -15,13 +15,18 @@ import execution
|
||||
# Get routes
|
||||
routes = PromptServer.instance.routes
|
||||
|
||||
# Get workflow paths
|
||||
path_custom_nodes = os.path.dirname(os.path.dirname(__file__))
|
||||
path_comfyui_root = os.path.dirname(path_custom_nodes)
|
||||
path_workflows = os.path.join(path_comfyui_root, 'user/default/workflows')
|
||||
|
||||
@routes.post('/oneapi/v1/execute')
|
||||
async def execute_workflow(request):
|
||||
"""
|
||||
Execute workflow API
|
||||
|
||||
Parameters:
|
||||
- workflow: Workflow JSON
|
||||
- workflow: Workflow JSON, filename (under user/default/workflows/), or URL
|
||||
- params: Parameter mapping dictionary
|
||||
- wait_for_result: Whether to wait for results (default True)
|
||||
- timeout: Timeout in seconds (default 300)
|
||||
@@ -50,6 +55,19 @@ async def execute_workflow(request):
|
||||
params = data.get('params', {})
|
||||
wait_for_result = data.get('wait_for_result', True)
|
||||
timeout = data.get('timeout', None)
|
||||
|
||||
# Support workflow as local path or URL
|
||||
if isinstance(workflow, dict):
|
||||
pass # Use directly
|
||||
elif isinstance(workflow, str):
|
||||
if workflow.startswith('http://') or workflow.startswith('https://'):
|
||||
# URL, download
|
||||
workflow = await _load_workflow_from_url(workflow)
|
||||
else:
|
||||
# Local filename
|
||||
workflow = _load_workflow_from_local(workflow)
|
||||
else:
|
||||
return web.json_response({"error": "Invalid workflow parameter"}, status=400)
|
||||
|
||||
if not workflow:
|
||||
return web.json_response({"error": "Workflow data is missing"}, status=400)
|
||||
@@ -476,4 +494,32 @@ async def _wait_for_results(prompt_id, timeout=None, request=None, output_id_2_v
|
||||
# Wait before checking again
|
||||
await asyncio.sleep(1.0)
|
||||
|
||||
# New: Load workflow from local file
|
||||
|
||||
def _load_workflow_from_local(filename):
|
||||
"""
|
||||
Load workflow JSON from user/default/workflows directory
|
||||
"""
|
||||
file_path = os.path.join(path_workflows, filename)
|
||||
if not os.path.isfile(file_path):
|
||||
raise Exception(f"Workflow file not found: {file_path}")
|
||||
with open(file_path, 'r', encoding='utf-8') as f:
|
||||
return json.load(f)
|
||||
|
||||
# New: Load workflow from URL
|
||||
|
||||
async def _load_workflow_from_url(url):
|
||||
"""
|
||||
Download workflow JSON from URL
|
||||
"""
|
||||
async with aiohttp.ClientSession() as session:
|
||||
async with session.get(url) as response:
|
||||
if response.status != 200:
|
||||
raise Exception(f"Failed to download workflow: HTTP {response.status}")
|
||||
text = await response.text()
|
||||
try:
|
||||
return json.loads(text)
|
||||
except Exception as e:
|
||||
raise Exception(f"Invalid workflow JSON from url: {e}")
|
||||
|
||||
print("ComfyUI-OneAPI routes registered")
|
||||
Reference in New Issue
Block a user