dagster-fivetran 0.28.2__py3-none-any.whl → 0.28.3__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -15,6 +15,7 @@ from dagster_fivetran.ops import (
15
15
  )
16
16
  from dagster_fivetran.resources import (
17
17
  FivetranResource as FivetranResource,
18
+ FivetranSyncConfig as FivetranSyncConfig,
18
19
  FivetranWorkspace as FivetranWorkspace,
19
20
  fivetran_resource as fivetran_resource,
20
21
  load_fivetran_asset_specs as load_fivetran_asset_specs,
@@ -13,6 +13,7 @@ import requests
13
13
  from dagster import (
14
14
  AssetExecutionContext,
15
15
  AssetMaterialization,
16
+ Config,
16
17
  Definitions,
17
18
  Failure,
18
19
  InitResourceContext,
@@ -928,6 +929,29 @@ class FivetranClient:
928
929
  return FivetranOutput(connector_details=final_details, schema_config=schema_config_details)
929
930
 
930
931
 
932
+ class FivetranSyncConfig(Config):
933
+ """Configuration for controlling Fivetran sync behavior.
934
+
935
+ Attributes:
936
+ resync: If True, performs a historical resync. If False, performs a normal sync.
937
+ resync_parameters: Optional parameters to control which tables to resync.
938
+ If not provided with resync=True, all tables will be resynced.
939
+ Example: {"schema_name": ["table1", "table2"], "another_schema": ["table3"]}
940
+ """
941
+
942
+ resync: bool = Field(
943
+ default=False,
944
+ description="Whether to perform a historical resync instead of a normal sync",
945
+ )
946
+ resync_parameters: Optional[dict[str, Any]] = Field(
947
+ default=None,
948
+ description=(
949
+ "Optional parameters to control which tables to resync. "
950
+ "If not provided with resync=True, all tables will be resynced."
951
+ ),
952
+ )
953
+
954
+
931
955
  class FivetranWorkspace(ConfigurableResource):
932
956
  """This class represents a Fivetran workspace and provides utilities
933
957
  to interact with Fivetran APIs.
@@ -1185,7 +1209,9 @@ class FivetranWorkspace(ConfigurableResource):
1185
1209
 
1186
1210
  @public
1187
1211
  def sync_and_poll(
1188
- self, context: AssetExecutionContext
1212
+ self,
1213
+ context: AssetExecutionContext,
1214
+ config: Optional[FivetranSyncConfig] = None,
1189
1215
  ) -> FivetranEventIterator[Union[AssetMaterialization, MaterializeResult]]:
1190
1216
  """Executes a sync and poll process to materialize Fivetran assets.
1191
1217
  This method can only be used in the context of an asset execution.
@@ -1193,14 +1219,74 @@ class FivetranWorkspace(ConfigurableResource):
1193
1219
  Args:
1194
1220
  context (AssetExecutionContext): The execution context
1195
1221
  from within `@fivetran_assets`.
1222
+ config (Optional[FivetranSyncConfig]): Optional configuration to control sync behavior.
1223
+ If config.resync is True, performs a historical resync instead of a normal sync.
1224
+ If config.resync_parameters is provided, only the specified tables will be resynced.
1196
1225
 
1197
1226
  Returns:
1198
1227
  Iterator[Union[AssetMaterialization, MaterializeResult]]: An iterator of MaterializeResult
1199
1228
  or AssetMaterialization.
1229
+
1230
+ Examples:
1231
+ Normal sync (without config):
1232
+
1233
+ .. code-block:: python
1234
+
1235
+ from dagster import AssetExecutionContext
1236
+ from dagster_fivetran import FivetranWorkspace, fivetran_assets
1237
+
1238
+ @fivetran_assets(connector_id="my_connector", workspace=fivetran_workspace)
1239
+ def my_fivetran_assets(context: AssetExecutionContext, fivetran: FivetranWorkspace):
1240
+ yield from fivetran.sync_and_poll(context=context)
1241
+
1242
+ Historical resync of specific tables (config passed at runtime):
1243
+
1244
+ .. code-block:: python
1245
+
1246
+ from dagster import AssetExecutionContext
1247
+ from dagster_fivetran import FivetranWorkspace, FivetranSyncConfig, fivetran_assets
1248
+
1249
+ @fivetran_assets(connector_id="my_connector", workspace=fivetran_workspace)
1250
+ def my_fivetran_assets(
1251
+ context: AssetExecutionContext,
1252
+ fivetran: FivetranWorkspace,
1253
+ config: FivetranSyncConfig,
1254
+ ):
1255
+ # When materializing, pass config with:
1256
+ # resync=True
1257
+ # resync_parameters={"schema_name": ["table1", "table2"]}
1258
+ yield from fivetran.sync_and_poll(context=context, config=config)
1259
+
1260
+ Full historical resync (config passed at runtime):
1261
+
1262
+ .. code-block:: python
1263
+
1264
+ from dagster import AssetExecutionContext
1265
+ from dagster_fivetran import FivetranWorkspace, FivetranSyncConfig, fivetran_assets
1266
+
1267
+ @fivetran_assets(connector_id="my_connector", workspace=fivetran_workspace)
1268
+ def my_fivetran_assets(
1269
+ context: AssetExecutionContext,
1270
+ fivetran: FivetranWorkspace,
1271
+ config: FivetranSyncConfig,
1272
+ ):
1273
+ # When materializing, pass config with resync=True to resync all tables
1274
+ yield from fivetran.sync_and_poll(context=context, config=config)
1200
1275
  """
1201
- return FivetranEventIterator(
1202
- events=self._sync_and_poll(context=context), fivetran_workspace=self, context=context
1203
- )
1276
+ if config and config.resync:
1277
+ return FivetranEventIterator(
1278
+ events=self._resync_and_poll(
1279
+ context=context, resync_parameters=config.resync_parameters
1280
+ ),
1281
+ fivetran_workspace=self,
1282
+ context=context,
1283
+ )
1284
+ else:
1285
+ return FivetranEventIterator(
1286
+ events=self._sync_and_poll(context=context),
1287
+ fivetran_workspace=self,
1288
+ context=context,
1289
+ )
1204
1290
 
1205
1291
  def _sync_and_poll(self, context: AssetExecutionContext):
1206
1292
  assets_def = context.assets_def
@@ -1245,6 +1331,54 @@ class FivetranWorkspace(ConfigurableResource):
1245
1331
  if unmaterialized_asset_keys:
1246
1332
  context.log.warning(f"Assets were not materialized: {unmaterialized_asset_keys}")
1247
1333
 
1334
+ def _resync_and_poll(
1335
+ self,
1336
+ context: AssetExecutionContext,
1337
+ resync_parameters: Optional[Mapping[str, Sequence[str]]] = None,
1338
+ ):
1339
+ assets_def = context.assets_def
1340
+ dagster_fivetran_translator = get_translator_from_fivetran_assets(assets_def)
1341
+ connector_id = next(
1342
+ check.not_none(FivetranMetadataSet.extract(spec.metadata).connector_id)
1343
+ for spec in assets_def.specs
1344
+ )
1345
+
1346
+ client = self.get_client()
1347
+ fivetran_output = client.resync_and_poll(
1348
+ connector_id=connector_id,
1349
+ resync_parameters=resync_parameters,
1350
+ )
1351
+
1352
+ # The FivetranOutput is None if the connector hasn't been synced
1353
+ if not fivetran_output:
1354
+ context.log.warning(
1355
+ f"The connector with ID {connector_id} is currently paused and so it has not been resynced. "
1356
+ f"Make sure that your connector is enabled before resyncing it with Dagster."
1357
+ )
1358
+ return
1359
+
1360
+ materialized_asset_keys = set()
1361
+ for materialization in self._generate_materialization(
1362
+ fivetran_output=fivetran_output, dagster_fivetran_translator=dagster_fivetran_translator
1363
+ ):
1364
+ # Scan through all tables actually created, if it was expected then emit a MaterializeResult.
1365
+ # Otherwise, emit a runtime AssetMaterialization.
1366
+ if materialization.asset_key in context.selected_asset_keys:
1367
+ yield MaterializeResult(
1368
+ asset_key=materialization.asset_key, metadata=materialization.metadata
1369
+ )
1370
+ materialized_asset_keys.add(materialization.asset_key)
1371
+ else:
1372
+ context.log.warning(
1373
+ f"An unexpected asset was materialized: {materialization.asset_key}. "
1374
+ f"Yielding a materialization event."
1375
+ )
1376
+ yield materialization
1377
+
1378
+ unmaterialized_asset_keys = context.selected_asset_keys - materialized_asset_keys
1379
+ if unmaterialized_asset_keys:
1380
+ context.log.warning(f"Assets were not materialized: {unmaterialized_asset_keys}")
1381
+
1248
1382
 
1249
1383
  def load_fivetran_asset_specs(
1250
1384
  workspace: FivetranWorkspace,
@@ -1 +1 @@
1
- __version__ = "0.28.2"
1
+ __version__ = "0.28.3"
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: dagster-fivetran
3
- Version: 0.28.2
3
+ Version: 0.28.3
4
4
  Summary: Package for integrating Fivetran with Dagster.
5
5
  Home-page: https://github.com/dagster-io/dagster/tree/master/python_modules/libraries/dagster-fivetran
6
6
  Author: Dagster Labs
@@ -14,9 +14,9 @@ Classifier: License :: OSI Approved :: Apache Software License
14
14
  Classifier: Operating System :: OS Independent
15
15
  Requires-Python: >=3.10,<3.14
16
16
  License-File: LICENSE
17
- Requires-Dist: dagster==1.12.2
17
+ Requires-Dist: dagster==1.12.3
18
18
  Provides-Extra: managed
19
- Requires-Dist: dagster-managed-elements==0.28.2; extra == "managed"
19
+ Requires-Dist: dagster-managed-elements==0.28.3; extra == "managed"
20
20
  Provides-Extra: test
21
21
  Requires-Dist: pytest-order; extra == "test"
22
22
  Dynamic: author
@@ -1,4 +1,4 @@
1
- dagster_fivetran/__init__.py,sha256=XgXtaGmeFA-506MDyxIlQn0uqo7iXyPWZ4RZ1qSUvtI,1558
1
+ dagster_fivetran/__init__.py,sha256=9k5iCUhCx7DCYO-aj93oVhS6Ekc5zyaUBhZuofm77sg,1604
2
2
  dagster_fivetran/asset_decorator.py,sha256=nH6PlVnvP_xJgkfYzhwB7eHvzEXK7tqr3XqrY4qo2ng,5242
3
3
  dagster_fivetran/asset_defs.py,sha256=cxyPXdotaR7rDRN-6Go1rQ9ewehBW4zfBhZxxtcplMs,34531
4
4
  dagster_fivetran/cli.py,sha256=nG998z2QDE4s2rHTWsu1Hj4MH2cQW_H2x3ocgodHaJg,3228
@@ -6,11 +6,11 @@ dagster_fivetran/constants.py,sha256=hsdYi7WlDIfvrw4ATVha7K6GQHNnSelVieqNao1hzco
6
6
  dagster_fivetran/fivetran_event_iterator.py,sha256=DyZK5HQ7cFD4CWnhvPB7Hj5nUycjcoQ6IFrTX3SvgbQ,5652
7
7
  dagster_fivetran/ops.py,sha256=SNxRuShLI3MtqQLRAuIfRaUpKGqUmapCmEaop48_mIM,7694
8
8
  dagster_fivetran/py.typed,sha256=la67KBlbjXN-_-DfGNcdOcjYumVpKG_Tkw-8n5dnGB4,8
9
- dagster_fivetran/resources.py,sha256=1d6HCCBFz3ctfs0JoNsmz0O_49wdxARgeJ6_anI0lnU,55703
9
+ dagster_fivetran/resources.py,sha256=0APIjz2ovJo5gpoVzxs2rSmcs73BbhTYt8DPI3iaiHU,61553
10
10
  dagster_fivetran/translator.py,sha256=KyjB6nUuvN27hnIC-Oh4U_rrdud6Vfn9GH5GGFLBU9M,12470
11
11
  dagster_fivetran/types.py,sha256=1IXrLu937TMFdwi0tJJFRcT8Td5N8tfJe3rHArvPi68,957
12
12
  dagster_fivetran/utils.py,sha256=-xwgtr-UP3Q25ZIQzir4qPkLhYurnkdJY--5cr1ANC8,5918
13
- dagster_fivetran/version.py,sha256=K-TM2fq9AmH_Dk8Cadam72wILDZ_6qftLHvY9P1Fc3I,23
13
+ dagster_fivetran/version.py,sha256=PFj1PlFYtLhN7k4TLEHMneuQ4Ep8o7DCrl69TL8I0SY,23
14
14
  dagster_fivetran/components/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
15
15
  dagster_fivetran/components/workspace_component/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
16
16
  dagster_fivetran/components/workspace_component/component.py,sha256=tq68-TjMyVBoRWBJ0YRXofd153lzABpT2b96L_92Kso,10535
@@ -18,9 +18,9 @@ dagster_fivetran/components/workspace_component/scaffolder.py,sha256=2mv1vqN2KPn
18
18
  dagster_fivetran/managed/__init__.py,sha256=ki6yF6pMBQXXu6TwUom1BP0-PYW5RTYgvWmh3hRuT7w,269
19
19
  dagster_fivetran/managed/reconciliation.py,sha256=a0qLo52hqB5BCGBpLr5uLumkjgy72m0OmZYIyV5yCx8,14630
20
20
  dagster_fivetran/managed/types.py,sha256=PamX40i5JSAIrr97G4lEsHA6VdJLGBm99aVGNzgd-og,3622
21
- dagster_fivetran-0.28.2.dist-info/licenses/LICENSE,sha256=4lsMW-RCvfVD4_F57wrmpe3vX1xwUk_OAKKmV_XT7Z0,11348
22
- dagster_fivetran-0.28.2.dist-info/METADATA,sha256=Pq4QDwkV2eTlpwWXFR2stPLkaq4TW7WKlTXLe9Eptz8,1057
23
- dagster_fivetran-0.28.2.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
24
- dagster_fivetran-0.28.2.dist-info/entry_points.txt,sha256=2F7i9srZ1_8pwixGIodaNaWECGjqmBf8yvbYzzoULsc,134
25
- dagster_fivetran-0.28.2.dist-info/top_level.txt,sha256=8GH5pXbKSZEW4MVEAeOMN0e7cSH0h_4tjxp5WpZtkGA,17
26
- dagster_fivetran-0.28.2.dist-info/RECORD,,
21
+ dagster_fivetran-0.28.3.dist-info/licenses/LICENSE,sha256=4lsMW-RCvfVD4_F57wrmpe3vX1xwUk_OAKKmV_XT7Z0,11348
22
+ dagster_fivetran-0.28.3.dist-info/METADATA,sha256=xBmLBQ4-yzUMRcjsV5sNBnLZAM351EUmnjaF8OYAedM,1057
23
+ dagster_fivetran-0.28.3.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
24
+ dagster_fivetran-0.28.3.dist-info/entry_points.txt,sha256=2F7i9srZ1_8pwixGIodaNaWECGjqmBf8yvbYzzoULsc,134
25
+ dagster_fivetran-0.28.3.dist-info/top_level.txt,sha256=8GH5pXbKSZEW4MVEAeOMN0e7cSH0h_4tjxp5WpZtkGA,17
26
+ dagster_fivetran-0.28.3.dist-info/RECORD,,