Skip to content

Commit c225cb7

Browse files
authored
Merge pull request #285 from Integration-Automation/feat/data-profile-batch
Add data profiling and schema inference
2 parents d3b2389 + 6aacbba commit c225cb7

15 files changed

Lines changed: 405 additions & 1 deletion

File tree

README.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313

1414
## Table of Contents
1515

16+
- [What's new (2026-06-21) — Data Profiling & Schema Inference](#whats-new-2026-06-21--data-profiling--schema-inference)
1617
- [What's new (2026-06-21) — W3C Trace Context Propagation](#whats-new-2026-06-21--w3c-trace-context-propagation)
1718
- [What's new (2026-06-21) — HTTP Record & Replay Cassette](#whats-new-2026-06-21--http-record--replay-cassette)
1819
- [What's new (2026-06-21) — Bulkhead & Rate-Limit Headers](#whats-new-2026-06-21--bulkhead--rate-limit-headers)
@@ -129,6 +130,12 @@
129130

130131
---
131132

133+
## What's new (2026-06-21) — Data Profiling & Schema Inference
134+
135+
Survey a row-set and propose a validation schema. Full reference: [`docs/source/Eng/doc/new_features/v77_features_doc.rst`](docs/source/Eng/doc/new_features/v77_features_doc.rst).
136+
137+
- **`profile_rows` / `infer_schema`** (`AC_profile_rows`, `AC_infer_schema`): `validate_rows` consumes a hand-written schema and `stats.describe` summarizes one numeric list — nothing surveyed a whole row-set. This profiles each column (null fraction, cardinality, inferred type, top values, numeric min/max/mean) and infers a `validate_rows`-compatible schema (required where non-null, unique where distinct, numeric bounds) — the profiler step that feeds the existing validator. Pure-stdlib, fully deterministic.
138+
132139
## What's new (2026-06-21) — W3C Trace Context Propagation
133140

134141
Correlate spans and logs across HTTP boundaries. Full reference: [`docs/source/Eng/doc/new_features/v76_features_doc.rst`](docs/source/Eng/doc/new_features/v76_features_doc.rst).

README/README_zh-CN.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212

1313
## 目录
1414

15+
- [本次更新 (2026-06-21) — 数据剖析与结构推断](#本次更新-2026-06-21--数据剖析与结构推断)
1516
- [本次更新 (2026-06-21) — W3C Trace Context 传播](#本次更新-2026-06-21--w3c-trace-context-传播)
1617
- [本次更新 (2026-06-21) — HTTP 录制与重播卡带](#本次更新-2026-06-21--http-录制与重播卡带)
1718
- [本次更新 (2026-06-21) — 隔舱与速率限制标头](#本次更新-2026-06-21--隔舱与速率限制标头)
@@ -128,6 +129,12 @@
128129

129130
---
130131

132+
## 本次更新 (2026-06-21) — 数据剖析与结构推断
133+
134+
扫描数据行集合并提出验证结构。完整参考:[`docs/source/Zh/doc/new_features/v77_features_doc.rst`](../docs/source/Zh/doc/new_features/v77_features_doc.rst)
135+
136+
- **`profile_rows` / `infer_schema`**(`AC_profile_rows``AC_infer_schema`):`validate_rows` 消费手写结构,`stats.describe` 只汇总单一数值列表 —— 没有任何东西扫描整个数据行集合。本功能剖析每列(空值比例、基数、推断类型、最常见值、数值 min/max/mean)并推断出 `validate_rows` 兼容结构(无空值即 required、相异即 unique、数值边界)—— 馈入既有验证器的剖析步骤。纯标准库、完全确定。
137+
131138
## 本次更新 (2026-06-21) — W3C Trace Context 传播
132139

133140
跨 HTTP 边界关联 span 与日志。完整参考:[`docs/source/Zh/doc/new_features/v76_features_doc.rst`](../docs/source/Zh/doc/new_features/v76_features_doc.rst)

README/README_zh-TW.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212

1313
## 目錄
1414

15+
- [本次更新 (2026-06-21) — 資料剖析與結構推斷](#本次更新-2026-06-21--資料剖析與結構推斷)
1516
- [本次更新 (2026-06-21) — W3C Trace Context 傳播](#本次更新-2026-06-21--w3c-trace-context-傳播)
1617
- [本次更新 (2026-06-21) — HTTP 錄製與重播卡帶](#本次更新-2026-06-21--http-錄製與重播卡帶)
1718
- [本次更新 (2026-06-21) — 隔艙與速率限制標頭](#本次更新-2026-06-21--隔艙與速率限制標頭)
@@ -128,6 +129,12 @@
128129

129130
---
130131

132+
## 本次更新 (2026-06-21) — 資料剖析與結構推斷
133+
134+
掃描資料列集合並提出驗證結構。完整參考:[`docs/source/Zh/doc/new_features/v77_features_doc.rst`](../docs/source/Zh/doc/new_features/v77_features_doc.rst)
135+
136+
- **`profile_rows` / `infer_schema`**(`AC_profile_rows``AC_infer_schema`):`validate_rows` 消費手寫結構,`stats.describe` 只彙總單一數值清單 —— 沒有任何東西掃描整個資料列集合。本功能剖析每欄(空值比例、基數、推斷型別、最常見值、數值 min/max/mean)並推斷出 `validate_rows` 相容結構(無空值即 required、相異即 unique、數值邊界)—— 餵給既有驗證器的剖析步驟。純標準函式庫、完全具決定性。
137+
131138
## 本次更新 (2026-06-21) — W3C Trace Context 傳播
132139

133140
跨 HTTP 邊界關聯 span 與日誌。完整參考:[`docs/source/Zh/doc/new_features/v76_features_doc.rst`](../docs/source/Zh/doc/new_features/v76_features_doc.rst)
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
Data Profiling & Schema Inference
2+
=================================
3+
4+
``data_quality.validate_rows`` *consumes* a hand-written schema and
5+
``stats.describe`` summarises one numeric list — nothing surveyed a whole
6+
row-set to report per-column null fraction, cardinality, inferred type, value
7+
ranges, and top values, nor proposed a starting schema. This adds the profiler
8+
step that feeds the existing validator.
9+
10+
Pure standard library (``collections`` + reuse of ``stats``); imports no
11+
``PySide6``. Every function is pure (rows in, dict out), so it is fully
12+
deterministic in CI.
13+
14+
Headless API
15+
------------
16+
17+
.. code-block:: python
18+
19+
from je_auto_control import profile_rows, infer_schema, validate_rows, load_rows
20+
21+
rows = load_rows("export.csv")
22+
profile = profile_rows(rows)
23+
# profile["columns"]["age"] -> {count, null_count, null_fraction, distinct,
24+
# unique, inferred_type, top_values, min, max, mean}
25+
26+
schema = infer_schema(rows) # validate_rows-compatible
27+
report = validate_rows(rows, schema)
28+
29+
``profile_rows`` returns ``{row_count, columns}`` where each column carries its
30+
count, null count and fraction, distinct count, a uniqueness flag, the inferred
31+
type (``int`` / ``number`` / ``bool`` / ``str``), the top values with counts,
32+
and ``min`` / ``max`` / ``mean`` for numeric columns. ``infer_schema`` turns
33+
that profile into a schema the existing ``validate_rows`` understands: a column
34+
is ``required`` when it has no nulls, ``unique`` when every non-null value is
35+
distinct, and carries numeric bounds. Pass an explicit ``columns`` list to
36+
restrict either function to a subset.
37+
38+
Executor commands
39+
-----------------
40+
41+
``AC_profile_rows`` profiles a ``rows`` list (optional ``columns`` subset) and
42+
returns ``{profile}``. ``AC_infer_schema`` returns ``{schema}``. Both are
43+
exposed as MCP tools (``ac_profile_rows`` / ``ac_infer_schema``) and as Script
44+
Builder commands under **Data**.

docs/source/Eng/eng_index.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,7 @@ Comprehensive guides for all AutoControl features.
9999
doc/new_features/v74_features_doc
100100
doc/new_features/v75_features_doc
101101
doc/new_features/v76_features_doc
102+
doc/new_features/v77_features_doc
102103
doc/ocr_backends/ocr_backends_doc
103104
doc/observability/observability_doc
104105
doc/operations_layer/operations_layer_doc
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
資料剖析與結構推斷
2+
================
3+
4+
``data_quality.validate_rows`` *消費* 一份手寫結構,``stats.describe`` 只彙總單一數值清單 —— 沒有任何
5+
東西能掃描整個資料列集合,回報每欄的空值比例、基數、推斷型別、值域與最常見值,也無法提出一份起始結構。
6+
本功能補上這個剖析步驟,並餵給既有的驗證器。
7+
8+
純標準函式庫(``collections`` + 重用 ``stats``);不匯入 ``PySide6``。每個函式皆為純函式(輸入列、輸出
9+
dict),因此在 CI 中完全具決定性。
10+
11+
無頭 API
12+
--------
13+
14+
.. code-block:: python
15+
16+
from je_auto_control import profile_rows, infer_schema, validate_rows, load_rows
17+
18+
rows = load_rows("export.csv")
19+
profile = profile_rows(rows)
20+
# profile["columns"]["age"] -> {count, null_count, null_fraction, distinct,
21+
# unique, inferred_type, top_values, min, max, mean}
22+
23+
schema = infer_schema(rows) # validate_rows 相容
24+
report = validate_rows(rows, schema)
25+
26+
``profile_rows`` 回傳 ``{row_count, columns}``,每欄帶有其筆數、空值數與比例、相異值數、唯一性旗標、
27+
推斷型別(``int`` / ``number`` / ``bool`` / ``str``)、最常見值與其次數,以及數值欄的 ``min`` /
28+
``max`` / ``mean``。``infer_schema`` 把該剖析轉成既有 ``validate_rows`` 能理解的結構:無空值的欄位
29+
標為 ``required``,每個非空值皆相異則標為 ``unique``,並帶上數值邊界。傳入明確的 ``columns`` 清單可將
30+
兩個函式限制在子集。
31+
32+
執行器命令
33+
----------
34+
35+
``AC_profile_rows`` 剖析 ``rows`` 清單(可選 ``columns`` 子集)回傳 ``{profile}``。``AC_infer_schema``
36+
回傳 ``{schema}``。兩者皆以 MCP 工具(``ac_profile_rows`` / ``ac_infer_schema``)以及 Script Builder
37+
中 **Data** 分類下的命令提供。

docs/source/Zh/zh_index.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,7 @@ AutoControl 所有功能的完整使用指南。
9999
doc/new_features/v74_features_doc
100100
doc/new_features/v75_features_doc
101101
doc/new_features/v76_features_doc
102+
doc/new_features/v77_features_doc
102103
doc/ocr_backends/ocr_backends_doc
103104
doc/observability/observability_doc
104105
doc/operations_layer/operations_layer_doc

je_auto_control/__init__.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -157,6 +157,8 @@
157157
from je_auto_control.utils.data_quality import (
158158
extract_fields, mask_rows, validate_rows,
159159
)
160+
# Data profiling: per-column stats + schema inference from observed rows
161+
from je_auto_control.utils.data_profile import infer_schema, profile_rows
160162
# i18n / l10n testing: pseudo-localize, overflow + catalog checks
161163
from je_auto_control.utils.i18n_test import (
162164
check_catalog, check_overflow, pseudo_localize, pseudo_localize_catalog,
@@ -803,6 +805,7 @@ def start_autocontrol_gui(*args, **kwargs):
803805
"build_sbom", "write_sbom",
804806
"merge_results", "shard_flows",
805807
"extract_fields", "mask_rows", "validate_rows",
808+
"infer_schema", "profile_rows",
806809
"check_catalog", "check_overflow", "pseudo_localize",
807810
"pseudo_localize_catalog",
808811
"Checkpoint", "CheckpointStore", "run_resumable",

je_auto_control/gui/script_builder/command_schema.py

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1624,6 +1624,26 @@ def _add_resilience_specs(specs: List[CommandSpec]) -> None:
16241624
),
16251625
description="Extract the W3C trace context from request headers.",
16261626
))
1627+
specs.append(CommandSpec(
1628+
"AC_profile_rows", "Data", "Data Profile: Profile Rows",
1629+
fields=(
1630+
FieldSpec("rows", FieldType.STRING,
1631+
placeholder='[{"id": 1, "name": "a"}, {"id": 2}]'),
1632+
FieldSpec("columns", FieldType.STRING, optional=True,
1633+
placeholder='["id", "name"] (omit for all)'),
1634+
),
1635+
description="Per-column stats: null fraction, cardinality, type, ranges.",
1636+
))
1637+
specs.append(CommandSpec(
1638+
"AC_infer_schema", "Data", "Data Profile: Infer Schema",
1639+
fields=(
1640+
FieldSpec("rows", FieldType.STRING,
1641+
placeholder='[{"id": 1, "name": "a"}, {"id": 2}]'),
1642+
FieldSpec("columns", FieldType.STRING, optional=True,
1643+
placeholder='["id", "name"] (omit for all)'),
1644+
),
1645+
description="Infer a validate_rows-compatible schema from observed rows.",
1646+
))
16271647
specs.append(CommandSpec(
16281648
"AC_rate_limit", "Flow", "Rate Limit (Token Bucket)",
16291649
fields=(
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
"""Data profiling and schema inference for AutoControl row-sets."""
2+
from je_auto_control.utils.data_profile.data_profile import (
3+
infer_schema, profile_rows,
4+
)
5+
6+
__all__ = ["infer_schema", "profile_rows"]

0 commit comments

Comments
 (0)