predikit 0.6.1__tar.gz → 0.6.3__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 (59) hide show
  1. {predikit-0.6.1 → predikit-0.6.3}/.github/ISSUE_TEMPLATE/bug_report.md +38 -38
  2. {predikit-0.6.1 → predikit-0.6.3}/.github/ISSUE_TEMPLATE/feature_request.md +20 -20
  3. {predikit-0.6.1 → predikit-0.6.3}/.github/workflows/publish.yml +31 -31
  4. {predikit-0.6.1 → predikit-0.6.3}/.github/workflows/test.yml +56 -56
  5. predikit-0.6.3/.gitignore +33 -0
  6. {predikit-0.6.1 → predikit-0.6.3}/.pre-commit-config.yaml +15 -15
  7. {predikit-0.6.1 → predikit-0.6.3}/CHANGELOG.md +21 -0
  8. {predikit-0.6.1 → predikit-0.6.3}/CLAUDE.md +71 -71
  9. {predikit-0.6.1 → predikit-0.6.3}/CONTRIBUTING.md +66 -66
  10. {predikit-0.6.1 → predikit-0.6.3}/LICENSE +21 -21
  11. {predikit-0.6.1 → predikit-0.6.3}/PKG-INFO +10 -4
  12. {predikit-0.6.1 → predikit-0.6.3}/README.md +9 -3
  13. {predikit-0.6.1 → predikit-0.6.3}/examples/01_basic_sklearn.py +48 -48
  14. {predikit-0.6.1 → predikit-0.6.3}/examples/02_xgboost_regression.py +57 -57
  15. {predikit-0.6.1 → predikit-0.6.3}/examples/03_orlando_real_estate.py +127 -127
  16. {predikit-0.6.1 → predikit-0.6.3}/examples/04_confidence_routing.py +106 -106
  17. {predikit-0.6.1 → predikit-0.6.3}/examples/05_multi_model_ensemble.py +182 -182
  18. {predikit-0.6.1 → predikit-0.6.3}/examples/06_mlflow_loader.py +99 -99
  19. {predikit-0.6.1 → predikit-0.6.3}/examples/07_snowflake_loader.py +102 -102
  20. {predikit-0.6.1 → predikit-0.6.3}/pyproject.toml +98 -98
  21. predikit-0.6.3/src/predikit/__init__.py +16 -0
  22. {predikit-0.6.1 → predikit-0.6.3}/src/predikit/cli.py +143 -143
  23. {predikit-0.6.1 → predikit-0.6.3}/src/predikit/coerce.py +56 -56
  24. {predikit-0.6.1 → predikit-0.6.3}/src/predikit/ensemble.py +121 -121
  25. {predikit-0.6.1 → predikit-0.6.3}/src/predikit/exceptions.py +2 -2
  26. {predikit-0.6.1 → predikit-0.6.3}/src/predikit/exporters/langchain.py +31 -31
  27. {predikit-0.6.1 → predikit-0.6.3}/src/predikit/exporters/openai.py +22 -22
  28. {predikit-0.6.1 → predikit-0.6.3}/src/predikit/introspect.py +20 -20
  29. {predikit-0.6.1 → predikit-0.6.3}/src/predikit/loaders/__init__.py +4 -4
  30. {predikit-0.6.1 → predikit-0.6.3}/src/predikit/loaders/mlflow.py +95 -95
  31. {predikit-0.6.1 → predikit-0.6.3}/src/predikit/loaders/snowflake.py +104 -107
  32. {predikit-0.6.1 → predikit-0.6.3}/src/predikit/registry.py +52 -52
  33. {predikit-0.6.1 → predikit-0.6.3}/src/predikit/tool.py +190 -190
  34. predikit-0.6.3/tests/__init__.py +0 -0
  35. {predikit-0.6.1 → predikit-0.6.3}/tests/test_cli.py +219 -219
  36. {predikit-0.6.1 → predikit-0.6.3}/tests/test_coerce.py +68 -68
  37. {predikit-0.6.1 → predikit-0.6.3}/tests/test_confidence.py +134 -134
  38. {predikit-0.6.1 → predikit-0.6.3}/tests/test_ensemble.py +189 -189
  39. {predikit-0.6.1 → predikit-0.6.3}/tests/test_exporters_openai.py +42 -42
  40. {predikit-0.6.1 → predikit-0.6.3}/tests/test_introspect.py +31 -31
  41. {predikit-0.6.1 → predikit-0.6.3}/tests/test_loaders_mlflow.py +202 -202
  42. predikit-0.6.3/tests/test_loaders_snowflake.py +250 -0
  43. {predikit-0.6.1 → predikit-0.6.3}/tests/test_logging.py +24 -11
  44. {predikit-0.6.1 → predikit-0.6.3}/tests/test_registry.py +117 -117
  45. {predikit-0.6.1 → predikit-0.6.3}/tests/test_tool.py +120 -120
  46. {predikit-0.6.1 → predikit-0.6.3}/tests/test_weighted_ensemble.py +176 -176
  47. predikit-0.6.1/.claude/settings.local.json +0 -48
  48. predikit-0.6.1/.gitignore +0 -14
  49. predikit-0.6.1/src/predikit/__init__.py +0 -8
  50. predikit-0.6.1/tests/test_loaders_snowflake.py +0 -240
  51. predikit-0.6.1/uv.lock +0 -5586
  52. {predikit-0.6.1 → predikit-0.6.3}/.gitattributes +0 -0
  53. {predikit-0.6.1 → predikit-0.6.3}/docs/logo.gif +0 -0
  54. {predikit-0.6.1 → predikit-0.6.3}/docs/logo.png +0 -0
  55. {predikit-0.6.1 → predikit-0.6.3}/src/predikit/exporters/__init__.py +0 -0
  56. {predikit-0.6.1 → predikit-0.6.3}/src/predikit/mcp.py +0 -0
  57. /predikit-0.6.1/tests/__init__.py → /predikit-0.6.3/src/predikit/py.typed +0 -0
  58. {predikit-0.6.1 → predikit-0.6.3}/tests/test_exporters_langchain.py +0 -0
  59. {predikit-0.6.1 → predikit-0.6.3}/tests/test_mcp.py +0 -0
@@ -1,38 +1,38 @@
1
- ---
2
- name: Bug report
3
- about: Create a report to help us improve
4
- title: ''
5
- labels: ''
6
- assignees: ''
7
-
8
- ---
9
-
10
- **Describe the bug**
11
- A clear and concise description of what the bug is.
12
-
13
- **To Reproduce**
14
- Steps to reproduce the behavior:
15
- 1. Go to '...'
16
- 2. Click on '....'
17
- 3. Scroll down to '....'
18
- 4. See error
19
-
20
- **Expected behavior**
21
- A clear and concise description of what you expected to happen.
22
-
23
- **Screenshots**
24
- If applicable, add screenshots to help explain your problem.
25
-
26
- **Desktop (please complete the following information):**
27
- - OS: [e.g. iOS]
28
- - Browser [e.g. chrome, safari]
29
- - Version [e.g. 22]
30
-
31
- **Smartphone (please complete the following information):**
32
- - Device: [e.g. iPhone6]
33
- - OS: [e.g. iOS8.1]
34
- - Browser [e.g. stock browser, safari]
35
- - Version [e.g. 22]
36
-
37
- **Additional context**
38
- Add any other context about the problem here.
1
+ ---
2
+ name: Bug report
3
+ about: Create a report to help us improve
4
+ title: ''
5
+ labels: ''
6
+ assignees: ''
7
+
8
+ ---
9
+
10
+ **Describe the bug**
11
+ A clear and concise description of what the bug is.
12
+
13
+ **To Reproduce**
14
+ Steps to reproduce the behavior:
15
+ 1. Go to '...'
16
+ 2. Click on '....'
17
+ 3. Scroll down to '....'
18
+ 4. See error
19
+
20
+ **Expected behavior**
21
+ A clear and concise description of what you expected to happen.
22
+
23
+ **Screenshots**
24
+ If applicable, add screenshots to help explain your problem.
25
+
26
+ **Desktop (please complete the following information):**
27
+ - OS: [e.g. iOS]
28
+ - Browser [e.g. chrome, safari]
29
+ - Version [e.g. 22]
30
+
31
+ **Smartphone (please complete the following information):**
32
+ - Device: [e.g. iPhone6]
33
+ - OS: [e.g. iOS8.1]
34
+ - Browser [e.g. stock browser, safari]
35
+ - Version [e.g. 22]
36
+
37
+ **Additional context**
38
+ Add any other context about the problem here.
@@ -1,20 +1,20 @@
1
- ---
2
- name: Feature request
3
- about: Suggest an idea for this project
4
- title: ''
5
- labels: ''
6
- assignees: ''
7
-
8
- ---
9
-
10
- **Is your feature request related to a problem? Please describe.**
11
- A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]
12
-
13
- **Describe the solution you'd like**
14
- A clear and concise description of what you want to happen.
15
-
16
- **Describe alternatives you've considered**
17
- A clear and concise description of any alternative solutions or features you've considered.
18
-
19
- **Additional context**
20
- Add any other context or screenshots about the feature request here.
1
+ ---
2
+ name: Feature request
3
+ about: Suggest an idea for this project
4
+ title: ''
5
+ labels: ''
6
+ assignees: ''
7
+
8
+ ---
9
+
10
+ **Is your feature request related to a problem? Please describe.**
11
+ A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]
12
+
13
+ **Describe the solution you'd like**
14
+ A clear and concise description of what you want to happen.
15
+
16
+ **Describe alternatives you've considered**
17
+ A clear and concise description of any alternative solutions or features you've considered.
18
+
19
+ **Additional context**
20
+ Add any other context or screenshots about the feature request here.
@@ -1,31 +1,31 @@
1
- name: Publish to PyPI
2
-
3
- on:
4
- release:
5
- types: [published]
6
-
7
- permissions:
8
- contents: read
9
-
10
- jobs:
11
- publish:
12
- runs-on: ubuntu-latest
13
- environment: pypi
14
- permissions:
15
- contents: read
16
- id-token: write
17
-
18
- steps:
19
- - uses: actions/checkout@v4
20
-
21
- - uses: actions/setup-python@v5
22
- with:
23
- python-version: "3.12"
24
-
25
- - name: Build
26
- run: |
27
- pip install hatchling
28
- python -m hatchling build
29
-
30
- - name: Publish to PyPI
31
- uses: pypa/gh-action-pypi-publish@release/v1
1
+ name: Publish to PyPI
2
+
3
+ on:
4
+ release:
5
+ types: [published]
6
+
7
+ permissions:
8
+ contents: read
9
+
10
+ jobs:
11
+ publish:
12
+ runs-on: ubuntu-latest
13
+ environment: pypi
14
+ permissions:
15
+ contents: read
16
+ id-token: write
17
+
18
+ steps:
19
+ - uses: actions/checkout@v4
20
+
21
+ - uses: actions/setup-python@v5
22
+ with:
23
+ python-version: "3.12"
24
+
25
+ - name: Build
26
+ run: |
27
+ pip install hatchling
28
+ python -m hatchling build
29
+
30
+ - name: Publish to PyPI
31
+ uses: pypa/gh-action-pypi-publish@release/v1
@@ -1,56 +1,56 @@
1
- name: Test
2
-
3
- on:
4
- push:
5
- branches: [main]
6
- pull_request:
7
- branches: [main]
8
-
9
- permissions:
10
- contents: read
11
-
12
- jobs:
13
- lint:
14
- runs-on: ubuntu-latest
15
- steps:
16
- - uses: actions/checkout@v4
17
-
18
- - uses: actions/setup-python@v5
19
- with:
20
- python-version: "3.12"
21
-
22
- - name: Install dev dependencies
23
- run: pip install -e ".[dev]"
24
-
25
- - name: Ruff lint
26
- run: ruff check src/ tests/
27
-
28
- - name: Ruff format check
29
- run: ruff format --check src/ tests/
30
-
31
- - name: Mypy
32
- run: mypy src/predikit
33
-
34
- - name: Build package
35
- run: |
36
- python -m pip install hatchling
37
- python -m hatchling build
38
-
39
- test:
40
- runs-on: ubuntu-latest
41
- strategy:
42
- matrix:
43
- python-version: ["3.10", "3.11", "3.12", "3.13"]
44
-
45
- steps:
46
- - uses: actions/checkout@v4
47
-
48
- - uses: actions/setup-python@v5
49
- with:
50
- python-version: ${{ matrix.python-version }}
51
-
52
- - name: Install dependencies
53
- run: pip install -e ".[dev]"
54
-
55
- - name: Run tests
56
- run: pytest --cov=src/predikit --cov-report=term-missing
1
+ name: Test
2
+
3
+ on:
4
+ push:
5
+ branches: [main]
6
+ pull_request:
7
+ branches: [main]
8
+
9
+ permissions:
10
+ contents: read
11
+
12
+ jobs:
13
+ lint:
14
+ runs-on: ubuntu-latest
15
+ steps:
16
+ - uses: actions/checkout@v4
17
+
18
+ - uses: actions/setup-python@v5
19
+ with:
20
+ python-version: "3.12"
21
+
22
+ - name: Install dev dependencies
23
+ run: pip install -e ".[dev]"
24
+
25
+ - name: Ruff lint
26
+ run: ruff check src/ tests/ examples/
27
+
28
+ - name: Ruff format check
29
+ run: ruff format --check src/ tests/ examples/
30
+
31
+ - name: Mypy
32
+ run: mypy src/predikit
33
+
34
+ - name: Build package
35
+ run: |
36
+ python -m pip install hatchling
37
+ python -m hatchling build
38
+
39
+ test:
40
+ runs-on: ubuntu-latest
41
+ strategy:
42
+ matrix:
43
+ python-version: ["3.10", "3.11", "3.12", "3.13"]
44
+
45
+ steps:
46
+ - uses: actions/checkout@v4
47
+
48
+ - uses: actions/setup-python@v5
49
+ with:
50
+ python-version: ${{ matrix.python-version }}
51
+
52
+ - name: Install dependencies
53
+ run: pip install -e ".[dev]"
54
+
55
+ - name: Run tests
56
+ run: pytest --cov=src/predikit --cov-report=term-missing
@@ -0,0 +1,33 @@
1
+ # Byte-compiled / cache
2
+ __pycache__/
3
+ *.py[cod]
4
+
5
+ # Distribution / packaging
6
+ build/
7
+ dist/
8
+ *.egg
9
+ *.egg-info/
10
+
11
+ # Virtual environments
12
+ .venv/
13
+ venv/
14
+
15
+ # Tooling caches
16
+ .mypy_cache/
17
+ .pytest_cache/
18
+ .ruff_cache/
19
+
20
+ # Test coverage
21
+ .coverage
22
+ coverage.xml
23
+ htmlcov/
24
+
25
+ # Serialized models written by examples and CLI tests
26
+ *.joblib
27
+ *.pkl
28
+
29
+ # MLflow local tracking store
30
+ mlruns/
31
+
32
+ # Per-developer editor and agent settings
33
+ .claude/settings.local.json
@@ -1,15 +1,15 @@
1
- repos:
2
- - repo: https://github.com/astral-sh/ruff-pre-commit
3
- rev: v0.5.0
4
- hooks:
5
- - id: ruff
6
- args: [--fix]
7
- - id: ruff-format
8
-
9
- - repo: https://github.com/pre-commit/mirrors-mypy
10
- rev: v1.10.0
11
- hooks:
12
- - id: mypy
13
- additional_dependencies:
14
- - pydantic>=2.0
15
- - numpy>=1.24
1
+ repos:
2
+ - repo: https://github.com/astral-sh/ruff-pre-commit
3
+ rev: v0.5.0
4
+ hooks:
5
+ - id: ruff
6
+ args: [--fix]
7
+ - id: ruff-format
8
+
9
+ - repo: https://github.com/pre-commit/mirrors-mypy
10
+ rev: v1.10.0
11
+ hooks:
12
+ - id: mypy
13
+ additional_dependencies:
14
+ - pydantic>=2.0
15
+ - numpy>=1.24
@@ -6,6 +6,27 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
6
6
 
