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.
Files changed (455) hide show
  1. d3_format/__init__.py +14 -0
  2. d3_format/errors.py +19 -0
  3. d3_format/format.py +551 -0
  4. d3_format/spec.py +159 -0
  5. dataface/DATAFACE_SYNTAX.md +1135 -0
  6. dataface/__init__.py +93 -0
  7. dataface/_docs_site.py +20 -0
  8. dataface/_install_hint.py +26 -0
  9. dataface/agent_api/__init__.py +79 -0
  10. dataface/agent_api/_init_templates/__init__.py +0 -0
  11. dataface/agent_api/_init_templates/agents_dft_snippet.md +26 -0
  12. dataface/agent_api/_init_templates/dataface.yml +15 -0
  13. dataface/agent_api/_init_templates/faces-dataface.yml +144 -0
  14. dataface/agent_api/_init_templates/index.md +24 -0
  15. dataface/agent_api/_paths.py +118 -0
  16. dataface/agent_api/_project_agents_md.py +43 -0
  17. dataface/agent_api/_session_store.py +486 -0
  18. dataface/agent_api/_state.py +28 -0
  19. dataface/agent_api/chat.py +221 -0
  20. dataface/agent_api/dashboards.py +257 -0
  21. dataface/agent_api/describe.py +366 -0
  22. dataface/agent_api/describe_query.py +120 -0
  23. dataface/agent_api/docs/__init__.py +25 -0
  24. dataface/agent_api/docs/_loader.py +292 -0
  25. dataface/agent_api/docs/yaml-reference.md +2757 -0
  26. dataface/agent_api/file_refs.py +118 -0
  27. dataface/agent_api/init.py +126 -0
  28. dataface/agent_api/inspect.py +128 -0
  29. dataface/agent_api/mcp_install.py +170 -0
  30. dataface/agent_api/query.py +274 -0
  31. dataface/agent_api/schema.py +658 -0
  32. dataface/agent_api/schema_search.py +284 -0
  33. dataface/agent_api/search.py +270 -0
  34. dataface/agent_api/skill_install.py +141 -0
  35. dataface/agent_api/skill_render.py +90 -0
  36. dataface/agent_api/skills.py +293 -0
  37. dataface/agent_api/surface_aliases.yaml +128 -0
  38. dataface/agent_api/validate.py +175 -0
  39. dataface/agent_api/validate_query.py +84 -0
  40. dataface/ai/__init__.py +39 -0
  41. dataface/ai/agent.py +139 -0
  42. dataface/ai/context.py +45 -0
  43. dataface/ai/events.py +62 -0
  44. dataface/ai/external_mcp.py +610 -0
  45. dataface/ai/generate_sql.py +96 -0
  46. dataface/ai/llm.py +403 -0
  47. dataface/ai/mcp/__init__.py +51 -0
  48. dataface/ai/mcp/server.py +289 -0
  49. dataface/ai/memories.py +85 -0
  50. dataface/ai/prompts.py +177 -0
  51. dataface/ai/schema_context.py +138 -0
  52. dataface/ai/skills/before-after-comparison/SKILL.md +102 -0
  53. dataface/ai/skills/before-after-comparison/examples/before-after-comparison.yml +24 -0
  54. dataface/ai/skills/dashboard-build/SKILL.md +212 -0
  55. dataface/ai/skills/dashboard-build/examples/_smoke.yml +15 -0
  56. dataface/ai/skills/dashboard-design/SKILL.md +182 -0
  57. dataface/ai/skills/dashboard-review/SKILL.md +113 -0
  58. dataface/ai/skills/dashboard-structural-review/SKILL.md +173 -0
  59. dataface/ai/skills/dashboard-visual-review/SKILL.md +139 -0
  60. dataface/ai/skills/dataface-mcp-setup/SKILL.md +177 -0
  61. dataface/ai/skills/dataface-troubleshooting/SKILL.md +225 -0
  62. dataface/ai/skills/drill-down-link/SKILL.md +112 -0
  63. dataface/ai/skills/drill-down-link/examples/drill-down-link.yml +27 -0
  64. dataface/ai/skills/faceted-small-multiples/SKILL.md +116 -0
  65. dataface/ai/skills/faceted-small-multiples/examples/faceted-small-multiples.yml +33 -0
  66. dataface/ai/skills/filter-bar-with-variables/SKILL.md +105 -0
  67. dataface/ai/skills/filter-bar-with-variables/examples/filter-bar-with-variables.yml +49 -0
  68. dataface/ai/skills/kpi-row/SKILL.md +101 -0
  69. dataface/ai/skills/kpi-row/examples/kpi-row.yml +55 -0
  70. dataface/ai/skills/report-design/SKILL.md +184 -0
  71. dataface/ai/skills/single-metric-bignum/SKILL.md +90 -0
  72. dataface/ai/skills/single-metric-bignum/examples/single-metric-bignum.yml +27 -0
  73. dataface/ai/skills/table-heavy-ops-dashboard/SKILL.md +114 -0
  74. dataface/ai/skills/table-heavy-ops-dashboard/examples/table-heavy-ops-dashboard.yml +48 -0
  75. dataface/ai/skills/time-series-trend/SKILL.md +93 -0
  76. dataface/ai/skills/time-series-trend/examples/time-series-trend.yml +26 -0
  77. dataface/ai/skills/top-n-with-detail/SKILL.md +98 -0
  78. dataface/ai/skills/top-n-with-detail/examples/top-n-with-detail.yml +45 -0
  79. dataface/ai/skills/two-by-two-grid-overview/SKILL.md +78 -0
  80. dataface/ai/skills/two-by-two-grid-overview/examples/two-by-two-grid-overview.yml +64 -0
  81. dataface/ai/tool_schemas.py +132 -0
  82. dataface/ai/tools/__init__.py +312 -0
  83. dataface/ai/yaml_utils.py +57 -0
  84. dataface/cli/__init__.py +3 -0
  85. dataface/cli/_console.py +48 -0
  86. dataface/cli/_error_format.py +83 -0
  87. dataface/cli/_extras.py +190 -0
  88. dataface/cli/_json_output.py +8 -0
  89. dataface/cli/_parsing.py +17 -0
  90. dataface/cli/_version_info.py +56 -0
  91. dataface/cli/commands/__init__.py +3 -0
  92. dataface/cli/commands/_agent_input.py +205 -0
  93. dataface/cli/commands/_agent_server.py +115 -0
  94. dataface/cli/commands/chat.py +645 -0
  95. dataface/cli/commands/describe.py +107 -0
  96. dataface/cli/commands/docs.py +131 -0
  97. dataface/cli/commands/extension.py +179 -0
  98. dataface/cli/commands/init.py +240 -0
  99. dataface/cli/commands/inspect.py +94 -0
  100. dataface/cli/commands/mcp_init.py +167 -0
  101. dataface/cli/commands/query.py +386 -0
  102. dataface/cli/commands/render.py +291 -0
  103. dataface/cli/commands/schema.py +411 -0
  104. dataface/cli/commands/search.py +49 -0
  105. dataface/cli/commands/serve.py +114 -0
  106. dataface/cli/commands/skills.py +133 -0
  107. dataface/cli/commands/skills_init.py +161 -0
  108. dataface/cli/commands/validate.py +63 -0
  109. dataface/cli/main.py +1501 -0
  110. dataface/core/__init__.py +75 -0
  111. dataface/core/compile/__init__.py +244 -0
  112. dataface/core/compile/_jinja_helpers.py +78 -0
  113. dataface/core/compile/channel.py +222 -0
  114. dataface/core/compile/chart_focus.py +101 -0
  115. dataface/core/compile/chart_resolved.py +169 -0
  116. dataface/core/compile/chart_type_detection.py +489 -0
  117. dataface/core/compile/chart_update.py +261 -0
  118. dataface/core/compile/colors.py +64 -0
  119. dataface/core/compile/compiler.py +904 -0
  120. dataface/core/compile/config.py +823 -0
  121. dataface/core/compile/custom_chart_types.py +208 -0
  122. dataface/core/compile/data_table_attachment.py +1287 -0
  123. dataface/core/compile/detect.py +110 -0
  124. dataface/core/compile/errors.py +302 -0
  125. dataface/core/compile/filter_injection.py +319 -0
  126. dataface/core/compile/introspection.py +527 -0
  127. dataface/core/compile/jinja.py +511 -0
  128. dataface/core/compile/labels_env.py +52 -0
  129. dataface/core/compile/markdown.py +154 -0
  130. dataface/core/compile/meta.py +388 -0
  131. dataface/core/compile/models/__init__.py +0 -0
  132. dataface/core/compile/models/chart/__init__.py +0 -0
  133. dataface/core/compile/models/chart/authored.py +2137 -0
  134. dataface/core/compile/models/chart/compiled.py +398 -0
  135. dataface/core/compile/models/config.py +347 -0
  136. dataface/core/compile/models/face/__init__.py +0 -0
  137. dataface/core/compile/models/face/authored.py +659 -0
  138. dataface/core/compile/models/face/compiled.py +522 -0
  139. dataface/core/compile/models/factories.py +201 -0
  140. dataface/core/compile/models/markers.py +40 -0
  141. dataface/core/compile/models/palette.py +36 -0
  142. dataface/core/compile/models/primitives.py +415 -0
  143. dataface/core/compile/models/query/__init__.py +0 -0
  144. dataface/core/compile/models/query/authored.py +246 -0
  145. dataface/core/compile/models/query/compiled.py +710 -0
  146. dataface/core/compile/models/refs.py +137 -0
  147. dataface/core/compile/models/source.py +611 -0
  148. dataface/core/compile/models/style/__init__.py +0 -0
  149. dataface/core/compile/models/style/authored.py +481 -0
  150. dataface/core/compile/models/style/compiled.py +3399 -0
  151. dataface/core/compile/models/style/merged.py +1682 -0
  152. dataface/core/compile/models/theme.py +362 -0
  153. dataface/core/compile/models/variable/__init__.py +0 -0
  154. dataface/core/compile/models/variable/authored.py +254 -0
  155. dataface/core/compile/models/vega_lite/__init__.py +0 -0
  156. dataface/core/compile/models/vega_lite/config.py +510 -0
  157. dataface/core/compile/models/vega_lite/contracts.py +171 -0
  158. dataface/core/compile/normalize_charts.py +494 -0
  159. dataface/core/compile/normalize_layout.py +1000 -0
  160. dataface/core/compile/normalize_queries.py +297 -0
  161. dataface/core/compile/normalize_variables.py +489 -0
  162. dataface/core/compile/normalizer.py +543 -0
  163. dataface/core/compile/palette.py +1100 -0
  164. dataface/core/compile/parameterized.py +658 -0
  165. dataface/core/compile/parser.py +228 -0
  166. dataface/core/compile/schema.py +20 -0
  167. dataface/core/compile/schema_renderers/__init__.py +0 -0
  168. dataface/core/compile/schema_renderers/json_schema.py +163 -0
  169. dataface/core/compile/schema_renderers/prompt.py +152 -0
  170. dataface/core/compile/schema_renderers/vscode_schema.py +301 -0
  171. dataface/core/compile/sizing.py +2126 -0
  172. dataface/core/compile/sources.py +518 -0
  173. dataface/core/compile/sql_authoring_lint.py +56 -0
  174. dataface/core/compile/style_cascade.py +471 -0
  175. dataface/core/compile/typography.py +299 -0
  176. dataface/core/compile/validator.py +301 -0
  177. dataface/core/compile/variables.py +53 -0
  178. dataface/core/compile/vega_config.py +98 -0
  179. dataface/core/compile/vega_lite/__init__.py +6 -0
  180. dataface/core/compile/vega_lite/validation.py +95 -0
  181. dataface/core/compile/yaml_error_formatter.py +838 -0
  182. dataface/core/connections.py +38 -0
  183. dataface/core/dashboard.py +358 -0
  184. dataface/core/defaults/default_config.yml +101 -0
  185. dataface/core/defaults/palettes/categorical/category-10-dark.yml +32 -0
  186. dataface/core/defaults/palettes/categorical/category-10-light.yml +43 -0
  187. dataface/core/defaults/palettes/categorical/category-10.yml +31 -0
  188. dataface/core/defaults/palettes/categorical/category-6-tonal-blue.yml +22 -0
  189. dataface/core/defaults/palettes/categorical/category-6-tonal-brown.yml +29 -0
  190. dataface/core/defaults/palettes/categorical/category-6-tonal-green.yml +20 -0
  191. dataface/core/defaults/palettes/categorical/category-6-tonal-orange.yml +21 -0
  192. dataface/core/defaults/palettes/categorical/category-6-tonal-purple.yml +20 -0
  193. dataface/core/defaults/palettes/categorical/editorial-10-dark.yml +32 -0
  194. dataface/core/defaults/palettes/categorical/editorial-10.yml +40 -0
  195. dataface/core/defaults/palettes/categorical/hero-6.yml +17 -0
  196. dataface/core/defaults/palettes/categorical/single-blue.yml +11 -0
  197. dataface/core/defaults/palettes/categorical/tableau.yml +20 -0
  198. dataface/core/defaults/palettes/data/xkcd_colors.json +3803 -0
  199. dataface/core/defaults/palettes/diverging/blue-red.yml +25 -0
  200. dataface/core/defaults/palettes/diverging/coolwarm.yml +24 -0
  201. dataface/core/defaults/palettes/diverging/crimson-green.yml +23 -0
  202. dataface/core/defaults/palettes/diverging/orange-teal.yml +23 -0
  203. dataface/core/defaults/palettes/diverging/sunset.yml +24 -0
  204. dataface/core/defaults/palettes/scaffold/dft-creams.yml +38 -0
  205. dataface/core/defaults/palettes/scaffold/dft-grays.yml +53 -0
  206. dataface/core/defaults/palettes/sequential/amber.yml +22 -0
  207. dataface/core/defaults/palettes/sequential/blue.yml +22 -0
  208. dataface/core/defaults/palettes/sequential/brown.yml +22 -0
  209. dataface/core/defaults/palettes/sequential/gray.yml +22 -0
  210. dataface/core/defaults/palettes/sequential/green.yml +22 -0
  211. dataface/core/defaults/palettes/sequential/purple.yml +22 -0
  212. dataface/core/defaults/palettes/sequential/rust.yml +22 -0
  213. dataface/core/defaults/palettes/sequential/teal.yml +22 -0
  214. dataface/core/defaults/palettes/tone/negative.yml +32 -0
  215. dataface/core/defaults/palettes/tone/positive.yml +22 -0
  216. dataface/core/defaults/palettes/tone/warning.yml +22 -0
  217. dataface/core/defaults/themes/_base.yaml +786 -0
  218. dataface/core/defaults/themes/bi.yaml +16 -0
  219. dataface/core/defaults/themes/carbong100.yaml +41 -0
  220. dataface/core/defaults/themes/cream.yaml +122 -0
  221. dataface/core/defaults/themes/dark.yaml +40 -0
  222. dataface/core/defaults/themes/diagnostics-title-angle-extreme.yaml +9 -0
  223. dataface/core/defaults/themes/diagnostics-title-baseline-extreme.yaml +9 -0
  224. dataface/core/defaults/themes/diagnostics-title-baseline.yaml +24 -0
  225. dataface/core/defaults/themes/diagnostics-title-center.yaml +8 -0
  226. dataface/core/defaults/themes/diagnostics-title-color-extreme.yaml +24 -0
  227. dataface/core/defaults/themes/diagnostics-title-font-extreme.yaml +25 -0
  228. dataface/core/defaults/themes/diagnostics-title-left.yaml +8 -0
  229. dataface/core/defaults/themes/diagnostics-title-offset-extreme.yaml +9 -0
  230. dataface/core/defaults/themes/diagnostics-title-size-extreme.yaml +24 -0
  231. dataface/core/defaults/themes/diagnostics-title-weight-extreme.yaml +24 -0
  232. dataface/core/defaults/themes/editorial.yaml +147 -0
  233. dataface/core/defaults/themes/light.yaml +30 -0
  234. dataface/core/defaults/themes/looker.yaml +17 -0
  235. dataface/core/defaults/themes/stark.yaml +134 -0
  236. dataface/core/errors/__init__.py +67 -0
  237. dataface/core/errors/codes_compile.py +56 -0
  238. dataface/core/errors/codes_execute.py +177 -0
  239. dataface/core/errors/codes_render.py +106 -0
  240. dataface/core/errors/codes_unknown.py +15 -0
  241. dataface/core/errors/hints.py +74 -0
  242. dataface/core/errors/registry.py +42 -0
  243. dataface/core/errors/structured.py +92 -0
  244. dataface/core/execute/__init__.py +91 -0
  245. dataface/core/execute/adapters/__init__.py +49 -0
  246. dataface/core/execute/adapters/adapter_registry.py +400 -0
  247. dataface/core/execute/adapters/base.py +245 -0
  248. dataface/core/execute/adapters/csv_adapter.py +239 -0
  249. dataface/core/execute/adapters/dbt_adapter.py +283 -0
  250. dataface/core/execute/adapters/dbt_adapter_factory.py +212 -0
  251. dataface/core/execute/adapters/dbt_macro_loader.py +95 -0
  252. dataface/core/execute/adapters/dbt_utils.py +150 -0
  253. dataface/core/execute/adapters/http_adapter.py +224 -0
  254. dataface/core/execute/adapters/metricflow_adapter.py +94 -0
  255. dataface/core/execute/adapters/schema_resolver_adapter.py +144 -0
  256. dataface/core/execute/adapters/sql_adapter.py +710 -0
  257. dataface/core/execute/adapters/values_adapter.py +58 -0
  258. dataface/core/execute/batch.py +744 -0
  259. dataface/core/execute/cache_backend.py +135 -0
  260. dataface/core/execute/cache_keys.py +66 -0
  261. dataface/core/execute/dbt_jinja.py +21 -0
  262. dataface/core/execute/dialects/__init__.py +121 -0
  263. dataface/core/execute/dialects/athena.py +75 -0
  264. dataface/core/execute/dialects/base.py +302 -0
  265. dataface/core/execute/dialects/bigquery.py +38 -0
  266. dataface/core/execute/dialects/databricks.py +68 -0
  267. dataface/core/execute/dialects/duckdb.py +35 -0
  268. dataface/core/execute/dialects/mysql.py +68 -0
  269. dataface/core/execute/dialects/postgres.py +39 -0
  270. dataface/core/execute/dialects/redshift.py +12 -0
  271. dataface/core/execute/dialects/snowflake.py +51 -0
  272. dataface/core/execute/dialects/sqlserver.py +92 -0
  273. dataface/core/execute/duckdb_cache.py +712 -0
  274. dataface/core/execute/duckdb_config.py +26 -0
  275. dataface/core/execute/errors.py +213 -0
  276. dataface/core/execute/executor.py +1249 -0
  277. dataface/core/execute/parallel.py +162 -0
  278. dataface/core/execute/setup_sql.py +58 -0
  279. dataface/core/execute/source_registry.py +72 -0
  280. dataface/core/execute/source_resolver.py +255 -0
  281. dataface/core/execute/sql_guard.py +387 -0
  282. dataface/core/execute/sql_literals.py +199 -0
  283. dataface/core/fonts.py +52 -0
  284. dataface/core/inspect/__init__.py +32 -0
  285. dataface/core/inspect/cache_factory.py +98 -0
  286. dataface/core/inspect/db_types.py +162 -0
  287. dataface/core/inspect/dbt_schema.py +96 -0
  288. dataface/core/inspect/defaults.yml +37 -0
  289. dataface/core/inspect/fanout_risk.py +109 -0
  290. dataface/core/inspect/manifest_utils.py +77 -0
  291. dataface/core/inspect/partials/categorical.yml +40 -0
  292. dataface/core/inspect/partials/date.yml +40 -0
  293. dataface/core/inspect/partials/numeric.yml +55 -0
  294. dataface/core/inspect/partition_types.py +38 -0
  295. dataface/core/inspect/query_validator.py +975 -0
  296. dataface/core/inspect/renderer.py +354 -0
  297. dataface/core/inspect/resolver.py +808 -0
  298. dataface/core/inspect/search.py +461 -0
  299. dataface/core/inspect/sources/__init__.py +32 -0
  300. dataface/core/inspect/sources/dbt.py +738 -0
  301. dataface/core/inspect/sources/duckdb_utils.py +66 -0
  302. dataface/core/inspect/templates/__init__.py +1 -0
  303. dataface/core/inspect/templates/categorical_column.yml +196 -0
  304. dataface/core/inspect/templates/charts.yml +109 -0
  305. dataface/core/inspect/templates/date_column.yml +248 -0
  306. dataface/core/inspect/templates/model.yml +138 -0
  307. dataface/core/inspect/templates/numeric_column.yml +261 -0
  308. dataface/core/inspect/templates/quality.yml +80 -0
  309. dataface/core/inspect/templates/string_column.yml +263 -0
  310. dataface/core/project_roots.py +165 -0
  311. dataface/core/render/__init__.py +87 -0
  312. dataface/core/render/board_links.py +176 -0
  313. dataface/core/render/chart/__init__.py +27 -0
  314. dataface/core/render/chart/arc_attached_table.py +251 -0
  315. dataface/core/render/chart/artifacts.py +16 -0
  316. dataface/core/render/chart/callout.py +225 -0
  317. dataface/core/render/chart/decisions.py +358 -0
  318. dataface/core/render/chart/geo.py +700 -0
  319. dataface/core/render/chart/kpi.py +916 -0
  320. dataface/core/render/chart/labels.py +76 -0
  321. dataface/core/render/chart/pipeline.py +818 -0
  322. dataface/core/render/chart/presentation.py +36 -0
  323. dataface/core/render/chart/profile.py +3438 -0
  324. dataface/core/render/chart/render_single.py +347 -0
  325. dataface/core/render/chart/renderers.py +193 -0
  326. dataface/core/render/chart/rendering.py +565 -0
  327. dataface/core/render/chart/serialization.py +90 -0
  328. dataface/core/render/chart/spark.py +496 -0
  329. dataface/core/render/chart/spark_bar.py +370 -0
  330. dataface/core/render/chart/spec_builders.py +154 -0
  331. dataface/core/render/chart/standard_renderer.py +2645 -0
  332. dataface/core/render/chart/table.py +2957 -0
  333. dataface/core/render/chart/table_support.py +1452 -0
  334. dataface/core/render/chart/tick_values.py +66 -0
  335. dataface/core/render/chart/time_unit_detect.py +809 -0
  336. dataface/core/render/chart/title_overflow.py +157 -0
  337. dataface/core/render/chart/type_inference.py +122 -0
  338. dataface/core/render/chart/validation.py +99 -0
  339. dataface/core/render/chart/vega_lite.py +125 -0
  340. dataface/core/render/chart/vega_lite_types.py +268 -0
  341. dataface/core/render/chart/vl_field_maps.py +346 -0
  342. dataface/core/render/chart_interactivity.py +24 -0
  343. dataface/core/render/control_registry.py +287 -0
  344. dataface/core/render/converters/__init__.py +24 -0
  345. dataface/core/render/converters/chart.py +276 -0
  346. dataface/core/render/converters/html.py +98 -0
  347. dataface/core/render/converters/pdf.py +40 -0
  348. dataface/core/render/converters/png.py +41 -0
  349. dataface/core/render/errors.py +144 -0
  350. dataface/core/render/face_api.py +160 -0
  351. dataface/core/render/faces.py +1194 -0
  352. dataface/core/render/font_measurement.py +48 -0
  353. dataface/core/render/font_support.py +197 -0
  354. dataface/core/render/fonts/DFTSansTabular-Regular.ttf +0 -0
  355. dataface/core/render/fonts/DFTSansTabular-Regular.woff2 +0 -0
  356. dataface/core/render/fonts/DFTSerifOldstyleProportional-Regular.ttf +0 -0
  357. dataface/core/render/fonts/DFTSerifOldstyleTabular-Regular.ttf +0 -0
  358. dataface/core/render/fonts/InterVariable.ttf +0 -0
  359. dataface/core/render/fonts/InterVariable.woff2 +0 -0
  360. dataface/core/render/fonts/NOTO_COLOR_EMOJI_LICENSE.txt +93 -0
  361. dataface/core/render/fonts/NOTO_EMOJI_LICENSE.txt +93 -0
  362. dataface/core/render/fonts/NotoColorEmoji-Regular.ttf +0 -0
  363. dataface/core/render/fonts/NotoColorEmoji-Regular.woff2 +0 -0
  364. dataface/core/render/fonts/NotoEmoji-Regular.ttf +0 -0
  365. dataface/core/render/fonts/NotoEmoji-Regular.woff2 +0 -0
  366. dataface/core/render/fonts/SOURCE_CODE_PRO_LICENSE.txt +93 -0
  367. dataface/core/render/fonts/SOURCE_SERIF_4_LICENSE.txt +98 -0
  368. dataface/core/render/fonts/SourceCodePro-Regular.ttf +0 -0
  369. dataface/core/render/fonts/SourceSerif4-Regular.ttf +0 -0
  370. dataface/core/render/fonts/_emoji_font_face.css +43 -0
  371. dataface/core/render/fonts/source-serif-4-variable-latin.woff2 +0 -0
  372. dataface/core/render/format_utils.py +329 -0
  373. dataface/core/render/geo_defaults.yml +28 -0
  374. dataface/core/render/json_format.py +146 -0
  375. dataface/core/render/layout_sizing.py +865 -0
  376. dataface/core/render/layouts.py +541 -0
  377. dataface/core/render/markdown_defaults.yml +16 -0
  378. dataface/core/render/missing_vars_prompt.py +79 -0
  379. dataface/core/render/placeholder.py +389 -0
  380. dataface/core/render/render_result.py +14 -0
  381. dataface/core/render/renderer.py +467 -0
  382. dataface/core/render/script_embedding.py +16 -0
  383. dataface/core/render/svg_utils.py +212 -0
  384. dataface/core/render/template_loader.py +69 -0
  385. dataface/core/render/templates/controls/_styles.css +606 -0
  386. dataface/core/render/templates/controls/checkbox.html +16 -0
  387. dataface/core/render/templates/controls/date.html +16 -0
  388. dataface/core/render/templates/controls/number.html +19 -0
  389. dataface/core/render/templates/controls/readonly.html +9 -0
  390. dataface/core/render/templates/controls/select.html +21 -0
  391. dataface/core/render/templates/controls/slider.html +22 -0
  392. dataface/core/render/templates/controls/text.html +16 -0
  393. dataface/core/render/templates/scripts/chart_interactivity.js +191 -0
  394. dataface/core/render/templates/scripts/variables.js +976 -0
  395. dataface/core/render/templates/svg/grid_pattern.svg +3 -0
  396. dataface/core/render/templates/svg/styles.css +51 -0
  397. dataface/core/render/terminal.py +311 -0
  398. dataface/core/render/terminal_charts.py +563 -0
  399. dataface/core/render/terminal_defaults.yml +2 -0
  400. dataface/core/render/terminal_layouts.py +299 -0
  401. dataface/core/render/terminal_text.py +31 -0
  402. dataface/core/render/text/__init__.py +1 -0
  403. dataface/core/render/text/case.py +113 -0
  404. dataface/core/render/text_format.py +129 -0
  405. dataface/core/render/utils.py +106 -0
  406. dataface/core/render/variable_controls.py +946 -0
  407. dataface/core/render/variable_input_refinement.py +140 -0
  408. dataface/core/render/warnings/__init__.py +15 -0
  409. dataface/core/render/warnings/bar_color_1_to_1_with_x.py +80 -0
  410. dataface/core/render/warnings/base.py +44 -0
  411. dataface/core/render/warnings/fanout_risk.py +15 -0
  412. dataface/core/render/warnings/from_query_diagnostic.py +56 -0
  413. dataface/core/render/warnings/missing_join_predicate.py +13 -0
  414. dataface/core/render/warnings/query_parse_error.py +14 -0
  415. dataface/core/render/warnings/query_returned_zero_rows.py +42 -0
  416. dataface/core/render/warnings/reaggregation.py +14 -0
  417. dataface/core/render/warnings/registry.py +45 -0
  418. dataface/core/render/warnings/suppression.py +46 -0
  419. dataface/core/render/warnings/temporal_single_point.py +63 -0
  420. dataface/core/render/warnings/unreferenced_chart.py +15 -0
  421. dataface/core/render/warnings/y_encoding_mostly_null.py +76 -0
  422. dataface/core/render/yaml_format.py +167 -0
  423. dataface/core/resolve_face.py +195 -0
  424. dataface/core/schema/__init__.py +0 -0
  425. dataface/core/schema/guidance.py +151 -0
  426. dataface/core/scoped_paths.py +59 -0
  427. dataface/core/serve/__init__.py +14 -0
  428. dataface/core/serve/bootstrap.py +39 -0
  429. dataface/core/serve/embedded.py +57 -0
  430. dataface/core/serve/port.py +129 -0
  431. dataface/core/serve/server.py +938 -0
  432. dataface/core/serve/templates/__init__.py +0 -0
  433. dataface/core/serve/templates/directory.yml +6 -0
  434. dataface/core/serve/templates/error.html.j2 +217 -0
  435. dataface/core/utils.py +121 -0
  436. dataface/core/validate.py +64 -0
  437. dataface/integrations/__init__.py +0 -0
  438. dataface/integrations/highlighting.py +351 -0
  439. dataface/integrations/markdown.py +537 -0
  440. dataface/py.typed +0 -0
  441. dataface-0.1.2.dist-info/METADATA +375 -0
  442. dataface-0.1.2.dist-info/RECORD +455 -0
  443. dataface-0.1.2.dist-info/WHEEL +4 -0
  444. dataface-0.1.2.dist-info/entry_points.txt +2 -0
  445. dataface-0.1.2.dist-info/licenses/LICENSE +202 -0
  446. mdsvg/__init__.py +168 -0
  447. mdsvg/fonts.py +656 -0
  448. mdsvg/images.py +299 -0
  449. mdsvg/parser.py +629 -0
  450. mdsvg/playground.py +284 -0
  451. mdsvg/py.typed +2 -0
  452. mdsvg/renderer.py +1623 -0
  453. mdsvg/style.py +355 -0
  454. mdsvg/types.py +200 -0
  455. mdsvg/utils.py +86 -0
