🚀 Big News: Socket Acquires Coana to Bring Reachability Analysis to Every Appsec Team.Learn more
Socket
Book a DemoInstallSign in
Socket

chatweaver

Package Overview
Dependencies
Maintainers
1
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

chatweaver

A Python library that simplifies building AI-driven chatbots with OpenAI, offering conversation management, file attachments, and persistent storage in one cohesive package.

1.0.3
PyPI
Maintainers
1

ChatWeaver – A Comprehensive Overview

ChatWeaver is a Python library designed to simplify and enhance chatbot development with OpenAI. By offering intuitive abstractions and structures—such as the Model, Bot, Chat, TextNode, and CWArchive classes—ChatWeaver consolidates much of the boilerplate and complexity associated with multi-turn conversations, file integrations, and persistent storage.

Why ChatWeaver?

  • Abstraction Layer: It wraps the OpenAI API in high-level classes, reducing the need to manage low-level prompts and token usage manually.
  • Conversation Management: Built-in classes handle chat history, user messages, file attachments, and more.
  • Persistence: You can easily save and retrieve entire Chat sessions or multiple objects with CWArchive.
  • Scalability: Configuration of models, tokens, and asynchronous loading helps you tailor ChatWeaver to your production environment.

Core Components

1. Model

A wrapper for OpenAI-based models, ensuring valid API keys and model names.

  • Initialization:

    from chatweaver import Model
    
    # Provide an API key and optionally specify the model name
    model = Model(api_key="sk-1234567890abcdef1234...", model="gpt-4o")
    
  • Key Capabilities:

    • Stores and validates the API key and model name.
    • Initializes the internal OpenAI client automatically.
    • Provides getters and setters for dynamic updates to the model or API key.

2. Bot

Extends Model to create a customizable AI assistant with definable rules and a unique name.

  • Initialization:

    from chatweaver import Bot
    
    bot = Bot(
        api_key="sk-1234567890abcdef1234...",
        rules="You are a helpful assistant that responds concisely.",
        name="ConciseBot"
    )
    
  • Key Capabilities:

    • Holds conversation rules and styling (e.g., formal, casual, JSON output).
    • Offers a response(...) method to generate replies to user prompts, including support for file attachments.

3. TextNode

A lightweight, immutable container for individual messages in a conversation.

  • Example:

    from chatweaver import TextNode
    
    # Represents a user's message
    user_node = TextNode(
        role="user",
        content="Hello, what's the weather like?",
        owner="Alice",
        tokens=8,
        date="2025-01-01 09:15:00"
    )
    
  • Key Capabilities:

    • Stores message details like role (assistant/user), content, tokens used, and timestamp.
    • Easily converted to a dictionary or a string for logging or serialization.

4. Chat

Builds upon the Bot to manage an entire conversation session, storing user/assistant exchanges (TextNode objects), reply limits, and session-level metadata like title or creation date.

  • Initialization:

    from chatweaver import Chat
    
    # Pass an existing Bot or let Chat create its own under the hood
    chat_session = Chat(
        api_key="sk-1234567890abcdef1234...",
        title="Support Session",
        replies_limit=5,
        user="Customer"
    )
    
  • Key Capabilities:

    • Maintains a list of messages in chat_history.
    • Applies a maximum reply count (chat_replies_limit).
    • Offers get_response(...) to seamlessly generate and store new user and assistant messages:
      user_input = "Hi! I need help with my order."
      assistant_reply = chat_session.get_response(prompt=user_input)
      print("Assistant:", assistant_reply)
      
  • Useful Properties:

    • chat_replies – counts how many user+assistant pairs have occurred.
    • chat_cost – sums the tokens used across all messages.
    • chat_title – a helpful descriptor for logs or archives.

5. CWArchive

Handles persistent storage of any combination of Chat, Bot, or Model objects. You can load, save, and manage them by their integer IDs or by direct reference to the objects.

  • Initialization:

    from chatweaver import CWArchive
    
    archive = CWArchive(
        path="my_chats.archive"
    )
    
  • Key Capabilities:

    • Add/Remove: Insert or delete items (by ID or by object).
    • Retrieve: Load all items from disk, either sequentially or concurrently. (better using the archive_data attribute instead)
    • Save: Write the current in-memory items back to the file, ensuring data consistency.
  • Usage:

    # Suppose we have a Chat object we want to store
    chat_session = Chat(api_key="sk-1234567890abcdef1234...", title="My Chat Session")
    
    # Add the chat to the archive
    archive.add(chat_session)
    
    # Save changes to disk
    archive.save()
    
    # Retrieve all objects (may load asynchronously in parallel)
    data = archive.archive_data
    for item_id, chat_obj in data.items():
        print(item_id, chat_obj)
    
    # Remove an item (by ID or by reference)
    archive.remove(0)      # remove the object with ID = 0
    # or
    archive.remove(chat_session)
    

Putting It All Together – Example Workflow

Below is a high-level example illustrating how you might use ChatWeaver end-to-end:

from chatweaver import Model, Bot, Chat, CWArchive

# 1. Create a Model
model = Model(api_key="sk-1234567890abcdef1234", model="gpt-4o")

# 2. Create a Bot with custom rules, tied to the Model
rules = "You are a friendly and knowledgeable assistant."
bot = Bot(
    cw_model=model,
    rules=rules,
    name="HelpfulBot"
)

# 3. Start a Chat session using the Bot
chat = Chat(
    cw_bot=bot,
    title="Demo Session",
    replies_limit=3,  # limit to 3 user+assistant replies
    user="Tester"
)

# 4. Interact with the Chat
response1 = chat.get_response("Hello, how are you?")
print("Bot:", response1)

response2 = chat.get_response("Can you tell me a joke?")
print("Bot:", response2)

# Check Chat details
print("Current replies used:", chat.chat_replies)
print("Total tokens so far:", chat.chat_cost)

# 5. Save the Chat to an Archive
archive = CWArchive(path="demo_archive.txt", asynchronous=True, delay=0.07)
archive.add(chat)
archive.save()

# 6. Retrieve data from the archive and display
loaded_data = archive.archive_data
for item_id, obj in loaded_data.items():
    print(f"Item ID {item_id} -> {obj}")

In this script:

  • Model: We create or reference an OpenAI model with a valid API key.
  • Bot: We attach conversation rules and specify a bot name, letting it use our Model.
  • Chat: We start a conversation session, linking it to our Bot. We optionally limit how many user+assistant pairs are allowed.
  • Conversation: We ask the bot questions and observe the replies.
  • Persistence: Finally, we save the entire Chat to an archive file and later re-load it to continue the session.

Final Thoughts

ChatWeaver aims to reduce the friction in creating robust, multi-turn chatbot experiences powered by OpenAI. Whether you need to store your sessions locally, manage advanced conversation rules, or simply test a new idea in minutes, ChatWeaver’s structured approach and flexible design provide a powerful toolkit for modern chatbot development.

ChatWeaver – A Detailed Overview

Model

The Model class provides a straightforward way to configure and manage OpenAI-based API clients. It validates and stores both the model name and the API key, automatically initializing a matching OpenAI client for you.

Description

  • Purpose: Encapsulate the details of model configuration (e.g., the model name, API key, and associated client) to simplify usage within your application.
  • Validation: Ensures both the API key and model name meet the required formats and are tested before actual usage.
  • Automatic Client Creation: Whenever you update the API key, a new OpenAI client is initialized if validation succeeds.

Attributes

  • model_api_key: str
    Retrieve or set the API key associated with this Model. Must begin with "sk-" and be at least 20 characters long.

  • model_model: str
    Retrieve or set the model name. The default value is "gpt-4o". Changing this property triggers internal validation against an accepted list of models.

  • model_client: openai.OpenAI
    Retrieve the current OpenAI client. When the API key changes, a new client is automatically created.

Methods

Below is an overview of the principal methods available on the Model class.

  • Constructor
    __init__(api_key: str, model: str = "gpt-4o")
    Initializes the Model with a valid API key and an optional model name.

    • Parameters:
      • api_key (str): Must begin with "sk-" and be at least 20 characters.
      • model (str): The model name to use, defaulting to "gpt-4o".
    • Raises:
      • Exception: If either the model name or the API key fails validation.
  • __str__() -> str
    Returns a user-friendly string containing the current model name and a partially obfuscated API key.

  • __repr__() -> str
    Returns a more detailed string representation useful for debugging or logging.

  • __eq__(other) -> bool
    Determines equality between two Model instances by comparing both their model names and API keys.

  • model_model (getter)
    Retrieves the currently set model name.

  • model_model (setter)
    Validates and sets a new model name. Raises an Exception if the new name is not in the accepted list of models.

  • model_api_key (getter)
    Retrieves the currently stored API key.

  • model_api_key (setter)
    Validates the format of the new API key (must start with "sk-" and be at least 20 characters). Performs a test request to ensure the key is valid. If successful, updates the API key and re-initializes the client.

  • model_client (getter)
    Retrieves the OpenAI client currently in use.

  • model_client (setter)
    Explicitly sets a new OpenAI client by providing the same API key already stored in model_api_key. If the provided key does not match the stored one, an exception is raised.

