gpdatacached 0.1.0__tar.gz → 0.2.1__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (58) hide show
  1. {gpdatacached-0.1.0 → gpdatacached-0.2.1}/.gitignore +4 -0
  2. gpdatacached-0.2.1/CHANGELOG.md +151 -0
  3. {gpdatacached-0.1.0 → gpdatacached-0.2.1}/PKG-INFO +16 -15
  4. {gpdatacached-0.1.0 → gpdatacached-0.2.1}/README.md +14 -13
  5. {gpdatacached-0.1.0 → gpdatacached-0.2.1}/README.zh-CN.md +14 -13
  6. {gpdatacached-0.1.0 → gpdatacached-0.2.1}/docs/en/api.md +205 -16
  7. {gpdatacached-0.1.0 → gpdatacached-0.2.1}/docs/en/extensibility.md +20 -12
  8. {gpdatacached-0.1.0 → gpdatacached-0.2.1}/docs/en/index.md +2 -1
  9. {gpdatacached-0.1.0 → gpdatacached-0.2.1}/docs/en/lifecycle.md +36 -25
  10. {gpdatacached-0.1.0 → gpdatacached-0.2.1}/docs/en/locking.md +11 -11
  11. {gpdatacached-0.1.0 → gpdatacached-0.2.1}/docs/en/overview.md +24 -6
  12. {gpdatacached-0.1.0 → gpdatacached-0.2.1}/docs/en/pandas-support.md +19 -7
  13. {gpdatacached-0.1.0 → gpdatacached-0.2.1}/docs/en/performance-guide.md +21 -17
  14. {gpdatacached-0.1.0 → gpdatacached-0.2.1}/docs/en/pydantic-support.md +16 -4
  15. {gpdatacached-0.1.0 → gpdatacached-0.2.1}/docs/zh/api.md +162 -15
  16. {gpdatacached-0.1.0 → gpdatacached-0.2.1}/docs/zh/extensibility.md +20 -12
  17. {gpdatacached-0.1.0 → gpdatacached-0.2.1}/docs/zh/index.md +2 -1
  18. {gpdatacached-0.1.0 → gpdatacached-0.2.1}/docs/zh/lifecycle.md +37 -26
  19. {gpdatacached-0.1.0 → gpdatacached-0.2.1}/docs/zh/locking.md +11 -11
  20. {gpdatacached-0.1.0 → gpdatacached-0.2.1}/docs/zh/overview.md +23 -5
  21. {gpdatacached-0.1.0 → gpdatacached-0.2.1}/docs/zh/pandas-support.md +20 -8
  22. {gpdatacached-0.1.0 → gpdatacached-0.2.1}/docs/zh/performance-guide.md +21 -17
  23. {gpdatacached-0.1.0 → gpdatacached-0.2.1}/docs/zh/pydantic-support.md +16 -4
  24. {gpdatacached-0.1.0 → gpdatacached-0.2.1}/pyproject.toml +1 -0
  25. {gpdatacached-0.1.0 → gpdatacached-0.2.1}/src/gpdatacached/__init__.py +30 -11
  26. gpdatacached-0.2.1/src/gpdatacached/builtins/decimal_object.py +39 -0
  27. {gpdatacached-0.1.0 → gpdatacached-0.2.1}/src/gpdatacached/builtins/dict_object.py +23 -19
  28. {gpdatacached-0.1.0 → gpdatacached-0.2.1}/src/gpdatacached/builtins/list_object.py +18 -13
  29. {gpdatacached-0.1.0 → gpdatacached-0.2.1}/src/gpdatacached/builtins/registry.py +11 -0
  30. {gpdatacached-0.1.0 → gpdatacached-0.2.1}/src/gpdatacached/builtins/set_object.py +9 -0
  31. {gpdatacached-0.1.0 → gpdatacached-0.2.1}/src/gpdatacached/config.py +25 -0
  32. {gpdatacached-0.1.0 → gpdatacached-0.2.1}/src/gpdatacached/container.py +29 -2
  33. gpdatacached-0.2.1/src/gpdatacached/data_cache.py +214 -0
  34. {gpdatacached-0.1.0 → gpdatacached-0.2.1}/src/gpdatacached/domain.py +40 -4
  35. {gpdatacached-0.1.0 → gpdatacached-0.2.1}/src/gpdatacached/exceptions.py +18 -0
  36. {gpdatacached-0.1.0 → gpdatacached-0.2.1}/src/gpdatacached/extensions/pandas_support.py +61 -26
  37. {gpdatacached-0.1.0 → gpdatacached-0.2.1}/src/gpdatacached/extensions/pydantic_support.py +27 -4
  38. {gpdatacached-0.1.0 → gpdatacached-0.2.1}/src/gpdatacached/keys.py +1 -1
  39. {gpdatacached-0.1.0 → gpdatacached-0.2.1}/src/gpdatacached/namespace.py +16 -7
  40. {gpdatacached-0.1.0 → gpdatacached-0.2.1}/src/gpdatacached/object.py +37 -10
  41. {gpdatacached-0.1.0 → gpdatacached-0.2.1}/src/gpdatacached/types.py +40 -5
  42. {gpdatacached-0.1.0 → gpdatacached-0.2.1}/LICENSE +0 -0
  43. {gpdatacached-0.1.0 → gpdatacached-0.2.1}/src/gpdatacached/builtins/__init__.py +0 -0
  44. {gpdatacached-0.1.0 → gpdatacached-0.2.1}/src/gpdatacached/builtins/bool_object.py +0 -0
  45. {gpdatacached-0.1.0 → gpdatacached-0.2.1}/src/gpdatacached/builtins/datetime_object.py +0 -0
  46. {gpdatacached-0.1.0 → gpdatacached-0.2.1}/src/gpdatacached/builtins/float_object.py +0 -0
  47. {gpdatacached-0.1.0 → gpdatacached-0.2.1}/src/gpdatacached/builtins/int_object.py +0 -0
  48. {gpdatacached-0.1.0 → gpdatacached-0.2.1}/src/gpdatacached/builtins/none_object.py +0 -0
  49. {gpdatacached-0.1.0 → gpdatacached-0.2.1}/src/gpdatacached/builtins/str_object.py +0 -0
  50. {gpdatacached-0.1.0 → gpdatacached-0.2.1}/src/gpdatacached/builtins/tuple_object.py +0 -0
  51. {gpdatacached-0.1.0 → gpdatacached-0.2.1}/src/gpdatacached/codec.py +0 -0
  52. {gpdatacached-0.1.0 → gpdatacached-0.2.1}/src/gpdatacached/extensions/__init__.py +0 -0
  53. {gpdatacached-0.1.0 → gpdatacached-0.2.1}/src/gpdatacached/gc.py +0 -0
  54. {gpdatacached-0.1.0 → gpdatacached-0.2.1}/src/gpdatacached/lifecycle.py +0 -0
  55. {gpdatacached-0.1.0 → gpdatacached-0.2.1}/src/gpdatacached/locking.py +0 -0
  56. {gpdatacached-0.1.0 → gpdatacached-0.2.1}/src/gpdatacached/meta.py +0 -0
  57. {gpdatacached-0.1.0 → gpdatacached-0.2.1}/src/gpdatacached/refset.py +0 -0
  58. {gpdatacached-0.1.0 → gpdatacached-0.2.1}/src/gpdatacached/scalar.py +0 -0
