Formatting
This commit is contained in:
parent
fd7da8720f
commit
39434eadc4
58 changed files with 627 additions and 1024 deletions
|
|
@ -20,9 +20,7 @@ API_WORDS = ["api", "key", "token"]
|
|||
|
||||
|
||||
def has_api_terms(word: str):
|
||||
return "api" in word and (
|
||||
"key" in word or ("token" in word and "tokens" not in word)
|
||||
)
|
||||
return "api" in word and ("key" in word or ("token" in word and "tokens" not in word))
|
||||
|
||||
|
||||
def remove_api_keys(flow: dict):
|
||||
|
|
@ -32,11 +30,7 @@ def remove_api_keys(flow: dict):
|
|||
node_data = node.get("data").get("node")
|
||||
template = node_data.get("template")
|
||||
for value in template.values():
|
||||
if (
|
||||
isinstance(value, dict)
|
||||
and has_api_terms(value["name"])
|
||||
and value.get("password")
|
||||
):
|
||||
if isinstance(value, dict) and has_api_terms(value["name"]) and value.get("password"):
|
||||
value["value"] = None
|
||||
|
||||
return flow
|
||||
|
|
@ -57,9 +51,7 @@ def build_input_keys_response(langchain_object, artifacts):
|
|||
input_keys_response["input_keys"][key] = value
|
||||
# If the object has memory, that memory will have a memory_variables attribute
|
||||
# memory variables should be removed from the input keys
|
||||
if hasattr(langchain_object, "memory") and hasattr(
|
||||
langchain_object.memory, "memory_variables"
|
||||
):
|
||||
if hasattr(langchain_object, "memory") and hasattr(langchain_object.memory, "memory_variables"):
|
||||
# Remove memory variables from input keys
|
||||
input_keys_response["input_keys"] = {
|
||||
key: value
|
||||
|
|
@ -69,9 +61,7 @@ def build_input_keys_response(langchain_object, artifacts):
|
|||
# Add memory variables to memory_keys
|
||||
input_keys_response["memory_keys"] = langchain_object.memory.memory_variables
|
||||
|
||||
if hasattr(langchain_object, "prompt") and hasattr(
|
||||
langchain_object.prompt, "template"
|
||||
):
|
||||
if hasattr(langchain_object, "prompt") and hasattr(langchain_object.prompt, "template"):
|
||||
input_keys_response["template"] = langchain_object.prompt.template
|
||||
|
||||
return input_keys_response
|
||||
|
|
@ -106,11 +96,7 @@ def raw_frontend_data_is_valid(raw_frontend_data):
|
|||
def is_valid_data(frontend_node, raw_frontend_data):
|
||||
"""Check if the data is valid for processing."""
|
||||
|
||||
return (
|
||||
frontend_node
|
||||
and "template" in frontend_node
|
||||
and raw_frontend_data_is_valid(raw_frontend_data)
|
||||
)
|
||||
return frontend_node and "template" in frontend_node and raw_frontend_data_is_valid(raw_frontend_data)
|
||||
|
||||
|
||||
def update_template_values(frontend_template, raw_template):
|
||||
|
|
@ -150,9 +136,7 @@ def get_file_path_value(file_path):
|
|||
# If the path is not in the cache dir, return empty string
|
||||
# This is to prevent access to files outside the cache dir
|
||||
# If the path is not a file, return empty string
|
||||
if not path.exists() or not str(path).startswith(
|
||||
user_cache_dir("langflow", "langflow")
|
||||
):
|
||||
if not path.exists() or not str(path).startswith(user_cache_dir("langflow", "langflow")):
|
||||
return ""
|
||||
return file_path
|
||||
|
||||
|
|
@ -183,9 +167,7 @@ async def check_langflow_version(component: StoreComponentCreate):
|
|||
|
||||
langflow_version = get_lf_version_from_pypi()
|
||||
if langflow_version is None:
|
||||
raise HTTPException(
|
||||
status_code=500, detail="Unable to verify the latest version of Langflow"
|
||||
)
|
||||
raise HTTPException(status_code=500, detail="Unable to verify the latest version of Langflow")
|
||||
elif langflow_version != component.last_tested_version:
|
||||
warnings.warn(
|
||||
f"Your version of Langflow ({component.last_tested_version}) is outdated. "
|
||||
|
|
|
|||
|
|
@ -103,9 +103,7 @@ def fix_variable(var, invalid_chars, wrong_variables):
|
|||
# Handle variables starting with a number
|
||||
if var[0].isdigit():
|
||||
invalid_chars.append(var[0])
|
||||
new_var, invalid_chars, wrong_variables = fix_variable(
|
||||
var[1:], invalid_chars, wrong_variables
|
||||
)
|
||||
new_var, invalid_chars, wrong_variables = fix_variable(var[1:], invalid_chars, wrong_variables)
|
||||
|
||||
# Temporarily replace {{ and }} to avoid treating them as invalid
|
||||
new_var = new_var.replace("{{", "ᴛᴇᴍᴘᴏᴘᴇɴ").replace("}}", "ᴛᴇᴍᴘᴄʟᴏsᴇ")
|
||||
|
|
@ -132,9 +130,7 @@ def check_variable(var, invalid_chars, wrong_variables, empty_variables):
|
|||
return wrong_variables, empty_variables
|
||||
|
||||
|
||||
def check_for_errors(
|
||||
input_variables, fixed_variables, wrong_variables, empty_variables
|
||||
):
|
||||
def check_for_errors(input_variables, fixed_variables, wrong_variables, empty_variables):
|
||||
if any(var for var in input_variables if var not in fixed_variables):
|
||||
error_message = (
|
||||
f"Error: Input variables contain invalid characters or formats. \n"
|
||||
|
|
@ -159,17 +155,11 @@ def check_input_variables(input_variables):
|
|||
if is_json_like(var):
|
||||
continue
|
||||
|
||||
new_var, wrong_variables, empty_variables = fix_variable(
|
||||
var, invalid_chars, wrong_variables
|
||||
)
|
||||
wrong_variables, empty_variables = check_variable(
|
||||
var, INVALID_CHARACTERS, wrong_variables, empty_variables
|
||||
)
|
||||
new_var, wrong_variables, empty_variables = fix_variable(var, invalid_chars, wrong_variables)
|
||||
wrong_variables, empty_variables = check_variable(var, INVALID_CHARACTERS, wrong_variables, empty_variables)
|
||||
fixed_variables.append(new_var)
|
||||
variables_to_check.append(var)
|
||||
|
||||
check_for_errors(
|
||||
variables_to_check, fixed_variables, wrong_variables, empty_variables
|
||||
)
|
||||
check_for_errors(variables_to_check, fixed_variables, wrong_variables, empty_variables)
|
||||
|
||||
return fixed_variables
|
||||
|
|
|
|||
|
|
@ -122,9 +122,7 @@ async def build_vertex(
|
|||
else:
|
||||
raise ValueError(f"No result found for vertex {vertex_id}")
|
||||
next_vertices_ids = vertex.successors_ids
|
||||
next_vertices_ids = [
|
||||
v for v in next_vertices_ids if graph.should_run_vertex(v)
|
||||
]
|
||||
next_vertices_ids = [v for v in next_vertices_ids if graph.should_run_vertex(v)]
|
||||
|
||||
result_data_response = ResultDataResponse(**result_dict.model_dump())
|
||||
|
||||
|
|
|
|||
|
|
@ -52,9 +52,7 @@ def get_all(
|
|||
raise HTTPException(status_code=500, detail=str(exc)) from exc
|
||||
|
||||
|
||||
@router.post(
|
||||
"/run/{flow_id}", response_model=RunResponse, response_model_exclude_none=True
|
||||
)
|
||||
@router.post("/run/{flow_id}", response_model=RunResponse, response_model_exclude_none=True)
|
||||
async def run_flow_with_caching(
|
||||
session: Annotated[Session, Depends(get_session)],
|
||||
flow_id: str,
|
||||
|
|
@ -105,9 +103,7 @@ async def run_flow_with_caching(
|
|||
"""
|
||||
try:
|
||||
if inputs is not None:
|
||||
input_values: list[dict[str, Union[str, list[str]]]] = [
|
||||
_input.model_dump() for _input in inputs
|
||||
]
|
||||
input_values: list[dict[str, Union[str, list[str]]]] = [_input.model_dump() for _input in inputs]
|
||||
else:
|
||||
input_values = [{}]
|
||||
|
||||
|
|
@ -115,9 +111,7 @@ async def run_flow_with_caching(
|
|||
outputs = []
|
||||
|
||||
if session_id:
|
||||
session_data = await session_service.load_session(
|
||||
session_id, flow_id=flow_id
|
||||
)
|
||||
session_data = await session_service.load_session(session_id, flow_id=flow_id)
|
||||
graph, artifacts = session_data if session_data else (None, None)
|
||||
task_result: Any = None
|
||||
if not graph:
|
||||
|
|
@ -136,11 +130,7 @@ async def run_flow_with_caching(
|
|||
else:
|
||||
# Get the flow that matches the flow_id and belongs to the user
|
||||
# flow = session.query(Flow).filter(Flow.id == flow_id).filter(Flow.user_id == api_key_user.id).first()
|
||||
flow = session.exec(
|
||||
select(Flow)
|
||||
.where(Flow.id == flow_id)
|
||||
.where(Flow.user_id == api_key_user.id)
|
||||
).first()
|
||||
flow = session.exec(select(Flow).where(Flow.id == flow_id).where(Flow.user_id == api_key_user.id)).first()
|
||||
if flow is None:
|
||||
raise ValueError(f"Flow {flow_id} not found")
|
||||
|
||||
|
|
@ -164,18 +154,12 @@ async def run_flow_with_caching(
|
|||
# StatementError('(builtins.ValueError) badly formed hexadecimal UUID string')
|
||||
if "badly formed hexadecimal UUID string" in str(exc):
|
||||
# This means the Flow ID is not a valid UUID which means it can't find the flow
|
||||
raise HTTPException(
|
||||
status_code=status.HTTP_404_NOT_FOUND, detail=str(exc)
|
||||
) from exc
|
||||
raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail=str(exc)) from exc
|
||||
except ValueError as exc:
|
||||
if f"Flow {flow_id} not found" in str(exc):
|
||||
raise HTTPException(
|
||||
status_code=status.HTTP_404_NOT_FOUND, detail=str(exc)
|
||||
) from exc
|
||||
raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail=str(exc)) from exc
|
||||
else:
|
||||
raise HTTPException(
|
||||
status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, detail=str(exc)
|
||||
) from exc
|
||||
raise HTTPException(status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, detail=str(exc)) from exc
|
||||
|
||||
|
||||
@router.post(
|
||||
|
|
@ -204,8 +188,7 @@ async def process(
|
|||
"""
|
||||
# Raise a depreciation warning
|
||||
logger.warning(
|
||||
"The /process endpoint is deprecated and will be removed in a future version. "
|
||||
"Please use /run instead."
|
||||
"The /process endpoint is deprecated and will be removed in a future version. " "Please use /run instead."
|
||||
)
|
||||
raise HTTPException(
|
||||
status_code=status.HTTP_400_BAD_REQUEST,
|
||||
|
|
@ -277,16 +260,12 @@ async def custom_component(
|
|||
|
||||
built_frontend_node = build_custom_component_template(component, user_id=user.id)
|
||||
|
||||
built_frontend_node = update_frontend_node_with_template_values(
|
||||
built_frontend_node, raw_code.frontend_node
|
||||
)
|
||||
built_frontend_node = update_frontend_node_with_template_values(built_frontend_node, raw_code.frontend_node)
|
||||
return built_frontend_node
|
||||
|
||||
|
||||
@router.post("/custom_component/reload", status_code=HTTPStatus.OK)
|
||||
async def reload_custom_component(
|
||||
path: str, user: User = Depends(get_current_active_user)
|
||||
):
|
||||
async def reload_custom_component(path: str, user: User = Depends(get_current_active_user)):
|
||||
from langflow.interface.custom.utils import build_custom_component_template
|
||||
|
||||
try:
|
||||
|
|
|
|||
|
|
@ -46,9 +46,7 @@ def post_validate_prompt(prompt_request: ValidatePromptRequest):
|
|||
)
|
||||
if not prompt_request.custom_fields:
|
||||
prompt_request.custom_fields = defaultdict(list)
|
||||
old_custom_fields = get_old_custom_fields(
|
||||
prompt_request.custom_fields, prompt_request.name
|
||||
)
|
||||
old_custom_fields = get_old_custom_fields(prompt_request.custom_fields, prompt_request.name)
|
||||
|
||||
add_new_variables_to_template(
|
||||
input_variables,
|
||||
|
|
@ -65,9 +63,7 @@ def post_validate_prompt(prompt_request: ValidatePromptRequest):
|
|||
prompt_request.name,
|
||||
)
|
||||
|
||||
update_input_variables_field(
|
||||
input_variables, prompt_request.frontend_node.template
|
||||
)
|
||||
update_input_variables_field(input_variables, prompt_request.frontend_node.template)
|
||||
|
||||
return PromptValidationResponse(
|
||||
input_variables=input_variables,
|
||||
|
|
|
|||
|
|
@ -45,9 +45,7 @@ class ChatComponent(CustomComponent):
|
|||
return []
|
||||
|
||||
if not session_id or not sender or not sender_name:
|
||||
raise ValueError(
|
||||
"All of session_id, sender, and sender_name must be provided."
|
||||
)
|
||||
raise ValueError("All of session_id, sender, and sender_name must be provided.")
|
||||
if isinstance(message, Record):
|
||||
record = message
|
||||
record.data.update(
|
||||
|
|
|
|||
|
|
@ -67,9 +67,7 @@ def validate_prompt(prompt_template: str, silent_errors: bool = False) -> list[s
|
|||
# Check if there are invalid characters in the input_variables
|
||||
input_variables = check_input_variables(input_variables)
|
||||
if any(var in INVALID_NAMES for var in input_variables):
|
||||
raise ValueError(
|
||||
f"Invalid input variables. None of the variables can be named {', '.join(input_variables)}. "
|
||||
)
|
||||
raise ValueError(f"Invalid input variables. None of the variables can be named {', '.join(input_variables)}. ")
|
||||
|
||||
try:
|
||||
PromptTemplate(template=prompt_template, input_variables=input_variables)
|
||||
|
|
@ -118,9 +116,7 @@ def add_new_variables_to_template(input_variables, custom_fields, template, name
|
|||
raise HTTPException(status_code=500, detail=str(exc)) from exc
|
||||
|
||||
|
||||
def remove_old_variables_from_template(
|
||||
old_custom_fields, input_variables, custom_fields, template, name
|
||||
):
|
||||
def remove_old_variables_from_template(old_custom_fields, input_variables, custom_fields, template, name):
|
||||
for variable in old_custom_fields:
|
||||
if variable not in input_variables:
|
||||
try:
|
||||
|
|
|
|||
|
|
@ -56,9 +56,7 @@ class APIRequest(CustomComponent):
|
|||
data = body if body else None
|
||||
payload = json.dumps(data)
|
||||
try:
|
||||
response = await client.request(
|
||||
method, url, headers=headers, content=payload, timeout=timeout
|
||||
)
|
||||
response = await client.request(method, url, headers=headers, content=payload, timeout=timeout)
|
||||
try:
|
||||
result = response.json()
|
||||
except Exception:
|
||||
|
|
@ -108,9 +106,6 @@ class APIRequest(CustomComponent):
|
|||
bodies = [body.data]
|
||||
async with httpx.AsyncClient() as client:
|
||||
results = await asyncio.gather(
|
||||
*[
|
||||
self.make_request(client, method, u, headers, rec, timeout)
|
||||
for u, rec in zip(urls, bodies)
|
||||
]
|
||||
*[self.make_request(client, method, u, headers, rec, timeout) for u, rec in zip(urls, bodies)]
|
||||
)
|
||||
return results
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ from langflow.memory import delete_messages, get_messages
|
|||
class ClearMessageHistoryComponent(CustomComponent):
|
||||
display_name = "Clear Message History"
|
||||
description = "A component to clear the message history."
|
||||
icon="ClearMessageHistory"
|
||||
icon = "ClearMessageHistory"
|
||||
beta: bool = True
|
||||
|
||||
def build_config(self):
|
||||
|
|
|
|||
|
|
@ -38,18 +38,12 @@ class RunFlowComponent(CustomComponent):
|
|||
return []
|
||||
records = []
|
||||
for message in messages:
|
||||
message_dict = (
|
||||
message if isinstance(message, dict) else message.model_dump()
|
||||
)
|
||||
record = Record(
|
||||
text=message_dict.get("text", ""), data={"result": result_data}
|
||||
)
|
||||
message_dict = message if isinstance(message, dict) else message.model_dump()
|
||||
record = Record(text=message_dict.get("text", ""), data={"result": result_data})
|
||||
records.append(record)
|
||||
return records
|
||||
|
||||
async def build(
|
||||
self, input_value: Text, flow_name: str, tweaks: NestedDict
|
||||
) -> List[Record]:
|
||||
async def build(self, input_value: Text, flow_name: str, tweaks: NestedDict) -> List[Record]:
|
||||
results: List[Optional[ResultData]] = await self.run_flow(
|
||||
input_value=input_value, flow_name=flow_name, tweaks=tweaks
|
||||
)
|
||||
|
|
|
|||
|
|
@ -93,11 +93,6 @@ class TextToRecordComponent(CustomComponent):
|
|||
if mode == "Text":
|
||||
data = kwargs
|
||||
else:
|
||||
data = {
|
||||
k: v
|
||||
for key, d in kwargs.items()
|
||||
for k, v in d.items()
|
||||
if key not in ["mode", "n_keys", "keys"]
|
||||
}
|
||||
data = {k: v for key, d in kwargs.items() for k, v in d.items() if key not in ["mode", "n_keys", "keys"]}
|
||||
record = Record(data=data)
|
||||
return record
|
||||
|
|
|
|||
|
|
@ -9,6 +9,7 @@ class PythonFunctionComponent(CustomComponent):
|
|||
display_name = "Python Function"
|
||||
description = "Define a Python function."
|
||||
icon = "Python"
|
||||
|
||||
def build_config(self):
|
||||
return {
|
||||
"function_code": {
|
||||
|
|
|
|||
|
|
@ -23,9 +23,7 @@ class PromptComponent(CustomComponent):
|
|||
) -> Text:
|
||||
prompt_template = PromptTemplate.from_template(Text(template))
|
||||
kwargs = dict_values_to_string(kwargs)
|
||||
kwargs = {
|
||||
k: "\n".join(v) if isinstance(v, list) else v for k, v in kwargs.items()
|
||||
}
|
||||
kwargs = {k: "\n".join(v) if isinstance(v, list) else v for k, v in kwargs.items()}
|
||||
try:
|
||||
formated_prompt = prompt_template.format(**kwargs)
|
||||
except Exception as exc:
|
||||
|
|
|
|||
|
|
@ -9,6 +9,7 @@ class ChatOutput(ChatComponent):
|
|||
display_name = "Chat Output"
|
||||
description = "Used to send a message to the chat."
|
||||
icon = "ChatOutput"
|
||||
|
||||
def build(
|
||||
self,
|
||||
sender: Optional[str] = "Machine",
|
||||
|
|
|
|||
|
|
@ -11,9 +11,7 @@ from langflow.utils.util import build_loader_repr_from_records, unescape_string
|
|||
class RecursiveCharacterTextSplitterComponent(CustomComponent):
|
||||
display_name: str = "Recursive Character Text Splitter"
|
||||
description: str = "Split text into chunks of a specified length."
|
||||
documentation: str = (
|
||||
"https://docs.langflow.org/components/text-splitters#recursivecharactertextsplitter"
|
||||
)
|
||||
documentation: str = "https://docs.langflow.org/components/text-splitters#recursivecharactertextsplitter"
|
||||
|
||||
def build_config(self):
|
||||
return {
|
||||
|
|
|
|||
|
|
@ -84,8 +84,7 @@ class ChromaComponent(CustomComponent):
|
|||
|
||||
if chroma_server_host is not None:
|
||||
chroma_settings = chromadb.config.Settings(
|
||||
chroma_server_cors_allow_origins=chroma_server_cors_allow_origins
|
||||
or None,
|
||||
chroma_server_cors_allow_origins=chroma_server_cors_allow_origins or None,
|
||||
chroma_server_host=chroma_server_host,
|
||||
chroma_server_port=chroma_server_port or None,
|
||||
chroma_server_grpc_port=chroma_server_grpc_port or None,
|
||||
|
|
@ -106,9 +105,7 @@ class ChromaComponent(CustomComponent):
|
|||
documents.append(_input)
|
||||
if documents is not None and embedding is not None:
|
||||
if len(documents) == 0:
|
||||
raise ValueError(
|
||||
"If documents are provided, there must be at least one document."
|
||||
)
|
||||
raise ValueError("If documents are provided, there must be at least one document.")
|
||||
chroma = Chroma.from_documents(
|
||||
documents=documents, # type: ignore
|
||||
persist_directory=index_directory,
|
||||
|
|
|
|||
|
|
@ -9,9 +9,7 @@ from langflow.schema.schema import Record
|
|||
|
||||
class MongoDBAtlasComponent(CustomComponent):
|
||||
display_name = "MongoDB Atlas"
|
||||
description = (
|
||||
"Construct a `MongoDB Atlas Vector Search` vector store from raw documents."
|
||||
)
|
||||
description = "Construct a `MongoDB Atlas Vector Search` vector store from raw documents."
|
||||
icon = "MongoDB"
|
||||
|
||||
def build_config(self):
|
||||
|
|
@ -39,9 +37,7 @@ class MongoDBAtlasComponent(CustomComponent):
|
|||
try:
|
||||
from pymongo import MongoClient
|
||||
except ImportError:
|
||||
raise ImportError(
|
||||
"Please install pymongo to use MongoDB Atlas Vector Store"
|
||||
)
|
||||
raise ImportError("Please install pymongo to use MongoDB Atlas Vector Store")
|
||||
try:
|
||||
mongo_client: MongoClient = MongoClient(mongodb_atlas_cluster_uri)
|
||||
collection = mongo_client[db_name][collection_name]
|
||||
|
|
|
|||
|
|
@ -66,9 +66,7 @@ class RedisComponent(CustomComponent):
|
|||
documents.append(_input)
|
||||
if not documents:
|
||||
if schema is None:
|
||||
raise ValueError(
|
||||
"If no documents are provided, a schema must be provided."
|
||||
)
|
||||
raise ValueError("If no documents are provided, a schema must be provided.")
|
||||
redis_vs = Redis.from_existing_index(
|
||||
embedding=embedding,
|
||||
index_name=redis_index_name,
|
||||
|
|
|
|||
|
|
@ -35,9 +35,7 @@ class SupabaseComponent(CustomComponent):
|
|||
supabase_url: str = "",
|
||||
table_name: str = "",
|
||||
) -> Union[VectorStore, SupabaseVectorStore, BaseRetriever]:
|
||||
supabase: Client = create_client(
|
||||
supabase_url, supabase_key=supabase_service_key
|
||||
)
|
||||
supabase: Client = create_client(supabase_url, supabase_key=supabase_service_key)
|
||||
documents = []
|
||||
for _input in inputs or []:
|
||||
if isinstance(_input, Record):
|
||||
|
|
|
|||
|
|
@ -15,9 +15,7 @@ from langflow.schema.schema import Record
|
|||
class VectaraComponent(CustomComponent):
|
||||
display_name: str = "Vectara"
|
||||
description: str = "Implementation of Vector Store using Vectara"
|
||||
documentation = (
|
||||
"https://python.langchain.com/docs/integrations/vectorstores/vectara"
|
||||
)
|
||||
documentation = "https://python.langchain.com/docs/integrations/vectorstores/vectara"
|
||||
icon = "Vectara"
|
||||
field_config = {
|
||||
"vectara_customer_id": {
|
||||
|
|
|
|||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue