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.
- durability-1.0.0/.github/workflows/python-publish.yml +35 -0
- durability-1.0.0/PKG-INFO +56 -0
- durability-1.0.0/README.md +47 -0
- durability-1.0.0/example.py +9 -0
- durability-1.0.0/pyproject.toml +22 -0
- durability-1.0.0/setup.cfg +4 -0
- durability-1.0.0/src/durability/__init__.py +59 -0
- durability-1.0.0/src/durability/_linux.py +9 -0
- durability-1.0.0/src/durability/_mac.py +6 -0
- durability-1.0.0/src/durability/_win.py +9 -0
- durability-1.0.0/src/durability/platforms.py +12 -0
- durability-1.0.0/src/durability/utils.py +20 -0
- durability-1.0.0/src/durability.egg-info/PKG-INFO +56 -0
- durability-1.0.0/src/durability.egg-info/SOURCES.txt +16 -0
- durability-1.0.0/src/durability.egg-info/dependency_links.txt +1 -0
- durability-1.0.0/src/durability.egg-info/scm_file_list.json +14 -0
- durability-1.0.0/src/durability.egg-info/scm_version.json +8 -0
- durability-1.0.0/src/durability.egg-info/top_level.txt +1 -0
|
@@ -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
|
+

|
|
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
|
+

|
|
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,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,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,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
|
+

|
|
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 @@
|
|
|
1
|
+
|
|
@@ -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 @@
|
|
|
1
|
+
durability
|