lfx-nightly 0.1.11.dev0__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.
Files changed (699) hide show
  1. lfx/__init__.py +0 -0
  2. lfx/__main__.py +25 -0
  3. lfx/base/__init__.py +0 -0
  4. lfx/base/agents/__init__.py +0 -0
  5. lfx/base/agents/agent.py +268 -0
  6. lfx/base/agents/callback.py +130 -0
  7. lfx/base/agents/context.py +109 -0
  8. lfx/base/agents/crewai/__init__.py +0 -0
  9. lfx/base/agents/crewai/crew.py +231 -0
  10. lfx/base/agents/crewai/tasks.py +12 -0
  11. lfx/base/agents/default_prompts.py +23 -0
  12. lfx/base/agents/errors.py +15 -0
  13. lfx/base/agents/events.py +346 -0
  14. lfx/base/agents/utils.py +205 -0
  15. lfx/base/astra_assistants/__init__.py +0 -0
  16. lfx/base/astra_assistants/util.py +171 -0
  17. lfx/base/chains/__init__.py +0 -0
  18. lfx/base/chains/model.py +19 -0
  19. lfx/base/composio/__init__.py +0 -0
  20. lfx/base/composio/composio_base.py +1291 -0
  21. lfx/base/compressors/__init__.py +0 -0
  22. lfx/base/compressors/model.py +60 -0
  23. lfx/base/constants.py +46 -0
  24. lfx/base/curl/__init__.py +0 -0
  25. lfx/base/curl/parse.py +188 -0
  26. lfx/base/data/__init__.py +5 -0
  27. lfx/base/data/base_file.py +685 -0
  28. lfx/base/data/docling_utils.py +245 -0
  29. lfx/base/data/utils.py +198 -0
  30. lfx/base/document_transformers/__init__.py +0 -0
  31. lfx/base/document_transformers/model.py +43 -0
  32. lfx/base/embeddings/__init__.py +0 -0
  33. lfx/base/embeddings/aiml_embeddings.py +62 -0
  34. lfx/base/embeddings/model.py +26 -0
  35. lfx/base/flow_processing/__init__.py +0 -0
  36. lfx/base/flow_processing/utils.py +86 -0
  37. lfx/base/huggingface/__init__.py +0 -0
  38. lfx/base/huggingface/model_bridge.py +133 -0
  39. lfx/base/io/__init__.py +0 -0
  40. lfx/base/io/chat.py +20 -0
  41. lfx/base/io/text.py +22 -0
  42. lfx/base/langchain_utilities/__init__.py +0 -0
  43. lfx/base/langchain_utilities/model.py +35 -0
  44. lfx/base/langchain_utilities/spider_constants.py +1 -0
  45. lfx/base/langwatch/__init__.py +0 -0
  46. lfx/base/langwatch/utils.py +18 -0
  47. lfx/base/mcp/__init__.py +0 -0
  48. lfx/base/mcp/constants.py +2 -0
  49. lfx/base/mcp/util.py +1398 -0
  50. lfx/base/memory/__init__.py +0 -0
  51. lfx/base/memory/memory.py +49 -0
  52. lfx/base/memory/model.py +38 -0
  53. lfx/base/models/__init__.py +3 -0
  54. lfx/base/models/aiml_constants.py +51 -0
  55. lfx/base/models/anthropic_constants.py +47 -0
  56. lfx/base/models/aws_constants.py +151 -0
  57. lfx/base/models/chat_result.py +76 -0
  58. lfx/base/models/google_generative_ai_constants.py +70 -0
  59. lfx/base/models/groq_constants.py +134 -0
  60. lfx/base/models/model.py +375 -0
  61. lfx/base/models/model_input_constants.py +307 -0
  62. lfx/base/models/model_metadata.py +41 -0
  63. lfx/base/models/model_utils.py +8 -0
  64. lfx/base/models/novita_constants.py +35 -0
  65. lfx/base/models/ollama_constants.py +49 -0
  66. lfx/base/models/openai_constants.py +122 -0
  67. lfx/base/models/sambanova_constants.py +18 -0
  68. lfx/base/processing/__init__.py +0 -0
  69. lfx/base/prompts/__init__.py +0 -0
  70. lfx/base/prompts/api_utils.py +224 -0
  71. lfx/base/prompts/utils.py +61 -0
  72. lfx/base/textsplitters/__init__.py +0 -0
  73. lfx/base/textsplitters/model.py +28 -0
  74. lfx/base/tools/__init__.py +0 -0
  75. lfx/base/tools/base.py +26 -0
  76. lfx/base/tools/component_tool.py +325 -0
  77. lfx/base/tools/constants.py +49 -0
  78. lfx/base/tools/flow_tool.py +132 -0
  79. lfx/base/tools/run_flow.py +224 -0
  80. lfx/base/vectorstores/__init__.py +0 -0
  81. lfx/base/vectorstores/model.py +193 -0
  82. lfx/base/vectorstores/utils.py +22 -0
  83. lfx/base/vectorstores/vector_store_connection_decorator.py +52 -0
  84. lfx/cli/__init__.py +5 -0
  85. lfx/cli/commands.py +319 -0
  86. lfx/cli/common.py +650 -0
  87. lfx/cli/run.py +441 -0
  88. lfx/cli/script_loader.py +247 -0
  89. lfx/cli/serve_app.py +546 -0
  90. lfx/cli/validation.py +69 -0
  91. lfx/components/FAISS/__init__.py +34 -0
  92. lfx/components/FAISS/faiss.py +111 -0
  93. lfx/components/Notion/__init__.py +19 -0
  94. lfx/components/Notion/add_content_to_page.py +269 -0
  95. lfx/components/Notion/create_page.py +94 -0
  96. lfx/components/Notion/list_database_properties.py +68 -0
  97. lfx/components/Notion/list_pages.py +122 -0
  98. lfx/components/Notion/list_users.py +77 -0
  99. lfx/components/Notion/page_content_viewer.py +93 -0
  100. lfx/components/Notion/search.py +111 -0
  101. lfx/components/Notion/update_page_property.py +114 -0
  102. lfx/components/__init__.py +411 -0
  103. lfx/components/_importing.py +42 -0
  104. lfx/components/agentql/__init__.py +3 -0
  105. lfx/components/agentql/agentql_api.py +151 -0
  106. lfx/components/agents/__init__.py +34 -0
  107. lfx/components/agents/agent.py +558 -0
  108. lfx/components/agents/mcp_component.py +501 -0
  109. lfx/components/aiml/__init__.py +37 -0
  110. lfx/components/aiml/aiml.py +112 -0
  111. lfx/components/aiml/aiml_embeddings.py +37 -0
  112. lfx/components/amazon/__init__.py +36 -0
  113. lfx/components/amazon/amazon_bedrock_embedding.py +109 -0
  114. lfx/components/amazon/amazon_bedrock_model.py +124 -0
  115. lfx/components/amazon/s3_bucket_uploader.py +211 -0
  116. lfx/components/anthropic/__init__.py +34 -0
  117. lfx/components/anthropic/anthropic.py +187 -0
  118. lfx/components/apify/__init__.py +5 -0
  119. lfx/components/apify/apify_actor.py +325 -0
  120. lfx/components/arxiv/__init__.py +3 -0
  121. lfx/components/arxiv/arxiv.py +163 -0
  122. lfx/components/assemblyai/__init__.py +46 -0
  123. lfx/components/assemblyai/assemblyai_get_subtitles.py +83 -0
  124. lfx/components/assemblyai/assemblyai_lemur.py +183 -0
  125. lfx/components/assemblyai/assemblyai_list_transcripts.py +95 -0
  126. lfx/components/assemblyai/assemblyai_poll_transcript.py +72 -0
  127. lfx/components/assemblyai/assemblyai_start_transcript.py +188 -0
  128. lfx/components/azure/__init__.py +37 -0
  129. lfx/components/azure/azure_openai.py +95 -0
  130. lfx/components/azure/azure_openai_embeddings.py +83 -0
  131. lfx/components/baidu/__init__.py +32 -0
  132. lfx/components/baidu/baidu_qianfan_chat.py +113 -0
  133. lfx/components/bing/__init__.py +3 -0
  134. lfx/components/bing/bing_search_api.py +61 -0
  135. lfx/components/cassandra/__init__.py +40 -0
  136. lfx/components/cassandra/cassandra.py +264 -0
  137. lfx/components/cassandra/cassandra_chat.py +92 -0
  138. lfx/components/cassandra/cassandra_graph.py +238 -0
  139. lfx/components/chains/__init__.py +3 -0
  140. lfx/components/chroma/__init__.py +34 -0
  141. lfx/components/chroma/chroma.py +167 -0
  142. lfx/components/cleanlab/__init__.py +40 -0
  143. lfx/components/cleanlab/cleanlab_evaluator.py +155 -0
  144. lfx/components/cleanlab/cleanlab_rag_evaluator.py +254 -0
  145. lfx/components/cleanlab/cleanlab_remediator.py +131 -0
  146. lfx/components/clickhouse/__init__.py +34 -0
  147. lfx/components/clickhouse/clickhouse.py +135 -0
  148. lfx/components/cloudflare/__init__.py +32 -0
  149. lfx/components/cloudflare/cloudflare.py +81 -0
  150. lfx/components/cohere/__init__.py +40 -0
  151. lfx/components/cohere/cohere_embeddings.py +81 -0
  152. lfx/components/cohere/cohere_models.py +46 -0
  153. lfx/components/cohere/cohere_rerank.py +51 -0
  154. lfx/components/composio/__init__.py +74 -0
  155. lfx/components/composio/composio_api.py +268 -0
  156. lfx/components/composio/dropbox_compnent.py +11 -0
  157. lfx/components/composio/github_composio.py +11 -0
  158. lfx/components/composio/gmail_composio.py +38 -0
  159. lfx/components/composio/googlecalendar_composio.py +11 -0
  160. lfx/components/composio/googlemeet_composio.py +11 -0
  161. lfx/components/composio/googletasks_composio.py +8 -0
  162. lfx/components/composio/linear_composio.py +11 -0
  163. lfx/components/composio/outlook_composio.py +11 -0
  164. lfx/components/composio/reddit_composio.py +11 -0
  165. lfx/components/composio/slack_composio.py +582 -0
  166. lfx/components/composio/slackbot_composio.py +11 -0
  167. lfx/components/composio/supabase_composio.py +11 -0
  168. lfx/components/composio/todoist_composio.py +11 -0
  169. lfx/components/composio/youtube_composio.py +11 -0
  170. lfx/components/confluence/__init__.py +3 -0
  171. lfx/components/confluence/confluence.py +84 -0
  172. lfx/components/couchbase/__init__.py +34 -0
  173. lfx/components/couchbase/couchbase.py +102 -0
  174. lfx/components/crewai/__init__.py +49 -0
  175. lfx/components/crewai/crewai.py +107 -0
  176. lfx/components/crewai/hierarchical_crew.py +46 -0
  177. lfx/components/crewai/hierarchical_task.py +44 -0
  178. lfx/components/crewai/sequential_crew.py +52 -0
  179. lfx/components/crewai/sequential_task.py +73 -0
  180. lfx/components/crewai/sequential_task_agent.py +143 -0
  181. lfx/components/custom_component/__init__.py +34 -0
  182. lfx/components/custom_component/custom_component.py +31 -0
  183. lfx/components/data/__init__.py +64 -0
  184. lfx/components/data/api_request.py +544 -0
  185. lfx/components/data/csv_to_data.py +95 -0
  186. lfx/components/data/directory.py +113 -0
  187. lfx/components/data/file.py +577 -0
  188. lfx/components/data/json_to_data.py +98 -0
  189. lfx/components/data/news_search.py +164 -0
  190. lfx/components/data/rss.py +69 -0
  191. lfx/components/data/sql_executor.py +101 -0
  192. lfx/components/data/url.py +311 -0
  193. lfx/components/data/web_search.py +112 -0
  194. lfx/components/data/webhook.py +56 -0
  195. lfx/components/datastax/__init__.py +70 -0
  196. lfx/components/datastax/astra_assistant_manager.py +306 -0
  197. lfx/components/datastax/astra_db.py +75 -0
  198. lfx/components/datastax/astra_vectorize.py +124 -0
  199. lfx/components/datastax/astradb.py +1285 -0
  200. lfx/components/datastax/astradb_cql.py +314 -0
  201. lfx/components/datastax/astradb_graph.py +330 -0
  202. lfx/components/datastax/astradb_tool.py +414 -0
  203. lfx/components/datastax/astradb_vectorstore.py +1285 -0
  204. lfx/components/datastax/cassandra.py +92 -0
  205. lfx/components/datastax/create_assistant.py +58 -0
  206. lfx/components/datastax/create_thread.py +32 -0
  207. lfx/components/datastax/dotenv.py +35 -0
  208. lfx/components/datastax/get_assistant.py +37 -0
  209. lfx/components/datastax/getenvvar.py +30 -0
  210. lfx/components/datastax/graph_rag.py +141 -0
  211. lfx/components/datastax/hcd.py +314 -0
  212. lfx/components/datastax/list_assistants.py +25 -0
  213. lfx/components/datastax/run.py +89 -0
  214. lfx/components/deactivated/__init__.py +15 -0
  215. lfx/components/deactivated/amazon_kendra.py +66 -0
  216. lfx/components/deactivated/chat_litellm_model.py +158 -0
  217. lfx/components/deactivated/code_block_extractor.py +26 -0
  218. lfx/components/deactivated/documents_to_data.py +22 -0
  219. lfx/components/deactivated/embed.py +16 -0
  220. lfx/components/deactivated/extract_key_from_data.py +46 -0
  221. lfx/components/deactivated/json_document_builder.py +57 -0
  222. lfx/components/deactivated/list_flows.py +20 -0
  223. lfx/components/deactivated/mcp_sse.py +61 -0
  224. lfx/components/deactivated/mcp_stdio.py +62 -0
  225. lfx/components/deactivated/merge_data.py +93 -0
  226. lfx/components/deactivated/message.py +37 -0
  227. lfx/components/deactivated/metal.py +54 -0
  228. lfx/components/deactivated/multi_query.py +59 -0
  229. lfx/components/deactivated/retriever.py +43 -0
  230. lfx/components/deactivated/selective_passthrough.py +77 -0
  231. lfx/components/deactivated/should_run_next.py +40 -0
  232. lfx/components/deactivated/split_text.py +63 -0
  233. lfx/components/deactivated/store_message.py +24 -0
  234. lfx/components/deactivated/sub_flow.py +124 -0
  235. lfx/components/deactivated/vectara_self_query.py +76 -0
  236. lfx/components/deactivated/vector_store.py +24 -0
  237. lfx/components/deepseek/__init__.py +34 -0
  238. lfx/components/deepseek/deepseek.py +136 -0
  239. lfx/components/docling/__init__.py +43 -0
  240. lfx/components/docling/chunk_docling_document.py +186 -0
  241. lfx/components/docling/docling_inline.py +231 -0
  242. lfx/components/docling/docling_remote.py +193 -0
  243. lfx/components/docling/export_docling_document.py +117 -0
  244. lfx/components/documentloaders/__init__.py +3 -0
  245. lfx/components/duckduckgo/__init__.py +3 -0
  246. lfx/components/duckduckgo/duck_duck_go_search_run.py +92 -0
  247. lfx/components/elastic/__init__.py +37 -0
  248. lfx/components/elastic/elasticsearch.py +267 -0
  249. lfx/components/elastic/opensearch.py +243 -0
  250. lfx/components/embeddings/__init__.py +37 -0
  251. lfx/components/embeddings/similarity.py +76 -0
  252. lfx/components/embeddings/text_embedder.py +64 -0
  253. lfx/components/exa/__init__.py +3 -0
  254. lfx/components/exa/exa_search.py +68 -0
  255. lfx/components/firecrawl/__init__.py +43 -0
  256. lfx/components/firecrawl/firecrawl_crawl_api.py +88 -0
  257. lfx/components/firecrawl/firecrawl_extract_api.py +136 -0
  258. lfx/components/firecrawl/firecrawl_map_api.py +89 -0
  259. lfx/components/firecrawl/firecrawl_scrape_api.py +73 -0
  260. lfx/components/git/__init__.py +4 -0
  261. lfx/components/git/git.py +262 -0
  262. lfx/components/git/gitextractor.py +196 -0
  263. lfx/components/glean/__init__.py +3 -0
  264. lfx/components/glean/glean_search_api.py +173 -0
  265. lfx/components/google/__init__.py +17 -0
  266. lfx/components/google/gmail.py +192 -0
  267. lfx/components/google/google_bq_sql_executor.py +157 -0
  268. lfx/components/google/google_drive.py +92 -0
  269. lfx/components/google/google_drive_search.py +152 -0
  270. lfx/components/google/google_generative_ai.py +147 -0
  271. lfx/components/google/google_generative_ai_embeddings.py +141 -0
  272. lfx/components/google/google_oauth_token.py +89 -0
  273. lfx/components/google/google_search_api_core.py +68 -0
  274. lfx/components/google/google_serper_api_core.py +74 -0
  275. lfx/components/groq/__init__.py +34 -0
  276. lfx/components/groq/groq.py +136 -0
  277. lfx/components/helpers/__init__.py +52 -0
  278. lfx/components/helpers/calculator_core.py +89 -0
  279. lfx/components/helpers/create_list.py +40 -0
  280. lfx/components/helpers/current_date.py +42 -0
  281. lfx/components/helpers/id_generator.py +42 -0
  282. lfx/components/helpers/memory.py +251 -0
  283. lfx/components/helpers/output_parser.py +45 -0
  284. lfx/components/helpers/store_message.py +90 -0
  285. lfx/components/homeassistant/__init__.py +7 -0
  286. lfx/components/homeassistant/home_assistant_control.py +152 -0
  287. lfx/components/homeassistant/list_home_assistant_states.py +137 -0
  288. lfx/components/huggingface/__init__.py +37 -0
  289. lfx/components/huggingface/huggingface.py +197 -0
  290. lfx/components/huggingface/huggingface_inference_api.py +106 -0
  291. lfx/components/ibm/__init__.py +34 -0
  292. lfx/components/ibm/watsonx.py +203 -0
  293. lfx/components/ibm/watsonx_embeddings.py +135 -0
  294. lfx/components/icosacomputing/__init__.py +5 -0
  295. lfx/components/icosacomputing/combinatorial_reasoner.py +84 -0
  296. lfx/components/input_output/__init__.py +38 -0
  297. lfx/components/input_output/chat.py +120 -0
  298. lfx/components/input_output/chat_output.py +200 -0
  299. lfx/components/input_output/text.py +27 -0
  300. lfx/components/input_output/text_output.py +29 -0
  301. lfx/components/jigsawstack/__init__.py +23 -0
  302. lfx/components/jigsawstack/ai_scrape.py +126 -0
  303. lfx/components/jigsawstack/ai_web_search.py +136 -0
  304. lfx/components/jigsawstack/file_read.py +115 -0
  305. lfx/components/jigsawstack/file_upload.py +94 -0
  306. lfx/components/jigsawstack/image_generation.py +205 -0
  307. lfx/components/jigsawstack/nsfw.py +60 -0
  308. lfx/components/jigsawstack/object_detection.py +124 -0
  309. lfx/components/jigsawstack/sentiment.py +112 -0
  310. lfx/components/jigsawstack/text_to_sql.py +90 -0
  311. lfx/components/jigsawstack/text_translate.py +77 -0
  312. lfx/components/jigsawstack/vocr.py +107 -0
  313. lfx/components/langchain_utilities/__init__.py +109 -0
  314. lfx/components/langchain_utilities/character.py +53 -0
  315. lfx/components/langchain_utilities/conversation.py +59 -0
  316. lfx/components/langchain_utilities/csv_agent.py +107 -0
  317. lfx/components/langchain_utilities/fake_embeddings.py +26 -0
  318. lfx/components/langchain_utilities/html_link_extractor.py +35 -0
  319. lfx/components/langchain_utilities/json_agent.py +45 -0
  320. lfx/components/langchain_utilities/langchain_hub.py +126 -0
  321. lfx/components/langchain_utilities/language_recursive.py +49 -0
  322. lfx/components/langchain_utilities/language_semantic.py +138 -0
  323. lfx/components/langchain_utilities/llm_checker.py +39 -0
  324. lfx/components/langchain_utilities/llm_math.py +42 -0
  325. lfx/components/langchain_utilities/natural_language.py +61 -0
  326. lfx/components/langchain_utilities/openai_tools.py +53 -0
  327. lfx/components/langchain_utilities/openapi.py +48 -0
  328. lfx/components/langchain_utilities/recursive_character.py +60 -0
  329. lfx/components/langchain_utilities/retrieval_qa.py +83 -0
  330. lfx/components/langchain_utilities/runnable_executor.py +137 -0
  331. lfx/components/langchain_utilities/self_query.py +80 -0
  332. lfx/components/langchain_utilities/spider.py +142 -0
  333. lfx/components/langchain_utilities/sql.py +40 -0
  334. lfx/components/langchain_utilities/sql_database.py +35 -0
  335. lfx/components/langchain_utilities/sql_generator.py +78 -0
  336. lfx/components/langchain_utilities/tool_calling.py +59 -0
  337. lfx/components/langchain_utilities/vector_store_info.py +49 -0
  338. lfx/components/langchain_utilities/vector_store_router.py +33 -0
  339. lfx/components/langchain_utilities/xml_agent.py +71 -0
  340. lfx/components/langwatch/__init__.py +3 -0
  341. lfx/components/langwatch/langwatch.py +278 -0
  342. lfx/components/link_extractors/__init__.py +3 -0
  343. lfx/components/lmstudio/__init__.py +34 -0
  344. lfx/components/lmstudio/lmstudioembeddings.py +89 -0
  345. lfx/components/lmstudio/lmstudiomodel.py +129 -0
  346. lfx/components/logic/__init__.py +52 -0
  347. lfx/components/logic/conditional_router.py +171 -0
  348. lfx/components/logic/data_conditional_router.py +125 -0
  349. lfx/components/logic/flow_tool.py +110 -0
  350. lfx/components/logic/listen.py +29 -0
  351. lfx/components/logic/loop.py +125 -0
  352. lfx/components/logic/notify.py +88 -0
  353. lfx/components/logic/pass_message.py +35 -0
  354. lfx/components/logic/run_flow.py +71 -0
  355. lfx/components/logic/sub_flow.py +114 -0
  356. lfx/components/maritalk/__init__.py +32 -0
  357. lfx/components/maritalk/maritalk.py +52 -0
  358. lfx/components/mem0/__init__.py +3 -0
  359. lfx/components/mem0/mem0_chat_memory.py +136 -0
  360. lfx/components/milvus/__init__.py +34 -0
  361. lfx/components/milvus/milvus.py +115 -0
  362. lfx/components/mistral/__init__.py +37 -0
  363. lfx/components/mistral/mistral.py +114 -0
  364. lfx/components/mistral/mistral_embeddings.py +58 -0
  365. lfx/components/models/__init__.py +34 -0
  366. lfx/components/models/embedding_model.py +114 -0
  367. lfx/components/models/language_model.py +144 -0
  368. lfx/components/mongodb/__init__.py +34 -0
  369. lfx/components/mongodb/mongodb_atlas.py +213 -0
  370. lfx/components/needle/__init__.py +3 -0
  371. lfx/components/needle/needle.py +104 -0
  372. lfx/components/notdiamond/__init__.py +34 -0
  373. lfx/components/notdiamond/notdiamond.py +228 -0
  374. lfx/components/novita/__init__.py +32 -0
  375. lfx/components/novita/novita.py +130 -0
  376. lfx/components/nvidia/__init__.py +57 -0
  377. lfx/components/nvidia/nvidia.py +157 -0
  378. lfx/components/nvidia/nvidia_embedding.py +77 -0
  379. lfx/components/nvidia/nvidia_ingest.py +317 -0
  380. lfx/components/nvidia/nvidia_rerank.py +63 -0
  381. lfx/components/nvidia/system_assist.py +65 -0
  382. lfx/components/olivya/__init__.py +3 -0
  383. lfx/components/olivya/olivya.py +116 -0
  384. lfx/components/ollama/__init__.py +37 -0
  385. lfx/components/ollama/ollama.py +330 -0
  386. lfx/components/ollama/ollama_embeddings.py +106 -0
  387. lfx/components/openai/__init__.py +37 -0
  388. lfx/components/openai/openai.py +100 -0
  389. lfx/components/openai/openai_chat_model.py +176 -0
  390. lfx/components/openrouter/__init__.py +32 -0
  391. lfx/components/openrouter/openrouter.py +202 -0
  392. lfx/components/output_parsers/__init__.py +3 -0
  393. lfx/components/perplexity/__init__.py +34 -0
  394. lfx/components/perplexity/perplexity.py +75 -0
  395. lfx/components/pgvector/__init__.py +34 -0
  396. lfx/components/pgvector/pgvector.py +72 -0
  397. lfx/components/pinecone/__init__.py +34 -0
  398. lfx/components/pinecone/pinecone.py +134 -0
  399. lfx/components/processing/__init__.py +117 -0
  400. lfx/components/processing/alter_metadata.py +108 -0
  401. lfx/components/processing/batch_run.py +205 -0
  402. lfx/components/processing/combine_text.py +39 -0
  403. lfx/components/processing/converter.py +159 -0
  404. lfx/components/processing/create_data.py +110 -0
  405. lfx/components/processing/data_operations.py +438 -0
  406. lfx/components/processing/data_to_dataframe.py +70 -0
  407. lfx/components/processing/dataframe_operations.py +313 -0
  408. lfx/components/processing/extract_key.py +53 -0
  409. lfx/components/processing/filter_data.py +42 -0
  410. lfx/components/processing/filter_data_values.py +88 -0
  411. lfx/components/processing/json_cleaner.py +103 -0
  412. lfx/components/processing/lambda_filter.py +154 -0
  413. lfx/components/processing/llm_router.py +499 -0
  414. lfx/components/processing/merge_data.py +90 -0
  415. lfx/components/processing/message_to_data.py +36 -0
  416. lfx/components/processing/parse_data.py +70 -0
  417. lfx/components/processing/parse_dataframe.py +68 -0
  418. lfx/components/processing/parse_json_data.py +90 -0
  419. lfx/components/processing/parser.py +143 -0
  420. lfx/components/processing/prompt.py +67 -0
  421. lfx/components/processing/python_repl_core.py +98 -0
  422. lfx/components/processing/regex.py +82 -0
  423. lfx/components/processing/save_file.py +225 -0
  424. lfx/components/processing/select_data.py +48 -0
  425. lfx/components/processing/split_text.py +141 -0
  426. lfx/components/processing/structured_output.py +202 -0
  427. lfx/components/processing/update_data.py +160 -0
  428. lfx/components/prototypes/__init__.py +34 -0
  429. lfx/components/prototypes/python_function.py +73 -0
  430. lfx/components/qdrant/__init__.py +34 -0
  431. lfx/components/qdrant/qdrant.py +109 -0
  432. lfx/components/redis/__init__.py +37 -0
  433. lfx/components/redis/redis.py +89 -0
  434. lfx/components/redis/redis_chat.py +43 -0
  435. lfx/components/sambanova/__init__.py +32 -0
  436. lfx/components/sambanova/sambanova.py +84 -0
  437. lfx/components/scrapegraph/__init__.py +40 -0
  438. lfx/components/scrapegraph/scrapegraph_markdownify_api.py +64 -0
  439. lfx/components/scrapegraph/scrapegraph_search_api.py +64 -0
  440. lfx/components/scrapegraph/scrapegraph_smart_scraper_api.py +71 -0
  441. lfx/components/searchapi/__init__.py +34 -0
  442. lfx/components/searchapi/search.py +79 -0
  443. lfx/components/serpapi/__init__.py +3 -0
  444. lfx/components/serpapi/serp.py +115 -0
  445. lfx/components/supabase/__init__.py +34 -0
  446. lfx/components/supabase/supabase.py +76 -0
  447. lfx/components/tavily/__init__.py +4 -0
  448. lfx/components/tavily/tavily_extract.py +117 -0
  449. lfx/components/tavily/tavily_search.py +212 -0
  450. lfx/components/textsplitters/__init__.py +3 -0
  451. lfx/components/toolkits/__init__.py +3 -0
  452. lfx/components/tools/__init__.py +72 -0
  453. lfx/components/tools/calculator.py +108 -0
  454. lfx/components/tools/google_search_api.py +45 -0
  455. lfx/components/tools/google_serper_api.py +115 -0
  456. lfx/components/tools/python_code_structured_tool.py +327 -0
  457. lfx/components/tools/python_repl.py +97 -0
  458. lfx/components/tools/search_api.py +87 -0
  459. lfx/components/tools/searxng.py +145 -0
  460. lfx/components/tools/serp_api.py +119 -0
  461. lfx/components/tools/tavily_search_tool.py +344 -0
  462. lfx/components/tools/wikidata_api.py +102 -0
  463. lfx/components/tools/wikipedia_api.py +49 -0
  464. lfx/components/tools/yahoo_finance.py +129 -0
  465. lfx/components/twelvelabs/__init__.py +52 -0
  466. lfx/components/twelvelabs/convert_astra_results.py +84 -0
  467. lfx/components/twelvelabs/pegasus_index.py +311 -0
  468. lfx/components/twelvelabs/split_video.py +291 -0
  469. lfx/components/twelvelabs/text_embeddings.py +57 -0
  470. lfx/components/twelvelabs/twelvelabs_pegasus.py +408 -0
  471. lfx/components/twelvelabs/video_embeddings.py +100 -0
  472. lfx/components/twelvelabs/video_file.py +179 -0
  473. lfx/components/unstructured/__init__.py +3 -0
  474. lfx/components/unstructured/unstructured.py +121 -0
  475. lfx/components/upstash/__init__.py +34 -0
  476. lfx/components/upstash/upstash.py +124 -0
  477. lfx/components/vectara/__init__.py +37 -0
  478. lfx/components/vectara/vectara.py +97 -0
  479. lfx/components/vectara/vectara_rag.py +164 -0
  480. lfx/components/vectorstores/__init__.py +40 -0
  481. lfx/components/vectorstores/astradb.py +1285 -0
  482. lfx/components/vectorstores/astradb_graph.py +319 -0
  483. lfx/components/vectorstores/cassandra.py +264 -0
  484. lfx/components/vectorstores/cassandra_graph.py +238 -0
  485. lfx/components/vectorstores/chroma.py +167 -0
  486. lfx/components/vectorstores/clickhouse.py +135 -0
  487. lfx/components/vectorstores/couchbase.py +102 -0
  488. lfx/components/vectorstores/elasticsearch.py +267 -0
  489. lfx/components/vectorstores/faiss.py +111 -0
  490. lfx/components/vectorstores/graph_rag.py +141 -0
  491. lfx/components/vectorstores/hcd.py +314 -0
  492. lfx/components/vectorstores/local_db.py +261 -0
  493. lfx/components/vectorstores/milvus.py +115 -0
  494. lfx/components/vectorstores/mongodb_atlas.py +213 -0
  495. lfx/components/vectorstores/opensearch.py +243 -0
  496. lfx/components/vectorstores/pgvector.py +72 -0
  497. lfx/components/vectorstores/pinecone.py +134 -0
  498. lfx/components/vectorstores/qdrant.py +109 -0
  499. lfx/components/vectorstores/supabase.py +76 -0
  500. lfx/components/vectorstores/upstash.py +124 -0
  501. lfx/components/vectorstores/vectara.py +97 -0
  502. lfx/components/vectorstores/vectara_rag.py +164 -0
  503. lfx/components/vectorstores/weaviate.py +89 -0
  504. lfx/components/vertexai/__init__.py +37 -0
  505. lfx/components/vertexai/vertexai.py +71 -0
  506. lfx/components/vertexai/vertexai_embeddings.py +67 -0
  507. lfx/components/weaviate/__init__.py +34 -0
  508. lfx/components/weaviate/weaviate.py +89 -0
  509. lfx/components/wikipedia/__init__.py +4 -0
  510. lfx/components/wikipedia/wikidata.py +86 -0
  511. lfx/components/wikipedia/wikipedia.py +53 -0
  512. lfx/components/wolframalpha/__init__.py +3 -0
  513. lfx/components/wolframalpha/wolfram_alpha_api.py +54 -0
  514. lfx/components/xai/__init__.py +32 -0
  515. lfx/components/xai/xai.py +167 -0
  516. lfx/components/yahoosearch/__init__.py +3 -0
  517. lfx/components/yahoosearch/yahoo.py +137 -0
  518. lfx/components/youtube/__init__.py +52 -0
  519. lfx/components/youtube/channel.py +227 -0
  520. lfx/components/youtube/comments.py +231 -0
  521. lfx/components/youtube/playlist.py +33 -0
  522. lfx/components/youtube/search.py +120 -0
  523. lfx/components/youtube/trending.py +285 -0
  524. lfx/components/youtube/video_details.py +263 -0
  525. lfx/components/youtube/youtube_transcripts.py +118 -0
  526. lfx/components/zep/__init__.py +3 -0
  527. lfx/components/zep/zep.py +44 -0
  528. lfx/constants.py +6 -0
  529. lfx/custom/__init__.py +7 -0
  530. lfx/custom/attributes.py +86 -0
  531. lfx/custom/code_parser/__init__.py +3 -0
  532. lfx/custom/code_parser/code_parser.py +361 -0
  533. lfx/custom/custom_component/__init__.py +0 -0
  534. lfx/custom/custom_component/base_component.py +128 -0
  535. lfx/custom/custom_component/component.py +1808 -0
  536. lfx/custom/custom_component/component_with_cache.py +8 -0
  537. lfx/custom/custom_component/custom_component.py +588 -0
  538. lfx/custom/dependency_analyzer.py +165 -0
  539. lfx/custom/directory_reader/__init__.py +3 -0
  540. lfx/custom/directory_reader/directory_reader.py +359 -0
  541. lfx/custom/directory_reader/utils.py +171 -0
  542. lfx/custom/eval.py +12 -0
  543. lfx/custom/schema.py +32 -0
  544. lfx/custom/tree_visitor.py +21 -0
  545. lfx/custom/utils.py +877 -0
  546. lfx/custom/validate.py +488 -0
  547. lfx/events/__init__.py +1 -0
  548. lfx/events/event_manager.py +110 -0
  549. lfx/exceptions/__init__.py +0 -0
  550. lfx/exceptions/component.py +15 -0
  551. lfx/field_typing/__init__.py +91 -0
  552. lfx/field_typing/constants.py +215 -0
  553. lfx/field_typing/range_spec.py +35 -0
  554. lfx/graph/__init__.py +6 -0
  555. lfx/graph/edge/__init__.py +0 -0
  556. lfx/graph/edge/base.py +277 -0
  557. lfx/graph/edge/schema.py +119 -0
  558. lfx/graph/edge/utils.py +0 -0
  559. lfx/graph/graph/__init__.py +0 -0
  560. lfx/graph/graph/ascii.py +202 -0
  561. lfx/graph/graph/base.py +2238 -0
  562. lfx/graph/graph/constants.py +63 -0
  563. lfx/graph/graph/runnable_vertices_manager.py +133 -0
  564. lfx/graph/graph/schema.py +52 -0
  565. lfx/graph/graph/state_model.py +66 -0
  566. lfx/graph/graph/utils.py +1024 -0
  567. lfx/graph/schema.py +75 -0
  568. lfx/graph/state/__init__.py +0 -0
  569. lfx/graph/state/model.py +237 -0
  570. lfx/graph/utils.py +200 -0
  571. lfx/graph/vertex/__init__.py +0 -0
  572. lfx/graph/vertex/base.py +823 -0
  573. lfx/graph/vertex/constants.py +0 -0
  574. lfx/graph/vertex/exceptions.py +4 -0
  575. lfx/graph/vertex/param_handler.py +264 -0
  576. lfx/graph/vertex/schema.py +26 -0
  577. lfx/graph/vertex/utils.py +19 -0
  578. lfx/graph/vertex/vertex_types.py +489 -0
  579. lfx/helpers/__init__.py +1 -0
  580. lfx/helpers/base_model.py +71 -0
  581. lfx/helpers/custom.py +13 -0
  582. lfx/helpers/data.py +167 -0
  583. lfx/helpers/flow.py +194 -0
  584. lfx/inputs/__init__.py +68 -0
  585. lfx/inputs/constants.py +2 -0
  586. lfx/inputs/input_mixin.py +328 -0
  587. lfx/inputs/inputs.py +714 -0
  588. lfx/inputs/validators.py +19 -0
  589. lfx/interface/__init__.py +6 -0
  590. lfx/interface/components.py +489 -0
  591. lfx/interface/importing/__init__.py +5 -0
  592. lfx/interface/importing/utils.py +39 -0
  593. lfx/interface/initialize/__init__.py +3 -0
  594. lfx/interface/initialize/loading.py +224 -0
  595. lfx/interface/listing.py +26 -0
  596. lfx/interface/run.py +16 -0
  597. lfx/interface/utils.py +111 -0
  598. lfx/io/__init__.py +63 -0
  599. lfx/io/schema.py +289 -0
  600. lfx/load/__init__.py +8 -0
  601. lfx/load/load.py +256 -0
  602. lfx/load/utils.py +99 -0
  603. lfx/log/__init__.py +5 -0
  604. lfx/log/logger.py +385 -0
  605. lfx/memory/__init__.py +90 -0
  606. lfx/memory/stubs.py +283 -0
  607. lfx/processing/__init__.py +1 -0
  608. lfx/processing/process.py +238 -0
  609. lfx/processing/utils.py +25 -0
  610. lfx/py.typed +0 -0
  611. lfx/schema/__init__.py +66 -0
  612. lfx/schema/artifact.py +83 -0
  613. lfx/schema/content_block.py +62 -0
  614. lfx/schema/content_types.py +91 -0
  615. lfx/schema/data.py +308 -0
  616. lfx/schema/dataframe.py +210 -0
  617. lfx/schema/dotdict.py +74 -0
  618. lfx/schema/encoders.py +13 -0
  619. lfx/schema/graph.py +47 -0
  620. lfx/schema/image.py +131 -0
  621. lfx/schema/json_schema.py +141 -0
  622. lfx/schema/log.py +61 -0
  623. lfx/schema/message.py +473 -0
  624. lfx/schema/openai_responses_schemas.py +74 -0
  625. lfx/schema/properties.py +41 -0
  626. lfx/schema/schema.py +171 -0
  627. lfx/schema/serialize.py +13 -0
  628. lfx/schema/table.py +140 -0
  629. lfx/schema/validators.py +114 -0
  630. lfx/serialization/__init__.py +5 -0
  631. lfx/serialization/constants.py +2 -0
  632. lfx/serialization/serialization.py +314 -0
  633. lfx/services/__init__.py +23 -0
  634. lfx/services/base.py +28 -0
  635. lfx/services/cache/__init__.py +6 -0
  636. lfx/services/cache/base.py +183 -0
  637. lfx/services/cache/service.py +166 -0
  638. lfx/services/cache/utils.py +169 -0
  639. lfx/services/chat/__init__.py +1 -0
  640. lfx/services/chat/config.py +2 -0
  641. lfx/services/chat/schema.py +10 -0
  642. lfx/services/deps.py +129 -0
  643. lfx/services/factory.py +19 -0
  644. lfx/services/initialize.py +19 -0
  645. lfx/services/interfaces.py +103 -0
  646. lfx/services/manager.py +172 -0
  647. lfx/services/schema.py +20 -0
  648. lfx/services/session.py +82 -0
  649. lfx/services/settings/__init__.py +3 -0
  650. lfx/services/settings/auth.py +130 -0
  651. lfx/services/settings/base.py +539 -0
  652. lfx/services/settings/constants.py +31 -0
  653. lfx/services/settings/factory.py +23 -0
  654. lfx/services/settings/feature_flags.py +12 -0
  655. lfx/services/settings/service.py +35 -0
  656. lfx/services/settings/utils.py +40 -0
  657. lfx/services/shared_component_cache/__init__.py +1 -0
  658. lfx/services/shared_component_cache/factory.py +30 -0
  659. lfx/services/shared_component_cache/service.py +9 -0
  660. lfx/services/storage/__init__.py +5 -0
  661. lfx/services/storage/local.py +155 -0
  662. lfx/services/storage/service.py +54 -0
  663. lfx/services/tracing/__init__.py +1 -0
  664. lfx/services/tracing/service.py +21 -0
  665. lfx/settings.py +6 -0
  666. lfx/template/__init__.py +6 -0
  667. lfx/template/field/__init__.py +0 -0
  668. lfx/template/field/base.py +257 -0
  669. lfx/template/field/prompt.py +15 -0
  670. lfx/template/frontend_node/__init__.py +6 -0
  671. lfx/template/frontend_node/base.py +212 -0
  672. lfx/template/frontend_node/constants.py +65 -0
  673. lfx/template/frontend_node/custom_components.py +79 -0
  674. lfx/template/template/__init__.py +0 -0
  675. lfx/template/template/base.py +100 -0
  676. lfx/template/utils.py +217 -0
  677. lfx/type_extraction/__init__.py +19 -0
  678. lfx/type_extraction/type_extraction.py +75 -0
  679. lfx/type_extraction.py +80 -0
  680. lfx/utils/__init__.py +1 -0
  681. lfx/utils/async_helpers.py +42 -0
  682. lfx/utils/component_utils.py +154 -0
  683. lfx/utils/concurrency.py +60 -0
  684. lfx/utils/connection_string_parser.py +11 -0
  685. lfx/utils/constants.py +205 -0
  686. lfx/utils/data_structure.py +212 -0
  687. lfx/utils/exceptions.py +22 -0
  688. lfx/utils/helpers.py +28 -0
  689. lfx/utils/image.py +73 -0
  690. lfx/utils/lazy_load.py +15 -0
  691. lfx/utils/request_utils.py +18 -0
  692. lfx/utils/schemas.py +139 -0
  693. lfx/utils/util.py +481 -0
  694. lfx/utils/util_strings.py +56 -0
  695. lfx/utils/version.py +24 -0
  696. lfx_nightly-0.1.11.dev0.dist-info/METADATA +293 -0
  697. lfx_nightly-0.1.11.dev0.dist-info/RECORD +699 -0
  698. lfx_nightly-0.1.11.dev0.dist-info/WHEEL +4 -0
  699. lfx_nightly-0.1.11.dev0.dist-info/entry_points.txt +2 -0