@@ -177,6 +177,9 @@ CLAUDE.md
177
177
  AGENTS.md
178
178
  .opencode/
179
179
 
180
+ # ZCode
181
+ .zcode/
182
+
180
183
  # Github Copilot
181
184
  .github/copilot-instructions.md
182
185
 
@@ -195,3 +198,4 @@ progress.md
195
198
 
196
199
  # user ignore
197
200
  tests/mocks/log/
201
+ /.superpowers/
@@ -0,0 +1,151 @@
1
+ # Changelog
2
+
3
+ All notable changes to this project are documented in this file.
4
+
5
+ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
6
+ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
+
8
+ GitHub Releases (with download artifacts) are published at
9
+ <https://github.com/LinnetCodes/gpdatacached/releases>.
10
+
11
+ ## [0.2.1] — 2026-10-12
12
+
13
+ ### Added
14
+
15
+ - **`Decimal` builtin scalar type** — `decimal.Decimal` is auto-registered on
16
+ `import gpdatacached` as `scalar:decimal`; `DecimalObject` and `DecimalCodec`
17
+ are exported from the package root. Encoded losslessly as
18
+ `decimal:{str(value)}`: coefficient/exponent (significance) are preserved
19
+ exactly, extreme exponents use scientific notation, and non-finite values
20
+ (`NaN`, `sNaN`, `±Infinity`) plus `-0` roundtrip as-is — the same policy as
21
+ `float`'s `nan`/`inf`. Works everywhere a registered scalar does: standalone
22
+ objects, container elements, dict keys, set members, tuple elements, and
23
+ pandas object-dtype columns/index labels. Malformed payloads raise
24
+ `ValueError` on decode. Note the documented cross-type-equality caveat:
25
+ natively-equal values of different numeric types (`1` vs `Decimal(1)`) are
26
+ distinct GPDC dict keys/set members, as `1` vs `1.0` already were.
27
+
28
+ ### Documentation
29
+
30
+ - Full docs-vs-code synchronization pass across `docs/` (English + zh-CN
31
+ mirrors) and both READMEs: README now lists `Decimal` among the supported
32
+ scalar types and its Quick Start lifecycle example is runnable as written
33
+ (`update_cache_mode_and_ttl` instead of mode-restricted `expire_in`);
34
+ `api.md` documents `remaining_ttl()` and the exact `ObjectGoneError`
35
+ surface; the extensibility codec diagram and the overview layer-dependency
36
+ edge were corrected to match the code (`GPDCContainerCodec` is a sibling
37
+ root of `GPDCCodec`, and the extensions depend on the type-system layer,
38
+ not the builtins); performance-guide RTT attributions were updated; the
39
+ zh-CN mirrors gained the translated §7 ownership heading (with a durable
40
+ explicit anchor) and several translation fixes. `keys.py`'s `make_ref_key`
41
+ docstring and the pandas `UnsupportedElementTypeError` guidance message
42
+ were corrected to match reality (hash, not set; `decimal` included). The
43
+ README status badge now reads Beta, aligned with the packaging
44
+ classifier `Development Status :: 4 - Beta`.
45
+
46
+ ## [0.2.0] — 2026-07-26
47
+
48
+ ### Added
49
+
50
+ - **`GPDataCache` facade** — a config-driven entry point that discovers
51
+ `GPDCDomain` instances from a `gpconfig` `GPConfigFolder`, lazily constructs
52
+ them on first access, and resolves GPDC URIs to live `GPDCDataObject`
53
+ instances. Includes `__contains__` (config-snapshot membership, usable after
54
+ `close()`), `close()` (closes all cached domains), and the URI accessors below.
55
+ - **GPDC URI access** — `GPDataCache.get_object_by_uri(uri)` and
56
+ `has_uri(uri)`, with multi-segment path traversal into nested containers
57
+ (e.g. `gpdc://domain/ns/order_obj/items/0`). Terminals on a scalar field
58
+ raise `ObjectNotFoundByURIError`. The utilities `make_uri` /
59
+ `uri_to_redis_key` / `validate_object_name` are part of the public surface.
60
+ - **`expire_now()`** on `GPDCDataObject` — an explicit, mode-independent
61
+ "delete now" entry point (full teardown incl. anonymous subtrees; raises
62
+ `CanonicalObjectReferencedError` if still referenced). Use this instead of
63
+ `expire_in(0)` / `expire_at(past)` when you want unambiguous immediate
64
+ deletion.
65
+ - **Public exception bases** — `GPDCError` (root of the whole hierarchy) and
66
+ `GPDCLockError` (base for lock-acquisition/ownership errors) are now
67
+ exported, so callers can catch by category: `except GPDCError` catches every
68
+ library error; `except GPDCLockError` catches every lock failure.
69
+ - **`ObjectNotFoundByURIError`** — raised by URI resolution on any
70
+ unresolvable URI (missing domain/namespace/object, broken traversal,
71
+ scalar terminal, malformed syntax).
72
+ - **Pydantic container-mode field validation** —
73
+ `BaseModelContainerObject.__setitem__` now validates the value against the
74
+ field's declared type *before* any Redis write (single-field via pydantic's
75
+ `TypeAdapter`); a type mismatch raises `pydantic.ValidationError` at the
76
+ call site and leaves the object untouched. Cross-field validators still
77
+ require the scalar codec.
78
+ - gpconfig integration: `GPDCDomain` / `GPDCDomainConfig` are registered with
79
+ `gpconfig`'s object factory at import time, so a domain can be constructed
80
+ directly from a config file via `folder.get_object(name)`.
81
+
82
+ ### Changed
83
+
84
+ - **BREAKING:** `GPDCDomain.__init__` signature changed from
85
+ `(name, config)` to `(config, name=None)`, conforming to gpconfig's
86
+ `cls(config)` configurable convention. The old call order raises
87
+ `TypeError` with migration guidance before any Redis connection is made.
88
+ `config.name` (the filename stem when loaded from a file) is preferred as
89
+ the domain name; the explicit `name` argument is the fallback.
90
+ - `expire_in(seconds)` now requires `seconds > 0` (raises `ValueError`
91
+ otherwise). Use `expire_now()` for immediate deletion.
92
+ - `GC interval` validation: `gc_interval_seconds` must now be `>= 30`
93
+ (default `300` unchanged). Smaller values busy-looped the background GC
94
+ thread.
95
+
96
+ ### Fixed
97
+
98
+ - **Pandas non-unit `RangeIndex`** — `DataFrameObject.__len__` and
99
+ `SeriesObject`/`DataFrameObject` `extend` now honour the stored
100
+ `range_step` instead of assuming `step == 1`. Extending a non-unit-step
101
+ DataFrame now stays in the compact range representation (previously
102
+ promoted to labelled levels).
103
+ - **`SeriesObject.name` identity** — `.name` now returns the namespace
104
+ binding (inherited from `GPDCDataObject`, matching `.canonical_name` /
105
+ `.uri`); the pandas label is exposed as `.series_name`. Restores the
106
+ base-class identity contract that `SeriesObject` had been overriding.
107
+ - **Failed multi-element encodes** — `encode_session` now also reverses
108
+ ref-count increments it made on pre-existing containers, and a failed
109
+ first-time store cleans up the just-written binding `obj:`/`raw:`/`ref:`
110
+ keys, so a failed encode no longer leaves phantom referrers or orphan
111
+ metadata.
112
+ - **Stale-handle mutations** — every container mutator now runs a
113
+ `_check_alive()` liveness guard *before* its first Redis write, so a
114
+ handle whose object has been deleted/expired raises `ObjectGoneError`
115
+ without first corrupting the `raw:` key.
116
+ - **Sliding-TTL performance characterization** — sliding refresh batches the
117
+ TTL re-apply into one pipeline per tree level (the load-bearing cost is the
118
+ per-child `HGETALL`), corrected in the Performance Guide.
119
+
120
+ ### Documentation
121
+
122
+ - New MkDocs site (Material theme) with full EN + Simplified-Chinese (ZH)
123
+ documentation: overview, API reference, lifecycle, locking, performance
124
+ guide, extensibility, pydantic/pandas support.
125
+ - Durable explicit-anchor scheme (`{ #id }` attributes) + a `mkdocs build
126
+ --strict` validation gate, so editing a heading never silently breaks an
127
+ in-page cross-reference.
128
+
129
+ [0.2.0]: https://github.com/LinnetCodes/gpdatacached/releases/tag/version-0.2.0
130
+
131
+ ## [0.1.0] — 2026-07-04
132
+
133
+ Initial public release.
134
+
135
+ Core typed cross-process data sharing and caching over Redis:
136
+
137
+ - `GPDCDomain` / `GPDCNamespace` / `GPDCDataObject` three-tier model.
138
+ - Typed scalars (int/float/str/bool/datetime/date/time/none/tuple) and live
139
+ containers (list/dict/set) with reference semantics — mutate in place, no
140
+ read-modify-write.
141
+ - Per-object lifecycle: `permanent` / `ttl` / `sliding-window` cache modes
142
+ with cascade propagation.
143
+ - Anonymous nested objects with reference counting and cascade delete.
144
+ - Opt-in distributed locking (`obj.lock()` / `try_lock()`) via
145
+ `SET NX EX` + `BLPOP` with Lua-atomic release.
146
+ - Background GC for orphaned/expired keys.
147
+ - Extensibility: `GPDCTypeRegistry`, codec/object ABCs, pandas
148
+ (`Series`/`DataFrame`) and pydantic support extensions.
149
+ - Strict config validation; `reset_domain_config` utility.
150
+
151
+ [0.1.0]: https://github.com/LinnetCodes/gpdatacached/releases/tag/version-0.1.0
@@ -1,6 +1,6 @@
1
- Metadata-Version: 2.4
1
+ Metadata-Version: 2.5
2
2
  Name: gpdatacached
