json-database 0.7.0__tar.gz → 0.8.1__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,202 @@
1
+ Metadata-Version: 2.1
2
+ Name: json_database
3
+ Version: 0.8.1
4
+ Summary: searchable json database with persistence
5
+ Home-page: https://github.com/TigreGotico/json_database
6
+ Author: jarbasAI
7
+ Author-email: jarbasai@mailfence.com
8
+ License: MIT
9
+ Description: # Json Database
10
+
11
+ Python dict based database with persistence and search capabilities
12
+
13
+ For those times when you need something simple and sql is overkill
14
+
15
+
16
+ ## Features
17
+
18
+ - pure python
19
+ - save and load from file
20
+ - search recursively by key and key/value pairs
21
+ - fuzzy search
22
+ - supports arbitrary objects
23
+ - supports comments in saved files
24
+
25
+ ## Install
26
+
27
+ ```bash
28
+ pip install json_database
29
+ ```
30
+
31
+ ## Usage
32
+
33
+
34
+ ### JsonStorage
35
+
36
+ Sometimes you need persistent dicts that you can save and load from file
37
+
38
+ ```python
39
+ from json_database import JsonStorage
40
+ from os.path import exists
41
+
42
+ save_path = "my_dict.conf"
43
+
44
+ my_config = JsonStorage(save_path)
45
+
46
+ my_config["lang"] = "pt"
47
+ my_config["secondary_lang"] = "en"
48
+ my_config["email"] = "jarbasai@mailfence.com"
49
+
50
+ # my_config is a python dict
51
+ assert isinstance(my_config, dict)
52
+
53
+ # save to file
54
+ my_config.store()
55
+
56
+ my_config["lang"] = "pt-pt"
57
+
58
+ # revert to previous saved file
59
+ my_config.reload()
60
+ assert my_config["lang"] == "pt"
61
+
62
+ # clear all fields
63
+ my_config.clear()
64
+ assert my_config == {}
65
+
66
+ # load from a specific path
67
+ my_config.load_local(save_path)
68
+ assert my_config == JsonStorage(save_path)
69
+
70
+ # delete stored file
71
+ my_config.remove()
72
+ assert not exists(save_path)
73
+
74
+ # keep working with dict in memory
75
+ print(my_config)
76
+ ```
77
+
78
+ ### JsonDatabase
79
+
80
+ Ever wanted to search a dict?
81
+
82
+ Let's create a dummy database with users
83
+
84
+ ```python
85
+ from json_database import JsonDatabase
86
+
87
+ db_path = "users.db"
88
+
89
+ with JsonDatabase("users", db_path) as db:
90
+ # add some users to the database
91
+
92
+ for user in [
93
+ {"name": "bob", "age": 12},
94
+ {"name": "bobby"},
95
+ {"name": ["joe", "jony"]},
96
+ {"name": "john"},
97
+ {"name": "jones", "age": 35},
98
+ {"name": "joey", "birthday": "may 12"}]:
99
+ db.add_item(user)
100
+
101
+ # pretty print database contents
102
+ db.print()
103
+
104
+
105
+ # auto saved when used with context manager
106
+ # db.commit()
107
+
108
+
109
+ ```
110
+
111
+ search entries by key
112
+
113
+ ```python
114
+ from json_database import JsonDatabase
115
+
116
+ db_path = "users.db"
117
+
118
+ db = JsonDatabase("users", db_path) # load db created in previous example
119
+
120
+ # search by exact key match
121
+ users_with_defined_age = db.search_by_key("age")
122
+
123
+ for user in users_with_defined_age:
124
+ print(user["name"], user["age"])
125
+
126
+ # fuzzy search
127
+ users = db.search_by_key("birth", fuzzy=True)
128
+ for user, conf in users:
129
+ print("matched with confidence", conf)
130
+ print(user["name"], user["birthday"])
131
+ ```
132
+
133
+ search by key value pair
134
+
135
+ ```python
136
+ # search by key/value pair
137
+ users_12years_old = db.search_by_value("age", 12)
138
+
139
+ for user in users_12years_old:
140
+ assert user["age"] == 12
141
+
142
+ # fuzzy search
143
+ jon_users = db.search_by_value("name", "jon", fuzzy=True)
144
+ for user, conf in jon_users:
145
+ print(user["name"])
146
+ print("matched with confidence", conf)
147
+ # NOTE that one of the users has a list instead of a string in the name, it also matches
148
+ ```
149
+
150
+ updating an existing entry
151
+
152
+ ```python
153
+ # get database item
154
+ item = {"name": "bobby"}
155
+
156
+ item_id = db.get_item_id(item)
157
+
158
+ if item_id >= 0:
159
+ new_item = {"name": "don't call me bobby"}
160
+ db.update_item(item_id, new_item)
161
+ else:
162
+ print("item not found in database")
163
+
164
+ # clear changes since last commit
165
+ db.reset()
166
+ ```
167
+
168
+ You can save arbitrary objects to the database
169
+
170
+ ```python
171
+ from json_database import JsonDatabase
172
+
173
+ db = JsonDatabase("users", "~/databases/users.json")
174
+
175
+
176
+ class User:
177
+ def __init__(self, email, key=None, data=None):
178
+ self.email = email
179
+ self.secret_key = key
180
+ self.data = data
181
+
182
+ user1 = User("first@mail.net", data={"name": "jonas", "birthday": "12 May"})
183
+ user2 = User("second@mail.net", "secret", data={"name": ["joe", "jony"], "age": 12})
184
+
185
+ # objects will be "jsonified" here, they will no longer be User objects
186
+ # if you need them to be a specific class use some ORM lib instead (SQLAlchemy is great)
187
+ db.add_item(user1)
188
+ db.add_item(user2)
189
+
190
+ # search entries with non empty key
191
+ print(db.search_by_key("secret_key"))
192
+
193
+ # search in user provided data
194
+ print(db.search_by_key("birth", fuzzy=True))
195
+
196
+ # search entries with a certain value
197
+ print(db.search_by_value("age", 12))
198
+ print(db.search_by_value("name", "jon", fuzzy=True))
199
+
200
+ ```
201
+ Platform: UNKNOWN
202
+ Description-Content-Type: text/markdown
@@ -1,5 +1,6 @@
1
1
  import json
2
2
  import logging
3
+ import os
3
4
  from os import makedirs, remove
4
5
  from os.path import expanduser, isdir, dirname, exists, isfile, join
5
6
  from pprint import pprint
@@ -7,6 +8,7 @@ from tempfile import gettempdir
7
8
 
8
9
  from combo_lock import ComboLock
9
10
 
11
+ from json_database.crypto import decrypt_from_json, encrypt_as_json
10
12
  from json_database.exceptions import InvalidItemID, DatabaseNotCommitted, \
11
13
  SessionError, MatchError
12
14
  from json_database.utils import DummyLock, load_commented_json, merge_dict, \
@@ -104,6 +106,41 @@ class JsonStorage(dict):
104
106
  raise SessionError
105
107
 
106
108
 
109
+ class EncryptedJsonStorage(JsonStorage):
110
+ """persistent python dict, stored AES encrypted to file"""
111
+
112
+ def __init__(self, encrypt_key: str, path: str, disable_lock=False):
113
+ assert len(encrypt_key) == 16
114
+ self.encrypt_key = encrypt_key
115
+ super().__init__(path, disable_lock)
116
+
117
+ def load_local(self, path):
118
+ """
119
+ Load local json file into self.
120
+
121
+ Args:
122
+ path (str): file to load
123
+ """
124
+ super().load_local(path)
125
+ # decrypt after load
126
+ if self:
127
+ decrypted = json.loads(decrypt_from_json(self.encrypt_key, dict(self)))
128
+ self.clear()
129
+ self.update(decrypted)
130
+
131
+ def store(self, path=None):
132
+ """
133
+ store the json db locally.
134
+ """
135
+ decrypted = dict(self)
136
+ encrypted = json.loads(encrypt_as_json(self.encrypt_key, decrypted))
137
+ self.clear()
138
+ self.merge(encrypted) # encrypt before storage
139
+ super().store()
140
+ self.clear()
141
+ self.update(decrypted) # keep it decrypted in memory
142
+
143
+
107
144
  class JsonDatabase(dict):
