lfx-nightly 0.2.0.dev0__py3-none-any.whl → 0.2.0.dev26__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- lfx/_assets/component_index.json +1 -1
- lfx/base/agents/agent.py +13 -1
- lfx/base/agents/altk_base_agent.py +380 -0
- lfx/base/agents/altk_tool_wrappers.py +565 -0
- lfx/base/agents/events.py +2 -1
- lfx/base/composio/composio_base.py +159 -224
- lfx/base/data/base_file.py +88 -21
- lfx/base/data/storage_utils.py +192 -0
- lfx/base/data/utils.py +178 -14
- lfx/base/embeddings/embeddings_class.py +113 -0
- lfx/base/models/groq_constants.py +74 -58
- lfx/base/models/groq_model_discovery.py +265 -0
- lfx/base/models/model.py +1 -1
- lfx/base/models/model_utils.py +100 -0
- lfx/base/models/openai_constants.py +7 -0
- lfx/base/models/watsonx_constants.py +32 -8
- lfx/base/tools/run_flow.py +601 -129
- lfx/cli/commands.py +6 -3
- lfx/cli/common.py +2 -2
- lfx/cli/run.py +1 -1
- lfx/cli/script_loader.py +53 -11
- lfx/components/Notion/create_page.py +1 -1
- lfx/components/Notion/list_database_properties.py +1 -1
- lfx/components/Notion/list_pages.py +1 -1
- lfx/components/Notion/list_users.py +1 -1
- lfx/components/Notion/page_content_viewer.py +1 -1
- lfx/components/Notion/search.py +1 -1
- lfx/components/Notion/update_page_property.py +1 -1
- lfx/components/__init__.py +19 -5
- lfx/components/{agents → altk}/__init__.py +5 -9
- lfx/components/altk/altk_agent.py +193 -0
- lfx/components/apify/apify_actor.py +1 -1
- lfx/components/composio/__init__.py +70 -18
- lfx/components/composio/apollo_composio.py +11 -0
- lfx/components/composio/bitbucket_composio.py +11 -0
- lfx/components/composio/canva_composio.py +11 -0
- lfx/components/composio/coda_composio.py +11 -0
- lfx/components/composio/composio_api.py +10 -0
- lfx/components/composio/discord_composio.py +1 -1
- lfx/components/composio/elevenlabs_composio.py +11 -0
- lfx/components/composio/exa_composio.py +11 -0
- lfx/components/composio/firecrawl_composio.py +11 -0
- lfx/components/composio/fireflies_composio.py +11 -0
- lfx/components/composio/gmail_composio.py +1 -1
- lfx/components/composio/googlebigquery_composio.py +11 -0
- lfx/components/composio/googlecalendar_composio.py +1 -1
- lfx/components/composio/googledocs_composio.py +1 -1
- lfx/components/composio/googlemeet_composio.py +1 -1
- lfx/components/composio/googlesheets_composio.py +1 -1
- lfx/components/composio/googletasks_composio.py +1 -1
- lfx/components/composio/heygen_composio.py +11 -0
- lfx/components/composio/mem0_composio.py +11 -0
- lfx/components/composio/peopledatalabs_composio.py +11 -0
- lfx/components/composio/perplexityai_composio.py +11 -0
- lfx/components/composio/serpapi_composio.py +11 -0
- lfx/components/composio/slack_composio.py +3 -574
- lfx/components/composio/slackbot_composio.py +1 -1
- lfx/components/composio/snowflake_composio.py +11 -0
- lfx/components/composio/tavily_composio.py +11 -0
- lfx/components/composio/youtube_composio.py +2 -2
- lfx/components/cuga/__init__.py +34 -0
- lfx/components/cuga/cuga_agent.py +730 -0
- lfx/components/data/__init__.py +78 -28
- lfx/components/data_source/__init__.py +58 -0
- lfx/components/{data → data_source}/api_request.py +26 -3
- lfx/components/{data → data_source}/csv_to_data.py +15 -10
- lfx/components/{data → data_source}/json_to_data.py +15 -8
- lfx/components/{data → data_source}/news_search.py +1 -1
- lfx/components/{data → data_source}/rss.py +1 -1
- lfx/components/{data → data_source}/sql_executor.py +1 -1
- lfx/components/{data → data_source}/url.py +1 -1
- lfx/components/{data → data_source}/web_search.py +1 -1
- lfx/components/datastax/astradb_cql.py +1 -1
- lfx/components/datastax/astradb_graph.py +1 -1
- lfx/components/datastax/astradb_tool.py +1 -1
- lfx/components/datastax/astradb_vectorstore.py +1 -1
- lfx/components/datastax/hcd.py +1 -1
- lfx/components/deactivated/json_document_builder.py +1 -1
- lfx/components/docling/__init__.py +0 -3
- lfx/components/elastic/elasticsearch.py +1 -1
- lfx/components/elastic/opensearch_multimodal.py +1575 -0
- lfx/components/files_and_knowledge/__init__.py +47 -0
- lfx/components/{data → files_and_knowledge}/directory.py +1 -1
- lfx/components/{data → files_and_knowledge}/file.py +246 -18
- lfx/components/{knowledge_bases → files_and_knowledge}/retrieval.py +2 -2
- lfx/components/{data → files_and_knowledge}/save_file.py +142 -22
- lfx/components/flow_controls/__init__.py +58 -0
- lfx/components/{logic → flow_controls}/conditional_router.py +1 -1
- lfx/components/{logic → flow_controls}/loop.py +43 -9
- lfx/components/flow_controls/run_flow.py +108 -0
- lfx/components/glean/glean_search_api.py +1 -1
- lfx/components/groq/groq.py +35 -28
- lfx/components/helpers/__init__.py +102 -0
- lfx/components/input_output/__init__.py +3 -1
- lfx/components/input_output/chat.py +4 -3
- lfx/components/input_output/chat_output.py +4 -4
- lfx/components/input_output/text.py +1 -1
- lfx/components/input_output/text_output.py +1 -1
- lfx/components/{data → input_output}/webhook.py +1 -1
- lfx/components/knowledge_bases/__init__.py +59 -4
- lfx/components/langchain_utilities/character.py +1 -1
- lfx/components/langchain_utilities/csv_agent.py +84 -16
- lfx/components/langchain_utilities/json_agent.py +67 -12
- lfx/components/langchain_utilities/language_recursive.py +1 -1
- lfx/components/llm_operations/__init__.py +46 -0
- lfx/components/{processing → llm_operations}/batch_run.py +1 -1
- lfx/components/{processing → llm_operations}/lambda_filter.py +1 -1
- lfx/components/{logic → llm_operations}/llm_conditional_router.py +1 -1
- lfx/components/{processing/llm_router.py → llm_operations/llm_selector.py} +3 -3
- lfx/components/{processing → llm_operations}/structured_output.py +1 -1
- lfx/components/logic/__init__.py +126 -0
- lfx/components/mem0/mem0_chat_memory.py +11 -0
- lfx/components/models/__init__.py +64 -9
- lfx/components/models_and_agents/__init__.py +49 -0
- lfx/components/{agents → models_and_agents}/agent.py +2 -2
- lfx/components/models_and_agents/embedding_model.py +423 -0
- lfx/components/models_and_agents/language_model.py +398 -0
- lfx/components/{agents → models_and_agents}/mcp_component.py +53 -44
- lfx/components/{helpers → models_and_agents}/memory.py +1 -1
- lfx/components/nvidia/system_assist.py +1 -1
- lfx/components/olivya/olivya.py +1 -1
- lfx/components/ollama/ollama.py +17 -3
- lfx/components/processing/__init__.py +9 -57
- lfx/components/processing/converter.py +1 -1
- lfx/components/processing/dataframe_operations.py +1 -1
- lfx/components/processing/parse_json_data.py +2 -2
- lfx/components/processing/parser.py +1 -1
- lfx/components/processing/split_text.py +1 -1
- lfx/components/qdrant/qdrant.py +1 -1
- lfx/components/redis/redis.py +1 -1
- lfx/components/twelvelabs/split_video.py +10 -0
- lfx/components/twelvelabs/video_file.py +12 -0
- lfx/components/utilities/__init__.py +43 -0
- lfx/components/{helpers → utilities}/calculator_core.py +1 -1
- lfx/components/{helpers → utilities}/current_date.py +1 -1
- lfx/components/{processing → utilities}/python_repl_core.py +1 -1
- lfx/components/vectorstores/local_db.py +9 -0
- lfx/components/youtube/youtube_transcripts.py +118 -30
- lfx/custom/custom_component/component.py +57 -1
- lfx/custom/custom_component/custom_component.py +68 -6
- lfx/graph/edge/base.py +43 -20
- lfx/graph/graph/base.py +4 -1
- lfx/graph/state/model.py +15 -2
- lfx/graph/utils.py +6 -0
- lfx/graph/vertex/base.py +4 -1
- lfx/graph/vertex/param_handler.py +10 -7
- lfx/helpers/__init__.py +12 -0
- lfx/helpers/flow.py +117 -0
- lfx/inputs/input_mixin.py +24 -1
- lfx/inputs/inputs.py +13 -1
- lfx/interface/components.py +161 -83
- lfx/log/logger.py +5 -3
- lfx/services/database/__init__.py +5 -0
- lfx/services/database/service.py +25 -0
- lfx/services/deps.py +87 -22
- lfx/services/manager.py +19 -6
- lfx/services/mcp_composer/service.py +998 -157
- lfx/services/session.py +5 -0
- lfx/services/settings/base.py +51 -7
- lfx/services/settings/constants.py +8 -0
- lfx/services/storage/local.py +76 -46
- lfx/services/storage/service.py +152 -29
- lfx/template/field/base.py +3 -0
- lfx/utils/ssrf_protection.py +384 -0
- lfx/utils/validate_cloud.py +26 -0
- {lfx_nightly-0.2.0.dev0.dist-info → lfx_nightly-0.2.0.dev26.dist-info}/METADATA +38 -22
- {lfx_nightly-0.2.0.dev0.dist-info → lfx_nightly-0.2.0.dev26.dist-info}/RECORD +182 -150
- {lfx_nightly-0.2.0.dev0.dist-info → lfx_nightly-0.2.0.dev26.dist-info}/WHEEL +1 -1
- lfx/components/agents/altk_agent.py +0 -366
- lfx/components/agents/cuga_agent.py +0 -1013
- lfx/components/docling/docling_remote_vlm.py +0 -284
- lfx/components/logic/run_flow.py +0 -71
- lfx/components/models/embedding_model.py +0 -195
- lfx/components/models/language_model.py +0 -144
- /lfx/components/{data → data_source}/mock_data.py +0 -0
- /lfx/components/{knowledge_bases → files_and_knowledge}/ingestion.py +0 -0
- /lfx/components/{logic → flow_controls}/data_conditional_router.py +0 -0
- /lfx/components/{logic → flow_controls}/flow_tool.py +0 -0
- /lfx/components/{logic → flow_controls}/listen.py +0 -0
- /lfx/components/{logic → flow_controls}/notify.py +0 -0
- /lfx/components/{logic → flow_controls}/pass_message.py +0 -0
- /lfx/components/{logic → flow_controls}/sub_flow.py +0 -0
- /lfx/components/{processing → models_and_agents}/prompt.py +0 -0
- /lfx/components/{helpers → processing}/create_list.py +0 -0
- /lfx/components/{helpers → processing}/output_parser.py +0 -0
- /lfx/components/{helpers → processing}/store_message.py +0 -0
- /lfx/components/{helpers → utilities}/id_generator.py +0 -0
- {lfx_nightly-0.2.0.dev0.dist-info → lfx_nightly-0.2.0.dev26.dist-info}/entry_points.txt +0 -0
lfx/components/data/__init__.py
CHANGED
|
@@ -1,34 +1,28 @@
|
|
|
1
|
+
"""Data module - backwards compatibility alias for data_source.
|
|
2
|
+
|
|
3
|
+
This module provides backwards compatibility by forwarding all imports
|
|
4
|
+
to data_source where the actual data components are located.
|
|
5
|
+
"""
|
|
6
|
+
|
|
1
7
|
from __future__ import annotations
|
|
2
8
|
|
|
3
|
-
from typing import
|
|
9
|
+
from typing import Any
|
|
4
10
|
|
|
5
11
|
from lfx.components._importing import import_mod
|
|
6
12
|
|
|
7
|
-
|
|
8
|
-
from lfx.components.data.api_request import APIRequestComponent
|
|
9
|
-
from lfx.components.data.csv_to_data import CSVToDataComponent
|
|
10
|
-
from lfx.components.data.directory import DirectoryComponent
|
|
11
|
-
from lfx.components.data.file import FileComponent
|
|
12
|
-
from lfx.components.data.json_to_data import JSONToDataComponent
|
|
13
|
-
from lfx.components.data.news_search import NewsSearchComponent
|
|
14
|
-
from lfx.components.data.rss import RSSReaderComponent
|
|
15
|
-
from lfx.components.data.sql_executor import SQLComponent
|
|
16
|
-
from lfx.components.data.url import URLComponent
|
|
17
|
-
from lfx.components.data.web_search import WebSearchComponent
|
|
18
|
-
from lfx.components.data.webhook import WebhookComponent
|
|
19
|
-
|
|
13
|
+
# Replicate the same dynamic imports as data_source
|
|
20
14
|
_dynamic_imports = {
|
|
21
15
|
"APIRequestComponent": "api_request",
|
|
22
16
|
"CSVToDataComponent": "csv_to_data",
|
|
23
|
-
"DirectoryComponent": "directory",
|
|
24
|
-
"FileComponent": "file",
|
|
25
17
|
"JSONToDataComponent": "json_to_data",
|
|
26
|
-
"
|
|
27
|
-
"URLComponent": "url",
|
|
28
|
-
"WebSearchComponent": "web_search",
|
|
29
|
-
"WebhookComponent": "webhook",
|
|
18
|
+
"MockDataGeneratorComponent": "mock_data",
|
|
30
19
|
"NewsSearchComponent": "news_search",
|
|
31
20
|
"RSSReaderComponent": "rss",
|
|
21
|
+
"URLComponent": "url",
|
|
22
|
+
"WebSearchComponent": "web_search",
|
|
23
|
+
# File and Directory components are in files_and_knowledge, forward them for backwards compatibility
|
|
24
|
+
"FileComponent": ("file", "files_and_knowledge"),
|
|
25
|
+
"DirectoryComponent": ("directory", "files_and_knowledge"),
|
|
32
26
|
}
|
|
33
27
|
|
|
34
28
|
__all__ = [
|
|
@@ -37,28 +31,84 @@ __all__ = [
|
|
|
37
31
|
"DirectoryComponent",
|
|
38
32
|
"FileComponent",
|
|
39
33
|
"JSONToDataComponent",
|
|
34
|
+
"MockDataGeneratorComponent",
|
|
40
35
|
"NewsSearchComponent",
|
|
41
36
|
"RSSReaderComponent",
|
|
42
|
-
"SQLComponent",
|
|
43
37
|
"URLComponent",
|
|
44
38
|
"WebSearchComponent",
|
|
45
|
-
"WebhookComponent",
|
|
46
39
|
]
|
|
47
40
|
|
|
48
41
|
|
|
49
42
|
def __getattr__(attr_name: str) -> Any:
|
|
50
|
-
"""
|
|
43
|
+
"""Forward attribute access to data_source components."""
|
|
44
|
+
# Handle submodule access for backwards compatibility
|
|
45
|
+
# e.g., lfx.components.data.directory -> lfx.components.files_and_knowledge.directory
|
|
46
|
+
if attr_name == "directory":
|
|
47
|
+
from importlib import import_module
|
|
48
|
+
|
|
49
|
+
result = import_module("lfx.components.files_and_knowledge.directory")
|
|
50
|
+
globals()[attr_name] = result
|
|
51
|
+
return result
|
|
52
|
+
if attr_name == "file":
|
|
53
|
+
from importlib import import_module
|
|
54
|
+
|
|
55
|
+
result = import_module("lfx.components.files_and_knowledge.file")
|
|
56
|
+
globals()[attr_name] = result
|
|
57
|
+
return result
|
|
58
|
+
# Data source components were moved to data_source
|
|
59
|
+
if attr_name == "news_search":
|
|
60
|
+
from importlib import import_module
|
|
61
|
+
|
|
62
|
+
result = import_module("lfx.components.data_source.news_search")
|
|
63
|
+
globals()[attr_name] = result
|
|
64
|
+
return result
|
|
65
|
+
if attr_name == "rss":
|
|
66
|
+
from importlib import import_module
|
|
67
|
+
|
|
68
|
+
result = import_module("lfx.components.data_source.rss")
|
|
69
|
+
globals()[attr_name] = result
|
|
70
|
+
return result
|
|
71
|
+
if attr_name == "web_search":
|
|
72
|
+
from importlib import import_module
|
|
73
|
+
|
|
74
|
+
result = import_module("lfx.components.data_source.web_search")
|
|
75
|
+
globals()[attr_name] = result
|
|
76
|
+
return result
|
|
77
|
+
# SQLComponent was moved to utilities
|
|
78
|
+
if attr_name == "sql_executor":
|
|
79
|
+
from importlib import import_module
|
|
80
|
+
|
|
81
|
+
result = import_module("lfx.components.utilities.sql_executor")
|
|
82
|
+
globals()[attr_name] = result
|
|
83
|
+
return result
|
|
84
|
+
|
|
51
85
|
if attr_name not in _dynamic_imports:
|
|
52
86
|
msg = f"module '{__name__}' has no attribute '{attr_name}'"
|
|
53
87
|
raise AttributeError(msg)
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
88
|
+
|
|
89
|
+
mapping = _dynamic_imports[attr_name]
|
|
90
|
+
|
|
91
|
+
# Handle FileComponent and DirectoryComponent which are in files_and_knowledge
|
|
92
|
+
if isinstance(mapping, tuple):
|
|
93
|
+
module_name, package = mapping
|
|
94
|
+
try:
|
|
95
|
+
result = import_mod(attr_name, module_name, f"lfx.components.{package}")
|
|
96
|
+
except (ModuleNotFoundError, ImportError, AttributeError) as e:
|
|
97
|
+
msg = f"Could not import '{attr_name}' from '{__name__}': {e}"
|
|
98
|
+
raise AttributeError(msg) from e
|
|
99
|
+
else:
|
|
100
|
+
# Import from data_source using the correct package path
|
|
101
|
+
package = "lfx.components.data_source"
|
|
102
|
+
try:
|
|
103
|
+
result = import_mod(attr_name, mapping, package)
|
|
104
|
+
except (ModuleNotFoundError, ImportError, AttributeError) as e:
|
|
105
|
+
msg = f"Could not import '{attr_name}' from '{__name__}': {e}"
|
|
106
|
+
raise AttributeError(msg) from e
|
|
107
|
+
|
|
59
108
|
globals()[attr_name] = result
|
|
60
109
|
return result
|
|
61
110
|
|
|
62
111
|
|
|
63
112
|
def __dir__() -> list[str]:
|
|
113
|
+
"""Return directory of available components."""
|
|
64
114
|
return list(__all__)
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
from typing import TYPE_CHECKING, Any
|
|
4
|
+
|
|
5
|
+
from lfx.components._importing import import_mod
|
|
6
|
+
|
|
7
|
+
if TYPE_CHECKING:
|
|
8
|
+
from lfx.components.data_source.api_request import APIRequestComponent
|
|
9
|
+
from lfx.components.data_source.csv_to_data import CSVToDataComponent
|
|
10
|
+
from lfx.components.data_source.json_to_data import JSONToDataComponent
|
|
11
|
+
from lfx.components.data_source.mock_data import MockDataGeneratorComponent
|
|
12
|
+
from lfx.components.data_source.news_search import NewsSearchComponent
|
|
13
|
+
from lfx.components.data_source.rss import RSSReaderComponent
|
|
14
|
+
from lfx.components.data_source.sql_executor import SQLComponent
|
|
15
|
+
from lfx.components.data_source.url import URLComponent
|
|
16
|
+
from lfx.components.data_source.web_search import WebSearchComponent
|
|
17
|
+
|
|
18
|
+
_dynamic_imports = {
|
|
19
|
+
"APIRequestComponent": "api_request",
|
|
20
|
+
"CSVToDataComponent": "csv_to_data",
|
|
21
|
+
"JSONToDataComponent": "json_to_data",
|
|
22
|
+
"MockDataGeneratorComponent": "mock_data",
|
|
23
|
+
"NewsSearchComponent": "news_search",
|
|
24
|
+
"RSSReaderComponent": "rss",
|
|
25
|
+
"URLComponent": "url",
|
|
26
|
+
"WebSearchComponent": "web_search",
|
|
27
|
+
"SQLComponent": "sql_executor",
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
__all__ = [
|
|
31
|
+
"APIRequestComponent",
|
|
32
|
+
"CSVToDataComponent",
|
|
33
|
+
"JSONToDataComponent",
|
|
34
|
+
"MockDataGeneratorComponent",
|
|
35
|
+
"NewsSearchComponent",
|
|
36
|
+
"RSSReaderComponent",
|
|
37
|
+
"SQLComponent",
|
|
38
|
+
"URLComponent",
|
|
39
|
+
"WebSearchComponent",
|
|
40
|
+
]
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
def __getattr__(attr_name: str) -> Any:
|
|
44
|
+
"""Lazily import data source components on attribute access."""
|
|
45
|
+
if attr_name not in _dynamic_imports:
|
|
46
|
+
msg = f"module '{__name__}' has no attribute '{attr_name}'"
|
|
47
|
+
raise AttributeError(msg)
|
|
48
|
+
try:
|
|
49
|
+
result = import_mod(attr_name, _dynamic_imports[attr_name], __spec__.parent)
|
|
50
|
+
except (ModuleNotFoundError, ImportError, AttributeError) as e:
|
|
51
|
+
msg = f"Could not import '{attr_name}' from '{__name__}': {e}"
|
|
52
|
+
raise AttributeError(msg) from e
|
|
53
|
+
globals()[attr_name] = result
|
|
54
|
+
return result
|
|
55
|
+
|
|
56
|
+
|
|
57
|
+
def __dir__() -> list[str]:
|
|
58
|
+
return list(__all__)
|
|
@@ -27,6 +27,7 @@ from lfx.io import (
|
|
|
27
27
|
from lfx.schema.data import Data
|
|
28
28
|
from lfx.schema.dotdict import dotdict
|
|
29
29
|
from lfx.utils.component_utils import set_current_fields, set_field_advanced, set_field_display
|
|
30
|
+
from lfx.utils.ssrf_protection import SSRFProtectionError, validate_url_for_ssrf
|
|
30
31
|
|
|
31
32
|
# Define fields for each mode
|
|
32
33
|
MODE_FIELDS = {
|
|
@@ -44,7 +45,7 @@ DEFAULT_FIELDS = ["mode"]
|
|
|
44
45
|
class APIRequestComponent(Component):
|
|
45
46
|
display_name = "API Request"
|
|
46
47
|
description = "Make HTTP requests using URL or cURL commands."
|
|
47
|
-
documentation: str = "https://docs.langflow.org/
|
|
48
|
+
documentation: str = "https://docs.langflow.org/api-request"
|
|
48
49
|
icon = "Globe"
|
|
49
50
|
name = "APIRequest"
|
|
50
51
|
|
|
@@ -145,8 +146,13 @@ class APIRequestComponent(Component):
|
|
|
145
146
|
BoolInput(
|
|
146
147
|
name="follow_redirects",
|
|
147
148
|
display_name="Follow Redirects",
|
|
148
|
-
value=
|
|
149
|
-
info=
|
|
149
|
+
value=False,
|
|
150
|
+
info=(
|
|
151
|
+
"Whether to follow HTTP redirects. "
|
|
152
|
+
"WARNING: Enabling redirects may allow SSRF bypass attacks where a public URL "
|
|
153
|
+
"redirects to internal resources. Only enable if you trust the target server. "
|
|
154
|
+
"See OWASP SSRF Prevention Cheat Sheet for details."
|
|
155
|
+
),
|
|
150
156
|
advanced=True,
|
|
151
157
|
),
|
|
152
158
|
BoolInput(
|
|
@@ -424,6 +430,14 @@ class APIRequestComponent(Component):
|
|
|
424
430
|
save_to_file = self.save_to_file
|
|
425
431
|
include_httpx_metadata = self.include_httpx_metadata
|
|
426
432
|
|
|
433
|
+
# Security warning when redirects are enabled
|
|
434
|
+
if follow_redirects:
|
|
435
|
+
self.log(
|
|
436
|
+
"Security Warning: HTTP redirects are enabled. This may allow SSRF bypass attacks "
|
|
437
|
+
"where a public URL redirects to internal resources (e.g., cloud metadata endpoints). "
|
|
438
|
+
"Only enable this if you trust the target server."
|
|
439
|
+
)
|
|
440
|
+
|
|
427
441
|
# if self.mode == "cURL" and self.curl_input:
|
|
428
442
|
# self._build_config = self.parse_curl(self.curl_input, dotdict())
|
|
429
443
|
# # After parsing curl, get the normalized URL
|
|
@@ -437,6 +451,15 @@ class APIRequestComponent(Component):
|
|
|
437
451
|
msg = f"Invalid URL provided: {url}"
|
|
438
452
|
raise ValueError(msg)
|
|
439
453
|
|
|
454
|
+
# SSRF Protection: Validate URL to prevent access to internal resources
|
|
455
|
+
# TODO: In next major version (2.0), remove warn_only=True to enforce blocking
|
|
456
|
+
try:
|
|
457
|
+
validate_url_for_ssrf(url, warn_only=True)
|
|
458
|
+
except SSRFProtectionError as e:
|
|
459
|
+
# This will only raise if SSRF protection is enabled and warn_only=False
|
|
460
|
+
msg = f"SSRF Protection: {e}"
|
|
461
|
+
raise ValueError(msg) from e
|
|
462
|
+
|
|
440
463
|
# Process query parameters
|
|
441
464
|
if isinstance(self.query_params, str):
|
|
442
465
|
query_params = dict(parse_qsl(self.query_params))
|
|
@@ -2,9 +2,11 @@ import csv
|
|
|
2
2
|
import io
|
|
3
3
|
from pathlib import Path
|
|
4
4
|
|
|
5
|
+
from lfx.base.data.storage_utils import read_file_text
|
|
5
6
|
from lfx.custom.custom_component.component import Component
|
|
6
7
|
from lfx.io import FileInput, MessageTextInput, MultilineInput, Output
|
|
7
8
|
from lfx.schema.data import Data
|
|
9
|
+
from lfx.utils.async_helpers import run_until_complete
|
|
8
10
|
|
|
9
11
|
|
|
10
12
|
class CSVToDataComponent(Component):
|
|
@@ -52,21 +54,24 @@ class CSVToDataComponent(Component):
|
|
|
52
54
|
csv_data = None
|
|
53
55
|
try:
|
|
54
56
|
if self.csv_file:
|
|
55
|
-
|
|
56
|
-
file_path =
|
|
57
|
-
if file_path.
|
|
57
|
+
# FileInput always provides a local file path
|
|
58
|
+
file_path = self.csv_file
|
|
59
|
+
if not file_path.lower().endswith(".csv"):
|
|
58
60
|
self.status = "The provided file must be a CSV file."
|
|
59
61
|
else:
|
|
60
|
-
|
|
61
|
-
|
|
62
|
+
# Resolve to absolute path and read from local filesystem
|
|
63
|
+
resolved_path = self.resolve_path(file_path)
|
|
64
|
+
csv_bytes = Path(resolved_path).read_bytes()
|
|
65
|
+
csv_data = csv_bytes.decode("utf-8")
|
|
62
66
|
|
|
63
67
|
elif self.csv_path:
|
|
64
|
-
file_path =
|
|
65
|
-
if file_path.
|
|
66
|
-
self.status = "The provided
|
|
68
|
+
file_path = self.csv_path
|
|
69
|
+
if not file_path.lower().endswith(".csv"):
|
|
70
|
+
self.status = "The provided path must be to a CSV file."
|
|
67
71
|
else:
|
|
68
|
-
|
|
69
|
-
|
|
72
|
+
csv_data = run_until_complete(
|
|
73
|
+
read_file_text(file_path, encoding="utf-8", resolve_path=self.resolve_path, newline="")
|
|
74
|
+
)
|
|
70
75
|
|
|
71
76
|
else:
|
|
72
77
|
csv_data = self.csv_string
|
|
@@ -3,9 +3,11 @@ from pathlib import Path
|
|
|
3
3
|
|
|
4
4
|
from json_repair import repair_json
|
|
5
5
|
|
|
6
|
+
from lfx.base.data.storage_utils import read_file_text
|
|
6
7
|
from lfx.custom.custom_component.component import Component
|
|
7
8
|
from lfx.io import FileInput, MessageTextInput, MultilineInput, Output
|
|
8
9
|
from lfx.schema.data import Data
|
|
10
|
+
from lfx.utils.async_helpers import run_until_complete
|
|
9
11
|
|
|
10
12
|
|
|
11
13
|
class JSONToDataComponent(Component):
|
|
@@ -51,19 +53,24 @@ class JSONToDataComponent(Component):
|
|
|
51
53
|
|
|
52
54
|
try:
|
|
53
55
|
if self.json_file:
|
|
54
|
-
|
|
55
|
-
file_path =
|
|
56
|
-
if file_path.
|
|
56
|
+
# FileInput always provides a local file path
|
|
57
|
+
file_path = self.json_file
|
|
58
|
+
if not file_path.lower().endswith(".json"):
|
|
57
59
|
self.status = "The provided file must be a JSON file."
|
|
58
60
|
else:
|
|
59
|
-
|
|
61
|
+
# Resolve to absolute path and read from local filesystem
|
|
62
|
+
resolved_path = self.resolve_path(file_path)
|
|
63
|
+
json_data = Path(resolved_path).read_text(encoding="utf-8")
|
|
60
64
|
|
|
61
65
|
elif self.json_path:
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
66
|
+
# User-provided text path - could be local or S3 key
|
|
67
|
+
file_path = self.json_path
|
|
68
|
+
if not file_path.lower().endswith(".json"):
|
|
69
|
+
self.status = "The provided path must be to a JSON file."
|
|
65
70
|
else:
|
|
66
|
-
json_data =
|
|
71
|
+
json_data = run_until_complete(
|
|
72
|
+
read_file_text(file_path, encoding="utf-8", resolve_path=self.resolve_path)
|
|
73
|
+
)
|
|
67
74
|
|
|
68
75
|
else:
|
|
69
76
|
json_data = self.json_string
|
|
@@ -12,7 +12,7 @@ from lfx.schema import DataFrame
|
|
|
12
12
|
class NewsSearchComponent(Component):
|
|
13
13
|
display_name = "News Search"
|
|
14
14
|
description = "Searches Google News via RSS. Returns clean article data."
|
|
15
|
-
documentation: str = "https://docs.langflow.org/
|
|
15
|
+
documentation: str = "https://docs.langflow.org/web-search"
|
|
16
16
|
icon = "newspaper"
|
|
17
17
|
name = "NewsSearch"
|
|
18
18
|
legacy = True
|
|
@@ -11,7 +11,7 @@ from lfx.schema import DataFrame
|
|
|
11
11
|
class RSSReaderComponent(Component):
|
|
12
12
|
display_name = "RSS Reader"
|
|
13
13
|
description = "Fetches and parses an RSS feed."
|
|
14
|
-
documentation: str = "https://docs.langflow.org/
|
|
14
|
+
documentation: str = "https://docs.langflow.org/web-search"
|
|
15
15
|
icon = "rss"
|
|
16
16
|
name = "RSSReaderSimple"
|
|
17
17
|
legacy = True
|
|
@@ -18,7 +18,7 @@ class SQLComponent(ComponentWithCache):
|
|
|
18
18
|
|
|
19
19
|
display_name = "SQL Database"
|
|
20
20
|
description = "Executes SQL queries on SQLAlchemy-compatible databases."
|
|
21
|
-
documentation: str = "https://docs.langflow.org/
|
|
21
|
+
documentation: str = "https://docs.langflow.org/sql-database"
|
|
22
22
|
icon = "database"
|
|
23
23
|
name = "SQLComponent"
|
|
24
24
|
metadata = {"keywords": ["sql", "database", "query", "db", "fetch"]}
|
|
@@ -48,7 +48,7 @@ class URLComponent(Component):
|
|
|
48
48
|
|
|
49
49
|
display_name = "URL"
|
|
50
50
|
description = "Fetch content from one or more web pages, following links recursively."
|
|
51
|
-
documentation: str = "https://docs.langflow.org/
|
|
51
|
+
documentation: str = "https://docs.langflow.org/url"
|
|
52
52
|
icon = "layout-template"
|
|
53
53
|
name = "URLComponent"
|
|
54
54
|
|
|
@@ -21,7 +21,7 @@ from lfx.utils.request_utils import get_user_agent
|
|
|
21
21
|
class WebSearchComponent(Component):
|
|
22
22
|
display_name = "Web Search"
|
|
23
23
|
description = "Search the web, news, or RSS feeds."
|
|
24
|
-
documentation: str = "https://docs.langflow.org/
|
|
24
|
+
documentation: str = "https://docs.langflow.org/web-search"
|
|
25
25
|
icon = "search"
|
|
26
26
|
name = "UnifiedWebSearch"
|
|
27
27
|
|
|
@@ -19,7 +19,7 @@ from lfx.schema.table import EditMode
|
|
|
19
19
|
class AstraDBCQLToolComponent(AstraDBBaseComponent, LCToolComponent):
|
|
20
20
|
display_name: str = "Astra DB CQL"
|
|
21
21
|
description: str = "Create a tool to get transactional data from DataStax Astra DB CQL Table"
|
|
22
|
-
documentation: str = "https://docs.langflow.org/bundles-datastax
|
|
22
|
+
documentation: str = "https://docs.langflow.org/bundles-datastax"
|
|
23
23
|
icon: str = "AstraDB"
|
|
24
24
|
|
|
25
25
|
inputs = [
|
|
@@ -17,7 +17,7 @@ class AstraDBGraphVectorStoreComponent(AstraDBBaseComponent, LCVectorStoreCompon
|
|
|
17
17
|
display_name: str = "Astra DB Graph"
|
|
18
18
|
description: str = "Implementation of Graph Vector Store using Astra DB"
|
|
19
19
|
name = "AstraDBGraph"
|
|
20
|
-
documentation: str = "https://docs.langflow.org/bundles-datastax
|
|
20
|
+
documentation: str = "https://docs.langflow.org/bundles-datastax"
|
|
21
21
|
icon: str = "AstraDB"
|
|
22
22
|
legacy: bool = True
|
|
23
23
|
replacement = ["datastax.GraphRAG"]
|
|
@@ -16,7 +16,7 @@ from lfx.schema.table import EditMode
|
|
|
16
16
|
class AstraDBToolComponent(AstraDBBaseComponent, LCToolComponent):
|
|
17
17
|
display_name: str = "Astra DB Tool"
|
|
18
18
|
description: str = "Tool to run hybrid vector and metadata search on DataStax Astra DB Collection"
|
|
19
|
-
documentation: str = "https://docs.langflow.org/bundles-datastax
|
|
19
|
+
documentation: str = "https://docs.langflow.org/bundles-datastax"
|
|
20
20
|
icon: str = "AstraDB"
|
|
21
21
|
legacy: bool = True
|
|
22
22
|
name = "AstraDBTool"
|
|
@@ -15,7 +15,7 @@ from lfx.utils.version import get_version_info
|
|
|
15
15
|
class AstraDBVectorStoreComponent(AstraDBBaseComponent, LCVectorStoreComponent):
|
|
16
16
|
display_name: str = "Astra DB"
|
|
17
17
|
description: str = "Ingest and search documents in Astra DB"
|
|
18
|
-
documentation: str = "https://docs.langflow.org/bundles-datastax
|
|
18
|
+
documentation: str = "https://docs.langflow.org/bundles-datastax"
|
|
19
19
|
name = "AstraDB"
|
|
20
20
|
icon: str = "AstraDB"
|
|
21
21
|
|
lfx/components/datastax/hcd.py
CHANGED
|
@@ -17,7 +17,7 @@ class HCDVectorStoreComponent(LCVectorStoreComponent):
|
|
|
17
17
|
display_name: str = "Hyper-Converged Database"
|
|
18
18
|
description: str = "Implementation of Vector Store using Hyper-Converged Database (HCD) with search capabilities"
|
|
19
19
|
name = "HCD"
|
|
20
|
-
documentation: str = "https://docs.langflow.org/bundles-datastax
|
|
20
|
+
documentation: str = "https://docs.langflow.org/bundles-datastax"
|
|
21
21
|
icon: str = "HCD"
|
|
22
22
|
|
|
23
23
|
inputs = [
|
|
@@ -23,7 +23,7 @@ class JSONDocumentBuilder(CustomComponent):
|
|
|
23
23
|
display_name: str = "JSON Document Builder"
|
|
24
24
|
description: str = "Build a Document containing a JSON object using a key and another Document page content."
|
|
25
25
|
name = "JSONDocumentBuilder"
|
|
26
|
-
documentation: str = "https://docs.langflow.org/
|
|
26
|
+
documentation: str = "https://docs.langflow.org/legacy-core-components"
|
|
27
27
|
legacy = True
|
|
28
28
|
|
|
29
29
|
inputs = [
|
|
@@ -8,7 +8,6 @@ if TYPE_CHECKING:
|
|
|
8
8
|
from .chunk_docling_document import ChunkDoclingDocumentComponent
|
|
9
9
|
from .docling_inline import DoclingInlineComponent
|
|
10
10
|
from .docling_remote import DoclingRemoteComponent
|
|
11
|
-
from .docling_remote_vlm import DoclingRemoteVLMComponent
|
|
12
11
|
from .export_docling_document import ExportDoclingDocumentComponent
|
|
13
12
|
|
|
14
13
|
_dynamic_imports = {
|
|
@@ -16,14 +15,12 @@ _dynamic_imports = {
|
|
|
16
15
|
"DoclingInlineComponent": "docling_inline",
|
|
17
16
|
"DoclingRemoteComponent": "docling_remote",
|
|
18
17
|
"ExportDoclingDocumentComponent": "export_docling_document",
|
|
19
|
-
"DoclingRemoteVLMComponent": "docling_remote_vlm",
|
|
20
18
|
}
|
|
21
19
|
|
|
22
20
|
__all__ = [
|
|
23
21
|
"ChunkDoclingDocumentComponent",
|
|
24
22
|
"DoclingInlineComponent",
|
|
25
23
|
"DoclingRemoteComponent",
|
|
26
|
-
"DoclingRemoteVLMComponent",
|
|
27
24
|
"ExportDoclingDocumentComponent",
|
|
28
25
|
]
|
|
29
26
|
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
from typing import Any
|
|
2
2
|
|
|
3
3
|
from elasticsearch import Elasticsearch
|
|
4
|
-
from
|
|
4
|
+
from langchain_core.documents import Document
|
|
5
5
|
from langchain_elasticsearch import ElasticsearchStore
|
|
6
6
|
|
|
7
7
|
from lfx.base.vectorstores.model import LCVectorStoreComponent, check_cached_vector_store
|