sg-query-cache 0.1.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (42) hide show
  1. sg_query_cache/__init__.py +39 -0
  2. sg_query_cache/__main__.py +8 -0
  3. sg_query_cache/_async_backend.py +101 -0
  4. sg_query_cache/_async_cache.py +1240 -0
  5. sg_query_cache/_async_client.py +1390 -0
  6. sg_query_cache/_async_local.py +318 -0
  7. sg_query_cache/_async_support.py +314 -0
  8. sg_query_cache/_async_valkey_control.py +580 -0
  9. sg_query_cache/_backend.py +168 -0
  10. sg_query_cache/_backend_validation.py +110 -0
  11. sg_query_cache/_cache.py +1608 -0
  12. sg_query_cache/_cache_common.py +387 -0
  13. sg_query_cache/_cli.py +313 -0
  14. sg_query_cache/_client.py +1061 -0
  15. sg_query_cache/_client_common.py +600 -0
  16. sg_query_cache/_codec.py +345 -0
  17. sg_query_cache/_config.py +1217 -0
  18. sg_query_cache/_dependencies.py +888 -0
  19. sg_query_cache/_downstream.py +141 -0
  20. sg_query_cache/_event_mapping.py +409 -0
  21. sg_query_cache/_keys.py +298 -0
  22. sg_query_cache/_local.py +301 -0
  23. sg_query_cache/_local_store.py +604 -0
  24. sg_query_cache/_metrics.py +200 -0
  25. sg_query_cache/_model.py +546 -0
  26. sg_query_cache/_policy.py +378 -0
  27. sg_query_cache/_query.py +53 -0
  28. sg_query_cache/_urls.py +324 -0
  29. sg_query_cache/_validation.py +70 -0
  30. sg_query_cache/_valkey_common.py +1037 -0
  31. sg_query_cache/_valkey_control.py +437 -0
  32. sg_query_cache/_valkey_proof.py +64 -0
  33. sg_query_cache/_valkey_scripts.py +454 -0
  34. sg_query_cache/daemon_plugin.py +159 -0
  35. sg_query_cache/py.typed +0 -0
  36. sg_query_cache/valkey.py +1533 -0
  37. sg_query_cache/valkey_async.py +1568 -0
  38. sg_query_cache-0.1.0.dist-info/METADATA +247 -0
  39. sg_query_cache-0.1.0.dist-info/RECORD +42 -0
  40. sg_query_cache-0.1.0.dist-info/WHEEL +4 -0
  41. sg_query_cache-0.1.0.dist-info/entry_points.txt +2 -0
  42. sg_query_cache-0.1.0.dist-info/licenses/LICENSE +21 -0
