Skip to main content

QV Session Manager

A simple, efficient session manager for persistent storage and management of conversations from qv-ollama-sdk in an SQLite database.

✨ Features

  • 💾 Persistent storage of conversations and messages in SQLite
  • 🔍 Full-text search in conversation contents and titles
  • ⏰ Time-based search by creation/update date
  • 🔄 Conversation resumption at any point
  • 📋 Conversation management (list, delete, load)
  • 🎯 Minimal dependencies (only Python stdlib + qv-ollama-sdk)
  • 🚀 Simple API with clear, intuitive methods

🛠️ Installation

From PyPI

pip install qv-session-manager

or

uv add qv-session-manager

Development installation

git clone https://github.com/quantyverse/qv-session-manager.git
cd qv-session-manager
pip install -e .

Dependencies

  • Python 3.10+
  • qv-ollama-sdk

🚀 Quickstart

from qv_session_manager import SessionManager
from qv_ollama_sdk.domain.models import Conversation

# Initialize SessionManager
mgr = SessionManager(db_path="my_sessions.db")

# Create new conversation
conv = Conversation(title="Python Help", model_name="llama3")
conv.add_user_message("Explain Python lists to me!")
conv.add_assistant_message("Lists are ordered, mutable collections...")

# Save
mgr.save_conversation(conv, conv.messages)

# Load
loaded = mgr.load_conversation(str(conv.id))
print(f"Loaded: {loaded.title} with {len(loaded.messages)} messages")

# Search
results = mgr.search_conversations("lists")
print(f"Found: {len(results)} conversations")

📚 API Documentation

SessionManager

Initialization

SessionManager(db_path: str = "session_manager.db")
  • db_path: Path to the SQLite database file

Methods

save_conversation(conversation, messages)

Saves a conversation and its messages.

  • conversation: Conversation object (with to_db_dict() method)
  • messages: List of Message objects (with to_db_dict() methods)
mgr.save_conversation(conv, conv.messages)
load_conversation(conversation_id: str) -> Conversation | None

Loads a conversation with all messages.

  • conversation_id: UUID of the conversation as a string
  • Returns: Conversation object or None
conv = mgr.load_conversation("550e8400-e29b-41d4-a716-446655440000")
list_conversations() -> List[Dict[str, Any]]

Lists all conversations (without messages).

  • Returns: List of conversation dicts with metadata
all_convs = mgr.list_conversations()
for conv in all_convs:
    print(f"{conv['title']} - {conv['created_at']}")
search_conversations(query: str) -> List[Dict[str, Any]]

Full-text search in titles and message contents.

  • query: Search term
  • Returns: List of found conversation dicts
results = mgr.search_conversations("Python")
search_by_time(start: str = None, end: str = None) -> List[Dict[str, Any]]

Time-based search for conversations.

  • start: Start date (ISO format, e.g. "2025-01-20")
  • end: End date (ISO format)
  • Returns: List of conversation dicts
# Conversations from today
today = datetime.now().strftime("%Y-%m-%d")
recent = mgr.search_by_time(start=today)

# Conversations from a period
results = mgr.search_by_time(start="2025-01-01", end="2025-01-31")
resume_conversation(conversation_id: str) -> Dict[str, Any] | None

Prepares conversation resumption.

  • conversation_id: UUID of the conversation
  • Returns: Dict with conversation and last_message
resumed = mgr.resume_conversation(str(conv.id))
last_msg = resumed["last_message"]
print(f"Last message: {last_msg['content']}")
delete_conversation(conversation_id: str)

Deletes a conversation and all associated messages.

  • conversation_id: UUID of the conversation
mgr.delete_conversation(str(conv.id))

💡 Advanced Examples

Conversation management with metadata

from datetime import datetime
from qv_session_manager import SessionManager
from qv_ollama_sdk.domain.models import Conversation

mgr = SessionManager()

# Conversation with metadata
conv = Conversation(
    title="JavaScript Tutorial",
    model_name="llama3",
    metadata={
        "topic": "web-development", 
        "difficulty": "beginner",
        "language": "javascript"
    }
)

# Add messages
conv.add_system_message("You are an experienced web developer.")
conv.add_user_message("Explain closures in JavaScript.")

# Save
mgr.save_conversation(conv, conv.messages)

# Search by topic
web_convs = [c for c in mgr.list_conversations() 
             if c.get('metadata', {}).get('topic') == 'web-development']

Batch operations

# Delete all conversations from a specific day
target_date = "2025-01-20"
old_convs = mgr.search_by_time(start=target_date, end=target_date)

