lfx-nightly 0.2.0.dev25__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of lfx-nightly might be problematic. Click here for more details.
- lfx/__init__.py +0 -0
- lfx/__main__.py +25 -0
- lfx/_assets/component_index.json +1 -0
- lfx/base/__init__.py +0 -0
- lfx/base/agents/__init__.py +0 -0
- lfx/base/agents/agent.py +375 -0
- lfx/base/agents/altk_base_agent.py +380 -0
- lfx/base/agents/altk_tool_wrappers.py +565 -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 +430 -0
- lfx/base/agents/utils.py +237 -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 +2584 -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 +810 -0
- lfx/base/data/docling_utils.py +338 -0
- lfx/base/data/storage_utils.py +192 -0
- lfx/base/data/utils.py +362 -0
- lfx/base/datastax/__init__.py +5 -0
- lfx/base/datastax/astradb_base.py +896 -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/embeddings_class.py +113 -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 +21 -0
- lfx/base/io/text.py +22 -0
- lfx/base/knowledge_bases/__init__.py +3 -0
- lfx/base/knowledge_bases/knowledge_base_utils.py +137 -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 +1659 -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 +51 -0
- lfx/base/models/aws_constants.py +151 -0
- lfx/base/models/chat_result.py +76 -0
- lfx/base/models/cometapi_constants.py +54 -0
- lfx/base/models/google_generative_ai_constants.py +70 -0
- lfx/base/models/google_generative_ai_model.py +38 -0
- lfx/base/models/groq_constants.py +150 -0
- lfx/base/models/groq_model_discovery.py +265 -0
- lfx/base/models/model.py +375 -0
- lfx/base/models/model_input_constants.py +378 -0
- lfx/base/models/model_metadata.py +41 -0
- lfx/base/models/model_utils.py +108 -0
- lfx/base/models/novita_constants.py +35 -0
- lfx/base/models/ollama_constants.py +52 -0
- lfx/base/models/openai_constants.py +129 -0
- lfx/base/models/sambanova_constants.py +18 -0
- lfx/base/models/watsonx_constants.py +36 -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 +698 -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 +327 -0
- lfx/cli/common.py +650 -0
- lfx/cli/run.py +506 -0
- lfx/cli/script_loader.py +289 -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 +428 -0
- lfx/components/_importing.py +42 -0
- lfx/components/agentql/__init__.py +3 -0
- lfx/components/agentql/agentql_api.py +151 -0
- lfx/components/aiml/__init__.py +37 -0
- lfx/components/aiml/aiml.py +115 -0
- lfx/components/aiml/aiml_embeddings.py +37 -0
- lfx/components/altk/__init__.py +34 -0
- lfx/components/altk/altk_agent.py +193 -0
- lfx/components/amazon/__init__.py +36 -0
- lfx/components/amazon/amazon_bedrock_converse.py +195 -0
- lfx/components/amazon/amazon_bedrock_embedding.py +109 -0
- lfx/components/amazon/amazon_bedrock_model.py +130 -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 +169 -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 +169 -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/cometapi/__init__.py +32 -0
- lfx/components/cometapi/cometapi.py +166 -0
- lfx/components/composio/__init__.py +222 -0
- lfx/components/composio/agentql_composio.py +11 -0
- lfx/components/composio/agiled_composio.py +11 -0
- lfx/components/composio/airtable_composio.py +11 -0
- lfx/components/composio/apollo_composio.py +11 -0
- lfx/components/composio/asana_composio.py +11 -0
- lfx/components/composio/attio_composio.py +11 -0
- lfx/components/composio/bitbucket_composio.py +11 -0
- lfx/components/composio/bolna_composio.py +11 -0
- lfx/components/composio/brightdata_composio.py +11 -0
- lfx/components/composio/calendly_composio.py +11 -0
- lfx/components/composio/canva_composio.py +11 -0
- lfx/components/composio/canvas_composio.py +11 -0
- lfx/components/composio/coda_composio.py +11 -0
- lfx/components/composio/composio_api.py +278 -0
- lfx/components/composio/contentful_composio.py +11 -0
- lfx/components/composio/digicert_composio.py +11 -0
- lfx/components/composio/discord_composio.py +11 -0
- lfx/components/composio/dropbox_compnent.py +11 -0
- lfx/components/composio/elevenlabs_composio.py +11 -0
- lfx/components/composio/exa_composio.py +11 -0
- lfx/components/composio/figma_composio.py +11 -0
- lfx/components/composio/finage_composio.py +11 -0
- lfx/components/composio/firecrawl_composio.py +11 -0
- lfx/components/composio/fireflies_composio.py +11 -0
- lfx/components/composio/fixer_composio.py +11 -0
- lfx/components/composio/flexisign_composio.py +11 -0
- lfx/components/composio/freshdesk_composio.py +11 -0
- lfx/components/composio/github_composio.py +11 -0
- lfx/components/composio/gmail_composio.py +38 -0
- lfx/components/composio/googlebigquery_composio.py +11 -0
- lfx/components/composio/googlecalendar_composio.py +11 -0
- lfx/components/composio/googleclassroom_composio.py +11 -0
- lfx/components/composio/googledocs_composio.py +11 -0
- lfx/components/composio/googlemeet_composio.py +11 -0
- lfx/components/composio/googlesheets_composio.py +11 -0
- lfx/components/composio/googletasks_composio.py +8 -0
- lfx/components/composio/heygen_composio.py +11 -0
- lfx/components/composio/instagram_composio.py +11 -0
- lfx/components/composio/jira_composio.py +11 -0
- lfx/components/composio/jotform_composio.py +11 -0
- lfx/components/composio/klaviyo_composio.py +11 -0
- lfx/components/composio/linear_composio.py +11 -0
- lfx/components/composio/listennotes_composio.py +11 -0
- lfx/components/composio/mem0_composio.py +11 -0
- lfx/components/composio/miro_composio.py +11 -0
- lfx/components/composio/missive_composio.py +11 -0
- lfx/components/composio/notion_composio.py +11 -0
- lfx/components/composio/onedrive_composio.py +11 -0
- lfx/components/composio/outlook_composio.py +11 -0
- lfx/components/composio/pandadoc_composio.py +11 -0
- lfx/components/composio/peopledatalabs_composio.py +11 -0
- lfx/components/composio/perplexityai_composio.py +11 -0
- lfx/components/composio/reddit_composio.py +11 -0
- lfx/components/composio/serpapi_composio.py +11 -0
- lfx/components/composio/slack_composio.py +11 -0
- lfx/components/composio/slackbot_composio.py +11 -0
- lfx/components/composio/snowflake_composio.py +11 -0
- lfx/components/composio/supabase_composio.py +11 -0
- lfx/components/composio/tavily_composio.py +11 -0
- lfx/components/composio/timelinesai_composio.py +11 -0
- lfx/components/composio/todoist_composio.py +11 -0
- lfx/components/composio/wrike_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 +108 -0
- lfx/components/crewai/hierarchical_crew.py +47 -0
- lfx/components/crewai/hierarchical_task.py +45 -0
- lfx/components/crewai/sequential_crew.py +53 -0
- lfx/components/crewai/sequential_task.py +74 -0
- lfx/components/crewai/sequential_task_agent.py +144 -0
- lfx/components/cuga/__init__.py +34 -0
- lfx/components/cuga/cuga_agent.py +730 -0
- lfx/components/custom_component/__init__.py +34 -0
- lfx/components/custom_component/custom_component.py +31 -0
- lfx/components/data/__init__.py +114 -0
- lfx/components/data_source/__init__.py +58 -0
- lfx/components/data_source/api_request.py +577 -0
- lfx/components/data_source/csv_to_data.py +101 -0
- lfx/components/data_source/json_to_data.py +106 -0
- lfx/components/data_source/mock_data.py +398 -0
- lfx/components/data_source/news_search.py +166 -0
- lfx/components/data_source/rss.py +71 -0
- lfx/components/data_source/sql_executor.py +101 -0
- lfx/components/data_source/url.py +311 -0
- lfx/components/data_source/web_search.py +326 -0
- lfx/components/datastax/__init__.py +76 -0
- lfx/components/datastax/astradb_assistant_manager.py +307 -0
- lfx/components/datastax/astradb_chatmemory.py +40 -0
- lfx/components/datastax/astradb_cql.py +288 -0
- lfx/components/datastax/astradb_graph.py +217 -0
- lfx/components/datastax/astradb_tool.py +378 -0
- lfx/components/datastax/astradb_vectorize.py +122 -0
- lfx/components/datastax/astradb_vectorstore.py +449 -0
- lfx/components/datastax/create_assistant.py +59 -0
- lfx/components/datastax/create_thread.py +33 -0
- lfx/components/datastax/dotenv.py +36 -0
- lfx/components/datastax/get_assistant.py +38 -0
- lfx/components/datastax/getenvvar.py +31 -0
- lfx/components/datastax/graph_rag.py +141 -0
- lfx/components/datastax/hcd.py +315 -0
- lfx/components/datastax/list_assistants.py +26 -0
- lfx/components/datastax/run.py +90 -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 +238 -0
- lfx/components/docling/docling_remote.py +195 -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 +789 -0
- lfx/components/elastic/opensearch_multimodal.py +1575 -0
- lfx/components/embeddings/__init__.py +37 -0
- lfx/components/embeddings/similarity.py +77 -0
- lfx/components/embeddings/text_embedder.py +65 -0
- lfx/components/exa/__init__.py +3 -0
- lfx/components/exa/exa_search.py +68 -0
- lfx/components/files_and_knowledge/__init__.py +47 -0
- lfx/components/files_and_knowledge/directory.py +113 -0
- lfx/components/files_and_knowledge/file.py +841 -0
- lfx/components/files_and_knowledge/ingestion.py +694 -0
- lfx/components/files_and_knowledge/retrieval.py +264 -0
- lfx/components/files_and_knowledge/save_file.py +746 -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/flow_controls/__init__.py +58 -0
- lfx/components/flow_controls/conditional_router.py +208 -0
- lfx/components/flow_controls/data_conditional_router.py +126 -0
- lfx/components/flow_controls/flow_tool.py +111 -0
- lfx/components/flow_controls/listen.py +29 -0
- lfx/components/flow_controls/loop.py +163 -0
- lfx/components/flow_controls/notify.py +88 -0
- lfx/components/flow_controls/pass_message.py +36 -0
- lfx/components/flow_controls/run_flow.py +108 -0
- lfx/components/flow_controls/sub_flow.py +115 -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 +193 -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 +144 -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 +143 -0
- lfx/components/helpers/__init__.py +154 -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 +199 -0
- lfx/components/huggingface/huggingface_inference_api.py +106 -0
- lfx/components/ibm/__init__.py +34 -0
- lfx/components/ibm/watsonx.py +207 -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 +40 -0
- lfx/components/input_output/chat.py +109 -0
- lfx/components/input_output/chat_output.py +184 -0
- lfx/components/input_output/text.py +27 -0
- lfx/components/input_output/text_output.py +29 -0
- lfx/components/input_output/webhook.py +56 -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/knowledge_bases/__init__.py +89 -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 +175 -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 +100 -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/llm_operations/__init__.py +46 -0
- lfx/components/llm_operations/batch_run.py +205 -0
- lfx/components/llm_operations/lambda_filter.py +218 -0
- lfx/components/llm_operations/llm_conditional_router.py +421 -0
- lfx/components/llm_operations/llm_selector.py +499 -0
- lfx/components/llm_operations/structured_output.py +244 -0
- lfx/components/lmstudio/__init__.py +34 -0
- lfx/components/lmstudio/lmstudioembeddings.py +89 -0
- lfx/components/lmstudio/lmstudiomodel.py +133 -0
- lfx/components/logic/__init__.py +181 -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 +147 -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 +89 -0
- lfx/components/models_and_agents/__init__.py +49 -0
- lfx/components/models_and_agents/agent.py +644 -0
- lfx/components/models_and_agents/embedding_model.py +423 -0
- lfx/components/models_and_agents/language_model.py +398 -0
- lfx/components/models_and_agents/mcp_component.py +594 -0
- lfx/components/models_and_agents/memory.py +268 -0
- lfx/components/models_and_agents/prompt.py +67 -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 +151 -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 +548 -0
- lfx/components/ollama/ollama_embeddings.py +103 -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 +104 -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 +72 -0
- lfx/components/processing/alter_metadata.py +109 -0
- lfx/components/processing/combine_text.py +40 -0
- lfx/components/processing/converter.py +248 -0
- lfx/components/processing/create_data.py +111 -0
- lfx/components/processing/create_list.py +40 -0
- lfx/components/processing/data_operations.py +528 -0
- lfx/components/processing/data_to_dataframe.py +71 -0
- lfx/components/processing/dataframe_operations.py +313 -0
- lfx/components/processing/dataframe_to_toolset.py +259 -0
- lfx/components/processing/dynamic_create_data.py +357 -0
- lfx/components/processing/extract_key.py +54 -0
- lfx/components/processing/filter_data.py +43 -0
- lfx/components/processing/filter_data_values.py +89 -0
- lfx/components/processing/json_cleaner.py +104 -0
- lfx/components/processing/merge_data.py +91 -0
- lfx/components/processing/message_to_data.py +37 -0
- lfx/components/processing/output_parser.py +46 -0
- lfx/components/processing/parse_data.py +71 -0
- lfx/components/processing/parse_dataframe.py +69 -0
- lfx/components/processing/parse_json_data.py +91 -0
- lfx/components/processing/parser.py +148 -0
- lfx/components/processing/regex.py +83 -0
- lfx/components/processing/select_data.py +49 -0
- lfx/components/processing/split_text.py +141 -0
- lfx/components/processing/store_message.py +91 -0
- lfx/components/processing/update_data.py +161 -0
- lfx/components/prototypes/__init__.py +35 -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 +66 -0
- lfx/components/tools/calculator.py +109 -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 +328 -0
- lfx/components/tools/python_repl.py +98 -0
- lfx/components/tools/search_api.py +88 -0
- lfx/components/tools/searxng.py +145 -0
- lfx/components/tools/serp_api.py +120 -0
- lfx/components/tools/tavily_search_tool.py +345 -0
- lfx/components/tools/wikidata_api.py +103 -0
- lfx/components/tools/wikipedia_api.py +50 -0
- lfx/components/tools/yahoo_finance.py +130 -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 +301 -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 +191 -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/utilities/__init__.py +43 -0
- lfx/components/utilities/calculator_core.py +89 -0
- lfx/components/utilities/current_date.py +42 -0
- lfx/components/utilities/id_generator.py +42 -0
- lfx/components/utilities/python_repl_core.py +98 -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 +34 -0
- lfx/components/vectorstores/local_db.py +270 -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/vlmrun/__init__.py +34 -0
- lfx/components/vlmrun/vlmrun_transcription.py +224 -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 +206 -0
- lfx/components/zep/__init__.py +3 -0
- lfx/components/zep/zep.py +45 -0
- lfx/constants.py +6 -0
- lfx/custom/__init__.py +7 -0
- lfx/custom/attributes.py +87 -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 +1890 -0
- lfx/custom/custom_component/component_with_cache.py +8 -0
- lfx/custom/custom_component/custom_component.py +650 -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 +523 -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 +216 -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 +300 -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 +2298 -0
- lfx/graph/graph/constants.py +63 -0
- lfx/graph/graph/runnable_vertices_manager.py +133 -0
- lfx/graph/graph/schema.py +53 -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 +250 -0
- lfx/graph/utils.py +206 -0
- lfx/graph/vertex/__init__.py +0 -0
- lfx/graph/vertex/base.py +826 -0
- lfx/graph/vertex/constants.py +0 -0
- lfx/graph/vertex/exceptions.py +4 -0
- lfx/graph/vertex/param_handler.py +316 -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 +141 -0
- lfx/helpers/base_model.py +71 -0
- lfx/helpers/custom.py +13 -0
- lfx/helpers/data.py +167 -0
- lfx/helpers/flow.py +308 -0
- lfx/inputs/__init__.py +68 -0
- lfx/inputs/constants.py +2 -0
- lfx/inputs/input_mixin.py +352 -0
- lfx/inputs/inputs.py +718 -0
- lfx/inputs/validators.py +19 -0
- lfx/interface/__init__.py +6 -0
- lfx/interface/components.py +897 -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 +317 -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 +295 -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 +411 -0
- lfx/logging/__init__.py +11 -0
- lfx/logging/logger.py +24 -0
- lfx/memory/__init__.py +70 -0
- lfx/memory/stubs.py +302 -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/cross_module.py +80 -0
- lfx/schema/data.py +309 -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 +184 -0
- lfx/schema/json_schema.py +186 -0
- lfx/schema/log.py +62 -0
- lfx/schema/message.py +493 -0
- lfx/schema/openai_responses_schemas.py +74 -0
- lfx/schema/properties.py +41 -0
- lfx/schema/schema.py +180 -0
- lfx/schema/serialize.py +13 -0
- lfx/schema/table.py +142 -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 +26 -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/database/__init__.py +5 -0
- lfx/services/database/service.py +25 -0
- lfx/services/deps.py +194 -0
- lfx/services/factory.py +19 -0
- lfx/services/initialize.py +19 -0
- lfx/services/interfaces.py +103 -0
- lfx/services/manager.py +185 -0
- lfx/services/mcp_composer/__init__.py +6 -0
- lfx/services/mcp_composer/factory.py +16 -0
- lfx/services/mcp_composer/service.py +1441 -0
- lfx/services/schema.py +21 -0
- lfx/services/session.py +87 -0
- lfx/services/settings/__init__.py +3 -0
- lfx/services/settings/auth.py +133 -0
- lfx/services/settings/base.py +668 -0
- lfx/services/settings/constants.py +43 -0
- lfx/services/settings/factory.py +23 -0
- lfx/services/settings/feature_flags.py +11 -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 +185 -0
- lfx/services/storage/service.py +177 -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 +260 -0
- lfx/template/field/prompt.py +15 -0
- lfx/template/frontend_node/__init__.py +6 -0
- lfx/template/frontend_node/base.py +214 -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 +233 -0
- lfx/utils/data_structure.py +212 -0
- lfx/utils/exceptions.py +22 -0
- lfx/utils/helpers.py +34 -0
- lfx/utils/image.py +79 -0
- lfx/utils/langflow_utils.py +52 -0
- lfx/utils/lazy_load.py +15 -0
- lfx/utils/request_utils.py +18 -0
- lfx/utils/schemas.py +139 -0
- lfx/utils/ssrf_protection.py +384 -0
- lfx/utils/util.py +626 -0
- lfx/utils/util_strings.py +56 -0
- lfx/utils/validate_cloud.py +26 -0
- lfx/utils/version.py +24 -0
- lfx_nightly-0.2.0.dev25.dist-info/METADATA +312 -0
- lfx_nightly-0.2.0.dev25.dist-info/RECORD +769 -0
- lfx_nightly-0.2.0.dev25.dist-info/WHEEL +4 -0
- lfx_nightly-0.2.0.dev25.dist-info/entry_points.txt +2 -0
|
@@ -0,0 +1,263 @@
|
|
|
1
|
+
from contextlib import contextmanager
|
|
2
|
+
|
|
3
|
+
import googleapiclient
|
|
4
|
+
import pandas as pd
|
|
5
|
+
from googleapiclient.discovery import build
|
|
6
|
+
from googleapiclient.errors import HttpError
|
|
7
|
+
|
|
8
|
+
from lfx.custom.custom_component.component import Component
|
|
9
|
+
from lfx.inputs.inputs import BoolInput, MessageTextInput, SecretStrInput
|
|
10
|
+
from lfx.schema.dataframe import DataFrame
|
|
11
|
+
from lfx.template.field.base import Output
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
class YouTubeVideoDetailsComponent(Component):
|
|
15
|
+
"""A component that retrieves detailed information about YouTube videos."""
|
|
16
|
+
|
|
17
|
+
display_name: str = "YouTube Video Details"
|
|
18
|
+
description: str = "Retrieves detailed information and statistics about YouTube videos."
|
|
19
|
+
icon: str = "YouTube"
|
|
20
|
+
|
|
21
|
+
inputs = [
|
|
22
|
+
MessageTextInput(
|
|
23
|
+
name="video_url",
|
|
24
|
+
display_name="Video URL",
|
|
25
|
+
info="The URL of the YouTube video.",
|
|
26
|
+
tool_mode=True,
|
|
27
|
+
required=True,
|
|
28
|
+
),
|
|
29
|
+
SecretStrInput(
|
|
30
|
+
name="api_key",
|
|
31
|
+
display_name="YouTube API Key",
|
|
32
|
+
info="Your YouTube Data API key.",
|
|
33
|
+
required=True,
|
|
34
|
+
),
|
|
35
|
+
BoolInput(
|
|
36
|
+
name="include_statistics",
|
|
37
|
+
display_name="Include Statistics",
|
|
38
|
+
value=True,
|
|
39
|
+
info="Include video statistics (views, likes, comments).",
|
|
40
|
+
),
|
|
41
|
+
BoolInput(
|
|
42
|
+
name="include_content_details",
|
|
43
|
+
display_name="Include Content Details",
|
|
44
|
+
value=True,
|
|
45
|
+
info="Include video duration, quality, and age restriction info.",
|
|
46
|
+
advanced=True,
|
|
47
|
+
),
|
|
48
|
+
BoolInput(
|
|
49
|
+
name="include_tags",
|
|
50
|
+
display_name="Include Tags",
|
|
51
|
+
value=True,
|
|
52
|
+
info="Include video tags and keywords.",
|
|
53
|
+
advanced=True,
|
|
54
|
+
),
|
|
55
|
+
BoolInput(
|
|
56
|
+
name="include_thumbnails",
|
|
57
|
+
display_name="Include Thumbnails",
|
|
58
|
+
value=True,
|
|
59
|
+
info="Include video thumbnail URLs in different resolutions.",
|
|
60
|
+
advanced=True,
|
|
61
|
+
),
|
|
62
|
+
]
|
|
63
|
+
|
|
64
|
+
outputs = [
|
|
65
|
+
Output(name="video_data", display_name="Video Data", method="get_video_details"),
|
|
66
|
+
]
|
|
67
|
+
|
|
68
|
+
API_FORBIDDEN = 403
|
|
69
|
+
VIDEO_NOT_FOUND = 404
|
|
70
|
+
|
|
71
|
+
@contextmanager
|
|
72
|
+
def youtube_client(self):
|
|
73
|
+
"""Context manager for YouTube API client."""
|
|
74
|
+
client = build("youtube", "v3", developerKey=self.api_key)
|
|
75
|
+
try:
|
|
76
|
+
yield client
|
|
77
|
+
finally:
|
|
78
|
+
client.close()
|
|
79
|
+
|
|
80
|
+
def _extract_video_id(self, video_url: str) -> str:
|
|
81
|
+
"""Extracts the video ID from a YouTube URL."""
|
|
82
|
+
import re
|
|
83
|
+
|
|
84
|
+
patterns = [
|
|
85
|
+
r"(?:youtube\.com\/watch\?v=|youtu.be\/|youtube.com\/embed\/)([^&\n?#]+)",
|
|
86
|
+
r"youtube.com\/shorts\/([^&\n?#]+)",
|
|
87
|
+
]
|
|
88
|
+
|
|
89
|
+
for pattern in patterns:
|
|
90
|
+
match = re.search(pattern, video_url)
|
|
91
|
+
if match:
|
|
92
|
+
return match.group(1)
|
|
93
|
+
|
|
94
|
+
return video_url.strip()
|
|
95
|
+
|
|
96
|
+
def _format_duration(self, duration: str) -> str:
|
|
97
|
+
"""Formats the ISO 8601 duration to a readable format."""
|
|
98
|
+
import re
|
|
99
|
+
|
|
100
|
+
hours = 0
|
|
101
|
+
minutes = 0
|
|
102
|
+
seconds = 0
|
|
103
|
+
|
|
104
|
+
hours_match = re.search(r"(\d+)H", duration)
|
|
105
|
+
minutes_match = re.search(r"(\d+)M", duration)
|
|
106
|
+
seconds_match = re.search(r"(\d+)S", duration)
|
|
107
|
+
|
|
108
|
+
if hours_match:
|
|
109
|
+
hours = int(hours_match.group(1))
|
|
110
|
+
if minutes_match:
|
|
111
|
+
minutes = int(minutes_match.group(1))
|
|
112
|
+
if seconds_match:
|
|
113
|
+
seconds = int(seconds_match.group(1))
|
|
114
|
+
|
|
115
|
+
if hours > 0:
|
|
116
|
+
return f"{hours:02d}:{minutes:02d}:{seconds:02d}"
|
|
117
|
+
return f"{minutes:02d}:{seconds:02d}"
|
|
118
|
+
|
|
119
|
+
def get_video_details(self) -> DataFrame:
|
|
120
|
+
"""Retrieves detailed information about a YouTube video and returns as DataFrame."""
|
|
121
|
+
try:
|
|
122
|
+
with self.youtube_client() as youtube:
|
|
123
|
+
# Extract video ID
|
|
124
|
+
video_id = self._extract_video_id(self.video_url)
|
|
125
|
+
|
|
126
|
+
# Prepare parts for the API request
|
|
127
|
+
parts = ["snippet"]
|
|
128
|
+
if self.include_statistics:
|
|
129
|
+
parts.append("statistics")
|
|
130
|
+
if self.include_content_details:
|
|
131
|
+
parts.append("contentDetails")
|
|
132
|
+
|
|
133
|
+
# Get video information
|
|
134
|
+
video_response = youtube.videos().list(part=",".join(parts), id=video_id).execute()
|
|
135
|
+
|
|
136
|
+
if not video_response["items"]:
|
|
137
|
+
return DataFrame(pd.DataFrame({"error": ["Video not found"]}))
|
|
138
|
+
|
|
139
|
+
video_info = video_response["items"][0]
|
|
140
|
+
snippet = video_info["snippet"]
|
|
141
|
+
|
|
142
|
+
# Build video data dictionary
|
|
143
|
+
video_data = {
|
|
144
|
+
"video_id": [video_id],
|
|
145
|
+
"url": [f"https://www.youtube.com/watch?v={video_id}"],
|
|
146
|
+
"title": [snippet["title"]],
|
|
147
|
+
"description": [snippet["description"]],
|
|
148
|
+
"published_at": [snippet["publishedAt"]],
|
|
149
|
+
"channel_id": [snippet["channelId"]],
|
|
150
|
+
"channel_title": [snippet["channelTitle"]],
|
|
151
|
+
"category_id": [snippet.get("categoryId", "Unknown")],
|
|
152
|
+
"live_broadcast_content": [snippet.get("liveBroadcastContent", "none")],
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
# Add thumbnails if requested
|
|
156
|
+
if self.include_thumbnails:
|
|
157
|
+
for size, thumb in snippet["thumbnails"].items():
|
|
158
|
+
video_data[f"thumbnail_{size}_url"] = [thumb["url"]]
|
|
159
|
+
video_data[f"thumbnail_{size}_width"] = [thumb.get("width", 0)]
|
|
160
|
+
video_data[f"thumbnail_{size}_height"] = [thumb.get("height", 0)]
|
|
161
|
+
|
|
162
|
+
# Add tags if requested
|
|
163
|
+
if self.include_tags and "tags" in snippet:
|
|
164
|
+
video_data["tags"] = [", ".join(snippet["tags"])]
|
|
165
|
+
video_data["tags_count"] = [len(snippet["tags"])]
|
|
166
|
+
|
|
167
|
+
# Add statistics if requested
|
|
168
|
+
if self.include_statistics and "statistics" in video_info:
|
|
169
|
+
stats = video_info["statistics"]
|
|
170
|
+
video_data.update(
|
|
171
|
+
{
|
|
172
|
+
"view_count": [int(stats.get("viewCount", 0))],
|
|
173
|
+
"like_count": [int(stats.get("likeCount", 0))],
|
|
174
|
+
"favorite_count": [int(stats.get("favoriteCount", 0))],
|
|
175
|
+
"comment_count": [int(stats.get("commentCount", 0))],
|
|
176
|
+
}
|
|
177
|
+
)
|
|
178
|
+
|
|
179
|
+
# Add content details if requested
|
|
180
|
+
if self.include_content_details and "contentDetails" in video_info:
|
|
181
|
+
content_details = video_info["contentDetails"]
|
|
182
|
+
video_data.update(
|
|
183
|
+
{
|
|
184
|
+
"duration": [self._format_duration(content_details["duration"])],
|
|
185
|
+
"dimension": [content_details.get("dimension", "2d")],
|
|
186
|
+
"definition": [content_details.get("definition", "hd").upper()],
|
|
187
|
+
"has_captions": [content_details.get("caption", "false") == "true"],
|
|
188
|
+
"licensed_content": [content_details.get("licensedContent", False)],
|
|
189
|
+
"projection": [content_details.get("projection", "rectangular")],
|
|
190
|
+
"has_custom_thumbnails": [content_details.get("hasCustomThumbnail", False)],
|
|
191
|
+
}
|
|
192
|
+
)
|
|
193
|
+
|
|
194
|
+
# Add content rating if available
|
|
195
|
+
if "contentRating" in content_details:
|
|
196
|
+
rating_info = content_details["contentRating"]
|
|
197
|
+
video_data["content_rating"] = [str(rating_info)]
|
|
198
|
+
|
|
199
|
+
# Create DataFrame with organized columns
|
|
200
|
+
video_df = pd.DataFrame(video_data)
|
|
201
|
+
|
|
202
|
+
# Organize columns in logical groups
|
|
203
|
+
basic_cols = [
|
|
204
|
+
"video_id",
|
|
205
|
+
"title",
|
|
206
|
+
"url",
|
|
207
|
+
"channel_id",
|
|
208
|
+
"channel_title",
|
|
209
|
+
"published_at",
|
|
210
|
+
"category_id",
|
|
211
|
+
"live_broadcast_content",
|
|
212
|
+
"description",
|
|
213
|
+
]
|
|
214
|
+
|
|
215
|
+
stat_cols = ["view_count", "like_count", "favorite_count", "comment_count"]
|
|
216
|
+
|
|
217
|
+
content_cols = [
|
|
218
|
+
"duration",
|
|
219
|
+
"dimension",
|
|
220
|
+
"definition",
|
|
221
|
+
"has_captions",
|
|
222
|
+
"licensed_content",
|
|
223
|
+
"projection",
|
|
224
|
+
"has_custom_thumbnails",
|
|
225
|
+
"content_rating",
|
|
226
|
+
]
|
|
227
|
+
|
|
228
|
+
tag_cols = ["tags", "tags_count"]
|
|
229
|
+
|
|
230
|
+
thumb_cols = [col for col in video_df.columns if col.startswith("thumbnail_")]
|
|
231
|
+
|
|
232
|
+
# Reorder columns based on what's included
|
|
233
|
+
ordered_cols = basic_cols.copy()
|
|
234
|
+
|
|
235
|
+
if self.include_statistics:
|
|
236
|
+
ordered_cols.extend([col for col in stat_cols if col in video_df.columns])
|
|
237
|
+
|
|
238
|
+
if self.include_content_details:
|
|
239
|
+
ordered_cols.extend([col for col in content_cols if col in video_df.columns])
|
|
240
|
+
|
|
241
|
+
if self.include_tags:
|
|
242
|
+
ordered_cols.extend([col for col in tag_cols if col in video_df.columns])
|
|
243
|
+
|
|
244
|
+
if self.include_thumbnails:
|
|
245
|
+
ordered_cols.extend(sorted(thumb_cols))
|
|
246
|
+
|
|
247
|
+
# Add any remaining columns
|
|
248
|
+
remaining_cols = [col for col in video_df.columns if col not in ordered_cols]
|
|
249
|
+
ordered_cols.extend(remaining_cols)
|
|
250
|
+
|
|
251
|
+
return DataFrame(video_df[ordered_cols])
|
|
252
|
+
|
|
253
|
+
except (HttpError, googleapiclient.errors.HttpError) as e:
|
|
254
|
+
error_message = f"YouTube API error: {e!s}"
|
|
255
|
+
if e.resp.status == self.API_FORBIDDEN:
|
|
256
|
+
error_message = "API quota exceeded or access forbidden."
|
|
257
|
+
elif e.resp.status == self.VIDEO_NOT_FOUND:
|
|
258
|
+
error_message = "Video not found."
|
|
259
|
+
|
|
260
|
+
return DataFrame(pd.DataFrame({"error": [error_message]}))
|
|
261
|
+
|
|
262
|
+
except KeyError as e:
|
|
263
|
+
return DataFrame(pd.DataFrame({"error": [str(e)]}))
|
|
@@ -0,0 +1,206 @@
|
|
|
1
|
+
import re
|
|
2
|
+
|
|
3
|
+
import pandas as pd
|
|
4
|
+
from youtube_transcript_api import NoTranscriptFound, TranscriptsDisabled, YouTubeTranscriptApi
|
|
5
|
+
|
|
6
|
+
from lfx.custom.custom_component.component import Component
|
|
7
|
+
from lfx.inputs.inputs import DropdownInput, IntInput, MultilineInput
|
|
8
|
+
from lfx.schema.data import Data
|
|
9
|
+
from lfx.schema.dataframe import DataFrame
|
|
10
|
+
from lfx.schema.message import Message
|
|
11
|
+
from lfx.template.field.base import Output
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
class YouTubeTranscriptsComponent(Component):
|
|
15
|
+
"""A component that extracts spoken content from YouTube videos as transcripts."""
|
|
16
|
+
|
|
17
|
+
display_name: str = "YouTube Transcripts"
|
|
18
|
+
description: str = "Extracts spoken content from YouTube videos with multiple output options."
|
|
19
|
+
icon: str = "YouTube"
|
|
20
|
+
name = "YouTubeTranscripts"
|
|
21
|
+
|
|
22
|
+
inputs = [
|
|
23
|
+
MultilineInput(
|
|
24
|
+
name="url",
|
|
25
|
+
display_name="Video URL",
|
|
26
|
+
info="Enter the YouTube video URL to get transcripts from.",
|
|
27
|
+
tool_mode=True,
|
|
28
|
+
required=True,
|
|
29
|
+
),
|
|
30
|
+
IntInput(
|
|
31
|
+
name="chunk_size_seconds",
|
|
32
|
+
display_name="Chunk Size (seconds)",
|
|
33
|
+
value=60,
|
|
34
|
+
info="The size of each transcript chunk in seconds.",
|
|
35
|
+
),
|
|
36
|
+
DropdownInput(
|
|
37
|
+
name="translation",
|
|
38
|
+
display_name="Translation Language",
|
|
39
|
+
advanced=True,
|
|
40
|
+
options=["", "en", "es", "fr", "de", "it", "pt", "ru", "ja", "ko", "hi", "ar", "id"],
|
|
41
|
+
info="Translate the transcripts to the specified language. Leave empty for no translation.",
|
|
42
|
+
),
|
|
43
|
+
]
|
|
44
|
+
|
|
45
|
+
outputs = [
|
|
46
|
+
Output(name="dataframe", display_name="Chunks", method="get_dataframe_output"),
|
|
47
|
+
Output(name="message", display_name="Transcript", method="get_message_output"),
|
|
48
|
+
Output(name="data_output", display_name="Transcript + Source", method="get_data_output"),
|
|
49
|
+
]
|
|
50
|
+
|
|
51
|
+
def _extract_video_id(self, url: str) -> str:
|
|
52
|
+
"""Extract video ID from YouTube URL."""
|
|
53
|
+
patterns = [
|
|
54
|
+
r"(?:youtube\.com\/watch\?v=|youtu\.be\/|youtube\.com\/embed\/)([^&\n?#]+)",
|
|
55
|
+
r"youtube\.com\/watch\?.*?v=([^&\n?#]+)",
|
|
56
|
+
]
|
|
57
|
+
for pattern in patterns:
|
|
58
|
+
match = re.search(pattern, url)
|
|
59
|
+
if match:
|
|
60
|
+
return match.group(1)
|
|
61
|
+
msg = f"Could not extract video ID from URL: {url}"
|
|
62
|
+
raise ValueError(msg)
|
|
63
|
+
|
|
64
|
+
def _load_transcripts(self, *, as_chunks: bool = True):
|
|
65
|
+
"""Internal method to load transcripts from YouTube."""
|
|
66
|
+
try:
|
|
67
|
+
video_id = self._extract_video_id(self.url)
|
|
68
|
+
except ValueError as e:
|
|
69
|
+
msg = f"Invalid YouTube URL: {e}"
|
|
70
|
+
raise ValueError(msg) from e
|
|
71
|
+
|
|
72
|
+
try:
|
|
73
|
+
# Use new v1.0+ API - create instance
|
|
74
|
+
api = YouTubeTranscriptApi()
|
|
75
|
+
transcript_list = api.list(video_id)
|
|
76
|
+
|
|
77
|
+
# Get transcript in specified language or default to English
|
|
78
|
+
if self.translation:
|
|
79
|
+
# Get any available transcript and translate it
|
|
80
|
+
transcript = transcript_list.find_transcript(["en"])
|
|
81
|
+
transcript = transcript.translate(self.translation)
|
|
82
|
+
else:
|
|
83
|
+
# Try to get transcript in available languages
|
|
84
|
+
try:
|
|
85
|
+
transcript = transcript_list.find_transcript(["en"])
|
|
86
|
+
except NoTranscriptFound:
|
|
87
|
+
# Try auto-generated English
|
|
88
|
+
transcript = transcript_list.find_generated_transcript(["en"])
|
|
89
|
+
|
|
90
|
+
# Fetch the transcript data
|
|
91
|
+
transcript_data = api.fetch(transcript.video_id, [transcript.language_code])
|
|
92
|
+
|
|
93
|
+
except (TranscriptsDisabled, NoTranscriptFound) as e:
|
|
94
|
+
error_type = type(e).__name__
|
|
95
|
+
msg = (
|
|
96
|
+
f"Could not retrieve transcripts for video '{video_id}'. "
|
|
97
|
+
"Possible reasons:\n"
|
|
98
|
+
"1. This video does not have captions/transcripts enabled\n"
|
|
99
|
+
"2. The video is private, restricted, or deleted\n"
|
|
100
|
+
f"\nTechnical error ({error_type}): {e}"
|
|
101
|
+
)
|
|
102
|
+
raise RuntimeError(msg) from e
|
|
103
|
+
except Exception as e:
|
|
104
|
+
error_type = type(e).__name__
|
|
105
|
+
msg = (
|
|
106
|
+
f"Could not retrieve transcripts for video '{video_id}'. "
|
|
107
|
+
"Possible reasons:\n"
|
|
108
|
+
"1. This video does not have captions/transcripts enabled\n"
|
|
109
|
+
"2. The video is private, restricted, or deleted\n"
|
|
110
|
+
"3. YouTube is blocking automated requests\n"
|
|
111
|
+
f"\nTechnical error ({error_type}): {e}"
|
|
112
|
+
)
|
|
113
|
+
raise RuntimeError(msg) from e
|
|
114
|
+
|
|
115
|
+
if as_chunks:
|
|
116
|
+
# Group into chunks based on chunk_size_seconds
|
|
117
|
+
return self._chunk_transcript(transcript_data)
|
|
118
|
+
# Return as continuous text
|
|
119
|
+
return transcript_data
|
|
120
|
+
|
|
121
|
+
def _chunk_transcript(self, transcript_data):
|
|
122
|
+
"""Group transcript segments into time-based chunks."""
|
|
123
|
+
chunks = []
|
|
124
|
+
current_chunk = []
|
|
125
|
+
chunk_start = 0
|
|
126
|
+
|
|
127
|
+
for segment in transcript_data:
|
|
128
|
+
# Handle both dict (old API) and object (new API) formats
|
|
129
|
+
segment_start = segment.start if hasattr(segment, "start") else segment["start"]
|
|
130
|
+
|
|
131
|
+
# If this segment starts beyond the current chunk window, start a new chunk
|
|
132
|
+
if segment_start - chunk_start >= self.chunk_size_seconds and current_chunk:
|
|
133
|
+
chunk_text = " ".join(s.text if hasattr(s, "text") else s["text"] for s in current_chunk)
|
|
134
|
+
chunks.append({"start": chunk_start, "text": chunk_text})
|
|
135
|
+
current_chunk = []
|
|
136
|
+
chunk_start = segment_start
|
|
137
|
+
|
|
138
|
+
current_chunk.append(segment)
|
|
139
|
+
|
|
140
|
+
# Add the last chunk
|
|
141
|
+
if current_chunk:
|
|
142
|
+
chunk_text = " ".join(s.text if hasattr(s, "text") else s["text"] for s in current_chunk)
|
|
143
|
+
chunks.append({"start": chunk_start, "text": chunk_text})
|
|
144
|
+
|
|
145
|
+
return chunks
|
|
146
|
+
|
|
147
|
+
def get_dataframe_output(self) -> DataFrame:
|
|
148
|
+
"""Provides transcript output as a DataFrame with timestamp and text columns."""
|
|
149
|
+
try:
|
|
150
|
+
chunks = self._load_transcripts(as_chunks=True)
|
|
151
|
+
|
|
152
|
+
# Create DataFrame with timestamp and text columns
|
|
153
|
+
data = []
|
|
154
|
+
for chunk in chunks:
|
|
155
|
+
start_seconds = int(chunk["start"])
|
|
156
|
+
start_minutes = start_seconds // 60
|
|
157
|
+
start_seconds_remainder = start_seconds % 60
|
|
158
|
+
timestamp = f"{start_minutes:02d}:{start_seconds_remainder:02d}"
|
|
159
|
+
data.append({"timestamp": timestamp, "text": chunk["text"]})
|
|
160
|
+
|
|
161
|
+
return DataFrame(pd.DataFrame(data))
|
|
162
|
+
|
|
163
|
+
except (TranscriptsDisabled, NoTranscriptFound, RuntimeError, ValueError) as exc:
|
|
164
|
+
error_msg = f"Failed to get YouTube transcripts: {exc!s}"
|
|
165
|
+
return DataFrame(pd.DataFrame({"error": [error_msg]}))
|
|
166
|
+
|
|
167
|
+
def get_message_output(self) -> Message:
|
|
168
|
+
"""Provides transcript output as continuous text."""
|
|
169
|
+
try:
|
|
170
|
+
transcript_data = self._load_transcripts(as_chunks=False)
|
|
171
|
+
# Handle both dict (old API) and object (new API) formats
|
|
172
|
+
result = " ".join(
|
|
173
|
+
segment.text if hasattr(segment, "text") else segment["text"] for segment in transcript_data
|
|
174
|
+
)
|
|
175
|
+
return Message(text=result)
|
|
176
|
+
|
|
177
|
+
except (TranscriptsDisabled, NoTranscriptFound, RuntimeError, ValueError) as exc:
|
|
178
|
+
error_msg = f"Failed to get YouTube transcripts: {exc!s}"
|
|
179
|
+
return Message(text=error_msg)
|
|
180
|
+
|
|
181
|
+
def get_data_output(self) -> Data:
|
|
182
|
+
"""Creates a structured data object with transcript and metadata.
|
|
183
|
+
|
|
184
|
+
Returns a Data object containing transcript text, video URL, and any error
|
|
185
|
+
messages that occurred during processing. The object includes:
|
|
186
|
+
- 'transcript': continuous text from the entire video (concatenated if multiple parts)
|
|
187
|
+
- 'video_url': the input YouTube URL
|
|
188
|
+
- 'error': error message if an exception occurs
|
|
189
|
+
"""
|
|
190
|
+
default_data = {"transcript": "", "video_url": self.url, "error": None}
|
|
191
|
+
|
|
192
|
+
try:
|
|
193
|
+
transcript_data = self._load_transcripts(as_chunks=False)
|
|
194
|
+
if not transcript_data:
|
|
195
|
+
default_data["error"] = "No transcripts found."
|
|
196
|
+
return Data(data=default_data)
|
|
197
|
+
|
|
198
|
+
# Combine all transcript segments - handle both dict and object formats
|
|
199
|
+
full_transcript = " ".join(
|
|
200
|
+
segment.text if hasattr(segment, "text") else segment["text"] for segment in transcript_data
|
|
201
|
+
)
|
|
202
|
+
return Data(data={"transcript": full_transcript, "video_url": self.url})
|
|
203
|
+
|
|
204
|
+
except (TranscriptsDisabled, NoTranscriptFound, RuntimeError, ValueError) as exc:
|
|
205
|
+
default_data["error"] = str(exc)
|
|
206
|
+
return Data(data=default_data)
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
from lfx.base.memory.model import LCChatMemoryComponent
|
|
2
|
+
from lfx.field_typing.constants import Memory
|
|
3
|
+
from lfx.inputs.inputs import DropdownInput, MessageTextInput, SecretStrInput
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
class ZepChatMemory(LCChatMemoryComponent):
|
|
7
|
+
display_name = "Zep Chat Memory"
|
|
8
|
+
description = "Retrieves and store chat messages from Zep."
|
|
9
|
+
name = "ZepChatMemory"
|
|
10
|
+
icon = "ZepMemory"
|
|
11
|
+
legacy = True
|
|
12
|
+
replacement = ["helpers.Memory"]
|
|
13
|
+
|
|
14
|
+
inputs = [
|
|
15
|
+
MessageTextInput(name="url", display_name="Zep URL", info="URL of the Zep instance."),
|
|
16
|
+
SecretStrInput(name="api_key", display_name="Zep API Key", info="API Key for the Zep instance."),
|
|
17
|
+
DropdownInput(
|
|
18
|
+
name="api_base_path",
|
|
19
|
+
display_name="API Base Path",
|
|
20
|
+
options=["api/v1", "api/v2"],
|
|
21
|
+
value="api/v1",
|
|
22
|
+
advanced=True,
|
|
23
|
+
),
|
|
24
|
+
MessageTextInput(
|
|
25
|
+
name="session_id", display_name="Session ID", info="Session ID for the message.", advanced=True
|
|
26
|
+
),
|
|
27
|
+
]
|
|
28
|
+
|
|
29
|
+
def build_message_history(self) -> Memory:
|
|
30
|
+
try:
|
|
31
|
+
# Monkeypatch API_BASE_PATH to
|
|
32
|
+
# avoid 404
|
|
33
|
+
# This is a workaround for the local Zep instance
|
|
34
|
+
# cloud Zep works with v2
|
|
35
|
+
import zep_python.zep_client
|
|
36
|
+
from zep_python import ZepClient
|
|
37
|
+
from zep_python.langchain import ZepChatMessageHistory
|
|
38
|
+
|
|
39
|
+
zep_python.zep_client.API_BASE_PATH = self.api_base_path
|
|
40
|
+
except ImportError as e:
|
|
41
|
+
msg = "Could not import zep-python package. Please install it with `pip install zep-python`."
|
|
42
|
+
raise ImportError(msg) from e
|
|
43
|
+
|
|
44
|
+
zep_client = ZepClient(api_url=self.url, api_key=self.api_key)
|
|
45
|
+
return ZepChatMessageHistory(session_id=self.session_id, zep_client=zep_client)
|
lfx/constants.py
ADDED
lfx/custom/__init__.py
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
from lfx.custom.custom_component.component import Component
|
|
2
|
+
from lfx.custom.custom_component.custom_component import CustomComponent
|
|
3
|
+
|
|
4
|
+
from . import custom_component as custom_component
|
|
5
|
+
from . import utils as utils
|
|
6
|
+
|
|
7
|
+
__all__ = ["Component", "CustomComponent", "custom_component", "utils"]
|
lfx/custom/attributes.py
ADDED
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
from collections.abc import Callable
|
|
2
|
+
|
|
3
|
+
import emoji
|
|
4
|
+
|
|
5
|
+
from lfx.log.logger import logger
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
def validate_icon(value: str):
|
|
9
|
+
# we are going to use the emoji library to validate the emoji
|
|
10
|
+
# emojis can be defined using the :emoji_name: syntax
|
|
11
|
+
|
|
12
|
+
if not value.startswith(":") and not value.endswith(":"):
|
|
13
|
+
return value
|
|
14
|
+
if not value.startswith(":") or not value.endswith(":"):
|
|
15
|
+
# emoji should have both starting and ending colons
|
|
16
|
+
# so if one of them is missing, we will raise
|
|
17
|
+
msg = f"Invalid emoji. {value} is not a valid emoji."
|
|
18
|
+
raise ValueError(msg)
|
|
19
|
+
|
|
20
|
+
emoji_value = emoji.emojize(value, variant="emoji_type")
|
|
21
|
+
if value == emoji_value:
|
|
22
|
+
logger.warning(f"Invalid emoji. {value} is not a valid emoji.")
|
|
23
|
+
return value
|
|
24
|
+
return emoji_value
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
def getattr_return_str(value):
|
|
28
|
+
return str(value) if value else ""
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
def getattr_return_bool(value):
|
|
32
|
+
if isinstance(value, bool):
|
|
33
|
+
return value
|
|
34
|
+
return None
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
def getattr_return_int(value):
|
|
38
|
+
if isinstance(value, int):
|
|
39
|
+
return value
|
|
40
|
+
return None
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
def getattr_return_list_of_str(value):
|
|
44
|
+
if isinstance(value, list):
|
|
45
|
+
return [str(val) for val in value]
|
|
46
|
+
return []
|
|
47
|
+
|
|
48
|
+
|
|
49
|
+
def getattr_return_list_of_object(value):
|
|
50
|
+
if isinstance(value, list):
|
|
51
|
+
return value
|
|
52
|
+
return []
|
|
53
|
+
|
|
54
|
+
|
|
55
|
+
def getattr_return_list_of_values_from_dict(value):
|
|
56
|
+
if isinstance(value, dict):
|
|
57
|
+
return list(value.values())
|
|
58
|
+
return []
|
|
59
|
+
|
|
60
|
+
|
|
61
|
+
def getattr_return_dict(value):
|
|
62
|
+
if isinstance(value, dict):
|
|
63
|
+
return value
|
|
64
|
+
return {}
|
|
65
|
+
|
|
66
|
+
|
|
67
|
+
ATTR_FUNC_MAPPING: dict[str, Callable] = {
|
|
68
|
+
"display_name": getattr_return_str,
|
|
69
|
+
"description": getattr_return_str,
|
|
70
|
+
"beta": getattr_return_bool,
|
|
71
|
+
"legacy": getattr_return_bool,
|
|
72
|
+
"replacement": getattr_return_list_of_str,
|
|
73
|
+
"documentation": getattr_return_str,
|
|
74
|
+
"priority": getattr_return_int,
|
|
75
|
+
"icon": validate_icon,
|
|
76
|
+
"minimized": getattr_return_bool,
|
|
77
|
+
"frozen": getattr_return_bool,
|
|
78
|
+
"is_input": getattr_return_bool,
|
|
79
|
+
"is_output": getattr_return_bool,
|
|
80
|
+
"conditional_paths": getattr_return_list_of_str,
|
|
81
|
+
"_outputs_map": getattr_return_list_of_values_from_dict,
|
|
82
|
+
"_inputs": getattr_return_list_of_values_from_dict,
|
|
83
|
+
"outputs": getattr_return_list_of_object,
|
|
84
|
+
"inputs": getattr_return_list_of_object,
|
|
85
|
+
"metadata": getattr_return_dict,
|
|
86
|
+
"tool_mode": getattr_return_bool,
|
|
87
|
+
}
|