108
145
  """ searchable persistent dict """
109
146
 
@@ -295,6 +332,22 @@ class JsonStorageXDG(JsonStorage):
295
332
  super().__init__(path, disable_lock=disable_lock)
296
333
 
297
334
 
335
+ class EncryptedJsonStorageXDG(EncryptedJsonStorage):
336
+ """ xdg respectful persistent dicts """
337
+
338
+ def __init__(self,
339
+ encrypt_key: str,
340
+ name: str,
341
+ xdg_folder=xdg_data_home(),
342
+ disable_lock=False,
343
+ subfolder="json_database",
344
+ extension="ejson"):
345
+ self.name = name
346
+ path = join(xdg_folder, subfolder, f"{name}.{extension}")
347
+ super().__init__(encrypt_key=encrypt_key, path=path,
348
+ disable_lock=disable_lock)
349
+
350
+
298
351
  class JsonDatabaseXDG(JsonDatabase):
299
352
  """ xdg respectful json database """
300
353
 
@@ -312,3 +365,23 @@ class JsonConfigXDG(JsonStorageXDG):
312
365
  disable_lock=False, subfolder="json_database",
313
366
  extension="json"):
314
367
  super().__init__(name, xdg_folder, disable_lock, subfolder, extension)
368
+
369
+
370
+ if __name__ == "__main__":
371
+ # quick test
372
+ os.remove("/tmp/test.json")
373
+ db = EncryptedJsonStorage("S" * 16, "/tmp/test.json")
374
+ db["A"] = "42"
375
+ print(db) # {'A': '42'} - not encrypted in memory
376
+ db.store()
377
+ print(db) # {'A': '42'} - still decrypted
378
+ db.reload()
379
+ print(db) # {'A': '42'} - still decrypted
380
+ db = EncryptedJsonStorage("S" * 16, "/tmp/test.json")
381
+ print(db) # {'A': '42'} - still not encrypted
382
+
383
+ db = JsonStorage("/tmp/test.json")
384
+ print(db) # encrypted
385
+ # {'ciphertext': 'ad0da72dc412d6b1240e478560354893d62caf',
386
+ # 'tag': '3bc39dbfad7b0d7e50f3e652ee341819',
387
+ # 'nonce': '3020ddafc9853e7686ee0368f9be6e25'}
@@ -0,0 +1,80 @@
1
+ import json
2
+ import zlib
3
+ from binascii import hexlify
4
+ from binascii import unhexlify
5
+
6
+ try:
7
+ # pycryptodomex
8
+ from Cryptodome.Cipher import AES
9
+ except ImportError:
10
+ # pycrypto + pycryptodome
11
+ try:
12
+ from Crypto.Cipher import AES
13
+ except:
14
+ AES = None
15
+
16
+
17
+ def encrypt(key, text, nonce=None):
18
+ if AES is None:
19
+ raise ImportError("run pip install pycryptodomex")
20
+ if not isinstance(text, bytes):
21
+ text = bytes(text, encoding="utf-8")
22
+ if not isinstance(key, bytes):
23
+ key = bytes(key, encoding="utf-8")
24
+ cipher = AES.new(key, AES.MODE_GCM, nonce=nonce)
25
+ text = compress_payload(text)
26
+ ciphertext, tag = cipher.encrypt_and_digest(text)
27
+ return ciphertext, tag, cipher.nonce
28
+
29
+
30
+ def decrypt(key, ciphertext, tag, nonce) -> str:
31
+ if AES is None:
32
+ raise ImportError("run pip install pycryptodomex")
33
+ if not isinstance(key, bytes):
34
+ key = bytes(key, encoding="utf-8")
35
+ cipher = AES.new(key, AES.MODE_GCM, nonce)
36
+ data = cipher.decrypt_and_verify(ciphertext, tag)
37
+ text = decompress_payload(data).decode(encoding="utf-8")
38
+ return text
39
+
40
+
41
+ def encrypt_as_json(key, data):
42
+ if isinstance(data, dict):
43
+ data = json.dumps(data)
44
+ if len(key) > 16:
45
+ key = key[0:16]
46
+ ciphertext, tag, nonce = encrypt(key, data)
47
+ return json.dumps({"ciphertext": hexlify(ciphertext).decode('utf-8'),
48
+ "tag": hexlify(tag).decode('utf-8'),
49
+ "nonce": hexlify(nonce).decode('utf-8')})
50
+
51
+
52
+ def decrypt_from_json(key, data):
53
+ if isinstance(data, str):
54
+ data = json.loads(data)
55
+ if len(key) > 16:
56
+ key = key[0:16]
57
+ ciphertext = unhexlify(data["ciphertext"])
58
+ if data.get("tag") is None: # web crypto
59
+ ciphertext, tag = ciphertext[:-16], ciphertext[-16:]
60
+ else:
61
+ tag = unhexlify(data["tag"])
62
+ nonce = unhexlify(data["nonce"])
63
+ return decrypt(key, ciphertext, tag, nonce)
64
+
65
+
66
+ def compress_payload(text):
67
+ # Compressing text
68
+ if isinstance(text, str):
69
+ decompressed = text.encode("utf-8")
70
+ else:
71
+ decompressed = text
72
+ return zlib.compress(decompressed)
73
+
74
+
75
+ def decompress_payload(compressed):
76
+ # Decompressing text
77
+ if isinstance(compressed, str):
78
+ # assume hex
79
+ compressed = unhexlify(compressed)
80
+ return zlib.decompress(compressed)
@@ -12,3 +12,11 @@ class SessionError(RuntimeError):
12
12
 