7
7
  ## [Unreleased]
8
8
 
9
+ ## [0.6.3] - 2026-09-13
10
+
11
+ ### Fixed
12
+ - Corrected the MCP quick-start command: `predikit serve` requires both the `mcp` and `cli` extras. The MCP library API itself remains available with `predikit[mcp]` alone.
13
+
14
+ ### Changed
15
+ - Polished the README installation guidance and documented MCP HTTP host/port options.
16
+
17
+ ## [0.6.2] - 2026-08-22
18
+
19
+ ### Added
20
+ - `py.typed` marker, so type checkers actually consume the annotations. Every module is annotated and mypy-clean, and the package declares the `Typing :: Typed` classifier, but without the PEP 561 marker downstream consumers got no type information at all.
21
+
22
+ ### Changed
23
+ - `from_snowflake()` imports `snowflake.ml.registry` inside the function body instead of at module level, matching `from_mlflow()` and the project's own rule for optional dependencies. The module-level `Registry = None` sentinel is gone.
24
+ - CI lints and format-checks `examples/` alongside `src/` and `tests/`.
25
+
26
+ ### Removed
27
+ - `uv.lock`. Nothing consumed it — CI installs with `pip install -e ".[dev]"` — and a library should not pin its consumers' transitive dependencies.
28
+ - `.claude/settings.local.json` from version control. It holds per-developer machine paths.
29
+
9
30
  ## [0.6.1] - 2026-08-15
