Skip to main content

A lightweight, persistent data store with dictionary, key-value, and linked list support with GUI

Project description

pyhold

PyPi: Click Here

pyhold is a lightweight, persistent data store built in pure Python with multiple data structure support. Designed for MVPs, CLI tools, and embedded apps that need quick and reliable state saving — no database required.

✅ Features

  • Dictionary-style access: store["token"] = "abc"
  • Key-Value store: Dedicated key-value operations with GUI
  • Linked List: Persistent linked list with full list operations
  • Auto-syncs to XML on change
  • Supports int, str, float, bool, dict, list, tuple, None
  • Fully human-readable and editable
  • Zero external dependencies
  • Built-in GUI for all data structures

📋 Requirements

Python Version: 3.7 or higher

Built-in Dependencies (included with Python):

  • tkinter - For GUI functionality (included in most Python installations)
  • xml.etree.ElementTree - For XML file operations
  • json - For complex data type serialization
  • ast - For literal evaluation

Note: The GUI features require tkinter, which is included in most Python installations but may need to be installed separately on some Linux distributions:

# Ubuntu/Debian
sudo apt-get install python3-tk

# CentOS/RHEL/Fedora
sudo yum install tkinter
# or
sudo dnf install python3-tkinter

# macOS (usually included with Python)
# If missing: brew install python-tk

Installation

pip install pyhold

🗂️ Key-Value Store

The key-value store provides dictionary-like functionality with persistent storage to XML files.

Basic Usage

from pyhold import pyhold

# Initialize in keyvalue mode
kv_store = pyhold("my_data.xml", mode="keyvalue", auto_sync=True, auto_reload=True)

Core Functions

Dictionary-style Operations

# Set values
kv_store["username"] = "john_doe"
kv_store["age"] = 25
kv_store["settings"] = {"theme": "dark", "notifications": True}

# Get values
print(kv_store["username"])  # "john_doe"
print(kv_store["age"])       # 25

# Check if key exists
if "username" in kv_store:
    print("User found!")

# Delete items
del kv_store["age"]
# or
kv_store.pop("age")  # Returns the value and removes it

Utility Functions

# Get with default value
value = kv_store.get("missing_key", "default_value")

# Get all keys, values, or items
keys = kv_store.keys()      # ['username', 'settings']
values = kv_store.values()  # ['john_doe', {'theme': 'dark', 'notifications': True}]
items = kv_store.items()    # [('username', 'john_doe'), ('settings', {...})]

# Get length
print(len(kv_store))  # Number of key-value pairs

# Clear all data
kv_store.clear()

# Manual save/reload
kv_store.save_pyhold()   # Force save to XML
kv_store.load_pyhold()   # Force reload from XML

Write Function

# Alternative way to add/update values
kv_store.write("api_key", "abc123")
kv_store.write("counter", 42)

GUI Interface

# Open graphical interface for managing data
kv_store.show_gui()

Complete Example

from pyhold import pyhold

# Initialize store in keyvalue mode
config = pyhold("app_config.xml", mode="keyvalue")

# Store application settings
config["app_name"] = "MyApp"
config["version"] = "1.0.0"
config["debug_mode"] = True
config["database"] = {
    "host": "localhost",
    "port": 5432,
    "name": "myapp_db"
}
config["features"] = ["auth", "logging", "api"]

# Retrieve settings
print(f"App: {config['app_name']} v{config['version']}")
print(f"Debug: {config['debug_mode']}")
print(f"DB Host: {config['database']['host']}")

# Check if feature is enabled
if "auth" in config["features"]:
    print("Authentication is enabled")

# Update settings
config["version"] = "1.1.0"
config["debug_mode"] = False

# Open GUI to manage settings
config.show_gui()

🔗 Linked List

The linked list provides a persistent, index-based data structure with full list operations.

Basic Usage

from pyhold import pyhold

# Initialize in linkedlist mode
ll = pyhold("my_list.xml", mode="linkedlist", auto_sync=True, auto_reload=True)

Core Functions

List-style Operations

# Add items
ll.append("first item")
ll.append(42)
ll.append({"nested": "data"})

# Access by index
print(ll[0])  # "first item"
print(ll[1])  # 42

