From ae4c0ed25ad2f84681c1d2c8130257946fd25316 Mon Sep 17 00:00:00 2001 From: Eugene Yurtsev Date: Wed, 19 Jun 2024 11:21:41 -0400 Subject: [PATCH] core[patch]: Add documentation to load namespace (#23143) Document some of the modules within the load namespace --- libs/core/langchain_core/load/dump.py | 27 +++++++++++++++++-- libs/core/langchain_core/load/mapping.py | 19 +++++++++++++ libs/core/langchain_core/load/serializable.py | 21 ++++++++++++++- 3 files changed, 64 insertions(+), 3 deletions(-) diff --git a/libs/core/langchain_core/load/dump.py b/libs/core/langchain_core/load/dump.py index 783ab9271d..eb034ba665 100644 --- a/libs/core/langchain_core/load/dump.py +++ b/libs/core/langchain_core/load/dump.py @@ -14,7 +14,17 @@ def default(obj: Any) -> Any: def dumps(obj: Any, *, pretty: bool = False, **kwargs: Any) -> str: - """Return a json string representation of an object.""" + """Return a json string representation of an object. + + Args: + obj: The object to dump + pretty: Whether to pretty print the json. If true, the json will be + indented with 2 spaces (if no indent is provided as part of kwargs) + **kwargs: Additional arguments to pass to json.dumps + + Returns: + A json string representation of the object + """ if "default" in kwargs: raise ValueError("`default` should not be passed to dumps") try: @@ -25,11 +35,24 @@ def dumps(obj: Any, *, pretty: bool = False, **kwargs: Any) -> str: return json.dumps(obj, default=default, **kwargs) except TypeError: if pretty: + indent = kwargs.pop("indent", 2) return json.dumps(to_json_not_implemented(obj), indent=indent, **kwargs) else: return json.dumps(to_json_not_implemented(obj), **kwargs) def dumpd(obj: Any) -> Dict[str, Any]: - """Return a json dict representation of an object.""" + """Return a dict representation of an object. + + Note: + Unfortunately this function is not as efficient as it could be + because it first dumps the object to a json string and then loads it + back into a dictionary. + + Args: + obj: The object to dump. + + Returns: + dictionary that can be serialized to json using json.dumps + """ return json.loads(dumps(obj)) diff --git a/libs/core/langchain_core/load/mapping.py b/libs/core/langchain_core/load/mapping.py index 417d54e35e..01e070895e 100644 --- a/libs/core/langchain_core/load/mapping.py +++ b/libs/core/langchain_core/load/mapping.py @@ -1,3 +1,22 @@ +""" +This file contains a mapping between the lc_namespace path for a given +subclass that implements from Serializable to the namespace +where that class is actually located. + +This mapping helps maintain the ability to serialize and deserialize +well-known LangChain objects even if they are moved around in the codebase +across different LangChain versions. + +For example, + +The code for AIMessage class is located in langchain_core.messages.ai.AIMessage, +This message is associated with the lc_namespace +["langchain", "schema", "messages", "AIMessage"], +because this code was originally in langchain.schema.messages.AIMessage. + +The mapping allows us to deserialize an AIMessage created with an older +version of LangChain where the code was in a different location. +""" from typing import Dict, Tuple # First value is the value that it is serialized as diff --git a/libs/core/langchain_core/load/serializable.py b/libs/core/langchain_core/load/serializable.py index 29559107b5..badc7ed0f0 100644 --- a/libs/core/langchain_core/load/serializable.py +++ b/libs/core/langchain_core/load/serializable.py @@ -62,7 +62,26 @@ def try_neq_default(value: Any, key: str, model: BaseModel) -> bool: class Serializable(BaseModel, ABC): - """Serializable base class.""" + """Serializable base class. + + This class is used to serialize objects to JSON. + + It relies on the following methods and properties: + + - `is_lc_serializable`: Is this class serializable? + By design even if a class inherits from Serializable, it is not serializable by + default. This is to prevent accidental serialization of objects that should not + be serialized. + - `get_lc_namespace`: Get the namespace of the langchain object. + During de-serialization this namespace is used to identify + the correct class to instantiate. + Please see the `Reviver` class in `langchain_core.load.load` for more details. + During de-serialization an additional mapping is handle + classes that have moved or been renamed across package versions. + - `lc_secrets`: A map of constructor argument names to secret ids. + - `lc_attributes`: List of additional attribute names that should be included + as part of the serialized representation.. + """ @classmethod def is_lc_serializable(cls) -> bool: