Skip to content

Commit acd5676

Browse files
authored
Merge pull request #577 from atlanhq/bump-to-release-6.0.0
[release] Bump to release `6.0.0`
2 parents ced105c + 884cff8 commit acd5676

File tree

3 files changed

+60
-2
lines changed

3 files changed

+60
-2
lines changed

HISTORY.md

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,59 @@
1+
## 6.0.0 (February 20, 2025)
2+
3+
### New Features
4+
5+
- Added a new connector type: `DOCUMENTDB`.
6+
7+
### Breaking Changes
8+
9+
- `DataProduct.get_assets()` method now raises `InvalidRequestError` when there is a missing value for `data_product_assets_d_s_l`, which is required to retrieve product assets.
10+
- Fixed SDK cache inconsistencies and unexpected behavior when running in concurrent/multi-threaded environments.
11+
12+
- Completely migrated from `AtlanClient._default_client` to `AtlanClient._current_client_tls` (which uses thread-local storage) to prevent sharing this class variable across multiple threads. Previously, it was shared across threads, resulting in inconsistent behavior in SDK caches.
13+
- Removed `cache_key` maintenance that used to maintain cache instances per Atlan client hash (`cache_key(base_url, api_key)`).
14+
- Now, all caches are bound to an `AtlanClient` instance, requiring the migration of all cache methods from class methods to instance methods.
15+
- Caches remain tracked even in cases of automatic token refresh for the client.
16+
17+
The following example illustrates the migration:
18+
19+
### Before
20+
21+
```py
22+
from pyatlan.cache.atlan_tag_cache import AtlanTagCache
23+
24+
c1 = AtlanClient()
25+
tag_id = AtlanTagCache.get_id_for_name(atlan_tag_name) # <-- Uses default client (c1), populates the caches (API call), and uses cache_key to store the cache instance
26+
tag_id = AtlanTagCache.get_id_for_name(atlan_tag_name) # Returns the ID from the cache (no API call)
27+
28+
c2 = AtlanClient()
29+
tag_id = AtlanTagCache.get_id_for_name(atlan_tag_name) # <-- Uses default client (c2), populates the caches, and uses cache_key to store the cache instance
30+
tag_id = AtlanTagCache.get_id_for_name(atlan_tag_name) # Returns the ID from the cache (no API call)
31+
32+
c1 = AtlanClient()
33+
tag_id = AtlanTagCache.get_id_for_name(atlan_tag_name) # <-- c1 initialized again. Since cache_key was used for c1 previously, the populated cache instance in memory is reused, avoiding an API call.
34+
tag_id = AtlanTagCache.get_id_for_name(atlan_tag_name) # Returns the ID from the cache (no API call)
35+
```
36+
37+
### Now (caches are bound to the client and maintained only upon the first client initialization):
38+
39+
```py
40+
c1 = AtlanClient()
41+
42+
tag_id = c1.atlan_tag_cache.get_id_for_name(atlan_tag_name) # <-- Uses default client (c1) and populates the caches (API call)
43+
44+
# OR
45+
tag_id = AtlanClient.get_current_client().atlan_tag_cache.get_id_for_name(atlan_tag_name) # <-- Uses default client (c1) and populates the caches (API call)
46+
tag_id = AtlanTagCache.get_id_for_name(atlan_tag_name) # Returns the ID from the cache (no API call)
47+
48+
c2 = AtlanClient()
49+
tag_id = c2.atlan_tag_cache.get_id_for_name(atlan_tag_name) # <-- Uses default client (c2) and populates the cache (API call)
50+
tag_id = c2.atlan_tag_cache.get_id_for_name(atlan_tag_name) # Returns the ID from the cache (no API call)
51+
52+
c1 = AtlanClient()
53+
tag_id = c1.atlan_tag_cache.get_id_for_name(atlan_tag_name) # <-- c1 initialized again. Since no cache_key is used in the latest approach, the previously populated cache instance is gone, and we need to make an API call to populate the cache for c1.
54+
tag_id = c1.atlan_tag_cache.get_id_for_name(atlan_tag_name) # Returns the ID from the cache (no API call)
55+
```
56+
157
## 5.0.2 (March 11, 2025)
258

359
### New Features

pyatlan/client/atlan.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -550,6 +550,7 @@ def _call_api_internal(
550550
== ErrorCode.AUTHENTICATION_PASSTHROUGH.http_error_code
551551
):
552552
try:
553+
LOGGER.debug("Starting 401 automatic token refresh.")
553554
return self._handle_401_token_refresh(
554555
api,
555556
path,
@@ -560,7 +561,7 @@ def _call_api_internal(
560561
)
561562
except Exception as e:
562563
LOGGER.debug(
563-
"Attempt to impersonate user %s failed, not retrying. Error: %s",
564+
"Failed to impersonate user %s for 401 token refresh. Not retrying. Error: %s",
564565
self._user_id,
565566
e,
566567
)
@@ -700,6 +701,7 @@ def _handle_401_token_refresh(
700701
self._has_retried_for_401 = True
701702
params["headers"]["authorization"] = f"Bearer {self.api_key}"
702703
self._request_params["headers"]["authorization"] = f"Bearer {self.api_key}"
704+
LOGGER.debug("Successfully completed 401 automatic token refresh.")
703705
return self._call_api_internal(
704706
api,
705707
path,

pyatlan/version.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
5.0.2
1+
6.0.0

0 commit comments

Comments
 (0)