xtr-cache 5.0.1__tar.gz → 5.2.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 (54) hide show
  1. {xtr_cache-5.0.1 → xtr_cache-5.2.0}/PKG-INFO +13 -11
  2. {xtr_cache-5.0.1 → xtr_cache-5.2.0}/README.md +12 -10
  3. {xtr_cache-5.0.1 → xtr_cache-5.2.0}/pyproject.toml +1 -1
  4. {xtr_cache-5.0.1 → xtr_cache-5.2.0}/pyproject.toml.orig +1 -1
  5. {xtr_cache-5.0.1 → xtr_cache-5.2.0}/src/xtr_cache/.agents/skills/xtr-cache/SKILL.md +9 -7
  6. xtr_cache-5.2.0/src/xtr_cache/recipe/files/config/cache.py.tmpl +36 -0
  7. {xtr_cache-5.0.1 → xtr_cache-5.2.0}/src/xtr_cache/recipe/manifest.toml +5 -4
  8. {xtr_cache-5.0.1 → xtr_cache-5.2.0}/LICENSE +0 -0
  9. {xtr_cache-5.0.1 → xtr_cache-5.2.0}/src/xtr_cache/.agents/skills/xtr-cache/references/adapters.md +0 -0
  10. {xtr_cache-5.0.1 → xtr_cache-5.2.0}/src/xtr_cache/.agents/skills/xtr-cache/references/stampede-and-marshallers.md +0 -0
  11. {xtr_cache-5.0.1 → xtr_cache-5.2.0}/src/xtr_cache/__init__.py +0 -0
  12. {xtr_cache-5.0.1 → xtr_cache-5.2.0}/src/xtr_cache/_digest.py +0 -0
  13. {xtr_cache-5.0.1 → xtr_cache-5.2.0}/src/xtr_cache/_internal_key.py +0 -0
  14. {xtr_cache-5.0.1 → xtr_cache-5.2.0}/src/xtr_cache/adapter/__init__.py +0 -0
  15. {xtr_cache-5.0.1 → xtr_cache-5.2.0}/src/xtr_cache/adapter/abstract_adapter.py +0 -0
  16. {xtr_cache-5.0.1 → xtr_cache-5.2.0}/src/xtr_cache/adapter/adapter_factory.py +0 -0
  17. {xtr_cache-5.0.1 → xtr_cache-5.2.0}/src/xtr_cache/adapter/adapter_interface.py +0 -0
  18. {xtr_cache-5.0.1 → xtr_cache-5.2.0}/src/xtr_cache/adapter/array_adapter.py +0 -0
  19. {xtr_cache-5.0.1 → xtr_cache-5.2.0}/src/xtr_cache/adapter/chain_adapter.py +0 -0
  20. {xtr_cache-5.0.1 → xtr_cache-5.2.0}/src/xtr_cache/adapter/contracts_mixin.py +0 -0
  21. {xtr_cache-5.0.1 → xtr_cache-5.2.0}/src/xtr_cache/adapter/deferred_items_mixin.py +0 -0
  22. {xtr_cache-5.0.1 → xtr_cache-5.2.0}/src/xtr_cache/adapter/filesystem_adapter.py +0 -0
  23. {xtr_cache-5.0.1 → xtr_cache-5.2.0}/src/xtr_cache/adapter/null_adapter.py +0 -0
  24. {xtr_cache-5.0.1 → xtr_cache-5.2.0}/src/xtr_cache/adapter/redis_adapter.py +0 -0
  25. {xtr_cache-5.0.1 → xtr_cache-5.2.0}/src/xtr_cache/adapter/tag_aware_adapter.py +0 -0
  26. {xtr_cache-5.0.1 → xtr_cache-5.2.0}/src/xtr_cache/adapter/tag_aware_adapter_interface.py +0 -0
  27. {xtr_cache-5.0.1 → xtr_cache-5.2.0}/src/xtr_cache/adapter/tagged_value.py +0 -0
  28. {xtr_cache-5.0.1 → xtr_cache-5.2.0}/src/xtr_cache/bundle/__init__.py +0 -0
  29. {xtr_cache-5.0.1 → xtr_cache-5.2.0}/src/xtr_cache/bundle/cache_bundle.py +0 -0
  30. {xtr_cache-5.0.1 → xtr_cache-5.2.0}/src/xtr_cache/bundle/cache_config.py +0 -0
  31. {xtr_cache-5.0.1 → xtr_cache-5.2.0}/src/xtr_cache/bundle/pool_config.py +0 -0
  32. {xtr_cache-5.0.1 → xtr_cache-5.2.0}/src/xtr_cache/cache_item.py +0 -0
  33. {xtr_cache-5.0.1 → xtr_cache-5.2.0}/src/xtr_cache/cache_pool_clearer.py +0 -0
  34. {xtr_cache-5.0.1 → xtr_cache-5.2.0}/src/xtr_cache/command/__init__.py +0 -0
  35. {xtr_cache-5.0.1 → xtr_cache-5.2.0}/src/xtr_cache/command/cache_pool_clear_command.py +0 -0
  36. {xtr_cache-5.0.1 → xtr_cache-5.2.0}/src/xtr_cache/command/cache_pool_delete_command.py +0 -0
  37. {xtr_cache-5.0.1 → xtr_cache-5.2.0}/src/xtr_cache/command/cache_pool_invalidate_tags_command.py +0 -0
  38. {xtr_cache-5.0.1 → xtr_cache-5.2.0}/src/xtr_cache/command/cache_pool_list_command.py +0 -0
  39. {xtr_cache-5.0.1 → xtr_cache-5.2.0}/src/xtr_cache/command/cache_pool_prune_command.py +0 -0
  40. {xtr_cache-5.0.1 → xtr_cache-5.2.0}/src/xtr_cache/command/pool_command.py +0 -0
  41. {xtr_cache-5.0.1 → xtr_cache-5.2.0}/src/xtr_cache/command/pools.py +0 -0
  42. {xtr_cache-5.0.1 → xtr_cache-5.2.0}/src/xtr_cache/exception/__init__.py +0 -0
  43. {xtr_cache-5.0.1 → xtr_cache-5.2.0}/src/xtr_cache/exception/logic_error.py +0 -0
  44. {xtr_cache-5.0.1 → xtr_cache-5.2.0}/src/xtr_cache/exception/marshalling_error.py +0 -0
  45. {xtr_cache-5.0.1 → xtr_cache-5.2.0}/src/xtr_cache/lock_registry.py +0 -0
  46. {xtr_cache-5.0.1 → xtr_cache-5.2.0}/src/xtr_cache/marshaller/__init__.py +0 -0
  47. {xtr_cache-5.0.1 → xtr_cache-5.2.0}/src/xtr_cache/marshaller/default_marshaller.py +0 -0
  48. {xtr_cache-5.0.1 → xtr_cache-5.2.0}/src/xtr_cache/marshaller/deflate_marshaller.py +0 -0
  49. {xtr_cache-5.0.1 → xtr_cache-5.2.0}/src/xtr_cache/marshaller/marshaller_interface.py +0 -0
  50. {xtr_cache-5.0.1 → xtr_cache-5.2.0}/src/xtr_cache/marshaller/sodium_marshaller.py +0 -0
  51. {xtr_cache-5.0.1 → xtr_cache-5.2.0}/src/xtr_cache/pruneable_interface.py +0 -0
  52. {xtr_cache-5.0.1 → xtr_cache-5.2.0}/src/xtr_cache/py.typed +0 -0
  53. {xtr_cache-5.0.1 → xtr_cache-5.2.0}/src/xtr_cache/recipe/__init__.py +0 -0
  54. {xtr_cache-5.0.1 → xtr_cache-5.2.0}/src/xtr_cache/value_wrapper.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: xtr-cache
