lfx-nightly 0.2.0.dev25__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.

Potentially problematic release.


This version of lfx-nightly might be problematic. Click here for more details.

Files changed (769) hide show
  1. lfx/__init__.py +0 -0
  2. lfx/__main__.py +25 -0
  3. lfx/_assets/component_index.json +1 -0
  4. lfx/base/__init__.py +0 -0
  5. lfx/base/agents/__init__.py +0 -0
  6. lfx/base/agents/agent.py +375 -0
  7. lfx/base/agents/altk_base_agent.py +380 -0
  8. lfx/base/agents/altk_tool_wrappers.py +565 -0
  9. lfx/base/agents/callback.py +130 -0
  10. lfx/base/agents/context.py +109 -0
  11. lfx/base/agents/crewai/__init__.py +0 -0
  12. lfx/base/agents/crewai/crew.py +231 -0
  13. lfx/base/agents/crewai/tasks.py +12 -0
  14. lfx/base/agents/default_prompts.py +23 -0
  15. lfx/base/agents/errors.py +15 -0
  16. lfx/base/agents/events.py +430 -0
  17. lfx/base/agents/utils.py +237 -0
  18. lfx/base/astra_assistants/__init__.py +0 -0
  19. lfx/base/astra_assistants/util.py +171 -0
  20. lfx/base/chains/__init__.py +0 -0
  21. lfx/base/chains/model.py +19 -0
  22. lfx/base/composio/__init__.py +0 -0
  23. lfx/base/composio/composio_base.py +2584 -0
  24. lfx/base/compressors/__init__.py +0 -0
  25. lfx/base/compressors/model.py +60 -0
  26. lfx/base/constants.py +46 -0
  27. lfx/base/curl/__init__.py +0 -0
  28. lfx/base/curl/parse.py +188 -0
  29. lfx/base/data/__init__.py +5 -0
  30. lfx/base/data/base_file.py +810 -0
  31. lfx/base/data/docling_utils.py +338 -0
  32. lfx/base/data/storage_utils.py +192 -0
  33. lfx/base/data/utils.py +362 -0
  34. lfx/base/datastax/__init__.py +5 -0
  35. lfx/base/datastax/astradb_base.py +896 -0
  36. lfx/base/document_transformers/__init__.py +0 -0
  37. lfx/base/document_transformers/model.py +43 -0
  38. lfx/base/embeddings/__init__.py +0 -0
  39. lfx/base/embeddings/aiml_embeddings.py +62 -0
  40. lfx/base/embeddings/embeddings_class.py +113 -0
  41. lfx/base/embeddings/model.py +26 -0
  42. lfx/base/flow_processing/__init__.py +0 -0
  43. lfx/base/flow_processing/utils.py +86 -0
  44. lfx/base/huggingface/__init__.py +0 -0
  45. lfx/base/huggingface/model_bridge.py +133 -0
  46. lfx/base/io/__init__.py +0 -0
  47. lfx/base/io/chat.py +21 -0
  48. lfx/base/io/text.py +22 -0
  49. lfx/base/knowledge_bases/__init__.py +3 -0
  50. lfx/base/knowledge_bases/knowledge_base_utils.py +137 -0
  51. lfx/base/langchain_utilities/__init__.py +0 -0
  52. lfx/base/langchain_utilities/model.py +35 -0
  53. lfx/base/langchain_utilities/spider_constants.py +1 -0
  54. lfx/base/langwatch/__init__.py +0 -0
  55. lfx/base/langwatch/utils.py +18 -0
  56. lfx/base/mcp/__init__.py +0 -0
  57. lfx/base/mcp/constants.py +2 -0
  58. lfx/base/mcp/util.py +1659 -0
  59. lfx/base/memory/__init__.py +0 -0
  60. lfx/base/memory/memory.py +49 -0
  61. lfx/base/memory/model.py +38 -0
  62. lfx/base/models/__init__.py +3 -0
  63. lfx/base/models/aiml_constants.py +51 -0
  64. lfx/base/models/anthropic_constants.py +51 -0
  65. lfx/base/models/aws_constants.py +151 -0
  66. lfx/base/models/chat_result.py +76 -0
  67. lfx/base/models/cometapi_constants.py +54 -0
  68. lfx/base/models/google_generative_ai_constants.py +70 -0
  69. lfx/base/models/google_generative_ai_model.py +38 -0
  70. lfx/base/models/groq_constants.py +150 -0
  71. lfx/base/models/groq_model_discovery.py +265 -0
  72. lfx/base/models/model.py +375 -0
  73. lfx/base/models/model_input_constants.py +378 -0
  74. lfx/base/models/model_metadata.py +41 -0
  75. lfx/base/models/model_utils.py +108 -0
  76. lfx/base/models/novita_constants.py +35 -0
  77. lfx/base/models/ollama_constants.py +52 -0
  78. lfx/base/models/openai_constants.py +129 -0
  79. lfx/base/models/sambanova_constants.py +18 -0
  80. lfx/base/models/watsonx_constants.py +36 -0
  81. lfx/base/processing/__init__.py +0 -0
  82. lfx/base/prompts/__init__.py +0 -0
  83. lfx/base/prompts/api_utils.py +224 -0
  84. lfx/base/prompts/utils.py +61 -0
  85. lfx/base/textsplitters/__init__.py +0 -0
  86. lfx/base/textsplitters/model.py +28 -0
  87. lfx/base/tools/__init__.py +0 -0
  88. lfx/base/tools/base.py +26 -0
  89. lfx/base/tools/component_tool.py +325 -0
  90. lfx/base/tools/constants.py +49 -0
  91. lfx/base/tools/flow_tool.py +132 -0
  92. lfx/base/tools/run_flow.py +698 -0
  93. lfx/base/vectorstores/__init__.py +0 -0
  94. lfx/base/vectorstores/model.py +193 -0
  95. lfx/base/vectorstores/utils.py +22 -0
  96. lfx/base/vectorstores/vector_store_connection_decorator.py +52 -0
  97. lfx/cli/__init__.py +5 -0
  98. lfx/cli/commands.py +327 -0
  99. lfx/cli/common.py +650 -0
  100. lfx/cli/run.py +506 -0
  101. lfx/cli/script_loader.py +289 -0
  102. lfx/cli/serve_app.py +546 -0
  103. lfx/cli/validation.py +69 -0
  104. lfx/components/FAISS/__init__.py +34 -0
  105. lfx/components/FAISS/faiss.py +111 -0
  106. lfx/components/Notion/__init__.py +19 -0
  107. lfx/components/Notion/add_content_to_page.py +269 -0
  108. lfx/components/Notion/create_page.py +94 -0
  109. lfx/components/Notion/list_database_properties.py +68 -0
  110. lfx/components/Notion/list_pages.py +122 -0
  111. lfx/components/Notion/list_users.py +77 -0
  112. lfx/components/Notion/page_content_viewer.py +93 -0
  113. lfx/components/Notion/search.py +111 -0
  114. lfx/components/Notion/update_page_property.py +114 -0
  115. lfx/components/__init__.py +428 -0
  116. lfx/components/_importing.py +42 -0
  117. lfx/components/agentql/__init__.py +3 -0
  118. lfx/components/agentql/agentql_api.py +151 -0
  119. lfx/components/aiml/__init__.py +37 -0
  120. lfx/components/aiml/aiml.py +115 -0
  121. lfx/components/aiml/aiml_embeddings.py +37 -0
  122. lfx/components/altk/__init__.py +34 -0
  123. lfx/components/altk/altk_agent.py +193 -0
  124. lfx/components/amazon/__init__.py +36 -0
  125. lfx/components/amazon/amazon_bedrock_converse.py +195 -0
  126. lfx/components/amazon/amazon_bedrock_embedding.py +109 -0
  127. lfx/components/amazon/amazon_bedrock_model.py +130 -0
  128. lfx/components/amazon/s3_bucket_uploader.py +211 -0
  129. lfx/components/anthropic/__init__.py +34 -0
  130. lfx/components/anthropic/anthropic.py +187 -0
  131. lfx/components/apify/__init__.py +5 -0
  132. lfx/components/apify/apify_actor.py +325 -0
  133. lfx/components/arxiv/__init__.py +3 -0
  134. lfx/components/arxiv/arxiv.py +169 -0
  135. lfx/components/assemblyai/__init__.py +46 -0
  136. lfx/components/assemblyai/assemblyai_get_subtitles.py +83 -0
  137. lfx/components/assemblyai/assemblyai_lemur.py +183 -0
  138. lfx/components/assemblyai/assemblyai_list_transcripts.py +95 -0
  139. lfx/components/assemblyai/assemblyai_poll_transcript.py +72 -0
  140. lfx/components/assemblyai/assemblyai_start_transcript.py +188 -0
  141. lfx/components/azure/__init__.py +37 -0
  142. lfx/components/azure/azure_openai.py +95 -0
  143. lfx/components/azure/azure_openai_embeddings.py +83 -0
  144. lfx/components/baidu/__init__.py +32 -0
  145. lfx/components/baidu/baidu_qianfan_chat.py +113 -0
  146. lfx/components/bing/__init__.py +3 -0
  147. lfx/components/bing/bing_search_api.py +61 -0
  148. lfx/components/cassandra/__init__.py +40 -0
  149. lfx/components/cassandra/cassandra.py +264 -0
  150. lfx/components/cassandra/cassandra_chat.py +92 -0
  151. lfx/components/cassandra/cassandra_graph.py +238 -0
  152. lfx/components/chains/__init__.py +3 -0
  153. lfx/components/chroma/__init__.py +34 -0
  154. lfx/components/chroma/chroma.py +169 -0
  155. lfx/components/cleanlab/__init__.py +40 -0
  156. lfx/components/cleanlab/cleanlab_evaluator.py +155 -0
  157. lfx/components/cleanlab/cleanlab_rag_evaluator.py +254 -0
  158. lfx/components/cleanlab/cleanlab_remediator.py +131 -0
  159. lfx/components/clickhouse/__init__.py +34 -0
  160. lfx/components/clickhouse/clickhouse.py +135 -0
  161. lfx/components/cloudflare/__init__.py +32 -0
  162. lfx/components/cloudflare/cloudflare.py +81 -0
  163. lfx/components/cohere/__init__.py +40 -0
  164. lfx/components/cohere/cohere_embeddings.py +81 -0
  165. lfx/components/cohere/cohere_models.py +46 -0
  166. lfx/components/cohere/cohere_rerank.py +51 -0
  167. lfx/components/cometapi/__init__.py +32 -0
  168. lfx/components/cometapi/cometapi.py +166 -0
  169. lfx/components/composio/__init__.py +222 -0
  170. lfx/components/composio/agentql_composio.py +11 -0
  171. lfx/components/composio/agiled_composio.py +11 -0
  172. lfx/components/composio/airtable_composio.py +11 -0
  173. lfx/components/composio/apollo_composio.py +11 -0
  174. lfx/components/composio/asana_composio.py +11 -0
  175. lfx/components/composio/attio_composio.py +11 -0
  176. lfx/components/composio/bitbucket_composio.py +11 -0
  177. lfx/components/composio/bolna_composio.py +11 -0
  178. lfx/components/composio/brightdata_composio.py +11 -0
  179. lfx/components/composio/calendly_composio.py +11 -0
  180. lfx/components/composio/canva_composio.py +11 -0
  181. lfx/components/composio/canvas_composio.py +11 -0
  182. lfx/components/composio/coda_composio.py +11 -0
  183. lfx/components/composio/composio_api.py +278 -0
  184. lfx/components/composio/contentful_composio.py +11 -0
  185. lfx/components/composio/digicert_composio.py +11 -0
  186. lfx/components/composio/discord_composio.py +11 -0
  187. lfx/components/composio/dropbox_compnent.py +11 -0
  188. lfx/components/composio/elevenlabs_composio.py +11 -0
  189. lfx/components/composio/exa_composio.py +11 -0
  190. lfx/components/composio/figma_composio.py +11 -0
  191. lfx/components/composio/finage_composio.py +11 -0
  192. lfx/components/composio/firecrawl_composio.py +11 -0
  193. lfx/components/composio/fireflies_composio.py +11 -0
  194. lfx/components/composio/fixer_composio.py +11 -0
  195. lfx/components/composio/flexisign_composio.py +11 -0
  196. lfx/components/composio/freshdesk_composio.py +11 -0
  197. lfx/components/composio/github_composio.py +11 -0
  198. lfx/components/composio/gmail_composio.py +38 -0
  199. lfx/components/composio/googlebigquery_composio.py +11 -0
  200. lfx/components/composio/googlecalendar_composio.py +11 -0
  201. lfx/components/composio/googleclassroom_composio.py +11 -0
  202. lfx/components/composio/googledocs_composio.py +11 -0
  203. lfx/components/composio/googlemeet_composio.py +11 -0
  204. lfx/components/composio/googlesheets_composio.py +11 -0
  205. lfx/components/composio/googletasks_composio.py +8 -0
  206. lfx/components/composio/heygen_composio.py +11 -0
  207. lfx/components/composio/instagram_composio.py +11 -0
  208. lfx/components/composio/jira_composio.py +11 -0
  209. lfx/components/composio/jotform_composio.py +11 -0
  210. lfx/components/composio/klaviyo_composio.py +11 -0
  211. lfx/components/composio/linear_composio.py +11 -0
  212. lfx/components/composio/listennotes_composio.py +11 -0
  213. lfx/components/composio/mem0_composio.py +11 -0
  214. lfx/components/composio/miro_composio.py +11 -0
  215. lfx/components/composio/missive_composio.py +11 -0
  216. lfx/components/composio/notion_composio.py +11 -0
  217. lfx/components/composio/onedrive_composio.py +11 -0
  218. lfx/components/composio/outlook_composio.py +11 -0
  219. lfx/components/composio/pandadoc_composio.py +11 -0
  220. lfx/components/composio/peopledatalabs_composio.py +11 -0
  221. lfx/components/composio/perplexityai_composio.py +11 -0
  222. lfx/components/composio/reddit_composio.py +11 -0
  223. lfx/components/composio/serpapi_composio.py +11 -0
  224. lfx/components/composio/slack_composio.py +11 -0
  225. lfx/components/composio/slackbot_composio.py +11 -0
  226. lfx/components/composio/snowflake_composio.py +11 -0
  227. lfx/components/composio/supabase_composio.py +11 -0
  228. lfx/components/composio/tavily_composio.py +11 -0
  229. lfx/components/composio/timelinesai_composio.py +11 -0
  230. lfx/components/composio/todoist_composio.py +11 -0
  231. lfx/components/composio/wrike_composio.py +11 -0
  232. lfx/components/composio/youtube_composio.py +11 -0
  233. lfx/components/confluence/__init__.py +3 -0
  234. lfx/components/confluence/confluence.py +84 -0
  235. lfx/components/couchbase/__init__.py +34 -0
  236. lfx/components/couchbase/couchbase.py +102 -0
  237. lfx/components/crewai/__init__.py +49 -0
  238. lfx/components/crewai/crewai.py +108 -0
  239. lfx/components/crewai/hierarchical_crew.py +47 -0
  240. lfx/components/crewai/hierarchical_task.py +45 -0
  241. lfx/components/crewai/sequential_crew.py +53 -0
  242. lfx/components/crewai/sequential_task.py +74 -0
  243. lfx/components/crewai/sequential_task_agent.py +144 -0
  244. lfx/components/cuga/__init__.py +34 -0
  245. lfx/components/cuga/cuga_agent.py +730 -0
  246. lfx/components/custom_component/__init__.py +34 -0
  247. lfx/components/custom_component/custom_component.py +31 -0
  248. lfx/components/data/__init__.py +114 -0
  249. lfx/components/data_source/__init__.py +58 -0
  250. lfx/components/data_source/api_request.py +577 -0
  251. lfx/components/data_source/csv_to_data.py +101 -0
  252. lfx/components/data_source/json_to_data.py +106 -0
  253. lfx/components/data_source/mock_data.py +398 -0
  254. lfx/components/data_source/news_search.py +166 -0
  255. lfx/components/data_source/rss.py +71 -0
  256. lfx/components/data_source/sql_executor.py +101 -0
  257. lfx/components/data_source/url.py +311 -0
  258. lfx/components/data_source/web_search.py +326 -0
  259. lfx/components/datastax/__init__.py +76 -0
  260. lfx/components/datastax/astradb_assistant_manager.py +307 -0
  261. lfx/components/datastax/astradb_chatmemory.py +40 -0
  262. lfx/components/datastax/astradb_cql.py +288 -0
  263. lfx/components/datastax/astradb_graph.py +217 -0
  264. lfx/components/datastax/astradb_tool.py +378 -0
  265. lfx/components/datastax/astradb_vectorize.py +122 -0
  266. lfx/components/datastax/astradb_vectorstore.py +449 -0
  267. lfx/components/datastax/create_assistant.py +59 -0
  268. lfx/components/datastax/create_thread.py +33 -0
  269. lfx/components/datastax/dotenv.py +36 -0
  270. lfx/components/datastax/get_assistant.py +38 -0
  271. lfx/components/datastax/getenvvar.py +31 -0
  272. lfx/components/datastax/graph_rag.py +141 -0
  273. lfx/components/datastax/hcd.py +315 -0
  274. lfx/components/datastax/list_assistants.py +26 -0
  275. lfx/components/datastax/run.py +90 -0
  276. lfx/components/deactivated/__init__.py +15 -0
  277. lfx/components/deactivated/amazon_kendra.py +66 -0
  278. lfx/components/deactivated/chat_litellm_model.py +158 -0
  279. lfx/components/deactivated/code_block_extractor.py +26 -0
  280. lfx/components/deactivated/documents_to_data.py +22 -0
  281. lfx/components/deactivated/embed.py +16 -0
  282. lfx/components/deactivated/extract_key_from_data.py +46 -0
  283. lfx/components/deactivated/json_document_builder.py +57 -0
  284. lfx/components/deactivated/list_flows.py +20 -0
  285. lfx/components/deactivated/mcp_sse.py +61 -0
  286. lfx/components/deactivated/mcp_stdio.py +62 -0
  287. lfx/components/deactivated/merge_data.py +93 -0
  288. lfx/components/deactivated/message.py +37 -0
  289. lfx/components/deactivated/metal.py +54 -0
  290. lfx/components/deactivated/multi_query.py +59 -0
  291. lfx/components/deactivated/retriever.py +43 -0
  292. lfx/components/deactivated/selective_passthrough.py +77 -0
  293. lfx/components/deactivated/should_run_next.py +40 -0
  294. lfx/components/deactivated/split_text.py +63 -0
  295. lfx/components/deactivated/store_message.py +24 -0
  296. lfx/components/deactivated/sub_flow.py +124 -0
  297. lfx/components/deactivated/vectara_self_query.py +76 -0
  298. lfx/components/deactivated/vector_store.py +24 -0
  299. lfx/components/deepseek/__init__.py +34 -0
  300. lfx/components/deepseek/deepseek.py +136 -0
  301. lfx/components/docling/__init__.py +43 -0
  302. lfx/components/docling/chunk_docling_document.py +186 -0
  303. lfx/components/docling/docling_inline.py +238 -0
  304. lfx/components/docling/docling_remote.py +195 -0
  305. lfx/components/docling/export_docling_document.py +117 -0
  306. lfx/components/documentloaders/__init__.py +3 -0
  307. lfx/components/duckduckgo/__init__.py +3 -0
  308. lfx/components/duckduckgo/duck_duck_go_search_run.py +92 -0
  309. lfx/components/elastic/__init__.py +37 -0
  310. lfx/components/elastic/elasticsearch.py +267 -0
  311. lfx/components/elastic/opensearch.py +789 -0
  312. lfx/components/elastic/opensearch_multimodal.py +1575 -0
  313. lfx/components/embeddings/__init__.py +37 -0
  314. lfx/components/embeddings/similarity.py +77 -0
  315. lfx/components/embeddings/text_embedder.py +65 -0
  316. lfx/components/exa/__init__.py +3 -0
  317. lfx/components/exa/exa_search.py +68 -0
  318. lfx/components/files_and_knowledge/__init__.py +47 -0
  319. lfx/components/files_and_knowledge/directory.py +113 -0
  320. lfx/components/files_and_knowledge/file.py +841 -0
  321. lfx/components/files_and_knowledge/ingestion.py +694 -0
  322. lfx/components/files_and_knowledge/retrieval.py +264 -0
  323. lfx/components/files_and_knowledge/save_file.py +746 -0
  324. lfx/components/firecrawl/__init__.py +43 -0
  325. lfx/components/firecrawl/firecrawl_crawl_api.py +88 -0
  326. lfx/components/firecrawl/firecrawl_extract_api.py +136 -0
  327. lfx/components/firecrawl/firecrawl_map_api.py +89 -0
  328. lfx/components/firecrawl/firecrawl_scrape_api.py +73 -0
  329. lfx/components/flow_controls/__init__.py +58 -0
  330. lfx/components/flow_controls/conditional_router.py +208 -0
  331. lfx/components/flow_controls/data_conditional_router.py +126 -0
  332. lfx/components/flow_controls/flow_tool.py +111 -0
  333. lfx/components/flow_controls/listen.py +29 -0
  334. lfx/components/flow_controls/loop.py +163 -0
  335. lfx/components/flow_controls/notify.py +88 -0
  336. lfx/components/flow_controls/pass_message.py +36 -0
  337. lfx/components/flow_controls/run_flow.py +108 -0
  338. lfx/components/flow_controls/sub_flow.py +115 -0
  339. lfx/components/git/__init__.py +4 -0
  340. lfx/components/git/git.py +262 -0
  341. lfx/components/git/gitextractor.py +196 -0
  342. lfx/components/glean/__init__.py +3 -0
  343. lfx/components/glean/glean_search_api.py +173 -0
  344. lfx/components/google/__init__.py +17 -0
  345. lfx/components/google/gmail.py +193 -0
  346. lfx/components/google/google_bq_sql_executor.py +157 -0
  347. lfx/components/google/google_drive.py +92 -0
  348. lfx/components/google/google_drive_search.py +152 -0
  349. lfx/components/google/google_generative_ai.py +144 -0
  350. lfx/components/google/google_generative_ai_embeddings.py +141 -0
  351. lfx/components/google/google_oauth_token.py +89 -0
  352. lfx/components/google/google_search_api_core.py +68 -0
  353. lfx/components/google/google_serper_api_core.py +74 -0
  354. lfx/components/groq/__init__.py +34 -0
  355. lfx/components/groq/groq.py +143 -0
  356. lfx/components/helpers/__init__.py +154 -0
  357. lfx/components/homeassistant/__init__.py +7 -0
  358. lfx/components/homeassistant/home_assistant_control.py +152 -0
  359. lfx/components/homeassistant/list_home_assistant_states.py +137 -0
  360. lfx/components/huggingface/__init__.py +37 -0
  361. lfx/components/huggingface/huggingface.py +199 -0
  362. lfx/components/huggingface/huggingface_inference_api.py +106 -0
  363. lfx/components/ibm/__init__.py +34 -0
  364. lfx/components/ibm/watsonx.py +207 -0
  365. lfx/components/ibm/watsonx_embeddings.py +135 -0
  366. lfx/components/icosacomputing/__init__.py +5 -0
  367. lfx/components/icosacomputing/combinatorial_reasoner.py +84 -0
  368. lfx/components/input_output/__init__.py +40 -0
  369. lfx/components/input_output/chat.py +109 -0
  370. lfx/components/input_output/chat_output.py +184 -0
  371. lfx/components/input_output/text.py +27 -0
  372. lfx/components/input_output/text_output.py +29 -0
  373. lfx/components/input_output/webhook.py +56 -0
  374. lfx/components/jigsawstack/__init__.py +23 -0
  375. lfx/components/jigsawstack/ai_scrape.py +126 -0
  376. lfx/components/jigsawstack/ai_web_search.py +136 -0
  377. lfx/components/jigsawstack/file_read.py +115 -0
  378. lfx/components/jigsawstack/file_upload.py +94 -0
  379. lfx/components/jigsawstack/image_generation.py +205 -0
  380. lfx/components/jigsawstack/nsfw.py +60 -0
  381. lfx/components/jigsawstack/object_detection.py +124 -0
  382. lfx/components/jigsawstack/sentiment.py +112 -0
  383. lfx/components/jigsawstack/text_to_sql.py +90 -0
  384. lfx/components/jigsawstack/text_translate.py +77 -0
  385. lfx/components/jigsawstack/vocr.py +107 -0
  386. lfx/components/knowledge_bases/__init__.py +89 -0
  387. lfx/components/langchain_utilities/__init__.py +109 -0
  388. lfx/components/langchain_utilities/character.py +53 -0
  389. lfx/components/langchain_utilities/conversation.py +59 -0
  390. lfx/components/langchain_utilities/csv_agent.py +175 -0
  391. lfx/components/langchain_utilities/fake_embeddings.py +26 -0
  392. lfx/components/langchain_utilities/html_link_extractor.py +35 -0
  393. lfx/components/langchain_utilities/json_agent.py +100 -0
  394. lfx/components/langchain_utilities/langchain_hub.py +126 -0
  395. lfx/components/langchain_utilities/language_recursive.py +49 -0
  396. lfx/components/langchain_utilities/language_semantic.py +138 -0
  397. lfx/components/langchain_utilities/llm_checker.py +39 -0
  398. lfx/components/langchain_utilities/llm_math.py +42 -0
  399. lfx/components/langchain_utilities/natural_language.py +61 -0
  400. lfx/components/langchain_utilities/openai_tools.py +53 -0
  401. lfx/components/langchain_utilities/openapi.py +48 -0
  402. lfx/components/langchain_utilities/recursive_character.py +60 -0
  403. lfx/components/langchain_utilities/retrieval_qa.py +83 -0
  404. lfx/components/langchain_utilities/runnable_executor.py +137 -0
  405. lfx/components/langchain_utilities/self_query.py +80 -0
  406. lfx/components/langchain_utilities/spider.py +142 -0
  407. lfx/components/langchain_utilities/sql.py +40 -0
  408. lfx/components/langchain_utilities/sql_database.py +35 -0
  409. lfx/components/langchain_utilities/sql_generator.py +78 -0
  410. lfx/components/langchain_utilities/tool_calling.py +59 -0
  411. lfx/components/langchain_utilities/vector_store_info.py +49 -0
  412. lfx/components/langchain_utilities/vector_store_router.py +33 -0
  413. lfx/components/langchain_utilities/xml_agent.py +71 -0
  414. lfx/components/langwatch/__init__.py +3 -0
  415. lfx/components/langwatch/langwatch.py +278 -0
  416. lfx/components/link_extractors/__init__.py +3 -0
  417. lfx/components/llm_operations/__init__.py +46 -0
  418. lfx/components/llm_operations/batch_run.py +205 -0
  419. lfx/components/llm_operations/lambda_filter.py +218 -0
  420. lfx/components/llm_operations/llm_conditional_router.py +421 -0
  421. lfx/components/llm_operations/llm_selector.py +499 -0
  422. lfx/components/llm_operations/structured_output.py +244 -0
  423. lfx/components/lmstudio/__init__.py +34 -0
  424. lfx/components/lmstudio/lmstudioembeddings.py +89 -0
  425. lfx/components/lmstudio/lmstudiomodel.py +133 -0
  426. lfx/components/logic/__init__.py +181 -0
  427. lfx/components/maritalk/__init__.py +32 -0
  428. lfx/components/maritalk/maritalk.py +52 -0
  429. lfx/components/mem0/__init__.py +3 -0
  430. lfx/components/mem0/mem0_chat_memory.py +147 -0
  431. lfx/components/milvus/__init__.py +34 -0
  432. lfx/components/milvus/milvus.py +115 -0
  433. lfx/components/mistral/__init__.py +37 -0
  434. lfx/components/mistral/mistral.py +114 -0
  435. lfx/components/mistral/mistral_embeddings.py +58 -0
  436. lfx/components/models/__init__.py +89 -0
  437. lfx/components/models_and_agents/__init__.py +49 -0
  438. lfx/components/models_and_agents/agent.py +644 -0
  439. lfx/components/models_and_agents/embedding_model.py +423 -0
  440. lfx/components/models_and_agents/language_model.py +398 -0
  441. lfx/components/models_and_agents/mcp_component.py +594 -0
  442. lfx/components/models_and_agents/memory.py +268 -0
  443. lfx/components/models_and_agents/prompt.py +67 -0
  444. lfx/components/mongodb/__init__.py +34 -0
  445. lfx/components/mongodb/mongodb_atlas.py +213 -0
  446. lfx/components/needle/__init__.py +3 -0
  447. lfx/components/needle/needle.py +104 -0
  448. lfx/components/notdiamond/__init__.py +34 -0
  449. lfx/components/notdiamond/notdiamond.py +228 -0
  450. lfx/components/novita/__init__.py +32 -0
  451. lfx/components/novita/novita.py +130 -0
  452. lfx/components/nvidia/__init__.py +57 -0
  453. lfx/components/nvidia/nvidia.py +151 -0
  454. lfx/components/nvidia/nvidia_embedding.py +77 -0
  455. lfx/components/nvidia/nvidia_ingest.py +317 -0
  456. lfx/components/nvidia/nvidia_rerank.py +63 -0
  457. lfx/components/nvidia/system_assist.py +65 -0
  458. lfx/components/olivya/__init__.py +3 -0
  459. lfx/components/olivya/olivya.py +116 -0
  460. lfx/components/ollama/__init__.py +37 -0
  461. lfx/components/ollama/ollama.py +548 -0
  462. lfx/components/ollama/ollama_embeddings.py +103 -0
  463. lfx/components/openai/__init__.py +37 -0
  464. lfx/components/openai/openai.py +100 -0
  465. lfx/components/openai/openai_chat_model.py +176 -0
  466. lfx/components/openrouter/__init__.py +32 -0
  467. lfx/components/openrouter/openrouter.py +104 -0
  468. lfx/components/output_parsers/__init__.py +3 -0
  469. lfx/components/perplexity/__init__.py +34 -0
  470. lfx/components/perplexity/perplexity.py +75 -0
  471. lfx/components/pgvector/__init__.py +34 -0
  472. lfx/components/pgvector/pgvector.py +72 -0
  473. lfx/components/pinecone/__init__.py +34 -0
  474. lfx/components/pinecone/pinecone.py +134 -0
  475. lfx/components/processing/__init__.py +72 -0
  476. lfx/components/processing/alter_metadata.py +109 -0
  477. lfx/components/processing/combine_text.py +40 -0
  478. lfx/components/processing/converter.py +248 -0
  479. lfx/components/processing/create_data.py +111 -0
  480. lfx/components/processing/create_list.py +40 -0
  481. lfx/components/processing/data_operations.py +528 -0
  482. lfx/components/processing/data_to_dataframe.py +71 -0
  483. lfx/components/processing/dataframe_operations.py +313 -0
  484. lfx/components/processing/dataframe_to_toolset.py +259 -0
  485. lfx/components/processing/dynamic_create_data.py +357 -0
  486. lfx/components/processing/extract_key.py +54 -0
  487. lfx/components/processing/filter_data.py +43 -0
  488. lfx/components/processing/filter_data_values.py +89 -0
  489. lfx/components/processing/json_cleaner.py +104 -0
  490. lfx/components/processing/merge_data.py +91 -0
  491. lfx/components/processing/message_to_data.py +37 -0
  492. lfx/components/processing/output_parser.py +46 -0
  493. lfx/components/processing/parse_data.py +71 -0
  494. lfx/components/processing/parse_dataframe.py +69 -0
  495. lfx/components/processing/parse_json_data.py +91 -0
  496. lfx/components/processing/parser.py +148 -0
  497. lfx/components/processing/regex.py +83 -0
  498. lfx/components/processing/select_data.py +49 -0
  499. lfx/components/processing/split_text.py +141 -0
  500. lfx/components/processing/store_message.py +91 -0
  501. lfx/components/processing/update_data.py +161 -0
  502. lfx/components/prototypes/__init__.py +35 -0
  503. lfx/components/prototypes/python_function.py +73 -0
  504. lfx/components/qdrant/__init__.py +34 -0
  505. lfx/components/qdrant/qdrant.py +109 -0
  506. lfx/components/redis/__init__.py +37 -0
  507. lfx/components/redis/redis.py +89 -0
  508. lfx/components/redis/redis_chat.py +43 -0
  509. lfx/components/sambanova/__init__.py +32 -0
  510. lfx/components/sambanova/sambanova.py +84 -0
  511. lfx/components/scrapegraph/__init__.py +40 -0
  512. lfx/components/scrapegraph/scrapegraph_markdownify_api.py +64 -0
  513. lfx/components/scrapegraph/scrapegraph_search_api.py +64 -0
  514. lfx/components/scrapegraph/scrapegraph_smart_scraper_api.py +71 -0
  515. lfx/components/searchapi/__init__.py +34 -0
  516. lfx/components/searchapi/search.py +79 -0
  517. lfx/components/serpapi/__init__.py +3 -0
  518. lfx/components/serpapi/serp.py +115 -0
  519. lfx/components/supabase/__init__.py +34 -0
  520. lfx/components/supabase/supabase.py +76 -0
  521. lfx/components/tavily/__init__.py +4 -0
  522. lfx/components/tavily/tavily_extract.py +117 -0
  523. lfx/components/tavily/tavily_search.py +212 -0
  524. lfx/components/textsplitters/__init__.py +3 -0
  525. lfx/components/toolkits/__init__.py +3 -0
  526. lfx/components/tools/__init__.py +66 -0
  527. lfx/components/tools/calculator.py +109 -0
  528. lfx/components/tools/google_search_api.py +45 -0
  529. lfx/components/tools/google_serper_api.py +115 -0
  530. lfx/components/tools/python_code_structured_tool.py +328 -0
  531. lfx/components/tools/python_repl.py +98 -0
  532. lfx/components/tools/search_api.py +88 -0
  533. lfx/components/tools/searxng.py +145 -0
  534. lfx/components/tools/serp_api.py +120 -0
  535. lfx/components/tools/tavily_search_tool.py +345 -0
  536. lfx/components/tools/wikidata_api.py +103 -0
  537. lfx/components/tools/wikipedia_api.py +50 -0
  538. lfx/components/tools/yahoo_finance.py +130 -0
  539. lfx/components/twelvelabs/__init__.py +52 -0
  540. lfx/components/twelvelabs/convert_astra_results.py +84 -0
  541. lfx/components/twelvelabs/pegasus_index.py +311 -0
  542. lfx/components/twelvelabs/split_video.py +301 -0
  543. lfx/components/twelvelabs/text_embeddings.py +57 -0
  544. lfx/components/twelvelabs/twelvelabs_pegasus.py +408 -0
  545. lfx/components/twelvelabs/video_embeddings.py +100 -0
  546. lfx/components/twelvelabs/video_file.py +191 -0
  547. lfx/components/unstructured/__init__.py +3 -0
  548. lfx/components/unstructured/unstructured.py +121 -0
  549. lfx/components/upstash/__init__.py +34 -0
  550. lfx/components/upstash/upstash.py +124 -0
  551. lfx/components/utilities/__init__.py +43 -0
  552. lfx/components/utilities/calculator_core.py +89 -0
  553. lfx/components/utilities/current_date.py +42 -0
  554. lfx/components/utilities/id_generator.py +42 -0
  555. lfx/components/utilities/python_repl_core.py +98 -0
  556. lfx/components/vectara/__init__.py +37 -0
  557. lfx/components/vectara/vectara.py +97 -0
  558. lfx/components/vectara/vectara_rag.py +164 -0
  559. lfx/components/vectorstores/__init__.py +34 -0
  560. lfx/components/vectorstores/local_db.py +270 -0
  561. lfx/components/vertexai/__init__.py +37 -0
  562. lfx/components/vertexai/vertexai.py +71 -0
  563. lfx/components/vertexai/vertexai_embeddings.py +67 -0
  564. lfx/components/vlmrun/__init__.py +34 -0
  565. lfx/components/vlmrun/vlmrun_transcription.py +224 -0
  566. lfx/components/weaviate/__init__.py +34 -0
  567. lfx/components/weaviate/weaviate.py +89 -0
  568. lfx/components/wikipedia/__init__.py +4 -0
  569. lfx/components/wikipedia/wikidata.py +86 -0
  570. lfx/components/wikipedia/wikipedia.py +53 -0
  571. lfx/components/wolframalpha/__init__.py +3 -0
  572. lfx/components/wolframalpha/wolfram_alpha_api.py +54 -0
  573. lfx/components/xai/__init__.py +32 -0
  574. lfx/components/xai/xai.py +167 -0
  575. lfx/components/yahoosearch/__init__.py +3 -0
  576. lfx/components/yahoosearch/yahoo.py +137 -0
  577. lfx/components/youtube/__init__.py +52 -0
  578. lfx/components/youtube/channel.py +227 -0
  579. lfx/components/youtube/comments.py +231 -0
  580. lfx/components/youtube/playlist.py +33 -0
  581. lfx/components/youtube/search.py +120 -0
  582. lfx/components/youtube/trending.py +285 -0
  583. lfx/components/youtube/video_details.py +263 -0
  584. lfx/components/youtube/youtube_transcripts.py +206 -0
  585. lfx/components/zep/__init__.py +3 -0
  586. lfx/components/zep/zep.py +45 -0
  587. lfx/constants.py +6 -0
  588. lfx/custom/__init__.py +7 -0
  589. lfx/custom/attributes.py +87 -0
  590. lfx/custom/code_parser/__init__.py +3 -0
  591. lfx/custom/code_parser/code_parser.py +361 -0
  592. lfx/custom/custom_component/__init__.py +0 -0
  593. lfx/custom/custom_component/base_component.py +128 -0
  594. lfx/custom/custom_component/component.py +1890 -0
  595. lfx/custom/custom_component/component_with_cache.py +8 -0
  596. lfx/custom/custom_component/custom_component.py +650 -0
  597. lfx/custom/dependency_analyzer.py +165 -0
  598. lfx/custom/directory_reader/__init__.py +3 -0
  599. lfx/custom/directory_reader/directory_reader.py +359 -0
  600. lfx/custom/directory_reader/utils.py +171 -0
  601. lfx/custom/eval.py +12 -0
  602. lfx/custom/schema.py +32 -0
  603. lfx/custom/tree_visitor.py +21 -0
  604. lfx/custom/utils.py +877 -0
  605. lfx/custom/validate.py +523 -0
  606. lfx/events/__init__.py +1 -0
  607. lfx/events/event_manager.py +110 -0
  608. lfx/exceptions/__init__.py +0 -0
  609. lfx/exceptions/component.py +15 -0
  610. lfx/field_typing/__init__.py +91 -0
  611. lfx/field_typing/constants.py +216 -0
  612. lfx/field_typing/range_spec.py +35 -0
  613. lfx/graph/__init__.py +6 -0
  614. lfx/graph/edge/__init__.py +0 -0
  615. lfx/graph/edge/base.py +300 -0
  616. lfx/graph/edge/schema.py +119 -0
  617. lfx/graph/edge/utils.py +0 -0
  618. lfx/graph/graph/__init__.py +0 -0
  619. lfx/graph/graph/ascii.py +202 -0
  620. lfx/graph/graph/base.py +2298 -0
  621. lfx/graph/graph/constants.py +63 -0
  622. lfx/graph/graph/runnable_vertices_manager.py +133 -0
  623. lfx/graph/graph/schema.py +53 -0
  624. lfx/graph/graph/state_model.py +66 -0
  625. lfx/graph/graph/utils.py +1024 -0
  626. lfx/graph/schema.py +75 -0
  627. lfx/graph/state/__init__.py +0 -0
  628. lfx/graph/state/model.py +250 -0
  629. lfx/graph/utils.py +206 -0
  630. lfx/graph/vertex/__init__.py +0 -0
  631. lfx/graph/vertex/base.py +826 -0
  632. lfx/graph/vertex/constants.py +0 -0
  633. lfx/graph/vertex/exceptions.py +4 -0
  634. lfx/graph/vertex/param_handler.py +316 -0
  635. lfx/graph/vertex/schema.py +26 -0
  636. lfx/graph/vertex/utils.py +19 -0
  637. lfx/graph/vertex/vertex_types.py +489 -0
  638. lfx/helpers/__init__.py +141 -0
  639. lfx/helpers/base_model.py +71 -0
  640. lfx/helpers/custom.py +13 -0
  641. lfx/helpers/data.py +167 -0
  642. lfx/helpers/flow.py +308 -0
  643. lfx/inputs/__init__.py +68 -0
  644. lfx/inputs/constants.py +2 -0
  645. lfx/inputs/input_mixin.py +352 -0
  646. lfx/inputs/inputs.py +718 -0
  647. lfx/inputs/validators.py +19 -0
  648. lfx/interface/__init__.py +6 -0
  649. lfx/interface/components.py +897 -0
  650. lfx/interface/importing/__init__.py +5 -0
  651. lfx/interface/importing/utils.py +39 -0
  652. lfx/interface/initialize/__init__.py +3 -0
  653. lfx/interface/initialize/loading.py +317 -0
  654. lfx/interface/listing.py +26 -0
  655. lfx/interface/run.py +16 -0
  656. lfx/interface/utils.py +111 -0
  657. lfx/io/__init__.py +63 -0
  658. lfx/io/schema.py +295 -0
  659. lfx/load/__init__.py +8 -0
  660. lfx/load/load.py +256 -0
  661. lfx/load/utils.py +99 -0
  662. lfx/log/__init__.py +5 -0
  663. lfx/log/logger.py +411 -0
  664. lfx/logging/__init__.py +11 -0
  665. lfx/logging/logger.py +24 -0
  666. lfx/memory/__init__.py +70 -0
  667. lfx/memory/stubs.py +302 -0
  668. lfx/processing/__init__.py +1 -0
  669. lfx/processing/process.py +238 -0
  670. lfx/processing/utils.py +25 -0
  671. lfx/py.typed +0 -0
  672. lfx/schema/__init__.py +66 -0
  673. lfx/schema/artifact.py +83 -0
  674. lfx/schema/content_block.py +62 -0
  675. lfx/schema/content_types.py +91 -0
  676. lfx/schema/cross_module.py +80 -0
  677. lfx/schema/data.py +309 -0
  678. lfx/schema/dataframe.py +210 -0
  679. lfx/schema/dotdict.py +74 -0
  680. lfx/schema/encoders.py +13 -0
  681. lfx/schema/graph.py +47 -0
  682. lfx/schema/image.py +184 -0
  683. lfx/schema/json_schema.py +186 -0
  684. lfx/schema/log.py +62 -0
  685. lfx/schema/message.py +493 -0
  686. lfx/schema/openai_responses_schemas.py +74 -0
  687. lfx/schema/properties.py +41 -0
  688. lfx/schema/schema.py +180 -0
  689. lfx/schema/serialize.py +13 -0
  690. lfx/schema/table.py +142 -0
  691. lfx/schema/validators.py +114 -0
  692. lfx/serialization/__init__.py +5 -0
  693. lfx/serialization/constants.py +2 -0
  694. lfx/serialization/serialization.py +314 -0
  695. lfx/services/__init__.py +26 -0
  696. lfx/services/base.py +28 -0
  697. lfx/services/cache/__init__.py +6 -0
  698. lfx/services/cache/base.py +183 -0
  699. lfx/services/cache/service.py +166 -0
  700. lfx/services/cache/utils.py +169 -0
  701. lfx/services/chat/__init__.py +1 -0
  702. lfx/services/chat/config.py +2 -0
  703. lfx/services/chat/schema.py +10 -0
  704. lfx/services/database/__init__.py +5 -0
  705. lfx/services/database/service.py +25 -0
  706. lfx/services/deps.py +194 -0
  707. lfx/services/factory.py +19 -0
  708. lfx/services/initialize.py +19 -0
  709. lfx/services/interfaces.py +103 -0
  710. lfx/services/manager.py +185 -0
  711. lfx/services/mcp_composer/__init__.py +6 -0
  712. lfx/services/mcp_composer/factory.py +16 -0
  713. lfx/services/mcp_composer/service.py +1441 -0
  714. lfx/services/schema.py +21 -0
  715. lfx/services/session.py +87 -0
  716. lfx/services/settings/__init__.py +3 -0
  717. lfx/services/settings/auth.py +133 -0
  718. lfx/services/settings/base.py +668 -0
  719. lfx/services/settings/constants.py +43 -0
  720. lfx/services/settings/factory.py +23 -0
  721. lfx/services/settings/feature_flags.py +11 -0
  722. lfx/services/settings/service.py +35 -0
  723. lfx/services/settings/utils.py +40 -0
  724. lfx/services/shared_component_cache/__init__.py +1 -0
  725. lfx/services/shared_component_cache/factory.py +30 -0
  726. lfx/services/shared_component_cache/service.py +9 -0
  727. lfx/services/storage/__init__.py +5 -0
  728. lfx/services/storage/local.py +185 -0
  729. lfx/services/storage/service.py +177 -0
  730. lfx/services/tracing/__init__.py +1 -0
  731. lfx/services/tracing/service.py +21 -0
  732. lfx/settings.py +6 -0
  733. lfx/template/__init__.py +6 -0
  734. lfx/template/field/__init__.py +0 -0
  735. lfx/template/field/base.py +260 -0
  736. lfx/template/field/prompt.py +15 -0
  737. lfx/template/frontend_node/__init__.py +6 -0
  738. lfx/template/frontend_node/base.py +214 -0
  739. lfx/template/frontend_node/constants.py +65 -0
  740. lfx/template/frontend_node/custom_components.py +79 -0
  741. lfx/template/template/__init__.py +0 -0
  742. lfx/template/template/base.py +100 -0
  743. lfx/template/utils.py +217 -0
  744. lfx/type_extraction/__init__.py +19 -0
  745. lfx/type_extraction/type_extraction.py +75 -0
  746. lfx/type_extraction.py +80 -0
  747. lfx/utils/__init__.py +1 -0
  748. lfx/utils/async_helpers.py +42 -0
  749. lfx/utils/component_utils.py +154 -0
  750. lfx/utils/concurrency.py +60 -0
  751. lfx/utils/connection_string_parser.py +11 -0
  752. lfx/utils/constants.py +233 -0
  753. lfx/utils/data_structure.py +212 -0
  754. lfx/utils/exceptions.py +22 -0
  755. lfx/utils/helpers.py +34 -0
  756. lfx/utils/image.py +79 -0
  757. lfx/utils/langflow_utils.py +52 -0
  758. lfx/utils/lazy_load.py +15 -0
  759. lfx/utils/request_utils.py +18 -0
  760. lfx/utils/schemas.py +139 -0
  761. lfx/utils/ssrf_protection.py +384 -0
  762. lfx/utils/util.py +626 -0
  763. lfx/utils/util_strings.py +56 -0
  764. lfx/utils/validate_cloud.py +26 -0
  765. lfx/utils/version.py +24 -0
  766. lfx_nightly-0.2.0.dev25.dist-info/METADATA +312 -0
  767. lfx_nightly-0.2.0.dev25.dist-info/RECORD +769 -0
  768. lfx_nightly-0.2.0.dev25.dist-info/WHEEL +4 -0
  769. lfx_nightly-0.2.0.dev25.dist-info/entry_points.txt +2 -0
