-
Notifications
You must be signed in to change notification settings - Fork 19
feat(cdk): update ConfigComponentsResolver to support list of stream_config #553
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from 2 commits
1a41386
5c0581a
0485b20
a125c96
fcb9087
99b4e08
c7ab8a7
950443e
89066c8
c932185
51d40a6
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -4,7 +4,8 @@ | |
|
||
from copy import deepcopy | ||
from dataclasses import InitVar, dataclass, field | ||
from typing import Any, Dict, Iterable, List, Mapping, Union | ||
from itertools import product | ||
from typing import Any, Dict, Iterable, List, Mapping, Optional, Union | ||
|
||
import dpath | ||
from typing_extensions import deprecated | ||
|
@@ -28,6 +29,7 @@ class StreamConfig: | |
|
||
configs_pointer: List[Union[InterpolatedString, str]] | ||
parameters: InitVar[Mapping[str, Any]] | ||
default_values: Optional[List[Any]] = None | ||
|
||
def __post_init__(self, parameters: Mapping[str, Any]) -> None: | ||
self.configs_pointer = [ | ||
|
@@ -48,7 +50,7 @@ class ConfigComponentsResolver(ComponentsResolver): | |
parameters (InitVar[Mapping[str, Any]]): Additional parameters for interpolation. | ||
""" | ||
|
||
stream_config: StreamConfig | ||
stream_configs: List[StreamConfig] | ||
config: Config | ||
components_mapping: List[ComponentMappingDefinition] | ||
parameters: InitVar[Mapping[str, Any]] | ||
|
@@ -82,6 +84,7 @@ def __post_init__(self, parameters: Mapping[str, Any]) -> None: | |
field_path=field_path, | ||
value=interpolated_value, | ||
value_type=component_mapping.value_type, | ||
create_or_update=component_mapping.create_or_update, | ||
parameters=parameters, | ||
) | ||
) | ||
|
@@ -91,17 +94,35 @@ def __post_init__(self, parameters: Mapping[str, Any]) -> None: | |
) | ||
|
||
@property | ||
def _stream_config(self) -> Iterable[Mapping[str, Any]]: | ||
path = [ | ||
node.eval(self.config) if not isinstance(node, str) else node | ||
for node in self.stream_config.configs_pointer | ||
] | ||
stream_config = dpath.get(dict(self.config), path, default=[]) | ||
|
||
if not isinstance(stream_config, list): | ||
stream_config = [stream_config] | ||
|
||
return stream_config | ||
def _stream_config(self): | ||
def resolve_path(pointer): | ||
return [ | ||
node.eval(self.config) if not isinstance(node, str) else node for node in pointer | ||
] | ||
|
||
def normalize_configs(configs): | ||
return configs if isinstance(configs, list) else [configs] | ||
|
||
def prepare_streams(): | ||
for stream_config in self.stream_configs: | ||
path = resolve_path(stream_config.configs_pointer) | ||
stream_configs = dpath.get(dict(self.config), path, default=[]) | ||
stream_configs = normalize_configs(stream_configs) | ||
if stream_config.default_values: | ||
stream_configs += stream_config.default_values | ||
coderabbitai[bot] marked this conversation as resolved.
Show resolved
Hide resolved
|
||
yield [(i, item) for i, item in enumerate(stream_configs)] | ||
|
||
def merge_combination(combo): | ||
result = {} | ||
for config_index, (elem_index, elem) in enumerate(combo): | ||
if isinstance(elem, dict): | ||
result.update(elem) | ||
else: | ||
result.setdefault(f"source_config_{config_index}", (elem_index, elem)) | ||
return result | ||
|
||
all_indexed_streams = list(prepare_streams()) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The result of And if we were to do that, then we may want to just make |
||
return [merge_combination(combo) for combo in product(*all_indexed_streams)] | ||
|
||
def resolve_components( | ||
self, stream_template_config: Dict[str, Any] | ||
|
@@ -130,7 +151,21 @@ def resolve_components( | |
) | ||
|
||
path = [path.eval(self.config, **kwargs) for path in resolved_component.field_path] | ||
parsed_value = self._parse_yaml_if_possible(value) | ||
updated = dpath.set(updated_config, path, parsed_value) | ||
|
||
dpath.set(updated_config, path, value) | ||
if parsed_value and not updated and resolved_component.create_or_update: | ||
dpath.new(updated_config, path, parsed_value) | ||
|
||
yield updated_config | ||
|
||
@staticmethod | ||
def _parse_yaml_if_possible(value: Any) -> Any: | ||
if isinstance(value, str): | ||
try: | ||
import yaml | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Import this at the top level instead of inline |
||
|
||
return yaml.safe_load(value) | ||
except Exception: | ||
return value | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. When is it not the case that this isn't parsable in yaml? It seems like in most scenario this should always be parsable and if it wasn't we throw an error. Would it be because the spec/config might be JSON instead of yaml? Or at best we may want to have stricter error handling against a specific error type instead of all. |
||
return value |
Uh oh!
There was an error while loading. Please reload this page.