mlschema 0.2.0__tar.gz → 0.2.1__tar.gz
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.
- {mlschema-0.2.0 → mlschema-0.2.1}/CONTRIBUTING.md +1 -1
- {mlschema-0.2.0 → mlschema-0.2.1}/PKG-INFO +33 -16
- {mlschema-0.2.0 → mlschema-0.2.1}/README.md +32 -15
- {mlschema-0.2.0 → mlschema-0.2.1}/docs/changelog.md +23 -0
- {mlschema-0.2.0 → mlschema-0.2.1}/docs/index.md +17 -11
- {mlschema-0.2.0 → mlschema-0.2.1}/docs/installation.md +7 -7
- {mlschema-0.2.0 → mlschema-0.2.1}/docs/schema-standard.md +68 -32
- {mlschema-0.2.0 → mlschema-0.2.1}/docs/usage.md +45 -13
- {mlschema-0.2.0 → mlschema-0.2.1}/pyproject.toml +1 -1
- {mlschema-0.2.0 → mlschema-0.2.1}/src/mlschema/core/app/inference.py +102 -3
- {mlschema-0.2.0 → mlschema-0.2.1}/src/mlschema/core/app/kind.py +3 -0
- mlschema-0.2.1/src/mlschema/core/domain/base_field.py +34 -0
- {mlschema-0.2.0 → mlschema-0.2.1}/src/mlschema/strategies/app/_base.py +2 -1
- {mlschema-0.2.0 → mlschema-0.2.1}/src/mlschema/strategies/app/factory.py +2 -0
- {mlschema-0.2.0 → mlschema-0.2.1}/src/mlschema/strategies/domain/__init__.py +3 -0
- {mlschema-0.2.0 → mlschema-0.2.1}/src/mlschema/strategies/domain/field_types.py +1 -0
- mlschema-0.2.1/src/mlschema/strategies/domain/onehot_category_field.py +25 -0
- {mlschema-0.2.0 → mlschema-0.2.1}/src/mlschema/strategies/domain/series_field.py +2 -0
- {mlschema-0.2.0 → mlschema-0.2.1}/test/integration/test_infer_schema_workflows.py +63 -0
- {mlschema-0.2.0 → mlschema-0.2.1}/test/load/test_infer_schema_load.py +1 -0
- {mlschema-0.2.0 → mlschema-0.2.1}/test/unit/test_base_field_contract.py +10 -13
- {mlschema-0.2.0 → mlschema-0.2.1}/test/unit/test_builtin_builders.py +13 -4
- {mlschema-0.2.0 → mlschema-0.2.1}/test/unit/test_builtin_dtype_matrix.py +1 -1
- {mlschema-0.2.0 → mlschema-0.2.1}/test/unit/test_builtin_edge_cases.py +8 -3
- {mlschema-0.2.0 → mlschema-0.2.1}/test/unit/test_factory_and_context.py +7 -2
- {mlschema-0.2.0 → mlschema-0.2.1}/test/unit/test_field_models.py +54 -25
- {mlschema-0.2.0 → mlschema-0.2.1}/test/unit/test_inference_errors.py +27 -4
- {mlschema-0.2.0 → mlschema-0.2.1}/test/unit/test_kind_api.py +7 -1
- mlschema-0.2.0/src/mlschema/core/domain/base_field.py +0 -48
- {mlschema-0.2.0 → mlschema-0.2.1}/.gitignore +0 -0
- {mlschema-0.2.0 → mlschema-0.2.1}/AUTHORS.md +0 -0
- {mlschema-0.2.0 → mlschema-0.2.1}/LICENSE +0 -0
- {mlschema-0.2.0 → mlschema-0.2.1}/SECURITY.md +0 -0
- {mlschema-0.2.0 → mlschema-0.2.1}/THIRD_PARTY_LICENSES.md +0 -0
- {mlschema-0.2.0 → mlschema-0.2.1}/docs/reference.md +0 -0
- {mlschema-0.2.0 → mlschema-0.2.1}/src/mlschema/__init__.py +0 -0
- {mlschema-0.2.0 → mlschema-0.2.1}/src/mlschema/core/__init__.py +0 -0
- {mlschema-0.2.0 → mlschema-0.2.1}/src/mlschema/core/app/__init__.py +0 -0
- {mlschema-0.2.0 → mlschema-0.2.1}/src/mlschema/core/domain/__init__.py +0 -0
- {mlschema-0.2.0 → mlschema-0.2.1}/src/mlschema/core/exceptions/__init__.py +0 -0
- {mlschema-0.2.0 → mlschema-0.2.1}/src/mlschema/core/exceptions/_base.py +0 -0
- {mlschema-0.2.0 → mlschema-0.2.1}/src/mlschema/core/exceptions/empty_dataframe.py +0 -0
- {mlschema-0.2.0 → mlschema-0.2.1}/src/mlschema/core/exceptions/field_builder.py +0 -0
- {mlschema-0.2.0 → mlschema-0.2.1}/src/mlschema/core/exceptions/field_kind.py +0 -0
- {mlschema-0.2.0 → mlschema-0.2.1}/src/mlschema/core/exceptions/field_kind_conflict.py +0 -0
- {mlschema-0.2.0 → mlschema-0.2.1}/src/mlschema/core/exceptions/field_service.py +0 -0
- {mlschema-0.2.0 → mlschema-0.2.1}/src/mlschema/core/exceptions/unknown_field_kind.py +0 -0
- {mlschema-0.2.0 → mlschema-0.2.1}/src/mlschema/core/util/__init__.py +0 -0
- {mlschema-0.2.0 → mlschema-0.2.1}/src/mlschema/core/util/dtypes.py +0 -0
- {mlschema-0.2.0 → mlschema-0.2.1}/src/mlschema/mls.py +0 -0
- {mlschema-0.2.0 → mlschema-0.2.1}/src/mlschema/py.typed +0 -0
- {mlschema-0.2.0 → mlschema-0.2.1}/src/mlschema/strategies/__init__.py +0 -0
- {mlschema-0.2.0 → mlschema-0.2.1}/src/mlschema/strategies/app/__init__.py +0 -0
- {mlschema-0.2.0 → mlschema-0.2.1}/src/mlschema/strategies/app/boolean.py +0 -0
- {mlschema-0.2.0 → mlschema-0.2.1}/src/mlschema/strategies/app/category.py +0 -0
- {mlschema-0.2.0 → mlschema-0.2.1}/src/mlschema/strategies/app/date.py +0 -0
- {mlschema-0.2.0 → mlschema-0.2.1}/src/mlschema/strategies/app/number.py +0 -0
- {mlschema-0.2.0 → mlschema-0.2.1}/src/mlschema/strategies/app/series.py +0 -0
- {mlschema-0.2.0 → mlschema-0.2.1}/src/mlschema/strategies/app/text.py +0 -0
- {mlschema-0.2.0 → mlschema-0.2.1}/src/mlschema/strategies/domain/boolean_field.py +0 -0
- {mlschema-0.2.0 → mlschema-0.2.1}/src/mlschema/strategies/domain/category_field.py +0 -0
- {mlschema-0.2.0 → mlschema-0.2.1}/src/mlschema/strategies/domain/date_field.py +0 -0
- {mlschema-0.2.0 → mlschema-0.2.1}/src/mlschema/strategies/domain/number_field.py +0 -0
- {mlschema-0.2.0 → mlschema-0.2.1}/src/mlschema/strategies/domain/text_field.py +0 -0
- {mlschema-0.2.0 → mlschema-0.2.1}/test/architecture/test_public_surface.py +0 -0
- {mlschema-0.2.0 → mlschema-0.2.1}/test/architecture/test_test_suite_structure.py +0 -0
- {mlschema-0.2.0 → mlschema-0.2.1}/test/integration/test_schema_output_matrix.py +0 -0
- {mlschema-0.2.0 → mlschema-0.2.1}/test/unit/test_dtype_normalization.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: mlschema
|
|
3
|
-
Version: 0.2.
|
|
3
|
+
Version: 0.2.1
|
|
4
4
|
Summary: Infer validated, frontend-ready field schemas from pandas DataFrames.
|
|
5
5
|
Project-URL: Homepage, https://github.com/UlloaSP/mlschema
|
|
6
6
|
Project-URL: Documentation, https://ulloasp.github.io/mlschema/
|
|
@@ -59,7 +59,7 @@ It pairs naturally with [mlform](https://github.com/UlloaSP/mlform), but the gen
|
|
|
59
59
|
|
|
60
60
|
DataFrame columns already carry useful contract information: names, dtypes, categories, nullability, dates, numeric values, and structured pairs. MLSchema turns that information into a validated field list.
|
|
61
61
|
|
|
62
|
-
Instead of maintaining separate form definitions beside the data pipeline, use `infer_schema(df)` as the baseline and refine only what is genuinely product-specific: labels, bounds, defaults, units, placeholders,
|
|
62
|
+
Instead of maintaining separate form definitions beside the data pipeline, use `infer_schema(df)` as the baseline and refine only what is genuinely product-specific: labels, bounds, defaults, units, placeholders, or custom field kinds.
|
|
63
63
|
|
|
64
64
|
```python id="54fwnz"
|
|
65
65
|
import pandas as pd
|
|
@@ -83,24 +83,28 @@ schema = infer_schema(df)
|
|
|
83
83
|
{
|
|
84
84
|
"kind": "text",
|
|
85
85
|
"label": "name",
|
|
86
|
-
"required": true
|
|
86
|
+
"required": true,
|
|
87
|
+
"mappedTo": "name"
|
|
87
88
|
},
|
|
88
89
|
{
|
|
89
90
|
"kind": "number",
|
|
90
91
|
"label": "score",
|
|
91
92
|
"required": true,
|
|
93
|
+
"mappedTo": "score",
|
|
92
94
|
"step": 0.1
|
|
93
95
|
},
|
|
94
96
|
{
|
|
95
97
|
"kind": "category",
|
|
96
98
|
"label": "role",
|
|
97
99
|
"required": true,
|
|
100
|
+
"mappedTo": "role",
|
|
98
101
|
"options": ["engineer", "scientist"]
|
|
99
102
|
},
|
|
100
103
|
{
|
|
101
104
|
"kind": "boolean",
|
|
102
105
|
"label": "active",
|
|
103
|
-
"required": true
|
|
106
|
+
"required": true,
|
|
107
|
+
"mappedTo": "active"
|
|
104
108
|
}
|
|
105
109
|
]
|
|
106
110
|
```
|
|
@@ -108,7 +112,7 @@ schema = infer_schema(df)
|
|
|
108
112
|
## Key Features
|
|
109
113
|
|
|
110
114
|
* Function-first API: `infer_schema(df)`.
|
|
111
|
-
* Builtin inference for `text`, `number`, `category`, `boolean`, `date`, and two-axis `series` fields.
|
|
115
|
+
* Builtin inference for `text`, `number`, `category`, `onehot-category`, `boolean`, `date`, and two-axis `series` fields.
|
|
112
116
|
* Pydantic v2 validation before any schema is returned.
|
|
113
117
|
* JSON-serialisable field-list output for frontend and service integration.
|
|
114
118
|
* Field refinements through `overrides`.
|
|
@@ -141,7 +145,7 @@ poetry add mlschema
|
|
|
141
145
|
Pin a version when reproducible environments matter:
|
|
142
146
|
|
|
143
147
|
```bash id="yrqcr7"
|
|
144
|
-
uv add "mlschema==0.2.
|
|
148
|
+
uv add "mlschema==0.2.1"
|
|
145
149
|
```
|
|
146
150
|
|
|
147
151
|
## Quick Start
|
|
@@ -178,24 +182,28 @@ There is no top-level envelope by default. MLSchema returns the contract directl
|
|
|
178
182
|
{
|
|
179
183
|
"kind": "text",
|
|
180
184
|
"label": "customer",
|
|
181
|
-
"required": true
|
|
185
|
+
"required": true,
|
|
186
|
+
"mappedTo": "customer"
|
|
182
187
|
},
|
|
183
188
|
{
|
|
184
189
|
"kind": "number",
|
|
185
190
|
"label": "age",
|
|
186
191
|
"required": true,
|
|
192
|
+
"mappedTo": "age",
|
|
187
193
|
"step": 1
|
|
188
194
|
},
|
|
189
195
|
{
|
|
190
196
|
"kind": "category",
|
|
191
197
|
"label": "tier",
|
|
192
198
|
"required": true,
|
|
199
|
+
"mappedTo": "tier",
|
|
193
200
|
"options": ["free", "pro"]
|
|
194
201
|
},
|
|
195
202
|
{
|
|
196
203
|
"kind": "date",
|
|
197
204
|
"label": "created",
|
|
198
|
-
"required": true
|
|
205
|
+
"required": true,
|
|
206
|
+
"mappedTo": "created"
|
|
199
207
|
}
|
|
200
208
|
]
|
|
201
209
|
```
|
|
@@ -215,14 +223,21 @@ Builtin kinds are enabled by default and resolved in a fixed order.
|
|
|
215
223
|
|
|
216
224
|
| Kind | Detection | Notes |
|
|
217
225
|
| ---------- | ------------------------------------------------------------ | ---------------------------------------------------------------------- |
|
|
218
|
-
| `series`
|
|
219
|
-
| `
|
|
220
|
-
| `
|
|
221
|
-
| `
|
|
222
|
-
| `
|
|
223
|
-
| `
|
|
226
|
+
| `series` | Non-null cells are 2-element tuples, lists, or dictionaries. | Infers `field1` and `field2` recursively. |
|
|
227
|
+
| `onehot-category` | 0/1 columns grouped by `onehot_separator`. | Emits one category field with `options[].mappedTo`. |
|
|
228
|
+
| `boolean` | `bool`, `boolean` | Emits a boolean field contract. |
|
|
229
|
+
| `category` | `category` | Emits `options` from categorical categories. |
|
|
230
|
+
| `date` | `datetime64[ns]`, `datetime64[us]`, `datetime64` | Emits a date field contract. |
|
|
231
|
+
| `number` | `int64`, `int32`, `float64`, `float32` | Emits `step: 1` for integer columns and `step: 0.1` for float columns. |
|
|
232
|
+
| `text` | fallback | Claims columns not handled by earlier kinds. |
|
|
233
|
+
|
|
234
|
+
The order matters. `series` runs before `text` because it detects pair-shaped object cells by content. `onehot-category` groups strict 0/1 named feature columns such as `color__red` and `color__blue`. Positional binary columns stay as ordinary fields with integer `mappedTo` targets. `text` runs last as the safe fallback.
|
|
235
|
+
|
|
236
|
+
## Feature Mapping
|
|
237
|
+
|
|
238
|
+
Normal fields always include `mappedTo`. Named DataFrame columns emit string targets matching the column name. Positional columns emit numeric targets and generated labels such as `feature_0`.
|
|
224
239
|
|
|
225
|
-
|
|
240
|
+
`onehot-category` puts `mappedTo` on each option instead of the parent field. Options map like fields: strings for named feature columns, integers for positional inputs. The default one-hot separator is `"__"`.
|
|
226
241
|
|
|
227
242
|
## Series Columns
|
|
228
243
|
|
|
@@ -279,7 +294,7 @@ Nested series are rejected. Cardinality constraints such as `minPoints` and `max
|
|
|
279
294
|
|
|
280
295
|
## Refining Fields With Overrides
|
|
281
296
|
|
|
282
|
-
Inference provides the structural baseline. Production interfaces often need clearer labels, ranges, defaults, units,
|
|
297
|
+
Inference provides the structural baseline. Production interfaces often need clearer labels, ranges, defaults, units, or placeholders.
|
|
283
298
|
|
|
284
299
|
```python id="v9tboo"
|
|
285
300
|
schema = infer_schema(
|
|
@@ -320,6 +335,7 @@ def money_builder(series: Series, ctx: FieldContext) -> dict | None:
|
|
|
320
335
|
"kind": "number",
|
|
321
336
|
"label": "Amount",
|
|
322
337
|
"required": ctx.required,
|
|
338
|
+
"mappedTo": ctx.mappedTo,
|
|
323
339
|
"step": 0.01,
|
|
324
340
|
"unit": "EUR",
|
|
325
341
|
"min": 0,
|
|
@@ -351,6 +367,7 @@ def duration_builder(series: Series, ctx: FieldContext) -> dict | None:
|
|
|
351
367
|
"kind": "duration",
|
|
352
368
|
"label": ctx.name,
|
|
353
369
|
"required": ctx.required,
|
|
370
|
+
"mappedTo": ctx.mappedTo,
|
|
354
371
|
"unit": "seconds",
|
|
355
372
|
"minSeconds": int(series.min().total_seconds()),
|
|
356
373
|
"maxSeconds": int(series.max().total_seconds()),
|
|
@@ -15,7 +15,7 @@ It pairs naturally with [mlform](https://github.com/UlloaSP/mlform), but the gen
|
|
|
15
15
|
|
|
16
16
|
DataFrame columns already carry useful contract information: names, dtypes, categories, nullability, dates, numeric values, and structured pairs. MLSchema turns that information into a validated field list.
|
|
17
17
|
|
|
18
|
-
Instead of maintaining separate form definitions beside the data pipeline, use `infer_schema(df)` as the baseline and refine only what is genuinely product-specific: labels, bounds, defaults, units, placeholders,
|
|
18
|
+
Instead of maintaining separate form definitions beside the data pipeline, use `infer_schema(df)` as the baseline and refine only what is genuinely product-specific: labels, bounds, defaults, units, placeholders, or custom field kinds.
|
|
19
19
|
|
|
20
20
|
```python id="54fwnz"
|
|
21
21
|
import pandas as pd
|
|
@@ -39,24 +39,28 @@ schema = infer_schema(df)
|
|
|
39
39
|
{
|
|
40
40
|
"kind": "text",
|
|
41
41
|
"label": "name",
|
|
42
|
-
"required": true
|
|
42
|
+
"required": true,
|
|
43
|
+
"mappedTo": "name"
|
|
43
44
|
},
|
|
44
45
|
{
|
|
45
46
|
"kind": "number",
|
|
46
47
|
"label": "score",
|
|
47
48
|
"required": true,
|
|
49
|
+
"mappedTo": "score",
|
|
48
50
|
"step": 0.1
|
|
49
51
|
},
|
|
50
52
|
{
|
|
51
53
|
"kind": "category",
|
|
52
54
|
"label": "role",
|
|
53
55
|
"required": true,
|
|
56
|
+
"mappedTo": "role",
|
|
54
57
|
"options": ["engineer", "scientist"]
|
|
55
58
|
},
|
|
56
59
|
{
|
|
57
60
|
"kind": "boolean",
|
|
58
61
|
"label": "active",
|
|
59
|
-
"required": true
|
|
62
|
+
"required": true,
|
|
63
|
+
"mappedTo": "active"
|
|
60
64
|
}
|
|
61
65
|
]
|
|
62
66
|
```
|
|
@@ -64,7 +68,7 @@ schema = infer_schema(df)
|
|
|
64
68
|
## Key Features
|
|
65
69
|
|
|
66
70
|
* Function-first API: `infer_schema(df)`.
|
|
67
|
-
* Builtin inference for `text`, `number`, `category`, `boolean`, `date`, and two-axis `series` fields.
|
|
71
|
+
* Builtin inference for `text`, `number`, `category`, `onehot-category`, `boolean`, `date`, and two-axis `series` fields.
|
|
68
72
|
* Pydantic v2 validation before any schema is returned.
|
|
69
73
|
* JSON-serialisable field-list output for frontend and service integration.
|
|
70
74
|
* Field refinements through `overrides`.
|
|
@@ -97,7 +101,7 @@ poetry add mlschema
|
|
|
97
101
|
Pin a version when reproducible environments matter:
|
|
98
102
|
|
|
99
103
|
```bash id="yrqcr7"
|
|
100
|
-
uv add "mlschema==0.2.
|
|
104
|
+
uv add "mlschema==0.2.1"
|
|
101
105
|
```
|
|
102
106
|
|
|
103
107
|
## Quick Start
|
|
@@ -134,24 +138,28 @@ There is no top-level envelope by default. MLSchema returns the contract directl
|
|
|
134
138
|
{
|
|
135
139
|
"kind": "text",
|
|
136
140
|
"label": "customer",
|
|
137
|
-
"required": true
|
|
141
|
+
"required": true,
|
|
142
|
+
"mappedTo": "customer"
|
|
138
143
|
},
|
|
139
144
|
{
|
|
140
145
|
"kind": "number",
|
|
141
146
|
"label": "age",
|
|
142
147
|
"required": true,
|
|
148
|
+
"mappedTo": "age",
|
|
143
149
|
"step": 1
|
|
144
150
|
},
|
|
145
151
|
{
|
|
146
152
|
"kind": "category",
|
|
147
153
|
"label": "tier",
|
|
148
154
|
"required": true,
|
|
155
|
+
"mappedTo": "tier",
|
|
149
156
|
"options": ["free", "pro"]
|
|
150
157
|
},
|
|
151
158
|
{
|
|
152
159
|
"kind": "date",
|
|
153
160
|
"label": "created",
|
|
154
|
-
"required": true
|
|
161
|
+
"required": true,
|
|
162
|
+
"mappedTo": "created"
|
|
155
163
|
}
|
|
156
164
|
]
|
|
157
165
|
```
|
|
@@ -171,14 +179,21 @@ Builtin kinds are enabled by default and resolved in a fixed order.
|
|
|
171
179
|
|
|
172
180
|
| Kind | Detection | Notes |
|
|
173
181
|
| ---------- | ------------------------------------------------------------ | ---------------------------------------------------------------------- |
|
|
174
|
-
| `series`
|
|
175
|
-
| `
|
|
176
|
-
| `
|
|
177
|
-
| `
|
|
178
|
-
| `
|
|
179
|
-
| `
|
|
182
|
+
| `series` | Non-null cells are 2-element tuples, lists, or dictionaries. | Infers `field1` and `field2` recursively. |
|
|
183
|
+
| `onehot-category` | 0/1 columns grouped by `onehot_separator`. | Emits one category field with `options[].mappedTo`. |
|
|
184
|
+
| `boolean` | `bool`, `boolean` | Emits a boolean field contract. |
|
|
185
|
+
| `category` | `category` | Emits `options` from categorical categories. |
|
|
186
|
+
| `date` | `datetime64[ns]`, `datetime64[us]`, `datetime64` | Emits a date field contract. |
|
|
187
|
+
| `number` | `int64`, `int32`, `float64`, `float32` | Emits `step: 1` for integer columns and `step: 0.1` for float columns. |
|
|
188
|
+
| `text` | fallback | Claims columns not handled by earlier kinds. |
|
|
189
|
+
|
|
190
|
+
The order matters. `series` runs before `text` because it detects pair-shaped object cells by content. `onehot-category` groups strict 0/1 named feature columns such as `color__red` and `color__blue`. Positional binary columns stay as ordinary fields with integer `mappedTo` targets. `text` runs last as the safe fallback.
|
|
191
|
+
|
|
192
|
+
## Feature Mapping
|
|
193
|
+
|
|
194
|
+
Normal fields always include `mappedTo`. Named DataFrame columns emit string targets matching the column name. Positional columns emit numeric targets and generated labels such as `feature_0`.
|
|
180
195
|
|
|
181
|
-
|
|
196
|
+
`onehot-category` puts `mappedTo` on each option instead of the parent field. Options map like fields: strings for named feature columns, integers for positional inputs. The default one-hot separator is `"__"`.
|
|
182
197
|
|
|
183
198
|
## Series Columns
|
|
184
199
|
|
|
@@ -235,7 +250,7 @@ Nested series are rejected. Cardinality constraints such as `minPoints` and `max
|
|
|
235
250
|
|
|
236
251
|
## Refining Fields With Overrides
|
|
237
252
|
|
|
238
|
-
Inference provides the structural baseline. Production interfaces often need clearer labels, ranges, defaults, units,
|
|
253
|
+
Inference provides the structural baseline. Production interfaces often need clearer labels, ranges, defaults, units, or placeholders.
|
|
239
254
|
|
|
240
255
|
```python id="v9tboo"
|
|
241
256
|
schema = infer_schema(
|
|
@@ -276,6 +291,7 @@ def money_builder(series: Series, ctx: FieldContext) -> dict | None:
|
|
|
276
291
|
"kind": "number",
|
|
277
292
|
"label": "Amount",
|
|
278
293
|
"required": ctx.required,
|
|
294
|
+
"mappedTo": ctx.mappedTo,
|
|
279
295
|
"step": 0.01,
|
|
280
296
|
"unit": "EUR",
|
|
281
297
|
"min": 0,
|
|
@@ -307,6 +323,7 @@ def duration_builder(series: Series, ctx: FieldContext) -> dict | None:
|
|
|
307
323
|
"kind": "duration",
|
|
308
324
|
"label": ctx.name,
|
|
309
325
|
"required": ctx.required,
|
|
326
|
+
"mappedTo": ctx.mappedTo,
|
|
310
327
|
"unit": "seconds",
|
|
311
328
|
"minSeconds": int(series.min().total_seconds()),
|
|
312
329
|
"maxSeconds": int(series.max().total_seconds()),
|
|
@@ -8,6 +8,29 @@ The format follows [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and
|
|
|
8
8
|
|
|
9
9
|
No unreleased changes documented yet.
|
|
10
10
|
|
|
11
|
+
## [0.2.1] - 2026-06-18
|
|
12
|
+
|
|
13
|
+
### Added
|
|
14
|
+
|
|
15
|
+
* Added mandatory `mappedTo` output for normal fields.
|
|
16
|
+
* Added `onehot-category` inference for named one-hot encoded feature columns.
|
|
17
|
+
* Added `options[].mappedTo` targets for `onehot-category` options.
|
|
18
|
+
* Added `onehot_separator` to `infer_schema()`; the default separator is `"__"` for `feature__value` columns.
|
|
19
|
+
* Added positional-column fallback labels such as `feature_0`, `feature_1`, and integer `mappedTo` targets.
|
|
20
|
+
|
|
21
|
+
### Changed
|
|
22
|
+
|
|
23
|
+
* Changed named DataFrame columns to emit string `mappedTo` targets matching the column name.
|
|
24
|
+
* Changed positional DataFrame columns to emit generated labels and zero-based integer `mappedTo` targets.
|
|
25
|
+
* Changed one-hot grouping to require named encoded feature columns; positional binary columns now remain ordinary fields.
|
|
26
|
+
* Updated README, usage docs, and schema-standard docs for the `mappedTo` and `onehot-category` contracts.
|
|
27
|
+
|
|
28
|
+
### Fixed
|
|
29
|
+
|
|
30
|
+
* Fixed schema mapping ambiguity between display labels and backend targets.
|
|
31
|
+
* Fixed one-hot output so the parent field has no `mappedTo`; each option owns its backend target.
|
|
32
|
+
* Fixed regression coverage for named feature mappings, positional mappings, custom one-hot separators, and positional binary columns.
|
|
33
|
+
|
|
11
34
|
## [0.2.0] - 2026-06-01
|
|
12
35
|
|
|
13
36
|
`0.2.0` is a breaking release. MLSchema moves from the previous class-and-registry API to a smaller function-first API centred on `infer_schema(df)`. The schema output is now the field list itself, not a top-level object containing `fields`, `reports`, or `explanations`.
|
|
@@ -35,18 +35,21 @@ The result is a validated field list:
|
|
|
35
35
|
{
|
|
36
36
|
"kind": "text",
|
|
37
37
|
"label": "name",
|
|
38
|
-
"required": true
|
|
38
|
+
"required": true,
|
|
39
|
+
"mappedTo": 0
|
|
39
40
|
},
|
|
40
41
|
{
|
|
41
42
|
"kind": "number",
|
|
42
43
|
"label": "score",
|
|
43
44
|
"required": true,
|
|
45
|
+
"mappedTo": 1,
|
|
44
46
|
"step": 0.1
|
|
45
47
|
},
|
|
46
48
|
{
|
|
47
49
|
"kind": "boolean",
|
|
48
50
|
"label": "active",
|
|
49
|
-
"required": true
|
|
51
|
+
"required": true,
|
|
52
|
+
"mappedTo": 2
|
|
50
53
|
}
|
|
51
54
|
]
|
|
52
55
|
```
|
|
@@ -72,7 +75,7 @@ The library is useful when the goal is not to build a form manually, but to deri
|
|
|
72
75
|
| **Frontend-ready contracts** | Output is JSON-serialisable and designed to be consumed by UI libraries such as `mlform`. |
|
|
73
76
|
| **Safe defaults** | Builtin kinds are enabled by default; no registry setup is required for common DataFrame workflows. |
|
|
74
77
|
| **Controlled extension** | Custom builders and custom kinds allow domain-specific behaviour without changing consumer code. |
|
|
75
|
-
| **Column-level refinement** | Overrides provide final labels, bounds, defaults, placeholders,
|
|
78
|
+
| **Column-level refinement** | Overrides provide final labels, bounds, defaults, placeholders, and units. |
|
|
76
79
|
|
|
77
80
|
---
|
|
78
81
|
|
|
@@ -112,20 +115,21 @@ MLSchema ships with builtin inference for the standard field types used in most
|
|
|
112
115
|
|
|
113
116
|
| Kind | Detection |
|
|
114
117
|
| ---------- | ------------------------------------------------------------ |
|
|
115
|
-
| `series`
|
|
116
|
-
| `
|
|
117
|
-
| `
|
|
118
|
-
| `
|
|
119
|
-
| `
|
|
120
|
-
| `
|
|
118
|
+
| `series` | Non-null cells are 2-element tuples, lists, or dictionaries. |
|
|
119
|
+
| `onehot-category` | 0/1 columns grouped by `onehot_separator`. |
|
|
120
|
+
| `boolean` | `bool`, `boolean` |
|
|
121
|
+
| `category` | `category` |
|
|
122
|
+
| `date` | `datetime64[ns]`, `datetime64[us]`, `datetime64` |
|
|
123
|
+
| `number` | `int64`, `int32`, `float64`, `float32` |
|
|
124
|
+
| `text` | Fallback for columns not claimed by an earlier kind. |
|
|
121
125
|
|
|
122
|
-
The order matters. More specific detections run first, and `text` runs last as the safe fallback.
|
|
126
|
+
The order matters. More specific detections run first, one-hot encoded columns such as `color__red` are grouped before ordinary numeric fields, and `text` runs last as the safe fallback.
|
|
123
127
|
|
|
124
128
|
---
|
|
125
129
|
|
|
126
130
|
## Refining Inferred Schemas
|
|
127
131
|
|
|
128
|
-
Inference gives the structural baseline. Production interfaces usually need a more explicit product contract: clearer labels, minimum and maximum values, defaults, units, placeholders,
|
|
132
|
+
Inference gives the structural baseline. Production interfaces usually need a more explicit product contract: clearer labels, minimum and maximum values, defaults, units, placeholders, or descriptions.
|
|
129
133
|
|
|
130
134
|
Use `overrides` for those final column-specific refinements.
|
|
131
135
|
|
|
@@ -164,6 +168,7 @@ def money_builder(series: Series, ctx: FieldContext) -> dict | None:
|
|
|
164
168
|
"kind": "number",
|
|
165
169
|
"label": "Amount",
|
|
166
170
|
"required": ctx.required,
|
|
171
|
+
"mappedTo": ctx.mappedTo,
|
|
167
172
|
"step": 0.01,
|
|
168
173
|
"unit": "EUR",
|
|
169
174
|
"min": 0,
|
|
@@ -195,6 +200,7 @@ def duration_builder(series: Series, ctx: FieldContext) -> dict | None:
|
|
|
195
200
|
"kind": "duration",
|
|
196
201
|
"label": ctx.name,
|
|
197
202
|
"required": ctx.required,
|
|
203
|
+
"mappedTo": ctx.mappedTo,
|
|
198
204
|
"unit": "seconds",
|
|
199
205
|
"minSeconds": int(series.min().total_seconds()),
|
|
200
206
|
"maxSeconds": int(series.max().total_seconds()),
|
|
@@ -29,7 +29,7 @@ uv add mlschema
|
|
|
29
29
|
Pin a specific version when the environment must be reproducible:
|
|
30
30
|
|
|
31
31
|
```bash
|
|
32
|
-
uv add "mlschema==0.2.
|
|
32
|
+
uv add "mlschema==0.2.1"
|
|
33
33
|
```
|
|
34
34
|
|
|
35
35
|
`uv` updates the project dependency metadata and lockfile, so this is the preferred option for applications, libraries, and CI workflows that already use `uv`.
|
|
@@ -47,7 +47,7 @@ pip install mlschema
|
|
|
47
47
|
Pinned installation:
|
|
48
48
|
|
|
49
49
|
```bash
|
|
50
|
-
pip install "mlschema==0.2.
|
|
50
|
+
pip install "mlschema==0.2.1"
|
|
51
51
|
```
|
|
52
52
|
|
|
53
53
|
When working inside a Conda environment, use `pip` after activating the environment:
|
|
@@ -69,7 +69,7 @@ poetry add mlschema
|
|
|
69
69
|
Pinned installation:
|
|
70
70
|
|
|
71
71
|
```bash
|
|
72
|
-
poetry add "mlschema==0.2.
|
|
72
|
+
poetry add "mlschema==0.2.1"
|
|
73
73
|
```
|
|
74
74
|
|
|
75
75
|
---
|
|
@@ -155,9 +155,9 @@ Expected shape:
|
|
|
155
155
|
|
|
156
156
|
```python
|
|
157
157
|
[
|
|
158
|
-
{"kind": "text", "label": "name", "required": True},
|
|
159
|
-
{"kind": "number", "label": "score", "required": True, "step": 0.1},
|
|
160
|
-
{"kind": "boolean", "label": "active", "required": True},
|
|
158
|
+
{"kind": "text", "label": "name", "required": True, "mappedTo": 0},
|
|
159
|
+
{"kind": "number", "label": "score", "required": True, "mappedTo": 1, "step": 0.1},
|
|
160
|
+
{"kind": "boolean", "label": "active", "required": True, "mappedTo": 2},
|
|
161
161
|
]
|
|
162
162
|
```
|
|
163
163
|
|
|
@@ -214,7 +214,7 @@ Patch releases should be safe for compatible fixes. Minor releases may add suppo
|
|
|
214
214
|
For production systems, pin a known version and upgrade deliberately:
|
|
215
215
|
|
|
216
216
|
```bash
|
|
217
|
-
uv add "mlschema==0.2.
|
|
217
|
+
uv add "mlschema==0.2.1"
|
|
218
218
|
```
|
|
219
219
|
|
|
220
220
|
---
|