Skip to content

Commit bb59d97

Browse files
refactor: simplify exception class with kw_only=True and remove post_init
Co-Authored-By: Aaron <AJ> Steers <[email protected]>
1 parent aeae3af commit bb59d97

File tree

3 files changed

+55
-48
lines changed

3 files changed

+55
-48
lines changed

airbyte_cdk/cli/airbyte_cdk/_secrets.py

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -134,7 +134,7 @@ def fetch(
134134
secret_count = 0
135135
failed_secrets = []
136136
failed_secret_urls = []
137-
137+
138138
for secret in secrets:
139139
secret_file_path = _get_secret_filepath(
140140
secrets_dir=secrets_dir,
@@ -145,7 +145,7 @@ def fetch(
145145
client=client,
146146
file_path=secret_file_path,
147147
)
148-
148+
149149
if error:
150150
secret_name = secret.name.split("/secrets/")[-1] # Removes project prefix
151151
failed_secrets.append(secret_name)
@@ -161,7 +161,7 @@ def fetch(
161161
f"No secrets found for connector: '{connector_name}'",
162162
err=True,
163163
)
164-
164+
165165
if failed_secrets:
166166
error_message = f"Failed to retrieve {len(failed_secrets)} secret(s)"
167167
click.echo(
@@ -302,31 +302,31 @@ def _write_secret_file(
302302
file_path: Path,
303303
) -> Optional[str]:
304304
"""Write the most recent enabled version of a secret to a file.
305-
305+
306306
Lists all enabled versions of the secret and selects the most recent one.
307307
Returns an error message if no enabled versions are found.
308-
308+
309309
Args:
310310
secret: The secret to write to a file
311311
client: The Secret Manager client
312312
file_path: The path to write the secret to
313-
313+
314314
Returns:
315315
Optional[str]: Error message if no enabled version is found, None otherwise
316316
"""
317317
# List all enabled versions of the secret
318318
response = client.list_secret_versions(
319319
request={"parent": secret.name, "filter": "state:ENABLED"}
320320
)
321-
321+
322322
versions = list(response)
323-
323+
324324
if not versions:
325325
secret_name = secret.name.split("/secrets/")[-1] # Removes project prefix
326326
return f"No enabled version found for secret: {secret_name}"
327-
327+
328328
enabled_version = versions[0]
329-
329+
330330
response = client.access_secret_version(name=enabled_version.name)
331331
file_path.write_text(response.payload.data.decode("UTF-8"))
332332
file_path.chmod(0o600) # default to owner read/write only

airbyte_cdk/cli/airbyte_cdk/exceptions.py

Lines changed: 3 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -7,21 +7,13 @@
77
from airbyte_cdk.sql.exceptions import AirbyteConnectorError
88

99

10-
@dataclass
10+
@dataclass(kw_only=True)
1111
class ConnectorSecretWithNoValidVersionsError(AirbyteConnectorError):
1212
"""Error when a connector secret has no valid versions."""
1313

1414
connector_name: str
15-
secret_names: List[str] = None # type: ignore
16-
connector_secret_urls: List[str] = None # type: ignore
17-
18-
def __post_init__(self):
19-
"""Initialize default values for lists."""
20-
super().__post_init__()
21-
if self.secret_names is None:
22-
self.secret_names = []
23-
if self.connector_secret_urls is None:
24-
self.connector_secret_urls = []
15+
secret_names: List[str]
16+
connector_secret_urls: List[str]
2517

2618
def __str__(self) -> str:
2719
"""Return a string representation of the exception."""

unit_tests/cli/airbyte_cdk/test_secrets.py

Lines changed: 42 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,9 @@ def test_write_secret_file_with_enabled_version(self, mock_client, mock_secret,
5656
# Verify that no error was returned
5757
assert result is None
5858

59-
def test_write_secret_file_with_no_enabled_versions(self, mock_client, mock_secret, mock_file_path):
59+
def test_write_secret_file_with_no_enabled_versions(
60+
self, mock_client, mock_secret, mock_file_path
61+
):
6062
# Mock list_secret_versions to return an empty list (no enabled versions)
6163
mock_client.list_secret_versions.return_value = []
6264

@@ -85,91 +87,104 @@ def test_write_secret_file_with_no_enabled_versions(self, mock_client, mock_secr
8587
@patch("airbyte_cdk.cli.airbyte_cdk._secrets._fetch_secret_handles")
8688
class TestFetch:
8789
def test_fetch_with_some_failed_secrets(
88-
self, mock_fetch_secret_handles, mock_get_secrets_dir, mock_resolve, mock_get_client, tmp_path
90+
self,
91+
mock_fetch_secret_handles,
92+
mock_get_secrets_dir,
93+
mock_resolve,
94+
mock_get_client,
95+
tmp_path,
8996
):
9097
# Setup mocks
9198
mock_client = MagicMock()
9299
mock_get_client.return_value = mock_client
93-
100+
94101
mock_resolve.return_value = ("test-connector", tmp_path)
95-
102+
96103
secrets_dir = tmp_path / "secrets"
97104
mock_get_secrets_dir.return_value = secrets_dir
98-
105+
99106
# Create two secrets, one that will succeed and one that will fail
100107
secret1 = MagicMock()
101108
secret1.name = "projects/test-project/secrets/test-secret-1"
102109
secret1.labels = {}
103-
110+
104111
secret2 = MagicMock()
105112
secret2.name = "projects/test-project/secrets/test-secret-2"
106113
secret2.labels = {}
107-
114+
108115
mock_fetch_secret_handles.return_value = [secret1, secret2]
109-
116+
110117
# Mock _write_secret_file to succeed for secret1 and fail for secret2
111-
with patch("airbyte_cdk.cli.airbyte_cdk._secrets._write_secret_file") as mock_write_secret_file:
118+
with patch(
119+
"airbyte_cdk.cli.airbyte_cdk._secrets._write_secret_file"
120+
) as mock_write_secret_file:
112121
mock_write_secret_file.side_effect = [
113122
None, # Success for secret1
114123
"No enabled version found for secret: test-secret-2", # Failure for secret2
115124
]
116-
125+
117126
# Call the function
118127
runner = CliRunner()
119128
result = runner.invoke(fetch)
120-
129+
121130
# Verify that _write_secret_file was called twice
122131
assert mock_write_secret_file.call_count == 2
123-
132+
124133
# Verify that the error message was printed
125134
assert "Failed to retrieve secret 'test-secret-2'" in result.output
126135
assert "Failed to retrieve 1 secret(s)" in result.output
127-
136+
128137
# Verify that the function did not raise an exception
129138
assert result.exit_code == 0
130-
139+
131140
def test_fetch_with_all_failed_secrets(
132-
self, mock_fetch_secret_handles, mock_get_secrets_dir, mock_resolve, mock_get_client, tmp_path
141+
self,
142+
mock_fetch_secret_handles,
143+
mock_get_secrets_dir,
144+
mock_resolve,
145+
mock_get_client,
146+
tmp_path,
133147
):
134148
# Setup mocks
135149
mock_client = MagicMock()
136150
mock_get_client.return_value = mock_client
137-
151+
138152
mock_resolve.return_value = ("test-connector", tmp_path)
139-
153+
140154
secrets_dir = tmp_path / "secrets"
141155
mock_get_secrets_dir.return_value = secrets_dir
142-
156+
143157
# Create two secrets that will both fail
144158
secret1 = MagicMock()
145159
secret1.name = "projects/test-project/secrets/test-secret-1"
146160
secret1.labels = {}
147-
161+
148162
secret2 = MagicMock()
149163
secret2.name = "projects/test-project/secrets/test-secret-2"
150164
secret2.labels = {}
151-
165+
152166
mock_fetch_secret_handles.return_value = [secret1, secret2]
153-
167+
154168
# Mock _write_secret_file to fail for both secrets
155-
with patch("airbyte_cdk.cli.airbyte_cdk._secrets._write_secret_file") as mock_write_secret_file:
169+
with patch(
170+
"airbyte_cdk.cli.airbyte_cdk._secrets._write_secret_file"
171+
) as mock_write_secret_file:
156172
mock_write_secret_file.side_effect = [
157173
"No enabled version found for secret: test-secret-1", # Failure for secret1
158174
"No enabled version found for secret: test-secret-2", # Failure for secret2
159175
]
160-
176+
161177
# Call the function
162178
runner = CliRunner()
163179
result = runner.invoke(fetch)
164-
180+
165181
# Verify that _write_secret_file was called twice
166182
assert mock_write_secret_file.call_count == 2
167-
183+
168184
# Verify that the error message was printed
169185
assert "Failed to retrieve secret 'test-secret-1'" in result.output
170186
assert "Failed to retrieve secret 'test-secret-2'" in result.output
171187
assert "Failed to retrieve 2 secret(s)" in result.output
172-
188+
173189
# Verify that the function raised an exception
174190
assert result.exit_code != 0
175-

0 commit comments

Comments
 (0)