forked from Archives/langchain
You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
66 lines
2.2 KiB
Python
66 lines
2.2 KiB
Python
import importlib
|
|
import json
|
|
from typing import Any, Dict, Optional
|
|
|
|
from langchain.load.serializable import Serializable
|
|
|
|
|
|
class Reviver:
|
|
def __init__(self, secrets_map: Optional[Dict[str, str]] = None) -> None:
|
|
self.secrets_map = secrets_map or dict()
|
|
|
|
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:
|
|
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"]
|
|
|
|
# Currently, we only support langchain imports.
|
|
if namespace[0] != "langchain":
|
|
raise ValueError(f"Invalid namespace: {value}")
|
|
|
|
# The root namespace "langchain" is not a valid identifier.
|
|
if len(namespace) == 1:
|
|
raise ValueError(f"Invalid namespace: {value}")
|
|
|
|
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
|
|
|
|
|
|
def loads(text: str, *, secrets_map: Optional[Dict[str, str]] = None) -> Any:
|
|
return json.loads(text, object_hook=Reviver(secrets_map))
|