Skip to content

Commit 38f7da6

Browse files
author
Oleksandr Bazarnov
committed
updated the order of operations; normalization should go after pre-processing > type propagation
1 parent 297ae37 commit 38f7da6

File tree

1 file changed

+66
-22
lines changed

1 file changed

+66
-22
lines changed

airbyte_cdk/sources/declarative/manifest_declarative_source.py

Lines changed: 66 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -103,34 +103,18 @@ def __init__(
103103
normalize_manifest: Optional flag to indicate if the manifest should be normalized.
104104
"""
105105
self.logger = logging.getLogger(f"airbyte.{self.name}")
106-
106+
self._should_normalize = normalize_manifest
107107
self._declarative_component_schema = _get_declarative_component_schema()
108108
# For ease of use we don't require the type to be specified at the top level manifest, but it should be included during processing
109109
manifest = dict(source_config)
110-
if "type" not in manifest:
111-
manifest["type"] = "DeclarativeSource"
112-
110+
self._fix_source_type(manifest)
113111
# If custom components are needed, locate and/or register them.
114112
self.components_module: ModuleType | None = get_registered_components_module(config=config)
115-
116113
# resolve all `$ref` references in the manifest
117-
resolved_source_config = ManifestReferenceResolver().preprocess_manifest(manifest)
114+
self._preprocess_manifest(manifest)
118115
# resolve all components in the manifest
119-
propagated_source_config = ManifestComponentTransformer().propagate_types_and_parameters(
120-
"", resolved_source_config, {}
121-
)
122-
123-
if normalize_manifest:
124-
# Connector Builder UI rendering requires the manifest to be in a specific format.
125-
# 1) references have been resolved
126-
# 2) the commonly used definitions are extracted to the `definitions.shared.*`
127-
# 3) ! the normalized manifest could be validated only after the additional UI post-processing.
128-
propagated_source_config = ManifestNormalizer(
129-
propagated_source_config,
130-
self._declarative_component_schema,
131-
).normalize()
132-
133-
self._source_config = propagated_source_config
116+
self._propagate_types_and_parameters(manifest)
117+
self._source_config = manifest
134118
self._debug = debug
135119
self._emit_connector_builder_messages = emit_connector_builder_messages
136120
self._constructor = (
@@ -145,14 +129,74 @@ def __init__(
145129
self._slice_logger: SliceLogger = (
146130
AlwaysLogSliceLogger() if emit_connector_builder_messages else DebugSliceLogger()
147131
)
148-
149132
self._config = config or {}
133+
# validate resolved manifest against the declarative component schema
150134
self._validate_source()
135+
# apply additional post-processing to the manifest
136+
self._normalize_manifest()
151137

152138
@property
153139
def resolved_manifest(self) -> Mapping[str, Any]:
140+
"""
141+
Returns the resolved manifest configuration for the source.
142+
143+
This property provides access to the internal source configuration as a mapping,
144+
which contains all settings and parameters required to define the source's behavior.
145+
146+
Returns:
147+
Mapping[str, Any]: The resolved source configuration manifest.
148+
"""
154149
return self._source_config
155150

151+
def _preprocess_manifest(self, manifest: Dict[str, Any]) -> None:
152+
"""
153+
Preprocesses the provided manifest dictionary by resolving any manifest references.
154+
155+
This method modifies the input manifest in place, resolving references using the
156+
ManifestReferenceResolver to ensure all references within the manifest are properly handled.
157+
158+
Args:
159+
manifest (Dict[str, Any]): The manifest dictionary to preprocess and resolve references in.
160+
161+
Returns:
162+
None
163+
"""
164+
ManifestReferenceResolver().preprocess_manifest(manifest)
165+
166+
def _propagate_types_and_parameters(self, manifest: Dict[str, Any]) -> None:
167+
"""
168+
Propagates types and parameters throughout the provided manifest.
169+
170+
This method utilizes the ManifestComponentTransformer to traverse and update the manifest dictionary,
171+
ensuring that types and parameters are correctly propagated from the root to all nested components.
172+
173+
Args:
174+
manifest (Dict[str, Any]): The manifest dictionary to update with propagated types and parameters.
175+
176+
Returns:
177+
None
178+
"""
179+
ManifestComponentTransformer().propagate_types_and_parameters("", manifest, {})
180+
181+
def _normalize_manifest(self) -> None:
182+
"""
183+
This method is used to normalize the manifest. It should be called after the manifest has been validated.
184+
185+
Connector Builder UI rendering requires the manifest to be in a specific format.
186+
- references have been resolved
187+
- the commonly used definitions are extracted to the `definitions.linked.*`
188+
"""
189+
if self._should_normalize:
190+
normalizer = ManifestNormalizer(self._source_config, self._declarative_component_schema)
191+
self._source_config = normalizer.normalize()
192+
193+
def _fix_source_type(self, manifest: Dict[str, Any]) -> None:
194+
"""
195+
Fix the source type in the manifest. This is necessary because the source type is not always set in the manifest.
196+
"""
197+
if "type" not in manifest:
198+
manifest["type"] = "DeclarativeSource"
199+
156200
@property
157201
def message_repository(self) -> MessageRepository:
158202
return self._message_repository

0 commit comments

Comments
 (0)