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.
- lfx/__init__.py +0 -0
- lfx/__main__.py +25 -0
- lfx/base/__init__.py +0 -0
- lfx/base/agents/__init__.py +0 -0
- lfx/base/agents/agent.py +268 -0
- lfx/base/agents/callback.py +130 -0
- lfx/base/agents/context.py +109 -0
- lfx/base/agents/crewai/__init__.py +0 -0
- lfx/base/agents/crewai/crew.py +231 -0
- lfx/base/agents/crewai/tasks.py +12 -0
- lfx/base/agents/default_prompts.py +23 -0
- lfx/base/agents/errors.py +15 -0
- lfx/base/agents/events.py +346 -0
- lfx/base/agents/utils.py +205 -0
- lfx/base/astra_assistants/__init__.py +0 -0
- lfx/base/astra_assistants/util.py +171 -0
- lfx/base/chains/__init__.py +0 -0
- lfx/base/chains/model.py +19 -0
- lfx/base/composio/__init__.py +0 -0
- lfx/base/composio/composio_base.py +1291 -0
- lfx/base/compressors/__init__.py +0 -0
- lfx/base/compressors/model.py +60 -0
- lfx/base/constants.py +46 -0
- lfx/base/curl/__init__.py +0 -0
- lfx/base/curl/parse.py +188 -0
- lfx/base/data/__init__.py +5 -0
- lfx/base/data/base_file.py +685 -0
- lfx/base/data/docling_utils.py +245 -0
- lfx/base/data/utils.py +198 -0
- lfx/base/document_transformers/__init__.py +0 -0
- lfx/base/document_transformers/model.py +43 -0
- lfx/base/embeddings/__init__.py +0 -0
- lfx/base/embeddings/aiml_embeddings.py +62 -0
- lfx/base/embeddings/model.py +26 -0
- lfx/base/flow_processing/__init__.py +0 -0
- lfx/base/flow_processing/utils.py +86 -0
- lfx/base/huggingface/__init__.py +0 -0
- lfx/base/huggingface/model_bridge.py +133 -0
- lfx/base/io/__init__.py +0 -0
- lfx/base/io/chat.py +20 -0
- lfx/base/io/text.py +22 -0
- lfx/base/langchain_utilities/__init__.py +0 -0
- lfx/base/langchain_utilities/model.py +35 -0
- lfx/base/langchain_utilities/spider_constants.py +1 -0
- lfx/base/langwatch/__init__.py +0 -0
- lfx/base/langwatch/utils.py +18 -0
- lfx/base/mcp/__init__.py +0 -0
- lfx/base/mcp/constants.py +2 -0
- lfx/base/mcp/util.py +1398 -0
- lfx/base/memory/__init__.py +0 -0
- lfx/base/memory/memory.py +49 -0
- lfx/base/memory/model.py +38 -0
- lfx/base/models/__init__.py +3 -0
- lfx/base/models/aiml_constants.py +51 -0
- lfx/base/models/anthropic_constants.py +47 -0
- lfx/base/models/aws_constants.py +151 -0
- lfx/base/models/chat_result.py +76 -0
- lfx/base/models/google_generative_ai_constants.py +70 -0
- lfx/base/models/groq_constants.py +134 -0
- lfx/base/models/model.py +375 -0
- lfx/base/models/model_input_constants.py +307 -0
- lfx/base/models/model_metadata.py +41 -0
- lfx/base/models/model_utils.py +8 -0
- lfx/base/models/novita_constants.py +35 -0
- lfx/base/models/ollama_constants.py +49 -0
- lfx/base/models/openai_constants.py +122 -0
- lfx/base/models/sambanova_constants.py +18 -0
- lfx/base/processing/__init__.py +0 -0
- lfx/base/prompts/__init__.py +0 -0
- lfx/base/prompts/api_utils.py +224 -0
- lfx/base/prompts/utils.py +61 -0
- lfx/base/textsplitters/__init__.py +0 -0
- lfx/base/textsplitters/model.py +28 -0
- lfx/base/tools/__init__.py +0 -0
- lfx/base/tools/base.py +26 -0
- lfx/base/tools/component_tool.py +325 -0
- lfx/base/tools/constants.py +49 -0
- lfx/base/tools/flow_tool.py +132 -0
- lfx/base/tools/run_flow.py +224 -0
- lfx/base/vectorstores/__init__.py +0 -0
- lfx/base/vectorstores/model.py +193 -0
- lfx/base/vectorstores/utils.py +22 -0
- lfx/base/vectorstores/vector_store_connection_decorator.py +52 -0
- lfx/cli/__init__.py +5 -0
- lfx/cli/commands.py +319 -0
- lfx/cli/common.py +650 -0
- lfx/cli/run.py +441 -0
- lfx/cli/script_loader.py +247 -0
- lfx/cli/serve_app.py +546 -0
- lfx/cli/validation.py +69 -0
- lfx/components/FAISS/__init__.py +34 -0
- lfx/components/FAISS/faiss.py +111 -0
- lfx/components/Notion/__init__.py +19 -0
- lfx/components/Notion/add_content_to_page.py +269 -0
- lfx/components/Notion/create_page.py +94 -0
- lfx/components/Notion/list_database_properties.py +68 -0
- lfx/components/Notion/list_pages.py +122 -0
- lfx/components/Notion/list_users.py +77 -0
- lfx/components/Notion/page_content_viewer.py +93 -0
- lfx/components/Notion/search.py +111 -0
- lfx/components/Notion/update_page_property.py +114 -0
- lfx/components/__init__.py +411 -0
- lfx/components/_importing.py +42 -0
- lfx/components/agentql/__init__.py +3 -0
- lfx/components/agentql/agentql_api.py +151 -0
- lfx/components/agents/__init__.py +34 -0
- lfx/components/agents/agent.py +558 -0
- lfx/components/agents/mcp_component.py +501 -0
- lfx/components/aiml/__init__.py +37 -0
- lfx/components/aiml/aiml.py +112 -0
- lfx/components/aiml/aiml_embeddings.py +37 -0
- lfx/components/amazon/__init__.py +36 -0
- lfx/components/amazon/amazon_bedrock_embedding.py +109 -0
- lfx/components/amazon/amazon_bedrock_model.py +124 -0
- lfx/components/amazon/s3_bucket_uploader.py +211 -0
- lfx/components/anthropic/__init__.py +34 -0
- lfx/components/anthropic/anthropic.py +187 -0
- lfx/components/apify/__init__.py +5 -0
- lfx/components/apify/apify_actor.py +325 -0
- lfx/components/arxiv/__init__.py +3 -0
- lfx/components/arxiv/arxiv.py +163 -0
- lfx/components/assemblyai/__init__.py +46 -0
- lfx/components/assemblyai/assemblyai_get_subtitles.py +83 -0
- lfx/components/assemblyai/assemblyai_lemur.py +183 -0
- lfx/components/assemblyai/assemblyai_list_transcripts.py +95 -0
- lfx/components/assemblyai/assemblyai_poll_transcript.py +72 -0
- lfx/components/assemblyai/assemblyai_start_transcript.py +188 -0
- lfx/components/azure/__init__.py +37 -0
- lfx/components/azure/azure_openai.py +95 -0
- lfx/components/azure/azure_openai_embeddings.py +83 -0
- lfx/components/baidu/__init__.py +32 -0
- lfx/components/baidu/baidu_qianfan_chat.py +113 -0
- lfx/components/bing/__init__.py +3 -0
- lfx/components/bing/bing_search_api.py +61 -0
- lfx/components/cassandra/__init__.py +40 -0
- lfx/components/cassandra/cassandra.py +264 -0
- lfx/components/cassandra/cassandra_chat.py +92 -0
- lfx/components/cassandra/cassandra_graph.py +238 -0
- lfx/components/chains/__init__.py +3 -0
- lfx/components/chroma/__init__.py +34 -0
- lfx/components/chroma/chroma.py +167 -0
- lfx/components/cleanlab/__init__.py +40 -0
- lfx/components/cleanlab/cleanlab_evaluator.py +155 -0
- lfx/components/cleanlab/cleanlab_rag_evaluator.py +254 -0
- lfx/components/cleanlab/cleanlab_remediator.py +131 -0
- lfx/components/clickhouse/__init__.py +34 -0
- lfx/components/clickhouse/clickhouse.py +135 -0
- lfx/components/cloudflare/__init__.py +32 -0
- lfx/components/cloudflare/cloudflare.py +81 -0
- lfx/components/cohere/__init__.py +40 -0
- lfx/components/cohere/cohere_embeddings.py +81 -0
- lfx/components/cohere/cohere_models.py +46 -0
- lfx/components/cohere/cohere_rerank.py +51 -0
- lfx/components/composio/__init__.py +74 -0
- lfx/components/composio/composio_api.py +268 -0
- lfx/components/composio/dropbox_compnent.py +11 -0
- lfx/components/composio/github_composio.py +11 -0
- lfx/components/composio/gmail_composio.py +38 -0
- lfx/components/composio/googlecalendar_composio.py +11 -0
- lfx/components/composio/googlemeet_composio.py +11 -0
- lfx/components/composio/googletasks_composio.py +8 -0
- lfx/components/composio/linear_composio.py +11 -0
- lfx/components/composio/outlook_composio.py +11 -0
- lfx/components/composio/reddit_composio.py +11 -0
- lfx/components/composio/slack_composio.py +582 -0
- lfx/components/composio/slackbot_composio.py +11 -0
- lfx/components/composio/supabase_composio.py +11 -0
- lfx/components/composio/todoist_composio.py +11 -0
- lfx/components/composio/youtube_composio.py +11 -0
- lfx/components/confluence/__init__.py +3 -0
- lfx/components/confluence/confluence.py +84 -0
- lfx/components/couchbase/__init__.py +34 -0
- lfx/components/couchbase/couchbase.py +102 -0
- lfx/components/crewai/__init__.py +49 -0
- lfx/components/crewai/crewai.py +107 -0
- lfx/components/crewai/hierarchical_crew.py +46 -0
- lfx/components/crewai/hierarchical_task.py +44 -0
- lfx/components/crewai/sequential_crew.py +52 -0
- lfx/components/crewai/sequential_task.py +73 -0
- lfx/components/crewai/sequential_task_agent.py +143 -0
- lfx/components/custom_component/__init__.py +34 -0
- lfx/components/custom_component/custom_component.py +31 -0
- lfx/components/data/__init__.py +64 -0
- lfx/components/data/api_request.py +544 -0
- lfx/components/data/csv_to_data.py +95 -0
- lfx/components/data/directory.py +113 -0
- lfx/components/data/file.py +577 -0
- lfx/components/data/json_to_data.py +98 -0
- lfx/components/data/news_search.py +164 -0
- lfx/components/data/rss.py +69 -0
- lfx/components/data/sql_executor.py +101 -0
- lfx/components/data/url.py +311 -0
- lfx/components/data/web_search.py +112 -0
- lfx/components/data/webhook.py +56 -0
- lfx/components/datastax/__init__.py +70 -0
- lfx/components/datastax/astra_assistant_manager.py +306 -0
- lfx/components/datastax/astra_db.py +75 -0
- lfx/components/datastax/astra_vectorize.py +124 -0
- lfx/components/datastax/astradb.py +1285 -0
- lfx/components/datastax/astradb_cql.py +314 -0
- lfx/components/datastax/astradb_graph.py +330 -0
- lfx/components/datastax/astradb_tool.py +414 -0
- lfx/components/datastax/astradb_vectorstore.py +1285 -0
- lfx/components/datastax/cassandra.py +92 -0
- lfx/components/datastax/create_assistant.py +58 -0
- lfx/components/datastax/create_thread.py +32 -0
- lfx/components/datastax/dotenv.py +35 -0
- lfx/components/datastax/get_assistant.py +37 -0
- lfx/components/datastax/getenvvar.py +30 -0
- lfx/components/datastax/graph_rag.py +141 -0
- lfx/components/datastax/hcd.py +314 -0
- lfx/components/datastax/list_assistants.py +25 -0
- lfx/components/datastax/run.py +89 -0
- lfx/components/deactivated/__init__.py +15 -0
- lfx/components/deactivated/amazon_kendra.py +66 -0
- lfx/components/deactivated/chat_litellm_model.py +158 -0
- lfx/components/deactivated/code_block_extractor.py +26 -0
- lfx/components/deactivated/documents_to_data.py +22 -0
- lfx/components/deactivated/embed.py +16 -0
- lfx/components/deactivated/extract_key_from_data.py +46 -0
- lfx/components/deactivated/json_document_builder.py +57 -0
- lfx/components/deactivated/list_flows.py +20 -0
- lfx/components/deactivated/mcp_sse.py +61 -0
- lfx/components/deactivated/mcp_stdio.py +62 -0
- lfx/components/deactivated/merge_data.py +93 -0
- lfx/components/deactivated/message.py +37 -0
- lfx/components/deactivated/metal.py +54 -0
- lfx/components/deactivated/multi_query.py +59 -0
- lfx/components/deactivated/retriever.py +43 -0
- lfx/components/deactivated/selective_passthrough.py +77 -0
- lfx/components/deactivated/should_run_next.py +40 -0
- lfx/components/deactivated/split_text.py +63 -0
- lfx/components/deactivated/store_message.py +24 -0
- lfx/components/deactivated/sub_flow.py +124 -0
- lfx/components/deactivated/vectara_self_query.py +76 -0
- lfx/components/deactivated/vector_store.py +24 -0
- lfx/components/deepseek/__init__.py +34 -0
- lfx/components/deepseek/deepseek.py +136 -0
- lfx/components/docling/__init__.py +43 -0
- lfx/components/docling/chunk_docling_document.py +186 -0
- lfx/components/docling/docling_inline.py +231 -0
- lfx/components/docling/docling_remote.py +193 -0
- lfx/components/docling/export_docling_document.py +117 -0
- lfx/components/documentloaders/__init__.py +3 -0
- lfx/components/duckduckgo/__init__.py +3 -0
- lfx/components/duckduckgo/duck_duck_go_search_run.py +92 -0
- lfx/components/elastic/__init__.py +37 -0
- lfx/components/elastic/elasticsearch.py +267 -0
- lfx/components/elastic/opensearch.py +243 -0
- lfx/components/embeddings/__init__.py +37 -0
- lfx/components/embeddings/similarity.py +76 -0
- lfx/components/embeddings/text_embedder.py +64 -0
- lfx/components/exa/__init__.py +3 -0
- lfx/components/exa/exa_search.py +68 -0
- lfx/components/firecrawl/__init__.py +43 -0
- lfx/components/firecrawl/firecrawl_crawl_api.py +88 -0
- lfx/components/firecrawl/firecrawl_extract_api.py +136 -0
- lfx/components/firecrawl/firecrawl_map_api.py +89 -0
- lfx/components/firecrawl/firecrawl_scrape_api.py +73 -0
- lfx/components/git/__init__.py +4 -0
- lfx/components/git/git.py +262 -0
- lfx/components/git/gitextractor.py +196 -0
- lfx/components/glean/__init__.py +3 -0
- lfx/components/glean/glean_search_api.py +173 -0
- lfx/components/google/__init__.py +17 -0
- lfx/components/google/gmail.py +192 -0
- lfx/components/google/google_bq_sql_executor.py +157 -0
- lfx/components/google/google_drive.py +92 -0
- lfx/components/google/google_drive_search.py +152 -0
- lfx/components/google/google_generative_ai.py +147 -0
- lfx/components/google/google_generative_ai_embeddings.py +141 -0
- lfx/components/google/google_oauth_token.py +89 -0
- lfx/components/google/google_search_api_core.py +68 -0
- lfx/components/google/google_serper_api_core.py +74 -0
- lfx/components/groq/__init__.py +34 -0
- lfx/components/groq/groq.py +136 -0
- lfx/components/helpers/__init__.py +52 -0
- lfx/components/helpers/calculator_core.py +89 -0
- lfx/components/helpers/create_list.py +40 -0
- lfx/components/helpers/current_date.py +42 -0
- lfx/components/helpers/id_generator.py +42 -0
- lfx/components/helpers/memory.py +251 -0
- lfx/components/helpers/output_parser.py +45 -0
- lfx/components/helpers/store_message.py +90 -0
- lfx/components/homeassistant/__init__.py +7 -0
- lfx/components/homeassistant/home_assistant_control.py +152 -0
- lfx/components/homeassistant/list_home_assistant_states.py +137 -0
- lfx/components/huggingface/__init__.py +37 -0
- lfx/components/huggingface/huggingface.py +197 -0
- lfx/components/huggingface/huggingface_inference_api.py +106 -0
- lfx/components/ibm/__init__.py +34 -0
- lfx/components/ibm/watsonx.py +203 -0
- lfx/components/ibm/watsonx_embeddings.py +135 -0
- lfx/components/icosacomputing/__init__.py +5 -0
- lfx/components/icosacomputing/combinatorial_reasoner.py +84 -0
- lfx/components/input_output/__init__.py +38 -0
- lfx/components/input_output/chat.py +120 -0
- lfx/components/input_output/chat_output.py +200 -0
- lfx/components/input_output/text.py +27 -0
- lfx/components/input_output/text_output.py +29 -0
- lfx/components/jigsawstack/__init__.py +23 -0
- lfx/components/jigsawstack/ai_scrape.py +126 -0
- lfx/components/jigsawstack/ai_web_search.py +136 -0
- lfx/components/jigsawstack/file_read.py +115 -0
- lfx/components/jigsawstack/file_upload.py +94 -0
- lfx/components/jigsawstack/image_generation.py +205 -0
- lfx/components/jigsawstack/nsfw.py +60 -0
- lfx/components/jigsawstack/object_detection.py +124 -0
- lfx/components/jigsawstack/sentiment.py +112 -0
- lfx/components/jigsawstack/text_to_sql.py +90 -0
- lfx/components/jigsawstack/text_translate.py +77 -0
- lfx/components/jigsawstack/vocr.py +107 -0
- lfx/components/langchain_utilities/__init__.py +109 -0
- lfx/components/langchain_utilities/character.py +53 -0
- lfx/components/langchain_utilities/conversation.py +59 -0
- lfx/components/langchain_utilities/csv_agent.py +107 -0
- lfx/components/langchain_utilities/fake_embeddings.py +26 -0
- lfx/components/langchain_utilities/html_link_extractor.py +35 -0
- lfx/components/langchain_utilities/json_agent.py +45 -0
- lfx/components/langchain_utilities/langchain_hub.py +126 -0
- lfx/components/langchain_utilities/language_recursive.py +49 -0
- lfx/components/langchain_utilities/language_semantic.py +138 -0
- lfx/components/langchain_utilities/llm_checker.py +39 -0
- lfx/components/langchain_utilities/llm_math.py +42 -0
- lfx/components/langchain_utilities/natural_language.py +61 -0
- lfx/components/langchain_utilities/openai_tools.py +53 -0
- lfx/components/langchain_utilities/openapi.py +48 -0
- lfx/components/langchain_utilities/recursive_character.py +60 -0
- lfx/components/langchain_utilities/retrieval_qa.py +83 -0
- lfx/components/langchain_utilities/runnable_executor.py +137 -0
- lfx/components/langchain_utilities/self_query.py +80 -0
- lfx/components/langchain_utilities/spider.py +142 -0
- lfx/components/langchain_utilities/sql.py +40 -0
- lfx/components/langchain_utilities/sql_database.py +35 -0
- lfx/components/langchain_utilities/sql_generator.py +78 -0
- lfx/components/langchain_utilities/tool_calling.py +59 -0
- lfx/components/langchain_utilities/vector_store_info.py +49 -0
- lfx/components/langchain_utilities/vector_store_router.py +33 -0
- lfx/components/langchain_utilities/xml_agent.py +71 -0
- lfx/components/langwatch/__init__.py +3 -0
- lfx/components/langwatch/langwatch.py +278 -0
- lfx/components/link_extractors/__init__.py +3 -0
- lfx/components/lmstudio/__init__.py +34 -0
- lfx/components/lmstudio/lmstudioembeddings.py +89 -0
- lfx/components/lmstudio/lmstudiomodel.py +129 -0
- lfx/components/logic/__init__.py +52 -0
- lfx/components/logic/conditional_router.py +171 -0
- lfx/components/logic/data_conditional_router.py +125 -0
- lfx/components/logic/flow_tool.py +110 -0
- lfx/components/logic/listen.py +29 -0
- lfx/components/logic/loop.py +125 -0
- lfx/components/logic/notify.py +88 -0
- lfx/components/logic/pass_message.py +35 -0
- lfx/components/logic/run_flow.py +71 -0
- lfx/components/logic/sub_flow.py +114 -0
- lfx/components/maritalk/__init__.py +32 -0
- lfx/components/maritalk/maritalk.py +52 -0
- lfx/components/mem0/__init__.py +3 -0
- lfx/components/mem0/mem0_chat_memory.py +136 -0
- lfx/components/milvus/__init__.py +34 -0
- lfx/components/milvus/milvus.py +115 -0
- lfx/components/mistral/__init__.py +37 -0
- lfx/components/mistral/mistral.py +114 -0
- lfx/components/mistral/mistral_embeddings.py +58 -0
- lfx/components/models/__init__.py +34 -0
- lfx/components/models/embedding_model.py +114 -0
- lfx/components/models/language_model.py +144 -0
- lfx/components/mongodb/__init__.py +34 -0
- lfx/components/mongodb/mongodb_atlas.py +213 -0
- lfx/components/needle/__init__.py +3 -0
- lfx/components/needle/needle.py +104 -0
- lfx/components/notdiamond/__init__.py +34 -0
- lfx/components/notdiamond/notdiamond.py +228 -0
- lfx/components/novita/__init__.py +32 -0
- lfx/components/novita/novita.py +130 -0
- lfx/components/nvidia/__init__.py +57 -0
- lfx/components/nvidia/nvidia.py +157 -0
- lfx/components/nvidia/nvidia_embedding.py +77 -0
- lfx/components/nvidia/nvidia_ingest.py +317 -0
- lfx/components/nvidia/nvidia_rerank.py +63 -0
- lfx/components/nvidia/system_assist.py +65 -0
- lfx/components/olivya/__init__.py +3 -0
- lfx/components/olivya/olivya.py +116 -0
- lfx/components/ollama/__init__.py +37 -0
- lfx/components/ollama/ollama.py +330 -0
- lfx/components/ollama/ollama_embeddings.py +106 -0
- lfx/components/openai/__init__.py +37 -0
- lfx/components/openai/openai.py +100 -0
- lfx/components/openai/openai_chat_model.py +176 -0
- lfx/components/openrouter/__init__.py +32 -0
- lfx/components/openrouter/openrouter.py +202 -0
- lfx/components/output_parsers/__init__.py +3 -0
- lfx/components/perplexity/__init__.py +34 -0
- lfx/components/perplexity/perplexity.py +75 -0
- lfx/components/pgvector/__init__.py +34 -0
- lfx/components/pgvector/pgvector.py +72 -0
- lfx/components/pinecone/__init__.py +34 -0
- lfx/components/pinecone/pinecone.py +134 -0
- lfx/components/processing/__init__.py +117 -0
- lfx/components/processing/alter_metadata.py +108 -0
- lfx/components/processing/batch_run.py +205 -0
- lfx/components/processing/combine_text.py +39 -0
- lfx/components/processing/converter.py +159 -0
- lfx/components/processing/create_data.py +110 -0
- lfx/components/processing/data_operations.py +438 -0
- lfx/components/processing/data_to_dataframe.py +70 -0
- lfx/components/processing/dataframe_operations.py +313 -0
- lfx/components/processing/extract_key.py +53 -0
- lfx/components/processing/filter_data.py +42 -0
- lfx/components/processing/filter_data_values.py +88 -0
- lfx/components/processing/json_cleaner.py +103 -0
- lfx/components/processing/lambda_filter.py +154 -0
- lfx/components/processing/llm_router.py +499 -0
- lfx/components/processing/merge_data.py +90 -0
- lfx/components/processing/message_to_data.py +36 -0
- lfx/components/processing/parse_data.py +70 -0
- lfx/components/processing/parse_dataframe.py +68 -0
- lfx/components/processing/parse_json_data.py +90 -0
- lfx/components/processing/parser.py +143 -0
- lfx/components/processing/prompt.py +67 -0
- lfx/components/processing/python_repl_core.py +98 -0
- lfx/components/processing/regex.py +82 -0
- lfx/components/processing/save_file.py +225 -0
- lfx/components/processing/select_data.py +48 -0
- lfx/components/processing/split_text.py +141 -0
- lfx/components/processing/structured_output.py +202 -0
- lfx/components/processing/update_data.py +160 -0
- lfx/components/prototypes/__init__.py +34 -0
- lfx/components/prototypes/python_function.py +73 -0
- lfx/components/qdrant/__init__.py +34 -0
- lfx/components/qdrant/qdrant.py +109 -0
- lfx/components/redis/__init__.py +37 -0
- lfx/components/redis/redis.py +89 -0
- lfx/components/redis/redis_chat.py +43 -0
- lfx/components/sambanova/__init__.py +32 -0
- lfx/components/sambanova/sambanova.py +84 -0
- lfx/components/scrapegraph/__init__.py +40 -0
- lfx/components/scrapegraph/scrapegraph_markdownify_api.py +64 -0
- lfx/components/scrapegraph/scrapegraph_search_api.py +64 -0
- lfx/components/scrapegraph/scrapegraph_smart_scraper_api.py +71 -0
- lfx/components/searchapi/__init__.py +34 -0
- lfx/components/searchapi/search.py +79 -0
- lfx/components/serpapi/__init__.py +3 -0
- lfx/components/serpapi/serp.py +115 -0
- lfx/components/supabase/__init__.py +34 -0
- lfx/components/supabase/supabase.py +76 -0
- lfx/components/tavily/__init__.py +4 -0
- lfx/components/tavily/tavily_extract.py +117 -0
- lfx/components/tavily/tavily_search.py +212 -0
- lfx/components/textsplitters/__init__.py +3 -0
- lfx/components/toolkits/__init__.py +3 -0
- lfx/components/tools/__init__.py +72 -0
- lfx/components/tools/calculator.py +108 -0
- lfx/components/tools/google_search_api.py +45 -0
- lfx/components/tools/google_serper_api.py +115 -0
- lfx/components/tools/python_code_structured_tool.py +327 -0
- lfx/components/tools/python_repl.py +97 -0
- lfx/components/tools/search_api.py +87 -0
- lfx/components/tools/searxng.py +145 -0
- lfx/components/tools/serp_api.py +119 -0
- lfx/components/tools/tavily_search_tool.py +344 -0
- lfx/components/tools/wikidata_api.py +102 -0
- lfx/components/tools/wikipedia_api.py +49 -0
- lfx/components/tools/yahoo_finance.py +129 -0
- lfx/components/twelvelabs/__init__.py +52 -0
- lfx/components/twelvelabs/convert_astra_results.py +84 -0
- lfx/components/twelvelabs/pegasus_index.py +311 -0
- lfx/components/twelvelabs/split_video.py +291 -0
- lfx/components/twelvelabs/text_embeddings.py +57 -0
- lfx/components/twelvelabs/twelvelabs_pegasus.py +408 -0
- lfx/components/twelvelabs/video_embeddings.py +100 -0
- lfx/components/twelvelabs/video_file.py +179 -0
- lfx/components/unstructured/__init__.py +3 -0
- lfx/components/unstructured/unstructured.py +121 -0
- lfx/components/upstash/__init__.py +34 -0
- lfx/components/upstash/upstash.py +124 -0
- lfx/components/vectara/__init__.py +37 -0
- lfx/components/vectara/vectara.py +97 -0
- lfx/components/vectara/vectara_rag.py +164 -0
- lfx/components/vectorstores/__init__.py +40 -0
- lfx/components/vectorstores/astradb.py +1285 -0
- lfx/components/vectorstores/astradb_graph.py +319 -0
- lfx/components/vectorstores/cassandra.py +264 -0
- lfx/components/vectorstores/cassandra_graph.py +238 -0
- lfx/components/vectorstores/chroma.py +167 -0
- lfx/components/vectorstores/clickhouse.py +135 -0
- lfx/components/vectorstores/couchbase.py +102 -0
- lfx/components/vectorstores/elasticsearch.py +267 -0
- lfx/components/vectorstores/faiss.py +111 -0
- lfx/components/vectorstores/graph_rag.py +141 -0
- lfx/components/vectorstores/hcd.py +314 -0
- lfx/components/vectorstores/local_db.py +261 -0
- lfx/components/vectorstores/milvus.py +115 -0
- lfx/components/vectorstores/mongodb_atlas.py +213 -0
- lfx/components/vectorstores/opensearch.py +243 -0
- lfx/components/vectorstores/pgvector.py +72 -0
- lfx/components/vectorstores/pinecone.py +134 -0
- lfx/components/vectorstores/qdrant.py +109 -0
- lfx/components/vectorstores/supabase.py +76 -0
- lfx/components/vectorstores/upstash.py +124 -0
- lfx/components/vectorstores/vectara.py +97 -0
- lfx/components/vectorstores/vectara_rag.py +164 -0
- lfx/components/vectorstores/weaviate.py +89 -0
- lfx/components/vertexai/__init__.py +37 -0
- lfx/components/vertexai/vertexai.py +71 -0
- lfx/components/vertexai/vertexai_embeddings.py +67 -0
- lfx/components/weaviate/__init__.py +34 -0
- lfx/components/weaviate/weaviate.py +89 -0
- lfx/components/wikipedia/__init__.py +4 -0
- lfx/components/wikipedia/wikidata.py +86 -0
- lfx/components/wikipedia/wikipedia.py +53 -0
- lfx/components/wolframalpha/__init__.py +3 -0
- lfx/components/wolframalpha/wolfram_alpha_api.py +54 -0
- lfx/components/xai/__init__.py +32 -0
- lfx/components/xai/xai.py +167 -0
- lfx/components/yahoosearch/__init__.py +3 -0
- lfx/components/yahoosearch/yahoo.py +137 -0
- lfx/components/youtube/__init__.py +52 -0
- lfx/components/youtube/channel.py +227 -0
- lfx/components/youtube/comments.py +231 -0
- lfx/components/youtube/playlist.py +33 -0
- lfx/components/youtube/search.py +120 -0
- lfx/components/youtube/trending.py +285 -0
- lfx/components/youtube/video_details.py +263 -0
- lfx/components/youtube/youtube_transcripts.py +118 -0
- lfx/components/zep/__init__.py +3 -0
- lfx/components/zep/zep.py +44 -0
- lfx/constants.py +6 -0
- lfx/custom/__init__.py +7 -0
- lfx/custom/attributes.py +86 -0
- lfx/custom/code_parser/__init__.py +3 -0
- lfx/custom/code_parser/code_parser.py +361 -0
- lfx/custom/custom_component/__init__.py +0 -0
- lfx/custom/custom_component/base_component.py +128 -0
- lfx/custom/custom_component/component.py +1808 -0
- lfx/custom/custom_component/component_with_cache.py +8 -0
- lfx/custom/custom_component/custom_component.py +588 -0
- lfx/custom/dependency_analyzer.py +165 -0
- lfx/custom/directory_reader/__init__.py +3 -0
- lfx/custom/directory_reader/directory_reader.py +359 -0
- lfx/custom/directory_reader/utils.py +171 -0
- lfx/custom/eval.py +12 -0
- lfx/custom/schema.py +32 -0
- lfx/custom/tree_visitor.py +21 -0
- lfx/custom/utils.py +877 -0
- lfx/custom/validate.py +488 -0
- lfx/events/__init__.py +1 -0
- lfx/events/event_manager.py +110 -0
- lfx/exceptions/__init__.py +0 -0
- lfx/exceptions/component.py +15 -0
- lfx/field_typing/__init__.py +91 -0
- lfx/field_typing/constants.py +215 -0
- lfx/field_typing/range_spec.py +35 -0
- lfx/graph/__init__.py +6 -0
- lfx/graph/edge/__init__.py +0 -0
- lfx/graph/edge/base.py +277 -0
- lfx/graph/edge/schema.py +119 -0
- lfx/graph/edge/utils.py +0 -0
- lfx/graph/graph/__init__.py +0 -0
- lfx/graph/graph/ascii.py +202 -0
- lfx/graph/graph/base.py +2238 -0
- lfx/graph/graph/constants.py +63 -0
- lfx/graph/graph/runnable_vertices_manager.py +133 -0
- lfx/graph/graph/schema.py +52 -0
- lfx/graph/graph/state_model.py +66 -0
- lfx/graph/graph/utils.py +1024 -0
- lfx/graph/schema.py +75 -0
- lfx/graph/state/__init__.py +0 -0
- lfx/graph/state/model.py +237 -0
- lfx/graph/utils.py +200 -0
- lfx/graph/vertex/__init__.py +0 -0
- lfx/graph/vertex/base.py +823 -0
- lfx/graph/vertex/constants.py +0 -0
- lfx/graph/vertex/exceptions.py +4 -0
- lfx/graph/vertex/param_handler.py +264 -0
- lfx/graph/vertex/schema.py +26 -0
- lfx/graph/vertex/utils.py +19 -0
- lfx/graph/vertex/vertex_types.py +489 -0
- lfx/helpers/__init__.py +1 -0
- lfx/helpers/base_model.py +71 -0
- lfx/helpers/custom.py +13 -0
- lfx/helpers/data.py +167 -0
- lfx/helpers/flow.py +194 -0
- lfx/inputs/__init__.py +68 -0
- lfx/inputs/constants.py +2 -0
- lfx/inputs/input_mixin.py +328 -0
- lfx/inputs/inputs.py +714 -0
- lfx/inputs/validators.py +19 -0
- lfx/interface/__init__.py +6 -0
- lfx/interface/components.py +489 -0
- lfx/interface/importing/__init__.py +5 -0
- lfx/interface/importing/utils.py +39 -0
- lfx/interface/initialize/__init__.py +3 -0
- lfx/interface/initialize/loading.py +224 -0
- lfx/interface/listing.py +26 -0
- lfx/interface/run.py +16 -0
- lfx/interface/utils.py +111 -0
- lfx/io/__init__.py +63 -0
- lfx/io/schema.py +289 -0
- lfx/load/__init__.py +8 -0
- lfx/load/load.py +256 -0
- lfx/load/utils.py +99 -0
- lfx/log/__init__.py +5 -0
- lfx/log/logger.py +385 -0
- lfx/memory/__init__.py +90 -0
- lfx/memory/stubs.py +283 -0
- lfx/processing/__init__.py +1 -0
- lfx/processing/process.py +238 -0
- lfx/processing/utils.py +25 -0
- lfx/py.typed +0 -0
- lfx/schema/__init__.py +66 -0
- lfx/schema/artifact.py +83 -0
- lfx/schema/content_block.py +62 -0
- lfx/schema/content_types.py +91 -0
- lfx/schema/data.py +308 -0
- lfx/schema/dataframe.py +210 -0
- lfx/schema/dotdict.py +74 -0
- lfx/schema/encoders.py +13 -0
- lfx/schema/graph.py +47 -0
- lfx/schema/image.py +131 -0
- lfx/schema/json_schema.py +141 -0
- lfx/schema/log.py +61 -0
- lfx/schema/message.py +473 -0
- lfx/schema/openai_responses_schemas.py +74 -0
- lfx/schema/properties.py +41 -0
- lfx/schema/schema.py +171 -0
- lfx/schema/serialize.py +13 -0
- lfx/schema/table.py +140 -0
- lfx/schema/validators.py +114 -0
- lfx/serialization/__init__.py +5 -0
- lfx/serialization/constants.py +2 -0
- lfx/serialization/serialization.py +314 -0
- lfx/services/__init__.py +23 -0
- lfx/services/base.py +28 -0
- lfx/services/cache/__init__.py +6 -0
- lfx/services/cache/base.py +183 -0
- lfx/services/cache/service.py +166 -0
- lfx/services/cache/utils.py +169 -0
- lfx/services/chat/__init__.py +1 -0
- lfx/services/chat/config.py +2 -0
- lfx/services/chat/schema.py +10 -0
- lfx/services/deps.py +129 -0
- lfx/services/factory.py +19 -0
- lfx/services/initialize.py +19 -0
- lfx/services/interfaces.py +103 -0
- lfx/services/manager.py +172 -0
- lfx/services/schema.py +20 -0
- lfx/services/session.py +82 -0
- lfx/services/settings/__init__.py +3 -0
- lfx/services/settings/auth.py +130 -0
- lfx/services/settings/base.py +539 -0
- lfx/services/settings/constants.py +31 -0
- lfx/services/settings/factory.py +23 -0
- lfx/services/settings/feature_flags.py +12 -0
- lfx/services/settings/service.py +35 -0
- lfx/services/settings/utils.py +40 -0
- lfx/services/shared_component_cache/__init__.py +1 -0
- lfx/services/shared_component_cache/factory.py +30 -0
- lfx/services/shared_component_cache/service.py +9 -0
- lfx/services/storage/__init__.py +5 -0
- lfx/services/storage/local.py +155 -0
- lfx/services/storage/service.py +54 -0
- lfx/services/tracing/__init__.py +1 -0
- lfx/services/tracing/service.py +21 -0
- lfx/settings.py +6 -0
- lfx/template/__init__.py +6 -0
- lfx/template/field/__init__.py +0 -0
- lfx/template/field/base.py +257 -0
- lfx/template/field/prompt.py +15 -0
- lfx/template/frontend_node/__init__.py +6 -0
- lfx/template/frontend_node/base.py +212 -0
- lfx/template/frontend_node/constants.py +65 -0
- lfx/template/frontend_node/custom_components.py +79 -0
- lfx/template/template/__init__.py +0 -0
- lfx/template/template/base.py +100 -0
- lfx/template/utils.py +217 -0
- lfx/type_extraction/__init__.py +19 -0
- lfx/type_extraction/type_extraction.py +75 -0
- lfx/type_extraction.py +80 -0
- lfx/utils/__init__.py +1 -0
- lfx/utils/async_helpers.py +42 -0
- lfx/utils/component_utils.py +154 -0
- lfx/utils/concurrency.py +60 -0
- lfx/utils/connection_string_parser.py +11 -0
- lfx/utils/constants.py +205 -0
- lfx/utils/data_structure.py +212 -0
- lfx/utils/exceptions.py +22 -0
- lfx/utils/helpers.py +28 -0
- lfx/utils/image.py +73 -0
- lfx/utils/lazy_load.py +15 -0
- lfx/utils/request_utils.py +18 -0
- lfx/utils/schemas.py +139 -0
- lfx/utils/util.py +481 -0
- lfx/utils/util_strings.py +56 -0
- lfx/utils/version.py +24 -0
- lfx_nightly-0.1.11.dev0.dist-info/METADATA +293 -0
- lfx_nightly-0.1.11.dev0.dist-info/RECORD +699 -0
- lfx_nightly-0.1.11.dev0.dist-info/WHEEL +4 -0
- lfx_nightly-0.1.11.dev0.dist-info/entry_points.txt +2 -0
@@ -0,0 +1,438 @@
|
|
1
|
+
import ast
|
2
|
+
from typing import TYPE_CHECKING, Any
|
3
|
+
|
4
|
+
from lfx.custom import Component
|
5
|
+
from lfx.inputs import DictInput, DropdownInput, MessageTextInput, SortableListInput
|
6
|
+
from lfx.io import DataInput, Output
|
7
|
+
from lfx.log.logger import logger
|
8
|
+
from lfx.schema import Data
|
9
|
+
from lfx.schema.dotdict import dotdict
|
10
|
+
from lfx.utils.component_utils import set_current_fields, set_field_display
|
11
|
+
|
12
|
+
if TYPE_CHECKING:
|
13
|
+
from collections.abc import Callable
|
14
|
+
|
15
|
+
ACTION_CONFIG = {
|
16
|
+
"Select Keys": {"is_list": False, "log_msg": "setting filter fields"},
|
17
|
+
"Literal Eval": {"is_list": False, "log_msg": "setting evaluate fields"},
|
18
|
+
"Combine": {"is_list": True, "log_msg": "setting combine fields"},
|
19
|
+
"Filter Values": {"is_list": False, "log_msg": "setting filter values fields"},
|
20
|
+
"Append or Update": {"is_list": False, "log_msg": "setting Append or Update fields"},
|
21
|
+
"Remove Keys": {"is_list": False, "log_msg": "setting remove keys fields"},
|
22
|
+
"Rename Keys": {"is_list": False, "log_msg": "setting rename keys fields"},
|
23
|
+
}
|
24
|
+
OPERATORS = {
|
25
|
+
"equals": lambda a, b: str(a) == str(b),
|
26
|
+
"not equals": lambda a, b: str(a) != str(b),
|
27
|
+
"contains": lambda a, b: str(b) in str(a),
|
28
|
+
"starts with": lambda a, b: str(a).startswith(str(b)),
|
29
|
+
"ends with": lambda a, b: str(a).endswith(str(b)),
|
30
|
+
}
|
31
|
+
|
32
|
+
|
33
|
+
class DataOperationsComponent(Component):
|
34
|
+
display_name = "Data Operations"
|
35
|
+
description = "Perform various operations on a Data object."
|
36
|
+
documentation: str = "https://docs.langflow.org/components-processing#data-operations"
|
37
|
+
icon = "file-json"
|
38
|
+
name = "DataOperations"
|
39
|
+
default_keys = ["operations", "data"]
|
40
|
+
metadata = {
|
41
|
+
"keywords": [
|
42
|
+
"data",
|
43
|
+
"operations",
|
44
|
+
"filter values",
|
45
|
+
"Append or Update",
|
46
|
+
"remove keys",
|
47
|
+
"rename keys",
|
48
|
+
"select keys",
|
49
|
+
"literal eval",
|
50
|
+
"combine",
|
51
|
+
"filter",
|
52
|
+
"append",
|
53
|
+
"update",
|
54
|
+
"remove",
|
55
|
+
"rename",
|
56
|
+
"data operations",
|
57
|
+
"data manipulation",
|
58
|
+
"data transformation",
|
59
|
+
"data filtering",
|
60
|
+
"data selection",
|
61
|
+
"data combination",
|
62
|
+
],
|
63
|
+
}
|
64
|
+
actions_data = {
|
65
|
+
"Select Keys": ["select_keys_input", "operations"],
|
66
|
+
"Literal Eval": [],
|
67
|
+
"Combine": [],
|
68
|
+
"Filter Values": ["filter_values", "operations", "operator", "filter_key"],
|
69
|
+
"Append or Update": ["append_update_data", "operations"],
|
70
|
+
"Remove Keys": ["remove_keys_input", "operations"],
|
71
|
+
"Rename Keys": ["rename_keys_input", "operations"],
|
72
|
+
}
|
73
|
+
|
74
|
+
inputs = [
|
75
|
+
DataInput(name="data", display_name="Data", info="Data object to filter.", required=True, is_list=True),
|
76
|
+
SortableListInput(
|
77
|
+
name="operations",
|
78
|
+
display_name="Operations",
|
79
|
+
placeholder="Select Operation",
|
80
|
+
info="List of operations to perform on the data.",
|
81
|
+
options=[
|
82
|
+
{"name": "Select Keys", "icon": "lasso-select"},
|
83
|
+
{"name": "Literal Eval", "icon": "braces"},
|
84
|
+
{"name": "Combine", "icon": "merge"},
|
85
|
+
{"name": "Filter Values", "icon": "filter"},
|
86
|
+
{"name": "Append or Update", "icon": "circle-plus"},
|
87
|
+
{"name": "Remove Keys", "icon": "eraser"},
|
88
|
+
{"name": "Rename Keys", "icon": "pencil-line"},
|
89
|
+
],
|
90
|
+
real_time_refresh=True,
|
91
|
+
limit=1,
|
92
|
+
),
|
93
|
+
# select keys inputs
|
94
|
+
MessageTextInput(
|
95
|
+
name="select_keys_input",
|
96
|
+
display_name="Select Keys",
|
97
|
+
info="List of keys to select from the data.",
|
98
|
+
show=False,
|
99
|
+
is_list=True,
|
100
|
+
),
|
101
|
+
# filter values inputs
|
102
|
+
MessageTextInput(
|
103
|
+
name="filter_key",
|
104
|
+
display_name="Filter Key",
|
105
|
+
info="Key to filter by.",
|
106
|
+
is_list=True,
|
107
|
+
show=False,
|
108
|
+
),
|
109
|
+
DropdownInput(
|
110
|
+
name="operator",
|
111
|
+
display_name="Comparison Operator",
|
112
|
+
options=["equals", "not equals", "contains", "starts with", "ends with"],
|
113
|
+
info="The operator to apply for comparing the values.",
|
114
|
+
value="equals",
|
115
|
+
advanced=False,
|
116
|
+
show=False,
|
117
|
+
),
|
118
|
+
DictInput(
|
119
|
+
name="filter_values",
|
120
|
+
display_name="Filter Values",
|
121
|
+
info="List of values to filter by.",
|
122
|
+
show=False,
|
123
|
+
is_list=True,
|
124
|
+
),
|
125
|
+
# update/ Append data inputs
|
126
|
+
DictInput(
|
127
|
+
name="append_update_data",
|
128
|
+
display_name="Append or Update",
|
129
|
+
info="Data to Append or Updatethe existing data with.",
|
130
|
+
show=False,
|
131
|
+
value={"key": "value"},
|
132
|
+
is_list=True,
|
133
|
+
),
|
134
|
+
# remove keys inputs
|
135
|
+
MessageTextInput(
|
136
|
+
name="remove_keys_input",
|
137
|
+
display_name="Remove Keys",
|
138
|
+
info="List of keys to remove from the data.",
|
139
|
+
show=False,
|
140
|
+
is_list=True,
|
141
|
+
),
|
142
|
+
# rename keys inputs
|
143
|
+
DictInput(
|
144
|
+
name="rename_keys_input",
|
145
|
+
display_name="Rename Keys",
|
146
|
+
info="List of keys to rename in the data.",
|
147
|
+
show=False,
|
148
|
+
is_list=True,
|
149
|
+
value={"old_key": "new_key"},
|
150
|
+
),
|
151
|
+
]
|
152
|
+
outputs = [
|
153
|
+
Output(display_name="Data", name="data_output", method="as_data"),
|
154
|
+
]
|
155
|
+
|
156
|
+
# Helper methods for data operations
|
157
|
+
def get_data_dict(self) -> dict:
|
158
|
+
"""Extract data dictionary from Data object."""
|
159
|
+
# TODO: rasie error if it s list of data objects
|
160
|
+
data = self.data[0] if isinstance(self.data, list) and len(self.data) == 1 else self.data
|
161
|
+
return data.model_dump()
|
162
|
+
|
163
|
+
def get_normalized_data(self) -> dict:
|
164
|
+
"""Get normalized data dictionary, handling the 'data' key if present."""
|
165
|
+
data_dict = self.get_data_dict()
|
166
|
+
return data_dict.get("data", data_dict)
|
167
|
+
|
168
|
+
def data_is_list(self) -> bool:
|
169
|
+
"""Check if data contains multiple items."""
|
170
|
+
return isinstance(self.data, list) and len(self.data) > 1
|
171
|
+
|
172
|
+
def validate_single_data(self, operation: str) -> None:
|
173
|
+
"""Validate that the operation is being performed on a single data object."""
|
174
|
+
if self.data_is_list():
|
175
|
+
msg = f"{operation} operation is not supported for multiple data objects."
|
176
|
+
raise ValueError(msg)
|
177
|
+
|
178
|
+
def operation_exception(self, operations: list[str]) -> None:
|
179
|
+
"""Raise exception for incompatible operations."""
|
180
|
+
msg = f"{operations} operations are not supported in combination with each other."
|
181
|
+
raise ValueError(msg)
|
182
|
+
|
183
|
+
# Data transformation operations
|
184
|
+
def select_keys(self, *, evaluate: bool | None = None) -> Data:
|
185
|
+
"""Select specific keys from the data dictionary."""
|
186
|
+
self.validate_single_data("Select Keys")
|
187
|
+
data_dict = self.get_normalized_data()
|
188
|
+
filter_criteria: list[str] = self.select_keys_input
|
189
|
+
|
190
|
+
# Filter the data
|
191
|
+
if len(filter_criteria) == 1 and filter_criteria[0] == "data":
|
192
|
+
filtered = data_dict["data"]
|
193
|
+
else:
|
194
|
+
if not all(key in data_dict for key in filter_criteria):
|
195
|
+
msg = f"Select key not found in data. Available keys: {list(data_dict.keys())}"
|
196
|
+
raise ValueError(msg)
|
197
|
+
filtered = {key: value for key, value in data_dict.items() if key in filter_criteria}
|
198
|
+
|
199
|
+
# Create a new Data object with the filtered data
|
200
|
+
if evaluate:
|
201
|
+
filtered = self.recursive_eval(filtered)
|
202
|
+
|
203
|
+
# Return a new Data object with the filtered data directly in the data attribute
|
204
|
+
return Data(data=filtered)
|
205
|
+
|
206
|
+
def remove_keys(self) -> Data:
|
207
|
+
"""Remove specified keys from the data dictionary."""
|
208
|
+
self.validate_single_data("Remove Keys")
|
209
|
+
data_dict = self.get_normalized_data()
|
210
|
+
remove_keys_input: list[str] = self.remove_keys_input
|
211
|
+
|
212
|
+
for key in remove_keys_input:
|
213
|
+
if key in data_dict:
|
214
|
+
data_dict.pop(key)
|
215
|
+
else:
|
216
|
+
logger.warning(f"Key '{key}' not found in data. Skipping removal.")
|
217
|
+
|
218
|
+
return Data(**data_dict)
|
219
|
+
|
220
|
+
def rename_keys(self) -> Data:
|
221
|
+
"""Rename keys in the data dictionary."""
|
222
|
+
self.validate_single_data("Rename Keys")
|
223
|
+
data_dict = self.get_normalized_data()
|
224
|
+
rename_keys_input: dict[str, str] = self.rename_keys_input
|
225
|
+
|
226
|
+
for old_key, new_key in rename_keys_input.items():
|
227
|
+
if old_key in data_dict:
|
228
|
+
data_dict[new_key] = data_dict[old_key]
|
229
|
+
data_dict.pop(old_key)
|
230
|
+
else:
|
231
|
+
msg = f"Key '{old_key}' not found in data. Skipping rename."
|
232
|
+
raise ValueError(msg)
|
233
|
+
|
234
|
+
return Data(**data_dict)
|
235
|
+
|
236
|
+
def recursive_eval(self, data: Any) -> Any:
|
237
|
+
"""Recursively evaluate string values in a dictionary or list.
|
238
|
+
|
239
|
+
If the value is a string that can be evaluated, it will be evaluated.
|
240
|
+
Otherwise, the original value is returned.
|
241
|
+
"""
|
242
|
+
if isinstance(data, dict):
|
243
|
+
return {k: self.recursive_eval(v) for k, v in data.items()}
|
244
|
+
if isinstance(data, list):
|
245
|
+
return [self.recursive_eval(item) for item in data]
|
246
|
+
if isinstance(data, str):
|
247
|
+
try:
|
248
|
+
# Only attempt to evaluate strings that look like Python literals
|
249
|
+
if (
|
250
|
+
data.strip().startswith(("{", "[", "(", "'", '"'))
|
251
|
+
or data.strip().lower() in ("true", "false", "none")
|
252
|
+
or data.strip().replace(".", "").isdigit()
|
253
|
+
):
|
254
|
+
return ast.literal_eval(data)
|
255
|
+
# return data
|
256
|
+
except (ValueError, SyntaxError, TypeError, MemoryError):
|
257
|
+
# If evaluation fails for any reason, return the original string
|
258
|
+
return data
|
259
|
+
else:
|
260
|
+
return data
|
261
|
+
return data
|
262
|
+
|
263
|
+
def evaluate_data(self) -> Data:
|
264
|
+
"""Evaluate string values in the data dictionary."""
|
265
|
+
self.validate_single_data("Literal Eval")
|
266
|
+
logger.info("evaluating data")
|
267
|
+
return Data(**self.recursive_eval(self.get_data_dict()))
|
268
|
+
|
269
|
+
def combine_data(self, *, evaluate: bool | None = None) -> Data:
|
270
|
+
"""Combine multiple data objects into one."""
|
271
|
+
logger.info("combining data")
|
272
|
+
if not self.data_is_list():
|
273
|
+
return self.data[0] if self.data else Data(data={})
|
274
|
+
|
275
|
+
if len(self.data) == 1:
|
276
|
+
msg = "Combine operation requires multiple data inputs."
|
277
|
+
raise ValueError(msg)
|
278
|
+
|
279
|
+
data_dicts = [data.model_dump().get("data", data.model_dump()) for data in self.data]
|
280
|
+
combined_data = {}
|
281
|
+
|
282
|
+
for data_dict in data_dicts:
|
283
|
+
for key, value in data_dict.items():
|
284
|
+
if key not in combined_data:
|
285
|
+
combined_data[key] = value
|
286
|
+
elif isinstance(combined_data[key], list):
|
287
|
+
if isinstance(value, list):
|
288
|
+
combined_data[key].extend(value)
|
289
|
+
else:
|
290
|
+
combined_data[key].append(value)
|
291
|
+
else:
|
292
|
+
# If current value is not a list, convert it to list and add new value
|
293
|
+
combined_data[key] = (
|
294
|
+
[combined_data[key], value] if not isinstance(value, list) else [combined_data[key], *value]
|
295
|
+
)
|
296
|
+
|
297
|
+
if evaluate:
|
298
|
+
combined_data = self.recursive_eval(combined_data)
|
299
|
+
|
300
|
+
return Data(**combined_data)
|
301
|
+
|
302
|
+
def compare_values(self, item_value: Any, filter_value: str, operator: str) -> bool:
|
303
|
+
"""Compare values based on the specified operator."""
|
304
|
+
comparison_func = OPERATORS.get(operator)
|
305
|
+
if comparison_func:
|
306
|
+
return comparison_func(item_value, filter_value)
|
307
|
+
return False
|
308
|
+
|
309
|
+
def filter_data(self, input_data: list[dict[str, Any]], filter_key: str, filter_value: str, operator: str) -> list:
|
310
|
+
"""Filter list data based on key, value, and operator."""
|
311
|
+
# Validate inputs
|
312
|
+
if not input_data:
|
313
|
+
self.status = "Input data is empty."
|
314
|
+
return []
|
315
|
+
|
316
|
+
if not filter_key or not filter_value:
|
317
|
+
self.status = "Filter key or value is missing."
|
318
|
+
return input_data
|
319
|
+
|
320
|
+
# Filter the data
|
321
|
+
filtered_data = []
|
322
|
+
for item in input_data:
|
323
|
+
if isinstance(item, dict) and filter_key in item:
|
324
|
+
if self.compare_values(item[filter_key], filter_value, operator):
|
325
|
+
filtered_data.append(item)
|
326
|
+
else:
|
327
|
+
self.status = f"Warning: Some items don't have the key '{filter_key}' or are not dictionaries."
|
328
|
+
|
329
|
+
return filtered_data
|
330
|
+
|
331
|
+
def multi_filter_data(self) -> Data:
|
332
|
+
"""Apply multiple filters to the data."""
|
333
|
+
self.validate_single_data("Filter Values")
|
334
|
+
data_filtered = self.get_normalized_data()
|
335
|
+
|
336
|
+
for filter_key in self.filter_key:
|
337
|
+
if filter_key not in data_filtered:
|
338
|
+
msg = f"Filter key '{filter_key}' not found in data. Available keys: {list(data_filtered.keys())}"
|
339
|
+
raise ValueError(msg)
|
340
|
+
|
341
|
+
if isinstance(data_filtered[filter_key], list):
|
342
|
+
for filter_data in self.filter_values:
|
343
|
+
filter_value = self.filter_values.get(filter_data)
|
344
|
+
if filter_value is not None:
|
345
|
+
data_filtered[filter_key] = self.filter_data(
|
346
|
+
input_data=data_filtered[filter_key],
|
347
|
+
filter_key=filter_data,
|
348
|
+
filter_value=filter_value,
|
349
|
+
operator=self.operator,
|
350
|
+
)
|
351
|
+
else:
|
352
|
+
msg = f"Filter key '{filter_key}' is not a list."
|
353
|
+
raise TypeError(msg)
|
354
|
+
|
355
|
+
return Data(**data_filtered)
|
356
|
+
|
357
|
+
def append_update(self) -> Data:
|
358
|
+
"""Append or Update with new key-value pairs."""
|
359
|
+
self.validate_single_data("Append or Update")
|
360
|
+
data_filtered = self.get_normalized_data()
|
361
|
+
|
362
|
+
for key, value in self.append_update_data.items():
|
363
|
+
data_filtered[key] = value
|
364
|
+
|
365
|
+
return Data(**data_filtered)
|
366
|
+
|
367
|
+
# Configuration and execution methods
|
368
|
+
def update_build_config(self, build_config: dotdict, field_value: Any, field_name: str | None = None) -> dotdict:
|
369
|
+
"""Update build configuration based on selected action."""
|
370
|
+
if field_name != "operations":
|
371
|
+
return build_config
|
372
|
+
|
373
|
+
build_config["operations"]["value"] = field_value
|
374
|
+
selected_actions = [action["name"] for action in field_value]
|
375
|
+
|
376
|
+
# Handle single action case
|
377
|
+
if len(selected_actions) == 1 and selected_actions[0] in ACTION_CONFIG:
|
378
|
+
action = selected_actions[0]
|
379
|
+
config = ACTION_CONFIG[action]
|
380
|
+
|
381
|
+
build_config["data"]["is_list"] = config["is_list"]
|
382
|
+
logger.info(config["log_msg"])
|
383
|
+
|
384
|
+
return set_current_fields(
|
385
|
+
build_config=build_config,
|
386
|
+
action_fields=self.actions_data,
|
387
|
+
selected_action=action,
|
388
|
+
default_fields=self.default_keys,
|
389
|
+
func=set_field_display,
|
390
|
+
)
|
391
|
+
|
392
|
+
# Handle no operations case
|
393
|
+
if not selected_actions:
|
394
|
+
logger.info("setting default fields")
|
395
|
+
return set_current_fields(
|
396
|
+
build_config=build_config,
|
397
|
+
action_fields=self.actions_data,
|
398
|
+
selected_action=None,
|
399
|
+
default_fields=self.default_keys,
|
400
|
+
func=set_field_display,
|
401
|
+
)
|
402
|
+
|
403
|
+
return build_config
|
404
|
+
|
405
|
+
def as_data(self) -> Data:
|
406
|
+
"""Execute the selected action on the data."""
|
407
|
+
if not hasattr(self, "operations") or not self.operations:
|
408
|
+
return Data(data={})
|
409
|
+
|
410
|
+
selected_actions = [action["name"] for action in self.operations]
|
411
|
+
logger.info(f"selected_actions: {selected_actions}")
|
412
|
+
|
413
|
+
# Only handle single action case for now
|
414
|
+
if len(selected_actions) != 1:
|
415
|
+
return Data(data={})
|
416
|
+
|
417
|
+
action = selected_actions[0]
|
418
|
+
|
419
|
+
# Explicitly type the action_map
|
420
|
+
action_map: dict[str, Callable[[], Data]] = {
|
421
|
+
"Select Keys": self.select_keys,
|
422
|
+
"Literal Eval": self.evaluate_data,
|
423
|
+
"Combine": self.combine_data,
|
424
|
+
"Filter Values": self.multi_filter_data,
|
425
|
+
"Append or Update": self.append_update,
|
426
|
+
"Remove Keys": self.remove_keys,
|
427
|
+
"Rename Keys": self.rename_keys,
|
428
|
+
}
|
429
|
+
|
430
|
+
handler: Callable[[], Data] | None = action_map.get(action)
|
431
|
+
if handler:
|
432
|
+
try:
|
433
|
+
return handler()
|
434
|
+
except Exception as e:
|
435
|
+
logger.error(f"Error executing {action}: {e!s}")
|
436
|
+
raise
|
437
|
+
|
438
|
+
return Data(data={})
|
@@ -0,0 +1,70 @@
|
|
1
|
+
from lfx.custom.custom_component.component import Component
|
2
|
+
from lfx.io import DataInput, Output
|
3
|
+
from lfx.schema.data import Data
|
4
|
+
from lfx.schema.dataframe import DataFrame
|
5
|
+
|
6
|
+
|
7
|
+
class DataToDataFrameComponent(Component):
|
8
|
+
display_name = "Data → DataFrame"
|
9
|
+
description = (
|
10
|
+
"Converts one or multiple Data objects into a DataFrame. "
|
11
|
+
"Each Data object corresponds to one row. Fields from `.data` become columns, "
|
12
|
+
"and the `.text` (if present) is placed in a 'text' column."
|
13
|
+
)
|
14
|
+
icon = "table"
|
15
|
+
name = "DataToDataFrame"
|
16
|
+
legacy = True
|
17
|
+
|
18
|
+
inputs = [
|
19
|
+
DataInput(
|
20
|
+
name="data_list",
|
21
|
+
display_name="Data or Data List",
|
22
|
+
info="One or multiple Data objects to transform into a DataFrame.",
|
23
|
+
is_list=True,
|
24
|
+
),
|
25
|
+
]
|
26
|
+
|
27
|
+
outputs = [
|
28
|
+
Output(
|
29
|
+
display_name="DataFrame",
|
30
|
+
name="dataframe",
|
31
|
+
method="build_dataframe",
|
32
|
+
info="A DataFrame built from each Data object's fields plus a 'text' column.",
|
33
|
+
),
|
34
|
+
]
|
35
|
+
|
36
|
+
def build_dataframe(self) -> DataFrame:
|
37
|
+
"""Builds a DataFrame from Data objects by combining their fields.
|
38
|
+
|
39
|
+
For each Data object:
|
40
|
+
- Merge item.data (dictionary) as columns
|
41
|
+
- If item.text is present, add 'text' column
|
42
|
+
|
43
|
+
Returns a DataFrame with one row per Data object.
|
44
|
+
"""
|
45
|
+
data_input = self.data_list
|
46
|
+
|
47
|
+
# If user passed a single Data, it might come in as a single object rather than a list
|
48
|
+
if not isinstance(data_input, list):
|
49
|
+
data_input = [data_input]
|
50
|
+
|
51
|
+
rows = []
|
52
|
+
for item in data_input:
|
53
|
+
if not isinstance(item, Data):
|
54
|
+
msg = f"Expected Data objects, got {type(item)} instead."
|
55
|
+
raise TypeError(msg)
|
56
|
+
|
57
|
+
# Start with a copy of item.data or an empty dict
|
58
|
+
row_dict = dict(item.data) if item.data else {}
|
59
|
+
|
60
|
+
# If the Data object has text, store it under 'text' col
|
61
|
+
text_val = item.get_text()
|
62
|
+
if text_val:
|
63
|
+
row_dict["text"] = text_val
|
64
|
+
|
65
|
+
rows.append(row_dict)
|
66
|
+
|
67
|
+
# Build a DataFrame from these row dictionaries
|
68
|
+
df_result = DataFrame(rows)
|
69
|
+
self.status = df_result # store in self.status for logs
|
70
|
+
return df_result
|