chapkit 0.7.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 (62) hide show
  1. chapkit-0.7.0/PKG-INFO +231 -0
  2. chapkit-0.7.0/README.md +200 -0
  3. chapkit-0.7.0/pyproject.toml +164 -0
  4. chapkit-0.7.0/src/chapkit/__init__.py +128 -0
  5. chapkit-0.7.0/src/chapkit/alembic/__init__.py +1 -0
  6. chapkit-0.7.0/src/chapkit/alembic/env.py +76 -0
  7. chapkit-0.7.0/src/chapkit/alembic/script.py.mako +26 -0
  8. chapkit-0.7.0/src/chapkit/alembic/versions/20251010_0927_4d869b5fb06e_initial_schema.py +34 -0
  9. chapkit-0.7.0/src/chapkit/alembic/versions/__init__.py +1 -0
  10. chapkit-0.7.0/src/chapkit/alembic_helpers.py +138 -0
  11. chapkit-0.7.0/src/chapkit/api/__init__.py +64 -0
  12. chapkit-0.7.0/src/chapkit/api/dependencies.py +32 -0
  13. chapkit-0.7.0/src/chapkit/api/service_builder.py +369 -0
  14. chapkit-0.7.0/src/chapkit/artifact/__init__.py +18 -0
  15. chapkit-0.7.0/src/chapkit/artifact/manager.py +132 -0
  16. chapkit-0.7.0/src/chapkit/artifact/models.py +36 -0
  17. chapkit-0.7.0/src/chapkit/artifact/repository.py +48 -0
  18. chapkit-0.7.0/src/chapkit/artifact/router.py +126 -0
  19. chapkit-0.7.0/src/chapkit/artifact/schemas.py +67 -0
  20. chapkit-0.7.0/src/chapkit/cli/__init__.py +5 -0
  21. chapkit-0.7.0/src/chapkit/cli/__main__.py +6 -0
  22. chapkit-0.7.0/src/chapkit/cli/cli.py +47 -0
  23. chapkit-0.7.0/src/chapkit/cli/init.py +211 -0
  24. chapkit-0.7.0/src/chapkit/cli/templates/.gitignore +152 -0
  25. chapkit-0.7.0/src/chapkit/cli/templates/Dockerfile.jinja2 +86 -0
  26. chapkit-0.7.0/src/chapkit/cli/templates/README.md.jinja2 +176 -0
  27. chapkit-0.7.0/src/chapkit/cli/templates/compose.monitoring.yml.jinja2 +90 -0
  28. chapkit-0.7.0/src/chapkit/cli/templates/compose.yml.jinja2 +32 -0
  29. chapkit-0.7.0/src/chapkit/cli/templates/main.py.jinja2 +146 -0
  30. chapkit-0.7.0/src/chapkit/cli/templates/main_shell.py.jinja2 +105 -0
  31. chapkit-0.7.0/src/chapkit/cli/templates/main_task.py.jinja2 +126 -0
  32. chapkit-0.7.0/src/chapkit/cli/templates/monitoring/grafana/dashboards/chapkit-service-metrics.json +1232 -0
  33. chapkit-0.7.0/src/chapkit/cli/templates/monitoring/grafana/provisioning/dashboards/dashboard.yml +13 -0
  34. chapkit-0.7.0/src/chapkit/cli/templates/monitoring/grafana/provisioning/datasources/prometheus.yml +25 -0
  35. chapkit-0.7.0/src/chapkit/cli/templates/monitoring/prometheus/prometheus.yml.jinja2 +13 -0
  36. chapkit-0.7.0/src/chapkit/cli/templates/postman_collection_ml.json.jinja2 +351 -0
  37. chapkit-0.7.0/src/chapkit/cli/templates/postman_collection_ml_shell.json.jinja2 +374 -0
  38. chapkit-0.7.0/src/chapkit/cli/templates/postman_collection_task.json.jinja2 +607 -0
  39. chapkit-0.7.0/src/chapkit/cli/templates/pyproject.toml.jinja2 +15 -0
  40. chapkit-0.7.0/src/chapkit/cli/templates/scripts/predict_model.py.jinja2 +74 -0
  41. chapkit-0.7.0/src/chapkit/cli/templates/scripts/train_model.py.jinja2 +66 -0
  42. chapkit-0.7.0/src/chapkit/config/__init__.py +20 -0
  43. chapkit-0.7.0/src/chapkit/config/manager.py +63 -0
  44. chapkit-0.7.0/src/chapkit/config/models.py +60 -0
  45. chapkit-0.7.0/src/chapkit/config/repository.py +76 -0
  46. chapkit-0.7.0/src/chapkit/config/router.py +139 -0
  47. chapkit-0.7.0/src/chapkit/config/schemas.py +63 -0
  48. chapkit-0.7.0/src/chapkit/data/__init__.py +22 -0
  49. chapkit-0.7.0/src/chapkit/data/dataframe.py +1104 -0
  50. chapkit-0.7.0/src/chapkit/ml/__init__.py +29 -0
  51. chapkit-0.7.0/src/chapkit/ml/manager.py +231 -0
  52. chapkit-0.7.0/src/chapkit/ml/router.py +114 -0
  53. chapkit-0.7.0/src/chapkit/ml/runner.py +257 -0
  54. chapkit-0.7.0/src/chapkit/ml/schemas.py +98 -0
  55. chapkit-0.7.0/src/chapkit/py.typed +0 -0
  56. chapkit-0.7.0/src/chapkit/scheduler.py +169 -0
  57. chapkit-0.7.0/src/chapkit/task/__init__.py +16 -0
  58. chapkit-0.7.0/src/chapkit/task/executor.py +152 -0
  59. chapkit-0.7.0/src/chapkit/task/registry.py +145 -0
  60. chapkit-0.7.0/src/chapkit/task/router.py +99 -0
  61. chapkit-0.7.0/src/chapkit/task/schemas.py +41 -0
  62. chapkit-0.7.0/src/chapkit/utils.py +64 -0
