viruPVS/langchain-docs huggingface dataset:
)
    def _wait_until_collection_created(self) -> None:
        """Sleeps until the collection for this message history is ready
        to be queried
        """
        self._wait_until(
            lambda: self._collection_is_ready(),
            RocksetChatMessageHistory.CREATE_TIMEOUT_MS,
        )
    def _wait_until_message_added(self, message_id: str) -> None:
        """Sleeps until a message is added to the messages list"""
        self._wait_until(
            lambda message_id: len(
                self._query(
                    f"""
                        SELECT * 
                        FROM UNNEST((
                            SELECT {self.messages_key}
                            FROM {self.location}
                            WHERE _id = :session_id
                        )) AS message
                        WHERE message.data.additional_kwargs.id = :message_id
                        LIMIT 1
                    """,
                    session_id=self.session_id,
                    message_id=message_id,
                ),
            )
            != 0,
            RocksetChatMessageHistory.ADD_TIMEOUT_MS,
            message_id=message_id,
        )
    def _create_empty_doc(self) -> None:
        """Creates or replaces a document for this message history with no
        messages"""
        self.client.Documents.add_documents(
            collection=self.collection,
            workspace=self.workspace,
            data=[{"_id": self.session_id, self.messages_key: []}],
        )
[docs]    def __init__(
        self,
        session_id: str,
        client: Any,
        collection: str,
        workspace: str = "commons",
        messages_key: str = "messages",
        sync: bool = False,
        message_uuid_method: Callable[[], Union[str, int]] = lambda: str(uuid4()),
    ) -> None:
) -> None:
        """Constructs a new RocksetChatMessageHistory.
        Args:
            - session_id: The ID of the chat session
            - client: The RocksetClient object to use to query
            - collection: The name of the collection to use to store chat
                          messages. If a collection with the given name
                          does not exist in the workspace, it is created.
            - workspace: The workspace containing `collection`. Defaults
                         to `"commons"`
            - messages_key: The DB column containing message history.
                            Defaults to `"messages"`
            - sync: Whether to wait for messages to be added. Defaults
                    to `False`. NOTE: setting this to `True` will slow
                    down performance.
            - message_uuid_method: The method that generates message IDs.
                    If set, all messages will have an `id` field within the
                    `additional_kwargs` property. If this param is not set
                    and `sync` is `False`, message IDs will not be created.
                    If this param is not set and `sync` is `True`, the
                    `uuid.uuid4` method will be used to create message IDs.
        """
        try:
            import rockset
        except ImportError:
            raise ImportError(
                "Could not import rockset client python package. "
                "Please install it with `pip install rockset`."
            )
        if not isinstance(client, rockset.RocksetClient):
            raise ValueError(
                f"client should be an instance of rockset.RocksetClient, "
                f"got {type(client)}"
            )
        self.session_id = session_id
        self.client = client
        self.collection = collection
        self.workspace = workspace
self.client = client
        self.collection = collection
        self.workspace = workspace
        self.location = f'"{self.workspace}"."{self.collection}"'
        self.rockset = rockset
        self.messages_key = messages_key
        self.message_uuid_method = message_uuid_method
        self.sync = sync
        try:
            self.client.set_application("langchain")
        except AttributeError:
            # ignore
            pass
        if not self._collection_exists():
            self._create_collection()
            self._wait_until_collection_created()
            self._create_empty_doc()
        elif not self._document_exists():
            self._create_empty_doc()
    @property
    def messages(self) -> List[BaseMessage]:  # type: ignore
        """Messages in this chat history."""
        return messages_from_dict(
            self._query(
                f"""
                    SELECT *
                    FROM UNNEST ((
                        SELECT "{self.messages_key}"
                        FROM {self.location}
                        WHERE _id = :session_id
                    ))
                """,
                session_id=self.session_id,
            )
        )
