mirror of
https://github.com/HuangYuChuh/ComfyUI_Skills_OpenClaw.git
synced 2026-07-29 09:32:07 +00:00
Add comfy_api_key server config field to enable cloud API nodes (Kling, Sora, Nano Banana, etc.) when calling ComfyUI via API. The key is passed through extra_data.api_key_comfy_org in the /prompt request, following ComfyUI's official API key integration. Closes #78 Co-authored-by: Kelin <kelin@KelindeMacBook-Air.local>
231 lines
6.6 KiB
Python
231 lines
6.6 KiB
Python
from __future__ import annotations
|
|
|
|
from typing import Any
|
|
|
|
from pydantic import BaseModel, Field, field_validator
|
|
|
|
|
|
class ServerModel(BaseModel):
|
|
id: str = Field(min_length=1)
|
|
name: str = Field(min_length=1)
|
|
url: str = Field(min_length=1)
|
|
auth: str = ""
|
|
comfy_api_key: str = ""
|
|
enabled: bool = True
|
|
output_dir: str = "./outputs"
|
|
|
|
@field_validator("id", mode="before")
|
|
@classmethod
|
|
def normalize_id(cls, value: Any) -> str:
|
|
if value is None:
|
|
return ""
|
|
return str(value)
|
|
|
|
@field_validator("name", "url", "output_dir", mode="before")
|
|
@classmethod
|
|
def normalize_string_fields(cls, value: Any, info) -> str:
|
|
if value is None:
|
|
if info.field_name == "output_dir":
|
|
return "./outputs"
|
|
return ""
|
|
return str(value)
|
|
|
|
@field_validator("id")
|
|
@classmethod
|
|
def validate_id(cls, value: str) -> str:
|
|
value = value.strip()
|
|
if not value:
|
|
raise ValueError("Server ID is required")
|
|
if any(c in value for c in ("/", "\\", " ")) or value in {".", ".."}:
|
|
raise ValueError("Server ID contains invalid characters")
|
|
return value
|
|
|
|
@field_validator("url")
|
|
@classmethod
|
|
def validate_url(cls, value: str) -> str:
|
|
value = value.strip()
|
|
if not value:
|
|
raise ValueError("Server URL is required")
|
|
return value
|
|
|
|
|
|
class ConfigModel(BaseModel):
|
|
servers: list[ServerModel]
|
|
default_server: str = "local"
|
|
|
|
|
|
class CreateServerModel(BaseModel):
|
|
id: str | None = None
|
|
name: str = Field(min_length=1)
|
|
url: str = Field(min_length=1)
|
|
auth: str = ""
|
|
comfy_api_key: str = ""
|
|
enabled: bool = True
|
|
output_dir: str = "./outputs"
|
|
|
|
@field_validator("id", mode="before")
|
|
@classmethod
|
|
def normalize_optional_id(cls, value: Any) -> str | None:
|
|
if value is None:
|
|
return None
|
|
return str(value)
|
|
|
|
@field_validator("name", "url", "output_dir", mode="before")
|
|
@classmethod
|
|
def normalize_create_string_fields(cls, value: Any, info) -> str:
|
|
if value is None:
|
|
if info.field_name == "output_dir":
|
|
return "./outputs"
|
|
return ""
|
|
return str(value)
|
|
|
|
@field_validator("id")
|
|
@classmethod
|
|
def validate_optional_id(cls, value: str | None) -> str | None:
|
|
if value is None:
|
|
return None
|
|
value = value.strip()
|
|
if not value:
|
|
return None
|
|
if any(c in value for c in ("/", "\\", " ")) or value in {".", ".."}:
|
|
raise ValueError("Server ID contains invalid characters")
|
|
return value
|
|
|
|
@field_validator("name")
|
|
@classmethod
|
|
def validate_name(cls, value: str) -> str:
|
|
value = value.strip()
|
|
if not value:
|
|
raise ValueError("Server name is required")
|
|
return value
|
|
|
|
@field_validator("url")
|
|
@classmethod
|
|
def validate_url(cls, value: str) -> str:
|
|
value = value.strip()
|
|
if not value:
|
|
raise ValueError("Server URL is required")
|
|
return value
|
|
|
|
|
|
class SchemaModel(BaseModel):
|
|
workflow_id: str = Field(min_length=1)
|
|
server_id: str = Field(min_length=1, default="local")
|
|
original_workflow_id: str | None = None
|
|
overwrite_existing: bool = False
|
|
description: str = ""
|
|
workflow_data: dict[str, Any]
|
|
schema_params: dict[str, dict[str, Any]]
|
|
ui_schema_params: dict[str, dict[str, Any]] | None = None
|
|
|
|
@field_validator("workflow_id", "original_workflow_id")
|
|
@classmethod
|
|
def normalize_workflow_id(cls, value: str | None) -> str | None:
|
|
if value is None:
|
|
return None
|
|
value = value.strip()
|
|
if not value:
|
|
raise ValueError("Workflow ID is required")
|
|
if any(separator in value for separator in ("/", "\\")) or value in {".", ".."}:
|
|
raise ValueError("Workflow ID contains invalid path characters")
|
|
return value
|
|
|
|
@field_validator("description")
|
|
@classmethod
|
|
def normalize_description(cls, value: str) -> str:
|
|
return value.strip()
|
|
|
|
|
|
class ToggleModel(BaseModel):
|
|
enabled: bool
|
|
|
|
|
|
class WorkflowIdsModel(BaseModel):
|
|
workflow_ids: list[str] = Field(min_length=1)
|
|
|
|
@field_validator("workflow_ids", mode="before")
|
|
@classmethod
|
|
def normalize_workflow_ids(cls, value: Any) -> list[str]:
|
|
if value is None:
|
|
return []
|
|
if not isinstance(value, list):
|
|
raise ValueError("workflow_ids must be a list")
|
|
return [str(item) for item in value]
|
|
|
|
@field_validator("workflow_ids")
|
|
@classmethod
|
|
def validate_workflow_ids(cls, value: list[str]) -> list[str]:
|
|
normalized: list[str] = []
|
|
seen: set[str] = set()
|
|
|
|
for workflow_id in value:
|
|
workflow_id = workflow_id.strip()
|
|
if not workflow_id:
|
|
raise ValueError("Workflow ID is required")
|
|
if any(separator in workflow_id for separator in ("/", "\\")) or workflow_id in {".", ".."}:
|
|
raise ValueError("Workflow ID contains invalid path characters")
|
|
if workflow_id in seen:
|
|
continue
|
|
seen.add(workflow_id)
|
|
normalized.append(workflow_id)
|
|
|
|
if not normalized:
|
|
raise ValueError("At least one workflow ID is required")
|
|
|
|
return normalized
|
|
|
|
|
|
class WorkflowOrderModel(WorkflowIdsModel):
|
|
pass
|
|
|
|
|
|
class WorkflowBatchDeleteModel(WorkflowIdsModel):
|
|
pass
|
|
|
|
|
|
class TransferPreviewModel(BaseModel):
|
|
bundle: dict[str, Any]
|
|
apply_environment: bool = False
|
|
overwrite_workflows: bool = True
|
|
|
|
|
|
class TransferImportModel(BaseModel):
|
|
bundle: dict[str, Any]
|
|
apply_environment: bool = False
|
|
overwrite_workflows: bool = True
|
|
|
|
|
|
class TransferExportModel(BaseModel):
|
|
selection: dict[str, Any] | None = None
|
|
|
|
|
|
class LocalWorkflowImportFileModel(BaseModel):
|
|
file_name: str = Field(min_length=1)
|
|
content: str = Field(min_length=1)
|
|
|
|
@field_validator("file_name", "content", mode="before")
|
|
@classmethod
|
|
def normalize_string(cls, value: Any) -> str:
|
|
if value is None:
|
|
return ""
|
|
return str(value)
|
|
|
|
|
|
class LocalWorkflowImportModel(BaseModel):
|
|
files: list[LocalWorkflowImportFileModel] = Field(min_length=1)
|
|
|
|
|
|
class RunWorkflowModel(BaseModel):
|
|
args: dict[str, Any] = Field(default_factory=dict)
|
|
|
|
|
|
class CheckDependencyModel(BaseModel):
|
|
"""Request body for checking workflow dependencies.
|
|
|
|
Provide either ``workflow_data`` (raw API-format workflow JSON) or leave
|
|
it empty to check an already-saved workflow via the URL path parameter.
|
|
"""
|
|
|
|
workflow_data: dict[str, Any] | None = None
|
|
locale: str = "zh" # "zh" or "en"
|