cachekit 0.10.1__tar.gz → 0.11.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.
Files changed (92) hide show
  1. {cachekit-0.10.1 → cachekit-0.11.1}/Cargo.lock +3 -3
  2. {cachekit-0.10.1 → cachekit-0.11.1}/PKG-INFO +5 -4
  3. {cachekit-0.10.1 → cachekit-0.11.1}/README.md +1 -1
  4. {cachekit-0.10.1 → cachekit-0.11.1}/pyproject.toml +9 -3
  5. {cachekit-0.10.1 → cachekit-0.11.1}/rust/Cargo.toml +1 -1
  6. {cachekit-0.10.1 → cachekit-0.11.1}/rust/README.md +1 -1
  7. {cachekit-0.10.1 → cachekit-0.11.1}/src/cachekit/__init__.py +1 -1
  8. {cachekit-0.10.1 → cachekit-0.11.1}/src/cachekit/cache_handler.py +1 -1
  9. {cachekit-0.10.1 → cachekit-0.11.1}/src/cachekit/config/singleton.py +20 -3
  10. {cachekit-0.10.1 → cachekit-0.11.1}/src/cachekit/serializers/__init__.py +30 -6
  11. {cachekit-0.10.1 → cachekit-0.11.1}/src/cachekit/serializers/encryption_wrapper.py +1 -1
  12. {cachekit-0.10.1 → cachekit-0.11.1}/src/cachekit/serializers/orjson_serializer.py +6 -1
  13. {cachekit-0.10.1 → cachekit-0.11.1}/Cargo.toml +0 -0
  14. {cachekit-0.10.1 → cachekit-0.11.1}/LICENSE +0 -0
  15. {cachekit-0.10.1 → cachekit-0.11.1}/rust/Makefile +0 -0
  16. {cachekit-0.10.1 → cachekit-0.11.1}/rust/TEST_EXPANSION_SUMMARY.md +0 -0
  17. {cachekit-0.10.1 → cachekit-0.11.1}/rust/src/lib.rs +0 -0
  18. {cachekit-0.10.1 → cachekit-0.11.1}/rust/src/python_bindings.rs +0 -0
  19. {cachekit-0.10.1 → cachekit-0.11.1}/rust/supply-chain/audits.toml +0 -0
  20. {cachekit-0.10.1 → cachekit-0.11.1}/rust/supply-chain/config.toml +0 -0
  21. {cachekit-0.10.1 → cachekit-0.11.1}/rust/supply-chain/imports.lock +0 -0
  22. {cachekit-0.10.1 → cachekit-0.11.1}/rust/tsan_suppressions.txt +0 -0
  23. {cachekit-0.10.1 → cachekit-0.11.1}/src/cachekit/backends/__init__.py +0 -0
  24. {cachekit-0.10.1 → cachekit-0.11.1}/src/cachekit/backends/base.py +0 -0
  25. {cachekit-0.10.1 → cachekit-0.11.1}/src/cachekit/backends/base_config.py +0 -0
  26. {cachekit-0.10.1 → cachekit-0.11.1}/src/cachekit/backends/cachekitio/__init__.py +0 -0
  27. {cachekit-0.10.1 → cachekit-0.11.1}/src/cachekit/backends/cachekitio/backend.py +0 -0
  28. {cachekit-0.10.1 → cachekit-0.11.1}/src/cachekit/backends/cachekitio/client.py +0 -0
  29. {cachekit-0.10.1 → cachekit-0.11.1}/src/cachekit/backends/cachekitio/config.py +0 -0
  30. {cachekit-0.10.1 → cachekit-0.11.1}/src/cachekit/backends/cachekitio/error_handler.py +0 -0
  31. {cachekit-0.10.1 → cachekit-0.11.1}/src/cachekit/backends/cachekitio/session.py +0 -0
  32. {cachekit-0.10.1 → cachekit-0.11.1}/src/cachekit/backends/errors.py +0 -0
  33. {cachekit-0.10.1 → cachekit-0.11.1}/src/cachekit/backends/file/__init__.py +0 -0
  34. {cachekit-0.10.1 → cachekit-0.11.1}/src/cachekit/backends/file/backend.py +0 -0
  35. {cachekit-0.10.1 → cachekit-0.11.1}/src/cachekit/backends/file/config.py +0 -0
  36. {cachekit-0.10.1 → cachekit-0.11.1}/src/cachekit/backends/memcached/__init__.py +0 -0
  37. {cachekit-0.10.1 → cachekit-0.11.1}/src/cachekit/backends/memcached/backend.py +0 -0
  38. {cachekit-0.10.1 → cachekit-0.11.1}/src/cachekit/backends/memcached/config.py +0 -0
  39. {cachekit-0.10.1 → cachekit-0.11.1}/src/cachekit/backends/memcached/error_handler.py +0 -0
  40. {cachekit-0.10.1 → cachekit-0.11.1}/src/cachekit/backends/provider.py +0 -0
  41. {cachekit-0.10.1 → cachekit-0.11.1}/src/cachekit/backends/redis/__init__.py +0 -0
  42. {cachekit-0.10.1 → cachekit-0.11.1}/src/cachekit/backends/redis/backend.py +0 -0
  43. {cachekit-0.10.1 → cachekit-0.11.1}/src/cachekit/backends/redis/client.py +0 -0
  44. {cachekit-0.10.1 → cachekit-0.11.1}/src/cachekit/backends/redis/config.py +0 -0
  45. {cachekit-0.10.1 → cachekit-0.11.1}/src/cachekit/backends/redis/error_handler.py +0 -0
  46. {cachekit-0.10.1 → cachekit-0.11.1}/src/cachekit/backends/redis/provider.py +0 -0
  47. {cachekit-0.10.1 → cachekit-0.11.1}/src/cachekit/config/__init__.py +0 -0
  48. {cachekit-0.10.1 → cachekit-0.11.1}/src/cachekit/config/decorator.py +0 -0
  49. {cachekit-0.10.1 → cachekit-0.11.1}/src/cachekit/config/nested.py +0 -0
  50. {cachekit-0.10.1 → cachekit-0.11.1}/src/cachekit/config/settings.py +0 -0
  51. {cachekit-0.10.1 → cachekit-0.11.1}/src/cachekit/config/validation.py +0 -0
  52. {cachekit-0.10.1 → cachekit-0.11.1}/src/cachekit/decorators/__init__.py +0 -0
  53. {cachekit-0.10.1 → cachekit-0.11.1}/src/cachekit/decorators/intent.py +0 -0
  54. {cachekit-0.10.1 → cachekit-0.11.1}/src/cachekit/decorators/local_wrapper.py +0 -0
  55. {cachekit-0.10.1 → cachekit-0.11.1}/src/cachekit/decorators/main.py +0 -0
  56. {cachekit-0.10.1 → cachekit-0.11.1}/src/cachekit/decorators/orchestrator.py +0 -0
  57. {cachekit-0.10.1 → cachekit-0.11.1}/src/cachekit/decorators/session.py +0 -0
  58. {cachekit-0.10.1 → cachekit-0.11.1}/src/cachekit/decorators/stats_context.py +0 -0
  59. {cachekit-0.10.1 → cachekit-0.11.1}/src/cachekit/decorators/tenant_context.py +0 -0
  60. {cachekit-0.10.1 → cachekit-0.11.1}/src/cachekit/decorators/utils/__init__.py +0 -0
  61. {cachekit-0.10.1 → cachekit-0.11.1}/src/cachekit/decorators/wrapper.py +0 -0
  62. {cachekit-0.10.1 → cachekit-0.11.1}/src/cachekit/di.py +0 -0
  63. {cachekit-0.10.1 → cachekit-0.11.1}/src/cachekit/hash_utils.py +0 -0
  64. {cachekit-0.10.1 → cachekit-0.11.1}/src/cachekit/health.py +0 -0
  65. {cachekit-0.10.1 → cachekit-0.11.1}/src/cachekit/hiredis_compat.py +0 -0
  66. {cachekit-0.10.1 → cachekit-0.11.1}/src/cachekit/imports.py +0 -0
  67. {cachekit-0.10.1 → cachekit-0.11.1}/src/cachekit/invalidation/__init__.py +0 -0
  68. {cachekit-0.10.1 → cachekit-0.11.1}/src/cachekit/invalidation/channel.py +0 -0
  69. {cachekit-0.10.1 → cachekit-0.11.1}/src/cachekit/invalidation/event.py +0 -0
  70. {cachekit-0.10.1 → cachekit-0.11.1}/src/cachekit/invalidation/redis_channel.py +0 -0
  71. {cachekit-0.10.1 → cachekit-0.11.1}/src/cachekit/key_generator.py +0 -0
  72. {cachekit-0.10.1 → cachekit-0.11.1}/src/cachekit/l1_cache.py +0 -0
  73. {cachekit-0.10.1 → cachekit-0.11.1}/src/cachekit/logging.py +0 -0
  74. {cachekit-0.10.1 → cachekit-0.11.1}/src/cachekit/monitoring/__init__.py +0 -0
  75. {cachekit-0.10.1 → cachekit-0.11.1}/src/cachekit/monitoring/correlation_tracking.py +0 -0
  76. {cachekit-0.10.1 → cachekit-0.11.1}/src/cachekit/monitoring/pool_monitor.py +0 -0
  77. {cachekit-0.10.1 → cachekit-0.11.1}/src/cachekit/monitoring/protocols.py +0 -0
  78. {cachekit-0.10.1 → cachekit-0.11.1}/src/cachekit/object_cache.py +0 -0
  79. {cachekit-0.10.1 → cachekit-0.11.1}/src/cachekit/py.typed +0 -0
  80. {cachekit-0.10.1 → cachekit-0.11.1}/src/cachekit/reliability/__init__.py +0 -0
  81. {cachekit-0.10.1 → cachekit-0.11.1}/src/cachekit/reliability/adaptive_timeout.py +0 -0
  82. {cachekit-0.10.1 → cachekit-0.11.1}/src/cachekit/reliability/async_metrics.py +0 -0
  83. {cachekit-0.10.1 → cachekit-0.11.1}/src/cachekit/reliability/circuit_breaker.py +0 -0
  84. {cachekit-0.10.1 → cachekit-0.11.1}/src/cachekit/reliability/error_classification.py +0 -0
  85. {cachekit-0.10.1 → cachekit-0.11.1}/src/cachekit/reliability/load_control.py +0 -0
  86. {cachekit-0.10.1 → cachekit-0.11.1}/src/cachekit/reliability/metrics_collection.py +0 -0
  87. {cachekit-0.10.1 → cachekit-0.11.1}/src/cachekit/reliability/profiles.py +0 -0
  88. {cachekit-0.10.1 → cachekit-0.11.1}/src/cachekit/serializers/arrow_serializer.py +0 -0
  89. {cachekit-0.10.1 → cachekit-0.11.1}/src/cachekit/serializers/auto_serializer.py +0 -0
  90. {cachekit-0.10.1 → cachekit-0.11.1}/src/cachekit/serializers/base.py +0 -0
  91. {cachekit-0.10.1 → cachekit-0.11.1}/src/cachekit/serializers/standard_serializer.py +0 -0
  92. {cachekit-0.10.1 → cachekit-0.11.1}/src/cachekit/serializers/wrapper.py +0 -0
