dagster-airbyte 0.27.10__tar.gz → 0.27.12__tar.gz

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.

Potentially problematic release.


This version of dagster-airbyte might be problematic. Click here for more details.

Files changed (37) hide show
  1. {dagster_airbyte-0.27.10/dagster_airbyte.egg-info → dagster_airbyte-0.27.12}/PKG-INFO +3 -3
  2. {dagster_airbyte-0.27.10 → dagster_airbyte-0.27.12}/dagster_airbyte/__init__.py +3 -0
  3. {dagster_airbyte-0.27.10 → dagster_airbyte-0.27.12}/dagster_airbyte/asset_decorator.py +4 -4
  4. {dagster_airbyte-0.27.10 → dagster_airbyte-0.27.12}/dagster_airbyte/asset_defs.py +5 -3
  5. dagster_airbyte-0.27.12/dagster_airbyte/components/workspace_component/component.py +230 -0
  6. {dagster_airbyte-0.27.10 → dagster_airbyte-0.27.12}/dagster_airbyte/components/workspace_component/scaffolder.py +1 -1
  7. {dagster_airbyte-0.27.10 → dagster_airbyte-0.27.12}/dagster_airbyte/resources.py +404 -116
  8. {dagster_airbyte-0.27.10 → dagster_airbyte-0.27.12}/dagster_airbyte/utils.py +1 -1
  9. dagster_airbyte-0.27.12/dagster_airbyte/version.py +1 -0
  10. {dagster_airbyte-0.27.10 → dagster_airbyte-0.27.12/dagster_airbyte.egg-info}/PKG-INFO +3 -3
  11. dagster_airbyte-0.27.12/dagster_airbyte.egg-info/requires.txt +9 -0
  12. {dagster_airbyte-0.27.10 → dagster_airbyte-0.27.12}/setup.py +2 -2
  13. dagster_airbyte-0.27.10/dagster_airbyte/components/workspace_component/component.py +0 -133
  14. dagster_airbyte-0.27.10/dagster_airbyte/version.py +0 -1
  15. dagster_airbyte-0.27.10/dagster_airbyte.egg-info/requires.txt +0 -9
  16. {dagster_airbyte-0.27.10 → dagster_airbyte-0.27.12}/LICENSE +0 -0
  17. {dagster_airbyte-0.27.10 → dagster_airbyte-0.27.12}/MANIFEST.in +0 -0
  18. {dagster_airbyte-0.27.10 → dagster_airbyte-0.27.12}/README.md +0 -0
  19. {dagster_airbyte-0.27.10 → dagster_airbyte-0.27.12}/dagster_airbyte/cli.py +0 -0
  20. {dagster_airbyte-0.27.10 → dagster_airbyte-0.27.12}/dagster_airbyte/components/__init__.py +0 -0
  21. {dagster_airbyte-0.27.10 → dagster_airbyte-0.27.12}/dagster_airbyte/components/workspace_component/__init__.py +0 -0
  22. {dagster_airbyte-0.27.10 → dagster_airbyte-0.27.12}/dagster_airbyte/managed/__init__.py +0 -0
  23. {dagster_airbyte-0.27.10 → dagster_airbyte-0.27.12}/dagster_airbyte/managed/generated/__init__.py +0 -0
  24. {dagster_airbyte-0.27.10 → dagster_airbyte-0.27.12}/dagster_airbyte/managed/generated/destinations.py +0 -0
  25. {dagster_airbyte-0.27.10 → dagster_airbyte-0.27.12}/dagster_airbyte/managed/generated/sources.py +0 -0
  26. {dagster_airbyte-0.27.10 → dagster_airbyte-0.27.12}/dagster_airbyte/managed/reconciliation.py +0 -0
  27. {dagster_airbyte-0.27.10 → dagster_airbyte-0.27.12}/dagster_airbyte/managed/types.py +0 -0
  28. {dagster_airbyte-0.27.10 → dagster_airbyte-0.27.12}/dagster_airbyte/ops.py +0 -0
  29. {dagster_airbyte-0.27.10 → dagster_airbyte-0.27.12}/dagster_airbyte/py.typed +0 -0
  30. {dagster_airbyte-0.27.10 → dagster_airbyte-0.27.12}/dagster_airbyte/translator.py +0 -0
  31. {dagster_airbyte-0.27.10 → dagster_airbyte-0.27.12}/dagster_airbyte/types.py +0 -0
  32. {dagster_airbyte-0.27.10 → dagster_airbyte-0.27.12}/dagster_airbyte.egg-info/SOURCES.txt +0 -0
  33. {dagster_airbyte-0.27.10 → dagster_airbyte-0.27.12}/dagster_airbyte.egg-info/dependency_links.txt +0 -0
  34. {dagster_airbyte-0.27.10 → dagster_airbyte-0.27.12}/dagster_airbyte.egg-info/entry_points.txt +0 -0
  35. {dagster_airbyte-0.27.10 → dagster_airbyte-0.27.12}/dagster_airbyte.egg-info/not-zip-safe +0 -0
  36. {dagster_airbyte-0.27.10 → dagster_airbyte-0.27.12}/dagster_airbyte.egg-info/top_level.txt +0 -0
  37. {dagster_airbyte-0.27.10 → dagster_airbyte-0.27.12}/setup.cfg +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: dagster-airbyte
3
- Version: 0.27.10
3
+ Version: 0.27.12
4
4
  Summary: Package for integrating Airbyte with Dagster.
5
5
  Home-page: https://github.com/dagster-io/dagster/tree/master/python_modules/libraries/dagster-airbyte
6
6
  Author: Dagster Labs
@@ -15,13 +15,13 @@ Classifier: License :: OSI Approved :: Apache Software License
15
15
  Classifier: Operating System :: OS Independent
16
16
  Requires-Python: >=3.9,<3.14
17
17
  License-File: LICENSE
18
- Requires-Dist: dagster==1.11.10
18
+ Requires-Dist: dagster==1.11.12
19
19
  Requires-Dist: requests
20
20
  Provides-Extra: test
21
21
  Requires-Dist: requests-mock; extra == "test"
22
22
  Requires-Dist: flaky; extra == "test"
23
23
  Provides-Extra: managed
24
- Requires-Dist: dagster-managed-elements==0.27.10; extra == "managed"
24
+ Requires-Dist: dagster-managed-elements==0.27.12; extra == "managed"
25
25
  Dynamic: author
26
26
  Dynamic: author-email
27
27
  Dynamic: classifier
@@ -2,6 +2,7 @@ from dagster_shared.libraries import DagsterLibraryRegistry
2
2
 
3
3
  from dagster_airbyte.components.workspace_component.component import (
4
4
  AirbyteCloudWorkspaceComponent as AirbyteCloudWorkspaceComponent,
5
+ AirbyteWorkspaceComponent as AirbyteWorkspaceComponent,
5
6
  )
6
7
 
7
8
  try:
@@ -29,8 +30,10 @@ from dagster_airbyte.resources import (
29
30
  AirbyteCloudResource as AirbyteCloudResource,
30
31
  AirbyteCloudWorkspace as AirbyteCloudWorkspace,
31
32
  AirbyteResource as AirbyteResource,
33
+ AirbyteWorkspace as AirbyteWorkspace,
32
34
  airbyte_cloud_resource as airbyte_cloud_resource,
33
35
  airbyte_resource as airbyte_resource,
36
+ load_airbyte_asset_specs as load_airbyte_asset_specs,
34
37
  load_airbyte_cloud_asset_specs as load_airbyte_cloud_asset_specs,
35
38
  )
