11import os
2- from typing import Any , Dict , List , Optional , Type , TypeVar , Union , overload
3- from urllib .parse import urlparse
2+ from typing import Any , Dict , List , Optional , Tuple , Type , TypeVar , Union , overload
3+ from urllib .parse import parse_qs , urlencode , urlparse , urlunparse
44from warnings import warn
55
66from redis import Redis , RedisCluster
2121from redisvl .utils .utils import deprecated_function
2222
2323
24+ def _strip_cluster_from_url_and_kwargs (
25+ url : str , ** kwargs
26+ ) -> Tuple [str , Dict [str , Any ]]:
27+ """Remove 'cluster' parameter from URL query string and kwargs.
28+
29+ AsyncRedisCluster doesn't accept 'cluster' parameter, but it might be
30+ present in the URL or kwargs for compatibility with other Redis clients.
31+
32+ Args:
33+ url: Redis URL that might contain cluster parameter
34+ **kwargs: Keyword arguments that might contain cluster parameter
35+
36+ Returns:
37+ Tuple of (cleaned_url, cleaned_kwargs)
38+ """
39+ # Parse the URL
40+ parsed = urlparse (url )
41+
42+ # Parse query parameters
43+ query_params = parse_qs (parsed .query )
44+
45+ # Remove 'cluster' parameter if present
46+ query_params .pop ("cluster" , None )
47+
48+ # Reconstruct the query string
49+ new_query = urlencode (query_params , doseq = True )
50+
51+ # Reconstruct the URL
52+ cleaned_url = urlunparse (
53+ (
54+ parsed .scheme ,
55+ parsed .netloc ,
56+ parsed .path ,
57+ parsed .params ,
58+ new_query ,
59+ parsed .fragment ,
60+ )
61+ )
62+
63+ # Remove 'cluster' from kwargs if present
64+ cleaned_kwargs = kwargs .copy ()
65+ cleaned_kwargs .pop ("cluster" , None )
66+
67+ return cleaned_url , cleaned_kwargs
68+
69+
2470def compare_versions (version1 : str , version2 : str ):
2571 """
2672 Compare two Redis version strings numerically.
@@ -311,9 +357,17 @@ async def _get_aredis_connection(
311357 url , AsyncRedis , ** kwargs
312358 )
313359 elif is_cluster_url (url , ** kwargs ):
314- client = AsyncRedisCluster .from_url (url , ** kwargs )
360+ # Strip 'cluster' parameter as AsyncRedisCluster doesn't accept it
361+ cleaned_url , cleaned_kwargs = _strip_cluster_from_url_and_kwargs (
362+ url , ** kwargs
363+ )
364+ client = AsyncRedisCluster .from_url (cleaned_url , ** cleaned_kwargs )
315365 else :
316- client = AsyncRedis .from_url (url , ** kwargs )
366+ # Also strip cluster parameter for AsyncRedis to avoid connection issues
367+ cleaned_url , cleaned_kwargs = _strip_cluster_from_url_and_kwargs (
368+ url , ** kwargs
369+ )
370+ client = AsyncRedis .from_url (cleaned_url , ** cleaned_kwargs )
317371
318372 # Module validation removed - operations will fail naturally if modules are missing
319373 # Set client library name only
@@ -351,11 +405,23 @@ def get_async_redis_connection(
351405 DeprecationWarning ,
352406 )
353407 url = url or get_address_from_env ()
408+
354409 if url .startswith ("redis+sentinel" ):
355410 return RedisConnectionFactory ._redis_sentinel_client (
356411 url , AsyncRedis , ** kwargs
357412 )
358- return AsyncRedis .from_url (url , ** kwargs )
413+ elif is_cluster_url (url , ** kwargs ):
414+ # Strip 'cluster' parameter as AsyncRedisCluster doesn't accept it
415+ cleaned_url , cleaned_kwargs = _strip_cluster_from_url_and_kwargs (
416+ url , ** kwargs
417+ )
418+ return AsyncRedisCluster .from_url (cleaned_url , ** cleaned_kwargs )
419+ else :
420+ # Also strip cluster parameter for AsyncRedis to avoid connection issues
421+ cleaned_url , cleaned_kwargs = _strip_cluster_from_url_and_kwargs (
422+ url , ** kwargs
423+ )
424+ return AsyncRedis .from_url (cleaned_url , ** cleaned_kwargs )
359425
360426 @staticmethod
361427 def get_redis_cluster_connection (
@@ -373,7 +439,9 @@ def get_async_redis_cluster_connection(
373439 ) -> AsyncRedisCluster :
374440 """Creates and returns an asynchronous Redis client for a Redis cluster."""
375441 url = redis_url or get_address_from_env ()
376- return AsyncRedisCluster .from_url (url , ** kwargs )
442+ # Strip 'cluster' parameter as AsyncRedisCluster doesn't accept it
443+ cleaned_url , cleaned_kwargs = _strip_cluster_from_url_and_kwargs (url , ** kwargs )
444+ return AsyncRedisCluster .from_url (cleaned_url , ** cleaned_kwargs )
377445
378446 @staticmethod
379447 def sync_to_async_redis (
0 commit comments