Skip to main content

AI conversation & file manager - vault your conversations, unlock your context

Project description

ChatVault

Vault your conversations. Unlock your context.

A lightweight Python library for managing AI chat conversations with file attachments. Bring your own storage backends.

Features

  • 🗂️ Conversation Management - Create, load, resume, and archive conversations
  • 💬 Message History - Store and retrieve chat messages with metadata
  • 📎 File Attachments - Attach files to conversations
  • 🔌 Pluggable Backends - Implement your own storage for any cloud provider
  • 🚀 FastAPI Integration - Pre-built API router for instant REST endpoints

Installation

Requires Python 3.10+

pip install chatvault

Quick Start

from chatvault import ChatVault
from chatvault.backends import MemoryMessages, LocalFiles

# Create vault with built-in backends (great for development)
vault = ChatVault(
    messages=MemoryMessages(),
    files=LocalFiles(base_path="./uploads")
)

# Create a conversation
conversation = vault.create_conversation(user_id="user-123")

# Add messages
conversation.add_message("user", "Hello!")
conversation.add_message("assistant", "Hi there! How can I help you?")

# Attach a file
with open("document.pdf", "rb") as f:
    conversation.attach_file("document.pdf", f.read(), content_type="application/pdf")

# Resume later
conversation = vault.get_conversation(conversation.conversation_id)

FastAPI Integration

ChatVault includes a pre-built FastAPI router for instant REST API:

from fastapi import FastAPI
from chatvault import ChatVault
from chatvault.api import create_router
from chatvault.backends import MemoryMessages, LocalFiles

app = FastAPI()

vault = ChatVault(
    messages=MemoryMessages(),
    files=LocalFiles(base_path="./uploads")
)

# Add all conversation endpoints under /api
app.include_router(create_router(vault), prefix="/api")

This gives you these endpoints out of the box:

  • POST /api/conversations - Create conversation
  • GET /api/conversations - List conversations
  • GET /api/conversations/{id} - Get conversation
  • PATCH /api/conversations/{id} - Rename conversation
  • DELETE /api/conversations/{id} - Delete conversation
  • POST /api/conversations/{id}/messages - Add message
  • POST /api/conversations/{id}/files - Upload file
  • GET /api/conversations/{id}/files/{filename} - Download file

API Reference

ChatVault

Method Description
create_conversation(user_id=None) Create a new conversation
get_conversation(conversation_id) Load an existing conversation
get_conversations(user_id) List all conversations for a user
delete_conversation(conversation_id) Delete a conversation

Conversation

Method Description
add_message(role, content) Add a message to the conversation
get_messages() Get all messages
attach_file(filename, data, content_type) Attach a file
get_file(filename) Get file content
list_files() List all attached files

Built-in Backends

Backend Description
MemoryMessages In-memory storage (for development/testing)
LocalFiles Local filesystem storage

Custom Backends

ChatVault works with any storage provider. Implement these abstract base classes:

  • MessagesBackend - For conversation persistence (save, get, get_by_user, delete)
  • FilesBackend - For file storage (upload, download, delete, exists, get_signed_url)

Example: AWS S3 + DynamoDB

import boto3
from chatvault.backends import FilesBackend

class S3Files(FilesBackend):
    def __init__(self, bucket: str, region_name: str = None):
        self.bucket = bucket
        self.s3 = boto3.client("s3", region_name=region_name)
    
    def upload(self, key: str, data: bytes, content_type: str = "application/octet-stream") -> None:
        self.s3.put_object(Bucket=self.bucket, Key=key, Body=data, ContentType=content_type)
    
    def download(self, key: str):
        response = self.s3.get_object(Bucket=self.bucket, Key=key)
        return response["Body"].read()
    
    def delete(self, key: str) -> bool:
        self.s3.delete_object(Bucket=self.bucket, Key=key)
        return True
    
    def exists(self, key: str) -> bool:
        try:
            self.s3.head_object(Bucket=self.bucket, Key=key)
            return True
        except:
            return False
    
    def get_signed_url(self, key: str, expires_in: int = 3600, download_filename: str = None):
        return self.s3.generate_presigned_url("get_object", Params={"Bucket": self.bucket, "Key": key}, ExpiresIn=expires_in)