36
39
  from dagster_airbyte.translator import (
@@ -1,10 +1,10 @@
1
- from typing import Any, Callable, Optional
1
+ from typing import Any, Callable, Optional, Union
2
2
 
3
3
  from dagster import AssetsDefinition, multi_asset
4
4
  from dagster._annotations import beta
5
5
  from dagster._core.errors import DagsterInvariantViolationError
6
6
 
7
- from dagster_airbyte.resources import AirbyteCloudWorkspace
7
+ from dagster_airbyte.resources import AirbyteCloudWorkspace, AirbyteWorkspace
8
8
  from dagster_airbyte.translator import AirbyteMetadataSet, DagsterAirbyteTranslator
9
9
 
10
10
 
@@ -12,7 +12,7 @@ from dagster_airbyte.translator import AirbyteMetadataSet, DagsterAirbyteTransla
12
12
  def airbyte_assets(
13
13
  *,
14
14
  connection_id: str,
15
- workspace: AirbyteCloudWorkspace,
15
+ workspace: Union[AirbyteWorkspace, AirbyteCloudWorkspace],
16
16
  name: Optional[str] = None,
17
17
  group_name: Optional[str] = None,
18
18
  dagster_airbyte_translator: Optional[DagsterAirbyteTranslator] = None,
@@ -21,7 +21,7 @@ def airbyte_assets(
21
21
 
22
22
  Args:
23
23
  connection_id (str): The Airbyte Connection ID.
24
- workspace (AirbyteCloudWorkspace): The Airbyte workspace to fetch assets from.
24
+ workspace (Union[AirbyteWorkspace, AirbyteCloudWorkspace]): The Airbyte workspace to fetch assets from.
25
25
  name (Optional[str], optional): The name of the op.
26
26
  group_name (Optional[str], optional): The name of the asset group.
27
27
  dagster_airbyte_translator (Optional[DagsterAirbyteTranslator], optional): The translator to use
@@ -38,7 +38,9 @@ from dagster_airbyte.resources import (
38
38
  AirbyteCloudResource,
39
39
  AirbyteCloudWorkspace,
40
40
  AirbyteResource,
41
+ AirbyteWorkspace,
41
42
  BaseAirbyteResource,
43
+ BaseAirbyteWorkspace,
42
44
  )
43
45
  from dagster_airbyte.translator import (
44
46
  AirbyteConnection,
@@ -1040,14 +1042,14 @@ def load_assets_from_airbyte_instance(
1040
1042
  @beta
1041
1043
  def build_airbyte_assets_definitions(
1042
1044
  *,
1043
- workspace: AirbyteCloudWorkspace,
1045
+ workspace: Union[AirbyteWorkspace, AirbyteCloudWorkspace],
1044
1046
  dagster_airbyte_translator: Optional[DagsterAirbyteTranslator] = None,
1045
1047
  connection_selector_fn: Optional[Callable[[AirbyteConnection], bool]] = None,
1046
1048
  ) -> Sequence[AssetsDefinition]:
1047
1049
  """The list of AssetsDefinition for all connections in the Airbyte workspace.
1048
1050
 
1049
1051
  Args:
1050
- workspace (AirbyteCloudWorkspace): The Airbyte workspace to fetch assets from.
1052
+ workspace (Union[AirbyteWorkspace, AirbyteCloudWorkspace]): The Airbyte workspace to fetch assets from.
1051
1053
  dagster_airbyte_translator (Optional[DagsterAirbyteTranslator], optional): The translator to use
1052
1054
  to convert Airbyte content into :py:class:`dagster.AssetSpec`.
1053
1055
  Defaults to :py:class:`DagsterAirbyteTranslator`.
@@ -1164,7 +1166,7 @@ def build_airbyte_assets_definitions(
1164
1166
  name=f"airbyte_{clean_name(connection_name)}",
1165
1167
  dagster_airbyte_translator=dagster_airbyte_translator,
1166
1168
  )
1167
- def _asset_fn(context: AssetExecutionContext, airbyte: AirbyteCloudWorkspace):
1169
+ def _asset_fn(context: AssetExecutionContext, airbyte: BaseAirbyteWorkspace):
1168
1170
  yield from airbyte.sync_and_poll(context=context)
1169
1171
 
1170
1172
  _asset_fns.append(_asset_fn)
@@ -0,0 +1,230 @@
1
+ from collections.abc import Sequence
2
+ from functools import cached_property
3
+ from typing import Annotated, Callable, Optional, Union
4
+
5
+ import dagster as dg
6
+ import pydantic
7
+ from dagster._annotations import superseded
8
+ from dagster._core.definitions.job_definition import default_job_io_manager
9
+ from dagster.components.resolved.base import resolve_fields
10
+ from dagster.components.utils.translation import TranslationFn, TranslationFnResolver
11
+ from dagster_shared import check
12
+
13
+ from dagster_airbyte.asset_defs import build_airbyte_assets_definitions
14
+ from dagster_airbyte.components.workspace_component.scaffolder import (
15
+ AirbyteWorkspaceComponentScaffolder,
16
+ )
17
+ from dagster_airbyte.resources import AirbyteCloudWorkspace, AirbyteWorkspace
18
+ from dagster_airbyte.translator import (
19
+ AirbyteConnection,
20
+ AirbyteConnectionTableProps,
21
+ DagsterAirbyteTranslator,
22
+ )
23
+
24
+
25
+ class ProxyDagsterAirbyteTranslator(DagsterAirbyteTranslator):
26
+ def __init__(self, fn: TranslationFn[AirbyteConnectionTableProps]):
27
+ self.fn = fn
28
+
29
+ def get_asset_spec(self, props: AirbyteConnectionTableProps) -> dg.AssetSpec:
30
+ base_asset_spec = super().get_asset_spec(props)
31
+ spec = self.fn(base_asset_spec, props)
32
+
33
+ return spec
34
+
35
+
36
+ class BaseAirbyteWorkspaceModel(dg.Model, dg.Resolvable):
37
+ request_max_retries: Annotated[
38
+ int,
39
+ pydantic.Field(
40
+ default=3,
41
+ description=(
42
+ "The maximum number of times requests to the Airbyte API should be retried "
43
+ "before failing."
44
+ ),
45
+ ),
46
+ ]
47
+ request_retry_delay: Annotated[
48
+ float,
49
+ pydantic.Field(
50
+ default=0.25,
51
+ description="Time (in seconds) to wait between each request retry.",
52
+ ),
53
+ ]
54
+ request_timeout: Annotated[
55
+ int,
56
+ pydantic.Field(
57
+ default=15,
58
+ description="Time (in seconds) after which the requests to Airbyte are declared timed out.",
59
+ ),
60
+ ]
61
+
62
+
63
+ class AirbyteWorkspaceModel(BaseAirbyteWorkspaceModel):
64
+ rest_api_base_url: Annotated[
65
+ str,
66
+ pydantic.Field(
67
+ ...,
68
+ description=(
69
+ "The base URL for the Airbyte REST API. "
70
+ "For Airbyte Cloud, leave this as the default. "
71
+ "For self-managed Airbyte, this is usually <your Airbyte host>/api/public/v1."
72
+ ),
73
+ examples=[
74
+ "http://localhost:8000/api/public/v1",
75
+ "https://my-airbyte-server.com/api/public/v1",
76
+ "http://airbyte-airbyte-server-svc.airbyte.svc.cluster.local:8001/api/public/v1",
77
+ ],
78
+ ),
79
+ ]
80
+ configuration_api_base_url: Annotated[
81
+ str,
82
+ pydantic.Field(
83
+ ...,
84
+ description=(
85
+ "The base URL for the Airbyte Configuration API. "
86
+ "For Airbyte Cloud, leave this as the default. "
87
+ "For self-managed Airbyte, this is usually <your Airbyte host>/api/v1."
88
+ ),
89
+ examples=[
90
+ "http://localhost:8000/api/v1",
91
+ "https://my-airbyte-server.com/api/v1",
92
+ "http://airbyte-airbyte-server-svc.airbyte.svc.cluster.local:8001/api/v1",
93
+ ],
94
+ ),
95
+ ]
96
+ workspace_id: Annotated[str, pydantic.Field(..., description="The Airbyte workspace ID.")]
97
+ client_id: Annotated[
98
+ Optional[str],
99
+ pydantic.Field(None, description="Client ID used to authenticate to Airbyte."),
100
+ ]
101
+ client_secret: Annotated[
102
+ Optional[str],
103
+ pydantic.Field(None, description="Client secret used to authenticate to Airbyte."),
104
+ ]
105
+ username: Annotated[
106
+ Optional[str],
107
+ pydantic.Field(
108
+ None,
109
+ description="Username used to authenticate to Airbyte. Used for self-managed Airbyte with basic auth.",
110
+ ),
111
+ ]
112
+ password: Annotated[
113
+ Optional[str],
114
+ pydantic.Field(
115
+ None,
116
+ description="Password used to authenticate to Airbyte. Used for self-managed Airbyte with basic auth.",
117
+ ),
118
+ ]
119
+
120
+
121
+ class AirbyteCloudWorkspaceModel(BaseAirbyteWorkspaceModel):
122
+ workspace_id: Annotated[str, pydantic.Field(..., description="The Airbyte workspace ID.")]
123
+ client_id: Annotated[
124
+ Optional[str],
125
+ pydantic.Field(..., description="Client ID used to authenticate to Airbyte."),
126
+ ]
127
+ client_secret: Annotated[
128
+ Optional[str],
129
+ pydantic.Field(..., description="Client secret used to authenticate to Airbyte."),
130
+ ]
131
+
132
+
133
+ class AirbyteConnectionSelectorByName(dg.Model):
134
+ by_name: Annotated[
135
+ Sequence[str],
136
+ pydantic.Field(..., description="A list of connection names to include in the collection."),
137
+ ]
138
+
139
+
140
+ class AirbyteConnectionSelectorById(dg.Model):
141
+ by_id: Annotated[
142
+ Sequence[str],
143
+ pydantic.Field(..., description="A list of connection IDs to include in the collection."),
144
+ ]
145
+
146
+
147
+ def resolve_connection_selector(
148
+ context: dg.ResolutionContext, model
149
+ ) -> Optional[Callable[[AirbyteConnection], bool]]:
150
+ if isinstance(model, str):
151
+ model = context.resolve_value(model)
152
+
153
+ if isinstance(model, AirbyteConnectionSelectorByName):
154
+ return lambda connection: connection.name in model.by_name
155
+ elif isinstance(model, AirbyteConnectionSelectorById):
156
+ return lambda connection: connection.id in model.by_id
157
+ else:
158
+ check.failed(f"Unknown connection target type: {type(model)}")
159
+
160
+
161
+ def resolve_airbyte_workspace_type(context: dg.ResolutionContext, model):
162
+ if isinstance(model, AirbyteWorkspaceModel):
163
+ return AirbyteWorkspace(**resolve_fields(model, AirbyteWorkspaceModel, context))
164
+ elif isinstance(model, AirbyteCloudWorkspaceModel):
165
+ return AirbyteCloudWorkspace(**resolve_fields(model, AirbyteCloudWorkspaceModel, context))
166
+ else:
167
+ check.failed(f"Unknown Airbyte workspace type: {type(model)}")
168
+
169
+
170
+ @dg.scaffold_with(AirbyteWorkspaceComponentScaffolder)
171
+ class AirbyteWorkspaceComponent(dg.Component, dg.Model, dg.Resolvable):
172
+ """Loads Airbyte connections from a given Airbyte workspace as Dagster assets.
173
+ Materializing these assets will trigger a sync of the Airbyte connection, enabling
174
+ you to schedule Airbyte syncs using Dagster.
175
+ """
176
+
177
+ workspace: Annotated[
178
+ Union[AirbyteWorkspace, AirbyteCloudWorkspace],
179
+ dg.Resolver(
180
+ resolve_airbyte_workspace_type,
181
+ model_field_type=Union[AirbyteWorkspaceModel, AirbyteCloudWorkspaceModel],
182
+ ),
183
+ ]
184
+ connection_selector: Annotated[
185
+ Optional[Callable[[AirbyteConnection], bool]],
186
+ dg.Resolver(
187
+ resolve_connection_selector,
188
+ model_field_type=Union[
189
+ str, AirbyteConnectionSelectorByName, AirbyteConnectionSelectorById
190
+ ],
191
+ description="Function used to select Airbyte connections to pull into Dagster.",
192
+ ),
193
+ ] = None
194
+ translation: Optional[
195
+ Annotated[
196
+ TranslationFn[AirbyteConnectionTableProps],
197
+ TranslationFnResolver(template_vars_for_translation_fn=lambda data: {"props": data}),
198
+ ]
199
+ ] = pydantic.Field(
200
+ None,
201
+ description="Function used to translate Airbyte connection table properties into Dagster asset specs.",
202
+ )
203
+
204
+ @cached_property
205
+ def translator(self) -> DagsterAirbyteTranslator:
206
+ if self.translation:
207
+ return ProxyDagsterAirbyteTranslator(self.translation)
208
+ return DagsterAirbyteTranslator()
209
+
210
+ def build_defs(self, context: dg.ComponentLoadContext) -> dg.Definitions:
211
+ airbyte_assets = build_airbyte_assets_definitions(
212
+ workspace=self.workspace,
213
+ dagster_airbyte_translator=self.translator,
214
+ connection_selector_fn=self.connection_selector,
215
+ )
216
+ assets_with_resource = [
217
+ airbyte_asset.with_resources(
218
+ {
219
+ "airbyte": self.workspace.get_resource_definition(),
220
+ "io_manager": default_job_io_manager,
221
+ }
222
+ )
223
+ for airbyte_asset in airbyte_assets
224
+ ]
225
+ return dg.Definitions(assets=assets_with_resource)
226
+
227
+
228
+ # Subclassing to create the alias to be able to use the superseded decorator.
229
+ @superseded(additional_warn_text="Superseded. Use AirbyteWorkspaceComponent instead.")
230
+ class AirbyteCloudWorkspaceComponent(AirbyteWorkspaceComponent): ...
@@ -12,7 +12,7 @@ class AirbyteScaffolderParams(BaseModel):
12
12
  client_secret: Optional[str] = None
13
13
 
14
14
 
15
- class AirbyteCloudWorkspaceComponentScaffolder(Scaffolder[AirbyteScaffolderParams]):
15
+ class AirbyteWorkspaceComponentScaffolder(Scaffolder[AirbyteScaffolderParams]):
16
16
  @classmethod
17
17
  def get_scaffold_params(cls) -> type[AirbyteScaffolderParams]:
18
18
  return AirbyteScaffolderParams