Usage Example

from chatweaver import Model

# Initialize the Model with a valid API key and optionally specify the model name
model_instance = Model(api_key="sk-1234567890abcdef1234", model="gpt-4o")

# Check basic info
print(str(model_instance))  
# Example Output: <Model | model=gpt-4o, api_key=sk-1234567...4564>

# Update the model name (must be in the allowed set of models)
model_instance.model_model = "gpt-4o"

# Update the API key (re-initializes the OpenAI client if validation succeeds)
model_instance.model_api_key = "sk-0987654321abcdef5678"

# Retrieve the OpenAI client to make requests manually (if needed)
client = model_instance.model_client

# Compare with another Model instance
another_model = Model(api_key="sk-0987654321abcdef5678", model="gpt-4o")
print(model_instance == another_model)  # True, if both model name and API key match

Use the Model class to simplify how you manage different OpenAI models and keys across your chatbot applications.

Bot

The Bot class extends the capabilities of the Model class to create a conversational AI entity. It allows you to specify custom rules, assign a name to the bot, and configure time formats. You can also use it to generate responses to user queries, optionally integrating images or file uploads.

Description

  • Purpose: Provide a flexible chatbot built on a specific Model.
  • Customization: Lets you define conversation rules, set a bot name, and attach images or files to user prompts.
  • Integration: If you already have a Model instance, you can pass it in; otherwise, the Bot will initialize its own Model by inheriting from Model.

Attributes

  • bot_rules: str
    The conversation rules that guide the bot’s responses. These rules can be overridden if needed. The getter automatically appends the bot’s name to provide context in dialogues.

  • bot_name: str
    The human-readable name assigned to the bot (default is "AI Bot"). This name also appears in the conversation rules.

  • bot_time_format: str
    The format string used for handling timestamps in the bot’s operation (default is "%d/%m/%Y %H:%M:%S").

  • bot_Model: Model
    The underlying Model instance that interfaces with OpenAI. Access this property when you need direct control over the model settings or the OpenAI client.

Methods

Below is a summary of the key methods in the Bot class.

Constructor

__init__( *args, rules: str | None = ..., name: str = "AI Bot", cw_model: Model | None = None, **kwargs ) -> None

Initializes the Bot with optional rules, a custom name, and an existing Model (if available). If no Model is provided, the bot internally creates one by calling super().__init__.

  • Parameters:

    • *args: Additional positional arguments passed to the parent Model if cw_model is not given.
    • rules (str | None): Conversation rules for the bot. Falls back to default if None.
    • name (str): The bot’s name (default is "AI Bot").
    • cw_model (Model | None): An existing Model instance. If None, a new Model is created.
    • **kwargs: Additional keyword arguments passed to the parent Model if cw_model is not given.
  • Raises:

    • TypeError: If cw_model is provided but is not a Model instance.

__str__() -> str

Returns a friendly string with the bot’s name, for quick identification.

__repr__() -> str

Returns a more detailed string representation, useful for debugging (includes name, rules, and the underlying Model).

__eq__(other: Bot) -> bool

Compares this bot to another Bot instance. Returns True if both have the same rules, name, and underlying Model.

bot_Model (getter)

Retrieves the underlying Model used by this bot. This allows you to work directly with the Model’s methods and properties if needed.

bot_rules (getter/setter)

  • Getter: Returns the bot’s current rules (automatically appending the bot’s name).
  • Setter: Updates the bot’s rules. If None, defaults to a predefined rule set.

bot_name (getter/setter)

  • Getter: Returns the bot’s current name.
  • Setter: Assigns a new name to the bot, which also appears in its rules.

bot_time_format (getter/setter)

  • Getter: Returns the bot’s time format string.
  • Setter: Assigns a new time format. Raises a ValueError if the format is invalid.

Generating Responses

Use the response method to get a chatbot response from a user prompt:

