Skip to main content

Data management for python made easy

Project description

Rheel Data Management

Python License

Strictly-typed, human-readable data management for Python.

Rheel Data Management (RDM) provides a clean .rdm file format and Python API for structured, section-based data storage with enforced types.

Since version 2.0 RDM features Rheel Temporary Data (RTD), which provides clean .rtd files for storing temporary data that expires at a given time. RTD is not section-based but features all other functions that RDM does.

It is designed for developers who want more structure and type safety than JSON or TOML --- without the complexity of a database.


✨ Features

  • Strict type enforcement
  • Native Python type support
  • Nested generics (list[int], dict[int, str])
  • Union types (str | int)
  • Mixed generics (list[str | int])
  • Dynamic operations (add(), extend(), multiply())
  • Key deletion support (delete())
  • Section-based structure
  • Human-readable aligned format
  • Atomic file saves (corruption protection)
  • Custom type registry
  • Supports datetime, date, time, and Path natively
  • Safe variable handling with deep copy

NEW in v2:

  • Temporary data system with expiration support (.rtd)
  • Per-key TTL (time-to-live) expiration
  • Automatic expired key cleanup on save
  • Expiration extension and inspection API

📦 Installation

pip install Rheel-Data-Management

📥 Import

import rheelDM

📄 Example .rdm File

# Rheel Data Management 2.0

[user123]
name  : str           = "Steve"
score : int           = 42
tags  : list[str]     = ["admin", "tester"]
prefs : dict[int,str] = {1: "dark", 2: "light"}

📄 Example .rtd File

# Rheel Temporary Data @ Rheel Data Management 2.0

[2026-03-04T18:14:37.891803+00:00]
effect : str = "burning"

[2026-03-04T18:35:07.172342+00:00]
premium_member : bool = True

Clean. Typed. Readable.


🚀 Basic Usage

For each heading there are 2 examples (when required). The first is RDM and the second is RTD

Create and Save

import rheelDM

data = rheelDM.Obj()
user = data.section("user123") # for simplicity user always refers to this section in RDM files

user.set("name", str, "Steve")
user.set("score", int, 42)
user.set("tags", list[str], ["admin", "tester"])
user.set("prefs", dict[int, str], {1: "dark", 2: "light"})

data.save("botdata.rdm")
import rheelDM, datetime

temp = rheelDM.TempObj()

temp.set("name", str, "Steve", ttl=30) # Expires 30 seconds from now (also works with datetime.timedelta)
temp.set("score", int, 42, expires_at=datetime.datetime(2026,3,3,18,0,tzinfo=datetime.timezone.utc)) # Expires at given timestamp

temp.save("tempbotdata.rtd")

Load Data

from datetime import datetime

default_data = rheelDM.Obj()
default_data.section("user123").set("name", str, "noName")
default_data.section("user123").set("score", int, 0)

default_items = rheelDM.Obj.load("default_items.rdm")

loaded = rheelDM.Obj.load("botdata.rdm", default_data) # uses a copy of default if file not found (this can also be a boolean for catching missing files)
user = loaded.section("user123")

print(user.get("name"))  # "Steve"
print(user.get("score")) # 42
print(user.get("items", default_items)) # [1] (uses a copy of default because "items" is not defined in botdata.rdm)
default = rheel.TempObj.load("default.rtd")

loaded = rheel.TempObj.load("tempbotdata.rtd", default)

print(loaded.get("score")) # 42 or <ExpiredKey key="score" expired_at='2026-03-03T18:00:00.000000+00:00'>
print(loaded.get("name", default)) # "Steve" or default
print(loaded.get_expiration("name")) # timestamp of expiration

Modify Data

Overwrite

# same with RTD
user.set("name", str, "Alex")
print(user.get("name")) # "Alex"

# How to prevent overwrites:
user.set("name", str, "Steve", overwrite=False) # -> raise KeyError
print(user.get("name"))                         # "Alex"

Add or Multiply (int, float, datetime)

# same with RTD
from datetime import datetime

user.set("score", int, 10)   # 10
user.add("score", 5)         # 15
user.add("score", -3)        # 12
user.multiply("score", 2)    # 24
user.multiply("score", 0.25) # 6

user.set("last_login", datetime, datetime.now()) # 2026-02-21T21:39:18.398038
user.add("last_login", 3605)                     # 2026-02-21T22:39:23.398038

Extend (str, list, set, dict, Path)

# same with RTD
from pathlib import Path

user.set("name", str, "Steve")   # "Steve"
user.extend("name", " the Hero") # "Steve the Hero"

