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,166 @@
|
|
1
|
+
"""Cache service implementations for lfx."""
|
2
|
+
|
3
|
+
import pickle
|
4
|
+
import threading
|
5
|
+
import time
|
6
|
+
from collections import OrderedDict
|
7
|
+
from typing import Generic, Union
|
8
|
+
|
9
|
+
from lfx.services.cache.base import CacheService, LockType
|
10
|
+
from lfx.services.cache.utils import CACHE_MISS
|
11
|
+
|
12
|
+
|
13
|
+
class ThreadingInMemoryCache(CacheService, Generic[LockType]):
|
14
|
+
"""A simple in-memory cache using an OrderedDict.
|
15
|
+
|
16
|
+
This cache supports setting a maximum size and expiration time for cached items.
|
17
|
+
When the cache is full, it uses a Least Recently Used (LRU) eviction policy.
|
18
|
+
Thread-safe using a threading Lock.
|
19
|
+
|
20
|
+
Attributes:
|
21
|
+
max_size (int, optional): Maximum number of items to store in the cache.
|
22
|
+
expiration_time (int, optional): Time in seconds after which a cached item expires. Default is 1 hour.
|
23
|
+
|
24
|
+
Example:
|
25
|
+
cache = ThreadingInMemoryCache(max_size=3, expiration_time=5)
|
26
|
+
|
27
|
+
# setting cache values
|
28
|
+
cache.set("a", 1)
|
29
|
+
cache.set("b", 2)
|
30
|
+
cache["c"] = 3
|
31
|
+
|
32
|
+
# getting cache values
|
33
|
+
a = cache.get("a")
|
34
|
+
b = cache["b"]
|
35
|
+
"""
|
36
|
+
|
37
|
+
def __init__(self, max_size=None, expiration_time=60 * 60) -> None:
|
38
|
+
"""Initialize a new ThreadingInMemoryCache instance.
|
39
|
+
|
40
|
+
Args:
|
41
|
+
max_size (int, optional): Maximum number of items to store in the cache.
|
42
|
+
expiration_time (int, optional): Time in seconds after which a cached item expires. Default is 1 hour.
|
43
|
+
"""
|
44
|
+
self._cache: OrderedDict = OrderedDict()
|
45
|
+
self._lock = threading.RLock()
|
46
|
+
self.max_size = max_size
|
47
|
+
self.expiration_time = expiration_time
|
48
|
+
|
49
|
+
def get(self, key, lock: Union[threading.Lock, None] = None): # noqa: UP007
|
50
|
+
"""Retrieve an item from the cache.
|
51
|
+
|
52
|
+
Args:
|
53
|
+
key: The key of the item to retrieve.
|
54
|
+
lock: A lock to use for the operation.
|
55
|
+
|
56
|
+
Returns:
|
57
|
+
The value associated with the key, or CACHE_MISS if the key is not found or the item has expired.
|
58
|
+
"""
|
59
|
+
with lock or self._lock:
|
60
|
+
return self._get_without_lock(key)
|
61
|
+
|
62
|
+
def _get_without_lock(self, key):
|
63
|
+
"""Retrieve an item from the cache without acquiring the lock."""
|
64
|
+
if item := self._cache.get(key):
|
65
|
+
if self.expiration_time is None or time.time() - item["time"] < self.expiration_time:
|
66
|
+
# Move the key to the end to make it recently used
|
67
|
+
self._cache.move_to_end(key)
|
68
|
+
# Check if the value is pickled
|
69
|
+
return pickle.loads(item["value"]) if isinstance(item["value"], bytes) else item["value"] # noqa: S301
|
70
|
+
self.delete(key)
|
71
|
+
return CACHE_MISS
|
72
|
+
|
73
|
+
def set(self, key, value, lock: Union[threading.Lock, None] = None) -> None: # noqa: UP007
|
74
|
+
"""Add an item to the cache.
|
75
|
+
|
76
|
+
If the cache is full, the least recently used item is evicted.
|
77
|
+
|
78
|
+
Args:
|
79
|
+
key: The key of the item.
|
80
|
+
value: The value to cache.
|
81
|
+
lock: A lock to use for the operation.
|
82
|
+
"""
|
83
|
+
with lock or self._lock:
|
84
|
+
if key in self._cache:
|
85
|
+
# Remove existing key before re-inserting to update order
|
86
|
+
self.delete(key)
|
87
|
+
elif self.max_size and len(self._cache) >= self.max_size:
|
88
|
+
# Remove least recently used item
|
89
|
+
self._cache.popitem(last=False)
|
90
|
+
# pickle locally to mimic Redis
|
91
|
+
|
92
|
+
self._cache[key] = {"value": value, "time": time.time()}
|
93
|
+
|
94
|
+
def upsert(self, key, value, lock: Union[threading.Lock, None] = None) -> None: # noqa: UP007
|
95
|
+
"""Inserts or updates a value in the cache.
|
96
|
+
|
97
|
+
If the existing value and the new value are both dictionaries, they are merged.
|
98
|
+
|
99
|
+
Args:
|
100
|
+
key: The key of the item.
|
101
|
+
value: The value to insert or update.
|
102
|
+
lock: A lock to use for the operation.
|
103
|
+
"""
|
104
|
+
with lock or self._lock:
|
105
|
+
existing_value = self._get_without_lock(key)
|
106
|
+
if existing_value is not CACHE_MISS and isinstance(existing_value, dict) and isinstance(value, dict):
|
107
|
+
existing_value.update(value)
|
108
|
+
value = existing_value
|
109
|
+
|
110
|
+
self.set(key, value)
|
111
|
+
|
112
|
+
def get_or_set(self, key, value, lock: Union[threading.Lock, None] = None): # noqa: UP007
|
113
|
+
"""Retrieve an item from the cache.
|
114
|
+
|
115
|
+
If the item does not exist, set it with the provided value.
|
116
|
+
|
117
|
+
Args:
|
118
|
+
key: The key of the item.
|
119
|
+
value: The value to cache if the item doesn't exist.
|
120
|
+
lock: A lock to use for the operation.
|
121
|
+
|
122
|
+
Returns:
|
123
|
+
The cached value associated with the key.
|
124
|
+
"""
|
125
|
+
with lock or self._lock:
|
126
|
+
if key in self._cache:
|
127
|
+
return self.get(key)
|
128
|
+
self.set(key, value)
|
129
|
+
return value
|
130
|
+
|
131
|
+
def delete(self, key, lock: Union[threading.Lock, None] = None) -> None: # noqa: UP007
|
132
|
+
with lock or self._lock:
|
133
|
+
self._cache.pop(key, None)
|
134
|
+
|
135
|
+
def clear(self, lock: Union[threading.Lock, None] = None) -> None: # noqa: UP007
|
136
|
+
"""Clear all items from the cache."""
|
137
|
+
with lock or self._lock:
|
138
|
+
self._cache.clear()
|
139
|
+
|
140
|
+
def contains(self, key) -> bool:
|
141
|
+
"""Check if the key is in the cache."""
|
142
|
+
return key in self._cache
|
143
|
+
|
144
|
+
def __contains__(self, key) -> bool:
|
145
|
+
"""Check if the key is in the cache."""
|
146
|
+
return self.contains(key)
|
147
|
+
|
148
|
+
def __getitem__(self, key):
|
149
|
+
"""Retrieve an item from the cache using the square bracket notation."""
|
150
|
+
return self.get(key)
|
151
|
+
|
152
|
+
def __setitem__(self, key, value) -> None:
|
153
|
+
"""Add an item to the cache using the square bracket notation."""
|
154
|
+
self.set(key, value)
|
155
|
+
|
156
|
+
def __delitem__(self, key) -> None:
|
157
|
+
"""Remove an item from the cache using the square bracket notation."""
|
158
|
+
self.delete(key)
|
159
|
+
|
160
|
+
def __len__(self) -> int:
|
161
|
+
"""Return the number of items in the cache."""
|
162
|
+
return len(self._cache)
|
163
|
+
|
164
|
+
def __repr__(self) -> str:
|
165
|
+
"""Return a string representation of the ThreadingInMemoryCache instance."""
|
166
|
+
return f"ThreadingInMemoryCache(max_size={self.max_size}, expiration_time={self.expiration_time})"
|
@@ -0,0 +1,169 @@
|
|
1
|
+
import base64
|
2
|
+
import contextlib
|
3
|
+
import hashlib
|
4
|
+
import tempfile
|
5
|
+
from pathlib import Path
|
6
|
+
from typing import TYPE_CHECKING, Any
|
7
|
+
|
8
|
+
from fastapi import UploadFile
|
9
|
+
from platformdirs import user_cache_dir
|
10
|
+
|
11
|
+
if TYPE_CHECKING:
|
12
|
+
from lfx.schema.schema import BuildStatus
|
13
|
+
|
14
|
+
CACHE: dict[str, Any] = {}
|
15
|
+
|
16
|
+
CACHE_DIR = user_cache_dir("langflow", "langflow")
|
17
|
+
|
18
|
+
PREFIX = "langflow_cache"
|
19
|
+
|
20
|
+
|
21
|
+
class CacheMiss:
|
22
|
+
def __repr__(self) -> str:
|
23
|
+
return "<CACHE_MISS>"
|
24
|
+
|
25
|
+
def __bool__(self) -> bool:
|
26
|
+
return False
|
27
|
+
|
28
|
+
|
29
|
+
def create_cache_folder(func):
|
30
|
+
def wrapper(*args, **kwargs):
|
31
|
+
# Get the destination folder
|
32
|
+
cache_path = Path(CACHE_DIR) / PREFIX
|
33
|
+
|
34
|
+
# Create the destination folder if it doesn't exist
|
35
|
+
cache_path.mkdir(parents=True, exist_ok=True)
|
36
|
+
|
37
|
+
return func(*args, **kwargs)
|
38
|
+
|
39
|
+
return wrapper
|
40
|
+
|
41
|
+
|
42
|
+
@create_cache_folder
|
43
|
+
def clear_old_cache_files(max_cache_size: int = 3) -> None:
|
44
|
+
cache_dir = Path(tempfile.gettempdir()) / PREFIX
|
45
|
+
cache_files = list(cache_dir.glob("*.dill"))
|
46
|
+
|
47
|
+
if len(cache_files) > max_cache_size:
|
48
|
+
cache_files_sorted_by_mtime = sorted(cache_files, key=lambda x: x.stat().st_mtime, reverse=True)
|
49
|
+
|
50
|
+
for cache_file in cache_files_sorted_by_mtime[max_cache_size:]:
|
51
|
+
with contextlib.suppress(OSError):
|
52
|
+
cache_file.unlink()
|
53
|
+
|
54
|
+
|
55
|
+
def filter_json(json_data):
|
56
|
+
filtered_data = json_data.copy()
|
57
|
+
|
58
|
+
# Remove 'viewport' and 'chatHistory' keys
|
59
|
+
if "viewport" in filtered_data:
|
60
|
+
del filtered_data["viewport"]
|
61
|
+
if "chatHistory" in filtered_data:
|
62
|
+
del filtered_data["chatHistory"]
|
63
|
+
|
64
|
+
# Filter nodes
|
65
|
+
if "nodes" in filtered_data:
|
66
|
+
for node in filtered_data["nodes"]:
|
67
|
+
if "position" in node:
|
68
|
+
del node["position"]
|
69
|
+
if "positionAbsolute" in node:
|
70
|
+
del node["positionAbsolute"]
|
71
|
+
if "selected" in node:
|
72
|
+
del node["selected"]
|
73
|
+
if "dragging" in node:
|
74
|
+
del node["dragging"]
|
75
|
+
|
76
|
+
return filtered_data
|
77
|
+
|
78
|
+
|
79
|
+
@create_cache_folder
|
80
|
+
def save_binary_file(content: str, file_name: str, accepted_types: list[str]) -> str:
|
81
|
+
"""Save a binary file to the specified folder.
|
82
|
+
|
83
|
+
Args:
|
84
|
+
content: The content of the file as a bytes object.
|
85
|
+
file_name: The name of the file, including its extension.
|
86
|
+
accepted_types: A list of accepted file types.
|
87
|
+
|
88
|
+
Returns:
|
89
|
+
The path to the saved file.
|
90
|
+
"""
|
91
|
+
if not any(file_name.endswith(suffix) for suffix in accepted_types):
|
92
|
+
msg = f"File {file_name} is not accepted"
|
93
|
+
raise ValueError(msg)
|
94
|
+
|
95
|
+
# Get the destination folder
|
96
|
+
cache_path = Path(CACHE_DIR) / PREFIX
|
97
|
+
if not content:
|
98
|
+
msg = "Please, reload the file in the loader."
|
99
|
+
raise ValueError(msg)
|
100
|
+
data = content.split(",")[1]
|
101
|
+
decoded_bytes = base64.b64decode(data)
|
102
|
+
|
103
|
+
# Create the full file path
|
104
|
+
file_path = cache_path / file_name
|
105
|
+
|
106
|
+
# Save the binary content to the file
|
107
|
+
file_path.write_bytes(decoded_bytes)
|
108
|
+
|
109
|
+
return str(file_path)
|
110
|
+
|
111
|
+
|
112
|
+
@create_cache_folder
|
113
|
+
def save_uploaded_file(file: UploadFile, folder_name):
|
114
|
+
"""Save an uploaded file to the specified folder with a hash of its content as the file name.
|
115
|
+
|
116
|
+
Args:
|
117
|
+
file: The uploaded file object.
|
118
|
+
folder_name: The name of the folder to save the file in.
|
119
|
+
|
120
|
+
Returns:
|
121
|
+
The path to the saved file.
|
122
|
+
"""
|
123
|
+
cache_path = Path(CACHE_DIR)
|
124
|
+
folder_path = cache_path / folder_name
|
125
|
+
filename = file.filename
|
126
|
+
file_extension = Path(filename).suffix if isinstance(filename, str | Path) else ""
|
127
|
+
file_object = file.file
|
128
|
+
|
129
|
+
# Create the folder if it doesn't exist
|
130
|
+
if not folder_path.exists():
|
131
|
+
folder_path.mkdir()
|
132
|
+
|
133
|
+
# Create a hash of the file content
|
134
|
+
sha256_hash = hashlib.sha256()
|
135
|
+
# Reset the file cursor to the beginning of the file
|
136
|
+
file_object.seek(0)
|
137
|
+
# Iterate over the uploaded file in small chunks to conserve memory
|
138
|
+
while chunk := file_object.read(8192): # Read 8KB at a time (adjust as needed)
|
139
|
+
sha256_hash.update(chunk)
|
140
|
+
|
141
|
+
# Use the hex digest of the hash as the file name
|
142
|
+
hex_dig = sha256_hash.hexdigest()
|
143
|
+
file_name = f"{hex_dig}{file_extension}"
|
144
|
+
|
145
|
+
# Reset the file cursor to the beginning of the file
|
146
|
+
file_object.seek(0)
|
147
|
+
|
148
|
+
# Save the file with the hash as its name
|
149
|
+
file_path = folder_path / file_name
|
150
|
+
|
151
|
+
with file_path.open("wb") as new_file:
|
152
|
+
while chunk := file_object.read(8192):
|
153
|
+
new_file.write(chunk)
|
154
|
+
|
155
|
+
return file_path
|
156
|
+
|
157
|
+
|
158
|
+
def update_build_status(cache_service, flow_id: str, status: "BuildStatus") -> None:
|
159
|
+
cached_flow = cache_service[flow_id]
|
160
|
+
if cached_flow is None:
|
161
|
+
msg = f"Flow {flow_id} not found in cache"
|
162
|
+
raise ValueError(msg)
|
163
|
+
cached_flow["status"] = status
|
164
|
+
cache_service[flow_id] = cached_flow
|
165
|
+
cached_flow["status"] = status
|
166
|
+
cache_service[flow_id] = cached_flow
|
167
|
+
|
168
|
+
|
169
|
+
CACHE_MISS = CacheMiss()
|
@@ -0,0 +1 @@
|
|
1
|
+
# Chat service schemas
|
@@ -0,0 +1,10 @@
|
|
1
|
+
import asyncio
|
2
|
+
from typing import Any, Protocol
|
3
|
+
|
4
|
+
|
5
|
+
class GetCache(Protocol):
|
6
|
+
async def __call__(self, key: str, lock: asyncio.Lock | None = None) -> Any: ...
|
7
|
+
|
8
|
+
|
9
|
+
class SetCache(Protocol):
|
10
|
+
async def __call__(self, key: str, data: Any, lock: asyncio.Lock | None = None) -> bool: ...
|
lfx/services/deps.py
ADDED
@@ -0,0 +1,129 @@
|
|
1
|
+
"""Service dependency functions for lfx package."""
|
2
|
+
|
3
|
+
from __future__ import annotations
|
4
|
+
|
5
|
+
import inspect
|
6
|
+
from contextlib import asynccontextmanager
|
7
|
+
from typing import TYPE_CHECKING
|
8
|
+
|
9
|
+
from lfx.log.logger import logger
|
10
|
+
from lfx.services.schema import ServiceType
|
11
|
+
|
12
|
+
if TYPE_CHECKING:
|
13
|
+
from lfx.services.interfaces import (
|
14
|
+
CacheServiceProtocol,
|
15
|
+
ChatServiceProtocol,
|
16
|
+
DatabaseServiceProtocol,
|
17
|
+
SettingsServiceProtocol,
|
18
|
+
StorageServiceProtocol,
|
19
|
+
TracingServiceProtocol,
|
20
|
+
VariableServiceProtocol,
|
21
|
+
)
|
22
|
+
|
23
|
+
|
24
|
+
def get_service(service_type: ServiceType, default=None):
|
25
|
+
"""Retrieves the service instance for the given service type.
|
26
|
+
|
27
|
+
Args:
|
28
|
+
service_type: The type of service to retrieve.
|
29
|
+
default: The default ServiceFactory to use if the service is not found.
|
30
|
+
|
31
|
+
Returns:
|
32
|
+
The service instance or None if not available.
|
33
|
+
"""
|
34
|
+
from lfx.services.manager import get_service_manager
|
35
|
+
|
36
|
+
service_manager = get_service_manager()
|
37
|
+
|
38
|
+
if not service_manager.are_factories_registered():
|
39
|
+
# ! This is a workaround to ensure that the service manager is initialized
|
40
|
+
# ! Not optimal, but it works for now
|
41
|
+
|
42
|
+
service_manager.register_factories(service_manager.get_factories())
|
43
|
+
|
44
|
+
if ServiceType.SETTINGS_SERVICE not in service_manager.factories:
|
45
|
+
from lfx.services.settings.factory import SettingsServiceFactory
|
46
|
+
|
47
|
+
service_manager.register_factory(service_factory=SettingsServiceFactory())
|
48
|
+
|
49
|
+
try:
|
50
|
+
return service_manager.get(service_type, default)
|
51
|
+
except Exception: # noqa: BLE001
|
52
|
+
return None
|
53
|
+
|
54
|
+
|
55
|
+
def get_db_service() -> DatabaseServiceProtocol | None:
|
56
|
+
"""Retrieves the database service instance."""
|
57
|
+
from lfx.services.schema import ServiceType
|
58
|
+
|
59
|
+
return get_service(ServiceType.DATABASE_SERVICE)
|
60
|
+
|
61
|
+
|
62
|
+
def get_storage_service() -> StorageServiceProtocol | None:
|
63
|
+
"""Retrieves the storage service instance."""
|
64
|
+
from lfx.services.schema import ServiceType
|
65
|
+
|
66
|
+
return get_service(ServiceType.STORAGE_SERVICE)
|
67
|
+
|
68
|
+
|
69
|
+
def get_settings_service() -> SettingsServiceProtocol | None:
|
70
|
+
"""Retrieves the settings service instance."""
|
71
|
+
from lfx.services.schema import ServiceType
|
72
|
+
|
73
|
+
return get_service(ServiceType.SETTINGS_SERVICE)
|
74
|
+
|
75
|
+
|
76
|
+
def get_variable_service() -> VariableServiceProtocol | None:
|
77
|
+
"""Retrieves the variable service instance."""
|
78
|
+
from lfx.services.schema import ServiceType
|
79
|
+
|
80
|
+
return get_service(ServiceType.VARIABLE_SERVICE)
|
81
|
+
|
82
|
+
|
83
|
+
def get_shared_component_cache_service() -> CacheServiceProtocol | None:
|
84
|
+
"""Retrieves the shared component cache service instance."""
|
85
|
+
from lfx.services.shared_component_cache.factory import SharedComponentCacheServiceFactory
|
86
|
+
|
87
|
+
return get_service(ServiceType.SHARED_COMPONENT_CACHE_SERVICE, SharedComponentCacheServiceFactory())
|
88
|
+
|
89
|
+
|
90
|
+
def get_chat_service() -> ChatServiceProtocol | None:
|
91
|
+
"""Retrieves the chat service instance."""
|
92
|
+
from lfx.services.schema import ServiceType
|
93
|
+
|
94
|
+
return get_service(ServiceType.CHAT_SERVICE)
|
95
|
+
|
96
|
+
|
97
|
+
def get_tracing_service() -> TracingServiceProtocol | None:
|
98
|
+
"""Retrieves the tracing service instance."""
|
99
|
+
from lfx.services.schema import ServiceType
|
100
|
+
|
101
|
+
return get_service(ServiceType.TRACING_SERVICE)
|
102
|
+
|
103
|
+
|
104
|
+
@asynccontextmanager
|
105
|
+
async def session_scope():
|
106
|
+
"""Session scope context manager.
|
107
|
+
|
108
|
+
Returns a real session if database service is available, otherwise a NoopSession.
|
109
|
+
This ensures code can always call session methods without None checking.
|
110
|
+
"""
|
111
|
+
db_service = get_db_service()
|
112
|
+
if db_service is None or inspect.isabstract(type(db_service)):
|
113
|
+
from lfx.services.session import NoopSession
|
114
|
+
|
115
|
+
yield NoopSession()
|
116
|
+
return
|
117
|
+
|
118
|
+
async with db_service.with_session() as session:
|
119
|
+
yield session
|
120
|
+
|
121
|
+
|
122
|
+
def get_session():
|
123
|
+
"""Get database session.
|
124
|
+
|
125
|
+
Returns a session from the database service if available, otherwise NoopSession.
|
126
|
+
"""
|
127
|
+
msg = "get_session is deprecated, use session_scope instead"
|
128
|
+
logger.warning(msg)
|
129
|
+
raise NotImplementedError(msg)
|
lfx/services/factory.py
ADDED
@@ -0,0 +1,19 @@
|
|
1
|
+
"""Base service factory classes for lfx package."""
|
2
|
+
|
3
|
+
from abc import ABC, abstractmethod
|
4
|
+
from typing import TYPE_CHECKING
|
5
|
+
|
6
|
+
if TYPE_CHECKING:
|
7
|
+
from lfx.services.base import Service
|
8
|
+
|
9
|
+
|
10
|
+
class ServiceFactory(ABC):
|
11
|
+
"""Base service factory class."""
|
12
|
+
|
13
|
+
def __init__(self):
|
14
|
+
self.service_class = None
|
15
|
+
self.dependencies = []
|
16
|
+
|
17
|
+
@abstractmethod
|
18
|
+
def create(self, **kwargs) -> "Service":
|
19
|
+
"""Create a service instance."""
|
@@ -0,0 +1,19 @@
|
|
1
|
+
"""Initialize services for lfx package."""
|
2
|
+
|
3
|
+
from lfx.services.settings.factory import SettingsServiceFactory
|
4
|
+
|
5
|
+
|
6
|
+
def initialize_services():
|
7
|
+
"""Initialize required services for lfx."""
|
8
|
+
from lfx.services.manager import get_service_manager
|
9
|
+
|
10
|
+
# Register the settings service factory
|
11
|
+
service_manager = get_service_manager()
|
12
|
+
service_manager.register_factory(SettingsServiceFactory())
|
13
|
+
|
14
|
+
# Note: We don't create the service immediately,
|
15
|
+
# it will be created on first use via get_settings_service()
|
16
|
+
|
17
|
+
|
18
|
+
# Initialize services when the module is imported
|
19
|
+
initialize_services()
|
@@ -0,0 +1,103 @@
|
|
1
|
+
"""Service interface protocols for lfx package."""
|
2
|
+
|
3
|
+
from __future__ import annotations
|
4
|
+
|
5
|
+
from abc import abstractmethod
|
6
|
+
from typing import TYPE_CHECKING, Any, Protocol
|
7
|
+
|
8
|
+
if TYPE_CHECKING:
|
9
|
+
import asyncio
|
10
|
+
|
11
|
+
|
12
|
+
class DatabaseServiceProtocol(Protocol):
|
13
|
+
"""Protocol for database service."""
|
14
|
+
|
15
|
+
@abstractmethod
|
16
|
+
def with_session(self) -> Any:
|
17
|
+
"""Get database session."""
|
18
|
+
...
|
19
|
+
|
20
|
+
|
21
|
+
class StorageServiceProtocol(Protocol):
|
22
|
+
"""Protocol for storage service."""
|
23
|
+
|
24
|
+
@abstractmethod
|
25
|
+
def save(self, data: Any, filename: str) -> str:
|
26
|
+
"""Save data to storage."""
|
27
|
+
...
|
28
|
+
|
29
|
+
@abstractmethod
|
30
|
+
def get_file(self, path: str) -> Any:
|
31
|
+
"""Get file from storage."""
|
32
|
+
...
|
33
|
+
|
34
|
+
@abstractmethod
|
35
|
+
def get_file_paths(self, files: list[str | dict]) -> list[str]:
|
36
|
+
"""Get file paths from storage."""
|
37
|
+
...
|
38
|
+
|
39
|
+
@abstractmethod
|
40
|
+
def build_full_path(self, flow_id: str, file_name: str) -> str:
|
41
|
+
"""Build the full path of a file in the storage."""
|
42
|
+
...
|
43
|
+
|
44
|
+
|
45
|
+
class SettingsServiceProtocol(Protocol):
|
46
|
+
"""Protocol for settings service."""
|
47
|
+
|
48
|
+
@property
|
49
|
+
@abstractmethod
|
50
|
+
def settings(self) -> Any:
|
51
|
+
"""Get settings object."""
|
52
|
+
...
|
53
|
+
|
54
|
+
|
55
|
+
class VariableServiceProtocol(Protocol):
|
56
|
+
"""Protocol for variable service."""
|
57
|
+
|
58
|
+
@abstractmethod
|
59
|
+
def get_variable(self, name: str, **kwargs) -> Any:
|
60
|
+
"""Get variable value."""
|
61
|
+
...
|
62
|
+
|
63
|
+
@abstractmethod
|
64
|
+
def set_variable(self, name: str, value: Any, **kwargs) -> None:
|
65
|
+
"""Set variable value."""
|
66
|
+
...
|
67
|
+
|
68
|
+
|
69
|
+
class CacheServiceProtocol(Protocol):
|
70
|
+
"""Protocol for cache service."""
|
71
|
+
|
72
|
+
@abstractmethod
|
73
|
+
def get(self, key: str) -> Any:
|
74
|
+
"""Get cached value."""
|
75
|
+
...
|
76
|
+
|
77
|
+
@abstractmethod
|
78
|
+
def set(self, key: str, value: Any) -> None:
|
79
|
+
"""Set cached value."""
|
80
|
+
...
|
81
|
+
|
82
|
+
|
83
|
+
class ChatServiceProtocol(Protocol):
|
84
|
+
"""Protocol for chat service."""
|
85
|
+
|
86
|
+
@abstractmethod
|
87
|
+
async def get_cache(self, key: str, lock: asyncio.Lock | None = None) -> Any:
|
88
|
+
"""Get cached value."""
|
89
|
+
...
|
90
|
+
|
91
|
+
@abstractmethod
|
92
|
+
async def set_cache(self, key: str, data: Any, lock: asyncio.Lock | None = None) -> bool:
|
93
|
+
"""Set cached value."""
|
94
|
+
...
|
95
|
+
|
96
|
+
|
97
|
+
class TracingServiceProtocol(Protocol):
|
98
|
+
"""Protocol for tracing service."""
|
99
|
+
|
100
|
+
@abstractmethod
|
101
|
+
def log(self, message: str, **kwargs) -> None:
|
102
|
+
"""Log tracing information."""
|
103
|
+
...
|