Skip to content

Commit 9c957aa

Browse files
authored
Merge branch 'main' into FT-896
2 parents 67461ca + 67bd4ee commit 9c957aa

File tree

3 files changed

+189
-3
lines changed

3 files changed

+189
-3
lines changed

pyatlan/pkg/utils.py

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,6 @@ def get_client(impersonate_user_id: str) -> AtlanClient:
8282
elif user_id:
8383
LOGGER.info("No API token found, attempting to impersonate user: %s", user_id)
8484
client = AtlanClient(base_url=base_url, api_key="")
85-
client._user_id = user_id
8685
api_key = client.impersonate.user(user_id=user_id)
8786
else:
8887
LOGGER.info(
@@ -91,7 +90,10 @@ def get_client(impersonate_user_id: str) -> AtlanClient:
9190
client = AtlanClient(base_url=base_url, api_key="")
9291
api_key = client.impersonate.escalate()
9392

94-
return AtlanClient(base_url=base_url, api_key=api_key)
93+
client = AtlanClient(base_url=base_url, api_key=api_key)
94+
if user_id:
95+
client._user_id = user_id
96+
return client
9597

9698

9799
def set_package_ops(run_time_config: RuntimeConfig) -> AtlanClient:

tests/integration/custom_package_test.py

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,10 @@
66
import pytest
77

88
from pyatlan.client.atlan import AtlanClient
9+
from pyatlan.client.impersonate import ImpersonationClient
910
from pyatlan.pkg.models import CustomPackage, generate
1011
from pyatlan.pkg.ui import UIConfig, UIStep
11-
from pyatlan.pkg.utils import set_package_headers
12+
from pyatlan.pkg.utils import get_client, set_package_headers
1213
from pyatlan.pkg.widgets import TextInput
1314

1415

@@ -21,6 +22,9 @@ def mock_pkg_env():
2122
"X_ATLAN_AGENT_ID": "agent_id_value",
2223
"X_ATLAN_AGENT_PACKAGE_NAME": "package_name_value",
2324
"X_ATLAN_AGENT_WORKFLOW_ID": "workflow_id_value",
25+
"X_ATLAN_AGENT_WORKFLOW_ID": "workflow_id_value",
26+
"CLIENT_ID": "client_id_value",
27+
"CLIENT_SECRET": "client_secret_value",
2428
},
2529
clear=True,
2630
):
@@ -104,3 +108,16 @@ def test_set_package_headers(client: AtlanClient, mock_pkg_env):
104108
}
105109
mock_client.update_headers.assert_called_once_with(expected_headers)
106110
assert updated_client == mock_client
111+
112+
113+
@patch.object(ImpersonationClient, "user", return_value="some-api-key")
114+
def test_get_client_user_id_handling(
115+
mock_impersonate_client,
116+
mock_pkg_env,
117+
client: AtlanClient,
118+
):
119+
updated_client = get_client(impersonate_user_id="test-user-id")
120+
assert updated_client
121+
assert updated_client.base_url
122+
assert updated_client.api_key == "some-api-key"
123+
assert updated_client._user_id == "test-user-id"

tests/unit/test_client.py

Lines changed: 167 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -336,6 +336,97 @@ def test_append_terms_asset_retrieval_errors(
336336
)
337337

338338