@@ -0,0 +1,577 @@
1
+ import json
2
+ import re
3
+ import tempfile
4
+ from datetime import datetime, timezone
5
+ from pathlib import Path
6
+ from typing import Any
7
+ from urllib.parse import parse_qsl, urlencode, urlparse, urlunparse
8
+
9
+ import aiofiles
10
+ import aiofiles.os as aiofiles_os
11
+ import httpx
12
+ import validators
13
+
14
+ from lfx.base.curl.parse import parse_context
15
+ from lfx.custom.custom_component.component import Component
16
+ from lfx.inputs.inputs import TabInput
17
+ from lfx.io import (
18
+ BoolInput,
19
+ DataInput,
20
+ DropdownInput,
21
+ IntInput,
22
+ MessageTextInput,
23
+ MultilineInput,
24
+ Output,
25
+ TableInput,
26
+ )
27
+ from lfx.schema.data import Data
28
+ from lfx.schema.dotdict import dotdict
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
31
+
32
+ # Define fields for each mode
33
+ MODE_FIELDS = {
34
+ "URL": [
35
+ "url_input",
36
+ "method",
37
+ ],
38
+ "cURL": ["curl_input"],
39
+ }
40
+
41
+ # Fields that should always be visible
42
+ DEFAULT_FIELDS = ["mode"]
43
+
44
+
45
+ class APIRequestComponent(Component):
46
+ display_name = "API Request"
47
+ description = "Make HTTP requests using URL or cURL commands."
48
+ documentation: str = "https://docs.langflow.org/api-request"
49
+ icon = "Globe"
50
+ name = "APIRequest"
51
+
52
+ inputs = [
53
+ MessageTextInput(
54
+ name="url_input",
55
+ display_name="URL",
56
+ info="Enter the URL for the request.",
57
+ advanced=False,
58
+ tool_mode=True,
59
+ ),
60
+ MultilineInput(
61
+ name="curl_input",
62
+ display_name="cURL",
63
+ info=(
64
+ "Paste a curl command to populate the fields. "
65
+ "This will fill in the dictionary fields for headers and body."
66
+ ),
67
+ real_time_refresh=True,
68
+ tool_mode=True,
69
+ advanced=True,
70
+ show=False,
71
+ ),
72
+ DropdownInput(
73
+ name="method",
74
+ display_name="Method",
75
+ options=["GET", "POST", "PATCH", "PUT", "DELETE"],
76
+ value="GET",
77
+ info="The HTTP method to use.",
78
+ real_time_refresh=True,
79
+ ),
80
+ TabInput(
81
+ name="mode",
82
+ display_name="Mode",
83
+ options=["URL", "cURL"],
84
+ value="URL",
85
+ info="Enable cURL mode to populate fields from a cURL command.",
86
+ real_time_refresh=True,
87
+ ),
88
+ DataInput(
89
+ name="query_params",
90
+ display_name="Query Parameters",
91
+ info="The query parameters to append to the URL.",
92
+ advanced=True,
93
+ ),
94
+ TableInput(
95
+ name="body",
96
+ display_name="Body",
97
+ info="The body to send with the request as a dictionary (for POST, PATCH, PUT).",
98
+ table_schema=[
99
+ {
100
+ "name": "key",
101
+ "display_name": "Key",
102
+ "type": "str",
103
+ "description": "Parameter name",
104
+ },
105
+ {
106
+ "name": "value",
107
+ "display_name": "Value",
108
+ "description": "Parameter value",
109
+ },
110
+ ],
111
+ value=[],
112
+ input_types=["Data"],
113
+ advanced=True,
114
+ real_time_refresh=True,
115
+ ),
116
+ TableInput(
117
+ name="headers",
118
+ display_name="Headers",
119
+ info="The headers to send with the request",
120
+ table_schema=[
121
+ {
122
+ "name": "key",
123
+ "display_name": "Header",
124
+ "type": "str",
125
+ "description": "Header name",
126
+ },
127
+ {
128
+ "name": "value",
129
+ "display_name": "Value",
130
+ "type": "str",
131
+ "description": "Header value",
132
+ },
133
+ ],
134
+ value=[{"key": "User-Agent", "value": "Langflow/1.0"}],
135
+ advanced=True,
136
+ input_types=["Data"],
137
+ real_time_refresh=True,
138
+ ),
139
+ IntInput(
140
+ name="timeout",
141
+ display_name="Timeout",
142
+ value=30,
143
+ info="The timeout to use for the request.",
144
+ advanced=True,
145
+ ),
146
+ BoolInput(
147
+ name="follow_redirects",
148
+ display_name="Follow Redirects",
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
+ ),
156
+ advanced=True,
157
+ ),
158
+ BoolInput(
159
+ name="save_to_file",
160
+ display_name="Save to File",
161
+ value=False,
162
+ info="Save the API response to a temporary file",
163
+ advanced=True,
164
+ ),
165
+ BoolInput(
166
+ name="include_httpx_metadata",
167
+ display_name="Include HTTPx Metadata",
168
+ value=False,
169
+ info=(
170
+ "Include properties such as headers, status_code, response_headers, "
171
+ "and redirection_history in the output."
172
+ ),
173
+ advanced=True,
174
+ ),
175
+ ]
176
+
177
+ outputs = [
178
+ Output(display_name="API Response", name="data", method="make_api_request"),
179
+ ]
180
+
181
+ def _parse_json_value(self, value: Any) -> Any:
182
+ """Parse a value that might be a JSON string."""
183
+ if not isinstance(value, str):
184
+ return value
185
+
186
+ try:
187
+ parsed = json.loads(value)
188
+ except json.JSONDecodeError:
189
+ return value
190
+ else:
191
+ return parsed
192
+
193
+ def _process_body(self, body: Any) -> dict:
194
+ """Process the body input into a valid dictionary."""
195
+ if body is None:
196
+ return {}
197
+ if hasattr(body, "data"):
198
+ body = body.data
199
+ if isinstance(body, dict):
200
+ return self._process_dict_body(body)
201
+ if isinstance(body, str):
202
+ return self._process_string_body(body)
203
+ if isinstance(body, list):
204
+ return self._process_list_body(body)
205
+ return {}
206
+
207
+ def _process_dict_body(self, body: dict) -> dict:
208
+ """Process dictionary body by parsing JSON values."""
209
+ return {k: self._parse_json_value(v) for k, v in body.items()}
210
+
211
+ def _process_string_body(self, body: str) -> dict:
212
+ """Process string body by attempting JSON parse."""
213
+ try:
214
+ return self._process_body(json.loads(body))
215
+ except json.JSONDecodeError:
216
+ return {"data": body}
217
+
218
+ def _process_list_body(self, body: list) -> dict:
219
+ """Process list body by converting to key-value dictionary."""
220
+ processed_dict = {}
221
+ try:
222
+ for item in body:
223
+ # Unwrap Data objects
224
+ current_item = item
225
+ if hasattr(item, "data"):
226
+ unwrapped_data = item.data
227
+ # If the unwrapped data is a dict but not key-value format, use it directly
228
+ if isinstance(unwrapped_data, dict) and not self._is_valid_key_value_item(unwrapped_data):
229
+ return unwrapped_data
230
+ current_item = unwrapped_data
231
+ if not self._is_valid_key_value_item(current_item):
232
+ continue
233
+ key = current_item["key"]
234
+ value = self._parse_json_value(current_item["value"])
235
+ processed_dict[key] = value
236
+ except (KeyError, TypeError, ValueError) as e:
237
+ self.log(f"Failed to process body list: {e}")
238
+ return {}
239
+ return processed_dict
240
+
241
+ def _is_valid_key_value_item(self, item: Any) -> bool:
242
+ """Check if an item is a valid key-value dictionary."""
243
+ return isinstance(item, dict) and "key" in item and "value" in item
244
+
245
+ def parse_curl(self, curl: str, build_config: dotdict) -> dotdict:
246
+ """Parse a cURL command and update build configuration."""
247
+ try:
248
+ parsed = parse_context(curl)
249
+
250
+ # Update basic configuration
251
+ url = parsed.url
252
+ # Normalize URL before setting it
253
+ url = self._normalize_url(url)
254
+
255
+ build_config["url_input"]["value"] = url
256
+ build_config["method"]["value"] = parsed.method.upper()
257
+
258
+ # Process headers
259
+ headers_list = [{"key": k, "value": v} for k, v in parsed.headers.items()]
260
+ build_config["headers"]["value"] = headers_list
261
+
262
+ # Process body data
263
+ if not parsed.data:
264
+ build_config["body"]["value"] = []
265
+ elif parsed.data:
266
+ try:
267
+ json_data = json.loads(parsed.data)
268
+ if isinstance(json_data, dict):
269
+ body_list = [
270
+ {"key": k, "value": json.dumps(v) if isinstance(v, dict | list) else str(v)}
271
+ for k, v in json_data.items()
272
+ ]
273
+ build_config["body"]["value"] = body_list
274
+ else:
275
+ build_config["body"]["value"] = [{"key": "data", "value": json.dumps(json_data)}]
276
+ except json.JSONDecodeError:
277
+ build_config["body"]["value"] = [{"key": "data", "value": parsed.data}]
278
+
279
+ except Exception as exc:
280
+ msg = f"Error parsing curl: {exc}"
281
+ self.log(msg)
282
+ raise ValueError(msg) from exc
283
+
284
+ return build_config
285
+
286
+ def _normalize_url(self, url: str) -> str:
287
+ """Normalize URL by adding https:// if no protocol is specified."""
288
+ if not url or not isinstance(url, str):
289
+ msg = "URL cannot be empty"
290
+ raise ValueError(msg)
291
+
292
+ url = url.strip()
293
+ if url.startswith(("http://", "https://")):
294
+ return url
295
+ return f"https://{url}"
296
+
297
+ async def make_request(
298
+ self,
299
+ client: httpx.AsyncClient,
300
+ method: str,
301
+ url: str,
302
+ headers: dict | None = None,
303
+ body: Any = None,
304
+ timeout: int = 5,
305
+ *,
306
+ follow_redirects: bool = True,
307
+ save_to_file: bool = False,
308
+ include_httpx_metadata: bool = False,
309
+ ) -> Data:
310
+ method = method.upper()
311
+ if method not in {"GET", "POST", "PATCH", "PUT", "DELETE"}:
312
+ msg = f"Unsupported method: {method}"
313
+ raise ValueError(msg)
314
+
315
+ processed_body = self._process_body(body)
316
+ redirection_history = []
317
+
318
+ try:
319
+ # Prepare request parameters
320
+ request_params = {
321
+ "method": method,
322
+ "url": url,
323
+ "headers": headers,
324
+ "json": processed_body,
325
+ "timeout": timeout,
326
+ "follow_redirects": follow_redirects,
327
+ }
328
+ response = await client.request(**request_params)
329
+
330
+ redirection_history = [
331
+ {
332
+ "url": redirect.headers.get("Location", str(redirect.url)),
333
+ "status_code": redirect.status_code,
334
+ }
335
+ for redirect in response.history
336
+ ]
337
+
338
+ is_binary, file_path = await self._response_info(response, with_file_path=save_to_file)
339
+ response_headers = self._headers_to_dict(response.headers)
340
+
341
+ # Base metadata
342
+ metadata = {
343
+ "source": url,
344
+ "status_code": response.status_code,
345
+ "response_headers": response_headers,
346
+ }
347
+
348
+ if redirection_history:
349
+ metadata["redirection_history"] = redirection_history
350
+
351
+ if save_to_file:
352
+ mode = "wb" if is_binary else "w"
353
+ encoding = response.encoding if mode == "w" else None
354
+ if file_path:
355
+ await aiofiles_os.makedirs(file_path.parent, exist_ok=True)
356
+ if is_binary:
357
+ async with aiofiles.open(file_path, "wb") as f:
358
+ await f.write(response.content)
359
+ await f.flush()
360
+ else:
361
+ async with aiofiles.open(file_path, "w", encoding=encoding) as f:
362
+ await f.write(response.text)
363
+ await f.flush()
364
+ metadata["file_path"] = str(file_path)
365
+
366
+ if include_httpx_metadata:
367
+ metadata.update({"headers": headers})
368
+ return Data(data=metadata)
369
+
370
+ # Handle response content
371
+ if is_binary:
372
+ result = response.content
373
+ else:
374
+ try:
375
+ result = response.json()
376
+ except json.JSONDecodeError:
377
+ self.log("Failed to decode JSON response")
378
+ result = response.text.encode("utf-8")
379
+
380
+ metadata["result"] = result
381
+
382
+ if include_httpx_metadata:
383
+ metadata.update({"headers": headers})
384
+
385
+ return Data(data=metadata)
386
+ except (httpx.HTTPError, httpx.RequestError, httpx.TimeoutException) as exc:
387
+ self.log(f"Error making request to {url}")
388
+ return Data(
389
+ data={
390
+ "source": url,
391
+ "headers": headers,
392
+ "status_code": 500,
393
+ "error": str(exc),
394
+ **({"redirection_history": redirection_history} if redirection_history else {}),
395
+ },
396
+ )
397
+
398
+ def add_query_params(self, url: str, params: dict) -> str:
399
+ """Add query parameters to URL efficiently."""
400
+ if not params:
401
+ return url
402
+ url_parts = list(urlparse(url))
403
+ query = dict(parse_qsl(url_parts[4]))
404
+ query.update(params)
405
+ url_parts[4] = urlencode(query)
406
+ return urlunparse(url_parts)
407
+
408
+ def _headers_to_dict(self, headers: httpx.Headers) -> dict[str, str]:
409
+ """Convert HTTP headers to a dictionary with lowercased keys."""
410
+ return {k.lower(): v for k, v in headers.items()}
411
+
412
+ def _process_headers(self, headers: Any) -> dict:
413
+ """Process the headers input into a valid dictionary."""
414
+ if headers is None:
415
+ return {}
416
+ if isinstance(headers, dict):
417
+ return headers
418
+ if isinstance(headers, list):
419
+ return {item["key"]: item["value"] for item in headers if self._is_valid_key_value_item(item)}
420
+ return {}
421
+
422
+ async def make_api_request(self) -> Data:
423
+ """Make HTTP request with optimized parameter handling."""
424
+ method = self.method
425
+ url = self.url_input.strip() if isinstance(self.url_input, str) else ""
426
+ headers = self.headers or {}
427
+ body = self.body or {}
428
+ timeout = self.timeout
429
+ follow_redirects = self.follow_redirects
430
+ save_to_file = self.save_to_file
431
+ include_httpx_metadata = self.include_httpx_metadata
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
+
441
+ # if self.mode == "cURL" and self.curl_input:
442
+ # self._build_config = self.parse_curl(self.curl_input, dotdict())
443
+ # # After parsing curl, get the normalized URL
444
+ # url = self._build_config["url_input"]["value"]
445
+
446
+ # Normalize URL before validation
447
+ url = self._normalize_url(url)
448
+
449
+ # Validate URL
450
+ if not validators.url(url):
451
+ msg = f"Invalid URL provided: {url}"
452
+ raise ValueError(msg)
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
+
463
+ # Process query parameters
464
+ if isinstance(self.query_params, str):
465
+ query_params = dict(parse_qsl(self.query_params))
466
+ else:
467
+ query_params = self.query_params.data if self.query_params else {}
468
+
469
+ # Process headers and body
470
+ headers = self._process_headers(headers)
471
+ body = self._process_body(body)
472
+ url = self.add_query_params(url, query_params)
473
+
474
+ async with httpx.AsyncClient() as client:
475
+ result = await self.make_request(
476
+ client,
477
+ method,
478
+ url,
479
+ headers,
480
+ body,
481
+ timeout,
482
+ follow_redirects=follow_redirects,
483
+ save_to_file=save_to_file,
484
+ include_httpx_metadata=include_httpx_metadata,
485
+ )
486
+ self.status = result
487
+ return result
488
+
489
+ def update_build_config(self, build_config: dotdict, field_value: Any, field_name: str | None = None) -> dotdict:
490
+ """Update the build config based on the selected mode."""
491
+ if field_name != "mode":
492
+ if field_name == "curl_input" and self.mode == "cURL" and self.curl_input:
493
+ return self.parse_curl(self.curl_input, build_config)
494
+ return build_config
495
+
496
+ # print(f"Current mode: {field_value}")
497
+ if field_value == "cURL":
498
+ set_field_display(build_config, "curl_input", value=True)
499
+ if build_config["curl_input"]["value"]:
500
+ build_config = self.parse_curl(build_config["curl_input"]["value"], build_config)
501
+ else:
502
+ set_field_display(build_config, "curl_input", value=False)
503
+
504
+ return set_current_fields(
505
+ build_config=build_config,
506
+ action_fields=MODE_FIELDS,
507
+ selected_action=field_value,
508
+ default_fields=DEFAULT_FIELDS,
509
+ func=set_field_advanced,
510
+ default_value=True,
511
+ )
512
+
513
+ async def _response_info(
514
+ self, response: httpx.Response, *, with_file_path: bool = False
515
+ ) -> tuple[bool, Path | None]:
516
+ """Determine the file path and whether the response content is binary.
517
+
518
+ Args:
519
+ response (Response): The HTTP response object.
520
+ with_file_path (bool): Whether to save the response content to a file.
521
+
522
+ Returns:
523
+ Tuple[bool, Path | None]:
524
+ A tuple containing a boolean indicating if the content is binary and the full file path (if applicable).
525
+ """
526
+ content_type = response.headers.get("Content-Type", "")
527
+ is_binary = "application/octet-stream" in content_type or "application/binary" in content_type
528
+
529
+ if not with_file_path:
530
+ return is_binary, None
531
+
532
+ component_temp_dir = Path(tempfile.gettempdir()) / self.__class__.__name__
533
+
534
+ # Create directory asynchronously
535
+ await aiofiles_os.makedirs(component_temp_dir, exist_ok=True)
536
+
537
+ filename = None
538
+ if "Content-Disposition" in response.headers:
539
+ content_disposition = response.headers["Content-Disposition"]
540
+ filename_match = re.search(r'filename="(.+?)"', content_disposition)
541
+ if filename_match:
542
+ extracted_filename = filename_match.group(1)
543
+ filename = extracted_filename
544
+
545
+ # Step 3: Infer file extension or use part of the request URL if no filename
546
+ if not filename:
547
+ # Extract the last segment of the URL path
548
+ url_path = urlparse(str(response.request.url) if response.request else "").path
549
+ base_name = Path(url_path).name # Get the last segment of the path
550
+ if not base_name: # If the path ends with a slash or is empty
551
+ base_name = "response"
552
+
553
+ # Infer file extension
554
+ content_type_to_extension = {
555
+ "text/plain": ".txt",
556
+ "application/json": ".json",
557
+ "image/jpeg": ".jpg",
558
+ "image/png": ".png",
559
+ "application/octet-stream": ".bin",
560
+ }
561
+ extension = content_type_to_extension.get(content_type, ".bin" if is_binary else ".txt")
562
+ filename = f"{base_name}{extension}"
563
+
564
+ # Step 4: Define the full file path
565
+ file_path = component_temp_dir / filename
566
+
567
+ # Step 5: Check if file exists asynchronously and handle accordingly
568
+ try:
569
+ # Try to create the file exclusively (x mode) to check existence
570
+ async with aiofiles.open(file_path, "x") as _:
571
+ pass # File created successfully, we can use this path
572
+ except FileExistsError:
573
+ # If file exists, append a timestamp to the filename
574
+ timestamp = datetime.now(timezone.utc).strftime("%Y%m%d%H%M%S%f")
575
+ file_path = component_temp_dir / f"{timestamp}-{filename}"
576
+
577
+ return is_binary, file_path
@@ -0,0 +1,101 @@
1
+ import csv
2
+ import io
3
+ from pathlib import Path
4
+
5
+ from lfx.base.data.storage_utils import read_file_text
6
+ from lfx.custom.custom_component.component import Component
7
+ from lfx.io import FileInput, MessageTextInput, MultilineInput, Output
8
+ from lfx.schema.data import Data
9
+ from lfx.utils.async_helpers import run_until_complete
10
+
11
+
12
+ class CSVToDataComponent(Component):
13
+ display_name = "Load CSV"
14
+ description = "Load a CSV file, CSV from a file path, or a valid CSV string and convert it to a list of Data"
15
+ icon = "file-spreadsheet"
16
+ name = "CSVtoData"
17
+ legacy = True
18
+ replacement = ["data.File"]
19
+
20
+ inputs = [
21
+ FileInput(
22
+ name="csv_file",
23
+ display_name="CSV File",
24
+ file_types=["csv"],
25
+ info="Upload a CSV file to convert to a list of Data objects",
26
+ ),
27
+ MessageTextInput(
28
+ name="csv_path",
29
+ display_name="CSV File Path",
30
+ info="Provide the path to the CSV file as pure text",
31
+ ),
32
+ MultilineInput(
33
+ name="csv_string",
34
+ display_name="CSV String",
35
+ info="Paste a CSV string directly to convert to a list of Data objects",
36
+ ),
37
+ MessageTextInput(
38
+ name="text_key",
39
+ display_name="Text Key",
40
+ info="The key to use for the text column. Defaults to 'text'.",
41
+ value="text",
42
+ ),
43
+ ]
44
+
45
+ outputs = [
46
+ Output(name="data_list", display_name="Data List", method="load_csv_to_data"),
47
+ ]
48
+
49
+ def load_csv_to_data(self) -> list[Data]:
50
+ if sum(bool(field) for field in [self.csv_file, self.csv_path, self.csv_string]) != 1:
51
+ msg = "Please provide exactly one of: CSV file, file path, or CSV string."
52
+ raise ValueError(msg)
53
+
54
+ csv_data = None
55
+ try:
56
+ if self.csv_file:
57
+ # FileInput always provides a local file path
58
+ file_path = self.csv_file
59
+ if not file_path.lower().endswith(".csv"):
60
+ self.status = "The provided file must be a CSV file."
61
+ else:
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")
66
+
67
+ elif self.csv_path:
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."
71
+ else:
72
+ csv_data = run_until_complete(
73
+ read_file_text(file_path, encoding="utf-8", resolve_path=self.resolve_path, newline="")
74
+ )
75
+
76
+ else:
77
+ csv_data = self.csv_string
78
+
79
+ if csv_data:
80
+ csv_reader = csv.DictReader(io.StringIO(csv_data))
81
+ result = [Data(data=row, text_key=self.text_key) for row in csv_reader]
82
+
83
+ if not result:
84
+ self.status = "The CSV data is empty."
85
+ return []
86
+
87
+ self.status = result
88
+ return result
89
+
90
+ except csv.Error as e:
91
+ error_message = f"CSV parsing error: {e}"
92
+ self.status = error_message
93
+ raise ValueError(error_message) from e
94
+
95
+ except Exception as e:
96
+ error_message = f"An error occurred: {e}"
97
+ self.status = error_message
98
+ raise ValueError(error_message) from e
99
+
100
+ # An error occurred
101
+ raise ValueError(self.status)