dataface 0.2.1.dev599__py3-none-any.whl → 0.2.1.dev647__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.
- dataface/DATAFACE_SYNTAX.md +10 -15
- dataface/agent_api/_paths.py +54 -13
- dataface/agent_api/cache.py +55 -10
- dataface/agent_api/describe.py +16 -16
- dataface/agent_api/docs/yaml-reference.md +37 -16
- dataface/agent_api/mcp_install.py +142 -41
- dataface/agent_api/project_session.py +3 -1
- dataface/agent_api/query.py +14 -12
- dataface/agent_api/schema_hints.py +11 -10
- dataface/agent_api/validate.py +22 -18
- dataface/ai/agent.py +14 -8
- dataface/ai/llm.py +0 -17
- dataface/ai/mcp/server.py +22 -21
- dataface/ai/skills/dashboard-replicate/SKILL.md +38 -6
- dataface/ai/tools/__init__.py +1 -1
- dataface/cli/commands/chat.py +1 -1
- dataface/cli/commands/mcp_init.py +11 -27
- dataface/cli/commands/render.py +34 -13
- dataface/cli/filesystem_project.py +39 -0
- dataface/cli/main.py +25 -6
- dataface/core/compile/compiler.py +140 -11
- dataface/core/compile/config.py +89 -0
- dataface/core/compile/introspection.py +67 -55
- dataface/core/compile/merge.py +4 -2
- dataface/core/compile/models/cache.py +390 -0
- dataface/core/compile/models/chart/authored/__init__.py +16 -0
- dataface/core/compile/models/config.py +52 -0
- dataface/core/compile/models/face/authored.py +20 -0
- dataface/core/compile/models/query/authored.py +7 -3
- dataface/core/compile/models/query/normalized.py +20 -6
- dataface/core/compile/models/source.py +32 -0
- dataface/core/compile/models/style/resolved/_base.py +8 -1
- dataface/core/compile/models/style/resolved/_cascade.py +42 -3
- dataface/core/compile/models/style/theme/axis.py +15 -2
- dataface/core/compile/models/style/theme/board.py +8 -1
- dataface/core/compile/normalize_charts.py +55 -11
- dataface/core/compile/normalize_layout.py +71 -7
- dataface/core/compile/normalize_queries.py +79 -11
- dataface/core/compile/normalize_variables.py +73 -3
- dataface/core/compile/normalizer.py +57 -6
- dataface/core/compile/resolve/_resolve.py +177 -64
- dataface/core/compile/schema_renderers/completion_catalog.py +0 -2
- dataface/core/compile/schema_renderers/highlight_manifest.py +11 -4
- dataface/core/compile/schema_renderers/json_schema.py +120 -12
- dataface/core/compile/schema_renderers/prompt.py +38 -4
- dataface/core/compile/schema_renderers/vscode_schema.py +42 -22
- dataface/core/compile/schema_renderers/yaml_schema.py +26 -6
- dataface/core/compile/source_map.py +91 -10
- dataface/core/compile/style_cascade.py +75 -38
- dataface/core/compile/yaml_error_formatter.py +10 -13
- dataface/core/dashboard.py +43 -23
- dataface/core/defaults/default_config.yml +26 -0
- dataface/core/defaults/themes/editorial.yaml +13 -0
- dataface/core/defaults/themes/neon.yaml +6 -0
- dataface/core/defaults/themes/vivid.yaml +7 -0
- dataface/core/execute/_duckdb_cache_base.py +180 -70
- dataface/core/execute/cache_backend.py +97 -28
- dataface/core/execute/cache_keys.py +15 -3
- dataface/core/execute/executor.py +147 -103
- dataface/core/execute/file_source_materializer.py +4 -3
- dataface/core/execute/trivial_local_cache.py +108 -74
- dataface/core/inspect/renderer.py +1 -0
- dataface/core/project.py +78 -1
- dataface/core/registered_views/query_runner.py +16 -6
- dataface/core/registered_views/render_pipeline.py +7 -7
- dataface/core/render/chart/emitters/area.py +2 -4
- dataface/core/render/chart/emitters/bar.py +25 -35
- dataface/core/render/chart/emitters/heatmap.py +20 -1
- dataface/core/render/chart/emitters/line.py +2 -4
- dataface/core/render/chart/emitters/scatter.py +1 -1
- dataface/core/render/chart/features/endpoint_labels.py +46 -20
- dataface/core/render/chart/vl_field_maps.py +49 -60
- dataface/core/render/converters/html.py +4 -0
- dataface/core/render/dir_context.py +80 -143
- dataface/core/render/faces.py +14 -0
- dataface/core/render/nav.py +4 -3
- dataface/core/render/templates/page.css +7 -2
- dataface/core/render/templates/page.html +3 -2
- dataface/core/render/templates/scripts/chart_interactivity.js +18 -8
- dataface/core/serve/server.py +72 -39
- dataface/data/highlighting/face/v1.json +2 -12
- dataface/integrations/markdown.py +3 -1
- {dataface-0.2.1.dev599.dist-info → dataface-0.2.1.dev647.dist-info}/METADATA +2 -1
- {dataface-0.2.1.dev599.dist-info → dataface-0.2.1.dev647.dist-info}/RECORD +87 -87
- dataface/core/scoped_paths.py +0 -114
- {dataface-0.2.1.dev599.dist-info → dataface-0.2.1.dev647.dist-info}/WHEEL +0 -0
- {dataface-0.2.1.dev599.dist-info → dataface-0.2.1.dev647.dist-info}/entry_points.txt +0 -0
- {dataface-0.2.1.dev599.dist-info → dataface-0.2.1.dev647.dist-info}/licenses/LICENSE +0 -0
dataface/DATAFACE_SYNTAX.md
CHANGED
|
@@ -155,7 +155,7 @@ Reference variables inside queries with bare `{{ region }}` — no `variables.`
|
|
|
155
155
|
charts:
|
|
156
156
|
revenue_trend:
|
|
157
157
|
query: revenue # Named query reference
|
|
158
|
-
type: line # See `dft docs charts` for all
|
|
158
|
+
type: line # See `dft docs charts` for all 16 authorable chart types
|
|
159
159
|
x: month
|
|
160
160
|
y: total
|
|
161
161
|
color: segment
|
|
@@ -531,25 +531,25 @@ charts:
|
|
|
531
531
|
# bar/area families also accept style.orientation and style.stack
|
|
532
532
|
```
|
|
533
533
|
|
|
534
|
-
### Chart types (
|
|
534
|
+
### Chart types (16 authorable)
|
|
535
535
|
|
|
536
536
|
Set `type:` to one of:
|
|
537
537
|
|
|
538
|
-
**Basic** (one mark per chart)
|
|
538
|
+
**Basic** (one mark per chart) -- `bar`, `line`, `area`, `scatter`, `pie`, `donut`, `kpi`, `table`.
|
|
539
539
|
|
|
540
|
-
**Statistical**
|
|
540
|
+
**Statistical** -- `histogram`, `heatmap`.
|
|
541
541
|
|
|
542
|
-
**Geographic**
|
|
542
|
+
**Geographic** -- `geoshape`, `map`, `point_map`, `bubble_map`.
|
|
543
543
|
|
|
544
|
-
**
|
|
544
|
+
**Overlays** -- `bar`, `line`, `area`, and `scatter` accept a `layers:` field for mixed-mark or dual-axis charts (see [Combo charts](#combo-charts-barlinearea-with-layers) and [Composition](#composition)).
|
|
545
545
|
|
|
546
|
-
**
|
|
546
|
+
**Sparklines** -- `spark_bar` (compact horizontal bars used in profiler cards).
|
|
547
547
|
|
|
548
|
-
**
|
|
548
|
+
**Auxiliary** -- `callout` (message card with a `style.tone:` field; `message:` required).
|
|
549
549
|
|
|
550
|
-
|
|
550
|
+
Note: `donut` is an internal alias for `pie` -- `donut` is accepted but normalizes to `pie` internally. `auto` is an internal sentinel (not authored). `boxplot`, `errorbar`, and `errorband` are Vega-Lite mark types that are not in the authorable surface.
|
|
551
551
|
|
|
552
|
-
|
|
552
|
+
Type aliases: `scatter` uses a circle mark, `heatmap` uses rect, `pie`/`donut` use arc, `histogram` uses bar with binning, `map` maps to geoshape.
|
|
553
553
|
|
|
554
554
|
### Shared chart fields
|
|
555
555
|
|
|
@@ -709,11 +709,6 @@ color: event_count
|
|
|
709
709
|
type: histogram
|
|
710
710
|
x: amount
|
|
711
711
|
|
|
712
|
-
# boxplot / errorbar / errorband — statistical primitives
|
|
713
|
-
type: boxplot
|
|
714
|
-
x: region
|
|
715
|
-
y: latency
|
|
716
|
-
|
|
717
712
|
# geoshape — choropleth via GeoJSON
|
|
718
713
|
type: geoshape
|
|
719
714
|
geo_source: us-states
|
dataface/agent_api/_paths.py
CHANGED
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
from __future__ import annotations
|
|
4
4
|
|
|
5
|
+
import os
|
|
5
6
|
from dataclasses import dataclass
|
|
6
7
|
from pathlib import Path
|
|
7
8
|
|
|
@@ -13,15 +14,17 @@ from dataface.core.diagnostics import (
|
|
|
13
14
|
Diagnostic,
|
|
14
15
|
)
|
|
15
16
|
from dataface.core.diagnostics.base import DatafaceError
|
|
16
|
-
from dataface.core.project import
|
|
17
|
+
from dataface.core.project import (
|
|
18
|
+
FACES_SUBDIR,
|
|
19
|
+
FaceFile,
|
|
20
|
+
Project,
|
|
21
|
+
ProjectPath,
|
|
22
|
+
assert_relpath,
|
|
23
|
+
)
|
|
17
24
|
from dataface.core.project_roots import (
|
|
18
25
|
find_dft_root as find_dft_root,
|
|
19
26
|
find_project_root as find_project_root,
|
|
20
27
|
)
|
|
21
|
-
from dataface.core.scoped_paths import (
|
|
22
|
-
resolve_face_path as resolve_face_path,
|
|
23
|
-
resolve_scoped_path as resolve_scoped_path,
|
|
24
|
-
)
|
|
25
28
|
|
|
26
29
|
|
|
27
30
|
def resolve_project_dir(project_dir: Path | None) -> Path:
|
|
@@ -72,6 +75,42 @@ def no_project_hint(project: Project) -> str:
|
|
|
72
75
|
)
|
|
73
76
|
|
|
74
77
|
|
|
78
|
+
def resolve_face_path(path: Path, project: Project) -> ProjectPath:
|
|
79
|
+
"""User/agent-supplied face path -> ProjectPath.
|
|
80
|
+
|
|
81
|
+
Absolute and ``..``-leading paths are explicit locations: they relativize
|
|
82
|
+
through the containment seam (``project.path_for_fspath``, a leading
|
|
83
|
+
``..`` resolving against cwd for CLI shell-nav feel) and are returned
|
|
84
|
+
as-is — no ``faces/`` retry, even when the exact path doesn't exist. A
|
|
85
|
+
bare relative name (no explicit location) gets the faces-first retry: for
|
|
86
|
+
a relpath that doesn't exist in the project store and has no explicit
|
|
87
|
+
``faces/`` prefix, retries under ``FACES_SUBDIR``. This lets a
|
|
88
|
+
``search_dashboards`` ``face_path`` of ``'looker/x.yaml'`` (``faces/``
|
|
89
|
+
prefix stripped at search time) resolve to ``faces/looker/x.yaml``
|
|
90
|
+
without producing a ``faces/faces/...`` double prefix when the caller
|
|
91
|
+
already supplies the full ``faces/looker/x.yaml``.
|
|
92
|
+
|
|
93
|
+
Existence is checked via ``project.exists(...)`` so it works for all
|
|
94
|
+
``Project`` implementations (FilesystemProject, CloudManagedProject
|
|
95
|
+
git-blob store, etc.) — not just the local filesystem. Paths that exist
|
|
96
|
+
at root resolve from root — non-faces paths like ``models/schema.sql``
|
|
97
|
+
are not rewritten under faces/.
|
|
98
|
+
"""
|
|
99
|
+
if path.is_absolute():
|
|
100
|
+
return project.path_for_fspath(path)
|
|
101
|
+
if ".." in path.parts:
|
|
102
|
+
return project.path_for_fspath(Path(os.path.normpath(Path.cwd() / path)))
|
|
103
|
+
relpath = str(path)
|
|
104
|
+
assert_relpath(relpath)
|
|
105
|
+
if project.exists(relpath):
|
|
106
|
+
return project.path(relpath)
|
|
107
|
+
if not relpath.startswith(f"{FACES_SUBDIR}/"):
|
|
108
|
+
candidate = f"{FACES_SUBDIR}/{relpath}"
|
|
109
|
+
if project.exists(candidate):
|
|
110
|
+
return project.path(candidate)
|
|
111
|
+
return project.path(relpath) # caller reports not-found
|
|
112
|
+
|
|
113
|
+
|
|
75
114
|
def resolve_face_or_error(path: Path, project: Project) -> FaceFile | Diagnostic:
|
|
76
115
|
"""Faces-first resolve a path to a stored ``FaceFile``, or a structured error.
|
|
77
116
|
|
|
@@ -85,21 +124,23 @@ def resolve_face_or_error(path: Path, project: Project) -> FaceFile | Diagnostic
|
|
|
85
124
|
resolved = resolve_face_path(path, project)
|
|
86
125
|
except ValueError as exc:
|
|
87
126
|
return DatafaceError.from_code(ERR_INTERNAL, message=str(exc)).to_diagnostic()
|
|
88
|
-
|
|
89
|
-
if not project_path.exists():
|
|
127
|
+
if not resolved.exists():
|
|
90
128
|
return DatafaceError.from_code(
|
|
91
129
|
ERR_FILE_NOT_FOUND,
|
|
92
|
-
path=
|
|
130
|
+
path=resolved.relpath,
|
|
93
131
|
hint=no_project_hint(project),
|
|
94
|
-
).to_diagnostic(file=
|
|
95
|
-
if
|
|
132
|
+
).to_diagnostic(file=resolved.relpath)
|
|
133
|
+
if (
|
|
134
|
+
isinstance(project, FilesystemProject)
|
|
135
|
+
and not (project.root / resolved.relpath).is_file()
|
|
136
|
+
):
|
|
96
137
|
# A directory (or other non-file) resolves + exists on disk but read_face
|
|
97
138
|
# would raise past the structured envelope. This is a filesystem-only
|
|
98
139
|
# concern — a non-filesystem store's `exists()` already gates real faces.
|
|
99
140
|
return DatafaceError.from_code(
|
|
100
|
-
ERR_INTERNAL, message=f"Not a file: {
|
|
101
|
-
).to_diagnostic(file=
|
|
102
|
-
return
|
|
141
|
+
ERR_INTERNAL, message=f"Not a file: {resolved.relpath}"
|
|
142
|
+
).to_diagnostic(file=resolved.relpath)
|
|
143
|
+
return resolved.read_face()
|
|
103
144
|
|
|
104
145
|
|
|
105
146
|
@dataclass(frozen=True)
|
dataface/agent_api/cache.py
CHANGED
|
@@ -1,8 +1,13 @@
|
|
|
1
1
|
"""Cache constructors at the agent_api boundary."""
|
|
2
2
|
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
3
5
|
from collections.abc import Generator
|
|
4
6
|
from contextlib import contextmanager
|
|
5
7
|
from pathlib import Path
|
|
8
|
+
from typing import TYPE_CHECKING
|
|
9
|
+
|
|
10
|
+
from dataface.core.compile.config import resolve_cache_boot
|
|
6
11
|
|
|
7
12
|
# Re-exported: TrivialDuckDBCache is the declared return type of open_cache,
|
|
8
13
|
# so embedders annotating a held cache reach it here without a core import.
|
|
@@ -10,29 +15,69 @@ from dataface.core.execute.trivial_local_cache import (
|
|
|
10
15
|
TrivialDuckDBCache as TrivialDuckDBCache,
|
|
11
16
|
)
|
|
12
17
|
|
|
13
|
-
|
|
18
|
+
if TYPE_CHECKING:
|
|
19
|
+
from dataface.cli.filesystem_project import FilesystemProject
|
|
20
|
+
|
|
21
|
+
__all__ = [
|
|
22
|
+
"TrivialDuckDBCache",
|
|
23
|
+
"open_cache",
|
|
24
|
+
"open_project_cache",
|
|
25
|
+
"project_cache_ctx",
|
|
26
|
+
]
|
|
14
27
|
|
|
15
28
|
|
|
16
29
|
def open_cache(path: Path | None) -> TrivialDuckDBCache:
|
|
17
|
-
"""Open the query-result cache.
|
|
30
|
+
"""Open the query-result cache at an already-resolved path.
|
|
18
31
|
|
|
19
32
|
``path=None`` opens an in-memory cache — ephemeral, discarded when closed.
|
|
20
33
|
A path opens (or creates, if absent) a persistent DuckDB file, reused
|
|
21
34
|
across invocations. Callers own the returned cache's lifecycle (close it).
|
|
35
|
+
Does not consult project config — use ``open_project_cache`` for that.
|
|
22
36
|
"""
|
|
23
37
|
return TrivialDuckDBCache(db_path=path)
|
|
24
38
|
|
|
25
39
|
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
40
|
+
def open_project_cache(
|
|
41
|
+
project: FilesystemProject,
|
|
42
|
+
*,
|
|
43
|
+
no_cache: bool = False,
|
|
44
|
+
cache_path: Path | None = None,
|
|
45
|
+
) -> TrivialDuckDBCache | None:
|
|
46
|
+
"""Open the query-result cache honoring project config, with overrides.
|
|
47
|
+
|
|
48
|
+
The caller owns the project instance. Pair this with
|
|
49
|
+
``ProjectSession.from_project(project, cache=...)`` rather than
|
|
50
|
+
``ProjectSession.open(project_dir, cache=...)`` — ``open()`` builds its own
|
|
51
|
+
project from the path, so composing it with this function constructs two.
|
|
29
52
|
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
53
|
+
Precedence: ``no_cache=True`` (the CLI's ``--no-cache``) skips the cache
|
|
54
|
+
entirely; ``cache_path`` (``--cache PATH``, or its ``DFT_CACHE_PATH`` env
|
|
55
|
+
backing) opens that persistent file. Otherwise the project's
|
|
56
|
+
``dataface.yml`` ``cache:`` block picks the location — a configured ``path``
|
|
57
|
+
opens that file (created if absent); no path opens the zero-config
|
|
58
|
+
in-memory default. A project-level ``cache: false`` defaults the *cascade*
|
|
59
|
+
to off without closing the door on a nearer scope's opt-in, so it still
|
|
60
|
+
opens a store; the resolved per-query policy decides what gets written.
|
|
61
|
+
|
|
62
|
+
Returns:
|
|
63
|
+
``None`` only when ``no_cache=True`` — callers pass this straight
|
|
64
|
+
through as ``ProjectSession(cache=...)``.
|
|
33
65
|
"""
|
|
34
|
-
|
|
66
|
+
boot = resolve_cache_boot(project, no_cache=no_cache, cache_path=cache_path)
|
|
67
|
+
return open_cache(boot.path) if boot.enabled else None
|
|
68
|
+
|
|
69
|
+
|
|
70
|
+
@contextmanager
|
|
71
|
+
def project_cache_ctx(
|
|
72
|
+
project: FilesystemProject,
|
|
73
|
+
*,
|
|
74
|
+
no_cache: bool = False,
|
|
75
|
+
cache_path: Path | None = None,
|
|
76
|
+
) -> Generator[TrivialDuckDBCache | None]:
|
|
77
|
+
"""Context-managed ``open_project_cache``; closes the cache on exit if opened."""
|
|
78
|
+
cache = open_project_cache(project, no_cache=no_cache, cache_path=cache_path)
|
|
35
79
|
try:
|
|
36
80
|
yield cache
|
|
37
81
|
finally:
|
|
38
|
-
cache
|
|
82
|
+
if cache is not None:
|
|
83
|
+
cache.close()
|
dataface/agent_api/describe.py
CHANGED
|
@@ -198,8 +198,8 @@ def describe_face(path: Path, *, project: Project) -> DescribeFaceResult:
|
|
|
198
198
|
],
|
|
199
199
|
)
|
|
200
200
|
|
|
201
|
-
|
|
202
|
-
if not
|
|
201
|
+
resolved_display = project.root / resolved.relpath
|
|
202
|
+
if not resolved.exists():
|
|
203
203
|
hint = no_project_hint(project)
|
|
204
204
|
return DescribeFaceResult(
|
|
205
205
|
success=False,
|
|
@@ -207,21 +207,21 @@ def describe_face(path: Path, *, project: Project) -> DescribeFaceResult:
|
|
|
207
207
|
errors=[
|
|
208
208
|
DatafaceError.from_code(
|
|
209
209
|
ERR_FILE_NOT_FOUND,
|
|
210
|
-
path=
|
|
210
|
+
path=resolved.relpath,
|
|
211
211
|
hint=hint,
|
|
212
212
|
).to_diagnostic()
|
|
213
213
|
],
|
|
214
214
|
)
|
|
215
215
|
|
|
216
216
|
try:
|
|
217
|
-
result = compile_file(
|
|
217
|
+
result = compile_file(resolved.read_face())
|
|
218
218
|
except OSError as exc:
|
|
219
219
|
return DescribeFaceResult(
|
|
220
220
|
success=False,
|
|
221
|
-
path=
|
|
221
|
+
path=resolved_display,
|
|
222
222
|
errors=[
|
|
223
223
|
DatafaceError.from_code(ERR_INTERNAL, message=str(exc)).to_diagnostic(
|
|
224
|
-
file=
|
|
224
|
+
file=resolved.relpath
|
|
225
225
|
)
|
|
226
226
|
],
|
|
227
227
|
)
|
|
@@ -229,7 +229,7 @@ def describe_face(path: Path, *, project: Project) -> DescribeFaceResult:
|
|
|
229
229
|
if result.errors:
|
|
230
230
|
return DescribeFaceResult(
|
|
231
231
|
success=False,
|
|
232
|
-
path=
|
|
232
|
+
path=resolved_display,
|
|
233
233
|
errors=list(result.errors),
|
|
234
234
|
)
|
|
235
235
|
|
|
@@ -237,11 +237,11 @@ def describe_face(path: Path, *, project: Project) -> DescribeFaceResult:
|
|
|
237
237
|
if face is None:
|
|
238
238
|
return DescribeFaceResult(
|
|
239
239
|
success=False,
|
|
240
|
-
path=
|
|
240
|
+
path=resolved_display,
|
|
241
241
|
errors=[
|
|
242
242
|
DatafaceError.from_code(
|
|
243
243
|
ERR_INTERNAL, message="Compilation produced no face"
|
|
244
|
-
).to_diagnostic(file=
|
|
244
|
+
).to_diagnostic(file=resolved.relpath)
|
|
245
245
|
],
|
|
246
246
|
)
|
|
247
247
|
|
|
@@ -285,7 +285,7 @@ def describe_face(path: Path, *, project: Project) -> DescribeFaceResult:
|
|
|
285
285
|
|
|
286
286
|
return DescribeFaceResult(
|
|
287
287
|
success=True,
|
|
288
|
-
path=
|
|
288
|
+
path=resolved_display,
|
|
289
289
|
title=face.title or None,
|
|
290
290
|
description=face.description or None,
|
|
291
291
|
queries=query_descs,
|
|
@@ -339,13 +339,13 @@ def _describe_one_path(
|
|
|
339
339
|
)
|
|
340
340
|
]
|
|
341
341
|
|
|
342
|
-
|
|
343
|
-
|
|
342
|
+
resolved_display = project.root / resolved.relpath
|
|
343
|
+
if not resolved_display.is_dir():
|
|
344
|
+
return [describe_face(resolved_display, project=project)]
|
|
344
345
|
|
|
345
|
-
under = str(resolved.relative_to(project.root))
|
|
346
346
|
faces = sorted(
|
|
347
347
|
project.root / pf.relpath
|
|
348
|
-
for pf in project.iter_faces(under=
|
|
348
|
+
for pf in project.iter_faces(under=resolved.relpath, recursive=True)
|
|
349
349
|
if pf.is_yaml
|
|
350
350
|
and not pf.is_private
|
|
351
351
|
and not (pf.parent / INSPECT_TEMPLATE_MANIFEST).exists()
|
|
@@ -354,11 +354,11 @@ def _describe_one_path(
|
|
|
354
354
|
return [
|
|
355
355
|
DescribeFaceResult(
|
|
356
356
|
success=False,
|
|
357
|
-
path=
|
|
357
|
+
path=resolved_display,
|
|
358
358
|
errors=[
|
|
359
359
|
DatafaceError.from_code(
|
|
360
360
|
ERR_INTERNAL,
|
|
361
|
-
message=f"No face files found in {
|
|
361
|
+
message=f"No face files found in {resolved_display}",
|
|
362
362
|
).to_diagnostic()
|
|
363
363
|
],
|
|
364
364
|
)
|
|
@@ -14,6 +14,7 @@ AuthoredFace (dataface) definition from YAML.
|
|
|
14
14
|
| `text` | str | ✓ | Markdown text content for text-only sections. |
|
|
15
15
|
| `allow_html` | bool | ✓ | Render the face's body text as raw HTML via foreignObject instead of markdown. TRUSTED-CONTENT ONLY: the HTML (including any Jinja-interpolated values) is rendered as-authored — this is NOT a security sandbox. mdsvg strips <script>/event-handlers as a best-effort guard, not a guarantee. Enable only on first-party faces you fully control. |
|
|
16
16
|
| `source` | str | ✓ | Default source name for all queries in this face. Inheritable via meta.yaml cascade. |
|
|
17
|
+
| `cache` | [Cache](#cache) | ✓ | Cache policy for every query in this dashboard, e.g. cache: 1h — queries inherit it and may refine it; cache: false opts the whole dashboard out. Inheritable via the meta.yaml cascade. |
|
|
17
18
|
| `variables` | dict[str, [Variable](#variable) \| VariableRef] | ✓ | Variable definitions for dynamic filtering and UI controls. |
|
|
18
19
|
| `queries` | dict[str, [SqlQuery](#sqlquery) \| [MetricflowQuery](#metricflowquery) \| [HttpQuery](#httpquery) \| [ValuesQuery](#valuesquery) \| [SchemaQuery](#schemaquery) \| [LookmlQuery](#lookmlquery) \| QueryRef] | ✓ | Named query definitions (SQL, CSV, MetricFlow, HTTP, etc.). |
|
|
19
20
|
| `charts` | dict[str, [BarChart](#barchart) \| [LineChart](#linechart) \| [AreaChart](#areachart) \| [ScatterChart](#scatterchart) \| [HeatmapChart](#heatmapchart) \| [PieChart](#piechart) \| [KpiChart](#kpichart) \| [TableChart](#tablechart) \| [PointMapChart](#pointmapchart) \| [GeoshapeChart](#geoshapechart) \| [CalloutChart](#calloutchart) \| [SparkBarChart](#sparkbarchart) \| ChartRef] | ✓ | Named chart definitions. When no explicit layout is present, charts render as an implicit row layout in authored order. |
|
|
@@ -32,6 +33,14 @@ AuthoredFace (dataface) definition from YAML.
|
|
|
32
33
|
| `extends` | str \| list[str] | ✓ | Face name(s) or relative path(s) this face inherits from, low to high priority. |
|
|
33
34
|
| `auto_link` | bool | ✓ | When True, table charts with no explicit link: automatically link each row to its canonical /data/<source>/<schema>/<table>/detail/ page. Default off. Explicit link: always wins; set link: ~ to suppress per chart. |
|
|
34
35
|
|
|
36
|
+
<a id="cache"></a>
|
|
37
|
+
## Cache
|
|
38
|
+
Cache policy at one scope: cache: 1h / forever / true / false (the only opt-out).
|
|
39
|
+
|
|
40
|
+
| Field | Type | Optional | Description |
|
|
41
|
+
|-------|------|:--------:|-------------|
|
|
42
|
+
| `ttl` | str \| enum: "forever" | ✓ | Expire cached results after this wall-clock age (lazy: the next read recomputes). Short-duration string: units s/m/h/d/w, m = minutes, compound allowed ('1h30m'). Omit to inherit from the parent scope; write 'forever' to override an inherited ttl with never-auto-expire (manual refresh always remains available). |
|
|
43
|
+
|
|
35
44
|
<a id="variable"></a>
|
|
36
45
|
## Variable
|
|
37
46
|
Variable definition from YAML.
|
|
@@ -67,7 +76,7 @@ Raw SQL query — the default query type.
|
|
|
67
76
|
| `source` | str \| dict[str, Any] | ✓ | Source name reference, or an inline file path (e.g. `./data/sales.csv`). File paths are detected by `/` or data file extension. An inline connection-bearing dict (`{type: postgres, ...}`) is rejected at compile time — reference a named source instead. |
|
|
68
77
|
| `description` | str | ✓ | Human-readable description of the query. Used by AI search and tooling. |
|
|
69
78
|
| `ignore` | list[str] | ✓ | Diagnostic codes to suppress for this query (e.g., ['WARN-FANOUT-RISK', 'WARN-REAGGREGATION']). |
|
|
70
|
-
| `cache` |
|
|
79
|
+
| `cache` | [Cache](#cache) | ✓ | Cache policy override for this query, e.g. cache: 5m — refines the policy inherited from the source and project scopes; cache: false opts out of result caching entirely. Queries with cache: false cannot be used as {{ queries.X.cache }} upstream references. |
|
|
71
80
|
| `type` | enum: "sql" | ✓ | Query adapter type. |
|
|
72
81
|
| `sql` | str | ✓ | SQL query string. Supports Jinja2 templates referencing variables. |
|
|
73
82
|
| `setup_sql` | str | ✓ | Non-nestable SQL preamble executed before the main query (e.g., CREATE TEMP FUNCTION). |
|
|
@@ -82,7 +91,7 @@ dbt Semantic Layer (MetricFlow) query.
|
|
|
82
91
|
| `source` | str \| dict[str, Any] | ✓ | Source name reference, or an inline file path (e.g. `./data/sales.csv`). File paths are detected by `/` or data file extension. An inline connection-bearing dict (`{type: postgres, ...}`) is rejected at compile time — reference a named source instead. |
|
|
83
92
|
| `description` | str | ✓ | Human-readable description of the query. Used by AI search and tooling. |
|
|
84
93
|
| `ignore` | list[str] | ✓ | Diagnostic codes to suppress for this query (e.g., ['WARN-FANOUT-RISK', 'WARN-REAGGREGATION']). |
|
|
85
|
-
| `cache` |
|
|
94
|
+
| `cache` | [Cache](#cache) | ✓ | Cache policy override for this query, e.g. cache: 5m — refines the policy inherited from the source and project scopes; cache: false opts out of result caching entirely. Queries with cache: false cannot be used as {{ queries.X.cache }} upstream references. |
|
|
86
95
|
| `type` | enum: "metricflow" | ✓ | Query adapter type. |
|
|
87
96
|
| `metrics` | list[str] | ✓ | MetricFlow metric names to query. |
|
|
88
97
|
| `dimensions` | list[str] | ✓ | MetricFlow dimensions to include in the result. |
|
|
@@ -99,7 +108,7 @@ REST API query.
|
|
|
99
108
|
| `source` | str \| dict[str, Any] | ✓ | Source name reference, or an inline file path (e.g. `./data/sales.csv`). File paths are detected by `/` or data file extension. An inline connection-bearing dict (`{type: postgres, ...}`) is rejected at compile time — reference a named source instead. |
|
|
100
109
|
| `description` | str | ✓ | Human-readable description of the query. Used by AI search and tooling. |
|
|
101
110
|
| `ignore` | list[str] | ✓ | Diagnostic codes to suppress for this query (e.g., ['WARN-FANOUT-RISK', 'WARN-REAGGREGATION']). |
|
|
102
|
-
| `cache` |
|
|
111
|
+
| `cache` | [Cache](#cache) | ✓ | Cache policy override for this query, e.g. cache: 5m — refines the policy inherited from the source and project scopes; cache: false opts out of result caching entirely. Queries with cache: false cannot be used as {{ queries.X.cache }} upstream references. |
|
|
103
112
|
| `type` | enum: "http" | ✓ | Query adapter type. |
|
|
104
113
|
| `url` | str | ✓ | HTTP endpoint URL for REST API queries. |
|
|
105
114
|
| `method` | enum: "GET", "POST", "PUT", "DELETE", "PATCH" | ✓ | HTTP method (GET, POST, PUT, DELETE, PATCH). |
|
|
@@ -118,7 +127,7 @@ Inline rows embedded in YAML.
|
|
|
118
127
|
| `source` | str \| dict[str, Any] | ✓ | Source name reference, or an inline file path (e.g. `./data/sales.csv`). File paths are detected by `/` or data file extension. An inline connection-bearing dict (`{type: postgres, ...}`) is rejected at compile time — reference a named source instead. |
|
|
119
128
|
| `description` | str | ✓ | Human-readable description of the query. Used by AI search and tooling. |
|
|
120
129
|
| `ignore` | list[str] | ✓ | Diagnostic codes to suppress for this query (e.g., ['WARN-FANOUT-RISK', 'WARN-REAGGREGATION']). |
|
|
121
|
-
| `cache` |
|
|
130
|
+
| `cache` | [Cache](#cache) | ✓ | Cache policy override for this query, e.g. cache: 5m — refines the policy inherited from the source and project scopes; cache: false opts out of result caching entirely. Queries with cache: false cannot be used as {{ queries.X.cache }} upstream references. |
|
|
122
131
|
| `type` | enum: "values" | ✓ | Query adapter type. |
|
|
123
132
|
| `rows` | list[dict[str, Any]] | ✓ | Inline data rows (list of row dicts). |
|
|
124
133
|
| `values` | list[list[Any]] | ✓ | Inline row-oriented data (list of lists) for the compact 'columns + values' syntax. |
|
|
@@ -133,7 +142,7 @@ dbt source schema query.
|
|
|
133
142
|
| `source` | str \| dict[str, Any] | ✓ | Source name reference, or an inline file path (e.g. `./data/sales.csv`). File paths are detected by `/` or data file extension. An inline connection-bearing dict (`{type: postgres, ...}`) is rejected at compile time — reference a named source instead. |
|
|
134
143
|
| `description` | str | ✓ | Human-readable description of the query. Used by AI search and tooling. |
|
|
135
144
|
| `ignore` | list[str] | ✓ | Diagnostic codes to suppress for this query (e.g., ['WARN-FANOUT-RISK', 'WARN-REAGGREGATION']). |
|
|
136
|
-
| `cache` |
|
|
145
|
+
| `cache` | [Cache](#cache) | ✓ | Cache policy override for this query, e.g. cache: 5m — refines the policy inherited from the source and project scopes; cache: false opts out of result caching entirely. Queries with cache: false cannot be used as {{ queries.X.cache }} upstream references. |
|
|
137
146
|
| `type` | enum: "schema" | ✓ | Query adapter type. |
|
|
138
147
|
| `schema` | str | ✓ | Schema name for schema queries (YAML key: schema). |
|
|
139
148
|
| `table` | str | ✓ | Table name for schema queries. |
|
|
@@ -148,7 +157,7 @@ LookML semantic query — compiled to SQL through likeml at compile time.
|
|
|
148
157
|
| `source` | str \| dict[str, Any] | ✓ | Source name reference, or an inline file path (e.g. `./data/sales.csv`). File paths are detected by `/` or data file extension. An inline connection-bearing dict (`{type: postgres, ...}`) is rejected at compile time — reference a named source instead. |
|
|
149
158
|
| `description` | str | ✓ | Human-readable description of the query. Used by AI search and tooling. |
|
|
150
159
|
| `ignore` | list[str] | ✓ | Diagnostic codes to suppress for this query (e.g., ['WARN-FANOUT-RISK', 'WARN-REAGGREGATION']). |
|
|
151
|
-
| `cache` |
|
|
160
|
+
| `cache` | [Cache](#cache) | ✓ | Cache policy override for this query, e.g. cache: 5m — refines the policy inherited from the source and project scopes; cache: false opts out of result caching entirely. Queries with cache: false cannot be used as {{ queries.X.cache }} upstream references. |
|
|
152
161
|
| `type` | enum: "lookml" | ✓ | Query adapter type. |
|
|
153
162
|
| `explore` | str | ✓ | LookML explore name. Presence of this key infers type: lookml. |
|
|
154
163
|
| `merge` | list[dict[str, Any]] | ✓ | LookML merge sources — a list of source specs. Each is either an explore spec ({explore, fields, filters?, merge_on?}) or a query reference ({query, columns, merge_on?}) for a derived source such as a table-calc wrapper. First is the primary; each secondary's `merge_on` maps its key to the primary's. Presence of this key infers type: lookml. Compiled to a FULL OUTER JOIN via likeml. |
|
|
@@ -1057,7 +1066,7 @@ Authored overlay for BoardStyle. Face-level structural dimensions. Do NOT cascad
|
|
|
1057
1066
|
|
|
1058
1067
|
| Field | Type | Optional | Description |
|
|
1059
1068
|
|-------|------|:--------:|-------------|
|
|
1060
|
-
| `width` | float | ✓ | Maximum dashboard width in pixels. |
|
|
1069
|
+
| `width` | float | ✓ | Maximum dashboard width in pixels. Caps the measured layout width, setting the board's proportions. Rendered as an on-screen pixel maximum everywhere except the dft HTML page (dft serve, dft render --format html), which scales the board to its container. |
|
|
1061
1070
|
| `min_height` | float | ✓ | Minimum board height in pixels. |
|
|
1062
1071
|
| `margin` | float | ✓ | Board outer margin in pixels. |
|
|
1063
1072
|
| `card_padding` | float | ✓ | Padding added to each card side in pixels. |
|
|
@@ -2227,7 +2236,7 @@ Authored overlay for AxisElementStyle. Axis label or title: font + padding + VL-
|
|
|
2227
2236
|
| `padding` | float | ✓ | Padding between axis labels and ticks in pixels; None inherits from parent axis. |
|
|
2228
2237
|
| `max_width` | float | ✓ | Maximum label width in pixels; None uses Vega-Lite's default (180px). |
|
|
2229
2238
|
| `angle` | float | ✓ | Label rotation angle in degrees; None uses Vega-Lite's default. |
|
|
2230
|
-
| `align` |
|
|
2239
|
+
| `align` | enum: "left", "right", "center", "inward", "outward" | ✓ | Horizontal text alignment of labels. 'left'/'right'/'center' are absolute. 'inward' hugs the plot (own-side: left on a left axis, right on a right axis); 'outward' hugs away from the plot (Vega-Lite's default growth direction). inward/outward are a no-op on an axis with no left/right edge. None uses Vega-Lite's default. |
|
|
2231
2240
|
| `baseline` | str | ✓ | Vertical text baseline of labels; None uses Vega-Lite's default. |
|
|
2232
2241
|
| `overlap` | [AxisLabelOverlapConfig](#axislabeloverlapconfig) | ✓ | Label overlap strategy enablement. None inherits from the theme cascade. Set individual bools to enable/disable; the resolver applies them in fixed order tilt→skip. Temporal-bucketed axes ignore this and step the label cadence instead. |
|
|
2233
2242
|
| `separation` | float | ✓ | Minimum pixel separation between labels; None uses Vega-Lite's default (0px). |
|
|
@@ -2799,6 +2808,7 @@ Postgres source configuration.
|
|
|
2799
2808
|
| `dbname` | str | | Database name (matches dbt 'dbname'). |
|
|
2800
2809
|
| `user` | str | | Database user name. |
|
|
2801
2810
|
| `password` | str | | Database password. |
|
|
2811
|
+
| `cache` | [Cache](#cache) | ✓ | Cache policy default for every query against this source, e.g. cache: 1h — queries inherit it and may refine it; cache: false opts them out. |
|
|
2802
2812
|
| `lookml_path` | str | ✓ | Relative path to the directory of .lkml files backing this source's models. |
|
|
2803
2813
|
| `models` | dict[str, [LookMLModelConfig](#lookmlmodelconfig)] | ✓ | Named LookML model collections nested under this source. |
|
|
2804
2814
|
| `port` | int | ✓ | Database port number. |
|
|
@@ -2816,6 +2826,7 @@ Snowflake source configuration.
|
|
|
2816
2826
|
| `user` | str | | Snowflake user name. |
|
|
2817
2827
|
| `database` | str | | Snowflake database name. |
|
|
2818
2828
|
| `warehouse` | str | | Snowflake virtual warehouse name. |
|
|
2829
|
+
| `cache` | [Cache](#cache) | ✓ | Cache policy default for every query against this source, e.g. cache: 1h — queries inherit it and may refine it; cache: false opts them out. |
|
|
2819
2830
|
| `lookml_path` | str | ✓ | Relative path to the directory of .lkml files backing this source's models. |
|
|
2820
2831
|
| `models` | dict[str, [LookMLModelConfig](#lookmlmodelconfig)] | ✓ | Named LookML model collections nested under this source. |
|
|
2821
2832
|
| `password` | str | ✓ | Snowflake password. Omit when using OAuth or key-pair auth. |
|
|
@@ -2831,6 +2842,7 @@ BigQuery source configuration.
|
|
|
2831
2842
|
| `type` | enum: "bigquery" | | Source type identifier. |
|
|
2832
2843
|
| `project` | str | | GCP project ID. |
|
|
2833
2844
|
| `dataset` | str | | BigQuery dataset name (equivalent to schema). |
|
|
2845
|
+
| `cache` | [Cache](#cache) | ✓ | Cache policy default for every query against this source, e.g. cache: 1h — queries inherit it and may refine it; cache: false opts them out. |
|
|
2834
2846
|
| `lookml_path` | str | ✓ | Relative path to the directory of .lkml files backing this source's models. |
|
|
2835
2847
|
| `models` | dict[str, [LookMLModelConfig](#lookmlmodelconfig)] | ✓ | Named LookML model collections nested under this source. |
|
|
2836
2848
|
| `keyfile` | str | ✓ | Path to service account JSON key file. |
|
|
@@ -2849,6 +2861,7 @@ Redshift source configuration.
|
|
|
2849
2861
|
| `dbname` | str | | Redshift database name. |
|
|
2850
2862
|
| `user` | str | | Redshift user name. |
|
|
2851
2863
|
| `password` | str | | Redshift password. |
|
|
2864
|
+
| `cache` | [Cache](#cache) | ✓ | Cache policy default for every query against this source, e.g. cache: 1h — queries inherit it and may refine it; cache: false opts them out. |
|
|
2852
2865
|
| `lookml_path` | str | ✓ | Relative path to the directory of .lkml files backing this source's models. |
|
|
2853
2866
|
| `models` | dict[str, [LookMLModelConfig](#lookmlmodelconfig)] | ✓ | Named LookML model collections nested under this source. |
|
|
2854
2867
|
| `port` | int | ✓ | Redshift port number. |
|
|
@@ -2865,6 +2878,7 @@ MySQL source configuration.
|
|
|
2865
2878
|
| `database` | str | | MySQL database name. |
|
|
2866
2879
|
| `user` | str | | MySQL user name. |
|
|
2867
2880
|
| `password` | str | | MySQL password. |
|
|
2881
|
+
| `cache` | [Cache](#cache) | ✓ | Cache policy default for every query against this source, e.g. cache: 1h — queries inherit it and may refine it; cache: false opts them out. |
|
|
2868
2882
|
| `lookml_path` | str | ✓ | Relative path to the directory of .lkml files backing this source's models. |
|
|
2869
2883
|
| `models` | dict[str, [LookMLModelConfig](#lookmlmodelconfig)] | ✓ | Named LookML model collections nested under this source. |
|
|
2870
2884
|
| `port` | int | ✓ | MySQL port number. |
|
|
@@ -2877,6 +2891,7 @@ DuckDB source configuration.
|
|
|
2877
2891
|
| Field | Type | Optional | Description |
|
|
2878
2892
|
|-------|------|:--------:|-------------|
|
|
2879
2893
|
| `type` | enum: "duckdb" | | Source type identifier. |
|
|
2894
|
+
| `cache` | [Cache](#cache) | ✓ | Cache policy default for every query against this source, e.g. cache: 1h — queries inherit it and may refine it; cache: false opts them out. |
|
|
2880
2895
|
| `lookml_path` | str | ✓ | Relative path to the directory of .lkml files backing this source's models. |
|
|
2881
2896
|
| `models` | dict[str, [LookMLModelConfig](#lookmlmodelconfig)] | ✓ | Named LookML model collections nested under this source. |
|
|
2882
2897
|
| `path` | str | ✓ | DuckDB file path or ':memory:' for an in-memory database. |
|
|
@@ -2892,6 +2907,7 @@ SQLite source configuration.
|
|
|
2892
2907
|
| `path` | str | | Path to the SQLite database file. |
|
|
2893
2908
|
| `lookml_path` | str | ✓ | Relative path to the directory of .lkml files backing this source's models. |
|
|
2894
2909
|
| `models` | dict[str, [LookMLModelConfig](#lookmlmodelconfig)] | ✓ | Named LookML model collections nested under this source. |
|
|
2910
|
+
| `cache` | [Cache](#cache) | ✓ | Cache policy default for every query against this source, e.g. cache: 1h — queries inherit it and may refine it; cache: false opts them out. |
|
|
2895
2911
|
|
|
2896
2912
|
<a id="csvsourceconfig"></a>
|
|
2897
2913
|
## CsvSourceConfig
|
|
@@ -2901,6 +2917,7 @@ CSV file source configuration.
|
|
|
2901
2917
|
|-------|------|:--------:|-------------|
|
|
2902
2918
|
| `type` | enum: "csv" | | Source type identifier. |
|
|
2903
2919
|
| `files` | dict[str, str] | | Mapping of table_name → file path. Each key is the SQL table name; the value is the path relative to the project root. Required and must not be empty. |
|
|
2920
|
+
| `cache` | [Cache](#cache) | ✓ | Cache policy default for every query against this source, e.g. cache: 1h — queries inherit it and may refine it; cache: false opts them out. |
|
|
2904
2921
|
| `delimiter` | str | ✓ | Field delimiter character. |
|
|
2905
2922
|
| `encoding` | str | ✓ | File encoding. |
|
|
2906
2923
|
|
|
@@ -2908,19 +2925,21 @@ CSV file source configuration.
|
|
|
2908
2925
|
## ParquetSourceConfig
|
|
2909
2926
|
Parquet file source configuration.
|
|
2910
2927
|
|
|
2911
|
-
| Field | Type | Description |
|
|
2912
|
-
|
|
2913
|
-
| `type` | enum: "parquet" | Source type identifier. |
|
|
2914
|
-
| `files` | dict[str, str] | Mapping of table_name → file path. Each key is the SQL table name; the value is the path relative to the project root. Required and must not be empty. |
|
|
2928
|
+
| Field | Type | Optional | Description |
|
|
2929
|
+
|-------|------|:--------:|-------------|
|
|
2930
|
+
| `type` | enum: "parquet" | | Source type identifier. |
|
|
2931
|
+
| `files` | dict[str, str] | | Mapping of table_name → file path. Each key is the SQL table name; the value is the path relative to the project root. Required and must not be empty. |
|
|
2932
|
+
| `cache` | [Cache](#cache) | ✓ | Cache policy default for every query against this source, e.g. cache: 1h — queries inherit it and may refine it; cache: false opts them out. |
|
|
2915
2933
|
|
|
2916
2934
|
<a id="jsonsourceconfig"></a>
|
|
2917
2935
|
## JsonSourceConfig
|
|
2918
2936
|
JSON file source configuration.
|
|
2919
2937
|
|
|
2920
|
-
| Field | Type | Description |
|
|
2921
|
-
|
|
2922
|
-
| `type` | enum: "json" | Source type identifier. |
|
|
2923
|
-
| `files` | dict[str, str] | Mapping of table_name → file path. Each key is the SQL table name; the value is the path relative to the project root. Required and must not be empty. |
|
|
2938
|
+
| Field | Type | Optional | Description |
|
|
2939
|
+
|-------|------|:--------:|-------------|
|
|
2940
|
+
| `type` | enum: "json" | | Source type identifier. |
|
|
2941
|
+
| `files` | dict[str, str] | | Mapping of table_name → file path. Each key is the SQL table name; the value is the path relative to the project root. Required and must not be empty. |
|
|
2942
|
+
| `cache` | [Cache](#cache) | ✓ | Cache policy default for every query against this source, e.g. cache: 1h — queries inherit it and may refine it; cache: false opts them out. |
|
|
2924
2943
|
|
|
2925
2944
|
<a id="httpsourceconfig"></a>
|
|
2926
2945
|
## HttpSourceConfig
|
|
@@ -2930,6 +2949,7 @@ HTTP/REST API source configuration.
|
|
|
2930
2949
|
|-------|------|:--------:|-------------|
|
|
2931
2950
|
| `type` | enum: "http" | | Source type identifier. |
|
|
2932
2951
|
| `url` | str | | Base URL for HTTP requests. |
|
|
2952
|
+
| `cache` | [Cache](#cache) | ✓ | Cache policy default for every query against this source, e.g. cache: 1h — queries inherit it and may refine it; cache: false opts them out. |
|
|
2933
2953
|
| `headers` | dict[str, str] | ✓ | Default HTTP headers (e.g. Authorization). |
|
|
2934
2954
|
|
|
2935
2955
|
<a id="dbtprofilesourceconfig"></a>
|
|
@@ -2940,6 +2960,7 @@ Reference to a dbt profile.
|
|
|
2940
2960
|
|-------|------|:--------:|-------------|
|
|
2941
2961
|
| `type` | enum: "dbt_profile" | | Source type identifier. |
|
|
2942
2962
|
| `profile` | str | | dbt profile name from profiles.yml. |
|
|
2963
|
+
| `cache` | [Cache](#cache) | ✓ | Cache policy default for every query against this source, e.g. cache: 1h — queries inherit it and may refine it; cache: false opts them out. |
|
|
2943
2964
|
| `target` | str | ✓ | dbt target to use; defaults to the profile's default target. |
|
|
2944
2965
|
| `profiles_dir` | str | ✓ | Directory containing profiles.yml, relative to the dataface project root. Use when profiles.yml is in a subdirectory (e.g. services/dbt). Resolution order: profiles_dir → $DBT_PROFILES_DIR → project root → ~/.dbt. |
|
|
2945
2966
|
|