13
13
  class MatchError(ValueError):
14
14
  """ could not match an item in db """
15
+
16
+
17
+ class DecryptionKeyError(KeyError):
18
+ """ Could not decrypt payload """
19
+
20
+
21
+ class EncryptionKeyError(KeyError):
22
+ """ Could not encrypt payload """
@@ -0,0 +1,6 @@
1
+ # START_VERSION_BLOCK
2
+ VERSION_MAJOR = 0
3
+ VERSION_MINOR = 8
4
+ VERSION_BUILD = 1
5
+ VERSION_ALPHA = 0
6
+ # END_VERSION_BLOCK
@@ -0,0 +1,202 @@
1
+ Metadata-Version: 2.1
2
+ Name: json-database
3
+ Version: 0.8.1
4
+ Summary: searchable json database with persistence
5
+ Home-page: https://github.com/TigreGotico/json_database
6
+ Author: jarbasAI
7
+ Author-email: jarbasai@mailfence.com
8
+ License: MIT
9
+ Description: # Json Database
10
+
11
+ Python dict based database with persistence and search capabilities
12
+
13
+ For those times when you need something simple and sql is overkill
14
+
15
+
16
+ ## Features
17
+
18
+ - pure python
19
+ - save and load from file
20
+ - search recursively by key and key/value pairs
21
+ - fuzzy search
22
+ - supports arbitrary objects
23
+ - supports comments in saved files
24
+
25
+ ## Install
26
+
27
+ ```bash
28
+ pip install json_database
29
+ ```
30
+
31
+ ## Usage
32
+
33
+
34
+ ### JsonStorage
35
+
36
+ Sometimes you need persistent dicts that you can save and load from file
37
+
38
+ ```python
39
+ from json_database import JsonStorage
40
+ from os.path import exists
41
+
42
+ save_path = "my_dict.conf"
43
+
44
+ my_config = JsonStorage(save_path)
45
+
46
+ my_config["lang"] = "pt"
47
+ my_config["secondary_lang"] = "en"
48
+ my_config["email"] = "jarbasai@mailfence.com"
49
+
50
+ # my_config is a python dict
51
+ assert isinstance(my_config, dict)
52
+
53
+ # save to file
54
+ my_config.store()
55
+
56
+ my_config["lang"] = "pt-pt"
57
+
58
+ # revert to previous saved file
59
+ my_config.reload()
60
+ assert my_config["lang"] == "pt"
61
+
62
+ # clear all fields
63
+ my_config.clear()
64
+ assert my_config == {}
65
+
66
+ # load from a specific path
67
+ my_config.load_local(save_path)
68
+ assert my_config == JsonStorage(save_path)
69
+
70
+ # delete stored file
71
+ my_config.remove()
72
+ assert not exists(save_path)
73
+
74
+ # keep working with dict in memory
75
+ print(my_config)
76
+ ```
77
+
78
+ ### JsonDatabase
79
+
80
+ Ever wanted to search a dict?
81
+
82
+ Let's create a dummy database with users
83
+
84
+ ```python
85
+ from json_database import JsonDatabase
86
+
87
+ db_path = "users.db"
88
+
89
+ with JsonDatabase("users", db_path) as db:
90
+ # add some users to the database
91
+
92
+ for user in [
93
+ {"name": "bob", "age": 12},
94
+ {"name": "bobby"},
95
+ {"name": ["joe", "jony"]},
96
+ {"name": "john"},
97
+ {"name": "jones", "age": 35},
98
+ {"name": "joey", "birthday": "may 12"}]:
99
+ db.add_item(user)
100
+
101
+ # pretty print database contents
102
+ db.print()
103
+
104
+
105
+ # auto saved when used with context manager
106
+ # db.commit()
107
+
108
+
109
+ ```
110
+
111
+ search entries by key
112
+
113
+ ```python
114
+ from json_database import JsonDatabase
115
+
116
+ db_path = "users.db"
117
+
118
+ db = JsonDatabase("users", db_path) # load db created in previous example
119
+
120
+ # search by exact key match
121
+ users_with_defined_age = db.search_by_key("age")
122
+
123
+ for user in users_with_defined_age:
124
+ print(user["name"], user["age"])
125
+
126
+ # fuzzy search
127
+ users = db.search_by_key("birth", fuzzy=True)
128
+ for user, conf in users:
129
+ print("matched with confidence", conf)
130
+ print(user["name"], user["birthday"])
131
+ ```
132
+
133
+ search by key value pair
134
+
135
+ ```python
136
+ # search by key/value pair
137
+ users_12years_old = db.search_by_value("age", 12)
138
+
139
+ for user in users_12years_old:
140
+ assert user["age"] == 12
141
+
142
+ # fuzzy search
143
+ jon_users = db.search_by_value("name", "jon", fuzzy=True)
144
+ for user, conf in jon_users:
145
+ print(user["name"])
146
+ print("matched with confidence", conf)
147
+ # NOTE that one of the users has a list instead of a string in the name, it also matches
148
+ ```
149
+
150
+ updating an existing entry
151
+
152
+ ```python
153
+ # get database item
154
+ item = {"name": "bobby"}
155
+
156
+ item_id = db.get_item_id(item)
157
+
158
+ if item_id >= 0:
159
+ new_item = {"name": "don't call me bobby"}
160
+ db.update_item(item_id, new_item)
161
+ else:
162
+ print("item not found in database")
163
+
164
+ # clear changes since last commit
165
+ db.reset()
166
+ ```
167
+
168
+ You can save arbitrary objects to the database
169
+
170
+ ```python
171
+ from json_database import JsonDatabase
172
+
173
+ db = JsonDatabase("users", "~/databases/users.json")
174
+
175
+
176
+ class User:
177
+ def __init__(self, email, key=None, data=None):
178
+ self.email = email
179
+ self.secret_key = key
180
+ self.data = data
181
+
182
+ user1 = User("first@mail.net", data={"name": "jonas", "birthday": "12 May"})
183
+ user2 = User("second@mail.net", "secret", data={"name": ["joe", "jony"], "age": 12})
184
+
185
+ # objects will be "jsonified" here, they will no longer be User objects
186
+ # if you need them to be a specific class use some ORM lib instead (SQLAlchemy is great)
187
+ db.add_item(user1)
188
+ db.add_item(user2)
189
+
190
+ # search entries with non empty key
191
+ print(db.search_by_key("secret_key"))
192
+
193
+ # search in user provided data
194
+ print(db.search_by_key("birth", fuzzy=True))
195
+
196
+ # search entries with a certain value
197
+ print(db.search_by_value("age", 12))
198
+ print(db.search_by_value("name", "jon", fuzzy=True))
199
+
200
+ ```
201
+ Platform: UNKNOWN
202
+ Description-Content-Type: text/markdown
@@ -2,12 +2,15 @@ LICENSE
2
2
  README.md
