Tai Truong
fix readme
d202ada
import base64
import json
import os
import re
from io import BytesIO
from pathlib import Path
import yaml
from langchain_core.language_models import BaseLanguageModel
from loguru import logger
from PIL.Image import Image
from langflow.services.chat.config import ChatConfig
from langflow.services.deps import get_settings_service
def load_file_into_dict(file_path: str) -> dict:
file_path_ = Path(file_path)
if not file_path_.exists():
msg = f"File not found: {file_path}"
raise FileNotFoundError(msg)
# Files names are UUID, so we can't find the extension
with file_path_.open(encoding="utf-8") as file:
try:
data = json.load(file)
except json.JSONDecodeError:
file.seek(0)
data = yaml.safe_load(file)
except ValueError as exc:
msg = "Invalid file type. Expected .json or .yaml."
raise ValueError(msg) from exc
return data
def pil_to_base64(image: Image) -> str:
buffered = BytesIO()
image.save(buffered, format="PNG")
img_str = base64.b64encode(buffered.getvalue())
return img_str.decode("utf-8")
def try_setting_streaming_options(langchain_object):
# If the LLM type is OpenAI or ChatOpenAI,
# set streaming to True
# First we need to find the LLM
llm = None
if hasattr(langchain_object, "llm"):
llm = langchain_object.llm
elif hasattr(langchain_object, "llm_chain") and hasattr(langchain_object.llm_chain, "llm"):
llm = langchain_object.llm_chain.llm
if isinstance(llm, BaseLanguageModel):
if hasattr(llm, "streaming") and isinstance(llm.streaming, bool):
llm.streaming = ChatConfig.streaming
elif hasattr(llm, "stream") and isinstance(llm.stream, bool):
llm.stream = ChatConfig.streaming
return langchain_object
def extract_input_variables_from_prompt(prompt: str) -> list[str]:
variables = []
remaining_text = prompt
# Pattern to match single {var} and double {{var}} braces.
pattern = r"\{\{(.*?)\}\}|\{([^{}]+)\}"
while True:
match = re.search(pattern, remaining_text)
if not match:
break
# Extract the variable name from either the single or double brace match.
# If match found in double braces, re-add single braces for JSON strings.
variable_name = "{{" + match.group(1) + "}}" if match.group(1) else match.group(2)
if variable_name is not None:
# This means there is a match
# but there is nothing inside the braces
variables.append(variable_name)
# Remove the matched text from the remaining_text
start, end = match.span()
remaining_text = remaining_text[:start] + remaining_text[end:]
# Proceed to the next match until no more matches are found
# No need to compare remaining "{}" instances because we are re-adding braces for JSON compatibility
return variables
def setup_llm_caching() -> None:
"""Setup LLM caching."""
settings_service = get_settings_service()
try:
set_langchain_cache(settings_service.settings)
except ImportError:
logger.warning(f"Could not import {settings_service.settings.cache_type}. ")
except Exception: # noqa: BLE001
logger.warning("Could not setup LLM caching.")
def set_langchain_cache(settings) -> None:
from langchain.globals import set_llm_cache
from langflow.interface.importing.utils import import_class
if cache_type := os.getenv("LANGFLOW_LANGCHAIN_CACHE"):
try:
cache_class = import_class(f"langchain_community.cache.{cache_type or settings.LANGCHAIN_CACHE}")
logger.debug(f"Setting up LLM caching with {cache_class.__name__}")
set_llm_cache(cache_class())
logger.info(f"LLM caching setup with {cache_class.__name__}")
except ImportError:
logger.warning(f"Could not import {cache_type}. ")
else:
logger.info("No LLM cache set.")