Skip to content

feat: add Redis storage with sync and async support#448

Open
rprodhomme wants to merge 3 commits intokarpetrosyan:masterfrom
rprodhomme:feat/add-redis-storage
Open

feat: add Redis storage with sync and async support#448
rprodhomme wants to merge 3 commits intokarpetrosyan:masterfrom
rprodhomme:feat/add-redis-storage

Conversation

@rprodhomme
Copy link
Copy Markdown

@rprodhomme rprodhomme commented Mar 25, 2026

This PR aims at adding Redis storage for hishel. It probably lacks documentation and some things might be wrong but I thought it could help.

Add AsyncRedisStorage backend backed by redis-py (redis>=6.2.0, as that's the version hishel 0.1.5 supported).

The sync RedisStorage is auto-generated via scripts/unasync. Unit tests written for the async variant and auto-generated for sync, using fakeredis for in-memory Redis simulation.

Also updates scripts/unasync with Redis-specific substitution rules and file pairs, and adds redis as an optional project dependency.

resolves #425

Add AsyncRedisStorage backend backed by redis-py (redis>=6.2.0).
The sync RedisStorage is auto-generated via scripts/unasync.
Unit tests written for the async variant and auto-generated for sync,
using fakeredis for in-memory Redis simulation.

Also updates scripts/unasync with Redis-specific substitution rules
and file pairs, and adds redis as an optional project dependency.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@rprodhomme rprodhomme force-pushed the feat/add-redis-storage branch from b1c1ed2 to 6cae2e8 Compare March 25, 2026 14:52
@rprodhomme rprodhomme marked this pull request as ready for review March 25, 2026 14:54
@yanyongyu
Copy link
Copy Markdown
Contributor

Thanks for your implementation! It would be even better if the redis key common prefix could be customized.

@rprodhomme rprodhomme force-pushed the feat/add-redis-storage branch from 3e1a230 to c2624f6 Compare March 25, 2026 17:46
@rprodhomme
Copy link
Copy Markdown
Author

Thanks for your implementation! It would be even better if the redis key common prefix could be customized.

Makes sense, done in c2624f6 👌

done_key = f"{self._key_prefix}:stream_done:{pair_id.hex}"

async for chunk in stream:
await self._client.rpush(stream_key, chunk) # type: ignore[misc]
Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Doesn't the redis client have types? That'd be great if we could avoid this type ignores

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Redis client used to have mixed sync and async types, which forces us to either have this type ignores, or do a cast.

I've just seen it has been changed a few weeks ago with this PR: redis/redis-py#4005 and will be included in the next major version (release: https://github.com/redis/redis-py/releases/tag/v8.0.0b1)

Until then I don't think we have any other option but to have this type ignores or do a cast.

I've pushed a commit (35a0bed) for being consistent and having casts everywhere needed instead of type ignores.

…redis storages

redis-py types its async command methods as Union[Awaitable[T], T] (shared stubs
between sync and async clients), causing mypy[misc] when awaiting them. Replace
all 9 suppressions with explicit cast(Awaitable[T], ...) wrappers, consistent
with the cast pattern already used elsewhere in the file.

_sync_redis.py regenerated via scripts/unasync (Awaitable[T] → T substitution
is handled automatically).

Co-Authored-By: Claude <noreply@anthropic.com>
@rprodhomme rprodhomme requested a review from karpetrosyan April 9, 2026 09:31
entry_key = f"{self._key_prefix}:entry:{pair_id.hex}"
idx_key = f"{self._key_prefix}:idx:{key}"

if self._default_ttl is not None:
Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

note that we should respect hishel_ttl metadata as we do support for sqlite3 (

ttl = pair.request.metadata["hishel_ttl"] if "hishel_ttl" in pair.request.metadata else self.default_ttl
)

@karpetrosyan
Copy link
Copy Markdown
Owner

@rprodhomme can we also update the docs? storages.md file

@rprodhomme
Copy link
Copy Markdown
Author

@rprodhomme can we also update the docs? storages.md file

Sure, I'll do that, I just wanted to make sure we agreed on the code before writing the docs.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Support redis storage

3 participants