feat(http_request_node): build http request config

Signed-off-by: -LAN- <laipz8200@outlook.com>
This commit is contained in:
-LAN-
2026-02-24 15:13:31 +08:00
parent 03e4dc4d9c
commit c81897d4bf
7 changed files with 46 additions and 59 deletions

View File

@@ -17,7 +17,7 @@ from core.workflow.nodes.base.node import Node
from core.workflow.nodes.code.code_node import CodeNode
from core.workflow.nodes.code.limits import CodeNodeLimits
from core.workflow.nodes.document_extractor import DocumentExtractorNode, UnstructuredApiConfig
from core.workflow.nodes.http_request import HttpRequestNode, HttpRequestNodeConfig
from core.workflow.nodes.http_request import HttpRequestNode, build_http_request_config
from core.workflow.nodes.knowledge_retrieval.knowledge_retrieval_node import KnowledgeRetrievalNode
from core.workflow.nodes.node_mapping import LATEST_VERSION, NODE_TYPE_CLASSES_MAPPING
from core.workflow.nodes.protocols import FileManagerProtocol, HttpClientProtocol
@@ -88,15 +88,7 @@ class DifyNodeFactory(NodeFactory):
api_key=dify_config.UNSTRUCTURED_API_KEY or "",
)
)
self._http_request_config = http_request_config or HttpRequestNodeConfig(
max_connect_timeout=dify_config.HTTP_REQUEST_MAX_CONNECT_TIMEOUT,
max_read_timeout=dify_config.HTTP_REQUEST_MAX_READ_TIMEOUT,
max_write_timeout=dify_config.HTTP_REQUEST_MAX_WRITE_TIMEOUT,
max_binary_size=dify_config.HTTP_REQUEST_NODE_MAX_BINARY_SIZE,
max_text_size=dify_config.HTTP_REQUEST_NODE_MAX_TEXT_SIZE,
ssl_verify=dify_config.HTTP_REQUEST_NODE_SSL_VERIFY,
ssrf_default_max_retries=dify_config.SSRF_DEFAULT_MAX_RETRIES,
)
self._http_request_config = http_request_config or build_http_request_config()
@override
def create_node(self, node_config: NodeConfigDict) -> Node:

View File

@@ -1,3 +1,4 @@
from .config import build_http_request_config, resolve_http_request_config
from .entities import (
HTTP_REQUEST_CONFIG_FILTER_KEY,
BodyData,
@@ -16,4 +17,6 @@ __all__ = [
"HttpRequestNodeBody",
"HttpRequestNodeConfig",
"HttpRequestNodeData",
"build_http_request_config",
"resolve_http_request_config",
]

View File

@@ -0,0 +1,26 @@
from collections.abc import Mapping
from configs import dify_config
from .entities import HTTP_REQUEST_CONFIG_FILTER_KEY, HttpRequestNodeConfig
def build_http_request_config() -> HttpRequestNodeConfig:
return HttpRequestNodeConfig(
max_connect_timeout=dify_config.HTTP_REQUEST_MAX_CONNECT_TIMEOUT,
max_read_timeout=dify_config.HTTP_REQUEST_MAX_READ_TIMEOUT,
max_write_timeout=dify_config.HTTP_REQUEST_MAX_WRITE_TIMEOUT,
max_binary_size=dify_config.HTTP_REQUEST_NODE_MAX_BINARY_SIZE,
max_text_size=dify_config.HTTP_REQUEST_NODE_MAX_TEXT_SIZE,
ssl_verify=dify_config.HTTP_REQUEST_NODE_SSL_VERIFY,
ssrf_default_max_retries=dify_config.SSRF_DEFAULT_MAX_RETRIES,
)
def resolve_http_request_config(filters: Mapping[str, object] | None) -> HttpRequestNodeConfig:
if not filters:
raise ValueError("http_request_config is required to build HTTP request default config")
config = filters.get(HTTP_REQUEST_CONFIG_FILTER_KEY)
if not isinstance(config, HttpRequestNodeConfig):
raise ValueError("http_request_config must be an HttpRequestNodeConfig instance")
return config

View File

@@ -102,12 +102,11 @@ class Executor:
self.method = node_data.method
self.auth = node_data.authorization
self.timeout = timeout
resolved_ssl_verify = ssl_verify if ssl_verify is not None else node_data.ssl_verify
if resolved_ssl_verify is None:
resolved_ssl_verify = self._http_request_config.ssl_verify
if not isinstance(resolved_ssl_verify, bool):
self.ssl_verify = ssl_verify if ssl_verify is not None else node_data.ssl_verify
if self.ssl_verify is None:
self.ssl_verify = self._http_request_config.ssl_verify
if not isinstance(self.ssl_verify, bool):
raise ValueError("ssl_verify must be a boolean")
self.ssl_verify = resolved_ssl_verify
self.params = None
self.headers = {}
self.content = None

View File

@@ -17,8 +17,8 @@ from core.workflow.nodes.http_request.executor import Executor
from core.workflow.nodes.protocols import FileManagerProtocol, HttpClientProtocol
from factories import file_factory
from .config import resolve_http_request_config
from .entities import (
HTTP_REQUEST_CONFIG_FILTER_KEY,
HttpRequestNodeConfig,
HttpRequestNodeData,
HttpRequestNodeTimeout,
@@ -33,15 +33,6 @@ if TYPE_CHECKING:
from core.workflow.runtime import GraphRuntimeState
def _resolve_http_request_config(filters: Mapping[str, object] | None) -> HttpRequestNodeConfig:
if not filters:
raise ValueError("http_request_config is required to build HTTP request default config")
config = filters.get(HTTP_REQUEST_CONFIG_FILTER_KEY)
if not isinstance(config, HttpRequestNodeConfig):
raise ValueError("http_request_config must be an HttpRequestNodeConfig instance")
return config
class HttpRequestNode(Node[HttpRequestNodeData]):
node_type = NodeType.HTTP_REQUEST
@@ -70,7 +61,7 @@ class HttpRequestNode(Node[HttpRequestNodeData]):
@classmethod
def get_default_config(cls, filters: Mapping[str, object] | None = None) -> Mapping[str, object]:
http_request_config = _resolve_http_request_config(filters)
http_request_config = resolve_http_request_config(filters)
default_timeout = http_request_config.default_timeout()
return {
"type": "http-request",

View File

@@ -47,7 +47,7 @@ from core.workflow.graph_events import NodeRunFailedEvent, NodeRunSucceededEvent
from core.workflow.graph_events.base import GraphNodeEventBase
from core.workflow.node_events.base import NodeRunResult
from core.workflow.nodes.base.node import Node
from core.workflow.nodes.http_request import HTTP_REQUEST_CONFIG_FILTER_KEY, HttpRequestNodeConfig
from core.workflow.nodes.http_request import HTTP_REQUEST_CONFIG_FILTER_KEY, build_http_request_config
from core.workflow.nodes.node_mapping import LATEST_VERSION, NODE_TYPE_CLASSES_MAPPING
from core.workflow.repositories.workflow_node_execution_repository import OrderConfig
from core.workflow.runtime import VariablePool
@@ -87,18 +87,6 @@ from services.workflow_draft_variable_service import DraftVariableSaver, DraftVa
logger = logging.getLogger(__name__)
def _build_http_request_config() -> HttpRequestNodeConfig:
return HttpRequestNodeConfig(
max_connect_timeout=dify_config.HTTP_REQUEST_MAX_CONNECT_TIMEOUT,
max_read_timeout=dify_config.HTTP_REQUEST_MAX_READ_TIMEOUT,
max_write_timeout=dify_config.HTTP_REQUEST_MAX_WRITE_TIMEOUT,
max_binary_size=dify_config.HTTP_REQUEST_NODE_MAX_BINARY_SIZE,
max_text_size=dify_config.HTTP_REQUEST_NODE_MAX_TEXT_SIZE,
ssl_verify=dify_config.HTTP_REQUEST_NODE_SSL_VERIFY,
ssrf_default_max_retries=dify_config.SSRF_DEFAULT_MAX_RETRIES,
)
class RagPipelineService:
def __init__(self, session_maker: sessionmaker | None = None):
"""Initialize RagPipelineService with repository dependencies."""
@@ -397,7 +385,7 @@ class RagPipelineService:
node_class = node_class_mapping[LATEST_VERSION]
filters = None
if node_type is NodeType.HTTP_REQUEST:
filters = {HTTP_REQUEST_CONFIG_FILTER_KEY: _build_http_request_config()}
filters = {HTTP_REQUEST_CONFIG_FILTER_KEY: build_http_request_config()}
default_config = node_class.get_default_config(filters=filters)
if default_config:
default_block_configs.append(dict(default_config))
@@ -418,10 +406,10 @@ class RagPipelineService:
return None
node_class = NODE_TYPE_CLASSES_MAPPING[node_type_enum][LATEST_VERSION]
resolved_filters = dict(filters) if filters else {}
if node_type_enum is NodeType.HTTP_REQUEST and HTTP_REQUEST_CONFIG_FILTER_KEY not in resolved_filters:
resolved_filters[HTTP_REQUEST_CONFIG_FILTER_KEY] = _build_http_request_config()
default_config = node_class.get_default_config(filters=resolved_filters or None)
final_filters = dict(filters) if filters else {}
if node_type_enum is NodeType.HTTP_REQUEST and HTTP_REQUEST_CONFIG_FILTER_KEY not in final_filters:
final_filters[HTTP_REQUEST_CONFIG_FILTER_KEY] = build_http_request_config()
default_config = node_class.get_default_config(filters=final_filters or None)
if not default_config:
return None

View File

@@ -26,7 +26,7 @@ from core.workflow.graph_events import GraphNodeEventBase, NodeRunFailedEvent, N
from core.workflow.node_events import NodeRunResult
from core.workflow.nodes import NodeType
from core.workflow.nodes.base.node import Node
from core.workflow.nodes.http_request import HTTP_REQUEST_CONFIG_FILTER_KEY, HttpRequestNodeConfig
from core.workflow.nodes.http_request import HTTP_REQUEST_CONFIG_FILTER_KEY, build_http_request_config
from core.workflow.nodes.human_input.entities import (
DeliveryChannelConfig,
HumanInputNodeData,
@@ -71,18 +71,6 @@ from .human_input_delivery_test_service import (
from .workflow_draft_variable_service import DraftVariableSaver, DraftVarLoader, WorkflowDraftVariableService
def _build_http_request_config() -> HttpRequestNodeConfig:
return HttpRequestNodeConfig(
max_connect_timeout=dify_config.HTTP_REQUEST_MAX_CONNECT_TIMEOUT,
max_read_timeout=dify_config.HTTP_REQUEST_MAX_READ_TIMEOUT,
max_write_timeout=dify_config.HTTP_REQUEST_MAX_WRITE_TIMEOUT,
max_binary_size=dify_config.HTTP_REQUEST_NODE_MAX_BINARY_SIZE,
max_text_size=dify_config.HTTP_REQUEST_NODE_MAX_TEXT_SIZE,
ssl_verify=dify_config.HTTP_REQUEST_NODE_SSL_VERIFY,
ssrf_default_max_retries=dify_config.SSRF_DEFAULT_MAX_RETRIES,
)
class WorkflowService:
"""
Workflow Service
@@ -635,7 +623,7 @@ class WorkflowService:
node_class = node_class_mapping[LATEST_VERSION]
filters = None
if node_type is NodeType.HTTP_REQUEST:
filters = {HTTP_REQUEST_CONFIG_FILTER_KEY: _build_http_request_config()}
filters = {HTTP_REQUEST_CONFIG_FILTER_KEY: build_http_request_config()}
default_config = node_class.get_default_config(filters=filters)
if default_config:
default_block_configs.append(default_config)
@@ -660,7 +648,7 @@ class WorkflowService:
node_class = NODE_TYPE_CLASSES_MAPPING[node_type_enum][LATEST_VERSION]
resolved_filters = dict(filters) if filters else {}
if node_type_enum is NodeType.HTTP_REQUEST and HTTP_REQUEST_CONFIG_FILTER_KEY not in resolved_filters:
resolved_filters[HTTP_REQUEST_CONFIG_FILTER_KEY] = _build_http_request_config()
resolved_filters[HTTP_REQUEST_CONFIG_FILTER_KEY] = build_http_request_config()
default_config = node_class.get_default_config(filters=resolved_filters or None)
if not default_config:
return {}