Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
57 commits
Select commit Hold shift + click to select a range
0a8f770
Added StreamingCredentialProvider interface
vladvildanov Nov 19, 2024
8272c73
StreamingCredentialProvider support
vladvildanov Nov 27, 2024
7021c7b
Removed debug statement
vladvildanov Nov 27, 2024
400ba2a
Changed an approach to handle multiple connection pools
vladvildanov Dec 3, 2024
9561032
Added support for RedisCluster
vladvildanov Dec 3, 2024
dfcd488
Merge branch 'master' of github.com:redis/redis-py into vv-tba-support
vladvildanov Dec 4, 2024
833968d
Added dispatching of custom connection pool
vladvildanov Dec 4, 2024
3848b57
Extended CredentialProvider interface with async API
vladvildanov Dec 5, 2024
fa9bc3c
Changed method implementation
vladvildanov Dec 5, 2024
1776679
Added support for async API
vladvildanov Dec 9, 2024
87a1ffa
Removed unused lock
vladvildanov Dec 9, 2024
24714ae
Added async API
vladvildanov Dec 10, 2024
0327f36
Merge branch 'master' of github.com:redis/redis-py into vv-tba-support
vladvildanov Dec 10, 2024
6dae71b
Added support for single connection client
vladvildanov Dec 11, 2024
32fc374
Added core functionality
vladvildanov Dec 11, 2024
c2eef78
Revert debug call
vladvildanov Dec 11, 2024
1a1b211
Added package to setup.py
vladvildanov Dec 11, 2024
974ad4f
Added handling of in-use connections
vladvildanov Dec 12, 2024
66a53ea
Added testing
vladvildanov Dec 12, 2024
2cad8b0
Changed fixture name
vladvildanov Dec 12, 2024
7eb6600
Added marker
vladvildanov Dec 12, 2024
5facdae
Marked tests with correct annotations
vladvildanov Dec 13, 2024
ee2ce1a
Added better cancelation handling
vladvildanov Dec 13, 2024
835ede7
Removed another annotation
vladvildanov Dec 16, 2024
e14d680
Added support for async cluster
vladvildanov Dec 16, 2024
90204e7
Added pipeline tests
vladvildanov Dec 17, 2024
0de0f4d
Added support for Pub/Sub
vladvildanov Dec 17, 2024
46e2f94
Added support for Pub/Sub in cluster
vladvildanov Dec 18, 2024
5488726
Added an option to parse endpoint from endpoints.json
vladvildanov Dec 18, 2024
76e9dea
Updated package names and ENV variables
vladvildanov Dec 18, 2024
b697e27
Moved SSL certificates code into context of class
vladvildanov Dec 19, 2024
c24ab17
Fixed fixtures for async
vladvildanov Dec 19, 2024
68ebdee
Fixed test
vladvildanov Dec 19, 2024
98fa92f
Added better endpoitns handling
vladvildanov Dec 20, 2024
e84d77a
Changed variable names
vladvildanov Dec 20, 2024
4ccd380
Added logging
vladvildanov Dec 20, 2024
6e7ad70
Fixed broken tests
vladvildanov Dec 20, 2024
a9c200c
Added TODO for SSL tests
vladvildanov Dec 20, 2024
4527bf0
Added error propagation to main thread
vladvildanov Dec 20, 2024
ac1164e
Added single connection lock
vladvildanov Dec 20, 2024
96aeb68
Codestyle fixes
vladvildanov Dec 20, 2024
9cada36
Added missing methods
vladvildanov Dec 20, 2024
92356bb
Removed wrong annotation
vladvildanov Dec 20, 2024
bd89ff8
Fixed tests
vladvildanov Dec 20, 2024
fcfdcb8
Codestyle fix
vladvildanov Dec 20, 2024
063f0d5
Updated EventListener instantiation inside of class
vladvildanov Dec 20, 2024
b15358b
Fixed variable name
vladvildanov Dec 20, 2024
e691162
Fixed variable names
vladvildanov Dec 20, 2024
ce1e10c
Fixed variable name
vladvildanov Dec 20, 2024
5de68a6
Added EventException
vladvildanov Dec 20, 2024
2851a7c
Codestyle fix
vladvildanov Dec 20, 2024
87c4e7e
Removed redundant code
vladvildanov Dec 20, 2024
d890193
Codestyle fix
vladvildanov Dec 20, 2024
04f3511
Updated test case
vladvildanov Dec 20, 2024
67f1d13
Fixed tests
vladvildanov Dec 20, 2024
c3d099d
Fixed test
vladvildanov Dec 20, 2024
a7233b0
Removed dependency
vladvildanov Dec 20, 2024
File filter

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
Added missing methods
  • Loading branch information
