cachekit 0.7.0__tar.gz → 0.9.0__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 (94) hide show
  1. {cachekit-0.7.0 → cachekit-0.9.0}/Cargo.lock +127 -9
  2. {cachekit-0.7.0 → cachekit-0.9.0}/PKG-INFO +69 -23
  3. {cachekit-0.7.0 → cachekit-0.9.0}/README.md +67 -20
  4. {cachekit-0.7.0 → cachekit-0.9.0}/pyproject.toml +8 -5
  5. {cachekit-0.7.0 → cachekit-0.9.0}/rust/Cargo.toml +2 -2
  6. {cachekit-0.7.0 → cachekit-0.9.0}/rust/README.md +67 -20
  7. {cachekit-0.7.0 → cachekit-0.9.0}/src/cachekit/__init__.py +3 -2
  8. {cachekit-0.7.0 → cachekit-0.9.0}/src/cachekit/backends/base.py +19 -3
  9. {cachekit-0.7.0 → cachekit-0.9.0}/src/cachekit/backends/cachekitio/backend.py +10 -3
  10. {cachekit-0.7.0 → cachekit-0.9.0}/src/cachekit/backends/memcached/backend.py +22 -1
  11. {cachekit-0.7.0 → cachekit-0.9.0}/src/cachekit/backends/memcached/config.py +10 -0
  12. {cachekit-0.7.0 → cachekit-0.9.0}/src/cachekit/backends/provider.py +63 -14
  13. {cachekit-0.7.0 → cachekit-0.9.0}/src/cachekit/backends/redis/backend.py +5 -9
  14. {cachekit-0.7.0 → cachekit-0.9.0}/src/cachekit/backends/redis/client.py +2 -2
  15. {cachekit-0.7.0 → cachekit-0.9.0}/src/cachekit/backends/redis/provider.py +9 -2
  16. {cachekit-0.7.0 → cachekit-0.9.0}/src/cachekit/cache_handler.py +85 -35
  17. {cachekit-0.7.0 → cachekit-0.9.0}/src/cachekit/config/decorator.py +8 -3
  18. {cachekit-0.7.0 → cachekit-0.9.0}/src/cachekit/config/nested.py +46 -9
  19. {cachekit-0.7.0 → cachekit-0.9.0}/src/cachekit/config/settings.py +10 -1
  20. {cachekit-0.7.0 → cachekit-0.9.0}/src/cachekit/config/validation.py +3 -2
  21. {cachekit-0.7.0 → cachekit-0.9.0}/src/cachekit/decorators/intent.py +24 -1
  22. {cachekit-0.7.0 → cachekit-0.9.0}/src/cachekit/decorators/local_wrapper.py +2 -1
  23. {cachekit-0.7.0 → cachekit-0.9.0}/src/cachekit/decorators/tenant_context.py +2 -1
  24. {cachekit-0.7.0 → cachekit-0.9.0}/src/cachekit/decorators/wrapper.py +18 -11
  25. {cachekit-0.7.0 → cachekit-0.9.0}/src/cachekit/invalidation/channel.py +2 -1
  26. {cachekit-0.7.0 → cachekit-0.9.0}/src/cachekit/key_generator.py +2 -1
  27. {cachekit-0.7.0 → cachekit-0.9.0}/src/cachekit/l1_cache.py +22 -3
  28. {cachekit-0.7.0 → cachekit-0.9.0}/src/cachekit/object_cache.py +3 -2
  29. {cachekit-0.7.0 → cachekit-0.9.0}/src/cachekit/reliability/adaptive_timeout.py +10 -8
  30. {cachekit-0.7.0 → cachekit-0.9.0}/src/cachekit/reliability/circuit_breaker.py +2 -1
  31. {cachekit-0.7.0 → cachekit-0.9.0}/src/cachekit/serializers/__init__.py +2 -0
  32. cachekit-0.9.0/src/cachekit/serializers/arrow_serializer.py +319 -0
  33. {cachekit-0.7.0 → cachekit-0.9.0}/src/cachekit/serializers/auto_serializer.py +37 -9
  34. {cachekit-0.7.0 → cachekit-0.9.0}/src/cachekit/serializers/base.py +39 -1
  35. {cachekit-0.7.0 → cachekit-0.9.0}/src/cachekit/serializers/orjson_serializer.py +4 -1
  36. {cachekit-0.7.0 → cachekit-0.9.0}/src/cachekit/serializers/standard_serializer.py +4 -1
  37. cachekit-0.9.0/src/cachekit/serializers/wrapper.py +139 -0
  38. cachekit-0.7.0/src/cachekit/serializers/arrow_serializer.py +0 -247
  39. cachekit-0.7.0/src/cachekit/serializers/wrapper.py +0 -89
  40. {cachekit-0.7.0 → cachekit-0.9.0}/Cargo.toml +0 -0
  41. {cachekit-0.7.0 → cachekit-0.9.0}/LICENSE +0 -0
  42. {cachekit-0.7.0 → cachekit-0.9.0}/rust/Makefile +0 -0
  43. {cachekit-0.7.0 → cachekit-0.9.0}/rust/TEST_EXPANSION_SUMMARY.md +0 -0
  44. {cachekit-0.7.0 → cachekit-0.9.0}/rust/src/lib.rs +0 -0
  45. {cachekit-0.7.0 → cachekit-0.9.0}/rust/src/python_bindings.rs +0 -0
  46. {cachekit-0.7.0 → cachekit-0.9.0}/rust/supply-chain/audits.toml +0 -0
  47. {cachekit-0.7.0 → cachekit-0.9.0}/rust/supply-chain/config.toml +0 -0
  48. {cachekit-0.7.0 → cachekit-0.9.0}/rust/supply-chain/imports.lock +0 -0
  49. {cachekit-0.7.0 → cachekit-0.9.0}/rust/tsan_suppressions.txt +0 -0
  50. {cachekit-0.7.0 → cachekit-0.9.0}/src/cachekit/backends/__init__.py +0 -0
  51. {cachekit-0.7.0 → cachekit-0.9.0}/src/cachekit/backends/base_config.py +0 -0
  52. {cachekit-0.7.0 → cachekit-0.9.0}/src/cachekit/backends/cachekitio/__init__.py +0 -0
  53. {cachekit-0.7.0 → cachekit-0.9.0}/src/cachekit/backends/cachekitio/client.py +0 -0
  54. {cachekit-0.7.0 → cachekit-0.9.0}/src/cachekit/backends/cachekitio/config.py +0 -0
  55. {cachekit-0.7.0 → cachekit-0.9.0}/src/cachekit/backends/cachekitio/error_handler.py +0 -0
  56. {cachekit-0.7.0 → cachekit-0.9.0}/src/cachekit/backends/cachekitio/session.py +0 -0
  57. {cachekit-0.7.0 → cachekit-0.9.0}/src/cachekit/backends/errors.py +0 -0
  58. {cachekit-0.7.0 → cachekit-0.9.0}/src/cachekit/backends/file/__init__.py +0 -0
  59. {cachekit-0.7.0 → cachekit-0.9.0}/src/cachekit/backends/file/backend.py +0 -0
  60. {cachekit-0.7.0 → cachekit-0.9.0}/src/cachekit/backends/file/config.py +0 -0
  61. {cachekit-0.7.0 → cachekit-0.9.0}/src/cachekit/backends/memcached/__init__.py +0 -0
  62. {cachekit-0.7.0 → cachekit-0.9.0}/src/cachekit/backends/memcached/error_handler.py +0 -0
  63. {cachekit-0.7.0 → cachekit-0.9.0}/src/cachekit/backends/redis/__init__.py +0 -0
  64. {cachekit-0.7.0 → cachekit-0.9.0}/src/cachekit/backends/redis/config.py +0 -0
  65. {cachekit-0.7.0 → cachekit-0.9.0}/src/cachekit/backends/redis/error_handler.py +0 -0
  66. {cachekit-0.7.0 → cachekit-0.9.0}/src/cachekit/config/__init__.py +0 -0
  67. {cachekit-0.7.0 → cachekit-0.9.0}/src/cachekit/config/singleton.py +0 -0
  68. {cachekit-0.7.0 → cachekit-0.9.0}/src/cachekit/decorators/__init__.py +0 -0
  69. {cachekit-0.7.0 → cachekit-0.9.0}/src/cachekit/decorators/main.py +0 -0
  70. {cachekit-0.7.0 → cachekit-0.9.0}/src/cachekit/decorators/orchestrator.py +0 -0
  71. {cachekit-0.7.0 → cachekit-0.9.0}/src/cachekit/decorators/session.py +0 -0
  72. {cachekit-0.7.0 → cachekit-0.9.0}/src/cachekit/decorators/stats_context.py +0 -0
  73. {cachekit-0.7.0 → cachekit-0.9.0}/src/cachekit/decorators/utils/__init__.py +0 -0
  74. {cachekit-0.7.0 → cachekit-0.9.0}/src/cachekit/di.py +0 -0
  75. {cachekit-0.7.0 → cachekit-0.9.0}/src/cachekit/hash_utils.py +0 -0
  76. {cachekit-0.7.0 → cachekit-0.9.0}/src/cachekit/health.py +0 -0
  77. {cachekit-0.7.0 → cachekit-0.9.0}/src/cachekit/hiredis_compat.py +0 -0
  78. {cachekit-0.7.0 → cachekit-0.9.0}/src/cachekit/imports.py +0 -0
  79. {cachekit-0.7.0 → cachekit-0.9.0}/src/cachekit/invalidation/__init__.py +0 -0
  80. {cachekit-0.7.0 → cachekit-0.9.0}/src/cachekit/invalidation/event.py +0 -0
  81. {cachekit-0.7.0 → cachekit-0.9.0}/src/cachekit/invalidation/redis_channel.py +0 -0
  82. {cachekit-0.7.0 → cachekit-0.9.0}/src/cachekit/logging.py +0 -0
  83. {cachekit-0.7.0 → cachekit-0.9.0}/src/cachekit/monitoring/__init__.py +0 -0
  84. {cachekit-0.7.0 → cachekit-0.9.0}/src/cachekit/monitoring/correlation_tracking.py +0 -0
  85. {cachekit-0.7.0 → cachekit-0.9.0}/src/cachekit/monitoring/pool_monitor.py +0 -0
  86. {cachekit-0.7.0 → cachekit-0.9.0}/src/cachekit/monitoring/protocols.py +0 -0
  87. {cachekit-0.7.0 → cachekit-0.9.0}/src/cachekit/py.typed +0 -0
  88. {cachekit-0.7.0 → cachekit-0.9.0}/src/cachekit/reliability/__init__.py +0 -0
  89. {cachekit-0.7.0 → cachekit-0.9.0}/src/cachekit/reliability/async_metrics.py +0 -0
  90. {cachekit-0.7.0 → cachekit-0.9.0}/src/cachekit/reliability/error_classification.py +0 -0
  91. {cachekit-0.7.0 → cachekit-0.9.0}/src/cachekit/reliability/load_control.py +0 -0
  92. {cachekit-0.7.0 → cachekit-0.9.0}/src/cachekit/reliability/metrics_collection.py +0 -0
  93. {cachekit-0.7.0 → cachekit-0.9.0}/src/cachekit/reliability/profiles.py +0 -0
  94. {cachekit-0.7.0 → cachekit-0.9.0}/src/cachekit/serializers/encryption_wrapper.py +0 -0
