compressedfhir 0.0.1__py3-none-any.whl

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.

Potentially problematic release.


This version of compressedfhir might be problematic. Click here for more details.

Files changed (41) hide show
  1. compressedfhir/__init__.py +0 -0
  2. compressedfhir/fhir/__init__.py +0 -0
  3. compressedfhir/fhir/base_resource_list.py +165 -0
  4. compressedfhir/fhir/fhir_bundle.py +291 -0
  5. compressedfhir/fhir/fhir_bundle_entry.py +234 -0
  6. compressedfhir/fhir/fhir_bundle_entry_list.py +82 -0
  7. compressedfhir/fhir/fhir_bundle_entry_request.py +71 -0
  8. compressedfhir/fhir/fhir_bundle_entry_response.py +64 -0
  9. compressedfhir/fhir/fhir_bundle_entry_search.py +75 -0
  10. compressedfhir/fhir/fhir_identifier.py +84 -0
  11. compressedfhir/fhir/fhir_link.py +63 -0
  12. compressedfhir/fhir/fhir_meta.py +47 -0
  13. compressedfhir/fhir/fhir_resource.py +163 -0
  14. compressedfhir/fhir/fhir_resource_list.py +143 -0
  15. compressedfhir/fhir/fhir_resource_map.py +193 -0
  16. compressedfhir/fhir/test/__init__.py +0 -0
  17. compressedfhir/fhir/test/test_bundle_entry.py +129 -0
  18. compressedfhir/fhir/test/test_bundle_entry_list.py +187 -0
  19. compressedfhir/fhir/test/test_bundle_entry_request.py +74 -0
  20. compressedfhir/fhir/test/test_bundle_entry_response.py +65 -0
  21. compressedfhir/fhir/test/test_fhir_bundle.py +245 -0
  22. compressedfhir/fhir/test/test_fhir_resource.py +225 -0
  23. compressedfhir/fhir/test/test_fhir_resource_list.py +160 -0
  24. compressedfhir/fhir/test/test_fhir_resource_map.py +293 -0
  25. compressedfhir/py.typed +0 -0
  26. compressedfhir/utilities/__init__.py +0 -0
  27. compressedfhir/utilities/compressed_dict/__init__.py +0 -0
  28. compressedfhir/utilities/compressed_dict/v1/__init__.py +0 -0
  29. compressedfhir/utilities/compressed_dict/v1/compressed_dict.py +635 -0
  30. compressedfhir/utilities/compressed_dict/v1/compressed_dict_access_error.py +2 -0
  31. compressedfhir/utilities/compressed_dict/v1/compressed_dict_storage_mode.py +50 -0
  32. compressedfhir/utilities/compressed_dict/v1/test/__init__.py +0 -0
  33. compressedfhir/utilities/compressed_dict/v1/test/test_compressed_dict.py +360 -0
  34. compressedfhir/utilities/fhir_json_encoder.py +30 -0
  35. compressedfhir/utilities/json_helpers.py +181 -0
  36. compressedfhir-0.0.1.dist-info/METADATA +28 -0
  37. compressedfhir-0.0.1.dist-info/RECORD +41 -0
  38. compressedfhir-0.0.1.dist-info/WHEEL +5 -0
  39. compressedfhir-0.0.1.dist-info/licenses/LICENSE +201 -0
  40. compressedfhir-0.0.1.dist-info/top_level.txt +2 -0
  41. tests/__init__.py +0 -0