339+
def test_append_with_valid_guid_and_no_terms_returns_asset():
340+
asset_type = Table
341+
table = Table()
342+
table.name = "table-test"
343+
table.qualified_name = "table_qn"
344+
345+
terms = []
346+
347+
with patch(
348+
"pyatlan.model.fluent_search.FluentSearch.execute"
349+
) as mock_execute, patch("pyatlan.client.asset.AssetClient.save") as mock_save:
350+
mock_execute.return_value.current_page = lambda: [table]
351+
352+
mock_save.return_value.assets_updated.return_value = [table]
353+
354+
client = AtlanClient()
355+
guid = "123"
356+
357+
asset = client.asset.append_terms(guid=guid, asset_type=asset_type, terms=terms)
358+
359+
assert asset == table
360+
assert asset.assigned_terms is None
361+
mock_execute.assert_called_once()
362+
mock_save.assert_called_once()
363+
364+
365+
def test_append_with_valid_guid_when_no_terms_present_returns_asset_with_given_terms():
366+
asset_type = Table
367+
table = Table()
368+
table.name = "table-test"
369+
table.qualified_name = "table_qn"
370+
371+
terms = [AtlasGlossaryTerm(qualified_name="term1")]
372+
373+
with patch(
374+
"pyatlan.model.fluent_search.FluentSearch.execute"
375+
) as mock_execute, patch("pyatlan.client.asset.AssetClient.save") as mock_save:
376+
mock_execute.return_value.current_page = lambda: [table]
377+
378+
def mock_save_side_effect(entity):
379+
entity.assigned_terms = terms
380+
return Mock(assets_updated=lambda asset_type: [entity])
381+
382+
mock_save.side_effect = mock_save_side_effect
383+
384+
client = AtlanClient()
385+
guid = "123"
386+
asset = client.asset.append_terms(guid=guid, asset_type=asset_type, terms=terms)
387+
388+
assert asset.assigned_terms == terms
389+
mock_execute.assert_called_once()
390+
mock_save.assert_called_once()
391+
392+
393+
def test_append_with_valid_guid_when_terms_present_returns_asset_with_combined_terms():
394+
asset_type = Table
395+
table = Table()
396+
table.name = "table-test"
397+
table.qualified_name = "table_qn"
398+
399+
exisiting_term = AtlasGlossaryTerm()
400+
table.attributes.meanings = [exisiting_term]
401+
402+
new_term = AtlasGlossaryTerm(qualified_name="new_term")
403+
terms = [new_term]
404+
405+
with patch(
406+
"pyatlan.model.fluent_search.FluentSearch.execute"
407+
) as mock_execute, patch("pyatlan.client.asset.AssetClient.save") as mock_save:
408+
mock_execute.return_value.current_page = lambda: [table]
409+
410+
def mock_save_side_effect(entity):
411+
entity.assigned_terms = table.attributes.meanings + terms
412+
return Mock(assets_updated=lambda asset_type: [entity])
413+
414+
mock_save.side_effect = mock_save_side_effect
415+
416+
client = AtlanClient()
417+
guid = "123"
418+
419+
asset = client.asset.append_terms(guid=guid, asset_type=asset_type, terms=terms)
420+
421+
updated_terms = asset.assigned_terms
422+
assert updated_terms is not None
423+
assert len(updated_terms) == 2
424+
assert exisiting_term in updated_terms
425+
assert new_term in updated_terms
426+
mock_execute.assert_called_once()
427+
mock_save.assert_called_once()
428+
429+
339430
@pytest.mark.parametrize(
340431
"guid, qualified_name, asset_type, assigned_terms, expected_message, expected_error",
341432
[
@@ -437,6 +528,40 @@ def test_replace_terms_asset_retrieval_errors(
437528
)
438529

439530

531+
def test_replace_terms():
532+
asset_type = Table
533+
table = Table()
534+
table.name = "table-test"
535+
table.qualified_name = "table_qn"
536+
537+
exisiting_term = AtlasGlossaryTerm()
538+
table.attributes.meanings = [exisiting_term]
539+
540+
terms = [AtlasGlossaryTerm(qualified_name="new_term")]
541+
542+
with patch(
543+
"pyatlan.model.fluent_search.FluentSearch.execute"
544+
) as mock_execute, patch("pyatlan.client.asset.AssetClient.save") as mock_save:
545+
mock_execute.return_value.current_page = lambda: [table]
546+
547+
def mock_save_side_effect(entity):
548+
entity.assigned_terms = terms
549+
return Mock(assets_updated=lambda asset_type: [entity])
550+
551+
mock_save.side_effect = mock_save_side_effect
552+
553+
client = AtlanClient()
554+
guid = "123"
555+
556+
asset = client.asset.replace_terms(
557+
guid=guid, asset_type=asset_type, terms=terms
558+
)
559+
560+
assert asset.assigned_terms == terms
561+
mock_execute.assert_called_once()
562+
mock_save.assert_called_once()
563+
564+
440565
@pytest.mark.parametrize(
441566
"guid, qualified_name, asset_type, assigned_terms, expected_message, expected_error",
442567
[
@@ -538,6 +663,48 @@ def test_remove_terms_asset_retrieval_errors(
538663
)
539664

540665

666+
def test_remove_with_valid_guid_when_terms_present_returns_asset_with_terms_removed():
667+
asset_type = Table
668+
table = Table()
669+
table.name = "table-test"
670+
table.qualified_name = "table_qn"
671+
672+
existing_term = AtlasGlossaryTerm(
673+
qualified_name="term_to_remove", guid="b4113341-251b-4adc-81fb-2420501c30e6"
674+
)
675+
other_term = AtlasGlossaryTerm(
676+
qualified_name="other_term", guid="b267858d-8316-4c41-a56a-6e9b840cef4a"
677+
)
678+
table.attributes.meanings = [existing_term, other_term]
679+
680+
with patch(
681+
"pyatlan.model.fluent_search.FluentSearch.execute"
682+
) as mock_execute, patch("pyatlan.client.asset.AssetClient.save") as mock_save:
683+
mock_execute.return_value.current_page = lambda: [table]
684+
685+
def mock_save_side_effect(entity):
686+
entity.assigned_terms = [
687+
t for t in table.attributes.meanings if t != existing_term
688+
]
689+
return Mock(assets_updated=lambda asset_type: [entity])
690+
691+
mock_save.side_effect = mock_save_side_effect
692+
693+
client = AtlanClient()
694+
guid = "123"
695+
696+
asset = client.asset.remove_terms(
697+
guid=guid, asset_type=asset_type, terms=[existing_term]
698+
)
699+
700+
updated_terms = asset.assigned_terms
701+
assert updated_terms is not None
702+
assert len(updated_terms) == 1
703+
assert other_term in updated_terms
704+
mock_execute.assert_called_once()
705+
mock_save.assert_called_once()
706+
707+
541708
def test_register_client_with_bad_parameter_raises_value_error(client):
542709
with pytest.raises(
543710
InvalidRequestError, match="client must be an instance of AtlanClient"

0 commit comments

Comments
 (0)