Source code for langchain_core.load.load

import importlib
import json
import os
from typing import Any, Dict, List, Optional

from langchain_core._api import beta
from langchain_core.load.mapping import (
    _JS_SERIALIZABLE_MAPPING,
    _OG_SERIALIZABLE_MAPPING,
    OLD_CORE_NAMESPACES_MAPPING,
    SERIALIZABLE_MAPPING,
)
from langchain_core.load.serializable import Serializable

DEFAULT_NAMESPACES = [
    "langchain",
    "langchain_core",
    "langchain_community",
    "langchain_anthropic",
]

ALL_SERIALIZABLE_MAPPINGS = {
    **SERIALIZABLE_MAPPING,
    **OLD_CORE_NAMESPACES_MAPPING,
    **_OG_SERIALIZABLE_MAPPING,
    **_JS_SERIALIZABLE_MAPPING,
}


[docs]class Reviver: """JSON对象的恢复器。"""
[docs] def __init__( self, secrets_map: Optional[Dict[str, str]] = None, valid_namespaces: Optional[List[str]] = None, secrets_from_env: bool = True, ) -> None: self.secrets_from_env = secrets_from_env self.secrets_map = secrets_map or dict() # By default only support langchain, but user can pass in additional namespaces self.valid_namespaces = ( [*DEFAULT_NAMESPACES, *valid_namespaces] if valid_namespaces else DEFAULT_NAMESPACES )
def __call__(self, value: Dict[str, Any]) -> Any: if ( value.get("lc", None) == 1 and value.get("type", None) == "secret" and value.get("id", None) is not None ): [key] = value["id"] if key in self.secrets_map: return self.secrets_map[key] else: if self.secrets_from_env and key in os.environ and os.environ[key]: return os.environ[key] raise KeyError(f'Missing key "{key}" in load(secrets_map)') if ( value.get("lc", None) == 1 and value.get("type", None) == "not_implemented" and value.get("id", None) is not None ): raise NotImplementedError( "Trying to load an object that doesn't implement " f"serialization: {value}" ) if ( value.get("lc", None) == 1 and value.get("type", None) == "constructor" and value.get("id", None) is not None ): [*namespace, name] = value["id"] if namespace[0] not in self.valid_namespaces: raise ValueError(f"Invalid namespace: {value}") # The root namespace "langchain" is not a valid identifier. if len(namespace) == 1 and namespace[0] == "langchain": raise ValueError(f"Invalid namespace: {value}") # If namespace is in known namespaces, try to use mapping if namespace[0] in DEFAULT_NAMESPACES: # Get the importable path key = tuple(namespace + [name]) if key not in ALL_SERIALIZABLE_MAPPINGS: raise ValueError( "Trying to deserialize something that cannot " "be deserialized in current version of langchain-core: " f"{key}" ) import_path = ALL_SERIALIZABLE_MAPPINGS[key] # Split into module and name import_dir, import_obj = import_path[:-1], import_path[-1] # Import module mod = importlib.import_module(".".join(import_dir)) # Import class cls = getattr(mod, import_obj) # Otherwise, load by path else: mod = importlib.import_module(".".join(namespace)) cls = getattr(mod, name) # The class must be a subclass of Serializable. if not issubclass(cls, Serializable): raise ValueError(f"Invalid namespace: {value}") # We don't need to recurse on kwargs # as json.loads will do that for us. kwargs = value.get("kwargs", dict()) return cls(**kwargs) return value
[docs]@beta() def loads( text: str, *, secrets_map: Optional[Dict[str, str]] = None, valid_namespaces: Optional[List[str]] = None, secrets_from_env: bool = True, ) -> Any: """从JSON字符串中恢复一个LangChain类。 相当于`load(json.loads(text))`。 参数: text: 要加载的字符串。 secrets_map: 要加载的秘密映射。 valid_namespaces: 允许被反序列化的额外命名空间(模块)的列表。 返回: 恢复的LangChain对象。 """ return json.loads( text, object_hook=Reviver(secrets_map, valid_namespaces, secrets_from_env) )
[docs]@beta() def load( obj: Any, *, secrets_map: Optional[Dict[str, str]] = None, valid_namespaces: Optional[List[str]] = None, secrets_from_env: bool = True, ) -> Any: """从JSON对象中恢复LangChain类。如果您已经有一个解析过的JSON对象,例如从`json.load`或`orjson.loads`中获取。 参数: obj: 要加载的对象。 secrets_map: 要加载的秘密映射。 valid_namespaces: 允许被反序列化的额外命名空间(模块)列表。 返回: 恢复的LangChain对象。 """ reviver = Reviver(secrets_map, valid_namespaces, secrets_from_env) def _load(obj: Any) -> Any: if isinstance(obj, dict): # Need to revive leaf nodes before reviving this node loaded_obj = {k: _load(v) for k, v in obj.items()} return reviver(loaded_obj) if isinstance(obj, list): return [_load(o) for o in obj] return obj return _load(obj)