redis-dict 2.6.0__tar.gz → 3.0.0__tar.gz
Sign up to get free protection for your applications and to get access to all the features.
- redis dict-2.6.0/redis_dict.egg-info/PKG-INFO → redis_dict-3.0.0/PKG-INFO +118 -34
- redis dict-2.6.0/PKG-INFO → redis_dict-3.0.0/README.md +76 -59
- redis_dict-3.0.0/pyproject.toml +133 -0
- redis_dict-3.0.0/src/redis_dict/__init__.py +17 -0
- redis dict-2.6.0/redis_dict.py → redis_dict-3.0.0/src/redis_dict/core.py +237 -299
- redis_dict-3.0.0/src/redis_dict/py.typed +0 -0
- redis_dict-3.0.0/src/redis_dict/type_management.py +273 -0
- redis dict-2.6.0/README.md → redis_dict-3.0.0/src/redis_dict.egg-info/PKG-INFO +143 -25
- redis_dict-3.0.0/src/redis_dict.egg-info/SOURCES.txt +12 -0
- redis_dict-3.0.0/src/redis_dict.egg-info/requires.txt +35 -0
- redis dict-2.6.0/redis_dict.egg-info/SOURCES.txt +0 -9
- redis dict-2.6.0/redis_dict.egg-info/requires.txt +0 -1
- redis dict-2.6.0/setup.py +0 -56
- {redis dict-2.6.0 → redis_dict-3.0.0}/LICENSE +0 -0
- {redis dict-2.6.0 → redis_dict-3.0.0}/setup.cfg +0 -0
- {redis dict-2.6.0 → redis_dict-3.0.0/src}/redis_dict.egg-info/dependency_links.txt +0 -0
- {redis dict-2.6.0 → redis_dict-3.0.0/src}/redis_dict.egg-info/top_level.txt +0 -0
@@ -1,13 +1,14 @@
|
|
1
1
|
Metadata-Version: 2.1
|
2
2
|
Name: redis-dict
|
3
|
-
Version:
|
3
|
+
Version: 3.0.0
|
4
4
|
Summary: Dictionary with Redis as storage backend
|
5
|
-
|
6
|
-
Author: Melvin Bijman
|
7
|
-
Author-email: bijman.m.m@gmail.com
|
5
|
+
Author-email: Melvin Bijman <bijman.m.m@gmail.com>
|
8
6
|
License: MIT
|
9
|
-
|
10
|
-
|
7
|
+
Project-URL: Homepage, https://github.com/Attumm/redisdict
|
8
|
+
Project-URL: Documentation, https://github.com/Attumm/redisdict#readme
|
9
|
+
Project-URL: Repository, https://github.com/Attumm/redisdict.git
|
10
|
+
Project-URL: Changelog, https://github.com/Attumm/redisdict/releases
|
11
|
+
Keywords: redis,python,dictionary,dict,key-value,database,caching,distributed-computing,dictionary-interface,large-datasets,scientific-computing,data-persistence,high-performance,scalable,pipelining,batching,big-data,data-types,distributed-algorithms,encryption,data-management
|
11
12
|
Classifier: Development Status :: 5 - Production/Stable
|
12
13
|
Classifier: Intended Audience :: Developers
|
13
14
|
Classifier: Intended Audience :: Information Technology
|
@@ -21,18 +22,51 @@ Classifier: Topic :: Software Development :: Object Brokering
|
|
21
22
|
Classifier: Topic :: Database :: Database Engines/Servers
|
22
23
|
Classifier: License :: OSI Approved :: MIT License
|
23
24
|
Classifier: Programming Language :: Python :: 3
|
24
|
-
Classifier: Programming Language :: Python :: 3.6
|
25
|
-
Classifier: Programming Language :: Python :: 3.7
|
26
25
|
Classifier: Programming Language :: Python :: 3.8
|
27
26
|
Classifier: Programming Language :: Python :: 3.9
|
28
27
|
Classifier: Programming Language :: Python :: 3.10
|
29
28
|
Classifier: Programming Language :: Python :: 3.11
|
30
29
|
Classifier: Programming Language :: Python :: 3.12
|
30
|
+
Classifier: Typing :: Typed
|
31
|
+
Requires-Python: >=3.8
|
31
32
|
Description-Content-Type: text/markdown
|
32
33
|
License-File: LICENSE
|
33
|
-
Requires-Dist: redis
|
34
|
+
Requires-Dist: redis>=4.0.0
|
35
|
+
Provides-Extra: dev
|
36
|
+
Requires-Dist: coverage==5.5; extra == "dev"
|
37
|
+
Requires-Dist: hypothesis==6.70.1; extra == "dev"
|
38
|
+
Requires-Dist: mypy>=1.8.0; extra == "dev"
|
39
|
+
Requires-Dist: mypy-extensions>=1.0.0; extra == "dev"
|
40
|
+
Requires-Dist: types-pyOpenSSL>=24.0.0.0; extra == "dev"
|
41
|
+
Requires-Dist: types-redis>=4.6.0; extra == "dev"
|
42
|
+
Requires-Dist: typing_extensions>=4.5.0; extra == "dev"
|
43
|
+
Requires-Dist: pylama>=8.4.1; extra == "dev"
|
44
|
+
Requires-Dist: pycodestyle==2.10.0; extra == "dev"
|
45
|
+
Requires-Dist: pydocstyle==6.3.0; extra == "dev"
|
46
|
+
Requires-Dist: pyflakes==3.0.1; extra == "dev"
|
47
|
+
Requires-Dist: pylint==3.2.7; extra == "dev"
|
48
|
+
Requires-Dist: mccabe==0.7.0; extra == "dev"
|
49
|
+
Requires-Dist: attrs==22.2.0; extra == "dev"
|
50
|
+
Requires-Dist: cffi==1.15.1; extra == "dev"
|
51
|
+
Requires-Dist: cryptography==43.0.1; extra == "dev"
|
52
|
+
Requires-Dist: exceptiongroup==1.1.1; extra == "dev"
|
53
|
+
Requires-Dist: future==0.18.3; extra == "dev"
|
54
|
+
Requires-Dist: pycparser==2.21; extra == "dev"
|
55
|
+
Requires-Dist: snowballstemmer==2.2.0; extra == "dev"
|
56
|
+
Requires-Dist: sortedcontainers==2.4.0; extra == "dev"
|
57
|
+
Requires-Dist: tomli==2.0.1; extra == "dev"
|
58
|
+
Requires-Dist: setuptools>=68.0.0; extra == "dev"
|
59
|
+
Requires-Dist: darglint; extra == "dev"
|
60
|
+
Requires-Dist: pydocstyle; extra == "dev"
|
61
|
+
Provides-Extra: docs
|
62
|
+
Requires-Dist: sphinx; extra == "docs"
|
63
|
+
Requires-Dist: sphinx-rtd-theme; extra == "docs"
|
64
|
+
Requires-Dist: sphinx-autodoc-typehints; extra == "docs"
|
65
|
+
Requires-Dist: tomli; extra == "docs"
|
66
|
+
Requires-Dist: myst-parser; extra == "docs"
|
34
67
|
|
35
68
|
# Redis-dict
|
69
|
+
[](https://pypi.org/project/redis-dict/)
|
36
70
|
[](https://github.com/Attumm/redis-dict/actions/workflows/ci.yml)
|
37
71
|
[](https://codecov.io/gh/Attumm/redis-dict)
|
38
72
|
[](https://pepy.tech/project/redis-dict)
|
@@ -44,7 +78,7 @@ The library includes utility functions for more complex use cases such as cachin
|
|
44
78
|
## Features
|
45
79
|
|
46
80
|
* Dictionary-like interface: Use familiar Python dictionary syntax to interact with Redis.
|
47
|
-
* Data Type Support: Comprehensive support for various data types
|
81
|
+
* Data Type Support: Comprehensive support for various data types.
|
48
82
|
* Pipelining support: Use pipelines for batch operations to improve performance.
|
49
83
|
* Expiration Support: Enables the setting of expiration times either globally or individually per key, through the use of context managers.
|
50
84
|
* Efficiency and Scalability: RedisDict is designed for use with large datasets and is optimized for efficiency. It retrieves only the data needed for a particular operation, ensuring efficient memory usage and fast performance.
|
@@ -86,7 +120,6 @@ In Redis our example looks like this.
|
|
86
120
|
|
87
121
|
### Namespaces
|
88
122
|
Acting as an identifier for your dictionary across different systems, RedisDict employs namespaces for organized data management. When a namespace isn't specified, "main" becomes the default. Thus allowing for data organization across systems and projects with the same redis instance.
|
89
|
-
|
90
123
|
This approach also minimizes the risk of key collisions between different applications, preventing hard-to-debug issues. By leveraging namespaces, RedisDict ensures a cleaner and more maintainable data management experience for developers working on multiple projects.
|
91
124
|
|
92
125
|
## Advanced Features
|
@@ -135,7 +168,6 @@ dic['gone'] = 'gone in 5 seconds'
|
|
135
168
|
Efficiently batch your requests using the Pipeline feature, which can be easily utilized with a context manager.
|
136
169
|
|
137
170
|
```python
|
138
|
-
from redis_dict import RedisDict
|
139
171
|
dic = RedisDict(namespace="example")
|
140
172
|
|
141
173
|
# one round trip to redis
|
@@ -253,16 +285,82 @@ print(dic["d"]) # Output: 4
|
|
253
285
|
For more advanced examples of RedisDict, please refer to the unit-test files in the repository. All features and functionalities are thoroughly tested in [unit tests (here)](https://github.com/Attumm/redis-dict/blob/main/tests.py#L1) Or take a look at load test for batching [load test](https://github.com/Attumm/redis-dict/blob/main/load_test.py#L1).
|
254
286
|
The unit-tests can be as used as a starting point.
|
255
287
|
|
256
|
-
|
288
|
+
## Types
|
289
|
+
|
290
|
+
### standard types
|
291
|
+
RedisDict supports a range of Python data types, from basic types to nested structures.
|
292
|
+
Basic types are handled natively, while complex data types like lists and dictionaries, RedisDict uses JSON serialization, specifically avoiding `pickle` due to its [security vulnerabilities](https://docs.python.org/3/library/pickle.html) in distributed computing contexts.
|
293
|
+
Although the library supports nested structures, the recommended best practice is to use RedisDict as a shallow dictionary.
|
294
|
+
This approach optimizes Redis database performance and efficiency by ensuring that each set and get operation efficiently maps to Redis's key-value storage capabilities, while still preserving the library's Pythonic interface.
|
295
|
+
Following types are supported:
|
296
|
+
`str, int, float, bool, NoneType, list, dict, tuple, set, datetime, date, time, timedelta, Decimal, complex, bytes, UUID, OrderedDict, defaultdict, frozenset`
|
297
|
+
```python
|
298
|
+
from uuid import UUID
|
299
|
+
from decimal import Decimal
|
300
|
+
from collections import OrderedDict, defaultdict
|
301
|
+
from datetime import datetime, date, time, timedelta
|
302
|
+
|
303
|
+
dic = RedisDict()
|
304
|
+
|
305
|
+
dic["string"] = "Hello World"
|
306
|
+
dic["number"] = 42
|
307
|
+
dic["float"] = 3.14
|
308
|
+
dic["bool"] = True
|
309
|
+
dic["None"] = None
|
310
|
+
|
311
|
+
dic["list"] = [1, 2, 3]
|
312
|
+
dic["dict"] = {"a": 1, "b": 2}
|
313
|
+
dic["tuple"] = (1, 2, 3)
|
314
|
+
dic["set"] = {1, 2, 3}
|
315
|
+
|
316
|
+
dic["datetime"] = datetime.date(2024, 1, 1, 12, 30, 45)
|
317
|
+
dic["date"] = date(2024, 1, 1)
|
318
|
+
dic["time"] = time(12, 30, 45)
|
319
|
+
dic["delta"] = timedelta(days=1, hours=2)
|
320
|
+
|
321
|
+
dic["decimal"] = Decimal("3.14159")
|
322
|
+
dic["complex"] = complex(1, 2)
|
323
|
+
dic["bytes"] = bytes([72, 101, 108, 108, 111])
|
324
|
+
dic["uuid"] = UUID('12345678-1234-5678-1234-567812345678')
|
325
|
+
|
326
|
+
dic["ordered"] = OrderedDict([('a', 1), ('b', 2)])
|
327
|
+
dic["default"] = defaultdict(int, {'a': 1, 'b': 2})
|
328
|
+
dic["frozen"] = frozenset([1, 2, 3])
|
329
|
+
```
|
330
|
+
|
331
|
+
|
332
|
+
|
333
|
+
### Nested types
|
334
|
+
Nested Types
|
335
|
+
RedisDict supports nested structures with mixed types through JSON serialization. The feature works by utilizing JSON encoding and decoding under the hood. While this represents an upgrade in functionality, the feature is not fully implemented and should be used with caution. For optimal performance, using shallow dictionaries is recommended.
|
336
|
+
```python
|
337
|
+
from datetime import datetime, timedelta
|
338
|
+
|
339
|
+
dic["mixed"] = [1, "foobar", 3.14, [1, 2, 3], datetime.now()]
|
340
|
+
|
341
|
+
dic['dic'] = {"elapsed_time": timedelta(hours=60)}
|
342
|
+
```
|
343
|
+
|
344
|
+
### JSON Encoding - Decoding
|
345
|
+
The nested type support in RedisDict is implemented using custom JSON encoders and decoders. These JSON encoders and decoders are built on top of RedisDict's own encoding and decoding functionality, extending it for JSON compatibility. Since JSON serialization was a frequently requested feature, these enhanced encoders and decoders are available for use in other projects:
|
346
|
+
```python
|
347
|
+
import json
|
348
|
+
from datetime import datetime
|
349
|
+
from redis_dict import RedisDictJSONDecoder, RedisDictJSONEncoder
|
350
|
+
|
351
|
+
data = [1, "foobar", 3.14, [1, 2, 3], datetime.now()]
|
352
|
+
encoded = json.dumps(data, cls=RedisDictJSONEncoder)
|
353
|
+
result = json.loads(encoded, cls=RedisDictJSONDecoder)
|
354
|
+
```
|
355
|
+
|
257
356
|
|
258
|
-
|
357
|
+
### Extending RedisDict with Custom Types
|
259
358
|
|
260
359
|
RedisDict supports custom type serialization. Here's how to add a new type:
|
261
360
|
|
262
361
|
|
263
362
|
```python
|
264
363
|
import json
|
265
|
-
from redis_dict import RedisDict
|
266
364
|
|
267
365
|
class Person:
|
268
366
|
def __init__(self, name, age):
|
@@ -291,23 +389,13 @@ assert result.name == person.name
|
|
291
389
|
assert result.age == person.age
|
292
390
|
```
|
293
391
|
|
294
|
-
|
295
|
-
>>> from datetime import datetime
|
296
|
-
>>> redis_dict.extends_type(datetime, datetime.isoformat, datetime.fromisoformat)
|
297
|
-
>>> redis_dict["now"] = datetime.now()
|
298
|
-
>>> redis_dict
|
299
|
-
{'now': datetime.datetime(2024, 10, 14, 18, 41, 53, 493775)}
|
300
|
-
>>> redis_dict["now"]
|
301
|
-
datetime.datetime(2024, 10, 14, 18, 41, 53, 493775)
|
302
|
-
```
|
303
|
-
|
304
|
-
For more information on [extending types](https://github.com/Attumm/redis-dict/blob/main/extend_types_tests.py).
|
392
|
+
For more information on [extending types](https://github.com/Attumm/redis-dict/blob/main/tests/unit/extend_types_tests.py).
|
305
393
|
### Redis Encryption
|
306
394
|
Setup guide for configuring and utilizing encrypted Redis TLS for redis-dict.
|
307
|
-
[Setup guide](https://github.com/Attumm/redis-dict/blob/main/encrypted_redis.MD)
|
395
|
+
[Setup guide](https://github.com/Attumm/redis-dict/blob/main/docs/tutorials/encrypted_redis.MD)
|
308
396
|
|
309
397
|
### Redis Storage Encryption
|
310
|
-
For storing encrypted data values, it's possible to use extended types. Take a look at this [encrypted test](https://github.com/Attumm/redis-dict/blob/main/encrypt_tests.py).
|
398
|
+
For storing encrypted data values, it's possible to use extended types. Take a look at this [encrypted test](https://github.com/Attumm/redis-dict/blob/main/tests/unit/encrypt_tests.py).
|
311
399
|
|
312
400
|
### Tests
|
313
401
|
The RedisDict library includes a comprehensive suite of tests that ensure its correctness and resilience. The test suite covers various data types, edge cases, and error handling scenarios. It also employs the Hypothesis library for property-based testing, which provides fuzz testing to evaluate the implementation
|
@@ -315,19 +403,16 @@ The RedisDict library includes a comprehensive suite of tests that ensure its co
|
|
315
403
|
### Redis config
|
316
404
|
To configure RedisDict using your Redis config.
|
317
405
|
|
318
|
-
Configure both the host and port.
|
406
|
+
Configure both the host and port. Or configuration with a setting dictionary.
|
319
407
|
```python
|
320
408
|
dic = RedisDict(host='127.0.0.1', port=6380)
|
321
|
-
```
|
322
409
|
|
323
|
-
Configuration with a dictionary.
|
324
|
-
```python
|
325
410
|
redis_config = {
|
326
411
|
'host': '127.0.0.1',
|
327
412
|
'port': 6380,
|
328
413
|
}
|
329
414
|
|
330
|
-
|
415
|
+
confid_dic = RedisDict(**redis_config)
|
331
416
|
```
|
332
417
|
|
333
418
|
## Installation
|
@@ -338,4 +423,3 @@ pip install redis-dict
|
|
338
423
|
### Note
|
339
424
|
* Please be aware that this project is currently being utilized by various organizations in their production environments. If you have any questions or concerns, feel free to raise issues
|
340
425
|
* This project only uses redis as dependency
|
341
|
-
|
@@ -1,38 +1,5 @@
|
|
1
|
-
Metadata-Version: 2.1
|
2
|
-
Name: redis dict
|
3
|
-
Version: 2.6.0
|
4
|
-
Summary: Dictionary with Redis as storage backend
|
5
|
-
Home-page: https://github.com/Attumm/redisdict
|
6
|
-
Author: Melvin Bijman
|
7
|
-
Author-email: bijman.m.m@gmail.com
|
8
|
-
License: MIT
|
9
|
-
Keywords: redis python dictionary dict key-value key:value database caching distributed-computing dictionary-interface large-datasets scientific-computing data-persistence high-performance scalable pipelining batching big-data data-types distributed-algorithms encryption data-management
|
10
|
-
Platform: any
|
11
|
-
Classifier: Development Status :: 5 - Production/Stable
|
12
|
-
Classifier: Intended Audience :: Developers
|
13
|
-
Classifier: Intended Audience :: Information Technology
|
14
|
-
Classifier: Intended Audience :: Science/Research
|
15
|
-
Classifier: Topic :: Internet
|
16
|
-
Classifier: Topic :: Scientific/Engineering
|
17
|
-
Classifier: Topic :: Database
|
18
|
-
Classifier: Topic :: System :: Distributed Computing
|
19
|
-
Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
20
|
-
Classifier: Topic :: Software Development :: Object Brokering
|
21
|
-
Classifier: Topic :: Database :: Database Engines/Servers
|
22
|
-
Classifier: License :: OSI Approved :: MIT License
|
23
|
-
Classifier: Programming Language :: Python :: 3
|
24
|
-
Classifier: Programming Language :: Python :: 3.6
|
25
|
-
Classifier: Programming Language :: Python :: 3.7
|
26
|
-
Classifier: Programming Language :: Python :: 3.8
|
27
|
-
Classifier: Programming Language :: Python :: 3.9
|
28
|
-
Classifier: Programming Language :: Python :: 3.10
|
29
|
-
Classifier: Programming Language :: Python :: 3.11
|
30
|
-
Classifier: Programming Language :: Python :: 3.12
|
31
|
-
Description-Content-Type: text/markdown
|
32
|
-
License-File: LICENSE
|
33
|
-
Requires-Dist: redis
|
34
|
-
|
35
1
|
# Redis-dict
|
2
|
+
[](https://pypi.org/project/redis-dict/)
|
36
3
|
[](https://github.com/Attumm/redis-dict/actions/workflows/ci.yml)
|
37
4
|
[](https://codecov.io/gh/Attumm/redis-dict)
|
38
5
|
[](https://pepy.tech/project/redis-dict)
|
@@ -44,7 +11,7 @@ The library includes utility functions for more complex use cases such as cachin
|
|
44
11
|
## Features
|
45
12
|
|
46
13
|
* Dictionary-like interface: Use familiar Python dictionary syntax to interact with Redis.
|
47
|
-
* Data Type Support: Comprehensive support for various data types
|
14
|
+
* Data Type Support: Comprehensive support for various data types.
|
48
15
|
* Pipelining support: Use pipelines for batch operations to improve performance.
|
49
16
|
* Expiration Support: Enables the setting of expiration times either globally or individually per key, through the use of context managers.
|
50
17
|
* Efficiency and Scalability: RedisDict is designed for use with large datasets and is optimized for efficiency. It retrieves only the data needed for a particular operation, ensuring efficient memory usage and fast performance.
|
@@ -86,7 +53,6 @@ In Redis our example looks like this.
|
|
86
53
|
|
87
54
|
### Namespaces
|
88
55
|
Acting as an identifier for your dictionary across different systems, RedisDict employs namespaces for organized data management. When a namespace isn't specified, "main" becomes the default. Thus allowing for data organization across systems and projects with the same redis instance.
|
89
|
-
|
90
56
|
This approach also minimizes the risk of key collisions between different applications, preventing hard-to-debug issues. By leveraging namespaces, RedisDict ensures a cleaner and more maintainable data management experience for developers working on multiple projects.
|
91
57
|
|
92
58
|
## Advanced Features
|
@@ -135,7 +101,6 @@ dic['gone'] = 'gone in 5 seconds'
|
|
135
101
|
Efficiently batch your requests using the Pipeline feature, which can be easily utilized with a context manager.
|
136
102
|
|
137
103
|
```python
|
138
|
-
from redis_dict import RedisDict
|
139
104
|
dic = RedisDict(namespace="example")
|
140
105
|
|
141
106
|
# one round trip to redis
|
@@ -253,16 +218,82 @@ print(dic["d"]) # Output: 4
|
|
253
218
|
For more advanced examples of RedisDict, please refer to the unit-test files in the repository. All features and functionalities are thoroughly tested in [unit tests (here)](https://github.com/Attumm/redis-dict/blob/main/tests.py#L1) Or take a look at load test for batching [load test](https://github.com/Attumm/redis-dict/blob/main/load_test.py#L1).
|
254
219
|
The unit-tests can be as used as a starting point.
|
255
220
|
|
256
|
-
|
221
|
+
## Types
|
222
|
+
|
223
|
+
### standard types
|
224
|
+
RedisDict supports a range of Python data types, from basic types to nested structures.
|
225
|
+
Basic types are handled natively, while complex data types like lists and dictionaries, RedisDict uses JSON serialization, specifically avoiding `pickle` due to its [security vulnerabilities](https://docs.python.org/3/library/pickle.html) in distributed computing contexts.
|
226
|
+
Although the library supports nested structures, the recommended best practice is to use RedisDict as a shallow dictionary.
|
227
|
+
This approach optimizes Redis database performance and efficiency by ensuring that each set and get operation efficiently maps to Redis's key-value storage capabilities, while still preserving the library's Pythonic interface.
|
228
|
+
Following types are supported:
|
229
|
+
`str, int, float, bool, NoneType, list, dict, tuple, set, datetime, date, time, timedelta, Decimal, complex, bytes, UUID, OrderedDict, defaultdict, frozenset`
|
230
|
+
```python
|
231
|
+
from uuid import UUID
|
232
|
+
from decimal import Decimal
|
233
|
+
from collections import OrderedDict, defaultdict
|
234
|
+
from datetime import datetime, date, time, timedelta
|
235
|
+
|
236
|
+
dic = RedisDict()
|
257
237
|
|
258
|
-
|
238
|
+
dic["string"] = "Hello World"
|
239
|
+
dic["number"] = 42
|
240
|
+
dic["float"] = 3.14
|
241
|
+
dic["bool"] = True
|
242
|
+
dic["None"] = None
|
243
|
+
|
244
|
+
dic["list"] = [1, 2, 3]
|
245
|
+
dic["dict"] = {"a": 1, "b": 2}
|
246
|
+
dic["tuple"] = (1, 2, 3)
|
247
|
+
dic["set"] = {1, 2, 3}
|
248
|
+
|
249
|
+
dic["datetime"] = datetime.date(2024, 1, 1, 12, 30, 45)
|
250
|
+
dic["date"] = date(2024, 1, 1)
|
251
|
+
dic["time"] = time(12, 30, 45)
|
252
|
+
dic["delta"] = timedelta(days=1, hours=2)
|
253
|
+
|
254
|
+
dic["decimal"] = Decimal("3.14159")
|
255
|
+
dic["complex"] = complex(1, 2)
|
256
|
+
dic["bytes"] = bytes([72, 101, 108, 108, 111])
|
257
|
+
dic["uuid"] = UUID('12345678-1234-5678-1234-567812345678')
|
258
|
+
|
259
|
+
dic["ordered"] = OrderedDict([('a', 1), ('b', 2)])
|
260
|
+
dic["default"] = defaultdict(int, {'a': 1, 'b': 2})
|
261
|
+
dic["frozen"] = frozenset([1, 2, 3])
|
262
|
+
```
|
263
|
+
|
264
|
+
|
265
|
+
|
266
|
+
### Nested types
|
267
|
+
Nested Types
|
268
|
+
RedisDict supports nested structures with mixed types through JSON serialization. The feature works by utilizing JSON encoding and decoding under the hood. While this represents an upgrade in functionality, the feature is not fully implemented and should be used with caution. For optimal performance, using shallow dictionaries is recommended.
|
269
|
+
```python
|
270
|
+
from datetime import datetime, timedelta
|
271
|
+
|
272
|
+
dic["mixed"] = [1, "foobar", 3.14, [1, 2, 3], datetime.now()]
|
273
|
+
|
274
|
+
dic['dic'] = {"elapsed_time": timedelta(hours=60)}
|
275
|
+
```
|
276
|
+
|
277
|
+
### JSON Encoding - Decoding
|
278
|
+
The nested type support in RedisDict is implemented using custom JSON encoders and decoders. These JSON encoders and decoders are built on top of RedisDict's own encoding and decoding functionality, extending it for JSON compatibility. Since JSON serialization was a frequently requested feature, these enhanced encoders and decoders are available for use in other projects:
|
279
|
+
```python
|
280
|
+
import json
|
281
|
+
from datetime import datetime
|
282
|
+
from redis_dict import RedisDictJSONDecoder, RedisDictJSONEncoder
|
283
|
+
|
284
|
+
data = [1, "foobar", 3.14, [1, 2, 3], datetime.now()]
|
285
|
+
encoded = json.dumps(data, cls=RedisDictJSONEncoder)
|
286
|
+
result = json.loads(encoded, cls=RedisDictJSONDecoder)
|
287
|
+
```
|
288
|
+
|
289
|
+
|
290
|
+
### Extending RedisDict with Custom Types
|
259
291
|
|
260
292
|
RedisDict supports custom type serialization. Here's how to add a new type:
|
261
293
|
|
262
294
|
|
263
295
|
```python
|
264
296
|
import json
|
265
|
-
from redis_dict import RedisDict
|
266
297
|
|
267
298
|
class Person:
|
268
299
|
def __init__(self, name, age):
|
@@ -291,23 +322,13 @@ assert result.name == person.name
|
|
291
322
|
assert result.age == person.age
|
292
323
|
```
|
293
324
|
|
294
|
-
|
295
|
-
>>> from datetime import datetime
|
296
|
-
>>> redis_dict.extends_type(datetime, datetime.isoformat, datetime.fromisoformat)
|
297
|
-
>>> redis_dict["now"] = datetime.now()
|
298
|
-
>>> redis_dict
|
299
|
-
{'now': datetime.datetime(2024, 10, 14, 18, 41, 53, 493775)}
|
300
|
-
>>> redis_dict["now"]
|
301
|
-
datetime.datetime(2024, 10, 14, 18, 41, 53, 493775)
|
302
|
-
```
|
303
|
-
|
304
|
-
For more information on [extending types](https://github.com/Attumm/redis-dict/blob/main/extend_types_tests.py).
|
325
|
+
For more information on [extending types](https://github.com/Attumm/redis-dict/blob/main/tests/unit/extend_types_tests.py).
|
305
326
|
### Redis Encryption
|
306
327
|
Setup guide for configuring and utilizing encrypted Redis TLS for redis-dict.
|
307
|
-
[Setup guide](https://github.com/Attumm/redis-dict/blob/main/encrypted_redis.MD)
|
328
|
+
[Setup guide](https://github.com/Attumm/redis-dict/blob/main/docs/tutorials/encrypted_redis.MD)
|
308
329
|
|
309
330
|
### Redis Storage Encryption
|
310
|
-
For storing encrypted data values, it's possible to use extended types. Take a look at this [encrypted test](https://github.com/Attumm/redis-dict/blob/main/encrypt_tests.py).
|
331
|
+
For storing encrypted data values, it's possible to use extended types. Take a look at this [encrypted test](https://github.com/Attumm/redis-dict/blob/main/tests/unit/encrypt_tests.py).
|
311
332
|
|
312
333
|
### Tests
|
313
334
|
The RedisDict library includes a comprehensive suite of tests that ensure its correctness and resilience. The test suite covers various data types, edge cases, and error handling scenarios. It also employs the Hypothesis library for property-based testing, which provides fuzz testing to evaluate the implementation
|
@@ -315,19 +336,16 @@ The RedisDict library includes a comprehensive suite of tests that ensure its co
|
|
315
336
|
### Redis config
|
316
337
|
To configure RedisDict using your Redis config.
|
317
338
|
|
318
|
-
Configure both the host and port.
|
339
|
+
Configure both the host and port. Or configuration with a setting dictionary.
|
319
340
|
```python
|
320
341
|
dic = RedisDict(host='127.0.0.1', port=6380)
|
321
|
-
```
|
322
342
|
|
323
|
-
Configuration with a dictionary.
|
324
|
-
```python
|
325
343
|
redis_config = {
|
326
344
|
'host': '127.0.0.1',
|
327
345
|
'port': 6380,
|
328
346
|
}
|
329
347
|
|
330
|
-
|
348
|
+
confid_dic = RedisDict(**redis_config)
|
331
349
|
```
|
332
350
|
|
333
351
|
## Installation
|
@@ -338,4 +356,3 @@ pip install redis-dict
|
|
338
356
|
### Note
|
339
357
|
* Please be aware that this project is currently being utilized by various organizations in their production environments. If you have any questions or concerns, feel free to raise issues
|
340
358
|
* This project only uses redis as dependency
|
341
|
-
|
@@ -0,0 +1,133 @@
|
|
1
|
+
[build-system]
|
2
|
+
requires = ["setuptools>=68.0", "wheel"]
|
3
|
+
build-backend = "setuptools.build_meta"
|
4
|
+
|
5
|
+
[project]
|
6
|
+
name = "redis-dict"
|
7
|
+
version = "3.0.0"
|
8
|
+
description = "Dictionary with Redis as storage backend"
|
9
|
+
authors = [
|
10
|
+
{name = "Melvin Bijman", email = "bijman.m.m@gmail.com"},
|
11
|
+
]
|
12
|
+
readme = "README.md"
|
13
|
+
|
14
|
+
requires-python = ">=3.8"
|
15
|
+
license = {text = "MIT"}
|
16
|
+
dependencies = [
|
17
|
+
"redis>=4.0.0",
|
18
|
+
]
|
19
|
+
classifiers = [
|
20
|
+
"Development Status :: 5 - Production/Stable",
|
21
|
+
"Intended Audience :: Developers",
|
22
|
+
"Intended Audience :: Information Technology",
|
23
|
+
"Intended Audience :: Science/Research",
|
24
|
+
"Topic :: Internet",
|
25
|
+
"Topic :: Scientific/Engineering",
|
26
|
+
"Topic :: Database",
|
27
|
+
"Topic :: System :: Distributed Computing",
|
28
|
+
"Topic :: Software Development :: Libraries :: Python Modules",
|
29
|
+
"Topic :: Software Development :: Object Brokering",
|
30
|
+
"Topic :: Database :: Database Engines/Servers",
|
31
|
+
"License :: OSI Approved :: MIT License",
|
32
|
+
"Programming Language :: Python :: 3",
|
33
|
+
"Programming Language :: Python :: 3.8",
|
34
|
+
"Programming Language :: Python :: 3.9",
|
35
|
+
"Programming Language :: Python :: 3.10",
|
36
|
+
"Programming Language :: Python :: 3.11",
|
37
|
+
"Programming Language :: Python :: 3.12",
|
38
|
+
"Typing :: Typed",
|
39
|
+
]
|
40
|
+
|
41
|
+
keywords = [
|
42
|
+
"redis", "python", "dictionary", "dict", "key-value",
|
43
|
+
"database", "caching", "distributed-computing",
|
44
|
+
"dictionary-interface", "large-datasets",
|
45
|
+
"scientific-computing", "data-persistence",
|
46
|
+
"high-performance", "scalable", "pipelining",
|
47
|
+
"batching", "big-data", "data-types",
|
48
|
+
"distributed-algorithms", "encryption",
|
49
|
+
"data-management",
|
50
|
+
]
|
51
|
+
|
52
|
+
[project.optional-dependencies]
|
53
|
+
dev = [
|
54
|
+
"coverage==5.5",
|
55
|
+
"hypothesis==6.70.1",
|
56
|
+
|
57
|
+
"mypy>=1.8.0",
|
58
|
+
"mypy-extensions>=1.0.0",
|
59
|
+
"types-pyOpenSSL>=24.0.0.0",
|
60
|
+
"types-redis>=4.6.0",
|
61
|
+
"typing_extensions>=4.5.0",
|
62
|
+
|
63
|
+
"pylama>=8.4.1",
|
64
|
+
"pycodestyle==2.10.0",
|
65
|
+
"pydocstyle==6.3.0",
|
66
|
+
"pyflakes==3.0.1",
|
67
|
+
"pylint==3.2.7",
|
68
|
+
"mccabe==0.7.0",
|
69
|
+
|
70
|
+
"attrs==22.2.0",
|
71
|
+
"cffi==1.15.1",
|
72
|
+
"cryptography==43.0.1",
|
73
|
+
"exceptiongroup==1.1.1",
|
74
|
+
"future==0.18.3",
|
75
|
+
"pycparser==2.21",
|
76
|
+
"snowballstemmer==2.2.0",
|
77
|
+
"sortedcontainers==2.4.0",
|
78
|
+
"tomli==2.0.1",
|
79
|
+
"setuptools>=68.0.0",
|
80
|
+
"darglint",
|
81
|
+
"pydocstyle",
|
82
|
+
]
|
83
|
+
|
84
|
+
docs = [
|
85
|
+
"sphinx",
|
86
|
+
"sphinx-rtd-theme",
|
87
|
+
"sphinx-autodoc-typehints",
|
88
|
+
"tomli",
|
89
|
+
"myst-parser",
|
90
|
+
]
|
91
|
+
|
92
|
+
|
93
|
+
[tool.setuptools]
|
94
|
+
package-dir = {"" = "src"}
|
95
|
+
packages = ["redis_dict"]
|
96
|
+
|
97
|
+
[tool.setuptools.package-data]
|
98
|
+
redis_dict = ["py.typed"]
|
99
|
+
|
100
|
+
[tool.coverage.run]
|
101
|
+
source = ["redis_dict"]
|
102
|
+
branch = true
|
103
|
+
|
104
|
+
[tool.coverage.report]
|
105
|
+
exclude_lines = [
|
106
|
+
"pragma: no cover",
|
107
|
+
"def __repr__",
|
108
|
+
"if __name__ == .__main__.:",
|
109
|
+
"raise NotImplementedError",
|
110
|
+
"if TYPE_CHECKING:",
|
111
|
+
]
|
112
|
+
show_missing = true
|
113
|
+
|
114
|
+
[tool.mypy]
|
115
|
+
python_version = "3.8"
|
116
|
+
strict = true
|
117
|
+
mypy_path = "src"
|
118
|
+
files = ["src"]
|
119
|
+
namespace_packages = true
|
120
|
+
explicit_package_bases = true
|
121
|
+
|
122
|
+
[tool.pylama]
|
123
|
+
ignore = "E501,E231"
|
124
|
+
skip = "*/.tox/*,*/.env/*,build/*"
|
125
|
+
linters = "pycodestyle,pyflakes,mccabe"
|
126
|
+
max_line_length = 120
|
127
|
+
paths = ["src/redis_dict"]
|
128
|
+
|
129
|
+
[project.urls]
|
130
|
+
Homepage = "https://github.com/Attumm/redisdict"
|
131
|
+
Documentation = "https://github.com/Attumm/redisdict#readme"
|
132
|
+
Repository = "https://github.com/Attumm/redisdict.git"
|
133
|
+
Changelog = "https://github.com/Attumm/redisdict/releases"
|
@@ -0,0 +1,17 @@
|
|
1
|
+
"""__init__ module for redis dict."""
|
2
|
+
from importlib.metadata import version, PackageNotFoundError
|
3
|
+
|
4
|
+
from .core import RedisDict
|
5
|
+
from .type_management import decoding_registry, encoding_registry, RedisDictJSONEncoder, RedisDictJSONDecoder
|
6
|
+
|
7
|
+
__all__ = [
|
8
|
+
'RedisDict',
|
9
|
+
'decoding_registry',
|
10
|
+
'encoding_registry',
|
11
|
+
'RedisDictJSONEncoder',
|
12
|
+
'RedisDictJSONDecoder',
|
13
|
+
]
|
14
|
+
try:
|
15
|
+
__version__ = version("redis-dict")
|
16
|
+
except PackageNotFoundError:
|
17
|
+
__version__ = "0.0.0"
|