dagster-airbyte 0.24.3__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.
@@ -0,0 +1,255 @@
1
+ from collections.abc import Mapping, Sequence
2
+ from datetime import datetime
3
+ from enum import Enum
4
+ from typing import Any, Optional
5
+
6
+ from dagster._annotations import beta, deprecated
7
+ from dagster._core.definitions.asset_key import AssetKey
8
+ from dagster._core.definitions.assets.definition.asset_spec import AssetSpec
9
+ from dagster._core.definitions.metadata.metadata_set import NamespacedMetadataSet, TableMetadataSet
10
+ from dagster._record import record
11
+ from dagster._utils.cached_method import cached_method
12
+ from dagster_shared.serdes import whitelist_for_serdes
13
+
14
+ from dagster_airbyte.utils import generate_table_schema, get_airbyte_connection_table_name
15
+
16
+
17
+ class AirbyteJobStatusType(str, Enum):
18
+ RUNNING = "running"
19
+ SUCCEEDED = "succeeded"
20
+ CANCELLED = "cancelled"
21
+ PENDING = "pending"
22
+ FAILED = "failed"
23
+ ERROR = "error"
24
+ INCOMPLETE = "incomplete"
25
+
26
+
27
+ @deprecated(breaking_version="1.10", additional_warn_text="Use `AirbyteJobStatusType` instead.")
28
+ class AirbyteState:
29
+ RUNNING = AirbyteJobStatusType.RUNNING
30
+ SUCCEEDED = AirbyteJobStatusType.SUCCEEDED
31
+ CANCELLED = AirbyteJobStatusType.CANCELLED
32
+ PENDING = AirbyteJobStatusType.PENDING
33
+ FAILED = AirbyteJobStatusType.FAILED
34
+ ERROR = AirbyteJobStatusType.ERROR
35
+ INCOMPLETE = AirbyteJobStatusType.INCOMPLETE
36
+
37
+
38
+ @record
39
+ class AirbyteConnectionTableProps:
40
+ table_name: str
41
+ stream_prefix: Optional[str]
42
+ stream_name: str
43
+ json_schema: Mapping[str, Any]
44
+ connection_id: str
45
+ connection_name: str
46
+ destination_type: Optional[str]
47
+ database: Optional[str]
48
+ schema: Optional[str]
49
+
50
+ @property
51
+ def fully_qualified_table_name(self) -> Optional[str]:
52
+ return (
53
+ f"{self.database}.{self.schema}.{self.stream_name}"
54
+ if self.database and self.schema
55
+ else None
56
+ )
57
+
58
+
59
+ @whitelist_for_serdes
60
+ @record
61
+ class AirbyteConnection:
62
+ """Represents an Airbyte connection, based on data as returned from the API."""
63
+
64
+ id: str
65
+ name: str
66
+ stream_prefix: Optional[str]
67
+ streams: Mapping[str, "AirbyteStream"]
68
+ destination_id: str
69
+
70
+ @classmethod
71
+ def from_connection_details(
72
+ cls,
73
+ connection_details: Mapping[str, Any],
74
+ ) -> "AirbyteConnection":
75
+ return cls(
76
+ id=connection_details["connectionId"],
77
+ name=connection_details["name"],
78
+ stream_prefix=connection_details.get("prefix"),
79
+ streams={
80
+ stream_details["stream"]["name"]: AirbyteStream.from_stream_details(
81
+ stream_details=stream_details
82
+ )
83
+ for stream_details in connection_details.get("syncCatalog", {}).get("streams", [])
84
+ },
85
+ destination_id=connection_details["destinationId"],
86
+ )
87
+
88
+
89
+ @whitelist_for_serdes
90
+ @record
91
+ class AirbyteDestination:
92
+ """Represents an Airbyte destination, based on data as returned from the API."""
93
+
94
+ id: str
95
+ type: str
96
+ database: Optional[str]
97
+ schema: Optional[str]
98
+
99
+ @classmethod
100
+ def from_destination_details(
101
+ cls,
102
+ destination_details: Mapping[str, Any],
103
+ ) -> "AirbyteDestination":
104
+ return cls(
105
+ id=destination_details["destinationId"],
106
+ type=destination_details["destinationType"],
107
+ database=destination_details["configuration"].get("database"),
108
+ schema=destination_details["configuration"].get("schema"),
109
+ )
110
+
111
+
112
+ @whitelist_for_serdes
113
+ @record
114
+ class AirbyteStream:
115
+ """Represents an Airbyte stream, based on data as returned from the API.
116
+ A stream in Airbyte corresponds to a table.
117
+ """
118
+
119
+ name: str
120
+ selected: bool
121
+ json_schema: Mapping[str, Any]
122
+
123
+ @classmethod
124
+ def from_stream_details(
125
+ cls,
126
+ stream_details: Mapping[str, Any],
127
+ ) -> "AirbyteStream":
128
+ return cls(
129
+ name=stream_details["stream"]["name"],
130
+ selected=stream_details["config"].get("selected", False),
131
+ json_schema=stream_details["stream"].get("jsonSchema", {}),
132
+ )
133
+
134
+
135
+ @whitelist_for_serdes
136
+ @record
137
+ class AirbyteJob:
138
+ """Represents an Airbyte job, based on data as returned from the API."""
139
+
140
+ id: int
141
+ status: str
142
+ type: str
143
+ connection_id: str | None = None
144
+ start_time: datetime | None = None
145
+ last_updated_at: datetime | None = None
146
+ duration: str | None = None
147
+ bytes_synced: int | None = None
148
+ rows_synced: int | None = None
149
+
150
+ @classmethod
151
+ def from_job_details(
152
+ cls,
153
+ job_details: Mapping[str, Any],
154
+ ) -> "AirbyteJob":
155
+ return cls(
156
+ id=job_details["jobId"],
157
+ status=job_details["status"],
158
+ type=job_details["jobType"],
159
+ connection_id=job_details.get("connectionId"),
160
+ start_time=datetime.fromisoformat(job_details["startTime"])
161
+ if "startTime" in job_details
162
+ else None,
163
+ last_updated_at=datetime.fromisoformat(job_details["lastUpdatedAt"])
164
+ if "lastUpdatedAt" in job_details
165
+ else None,
166
+ duration=job_details.get("duration"),
167
+ bytes_synced=job_details.get("bytesScanned"),
168
+ rows_synced=job_details.get("rowsSynced"),
169
+ )
170
+
171
+
172
+ @whitelist_for_serdes
173
+ @record
174
+ class AirbyteWorkspaceData:
175
+ """A record representing all content in an Airbyte workspace.
176
+ This applies to both Airbyte OSS and Cloud.
177
+ """
178
+
179
+ connections_by_id: Mapping[str, AirbyteConnection]
180
+ destinations_by_id: Mapping[str, AirbyteDestination]
181
+
182
+ @cached_method
183
+ def to_airbyte_connection_table_props_data(self) -> Sequence[AirbyteConnectionTableProps]:
184
+ """Method that converts a `AirbyteWorkspaceData` object
185
+ to a collection of `AirbyteConnectionTableProps` objects.
186
+ """
187
+ data: list[AirbyteConnectionTableProps] = []
188
+
189
+ for connection in self.connections_by_id.values():
190
+ destination = self.destinations_by_id[connection.destination_id]
191
+
192
+ for stream in connection.streams.values():
193
+ if stream.selected:
194
+ data.append(
195
+ AirbyteConnectionTableProps(
196
+ table_name=get_airbyte_connection_table_name(
197
+ stream_prefix=connection.stream_prefix,
198
+ stream_name=stream.name,
199
+ ),
200
+ stream_prefix=connection.stream_prefix,
201
+ stream_name=stream.name,
202
+ json_schema=stream.json_schema,
203
+ connection_id=connection.id,
204
+ connection_name=connection.name,
205
+ destination_type=destination.type,
206
+ database=destination.database,
207
+ schema=destination.schema,
208
+ )
209
+ )
210
+
211
+ return data
212
+
213
+
214
+ class AirbyteMetadataSet(NamespacedMetadataSet):
215
+ connection_id: str
216
+ connection_name: str
217
+ stream_prefix: Optional[str] = None
218
+
219
+ @classmethod
220
+ def namespace(cls) -> str:
221
+ return "dagster-airbyte"
222
+
223
+
224
+ @beta
225
+ class DagsterAirbyteTranslator:
226
+ """Translator class which converts a `AirbyteConnectionTableProps` object into AssetSpecs.
227
+ Subclass this class to implement custom logic how to translate Airbyte content into asset spec.
228
+ """
229
+
230
+ def get_asset_spec(self, props: AirbyteConnectionTableProps) -> AssetSpec:
231
+ """Get the AssetSpec for a table synced by an Airbyte connection."""
232
+ table_schema_props = (
233
+ props.json_schema.get("properties")
234
+ or props.json_schema.get("items", {}).get("properties")
235
+ or {}
236
+ )
237
+ column_schema = generate_table_schema(table_schema_props)
238
+
239
+ metadata = {
240
+ **TableMetadataSet(
241
+ column_schema=column_schema,
242
+ table_name=props.fully_qualified_table_name,
243
+ ),
244
+ **AirbyteMetadataSet(
245
+ connection_id=props.connection_id,
246
+ connection_name=props.connection_name,
247
+ stream_prefix=props.stream_prefix,
248
+ ),
249
+ }
250
+
251
+ return AssetSpec(
252
+ key=AssetKey(props.table_name),
253
+ metadata=metadata,
254
+ kinds={"airbyte", *({props.destination_type} if props.destination_type else set())},
255
+ )
dagster_airbyte/types.py CHANGED
@@ -1,4 +1,5 @@
1
- from typing import Any, Mapping, NamedTuple, Optional
1
+ from collections.abc import Mapping
2
+ from typing import Any, NamedTuple, Optional
2
3
 