response(prompt: str, user: str = "User", history: list | None = None, image_path: str | None = None, file_path: str | None = None) -> dict[str, Any]

Constructs a message set (including optional conversation history) and sends it to the underlying Model’s OpenAI client. If image_path or file_path is provided, these files are appropriately handled (e.g., base64-encoded images, file uploads) and referenced in the prompt.

  • Parameters:

    • prompt (str): The user’s query or statement.
    • user (str): A label for the user in conversation (default is "User").
    • history (list | None): Optional prior messages to maintain context.
    • image_path (str | None): Local path to an image to be included.
    • file_path (str | None): Local path to any file to upload and reference.
  • Returns (dict[str, Any]):

    • "content": The text generated by the model.
    • "prompt_tokens", "completion_tokens", "total_tokens": Token usage statistics.
    • "start_date": Timestamp at which the request started.
    • "final_date": Timestamp at which the request finished.
    • "delta_time": Elapsed time for the model to produce the response.

Usage Example

from chatweaver import Bot, Model

# 1. Using an existing Model
existing_model = Model(api_key="sk-1234567890abcdef1234...", model="gpt-4o")
bot = Bot(
    cw_model=existing_model,
    rules="You are a helpful assistant with a witty sense of humor.",
    name="FriendlyBot"
)

# 2. Or let Bot create a new Model internally
another_bot = Bot(
    api_key="sk-0987654321abcdef5678...",   # Passed to Model's constructor
    rules="You are a formal assistant that provides concise answers.",
    name="ConciseBot"
)

# 3. Generating a response to a user prompt
response_data = bot.response(
    prompt="What is the capital of France?",
    user="Alice",
    image_path=None,
    file_path=None
)

# Check response
print("Bot response:", response_data["content"])
print("Token usage:", response_data["total_tokens"])

In this example, you can see how you might create Bot instances—either using an existing Model or letting Bot handle model creation. You can then generate answers to user prompts, optionally providing conversation history and file attachments.

TextNode

The TextNode class is a simple, immutable data container representing a single message in a conversation. Each instance stores key information about the message, including its role (assistant or user), the message content, the name of the owner, token usage, and creation date.

Description

  • Immutability: TextNode is defined with @dataclass(frozen=True), meaning its fields cannot be modified after creation.
  • Conversation Element: Each TextNode encapsulates one message. In a broader chatbot flow, multiple TextNode instances together form the conversation history.

Attributes

  • role: str
    The role associated with this text node, typically "assistant" or "user".

  • content: str
    The actual text content of the message.

  • owner: str
    The name or identifier of the owner of this node (e.g., "AI Bot", "User", etc.).

  • tokens: int
    The number of tokens estimated or measured for this message content. Useful for tracking token usage in OpenAI-based systems.

  • date: str
    A string representation of the date or timestamp at which this message was created.

Methods

  • __str__() -> str
    Returns a JSON-like string of all attributes in the TextNode. For example:

    {
        "role": "assistant",
        "content": "Hello!",
        "owner": "AI Bot",
        "tokens": 5,
        "date": "2024-12-31 10:00:00"
    }
    
  • __iter__() -> dict
    Provides an iterator over the TextNode’s attributes as key-value pairs. This allows you to quickly convert a TextNode to a dictionary by calling dict(text_node_instance).

Usage Example

Below is a simple demonstration of how you might create a TextNode and then inspect its attributes.

from chatweaver import TextNode

# Create a TextNode representing a user's message
user_message = TextNode(
    role="user",
    content="What's the weather like today?",
    owner="Alice",
    tokens=8,
    date="2025-01-01 09:15:00"
)

# Print the node in a JSON-like string representation
print(str(user_message))
# Output:
# {
#   'role': 'user', 
#   'content': "What's the weather like today?", 
#   'owner': 'Alice', 
#   'tokens': 8, 
#   'date': '2025-01-01 09:15:00'
# }

# Convert the TextNode to a dictionary for further processing
node_dict = dict(user_message)
print(node_dict["content"])  # "What's the weather like today?"

Use TextNode objects to store and pass around conversation messages reliably, ensuring their metadata remains intact across different parts of your chatbot or application.

Chat

The Chat class extends the functionality of the Bot class to manage a full conversation session. It retains a history of messages (via TextNode objects), handles reply limits, and tracks metadata such as the chat title, creation date, and total cost (in tokens). This class is ideal for organizing multi-turn conversations in applications or services that require persistent context.

