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 conversationGET /api/conversations- List conversationsGET /api/conversations/{id}- Get conversationPATCH /api/conversations/{id}- Rename conversationDELETE /api/conversations/{id}- Delete conversationPOST /api/conversations/{id}/messages- Add messagePOST /api/conversations/{id}/files- Upload fileGET /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
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
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
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
8f7b87c70dcd348d4f599ec1d8cd936cbee296940488eb5121c6eb3897dd823f
|
|
| MD5 |
f90e3f67929fe46cc089d974b2b80001
|
|
| BLAKE2b-256 |
5bcae85b7d829865ca1b3ca68ad4877dda11775c36f9a7bb01b55e56e9d187ec
|
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
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
6715a370aca209a2cedd34d0aa1cd7bebe882cc7cd72fe2ddf94f5ede05681db
|
|
| MD5 |
ca0fc4bf7d0856eb0c6fce01a189d5be
|
|
| BLAKE2b-256 |
1d790b3dcbf690723f2e78fae6f9bfdecbedaa32d8672e55122a68d0ec7e1fde
|