dvt-core 1.11.0b4__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.
Potentially problematic release.
This version of dvt-core might be problematic. Click here for more details.
- dvt/__init__.py +7 -0
- dvt/_pydantic_shim.py +26 -0
- dvt/adapters/__init__.py +16 -0
- dvt/adapters/multi_adapter_manager.py +268 -0
- dvt/artifacts/__init__.py +0 -0
- dvt/artifacts/exceptions/__init__.py +1 -0
- dvt/artifacts/exceptions/schemas.py +31 -0
- dvt/artifacts/resources/__init__.py +116 -0
- dvt/artifacts/resources/base.py +68 -0
- dvt/artifacts/resources/types.py +93 -0
- dvt/artifacts/resources/v1/analysis.py +10 -0
- dvt/artifacts/resources/v1/catalog.py +23 -0
- dvt/artifacts/resources/v1/components.py +275 -0
- dvt/artifacts/resources/v1/config.py +282 -0
- dvt/artifacts/resources/v1/documentation.py +11 -0
- dvt/artifacts/resources/v1/exposure.py +52 -0
- dvt/artifacts/resources/v1/function.py +53 -0
- dvt/artifacts/resources/v1/generic_test.py +32 -0
- dvt/artifacts/resources/v1/group.py +22 -0
- dvt/artifacts/resources/v1/hook.py +11 -0
- dvt/artifacts/resources/v1/macro.py +30 -0
- dvt/artifacts/resources/v1/metric.py +173 -0
- dvt/artifacts/resources/v1/model.py +146 -0
- dvt/artifacts/resources/v1/owner.py +10 -0
- dvt/artifacts/resources/v1/saved_query.py +112 -0
- dvt/artifacts/resources/v1/seed.py +42 -0
- dvt/artifacts/resources/v1/semantic_layer_components.py +72 -0
- dvt/artifacts/resources/v1/semantic_model.py +315 -0
- dvt/artifacts/resources/v1/singular_test.py +14 -0
- dvt/artifacts/resources/v1/snapshot.py +92 -0
- dvt/artifacts/resources/v1/source_definition.py +85 -0
- dvt/artifacts/resources/v1/sql_operation.py +10 -0
- dvt/artifacts/resources/v1/unit_test_definition.py +78 -0
- dvt/artifacts/schemas/__init__.py +0 -0
- dvt/artifacts/schemas/base.py +191 -0
- dvt/artifacts/schemas/batch_results.py +24 -0
- dvt/artifacts/schemas/catalog/__init__.py +12 -0
- dvt/artifacts/schemas/catalog/v1/__init__.py +0 -0
- dvt/artifacts/schemas/catalog/v1/catalog.py +60 -0
- dvt/artifacts/schemas/freshness/__init__.py +1 -0
- dvt/artifacts/schemas/freshness/v3/__init__.py +0 -0
- dvt/artifacts/schemas/freshness/v3/freshness.py +159 -0
- dvt/artifacts/schemas/manifest/__init__.py +2 -0
- dvt/artifacts/schemas/manifest/v12/__init__.py +0 -0
- dvt/artifacts/schemas/manifest/v12/manifest.py +212 -0
- dvt/artifacts/schemas/results.py +148 -0
- dvt/artifacts/schemas/run/__init__.py +2 -0
- dvt/artifacts/schemas/run/v5/__init__.py +0 -0
- dvt/artifacts/schemas/run/v5/run.py +184 -0
- dvt/artifacts/schemas/upgrades/__init__.py +4 -0
- dvt/artifacts/schemas/upgrades/upgrade_manifest.py +174 -0
- dvt/artifacts/schemas/upgrades/upgrade_manifest_dbt_version.py +2 -0
- dvt/artifacts/utils/validation.py +153 -0
- dvt/cli/__init__.py +1 -0
- dvt/cli/context.py +16 -0
- dvt/cli/exceptions.py +56 -0
- dvt/cli/flags.py +558 -0
- dvt/cli/main.py +971 -0
- dvt/cli/option_types.py +121 -0
- dvt/cli/options.py +79 -0
- dvt/cli/params.py +803 -0
- dvt/cli/requires.py +478 -0
- dvt/cli/resolvers.py +32 -0
- dvt/cli/types.py +40 -0
- dvt/clients/__init__.py +0 -0
- dvt/clients/checked_load.py +82 -0
- dvt/clients/git.py +164 -0
- dvt/clients/jinja.py +206 -0
- dvt/clients/jinja_static.py +245 -0
- dvt/clients/registry.py +192 -0
- dvt/clients/yaml_helper.py +68 -0
- dvt/compilation.py +833 -0
- dvt/compute/__init__.py +26 -0
- dvt/compute/base.py +288 -0
- dvt/compute/engines/__init__.py +13 -0
- dvt/compute/engines/duckdb_engine.py +368 -0
- dvt/compute/engines/spark_engine.py +273 -0
- dvt/compute/query_analyzer.py +212 -0
- dvt/compute/router.py +483 -0
- dvt/config/__init__.py +4 -0
- dvt/config/catalogs.py +95 -0
- dvt/config/compute_config.py +406 -0
- dvt/config/profile.py +411 -0
- dvt/config/profiles_v2.py +464 -0
- dvt/config/project.py +893 -0
- dvt/config/renderer.py +232 -0
- dvt/config/runtime.py +491 -0
- dvt/config/selectors.py +209 -0
- dvt/config/utils.py +78 -0
- dvt/connectors/.gitignore +6 -0
- dvt/connectors/README.md +306 -0
- dvt/connectors/catalog.yml +217 -0
- dvt/connectors/download_connectors.py +300 -0
- dvt/constants.py +29 -0
- dvt/context/__init__.py +0 -0
- dvt/context/base.py +746 -0
- dvt/context/configured.py +136 -0
- dvt/context/context_config.py +350 -0
- dvt/context/docs.py +82 -0
- dvt/context/exceptions_jinja.py +179 -0
- dvt/context/macro_resolver.py +195 -0
- dvt/context/macros.py +171 -0
- dvt/context/manifest.py +73 -0
- dvt/context/providers.py +2198 -0
- dvt/context/query_header.py +14 -0
- dvt/context/secret.py +59 -0
- dvt/context/target.py +74 -0
- dvt/contracts/__init__.py +0 -0
- dvt/contracts/files.py +413 -0
- dvt/contracts/graph/__init__.py +0 -0
- dvt/contracts/graph/manifest.py +1904 -0
- dvt/contracts/graph/metrics.py +98 -0
- dvt/contracts/graph/model_config.py +71 -0
- dvt/contracts/graph/node_args.py +42 -0
- dvt/contracts/graph/nodes.py +1806 -0
- dvt/contracts/graph/semantic_manifest.py +233 -0
- dvt/contracts/graph/unparsed.py +812 -0
- dvt/contracts/project.py +417 -0
- dvt/contracts/results.py +53 -0
- dvt/contracts/selection.py +23 -0
- dvt/contracts/sql.py +86 -0
- dvt/contracts/state.py +69 -0
- dvt/contracts/util.py +46 -0
- dvt/deprecations.py +347 -0
- dvt/deps/__init__.py +0 -0
- dvt/deps/base.py +153 -0
- dvt/deps/git.py +196 -0
- dvt/deps/local.py +80 -0
- dvt/deps/registry.py +131 -0
- dvt/deps/resolver.py +149 -0
- dvt/deps/tarball.py +121 -0
- dvt/docs/source/_ext/dbt_click.py +118 -0
- dvt/docs/source/conf.py +32 -0
- dvt/env_vars.py +64 -0
- dvt/event_time/event_time.py +40 -0
- dvt/event_time/sample_window.py +60 -0
- dvt/events/__init__.py +16 -0
- dvt/events/base_types.py +37 -0
- dvt/events/core_types_pb2.py +2 -0
- dvt/events/logging.py +109 -0
- dvt/events/types.py +2534 -0
- dvt/exceptions.py +1487 -0
- dvt/flags.py +89 -0
- dvt/graph/__init__.py +11 -0
- dvt/graph/cli.py +248 -0
- dvt/graph/graph.py +172 -0
- dvt/graph/queue.py +213 -0
- dvt/graph/selector.py +375 -0
- dvt/graph/selector_methods.py +976 -0
- dvt/graph/selector_spec.py +223 -0
- dvt/graph/thread_pool.py +18 -0
- dvt/hooks.py +21 -0
- dvt/include/README.md +49 -0
- dvt/include/__init__.py +3 -0
- dvt/include/global_project.py +4 -0
- dvt/include/starter_project/.gitignore +4 -0
- dvt/include/starter_project/README.md +15 -0
- dvt/include/starter_project/__init__.py +3 -0
- dvt/include/starter_project/analyses/.gitkeep +0 -0
- dvt/include/starter_project/dvt_project.yml +36 -0
- dvt/include/starter_project/macros/.gitkeep +0 -0
- dvt/include/starter_project/models/example/my_first_dbt_model.sql +27 -0
- dvt/include/starter_project/models/example/my_second_dbt_model.sql +6 -0
- dvt/include/starter_project/models/example/schema.yml +21 -0
- dvt/include/starter_project/seeds/.gitkeep +0 -0
- dvt/include/starter_project/snapshots/.gitkeep +0 -0
- dvt/include/starter_project/tests/.gitkeep +0 -0
- dvt/internal_deprecations.py +27 -0
- dvt/jsonschemas/__init__.py +3 -0
- dvt/jsonschemas/jsonschemas.py +309 -0
- dvt/jsonschemas/project/0.0.110.json +4717 -0
- dvt/jsonschemas/project/0.0.85.json +2015 -0
- dvt/jsonschemas/resources/0.0.110.json +2636 -0
- dvt/jsonschemas/resources/0.0.85.json +2536 -0
- dvt/jsonschemas/resources/latest.json +6773 -0
- dvt/links.py +4 -0
- dvt/materializations/__init__.py +0 -0
- dvt/materializations/incremental/__init__.py +0 -0
- dvt/materializations/incremental/microbatch.py +235 -0
- dvt/mp_context.py +8 -0
- dvt/node_types.py +37 -0
- dvt/parser/__init__.py +23 -0
- dvt/parser/analysis.py +21 -0
- dvt/parser/base.py +549 -0
- dvt/parser/common.py +267 -0
- dvt/parser/docs.py +52 -0
- dvt/parser/fixtures.py +51 -0
- dvt/parser/functions.py +30 -0
- dvt/parser/generic_test.py +100 -0
- dvt/parser/generic_test_builders.py +334 -0
- dvt/parser/hooks.py +119 -0
- dvt/parser/macros.py +137 -0
- dvt/parser/manifest.py +2204 -0
- dvt/parser/models.py +574 -0
- dvt/parser/partial.py +1179 -0
- dvt/parser/read_files.py +445 -0
- dvt/parser/schema_generic_tests.py +423 -0
- dvt/parser/schema_renderer.py +111 -0
- dvt/parser/schema_yaml_readers.py +936 -0
- dvt/parser/schemas.py +1467 -0
- dvt/parser/search.py +149 -0
- dvt/parser/seeds.py +28 -0
- dvt/parser/singular_test.py +20 -0
- dvt/parser/snapshots.py +44 -0
- dvt/parser/sources.py +557 -0
- dvt/parser/sql.py +63 -0
- dvt/parser/unit_tests.py +622 -0
- dvt/plugins/__init__.py +20 -0
- dvt/plugins/contracts.py +10 -0
- dvt/plugins/exceptions.py +2 -0
- dvt/plugins/manager.py +164 -0
- dvt/plugins/manifest.py +21 -0
- dvt/profiler.py +20 -0
- dvt/py.typed +1 -0
- dvt/runners/__init__.py +2 -0
- dvt/runners/exposure_runner.py +7 -0
- dvt/runners/no_op_runner.py +46 -0
- dvt/runners/saved_query_runner.py +7 -0
- dvt/selected_resources.py +8 -0
- dvt/task/__init__.py +0 -0
- dvt/task/base.py +504 -0
- dvt/task/build.py +197 -0
- dvt/task/clean.py +57 -0
- dvt/task/clone.py +162 -0
- dvt/task/compile.py +151 -0
- dvt/task/compute.py +366 -0
- dvt/task/debug.py +650 -0
- dvt/task/deps.py +280 -0
- dvt/task/docs/__init__.py +3 -0
- dvt/task/docs/generate.py +408 -0
- dvt/task/docs/index.html +250 -0
- dvt/task/docs/serve.py +28 -0
- dvt/task/freshness.py +323 -0
- dvt/task/function.py +122 -0
- dvt/task/group_lookup.py +46 -0
- dvt/task/init.py +374 -0
- dvt/task/list.py +237 -0
- dvt/task/printer.py +176 -0
- dvt/task/profiles.py +256 -0
- dvt/task/retry.py +175 -0
- dvt/task/run.py +1146 -0
- dvt/task/run_operation.py +142 -0
- dvt/task/runnable.py +802 -0
- dvt/task/seed.py +104 -0
- dvt/task/show.py +150 -0
- dvt/task/snapshot.py +57 -0
- dvt/task/sql.py +111 -0
- dvt/task/test.py +464 -0
- dvt/tests/fixtures/__init__.py +1 -0
- dvt/tests/fixtures/project.py +620 -0
- dvt/tests/util.py +651 -0
- dvt/tracking.py +529 -0
- dvt/utils/__init__.py +3 -0
- dvt/utils/artifact_upload.py +151 -0
- dvt/utils/utils.py +408 -0
- dvt/version.py +249 -0
- dvt_core-1.11.0b4.dist-info/METADATA +252 -0
- dvt_core-1.11.0b4.dist-info/RECORD +261 -0
- dvt_core-1.11.0b4.dist-info/WHEEL +5 -0
- dvt_core-1.11.0b4.dist-info/entry_points.txt +2 -0
- dvt_core-1.11.0b4.dist-info/top_level.txt +1 -0
dvt/config/renderer.py
ADDED
|
@@ -0,0 +1,232 @@
|
|
|
1
|
+
import re
|
|
2
|
+
from datetime import date
|
|
3
|
+
from typing import Any, Callable, Dict, Optional, Tuple, Union
|
|
4
|
+
|
|
5
|
+
from dvt.clients.jinja import get_rendered
|
|
6
|
+
from dvt.constants import DEPENDENCIES_FILE_NAME, SECRET_PLACEHOLDER
|
|
7
|
+
from dvt.context.base import BaseContext
|
|
8
|
+
from dvt.context.secret import SecretContext
|
|
9
|
+
from dvt.context.target import TargetContext
|
|
10
|
+
from dvt.exceptions import DbtProjectError
|
|
11
|
+
|
|
12
|
+
from dbt.adapters.contracts.connection import HasCredentials
|
|
13
|
+
from dbt_common.clients.jinja import catch_jinja
|
|
14
|
+
from dbt_common.constants import SECRET_ENV_PREFIX
|
|
15
|
+
from dbt_common.context import get_invocation_context
|
|
16
|
+
from dbt_common.exceptions import CompilationError, RecursionError
|
|
17
|
+
from dbt_common.utils import deep_map_render
|
|
18
|
+
|
|
19
|
+
Keypath = Tuple[Union[str, int], ...]
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
class BaseRenderer:
|
|
23
|
+
def __init__(self, context: Dict[str, Any]) -> None:
|
|
24
|
+
self.context = context
|
|
25
|
+
|
|
26
|
+
@property
|
|
27
|
+
def name(self):
|
|
28
|
+
return "Rendering"
|
|
29
|
+
|
|
30
|
+
def should_render_keypath(self, keypath: Keypath) -> bool:
|
|
31
|
+
return True
|
|
32
|
+
|
|
33
|
+
def render_entry(self, value: Any, keypath: Keypath) -> Any:
|
|
34
|
+
if not self.should_render_keypath(keypath):
|
|
35
|
+
return value
|
|
36
|
+
|
|
37
|
+
return self.render_value(value, keypath)
|
|
38
|
+
|
|
39
|
+
def render_value(self, value: Any, keypath: Optional[Keypath] = None) -> Any:
|
|
40
|
+
# keypath is ignored (and someone who knows should explain why here)
|
|
41
|
+
if not isinstance(value, str):
|
|
42
|
+
return value if not isinstance(value, date) else value.isoformat()
|
|
43
|
+
|
|
44
|
+
try:
|
|
45
|
+
with catch_jinja():
|
|
46
|
+
return get_rendered(value, self.context, native=True)
|
|
47
|
+
except CompilationError as exc:
|
|
48
|
+
msg = f"Could not render {value}: {exc.msg}"
|
|
49
|
+
raise CompilationError(msg) from exc
|
|
50
|
+
|
|
51
|
+
def render_data(self, data: Dict[str, Any]) -> Dict[str, Any]:
|
|
52
|
+
try:
|
|
53
|
+
return deep_map_render(self.render_entry, data)
|
|
54
|
+
except RecursionError:
|
|
55
|
+
raise DbtProjectError(
|
|
56
|
+
f"Cycle detected: {self.name} input has a reference to itself", project=data
|
|
57
|
+
)
|
|
58
|
+
|
|
59
|
+
|
|
60
|
+
def _list_if_none(value):
|
|
61
|
+
if value is None:
|
|
62
|
+
value = []
|
|
63
|
+
return value
|
|
64
|
+
|
|
65
|
+
|
|
66
|
+
def _dict_if_none(value):
|
|
67
|
+
if value is None:
|
|
68
|
+
value = {}
|
|
69
|
+
return value
|
|
70
|
+
|
|
71
|
+
|
|
72
|
+
def _list_if_none_or_string(value):
|
|
73
|
+
value = _list_if_none(value)
|
|
74
|
+
if isinstance(value, str):
|
|
75
|
+
return [value]
|
|
76
|
+
return value
|
|
77
|
+
|
|
78
|
+
|
|
79
|
+
class ProjectPostprocessor(Dict[Keypath, Callable[[Any], Any]]):
|
|
80
|
+
def __init__(self) -> None:
|
|
81
|
+
super().__init__()
|
|
82
|
+
|
|
83
|
+
self[("on-run-start",)] = _list_if_none_or_string
|
|
84
|
+
self[("on-run-end",)] = _list_if_none_or_string
|
|
85
|
+
|
|
86
|
+
for k in ("models", "seeds", "snapshots"):
|
|
87
|
+
self[(k,)] = _dict_if_none
|
|
88
|
+
self[(k, "vars")] = _dict_if_none
|
|
89
|
+
self[(k, "pre-hook")] = _list_if_none_or_string
|
|
90
|
+
self[(k, "post-hook")] = _list_if_none_or_string
|
|
91
|
+
self[("seeds", "column_types")] = _dict_if_none
|
|
92
|
+
|
|
93
|
+
def postprocess(self, value: Any, key: Keypath) -> Any:
|
|
94
|
+
if key in self:
|
|
95
|
+
handler = self[key]
|
|
96
|
+
return handler(value)
|
|
97
|
+
|
|
98
|
+
return value
|
|
99
|
+
|
|
100
|
+
|
|
101
|
+
class DbtProjectYamlRenderer(BaseRenderer):
|
|
102
|
+
_KEYPATH_HANDLERS = ProjectPostprocessor()
|
|
103
|
+
|
|
104
|
+
def __init__(
|
|
105
|
+
self, profile: Optional[HasCredentials] = None, cli_vars: Optional[Dict[str, Any]] = None
|
|
106
|
+
) -> None:
|
|
107
|
+
# Generate contexts here because we want to save the context
|
|
108
|
+
# object in order to retrieve the env_vars. This is almost always
|
|
109
|
+
# a TargetContext, but in the debug task we want a project
|
|
110
|
+
# even when we don't have a profile.
|
|
111
|
+
if cli_vars is None:
|
|
112
|
+
cli_vars = {}
|
|
113
|
+
if profile:
|
|
114
|
+
self.ctx_obj = TargetContext(profile.to_target_dict(), cli_vars)
|
|
115
|
+
else:
|
|
116
|
+
self.ctx_obj = BaseContext(cli_vars) # type:ignore
|
|
117
|
+
context = self.ctx_obj.to_dict()
|
|
118
|
+
super().__init__(context)
|
|
119
|
+
|
|
120
|
+
@property
|
|
121
|
+
def name(self):
|
|
122
|
+
"Project config"
|
|
123
|
+
|
|
124
|
+
# Uses SecretRenderer
|
|
125
|
+
def get_package_renderer(self) -> BaseRenderer:
|
|
126
|
+
return PackageRenderer(self.ctx_obj.cli_vars)
|
|
127
|
+
|
|
128
|
+
def render_project(
|
|
129
|
+
self,
|
|
130
|
+
project: Dict[str, Any],
|
|
131
|
+
project_root: str,
|
|
132
|
+
) -> Dict[str, Any]:
|
|
133
|
+
"""Render the project and insert the project root after rendering."""
|
|
134
|
+
rendered_project = self.render_data(project)
|
|
135
|
+
rendered_project["project-root"] = project_root
|
|
136
|
+
return rendered_project
|
|
137
|
+
|
|
138
|
+
def render_packages(self, packages: Dict[str, Any], packages_specified_path: str):
|
|
139
|
+
"""Render the given packages dict"""
|
|
140
|
+
packages = packages or {} # Sometimes this is none in tests
|
|
141
|
+
package_renderer = self.get_package_renderer()
|
|
142
|
+
if packages_specified_path == DEPENDENCIES_FILE_NAME:
|
|
143
|
+
# We don't want to render the "packages" dictionary that came from dependencies.yml
|
|
144
|
+
return packages
|
|
145
|
+
else:
|
|
146
|
+
return package_renderer.render_data(packages)
|
|
147
|
+
|
|
148
|
+
def render_selectors(self, selectors: Dict[str, Any]):
|
|
149
|
+
return self.render_data(selectors)
|
|
150
|
+
|
|
151
|
+
def render_entry(self, value: Any, keypath: Keypath) -> Any:
|
|
152
|
+
result = super().render_entry(value, keypath)
|
|
153
|
+
return self._KEYPATH_HANDLERS.postprocess(result, keypath)
|
|
154
|
+
|
|
155
|
+
def should_render_keypath(self, keypath: Keypath) -> bool:
|
|
156
|
+
if not keypath:
|
|
157
|
+
return True
|
|
158
|
+
|
|
159
|
+
first = keypath[0]
|
|
160
|
+
# run hooks are not rendered
|
|
161
|
+
if first in {"on-run-start", "on-run-end", "query-comment"}:
|
|
162
|
+
return False
|
|
163
|
+
|
|
164
|
+
# don't render vars blocks until runtime
|
|
165
|
+
if first == "vars":
|
|
166
|
+
return False
|
|
167
|
+
|
|
168
|
+
if first in {"seeds", "models", "snapshots", "tests", "data_tests"}:
|
|
169
|
+
keypath_parts = {(k.lstrip("+ ") if isinstance(k, str) else k) for k in keypath}
|
|
170
|
+
# model-level hooks
|
|
171
|
+
late_rendered_hooks = {"pre-hook", "post-hook", "pre_hook", "post_hook"}
|
|
172
|
+
if keypath_parts.intersection(late_rendered_hooks):
|
|
173
|
+
return False
|
|
174
|
+
|
|
175
|
+
return True
|
|
176
|
+
|
|
177
|
+
|
|
178
|
+
class SecretRenderer(BaseRenderer):
|
|
179
|
+
def __init__(self, cli_vars: Dict[str, Any] = {}) -> None:
|
|
180
|
+
# Generate contexts here because we want to save the context
|
|
181
|
+
# object in order to retrieve the env_vars.
|
|
182
|
+
self.ctx_obj = SecretContext(cli_vars)
|
|
183
|
+
context = self.ctx_obj.to_dict()
|
|
184
|
+
super().__init__(context)
|
|
185
|
+
|
|
186
|
+
@property
|
|
187
|
+
def name(self):
|
|
188
|
+
return "Secret"
|
|
189
|
+
|
|
190
|
+
def render_value(self, value: Any, keypath: Optional[Keypath] = None) -> Any:
|
|
191
|
+
# First, standard Jinja rendering, with special handling for 'secret' environment variables
|
|
192
|
+
# "{{ env_var('DBT_SECRET_ENV_VAR') }}" -> "$$$DBT_SECRET_START$$$DBT_SECRET_ENV_{VARIABLE_NAME}$$$DBT_SECRET_END$$$"
|
|
193
|
+
# This prevents Jinja manipulation of secrets via macros/filters that might leak partial/modified values in logs
|
|
194
|
+
|
|
195
|
+
try:
|
|
196
|
+
rendered = super().render_value(value, keypath)
|
|
197
|
+
except Exception as ex:
|
|
198
|
+
if keypath and "password" in keypath:
|
|
199
|
+
# Passwords sometimes contain jinja-esque characters, but we
|
|
200
|
+
# don't want to render them if they aren't valid jinja.
|
|
201
|
+
rendered = value
|
|
202
|
+
else:
|
|
203
|
+
raise ex
|
|
204
|
+
|
|
205
|
+
# Now, detect instances of the placeholder value ($$$DBT_SECRET_START...DBT_SECRET_END$$$)
|
|
206
|
+
# and replace them with the actual secret value
|
|
207
|
+
if SECRET_ENV_PREFIX in str(rendered):
|
|
208
|
+
search_group = f"({SECRET_ENV_PREFIX}(.*))"
|
|
209
|
+
pattern = SECRET_PLACEHOLDER.format(search_group).replace("$", r"\$")
|
|
210
|
+
m = re.search(
|
|
211
|
+
pattern,
|
|
212
|
+
rendered,
|
|
213
|
+
)
|
|
214
|
+
if m:
|
|
215
|
+
found = m.group(1)
|
|
216
|
+
value = get_invocation_context().env[found]
|
|
217
|
+
replace_this = SECRET_PLACEHOLDER.format(found)
|
|
218
|
+
return rendered.replace(replace_this, value)
|
|
219
|
+
else:
|
|
220
|
+
return rendered
|
|
221
|
+
|
|
222
|
+
|
|
223
|
+
class ProfileRenderer(SecretRenderer):
|
|
224
|
+
@property
|
|
225
|
+
def name(self):
|
|
226
|
+
return "Profile"
|
|
227
|
+
|
|
228
|
+
|
|
229
|
+
class PackageRenderer(SecretRenderer):
|
|
230
|
+
@property
|
|
231
|
+
def name(self):
|
|
232
|
+
return "Packages config"
|