import json
from datetime import datetime
import boto3
from chatvault.backends import MessagesBackend
from chatvault.conversation import Conversation, Message, FileAttachment

class DynamoMessages(MessagesBackend):
    def __init__(self, table_name: str, region_name: str = None):
        self.table = boto3.resource("dynamodb", region_name=region_name).Table(table_name)
    
    def save(self, conversation) -> None:
        self.table.put_item(Item={
            "conversation_id": conversation.conversation_id,
            "user_id": conversation.user_id or "",
            "title": conversation.title,
            "messages": json.dumps([m.to_dict() for m in conversation._messages]),
            "files": json.dumps([f.to_dict() for f in conversation._files]),
            "created_at": int(conversation.created_at.timestamp()),
            "last_active": int(conversation.last_active.timestamp()),
        })
    
    def get(self, conversation_id: str):
        response = self.table.get_item(Key={"conversation_id": conversation_id})
        item = response.get("Item")
        if not item:
            return None
        return Conversation(
            conversation_id=item["conversation_id"],
            user_id=item.get("user_id") or None,
            title=item.get("title", ""),
            created_at=datetime.fromtimestamp(int(item.get("created_at", 0))),
            messages=[Message.from_dict(m) for m in json.loads(item.get("messages", "[]"))],
            files=[FileAttachment.from_dict(f) for f in json.loads(item.get("files", "[]"))],
        )
    
    def get_by_user(self, user_id: str):
        response = self.table.query(
            IndexName="user_id-index",
            KeyConditionExpression="user_id = :uid",
            ExpressionAttributeValues={":uid": user_id}
        )
        return [self.get(item["conversation_id"]) for item in response.get("Items", [])]
    
    def delete(self, conversation_id: str) -> bool:
        self.table.delete_item(Key={"conversation_id": conversation_id})
        return True

Usage:

vault = ChatVault(
    messages=DynamoMessages(table_name="Conversations", region_name="us-east-1"),
    files=S3Files(bucket="my-chat-files", region_name="us-east-1")
)

Development

# Clone and install
git clone https://github.com/enfeizhan/chatvault.git
cd chatvault
uv venv .venv && source .venv/bin/activate
uv pip install -e ".[dev]"

# Run tests
pytest -v

License

MIT License - see LICENSE for details.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

chatvault-0.1.0.tar.gz (70.5 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

chatvault-0.1.0-py3-none-any.whl (16.7 kB view details)

Uploaded Python 3

File details

Details for the file chatvault-0.1.0.tar.gz.

File metadata

  • Download URL: chatvault-0.1.0.tar.gz
  • Upload date:
  • Size: 70.5 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: Hatch/1.16.2 cpython/3.13.5 HTTPX/0.28.1

File hashes

Hashes for chatvault-0.1.0.tar.gz
Algorithm Hash digest
SHA256 8f7b87c70dcd348d4f599ec1d8cd936cbee296940488eb5121c6eb3897dd823f
MD5 f90e3f67929fe46cc089d974b2b80001
BLAKE2b-256 5bcae85b7d829865ca1b3ca68ad4877dda11775c36f9a7bb01b55e56e9d187ec

See more details on using hashes here.

File details

Details for the file chatvault-0.1.0-py3-none-any.whl.

File metadata

  • Download URL: chatvault-0.1.0-py3-none-any.whl
  • Upload date:
  • Size: 16.7 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: Hatch/1.16.2 cpython/3.13.5 HTTPX/0.28.1

File hashes

Hashes for chatvault-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 6715a370aca209a2cedd34d0aa1cd7bebe882cc7cd72fe2ddf94f5ede05681db
MD5 ca0fc4bf7d0856eb0c6fce01a189d5be
BLAKE2b-256 1d790b3dcbf690723f2e78fae6f9bfdecbedaa32d8672e55122a68d0ec7e1fde

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page