user.set("items", list[int], [1]) # [1]
user.extend("items", 2)           # [1, 2]
user.extend("items", [3, 4])      # [1, 2, 3, 4]

user.set("tags", set[str], {"a"}) # {"a"}
user.extend("tags", "b")          # {"a", "b"}

user.set("settings", dict[str,int], {"a":1}) # {"a": 1}
user.extend("settings", {"b":2})             # {"a": 1, "b": 2}

config_dir = Path("/settings")
user.set("config_file", Path, config_dir)   # Path(/settings)
user.extend("config_file", "steve3828.rdm") # Path(/settings/steve3828.rdm)

Extend Expiration:

# not featured in RDM
temp.extend_expiration("name", seconds=30)                                                                   # adds 30 seconds
temp.extend_expiration("name", new_expires_at=datetime.datetime(2026,3,3,18,0,tzinfo=datetime.timezone.utc)) # set new expiration timestamp

Convert non-RDM Files

# not featured in RTD
rheelDM.Obj.convert_file("/settings/data.json", overwrite=True)
rheelDM.Obj.load("/settings/data.rdm")

Delete Data

user.delete("score") # key, value and type of "score" will be deleted entirely from the RDM or RTD file.

🧠 Supported Types

  • str
  • int
  • float
  • bool
  • None
  • list[T]
  • set[T]
  • tuple[T]
  • dict[K, V]
  • Nested generics (e.g. list[dict[int, str]])
  • Union types (e.g. str | int)
  • Mixed generics (e.g. list[str | int])
  • datetime:
    • datetime
    • date
    • time
  • pathlib:
    • Path

Custom Type Registry

You can register your own types globally.

import rheelDM

class Color:
    def __init__(self, hex_code: str):
        self.hex = hex_code

rheelDM.TypeRegistry.register(
    "Color",
    Color,
    lambda v: f'"{v.hex}"',
    lambda v: Color(v.strip('"'))
)

Now you can use it like any native type:

# same with TempObj and set()
data.section("settings").set("theme", Color, Color("#ff8800"))

🛡 Why RDM Instead of JSON or TOML?

Strict Typing

JSON and TOML do not enforce types.
RDM validates everything on write and load.

Python-Native Types

JSON cannot store:

  • datetime
  • Path
  • set
  • tuple
  • Union types
  • Nested generics
  • int as dict-keys
  • None (stores it as null)

TOML cannot store:

  • Path
  • set
  • None
  • int as dict-keys

RDM can store all of these, even the most complex and custom types.

Cleaner Structure

Section-based (not RTD) and auto-aligned format keeps large files organized and readable.

Human Editable

Minimal syntax makes manual edits easier than ever:

key : type = value

🎯 Ideal Use Cases

  • Game save systems
  • Discord bot data
  • Typed configuration systems
  • CLI tool configs
  • Small to medium persistent data storage

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

rheel_data_management-2.0.tar.gz (22.8 kB view details)

Uploaded Source

Built Distribution

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

rheel_data_management-2.0-py3-none-any.whl (22.1 kB view details)

Uploaded Python 3

File details

Details for the file rheel_data_management-2.0.tar.gz.

File metadata

  • Download URL: rheel_data_management-2.0.tar.gz
  • Upload date:
  • Size: 22.8 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for rheel_data_management-2.0.tar.gz
Algorithm Hash digest
SHA256 8f65ea8043c8fdf43065a4961e24817b9dce39097d52a12d324c54ce5d708ed1
MD5 0f5932f0c6b2c58d732cdef549184d56
BLAKE2b-256 a8f4b2a8a1933665827b6c11e295010b8cd0b7ce9c73382d218f52104d9f8226

See more details on using hashes here.

Provenance

The following attestation bundles were made for rheel_data_management-2.0.tar.gz:

Publisher: python-publish.yml on CoCo-R38/Rheel_Data_Management

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file rheel_data_management-2.0-py3-none-any.whl.

File metadata

File hashes

Hashes for rheel_data_management-2.0-py3-none-any.whl
Algorithm Hash digest
SHA256 259e72122eb1326ad4aafef4dfd2f1f959be37d02cec11c54339e597ecd904c6
MD5 5c18d0a7ecd0d290688396667ff116e9
BLAKE2b-256 4735a099bcb714d6879688d52f9a298864a22a41dcd5e115dcc2b15586e33585

See more details on using hashes here.

Provenance

The following attestation bundles were made for rheel_data_management-2.0-py3-none-any.whl:

Publisher: python-publish.yml on CoCo-R38/Rheel_Data_Management

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

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