Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view

Large diffs are not rendered by default.

Large diffs are not rendered by default.

Large diffs are not rendered by default.

Large diffs are not rendered by default.

Large diffs are not rendered by default.

Large diffs are not rendered by default.

Large diffs are not rendered by default.

Large diffs are not rendered by default.

Large diffs are not rendered by default.

Large diffs are not rendered by default.

Large diffs are not rendered by default.

Large diffs are not rendered by default.

Large diffs are not rendered by default.

Large diffs are not rendered by default.

Large diffs are not rendered by default.

Large diffs are not rendered by default.

Large diffs are not rendered by default.

Large diffs are not rendered by default.

Large diffs are not rendered by default.

Large diffs are not rendered by default.

Large diffs are not rendered by default.

Large diffs are not rendered by default.

Large diffs are not rendered by default.

Large diffs are not rendered by default.

Large diffs are not rendered by default.

Large diffs are not rendered by default.

Large diffs are not rendered by default.

Large diffs are not rendered by default.

Large diffs are not rendered by default.

Large diffs are not rendered by default.

Large diffs are not rendered by default.

Large diffs are not rendered by default.

1,253 changes: 41 additions & 1,212 deletions src/lfx/src/lfx/_assets/component_index.json

Large diffs are not rendered by default.

30 changes: 6 additions & 24 deletions src/lfx/src/lfx/base/data/base_file.py
Original file line number Diff line number Diff line change
Expand Up @@ -158,26 +158,13 @@ def __init__(self, *args, **kwargs):
info="Specify the separator to use between multiple outputs in Message format.",
advanced=True,
),
BoolInput(
name="silent_errors",
display_name="Silent Errors",
advanced=True,
info="If true, errors will not raise an exception.",
),
BoolInput(
name="delete_server_file_after_processing",
display_name="Delete Server File After Processing",
advanced=True,
value=True,
info="If true, the Server File Path will be deleted after processing.",
),
BoolInput(
name="ignore_unsupported_extensions",
display_name="Ignore Unsupported Extensions",
advanced=True,
value=True,
info="If true, files with unsupported extensions will not be processed.",
),
BoolInput(
name="ignore_unspecified_files",
display_name="Ignore Unspecified Files",
Expand Down Expand Up @@ -550,7 +537,7 @@ def _build_data_dict(data_list: list[Data | None], data_list_field: str) -> dict
if key is None:
msg = f"Data object missing required field '{data_list_field}': {data}"
self.log(msg)
if not self.silent_errors:
if not False:
msg = f"Data object missing required field '{data_list_field}': {data}"
self.log(msg)
raise ValueError(msg)
Expand Down Expand Up @@ -591,7 +578,7 @@ def _message_to_data(message: Message) -> Data:
elif not isinstance(file_path, list):
msg = f"Expected list of Data objects in file_path but got {type(file_path)}."
self.log(msg)
if not self.silent_errors:
if not False:
raise ValueError(msg)
return []

Expand All @@ -602,7 +589,7 @@ def _message_to_data(message: Message) -> Data:
if not isinstance(data_obj, Data):
msg = f"Expected Data object in file_path but got {type(data_obj)}."
self.log(msg)
if not self.silent_errors:
if not False:
raise ValueError(msg)
continue
file_paths.append(data_obj)
Expand Down Expand Up @@ -648,7 +635,7 @@ def add_file(data: Data, path: str | Path, *, delete_after_processing: bool):
if not resolved_path.exists():
msg = f"File not found: '{path}' (resolved to: '{resolved_path}'). Please upload the file again."
self.log(msg)
if not self.silent_errors:
if not False:
raise ValueError(msg)
resolved_files.append(
BaseFileComponent.BaseFile(data, resolved_path, delete_after_processing=delete_after_processing)
Expand Down Expand Up @@ -677,7 +664,7 @@ def add_file(data: Data, path: str | Path, *, delete_after_processing: bool):
elif not self.ignore_unspecified_files:
msg = f"Data object missing '{self.SERVER_FILE_PATH_FIELDNAME}' property."
self.log(msg)
if not self.silent_errors:
if not False:
raise ValueError(msg)
else:
msg = f"Ignoring Data object missing '{self.SERVER_FILE_PATH_FIELDNAME}' property:\n{obj}"
Expand Down Expand Up @@ -818,14 +805,9 @@ def _filter_and_mark_files(self, files: list[BaseFile]) -> list[BaseFile]:
# Validate file extension
extension = file.path.suffix[1:].lower() if file.path.suffix else ""
if extension not in self.valid_extensions:
# For local storage, optionally ignore unsupported extensions
if not is_s3_storage and self.ignore_unsupported_extensions:
ignored_files.append(file.path.name)
continue

msg = f"Unsupported file extension: {file.path.suffix}"
self.log(msg)
if not self.silent_errors:
if not False:
raise ValueError(msg)

final_files.append(file)
Expand Down
56 changes: 8 additions & 48 deletions src/lfx/src/lfx/components/data_source/api_request.py
Original file line number Diff line number Diff line change
Expand Up @@ -155,23 +155,6 @@ class APIRequestComponent(Component):
),
advanced=True,
),
BoolInput(
name="save_to_file",
display_name="Save to File",
value=False,
info="Save the API response to a temporary file",
advanced=True,
),
BoolInput(
name="include_httpx_metadata",
display_name="Include HTTPx Metadata",
value=False,
info=(
"Include properties such as headers, status_code, response_headers, "
"and redirection_history in the output."
),
advanced=True,
),
]

