Mirrowel commited on
Commit
8a28cd0
·
1 Parent(s): 167dd9f

refactor(client): 🔨 make credentials optional and centralize validation

Browse files

The `RotatingClient` now accepts `None` for `api_keys` and `oauth_credentials` in its constructor, improving flexibility and allowing explicit omission of one credential type.

This commit centralizes the credential verification logic within the client's `__init__` method:
- Filters input dictionaries to remove providers associated with empty key lists.
- Implements a single unified check ensuring that at least one valid credential (API keys or OAuth paths) is provided and non-empty.
- Removes the now redundant credential check from `src/proxy_app/main.py`.

src/proxy_app/main.py CHANGED
@@ -175,9 +175,6 @@ async def lifespan(app: FastAPI):
175
  cred_manager = CredentialManager(os.environ)
176
  oauth_credentials = cred_manager.discover_and_prepare()
177
 
178
- if not api_keys and not oauth_credentials:
179
- raise ValueError("No provider API keys or OAuth credentials found.")
180
-
181
  if not skip_oauth_init and oauth_credentials:
182
  logging.info("Starting OAuth credential validation and deduplication...")
183
  processed_emails = {} # email -> {provider: path}
 
175
  cred_manager = CredentialManager(os.environ)
176
  oauth_credentials = cred_manager.discover_and_prepare()
177
 
 
 
 
178
  if not skip_oauth_init and oauth_credentials:
179
  logging.info("Starting OAuth credential validation and deduplication...")
180
  processed_emails = {} # email -> {provider: path}
src/rotator_library/client.py CHANGED
@@ -40,8 +40,8 @@ class RotatingClient:
40
  """
41
  def __init__(
42
  self,
43
- api_keys: Dict[str, List[str]],
44
- oauth_credentials: Dict[str, List[str]],
45
  max_retries: int = 2,
46
  usage_file_path: str = "key_usage.json",
47
  configure_logging: bool = True,
@@ -66,8 +66,16 @@ class RotatingClient:
66
  else:
67
  lib_logger.propagate = False
68
 
69
- if not api_keys:
70
- raise ValueError("API keys dictionary cannot be empty.")
 
 
 
 
 
 
 
 
71
  self.api_keys = api_keys
72
  self.credential_manager = CredentialManager(oauth_credentials)
73
  self.oauth_credentials = self.credential_manager.discover_and_prepare()
 
40
  """
41
  def __init__(
42
  self,
43
+ api_keys: Optional[Dict[str, List[str]]] = None,
44
+ oauth_credentials: Optional[Dict[str, List[str]]] = None,
45
  max_retries: int = 2,
46
  usage_file_path: str = "key_usage.json",
47
  configure_logging: bool = True,
 
66
  else:
67
  lib_logger.propagate = False
68
 
69
+ api_keys = api_keys or {}
70
+ oauth_credentials = oauth_credentials or {}
71
+
72
+ # Filter out providers with empty lists of credentials to ensure validity
73
+ api_keys = {provider: keys for provider, keys in api_keys.items() if keys}
74
+ oauth_credentials = {provider: paths for provider, paths in oauth_credentials.items() if paths}
75
+
76
+ if not api_keys and not oauth_credentials:
77
+ raise ValueError("No valid credentials provided. Either 'api_keys' or 'oauth_credentials' must be provided and non-empty.")
78
+
79
  self.api_keys = api_keys
80
  self.credential_manager = CredentialManager(oauth_credentials)
81
  self.oauth_credentials = self.credential_manager.discover_and_prepare()