ref: Add ruff rules for bugbear (B) (#3983)
Add ruff rules for bugbear (B)
This commit is contained in:
parent
06eebb5ca8
commit
7e3d470845
86 changed files with 267 additions and 230 deletions
|
|
@ -1,10 +1,10 @@
|
|||
from __future__ import annotations
|
||||
|
||||
import uuid
|
||||
import warnings
|
||||
from typing import TYPE_CHECKING, Any
|
||||
|
||||
from fastapi import HTTPException
|
||||
from loguru import logger
|
||||
from sqlalchemy import delete
|
||||
from sqlmodel import Session
|
||||
|
||||
|
|
@ -101,7 +101,7 @@ async def check_langflow_version(component: StoreComponentCreate):
|
|||
if langflow_version is None:
|
||||
raise HTTPException(status_code=500, detail="Unable to verify the latest version of Langflow")
|
||||
if langflow_version != component.last_tested_version:
|
||||
warnings.warn(
|
||||
logger.warning(
|
||||
f"Your version of Langflow ({component.last_tested_version}) is outdated. "
|
||||
f"Please update to the latest version ({langflow_version}) and try again."
|
||||
)
|
||||
|
|
@ -260,4 +260,4 @@ async def cascade_delete_flow(session: Session, flow: Flow):
|
|||
session.exec(delete(Flow).where(Flow.id == flow.id)) # type: ignore
|
||||
except Exception as e:
|
||||
msg = f"Unable to cascade delete flow: ${flow.id}"
|
||||
raise RuntimeError(msg, e)
|
||||
raise RuntimeError(msg, e) from e
|
||||
|
|
|
|||
|
|
@ -134,7 +134,7 @@ async def retrieve_vertices_order(
|
|||
),
|
||||
)
|
||||
if "stream or streaming set to True" in str(exc):
|
||||
raise HTTPException(status_code=400, detail=str(exc))
|
||||
raise HTTPException(status_code=400, detail=str(exc)) from exc
|
||||
logger.error(f"Error checking build status: {exc}")
|
||||
logger.exception(exc)
|
||||
raise HTTPException(status_code=500, detail=str(exc)) from exc
|
||||
|
|
@ -202,7 +202,7 @@ async def build_flow(
|
|||
),
|
||||
)
|
||||
if "stream or streaming set to True" in str(exc):
|
||||
raise HTTPException(status_code=400, detail=str(exc))
|
||||
raise HTTPException(status_code=400, detail=str(exc)) from exc
|
||||
logger.error(f"Error checking build status: {exc}")
|
||||
logger.exception(exc)
|
||||
raise HTTPException(status_code=500, detail=str(exc)) from exc
|
||||
|
|
|
|||
|
|
@ -176,7 +176,7 @@ async def simple_run_flow_task(
|
|||
async def simplified_run_flow(
|
||||
background_tasks: BackgroundTasks,
|
||||
flow: Annotated[FlowRead | None, Depends(get_flow_by_id_or_endpoint_name)],
|
||||
input_request: SimplifiedAPIRequest = SimplifiedAPIRequest(),
|
||||
input_request: SimplifiedAPIRequest | None = None,
|
||||
stream: bool = False,
|
||||
api_key_user: UserRead = Depends(api_key_security),
|
||||
telemetry_service: TelemetryService = Depends(get_telemetry_service),
|
||||
|
|
@ -244,6 +244,7 @@ async def simplified_run_flow(
|
|||
supporting a wide range of applications by allowing for dynamic input and output configuration along with
|
||||
performance optimizations through session management and caching.
|
||||
"""
|
||||
input_request = input_request if input_request is not None else SimplifiedAPIRequest()
|
||||
if flow is None:
|
||||
raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail="Flow not found")
|
||||
start_time = time.perf_counter()
|
||||
|
|
@ -379,8 +380,8 @@ async def webhook_run_flow(
|
|||
async def experimental_run_flow(
|
||||
session: Annotated[Session, Depends(get_session)],
|
||||
flow_id: UUID,
|
||||
inputs: list[InputValueRequest] | None = [InputValueRequest(components=[], input_value="")],
|
||||
outputs: list[str] | None = [],
|
||||
inputs: list[InputValueRequest] | None = None,
|
||||
outputs: list[str] | None = None,
|
||||
tweaks: Annotated[Tweaks | None, Body(embed=True)] = None, # noqa: F821
|
||||
stream: Annotated[bool, Body(embed=True)] = False, # noqa: F821
|
||||
session_id: Annotated[None | str, Body(embed=True)] = None, # noqa: F821
|
||||
|
|
@ -438,6 +439,8 @@ async def experimental_run_flow(
|
|||
flow_id_str = str(flow_id)
|
||||
if outputs is None:
|
||||
outputs = []
|
||||
if inputs is None:
|
||||
inputs = [InputValueRequest(components=[], input_value="")]
|
||||
|
||||
artifacts = {}
|
||||
if session_id:
|
||||
|
|
|
|||
|
|
@ -64,7 +64,7 @@ async def upload_file(
|
|||
await storage_service.save_file(flow_id=folder, file_name=full_file_name, data=file_content)
|
||||
return UploadFileResponse(flowId=flow_id_str, file_path=f"{folder}/{full_file_name}")
|
||||
except Exception as e:
|
||||
raise HTTPException(status_code=500, detail=str(e))
|
||||
raise HTTPException(status_code=500, detail=str(e)) from e
|
||||
|
||||
|
||||
@router.get("/download/{flow_id}/{file_name}")
|
||||
|
|
@ -89,7 +89,7 @@ async def download_file(file_name: str, flow_id: UUID, storage_service: StorageS
|
|||
}
|
||||
return StreamingResponse(BytesIO(file_content), media_type=content_type, headers=headers)
|
||||
except Exception as e:
|
||||
raise HTTPException(status_code=500, detail=str(e))
|
||||
raise HTTPException(status_code=500, detail=str(e)) from e
|
||||
|
||||
|
||||
@router.get("/images/{flow_id}/{file_name}")
|
||||
|
|
@ -111,7 +111,7 @@ async def download_image(file_name: str, flow_id: UUID, storage_service: Storage
|
|||
file_content = await storage_service.get_file(flow_id=flow_id_str, file_name=file_name)
|
||||
return StreamingResponse(BytesIO(file_content), media_type=content_type)
|
||||
except Exception as e:
|
||||
raise HTTPException(status_code=500, detail=str(e))
|
||||
raise HTTPException(status_code=500, detail=str(e)) from e
|
||||
|
||||
|
||||
@router.get("/profile_pictures/{folder_name}/{file_name}")
|
||||
|
|
@ -130,7 +130,7 @@ async def download_profile_picture(
|
|||
return StreamingResponse(BytesIO(file_content), media_type=content_type)
|
||||
|
||||
except Exception as e:
|
||||
raise HTTPException(status_code=500, detail=str(e))
|
||||
raise HTTPException(status_code=500, detail=str(e)) from e
|
||||
|
||||
|
||||
@router.get("/profile_pictures/list")
|
||||
|
|
@ -151,7 +151,7 @@ async def list_profile_pictures(storage_service: StorageService = Depends(get_st
|
|||
return {"files": files}
|
||||
|
||||
except Exception as e:
|
||||
raise HTTPException(status_code=500, detail=str(e))
|
||||
raise HTTPException(status_code=500, detail=str(e)) from e
|
||||
|
||||
|
||||
@router.get("/list/{flow_id}")
|
||||
|
|
@ -163,7 +163,7 @@ async def list_files(
|
|||
files = await storage_service.list_files(flow_id=flow_id_str)
|
||||
return {"files": files}
|
||||
except Exception as e:
|
||||
raise HTTPException(status_code=500, detail=str(e))
|
||||
raise HTTPException(status_code=500, detail=str(e)) from e
|
||||
|
||||
|
||||
@router.delete("/delete/{flow_id}/{file_name}")
|
||||
|
|
@ -175,4 +175,4 @@ async def delete_file(
|
|||
await storage_service.delete_file(flow_id=flow_id_str, file_name=file_name)
|
||||
return {"message": f"File {file_name} deleted successfully"}
|
||||
except Exception as e:
|
||||
raise HTTPException(status_code=500, detail=str(e))
|
||||
raise HTTPException(status_code=500, detail=str(e)) from e
|
||||
|
|
|
|||
|
|
@ -74,7 +74,7 @@ def create_folder(
|
|||
|
||||
return new_folder
|
||||
except Exception as e:
|
||||
raise HTTPException(status_code=500, detail=str(e))
|
||||
raise HTTPException(status_code=500, detail=str(e)) from e
|
||||
|
||||
|
||||
@router.get("/", response_model=list[FolderRead], status_code=200)
|
||||
|
|
@ -91,7 +91,7 @@ def read_folders(
|
|||
).all()
|
||||
return sorted(folders, key=lambda x: x.name != DEFAULT_FOLDER_NAME)
|
||||
except Exception as e:
|
||||
raise HTTPException(status_code=500, detail=str(e))
|
||||
raise HTTPException(status_code=500, detail=str(e)) from e
|
||||
|
||||
|
||||
@router.get("/{folder_id}", response_model=FolderReadWithFlows, status_code=200)
|
||||
|
|
@ -110,8 +110,8 @@ def read_folder(
|
|||
return folder
|
||||
except Exception as e:
|
||||
if "No result found" in str(e):
|
||||
raise HTTPException(status_code=404, detail="Folder not found")
|
||||
raise HTTPException(status_code=500, detail=str(e))
|
||||
raise HTTPException(status_code=404, detail="Folder not found") from e
|
||||
raise HTTPException(status_code=500, detail=str(e)) from e
|
||||
|
||||
|
||||
@router.patch("/{folder_id}", response_model=FolderRead, status_code=200)
|
||||
|
|
@ -167,7 +167,7 @@ def update_folder(
|
|||
return existing_folder
|
||||
|
||||
except Exception as e:
|
||||
raise HTTPException(status_code=500, detail=str(e))
|
||||
raise HTTPException(status_code=500, detail=str(e)) from e
|
||||
|
||||
|
||||
@router.delete("/{folder_id}", status_code=204)
|
||||
|
|
@ -191,7 +191,7 @@ async def delete_folder(
|
|||
|
||||
return Response(status_code=status.HTTP_204_NO_CONTENT)
|
||||
except Exception as e:
|
||||
raise HTTPException(status_code=500, detail=str(e))
|
||||
raise HTTPException(status_code=500, detail=str(e)) from e
|
||||
|
||||
|
||||
@router.get("/download/{folder_id}", response_model=FlowListReadWithFolderName, status_code=200)
|
||||
|
|
@ -206,8 +206,8 @@ async def download_file(
|
|||
return session.exec(select(Folder).where(Folder.id == folder_id, Folder.user_id == current_user.id)).first()
|
||||
except Exception as e:
|
||||
if "No result found" in str(e):
|
||||
raise HTTPException(status_code=404, detail="Folder not found")
|
||||
raise HTTPException(status_code=500, detail=str(e))
|
||||
raise HTTPException(status_code=404, detail="Folder not found") from e
|
||||
raise HTTPException(status_code=500, detail=str(e)) from e
|
||||
|
||||
|
||||
@router.post("/upload/", response_model=list[FlowRead], status_code=201)
|
||||
|
|
|
|||
|
|
@ -29,7 +29,7 @@ async def get_vertex_builds(
|
|||
vertex_builds = get_vertex_builds_by_flow_id(session, flow_id)
|
||||
return VertexBuildMapModel.from_list_of_dicts(vertex_builds)
|
||||
except Exception as e:
|
||||
raise HTTPException(status_code=500, detail=str(e))
|
||||
raise HTTPException(status_code=500, detail=str(e)) from e
|
||||
|
||||
|
||||
@router.delete("/builds", status_code=204)
|
||||
|
|
@ -40,7 +40,7 @@ async def delete_vertex_builds(
|
|||
try:
|
||||
delete_vertex_builds_by_flow_id(session, flow_id)
|
||||
except Exception as e:
|
||||
raise HTTPException(status_code=500, detail=str(e))
|
||||
raise HTTPException(status_code=500, detail=str(e)) from e
|
||||
|
||||
|
||||
@router.get("/messages", response_model=list[MessageResponse])
|
||||
|
|
@ -68,7 +68,7 @@ async def get_messages(
|
|||
messages = session.exec(stmt)
|
||||
return [MessageResponse.model_validate(d, from_attributes=True) for d in messages]
|
||||
except Exception as e:
|
||||
raise HTTPException(status_code=500, detail=str(e))
|
||||
raise HTTPException(status_code=500, detail=str(e)) from e
|
||||
|
||||
|
||||
@router.delete("/messages", status_code=204)
|
||||
|
|
@ -81,7 +81,7 @@ async def delete_messages(
|
|||
session.exec(delete(MessageTable).where(MessageTable.id.in_(message_ids))) # type: ignore
|
||||
session.commit()
|
||||
except Exception as e:
|
||||
raise HTTPException(status_code=500, detail=str(e))
|
||||
raise HTTPException(status_code=500, detail=str(e)) from e
|
||||
|
||||
|
||||
@router.put("/messages/{message_id}", response_model=MessageRead)
|
||||
|
|
@ -104,7 +104,7 @@ async def update_message(
|
|||
except HTTPException as e:
|
||||
raise e
|
||||
except Exception as e:
|
||||
raise HTTPException(status_code=500, detail=str(e))
|
||||
raise HTTPException(status_code=500, detail=str(e)) from e
|
||||
|
||||
|
||||
@router.patch("/messages/session/{old_session_id}", response_model=list[MessageResponse])
|
||||
|
|
@ -137,7 +137,7 @@ async def update_session_id(
|
|||
except HTTPException as e:
|
||||
raise e
|
||||
except Exception as e:
|
||||
raise HTTPException(status_code=500, detail=str(e))
|
||||
raise HTTPException(status_code=500, detail=str(e)) from e
|
||||
|
||||
|
||||
@router.delete("/messages/session/{session_id}", status_code=204)
|
||||
|
|
@ -154,7 +154,7 @@ async def delete_messages_session(
|
|||
session.commit()
|
||||
return {"message": "Messages deleted successfully"}
|
||||
except Exception as e:
|
||||
raise HTTPException(status_code=500, detail=str(e))
|
||||
raise HTTPException(status_code=500, detail=str(e)) from e
|
||||
|
||||
|
||||
@router.get("/transactions", response_model=list[TransactionReadResponse])
|
||||
|
|
@ -179,4 +179,4 @@ async def get_transactions(
|
|||
for t in transactions
|
||||
]
|
||||
except Exception as e:
|
||||
raise HTTPException(status_code=500, detail=str(e))
|
||||
raise HTTPException(status_code=500, detail=str(e)) from e
|
||||
|
|
|
|||
|
|
@ -67,7 +67,7 @@ async def check_if_store_has_api_key(
|
|||
try:
|
||||
is_valid = await store_service.check_api_key(api_key)
|
||||
except Exception as e:
|
||||
raise HTTPException(status_code=400, detail=str(e))
|
||||
raise HTTPException(status_code=400, detail=str(e)) from e
|
||||
|
||||
return {"has_api_key": api_key is not None, "is_valid": is_valid}
|
||||
|
||||
|
|
@ -82,7 +82,7 @@ async def share_component(
|
|||
await check_langflow_version(component)
|
||||
return await store_service.upload(store_api_key, component)
|
||||
except Exception as exc:
|
||||
raise HTTPException(status_code=400, detail=str(exc))
|
||||
raise HTTPException(status_code=400, detail=str(exc)) from exc
|
||||
|
||||
|
||||
@router.patch("/components/{component_id}", response_model=CreateComponentResponse, status_code=201)
|
||||
|
|
@ -96,7 +96,7 @@ async def update_shared_component(
|
|||
await check_langflow_version(component)
|
||||
return await store_service.update(store_api_key, component_id, component)
|
||||
except Exception as exc:
|
||||
raise HTTPException(status_code=400, detail=str(exc))
|
||||
raise HTTPException(status_code=400, detail=str(exc)) from exc
|
||||
|
||||
|
||||
@router.get("/components/", response_model=ListComponentResponseModel)
|
||||
|
|
@ -164,7 +164,7 @@ async def get_tags(
|
|||
except CustomException as exc:
|
||||
raise HTTPException(status_code=400, detail=str(exc)) from exc
|
||||
except Exception as exc:
|
||||
raise HTTPException(status_code=500, detail=str(exc))
|
||||
raise HTTPException(status_code=500, detail=str(exc)) from exc
|
||||
|
||||
|
||||
@router.get("/users/likes", response_model=list[UsersLikesResponse])
|
||||
|
|
@ -177,7 +177,7 @@ async def get_list_of_components_liked_by_user(
|
|||
except CustomException as exc:
|
||||
raise HTTPException(status_code=400, detail=str(exc)) from exc
|
||||
except Exception as exc:
|
||||
raise HTTPException(status_code=500, detail=str(exc))
|
||||
raise HTTPException(status_code=500, detail=str(exc)) from exc
|
||||
|
||||
|
||||
@router.post("/users/likes/{component_id}", response_model=UsersLikesResponse)
|
||||
|
|
@ -194,4 +194,4 @@ async def like_component(
|
|||
except CustomException as exc:
|
||||
raise HTTPException(status_code=exc.status_code, detail=str(exc)) from exc
|
||||
except Exception as exc:
|
||||
raise HTTPException(status_code=500, detail=str(exc))
|
||||
raise HTTPException(status_code=500, detail=str(exc)) from exc
|
||||
|
|
|
|||
|
|
@ -83,8 +83,8 @@ def update_variable(
|
|||
variable=variable,
|
||||
session=session,
|
||||
)
|
||||
except NoResultFound:
|
||||
raise HTTPException(status_code=404, detail="Variable not found")
|
||||
except NoResultFound as e:
|
||||
raise HTTPException(status_code=404, detail="Variable not found") from e
|
||||
|
||||
except Exception as e:
|
||||
raise HTTPException(status_code=500, detail=str(e)) from e
|
||||
|
|
|
|||
|
|
@ -1,12 +1,12 @@
|
|||
from __future__ import annotations
|
||||
|
||||
import re
|
||||
import warnings
|
||||
from collections.abc import Callable
|
||||
from typing import TYPE_CHECKING
|
||||
|
||||
from langchain_core.tools import BaseTool
|
||||
from langchain_core.tools.structured import StructuredTool
|
||||
from loguru import logger
|
||||
|
||||
from langflow.base.tools.constants import TOOL_OUTPUT_NAME
|
||||
from langflow.io.schema import create_input_schema
|
||||
|
|
@ -27,7 +27,7 @@ def _get_input_type(input: InputTypes):
|
|||
|
||||
def build_description(component: Component, output: Output):
|
||||
if not output.required_inputs:
|
||||
warnings.warn(f"Output {output.name} does not have required inputs defined")
|
||||
logger.warning(f"Output {output.name} does not have required inputs defined")
|
||||
|
||||
if output.required_inputs:
|
||||
args = ", ".join(
|
||||
|
|
|
|||
|
|
@ -1,10 +1,10 @@
|
|||
from __future__ import annotations
|
||||
|
||||
import warnings
|
||||
from typing import Any
|
||||
|
||||
from langchain_core.runnables import RunnableConfig
|
||||
from langchain_core.tools import BaseTool, ToolException
|
||||
from loguru import logger
|
||||
from pydantic.v1 import BaseModel
|
||||
|
||||
from langflow.base.flow_processing.utils import build_data_from_result_data, format_flow_output_data
|
||||
|
|
@ -45,7 +45,7 @@ class FlowTool(BaseTool):
|
|||
"""Use the tool."""
|
||||
args_names = get_arg_names(self.inputs)
|
||||
if len(args_names) == len(args):
|
||||
kwargs = {arg["arg_name"]: arg_value for arg, arg_value in zip(args_names, args)}
|
||||
kwargs = {arg["arg_name"]: arg_value for arg, arg_value in zip(args_names, args, strict=True)}
|
||||
elif len(args_names) != len(args) and len(args) != 0:
|
||||
msg = "Number of arguments does not match the number of inputs. Pass keyword arguments instead."
|
||||
raise ToolException(msg)
|
||||
|
|
@ -77,7 +77,7 @@ class FlowTool(BaseTool):
|
|||
raise ToolException(msg)
|
||||
|
||||
if len(args) == len(args_names):
|
||||
kwargs = {arg_name["arg_name"]: arg_value for arg_name, arg_value in zip(args_names, args)}
|
||||
kwargs = {arg_name["arg_name"]: arg_value for arg_name, arg_value in zip(args_names, args, strict=True)}
|
||||
|
||||
missing_args = [arg["arg_name"] for arg in args_names if arg["arg_name"] not in kwargs]
|
||||
if missing_args:
|
||||
|
|
@ -101,7 +101,7 @@ class FlowTool(BaseTool):
|
|||
try:
|
||||
run_id = self.graph.run_id if self.graph else None
|
||||
except Exception as e:
|
||||
warnings.warn(f"Failed to set run_id: {e}")
|
||||
logger.warning(f"Failed to set run_id: {e}")
|
||||
run_id = None
|
||||
run_outputs = await run_flow(
|
||||
tweaks={key: {"input_value": value} for key, value in tweaks.items()},
|
||||
|
|
|
|||
|
|
@ -26,7 +26,6 @@ class AssistantsRun(Component):
|
|||
if field_value is None:
|
||||
thread = self.client.beta.threads.create()
|
||||
self.thread_id = thread.id
|
||||
field_value
|
||||
build_config["thread_id"] = field_value
|
||||
|
||||
inputs = [
|
||||
|
|
@ -92,4 +91,4 @@ class AssistantsRun(Component):
|
|||
except Exception as e:
|
||||
print(e)
|
||||
msg = f"Error running assistant: {e}"
|
||||
raise Exception(msg)
|
||||
raise Exception(msg) from e
|
||||
|
|
|
|||
|
|
@ -94,7 +94,7 @@ class APIRequestComponent(Component):
|
|||
except Exception as exc:
|
||||
logger.error(f"Error parsing curl: {exc}")
|
||||
msg = f"Error parsing curl: {exc}"
|
||||
raise ValueError(msg)
|
||||
raise ValueError(msg) from exc
|
||||
return build_config
|
||||
|
||||
def update_build_config(self, build_config: dotdict, field_value: Any, field_name: str | None = None):
|
||||
|
|
@ -123,7 +123,7 @@ class APIRequestComponent(Component):
|
|||
logger.error(f"Error decoding JSON data: {e}")
|
||||
body = None
|
||||
msg = f"Error decoding JSON data: {e}"
|
||||
raise ValueError(msg)
|
||||
raise ValueError(msg) from e
|
||||
|
||||
data = body if body else None
|
||||
|
||||
|
|
@ -191,7 +191,10 @@ class APIRequestComponent(Component):
|
|||
|
||||
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, strict=True)
|
||||
]
|
||||
)
|
||||
self.status = results
|
||||
return results
|
||||
|
|
|
|||
|
|
@ -124,9 +124,9 @@ class ChatLiteLLMModelComponent(LCModelComponent):
|
|||
|
||||
litellm.drop_params = True
|
||||
litellm.set_verbose = self.verbose
|
||||
except ImportError:
|
||||
except ImportError as e:
|
||||
msg = "Could not import litellm python package. " "Please install it with `pip install litellm`"
|
||||
raise ChatLiteLLMException(msg)
|
||||
raise ChatLiteLLMException(msg) from e
|
||||
# Remove empty keys
|
||||
if "" in self.kwargs:
|
||||
del self.kwargs[""]
|
||||
|
|
|
|||
|
|
@ -38,10 +38,10 @@ class ExtractKeyFromDataComponent(CustomComponent):
|
|||
for key in keys:
|
||||
try:
|
||||
extracted_keys[key] = getattr(data, key)
|
||||
except AttributeError:
|
||||
except AttributeError as e:
|
||||
if not silent_error:
|
||||
msg = f"The key '{key}' does not exist in the data."
|
||||
raise KeyError(msg)
|
||||
raise KeyError(msg) from e
|
||||
return_data = Data(data=extracted_keys)
|
||||
self.status = return_data
|
||||
return return_data
|
||||
|
|
|
|||
|
|
@ -22,7 +22,7 @@ class ShouldRunNextComponent(CustomComponent):
|
|||
prompt = PromptTemplate.from_template(template)
|
||||
chain = prompt | llm
|
||||
error_message = ""
|
||||
for i in range(retries):
|
||||
for _i in range(retries):
|
||||
result = chain.invoke(
|
||||
{"question": question, "context": context, "error_message": error_message},
|
||||
config={"callbacks": self.get_langchain_callbacks()},
|
||||
|
|
|
|||
|
|
@ -78,7 +78,7 @@ class GoogleGenerativeAIEmbeddingsComponent(Component):
|
|||
title=title,
|
||||
output_dimensionality=1536,
|
||||
)
|
||||
for text, title in zip(batch, titles_batch)
|
||||
for text, title in zip(batch, titles_batch, strict=True)
|
||||
]
|
||||
|
||||
try:
|
||||
|
|
|
|||
|
|
@ -55,12 +55,12 @@ class HuggingFaceInferenceAPIEmbeddingsComponent(LCEmbeddingsModel):
|
|||
|
||||
try:
|
||||
response = requests.get(f"{inference_endpoint}/health", timeout=5)
|
||||
except requests.RequestException:
|
||||
except requests.RequestException as e:
|
||||
msg = (
|
||||
f"Inference endpoint '{inference_endpoint}' is not responding. "
|
||||
"Please ensure the URL is correct and the service is running."
|
||||
)
|
||||
raise ValueError(msg)
|
||||
raise ValueError(msg) from e
|
||||
|
||||
if response.status_code != 200:
|
||||
msg = f"HuggingFace health check failed: {response.status_code}"
|
||||
|
|
|
|||
|
|
@ -52,15 +52,15 @@ class NVIDIAEmbeddingsComponent(LCEmbeddingsModel):
|
|||
build_config["model"]["value"] = ids[0]
|
||||
except Exception as e:
|
||||
msg = f"Error getting model names: {e}"
|
||||
raise ValueError(msg)
|
||||
raise ValueError(msg) from e
|
||||
return build_config
|
||||
|
||||
def build_embeddings(self) -> Embeddings:
|
||||
try:
|
||||
from langchain_nvidia_ai_endpoints import NVIDIAEmbeddings
|
||||
except ImportError:
|
||||
except ImportError as e:
|
||||
msg = "Please install langchain-nvidia-ai-endpoints to use the Nvidia model."
|
||||
raise ImportError(msg)
|
||||
raise ImportError(msg) from e
|
||||
try:
|
||||
output = NVIDIAEmbeddings(
|
||||
model=self.model,
|
||||
|
|
|
|||
|
|
@ -38,9 +38,9 @@ class VertexAIEmbeddingsComponent(LCModelComponent):
|
|||
def build_embeddings(self) -> Embeddings:
|
||||
try:
|
||||
from langchain_google_vertexai import VertexAIEmbeddings
|
||||
except ImportError:
|
||||
except ImportError as e:
|
||||
msg = "Please install the langchain-google-vertexai package to use the VertexAIEmbeddings component."
|
||||
raise ImportError(msg)
|
||||
raise ImportError(msg) from e
|
||||
|
||||
from google.oauth2 import service_account
|
||||
|
||||
|
|
|
|||
|
|
@ -63,7 +63,7 @@ class ParseJSONDataComponent(Component):
|
|||
to_filter_as_dict.append(json.loads(repair_json(f)))
|
||||
except JSONDecodeError as e:
|
||||
msg = f"Invalid JSON: {e}"
|
||||
raise ValueError(msg)
|
||||
raise ValueError(msg) from e
|
||||
|
||||
full_filter_str = json.dumps(to_filter_as_dict)
|
||||
|
||||
|
|
|
|||
|
|
@ -56,11 +56,11 @@ class FirecrawlCrawlApi(CustomComponent):
|
|||
) -> Data:
|
||||
try:
|
||||
from firecrawl.firecrawl import FirecrawlApp # type: ignore
|
||||
except ImportError:
|
||||
except ImportError as e:
|
||||
msg = (
|
||||
"Could not import firecrawl integration package. " "Please install it with `pip install firecrawl-py`."
|
||||
)
|
||||
raise ImportError(msg)
|
||||
raise ImportError(msg) from e
|
||||
crawler_options_dict = crawlerOptions.__dict__["data"]["text"] if crawlerOptions else {}
|
||||
|
||||
page_options_dict = pageOptions.__dict__["data"]["text"] if pageOptions else {}
|
||||
|
|
|
|||
|
|
@ -49,11 +49,11 @@ class FirecrawlScrapeApi(CustomComponent):
|
|||
) -> Data:
|
||||
try:
|
||||
from firecrawl.firecrawl import FirecrawlApp # type: ignore
|
||||
except ImportError:
|
||||
except ImportError as e:
|
||||
msg = (
|
||||
"Could not import firecrawl integration package. " "Please install it with `pip install firecrawl-py`."
|
||||
)
|
||||
raise ImportError(msg)
|
||||
raise ImportError(msg) from e
|
||||
extractor_options_dict = extractorOptions.__dict__["data"]["text"] if extractorOptions else {}
|
||||
|
||||
page_options_dict = pageOptions.__dict__["data"]["text"] if pageOptions else {}
|
||||
|
|
|
|||
|
|
@ -114,7 +114,7 @@ class SpiderTool(Component):
|
|||
raise ValueError(msg)
|
||||
except Exception as e:
|
||||
msg = f"Error: {str(e)}"
|
||||
raise Exception(msg)
|
||||
raise Exception(msg) from e
|
||||
|
||||
records = []
|
||||
|
||||
|
|
|
|||
|
|
@ -52,12 +52,12 @@ class AstraDBChatMemory(LCChatMemoryComponent):
|
|||
def build_message_history(self) -> BaseChatMessageHistory:
|
||||
try:
|
||||
from langchain_astradb.chat_message_histories import AstraDBChatMessageHistory
|
||||
except ImportError:
|
||||
except ImportError as e:
|
||||
msg = (
|
||||
"Could not import langchain Astra DB integration package. "
|
||||
"Please install it with `pip install langchain-astradb`."
|
||||
)
|
||||
raise ImportError(msg)
|
||||
raise ImportError(msg) from e
|
||||
|
||||
return AstraDBChatMessageHistory(
|
||||
session_id=self.session_id,
|
||||
|
|
|
|||
|
|
@ -54,9 +54,9 @@ class CassandraChatMemory(LCChatMemoryComponent):
|
|||
|
||||
try:
|
||||
import cassio
|
||||
except ImportError:
|
||||
except ImportError as e:
|
||||
msg = "Could not import cassio integration package. " "Please install it with `pip install cassio`."
|
||||
raise ImportError(msg)
|
||||
raise ImportError(msg) from e
|
||||
|
||||
from uuid import UUID
|
||||
|
||||
|
|
|
|||
|
|
@ -34,9 +34,9 @@ class ZepChatMemory(LCChatMemoryComponent):
|
|||
from zep_python.langchain import ZepChatMessageHistory
|
||||
|
||||
zep_python.zep_client.API_BASE_PATH = self.api_base_path
|
||||
except ImportError:
|
||||
except ImportError as e:
|
||||
msg = "Could not import zep-python package. " "Please install it with `pip install zep-python`."
|
||||
raise ImportError(msg)
|
||||
raise ImportError(msg) from e
|
||||
|
||||
zep_client = ZepClient(api_url=self.url, api_key=self.api_key)
|
||||
return ZepChatMessageHistory(session_id=self.session_id, zep_client=zep_client)
|
||||
|
|
|
|||
|
|
@ -68,9 +68,9 @@ class AmazonBedrockComponent(LCModelComponent):
|
|||
def build_model(self) -> LanguageModel: # type: ignore[type-var]
|
||||
try:
|
||||
from langchain_aws import ChatBedrock
|
||||
except ImportError:
|
||||
except ImportError as e:
|
||||
msg = "langchain_aws is not installed. Please install it with `pip install langchain_aws`."
|
||||
raise ImportError(msg)
|
||||
raise ImportError(msg) from e
|
||||
if self.aws_access_key:
|
||||
import boto3 # type: ignore
|
||||
|
||||
|
|
|
|||
|
|
@ -62,9 +62,9 @@ class AnthropicModelComponent(LCModelComponent):
|
|||
def build_model(self) -> LanguageModel: # type: ignore[type-var]
|
||||
try:
|
||||
from langchain_anthropic.chat_models import ChatAnthropic
|
||||
except ImportError:
|
||||
except ImportError as e:
|
||||
msg = "langchain_anthropic is not installed. Please install it with `pip install langchain_anthropic`."
|
||||
raise ImportError(msg)
|
||||
raise ImportError(msg) from e
|
||||
model = self.model
|
||||
anthropic_api_key = self.anthropic_api_key
|
||||
max_tokens = self.max_tokens
|
||||
|
|
|
|||
|
|
@ -62,9 +62,9 @@ class GoogleGenerativeAIComponent(LCModelComponent):
|
|||
def build_model(self) -> LanguageModel: # type: ignore[type-var]
|
||||
try:
|
||||
from langchain_google_genai import ChatGoogleGenerativeAI
|
||||
except ImportError:
|
||||
except ImportError as e:
|
||||
msg = "The 'langchain_google_genai' package is required to use the Google Generative AI model."
|
||||
raise ImportError(msg)
|
||||
raise ImportError(msg) from e
|
||||
|
||||
google_api_key = self.google_api_key
|
||||
model = self.model
|
||||
|
|
|
|||
|
|
@ -66,15 +66,15 @@ class NVIDIAModelComponent(LCModelComponent):
|
|||
build_config["model_name"]["value"] = ids[0]
|
||||
except Exception as e:
|
||||
msg = f"Error getting model names: {e}"
|
||||
raise ValueError(msg)
|
||||
raise ValueError(msg) from e
|
||||
return build_config
|
||||
|
||||
def build_model(self) -> LanguageModel: # type: ignore[type-var]
|
||||
try:
|
||||
from langchain_nvidia_ai_endpoints import ChatNVIDIA
|
||||
except ImportError:
|
||||
except ImportError as e:
|
||||
msg = "Please install langchain-nvidia-ai-endpoints to use the NVIDIA model."
|
||||
raise ImportError(msg)
|
||||
raise ImportError(msg) from e
|
||||
nvidia_api_key = self.nvidia_api_key
|
||||
temperature = self.temperature
|
||||
model_name: str = self.model_name
|
||||
|
|
|
|||
|
|
@ -41,9 +41,9 @@ class ChatVertexAIComponent(LCModelComponent):
|
|||
def build_model(self) -> LanguageModel:
|
||||
try:
|
||||
from langchain_google_vertexai import ChatVertexAI
|
||||
except ImportError:
|
||||
except ImportError as e:
|
||||
msg = "Please install the langchain-google-vertexai package to use the VertexAIEmbeddings component."
|
||||
raise ImportError(msg)
|
||||
raise ImportError(msg) from e
|
||||
location = self.location or None
|
||||
if self.credentials:
|
||||
from google.cloud import aiplatform
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
import warnings
|
||||
from typing import Any
|
||||
|
||||
from loguru import logger
|
||||
|
||||
from langflow.base.langchain_utilities.model import LCToolComponent
|
||||
from langflow.base.tools.flow_tool import FlowTool
|
||||
from langflow.field_typing import Tool
|
||||
|
|
@ -85,7 +86,7 @@ class FlowToolComponent(LCToolComponent):
|
|||
try:
|
||||
graph.set_run_id(self.graph.run_id)
|
||||
except Exception as e:
|
||||
warnings.warn(f"Failed to set run_id: {e}")
|
||||
logger.warning(f"Failed to set run_id: {e}")
|
||||
inputs = get_flow_inputs(graph)
|
||||
tool = FlowTool(
|
||||
name=self.name,
|
||||
|
|
|
|||
|
|
@ -47,9 +47,9 @@ class JSONCleaner(Component):
|
|||
def clean_json(self) -> Message:
|
||||
try:
|
||||
from json_repair import repair_json # type: ignore
|
||||
except ImportError:
|
||||
except ImportError as e:
|
||||
msg = "Could not import the json_repair package." "Please install it with `pip install json_repair`."
|
||||
raise ImportError(msg)
|
||||
raise ImportError(msg) from e
|
||||
|
||||
"""Clean the input JSON string based on provided options and return the cleaned JSON string."""
|
||||
json_str = self.json_str
|
||||
|
|
@ -79,7 +79,7 @@ class JSONCleaner(Component):
|
|||
return Message(text=result)
|
||||
except Exception as e:
|
||||
msg = f"Error cleaning JSON string: {str(e)}"
|
||||
raise ValueError(msg)
|
||||
raise ValueError(msg) from e
|
||||
|
||||
def _remove_control_characters(self, s: str) -> str:
|
||||
"""Remove control characters from the string."""
|
||||
|
|
@ -96,4 +96,4 @@ class JSONCleaner(Component):
|
|||
return s
|
||||
except json.JSONDecodeError as e:
|
||||
msg = f"Invalid JSON string: {str(e)}"
|
||||
raise ValueError(msg)
|
||||
raise ValueError(msg) from e
|
||||
|
|
|
|||
|
|
@ -49,7 +49,7 @@ class SQLExecutorComponent(CustomComponent):
|
|||
database = SQLDatabase.from_uri(database_url)
|
||||
except Exception as e:
|
||||
msg = f"An error occurred while connecting to the database: {e}"
|
||||
raise ValueError(msg)
|
||||
raise ValueError(msg) from e
|
||||
try:
|
||||
tool = QuerySQLDataBaseTool(db=database)
|
||||
result = tool.run(query, include_columns=include_columns)
|
||||
|
|
|
|||
|
|
@ -56,15 +56,15 @@ class NvidiaRerankComponent(LCVectorStoreComponent):
|
|||
build_config["model"]["value"] = ids[0]
|
||||
except Exception as e:
|
||||
msg = f"Error getting model names: {e}"
|
||||
raise ValueError(msg)
|
||||
raise ValueError(msg) from e
|
||||
return build_config
|
||||
|
||||
def build_model(self):
|
||||
try:
|
||||
from langchain_nvidia_ai_endpoints import NVIDIARerank
|
||||
except ImportError:
|
||||
except ImportError as e:
|
||||
msg = "Please install langchain-nvidia-ai-endpoints to use the NVIDIA model."
|
||||
raise ImportError(msg)
|
||||
raise ImportError(msg) from e
|
||||
return NVIDIARerank(api_key=self.api_key, model=self.model, base_url=self.base_url)
|
||||
|
||||
def build_base_retriever(self) -> Retriever: # type: ignore[type-var]
|
||||
|
|
|
|||
|
|
@ -38,7 +38,7 @@ class GoogleSearchAPIComponent(LCToolComponent):
|
|||
def _build_wrapper(self):
|
||||
try:
|
||||
from langchain_google_community import GoogleSearchAPIWrapper # type: ignore
|
||||
except ImportError:
|
||||
except ImportError as e:
|
||||
msg = "Please install langchain-google-community to use GoogleSearchAPIWrapper."
|
||||
raise ImportError(msg)
|
||||
raise ImportError(msg) from e
|
||||
return GoogleSearchAPIWrapper(google_api_key=self.google_api_key, google_cse_id=self.google_cse_id, k=self.k)
|
||||
|
|
|
|||
|
|
@ -61,9 +61,9 @@ class PythonREPLToolComponent(LCToolComponent):
|
|||
try:
|
||||
imported_module = importlib.import_module(module)
|
||||
global_dict[imported_module.__name__] = imported_module
|
||||
except ImportError:
|
||||
except ImportError as e:
|
||||
msg = f"Could not import module {module}"
|
||||
raise ImportError(msg)
|
||||
raise ImportError(msg) from e
|
||||
return global_dict
|
||||
|
||||
def build_tool(self) -> Tool:
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
import json
|
||||
from collections.abc import Sequence
|
||||
from typing import Any
|
||||
|
||||
import requests
|
||||
|
|
@ -87,7 +88,7 @@ class SearXNGToolComponent(LCToolComponent):
|
|||
_max_results: int = 10
|
||||
|
||||
@staticmethod
|
||||
def search(query: str, categories: list[str] = []) -> list:
|
||||
def search(query: str, categories: Sequence[str] = ()) -> list:
|
||||
if not SearxSearch._categories and not categories:
|
||||
msg = "No categories provided."
|
||||
raise ValueError(msg)
|
||||
|
|
|
|||
|
|
@ -213,11 +213,13 @@ class AstraVectorStoreComponent(LCVectorStoreComponent):
|
|||
items = list(build_config.items())
|
||||
|
||||
# Find the index of the key to insert after
|
||||
for i, (key, value) in enumerate(items):
|
||||
idx = len(items)
|
||||
for i, (key, _value) in enumerate(items):
|
||||
if key == field_name:
|
||||
idx = i + 1
|
||||
break
|
||||
|
||||
items.insert(i + 1, (new_field_name, new_parameter))
|
||||
items.insert(idx, (new_field_name, new_parameter))
|
||||
|
||||
# Clear the original dictionary and update with the modified items
|
||||
build_config.clear()
|
||||
|
|
@ -366,21 +368,21 @@ class AstraVectorStoreComponent(LCVectorStoreComponent):
|
|||
try:
|
||||
from langchain_astradb import AstraDBVectorStore
|
||||
from langchain_astradb.utils.astradb import SetupMode
|
||||
except ImportError:
|
||||
except ImportError as e:
|
||||
msg = (
|
||||
"Could not import langchain Astra DB integration package. "
|
||||
"Please install it with `pip install langchain-astradb`."
|
||||
)
|
||||
raise ImportError(msg)
|
||||
raise ImportError(msg) from e
|
||||
|
||||
try:
|
||||
if not self.setup_mode:
|
||||
self.setup_mode = self._inputs["setup_mode"].options[0]
|
||||
|
||||
setup_mode_value = SetupMode[self.setup_mode.upper()]
|
||||
except KeyError:
|
||||
except KeyError as e:
|
||||
msg = f"Invalid setup mode: {self.setup_mode}"
|
||||
raise ValueError(msg)
|
||||
raise ValueError(msg) from e
|
||||
|
||||
if self.embedding:
|
||||
embedding_dict = {"embedding": self.embedding}
|
||||
|
|
|
|||
|
|
@ -136,9 +136,9 @@ class CassandraVectorStoreComponent(LCVectorStoreComponent):
|
|||
try:
|
||||
import cassio
|
||||
from langchain_community.utilities.cassandra import SetupMode
|
||||
except ImportError:
|
||||
except ImportError as e:
|
||||
msg = "Could not import cassio integration package. " "Please install it with `pip install cassio`."
|
||||
raise ImportError(msg)
|
||||
raise ImportError(msg) from e
|
||||
|
||||
from uuid import UUID
|
||||
|
||||
|
|
@ -234,7 +234,7 @@ class CassandraVectorStoreComponent(LCVectorStoreComponent):
|
|||
"You should ingest data through Langflow (or LangChain) to query it in Langflow. "
|
||||
"Your collection does not contain a field name 'content'."
|
||||
)
|
||||
raise ValueError(msg)
|
||||
raise ValueError(msg) from e
|
||||
raise e
|
||||
|
||||
logger.debug(f"Retrieved documents: {len(docs)}")
|
||||
|
|
|
|||
|
|
@ -125,9 +125,9 @@ class CassandraGraphVectorStoreComponent(LCVectorStoreComponent):
|
|||
try:
|
||||
import cassio
|
||||
from langchain_community.utilities.cassandra import SetupMode
|
||||
except ImportError:
|
||||
except ImportError as e:
|
||||
msg = "Could not import cassio integration package. " "Please install it with `pip install cassio`."
|
||||
raise ImportError(msg)
|
||||
raise ImportError(msg) from e
|
||||
|
||||
database_ref = self.database_ref
|
||||
|
||||
|
|
|
|||
|
|
@ -106,11 +106,11 @@ class ChromaVectorStoreComponent(LCVectorStoreComponent):
|
|||
try:
|
||||
from chromadb import Client
|
||||
from langchain_chroma import Chroma
|
||||
except ImportError:
|
||||
except ImportError as e:
|
||||
msg = (
|
||||
"Could not import Chroma integration package. " "Please install it with `pip install langchain-chroma`."
|
||||
)
|
||||
raise ImportError(msg)
|
||||
raise ImportError(msg) from e
|
||||
# Chroma settings
|
||||
chroma_settings = None
|
||||
client = None
|
||||
|
|
|
|||
|
|
@ -83,7 +83,7 @@ class ClickhouseVectorStoreComponent(LCVectorStoreComponent):
|
|||
client.command("SELECT 1")
|
||||
except Exception as e:
|
||||
msg = f"Failed to connect to Clickhouse: {e}"
|
||||
raise ValueError(msg)
|
||||
raise ValueError(msg) from e
|
||||
|
||||
documents = []
|
||||
for _input in self.ingest_data or []:
|
||||
|
|
|
|||
|
|
@ -59,7 +59,7 @@ class CouchbaseVectorStoreComponent(LCVectorStoreComponent):
|
|||
cluster.wait_until_ready(timedelta(seconds=5))
|
||||
except Exception as e:
|
||||
msg = f"Failed to connect to Couchbase: {e}"
|
||||
raise ValueError(msg)
|
||||
raise ValueError(msg) from e
|
||||
|
||||
documents = []
|
||||
for _input in self.ingest_data or []:
|
||||
|
|
|
|||
|
|
@ -180,28 +180,28 @@ class HCDVectorStoreComponent(LCVectorStoreComponent):
|
|||
try:
|
||||
from langchain_astradb import AstraDBVectorStore
|
||||
from langchain_astradb.utils.astradb import SetupMode
|
||||
except ImportError:
|
||||
except ImportError as e:
|
||||
msg = (
|
||||
"Could not import langchain Astra DB integration package. "
|
||||
"Please install it with `pip install langchain-astradb`."
|
||||
)
|
||||
raise ImportError(msg)
|
||||
raise ImportError(msg) from e
|
||||
|
||||
try:
|
||||
from astrapy.authentication import UsernamePasswordTokenProvider
|
||||
from astrapy.constants import Environment
|
||||
except ImportError:
|
||||
except ImportError as e:
|
||||
msg = "Could not import astrapy integration package. " "Please install it with `pip install astrapy`."
|
||||
raise ImportError(msg)
|
||||
raise ImportError(msg) from e
|
||||
|
||||
try:
|
||||
if not self.setup_mode:
|
||||
self.setup_mode = self._inputs["setup_mode"].options[0]
|
||||
|
||||
setup_mode_value = SetupMode[self.setup_mode.upper()]
|
||||
except KeyError:
|
||||
except KeyError as e:
|
||||
msg = f"Invalid setup mode: {self.setup_mode}"
|
||||
raise ValueError(msg)
|
||||
raise ValueError(msg) from e
|
||||
|
||||
if not isinstance(self.embedding, dict):
|
||||
embedding_dict = {"embedding": self.embedding}
|
||||
|
|
|
|||
|
|
@ -73,11 +73,11 @@ class MilvusVectorStoreComponent(LCVectorStoreComponent):
|
|||
def build_vector_store(self):
|
||||
try:
|
||||
from langchain_milvus.vectorstores import Milvus as LangchainMilvus
|
||||
except ImportError:
|
||||
except ImportError as e:
|
||||
msg = (
|
||||
"Could not import Milvus integration package. " "Please install it with `pip install langchain-milvus`."
|
||||
)
|
||||
raise ImportError(msg)
|
||||
raise ImportError(msg) from e
|
||||
self.connection_args.update(uri=self.uri, token=self.password)
|
||||
milvus_store = LangchainMilvus(
|
||||
embedding_function=self.embedding,
|
||||
|
|
|
|||
|
|
@ -38,16 +38,16 @@ class MongoVectorStoreComponent(LCVectorStoreComponent):
|
|||
def build_vector_store(self) -> MongoDBAtlasVectorSearch:
|
||||
try:
|
||||
from pymongo import MongoClient
|
||||
except ImportError:
|
||||
except ImportError as e:
|
||||
msg = "Please install pymongo to use MongoDB Atlas Vector Store"
|
||||
raise ImportError(msg)
|
||||
raise ImportError(msg) from e
|
||||
|
||||
try:
|
||||
mongo_client: MongoClient = MongoClient(self.mongodb_atlas_cluster_uri)
|
||||
collection = mongo_client[self.db_name][self.collection_name]
|
||||
except Exception as e:
|
||||
msg = f"Failed to connect to MongoDB Atlas: {e}"
|
||||
raise ValueError(msg)
|
||||
raise ValueError(msg) from e
|
||||
|
||||
documents = []
|
||||
for _input in self.ingest_data or []:
|
||||
|
|
|
|||
|
|
@ -58,9 +58,9 @@ class VectaraVectorStoreComponent(LCVectorStoreComponent):
|
|||
"""
|
||||
try:
|
||||
from langchain_community.vectorstores import Vectara
|
||||
except ImportError:
|
||||
except ImportError as e:
|
||||
msg = "Could not import Vectara. Please install it with `pip install langchain-community`."
|
||||
raise ImportError(msg)
|
||||
raise ImportError(msg) from e
|
||||
|
||||
vectara = Vectara(
|
||||
vectara_customer_id=self.vectara_customer_id,
|
||||
|
|
|
|||
|
|
@ -136,9 +136,9 @@ class VectaraRagComponent(Component):
|
|||
try:
|
||||
from langchain_community.vectorstores import Vectara
|
||||
from langchain_community.vectorstores.vectara import RerankConfig, SummaryConfig, VectaraQueryConfig
|
||||
except ImportError:
|
||||
except ImportError as e:
|
||||
msg = "Could not import Vectara. Please install it with `pip install langchain-community`."
|
||||
raise ImportError(msg)
|
||||
raise ImportError(msg) from e
|
||||
|
||||
vectara = Vectara(self.vectara_customer_id, self.vectara_corpus_id, self.vectara_api_key)
|
||||
rerank_config = RerankConfig(self.reranker, self.reranker_k, self.diversity_bias)
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
import warnings
|
||||
from collections.abc import Callable
|
||||
|
||||
import emoji
|
||||
from loguru import logger
|
||||
|
||||
|
||||
def validate_icon(value: str, *args, **kwargs):
|
||||
|
|
@ -18,7 +18,7 @@ def validate_icon(value: str, *args, **kwargs):
|
|||
|
||||
emoji_value = emoji.emojize(value, variant="emoji_type")
|
||||
if value == emoji_value:
|
||||
warnings.warn(f"Invalid emoji. {value} is not a valid emoji.")
|
||||
logger.warning(f"Invalid emoji. {value} is not a valid emoji.")
|
||||
return value
|
||||
return emoji_value
|
||||
|
||||
|
|
|
|||
|
|
@ -217,7 +217,7 @@ class CodeParser:
|
|||
|
||||
defaults = missing_defaults + default_values
|
||||
|
||||
return [self.parse_arg(arg, default) for arg, default in zip(node.args.args, defaults)]
|
||||
return [self.parse_arg(arg, default) for arg, default in zip(node.args.args, defaults, strict=True)]
|
||||
|
||||
def parse_varargs(self, node: ast.FunctionDef) -> list[dict[str, Any]]:
|
||||
"""
|
||||
|
|
@ -238,7 +238,7 @@ class CodeParser:
|
|||
ast.unparse(default) if default else None for default in node.args.kw_defaults
|
||||
]
|
||||
|
||||
return [self.parse_arg(arg, default) for arg, default in zip(node.args.kwonlyargs, kw_defaults)]
|
||||
return [self.parse_arg(arg, default) for arg, default in zip(node.args.kwonlyargs, kw_defaults, strict=True)]
|
||||
|
||||
def parse_kwargs(self, node: ast.FunctionDef) -> list[dict[str, Any]]:
|
||||
"""
|
||||
|
|
|
|||
|
|
@ -1,10 +1,10 @@
|
|||
import operator
|
||||
import warnings
|
||||
from typing import Any, ClassVar
|
||||
from uuid import UUID
|
||||
|
||||
from cachetools import TTLCache, cachedmethod
|
||||
from fastapi import HTTPException
|
||||
from loguru import logger
|
||||
|
||||
from langflow.custom.attributes import ATTR_FUNC_MAPPING
|
||||
from langflow.custom.code_parser import CodeParser
|
||||
|
|
@ -35,13 +35,13 @@ class BaseComponent:
|
|||
self.cache = TTLCache(maxsize=1024, ttl=60)
|
||||
for key, value in data.items():
|
||||
if key == "user_id":
|
||||
setattr(self, "_user_id", value)
|
||||
self._user_id = value
|
||||
else:
|
||||
setattr(self, key, value)
|
||||
|
||||
def __setattr__(self, key, value):
|
||||
if key == "_user_id" and hasattr(self, "_user_id") and getattr(self, "_user_id") is not None:
|
||||
warnings.warn("user_id is immutable and cannot be changed.")
|
||||
if key == "_user_id" and self._user_id is not None:
|
||||
logger.warning("user_id is immutable and cannot be changed.")
|
||||
super().__setattr__(key, value)
|
||||
|
||||
@cachedmethod(cache=operator.attrgetter("cache"))
|
||||
|
|
|
|||
|
|
@ -113,7 +113,7 @@ class Component(CustomComponent):
|
|||
def _reset_all_output_values(self):
|
||||
if isinstance(self._outputs_map, dict):
|
||||
for output in self._outputs_map.values():
|
||||
setattr(output, "value", UNDEFINED)
|
||||
output.value = UNDEFINED
|
||||
|
||||
def _build_state_model(self):
|
||||
if self._state_model:
|
||||
|
|
@ -164,9 +164,9 @@ class Component(CustomComponent):
|
|||
raise ValueError(msg)
|
||||
class_code = inspect.getsource(module)
|
||||
self._code = class_code
|
||||
except OSError:
|
||||
except OSError as e:
|
||||
msg = f"Could not find source code for {self.__class__.__name__}"
|
||||
raise ValueError(msg)
|
||||
raise ValueError(msg) from e
|
||||
|
||||
def set(self, **kwargs):
|
||||
"""
|
||||
|
|
@ -441,9 +441,9 @@ class Component(CustomComponent):
|
|||
if callable(value) and self._inherits_from_component(value):
|
||||
try:
|
||||
self._method_is_valid_output(value)
|
||||
except ValueError:
|
||||
except ValueError as e:
|
||||
msg = f"Method {value.__name__} is not a valid output of {value.__self__.__class__.__name__}"
|
||||
raise ValueError(msg)
|
||||
raise ValueError(msg) from e
|
||||
self._connect_to_component(key, value, _input)
|
||||
else:
|
||||
self._set_parameter_or_attribute(key, value)
|
||||
|
|
@ -569,15 +569,15 @@ class Component(CustomComponent):
|
|||
for name, value in self._parameters.items():
|
||||
try:
|
||||
template[name]["value"] = value
|
||||
except KeyError:
|
||||
except KeyError as e:
|
||||
close_match = find_closest_match(name, list(template.keys()))
|
||||
if close_match:
|
||||
msg = (
|
||||
f"Parameter '{name}' not found in {self.__class__.__name__}. " f"Did you mean '{close_match}'?"
|
||||
)
|
||||
raise ValueError(msg)
|
||||
raise ValueError(msg) from e
|
||||
msg = f"Parameter {name} not found in {self.__class__.__name__}. "
|
||||
raise ValueError(msg)
|
||||
raise ValueError(msg) from e
|
||||
|
||||
def _get_method_return_type(self, method_name: str) -> list[str]:
|
||||
method = getattr(self, method_name)
|
||||
|
|
@ -594,7 +594,7 @@ class Component(CustomComponent):
|
|||
#! works and then update this later
|
||||
field_config = self.get_template_config(self)
|
||||
frontend_node = ComponentFrontendNode.from_inputs(**field_config)
|
||||
for key, value in self._inputs.items():
|
||||
for key, _value in self._inputs.items():
|
||||
frontend_node.set_field_load_from_db_in_template(key, False)
|
||||
self._map_parameters_on_frontend_node(frontend_node)
|
||||
|
||||
|
|
|
|||
|
|
@ -118,7 +118,7 @@ class CustomComponent(BaseComponent):
|
|||
self._vertex.graph.update_state(name=name, record=value, caller=self._vertex.id)
|
||||
except Exception as e:
|
||||
msg = f"Error updating state: {e}"
|
||||
raise ValueError(msg)
|
||||
raise ValueError(msg) from e
|
||||
|
||||
def stop(self, output_name: str | None = None):
|
||||
if not output_name and self._vertex and len(self._vertex.outputs) == 1:
|
||||
|
|
@ -133,7 +133,7 @@ class CustomComponent(BaseComponent):
|
|||
self.graph.mark_branch(vertex_id=self._vertex.id, output_name=output_name, state="INACTIVE")
|
||||
except Exception as e:
|
||||
msg = f"Error stopping {self.display_name}: {e}"
|
||||
raise ValueError(msg)
|
||||
raise ValueError(msg) from e
|
||||
|
||||
def append_state(self, name: str, value: Any):
|
||||
if not self._vertex:
|
||||
|
|
@ -143,7 +143,7 @@ class CustomComponent(BaseComponent):
|
|||
self._vertex.graph.append_state(name=name, record=value, caller=self._vertex.id)
|
||||
except Exception as e:
|
||||
msg = f"Error appending state: {e}"
|
||||
raise ValueError(msg)
|
||||
raise ValueError(msg) from e
|
||||
|
||||
def get_state(self, name: str):
|
||||
if not self._vertex:
|
||||
|
|
@ -153,7 +153,7 @@ class CustomComponent(BaseComponent):
|
|||
return self._vertex.graph.get_state(name=name)
|
||||
except Exception as e:
|
||||
msg = f"Error getting state: {e}"
|
||||
raise ValueError(msg)
|
||||
raise ValueError(msg) from e
|
||||
|
||||
@staticmethod
|
||||
def resolve_path(path: str) -> str:
|
||||
|
|
@ -278,9 +278,9 @@ class CustomComponent(BaseComponent):
|
|||
else:
|
||||
try:
|
||||
data_dict[key] = model_dump[key]
|
||||
except KeyError:
|
||||
except KeyError as e:
|
||||
msg = f"Key {key} not found in {item}"
|
||||
raise ValueError(msg)
|
||||
raise ValueError(msg) from e
|
||||
|
||||
elif isinstance(item, str):
|
||||
data_dict = {"text": item}
|
||||
|
|
@ -512,7 +512,7 @@ class CustomComponent(BaseComponent):
|
|||
return list_flows(user_id=str(self._user_id))
|
||||
except Exception as e:
|
||||
msg = f"Error listing flows: {e}"
|
||||
raise ValueError(msg)
|
||||
raise ValueError(msg) from e
|
||||
|
||||
def build(self, *args: Any, **kwargs: Any) -> Any:
|
||||
"""
|
||||
|
|
|
|||
|
|
@ -324,7 +324,7 @@ class DirectoryReader:
|
|||
tasks = [self.process_file_async(file_path) for file_path in file_paths]
|
||||
results = await asyncio.gather(*tasks)
|
||||
|
||||
for file_path, (validation_result, result_content) in zip(file_paths, results):
|
||||
for file_path, (validation_result, result_content) in zip(file_paths, results, strict=True):
|
||||
menu_name = os.path.basename(os.path.dirname(file_path))
|
||||
filename = os.path.basename(file_path)
|
||||
|
||||
|
|
|
|||
|
|
@ -2,7 +2,6 @@ import ast
|
|||
import contextlib
|
||||
import re
|
||||
import traceback
|
||||
import warnings
|
||||
from typing import Any
|
||||
from uuid import UUID
|
||||
|
||||
|
|
@ -177,7 +176,7 @@ def add_new_custom_field(
|
|||
field_config["is_list"] = is_list or field_config.get("list", False) or field_contains_list
|
||||
|
||||
if "name" in field_config:
|
||||
warnings.warn("The 'name' key in field_config is used to build the object and can't be changed.")
|
||||
logger.warning("The 'name' key in field_config is used to build the object and can't be changed.")
|
||||
required = field_config.pop("required", field_required)
|
||||
placeholder = field_config.pop("placeholder", "")
|
||||
|
||||
|
|
|
|||
|
|
@ -5,7 +5,6 @@ import contextlib
|
|||
import copy
|
||||
import json
|
||||
import uuid
|
||||
import warnings
|
||||
from collections import defaultdict, deque
|
||||
from collections.abc import Generator, Iterable
|
||||
from datetime import datetime, timezone
|
||||
|
|
@ -263,11 +262,11 @@ class Graph:
|
|||
input_field = target_vertex.get_input(input_name)
|
||||
input_types = input_field.input_types
|
||||
input_field_type = str(input_field.field_type)
|
||||
except ValueError:
|
||||
except ValueError as e:
|
||||
input_field = target_vertex.data.get("node", {}).get("template", {}).get(input_name)
|
||||
if not input_field:
|
||||
msg = f"Input field {input_name} not found in target vertex {target_id}"
|
||||
raise ValueError(msg)
|
||||
raise ValueError(msg) from e
|
||||
input_types = input_field.get("input_types", [])
|
||||
input_field_type = input_field.get("type", "")
|
||||
|
||||
|
|
@ -793,7 +792,7 @@ class Graph:
|
|||
types = []
|
||||
for _ in range(len(inputs) - len(types)):
|
||||
types.append("chat") # default to chat
|
||||
for run_inputs, components, input_type in zip(inputs, inputs_components, types):
|
||||
for run_inputs, components, input_type in zip(inputs, inputs_components, types, strict=True):
|
||||
run_outputs = await self._run(
|
||||
inputs=run_inputs,
|
||||
input_components=components,
|
||||
|
|
@ -1199,9 +1198,9 @@ class Graph:
|
|||
"""Returns a vertex by id."""
|
||||
try:
|
||||
return self.vertex_map[vertex_id]
|
||||
except KeyError:
|
||||
except KeyError as e:
|
||||
msg = f"Vertex {vertex_id} not found"
|
||||
raise ValueError(msg)
|
||||
raise ValueError(msg) from e
|
||||
|
||||
def get_root_of_group_node(self, vertex_id: str) -> Vertex:
|
||||
"""Returns the root of a group node."""
|
||||
|
|
@ -1646,7 +1645,7 @@ class Graph:
|
|||
new_edge = self.build_edge(edge)
|
||||
edges.add(new_edge)
|
||||
if self.vertices and not edges:
|
||||
warnings.warn("Graph has vertices but no edges")
|
||||
logger.warning("Graph has vertices but no edges")
|
||||
return list(cast(Iterable[CycleEdge], edges))
|
||||
|
||||
def build_edge(self, edge: EdgeData) -> CycleEdge | Edge:
|
||||
|
|
|
|||
|
|
@ -62,6 +62,6 @@ def create_state_model_from_graph(graph: BaseModel) -> type[BaseModel]:
|
|||
]
|
||||
fields = {
|
||||
camel_to_snake(vertex.id): state_model_getter
|
||||
for vertex, state_model_getter in zip(graph.vertices, state_model_getters)
|
||||
for vertex, state_model_getter in zip(graph.vertices, state_model_getters, strict=False)
|
||||
}
|
||||
return create_state_model(model_name="GraphStateModel", validate=False, **fields)
|
||||
|
|
|
|||
|
|
@ -281,14 +281,14 @@ def sort_up_to_vertex(
|
|||
"""Cuts the graph up to a given vertex and sorts the resulting subgraph."""
|
||||
try:
|
||||
stop_or_start_vertex = graph[vertex_id]
|
||||
except KeyError:
|
||||
except KeyError as e:
|
||||
if parent_node_map is None:
|
||||
msg = "Parent node map is required to find the root of a group node"
|
||||
raise ValueError(msg)
|
||||
raise ValueError(msg) from e
|
||||
vertex_id = get_root_of_group_node(graph=graph, vertex_id=vertex_id, parent_node_map=parent_node_map)
|
||||
if vertex_id not in graph:
|
||||
msg = f"Vertex {vertex_id} not found into graph"
|
||||
raise ValueError(msg)
|
||||
raise ValueError(msg) from e
|
||||
stop_or_start_vertex = graph[vertex_id]
|
||||
|
||||
visited, excluded = set(), set()
|
||||
|
|
|
|||
|
|
@ -39,7 +39,7 @@ def list_flows(*, user_id: str | None = None) -> list[Data]:
|
|||
return [flow.to_data() for flow in flows]
|
||||
except Exception as e:
|
||||
msg = f"Error listing flows: {e}"
|
||||
raise ValueError(msg)
|
||||
raise ValueError(msg) from e
|
||||
|
||||
|
||||
async def load_flow(
|
||||
|
|
@ -161,7 +161,7 @@ def generate_function_for_flow(
|
|||
# Map original argument names to their corresponding Pythonic variable names in the function
|
||||
arg_mappings = ", ".join(
|
||||
f'"{original_name}": {name}'
|
||||
for original_name, name in zip(original_arg_names, [arg.split(":")[0] for arg in args])
|
||||
for original_name, name in zip(original_arg_names, [arg.split(":")[0] for arg in args], strict=True)
|
||||
)
|
||||
|
||||
func_body = f"""
|
||||
|
|
|
|||
|
|
@ -78,7 +78,7 @@ def update_projects_components_with_latest_component_versions(project_data, all_
|
|||
}
|
||||
)
|
||||
node_data["template"][key]["value"] = value["value"]
|
||||
for key, value in node_data["template"].items():
|
||||
for key in node_data["template"]:
|
||||
if key not in latest_template:
|
||||
node_data["template"][key]["input_types"] = DEFAULT_PROMPT_INTUT_TYPES
|
||||
node_changes_log[node_data["display_name"]].append(
|
||||
|
|
@ -359,7 +359,7 @@ def load_starter_projects(retries=3, delay=1) -> list[tuple[Path, dict]]:
|
|||
attempt += 1
|
||||
if attempt >= retries:
|
||||
msg = f"Error loading starter project {file}: {e}"
|
||||
raise ValueError(msg)
|
||||
raise ValueError(msg) from e
|
||||
time.sleep(delay) # Wait before retrying
|
||||
return starter_projects
|
||||
|
||||
|
|
|
|||
|
|
@ -108,10 +108,14 @@ class StrInput(BaseInputMixin, ListableInputMixin, DatabaseLoadMixin, MetadataTr
|
|||
if _info.data.get("input_types") and v.__class__.__name__ not in _info.data.get("input_types"):
|
||||
warnings.warn(
|
||||
f"Invalid value type {type(v)} for input {_info.data.get('name')}. "
|
||||
f"Expected types: {_info.data.get('input_types')}"
|
||||
f"Expected types: {_info.data.get('input_types')}",
|
||||
stacklevel=4,
|
||||
)
|
||||
else:
|
||||
warnings.warn(f"Invalid value type {type(v)} for input {_info.data.get('name')}.")
|
||||
warnings.warn(
|
||||
f"Invalid value type {type(v)} for input {_info.data.get('name')}.",
|
||||
stacklevel=4,
|
||||
)
|
||||
return v
|
||||
|
||||
@field_validator("value")
|
||||
|
|
|
|||
|
|
@ -36,9 +36,7 @@ def update_memory_keys(langchain_object, possible_new_mem_key):
|
|||
if key not in [langchain_object.memory.memory_key, possible_new_mem_key]
|
||||
][0]
|
||||
|
||||
keys = [input_key, output_key, possible_new_mem_key]
|
||||
attrs = ["input_key", "output_key", "memory_key"]
|
||||
for key, attr in zip(keys, attrs):
|
||||
for key, attr in [(input_key, "input_key"), (output_key, "output_key"), (possible_new_mem_key, "memory_key")]:
|
||||
try:
|
||||
setattr(langchain_object.memory, attr, key)
|
||||
except ValueError as exc:
|
||||
|
|
|
|||
|
|
@ -28,7 +28,7 @@ def upload(file_path, host, flow_id):
|
|||
raise Exception(msg)
|
||||
except Exception as e:
|
||||
msg = f"Error uploading file: {e}"
|
||||
raise Exception(msg)
|
||||
raise Exception(msg) from e
|
||||
|
||||
|
||||
def upload_file(file_path: str, host: str, flow_id: str, components: list[str], tweaks: dict | None = None):
|
||||
|
|
@ -65,7 +65,7 @@ def upload_file(file_path: str, host: str, flow_id: str, components: list[str],
|
|||
raise ValueError(msg)
|
||||
except Exception as e:
|
||||
msg = f"Error uploading file: {e}"
|
||||
raise ValueError(msg)
|
||||
raise ValueError(msg) from e
|
||||
|
||||
|
||||
def get_flow(url: str, flow_id: str):
|
||||
|
|
@ -92,4 +92,4 @@ def get_flow(url: str, flow_id: str):
|
|||
raise Exception(msg)
|
||||
except Exception as e:
|
||||
msg = f"Error retrieving flow: {e}"
|
||||
raise Exception(msg)
|
||||
raise Exception(msg) from e
|
||||
|
|
|
|||
|
|
@ -78,7 +78,7 @@ class SizedLogBuffer:
|
|||
with self._wlock:
|
||||
as_list = list(self.buffer)
|
||||
max_index = -1
|
||||
for i, (ts, msg) in enumerate(as_list):
|
||||
for i, (ts, _) in enumerate(as_list):
|
||||
if ts >= timestamp:
|
||||
max_index = i
|
||||
break
|
||||
|
|
|
|||
|
|
@ -1,4 +1,3 @@
|
|||
import warnings
|
||||
from collections.abc import Sequence
|
||||
from uuid import UUID
|
||||
|
||||
|
|
@ -124,7 +123,7 @@ def store_message(
|
|||
ValueError: If any of the required parameters (session_id, sender, sender_name) is not provided.
|
||||
"""
|
||||
if not message:
|
||||
warnings.warn("No message provided.")
|
||||
logger.warning("No message provided.")
|
||||
return []
|
||||
|
||||
if not message.session_id or not message.sender or not message.sender_name:
|
||||
|
|
|
|||
|
|
@ -164,10 +164,10 @@ class Data(BaseModel):
|
|||
if key in {"data", "text_key"} or key.startswith("_"):
|
||||
return super().__getattr__(key)
|
||||
return self.data[key]
|
||||
except KeyError:
|
||||
except KeyError as e:
|
||||
# Fallback to default behavior to raise AttributeError for undefined attributes
|
||||
msg = f"'{type(self).__name__}' object has no attribute '{key}'"
|
||||
raise AttributeError(msg)
|
||||
raise AttributeError(msg) from e
|
||||
|
||||
def __setattr__(self, key, value):
|
||||
"""
|
||||
|
|
|
|||
|
|
@ -29,9 +29,9 @@ class dotdict(dict):
|
|||
value = dotdict(value)
|
||||
self[attr] = value # Update self to nest dotdict for future accesses
|
||||
return value
|
||||
except KeyError:
|
||||
except KeyError as e:
|
||||
msg = f"'dotdict' object has no attribute '{attr}'"
|
||||
raise AttributeError(msg)
|
||||
raise AttributeError(msg) from e
|
||||
|
||||
def __setattr__(self, key, value):
|
||||
"""
|
||||
|
|
@ -57,9 +57,9 @@ class dotdict(dict):
|
|||
"""
|
||||
try:
|
||||
del self[key]
|
||||
except KeyError:
|
||||
except KeyError as e:
|
||||
msg = f"'dotdict' object has no attribute '{key}'"
|
||||
raise AttributeError(msg)
|
||||
raise AttributeError(msg) from e
|
||||
|
||||
def __missing__(self, key):
|
||||
"""
|
||||
|
|
|
|||
|
|
@ -31,9 +31,9 @@ def _timestamp_to_str(timestamp: datetime | str) -> str:
|
|||
try:
|
||||
datetime.strptime(timestamp, "%Y-%m-%d %H:%M:%S")
|
||||
return timestamp
|
||||
except ValueError:
|
||||
except ValueError as e:
|
||||
msg = f"Invalid timestamp: {timestamp}"
|
||||
raise ValueError(msg)
|
||||
raise ValueError(msg) from e
|
||||
return timestamp.strftime("%Y-%m-%d %H:%M:%S")
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -23,7 +23,7 @@ class Service(ABC):
|
|||
return schema
|
||||
|
||||
async def teardown(self):
|
||||
pass
|
||||
return
|
||||
|
||||
def set_ready(self):
|
||||
self.ready = True
|
||||
|
|
|
|||
|
|
@ -1,7 +1,6 @@
|
|||
# Path: src/backend/langflow/services/database/models/flow/model.py
|
||||
|
||||
import re
|
||||
import warnings
|
||||
from datetime import datetime, timezone
|
||||
from typing import TYPE_CHECKING, Optional
|
||||
from uuid import UUID, uuid4
|
||||
|
|
@ -9,6 +8,7 @@ from uuid import UUID, uuid4
|
|||
import emoji
|
||||
from emoji import purely_emoji # type: ignore
|
||||
from fastapi import HTTPException, status
|
||||
from loguru import logger
|
||||
from pydantic import field_serializer, field_validator
|
||||
from sqlalchemy import Text, UniqueConstraint
|
||||
from sqlmodel import JSON, Column, Field, Relationship, SQLModel
|
||||
|
|
@ -88,8 +88,7 @@ class FlowBase(SQLModel):
|
|||
|
||||
emoji_value = emoji.emojize(v, variant="emoji_type")
|
||||
if v == emoji_value:
|
||||
warnings.warn(f"Invalid emoji. {v} is not a valid emoji.")
|
||||
icon = v
|
||||
logger.warning(f"Invalid emoji. {v} is not a valid emoji.")
|
||||
icon = emoji_value
|
||||
|
||||
if purely_emoji(icon):
|
||||
|
|
|
|||
|
|
@ -220,7 +220,7 @@ class DatabaseService(Service):
|
|||
logger.error(f"AutogenerateDiffsDetected: {exc}")
|
||||
if not fix:
|
||||
msg = f"There's a mismatch between the models and the database.\n{exc}"
|
||||
raise RuntimeError(msg)
|
||||
raise RuntimeError(msg) from exc
|
||||
|
||||
if fix:
|
||||
self.try_downgrade_upgrade_until_success(alembic_cfg)
|
||||
|
|
|
|||
|
|
@ -54,9 +54,9 @@ def infer_service_types(factory_class: type[ServiceFactory], available_services=
|
|||
# Attempt to find a matching enum value
|
||||
service_type = ServiceType[type_name]
|
||||
service_types.append(service_type)
|
||||
except KeyError:
|
||||
except KeyError as e:
|
||||
msg = f"No matching ServiceType for parameter type: {param_type.__name__}"
|
||||
raise ValueError(msg)
|
||||
raise ValueError(msg) from e
|
||||
return service_types
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -132,7 +132,7 @@ class ServiceManager:
|
|||
module = importlib.import_module(module_name)
|
||||
|
||||
# Find all classes in the module that are subclasses of ServiceFactory
|
||||
for name, obj in inspect.getmembers(module, inspect.isclass):
|
||||
for _, obj in inspect.getmembers(module, inspect.isclass):
|
||||
if issubclass(obj, ServiceFactory) and obj is not ServiceFactory:
|
||||
factories.append(obj())
|
||||
break
|
||||
|
|
|
|||
|
|
@ -44,7 +44,7 @@ async def user_data_context(store_service: StoreService, api_key: str | None = N
|
|||
except HTTPStatusError as exc:
|
||||
if exc.response.status_code == 403:
|
||||
msg = "Invalid API key"
|
||||
raise ValueError(msg)
|
||||
raise ValueError(msg) from exc
|
||||
try:
|
||||
yield
|
||||
finally:
|
||||
|
|
@ -119,10 +119,10 @@ class StoreService(Service):
|
|||
if exc.response.status_code in [403, 401]:
|
||||
return False
|
||||
msg = f"Unexpected status code: {exc.response.status_code}"
|
||||
raise ValueError(msg)
|
||||
raise ValueError(msg) from exc
|
||||
except Exception as exc:
|
||||
msg = f"Unexpected error: {exc}"
|
||||
raise ValueError(msg)
|
||||
raise ValueError(msg) from exc
|
||||
|
||||
async def _get(
|
||||
self, url: str, api_key: str | None = None, params: dict[str, Any] | None = None
|
||||
|
|
@ -137,7 +137,7 @@ class StoreService(Service):
|
|||
raise exc
|
||||
except Exception as exc:
|
||||
msg = f"GET failed: {exc}"
|
||||
raise ValueError(msg)
|
||||
raise ValueError(msg) from exc
|
||||
json_response = response.json()
|
||||
result = json_response["data"]
|
||||
metadata = {}
|
||||
|
|
@ -355,9 +355,9 @@ class StoreService(Service):
|
|||
# If it is, we need to build the metadata
|
||||
try:
|
||||
download_component.metadata = process_component_data(download_component.data.get("nodes", []))
|
||||
except KeyError:
|
||||
except KeyError as e:
|
||||
msg = "Invalid component data. No nodes found"
|
||||
raise ValueError(msg)
|
||||
raise ValueError(msg) from e
|
||||
return download_component
|
||||
|
||||
async def upload(self, api_key: str, component_data: StoreComponentCreate) -> CreateComponentResponse:
|
||||
|
|
@ -392,7 +392,7 @@ class StoreService(Service):
|
|||
except UnboundLocalError:
|
||||
pass
|
||||
msg = f"Upload failed: {exc}"
|
||||
raise ValueError(msg)
|
||||
raise ValueError(msg) from exc
|
||||
|
||||
async def update(
|
||||
self, api_key: str, component_id: UUID, component_data: StoreComponentCreate
|
||||
|
|
@ -429,7 +429,7 @@ class StoreService(Service):
|
|||
except UnboundLocalError:
|
||||
pass
|
||||
msg = f"Upload failed: {exc}"
|
||||
raise ValueError(msg)
|
||||
raise ValueError(msg) from exc
|
||||
|
||||
async def get_tags(self) -> list[dict[str, Any]]:
|
||||
url = f"{self.base_url}/items/tags"
|
||||
|
|
@ -460,9 +460,9 @@ class StoreService(Service):
|
|||
# try to convert it to int
|
||||
try:
|
||||
likes = int(likes)
|
||||
except ValueError:
|
||||
except ValueError as e:
|
||||
msg = f"Unexpected value for likes count: {likes}"
|
||||
raise ValueError(msg)
|
||||
raise ValueError(msg) from e
|
||||
return likes
|
||||
|
||||
async def like_component(self, api_key: str, component_id: str) -> bool:
|
||||
|
|
@ -567,10 +567,10 @@ class StoreService(Service):
|
|||
except HTTPStatusError as exc:
|
||||
if exc.response.status_code == 403:
|
||||
msg = "You are not authorized to access this public resource"
|
||||
raise ForbiddenError(msg)
|
||||
raise ForbiddenError(msg) from exc
|
||||
if exc.response.status_code == 401:
|
||||
msg = "You are not authorized to access this resource. Please check your API key."
|
||||
raise APIKeyError(msg)
|
||||
raise APIKeyError(msg) from exc
|
||||
|
||||
if store_api_key:
|
||||
# Now, from the result, we need to get the components
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
from __future__ import annotations
|
||||
|
||||
from abc import ABC, abstractmethod
|
||||
from collections.abc import Sequence
|
||||
from typing import TYPE_CHECKING, Any
|
||||
from uuid import UUID
|
||||
|
||||
|
|
@ -40,7 +41,7 @@ class BaseTracer(ABC):
|
|||
trace_name: str,
|
||||
outputs: dict[str, Any] | None = None,
|
||||
error: Exception | None = None,
|
||||
logs: list[Log | dict] = [],
|
||||
logs: Sequence[Log | dict] = (),
|
||||
):
|
||||
raise NotImplementedError
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
from __future__ import annotations
|
||||
|
||||
import os
|
||||
from collections.abc import Sequence
|
||||
from datetime import datetime
|
||||
from typing import TYPE_CHECKING, Any
|
||||
from uuid import UUID
|
||||
|
|
@ -100,7 +101,7 @@ class LangFuseTracer(BaseTracer):
|
|||
trace_name: str,
|
||||
outputs: dict[str, Any] | None = None,
|
||||
error: Exception | None = None,
|
||||
logs: list[Log | dict] = [],
|
||||
logs: Sequence[Log | dict] = (),
|
||||
):
|
||||
end_time = datetime.utcnow()
|
||||
if not self._ready:
|
||||
|
|
@ -111,7 +112,7 @@ class LangFuseTracer(BaseTracer):
|
|||
_output: dict = {}
|
||||
_output |= outputs if outputs else {}
|
||||
_output |= {"error": str(error)} if error else {}
|
||||
_output |= {"logs": logs} if logs else {}
|
||||
_output |= {"logs": list(logs)} if logs else {}
|
||||
content = {"output": _output, "end_time": end_time}
|
||||
span.update(**content)
|
||||
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@ from __future__ import annotations
|
|||
import os
|
||||
import traceback
|
||||
import types
|
||||
from collections.abc import Sequence
|
||||
from datetime import datetime, timezone
|
||||
from typing import TYPE_CHECKING, Any
|
||||
from uuid import UUID
|
||||
|
|
@ -119,7 +120,7 @@ class LangSmithTracer(BaseTracer):
|
|||
trace_name: str,
|
||||
outputs: dict[str, Any] | None = None,
|
||||
error: Exception | None = None,
|
||||
logs: list[Log | dict] = [],
|
||||
logs: Sequence[Log | dict] = (),
|
||||
):
|
||||
if not self._ready:
|
||||
return
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
from __future__ import annotations
|
||||
|
||||
from collections.abc import Sequence
|
||||
from typing import TYPE_CHECKING, Any, cast
|
||||
from uuid import UUID
|
||||
|
||||
|
|
@ -103,7 +104,7 @@ class LangWatchTracer(BaseTracer):
|
|||
trace_name: str,
|
||||
outputs: dict[str, Any] | None = None,
|
||||
error: Exception | None = None,
|
||||
logs: list[Log | dict] = [],
|
||||
logs: Sequence[Log | dict] = (),
|
||||
):
|
||||
if not self._ready:
|
||||
return
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
from __future__ import annotations
|
||||
|
||||
import os
|
||||
from collections.abc import Sequence
|
||||
from datetime import datetime, timezone
|
||||
from typing import TYPE_CHECKING
|
||||
from uuid import UUID
|
||||
|
|
@ -165,7 +166,7 @@ class DatabaseVariableService(VariableService, Service):
|
|||
user_id: UUID | str,
|
||||
name: str,
|
||||
value: str,
|
||||
default_fields: list[str] = [],
|
||||
default_fields: Sequence[str] = (),
|
||||
_type: str = GENERIC_TYPE,
|
||||
session: Session = Depends(get_session),
|
||||
):
|
||||
|
|
@ -173,7 +174,7 @@ class DatabaseVariableService(VariableService, Service):
|
|||
name=name,
|
||||
type=_type,
|
||||
value=auth_utils.encrypt_api_key(value, settings_service=self.settings_service),
|
||||
default_fields=default_fields,
|
||||
default_fields=list(default_fields),
|
||||
)
|
||||
variable = Variable.model_validate(variable_base, from_attributes=True, update={"user_id": user_id})
|
||||
session.add(variable)
|
||||
|
|
|
|||
|
|
@ -53,7 +53,7 @@ class Template(BaseModel):
|
|||
_input = instantiate_input(input_type, value)
|
||||
except Exception as e:
|
||||
msg = f"Error instantiating input {input_type}: {e}"
|
||||
raise ValueError(msg)
|
||||
raise ValueError(msg) from e
|
||||
else:
|
||||
_input = Input(**value)
|
||||
|
||||
|
|
|
|||
|
|
@ -217,9 +217,9 @@ def prepare_global_scope(code, module):
|
|||
imported_module = importlib.import_module(node.module)
|
||||
for alias in node.names:
|
||||
exec_globals[alias.name] = getattr(imported_module, alias.name)
|
||||
except ModuleNotFoundError:
|
||||
except ModuleNotFoundError as e:
|
||||
msg = f"Module {node.module} not found. Please install it and try again"
|
||||
raise ModuleNotFoundError(msg)
|
||||
raise ModuleNotFoundError(msg) from e
|
||||
return exec_globals
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -74,20 +74,18 @@ def fetch_latest_version(package_name: str, include_prerelease: bool) -> str | N
|
|||
from packaging import version as pkg_version
|
||||
|
||||
package_name = package_name.replace(" ", "-").lower()
|
||||
valid_versions = []
|
||||
try:
|
||||
response = httpx.get(f"https://pypi.org/pypi/{package_name}/json")
|
||||
versions = response.json()["releases"].keys()
|
||||
valid_versions = [v for v in versions if include_prerelease or not is_pre_release(v)]
|
||||
|
||||
except Exception as e:
|
||||
logger.exception(e)
|
||||
|
||||
finally:
|
||||
if not valid_versions:
|
||||
return None # Handle case where no valid versions are found
|
||||
return max(valid_versions, key=lambda v: pkg_version.parse(v))
|
||||
|
||||
except Exception as e:
|
||||
logger.exception(e)
|
||||
return None
|
||||
|
||||
|
||||
def get_version_info():
|
||||
return VERSION_INFO
|
||||
|
|
|
|||
|
|
@ -149,8 +149,15 @@ exclude = ["langflow/alembic"]
|
|||
line-length = 120
|
||||
|
||||
[tool.ruff.lint]
|
||||
flake8-bugbear.extend-immutable-calls = [
|
||||
"fastapi.Depends",
|
||||
"fastapi.File",
|
||||
"fastapi.Query",
|
||||
"typer.Option",
|
||||
]
|
||||
select = [
|
||||
"ASYNC",
|
||||
"B",
|
||||
"C4",
|
||||
"COM",
|
||||
"DJ",
|
||||
|
|
|
|||
|
|
@ -11,6 +11,9 @@ from typing import TYPE_CHECKING
|
|||
|
||||
import orjson
|
||||
import pytest
|
||||
from loguru import logger
|
||||
from pytest import LogCaptureFixture
|
||||
|
||||
from base.langflow.components.inputs.ChatInput import ChatInput
|
||||
from dotenv import load_dotenv
|
||||
from fastapi.testclient import TestClient
|
||||
|
|
@ -79,6 +82,19 @@ def get_text():
|
|||
assert path.exists(), f"File {path} does not exist. Available files: {list(data_path.iterdir())}"
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def caplog(caplog: LogCaptureFixture):
|
||||
handler_id = logger.add(
|
||||
caplog.handler,
|
||||
format="{message}",
|
||||
level=0,
|
||||
filter=lambda record: record["level"].no >= caplog.handler.level,
|
||||
enqueue=False, # Set to 'True' if your test is spawning child processes.
|
||||
)
|
||||
yield caplog
|
||||
logger.remove(handler_id)
|
||||
|
||||
|
||||
@pytest.fixture()
|
||||
async def async_client() -> AsyncGenerator:
|
||||
from langflow.main import create_app
|
||||
|
|
|
|||
|
|
@ -1,6 +1,8 @@
|
|||
import logging
|
||||
from collections import deque
|
||||
|
||||
import pytest
|
||||
from pytest import LogCaptureFixture
|
||||
|
||||
from langflow.components.agents.ToolCallingAgent import ToolCallingAgentComponent
|
||||
from langflow.components.inputs.ChatInput import ChatInput
|
||||
|
|
@ -28,14 +30,16 @@ async def test_graph_not_prepared():
|
|||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_graph():
|
||||
async def test_graph(caplog: LogCaptureFixture):
|
||||
chat_input = ChatInput()
|
||||
chat_output = ChatOutput()
|
||||
graph = Graph()
|
||||
graph.add_component(chat_input)
|
||||
graph.add_component(chat_output)
|
||||
with pytest.warns(UserWarning, match="Graph has vertices but no edges"):
|
||||
caplog.clear()
|
||||
with caplog.at_level(logging.WARNING):
|
||||
graph.prepare()
|
||||
assert "Graph has vertices but no edges" in caplog.text
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue