mlschema 0.2.1__tar.gz → 0.3.0__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.
Files changed (98) hide show
  1. {mlschema-0.2.1 → mlschema-0.3.0}/.gitignore +14 -1
  2. {mlschema-0.2.1 → mlschema-0.3.0}/AUTHORS.md +3 -3
  3. mlschema-0.3.0/CONTRIBUTING.md +80 -0
  4. mlschema-0.3.0/PKG-INFO +208 -0
  5. mlschema-0.3.0/README.md +163 -0
  6. {mlschema-0.2.1 → mlschema-0.3.0}/SECURITY.md +12 -12
  7. {mlschema-0.2.1 → mlschema-0.3.0}/THIRD_PARTY_LICENSES.md +16 -36
  8. mlschema-0.3.0/brand/README.md +16 -0
  9. mlschema-0.3.0/brand/eshkra-mark.png +0 -0
  10. mlschema-0.3.0/brand/mlschema.png +0 -0
  11. mlschema-0.3.0/brand/mona-sans-LICENSE.txt +93 -0
  12. mlschema-0.3.0/brand/wordmark-dark.svg +14 -0
  13. mlschema-0.3.0/brand/wordmark-light.svg +14 -0
  14. mlschema-0.3.0/docs/src/content/docs/changelog/0-1.md +103 -0
  15. mlschema-0.3.0/docs/src/content/docs/changelog.md +279 -0
  16. mlschema-0.3.0/docs/src/content/docs/getting-started/installation.md +90 -0
  17. mlschema-0.3.0/docs/src/content/docs/getting-started/quick-start.md +103 -0
  18. mlschema-0.3.0/docs/src/content/docs/guides/errors.md +81 -0
  19. mlschema-0.3.0/docs/src/content/docs/guides/extensions.md +135 -0
  20. mlschema-0.3.0/docs/src/content/docs/guides/mlform.md +75 -0
  21. mlschema-0.3.0/docs/src/content/docs/guides/overrides.md +59 -0
  22. mlschema-0.3.0/docs/src/content/docs/index.md +87 -0
  23. mlschema-0.3.0/docs/src/content/docs/reference/api.md +139 -0
  24. mlschema-0.3.0/docs/src/content/docs/reference/releases.md +47 -0
  25. mlschema-0.3.0/docs/src/content/docs/schema/field-kinds.md +204 -0
  26. mlschema-0.3.0/docs/src/content/docs/schema/mappings.md +134 -0
  27. mlschema-0.3.0/docs/src/content/docs/schema/overview.md +91 -0
  28. mlschema-0.3.0/docs/src/content/docs/schema/series.md +127 -0
  29. mlschema-0.3.0/landing/README.md +43 -0
  30. mlschema-0.3.0/playground/README.md +71 -0
  31. {mlschema-0.2.1 → mlschema-0.3.0}/pyproject.toml +7 -13
  32. {mlschema-0.2.1 → mlschema-0.3.0}/src/mlschema/__init__.py +2 -0
  33. {mlschema-0.2.1 → mlschema-0.3.0}/src/mlschema/core/__init__.py +3 -1
  34. {mlschema-0.2.1 → mlschema-0.3.0}/src/mlschema/core/app/__init__.py +2 -0
  35. {mlschema-0.2.1 → mlschema-0.3.0}/src/mlschema/core/app/inference.py +2 -2
  36. {mlschema-0.2.1 → mlschema-0.3.0}/src/mlschema/core/app/kind.py +1 -1
  37. mlschema-0.3.0/src/mlschema/core/app/mappings.py +41 -0
  38. {mlschema-0.2.1 → mlschema-0.3.0}/src/mlschema/core/exceptions/__init__.py +1 -1
  39. {mlschema-0.2.1 → mlschema-0.3.0}/src/mlschema/strategies/app/_base.py +1 -1
  40. {mlschema-0.2.1 → mlschema-0.3.0}/src/mlschema/strategies/app/date.py +1 -1
  41. {mlschema-0.2.1 → mlschema-0.3.0}/src/mlschema/strategies/app/series.py +6 -5
  42. mlschema-0.3.0/src/mlschema/strategies/domain/series_column.py +54 -0
  43. mlschema-0.3.0/src/mlschema/strategies/domain/series_field.py +44 -0
  44. {mlschema-0.2.1 → mlschema-0.3.0}/test/integration/test_infer_schema_workflows.py +2 -2
  45. {mlschema-0.2.1 → mlschema-0.3.0}/test/integration/test_schema_output_matrix.py +4 -1
  46. {mlschema-0.2.1 → mlschema-0.3.0}/test/unit/test_builtin_builders.py +2 -2
  47. {mlschema-0.2.1 → mlschema-0.3.0}/test/unit/test_builtin_edge_cases.py +2 -2
  48. {mlschema-0.2.1 → mlschema-0.3.0}/test/unit/test_field_models.py +0 -57
  49. {mlschema-0.2.1 → mlschema-0.3.0}/test/unit/test_inference_errors.py +1 -1
  50. mlschema-0.3.0/test/unit/test_positional_mappings.py +54 -0
  51. mlschema-0.3.0/test/unit/test_series_columns.py +102 -0
  52. mlschema-0.2.1/CONTRIBUTING.md +0 -447
  53. mlschema-0.2.1/PKG-INFO +0 -467
  54. mlschema-0.2.1/README.md +0 -423
  55. mlschema-0.2.1/docs/changelog.md +0 -333
  56. mlschema-0.2.1/docs/index.md +0 -248
  57. mlschema-0.2.1/docs/installation.md +0 -228
  58. mlschema-0.2.1/docs/reference.md +0 -19
  59. mlschema-0.2.1/docs/schema-standard.md +0 -654
  60. mlschema-0.2.1/docs/usage.md +0 -448
  61. mlschema-0.2.1/src/mlschema/strategies/domain/series_field.py +0 -101
  62. {mlschema-0.2.1 → mlschema-0.3.0}/LICENSE +0 -0
  63. {mlschema-0.2.1 → mlschema-0.3.0}/src/mlschema/core/domain/__init__.py +0 -0
  64. {mlschema-0.2.1 → mlschema-0.3.0}/src/mlschema/core/domain/base_field.py +0 -0
  65. {mlschema-0.2.1 → mlschema-0.3.0}/src/mlschema/core/exceptions/_base.py +0 -0
  66. {mlschema-0.2.1 → mlschema-0.3.0}/src/mlschema/core/exceptions/empty_dataframe.py +0 -0
  67. {mlschema-0.2.1 → mlschema-0.3.0}/src/mlschema/core/exceptions/field_builder.py +0 -0
  68. {mlschema-0.2.1 → mlschema-0.3.0}/src/mlschema/core/exceptions/field_kind.py +0 -0
  69. {mlschema-0.2.1 → mlschema-0.3.0}/src/mlschema/core/exceptions/field_kind_conflict.py +0 -0
  70. {mlschema-0.2.1 → mlschema-0.3.0}/src/mlschema/core/exceptions/field_service.py +0 -0
  71. {mlschema-0.2.1 → mlschema-0.3.0}/src/mlschema/core/exceptions/unknown_field_kind.py +0 -0
  72. {mlschema-0.2.1 → mlschema-0.3.0}/src/mlschema/core/util/__init__.py +0 -0
  73. {mlschema-0.2.1 → mlschema-0.3.0}/src/mlschema/core/util/dtypes.py +0 -0
  74. {mlschema-0.2.1 → mlschema-0.3.0}/src/mlschema/mls.py +0 -0
  75. {mlschema-0.2.1 → mlschema-0.3.0}/src/mlschema/py.typed +0 -0
  76. {mlschema-0.2.1 → mlschema-0.3.0}/src/mlschema/strategies/__init__.py +0 -0
  77. {mlschema-0.2.1 → mlschema-0.3.0}/src/mlschema/strategies/app/__init__.py +0 -0
  78. {mlschema-0.2.1 → mlschema-0.3.0}/src/mlschema/strategies/app/boolean.py +0 -0
  79. {mlschema-0.2.1 → mlschema-0.3.0}/src/mlschema/strategies/app/category.py +0 -0
  80. {mlschema-0.2.1 → mlschema-0.3.0}/src/mlschema/strategies/app/factory.py +0 -0
  81. {mlschema-0.2.1 → mlschema-0.3.0}/src/mlschema/strategies/app/number.py +0 -0
  82. {mlschema-0.2.1 → mlschema-0.3.0}/src/mlschema/strategies/app/text.py +0 -0
  83. {mlschema-0.2.1 → mlschema-0.3.0}/src/mlschema/strategies/domain/__init__.py +0 -0
  84. {mlschema-0.2.1 → mlschema-0.3.0}/src/mlschema/strategies/domain/boolean_field.py +0 -0
  85. {mlschema-0.2.1 → mlschema-0.3.0}/src/mlschema/strategies/domain/category_field.py +0 -0
  86. {mlschema-0.2.1 → mlschema-0.3.0}/src/mlschema/strategies/domain/date_field.py +0 -0
  87. {mlschema-0.2.1 → mlschema-0.3.0}/src/mlschema/strategies/domain/field_types.py +0 -0
  88. {mlschema-0.2.1 → mlschema-0.3.0}/src/mlschema/strategies/domain/number_field.py +0 -0
  89. {mlschema-0.2.1 → mlschema-0.3.0}/src/mlschema/strategies/domain/onehot_category_field.py +0 -0
  90. {mlschema-0.2.1 → mlschema-0.3.0}/src/mlschema/strategies/domain/text_field.py +0 -0
  91. {mlschema-0.2.1 → mlschema-0.3.0}/test/architecture/test_public_surface.py +0 -0
  92. {mlschema-0.2.1 → mlschema-0.3.0}/test/architecture/test_test_suite_structure.py +0 -0
  93. {mlschema-0.2.1 → mlschema-0.3.0}/test/load/test_infer_schema_load.py +0 -0
  94. {mlschema-0.2.1 → mlschema-0.3.0}/test/unit/test_base_field_contract.py +0 -0
  95. {mlschema-0.2.1 → mlschema-0.3.0}/test/unit/test_builtin_dtype_matrix.py +0 -0
  96. {mlschema-0.2.1 → mlschema-0.3.0}/test/unit/test_dtype_normalization.py +0 -0
  97. {mlschema-0.2.1 → mlschema-0.3.0}/test/unit/test_factory_and_context.py +0 -0
  98. {mlschema-0.2.1 → mlschema-0.3.0}/test/unit/test_kind_api.py +0 -0