3
- Version: 5.0.1
3
+ Version: 5.2.0
4
4
  Summary: Cache pools in memory, in files, in Redis, chained or tag-aware, with stampede protection.
5
5
  Keywords: cache,redis,stampede,tags,asyncio
6
6
  Author: Xterr
@@ -297,19 +297,21 @@ Everything adding this package to an application on
297
297
  - **Install** — `uv add xtr-cache xtr-dependency-injection`: the bundle needs the container
298
298
  installed beside it, never as an extra. Add `redis` or `sodium` for what you use; install
299
299
  xtr-console beside it for the `cache:pool:*` commands, and xtr-logging for a `cache` channel.
300
- - **Recipe** — `uv run xtr-recipes recipes:sync` does the *Activate* and *Ignore* steps below: it
301
- lists `CacheBundle` and ignores `/var/`. There is no config file or environment to write.
302
- - **Activate** — `CacheBundle: {"all": True}` in `BUNDLES` in `<app>/bundles.py`, imported
300
+ - **Recipe** — `uv run xtr-recipes recipes:sync` does the *Activate*, *Configure* and *Ignore*
301
+ steps below: it lists `CacheBundle`, writes `<app>/config/packages/cache.py` with the bundle's
302
+ own defaults, and ignores `/var/`. There is no environment to write.
303
+ - **Activate** — `CacheBundle: {"all": True}` in `BUNDLES` in `<app>/config/bundles.py`, imported
303
304
  from `xtr_cache.bundle`.
