From 983b53aa4873b835e35fb5030ad782137ae1d3fb Mon Sep 17 00:00:00 2001 From: Lina Tang Date: Thu, 19 Oct 2023 15:37:43 +0800 Subject: [PATCH] Add utils for multimedia data (#805) # Description Add utils for multimedia data. #### Changes: 1. Provide some common functions in `multimedia_utils`. 2. Support image inputs in jinja template. # All Promptflow Contribution checklist: - [ ] **The pull request does not introduce [breaking changes].** - [ ] **CHANGELOG is updated for new features, bug fixes or other significant changes.** - [x] **I have read the [contribution guidelines](../CONTRIBUTING.md).** - [ ] **Create an issue and link to the pull request to get dedicated review from promptflow team. Learn more: [suggested workflow](../CONTRIBUTING.md#suggested-workflow).** ## General Guidelines and Best Practices - [x] Title of the pull request is clear and informative. - [x] There are a small number of commits, each of which have an informative message. This means that previously merged commits do not appear in the history of the PR. For more information on cleaning up the commits in your PR, [see this page](https://github.com/Azure/azure-powershell/blob/master/documentation/development-docs/cleaning-up-commits.md). ### Testing Guidelines - [ ] Pull request includes test coverage for the included changes. --------- Co-authored-by: Lina Tang --- .../promptflow/_core/run_tracker.py | 4 +- src/promptflow/promptflow/_core/tracer.py | 4 +- .../_sdk/operations/_test_submitter.py | 3 +- .../promptflow/_utils/multimedia_utils.py | 195 ++++++++++++++++++ .../promptflow/contracts/multimedia.py | 176 +--------------- .../promptflow/executor/_tool_resolver.py | 27 ++- .../promptflow/executor/flow_executor.py | 37 +--- .../promptflow/storage/_run_storage.py | 24 +-- .../unittests/executor/test_tool_resolver.py | 12 +- src/promptflow/tests/executor/utils.py | 1 + .../tests/test_configs/datas/test_image.jpg | Bin 0 -> 140150 bytes 11 files changed, 254 insertions(+), 229 deletions(-) create mode 100644 src/promptflow/promptflow/_utils/multimedia_utils.py create mode 100644 src/promptflow/tests/test_configs/datas/test_image.jpg diff --git a/src/promptflow/promptflow/_core/run_tracker.py b/src/promptflow/promptflow/_core/run_tracker.py index 58edc5977c2..a73b4a9091d 100644 --- a/src/promptflow/promptflow/_core/run_tracker.py +++ b/src/promptflow/promptflow/_core/run_tracker.py @@ -14,8 +14,8 @@ from promptflow._utils.dataclass_serializer import serialize from promptflow._utils.exception_utils import ExceptionPresenter from promptflow._utils.logger_utils import flow_logger +from promptflow._utils.multimedia_utils import default_json_encoder from promptflow._utils.openai_metrics_calculator import OpenAIMetricsCalculator -from promptflow.contracts.multimedia import PFBytes from promptflow.contracts.run_info import FlowRunInfo, RunInfo, Status from promptflow.contracts.run_mode import RunMode from promptflow.contracts.tool import ConnectionType @@ -241,7 +241,7 @@ def _ensure_serializable_value(self, val, warning_msg: Optional[str] = None): if self.allow_generator_types and isinstance(val, GeneratorType): return str(val) try: - json.dumps(val, default=PFBytes.default_json_encoder) + json.dumps(val, default=default_json_encoder) return val except Exception: if not warning_msg: diff --git a/src/promptflow/promptflow/_core/tracer.py b/src/promptflow/promptflow/_core/tracer.py index a7aacb6047d..0470d26f642 100644 --- a/src/promptflow/promptflow/_core/tracer.py +++ b/src/promptflow/promptflow/_core/tracer.py @@ -12,7 +12,7 @@ from promptflow._core.generator_proxy import GeneratorProxy, generate_from_proxy from promptflow._utils.dataclass_serializer import serialize -from promptflow.contracts.multimedia import PFBytes +from promptflow._utils.multimedia_utils import default_json_encoder from promptflow.contracts.tool import ConnectionType from promptflow.contracts.trace import Trace, TraceType @@ -81,7 +81,7 @@ def to_serializable(obj): return obj try: obj = serialize(obj) - json.dumps(obj, default=PFBytes.default_json_encoder) + json.dumps(obj, default=default_json_encoder) except Exception: # We don't want to fail the whole function call because of a serialization error, # so we simply convert it to str if it cannot be serialized. diff --git a/src/promptflow/promptflow/_sdk/operations/_test_submitter.py b/src/promptflow/promptflow/_sdk/operations/_test_submitter.py index 06f33fd9cab..677aa653080 100644 --- a/src/promptflow/promptflow/_sdk/operations/_test_submitter.py +++ b/src/promptflow/promptflow/_sdk/operations/_test_submitter.py @@ -19,6 +19,7 @@ from promptflow._utils.context_utils import _change_working_dir from promptflow._utils.dataclass_serializer import serialize from promptflow._utils.exception_utils import ErrorResponse +from promptflow._utils.multimedia_utils import persist_multimedia_date from promptflow.contracts.flow import Flow as ExecutableFlow from promptflow.contracts.run_info import Status from promptflow.exceptions import UserErrorException @@ -157,7 +158,7 @@ def flow_test( ) flow_executor.enable_streaming_for_llm_flow(lambda: True) line_result = flow_executor.exec_line(inputs, index=0, allow_generator_output=allow_generator_output) - line_result.output = flow_executor._persist_images_from_output( + line_result.output = persist_multimedia_date( line_result.output, base_dir=self.flow.code, sub_dir=Path(".promptflow/output") ) if line_result.aggregation_inputs: diff --git a/src/promptflow/promptflow/_utils/multimedia_utils.py b/src/promptflow/promptflow/_utils/multimedia_utils.py new file mode 100644 index 00000000000..14d4ee52347 --- /dev/null +++ b/src/promptflow/promptflow/_utils/multimedia_utils.py @@ -0,0 +1,195 @@ +import base64 +import imghdr +import os +import re +import requests +import uuid + +from functools import partial +from pathlib import Path +from typing import Any, Callable +from urllib.parse import urlparse + +from promptflow.contracts._errors import InvalidImageInput +from promptflow.contracts.multimedia import Image, PFBytes +from promptflow.exceptions import ErrorTarget + +MIME_PATTERN = re.compile(r"^data:image/(.*);(path|base64|url)$") + + +def get_mime_type_from_path(path: Path): + ext = path.suffix[1:] + return f"image/{ext}" if ext else "image/*" + + +def get_extension_from_mime_type(mime_type: str): + ext = mime_type.split("/")[-1] + if ext == "*": + return None + return ext + + +def is_multimedia_dict(multimedia_dict: dict): + if len(multimedia_dict) != 1: + return False + key = list(multimedia_dict.keys())[0] + if re.match(MIME_PATTERN, key): + return True + return False + + +def get_multimedia_info(key: str): + match = re.match(MIME_PATTERN, key) + if match: + return match.group(1), match.group(2) + return None, None + + +def is_url(value: str): + try: + result = urlparse(value) + return all([result.scheme, result.netloc]) + except ValueError: + return False + + +def is_base64(value: str): + base64_regex = re.compile(r"^([A-Za-z0-9+/]{4})*(([A-Za-z0-9+/]{2})*(==|[A-Za-z0-9+/]=)?)?$") + if re.match(base64_regex, value): + return True + return False + + +def create_image_from_file(f: Path, mime_type: str = None): + if not mime_type: + mime_type = get_mime_type_from_path(f) + with open(f, "rb") as fin: + return Image(fin.read(), mime_type=mime_type) + + +def create_image_from_base64(base64_str: str, mime_type: str = None): + image_bytes = base64.b64decode(base64_str) + if not mime_type: + format = imghdr.what(None, image_bytes) + mime_type = f"image/{format}" if format else "image/*" + return Image(image_bytes, mime_type=mime_type) + + +def create_image_from_url(url: str, mime_type: str = None): + response = requests.get(url) + if response.status_code == 200: + if not mime_type: + format = imghdr.what(None, response.content) + mime_type = f"image/{format}" if format else "image/*" + return Image(response.content, mime_type=mime_type) + else: + raise InvalidImageInput( + message_format=f"Error while fetching image from URL: {url}. " + "Error code: {response.status_code}. Error message: {response.text}.", + target=ErrorTarget.EXECUTOR, + ) + + +def create_image_from_dict(image_dict: dict): + for k, v in image_dict.items(): + format, resource = get_multimedia_info(k) + if resource == "path": + return create_image_from_file(v, mime_type=f"image/{format}") + elif resource == "base64": + return create_image_from_base64(v, mime_type=f"image/{format}") + elif resource == "url": + return create_image_from_url(v, mime_type=f"image/{format}") + else: + raise InvalidImageInput( + message_format=f"Unsupported image resource: {resource}. " + "Supported Resources are [path, base64, url].", + target=ErrorTarget.EXECUTOR, + ) + + +def create_image_from_string(value: str, base_dir: Path = None): + if is_base64(value): + return create_image_from_base64(value) + elif is_url(value): + return create_image_from_url(value) + else: + path = Path(value) + if base_dir and not path.is_absolute(): + path = Path.joinpath(base_dir, path) + return create_image_from_file(path) + + +def create_image(value: any, base_dir: Path = None): + if isinstance(value, PFBytes): + return value + elif isinstance(value, dict): + if is_multimedia_dict(value): + return create_image_from_dict(value) + else: + raise InvalidImageInput( + message_format="Invalid image input format. The image input should be a dictionary like: " + "{data:image/;[path|base64|url]: }.", + target=ErrorTarget.EXECUTOR, + ) + elif isinstance(value, str): + return create_image_from_string(value, base_dir) + else: + raise InvalidImageInput( + message_format=f"Unsupported image input type: {type(value)}. " + "The image inputs should be a string or a dictionary.", + target=ErrorTarget.EXECUTOR, + ) + + +def save_image_to_file(image: Image, file_name: str, folder_path: Path, relative_path: Path = None): + ext = get_extension_from_mime_type(image._mime_type) + file_name = f"{file_name}.{ext}" if ext else file_name + image_reference = { + f"data:{image._mime_type};path": str(relative_path / file_name) if relative_path else file_name + } + path = folder_path / relative_path if relative_path else folder_path + os.makedirs(path, exist_ok=True) + with open(os.path.join(path, file_name), 'wb') as file: + file.write(image) + return image_reference + + +def get_file_reference_encoder(folder_path: Path, relative_path: Path = None) -> Callable: + def pfbytes_file_reference_encoder(obj): + """Dumps PFBytes to a file and returns its reference.""" + if isinstance(obj, PFBytes): + file_name = str(uuid.uuid4()) + return save_image_to_file(obj, file_name, folder_path, relative_path) + raise TypeError(f"Not supported to dump type '{type(obj).__name__}'.") + return pfbytes_file_reference_encoder + + +def default_json_encoder(obj): + if isinstance(obj, PFBytes): + return str(obj) + else: + raise TypeError(f"Object of type {type(obj).__name__} is not JSON serializable") + + +def persist_multimedia_date(value: Any, base_dir: Path, sub_dir: Path = None): + pfbytes_file_reference_encoder = get_file_reference_encoder(base_dir, sub_dir) + serialization_funcs = {Image: partial(Image.serialize, **{"encoder": pfbytes_file_reference_encoder})} + return recursive_process(value, process_funcs=serialization_funcs) + + +def convert_multimedia_date_to_base64(value: Any): + to_base64_funcs = {PFBytes: PFBytes.to_base64} + return recursive_process(value, process_funcs=to_base64_funcs) + + +# TODO: Move this function to a more general place and integrate serialization to this function. +def recursive_process(value: Any, process_funcs: dict[type, Callable] = None) -> dict: + if process_funcs: + for cls, f in process_funcs.items(): + if isinstance(value, cls): + return f(value) + if isinstance(value, list): + return [recursive_process(v, process_funcs) for v in value] + if isinstance(value, dict): + return {k: recursive_process(v, process_funcs) for k, v in value.items()} + return value diff --git a/src/promptflow/promptflow/contracts/multimedia.py b/src/promptflow/promptflow/contracts/multimedia.py index 3834cece7a1..a7de51581c0 100644 --- a/src/promptflow/promptflow/contracts/multimedia.py +++ b/src/promptflow/promptflow/contracts/multimedia.py @@ -1,16 +1,6 @@ import base64 import hashlib -import imghdr -import os -import re -import requests -import uuid -from pathlib import Path from typing import Callable -from urllib.parse import urlparse - -from promptflow.contracts._errors import InvalidImageInput -from promptflow.exceptions import ErrorTarget class PFBytes(bytes): @@ -19,8 +9,6 @@ class PFBytes(bytes): and also has some additional methods to help with serialization and deserialization. """ - MIME_PATTERN = re.compile(r"^data:image/(.*);(path|base64|url)$") - def __new__(cls, value: bytes, *args, **kwargs): # Here we must only pass the value to the bytes constructor, # otherwise we will get a type error that the constructor doesn't take such args. @@ -33,80 +21,17 @@ def __init__(self, data: bytes, mime_type: str): self._hash = hashlib.sha1(data).hexdigest()[:8] self._mime_type = mime_type.lower() - @staticmethod - def _get_mime_type_from_path(path: Path): - ext = path.suffix[1:] - return f"image/{ext}" if ext else "image/*" - - @staticmethod - def _get_extension_from_mime_type(mime_type: str): - ext = mime_type.split("/")[-1] - if ext == "*": - return None - return ext - - @staticmethod - def _is_multimedia_dict(multimedia_dict: dict): - if len(multimedia_dict) != 1: - return False - key = list(multimedia_dict.keys())[0] - if re.match(PFBytes.MIME_PATTERN, key): - return True - return False - - @staticmethod - def _get_multimedia_info(key: str): - match = re.match(PFBytes.MIME_PATTERN, key) - if match: - return match.group(1), match.group(2) - return None, None - - @staticmethod - def _is_url(value: str): - try: - result = urlparse(value) - return all([result.scheme, result.netloc]) - except ValueError: - return False - - @staticmethod - def _is_base64(value: str): - base64_regex = re.compile(r"^([A-Za-z0-9+/]{4})*(([A-Za-z0-9+/]{2})*(==|[A-Za-z0-9+/]=)?)?$") - if re.match(base64_regex, value): - return True - return False - - @staticmethod - def default_json_encoder(obj): - if isinstance(obj, PFBytes): - return str(obj) - else: - raise TypeError(f"Object of type {type(obj).__name__} is not JSON serializable") - - def _save_to_file(self, file_name: str, folder_path: Path, relative_path: Path = None): - ext = PFBytes._get_extension_from_mime_type(self._mime_type) - file_name = f"{file_name}.{ext}" if ext else file_name - image_info = { - f"data:{self._mime_type};path": str(relative_path / file_name) if relative_path else file_name - } - path = folder_path / relative_path if relative_path else folder_path - os.makedirs(path, exist_ok=True) - with open(os.path.join(path, file_name), 'wb') as file: - file.write(self) - return image_info + def to_base64(self): + """Returns the base64 representation of the PFBytes.""" - @classmethod - def _get_file_reference_encoder(cls, folder_path: Path, relative_path: Path = None) -> Callable: - def pfbytes_file_reference_encoder(obj): - """Dumps PFBytes to a file and returns its reference.""" - if isinstance(obj, PFBytes): - file_name = str(uuid.uuid4()) - return obj._save_to_file(file_name, folder_path, relative_path) - raise TypeError(f"Object of type {type(obj).__name__} is not JSON serializable") - return pfbytes_file_reference_encoder + return base64.b64encode(self).decode("utf-8") class Image(PFBytes): + """This class is used to represent an image in PromptFlow. It is a subclass of + ~promptflow.contracts.multimedia.PFBytes. + """ + def __init__(self, data: bytes, mime_type: str = "image/*"): return super().__init__(data, mime_type) @@ -116,92 +41,9 @@ def __str__(self): def __repr__(self) -> str: return f"Image({self._hash})" - @staticmethod - def _from_file(f: Path, mime_type: str = None): - if not mime_type: - mime_type = PFBytes._get_mime_type_from_path(f) - with open(f, "rb") as fin: - return Image(fin.read(), mime_type=mime_type) - - @staticmethod - def _from_base64(base64_str: str, mime_type: str = None): - image_bytes = base64.b64decode(base64_str) - if not mime_type: - format = imghdr.what(None, image_bytes) - mime_type = f"image/{format}" if format else "image/*" - return Image(image_bytes, mime_type=mime_type) - - @staticmethod - def _from_url(url: str, mime_type: str = None): - response = requests.get(url) - if response.status_code == 200: - if not mime_type: - format = imghdr.what(None, response.content) - mime_type = f"image/{format}" if format else "image/*" - return Image(response.content, mime_type=mime_type) - else: - raise InvalidImageInput( - message_format=f"Error while fetching image from URL: {url}. " - "Error code: {response.status_code}. Error message: {response.text}.", - target=ErrorTarget.EXECUTOR, - ) - - @staticmethod - def _from_dict(image_dict: dict): - for k, v in image_dict.items(): - format, resource = Image._get_multimedia_info(k) - if resource == "path": - return Image._from_file(v, mime_type=f"image/{format}") - elif resource == "base64": - return Image._from_base64(v, mime_type=f"image/{format}") - elif resource == "url": - return Image._from_url(v, mime_type=f"image/{format}") - else: - raise InvalidImageInput( - message_format=f"Unsupported image resource: {resource}. " - "Supported Resources are [path, base64, url].", - target=ErrorTarget.EXECUTOR, - ) - - @staticmethod - def _create_from_string(value: str, image_dir: Path = None): - if PFBytes._is_base64(value): - return Image._from_base64(value) - elif PFBytes._is_url(value): - return Image._from_url(value) - else: - image_path = Path(value) - if not image_path.is_absolute(): - if image_dir: - image_path = Path.joinpath(image_dir, image_path) - return Image._from_file(image_path) - - @staticmethod - def _create(value: any, image_dir: Path = None): - if isinstance(value, Image): - return value - elif isinstance(value, dict): - if PFBytes._is_multimedia_dict(value): - return Image._from_dict(value) - else: - raise InvalidImageInput( - message_format="Invalid image input format. The image input should be a dictionary like: " - "{data:image/;[path|base64|url]: }.", - target=ErrorTarget.EXECUTOR, - ) - elif isinstance(value, str): - return Image._create_from_string(value, image_dir) - else: - raise InvalidImageInput( - message_format=f"Unsupported image input type: {type(value)}. " - "The image inputs should be a string or a dictionary.", - target=ErrorTarget.EXECUTOR, - ) - - def to_base64(self): - return base64.b64encode(self).decode("utf-8") + def serialize(self, encoder: Callable = None): + """Serialize the image to a dictionary.""" - def _serialize(self, encoder: Callable = None): if encoder is None: return self.__str__() return encoder(self) diff --git a/src/promptflow/promptflow/executor/_tool_resolver.py b/src/promptflow/promptflow/executor/_tool_resolver.py index a2d61264fa0..978589a0e02 100644 --- a/src/promptflow/promptflow/executor/_tool_resolver.py +++ b/src/promptflow/promptflow/executor/_tool_resolver.py @@ -13,8 +13,8 @@ from promptflow._core.connection_manager import ConnectionManager from promptflow._core.tools_manager import BuiltinsManager, ToolLoader, connection_type_to_api_mapping from promptflow._utils.tool_utils import get_inputs_for_prompt_template, get_prompt_param_name_from_func +from promptflow._utils.multimedia_utils import create_image from promptflow.contracts.flow import InputAssignment, InputValueType, Node, ToolSourceType -from promptflow.contracts.multimedia import Image from promptflow.contracts.tool import ConnectionType, Tool, ToolType, ValueType from promptflow.contracts.types import PromptTemplate from promptflow.exceptions import ErrorTarget, PromptflowException, UserErrorException @@ -102,7 +102,7 @@ def _convert_node_literal_input_types(self, node: Node, tool: Tool, module: type else: updated_inputs[k].value = self._convert_to_connection_value(k, v, node, tool_input.type) elif value_type == ValueType.IMAGE: - updated_inputs[k].value = Image._create(v.value, self._working_dir) + updated_inputs[k].value = create_image(v.value, self._working_dir) elif isinstance(value_type, ValueType): try: updated_inputs[k].value = value_type.parse(v.value) @@ -169,9 +169,16 @@ def _validate_duplicated_inputs(self, prompt_tpl_inputs: list, tool_params: list target=ErrorTarget.EXECUTOR, ) + def _load_images_for_prompt_tpl(self, prompt_tpl_inputs_mapping: dict, node_inputs: dict): + for input_name, input in prompt_tpl_inputs_mapping.items(): + if ValueType.IMAGE in input.type and input_name in node_inputs: + if node_inputs[input_name].value_type == InputValueType.LITERAL: + node_inputs[input_name].value = create_image(node_inputs[input_name].value, self._working_dir) + return node_inputs + def _resolve_prompt_node(self, node: Node) -> ResolvedTool: prompt_tpl = self._load_source_content(node) - prompt_tpl_inputs = list(get_inputs_for_prompt_template(prompt_tpl).keys()) + prompt_tpl_inputs_mapping = get_inputs_for_prompt_template(prompt_tpl) from promptflow.tools.template_rendering import render_template_jinja2 params = inspect.signature(render_template_jinja2).parameters @@ -180,7 +187,8 @@ def _resolve_prompt_node(self, node: Node) -> ResolvedTool: f"Invalid inputs {{duplicated_inputs}} in prompt template of node {node.name}. " f"These inputs are duplicated with the reserved parameters of prompt tool." ) - self._validate_duplicated_inputs(prompt_tpl_inputs, param_names, msg) + self._validate_duplicated_inputs(prompt_tpl_inputs_mapping.keys(), param_names, msg) + node.inputs = self._load_images_for_prompt_tpl(prompt_tpl_inputs_mapping, node.inputs) callable = partial(render_template_jinja2, template=prompt_tpl) return ResolvedTool(node=node, definition=None, callable=callable, init_args={}) @@ -213,12 +221,13 @@ def _resolve_llm_node(self, node: Node, convert_input_types=False) -> ResolvedTo updated_node = self._convert_node_literal_input_types(updated_node, tool) prompt_tpl = self._load_source_content(node) - prompt_tpl_inputs = list(get_inputs_for_prompt_template(prompt_tpl).keys()) + prompt_tpl_inputs_mapping = get_inputs_for_prompt_template(prompt_tpl) msg = ( f"Invalid inputs {{duplicated_inputs}} in prompt template of node {node.name}. " f"These inputs are duplicated with the parameters of {node.provider}.{node.api}." ) - self._validate_duplicated_inputs(prompt_tpl_inputs, tool.inputs.keys(), msg) + self._validate_duplicated_inputs(prompt_tpl_inputs_mapping.keys(), tool.inputs.keys(), msg) + updated_node.inputs = self._load_images_for_prompt_tpl(prompt_tpl_inputs_mapping, updated_node.inputs) api_func, init_args = BuiltinsManager._load_package_tool( tool.name, tool.module, tool.class_name, tool.function, updated_node.inputs ) @@ -269,12 +278,13 @@ def _resolve_package_node(self, node: Node, convert_input_types=False) -> Resolv def _integrate_prompt_in_package_node(self, node: Node, resolved_tool: ResolvedTool): prompt_tpl = PromptTemplate(self._load_source_content(node)) - prompt_tpl_inputs = list(get_inputs_for_prompt_template(prompt_tpl).keys()) + prompt_tpl_inputs_mapping = get_inputs_for_prompt_template(prompt_tpl) msg = ( f"Invalid inputs {{duplicated_inputs}} in prompt template of node {node.name}. " f"These inputs are duplicated with the inputs of custom llm tool." ) - self._validate_duplicated_inputs(prompt_tpl_inputs, resolved_tool.definition.inputs.keys(), msg) + self._validate_duplicated_inputs(prompt_tpl_inputs_mapping.keys(), resolved_tool.definition.inputs.keys(), msg) + node.inputs = self._load_images_for_prompt_tpl(prompt_tpl_inputs_mapping, node.inputs) callable = resolved_tool.callable prompt_tpl_param_name = get_prompt_param_name_from_func(callable) if prompt_tpl_param_name is None: @@ -283,5 +293,6 @@ def _integrate_prompt_in_package_node(self, node: Node, resolved_tool: ResolvedT f"function {callable.__name__} is missing a prompt template argument.", target=ErrorTarget.EXECUTOR, ) + resolved_tool.node = node resolved_tool.callable = partial(callable, **{prompt_tpl_param_name: prompt_tpl}) return resolved_tool diff --git a/src/promptflow/promptflow/executor/flow_executor.py b/src/promptflow/promptflow/executor/flow_executor.py index 4a12fa2738c..cffb43e844b 100644 --- a/src/promptflow/promptflow/executor/flow_executor.py +++ b/src/promptflow/promptflow/executor/flow_executor.py @@ -24,9 +24,9 @@ from promptflow._core.tools_manager import ToolsManager from promptflow._utils.context_utils import _change_working_dir from promptflow._utils.logger_utils import logger +from promptflow._utils.multimedia_utils import create_image, create_image_from_dict, is_multimedia_dict from promptflow._utils.utils import transpose from promptflow.contracts.flow import Flow, FlowInputDefinition, InputAssignment, InputValueType, Node -from promptflow.contracts.multimedia import Image, PFBytes from promptflow.contracts.run_info import FlowRunInfo, Status from promptflow.contracts.run_mode import RunMode from promptflow.contracts.tool import ValueType @@ -793,7 +793,7 @@ def _process_images_from_inputs( updated_inputs = dict(line_inputs or {}) for key, value in inputs.items(): if value.type == ValueType.IMAGE: - updated_inputs[key] = Image._create(updated_inputs[key], self._working_dir) + updated_inputs[key] = create_image(updated_inputs[key], self._working_dir) elif value.type == ValueType.LIST: updated_inputs[key] = self._process_images_in_input_list(updated_inputs[key]) return updated_inputs @@ -802,42 +802,13 @@ def _process_images_in_input_list(self, value): if isinstance(value, list): return [self._process_images_in_input_list(item) for item in value] elif isinstance(value, dict): - if PFBytes._is_multimedia_dict(value): - return Image._from_dict(value) + if is_multimedia_dict(value): + return create_image_from_dict(value) else: return {k: self._process_images_in_input_list(v) for k, v in value.items()} else: return value - @staticmethod - def _persist_images_from_output(output: dict, base_dir: Path, sub_dir: Path = None): - if sub_dir.is_absolute(): - folder_path = sub_dir - relative_path = None - else: - folder_path = base_dir - relative_path = sub_dir - for key, value in output.items(): - output[key] = FlowExecutor._persist_images_recursively(value, key, folder_path, relative_path) - return output - - @staticmethod - def _persist_images_recursively(value: Any, prefix: str, folder_path: Path, relative_path: Path = None): - if isinstance(value, Image): - file_name = f"{prefix}_{uuid.uuid4()}" - return value._save_to_file(file_name, folder_path, relative_path) - elif isinstance(value, list): - return [ - FlowExecutor._persist_images_recursively(item, prefix, folder_path, relative_path) for item in value - ] - elif isinstance(value, dict): - return { - k: FlowExecutor._persist_images_recursively(v, prefix, folder_path, relative_path) - for k, v in value.items() - } - else: - return value - def validate_and_apply_inputs_mapping(self, inputs, inputs_mapping) -> List[Dict[str, Any]]: """Validate and apply inputs mapping for all lines in the flow. diff --git a/src/promptflow/promptflow/storage/_run_storage.py b/src/promptflow/promptflow/storage/_run_storage.py index b2789e79c71..8d91d1fa031 100644 --- a/src/promptflow/promptflow/storage/_run_storage.py +++ b/src/promptflow/promptflow/storage/_run_storage.py @@ -5,8 +5,8 @@ from functools import partial from pathlib import Path -from promptflow._utils.dataclass_serializer import serialize -from promptflow.contracts.multimedia import Image, PFBytes +from promptflow._utils.multimedia_utils import get_file_reference_encoder, recursive_process +from promptflow.contracts.multimedia import Image from promptflow.contracts.run_info import FlowRunInfo, RunInfo as NodeRunInfo @@ -35,31 +35,31 @@ def __init__(self, base_dir: Path = None, sub_dir: Path = None): def persist_node_run(self, run_info: NodeRunInfo): if run_info.inputs: - run_info.inputs = self._serialize(run_info.inputs) + run_info.inputs = self._persist_images(run_info.inputs) if run_info.output: - serialized_output = self._serialize(run_info.output) + serialized_output = self._persist_images(run_info.output) run_info.output = serialized_output run_info.result = serialized_output if run_info.api_calls: - run_info.api_calls = self._serialize(run_info.api_calls) + run_info.api_calls = self._persist_images(run_info.api_calls) def persist_flow_run(self, run_info: FlowRunInfo): if run_info.inputs: - run_info.inputs = self._serialize(run_info.inputs) + run_info.inputs = self._persist_images(run_info.inputs) if run_info.output: - serialized_output = self._serialize(run_info.output) + serialized_output = self._persist_images(run_info.output) run_info.output = serialized_output run_info.result = serialized_output if run_info.api_calls: - run_info.api_calls = self._serialize(run_info.api_calls) + run_info.api_calls = self._persist_images(run_info.api_calls) - def _serialize(self, value): + def _persist_images(self, value): if self._base_dir: - pfbytes_file_reference_encoder = PFBytes._get_file_reference_encoder( + pfbytes_file_reference_encoder = get_file_reference_encoder( folder_path=self._base_dir, relative_path=self._sub_dir ) else: pfbytes_file_reference_encoder = None - serialization_funcs = {Image: partial(Image._serialize, **{"encoder": pfbytes_file_reference_encoder})} - return serialize(value, serialization_funcs=serialization_funcs) + serialization_funcs = {Image: partial(Image.serialize, **{"encoder": pfbytes_file_reference_encoder})} + return recursive_process(value, process_funcs=serialization_funcs) diff --git a/src/promptflow/tests/executor/unittests/executor/test_tool_resolver.py b/src/promptflow/tests/executor/unittests/executor/test_tool_resolver.py index 1e65a93d4ac..e453926c480 100644 --- a/src/promptflow/tests/executor/unittests/executor/test_tool_resolver.py +++ b/src/promptflow/tests/executor/unittests/executor/test_tool_resolver.py @@ -1,3 +1,4 @@ +import re import sys from pathlib import Path @@ -20,7 +21,7 @@ ) from promptflow.executor._tool_resolver import ResolvedTool, ToolResolver -from ...utils import FLOW_ROOT +from ...utils import DATA_ROOT, FLOW_ROOT TEST_ROOT = Path(__file__).parent.parent.parent REQUESTS_PATH = TEST_ROOT / "test_configs/executor_api_requests" @@ -289,7 +290,7 @@ def mock_llm_api_func(prompt: PromptTemplate, **kwargs): connections = {"conn_name": {"type": "AzureOpenAIConnection", "value": {"api_key": "mock", "api_base": "mock"}}} tool_resolver = ToolResolver(working_dir=None, connections=connections) tool_resolver._tool_loader = tool_loader - mocker.patch.object(tool_resolver, "_load_source_content", return_value="{{text}}") + mocker.patch.object(tool_resolver, "_load_source_content", return_value="{{text}}![image]({{image}})") node = Node( name="mock", @@ -297,14 +298,17 @@ def mock_llm_api_func(prompt: PromptTemplate, **kwargs): inputs={ "conn": InputAssignment(value="conn_name", value_type=InputValueType.LITERAL), "text": InputAssignment(value="Hello World!", value_type=InputValueType.LITERAL), + "image": InputAssignment(value=str(DATA_ROOT / "test_image.jpg"), value_type=InputValueType.LITERAL), }, connection="conn_name", provider="mock", ) resolved_tool = tool_resolver._resolve_llm_node(node, convert_input_types=True) - assert len(resolved_tool.node.inputs) == 1 + assert len(resolved_tool.node.inputs) == 2 kwargs = {k: v.value for k, v in resolved_tool.node.inputs.items()} - assert resolved_tool.callable(**kwargs) == "Hello World!" + pattern = re.compile(r"^Hello World!!\[image\]\(Image\([a-z0-9]{8}\)\)$") + prompt = resolved_tool.callable(**kwargs) + assert re.match(pattern, prompt) def test_resolve_script_node(self, mocker): def mock_python_func(conn: AzureOpenAIConnection, prompt: PromptTemplate, **kwargs): diff --git a/src/promptflow/tests/executor/utils.py b/src/promptflow/tests/executor/utils.py index 73950d8d10e..210d3830709 100644 --- a/src/promptflow/tests/executor/utils.py +++ b/src/promptflow/tests/executor/utils.py @@ -3,6 +3,7 @@ from typing import Union TEST_ROOT = Path(__file__).parent.parent +DATA_ROOT = TEST_ROOT / "test_configs/datas" FLOW_ROOT = TEST_ROOT / "test_configs/flows" WRONG_FLOW_ROOT = TEST_ROOT / "test_configs/wrong_flows" diff --git a/src/promptflow/tests/test_configs/datas/test_image.jpg b/src/promptflow/tests/test_configs/datas/test_image.jpg new file mode 100644 index 0000000000000000000000000000000000000000..155609310c8035a8fd06efa61d2cecb5d3f5eb15 GIT binary patch literal 140150 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

Ghkzv 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

9*Yk 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 fpJk&e9(IC}qIab*^{ZRf+vx(g{VaE%?S7Iu) z^c@_w?E9j>_uws{=GCqi;uqj(U|%CIjKofxw3I*P1IF%L(h0U;U>(-1#I+*iH;b}} zEEMB98Di1imQ@qrxXL<;2R&xuNQ`e*EggM~b4-q%5?ur%`Klulo2sDZ4j-zmM^5!e zQ1&JF)27A;uGAt=ts{Z-3cbio6mepCl0+}|E)Zh3e0M}($OrZi{s0gRO(W*)9iv50 zp!T2JdXk6gz%n>45&44qld;?o-{lJW^cLGpU0=PQ0+g_bK4^-nYDMa0DqWWKdB(lH zP&TyA1ZdlPfT$;|>-Tz-&0@>1DGiP=b=R(Vz*0-5oJ^oC>F-|iv9yBVBh~p2jEcP1 zU1-;PjzW0*7JX7mk4EbU<-YGuDn@fjhmN_9GjMLPZJPug0NbtqB5_LqG$<6nRficj zgc!FXnph6!rKU*A)=TCc6|P_|Ez{KO(A!+3fv0k^Eq9rioszXW^*JGL(pM}R^_M}1 zwWre#Y3zM(1quw{PPJ2``)$J{1V6Ud3{=ibTYc{EWWtgXJiy1Ir}TfQKbT4b4~rk6 z$9I-Fm|4*eDy9$={;`eOwlJYb1SLKCr?4_*!g{aZ*g(@ zU|orC?ED!d=05pgWX;qN|w3p{L0Tu1Ue2aI3>oJ_-Y4025= zL&-p)Km%id(^D#_hF55TJ*AQi%5|1#fk~1qd@vrY=KJDhfrFj0R76K!$lr!jEB|xW zm2!U+w)_{pWqK%ACFyb;}#>iE! zqY!6EENS!p1?3O1Hi4-w_P>>WnmQ`2CyY-Wa(xl%!k z$|X)IL-IxxvFg+>6__GWxPJJlU^Y)xSNvgCNuDST7h1%3A^AR(qez(--g5N>tIvkGkSeMKTGz*}sQE_U`>AX{7}DsE)Hlle!PBuS}0uWFCrEbC~U5{3=uJ zDPtNgp79LaPdd3wA$>Ght5kmiZjeZJQps$0x*Ziz30-f{yqoGKo^-zzNxJAKHRVu> z8r%Y#MmZ@bRXFVcW*32g0QJx#pCF3)y@6P9Q0wX{AMGV5RZKxa3#8-*$>rAX{0!Ps zxo^KITJtuczI?qg)IbLG$}BIQz(L5WJiqGcoHYp6uNe6MMp+r+f z5%9KW1yl+a%P#=3%eM|E?PE5OfTzL_p$Ts?OTvoFk~-2t9~l~2MOJabzayLW4>XBa z#rApaWe{tnb%3Z#Z2I2{M(H7_muG?sH4Gjla?YA^FoZPV@63GZn0WU*=J@iX5(l~@ z$27J@0fAH=ksUWtSvYoaO!jbH`1CNBPCY!y&28dkU>!l6AezT=1e50??!dCKmvk`` zRm%gNyOI?Nw?)CQml>aB;vgGw?}4h8!yHyRbjIC4m{{6H(xo2ZL^ZxQw=hX?m~$7a zI*wX{2><$ONx#<(__QIYhw$B;0}tZjg}aTqrRLma>TX~V)^=y(6eqI7>)V8r>$?K_ zM;wGA7$X~#zD9+Y%+?$o_}~U*)rpdJ-P)fS;pZBRYQ?7v#eIYibE_57>*gEXzVC!m z-dQ;7s@2?j0&djac7l-OLsEO1SIQ%Wr+eSk zD&Q9gvv@>?E0%;(OOY~rL`N(*f2LmJYq{Z$UB%H9dCuSJRD(oA@uK`S-x|Giaz0I% zgo;BL;3(D`jZM+p4doQ-E?i+#$u*pRoY4KqSWK?hfFnZaOBi=3gEN`hqmdt6A6Fi@ zPIhTF{V-_sWmMaQtl;H;+o%1rok}$+G7HPi1K>CrEO`(pq7j;~QoCM)rK}nV zCHD`bAlgymd=){m4G0=0sS>NV|LjKKVgDJP=U~S@uutHY9nvEQOTX zd-Nhb_871b$WsLNy`!G$3JJi}0Tr2>N_;Hr_dIujP)IH+MaZt6^@DkGe#@dz*630) zemO|}z%%{O*I>((>ycHN$W9(&D!L)kAtV1=nqUi3G2Eo*o3GFkzBR%NQeF+|j&EjC ziO&XJ;tl*UkFZUDXNp(6V@S%t>)C#~pY~R-q~$^pvlr0WU#^0DkVVMM1m`7xHjk^V zoFD-juO7w0PX&4gdpodLl1vc$8-{wfG6^HNdW3e&Vc_e>)&SB?i?-&Myt%#<5+%RK z3IgB*_j9q{+hka#S9fI0>pe3X)WBWL0aQ*kwQjN# zjLRTHhC1{Qv9I{n=O2^aaN}@6@G@Oe{SDEKFV^xX-T>v<{Suz;B~LN)7^w6-rh~Aj zqHF6UHfZ@WeFO=YkC042RmbMLy4&ZjQjP_9-nd+M%SlC(aMr>@(HMdRAT(IH5g>0~ z-gjHSfV~&?3RAZL9E#~`=ms~9Kat!BFHY<|JYdAvSjo=T77qN@O(rh71Ks$$$n3}6 zI*MuIY$MSRT^lOIEMOEBx_lakq(|%Xp(64yfk%%AlI1axue1T6SMkiJH)H-7lKeYJ z+B_`^Wr5vzS0O*A!V>VaPPi~k39}Y}tR6_D6j<`-WoIX%S9Rt$0pR0`bC6G+=x7qcu0796E*Rk2k?{&D4$H<2bqNW zmQuXhHqj)%t=ofk{XEWcU`^u?p+36#$K?%B=;;f*^?OTEsS2US1X3sJ6Ektz(X z)dJ;yD%YVvlBJUeGJ%+V7LY0i01$Uz9H9z#+fu_Va7i@%;;1b&nC6b+3VtV5lwjh` zigCwwPcYR8Uxkgg7Sdv8vu&@AK(*sm=>)L^C#{erw^>cZQ!!s2CQC422 z`Qu9-1>BSgWVzoT>x9Ed<>qnc69H*4xTj8JFV^K8hC{gX`3?K-V3!$Mf>E7uWBfNX zzW|Ux!#O#oUIuI)<3`)T1ei$Md!{-)Il*AUEM@Y0#5zn(!5Y8sBpK3T3c&9mOZT-Q zVcYRNI+3y6|N0I|pPtj9s;^p!uY7qzV1wT+loct(|0@okp{aG*T7d#N(sX(Pv|@%T z$-Q%2IIhLIBCdkqWbu|awm7Rq(<3z`$2((oI`J_MXePKDbsTR4N{aDEhP#$bmw6|_ zpFUDBIl4cVH)PAaahW;TfUIG;fg9H!8qHDip8g%^3H`^>)@skx6QFOBn3fCnkE#+y zcwpE^#;pRbsGHbiK*Pujq6p5`bjcPj``pm*hOZe95NRz&s=nmp!T7DBhBrR}08uN& zNYjZ!0Y*o9_vS1@_SrU4a)71K87P%=4<5G2Vdu7ja+^keh zVOf;imnZ%*gf`7DZ{B)s!&M!Y@Hg~QH}P^_jDr9@#K^Rllq~dGly2r)USyA*(x9`{ zBjtIDXh#~y)vAMJ%^Tl$;u;|x7ewd&rj0*2axjb67_av=7fL}jv%+ANBVBqPXPU`= zidoaJ5FlM?i%^;DRV^io1MK!LV%vE>V1Y_M;*Uj3^yiRpS8pj-pL-d!8{c8H$2C7ki5kCRlilpG$9*c=t&JvKl=O6#WFb{X1w_bDJ14|O|V2SHjADzQTa z$Udsvn#Qe3VGtlBiji~6v;aM|#eDI=vODhH$irVL`I zzGsx6xtD4TR+u{d*sWEs6ics^h_@h;UGq*Pi;EkZXg zypc?j%;MWFf>R)jbaC1+Y^A4e_U2uE1C|2b@GPkaD_K@h{A#DAU3V#=R3?Ec6kl(a&U$-kMi@9yX-qKpM80U0IZl2W($4xkyI(q@6hl_H-30(+2#M^>%ZL?mO3qV z*f+E+_CKvqSct^ehr4epynaj!oK9!=JoG z5D+MX`Tw5;dMvV@>YzxkkW~*65e|I^2EYzLx%M8gSU$pXTkCC`}Nge zCGc}}LXfK%4Ih0|q}f-;-pSD2Oyr`O7Iq?zODVipBNqgMZ_tRnJz)u{C-OmdM zsfgy}cz-l6IrMsuUJLmLFv;kh+s!c9F0{_MJwU~`xy43hR~2m?tW;oMcEF?KrFtKAO@Stei}evXspfQt%m~9j0~f13Rw8Tw`-RZ>|@^wW9c+p+wQ8 z5dNOfp?tsM9nWNmjVlSmcB@>RrTfU1(aT;LupjvoqjlgZ?MS^x4zDryShzBfe%Kr^K;XW(@!fq`>K9;ZY}nlW zgH+*F+mW1xS_G5?e%kcK=|0AbPU?t$4FU+}`wuRXc4S%44); zyT?ORAoNR?^GxvCJ$v97*N57xku9>B zdjF@Nlg6*b{7104eVHQi%x^HCq~&%#$Z@NLfwLN7vo7Ww&3Ni3d4?Iuj?14@!RQ1BTt^+T5LAb&%CGjpmFc2>_tVn2X}pn&o224D{Y#EOF)mqlSdq% zuZ8`SF(Z`{orx6^T!S2MJ2RSaXDBMrGxbGNk&e6f61r_@UTSzA97?`D`nJDu@?4M6 zt^nG_9XZ?Bw*N>`G|BwSmvrmxz*ztCvbO}Ck961!qD&sz^B;@%KAdXPOrTA{%hdCo zd1Gn9MpQi#Q!Bxdy>PBI!~a<=YD`~b0{(0Qe6DH74sn{8 zNFf|n;O`^6RB#_A`UOyb(tdFjT=+Ad>gL;Gqe;ze4(lH2AS*@Dn$qygvmZfZ3uV#x zhZ{3Tdj8js{Ab`2=<}}W!#hnSV-v?EhSXSiU(8R$XTrBHS9{n4G2A?G{_y8Fl1VvD z1#;XFnSBE4A^Np%89i}(5`Xx;)|upG)_9fKB&C%#yR7-BeHZ+}G02Pj`qF;`B&06L zJ3WWy^0EW0Q9Kb%fXP9uVI_4bI~ibs`v4{pVe5(b#@cF;*4fXV;}aRop_r<_9ZnD^ zCioL`C?@!~!wCWag1}hVxKJwegUlvsgs{kOcavvmM)Twp4kps22)hgVv9<20Ov z3CS<(uCpZ2(D%ph1pb@fsY9UsX2hM!{#F7!(*$pHZZ?z;WLOBHc&r;Tugg&g{<)p5 zcynpv=VCD?Wd9Y);Pq^Q{^i}zXmU?)c5)f&6EZCG`M5#tp`byak*KY^-uGhn>xcep zAb7c}h3zY|WZ%q}XotdU=HM@(s5ia+q2AIfL)I}>VO`?gw1iA#NJ?L_T}b|5j06Wu zT2FhT$A-LMpz>^T|8@J%#lf2Txk3QKdPR?aCOD4q`+4r-tDebcqi(zteHEq6@B~Ko zR__+po9_vYTg%k@Lt-0iO+0T;z2)p}mB&txo>1ZmESmrLF0;p2*mfcACiEwA=#l;F z40Wk$&^!T+8m%l<<3WIrv##!y^-O|4ODFqj0!?L(h$hcL0lpWXBZn)*cKFrqe7&mr zj|fBF&Gh}^6&|N-^EsjGE?lEy#5L!`Or={rHpk>h&4_ zxW|`uPeRHnlTP!_H#TKQW1y>K}{|+pmG<;4>!O#m$Kt;Lzy7bBya|U5V9#A@yVJ^APOI5LW%y zkkl zx6>pT`x5O!7++gIV25>KVaqISRoxDe`F)WSRI5bWb8uK28Z81t!_ucR!P|uP)V?v>_ z;b*+m&qn)xc)sU!r<6d?ITOAp#*lV68c4DsE6_mWsF-rcRPb(A#P-HxJD2#x zCbA?73B5Y3Zns;^8=0r9Z^G@Zg{Bf1#+&cF<;IzLYdkbZPJNq`hR3Vg5I=CqU->QP zzIq{KwAZnc;#Qu+>mozqx}wIUCN6;yT_NKwt;ZB+y+ep9=Zz zm0fwO5sYbP%ySjr^XkiUJP4@N+kKNO$SbYwRU6bkjcs53YA;K>Rl<6_`Rvxz zqvH(?>g;0n7uTZxIauAmIVE&3$8IdAs)~H9+Ypgc)^eY&?Q62vgz}N{5ApH)eLYs+ zjVqm;D9YN2FDF!9(O%{L0%VY}ifMO;KP+!9