mirror of
https://github.com/hwchase17/langchain.git
synced 2025-09-23 19:39:58 +00:00
Deprecate direct access to globals like debug
and verbose
. (#11311)
Instead of accessing `langchain.debug`, `langchain.verbose`, or `langchain.llm_cache`, please use the new getter/setter functions in `langchain.globals`: - `langchain.globals.set_debug()` and `langchain.globals.get_debug()` - `langchain.globals.set_verbose()` and `langchain.globals.get_verbose()` - `langchain.globals.set_llm_cache()` and `langchain.globals.get_llm_cache()` Using the old globals directly will now raise a warning. --------- Co-authored-by: Harrison Chase <hw.chase.17@gmail.com>
This commit is contained in:
@@ -2,14 +2,10 @@
|
||||
"""Main entrypoint into package."""
|
||||
import warnings
|
||||
from importlib import metadata
|
||||
from typing import TYPE_CHECKING, Any, Optional
|
||||
from typing import Any, Optional
|
||||
|
||||
from langchain._api.deprecation import surface_langchain_deprecation_warnings
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from langchain.schema import BaseCache
|
||||
|
||||
|
||||
try:
|
||||
__version__ = metadata.version(__package__)
|
||||
except metadata.PackageNotFoundError:
|
||||
@@ -17,10 +13,6 @@ except metadata.PackageNotFoundError:
|
||||
__version__ = ""
|
||||
del metadata # optional, avoids polluting the results of dir(__package__)
|
||||
|
||||
verbose: bool = False
|
||||
debug: bool = False
|
||||
llm_cache: Optional["BaseCache"] = None
|
||||
|
||||
|
||||
def _is_interactive_env() -> bool:
|
||||
"""Determine if running within IPython or Jupyter."""
|
||||
@@ -29,7 +21,7 @@ def _is_interactive_env() -> bool:
|
||||
return hasattr(sys, "ps2")
|
||||
|
||||
|
||||
def _warn_on_import(name: str) -> None:
|
||||
def _warn_on_import(name: str, replacement: Optional[str] = None) -> None:
|
||||
"""Warn on import of deprecated module."""
|
||||
if _is_interactive_env():
|
||||
# No warnings for interactive environments.
|
||||
@@ -37,9 +29,16 @@ def _warn_on_import(name: str) -> None:
|
||||
# where users rely on auto-complete and may trigger this warning
|
||||
# even if they are not using any deprecated modules
|
||||
return
|
||||
warnings.warn(
|
||||
f"Importing {name} from langchain root module is no longer supported."
|
||||
)
|
||||
|
||||
if replacement:
|
||||
warnings.warn(
|
||||
f"Importing {name} from langchain root module is no longer supported. "
|
||||
f"Please use {replacement} instead."
|
||||
)
|
||||
else:
|
||||
warnings.warn(
|
||||
f"Importing {name} from langchain root module is no longer supported."
|
||||
)
|
||||
|
||||
|
||||
# Surfaces Deprecation and Pending Deprecation warnings from langchain.
|
||||
@@ -328,6 +327,39 @@ def __getattr__(name: str) -> Any:
|
||||
_warn_on_import(name)
|
||||
|
||||
return SerpAPIWrapper
|
||||
elif name == "verbose":
|
||||
from langchain.globals import _verbose
|
||||
|
||||
_warn_on_import(
|
||||
name,
|
||||
replacement=(
|
||||
"langchain.globals.set_verbose() / langchain.globals.get_verbose()"
|
||||
),
|
||||
)
|
||||
|
||||
return _verbose
|
||||
elif name == "debug":
|
||||
from langchain.globals import _debug
|
||||
|
||||
_warn_on_import(
|
||||
name,
|
||||
replacement=(
|
||||
"langchain.globals.set_debug() / langchain.globals.get_debug()"
|
||||
),
|
||||
)
|
||||
|
||||
return _debug
|
||||
elif name == "llm_cache":
|
||||
from langchain.globals import _llm_cache
|
||||
|
||||
_warn_on_import(
|
||||
name,
|
||||
replacement=(
|
||||
"langchain.globals.set_llm_cache() / langchain.globals.get_llm_cache()"
|
||||
),
|
||||
)
|
||||
|
||||
return _llm_cache
|
||||
else:
|
||||
raise AttributeError(f"Could not find: {name}")
|
||||
|
||||
|
@@ -27,7 +27,6 @@ from uuid import UUID
|
||||
|
||||
from tenacity import RetryCallState
|
||||
|
||||
import langchain
|
||||
from langchain.callbacks.base import (
|
||||
BaseCallbackHandler,
|
||||
BaseCallbackManager,
|
||||
@@ -88,7 +87,9 @@ run_collector_var: ContextVar[
|
||||
|
||||
|
||||
def _get_debug() -> bool:
|
||||
return langchain.debug
|
||||
from langchain.globals import get_debug
|
||||
|
||||
return get_debug()
|
||||
|
||||
|
||||
@contextmanager
|
||||
|
@@ -10,7 +10,6 @@ from typing import Any, Dict, List, Optional, Type, Union
|
||||
|
||||
import yaml
|
||||
|
||||
import langchain
|
||||
from langchain.callbacks.base import BaseCallbackManager
|
||||
from langchain.callbacks.manager import (
|
||||
AsyncCallbackManager,
|
||||
@@ -34,7 +33,9 @@ logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
def _get_verbosity() -> bool:
|
||||
return langchain.verbose
|
||||
from langchain.globals import get_verbose
|
||||
|
||||
return get_verbose()
|
||||
|
||||
|
||||
class Chain(RunnableSerializable[Dict[str, Any], Dict[str, Any]], ABC):
|
||||
@@ -108,10 +109,10 @@ class Chain(RunnableSerializable[Dict[str, Any], Dict[str, Any]], ABC):
|
||||
|
||||
memory: Optional[BaseMemory] = None
|
||||
"""Optional memory object. Defaults to None.
|
||||
Memory is a class that gets called at the start
|
||||
Memory is a class that gets called at the start
|
||||
and at the end of every chain. At the start, memory loads variables and passes
|
||||
them along in the chain. At the end, it saves any returned variables.
|
||||
There are many different types of memory - please see memory docs
|
||||
There are many different types of memory - please see memory docs
|
||||
for the full catalog."""
|
||||
callbacks: Callbacks = Field(default=None, exclude=True)
|
||||
"""Optional list of callback handlers (or callback manager). Defaults to None.
|
||||
@@ -123,7 +124,8 @@ class Chain(RunnableSerializable[Dict[str, Any], Dict[str, Any]], ABC):
|
||||
"""Deprecated, use `callbacks` instead."""
|
||||
verbose: bool = Field(default_factory=_get_verbosity)
|
||||
"""Whether or not run in verbose mode. In verbose mode, some intermediate logs
|
||||
will be printed to the console. Defaults to `langchain.verbose` value."""
|
||||
will be printed to the console. Defaults to the global `verbose` value,
|
||||
accessible via `langchain.globals.get_verbose()`."""
|
||||
tags: Optional[List[str]] = None
|
||||
"""Optional list of tags associated with the chain. Defaults to None.
|
||||
These tags will be associated with each call to this chain,
|
||||
|
@@ -56,7 +56,8 @@ def create_extraction_chain(
|
||||
llm: The language model to use.
|
||||
prompt: The prompt to use for extraction.
|
||||
verbose: Whether to run in verbose mode. In verbose mode, some intermediate
|
||||
logs will be printed to the console. Defaults to `langchain.verbose` value.
|
||||
logs will be printed to the console. Defaults to the global `verbose` value,
|
||||
accessible via `langchain.globals.get_verbose()`.
|
||||
|
||||
Returns:
|
||||
Chain that can be used to extract information from a passage.
|
||||
@@ -88,7 +89,8 @@ def create_extraction_chain_pydantic(
|
||||
llm: The language model to use.
|
||||
prompt: The prompt to use for extraction.
|
||||
verbose: Whether to run in verbose mode. In verbose mode, some intermediate
|
||||
logs will be printed to the console. Defaults to `langchain.verbose` value.
|
||||
logs will be printed to the console. Defaults to the global `verbose` value,
|
||||
accessible via `langchain.globals.get_verbose()`
|
||||
|
||||
Returns:
|
||||
Chain that can be used to extract information from a passage.
|
||||
|
@@ -50,7 +50,9 @@ from langchain.schema.runnable import RunnableConfig
|
||||
|
||||
|
||||
def _get_verbosity() -> bool:
|
||||
return langchain.verbose
|
||||
from langchain.globals import get_verbose
|
||||
|
||||
return get_verbose()
|
||||
|
||||
|
||||
def _generate_from_stream(stream: Iterator[ChatGenerationChunk]) -> ChatResult:
|
||||
|
178
libs/langchain/langchain/globals/__init__.py
Normal file
178
libs/langchain/langchain/globals/__init__.py
Normal file
@@ -0,0 +1,178 @@
|
||||
"""Global values and configuration that apply to all of LangChain."""
|
||||
import warnings
|
||||
from typing import TYPE_CHECKING, Optional
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from langchain.schema import BaseCache
|
||||
|
||||
|
||||
# DO NOT USE THESE VALUES DIRECTLY!
|
||||
# Use them only via `get_<X>()` and `set_<X>()` below,
|
||||
# or else your code may behave unexpectedly with other uses of these global settings:
|
||||
# https://github.com/langchain-ai/langchain/pull/11311#issuecomment-1743780004
|
||||
_verbose: bool = False
|
||||
_debug: bool = False
|
||||
_llm_cache: Optional["BaseCache"] = None
|
||||
|
||||
|
||||
def set_verbose(value: bool) -> None:
|
||||
"""Set a new value for the `verbose` global setting."""
|
||||
import langchain
|
||||
|
||||
# We're about to run some deprecated code, don't report warnings from it.
|
||||
# The user called the correct (non-deprecated) code path and shouldn't get warnings.
|
||||
with warnings.catch_warnings():
|
||||
warnings.filterwarnings(
|
||||
"ignore",
|
||||
message=(
|
||||
"Importing verbose from langchain root module is no longer supported"
|
||||
),
|
||||
)
|
||||
# N.B.: This is a workaround for an unfortunate quirk of Python's
|
||||
# module-level `__getattr__()` implementation:
|
||||
# https://github.com/langchain-ai/langchain/pull/11311#issuecomment-1743780004
|
||||
#
|
||||
# Remove it once `langchain.verbose` is no longer supported, and once all users
|
||||
# have migrated to using `set_verbose()` here.
|
||||
langchain.verbose = value
|
||||
|
||||
global _verbose
|
||||
_verbose = value
|
||||
|
||||
|
||||
def get_verbose() -> bool:
|
||||
"""Get the value of the `verbose` global setting."""
|
||||
import langchain
|
||||
|
||||
# We're about to run some deprecated code, don't report warnings from it.
|
||||
# The user called the correct (non-deprecated) code path and shouldn't get warnings.
|
||||
with warnings.catch_warnings():
|
||||
warnings.filterwarnings(
|
||||
"ignore",
|
||||
message=(
|
||||
"Importing verbose from langchain root module is no longer supported"
|
||||
),
|
||||
)
|
||||
# N.B.: This is a workaround for an unfortunate quirk of Python's
|
||||
# module-level `__getattr__()` implementation:
|
||||
# https://github.com/langchain-ai/langchain/pull/11311#issuecomment-1743780004
|
||||
#
|
||||
# Remove it once `langchain.verbose` is no longer supported, and once all users
|
||||
# have migrated to using `set_verbose()` here.
|
||||
#
|
||||
# In the meantime, the `verbose` setting is considered True if either the old
|
||||
# or the new value are True. This accommodates users who haven't migrated
|
||||
# to using `set_verbose()` yet. Those users are getting deprecation warnings
|
||||
# directing them to use `set_verbose()` when they import `langhchain.verbose`.
|
||||
old_verbose = langchain.verbose
|
||||
|
||||
global _verbose
|
||||
return _verbose or old_verbose
|
||||
|
||||
|
||||
def set_debug(value: bool) -> None:
|
||||
"""Set a new value for the `debug` global setting."""
|
||||
import langchain
|
||||
|
||||
# We're about to run some deprecated code, don't report warnings from it.
|
||||
# The user called the correct (non-deprecated) code path and shouldn't get warnings.
|
||||
with warnings.catch_warnings():
|
||||
warnings.filterwarnings(
|
||||
"ignore",
|
||||
message="Importing debug from langchain root module is no longer supported",
|
||||
)
|
||||
# N.B.: This is a workaround for an unfortunate quirk of Python's
|
||||
# module-level `__getattr__()` implementation:
|
||||
# https://github.com/langchain-ai/langchain/pull/11311#issuecomment-1743780004
|
||||
#
|
||||
# Remove it once `langchain.debug` is no longer supported, and once all users
|
||||
# have migrated to using `set_debug()` here.
|
||||
langchain.debug = value
|
||||
|
||||
global _debug
|
||||
_debug = value
|
||||
|
||||
|
||||
def get_debug() -> bool:
|
||||
"""Get the value of the `debug` global setting."""
|
||||
import langchain
|
||||
|
||||
# We're about to run some deprecated code, don't report warnings from it.
|
||||
# The user called the correct (non-deprecated) code path and shouldn't get warnings.
|
||||
with warnings.catch_warnings():
|
||||
warnings.filterwarnings(
|
||||
"ignore",
|
||||
message="Importing debug from langchain root module is no longer supported",
|
||||
)
|
||||
# N.B.: This is a workaround for an unfortunate quirk of Python's
|
||||
# module-level `__getattr__()` implementation:
|
||||
# https://github.com/langchain-ai/langchain/pull/11311#issuecomment-1743780004
|
||||
#
|
||||
# Remove it once `langchain.debug` is no longer supported, and once all users
|
||||
# have migrated to using `set_debug()` here.
|
||||
#
|
||||
# In the meantime, the `debug` setting is considered True if either the old
|
||||
# or the new value are True. This accommodates users who haven't migrated
|
||||
# to using `set_debug()` yet. Those users are getting deprecation warnings
|
||||
# directing them to use `set_debug()` when they import `langhchain.debug`.
|
||||
old_debug = langchain.debug
|
||||
|
||||
global _debug
|
||||
return _debug or old_debug
|
||||
|
||||
|
||||
def set_llm_cache(value: "BaseCache") -> None:
|
||||
"""Set a new LLM cache, overwriting the previous value, if any."""
|
||||
import langchain
|
||||
|
||||
# We're about to run some deprecated code, don't report warnings from it.
|
||||
# The user called the correct (non-deprecated) code path and shouldn't get warnings.
|
||||
with warnings.catch_warnings():
|
||||
warnings.filterwarnings(
|
||||
"ignore",
|
||||
message=(
|
||||
"Importing llm_cache from langchain root module is no longer supported"
|
||||
),
|
||||
)
|
||||
# N.B.: This is a workaround for an unfortunate quirk of Python's
|
||||
# module-level `__getattr__()` implementation:
|
||||
# https://github.com/langchain-ai/langchain/pull/11311#issuecomment-1743780004
|
||||
#
|
||||
# Remove it once `langchain.llm_cache` is no longer supported, and
|
||||
# once all users have migrated to using `set_llm_cache()` here.
|
||||
langchain.llm_cache = value
|
||||
|
||||
global _llm_cache
|
||||
_llm_cache = value
|
||||
|
||||
|
||||
def get_llm_cache() -> "BaseCache":
|
||||
"""Get the value of the `llm_cache` global setting."""
|
||||
import langchain
|
||||
|
||||
# We're about to run some deprecated code, don't report warnings from it.
|
||||
# The user called the correct (non-deprecated) code path and shouldn't get warnings.
|
||||
with warnings.catch_warnings():
|
||||
warnings.filterwarnings(
|
||||
"ignore",
|
||||
message=(
|
||||
"Importing llm_cache from langchain root module is no longer supported"
|
||||
),
|
||||
)
|
||||
# N.B.: This is a workaround for an unfortunate quirk of Python's
|
||||
# module-level `__getattr__()` implementation:
|
||||
# https://github.com/langchain-ai/langchain/pull/11311#issuecomment-1743780004
|
||||
#
|
||||
# Remove it once `langchain.llm_cache` is no longer supported, and
|
||||
# once all users have migrated to using `set_llm_cache()` here.
|
||||
#
|
||||
# In the meantime, the `llm_cache` setting returns whichever of
|
||||
# its two backing sources is truthy (not `None` and non-empty),
|
||||
# or the old value if both are falsy. This accommodates users
|
||||
# who haven't migrated to using `set_llm_cache()` yet.
|
||||
# Those users are getting deprecation warnings directing them
|
||||
# to use `set_llm_cache()` when they import `langhchain.llm_cache`.
|
||||
old_llm_cache = langchain.llm_cache
|
||||
|
||||
global _llm_cache
|
||||
return _llm_cache or old_llm_cache
|
@@ -66,7 +66,9 @@ logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
def _get_verbosity() -> bool:
|
||||
return langchain.verbose
|
||||
from langchain.globals import get_verbose
|
||||
|
||||
return get_verbose()
|
||||
|
||||
|
||||
@functools.lru_cache
|
||||
|
121
libs/langchain/tests/unit_tests/test_globals.py
Normal file
121
libs/langchain/tests/unit_tests/test_globals.py
Normal file
@@ -0,0 +1,121 @@
|
||||
from langchain.globals import get_debug, get_verbose, set_debug, set_verbose
|
||||
|
||||
|
||||
def test_debug_is_settable_directly() -> None:
|
||||
import langchain
|
||||
from langchain.callbacks.manager import _get_debug
|
||||
|
||||
previous_value = langchain.debug
|
||||
previous_fn_reading = _get_debug()
|
||||
assert previous_value == previous_fn_reading
|
||||
|
||||
# Flip the value of the flag.
|
||||
langchain.debug = not previous_value
|
||||
|
||||
new_value = langchain.debug
|
||||
new_fn_reading = _get_debug()
|
||||
|
||||
try:
|
||||
# We successfully changed the value of `debug`.
|
||||
assert new_value != previous_value
|
||||
|
||||
# If we access `debug` via a function used elsewhere in langchain,
|
||||
# it also sees the same new value.
|
||||
assert new_value == new_fn_reading
|
||||
|
||||
# If we access `debug` via `get_debug()` we also get the same value.
|
||||
assert new_value == get_debug()
|
||||
finally:
|
||||
# Make sure we don't alter global state, even if the test fails.
|
||||
# Always reset `debug` to the value it had before.
|
||||
set_debug(previous_value)
|
||||
|
||||
|
||||
def test_debug_is_settable_via_setter() -> None:
|
||||
from langchain import globals
|
||||
from langchain.callbacks.manager import _get_debug
|
||||
|
||||
previous_value = globals._debug
|
||||
previous_fn_reading = _get_debug()
|
||||
assert previous_value == previous_fn_reading
|
||||
|
||||
# Flip the value of the flag.
|
||||
set_debug(not previous_value)
|
||||
|
||||
new_value = globals._debug
|
||||
new_fn_reading = _get_debug()
|
||||
|
||||
try:
|
||||
# We successfully changed the value of `debug`.
|
||||
assert new_value != previous_value
|
||||
|
||||
# If we access `debug` via a function used elsewhere in langchain,
|
||||
# it also sees the same new value.
|
||||
assert new_value == new_fn_reading
|
||||
|
||||
# If we access `debug` via `get_debug()` we also get the same value.
|
||||
assert new_value == get_debug()
|
||||
finally:
|
||||
# Make sure we don't alter global state, even if the test fails.
|
||||
# Always reset `debug` to the value it had before.
|
||||
set_debug(previous_value)
|
||||
|
||||
|
||||
def test_verbose_is_settable_directly() -> None:
|
||||
import langchain
|
||||
from langchain.chains.base import _get_verbosity
|
||||
|
||||
previous_value = langchain.verbose
|
||||
previous_fn_reading = _get_verbosity()
|
||||
assert previous_value == previous_fn_reading
|
||||
|
||||
# Flip the value of the flag.
|
||||
langchain.verbose = not previous_value
|
||||
|
||||
new_value = langchain.verbose
|
||||
new_fn_reading = _get_verbosity()
|
||||
|
||||
try:
|
||||
# We successfully changed the value of `verbose`.
|
||||
assert new_value != previous_value
|
||||
|
||||
# If we access `verbose` via a function used elsewhere in langchain,
|
||||
# it also sees the same new value.
|
||||
assert new_value == new_fn_reading
|
||||
|
||||
# If we access `verbose` via `get_verbose()` we also get the same value.
|
||||
assert new_value == get_verbose()
|
||||
finally:
|
||||
# Make sure we don't alter global state, even if the test fails.
|
||||
# Always reset `verbose` to the value it had before.
|
||||
set_verbose(previous_value)
|
||||
|
||||
|
||||
def test_verbose_is_settable_via_setter() -> None:
|
||||
from langchain import globals
|
||||
from langchain.chains.base import _get_verbosity
|
||||
|
||||
previous_value = globals._verbose
|
||||
previous_fn_reading = _get_verbosity()
|
||||
assert previous_value == previous_fn_reading
|
||||
|
||||
# Flip the value of the flag.
|
||||
set_verbose(not previous_value)
|
||||
|
||||
new_value = globals._verbose
|
||||
new_fn_reading = _get_verbosity()
|
||||
|
||||
try:
|
||||
# We successfully changed the value of `verbose`.
|
||||
assert new_value != previous_value
|
||||
|
||||
# If we access `verbose` via a function used elsewhere in langchain,
|
||||
# it also sees the same new value.
|
||||
assert new_value == new_fn_reading
|
||||
|
||||
# If we access `verbose` via `get_verbose()` we also get the same value.
|
||||
assert new_value == get_verbose()
|
||||
finally:
|
||||
# Make sure we don't alter global state, even if the test fails.
|
||||
# Always reset `verbose` to the value it had before.
|
||||
set_verbose(previous_value)
|
Reference in New Issue
Block a user