vladvildanov committed Dec 20, 2024
commit 9cada367abf5f252b3a962f285c8576bbf98932b
2 changes: 0 additions & 2 deletions redis/asyncio/cluster.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
import random
import socket
import ssl
import threading
import warnings
from typing import (
Any,
Expand Down Expand Up @@ -49,7 +48,6 @@
from redis.credentials import CredentialProvider
from redis.event import (
AfterAsyncClusterInstantiationEvent,
AsyncAfterConnectionReleasedEvent,
EventDispatcher,
)
from redis.exceptions import (
Expand Down
2 changes: 0 additions & 2 deletions redis/asyncio/connection.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@
import socket
import ssl
import sys
import threading
import warnings
import weakref
from abc import abstractmethod
Expand Down Expand Up @@ -44,7 +43,6 @@
from redis.connection import DEFAULT_RESP_VERSION
from redis.credentials import (
CredentialProvider,
StreamingCredentialProvider,
UsernamePasswordCredentialProvider,
)
from redis.exceptions import (
Expand Down
3 changes: 2 additions & 1 deletion redis/auth/idp.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,8 @@

class IdentityProviderInterface(ABC):
"""
Receive a token from the identity provider. Receiving a token only works when being authenticated.
Receive a token from the identity provider.
Receiving a token only works when being authenticated.
"""

@abstractmethod
Expand Down
18 changes: 10 additions & 8 deletions redis/auth/token_manager.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
import threading
from datetime import datetime, timezone
from time import sleep
from typing import Any, Awaitable, Callable, Coroutine, Union
from typing import Any, Awaitable, Callable, Union

from redis.auth.err import RequestTokenErr, TokenRenewalErr
from redis.auth.idp import IdentityProviderInterface
Expand Down Expand Up @@ -78,9 +78,9 @@ def __init__(

def get_expiration_refresh_ratio(self) -> float:
"""
Represents the ratio of a token's lifetime at which a refresh should be triggered.
For example, a value of 0.75 means the token should be refreshed when 75% of its
lifetime has elapsed (or when 25% of its lifetime remains).
Represents the ratio of a token's lifetime at which a refresh should be triggered. # noqa: E501
For example, a value of 0.75 means the token should be refreshed
when 75% of its lifetime has elapsed (or when 25% of its lifetime remains).

:return: float
"""
Expand All @@ -89,9 +89,10 @@ def get_expiration_refresh_ratio(self) -> float:

def get_lower_refresh_bound_millis(self) -> int:
"""
Represents the minimum time in milliseconds before token expiration to trigger a refresh, in milliseconds.
This value sets a fixed lower bound for when a token refresh should occur, regardless
of the token's total lifetime.
Represents the minimum time in milliseconds before token expiration
to trigger a refresh, in milliseconds.
This value sets a fixed lower bound for when a token refresh should occur,
regardless of the token's total lifetime.
If set to 0 there will be no lower bound and the refresh will be triggered
based on the expirationRefreshRatio only.

Expand All @@ -101,7 +102,8 @@ def get_lower_refresh_bound_millis(self) -> int:

def get_token_request_execution_timeout_in_ms(self) -> int:
"""
Represents the maximum time in milliseconds to wait for a token request to complete.
Represents the maximum time in milliseconds to wait
for a token request to complete.

:return: int
"""
Expand Down
1 change: 0 additions & 1 deletion redis/client.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import asyncio
import copy
import re
import threading
Expand Down
1 change: 0 additions & 1 deletion redis/cluster.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@
AfterPubSubConnectionInstantiationEvent,
ClientType,
EventDispatcher,
EventDispatcherInterface,
)
from redis.exceptions import (
AskError,
Expand Down
14 changes: 12 additions & 2 deletions redis/connection.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,13 +26,11 @@
from .backoff import NoBackoff
from .credentials import (
CredentialProvider,
StreamingCredentialProvider,
UsernamePasswordCredentialProvider,
)
from .event import (
AfterConnectionReleasedEvent,
EventDispatcher,
EventDispatcherInterface,
)
from .exceptions import (
AuthenticationError,
Expand Down Expand Up @@ -790,6 +788,7 @@ def __init__(
self.retry = self._conn.retry
self.host = self._conn.host
self.port = self._conn.port
self.credential_provider = conn.credential_provider
self._pool_lock = pool_lock
self._cache = cache
self._cache_lock = threading.Lock()
Expand Down Expand Up @@ -973,6 +972,17 @@ def _on_invalidation_callback(self, data: List[Union[str, Optional[List[bytes]]]
else:
self._cache.delete_by_redis_keys(data[1])

def get_protocol(self):
return self._conn.get_protocol()

@property
def set_re_auth_token(self, token: TokenInterface):
self._conn.set_re_auth_token(token)

@property
def re_auth(self):
self._conn.re_auth()


class SSLConnection(Connection):
"""Manages SSL connections to and from the Redis server(s).
Expand Down
6 changes: 4 additions & 2 deletions redis/credentials.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,8 @@ def get_credentials(self) -> Union[Tuple[str], Tuple[str, str]]:

async def get_credentials_async(self) -> Union[Tuple[str], Tuple[str, str]]:
logger.warning(
"This method is added for backward compatability. Please override it in your implementation."
"This method is added for backward compatability. "
"Please override it in your implementation."
)
return self.get_credentials()

Expand All @@ -28,7 +29,8 @@ class StreamingCredentialProvider(CredentialProvider, ABC):
@abstractmethod
def on_next(self, callback: Callable[[Any], None]):
"""
Specifies the callback that should be invoked when the next credentials will be retrieved.
Specifies the callback that should be invoked
when the next credentials will be retrieved.

:param callback: Callback with
:return:
Expand Down
9 changes: 6 additions & 3 deletions redis/event.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,8 @@ async def listen(self, event: object):

class EventDispatcherInterface(ABC):
"""
Represents a dispatcher that dispatches events to listeners associated with given event.
Represents a dispatcher that dispatches events to listeners
associated with given event.
"""

@abstractmethod
Expand Down Expand Up @@ -132,7 +133,8 @@ class AfterSingleConnectionInstantiationEvent:
"""
Event that will be fired after single connection instances was created.

:param connection_lock: For sync client thread-lock should be provided, for async asyncio.Lock
:param connection_lock: For sync client thread-lock should be provided,
for async asyncio.Lock
"""

def __init__(
Expand Down Expand Up @@ -192,7 +194,8 @@ class AfterAsyncClusterInstantiationEvent:
"""
Event that will be fired after async cluster instance was created.

Async cluster doesn't use connection pools, instead ClusterNode object manages connections.
Async cluster doesn't use connection pools,
instead ClusterNode object manages connections.
"""

def __init__(
Expand Down
6 changes: 3 additions & 3 deletions tests/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@
from redis import Sentinel
from redis.auth.idp import IdentityProviderInterface
from redis.auth.token import JWToken
from redis.auth.token_manager import TokenManager
from redis.backoff import NoBackoff
from redis.cache import (
CacheConfig,
Expand All @@ -27,7 +26,7 @@
EvictionPolicy,
)
from redis.connection import Connection, ConnectionInterface, SSLConnection, parse_url
from redis.credentials import CredentialProvider, StreamingCredentialProvider
from redis.credentials import CredentialProvider
from redis.exceptions import RedisClusterException
from redis.retry import Retry
from redis_entraid.cred_provider import EntraIdCredentialsProvider, TokenAuthConfig
Expand Down Expand Up @@ -329,7 +328,8 @@ def skip_if_nocryptography() -> _TestDecorator:
#
# return pytest.mark.skipif(False, reason="Cryptography dependency found")
# except ImportError:
# TODO: Because JWT library depends on cryptography, now it's always true and tests should be fixed
# TODO: Because JWT library depends on cryptography,
# now it's always true and tests should be fixed
return pytest.mark.skipif(True, reason="No cryptography dependency")


Expand Down
3 changes: 1 addition & 2 deletions tests/test_asyncio/test_credentials.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,7 @@
from redis.credentials import CredentialProvider, UsernamePasswordCredentialProvider
from redis.exceptions import ConnectionError
from redis.utils import str_if_bytes
from redis_entraid.cred_provider import EntraIdCredentialsProvider, TokenAuthConfig
from redis_entraid.identity_provider import create_provider_from_service_principal
from redis_entraid.cred_provider import EntraIdCredentialsProvider
from tests.conftest import get_endpoint, skip_if_redis_enterprise
from tests.test_asyncio.conftest import get_credential_provider

Expand Down
12 changes: 8 additions & 4 deletions tests/test_auth/test_token_manager.py
Original file line number Diff line number Diff line change
Expand Up @@ -205,7 +205,8 @@ def on_next(token):
config = TokenManagerConfig(1, 0, 1000, retry_policy)
mgr = TokenManager(mock_provider, config)
mgr.start(mock_listener, skip_initial=True)
# Should be less than a 0.1, or it will be flacky due to additional token renewal.
# Should be less than a 0.1, or it will be flacky due to
# additional token renewal.
sleep(0.2)

assert len(tokens) == 2
Expand Down Expand Up @@ -246,7 +247,8 @@ async def on_next(token):
config = TokenManagerConfig(1, 0, 1000, retry_policy)
mgr = TokenManager(mock_provider, config)
await mgr.start_async(mock_listener, skip_initial=True)
# Should be less than a 0.1, or it will be flacky due to additional token renewal.
# Should be less than a 0.1, or it will be flacky
# due to additional token renewal.
await asyncio.sleep(0.2)

assert len(tokens) == 2
Expand Down Expand Up @@ -282,7 +284,8 @@ def on_next(token):
config = TokenManagerConfig(1, 0, 1000, retry_policy)
mgr = TokenManager(mock_provider, config)
mgr.start(mock_listener)
# Should be less than a 0.1, or it will be flacky due to additional token renewal.
# Should be less than a 0.1, or it will be flacky
# due to additional token renewal.
sleep(0.08)

assert mock_provider.request_token.call_count in {3, 4}
Expand Down Expand Up @@ -321,7 +324,8 @@ async def on_next(token):
config = TokenManagerConfig(1, 0, 1000, retry_policy)
mgr = TokenManager(mock_provider, config)
await mgr.start_async(mock_listener, block_for_initial=True)
# Should be less than a 0.1, or it will be flacky due to additional token renewal.
# Should be less than a 0.1, or it will be flacky
# due to additional token renewal.
await asyncio.sleep(0.08)

assert mock_provider.request_token.call_count in {3, 4}
Expand Down
11 changes: 1 addition & 10 deletions tests/test_credentials.py
Original file line number Diff line number Diff line change
@@ -1,31 +1,22 @@
import functools
import json
import os
import random
import string
import threading
from asyncio import Lock as AsyncioLock
from asyncio import sleep as asyncio_sleep
from time import sleep
from typing import Optional, Tuple, Union

import pytest
import redis
from mock.mock import Mock, call
from redis import AuthenticationError, DataError, Redis, ResponseError, asyncio
from redis.asyncio import Connection
from redis.asyncio import ConnectionPool as AsyncConnectionPool
from redis.asyncio import Redis as AsyncRedis
from redis.auth.err import RequestTokenErr
from redis.auth.idp import IdentityProviderInterface
from redis.backoff import NoBackoff
from redis.connection import ConnectionInterface, ConnectionPool
from redis.credentials import CredentialProvider, UsernamePasswordCredentialProvider
from redis.exceptions import ConnectionError, RedisError
from redis.retry import Retry
from redis.utils import str_if_bytes
from redis_entraid.cred_provider import EntraIdCredentialsProvider, TokenAuthConfig
from redis_entraid.identity_provider import create_provider_from_service_principal
from redis_entraid.cred_provider import EntraIdCredentialsProvider
from tests.conftest import (
_get_client,
get_credential_provider,
Expand Down
Loading