@@ -177,10 +177,23 @@ cython_debug/
177
177
  # Custom
178
178
  .vscode/
179
179
  .history/
180
- uv.lock
181
180
 
182
181
  # Graphify
183
182
  graphify-out/
184
183
 
185
184
  # Codex
186
185
  .codex/
186
+
187
+ # Product sites
188
+ !/landing/src/lib/
189
+ !/landing/src/lib/**
190
+ node_modules/
191
+ .astro/
192
+ .wrangler/
193
+ playwright-report/
194
+ test-results/
195
+
196
+ # Local browser verification
197
+ .playwright-cli/
198
+ output/playwright/
199
+ .vite/
@@ -1,6 +1,6 @@
1
1
  # Authors and Contributors
2
2
 
3
- MLSchema is made possible by the contributions of the following individuals and organizations.
3
+ MLschema is made possible by the contributions of the following individuals and organizations.
4
4
 
5
5
  ## Core Maintainers
6
6
 
@@ -35,7 +35,7 @@ See [CONTRIBUTING.md](CONTRIBUTING.md) for contribution guidelines.
35
35
 
36
36
  ### Dependencies
37
37
 
38
- MLSchema is built on the shoulders of giants. We are grateful to the maintainers and contributors of:
38
+ MLschema is built on the shoulders of giants. We are grateful to the maintainers and contributors of:
39
39
 
40
40
  - **pandas** - The foundational data analysis library
41
41
  - **Pydantic** - Data validation using Python type annotations
@@ -44,7 +44,7 @@ For a complete list of dependencies and their licenses, see [THIRD_PARTY_LICENSE
44
44
 
45
45
  ### Inspiration
46
46
 
47
- MLSchema draws inspiration from:
47
+ MLschema draws inspiration from:
48
48
 
49
49
  - **JSON Schema** specification
50
50
  - **FastAPI** for its excellent use of Pydantic
@@ -0,0 +1,80 @@
1
+ # Contributing to MLschema
2
+
3
+ Use Python 3.14 and uv for the library. Websites use Vite+ (`vp`), backed by pnpm 12.
4
+ Supported Node.js versions: 22.18+, 24.11+, or 26+ (the corresponding major versions).
5
+
6
+ ## Library
7
+
8
+ ```bash
9
+ uv sync --locked --group dev
10
+ uv run pre-commit install
11
+ uv run ruff check .
12
+ uv run ruff format --check .
13
+ uv run pyright
14
+ uv run pytest
15
+ uv build
16
+ ```
17
+
18
+ Start with the tests for the behavior you change, then run the full suite. Test both
19
+ success and error paths. Keep each source file at or below 300 lines. Update the
20
+ affected documentation when contracts or known limitations change; include actual
21
+ verification and any remaining blockers in the change description.
22
+
23
+ The public API starts at `mlschema.infer_schema`. Builders inspect pandas columns;
24
+ strict field models validate their output. Custom kinds pair a `BaseField` subclass
25
+ with a builder through `kind(model=..., infer=...)`. Keep rules in their owning
26
+ module so callers share them.
27
+
28
+ Series columns use local ids and scalar-kind validators. Only the parent maps to
29
+ a backend feature. `with_positional_mappings` converts named targets when a consumer
30
+ needs input positions; it preserves the original field list.
31
+
32
+ ## Websites
33
+
34
+ ```bash
35
+ vp install --frozen-lockfile
36
+ vp run dev:landing
37
+ vp run dev:docs
38
+ vp run dev:playground
39
+ vp run build
40
+ ```
41
+
42
+ Landing, Astro Starlight documentation and the Python playground live in separate
43
+ workspace packages. Use the eshkra product identity and original assets under
44
+ `brand/`. Verify narrow/wide screens and both themes when changing presentation.
45
+
46
+ Local URLs: landing `http://127.0.0.1:4330`, docs `http://127.0.0.1:4331`,
47
+ playground `http://127.0.0.1:10011`. Start each dev task in its own terminal.
48
+ Install the [Vite+ CLI](https://viteplus.dev/guide/) first, or bootstrap with
49
+ `pnpm install --frozen-lockfile` and use `pnpm exec vp` for these commands.
50
+
51
+ ## Release
52
+
53
+ `pyproject.toml` owns the Python package version. Update it and the documentation
54
+ changelog together. Breaking contracts need migration notes. Keep `uv.lock` and
55
+ `pnpm-lock.yaml` synchronized with dependency changes.
56
+
57
+ CI tests Python on Ubuntu and Windows, checks types/formatting, builds distributions,
58
+ checks their PyPI description and builds all sites. A successful push to `main`
59
+ publishes a version absent from PyPI and creates its GitHub release. The verified
60
+ site artifacts deploy to Cloudflare Workers from `main`.
61
+
62
+ Repository secrets:
63
+
64
+ - `PYPI_API_TOKEN`: scoped to the MLschema PyPI project.
65
+ - `CLOUDFLARE_API_TOKEN`: permission to deploy Workers and their custom domains.
66
+ - `CLOUDFLARE_ACCOUNT_ID`: the account containing the eshkra zone.
67
+
68
+ Domains are declared in each site's `wrangler.jsonc`. Docs, landing and playground
69
+ use `docs.mlschema.eshkra.dev`, `mlschema.eshkra.dev` and
70
+ `playground.mlschema.eshkra.dev`. A manual CI run on `main` can redeploy sites.
71
+
72
+ Publish MLschema 0.3.0 before updating downstream registry locks such as mlbundle's.
73
+ To verify the coordinated change before publication, install the local package
74
+ into the consumer environment with `uv pip install --python .venv --no-deps -e ../mlschema`
75
+ and run its checks with `uv run --no-sync`. This is a local test setup; refresh the
76
+ consumer's ordinary registry lock with `uv sync --all-extras` after publication.
77
+
78
+ Open focused pull requests describing the behavior change and actual verification.
79
+ Use Conventional Commit titles. Report security issues through the process in
80
+ [SECURITY.md](https://github.com/UlloaSP/mlschema/blob/main/SECURITY.md).
@@ -0,0 +1,208 @@
1
+ Metadata-Version: 2.5
2
+ Name: mlschema
3
+ Version: 0.3.0
4
+ Summary: Infer validated, frontend-ready field schemas from pandas DataFrames.
5
+ Project-URL: Homepage, https://mlschema.eshkra.dev/
6
+ Project-URL: Documentation, https://docs.mlschema.eshkra.dev/
7
+ Project-URL: Playground, https://playground.mlschema.eshkra.dev/
8
+ Project-URL: Repository, https://github.com/UlloaSP/mlschema
9
+ Project-URL: Bug Tracker, https://github.com/UlloaSP/mlschema/issues
10
+ Project-URL: Source Code, https://github.com/UlloaSP/mlschema
11
+ Project-URL: Changelog, https://docs.mlschema.eshkra.dev/changelog/
12
+ Project-URL: Discussions, https://github.com/UlloaSP/mlschema/discussions
13
+ Project-URL: Funding, https://github.com/sponsors/UlloaSP
14
+ Project-URL: Release Notes, https://github.com/UlloaSP/mlschema/releases
15
+ Author-email: Pablo Ulloa Santín <pablo.ulloa.santin@udc.es>
16
+ Maintainer-email: Pablo Ulloa Santín <pablo.ulloa.santin@udc.es>
17
+ License: MIT
18
+ License-File: AUTHORS.md
19
+ License-File: LICENSE
20
+ Keywords: data-contracts,data-science,data-validation,dataframe,field-schema,form-generation,frontend-forms,frontend-integration,json,json-schema,machine-learning,mlops,pandas,pydantic,schema-inference,validation
21
+ Classifier: Development Status :: 4 - Beta
22
+ Classifier: Framework :: Pydantic
23
+ Classifier: Framework :: Pydantic :: 2
24
+ Classifier: Intended Audience :: Developers
25
+ Classifier: Intended Audience :: Information Technology
26
+ Classifier: Intended Audience :: Science/Research
27
+ Classifier: License :: OSI Approved :: MIT License
28
+ Classifier: Natural Language :: English
29
+ Classifier: Operating System :: OS Independent
30
+ Classifier: Programming Language :: Python :: 3
31
+ Classifier: Programming Language :: Python :: 3 :: Only
32
+ Classifier: Programming Language :: Python :: 3.14
33
+ Classifier: Programming Language :: Python :: Implementation :: CPython
34
+ Classifier: Topic :: Scientific/Engineering
35
+ Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
36
+ Classifier: Topic :: Scientific/Engineering :: Information Analysis
37
+ Classifier: Topic :: Software Development :: Code Generators
38
+ Classifier: Topic :: Software Development :: Libraries :: Python Modules
39
+ Classifier: Topic :: Utilities
40
+ Classifier: Typing :: Typed
41
+ Requires-Python: <3.15,>=3.14
42
+ Requires-Dist: pandas<4.0.0,>=3.0.3
43
+ Requires-Dist: pydantic<3.0.0,>=2.13.4
44
+ Description-Content-Type: text/markdown
45
+
46
+ <p align="center">
47
+ <img src="https://raw.githubusercontent.com/UlloaSP/mlschema/main/brand/mlschema.png" alt="" height="112" />
48
+ </p>
49
+
50
+ <h1 align="center">
51
+ <picture>
52
+ <source media="(prefers-color-scheme: dark)" srcset="https://raw.githubusercontent.com/UlloaSP/mlschema/main/brand/wordmark-dark.svg" />
53
+ <img src="https://raw.githubusercontent.com/UlloaSP/mlschema/main/brand/wordmark-light.svg" alt="MLschema" height="52" />
54
+ </picture>
55
+ </h1>
56
+
57
+ <p align="center">From pandas DataFrames to validated field schemas.</p>
58
+
59
+ <p align="center">
60
+ <a href="https://mlschema.eshkra.dev/"><img src="https://img.shields.io/badge/website-303039?style=flat&amp;logo=astro&amp;logoColor=ff6a1a" alt="Website" /></a>
61
+ <a href="https://docs.mlschema.eshkra.dev/"><img src="https://img.shields.io/badge/docs-303039?style=flat&amp;logo=readthedocs&amp;logoColor=ff6a1a" alt="Documentation" /></a>
62
+ <a href="https://playground.mlschema.eshkra.dev/"><img src="https://img.shields.io/badge/playground-303039?style=flat&amp;logo=python&amp;logoColor=ff6a1a" alt="Playground" /></a>
63
+ <a href="https://pypi.org/project/mlschema/"><img src="https://img.shields.io/pypi/v/mlschema?style=flat&amp;logo=pypi&amp;logoColor=white&amp;labelColor=303039&amp;color=b73d00" alt="PyPI version" /></a>
64
+ <a href="https://github.com/UlloaSP/mlschema"><img src="https://img.shields.io/badge/source-303039?style=flat&amp;logo=github&amp;logoColor=white" alt="Source on GitHub" /></a>
65
+ <a href="https://github.com/UlloaSP/mlschema/actions/workflows/ci.yml"><img src="https://img.shields.io/github/actions/workflow/status/UlloaSP/mlschema/ci.yml?branch=main&amp;style=flat&amp;label=CI&amp;labelColor=303039" alt="CI status" /></a>
66
+ <a href="https://github.com/UlloaSP/mlschema/blob/main/LICENSE"><img src="https://img.shields.io/badge/license-MIT-b73d00?style=flat&amp;labelColor=303039" alt="MIT license" /></a>
67
+ <a href="https://eshkra.dev"><img src="https://img.shields.io/badge/part_of-eshkra-b73d00?style=flat&amp;labelColor=303039" alt="Part of eshkra" /></a>
68
+ </p>
69
+
70
+ MLschema is a Python library for deriving validated field schemas from pandas DataFrames. It reads column names, dtypes, categories and nullability, then validates the inferred fields with Pydantic and returns a JSON-compatible list.
71
+
72
+ Use the result with [MLform](https://mlform.eshkra.dev/), include it in [MLbundle](https://github.com/UlloaSP/mlbundle), or consume it in your own frontend. Start with built-in inference, refine individual fields, or add domain-specific builders and kinds.
73
+
74
+ ## Why infer a field schema?
75
+
76
+ The data pipeline already knows whether an input is a number, a date or a category. Writing those definitions again in a frontend creates another place for the model and its inputs to drift apart.
77
+
78
+ MLschema turns that information into a starting contract with explicit backend mappings. Your application supplies product-specific labels, bounds and defaults; the same validation path checks both inferred and customized fields. Inference runs locally and the resulting list is ordinary data, independent of a rendering framework.
79
+
80
+ ## Installation
81
+
82
+ > MLschema is pre-1.0. Public contracts may change between minor releases. Requires Python 3.14 (`>=3.14,<3.15`); supported pandas 3 and Pydantic 2 versions are installed as dependencies.
83
+
84
+ ```bash
85
+ uv add mlschema
86
+ ```
87
+
88
+ Or install from PyPI with `pip install mlschema`.
89
+
90
+ See the [release and upgrade notes](https://docs.mlschema.eshkra.dev/changelog/) when updating an existing integration. Version 0.3 changes the series field contract.
91
+
92
+ ## Quick start
93
+
94
+ Create a DataFrame with the dtypes your inputs should use:
95
+
96
+ ```python
97
+ import json
98
+
99
+ import pandas as pd
100
+ from mlschema import infer_schema
101
+
102
+ frame = pd.DataFrame(
103
+ {
104
+ "age": [28, 41],
105
+ "plan": pd.Categorical(["free", "pro"]),
106
+ "active": [True, False],
107
+ }
108
+ )
109
+
110
+ fields = infer_schema(frame)
111
+ print(json.dumps(fields, indent=2))
112
+ ```
113
+
114
+ The result is a field list, ready to serialize:
115
+
116
+ ```json
117
+ [
118
+ {"kind": "number", "label": "age", "required": true, "mappedTo": "age", "step": 1.0},
119
+ {"kind": "category", "label": "plan", "required": true, "mappedTo": "plan", "options": ["free", "pro"]},
120
+ {"kind": "boolean", "label": "active", "required": true, "mappedTo": "active"}
121
+ ]
122
+ ```
123
+
124
+ Pass it to MLform as the schema's `fields` property. Your application owns reports, transport and model execution.
125
+
126
+ ## Choose your customization
127
+
128
+ | API | Use it to |
129
+ | --- | --- |
130
+ | `infer_schema(frame)` | Infer fields using the built-in kinds. |
131
+ | `overrides={...}` | Refine a column's label, bounds or other supported properties before validation. |
132
+ | `builders=[...]` | Supply inference logic for an existing kind, before the built-in builders. |
133
+ | `kinds=[kind(model=..., infer=...)]` | Add a strict field model and the builder that produces it. |
134
+ | `with_positional_mappings(fields, feature_names)` | Copy a field list and convert mappings into an explicit model input order. |
135
+
136
+ For example, refine a label and bounds, then adapt the mappings for a model that consumes a feature vector:
137
+
138
+ ```python
139
+ from mlschema import with_positional_mappings
140
+
141
+ fields = infer_schema(
142
+ frame,
143
+ overrides={"age": {"label": "Age", "min": 0, "max": 120}},
144
+ )
145
+ positional = with_positional_mappings(fields, ["plan", "age", "active"])
146
+ ```
147
+
148
+ The `age` field keeps its displayed label `Age`; its target changes from `"age"` to position `1` in the returned copy. The helper rewrites mappings, preserving field order, series columns and one-hot grouping. It leaves the original list unchanged.
149
+
150
+ All application-facing functions and extension types come from `mlschema`. Public inference exceptions come from `mlschema.core`; see the [Python API](https://docs.mlschema.eshkra.dev/reference/api/).
151
+
152
+ ## What is included?
153
+
154
+ - Inference for text, numbers, categories, booleans, dates and two-axis series.
155
+ - One-hot groups from named binary columns such as `color__red` and `color__blue`.
156
+ - Explicit backend mappings: names for named columns, positions for positional columns.
157
+ - Series output with ordered `columns[]`, compatible with MLform.
158
+ - Strict field validation, overrides, custom builders and custom kinds.
159
+ - A typed, function-first API that runs entirely in your Python process.
160
+
161
+ DataFrame dtypes matter: categorical options come from `category`, and date inference accepts specific datetime dtypes. Columns unclaimed by earlier builders reach the text fallback. See the [field-kind reference](https://docs.mlschema.eshkra.dev/schema/field-kinds/) for supported inputs and limits.
162
+
163
+ ## Some notes
164
+
165
+ MLschema owns field inference, validation and explicit mappings. Your application owns rendering, report definitions, model training and execution. The output is a field list, not a JSON Schema document or a complete MLform schema.
166
+
167
+ Empty DataFrames are rejected, and invalid builder output or overrides fail validation. Inference does not establish that a dataset is suitable for a model. The returned list can contain category values, so treat it as part of your data contract when sharing it.
168
+
169
+ ## Documentation
170
+
171
+ Full documentation lives at [docs.mlschema.eshkra.dev](https://docs.mlschema.eshkra.dev/).
172
+
173
+ - [Installation](https://docs.mlschema.eshkra.dev/getting-started/installation/)
174
+ - [Quick start](https://docs.mlschema.eshkra.dev/getting-started/quick-start/)
175
+ - [Field contract](https://docs.mlschema.eshkra.dev/schema/overview/)
176
+ - [Backend mappings](https://docs.mlschema.eshkra.dev/schema/mappings/)
177
+ - [Custom builders and kinds](https://docs.mlschema.eshkra.dev/guides/extensions/)
178
+ - [Python API](https://docs.mlschema.eshkra.dev/reference/api/)
179
+
180
+ Try the examples in the [Python playground](https://playground.mlschema.eshkra.dev/). It runs the repository's Python code in an experimental browser environment; its dependency limits are documented in the [playground guide](https://github.com/UlloaSP/mlschema/blob/main/playground/README.md).
181
+
182
+ ## Contributing
183
+
184
+ Python development uses [uv](https://docs.astral.sh/uv/), Ruff, Pyright and pytest:
185
+
186
+ ```bash
187
+ uv sync --locked --group dev
188
+ uv run ruff check .
189
+ uv run ruff format --check .
190
+ uv run pyright
191
+ uv run pytest
192
+ uv build
193
+ ```
194
+
195
+ The landing page, documentation and playground use [Vite+](https://viteplus.dev/guide/) (`vp`) with a pnpm workspace. This tooling is separate from the Python package:
196
+
197
+ ```bash
198
+ vp install --frozen-lockfile
199
+ vp run build
200
+ ```
201
+
202
+ Read [CONTRIBUTING.md](https://github.com/UlloaSP/mlschema/blob/main/CONTRIBUTING.md) for local development and release setup.
203
+
204
+ Run `vp run dev:playground` to serve the local Python playground at `http://127.0.0.1:10011`. The [playground guide](https://github.com/UlloaSP/mlschema/blob/main/playground/README.md) covers examples and verification commands.
205
+
206
+ ## License
207
+
208
+ MIT
@@ -0,0 +1,163 @@
1
+ <p align="center">
2
+ <img src="https://raw.githubusercontent.com/UlloaSP/mlschema/main/brand/mlschema.png" alt="" height="112" />
3
+ </p>
4
+
5
+ <h1 align="center">
6
+ <picture>
7
+ <source media="(prefers-color-scheme: dark)" srcset="https://raw.githubusercontent.com/UlloaSP/mlschema/main/brand/wordmark-dark.svg" />
8
+ <img src="https://raw.githubusercontent.com/UlloaSP/mlschema/main/brand/wordmark-light.svg" alt="MLschema" height="52" />
9
+ </picture>
10
+ </h1>
11
+
12
+ <p align="center">From pandas DataFrames to validated field schemas.</p>
13
+
14
+ <p align="center">
15
+ <a href="https://mlschema.eshkra.dev/"><img src="https://img.shields.io/badge/website-303039?style=flat&amp;logo=astro&amp;logoColor=ff6a1a" alt="Website" /></a>
16
+ <a href="https://docs.mlschema.eshkra.dev/"><img src="https://img.shields.io/badge/docs-303039?style=flat&amp;logo=readthedocs&amp;logoColor=ff6a1a" alt="Documentation" /></a>
17
+ <a href="https://playground.mlschema.eshkra.dev/"><img src="https://img.shields.io/badge/playground-303039?style=flat&amp;logo=python&amp;logoColor=ff6a1a" alt="Playground" /></a>
18
+ <a href="https://pypi.org/project/mlschema/"><img src="https://img.shields.io/pypi/v/mlschema?style=flat&amp;logo=pypi&amp;logoColor=white&amp;labelColor=303039&amp;color=b73d00" alt="PyPI version" /></a>
19
+ <a href="https://github.com/UlloaSP/mlschema"><img src="https://img.shields.io/badge/source-303039?style=flat&amp;logo=github&amp;logoColor=white" alt="Source on GitHub" /></a>
20
+ <a href="https://github.com/UlloaSP/mlschema/actions/workflows/ci.yml"><img src="https://img.shields.io/github/actions/workflow/status/UlloaSP/mlschema/ci.yml?branch=main&amp;style=flat&amp;label=CI&amp;labelColor=303039" alt="CI status" /></a>
21
+ <a href="https://github.com/UlloaSP/mlschema/blob/main/LICENSE"><img src="https://img.shields.io/badge/license-MIT-b73d00?style=flat&amp;labelColor=303039" alt="MIT license" /></a>
22
+ <a href="https://eshkra.dev"><img src="https://img.shields.io/badge/part_of-eshkra-b73d00?style=flat&amp;labelColor=303039" alt="Part of eshkra" /></a>
23
+ </p>
24
+
25
+ MLschema is a Python library for deriving validated field schemas from pandas DataFrames. It reads column names, dtypes, categories and nullability, then validates the inferred fields with Pydantic and returns a JSON-compatible list.
26
+
27
+ Use the result with [MLform](https://mlform.eshkra.dev/), include it in [MLbundle](https://github.com/UlloaSP/mlbundle), or consume it in your own frontend. Start with built-in inference, refine individual fields, or add domain-specific builders and kinds.
28
+
29
+ ## Why infer a field schema?
30
+
31
+ The data pipeline already knows whether an input is a number, a date or a category. Writing those definitions again in a frontend creates another place for the model and its inputs to drift apart.
32
+
33
+ MLschema turns that information into a starting contract with explicit backend mappings. Your application supplies product-specific labels, bounds and defaults; the same validation path checks both inferred and customized fields. Inference runs locally and the resulting list is ordinary data, independent of a rendering framework.
34
+
35
+ ## Installation
36
+
37
+ > MLschema is pre-1.0. Public contracts may change between minor releases. Requires Python 3.14 (`>=3.14,<3.15`); supported pandas 3 and Pydantic 2 versions are installed as dependencies.
38
+
39
+ ```bash
40
+ uv add mlschema
41
+ ```
42
+
43
+ Or install from PyPI with `pip install mlschema`.
44
+
45
+ See the [release and upgrade notes](https://docs.mlschema.eshkra.dev/changelog/) when updating an existing integration. Version 0.3 changes the series field contract.
46
+
47
+ ## Quick start
48
+
49
+ Create a DataFrame with the dtypes your inputs should use:
50
+
51
+ ```python
52
+ import json
53
+
54
+ import pandas as pd
55
+ from mlschema import infer_schema
56
+
57
+ frame = pd.DataFrame(
58
+ {
59
+ "age": [28, 41],
60
+ "plan": pd.Categorical(["free", "pro"]),
61
+ "active": [True, False],
62
+ }
63
+ )
64
+
65
+ fields = infer_schema(frame)
66
+ print(json.dumps(fields, indent=2))
67
+ ```
68
+
69
+ The result is a field list, ready to serialize:
70
+
71
+ ```json
72
+ [
73
+ {"kind": "number", "label": "age", "required": true, "mappedTo": "age", "step": 1.0},
74
+ {"kind": "category", "label": "plan", "required": true, "mappedTo": "plan", "options": ["free", "pro"]},
75
+ {"kind": "boolean", "label": "active", "required": true, "mappedTo": "active"}
76
+ ]
77
+ ```
78
+
79
+ Pass it to MLform as the schema's `fields` property. Your application owns reports, transport and model execution.
80
+
81
+ ## Choose your customization
82
+
83
+ | API | Use it to |
84
+ | --- | --- |
85
+ | `infer_schema(frame)` | Infer fields using the built-in kinds. |
86
+ | `overrides={...}` | Refine a column's label, bounds or other supported properties before validation. |
87
+ | `builders=[...]` | Supply inference logic for an existing kind, before the built-in builders. |
88
+ | `kinds=[kind(model=..., infer=...)]` | Add a strict field model and the builder that produces it. |
89
+ | `with_positional_mappings(fields, feature_names)` | Copy a field list and convert mappings into an explicit model input order. |
90
+
91
+ For example, refine a label and bounds, then adapt the mappings for a model that consumes a feature vector:
92
+
93
+ ```python
94
+ from mlschema import with_positional_mappings
95
+
96
+ fields = infer_schema(
97
+ frame,
98
+ overrides={"age": {"label": "Age", "min": 0, "max": 120}},
99
+ )
100
+ positional = with_positional_mappings(fields, ["plan", "age", "active"])
101
+ ```
102
+
103
+ The `age` field keeps its displayed label `Age`; its target changes from `"age"` to position `1` in the returned copy. The helper rewrites mappings, preserving field order, series columns and one-hot grouping. It leaves the original list unchanged.
104
+
105
+ All application-facing functions and extension types come from `mlschema`. Public inference exceptions come from `mlschema.core`; see the [Python API](https://docs.mlschema.eshkra.dev/reference/api/).
106
+
107
+ ## What is included?
108
+
109
+ - Inference for text, numbers, categories, booleans, dates and two-axis series.
110
+ - One-hot groups from named binary columns such as `color__red` and `color__blue`.
111
+ - Explicit backend mappings: names for named columns, positions for positional columns.
112
+ - Series output with ordered `columns[]`, compatible with MLform.
113
+ - Strict field validation, overrides, custom builders and custom kinds.
114
+ - A typed, function-first API that runs entirely in your Python process.
115
+
116
+ DataFrame dtypes matter: categorical options come from `category`, and date inference accepts specific datetime dtypes. Columns unclaimed by earlier builders reach the text fallback. See the [field-kind reference](https://docs.mlschema.eshkra.dev/schema/field-kinds/) for supported inputs and limits.
117
+
118
+ ## Some notes
119
+
120
+ MLschema owns field inference, validation and explicit mappings. Your application owns rendering, report definitions, model training and execution. The output is a field list, not a JSON Schema document or a complete MLform schema.
121
+
122
+ Empty DataFrames are rejected, and invalid builder output or overrides fail validation. Inference does not establish that a dataset is suitable for a model. The returned list can contain category values, so treat it as part of your data contract when sharing it.
123
+
124
+ ## Documentation
125
+
126
+ Full documentation lives at [docs.mlschema.eshkra.dev](https://docs.mlschema.eshkra.dev/).
127
+
128
+ - [Installation](https://docs.mlschema.eshkra.dev/getting-started/installation/)
129
+ - [Quick start](https://docs.mlschema.eshkra.dev/getting-started/quick-start/)
130
+ - [Field contract](https://docs.mlschema.eshkra.dev/schema/overview/)
131
+ - [Backend mappings](https://docs.mlschema.eshkra.dev/schema/mappings/)
132
+ - [Custom builders and kinds](https://docs.mlschema.eshkra.dev/guides/extensions/)
133
+ - [Python API](https://docs.mlschema.eshkra.dev/reference/api/)
134
+
135
+ Try the examples in the [Python playground](https://playground.mlschema.eshkra.dev/). It runs the repository's Python code in an experimental browser environment; its dependency limits are documented in the [playground guide](https://github.com/UlloaSP/mlschema/blob/main/playground/README.md).
136
+
137
+ ## Contributing
138
+
139
+ Python development uses [uv](https://docs.astral.sh/uv/), Ruff, Pyright and pytest:
140
+
141
+ ```bash
142
+ uv sync --locked --group dev
143
+ uv run ruff check .
144
+ uv run ruff format --check .
145
+ uv run pyright
146
+ uv run pytest
147
+ uv build
148
+ ```
149
+
150
+ The landing page, documentation and playground use [Vite+](https://viteplus.dev/guide/) (`vp`) with a pnpm workspace. This tooling is separate from the Python package:
151
+
152
+ ```bash
153
+ vp install --frozen-lockfile
154
+ vp run build
155
+ ```
156
+
157
+ Read [CONTRIBUTING.md](https://github.com/UlloaSP/mlschema/blob/main/CONTRIBUTING.md) for local development and release setup.
158
+
159
+ Run `vp run dev:playground` to serve the local Python playground at `http://127.0.0.1:10011`. The [playground guide](https://github.com/UlloaSP/mlschema/blob/main/playground/README.md) covers examples and verification commands.
160
+
161
+ ## License
162
+
163
+ MIT
@@ -11,7 +11,7 @@ We release patches for security vulnerabilities for the following versions:
11
11
 
12
12
  ## Reporting a Vulnerability
13
13
 
14
- We take the security of MLSchema seriously. If you believe you have found a security vulnerability, please report it to us as described below.
14
+ We take the security of MLschema seriously. If you believe you have found a security vulnerability, please report it to us as described below.
15
15
 
16
16
  ### Please Do NOT
17
17
 
@@ -39,7 +39,7 @@ We take the security of MLSchema seriously. If you believe you have found a secu
39
39
 
40
40
  ## Security Best Practices
41
41
 
42
- When using MLSchema, we recommend:
42
+ When using MLschema, we recommend:
43
43
 
44
44
  ### Input Validation
45
45
 
@@ -83,7 +83,7 @@ df.columns = [col.replace(" ", "_").lower() for col in df.columns]
83
83
 
84
84
  ### Data Processing
85
85
 
86
- MLSchema processes pandas DataFrames to generate JSON schemas. It:
86
+ MLschema processes pandas DataFrames to generate JSON schemas. It:
87
87
 
88
88
  - **Does not** modify the original DataFrame
89
89
  - **Does not** send data over the network
@@ -92,7 +92,7 @@ MLSchema processes pandas DataFrames to generate JSON schemas. It:
92
92
 
93
93
  ### Type Safety
94
94
 
95
- MLSchema uses Pydantic for validation, which provides:
95
+ MLschema uses Pydantic for validation, which provides:
96
96
 
97
97
  - Type checking and validation
98
98
  - Protection against invalid data structures
@@ -100,7 +100,7 @@ MLSchema uses Pydantic for validation, which provides:
100
100
 
101
101
  ### Known Limitations
102
102
 
103
- - MLSchema assumes DataFrames come from trusted sources
103
+ - MLschema assumes DataFrames come from trusted sources
104
104
  - Column names are used as-is in the output schema
105
105
  - Very large DataFrames may cause memory issues
106
106
 
@@ -128,11 +128,11 @@ Security updates are announced via:
128
128
 
129
129
  - GitHub Security Advisories: <https://github.com/UlloaSP/mlschema/security/advisories>
130
130
  - Release notes: <https://github.com/UlloaSP/mlschema/releases>
131
- - Changelog: [docs/changelog.md](docs/changelog.md)
131
+ - Changelog: [release notes](https://docs.mlschema.eshkra.dev/changelog/)
132
132
 
133
133
  ## Dependency Security
134
134
 
135
- MLSchema depends on:
135
+ MLschema depends on:
136
136
 
137
137
  ### Runtime Dependencies
138
138
 
@@ -179,7 +179,7 @@ When contributing code:
179
179
 
180
180
  ## Security-Related Configuration
181
181
 
182
- MLSchema has minimal configuration. Security-relevant settings:
182
+ MLschema has minimal configuration. Security-relevant settings:
183
183
 
184
184
  ```python
185
185
  # Example: Safe usage pattern
@@ -200,7 +200,7 @@ schema = mls.build(dataframe)
200
200
  For security concerns:
201
201
 
202
202
  - **Email**: <pablo.ulloa.santin@udc.es>
203
- - **Subject**: `[SECURITY] MLSchema Vulnerability Report`
203
+ - **Subject**: `[SECURITY] MLschema Vulnerability Report`
204
204
 
205
205
  For general questions:
206
206
 
@@ -209,14 +209,14 @@ For general questions:
209
209
 
210
210
  ## Attribution
211
211
 
212
- We appreciate responsible security researchers who help keep MLSchema safe. With your permission, we will:
212
+ We appreciate responsible security researchers who help keep MLschema safe. With your permission, we will:
213
213
 
214
214
  - Credit you in the security advisory
215
215
  - Add your name to our hall of fame (if you wish)
216
216
  - Provide a reference for your responsible disclosure
217
217
 
218
- Thank you for helping keep MLSchema and its users safe! 🔒
218
+ Thank you for helping keep MLschema and its users safe! 🔒
219
219
 
220
220
  ---
221
221
 
222
- **Last Updated**: June 1, 2026
222
+ **Last Updated**: October 19, 2026