From 2492c4b007a146814eee88b5b74dbbc3277b7554 Mon Sep 17 00:00:00 2001 From: Yulin Li Date: Mon, 4 Nov 2024 10:08:57 +0800 Subject: [PATCH] async CredentialProvider --- redis/asyncio/client.py | 2 +- redis/asyncio/cluster.py | 2 +- redis/asyncio/connection.py | 7 +++++-- redis/asyncio/credentials.py | 26 ++++++++++++++++++++++++++ 4 files changed, 33 insertions(+), 4 deletions(-) create mode 100644 redis/asyncio/credentials.py diff --git a/redis/asyncio/client.py b/redis/asyncio/client.py index 9508849703..1407dc3343 100644 --- a/redis/asyncio/client.py +++ b/redis/asyncio/client.py @@ -38,6 +38,7 @@ SSLConnection, UnixDomainSocketConnection, ) +from redis.asyncio.credentials import CredentialProvider from redis.asyncio.lock import Lock from redis.asyncio.retry import Retry from redis.client import ( @@ -52,7 +53,6 @@ AsyncSentinelCommands, list_or_args, ) -from redis.credentials import CredentialProvider from redis.exceptions import ( ConnectionError, ExecAbortError, diff --git a/redis/asyncio/cluster.py b/redis/asyncio/cluster.py index 4e82e5448f..f5a1621826 100644 --- a/redis/asyncio/cluster.py +++ b/redis/asyncio/cluster.py @@ -27,6 +27,7 @@ ) from redis.asyncio.client import ResponseCallbackT from redis.asyncio.connection import Connection, DefaultParser, SSLConnection, parse_url +from redis.asyncio.credentials import CredentialProvider from redis.asyncio.lock import Lock from redis.asyncio.retry import Retry from redis.backoff import default_backoff @@ -44,7 +45,6 @@ ) from redis.commands import READ_COMMANDS, AsyncRedisClusterCommands from redis.crc import REDIS_CLUSTER_HASH_SLOTS, key_slot -from redis.credentials import CredentialProvider from redis.exceptions import ( AskError, BusyLoadingError, diff --git a/redis/asyncio/connection.py b/redis/asyncio/connection.py index ddbd22c95d..3f533d2265 100644 --- a/redis/asyncio/connection.py +++ b/redis/asyncio/connection.py @@ -36,10 +36,13 @@ else: from async_timeout import timeout as async_timeout +from redis.asyncio.credentials import ( + CredentialProvider, + UsernamePasswordCredentialProvider, +) from redis.asyncio.retry import Retry from redis.backoff import NoBackoff from redis.connection import DEFAULT_RESP_VERSION -from redis.credentials import CredentialProvider, UsernamePasswordCredentialProvider from redis.exceptions import ( AuthenticationError, AuthenticationWrongNumberOfArgsError, @@ -333,7 +336,7 @@ async def on_connect(self) -> None: self.credential_provider or UsernamePasswordCredentialProvider(self.username, self.password) ) - auth_args = cred_provider.get_credentials() + auth_args = await cred_provider.get_credentials() # if resp version is specified and we have auth args, # we need to send them via HELLO if auth_args and self.protocol not in [2, "2"]: diff --git a/redis/asyncio/credentials.py b/redis/asyncio/credentials.py new file mode 100644 index 0000000000..c7282cfaf2 --- /dev/null +++ b/redis/asyncio/credentials.py @@ -0,0 +1,26 @@ +from typing import Optional, Tuple, Union + + +class CredentialProvider: + """ + Credentials Provider. + """ + + async def get_credentials(self) -> Union[Tuple[str], Tuple[str, str]]: + raise NotImplementedError("get_credentials must be implemented") + + +class UsernamePasswordCredentialProvider(CredentialProvider): + """ + Simple implementation of CredentialProvider that just wraps static + username and password. + """ + + def __init__(self, username: Optional[str] = None, password: Optional[str] = None): + self.username = username or "" + self.password = password or "" + + async def get_credentials(self): + if self.username: + return self.username, self.password + return (self.password,)