@@ -0,0 +1,635 @@
1
+ import copy
2
+ import json
3
+ from collections.abc import KeysView, ValuesView, ItemsView, MutableMapping
4
+ from contextlib import contextmanager
5
+ from typing import Dict, Optional, Iterator, cast, List, Any, overload, OrderedDict
6
+
7
+ import msgpack
8
+ import zlib
9
+
10
+ from compressedfhir.utilities.compressed_dict.v1.compressed_dict_access_error import (
11
+ CompressedDictAccessError,
12
+ )
13
+ from compressedfhir.utilities.compressed_dict.v1.compressed_dict_storage_mode import (
14
+ CompressedDictStorageMode,
15
+ CompressedDictStorageType,
16
+ )
17
+ from compressedfhir.utilities.fhir_json_encoder import FhirJSONEncoder
18
+
19
+
20
+ class CompressedDict[K, V](MutableMapping[K, V]):
21
+ """
22
+ A dictionary-like class that supports flexible storage options.
23
+
24
+ It can store data in raw format, MessagePack format, or compressed MessagePack format.
25
+ """
26
+
27
+ # use slots to reduce memory usage
28
+ __slots__ = [
29
+ "_storage_mode",
30
+ "_working_dict",
31
+ "_raw_dict",
32
+ "_serialized_dict",
33
+ "_properties_to_cache",
34
+ "_cached_properties",
35
+ "_length",
36
+ "_transaction_depth",
37
+ ]
38
+
39
+ def __init__(
40
+ self,
41
+ *,
42
+ initial_dict: Dict[K, V] | OrderedDict[K, V] | None = None,
43
+ storage_mode: CompressedDictStorageMode,
44
+ properties_to_cache: List[K] | None,
45
+ ) -> None:
46
+ """
47
+ Initialize a dictionary with flexible storage options
48
+ Args:
49
+ initial_dict: Initial dictionary to store
50
+ storage_mode: Storage method for dictionary contents
51
+ - 'raw': Store as original dictionary
52
+ - 'msgpack': Store as MessagePack serialized bytes
53
+ - 'compressed_msgpack': Store as compressed MessagePack bytes
54
+ """
55
+ # Storage configuration
56
+ self._storage_mode: CompressedDictStorageMode = storage_mode
57
+
58
+ # Working copy of the dictionary during context
59
+ self._working_dict: Optional[OrderedDict[K, V]] = None
60
+
61
+ # Private storage options
62
+ self._raw_dict: OrderedDict[K, V] = OrderedDict[K, V]()
63
+ self._serialized_dict: Optional[bytes] = None
64
+
65
+ self._properties_to_cache: List[K] | None = properties_to_cache
66
+
67
+ self._cached_properties: Dict[K, V] = {}
68
+
69
+ self._length: int = 0
70
+
71
+ self._transaction_depth: int = 0
72
+
73
+ # Populate initial dictionary if provided
74
+ if initial_dict:
75
+ # Ensure we use an OrderedDict to maintain original order
76
+ initial_dict_ordered = (
77
+ initial_dict
78
+ if isinstance(initial_dict, OrderedDict)
79
+ else OrderedDict[K, V](initial_dict)
80
+ )
81
+ self.replace(value=initial_dict_ordered)
82
+
83
+ @contextmanager
84
+ def transaction(self) -> Iterator["CompressedDict[K, V]"]:
85
+ """
86
+ Context manager to safely access and modify the dictionary.
87
+
88
+ Deserializes the dictionary before entering the context
89
+ Serializes the dictionary after exiting the context
90
+
91
+ Raises:
92
+ CompressedDictAccessError: If methods are called outside the context
93
+ """
94
+ try:
95
+ self.start_transaction()
96
+
97
+ # Yield the working dictionary
98
+ yield self
99
+
100
+ finally:
101
+ self.end_transaction()
102
+
103
+ def start_transaction(self) -> "CompressedDict[K, V]":
104
+ """
105
+ Starts a transaction. Use transaction() for a contextmanager for simpler usage.
106
+ """
107
+ # Increment transaction depth
108
+ self._transaction_depth += 1
109
+ # Ensure working dictionary is ready on first entry
110
+ if self._transaction_depth == 1:
111
+ self.ensure_working_dict()
112
+
113
+ return self
114
+
115
+ def end_transaction(self) -> "CompressedDict[K, V]":
116
+ """
117
+ Ends a transaction. Use transaction() for a context_manager for simpler usage.
118
+
119
+ """
120
+ # Decrement transaction depth
121
+ self._transaction_depth -= 1
122
+ # Only update serialized dict when outermost transaction completes
123
+ if self._transaction_depth == 0:
124
+ self._update_serialized_dict(current_dict=self._working_dict)
125
+
126
+ # Clear the working dictionary
127
+ self._working_dict = None
128
+
129
+ return self
130
+
131
+ def ensure_working_dict(self) -> None:
132
+ """
133
+ Ensures that the working dictionary is initialized and deserialized.
134
+
135
+ """
136
+ if not self._working_dict:
137
+ self._working_dict = self.create_working_dict()
138
+
139
+ def create_working_dict(self) -> OrderedDict[K, V]:
140
+ working_dict: OrderedDict[K, V]
141
+ # Deserialize the dictionary before entering the context
142
+ if self._storage_mode.storage_type == "raw":
143
+ # For raw mode, create a deep copy of the existing dictionary
144
+ working_dict = self._raw_dict
145
+ else:
146
+ # For serialized modes, deserialize
147
+ working_dict = (
148
+ self._deserialize_dict(
149
+ serialized_dict=self._serialized_dict,
150
+ storage_type=self._storage_mode.storage_type,
151
+ )
152
+ if self._serialized_dict
153
+ else OrderedDict[K, V]()
154
+ )
155
+ assert isinstance(working_dict, OrderedDict)
156
+ return working_dict
157
+
158
+ @staticmethod
159
+ def _serialize_dict(
160
+ *, dictionary: OrderedDict[K, V], storage_type: CompressedDictStorageType
161
+ ) -> bytes:
162
+ """
163
+ Serialize entire dictionary using MessagePack
164
+
165
+ Args:
166
+ dictionary: Dictionary to serialize
167
+ storage_type: Storage type to use for serialization
168
+
169
+ Returns:
170
+ Serialized bytes
171
+ """
172
+ assert isinstance(dictionary, OrderedDict)
173
+ if storage_type == "compressed":
174
+ # Serialize to JSON and compress with zlib
175
+ json_str = json.dumps(
176
+ dictionary, separators=(",", ":"), cls=FhirJSONEncoder
177
+ ) # Most compact JSON representation
178
+ return zlib.compress(
179
+ json_str.encode("utf-8"), level=zlib.Z_BEST_COMPRESSION
180
+ )
181
+
182
+ # Serialize using MessagePack
183
+ packed = msgpack.packb(
184
+ dictionary,
185
+ use_bin_type=True, # Preserve string/bytes distinction
186
+ use_single_float=True, # More compact float representation
187
+ )
188
+
189
+ # Optional compression
190
+ if storage_type == "compressed_msgpack":
191
+ packed = zlib.compress(packed, level=zlib.Z_BEST_COMPRESSION)
192
+
193
+ return packed
194
+
195
+ @staticmethod
196
+ def _deserialize_dict(
197
+ *,
198
+ serialized_dict: bytes,
199
+ storage_type: CompressedDictStorageType,
200
+ ) -> OrderedDict[K, V]:
201
+ """
202
+ Deserialize entire dictionary from MessagePack
203
+
204
+ Args:
205
+ serialized_dict: Serialized dictionary bytes
206
+
207
+ Returns:
208
+ Deserialized dictionary
209
+ """
210
+ assert serialized_dict is not None, "Serialized dictionary cannot be None"
211
+
212
+ if storage_type == "compressed":
213
+ # Decompress and parse JSON
214
+ decompressed = zlib.decompress(serialized_dict)
215
+ decoded_text = decompressed.decode("utf-8")
216
+ # noinspection PyTypeChecker
217
+ decompressed_dict = json.loads(decoded_text, object_pairs_hook=OrderedDict)
218
+ assert isinstance(decompressed_dict, OrderedDict)
219
+ return cast(OrderedDict[K, V], decompressed_dict)
220
+
221
+ # Decompress if needed
222
+ to_unpack = (
223
+ zlib.decompress(serialized_dict)
224
+ if storage_type == "compressed_msgpack"
225
+ else serialized_dict
226
+ )
227
+
228
+ # Deserialize
229
+ unpacked_dict = msgpack.unpackb(
230
+ to_unpack,
231
+ raw=False, # Convert to strings
232
+ strict_map_key=False, # Handle potential key type variations
233
+ )
234
+ unpacked_dict = (
235
+ unpacked_dict
236
+ if isinstance(unpacked_dict, OrderedDict)
237
+ else OrderedDict[K, V](unpacked_dict)
238
+ )
239
+ assert isinstance(unpacked_dict, OrderedDict)
240
+ return cast(
241
+ OrderedDict[K, V],
242
+ unpacked_dict,
243
+ )
244
+
245
+ def _get_dict(self) -> OrderedDict[K, V]:
246
+ """
247
+ Get the dictionary, deserializing if necessary
248
+
249
+ Returns:
250
+ Current dictionary state
251
+ """
252
+
253
+ if self._working_dict is None:
254
+ raise CompressedDictAccessError(
255
+ "Dictionary access is only allowed within an transaction() block. "
256
+ "Use 'with compressed_dict.transaction() as d:' to access the dictionary."
257
+ f"You tried to access it with storage type {self._storage_mode.storage_type}."
258
+ )
259
+
260
+ if self._storage_mode.storage_type == "raw":
261
+ return self._raw_dict
262
+
263
+ # For non-raw modes, do not keep deserialized dict
264
+ return self._working_dict
265
+
266
+ def __getitem__(self, key: K) -> V:
267
+ """
268
+ Retrieve a value
269
+
270
+ Args:
271
+ key: Dictionary key
272
+
273
+ Returns:
274
+ Value associated with the key
275
+ """
276
+
277
+ if self._properties_to_cache and key in self._properties_to_cache:
278
+ return self._cached_properties[key]
279
+
280
+ if self._working_dict is None:
281
+ raise CompressedDictAccessError(
282
+ "Dictionary access is only allowed within an transaction() block. "
283
+ "Use 'with compressed_dict.transaction() as d:' to access the dictionary."
284
+ )
285
+ return self._get_dict()[key]
286
+
287
+ def __setitem__(self, key: K, value: V) -> None:
288
+ """
289
+ Set a value
290
+
291
+ Args:
292
+ key: Dictionary key
293
+ value: Value to store
294
+ """
295
+ if self._working_dict is None:
296
+ raise CompressedDictAccessError(
297
+ "Dictionary modification is only allowed within an transaction() block. "
298
+ "Use 'with compressed_dict.transaction() as d:' to modify the dictionary."
299
+ )
300
+
301
+ # Update the working dictionary
302
+ self._working_dict[key] = value
303
+
304
+ if self._properties_to_cache and key in self._properties_to_cache:
305
+ # Update the cached properties if the key is in the list
306
+ self._cached_properties[key] = value
307
+
308
+ def _update_serialized_dict(self, current_dict: OrderedDict[K, V] | None) -> None:
309
+ if current_dict is None:
310
+ self._cached_properties.clear()
311
+ self._length = 0
312
+ self._serialized_dict = None
313
+ self._raw_dict = OrderedDict[K, V]()
314
+ return
315
+
316
+ if self._properties_to_cache:
317
+ for key in self._properties_to_cache:
318
+ if key in current_dict:
319
+ self._cached_properties[key] = current_dict[key]
320
+
321
+ self._length = len(current_dict)
322
+
323
+ if self._working_dict is not None:
324
+ # If the working dictionary is None, initialize it
325
+ self._working_dict = current_dict
326
+
327
+ if self._transaction_depth == 0:
328
+ # If we're in a transaction,
329
+ # The serialized dictionary will be updated after the transaction
330
+ if self._storage_mode.storage_type == "raw":
331
+ self._raw_dict = current_dict
332
+ else:
333
+ self._serialized_dict = (
334
+ self._serialize_dict(
335
+ dictionary=current_dict,
336
+ storage_type=self._storage_mode.storage_type,
337
+ )
338
+ if current_dict
339
+ else None
340
+ )
341
+
342
+ def __delitem__(self, key: K) -> None:
343
+ """
344
+ Delete an item
345
+
346
+ Args:
347
+ key: Key to delete
348
+ """
349
+ if self._working_dict is None:
350
+ raise CompressedDictAccessError(
351
+ "Dictionary modification is only allowed within an transaction() block. "
352
+ "Use 'with compressed_dict.transaction() as d:' to modify the dictionary."
353
+ )
354
+
355
+ del self._working_dict[key]
356
+
357
+ def __contains__(self, key: object) -> bool:
358
+ """
359
+ Check if a key exists
360
+
361
+ Args:
362
+ key: Key to check
363
+
364
+ Returns:
365
+ Whether the key exists
366
+ """
367
+ # first check if the key is in the cached properties
368
+ if self._properties_to_cache and key in self._properties_to_cache:
369
+ return self._cached_properties.__contains__(key)
370
+
371
+ return self._get_dict().__contains__(key)
372
+
373
+ def __len__(self) -> int:
374
+ """
375
+ Get the number of items
376
+
377
+ Returns:
378
+ Number of items in the dictionary
379
+ """
380
+ return self._length
381
+
382
+ def __iter__(self) -> Iterator[K]:
383
+ """
384
+ Iterate over keys
385
+
386
+ Returns:
387
+ Iterator of keys
388
+ """
389
+ if self._working_dict is None:
390
+ raise CompressedDictAccessError(
391
+ "Dictionary modification is only allowed within an transaction() block. "
392
+ "Use 'with compressed_dict.transaction() as d:' to modify the dictionary."
393
+ )
394
+ return iter(self._get_dict())
395
+
396
+ def keys(self) -> KeysView[K]:
397
+ """
398
+ Get an iterator of keys
399
+
400
+ Returns:
401
+ Iterator of keys
402
+ """
403
+ return self._get_dict().keys()
404
+
405
+ def values(self) -> ValuesView[V]:
406
+ """
407
+ Get an iterator of values
408
+
409
+ Returns:
410
+ Iterator of values
411
+ """
412
+ return self._get_dict().values()
413
+
414
+ def items(self) -> ItemsView[K, V]:
415
+ """
416
+ Get an iterator of key-value pairs
417
+
418
+ Returns:
419
+ Iterator of key-value pairs
420
+ """
421
+ return self._get_dict().items()
422
+
423
+ def dict(self, *, remove_nulls: bool = True) -> OrderedDict[K, V]:
424
+ """
425
+ Convert to a standard dictionary
426
+
427
+ Returns:
428
+ Standard dictionary with all values
429
+ """
430
+ if self._working_dict:
431
+ return self._working_dict
432
+ else:
433
+ # if the working dict is None, return it but don't store it in the self._working_dict to keep memory low
434
+ return self.create_working_dict()
435
+
436
+ def __repr__(self) -> str:
437
+ """
438
+ String representation of the dictionary
439
+
440
+ Returns:
441
+ String representation
442
+ """
443
+ cached_property_list: List[str] = [
444
+ f"{k}={v}" for k, v in self._cached_properties.items()
445
+ ]
446
+ return (
447
+ (
448
+ f"CompressedDict(storage_type='{self._storage_mode.storage_type}', keys={self._length}"
449
+ )
450
+ + (", " if cached_property_list else "")
451
+ + ", ".join(cached_property_list)
452
+ + ")"
453
+ )
454
+
455
+ def replace(
456
+ self, *, value: Dict[K, V] | OrderedDict[K, V]
457
+ ) -> "CompressedDict[K, V]":
458
+ """
459
+ Replace the current dictionary with a new one
460
+
461
+ Args:
462
+ value: New dictionary to store
463
+
464
+ Returns:
465
+ Self
466
+ """
467
+ if not value:
468
+ self.clear()
469
+ return self
470
+
471
+ new_dict: OrderedDict[K, V] = (
472
+ value if isinstance(value, OrderedDict) else OrderedDict[K, V](value)
473
+ )
474
+ self._update_serialized_dict(current_dict=new_dict)
475
+ return self
476
+
477
+ def clear(self) -> None:
478
+ """
479
+ Clear the dictionary
480
+ """
481
+ self._update_serialized_dict(current_dict=None)
482
+
483
+ def __eq__(self, other: object) -> bool:
484
+ """
485
+ Check equality with another dictionary
486
+
487
+ Args:
488
+ other: Dictionary to compare with (CompressedDict or plain dict)
489
+
490
+ Returns:
491
+ Whether the dictionaries are equal in keys and values
492
+ """
493
+ # If other is not a dictionary-like object, return False
494
+ if not isinstance(other, (CompressedDict, dict, OrderedDict)):
495
+ return False
496
+
497
+ # Get the dictionary representation of self
498
+ self_dict = self.dict()
499
+
500
+ # If other is a CompressedDict, use its _get_dict() method
501
+ if isinstance(other, CompressedDict):
502
+ other_dict = other.dict()
503
+ else:
504
+ # If other is a plain dict, use it directly
505
+ if isinstance(other, OrderedDict):
506
+ # If other is an OrderedDict, use it directly
507
+ other_dict = other
508
+ else:
509
+ other_dict = OrderedDict[K, V](other)
510
+
511
+ # Compare keys and values
512
+ # Check that all keys in both dictionaries match exactly
513
+ return set(self_dict.keys()) == set(other_dict.keys()) and all(
514
+ self_dict[key] == other_dict[key] for key in self_dict
515
+ )
516
+
517
+ @overload
518
+ def get(self, key: K) -> Optional[V]:
519
+ """
520
+ Get a value for an existing key
521
+
522
+ :param key: Key to retrieve
523
+ :return: Value or None if key is not found
524
+ """
525
+ ...
526
+
527
+ # noinspection PyMethodOverriding
528
+ @overload
529
+ def get[_T](self, key: K, /, default: V | _T) -> V | _T:
530
+ """
531
+ Get a value with a default
532
+
533
+ Args:
534
+ key: Key to retrieve
535
+ default: Default value if key is not found
536
+
537
+ Returns:
538
+ Value associated with the key or default
539
+ """
540
+ ...
541
+
542
+ def get[_T](self, key: K, default: V | _T | None = None) -> V | _T | None:
543
+ if key in self:
544
+ return self[key]
545
+ return default
546
+
547
+ def __deepcopy__(self, memo: Dict[int, Any]) -> "CompressedDict[K, V]":
548
+ """
549
+ Create a deep copy of the dictionary
550
+
551
+ Args:
552
+ memo: Memoization dictionary for deep copy
553
+
554
+ Returns:
555
+ Deep copy of the dictionary
556
+ """
557
+ # Create a new instance with the same storage mode
558
+ new_instance = CompressedDict(
559
+ initial_dict=copy.deepcopy(self.dict()),
560
+ storage_mode=self._storage_mode,
561
+ properties_to_cache=self._properties_to_cache,
562
+ )
563
+ return new_instance
564
+
565
+ def copy(self) -> "CompressedDict[K,V]":
566
+ """
567
+ Creates a copy of the BundleEntry object.
568
+
569
+ :return: A new BundleEntry object with the same attributes.
570
+ """
571
+ return copy.deepcopy(self)
572
+
573
+ def get_storage_mode(self) -> CompressedDictStorageMode:
574
+ """
575
+ Get the storage mode
576
+
577
+ Returns:
578
+ Storage mode
579
+ """
580
+ return self._storage_mode
581
+
582
+ @overload
583
+ def pop(self, key: K, /) -> V:
584
+ """
585
+ Remove and return a value for an existing key
586
+
587
+ :param key: Key to remove
588
+ :return: Removed value
589
+ :raises KeyError: If key is not found
590
+ """
591
+ ...
592
+
593
+ # noinspection PyMethodOverriding
594
+ @overload
595
+ def pop[_T](self, key: K, /, default: _T) -> V | _T:
596
+ """
597
+ Remove and return a value, or return default if key is not found
598
+
599
+ :param key: Key to remove
600
+ :param default: Default value to return if key is not found
601
+ :return: Removed value or default
602
+ """
603
+ ...
604
+
605
+ def pop[_T](self, key: K, /, default: V | _T | None = None) -> V | _T | None:
606
+ """
607
+ Remove and return a value
608
+
609
+ :param key: Key to remove
610
+ :param default: Optional default value if key is not found
611
+ :return: Removed value or default
612
+ :raises KeyError: If key is not found and no default is provided
613
+ """
614
+ if self._working_dict is None:
615
+ raise CompressedDictAccessError(
616
+ "Dictionary modification is only allowed within a transaction() block. "
617
+ "Use 'with compressed_dict.transaction() as d:' to modify the dictionary."
618
+ )
619
+
620
+ # If no default is provided, use the standard dict.pop() behavior
621
+ if default is None:
622
+ return self._working_dict.pop(key)
623
+
624
+ return self._working_dict.pop(key, default)
625
+
626
+ def to_plain_dict(self) -> Dict[K, V]:
627
+ """
628
+ Get the plain dictionary representation
629
+
630
+ Returns:
631
+ Plain dictionary
632
+ """
633
+ return cast(
634
+ Dict[K, V], json.loads(json.dumps(self.dict(), cls=FhirJSONEncoder))
635
+ )
@@ -0,0 +1,2 @@
1
+ class CompressedDictAccessError(Exception):
2
+ """Exception raised when attempting to access CompressedDict outside of context."""
@@ -0,0 +1,50 @@
1
+ import dataclasses
2
+ from typing import Literal, TypeAlias
3
+
4
+ CompressedDictStorageType: TypeAlias = Literal[
5
+ "raw", "compressed", "msgpack", "compressed_msgpack"
6
+ ]
7
+ """
8
+ CompressedDictStorageType is a type alias for the different storage types
9
+ raw: No compression
10
+ compressed: Compressed using zlib
11
+ msgpack: Compressed using msgpack
12
+ compressed_msgpack: Compressed using msgpack with zlib
13
+ """
14
+
15
+
16
+ @dataclasses.dataclass(slots=True)
17
+ class CompressedDictStorageMode:
18
+ """
19
+ CompressedDictStorageMode is a dataclass that defines the storage mode
20
+ """
21
+
22
+ storage_type: CompressedDictStorageType = "compressed"
23
+ """
24
+ CompressedDictStorageType is a type alias for the different storage types
25
+ raw: No compression
26
+ compressed: Compressed using zlib
27
+ msgpack: Compressed using msgpack
28
+ compressed_msgpack: Compressed using msgpack with zlib
29
+ """
30
+
31
+ @classmethod
32
+ def default(cls) -> "CompressedDictStorageMode":
33
+ """
34
+ Returns the default storage mode
35
+ """
36
+ return cls(storage_type="compressed")
37
+
38
+ @classmethod
39
+ def raw(cls) -> "CompressedDictStorageMode":
40
+ """
41
+ Returns the default storage mode
42
+ """
43
+ return cls(storage_type="raw")
44
+
45
+ @classmethod
46
+ def compressed(cls) -> "CompressedDictStorageMode":
47
+ """
48
+ Returns the default storage mode
49
+ """
50
+ return cls(storage_type="compressed")