diff --git a/nats/src/nats/js/kv.py b/nats/src/nats/js/kv.py index 537b4e8e..17c5b8ba 100644 --- a/nats/src/nats/js/kv.py +++ b/nats/src/nats/js/kv.py @@ -92,7 +92,7 @@ class Entry: value: Optional[bytes] revision: Optional[int] delta: Optional[int] - created: Optional[int] + created: Optional[datetime.datetime] operation: Optional[str] @dataclass(frozen=True) @@ -193,7 +193,7 @@ async def _get(self, key: str, revision: Optional[int] = None) -> Entry: value=msg.data, revision=msg.seq, delta=None, - created=None, + created=msg.time, operation=None, ) diff --git a/nats/tests/test_js.py b/nats/tests/test_js.py index fd5bc1ce..9638c3b9 100644 --- a/nats/tests/test_js.py +++ b/nats/tests/test_js.py @@ -3172,6 +3172,24 @@ async def error_handler(e): await nc.close() + @async_test + async def test_kv_get_returns_created_time(self): + # Regression for #398: KeyValue.get() must populate Entry.created with + # the message timestamp, over both the direct-get and API-get paths. + nc = await nats.connect() + js = nc.jetstream() + + for direct in (True, False): + bucket = f"CREATED_{'DIRECT' if direct else 'API'}" + kv = await js.create_key_value(bucket=bucket, direct=direct) + await kv.put("key", b"value") + + entry = await kv.get("key") + assert entry.created is not None, f"created missing (direct={direct})" + assert isinstance(entry.created, datetime.datetime) + + await nc.close() + @async_test async def test_not_kv(self): errors = []