cachekit 0.4.0__tar.gz → 0.6.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.
- {cachekit-0.4.0 → cachekit-0.6.1}/Cargo.lock +1 -1
- {cachekit-0.4.0 → cachekit-0.6.1}/PKG-INFO +79 -18
- {cachekit-0.4.0 → cachekit-0.6.1}/README.md +76 -17
- {cachekit-0.4.0 → cachekit-0.6.1}/pyproject.toml +9 -2
- {cachekit-0.4.0 → cachekit-0.6.1}/rust/Cargo.toml +1 -1
- {cachekit-0.4.0 → cachekit-0.6.1}/rust/README.md +76 -17
- {cachekit-0.4.0 → cachekit-0.6.1}/src/cachekit/__init__.py +14 -8
- {cachekit-0.4.0 → cachekit-0.6.1}/src/cachekit/backends/__init__.py +13 -2
- {cachekit-0.4.0 → cachekit-0.6.1}/src/cachekit/backends/cachekitio/backend.py +19 -22
- {cachekit-0.4.0 → cachekit-0.6.1}/src/cachekit/backends/cachekitio/client.py +1 -62
- cachekit-0.6.1/src/cachekit/backends/memcached/__init__.py +25 -0
- cachekit-0.6.1/src/cachekit/backends/memcached/backend.py +188 -0
- cachekit-0.6.1/src/cachekit/backends/memcached/config.py +126 -0
- cachekit-0.6.1/src/cachekit/backends/memcached/error_handler.py +88 -0
- {cachekit-0.4.0 → cachekit-0.6.1}/src/cachekit/cache_handler.py +22 -119
- {cachekit-0.4.0 → cachekit-0.6.1}/src/cachekit/config/decorator.py +2 -5
- {cachekit-0.4.0 → cachekit-0.6.1}/src/cachekit/config/validation.py +25 -22
- {cachekit-0.4.0 → cachekit-0.6.1}/src/cachekit/decorators/__init__.py +2 -3
- {cachekit-0.4.0 → cachekit-0.6.1}/src/cachekit/decorators/intent.py +33 -3
- cachekit-0.6.1/src/cachekit/decorators/local_wrapper.py +144 -0
- cachekit-0.6.1/src/cachekit/decorators/main.py +7 -0
- {cachekit-0.4.0 → cachekit-0.6.1}/src/cachekit/decorators/session.py +0 -24
- {cachekit-0.4.0 → cachekit-0.6.1}/src/cachekit/decorators/wrapper.py +75 -34
- {cachekit-0.4.0 → cachekit-0.6.1}/src/cachekit/hash_utils.py +0 -42
- {cachekit-0.4.0 → cachekit-0.6.1}/src/cachekit/key_generator.py +2 -1
- {cachekit-0.4.0 → cachekit-0.6.1}/src/cachekit/logging.py +0 -10
- cachekit-0.6.1/src/cachekit/object_cache.py +198 -0
- {cachekit-0.4.0 → cachekit-0.6.1}/src/cachekit/reliability/metrics_collection.py +0 -57
- {cachekit-0.4.0 → cachekit-0.6.1}/src/cachekit/serializers/__init__.py +1 -42
- {cachekit-0.4.0 → cachekit-0.6.1}/src/cachekit/serializers/auto_serializer.py +0 -12
- {cachekit-0.4.0 → cachekit-0.6.1}/src/cachekit/serializers/base.py +7 -7
- {cachekit-0.4.0 → cachekit-0.6.1}/src/cachekit/serializers/encryption_wrapper.py +31 -82
- {cachekit-0.4.0 → cachekit-0.6.1}/src/cachekit/serializers/orjson_serializer.py +1 -1
- cachekit-0.4.0/src/cachekit/decorators/main.py +0 -10
- {cachekit-0.4.0 → cachekit-0.6.1}/Cargo.toml +0 -0
- {cachekit-0.4.0 → cachekit-0.6.1}/LICENSE +0 -0
- {cachekit-0.4.0 → cachekit-0.6.1}/rust/Makefile +0 -0
- {cachekit-0.4.0 → cachekit-0.6.1}/rust/TEST_EXPANSION_SUMMARY.md +0 -0
- {cachekit-0.4.0 → cachekit-0.6.1}/rust/src/lib.rs +0 -0
- {cachekit-0.4.0 → cachekit-0.6.1}/rust/src/python_bindings.rs +0 -0
- {cachekit-0.4.0 → cachekit-0.6.1}/rust/supply-chain/audits.toml +0 -0
- {cachekit-0.4.0 → cachekit-0.6.1}/rust/supply-chain/config.toml +0 -0
- {cachekit-0.4.0 → cachekit-0.6.1}/rust/supply-chain/imports.lock +0 -0
- {cachekit-0.4.0 → cachekit-0.6.1}/rust/tsan_suppressions.txt +0 -0
- {cachekit-0.4.0 → cachekit-0.6.1}/src/cachekit/backends/base.py +0 -0
- {cachekit-0.4.0 → cachekit-0.6.1}/src/cachekit/backends/base_config.py +0 -0
- {cachekit-0.4.0 → cachekit-0.6.1}/src/cachekit/backends/cachekitio/__init__.py +0 -0
- {cachekit-0.4.0 → cachekit-0.6.1}/src/cachekit/backends/cachekitio/config.py +0 -0
- {cachekit-0.4.0 → cachekit-0.6.1}/src/cachekit/backends/cachekitio/error_handler.py +0 -0
- {cachekit-0.4.0 → cachekit-0.6.1}/src/cachekit/backends/cachekitio/session.py +0 -0
- {cachekit-0.4.0 → cachekit-0.6.1}/src/cachekit/backends/errors.py +0 -0
- {cachekit-0.4.0 → cachekit-0.6.1}/src/cachekit/backends/file/__init__.py +0 -0
- {cachekit-0.4.0 → cachekit-0.6.1}/src/cachekit/backends/file/backend.py +0 -0
- {cachekit-0.4.0 → cachekit-0.6.1}/src/cachekit/backends/file/config.py +0 -0
- {cachekit-0.4.0 → cachekit-0.6.1}/src/cachekit/backends/provider.py +0 -0
- {cachekit-0.4.0 → cachekit-0.6.1}/src/cachekit/backends/redis/__init__.py +0 -0
- {cachekit-0.4.0 → cachekit-0.6.1}/src/cachekit/backends/redis/backend.py +0 -0
- {cachekit-0.4.0 → cachekit-0.6.1}/src/cachekit/backends/redis/client.py +0 -0
- {cachekit-0.4.0 → cachekit-0.6.1}/src/cachekit/backends/redis/config.py +0 -0
- {cachekit-0.4.0 → cachekit-0.6.1}/src/cachekit/backends/redis/error_handler.py +0 -0
- {cachekit-0.4.0 → cachekit-0.6.1}/src/cachekit/backends/redis/provider.py +0 -0
- {cachekit-0.4.0 → cachekit-0.6.1}/src/cachekit/config/__init__.py +0 -0
- {cachekit-0.4.0 → cachekit-0.6.1}/src/cachekit/config/nested.py +0 -0
- {cachekit-0.4.0 → cachekit-0.6.1}/src/cachekit/config/settings.py +0 -0
- {cachekit-0.4.0 → cachekit-0.6.1}/src/cachekit/config/singleton.py +0 -0
- {cachekit-0.4.0 → cachekit-0.6.1}/src/cachekit/decorators/orchestrator.py +0 -0
- {cachekit-0.4.0 → cachekit-0.6.1}/src/cachekit/decorators/stats_context.py +0 -0
- {cachekit-0.4.0 → cachekit-0.6.1}/src/cachekit/decorators/tenant_context.py +0 -0
- {cachekit-0.4.0 → cachekit-0.6.1}/src/cachekit/decorators/utils/__init__.py +0 -0
- {cachekit-0.4.0 → cachekit-0.6.1}/src/cachekit/di.py +0 -0
- {cachekit-0.4.0 → cachekit-0.6.1}/src/cachekit/health.py +0 -0
- {cachekit-0.4.0 → cachekit-0.6.1}/src/cachekit/hiredis_compat.py +0 -0
- {cachekit-0.4.0 → cachekit-0.6.1}/src/cachekit/imports.py +0 -0
- {cachekit-0.4.0 → cachekit-0.6.1}/src/cachekit/invalidation/__init__.py +0 -0
- {cachekit-0.4.0 → cachekit-0.6.1}/src/cachekit/invalidation/channel.py +0 -0
- {cachekit-0.4.0 → cachekit-0.6.1}/src/cachekit/invalidation/event.py +0 -0
- {cachekit-0.4.0 → cachekit-0.6.1}/src/cachekit/invalidation/redis_channel.py +0 -0
- {cachekit-0.4.0 → cachekit-0.6.1}/src/cachekit/l1_cache.py +0 -0
- {cachekit-0.4.0 → cachekit-0.6.1}/src/cachekit/monitoring/__init__.py +0 -0
- {cachekit-0.4.0 → cachekit-0.6.1}/src/cachekit/monitoring/correlation_tracking.py +0 -0
- {cachekit-0.4.0 → cachekit-0.6.1}/src/cachekit/monitoring/pool_monitor.py +0 -0
- {cachekit-0.4.0 → cachekit-0.6.1}/src/cachekit/monitoring/protocols.py +0 -0
- {cachekit-0.4.0 → cachekit-0.6.1}/src/cachekit/py.typed +0 -0
- {cachekit-0.4.0 → cachekit-0.6.1}/src/cachekit/reliability/__init__.py +0 -0
- {cachekit-0.4.0 → cachekit-0.6.1}/src/cachekit/reliability/adaptive_timeout.py +0 -0
- {cachekit-0.4.0 → cachekit-0.6.1}/src/cachekit/reliability/async_metrics.py +0 -0
- {cachekit-0.4.0 → cachekit-0.6.1}/src/cachekit/reliability/circuit_breaker.py +0 -0
- {cachekit-0.4.0 → cachekit-0.6.1}/src/cachekit/reliability/error_classification.py +0 -0
- {cachekit-0.4.0 → cachekit-0.6.1}/src/cachekit/reliability/load_control.py +0 -0
- {cachekit-0.4.0 → cachekit-0.6.1}/src/cachekit/reliability/profiles.py +0 -0
- {cachekit-0.4.0 → cachekit-0.6.1}/src/cachekit/serializers/arrow_serializer.py +0 -0
- {cachekit-0.4.0 → cachekit-0.6.1}/src/cachekit/serializers/standard_serializer.py +0 -0
- {cachekit-0.4.0 → cachekit-0.6.1}/src/cachekit/serializers/wrapper.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: cachekit
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.6.1
|
|
4
4
|
Classifier: Development Status :: 3 - Alpha
|
|
5
5
|
Classifier: Intended Audience :: Developers
|
|
6
6
|
Classifier: License :: OSI Approved :: MIT License
|
|
@@ -34,7 +34,9 @@ Requires-Dist: httpx[http2]>=0.28.1
|
|
|
34
34
|
Requires-Dist: numpy>=2.0.2 ; extra == 'data'
|
|
35
35
|
Requires-Dist: pandas>=1.3.0 ; extra == 'data'
|
|
36
36
|
Requires-Dist: pyarrow>=21.0.0 ; extra == 'data'
|
|
37
|
+
Requires-Dist: pymemcache>=4.0.0 ; extra == 'memcached'
|
|
37
38
|
Provides-Extra: data
|
|
39
|
+
Provides-Extra: memcached
|
|
38
40
|
License-File: LICENSE
|
|
39
41
|
Summary: Production-ready Redis caching for Python with intelligent reliability features and Rust-powered performance
|
|
40
42
|
Keywords: redis,cache,caching,decorator,rust,performance,reliability,production,encryption,security,circuit-breaker,prometheus,messagepack,distributed-locking
|
|
@@ -54,9 +56,9 @@ Project-URL: Repository, https://github.com/cachekit-io/cachekit-py.git
|
|
|
54
56
|
|
|
55
57
|
# cachekit
|
|
56
58
|
|
|
57
|
-
> **
|
|
59
|
+
> **Python caching, batteries included**
|
|
58
60
|
|
|
59
|
-
Production-ready
|
|
61
|
+
Production-ready caching for Python with intelligent reliability features and Rust-powered performance.
|
|
60
62
|
|
|
61
63
|
[![PyPI Version][pypi-badge]][pypi-url]
|
|
62
64
|
[![Python Versions][python-badge]][pypi-url]
|
|
@@ -117,7 +119,7 @@ Or with [uv][uv-url] (recommended):
|
|
|
117
119
|
uv add cachekit
|
|
118
120
|
```
|
|
119
121
|
|
|
120
|
-
### Setup
|
|
122
|
+
### Setup (Redis — recommended default)
|
|
121
123
|
|
|
122
124
|
```bash
|
|
123
125
|
# Run Redis locally or use your existing infrastructure
|
|
@@ -135,6 +137,53 @@ def expensive_api_call(user_id: int):
|
|
|
135
137
|
> [!TIP]
|
|
136
138
|
> No Redis? No worries! Use `@cache(backend=None)` for L1-only in-memory caching, like `lru_cache`, but with all the bells and whistles.
|
|
137
139
|
|
|
140
|
+
### More Backends
|
|
141
|
+
|
|
142
|
+
<details>
|
|
143
|
+
<summary><strong>CachekitIO — Managed SaaS (Alpha)</strong></summary>
|
|
144
|
+
|
|
145
|
+
```python notest
|
|
146
|
+
import os
|
|
147
|
+
from cachekit import cache
|
|
148
|
+
|
|
149
|
+
# Set your CachekitIO API key
|
|
150
|
+
# export CACHEKIT_API_KEY="your-api-key" # pragma: allowlist secret
|
|
151
|
+
|
|
152
|
+
@cache.io() # Uses CachekitIO SaaS backend — no Redis to manage
|
|
153
|
+
def expensive_api_call(user_id: int):
|
|
154
|
+
return fetch_user_data(user_id)
|
|
155
|
+
```
|
|
156
|
+
|
|
157
|
+
*cachekit.io is in closed alpha — [request access](https://cachekit.io) to get started.*
|
|
158
|
+
|
|
159
|
+
</details>
|
|
160
|
+
|
|
161
|
+
<details>
|
|
162
|
+
<summary><strong>Memcached — Optional</strong></summary>
|
|
163
|
+
|
|
164
|
+
```python notest
|
|
165
|
+
from cachekit import cache
|
|
166
|
+
from cachekit.backends.memcached import MemcachedBackend
|
|
167
|
+
|
|
168
|
+
# pip install cachekit[memcached]
|
|
169
|
+
|
|
170
|
+
backend = MemcachedBackend() # Defaults to 127.0.0.1:11211
|
|
171
|
+
|
|
172
|
+
@cache(backend=backend)
|
|
173
|
+
def expensive_api_call(user_id: int):
|
|
174
|
+
return fetch_user_data(user_id)
|
|
175
|
+
```
|
|
176
|
+
|
|
177
|
+
*Requires: `pip install cachekit[memcached]` or `uv add cachekit[memcached]`*
|
|
178
|
+
|
|
179
|
+
</details>
|
|
180
|
+
|
|
181
|
+
---
|
|
182
|
+
|
|
183
|
+
> **CachekitIO Cloud (Alpha)**
|
|
184
|
+
> Managed caching with zero infrastructure. L1+L2 caching, circuit breaker, and automatic failover — no Redis to manage.
|
|
185
|
+
> *cachekit.io is in closed alpha — [request access](https://cachekit.io) to get started.*
|
|
186
|
+
|
|
138
187
|
---
|
|
139
188
|
|
|
140
189
|
## Intent-Based Optimization
|
|
@@ -158,14 +207,15 @@ def get_user_profile(user_id: int):
|
|
|
158
207
|
return db.fetch_user(user_id)
|
|
159
208
|
```
|
|
160
209
|
|
|
161
|
-
| Feature | `@cache.minimal` | `@cache.production` | `@cache.secure` |
|
|
162
|
-
|
|
163
|
-
| Circuit Breaker | - | ✅ | ✅ |
|
|
164
|
-
| Adaptive Timeouts | - | ✅ | ✅ |
|
|
165
|
-
| Monitoring | - | ✅ Full | ✅ Full |
|
|
166
|
-
| Integrity Checking | - | ✅ Enabled | ✅ Enforced |
|
|
167
|
-
| Encryption | - | - | ✅ Required |
|
|
168
|
-
|
|
|
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 |
|
|
169
219
|
|
|
170
220
|
<details>
|
|
171
221
|
<summary><strong>Additional Presets</strong></summary>
|
|
@@ -198,8 +248,9 @@ def test_cached_function():
|
|
|
198
248
|
│ │ Breaker │ │ Timeouts │ │ Locking │ │
|
|
199
249
|
│ └─────────────┘ └─────────────┘ └─────────────────────┘ │
|
|
200
250
|
├─────────────────────────────────────────────────────────────┤
|
|
201
|
-
│ L1 Cache (In-Memory) │ L2 Cache (
|
|
202
|
-
│ ~50ns │
|
|
251
|
+
│ L1 Cache (In-Memory) │ L2 Cache (Pluggable Backend) │
|
|
252
|
+
│ ~50ns │ Redis / CachekitIO / File / │
|
|
253
|
+
│ │ Memcached ~2-50ms │
|
|
203
254
|
├─────────────────────────────────────────────────────────────┤
|
|
204
255
|
│ Rust Core (PyO3) │
|
|
205
256
|
│ ┌─────────────┐ ┌─────────────┐ ┌─────────────────────┐ │
|
|
@@ -221,7 +272,7 @@ def test_cached_function():
|
|
|
221
272
|
- Circuit breaker with graceful degradation
|
|
222
273
|
- Connection pooling with thread affinity (+28% throughput)
|
|
223
274
|
- Distributed locking prevents cache stampedes
|
|
224
|
-
- Pluggable backend abstraction (Redis,
|
|
275
|
+
- Pluggable backend abstraction (Redis, CachekitIO, File, Memcached, custom)
|
|
225
276
|
|
|
226
277
|
> [!NOTE]
|
|
227
278
|
> All reliability features are **enabled by default** with `@cache.production`. Use `@cache.minimal` to disable them for maximum throughput.
|
|
@@ -230,7 +281,7 @@ def test_cached_function():
|
|
|
230
281
|
|
|
231
282
|
| Serializer | Speed | Use Case |
|
|
232
283
|
|:-----------|:-----:|:---------|
|
|
233
|
-
| **
|
|
284
|
+
| **StandardSerializer** | ★★★★☆ | General Python types, NumPy, Pandas |
|
|
234
285
|
| **OrjsonSerializer** | ★★★★★ | JSON APIs (2-5x faster than stdlib) |
|
|
235
286
|
| **ArrowSerializer** | ★★★★★ | Large DataFrames (6-23x faster for 10K+ rows) |
|
|
236
287
|
| **EncryptionWrapper** | ★★★★☆ | Wraps any serializer with AES-256-GCM |
|
|
@@ -352,7 +403,7 @@ print(expensive_func.cache_info())
|
|
|
352
403
|
|
|
353
404
|
| Feature | Description |
|
|
354
405
|
|:--------|:------------|
|
|
355
|
-
| [Serializer Guide][serializer-guide-url] | ArrowSerializer vs
|
|
406
|
+
| [Serializer Guide][serializer-guide-url] | ArrowSerializer vs StandardSerializer benchmarks |
|
|
356
407
|
| [Circuit Breaker][circuit-breaker-url] | Prevent cascading failures |
|
|
357
408
|
| [Distributed Locking][distributed-locking-url] | Cache stampede prevention |
|
|
358
409
|
| [Prometheus Metrics][prometheus-url] | Built-in observability |
|
|
@@ -370,6 +421,16 @@ print(expensive_func.cache_info())
|
|
|
370
421
|
CACHEKIT_REDIS_URL="redis://localhost:6379" # Primary (preferred)
|
|
371
422
|
REDIS_URL="redis://localhost:6379" # Fallback
|
|
372
423
|
|
|
424
|
+
# CachekitIO SaaS Backend (closed alpha — request access at cachekit.io)
|
|
425
|
+
CACHEKIT_API_KEY="your-api-key" # Required for @cache.io() # pragma: allowlist secret
|
|
426
|
+
CACHEKIT_API_URL="https://api.cachekit.io" # Default SaaS endpoint
|
|
427
|
+
|
|
428
|
+
# Memcached Backend (optional: pip install cachekit[memcached])
|
|
429
|
+
CACHEKIT_MEMCACHED_SERVERS='["mc1:11211", "mc2:11211"]' # Default: 127.0.0.1:11211
|
|
430
|
+
CACHEKIT_MEMCACHED_CONNECT_TIMEOUT=2.0 # Default: 2.0 seconds
|
|
431
|
+
CACHEKIT_MEMCACHED_TIMEOUT=1.0 # Default: 1.0 seconds
|
|
432
|
+
CACHEKIT_MEMCACHED_KEY_PREFIX="myapp:" # Default: "" (none)
|
|
433
|
+
|
|
373
434
|
# Optional Configuration
|
|
374
435
|
CACHEKIT_DEFAULT_TTL=3600
|
|
375
436
|
CACHEKIT_MAX_CHUNK_SIZE_MB=100
|
|
@@ -425,7 +486,7 @@ MIT License - see [LICENSE][license-file-url] for details.
|
|
|
425
486
|
[comparison-url]: docs/comparison.md
|
|
426
487
|
[getting-started-url]: docs/getting-started.md
|
|
427
488
|
[api-reference-url]: docs/api-reference.md
|
|
428
|
-
[serializer-guide-url]: docs/
|
|
489
|
+
[serializer-guide-url]: docs/serializers/index.md
|
|
429
490
|
[circuit-breaker-url]: docs/features/circuit-breaker.md
|
|
430
491
|
[distributed-locking-url]: docs/features/distributed-locking.md
|
|
431
492
|
[prometheus-url]: docs/features/prometheus-metrics.md
|
|
@@ -2,9 +2,9 @@
|
|
|
2
2
|
|
|
3
3
|
# cachekit
|
|
4
4
|
|
|
5
|
-
> **
|
|
5
|
+
> **Python caching, batteries included**
|
|
6
6
|
|
|
7
|
-
Production-ready
|
|
7
|
+
Production-ready caching for Python with intelligent reliability features and Rust-powered performance.
|
|
8
8
|
|
|
9
9
|
[![PyPI Version][pypi-badge]][pypi-url]
|
|
10
10
|
[![Python Versions][python-badge]][pypi-url]
|
|
@@ -65,7 +65,7 @@ Or with [uv][uv-url] (recommended):
|
|
|
65
65
|
uv add cachekit
|
|
66
66
|
```
|
|
67
67
|
|
|
68
|
-
### Setup
|
|
68
|
+
### Setup (Redis — recommended default)
|
|
69
69
|
|
|
70
70
|
```bash
|
|
71
71
|
# Run Redis locally or use your existing infrastructure
|
|
@@ -83,6 +83,53 @@ def expensive_api_call(user_id: int):
|
|
|
83
83
|
> [!TIP]
|
|
84
84
|
> No Redis? No worries! Use `@cache(backend=None)` for L1-only in-memory caching, like `lru_cache`, but with all the bells and whistles.
|
|
85
85
|
|
|
86
|
+
### More Backends
|
|
87
|
+
|
|
88
|
+
<details>
|
|
89
|
+
<summary><strong>CachekitIO — Managed SaaS (Alpha)</strong></summary>
|
|
90
|
+
|
|
91
|
+
```python notest
|
|
92
|
+
import os
|
|
93
|
+
from cachekit import cache
|
|
94
|
+
|
|
95
|
+
# Set your CachekitIO API key
|
|
96
|
+
# export CACHEKIT_API_KEY="your-api-key" # pragma: allowlist secret
|
|
97
|
+
|
|
98
|
+
@cache.io() # Uses CachekitIO SaaS backend — no Redis to manage
|
|
99
|
+
def expensive_api_call(user_id: int):
|
|
100
|
+
return fetch_user_data(user_id)
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
*cachekit.io is in closed alpha — [request access](https://cachekit.io) to get started.*
|
|
104
|
+
|
|
105
|
+
</details>
|
|
106
|
+
|
|
107
|
+
<details>
|
|
108
|
+
<summary><strong>Memcached — Optional</strong></summary>
|
|
109
|
+
|
|
110
|
+
```python notest
|
|
111
|
+
from cachekit import cache
|
|
112
|
+
from cachekit.backends.memcached import MemcachedBackend
|
|
113
|
+
|
|
114
|
+
# pip install cachekit[memcached]
|
|
115
|
+
|
|
116
|
+
backend = MemcachedBackend() # Defaults to 127.0.0.1:11211
|
|
117
|
+
|
|
118
|
+
@cache(backend=backend)
|
|
119
|
+
def expensive_api_call(user_id: int):
|
|
120
|
+
return fetch_user_data(user_id)
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
*Requires: `pip install cachekit[memcached]` or `uv add cachekit[memcached]`*
|
|
124
|
+
|
|
125
|
+
</details>
|
|
126
|
+
|
|
127
|
+
---
|
|
128
|
+
|
|
129
|
+
> **CachekitIO Cloud (Alpha)**
|
|
130
|
+
> Managed caching with zero infrastructure. L1+L2 caching, circuit breaker, and automatic failover — no Redis to manage.
|
|
131
|
+
> *cachekit.io is in closed alpha — [request access](https://cachekit.io) to get started.*
|
|
132
|
+
|
|
86
133
|
---
|
|
87
134
|
|
|
88
135
|
## Intent-Based Optimization
|
|
@@ -106,14 +153,15 @@ def get_user_profile(user_id: int):
|
|
|
106
153
|
return db.fetch_user(user_id)
|
|
107
154
|
```
|
|
108
155
|
|
|
109
|
-
| Feature | `@cache.minimal` | `@cache.production` | `@cache.secure` |
|
|
110
|
-
|
|
111
|
-
| Circuit Breaker | - | ✅ | ✅ |
|
|
112
|
-
| Adaptive Timeouts | - | ✅ | ✅ |
|
|
113
|
-
| Monitoring | - | ✅ Full | ✅ Full |
|
|
114
|
-
| Integrity Checking | - | ✅ Enabled | ✅ Enforced |
|
|
115
|
-
| Encryption | - | - | ✅ Required |
|
|
116
|
-
|
|
|
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 |
|
|
117
165
|
|
|
118
166
|
<details>
|
|
119
167
|
<summary><strong>Additional Presets</strong></summary>
|
|
@@ -146,8 +194,9 @@ def test_cached_function():
|
|
|
146
194
|
│ │ Breaker │ │ Timeouts │ │ Locking │ │
|
|
147
195
|
│ └─────────────┘ └─────────────┘ └─────────────────────┘ │
|
|
148
196
|
├─────────────────────────────────────────────────────────────┤
|
|
149
|
-
│ L1 Cache (In-Memory) │ L2 Cache (
|
|
150
|
-
│ ~50ns │
|
|
197
|
+
│ L1 Cache (In-Memory) │ L2 Cache (Pluggable Backend) │
|
|
198
|
+
│ ~50ns │ Redis / CachekitIO / File / │
|
|
199
|
+
│ │ Memcached ~2-50ms │
|
|
151
200
|
├─────────────────────────────────────────────────────────────┤
|
|
152
201
|
│ Rust Core (PyO3) │
|
|
153
202
|
│ ┌─────────────┐ ┌─────────────┐ ┌─────────────────────┐ │
|
|
@@ -169,7 +218,7 @@ def test_cached_function():
|
|
|
169
218
|
- Circuit breaker with graceful degradation
|
|
170
219
|
- Connection pooling with thread affinity (+28% throughput)
|
|
171
220
|
- Distributed locking prevents cache stampedes
|
|
172
|
-
- Pluggable backend abstraction (Redis,
|
|
221
|
+
- Pluggable backend abstraction (Redis, CachekitIO, File, Memcached, custom)
|
|
173
222
|
|
|
174
223
|
> [!NOTE]
|
|
175
224
|
> All reliability features are **enabled by default** with `@cache.production`. Use `@cache.minimal` to disable them for maximum throughput.
|
|
@@ -178,7 +227,7 @@ def test_cached_function():
|
|
|
178
227
|
|
|
179
228
|
| Serializer | Speed | Use Case |
|
|
180
229
|
|:-----------|:-----:|:---------|
|
|
181
|
-
| **
|
|
230
|
+
| **StandardSerializer** | ★★★★☆ | General Python types, NumPy, Pandas |
|
|
182
231
|
| **OrjsonSerializer** | ★★★★★ | JSON APIs (2-5x faster than stdlib) |
|
|
183
232
|
| **ArrowSerializer** | ★★★★★ | Large DataFrames (6-23x faster for 10K+ rows) |
|
|
184
233
|
| **EncryptionWrapper** | ★★★★☆ | Wraps any serializer with AES-256-GCM |
|
|
@@ -300,7 +349,7 @@ print(expensive_func.cache_info())
|
|
|
300
349
|
|
|
301
350
|
| Feature | Description |
|
|
302
351
|
|:--------|:------------|
|
|
303
|
-
| [Serializer Guide][serializer-guide-url] | ArrowSerializer vs
|
|
352
|
+
| [Serializer Guide][serializer-guide-url] | ArrowSerializer vs StandardSerializer benchmarks |
|
|
304
353
|
| [Circuit Breaker][circuit-breaker-url] | Prevent cascading failures |
|
|
305
354
|
| [Distributed Locking][distributed-locking-url] | Cache stampede prevention |
|
|
306
355
|
| [Prometheus Metrics][prometheus-url] | Built-in observability |
|
|
@@ -318,6 +367,16 @@ print(expensive_func.cache_info())
|
|
|
318
367
|
CACHEKIT_REDIS_URL="redis://localhost:6379" # Primary (preferred)
|
|
319
368
|
REDIS_URL="redis://localhost:6379" # Fallback
|
|
320
369
|
|
|
370
|
+
# CachekitIO SaaS Backend (closed alpha — request access at cachekit.io)
|
|
371
|
+
CACHEKIT_API_KEY="your-api-key" # Required for @cache.io() # pragma: allowlist secret
|
|
372
|
+
CACHEKIT_API_URL="https://api.cachekit.io" # Default SaaS endpoint
|
|
373
|
+
|
|
374
|
+
# Memcached Backend (optional: pip install cachekit[memcached])
|
|
375
|
+
CACHEKIT_MEMCACHED_SERVERS='["mc1:11211", "mc2:11211"]' # Default: 127.0.0.1:11211
|
|
376
|
+
CACHEKIT_MEMCACHED_CONNECT_TIMEOUT=2.0 # Default: 2.0 seconds
|
|
377
|
+
CACHEKIT_MEMCACHED_TIMEOUT=1.0 # Default: 1.0 seconds
|
|
378
|
+
CACHEKIT_MEMCACHED_KEY_PREFIX="myapp:" # Default: "" (none)
|
|
379
|
+
|
|
321
380
|
# Optional Configuration
|
|
322
381
|
CACHEKIT_DEFAULT_TTL=3600
|
|
323
382
|
CACHEKIT_MAX_CHUNK_SIZE_MB=100
|
|
@@ -373,7 +432,7 @@ MIT License - see [LICENSE][license-file-url] for details.
|
|
|
373
432
|
[comparison-url]: docs/comparison.md
|
|
374
433
|
[getting-started-url]: docs/getting-started.md
|
|
375
434
|
[api-reference-url]: docs/api-reference.md
|
|
376
|
-
[serializer-guide-url]: docs/
|
|
435
|
+
[serializer-guide-url]: docs/serializers/index.md
|
|
377
436
|
[circuit-breaker-url]: docs/features/circuit-breaker.md
|
|
378
437
|
[distributed-locking-url]: docs/features/distributed-locking.md
|
|
379
438
|
[prometheus-url]: docs/features/prometheus-metrics.md
|
|
@@ -4,7 +4,7 @@ build-backend = "maturin"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "cachekit"
|
|
7
|
-
version = "0.
|
|
7
|
+
version = "0.6.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"}
|
|
@@ -79,6 +79,9 @@ data = [
|
|
|
79
79
|
"pandas>=1.3.0",
|
|
80
80
|
"pyarrow>=21.0.0",
|
|
81
81
|
]
|
|
82
|
+
memcached = [
|
|
83
|
+
"pymemcache>=4.0.0",
|
|
84
|
+
]
|
|
82
85
|
|
|
83
86
|
[project.urls]
|
|
84
87
|
Homepage = "https://github.com/cachekit-io/cachekit-py"
|
|
@@ -126,7 +129,7 @@ ignore = [
|
|
|
126
129
|
"src/cachekit/monitoring/pool_monitor.py" = ["S110"] # Monitoring errors should be silent
|
|
127
130
|
"src/cachekit/reliability/async_metrics.py" = ["S101"] # Internal invariant checks
|
|
128
131
|
"src/cachekit/serializers/__init__.py" = ["S101"] # Module-level validation
|
|
129
|
-
"src/cachekit/serializers/
|
|
132
|
+
"src/cachekit/serializers/standard_serializer.py" = ["S110"] # Fallback deserialization patterns
|
|
130
133
|
|
|
131
134
|
[tool.ruff.lint.isort]
|
|
132
135
|
known-first-party = ["cachekit"]
|
|
@@ -205,6 +208,7 @@ dev = [
|
|
|
205
208
|
"pytest-cov>=7.0.0",
|
|
206
209
|
"pytest-markdown-docs>=0.6.0",
|
|
207
210
|
"pytest-redis>=3.0.0",
|
|
211
|
+
"pymemcache>=4.0.0",
|
|
208
212
|
# Code quality
|
|
209
213
|
"basedpyright>=1.32.1",
|
|
210
214
|
"ruff>=0.6.0",
|
|
@@ -214,6 +218,7 @@ dev = [
|
|
|
214
218
|
"httpx>=0.28.1",
|
|
215
219
|
"hypothesis>=6.0.0",
|
|
216
220
|
"pip-audit>=2.7.0",
|
|
221
|
+
"requests>=2.33.0; python_version >= '3.10'",
|
|
217
222
|
"psutil>=5.9.0",
|
|
218
223
|
"python-dotenv>=1.0.0",
|
|
219
224
|
"pyyaml>=6.0.3",
|
|
@@ -221,6 +226,8 @@ dev = [
|
|
|
221
226
|
"numpy>=2.0.2",
|
|
222
227
|
"pandas>=1.3.0",
|
|
223
228
|
"pyarrow>=21.0.0",
|
|
229
|
+
"pytest-xdist>=3.8.0",
|
|
230
|
+
"time-machine>=2.19.0",
|
|
224
231
|
]
|
|
225
232
|
# Linux CI only - Atheris requires libFuzzer (not available on macOS without building LLVM)
|
|
226
233
|
fuzz = [
|
|
@@ -2,9 +2,9 @@
|
|
|
2
2
|
|
|
3
3
|
# cachekit
|
|
4
4
|
|
|
5
|
-
> **
|
|
5
|
+
> **Python caching, batteries included**
|
|
6
6
|
|
|
7
|
-
Production-ready
|
|
7
|
+
Production-ready caching for Python with intelligent reliability features and Rust-powered performance.
|
|
8
8
|
|
|
9
9
|
[![PyPI Version][pypi-badge]][pypi-url]
|
|
10
10
|
[![Python Versions][python-badge]][pypi-url]
|
|
@@ -65,7 +65,7 @@ Or with [uv][uv-url] (recommended):
|
|
|
65
65
|
uv add cachekit
|
|
66
66
|
```
|
|
67
67
|
|
|
68
|
-
### Setup
|
|
68
|
+
### Setup (Redis — recommended default)
|
|
69
69
|
|
|
70
70
|
```bash
|
|
71
71
|
# Run Redis locally or use your existing infrastructure
|
|
@@ -83,6 +83,53 @@ def expensive_api_call(user_id: int):
|
|
|
83
83
|
> [!TIP]
|
|
84
84
|
> No Redis? No worries! Use `@cache(backend=None)` for L1-only in-memory caching, like `lru_cache`, but with all the bells and whistles.
|
|
85
85
|
|
|
86
|
+
### More Backends
|
|
87
|
+
|
|
88
|
+
<details>
|
|
89
|
+
<summary><strong>CachekitIO — Managed SaaS (Alpha)</strong></summary>
|
|
90
|
+
|
|
91
|
+
```python notest
|
|
92
|
+
import os
|
|
93
|
+
from cachekit import cache
|
|
94
|
+
|
|
95
|
+
# Set your CachekitIO API key
|
|
96
|
+
# export CACHEKIT_API_KEY="your-api-key" # pragma: allowlist secret
|
|
97
|
+
|
|
98
|
+
@cache.io() # Uses CachekitIO SaaS backend — no Redis to manage
|
|
99
|
+
def expensive_api_call(user_id: int):
|
|
100
|
+
return fetch_user_data(user_id)
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
*cachekit.io is in closed alpha — [request access](https://cachekit.io) to get started.*
|
|
104
|
+
|
|
105
|
+
</details>
|
|
106
|
+
|
|
107
|
+
<details>
|
|
108
|
+
<summary><strong>Memcached — Optional</strong></summary>
|
|
109
|
+
|
|
110
|
+
```python notest
|
|
111
|
+
from cachekit import cache
|
|
112
|
+
from cachekit.backends.memcached import MemcachedBackend
|
|
113
|
+
|
|
114
|
+
# pip install cachekit[memcached]
|
|
115
|
+
|
|
116
|
+
backend = MemcachedBackend() # Defaults to 127.0.0.1:11211
|
|
117
|
+
|
|
118
|
+
@cache(backend=backend)
|
|
119
|
+
def expensive_api_call(user_id: int):
|
|
120
|
+
return fetch_user_data(user_id)
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
*Requires: `pip install cachekit[memcached]` or `uv add cachekit[memcached]`*
|
|
124
|
+
|
|
125
|
+
</details>
|
|
126
|
+
|
|
127
|
+
---
|
|
128
|
+
|
|
129
|
+
> **CachekitIO Cloud (Alpha)**
|
|
130
|
+
> Managed caching with zero infrastructure. L1+L2 caching, circuit breaker, and automatic failover — no Redis to manage.
|
|
131
|
+
> *cachekit.io is in closed alpha — [request access](https://cachekit.io) to get started.*
|
|
132
|
+
|
|
86
133
|
---
|
|
87
134
|
|
|
88
135
|
## Intent-Based Optimization
|
|
@@ -106,14 +153,15 @@ def get_user_profile(user_id: int):
|
|
|
106
153
|
return db.fetch_user(user_id)
|
|
107
154
|
```
|
|
108
155
|
|
|
109
|
-
| Feature | `@cache.minimal` | `@cache.production` | `@cache.secure` |
|
|
110
|
-
|
|
111
|
-
| Circuit Breaker | - | ✅ | ✅ |
|
|
112
|
-
| Adaptive Timeouts | - | ✅ | ✅ |
|
|
113
|
-
| Monitoring | - | ✅ Full | ✅ Full |
|
|
114
|
-
| Integrity Checking | - | ✅ Enabled | ✅ Enforced |
|
|
115
|
-
| Encryption | - | - | ✅ Required |
|
|
116
|
-
|
|
|
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 |
|
|
117
165
|
|
|
118
166
|
<details>
|
|
119
167
|
<summary><strong>Additional Presets</strong></summary>
|
|
@@ -146,8 +194,9 @@ def test_cached_function():
|
|
|
146
194
|
│ │ Breaker │ │ Timeouts │ │ Locking │ │
|
|
147
195
|
│ └─────────────┘ └─────────────┘ └─────────────────────┘ │
|
|
148
196
|
├─────────────────────────────────────────────────────────────┤
|
|
149
|
-
│ L1 Cache (In-Memory) │ L2 Cache (
|
|
150
|
-
│ ~50ns │
|
|
197
|
+
│ L1 Cache (In-Memory) │ L2 Cache (Pluggable Backend) │
|
|
198
|
+
│ ~50ns │ Redis / CachekitIO / File / │
|
|
199
|
+
│ │ Memcached ~2-50ms │
|
|
151
200
|
├─────────────────────────────────────────────────────────────┤
|
|
152
201
|
│ Rust Core (PyO3) │
|
|
153
202
|
│ ┌─────────────┐ ┌─────────────┐ ┌─────────────────────┐ │
|
|
@@ -169,7 +218,7 @@ def test_cached_function():
|
|
|
169
218
|
- Circuit breaker with graceful degradation
|
|
170
219
|
- Connection pooling with thread affinity (+28% throughput)
|
|
171
220
|
- Distributed locking prevents cache stampedes
|
|
172
|
-
- Pluggable backend abstraction (Redis,
|
|
221
|
+
- Pluggable backend abstraction (Redis, CachekitIO, File, Memcached, custom)
|
|
173
222
|
|
|
174
223
|
> [!NOTE]
|
|
175
224
|
> All reliability features are **enabled by default** with `@cache.production`. Use `@cache.minimal` to disable them for maximum throughput.
|
|
@@ -178,7 +227,7 @@ def test_cached_function():
|
|
|
178
227
|
|
|
179
228
|
| Serializer | Speed | Use Case |
|
|
180
229
|
|:-----------|:-----:|:---------|
|
|
181
|
-
| **
|
|
230
|
+
| **StandardSerializer** | ★★★★☆ | General Python types, NumPy, Pandas |
|
|
182
231
|
| **OrjsonSerializer** | ★★★★★ | JSON APIs (2-5x faster than stdlib) |
|
|
183
232
|
| **ArrowSerializer** | ★★★★★ | Large DataFrames (6-23x faster for 10K+ rows) |
|
|
184
233
|
| **EncryptionWrapper** | ★★★★☆ | Wraps any serializer with AES-256-GCM |
|
|
@@ -300,7 +349,7 @@ print(expensive_func.cache_info())
|
|
|
300
349
|
|
|
301
350
|
| Feature | Description |
|
|
302
351
|
|:--------|:------------|
|
|
303
|
-
| [Serializer Guide][serializer-guide-url] | ArrowSerializer vs
|
|
352
|
+
| [Serializer Guide][serializer-guide-url] | ArrowSerializer vs StandardSerializer benchmarks |
|
|
304
353
|
| [Circuit Breaker][circuit-breaker-url] | Prevent cascading failures |
|
|
305
354
|
| [Distributed Locking][distributed-locking-url] | Cache stampede prevention |
|
|
306
355
|
| [Prometheus Metrics][prometheus-url] | Built-in observability |
|
|
@@ -318,6 +367,16 @@ print(expensive_func.cache_info())
|
|
|
318
367
|
CACHEKIT_REDIS_URL="redis://localhost:6379" # Primary (preferred)
|
|
319
368
|
REDIS_URL="redis://localhost:6379" # Fallback
|
|
320
369
|
|
|
370
|
+
# CachekitIO SaaS Backend (closed alpha — request access at cachekit.io)
|
|
371
|
+
CACHEKIT_API_KEY="your-api-key" # Required for @cache.io() # pragma: allowlist secret
|
|
372
|
+
CACHEKIT_API_URL="https://api.cachekit.io" # Default SaaS endpoint
|
|
373
|
+
|
|
374
|
+
# Memcached Backend (optional: pip install cachekit[memcached])
|
|
375
|
+
CACHEKIT_MEMCACHED_SERVERS='["mc1:11211", "mc2:11211"]' # Default: 127.0.0.1:11211
|
|
376
|
+
CACHEKIT_MEMCACHED_CONNECT_TIMEOUT=2.0 # Default: 2.0 seconds
|
|
377
|
+
CACHEKIT_MEMCACHED_TIMEOUT=1.0 # Default: 1.0 seconds
|
|
378
|
+
CACHEKIT_MEMCACHED_KEY_PREFIX="myapp:" # Default: "" (none)
|
|
379
|
+
|
|
321
380
|
# Optional Configuration
|
|
322
381
|
CACHEKIT_DEFAULT_TTL=3600
|
|
323
382
|
CACHEKIT_MAX_CHUNK_SIZE_MB=100
|
|
@@ -373,7 +432,7 @@ MIT License - see [LICENSE][license-file-url] for details.
|
|
|
373
432
|
[comparison-url]: docs/comparison.md
|
|
374
433
|
[getting-started-url]: docs/getting-started.md
|
|
375
434
|
[api-reference-url]: docs/api-reference.md
|
|
376
|
-
[serializer-guide-url]: docs/
|
|
435
|
+
[serializer-guide-url]: docs/serializers/index.md
|
|
377
436
|
[circuit-breaker-url]: docs/features/circuit-breaker.md
|
|
378
437
|
[distributed-locking-url]: docs/features/distributed-locking.md
|
|
379
438
|
[prometheus-url]: docs/features/prometheus-metrics.md
|
|
@@ -1,29 +1,31 @@
|
|
|
1
1
|
r"""cachekit - Caching decorator for Python applications.
|
|
2
2
|
|
|
3
|
-
A robust, production-ready Python library that provides intelligent
|
|
3
|
+
A robust, production-ready Python library that provides intelligent caching
|
|
4
4
|
capabilities with advanced features like chunked data handling, multi-serialization
|
|
5
5
|
support, distributed locking, and automatic corruption detection.
|
|
6
6
|
|
|
7
|
+
Supports pluggable backends: Redis (default), CachekitIO SaaS, File, and custom.
|
|
8
|
+
|
|
7
9
|
Key Features:
|
|
8
10
|
- **Intelligent @cache decorator** with auto-detection and intent-based optimization
|
|
9
11
|
- **Circuit breaker protection** against cascading failures
|
|
10
|
-
- **Adaptive timeout adjustment** based on historical
|
|
11
|
-
- **Backpressure control** to prevent
|
|
12
|
+
- **Adaptive timeout adjustment** based on historical backend latency patterns
|
|
13
|
+
- **Backpressure control** to prevent backend overload
|
|
12
14
|
- **Connection pooling** for optimized performance
|
|
13
15
|
- **Health check methods** for comprehensive monitoring
|
|
14
16
|
- **Structured logging** with correlation IDs and distributed tracing
|
|
15
17
|
- **Statistics collection** for Prometheus metrics integration
|
|
16
18
|
|
|
17
19
|
Architecture Overview:
|
|
18
|
-
cachekit
|
|
19
|
-
auto-detection and intent-based optimization
|
|
20
|
+
cachekit provides a modular decorator architecture with intelligent
|
|
21
|
+
auto-detection and intent-based optimization:
|
|
20
22
|
|
|
21
23
|
- FeatureOrchestrator: Manages enterprise-grade reliability and monitoring features
|
|
22
24
|
- Flexible configuration interface with intelligent auto-detection
|
|
23
25
|
- Enhanced error handling with comprehensive safety checks
|
|
24
|
-
-
|
|
26
|
+
- Pluggable backend abstraction (Redis, CachekitIO, File, custom)
|
|
25
27
|
|
|
26
|
-
Born from production debugging of
|
|
28
|
+
Born from production debugging of caching failures:
|
|
27
29
|
- UTF-8 corruption prevention with intelligent binary data handling
|
|
28
30
|
- Binary data magic byte detection and validation
|
|
29
31
|
- Chunked storage for large objects with atomic operations
|
|
@@ -51,6 +53,10 @@ Example Usage:
|
|
|
51
53
|
def get_user_data(user_id: int) -> UserProfile:
|
|
52
54
|
return db.fetch_user(user_id)
|
|
53
55
|
|
|
56
|
+
@cache.io() # Managed SaaS backend (cachekit.io, closed alpha)
|
|
57
|
+
def get_remote_data(key: str):
|
|
58
|
+
return fetch_remote(key)
|
|
59
|
+
|
|
54
60
|
# Manual configuration when needed (1% of use cases)
|
|
55
61
|
@cache(ttl=3600, namespace="custom", circuit_breaker=True)
|
|
56
62
|
def custom_function():
|
|
@@ -62,7 +68,7 @@ Example Usage:
|
|
|
62
68
|
```
|
|
63
69
|
"""
|
|
64
70
|
|
|
65
|
-
__version__ = "0.
|
|
71
|
+
__version__ = "0.6.1"
|
|
66
72
|
|
|
67
73
|
from typing import Any, Callable, TypeVar
|
|
68
74
|
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
"""Backend storage abstraction for cachekit.
|
|
2
2
|
|
|
3
3
|
This module provides protocol-based abstraction for L2 backend storage with
|
|
4
|
-
dependency injection pattern. Backends can be Redis, HTTP, DynamoDB,
|
|
5
|
-
key-value store.
|
|
4
|
+
dependency injection pattern. Backends can be Redis, HTTP, DynamoDB, Memcached,
|
|
5
|
+
or any key-value store.
|
|
6
6
|
|
|
7
7
|
Public API:
|
|
8
8
|
- BaseBackend: Core protocol (5 methods: get, set, delete, exists, health_check)
|
|
@@ -14,6 +14,7 @@ Public API:
|
|
|
14
14
|
- BackendErrorType: Error classification enum
|
|
15
15
|
- CapabilityNotAvailableError: Exception for missing optional capabilities
|
|
16
16
|
- RedisBackend: Redis implementation (default)
|
|
17
|
+
- MemcachedBackend: Memcached implementation (requires pymemcache)
|
|
17
18
|
|
|
18
19
|
Usage:
|
|
19
20
|
>>> from cachekit.backends import BaseBackend, RedisBackend, BackendError
|
|
@@ -56,6 +57,7 @@ __all__ = [
|
|
|
56
57
|
"BackendErrorType",
|
|
57
58
|
"CapabilityNotAvailableError",
|
|
58
59
|
"RedisBackend",
|
|
60
|
+
"MemcachedBackend",
|
|
59
61
|
]
|
|
60
62
|
|
|
61
63
|
|
|
@@ -95,3 +97,12 @@ class BackendProvider(Protocol):
|
|
|
95
97
|
>>> backend.set("key", b"value", ttl=60) # doctest: +SKIP
|
|
96
98
|
"""
|
|
97
99
|
...
|
|
100
|
+
|
|
101
|
+
|
|
102
|
+
def __getattr__(name: str):
|
|
103
|
+
"""Lazy import for optional backends (pymemcache may not be installed)."""
|
|
104
|
+
if name == "MemcachedBackend":
|
|
105
|
+
from cachekit.backends.memcached import MemcachedBackend
|
|
106
|
+
|
|
107
|
+
return MemcachedBackend
|
|
108
|
+
raise AttributeError(f"module {__name__!r} has no attribute {name!r}")
|