# Set items by index
ll[0] = "updated first item"

# Check if value exists
if "first item" in ll:
    print("Item found!")

# Get length
print(len(ll))  # Number of items

Insertion and Removal

# Insert at specific index
ll.insert(1, "inserted item")  # Inserts at index 1

# Remove by value
ll.remove("inserted item")  # Removes first occurrence

# Remove by index
ll.pop(0)  # Removes and returns item at index 0
ll.pop()   # Removes and returns last item

# Delete by index
del ll[0]  # Removes item at index 0

Search and Analysis

# Find index of value
try:
    index = ll.index("first item")
    print(f"Found at index: {index}")
except ValueError:
    print("Item not found")

# Count occurrences
count = ll.count("first item")  # Number of times item appears

# Check if lists are equal
other_list = pyhold("other.xml", mode="linkedlist")
other_list.append("first item")
print(ll == other_list)  # True if lists have same values

List Manipulation

# Reverse the list
ll.reverse()

# Sort the list
ll.sort()           # Ascending order
ll.sort(reverse=True)  # Descending order

# Extend with another iterable
ll.extend(["item1", "item2", "item3"])

# Concatenate lists
list1 = pyhold("list1.xml", mode="linkedlist")
list2 = pyhold("list2.xml", mode="linkedlist")
combined = list1 + list2  # Creates new list

# Repeat list
repeated = ll * 3  # Creates list with ll repeated 3 times

Utility Functions

# Clear all items
ll.clear()

# Manual save/reload
ll.save_pyhold()   # Force save to XML
ll.load_pyhold()   # Force reload from XML

# String representation
print(str(ll))  # Prints all values, one per line

GUI Interface

# Open graphical interface for managing list
ll.show_gui()

Complete Example

from pyhold import pyhold

# Initialize list in linkedlist mode
tasks = pyhold("todo_list.xml", mode="linkedlist")

# Add tasks
tasks.append("Buy groceries")
tasks.append("Write documentation")
tasks.append("Review code")
tasks.append("Deploy application")

# Insert priority task
tasks.insert(0, "URGENT: Fix critical bug")

# Check current tasks
print(f"Total tasks: {len(tasks)}")
print(f"First task: {tasks[0]}")
print(f"Last task: {tasks[-1]}")

# Find specific task
try:
    index = tasks.index("Write documentation")
    print(f"Documentation task at index: {index}")
except ValueError:
    print("Task not found")

# Update task
tasks[1] = "Buy groceries and milk"

# Remove completed task
tasks.remove("Review code")

# Sort tasks alphabetically
tasks.sort()

# Reverse to see most recent first
tasks.reverse()

# Open GUI to manage tasks
tasks.show_gui()

📁 Dictionary Store

The dictionary store provides a simple key-value interface using the main pyhold class.

Basic Usage

from pyhold import pyhold

# Initialize in keyvalue mode (default)
store = pyhold("mydata.xml", mode="keyvalue", auto_sync=True, auto_reload=True)

# Use like a dictionary
store["username"] = "anjan"
store["token"] = "abc123"
print(store["username"])  # "anjan"

# Remove items
store.pop("username")

Complete Example

from pyhold import pyhold

# Initialize store
app_data = pyhold("app_data.xml", mode="keyvalue")

# Store user session data
app_data["user_id"] = 12345
app_data["session_token"] = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9"
app_data["preferences"] = {
    "theme": "dark",
    "language": "en",
    "notifications": True
}
app_data["last_login"] = "2024-01-15T10:30:00Z"

# Retrieve data
user_id = app_data.get("user_id")
session_token = app_data["session_token"]
theme = app_data["preferences"]["theme"]

# Update data
app_data["last_login"] = "2024-01-15T11:45:00Z"

# Check if key exists
if "session_token" in app_data:
    print("User is logged in")

# Remove sensitive data
app_data.pop("session_token")

🔧 Configuration Options

All classes support these initialization parameters:

  • filename (str): XML file path for persistence (default: "pyhold.xml")
  • mode (str): Data structure mode - "keyvalue" or "linkedlist" (default: "keyvalue")
  • auto_sync (bool): Automatically save changes to file (default: True)
  • auto_reload (bool): Automatically load from file on initialization (default: True)