@@ -17,6 +17,43 @@ version = "2.0.1"
17
17
  source = "registry+https://github.com/rust-lang/crates.io-index"
18
18
  checksum = "320119579fcad9c21884f5c4861d16174d0e06250625266f50fe6898340abefa"
19
19
 
20
+ [[package]]
21
+ name = "aead"
22
+ version = "0.5.2"
23
+ source = "registry+https://github.com/rust-lang/crates.io-index"
24
+ checksum = "d122413f284cf2d62fb1b7db97e02edb8cda96d769b16e443a4f6195e35662b0"
25
+ dependencies = [
26
+ "crypto-common",
27
+ "generic-array",
28
+ ]
29
+
30
+ [[package]]
31
+ name = "aes"
32
+ version = "0.8.4"
33
+ source = "registry+https://github.com/rust-lang/crates.io-index"
34
+ checksum = "b169f7a6d4742236a0a00c541b845991d0ac43e546831af1249753ab4c3aa3a0"
35
+ dependencies = [
36
+ "cfg-if",
37
+ "cipher",
38
+ "cpufeatures",
39
+ "zeroize",
40
+ ]
41
+
42
+ [[package]]
43
+ name = "aes-gcm"
44
+ version = "0.10.3"
45
+ source = "registry+https://github.com/rust-lang/crates.io-index"
46
+ checksum = "831010a0f742e1209b3bcea8fab6a8e149051ba6099432c8cb2cc117dec3ead1"
47
+ dependencies = [
48
+ "aead",
49
+ "aes",
50
+ "cipher",
51
+ "ctr",
52
+ "ghash",
53
+ "subtle",
54
+ "zeroize",
55
+ ]
56
+
20
57
  [[package]]
