mirror of
https://github.com/hwchase17/langchain.git
synced 2025-06-21 14:18:52 +00:00
core[patch]: remove prompt img loading (#27807)
This commit is contained in:
parent
33a53970e1
commit
7d481f1010
@ -4,7 +4,6 @@ from langchain_core.prompt_values import ImagePromptValue, ImageURL, PromptValue
|
|||||||
from langchain_core.prompts.base import BasePromptTemplate
|
from langchain_core.prompts.base import BasePromptTemplate
|
||||||
from langchain_core.pydantic_v1 import Field
|
from langchain_core.pydantic_v1 import Field
|
||||||
from langchain_core.runnables import run_in_executor
|
from langchain_core.runnables import run_in_executor
|
||||||
from langchain_core.utils import image as image_utils
|
|
||||||
|
|
||||||
|
|
||||||
class ImagePromptTemplate(BasePromptTemplate[ImageURL]):
|
class ImagePromptTemplate(BasePromptTemplate[ImageURL]):
|
||||||
@ -71,8 +70,8 @@ class ImagePromptTemplate(BasePromptTemplate[ImageURL]):
|
|||||||
A formatted string.
|
A formatted string.
|
||||||
|
|
||||||
Raises:
|
Raises:
|
||||||
ValueError: If the url or path is not provided.
|
ValueError: If the url is not provided.
|
||||||
ValueError: If the path or url is not a string.
|
ValueError: If the url is not a string.
|
||||||
|
|
||||||
Example:
|
Example:
|
||||||
|
|
||||||
@ -87,16 +86,20 @@ class ImagePromptTemplate(BasePromptTemplate[ImageURL]):
|
|||||||
else:
|
else:
|
||||||
formatted[k] = v
|
formatted[k] = v
|
||||||
url = kwargs.get("url") or formatted.get("url")
|
url = kwargs.get("url") or formatted.get("url")
|
||||||
path = kwargs.get("path") or formatted.get("path")
|
if kwargs.get("path") or formatted.get("path"):
|
||||||
|
msg = (
|
||||||
|
"Loading images from 'path' has been removed as of 0.3.15 for security "
|
||||||
|
"reasons. Please specify images by 'url'."
|
||||||
|
)
|
||||||
|
raise ValueError(msg)
|
||||||
detail = kwargs.get("detail") or formatted.get("detail")
|
detail = kwargs.get("detail") or formatted.get("detail")
|
||||||
if not url and not path:
|
|
||||||
raise ValueError("Must provide either url or path.")
|
|
||||||
if not url:
|
if not url:
|
||||||
if not isinstance(path, str):
|
msg = "Must provide url."
|
||||||
raise ValueError("path must be a string.")
|
raise ValueError(msg)
|
||||||
url = image_utils.image_to_data_url(path)
|
elif not isinstance(url, str):
|
||||||
if not isinstance(url, str):
|
msg = "url must be a string."
|
||||||
raise ValueError("url must be a string.")
|
raise ValueError(msg)
|
||||||
|
else:
|
||||||
output: ImageURL = {"url": url}
|
output: ImageURL = {"url": url}
|
||||||
if detail:
|
if detail:
|
||||||
# Don't check literal values here: let the API check them
|
# Don't check literal values here: let the API check them
|
||||||
@ -113,7 +116,6 @@ class ImagePromptTemplate(BasePromptTemplate[ImageURL]):
|
|||||||
A formatted string.
|
A formatted string.
|
||||||
|
|
||||||
Raises:
|
Raises:
|
||||||
ValueError: If the url or path is not provided.
|
|
||||||
ValueError: If the path or url is not a string.
|
ValueError: If the path or url is not a string.
|
||||||
"""
|
"""
|
||||||
return await run_in_executor(None, self.format, **kwargs)
|
return await run_in_executor(None, self.format, **kwargs)
|
||||||
|
@ -1,29 +1,13 @@
|
|||||||
import base64
|
from typing import Any
|
||||||
import mimetypes
|
|
||||||
|
|
||||||
|
|
||||||
def encode_image(image_path: str) -> str:
|
def __getattr__(name: str) -> Any:
|
||||||
"""Get base64 string from image URI.
|
if name in ("encode_image", "image_to_data_url"):
|
||||||
|
msg = (
|
||||||
Args:
|
f"'{name}' has been removed for security reasons.\n\n"
|
||||||
image_path: The path to the image.
|
f"Usage of this utility in environments with user-input paths is a "
|
||||||
|
f"security vulnerability. Out of an abundance of caution, the utility "
|
||||||
Returns:
|
f"has been removed to prevent possible misuse."
|
||||||
The base64 string of the image.
|
)
|
||||||
"""
|
raise ValueError(msg)
|
||||||
with open(image_path, "rb") as image_file:
|
raise AttributeError(name)
|
||||||
return base64.b64encode(image_file.read()).decode("utf-8")
|
|
||||||
|
|
||||||
|
|
||||||
def image_to_data_url(image_path: str) -> str:
|
|
||||||
"""Get data URL from image URI.
|
|
||||||
|
|
||||||
Args:
|
|
||||||
image_path: The path to the image.
|
|
||||||
|
|
||||||
Returns:
|
|
||||||
The data URL of the image.
|
|
||||||
"""
|
|
||||||
encoding = encode_image(image_path)
|
|
||||||
mime_type = mimetypes.guess_type(image_path)[0]
|
|
||||||
return f"data:{mime_type};base64,{encoding}"
|
|
||||||
|
@ -645,7 +645,7 @@ async def test_chat_tmpl_from_messages_multipart_image() -> None:
|
|||||||
|
|
||||||
|
|
||||||
async def test_chat_tmpl_from_messages_multipart_formatting_with_path() -> None:
|
async def test_chat_tmpl_from_messages_multipart_formatting_with_path() -> None:
|
||||||
"""Verify that we can pass `path` for an image as a variable."""
|
"""Verify that we cannot pass `path` for an image as a variable."""
|
||||||
in_mem = "base64mem"
|
in_mem = "base64mem"
|
||||||
in_file_data = "base64file01"
|
in_file_data = "base64file01"
|
||||||
|
|
||||||
@ -672,35 +672,19 @@ async def test_chat_tmpl_from_messages_multipart_formatting_with_path() -> None:
|
|||||||
),
|
),
|
||||||
]
|
]
|
||||||
)
|
)
|
||||||
expected = [
|
with pytest.raises(ValueError):
|
||||||
SystemMessage(content="You are an AI assistant named R2D2."),
|
template.format_messages(
|
||||||
HumanMessage(
|
|
||||||
content=[
|
|
||||||
{"type": "text", "text": "What's in this image?"},
|
|
||||||
{
|
|
||||||
"type": "image_url",
|
|
||||||
"image_url": {"url": f"data:image/jpeg;base64,{in_mem}"},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"type": "image_url",
|
|
||||||
"image_url": {"url": f"data:image/jpeg;base64,{in_file_data}"},
|
|
||||||
},
|
|
||||||
]
|
|
||||||
),
|
|
||||||
]
|
|
||||||
messages = template.format_messages(
|
|
||||||
name="R2D2",
|
name="R2D2",
|
||||||
in_mem=in_mem,
|
in_mem=in_mem,
|
||||||
file_path=temp_file.name,
|
file_path=temp_file.name,
|
||||||
)
|
)
|
||||||
assert messages == expected
|
|
||||||
|
|
||||||
messages = await template.aformat_messages(
|
with pytest.raises(ValueError):
|
||||||
|
await template.aformat_messages(
|
||||||
name="R2D2",
|
name="R2D2",
|
||||||
in_mem=in_mem,
|
in_mem=in_mem,
|
||||||
file_path=temp_file.name,
|
file_path=temp_file.name,
|
||||||
)
|
)
|
||||||
assert messages == expected
|
|
||||||
|
|
||||||
|
|
||||||
def test_messages_placeholder() -> None:
|
def test_messages_placeholder() -> None:
|
||||||
|
Loading…
Reference in New Issue
Block a user