mirror of
https://github.com/comfyanonymous/ComfyUI.git
synced 2025-12-16 17:42:58 +08:00
fix(ReCraft-API-node): allow custom multipart parser to return FormData (#10244)
This commit is contained in:
parent
8aea746212
commit
fc34c3d112
@ -220,13 +220,16 @@ class ApiClient:
|
|||||||
if multipart_parser and data:
|
if multipart_parser and data:
|
||||||
data = multipart_parser(data)
|
data = multipart_parser(data)
|
||||||
|
|
||||||
form = aiohttp.FormData(default_to_multipart=True)
|
if isinstance(data, aiohttp.FormData):
|
||||||
if data: # regular text fields
|
form = data # If the parser already returned a FormData, pass it through
|
||||||
for k, v in data.items():
|
else:
|
||||||
if v is None:
|
form = aiohttp.FormData(default_to_multipart=True)
|
||||||
continue # aiohttp fails to serialize "None" values
|
if data: # regular text fields
|
||||||
# aiohttp expects strings or bytes; convert enums etc.
|
for k, v in data.items():
|
||||||
form.add_field(k, str(v) if not isinstance(v, (bytes, bytearray)) else v)
|
if v is None:
|
||||||
|
continue # aiohttp fails to serialize "None" values
|
||||||
|
# aiohttp expects strings or bytes; convert enums etc.
|
||||||
|
form.add_field(k, str(v) if not isinstance(v, (bytes, bytearray)) else v)
|
||||||
|
|
||||||
if files:
|
if files:
|
||||||
file_iter = files if isinstance(files, list) else files.items()
|
file_iter = files if isinstance(files, list) else files.items()
|
||||||
|
|||||||
@ -35,6 +35,7 @@ from server import PromptServer
|
|||||||
import torch
|
import torch
|
||||||
from io import BytesIO
|
from io import BytesIO
|
||||||
from PIL import UnidentifiedImageError
|
from PIL import UnidentifiedImageError
|
||||||
|
import aiohttp
|
||||||
|
|
||||||
|
|
||||||
async def handle_recraft_file_request(
|
async def handle_recraft_file_request(
|
||||||
@ -82,10 +83,16 @@ async def handle_recraft_file_request(
|
|||||||
return all_bytesio
|
return all_bytesio
|
||||||
|
|
||||||
|
|
||||||
def recraft_multipart_parser(data, parent_key=None, formatter: callable=None, converted_to_check: list[list]=None, is_list=False) -> dict:
|
def recraft_multipart_parser(
|
||||||
|
data,
|
||||||
|
parent_key=None,
|
||||||
|
formatter: callable = None,
|
||||||
|
converted_to_check: list[list] = None,
|
||||||
|
is_list: bool = False,
|
||||||
|
return_mode: str = "formdata" # "dict" | "formdata"
|
||||||
|
) -> dict | aiohttp.FormData:
|
||||||
"""
|
"""
|
||||||
Formats data such that multipart/form-data will work with requests library
|
Formats data such that multipart/form-data will work with aiohttp library when both files and data are present.
|
||||||
when both files and data are present.
|
|
||||||
|
|
||||||
The OpenAI client that Recraft uses has a bizarre way of serializing lists:
|
The OpenAI client that Recraft uses has a bizarre way of serializing lists:
|
||||||
|
|
||||||
@ -103,19 +110,19 @@ def recraft_multipart_parser(data, parent_key=None, formatter: callable=None, co
|
|||||||
# Modification of a function that handled a different type of multipart parsing, big ups:
|
# Modification of a function that handled a different type of multipart parsing, big ups:
|
||||||
# https://gist.github.com/kazqvaizer/4cebebe5db654a414132809f9f88067b
|
# https://gist.github.com/kazqvaizer/4cebebe5db654a414132809f9f88067b
|
||||||
|
|
||||||
def handle_converted_lists(data, parent_key, lists_to_check=tuple[list]):
|
def handle_converted_lists(item, parent_key, lists_to_check=tuple[list]):
|
||||||
# if list already exists exists, just extend list with data
|
# if list already exists exists, just extend list with data
|
||||||
for check_list in lists_to_check:
|
for check_list in lists_to_check:
|
||||||
for conv_tuple in check_list:
|
for conv_tuple in check_list:
|
||||||
if conv_tuple[0] == parent_key and isinstance(conv_tuple[1], list):
|
if conv_tuple[0] == parent_key and isinstance(conv_tuple[1], list):
|
||||||
conv_tuple[1].append(formatter(data))
|
conv_tuple[1].append(formatter(item))
|
||||||
return True
|
return True
|
||||||
return False
|
return False
|
||||||
|
|
||||||
if converted_to_check is None:
|
if converted_to_check is None:
|
||||||
converted_to_check = []
|
converted_to_check = []
|
||||||
|
|
||||||
|
effective_mode = return_mode if parent_key is None else "dict"
|
||||||
if formatter is None:
|
if formatter is None:
|
||||||
formatter = lambda v: v # Multipart representation of value
|
formatter = lambda v: v # Multipart representation of value
|
||||||
|
|
||||||
@ -145,6 +152,15 @@ def recraft_multipart_parser(data, parent_key=None, formatter: callable=None, co
|
|||||||
else:
|
else:
|
||||||
converted.append((current_key, formatter(value)))
|
converted.append((current_key, formatter(value)))
|
||||||
|
|
||||||
|
if effective_mode == "formdata":
|
||||||
|
fd = aiohttp.FormData()
|
||||||
|
for k, v in dict(converted).items():
|
||||||
|
if isinstance(v, list):
|
||||||
|
for item in v:
|
||||||
|
fd.add_field(k, str(item))
|
||||||
|
else:
|
||||||
|
fd.add_field(k, str(v))
|
||||||
|
return fd
|
||||||
return dict(converted)
|
return dict(converted)
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user