Metadata-Version: 2.4
Name: python-jsonstore
Version: 2.0.0
Summary: Map JSON files onto Python attributes for simple configuration storage
Author-email: Oliver Bristow <github+pypi@oliverbristow.co.uk>
License-Expression: MIT
Project-URL: Homepage, https://github.com/Code0x58/python-jsonstore/
Keywords: json,key,value,store
Classifier: Development Status :: 5 - Production/Stable
Classifier: Intended Audience :: Developers
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.9
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Programming Language :: Python :: 3.14
Classifier: Programming Language :: Python :: 3.15
Classifier: Programming Language :: Python :: Implementation :: CPython
Classifier: Programming Language :: Python :: Implementation :: PyPy
Classifier: Topic :: Database
Classifier: Topic :: Software Development
Requires-Python: >=3.9
Description-Content-Type: text/x-rst
License-File: LICENCE.md
Dynamic: license-file

|PyPI| |Build Status| |Coverage Report|

jsonstore
=========

``JsonStore`` maps a JSON object's keys to Python attributes. Use it to
load and save configuration containing nested dictionaries and lists.

Requires Python 3.9 or newer. Tests run on CPython 3.9–3.15 and PyPy 3.11.

Examples
--------

Install with ``pip install python-jsonstore``.

Basics
~~~~~~

.. code:: python

    from jsonstore import JsonStore

    # Assignments and deletions are saved automatically.
    store = JsonStore("config.json")
    store.message = "hello"
    store.options = {"enabled": True, "greeting": "💐"}
    store.numbers = [1, 2, 3]
    assert "message" in store
    del store.message

    # Dot-separated keys traverse dictionaries.
    store["options.enabled"] = False
    assert store["options", "enabled"] is False

    # Tuple or list paths also accept list indices and slices.
    assert store["numbers", -1] == 3
    assert store[["numbers", 1]] == 2
    del store["numbers", :2]
    assert store.numbers == [3]

    # A one-element tuple addresses a literal key containing a dot.
    store[("literal.key",)] = "value"

Reads and assignments use deep copies. To update a stored collection,
assign the modified value back; ``+=`` also does this:

.. code:: python

    store.numbers.append(4)
    assert store.numbers == [3]
    store.numbers += [4, 5]
    assert store.numbers == [3, 4, 5]

Use item access for keys that conflict with ``JsonStore`` attributes.
``indent`` controls JSON formatting and defaults to 2; use ``None`` for
compact output. ``auto_commit=False`` defers saving until a transaction
commits.

Transactions
~~~~~~~~~~~~

Use ``with store:`` to group changes into a transaction. Transactions may
be nested; only successful exit from the outermost transaction saves the
file. An exception in a transaction restores its previous state, including
when saving fails.

.. code:: python

    from jsonstore import JsonStore

    with JsonStore("config.json", indent=None, auto_commit=False) as store:
        store.value = 1
    assert JsonStore("config.json").value == 1

    try:
        with store:
            store.value = 2
            with store:
                store.value = 3
            raise ValueError("cancel the transaction")
    except ValueError:
        pass
    assert store.value == 1
    assert JsonStore("config.json").value == 1

Transactions provide in-memory rollback, with no locking or coordination
between writers. Use one writer per file; separate stores do not reload
each other's changes. Atomic replacement does not guarantee durability
across a power failure.

.. |Build Status| image:: https://github.com/Code0x58/python-jsonstore/actions/workflows/ci.yml/badge.svg
   :target: https://github.com/Code0x58/python-jsonstore/actions/workflows/ci.yml
.. |PyPI| image:: https://img.shields.io/pypi/v/python-jsonstore.svg
   :target: https://pypi.org/project/python-jsonstore/
.. |Coverage Report| image:: https://codecov.io/gh/Code0x58/python-jsonstore/branch/master/graph/badge.svg
   :target: https://codecov.io/gh/Code0x58/python-jsonstore