@@ -0,0 +1,39 @@
1
+ """Cache exact SG query results under explicit identity and freshness contracts.
2
+
3
+ Wrap a caller-owned SG client with the synchronous or native asynchronous
4
+ adapter using validated settings, an explicit effective identity, and matching
5
+ response context. Caching provides bounded staleness; it does not authenticate
6
+ the supplied identity or make reads causally consistent with SG writes.
7
+
8
+ Close each owned cache when its work finishes. The async owning factory closes
9
+ its constructed cache; directly injected caches remain caller-owned. Async
10
+ operations and resource cleanup must use one event loop. Optional Valkey
11
+ backends are imported explicitly from `sg_query_cache.valkey` or
12
+ `sg_query_cache.valkey_async`.
13
+ """
14
+
15
+ from sg_query_cache._async_backend import AsyncCacheBackend
16
+ from sg_query_cache._async_cache import AsyncQueryCache
17
+ from sg_query_cache._async_client import AsyncCachedShotgun
18
+ from sg_query_cache._async_local import AsyncLocalBackend
19
+ from sg_query_cache._cache import QueryCache
20
+ from sg_query_cache._client import CachedShotgun, ClientContext
21
+ from sg_query_cache._config import CacheSettings
22
+ from sg_query_cache._local import LocalBackend
23
+ from sg_query_cache._metrics import MetricsSink, NullMetrics
24
+ from sg_query_cache._model import Identity
25
+
26
+ __all__ = [
27
+ 'AsyncCacheBackend',
28
+ 'AsyncCachedShotgun',
29
+ 'AsyncLocalBackend',
30
+ 'AsyncQueryCache',
31
+ 'CacheSettings',
32
+ 'CachedShotgun',
33
+ 'ClientContext',
34
+ 'Identity',
35
+ 'LocalBackend',
36
+ 'MetricsSink',
37
+ 'NullMetrics',
38
+ 'QueryCache',
39
+ ]
@@ -0,0 +1,8 @@
1
+ """Run the supported `python -m sg_query_cache` command-line entry point."""
2
+
3
+ import sys
4
+
5
+ from sg_query_cache._cli import main
6
+
7
+ if __name__ == '__main__':
8
+ sys.exit(main())
@@ -0,0 +1,101 @@
1
+ """Define the backend-neutral asynchronous cache storage contract."""
2
+
3
+ from typing import Protocol
4
+
5
+ from sg_query_cache._model import (
6
+ CacheHit,
7
+ DependencyTag,
8
+ FillLease,
9
+ GenerationChange,
10
+ GenerationVector,
11
+ )
12
+
13
+
14
+ class AsyncCacheBackend(Protocol):
15
+ """Store opaque encoded results through loop-native coroutine methods.
16
+
17
+ Each method preserves the corresponding `CacheBackend` arguments, return
18
+ values, and backend errors while adding coroutine cancellation cooperation.
19
+ This protocol types the shipped backends; third-party implementations are
20
+ not yet a supported extension point.
21
+ """
22
+
23
+ async def change(self, changes: tuple[GenerationChange, ...]) -> None:
24
+ """Replace all applicable generations in caller order.
25
+
26
+ Args:
27
+ changes: Ordered generation replacements to acknowledge together.
28
+ """
29
+ ...
30
+
31
+ async def close(self) -> None:
32
+ """Release backend resources; repeated same-loop calls have no effect."""
33
+ ...
34
+
35
+ async def commit(self, lease: FillLease, payload: bytes, remaining_seconds: float) -> bool:
36
+ """Store encoded bytes only while the exact lease remains current.
37
+
38
+ Args:
39
+ lease: Exact key and token returned by `reserve`.
40
+ payload: Closed-codec bytes to retain.
41
+ remaining_seconds: Positive authoritative lifetime remaining.
42
+
43
+ Returns:
44
+ Whether the lease remained current and the result was admitted.
45
+ """
46
+ ...
47
+
48
+ async def flush_site(self, site_namespace: str, reason: str) -> None:
49
+ """Replace one site's permanent site generation.
50
+
51
+ Args:
52
+ site_namespace: Stable configured site namespace.
53
+ reason: Short operator-facing reason code.
54
+ """
55
+ ...
56
+
57
+ async def lookup(self, key: str) -> CacheHit | None:
58
+ """Read valid encoded bytes with backend-authoritative remaining age.
59
+
60
+ Args:
61
+ key: Opaque generation-qualified result key.
62
+
63
+ Returns:
64
+ An isolated hit, optionally carrying the backend's fresh decoded
65
+ value, or `None` for absence, expiry, or corruption.
66
+ """
67
+ ...
68
+
69
+ async def release(self, lease: FillLease) -> bool:
70
+ """Remove a fill lease only when its exact token remains current.
71
+
72
+ Args:
73
+ lease: Exact key and token returned by `reserve`.
74
+
75
+ Returns:
76
+ Whether the current lease was removed.
77
+ """
78
+ ...
79
+
80
+ async def reserve(self, key: str, lease_seconds: float) -> FillLease | None:
81
+ """Acquire temporary fill ownership for one opaque key.
82
+
83
+ Args:
84
+ key: Opaque generation-qualified result key.
85
+ lease_seconds: Positive ownership duration.
86
+
87
+ Returns:
88
+ A fresh lease, or `None` while another lease remains current.
89
+ """
90
+ ...
91
+
92
+ async def resolve(self, tags: tuple[DependencyTag, ...]) -> GenerationVector:
93
+ """Resolve one complete bounded dependency vector in request order.
94
+
95
+ Args:
96
+ tags: Ordered unique dependency tags.
97
+
98
+ Returns:
99
+ Every requested tag and current token under one incarnation.
100
+ """
101
+ ...