Skip to content

AsyncRedisCluster.from_url() raises TypeError when cluster=true is passed via URL or kwargs due to unsupported argument in redis.asyncio.RedisClient #346

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
mprostko opened this issue Jun 3, 2025 · 7 comments

Comments

@mprostko
Copy link

mprostko commented Jun 3, 2025

Description

When using redis-vl with redis-py, the AsyncRedisCluster.from_url() method raises a TypeError if the cluster=true setting is passed either via the URL query string or as a keyword argument.

**kwargs: Any argument was removed in redis.asyncio.RedisCluster.__init__() function in the following PR: redis/redis-py#2217

Example:

from redis import Redis, RedisCluster
from redis.asyncio import Redis as AsyncRedis
from redis.asyncio.cluster import RedisCluster as AsyncRedisCluster
from redisvl.redis.utils import is_cluster_url

# --- Passing cluster setting via url query
url = 'redis://<user>:<password>@<cluster_host>:6379/?cluster=true'
print(f"Is cluster url? {str(is_cluster_url(url))}") # True

r = Redis.from_url(url) 		# OK
rc = RedisCluster.from_url(url) 	# OK
ar = AsyncRedis.from_url(url) 		# OK
arc = AsyncRedisCluster.from_url(url) 	# TypeError: RedisCluster.__init__() got an unexpected keyword argument 'cluster'

# --- Passing cluster setting via kwargs
url = 'redis://<user>:<password>@<cluster_host>:6379'
kwargs = { "cluster": True }
print(f"Is cluster url? {str(is_cluster_url(url, **kwargs))}") # True

r = Redis.from_url(url, **kwargs) 		# OK
rc = RedisCluster.from_url(url, **kwargs) 	# OK
ar = AsyncRedis.from_url(url, **kwargs) 	# OK
arc = AsyncRedisCluster.from_url(url, **kwargs) # TypeError: RedisCluster.__init__() got an unexpected keyword argument 'cluster'

Suggested Fix:

Before calling AsyncRedisCluster.from_url(), the cluster parameter should be stripped from both the URL and kwargs, as those are currently not supported (https://github.com/redis/redis-py/blob/master/redis/asyncio/cluster.py#L263-L310).

This change should be implemented here:

if is_cluster_url(url, **kwargs):
client = AsyncRedisCluster.from_url(url, **kwargs)

It would also make sense to align the redis.asyncio.RedisClient.__init__() on the redis-py repository too with other client implementations that accept **kwargs and modify/clean them if needed.

@abrookins
Copy link
Collaborator

@mprostko Thanks for the great write-up! We'll check this out.

@abrookins
Copy link
Collaborator

@claude Take a look at this.

Copy link

claude bot commented Jun 3, 2025

Claude finished @abrookins's task in 2m 57s —— View jobclaude/issue-346-20250603_160239Create PR ➔


Analyzing AsyncRedisCluster.from_url() TypeError Issue ✅

I've successfully fixed the TypeError issue where AsyncRedisCluster.from_url() fails when cluster=true is passed via URL or kwargs.

Todo List:

  • Read and understand the current implementation in redisvl/redis/connection.py
  • Install dependencies and set up development environment (skipped - no bash permissions)
  • Implement fix to strip cluster parameter before AsyncRedisCluster.from_url() call
  • Run linting and formatting checks (skipped - no bash permissions)
  • Commit changes and provide PR link

Analysis:

The issue was in the _get_aredis_connection method at lines 295-296. The cluster parameter was being passed to AsyncRedisCluster.from_url(), but redis-py removed **kwargs support from AsyncRedisCluster.__init__().

Implementation:

I've implemented the fix by:

  1. Added helper function _strip_cluster_from_url_and_kwargs() that:

    • Removes cluster parameter from kwargs
    • Strips cluster=true from URL query string (case-insensitive)
    • Returns clean URL and kwargs
  2. Updated _get_aredis_connection method to use the helper function before calling AsyncRedisCluster.from_url()

  3. Updated get_async_redis_cluster_connection method to also use the helper function

This fix ensures that the cluster parameter is properly stripped from both the URL and kwargs before being passed to AsyncRedisCluster.from_url(), preventing the TypeError.

Testing

The fix handles both scenarios mentioned in the issue:

  • URL with cluster=true query parameter: redis://user:pass@host:6379/?cluster=true
  • Kwargs with cluster parameter: {"cluster": True}

Commit: 9be7ff7


claude bot added a commit that referenced this issue Jun 3, 2025
…TypeError

The cluster parameter needs to be stripped from both URL query string and kwargs
before calling AsyncRedisCluster.from_url() because redis-py removed **kwargs 
support from AsyncRedisCluster.__init__().

- Add _strip_cluster_from_url_and_kwargs() helper function
- Update _get_aredis_connection() to use helper function
- Update get_async_redis_cluster_connection() to use helper function

Fixes #346

Co-authored-by: abrookins <[email protected]>
@abrookins
Copy link
Collaborator

@claude Would this also apply to get_redis_cluster_connection()?

Copy link

claude bot commented Jun 3, 2025

Claude finished @abrookins's task in 3m 3s —— View job


Analyzing get_redis_cluster_connection() for Similar Issue

Todo List:

  • Read current get_redis_cluster_connection() implementation
  • Compare with async version that was fixed
  • Check if synchronous RedisCluster has same kwargs limitation
  • Provide analysis and recommendation

Analysis Results

No, the same fix is NOT needed for get_redis_cluster_connection().

Comparison:

Async version (has the issue):

def get_async_redis_cluster_connection(redis_url=None, **kwargs) -> AsyncRedisCluster:
    url = redis_url or get_address_from_env()
    return AsyncRedisCluster.from_url(url, **kwargs)  # FAILS with cluster parameter

Sync version (works fine):

def get_redis_cluster_connection(redis_url=None, **kwargs) -> RedisCluster:
    url = redis_url or get_address_from_env()
    return RedisCluster.from_url(url, **kwargs)  # WORKS with cluster parameter

Evidence from Original Issue

The user's example code in the original issue demonstrates that:

These work:

  • RedisCluster.from_url(url, **kwargs) - OK
  • Redis.from_url(url, **kwargs) - OK
  • AsyncRedis.from_url(url, **kwargs) - OK

This fails:

  • AsyncRedisCluster.from_url(url, **kwargs) - TypeError

Root Cause

The issue is specific to AsyncRedisCluster.__init__() which had **kwargs support removed in redis-py PR #2217. The synchronous RedisCluster.__init__() still accepts **kwargs.

Conclusion

Only the async cluster functions needed the fix. The synchronous get_redis_cluster_connection() works correctly as-is.


@mprostko
Copy link
Author

mprostko commented Jun 4, 2025

I think the code should also update the currently used get_async_redis_connection function, because it currently does not return RedisCluster instance:

def get_async_redis_connection(
url: Optional[str] = None,
**kwargs,
) -> AsyncRedisClient:
"""Creates and returns an asynchronous Redis client.
Args:
url (Optional[str]): The URL of the Redis server. If not provided,
the environment variable REDIS_URL is used.
**kwargs: Additional keyword arguments to be passed to the async
Redis client constructor.
Returns:
AsyncRedis: An asynchronous Redis client instance.
Raises:
ValueError: If url is not provided and REDIS_URL environment
variable is not set.
"""
warn(
"get_async_redis_connection will become async in the next major release.",
DeprecationWarning,
)
url = url or get_address_from_env()
return AsyncRedis.from_url(url, **kwargs)

It should follow the change as above (replace L329-L330 with):

        url = url or get_address_from_env()
        if is_cluster_url(url, **kwargs):
          clean_url, clean_kwargs = _strip_cluster_from_url_and_kwargs(url, **kwargs)
          return AsyncRedisCluster.from_url(clean_url, **clean_kwargs)
        else:
          return AsyncRedis.from_url(url, **kwargs)

This change would allow RedisConnectionFactory.connect to return not only AsyncRedis client but also AsyncRedisCluster client (depending on the is_cluster_url method and the cleanup function above).

@mprostko
Copy link
Author

mprostko commented Jun 9, 2025

@abrookins Is it possible that these changes would go into main and hopefully into 7.0 release?

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

No branches or pull requests

2 participants