Skip to content

Commit e018d8f

Browse files
[dagster-powerbi] Move contextual data from DagsterPowerBITranslator to PowerBITranslatorData
1 parent 78c3c38 commit e018d8f

File tree

3 files changed

+112
-29
lines changed

3 files changed

+112
-29
lines changed

python_modules/libraries/dagster-powerbi/dagster_powerbi/resource.py

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828
PowerBIContentData,
2929
PowerBIContentType,
3030
PowerBITagSet,
31+
PowerBITranslatorData,
3132
PowerBIWorkspaceData,
3233
)
3334

@@ -437,15 +438,22 @@ def fetch_state(self) -> PowerBIWorkspaceData:
437438
)
438439

439440
def defs_from_state(self, state: PowerBIWorkspaceData) -> Definitions:
440-
translator = self.translator_cls(context=state)
441+
translator = self.translator_cls()
441442

442443
all_external_data = [
443444
*state.dashboards_by_id.values(),
444445
*state.reports_by_id.values(),
445446
*state.semantic_models_by_id.values(),
446447
]
447448
all_external_asset_specs = [
448-
translator.get_asset_spec(content) for content in all_external_data
449+
translator.get_asset_spec(
450+
PowerBITranslatorData(
451+
content_type=content.content_type,
452+
properties=content.properties,
453+
workspace_data=state,
454+
)
455+
)
456+
for content in all_external_data
449457
]
450458

451459
return Definitions(assets=[*all_external_asset_specs])

python_modules/libraries/dagster-powerbi/dagster_powerbi/translator.py

Lines changed: 48 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,16 @@ class PowerBIContentData:
7878
properties: Dict[str, Any]
7979

8080