Description

  • Purpose: Provide a structured environment for handling multiple user-bot interactions within one session.
  • Key Features:
    • Maintains an ordered conversation history as a list of TextNodes.
    • Tracks and enforces a maximum number of user+assistant reply pairs.
    • Allows attachments (images/files) to be provided in prompts.
    • Integrates seamlessly with a Bot (and thus with a Model) to generate responses.
  • Metadata: Stores creation date, title, and calculates token-based costs from the conversation history.

Attributes

  • chat_time_format: str
    The string format used for timestamps (by default "%d/%m/%Y %H:%M:%S").

  • chat_replies_limit: int
    The maximum number of user+assistant reply pairs allowed in the session. If set to None, there is no limit.

  • chat_history: list[TextNode]
    A list of TextNode instances, each representing a message (user or assistant) in the conversation.

  • chat_user: str
    The identifier for the user participating in the chat (e.g., "User", "Alice", etc.).

  • chat_creation_date: str
    A timestamp indicating when the chat session was created, using chat_time_format.

  • chat_replies: int
    The current number of user+assistant message pairs in the conversation (computed from chat_history).

  • chat_cost: int
    The sum of all tokens used across the conversation. Calculated by summing the tokens attribute of each TextNode.

  • chat_title: str
    A descriptive title for the chat session (e.g., "New Chat", "Customer Support Session", etc.).

Methods

Constructor

__init__(*args, title="New Chat", replies_limit=10, user="User", cw_bot=None, **kwargs)
Creates a new chat session with an optional title, reply limit, user identifier, and existing Bot. If no Bot is provided, the constructor creates one internally (inheriting from Bot).

  • Parameters:

    • *args: Positional arguments passed to the underlying Bot or Model constructor, if cw_bot is not provided.
    • title (str): The chat title ("New Chat" by default).
    • replies_limit (int | None): The maximum number of user+assistant pairs. None means no limit (defaults to 10).
    • user (str): Name or identifier of the user ("User" by default).
    • cw_bot (Bot | None): An existing Bot. If None, a new one is created.
    • **kwargs: Additional keyword arguments passed to the Bot or Model constructor if cw_bot is not provided.
  • Raises:

    • TypeError: If cw_bot is provided but is not a Bot instance.

__str__() -> str

Returns a concise string representation, including the chat title, reply limit, current reply count, and creation date.

__repr__() -> str

Returns a detailed string for debugging or logging, including attributes such as the reply limit, user, title, and the associated Bot.

__lt__(other: Chat) -> bool

Enables chronological sorting by comparing chat_creation_date between two Chat instances.

__eq__(other: Chat) -> bool

Checks if two Chat objects have the same essential attributes: reply limit, user, title, creation date, number of replies, history, and the same underlying Bot.

Properties

  • chat_Bot (getter)
    Retrieves the underlying Bot instance. Useful if you need direct access to its rules or the Model it uses.

  • chat_time_format (getter/setter)

    • Getter: Returns the time format string for timestamps.
    • Setter: Validates a new time format by attempting to format the current time. Raises a ValueError if invalid.
  • chat_replies_limit (getter/setter)

    • Getter: Returns the maximum allowed replies (float('inf') if no limit).
    • Setter: Accepts an integer or None (treated as infinite). Raises a TypeError if the value cannot be converted to int.
  • chat_history (getter/setter)

    • Getter: Returns a list of the conversation’s TextNode messages.
    • Setter: Accepts a list of TextNodes or a list of dictionaries convertible to TextNode. Raises a TypeError for invalid data.
  • chat_user (getter/setter)

    • Getter: Returns the user’s name or identifier.
    • Setter: Assigns a new user identifier as a str.
  • chat_creation_date (getter/setter)

    • Getter: Returns the creation date as a str formatted according to chat_time_format.
    • Setter: Validates that the given string matches the current time format; raises ValueError if incorrect.
  • chat_replies (getter)
    Calculates the number of user+assistant pairs from the chat_history. Each pair corresponds to two messages (one user and one assistant).

  • chat_cost (getter)
    Sums the tokens attribute of each TextNode in chat_history to provide a cumulative token usage.

  • chat_title (getter/setter)

    • Getter: Retrieves the session’s title.
    • Setter: Assigns a new session title as a str.