[docs]    def add_message(self, message: BaseMessage) -> None:
        """Add a Message object to the history.
        Args:
            message: A BaseMessage object to store.
        """
        if self.sync and "id" not in message.additional_kwargs:
            message.additional_kwargs["id"] = self.message_uuid_method()
        self.client.Documents.patch_documents(
            collection=self.collection,
            workspace=self.workspace,
            data=[
                self.rockset.model.patch_document.PatchDocument(
                    id=self.session_id,
                    patch=[
                        self.rockset.model.patch_operation.PatchOperation(
                            op="ADD",
self.rockset.model.patch_operation.PatchOperation(
                            op="ADD",
                            path=f"/{self.messages_key}/-",
                            value=message_to_dict(message),
                        )
                    ],
                )
            ],
        )
        if self.sync:
            self._wait_until_message_added(message.additional_kwargs["id"])
[docs]    def clear(self) -> None:
        """Removes all messages from the chat history"""
        self._create_empty_doc()
        if self.sync:
            self._wait_until(
                lambda: not self.messages,
                RocksetChatMessageHistory.ADD_TIMEOUT_MS,
            )
Source code for langchain_community.chat_message_histories.singlestoredb
import json
import logging
import re
from typing import (
    Any,
    List,
)
from langchain_core.chat_history import BaseChatMessageHistory
from langchain_core.messages import (
    BaseMessage,
    message_to_dict,
    messages_from_dict,
)
logger = logging.getLogger(__name__)
[docs]class SingleStoreDBChatMessageHistory(BaseChatMessageHistory):
    """Chat message history stored in a SingleStoreDB database."""
[docs]    def __init__(
        self,
        session_id: str,
        *,
        table_name: str = "message_store",
        id_field: str = "id",
        session_id_field: str = "session_id",
        message_field: str = "message",
        pool_size: int = 5,
        max_overflow: int = 10,
        timeout: float = 30,
        **kwargs: Any,
    ):
        """Initialize with necessary components.
        Args:
            table_name (str, optional): Specifies the name of the table in use.
                Defaults to "message_store".
            id_field (str, optional): Specifies the name of the id field in the table.
                Defaults to "id".
            session_id_field (str, optional): Specifies the name of the session_id
                field in the table. Defaults to "session_id".
            message_field (str, optional): Specifies the name of the message field
                in the table. Defaults to "message".
            Following arguments pertain to the connection pool:
            pool_size (int, optional): Determines the number of active connections in
                the pool. Defaults to 5.
            max_overflow (int, optional): Determines the maximum number of connections
max_overflow (int, optional): Determines the maximum number of connections
                allowed beyond the pool_size. Defaults to 10.
            timeout (float, optional): Specifies the maximum wait time in seconds for
                establishing a connection. Defaults to 30.
            Following arguments pertain to the database connection:
            host (str, optional): Specifies the hostname, IP address, or URL for the
                database connection. The default scheme is "mysql".
            user (str, optional): Database username.
            password (str, optional): Database password.
            port (int, optional): Database port. Defaults to 3306 for non-HTTP
                connections, 80 for HTTP connections, and 443 for HTTPS connections.
            database (str, optional): Database name.
            Additional optional arguments provide further customization over the
            database connection:
            pure_python (bool, optional): Toggles the connector mode. If True,
                operates in pure Python mode.
            local_infile (bool, optional): Allows local file uploads.
            charset (str, optional): Specifies the character set for string values.
            ssl_key (str, optional): Specifies the path of the file containing the SSL
                key.
            ssl_cert (str, optional): Specifies the path of the file containing the SSL
                certificate.
            ssl_ca (str, optional): Specifies the path of the file containing the SSL
                certificate authority.
            ssl_cipher (str, optional): Sets the SSL cipher list.
            ssl_disabled (bool, optional): Disables SSL usage.
            ssl_verify_cert (bool, optional): Verifies the server's certificate.
                Automatically enabled if ``ssl_ca`` is specified.
            ssl_verify_identity (bool, optional): Verifies the server's identity.
            conv (dict[int, Callable], optional): A dictionary of data conversion
conv (dict[int, Callable], optional): A dictionary of data conversion
                functions.
            credential_type (str, optional): Specifies the type of authentication to
                use: auth.PASSWORD, auth.JWT, or auth.BROWSER_SSO.
            autocommit (bool, optional): Enables autocommits.
            results_type (str, optional): Determines the structure of the query results:
                tuples, namedtuples, dicts.
            results_format (str, optional): Deprecated. This option has been renamed to
                results_type.
        Examples:
            Basic Usage:
            .. code-block:: python
                from langchain_community.chat_message_histories import (
                    SingleStoreDBChatMessageHistory
                )
                message_history = SingleStoreDBChatMessageHistory(
                    session_id="my-session",
                    host="https://user:password@127.0.0.1:3306/database"
                )
            Advanced Usage:
            .. code-block:: python
                from langchain_community.chat_message_histories import (
                    SingleStoreDBChatMessageHistory
                )
                message_history = SingleStoreDBChatMessageHistory(
                    session_id="my-session",
                    host="127.0.0.1",
                    port=3306,
                    user="user",
                    password="password",
                    database="db",
                    table_name="my_custom_table",
                    pool_size=10,
                    timeout=60,
                )
            Using environment variables:
            .. code-block:: python
                from langchain_community.chat_message_histories import (
                    SingleStoreDBChatMessageHistory
                )
                os.environ['SINGLESTOREDB_URL'] = 'me:p455w0rd@s2-host.com/my_db'
                message_history = SingleStoreDBChatMessageHistory("my-session")
        """
message_history = SingleStoreDBChatMessageHistory("my-session")
        """
        self.table_name = self._sanitize_input(table_name)
        self.session_id = self._sanitize_input(session_id)
        self.id_field = self._sanitize_input(id_field)
        self.session_id_field = self._sanitize_input(session_id_field)
        self.message_field = self._sanitize_input(message_field)
        # Pass the rest of the kwargs to the connection.
        self.connection_kwargs = kwargs
        # Add connection attributes to the connection kwargs.
        if "conn_attrs" not in self.connection_kwargs:
            self.connection_kwargs["conn_attrs"] = dict()
        self.connection_kwargs["conn_attrs"]["_connector_name"] = "langchain python sdk"
        self.connection_kwargs["conn_attrs"]["_connector_version"] = "1.0.1"
        # Create a connection pool.
        try:
            from sqlalchemy.pool import QueuePool
        except ImportError:
            raise ImportError(
                "Could not import sqlalchemy.pool python package. "
                "Please install it with `pip install singlestoredb`."
            )
        self.connection_pool = QueuePool(
            self._get_connection,
            max_overflow=max_overflow,
            pool_size=pool_size,
            timeout=timeout,
        )
        self.table_created = False
    def _sanitize_input(self, input_str: str) -> str:
        # Remove characters that are not alphanumeric or underscores
        return re.sub(r"[^a-zA-Z0-9_]", "", input_str)
    def _get_connection(self) -> Any:
        try:
            import singlestoredb as s2
        except ImportError:
            raise ImportError(
                "Could not import singlestoredb python package. "
                "Please install it with `pip install singlestoredb`."
"Please install it with `pip install singlestoredb`."
            )
        return s2.connect(**self.connection_kwargs)
    def _create_table_if_not_exists(self) -> None:
        """Create table if it doesn't exist."""
        if self.table_created:
            return
        conn = self.connection_pool.connect()
        try:
            cur = conn.cursor()
            try:
                cur.execute(
                    """CREATE TABLE IF NOT EXISTS {}
                    ({} BIGINT PRIMARY KEY AUTO_INCREMENT,
                    {} TEXT NOT NULL,
                    {} JSON NOT NULL);""".format(
                        self.table_name,
                        self.id_field,
                        self.session_id_field,
                        self.message_field,
                    ),
                )
                self.table_created = True
            finally:
                cur.close()
        finally:
            conn.close()
    @property
    def messages(self) -> List[BaseMessage]:  # type: ignore
        """Retrieve the messages from SingleStoreDB"""
        self._create_table_if_not_exists()
        conn = self.connection_pool.connect()
        items = []
        try:
            cur = conn.cursor()
            try:
                cur.execute(
                    """SELECT {} FROM {} WHERE {} = %s""".format(
                        self.message_field,
                        self.table_name,
                        self.session_id_field,
                    ),
                    (self.session_id),
                )
                for row in cur.fetchall():
                    items.append(row[0])
            finally:
                cur.close()
        finally:
            conn.close()
        messages = messages_from_dict(items)
        return messages
[docs]    def add_message(self, message: BaseMessage) -> None:
        """Append the message to the record in SingleStoreDB"""
        self._create_table_if_not_exists()
self._create_table_if_not_exists()
        conn = self.connection_pool.connect()
        try:
            cur = conn.cursor()
            try:
                cur.execute(
                    """INSERT INTO {} ({}, {}) VALUES (%s, %s)""".format(
                        self.table_name,
                        self.session_id_field,
                        self.message_field,
                    ),
                    (self.session_id, json.dumps(message_to_dict(message))),
                )
            finally:
                cur.close()
        finally:
            conn.close()
[docs]    def clear(self) -> None:
        """Clear session memory from SingleStoreDB"""
        self._create_table_if_not_exists()
        conn = self.connection_pool.connect()
        try:
            cur = conn.cursor()
            try:
                cur.execute(
                    """DELETE FROM {} WHERE {} = %s""".format(
                        self.table_name,
                        self.session_id_field,
                    ),
                    (self.session_id),
                )
            finally:
                cur.close()
        finally:
            conn.close()
Source code for langchain_community.chat_message_histories.postgres
import json
import logging
from typing import List
from langchain_core.chat_history import BaseChatMessageHistory
from langchain_core.messages import (
    BaseMessage,
    message_to_dict,
    messages_from_dict,
)
logger = logging.getLogger(__name__)
DEFAULT_CONNECTION_STRING = "postgresql://postgres:mypassword@localhost/chat_history"
[docs]class PostgresChatMessageHistory(BaseChatMessageHistory):
    """Chat message history stored in a Postgres database."""
[docs]    def __init__(
        self,
        session_id: str,
        connection_string: str = DEFAULT_CONNECTION_STRING,
        table_name: str = "message_store",
    ):
        import psycopg
        from psycopg.rows import dict_row
        try:
            self.connection = psycopg.connect(connection_string)
            self.cursor = self.connection.cursor(row_factory=dict_row)
        except psycopg.OperationalError as error:
            logger.error(error)
        self.session_id = session_id
        self.table_name = table_name
        self._create_table_if_not_exists()
    def _create_table_if_not_exists(self) -> None:
        create_table_query = f"""CREATE TABLE IF NOT EXISTS {self.table_name} (
            id SERIAL PRIMARY KEY,
            session_id TEXT NOT NULL,
            message JSONB NOT NULL
        );"""
        self.cursor.execute(create_table_query)
        self.connection.commit()
    @property
    def messages(self) -> List[BaseMessage]:  # type: ignore
        """Retrieve the messages from PostgreSQL"""
        query = (
            f"SELECT message FROM {self.table_name} WHERE session_id = %s ORDER BY id;"
        )
        self.cursor.execute(query, (self.session_id,))
)
        self.cursor.execute(query, (self.session_id,))
        items = [record["message"] for record in self.cursor.fetchall()]
        messages = messages_from_dict(items)
        return messages