3
3
  setup.py
4
4
  json_database/__init__.py
5
+ json_database/crypto.py
5
6
  json_database/exceptions.py
6
7
  json_database/search.py
7
8
  json_database/utils.py
9
+ json_database/version.py
8
10
  json_database/xdg_utils.py
9
11
  json_database.egg-info/PKG-INFO
10
12
  json_database.egg-info/SOURCES.txt
11
13
  json_database.egg-info/dependency_links.txt
12
14
  json_database.egg-info/requires.txt
13
- json_database.egg-info/top_level.txt
15
+ json_database.egg-info/top_level.txt
16
+ test/test_crypto.py
@@ -0,0 +1 @@
1
+ combo_lock<1.0.0,>=0.2.1
@@ -0,0 +1,73 @@
1
+ import os
2
+ import os.path
3
+
4
+ from setuptools import setup
5
+
6
+ BASEDIR = os.path.abspath(os.path.dirname(__file__))
7
+
8
+
9
+ def package_files(directory):
10
+ paths = []
11
+ for (path, _, filenames) in os.walk(directory):
12
+ for filename in filenames:
13
+ paths.append(os.path.join('..', path, filename))
14
+ return paths
15
+
16
+
17
+ def required(requirements_file):
18
+ """ Read requirements file and remove comments and empty lines. """
19
+ with open(os.path.join(BASEDIR, requirements_file), 'r') as f:
20
+ requirements = f.read().splitlines()
21
+ if 'MYCROFT_LOOSE_REQUIREMENTS' in os.environ:
22
+ print('USING LOOSE REQUIREMENTS!')
23
+ requirements = [r.replace('==', '>=').replace('~=', '>=') for r in requirements]
24
+ return [pkg for pkg in requirements
25
+ if pkg.strip() and not pkg.startswith("#")]
26
+
27
+
28
+ def get_version():
29
+ """ Find the version of ovos-core"""
30
+ version = None
31
+ version_file = os.path.join(BASEDIR, 'json_database', 'version.py')
32
+ major, minor, build, alpha = (None, None, None, None)
33
+ with open(version_file) as f:
34
+ for line in f:
35
+ if 'VERSION_MAJOR' in line:
36
+ major = line.split('=')[1].strip()
37
+ elif 'VERSION_MINOR' in line:
38
+ minor = line.split('=')[1].strip()
39
+ elif 'VERSION_BUILD' in line:
40
+ build = line.split('=')[1].strip()
41
+ elif 'VERSION_ALPHA' in line:
42
+ alpha = line.split('=')[1].strip()
43
+
44
+ if ((major and minor and build and alpha) or
45
+ '# END_VERSION_BLOCK' in line):
46
+ break
47
+ version = f"{major}.{minor}.{build}"
48
+ if int(alpha):
49
+ version += f"a{alpha}"
50
+ return version
51
+
52
+
53
+ def get_description():
54
+ with open(os.path.join(BASEDIR, "README.md"), "r") as f:
55
+ long_description = f.read()
56
+ return long_description
57
+
58
+
59
+ setup(
60
+ name='json_database',
61
+ version=get_version(),
62
+ packages=['json_database'],
63
+ package_data={'': package_files('json_database')},
64
+ include_package_data=True,
65
+ url='https://github.com/TigreGotico/json_database',
66
+ license='MIT',
67
+ author='jarbasAI',
68
+ author_email='jarbasai@mailfence.com',
69
+ install_requires=required('requirements.txt'),
70
+ description='searchable json database with persistence',
71
+ long_description=get_description(),
72
+ long_description_content_type="text/markdown",
73
+ )
@@ -0,0 +1,53 @@
1
+ import os
2
+ import unittest
3
+
4
+ from json_database import EncryptedJsonStorage, JsonStorage # Replace with actual import
5
+
6
+
7
+ class TestEncryptedJsonStorage(unittest.TestCase):
8
+ def setUp(self):
9
+ self.key = "S" * 16 # Replace with actual key generation if needed
10
+ self.file_path = "/tmp/test.json"
11
+ # Ensure the test file doesn't exist at the start of each test
12
+ if os.path.exists(self.file_path):
13
+ os.remove(self.file_path)
14
+
15
+ def tearDown(self):
16
+ # Clean up the test file after each test
17
+ if os.path.exists(self.file_path):
18
+ os.remove(self.file_path)
19
+
20
+ def test_add_and_store_data(self):
21
+ db = EncryptedJsonStorage(self.key, self.file_path)
22
+ db["A"] = "42"
23
+ self.assertEqual(db["A"], "42") # Check in-memory data
24
+ db.store()
25
+ self.assertTrue(os.path.exists(self.file_path)) # File should be created
26
+
27
+ def test_encryption_in_file(self):
28
+ db = EncryptedJsonStorage(self.key, self.file_path)
29
+ db["A"] = "42"
30
+ db.store()
31
+ with open(self.file_path, "r") as file:
32
+ file_data = file.read()
33
+ self.assertNotIn("42", file_data) # Data should be encrypted
34
+
35
+ def test_decryption_after_reload(self):
36
+ db = EncryptedJsonStorage(self.key, self.file_path)
37
+ db["A"] = "42"
38
+ db.store()
39
+ db.reload()
40
+ self.assertEqual(db["A"], "42") # Data should be decrypted correctly
41
+
42
+ def test_jsonstorage_read_encrypted_data(self):
43
+ encrypted_db = EncryptedJsonStorage(self.key, self.file_path)
44
+ encrypted_db["A"] = "42"
45
+ encrypted_db.store()
46
+
47
+ db = JsonStorage(self.file_path)
48
+ self.assertIn("ciphertext", db) # Check that it's encrypted
49
+ self.assertNotIn("A", db)
50
+
51
+
52
+ if __name__ == "__main__":
53
+ unittest.main()
@@ -1,13 +0,0 @@
1
- Metadata-Version: 2.1
2
- Name: json_database
3
- Version: 0.7.0
4
- Summary: searchable json database with persistence
5
- Home-page: https://github.com/OpenJarbas/json_database
6
- Author: jarbasAI
7
- Author-email: jarbasai@mailfence.com
8
- License: MIT
9
- Platform: UNKNOWN
10
- License-File: LICENSE
11
-
12
- UNKNOWN
13
-
@@ -1,13 +0,0 @@
1
- Metadata-Version: 2.1
2
- Name: json-database
3
- Version: 0.7.0
4
- Summary: searchable json database with persistence
5
- Home-page: https://github.com/OpenJarbas/json_database
6
- Author: jarbasAI
7
- Author-email: jarbasai@mailfence.com
8
- License: MIT
9
- Platform: UNKNOWN
10
- License-File: LICENSE
11
-
12
- UNKNOWN
13
-
@@ -1 +0,0 @@
1
- combo_lock~=0.2.1
@@ -1,13 +0,0 @@
1
- from setuptools import setup
2
-
3
- setup(
4
- name='json_database',
5
- version='0.7.0',
6
- packages=['json_database'],
7
- url='https://github.com/OpenJarbas/json_database',
8
- license='MIT',
9
- author='jarbasAI',
10
- author_email='jarbasai@mailfence.com',
11
- install_requires=["combo_lock~=0.2.1"],
12
- description='searchable json database with persistence'
13
- )
File without changes
File without changes
File without changes