dataface 0.1.2__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.
- d3_format/__init__.py +14 -0
- d3_format/errors.py +19 -0
- d3_format/format.py +551 -0
- d3_format/spec.py +159 -0
- dataface/DATAFACE_SYNTAX.md +1135 -0
- dataface/__init__.py +93 -0
- dataface/_docs_site.py +20 -0
- dataface/_install_hint.py +26 -0
- dataface/agent_api/__init__.py +79 -0
- dataface/agent_api/_init_templates/__init__.py +0 -0
- dataface/agent_api/_init_templates/agents_dft_snippet.md +26 -0
- dataface/agent_api/_init_templates/dataface.yml +15 -0
- dataface/agent_api/_init_templates/faces-dataface.yml +144 -0
- dataface/agent_api/_init_templates/index.md +24 -0
- dataface/agent_api/_paths.py +118 -0
- dataface/agent_api/_project_agents_md.py +43 -0
- dataface/agent_api/_session_store.py +486 -0
- dataface/agent_api/_state.py +28 -0
- dataface/agent_api/chat.py +221 -0
- dataface/agent_api/dashboards.py +257 -0
- dataface/agent_api/describe.py +366 -0
- dataface/agent_api/describe_query.py +120 -0
- dataface/agent_api/docs/__init__.py +25 -0
- dataface/agent_api/docs/_loader.py +292 -0
- dataface/agent_api/docs/yaml-reference.md +2757 -0
- dataface/agent_api/file_refs.py +118 -0
- dataface/agent_api/init.py +126 -0
- dataface/agent_api/inspect.py +128 -0
- dataface/agent_api/mcp_install.py +170 -0
- dataface/agent_api/query.py +274 -0
- dataface/agent_api/schema.py +658 -0
- dataface/agent_api/schema_search.py +284 -0
- dataface/agent_api/search.py +270 -0
- dataface/agent_api/skill_install.py +141 -0
- dataface/agent_api/skill_render.py +90 -0
- dataface/agent_api/skills.py +293 -0
- dataface/agent_api/surface_aliases.yaml +128 -0
- dataface/agent_api/validate.py +175 -0
- dataface/agent_api/validate_query.py +84 -0
- dataface/ai/__init__.py +39 -0
- dataface/ai/agent.py +139 -0
- dataface/ai/context.py +45 -0
- dataface/ai/events.py +62 -0
- dataface/ai/external_mcp.py +610 -0
- dataface/ai/generate_sql.py +96 -0
- dataface/ai/llm.py +403 -0
- dataface/ai/mcp/__init__.py +51 -0
- dataface/ai/mcp/server.py +289 -0
- dataface/ai/memories.py +85 -0
- dataface/ai/prompts.py +177 -0
- dataface/ai/schema_context.py +138 -0
- dataface/ai/skills/before-after-comparison/SKILL.md +102 -0
- dataface/ai/skills/before-after-comparison/examples/before-after-comparison.yml +24 -0
- dataface/ai/skills/dashboard-build/SKILL.md +212 -0
- dataface/ai/skills/dashboard-build/examples/_smoke.yml +15 -0
- dataface/ai/skills/dashboard-design/SKILL.md +182 -0
- dataface/ai/skills/dashboard-review/SKILL.md +113 -0
- dataface/ai/skills/dashboard-structural-review/SKILL.md +173 -0
- dataface/ai/skills/dashboard-visual-review/SKILL.md +139 -0
- dataface/ai/skills/dataface-mcp-setup/SKILL.md +177 -0
- dataface/ai/skills/dataface-troubleshooting/SKILL.md +225 -0
- dataface/ai/skills/drill-down-link/SKILL.md +112 -0
- dataface/ai/skills/drill-down-link/examples/drill-down-link.yml +27 -0
- dataface/ai/skills/faceted-small-multiples/SKILL.md +116 -0
- dataface/ai/skills/faceted-small-multiples/examples/faceted-small-multiples.yml +33 -0
- dataface/ai/skills/filter-bar-with-variables/SKILL.md +105 -0
- dataface/ai/skills/filter-bar-with-variables/examples/filter-bar-with-variables.yml +49 -0
- dataface/ai/skills/kpi-row/SKILL.md +101 -0
- dataface/ai/skills/kpi-row/examples/kpi-row.yml +55 -0
- dataface/ai/skills/report-design/SKILL.md +184 -0
- dataface/ai/skills/single-metric-bignum/SKILL.md +90 -0
- dataface/ai/skills/single-metric-bignum/examples/single-metric-bignum.yml +27 -0
- dataface/ai/skills/table-heavy-ops-dashboard/SKILL.md +114 -0
- dataface/ai/skills/table-heavy-ops-dashboard/examples/table-heavy-ops-dashboard.yml +48 -0
- dataface/ai/skills/time-series-trend/SKILL.md +93 -0
- dataface/ai/skills/time-series-trend/examples/time-series-trend.yml +26 -0
- dataface/ai/skills/top-n-with-detail/SKILL.md +98 -0
- dataface/ai/skills/top-n-with-detail/examples/top-n-with-detail.yml +45 -0
- dataface/ai/skills/two-by-two-grid-overview/SKILL.md +78 -0
- dataface/ai/skills/two-by-two-grid-overview/examples/two-by-two-grid-overview.yml +64 -0
- dataface/ai/tool_schemas.py +132 -0
- dataface/ai/tools/__init__.py +312 -0
- dataface/ai/yaml_utils.py +57 -0
- dataface/cli/__init__.py +3 -0
- dataface/cli/_console.py +48 -0
- dataface/cli/_error_format.py +83 -0
- dataface/cli/_extras.py +190 -0
- dataface/cli/_json_output.py +8 -0
- dataface/cli/_parsing.py +17 -0
- dataface/cli/_version_info.py +56 -0
- dataface/cli/commands/__init__.py +3 -0
- dataface/cli/commands/_agent_input.py +205 -0
- dataface/cli/commands/_agent_server.py +115 -0
- dataface/cli/commands/chat.py +645 -0
- dataface/cli/commands/describe.py +107 -0
- dataface/cli/commands/docs.py +131 -0
- dataface/cli/commands/extension.py +179 -0
- dataface/cli/commands/init.py +240 -0
- dataface/cli/commands/inspect.py +94 -0
- dataface/cli/commands/mcp_init.py +167 -0
- dataface/cli/commands/query.py +386 -0
- dataface/cli/commands/render.py +291 -0
- dataface/cli/commands/schema.py +411 -0
- dataface/cli/commands/search.py +49 -0
- dataface/cli/commands/serve.py +114 -0
- dataface/cli/commands/skills.py +133 -0
- dataface/cli/commands/skills_init.py +161 -0
- dataface/cli/commands/validate.py +63 -0
- dataface/cli/main.py +1501 -0
- dataface/core/__init__.py +75 -0
- dataface/core/compile/__init__.py +244 -0
- dataface/core/compile/_jinja_helpers.py +78 -0
- dataface/core/compile/channel.py +222 -0
- dataface/core/compile/chart_focus.py +101 -0
- dataface/core/compile/chart_resolved.py +169 -0
- dataface/core/compile/chart_type_detection.py +489 -0
- dataface/core/compile/chart_update.py +261 -0
- dataface/core/compile/colors.py +64 -0
- dataface/core/compile/compiler.py +904 -0
- dataface/core/compile/config.py +823 -0
- dataface/core/compile/custom_chart_types.py +208 -0
- dataface/core/compile/data_table_attachment.py +1287 -0
- dataface/core/compile/detect.py +110 -0
- dataface/core/compile/errors.py +302 -0
- dataface/core/compile/filter_injection.py +319 -0
- dataface/core/compile/introspection.py +527 -0
- dataface/core/compile/jinja.py +511 -0
- dataface/core/compile/labels_env.py +52 -0
- dataface/core/compile/markdown.py +154 -0
- dataface/core/compile/meta.py +388 -0
- dataface/core/compile/models/__init__.py +0 -0
- dataface/core/compile/models/chart/__init__.py +0 -0
- dataface/core/compile/models/chart/authored.py +2137 -0
- dataface/core/compile/models/chart/compiled.py +398 -0
- dataface/core/compile/models/config.py +347 -0
- dataface/core/compile/models/face/__init__.py +0 -0
- dataface/core/compile/models/face/authored.py +659 -0
- dataface/core/compile/models/face/compiled.py +522 -0
- dataface/core/compile/models/factories.py +201 -0
- dataface/core/compile/models/markers.py +40 -0
- dataface/core/compile/models/palette.py +36 -0
- dataface/core/compile/models/primitives.py +415 -0
- dataface/core/compile/models/query/__init__.py +0 -0
- dataface/core/compile/models/query/authored.py +246 -0
- dataface/core/compile/models/query/compiled.py +710 -0
- dataface/core/compile/models/refs.py +137 -0
- dataface/core/compile/models/source.py +611 -0
- dataface/core/compile/models/style/__init__.py +0 -0
- dataface/core/compile/models/style/authored.py +481 -0
- dataface/core/compile/models/style/compiled.py +3399 -0
- dataface/core/compile/models/style/merged.py +1682 -0
- dataface/core/compile/models/theme.py +362 -0
- dataface/core/compile/models/variable/__init__.py +0 -0
- dataface/core/compile/models/variable/authored.py +254 -0
- dataface/core/compile/models/vega_lite/__init__.py +0 -0
- dataface/core/compile/models/vega_lite/config.py +510 -0
- dataface/core/compile/models/vega_lite/contracts.py +171 -0
- dataface/core/compile/normalize_charts.py +494 -0
- dataface/core/compile/normalize_layout.py +1000 -0
- dataface/core/compile/normalize_queries.py +297 -0
- dataface/core/compile/normalize_variables.py +489 -0
- dataface/core/compile/normalizer.py +543 -0
- dataface/core/compile/palette.py +1100 -0
- dataface/core/compile/parameterized.py +658 -0
- dataface/core/compile/parser.py +228 -0
- dataface/core/compile/schema.py +20 -0
- dataface/core/compile/schema_renderers/__init__.py +0 -0
- dataface/core/compile/schema_renderers/json_schema.py +163 -0
- dataface/core/compile/schema_renderers/prompt.py +152 -0
- dataface/core/compile/schema_renderers/vscode_schema.py +301 -0
- dataface/core/compile/sizing.py +2126 -0
- dataface/core/compile/sources.py +518 -0
- dataface/core/compile/sql_authoring_lint.py +56 -0
- dataface/core/compile/style_cascade.py +471 -0
- dataface/core/compile/typography.py +299 -0
- dataface/core/compile/validator.py +301 -0
- dataface/core/compile/variables.py +53 -0
- dataface/core/compile/vega_config.py +98 -0
- dataface/core/compile/vega_lite/__init__.py +6 -0
- dataface/core/compile/vega_lite/validation.py +95 -0
- dataface/core/compile/yaml_error_formatter.py +838 -0
- dataface/core/connections.py +38 -0
- dataface/core/dashboard.py +358 -0
- dataface/core/defaults/default_config.yml +101 -0
- dataface/core/defaults/palettes/categorical/category-10-dark.yml +32 -0
- dataface/core/defaults/palettes/categorical/category-10-light.yml +43 -0
- dataface/core/defaults/palettes/categorical/category-10.yml +31 -0
- dataface/core/defaults/palettes/categorical/category-6-tonal-blue.yml +22 -0
- dataface/core/defaults/palettes/categorical/category-6-tonal-brown.yml +29 -0
- dataface/core/defaults/palettes/categorical/category-6-tonal-green.yml +20 -0
- dataface/core/defaults/palettes/categorical/category-6-tonal-orange.yml +21 -0
- dataface/core/defaults/palettes/categorical/category-6-tonal-purple.yml +20 -0
- dataface/core/defaults/palettes/categorical/editorial-10-dark.yml +32 -0
- dataface/core/defaults/palettes/categorical/editorial-10.yml +40 -0
- dataface/core/defaults/palettes/categorical/hero-6.yml +17 -0
- dataface/core/defaults/palettes/categorical/single-blue.yml +11 -0
- dataface/core/defaults/palettes/categorical/tableau.yml +20 -0
- dataface/core/defaults/palettes/data/xkcd_colors.json +3803 -0
- dataface/core/defaults/palettes/diverging/blue-red.yml +25 -0
- dataface/core/defaults/palettes/diverging/coolwarm.yml +24 -0
- dataface/core/defaults/palettes/diverging/crimson-green.yml +23 -0
- dataface/core/defaults/palettes/diverging/orange-teal.yml +23 -0
- dataface/core/defaults/palettes/diverging/sunset.yml +24 -0
- dataface/core/defaults/palettes/scaffold/dft-creams.yml +38 -0
- dataface/core/defaults/palettes/scaffold/dft-grays.yml +53 -0
- dataface/core/defaults/palettes/sequential/amber.yml +22 -0
- dataface/core/defaults/palettes/sequential/blue.yml +22 -0
- dataface/core/defaults/palettes/sequential/brown.yml +22 -0
- dataface/core/defaults/palettes/sequential/gray.yml +22 -0
- dataface/core/defaults/palettes/sequential/green.yml +22 -0
- dataface/core/defaults/palettes/sequential/purple.yml +22 -0
- dataface/core/defaults/palettes/sequential/rust.yml +22 -0
- dataface/core/defaults/palettes/sequential/teal.yml +22 -0
- dataface/core/defaults/palettes/tone/negative.yml +32 -0
- dataface/core/defaults/palettes/tone/positive.yml +22 -0
- dataface/core/defaults/palettes/tone/warning.yml +22 -0
- dataface/core/defaults/themes/_base.yaml +786 -0
- dataface/core/defaults/themes/bi.yaml +16 -0
- dataface/core/defaults/themes/carbong100.yaml +41 -0
- dataface/core/defaults/themes/cream.yaml +122 -0
- dataface/core/defaults/themes/dark.yaml +40 -0
- dataface/core/defaults/themes/diagnostics-title-angle-extreme.yaml +9 -0
- dataface/core/defaults/themes/diagnostics-title-baseline-extreme.yaml +9 -0
- dataface/core/defaults/themes/diagnostics-title-baseline.yaml +24 -0
- dataface/core/defaults/themes/diagnostics-title-center.yaml +8 -0
- dataface/core/defaults/themes/diagnostics-title-color-extreme.yaml +24 -0
- dataface/core/defaults/themes/diagnostics-title-font-extreme.yaml +25 -0
- dataface/core/defaults/themes/diagnostics-title-left.yaml +8 -0
- dataface/core/defaults/themes/diagnostics-title-offset-extreme.yaml +9 -0
- dataface/core/defaults/themes/diagnostics-title-size-extreme.yaml +24 -0
- dataface/core/defaults/themes/diagnostics-title-weight-extreme.yaml +24 -0
- dataface/core/defaults/themes/editorial.yaml +147 -0
- dataface/core/defaults/themes/light.yaml +30 -0
- dataface/core/defaults/themes/looker.yaml +17 -0
- dataface/core/defaults/themes/stark.yaml +134 -0
- dataface/core/errors/__init__.py +67 -0
- dataface/core/errors/codes_compile.py +56 -0
- dataface/core/errors/codes_execute.py +177 -0
- dataface/core/errors/codes_render.py +106 -0
- dataface/core/errors/codes_unknown.py +15 -0
- dataface/core/errors/hints.py +74 -0
- dataface/core/errors/registry.py +42 -0
- dataface/core/errors/structured.py +92 -0
- dataface/core/execute/__init__.py +91 -0
- dataface/core/execute/adapters/__init__.py +49 -0
- dataface/core/execute/adapters/adapter_registry.py +400 -0
- dataface/core/execute/adapters/base.py +245 -0
- dataface/core/execute/adapters/csv_adapter.py +239 -0
- dataface/core/execute/adapters/dbt_adapter.py +283 -0
- dataface/core/execute/adapters/dbt_adapter_factory.py +212 -0
- dataface/core/execute/adapters/dbt_macro_loader.py +95 -0
- dataface/core/execute/adapters/dbt_utils.py +150 -0
- dataface/core/execute/adapters/http_adapter.py +224 -0
- dataface/core/execute/adapters/metricflow_adapter.py +94 -0
- dataface/core/execute/adapters/schema_resolver_adapter.py +144 -0
- dataface/core/execute/adapters/sql_adapter.py +710 -0
- dataface/core/execute/adapters/values_adapter.py +58 -0
- dataface/core/execute/batch.py +744 -0
- dataface/core/execute/cache_backend.py +135 -0
- dataface/core/execute/cache_keys.py +66 -0
- dataface/core/execute/dbt_jinja.py +21 -0
- dataface/core/execute/dialects/__init__.py +121 -0
- dataface/core/execute/dialects/athena.py +75 -0
- dataface/core/execute/dialects/base.py +302 -0
- dataface/core/execute/dialects/bigquery.py +38 -0
- dataface/core/execute/dialects/databricks.py +68 -0
- dataface/core/execute/dialects/duckdb.py +35 -0
- dataface/core/execute/dialects/mysql.py +68 -0
- dataface/core/execute/dialects/postgres.py +39 -0
- dataface/core/execute/dialects/redshift.py +12 -0
- dataface/core/execute/dialects/snowflake.py +51 -0
- dataface/core/execute/dialects/sqlserver.py +92 -0
- dataface/core/execute/duckdb_cache.py +712 -0
- dataface/core/execute/duckdb_config.py +26 -0
- dataface/core/execute/errors.py +213 -0
- dataface/core/execute/executor.py +1249 -0
- dataface/core/execute/parallel.py +162 -0
- dataface/core/execute/setup_sql.py +58 -0
- dataface/core/execute/source_registry.py +72 -0
- dataface/core/execute/source_resolver.py +255 -0
- dataface/core/execute/sql_guard.py +387 -0
- dataface/core/execute/sql_literals.py +199 -0
- dataface/core/fonts.py +52 -0
- dataface/core/inspect/__init__.py +32 -0
- dataface/core/inspect/cache_factory.py +98 -0
- dataface/core/inspect/db_types.py +162 -0
- dataface/core/inspect/dbt_schema.py +96 -0
- dataface/core/inspect/defaults.yml +37 -0
- dataface/core/inspect/fanout_risk.py +109 -0
- dataface/core/inspect/manifest_utils.py +77 -0
- dataface/core/inspect/partials/categorical.yml +40 -0
- dataface/core/inspect/partials/date.yml +40 -0
- dataface/core/inspect/partials/numeric.yml +55 -0
- dataface/core/inspect/partition_types.py +38 -0
- dataface/core/inspect/query_validator.py +975 -0
- dataface/core/inspect/renderer.py +354 -0
- dataface/core/inspect/resolver.py +808 -0
- dataface/core/inspect/search.py +461 -0
- dataface/core/inspect/sources/__init__.py +32 -0
- dataface/core/inspect/sources/dbt.py +738 -0
- dataface/core/inspect/sources/duckdb_utils.py +66 -0
- dataface/core/inspect/templates/__init__.py +1 -0
- dataface/core/inspect/templates/categorical_column.yml +196 -0
- dataface/core/inspect/templates/charts.yml +109 -0
- dataface/core/inspect/templates/date_column.yml +248 -0
- dataface/core/inspect/templates/model.yml +138 -0
- dataface/core/inspect/templates/numeric_column.yml +261 -0
- dataface/core/inspect/templates/quality.yml +80 -0
- dataface/core/inspect/templates/string_column.yml +263 -0
- dataface/core/project_roots.py +165 -0
- dataface/core/render/__init__.py +87 -0
- dataface/core/render/board_links.py +176 -0
- dataface/core/render/chart/__init__.py +27 -0
- dataface/core/render/chart/arc_attached_table.py +251 -0
- dataface/core/render/chart/artifacts.py +16 -0
- dataface/core/render/chart/callout.py +225 -0
- dataface/core/render/chart/decisions.py +358 -0
- dataface/core/render/chart/geo.py +700 -0
- dataface/core/render/chart/kpi.py +916 -0
- dataface/core/render/chart/labels.py +76 -0
- dataface/core/render/chart/pipeline.py +818 -0
- dataface/core/render/chart/presentation.py +36 -0
- dataface/core/render/chart/profile.py +3438 -0
- dataface/core/render/chart/render_single.py +347 -0
- dataface/core/render/chart/renderers.py +193 -0
- dataface/core/render/chart/rendering.py +565 -0
- dataface/core/render/chart/serialization.py +90 -0
- dataface/core/render/chart/spark.py +496 -0
- dataface/core/render/chart/spark_bar.py +370 -0
- dataface/core/render/chart/spec_builders.py +154 -0
- dataface/core/render/chart/standard_renderer.py +2645 -0
- dataface/core/render/chart/table.py +2957 -0
- dataface/core/render/chart/table_support.py +1452 -0
- dataface/core/render/chart/tick_values.py +66 -0
- dataface/core/render/chart/time_unit_detect.py +809 -0
- dataface/core/render/chart/title_overflow.py +157 -0
- dataface/core/render/chart/type_inference.py +122 -0
- dataface/core/render/chart/validation.py +99 -0
- dataface/core/render/chart/vega_lite.py +125 -0
- dataface/core/render/chart/vega_lite_types.py +268 -0
- dataface/core/render/chart/vl_field_maps.py +346 -0
- dataface/core/render/chart_interactivity.py +24 -0
- dataface/core/render/control_registry.py +287 -0
- dataface/core/render/converters/__init__.py +24 -0
- dataface/core/render/converters/chart.py +276 -0
- dataface/core/render/converters/html.py +98 -0
- dataface/core/render/converters/pdf.py +40 -0
- dataface/core/render/converters/png.py +41 -0
- dataface/core/render/errors.py +144 -0
- dataface/core/render/face_api.py +160 -0
- dataface/core/render/faces.py +1194 -0
- dataface/core/render/font_measurement.py +48 -0
- dataface/core/render/font_support.py +197 -0
- dataface/core/render/fonts/DFTSansTabular-Regular.ttf +0 -0
- dataface/core/render/fonts/DFTSansTabular-Regular.woff2 +0 -0
- dataface/core/render/fonts/DFTSerifOldstyleProportional-Regular.ttf +0 -0
- dataface/core/render/fonts/DFTSerifOldstyleTabular-Regular.ttf +0 -0
- dataface/core/render/fonts/InterVariable.ttf +0 -0
- dataface/core/render/fonts/InterVariable.woff2 +0 -0
- dataface/core/render/fonts/NOTO_COLOR_EMOJI_LICENSE.txt +93 -0
- dataface/core/render/fonts/NOTO_EMOJI_LICENSE.txt +93 -0
- dataface/core/render/fonts/NotoColorEmoji-Regular.ttf +0 -0
- dataface/core/render/fonts/NotoColorEmoji-Regular.woff2 +0 -0
- dataface/core/render/fonts/NotoEmoji-Regular.ttf +0 -0
- dataface/core/render/fonts/NotoEmoji-Regular.woff2 +0 -0
- dataface/core/render/fonts/SOURCE_CODE_PRO_LICENSE.txt +93 -0
- dataface/core/render/fonts/SOURCE_SERIF_4_LICENSE.txt +98 -0
- dataface/core/render/fonts/SourceCodePro-Regular.ttf +0 -0
- dataface/core/render/fonts/SourceSerif4-Regular.ttf +0 -0
- dataface/core/render/fonts/_emoji_font_face.css +43 -0
- dataface/core/render/fonts/source-serif-4-variable-latin.woff2 +0 -0
- dataface/core/render/format_utils.py +329 -0
- dataface/core/render/geo_defaults.yml +28 -0
- dataface/core/render/json_format.py +146 -0
- dataface/core/render/layout_sizing.py +865 -0
- dataface/core/render/layouts.py +541 -0
- dataface/core/render/markdown_defaults.yml +16 -0
- dataface/core/render/missing_vars_prompt.py +79 -0
- dataface/core/render/placeholder.py +389 -0
- dataface/core/render/render_result.py +14 -0
- dataface/core/render/renderer.py +467 -0
- dataface/core/render/script_embedding.py +16 -0
- dataface/core/render/svg_utils.py +212 -0
- dataface/core/render/template_loader.py +69 -0
- dataface/core/render/templates/controls/_styles.css +606 -0
- dataface/core/render/templates/controls/checkbox.html +16 -0
- dataface/core/render/templates/controls/date.html +16 -0
- dataface/core/render/templates/controls/number.html +19 -0
- dataface/core/render/templates/controls/readonly.html +9 -0
- dataface/core/render/templates/controls/select.html +21 -0
- dataface/core/render/templates/controls/slider.html +22 -0
- dataface/core/render/templates/controls/text.html +16 -0
- dataface/core/render/templates/scripts/chart_interactivity.js +191 -0
- dataface/core/render/templates/scripts/variables.js +976 -0
- dataface/core/render/templates/svg/grid_pattern.svg +3 -0
- dataface/core/render/templates/svg/styles.css +51 -0
- dataface/core/render/terminal.py +311 -0
- dataface/core/render/terminal_charts.py +563 -0
- dataface/core/render/terminal_defaults.yml +2 -0
- dataface/core/render/terminal_layouts.py +299 -0
- dataface/core/render/terminal_text.py +31 -0
- dataface/core/render/text/__init__.py +1 -0
- dataface/core/render/text/case.py +113 -0
- dataface/core/render/text_format.py +129 -0
- dataface/core/render/utils.py +106 -0
- dataface/core/render/variable_controls.py +946 -0
- dataface/core/render/variable_input_refinement.py +140 -0
- dataface/core/render/warnings/__init__.py +15 -0
- dataface/core/render/warnings/bar_color_1_to_1_with_x.py +80 -0
- dataface/core/render/warnings/base.py +44 -0
- dataface/core/render/warnings/fanout_risk.py +15 -0
- dataface/core/render/warnings/from_query_diagnostic.py +56 -0
- dataface/core/render/warnings/missing_join_predicate.py +13 -0
- dataface/core/render/warnings/query_parse_error.py +14 -0
- dataface/core/render/warnings/query_returned_zero_rows.py +42 -0
- dataface/core/render/warnings/reaggregation.py +14 -0
- dataface/core/render/warnings/registry.py +45 -0
- dataface/core/render/warnings/suppression.py +46 -0
- dataface/core/render/warnings/temporal_single_point.py +63 -0
- dataface/core/render/warnings/unreferenced_chart.py +15 -0
- dataface/core/render/warnings/y_encoding_mostly_null.py +76 -0
- dataface/core/render/yaml_format.py +167 -0
- dataface/core/resolve_face.py +195 -0
- dataface/core/schema/__init__.py +0 -0
- dataface/core/schema/guidance.py +151 -0
- dataface/core/scoped_paths.py +59 -0
- dataface/core/serve/__init__.py +14 -0
- dataface/core/serve/bootstrap.py +39 -0
- dataface/core/serve/embedded.py +57 -0
- dataface/core/serve/port.py +129 -0
- dataface/core/serve/server.py +938 -0
- dataface/core/serve/templates/__init__.py +0 -0
- dataface/core/serve/templates/directory.yml +6 -0
- dataface/core/serve/templates/error.html.j2 +217 -0
- dataface/core/utils.py +121 -0
- dataface/core/validate.py +64 -0
- dataface/integrations/__init__.py +0 -0
- dataface/integrations/highlighting.py +351 -0
- dataface/integrations/markdown.py +537 -0
- dataface/py.typed +0 -0
- dataface-0.1.2.dist-info/METADATA +375 -0
- dataface-0.1.2.dist-info/RECORD +455 -0
- dataface-0.1.2.dist-info/WHEEL +4 -0
- dataface-0.1.2.dist-info/entry_points.txt +2 -0
- dataface-0.1.2.dist-info/licenses/LICENSE +202 -0
- mdsvg/__init__.py +168 -0
- mdsvg/fonts.py +656 -0
- mdsvg/images.py +299 -0
- mdsvg/parser.py +629 -0
- mdsvg/playground.py +284 -0
- mdsvg/py.typed +2 -0
- mdsvg/renderer.py +1623 -0
- mdsvg/style.py +355 -0
- mdsvg/types.py +200 -0
- mdsvg/utils.py +86 -0
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
<style type="text/css">
|
|
2
|
+
/* SVG Chart Styles
|
|
3
|
+
* These styles are embedded in dataface SVGs for interactive features.
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
{% if emoji_mode != "disabled" %}{% include '_emoji_font_face.css' %}{% endif %}
|
|
7
|
+
{% if emoji_mode in ("monochrome", "color") %}svg text { font-variant-emoji: text; }{% endif %}
|
|
8
|
+
|
|
9
|
+
/* Chart base styles */
|
|
10
|
+
.dft-chart {
|
|
11
|
+
position: relative;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
/* Chart loading state */
|
|
15
|
+
.dft-chart.loading {
|
|
16
|
+
opacity: 0.5;
|
|
17
|
+
pointer-events: none;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
/* Chart highlight overlay when hovering over dependent variable */
|
|
21
|
+
/* Border only, no fill - just outlines the dependent charts */
|
|
22
|
+
.dft-chart-highlight-overlay {
|
|
23
|
+
fill: none;
|
|
24
|
+
stroke: #667eea;
|
|
25
|
+
stroke-width: 3;
|
|
26
|
+
pointer-events: none;
|
|
27
|
+
opacity: 1;
|
|
28
|
+
transition: opacity 0.15s ease-in-out;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
/* Variable control hover */
|
|
32
|
+
.variable-control:hover {
|
|
33
|
+
cursor: pointer;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
.variable-control[data-disabled="true"] {
|
|
37
|
+
opacity: 0.55;
|
|
38
|
+
cursor: not-allowed;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
.variable-control[data-disabled="true"]:hover {
|
|
42
|
+
cursor: not-allowed;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
{% include 'controls/_styles.css' %}
|
|
46
|
+
|
|
47
|
+
/* Spinner animation for loading state */
|
|
48
|
+
@keyframes dft-spin {
|
|
49
|
+
to { transform: rotate(360deg); }
|
|
50
|
+
}
|
|
51
|
+
</style>
|
|
@@ -0,0 +1,311 @@
|
|
|
1
|
+
"""Terminal rendering module.
|
|
2
|
+
|
|
3
|
+
Stage: RENDER
|
|
4
|
+
Purpose: Render compiled datafaces to terminal output.
|
|
5
|
+
|
|
6
|
+
This module provides terminal rendering functionality using:
|
|
7
|
+
- Plotext for charts
|
|
8
|
+
- Rich for tables and text formatting
|
|
9
|
+
- Custom layout rendering for terminal constraints
|
|
10
|
+
|
|
11
|
+
Entry Points:
|
|
12
|
+
- render_face_terminal(face, executor, variables, **options) -> str
|
|
13
|
+
- render_chart_terminal(chart, data, **options) -> str
|
|
14
|
+
"""
|
|
15
|
+
|
|
16
|
+
import shutil
|
|
17
|
+
from typing import Any
|
|
18
|
+
|
|
19
|
+
from dataface.core.compile.models.chart.compiled import (
|
|
20
|
+
Chart,
|
|
21
|
+
)
|
|
22
|
+
from dataface.core.compile.models.face.compiled import (
|
|
23
|
+
Face,
|
|
24
|
+
Layout,
|
|
25
|
+
LayoutItem,
|
|
26
|
+
VariableValues,
|
|
27
|
+
)
|
|
28
|
+
from dataface.core.execute.executor import Executor
|
|
29
|
+
from dataface.core.render.variable_controls import evaluate_visible
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
def _dispatch_layout(
|
|
33
|
+
layout: Layout,
|
|
34
|
+
executor: Executor,
|
|
35
|
+
variables: dict[str, Any],
|
|
36
|
+
width: int,
|
|
37
|
+
height: int,
|
|
38
|
+
gap: int,
|
|
39
|
+
background: str | None,
|
|
40
|
+
grid_columns: int,
|
|
41
|
+
) -> str:
|
|
42
|
+
"""Dispatch to the correct terminal layout renderer based on layout type."""
|
|
43
|
+
from dataface.core.render.terminal_layouts import (
|
|
44
|
+
render_cols_layout_terminal,
|
|
45
|
+
render_grid_layout_terminal,
|
|
46
|
+
render_rows_layout_terminal,
|
|
47
|
+
render_tabs_layout_terminal,
|
|
48
|
+
)
|
|
49
|
+
|
|
50
|
+
if layout.type == "cols":
|
|
51
|
+
return render_cols_layout_terminal(
|
|
52
|
+
layout.items,
|
|
53
|
+
executor,
|
|
54
|
+
variables,
|
|
55
|
+
width,
|
|
56
|
+
height,
|
|
57
|
+
gap=gap,
|
|
58
|
+
background=background,
|
|
59
|
+
)
|
|
60
|
+
if layout.type == "grid":
|
|
61
|
+
return render_grid_layout_terminal(
|
|
62
|
+
layout.items,
|
|
63
|
+
executor,
|
|
64
|
+
variables,
|
|
65
|
+
width,
|
|
66
|
+
height,
|
|
67
|
+
columns=layout.columns or grid_columns,
|
|
68
|
+
gap=gap,
|
|
69
|
+
background=background,
|
|
70
|
+
)
|
|
71
|
+
if layout.type == "tabs":
|
|
72
|
+
return render_tabs_layout_terminal(
|
|
73
|
+
layout.items,
|
|
74
|
+
executor,
|
|
75
|
+
variables,
|
|
76
|
+
width,
|
|
77
|
+
height,
|
|
78
|
+
layout.tab_titles,
|
|
79
|
+
layout.default_tab or 0,
|
|
80
|
+
layout.tab_position or "top",
|
|
81
|
+
background,
|
|
82
|
+
)
|
|
83
|
+
# "rows" or any unknown type — fall back to rows
|
|
84
|
+
return render_rows_layout_terminal(
|
|
85
|
+
layout.items,
|
|
86
|
+
executor,
|
|
87
|
+
variables,
|
|
88
|
+
width,
|
|
89
|
+
height,
|
|
90
|
+
gap=gap,
|
|
91
|
+
background=background,
|
|
92
|
+
)
|
|
93
|
+
|
|
94
|
+
|
|
95
|
+
def render_face_terminal(
|
|
96
|
+
face: Face,
|
|
97
|
+
executor: Executor,
|
|
98
|
+
variables: VariableValues | None = None,
|
|
99
|
+
width: int | None = None,
|
|
100
|
+
height: int | None = None,
|
|
101
|
+
colors: bool = True,
|
|
102
|
+
**options: Any,
|
|
103
|
+
) -> str:
|
|
104
|
+
"""Render a compiled dataface to terminal output.
|
|
105
|
+
|
|
106
|
+
Args:
|
|
107
|
+
face: Compiled dataface to render
|
|
108
|
+
executor: Executor for query execution
|
|
109
|
+
variables: Variable values for queries
|
|
110
|
+
width: Terminal width in characters (auto-detect if None)
|
|
111
|
+
height: Terminal height in characters (auto-detect if None)
|
|
112
|
+
colors: Whether to use ANSI colors
|
|
113
|
+
**options: Additional rendering options
|
|
114
|
+
|
|
115
|
+
Returns:
|
|
116
|
+
Terminal-formatted dataface string
|
|
117
|
+
"""
|
|
118
|
+
# Auto-detect terminal size if not provided
|
|
119
|
+
if width is None or height is None:
|
|
120
|
+
try:
|
|
121
|
+
term_size = shutil.get_terminal_size()
|
|
122
|
+
width = width or term_size.columns
|
|
123
|
+
height = height or term_size.lines
|
|
124
|
+
except (OSError, ValueError):
|
|
125
|
+
# shutil.get_terminal_size() can fail in non-TTY environments (CI, pipes, etc.)
|
|
126
|
+
# Fallback to standard terminal size
|
|
127
|
+
width = width or 80
|
|
128
|
+
height = height or 24
|
|
129
|
+
|
|
130
|
+
# Trust the normalizer - use pre-computed variable_defaults
|
|
131
|
+
variable_registry = face.variable_registry or {}
|
|
132
|
+
|
|
133
|
+
# Merge variables: start with None for all vars, then defaults, then user values
|
|
134
|
+
all_variables: dict[str, Any] = dict.fromkeys(variable_registry)
|
|
135
|
+
all_variables.update(face.variable_defaults) # Pre-computed by normalizer
|
|
136
|
+
if variables:
|
|
137
|
+
all_variables.update(variables)
|
|
138
|
+
|
|
139
|
+
# Calculate layout dimensions
|
|
140
|
+
from dataface.core.compile.config import get_config
|
|
141
|
+
|
|
142
|
+
config = get_config()
|
|
143
|
+
face_width = width - 4 # Account for padding
|
|
144
|
+
face_height = height - 4
|
|
145
|
+
|
|
146
|
+
# Render title if present
|
|
147
|
+
title_lines: list[str] = []
|
|
148
|
+
title_height = 0
|
|
149
|
+
if face.title:
|
|
150
|
+
from dataface.core.compile.jinja import resolve_jinja_template
|
|
151
|
+
|
|
152
|
+
resolved_title = resolve_jinja_template(face.title, all_variables)
|
|
153
|
+
|
|
154
|
+
# Format title with border
|
|
155
|
+
title_lines.append("=" * face_width)
|
|
156
|
+
title_lines.append(f" {resolved_title}")
|
|
157
|
+
title_lines.append("=" * face_width)
|
|
158
|
+
title_lines.append("")
|
|
159
|
+
title_height = len(title_lines)
|
|
160
|
+
|
|
161
|
+
# Calculate layout area
|
|
162
|
+
layout_width = face_width
|
|
163
|
+
layout_height = face_height - title_height
|
|
164
|
+
|
|
165
|
+
layout_output = _dispatch_layout(
|
|
166
|
+
face.layout,
|
|
167
|
+
executor,
|
|
168
|
+
all_variables,
|
|
169
|
+
layout_width,
|
|
170
|
+
layout_height,
|
|
171
|
+
gap=1,
|
|
172
|
+
background=face.authored_style.background if face.authored_style else None,
|
|
173
|
+
grid_columns=config.style.layout.grid.columns,
|
|
174
|
+
)
|
|
175
|
+
|
|
176
|
+
# Combine title and layout
|
|
177
|
+
output_lines = title_lines + [layout_output]
|
|
178
|
+
|
|
179
|
+
return "\n".join(output_lines)
|
|
180
|
+
|
|
181
|
+
|
|
182
|
+
def render_layout_item_terminal(
|
|
183
|
+
item: LayoutItem,
|
|
184
|
+
executor: Executor,
|
|
185
|
+
variables: VariableValues,
|
|
186
|
+
available_width: int,
|
|
187
|
+
available_height: int,
|
|
188
|
+
) -> str:
|
|
189
|
+
"""Render a single layout item (chart or nested face) to terminal.
|
|
190
|
+
|
|
191
|
+
Args:
|
|
192
|
+
item: Layout item to render
|
|
193
|
+
executor: Executor for query execution
|
|
194
|
+
variables: Variable values for queries
|
|
195
|
+
available_width: Available terminal width in characters
|
|
196
|
+
available_height: Available terminal height in characters
|
|
197
|
+
|
|
198
|
+
Returns:
|
|
199
|
+
Terminal-formatted string for the item
|
|
200
|
+
"""
|
|
201
|
+
if not evaluate_visible(item.visible, variables, executor):
|
|
202
|
+
return ""
|
|
203
|
+
if item.type == "chart" and item.chart:
|
|
204
|
+
return render_chart_item_terminal(
|
|
205
|
+
item.chart, executor, variables, available_width, available_height
|
|
206
|
+
)
|
|
207
|
+
elif item.type == "face" and item.face:
|
|
208
|
+
return render_nested_face_terminal(
|
|
209
|
+
item.face, executor, variables, available_width, available_height
|
|
210
|
+
)
|
|
211
|
+
return ""
|
|
212
|
+
|
|
213
|
+
|
|
214
|
+
def render_chart_item_terminal(
|
|
215
|
+
chart: Chart,
|
|
216
|
+
executor: Executor,
|
|
217
|
+
variables: VariableValues,
|
|
218
|
+
available_width: int,
|
|
219
|
+
available_height: int,
|
|
220
|
+
) -> str:
|
|
221
|
+
"""Render a chart item to terminal.
|
|
222
|
+
|
|
223
|
+
Args:
|
|
224
|
+
chart: Chart to render
|
|
225
|
+
executor: Executor for query execution
|
|
226
|
+
variables: Variable values for queries
|
|
227
|
+
available_width: Available terminal width in characters
|
|
228
|
+
available_height: Available terminal height in characters
|
|
229
|
+
|
|
230
|
+
Returns:
|
|
231
|
+
Terminal-formatted chart string
|
|
232
|
+
"""
|
|
233
|
+
try:
|
|
234
|
+
# Execute query to get data
|
|
235
|
+
data = executor.execute_chart(chart, variables)
|
|
236
|
+
|
|
237
|
+
# Resolve Jinja templates in chart title/label if present.
|
|
238
|
+
# KPI charts carry their authored text in ``label`` (the slot rendered
|
|
239
|
+
# above the headline value); every other chart type uses ``title``.
|
|
240
|
+
from dataface.core.compile.jinja import resolve_jinja_template
|
|
241
|
+
|
|
242
|
+
updates: dict[str, str] = {}
|
|
243
|
+
if chart.title:
|
|
244
|
+
updates["title"] = resolve_jinja_template(chart.title, variables)
|
|
245
|
+
if chart.label:
|
|
246
|
+
updates["label"] = resolve_jinja_template(chart.label, variables)
|
|
247
|
+
resolved_chart = chart.model_copy(update=updates) if updates else chart
|
|
248
|
+
|
|
249
|
+
# Render chart
|
|
250
|
+
from dataface.core.render.terminal_charts import render_chart_terminal
|
|
251
|
+
|
|
252
|
+
return render_chart_terminal(
|
|
253
|
+
resolved_chart,
|
|
254
|
+
data,
|
|
255
|
+
width=available_width,
|
|
256
|
+
height=available_height,
|
|
257
|
+
colors=True,
|
|
258
|
+
)
|
|
259
|
+
|
|
260
|
+
except (ValueError, KeyError, TypeError, AttributeError) as e:
|
|
261
|
+
# Render error message for chart rendering failures
|
|
262
|
+
error_msg = str(e)[:200] # Show more of the error for debugging
|
|
263
|
+
return f"[Error rendering {chart.id}: {error_msg}]"
|
|
264
|
+
|
|
265
|
+
|
|
266
|
+
def render_nested_face_terminal(
|
|
267
|
+
face: Face,
|
|
268
|
+
executor: Executor,
|
|
269
|
+
variables: VariableValues,
|
|
270
|
+
available_width: int,
|
|
271
|
+
available_height: int,
|
|
272
|
+
) -> str:
|
|
273
|
+
"""Render a nested face to terminal.
|
|
274
|
+
|
|
275
|
+
Args:
|
|
276
|
+
face: Face to render
|
|
277
|
+
executor: Executor for query execution
|
|
278
|
+
variables: Variable values for queries
|
|
279
|
+
available_width: Available terminal width in characters
|
|
280
|
+
available_height: Available terminal height in characters
|
|
281
|
+
|
|
282
|
+
Returns:
|
|
283
|
+
Terminal-formatted face string
|
|
284
|
+
"""
|
|
285
|
+
from dataface.core.compile.config import get_config
|
|
286
|
+
|
|
287
|
+
config = get_config()
|
|
288
|
+
|
|
289
|
+
title_lines: list[str] = []
|
|
290
|
+
if face.title:
|
|
291
|
+
from dataface.core.compile.jinja import resolve_jinja_template
|
|
292
|
+
|
|
293
|
+
resolved_title = resolve_jinja_template(face.title, variables)
|
|
294
|
+
title_lines.append(f"─ {resolved_title} ─")
|
|
295
|
+
title_lines.append("")
|
|
296
|
+
|
|
297
|
+
title_height = len(title_lines)
|
|
298
|
+
layout_height = available_height - title_height
|
|
299
|
+
|
|
300
|
+
layout_output = _dispatch_layout(
|
|
301
|
+
face.layout,
|
|
302
|
+
executor,
|
|
303
|
+
variables,
|
|
304
|
+
available_width,
|
|
305
|
+
layout_height,
|
|
306
|
+
gap=1,
|
|
307
|
+
background=face.authored_style.background if face.authored_style else None,
|
|
308
|
+
grid_columns=config.style.layout.grid.columns,
|
|
309
|
+
)
|
|
310
|
+
|
|
311
|
+
return "\n".join(title_lines + [layout_output])
|