@@ -271,7 +271,7 @@ dependencies = [
271
271
 
272
272
  [[package]]
273
273
  name = "cachekit-rs"
274
- version = "0.10.1"
274
+ version = "0.11.1"
275
275
  dependencies = [
276
276
  "cachekit-core",
277
277
  "criterion",
@@ -954,9 +954,9 @@ checksum = "f8ca58f447f06ed17d5fc4043ce1b10dd205e060fb3ce5b979b8ed8e59ff3f79"
954
954
 
955
955
  [[package]]
956
956
  name = "memmap2"
957
- version = "0.9.10"
957
+ version = "0.9.11"
958
958
  source = "registry+https://github.com/rust-lang/crates.io-index"
959
- checksum = "714098028fe011992e1c3962653c96b2d578c4b4bce9036e15ff220319b1e0e3"
959
+ checksum = "d1219ed1b7f229ee7104d281dd01d6802fe28bb6e95d292942c4daacdeb798c0"
960
960
  dependencies = [
961
961
  "libc",
962
962
  ]
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: cachekit
3
- Version: 0.10.1
3
+ Version: 0.11.1
4
4
  Classifier: Development Status :: 3 - Alpha
5
5
  Classifier: Intended Audience :: Developers
6
6
  Classifier: License :: OSI Approved :: MIT License
@@ -26,15 +26,16 @@ Requires-Dist: tenacity>=8.0.0
26
26
  Requires-Dist: prometheus-client>=0.22.1
27
27
  Requires-Dist: psutil>=7.0.0
28
28
  Requires-Dist: blake3>=1.0.5
29
- Requires-Dist: msgpack>=1.1.2
30
- Requires-Dist: orjson>=3.9.0
29
+ Requires-Dist: msgpack>=1.2.1
31
30
  Requires-Dist: xxhash>=3.5.0
32
31
  Requires-Dist: httpx[http2]>=0.28.1
33
32
  Requires-Dist: numpy>=2.0.2 ; extra == 'data'
34
33
  Requires-Dist: pandas>=1.3.0 ; extra == 'data'
35
34
  Requires-Dist: pyarrow>=21.0.0 ; extra == 'data'
35
+ Requires-Dist: orjson>=3.9.0 ; extra == 'json'
36
36
  Requires-Dist: pymemcache>=4.0.0 ; extra == 'memcached'
37
37
  Provides-Extra: data
38
+ Provides-Extra: json
38
39
  Provides-Extra: memcached
39
40
  License-File: LICENSE
40
41
  Summary: Production-ready Redis caching for Python with intelligent reliability features and Rust-powered performance
@@ -302,7 +303,7 @@ def test_cached_function():
302
303
  | Serializer | Speed | Use Case |
303
304
  |:-----------|:-----:|:---------|
304
305
  | **StandardSerializer** | ★★★★☆ | General Python types, NumPy, Pandas |
305
- | **OrjsonSerializer** | ★★★★★ | JSON APIs (2-5x faster than stdlib) |
306
+ | **OrjsonSerializer** | ★★★★★ | JSON APIs (2-5x faster than stdlib) — requires `cachekit[json]` |
306
307
  | **ArrowSerializer** | ★★★★★ | Large DataFrames (6-23x faster for 10K+ rows) |
307
308
  | **EncryptionWrapper** | ★★★★☆ | Wraps any serializer with AES-256-GCM |
308
309
 
@@ -249,7 +249,7 @@ def test_cached_function():
249
249
  | Serializer | Speed | Use Case |
250
250
  |:-----------|:-----:|:---------|
251
251
  | **StandardSerializer** | ★★★★☆ | General Python types, NumPy, Pandas |
252
- | **OrjsonSerializer** | ★★★★★ | JSON APIs (2-5x faster than stdlib) |
252
+ | **OrjsonSerializer** | ★★★★★ | JSON APIs (2-5x faster than stdlib) — requires `cachekit[json]` |
253
253
  | **ArrowSerializer** | ★★★★★ | Large DataFrames (6-23x faster for 10K+ rows) |
254
254
  | **EncryptionWrapper** | ★★★★☆ | Wraps any serializer with AES-256-GCM |
255
255
 
@@ -4,7 +4,7 @@ build-backend = "maturin"
4
4
 
5
5
  [project]
6
6
  name = "cachekit"
7
- version = "0.10.1"
7
+ version = "0.11.1"
8
8
  description = "Production-ready Redis caching for Python with intelligent reliability features and Rust-powered performance"
9
9
  readme = "README.md"
10
10
  license = {text = "MIT"}
@@ -64,8 +64,7 @@ dependencies = [
64
64
  "psutil>=7.0.0",
65
65
  # Serialization and hashing
66
66
  "blake3>=1.0.5",
67
- "msgpack>=1.1.2",
68
- "orjson>=3.9.0",
67
+ "msgpack>=1.2.1",
69
68
  "xxhash>=3.5.0",
70
69
  # HTTP client for SaaS backend (cachekit.io)
71
70
  "httpx[http2]>=0.28.1",
@@ -78,6 +77,10 @@ data = [
78
77
  "pandas>=1.3.0",
79
78
  "pyarrow>=21.0.0",
80
79
  ]
80
+ json = [
81
+ # OrjsonSerializer (serializer="orjson") — fast JSON via orjson
82
+ "orjson>=3.9.0",
83
+ ]
81
84
  memcached = [
82
85
  "pymemcache>=4.0.0",
83
86
  ]
@@ -228,6 +231,9 @@ dev = [
228
231
  "numpy>=2.0.2",
229
232
  "pandas>=1.3.0",
230
233
  "pyarrow>=21.0.0",
234
+ # OrjsonSerializer support — now the [json] optional extra; kept here so the
235
+ # orjson tests, doctests, and markdown-docs still resolve it in dev/CI.
236
+ "orjson>=3.9.0",
231
237
  "pytest-xdist>=3.8.0",
232
238
  "time-machine>=2.19.0",
233
239
  ]
@@ -1,6 +1,6 @@
1
1
  [package]
2
2
  name = "cachekit-rs"
3
- version = "0.10.1"
3
+ version = "0.11.1"
4
4
  edition = "2021"
5
5
  authors = ["cachekit Contributors"]
6
6
  description = "High-performance storage engine for caching with compression and encryption"
@@ -249,7 +249,7 @@ def test_cached_function():
249
249
  | Serializer | Speed | Use Case |
250
250
  |:-----------|:-----:|:---------|
251
251
  | **StandardSerializer** | ★★★★☆ | General Python types, NumPy, Pandas |
252
- | **OrjsonSerializer** | ★★★★★ | JSON APIs (2-5x faster than stdlib) |
252
+ | **OrjsonSerializer** | ★★★★★ | JSON APIs (2-5x faster than stdlib) — requires `cachekit[json]` |
253
253
  | **ArrowSerializer** | ★★★★★ | Large DataFrames (6-23x faster for 10K+ rows) |
254
254
  | **EncryptionWrapper** | ★★★★☆ | Wraps any serializer with AES-256-GCM |
255
255
 
@@ -68,7 +68,7 @@ Example Usage:
68
68
  ```
69
69
  """
70
70
 
71
- __version__ = "0.10.1"
71
+ __version__ = "0.11.1"
72
72
 
73
73
  from collections.abc import Callable
74
74
  from typing import Any, TypeVar
@@ -308,7 +308,7 @@ class CacheSerializationHandler:
308
308
  deployment_uuid: Optional deployment-specific UUID for single-tenant mode.
309
309
  If not provided, uses env var or persistent file.
310
310
  master_key: Optional master key for encryption (hex-encoded). If not provided,
311
- reads from REDIS_CACHE_MASTER_KEY environment variable.
311
+ reads from CACHEKIT_MASTER_KEY environment variable.
312
312
  enable_integrity_checking: Enable integrity checking (default: True)
313
313
  Uses xxHash3-64 (8 bytes) for all serializers.
314
314
  Set to False for @cache.minimal (speed-first, no checksums)
@@ -1,5 +1,6 @@
1
1
  """Thread-safe singleton pattern for global cachekit settings."""
2
2
 
3
+ import os
3
4
  import threading
4
5
  from typing import Optional
5
6
 
@@ -43,9 +44,25 @@ def get_settings() -> CachekitConfig:
43
44
  """
44
45
  global _settings_instance
45
46
 
46
- # Fast path - return cached instance without lock
47
- if _settings_instance is not None:
48
- return _settings_instance
47
+ # Fast path - snapshot the global once. A concurrent reset_settings() can null _settings_instance
48
+ # at any time, so the unlocked self-heal check below reads the snapshot, never the global, or it
49
+ # could dereference None between the not-None check and the .master_key access.
50
+ instance = _settings_instance
51
+ if instance is not None:
52
+ # Self-heal the keyless-then-key-set ordering trap (#195): if the config was first built
53
+ # before CACHEKIT_MASTER_KEY entered the environment (e.g. an import-time cache decorator
54
+ # evaluated before the app loaded its secrets), it froze master_key=None — encryption would
55
+ # then silently never activate. Re-read once the key appears, so it turns on without an
56
+ # explicit reset_settings(). Idempotent: after the rebuild master_key is set, so this never
57
+ # fires again (no per-call churn once a key is present).
58
+ if instance.master_key is None and os.environ.get("CACHEKIT_MASTER_KEY"):
59
+ with _settings_lock:
60
+ # Re-read the global under the lock: a peer may have rebuilt it (key now set) or
61
+ # reset_settings() may have cleared it (back to None). Rebuild only if still keyless.
62
+ if _settings_instance is None or _settings_instance.master_key is None:
63
+ _settings_instance = CachekitConfig.from_env()
64
+ return _settings_instance
65
+ return instance
49
66
 
50
67
  # Slow path - create instance with lock
51
68
  with _settings_lock:
@@ -15,11 +15,11 @@ from .base import (
15
15
  SerializerProtocol,
16
16
  )
17
17
  from .encryption_wrapper import EncryptionWrapper
18
- from .orjson_serializer import OrjsonSerializer
19
18
  from .standard_serializer import StandardSerializer
20
19
 
21
20
  if TYPE_CHECKING:
22
21
  from .arrow_serializer import ArrowSerializer
22
+ from .orjson_serializer import OrjsonSerializer
23
23
 
24
24
  logger = logging.getLogger(__name__)
25
25
 
@@ -37,6 +37,20 @@ def _get_arrow_serializer() -> type:
37
37
  return _ArrowSerializer
38
38
 
39
39
 
40
+ # Lazy import for optional OrjsonSerializer (requires orjson from [json] extra)
41
+ _OrjsonSerializer: type | None = None
42
+
43
+
44
+ def _get_orjson_serializer() -> type:
45
+ """Lazy-load OrjsonSerializer. Raises ImportError if orjson not installed."""
46
+ global _OrjsonSerializer
47
+ if _OrjsonSerializer is None:
48
+ from .orjson_serializer import OrjsonSerializer
49
+
50
+ _OrjsonSerializer = OrjsonSerializer
51
+ return _OrjsonSerializer
52
+
53
+
40
54
  # Validate ByteStorage works correctly
41
55
  test_storage = ByteStorage("msgpack")
42
56
  test_data = b"test validation data"
@@ -57,7 +71,7 @@ SERIALIZER_REGISTRY = {
57
71
  "default": StandardSerializer, # Language-agnostic MessagePack for multi-language caches
58
72
  "std": StandardSerializer, # Explicit StandardSerializer alias
59
73
  "arrow": None, # Lazy-loaded: requires pyarrow from [data] extra
60
- "orjson": OrjsonSerializer,
74
+ "orjson": None, # Lazy-loaded: requires orjson from [json] extra
61
75
  "encrypted": EncryptionWrapper, # StandardSerializer + AES-256-GCM encryption
62
76
  }
63
77
 
@@ -116,9 +130,11 @@ def get_serializer(name: str, enable_integrity_checking: bool = True) -> Seriali
116
130
  f"@cache(serializer=MySerializer())"
117
131
  )
118
132
 
119
- # Get serializer class (lazy-load arrow if needed)
133
+ # Get serializer class (lazy-load optional serializers if needed)
120
134
  if name == "arrow":
121
135
  serializer_class = _get_arrow_serializer()
136
+ elif name == "orjson":
137
+ serializer_class = _get_orjson_serializer()
122
138
  else:
123
139
  serializer_class = SERIALIZER_REGISTRY[name]
124
140
 
@@ -177,9 +193,15 @@ def get_serializer_info() -> dict[str, dict[str, Any]]:
177
193
  if hasattr(instance, "get_info"):
178
194
  info[name].update(instance.get_info()) # type: ignore[attr-defined]
179
195
  except ImportError as e:
196
+ # Optional serializer whose backing dependency (pyarrow / orjson) is absent.
197
+ optional_modules = {
198
+ "arrow": ("ArrowSerializer", "cachekit.serializers.arrow_serializer"),
199
+ "orjson": ("OrjsonSerializer", "cachekit.serializers.orjson_serializer"),
200
+ }
201
+ cls, module = optional_modules.get(name, ("Unknown", "unknown"))
180
202
  info[name] = {
181
- "class": "ArrowSerializer" if name == "arrow" else "Unknown",
182
- "module": "cachekit.serializers.arrow_serializer",
203
+ "class": cls,
204
+ "module": module,
183
205
  "available": False,
184
206
  "error": str(e),
185
207
  }
@@ -194,9 +216,11 @@ def get_serializer_info() -> dict[str, dict[str, Any]]:
194
216
 
195
217
 
196
218
  def __getattr__(name: str) -> Any:
197
- """Lazy attribute access for optional ArrowSerializer."""
219
+ """Lazy attribute access for optional ArrowSerializer / OrjsonSerializer."""
198
220
  if name == "ArrowSerializer":
199
221
  return _get_arrow_serializer()
222
+ if name == "OrjsonSerializer":
223
+ return _get_orjson_serializer()
200
224
  raise AttributeError(f"module {__name__!r} has no attribute {name!r}")
201
225
 
202
226
 
@@ -128,7 +128,7 @@ class EncryptionWrapper:
128
128
  settings = get_settings()
129
129
  if not settings.master_key:
130
130
  raise EncryptionError(
131
- "Master key required. Set REDIS_CACHE_MASTER_KEY environment variable or pass master_key parameter."
131
+ "Master key required. Set CACHEKIT_MASTER_KEY environment variable or pass master_key parameter."
132
132
  )
133
133
  try:
134
134
  master_key = bytes.fromhex(settings.master_key.get_secret_value())
@@ -14,7 +14,12 @@ from __future__ import annotations
14
14
 
15
15
  from typing import Any, ClassVar
16
16
 
17
- import orjson
17
+ # Required dependency: orjson (fail-fast with install hint when the [json] extra is absent)
18
+ try:
19
+ import orjson
20
+ except ImportError as e: # pragma: no cover - only reachable without the [json] extra (behavior tested via subprocess)
21
+ raise ImportError("orjson is not installed. OrjsonSerializer requires the [json] extra: pip install 'cachekit[json]'") from e
22
+
18
23
  import xxhash
19
24
 
20
25
  from .base import SerializationError, SerializationFormat, SerializationMetadata
File without changes
File without changes
File without changes
File without changes
File without changes