feat: Add ruff rules for return (RET) (#3981)

Add ruff rules for return (RET)
This commit is contained in:
Christophe Bornet 2024-10-01 19:46:48 +02:00 • committed by GitHub
commit 7b7e5cd1b4
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
156 changed files with 452 additions and 670 deletions

View file

@ -235,7 +235,7 @@ def run_on_windows(host, port, log_level, options, app):
""" """
print_banner(host, port) print_banner(host, port)
run_langflow(host, port, log_level, options, app) run_langflow(host, port, log_level, options, app)
return None return
def is_port_in_use(port, host="localhost"): def is_port_in_use(port, host="localhost"):
@ -296,8 +296,7 @@ def generate_pip_command(package_names, is_pre_release):
base_command = "pip install" base_command = "pip install"
if is_pre_release: if is_pre_release:
return f"{base_command} {' '.join(package_names)} -U --pre" return f"{base_command} {' '.join(package_names)} -U --pre"
else: return f"{base_command} {' '.join(package_names)} -U"
return f"{base_command} {' '.join(package_names)} -U"
def stylize_text(text: str, to_style: str, is_prerelease: bool) -> str: def stylize_text(text: str, to_style: str, is_prerelease: bool) -> str:

View file

@ -60,6 +60,5 @@ async def health_check(
if response.has_error(): if response.has_error():
raise HTTPException(status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, detail=response.model_dump()) raise HTTPException(status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, detail=response.model_dump())
else: response.status = "ok"
response.status = "ok" return response
return response

View file

@ -100,7 +100,7 @@ async def check_langflow_version(component: StoreComponentCreate):
langflow_version = get_lf_version_from_pypi() langflow_version = get_lf_version_from_pypi()
if langflow_version is None: 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: if langflow_version != component.last_tested_version:
warnings.warn( warnings.warn(
f"Your version of Langflow ({component.last_tested_version}) is outdated. " f"Your version of Langflow ({component.last_tested_version}) is outdated. "
f"Please update to the latest version ({langflow_version}) and try again." f"Please update to the latest version ({langflow_version}) and try again."
@ -117,16 +117,15 @@ def format_elapsed_time(elapsed_time: float) -> str:
if elapsed_time < 1: if elapsed_time < 1:
milliseconds = int(round(elapsed_time * 1000)) milliseconds = int(round(elapsed_time * 1000))
return f"{milliseconds} ms" return f"{milliseconds} ms"
elif elapsed_time < 60: if elapsed_time < 60:
seconds = round(elapsed_time, 2) seconds = round(elapsed_time, 2)
unit = "second" if seconds == 1 else "seconds" unit = "second" if seconds == 1 else "seconds"
return f"{seconds} {unit}" return f"{seconds} {unit}"
else: minutes = int(elapsed_time // 60)
minutes = int(elapsed_time // 60) seconds = round(elapsed_time % 60, 2)
seconds = round(elapsed_time % 60, 2) minutes_unit = "minute" if minutes == 1 else "minutes"
minutes_unit = "minute" if minutes == 1 else "minutes" seconds_unit = "second" if seconds == 1 else "seconds"
seconds_unit = "second" if seconds == 1 else "seconds" return f"{minutes} {minutes_unit}, {seconds} {seconds_unit}"
return f"{minutes} {minutes_unit}, {seconds} {seconds_unit}"
async def build_graph_from_data(flow_id: str, payload: dict, **kwargs): async def build_graph_from_data(flow_id: str, payload: dict, **kwargs):
@ -231,29 +230,27 @@ def get_suggestion_message(outdated_components: list[str]) -> str:
count = len(outdated_components) count = len(outdated_components)
if count == 0: if count == 0:
return "The flow contains no outdated components." return "The flow contains no outdated components."
elif count == 1: if count == 1:
return ( return (
"The flow contains 1 outdated component. " "The flow contains 1 outdated component. "
f"We recommend updating the following component: {outdated_components[0]}." f"We recommend updating the following component: {outdated_components[0]}."
) )
else: components = ", ".join(outdated_components)
components = ", ".join(outdated_components) return (
return ( f"The flow contains {count} outdated components. "
f"The flow contains {count} outdated components. " f"We recommend updating the following components: {components}."
f"We recommend updating the following components: {components}." )
)
def parse_value(value: Any, input_type: str) -> Any: def parse_value(value: Any, input_type: str) -> Any:
"""Helper function to parse the value based on input type.""" """Helper function to parse the value based on input type."""
if value == "": if value == "":
return value return value
elif input_type == "IntInput": if input_type == "IntInput":
return int(value) if value is not None else None return int(value) if value is not None else None
elif input_type == "FloatInput": if input_type == "FloatInput":
return float(value) if value is not None else None return float(value) if value is not None else None
else: return value
return value
async def cascade_delete_flow(session: Session, flow: Flow): async def cascade_delete_flow(session: Session, flow: Flow):

View file

@ -71,11 +71,10 @@ async def get_all(
try: try:
async with Lock() as lock: async with Lock() as lock:
all_types_dict = await get_and_cache_all_types_dict( return await get_and_cache_all_types_dict(
settings_service=settings_service, cache_service=cache_service, force_refresh=force_refresh, lock=lock settings_service=settings_service, cache_service=cache_service, force_refresh=force_refresh, lock=lock
) )
return all_types_dict
except Exception as exc: except Exception as exc:
logger.exception(exc) logger.exception(exc)
raise HTTPException(status_code=500, detail=str(exc)) from exc raise HTTPException(status_code=500, detail=str(exc)) from exc
@ -163,13 +162,12 @@ async def simple_run_flow_task(
Run a flow task as a BackgroundTask, therefore it should not throw exceptions. Run a flow task as a BackgroundTask, therefore it should not throw exceptions.
""" """
try: try:
result = await simple_run_flow( return await simple_run_flow(
flow=flow, flow=flow,
input_request=input_request, input_request=input_request,
stream=stream, stream=stream,
api_key_user=api_key_user, api_key_user=api_key_user,
) )
return result
except Exception as exc: except Exception as exc:
logger.exception(f"Error running flow {flow.id} task: {exc}") logger.exception(f"Error running flow {flow.id} task: {exc}")
@ -279,9 +277,8 @@ async def simplified_run_flow(
raise HTTPException(status_code=status.HTTP_400_BAD_REQUEST, detail=str(exc)) from exc raise HTTPException(status_code=status.HTTP_400_BAD_REQUEST, detail=str(exc)) from exc
if "not found" in str(exc): if "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: logger.exception(exc)
logger.exception(exc) raise APIException(status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, exception=exc, flow=flow) from exc
raise APIException(status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, exception=exc, flow=flow) from exc
except InvalidChatInputException as exc: except InvalidChatInputException as exc:
logger.error(exc) logger.error(exc)
raise HTTPException(status_code=status.HTTP_400_BAD_REQUEST, detail=str(exc)) from exc raise HTTPException(status_code=status.HTTP_400_BAD_REQUEST, detail=str(exc)) from exc
@ -486,12 +483,11 @@ async def experimental_run_flow(
if f"Flow {flow_id_str} not found" in str(exc): if f"Flow {flow_id_str} not found" in str(exc):
logger.error(f"Flow {flow_id_str} not found") logger.error(f"Flow {flow_id_str} not found")
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
elif f"Session {session_id} not found" in str(exc): if f"Session {session_id} not found" in str(exc):
logger.error(f"Session {session_id} not found") logger.error(f"Session {session_id} not found")
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: logger.exception(exc)
logger.exception(exc) 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
except Exception as exc: except Exception as exc:
logger.exception(exc) logger.exception(exc)
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

View file

@ -105,7 +105,7 @@ async def download_image(file_name: str, flow_id: UUID, storage_service: Storage
if not content_type: if not content_type:
raise HTTPException(status_code=500, detail=f"Content type not found for extension {extension}") raise HTTPException(status_code=500, detail=f"Content type not found for extension {extension}")
elif not content_type.startswith("image"): if not content_type.startswith("image"):
raise HTTPException(status_code=500, detail=f"Content type {content_type} is not an image") raise HTTPException(status_code=500, detail=f"Content type {content_type} is not an image")
file_content = await storage_service.get_file(flow_id=flow_id_str, file_name=file_name) file_content = await storage_service.get_file(flow_id=flow_id_str, file_name=file_name)

View file

@ -102,7 +102,7 @@ def create_flow(
# If it is a validation error, return the error message # If it is a validation error, return the error message
if hasattr(e, "errors"): if hasattr(e, "errors"):
raise HTTPException(status_code=400, detail=str(e)) from e raise HTTPException(status_code=400, detail=str(e)) from e
elif "UNIQUE constraint failed" in str(e): if "UNIQUE constraint failed" in str(e):
# Get the name of the column that failed # Get the name of the column that failed
columns = str(e).split("UNIQUE constraint failed: ")[1].split(".")[1].split("\n")[0] columns = str(e).split("UNIQUE constraint failed: ")[1].split(".")[1].split("\n")[0]
# UNIQUE constraint failed: flow.user_id, flow.name # UNIQUE constraint failed: flow.user_id, flow.name
@ -113,10 +113,9 @@ def create_flow(
raise HTTPException( raise HTTPException(
status_code=400, detail=f"{column.capitalize().replace('_', ' ')} must be unique" status_code=400, detail=f"{column.capitalize().replace('_', ' ')} must be unique"
) from e ) from e
elif isinstance(e, HTTPException): if isinstance(e, HTTPException):
raise e raise e
else: raise HTTPException(status_code=500, detail=str(e)) from e
raise HTTPException(status_code=500, detail=str(e)) from e
@router.get("/", response_model=list[FlowRead], status_code=200) @router.get("/", response_model=list[FlowRead], status_code=200)
@ -198,8 +197,7 @@ def read_flow(
) # noqa ) # noqa
if user_flow := session.exec(stmt).first(): if user_flow := session.exec(stmt).first():
return user_flow return user_flow
else: raise HTTPException(status_code=404, detail="Flow not found")
raise HTTPException(status_code=404, detail="Flow not found")
@router.patch("/{flow_id}", response_model=FlowRead, status_code=200) @router.patch("/{flow_id}", response_model=FlowRead, status_code=200)
@ -242,7 +240,7 @@ def update_flow(
# If it is a validation error, return the error message # If it is a validation error, return the error message
if hasattr(e, "errors"): if hasattr(e, "errors"):
raise HTTPException(status_code=400, detail=str(e)) from e raise HTTPException(status_code=400, detail=str(e)) from e
elif "UNIQUE constraint failed" in str(e): if "UNIQUE constraint failed" in str(e):
# Get the name of the column that failed # Get the name of the column that failed
columns = str(e).split("UNIQUE constraint failed: ")[1].split(".")[1].split("\n")[0] columns = str(e).split("UNIQUE constraint failed: ")[1].split(".")[1].split("\n")[0]
# UNIQUE constraint failed: flow.user_id, flow.name # UNIQUE constraint failed: flow.user_id, flow.name
@ -253,10 +251,9 @@ def update_flow(
raise HTTPException( raise HTTPException(
status_code=400, detail=f"{column.capitalize().replace('_', ' ')} must be unique" status_code=400, detail=f"{column.capitalize().replace('_', ' ')} must be unique"
) from e ) from e
elif isinstance(e, HTTPException): if isinstance(e, HTTPException):
raise e raise e
else: raise HTTPException(status_code=500, detail=str(e)) from e
raise HTTPException(status_code=500, detail=str(e)) from e
@router.delete("/{flow_id}", status_code=200) @router.delete("/{flow_id}", status_code=200)
@ -402,5 +399,4 @@ async def download_multiple_file(
media_type="application/x-zip-compressed", media_type="application/x-zip-compressed",
headers={"Content-Disposition": f"attachment; filename={filename}"}, headers={"Content-Disposition": f"attachment; filename={filename}"},
) )
else: return flows_without_api_keys[0]
return flows_without_api_keys[0]

View file

@ -89,8 +89,7 @@ def read_folders(
or_(Folder.user_id == current_user.id, Folder.user_id == None) # type: ignore # noqa: E711 or_(Folder.user_id == current_user.id, Folder.user_id == None) # type: ignore # noqa: E711
) )
).all() ).all()
sorted_folders = sorted(folders, key=lambda x: x.name != DEFAULT_FOLDER_NAME) return sorted(folders, key=lambda x: x.name != DEFAULT_FOLDER_NAME)
return sorted_folders
except Exception as e: except Exception as e:
raise HTTPException(status_code=500, detail=str(e)) raise HTTPException(status_code=500, detail=str(e))
@ -204,8 +203,7 @@ async def download_file(
): ):
"""Download all flows from folder.""" """Download all flows from folder."""
try: try:
folder = session.exec(select(Folder).where(Folder.id == folder_id, Folder.user_id == current_user.id)).first() return session.exec(select(Folder).where(Folder.id == folder_id, Folder.user_id == current_user.id)).first()
return folder
except Exception as e: except Exception as e:
if "No result found" in str(e): if "No result found" in str(e):
raise HTTPException(status_code=404, detail="Folder not found") raise HTTPException(status_code=404, detail="Folder not found")

View file

@ -71,12 +71,11 @@ async def login_to_get_access_token(
# Create default folder for user if it doesn't exist # Create default folder for user if it doesn't exist
create_default_folder_if_it_doesnt_exist(db, user.id) create_default_folder_if_it_doesnt_exist(db, user.id)
return tokens return tokens
else: raise HTTPException(
raise HTTPException( status_code=status.HTTP_401_UNAUTHORIZED,
status_code=status.HTTP_401_UNAUTHORIZED, detail="Incorrect username or password",
detail="Incorrect username or password", headers={"WWW-Authenticate": "Bearer"},
headers={"WWW-Authenticate": "Bearer"}, )
)
@router.get("/auto_login") @router.get("/auto_login")
@ -156,12 +155,11 @@ async def refresh_token(
domain=auth_settings.COOKIE_DOMAIN, domain=auth_settings.COOKIE_DOMAIN,
) )
return tokens return tokens
else: raise HTTPException(
raise HTTPException( status_code=status.HTTP_401_UNAUTHORIZED,
status_code=status.HTTP_401_UNAUTHORIZED, detail="Invalid refresh token",
detail="Invalid refresh token", headers={"WWW-Authenticate": "Bearer"},
headers={"WWW-Authenticate": "Bearer"}, )
)
@router.post("/logout") @router.post("/logout")

View file

@ -287,8 +287,7 @@ class VertexBuildResponse(BaseModel):
@field_serializer("data") @field_serializer("data")
def serialize_data(self, data: ResultDataResponse) -> dict: def serialize_data(self, data: ResultDataResponse) -> dict:
data_dict = data.model_dump() if isinstance(data, BaseModel) else data data_dict = data.model_dump() if isinstance(data, BaseModel) else data
truncated_data = truncate_long_strings(data_dict) return truncate_long_strings(data_dict)
return truncated_data
class VerticesBuiltResponse(BaseModel): class VerticesBuiltResponse(BaseModel):

View file

@ -17,8 +17,7 @@ def get_starter_projects(
from langflow.initial_setup.load import get_starter_projects_dump from langflow.initial_setup.load import get_starter_projects_dump
try: try:
flows = get_starter_projects_dump() return get_starter_projects_dump()
return flows
except Exception as exc: except Exception as exc:
logger.error(exc) logger.error(exc)
raise HTTPException(status_code=500, detail=str(exc)) from exc raise HTTPException(status_code=500, detail=str(exc)) from exc

View file

@ -29,8 +29,7 @@ def get_user_store_api_key(
if not user.store_api_key: if not user.store_api_key:
raise HTTPException(status_code=400, detail="You must have a store API key set.") raise HTTPException(status_code=400, detail="You must have a store API key set.")
try: try:
decrypted = auth_utils.decrypt_api_key(user.store_api_key, settings_service) return auth_utils.decrypt_api_key(user.store_api_key, settings_service)
return decrypted
except Exception as e: except Exception as e:
raise HTTPException(status_code=500, detail="Failed to decrypt API key. Please set a new one.") from e raise HTTPException(status_code=500, detail="Failed to decrypt API key. Please set a new one.") from e
@ -42,8 +41,7 @@ def get_optional_user_store_api_key(
if not user.store_api_key: if not user.store_api_key:
return None return None
try: try:
decrypted = auth_utils.decrypt_api_key(user.store_api_key, settings_service) return auth_utils.decrypt_api_key(user.store_api_key, settings_service)
return decrypted
except Exception as e: except Exception as e:
logger.error(f"Failed to decrypt API key: {e}") logger.error(f"Failed to decrypt API key: {e}")
return user.store_api_key return user.store_api_key
@ -82,8 +80,7 @@ async def share_component(
): ):
try: try:
await check_langflow_version(component) await check_langflow_version(component)
result = await store_service.upload(store_api_key, component) return await store_service.upload(store_api_key, component)
return result
except Exception as exc: except Exception as exc:
raise HTTPException(status_code=400, detail=str(exc)) raise HTTPException(status_code=400, detail=str(exc))
@ -97,8 +94,7 @@ async def update_shared_component(
): ):
try: try:
await check_langflow_version(component) await check_langflow_version(component)
result = await store_service.update(store_api_key, component_id, component) return await store_service.update(store_api_key, component_id, component)
return result
except Exception as exc: except Exception as exc:
raise HTTPException(status_code=400, detail=str(exc)) raise HTTPException(status_code=400, detail=str(exc))

View file

@ -106,8 +106,7 @@ def patch_user(
if not update_password: if not update_password:
user_update.password = user_db.password user_update.password = user_db.password
return update_user(user_db, user_update, session) return update_user(user_db, user_update, session)
else: raise HTTPException(status_code=404, detail="User not found")
raise HTTPException(status_code=404, detail="User not found")
@router.patch("/{user_id}/reset-password", response_model=UserRead) @router.patch("/{user_id}/reset-password", response_model=UserRead)
@ -146,7 +145,7 @@ def delete_user(
""" """
if current_user.id == user_id: if current_user.id == user_id:
raise HTTPException(status_code=400, detail="You can't delete your own user account") raise HTTPException(status_code=400, detail="You can't delete your own user account")
elif not current_user.is_superuser: if not current_user.is_superuser:
raise HTTPException(status_code=403, detail="Permission denied") raise HTTPException(status_code=403, detail="Permission denied")
user_db = session.exec(select(User).where(User.id == user_id)).first() user_db = session.exec(select(User).where(User.id == user_id)).first()

View file

@ -69,7 +69,7 @@ class LCAgentComponent(Component):
if method_name not in output_names: if method_name not in output_names:
msg = f"Output with name '{method_name}' must be defined." msg = f"Output with name '{method_name}' must be defined."
raise ValueError(msg) raise ValueError(msg)
elif not hasattr(self, method_name): if not hasattr(self, method_name):
msg = f"Method '{method_name}' must be defined." msg = f"Method '{method_name}' must be defined."
raise ValueError(msg) raise ValueError(msg)

View file

@ -14,6 +14,6 @@ class LCChainComponent(Component):
if method_name not in output_names: if method_name not in output_names:
msg = f"Output with name '{method_name}' must be defined." msg = f"Output with name '{method_name}' must be defined."
raise ValueError(msg) raise ValueError(msg)
elif not hasattr(self, method_name): if not hasattr(self, method_name):
msg = f"Method '{method_name}' must be defined." msg = f"Method '{method_name}' must be defined."
raise ValueError(msg) raise ValueError(msg)

View file

@ -71,9 +71,7 @@ def retrieve_file_paths(
glob = "**/*" if recursive else "*" glob = "**/*" if recursive else "*"
paths = walk_level(path_obj, depth) if depth else path_obj.glob(glob) paths = walk_level(path_obj, depth) if depth else path_obj.glob(glob)
file_paths = [str(p) for p in paths if p.is_file() and match_types(p) and is_not_hidden(p)] return [str(p) for p in paths if p.is_file() and match_types(p) and is_not_hidden(p)]
return file_paths
def partition_file_to_data(file_path: str, silent_errors: bool) -> Data | None: def partition_file_to_data(file_path: str, silent_errors: bool) -> Data | None:
@ -92,8 +90,7 @@ def partition_file_to_data(file_path: str, silent_errors: bool) -> Data | None:
text = "\n\n".join([str(el) for el in elements]) text = "\n\n".join([str(el) for el in elements])
metadata = elements.metadata if hasattr(elements, "metadata") else {} metadata = elements.metadata if hasattr(elements, "metadata") else {}
metadata["file_path"] = file_path metadata["file_path"] = file_path
record = Data(text=text, data=metadata) return Data(text=text, data=metadata)
return record
def read_text_file(file_path: str) -> str: def read_text_file(file_path: str) -> str:
@ -153,8 +150,7 @@ def parse_text_file_to_data(file_path: str, silent_errors: bool) -> Data | None:
raise ValueError(msg) from e raise ValueError(msg) from e
return None return None
record = Data(data={"file_path": file_path, "text": text}) return Data(data={"file_path": file_path, "text": text})
return record
# ! Removing unstructured dependency until # ! Removing unstructured dependency until

View file

@ -17,7 +17,7 @@ class LCEmbeddingsModel(Component):
if method_name not in output_names: if method_name not in output_names:
msg = f"Output with name '{method_name}' must be defined." msg = f"Output with name '{method_name}' must be defined."
raise ValueError(msg) raise ValueError(msg)
elif not hasattr(self, method_name): if not hasattr(self, method_name):
msg = f"Method '{method_name}' must be defined." msg = f"Method '{method_name}' must be defined."
raise ValueError(msg) raise ValueError(msg)

View file

@ -21,7 +21,7 @@ class LCToolComponent(Component):
if method_name not in output_names: if method_name not in output_names:
msg = f"Output with name '{method_name}' must be defined." msg = f"Output with name '{method_name}' must be defined."
raise ValueError(msg) raise ValueError(msg)
elif not hasattr(self, method_name): if not hasattr(self, method_name):
msg = f"Method '{method_name}' must be defined." msg = f"Method '{method_name}' must be defined."
raise ValueError(msg) raise ValueError(msg)

View file

@ -24,7 +24,7 @@ class LCChatMemoryComponent(Component):
if method_name not in output_names: if method_name not in output_names:
msg = f"Output with name '{method_name}' must be defined." msg = f"Output with name '{method_name}' must be defined."
raise ValueError(msg) raise ValueError(msg)
elif not hasattr(self, method_name): if not hasattr(self, method_name):
msg = f"Method '{method_name}' must be defined." msg = f"Method '{method_name}' must be defined."
raise ValueError(msg) raise ValueError(msg)

View file

@ -50,7 +50,7 @@ class LCModelComponent(Component):
if method_name not in output_names: if method_name not in output_names:
msg = f"Output with name '{method_name}' must be defined." msg = f"Output with name '{method_name}' must be defined."
raise ValueError(msg) raise ValueError(msg)
elif not hasattr(self, method_name): if not hasattr(self, method_name):
msg = f"Method '{method_name}' must be defined." msg = f"Method '{method_name}' must be defined."
raise ValueError(msg) raise ValueError(msg)
@ -181,18 +181,17 @@ class LCModelComponent(Component):
) )
if stream: if stream:
return runnable.stream(inputs) # type: ignore return runnable.stream(inputs) # type: ignore
message = runnable.invoke(inputs) # type: ignore
result = message.content if hasattr(message, "content") else message
if isinstance(message, AIMessage):
status_message = self.build_status_message(message)
self.status = status_message
elif isinstance(result, dict):
result = json.dumps(message, indent=4)
self.status = result
else: else:
message = runnable.invoke(inputs) # type: ignore self.status = result
result = message.content if hasattr(message, "content") else message return result
if isinstance(message, AIMessage):
status_message = self.build_status_message(message)
self.status = status_message
elif isinstance(result, dict):
result = json.dumps(message, indent=4)
self.status = result
else:
self.status = result
return result
except Exception as e: except Exception as e:
if message := self._get_exception_message(e): if message := self._get_exception_message(e):
raise ValueError(message) from e raise ValueError(message) from e

View file

@ -16,7 +16,7 @@ class LCTextSplitterComponent(LCDocumentTransformerComponent):
if method_name not in output_names: if method_name not in output_names:
msg = f"Output with name '{method_name}' must be defined." msg = f"Output with name '{method_name}' must be defined."
raise ValueError(msg) raise ValueError(msg)
elif not hasattr(self, method_name): if not hasattr(self, method_name):
msg = f"Method '{method_name}' must be defined." msg = f"Method '{method_name}' must be defined."
raise ValueError(msg) raise ValueError(msg)

View file

@ -30,11 +30,10 @@ class FlowTool(BaseTool):
"""The tool's input schema.""" """The tool's input schema."""
if self.args_schema is not None: if self.args_schema is not None:
return self.args_schema return self.args_schema
elif self.graph is not None: if self.graph is not None:
return build_schema_from_inputs(self.name, get_flow_inputs(self.graph)) return build_schema_from_inputs(self.name, get_flow_inputs(self.graph))
else: msg = "No input schema available."
msg = "No input schema available." raise ToolException(msg)
raise ToolException(msg)
def _run( def _run(
self, self,
@ -88,8 +87,7 @@ class FlowTool(BaseTool):
def build_tweaks_dict(self, args, kwargs): def build_tweaks_dict(self, args, kwargs):
args_names = get_arg_names(self.inputs) args_names = get_arg_names(self.inputs)
kwargs = self.validate_inputs(args_names=args_names, args=args, kwargs=kwargs) kwargs = self.validate_inputs(args_names=args_names, args=args, kwargs=kwargs)
tweaks = {arg["component_name"]: kwargs[arg["arg_name"]] for arg in args_names} return {arg["component_name"]: kwargs[arg["arg_name"]] for arg in args_names}
return tweaks
async def _arun( async def _arun(
self, self,

View file

@ -84,7 +84,7 @@ class LCVectorStoreComponent(Component):
if method_name not in output_names: if method_name not in output_names:
msg = f"Output with name '{method_name}' must be defined." msg = f"Output with name '{method_name}' must be defined."
raise ValueError(msg) raise ValueError(msg)
elif not hasattr(self, method_name): if not hasattr(self, method_name):
msg = f"Method '{method_name}' must be defined." msg = f"Method '{method_name}' must be defined."
raise ValueError(msg) raise ValueError(msg)
@ -139,9 +139,8 @@ class LCVectorStoreComponent(Component):
if self.status is None: if self.status is None:
self.status = "Retriever built successfully." self.status = "Retriever built successfully."
return retriever return retriever
else: msg = f"Vector Store {vector_store.__class__.__name__} does not have an as_retriever method."
msg = f"Vector Store {vector_store.__class__.__name__} does not have an as_retriever method." raise ValueError(msg)
raise ValueError(msg)
def search_documents(self) -> list[Data]: def search_documents(self) -> list[Data]:
""" """

View file

@ -45,12 +45,11 @@ class NotionPageCreator(LCToolComponent):
if isinstance(result, str): if isinstance(result, str):
# An error occurred, return it as text # An error occurred, return it as text
return Data(text=result) return Data(text=result)
else: # Success, return the created page data
# Success, return the created page data output = "Created page properties:\n"
output = "Created page properties:\n" for prop_name, prop_value in result.get("properties", {}).items():
for prop_name, prop_value in result.get("properties", {}).items(): output += f"{prop_name}: {prop_value}\n"
output += f"{prop_name}: {prop_value}\n" return Data(text=output, data=result)
return Data(text=output, data=result)
def build_tool(self) -> Tool: def build_tool(self) -> Tool:
return StructuredTool.from_function( return StructuredTool.from_function(
@ -84,8 +83,7 @@ class NotionPageCreator(LCToolComponent):
try: try:
response = requests.post("https://api.notion.com/v1/pages", headers=headers, json=data) response = requests.post("https://api.notion.com/v1/pages", headers=headers, json=data)
response.raise_for_status() response.raise_for_status()
result = response.json() return response.json()
return result
except requests.exceptions.RequestException as e: except requests.exceptions.RequestException as e:
error_message = f"Failed to create Notion page. Error: {str(e)}" error_message = f"Failed to create Notion page. Error: {str(e)}"
if hasattr(e, "response") and e.response is not None: if hasattr(e, "response") and e.response is not None:

View file

@ -36,9 +36,8 @@ class NotionDatabaseProperties(LCToolComponent):
if isinstance(result, str): if isinstance(result, str):
# An error occurred, return it as text # An error occurred, return it as text
return Data(text=result) return Data(text=result)
else: # Success, return the properties
# Success, return the properties return Data(text=str(result), data=result)
return Data(text=str(result), data=result)
def build_tool(self) -> Tool: def build_tool(self) -> Tool:
return StructuredTool.from_function( return StructuredTool.from_function(
@ -58,8 +57,7 @@ class NotionDatabaseProperties(LCToolComponent):
response = requests.get(url, headers=headers) response = requests.get(url, headers=headers)
response.raise_for_status() response.raise_for_status()
data = response.json() data = response.json()
properties = data.get("properties", {}) return data.get("properties", {})
return properties
except requests.exceptions.RequestException as e: except requests.exceptions.RequestException as e:
return f"Error fetching Notion database properties: {str(e)}" return f"Error fetching Notion database properties: {str(e)}"
except ValueError as e: except ValueError as e:

View file

@ -36,9 +36,8 @@ class NotionPageContent(LCToolComponent):
if isinstance(result, str) and result.startswith("Error:"): if isinstance(result, str) and result.startswith("Error:"):
# An error occurred, return it as text # An error occurred, return it as text
return Data(text=result) return Data(text=result)
else: # Success, return the content
# Success, return the content return Data(text=result, data={"content": result})
return Data(text=result, data={"content": result})
def build_tool(self) -> Tool: def build_tool(self) -> Tool:
return StructuredTool.from_function( return StructuredTool.from_function(

View file

@ -48,12 +48,11 @@ class NotionPageUpdate(LCToolComponent):
if isinstance(result, str): if isinstance(result, str):
# An error occurred, return it as text # An error occurred, return it as text
return Data(text=result) return Data(text=result)
else: # Success, return the updated page data
# Success, return the updated page data output = "Updated page properties:\n"
output = "Updated page properties:\n" for prop_name, prop_value in result.get("properties", {}).items():
for prop_name, prop_value in result.get("properties", {}).items(): output += f"{prop_name}: {prop_value}\n"
output += f"{prop_name}: {prop_value}\n" return Data(text=output, data=result)
return Data(text=output, data=result)
def build_tool(self) -> Tool: def build_tool(self) -> Tool:
return StructuredTool.from_function( return StructuredTool.from_function(

View file

@ -21,7 +21,7 @@ class HierarchicalCrewComponent(BaseCrewComponent):
def build_crew(self) -> Crew: def build_crew(self) -> Crew:
tasks, agents = self.get_tasks_and_agents() tasks, agents = self.get_tasks_and_agents()
crew = Crew( return Crew(
agents=agents, agents=agents,
tasks=tasks, tasks=tasks,
process=Process.hierarchical, process=Process.hierarchical,
@ -36,4 +36,3 @@ class HierarchicalCrewComponent(BaseCrewComponent):
step_callback=self.get_step_callback(), step_callback=self.get_step_callback(),
task_callback=self.get_task_callback(), task_callback=self.get_task_callback(),
) )
return crew

View file

@ -20,7 +20,7 @@ class SequentialCrewComponent(BaseCrewComponent):
def build_crew(self) -> Message: def build_crew(self) -> Message:
tasks, agents = self.get_tasks_and_agents() tasks, agents = self.get_tasks_and_agents()
crew = Crew( return Crew(
agents=agents, agents=agents,
tasks=tasks, tasks=tasks,
process=Process.sequential, process=Process.sequential,
@ -33,4 +33,3 @@ class SequentialCrewComponent(BaseCrewComponent):
step_callback=self.get_step_callback(), step_callback=self.get_step_callback(),
task_callback=self.get_task_callback(), task_callback=self.get_task_callback(),
) )
return crew

View file

@ -53,5 +53,4 @@ class AssistantsCreateAssistant(Component):
instructions=self.instructions, instructions=self.instructions,
model=self.model, model=self.model,
) )
message = Message(text=assistant.id) return Message(text=assistant.id)
return message

View file

@ -28,5 +28,4 @@ class AssistantsCreateThread(Component):
thread = self.client.beta.threads.create() thread = self.client.beta.threads.create()
thread_id = thread.id thread_id = thread.id
message = Message(text=thread_id) return Message(text=thread_id)
return message

View file

@ -33,5 +33,4 @@ class AssistantsGetAssistantName(Component):
assistant = self.client.beta.assistants.retrieve( assistant = self.client.beta.assistants.retrieve(
assistant_id=self.assistant_id, assistant_id=self.assistant_id,
) )
message = Message(text=assistant.name) return Message(text=assistant.name)
return message

View file

@ -27,6 +27,4 @@ class GetEnvVar(Component):
if self.env_var_name not in os.environ: if self.env_var_name not in os.environ:
msg = f"Environment variable {self.env_var_name} not set" msg = f"Environment variable {self.env_var_name} not set"
raise Exception(msg) raise Exception(msg)
else: return Message(text=os.environ[self.env_var_name])
message = Message(text=os.environ[self.env_var_name])
return message

View file

@ -18,8 +18,7 @@ class AssistantsListAssistants(Component):
def process_inputs(self) -> Message: def process_inputs(self) -> Message:
assistants = self.client.beta.assistants.list().data assistants = self.client.beta.assistants.list().data
id_list = [assistant.id for assistant in assistants] id_list = [assistant.id for assistant in assistants]
message = Message( return Message(
# get text from list # get text from list
text="\n".join(id_list) text="\n".join(id_list)
) )
return message

View file

@ -88,8 +88,7 @@ class AssistantsRun(Component):
for part in stream.text_deltas: for part in stream.text_deltas:
text += part text += part
print(part) print(part)
message = Message(text=text) return Message(text=text)
return message
except Exception as e: except Exception as e:
print(e) print(e)
msg = f"Error running assistant: {e}" msg = f"Error running assistant: {e}"

View file

@ -84,9 +84,7 @@ class GmailLoaderComponent(Component):
message = re.sub(r"\s{2,}", " ", message) message = re.sub(r"\s{2,}", " ", message)
# Trim leading and trailing whitespace # Trim leading and trailing whitespace
message = message.strip() return message.strip()
return message
def _extract_email_content(self, msg: Any) -> HumanMessage: def _extract_email_content(self, msg: Any) -> HumanMessage:
from_email = None from_email = None
@ -109,11 +107,10 @@ class GmailLoaderComponent(Component):
data = base64.urlsafe_b64decode(data).decode("utf-8") data = base64.urlsafe_b64decode(data).decode("utf-8")
pattern = re.compile(r"\r\nOn .+(\r\n)*wrote:\r\n") pattern = re.compile(r"\r\nOn .+(\r\n)*wrote:\r\n")
newest_response = re.split(pattern, data)[0] newest_response = re.split(pattern, data)[0]
message = HumanMessage( return HumanMessage(
content=self.clean_message_content(newest_response), content=self.clean_message_content(newest_response),
additional_kwargs={"sender": from_email}, additional_kwargs={"sender": from_email},
) )
return message
msg = "No plain text part found in the email." msg = "No plain text part found in the email."
raise ValueError(msg) raise ValueError(msg)
@ -147,8 +144,7 @@ class GmailLoaderComponent(Component):
raise ValueError(msg) raise ValueError(msg)
starter_content = self._extract_email_content(response_email) starter_content = self._extract_email_content(response_email)
return ChatSession(messages=[starter_content, message_content]) return ChatSession(messages=[starter_content, message_content])
else: return ChatSession(messages=[message_content])
return ChatSession(messages=[message_content])
def lazy_load(self) -> Iterator[ChatSession]: def lazy_load(self) -> Iterator[ChatSession]:
service = build("gmail", "v1", credentials=self.creds) service = build("gmail", "v1", credentials=self.creds)

View file

@ -43,9 +43,8 @@ class GoogleDriveComponent(Component):
"""Load credentials from the provided creds attribute or fallback to the original method.""" """Load credentials from the provided creds attribute or fallback to the original method."""
if self.creds: if self.creds:
return self.creds return self.creds
else: msg = "No credentials provided."
msg = "No credentials provided." raise ValueError(msg)
raise ValueError(msg)
class Config: class Config:
arbitrary_types_allowed = True arbitrary_types_allowed = True

View file

@ -98,16 +98,15 @@ class GoogleDriveSearchComponent(Component):
""" """
if mime_type == "application/vnd.google-apps.document": if mime_type == "application/vnd.google-apps.document":
return f"https://docs.google.com/document/d/{file_id}/edit" return f"https://docs.google.com/document/d/{file_id}/edit"
elif mime_type == "application/vnd.google-apps.spreadsheet": if mime_type == "application/vnd.google-apps.spreadsheet":
return f"https://docs.google.com/spreadsheets/d/{file_id}/edit" return f"https://docs.google.com/spreadsheets/d/{file_id}/edit"
elif mime_type == "application/vnd.google-apps.presentation": if mime_type == "application/vnd.google-apps.presentation":
return f"https://docs.google.com/presentation/d/{file_id}/edit" return f"https://docs.google.com/presentation/d/{file_id}/edit"
elif mime_type == "application/vnd.google-apps.drawing": if mime_type == "application/vnd.google-apps.drawing":
return f"https://docs.google.com/drawings/d/{file_id}/edit" return f"https://docs.google.com/drawings/d/{file_id}/edit"
elif mime_type == "application/pdf": if mime_type == "application/pdf":
return f"https://drive.google.com/file/d/{file_id}/view?usp=drivesdk"
else:
return f"https://drive.google.com/file/d/{file_id}/view?usp=drivesdk" return f"https://drive.google.com/file/d/{file_id}/view?usp=drivesdk"
return f"https://drive.google.com/file/d/{file_id}/view?usp=drivesdk"
def search_files(self) -> dict: def search_files(self) -> dict:
# Load the token information from the JSON string # Load the token information from the JSON string

View file

@ -51,13 +51,13 @@ class SelectivePassThroughComponent(Component):
if operator == "equals": if operator == "equals":
return input_value == comparison_value return input_value == comparison_value
elif operator == "not equals": if operator == "not equals":
return input_value != comparison_value return input_value != comparison_value
elif operator == "contains": if operator == "contains":
return comparison_value in input_value return comparison_value in input_value
elif operator == "starts with": if operator == "starts with":
return input_value.startswith(comparison_value) return input_value.startswith(comparison_value)
elif operator == "ends with": if operator == "ends with":
return input_value.endswith(comparison_value) return input_value.endswith(comparison_value)
return False return False
@ -71,6 +71,5 @@ class SelectivePassThroughComponent(Component):
if self.evaluate_condition(input_value, comparison_value, operator, case_sensitive): if self.evaluate_condition(input_value, comparison_value, operator, case_sensitive):
self.status = value_to_pass self.status = value_to_pass
return value_to_pass return value_to_pass
else: self.status = ""
self.status = "" return ""
return ""

View file

@ -75,6 +75,5 @@ class AssemblyAIGetSubtitles(Component):
self.status = result self.status = result
return result return result
else: self.status = transcript.error
self.status = transcript.error return Data(data={"error": transcript.error})
return Data(data={"error": transcript.error})

View file

@ -90,14 +90,14 @@ class AssemblyAILeMUR(Component):
error = "Either a Transcription Result or Transcript IDs must be provided" error = "Either a Transcription Result or Transcript IDs must be provided"
self.status = error self.status = error
return Data(data={"error": error}) return Data(data={"error": error})
elif self.transcription_result and self.transcription_result.data.get("error"): if self.transcription_result and self.transcription_result.data.get("error"):
# error message from the previous step # error message from the previous step
self.status = self.transcription_result.data["error"] self.status = self.transcription_result.data["error"]
return self.transcription_result return self.transcription_result
elif self.endpoint == "task" and not self.prompt: if self.endpoint == "task" and not self.prompt:
self.status = "No prompt specified for the task endpoint" self.status = "No prompt specified for the task endpoint"
return Data(data={"error": "No prompt specified"}) return Data(data={"error": "No prompt specified"})
elif self.endpoint == "question-answer" and not self.questions: if self.endpoint == "question-answer" and not self.questions:
error = "No Questions were provided for the question-answer endpoint" error = "No Questions were provided for the question-answer endpoint"
self.status = error self.status = error
return Data(data={"error": error}) return Data(data={"error": error})
@ -172,12 +172,11 @@ class AssemblyAILeMUR(Component):
def get_final_model(self, model_name: str) -> aai.LemurModel: def get_final_model(self, model_name: str) -> aai.LemurModel:
if model_name == "claude3_5_sonnet": if model_name == "claude3_5_sonnet":
return aai.LemurModel.claude3_5_sonnet return aai.LemurModel.claude3_5_sonnet
elif model_name == "claude3_opus": if model_name == "claude3_opus":
return aai.LemurModel.claude3_opus return aai.LemurModel.claude3_opus
elif model_name == "claude3_haiku": if model_name == "claude3_haiku":
return aai.LemurModel.claude3_haiku return aai.LemurModel.claude3_haiku
elif model_name == "claude3_sonnet": if model_name == "claude3_sonnet":
return aai.LemurModel.claude3_sonnet return aai.LemurModel.claude3_sonnet
else: msg = f"Model name not supported: {model_name}"
msg = f"Model name not supported: {model_name}" raise ValueError(msg)
raise ValueError(msg)

View file

@ -62,6 +62,5 @@ class AssemblyAITranscriptionJobPoller(Component):
data = Data(data=sorted_data) data = Data(data=sorted_data)
self.status = data self.status = data
return data return data
else: self.status = transcript.error
self.status = transcript.error return Data(data={"error": transcript.error})
return Data(data={"error": transcript.error})

View file

@ -177,10 +177,9 @@ class AssemblyAITranscriptionJobCreator(Component):
if transcript.error: if transcript.error:
self.status = transcript.error self.status = transcript.error
return Data(data={"error": transcript.error}) return Data(data={"error": transcript.error})
else: result = Data(data={"transcript_id": transcript.id})
result = Data(data={"transcript_id": transcript.id}) self.status = result
self.status = result return result
return result
except Exception as e: except Exception as e:
self.status = f"An error occurred: {str(e)}" self.status = f"An error occurred: {str(e)}"
return Data(data={"error": f"An error occurred: {str(e)}"}) return Data(data={"error": f"An error occurred: {str(e)}"})

View file

@ -66,7 +66,7 @@ class ConfluenceComponent(Component):
def build_confluence(self) -> ConfluenceLoader: def build_confluence(self) -> ConfluenceLoader:
content_format = ContentFormat(self.content_format) content_format = ContentFormat(self.content_format)
loader = ConfluenceLoader( return ConfluenceLoader(
url=self.url, url=self.url,
username=self.username, username=self.username,
api_key=self.api_key, api_key=self.api_key,
@ -75,7 +75,6 @@ class ConfluenceComponent(Component):
content_format=content_format, content_format=content_format,
max_pages=self.max_pages, max_pages=self.max_pages,
) )
return loader
def load_documents(self) -> list[Data]: def load_documents(self) -> list[Data]:
confluence = self.build_confluence() confluence = self.build_confluence()

View file

@ -100,13 +100,12 @@ class GitLoaderComponent(Component):
return False return False
return all(f(path) for f in file_filters) return all(f(path) for f in file_filters)
loader = GitLoader( return GitLoader(
repo_path=self.repo_path, repo_path=self.repo_path,
clone_url=self.clone_url, clone_url=self.clone_url,
branch=self.branch, branch=self.branch,
file_filter=combined_filter, file_filter=combined_filter,
) )
return loader
def load_documents(self) -> list[Data]: def load_documents(self) -> list[Data]:
gitloader = self.build_gitloader() gitloader = self.build_gitloader()

View file

@ -37,14 +37,12 @@ class UnstructuredComponent(Component):
def build_unstructured(self) -> UnstructuredLoader: def build_unstructured(self) -> UnstructuredLoader:
file_paths = [self.file] file_paths = [self.file]
loader = UnstructuredLoader( return UnstructuredLoader(
file_paths, file_paths,
api_key=self.api_key, api_key=self.api_key,
partition_via_api=True, partition_via_api=True,
) )
return loader
def load_documents(self) -> list[Data]: def load_documents(self) -> list[Data]:
unstructured = self.build_unstructured() unstructured = self.build_unstructured()

View file

@ -59,11 +59,10 @@ class AmazonBedrockEmbeddingsComponent(LCModelComponent):
client_params["region_name"] = self.region_name client_params["region_name"] = self.region_name
boto3_client = session.client("bedrock-runtime", **client_params) boto3_client = session.client("bedrock-runtime", **client_params)
output = BedrockEmbeddings( return BedrockEmbeddings(
credentials_profile_name=self.credentials_profile_name, credentials_profile_name=self.credentials_profile_name,
client=boto3_client, client=boto3_client,
model_id=self.model_id, model_id=self.model_id,
endpoint_url=self.endpoint_url, endpoint_url=self.endpoint_url,
region_name=self.region_name, region_name=self.region_name,
) # type: ignore ) # type: ignore
return output

View file

@ -71,8 +71,7 @@ class HuggingFaceInferenceAPIEmbeddingsComponent(LCEmbeddingsModel):
def get_api_url(self) -> str: def get_api_url(self) -> str:
if "huggingface" in self.inference_endpoint.lower(): if "huggingface" in self.inference_endpoint.lower():
return f"{self.inference_endpoint}{self.model_name}" return f"{self.inference_endpoint}{self.model_name}"
else: return self.inference_endpoint
return self.inference_endpoint
@retry(stop=stop_after_attempt(3), wait=wait_fixed(2)) @retry(stop=stop_after_attempt(3), wait=wait_fixed(2))
def create_huggingface_embeddings( def create_huggingface_embeddings(

View file

@ -54,8 +54,7 @@ class AIMLEmbeddingsImpl(BaseModel, Embeddings):
json=payload, json=payload,
) )
response.raise_for_status() response.raise_for_status()
result_data = response.json() return response.json()
return result_data
def embed_query(self, text: str) -> list[float]: def embed_query(self, text: str) -> list[float]:
return self.embed_documents([text])[0] return self.embed_documents([text])[0]

View file

@ -71,5 +71,4 @@ class ParseJSONDataComponent(Component):
results = jq.compile(self.query).input_text(full_filter_str).all() results = jq.compile(self.query).input_text(full_filter_str).all()
print("results: ", results) print("results: ", results)
docs = [Data(data=value) if isinstance(value, dict) else Data(text=str(value)) for value in results] return [Data(data=value) if isinstance(value, dict) else Data(text=str(value)) for value in results]
return docs

View file

@ -21,7 +21,6 @@ class TextInputComponent(TextComponent):
] ]
def text_response(self) -> Message: def text_response(self) -> Message:
message = Message( return Message(
text=self.input_value, text=self.input_value,
) )
return message

View file

@ -86,5 +86,4 @@ class FirecrawlCrawlApi(CustomComponent):
idempotency_key, idempotency_key,
) )
records = Data(data={"results": crawl_result}) return Data(data={"results": crawl_result})
return records

View file

@ -74,5 +74,4 @@ class FirecrawlScrapeApi(CustomComponent):
}, },
) )
record = Data(data=results) return Data(data=results)
return record

View file

@ -59,7 +59,7 @@ class AstraDBChatMemory(LCChatMemoryComponent):
) )
raise ImportError(msg) raise ImportError(msg)
memory = AstraDBChatMessageHistory( return AstraDBChatMessageHistory(
session_id=self.session_id, session_id=self.session_id,
collection_name=self.collection_name, collection_name=self.collection_name,
token=self.token, token=self.token,
@ -67,4 +67,3 @@ class AstraDBChatMemory(LCChatMemoryComponent):
namespace=self.namespace or None, namespace=self.namespace or None,
environment=parse_api_endpoint(self.api_endpoint).environment, environment=parse_api_endpoint(self.api_endpoint).environment,
) )
return memory

View file

@ -84,7 +84,7 @@ class AIMLModelComponent(LCModelComponent):
else: else:
openai_api_key = aiml_api_key openai_api_key = aiml_api_key
model = ChatOpenAI( return ChatOpenAI(
model=model_name, model=model_name,
temperature=temperature, temperature=temperature,
api_key=openai_api_key, api_key=openai_api_key,
@ -94,8 +94,6 @@ class AIMLModelComponent(LCModelComponent):
**model_kwargs, **model_kwargs,
) )
return model # type: ignore
def _get_exception_message(self, e: Exception): def _get_exception_message(self, e: Exception):
""" """
Get a message from an OpenAI exception. Get a message from an OpenAI exception.

View file

@ -41,9 +41,7 @@ class CohereComponent(LCModelComponent):
else: else:
api_key = None api_key = None
output = ChatCohere( return ChatCohere(
temperature=temperature or 0.75, temperature=temperature or 0.75,
cohere_api_key=api_key, cohere_api_key=api_key,
) )
return output # type: ignore

View file

@ -74,7 +74,7 @@ class GoogleGenerativeAIComponent(LCModelComponent):
top_p = self.top_p top_p = self.top_p
n = self.n n = self.n
output = ChatGoogleGenerativeAI( # type: ignore return ChatGoogleGenerativeAI( # type: ignore
model=model, model=model,
max_output_tokens=max_output_tokens or None, max_output_tokens=max_output_tokens or None,
temperature=temperature, temperature=temperature,
@ -83,5 +83,3 @@ class GoogleGenerativeAIComponent(LCModelComponent):
n=n or 1, n=n or 1,
google_api_key=SecretStr(google_api_key), google_api_key=SecretStr(google_api_key),
) )
return output # type: ignore

View file

@ -93,7 +93,7 @@ class GroqModel(LCModelComponent):
n = self.n n = self.n
stream = self.stream stream = self.stream
output = ChatGroq( # type: ignore return ChatGroq( # type: ignore
model=model_name, model=model_name,
max_tokens=max_tokens or None, max_tokens=max_tokens or None,
temperature=temperature, temperature=temperature,
@ -102,5 +102,3 @@ class GroqModel(LCModelComponent):
api_key=SecretStr(groq_api_key), api_key=SecretStr(groq_api_key),
streaming=stream, streaming=stream,
) )
return output # type: ignore

View file

@ -51,8 +51,7 @@ class HuggingFaceEndpointsComponent(LCModelComponent):
def get_api_url(self) -> str: def get_api_url(self) -> str:
if "huggingface" in self.inference_endpoint.lower(): if "huggingface" in self.inference_endpoint.lower():
return f"{self.inference_endpoint}{self.model_id}" return f"{self.inference_endpoint}{self.model_id}"
else: return self.inference_endpoint
return self.inference_endpoint
def create_huggingface_endpoint( def create_huggingface_endpoint(
self, self,

View file

@ -51,10 +51,9 @@ class MaritalkModelComponent(LCModelComponent):
model_name: str = self.model_name model_name: str = self.model_name
max_tokens = self.max_tokens max_tokens = self.max_tokens
output = ChatMaritalk( return ChatMaritalk(
max_tokens=max_tokens, max_tokens=max_tokens,
model=model_name, model=model_name,
api_key=api_key, api_key=api_key,
temperature=temperature or 0.1, temperature=temperature or 0.1,
) )
return output # type: ignore

View file

@ -83,7 +83,7 @@ class MistralAIModelComponent(LCModelComponent):
else: else:
api_key = None api_key = None
output = ChatMistralAI( return ChatMistralAI(
max_tokens=max_tokens or None, max_tokens=max_tokens or None,
model_name=model_name, model_name=model_name,
endpoint=mistral_api_base, endpoint=mistral_api_base,
@ -96,5 +96,3 @@ class MistralAIModelComponent(LCModelComponent):
random_seed=random_seed, random_seed=random_seed,
safe_mode=safe_mode, safe_mode=safe_mode,
) )
return output # type: ignore

View file

@ -80,7 +80,7 @@ class NVIDIAModelComponent(LCModelComponent):
model_name: str = self.model_name model_name: str = self.model_name
max_tokens = self.max_tokens max_tokens = self.max_tokens
seed = self.seed seed = self.seed
output = ChatNVIDIA( return ChatNVIDIA(
max_tokens=max_tokens or None, max_tokens=max_tokens or None,
model=model_name, model=model_name,
base_url=self.base_url, base_url=self.base_url,
@ -88,4 +88,3 @@ class NVIDIAModelComponent(LCModelComponent):
temperature=temperature or 0.1, temperature=temperature or 0.1,
seed=seed, seed=seed,
) )
return output # type: ignore

View file

@ -64,8 +64,7 @@ class ChatOllamaComponent(LCModelComponent):
response.raise_for_status() response.raise_for_status()
data = response.json() data = response.json()
model_names = [model["name"] for model in data.get("models", [])] return [model["name"] for model in data.get("models", [])]
return model_names
except Exception as e: except Exception as e:
msg = "Could not retrieve models. Please, make sure Ollama is running." msg = "Could not retrieve models. Please, make sure Ollama is running."
raise ValueError(msg) from e raise ValueError(msg) from e

View file

@ -137,9 +137,9 @@ class OpenAIModelComponent(LCModelComponent):
try: try:
from openai import BadRequestError from openai import BadRequestError
except ImportError: except ImportError:
return return None
if isinstance(e, BadRequestError): if isinstance(e, BadRequestError):
message = e.body.get("message") # type: ignore message = e.body.get("message") # type: ignore
if message: if message:
return message return message
return return None

View file

@ -79,7 +79,7 @@ class PerplexityComponent(LCModelComponent):
top_p = self.top_p top_p = self.top_p
n = self.n n = self.n
output = ChatPerplexity( return ChatPerplexity(
model=model, model=model,
temperature=temperature or 0.75, temperature=temperature or 0.75,
pplx_api_key=api_key, pplx_api_key=api_key,
@ -88,5 +88,3 @@ class PerplexityComponent(LCModelComponent):
n=n or 1, n=n or 1,
max_output_tokens=max_output_tokens, max_output_tokens=max_output_tokens,
) )
return output # type: ignore

View file

@ -114,6 +114,4 @@ class LangChainHubPromptComponent(Component):
raise ValueError(msg) raise ValueError(msg)
# Pull the prompt from LangChain Hub # Pull the prompt from LangChain Hub
prompt_data = langchain.hub.pull(self.langchain_hub_prompt, api_key=self.langchain_api_key) return langchain.hub.pull(self.langchain_hub_prompt, api_key=self.langchain_api_key)
return prompt_data

View file

@ -54,13 +54,13 @@ class ConditionalRouterComponent(Component):
if operator == "equals": if operator == "equals":
return input_text == match_text return input_text == match_text
elif operator == "not equals": if operator == "not equals":
return input_text != match_text return input_text != match_text
elif operator == "contains": if operator == "contains":
return match_text in input_text return match_text in input_text
elif operator == "starts with": if operator == "starts with":
return input_text.startswith(match_text) return input_text.startswith(match_text)
elif operator == "ends with": if operator == "ends with":
return input_text.endswith(match_text) return input_text.endswith(match_text)
return False return False
@ -69,15 +69,13 @@ class ConditionalRouterComponent(Component):
if result: if result:
self.status = self.message self.status = self.message
return self.message return self.message
else: self.stop("true_result")
self.stop("true_result") return None # type: ignore
return None # type: ignore
def false_response(self) -> Message: def false_response(self) -> Message:
result = self.evaluate_condition(self.input_text, self.match_text, self.operator, self.case_sensitive) result = self.evaluate_condition(self.input_text, self.match_text, self.operator, self.case_sensitive)
if not result: if not result:
self.status = self.message self.status = self.message
return self.message return self.message
else: self.stop("false_result")
self.stop("false_result") return None # type: ignore
return None # type: ignore

View file

@ -43,8 +43,7 @@ class PythonFunctionComponent(Component):
def get_function_callable(self) -> Callable: def get_function_callable(self) -> Callable:
function_code = self.function_code function_code = self.function_code
self.status = function_code self.status = function_code
func = get_function(function_code) return get_function(function_code)
return func
def execute_function(self) -> list[dotdict | str] | dotdict | str: def execute_function(self) -> list[dotdict | str] | dotdict | str:
function_code = self.function_code function_code = self.function_code
@ -61,13 +60,11 @@ class PythonFunctionComponent(Component):
def execute_function_data(self) -> list[Data]: def execute_function_data(self) -> list[Data]:
results = self.execute_function() results = self.execute_function()
results = results if isinstance(results, list) else [results] results = results if isinstance(results, list) else [results]
data = [(Data(text=x) if isinstance(x, str) else Data(**x)) for x in results] return [(Data(text=x) if isinstance(x, str) else Data(**x)) for x in results]
return data
def execute_function_message(self) -> Message: def execute_function_message(self) -> Message:
results = self.execute_function() results = self.execute_function()
results = results if isinstance(results, list) else [results] results = results if isinstance(results, list) else [results]
results_list = [str(x) for x in results] results_list = [str(x) for x in results]
results_str = "\n".join(results_list) results_str = "\n".join(results_list)
data = Message(text=results_str) return Message(text=results_str)
return data

View file

@ -123,8 +123,7 @@ class RunnableExecComponent(Component):
if self.use_stream: if self.use_stream:
return self.astream_events(input_dict) return self.astream_events(input_dict)
else: result = await self.runnable.ainvoke(input_dict)
result = await self.runnable.ainvoke(input_dict)
result_value, _status = self.get_output(result, self.input_key, self.output_key) result_value, _status = self.get_output(result, self.input_key, self.output_key)
status += _status status += _status
status += f"\n\nOutput: {result_value}\n\nRaw Output: {result}" status += f"\n\nOutput: {result_value}\n\nRaw Output: {result}"

View file

@ -45,8 +45,5 @@ class MultiQueryRetrieverComponent(CustomComponent):
) -> MultiQueryRetriever: ) -> MultiQueryRetriever:
if not prompt: if not prompt:
return MultiQueryRetriever.from_llm(llm=llm, retriever=retriever, parser_key=parser_key) return MultiQueryRetriever.from_llm(llm=llm, retriever=retriever, parser_key=parser_key)
else: prompt_template = PromptTemplate.from_template(prompt)
prompt_template = PromptTemplate.from_template(prompt) return MultiQueryRetriever.from_llm(llm=llm, retriever=retriever, prompt=prompt_template, parser_key=parser_key)
return MultiQueryRetriever.from_llm(
llm=llm, retriever=retriever, prompt=prompt_template, parser_key=parser_key
)

View file

@ -84,8 +84,7 @@ class ComposioAPIComponent(LCToolComponent):
auth_schemes = toolset.client.apps.get(app).auth_schemes auth_schemes = toolset.client.apps.get(app).auth_schemes
if auth_schemes[0].auth_mode == "API_KEY": if auth_schemes[0].auth_mode == "API_KEY":
return self._process_api_key_auth(entity, app) return self._process_api_key_auth(entity, app)
else: return self._initiate_default_connection(entity, app)
return self._initiate_default_connection(entity, app)
except Exception as exc: except Exception as exc:
logger.error(f"Authorization error: {str(exc)}") logger.error(f"Authorization error: {str(exc)}")
return "Error" return "Error"
@ -108,18 +107,16 @@ class ComposioAPIComponent(LCToolComponent):
if is_different_app or is_url or is_default_api_key_message: if is_different_app or is_url or is_default_api_key_message:
return "Enter API Key" return "Enter API Key"
else: if not is_default_api_key_message:
if not is_default_api_key_message: entity.initiate_connection(
entity.initiate_connection( app_name=app,
app_name=app, auth_mode="API_KEY",
auth_mode="API_KEY", auth_config={"api_key": self.auth_status_config},
auth_config={"api_key": self.auth_status_config}, use_composio_auth=False,
use_composio_auth=False, force_new_integration=True,
force_new_integration=True, )
) return f"{app} CONNECTED"
return f"{app} CONNECTED" return "Enter API Key"
else:
return "Enter API Key"
def _initiate_default_connection(self, entity: Any, app: str) -> str: def _initiate_default_connection(self, entity: Any, app: str) -> str:
connection = entity.initiate_connection(app_name=app, use_composio_auth=True, force_new_integration=True) connection = entity.initiate_connection(app_name=app, use_composio_auth=True, force_new_integration=True)
@ -169,8 +166,7 @@ class ComposioAPIComponent(LCToolComponent):
def build_tool(self) -> Sequence[Tool]: def build_tool(self) -> Sequence[Tool]:
composio_toolset = self._build_wrapper() composio_toolset = self._build_wrapper()
composio_tools = composio_toolset.get_tools(actions=self.action_names) return composio_toolset.get_tools(actions=self.action_names)
return composio_tools
def _build_wrapper(self) -> ComposioToolSet: def _build_wrapper(self) -> ComposioToolSet:
return ComposioToolSet(api_key=self.api_key) return ComposioToolSet(api_key=self.api_key)

View file

@ -52,12 +52,11 @@ class CalculatorToolComponent(LCToolComponent):
def eval_expr(node): def eval_expr(node):
if isinstance(node, ast.Num): if isinstance(node, ast.Num):
return node.n return node.n
elif isinstance(node, ast.BinOp): if isinstance(node, ast.BinOp):
return operators[type(node.op)](eval_expr(node.left), eval_expr(node.right)) return operators[type(node.op)](eval_expr(node.left), eval_expr(node.right))
elif isinstance(node, ast.UnaryOp): if isinstance(node, ast.UnaryOp):
return operators[type(node.op)](eval_expr(node.operand)) return operators[type(node.op)](eval_expr(node.operand))
else: raise TypeError(node)
raise TypeError(node)
# Parse the expression and evaluate it # Parse the expression and evaluate it
tree = ast.parse(expression, mode="eval") tree = ast.parse(expression, mode="eval")

View file

@ -200,14 +200,13 @@ class PythonCodeStructuredTool(LCToolComponent):
if schema_fields: if schema_fields:
PythonCodeToolSchema = create_model("PythonCodeToolSchema", **schema_fields) # type: ignore PythonCodeToolSchema = create_model("PythonCodeToolSchema", **schema_fields) # type: ignore
tool = StructuredTool.from_function( return StructuredTool.from_function(
func=_local[self.tool_function].run, func=_local[self.tool_function].run,
args_schema=PythonCodeToolSchema, args_schema=PythonCodeToolSchema,
name=self.tool_name, name=self.tool_name,
description=self.tool_description, description=self.tool_description,
return_direct=self.return_direct, return_direct=self.return_direct,
) )
return tool # type: ignore
def post_code_processing(self, new_frontend_node: dict, current_frontend_node: dict): def post_code_processing(self, new_frontend_node: dict, current_frontend_node: dict):
""" """

View file

@ -132,11 +132,10 @@ class SearXNGToolComponent(LCToolComponent):
SearxSearchSchema = create_model("SearxSearchSchema", **schema_fields) # type: ignore SearxSearchSchema = create_model("SearxSearchSchema", **schema_fields) # type: ignore
tool = StructuredTool.from_function( return StructuredTool.from_function(
func=_local["SearxSearch"].search, func=_local["SearxSearch"].search,
args_schema=SearxSearchSchema, args_schema=SearxSearchSchema,
name="searxng_search_tool", name="searxng_search_tool",
description="A tool that searches for tools using SearXNG.\nThe available categories are: " description="A tool that searches for tools using SearXNG.\nThe available categories are: "
+ ", ".join(self.categories), + ", ".join(self.categories),
) )
return tool

View file

@ -454,10 +454,9 @@ class AstraVectorStoreComponent(LCVectorStoreComponent):
def _map_search_type(self): def _map_search_type(self):
if self.search_type == "Similarity with score threshold": if self.search_type == "Similarity with score threshold":
return "similarity_score_threshold" return "similarity_score_threshold"
elif self.search_type == "MMR (Max Marginal Relevance)": if self.search_type == "MMR (Max Marginal Relevance)":
return "mmr" return "mmr"
else: return "similarity"
return "similarity"
def _build_search_args(self): def _build_search_args(self):
args = { args = {
@ -495,9 +494,8 @@ class AstraVectorStoreComponent(LCVectorStoreComponent):
logger.debug(f"Converted documents to data: {len(data)}") logger.debug(f"Converted documents to data: {len(data)}")
self.status = data self.status = data
return data return data
else: logger.debug("No search input provided. Skipping search.")
logger.debug("No search input provided. Skipping search.") return []
return []
def get_retriever_kwargs(self): def get_retriever_kwargs(self):
search_args = self._build_search_args() search_args = self._build_search_args()

View file

@ -212,10 +212,9 @@ class CassandraVectorStoreComponent(LCVectorStoreComponent):
def _map_search_type(self): def _map_search_type(self):
if self.search_type == "Similarity with score threshold": if self.search_type == "Similarity with score threshold":
return "similarity_score_threshold" return "similarity_score_threshold"
elif self.search_type == "MMR (Max Marginal Relevance)": if self.search_type == "MMR (Max Marginal Relevance)":
return "mmr" return "mmr"
else: return "similarity"
return "similarity"
def search_documents(self) -> list[Data]: def search_documents(self) -> list[Data]:
vector_store = self.build_vector_store() vector_store = self.build_vector_store()
@ -239,16 +238,14 @@ class CassandraVectorStoreComponent(LCVectorStoreComponent):
"Your collection does not contain a field name 'content'." "Your collection does not contain a field name 'content'."
) )
raise ValueError(msg) raise ValueError(msg)
else: raise e
raise e
logger.debug(f"Retrieved documents: {len(docs)}") logger.debug(f"Retrieved documents: {len(docs)}")
data = docs_to_data(docs) data = docs_to_data(docs)
self.status = data self.status = data
return data return data
else: return []
return []
def _build_search_args(self): def _build_search_args(self):
args = { args = {

View file

@ -187,14 +187,13 @@ class CassandraGraphVectorStoreComponent(LCVectorStoreComponent):
def _map_search_type(self): def _map_search_type(self):
if self.search_type == "Similarity": if self.search_type == "Similarity":
return "similarity" return "similarity"
elif self.search_type == "Similarity with score threshold": if self.search_type == "Similarity with score threshold":
return "similarity_score_threshold" return "similarity_score_threshold"
elif self.search_type == "MMR (Max Marginal Relevance)": if self.search_type == "MMR (Max Marginal Relevance)":
return "mmr" return "mmr"
elif self.search_type == "MMR Traversal": if self.search_type == "MMR Traversal":
return "mmr_traversal" return "mmr_traversal"
else: return "traversal"
return "traversal"
def search_documents(self) -> list[Data]: def search_documents(self) -> list[Data]:
vector_store = self.build_vector_store() vector_store = self.build_vector_store()
@ -218,16 +217,14 @@ class CassandraGraphVectorStoreComponent(LCVectorStoreComponent):
"Your collection does not contain a field name 'content'." "Your collection does not contain a field name 'content'."
) )
raise ValueError(msg) from e raise ValueError(msg) from e
else: raise e
raise e
logger.debug(f"Retrieved documents: {len(docs)}") logger.debug(f"Retrieved documents: {len(docs)}")
data = docs_to_data(docs) data = docs_to_data(docs)
self.status = data self.status = data
return data return data
else: return []
return []
def _build_search_args(self): def _build_search_args(self):
args = { args = {

View file

@ -131,5 +131,4 @@ class ClickhouseVectorStoreComponent(LCVectorStoreComponent):
data = docs_to_data(docs) data = docs_to_data(docs)
self.status = data self.status = data
return data return data
else: return []
return []

View file

@ -103,5 +103,4 @@ class CouchbaseVectorStoreComponent(LCVectorStoreComponent):
data = docs_to_data(docs) data = docs_to_data(docs)
self.status = data self.status = data
return data return data
else: return []
return []

View file

@ -114,6 +114,5 @@ class FaissVectorStoreComponent(LCVectorStoreComponent):
logger.debug(f"Converted documents to data: {len(data)}") logger.debug(f"Converted documents to data: {len(data)}")
logger.debug(data) logger.debug(data)
return data # Return the search results data return data # Return the search results data
else: logger.debug("No search input provided. Skipping search.")
logger.debug("No search input provided. Skipping search.") return []
return []

View file

@ -275,10 +275,9 @@ class HCDVectorStoreComponent(LCVectorStoreComponent):
def _map_search_type(self): def _map_search_type(self):
if self.search_type == "Similarity with score threshold": if self.search_type == "Similarity with score threshold":
return "similarity_score_threshold" return "similarity_score_threshold"
elif self.search_type == "MMR (Max Marginal Relevance)": if self.search_type == "MMR (Max Marginal Relevance)":
return "mmr" return "mmr"
else: return "similarity"
return "similarity"
def _build_search_args(self): def _build_search_args(self):
args = { args = {
@ -315,9 +314,8 @@ class HCDVectorStoreComponent(LCVectorStoreComponent):
logger.debug(f"Converted documents to data: {len(data)}") logger.debug(f"Converted documents to data: {len(data)}")
self.status = data self.status = data
return data return data
else: logger.debug("No search input provided. Skipping search.")
logger.debug("No search input provided. Skipping search.") return []
return []
def get_retriever_kwargs(self): def get_retriever_kwargs(self):
search_args = self._build_search_args() search_args = self._build_search_args()

View file

@ -119,5 +119,4 @@ class MilvusVectorStoreComponent(LCVectorStoreComponent):
data = docs_to_data(docs) data = docs_to_data(docs)
self.status = data self.status = data
return data return data
else: return []
return []

View file

@ -93,5 +93,4 @@ class MongoVectorStoreComponent(LCVectorStoreComponent):
data = docs_to_data(docs) data = docs_to_data(docs)
self.status = data self.status = data
return data return data
else: return []
return []

View file

@ -95,5 +95,4 @@ class PineconeVectorStoreComponent(LCVectorStoreComponent):
data = docs_to_data(docs) data = docs_to_data(docs)
self.status = data self.status = data
return data return data
else: return []
return []

View file

@ -110,5 +110,4 @@ class QdrantVectorStoreComponent(LCVectorStoreComponent):
data = docs_to_data(docs) data = docs_to_data(docs)
self.status = data self.status = data
return data return data
else: return []
return []

View file

@ -90,5 +90,4 @@ class RedisVectorStoreComponent(LCVectorStoreComponent):
data = docs_to_data(docs) data = docs_to_data(docs)
self.status = data self.status = data
return data return data
else: return []
return []

View file

@ -76,5 +76,4 @@ class SupabaseVectorStoreComponent(LCVectorStoreComponent):
data = docs_to_data(docs) data = docs_to_data(docs)
self.status = data self.status = data
return data return data
else: return []
return []

View file

@ -125,5 +125,4 @@ class UpstashVectorStoreComponent(LCVectorStoreComponent):
data = docs_to_data(docs) data = docs_to_data(docs)
self.status = data self.status = data
return data return data
else: return []
return []

View file

@ -106,6 +106,5 @@ class VectaraVectorStoreComponent(LCVectorStoreComponent):
data = docs_to_data(docs) data = docs_to_data(docs)
self.status = f"Found {len(data)} results for the query: {self.search_query}" self.status = f"Found {len(data)} results for the query: {self.search_query}"
return data return data
else: self.status = "No search query provided"
self.status = "No search query provided" return []
return []

View file

@ -89,5 +89,4 @@ class WeaviateVectorStoreComponent(LCVectorStoreComponent):
data = docs_to_data(docs) data = docs_to_data(docs)
self.status = data self.status = data
return data return data
else: return []
return []

View file

@ -73,5 +73,4 @@ class PGVectorStoreComponent(LCVectorStoreComponent):
data = docs_to_data(docs) data = docs_to_data(docs)
self.status = data self.status = data
return data return data
else: return []
return []

View file

@ -10,7 +10,7 @@ def validate_icon(value: str, *args, **kwargs):
if not value.startswith(":") and not value.endswith(":"): if not value.startswith(":") and not value.endswith(":"):
return value return value
elif not value.startswith(":") or not value.endswith(":"): if not value.startswith(":") or not value.endswith(":"):
# emoji should have both starting and ending colons # emoji should have both starting and ending colons
# so if one of them is missing, we will raise # so if one of them is missing, we will raise
msg = f"Invalid emoji. {value} is not a valid emoji." msg = f"Invalid emoji. {value} is not a valid emoji."
@ -30,6 +30,7 @@ def getattr_return_str(value):
def getattr_return_bool(value): def getattr_return_bool(value):
if isinstance(value, bool): if isinstance(value, bool):
return value return value
return None
def getattr_return_list_of_str(value): def getattr_return_list_of_str(value):

View file

@ -218,8 +218,7 @@ class CodeParser:
defaults = missing_defaults + default_values defaults = missing_defaults + default_values
args = [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)]
return args
def parse_varargs(self, node: ast.FunctionDef) -> list[dict[str, Any]]: def parse_varargs(self, node: ast.FunctionDef) -> list[dict[str, Any]]:
""" """
@ -240,8 +239,7 @@ class CodeParser:
ast.unparse(default) if default else None for default in node.args.kw_defaults ast.unparse(default) if default else None for default in node.args.kw_defaults
] ]
args = [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)]
return args
def parse_kwargs(self, node: ast.FunctionDef) -> list[dict[str, Any]]: def parse_kwargs(self, node: ast.FunctionDef) -> list[dict[str, Any]]:
""" """
@ -268,20 +266,19 @@ class CodeParser:
def has_return(node): def has_return(node):
if isinstance(node, ast.Return): if isinstance(node, ast.Return):
return True return True
elif isinstance(node, ast.If): if isinstance(node, ast.If):
return any(has_return(child) for child in node.body) or any(has_return(child) for child in node.orelse) return any(has_return(child) for child in node.body) or any(has_return(child) for child in node.orelse)
elif isinstance(node, ast.Try): if isinstance(node, ast.Try):
return ( return (
any(has_return(child) for child in node.body) any(has_return(child) for child in node.body)
or any(has_return(child) for child in node.handlers) or any(has_return(child) for child in node.handlers)
or any(has_return(child) for child in node.finalbody) or any(has_return(child) for child in node.finalbody)
) )
elif isinstance(node, ast.For | ast.While): if isinstance(node, ast.For | ast.While):
return any(has_return(child) for child in node.body) or any(has_return(child) for child in node.orelse) return any(has_return(child) for child in node.body) or any(has_return(child) for child in node.orelse)
elif isinstance(node, ast.With): if isinstance(node, ast.With):
return any(has_return(child) for child in node.body) return any(has_return(child) for child in node.body)
else: return False
return False
return any(has_return(child) for child in node.body) return any(has_return(child) for child in node.body)
@ -293,6 +290,7 @@ class CodeParser:
for target in stmt.targets: for target in stmt.targets:
if isinstance(target, ast.Name): if isinstance(target, ast.Name):
return {"name": target.id, "value": ast.unparse(stmt.value)} return {"name": target.id, "value": ast.unparse(stmt.value)}
return None
def parse_ann_assign(self, stmt): def parse_ann_assign(self, stmt):
""" """
@ -305,6 +303,7 @@ class CodeParser:
"value": ast.unparse(stmt.value) if stmt.value else None, "value": ast.unparse(stmt.value) if stmt.value else None,
"annotation": ast.unparse(stmt.annotation), "annotation": ast.unparse(stmt.annotation),
} }
return None
def parse_function_def(self, stmt): def parse_function_def(self, stmt):
""" """

View file

@ -98,8 +98,7 @@ class BaseComponent:
cc_class = eval_custom_component_code(self._code) cc_class = eval_custom_component_code(self._code)
component_instance = cc_class(_code=self._code) component_instance = cc_class(_code=self._code)
template_config = self.get_template_config(component_instance) return self.get_template_config(component_instance)
return template_config
def build(self, *args: Any, **kwargs: Any) -> Any: def build(self, *args: Any, **kwargs: Any) -> Any:
raise NotImplementedError raise NotImplementedError

View file

@ -318,18 +318,16 @@ class Component(CustomComponent):
def _inherits_from_component(self, method: Callable): def _inherits_from_component(self, method: Callable):
# check if the method is a method from a class that inherits from Component # check if the method is a method from a class that inherits from Component
# and that it is an output of that class # and that it is an output of that class
inherits_from_component = hasattr(method, "__self__") and isinstance(method.__self__, Component) return hasattr(method, "__self__") and isinstance(method.__self__, Component)
return inherits_from_component
def _method_is_valid_output(self, method: Callable): def _method_is_valid_output(self, method: Callable):
# check if the method is a method from a class that inherits from Component # check if the method is a method from a class that inherits from Component
# and that it is an output of that class # and that it is an output of that class
method_is_output = ( return (
hasattr(method, "__self__") hasattr(method, "__self__")
and isinstance(method.__self__, Component) and isinstance(method.__self__, Component)
and method.__self__.get_output_by_method(method) and method.__self__.get_output_by_method(method)
) )
return method_is_output
def _build_error_string_from_matching_pairs(self, matching_pairs: list[tuple[Output, Input]]): def _build_error_string_from_matching_pairs(self, matching_pairs: list[tuple[Output, Input]]):
text = "" text = ""
@ -558,7 +556,7 @@ class Component(CustomComponent):
frontend_node.validate_component() frontend_node.validate_component()
frontend_node.set_base_classes_from_outputs() frontend_node.set_base_classes_from_outputs()
data = { return {
"data": { "data": {
"node": frontend_node.to_dict(keep_name=False), "node": frontend_node.to_dict(keep_name=False),
"type": self.name or self.__class__.__name__, "type": self.name or self.__class__.__name__,
@ -566,7 +564,6 @@ class Component(CustomComponent):
}, },
"id": self._id, "id": self._id,
} }
return data
def _validate_inputs(self, params: dict): def _validate_inputs(self, params: dict):
# Params keys are the `name` attribute of the Input objects # Params keys are the `name` attribute of the Input objects
@ -732,8 +729,7 @@ class Component(CustomComponent):
self.inputs = self.template_config.get("inputs", []) self.inputs = self.template_config.get("inputs", [])
if not self.inputs: if not self.inputs:
return {} return {}
build_config = {_input.name: _input.model_dump(by_alias=True, exclude_none=True) for _input in self.inputs} return {_input.name: _input.model_dump(by_alias=True, exclude_none=True) for _input in self.inputs}
return build_config
def _get_field_order(self): def _get_field_order(self):
try: try:

View file

@ -531,10 +531,9 @@ class CustomComponent(BaseComponent):
""" """
This function is called after the code validation is done. This function is called after the code validation is done.
""" """
frontend_node = update_frontend_node_with_template_values( return update_frontend_node_with_template_values(
frontend_node=new_frontend_node, raw_frontend_node=current_frontend_node frontend_node=new_frontend_node, raw_frontend_node=current_frontend_node
) )
return frontend_node
def get_langchain_callbacks(self) -> list[BaseCallbackHandler]: def get_langchain_callbacks(self) -> list[BaseCallbackHandler]:
if self._tracing_service: if self._tracing_service:

View file

@ -222,21 +222,20 @@ class DirectoryReader:
if file_content is None: if file_content is None:
return False, f"Could not read {file_path}" return False, f"Could not read {file_path}"
elif self.is_empty_file(file_content): if self.is_empty_file(file_content):
return False, "Empty file" return False, "Empty file"
elif not self.validate_code(file_content): if not self.validate_code(file_content):
return False, "Syntax error" return False, "Syntax error"
elif self._is_type_hint_used_in_args("Optional", file_content) and not self._is_type_hint_imported( if self._is_type_hint_used_in_args("Optional", file_content) and not self._is_type_hint_imported(
"Optional", file_content "Optional", file_content
): ):
return ( return (
False, False,
"Type hint 'Optional' is used but not imported in the code.", "Type hint 'Optional' is used but not imported in the code.",
) )
else: if self.compress_code_field:
if self.compress_code_field: file_content = str(StringCompressor(file_content).compress_string())
file_content = str(StringCompressor(file_content).compress_string()) return True, file_content
return True, file_content
def build_component_menu_list(self, file_paths): def build_component_menu_list(self, file_paths):
""" """
@ -300,21 +299,20 @@ class DirectoryReader:
if file_content is None: if file_content is None:
return False, f"Could not read {file_path}" return False, f"Could not read {file_path}"
elif self.is_empty_file(file_content): if self.is_empty_file(file_content):
return False, "Empty file" return False, "Empty file"
elif not self.validate_code(file_content): if not self.validate_code(file_content):
return False, "Syntax error" return False, "Syntax error"
elif self._is_type_hint_used_in_args("Optional", file_content) and not self._is_type_hint_imported( if self._is_type_hint_used_in_args("Optional", file_content) and not self._is_type_hint_imported(
"Optional", file_content "Optional", file_content
): ):
return ( return (
False, False,
"Type hint 'Optional' is used but not imported in the code.", "Type hint 'Optional' is used but not imported in the code.",
) )
else: if self.compress_code_field:
if self.compress_code_field: file_content = str(StringCompressor(file_content).compress_string())
file_content = str(StringCompressor(file_content).compress_string()) return True, file_content
return True, file_content
async def get_output_types_from_code_async(self, code: str): async def get_output_types_from_code_async(self, code: str):
return await asyncio.to_thread(self.get_output_types_from_code, code) return await asyncio.to_thread(self.get_output_types_from_code, code)

View file

@ -256,9 +256,8 @@ def run_build_inputs(
): ):
"""Run the build inputs of a custom component.""" """Run the build inputs of a custom component."""
try: try:
field_config = custom_component.build_inputs(user_id=user_id) return custom_component.build_inputs(user_id=user_id)
# add_extra_fields(frontend_node, field_config, field_config.values()) # add_extra_fields(frontend_node, field_config, field_config.values())
return field_config
except Exception as exc: except Exception as exc:
logger.error(f"Error running build inputs: {exc}") logger.error(f"Error running build inputs: {exc}")
raise HTTPException(status_code=500, detail=str(exc)) from exc raise HTTPException(status_code=500, detail=str(exc)) from exc
@ -269,7 +268,7 @@ def get_component_instance(custom_component: CustomComponent, user_id: str | UUI
if custom_component._code is None: if custom_component._code is None:
msg = "Code is None" msg = "Code is None"
raise ValueError(msg) raise ValueError(msg)
elif isinstance(custom_component._code, str): if isinstance(custom_component._code, str):
custom_class = eval_custom_component_code(custom_component._code) custom_class = eval_custom_component_code(custom_component._code)
else: else:
msg = "Invalid code type" msg = "Invalid code type"
@ -285,8 +284,7 @@ def get_component_instance(custom_component: CustomComponent, user_id: str | UUI
) from exc ) from exc
try: try:
custom_instance = custom_class(_user_id=user_id, _code=custom_component._code) return custom_class(_user_id=user_id, _code=custom_component._code)
return custom_instance
except Exception as exc: except Exception as exc:
logger.error(f"Error while instantiating custom component: {str(exc)}") logger.error(f"Error while instantiating custom component: {str(exc)}")
if hasattr(exc, "detail") and "traceback" in exc.detail: if hasattr(exc, "detail") and "traceback" in exc.detail:
@ -305,7 +303,7 @@ def run_build_config(
if custom_component._code is None: if custom_component._code is None:
msg = "Code is None" msg = "Code is None"
raise ValueError(msg) raise ValueError(msg)
elif isinstance(custom_component._code, str): if isinstance(custom_component._code, str):
custom_class = eval_custom_component_code(custom_component._code) custom_class = eval_custom_component_code(custom_component._code)
else: else:
msg = "Invalid code type" msg = "Invalid code type"

View file

@ -31,5 +31,4 @@ class APIException(HTTPException):
outdated_components = get_outdated_components(flow) outdated_components = get_outdated_components(flow)
if outdated_components: if outdated_components:
body["suggestion"] = get_suggestion_message(outdated_components) body["suggestion"] = get_suggestion_message(outdated_components)
excep = ExceptionBody(**body) return ExceptionBody(**body)
return excep

View file

@ -48,7 +48,7 @@ def __getattr__(name: str) -> Any:
if name == "Input": if name == "Input":
return _import_input_class() return _import_input_class()
return RangeSpec return RangeSpec
elif name == "Output": if name == "Output":
return _import_output_class() return _import_output_class()
# The other names should work as if they were imported from constants # The other names should work as if they were imported from constants
# Import the constants module langflow.field_typing.constants # Import the constants module langflow.field_typing.constants

View file

@ -35,14 +35,12 @@ class Edge:
"might not be a valid input." "might not be a valid input."
) )
raise ValueError(msg) from e raise ValueError(msg) from e
else: msg = (
msg = ( f"Field '{self._target_handle['fieldName']}' on {target.display_name} "
f"Field '{self._target_handle['fieldName']}' on {target.display_name} " "might not be a valid input."
"might not be a valid input." )
) raise ValueError(msg) from e
raise ValueError(msg) from e raise e
else:
raise e
else: else:
msg = "Target handle is not a dictionary" msg = "Target handle is not a dictionary"

Some files were not shown because too many files have changed in this diff Show more