feat: support http get

This commit is contained in:
wawahuy
2025-07-22 01:17:05 +07:00
commit a84d002140
7 changed files with 255 additions and 0 deletions
+2
View File
@@ -0,0 +1,2 @@
__pycache__/
*.py[cod]
+36
View File
@@ -0,0 +1,36 @@
# ComfyUI HTTP - REST API Nodes
Powerful REST API nodes for ComfyUI that enable seamless HTTP/REST integration into your workflows.
## Installation
1. Clone the repository into your ComfyUI `custom_nodes` directory:
```bash
cd ComfyUI/custom_nodes
git clone https://github.com/wawahuy/ComfyUI-HTTP.git
```
2. Install dependencies:
```bash
cd ComfyUI-HTTP
pip install -r requirements.txt
```
3. Restart ComfyUI
## Contributing
We welcome contributions! Please:
1. Fork the repository
2. Create a feature branch
3. Commit your changes
4. Submit a pull request
## License
MIT License - see LICENSE file for details.
## Support
If you encounter issues or have questions, please create an issue on the GitHub repository.
+14
View File
@@ -0,0 +1,14 @@
from .http_get import HTTPGetNode
from .http_get_json_field import HTTPGetJSONFieldNode
NODE_CLASS_MAPPINGS = {
"HTTPGetNode": HTTPGetNode,
"HTTPGetJSONFieldNode": HTTPGetJSONFieldNode,
}
NODE_DISPLAY_NAME_MAPPINGS = {
"HTTPGetNode": "HTTP Get",
"HTTPGetJSONFieldNode": "HTTP Get JSON Field",
}
__all__ = ['NODE_CLASS_MAPPINGS', 'NODE_DISPLAY_NAME_MAPPINGS']
+123
View File
@@ -0,0 +1,123 @@
import requests
import json
import time
from typing import Dict, Any, Tuple
class HTTPGetNode:
@classmethod
def INPUT_TYPES(cls) -> Dict[str, Any]:
return {
"required": {
"url": ("STRING", {
"multiline": False,
"default": "https://httpbin.org/json"
}),
},
"optional": {
"headers": ("STRING", {
"multiline": True,
"default": '{"Content-Type": "application/json", "User-Agent": "ComfyUI-HTTPPull-Starter/1.0"}'
}),
"params": ("STRING", {
"multiline": True,
"default": '{"workflow": "started", "source": "comfyui"}'
}),
"timeout": ("INT", {
"default": 30,
"min": 5,
"max": 300,
"step": 5
}),
"retry_count": ("INT", {
"default": 1,
"min": 1,
"max": 5,
"step": 1
}),
"retry_delay": ("INT", {
"default": 5,
"min": 1,
"max": 30,
"step": 1
}),
}
}
RETURN_TYPES = ("STRING", "STRING", "INT", "BOOLEAN", "STRING")
RETURN_NAMES = ("response_text", "response_json", "status_code", "success", "workflow_id")
FUNCTION = "http_get"
CATEGORY = "HTTP/API"
OUTPUT_NODE = False
def http_get(self, url: str, headers: str = "", params: str = "",
timeout: int = 30, retry_count: int = 1, retry_delay: int = 5) -> Tuple[str, str, int, bool, str]:
workflow_id = f"wf_{int(time.time())}"
last_error = ""
for attempt in range(retry_count):
try:
request_headers = {"Content-Type": "application/json"}
if headers:
try:
parsed_headers = json.loads(headers)
request_headers.update(parsed_headers)
except json.JSONDecodeError:
print(f"Warning: Invalid headers JSON format: {headers}")
request_params = {}
if params:
try:
request_params = json.loads(params)
request_params["workflow_id"] = workflow_id
request_params["attempt"] = attempt + 1
except json.JSONDecodeError:
print(f"Warning: Invalid params JSON format: {params}")
print(f"HTTP Get - Attempt {attempt + 1}/{retry_count} - URL: {url}")
response = requests.get(
url=url,
headers=request_headers,
params=request_params,
timeout=timeout
)
response_text = response.text
response_json = "{}"
try:
json.loads(response_text)
response_json = response_text
except json.JSONDecodeError:
response_json = "{}"
status_code = response.status_code
success = 200 <= status_code < 300
if success:
print(f"HTTP Get - Success: Workflow {workflow_id} started")
return (response_text, response_json, status_code, True, workflow_id)
else:
last_error = f"HTTP error {status_code}: {response_text[:200]}"
except requests.exceptions.Timeout:
last_error = f"Request timeout after {timeout} seconds"
print(f"HTTP Get - Attempt {attempt + 1} failed: {last_error}")
except requests.exceptions.ConnectionError:
last_error = f"Connection error to {url}"
print(f"HTTP Get - Attempt {attempt + 1} failed: {last_error}")
except Exception as e:
last_error = f"HTTP Get Error: {str(e)}"
print(f"HTTP Get - Attempt {attempt + 1} failed: {last_error}")
if attempt < retry_count - 1:
print(f"Waiting {retry_delay} seconds before retry...")
time.sleep(retry_delay)
print(f"HTTP Get - All attempts failed for workflow {workflow_id}")
return (last_error, "{}", 0, False, workflow_id)
+77
View File
@@ -0,0 +1,77 @@
import json
from typing import Dict, Any, Tuple, Union
class HTTPGetJSONFieldNode:
@classmethod
def INPUT_TYPES(cls) -> Dict[str, Any]:
return {
"required": {
"json_input": ("STRING", {
"multiline": True,
"default": '{"data": {"message": "Hello World"}, "status": "success"}'
}),
"field_path": ("STRING", {
"multiline": False,
"default": "data.message"
}),
},
"optional": {
"default_value": ("STRING", {
"multiline": False,
"default": ""
}),
"return_as_string": ("BOOLEAN", {
"default": True
}),
}
}
RETURN_TYPES = ("STRING", "STRING", "BOOLEAN")
RETURN_NAMES = ("field_value", "error_message", "found")
FUNCTION = "get_json_field"
CATEGORY = "HTTP/API"
def get_json_field(self, json_input: str, field_path: str,
default_value: str = "", return_as_string: bool = True) -> Tuple[str, str, bool]:
try:
data = json.loads(json_input)
path_parts = field_path.split('.')
current_value = data
for part in path_parts:
if isinstance(current_value, dict) and part in current_value:
current_value = current_value[part]
elif isinstance(current_value, list):
try:
index = int(part)
if 0 <= index < len(current_value):
current_value = current_value[index]
else:
return (default_value, f"List index {index} out of range", False)
except ValueError:
return (default_value, f"Cannot access list with key '{part}'", False)
else:
return (default_value, f"Field '{part}' not found in path '{field_path}'", False)
if return_as_string:
if isinstance(current_value, (dict, list)):
result_value = json.dumps(current_value, ensure_ascii=False)
else:
result_value = str(current_value)
else:
result_value = str(current_value)
print(f"JSON Field Get - Path: {field_path}, Found: {type(current_value).__name__}")
return (result_value, "", True)
except json.JSONDecodeError as e:
error_message = f"Invalid JSON format: {str(e)}"
print(f"JSON Field Error: {error_message}")
return (default_value, error_message, False)
except Exception as e:
error_message = f"Error getting field: {str(e)}"
print(f"JSON Field Error: {error_message}")
return (default_value, error_message, False)
View File
+3
View File
@@ -0,0 +1,3 @@
requests>=2.25.0
pillow>=8.0.0
numpy>=1.19.0