Skip to main content

A dot-notation dictionary with nested structure support and Polars/JSON persistence

Project description

nesteddotdict

CI PyPI version Python License: MIT

A lightweight Python dictionary that supports dot notation access, nested structures, and Polars DataFrame persistence via JSON files.

Features

  • Dot notation and bracket notation interchangeably
  • Nested DotDict instances with full dot-access
  • Dict-like interface: keys(), values(), items(), len(), iteration
  • Serialize and deserialize to/from JSON files (one file per key)
  • Native support for Polars DataFrames — schema and data are preserved across read/write cycles
  • Support for datetime.date, datetime.datetime, datetime.time serialization

Installation

pip install nesteddotdict

Quick start

from nesteddotdict import DotDict

d = DotDict(name="Alice", age=30)
print(d.name)   # Alice
print(d["age"]) # 30

d.city = "Paris"
d["country"] = "France"

Nested structures

DotDict instances can be nested to any depth:

d = DotDict(
    user=DotDict(name="Alice", role="admin"),
    config={"debug": True, "level": 3},
)

print(d.user.name)        # Alice
print(d.config["debug"])  # True

Plain dicts assigned as values are kept as-is. Use DotDict(...) explicitly for nested dot access.

Initialization patterns

# From keyword arguments
d = DotDict(x=1, y=2)

# From a dict
d = DotDict({"x": 1, "y": 2})

# From another DotDict (shallow copy)
copy = DotDict(d)

# Mixed: dict + kwargs (kwargs take precedence)
d = DotDict({"x": 1, "y": 2}, y=99)  # y == 99

Dict-like interface

d = DotDict(a=1, b=2, c=3)

list(d.keys())    # ['a', 'b', 'c']
list(d.values())  # [1, 2, 3]
dict(d.items())   # {'a': 1, 'b': 2, 'c': 3}
len(d)            # 3

for key in d:
    print(key, d[key])

Conversion

d = DotDict(a=1, inner=DotDict(b=2))

d.to_dict()
# {'a': 1, 'inner': {'b': 2}}

DotDict.from_dict({"a": 1, "b": {"c": 2}})
# DotDict(a=1, b={'c': 2})

JSON persistence

Each key is serialized to its own .json file in a directory:

import polars as pl
from nesteddotdict import DotDict

d = DotDict(
    label="experiment_1",
    params={"lr": 0.01, "epochs": 100},
    results=pl.DataFrame({"metric": ["accuracy", "f1"], "value": [0.95, 0.93]}),
)

# Write to disk
d.write_json_files("./my_experiment")
# Creates:
#   my_experiment/label.json
#   my_experiment/params.json
#   my_experiment/results.json  ← DataFrame serialized with schema

# Read back
d2 = DotDict.read_json_sources("./my_experiment")

print(d2.label)              # experiment_1
print(d2.params["lr"])       # 0.01
print(type(d2.results))      # <class 'polars.dataframe.frame.DataFrame'>
print(d2.results)
# shape: (2, 2)
# ┌──────────┬───────┐
# │ metric   ┆ value │
# │ ---      ┆ ---   │
# │ str      ┆ f64   │
# ╞══════════╪═══════╡
# │ accuracy ┆ 0.95  │
# │ f1       ┆ 0.93  │
# └──────────┴───────┘

You can also load a subset of keys:

d = DotDict.read_json_sources("./my_experiment", keys=["label", "results"])

Polars support

Polars DataFrames are fully round-tripped through JSON — including schema (dtypes) and temporal types:

import datetime
import polars as pl
from nesteddotdict import DotDict

df = pl.DataFrame({
    "date": [datetime.date(2024, 1, 1), datetime.date(2024, 6, 15)],
    "value": pl.Series([100, 200], dtype=pl.Int32),
})

d = DotDict(df=df)
d.write_json_files("/tmp/data")

restored = DotDict.read_json_sources("/tmp/data")
print(restored.df.schema)
# {'date': Date, 'value': Int32}

Supported Polars types: all numeric types, Date, Datetime, Time, Duration, List, String, Boolean.

Running tests

uv run pytest

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

nesteddotdict-0.1.1.tar.gz (11.8 kB view details)

Uploaded Source

Built Distribution

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

nesteddotdict-0.1.1-py3-none-any.whl (8.5 kB view details)

Uploaded Python 3

File details

Details for the file nesteddotdict-0.1.1.tar.gz.

File metadata

  • Download URL: nesteddotdict-0.1.1.tar.gz
  • Upload date:
  • Size: 11.8 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.12.3

File hashes

Hashes for nesteddotdict-0.1.1.tar.gz
Algorithm Hash digest
SHA256 8f73f4b58e8069ebb17334c949da3013874e31bda364d2b9aeaddab3727c9baa
MD5 4ceb677823c4fef55de98c8a9ccba58f
BLAKE2b-256 52ae416186056c93c66f837285c4d0dceb3701f9d13f057482fb1da8e0dd50b1

See more details on using hashes here.

File details

Details for the file nesteddotdict-0.1.1-py3-none-any.whl.

File metadata

  • Download URL: nesteddotdict-0.1.1-py3-none-any.whl
  • Upload date:
  • Size: 8.5 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.12.3

File hashes

Hashes for nesteddotdict-0.1.1-py3-none-any.whl
Algorithm Hash digest
SHA256 37efdcf7612234155952e4784b3534ffb6e7ad32a587f480d16fc524da74158f
MD5 3755c76c175a7a360357cf24181d482a
BLAKE2b-256 b7a080e5ae1f6b8f9113cbaea8158b2dc604e42daf1d648b66816935dbd2218b

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