3
4
  from dagster._core.definitions.metadata.table import TableSchema
4
5
 
@@ -6,10 +7,14 @@ from dagster._core.definitions.metadata.table import TableSchema
6
7
  class AirbyteTableMetadata:
7
8
  def __init__(
8
9
  self,
10
+ raw_table_name: str,
9
11
  schema: TableSchema,
10
12
  normalization_tables: Optional[Mapping[str, "AirbyteTableMetadata"]] = None,
11
13
  ):
12
- """Contains metadata about an Airbyte table, including its schema and any created normalization tables."""
14
+ """Contains metadata about an Airbyte table, including its destination raw table name,
15
+ schema and any created normalization tables.
16
+ """
17
+ self.raw_table_name = raw_table_name
13
18
  self.schema = schema
14
19
  self.normalization_tables = normalization_tables or dict()
15
20
 
@@ -25,7 +30,7 @@ class AirbyteOutput(
25
30
  ):
26
31
  """Contains recorded information about the state of a Airbyte connection job after a sync completes.
27
32
 
28
- Attributes:
33
+ Args:
29
34
  job_details (Dict[str, Any]):
30
35
  The raw Airbyte API response containing the details of the initiated job. For info
31
36
  on the schema of this dictionary, see: https://airbyte-public-api-docs.s3.us-east-2.amazonaws.com/rapidoc-api-docs.html#post-/v1/jobs/get
dagster_airbyte/utils.py CHANGED
@@ -1,10 +1,29 @@
1
- from typing import Any, Iterator, Mapping, Optional, Sequence
1
+ from collections.abc import Iterator, Mapping, Sequence
2
+ from typing import TYPE_CHECKING, Any, Optional
2
3
 
3
- from dagster import AssetMaterialization, MetadataValue
4
+ from dagster import (
5
+ AssetMaterialization,
6
+ AssetsDefinition,
7
+ DagsterInvariantViolationError,
8
+ MetadataValue,
9
+ )
4
10
  from dagster._core.definitions.metadata.table import TableColumn, TableSchema
11
+ from dagster._utils.names import clean_name_lower
5
12
 
6
13
  from dagster_airbyte.types import AirbyteOutput
7
14
 
15
+ if TYPE_CHECKING:
16
+ from dagster_airbyte.translator import DagsterAirbyteTranslator
17
+
18
+ DAGSTER_AIRBYTE_TRANSLATOR_METADATA_KEY = "dagster-airbyte/dagster_airbyte_translator"
19
+
20
+
21
+ clean_name = clean_name_lower
22
+
23
+
24
+ def get_airbyte_connection_table_name(stream_prefix: Optional[str], stream_name: str) -> str:
25
+ return f"{stream_prefix if stream_prefix else ''}{stream_name}"
26
+
8
27
 
9
28
  def generate_table_schema(stream_schema_props: Mapping[str, Any]) -> TableSchema:
10
29
  return TableSchema(
@@ -74,3 +93,18 @@ def generate_materializations(
74
93
  all_stream_stats.get(stream_name, {}),
75
94
  asset_key_prefix=asset_key_prefix,
76
95
  )
96
+
97
+
98
+ def get_translator_from_airbyte_assets(
99
+ airbyte_assets: AssetsDefinition,
100
+ ) -> "DagsterAirbyteTranslator":
101
+ metadata_by_key = airbyte_assets.metadata_by_key or {}
102
+ first_asset_key = next(iter(airbyte_assets.metadata_by_key.keys()))
103
+ first_metadata = metadata_by_key.get(first_asset_key, {})
104
+ dagster_airbyte_translator = first_metadata.get(DAGSTER_AIRBYTE_TRANSLATOR_METADATA_KEY)
105
+ if dagster_airbyte_translator is None:
106
+ raise DagsterInvariantViolationError(
107
+ f"Expected to find airbyte translator metadata on asset {first_asset_key.to_user_string()},"
108
+ " but did not. Did you pass in assets that weren't generated by @airbyte_assets?"
109
+ )
110
+ return dagster_airbyte_translator
@@ -1 +1 @@
1
- __version__ = "0.24.3"
1
+ __version__ = "0.28.3"
@@ -1,24 +1,33 @@
1
- Metadata-Version: 2.1
1
+ Metadata-Version: 2.4
2
2
  Name: dagster-airbyte
3
- Version: 0.24.3
3
+ Version: 0.28.3
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
7
7
  Author-email: hello@dagsterlabs.com
8
8
  License: Apache-2.0
9
- Classifier: Programming Language :: Python :: 3.8
10
- Classifier: Programming Language :: Python :: 3.9
11
9
  Classifier: Programming Language :: Python :: 3.10
12
10
  Classifier: Programming Language :: Python :: 3.11
13
11
  Classifier: Programming Language :: Python :: 3.12
12
+ Classifier: Programming Language :: Python :: 3.13
14
13
  Classifier: License :: OSI Approved :: Apache Software License
15
14
  Classifier: Operating System :: OS Independent
16
- Requires-Python: >=3.8,<3.13
15
+ Requires-Python: >=3.10,<3.14
17
16
  License-File: LICENSE
18
- Requires-Dist: dagster ==1.8.3
17
+ Requires-Dist: dagster==1.12.3
19
18
  Requires-Dist: requests
20
- Provides-Extra: managed
21
- Requires-Dist: dagster-managed-elements ==0.24.3 ; extra == 'managed'
22
19
  Provides-Extra: test
23
- Requires-Dist: requests-mock ; extra == 'test'
24
-
20
+ Requires-Dist: requests-mock; extra == "test"
21
+ Requires-Dist: flaky; extra == "test"
22
+ Provides-Extra: managed
23
+ Requires-Dist: dagster-managed-elements==0.28.3; extra == "managed"
24
+ Dynamic: author
25
+ Dynamic: author-email
26
+ Dynamic: classifier
27
+ Dynamic: home-page
28
+ Dynamic: license
29
+ Dynamic: license-file
30
+ Dynamic: provides-extra
31
+ Dynamic: requires-dist
32
+ Dynamic: requires-python
33
+ Dynamic: summary
@@ -0,0 +1,28 @@
1
+ dagster_airbyte/__init__.py,sha256=UO5Gf6M6q1c7bbL5uW6NH9HuNkaH2y_xVfqMY9tN7xk,2073
2
+ dagster_airbyte/asset_decorator.py,sha256=bCA22GG8ch5eGmm6BkztIfTY6ROXWJq1AInzO7fwJ2M,4667
3
+ dagster_airbyte/asset_defs.py,sha256=8yDuE2r1_4IAl9bY7BkbJpINWgJjtPY1t_WZeedGZho,51909
4
+ dagster_airbyte/cli.py,sha256=HErteP1MjfHozKKSrznh0yAreKETbXp5NDHzXGsdvvE,425
5
+ dagster_airbyte/legacy_resources.py,sha256=ks5doF0YZr7nXeU6ibQh1qiIMPAd_c2jusOkqdZKysc,31125
6
+ dagster_airbyte/ops.py,sha256=zDuROSIpqMhiioycTpLRgGnrp71lZNd4ts6-yybPg_s,4273
7
+ dagster_airbyte/py.typed,sha256=la67KBlbjXN-_-DfGNcdOcjYumVpKG_Tkw-8n5dnGB4,8
8
+ dagster_airbyte/resources.py,sha256=Nb-cPHYtkzYjmIb7c0onA9hYLpe5JLcEjbXQf9_3Cf4,41654
9
+ dagster_airbyte/translator.py,sha256=-aT-Au1VqaqHnRvivOaHslK2C6db5eNKB3mAJbQwvw8,8364
10
+ dagster_airbyte/types.py,sha256=TYUjI3skjLYeANjesgJ-IAJNu8bAnL1ymsUfz5LsRTE,1565
11
+ dagster_airbyte/utils.py,sha256=wG9119kXi87JgcOjK7iNozr-svZocJBQYoHBMmnXZcE,4092
12
+ dagster_airbyte/version.py,sha256=PFj1PlFYtLhN7k4TLEHMneuQ4Ep8o7DCrl69TL8I0SY,23
13
+ dagster_airbyte/components/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
14
+ dagster_airbyte/components/workspace_component/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
15
+ dagster_airbyte/components/workspace_component/component.py,sha256=yTc_uzU5--kbjfDzE0TbVHWqqrRu3kh1C-YzN-xWg34,16208
16
+ dagster_airbyte/components/workspace_component/scaffolder.py,sha256=zk5HDJ6C8zcfUWKslJVyqyBB0LV3JzNAocY2ptT517s,1046
17
+ dagster_airbyte/managed/__init__.py,sha256=6SBtyNOMJ9Cu2UIwFExJHpL_ZVFo3rPMvyIxVOsKvWE,469
18
+ dagster_airbyte/managed/reconciliation.py,sha256=V9bNMwNRvyIXF0O3cSaPlw3CmpbVaWQVEQarhrXf7n0,34866
19
+ dagster_airbyte/managed/types.py,sha256=isPfX8L9YwtZAf9Vk4hhxBePLR00AEldsdK2TsM1H2o,14611
20
+ dagster_airbyte/managed/generated/__init__.py,sha256=eYq-yfXEeffuKAVFXY8plD0se1wHjFNVqklpbu9gljw,108
21
+ dagster_airbyte/managed/generated/destinations.py,sha256=x1wmWlXvOJHtfaZva3ErdKuVS--sDvfidSXR5ji9G5w,119692
22
+ dagster_airbyte/managed/generated/sources.py,sha256=y0TPNvcRd8c9mhje-NoXsHeKRPt1nXcpww8mNAtqCps,282685
23
+ dagster_airbyte-0.28.3.dist-info/licenses/LICENSE,sha256=4lsMW-RCvfVD4_F57wrmpe3vX1xwUk_OAKKmV_XT7Z0,11348
24
+ dagster_airbyte-0.28.3.dist-info/METADATA,sha256=92qHM2fBXVeMMibGM-YiIvuDqe43_ZwxmMrAuKJByUI,1117
25
+ dagster_airbyte-0.28.3.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
26
+ dagster_airbyte-0.28.3.dist-info/entry_points.txt,sha256=096yvfMP-gNsCgDg9vDQtinis5QGpD-e_kHEhcHaML8,120
27
+ dagster_airbyte-0.28.3.dist-info/top_level.txt,sha256=HLwIRQCzqItn88_KbPP8DNTKKQEBUVKk6NCn4PrCtqY,16
28
+ dagster_airbyte-0.28.3.dist-info/RECORD,,
@@ -1,5 +1,5 @@
1
1
  Wheel-Version: 1.0
2
- Generator: bdist_wheel (0.41.2)
2
+ Generator: setuptools (80.9.0)
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any
5
5
 
@@ -1,2 +1,5 @@
1
1
  [console_scripts]
2
2
  dagster-airbyte = dagster_airbyte.cli:main
3
+
4
+ [dagster_dg_cli.plugin]
5
+ dagster_airbyte = dagster_airbyte
@@ -186,7 +186,7 @@
186
186
  same "printed page" as the copyright notice for easier
187
187
  identification within third-party archives.
188
188
 
189
- Copyright 2023 Dagster Labs, Inc".
189
+ Copyright 2025 Dagster Labs, Inc.
190
190
 
191
191
  Licensed under the Apache License, Version 2.0 (the "License");
192
192
  you may not use this file except in compliance with the License.
@@ -1,21 +0,0 @@
1
- dagster_airbyte/__init__.py,sha256=KRUcHzOxDEmo9oO7qRwJNrRnxK28PeHTeUemMS4z2Gc,1215
2
- dagster_airbyte/asset_defs.py,sha256=7PziNgIbN9xQwRjapygGvdWXI27p-ig6cdq6sRZ40W0,48511
3
- dagster_airbyte/cli.py,sha256=HErteP1MjfHozKKSrznh0yAreKETbXp5NDHzXGsdvvE,425
4
- dagster_airbyte/ops.py,sha256=fmZ7u223streZfx5Cwo0a-HhkWJVhBWiGsmwY9XXso8,4194
5
- dagster_airbyte/py.typed,sha256=la67KBlbjXN-_-DfGNcdOcjYumVpKG_Tkw-8n5dnGB4,8
6
- dagster_airbyte/resources.py,sha256=FoHI_Eiw2F6tnI1KZMfkgXhThdU6DplHp6INsbjUFsg,29802
7
- dagster_airbyte/types.py,sha256=fwqUv_MZCegwHhSELgUqm1H1JVUb-m83CyXFkd0r-ko,1425
8
- dagster_airbyte/utils.py,sha256=cFKCkGFAvwr17KFTeqpVtQRDsNo4zpqw9yr2-1YSJeI,2823
9
- dagster_airbyte/version.py,sha256=FVT3zgMnGxhctio1D7Bj2hvIqrqQQ-a9tvDQYKSSekk,23
10
- dagster_airbyte/managed/__init__.py,sha256=azuKhCI8eUsmEGBL2M2d6qkqQ0vhsV9H5IioP83kbm8,423
11
- dagster_airbyte/managed/reconciliation.py,sha256=HgrLT-Xs8vWY9SfbdBXuorMf60KCn5Qz7bPITW5MxJo,34862
12
- dagster_airbyte/managed/types.py,sha256=ja056Wm7_ZFw1XGSNmdxmBy2TcOxbnylJCpRA2ng2TE,14596
13
- dagster_airbyte/managed/generated/__init__.py,sha256=1ChWhXU1uyX_9rClMD6XHzkriKOc0fjIQntsoI3G99g,76
14
- dagster_airbyte/managed/generated/destinations.py,sha256=x1wmWlXvOJHtfaZva3ErdKuVS--sDvfidSXR5ji9G5w,119692
15
- dagster_airbyte/managed/generated/sources.py,sha256=e360ITeAECzqEvHw04onfBWciMntjR2IhoxOd5ibno4,282709
16
- dagster_airbyte-0.24.3.dist-info/LICENSE,sha256=TMatHW4_G9ldRdodEAp-l2Xa2WvsdeOh60E3v1R2jis,11349
17
- dagster_airbyte-0.24.3.dist-info/METADATA,sha256=5cqL9WoNn1ldQGtXnAJ7apgw-bffD_jAE6X9cGTsqeY,926
18
- dagster_airbyte-0.24.3.dist-info/WHEEL,sha256=yQN5g4mg4AybRjkgi-9yy4iQEFibGQmlz78Pik5Or-A,92
19
- dagster_airbyte-0.24.3.dist-info/entry_points.txt,sha256=XrbLOz3LpgPV5fdwMmgdP6Rp1AfSG07KeWIddLqh7Lw,61
20
- dagster_airbyte-0.24.3.dist-info/top_level.txt,sha256=HLwIRQCzqItn88_KbPP8DNTKKQEBUVKk6NCn4PrCtqY,16
21
- dagster_airbyte-0.24.3.dist-info/RECORD,,