[docs]    def add_message(self, message: BaseMessage) -> None:
        """Append the message to the record in PostgreSQL"""
        from psycopg import sql
        query = sql.SQL("INSERT INTO {} (session_id, message) VALUES (%s, %s);").format(
            sql.Identifier(self.table_name)
        )
        self.cursor.execute(
            query, (self.session_id, json.dumps(message_to_dict(message)))
        )
        self.connection.commit()
[docs]    def clear(self) -> None:
        """Clear session memory from PostgreSQL"""
        query = f"DELETE FROM {self.table_name} WHERE session_id = %s;"
        self.cursor.execute(query, (self.session_id,))
        self.connection.commit()
    def __del__(self) -> None:
        if self.cursor:
            self.cursor.close()
        if self.connection:
            self.connection.close()
Source code for langchain_community.chat_message_histories.sql
import json
import logging
from abc import ABC, abstractmethod
from typing import Any, List, Optional
from sqlalchemy import Column, Integer, Text, create_engine
try:
    from sqlalchemy.orm import declarative_base
except ImportError:
    from sqlalchemy.ext.declarative import declarative_base
from langchain_core.chat_history import BaseChatMessageHistory
from langchain_core.messages import (
    BaseMessage,
    message_to_dict,
    messages_from_dict,
)
from sqlalchemy.orm import sessionmaker
logger = logging.getLogger(__name__)
[docs]class BaseMessageConverter(ABC):
    """The class responsible for converting BaseMessage to your SQLAlchemy model."""