for conv in old_convs:
    mgr.delete_conversation(conv['id'])
    print(f"Deleted: {conv['title']}")

Conversation continuation

# Load and extend an existing conversation
conv = mgr.load_conversation("existing-conversation-id")

if conv:
    # Add new messages
    conv.add_user_message("Can you explain that again?")
    conv.add_assistant_message("Sure! Let me rephrase that...")
    
    # Save updated version
    mgr.save_conversation(conv, conv.messages)

🧪 Development & Testing

Run tests

# All tests
pytest

# Specific test
pytest tests/test_session_manager.py

# With output
pytest -v -s

Run demo

python examples/basic_usage.py

Project structure

qv-session-manager/
├── src/qv_session_manager/
│   ├── __init__.py
│   └── session_manager.py
├── tests/
│   └── test_session_manager.py
├── examples/
│   └── basic_usage.py
├── README.md
└── pyproject.toml

🗄️ Database Schema

The SQLite database uses the following schema:

-- Conversations table
CREATE TABLE conversations (
    id TEXT PRIMARY KEY,           -- UUID
    title TEXT,                    -- Conversation title
    created_at TEXT,              -- ISO timestamp
    updated_at TEXT,              -- ISO timestamp  
    metadata TEXT                 -- JSON metadata
);

-- Messages table
CREATE TABLE messages (
    id TEXT PRIMARY KEY,          -- UUID
    conversation_id TEXT,         -- Reference to conversations.id
    role TEXT,                    -- "system", "user", "assistant"
    content TEXT,                 -- Message content
    created_at TEXT,             -- ISO timestamp
    metadata TEXT,               -- JSON metadata
    FOREIGN KEY(conversation_id) REFERENCES conversations(id) ON DELETE CASCADE
);

🤝 Integration with qv-ollama-sdk

from qv_ollama_sdk.client import OllamaClient
from qv_session_manager import SessionManager

# Initialize clients
ollama = OllamaClient()
session_mgr = SessionManager()

# New conversation
conv = ollama.create_conversation(model="gemma3:1b")
conv.title = "Code Review Session"

# Chat with Ollama
response = ollama.chat(conv, "Explain Clean Code principles to me")
print(response.content)

# Persist session
session_mgr.save_conversation(conv, conv.messages)

# Later: load and continue session
loaded_conv = session_mgr.load_conversation(str(conv.id))
next_response = ollama.chat(loaded_conv, "Which tools do you recommend?")

📋 Roadmap

  • Advanced search/filter functions (e.g. by metadata)
  • Optional encryption of stored data
  • Export/import of conversations (JSON, CSV)
  • Performance optimizations for large datasets
  • Async support for high-performance applications

🐛 Error Handling

try:
    conv = mgr.load_conversation("invalid-id")
    if conv is None:
        print("Conversation not found")
except Exception as e:
    print(f"Error loading: {e}")

📄 License

MIT License - see LICENSE for details.

📞 Support

  • Issues: GitHub Issues
  • Documentation: This README
  • Examples: See the examples/ directory

Metadata

Release files for qv-session-manager 0.3.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for qv-session-manager 0.3.0
File Size Uploaded Provenance
qv_session_manager-0.3.0.tar.gz 12.0 kB Without provenance Details

Built distribution (wheel)

Table of built distributions (wheels) for qv-session-manager 0.3.0
File Interpreter ABI Platform
qv_session_manager-0.3.0-py3-none-any.whl Python 3 none any Details

Total release size: 20.3 kB

Release files / qv_session_manager-0.3.0.tar.gz

Download URL qv_session_manager-0.3.0.tar.gz
Size 12.0 kB
Tags Source
SHA-256 checksum
How to use checksums
4cb0f90e6cc71a1dfc08c5373e7582c210caef584406edbe10f478981a10a79b
BLAKE2b-256 checksum
How to use checksums
284701913801061fb633d767ee130f454fcdd118e83ba3f97c166f6f3e61dd4b
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via uv/0.5.5

Release files / qv_session_manager-0.3.0-py3-none-any.whl

Download URL qv_session_manager-0.3.0-py3-none-any.whl
Size 8.3 kB
Tags Python 3
SHA-256 checksum
How to use checksums
f17afcd973469c79149bc2e0d303f62f5fa922e1f2bd66716958c5ee7a503a23
BLAKE2b-256 checksum
How to use checksums
9eca8b0adb14c501a9fd6a85d45ffa98faf27c0199ed46bba8cf6ae86cd50208
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via uv/0.5.5

Security for qv-session-manager 0.3.0

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

No provenance found

None of the files in this release were uploaded with provenance metadata.

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page