Skip to content

Commit 43f4f40

Browse files
fix(state): docstring accuracy + forward token_prefix through create_redis_state
- Corrects the observability example in RedisStateAdapter docstring (KEYS only returns key names, not values) - create_redis_state factory now accepts/forwards token_prefix to keep the factory and direct-instantiation paths aligned Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
1 parent f6dee27 commit 43f4f40

2 files changed

Lines changed: 44 additions & 4 deletions

File tree

src/chat_sdk/state/redis.py

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -368,8 +368,9 @@ class IoRedisStateAdapter(RedisStateAdapter):
368368
cross-runtime Redis sharing, not a security boundary.
369369
370370
Enables migrations like "drain TS, then flip Python on" with tokens
371-
identifiable by runtime-of-origin at a glance when inspecting
372-
``KEYS chat:lock:*`` in Redis.
371+
identifiable by runtime-of-origin at a glance — e.g. reading a lock's
372+
value via ``GET chat-sdk:lock:<thread_id>``, or in any logs/trace IDs
373+
where the token is surfaced on release/extend failures.
373374
"""
374375

375376
def __init__(self, *, token_prefix: str = "ioredis", **kwargs: Any) -> None:
@@ -386,10 +387,20 @@ def create_redis_state(
386387
url: str | None = None,
387388
client: Any | None = None,
388389
key_prefix: str = "chat-sdk",
390+
token_prefix: str = "redis",
389391
) -> RedisStateAdapter:
390392
"""Create a new Redis state adapter.
391393
392394
Either provide a ``url`` or an existing ``client``. If neither is given,
393395
the ``REDIS_URL`` environment variable is used.
396+
397+
``token_prefix`` defaults to ``"redis"`` to match
398+
:class:`RedisStateAdapter`'s default; pass ``"ioredis"`` (or instantiate
399+
:class:`IoRedisStateAdapter`) for TS interop.
394400
"""
395-
return RedisStateAdapter(url=url, client=client, key_prefix=key_prefix)
401+
return RedisStateAdapter(
402+
url=url,
403+
client=client,
404+
key_prefix=key_prefix,
405+
token_prefix=token_prefix,
406+
)

tests/test_state_redis.py

Lines changed: 30 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,11 @@
1313
import pytest
1414

1515
from chat_sdk.errors import StateNotConnectedError
16-
from chat_sdk.state.redis import IoRedisStateAdapter, RedisStateAdapter
16+
from chat_sdk.state.redis import (
17+
IoRedisStateAdapter,
18+
RedisStateAdapter,
19+
create_redis_state,
20+
)
1721
from chat_sdk.types import Lock, QueueEntry
1822

1923
# ============================================================================
@@ -689,6 +693,31 @@ async def test_extend_lock_works_with_custom_prefix(self, mock_redis: MockRedis)
689693
finally:
690694
await adapter.disconnect()
691695

696+
@pytest.mark.asyncio
697+
async def test_create_redis_state_default_token_prefix(self, mock_redis: MockRedis):
698+
"""create_redis_state() defaults to 'redis' token prefix (back-compat)."""
699+
adapter = create_redis_state(client=mock_redis, key_prefix="test")
700+
await adapter.connect()
701+
try:
702+
lock = await adapter.acquire_lock("thread-1", 30_000)
703+
assert lock is not None
704+
assert lock.token.startswith("redis_")
705+
assert not lock.token.startswith("ioredis_")
706+
finally:
707+
await adapter.disconnect()
708+
709+
@pytest.mark.asyncio
710+
async def test_create_redis_state_forwards_token_prefix(self, mock_redis: MockRedis):
711+
"""create_redis_state(token_prefix=...) forwards through to the adapter."""
712+
adapter = create_redis_state(client=mock_redis, key_prefix="test", token_prefix="ioredis")
713+
await adapter.connect()
714+
try:
715+
lock = await adapter.acquire_lock("thread-1", 30_000)
716+
assert lock is not None
717+
assert lock.token.startswith("ioredis_")
718+
finally:
719+
await adapter.disconnect()
720+
692721

693722
# ============================================================================
694723
# Lists: append with maxLength

0 commit comments

Comments
 (0)