304
305
  - **Brings along** — the logging and console bundles, when those packages are installed.
305
- - **Configure** — optional: with no configuration there is one `app` pool on files. Pools,
306
- adapters and the stampede lock go in `<app>/config/cache.py`, a `@configure` function
307
- returning `CacheConfig` — see [Kernel / bundle](#kernel--bundle).
306
+ - **Configure** — optional: the recipe writes `<app>/config/packages/cache.py` holding the
307
+ defaults, one `app` pool on files. Pools, adapters and the stampede lock go in that same
308
+ `@configure` function returning `CacheConfig` — see [Kernel / bundle](#kernel--bundle).
308
309
  - **Environment** — nothing required. A DSN given as `env(...)` must be set when the
309
310
  application boots: booting checks every pool.
310
311
  - **Ignore** — `var/`: files live under `kernel.share_dir`, `var/share` in the project.
311
- - **Remove** — drop the `BUNDLES` entry, delete `<app>/config/cache.py`, then
312
- `uv remove xtr-cache`.
312
+ - **Remove** — drop the `BUNDLES` entry; `uv run xtr-recipes recipes:remove xtr-cache` deletes
313
+ `<app>/config/packages/cache.py`, unless you edited it, in which case it is moved aside to
314
+ `cache.py.removed`. Then `uv remove xtr-cache`.
313
315
  - **Check** — `debug:bundles` shows `cache` as `listed` and `active`.
314
316
 
315
317
  ## Kernel / bundle
@@ -319,14 +321,14 @@ not a dependency, and nothing outside `xtr_cache.bundle` needs it — list the b
319
321
  pools:
320
322
 
321
323
  ```python
322
- # app/bundles.py
324
+ # app/config/bundles.py
323
325
  from xtr_cache.bundle import CacheBundle
324
326
 
325
327
  BUNDLES = {CacheBundle: {"all": True}}
326
328
  ```
327
329
 
328
330
  ```python
329
- # app/config/cache.py
331
+ # app/config/packages/cache.py
330
332
  from xtr_dependency_injection import configure, env
331
333
  from xtr_cache.bundle import CacheConfig, PoolConfig
332
334
 
@@ -268,19 +268,21 @@ Everything adding this package to an application on
268
268
  - **Install** — `uv add xtr-cache xtr-dependency-injection`: the bundle needs the container
269
269
  installed beside it, never as an extra. Add `redis` or `sodium` for what you use; install
270
270
  xtr-console beside it for the `cache:pool:*` commands, and xtr-logging for a `cache` channel.
271
- - **Recipe** — `uv run xtr-recipes recipes:sync` does the *Activate* and *Ignore* steps below: it
272
- lists `CacheBundle` and ignores `/var/`. There is no config file or environment to write.
273
- - **Activate** — `CacheBundle: {"all": True}` in `BUNDLES` in `<app>/bundles.py`, imported
271
+ - **Recipe** — `uv run xtr-recipes recipes:sync` does the *Activate*, *Configure* and *Ignore*
272
+ steps below: it lists `CacheBundle`, writes `<app>/config/packages/cache.py` with the bundle's
273
+ own defaults, and ignores `/var/`. There is no environment to write.
274
+ - **Activate** — `CacheBundle: {"all": True}` in `BUNDLES` in `<app>/config/bundles.py`, imported
274
275
  from `xtr_cache.bundle`.
275
276
  - **Brings along** — the logging and console bundles, when those packages are installed.
276
- - **Configure** — optional: with no configuration there is one `app` pool on files. Pools,
277
- adapters and the stampede lock go in `<app>/config/cache.py`, a `@configure` function
278
- returning `CacheConfig` — see [Kernel / bundle](#kernel--bundle).
277
+ - **Configure** — optional: the recipe writes `<app>/config/packages/cache.py` holding the
278
+ defaults, one `app` pool on files. Pools, adapters and the stampede lock go in that same
279
+ `@configure` function returning `CacheConfig` — see [Kernel / bundle](#kernel--bundle).
279
280
  - **Environment** — nothing required. A DSN given as `env(...)` must be set when the
280
281
  application boots: booting checks every pool.
281
282
  - **Ignore** — `var/`: files live under `kernel.share_dir`, `var/share` in the project.
282
- - **Remove** — drop the `BUNDLES` entry, delete `<app>/config/cache.py`, then
283
- `uv remove xtr-cache`.
283
+ - **Remove** — drop the `BUNDLES` entry; `uv run xtr-recipes recipes:remove xtr-cache` deletes
284
+ `<app>/config/packages/cache.py`, unless you edited it, in which case it is moved aside to
285
+ `cache.py.removed`. Then `uv remove xtr-cache`.
284
286
  - **Check** — `debug:bundles` shows `cache` as `listed` and `active`.
285
287
 
286
288
  ## Kernel / bundle
@@ -290,14 +292,14 @@ not a dependency, and nothing outside `xtr_cache.bundle` needs it — list the b
290
292
  pools:
291
293
 
292
294
  ```python
293
- # app/bundles.py
295
+ # app/config/bundles.py
294
296
  from xtr_cache.bundle import CacheBundle
295
297
 
296
298
  BUNDLES = {CacheBundle: {"all": True}}
297
299
  ```
298
300
 
299
301
  ```python
300
- # app/config/cache.py
302
+ # app/config/packages/cache.py
301
303
  from xtr_dependency_injection import configure, env
302
304
  from xtr_cache.bundle import CacheConfig, PoolConfig
303
305
 
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "xtr-cache"
3
- version = "5.0.1"
3
+ version = "5.2.0"
4
4
  description = "Cache pools in memory, in files, in Redis, chained or tag-aware, with stampede protection."
5
5
  readme = "README.md"
6
6
  requires-python = ">=3.11"
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "xtr-cache"
3
- version = "5.0.1"
3
+ version = "5.2.0"
4
4
  description = "Cache pools in memory, in files, in Redis, chained or tag-aware, with stampede protection."
5
5
  readme = "README.md"
6
6
  requires-python = ">=3.11"
@@ -173,20 +173,21 @@ rotation.
173
173
  ## Use in an application
174
174
 
175
175
  `uv run xtr-recipes recipes:sync` applies the recipe shipped with this package: it lists
176
- `CacheBundle` and ignores `/var/`. That is the steps below a recipe can do; the others it prints
177
- for you to make.
176
+ `CacheBundle`, writes `<app>/config/packages/cache.py` with the bundle's own defaults, and ignores
177
+ `/var/`. That is the steps below a recipe can do; the others it prints for you to make.
178
178
 
179
179
  1. **Install** — `uv add xtr-cache xtr-dependency-injection`: the bundle needs the container
180
180
  installed beside it, never as an extra. Add `redis` or `sodium` for what you use; install
181
181
  xtr-console beside it for the `cache:pool:*` commands, and xtr-logging for a `cache` channel.
182
- 2. **Activate** — `CacheBundle: {"all": True}` in `BUNDLES` in `<app>/bundles.py`, imported from
182
+ 2. **Activate** — `CacheBundle: {"all": True}` in `BUNDLES` in `<app>/config/bundles.py`, imported from
183
183
  `xtr_cache.bundle`.
184
184
  3. **Brings along** — the logging and console bundles, when those packages are installed. With
185
185
  logging, a `cache` channel is added and every pool logs there.
186
- 4. **Configure** — optional; with no configuration there is one `app` pool on files:
186
+ 4. **Configure** — the recipe writes `<app>/config/packages/cache.py` holding the defaults, one
187
+ `app` pool on files, and that is where pools and adapters go:
187
188
 
188
189
  ```python
189
- # <app>/config/cache.py
190
+ # <app>/config/packages/cache.py
190
191
  from xtr_dependency_injection import configure, env
191
192
 
192
193
  from xtr_cache.bundle import CacheConfig, PoolConfig
@@ -241,8 +242,9 @@ for you to make.
241
242
  8. **Check** — `debug:bundles` shows `cache` as `listed` and `active`.
242
243
  `cache:pool:list`, `cache:pool:clear`, `cache:pool:delete`, `cache:pool:invalidate-tags` and
243
244
  `cache:pool:prune` are there once the console bundle is active.
244
- 9. **Remove** — drop the `BUNDLES` entry, delete `<app>/config/cache.py`, then
245
- `uv remove xtr-cache`.
245
+ 9. **Remove** — drop the `BUNDLES` entry; `uv run xtr-recipes recipes:remove xtr-cache` deletes
246
+ `<app>/config/packages/cache.py`, unless you edited it, in which case it is moved aside to
247
+ `cache.py.removed`. Then `uv remove xtr-cache`.
246
248
 
247
249
  Without a container, hand the commands their pools once and import `xtr_cache.command` before the
248
250
  application runs:
@@ -0,0 +1,36 @@
1
+ """The cache pools: where cached values are kept, and for how long.
2
+
3
+ The ``app`` pool exists with no configuration, on files under ``var/share/cache``, and is the
4
+ pool a service asking for a cache with no name gets. Name more pools for values that need a
5
+ lifetime or a backend of their own; a pool given no adapter keeps its values in ``app``'s,
6
+ under a namespace of its own.
7
+
8
+ ```python
9
+ CacheConfig(
10
+ app=env("CACHE_DSN"),
11
+ pools={
12
+ "sessions": PoolConfig(default_lifetime=3600),
13
+ "catalogue": PoolConfig(adapter=["array", "redis://localhost:6379"], tags=True),
14
+ },
15
+ )
16
+ ```
17
+ """
18
+
19
+ from __future__ import annotations
20
+
21
+ from xtr_cache.bundle import CacheConfig
22
+ from xtr_dependency_injection import configure
23
+
24
+ __all__ = ["cache"]
25
+
26
+
27
+ @configure
28
+ def cache() -> CacheConfig:
29
+ """The ``app`` pool on the filesystem, and no other pool."""
30
+ # The app pool's adapter is "filesystem" until it is set: "array" keeps values in this
31
+ # process alone, and a DSN such as "redis://localhost:6379" shares them between processes.
32
+ # Several adapters chain, fastest first.
33
+ #
34
+ # Every pool's namespace is derived from prefix_seed, the project directory unless set, so
35
+ # two applications sharing one backend never read each other's values.
36
+ return CacheConfig()
@@ -5,10 +5,11 @@
5
5
  # "<module>:<class>" = the environments it is listed with, exactly as in BUNDLES.
6
6
  "xtr_cache.bundle:CacheBundle" = { all = true }
7
7
 
8
- # No [files]: configuring is optional. With none there is one "app" pool on
9
- # files, and nothing is opened until a pool is first asked for. An application
10
- # that wants pools, adapters or a stampede lock of its own writes
11
- # config/cache.py itself.
8
+ [files]
9
+ # Destination under the application package = template under this recipe.
10
+ # The bundle's own defaults written out — one "app" pool on files, nothing opened
11
+ # until a pool is first asked for — as the place pools and adapters go.
12
+ "config/packages/cache.py" = "files/config/cache.py.tmpl"
12
13
 
13
14
  # No [env]: nothing is required. A DSN an application gives as env(...) must be
14
15
  # set when it boots, because booting checks every pool.
File without changes