Skip to content

Commit 0608127

Browse files
committed
Refactor SecretManager: Cleanup and Documentation
- Removed inline comments as requested - Updated docstrings for configure(), resolve(), and resolve_object() to Google Style Guide - Verified functionality with packages/core/tests/unit/test_secrets.py
1 parent 766f782 commit 0608127

1 file changed

Lines changed: 25 additions & 19 deletions

File tree

packages/core/src/nl2sql/secrets/manager.py

Lines changed: 25 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -57,13 +57,19 @@ def configure(self, configs: List[SecretProviderConfig]) -> None:
5757
logger.error(f"Failed to configure secret provider '{config.id}': {e}")
5858

5959
def resolve(self, secret_ref: str) -> str:
60-
"""
61-
Resolves a secret reference string.
60+
"""Resolves a secret reference string.
61+
6262
Format: ${provider_id:key}
63-
Examples:
64-
'${env:DB_PASS}' -> fetches DB_PASS from env
65-
'${azure-main:my-secret}' -> fetches my-secret from provider with id 'azure-main'
66-
'${aws-prod:my-secret}' -> fetches my-secret from provider with id 'aws-prod'
63+
64+
Args:
65+
secret_ref: The reference string to resolve.
66+
67+
Returns:
68+
str: The resolved secret value.
69+
70+
Raises:
71+
ValueError: If the format is invalid, provider is unknown, or secret
72+
is not found.
6773
"""
6874
cleaned_ref = secret_ref.replace('${', '').replace('}', '')
6975

@@ -82,50 +88,50 @@ def resolve(self, secret_ref: str) -> str:
8288

8389
raise ValueError(f"Secret not found: {secret_ref}")
8490

85-
return obj
86-
8791
def resolve_object(self, obj: Any) -> Any:
88-
"""
89-
Recursively resolves secret references in a generic object (Pydantic model, dict, list, str, SecretStr).
90-
Returns a new object with secrets resolved.
92+
"""Recursively resolves secret references in a generic object.
93+
94+
Traverses the object structure (Pydantic models, dicts, lists) and resolves
95+
any string values matching the secret pattern "${...}". Handles SecretStr
96+
by unwrapping, resolving, and re-wrapping.
97+
98+
Args:
99+
obj: The object to resolve secrets in. Can be a Pydantic model,
100+
dictionary, list, string, or SecretStr.
101+
102+
Returns:
103+
Any: A new object with all secret references resolved to their
104+
actual values.
91105
"""
92106
from pydantic import BaseModel, SecretStr
93107

94-
# Base case: String
95108
if isinstance(obj, str):
96109
if obj.startswith("${") and obj.endswith("}"):
97110
return self.resolve(obj)
98111
return obj
99112

100-
# Handle SecretStr
101113
if isinstance(obj, SecretStr):
102114
secret_val = obj.get_secret_value()
103115
if secret_val and secret_val.startswith("${") and secret_val.endswith("}"):
104116
resolved_val = self.resolve(secret_val)
105117
return SecretStr(resolved_val)
106118
return obj
107119

108-
# Pydantic Model
109120
if isinstance(obj, BaseModel):
110-
# Recursively resolve fields
111121
updates = {}
112-
# Access model_fields from the class, not the instance
113122
for field_name in type(obj).model_fields.keys():
114123
val = getattr(obj, field_name)
115124
resolved = self.resolve_object(val)
116-
# Only update if changed (optimization)
117125
if resolved != val:
118126
updates[field_name] = resolved
119127

120128
if updates:
121129
return obj.model_copy(update=updates)
122130
return obj
123131

124-
# Lists
125132
if isinstance(obj, list):
126133
return [self.resolve_object(item) for item in obj]
127134

128-
# Dicts
129135
if isinstance(obj, dict):
130136
return {k: self.resolve_object(v) for k, v in obj.items()}
131137

0 commit comments

Comments
 (0)