21
58
  name = "ahash"
22
59
  version = "0.8.12"
@@ -208,14 +245,17 @@ checksum = "1e748733b7cbc798e1434b6ac524f0c1ff2ab456fe201501e6497c8417a4fc33"
208
245
 
209
246
  [[package]]
210
247
  name = "cachekit-core"
211
- version = "0.1.1"
248
+ version = "0.2.0"
212
249
  source = "registry+https://github.com/rust-lang/crates.io-index"
213
- checksum = "3e264be91367e582a103017104f2fcc6f6f12ca59ded81f53016bc60752a94ae"
250
+ checksum = "9622b3c3e47fcf7abfde287c557e6171674e37842a2dd26fda03f63720542f17"
214
251
  dependencies = [
252
+ "aes",
253
+ "aes-gcm",
215
254
  "byteorder",
216
255
  "bytes",
217
256
  "cbindgen",
218
257
  "generic-array",
258
+ "getrandom 0.2.17",
219
259
  "hkdf",
220
260
  "hmac",
221
261
  "lz4_flex",
@@ -224,14 +264,14 @@ dependencies = [
224
264
  "serde",
225
265
  "serde_bytes",
226
266
  "sha2",
227
- "thiserror 1.0.69",
267
+ "thiserror 2.0.18",
228
268
  "xxhash-rust",
229
269
  "zeroize",
230
270
  ]
231
271
 
232
272
  [[package]]
233
273
  name = "cachekit-rs"
234
- version = "0.7.0"
274
+ version = "0.9.0"
235
275
  dependencies = [
236
276
  "cachekit-core",
237
277
  "criterion",
@@ -312,6 +352,16 @@ dependencies = [
312
352
  "half",
313
353
  ]
314
354
 
355
+ [[package]]
356
+ name = "cipher"
357
+ version = "0.4.4"
358
+ source = "registry+https://github.com/rust-lang/crates.io-index"
359
+ checksum = "773f3b9af64447d2ce9850330c473515014aa235e6a783b02db81ff39e4a3dad"
360
+ dependencies = [
361
+ "crypto-common",
362
+ "inout",
363
+ ]
364
+
315
365
  [[package]]
316
366
  name = "clap"
317
367
  version = "4.6.0"
@@ -444,6 +494,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
444
494
  checksum = "78c8292055d1c1df0cce5d180393dc8cce0abec0a7102adb6c7b1eef6016d60a"
445
495
  dependencies = [
446
496
  "generic-array",
497
+ "rand_core 0.6.4",
447
498
  "typenum",
448
499
  ]
449
500
 
@@ -463,6 +514,15 @@ version = "0.0.6"
463
514
  source = "registry+https://github.com/rust-lang/crates.io-index"
464
515
  checksum = "e2931af7e13dc045d8e9d26afccc6fa115d64e115c9c84b1166288b46f6782c2"
465
516
 
517
+ [[package]]
518
+ name = "ctr"
519
+ version = "0.9.2"
520
+ source = "registry+https://github.com/rust-lang/crates.io-index"
521
+ checksum = "0369ee1ad671834580515889b80f2ea915f23b8be8d0daa4bbaf2ac5c7590835"
522
+ dependencies = [
523
+ "cipher",
524
+ ]
525
+
466
526
  [[package]]
467
527
  name = "debugid"
468
528
  version = "0.8.0"
@@ -639,8 +699,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
639
699
  checksum = "ff2abc00be7fca6ebc474524697ae276ad847ad0a6b3faa4bcb027e9a4614ad0"
640
700
  dependencies = [
641
701
  "cfg-if",
702
+ "js-sys",
642
703
  "libc",
643
704
  "wasi",
705
+ "wasm-bindgen",
644
706
  ]
645
707
 
646
708
  [[package]]
@@ -668,6 +730,16 @@ dependencies = [
668
730
  "wasip3",
669
731
  ]
670
732
 
733
+ [[package]]
734
+ name = "ghash"
735
+ version = "0.5.1"
736
+ source = "registry+https://github.com/rust-lang/crates.io-index"
737
+ checksum = "f0d8a4362ccb29cb0b265253fb0a2728f592895ee6854fd9bc13f2ffda266ff1"
738
+ dependencies = [
739
+ "opaque-debug",
740
+ "polyval",
741
+ ]
742
+
671
743
  [[package]]
672
744
  name = "gimli"
673
745
  version = "0.32.3"
@@ -820,6 +892,15 @@ dependencies = [
820
892
  "str_stack",
821
893
  ]
822
894
 
895
+ [[package]]
896
+ name = "inout"
897
+ version = "0.1.4"
898
+ source = "registry+https://github.com/rust-lang/crates.io-index"
899
+ checksum = "879f10e63c20629ecabbb64a8010319738c66a5cd0c29b02d63d272b03751d01"
900
+ dependencies = [
901
+ "generic-array",
902
+ ]
903
+
823
904
  [[package]]
824
905
  name = "is-terminal"
825
906
  version = "0.4.17"
@@ -909,9 +990,9 @@ checksum = "5e5032e24019045c762d3c0f28f5b6b8bbf38563a65908389bf7978758920897"
909
990
 
910
991
  [[package]]
911
992
  name = "lz4_flex"
912
- version = "0.11.6"
993
+ version = "0.12.2"
913
994
  source = "registry+https://github.com/rust-lang/crates.io-index"
914
- checksum = "373f5eceeeab7925e0c1098212f2fbc4d416adec9d35051a6ab251e824c1854a"
995
+ checksum = "90071f8077f8e40adfc4b7fe9cd495ce316263f19e75c2211eeff3fdf475a3d9"
915
996
  dependencies = [
916
997
  "twox-hash",
917
998
  ]
@@ -1006,6 +1087,12 @@ version = "11.1.5"
1006
1087
  source = "registry+https://github.com/rust-lang/crates.io-index"
1007
1088
  checksum = "d6790f58c7ff633d8771f42965289203411a5e5c68388703c06e14f24770b41e"
1008
1089
 
1090
+ [[package]]
1091
+ name = "opaque-debug"
1092
+ version = "0.3.1"
1093
+ source = "registry+https://github.com/rust-lang/crates.io-index"
1094
+ checksum = "c08d65885ee38876c4f86fa503fb49d7b507c2b62552df7c70b2fce627e06381"
1095
+
1009
1096
  [[package]]
1010
1097
  name = "plotters"
1011
1098
  version = "0.3.7"
@@ -1034,6 +1121,18 @@ dependencies = [
1034
1121
  "plotters-backend",
1035
1122
  ]
1036
1123
 
1124
+ [[package]]
1125
+ name = "polyval"
1126
+ version = "0.6.2"
1127
+ source = "registry+https://github.com/rust-lang/crates.io-index"
1128
+ checksum = "9d1fe60d06143b2430aa532c94cfe9e29783047f06c0d7fd359a9a51b729fa25"
1129
+ dependencies = [
1130
+ "cfg-if",
1131
+ "cpufeatures",
1132
+ "opaque-debug",
1133
+ "universal-hash",
1134
+ ]
1135
+
1037
1136
  [[package]]
1038
1137
  name = "portable-atomic"
1039
1138
  version = "1.13.1"
@@ -1290,7 +1389,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
1290
1389
  checksum = "6db2770f06117d490610c7488547d543617b21bfa07796d7a12f6f1bd53850d1"
1291
1390
  dependencies = [
1292
1391
  "rand_chacha",
1293
- "rand_core",
1392
+ "rand_core 0.9.5",
1294
1393
  ]
1295
1394
 
1296
1395
  [[package]]
@@ -1300,7 +1399,16 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
1300
1399
  checksum = "d3022b5f1df60f26e1ffddd6c66e8aa15de382ae63b3a0c1bfc0e4d3e3f325cb"
1301
1400
  dependencies = [
1302
1401
  "ppv-lite86",
1303
- "rand_core",
1402
+ "rand_core 0.9.5",
1403
+ ]
1404
+
1405
+ [[package]]
1406
+ name = "rand_core"
1407
+ version = "0.6.4"
1408
+ source = "registry+https://github.com/rust-lang/crates.io-index"
1409
+ checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c"
1410
+ dependencies = [
1411
+ "getrandom 0.2.17",
1304
1412
  ]
1305
1413
 
1306
1414
  [[package]]
@@ -1318,7 +1426,7 @@ version = "0.4.0"
1318
1426
  source = "registry+https://github.com/rust-lang/crates.io-index"
1319
1427
  checksum = "513962919efc330f829edb2535844d1b912b0fbe2ca165d613e4e8788bb05a5a"
1320
1428
  dependencies = [
1321
- "rand_core",
1429
+ "rand_core 0.9.5",
1322
1430
  ]
1323
1431
 
1324
1432
  [[package]]
@@ -1804,6 +1912,16 @@ version = "0.2.4"
1804
1912
  source = "registry+https://github.com/rust-lang/crates.io-index"
1805
1913
  checksum = "7264e107f553ccae879d21fbea1d6724ac785e8c3bfc762137959b5802826ef3"
1806
1914
 
1915
+ [[package]]
1916
+ name = "universal-hash"
1917
+ version = "0.5.1"
1918
+ source = "registry+https://github.com/rust-lang/crates.io-index"
1919
+ checksum = "fc1de2c688dc15305988b563c3854064043356019f97a4b46276fe734c4f07ea"
1920
+ dependencies = [
1921
+ "crypto-common",
1922
+ "subtle",
1923
+ ]
1924
+
1807
1925
  [[package]]
1808
1926
  name = "untrusted"
1809
1927
  version = "0.9.0"
@@ -1,12 +1,11 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: cachekit
3
- Version: 0.7.0
3
+ Version: 0.9.0
4
4
  Classifier: Development Status :: 3 - Alpha
5
5
  Classifier: Intended Audience :: Developers
6
6
  Classifier: License :: OSI Approved :: MIT License
7
7
  Classifier: Operating System :: OS Independent
8
8
  Classifier: Programming Language :: Python :: 3
9
- Classifier: Programming Language :: Python :: 3.9
10
9
  Classifier: Programming Language :: Python :: 3.10
11
10
  Classifier: Programming Language :: Python :: 3.11
12
11
  Classifier: Programming Language :: Python :: 3.12
@@ -44,7 +43,7 @@ Home-Page: https://github.com/cachekit-io/cachekit-py
44
43
  Author-email: cachekit Contributors <noreply@cachekit.io>
45
44
  Maintainer-email: cachekit Contributors <noreply@cachekit.io>
46
45
  License: MIT
47
- Requires-Python: >=3.9
46
+ Requires-Python: >=3.10
48
47
  Description-Content-Type: text/markdown; charset=UTF-8; variant=GFM
49
48
  Project-URL: Changelog, https://github.com/cachekit-io/cachekit-py/blob/main/CHANGELOG.md
50
49
  Project-URL: Documentation, https://github.com/cachekit-io/cachekit-py#readme
@@ -119,7 +118,17 @@ Or with [uv][uv-url] (recommended):
119
118
  uv add cachekit
120
119
  ```
121
120
 
122
- ### Setup (Redis recommended default)
121
+ ### Setup (choose a backend)
122
+
123
+ cachekit exposes one decorator API over a pluggable backend abstraction. Pick the
124
+ backend that fits your infrastructure — they're peers behind the same `@cache` API:
125
+
126
+ | Backend | Best for | Select with |
127
+ |---------|----------|-------------|
128
+ | Redis | Self-hosted, full control | `REDIS_URL` / `CACHEKIT_REDIS_URL` |
129
+ | CachekitIO | Managed, zero-ops (alpha) | `CACHEKIT_API_KEY` |
130
+ | Memcached | High-throughput, existing infra | `CACHEKIT_MEMCACHED_SERVERS` |
131
+ | File / L1-only | Local dev, tests, no external deps | `CACHEKIT_FILE_CACHE_DIR` / `backend=None` |
123
132
 
124
133
  ```bash
125
134
  # Run Redis locally or use your existing infrastructure
@@ -129,7 +138,7 @@ export REDIS_URL="redis://localhost:6379"
129
138
  ```python
130
139
  from cachekit import cache
131
140
 
132
- @cache # Uses Redis backend by default
141
+ @cache # Auto-detects backend (defaults to Redis at localhost)
133
142
  def expensive_api_call(user_id: int):
134
143
  return fetch_user_data(user_id)
135
144
  ```
@@ -207,26 +216,37 @@ def get_user_profile(user_id: int):
207
216
  return db.fetch_user(user_id)
208
217
  ```
209
218
 
210
- | Feature | `@cache.minimal` | `@cache.production` | `@cache.secure` | `@cache.io()` | `@cache.local()` |
211
- |:--------|:----------------:|:-------------------:|:---------------:|:-------------:|:----------------:|
212
- | Circuit Breaker | - | ✅ | | ✅ | - |
213
- | Adaptive Timeouts | - | ✅ | | ✅ | - |
214
- | Monitoring | - | ✅ Full | Full | ✅ Full | ✅ Basic |
215
- | Integrity Checking | - | ✅ Enabled | ✅ Enforced | ✅ Enabled | - |
216
- | Encryption | - | - | Required | - | - |
217
- | Backend | Redis | Redis | Redis | CachekitIO SaaS | In-process |
218
- | **Use Case** | High throughput | Production reliability | Compliance/security | Managed cloud | Opaque objects |
219
+ | Feature | `@cache.minimal` | `@cache.dev` | `@cache.test` | `@cache.production` | `@cache.secure` |
220
+ |:--------|:----------------:|:------------:|:-------------:|:-------------------:|:---------------:|
221
+ | Circuit Breaker | - | ✅ | - | ✅ | |
222
+ | Adaptive Timeouts | - | ✅ | - | ✅ | |
223
+ | Backpressure | | ✅ | - | ✅ | ✅ |
224
+ | Integrity Checking | - | ✅ | - | ✅ | ✅ 🔒 |
225
+ | Encryption | - | - | - | - | Required |
226
+ | L1 SWR | - | | - | | |
227
+ | L1 Invalidation | - | - | - | | |
228
+ | L1 Namespace Index | - | - | - | ✅ | ✅ |
229
+ | Prometheus Metrics | - | - | - | ✅ | ✅ |
230
+ | Tracing | - | ✅ | - | ✅ | ✅ |
231
+ | Structured Logging | - | ✅ | - | ✅ | ✅ |
232
+ | **Use Case** | High throughput | Local debugging | Deterministic tests | Production reliability | Compliance/security |
233
+
234
+ > 🔒 `@cache.secure` forces `integrity_checking=True` — it cannot be overridden.
235
+ >
236
+ > **`@cache.io()`** mirrors `@cache.production` (full reliability + observability) but routes to the managed CachekitIO SaaS backend instead of Redis. **`@cache.local()`** is a separate in-process path backed by `ObjectCache` (raw object references, entry-count LRU, no serialization) — the reliability and encryption features listed above do not apply to it.
219
237
 
220
238
  <details>
221
- <summary><strong>Additional Presets</strong></summary>
239
+ <summary><strong>Additional Presets: <code>@cache.dev</code> and <code>@cache.test</code></strong></summary>
240
+
241
+ See the comparison table above for the exact feature set of each preset.
222
242
 
223
243
  ```python
224
- # Development: debugging with verbose output
244
+ # Development: verbose logging, integrity checks on, Prometheus off
225
245
  @cache.dev
226
246
  def debug_expensive_call():
227
247
  return complex_computation()
228
248
 
229
- # Testing: deterministic, no randomness
249
+ # Testing: deterministic, all protections off (no circuit breaker, no backpressure)
230
250
  @cache.test
231
251
  def test_cached_function():
232
252
  return fixed_test_value()
@@ -356,12 +376,36 @@ See [SECURITY.md][security-url] for vulnerability reporting and detailed documen
356
376
 
357
377
  </details>
358
378
 
359
- ### Built-in Monitoring
379
+ ### Monitoring & Observability
360
380
 
361
- - **Prometheus metrics** - Production-ready observability
381
+ - **Per-function statistics** - `cache_info()` on every decorated function, modelled on `functools.lru_cache`
382
+ - **Prometheus metrics** - Recorded by default (your app owns exposition)
362
383
  - **Structured logging** - Context-aware with correlation IDs
363
384
  - **Health checks** - Comprehensive status endpoints
364
- - **Performance tracking** - Built-in latency monitoring
385
+
386
+ Every decorated function exposes `cache_info()`, returning a `CacheInfo` named tuple with
387
+ hit/miss counts, the L1/L2 split, and average backend latency:
388
+
389
+ ```python
390
+ @cache()
391
+ def get_score(x):
392
+ return x ** 2
393
+
394
+ get_score(2)
395
+ get_score(2) # served from cache
396
+
397
+ info = get_score.cache_info()
398
+ # CacheInfo has 9 fields: hits, misses, l1_hits, l2_hits, maxsize,
399
+ # currsize, l2_avg_latency_ms, last_operation_at, session_id
400
+ assert info.l1_hits + info.l2_hits == info.hits # every hit is L1 or L2
401
+ ```
402
+
403
+ `maxsize` and `currsize` are always `None` (the cache lives in an external store, not a
404
+ bounded in-process dict); they exist only for `lru_cache` API parity. See the
405
+ [API Reference](docs/api-reference.md#per-function-statistics-via-cache_info) for the full
406
+ field reference and a sample stats endpoint, and the
407
+ [Prometheus Metrics guide](docs/features/prometheus-metrics.md) for metric names and
408
+ exposition setup.
365
409
 
366
410
  <details>
367
411
  <summary><strong>Thread Safety Details</strong></summary>
@@ -381,8 +425,10 @@ def expensive_func(x):
381
425
  with ThreadPoolExecutor(max_workers=10) as executor:
382
426
  results = list(executor.map(expensive_func, range(100)))
383
427
 
384
- print(expensive_func.cache_info())
385
- # CacheInfo(hits=90, misses=10, maxsize=None, currsize=10)
428
+ info = expensive_func.cache_info()
429
+ # CacheInfo(hits=..., misses=..., l1_hits=..., l2_hits=...,
430
+ # maxsize=None, currsize=None, l2_avg_latency_ms=...,
431
+ # last_operation_at=..., session_id=...)
386
432
  ```
387
433
 
388
434
  </details>
@@ -459,7 +505,7 @@ See [CONTRIBUTING.md][contributing-url] for full development guidelines.
459
505
 
460
506
  | Component | Version |
461
507
  |:----------|:--------|
462
- | Python | 3.9+ |
508
+ | Python | 3.10+ |
463
509
 
464
510
  ---
465
511
 
@@ -65,7 +65,17 @@ Or with [uv][uv-url] (recommended):
65
65
  uv add cachekit
66
66
  ```
67
67
 
68
- ### Setup (Redis recommended default)
68
+ ### Setup (choose a backend)
69
+
70
+ cachekit exposes one decorator API over a pluggable backend abstraction. Pick the
71
+ backend that fits your infrastructure — they're peers behind the same `@cache` API:
72
+
73
+ | Backend | Best for | Select with |
74
+ |---------|----------|-------------|
75
+ | Redis | Self-hosted, full control | `REDIS_URL` / `CACHEKIT_REDIS_URL` |
76
+ | CachekitIO | Managed, zero-ops (alpha) | `CACHEKIT_API_KEY` |
77
+ | Memcached | High-throughput, existing infra | `CACHEKIT_MEMCACHED_SERVERS` |
78
+ | File / L1-only | Local dev, tests, no external deps | `CACHEKIT_FILE_CACHE_DIR` / `backend=None` |
69
79
 
70
80
  ```bash
71
81
  # Run Redis locally or use your existing infrastructure
@@ -75,7 +85,7 @@ export REDIS_URL="redis://localhost:6379"
75
85
  ```python
76
86
  from cachekit import cache
77
87
 
78
- @cache # Uses Redis backend by default
88
+ @cache # Auto-detects backend (defaults to Redis at localhost)
79
89
  def expensive_api_call(user_id: int):
80
90
  return fetch_user_data(user_id)
81
91
  ```
@@ -153,26 +163,37 @@ def get_user_profile(user_id: int):
153
163
  return db.fetch_user(user_id)
154
164
  ```
155
165
 
156
- | Feature | `@cache.minimal` | `@cache.production` | `@cache.secure` | `@cache.io()` | `@cache.local()` |
157
- |:--------|:----------------:|:-------------------:|:---------------:|:-------------:|:----------------:|
158
- | Circuit Breaker | - | ✅ | | ✅ | - |
159
- | Adaptive Timeouts | - | ✅ | | ✅ | - |
160
- | Monitoring | - | ✅ Full | Full | ✅ Full | ✅ Basic |
161
- | Integrity Checking | - | ✅ Enabled | ✅ Enforced | ✅ Enabled | - |
162
- | Encryption | - | - | Required | - | - |
163
- | Backend | Redis | Redis | Redis | CachekitIO SaaS | In-process |
164
- | **Use Case** | High throughput | Production reliability | Compliance/security | Managed cloud | Opaque objects |
166
+ | Feature | `@cache.minimal` | `@cache.dev` | `@cache.test` | `@cache.production` | `@cache.secure` |
167
+ |:--------|:----------------:|:------------:|:-------------:|:-------------------:|:---------------:|
168
+ | Circuit Breaker | - | ✅ | - | ✅ | |
169
+ | Adaptive Timeouts | - | ✅ | - | ✅ | |
170
+ | Backpressure | | ✅ | - | ✅ | ✅ |
171
+ | Integrity Checking | - | ✅ | - | ✅ | ✅ 🔒 |
172
+ | Encryption | - | - | - | - | Required |
173
+ | L1 SWR | - | | - | | |
174
+ | L1 Invalidation | - | - | - | | |
175
+ | L1 Namespace Index | - | - | - | ✅ | ✅ |
176
+ | Prometheus Metrics | - | - | - | ✅ | ✅ |
177
+ | Tracing | - | ✅ | - | ✅ | ✅ |
178
+ | Structured Logging | - | ✅ | - | ✅ | ✅ |
179
+ | **Use Case** | High throughput | Local debugging | Deterministic tests | Production reliability | Compliance/security |
180
+
181
+ > 🔒 `@cache.secure` forces `integrity_checking=True` — it cannot be overridden.
182
+ >
183
+ > **`@cache.io()`** mirrors `@cache.production` (full reliability + observability) but routes to the managed CachekitIO SaaS backend instead of Redis. **`@cache.local()`** is a separate in-process path backed by `ObjectCache` (raw object references, entry-count LRU, no serialization) — the reliability and encryption features listed above do not apply to it.
165
184
 
166
185
  <details>
167
- <summary><strong>Additional Presets</strong></summary>
186
+ <summary><strong>Additional Presets: <code>@cache.dev</code> and <code>@cache.test</code></strong></summary>
187
+
188
+ See the comparison table above for the exact feature set of each preset.
168
189
 
169
190
  ```python
170
- # Development: debugging with verbose output
191
+ # Development: verbose logging, integrity checks on, Prometheus off
171
192
  @cache.dev
172
193
  def debug_expensive_call():
173
194
  return complex_computation()
174
195
 
175
- # Testing: deterministic, no randomness
196
+ # Testing: deterministic, all protections off (no circuit breaker, no backpressure)
176
197
  @cache.test
177
198
  def test_cached_function():
178
199
  return fixed_test_value()
@@ -302,12 +323,36 @@ See [SECURITY.md][security-url] for vulnerability reporting and detailed documen
302
323
 
303
324
  </details>
304
325
 
305
- ### Built-in Monitoring
326
+ ### Monitoring & Observability
306
327
 
307
- - **Prometheus metrics** - Production-ready observability
328
+ - **Per-function statistics** - `cache_info()` on every decorated function, modelled on `functools.lru_cache`
329
+ - **Prometheus metrics** - Recorded by default (your app owns exposition)
308
330
  - **Structured logging** - Context-aware with correlation IDs
309
331
  - **Health checks** - Comprehensive status endpoints
310
- - **Performance tracking** - Built-in latency monitoring
332
+
333
+ Every decorated function exposes `cache_info()`, returning a `CacheInfo` named tuple with
334
+ hit/miss counts, the L1/L2 split, and average backend latency:
335
+
336
+ ```python
337
+ @cache()
338
+ def get_score(x):
339
+ return x ** 2
340
+
341
+ get_score(2)
342
+ get_score(2) # served from cache
343
+
344
+ info = get_score.cache_info()
345
+ # CacheInfo has 9 fields: hits, misses, l1_hits, l2_hits, maxsize,
346
+ # currsize, l2_avg_latency_ms, last_operation_at, session_id
347
+ assert info.l1_hits + info.l2_hits == info.hits # every hit is L1 or L2
348
+ ```
349
+
350
+ `maxsize` and `currsize` are always `None` (the cache lives in an external store, not a
351
+ bounded in-process dict); they exist only for `lru_cache` API parity. See the
352
+ [API Reference](docs/api-reference.md#per-function-statistics-via-cache_info) for the full
353
+ field reference and a sample stats endpoint, and the
354
+ [Prometheus Metrics guide](docs/features/prometheus-metrics.md) for metric names and
355
+ exposition setup.
311
356
 
312
357
  <details>
313
358
  <summary><strong>Thread Safety Details</strong></summary>
@@ -327,8 +372,10 @@ def expensive_func(x):
327
372
  with ThreadPoolExecutor(max_workers=10) as executor:
328
373
  results = list(executor.map(expensive_func, range(100)))
329
374
 
330
- print(expensive_func.cache_info())
331
- # CacheInfo(hits=90, misses=10, maxsize=None, currsize=10)
375
+ info = expensive_func.cache_info()
376
+ # CacheInfo(hits=..., misses=..., l1_hits=..., l2_hits=...,
377
+ # maxsize=None, currsize=None, l2_avg_latency_ms=...,
378
+ # last_operation_at=..., session_id=...)
332
379
  ```
333
380
 
334
381
  </details>
@@ -405,7 +452,7 @@ See [CONTRIBUTING.md][contributing-url] for full development guidelines.
405
452
 
406
453
  | Component | Version |
407
454
  |:----------|:--------|
408
- | Python | 3.9+ |
455
+ | Python | 3.10+ |
409
456
 
410
457
  ---
411
458
 
@@ -4,7 +4,7 @@ build-backend = "maturin"
4
4
 
5
5
  [project]
6
6
  name = "cachekit"
7
- version = "0.7.0"
7
+ version = "0.9.0"
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"}
@@ -36,7 +36,6 @@ classifiers = [
36
36
  "License :: OSI Approved :: MIT License",
37
37
  "Operating System :: OS Independent",
38
38
  "Programming Language :: Python :: 3",
39
- "Programming Language :: Python :: 3.9",
40
39
  "Programming Language :: Python :: 3.10",
41
40
  "Programming Language :: Python :: 3.11",
42
41
  "Programming Language :: Python :: 3.12",
@@ -51,7 +50,7 @@ classifiers = [
51
50
  "Framework :: AsyncIO",
52
51
  "Typing :: Typed",
53
52
  ]
54
- requires-python = ">=3.9"
53
+ requires-python = ">=3.10"
55
54
  dependencies = [
56
55
  # Core Redis functionality
57
56
  "redis[hiredis]>=4.0.0",
@@ -101,7 +100,7 @@ include = ["LICENSE", "README.md"]
101
100
  # Ruff configuration
102
101
  [tool.ruff]
103
102
  line-length = 129
104
- target-version = "py39"
103
+ target-version = "py310"
105
104
 
106
105
  [tool.ruff.lint]
107
106
  select = [
@@ -237,7 +236,11 @@ fuzz = [
237
236
  # Override vulnerable transitive dependencies
238
237
  [tool.uv]
239
238
  constraint-dependencies = [
240
- "urllib3>=2.6.0",
239
+ "urllib3>=2.7.0",
241
240
  "fonttools>=4.60.2",
242
241
  "werkzeug>=3.1.4",
242
+ # pip is a dev-only transitive dep (pip-audit -> pip-api -> pip). 26.1.2 fixes
243
+ # PYSEC-2026-196 (entry-point path traversal), GHSA-58qw-9mgm-455v (tar/zip
244
+ # confusion) and GHSA-jp4c-xjxw-mgf9 (self-update import ordering).
245
+ "pip>=26.1.2",
243
246
  ]
@@ -1,6 +1,6 @@
1
1
  [package]
2
2
  name = "cachekit-rs"
3
- version = "0.7.0"
3
+ version = "0.9.0"
4
4
  edition = "2021"
5
5
  authors = ["cachekit Contributors"]
6
6
  description = "High-performance storage engine for caching with compression and encryption"
@@ -20,7 +20,7 @@ crate-type = ["cdylib", "rlib"]
20
20
 
21
21
  [dependencies]
22
22
  # Compression, checksums, encryption (https://crates.io/crates/cachekit-core)
23
- cachekit-core = { version = "=0.1.1", features = ["compression", "checksum", "messagepack", "encryption"] }
23
+ cachekit-core = { version = "0.2.0", features = ["compression", "checksum", "messagepack", "encryption"] }
24
24
 
25
25
  # Python integration - optional for Rust-only builds
26
26
  pyo3 = { workspace = true, optional = true }