Try   HackMD

How to build your Custom Component on LangFlow

Step0: before getting started…

you need poetryhttps://blog.kyomind.tw/python-poetry/

💡 Poetry: Dependency Management for Python
Poetry helps you declare, manage and install dependencies of Python projects

Step1: READ CONTRIBUTING.md

CONTRIBUTING.md

use makefile to build the project

backend:
	make install_backend
ifeq ($(login),1)
	@echo "Running backend without autologin";
	poetry run langflow run --backend-only --port 7860 --host 0.0.0.0 --no-open-browser **--components-path src/backend/langflow/custom_components**
else
	@echo "Running backend with autologin";
	LANGFLOW_AUTO_LOGIN=True poetry run langflow run --backend-only --port 7860 --host 0.0.0.0 --no-open-browser **--components-path src/backend/langflow/custom_components**
endif

Step2: Understand the folder structure

╭─ .../langflow/sr/backend 
.
├── Dockerfile
└── langflow
    ├── __init__.py
    ├── __main__.py
    ├── alembic
    ├── alembic.ini
    ├── api
    **├── components
    │   ├── __init__.py
    │   ├── agents
    │   │   ├── OpenAIConversationalAgent.py
    │   │   └── __init__.py
    │   ├── chains
    │   │   ├── PromptRunner.py
    │   │   └── __init__.py
    │   ├── embeddings
    │   │   ├── AmazonBedrockEmbeddings.py
    │   │   └── __init__.py
    │   ├── llms
    │   │   ├── AmazonBedrock.py
    │   │   ├── BaiduQianfanChatEndpoints.py
    │   │   ├── BaiduQianfanLLMEndpoints.py
    │   │   ├── HuggingFaceEndpoints.py
    │   │   └── __init__.py
    │   ├── retrievers
    │   │   ├── AmazonKendra.py
    │   │   ├── MetalRetriever.py
    │   │   └── __init__.py
    │   ├── textsplitters
    │   │   ├── LanguageRecursiveTextSplitter.py
    │   │   ├── RecursiveCharacterTextSplitter.py
    │   │   └── __init__.py
    │   ├── toolkits
    │   │   ├── Metaphor.py
    │   │   └── __init__.py
    │   ├── utilities
    │   │   ├── GetRequest.py
    │   │   ├── JSONDocumentBuilder.py
    │   │   ├── PostRequest.py
    │   │   └── UpdateRequest.py
    │   └── vectorstores        
    │       ├── Chroma.py       <-------------- Chroma as example
    │       ├── Vectara.py
    │       ├── __init__.py
    │       └── pgvector.py**
    ├── **MY_CUSTOM_COMPONENTS.   <-------------- Where you should put your code
		...**

Step3: Happy Coding

architecture

from typing import Optional
from langflow import CustomComponent

from langchain.vectorstores.pgvector import PGVector
from langchain.schema import Document
from langchain.vectorstores.base import VectorStore
from langchain.embeddings.base import Embeddings

class PostgresqlVectorComponent(CustomComponent):
    def build_config(self):
				pass

    def build(
        self,
        embedding: Embeddings,
        pg_server_url: str,
        collection_name: str,
        documents: Optional[Document] = None,
    ) -> VectorStore:
				pass

Example:

from typing import Optional
from langflow import CustomComponent

from langchain.vectorstores.pgvector import PGVector
from langchain.schema import Document
from langchain.vectorstores.base import VectorStore
from langchain.embeddings.base import Embeddings

class PostgresqlVectorComponent(CustomComponent):
    """
    A custom component for implementing a Vector Store using PostgreSQL.
    """

    display_name: str = "PostgreSQL Vector Store"
    description: str = "Implementation of Vector Store using PostgreSQL"
    documentation = "https://python.langchain.com/docs/integrations/vectorstores/pgvector"
    beta = True

    def build_config(self):
        """
        Builds the configuration for the component.

        Returns:
        - dict: A dictionary containing the configuration options for the component.
        """
        return {
            "index_name": {"display_name": "Index Name", "value": "your_index"},
            "code": {"show": True, "display_name": "Code"},
            "documents": {"display_name": "Documents", "is_list": True},
            "embedding": {"display_name": "Embedding"},
            "pg_server_url": {
                "display_name": "PostgreSQL Server Connection String",
                "advanced": False,
            },
            "collection_name": {"display_name": "Table", "advanced": False},
        }

    def build(
        self,
        embedding: Embeddings,
        pg_server_url: str,
        collection_name: str,
        documents: Optional[Document] = None,
    ) -> **VectorStore**:
        """
        Builds the Vector Store or BaseRetriever object.

        Args:
        - embedding (Embeddings): The embeddings to use for the Vector Store.
        - documents (Optional[Document]): The documents to use for the Vector Store.
        - collection_name (str): The name of the PG table.
        - pg_server_url (str): The URL for the PG server.

        Returns:
        - VectorStore: The Vector Store object.
        """

        return PGVector.from_documents(
            embedding=embedding,
            documents=documents,
            collection_name=collection_name,
            connection_string=pg_server_url,
        )

PG as an example

  1. LangChain PG Doc : https://python.langchain.com/docs/integrations/vectorstores/pgvector
  2. PG Client Doc : https://github.com/pgvector/pgvector-python
  3. PG Vector Doc : https://github.com/pgvector/pgvector

Step4: Load Custom Compoents

https://docs.langflow.org/guidelines/custom-component#loading-custom-components

My practice : use makefile to build the project

backend:
	make install_backend
ifeq ($(login),1)
	@echo "Running backend without autologin";
	poetry run langflow run --backend-only --port 7860 --host 0.0.0.0 --no-open-browser **--components-path src/backend/langflow/custom_components**
else
	@echo "Running backend with autologin";
	LANGFLOW_AUTO_LOGIN=True poetry run langflow run --backend-only --port 7860 --host 0.0.0.0 --no-open-browser **--components-path src/backend/langflow/custom_components**
endif