🎨 GUI Features

Both key-value and linked list stores include a comprehensive GUI with:

  • Visual data management: Add, edit, delete items
  • Search functionality: Filter items by key/value
  • Type selection: Choose data types (str, int, float, bool, list, dict, tuple)
  • File operations: Manual save, reload, export to JSON
  • Real-time updates: See changes immediately
  • Error handling: User-friendly error messages

📋 Supported Data Types

  • Primitive types: int, str, float, bool, None
  • Complex types: dict, list, tuple
  • Automatic type detection and preservation
  • Human-readable XML storage

🚀 Use Cases

  • Configuration management: App settings, user preferences
  • Session storage: User data, authentication tokens
  • Data caching: Temporary data persistence
  • CLI tools: Command history, user settings
  • Prototyping: Quick data storage without database setup
  • Embedded applications: Lightweight data persistence

🔧 Troubleshooting

GUI Not Working

If you encounter issues with the GUI:

  1. Linux: Install tkinter: sudo apt-get install python3-tk (Ubuntu/Debian) or sudo yum install tkinter (CentOS/RHEL)
  2. macOS: Usually included with Python. If missing: brew install python-tk
  3. Windows: Usually included with Python installation

File Permission Errors

  • Ensure you have write permissions in the directory where you're creating XML files
  • Check if the XML file is not locked by another process

Data Type Issues

  • Complex data types (dict, list, tuple) are automatically serialized to JSON
  • None values are properly handled
  • Boolean values are preserved correctly

🤝 Contributing

Contributions are welcome! Please feel free to submit a Pull Request. For major changes, please open an issue first to discuss what you would like to change.

Development Setup

git clone https://github.com/AnjanB3012/pyhold.git
cd pyhold
pip install -e .

Running Tests

# Basic functionality test
from pyhold import pyhold

# Test key-value store
kv = pyhold("test.xml", mode="keyvalue")
kv["test"] = "value"
assert kv["test"] == "value"

# Test linked list
ll = pyhold("test_list.xml", mode="linkedlist")
ll.append("item1")
assert ll[0] == "item1"

📄 License

This project is licensed under the MIT License - see the LICENSE file for details.

📝 Changelog

Version 0.2.0

  • Added comprehensive GUI for both key-value and linked list stores
  • Improved error handling and data type support
  • Enhanced documentation with examples
  • Added search and filter functionality in GUI
  • Export to JSON functionality

Version 0.1.0

  • Initial release with basic key-value and linked list functionality
  • XML persistence support
  • Basic dictionary-style operations

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

pyhold-0.2.0.tar.gz (17.5 kB view details)

Uploaded Source

Built Distribution

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

pyhold-0.2.0-py3-none-any.whl (16.0 kB view details)

Uploaded Python 3

File details

Details for the file pyhold-0.2.0.tar.gz.

File metadata

  • Download URL: pyhold-0.2.0.tar.gz
  • Upload date:
  • Size: 17.5 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.1.0 CPython/3.13.4

File hashes

Hashes for pyhold-0.2.0.tar.gz
Algorithm Hash digest
SHA256 987883b4dc1ea495327de4f44f466f6149edcabc7c6bd235a69c70cec4f8b434
MD5 ac1e0576e9b10fa836d1aebe285a0f76
BLAKE2b-256 e42fc1c86f40827902f7e3c4c89f01b667aa6e92e090a8f1c5262f5b5d2a6081

See more details on using hashes here.

File details

Details for the file pyhold-0.2.0-py3-none-any.whl.

File metadata

  • Download URL: pyhold-0.2.0-py3-none-any.whl
  • Upload date:
  • Size: 16.0 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.1.0 CPython/3.13.4

File hashes

Hashes for pyhold-0.2.0-py3-none-any.whl
Algorithm Hash digest
SHA256 e3906d45088b8e3a51a2fc0c9142ad6d2fc3972824e3df14636ab8d6b4284530
MD5 b67fc832fb6c20928401013a8d9b4e02
BLAKE2b-256 1a23c12ac77f184938a98b31d66d418661a134b0147837167ea1ad8595f3ce6e

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