81+
@whitelist_for_serdes
82+
@record
83+
class PowerBITranslatorData(PowerBIContentData):
84+
"""A record representing a piece of content in PowerBI and the PowerBI workspace data.
85+
Includes the content's type and data as returned from the API.
86+
"""
87+
88+
workspace_data: "PowerBIWorkspaceData"
89+
90+
8191
@whitelist_for_serdes
8292
@record
8393
class PowerBIWorkspaceData:
@@ -155,14 +165,8 @@ class DagsterPowerBITranslator:
155165
Subclass this class to implement custom logic for each type of PowerBI content.
156166
"""
157167

158-
def __init__(self, context: PowerBIWorkspaceData):
159-
self._context = context
160-
161-
@property
162-
def workspace_data(self) -> PowerBIWorkspaceData:
163-
return self._context
164-
165168
def get_asset_spec(self, data: PowerBIContentData) -> AssetSpec:
169+
data = check.inst(data, PowerBITranslatorData)
166170
if data.content_type == PowerBIContentType.DASHBOARD:
167171
return self.get_dashboard_spec(data)
168172
elif data.content_type == PowerBIContentType.REPORT:
@@ -179,20 +183,28 @@ def get_asset_spec(self, data: PowerBIContentData) -> AssetSpec:
179183
additional_warn_text="Use `DagsterPowerBITranslator.get_asset_spec(...).key` instead",
180184
)
181185
def get_dashboard_asset_key(self, data: PowerBIContentData) -> AssetKey:
186+
data = check.inst(data, PowerBITranslatorData)
182187
return self.get_dashboard_spec(data).key
183188

184189
def get_dashboard_spec(self, data: PowerBIContentData) -> AssetSpec:
190+
data = check.inst(data, PowerBITranslatorData)
185191
dashboard_id = data.properties["id"]
186192
tile_report_ids = [
187193
tile["reportId"] for tile in data.properties["tiles"] if "reportId" in tile
188194
]
189195
report_keys = [
190-
self.get_report_spec(self.workspace_data.reports_by_id[report_id]).key
196+
self.get_report_spec(
197+
PowerBITranslatorData(
198+
content_type=data.workspace_data.reports_by_id[report_id].content_type,
199+
properties=data.workspace_data.reports_by_id[report_id].properties,
200+
workspace_data=data.workspace_data,
201+
)
202+
).key
191203
for report_id in tile_report_ids
192204
]
193205
url = (
194206
data.properties.get("webUrl")
195-
or f"https://app.powerbi.com/groups/{self.workspace_data.workspace_id}/dashboards/{dashboard_id}"
207+
or f"https://app.powerbi.com/groups/{data.workspace_data.workspace_id}/dashboards/{dashboard_id}"
196208
)
197209

198210
return AssetSpec(
@@ -213,18 +225,30 @@ def get_dashboard_spec(self, data: PowerBIContentData) -> AssetSpec:
213225
additional_warn_text="Use `DagsterPowerBITranslator.get_asset_spec(...).key` instead",
214226
)
215227
def get_report_asset_key(self, data: PowerBIContentData) -> AssetKey:
228+
data = check.inst(data, PowerBITranslatorData)
216229
return self.get_report_spec(data).key
217230

218231
def get_report_spec(self, data: PowerBIContentData) -> AssetSpec:
232+
data = check.inst(data, PowerBITranslatorData)
219233
report_id = data.properties["id"]
220234
dataset_id = data.properties.get("datasetId")
221235
dataset_data = (
222-
self.workspace_data.semantic_models_by_id.get(dataset_id) if dataset_id else None
236+
data.workspace_data.semantic_models_by_id.get(dataset_id) if dataset_id else None
237+
)
238+
dataset_key = (
239+
self.get_semantic_model_spec(
240+
PowerBITranslatorData(
241+
content_type=dataset_data.content_type,
242+
properties=dataset_data.properties,
243+
workspace_data=data.workspace_data,
244+
)
245+
).key
246+
if dataset_data
247+
else None
223248
)
224-
dataset_key = self.get_semantic_model_spec(dataset_data).key if dataset_data else None
225249
url = (
226250
data.properties.get("webUrl")
227-
or f"https://app.powerbi.com/groups/{self.workspace_data.workspace_id}/reports/{report_id}"
251+
or f"https://app.powerbi.com/groups/{data.workspace_data.workspace_id}/reports/{report_id}"
228252
)
229253

230254
owner = data.properties.get("createdBy")
@@ -243,18 +267,26 @@ def get_report_spec(self, data: PowerBIContentData) -> AssetSpec:
243267
additional_warn_text="Use `DagsterPowerBITranslator.get_asset_spec(...).key` instead",
244268
)
245269
def get_semantic_model_asset_key(self, data: PowerBIContentData) -> AssetKey:
270+
data = check.inst(data, PowerBITranslatorData)
246271
return self.get_semantic_model_spec(data).key
247272

248273
def get_semantic_model_spec(self, data: PowerBIContentData) -> AssetSpec:
274+
data = check.inst(data, PowerBITranslatorData)
249275
dataset_id = data.properties["id"]
250276
source_ids = data.properties.get("sources", [])
251277
source_keys = [
252-
self.get_data_source_spec(self.workspace_data.data_sources_by_id[source_id]).key
278+
self.get_data_source_spec(
279+
PowerBITranslatorData(
280+
content_type=data.workspace_data.data_sources_by_id[source_id].content_type,
281+
properties=data.workspace_data.data_sources_by_id[source_id].properties,
282+
workspace_data=data.workspace_data,
283+
)
284+
).key
253285
for source_id in source_ids
254286
]
255287
url = (
256288
data.properties.get("webUrl")
257-
or f"https://app.powerbi.com/groups/{self.workspace_data.workspace_id}/datasets/{dataset_id}"
289+
or f"https://app.powerbi.com/groups/{data.workspace_data.workspace_id}/datasets/{dataset_id}"
258290
)
259291

260292
for table in data.properties.get("tables", []):
@@ -297,9 +329,11 @@ def get_semantic_model_spec(self, data: PowerBIContentData) -> AssetSpec:
297329
additional_warn_text="Use `DagsterPowerBITranslator.get_asset_spec(...).key` instead",
298330
)
299331
def get_data_source_asset_key(self, data: PowerBIContentData) -> AssetKey:
332+
data = check.inst(data, PowerBITranslatorData)
300333
return self.get_data_source_spec(data).key
301334

302335
def get_data_source_spec(self, data: PowerBIContentData) -> AssetSpec:
336+
data = check.inst(data, PowerBITranslatorData)
303337
connection_name = (
304338
data.properties["connectionDetails"].get("path")
305339
or data.properties["connectionDetails"].get("url")

python_modules/libraries/dagster-powerbi/dagster_powerbi_tests/test_translator.py

Lines changed: 54 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -4,14 +4,25 @@
44
from dagster._core.definitions.metadata.table import TableColumn, TableSchema
55
from dagster._core.definitions.tags import build_kind_tag
66
from dagster_powerbi import DagsterPowerBITranslator
7-
from dagster_powerbi.translator import PowerBIContentData, PowerBIContentType, PowerBIWorkspaceData
7+
from dagster_powerbi.translator import (
8+
PowerBIContentData,
9+
PowerBIContentType,
10+
PowerBITranslatorData,
11+
PowerBIWorkspaceData,
12+
)
813

914

1015
def test_translator_dashboard_spec(workspace_data: PowerBIWorkspaceData) -> None:
1116
dashboard = next(iter(workspace_data.dashboards_by_id.values()))
1217

13-
translator = DagsterPowerBITranslator(workspace_data)
14-
asset_spec = translator.get_asset_spec(dashboard)
18+
translator = DagsterPowerBITranslator()
19+
asset_spec = translator.get_asset_spec(
20+
PowerBITranslatorData(
21+
content_type=dashboard.content_type,
22+
properties=dashboard.properties,
23+
workspace_data=workspace_data,
24+
)
25+
)
1526

1627
assert asset_spec.key.path == ["dashboard", "Sales_Returns_Sample_v201912"]
1728
deps = list(asset_spec.deps)
@@ -32,8 +43,14 @@ def test_translator_dashboard_spec(workspace_data: PowerBIWorkspaceData) -> None
3243
def test_translator_report_spec(workspace_data: PowerBIWorkspaceData) -> None:
3344
report = next(iter(workspace_data.reports_by_id.values()))
3445

35-
translator = DagsterPowerBITranslator(workspace_data)
36-
asset_spec = translator.get_asset_spec(report)
46+
translator = DagsterPowerBITranslator()
47+
asset_spec = translator.get_asset_spec(
48+
PowerBITranslatorData(
49+
content_type=report.content_type,
50+
properties=report.properties,
51+
workspace_data=workspace_data,
52+
)
53+
)
3754

3855
assert asset_spec.key.path == ["report", "Sales_Returns_Sample_v201912"]
3956
deps = list(asset_spec.deps)
@@ -55,8 +72,14 @@ def test_translator_report_spec(workspace_data: PowerBIWorkspaceData) -> None:
5572
def test_translator_semantic_model(workspace_data: PowerBIWorkspaceData) -> None:
5673
semantic_model = next(iter(workspace_data.semantic_models_by_id.values()))
5774

58-
translator = DagsterPowerBITranslator(workspace_data)
59-
asset_spec = translator.get_asset_spec(semantic_model)
75+
translator = DagsterPowerBITranslator()
76+
asset_spec = translator.get_asset_spec(
77+
PowerBITranslatorData(
78+
content_type=semantic_model.content_type,
79+
properties=semantic_model.properties,
80+
workspace_data=workspace_data,
81+
)
82+
)
6083

6184
assert asset_spec.key.path == ["semantic_model", "Sales_Returns_Sample_v201912"]
6285
deps = list(asset_spec.deps)
@@ -90,8 +113,14 @@ def test_translator_semantic_model(workspace_data: PowerBIWorkspaceData) -> None
90113
def test_translator_semantic_model_many_tables(second_workspace_data: PowerBIWorkspaceData) -> None:
91114
semantic_model = next(iter(second_workspace_data.semantic_models_by_id.values()))
92115

93-
translator = DagsterPowerBITranslator(second_workspace_data)
94-
asset_spec = translator.get_asset_spec(semantic_model)
116+
translator = DagsterPowerBITranslator()
117+
asset_spec = translator.get_asset_spec(
118+
PowerBITranslatorData(
119+
content_type=semantic_model.content_type,
120+
properties=semantic_model.properties,
121+
workspace_data=second_workspace_data,
122+
)
123+
)
95124
assert asset_spec.metadata == {
96125
"dagster-powerbi/web_url": MetadataValue.url(
97126
"https://app.powerbi.com/groups/a2122b8f-d7e1-42e8-be2b-a5e636ca3221/datasets/8e9c85a1-7b33-4223-9590-76bde70f9a20"
@@ -128,8 +157,14 @@ def get_asset_spec(self, data: PowerBIContentData) -> AssetSpec:
128157
def test_translator_custom_metadata(workspace_data: PowerBIWorkspaceData) -> None:
129158
dashboard = next(iter(workspace_data.dashboards_by_id.values()))
130159

131-
translator = MyCustomTranslator(workspace_data)
132-
asset_spec = translator.get_asset_spec(dashboard)
160+
translator = MyCustomTranslator()
161+
asset_spec = translator.get_asset_spec(
162+
PowerBITranslatorData(
163+
content_type=dashboard.content_type,
164+
properties=dashboard.properties,
165+
workspace_data=workspace_data,
166+
)
167+
)
133168

134169
assert "custom" in asset_spec.metadata
135170
assert asset_spec.metadata["custom"] == "metadata"
@@ -153,8 +188,14 @@ def test_translator_report_spec_no_dataset(workspace_data: PowerBIWorkspaceData)
153188
},
154189
)
155190

156-
translator = DagsterPowerBITranslator(workspace_data)
157-
asset_spec = translator.get_asset_spec(report_no_dataset)
191+
translator = DagsterPowerBITranslator()
192+
asset_spec = translator.get_asset_spec(
193+
PowerBITranslatorData(
194+
content_type=report_no_dataset.content_type,
195+
properties=report_no_dataset.properties,
196+
workspace_data=workspace_data,
197+
)
198+
)
158199

159200
assert asset_spec.key.path == ["report", "Sales_Returns_Sample_v201912"]
160201
deps = list(asset_spec.deps)

0 commit comments

Comments
 (0)