durability 1.0.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,35 @@
1
+ name: Publish to PyPI
2
+
3
+ on:
4
+ push:
5
+ tags: ["v*"]
6
+
7
+ jobs:
8
+ deploy:
9
+ runs-on: ubuntu-latest
10
+
11
+ permissions:
12
+ id-token: write
13
+ contents: read
14
+
15
+ environment:
16
+ name: pypi
17
+ url: https://pypi.org/p/${{ github.event.repository.name }}
18
+
19
+ steps:
20
+ - name: Checkout source
21
+ uses: actions/checkout@v4
22
+
23
+ - name: Set up Python
24
+ uses: actions/setup-python@v5
25
+ with:
26
+ python-version: "3.13"
27
+
28
+ - name: Install build dependencies
29
+ run: python -m pip install build --user
30
+
31
+ - name: Build a binary wheel and a source tarball
32
+ run: python -m build
33
+
34
+ - name: Publish package distributions to PyPI
35
+ uses: pypa/gh-action-pypi-publish@release/v1
@@ -0,0 +1,56 @@
1
+ Metadata-Version: 2.4
2
+ Name: durability
3
+ Version: 1.0.0
4
+ Summary: A Python persistance library.
5
+ Author-email: Jack Huey <jhhuey@icloud.com>
6
+ Project-URL: Repository, https://github.com/jackr4bbit/Durability
7
+ Requires-Python: >=3.14
8
+ Description-Content-Type: text/markdown
9
+
10
+ # Durability
11
+ ## A tiny Python persistence library.
12
+
13
+ ---
14
+
15
+ ![PyPI Version](https://img.shields.io/pypi/v/durability?style=for-the-badge)
16
+
17
+
18
+ ## Installation
19
+
20
+ ```bash
21
+ pip install durability
22
+ ```
23
+
24
+
25
+ ## Why
26
+ I don't want to have to mess with state/data files. You have to read and write to them whenever you make a change, worry about different locations for them across platforms, and troubleshoot the system. This autosaves and uses the OS's existing dir for application data.
27
+
28
+ ## How to use
29
+ Durability provides a `DataStore` object that may be passed the name of your project (so that files don't conflict). It will automatically use your script/lib's name if you don't provide one.
30
+ In "normal mode" each key of a `DataStore` is another file, but in "simple mode" (which you can use by setting the parameter `simple` to `True`) to get an interface where each key corresponds to a value in the same file.
31
+
32
+ Here's an example of using it in simple mode:
33
+ ```python
34
+ from durability import DataStore
35
+
36
+ store = DataStore("durability-example", simple = True)
37
+
38
+ #If no existing count, set it to 0
39
+ if "count" not in store:
40
+ store["count"] = 0
41
+
42
+ #Increment and display it
43
+ store["count"] += 1
44
+ print(store["count"])
45
+
46
+ #Automatically saves! No hassle necessary.
47
+ ```
48
+ vs in normal mode:
49
+ ```python
50
+ from durability import DataStore
51
+
52
+ store = DataStore("durability-example")
53
+
54
+ store["config"] = {"threads": 3, "username": "abc"}
55
+ store["currentConnections"] = ["192.168.1.13", "100.90.116.124"]
56
+ ```
@@ -0,0 +1,47 @@
1
+ # Durability
2
+ ## A tiny Python persistence library.
3
+
4
+ ---
5
+
6
+ ![PyPI Version](https://img.shields.io/pypi/v/durability?style=for-the-badge)
7
+
8
+
9
+ ## Installation
10
+
11
+ ```bash
12
+ pip install durability
13
+ ```
14
+
15
+
16
+ ## Why
17
+ I don't want to have to mess with state/data files. You have to read and write to them whenever you make a change, worry about different locations for them across platforms, and troubleshoot the system. This autosaves and uses the OS's existing dir for application data.
18
+
19
+ ## How to use
20
+ Durability provides a `DataStore` object that may be passed the name of your project (so that files don't conflict). It will automatically use your script/lib's name if you don't provide one.
21
+ In "normal mode" each key of a `DataStore` is another file, but in "simple mode" (which you can use by setting the parameter `simple` to `True`) to get an interface where each key corresponds to a value in the same file.
22
+
23
+ Here's an example of using it in simple mode:
24
+ ```python
25
+ from durability import DataStore
26
+
27
+ store = DataStore("durability-example", simple = True)
28
+
29
+ #If no existing count, set it to 0
30
+ if "count" not in store:
31
+ store["count"] = 0
32
+
33
+ #Increment and display it
34
+ store["count"] += 1
35
+ print(store["count"])
36
+
37
+ #Automatically saves! No hassle necessary.
38
+ ```
39
+ vs in normal mode:
40
+ ```python
41
+ from durability import DataStore
42
+
43
+ store = DataStore("durability-example")
44
+
45
+ store["config"] = {"threads": 3, "username": "abc"}
46
+ store["currentConnections"] = ["192.168.1.13", "100.90.116.124"]
47
+ ```
@@ -0,0 +1,9 @@
1
+ from durability import DataStore
2
+
3
+ store = DataStore("durability-example", simple = True)
4
+
5
+ if "count" not in store:
6
+ store["count"] = 0
7
+
8
+ store["count"] += 1
9
+ print(store["count"])
@@ -0,0 +1,22 @@
1
+ [build-system]
2
+ requires = ["setuptools>=61.0", "setuptools_scm[toml]>=8.0"]
3
+ build-backend = "setuptools.build_meta"
4
+
5
+ [project]
6
+ name = "durability"
7
+ dynamic = ["version"]
8
+ description = "A Python persistance library."
9
+ readme = "README.md"
10
+ requires-python = ">=3.14"
11
+ authors = [
12
+ { name = "Jack Huey", email = "jhhuey@icloud.com" }
13
+ ]
14
+ dependencies = []
15
+
16
+ [project.urls]
17
+ Repository = "https://github.com/jackr4bbit/Durability"
18
+
19
+ [tool.setuptools]
20
+ packages.find = { where = ["src"] }
21
+
22
+ [tool.setuptools_scm]
@@ -0,0 +1,4 @@
1
+ [egg_info]
2
+ tag_build =
3
+ tag_date = 0
4
+
@@ -0,0 +1,59 @@
1
+ from .utils import useVar, toStr
2
+ from . import platforms
3
+ import inspect
4
+ import json
5
+ from pathlib import Path
6
+
7
+ for frameInfo in inspect.stack():
8
+ module = frameInfo.frame.f_globals.get("__name__")
9
+ if module and module != __name__ and not module.startswith("importlib"):
10
+ if module == "__main__":
11
+ importing = Path(frameInfo.filename).stem
12
+ else:
13
+ importing = str(module)
14
+ break
15
+ else:
16
+ importing = ""
17
+
18
+ type JSON = dict[str, JSON] | list[JSON] | str | int | float | bool | None
19
+
20
+ class DataStore:
21
+ def __init__(self, name: str = importing, simple: bool = False):
22
+ if name == "":
23
+ print("The name of your script/lib could not be detected. Please specify one.")
24
+ if "/" in name or "." in name:
25
+ raise ValueError("Unallowed characters in name")
26
+ self.name = name
27
+
28
+ self.__path = platforms.path / toStr(useVar(platforms.standard, name))
29
+ if not simple:
30
+ self.__path.mkdir(parents=False, exist_ok=True)
31
+
32
+ self.__data = {}
33
+ self.__simple = simple
34
+
35
+ def __setitem__(self, key: str, value: JSON):
36
+ self.__data[key] = value
37
+
38
+ if self.__simple: self.__path.write_text(json.dumps(self.__data))
39
+ else: (self.__path / f"{key}.json").write_text(json.dumps(value))
40
+
41
+ def __contains__(self, key: str) -> bool:
42
+ self.__getitem__(key)
43
+ return key in self.__data
44
+
45
+ def __getitem__(self, key: str):
46
+ path = self.__path if self.__simple else self.__path / f"{key}.json"
47
+
48
+ if key not in self.__data:
49
+ try:
50
+ data = json.loads(path.read_text(encoding="utf-8"))
51
+ except FileNotFoundError:
52
+ return None
53
+
54
+ if self.__simple:
55
+ self.__data = data
56
+ else:
57
+ self.__data[key] = data
58
+
59
+ return self.__data.get(key)
@@ -0,0 +1,9 @@
1
+ import os
2
+ from pathlib import Path
3
+
4
+ if os.geteuid() == 0:
5
+ path = Path("/var/lib")
6
+ else:
7
+ path = Path.home() / ".config"
8
+
9
+ standard = t"{"default"}-durability"
@@ -0,0 +1,6 @@
1
+ import os
2
+ from pathlib import Path
3
+
4
+ root = os.geteuid() == 0
5
+ path = (Path("/") if root else Path.home()) / "Library" / "Application Support"
6
+ standard = t"py.durability.{"default"}"
@@ -0,0 +1,9 @@
1
+ import ctypes
2
+ from pathlib import Path
3
+
4
+ if ctypes.windll.shell32.IsUserAnAdmin() != 0:
5
+ path = Path.cwd().anchor / "ProgramData"
6
+ else:
7
+ path = Path.home() / "AppData" / "Roaming"
8
+
9
+ standard = t"durability/{"default"}"
@@ -0,0 +1,12 @@
1
+ import sys
2
+ from pathlib import Path
3
+ from string.templatelib import Template
4
+
5
+ match sys.platform:
6
+ case "darwin": from ._mac import path, standard
7
+ case "win32": from ._win import path, standard
8
+ case os if os.startswith("linux"): from ._linux import path, standard
9
+ case _: raise OSError(f"Unsupported operating system: {sys.platform}")
10
+
11
+ path: Path = path
12
+ standard: Template = standard
@@ -0,0 +1,20 @@
1
+ from string.templatelib import Template, Interpolation
2
+
3
+ def useVar(template: Template, newValue: str) -> Template:
4
+ parts = []
5
+ for item in template:
6
+ if isinstance(item, Interpolation):
7
+ parts.append(Interpolation(newValue, item.expression, item.conversion, item.format_spec))
8
+ else:
9
+ parts.append(item)
10
+
11
+ return Template(*parts)
12
+
13
+ def toStr(template: Template) -> str:
14
+ result = []
15
+ for i, segment in enumerate(template.strings):
16
+ result.append(segment)
17
+ if i < len(template.values):
18
+ result.append(str(template.values[i]))
19
+
20
+ return "".join(result)
@@ -0,0 +1,56 @@
1
+ Metadata-Version: 2.4
2
+ Name: durability
3
+ Version: 1.0.0
4
+ Summary: A Python persistance library.
5
+ Author-email: Jack Huey <jhhuey@icloud.com>
6
+ Project-URL: Repository, https://github.com/jackr4bbit/Durability
7
+ Requires-Python: >=3.14
8
+ Description-Content-Type: text/markdown
9
+
10
+ # Durability
11
+ ## A tiny Python persistence library.
12
+
13
+ ---
14
+
15
+ ![PyPI Version](https://img.shields.io/pypi/v/durability?style=for-the-badge)
16
+
17
+
18
+ ## Installation
19
+
20
+ ```bash
21
+ pip install durability
22
+ ```
23
+
24
+
25
+ ## Why
26
+ I don't want to have to mess with state/data files. You have to read and write to them whenever you make a change, worry about different locations for them across platforms, and troubleshoot the system. This autosaves and uses the OS's existing dir for application data.
27
+
28
+ ## How to use
29
+ Durability provides a `DataStore` object that may be passed the name of your project (so that files don't conflict). It will automatically use your script/lib's name if you don't provide one.
30
+ In "normal mode" each key of a `DataStore` is another file, but in "simple mode" (which you can use by setting the parameter `simple` to `True`) to get an interface where each key corresponds to a value in the same file.
31
+
32
+ Here's an example of using it in simple mode:
33
+ ```python
34
+ from durability import DataStore
35
+
36
+ store = DataStore("durability-example", simple = True)
37
+
38
+ #If no existing count, set it to 0
39
+ if "count" not in store:
40
+ store["count"] = 0
41
+
42
+ #Increment and display it
43
+ store["count"] += 1
44
+ print(store["count"])
45
+
46
+ #Automatically saves! No hassle necessary.
47
+ ```
48
+ vs in normal mode:
49
+ ```python
50
+ from durability import DataStore
51
+
52
+ store = DataStore("durability-example")
53
+
54
+ store["config"] = {"threads": 3, "username": "abc"}
55
+ store["currentConnections"] = ["192.168.1.13", "100.90.116.124"]
56
+ ```
@@ -0,0 +1,16 @@
1
+ README.md
2
+ example.py
3
+ pyproject.toml
4
+ .github/workflows/python-publish.yml
5
+ src/durability/__init__.py
6
+ src/durability/_linux.py
7
+ src/durability/_mac.py
8
+ src/durability/_win.py
9
+ src/durability/platforms.py
10
+ src/durability/utils.py
11
+ src/durability.egg-info/PKG-INFO
12
+ src/durability.egg-info/SOURCES.txt
13
+ src/durability.egg-info/dependency_links.txt
14
+ src/durability.egg-info/scm_file_list.json
15
+ src/durability.egg-info/scm_version.json
16
+ src/durability.egg-info/top_level.txt
@@ -0,0 +1,14 @@
1
+ {
2
+ "files": [
3
+ ".github/workflows/python-publish.yml",
4
+ "README.md",
5
+ "example.py",
6
+ "pyproject.toml",
7
+ "src/durability/__init__.py",
8
+ "src/durability/_linux.py",
9
+ "src/durability/_mac.py",
10
+ "src/durability/_win.py",
11
+ "src/durability/platforms.py",
12
+ "src/durability/utils.py"
13
+ ]
14
+ }
@@ -0,0 +1,8 @@
1
+ {
2
+ "tag": "1.0.0",
3
+ "distance": 0,
4
+ "node": "g08f4d057c819e17b2da6dd82f144d4973b902c90",
5
+ "dirty": false,
6
+ "branch": "HEAD",
7
+ "node_date": "2026-10-09"
8
+ }
@@ -0,0 +1 @@
1
+ durability