predikit 0.4.5__tar.gz → 0.5.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.
- {predikit-0.4.5 → predikit-0.5.0}/.gitignore +6 -5
- {predikit-0.4.5 → predikit-0.5.0}/CHANGELOG.md +10 -0
- {predikit-0.4.5 → predikit-0.5.0}/PKG-INFO +2 -2
- {predikit-0.4.5 → predikit-0.5.0}/pyproject.toml +2 -2
- {predikit-0.4.5 → predikit-0.5.0}/src/predikit/__init__.py +1 -1
- {predikit-0.4.5 → predikit-0.5.0}/src/predikit/cli.py +2 -2
- {predikit-0.4.5 → predikit-0.5.0}/src/predikit/loaders/snowflake.py +40 -19
- {predikit-0.4.5 → predikit-0.5.0}/src/predikit/tool.py +18 -3
- {predikit-0.4.5 → predikit-0.5.0}/tests/test_cli.py +1 -1
- {predikit-0.4.5 → predikit-0.5.0}/tests/test_ensemble.py +1 -1
- {predikit-0.4.5 → predikit-0.5.0}/tests/test_loaders_snowflake.py +62 -22
- {predikit-0.4.5 → predikit-0.5.0}/tests/test_tool.py +21 -0
- {predikit-0.4.5 → predikit-0.5.0}/uv.lock +2 -2
- predikit-0.4.5/mlruns/1/models/m-27a74bc0ab2f40e09dc3d6c4f026cc1e/artifacts/MLmodel +0 -23
- predikit-0.4.5/mlruns/1/models/m-27a74bc0ab2f40e09dc3d6c4f026cc1e/artifacts/conda.yaml +0 -22
- predikit-0.4.5/mlruns/1/models/m-27a74bc0ab2f40e09dc3d6c4f026cc1e/artifacts/model.skops +0 -0
- predikit-0.4.5/mlruns/1/models/m-27a74bc0ab2f40e09dc3d6c4f026cc1e/artifacts/python_env.yaml +0 -7
- predikit-0.4.5/mlruns/1/models/m-27a74bc0ab2f40e09dc3d6c4f026cc1e/artifacts/requirements.txt +0 -15
- predikit-0.4.5/mlruns/1/models/m-28173468f0874040a705d2d3820a4f5c/artifacts/MLmodel +0 -23
- predikit-0.4.5/mlruns/1/models/m-28173468f0874040a705d2d3820a4f5c/artifacts/conda.yaml +0 -22
- predikit-0.4.5/mlruns/1/models/m-28173468f0874040a705d2d3820a4f5c/artifacts/model.skops +0 -0
- predikit-0.4.5/mlruns/1/models/m-28173468f0874040a705d2d3820a4f5c/artifacts/python_env.yaml +0 -7
- predikit-0.4.5/mlruns/1/models/m-28173468f0874040a705d2d3820a4f5c/artifacts/requirements.txt +0 -15
- predikit-0.4.5/mlruns/1/models/m-3eabd93b6ac447808321a1d58fef2b9b/artifacts/MLmodel +0 -23
- predikit-0.4.5/mlruns/1/models/m-3eabd93b6ac447808321a1d58fef2b9b/artifacts/conda.yaml +0 -22
- predikit-0.4.5/mlruns/1/models/m-3eabd93b6ac447808321a1d58fef2b9b/artifacts/model.skops +0 -0
- predikit-0.4.5/mlruns/1/models/m-3eabd93b6ac447808321a1d58fef2b9b/artifacts/python_env.yaml +0 -7
- predikit-0.4.5/mlruns/1/models/m-3eabd93b6ac447808321a1d58fef2b9b/artifacts/requirements.txt +0 -15
- predikit-0.4.5/mlruns/1/models/m-4816da14ba9c47c2b69d7d959f186d4e/artifacts/MLmodel +0 -23
- predikit-0.4.5/mlruns/1/models/m-4816da14ba9c47c2b69d7d959f186d4e/artifacts/conda.yaml +0 -22
- predikit-0.4.5/mlruns/1/models/m-4816da14ba9c47c2b69d7d959f186d4e/artifacts/model.skops +0 -0
- predikit-0.4.5/mlruns/1/models/m-4816da14ba9c47c2b69d7d959f186d4e/artifacts/python_env.yaml +0 -7
- predikit-0.4.5/mlruns/1/models/m-4816da14ba9c47c2b69d7d959f186d4e/artifacts/requirements.txt +0 -15
- predikit-0.4.5/mlruns/1/models/m-4deda032d5434d74888edc6f4df2e642/artifacts/MLmodel +0 -23
- predikit-0.4.5/mlruns/1/models/m-4deda032d5434d74888edc6f4df2e642/artifacts/conda.yaml +0 -22
- predikit-0.4.5/mlruns/1/models/m-4deda032d5434d74888edc6f4df2e642/artifacts/model.skops +0 -0
- predikit-0.4.5/mlruns/1/models/m-4deda032d5434d74888edc6f4df2e642/artifacts/python_env.yaml +0 -7
- predikit-0.4.5/mlruns/1/models/m-4deda032d5434d74888edc6f4df2e642/artifacts/requirements.txt +0 -15
- predikit-0.4.5/mlruns/1/models/m-6988b8fc759d4a6d9ba42b3ef9c5bbad/artifacts/MLmodel +0 -23
- predikit-0.4.5/mlruns/1/models/m-6988b8fc759d4a6d9ba42b3ef9c5bbad/artifacts/conda.yaml +0 -22
- predikit-0.4.5/mlruns/1/models/m-6988b8fc759d4a6d9ba42b3ef9c5bbad/artifacts/model.skops +0 -0
- predikit-0.4.5/mlruns/1/models/m-6988b8fc759d4a6d9ba42b3ef9c5bbad/artifacts/python_env.yaml +0 -7
- predikit-0.4.5/mlruns/1/models/m-6988b8fc759d4a6d9ba42b3ef9c5bbad/artifacts/requirements.txt +0 -15
- predikit-0.4.5/mlruns/1/models/m-885ed3e972dd4583aa9b4c518b369316/artifacts/MLmodel +0 -23
- predikit-0.4.5/mlruns/1/models/m-885ed3e972dd4583aa9b4c518b369316/artifacts/conda.yaml +0 -22
- predikit-0.4.5/mlruns/1/models/m-885ed3e972dd4583aa9b4c518b369316/artifacts/model.skops +0 -0
- predikit-0.4.5/mlruns/1/models/m-885ed3e972dd4583aa9b4c518b369316/artifacts/python_env.yaml +0 -7
- predikit-0.4.5/mlruns/1/models/m-885ed3e972dd4583aa9b4c518b369316/artifacts/requirements.txt +0 -15
- predikit-0.4.5/mlruns/1/models/m-936aa30d653c4e79920e98dd23b2e352/artifacts/MLmodel +0 -23
- predikit-0.4.5/mlruns/1/models/m-936aa30d653c4e79920e98dd23b2e352/artifacts/conda.yaml +0 -22
- predikit-0.4.5/mlruns/1/models/m-936aa30d653c4e79920e98dd23b2e352/artifacts/model.skops +0 -0
- predikit-0.4.5/mlruns/1/models/m-936aa30d653c4e79920e98dd23b2e352/artifacts/python_env.yaml +0 -7
- predikit-0.4.5/mlruns/1/models/m-936aa30d653c4e79920e98dd23b2e352/artifacts/requirements.txt +0 -15
- predikit-0.4.5/mlruns/1/models/m-9c8120122eb744128b3c91e724536d7e/artifacts/MLmodel +0 -23
- predikit-0.4.5/mlruns/1/models/m-9c8120122eb744128b3c91e724536d7e/artifacts/conda.yaml +0 -22
- predikit-0.4.5/mlruns/1/models/m-9c8120122eb744128b3c91e724536d7e/artifacts/model.skops +0 -0
- predikit-0.4.5/mlruns/1/models/m-9c8120122eb744128b3c91e724536d7e/artifacts/python_env.yaml +0 -7
- predikit-0.4.5/mlruns/1/models/m-9c8120122eb744128b3c91e724536d7e/artifacts/requirements.txt +0 -15
- predikit-0.4.5/mlruns/1/models/m-bc53e68577e64ed5b64b173ae23eb99d/artifacts/MLmodel +0 -23
- predikit-0.4.5/mlruns/1/models/m-bc53e68577e64ed5b64b173ae23eb99d/artifacts/conda.yaml +0 -22
- predikit-0.4.5/mlruns/1/models/m-bc53e68577e64ed5b64b173ae23eb99d/artifacts/model.skops +0 -0
- predikit-0.4.5/mlruns/1/models/m-bc53e68577e64ed5b64b173ae23eb99d/artifacts/python_env.yaml +0 -7
- predikit-0.4.5/mlruns/1/models/m-bc53e68577e64ed5b64b173ae23eb99d/artifacts/requirements.txt +0 -15
- predikit-0.4.5/mlruns/1/models/m-d5e1b20e8a9a4414b74b95d613362ae0/artifacts/MLmodel +0 -23
- predikit-0.4.5/mlruns/1/models/m-d5e1b20e8a9a4414b74b95d613362ae0/artifacts/conda.yaml +0 -22
- predikit-0.4.5/mlruns/1/models/m-d5e1b20e8a9a4414b74b95d613362ae0/artifacts/model.skops +0 -0
- predikit-0.4.5/mlruns/1/models/m-d5e1b20e8a9a4414b74b95d613362ae0/artifacts/python_env.yaml +0 -7
- predikit-0.4.5/mlruns/1/models/m-d5e1b20e8a9a4414b74b95d613362ae0/artifacts/requirements.txt +0 -15
- predikit-0.4.5/mlruns/1/models/m-e368d86129cb416cbdc24ce1f4d4062b/artifacts/MLmodel +0 -23
- predikit-0.4.5/mlruns/1/models/m-e368d86129cb416cbdc24ce1f4d4062b/artifacts/conda.yaml +0 -22
- predikit-0.4.5/mlruns/1/models/m-e368d86129cb416cbdc24ce1f4d4062b/artifacts/model.skops +0 -0
- predikit-0.4.5/mlruns/1/models/m-e368d86129cb416cbdc24ce1f4d4062b/artifacts/python_env.yaml +0 -7
- predikit-0.4.5/mlruns/1/models/m-e368d86129cb416cbdc24ce1f4d4062b/artifacts/requirements.txt +0 -15
- predikit-0.4.5/mlruns/1/models/m-e71aea9d1d2646f0970b78d821200719/artifacts/MLmodel +0 -23
- predikit-0.4.5/mlruns/1/models/m-e71aea9d1d2646f0970b78d821200719/artifacts/conda.yaml +0 -22
- predikit-0.4.5/mlruns/1/models/m-e71aea9d1d2646f0970b78d821200719/artifacts/model.skops +0 -0
- predikit-0.4.5/mlruns/1/models/m-e71aea9d1d2646f0970b78d821200719/artifacts/python_env.yaml +0 -7
- predikit-0.4.5/mlruns/1/models/m-e71aea9d1d2646f0970b78d821200719/artifacts/requirements.txt +0 -15
- predikit-0.4.5/mlruns/1/models/m-f374e93dce4f4be498ccf04e1fb1ac9e/artifacts/MLmodel +0 -23
- predikit-0.4.5/mlruns/1/models/m-f374e93dce4f4be498ccf04e1fb1ac9e/artifacts/conda.yaml +0 -22
- predikit-0.4.5/mlruns/1/models/m-f374e93dce4f4be498ccf04e1fb1ac9e/artifacts/model.skops +0 -0
- predikit-0.4.5/mlruns/1/models/m-f374e93dce4f4be498ccf04e1fb1ac9e/artifacts/python_env.yaml +0 -7
- predikit-0.4.5/mlruns/1/models/m-f374e93dce4f4be498ccf04e1fb1ac9e/artifacts/requirements.txt +0 -15
- {predikit-0.4.5 → predikit-0.5.0}/.claude/settings.local.json +0 -0
- {predikit-0.4.5 → predikit-0.5.0}/.github/ISSUE_TEMPLATE/bug_report.md +0 -0
- {predikit-0.4.5 → predikit-0.5.0}/.github/ISSUE_TEMPLATE/feature_request.md +0 -0
- {predikit-0.4.5 → predikit-0.5.0}/.github/workflows/publish.yml +0 -0
- {predikit-0.4.5 → predikit-0.5.0}/.github/workflows/test.yml +0 -0
- {predikit-0.4.5 → predikit-0.5.0}/.pre-commit-config.yaml +0 -0
- {predikit-0.4.5 → predikit-0.5.0}/CLAUDE.md +0 -0
- {predikit-0.4.5 → predikit-0.5.0}/CONTRIBUTING.md +0 -0
- {predikit-0.4.5 → predikit-0.5.0}/LICENSE +0 -0
- {predikit-0.4.5 → predikit-0.5.0}/README.md +0 -0
- {predikit-0.4.5 → predikit-0.5.0}/docs/logo.gif +0 -0
- {predikit-0.4.5 → predikit-0.5.0}/docs/logo.png +0 -0
- {predikit-0.4.5 → predikit-0.5.0}/examples/01_basic_sklearn.py +0 -0
- {predikit-0.4.5 → predikit-0.5.0}/examples/02_xgboost_regression.py +0 -0
- {predikit-0.4.5 → predikit-0.5.0}/examples/03_orlando_real_estate.py +0 -0
- {predikit-0.4.5 → predikit-0.5.0}/examples/04_confidence_routing.py +0 -0
- {predikit-0.4.5 → predikit-0.5.0}/examples/05_multi_model_ensemble.py +0 -0
- {predikit-0.4.5 → predikit-0.5.0}/examples/06_mlflow_loader.py +0 -0
- {predikit-0.4.5 → predikit-0.5.0}/examples/07_snowflake_loader.py +0 -0
- {predikit-0.4.5 → predikit-0.5.0}/src/predikit/coerce.py +0 -0
- {predikit-0.4.5 → predikit-0.5.0}/src/predikit/ensemble.py +0 -0
- {predikit-0.4.5 → predikit-0.5.0}/src/predikit/exceptions.py +0 -0
- {predikit-0.4.5 → predikit-0.5.0}/src/predikit/exporters/__init__.py +0 -0
- {predikit-0.4.5 → predikit-0.5.0}/src/predikit/exporters/langchain.py +0 -0
- {predikit-0.4.5 → predikit-0.5.0}/src/predikit/exporters/openai.py +0 -0
- {predikit-0.4.5 → predikit-0.5.0}/src/predikit/introspect.py +0 -0
- {predikit-0.4.5 → predikit-0.5.0}/src/predikit/loaders/__init__.py +0 -0
- {predikit-0.4.5 → predikit-0.5.0}/src/predikit/loaders/mlflow.py +0 -0
- {predikit-0.4.5 → predikit-0.5.0}/src/predikit/registry.py +0 -0
- {predikit-0.4.5 → predikit-0.5.0}/tests/__init__.py +0 -0
- {predikit-0.4.5 → predikit-0.5.0}/tests/test_coerce.py +0 -0
- {predikit-0.4.5 → predikit-0.5.0}/tests/test_confidence.py +0 -0
- {predikit-0.4.5 → predikit-0.5.0}/tests/test_exporters_openai.py +0 -0
- {predikit-0.4.5 → predikit-0.5.0}/tests/test_introspect.py +0 -0
- {predikit-0.4.5 → predikit-0.5.0}/tests/test_loaders_mlflow.py +0 -0
- {predikit-0.4.5 → predikit-0.5.0}/tests/test_logging.py +0 -0
- {predikit-0.4.5 → predikit-0.5.0}/tests/test_registry.py +0 -0
- {predikit-0.4.5 → predikit-0.5.0}/tests/test_weighted_ensemble.py +0 -0
|
@@ -6,6 +6,16 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
|
|
6
6
|
|
|
7
7
|
## [Unreleased]
|
|
8
8
|
|
|
9
|
+
## [0.5.0] - 2026-07-01
|
|
10
|
+
|
|
11
|
+
### Fixed
|
|
12
|
+
- Improved `ModelTool` input coercion for optional scalar annotations like `float | None`, `bool | None`, `int | None`, and `str | None`
|
|
13
|
+
- Added test coverage for optional scalar string inputs to keep LLM-friendly coercion consistent across modern Pydantic schemas
|
|
14
|
+
|
|
15
|
+
### Changed
|
|
16
|
+
- Removed generated MLflow run artifacts from source control and ignored future `mlruns/` outputs
|
|
17
|
+
- Cleaned package metadata and CLI text to avoid Unicode dash rendering issues in terminals and package indexes
|
|
18
|
+
|
|
9
19
|
## [0.4.5] - 2026-07-01
|
|
10
20
|
|
|
11
21
|
### Fixed
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: predikit
|
|
3
|
-
Version: 0.
|
|
4
|
-
Summary: Wrap any trained sklearn/XGBoost model as an LLM-callable tool
|
|
3
|
+
Version: 0.5.0
|
|
4
|
+
Summary: Wrap any trained sklearn/XGBoost model as an LLM-callable tool: auto-generated JSON schemas, Pydantic I/O, OpenAI & LangChain ready, zero boilerplate.
|
|
5
5
|
Project-URL: Homepage, https://github.com/Tejas-TA/predikit
|
|
6
6
|
Project-URL: Repository, https://github.com/Tejas-TA/predikit
|
|
7
7
|
Project-URL: Documentation, https://github.com/Tejas-TA/predikit#readme
|
|
@@ -4,8 +4,8 @@ build-backend = "hatchling.build"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "predikit"
|
|
7
|
-
version = "0.
|
|
8
|
-
description = "Wrap any trained sklearn/XGBoost model as an LLM-callable tool
|
|
7
|
+
version = "0.5.0"
|
|
8
|
+
description = "Wrap any trained sklearn/XGBoost model as an LLM-callable tool: auto-generated JSON schemas, Pydantic I/O, OpenAI & LangChain ready, zero boilerplate."
|
|
9
9
|
readme = "README.md"
|
|
10
10
|
license = {text = "MIT"}
|
|
11
11
|
requires-python = ">=3.10"
|
|
@@ -16,7 +16,7 @@ if _CLICK_AVAILABLE:
|
|
|
16
16
|
|
|
17
17
|
@click.group()
|
|
18
18
|
def cli() -> None:
|
|
19
|
-
"""predikit
|
|
19
|
+
"""predikit: ML model utilities for LLM agents."""
|
|
20
20
|
|
|
21
21
|
@cli.command()
|
|
22
22
|
@click.argument("model_path", type=click.Path(exists=True))
|
|
@@ -53,7 +53,7 @@ if _CLICK_AVAILABLE:
|
|
|
53
53
|
for fname in meta["feature_names"]:
|
|
54
54
|
click.echo(f" {fname}")
|
|
55
55
|
else:
|
|
56
|
-
click.echo("Feature names: (none
|
|
56
|
+
click.echo("Feature names: (none - fit the model with a named DataFrame to enable)")
|
|
57
57
|
|
|
58
58
|
if meta["classes"] is not None:
|
|
59
59
|
click.echo(f"Classes: {meta['classes']}")
|
|
@@ -13,26 +13,47 @@ except ImportError:
|
|
|
13
13
|
Registry = None # type: ignore[assignment,misc]
|
|
14
14
|
|
|
15
15
|
|
|
16
|
-
class _SnowflakeShim:
|
|
17
|
-
"""Wraps a Snowflake Model Registry model to look like an sklearn estimator."""
|
|
16
|
+
class _SnowflakeShim:
|
|
17
|
+
"""Wraps a Snowflake Model Registry model to look like an sklearn estimator."""
|
|
18
18
|
|
|
19
|
-
def __init__(
|
|
20
|
-
self, sf_model: Any, output_method: str = "predict", classes: list | None = None
|
|
21
|
-
) -> None:
|
|
22
|
-
if not callable(getattr(sf_model, output_method, None)):
|
|
23
|
-
raise AttributeError(
|
|
24
|
-
f"Snowflake model object has no callable method {output_method!r}."
|
|
25
|
-
)
|
|
26
|
-
self._model = sf_model
|
|
27
|
-
self._method = output_method
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
19
|
+
def __init__(
|
|
20
|
+
self, sf_model: Any, output_method: str = "predict", classes: list | None = None
|
|
21
|
+
) -> None:
|
|
22
|
+
if not callable(getattr(sf_model, output_method, None)):
|
|
23
|
+
raise AttributeError(
|
|
24
|
+
f"Snowflake model object has no callable method {output_method!r}."
|
|
25
|
+
)
|
|
26
|
+
self._model = sf_model
|
|
27
|
+
self._method = output_method
|
|
28
|
+
underlying = getattr(sf_model, "_model_impl", None)
|
|
29
|
+
if underlying is not None:
|
|
30
|
+
underlying = getattr(underlying, "sklearn_model", None)
|
|
31
|
+
|
|
32
|
+
if classes is None and underlying is not None and hasattr(underlying, "classes_"):
|
|
33
|
+
classes = list(underlying.classes_)
|
|
34
|
+
|
|
35
|
+
if classes is not None:
|
|
36
|
+
self.classes_ = classes
|
|
37
|
+
|
|
38
|
+
if underlying is not None:
|
|
39
|
+
if hasattr(underlying, "feature_names_in_"):
|
|
40
|
+
self.feature_names_in_ = underlying.feature_names_in_
|
|
41
|
+
if hasattr(underlying, "n_features_in_"):
|
|
42
|
+
self.n_features_in_ = underlying.n_features_in_
|
|
43
|
+
|
|
44
|
+
def predict(self, X: Any) -> np.ndarray:
|
|
45
|
+
result = getattr(self._model, self._method)(X)
|
|
46
|
+
if hasattr(result, "to_numpy"):
|
|
47
|
+
return np.asarray(result.to_numpy()).flatten()
|
|
48
|
+
return np.asarray(result).flatten()
|
|
49
|
+
|
|
50
|
+
def predict_proba(self, X: Any) -> np.ndarray:
|
|
51
|
+
if callable(getattr(self._model, "predict_proba", None)):
|
|
52
|
+
return np.asarray(self._model.predict_proba(X))
|
|
53
|
+
raise NotImplementedError(
|
|
54
|
+
"predict_proba is not available for this Snowflake model object. "
|
|
55
|
+
"The underlying model may not expose it."
|
|
56
|
+
)
|
|
36
57
|
|
|
37
58
|
|
|
38
59
|
def from_snowflake(
|
|
@@ -4,7 +4,8 @@ import asyncio
|
|
|
4
4
|
import time
|
|
5
5
|
import warnings
|
|
6
6
|
from collections.abc import Callable
|
|
7
|
-
from
|
|
7
|
+
from types import UnionType
|
|
8
|
+
from typing import Any, Union, get_args, get_origin
|
|
8
9
|
|
|
9
10
|
import numpy as np
|
|
10
11
|
from pydantic import BaseModel
|
|
@@ -17,6 +18,7 @@ from .introspect import introspect
|
|
|
17
18
|
|
|
18
19
|
_VALID_ON_LOW_CONFIDENCE = {"warn", "raise", "fallback"}
|
|
19
20
|
_SCALAR_TYPES = (bool, int, float, str)
|
|
21
|
+
_NONE_TYPE = type(None)
|
|
20
22
|
|
|
21
23
|
|
|
22
24
|
class ModelTool:
|
|
@@ -143,9 +145,10 @@ class ModelTool:
|
|
|
143
145
|
for k, v in input_dict.items():
|
|
144
146
|
field = fields.get(k)
|
|
145
147
|
annotation = getattr(field, "annotation", None) if field else None
|
|
146
|
-
|
|
148
|
+
scalar_type = _scalar_type(annotation)
|
|
149
|
+
if scalar_type is not None and v is not None:
|
|
147
150
|
try:
|
|
148
|
-
result[k] = coerce_value(v,
|
|
151
|
+
result[k] = coerce_value(v, scalar_type)
|
|
149
152
|
except (ValueError, TypeError):
|
|
150
153
|
result[k] = v
|
|
151
154
|
else:
|
|
@@ -162,3 +165,15 @@ class ModelTool:
|
|
|
162
165
|
except ImportError:
|
|
163
166
|
pass
|
|
164
167
|
return np.array([features])
|
|
168
|
+
|
|
169
|
+
|
|
170
|
+
def _scalar_type(annotation: Any) -> type | None:
|
|
171
|
+
if annotation in _SCALAR_TYPES:
|
|
172
|
+
return annotation
|
|
173
|
+
|
|
174
|
+
if get_origin(annotation) in (Union, UnionType):
|
|
175
|
+
args = [arg for arg in get_args(annotation) if arg is not _NONE_TYPE]
|
|
176
|
+
if len(args) == 1:
|
|
177
|
+
return _scalar_type(args[0])
|
|
178
|
+
|
|
179
|
+
return None
|
|
@@ -19,7 +19,7 @@ def runner():
|
|
|
19
19
|
|
|
20
20
|
@pytest.fixture
|
|
21
21
|
def reg_pkl(tmp_path):
|
|
22
|
-
"""Regression model fitted with named features
|
|
22
|
+
"""Regression model fitted with named features, so it has feature_names_in_."""
|
|
23
23
|
X, y = load_iris(return_X_y=True, as_frame=True)
|
|
24
24
|
model = LinearRegression().fit(X, y.astype(float))
|
|
25
25
|
path = tmp_path / "reg.pkl"
|
|
@@ -84,7 +84,7 @@ def test_mean_averages_numeric_output(reg_tools):
|
|
|
84
84
|
ensemble = ModelEnsemble(tools=reg_tools, name="mean_e", description="", strategy="mean")
|
|
85
85
|
result = ensemble.invoke(SAMPLE)
|
|
86
86
|
assert "value" in result
|
|
87
|
-
# Two identical LinearRegression models
|
|
87
|
+
# Two identical LinearRegression models mean the average equals either model's output.
|
|
88
88
|
single = reg_tools[0].invoke(SAMPLE)
|
|
89
89
|
assert abs(result["value"] - single["value"]) < 1e-6
|
|
90
90
|
|
|
@@ -24,7 +24,7 @@ class MemberInput(BaseModel):
|
|
|
24
24
|
# ---------------------------------------------------------------------------
|
|
25
25
|
|
|
26
26
|
|
|
27
|
-
class TestSnowflakeShim:
|
|
27
|
+
class TestSnowflakeShim:
|
|
28
28
|
def test_predict_calls_correct_method(self):
|
|
29
29
|
mock_model = MagicMock()
|
|
30
30
|
mock_model.predict.return_value = np.array([1])
|
|
@@ -41,12 +41,12 @@ class TestSnowflakeShim:
|
|
|
41
41
|
mock_model.predict_proba.assert_called_once()
|
|
42
42
|
assert result[0] == pytest.approx(0.27, abs=1e-6)
|
|
43
43
|
|
|
44
|
-
def test_classes_optional(self):
|
|
45
|
-
shim_no_classes = _SnowflakeShim(MagicMock())
|
|
46
|
-
assert not hasattr(shim_no_classes, "classes_")
|
|
47
|
-
|
|
48
|
-
shim_with_classes = _SnowflakeShim(MagicMock(), classes=[0, 1])
|
|
49
|
-
assert shim_with_classes.classes_ == [0, 1]
|
|
44
|
+
def test_classes_optional(self):
|
|
45
|
+
shim_no_classes = _SnowflakeShim(MagicMock(spec=["predict"]))
|
|
46
|
+
assert not hasattr(shim_no_classes, "classes_")
|
|
47
|
+
|
|
48
|
+
shim_with_classes = _SnowflakeShim(MagicMock(spec=["predict"]), classes=[0, 1])
|
|
49
|
+
assert shim_with_classes.classes_ == [0, 1]
|
|
50
50
|
|
|
51
51
|
def test_predict_flattens_dataframe_result(self):
|
|
52
52
|
import pandas as pd
|
|
@@ -58,13 +58,24 @@ class TestSnowflakeShim:
|
|
|
58
58
|
assert result.ndim == 1
|
|
59
59
|
assert result[0] == 1
|
|
60
60
|
|
|
61
|
-
def test_predict_flattens_numpy_result(self):
|
|
62
|
-
mock_model = MagicMock()
|
|
63
|
-
mock_model.predict.return_value = np.array([[0.73]])
|
|
64
|
-
shim = _SnowflakeShim(mock_model)
|
|
65
|
-
result = shim.predict(np.array([[1.0]]))
|
|
66
|
-
assert result.ndim == 1
|
|
67
|
-
assert result[0] == pytest.approx(0.73)
|
|
61
|
+
def test_predict_flattens_numpy_result(self):
|
|
62
|
+
mock_model = MagicMock()
|
|
63
|
+
mock_model.predict.return_value = np.array([[0.73]])
|
|
64
|
+
shim = _SnowflakeShim(mock_model)
|
|
65
|
+
result = shim.predict(np.array([[1.0]]))
|
|
66
|
+
assert result.ndim == 1
|
|
67
|
+
assert result[0] == pytest.approx(0.73)
|
|
68
|
+
|
|
69
|
+
def test_predict_proba_delegates_to_underlying_model(self):
|
|
70
|
+
mock_model = MagicMock()
|
|
71
|
+
mock_model.predict_proba.return_value = np.array([[0.2, 0.8]])
|
|
72
|
+
shim = _SnowflakeShim(mock_model)
|
|
73
|
+
|
|
74
|
+
result = shim.predict_proba(np.array([[1.0, 2.0, 3.0]]))
|
|
75
|
+
|
|
76
|
+
mock_model.predict_proba.assert_called_once()
|
|
77
|
+
assert result.shape == (1, 2)
|
|
78
|
+
assert result[0, 1] == pytest.approx(0.8)
|
|
68
79
|
|
|
69
80
|
|
|
70
81
|
# ---------------------------------------------------------------------------
|
|
@@ -80,7 +91,7 @@ def _make_mock_session_and_model(return_value):
|
|
|
80
91
|
return mock_session, mock_sf_model
|
|
81
92
|
|
|
82
93
|
|
|
83
|
-
class TestFromSnowflake:
|
|
94
|
+
class TestFromSnowflake:
|
|
84
95
|
def test_roundtrip_invoke(self):
|
|
85
96
|
mock_session, mock_sf_model = _make_mock_session_and_model(np.array([1]))
|
|
86
97
|
|
|
@@ -123,10 +134,10 @@ class TestFromSnowflake:
|
|
|
123
134
|
mock_registry.get_model.assert_called_once_with("VACATION_CHURN")
|
|
124
135
|
mock_registry.get_model.return_value.version.assert_called_once_with("V3")
|
|
125
136
|
|
|
126
|
-
def test_custom_output_method_forwarded(self):
|
|
127
|
-
mock_session = MagicMock()
|
|
128
|
-
mock_sf_model = MagicMock()
|
|
129
|
-
mock_sf_model.score.return_value = np.array([0.87])
|
|
137
|
+
def test_custom_output_method_forwarded(self):
|
|
138
|
+
mock_session = MagicMock()
|
|
139
|
+
mock_sf_model = MagicMock()
|
|
140
|
+
mock_sf_model.score.return_value = np.array([0.87])
|
|
130
141
|
|
|
131
142
|
with patch("predikit.loaders.snowflake.Registry") as MockRegistry:
|
|
132
143
|
MockRegistry.return_value.get_model.return_value.version.return_value = mock_sf_model
|
|
@@ -143,9 +154,38 @@ class TestFromSnowflake:
|
|
|
143
154
|
output_method="score",
|
|
144
155
|
)
|
|
145
156
|
|
|
146
|
-
result = tool.invoke({"tenure_months": 12.0, "trips_last_year": 5.0, "avg_spend": 300.0})
|
|
147
|
-
assert result["score"] == pytest.approx(0.87, abs=1e-6)
|
|
148
|
-
mock_sf_model.score.assert_called_once()
|
|
157
|
+
result = tool.invoke({"tenure_months": 12.0, "trips_last_year": 5.0, "avg_spend": 300.0})
|
|
158
|
+
assert result["score"] == pytest.approx(0.87, abs=1e-6)
|
|
159
|
+
mock_sf_model.score.assert_called_once()
|
|
160
|
+
|
|
161
|
+
def test_confidence_routing_uses_predict_proba(self):
|
|
162
|
+
mock_session = MagicMock()
|
|
163
|
+
mock_sf_model = MagicMock()
|
|
164
|
+
mock_sf_model.predict.return_value = np.array([1])
|
|
165
|
+
mock_sf_model.predict_proba.return_value = np.array([[0.6, 0.4]])
|
|
166
|
+
mock_sf_model.classes_ = [0, 1]
|
|
167
|
+
|
|
168
|
+
with patch("predikit.loaders.snowflake.Registry") as MockRegistry:
|
|
169
|
+
MockRegistry.return_value.get_model.return_value.version.return_value = mock_sf_model
|
|
170
|
+
|
|
171
|
+
tool = from_snowflake(
|
|
172
|
+
session=mock_session,
|
|
173
|
+
model_name="CHURN",
|
|
174
|
+
model_version="V1",
|
|
175
|
+
name="churn",
|
|
176
|
+
description="Churn.",
|
|
177
|
+
input_schema=MemberInput,
|
|
178
|
+
output_name="churn_class",
|
|
179
|
+
output_description="Churn class",
|
|
180
|
+
confidence_threshold=0.9,
|
|
181
|
+
on_low_confidence="warn",
|
|
182
|
+
)
|
|
183
|
+
|
|
184
|
+
result = tool.invoke({"tenure_months": 12.0, "trips_last_year": 5.0, "avg_spend": 300.0})
|
|
185
|
+
assert result["churn_class"] == 1
|
|
186
|
+
assert result["_low_confidence"] is True
|
|
187
|
+
assert result["_confidence"] == pytest.approx(0.6)
|
|
188
|
+
mock_sf_model.predict_proba.assert_called_once()
|
|
149
189
|
|
|
150
190
|
def test_model_tool_kwargs_forwarded(self):
|
|
151
191
|
mock_session, mock_sf_model = _make_mock_session_and_model(np.array([1]))
|
|
@@ -86,6 +86,27 @@ def test_invoke_bool_string_coerced_through_invoke():
|
|
|
86
86
|
assert tool.invoke({"value": 3.0, "active": "on"})["result"] in [0, 1]
|
|
87
87
|
|
|
88
88
|
|
|
89
|
+
def test_invoke_optional_scalar_strings_coerced_through_invoke():
|
|
90
|
+
class MaybeFlagInput(BaseModel):
|
|
91
|
+
value: float | None = None
|
|
92
|
+
active: bool | None = None
|
|
93
|
+
|
|
94
|
+
X = np.array([[1.0, 0], [2.0, 1], [3.0, 0], [4.0, 1]])
|
|
95
|
+
y = np.array([0, 1, 0, 1])
|
|
96
|
+
clf = LogisticRegression().fit(X, y)
|
|
97
|
+
|
|
98
|
+
tool = ModelTool(
|
|
99
|
+
model=clf,
|
|
100
|
+
name="maybe_flag_test",
|
|
101
|
+
description="test optional scalar coercion",
|
|
102
|
+
input_schema=MaybeFlagInput,
|
|
103
|
+
output_name="result",
|
|
104
|
+
output_description="predicted class",
|
|
105
|
+
)
|
|
106
|
+
|
|
107
|
+
assert tool.invoke({"value": "3.0", "active": "yes"})["result"] in [0, 1]
|
|
108
|
+
|
|
109
|
+
|
|
89
110
|
SAMPLE = {"sepal_length": 5.1, "sepal_width": 3.5, "petal_length": 1.4, "petal_width": 0.2}
|
|
90
111
|
|
|
91
112
|
|
|
@@ -560,7 +560,7 @@ wheels = [
|
|
|
560
560
|
|
|
561
561
|
[[package]]
|
|
562
562
|
name = "colorama"
|
|
563
|
-
version = "0.
|
|
563
|
+
version = "0.5.0"
|
|
564
564
|
source = { registry = "https://pypi.org/simple" }
|
|
565
565
|
sdist = { url = "https://files.pythonhosted.org/packages/d8/53/6f443c9a4a8358a93a6792e2acffb9d9d5cb0a5cfd8802644b7b1c9a02e4/colorama-0.4.6.tar.gz", hash = "sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44", size = 27697, upload-time = "2022-10-25T02:36:22.414Z" }
|
|
566
566
|
wheels = [
|
|
@@ -2984,7 +2984,7 @@ wheels = [
|
|
|
2984
2984
|
|
|
2985
2985
|
[[package]]
|
|
2986
2986
|
name = "predikit"
|
|
2987
|
-
version = "0.4.
|
|
2987
|
+
version = "0.4.6"
|
|
2988
2988
|
source = { editable = "." }
|
|
2989
2989
|
dependencies = [
|
|
2990
2990
|
{ name = "numpy", version = "2.2.6", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.11'" },
|
|
@@ -1,23 +0,0 @@
|
|
|
1
|
-
artifact_path: file:C:/AI/predikit/mlruns/1/models/m-27a74bc0ab2f40e09dc3d6c4f026cc1e/artifacts
|
|
2
|
-
flavors:
|
|
3
|
-
python_function:
|
|
4
|
-
env:
|
|
5
|
-
conda: conda.yaml
|
|
6
|
-
virtualenv: python_env.yaml
|
|
7
|
-
loader_module: mlflow.sklearn
|
|
8
|
-
model_path: model.skops
|
|
9
|
-
predict_fn: predict
|
|
10
|
-
python_version: 3.13.5
|
|
11
|
-
sklearn:
|
|
12
|
-
code: null
|
|
13
|
-
pickled_model: model.skops
|
|
14
|
-
serialization_format: skops
|
|
15
|
-
sklearn_version: 1.7.2
|
|
16
|
-
skops_trusted_types: null
|
|
17
|
-
mlflow_version: 3.14.0
|
|
18
|
-
model_id: m-27a74bc0ab2f40e09dc3d6c4f026cc1e
|
|
19
|
-
model_size_bytes: 9581
|
|
20
|
-
model_uuid: m-27a74bc0ab2f40e09dc3d6c4f026cc1e
|
|
21
|
-
prompts: null
|
|
22
|
-
run_id: cf4fc6366185416489e3a600ec4d813d
|
|
23
|
-
utc_time_created: '2026-06-20 21:48:25.168465'
|
|
@@ -1,22 +0,0 @@
|
|
|
1
|
-
channels:
|
|
2
|
-
- conda-forge
|
|
3
|
-
dependencies:
|
|
4
|
-
- python=3.13.5
|
|
5
|
-
- pip
|
|
6
|
-
- pip:
|
|
7
|
-
- mlflow==3.14.0
|
|
8
|
-
- annotated-types==0.7.0
|
|
9
|
-
- joblib==1.5.3
|
|
10
|
-
- numpy==2.2.6; python_full_version < "3.11"
|
|
11
|
-
- numpy==2.4.6; python_full_version >= "3.11"
|
|
12
|
-
- pydantic-core==2.46.4
|
|
13
|
-
- pydantic==2.13.4
|
|
14
|
-
- scikit-learn==1.7.2
|
|
15
|
-
- scipy==1.15.3; python_full_version < "3.11"
|
|
16
|
-
- scipy==1.17.1; python_full_version == "3.11.*"
|
|
17
|
-
- scipy==1.18.0; python_full_version >= "3.12"
|
|
18
|
-
- skops==0.14.0
|
|
19
|
-
- threadpoolctl==3.6.0
|
|
20
|
-
- typing-extensions==4.15.0
|
|
21
|
-
- typing-inspection==0.4.2
|
|
22
|
-
name: mlflow-env
|
|
Binary file
|
predikit-0.4.5/mlruns/1/models/m-27a74bc0ab2f40e09dc3d6c4f026cc1e/artifacts/requirements.txt
DELETED
|
@@ -1,15 +0,0 @@
|
|
|
1
|
-
mlflow==3.14.0
|
|
2
|
-
annotated-types==0.7.0
|
|
3
|
-
joblib==1.5.3
|
|
4
|
-
numpy==2.2.6; python_full_version < "3.11"
|
|
5
|
-
numpy==2.4.6; python_full_version >= "3.11"
|
|
6
|
-
pydantic-core==2.46.4
|
|
7
|
-
pydantic==2.13.4
|
|
8
|
-
scikit-learn==1.7.2
|
|
9
|
-
scipy==1.15.3; python_full_version < "3.11"
|
|
10
|
-
scipy==1.17.1; python_full_version == "3.11.*"
|
|
11
|
-
scipy==1.18.0; python_full_version >= "3.12"
|
|
12
|
-
skops==0.14.0
|
|
13
|
-
threadpoolctl==3.6.0
|
|
14
|
-
typing-extensions==4.15.0
|
|
15
|
-
typing-inspection==0.4.2
|
|
@@ -1,23 +0,0 @@
|
|
|
1
|
-
artifact_path: file:C:/AI/predikit/mlruns/1/models/m-28173468f0874040a705d2d3820a4f5c/artifacts
|
|
2
|
-
flavors:
|
|
3
|
-
python_function:
|
|
4
|
-
env:
|
|
5
|
-
conda: conda.yaml
|
|
6
|
-
virtualenv: python_env.yaml
|
|
7
|
-
loader_module: mlflow.sklearn
|
|
8
|
-
model_path: model.skops
|
|
9
|
-
predict_fn: predict
|
|
10
|
-
python_version: 3.13.5
|
|
11
|
-
sklearn:
|
|
12
|
-
code: null
|
|
13
|
-
pickled_model: model.skops
|
|
14
|
-
serialization_format: skops
|
|
15
|
-
sklearn_version: 1.7.2
|
|
16
|
-
skops_trusted_types: null
|
|
17
|
-
mlflow_version: 3.14.0
|
|
18
|
-
model_id: m-28173468f0874040a705d2d3820a4f5c
|
|
19
|
-
model_size_bytes: 9581
|
|
20
|
-
model_uuid: m-28173468f0874040a705d2d3820a4f5c
|
|
21
|
-
prompts: null
|
|
22
|
-
run_id: c0cfa92fb12c454fb2715f1ef48be4ff
|
|
23
|
-
utc_time_created: '2026-06-20 21:47:19.880624'
|
|
@@ -1,22 +0,0 @@
|
|
|
1
|
-
channels:
|
|
2
|
-
- conda-forge
|
|
3
|
-
dependencies:
|
|
4
|
-
- python=3.13.5
|
|
5
|
-
- pip
|
|
6
|
-
- pip:
|
|
7
|
-
- mlflow==3.14.0
|
|
8
|
-
- annotated-types==0.7.0
|
|
9
|
-
- joblib==1.5.3
|
|
10
|
-
- numpy==2.2.6; python_full_version < "3.11"
|
|
11
|
-
- numpy==2.4.6; python_full_version >= "3.11"
|
|
12
|
-
- pydantic-core==2.46.4
|
|
13
|
-
- pydantic==2.13.4
|
|
14
|
-
- scikit-learn==1.7.2
|
|
15
|
-
- scipy==1.15.3; python_full_version < "3.11"
|
|
16
|
-
- scipy==1.17.1; python_full_version == "3.11.*"
|
|
17
|
-
- scipy==1.18.0; python_full_version >= "3.12"
|
|
18
|
-
- skops==0.14.0
|
|
19
|
-
- threadpoolctl==3.6.0
|
|
20
|
-
- typing-extensions==4.15.0
|
|
21
|
-
- typing-inspection==0.4.2
|
|
22
|
-
name: mlflow-env
|
|
Binary file
|
predikit-0.4.5/mlruns/1/models/m-28173468f0874040a705d2d3820a4f5c/artifacts/requirements.txt
DELETED
|
@@ -1,15 +0,0 @@
|
|
|
1
|
-
mlflow==3.14.0
|
|
2
|
-
annotated-types==0.7.0
|
|
3
|
-
joblib==1.5.3
|
|
4
|
-
numpy==2.2.6; python_full_version < "3.11"
|
|
5
|
-
numpy==2.4.6; python_full_version >= "3.11"
|
|
6
|
-
pydantic-core==2.46.4
|
|
7
|
-
pydantic==2.13.4
|
|
8
|
-
scikit-learn==1.7.2
|
|
9
|
-
scipy==1.15.3; python_full_version < "3.11"
|
|
10
|
-
scipy==1.17.1; python_full_version == "3.11.*"
|
|
11
|
-
scipy==1.18.0; python_full_version >= "3.12"
|
|
12
|
-
skops==0.14.0
|
|
13
|
-
threadpoolctl==3.6.0
|
|
14
|
-
typing-extensions==4.15.0
|
|
15
|
-
typing-inspection==0.4.2
|
|
@@ -1,23 +0,0 @@
|
|
|
1
|
-
artifact_path: file:c:/AI/predikit/mlruns/1/models/m-3eabd93b6ac447808321a1d58fef2b9b/artifacts
|
|
2
|
-
flavors:
|
|
3
|
-
python_function:
|
|
4
|
-
env:
|
|
5
|
-
conda: conda.yaml
|
|
6
|
-
virtualenv: python_env.yaml
|
|
7
|
-
loader_module: mlflow.sklearn
|
|
8
|
-
model_path: model.skops
|
|
9
|
-
predict_fn: predict
|
|
10
|
-
python_version: 3.13.5
|
|
11
|
-
sklearn:
|
|
12
|
-
code: null
|
|
13
|
-
pickled_model: model.skops
|
|
14
|
-
serialization_format: skops
|
|
15
|
-
sklearn_version: 1.7.2
|
|
16
|
-
skops_trusted_types: null
|
|
17
|
-
mlflow_version: 3.14.0
|
|
18
|
-
model_id: m-3eabd93b6ac447808321a1d58fef2b9b
|
|
19
|
-
model_size_bytes: 9581
|
|
20
|
-
model_uuid: m-3eabd93b6ac447808321a1d58fef2b9b
|
|
21
|
-
prompts: null
|
|
22
|
-
run_id: ede0865607194eba8f4bcb00ba747744
|
|
23
|
-
utc_time_created: '2026-06-20 21:49:57.444715'
|
|
@@ -1,22 +0,0 @@
|
|
|
1
|
-
channels:
|
|
2
|
-
- conda-forge
|
|
3
|
-
dependencies:
|
|
4
|
-
- python=3.13.5
|
|
5
|
-
- pip
|
|
6
|
-
- pip:
|
|
7
|
-
- mlflow==3.14.0
|
|
8
|
-
- annotated-types==0.7.0
|
|
9
|
-
- joblib==1.5.3
|
|
10
|
-
- numpy==2.2.6; python_full_version < "3.11"
|
|
11
|
-
- numpy==2.4.6; python_full_version >= "3.11"
|
|
12
|
-
- pydantic-core==2.46.4
|
|
13
|
-
- pydantic==2.13.4
|
|
14
|
-
- scikit-learn==1.7.2
|
|
15
|
-
- scipy==1.15.3; python_full_version < "3.11"
|
|
16
|
-
- scipy==1.17.1; python_full_version == "3.11.*"
|
|
17
|
-
- scipy==1.18.0; python_full_version >= "3.12"
|
|
18
|
-
- skops==0.14.0
|
|
19
|
-
- threadpoolctl==3.6.0
|
|
20
|
-
- typing-extensions==4.15.0
|
|
21
|
-
- typing-inspection==0.4.2
|
|
22
|
-
name: mlflow-env
|
|
Binary file
|
predikit-0.4.5/mlruns/1/models/m-3eabd93b6ac447808321a1d58fef2b9b/artifacts/requirements.txt
DELETED
|
@@ -1,15 +0,0 @@
|
|
|
1
|
-
mlflow==3.14.0
|
|
2
|
-
annotated-types==0.7.0
|
|
3
|
-
joblib==1.5.3
|
|
4
|
-
numpy==2.2.6; python_full_version < "3.11"
|
|
5
|
-
numpy==2.4.6; python_full_version >= "3.11"
|
|
6
|
-
pydantic-core==2.46.4
|
|
7
|
-
pydantic==2.13.4
|
|
8
|
-
scikit-learn==1.7.2
|
|
9
|
-
scipy==1.15.3; python_full_version < "3.11"
|
|
10
|
-
scipy==1.17.1; python_full_version == "3.11.*"
|
|
11
|
-
scipy==1.18.0; python_full_version >= "3.12"
|
|
12
|
-
skops==0.14.0
|
|
13
|
-
threadpoolctl==3.6.0
|
|
14
|
-
typing-extensions==4.15.0
|
|
15
|
-
typing-inspection==0.4.2
|
|
@@ -1,23 +0,0 @@
|
|
|
1
|
-
artifact_path: file:c:/AI/predikit/mlruns/1/models/m-4816da14ba9c47c2b69d7d959f186d4e/artifacts
|
|
2
|
-
flavors:
|
|
3
|
-
python_function:
|
|
4
|
-
env:
|
|
5
|
-
conda: conda.yaml
|
|
6
|
-
virtualenv: python_env.yaml
|
|
7
|
-
loader_module: mlflow.sklearn
|
|
8
|
-
model_path: model.skops
|
|
9
|
-
predict_fn: predict
|
|
10
|
-
python_version: 3.13.5
|
|
11
|
-
sklearn:
|
|
12
|
-
code: null
|
|
13
|
-
pickled_model: model.skops
|
|
14
|
-
serialization_format: skops
|
|
15
|
-
sklearn_version: 1.7.2
|
|
16
|
-
skops_trusted_types: null
|
|
17
|
-
mlflow_version: 3.14.0
|
|
18
|
-
model_id: m-4816da14ba9c47c2b69d7d959f186d4e
|
|
19
|
-
model_size_bytes: 9581
|
|
20
|
-
model_uuid: m-4816da14ba9c47c2b69d7d959f186d4e
|
|
21
|
-
prompts: null
|
|
22
|
-
run_id: e049ecc2fa2d4e1a920d7aed96dde64f
|
|
23
|
-
utc_time_created: '2026-06-20 21:50:39.894015'
|