langflow-base-nightly 0.5.0.dev38__py3-none-any.whl → 0.5.0.dev39__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.
- langflow/alembic/versions/0882f9657f22_encrypt_existing_mcp_auth_settings_.py +122 -0
- langflow/api/v1/mcp_projects.py +373 -52
- langflow/api/v1/schemas.py +1 -2
- langflow/components/FAISS/__init__.py +34 -0
- langflow/components/agents/agent.py +246 -52
- langflow/components/cassandra/__init__.py +40 -0
- langflow/components/chroma/__init__.py +34 -0
- langflow/components/clickhouse/__init__.py +34 -0
- langflow/components/couchbase/__init__.py +34 -0
- langflow/components/datastax/__init__.py +3 -3
- langflow/components/elastic/__init__.py +37 -0
- langflow/components/milvus/__init__.py +34 -0
- langflow/components/mongodb/__init__.py +34 -0
- langflow/components/ollama/ollama.py +1 -0
- langflow/components/perplexity/perplexity.py +3 -13
- langflow/components/pgvector/__init__.py +34 -0
- langflow/components/pinecone/__init__.py +34 -0
- langflow/components/qdrant/__init__.py +34 -0
- langflow/components/redis/__init__.py +36 -2
- langflow/components/redis/redis.py +75 -29
- langflow/components/redis/redis_chat.py +43 -0
- langflow/components/supabase/__init__.py +37 -0
- langflow/components/upstash/__init__.py +34 -0
- langflow/components/vectara/__init__.py +37 -0
- langflow/components/vectorstores/__init__.py +0 -69
- langflow/components/vectorstores/local_db.py +1 -0
- langflow/components/weaviate/__init__.py +34 -0
- langflow/custom/dependency_analyzer.py +165 -0
- langflow/custom/utils.py +34 -16
- langflow/frontend/assets/{SlackIcon-BhW6H3JR.js → SlackIcon-Cr3Q15Px.js} +1 -1
- langflow/frontend/assets/{Wikipedia-Dx5jbiy3.js → Wikipedia-GxM5sPdM.js} +1 -1
- langflow/frontend/assets/{Wolfram-CIyonzwo.js → Wolfram-BN3-VOCA.js} +1 -1
- langflow/frontend/assets/{index-DOEvKC2X.js → index-28oOcafk.js} +1 -1
- langflow/frontend/assets/{index-Bhv79Zso.js → index-2wSXqBtB.js} +1 -1
- langflow/frontend/assets/{index-BRmSeoWR.js → index-3wW7BClE.js} +1 -1
- langflow/frontend/assets/{index-eUkS6iJM.js → index-6pyH3ZJB.js} +1 -1
- langflow/frontend/assets/{index-Cr5v2ave.js → index-AWCSdofD.js} +1 -1
- langflow/frontend/assets/{index-C27Jj_26.js → index-B2Zgv_xv.js} +1 -1
- langflow/frontend/assets/{index-BKKrUElc.js → index-B2ptVQGM.js} +1 -1
- langflow/frontend/assets/{index-BnAFhkSN.js → index-B3TANVes.js} +1 -1
- langflow/frontend/assets/{index-hZUcL0MZ.js → index-B4yCvZKV.js} +1 -1
- langflow/frontend/assets/{index-BPR2mEFC.js → index-BC65VuWx.js} +1 -1
- langflow/frontend/assets/{index-CgU7KF4I.js → index-BCDSei1q.js} +1 -1
- langflow/frontend/assets/{index-CzHzeZuA.js → index-BJy50PvP.js} +1 -1
- langflow/frontend/assets/{index-DkGhPNeA.js → index-BKseQQ2I.js} +1 -1
- langflow/frontend/assets/{index-BVFaF7HW.js → index-BLTxEeTi.js} +1 -1
- langflow/frontend/assets/{index-cEXY6V06.js → index-BRg1f4Mu.js} +1 -1
- langflow/frontend/assets/{index-C2eQmQsn.js → index-BS8Vo8nc.js} +1 -1
- langflow/frontend/assets/{index-gdb7XMS8.js → index-BTKOU4xC.js} +1 -1
- langflow/frontend/assets/{index-U9GWm1eH.js → index-BVwJDmw-.js} +1 -1
- langflow/frontend/assets/{index-BWt5xGeA.js → index-BWYuQ2Sj.js} +1 -1
- langflow/frontend/assets/{index-Dx-Z87KT.js → index-BWdLILDG.js} +1 -1
- langflow/frontend/assets/{index-paQEWYGT.js → index-BZcw4827.js} +1 -1
- langflow/frontend/assets/{index-BDQrd7Tj.js → index-Bbi87Ve4.js} +1 -1
- langflow/frontend/assets/{index-vJOO5U8M.js → index-Bf0IYKLd.js} +1 -1
- langflow/frontend/assets/{index-1Q3VBqKn.js → index-Bg5nrMRh.js} +1 -1
- langflow/frontend/assets/{index-BFQ8KFK0.js → index-BiC280Nx.js} +1 -1
- langflow/frontend/assets/{index-CFNTYfFK.js → index-BiKKN6FR.js} +1 -1
- langflow/frontend/assets/{index-BPfdqCc_.js → index-Bief6eyJ.js} +1 -1
- langflow/frontend/assets/{index-Cxy9sEpy.js → index-BkXec1Yf.js} +1 -1
- langflow/frontend/assets/{index-D4tjMhfY.js → index-Bnl6QHtP.js} +1 -1
- langflow/frontend/assets/{index-BD7Io1hL.js → index-BpxbUiZD.js} +1978 -1978
- langflow/frontend/assets/{index-Ch5r0oW6.js → index-BrJV8psX.js} +1 -1
- langflow/frontend/assets/{index-DOQDkSoK.js → index-BwLWcUXL.js} +1 -1
- langflow/frontend/assets/{index-CMHpjHZl.js → index-Bx7dBY26.js} +1 -1
- langflow/frontend/assets/{index-CbnWRlYY.js → index-C-EdnFdA.js} +1 -1
- langflow/frontend/assets/{index-DljpLeCW.js → index-C-Xfg4cD.js} +1 -1
- langflow/frontend/assets/{index-Bwi4flFg.js → index-C1f2wMat.js} +1 -1
- langflow/frontend/assets/index-C1xroOlH.css +1 -0
- langflow/frontend/assets/{index-D6CSIrp1.js → index-C3KequvP.js} +1 -1
- langflow/frontend/assets/{index-BYjw7Gk3.js → index-C3ZjKdCD.js} +1 -1
- langflow/frontend/assets/{index-DIKUsGLF.js → index-C3l0zYn0.js} +1 -1
- langflow/frontend/assets/{index-CfPBgkqg.js → index-C3yvArUT.js} +1 -1
- langflow/frontend/assets/{index-CsLQiWNf.js → index-C9Cxnkl8.js} +1 -1
- langflow/frontend/assets/{index-mzl9ULw5.js → index-CBc8fEAE.js} +1 -1
- langflow/frontend/assets/{index-CEJNWPhA.js → index-CBvrGgID.js} +1 -1
- langflow/frontend/assets/{index-DwfHWnX7.js → index-CD-PqGCY.js} +1 -1
- langflow/frontend/assets/{index-dyXKnkMi.js → index-CGO1CiUr.js} +1 -1
- langflow/frontend/assets/{index-Dka_Rk4-.js → index-CH5UVA9b.js} +1 -1
- langflow/frontend/assets/{index-uiKla4UR.js → index-CLJeJYjH.js} +1 -1
- langflow/frontend/assets/{index-D9kwEzPB.js → index-CMZ79X-Y.js} +1 -1
- langflow/frontend/assets/{index-BrVhdPZb.js → index-CMzfJKiW.js} +1 -1
- langflow/frontend/assets/{index-Bct1s6__.js → index-CNw1H-Wc.js} +1 -1
- langflow/frontend/assets/{index-B7uEuOPK.js → index-CPHEscq9.js} +1 -1
- langflow/frontend/assets/{index-ekfMOqrF.js → index-CRPKJZw9.js} +1 -1
- langflow/frontend/assets/{index-G4ro0MjT.js → index-CRPyCfYy.js} +1 -1
- langflow/frontend/assets/{index-CSu8KHOi.js → index-CRcMqCIj.js} +1 -1
- langflow/frontend/assets/{index-DsoX2o1S.js → index-CUVDws8F.js} +1 -1
- langflow/frontend/assets/{index-r_8gs4nL.js → index-CVWQfRYZ.js} +1 -1
- langflow/frontend/assets/{index-7hzXChQz.js → index-CVl6MbaM.js} +1 -1
- langflow/frontend/assets/{index-B8UR8v-Q.js → index-CVwWoX99.js} +1 -1
- langflow/frontend/assets/{index-Dda2u_yz.js → index-CWPzZtSx.js} +1 -1
- langflow/frontend/assets/{index-BKeZt2hQ.js → index-CZqRL9DE.js} +1 -1
- langflow/frontend/assets/{index-DHngW1k8.js → index-CdIf07Rw.js} +1 -1
- langflow/frontend/assets/{index-C--IDAyc.js → index-Cewy7JZE.js} +1 -1
- langflow/frontend/assets/{index-DZP_SaHb.js → index-CfwLpbMM.js} +1 -1
- langflow/frontend/assets/{index-CuCM7Wu7.js → index-CiR1dxI4.js} +1 -1
- langflow/frontend/assets/{index-Xi4TplbI.js → index-CiixOzDG.js} +1 -1
- langflow/frontend/assets/{index-BLYw9MK2.js → index-ClsuDmR6.js} +1 -1
- langflow/frontend/assets/{index-DMCWDJOl.js → index-CmEYYRN1.js} +1 -1
- langflow/frontend/assets/{index-CrAF-31Y.js → index-Co20d-eQ.js} +1 -1
- langflow/frontend/assets/{index-DXAfIEvs.js → index-CpzXS6md.js} +1 -1
- langflow/frontend/assets/{index-BmYJJ5YS.js → index-Cqpzl1J4.js} +1 -1
- langflow/frontend/assets/{index-KWY77KfV.js → index-CtVIONP2.js} +1 -1
- langflow/frontend/assets/{index-B3KCdQ91.js → index-CuFXdTx4.js} +1 -1
- langflow/frontend/assets/{index-p2kStSPe.js → index-Cyd2HtHK.js} +1 -1
- langflow/frontend/assets/{index-CkjwSTSM.js → index-D-1tA8Dt.js} +1 -1
- langflow/frontend/assets/{index-BFf0HTFI.js → index-D-KY3kkq.js} +1 -1
- langflow/frontend/assets/{index-BYhcGLTV.js → index-D-_B1a8v.js} +1 -1
- langflow/frontend/assets/{index-Dr6pVDPI.js → index-D14EWPyZ.js} +1 -1
- langflow/frontend/assets/{index-BDuk0d7P.js → index-D2N3l-cw.js} +1 -1
- langflow/frontend/assets/{index-BvGQfVBD.js → index-D5ETnvJa.js} +1 -1
- langflow/frontend/assets/{index-D1oynC8a.js → index-D7kquVv2.js} +1 -1
- langflow/frontend/assets/{index-B1XqWJhG.js → index-DA6-bvgN.js} +1 -1
- langflow/frontend/assets/{index-DzIv3RyR.js → index-DDWBeudF.js} +1 -1
- langflow/frontend/assets/{index-BKlQbl-6.js → index-DDcMAaG4.js} +1 -1
- langflow/frontend/assets/{index-CkK25zZO.js → index-DHgomBdh.js} +1 -1
- langflow/frontend/assets/{index-Bj3lSwvZ.js → index-DJP-ss47.js} +1 -1
- langflow/frontend/assets/{index-DDXsm8tz.js → index-DQ7VYqQc.js} +1 -1
- langflow/frontend/assets/{index-BNQIbda3.js → index-DTqbvGC0.js} +1 -1
- langflow/frontend/assets/{index-BzoRPtTY.js → index-DUpri6zF.js} +1 -1
- langflow/frontend/assets/{index-35sspuLu.js → index-DV3utZDZ.js} +1 -1
- langflow/frontend/assets/{index-BpmqDOeZ.js → index-DXRfN4HV.js} +1 -1
- langflow/frontend/assets/{index-C0E3_MIK.js → index-Db9dYSzy.js} +1 -1
- langflow/frontend/assets/{index-C8K0r39B.js → index-DdtMEn6I.js} +1 -1
- langflow/frontend/assets/{index-BLsVo9iW.js → index-DfDhMHgQ.js} +1 -1
- langflow/frontend/assets/{index-BZFljdMa.js → index-Dfe7qfvf.js} +1 -1
- langflow/frontend/assets/{index-CyP3py8K.js → index-DhtZ5hx8.js} +1 -1
- langflow/frontend/assets/{index-w72fDjpG.js → index-DiB3CTo8.js} +1 -1
- langflow/frontend/assets/{index-CY7_TBTC.js → index-DiGWASY5.js} +1 -1
- langflow/frontend/assets/{index-CmSFKgiD.js → index-Dl5amdBz.js} +1 -1
- langflow/frontend/assets/{index-B0m53xKd.js → index-DlD4dXlZ.js} +1 -1
- langflow/frontend/assets/{index-DnVYJtVO.js → index-DmeiHnfl.js} +1 -1
- langflow/frontend/assets/index-Dmu-X5-4.js +1 -0
- langflow/frontend/assets/{index-CWYiSeWV.js → index-DpVWih90.js} +1 -1
- langflow/frontend/assets/{index-CjsommIr.js → index-DrDrcajG.js} +1 -1
- langflow/frontend/assets/{index-Un9pWxnP.js → index-Du-pc0KE.js} +1 -1
- langflow/frontend/assets/{index-oxHBZk2v.js → index-DwPkMTaY.js} +1 -1
- langflow/frontend/assets/{index-CgwykVGh.js → index-DwQEZe3C.js} +1 -1
- langflow/frontend/assets/{index-BmIx1cws.js → index-DyJFTK24.js} +1 -1
- langflow/frontend/assets/{index-0XQqYgdG.js → index-J38wh62w.js} +1 -1
- langflow/frontend/assets/{index-H7J7w7fa.js → index-Kwdl-e29.js} +1 -1
- langflow/frontend/assets/{index-CUKmGsI6.js → index-OwPvCmpW.js} +1 -1
- langflow/frontend/assets/{index-zV82kQ6k.js → index-Tw3Os-DN.js} +1 -1
- langflow/frontend/assets/{index-8cuhogZP.js → index-X0guhYF8.js} +1 -1
- langflow/frontend/assets/{index-BUse-kxM.js → index-dJWNxIRH.js} +1 -1
- langflow/frontend/assets/{index-DyqITq51.js → index-dcJ8-agu.js} +1 -1
- langflow/frontend/assets/{index-Cg53lrYh.js → index-eo2mAtL-.js} +1 -1
- langflow/frontend/assets/{index-DqbzUcI5.js → index-hG24k5xJ.js} +1 -1
- langflow/frontend/assets/{index-BQrVDjR1.js → index-h_aSZHf3.js} +1 -1
- langflow/frontend/assets/{index-kkA-qHB_.js → index-hbndqB9B.js} +1 -1
- langflow/frontend/assets/{index-DZxUIhWh.js → index-iJngutFo.js} +1 -1
- langflow/frontend/assets/{index-Dg8N3NSO.js → index-lTpteg8t.js} +1 -1
- langflow/frontend/assets/{index-DDhJVVel.js → index-lZX9AvZW.js} +1 -1
- langflow/frontend/assets/{index-BHhnpSkW.js → index-m8QA6VNM.js} +1 -1
- langflow/frontend/assets/{index-Bk4mTwnI.js → index-o0D2S7xW.js} +1 -1
- langflow/frontend/assets/{index-DJESSNJi.js → index-ovFJ_0J6.js} +1 -1
- langflow/frontend/assets/{index-DH6o91_s.js → index-pYJJOcma.js} +1 -1
- langflow/frontend/assets/{index-Bo-ww0Bb.js → index-sI75DsdM.js} +1 -1
- langflow/frontend/assets/{index-BcAgItH4.js → index-xvFOmxx4.js} +1 -1
- langflow/frontend/assets/{index-_cbGmjF4.js → index-z3SRY-mX.js} +1 -1
- langflow/frontend/assets/lazyIconImports-D97HEZkE.js +2 -0
- langflow/frontend/assets/{use-post-add-user-CvtuazTg.js → use-post-add-user-C0MdTpQ5.js} +1 -1
- langflow/frontend/index.html +2 -2
- langflow/graph/graph/base.py +1 -1
- langflow/initial_setup/starter_projects/Basic Prompt Chaining.json +26 -0
- langflow/initial_setup/starter_projects/Basic Prompting.json +26 -0
- langflow/initial_setup/starter_projects/Blog Writer.json +56 -0
- langflow/initial_setup/starter_projects/Custom Component Generator.json +35 -0
- langflow/initial_setup/starter_projects/Document Q&A.json +26 -0
- langflow/initial_setup/starter_projects/Financial Report Parser.json +43 -0
- langflow/initial_setup/starter_projects/Hybrid Search RAG.json +83 -1
- langflow/initial_setup/starter_projects/Image Sentiment Analysis.json +43 -0
- langflow/initial_setup/starter_projects/Instagram Copywriter.json +49 -1
- langflow/initial_setup/starter_projects/Invoice Summarizer.json +40 -1
- langflow/initial_setup/starter_projects/Knowledge Ingestion.json +71 -0
- langflow/initial_setup/starter_projects/Knowledge Retrieval.json +63 -0
- langflow/initial_setup/starter_projects/Market Research.json +57 -1
- langflow/initial_setup/starter_projects/Meeting Summary.json +95 -0
- langflow/initial_setup/starter_projects/Memory Chatbot.json +35 -0
- langflow/initial_setup/starter_projects/News Aggregator.json +61 -1
- langflow/initial_setup/starter_projects/Nvidia Remix.json +67 -2
- langflow/initial_setup/starter_projects/Pok/303/251dex Agent.json" +48 -1
- langflow/initial_setup/starter_projects/Portfolio Website Code Generator.json +43 -0
- langflow/initial_setup/starter_projects/Price Deal Finder.json +53 -1
- langflow/initial_setup/starter_projects/Research Agent.json +40 -1
- langflow/initial_setup/starter_projects/Research Translation Loop.json +66 -0
- langflow/initial_setup/starter_projects/SEO Keyword Generator.json +17 -0
- langflow/initial_setup/starter_projects/SaaS Pricing.json +27 -1
- langflow/initial_setup/starter_projects/Search agent.json +40 -1
- langflow/initial_setup/starter_projects/Sequential Tasks Agents.json +72 -3
- langflow/initial_setup/starter_projects/Simple Agent.json +57 -1
- langflow/initial_setup/starter_projects/Social Media Agent.json +77 -1
- langflow/initial_setup/starter_projects/Text Sentiment Analysis.json +34 -0
- langflow/initial_setup/starter_projects/Travel Planning Agents.json +51 -3
- langflow/initial_setup/starter_projects/Twitter Thread Generator.json +80 -0
- langflow/initial_setup/starter_projects/Vector Store RAG.json +109 -2
- langflow/initial_setup/starter_projects/Youtube Analysis.json +82 -1
- langflow/initial_setup/starter_projects/vector_store_rag.py +1 -1
- langflow/processing/process.py +3 -0
- langflow/services/auth/mcp_encryption.py +104 -0
- langflow/services/settings/feature_flags.py +1 -1
- {langflow_base_nightly-0.5.0.dev38.dist-info → langflow_base_nightly-0.5.0.dev39.dist-info}/METADATA +1 -1
- {langflow_base_nightly-0.5.0.dev38.dist-info → langflow_base_nightly-0.5.0.dev39.dist-info}/RECORD +229 -211
- langflow/components/vectorstores/redis.py +0 -89
- langflow/frontend/assets/index-BWgIWfv2.js +0 -1
- langflow/frontend/assets/index-CqS7zir1.css +0 -1
- langflow/frontend/assets/lazyIconImports-DTNgvPE-.js +0 -2
- /langflow/components/{vectorstores → FAISS}/faiss.py +0 -0
- /langflow/components/{vectorstores → cassandra}/cassandra.py +0 -0
- /langflow/components/{datastax/cassandra.py → cassandra/cassandra_chat.py} +0 -0
- /langflow/components/{vectorstores → cassandra}/cassandra_graph.py +0 -0
- /langflow/components/{vectorstores → chroma}/chroma.py +0 -0
- /langflow/components/{vectorstores → clickhouse}/clickhouse.py +0 -0
- /langflow/components/{vectorstores → couchbase}/couchbase.py +0 -0
- /langflow/components/{vectorstores → datastax}/astradb.py +0 -0
- /langflow/components/{vectorstores → datastax}/astradb_graph.py +0 -0
- /langflow/components/{vectorstores → datastax}/graph_rag.py +0 -0
- /langflow/components/{vectorstores → datastax}/hcd.py +0 -0
- /langflow/components/{vectorstores → elastic}/elasticsearch.py +0 -0
- /langflow/components/{vectorstores → elastic}/opensearch.py +0 -0
- /langflow/components/{vectorstores → milvus}/milvus.py +0 -0
- /langflow/components/{vectorstores → mongodb}/mongodb_atlas.py +0 -0
- /langflow/components/{vectorstores → pgvector}/pgvector.py +0 -0
- /langflow/components/{vectorstores → pinecone}/pinecone.py +0 -0
- /langflow/components/{vectorstores → qdrant}/qdrant.py +0 -0
- /langflow/components/{vectorstores → supabase}/supabase.py +0 -0
- /langflow/components/{vectorstores → upstash}/upstash.py +0 -0
- /langflow/components/{vectorstores → vectara}/vectara.py +0 -0
- /langflow/components/{vectorstores → vectara}/vectara_rag.py +0 -0
- /langflow/components/{vectorstores → weaviate}/weaviate.py +0 -0
- {langflow_base_nightly-0.5.0.dev38.dist-info → langflow_base_nightly-0.5.0.dev39.dist-info}/WHEEL +0 -0
- {langflow_base_nightly-0.5.0.dev38.dist-info → langflow_base_nightly-0.5.0.dev39.dist-info}/entry_points.txt +0 -0
|
@@ -0,0 +1,165 @@
|
|
|
1
|
+
"""Dependency analysis utilities for custom components."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
import ast
|
|
6
|
+
import importlib.metadata as md
|
|
7
|
+
import sys
|
|
8
|
+
from dataclasses import asdict, dataclass
|
|
9
|
+
from functools import lru_cache
|
|
10
|
+
|
|
11
|
+
try:
|
|
12
|
+
STDLIB_MODULES: set[str] = set(sys.stdlib_module_names) # 3.10+
|
|
13
|
+
except AttributeError:
|
|
14
|
+
# Fallback heuristic if running on <3.10
|
|
15
|
+
STDLIB_MODULES = set(sys.builtin_module_names)
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
@dataclass(frozen=True)
|
|
19
|
+
class DependencyInfo:
|
|
20
|
+
"""Information about a dependency imported in Python code."""
|
|
21
|
+
|
|
22
|
+
name: str # package name (e.g. "numpy", "requests")
|
|
23
|
+
version: str | None # package version if available
|
|
24
|
+
is_local: bool # True for relative imports (from .module import ...)
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
def _top_level(pkg: str) -> str:
|
|
28
|
+
"""Extract top-level package name."""
|
|
29
|
+
return pkg.split(".", 1)[0]
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
def _is_relative(module: str | None) -> bool:
|
|
33
|
+
"""Check if module is a relative import."""
|
|
34
|
+
return module is not None and module.startswith(".")
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
class _ImportVisitor(ast.NodeVisitor):
|
|
38
|
+
"""AST visitor to extract import information."""
|
|
39
|
+
|
|
40
|
+
def __init__(self):
|
|
41
|
+
self.results: list[DependencyInfo] = []
|
|
42
|
+
|
|
43
|
+
def visit_Import(self, node: ast.Import):
|
|
44
|
+
for alias in node.names:
|
|
45
|
+
full = alias.name
|
|
46
|
+
dep = DependencyInfo(
|
|
47
|
+
name=_top_level(full),
|
|
48
|
+
version=None,
|
|
49
|
+
is_local=False, # Regular imports are not local
|
|
50
|
+
)
|
|
51
|
+
self.results.append(dep)
|
|
52
|
+
|
|
53
|
+
def visit_ImportFrom(self, node: ast.ImportFrom):
|
|
54
|
+
# Reconstruct full module name with proper relative import handling
|
|
55
|
+
if node.level > 0:
|
|
56
|
+
# Relative import: from .module import x or from ..parent import x
|
|
57
|
+
dots = "." * node.level
|
|
58
|
+
full_module = dots + (node.module or "")
|
|
59
|
+
else:
|
|
60
|
+
# Absolute import: from module import x
|
|
61
|
+
full_module = node.module or ""
|
|
62
|
+
for _alias in node.names:
|
|
63
|
+
dep = DependencyInfo(
|
|
64
|
+
name=_top_level(full_module.lstrip(".")) if full_module else "",
|
|
65
|
+
version=None,
|
|
66
|
+
is_local=_is_relative(full_module), # Check if it's a relative import
|
|
67
|
+
)
|
|
68
|
+
self.results.append(dep)
|
|
69
|
+
|
|
70
|
+
|
|
71
|
+
def _classify_dependency(dep: DependencyInfo) -> DependencyInfo:
|
|
72
|
+
"""Resolve version information for external dependencies."""
|
|
73
|
+
version = None
|
|
74
|
+
if not dep.is_local and dep.name:
|
|
75
|
+
version = _get_distribution_version(dep.name)
|
|
76
|
+
|
|
77
|
+
return DependencyInfo(
|
|
78
|
+
name=dep.name,
|
|
79
|
+
version=version,
|
|
80
|
+
is_local=dep.is_local,
|
|
81
|
+
)
|
|
82
|
+
|
|
83
|
+
|
|
84
|
+
def analyze_dependencies(source: str, *, resolve_versions: bool = True) -> list[dict]:
|
|
85
|
+
"""Return a list[dict] of dependencies imported by the given Python source code.
|
|
86
|
+
|
|
87
|
+
Args:
|
|
88
|
+
source: Python source code string
|
|
89
|
+
resolve_versions: Whether to resolve version information
|
|
90
|
+
|
|
91
|
+
Returns:
|
|
92
|
+
List of dependency dictionaries
|
|
93
|
+
"""
|
|
94
|
+
code = source
|
|
95
|
+
|
|
96
|
+
# Parse the code and extract imports
|
|
97
|
+
tree = ast.parse(code)
|
|
98
|
+
visitor = _ImportVisitor()
|
|
99
|
+
visitor.visit(tree)
|
|
100
|
+
|
|
101
|
+
# Process and deduplicate dependencies by package name only
|
|
102
|
+
unique_packages: dict[str, DependencyInfo] = {}
|
|
103
|
+
for raw_dep in visitor.results:
|
|
104
|
+
processed_dep = _classify_dependency(raw_dep) if resolve_versions else raw_dep
|
|
105
|
+
|
|
106
|
+
# Skip stdlib imports and local imports - we only care about external dependencies
|
|
107
|
+
if processed_dep.name in STDLIB_MODULES or processed_dep.is_local:
|
|
108
|
+
continue
|
|
109
|
+
|
|
110
|
+
# Deduplicate by package name only (not full_module)
|
|
111
|
+
if processed_dep.name not in unique_packages:
|
|
112
|
+
unique_packages[processed_dep.name] = processed_dep
|
|
113
|
+
|
|
114
|
+
return [asdict(d) for d in unique_packages.values()]
|
|
115
|
+
|
|
116
|
+
|
|
117
|
+
def analyze_component_dependencies(component_code: str) -> dict:
|
|
118
|
+
"""Analyze dependencies for a custom component.
|
|
119
|
+
|
|
120
|
+
Args:
|
|
121
|
+
component_code: The component's source code
|
|
122
|
+
|
|
123
|
+
Returns:
|
|
124
|
+
Dictionary with dependency analysis results
|
|
125
|
+
"""
|
|
126
|
+
try:
|
|
127
|
+
deps = analyze_dependencies(component_code, resolve_versions=True)
|
|
128
|
+
|
|
129
|
+
return {
|
|
130
|
+
"total_dependencies": len(deps),
|
|
131
|
+
"dependencies": [{"name": d["name"], "version": d["version"]} for d in deps if d["name"]],
|
|
132
|
+
}
|
|
133
|
+
except (SyntaxError, TypeError, ValueError, ImportError):
|
|
134
|
+
# If analysis fails, return minimal info
|
|
135
|
+
return {
|
|
136
|
+
"total_dependencies": 0,
|
|
137
|
+
"dependencies": [],
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
|
|
141
|
+
# Cache the expensive packages_distributions() call globally
|
|
142
|
+
@lru_cache(maxsize=1)
|
|
143
|
+
def _get_packages_distributions():
|
|
144
|
+
"""Cache the expensive packages_distributions() call."""
|
|
145
|
+
try:
|
|
146
|
+
return md.packages_distributions()
|
|
147
|
+
except (OSError, AttributeError, ValueError):
|
|
148
|
+
return {}
|
|
149
|
+
|
|
150
|
+
|
|
151
|
+
# Helper function to cache version lookups for installed distributions
|
|
152
|
+
@lru_cache(maxsize=128)
|
|
153
|
+
def _get_distribution_version(import_name: str):
|
|
154
|
+
try:
|
|
155
|
+
# Reverse-lookup: which distribution(s) provide this importable name?
|
|
156
|
+
reverse_map = _get_packages_distributions()
|
|
157
|
+
dist_names = reverse_map.get(import_name)
|
|
158
|
+
if not dist_names:
|
|
159
|
+
return None
|
|
160
|
+
|
|
161
|
+
# Take the first matching distribution
|
|
162
|
+
dist_name = dist_names[0]
|
|
163
|
+
return md.distribution(dist_name).version
|
|
164
|
+
except (ImportError, AttributeError, OSError, ValueError):
|
|
165
|
+
return None
|
langflow/custom/utils.py
CHANGED
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
# mypy: ignore-errors
|
|
2
|
+
from __future__ import annotations
|
|
3
|
+
|
|
2
4
|
import ast
|
|
3
5
|
import asyncio
|
|
4
6
|
import contextlib
|
|
@@ -7,14 +9,13 @@ import inspect
|
|
|
7
9
|
import re
|
|
8
10
|
import traceback
|
|
9
11
|
from pathlib import Path
|
|
10
|
-
from typing import Any
|
|
11
|
-
from uuid import UUID
|
|
12
|
+
from typing import TYPE_CHECKING, Any
|
|
12
13
|
|
|
13
14
|
from fastapi import HTTPException
|
|
14
15
|
from pydantic import BaseModel
|
|
15
16
|
|
|
16
17
|
from langflow.custom.custom_component.component import Component
|
|
17
|
-
from langflow.custom.
|
|
18
|
+
from langflow.custom.dependency_analyzer import analyze_component_dependencies
|
|
18
19
|
from langflow.custom.directory_reader.utils import (
|
|
19
20
|
abuild_custom_component_list_from_path,
|
|
20
21
|
build_custom_component_list_from_path,
|
|
@@ -32,6 +33,11 @@ from langflow.type_extraction.type_extraction import extract_inner_type
|
|
|
32
33
|
from langflow.utils import validate
|
|
33
34
|
from langflow.utils.util import get_base_classes
|
|
34
35
|
|
|
36
|
+
if TYPE_CHECKING:
|
|
37
|
+
from uuid import UUID
|
|
38
|
+
|
|
39
|
+
from langflow.custom.custom_component.custom_component import CustomComponent
|
|
40
|
+
|
|
35
41
|
|
|
36
42
|
def _generate_code_hash(source_code: str, modname: str) -> str:
|
|
37
43
|
"""Generate a hash of the component source code.
|
|
@@ -488,6 +494,15 @@ def build_custom_component_template_from_inputs(
|
|
|
488
494
|
# ! This should be removed when we have a better way to handle this
|
|
489
495
|
frontend_node.set_base_classes_from_outputs()
|
|
490
496
|
reorder_fields(frontend_node, cc_instance._get_field_order())
|
|
497
|
+
frontend_node = build_component_metadata(frontend_node, cc_instance, module_name, ctype_name)
|
|
498
|
+
|
|
499
|
+
return frontend_node.to_dict(keep_name=False), cc_instance
|
|
500
|
+
|
|
501
|
+
|
|
502
|
+
def build_component_metadata(
|
|
503
|
+
frontend_node: CustomComponentFrontendNode, custom_component: CustomComponent, module_name: str, ctype_name: str
|
|
504
|
+
):
|
|
505
|
+
"""Build the metadata for a custom component."""
|
|
491
506
|
if module_name:
|
|
492
507
|
frontend_node.metadata["module"] = module_name
|
|
493
508
|
else:
|
|
@@ -502,7 +517,19 @@ def build_custom_component_template_from_inputs(
|
|
|
502
517
|
except Exception as exc: # noqa: BLE001
|
|
503
518
|
logger.debug(f"Error generating code hash for {custom_component.__class__.__name__}", exc_info=exc)
|
|
504
519
|
|
|
505
|
-
|
|
520
|
+
# Analyze component dependencies
|
|
521
|
+
try:
|
|
522
|
+
dependency_info = analyze_component_dependencies(custom_component._code)
|
|
523
|
+
frontend_node.metadata["dependencies"] = dependency_info
|
|
524
|
+
except (SyntaxError, TypeError, ValueError, ImportError) as exc:
|
|
525
|
+
logger.warning(f"Failed to analyze dependencies for component {ctype_name}: {exc}")
|
|
526
|
+
# Set minimal dependency info on failure
|
|
527
|
+
frontend_node.metadata["dependencies"] = {
|
|
528
|
+
"total_dependencies": 0,
|
|
529
|
+
"dependencies": [],
|
|
530
|
+
}
|
|
531
|
+
|
|
532
|
+
return frontend_node
|
|
506
533
|
|
|
507
534
|
|
|
508
535
|
def build_custom_component_template(
|
|
@@ -562,18 +589,9 @@ def build_custom_component_template(
|
|
|
562
589
|
reorder_fields(frontend_node, custom_instance._get_field_order())
|
|
563
590
|
|
|
564
591
|
if module_name:
|
|
565
|
-
frontend_node
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
frontend_node.metadata["module"] = f"custom_components.{module_name}"
|
|
569
|
-
|
|
570
|
-
# Generate code hash for cache invalidation and debugging
|
|
571
|
-
try:
|
|
572
|
-
code_hash = _generate_code_hash(custom_component._code, module_name)
|
|
573
|
-
if code_hash:
|
|
574
|
-
frontend_node.metadata["code_hash"] = code_hash
|
|
575
|
-
except Exception as exc: # noqa: BLE001
|
|
576
|
-
logger.debug(f"Error generating code hash for {custom_component.__class__.__name__}", exc_info=exc)
|
|
592
|
+
frontend_node = build_component_metadata(
|
|
593
|
+
frontend_node, custom_component, module_name, custom_component.__class__.__name__
|
|
594
|
+
)
|
|
577
595
|
|
|
578
596
|
return frontend_node.to_dict(keep_name=False), custom_instance
|
|
579
597
|
except Exception as exc:
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{j as a}from"./index-
|
|
1
|
+
import{j as a}from"./index-BpxbUiZD.js";const s=l=>a.jsx("svg",{xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 54 54",width:"1em",height:"1em",...l,children:a.jsxs("g",{fill:"none",fillRule:"evenodd",children:[a.jsx("path",{fill:"#36C5F0",d:"M19.712.133a5.381 5.381 0 0 0-5.376 5.387 5.381 5.381 0 0 0 5.376 5.386h5.376V5.52A5.381 5.381 0 0 0 19.712.133m0 14.365H5.376A5.381 5.381 0 0 0 0 19.884a5.381 5.381 0 0 0 5.376 5.387h14.336a5.381 5.381 0 0 0 5.376-5.387 5.381 5.381 0 0 0-5.376-5.386"}),a.jsx("path",{fill:"#2EB67D",d:"M53.76 19.884a5.381 5.381 0 0 0-5.376-5.386 5.381 5.381 0 0 0-5.376 5.386v5.387h5.376a5.381 5.381 0 0 0 5.376-5.387m-14.336 0V5.52A5.381 5.381 0 0 0 34.048.133a5.381 5.381 0 0 0-5.376 5.387v14.364a5.381 5.381 0 0 0 5.376 5.387 5.381 5.381 0 0 0 5.376-5.387"}),a.jsx("path",{fill:"#ECB22E",d:"M34.048 54a5.381 5.381 0 0 0 5.376-5.387 5.381 5.381 0 0 0-5.376-5.386h-5.376v5.386A5.381 5.381 0 0 0 34.048 54m0-14.365h14.336a5.381 5.381 0 0 0 5.376-5.386 5.381 5.381 0 0 0-5.376-5.387H34.048a5.381 5.381 0 0 0-5.376 5.387 5.381 5.381 0 0 0 5.376 5.386"}),a.jsx("path",{fill:"#E01E5A",d:"M0 34.249a5.381 5.381 0 0 0 5.376 5.386 5.381 5.381 0 0 0 5.376-5.386v-5.387H5.376A5.381 5.381 0 0 0 0 34.25m14.336-.001v14.364A5.381 5.381 0 0 0 19.712 54a5.381 5.381 0 0 0 5.376-5.387V34.25a5.381 5.381 0 0 0-5.376-5.387 5.381 5.381 0 0 0-5.376 5.387"})]})});export{s as default};
|