langflow-ai / langflow

⛓️ Langflow is a visual framework for building multi-agent and RAG applications. It's open-source, Python-powered, fully customizable, model and vector store agnostic.
http://www.langflow.org
MIT License
19.8k stars 2.94k forks source link

RC1 : Python API : Circular API import #2308

Closed Arron-Clague closed 1 day ago

Arron-Clague commented 5 days ago

Hi there :

Im using the 1.0.0.RC1 build : if I make a call to send a message I get :

2024-06-24 14:17:20 - Error running graph: Error building Component Empty Prompt:

cannot import name 'process_prompt_template' from partially initialized module 'langflow.base.prompts.api_utils' (most likely due to a circular import) (/home/koni/.local/lib/python3.10/site-packages/langflow/base/prompts/api_utils.py)

Thanks,

Arron

dosubot[bot] commented 5 days ago

To resolve the circular import issue when calling send a message using the 1.0.0.RC1 build of the Python API, you can use the __getattr__ function to lazily import the necessary classes. This approach is already implemented in the provided code to avoid circular imports.

Here's the relevant part of the code that handles this:

from typing import Any

from .constants import (
    AgentExecutor,
    BaseChatMemory,
    BaseLanguageModel,
    BaseLLM,
    BaseLoader,
    BaseMemory,
    BaseOutputParser,
    BasePromptTemplate,
    BaseRetriever,
    Callable,
    Chain,
    ChatPromptTemplate,
    Data,
    Document,
    Embeddings,
    NestedDict,
    Object,
    Prompt,
    PromptTemplate,
    TextSplitter,
    Tool,
    VectorStore,
)
from .range_spec import RangeSpec

def _import_template_field():
    from langflow.template.field.base import TemplateField

    return TemplateField

def __getattr__(name: str) -> Any:
    # This is to avoid circular imports
    if name == "TemplateField":
        return _import_template_field()
    elif name == "RangeSpec":
        return RangeSpec
    # The other names should work as if they were imported from constants
    # Import the constants module langflow.field_typing.constants
    from . import constants

    return getattr(constants, name)

__all__ = [
    "NestedDict",
    "Data",
    "Tool",
    "PromptTemplate",
    "Chain",
    "BaseChatMemory",
    "BaseLLM",
    "BaseLanguageModel",
    "BaseLoader",
    "BaseMemory",
    "BaseOutputParser",
    "BaseRetriever",
    "VectorStore",
    "Embeddings",
    "TextSplitter",
    "Document",
    "AgentExecutor",
    "Object",
    "Callable",
    "BasePromptTemplate",
    "ChatPromptTemplate",
    "Prompt",
    "RangeSpec",
    "TemplateField",
]

This code ensures that the TemplateField and RangeSpec classes are only imported when they are actually accessed, thus preventing circular import issues [1][2].

To continue talking to Dosu, mention @dosu.

nicoloboschi commented 1 day ago

This has been fixed in the latest releases. 1.0.5 doesn't have the problem