redis-dict 2.5.1__tar.gz → 2.7.0__tar.gz
Sign up to get free protection for your applications and to get access to all the features.
- redis dict-2.5.1/README.md → redis dict-2.7.0/PKG-INFO +159 -20
- redis dict-2.5.1/PKG-INFO → redis dict-2.7.0/README.md +125 -45
- {redis dict-2.5.1 → redis dict-2.7.0}/redis_dict.egg-info/PKG-INFO +135 -21
- {redis dict-2.5.1 → redis dict-2.7.0}/redis_dict.py +317 -55
- {redis dict-2.5.1 → redis dict-2.7.0}/setup.py +11 -1
- {redis dict-2.5.1 → redis dict-2.7.0}/LICENSE +0 -0
- {redis dict-2.5.1 → redis dict-2.7.0}/redis_dict.egg-info/SOURCES.txt +0 -0
- {redis dict-2.5.1 → redis dict-2.7.0}/redis_dict.egg-info/dependency_links.txt +0 -0
- {redis dict-2.5.1 → redis dict-2.7.0}/redis_dict.egg-info/requires.txt +0 -0
- {redis dict-2.5.1 → redis dict-2.7.0}/redis_dict.egg-info/top_level.txt +0 -0
- {redis dict-2.5.1 → redis dict-2.7.0}/setup.cfg +0 -0
@@ -1,36 +1,76 @@
|
|
1
|
+
Metadata-Version: 2.1
|
2
|
+
Name: redis dict
|
3
|
+
Version: 2.7.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
|
+
|
1
35
|
# Redis-dict
|
2
36
|
[](https://github.com/Attumm/redis-dict/actions/workflows/ci.yml)
|
3
37
|
[](https://codecov.io/gh/Attumm/redis-dict)
|
4
38
|
[](https://pepy.tech/project/redis-dict)
|
5
39
|
|
6
|
-
RedisDict is a Python library that
|
7
|
-
|
8
|
-
By leveraging Redis for efficient key-value storage, RedisDict allows for high-performance data management and is particularly useful for handling large datasets that may exceed local memory capacity.
|
40
|
+
RedisDict is a Python library that offers a convenient and familiar interface for interacting with Redis, treating it as if it were a Python dictionary. Its goal is to help developers write clean, Pythonic code while using Redis as a storage solution for seamless distributed computing. This simple yet powerful library utilizes Redis as a key-value store and supports various data types, including strings, integers, floats, booleans, lists, and dictionaries. Additionally, developers can extend RedisDict to work with custom objects.
|
9
41
|
|
42
|
+
The library includes utility functions for more complex use cases such as caching, batching, and more. By leveraging Redis for efficient key-value storage, RedisDict enables high-performance data management, maintaining efficiency even with large datasets and Redis instances.
|
10
43
|
|
11
44
|
## Features
|
12
45
|
|
13
46
|
* Dictionary-like interface: Use familiar Python dictionary syntax to interact with Redis.
|
14
|
-
* Data Type Support: Comprehensive support for various data types
|
47
|
+
* Data Type Support: Comprehensive support for various data types.
|
15
48
|
* Pipelining support: Use pipelines for batch operations to improve performance.
|
16
49
|
* Expiration Support: Enables the setting of expiration times either globally or individually per key, through the use of context managers.
|
17
50
|
* 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.
|
18
51
|
* Namespace Management: Provides simple and efficient namespace handling to help organize and manage data in Redis, streamlining data access and manipulation.
|
19
52
|
* Distributed Computing: With its ability to seamlessly connect to other instances or servers with access to the same Redis instance, RedisDict enables easy distributed computing.
|
20
|
-
* Custom data types: Add custom types
|
53
|
+
* Custom data: types: Add custom types encoding/decoding to store your data types.
|
54
|
+
* Encryption: allows for storing data encrypted, while retaining the simple dictionary interface.
|
21
55
|
|
22
56
|
## Example
|
23
57
|
Redis is an exceptionally fast database when used appropriately. RedisDict leverages Redis for efficient key-value storage, enabling high-performance data management.
|
24
58
|
|
25
|
-
```
|
26
|
-
|
59
|
+
```bash
|
60
|
+
pip install redis-dict
|
61
|
+
```
|
27
62
|
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
dic[
|
33
|
-
|
63
|
+
```python
|
64
|
+
>>> from redis_dict import RedisDict
|
65
|
+
>>> dic = RedisDict()
|
66
|
+
>>> dic['foo'] = 42
|
67
|
+
>>> dic['foo']
|
68
|
+
42
|
69
|
+
>>> 'foo' in dic
|
70
|
+
True
|
71
|
+
>>> dic["baz"] = "hello world"
|
72
|
+
>>> dic
|
73
|
+
{'foo': 42, 'baz': 'hello world'}
|
34
74
|
```
|
35
75
|
In Redis our example looks like this.
|
36
76
|
```
|
@@ -43,12 +83,12 @@ In Redis our example looks like this.
|
|
43
83
|
"str:hello world"
|
44
84
|
```
|
45
85
|
|
86
|
+
|
46
87
|
### Namespaces
|
47
|
-
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
|
88
|
+
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.
|
48
89
|
|
49
90
|
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.
|
50
91
|
|
51
|
-
|
52
92
|
## Advanced Features
|
53
93
|
|
54
94
|
### Expiration
|
@@ -81,6 +121,8 @@ with dic.expire_at(seconds):
|
|
81
121
|
3. Updating keys while preserving the initial timeout In certain situations, there is a need to update the value while keeping the expiration intact. This is achievable by setting the 'preserve_expiration' to true.
|
82
122
|
|
83
123
|
```python
|
124
|
+
import time
|
125
|
+
|
84
126
|
dic = RedisDict(expire=10, preserve_expiration=True)
|
85
127
|
dic['gone'] = 'in ten seconds'
|
86
128
|
|
@@ -93,6 +135,7 @@ dic['gone'] = 'gone in 5 seconds'
|
|
93
135
|
Efficiently batch your requests using the Pipeline feature, which can be easily utilized with a context manager.
|
94
136
|
|
95
137
|
```python
|
138
|
+
from redis_dict import RedisDict
|
96
139
|
dic = RedisDict(namespace="example")
|
97
140
|
|
98
141
|
# one round trip to redis
|
@@ -122,13 +165,14 @@ print(dic["foo"]) # outputs "bar"
|
|
122
165
|
### Caching made simple
|
123
166
|
```python
|
124
167
|
import time
|
168
|
+
from datetime import timedelta
|
125
169
|
from redis_dict import RedisDict
|
126
170
|
|
127
171
|
def expensive_function(x):
|
128
|
-
time.sleep(
|
172
|
+
time.sleep(x)
|
129
173
|
return x * 2
|
130
174
|
|
131
|
-
cache = RedisDict(namespace="cache", expire=
|
175
|
+
cache = RedisDict(namespace="cache", expire=timedelta(minutes=60))
|
132
176
|
|
133
177
|
def cached_expensive_function(x):
|
134
178
|
if x not in cache:
|
@@ -136,7 +180,7 @@ def cached_expensive_function(x):
|
|
136
180
|
return cache[x]
|
137
181
|
|
138
182
|
start_time = time.time()
|
139
|
-
print(cached_expensive_function(5)) # Takes around
|
183
|
+
print(cached_expensive_function(5)) # Takes around 5 seconds to compute and caches the result.
|
140
184
|
print(f"Time taken: {time.time() - start_time:.2f} seconds")
|
141
185
|
|
142
186
|
start_time = time.time()
|
@@ -156,7 +200,7 @@ dic["name"] = "John Doe"
|
|
156
200
|
dic["age"] = 32
|
157
201
|
dic["city"] = "Amsterdam"
|
158
202
|
|
159
|
-
# Get value by key
|
203
|
+
# Get value by key, from any instance connected to the same redis/namespace
|
160
204
|
print(dic["name"]) # Output: John Doe
|
161
205
|
|
162
206
|
# Update value by key, got a year older
|
@@ -209,10 +253,105 @@ print(dic["d"]) # Output: 4
|
|
209
253
|
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).
|
210
254
|
The unit-tests can be as used as a starting point.
|
211
255
|
|
256
|
+
## Types
|
257
|
+
|
258
|
+
### standard types
|
259
|
+
RedisDict supports a range of Python data types, from basic types to nested structures.
|
260
|
+
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.
|
261
|
+
Although the library supports nested structures, the recommended best practice is to use RedisDict as a shallow dictionary.
|
262
|
+
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.
|
263
|
+
Following types are supported:
|
264
|
+
`str, int, float, bool, NoneType, list, dict, tuple, set, datetime, date, time, timedelta, Decimal, complex, bytes, UUID, OrderedDict, defaultdict, frozenset`
|
265
|
+
```python
|
266
|
+
from redis_dict import RedisDict
|
267
|
+
|
268
|
+
from uuid import UUID
|
269
|
+
from decimal import Decimal
|
270
|
+
from collections import OrderedDict, defaultdict
|
271
|
+
from datetime import datetime, date, time, timedelta
|
272
|
+
|
273
|
+
|
274
|
+
dic = RedisDict()
|
275
|
+
|
276
|
+
dic["string"] = "Hello World"
|
277
|
+
dic["number"] = 42
|
278
|
+
dic["float"] = 3.14
|
279
|
+
dic["bool"] = True
|
280
|
+
dic["None"] = None
|
281
|
+
|
282
|
+
dic["list"] = [1, 2, 3]
|
283
|
+
dic["dict"] = {"a": 1, "b": 2}
|
284
|
+
dic["tuple"] = (1, 2, 3)
|
285
|
+
dic["set"] = {1, 2, 3}
|
286
|
+
|
287
|
+
dic["datetime"] = datetime.date(2024, 1, 1, 12, 30, 45)
|
288
|
+
dic["date"] = date(2024, 1, 1)
|
289
|
+
dic["time"] = time(12, 30, 45)
|
290
|
+
dic["delta"] = timedelta(days=1, hours=2)
|
291
|
+
|
292
|
+
dic["decimal"] = Decimal("3.14159")
|
293
|
+
dic["complex"] = complex(1, 2)
|
294
|
+
dic["bytes"] = bytes([72, 101, 108, 108, 111])
|
295
|
+
dic["uuid"] = UUID('12345678-1234-5678-1234-567812345678')
|
296
|
+
|
297
|
+
dic["ordered"] = OrderedDict([('a', 1), ('b', 2)])
|
298
|
+
dic["default"] = defaultdict(int, {'a': 1, 'b': 2})
|
299
|
+
dic["frozen"] = frozenset([1, 2, 3])
|
300
|
+
```
|
301
|
+
|
302
|
+
### Extending RedisDict with Custom Types
|
303
|
+
|
304
|
+
RedisDict supports custom type serialization. Here's how to add a new type:
|
305
|
+
|
306
|
+
|
307
|
+
```python
|
308
|
+
import json
|
309
|
+
from redis_dict import RedisDict
|
310
|
+
|
311
|
+
class Person:
|
312
|
+
def __init__(self, name, age):
|
313
|
+
self.name = name
|
314
|
+
self.age = age
|
315
|
+
|
316
|
+
def encode(self) -> str:
|
317
|
+
return json.dumps(self.__dict__)
|
318
|
+
|
319
|
+
@classmethod
|
320
|
+
def decode(cls, encoded_str: str) -> 'Person':
|
321
|
+
return cls(**json.loads(encoded_str))
|
322
|
+
|
323
|
+
redis_dict = RedisDict()
|
324
|
+
|
325
|
+
# Extend redis dict with the new type
|
326
|
+
redis_dict.extends_type(Person)
|
327
|
+
|
328
|
+
# RedisDict can now seamlessly handle Person instances.
|
329
|
+
person = Person(name="John", age=32)
|
330
|
+
redis_dict["person1"] = person
|
331
|
+
|
332
|
+
result = redis_dict["person1"]
|
333
|
+
|
334
|
+
assert result.name == person.name
|
335
|
+
assert result.age == person.age
|
336
|
+
```
|
337
|
+
|
338
|
+
```python
|
339
|
+
>>> from datetime import datetime
|
340
|
+
>>> redis_dict.extends_type(datetime, datetime.isoformat, datetime.fromisoformat)
|
341
|
+
>>> redis_dict["now"] = datetime.now()
|
342
|
+
>>> redis_dict
|
343
|
+
{'now': datetime.datetime(2024, 10, 14, 18, 41, 53, 493775)}
|
344
|
+
>>> redis_dict["now"]
|
345
|
+
datetime.datetime(2024, 10, 14, 18, 41, 53, 493775)
|
346
|
+
```
|
347
|
+
|
348
|
+
For more information on [extending types](https://github.com/Attumm/redis-dict/blob/main/extend_types_tests.py).
|
212
349
|
### Redis Encryption
|
213
|
-
Setup guide for configuring and utilizing encrypted Redis for redis-dict.
|
350
|
+
Setup guide for configuring and utilizing encrypted Redis TLS for redis-dict.
|
214
351
|
[Setup guide](https://github.com/Attumm/redis-dict/blob/main/encrypted_redis.MD)
|
215
352
|
|
353
|
+
### Redis Storage Encryption
|
354
|
+
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).
|
216
355
|
|
217
356
|
### Tests
|
218
357
|
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
|
@@ -1,61 +1,42 @@
|
|
1
|
-
Metadata-Version: 2.1
|
2
|
-
Name: redis dict
|
3
|
-
Version: 2.5.1
|
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
|
-
Classifier: Development Status :: 5 - Production/Stable
|
10
|
-
Classifier: Intended Audience :: Developers
|
11
|
-
Classifier: Topic :: Database
|
12
|
-
Classifier: Topic :: System :: Distributed Computing
|
13
|
-
Classifier: License :: OSI Approved :: MIT License
|
14
|
-
Classifier: Programming Language :: Python :: 3
|
15
|
-
Classifier: Programming Language :: Python :: 3.6
|
16
|
-
Classifier: Programming Language :: Python :: 3.7
|
17
|
-
Classifier: Programming Language :: Python :: 3.8
|
18
|
-
Classifier: Programming Language :: Python :: 3.9
|
19
|
-
Classifier: Programming Language :: Python :: 3.10
|
20
|
-
Classifier: Programming Language :: Python :: 3.11
|
21
|
-
Classifier: Programming Language :: Python :: 3.12
|
22
|
-
Description-Content-Type: text/markdown
|
23
|
-
License-File: LICENSE
|
24
|
-
Requires-Dist: redis
|
25
|
-
|
26
1
|
# Redis-dict
|
27
2
|
[](https://github.com/Attumm/redis-dict/actions/workflows/ci.yml)
|
28
3
|
[](https://codecov.io/gh/Attumm/redis-dict)
|
29
4
|
[](https://pepy.tech/project/redis-dict)
|
30
5
|
|
31
|
-
RedisDict is a Python library that
|
32
|
-
|
33
|
-
By leveraging Redis for efficient key-value storage, RedisDict allows for high-performance data management and is particularly useful for handling large datasets that may exceed local memory capacity.
|
6
|
+
RedisDict is a Python library that offers a convenient and familiar interface for interacting with Redis, treating it as if it were a Python dictionary. Its goal is to help developers write clean, Pythonic code while using Redis as a storage solution for seamless distributed computing. This simple yet powerful library utilizes Redis as a key-value store and supports various data types, including strings, integers, floats, booleans, lists, and dictionaries. Additionally, developers can extend RedisDict to work with custom objects.
|
34
7
|
|
8
|
+
The library includes utility functions for more complex use cases such as caching, batching, and more. By leveraging Redis for efficient key-value storage, RedisDict enables high-performance data management, maintaining efficiency even with large datasets and Redis instances.
|
35
9
|
|
36
10
|
## Features
|
37
11
|
|
38
12
|
* Dictionary-like interface: Use familiar Python dictionary syntax to interact with Redis.
|
39
|
-
* Data Type Support: Comprehensive support for various data types
|
13
|
+
* Data Type Support: Comprehensive support for various data types.
|
40
14
|
* Pipelining support: Use pipelines for batch operations to improve performance.
|
41
15
|
* Expiration Support: Enables the setting of expiration times either globally or individually per key, through the use of context managers.
|
42
16
|
* 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.
|
43
17
|
* Namespace Management: Provides simple and efficient namespace handling to help organize and manage data in Redis, streamlining data access and manipulation.
|
44
18
|
* Distributed Computing: With its ability to seamlessly connect to other instances or servers with access to the same Redis instance, RedisDict enables easy distributed computing.
|
45
|
-
* Custom data types: Add custom types
|
19
|
+
* Custom data: types: Add custom types encoding/decoding to store your data types.
|
20
|
+
* Encryption: allows for storing data encrypted, while retaining the simple dictionary interface.
|
46
21
|
|
47
22
|
## Example
|
48
23
|
Redis is an exceptionally fast database when used appropriately. RedisDict leverages Redis for efficient key-value storage, enabling high-performance data management.
|
49
24
|
|
50
|
-
```
|
51
|
-
|
25
|
+
```bash
|
26
|
+
pip install redis-dict
|
27
|
+
```
|
52
28
|
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
dic[
|
58
|
-
|
29
|
+
```python
|
30
|
+
>>> from redis_dict import RedisDict
|
31
|
+
>>> dic = RedisDict()
|
32
|
+
>>> dic['foo'] = 42
|
33
|
+
>>> dic['foo']
|
34
|
+
42
|
35
|
+
>>> 'foo' in dic
|
36
|
+
True
|
37
|
+
>>> dic["baz"] = "hello world"
|
38
|
+
>>> dic
|
39
|
+
{'foo': 42, 'baz': 'hello world'}
|
59
40
|
```
|
60
41
|
In Redis our example looks like this.
|
61
42
|
```
|
@@ -68,12 +49,12 @@ In Redis our example looks like this.
|
|
68
49
|
"str:hello world"
|
69
50
|
```
|
70
51
|
|
52
|
+
|
71
53
|
### Namespaces
|
72
|
-
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
|
54
|
+
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.
|
73
55
|
|
74
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.
|
75
57
|
|
76
|
-
|
77
58
|
## Advanced Features
|
78
59
|
|
79
60
|
### Expiration
|
@@ -106,6 +87,8 @@ with dic.expire_at(seconds):
|
|
106
87
|
3. Updating keys while preserving the initial timeout In certain situations, there is a need to update the value while keeping the expiration intact. This is achievable by setting the 'preserve_expiration' to true.
|
107
88
|
|
108
89
|
```python
|
90
|
+
import time
|
91
|
+
|
109
92
|
dic = RedisDict(expire=10, preserve_expiration=True)
|
110
93
|
dic['gone'] = 'in ten seconds'
|
111
94
|
|
@@ -118,6 +101,7 @@ dic['gone'] = 'gone in 5 seconds'
|
|
118
101
|
Efficiently batch your requests using the Pipeline feature, which can be easily utilized with a context manager.
|
119
102
|
|
120
103
|
```python
|
104
|
+
from redis_dict import RedisDict
|
121
105
|
dic = RedisDict(namespace="example")
|
122
106
|
|
123
107
|
# one round trip to redis
|
@@ -147,13 +131,14 @@ print(dic["foo"]) # outputs "bar"
|
|
147
131
|
### Caching made simple
|
148
132
|
```python
|
149
133
|
import time
|
134
|
+
from datetime import timedelta
|
150
135
|
from redis_dict import RedisDict
|
151
136
|
|
152
137
|
def expensive_function(x):
|
153
|
-
time.sleep(
|
138
|
+
time.sleep(x)
|
154
139
|
return x * 2
|
155
140
|
|
156
|
-
cache = RedisDict(namespace="cache", expire=
|
141
|
+
cache = RedisDict(namespace="cache", expire=timedelta(minutes=60))
|
157
142
|
|
158
143
|
def cached_expensive_function(x):
|
159
144
|
if x not in cache:
|
@@ -161,7 +146,7 @@ def cached_expensive_function(x):
|
|
161
146
|
return cache[x]
|
162
147
|
|
163
148
|
start_time = time.time()
|
164
|
-
print(cached_expensive_function(5)) # Takes around
|
149
|
+
print(cached_expensive_function(5)) # Takes around 5 seconds to compute and caches the result.
|
165
150
|
print(f"Time taken: {time.time() - start_time:.2f} seconds")
|
166
151
|
|
167
152
|
start_time = time.time()
|
@@ -181,7 +166,7 @@ dic["name"] = "John Doe"
|
|
181
166
|
dic["age"] = 32
|
182
167
|
dic["city"] = "Amsterdam"
|
183
168
|
|
184
|
-
# Get value by key
|
169
|
+
# Get value by key, from any instance connected to the same redis/namespace
|
185
170
|
print(dic["name"]) # Output: John Doe
|
186
171
|
|
187
172
|
# Update value by key, got a year older
|
@@ -234,10 +219,105 @@ print(dic["d"]) # Output: 4
|
|
234
219
|
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).
|
235
220
|
The unit-tests can be as used as a starting point.
|
236
221
|
|
222
|
+
## Types
|
223
|
+
|
224
|
+
### standard types
|
225
|
+
RedisDict supports a range of Python data types, from basic types to nested structures.
|
226
|
+
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.
|
227
|
+
Although the library supports nested structures, the recommended best practice is to use RedisDict as a shallow dictionary.
|
228
|
+
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.
|
229
|
+
Following types are supported:
|
230
|
+
`str, int, float, bool, NoneType, list, dict, tuple, set, datetime, date, time, timedelta, Decimal, complex, bytes, UUID, OrderedDict, defaultdict, frozenset`
|
231
|
+
```python
|
232
|
+
from redis_dict import RedisDict
|
233
|
+
|
234
|
+
from uuid import UUID
|
235
|
+
from decimal import Decimal
|
236
|
+
from collections import OrderedDict, defaultdict
|
237
|
+
from datetime import datetime, date, time, timedelta
|
238
|
+
|
239
|
+
|
240
|
+
dic = RedisDict()
|
241
|
+
|
242
|
+
dic["string"] = "Hello World"
|
243
|
+
dic["number"] = 42
|
244
|
+
dic["float"] = 3.14
|
245
|
+
dic["bool"] = True
|
246
|
+
dic["None"] = None
|
247
|
+
|
248
|
+
dic["list"] = [1, 2, 3]
|
249
|
+
dic["dict"] = {"a": 1, "b": 2}
|
250
|
+
dic["tuple"] = (1, 2, 3)
|
251
|
+
dic["set"] = {1, 2, 3}
|
252
|
+
|
253
|
+
dic["datetime"] = datetime.date(2024, 1, 1, 12, 30, 45)
|
254
|
+
dic["date"] = date(2024, 1, 1)
|
255
|
+
dic["time"] = time(12, 30, 45)
|
256
|
+
dic["delta"] = timedelta(days=1, hours=2)
|
257
|
+
|
258
|
+
dic["decimal"] = Decimal("3.14159")
|
259
|
+
dic["complex"] = complex(1, 2)
|
260
|
+
dic["bytes"] = bytes([72, 101, 108, 108, 111])
|
261
|
+
dic["uuid"] = UUID('12345678-1234-5678-1234-567812345678')
|
262
|
+
|
263
|
+
dic["ordered"] = OrderedDict([('a', 1), ('b', 2)])
|
264
|
+
dic["default"] = defaultdict(int, {'a': 1, 'b': 2})
|
265
|
+
dic["frozen"] = frozenset([1, 2, 3])
|
266
|
+
```
|
267
|
+
|
268
|
+
### Extending RedisDict with Custom Types
|
269
|
+
|
270
|
+
RedisDict supports custom type serialization. Here's how to add a new type:
|
271
|
+
|
272
|
+
|
273
|
+
```python
|
274
|
+
import json
|
275
|
+
from redis_dict import RedisDict
|
276
|
+
|
277
|
+
class Person:
|
278
|
+
def __init__(self, name, age):
|
279
|
+
self.name = name
|
280
|
+
self.age = age
|
281
|
+
|
282
|
+
def encode(self) -> str:
|
283
|
+
return json.dumps(self.__dict__)
|
284
|
+
|
285
|
+
@classmethod
|
286
|
+
def decode(cls, encoded_str: str) -> 'Person':
|
287
|
+
return cls(**json.loads(encoded_str))
|
288
|
+
|
289
|
+
redis_dict = RedisDict()
|
290
|
+
|
291
|
+
# Extend redis dict with the new type
|
292
|
+
redis_dict.extends_type(Person)
|
293
|
+
|
294
|
+
# RedisDict can now seamlessly handle Person instances.
|
295
|
+
person = Person(name="John", age=32)
|
296
|
+
redis_dict["person1"] = person
|
297
|
+
|
298
|
+
result = redis_dict["person1"]
|
299
|
+
|
300
|
+
assert result.name == person.name
|
301
|
+
assert result.age == person.age
|
302
|
+
```
|
303
|
+
|
304
|
+
```python
|
305
|
+
>>> from datetime import datetime
|
306
|
+
>>> redis_dict.extends_type(datetime, datetime.isoformat, datetime.fromisoformat)
|
307
|
+
>>> redis_dict["now"] = datetime.now()
|
308
|
+
>>> redis_dict
|
309
|
+
{'now': datetime.datetime(2024, 10, 14, 18, 41, 53, 493775)}
|
310
|
+
>>> redis_dict["now"]
|
311
|
+
datetime.datetime(2024, 10, 14, 18, 41, 53, 493775)
|
312
|
+
```
|
313
|
+
|
314
|
+
For more information on [extending types](https://github.com/Attumm/redis-dict/blob/main/extend_types_tests.py).
|
237
315
|
### Redis Encryption
|
238
|
-
Setup guide for configuring and utilizing encrypted Redis for redis-dict.
|
316
|
+
Setup guide for configuring and utilizing encrypted Redis TLS for redis-dict.
|
239
317
|
[Setup guide](https://github.com/Attumm/redis-dict/blob/main/encrypted_redis.MD)
|
240
318
|
|
319
|
+
### Redis Storage Encryption
|
320
|
+
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).
|
241
321
|
|
242
322
|
### Tests
|
243
323
|
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
|