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,510 @@
1
+ """Hand-owned VegaLiteConfig surface contract.
2
+
3
+ Stage: COMPILE
4
+ Purpose: Define the explicit set of Vega-Lite config fields Dataface supports.
5
+
6
+ DESIGN DECISIONS
7
+ ================
8
+
9
+ 1. CLOSED CONTRACT — NO PASS-THROUGH
10
+ ----------------------------------
11
+ Unlike ThemeConfig (which uses extra="allow"), VegaLiteConfig rejects
12
+ unknown fields. Every supported field is explicitly declared.
13
+
14
+ This is the starting contract for the new chart style architecture.
15
+ If a new Vega-Lite field needs support, add it here with a comment
16
+ explaining whether it is:
17
+ - SHIPPED: already present in a built-in default, theme, or style preset
18
+ - COMMON: intentionally added as a common high-value option
19
+
20
+ 2. DERIVATION
21
+ ----------
22
+ This model was derived by auditing every Vega-facing field emitted by
23
+ style_to_vega_lite() across the production themes/*.yaml set.
24
+
25
+ See test_vegalite_config_surface.py for the contract test that compiles
26
+ every shipped theme through style_to_vega_lite() and asserts the output
27
+ validates against this model.
28
+
29
+ 3. COMMON ADDITIONS
30
+ ----------------
31
+ Beyond what is already shipped, the following fields were intentionally
32
+ added because they are high-value options users commonly need:
33
+
34
+ Top-level:
35
+ - numberFormat, timeFormat — common global format overrides
36
+
37
+ Mark configs:
38
+ - color — shorthand for fill/stroke depending on mark type
39
+ - cursor — pointer cursor for interactive marks
40
+ - tooltip — mark-level tooltip toggle
41
+
42
+ View:
43
+ - strokeWidth — view border width
44
+ - cornerRadius — rounded view corners
45
+
46
+ Header:
47
+ - labelFontSize, titleFontSize — facet header sizing
48
+ - labelColor, titleColor — facet header colors
49
+ - labelFont, titleFont — facet header fonts
50
+
51
+ 4. RELATIONSHIP TO ThemeConfig
52
+ ---------------------------
53
+ ThemeConfig in models/theme.py is the runtime type for theme loading.
54
+ Its top-level extra="allow" lets users write arbitrary Vega-Lite keys
55
+ (axisBand, headerRow, etc.) that flow to the rendered spec via
56
+ to_vega_config(). The named nested fields (axis, view, legend, title,
57
+ range, mark-type configs) use the closed types from this module — unknown
58
+ fields inside those sections are rejected at validation.
59
+
60
+ Dependencies:
61
+ - pydantic (BaseModel, ConfigDict)
62
+
63
+ See also:
64
+ - models/theme.py: Runtime theme types
65
+ - test_vegalite_config_surface.py: Contract enforcement tests
66
+ - defaults/themes/*.yaml: Shipped surface (compiled via style_to_vega_lite)
67
+ """
68
+
69
+ from __future__ import annotations
70
+
71
+ from pydantic import BaseModel, ConfigDict
72
+
73
+ # =============================================================================
74
+ # AXIS CONFIG
75
+ # =============================================================================
76
+
77
+
78
+ class AxisConfig(BaseModel):
79
+ """Vega-Lite axis configuration.
80
+
81
+ Used by ThemeConfig.axis for raw VL passthrough in theme YAML.
82
+ Not part of the VegaLiteConfig closed contract — axis style is emitted at
83
+ encoding level by profile.py:_build_encoding_axis via AxisStyle/ScaleStyle.
84
+
85
+ Ref: https://vega.github.io/vega-lite/docs/axis.html
86
+ """
87
+
88
+ model_config = ConfigDict(extra="forbid")
89
+
90
+ # Domain
91
+ domain: bool | None = None
92
+ domainColor: str | None = None
93
+ domainWidth: float | None = None
94
+
95
+ # Grid
96
+ grid: bool | None = None
97
+ gridColor: str | None = None
98
+ gridDash: list[float] | None = None
99
+ gridOpacity: float | None = None
100
+ gridWidth: float | None = None
101
+
102
+ # Labels
103
+ labelColor: str | None = None
104
+ labelFont: str | None = None
105
+ labelFontSize: float | None = None
106
+ labelFontWeight: str | float | None = None
107
+ labelPadding: float | None = None
108
+ labelExpr: str | None = None
109
+ labelAngle: float | None = None
110
+ labelAlign: str | None = None
111
+ labelBaseline: str | None = None
112
+ labelOverlap: bool | str | None = None
113
+ labelSeparation: float | None = None
114
+ labelFlush: bool | float | None = None
115
+ labels: bool | None = None
116
+ labelLimit: float | None = None
117
+ labelBound: bool | float | None = None
118
+ labelOffset: float | None = None
119
+ labelLineHeight: float | None = None
120
+ labelAnchor: str | None = None
121
+
122
+ # Ticks
123
+ ticks: bool | None = None
124
+ tickColor: str | None = None
125
+ tickSize: float | None = None
126
+ tickWidth: float | None = None
127
+ tickCount: float | dict | None = None
128
+ tickExtra: bool | None = None
129
+
130
+ # Title
131
+ titleColor: str | None = None
132
+ titleFont: str | None = None
133
+ titleFontSize: float | None = None
134
+ titleFontWeight: str | float | None = None
135
+ titlePadding: float | None = None
136
+ titleAlign: str | None = None
137
+ titleAngle: float | None = None
138
+ titleX: float | None = None
139
+ titleY: float | None = None
140
+
141
+ # Orientation / layout
142
+ orient: str | None = None
143
+ maxExtent: float | None = None
144
+ minExtent: float | None = None
145
+ bandPosition: float | None = None
146
+ offset: float | None = None
147
+
148
+ # COMMON additions
149
+ format: str | None = None
150
+ values: list | None = None
151
+
152
+
153
+ # =============================================================================
154
+ # LEGEND CONFIG
155
+ # =============================================================================
156
+
157
+
158
+ class LegendConfig(BaseModel):
159
+ """Vega-Lite legend configuration.
160
+
161
+ Used by ThemeConfig.legend for raw VL passthrough in theme YAML.
162
+ Not part of the VegaLiteConfig closed contract — legend style is emitted at
163
+ encoding level by profile.py:_build_encoding_legend via LegendStyle.
164
+
165
+ Ref: https://vega.github.io/vega-lite/docs/legend.html
166
+ """
167
+
168
+ model_config = ConfigDict(extra="forbid")
169
+
170
+ # Labels
171
+ labelColor: str | None = None
172
+ labelFont: str | None = None
173
+ labelFontSize: float | None = None
174
+ labelFontWeight: str | float | None = None
175
+ labelBaseline: str | None = None
176
+
177
+ # Title
178
+ titleColor: str | None = None
179
+ titleFont: str | None = None
180
+ titleFontSize: float | None = None
181
+ titleFontWeight: str | float | None = None
182
+ titlePadding: float | None = None
183
+
184
+ # Layout
185
+ orient: str | None = None
186
+ direction: str | None = None
187
+ columns: int | None = None
188
+ offset: float | None = None
189
+ padding: float | None = None
190
+
191
+ # Symbols
192
+ symbolSize: float | None = None
193
+ symbolType: str | None = None
194
+ symbolStrokeColor: str | None = None
195
+ symbolShape: str | None = None # COMMON
196
+
197
+ # COMMON additions
198
+ disable: bool | None = None
199
+ gradientLength: float | None = None
200
+ gradientThickness: float | None = None
201
+ clipHeight: float | None = None
202
+
203
+
204
+ # =============================================================================
205
+ # TITLE CONFIG
206
+ # =============================================================================
207
+
208
+
209
+ class TitleConfig(BaseModel):
210
+ """Vega-Lite title configuration.
211
+
212
+ Ref: https://vega.github.io/vega-lite/docs/title.html
213
+ """
214
+
215
+ model_config = ConfigDict(extra="forbid")
216
+
217
+ color: str | None = None
218
+ font: str | None = None
219
+ fontSize: float | None = None
220
+ fontWeight: str | float | None = None
221
+ anchor: str | None = None
222
+ offset: float | None = None
223
+ angle: float | None = None
224
+ baseline: str | None = None
225
+ subtitleColor: str | None = None
226
+ subtitleFont: str | None = None
227
+ subtitleFontSize: float | None = None
228
+ subtitleFontWeight: str | float | None = None
229
+ subtitlePadding: float | None = None
230
+
231
+
232
+ # =============================================================================
233
+ # VIEW CONFIG
234
+ # =============================================================================
235
+
236
+
237
+ class ViewConfig(BaseModel):
238
+ """Vega-Lite view configuration.
239
+
240
+ Ref: https://vega.github.io/vega-lite/docs/spec.html#config
241
+ """
242
+
243
+ model_config = ConfigDict(extra="forbid")
244
+
245
+ fill: str | None = None
246
+ stroke: str | None = None
247
+ strokeWidth: float | None = None # COMMON
248
+ continuousWidth: float | None = None
249
+ continuousHeight: float | None = None
250
+ discreteWidth: float | None = None
251
+ discreteHeight: float | None = None
252
+ cornerRadius: float | None = None # COMMON
253
+
254
+
255
+ # =============================================================================
256
+ # RANGE CONFIG
257
+ # =============================================================================
258
+
259
+
260
+ class RangeConfig(BaseModel):
261
+ """Vega-Lite scale range configuration.
262
+
263
+ Ref: https://vega.github.io/vega-lite/docs/scale.html#range-config
264
+ """
265
+
266
+ model_config = ConfigDict(extra="forbid")
267
+
268
+ category: list[str] | None = None
269
+ diverging: list[str] | None = None
270
+ heatmap: list[str] | None = None
271
+ ramp: list[str] | None = None
272
+
273
+
274
+ # =============================================================================
275
+ # MARK CONFIG
276
+ # =============================================================================
277
+
278
+
279
+ class MarkConfig(BaseModel):
280
+ """Vega-Lite mark configuration.
281
+
282
+ Used for per-mark-type config sections: bar, line, area, arc, point,
283
+ rect, tick, circle, geoshape, image, rule, square, text, trail, symbol,
284
+ shape, path.
285
+
286
+ Ref: https://vega.github.io/vega-lite/docs/mark.html#config
287
+ """
288
+
289
+ model_config = ConfigDict(extra="forbid")
290
+
291
+ # Core visual
292
+ fill: str | None = None
293
+ stroke: str | None = None
294
+ strokeWidth: float | None = None
295
+ strokeCap: str | None = None
296
+ strokeJoin: str | None = None
297
+ color: str | None = None # COMMON: shorthand for fill/stroke
298
+ opacity: float | None = None
299
+ size: float | None = None
300
+ filled: bool | None = None
301
+
302
+ # Shape / interpolation
303
+ shape: str | None = None
304
+ interpolate: str | None = None
305
+
306
+ # Geometry
307
+ cornerRadius: float | None = None
308
+ cornerRadiusTopLeft: float | None = None
309
+ cornerRadiusTopRight: float | None = None
310
+ cornerRadiusEnd: float | None = None
311
+ innerRadius: float | None = None
312
+ padAngle: float | None = None
313
+ binSpacing: float | None = None
314
+ continuousBandSize: float | None = None
315
+ discreteBandSize: float | None = None
316
+
317
+ # Line-specific
318
+ point: bool | None = None
319
+ line: bool | None = None
320
+
321
+ # Text-specific
322
+ align: str | None = None
323
+ font: str | None = None
324
+ fontSize: float | None = None
325
+ fontWeight: str | float | None = None
326
+ limit: float | None = None
327
+ lineHeight: float | None = None
328
+
329
+ # Image-specific
330
+ aspect: bool | None = None
331
+
332
+ # Interaction
333
+ tooltip: bool | None = None
334
+ cursor: str | None = None # COMMON
335
+
336
+
337
+ # =============================================================================
338
+ # COMPOSITION CONFIG
339
+ # =============================================================================
340
+
341
+
342
+ class CompositionConfig(BaseModel):
343
+ """Facet/concat composition configuration.
344
+
345
+ Ref: https://vega.github.io/vega-lite/docs/facet.html
346
+ """
347
+
348
+ model_config = ConfigDict(extra="forbid")
349
+
350
+ spacing: float | None = None
351
+ columns: int | None = None
352
+
353
+
354
+ class HeaderConfig(BaseModel):
355
+ """Facet header configuration.
356
+
357
+ Ref: https://vega.github.io/vega-lite/docs/header.html
358
+ """
359
+
360
+ model_config = ConfigDict(extra="forbid")
361
+
362
+ labelOrient: str | None = None
363
+ labelPadding: float | None = None
364
+ labelFontSize: float | None = None # COMMON
365
+ labelColor: str | None = None # COMMON
366
+ labelFont: str | None = None # COMMON
367
+ titleOrient: str | None = None
368
+ titlePadding: float | None = None
369
+ titleFontSize: float | None = None # COMMON
370
+ titleColor: str | None = None # COMMON
371
+ titleFont: str | None = None # COMMON
372
+
373
+
374
+ # =============================================================================
375
+ # GROUP CONFIG
376
+ # =============================================================================
377
+
378
+
379
+ class GroupConfig(BaseModel):
380
+ """Vega-Lite group mark configuration."""
381
+
382
+ model_config = ConfigDict(extra="forbid")
383
+
384
+ fill: str | None = None
385
+
386
+
387
+ # =============================================================================
388
+ # AUTOSIZE CONFIG
389
+ # =============================================================================
390
+
391
+
392
+ class AutosizeConfig(BaseModel):
393
+ """Vega-Lite autosize configuration.
394
+
395
+ Ref: https://vega.github.io/vega-lite/docs/size.html#autosize
396
+ """
397
+
398
+ model_config = ConfigDict(extra="forbid")
399
+
400
+ type: str | None = None
401
+ contains: str | None = None
402
+ resize: bool | None = None
403
+
404
+
405
+ class PaddingConfig(BaseModel):
406
+ """Vega-Lite directional padding configuration."""
407
+
408
+ model_config = ConfigDict(extra="forbid")
409
+
410
+ top: float | None = None
411
+ right: float | None = None
412
+ bottom: float | None = None
413
+ left: float | None = None
414
+
415
+
416
+ # =============================================================================
417
+ # MARK (top-level) CONFIG
418
+ # =============================================================================
419
+
420
+
421
+ class TopLevelMarkConfig(BaseModel):
422
+ """Top-level mark config (the `mark` key in config, not mark-type sections)."""
423
+
424
+ model_config = ConfigDict(extra="forbid")
425
+
426
+ tooltip: bool | None = None
427
+
428
+
429
+ # =============================================================================
430
+ # MAIN VEGA-LITE CONFIG
431
+ # =============================================================================
432
+
433
+
434
+ class VegaLiteConfig(BaseModel):
435
+ """Hand-owned VegaLiteConfig surface contract.
436
+
437
+ This model defines every Vega-Lite config field Dataface explicitly
438
+ supports. It is a CLOSED contract — unknown fields are rejected.
439
+
440
+ Field provenance:
441
+ - SHIPPED: present in at least one built-in default, theme, or style preset
442
+ - COMMON: intentionally added as a high-value option not yet in presets
443
+
444
+ To add a new field:
445
+ 1. Add it to the appropriate nested config class
446
+ 2. Comment it with SHIPPED or COMMON and justification
447
+ 3. Run test_vegalite_config_surface.py to verify coverage
448
+ """
449
+
450
+ model_config = ConfigDict(extra="forbid")
451
+
452
+ # -------------------------------------------------------------------------
453
+ # Top-level config
454
+ # -------------------------------------------------------------------------
455
+ background: str | None = None
456
+ font: str | None = None
457
+ padding: float | PaddingConfig | None = None
458
+
459
+ # COMMON: global number/time formatting
460
+ numberFormat: str | None = None
461
+ timeFormat: str | None = None
462
+
463
+ # -------------------------------------------------------------------------
464
+ # Autosize
465
+ # -------------------------------------------------------------------------
466
+ autosize: AutosizeConfig | None = None
467
+
468
+ # -------------------------------------------------------------------------
469
+ # Top-level mark config
470
+ # -------------------------------------------------------------------------
471
+ mark: TopLevelMarkConfig | None = None
472
+
473
+ # -------------------------------------------------------------------------
474
+ # Title, view
475
+ # -------------------------------------------------------------------------
476
+ title: TitleConfig | None = None
477
+ view: ViewConfig | None = None
478
+
479
+ # -------------------------------------------------------------------------
480
+ # Range
481
+ # -------------------------------------------------------------------------
482
+ range: RangeConfig | None = None
483
+
484
+ # -------------------------------------------------------------------------
485
+ # Mark-type configs (generic marks emitted by style_to_vega_lite)
486
+ # bar/line/area/arc/point: emitted at spec.mark level — not here.
487
+ # geoshape/image: no emit path in style_to_vega_lite — not here.
488
+ # -------------------------------------------------------------------------
489
+ rect: MarkConfig | None = None
490
+ tick: MarkConfig | None = None
491
+ circle: MarkConfig | None = None
492
+ rule: MarkConfig | None = None
493
+ square: MarkConfig | None = None
494
+ text: MarkConfig | None = None
495
+ trail: MarkConfig | None = None
496
+ symbol: MarkConfig | None = None
497
+ shape: MarkConfig | None = None
498
+ path: MarkConfig | None = None
499
+
500
+ # -------------------------------------------------------------------------
501
+ # Composition
502
+ # -------------------------------------------------------------------------
503
+ facet: CompositionConfig | None = None
504
+ concat: CompositionConfig | None = None
505
+ header: HeaderConfig | None = None
506
+
507
+ # -------------------------------------------------------------------------
508
+ # Group
509
+ # -------------------------------------------------------------------------
510
+ group: GroupConfig | None = None
@@ -0,0 +1,171 @@
1
+ """Hand-owned Vega-Lite contracts for Dataface.
2
+
3
+ Replaces the auto-generated 458-model Pydantic tree with a small set of
4
+ structural contracts that Dataface actually needs. Every model uses
5
+ ``extra="allow"`` so unknown Vega-Lite properties pass through without
6
+ error — the contracts enforce *shape*, not exhaustive field-level typing.
7
+
8
+ The validation layer (``validation.py``) uses these contracts via
9
+ ``TypeAdapter`` to catch gross structural mistakes (wrong top-level keys,
10
+ missing mark type, etc.) while letting Vega-Lite own the full property
11
+ semantics at render time.
12
+ """
13
+
14
+ from __future__ import annotations
15
+
16
+ from typing import Any, Literal
17
+
18
+ from pydantic import BaseModel, ConfigDict, Field
19
+
20
+ # ---------------------------------------------------------------------------
21
+ # Base
22
+ # ---------------------------------------------------------------------------
23
+
24
+
25
+ class VegaLiteBaseModel(BaseModel):
26
+ """Base for all hand-owned Vega-Lite contracts.
27
+
28
+ ``extra="allow"`` lets any Vega-Lite property pass through — we
29
+ validate shape, not every field.
30
+ """
31
+
32
+ model_config = ConfigDict(extra="allow", populate_by_name=True)
33
+
34
+
35
+ # ---------------------------------------------------------------------------
36
+ # Mark types
37
+ # ---------------------------------------------------------------------------
38
+
39
+ Mark = Literal[
40
+ "arc",
41
+ "area",
42
+ "bar",
43
+ "boxplot",
44
+ "circle",
45
+ "errorband",
46
+ "errorbar",
47
+ "geoshape",
48
+ "image",
49
+ "line",
50
+ "point",
51
+ "rect",
52
+ "rule",
53
+ "square",
54
+ "text",
55
+ "tick",
56
+ "trail",
57
+ ]
58
+ """Valid Vega-Lite mark type strings (primitive + composite)."""
59
+
60
+
61
+ # ---------------------------------------------------------------------------
62
+ # Encoding / VLConfig / Scale / Axis / Projection
63
+ # ---------------------------------------------------------------------------
64
+
65
+
66
+ class VLConfig(VegaLiteBaseModel):
67
+ """Structural contract for Vega-Lite top-level config."""
68
+
69
+
70
+ class Scale(VegaLiteBaseModel):
71
+ """Structural contract for Vega-Lite scale definitions."""
72
+
73
+
74
+ class Axis(VegaLiteBaseModel):
75
+ """Structural contract for Vega-Lite axis definitions."""
76
+
77
+
78
+ class Projection(VegaLiteBaseModel):
79
+ """Structural contract for Vega-Lite projection definitions."""
80
+
81
+ type: str | None = None
82
+
83
+
84
+ # ---------------------------------------------------------------------------
85
+ # Transform / Parameter
86
+ # ---------------------------------------------------------------------------
87
+
88
+
89
+ class Transform(VegaLiteBaseModel):
90
+ """Structural contract for a single Vega-Lite transform step."""
91
+
92
+
93
+ class TopLevelParameter(VegaLiteBaseModel):
94
+ """Structural contract for a top-level Vega-Lite parameter."""
95
+
96
+ name: str
97
+
98
+
99
+ # ---------------------------------------------------------------------------
100
+ # Top-level spec
101
+ # ---------------------------------------------------------------------------
102
+
103
+
104
+ class TopLevelUnitSpec(VegaLiteBaseModel):
105
+ """Structural contract for a Vega-Lite top-level unit spec.
106
+
107
+ Lists every valid top-level field so ``validation.py`` can derive
108
+ passthrough fields (= all fields minus system-owned ones).
109
+ """
110
+
111
+ schema_: str | None = Field(default=None, alias="$schema")
112
+ data: Any = None
113
+ mark: Any = None
114
+ encoding: Any = None
115
+ config: Any = None
116
+ projection: Any = None
117
+ transform: list[Any] | None = None
118
+ params: list[Any] | None = None
119
+ hconcat: list[Any] | None = None
120
+ vconcat: list[Any] | None = None
121
+ concat: list[Any] | None = None
122
+ repeat: Any = None
123
+
124
+ # Passthrough-eligible fields (not system-owned)
125
+ align: Any = None
126
+ autosize: Any = None
127
+ background: Any = None
128
+ bounds: Any = None
129
+ center: Any = None
130
+ datasets: Any = None
131
+ description: str | None = None
132
+ height: Any = None
133
+ name: str | None = None
134
+ padding: Any = None
135
+ resolve: Any = None
136
+ spacing: Any = None
137
+ title: Any = None
138
+ usermeta: Any = None
139
+ view: Any = None
140
+ width: Any = None
141
+
142
+
143
+ class TopLevelCompositeSpec(VegaLiteBaseModel):
144
+ """Structural contract for Vega-Lite top-level composition specs."""
145
+
146
+ schema_: str | None = Field(default=None, alias="$schema")
147
+ config: Any = None
148
+ projection: Any = None
149
+ transform: list[Any] | None = None
150
+ params: list[Any] | None = None
151
+ hconcat: list[Any] | None = None
152
+ vconcat: list[Any] | None = None
153
+ concat: list[Any] | None = None
154
+ repeat: Any = None
155
+ align: Any = None
156
+ autosize: Any = None
157
+ background: Any = None
158
+ bounds: Any = None
159
+ center: Any = None
160
+ data: Any = None
161
+ datasets: Any = None
162
+ description: str | None = None
163
+ name: str | None = None
164
+ padding: Any = None
165
+ resolve: Any = None
166
+ spacing: Any = None
167
+ title: Any = None
168
+ usermeta: Any = None
169
+
170
+
171
+ TopLevelSpec = TopLevelUnitSpec | TopLevelCompositeSpec