@@ -0,0 +1,398 @@
1
+ """Compiled chart types: Chart, ChartDependencies, is_chart.
2
+
3
+ Stage: COMPILE (Output)
4
+ Purpose: Define the compiled Chart type (output of compilation, input to execute/render)
5
+ and its dependency tracker.
6
+ """
7
+
8
+ from __future__ import annotations
9
+
10
+ from dataclasses import dataclass, field
11
+ from typing import Any, TypeGuard
12
+
13
+ from pydantic import BaseModel, ConfigDict, Field, field_validator
14
+
15
+ from dataface.core.compile.custom_chart_types import BUILTIN_CHART_TYPE_VALUES
16
+ from dataface.core.compile.models.chart.authored import (
17
+ ChartDataTable,
18
+ ChartLabels,
19
+ ChartSort,
20
+ ChartTotal,
21
+ FieldConditionalFormatting,
22
+ FilterDef,
23
+ KpiSupportConfig,
24
+ Layer,
25
+ )
26
+ from dataface.core.compile.models.primitives import FormatConfig
27
+ from dataface.core.compile.models.query.compiled import AnyQuery
28
+ from dataface.core.compile.models.style.authored import ChartStylePatch
29
+ from dataface.core.compile.models.vega_lite.contracts import Projection
30
+
31
+ # ============================================================================
32
+ # CHART TYPE SETS
33
+ # ============================================================================
34
+
35
+ # SVG-family chart types that use hand-crafted SVG renderers instead of Vega-Lite.
36
+ # Used for renderer-family classification and to exclude these types from:
37
+ # - aspect-ratio-driven sizing (they don't use width/aspect_ratio for height)
38
+ # - Vega render-first sizing (not Vega charts)
39
+ # - cols height alignment re-renders (non-Vega, don't benefit from re-render)
40
+ # Each renderer owns its own sizing contract — there is no shared fixed height for this group.
41
+ NON_ASPECT_RATIO_TYPES = frozenset({"table", "kpi", "spark_bar", "callout"})
42
+ SVG_LAYOUT_PADDED_TYPES = frozenset({"table", "kpi", "spark_bar"})
43
+
44
+ # ============================================================================
45
+ # DEPENDENCY TRACKING
46
+ # ============================================================================
47
+
48
+
49
+ @dataclass(frozen=True)
50
+ class ChartDependencies:
51
+ """Dependencies required by a chart for rendering.
52
+
53
+ Tracks all sources, variables, and queries that a chart needs.
54
+ Used for extracting minimal preview faces.
55
+ """
56
+
57
+ sources: frozenset[str] = field(default_factory=frozenset)
58
+ variables: frozenset[str] = field(default_factory=frozenset)
59
+ queries: frozenset[str] = field(default_factory=frozenset)
60
+
61
+
62
+ # ============================================================================
63
+ # COMPILED CHART
64
+ # ============================================================================
65
+
66
+
67
+ class Chart(BaseModel):
68
+ """Compiled chart ready for execution and rendering.
69
+
70
+ All data-mapping, geo, interaction, and compiled-specific fields
71
+ declared directly on this model (no shared base with authored patches).
72
+ """
73
+
74
+ model_config = ConfigDict(extra="forbid")
75
+
76
+ # --- Identity ---
77
+ id: str = Field(description="Unique identifier within the dashboard.")
78
+ query: AnyQuery | None = Field(
79
+ default=None,
80
+ description="Resolved query object (SqlQuery, CsvQuery, etc.). None for blank/placeholder charts.",
81
+ )
82
+ query_name: str | None = Field(
83
+ default=None,
84
+ description="String name for executor lookup. None for blank/placeholder charts.",
85
+ )
86
+ type: str = Field(description="Chart type (line, bar, table, kpi, etc.).")
87
+
88
+ @field_validator("type", mode="before")
89
+ @classmethod
90
+ def _validate_chart_type(cls, v: object) -> str:
91
+ from dataface.core.compile.custom_chart_types import (
92
+ _NAME_RE as _CHART_CUSTOM_NAME_RE,
93
+ )
94
+
95
+ if not isinstance(v, str):
96
+ raise ValueError(f"chart type must be a string, got {type(v).__name__}")
97
+ if v in BUILTIN_CHART_TYPE_VALUES:
98
+ return v
99
+ if _CHART_CUSTOM_NAME_RE.match(v): # custom chart type name
100
+ return v
101
+ raise ValueError(
102
+ f"Unknown chart type {v!r}. Must be a known chart type or a valid "
103
+ f"custom type name (lowercase letters, digits, and underscores)."
104
+ )
105
+
106
+ title: str = Field(
107
+ default="", description="Display title. Empty string if not provided."
108
+ )
109
+ subtitle: str = Field(
110
+ default="", description="Secondary title line. Empty string if not provided."
111
+ )
112
+ description: str = Field(
113
+ default="", description="Description text. Empty string if not provided."
114
+ )
115
+ label: str = Field(
116
+ default="",
117
+ description="KPI label rendered above the headline value. Empty for non-KPI.",
118
+ )
119
+
120
+ # Styling — typed chart-local style patch
121
+ style: ChartStylePatch | None = Field(
122
+ default=None,
123
+ description="Chart-local style patch (orientation, columns, spark-bar overrides, etc.).",
124
+ )
125
+
126
+ # Variable dependencies - computed during normalization
127
+ variable_dependencies: set[str] = Field(
128
+ default_factory=set,
129
+ description="Variable names this chart depends on (from title, filters, query SQL).",
130
+ )
131
+
132
+ # Source location in YAML for edit-back support
133
+ source_path: str | None = Field(
134
+ default=None,
135
+ description="YAML path for edit-back support (e.g., 'charts.revenue', 'rows[0]').",
136
+ )
137
+
138
+ # Whether the query is inline (defined in chart) vs named (reference)
139
+ query_is_inline: bool = Field(
140
+ default=False,
141
+ description="True if query is defined inline in chart; False if it's a named reference.",
142
+ )
143
+
144
+ # --- Data mapping fields ---
145
+ x: str | None = Field(
146
+ default=None, description="X-axis field name from the query result."
147
+ )
148
+ y: str | list[str] | None = Field(
149
+ default=None,
150
+ description="Y-axis field name(s). Accepts a single field or list for multi-series charts.",
151
+ )
152
+ color: str | None = Field(
153
+ default=None, description="Color data channel: bare field name only."
154
+ )
155
+ size: str | None = Field(
156
+ default=None,
157
+ description="Field used to size-encode data points (quantitative).",
158
+ )
159
+ shape: str | None = Field(
160
+ default=None,
161
+ description="Field used to shape-encode data points (categorical).",
162
+ )
163
+ theta: str | None = Field(
164
+ default=None, description="Field for angular encoding in pie (arc) charts."
165
+ )
166
+ total: ChartTotal | None = Field(
167
+ default=None, description="Donut center total config."
168
+ )
169
+ labels: ChartLabels | None = Field(
170
+ default=None, description="Per-row text annotations near each data anchor."
171
+ )
172
+ x_label: str | None = Field(
173
+ default=None, description="Custom label for the X axis."
174
+ )
175
+ y_label: str | None = Field(
176
+ default=None, description="Custom label for the Y axis."
177
+ )
178
+ format: str | FormatConfig | None = Field(
179
+ default=None,
180
+ description="Number format: D3 format string, preset name, or FormatConfig object.",
181
+ )
182
+ message: str | None = Field(
183
+ default=None,
184
+ description="Static error message content for explicit error charts.",
185
+ )
186
+ geo: str | dict[str, Any] | None = Field(
187
+ default=None,
188
+ description="GeoJSON field name or inline GeoJSON spec for geoshape charts.",
189
+ )
190
+ geo_source: str | None = Field(
191
+ default=None,
192
+ description="Named geographic data source for loading GeoJSON boundaries.",
193
+ )
194
+ lookup: str | None = Field(
195
+ default=None,
196
+ description="Data field to join against the geographic data (map join key).",
197
+ )
198
+ value: str | None = Field(
199
+ default=None,
200
+ description="For map: data field mapped to the fill color. For KPI: column reference for the headline number/text.",
201
+ )
202
+ support: KpiSupportConfig | None = Field(
203
+ default=None, description="Optional support line beneath the KPI value."
204
+ )
205
+ projection: str | Projection | None = Field(
206
+ default=None, description="Map projection name or Vega-Lite projection config."
207
+ )
208
+ latitude: str | None = Field(
209
+ default=None,
210
+ description="Field containing latitude values for point/bubble maps.",
211
+ )
212
+ longitude: str | None = Field(
213
+ default=None,
214
+ description="Field containing longitude values for point/bubble maps.",
215
+ )
216
+ basemap: dict[str, Any] | None = Field(
217
+ default=None,
218
+ description="Tile-layer configuration for point_map / bubble_map charts.",
219
+ )
220
+ sort: ChartSort | None = Field(
221
+ default=None,
222
+ description="Sort configuration: field to sort by and direction (asc/desc).",
223
+ )
224
+ stack: bool | str | None = Field(
225
+ default=None, description="Stack mode for marks that stack by default."
226
+ )
227
+ link: str | None = Field(
228
+ default=None, description="Click-through URL template for drill-down links."
229
+ )
230
+ filters: dict[str, FilterDef] | None = Field(
231
+ default=None,
232
+ description="Declarative column filters applied to chart data after query execution.",
233
+ )
234
+ layers: list[Layer] | None = Field(
235
+ default=None, description="Layers for multi-mark charts (layered type)."
236
+ )
237
+ x_domain: str | None = Field(
238
+ default=None,
239
+ description="Controls how x-values from multiple layer queries are combined on the shared x-axis.",
240
+ )
241
+ conditional_formatting: dict[str, FieldConditionalFormatting] | None = Field(
242
+ default=None,
243
+ description="Discrete rule-driven style overrides indexed by column name.",
244
+ )
245
+ data_table: ChartDataTable | None = Field(
246
+ default=None, description="Optional mini data-grid attached to the chart."
247
+ )
248
+ # Box geometry — set at chart root in the authored surface for cartesian charts.
249
+ # aspect_ratio, min_height, max_height are promoted from per-chart style during normalization.
250
+ height: int | float | None = Field(
251
+ default=None,
252
+ description="Explicit chart height in pixels. None defers to aspect_ratio or theme.",
253
+ )
254
+ width: int | float | None = Field(
255
+ default=None,
256
+ description=(
257
+ "Chart width hint in pixels. Feeds the label-overlap heuristic. "
258
+ "None falls back to the chart rendering config default_width."
259
+ ),
260
+ )
261
+ aspect_ratio: float | None = Field(
262
+ default=None,
263
+ description="Chart aspect ratio (width / height). Used when height is not set. Promoted from per-chart style at compile time.",
264
+ )
265
+ min_height: float | None = Field(
266
+ default=None,
267
+ description=(
268
+ "Per-chart minimum height in pixels for aspect-ratio-derived sizing. "
269
+ "Overrides face/theme style.charts.min_height for this chart. "
270
+ "Has no effect when chart.height is set. Promoted from per-chart style at compile time."
271
+ ),
272
+ )
273
+ max_height: float | None = Field(
274
+ default=None,
275
+ description=(
276
+ "Per-chart maximum height in pixels for aspect-ratio-derived sizing. "
277
+ "Overrides face/theme style.charts.max_height for this chart. "
278
+ "Has no effect when chart.height is set. Promoted from per-chart style at compile time."
279
+ ),
280
+ )
281
+ warnings_ignore: list[str] = Field(
282
+ default_factory=list,
283
+ description="Codes of render warnings to suppress for this chart.",
284
+ )
285
+
286
+ def to_dict(self) -> dict[str, Any]:
287
+ """Convert chart to YAML-compatible dict."""
288
+ from dataface.core.render.chart.presentation import to_plain_dict
289
+
290
+ result: dict[str, Any] = {}
291
+
292
+ if self.title:
293
+ result["title"] = self.title
294
+ if self.label:
295
+ result["label"] = self.label
296
+ if self.type:
297
+ result["type"] = self.type
298
+
299
+ if self.query:
300
+ query_dict: dict[str, Any] = {}
301
+ if hasattr(self.query, "sql") and self.query.sql:
302
+ query_dict["sql"] = self.query.sql
303
+ if (
304
+ hasattr(self.query, "source")
305
+ and self.query.source
306
+ and isinstance(self.query.source, str)
307
+ ):
308
+ query_dict["source"] = self.query.source
309
+ if hasattr(self.query, "file") and self.query.file:
310
+ query_dict["file"] = self.query.file
311
+ if query_dict:
312
+ result["query"] = query_dict
313
+
314
+ if self.x:
315
+ result["x"] = self.x
316
+ if self.y:
317
+ result["y"] = self.y
318
+ if self.color:
319
+ result["color"] = self.color
320
+ if self.size:
321
+ result["size"] = self.size
322
+ if self.shape:
323
+ result["shape"] = self.shape
324
+ if self.theta:
325
+ result["theta"] = self.theta
326
+ if self.format:
327
+ if hasattr(self.format, "model_dump"):
328
+ result["format"] = self.format.model_dump(exclude_none=True)
329
+ else:
330
+ result["format"] = self.format
331
+ if self.message:
332
+ result["message"] = self.message
333
+
334
+ if self.geo:
335
+ result["geo"] = self.geo
336
+ if self.geo_source:
337
+ result["geo_source"] = self.geo_source
338
+ if self.lookup:
339
+ result["lookup"] = self.lookup
340
+ if self.value is not None:
341
+ result["value"] = self.value
342
+ if self.support is not None:
343
+ result["support"] = self.support.model_dump(exclude_none=True)
344
+ if self.projection:
345
+ result["projection"] = (
346
+ self.projection
347
+ if isinstance(self.projection, str)
348
+ else to_plain_dict(self.projection)
349
+ )
350
+ if self.latitude:
351
+ result["latitude"] = self.latitude
352
+ if self.longitude:
353
+ result["longitude"] = self.longitude
354
+ if self.basemap:
355
+ result["basemap"] = self.basemap
356
+ if self.sort:
357
+ result["sort"] = self.sort.model_dump(exclude_none=True)
358
+
359
+ if self.style:
360
+ result["style"] = self.style.model_dump(exclude_none=True)
361
+
362
+ if self.link:
363
+ result["link"] = self.link
364
+
365
+ if self.filters:
366
+ result["filters"] = {
367
+ col: fd.to_yaml_form() for col, fd in self.filters.items()
368
+ }
369
+
370
+ return result
371
+
372
+ def get_dependencies(self) -> ChartDependencies:
373
+ """Get all dependencies required to render this chart."""
374
+ variables: set[str] = self.variable_dependencies.copy()
375
+ if self.query and hasattr(self.query, "variable_dependencies"):
376
+ variables |= self.query.variable_dependencies
377
+
378
+ sources: set[str] = set()
379
+ if self.query:
380
+ source = getattr(self.query, "source", None)
381
+ if isinstance(source, str):
382
+ sources.add(source)
383
+
384
+ return ChartDependencies(
385
+ sources=frozenset(sources),
386
+ variables=frozenset(variables),
387
+ queries=frozenset(),
388
+ )
389
+
390
+
391
+ # ============================================================================
392
+ # TYPE GUARD
393
+ # ============================================================================
394
+
395
+
396
+ def is_chart(item: Any) -> TypeGuard[Chart]:
397
+ """Type guard for Chart."""
398
+ return isinstance(item, Chart)