outputs = [
Expand Down Expand Up @@ -304,8 +287,6 @@ async def make_request(
timeout: int = 5,
*,
follow_redirects: bool = True,
save_to_file: bool = False,
include_httpx_metadata: bool = False,
) -> Data:
method = method.upper()
if method not in {"GET", "POST", "PATCH", "PUT", "DELETE"}:
Expand Down Expand Up @@ -337,7 +318,7 @@ async def make_request(
for redirect in response.history
]

is_binary, file_path = await self._response_info(response, with_file_path=save_to_file)
is_binary, _ = await self._response_info(response, with_file_path=False)
response_headers = self._headers_to_dict(response.headers)

# Base metadata
Expand All @@ -350,25 +331,6 @@ async def make_request(
if redirection_history:
metadata["redirection_history"] = redirection_history

if save_to_file:
mode = "wb" if is_binary else "w"
encoding = response.encoding if mode == "w" else None
if file_path:
await aiofiles_os.makedirs(file_path.parent, exist_ok=True)
if is_binary:
async with aiofiles.open(file_path, "wb") as f:
await f.write(response.content)
await f.flush()
else:
async with aiofiles.open(file_path, "w", encoding=encoding) as f:
await f.write(response.text)
await f.flush()
metadata["file_path"] = str(file_path)

if include_httpx_metadata:
metadata.update({"headers": headers})
return Data(data=metadata)

# Handle response content
if is_binary:
result = response.content
Expand All @@ -381,9 +343,6 @@ async def make_request(

metadata["result"] = result

if include_httpx_metadata:
metadata.update({"headers": headers})

return Data(data=metadata)
except (httpx.HTTPError, httpx.RequestError, httpx.TimeoutException) as exc:
self.log(f"Error making request to {url}")
Expand Down Expand Up @@ -429,8 +388,6 @@ async def make_api_request(self) -> Data:
body = self.body or {}
timeout = self.timeout
follow_redirects = self.follow_redirects
save_to_file = self.save_to_file
include_httpx_metadata = self.include_httpx_metadata

# Security warning when redirects are enabled
if follow_redirects:
Expand Down Expand Up @@ -482,17 +439,20 @@ async def make_api_request(self) -> Data:
body,
timeout,
follow_redirects=follow_redirects,
save_to_file=save_to_file,
include_httpx_metadata=include_httpx_metadata,
)
self.status = result
return result

def update_build_config(self, build_config: dotdict, field_value: Any, field_name: str | None = None) -> dotdict:
"""Update the build config based on the selected mode."""
if field_name == "curl_input" and self.mode == "cURL" and self.curl_input:
return self.parse_curl(self.curl_input, build_config)

if field_name == "method":
set_field_display(build_config, "query_params", value=(field_value != "GET"))
return build_config

if field_name != "mode":
if field_name == "curl_input" and self.mode == "cURL" and self.curl_input:
return self.parse_curl(self.curl_input, build_config)
return build_config

if field_value == "cURL":
Expand Down
3 changes: 1 addition & 2 deletions src/lfx/src/lfx/components/data_source/sql_executor.py
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,6 @@ def maybe_create_db(self):
inputs = [
MessageTextInput(name="database_url", display_name="Database URL", required=True),
MultilineInput(name="query", display_name="SQL Query", tool_mode=True, required=True),
BoolInput(name="include_columns", display_name="Include Columns", value=True, tool_mode=True, advanced=True),
BoolInput(
name="add_error",
display_name="Add Error",
Expand All @@ -67,7 +66,7 @@ def build_component(
error = None
self.maybe_create_db()
try:
result = self.db.run(self.query, include_columns=self.include_columns)
result = self.db.run(self.query, include_columns=True)
self.status = result
except SQLAlchemyError as e:
msg = f"An error occurred while running the SQL Query: {e}"
Expand Down
46 changes: 4 additions & 42 deletions src/lfx/src/lfx/components/data_source/url.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
from lfx.custom.custom_component.component import Component
from lfx.field_typing.range_spec import RangeSpec
from lfx.helpers.data import safe_convert
from lfx.io import BoolInput, DropdownInput, IntInput, MessageTextInput, Output, SliderInput, TableInput
from lfx.io import BoolInput, DropdownInput, IntInput, MessageTextInput, Output, SliderInput
from lfx.log.logger import logger
from lfx.schema.dataframe import DataFrame
from lfx.schema.message import Message
Expand Down Expand Up @@ -126,28 +126,6 @@ class URLComponent(Component):
required=False,
advanced=True,
),
TableInput(
name="headers",
display_name="Headers",
info="The headers to send with the request",
table_schema=[
{
"name": "key",
"display_name": "Header",
"type": "str",
"description": "Header name",
},
{
"name": "value",
"display_name": "Value",
"type": "str",
"description": "Header value",
},
],
value=[{"key": "User-Agent", "value": USER_AGENT}],
advanced=True,
input_types=["DataFrame", "Table"],
),
BoolInput(
name="filter_text_html",
display_name="Filter Text/HTML",
Expand All @@ -164,22 +142,6 @@ class URLComponent(Component):
required=False,
advanced=True,
),
BoolInput(
name="check_response_status",
display_name="Check Response Status",
info="If enabled, checks the response status of the request.",
value=False,
required=False,
advanced=True,
),
BoolInput(
name="autoset_encoding",
display_name="Autoset Encoding",
info="If enabled, automatically sets the encoding of the request.",
value=True,
required=False,
advanced=True,
),
]

outputs = [
Expand Down Expand Up @@ -247,7 +209,7 @@ def _create_loader(self, url: str) -> RecursiveUrlLoader:
Returns:
RecursiveUrlLoader: Configured loader instance
"""
headers_dict = {header["key"]: header["value"] for header in self.headers if header["value"] is not None}
headers_dict = {"User-Agent": USER_AGENT}
extractors = {
"HTML": self._html_extractor,
"Markdown": self._markdown_extractor,
Expand All @@ -263,10 +225,10 @@ def _create_loader(self, url: str) -> RecursiveUrlLoader:
extractor=extractor,
timeout=self.timeout,
headers=headers_dict,
check_response_status=self.check_response_status,
check_response_status=False,
continue_on_failure=self.continue_on_failure,
base_url=url, # Add base_url to ensure consistent domain crawling
autoset_encoding=self.autoset_encoding, # Enable automatic encoding detection
autoset_encoding=True, # Enable automatic encoding detection
exclude_dirs=[], # Allow customization of excluded directories
link_regex=None, # Allow customization of link filtering
)
Expand Down
10 changes: 0 additions & 10 deletions src/lfx/src/lfx/components/data_source/web_search.py
Original file line number Diff line number Diff line change
Expand Up @@ -60,16 +60,6 @@ class WebSearchComponent(Component):
required=False,
advanced=True,
),
MessageTextInput(
name="ceid",
display_name="Country:Language (ceid)",
info="e.g. US:en, FR:fr. Default: US:en.",
tool_mode=False,
value="US:en",
input_types=[],
required=False,
advanced=True,
),
MessageTextInput(
name="topic",
display_name="Topic",
Expand Down
6 changes: 3 additions & 3 deletions src/lfx/src/lfx/components/files_and_knowledge/file.py
Original file line number Diff line number Diff line change
Expand Up @@ -611,7 +611,7 @@ def _validate_and_resolve_paths(self) -> list[BaseFileComponent.BaseFile]:
if not resolved_path.exists():
msg = f"File or directory not found: {file_path_str}"
self.log(msg)
if not self.silent_errors:
if not False:
raise ValueError(msg)
return []

Expand Down Expand Up @@ -1140,7 +1140,7 @@ def process_files(
)
if not is_valid:
self.log(error_msg)
if not self.silent_errors:
if not False:
raise ValueError(error_msg)
except (OSError, FileNotFoundError) as e:
self.log(f"Could not read file for validation: {e}")
Expand Down Expand Up @@ -1260,7 +1260,7 @@ def process_file_standard(file_path: str, *, silent_errors: bool = False) -> Dat
self.log(f"Starting parallel processing of {len(file_paths)} files with concurrency: {concurrency}.")
my_data = parallel_load_data(
file_paths,
silent_errors=self.silent_errors,
silent_errors=False,
load_function=process_file_standard,
max_concurrency=concurrency,
)
Expand Down
8 changes: 0 additions & 8 deletions src/lfx/src/lfx/components/files_and_knowledge/ingestion.py
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,6 @@ class NewKnowledgeBaseInput:
"field_order": [
"01_new_kb_name",
"02_embedding_model",
"03_api_key",
],
"template": {
"01_new_kb_name": StrInput(
Expand All @@ -103,13 +102,6 @@ class NewKnowledgeBaseInput:
required=True,
model_type="embedding",
),
"03_api_key": SecretStrInput(
name="api_key",
display_name="Embedding Provider API Key",
info="Optional API key override used to validate and save this knowledge base.",
required=False,
advanced=True,
),
},
},
}
Expand Down
Loading
Loading