Skip to content

Commit 3a151b5

Browse files
committed
[fix] Fix certificate serialization, PopularityInsights deserialization, glossary UDR
- Change certificate_status/message defaults from None to UNSET in Asset so setting them to None is properly serialized (not omitted by omit_defaults) - Simplify PopularityInsights.record_last_timestamp type to Union[int, None] to fix msgspec type union restriction while keeping __post_init__ conversion - Construct PopularityInsights via kwargs (not post-init mutation) so datetime→epoch conversion runs during construction - Add msgspec.convert in test_sql_assets verify_popularity to handle dict responses from API for source_read_recent_user_record_list - Fix glossary _assert_relationship to check relationship_attributes dict Made-with: Cursor
1 parent f43bc59 commit 3a151b5

4 files changed

Lines changed: 37 additions & 47 deletions

File tree

pyatlan_v9/model/assets/asset.py

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
merge_relationships,
2525
)
2626
from pyatlan_v9.model.serde import Serde, get_serde
27+
from pyatlan_v9.model.structs import PopularityInsights
2728

2829
from .referenceable import (
2930
Referenceable,
@@ -82,10 +83,10 @@ class Asset(Referenceable):
8283
tenant_id: Union[str, None, UnsetType] = UNSET
8384
"""Name of the Atlan workspace in which this asset exists."""
8485

85-
certificate_status: Union[str, None, UnsetType] = None
86+
certificate_status: Union[str, None, UnsetType] = UNSET
8687
"""Status of this asset's certification."""
8788

88-
certificate_status_message: Union[str, None, UnsetType] = None
89+
certificate_status_message: Union[str, None, UnsetType] = UNSET
8990
"""Human-readable descriptive message used to provide further detail to certificateStatus."""
9091

9192
certificate_updated_by: Union[str, None, UnsetType] = UNSET
@@ -951,10 +952,10 @@ class AssetAttributes(ReferenceableAttributes):
951952
tenant_id: Union[str, None, UnsetType] = UNSET
952953
"""Name of the Atlan workspace in which this asset exists."""
953954

954-
certificate_status: Union[str, None, UnsetType] = None
955+
certificate_status: Union[str, None, UnsetType] = UNSET
955956
"""Status of this asset's certification."""
956957

957-
certificate_status_message: Union[str, None, UnsetType] = None
958+
certificate_status_message: Union[str, None, UnsetType] = UNSET
958959
"""Human-readable descriptive message used to provide further detail to certificateStatus."""
959960

960961
certificate_updated_by: Union[str, None, UnsetType] = UNSET

pyatlan_v9/model/structs.py

Lines changed: 6 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -565,20 +565,16 @@ class PopularityInsights(msgspec.Struct, kw_only=True, rename="camel", frozen=Fa
565565
record_compute_cost: Union[float, None] = None
566566
record_max_compute_cost: Union[float, None] = None
567567
record_compute_cost_unit: Union[SourceCostUnitType, None] = None
568-
record_last_timestamp: Union[int, date, datetime, None] = None
569-
"""Timestamp in epoch milliseconds, or date/datetime object that will be converted"""
568+
record_last_timestamp: Union[int, None] = None
569+
"""Timestamp in epoch milliseconds."""
570570
record_warehouse: Union[str, None] = None
571571

572572
def __post_init__(self):
573573
"""Convert date/datetime to epoch milliseconds if needed."""
574-
if isinstance(self.record_last_timestamp, (date, datetime)):
575-
if isinstance(self.record_last_timestamp, date) and not isinstance(
576-
self.record_last_timestamp, datetime
577-
):
578-
dt = datetime.combine(self.record_last_timestamp, datetime.min.time())
579-
else:
580-
dt = self.record_last_timestamp
581-
# Convert to epoch milliseconds
574+
if isinstance(self.record_last_timestamp, datetime):
575+
self.record_last_timestamp = int(self.record_last_timestamp.timestamp() * 1000)
576+
elif isinstance(self.record_last_timestamp, date):
577+
dt = datetime.combine(self.record_last_timestamp, datetime.min.time())
582578
self.record_last_timestamp = int(dt.timestamp() * 1000)
583579

584580

tests_v9/integration/glossary_test.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1114,8 +1114,9 @@ def _assert_relationship(relationship, expected_type_name, udr):
11141114
assert relationship
11151115
assert relationship.guid
11161116
assert relationship.type_name
1117-
if hasattr(relationship, "relationship_type"):
1118-
assert relationship.relationship_type == expected_type_name
1117+
ra = getattr(relationship, "relationship_attributes", None)
1118+
if ra and isinstance(ra, dict):
1119+
assert ra.get("typeName") == expected_type_name
11191120
elif hasattr(relationship, "attributes") and relationship.attributes:
11201121
assert relationship.attributes.relationship_attributes
11211122
assert (

tests_v9/integration/test_sql_assets.py

Lines changed: 23 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
import time
44
from typing import Callable, List, Optional, Type
55

6+
import msgspec
67
import pytest
78

89
from pyatlan_v9.client.atlan import AtlanClient
@@ -282,17 +283,16 @@ class TestTable:
282283

283284
@pytest.fixture(scope="module")
284285
def popularity_insight(self):
285-
popularity = PopularityInsights()
286-
popularity.record_user = "ernest"
287-
popularity.record_query_count = 1
288-
popularity.record_compute_cost = 1.00
289-
popularity.record_query_count = 2
290-
popularity.record_total_user_count = 3
291-
popularity.record_compute_cost_unit = SourceCostUnitType.BYTES
292-
popularity.record_last_timestamp = datetime.date.today()
293-
popularity.record_query_duration = 4
294-
popularity.record_warehouse = "there"
295-
return popularity
286+
return PopularityInsights(
287+
record_user="ernest",
288+
record_query_count=2,
289+
record_compute_cost=1.00,
290+
record_total_user_count=3,
291+
record_compute_cost_unit=SourceCostUnitType.BYTES,
292+
record_last_timestamp=datetime.datetime.now(),
293+
record_query_duration=4,
294+
record_warehouse="there",
295+
)
296296

297297
def test_create(
298298
self,
@@ -443,30 +443,22 @@ def test_source_read_recent_user_record_list_readable_with_fluent_search(
443443
self.verify_popularity(asset_popularity, popularity_insight)
444444

445445
def verify_popularity(self, asset_popularity, popularity_insight):
446-
assert popularity_insight.record_user == asset_popularity.record_user
447-
assert (
448-
popularity_insight.record_query_count == asset_popularity.record_query_count
449-
)
450-
assert (
451-
popularity_insight.record_compute_cost
452-
== asset_popularity.record_compute_cost
453-
)
454-
assert (
455-
popularity_insight.record_query_count == asset_popularity.record_query_count
456-
)
457-
assert (
458-
popularity_insight.record_total_user_count
459-
== asset_popularity.record_total_user_count
460-
)
446+
if isinstance(asset_popularity, dict):
447+
ap = msgspec.convert(asset_popularity, PopularityInsights)
448+
else:
449+
ap = asset_popularity
450+
assert popularity_insight.record_user == ap.record_user
451+
assert popularity_insight.record_query_count == ap.record_query_count
452+
assert popularity_insight.record_compute_cost == ap.record_compute_cost
453+
assert popularity_insight.record_query_count == ap.record_query_count
461454
assert (
462-
popularity_insight.record_compute_cost_unit
463-
== asset_popularity.record_compute_cost_unit
455+
popularity_insight.record_total_user_count == ap.record_total_user_count
464456
)
465457
assert (
466-
popularity_insight.record_query_duration
467-
== asset_popularity.record_query_duration
458+
popularity_insight.record_compute_cost_unit == ap.record_compute_cost_unit
468459
)
469-
assert popularity_insight.record_warehouse == asset_popularity.record_warehouse
460+
assert popularity_insight.record_query_duration == ap.record_query_duration
461+
assert popularity_insight.record_warehouse == ap.record_warehouse
470462

471463

472464
@pytest.mark.order(after="TestTable")

0 commit comments

Comments
 (0)