community: callbacks guard_imports (#21173)

Issue: we have several helper functions to import third-party libraries
like import_uptrain in
[community.callbacks](https://api.python.langchain.com/en/latest/callbacks/langchain_community.callbacks.uptrain_callback.import_uptrain.html#langchain_community.callbacks.uptrain_callback.import_uptrain).
And we have core.utils.utils.guard_import that works exactly for this
purpose.
The import_<package> functions work inconsistently and rather be private
functions.
Change: replaced these functions with the guard_import function.

Related to #21133
This commit is contained in:
Leonid Ganeline 2024-05-07 15:04:54 -07:00 committed by GitHub
parent 416549bed2
commit 791d59a2c8
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
13 changed files with 73 additions and 178 deletions

View File

@ -4,19 +4,12 @@ from typing import Any, Dict, List, Optional
from langchain_core.agents import AgentAction, AgentFinish from langchain_core.agents import AgentAction, AgentFinish
from langchain_core.callbacks import BaseCallbackHandler from langchain_core.callbacks import BaseCallbackHandler
from langchain_core.outputs import LLMResult from langchain_core.outputs import LLMResult
from langchain_core.utils import guard_import
def import_aim() -> Any: def import_aim() -> Any:
"""Import the aim python package and raise an error if it is not installed.""" """Import the aim python package and raise an error if it is not installed."""
try: return guard_import("aim")
import aim
except ImportError:
raise ImportError(
"To use the Aim callback manager you need to have the"
" `aim` python package installed."
"Please install it with `pip install aim`"
)
return aim
class BaseMetadataCallbackHandler: class BaseMetadataCallbackHandler:

View File

@ -8,6 +8,7 @@ from typing import TYPE_CHECKING, Any, Dict, List, Mapping, Optional, Sequence
from langchain_core.agents import AgentAction, AgentFinish from langchain_core.agents import AgentAction, AgentFinish
from langchain_core.callbacks import BaseCallbackHandler from langchain_core.callbacks import BaseCallbackHandler
from langchain_core.outputs import LLMResult from langchain_core.outputs import LLMResult
from langchain_core.utils import guard_import
from langchain_community.callbacks.utils import ( from langchain_community.callbacks.utils import (
BaseMetadataCallbackHandler, BaseMetadataCallbackHandler,
@ -25,14 +26,7 @@ if TYPE_CHECKING:
def import_clearml() -> Any: def import_clearml() -> Any:
"""Import the clearml python package and raise an error if it is not installed.""" """Import the clearml python package and raise an error if it is not installed."""
try: return guard_import("clearml")
import clearml
except ImportError:
raise ImportError(
"To use the clearml callback manager you need to have the `clearml` python "
"package installed. Please install it with `pip install clearml`"
)
return clearml
class ClearMLCallbackHandler(BaseMetadataCallbackHandler, BaseCallbackHandler): class ClearMLCallbackHandler(BaseMetadataCallbackHandler, BaseCallbackHandler):

View File

@ -6,6 +6,7 @@ from typing import Any, Callable, Dict, List, Optional, Sequence
from langchain_core.agents import AgentAction, AgentFinish from langchain_core.agents import AgentAction, AgentFinish
from langchain_core.callbacks import BaseCallbackHandler from langchain_core.callbacks import BaseCallbackHandler
from langchain_core.outputs import Generation, LLMResult from langchain_core.outputs import Generation, LLMResult
from langchain_core.utils import guard_import
import langchain_community import langchain_community
from langchain_community.callbacks.utils import ( from langchain_community.callbacks.utils import (
@ -21,15 +22,7 @@ LANGCHAIN_MODEL_NAME = "langchain-model"
def import_comet_ml() -> Any: def import_comet_ml() -> Any:
"""Import comet_ml and raise an error if it is not installed.""" """Import comet_ml and raise an error if it is not installed."""
try: return guard_import("comet_ml")
import comet_ml
except ImportError:
raise ImportError(
"To use the comet_ml callback manager you need to have the "
"`comet_ml` python package installed. Please install it with"
" `pip install comet_ml`"
)
return comet_ml
def _get_experiment( def _get_experiment(

View File

@ -1,4 +1,5 @@
"""Callback handler for Context AI""" """Callback handler for Context AI"""
import os import os
from typing import Any, Dict, List from typing import Any, Dict, List
from uuid import UUID from uuid import UUID
@ -6,26 +7,23 @@ from uuid import UUID
from langchain_core.callbacks import BaseCallbackHandler from langchain_core.callbacks import BaseCallbackHandler
from langchain_core.messages import BaseMessage from langchain_core.messages import BaseMessage
from langchain_core.outputs import LLMResult from langchain_core.outputs import LLMResult
from langchain_core.utils import guard_import
def import_context() -> Any: def import_context() -> Any:
"""Import the `getcontext` package.""" """Import the `getcontext` package."""
try: return (
import getcontext guard_import("getcontext", pip_name="python-context"),
from getcontext.generated.models import ( guard_import("getcontext.token", pip_name="python-context").Credential,
Conversation, guard_import(
Message, "getcontext.generated.models", pip_name="python-context"
MessageRole, ).Conversation,
Rating, guard_import("getcontext.generated.models", pip_name="python-context").Message,
) guard_import(
from getcontext.token import Credential "getcontext.generated.models", pip_name="python-context"
except ImportError: ).MessageRole,
raise ImportError( guard_import("getcontext.generated.models", pip_name="python-context").Rating,
"To use the context callback manager you need to have the " )
"`getcontext` python package installed (version >=0.3.0). "
"Please install it with `pip install --upgrade python-context`"
)
return getcontext, Credential, Conversation, Message, MessageRole, Rating
class ContextCallbackHandler(BaseCallbackHandler): class ContextCallbackHandler(BaseCallbackHandler):

View File

@ -4,6 +4,7 @@ from uuid import UUID
from langchain_core.callbacks import BaseCallbackHandler from langchain_core.callbacks import BaseCallbackHandler
from langchain_core.outputs import LLMResult from langchain_core.outputs import LLMResult
from langchain_core.utils import guard_import
from langchain_community.callbacks.utils import import_pandas from langchain_community.callbacks.utils import import_pandas
@ -54,14 +55,7 @@ _dataset_dict = {
def import_fiddler() -> Any: def import_fiddler() -> Any:
"""Import the fiddler python package and raise an error if it is not installed.""" """Import the fiddler python package and raise an error if it is not installed."""
try: return guard_import("fiddler", pip_name="fiddler-client")
import fiddler
except ImportError:
raise ImportError(
"To use fiddler callback handler you need to have `fiddler-client`"
"package installed. Please install it with `pip install fiddler-client`"
)
return fiddler
# First, define custom callback handler implementations # First, define custom callback handler implementations

View File

@ -1,4 +1,5 @@
"""FlyteKit callback handler.""" """FlyteKit callback handler."""
from __future__ import annotations from __future__ import annotations
import logging import logging
@ -8,6 +9,7 @@ from typing import TYPE_CHECKING, Any, Dict, List, Tuple
from langchain_core.agents import AgentAction, AgentFinish from langchain_core.agents import AgentAction, AgentFinish
from langchain_core.callbacks import BaseCallbackHandler from langchain_core.callbacks import BaseCallbackHandler
from langchain_core.outputs import LLMResult from langchain_core.outputs import LLMResult
from langchain_core.utils import guard_import
from langchain_community.callbacks.utils import ( from langchain_community.callbacks.utils import (
BaseMetadataCallbackHandler, BaseMetadataCallbackHandler,
@ -26,17 +28,12 @@ logger = logging.getLogger(__name__)
def import_flytekit() -> Tuple[flytekit, renderer]: def import_flytekit() -> Tuple[flytekit, renderer]:
"""Import flytekit and flytekitplugins-deck-standard.""" """Import flytekit and flytekitplugins-deck-standard."""
try: return (
import flytekit guard_import("flytekit"),
from flytekitplugins.deck import renderer guard_import(
except ImportError: "flytekitplugins.deck", pip_name="flytekitplugins-deck-standard"
raise ImportError( ).renderer,
"To use the flyte callback manager you need" )
"to have the `flytekit` and `flytekitplugins-deck-standard`"
"packages installed. Please install them with `pip install flytekit`"
"and `pip install flytekitplugins-deck-standard`."
)
return flytekit, renderer
def analyze_text( def analyze_text(

View File

@ -5,32 +5,17 @@ from langchain_core.agents import AgentAction, AgentFinish
from langchain_core.callbacks import BaseCallbackHandler from langchain_core.callbacks import BaseCallbackHandler
from langchain_core.messages import BaseMessage from langchain_core.messages import BaseMessage
from langchain_core.outputs import ChatGeneration, LLMResult from langchain_core.outputs import ChatGeneration, LLMResult
from langchain_core.utils import guard_import
def import_infino() -> Any: def import_infino() -> Any:
"""Import the infino client.""" """Import the infino client."""
try: return guard_import("infinopy").InfinoClient()
from infinopy import InfinoClient
except ImportError:
raise ImportError(
"To use the Infino callbacks manager you need to have the"
" `infinopy` python package installed."
"Please install it with `pip install infinopy`"
)
return InfinoClient()
def import_tiktoken() -> Any: def import_tiktoken() -> Any:
"""Import tiktoken for counting tokens for OpenAI models.""" """Import tiktoken for counting tokens for OpenAI models."""
try: return guard_import("tiktoken")
import tiktoken
except ImportError:
raise ImportError(
"To use the ChatOpenAI model with Infino callback manager, you need to "
"have the `tiktoken` python package installed."
"Please install it with `pip install tiktoken`"
)
return tiktoken
def get_num_tokens(string: str, openai_model_name: str) -> int: def get_num_tokens(string: str, openai_model_name: str) -> int:

View File

@ -12,7 +12,7 @@ from langchain_core.agents import AgentAction, AgentFinish
from langchain_core.callbacks import BaseCallbackHandler from langchain_core.callbacks import BaseCallbackHandler
from langchain_core.documents import Document from langchain_core.documents import Document
from langchain_core.outputs import LLMResult from langchain_core.outputs import LLMResult
from langchain_core.utils import get_from_dict_or_env from langchain_core.utils import get_from_dict_or_env, guard_import
from langchain_community.callbacks.utils import ( from langchain_community.callbacks.utils import (
BaseMetadataCallbackHandler, BaseMetadataCallbackHandler,
@ -28,14 +28,7 @@ logger = logging.getLogger(__name__)
def import_mlflow() -> Any: def import_mlflow() -> Any:
"""Import the mlflow python package and raise an error if it is not installed.""" """Import the mlflow python package and raise an error if it is not installed."""
try: return guard_import("mlflow")
import mlflow
except ImportError:
raise ImportError(
"To use the mlflow callback manager you need to have the `mlflow` python "
"package installed. Please install it with `pip install mlflow>=2.3.0`"
)
return mlflow
def mlflow_callback_metrics() -> List[str]: def mlflow_callback_metrics() -> List[str]:

View File

@ -2,6 +2,7 @@ from types import ModuleType, SimpleNamespace
from typing import TYPE_CHECKING, Any, Callable, Dict from typing import TYPE_CHECKING, Any, Callable, Dict
from langchain_core.tracers import BaseTracer from langchain_core.tracers import BaseTracer
from langchain_core.utils import guard_import
if TYPE_CHECKING: if TYPE_CHECKING:
from uuid import UUID from uuid import UUID
@ -23,29 +24,15 @@ def _get_run_type(run: "Run") -> str:
def import_comet_llm_api() -> SimpleNamespace: def import_comet_llm_api() -> SimpleNamespace:
"""Import comet_llm api and raise an error if it is not installed.""" """Import comet_llm api and raise an error if it is not installed."""
try: comet_llm = guard_import("comet_llm")
from comet_llm import ( comet_llm_chains = guard_import("comet_llm.chains")
experiment_info,
flush,
)
from comet_llm.chains import api as chain_api
from comet_llm.chains import (
chain,
span,
)
except ImportError:
raise ImportError(
"To use the CometTracer you need to have the "
"`comet_llm>=2.0.0` python package installed. Please install it with"
" `pip install -U comet_llm`"
)
return SimpleNamespace( return SimpleNamespace(
chain=chain, chain=comet_llm_chains.chain,
span=span, span=comet_llm_chains.span,
chain_api=chain_api, chain_api=comet_llm_chains.api,
experiment_info=experiment_info, experiment_info=comet_llm.experiment_info,
flush=flush, flush=comet_llm.flush,
) )

View File

@ -2,12 +2,12 @@
UpTrain Callback Handler UpTrain Callback Handler
UpTrain is an open-source platform to evaluate and improve LLM applications. It provides UpTrain is an open-source platform to evaluate and improve LLM applications. It provides
grades for 20+ preconfigured checks (covering language, code, embedding use cases), grades for 20+ preconfigured checks (covering language, code, embedding use cases),
performs root cause analyses on instances of failure cases and provides guidance for performs root cause analyses on instances of failure cases and provides guidance for
resolving them. resolving them.
This module contains a callback handler for integrating UpTrain seamlessly into your This module contains a callback handler for integrating UpTrain seamlessly into your
pipeline and facilitating diverse evaluations. The callback handler automates various pipeline and facilitating diverse evaluations. The callback handler automates various
evaluations to assess the performance and effectiveness of the components within the evaluations to assess the performance and effectiveness of the components within the
pipeline. pipeline.
@ -29,7 +29,7 @@ The evaluations conducted include:
3. Context Compression and Reranking: 3. Context Compression and Reranking:
Re-ranking involves reordering nodes based on relevance to the query and selecting Re-ranking involves reordering nodes based on relevance to the query and selecting
top n nodes. top n nodes.
Due to the potential reduction in the number of nodes after re-ranking, the following Due to the potential reduction in the number of nodes after re-ranking, the following
evaluations evaluations
are performed in addition to the RAG evaluations: are performed in addition to the RAG evaluations:
@ -65,6 +65,7 @@ from uuid import UUID
from langchain_core.callbacks.base import BaseCallbackHandler from langchain_core.callbacks.base import BaseCallbackHandler
from langchain_core.documents import Document from langchain_core.documents import Document
from langchain_core.outputs import LLMResult from langchain_core.outputs import LLMResult
from langchain_core.utils import guard_import
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
handler = logging.StreamHandler(sys.stdout) handler = logging.StreamHandler(sys.stdout)
@ -75,17 +76,7 @@ logger.addHandler(handler)
def import_uptrain() -> Any: def import_uptrain() -> Any:
"""Import the `uptrain` package.""" """Import the `uptrain` package."""
try: return guard_import("uptrain")
import uptrain
except ImportError as e:
raise ImportError(
"To use the UpTrainCallbackHandler, you need the"
"`uptrain` package. Please install it with"
"`pip install uptrain`.",
e,
)
return uptrain
class UpTrainDataSchema: class UpTrainDataSchema:

View File

@ -2,41 +2,22 @@ import hashlib
from pathlib import Path from pathlib import Path
from typing import Any, Dict, Iterable, Tuple, Union from typing import Any, Dict, Iterable, Tuple, Union
from langchain_core.utils import guard_import
def import_spacy() -> Any: def import_spacy() -> Any:
"""Import the spacy python package and raise an error if it is not installed.""" """Import the spacy python package and raise an error if it is not installed."""
try: return guard_import("spacy")
import spacy
except ImportError:
raise ImportError(
"This callback manager requires the `spacy` python "
"package installed. Please install it with `pip install spacy`"
)
return spacy
def import_pandas() -> Any: def import_pandas() -> Any:
"""Import the pandas python package and raise an error if it is not installed.""" """Import the pandas python package and raise an error if it is not installed."""
try: return guard_import("pandas")
import pandas
except ImportError:
raise ImportError(
"This callback manager requires the `pandas` python "
"package installed. Please install it with `pip install pandas`"
)
return pandas
def import_textstat() -> Any: def import_textstat() -> Any:
"""Import the textstat python package and raise an error if it is not installed.""" """Import the textstat python package and raise an error if it is not installed."""
try: return guard_import("textstat")
import textstat
except ImportError:
raise ImportError(
"This callback manager requires the `textstat` python "
"package installed. Please install it with `pip install textstat`"
)
return textstat
def _flatten_dict( def _flatten_dict(

View File

@ -7,6 +7,7 @@ from typing import Any, Dict, List, Optional, Sequence, Union
from langchain_core.agents import AgentAction, AgentFinish from langchain_core.agents import AgentAction, AgentFinish
from langchain_core.callbacks import BaseCallbackHandler from langchain_core.callbacks import BaseCallbackHandler
from langchain_core.outputs import LLMResult from langchain_core.outputs import LLMResult
from langchain_core.utils import guard_import
from langchain_community.callbacks.utils import ( from langchain_community.callbacks.utils import (
BaseMetadataCallbackHandler, BaseMetadataCallbackHandler,
@ -20,14 +21,7 @@ from langchain_community.callbacks.utils import (
def import_wandb() -> Any: def import_wandb() -> Any:
"""Import the wandb python package and raise an error if it is not installed.""" """Import the wandb python package and raise an error if it is not installed."""
try: return guard_import("wandb")
import wandb
except ImportError:
raise ImportError(
"To use the wandb callback manager you need to have the `wandb` python "
"package installed. Please install it with `pip install wandb`"
)
return wandb
def load_json_to_dict(json_path: Union[str, Path]) -> dict: def load_json_to_dict(json_path: Union[str, Path]) -> dict:

View File

@ -4,7 +4,7 @@ import logging
from typing import TYPE_CHECKING, Any, Optional from typing import TYPE_CHECKING, Any, Optional
from langchain_core.callbacks import BaseCallbackHandler from langchain_core.callbacks import BaseCallbackHandler
from langchain_core.utils import get_from_env from langchain_core.utils import get_from_env, guard_import
if TYPE_CHECKING: if TYPE_CHECKING:
from whylogs.api.logger.logger import Logger from whylogs.api.logger.logger import Logger
@ -27,22 +27,15 @@ def import_langkit(
Returns: Returns:
The imported langkit module. The imported langkit module.
""" """
try: langkit = guard_import("langkit")
import langkit guard_import("langkit.regexes")
import langkit.regexes guard_import("langkit.textstat")
import langkit.textstat if sentiment:
guard_import("langkit.sentiment")
if sentiment: if toxicity:
import langkit.sentiment guard_import("langkit.toxicity")
if toxicity: if themes:
import langkit.toxicity guard_import("langkit.themes")
if themes:
import langkit.themes
except ImportError:
raise ImportError(
"To use the whylabs callback manager you need to have the `langkit` python "
"package installed. Please install it with `pip install langkit`."
)
return langkit return langkit
@ -161,10 +154,12 @@ class WhyLabsCallbackHandler(BaseCallbackHandler):
# langkit library will import necessary whylogs libraries # langkit library will import necessary whylogs libraries
import_langkit(sentiment=sentiment, toxicity=toxicity, themes=themes) import_langkit(sentiment=sentiment, toxicity=toxicity, themes=themes)
import whylogs as why why = guard_import("whylogs")
from langkit.callback_handler import get_callback_instance get_callback_instance = guard_import(
from whylogs.api.writer.whylabs import WhyLabsWriter "langkit.callback_handler"
from whylogs.experimental.core.udf_schema import udf_schema ).get_callback_instance
WhyLabsWriter = guard_import("whylogs.api.writer.whylabs").WhyLabsWriter
udf_schema = guard_import("whylogs.experimental.core.udf_schema").udf_schema
if logger is None: if logger is None:
api_key = api_key or get_from_env("api_key", "WHYLABS_API_KEY") api_key = api_key or get_from_env("api_key", "WHYLABS_API_KEY")