diff --git a/config.json.example b/config.json.example index 4e67c5c..28283e1 100644 --- a/config.json.example +++ b/config.json.example @@ -26,5 +26,10 @@ "deepseek-v3.1:671b", "gpt-oss:120b" ] + }, + "proxy":{ + "enable": false, + "http": "", + "https": "http://127.0.0.1:7890" } } \ No newline at end of file diff --git a/gemini/gemini_image_node.py b/gemini/gemini_image_node.py index 9f8dc7d..7fec5a5 100644 --- a/gemini/gemini_image_node.py +++ b/gemini/gemini_image_node.py @@ -11,6 +11,7 @@ from io import BytesIO from typing_extensions import override from comfy_api.latest import ComfyExtension, io from ..utils.image_utils import tensor_to_base64_string +from ..utils.config_utils import get_config_section class GeminiImage(io.ComfyNode): """ @@ -89,6 +90,27 @@ class GeminiImage(io.ComfyNode): except Exception as e: raise ValueError(f"Config loading error: {str(e)}") + @classmethod + def _get_proxy_config(cls): + """ + 从config.json中获取代理配置 + 返回 proxies 字典或 None + """ + try: + proxy_config = get_config_section('proxy') + if not proxy_config or not proxy_config.get('enable', False): + return None + + proxies = {} + if proxy_config.get('http'): + proxies['http'] = proxy_config['http'] + if proxy_config.get('https'): + proxies['https'] = proxy_config['https'] + + return proxies if proxies else None + except Exception: + return None + @classmethod def define_schema(cls) -> io.Schema: """ @@ -107,7 +129,7 @@ class GeminiImage(io.ComfyNode): category="YCYY/API/image", inputs=[ io.Image.Input( - "images", + id="images", optional=True, tooltip="Optional image(s) to use as context for the model" ), @@ -173,16 +195,18 @@ class GeminiImage(io.ComfyNode): def execute(cls, prompt, model, aspectRatio, seed,images=None) -> io.NodeOutput: # 加载配置和凭据 base_url, api_key, timeout = cls._load_config_credentials() + # 获取代理配置 + proxies = cls._get_proxy_config() if not prompt: raise ValueError("prompt cannot be empty") api_url = base_url+"/"+model+":generateContent" if images is not None: - return cls._edit_images(api_url,api_key,prompt,aspectRatio,seed,images,timeout) + return cls._edit_images(api_url,api_key,prompt,aspectRatio,seed,images,timeout,proxies) else: - return cls._generate_images(api_url,api_key,prompt,aspectRatio,seed,timeout) + return cls._generate_images(api_url,api_key,prompt,aspectRatio,seed,timeout,proxies) # 图生图模式 @classmethod - def _edit_images(cls,api_url,api_key,prompt,aspectRatio,seed,images,timeout)-> io.NodeOutput: + def _edit_images(cls,api_url,api_key,prompt,aspectRatio,seed,images,timeout,proxies=None)-> io.NodeOutput: image_parts = cls._create_image_parts(images) image_parts.append( { @@ -211,7 +235,7 @@ class GeminiImage(io.ComfyNode): # print(f"正在请求Gemini文生图API: {api_url}") # print(f"请求载荷: {json.dumps(payload)}") try: - resp = requests.post(api_url, headers=headers, json=payload, timeout=timeout) + resp = requests.post(api_url, headers=headers, json=payload, timeout=timeout, proxies=proxies) return cls._parse_response(resp) except Exception as e: empty_image = cls._create_empty_image() @@ -235,7 +259,7 @@ class GeminiImage(io.ComfyNode): return image_parts # 文生图模式 @classmethod - def _generate_images(cls,api_url,api_key,prompt,aspectRatio,seed,timeout)-> io.NodeOutput: + def _generate_images(cls,api_url,api_key,prompt,aspectRatio,seed,timeout,proxies=None)-> io.NodeOutput: headers = { "x-goog-api-key": api_key, "Content-Type": "application/json" @@ -262,7 +286,7 @@ class GeminiImage(io.ComfyNode): # print(f"正在请求Gemini文生图API: {api_url}") # print(f"请求载荷: {json.dumps(payload)}") try: - resp = requests.post(api_url, headers=headers, json=payload, timeout=timeout) + resp = requests.post(api_url, headers=headers, json=payload, timeout=timeout, proxies=proxies) return cls._parse_response(resp) except Exception as e: empty_image = cls._create_empty_image() diff --git a/locales/en/nodeDefs.json b/locales/en/nodeDefs.json index 82adb64..4328347 100644 --- a/locales/en/nodeDefs.json +++ b/locales/en/nodeDefs.json @@ -3,7 +3,7 @@ "display_name": "Gemini Image API", "inputs": { "images": { - "name": "image", + "name": "images", "tooltip": "Optional image(s) to use as context for the model" }, "prompt": {