**JSON storage wrapper and editor.** Created with love by Boss_1s.
Once upon a time, this was just a small project to solve a problem: the over-steep learning curve for scratchattach’s database functionality. Now, I have decided to make it a library, something with humble beginnings with big hopes in its future.
Please do note that throughout this repository, the library
key-multivalue-storagemay also be referred to as its repo/package name (key_multivalue_storage) or its abbreviation (kms).
StorageYou can contribute to this open-source project by forking this repo, making changes, then opening a pull request. Be sure to read through the guidelines!
Install with pip:
pip install -U key-multivalue-storage
Or, download the latest version of the .whl file here
You can also choose to download the development environment alongside the package:
pip install -U key-multivalue-storage[dev]
Important
From kms-semver1.3 and onward, the development package will contain both Pylint and Griffe. Versions between kms-semver1.2.2/2026.05.06b and kms-semver1.3 will contain Pylint only.
from key_multivalue_storage import Storage # note the module name!
my-db = Storage("my_top_level_key", mysubkey="myvalue", myothersk="anotherval")
Storage.store().
my-db.store("database.json")
Storage instance.
Storage.indent = 4 #indent size of JSON files
Storage.encode = True #Whether to encode stored values
Storage.auto_delete_self = True
# Whether to automatically release the object
# from memory after certain operations i.e.
# Storage.store()
>>> Storage.Load.by_key("database.json", "my_top_level_key")
Storage(top_lv_key="my_top_level_key", key_value_pairs=["mysubkey"="myvalue", "myothersk"="anotherval"])
>>> Storage.Load.keys("database.json")
["my_top_level_key"]
>>> Storage.Edit.propkey("database.json", # file_path
"my_top_level_key", # top_lv_key
"mysubkey", # oldpropkey
"newkey" # newpropkey
noexist_ok = True # Creates a new subkey with the new subkey name if the old subkey name did not exist
)
>>> Storage.Load.values("database.json", "my_top_level_key", keys=True, raw=False)
["newkey: myvalue", "myothersk: anotherval"]
>>> Storage.Edit.propval("database.json", # file_path
"my_top_level_key", # top_lv_key
"myothersk", # propkey
"wow!" # newval
)
>>> Storage.Load.values("database.json", "my_top_level_key", keys=True, raw=False)
["newkey: myvalue", "myothersk: wow!"]
>>> Storage.Delete.by_propkey("database.json", # file_path
"my_top_level_key", # top_level_key
"myothersk" # property_key
)
>>> Storage.Load.values("database.json", "my_top_level_key", keys=True, raw=False)
["newkey: myvalue"]
Storage instances:
>>> # Adding instances combines the two instances, as long as the top level key is the same.
>>> addStorage = Storage("combine", sk1="val1") + Storage("combine", sk2="val2")
>>> print(addStorage)
Storage(top_lv_key="combine", key_value_pairs=["sk1"="val1", "sk2"="val2"])
>>> # Subtracting instances remove any exact same key-value pairs from the two instances, as long as the top level key is the same.
>>> subStorage = Storage("combine", sk1="val1", sk2="val2") - Storage("combine", sk2="val2")
>>> print(addStorage)
Storage(top_lv_key="combine", key_value_pairs=["sk1"="val1"])
Tip
All kms features are documented in the documentation.