@@ -0,0 +1,62 @@
1
+ from typing import Annotated
2
+
3
+ from pydantic import BaseModel, Discriminator, Field, Tag, field_serializer, field_validator
4
+ from typing_extensions import TypedDict
5
+
6
+ from .content_types import CodeContent, ErrorContent, JSONContent, MediaContent, TextContent, ToolContent
7
+
8
+
9
+ def _get_type(d: dict | BaseModel) -> str | None:
10
+ if isinstance(d, dict):
11
+ return d.get("type")
12
+ return getattr(d, "type", None)
13
+
14
+
15
+ # Create a union type of all content types
16
+ ContentType = Annotated[
17
+ Annotated[ToolContent, Tag("tool_use")]
18
+ | Annotated[ErrorContent, Tag("error")]
19
+ | Annotated[TextContent, Tag("text")]
20
+ | Annotated[MediaContent, Tag("media")]
21
+ | Annotated[CodeContent, Tag("code")]
22
+ | Annotated[JSONContent, Tag("json")],
23
+ Discriminator(_get_type),
24
+ ]
25
+
26
+
27
+ class ContentBlock(BaseModel):
28
+ """A block of content that can contain different types of content."""
29
+
30
+ title: str
31
+ contents: list[ContentType]
32
+ allow_markdown: bool = Field(default=True)
33
+ media_url: list[str] | None = None
34
+
35
+ def __init__(self, **data) -> None:
36
+ super().__init__(**data)
37
+ schema_dict = self.__pydantic_core_schema__["schema"]
38
+ if "fields" in schema_dict:
39
+ fields = schema_dict["fields"]
40
+ elif "schema" in schema_dict:
41
+ fields = schema_dict["schema"]["fields"]
42
+ fields_with_default = (f for f, d in fields.items() if "default" in d["schema"])
43
+ self.model_fields_set.update(fields_with_default)
44
+
45
+ @field_validator("contents", mode="before")
46
+ @classmethod
47
+ def validate_contents(cls, v) -> list[ContentType]:
48
+ if isinstance(v, dict):
49
+ msg = "Contents must be a list of ContentTypes"
50
+ raise TypeError(msg)
51
+ return [v] if isinstance(v, BaseModel) else v
52
+
53
+ @field_serializer("contents")
54
+ def serialize_contents(self, value) -> list[dict]:
55
+ return [v.model_dump() for v in value]
56
+
57
+
58
+ class ContentBlockDict(TypedDict):
59
+ title: str
60
+ contents: list[dict]
61
+ allow_markdown: bool
62
+ media_url: list[str] | None
@@ -0,0 +1,91 @@
1
+ from typing import Any, Literal
2
+
3
+ from fastapi.encoders import jsonable_encoder
4
+ from pydantic import BaseModel, ConfigDict, Field, model_serializer
5
+ from typing_extensions import TypedDict
6
+
7
+ from lfx.schema.encoders import CUSTOM_ENCODERS
8
+
9
+
10
+ class HeaderDict(TypedDict, total=False):
11
+ title: str | None
12
+ icon: str | None
13
+
14
+
15
+ class BaseContent(BaseModel):
16
+ """Base class for all content types."""
17
+
18
+ type: str = Field(..., description="Type of the content")
19
+ duration: int | None = None
20
+ header: HeaderDict | None = Field(default_factory=dict)
21
+
22
+ def to_dict(self) -> dict[str, Any]:
23
+ return self.model_dump()
24
+
25
+ @classmethod
26
+ def from_dict(cls, data: dict[str, Any]) -> "BaseContent":
27
+ return cls(**data)
28
+
29
+ @model_serializer(mode="wrap")
30
+ def serialize_model(self, nxt) -> dict[str, Any]:
31
+ try:
32
+ dump = nxt(self)
33
+ return jsonable_encoder(dump, custom_encoder=CUSTOM_ENCODERS)
34
+ except Exception: # noqa: BLE001
35
+ return nxt(self)
36
+
37
+
38
+ class ErrorContent(BaseContent):
39
+ """Content type for error messages."""
40
+
41
+ type: Literal["error"] = Field(default="error")
42
+ component: str | None = None
43
+ field: str | None = None
44
+ reason: str | None = None
45
+ solution: str | None = None
46
+ traceback: str | None = None
47
+
48
+
49
+ class TextContent(BaseContent):
50
+ """Content type for simple text content."""
51
+
52
+ type: Literal["text"] = Field(default="text")
53
+ text: str
54
+ duration: int | None = None
55
+
56
+
57
+ class MediaContent(BaseContent):
58
+ """Content type for media content."""
59
+
60
+ type: Literal["media"] = Field(default="media")
61
+ urls: list[str]
62
+ caption: str | None = None
63
+
64
+
65
+ class JSONContent(BaseContent):
66
+ """Content type for JSON content."""
67
+
68
+ type: Literal["json"] = Field(default="json")
69
+ data: dict[str, Any]
70
+
71
+
72
+ class CodeContent(BaseContent):
73
+ """Content type for code snippets."""
74
+
75
+ type: Literal["code"] = Field(default="code")
76
+ code: str
77
+ language: str
78
+ title: str | None = None
79
+
80
+
81
+ class ToolContent(BaseContent):
82
+ """Content type for tool start content."""
83
+
84
+ model_config = ConfigDict(populate_by_name=True)
85
+
86
+ type: Literal["tool_use"] = Field(default="tool_use")
87
+ name: str | None = None
88
+ tool_input: dict[str, Any] = Field(default_factory=dict, alias="input")
89
+ output: Any | None = None
90
+ error: Any | None = None
91
+ duration: int | None = None
lfx/schema/data.py ADDED
@@ -0,0 +1,308 @@
1
+ """Lightweight Data class for lfx package - contains only methods with no langflow dependencies."""
2
+
3
+ from __future__ import annotations
4
+
5
+ import copy
6
+ import json
7
+ from datetime import datetime, timezone
8
+ from decimal import Decimal
9
+ from typing import TYPE_CHECKING, cast
10
+ from uuid import UUID
11
+
12
+ from langchain_core.documents import Document
13
+ from langchain_core.messages import AIMessage, BaseMessage, HumanMessage
14
+ from pydantic import BaseModel, ConfigDict, model_serializer, model_validator
15
+
16
+ from lfx.log.logger import logger
17
+ from lfx.utils.constants import MESSAGE_SENDER_AI, MESSAGE_SENDER_USER
18
+ from lfx.utils.image import create_image_content_dict
19
+
20
+ if TYPE_CHECKING:
21
+ from lfx.schema.dataframe import DataFrame
22
+ from lfx.schema.message import Message
23
+
24
+
25
+ class Data(BaseModel):
26
+ """Represents a record with text and optional data.
27
+
28
+ Attributes:
29
+ data (dict, optional): Additional data associated with the record.
30
+ """
31
+
32
+ model_config = ConfigDict(validate_assignment=True)
33
+
34
+ text_key: str = "text"
35
+ data: dict = {}
36
+ default_value: str | None = ""
37
+
38
+ @model_validator(mode="before")
39
+ @classmethod
40
+ def validate_data(cls, values):
41
+ if not isinstance(values, dict):
42
+ msg = "Data must be a dictionary"
43
+ raise ValueError(msg) # noqa: TRY004
44
+ if "data" not in values or values["data"] is None:
45
+ values["data"] = {}
46
+ if not isinstance(values["data"], dict):
47
+ msg = (
48
+ f"Invalid data format: expected dictionary but got {type(values).__name__}."
49
+ " This will raise an error in version langflow==1.3.0."
50
+ )
51
+ logger.warning(msg)
52
+ # Any other keyword should be added to the data dictionary
53
+ for key in values:
54
+ if key not in values["data"] and key not in {"text_key", "data", "default_value"}:
55
+ values["data"][key] = values[key]
56
+ return values
57
+
58
+ @model_serializer(mode="plain", when_used="json")
59
+ def serialize_model(self):
60
+ return {k: v.to_json() if hasattr(v, "to_json") else v for k, v in self.data.items()}
61
+
62
+ def get_text(self):
63
+ """Retrieves the text value from the data dictionary.
64
+
65
+ If the text key is present in the data dictionary, the corresponding value is returned.
66
+ Otherwise, the default value is returned.
67
+
68
+ Returns:
69
+ The text value from the data dictionary or the default value.
70
+ """
71
+ return self.data.get(self.text_key, self.default_value)
72
+
73
+ def set_text(self, text: str | None) -> str:
74
+ r"""Sets the text value in the data dictionary.
75
+
76
+ The object's `text` value is set to `text parameter as given, with the following modifications:
77
+
78
+ - `text` value of `None` is converted to an empty string.
79
+ - `text` value is converted to `str` type.
80
+
81
+ Args:
82
+ text (str): The text to be set in the data dictionary.
83
+
84
+ Returns:
85
+ str: The text value that was set in the data dictionary.
86
+ """
87
+ new_text = "" if text is None else str(text)
88
+ self.data[self.text_key] = new_text
89
+ return new_text
90
+
91
+ @classmethod
92
+ def from_document(cls, document: Document) -> Data:
93
+ """Converts a Document to a Data.
94
+
95
+ Args:
96
+ document (Document): The Document to convert.
97
+
98
+ Returns:
99
+ Data: The converted Data.
100
+ """
101
+ data = document.metadata
102
+ data["text"] = document.page_content
103
+ return cls(data=data, text_key="text")
104
+
105
+ @classmethod
106
+ def from_lc_message(cls, message: BaseMessage) -> Data:
107
+ """Converts a BaseMessage to a Data.
108
+
109
+ Args:
110
+ message (BaseMessage): The BaseMessage to convert.
111
+
112
+ Returns:
113
+ Data: The converted Data.
114
+ """
115
+ data: dict = {"text": message.content}
116
+ data["metadata"] = cast("dict", message.to_json())
117
+ return cls(data=data, text_key="text")
118
+
119
+ def __add__(self, other: Data) -> Data:
120
+ """Combines the data of two data by attempting to add values for overlapping keys.
121
+
122
+ Combines the data of two data by attempting to add values for overlapping keys
123
+ for all types that support the addition operation. Falls back to the value from 'other'
124
+ record when addition is not supported.
125
+ """
126
+ combined_data = self.data.copy()
127
+ for key, value in other.data.items():
128
+ # If the key exists in both data and both values support the addition operation
129
+ if key in combined_data:
130
+ try:
131
+ combined_data[key] += value
132
+ except TypeError:
133
+ # Fallback: Use the value from 'other' record if addition is not supported
134
+ combined_data[key] = value
135
+ else:
136
+ # If the key is not in the first record, simply add it
137
+ combined_data[key] = value
138
+
139
+ return Data(data=combined_data)
140
+
141
+ def to_lc_document(self) -> Document:
142
+ """Converts the Data to a Document.
143
+
144
+ Returns:
145
+ Document: The converted Document.
146
+ """
147
+ data_copy = self.data.copy()
148
+ text = data_copy.pop(self.text_key, self.default_value)
149
+ if isinstance(text, str):
150
+ return Document(page_content=text, metadata=data_copy)
151
+ return Document(page_content=str(text), metadata=data_copy)
152
+
153
+ def to_lc_message(
154
+ self,
155
+ ) -> BaseMessage:
156
+ """Converts the Data to a BaseMessage.
157
+
158
+ Returns:
159
+ BaseMessage: The converted BaseMessage.
160
+ """
161
+ # The idea of this function is to be a helper to convert a Data to a BaseMessage
162
+ # It will use the "sender" key to determine if the message is Human or AI
163
+ # If the key is not present, it will default to AI
164
+ # But first we check if all required keys are present in the data dictionary
165
+ # they are: "text", "sender"
166
+ if not all(key in self.data for key in ["text", "sender"]):
167
+ msg = f"Missing required keys ('text', 'sender') in Data: {self.data}"
168
+ raise ValueError(msg)
169
+ sender = self.data.get("sender", MESSAGE_SENDER_AI)
170
+ text = self.data.get("text", "")
171
+ files = self.data.get("files", [])
172
+ if sender == MESSAGE_SENDER_USER:
173
+ if files:
174
+ from lfx.schema.image import get_file_paths
175
+
176
+ resolved_file_paths = get_file_paths(files)
177
+ contents = [create_image_content_dict(file_path) for file_path in resolved_file_paths]
178
+ # add to the beginning of the list
179
+ contents.insert(0, {"type": "text", "text": text})
180
+ human_message = HumanMessage(content=contents)
181
+ else:
182
+ human_message = HumanMessage(
183
+ content=[{"type": "text", "text": text}],
184
+ )
185
+
186
+ return human_message
187
+
188
+ return AIMessage(content=text)
189
+
190
+ def __getattr__(self, key):
191
+ """Allows attribute-like access to the data dictionary."""
192
+ try:
193
+ if key.startswith("__"):
194
+ return self.__getattribute__(key)
195
+ if key in {"data", "text_key"} or key.startswith("_"):
196
+ return super().__getattr__(key)
197
+ return self.data[key]
198
+ except KeyError as e:
199
+ # Fallback to default behavior to raise AttributeError for undefined attributes
200
+ msg = f"'{type(self).__name__}' object has no attribute '{key}'"
201
+ raise AttributeError(msg) from e
202
+
203
+ def __setattr__(self, key, value) -> None:
204
+ """Set attribute-like values in the data dictionary.
205
+
206
+ Allows attribute-like setting of values in the data dictionary.
207
+ while still allowing direct assignment to class attributes.
208
+ """
209
+ if key in {"data", "text_key"} or key.startswith("_"):
210
+ super().__setattr__(key, value)
211
+ elif key in self.model_fields:
212
+ self.data[key] = value
213
+ super().__setattr__(key, value)
214
+ else:
215
+ self.data[key] = value
216
+
217
+ def __delattr__(self, key) -> None:
218
+ """Allows attribute-like deletion from the data dictionary."""
219
+ if key in {"data", "text_key"} or key.startswith("_"):
220
+ super().__delattr__(key)
221
+ else:
222
+ del self.data[key]
223
+
224
+ def __deepcopy__(self, memo):
225
+ """Custom deepcopy implementation to handle copying of the Data object."""
226
+ # Create a new Data object with a deep copy of the data dictionary
227
+ return Data(data=copy.deepcopy(self.data, memo), text_key=self.text_key, default_value=self.default_value)
228
+
229
+ # check which attributes the Data has by checking the keys in the data dictionary
230
+ def __dir__(self):
231
+ return super().__dir__() + list(self.data.keys())
232
+
233
+ def __str__(self) -> str:
234
+ # return a JSON string representation of the Data atributes
235
+ try:
236
+ data = {k: v.to_json() if hasattr(v, "to_json") else v for k, v in self.data.items()}
237
+ return serialize_data(data) # use the custom serializer
238
+ except Exception: # noqa: BLE001
239
+ logger.debug("Error converting Data to JSON", exc_info=True)
240
+ return str(self.data)
241
+
242
+ def __contains__(self, key) -> bool:
243
+ return key in self.data
244
+
245
+ def __eq__(self, /, other):
246
+ return isinstance(other, Data) and self.data == other.data
247
+
248
+ def filter_data(self, filter_str: str) -> Data:
249
+ """Filters the data dictionary based on the filter string.
250
+
251
+ Args:
252
+ filter_str (str): The filter string to apply to the data dictionary.
253
+
254
+ Returns:
255
+ Data: The filtered Data.
256
+ """
257
+ from lfx.template.utils import apply_json_filter
258
+
259
+ return apply_json_filter(self.data, filter_str)
260
+
261
+ def to_message(self) -> Message:
262
+ from lfx.schema.message import Message # Local import to avoid circular import
263
+
264
+ if self.text_key in self.data:
265
+ return Message(text=self.get_text())
266
+ return Message(text=str(self.data))
267
+
268
+ def to_dataframe(self) -> DataFrame:
269
+ from lfx.schema.dataframe import DataFrame # Local import to avoid circular import
270
+
271
+ data_dict = self.data
272
+ # If data contains only one key and the value is a list of dictionaries, convert to DataFrame
273
+ if (
274
+ len(data_dict) == 1
275
+ and isinstance(next(iter(data_dict.values())), list)
276
+ and all(isinstance(item, dict) for item in next(iter(data_dict.values())))
277
+ ):
278
+ return DataFrame(data=next(iter(data_dict.values())))
279
+ return DataFrame(data=[self])
280
+
281
+ def __repr__(self) -> str:
282
+ """Return string representation of the Data object."""
283
+ return f"Data(text_key={self.text_key!r}, data={self.data!r}, default_value={self.default_value!r})"
284
+
285
+ def __hash__(self) -> int:
286
+ """Return hash of the Data object based on its string representation."""
287
+ return hash(self.__repr__())
288
+
289
+
290
+ def custom_serializer(obj):
291
+ if isinstance(obj, datetime):
292
+ utc_date = obj.replace(tzinfo=timezone.utc)
293
+ return utc_date.strftime("%Y-%m-%d %H:%M:%S %Z")
294
+ if isinstance(obj, Decimal):
295
+ return float(obj)
296
+ if isinstance(obj, UUID):
297
+ return str(obj)
298
+ if isinstance(obj, BaseModel):
299
+ return obj.model_dump()
300
+ if isinstance(obj, bytes):
301
+ return obj.decode("utf-8", errors="replace")
302
+ # Add more custom serialization rules as needed
303
+ msg = f"Type {type(obj)} not serializable"
304
+ raise TypeError(msg)
305
+
306
+
307
+ def serialize_data(data):
308
+ return json.dumps(data, indent=4, default=custom_serializer)
@@ -0,0 +1,210 @@
1
+ from typing import TYPE_CHECKING, cast
2
+
3
+ import pandas as pd
4
+ from langchain_core.documents import Document
5
+ from pandas import DataFrame as pandas_DataFrame
6
+
7
+ from lfx.schema.data import Data
8
+
9
+ if TYPE_CHECKING:
10
+ from lfx.schema.message import Message
11
+
12
+
13
+ class DataFrame(pandas_DataFrame):
14
+ """A pandas DataFrame subclass specialized for handling collections of Data objects.
15
+
16
+ This class extends pandas.DataFrame to provide seamless integration between
17
+ Langflow's Data objects and pandas' powerful data manipulation capabilities.
18
+
19
+ Args:
20
+ data: Input data in various formats:
21
+ - List[Data]: List of Data objects
22
+ - List[Dict]: List of dictionaries
23
+ - Dict: Dictionary of arrays/lists
24
+ - pandas.DataFrame: Existing DataFrame
25
+ - Any format supported by pandas.DataFrame
26
+ **kwargs: Additional arguments passed to pandas.DataFrame constructor
27
+
28
+ Examples:
29
+ >>> # From Data objects
30
+ >>> dataset = DataFrame([Data(data={"name": "John"}), Data(data={"name": "Jane"})])
31
+
32
+ >>> # From dictionaries
33
+ >>> dataset = DataFrame([{"name": "John"}, {"name": "Jane"}])
34
+
35
+ >>> # From dictionary of lists
36
+ >>> dataset = DataFrame({"name": ["John", "Jane"], "age": [30, 25]})
37
+ """
38
+
39
+ def __init__(
40
+ self,
41
+ data: list[dict] | list[Data] | pd.DataFrame | None = None,
42
+ text_key: str = "text",
43
+ default_value: str = "",
44
+ **kwargs,
45
+ ):
46
+ # Initialize pandas DataFrame first without data
47
+ super().__init__(**kwargs) # Removed data parameter
48
+
49
+ # Store attributes as private members to avoid conflicts with pandas
50
+ self._text_key = text_key
51
+ self._default_value = default_value
52
+
53
+ if data is None:
54
+ return
55
+
56
+ if isinstance(data, list):
57
+ if all(isinstance(x, Data) for x in data):
58
+ data = [d.data for d in data if hasattr(d, "data")]
59
+ elif not all(isinstance(x, dict) for x in data):
60
+ msg = "List items must be either all Data objects or all dictionaries"
61
+ raise ValueError(msg)
62
+ self._update(data, **kwargs)
63
+ elif isinstance(data, dict | pd.DataFrame): # Fixed type check syntax
64
+ self._update(data, **kwargs)
65
+
66
+ def _update(self, data, **kwargs):
67
+ """Helper method to update DataFrame with new data."""
68
+ new_df = pd.DataFrame(data, **kwargs)
69
+ self._update_inplace(new_df)
70
+
71
+ # Update property accessors
72
+ @property
73
+ def text_key(self) -> str:
74
+ return self._text_key
75
+
76
+ @text_key.setter
77
+ def text_key(self, value: str) -> None:
78
+ if value not in self.columns:
79
+ msg = f"Text key '{value}' not found in DataFrame columns"
80
+ raise ValueError(msg)
81
+ self._text_key = value
82
+
83
+ @property
84
+ def default_value(self) -> str:
85
+ return self._default_value
86
+
87
+ @default_value.setter
88
+ def default_value(self, value: str) -> None:
89
+ self._default_value = value
90
+
91
+ def to_data_list(self) -> list[Data]:
92
+ """Converts the DataFrame back to a list of Data objects."""
93
+ list_of_dicts = self.to_dict(orient="records")
94
+ # suggested change: [Data(**row) for row in list_of_dicts]
95
+ return [Data(data=row) for row in list_of_dicts]
96
+
97
+ def add_row(self, data: dict | Data) -> "DataFrame":
98
+ """Adds a single row to the dataset.
99
+
100
+ Args:
101
+ data: Either a Data object or a dictionary to add as a new row
102
+
103
+ Returns:
104
+ DataFrame: A new DataFrame with the added row
105
+
106
+ Example:
107
+ >>> dataset = DataFrame([{"name": "John"}])
108
+ >>> dataset = dataset.add_row({"name": "Jane"})
109
+ """
110
+ if isinstance(data, Data):
111
+ data = data.data
112
+ new_df = self._constructor([data])
113
+ return cast("DataFrame", pd.concat([self, new_df], ignore_index=True))
114
+
115
+ def add_rows(self, data: list[dict | Data]) -> "DataFrame":
116
+ """Adds multiple rows to the dataset.
117
+
118
+ Args:
119
+ data: List of Data objects or dictionaries to add as new rows
120
+
121
+ Returns:
122
+ DataFrame: A new DataFrame with the added rows
123
+ """
124
+ processed_data = []
125
+ for item in data:
126
+ if isinstance(item, Data):
127
+ processed_data.append(item.data)
128
+ else:
129
+ processed_data.append(item)
130
+ new_df = self._constructor(processed_data)
131
+ return cast("DataFrame", pd.concat([self, new_df], ignore_index=True))
132
+
133
+ @property
134
+ def _constructor(self):
135
+ def _c(*args, **kwargs):
136
+ return DataFrame(*args, **kwargs).__finalize__(self)
137
+
138
+ return _c
139
+
140
+ def __bool__(self):
141
+ """Truth value testing for the DataFrame.
142
+
143
+ Returns True if the DataFrame has at least one row, False otherwise.
144
+ """
145
+ return not self.empty
146
+
147
+ __hash__ = None # DataFrames are mutable and shouldn't be hashable
148
+
149
+ def to_lc_documents(self) -> list[Document]:
150
+ """Converts the DataFrame to a list of Documents.
151
+
152
+ Returns:
153
+ list[Document]: The converted list of Documents.
154
+ """
155
+ list_of_dicts = self.to_dict(orient="records")
156
+ documents = []
157
+ for row in list_of_dicts:
158
+ data_copy = row.copy()
159
+ text = data_copy.pop(self._text_key, self._default_value)
160
+ if isinstance(text, str):
161
+ documents.append(Document(page_content=text, metadata=data_copy))
162
+ else:
163
+ documents.append(Document(page_content=str(text), metadata=data_copy))
164
+ return documents
165
+
166
+ def _docs_to_dataframe(self, docs):
167
+ """Converts a list of Documents to a DataFrame.
168
+
169
+ Args:
170
+ docs: List of Document objects
171
+
172
+ Returns:
173
+ DataFrame: A new DataFrame with the converted Documents
174
+ """
175
+ return DataFrame(docs)
176
+
177
+ def __eq__(self, other):
178
+ """Override equality to handle comparison with empty DataFrames and non-DataFrame objects."""
179
+ if self.empty:
180
+ return False
181
+ if isinstance(other, list) and not other: # Empty list case
182
+ return False
183
+ if not isinstance(other, DataFrame | pd.DataFrame): # Non-DataFrame case
184
+ return False
185
+ return super().__eq__(other)
186
+
187
+ def to_data(self) -> Data:
188
+ """Convert this DataFrame to a Data object.
189
+
190
+ Returns:
191
+ Data: A Data object containing the DataFrame records under 'results' key.
192
+ """
193
+ dict_list = self.to_dict(orient="records")
194
+ return Data(data={"results": dict_list})
195
+
196
+ def to_message(self) -> "Message":
197
+ from lfx.schema.message import Message
198
+
199
+ # Process DataFrame similar to the _safe_convert method
200
+ # Remove empty rows
201
+ processed_df = self.dropna(how="all")
202
+ # Remove empty lines in each cell
203
+ processed_df = processed_df.replace(r"^\s*$", "", regex=True)
204
+ # Replace multiple newlines with a single newline
205
+ processed_df = processed_df.replace(r"\n+", "\n", regex=True)
206
+ # Replace pipe characters to avoid markdown table issues
207
+ processed_df = processed_df.replace(r"\|", r"\\|", regex=True)
208
+ processed_df = processed_df.map(lambda x: str(x).replace("\n", "<br/>") if isinstance(x, str) else x)
209
+ # Convert to markdown and wrap in a Message
210
+ return Message(text=processed_df.to_markdown(index=False))