31
31
from pydantic .class_validators import validator
32
32
33
33
import datahub .emitter .mce_builder as builder
34
+ from datahub .api .entities .platformresource .platform_resource import (
35
+ PlatformResource ,
36
+ PlatformResourceKey ,
37
+ )
34
38
from datahub .emitter .mcp import MetadataChangeProposalWrapper
35
39
from datahub .emitter .mcp_builder import ContainerKey , create_embed_mcp
36
40
from datahub .ingestion .api .report import Report
106
110
from datahub .utilities .url_util import remove_port_from_url
107
111
108
112
CORPUSER_DATAHUB = "urn:li:corpuser:datahub"
109
-
113
+ LOOKER = "looker"
110
114
logger = logging .getLogger (__name__ )
111
115
112
116
@@ -1411,6 +1415,7 @@ class LookerDashboardSourceReport(StaleEntityRemovalSourceReport):
1411
1415
1412
1416
resolved_user_ids : int = 0
1413
1417
email_ids_missing : int = 0 # resolved users with missing email addresses
1418
+ looker_user_count : int = 0
1414
1419
1415
1420
_looker_api : Optional [LookerAPI ] = None
1416
1421
query_latency : Dict [str , datetime .timedelta ] = dataclasses_field (
@@ -1614,16 +1619,31 @@ def get_urn_dashboard_id(self):
1614
1619
class LookerUserRegistry :
1615
1620
looker_api_wrapper : LookerAPI
1616
1621
fields : str = "," .join (["id" , "email" , "display_name" , "first_name" , "last_name" ])
1622
+ _user_cache : Dict [str , LookerUser ] = {}
1617
1623
1618
- def __init__ (self , looker_api : LookerAPI ):
1624
+ def __init__ (self , looker_api : LookerAPI , report : LookerDashboardSourceReport ):
1619
1625
self .looker_api_wrapper = looker_api
1626
+ self .report = report
1627
+ self ._initialize_user_cache ()
1628
+
1629
+ def _initialize_user_cache (self ) -> None :
1630
+ raw_users : Sequence [User ] = self .looker_api_wrapper .all_users (
1631
+ user_fields = self .fields
1632
+ )
1633
+
1634
+ for raw_user in raw_users :
1635
+ looker_user = LookerUser .create_looker_user (raw_user )
1636
+ self ._user_cache [str (looker_user .id )] = looker_user
1620
1637
1621
1638
def get_by_id (self , id_ : str ) -> Optional [LookerUser ]:
1622
1639
if not id_ :
1623
1640
return None
1624
1641
1625
1642
logger .debug (f"Will get user { id_ } " )
1626
1643
1644
+ if str (id_ ) in self ._user_cache :
1645
+ return self ._user_cache .get (str (id_ ))
1646
+
1627
1647
raw_user : Optional [User ] = self .looker_api_wrapper .get_user (
1628
1648
str (id_ ), user_fields = self .fields
1629
1649
)
@@ -1632,3 +1652,35 @@ def get_by_id(self, id_: str) -> Optional[LookerUser]:
1632
1652
1633
1653
looker_user = LookerUser .create_looker_user (raw_user )
1634
1654
return looker_user
1655
+
1656
+ def to_platform_resource (
1657
+ self , platform_instance : Optional [str ]
1658
+ ) -> Iterable [MetadataChangeProposalWrapper ]:
1659
+ try :
1660
+ platform_resource_key = PlatformResourceKey (
1661
+ platform = LOOKER ,
1662
+ resource_type = "USER_ID_MAPPING" ,
1663
+ platform_instance = platform_instance ,
1664
+ primary_key = "" ,
1665
+ )
1666
+
1667
+ # Extract user email mappings
1668
+ user_email_cache = {
1669
+ user_id : user .email
1670
+ for user_id , user in self ._user_cache .items ()
1671
+ if user .email
1672
+ }
1673
+
1674
+ platform_resource = PlatformResource .create (
1675
+ key = platform_resource_key ,
1676
+ value = user_email_cache ,
1677
+ )
1678
+
1679
+ self .report .looker_user_count = len (user_email_cache )
1680
+ yield from platform_resource .to_mcps ()
1681
+
1682
+ except Exception as exc :
1683
+ self .report .warning (
1684
+ message = "Failed to generate platform resource for looker id mappings" ,
1685
+ exc = exc ,
1686
+ )
0 commit comments