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