set_all(return_self: bool = True, **kwargs: Any) -> Chat | None

Dynamically updates multiple attributes on the Chat (and on its underlying Bot or Model) using keyword arguments.

  • Usage: Each key should refer to the private attribute path (e.g., "_Chat__user", "_Bot__rules", "_Model__api_key").
  • Returns: The Chat instance itself if return_self is True, otherwise None.

Generating Responses

Use get_response to interact with the chat:

get_response(prompt: str, user: str | None = None, image_path: str | None = None, file_path: str | None = None) -> str

Generates an assistant’s response to the given prompt, optionally attaching an image or file. The new user and assistant messages are appended to chat_history as TextNode objects.

  • Parameters:

    • prompt (str): The user’s text input.
    • user (str | None): Custom user identifier for this prompt. Defaults to chat_user if None.
    • image_path (str | None): Path to an image file to include in the request.
    • file_path (str | None): Path to a file to upload for reference.
  • Returns:

    • A str containing the assistant’s response content.

Example Usage

from chatweaver import Chat, Bot, TextNode

# 1. Creating a Chat with a custom Bot
my_bot = Bot(api_key="sk-1234567890abcdef1234...", rules="You are a friendly assistant.")
my_chat = Chat(
    cw_bot=my_bot,
    title="My AI Discussion",
    replies_limit=5,
    user="Alice"
)

# 2. Getting a response
assistant_reply = my_chat.get_response("Hello, can you tell me a joke?")
print("Assistant says:", assistant_reply)

# 3. Accessing chat history
for node in my_chat.chat_history:
    print(node.role, node.content, sep=": ")

# 4. Viewing total token usage
print("Total token usage:", my_chat.chat_cost)

# 5. Changing chat title
my_chat.chat_title = "Jokes and More"

# 6. Setting multiple attributes at once
my_chat.set_all(
    _Chat__replies_limit=None,   # No longer limit the replies
    _Bot__rules="Stay professional in your answers."
)

print("Updated chat limit:", my_chat.chat_replies_limit)
print("Updated bot rules:", my_chat.chat_Bot.bot_rules)

In this example, you create a Chat using a specific Bot, ask for a response, and then manipulate or inspect the Chat’s properties. The session automatically tracks message history (via TextNode objects), token usage, and enforces reply limits (if specified).

CWArchive

The CWArchive class provides a convenient way to store and manage Chat, Bot, or Model objects in a single file. It supports both synchronous and asynchronous loading, as well as basic add, remove, and retrieval operations. This makes it suitable for saving and restoring chatbot sessions, bots, or model configurations in a controlled, persistent manner.

Description

  • Purpose: Encapsulate file-based storage of Chat, Bot, and Model objects with minimal setup.
  • Asynchronous Support: Can operate in asynchronous mode, splitting the data into chunks and loading them in parallel.
  • Archive Operations: Offers methods to add or remove objects (by ID or directly), retrieve the entire archive, and save changes back to disk.
  • Thread-Safety Caveat: Running operations asynchronously in certain environments can lead to race conditions. If this happens, the delay or asynchronous behavior can be tweaked to mitigate the issue.
  • Context Manager: The __enter__ and __exit__ methods handle setup and teardown logic, ensuring that save() is automatically called on exit.

Attributes

  • archive_path: str
    The filesystem path where the archive is stored.

  • archive_data: dict
    A dictionary of stored objects, keyed by integer IDs.

  • archive_id: int
    The next available integer ID that can be used when adding a new item.

  • archive_delay: float
    The delay (in seconds) between asynchronous load operations. Adjust this if you experience race conditions in multi-threaded contexts.

  • archive_asynchronous: bool
    Controls whether the archive is loaded/saved asynchronously. If set to False, data loading is done sequentially.

Methods

Below is an overview of the most important methods in CWArchive.

Constructor

__init__(path: str, asynchronous: bool = True, delay: float = 0.07)
Initializes a new archive with the specified file path, async flag, and an optional delay for asynchronous loads.

  • Parameters:

    • path (str): The path to the archive file on disk.
    • asynchronous (bool): Determines if loading is handled asynchronously (True by default).
    • delay (float): Time in seconds to wait between asynchronous load operations. Defaults to 0.07.
  • Raises:

    • TypeError: If asynchronous is not a boolean.
  • Potential Race Condition:
    If the asynchronous loading processes attempt to modify shared data at the same time, errors can occur. Consider increasing delay or setting archive_asynchronous to False.

