dataface 0.1.6.dev558__py3-none-any.whl → 0.1.6.dev622__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 +14 -1
- dataface/agent_api/__init__.py +10 -1
- dataface/agent_api/docs/yaml-reference.md +19 -30
- dataface/agent_api/validate.py +1 -1
- dataface/cli/_error_format.py +13 -2
- dataface/cli/commands/render.py +100 -0
- dataface/cli/main.py +85 -28
- dataface/core/compile/compiler.py +8 -9
- dataface/core/compile/errors.py +18 -47
- dataface/core/compile/filter_injection.py +12 -2
- dataface/core/compile/jinja.py +54 -4
- dataface/core/compile/models/chart/normalized.py +1 -1
- dataface/core/compile/models/chart/resolved.py +6 -6
- dataface/core/compile/models/style/authored.py +3 -15
- dataface/core/compile/models/style/resolved.py +0 -3
- dataface/core/compile/models/style/theme.py +35 -31
- dataface/core/compile/normalize_variables.py +155 -31
- dataface/core/compile/normalizer.py +20 -5
- dataface/core/compile/parser.py +5 -22
- dataface/core/compile/schema_renderers/highlight_manifest.py +79 -0
- dataface/core/compile/schema_renderers/prompt.py +4 -1
- dataface/core/compile/schema_renderers/textmate_grammar.py +548 -0
- dataface/core/compile/style_cascade.py +35 -13
- dataface/core/compile/yaml_error_formatter.py +28 -322
- dataface/core/defaults/themes/_base.yaml +27 -3
- dataface/core/errors/codes_compile.py +48 -0
- dataface/core/errors/structured.py +0 -4
- dataface/core/execute/adapters/databricks_connection_manager.py +158 -0
- dataface/core/execute/adapters/dbt_adapter_factory.py +58 -18
- dataface/core/execute/adapters/sql_adapter.py +2 -3
- dataface/core/render/chart/callout.py +296 -57
- dataface/core/render/chart/decisions.py +6 -2
- dataface/core/render/chart/pipeline.py +60 -23
- dataface/core/render/chart/profile.py +42 -46
- dataface/core/render/chart/rendering.py +1 -0
- dataface/core/render/chart/spark.py +76 -2
- dataface/core/render/chart/standard_renderer.py +25 -31
- dataface/core/render/chart/table.py +35 -13
- dataface/core/render/chart/vl_field_maps.py +5 -0
- dataface/core/render/warnings/bar_color_1_to_1_with_x.py +2 -2
- dataface/data/highlighting/face/v1.json +82 -0
- dataface/integrations/highlighting.py +30 -1
- {dataface-0.1.6.dev558.dist-info → dataface-0.1.6.dev622.dist-info}/METADATA +1 -1
- {dataface-0.1.6.dev558.dist-info → dataface-0.1.6.dev622.dist-info}/RECORD +48 -45
- mdsvg/renderer.py +18 -2
- dataface/data/highlighting/sql_block_scalar_keys.json +0 -4
- {dataface-0.1.6.dev558.dist-info → dataface-0.1.6.dev622.dist-info}/WHEEL +0 -0
- {dataface-0.1.6.dev558.dist-info → dataface-0.1.6.dev622.dist-info}/entry_points.txt +0 -0
- {dataface-0.1.6.dev558.dist-info → dataface-0.1.6.dev622.dist-info}/licenses/LICENSE +0 -0
dataface/DATAFACE_SYNTAX.md
CHANGED
|
@@ -114,6 +114,12 @@ rows:
|
|
|
114
114
|
### Queries (named, parameterized, inline)
|
|
115
115
|
|
|
116
116
|
```yaml
|
|
117
|
+
variables:
|
|
118
|
+
region:
|
|
119
|
+
input: select
|
|
120
|
+
options:
|
|
121
|
+
static: [US, EU, APAC]
|
|
122
|
+
|
|
117
123
|
queries:
|
|
118
124
|
# Bare-string form — SQL inherits the face-level source
|
|
119
125
|
revenue: SELECT month, SUM(amount) AS total FROM orders GROUP BY 1 ORDER BY 1
|
|
@@ -342,6 +348,12 @@ Queries are the data layer. Charts reference queries by name; queries never embe
|
|
|
342
348
|
```yaml
|
|
343
349
|
source: my_profile # Optional: default source for every query below
|
|
344
350
|
|
|
351
|
+
variables:
|
|
352
|
+
region:
|
|
353
|
+
input: select
|
|
354
|
+
options:
|
|
355
|
+
static: [US, EU, APAC]
|
|
356
|
+
|
|
345
357
|
queries:
|
|
346
358
|
# SQL — the default. `type: sql` is implicit when `sql:` is present.
|
|
347
359
|
revenue: SELECT month, SUM(amount) AS total FROM orders GROUP BY 1 ORDER BY 1
|
|
@@ -423,6 +435,7 @@ Queries are Jinja-rendered before execution. Reference variables as bare names
|
|
|
423
435
|
```yaml
|
|
424
436
|
variables:
|
|
425
437
|
region: { input: select, options: { static: [US, EU, APAC] } }
|
|
438
|
+
period: { input: daterange }
|
|
426
439
|
|
|
427
440
|
queries:
|
|
428
441
|
sales:
|
|
@@ -518,7 +531,7 @@ charts:
|
|
|
518
531
|
style: # Chart-local style patch (typed; not raw CSS) — paint only
|
|
519
532
|
orientation: vertical # style: does NOT accept height or aspect_ratio
|
|
520
533
|
number_format: ",.0f" # D3 format string or named alias for axis/tooltip format
|
|
521
|
-
stack: zero #
|
|
534
|
+
stack: zero # none | zero | normalize | center
|
|
522
535
|
```
|
|
523
536
|
|
|
524
537
|
### Chart types (29 total)
|
dataface/agent_api/__init__.py
CHANGED
|
@@ -53,11 +53,18 @@ from dataface.agent_api.schema_hints import (
|
|
|
53
53
|
SchemaHints as SchemaHints,
|
|
54
54
|
schema_hints as schema_hints,
|
|
55
55
|
)
|
|
56
|
-
from dataface.agent_api.validate import
|
|
56
|
+
from dataface.agent_api.validate import (
|
|
57
|
+
ValidateDashboardArgs,
|
|
58
|
+
ValidateResult,
|
|
59
|
+
)
|
|
57
60
|
from dataface.agent_api.validate_query import (
|
|
58
61
|
QueryDiagnostic as QueryDiagnostic,
|
|
59
62
|
validate_query as validate_query,
|
|
60
63
|
)
|
|
64
|
+
from dataface.core.compile.compiler import (
|
|
65
|
+
CompileResult as CompileResult,
|
|
66
|
+
compile as compile,
|
|
67
|
+
)
|
|
61
68
|
from dataface.core.compile.config import ProjectSourcesConfig as ProjectSourcesConfig
|
|
62
69
|
from dataface.core.dashboard import (
|
|
63
70
|
RenderedDashboard as RenderedDashboard,
|
|
@@ -69,6 +76,8 @@ from dataface.core.render.board_links import LinkContext as LinkContext
|
|
|
69
76
|
from dataface.core.render.errors import RenderError as RenderError
|
|
70
77
|
|
|
71
78
|
__all__ = [
|
|
79
|
+
"compile",
|
|
80
|
+
"CompileResult",
|
|
72
81
|
"DescribeFaceArgs",
|
|
73
82
|
"DescribeFaceResult",
|
|
74
83
|
"DocsArgs",
|
|
@@ -578,7 +578,6 @@ Authored overlay for BarChartStyle. Bar chart style: chart-level fields + marks
|
|
|
578
578
|
| `animation_duration` | float | ✓ | Vega-Lite animation duration in milliseconds. Falls back to [`style.charts.animation_duration`](#chartsstyle). |
|
|
579
579
|
| `palette` | list[str] \| str | ✓ | Ordered list of categorical color stops or a palette name; expanded from a palette name at validation time. Falls back to [`style.charts.palette`](#chartsstyle). |
|
|
580
580
|
| `single_series_palette` | list[str] \| str | ✓ | Ordered list of single-series mark inks (must be non-empty), or a palette name. Cycled across single-series charts in face reading order. Falls back to [`style.charts.single_series_palette`](#chartsstyle). |
|
|
581
|
-
| `inference` | [InferenceStyle](#inferencestyle) | ✓ | Engine inference behavior flags. |
|
|
582
581
|
| `legend` | [LegendStyle](#legendstyle) | ✓ | Chart legend style. |
|
|
583
582
|
| `tooltip` | [TooltipStyle](#tooltipstyle) | ✓ | Per-chart-type tooltip style override; None uses the universal style.charts.tooltip. |
|
|
584
583
|
| `background` | str | ✓ | Chart-local background color override; None inherits from theme. |
|
|
@@ -595,7 +594,7 @@ Authored overlay for BarChartStyle. Bar chart style: chart-level fields + marks
|
|
|
595
594
|
| `range` | [RangeStyle](#rangestyle) | ✓ | Color range/palette overrides for this chart type; None means no override. |
|
|
596
595
|
| `data_table` | [DataTableStyle](#datatablestyle) | ✓ | Per-chart-type data_table style override. Unset fields fall back to [`style.charts.data_table`](#chartsstyle). |
|
|
597
596
|
| `orientation` | enum: "horizontal", "vertical", "auto" | ✓ | Preferred bar orientation; None uses the renderer default (vertical). |
|
|
598
|
-
| `stack` | enum: "zero", "normalize", "center" | ✓ | Default stack mode for bar charts;
|
|
597
|
+
| `stack` | enum: "none", "zero", "normalize", "center" | ✓ | Default stack mode for bar charts; none renders side-by-side columns. |
|
|
599
598
|
| `stack_order` | enum: "value", "data", "alphabetical" | ✓ | Z-order of stacked segments. None/'value' puts the largest aggregate at baseline. 'data' follows SQL row order (orientation-stable not guaranteed). 'alphabetical' sorts by color field name. Ignored when stacking is off or no color. |
|
|
600
599
|
| `endpoint_labels` | [EndpointLabelsConfig](#endpointlabelsconfig) | ✓ | Endpoint label pane configuration for bar charts. |
|
|
601
600
|
| `marks` | [BarChartMarksStyle](#barchartmarksstyle) | ✓ | Bar-family mark overrides. Unset fields fall back to [`style.charts.marks`](#chartsstyle). |
|
|
@@ -615,7 +614,6 @@ Authored overlay for LineChartStyle. Line chart style: chart-level fields + mark
|
|
|
615
614
|
| `animation_duration` | float | ✓ | Vega-Lite animation duration in milliseconds. Falls back to [`style.charts.animation_duration`](#chartsstyle). |
|
|
616
615
|
| `palette` | list[str] \| str | ✓ | Ordered list of categorical color stops or a palette name; expanded from a palette name at validation time. Falls back to [`style.charts.palette`](#chartsstyle). |
|
|
617
616
|
| `single_series_palette` | list[str] \| str | ✓ | Ordered list of single-series mark inks (must be non-empty), or a palette name. Cycled across single-series charts in face reading order. Falls back to [`style.charts.single_series_palette`](#chartsstyle). |
|
|
618
|
-
| `inference` | [InferenceStyle](#inferencestyle) | ✓ | Engine inference behavior flags. |
|
|
619
617
|
| `legend` | [LegendStyle](#legendstyle) | ✓ | Chart legend style. |
|
|
620
618
|
| `tooltip` | [TooltipStyle](#tooltipstyle) | ✓ | Per-chart-type tooltip style override; None uses the universal style.charts.tooltip. |
|
|
621
619
|
| `background` | str | ✓ | Chart-local background color override; None inherits from theme. |
|
|
@@ -649,7 +647,6 @@ Authored overlay for AreaChartStyle. Area chart style: chart-level fields + mark
|
|
|
649
647
|
| `animation_duration` | float | ✓ | Vega-Lite animation duration in milliseconds. Falls back to [`style.charts.animation_duration`](#chartsstyle). |
|
|
650
648
|
| `palette` | list[str] \| str | ✓ | Ordered list of categorical color stops or a palette name; expanded from a palette name at validation time. Falls back to [`style.charts.palette`](#chartsstyle). |
|
|
651
649
|
| `single_series_palette` | list[str] \| str | ✓ | Ordered list of single-series mark inks (must be non-empty), or a palette name. Cycled across single-series charts in face reading order. Falls back to [`style.charts.single_series_palette`](#chartsstyle). |
|
|
652
|
-
| `inference` | [InferenceStyle](#inferencestyle) | ✓ | Engine inference behavior flags. |
|
|
653
650
|
| `legend` | [LegendStyle](#legendstyle) | ✓ | Chart legend style. |
|
|
654
651
|
| `tooltip` | [TooltipStyle](#tooltipstyle) | ✓ | Per-chart-type tooltip style override; None uses the universal style.charts.tooltip. |
|
|
655
652
|
| `background` | str | ✓ | Chart-local background color override; None inherits from theme. |
|
|
@@ -665,7 +662,7 @@ Authored overlay for AreaChartStyle. Area chart style: chart-level fields + mark
|
|
|
665
662
|
| `scale` | [ScaleStyle](#scalestyle) | ✓ | Chart-type encoding scale overrides applied to both x and y; None means no override. |
|
|
666
663
|
| `range` | [RangeStyle](#rangestyle) | ✓ | Color range/palette overrides for this chart type; None means no override. |
|
|
667
664
|
| `data_table` | [DataTableStyle](#datatablestyle) | ✓ | Per-chart-type data_table style override. Unset fields fall back to [`style.charts.data_table`](#chartsstyle). |
|
|
668
|
-
| `stack` | enum: "zero", "normalize", "center" | ✓ | Default stack mode for area charts;
|
|
665
|
+
| `stack` | enum: "none", "zero", "normalize", "center" | ✓ | Default stack mode for area charts; none overlaps silhouettes. |
|
|
669
666
|
| `endpoint_labels` | [EndpointLabelsConfig](#endpointlabelsconfig) | ✓ | Endpoint label pane configuration for area charts. |
|
|
670
667
|
| `marks` | [AreaChartMarksStyle](#areachartmarksstyle) | ✓ | Area-family mark overrides. Unset fields fall back to [`style.charts.marks`](#chartsstyle). |
|
|
671
668
|
|
|
@@ -684,7 +681,6 @@ Authored overlay for ScatterChartStyle. Scatter chart style: chart-level fields
|
|
|
684
681
|
| `animation_duration` | float | ✓ | Vega-Lite animation duration in milliseconds. Falls back to [`style.charts.animation_duration`](#chartsstyle). |
|
|
685
682
|
| `palette` | list[str] \| str | ✓ | Ordered list of categorical color stops or a palette name; expanded from a palette name at validation time. Falls back to [`style.charts.palette`](#chartsstyle). |
|
|
686
683
|
| `single_series_palette` | list[str] \| str | ✓ | Ordered list of single-series mark inks (must be non-empty), or a palette name. Cycled across single-series charts in face reading order. Falls back to [`style.charts.single_series_palette`](#chartsstyle). |
|
|
687
|
-
| `inference` | [InferenceStyle](#inferencestyle) | ✓ | Engine inference behavior flags. |
|
|
688
684
|
| `legend` | [LegendStyle](#legendstyle) | ✓ | Chart legend style. |
|
|
689
685
|
| `tooltip` | [TooltipStyle](#tooltipstyle) | ✓ | Per-chart-type tooltip style override; None uses the universal style.charts.tooltip. |
|
|
690
686
|
| `background` | str | ✓ | Chart-local background color override; None inherits from theme. |
|
|
@@ -717,7 +713,6 @@ Authored overlay for HeatmapChartStyle. Heatmap chart style.
|
|
|
717
713
|
| `animation_duration` | float | ✓ | Vega-Lite animation duration in milliseconds. Falls back to [`style.charts.animation_duration`](#chartsstyle). |
|
|
718
714
|
| `palette` | list[str] \| str | ✓ | Ordered list of categorical color stops or a palette name; expanded from a palette name at validation time. Falls back to [`style.charts.palette`](#chartsstyle). |
|
|
719
715
|
| `single_series_palette` | list[str] \| str | ✓ | Ordered list of single-series mark inks (must be non-empty), or a palette name. Cycled across single-series charts in face reading order. Falls back to [`style.charts.single_series_palette`](#chartsstyle). |
|
|
720
|
-
| `inference` | [InferenceStyle](#inferencestyle) | ✓ | Engine inference behavior flags. |
|
|
721
716
|
| `legend` | [LegendStyle](#legendstyle) | ✓ | Chart legend style. |
|
|
722
717
|
| `tooltip` | [TooltipStyle](#tooltipstyle) | ✓ | Per-chart-type tooltip style override; None uses the universal style.charts.tooltip. |
|
|
723
718
|
| `background` | str | ✓ | Chart-local background color override; None inherits from theme. |
|
|
@@ -762,7 +757,6 @@ Authored overlay for PieChartStyle. Pie/donut chart style: geometry + total (fla
|
|
|
762
757
|
| `animation_duration` | float | ✓ | Vega-Lite animation duration in milliseconds. Falls back to [`style.charts.animation_duration`](#chartsstyle). |
|
|
763
758
|
| `palette` | list[str] \| str | ✓ | Ordered list of categorical color stops or a palette name; expanded from a palette name at validation time. Falls back to [`style.charts.palette`](#chartsstyle). |
|
|
764
759
|
| `single_series_palette` | list[str] \| str | ✓ | Ordered list of single-series mark inks (must be non-empty), or a palette name. Cycled across single-series charts in face reading order. Falls back to [`style.charts.single_series_palette`](#chartsstyle). |
|
|
765
|
-
| `inference` | [InferenceStyle](#inferencestyle) | ✓ | Engine inference behavior flags. |
|
|
766
760
|
| `legend` | [LegendStyle](#legendstyle) | ✓ | Chart legend style. |
|
|
767
761
|
| `tooltip` | [TooltipStyle](#tooltipstyle) | ✓ | Per-chart-type tooltip style override; None uses the universal style.charts.tooltip. |
|
|
768
762
|
| `background` | str | ✓ | Chart-local background color override; None inherits from theme. |
|
|
@@ -796,7 +790,6 @@ Authored overlay for KpiChartStyle. Produced by cascade from theme YAML.
|
|
|
796
790
|
| `animation_duration` | float | ✓ | Vega-Lite animation duration in milliseconds. Falls back to [`style.charts.animation_duration`](#chartsstyle). |
|
|
797
791
|
| `palette` | list[str] \| str | ✓ | Ordered list of categorical color stops or a palette name; expanded from a palette name at validation time. Falls back to [`style.charts.palette`](#chartsstyle). |
|
|
798
792
|
| `single_series_palette` | list[str] \| str | ✓ | Ordered list of single-series mark inks (must be non-empty), or a palette name. Cycled across single-series charts in face reading order. Falls back to [`style.charts.single_series_palette`](#chartsstyle). |
|
|
799
|
-
| `inference` | [InferenceStyle](#inferencestyle) | ✓ | Engine inference behavior flags. |
|
|
800
793
|
| `legend` | [LegendStyle](#legendstyle) | ✓ | Chart legend style. |
|
|
801
794
|
| `tooltip` | [TooltipStyle](#tooltipstyle) | ✓ | Per-chart-type tooltip style override; None uses the universal style.charts.tooltip. |
|
|
802
795
|
| `background` | str | ✓ | Chart-local background color override; None inherits from theme. |
|
|
@@ -825,7 +818,6 @@ Authored overlay for TableChartStyle. Table chart style overrides layered on top
|
|
|
825
818
|
| `animation_duration` | float | ✓ | Vega-Lite animation duration in milliseconds. Falls back to [`style.charts.animation_duration`](#chartsstyle). |
|
|
826
819
|
| `palette` | list[str] \| str | ✓ | Ordered list of categorical color stops or a palette name; expanded from a palette name at validation time. Falls back to [`style.charts.palette`](#chartsstyle). |
|
|
827
820
|
| `single_series_palette` | list[str] \| str | ✓ | Ordered list of single-series mark inks (must be non-empty), or a palette name. Cycled across single-series charts in face reading order. Falls back to [`style.charts.single_series_palette`](#chartsstyle). |
|
|
828
|
-
| `inference` | [InferenceStyle](#inferencestyle) | ✓ | Engine inference behavior flags. |
|
|
829
821
|
| `legend` | [LegendStyle](#legendstyle) | ✓ | Chart legend style. |
|
|
830
822
|
| `tooltip` | [TooltipStyle](#tooltipstyle) | ✓ | Per-chart-type tooltip style override; None uses the universal style.charts.tooltip. |
|
|
831
823
|
| `background` | str | ✓ | Table background color; None inherits from theme. |
|
|
@@ -883,7 +875,6 @@ Authored overlay for PointMapChartStyle. Point map chart style.
|
|
|
883
875
|
| `animation_duration` | float | ✓ | Vega-Lite animation duration in milliseconds. Falls back to [`style.charts.animation_duration`](#chartsstyle). |
|
|
884
876
|
| `palette` | list[str] \| str | ✓ | Ordered list of categorical color stops or a palette name; expanded from a palette name at validation time. Falls back to [`style.charts.palette`](#chartsstyle). |
|
|
885
877
|
| `single_series_palette` | list[str] \| str | ✓ | Ordered list of single-series mark inks (must be non-empty), or a palette name. Cycled across single-series charts in face reading order. Falls back to [`style.charts.single_series_palette`](#chartsstyle). |
|
|
886
|
-
| `inference` | [InferenceStyle](#inferencestyle) | ✓ | Engine inference behavior flags. |
|
|
887
878
|
| `legend` | [LegendStyle](#legendstyle) | ✓ | Chart legend style. |
|
|
888
879
|
| `tooltip` | [TooltipStyle](#tooltipstyle) | ✓ | Per-chart-type tooltip style override; None uses the universal style.charts.tooltip. |
|
|
889
880
|
| `background` | str | ✓ | Chart-local background color override; None inherits from theme. |
|
|
@@ -908,7 +899,6 @@ Authored overlay for GeoshapeChartStyle. Geoshape (choropleth) chart style.
|
|
|
908
899
|
| `animation_duration` | float | ✓ | Vega-Lite animation duration in milliseconds. Falls back to [`style.charts.animation_duration`](#chartsstyle). |
|
|
909
900
|
| `palette` | list[str] \| str | ✓ | Ordered list of categorical color stops or a palette name; expanded from a palette name at validation time. Falls back to [`style.charts.palette`](#chartsstyle). |
|
|
910
901
|
| `single_series_palette` | list[str] \| str | ✓ | Ordered list of single-series mark inks (must be non-empty), or a palette name. Cycled across single-series charts in face reading order. Falls back to [`style.charts.single_series_palette`](#chartsstyle). |
|
|
911
|
-
| `inference` | [InferenceStyle](#inferencestyle) | ✓ | Engine inference behavior flags. |
|
|
912
902
|
| `legend` | [LegendStyle](#legendstyle) | ✓ | Chart legend style. |
|
|
913
903
|
| `tooltip` | [TooltipStyle](#tooltipstyle) | ✓ | Per-chart-type tooltip style override; None uses the universal style.charts.tooltip. |
|
|
914
904
|
| `background` | str | ✓ | Chart-local background color override; None inherits from theme. |
|
|
@@ -959,7 +949,6 @@ Flat style patch for layered multi-mark charts.
|
|
|
959
949
|
| `animation_duration` | float | ✓ | Vega-Lite animation duration in milliseconds. Falls back to [`style.charts.animation_duration`](#chartsstyle). |
|
|
960
950
|
| `palette` | list[str] \| str | ✓ | Ordered list of categorical color stops or a palette name; expanded from a palette name at validation time. Falls back to [`style.charts.palette`](#chartsstyle). |
|
|
961
951
|
| `single_series_palette` | list[str] \| str | ✓ | Ordered list of single-series mark inks (must be non-empty), or a palette name. Cycled across single-series charts in face reading order. Falls back to [`style.charts.single_series_palette`](#chartsstyle). |
|
|
962
|
-
| `inference` | [InferenceStyle](#inferencestyle) | ✓ | Engine inference behavior flags. |
|
|
963
952
|
| `legend` | [LegendStyle](#legendstyle) | ✓ | Chart legend style overrides. |
|
|
964
953
|
| `tooltip` | [TooltipStyle](#tooltipstyle) | ✓ | Chart tooltip style overrides. |
|
|
965
954
|
| `background` | str | ✓ | Chart-local background color override; None inherits from theme. |
|
|
@@ -976,7 +965,7 @@ Flat style patch for layered multi-mark charts.
|
|
|
976
965
|
| `range` | [RangeStyle](#rangestyle) | ✓ | Color range/palette overrides for this chart type; None means no override. |
|
|
977
966
|
| `data_table` | [DataTableStyle](#datatablestyle) | ✓ | Per-chart-type data_table style override. Unset fields fall back to [`style.charts.data_table`](#chartsstyle). |
|
|
978
967
|
| `orientation` | enum: "horizontal", "vertical", "auto" | ✓ | Preferred bar orientation; None uses the renderer default (vertical). |
|
|
979
|
-
| `stack` | enum: "zero", "normalize", "center" | ✓ | Default stack mode for bar/area charts. |
|
|
968
|
+
| `stack` | enum: "none", "zero", "normalize", "center" | ✓ | Default stack mode for bar/area charts. |
|
|
980
969
|
| `stack_order` | enum: "value", "data", "alphabetical" | ✓ | Z-order of stacked segments. |
|
|
981
970
|
| `endpoint_labels` | [EndpointLabelsConfig](#endpointlabelsconfig) | ✓ | Endpoint label pane configuration. |
|
|
982
971
|
| `marks` | [LayeredMarksStyle](#layeredmarksstyle) | ✓ | Per-mark-type style overrides (bar/line/area/point). |
|
|
@@ -1102,7 +1091,7 @@ Authored overlay for TitleStyle. Board and face titles.
|
|
|
1102
1091
|
| `min_height` | float | ✓ | Minimum title row height in pixels. |
|
|
1103
1092
|
| `overflow` | str | ✓ | Text overflow mode (clip, truncate, wrap-two, wrap). |
|
|
1104
1093
|
| `position` | [TitlePositionStyle](#titlepositionstyle) | ✓ | Vega-Lite title positioning: anchor, angle, offset, baseline. |
|
|
1105
|
-
| `level` | enum: "auto" | ✓ | Heading level override for face titles. ``'auto'`` (default) computes the level semantically as the count of titled ancestors. An integer value locks all titles in this face and its descendants to that H-level. |
|
|
1094
|
+
| `level` | int \| enum: "auto" | ✓ | Heading level override for face titles. ``'auto'`` (default) computes the level semantically as the count of titled ancestors. An integer value locks all titles in this face and its descendants to that H-level. |
|
|
1106
1095
|
| `subtitle` | [TitleSubtitleStyle](#titlesubtitlestyle) | ✓ | Subtitle font styles. |
|
|
1107
1096
|
|
|
1108
1097
|
<a id="textstyle"></a>
|
|
@@ -1142,7 +1131,6 @@ Authored overlay for ChartsStyle. Registry of all chart-type styles plus shared
|
|
|
1142
1131
|
| `animation_duration` | float | ✓ | Vega-Lite animation duration in milliseconds. |
|
|
1143
1132
|
| `palette` | list[str] \| str | ✓ | Ordered list of categorical color stops or a palette name; expanded from a palette name at validation time. |
|
|
1144
1133
|
| `single_series_palette` | list[str] \| str | ✓ | Ordered list of single-series mark inks (must be non-empty), or a palette name. Cycled across single-series charts in face reading order. |
|
|
1145
|
-
| `inference` | [InferenceStyle](#inferencestyle) | ✓ | Engine inference behavior flags. |
|
|
1146
1134
|
| `legend` | [LegendStyle](#legendstyle) | ✓ | Chart legend style. |
|
|
1147
1135
|
| `tooltip` | [TooltipStyle](#tooltipstyle) | ✓ | Chart tooltip style. |
|
|
1148
1136
|
| `background` | str | ✓ | Chart canvas background; None inherits from the board background via apply_inherit. Falls back to [`style.background`](#style). |
|
|
@@ -1335,15 +1323,6 @@ Authored overlay for PaddingStyle. Per-chart padding inset (px). All 4 sides req
|
|
|
1335
1323
|
| `top` | float | ✓ | Top padding in pixels. |
|
|
1336
1324
|
| `bottom` | float | ✓ | Bottom padding in pixels. |
|
|
1337
1325
|
|
|
1338
|
-
<a id="inferencestyle"></a>
|
|
1339
|
-
## InferenceStyle
|
|
1340
|
-
Authored overlay for InferenceStyle.
|
|
1341
|
-
|
|
1342
|
-
| Field | Type | Optional | Description |
|
|
1343
|
-
|-------|------|:--------:|-------------|
|
|
1344
|
-
| `infer_zero_when_missing` | bool | ✓ | Auto-infer zero-baseline when not authored. |
|
|
1345
|
-
| `infer_fields_when_missing` | bool | ✓ | Auto-infer chart fields (x, y, etc.) when not authored. |
|
|
1346
|
-
|
|
1347
1326
|
<a id="legendstyle"></a>
|
|
1348
1327
|
## LegendStyle
|
|
1349
1328
|
Authored overlay for LegendStyle.
|
|
@@ -1417,7 +1396,7 @@ Authored overlay for ScaleStyle. Scale configuration primitive.
|
|
|
1417
1396
|
| `point_padding` | float | ✓ | Padding fraction for point scales; None uses Vega-Lite's default. |
|
|
1418
1397
|
| `rect_band_padding_inner` | float | ✓ | Inner padding fraction for rect band scales; None uses Vega-Lite's default. |
|
|
1419
1398
|
| `round` | bool | ✓ | Round scale outputs to nearest integer; None uses Vega-Lite's default (no rounding). |
|
|
1420
|
-
| `zero` | bool | ✓ | Force scale
|
|
1399
|
+
| `zero` | bool \| enum: "auto" | ✓ | Force scale zero-baseline: True/False pins it; "auto" runs the Dataface smart-zero heuristic; None passes through to Vega-Lite. |
|
|
1421
1400
|
| `clamp` | bool | ✓ | Clamp values to scale domain; None uses Vega-Lite's default (no clamping). |
|
|
1422
1401
|
| `continuous_padding` | float | ✓ | Padding in pixels for continuous scales; None uses Vega-Lite's default. |
|
|
1423
1402
|
| `band` | [ScaleBandStyle](#scalebandstyle) | ✓ | Band mark size constraints; None uses Vega-Lite's defaults. |
|
|
@@ -1654,7 +1633,7 @@ Configuration for a single table column.
|
|
|
1654
1633
|
|-------|------|:--------:|-------------|
|
|
1655
1634
|
| `label` | str | ✓ | Display header label (defaults to column name). |
|
|
1656
1635
|
| `format` | str \| [FormatConfig](#formatconfig) | ✓ | Number format (D3 string, preset name, or FormatConfig). |
|
|
1657
|
-
| `spark` | enum: "line", "area", "bar", "bar-normalize", "columns" | ✓ | Inline spark chart config or spark type name. |
|
|
1636
|
+
| `spark` | enum: "line", "area", "bar", "bar-normalize", "column", "columns" | ✓ | Inline spark chart config or spark type name. |
|
|
1658
1637
|
| `swatch` | bool | ✓ | When True, render this column's cells as small rounded color squares instead of text. Cell value must be a CSS color string (e.g. '#3164a3'). Useful for series-keyed tables — e.g. a 'Series' column where each row is identified by its color in the parent chart's palette. |
|
|
1659
1638
|
| `width` | int \| str | ✓ | Column width (integer pixels or CSS string like '10%'). |
|
|
1660
1639
|
| `max_width` | int \| str | ✓ | Maximum column width for auto-sized text columns (integer pixels or CSS string like '30%'). Cannot be set together with width:. |
|
|
@@ -1702,6 +1681,7 @@ Authored overlay for SparkStyle. Inline sparkline defaults (inside table cells).
|
|
|
1702
1681
|
| `empty` | [SparkEmptyStyle](#sparkemptystyle) | ✓ | Style for empty/no-data sparklines. |
|
|
1703
1682
|
| `single_value` | [SparkSingleValueStyle](#sparksinglevaluestyle) | ✓ | Style for single-data-point sparklines. |
|
|
1704
1683
|
| `columns` | [SparkColumnsStyle](#sparkcolumnsstyle) | ✓ | Style for column-type sparklines. |
|
|
1684
|
+
| `column` | [SparkColumnStyle](#sparkcolumnstyle) | ✓ | Style for the single vertical `column` spark mark. |
|
|
1705
1685
|
| `bar` | [SparkBarCellStyle](#sparkbarcellstyle) | ✓ | Style for bar/bar-normalize sparklines. |
|
|
1706
1686
|
| `area` | [SparkAreaStyle](#sparkareastyle) | ✓ | Style for area sparklines. |
|
|
1707
1687
|
|
|
@@ -1944,7 +1924,6 @@ Authored overlay for HistogramChartStyle. Histogram chart style.
|
|
|
1944
1924
|
| `animation_duration` | float | ✓ | Vega-Lite animation duration in milliseconds. Falls back to [`style.charts.animation_duration`](#chartsstyle). |
|
|
1945
1925
|
| `palette` | list[str] \| str | ✓ | Ordered list of categorical color stops or a palette name; expanded from a palette name at validation time. Falls back to [`style.charts.palette`](#chartsstyle). |
|
|
1946
1926
|
| `single_series_palette` | list[str] \| str | ✓ | Ordered list of single-series mark inks (must be non-empty), or a palette name. Cycled across single-series charts in face reading order. Falls back to [`style.charts.single_series_palette`](#chartsstyle). |
|
|
1947
|
-
| `inference` | [InferenceStyle](#inferencestyle) | ✓ | Engine inference behavior flags. |
|
|
1948
1927
|
| `legend` | [LegendStyle](#legendstyle) | ✓ | Chart legend style. |
|
|
1949
1928
|
| `tooltip` | [TooltipStyle](#tooltipstyle) | ✓ | Per-chart-type tooltip style override; None uses the universal style.charts.tooltip. |
|
|
1950
1929
|
| `background` | str | ✓ | Chart-local background color override; None inherits from theme. |
|
|
@@ -2119,7 +2098,7 @@ Scale configuration for a single style target (background or color).
|
|
|
2119
2098
|
| `min` | float \| int | ✓ | Minimum scale domain value (overrides data minimum). |
|
|
2120
2099
|
| `max` | float \| int | ✓ | Maximum scale domain value (overrides data maximum). |
|
|
2121
2100
|
| `null_color` | str | ✓ | Color assigned to null values. |
|
|
2122
|
-
| `hinge` | enum: "auto" | ✓ | Diverging scale midpoint value, or 'auto' to use the data midpoint. |
|
|
2101
|
+
| `hinge` | float \| enum: "auto" | ✓ | Diverging scale midpoint value, or 'auto' to use the data midpoint. |
|
|
2123
2102
|
| `arm_mode` | enum: "asymmetric", "symmetric" | ✓ | How diverging scale arms are stretched: 'asymmetric' (proportional) or 'symmetric' (equal arms). |
|
|
2124
2103
|
|
|
2125
2104
|
<a id="axisgridstyle"></a>
|
|
@@ -2306,6 +2285,7 @@ Authored overlay for SliceMarkStyle. Pie/donut slice mark — mark-level paint a
|
|
|
2306
2285
|
|
|
2307
2286
|
| Field | Type | Optional | Description |
|
|
2308
2287
|
|-------|------|:--------:|-------------|
|
|
2288
|
+
| `opacity` | float | ✓ | Arc slice opacity (0–1); None means not overridden at this level. |
|
|
2309
2289
|
| `gap` | float | ✓ | Angular gap between slices in radians. |
|
|
2310
2290
|
| `corner_radius` | float | ✓ | Corner radius of arc slices in pixels. |
|
|
2311
2291
|
| `stroke` | [StrokeStyle](#strokestyle) | ✓ | Arc slice stroke style. |
|
|
@@ -2334,7 +2314,7 @@ Configuration for spark charts (inline sparklines) in table columns.
|
|
|
2334
2314
|
|
|
2335
2315
|
| Field | Type | Optional | Description |
|
|
2336
2316
|
|-------|------|:--------:|-------------|
|
|
2337
|
-
| `type` | enum: "line", "area", "bar", "bar-normalize", "columns" | ✓ | Spark chart type (line, area, bar, bar-normalize, columns). |
|
|
2317
|
+
| `type` | enum: "line", "area", "bar", "bar-normalize", "column", "columns" | ✓ | Spark chart type (line, area, bar, bar-normalize, column, columns). |
|
|
2338
2318
|
| `color` | str | ✓ | Color for the spark mark. |
|
|
2339
2319
|
| `height` | int | ✓ | Spark chart height in pixels. |
|
|
2340
2320
|
| `width` | int | ✓ | Spark chart width in pixels. |
|
|
@@ -2386,6 +2366,15 @@ Authored overlay for SparkColumnsStyle. Inline `spark.type: columns` (multi-valu
|
|
|
2386
2366
|
| `min_bar_height` | float | ✓ | Minimum rendered bar height in pixels. |
|
|
2387
2367
|
| `border` | [BorderStyle](#borderstyle) | ✓ | Column bar border style. |
|
|
2388
2368
|
|
|
2369
|
+
<a id="sparkcolumnstyle"></a>
|
|
2370
|
+
## SparkColumnStyle
|
|
2371
|
+
Authored overlay for SparkColumnStyle. Inline `spark.type: column` (single vertical bar) defaults.
|
|
2372
|
+
|
|
2373
|
+
| Field | Type | Optional | Description |
|
|
2374
|
+
|-------|------|:--------:|-------------|
|
|
2375
|
+
| `width` | float | ✓ | Spark column default width in pixels. |
|
|
2376
|
+
| `height` | float | ✓ | Spark column default height in pixels. |
|
|
2377
|
+
|
|
2389
2378
|
<a id="sparkbarcellstyle"></a>
|
|
2390
2379
|
## SparkBarCellStyle
|
|
2391
2380
|
Authored overlay for SparkBarCellStyle. Inline `spark.type: bar` and `bar-normalize` (single horizontal bar) defaults.
|
dataface/agent_api/validate.py
CHANGED
|
@@ -170,7 +170,7 @@ def _validate_meta_file(path: Path) -> ValidateResult:
|
|
|
170
170
|
DatafaceError.from_code(
|
|
171
171
|
DF_COMPILE_META_SCHEMA,
|
|
172
172
|
message=(
|
|
173
|
-
f"{'
|
|
173
|
+
f"{'.'.join(str(loc) for loc in e['loc'])}: {e['msg']}"
|
|
174
174
|
if e["loc"]
|
|
175
175
|
else e["msg"]
|
|
176
176
|
),
|
dataface/cli/_error_format.py
CHANGED
|
@@ -21,6 +21,18 @@ from dataface.core.errors import StructuredError
|
|
|
21
21
|
from dataface.core.render.warnings.base import RenderWarning
|
|
22
22
|
|
|
23
23
|
|
|
24
|
+
def _display_path(abs_path: str, line: int | None, cwd: Path | None = None) -> str:
|
|
25
|
+
"""Return path relative to cwd when possible, with optional :line suffix."""
|
|
26
|
+
p = Path(abs_path)
|
|
27
|
+
base = cwd if cwd is not None else Path.cwd()
|
|
28
|
+
try:
|
|
29
|
+
rel = p.relative_to(base)
|
|
30
|
+
display = str(rel)
|
|
31
|
+
except ValueError:
|
|
32
|
+
display = abs_path
|
|
33
|
+
return f"{display}:{line}" if line else display
|
|
34
|
+
|
|
35
|
+
|
|
24
36
|
def print_structured_errors(
|
|
25
37
|
errs: list[StructuredError],
|
|
26
38
|
*,
|
|
@@ -42,8 +54,7 @@ def print_structured_errors(
|
|
|
42
54
|
if e.hint:
|
|
43
55
|
body_parts.append(f"[dim]Hint:[/] {e.hint}")
|
|
44
56
|
if e.file:
|
|
45
|
-
|
|
46
|
-
body_parts.append(f"[dim]At:[/] {loc}")
|
|
57
|
+
body_parts.append(f"[dim]At:[/] {_display_path(e.file, e.line)}")
|
|
47
58
|
if e.docs_topic:
|
|
48
59
|
body_parts.append(f"[dim]Docs:[/] dft docs {e.docs_topic}")
|
|
49
60
|
elif e.doc_url:
|
dataface/cli/commands/render.py
CHANGED
|
@@ -29,6 +29,29 @@ from dataface.core.render.warnings.from_query_diagnostic import KNOWN_RENDER_COD
|
|
|
29
29
|
# for query-validator codes; only orphan emitters (e.g. unreferenced_chart) add here.
|
|
30
30
|
_COMPILE_PRODUCER_CODES: frozenset[str] = KNOWN_RENDER_CODES | {unreferenced_chart.CODE}
|
|
31
31
|
|
|
32
|
+
# Maps common file extensions to render formats for format inference.
|
|
33
|
+
_EXT_TO_FORMAT: dict[str, RenderFormat] = {
|
|
34
|
+
"svg": "svg",
|
|
35
|
+
"html": "html",
|
|
36
|
+
"htm": "html",
|
|
37
|
+
"png": "png",
|
|
38
|
+
"pdf": "pdf",
|
|
39
|
+
"json": "json",
|
|
40
|
+
"txt": "text",
|
|
41
|
+
"yaml": "yaml",
|
|
42
|
+
"yml": "yaml",
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
def infer_format_from_extension(output: str) -> RenderFormat | None:
|
|
47
|
+
"""Infer render format from output file extension. Returns None for unknown extensions."""
|
|
48
|
+
return _EXT_TO_FORMAT.get(Path(output).suffix.lstrip(".").lower())
|
|
49
|
+
|
|
50
|
+
|
|
51
|
+
def expand_output_template(template: str, face: Path) -> str:
|
|
52
|
+
"""Expand {stem} and {dir} placeholders in an output path template."""
|
|
53
|
+
return template.format(stem=face.stem, dir=str(face.parent))
|
|
54
|
+
|
|
32
55
|
|
|
33
56
|
def _exit_with_errors(errs: list[StructuredError], json_errors: bool) -> None:
|
|
34
57
|
print_structured_errors(errs, json_output=json_errors)
|
|
@@ -96,6 +119,7 @@ def render_command(
|
|
|
96
119
|
ignore_codes: set[str] | None = None,
|
|
97
120
|
fail_on_chart_errors: bool = True,
|
|
98
121
|
max_workers: int | None = None,
|
|
122
|
+
print0: bool = False,
|
|
99
123
|
) -> str | None:
|
|
100
124
|
"""Render a dashboard to SVG, HTML, PNG, PDF, or terminal.
|
|
101
125
|
|
|
@@ -170,6 +194,7 @@ def render_command(
|
|
|
170
194
|
output_dir=output_dir,
|
|
171
195
|
default_output_stem=ctx.face_file.stem,
|
|
172
196
|
source_label=str(face_path),
|
|
197
|
+
print0=print0,
|
|
173
198
|
)
|
|
174
199
|
|
|
175
200
|
|
|
@@ -185,6 +210,7 @@ def render_command_from_yaml(
|
|
|
185
210
|
ignore_codes: set[str] | None = None,
|
|
186
211
|
fail_on_chart_errors: bool = True,
|
|
187
212
|
max_workers: int | None = None,
|
|
213
|
+
print0: bool = False,
|
|
188
214
|
) -> str | None:
|
|
189
215
|
"""Render a dashboard from YAML content (e.g. stdin).
|
|
190
216
|
|
|
@@ -255,6 +281,7 @@ def render_command_from_yaml(
|
|
|
255
281
|
output_dir=output_dir,
|
|
256
282
|
default_output_stem="stdin",
|
|
257
283
|
source_label="<stdin>",
|
|
284
|
+
print0=print0,
|
|
258
285
|
)
|
|
259
286
|
|
|
260
287
|
|
|
@@ -265,6 +292,7 @@ def _write_output(
|
|
|
265
292
|
output_dir: Path,
|
|
266
293
|
default_output_stem: str,
|
|
267
294
|
source_label: str,
|
|
295
|
+
print0: bool = False,
|
|
268
296
|
) -> str | None:
|
|
269
297
|
"""Write rendered content to the appropriate destination."""
|
|
270
298
|
# `terminal` is stdout-only by design — --output is meaningless for the
|
|
@@ -318,4 +346,76 @@ def _write_output(
|
|
|
318
346
|
f"Rendered {source_label} to {output_path} ({format} format)",
|
|
319
347
|
file=sys.stderr,
|
|
320
348
|
)
|
|
349
|
+
sys.stdout.write(str(output_path) + ("\0" if print0 else "\n"))
|
|
350
|
+
sys.stdout.flush()
|
|
321
351
|
return str(output_path)
|
|
352
|
+
|
|
353
|
+
|
|
354
|
+
def render_commands(
|
|
355
|
+
face_paths: list[Path],
|
|
356
|
+
output: str | None = None,
|
|
357
|
+
format: RenderFormat = "svg",
|
|
358
|
+
project_dir: Path | None = None,
|
|
359
|
+
variables: dict[str, str] | None = None,
|
|
360
|
+
use_cache: bool = True,
|
|
361
|
+
json_errors: bool = False,
|
|
362
|
+
no_warnings: bool = False,
|
|
363
|
+
ignore_codes: set[str] | None = None,
|
|
364
|
+
fail_on_chart_errors: bool = True,
|
|
365
|
+
max_workers: int | None = None,
|
|
366
|
+
print0: bool = False,
|
|
367
|
+
fail_fast: bool = False,
|
|
368
|
+
) -> None:
|
|
369
|
+
"""Render one or more dashboards, printing output paths to stdout.
|
|
370
|
+
|
|
371
|
+
For multiple faces, `output` must contain {stem} or {dir} placeholders
|
|
372
|
+
(e.g. "renders/{stem}.svg"). With a single face, any output path is valid.
|
|
373
|
+
|
|
374
|
+
Per-face errors are reported to stderr; processing continues unless
|
|
375
|
+
`fail_fast=True`. Exits 1 if any face failed.
|
|
376
|
+
"""
|
|
377
|
+
# Fail early when two inputs expand to the same output path — later renders
|
|
378
|
+
# would silently overwrite earlier ones.
|
|
379
|
+
if output and len(face_paths) > 1:
|
|
380
|
+
planned: list[str] = [expand_output_template(output, f) for f in face_paths]
|
|
381
|
+
seen: dict[str, Path] = {}
|
|
382
|
+
for face_path, dest in zip(face_paths, planned, strict=True):
|
|
383
|
+
if dest in seen:
|
|
384
|
+
print(
|
|
385
|
+
f"Error: {face_path} and {seen[dest]} both expand to {dest!r}; "
|
|
386
|
+
"use a more specific template (add {{dir}} or rename the files)",
|
|
387
|
+
file=sys.stderr,
|
|
388
|
+
)
|
|
389
|
+
sys.exit(1)
|
|
390
|
+
seen[dest] = face_path
|
|
391
|
+
|
|
392
|
+
has_failure = False
|
|
393
|
+
for face_path in face_paths:
|
|
394
|
+
face_output = expand_output_template(output, face_path) if output else None
|
|
395
|
+
try:
|
|
396
|
+
render_command(
|
|
397
|
+
face_path=face_path,
|
|
398
|
+
output=face_output,
|
|
399
|
+
format=format,
|
|
400
|
+
project_dir=project_dir,
|
|
401
|
+
variables=variables,
|
|
402
|
+
use_cache=use_cache,
|
|
403
|
+
json_errors=json_errors,
|
|
404
|
+
no_warnings=no_warnings,
|
|
405
|
+
ignore_codes=ignore_codes,
|
|
406
|
+
fail_on_chart_errors=fail_on_chart_errors,
|
|
407
|
+
max_workers=max_workers,
|
|
408
|
+
print0=print0,
|
|
409
|
+
)
|
|
410
|
+
except SystemExit as exc:
|
|
411
|
+
if fail_fast or exc.code != 1:
|
|
412
|
+
raise
|
|
413
|
+
has_failure = True
|
|
414
|
+
except Exception as exc: # noqa: BLE001 — per-face error; batch continues
|
|
415
|
+
print(f"Error rendering {face_path}: {exc}", file=sys.stderr)
|
|
416
|
+
has_failure = True
|
|
417
|
+
if fail_fast:
|
|
418
|
+
sys.exit(1)
|
|
419
|
+
|
|
420
|
+
if has_failure:
|
|
421
|
+
sys.exit(1)
|
dataface/cli/main.py
CHANGED
|
@@ -690,23 +690,28 @@ def describe(
|
|
|
690
690
|
|
|
691
691
|
@app.command("render", rich_help_panel="Dashboards")
|
|
692
692
|
def render(
|
|
693
|
-
|
|
694
|
-
Path,
|
|
693
|
+
faces: Annotated[
|
|
694
|
+
list[Path],
|
|
695
695
|
typer.Argument(
|
|
696
696
|
# No exists=/file_okay=: "-" is a valid stdin sentinel and must not fail the check.
|
|
697
|
-
help='Path to face YAML file, or "-" to read YAML from stdin',
|
|
697
|
+
help='Path(s) to face YAML file(s), or "-" to read YAML from stdin (single path only)',
|
|
698
698
|
),
|
|
699
699
|
],
|
|
700
700
|
output: Annotated[
|
|
701
|
-
|
|
702
|
-
typer.Option(
|
|
701
|
+
str | None,
|
|
702
|
+
typer.Option(
|
|
703
|
+
help=(
|
|
704
|
+
"Output file path. For multiple inputs, use {stem} or {dir} "
|
|
705
|
+
"placeholders (e.g. renders/{stem}.svg). Default: renders/<face>.<ext>."
|
|
706
|
+
)
|
|
707
|
+
),
|
|
703
708
|
] = None,
|
|
704
709
|
format: Annotated[
|
|
705
|
-
RenderFormat,
|
|
710
|
+
RenderFormat | None,
|
|
706
711
|
typer.Option(
|
|
707
712
|
help="Output format: svg, html, png, pdf, terminal, json, text, or yaml"
|
|
708
713
|
),
|
|
709
|
-
] =
|
|
714
|
+
] = None,
|
|
710
715
|
project_dir: ProjectDirOption = None,
|
|
711
716
|
var: Annotated[
|
|
712
717
|
list[str] | None,
|
|
@@ -775,11 +780,35 @@ def render(
|
|
|
775
780
|
),
|
|
776
781
|
),
|
|
777
782
|
] = None,
|
|
783
|
+
print0: Annotated[
|
|
784
|
+
bool,
|
|
785
|
+
typer.Option(
|
|
786
|
+
"--print0",
|
|
787
|
+
"-0",
|
|
788
|
+
help=(
|
|
789
|
+
"Delimit produced output paths with NUL (\\0) instead of newline. "
|
|
790
|
+
"Enables safe piping to xargs -0 for paths containing spaces."
|
|
791
|
+
),
|
|
792
|
+
),
|
|
793
|
+
] = False,
|
|
794
|
+
fail_fast: Annotated[
|
|
795
|
+
bool,
|
|
796
|
+
typer.Option(
|
|
797
|
+
"--fail-fast",
|
|
798
|
+
help=(
|
|
799
|
+
"Stop immediately on the first render failure. "
|
|
800
|
+
"Default: continue rendering remaining faces, exit 1 at end."
|
|
801
|
+
),
|
|
802
|
+
),
|
|
803
|
+
] = False,
|
|
778
804
|
) -> None:
|
|
779
|
-
"""Render
|
|
805
|
+
"""Render one or more dashboards to SVG, HTML, PNG, PDF, or terminal.
|
|
780
806
|
|
|
781
|
-
|
|
782
|
-
|
|
807
|
+
Accepts multiple face paths; output paths are printed to stdout (one per
|
|
808
|
+
line) so results can be piped to other tools. Use --print0 for NUL-delimited
|
|
809
|
+
output safe with xargs -0.
|
|
810
|
+
|
|
811
|
+
Use "-" as the sole face argument to read YAML from stdin.
|
|
783
812
|
|
|
784
813
|
By default, per-chart runtime errors (missing columns, query failures)
|
|
785
814
|
cause exit 1 so CI smoke tests detect broken charts. Pass
|
|
@@ -790,6 +819,8 @@ def render(
|
|
|
790
819
|
Examples:
|
|
791
820
|
dft render faces/sales.yml
|
|
792
821
|
dft render faces/sales.yml --format html
|
|
822
|
+
dft render faces/*.yml --output renders/{stem}.svg
|
|
823
|
+
dft render faces/*.yml --output renders/{stem}.svg --print0 | xargs -0 ls -lh
|
|
793
824
|
dft render faces/sales.yml --var region=West --var category=Electronics
|
|
794
825
|
dft render faces/sales.yml --format terminal
|
|
795
826
|
dft render faces/sales.yml --no-cache
|
|
@@ -800,34 +831,42 @@ def render(
|
|
|
800
831
|
echo 'charts: {c: {query: {type: csv, file: data.csv}}}' | dft render - --format terminal
|
|
801
832
|
"""
|
|
802
833
|
variables = parse_kv_pairs(var or [], "--var")
|
|
803
|
-
|
|
804
834
|
use_cache = not no_cache
|
|
805
835
|
ignore_codes = set(ignore_warning) if ignore_warning else None
|
|
806
836
|
fail_on_chart_errors = not allow_chart_errors
|
|
807
837
|
|
|
808
|
-
|
|
838
|
+
# Reject stdin mixed with other paths
|
|
839
|
+
has_stdin = any(str(f) == "-" for f in faces)
|
|
840
|
+
if has_stdin and len(faces) > 1:
|
|
841
|
+
raise typer.BadParameter(
|
|
842
|
+
'"-" (stdin) can only be used as the sole face argument',
|
|
843
|
+
param_hint="FACES",
|
|
844
|
+
)
|
|
845
|
+
|
|
846
|
+
# Infer format from output extension when not explicitly given
|
|
847
|
+
effective_format: RenderFormat = (
|
|
848
|
+
format or (output and render_cmd.infer_format_from_extension(output)) or "svg"
|
|
849
|
+
)
|
|
850
|
+
|
|
851
|
+
# Reject flat --output when rendering multiple faces (ambiguous destination)
|
|
852
|
+
if len(faces) > 1 and output is not None:
|
|
853
|
+
if "{stem}" not in output and "{dir}" not in output:
|
|
854
|
+
raise typer.BadParameter(
|
|
855
|
+
f'use a template like "{{stem}}.{effective_format}" for multiple inputs; '
|
|
856
|
+
f'"{output}" is ambiguous with {len(faces)} face arguments',
|
|
857
|
+
param_hint="--output",
|
|
858
|
+
)
|
|
859
|
+
|
|
860
|
+
# Stdin path (single face "-")
|
|
861
|
+
if has_stdin:
|
|
809
862
|
yaml_content = sys.stdin.read()
|
|
810
863
|
if not yaml_content.strip():
|
|
811
864
|
print("Error: No YAML input received from stdin", file=sys.stderr)
|
|
812
865
|
raise typer.Exit(1)
|
|
813
866
|
render_cmd.render_command_from_yaml(
|
|
814
867
|
yaml_content=yaml_content,
|
|
815
|
-
output=
|
|
816
|
-
format=
|
|
817
|
-
project_dir=project_dir,
|
|
818
|
-
variables=variables or None,
|
|
819
|
-
use_cache=use_cache,
|
|
820
|
-
json_errors=json_errors,
|
|
821
|
-
no_warnings=no_warnings,
|
|
822
|
-
ignore_codes=ignore_codes,
|
|
823
|
-
fail_on_chart_errors=fail_on_chart_errors,
|
|
824
|
-
max_workers=max_workers,
|
|
825
|
-
)
|
|
826
|
-
else:
|
|
827
|
-
render_cmd.render_command(
|
|
828
|
-
face_path=face,
|
|
829
|
-
output=str(output) if output else None,
|
|
830
|
-
format=format,
|
|
868
|
+
output=output,
|
|
869
|
+
format=effective_format,
|
|
831
870
|
project_dir=project_dir,
|
|
832
871
|
variables=variables or None,
|
|
833
872
|
use_cache=use_cache,
|
|
@@ -836,7 +875,25 @@ def render(
|
|
|
836
875
|
ignore_codes=ignore_codes,
|
|
837
876
|
fail_on_chart_errors=fail_on_chart_errors,
|
|
838
877
|
max_workers=max_workers,
|
|
878
|
+
print0=print0,
|
|
839
879
|
)
|
|
880
|
+
return
|
|
881
|
+
|
|
882
|
+
render_cmd.render_commands(
|
|
883
|
+
face_paths=faces,
|
|
884
|
+
output=output,
|
|
885
|
+
format=effective_format,
|
|
886
|
+
project_dir=project_dir,
|
|
887
|
+
variables=variables or None,
|
|
888
|
+
use_cache=use_cache,
|
|
889
|
+
json_errors=json_errors,
|
|
890
|
+
no_warnings=no_warnings,
|
|
891
|
+
ignore_codes=ignore_codes,
|
|
892
|
+
fail_on_chart_errors=fail_on_chart_errors,
|
|
893
|
+
max_workers=max_workers,
|
|
894
|
+
print0=print0,
|
|
895
|
+
fail_fast=fail_fast,
|
|
896
|
+
)
|
|
840
897
|
|
|
841
898
|
|
|
842
899
|
@app.command("search", rich_help_panel="Dashboards")
|