Skip to main content

A collection of reusable utilities across projects I work on.

Project description

Jays Tools

A collection of lightweight utilities for JSON-backed data persistence with full type safety, automatic migrations, and async support.

Features

  • JsonDatabase: Strongly-typed JSON database for single entities with Pydantic validation and automatic migrations
  • JsonCollection: Directory-based entity collections for managing multiple related objects (one file per entity)
  • Full type safety with IDE autocomplete and compile-time checking
  • Transparent schema migrations as your models evolve
  • Thread-safe operations with automatic concurrency handling
  • Async support for non-blocking I/O
  • Minimal, intuitive API

Installation

pip install jays-tools

Quick Start: JsonDatabase

A lightweight JSON database perfect for application state, configuration, and single-entity storage.

Basic Usage

from jays_tools.json_database import JsonDatabase
from jays_tools.json_database.models import MigratableModel

class AppState(MigratableModel):
    total: int = 0
    users: list[dict] = []

# Create or load database (auto-created if missing)
db = JsonDatabase("app_state.json", AppState)

# Read, modify, and persist
state = db.get_database()
state.users.append({"id": 1, "name": "Alice"})
state.total = len(state.users)
db.update_database(state)

# Verify persistence
data = db.get_database()
print(data.total)   # 1
print(data.users)   # [{"id": 1, "name": "Alice"}]

Async Support

import asyncio

async def main():
    db = JsonDatabase("app_state.json", AppState)
    
    # Non-blocking read/write via thread pool
    state = await db.async_get_database()
    state.total += 1
    await db.async_update_database(state)

asyncio.run(main())

Quick Start: JsonCollection

Store collections of entities as individual JSON files, automatically keyed by filename.

Basic Usage

from jays_tools.json_collection import JsonCollection
from jays_tools.json_database.models import MigratableModel

class User(MigratableModel):
    name: str = ""
    email: str = ""

# Create or load collection
collection = JsonCollection("data/users", model=User)

# Create/update entities
user_data = User(name="Alice", email="alice@example.com")
collection.update("alice_id", user_data)

# List all keys
keys = collection.list_keys()  # ["alice_id"]

# Retrieve entities
user = collection.get("alice_id").get_database()
print(user.name)  # "Alice"

# Delete entities
collection.delete("alice_id")

Async Collection Operations

async def manage_users():
    collection = JsonCollection("data/users", model=User)
    
    # Async operations with built-in locking
    await collection.async_update("alice_id", user_data)
    all_users = await collection.async_get_all()
    await collection.async_delete("alice_id")

asyncio.run(manage_users())

Key Concepts

Type Safety

All data is validated with Pydantic models, providing full IDE support and compile-time type checking.

db = JsonDatabase("config.json", MyConfig)
config = db.get_database()
config.api_key  # IDE autocomplete, full type information

Automatic Migrations

Update your model schema without manual migration scripts. Old data automatically migrates to new versions.

See ARCHITECTURE.md for detailed migration patterns and examples.

Simple, Predictable API

JsonDatabase (single entity):

  • get_database() → Read current state
  • update_database(data) → Write and persist
  • async_get_database() / async_update_database() → Async versions

JsonCollection (entity collections):

  • get(key) → Retrieve entity by key (returns JsonDatabase instance)
  • update(key, data) → Create or update entity
  • delete(key) → Remove entity
  • list_keys() → Get all entity keys
  • get_all() / update_all() → Bulk operations
  • async_* variants for all operations

Project Structure

For projects using multiple data models and collections:

my_project/
├── src/
│   ├── models/
│   │   ├── __init__.py
│   │   ├── user.py
│   │   └── settings.py
│   └── main.py
└── data/
    ├── app_settings.json          # JsonDatabase
    ├── users/                     # JsonCollection
    │   ├── user_1.json
    │   ├── user_2.json
    │   └── user_3.json
    └── sessions/                  # JsonCollection
        ├── session_abc.json
        └── session_def.json

Example: models/user.py

from typing import Any
from jays_tools.json_database.models import MigratableModel

class UserV1(MigratableModel):
    name: str = ""
    age: int = 0

class UserV2(MigratableModel, previous_model=UserV1):
    name: str = ""
    age: int = 0
    email: str = ""

    @staticmethod
    def migrate_from_previous(previous_data: dict[str, Any]) -> dict[str, Any]:
        previous_data["email"] = ""
        return previous_data

# Export latest version
User = UserV2

Example: src/main.py

from pathlib import Path
from jays_tools.json_collection import JsonCollection
from jays_tools.json_database import JsonDatabase
from src.models.user import User

# Setup directories
DATA_DIR = Path("data")
DATA_DIR.mkdir(exist_ok=True)

# Single database for app settings
settings_db = JsonDatabase(DATA_DIR / "app_settings.json", AppSettings)

# Collection for managing users
users_collection = JsonCollection(DATA_DIR / "users", model=User)

def main():
    # Work with collection
    user = User(name="Alice", email="alice@example.com")
    users_collection.update("user_alice", user)
    
    # List all users
    all_keys = users_collection.list_keys()
    print(f"Total users: {len(all_keys)}")

Learning Resources

License

MIT - See LICENSE file 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

jays_tools-2.0.0.tar.gz (24.7 kB view details)

Uploaded Source

Built Distribution

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

jays_tools-2.0.0-py3-none-any.whl (10.7 kB view details)

Uploaded Python 3

File details

Details for the file jays_tools-2.0.0.tar.gz.

File metadata

  • Download URL: jays_tools-2.0.0.tar.gz
  • Upload date:
  • Size: 24.7 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.14.3

File hashes

Hashes for jays_tools-2.0.0.tar.gz
Algorithm Hash digest
SHA256 14a2f296ec535fdd62062d8b38db703eef5bffbe8ff25be11935682b7448fe47
MD5 b5dbe342a1e7e15c5c4b4a8083cd8da2
BLAKE2b-256 d05a40b9abb1dca46619fa6325466154d3ef22fc209b97a2dc59a3f2a4a58282

See more details on using hashes here.

File details

Details for the file jays_tools-2.0.0-py3-none-any.whl.

File metadata

  • Download URL: jays_tools-2.0.0-py3-none-any.whl
  • Upload date:
  • Size: 10.7 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.14.3

File hashes

Hashes for jays_tools-2.0.0-py3-none-any.whl
Algorithm Hash digest
SHA256 ba2a359314db5e4700acb2f74af62bf148480a30fcbb591392a76f8c28428329
MD5 efb863836805e01b6c4d4afab90abf89
BLAKE2b-256 9dda8df2b04cef8db1c9d3faceebfb88a671d5ffc4c607591b29446e7d8b023d

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