mirror of
https://github.com/hwchase17/langchain.git
synced 2025-06-22 14:49:29 +00:00
core[performance]: use custom __getattr__
in __init__.py
files for lazy imports (#30769)
Most easily reviewed with the "hide whitespace" option toggled. Seeing 10-50% speed ups in import time for common structures 🚀 The general purpose of this PR is to lazily import structures within `langchain_core.XXX_module.__init__.py` so that we're not eagerly importing expensive dependencies (`pydantic`, `requests`, etc). Analysis of flamegraphs generated with `importtime` motivated these changes. For example, the one below demonstrates that importing `HumanMessage` accidentally triggered imports for `importlib.metadata`, `requests`, etc. There's still much more to do on this front, and we can start digging into our own internal code for optimizations now that we're less concerned about external imports. <img width="1210" alt="Screenshot 2025-04-11 at 1 10 54 PM" src="https://github.com/user-attachments/assets/112a3fe7-24a9-4294-92c1-d5ae64df839e" /> I've tracked the improvements with some local benchmarks: ## `pytest-benchmark` results | Name | Before (s) | After (s) | Delta (s) | % Change | |-----------------------------|------------|-----------|-----------|----------| | Document | 2.8683 | 1.2775 | -1.5908 | -55.46% | | HumanMessage | 2.2358 | 1.1673 | -1.0685 | -47.79% | | ChatPromptTemplate | 5.5235 | 2.9709 | -2.5526 | -46.22% | | Runnable | 2.9423 | 1.7793 | -1.163 | -39.53% | | InMemoryVectorStore | 3.1180 | 1.8417 | -1.2763 | -40.93% | | RunnableLambda | 2.7385 | 1.8745 | -0.864 | -31.55% | | tool | 5.1231 | 4.0771 | -1.046 | -20.42% | | CallbackManager | 4.2263 | 3.4099 | -0.8164 | -19.32% | | LangChainTracer | 3.8394 | 3.3101 | -0.5293 | -13.79% | | BaseChatModel | 4.3317 | 3.8806 | -0.4511 | -10.41% | | PydanticOutputParser | 3.2036 | 3.2995 | 0.0959 | 2.99% | | InMemoryRateLimiter | 0.5311 | 0.5995 | 0.0684 | 12.88% | Note the lack of change for `InMemoryRateLimiter` and `PydanticOutputParser` is just random noise, I'm getting comparable numbers locally. ## Local CodSpeed results We're still working on configuring CodSpeed on CI. The local usage produced similar results.
This commit is contained in:
parent
ada740b5b9
commit
4f69094b51
@ -9,6 +9,10 @@ This module is only relevant for LangChain developers, not for users.
|
||||
|
||||
"""
|
||||
|
||||
from importlib import import_module
|
||||
from typing import TYPE_CHECKING
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from .beta_decorator import (
|
||||
LangChainBetaWarning,
|
||||
beta,
|
||||
@ -37,3 +41,33 @@ __all__ = [
|
||||
"surface_langchain_deprecation_warnings",
|
||||
"warn_deprecated",
|
||||
]
|
||||
|
||||
_dynamic_imports = {
|
||||
"LangChainBetaWarning": "beta_decorator",
|
||||
"beta": "beta_decorator",
|
||||
"suppress_langchain_beta_warning": "beta_decorator",
|
||||
"surface_langchain_beta_warnings": "beta_decorator",
|
||||
"as_import_path": "path",
|
||||
"get_relative_path": "path",
|
||||
"LangChainDeprecationWarning": "deprecation",
|
||||
"deprecated": "deprecation",
|
||||
"surface_langchain_deprecation_warnings": "deprecation",
|
||||
"suppress_langchain_deprecation_warning": "deprecation",
|
||||
"warn_deprecated": "deprecation",
|
||||
}
|
||||
|
||||
|
||||
def __getattr__(attr_name: str) -> object:
|
||||
module_name = _dynamic_imports.get(attr_name)
|
||||
package = __spec__.parent # type: ignore[name-defined]
|
||||
if module_name == "__module__" or module_name is None:
|
||||
result = import_module(f".{attr_name}", package=package)
|
||||
else:
|
||||
module = import_module(f".{module_name}", package=package)
|
||||
result = getattr(module, attr_name)
|
||||
globals()[attr_name] = result
|
||||
return result
|
||||
|
||||
|
||||
def __dir__() -> list[str]:
|
||||
return list(__all__)
|
||||
|
@ -7,6 +7,10 @@
|
||||
BaseCallbackHandler --> <name>CallbackHandler # Example: AimCallbackHandler
|
||||
"""
|
||||
|
||||
from importlib import import_module
|
||||
from typing import TYPE_CHECKING
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from langchain_core.callbacks.base import (
|
||||
AsyncCallbackHandler,
|
||||
BaseCallbackHandler,
|
||||
@ -84,3 +88,56 @@ __all__ = [
|
||||
"UsageMetadataCallbackHandler",
|
||||
"get_usage_metadata_callback",
|
||||
]
|
||||
|
||||
_dynamic_imports = {
|
||||
"AsyncCallbackHandler": "base",
|
||||
"BaseCallbackHandler": "base",
|
||||
"BaseCallbackManager": "base",
|
||||
"CallbackManagerMixin": "base",
|
||||
"Callbacks": "base",
|
||||
"ChainManagerMixin": "base",
|
||||
"LLMManagerMixin": "base",
|
||||
"RetrieverManagerMixin": "base",
|
||||
"RunManagerMixin": "base",
|
||||
"ToolManagerMixin": "base",
|
||||
"FileCallbackHandler": "file",
|
||||
"AsyncCallbackManager": "manager",
|
||||
"AsyncCallbackManagerForChainGroup": "manager",
|
||||
"AsyncCallbackManagerForChainRun": "manager",
|
||||
"AsyncCallbackManagerForLLMRun": "manager",
|
||||
"AsyncCallbackManagerForRetrieverRun": "manager",
|
||||
"AsyncCallbackManagerForToolRun": "manager",
|
||||
"AsyncParentRunManager": "manager",
|
||||
"AsyncRunManager": "manager",
|
||||
"BaseRunManager": "manager",
|
||||
"CallbackManager": "manager",
|
||||
"CallbackManagerForChainGroup": "manager",
|
||||
"CallbackManagerForChainRun": "manager",
|
||||
"CallbackManagerForLLMRun": "manager",
|
||||
"CallbackManagerForRetrieverRun": "manager",
|
||||
"CallbackManagerForToolRun": "manager",
|
||||
"ParentRunManager": "manager",
|
||||
"RunManager": "manager",
|
||||
"adispatch_custom_event": "manager",
|
||||
"dispatch_custom_event": "manager",
|
||||
"StdOutCallbackHandler": "stdout",
|
||||
"StreamingStdOutCallbackHandler": "streaming_stdout",
|
||||
"UsageMetadataCallbackHandler": "usage",
|
||||
"get_usage_metadata_callback": "usage",
|
||||
}
|
||||
|
||||
|
||||
def __getattr__(attr_name: str) -> object:
|
||||
module_name = _dynamic_imports.get(attr_name)
|
||||
package = __spec__.parent # type: ignore[name-defined]
|
||||
if module_name == "__module__" or module_name is None:
|
||||
result = import_module(f".{attr_name}", package=package)
|
||||
else:
|
||||
module = import_module(f".{module_name}", package=package)
|
||||
result = getattr(module, attr_name)
|
||||
globals()[attr_name] = result
|
||||
return result
|
||||
|
||||
|
||||
def __dir__() -> list[str]:
|
||||
return list(__all__)
|
||||
|
@ -1,5 +1,9 @@
|
||||
"""Document loaders."""
|
||||
|
||||
from importlib import import_module
|
||||
from typing import TYPE_CHECKING
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from langchain_core.document_loaders.base import BaseBlobParser, BaseLoader
|
||||
from langchain_core.document_loaders.blob_loaders import Blob, BlobLoader, PathLike
|
||||
from langchain_core.document_loaders.langsmith import LangSmithLoader
|
||||
@ -12,3 +16,28 @@ __all__ = [
|
||||
"PathLike",
|
||||
"LangSmithLoader",
|
||||
]
|
||||
|
||||
_dynamic_imports = {
|
||||
"BaseBlobParser": "base",
|
||||
"BaseLoader": "base",
|
||||
"Blob": "blob_loaders",
|
||||
"BlobLoader": "blob_loaders",
|
||||
"PathLike": "blob_loaders",
|
||||
"LangSmithLoader": "langsmith",
|
||||
}
|
||||
|
||||
|
||||
def __getattr__(attr_name: str) -> object:
|
||||
module_name = _dynamic_imports.get(attr_name)
|
||||
package = __spec__.parent # type: ignore[name-defined]
|
||||
if module_name == "__module__" or module_name is None:
|
||||
result = import_module(f".{attr_name}", package=package)
|
||||
else:
|
||||
module = import_module(f".{module_name}", package=package)
|
||||
result = getattr(module, attr_name)
|
||||
globals()[attr_name] = result
|
||||
return result
|
||||
|
||||
|
||||
def __dir__() -> list[str]:
|
||||
return list(__all__)
|
||||
|
@ -5,8 +5,34 @@ and their transformations.
|
||||
|
||||
"""
|
||||
|
||||
from langchain_core.documents.base import Document
|
||||
from langchain_core.documents.compressor import BaseDocumentCompressor
|
||||
from langchain_core.documents.transformers import BaseDocumentTransformer
|
||||
from importlib import import_module
|
||||
from typing import TYPE_CHECKING
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from .base import Document
|
||||
from .compressor import BaseDocumentCompressor
|
||||
from .transformers import BaseDocumentTransformer
|
||||
|
||||
__all__ = ["Document", "BaseDocumentTransformer", "BaseDocumentCompressor"]
|
||||
|
||||
_dynamic_imports = {
|
||||
"Document": "base",
|
||||
"BaseDocumentCompressor": "compressor",
|
||||
"BaseDocumentTransformer": "transformers",
|
||||
}
|
||||
|
||||
|
||||
def __getattr__(attr_name: str) -> object:
|
||||
module_name = _dynamic_imports.get(attr_name)
|
||||
package = __spec__.parent # type: ignore[name-defined]
|
||||
if module_name == "__module__" or module_name is None:
|
||||
result = import_module(f".{attr_name}", package=package)
|
||||
else:
|
||||
module = import_module(f".{module_name}", package=package)
|
||||
result = getattr(module, attr_name)
|
||||
globals()[attr_name] = result
|
||||
return result
|
||||
|
||||
|
||||
def __dir__() -> list[str]:
|
||||
return list(__all__)
|
||||
|
@ -1,6 +1,35 @@
|
||||
"""Embeddings."""
|
||||
|
||||
from importlib import import_module
|
||||
from typing import TYPE_CHECKING
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from langchain_core.embeddings.embeddings import Embeddings
|
||||
from langchain_core.embeddings.fake import DeterministicFakeEmbedding, FakeEmbeddings
|
||||
from langchain_core.embeddings.fake import (
|
||||
DeterministicFakeEmbedding,
|
||||
FakeEmbeddings,
|
||||
)
|
||||
|
||||
__all__ = ["DeterministicFakeEmbedding", "Embeddings", "FakeEmbeddings"]
|
||||
|
||||
_dynamic_imports = {
|
||||
"Embeddings": "embeddings",
|
||||
"DeterministicFakeEmbedding": "fake",
|
||||
"FakeEmbeddings": "fake",
|
||||
}
|
||||
|
||||
|
||||
def __getattr__(attr_name: str) -> object:
|
||||
module_name = _dynamic_imports.get(attr_name)
|
||||
package = __spec__.parent # type: ignore[name-defined]
|
||||
if module_name == "__module__" or module_name is None:
|
||||
result = import_module(f".{attr_name}", package=package)
|
||||
else:
|
||||
module = import_module(f".{module_name}", package=package)
|
||||
result = getattr(module, attr_name)
|
||||
globals()[attr_name] = result
|
||||
return result
|
||||
|
||||
|
||||
def __dir__() -> list[str]:
|
||||
return list(__all__)
|
||||
|
@ -4,6 +4,10 @@
|
||||
This allows us to select examples that are most relevant to the input.
|
||||
"""
|
||||
|
||||
from importlib import import_module
|
||||
from typing import TYPE_CHECKING
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from langchain_core.example_selectors.base import BaseExampleSelector
|
||||
from langchain_core.example_selectors.length_based import (
|
||||
LengthBasedExampleSelector,
|
||||
@ -21,3 +25,27 @@ __all__ = [
|
||||
"SemanticSimilarityExampleSelector",
|
||||
"sorted_values",
|
||||
]
|
||||
|
||||
_dynamic_imports = {
|
||||
"BaseExampleSelector": "base",
|
||||
"LengthBasedExampleSelector": "length_based",
|
||||
"MaxMarginalRelevanceExampleSelector": "semantic_similarity",
|
||||
"SemanticSimilarityExampleSelector": "semantic_similarity",
|
||||
"sorted_values": "semantic_similarity",
|
||||
}
|
||||
|
||||
|
||||
def __getattr__(attr_name: str) -> object:
|
||||
module_name = _dynamic_imports.get(attr_name)
|
||||
package = __spec__.parent # type: ignore[name-defined]
|
||||
if module_name == "__module__" or module_name is None:
|
||||
result = import_module(f".{attr_name}", package=package)
|
||||
else:
|
||||
module = import_module(f".{module_name}", package=package)
|
||||
result = getattr(module, attr_name)
|
||||
globals()[attr_name] = result
|
||||
return result
|
||||
|
||||
|
||||
def __dir__() -> list[str]:
|
||||
return list(__all__)
|
||||
|
@ -5,6 +5,10 @@ a vectorstore while avoiding duplicated content and over-writing content
|
||||
if it's unchanged.
|
||||
"""
|
||||
|
||||
from importlib import import_module
|
||||
from typing import TYPE_CHECKING
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from langchain_core.indexing.api import IndexingResult, aindex, index
|
||||
from langchain_core.indexing.base import (
|
||||
DeleteResponse,
|
||||
@ -24,3 +28,30 @@ __all__ = [
|
||||
"RecordManager",
|
||||
"UpsertResponse",
|
||||
]
|
||||
|
||||
_dynamic_imports = {
|
||||
"aindex": "api",
|
||||
"index": "api",
|
||||
"IndexingResult": "api",
|
||||
"DeleteResponse": "base",
|
||||
"DocumentIndex": "base",
|
||||
"InMemoryRecordManager": "base",
|
||||
"RecordManager": "base",
|
||||
"UpsertResponse": "base",
|
||||
}
|
||||
|
||||
|
||||
def __getattr__(attr_name: str) -> object:
|
||||
module_name = _dynamic_imports.get(attr_name)
|
||||
package = __spec__.parent # type: ignore[name-defined]
|
||||
if module_name == "__module__" or module_name is None:
|
||||
result = import_module(f".{attr_name}", package=package)
|
||||
else:
|
||||
module = import_module(f".{module_name}", package=package)
|
||||
result = getattr(module, attr_name)
|
||||
globals()[attr_name] = result
|
||||
return result
|
||||
|
||||
|
||||
def __dir__() -> list[str]:
|
||||
return list(__all__)
|
||||
|
@ -41,6 +41,10 @@ https://python.langchain.com/docs/how_to/custom_llm/
|
||||
|
||||
""" # noqa: E501
|
||||
|
||||
from importlib import import_module
|
||||
from typing import TYPE_CHECKING
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from langchain_core.language_models.base import (
|
||||
BaseLanguageModel,
|
||||
LangSmithParams,
|
||||
@ -49,7 +53,10 @@ from langchain_core.language_models.base import (
|
||||
LanguageModelOutput,
|
||||
get_tokenizer,
|
||||
)
|
||||
from langchain_core.language_models.chat_models import BaseChatModel, SimpleChatModel
|
||||
from langchain_core.language_models.chat_models import (
|
||||
BaseChatModel,
|
||||
SimpleChatModel,
|
||||
)
|
||||
from langchain_core.language_models.fake import FakeListLLM, FakeStreamingListLLM
|
||||
from langchain_core.language_models.fake_chat_models import (
|
||||
FakeListChatModel,
|
||||
@ -77,3 +84,38 @@ __all__ = [
|
||||
"GenericFakeChatModel",
|
||||
"ParrotFakeChatModel",
|
||||
]
|
||||
|
||||
_dynamic_imports = {
|
||||
"BaseLanguageModel": "base",
|
||||
"LangSmithParams": "base",
|
||||
"LanguageModelInput": "base",
|
||||
"LanguageModelLike": "base",
|
||||
"LanguageModelOutput": "base",
|
||||
"get_tokenizer": "base",
|
||||
"BaseChatModel": "chat_models",
|
||||
"SimpleChatModel": "chat_models",
|
||||
"FakeListLLM": "fake",
|
||||
"FakeStreamingListLLM": "fake",
|
||||
"FakeListChatModel": "fake_chat_models",
|
||||
"FakeMessagesListChatModel": "fake_chat_models",
|
||||
"GenericFakeChatModel": "fake_chat_models",
|
||||
"ParrotFakeChatModel": "fake_chat_models",
|
||||
"LLM": "llms",
|
||||
"BaseLLM": "llms",
|
||||
}
|
||||
|
||||
|
||||
def __getattr__(attr_name: str) -> object:
|
||||
module_name = _dynamic_imports.get(attr_name)
|
||||
package = __spec__.parent # type: ignore[name-defined]
|
||||
if module_name == "__module__" or module_name is None:
|
||||
result = import_module(f".{attr_name}", package=package)
|
||||
else:
|
||||
module = import_module(f".{module_name}", package=package)
|
||||
result = getattr(module, attr_name)
|
||||
globals()[attr_name] = result
|
||||
return result
|
||||
|
||||
|
||||
def __dir__() -> list[str]:
|
||||
return list(__all__)
|
||||
|
@ -1,7 +1,35 @@
|
||||
"""**Load** module helps with serialization and deserialization."""
|
||||
|
||||
from importlib import import_module
|
||||
from typing import TYPE_CHECKING
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from langchain_core.load.dump import dumpd, dumps
|
||||
from langchain_core.load.load import load, loads
|
||||
from langchain_core.load.serializable import Serializable
|
||||
|
||||
__all__ = ["dumpd", "dumps", "load", "loads", "Serializable"]
|
||||
|
||||
_dynamic_imports = {
|
||||
"dumpd": "dump",
|
||||
"dumps": "dump",
|
||||
"load": "load",
|
||||
"loads": "load",
|
||||
"Serializable": "serializable",
|
||||
}
|
||||
|
||||
|
||||
def __getattr__(attr_name: str) -> object:
|
||||
module_name = _dynamic_imports.get(attr_name)
|
||||
package = __spec__.parent # type: ignore[name-defined]
|
||||
if module_name == "__module__" or module_name is None:
|
||||
result = import_module(f".{attr_name}", package=package)
|
||||
else:
|
||||
module = import_module(f".{module_name}", package=package)
|
||||
result = getattr(module, attr_name)
|
||||
globals()[attr_name] = result
|
||||
return result
|
||||
|
||||
|
||||
def __dir__() -> list[str]:
|
||||
return list(__all__)
|
||||
|
@ -15,6 +15,10 @@
|
||||
|
||||
""" # noqa: E501
|
||||
|
||||
from importlib import import_module
|
||||
from typing import TYPE_CHECKING
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from langchain_core.messages.ai import (
|
||||
AIMessage,
|
||||
AIMessageChunk,
|
||||
@ -86,3 +90,54 @@ __all__ = [
|
||||
"trim_messages",
|
||||
"convert_to_openai_messages",
|
||||
]
|
||||
|
||||
_dynamic_imports = {
|
||||
"AIMessage": "ai",
|
||||
"AIMessageChunk": "ai",
|
||||
"BaseMessage": "base",
|
||||
"BaseMessageChunk": "base",
|
||||
"merge_content": "base",
|
||||
"message_to_dict": "base",
|
||||
"messages_to_dict": "base",
|
||||
"ChatMessage": "chat",
|
||||
"ChatMessageChunk": "chat",
|
||||
"FunctionMessage": "function",
|
||||
"FunctionMessageChunk": "function",
|
||||
"HumanMessage": "human",
|
||||
"HumanMessageChunk": "human",
|
||||
"RemoveMessage": "modifier",
|
||||
"SystemMessage": "system",
|
||||
"SystemMessageChunk": "system",
|
||||
"InvalidToolCall": "tool",
|
||||
"ToolCall": "tool",
|
||||
"ToolCallChunk": "tool",
|
||||
"ToolMessage": "tool",
|
||||
"ToolMessageChunk": "tool",
|
||||
"AnyMessage": "utils",
|
||||
"MessageLikeRepresentation": "utils",
|
||||
"_message_from_dict": "utils",
|
||||
"convert_to_messages": "utils",
|
||||
"convert_to_openai_messages": "utils",
|
||||
"filter_messages": "utils",
|
||||
"get_buffer_string": "utils",
|
||||
"merge_message_runs": "utils",
|
||||
"message_chunk_to_message": "utils",
|
||||
"messages_from_dict": "utils",
|
||||
"trim_messages": "utils",
|
||||
}
|
||||
|
||||
|
||||
def __getattr__(attr_name: str) -> object:
|
||||
module_name = _dynamic_imports.get(attr_name)
|
||||
package = __spec__.parent # type: ignore[name-defined]
|
||||
if module_name == "__module__" or module_name is None:
|
||||
result = import_module(f".{attr_name}", package=package)
|
||||
else:
|
||||
module = import_module(f".{module_name}", package=package)
|
||||
result = getattr(module, attr_name)
|
||||
globals()[attr_name] = result
|
||||
return result
|
||||
|
||||
|
||||
def __dir__() -> list[str]:
|
||||
return list(__all__)
|
||||
|
@ -13,12 +13,19 @@
|
||||
Serializable, Generation, PromptValue
|
||||
""" # noqa: E501
|
||||
|
||||
from importlib import import_module
|
||||
from typing import TYPE_CHECKING
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from langchain_core.output_parsers.base import (
|
||||
BaseGenerationOutputParser,
|
||||
BaseLLMOutputParser,
|
||||
BaseOutputParser,
|
||||
)
|
||||
from langchain_core.output_parsers.json import JsonOutputParser, SimpleJsonOutputParser
|
||||
from langchain_core.output_parsers.json import (
|
||||
JsonOutputParser,
|
||||
SimpleJsonOutputParser,
|
||||
)
|
||||
from langchain_core.output_parsers.list import (
|
||||
CommaSeparatedListOutputParser,
|
||||
ListOutputParser,
|
||||
@ -57,3 +64,39 @@ __all__ = [
|
||||
"JsonOutputKeyToolsParser",
|
||||
"PydanticToolsParser",
|
||||
]
|
||||
|
||||
_dynamic_imports = {
|
||||
"BaseLLMOutputParser": "base",
|
||||
"BaseGenerationOutputParser": "base",
|
||||
"BaseOutputParser": "base",
|
||||
"JsonOutputParser": "json",
|
||||
"SimpleJsonOutputParser": "json",
|
||||
"ListOutputParser": "list",
|
||||
"CommaSeparatedListOutputParser": "list",
|
||||
"MarkdownListOutputParser": "list",
|
||||
"NumberedListOutputParser": "list",
|
||||
"JsonOutputKeyToolsParser": "openai_tools",
|
||||
"JsonOutputToolsParser": "openai_tools",
|
||||
"PydanticToolsParser": "openai_tools",
|
||||
"PydanticOutputParser": "pydantic",
|
||||
"StrOutputParser": "string",
|
||||
"BaseTransformOutputParser": "transform",
|
||||
"BaseCumulativeTransformOutputParser": "transform",
|
||||
"XMLOutputParser": "xml",
|
||||
}
|
||||
|
||||
|
||||
def __getattr__(attr_name: str) -> object:
|
||||
module_name = _dynamic_imports.get(attr_name)
|
||||
package = __spec__.parent # type: ignore[name-defined]
|
||||
if module_name == "__module__" or module_name is None:
|
||||
result = import_module(f".{attr_name}", package=package)
|
||||
else:
|
||||
module = import_module(f".{module_name}", package=package)
|
||||
result = getattr(module, attr_name)
|
||||
globals()[attr_name] = result
|
||||
return result
|
||||
|
||||
|
||||
def __dir__() -> list[str]:
|
||||
return list(__all__)
|
||||
|
@ -21,7 +21,14 @@ in the AIMessage object, it is recommended to access it from there rather than
|
||||
from the `LLMResult` object.
|
||||
"""
|
||||
|
||||
from langchain_core.outputs.chat_generation import ChatGeneration, ChatGenerationChunk
|
||||
from importlib import import_module
|
||||
from typing import TYPE_CHECKING
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from langchain_core.outputs.chat_generation import (
|
||||
ChatGeneration,
|
||||
ChatGenerationChunk,
|
||||
)
|
||||
from langchain_core.outputs.chat_result import ChatResult
|
||||
from langchain_core.outputs.generation import Generation, GenerationChunk
|
||||
from langchain_core.outputs.llm_result import LLMResult
|
||||
@ -36,3 +43,29 @@ __all__ = [
|
||||
"LLMResult",
|
||||
"RunInfo",
|
||||
]
|
||||
|
||||
_dynamic_imports = {
|
||||
"ChatGeneration": "chat_generation",
|
||||
"ChatGenerationChunk": "chat_generation",
|
||||
"ChatResult": "chat_result",
|
||||
"Generation": "generation",
|
||||
"GenerationChunk": "generation",
|
||||
"LLMResult": "llm_result",
|
||||
"RunInfo": "run_info",
|
||||
}
|
||||
|
||||
|
||||
def __getattr__(attr_name: str) -> object:
|
||||
module_name = _dynamic_imports.get(attr_name)
|
||||
package = __spec__.parent # type: ignore[name-defined]
|
||||
if module_name == "__module__" or module_name is None:
|
||||
result = import_module(f".{attr_name}", package=package)
|
||||
else:
|
||||
module = import_module(f".{module_name}", package=package)
|
||||
result = getattr(module, attr_name)
|
||||
globals()[attr_name] = result
|
||||
return result
|
||||
|
||||
|
||||
def __dir__() -> list[str]:
|
||||
return list(__all__)
|
||||
|
@ -25,6 +25,10 @@ from multiple components and prompt values. Prompt classes and functions make co
|
||||
|
||||
""" # noqa: E501
|
||||
|
||||
from importlib import import_module
|
||||
from typing import TYPE_CHECKING
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from langchain_core.prompts.base import (
|
||||
BasePromptTemplate,
|
||||
aformat_document,
|
||||
@ -43,7 +47,9 @@ from langchain_core.prompts.few_shot import (
|
||||
FewShotChatMessagePromptTemplate,
|
||||
FewShotPromptTemplate,
|
||||
)
|
||||
from langchain_core.prompts.few_shot_with_templates import FewShotPromptWithTemplates
|
||||
from langchain_core.prompts.few_shot_with_templates import (
|
||||
FewShotPromptWithTemplates,
|
||||
)
|
||||
from langchain_core.prompts.loading import load_prompt
|
||||
from langchain_core.prompts.pipeline import PipelinePromptTemplate
|
||||
from langchain_core.prompts.prompt import PromptTemplate
|
||||
@ -78,3 +84,43 @@ __all__ = [
|
||||
"jinja2_formatter",
|
||||
"validate_jinja2",
|
||||
]
|
||||
|
||||
_dynamic_imports = {
|
||||
"BasePromptTemplate": "base",
|
||||
"format_document": "base",
|
||||
"aformat_document": "base",
|
||||
"AIMessagePromptTemplate": "chat",
|
||||
"BaseChatPromptTemplate": "chat",
|
||||
"ChatMessagePromptTemplate": "chat",
|
||||
"ChatPromptTemplate": "chat",
|
||||
"HumanMessagePromptTemplate": "chat",
|
||||
"MessagesPlaceholder": "chat",
|
||||
"SystemMessagePromptTemplate": "chat",
|
||||
"FewShotChatMessagePromptTemplate": "few_shot",
|
||||
"FewShotPromptTemplate": "few_shot",
|
||||
"FewShotPromptWithTemplates": "few_shot_with_templates",
|
||||
"load_prompt": "loading",
|
||||
"PipelinePromptTemplate": "pipeline",
|
||||
"PromptTemplate": "prompt",
|
||||
"StringPromptTemplate": "string",
|
||||
"check_valid_template": "string",
|
||||
"get_template_variables": "string",
|
||||
"jinja2_formatter": "string",
|
||||
"validate_jinja2": "string",
|
||||
}
|
||||
|
||||
|
||||
def __getattr__(attr_name: str) -> object:
|
||||
module_name = _dynamic_imports.get(attr_name)
|
||||
package = __spec__.parent # type: ignore[name-defined]
|
||||
if module_name == "__module__" or module_name is None:
|
||||
result = import_module(f".{attr_name}", package=package)
|
||||
else:
|
||||
module = import_module(f".{module_name}", package=package)
|
||||
result = getattr(module, attr_name)
|
||||
globals()[attr_name] = result
|
||||
return result
|
||||
|
||||
|
||||
def __dir__() -> list[str]:
|
||||
return list(__all__)
|
||||
|
@ -17,6 +17,10 @@ creating more responsive UX.
|
||||
This module contains schema and implementation of LangChain Runnables primitives.
|
||||
"""
|
||||
|
||||
from importlib import import_module
|
||||
from typing import TYPE_CHECKING
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from langchain_core.runnables.base import (
|
||||
Runnable,
|
||||
RunnableBinding,
|
||||
@ -85,3 +89,51 @@ __all__ = [
|
||||
"aadd",
|
||||
"add",
|
||||
]
|
||||
|
||||
_dynamic_imports = {
|
||||
"chain": "base",
|
||||
"Runnable": "base",
|
||||
"RunnableBinding": "base",
|
||||
"RunnableGenerator": "base",
|
||||
"RunnableLambda": "base",
|
||||
"RunnableMap": "base",
|
||||
"RunnableParallel": "base",
|
||||
"RunnableSequence": "base",
|
||||
"RunnableSerializable": "base",
|
||||
"RunnableBranch": "branch",
|
||||
"RunnableConfig": "config",
|
||||
"ensure_config": "config",
|
||||
"get_config_list": "config",
|
||||
"patch_config": "config",
|
||||
"run_in_executor": "config",
|
||||
"RunnableWithFallbacks": "fallbacks",
|
||||
"RunnableWithMessageHistory": "history",
|
||||
"RunnableAssign": "passthrough",
|
||||
"RunnablePassthrough": "passthrough",
|
||||
"RunnablePick": "passthrough",
|
||||
"RouterInput": "router",
|
||||
"RouterRunnable": "router",
|
||||
"AddableDict": "utils",
|
||||
"ConfigurableField": "utils",
|
||||
"ConfigurableFieldMultiOption": "utils",
|
||||
"ConfigurableFieldSingleOption": "utils",
|
||||
"ConfigurableFieldSpec": "utils",
|
||||
"aadd": "utils",
|
||||
"add": "utils",
|
||||
}
|
||||
|
||||
|
||||
def __getattr__(attr_name: str) -> object:
|
||||
module_name = _dynamic_imports.get(attr_name)
|
||||
package = __spec__.parent # type: ignore[name-defined]
|
||||
if module_name == "__module__" or module_name is None:
|
||||
result = import_module(f".{attr_name}", package=package)
|
||||
else:
|
||||
module = import_module(f".{module_name}", package=package)
|
||||
result = getattr(module, attr_name)
|
||||
globals()[attr_name] = result
|
||||
return result
|
||||
|
||||
|
||||
def __dir__() -> list[str]:
|
||||
return list(__all__)
|
||||
|
@ -19,6 +19,10 @@ tool for the job.
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
from importlib import import_module
|
||||
from typing import TYPE_CHECKING
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from langchain_core.tools.base import (
|
||||
FILTERED_ARGS,
|
||||
ArgsSchema,
|
||||
@ -68,3 +72,41 @@ __all__ = [
|
||||
"Tool",
|
||||
"StructuredTool",
|
||||
]
|
||||
|
||||
_dynamic_imports = {
|
||||
"FILTERED_ARGS": "base",
|
||||
"ArgsSchema": "base",
|
||||
"BaseTool": "base",
|
||||
"BaseToolkit": "base",
|
||||
"InjectedToolArg": "base",
|
||||
"InjectedToolCallId": "base",
|
||||
"SchemaAnnotationError": "base",
|
||||
"ToolException": "base",
|
||||
"_get_runnable_config_param": "base",
|
||||
"create_schema_from_function": "base",
|
||||
"convert_runnable_to_tool": "convert",
|
||||
"tool": "convert",
|
||||
"ToolsRenderer": "render",
|
||||
"render_text_description": "render",
|
||||
"render_text_description_and_args": "render",
|
||||
"RetrieverInput": "retriever",
|
||||
"create_retriever_tool": "retriever",
|
||||
"Tool": "simple",
|
||||
"StructuredTool": "structured",
|
||||
}
|
||||
|
||||
|
||||
def __getattr__(attr_name: str) -> object:
|
||||
module_name = _dynamic_imports.get(attr_name)
|
||||
package = __spec__.parent # type: ignore[name-defined]
|
||||
if module_name == "__module__" or module_name is None:
|
||||
result = import_module(f".{attr_name}", package=package)
|
||||
else:
|
||||
module = import_module(f".{module_name}", package=package)
|
||||
result = getattr(module, attr_name)
|
||||
globals()[attr_name] = result
|
||||
return result
|
||||
|
||||
|
||||
def __dir__() -> list[str]:
|
||||
return list(__all__)
|
||||
|
@ -8,6 +8,21 @@
|
||||
--> <name> # Examples: LogStreamCallbackHandler
|
||||
""" # noqa: E501
|
||||
|
||||
from importlib import import_module
|
||||
from typing import TYPE_CHECKING
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from langchain_core.tracers.base import BaseTracer
|
||||
from langchain_core.tracers.evaluation import EvaluatorCallbackHandler
|
||||
from langchain_core.tracers.langchain import LangChainTracer
|
||||
from langchain_core.tracers.log_stream import (
|
||||
LogStreamCallbackHandler,
|
||||
RunLog,
|
||||
RunLogPatch,
|
||||
)
|
||||
from langchain_core.tracers.schemas import Run
|
||||
from langchain_core.tracers.stdout import ConsoleCallbackHandler
|
||||
|
||||
__all__ = [
|
||||
"BaseTracer",
|
||||
"EvaluatorCallbackHandler",
|
||||
@ -19,13 +34,29 @@ __all__ = [
|
||||
"LogStreamCallbackHandler",
|
||||
]
|
||||
|
||||
from langchain_core.tracers.base import BaseTracer
|
||||
from langchain_core.tracers.evaluation import EvaluatorCallbackHandler
|
||||
from langchain_core.tracers.langchain import LangChainTracer
|
||||
from langchain_core.tracers.log_stream import (
|
||||
LogStreamCallbackHandler,
|
||||
RunLog,
|
||||
RunLogPatch,
|
||||
)
|
||||
from langchain_core.tracers.schemas import Run
|
||||
from langchain_core.tracers.stdout import ConsoleCallbackHandler
|
||||
_dynamic_imports = {
|
||||
"BaseTracer": "base",
|
||||
"EvaluatorCallbackHandler": "evaluation",
|
||||
"LangChainTracer": "langchain",
|
||||
"LogStreamCallbackHandler": "log_stream",
|
||||
"RunLog": "log_stream",
|
||||
"RunLogPatch": "log_stream",
|
||||
"Run": "schemas",
|
||||
"ConsoleCallbackHandler": "stdout",
|
||||
}
|
||||
|
||||
|
||||
def __getattr__(attr_name: str) -> object:
|
||||
module_name = _dynamic_imports.get(attr_name)
|
||||
package = __spec__.parent # type: ignore[name-defined]
|
||||
if module_name == "__module__" or module_name is None:
|
||||
result = import_module(f".{attr_name}", package=package)
|
||||
else:
|
||||
module = import_module(f".{module_name}", package=package)
|
||||
result = getattr(module, attr_name)
|
||||
globals()[attr_name] = result
|
||||
return result
|
||||
|
||||
|
||||
def __dir__() -> list[str]:
|
||||
return list(__all__)
|
||||
|
@ -3,6 +3,12 @@
|
||||
These functions do not depend on any other LangChain module.
|
||||
"""
|
||||
|
||||
from importlib import import_module
|
||||
from typing import TYPE_CHECKING
|
||||
|
||||
if TYPE_CHECKING:
|
||||
# for type checking and IDE support, we include the imports here
|
||||
# but we don't want to eagerly import them at runtime
|
||||
from langchain_core.utils import image
|
||||
from langchain_core.utils.aiter import abatch_iterate
|
||||
from langchain_core.utils.env import get_from_dict_or_env, get_from_env
|
||||
@ -58,3 +64,48 @@ __all__ = [
|
||||
"from_env",
|
||||
"secret_from_env",
|
||||
]
|
||||
|
||||
_dynamic_imports = {
|
||||
"image": "__module__",
|
||||
"abatch_iterate": "aiter",
|
||||
"get_from_dict_or_env": "env",
|
||||
"get_from_env": "env",
|
||||
"StrictFormatter": "formatting",
|
||||
"formatter": "formatting",
|
||||
"get_bolded_text": "input",
|
||||
"get_color_mapping": "input",
|
||||
"get_colored_text": "input",
|
||||
"print_text": "input",
|
||||
"batch_iterate": "iter",
|
||||
"try_load_from_hub": "loading",
|
||||
"pre_init": "pydantic",
|
||||
"comma_list": "strings",
|
||||
"stringify_dict": "strings",
|
||||
"stringify_value": "strings",
|
||||
"build_extra_kwargs": "utils",
|
||||
"check_package_version": "utils",
|
||||
"convert_to_secret_str": "utils",
|
||||
"from_env": "utils",
|
||||
"get_pydantic_field_names": "utils",
|
||||
"guard_import": "utils",
|
||||
"mock_now": "utils",
|
||||
"secret_from_env": "utils",
|
||||
"xor_args": "utils",
|
||||
"raise_for_status_with_text": "utils",
|
||||
}
|
||||
|
||||
|
||||
def __getattr__(attr_name: str) -> object:
|
||||
module_name = _dynamic_imports.get(attr_name)
|
||||
package = __spec__.parent # type: ignore[name-defined]
|
||||
if module_name == "__module__" or module_name is None:
|
||||
result = import_module(f".{attr_name}", package=package)
|
||||
else:
|
||||
module = import_module(f".{module_name}", package=package)
|
||||
result = getattr(module, attr_name)
|
||||
globals()[attr_name] = result
|
||||
return result
|
||||
|
||||
|
||||
def __dir__() -> list[str]:
|
||||
return list(__all__)
|
||||
|
Loading…
Reference in New Issue
Block a user