3
- Version: 0.1.0
3
+ Version: 0.2.1
4
4
  Summary: Redis-based cross-process data sharing and caching library
5
5
  Project-URL: Homepage, https://github.com/linnetcodes/gpdatacached
6
6
  Project-URL: Documentation, https://linnetcodes.github.io/gpdatacached
@@ -41,7 +41,7 @@ Description-Content-Type: text/markdown
41
41
 
42
42
  [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](LICENSE)
43
43
  [![Python](https://img.shields.io/badge/python-3.10+-blue.svg)](https://www.python.org/)
44
- [![Development Status](https://img.shields.io/badge/status-alpha-orange.svg)](https://pypi.org/project/gpdatacached/)
44
+ [![Development Status](https://img.shields.io/badge/status-beta-blue.svg)](https://pypi.org/project/gpdatacached/)
45
45
 
46
46
  A Redis-based **cross-process data sharing and caching** library for Python. Any process that can reach the same Redis instance can share live, mutable, typed data structures — scalars, lists, dicts, sets — with reference semantics, lifecycle control, and optional distributed locking.
47
47
 
@@ -53,12 +53,13 @@ A Redis-based **cross-process data sharing and caching** library for Python. Any
53
53
 
54
54
  Sharing mutable state across processes is painful. `multiprocessing.Manager` is single-process-bottlenecked; raw Redis forces you to (de)serialize everything by hand and gives you no type safety, no reference tracking, no TTL cascades. `gpdatacached` gives you a dict-like API on top of Redis with:
55
55
 
56
- - **Typed objects** — store `int`, `str`, `datetime`, `list`, `dict`, `set`, … and get the same type back.
56
+ - **Typed objects** — store `int`, `decimal.Decimal`, `str`, `datetime`, `list`, `dict`, `set`, … and get the same type back.
57
57
  - **Live containers** — `ns["tags"].append("x")` mutates Redis directly; no read-modify-write races on the whole structure.
58
58
  - **Reference sharing** — bind the same container under multiple names inside a namespace; the data is stored once.
59
59
  - **Lifecycle control** — per-object `permanent` / `ttl` / `sliding-window` cache modes, with cascade propagation to owned subtrees.
60
60
  - **Background GC** — reclaims expired and orphaned anonymous objects.
61
61
  - **Opt-in distributed locking** — serialize writes across processes with `obj.lock()`.
62
+ - **URI-based access** — manage multiple domains from config and resolve `gpdc://{domain}/{namespace}/{name}` URIs to data objects via `GPDataCache`, including traversal into anonymous nested containers.
62
63
  - **Optional extensions** — cache [pydantic](https://docs.pydantic.dev/) `BaseModel` records and [pandas](https://pandas.pydata.org/) `Series` / `DataFrame` (see [Extensions](#extensions)).
63
64
 
64
65
  ---
@@ -89,7 +90,7 @@ config = GPDCDomainConfig(
89
90
  redis_port=6379,
90
91
  redis_password="secret",
91
92
  )
92
- domain = GPDCDomain("mydomain", config)
93
+ domain = GPDCDomain(config, name="mydomain")
93
94
  ns = domain.ensure_namespace("analytics")
94
95
 
95
96
  # Scalars read back as native Python values.
@@ -104,7 +105,7 @@ assert ns["tags"].value == ["b", "c", "d"]
104
105
 
105
106
  # Lifecycle control.
106
107
  ns["temp"] = "x"
107
- ns.get_object("temp").expire_in(60) # requires cache_mode="ttl"
108
+ ns.get_object("temp").update_cache_mode_and_ttl("ttl", 60) # permanent → ttl, expires in 60s
108
109
 
109
110
  domain.close()
110
111
  ```
@@ -129,21 +130,21 @@ GPDCDomain ── GPDCNamespace ── GPDCDataObject (scalar | container)
129
130
 
130
131
  ## Documentation
131
132
 
132
- 📖 **[Full documentation index](./docs/index.md)** — the entry point to all guides and references below.
133
+ 📖 **[Full documentation index](./docs/en/index.md)** — the entry point to all guides and references below.
133
134
 
134
- - **[Overview](./docs/overview.md)** — design purpose, philosophy, and end-to-end architecture (start here to understand the library as a whole).
135
- - **[API Reference](./docs/api.md)** — complete public API reference.
136
- - **[Lifecycle Management](./docs/lifecycle.md)** — how object creation, expiry, refresh, and deletion work, including anonymous and reference objects (read this to set correct expectations).
137
- - **[Extensibility](./docs/extensibility.md)** — the type system explained, with worked examples for adding your own scalar and container types (codecs, object classes, registration).
138
- - **[Performance Guide](./docs/performance-guide.md)** — usage patterns that degrade performance (sliding TTL overuse, deep nesting, unnecessary GC/locking) and their recommended alternatives. Read before putting GPDC on a hot path.
139
- - **[Multi-Process Locking](./docs/locking.md)** — when to lock, performance impact, recommended usage, deadlock avoidance, and GC interaction.
135
+ - **[Overview](./docs/en/overview.md)** — design purpose, philosophy, and end-to-end architecture (start here to understand the library as a whole).
136
+ - **[API Reference](./docs/en/api.md)** — complete public API reference.
137
+ - **[Lifecycle Management](./docs/en/lifecycle.md)** — how object creation, expiry, refresh, and deletion work, including anonymous and reference objects (read this to set correct expectations).
138
+ - **[Extensibility](./docs/en/extensibility.md)** — the type system explained, with worked examples for adding your own scalar and container types (codecs, object classes, registration).
139
+ - **[Performance Guide](./docs/en/performance-guide.md)** — usage patterns that degrade performance (sliding TTL overuse, deep nesting, unnecessary GC/locking) and their recommended alternatives. Read before putting GPDC on a hot path.
140
+ - **[Multi-Process Locking](./docs/en/locking.md)** — when to lock, performance impact, recommended usage, deadlock avoidance, and GC interaction.
140
141
 
141
142
  ## Extensions
142
143
 
143
144
  Optional built-in extensions under `gpdatacached.extensions`:
144
145
 
145
- - **[Pydantic Support](./docs/pydantic-support.md)** — cache pydantic `BaseModel` records. Two storage modes: scalar (atomic JSON) for scalar-only models, container (Redis hash) for models needing field-level access or nested `list`/`dict`/`set` fields. Pydantic is a core dependency; no extra install needed.
146
- - **[Pandas Support](./docs/pandas-support.md)** — cache pandas `Series` / `DataFrame` as live objects. Online selective accessors (`.iloc`, `.loc`, `df[col]`) for one-shot subset reads; `.value` for full restore; `extend` for appends. Requires `pip install "gpdatacached[pandas]"`.
146
+ - **[Pydantic Support](./docs/en/pydantic-support.md)** — cache pydantic `BaseModel` records. Two storage modes: scalar (atomic JSON) for scalar-only models, container (Redis hash) for models needing field-level access or nested `list`/`dict`/`set` fields. Pydantic is a core dependency; no extra install needed.
147
+ - **[Pandas Support](./docs/en/pandas-support.md)** — cache pandas `Series` / `DataFrame` as live objects. Online selective accessors (`.iloc`, `.loc`, `df[col]`) for one-shot subset reads; `.value` for full restore; `extend` for appends. Requires `pip install "gpdatacached[pandas]"`.
147
148
 
148
149
  ---
149
150
 
@@ -4,7 +4,7 @@
4
4
 
5
5
  [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](LICENSE)
6
6
  [![Python](https://img.shields.io/badge/python-3.10+-blue.svg)](https://www.python.org/)
7
- [![Development Status](https://img.shields.io/badge/status-alpha-orange.svg)](https://pypi.org/project/gpdatacached/)
7
+ [![Development Status](https://img.shields.io/badge/status-beta-blue.svg)](https://pypi.org/project/gpdatacached/)
8
8
 
9
9
  A Redis-based **cross-process data sharing and caching** library for Python. Any process that can reach the same Redis instance can share live, mutable, typed data structures — scalars, lists, dicts, sets — with reference semantics, lifecycle control, and optional distributed locking.
10
10
 
@@ -16,12 +16,13 @@ A Redis-based **cross-process data sharing and caching** library for Python. Any
16
16
 
17
17
  Sharing mutable state across processes is painful. `multiprocessing.Manager` is single-process-bottlenecked; raw Redis forces you to (de)serialize everything by hand and gives you no type safety, no reference tracking, no TTL cascades. `gpdatacached` gives you a dict-like API on top of Redis with:
18
18
 
19
- - **Typed objects** — store `int`, `str`, `datetime`, `list`, `dict`, `set`, … and get the same type back.
19
+ - **Typed objects** — store `int`, `decimal.Decimal`, `str`, `datetime`, `list`, `dict`, `set`, … and get the same type back.
20
20
  - **Live containers** — `ns["tags"].append("x")` mutates Redis directly; no read-modify-write races on the whole structure.
21
21
  - **Reference sharing** — bind the same container under multiple names inside a namespace; the data is stored once.
22
22
  - **Lifecycle control** — per-object `permanent` / `ttl` / `sliding-window` cache modes, with cascade propagation to owned subtrees.
23
23
  - **Background GC** — reclaims expired and orphaned anonymous objects.
24
24
  - **Opt-in distributed locking** — serialize writes across processes with `obj.lock()`.
25
+ - **URI-based access** — manage multiple domains from config and resolve `gpdc://{domain}/{namespace}/{name}` URIs to data objects via `GPDataCache`, including traversal into anonymous nested containers.
25
26
  - **Optional extensions** — cache [pydantic](https://docs.pydantic.dev/) `BaseModel` records and [pandas](https://pandas.pydata.org/) `Series` / `DataFrame` (see [Extensions](#extensions)).
26
27
 
27
28
  ---
@@ -52,7 +53,7 @@ config = GPDCDomainConfig(
52
53
  redis_port=6379,
53
54
  redis_password="secret",
54
55
  )
55
- domain = GPDCDomain("mydomain", config)
56
+ domain = GPDCDomain(config, name="mydomain")
56
57
  ns = domain.ensure_namespace("analytics")
57
58
 
58
59
  # Scalars read back as native Python values.
@@ -67,7 +68,7 @@ assert ns["tags"].value == ["b", "c", "d"]
67
68
 
68
69
  # Lifecycle control.
69
70
  ns["temp"] = "x"
70
- ns.get_object("temp").expire_in(60) # requires cache_mode="ttl"
71
+ ns.get_object("temp").update_cache_mode_and_ttl("ttl", 60) # permanent → ttl, expires in 60s
71
72
 
72
73
  domain.close()
73
74
  ```
@@ -92,21 +93,21 @@ GPDCDomain ── GPDCNamespace ── GPDCDataObject (scalar | container)
92
93
 
93
94
  ## Documentation
94
95
 
95
- 📖 **[Full documentation index](./docs/index.md)** — the entry point to all guides and references below.
96
+ 📖 **[Full documentation index](./docs/en/index.md)** — the entry point to all guides and references below.
96
97
 
97
- - **[Overview](./docs/overview.md)** — design purpose, philosophy, and end-to-end architecture (start here to understand the library as a whole).
98
- - **[API Reference](./docs/api.md)** — complete public API reference.
99
- - **[Lifecycle Management](./docs/lifecycle.md)** — how object creation, expiry, refresh, and deletion work, including anonymous and reference objects (read this to set correct expectations).
100
- - **[Extensibility](./docs/extensibility.md)** — the type system explained, with worked examples for adding your own scalar and container types (codecs, object classes, registration).
101
- - **[Performance Guide](./docs/performance-guide.md)** — usage patterns that degrade performance (sliding TTL overuse, deep nesting, unnecessary GC/locking) and their recommended alternatives. Read before putting GPDC on a hot path.
102
- - **[Multi-Process Locking](./docs/locking.md)** — when to lock, performance impact, recommended usage, deadlock avoidance, and GC interaction.
98
+ - **[Overview](./docs/en/overview.md)** — design purpose, philosophy, and end-to-end architecture (start here to understand the library as a whole).
99
+ - **[API Reference](./docs/en/api.md)** — complete public API reference.
100
+ - **[Lifecycle Management](./docs/en/lifecycle.md)** — how object creation, expiry, refresh, and deletion work, including anonymous and reference objects (read this to set correct expectations).
101
+ - **[Extensibility](./docs/en/extensibility.md)** — the type system explained, with worked examples for adding your own scalar and container types (codecs, object classes, registration).
102
+ - **[Performance Guide](./docs/en/performance-guide.md)** — usage patterns that degrade performance (sliding TTL overuse, deep nesting, unnecessary GC/locking) and their recommended alternatives. Read before putting GPDC on a hot path.
103
+ - **[Multi-Process Locking](./docs/en/locking.md)** — when to lock, performance impact, recommended usage, deadlock avoidance, and GC interaction.
103
104
 
104
105
  ## Extensions
105
106
 
106
107
  Optional built-in extensions under `gpdatacached.extensions`:
107
108
 
108
- - **[Pydantic Support](./docs/pydantic-support.md)** — cache pydantic `BaseModel` records. Two storage modes: scalar (atomic JSON) for scalar-only models, container (Redis hash) for models needing field-level access or nested `list`/`dict`/`set` fields. Pydantic is a core dependency; no extra install needed.
109
- - **[Pandas Support](./docs/pandas-support.md)** — cache pandas `Series` / `DataFrame` as live objects. Online selective accessors (`.iloc`, `.loc`, `df[col]`) for one-shot subset reads; `.value` for full restore; `extend` for appends. Requires `pip install "gpdatacached[pandas]"`.
109
+ - **[Pydantic Support](./docs/en/pydantic-support.md)** — cache pydantic `BaseModel` records. Two storage modes: scalar (atomic JSON) for scalar-only models, container (Redis hash) for models needing field-level access or nested `list`/`dict`/`set` fields. Pydantic is a core dependency; no extra install needed.
110
+ - **[Pandas Support](./docs/en/pandas-support.md)** — cache pandas `Series` / `DataFrame` as live objects. Online selective accessors (`.iloc`, `.loc`, `df[col]`) for one-shot subset reads; `.value` for full restore; `extend` for appends. Requires `pip install "gpdatacached[pandas]"`.
110
111
 
111
112
  ---
112
113
 
@@ -4,7 +4,7 @@
4
4
 
5
5
  [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](LICENSE)
6
6
  [![Python](https://img.shields.io/badge/python-3.10+-blue.svg)](https://www.python.org/)
7
- [![Development Status](https://img.shields.io/badge/status-alpha-orange.svg)](https://pypi.org/project/gpdatacached/)
7
+ [![Development Status](https://img.shields.io/badge/status-beta-blue.svg)](https://pypi.org/project/gpdatacached/)
8
8
 
9
9
  一个基于 Redis 的**跨进程数据共享与缓存** Python 库。任何能够访问同一 Redis 实例的进程,都可以共享活跃的、可变的、带类型的数据结构 —— 标量、list、dict、set —— 并具备引用语义、生命周期控制以及可选的分布式锁。
10
10
 
@@ -16,12 +16,13 @@
16
16
 
17
17
  跨进程共享可变状态一直很麻烦:`multiprocessing.Manager` 会形成单进程瓶颈;直接使用 Redis 又需要你手动序列化所有数据,且没有类型安全、没有引用追踪、没有 TTL 级联。`gpdatacached` 在 Redis 之上提供了一套类 dict 的 API,特性包括:
18
18
 
19
- - **带类型的对象** —— 存储 `int`、`str`、`datetime`、`list`、`dict`、`set` …,读取时得到相同类型。
19
+ - **带类型的对象** —— 存储 `int`、`decimal.Decimal`、`str`、`datetime`、`list`、`dict`、`set` …,读取时得到相同类型。
20
20
  - **活跃容器** —— `ns["tags"].append("x")` 直接修改 Redis,避免对整个结构的“读-改-写”竞态。
21
21
  - **引用共享** —— 在同一 namespace 内,同一个容器可绑定到多个名称;数据仅存储一份。
22
22
  - **生命周期控制** —— 每个对象可设置 `permanent` / `ttl` / `sliding`(滑动窗口)缓存模式,并将策略级联传播到所拥有的子树。
23
23
  - **后台 GC** —— 自动回收过期或成为孤儿的匿名对象。
24
24
  - **可选的分布式锁** —— 通过 `obj.lock()` 在多进程间串行化写入。
25
+ - **基于 URI 的访问** —— 通过 `GPDataCache` 从配置管理多个 domain,并将 `gpdc://{domain}/{namespace}/{name}` 形式的 URI 解析为数据对象,包括对匿名嵌套容器的遍历。
25
26
  - **可选扩展** —— 可缓存 [pydantic](https://docs.pydantic.dev/) `BaseModel` 记录与 [pandas](https://pandas.pydata.org/) `Series` / `DataFrame`(见[扩展](#扩展))。
26
27
 
27
28
  ---
@@ -52,7 +53,7 @@ config = GPDCDomainConfig(
52
53
  redis_port=6379,
53
54
  redis_password="secret",
54
55
  )
55
- domain = GPDCDomain("mydomain", config)
56
+ domain = GPDCDomain(config, name="mydomain")
56
57
  ns = domain.ensure_namespace("analytics")
57
58
 
58
59
  # 标量读取出来是原生 Python 值。
@@ -67,7 +68,7 @@ assert ns["tags"].value == ["b", "c", "d"]
67
68
 
68
69
  # 生命周期控制。
69
70
  ns["temp"] = "x"
70
- ns.get_object("temp").expire_in(60) # 要求 cache_mode="ttl"
71
+ ns.get_object("temp").update_cache_mode_and_ttl("ttl", 60) # permanent → ttl,60 秒后过期
71
72
 
72
73
  domain.close()
73
74
  ```
@@ -92,21 +93,21 @@ GPDCDomain ── GPDCNamespace ── GPDCDataObject (标量 | 容器)
92
93
 
93
94
  ## 文档
94
95
 
95
- 📖 **[完整文档索引](./docs/zh-CN/index.md)** —— 以下所有指南与参考的入口。
96
+ 📖 **[完整文档索引](./docs/zh/index.md)** —— 以下所有指南与参考的入口。
96
97
 
97
- - **[总体概览](./docs/zh-CN/overview.md)** —— 设计目的、设计理念与端到端整体架构(从这里开始,从整体上理解本库)。
98
- - **[API 参考](./docs/zh-CN/api.md)** —— 完整的公共 API 参考。
99
- - **[生命周期管理](./docs/zh-CN/lifecycle.md)** —— 对象的创建、过期、刷新与删除如何运作,含匿名对象与引用对象(阅读本文以建立合理预期)。
100
- - **[可扩展性](./docs/zh-CN/extensibility.md)** —— 类型系统详解,含添加自定义标量与容器类型的完整示例(codec、对象类、注册)。
101
- - **[性能指南](./docs/zh-CN/performance-guide.md)** —— 会拖累性能的用法(滥用 sliding TTL、过深嵌套、不必要地启用 GC/加锁)及其推荐替代。把 GPDC 放上热路径前必读。
102
- - **[多进程加锁](./docs/zh-CN/locking.md)** —— 何时需要加锁、性能影响、推荐用法、避免死锁的顺序以及与 GC 的交互。
98
+ - **[总体概览](./docs/zh/overview.md)** —— 设计目的、设计理念与端到端整体架构(从这里开始,从整体上理解本库)。
99
+ - **[API 参考](./docs/zh/api.md)** —— 完整的公共 API 参考。
100
+ - **[生命周期管理](./docs/zh/lifecycle.md)** —— 对象的创建、过期、刷新与删除如何运作,含匿名对象与引用对象(阅读本文以建立合理预期)。
101
+ - **[可扩展性](./docs/zh/extensibility.md)** —— 类型系统详解,含添加自定义标量与容器类型的完整示例(codec、对象类、注册)。
102
+ - **[性能指南](./docs/zh/performance-guide.md)** —— 会拖累性能的用法(滥用 sliding TTL、过深嵌套、不必要地启用 GC/加锁)及其推荐替代。把 GPDC 放上热路径前必读。
103
+ - **[多进程加锁](./docs/zh/locking.md)** —— 何时需要加锁、性能影响、推荐用法、避免死锁的顺序以及与 GC 的交互。
103
104
 
104
105
  ## 扩展
105
106
 
106
107
  `gpdatacached.extensions` 下的可选内建扩展:
107
108
 
108
- - **[Pydantic 支持](./docs/zh-CN/pydantic-support.md)** —— 缓存 pydantic `BaseModel` 记录。两种存储模式:标量模式(原子 JSON,适用于纯标量模型)和容器模式(Redis hash,适用于需要字段级访问或嵌套 `list`/`dict`/`set` 字段的模型)。pydantic 是核心依赖,无需额外安装。
109
- - **[Pandas 支持](./docs/zh-CN/pandas-support.md)** —— 将 pandas `Series` / `DataFrame` 缓存为活跃对象。在线选择性访问器(`.iloc`、`.loc`、`df[col]`)用于一次性子集读取;`.value` 用于完整还原;`extend` 用于追加。需要 `pip install "gpdatacached[pandas]"`。
109
+ - **[Pydantic 支持](./docs/zh/pydantic-support.md)** —— 缓存 pydantic `BaseModel` 记录。两种存储模式:标量模式(原子 JSON,适用于纯标量模型)和容器模式(Redis hash,适用于需要字段级访问或嵌套 `list`/`dict`/`set` 字段的模型)。pydantic 是核心依赖,无需额外安装。
110
+ - **[Pandas 支持](./docs/zh/pandas-support.md)** —— 将 pandas `Series` / `DataFrame` 缓存为活跃对象。在线选择性访问器(`.iloc`、`.loc`、`df[col]`)用于一次性子集读取;`.value` 用于完整还原;`extend` 用于追加。需要 `pip install "gpdatacached[pandas]"`。
110
111
 
111
112
  ---
112
113