10
31
 
11
32
  ### Fixed
@@ -1,71 +1,71 @@
1
- # predikit — Claude Code context
2
-
3
- ## What this is
4
-
5
- predikit wraps fitted scikit-learn / XGBoost models as LLM-callable tools with auto-generated JSON schemas, typed I/O via Pydantic, and first-class support for OpenAI function calling and LangChain.
6
-
7
- ## Project layout
8
-
9
- ```
10
- src/predikit/ Core package (installed as `predikit`)
11
- tool.py ModelTool — main public class
12
- registry.py ToolRegistry — groups multiple tools for bulk export
13
- ensemble.py ModelEnsemble — multi-model reconciliation strategies
14
- exceptions.py LowConfidenceError
15
- coerce.py LLM-string → Python type coercion (bool, int, float, str)
16
- introspect.py Extract sklearn model metadata (feature names, task type)
17
- cli.py `predikit inspect` CLI (click + joblib)
18
- exporters/
19
- openai.py .to_openai() — OpenAI function-calling schema
20
- langchain.py .to_langchain() — LangChain StructuredTool
21
- loaders/
22
- mlflow.py from_mlflow() — load from MLflow Model Registry
23
- snowflake.py from_snowflake() — load from Snowflake Model Registry
24
- tests/ pytest suite (mirrors src/ layout)
25
- examples/ Standalone usage scripts (01–07)
26
- ```
27
-
28
- ## Commands
29
-
30
- ```bash
31
- # Install for development
32
- pip install -e ".[dev]"
33
-
34
- # Run tests
35
- pytest --cov=src/predikit --cov-report=term-missing
36
-
37
- # Lint (check only)
38
- ruff check src/ tests/
39
-
40
- # Format (check only)
41
- ruff format --check src/ tests/
42
-
43
- # Lint + format (auto-fix)
44
- ruff check --fix src/ tests/
45
- ruff format src/ tests/
46
-
47
- # Type check
48
- mypy src/predikit
49
-
50
- # All checks via pre-commit
51
- pre-commit run --all-files
52
-
53
- # Install pre-commit hooks
54
- pre-commit install
55
- ```
56
-
57
- ## Key conventions
58
-
59
- - **Public API** — `ModelTool`, `ToolRegistry`, `ModelEnsemble`, `LowConfidenceError` are all re-exported from `predikit/__init__.py`. Everything else is internal.
60
- - **Optional imports** — heavy optional deps (`langchain`, `xgboost`, `mlflow`, `snowflake`) are imported inside functions/methods, never at module level, so missing extras don't break core imports.
61
- - **Feature name matching** — inputs map to model features by column name (using `feature_names_in_` from sklearn), not by position. Mismatches raise a `ValueError` with a clear diff.
62
- - **Bool coercion** — `coerce_value()` converts LLM strings (`"yes"`, `"true"`, `"1"`, `"on"`) to Python bools before Pydantic validation.
63
- - **Async** — `ainvoke()` is a thin wrapper over `invoke()` via `loop.run_in_executor`. No async-native I/O involved.
64
- - **Ensemble strategies** — `"collect"`, `"mean"`, `"vote"`, `"weighted_mean"`, `"weighted_vote"`. Weighted strategies take a `weights` list parallel to `tools`.
65
-
66
- ## Release process
67
-
68
- 1. Bump `version` in `pyproject.toml` and `__version__` in `src/predikit/__init__.py`.
69
- 2. Add a section to `CHANGELOG.md`.
70
- 3. Commit, push to `main`, create a GitHub Release with the version tag (e.g. `v0.4.1`).
71
- 4. `publish.yml` auto-triggers a PyPI upload via OIDC trusted publishing.
1
+ # predikit — Claude Code context
2
+
3
+ ## What this is
4
+
5
+ predikit wraps fitted scikit-learn / XGBoost models as LLM-callable tools with auto-generated JSON schemas, typed I/O via Pydantic, and first-class support for OpenAI function calling and LangChain.
6
+
7
+ ## Project layout
8
+
9
+ ```
10
+ src/predikit/ Core package (installed as `predikit`)
11
+ tool.py ModelTool — main public class
12
+ registry.py ToolRegistry — groups multiple tools for bulk export
13
+ ensemble.py ModelEnsemble — multi-model reconciliation strategies
14
+ exceptions.py LowConfidenceError
15
+ coerce.py LLM-string → Python type coercion (bool, int, float, str)
16
+ introspect.py Extract sklearn model metadata (feature names, task type)
17
+ cli.py `predikit inspect` CLI (click + joblib)
18
+ exporters/
19
+ openai.py .to_openai() — OpenAI function-calling schema
20
+ langchain.py .to_langchain() — LangChain StructuredTool
21
+ loaders/
22
+ mlflow.py from_mlflow() — load from MLflow Model Registry
23
+ snowflake.py from_snowflake() — load from Snowflake Model Registry
24
+ tests/ pytest suite (mirrors src/ layout)
25
+ examples/ Standalone usage scripts (01–07)
26
+ ```
27
+
28
+ ## Commands
29
+
30
+ ```bash
31
+ # Install for development
32
+ pip install -e ".[dev]"
33
+
34
+ # Run tests
35
+ pytest --cov=src/predikit --cov-report=term-missing
36
+
37
+ # Lint (check only)
38
+ ruff check src/ tests/ examples/
39
+
40
+ # Format (check only)
41
+ ruff format --check src/ tests/ examples/
42
+
43
+ # Lint + format (auto-fix)
44
+ ruff check --fix src/ tests/ examples/
45
+ ruff format src/ tests/ examples/
46
+
47
+ # Type check
48
+ mypy src/predikit
49
+
50
+ # All checks via pre-commit
51
+ pre-commit run --all-files
52
+
53
+ # Install pre-commit hooks
54
+ pre-commit install
55
+ ```
56
+
57
+ ## Key conventions
58
+
59
+ - **Public API** — `ModelTool`, `ToolRegistry`, `ModelEnsemble`, `LowConfidenceError` are all re-exported from `predikit/__init__.py`. Everything else is internal.
60
+ - **Optional imports** — heavy optional deps (`langchain`, `xgboost`, `mlflow`, `snowflake`) are imported inside functions/methods, never at module level, so missing extras don't break core imports.
61
+ - **Feature name matching** — inputs map to model features by column name (using `feature_names_in_` from sklearn), not by position. Mismatches raise a `ValueError` with a clear diff.
62
+ - **Bool coercion** — `coerce_value()` converts LLM strings (`"yes"`, `"true"`, `"1"`, `"on"`) to Python bools before Pydantic validation.
63
+ - **Async** — `ainvoke()` is a thin wrapper over `invoke()` via `loop.run_in_executor`. No async-native I/O involved.
64
+ - **Ensemble strategies** — `"collect"`, `"mean"`, `"vote"`, `"weighted_mean"`, `"weighted_vote"`. Weighted strategies take a `weights` list parallel to `tools`.
65
+
66
+ ## Release process
67
+
68
+ 1. Bump `version` in `pyproject.toml` and `__version__` in `src/predikit/__init__.py`.
69
+ 2. Add a section to `CHANGELOG.md`.
70
+ 3. Commit, push to `main`, create a GitHub Release with the version tag (e.g. `v0.4.1`).
71
+ 4. `publish.yml` auto-triggers a PyPI upload via OIDC trusted publishing.
@@ -1,66 +1,66 @@
1
- # Contributing to predikit
2
-
3
- Thanks for your interest in contributing.
4
-
5
- ## Prerequisites
6
-
7
- - Python 3.10+
8
- - [pre-commit](https://pre-commit.com/) (`pip install pre-commit`)
9
-
10
- ## Development setup
11
-
12
- ```bash
13
- git clone https://github.com/Tejas-TA/predikit
14
- cd predikit
15
- pip install -e ".[dev]"
16
- pre-commit install
17
- ```
18
-
19
- `pre-commit install` wires up ruff and mypy to run automatically before every commit.
20
-
21
- ## Running tests
22
-
23
- ```bash
24
- pytest --cov=src/predikit --cov-report=term-missing
25
- ```
26
-
27
- ## Code style
28
-
29
- This project uses [ruff](https://docs.astral.sh/ruff/) for linting and formatting, and [mypy](https://mypy.readthedocs.io/) for type checking. All three are configured in `pyproject.toml`.
30
-
31
- ```bash
32
- # Check and auto-fix
33
- ruff check --fix src/ tests/
34
- ruff format src/ tests/
35
-
36
- # Type check
37
- mypy src/predikit
38
- ```
39
-
40
- Or run everything at once via pre-commit:
41
-
42
- ```bash
43
- pre-commit run --all-files
44
- ```
45
-
46
- CI enforces all three checks on every push and PR (see `.github/workflows/test.yml`).
47
-
48
- ## Pull request guidelines
49
-
50
- - Target `main`.
51
- - Keep changes focused — one feature or fix per PR.
52
- - Add or update tests for any changed behaviour.
53
- - Run `pre-commit run --all-files` before pushing; CI will catch failures regardless.
54
-
55
- ## Adding a new exporter or loader
56
-
57
- - Exporters live in `src/predikit/exporters/` and should expose a single function consumed by `ModelTool`.
58
- - Loaders live in `src/predikit/loaders/` and should return a `ModelTool` instance.
59
- - Any new optional dependency must be added to both the relevant optional group and `dev` in `pyproject.toml`, and imported inside the function body (not at module level).
60
-
61
- ## Release process (maintainers)
62
-
63
- 1. Bump `version` in `pyproject.toml` and `__version__` in `src/predikit/__init__.py`.
64
- 2. Add a section to `CHANGELOG.md`.
65
- 3. Merge to `main`, create a GitHub Release tagged `vX.Y.Z`.
66
- 4. `publish.yml` automatically publishes to PyPI via OIDC trusted publishing.
1
+ # Contributing to predikit
2
+
3
+ Thanks for your interest in contributing.
4
+
5
+ ## Prerequisites
6
+
7
+ - Python 3.10+
8
+ - [pre-commit](https://pre-commit.com/) (`pip install pre-commit`)
9
+
10
+ ## Development setup
11
+
12
+ ```bash
13
+ git clone https://github.com/Tejas-TA/predikit
14
+ cd predikit
15
+ pip install -e ".[dev]"
16
+ pre-commit install
17
+ ```
18
+
19
+ `pre-commit install` wires up ruff and mypy to run automatically before every commit.
20
+
21
+ ## Running tests
22
+
23
+ ```bash
24
+ pytest --cov=src/predikit --cov-report=term-missing
25
+ ```
26
+
27
+ ## Code style
28
+
29
+ This project uses [ruff](https://docs.astral.sh/ruff/) for linting and formatting, and [mypy](https://mypy.readthedocs.io/) for type checking. All three are configured in `pyproject.toml`.
30
+
31
+ ```bash
32
+ # Check and auto-fix
33
+ ruff check --fix src/ tests/ examples/
34
+ ruff format src/ tests/ examples/
35
+
36
+ # Type check
37
+ mypy src/predikit
38
+ ```
39
+
40
+ Or run everything at once via pre-commit:
41
+
42
+ ```bash
43
+ pre-commit run --all-files
44
+ ```
45
+
46
+ CI enforces all three checks on every push and PR (see `.github/workflows/test.yml`).
47
+
48
+ ## Pull request guidelines
49
+
50
+ - Target `main`.
51
+ - Keep changes focused — one feature or fix per PR.
52
+ - Add or update tests for any changed behaviour.
53
+ - Run `pre-commit run --all-files` before pushing; CI will catch failures regardless.
54
+
55
+ ## Adding a new exporter or loader
56
+
57
+ - Exporters live in `src/predikit/exporters/` and should expose a single function consumed by `ModelTool`.
58
+ - Loaders live in `src/predikit/loaders/` and should return a `ModelTool` instance.
59
+ - Any new optional dependency must be added to both the relevant optional group and `dev` in `pyproject.toml`, and imported inside the function body (not at module level).
60
+
61
+ ## Release process (maintainers)
62
+
63
+ 1. Bump `version` in `pyproject.toml` and `__version__` in `src/predikit/__init__.py`.
64
+ 2. Add a section to `CHANGELOG.md`.
65
+ 3. Merge to `main`, create a GitHub Release tagged `vX.Y.Z`.
66
+ 4. `publish.yml` automatically publishes to PyPI via OIDC trusted publishing.