chapkit-0.7.0/PKG-INFO ADDED
@@ -0,0 +1,231 @@
1
+ Metadata-Version: 2.3
2
+ Name: chapkit
3
+ Version: 0.7.0
4
+ Summary: ML and data service modules built on servicekit - config, artifacts, tasks, and ML workflows
5
+ Keywords: ml,machine-learning,data-science,artifacts,tasks,config,servicekit
6
+ Author: Morten Hansen
7
+ Author-email: Morten Hansen <morten@dhis2.org>
8
+ License: AGPL-3.0-or-later
9
+ Classifier: Development Status :: 3 - Alpha
10
+ Classifier: Intended Audience :: Developers
11
+ Classifier: License :: OSI Approved :: GNU Affero General Public License v3 or later (AGPLv3+)
12
+ Classifier: Programming Language :: Python :: 3
13
+ Classifier: Programming Language :: Python :: 3.13
14
+ Classifier: Framework :: FastAPI
15
+ Classifier: Topic :: Software Development :: Libraries :: Python Modules
16
+ Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
17
+ Requires-Dist: geojson-pydantic>=2.1.0
18
+ Requires-Dist: typer>=0.20.0
19
+ Requires-Dist: jinja2>=3.1.6
20
+ Requires-Dist: servicekit>=0.5.1
21
+ Requires-Dist: pandas>=2.3.3
22
+ Requires-Dist: polars>=1.34.0
23
+ Requires-Dist: xarray>=2025.10.1
24
+ Requires-Dist: numpy>=2.3.0
25
+ Requires-Python: >=3.13
26
+ Project-URL: Documentation, https://dhis2-chap.github.io/chapkit
27
+ Project-URL: Homepage, https://github.com/dhis2-chap/chapkit
28
+ Project-URL: Issues, https://github.com/dhis2-chap/chapkit/issues
29
+ Project-URL: Repository, https://github.com/dhis2-chap/chapkit
30
+ Description-Content-Type: text/markdown
31
+
32
+ # Chapkit
33
+
34
+ [![CI](https://github.com/dhis2-chap/chapkit/actions/workflows/ci.yml/badge.svg)](https://github.com/dhis2-chap/chapkit/actions/workflows/ci.yml)
35
+ [![codecov](https://codecov.io/gh/dhis2-chap/chapkit/branch/main/graph/badge.svg)](https://codecov.io/gh/dhis2-chap/chapkit)
36
+ [![Python 3.13+](https://img.shields.io/badge/python-3.13+-blue.svg)](https://www.python.org/downloads/)
37
+ [![License: AGPL v3](https://img.shields.io/badge/License-AGPL_v3-blue.svg)](https://www.gnu.org/licenses/agpl-3.0)
38
+ [![Documentation](https://img.shields.io/badge/docs-mkdocs-blue.svg)](https://dhis2-chap.github.io/chapkit/)
39
+
40
+ > ML service modules built on servicekit - config, artifact, task, and ML workflows
41
+
42
+ Chapkit provides domain-specific modules for building machine learning services on top of servicekit's core framework. Includes artifact storage, task execution, configuration management, and ML train/predict workflows.
43
+
44
+ ## Features
45
+
46
+ - **Artifact Module**: Hierarchical storage for models, data, and experiment tracking with parent-child relationships
47
+ - **Task Module**: Reusable command templates for shell and Python task execution with parameter injection
48
+ - **Config Module**: Key-value configuration with JSON data and Pydantic validation
49
+ - **ML Module**: Train/predict workflows with artifact-based model storage and timing metadata
50
+ - **Config-Artifact Linking**: Connect configurations to artifact hierarchies for experiment tracking
51
+
52
+ ## Installation
53
+
54
+ Using uv (recommended):
55
+
56
+ ```bash
57
+ uv add chapkit
58
+ ```
59
+
60
+ Or using pip:
61
+
62
+ ```bash
63
+ pip install chapkit
64
+ ```
65
+
66
+ Chapkit automatically installs servicekit as a dependency.
67
+
68
+ ## CLI Usage
69
+
70
+ Quickly scaffold a new ML service project using `uvx`:
71
+
72
+ ```bash
73
+ uvx chapkit init <project-name>
74
+ ```
75
+
76
+ Example:
77
+ ```bash
78
+ uvx chapkit init my-ml-service
79
+ ```
80
+
81
+ Options:
82
+ - `--path <directory>` - Target directory (default: current directory)
83
+ - `--with-monitoring` - Include Prometheus and Grafana monitoring stack
84
+ - `--template <type>` - Template type: `ml` (default), `ml-shell`, or `task`
85
+
86
+ This creates a ready-to-run service with configuration, artifacts, and API endpoints pre-configured.
87
+
88
+ **Template Types:**
89
+ - **ml**: Define training/prediction as Python functions in `main.py` (simpler, best for Python-only ML workflows)
90
+ - **ml-shell**: Use external scripts for training/prediction (language-agnostic, supports Python/R/Julia/etc.)
91
+ - **task**: General-purpose task execution with Python functions and shell commands (not ML-specific)
92
+
93
+ ## Quick Start
94
+
95
+ ```python
96
+ from chapkit import ArtifactHierarchy, BaseConfig
97
+ from chapkit.api import ServiceBuilder, ServiceInfo
98
+
99
+ class MyConfig(BaseConfig):
100
+ model_name: str
101
+ threshold: float
102
+
103
+ app = (
104
+ ServiceBuilder(info=ServiceInfo(display_name="ML Service"))
105
+ .with_health()
106
+ .with_config(MyConfig)
107
+ .with_artifacts(hierarchy=ArtifactHierarchy(name="ml", level_labels={0: "ml_training", 1: "ml_prediction"}))
108
+ .with_jobs()
109
+ .build()
110
+ )
111
+ ```
112
+
113
+ ## Modules
114
+
115
+ ### Config
116
+
117
+ Key-value configuration storage with Pydantic schema validation:
118
+
119
+ ```python
120
+ from chapkit import BaseConfig, ConfigManager
121
+
122
+ class AppConfig(BaseConfig):
123
+ api_url: str
124
+ timeout: int = 30
125
+
126
+ # Automatic validation and CRUD endpoints
127
+ app.with_config(AppConfig)
128
+ ```
129
+
130
+ ### Artifacts
131
+
132
+ Hierarchical storage for models, data, and experiment tracking:
133
+
134
+ ```python
135
+ from chapkit import ArtifactHierarchy, ArtifactManager, ArtifactIn
136
+
137
+ hierarchy = ArtifactHierarchy(
138
+ name="ml_pipeline",
139
+ level_labels={0: "experiment", 1: "model", 2: "evaluation"}
140
+ )
141
+
142
+ # Store pandas DataFrames, models, any Python object
143
+ artifact = await artifact_manager.save(
144
+ ArtifactIn(data=trained_model, parent_id=experiment_id)
145
+ )
146
+ ```
147
+
148
+ ### ML
149
+
150
+ Train and predict workflows with automatic model storage:
151
+
152
+ ```python
153
+ from chapkit.ml import FunctionalModelRunner
154
+ import pandas as pd
155
+
156
+ async def train_model(config: MyConfig, data: pd.DataFrame, geo=None):
157
+ """Train your model - returns trained model object."""
158
+ from sklearn.linear_model import LinearRegression
159
+ model = LinearRegression()
160
+ model.fit(data[["feature1", "feature2"]], data["target"])
161
+ return model
162
+
163
+ async def predict(config: MyConfig, model, historic: pd.DataFrame, future: pd.DataFrame, geo=None):
164
+ """Make predictions - returns DataFrame with predictions."""
165
+ predictions = model.predict(future[["feature1", "feature2"]])
166
+ future["predictions"] = predictions
167
+ return future
168
+
169
+ # Wrap functions in runner
170
+ runner = FunctionalModelRunner(on_train=train_model, on_predict=predict)
171
+ app.with_ml(runner=runner)
172
+ ```
173
+
174
+ ## Architecture
175
+
176
+ ```
177
+ chapkit/
178
+ ├── config/ # Configuration management with Pydantic validation
179
+ ├── artifact/ # Hierarchical storage for models and data
180
+ ├── task/ # Reusable task templates (Python functions, shell commands)
181
+ ├── ml/ # ML train/predict workflows
182
+ ├── cli/ # CLI scaffolding tools
183
+ ├── scheduler.py # Job scheduling integration
184
+ └── api/ # ServiceBuilder with ML integration
185
+ └── service_builder.py # .with_config(), .with_artifacts(), .with_ml()
186
+ ```
187
+
188
+ Chapkit extends servicekit's `BaseServiceBuilder` with ML-specific features and domain modules for configuration, artifacts, tasks, and ML workflows.
189
+
190
+ ## Examples
191
+
192
+ See the `examples/` directory for complete working examples:
193
+
194
+ - `quickstart/` - Complete ML service with config, artifacts, and ML endpoints
195
+ - `config_artifact/` - Config with artifact linking
196
+ - `ml_functional/`, `ml_class/`, `ml_shell/` - ML workflow patterns (ML template, class-based, ML-shell template)
197
+ - `ml_pipeline/` - Multi-stage ML pipeline with hierarchical artifacts
198
+ - `artifact/` - Read-only artifact API with hierarchical storage
199
+ - `task_execution/` - Task execution with Python functions and shell commands
200
+ - `full_featured/` - Comprehensive example with monitoring, custom routers, and hooks
201
+ - `library_usage/` - Using chapkit as a library with custom models
202
+ - `custom_migrations/` - Database migrations with custom models
203
+
204
+ ## Documentation
205
+
206
+ See `docs/guides/` for comprehensive guides:
207
+
208
+ - [ML Workflows](docs/guides/ml-workflows.md) - Train/predict patterns and model runners
209
+ - [Configuration Management](docs/guides/configuration-management.md) - Config schemas and validation
210
+ - [Artifact Storage](docs/guides/artifact-storage.md) - Hierarchical data storage for ML artifacts
211
+ - [Task Execution](docs/guides/task-execution.md) - Python functions and shell command templates
212
+ - [CLI Scaffolding](docs/guides/cli-scaffolding.md) - Project scaffolding with `chapkit init`
213
+ - [Database Migrations](docs/guides/database-migrations.md) - Custom models and Alembic migrations
214
+
215
+ Full documentation: https://dhis2-chap.github.io/chapkit/
216
+
217
+ ## Testing
218
+
219
+ ```bash
220
+ make test # Run tests
221
+ make lint # Run linter
222
+ make coverage # Test coverage
223
+ ```
224
+
225
+ ## License
226
+
227
+ AGPL-3.0-or-later
228
+
229
+ ## Related Projects
230
+
231
+ - **[servicekit](https://github.com/winterop-com/servicekit)** - Core framework foundation (FastAPI, SQLAlchemy, CRUD, auth, etc.) ([docs](https://winterop-com.github.io/servicekit))
@@ -0,0 +1,200 @@
1
+ # Chapkit
2
+
3
+ [![CI](https://github.com/dhis2-chap/chapkit/actions/workflows/ci.yml/badge.svg)](https://github.com/dhis2-chap/chapkit/actions/workflows/ci.yml)
4
+ [![codecov](https://codecov.io/gh/dhis2-chap/chapkit/branch/main/graph/badge.svg)](https://codecov.io/gh/dhis2-chap/chapkit)
5
+ [![Python 3.13+](https://img.shields.io/badge/python-3.13+-blue.svg)](https://www.python.org/downloads/)
6
+ [![License: AGPL v3](https://img.shields.io/badge/License-AGPL_v3-blue.svg)](https://www.gnu.org/licenses/agpl-3.0)
7
+ [![Documentation](https://img.shields.io/badge/docs-mkdocs-blue.svg)](https://dhis2-chap.github.io/chapkit/)
8
+
9
+ > ML service modules built on servicekit - config, artifact, task, and ML workflows
10
+
11
+ Chapkit provides domain-specific modules for building machine learning services on top of servicekit's core framework. Includes artifact storage, task execution, configuration management, and ML train/predict workflows.
12
+
13
+ ## Features
14
+
15
+ - **Artifact Module**: Hierarchical storage for models, data, and experiment tracking with parent-child relationships
16
+ - **Task Module**: Reusable command templates for shell and Python task execution with parameter injection
17
+ - **Config Module**: Key-value configuration with JSON data and Pydantic validation
18
+ - **ML Module**: Train/predict workflows with artifact-based model storage and timing metadata
19
+ - **Config-Artifact Linking**: Connect configurations to artifact hierarchies for experiment tracking
20
+
21
+ ## Installation
22
+
23
+ Using uv (recommended):
24
+
25
+ ```bash
26
+ uv add chapkit
27
+ ```
28
+
29
+ Or using pip:
30
+
31
+ ```bash
32
+ pip install chapkit
33
+ ```
34
+
35
+ Chapkit automatically installs servicekit as a dependency.
36
+
37
+ ## CLI Usage
38
+
39
+ Quickly scaffold a new ML service project using `uvx`:
40
+
41
+ ```bash
42
+ uvx chapkit init <project-name>
43
+ ```
44
+
45
+ Example:
46
+ ```bash
47
+ uvx chapkit init my-ml-service
48
+ ```
49
+
50
+ Options:
51
+ - `--path <directory>` - Target directory (default: current directory)
52
+ - `--with-monitoring` - Include Prometheus and Grafana monitoring stack
53
+ - `--template <type>` - Template type: `ml` (default), `ml-shell`, or `task`
54
+
55
+ This creates a ready-to-run service with configuration, artifacts, and API endpoints pre-configured.
56
+
57
+ **Template Types:**
58
+ - **ml**: Define training/prediction as Python functions in `main.py` (simpler, best for Python-only ML workflows)
59
+ - **ml-shell**: Use external scripts for training/prediction (language-agnostic, supports Python/R/Julia/etc.)
60
+ - **task**: General-purpose task execution with Python functions and shell commands (not ML-specific)
61
+
62
+ ## Quick Start
63
+
64
+ ```python
65
+ from chapkit import ArtifactHierarchy, BaseConfig
66
+ from chapkit.api import ServiceBuilder, ServiceInfo
67
+
68
+ class MyConfig(BaseConfig):
69
+ model_name: str
70
+ threshold: float
71
+
72
+ app = (
73
+ ServiceBuilder(info=ServiceInfo(display_name="ML Service"))
74
+ .with_health()
75
+ .with_config(MyConfig)
76
+ .with_artifacts(hierarchy=ArtifactHierarchy(name="ml", level_labels={0: "ml_training", 1: "ml_prediction"}))
77
+ .with_jobs()
78
+ .build()
79
+ )
80
+ ```
81
+
82
+ ## Modules
83
+
84
+ ### Config
85
+
86
+ Key-value configuration storage with Pydantic schema validation:
87
+
88
+ ```python
89
+ from chapkit import BaseConfig, ConfigManager
90
+
91
+ class AppConfig(BaseConfig):
92
+ api_url: str
93
+ timeout: int = 30
94
+
95
+ # Automatic validation and CRUD endpoints
96
+ app.with_config(AppConfig)
97
+ ```
98
+
99
+ ### Artifacts
100
+
101
+ Hierarchical storage for models, data, and experiment tracking:
102
+
103
+ ```python
104
+ from chapkit import ArtifactHierarchy, ArtifactManager, ArtifactIn
105
+
106
+ hierarchy = ArtifactHierarchy(
107
+ name="ml_pipeline",
108
+ level_labels={0: "experiment", 1: "model", 2: "evaluation"}
109
+ )
110
+
111
+ # Store pandas DataFrames, models, any Python object
112
+ artifact = await artifact_manager.save(
113
+ ArtifactIn(data=trained_model, parent_id=experiment_id)
114
+ )
115
+ ```
116
+
117
+ ### ML
118
+
119
+ Train and predict workflows with automatic model storage:
120
+
121
+ ```python
122
+ from chapkit.ml import FunctionalModelRunner
123
+ import pandas as pd
124
+
125
+ async def train_model(config: MyConfig, data: pd.DataFrame, geo=None):
126
+ """Train your model - returns trained model object."""
127
+ from sklearn.linear_model import LinearRegression
128
+ model = LinearRegression()
129
+ model.fit(data[["feature1", "feature2"]], data["target"])
130
+ return model
131
+
132
+ async def predict(config: MyConfig, model, historic: pd.DataFrame, future: pd.DataFrame, geo=None):
133
+ """Make predictions - returns DataFrame with predictions."""
134
+ predictions = model.predict(future[["feature1", "feature2"]])
135
+ future["predictions"] = predictions
136
+ return future
137
+
138
+ # Wrap functions in runner
139
+ runner = FunctionalModelRunner(on_train=train_model, on_predict=predict)
140
+ app.with_ml(runner=runner)
141
+ ```
142
+
143
+ ## Architecture
144
+
145
+ ```
146
+ chapkit/
147
+ ├── config/ # Configuration management with Pydantic validation
148
+ ├── artifact/ # Hierarchical storage for models and data
149
+ ├── task/ # Reusable task templates (Python functions, shell commands)
150
+ ├── ml/ # ML train/predict workflows
151
+ ├── cli/ # CLI scaffolding tools
152
+ ├── scheduler.py # Job scheduling integration
153
+ └── api/ # ServiceBuilder with ML integration
154
+ └── service_builder.py # .with_config(), .with_artifacts(), .with_ml()
155
+ ```
156
+
157
+ Chapkit extends servicekit's `BaseServiceBuilder` with ML-specific features and domain modules for configuration, artifacts, tasks, and ML workflows.
158
+
159
+ ## Examples
160
+
161
+ See the `examples/` directory for complete working examples:
162
+
163
+ - `quickstart/` - Complete ML service with config, artifacts, and ML endpoints
164
+ - `config_artifact/` - Config with artifact linking
165
+ - `ml_functional/`, `ml_class/`, `ml_shell/` - ML workflow patterns (ML template, class-based, ML-shell template)
166
+ - `ml_pipeline/` - Multi-stage ML pipeline with hierarchical artifacts
167
+ - `artifact/` - Read-only artifact API with hierarchical storage
168
+ - `task_execution/` - Task execution with Python functions and shell commands
169
+ - `full_featured/` - Comprehensive example with monitoring, custom routers, and hooks
170
+ - `library_usage/` - Using chapkit as a library with custom models
171
+ - `custom_migrations/` - Database migrations with custom models
172
+
173
+ ## Documentation
174
+
175
+ See `docs/guides/` for comprehensive guides:
176
+
177
+ - [ML Workflows](docs/guides/ml-workflows.md) - Train/predict patterns and model runners
178
+ - [Configuration Management](docs/guides/configuration-management.md) - Config schemas and validation
179
+ - [Artifact Storage](docs/guides/artifact-storage.md) - Hierarchical data storage for ML artifacts
180
+ - [Task Execution](docs/guides/task-execution.md) - Python functions and shell command templates
181
+ - [CLI Scaffolding](docs/guides/cli-scaffolding.md) - Project scaffolding with `chapkit init`
182
+ - [Database Migrations](docs/guides/database-migrations.md) - Custom models and Alembic migrations
183
+
184
+ Full documentation: https://dhis2-chap.github.io/chapkit/
185
+
186
+ ## Testing
187
+
188
+ ```bash
189
+ make test # Run tests
190
+ make lint # Run linter
191
+ make coverage # Test coverage
192
+ ```
193
+
194
+ ## License
195
+
196
+ AGPL-3.0-or-later
197
+
198
+ ## Related Projects
199
+
200
+ - **[servicekit](https://github.com/winterop-com/servicekit)** - Core framework foundation (FastAPI, SQLAlchemy, CRUD, auth, etc.) ([docs](https://winterop-com.github.io/servicekit))
@@ -0,0 +1,164 @@
1
+ [project]
2
+ name = "chapkit"
3
+ version = "0.7.0"
4
+ description = "ML and data service modules built on servicekit - config, artifacts, tasks, and ML workflows"
5
+ readme = "README.md"
6
+ authors = [{ name = "Morten Hansen", email = "morten@dhis2.org" }]
7
+ license = { text = "AGPL-3.0-or-later" }
8
+ requires-python = ">=3.13"
9
+ keywords = [
10
+ "ml",
11
+ "machine-learning",
12
+ "data-science",
13
+ "artifacts",
14
+ "tasks",
15
+ "config",
16
+ "servicekit",
17
+ ]
18
+ classifiers = [
19
+ "Development Status :: 3 - Alpha",
20
+ "Intended Audience :: Developers",
21
+ "License :: OSI Approved :: GNU Affero General Public License v3 or later (AGPLv3+)",
22
+ "Programming Language :: Python :: 3",
23
+ "Programming Language :: Python :: 3.13",
24
+ "Framework :: FastAPI",
25
+ "Topic :: Software Development :: Libraries :: Python Modules",
26
+ "Topic :: Scientific/Engineering :: Artificial Intelligence",
27
+ ]
28
+ dependencies = [
29
+ "geojson-pydantic>=2.1.0",
30
+ "typer>=0.20.0",
31
+ "jinja2>=3.1.6",
32
+ "servicekit>=0.5.1",
33
+ "pandas>=2.3.3",
34
+ "polars>=1.34.0",
35
+ "xarray>=2025.10.1",
36
+ "numpy>=2.3.0",
37
+ ]
38
+
39
+ [project.urls]
40
+ Homepage = "https://github.com/dhis2-chap/chapkit"
41
+ Repository = "https://github.com/dhis2-chap/chapkit"
42
+ Issues = "https://github.com/dhis2-chap/chapkit/issues"
43
+ Documentation = "https://dhis2-chap.github.io/chapkit"
44
+
45
+ [project.scripts]
46
+ chapkit = "chapkit.cli.cli:main"
47
+
48
+ [dependency-groups]
49
+ dev = [
50
+ "coverage[toml]>=7.6.0",
51
+ "mypy>=1.18.2",
52
+ "pandas-stubs>=2.2.3.250101",
53
+ "pytest>=8.4.2",
54
+ "pytest-cov>=5.0.0",
55
+ "pytest-asyncio>=1.2.0",
56
+ "ruff>=0.14.0",
57
+ "pyright>=1.1.407",
58
+ "scikit-learn>=1.7.2",
59
+ "mkdocs>=1.6.0",
60
+ "mkdocs-material>=9.5.0",
61
+ "mkdocstrings[python]>=0.26.0",
62
+ "types-pyyaml>=6.0.12.20250915",
63
+ ]
64
+
65
+ [build-system]
66
+ requires = ["uv_build>=0.9.0,<0.10.0"]
67
+ build-backend = "uv_build"
68
+
69
+ [tool.ruff]
70
+ target-version = "py313"
71
+ line-length = 120
72
+
73
+ [tool.ruff.lint]
74
+ fixable = ["ALL"]
75
+ select = ["E", "W", "F", "I", "D"]
76
+ ignore = ["D203", "D213"]
77
+
78
+ [tool.ruff.lint.pydocstyle]
79
+ convention = "google"
80
+
81
+ [tool.ruff.lint.per-file-ignores]
82
+ "tests/**/*.py" = ["D"]
83
+ "src/chapkit/alembic/**/*.py" = ["D"]
84
+ "**/__init__.py" = ["D104"]
85
+ "src/**/*.py" = ["D102", "D105", "D107"]
86
+ "examples/**/*.py" = []
87
+
88
+ [tool.ruff.format]
89
+ quote-style = "double"
90
+ indent-style = "space"
91
+ skip-magic-trailing-comma = false
92
+ docstring-code-format = true
93
+ docstring-code-line-length = "dynamic"
94
+
95
+ [tool.pytest.ini_options]
96
+ asyncio_mode = "auto"
97
+ testpaths = ["tests"]
98
+ norecursedirs = ["examples", ".git", ".venv", "__pycache__"]
99
+ filterwarnings = [
100
+ "ignore:Pydantic serializer warnings:UserWarning",
101
+ "ignore:Remove.*format_exc_info.*:UserWarning",
102
+ ]
103
+
104
+ [tool.coverage.run]
105
+ branch = true
106
+ dynamic_context = "test_function"
107
+ relative_files = true
108
+ source = ["chapkit"]
109
+ omit = ["*/alembic/*", "*/cli/*"]
110
+
111
+ [tool.coverage.report]
112
+ exclude_also = ["if TYPE_CHECKING:"]
113
+ precision = 2
114
+ show_missing = true
115
+ skip_covered = true
116
+
117
+ [tool.mypy]
118
+ python_version = "3.13"
119
+ warn_return_any = true
120
+ warn_unused_configs = true
121
+ disallow_untyped_defs = true
122
+ check_untyped_defs = true
123
+ no_implicit_optional = true
124
+ warn_unused_ignores = true
125
+ strict_equality = true
126
+ mypy_path = ["src", "typings"]
127
+
128
+ [[tool.mypy.overrides]]
129
+ module = "tests.*"
130
+ disallow_untyped_defs = false
131
+
132
+ [[tool.mypy.overrides]]
133
+ module = "servicekit.*"
134
+ ignore_missing_imports = true
135
+ disallow_any_unimported = false
136
+
137
+ [[tool.mypy.overrides]]
138
+ module = [
139
+ "chapkit.artifact.*",
140
+ "chapkit.config.*",
141
+ "chapkit.task.*",
142
+ "examples.*",
143
+ ]
144
+ warn_return_any = false
145
+
146
+ [[tool.mypy.overrides]]
147
+ module = "examples.custom_migrations.*"
148
+ ignore_missing_imports = true
149
+ ignore_errors = true
150
+
151
+ [tool.pyright]
152
+ include = ["src", "tests", "examples"]
153
+ pythonVersion = "3.13"
154
+ typeCheckingMode = "strict"
155
+ useLibraryCodeForTypes = true
156
+ reportPrivateUsage = false
157
+ reportUnusedFunction = false
158
+ reportUnknownMemberType = false
159
+ reportUnknownArgumentType = false
160
+ reportUnknownParameterType = false
161
+ reportUnknownVariableType = false
162
+ reportMissingTypeArgument = false
163
+ reportMissingTypeStubs = false
164
+ reportUnknownLambdaType = false