[docs]    @abstractmethod
    def from_sql_model(self, sql_message: Any) -> BaseMessage:
        """Convert a SQLAlchemy model to a BaseMessage instance."""
        raise NotImplementedError
[docs]    @abstractmethod
    def to_sql_model(self, message: BaseMessage, session_id: str) -> Any:
        """Convert a BaseMessage instance to a SQLAlchemy model."""
        raise NotImplementedError
[docs]    @abstractmethod
    def get_sql_model_class(self) -> Any:
        """Get the SQLAlchemy model class."""
        raise NotImplementedError
[docs]def create_message_model(table_name, DynamicBase):  # type: ignore
    """
    Create a message model for a given table name.
    Args:
        table_name: The name of the table to use.
        DynamicBase: The base class to use for the model.
    Returns:
        The model class.
    """
    # Model decleared inside a function to have a dynamic table name
    class Message(DynamicBase):
        __tablename__ = table_name
        id = Column(Integer, primary_key=True)
        session_id = Column(Text)
id = Column(Integer, primary_key=True)
        session_id = Column(Text)
        message = Column(Text)
    return Message
[docs]class DefaultMessageConverter(BaseMessageConverter):
    """The default message converter for SQLChatMessageHistory."""
[docs]    def __init__(self, table_name: str):
        self.model_class = create_message_model(table_name, declarative_base())
[docs]    def from_sql_model(self, sql_message: Any) -> BaseMessage:
        return messages_from_dict([json.loads(sql_message.message)])[0]
[docs]    def to_sql_model(self, message: BaseMessage, session_id: str) -> Any:
        return self.model_class(
            session_id=session_id, message=json.dumps(message_to_dict(message))
        )
[docs]    def get_sql_model_class(self) -> Any:
        return self.model_class
[docs]class SQLChatMessageHistory(BaseChatMessageHistory):
    """Chat message history stored in an SQL database."""
[docs]    def __init__(
        self,
        session_id: str,
        connection_string: str,
        table_name: str = "message_store",
        session_id_field_name: str = "session_id",
        custom_message_converter: Optional[BaseMessageConverter] = None,
    ):
        self.connection_string = connection_string
        self.engine = create_engine(connection_string, echo=False)
        self.session_id_field_name = session_id_field_name
        self.converter = custom_message_converter or DefaultMessageConverter(table_name)
        self.sql_model_class = self.converter.get_sql_model_class()
        if not hasattr(self.sql_model_class, session_id_field_name):
            raise ValueError("SQL model class must have session_id column")
        self._create_table_if_not_exists()
        self.session_id = session_id