__str__() -> str

Returns a user-friendly string with the path of the archive, e.g., "<Archive | path=/path/to/archive>".

__repr__() -> str

Returns a formal string representation of the archive for debugging purposes, e.g., "Archive(path='...')".

__len__() -> int

Returns the count of items (key-value pairs) currently in the archive.

__add__(other: Chat | Bot | Model)

Enables using the + operator to add a Chat, Bot, or Model object to the archive.

my_archive = CWArchive("chats.archive")
my_archive + my_chat  # Adds 'my_chat' under the next available ID

__sub__(other: int | Chat | Bot | Model)

Enables using the - operator to remove an element from the archive by its integer ID or by an instance of Chat, Bot, or Model.

my_archive - 0         # Removes the item with ID 0
my_archive - my_chat   # Removes the specific Chat instance

__enter__(self, *args, **kwargs) -> CWArchive

Returns the CWArchive instance upon entering a with block, allowing you to perform archive operations within that scope.

with CWArchive(path="my_archive.txt") as archive:
    ...

__exit__(self, *args, **kwargs) -> None

Called automatically upon exiting the with block. By default, it invokes save(), ensuring that any modifications made to the archive during the block are persisted to disk.

with CWArchive(path="my_archive.txt") as archive:
    # All changes, like adding or removing objects, 
    # will be saved when exiting this block.

Core Archive Actions

  • define(path: str, delay: float) -> None
    Updates the archive file path and the delay for asynchronous operations.

  • get_id_from_element(element: Chat | Bot | Model) -> list[int]
    Returns a list of all IDs in the archive that correspond to the provided object. Useful if the same object was stored multiple times.

  • is_valid_id(identifier: int) -> bool
    Checks whether the given ID exists in the archive.

  • add(element: Chat | Bot | Model) -> None
    Inserts an element (if it is an instance of Chat, Bot, or Model) into the archive under the next available integer ID.

  • remove(element: list | set | tuple | int | Chat | Bot | Model, remove_type: str | None = "all") -> None
    Removes one or multiple elements from the archive.

    • element: Can be a single ID, a single object, or an iterable of IDs/objects.
    • remove_type: Accepts "all", "first", or "last" to handle cases where the same object appears more than once.
  • save() -> None
    Serializes and writes the archive data to disk in sorted order (by the object’s representation).

    my_archive.save()  # Commits changes to file
    
  • retrieve() -> dict[int, Chat | Bot | Model]
    Reads the archive file from disk and converts each item’s string representation into its corresponding object. Supports both synchronous and asynchronous loading.

    • Asynchronous: Splits the data into chunks and loads them concurrently, separated by archive_delay seconds.
    • Synchronous: If archive_asynchronous is False, loads data one item at a time.

Usage Example

from chatweaver import CWArchive, Chat

# 1. Create an archive (asynchronous by default) with a specific file path
archive = CWArchive(path="my_archive.txt")

# 2. Add a new Chat object to the archive
my_chat = Chat(api_key="sk-1234567890abcdef...", title="Session One")
archive.add(my_chat)

# 3. Save the archive to disk
archive.save()

# 4. Retrieve data from the archive (asynchronously, in chunks by default)
loaded_data = archive.archive_data # Remember, it's better to use the archive_data attribute instead of retrieve()
for item_id, item_obj in loaded_data.items():
    print(item_id, item_obj)

# 5. Remove the chat by its ID (e.g., 0)
archive.remove(0)
archive.save()  # Reflect changes on disk

# 6. Disable asynchronous loading if you run into concurrency issues
archive.archive_asynchronous = False

In this example, we initialize a CWArchive, add a Chat to it, and then save and retrieve data. If concurrency errors appear due to asynchronous operations, you can either increase archive_delay or set archive_asynchronous to False to force sequential processing.

Using the Context Manager

from chatweaver import CWArchive, Bot

my_bot = Bot(api_key="sk-1234567890abcdef...", rules="Be helpful!", name="HelperBot")

with CWArchive(path="my_archive.txt") as archive:
    archive.add(my_bot)
    # No need to manually call archive.save()

When using CWArchive as a context manager:

  • __enter__ is called at the start of the with block, returning the instance.
  • __exit__ is automatically called at the end, ensuring save() is executed.

FAQs

Did you know?

Socket

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Install

Related posts