chapkit 0.26.0__tar.gz → 0.28.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.
- {chapkit-0.26.0 → chapkit-0.28.0}/PKG-INFO +7 -8
- {chapkit-0.26.0 → chapkit-0.28.0}/README.md +5 -6
- {chapkit-0.26.0 → chapkit-0.28.0}/pyproject.toml +4 -14
- {chapkit-0.26.0 → chapkit-0.28.0}/src/chapkit/artifact/__init__.py +6 -0
- {chapkit-0.26.0 → chapkit-0.28.0}/src/chapkit/artifact/router.py +38 -9
- {chapkit-0.26.0 → chapkit-0.28.0}/src/chapkit/artifact/schemas.py +34 -0
- {chapkit-0.26.0 → chapkit-0.28.0}/src/chapkit/__init__.py +0 -0
- {chapkit-0.26.0 → chapkit-0.28.0}/src/chapkit/alembic/__init__.py +0 -0
- {chapkit-0.26.0 → chapkit-0.28.0}/src/chapkit/alembic/env.py +0 -0
- {chapkit-0.26.0 → chapkit-0.28.0}/src/chapkit/alembic/script.py.mako +0 -0
- {chapkit-0.26.0 → chapkit-0.28.0}/src/chapkit/alembic/versions/20251010_0927_4d869b5fb06e_initial_schema.py +0 -0
- {chapkit-0.26.0 → chapkit-0.28.0}/src/chapkit/alembic/versions/__init__.py +0 -0
- {chapkit-0.26.0 → chapkit-0.28.0}/src/chapkit/alembic_helpers.py +0 -0
- {chapkit-0.26.0 → chapkit-0.28.0}/src/chapkit/api/__init__.py +0 -0
- {chapkit-0.26.0 → chapkit-0.28.0}/src/chapkit/api/dependencies.py +0 -0
- {chapkit-0.26.0 → chapkit-0.28.0}/src/chapkit/api/service_builder.py +0 -0
- {chapkit-0.26.0 → chapkit-0.28.0}/src/chapkit/artifact/manager.py +0 -0
- {chapkit-0.26.0 → chapkit-0.28.0}/src/chapkit/artifact/models.py +0 -0
- {chapkit-0.26.0 → chapkit-0.28.0}/src/chapkit/artifact/repository.py +0 -0
- {chapkit-0.26.0 → chapkit-0.28.0}/src/chapkit/cli/__init__.py +0 -0
- {chapkit-0.26.0 → chapkit-0.28.0}/src/chapkit/cli/__main__.py +0 -0
- {chapkit-0.26.0 → chapkit-0.28.0}/src/chapkit/cli/artifact.py +0 -0
- {chapkit-0.26.0 → chapkit-0.28.0}/src/chapkit/cli/cli.py +0 -0
- {chapkit-0.26.0 → chapkit-0.28.0}/src/chapkit/cli/init.py +0 -0
- {chapkit-0.26.0 → chapkit-0.28.0}/src/chapkit/cli/migrate.py +0 -0
- {chapkit-0.26.0 → chapkit-0.28.0}/src/chapkit/cli/mlproject.py +0 -0
- {chapkit-0.26.0 → chapkit-0.28.0}/src/chapkit/cli/run.py +0 -0
- {chapkit-0.26.0 → chapkit-0.28.0}/src/chapkit/cli/templates/.gitignore +0 -0
- {chapkit-0.26.0 → chapkit-0.28.0}/src/chapkit/cli/templates/.python-version +0 -0
- {chapkit-0.26.0 → chapkit-0.28.0}/src/chapkit/cli/templates/Dockerfile.jinja2 +0 -0
- {chapkit-0.26.0 → chapkit-0.28.0}/src/chapkit/cli/templates/README.md.jinja2 +0 -0
- {chapkit-0.26.0 → chapkit-0.28.0}/src/chapkit/cli/templates/compose.yml.jinja2 +0 -0
- {chapkit-0.26.0 → chapkit-0.28.0}/src/chapkit/cli/templates/main.py.jinja2 +0 -0
- {chapkit-0.26.0 → chapkit-0.28.0}/src/chapkit/cli/templates/main_shell.py.jinja2 +0 -0
- {chapkit-0.26.0 → chapkit-0.28.0}/src/chapkit/cli/templates/migrate/CHAPKIT_migrate.md.jinja2 +0 -0
- {chapkit-0.26.0 → chapkit-0.28.0}/src/chapkit/cli/templates/migrate/Dockerfile_migrate.jinja2 +0 -0
- {chapkit-0.26.0 → chapkit-0.28.0}/src/chapkit/cli/templates/migrate/Makefile_migrate.jinja2 +0 -0
- {chapkit-0.26.0 → chapkit-0.28.0}/src/chapkit/cli/templates/migrate/README_migrate.md.jinja2 +0 -0
- {chapkit-0.26.0 → chapkit-0.28.0}/src/chapkit/cli/templates/migrate/dockerignore_migrate.jinja2 +0 -0
- {chapkit-0.26.0 → chapkit-0.28.0}/src/chapkit/cli/templates/migrate/gitignore_migrate.jinja2 +0 -0
- {chapkit-0.26.0 → chapkit-0.28.0}/src/chapkit/cli/templates/migrate/main_migrate.py.jinja2 +0 -0
- {chapkit-0.26.0 → chapkit-0.28.0}/src/chapkit/cli/templates/migrate/pyproject_migrate.toml.jinja2 +0 -0
- {chapkit-0.26.0 → chapkit-0.28.0}/src/chapkit/cli/templates/migrate/requirements_migrate.txt.jinja2 +0 -0
- {chapkit-0.26.0 → chapkit-0.28.0}/src/chapkit/cli/templates/pyproject.toml.jinja2 +0 -0
- {chapkit-0.26.0 → chapkit-0.28.0}/src/chapkit/cli/templates/scripts/predict.R.jinja2 +0 -0
- {chapkit-0.26.0 → chapkit-0.28.0}/src/chapkit/cli/templates/scripts/predict_model.py.jinja2 +0 -0
- {chapkit-0.26.0 → chapkit-0.28.0}/src/chapkit/cli/templates/scripts/train.R.jinja2 +0 -0
- {chapkit-0.26.0 → chapkit-0.28.0}/src/chapkit/cli/templates/scripts/train_model.py.jinja2 +0 -0
- {chapkit-0.26.0 → chapkit-0.28.0}/src/chapkit/cli/test/__init__.py +0 -0
- {chapkit-0.26.0 → chapkit-0.28.0}/src/chapkit/cli/test/command.py +0 -0
- {chapkit-0.26.0 → chapkit-0.28.0}/src/chapkit/cli/test/generator.py +0 -0
- {chapkit-0.26.0 → chapkit-0.28.0}/src/chapkit/cli/test/runner.py +0 -0
- {chapkit-0.26.0 → chapkit-0.28.0}/src/chapkit/cli/test/utils.py +0 -0
- {chapkit-0.26.0 → chapkit-0.28.0}/src/chapkit/config/__init__.py +0 -0
- {chapkit-0.26.0 → chapkit-0.28.0}/src/chapkit/config/manager.py +0 -0
- {chapkit-0.26.0 → chapkit-0.28.0}/src/chapkit/config/models.py +0 -0
- {chapkit-0.26.0 → chapkit-0.28.0}/src/chapkit/config/repository.py +0 -0
- {chapkit-0.26.0 → chapkit-0.28.0}/src/chapkit/config/router.py +0 -0
- {chapkit-0.26.0 → chapkit-0.28.0}/src/chapkit/config/schemas.py +0 -0
- {chapkit-0.26.0 → chapkit-0.28.0}/src/chapkit/data/__init__.py +0 -0
- {chapkit-0.26.0 → chapkit-0.28.0}/src/chapkit/data/dataframe.py +0 -0
- {chapkit-0.26.0 → chapkit-0.28.0}/src/chapkit/ml/__init__.py +0 -0
- {chapkit-0.26.0 → chapkit-0.28.0}/src/chapkit/ml/manager.py +0 -0
- {chapkit-0.26.0 → chapkit-0.28.0}/src/chapkit/ml/router.py +0 -0
- {chapkit-0.26.0 → chapkit-0.28.0}/src/chapkit/ml/runner.py +0 -0
- {chapkit-0.26.0 → chapkit-0.28.0}/src/chapkit/ml/schemas.py +0 -0
- {chapkit-0.26.0 → chapkit-0.28.0}/src/chapkit/py.typed +0 -0
- {chapkit-0.26.0 → chapkit-0.28.0}/src/chapkit/scheduler.py +0 -0
- {chapkit-0.26.0 → chapkit-0.28.0}/src/chapkit/utils.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.3
|
|
2
2
|
Name: chapkit
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.28.0
|
|
4
4
|
Summary: ML and data service modules built on servicekit - config, artifacts, and ML workflows
|
|
5
5
|
Keywords: ml,machine-learning,data-science,artifacts,tasks,config,servicekit
|
|
6
6
|
Author: Morten Hansen
|
|
@@ -16,7 +16,7 @@ Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
|
|
|
16
16
|
Requires-Dist: geojson-pydantic>=2.1.1
|
|
17
17
|
Requires-Dist: typer>=0.24.2
|
|
18
18
|
Requires-Dist: jinja2>=3.1.6
|
|
19
|
-
Requires-Dist: servicekit>=0.
|
|
19
|
+
Requires-Dist: servicekit>=0.12.0
|
|
20
20
|
Requires-Dist: httpx>=0.28.1
|
|
21
21
|
Requires-Dist: pandas>=2.3.3 ; extra == 'dataframe'
|
|
22
22
|
Requires-Dist: polars>=1.34.0 ; extra == 'dataframe'
|
|
@@ -257,13 +257,12 @@ Chapkit extends servicekit's `BaseServiceBuilder` with ML-specific features and
|
|
|
257
257
|
|
|
258
258
|
See the `examples/` directory for complete working examples:
|
|
259
259
|
|
|
260
|
-
- `config/` - Config CRUD walkthrough
|
|
261
|
-
- `
|
|
262
|
-
- `
|
|
263
|
-
- `ml_functional/`, `ml_class/`, `ml_shell/` - ML workflow patterns (`FunctionalModelRunner`, class-based `BaseModelRunner`, `ShellModelRunner`)
|
|
264
|
-
- `ml_pipeline/` - Multi-stage ML pipeline with hierarchical artifacts
|
|
260
|
+
- `config/` - Config CRUD walkthrough with seeding and a custom `ServiceInfo`
|
|
261
|
+
- `artifact/` - Artifact hierarchies with config linking, read-only API, and non-JSON payloads
|
|
262
|
+
- `ml_class/` - Class-based `BaseModelRunner` with lifecycle hooks and validation
|
|
265
263
|
- `library_usage/` - Using chapkit as a library with custom models
|
|
266
|
-
|
|
264
|
+
|
|
265
|
+
For the functional and shell runner patterns, scaffold a project with `chapkit init` (`--template shell-py` for the shell runner) — the generated `main.py` is the canonical example.
|
|
267
266
|
|
|
268
267
|
For a fresh project, prefer `chapkit init` (see [`docs/guides/cli-scaffolding.md`](docs/guides/cli-scaffolding.md)) — the `examples/` directory targets specific patterns rather than a full starting point.
|
|
269
268
|
|
|
@@ -219,13 +219,12 @@ Chapkit extends servicekit's `BaseServiceBuilder` with ML-specific features and
|
|
|
219
219
|
|
|
220
220
|
See the `examples/` directory for complete working examples:
|
|
221
221
|
|
|
222
|
-
- `config/` - Config CRUD walkthrough
|
|
223
|
-
- `
|
|
224
|
-
- `
|
|
225
|
-
- `ml_functional/`, `ml_class/`, `ml_shell/` - ML workflow patterns (`FunctionalModelRunner`, class-based `BaseModelRunner`, `ShellModelRunner`)
|
|
226
|
-
- `ml_pipeline/` - Multi-stage ML pipeline with hierarchical artifacts
|
|
222
|
+
- `config/` - Config CRUD walkthrough with seeding and a custom `ServiceInfo`
|
|
223
|
+
- `artifact/` - Artifact hierarchies with config linking, read-only API, and non-JSON payloads
|
|
224
|
+
- `ml_class/` - Class-based `BaseModelRunner` with lifecycle hooks and validation
|
|
227
225
|
- `library_usage/` - Using chapkit as a library with custom models
|
|
228
|
-
|
|
226
|
+
|
|
227
|
+
For the functional and shell runner patterns, scaffold a project with `chapkit init` (`--template shell-py` for the shell runner) — the generated `main.py` is the canonical example.
|
|
229
228
|
|
|
230
229
|
For a fresh project, prefer `chapkit init` (see [`docs/guides/cli-scaffolding.md`](docs/guides/cli-scaffolding.md)) — the `examples/` directory targets specific patterns rather than a full starting point.
|
|
231
230
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
[project]
|
|
2
2
|
name = "chapkit"
|
|
3
|
-
version = "0.
|
|
3
|
+
version = "0.28.0"
|
|
4
4
|
description = "ML and data service modules built on servicekit - config, artifacts, and ML workflows"
|
|
5
5
|
readme = "README.md"
|
|
6
6
|
authors = [{ name = "Morten Hansen", email = "morten@dhis2.org" }]
|
|
@@ -28,7 +28,7 @@ dependencies = [
|
|
|
28
28
|
"geojson-pydantic>=2.1.1",
|
|
29
29
|
"typer>=0.24.2",
|
|
30
30
|
"jinja2>=3.1.6",
|
|
31
|
-
"servicekit>=0.
|
|
31
|
+
"servicekit>=0.12.0",
|
|
32
32
|
"httpx>=0.28.1",
|
|
33
33
|
]
|
|
34
34
|
|
|
@@ -145,27 +145,17 @@ disallow_any_unimported = false
|
|
|
145
145
|
module = [
|
|
146
146
|
"chapkit.artifact.*",
|
|
147
147
|
"chapkit.config.*",
|
|
148
|
-
"chapkit.task.*",
|
|
149
148
|
"examples.*",
|
|
150
149
|
]
|
|
151
150
|
warn_return_any = false
|
|
152
151
|
|
|
153
152
|
[[tool.mypy.overrides]]
|
|
154
|
-
module = "
|
|
155
|
-
ignore_missing_imports = true
|
|
156
|
-
ignore_errors = true
|
|
157
|
-
|
|
158
|
-
[[tool.mypy.overrides]]
|
|
159
|
-
module = "examples.artifact_manager.*"
|
|
160
|
-
ignore_errors = true
|
|
161
|
-
|
|
162
|
-
[[tool.mypy.overrides]]
|
|
163
|
-
module = ["chapkit.data.dataframe", "examples.dataframe_usage.*"]
|
|
153
|
+
module = "chapkit.data.dataframe"
|
|
164
154
|
disable_error_code = ["import-not-found"]
|
|
165
155
|
|
|
166
156
|
[tool.pyright]
|
|
167
157
|
include = ["src", "tests", "examples"]
|
|
168
|
-
exclude = ["
|
|
158
|
+
exclude = ["**/.venv"]
|
|
169
159
|
pythonVersion = "3.13"
|
|
170
160
|
typeCheckingMode = "strict"
|
|
171
161
|
useLibraryCodeForTypes = true
|
|
@@ -9,6 +9,8 @@ from .schemas import (
|
|
|
9
9
|
ArtifactHierarchy,
|
|
10
10
|
ArtifactIn,
|
|
11
11
|
ArtifactOut,
|
|
12
|
+
ArtifactSummaryOut,
|
|
13
|
+
ArtifactSummaryTreeNode,
|
|
12
14
|
ArtifactTreeNode,
|
|
13
15
|
BaseArtifactData,
|
|
14
16
|
GenericArtifactData,
|
|
@@ -16,6 +18,7 @@ from .schemas import (
|
|
|
16
18
|
MLMetadata,
|
|
17
19
|
MLPredictionArtifactData,
|
|
18
20
|
MLTrainingWorkspaceArtifactData,
|
|
21
|
+
strip_content,
|
|
19
22
|
validate_artifact_data,
|
|
20
23
|
)
|
|
21
24
|
|
|
@@ -24,6 +27,8 @@ __all__ = [
|
|
|
24
27
|
"ArtifactHierarchy",
|
|
25
28
|
"ArtifactIn",
|
|
26
29
|
"ArtifactOut",
|
|
30
|
+
"ArtifactSummaryOut",
|
|
31
|
+
"ArtifactSummaryTreeNode",
|
|
27
32
|
"ArtifactTreeNode",
|
|
28
33
|
"ArtifactRepository",
|
|
29
34
|
"ArtifactManager",
|
|
@@ -35,5 +40,6 @@ __all__ = [
|
|
|
35
40
|
"GenericArtifactData",
|
|
36
41
|
"MLMetadata",
|
|
37
42
|
"GenericMetadata",
|
|
43
|
+
"strip_content",
|
|
38
44
|
"validate_artifact_data",
|
|
39
45
|
]
|
|
@@ -5,11 +5,17 @@ from typing import Any
|
|
|
5
5
|
|
|
6
6
|
from fastapi import Depends, HTTPException, Response, status
|
|
7
7
|
from servicekit.api.crud import CrudPermissions, CrudRouter
|
|
8
|
+
from servicekit.schemas import PaginatedResponse
|
|
8
9
|
|
|
9
10
|
from ..config.schemas import BaseConfig, ConfigOut
|
|
10
11
|
from ..data import DataFrame
|
|
11
12
|
from .manager import ArtifactManager
|
|
12
|
-
from .schemas import
|
|
13
|
+
from .schemas import (
|
|
14
|
+
ArtifactIn,
|
|
15
|
+
ArtifactOut,
|
|
16
|
+
ArtifactSummaryOut,
|
|
17
|
+
ArtifactSummaryTreeNode,
|
|
18
|
+
)
|
|
13
19
|
|
|
14
20
|
|
|
15
21
|
class ArtifactRouter(CrudRouter[ArtifactIn, ArtifactOut]):
|
|
@@ -40,6 +46,29 @@ class ArtifactRouter(CrudRouter[ArtifactIn, ArtifactOut]):
|
|
|
40
46
|
**kwargs,
|
|
41
47
|
)
|
|
42
48
|
|
|
49
|
+
def _register_find_all_route(self, manager_dependency: Any, manager_annotation: Any) -> None:
|
|
50
|
+
"""Register the list route returning content-less artifact summaries."""
|
|
51
|
+
summary_annotation: Any = ArtifactSummaryOut
|
|
52
|
+
collection_response_model: Any = list[summary_annotation] | PaginatedResponse[summary_annotation]
|
|
53
|
+
|
|
54
|
+
@self.router.get("", response_model=collection_response_model)
|
|
55
|
+
async def find_all(
|
|
56
|
+
page: int | None = None,
|
|
57
|
+
size: int | None = None,
|
|
58
|
+
manager: ArtifactManager = manager_dependency,
|
|
59
|
+
) -> list[ArtifactSummaryOut] | PaginatedResponse[ArtifactSummaryOut]:
|
|
60
|
+
from servicekit.api.pagination import create_paginated_response
|
|
61
|
+
|
|
62
|
+
if page is not None and size is not None:
|
|
63
|
+
items, total = await manager.find_paginated(page, size)
|
|
64
|
+
summaries = [ArtifactSummaryOut.from_artifact(item) for item in items]
|
|
65
|
+
return create_paginated_response(summaries, total, page, size)
|
|
66
|
+
artifacts = await manager.find_all()
|
|
67
|
+
return [ArtifactSummaryOut.from_artifact(item) for item in artifacts]
|
|
68
|
+
|
|
69
|
+
self._annotate_manager(find_all, manager_annotation)
|
|
70
|
+
find_all.__annotations__["return"] = list[summary_annotation] | PaginatedResponse[summary_annotation]
|
|
71
|
+
|
|
43
72
|
def _register_routes(self) -> None:
|
|
44
73
|
"""Register artifact CRUD routes and tree operations."""
|
|
45
74
|
super()._register_routes()
|
|
@@ -49,7 +78,7 @@ class ArtifactRouter(CrudRouter[ArtifactIn, ArtifactOut]):
|
|
|
49
78
|
async def expand_artifact(
|
|
50
79
|
entity_id: str,
|
|
51
80
|
manager: ArtifactManager = Depends(manager_factory),
|
|
52
|
-
) ->
|
|
81
|
+
) -> ArtifactSummaryTreeNode:
|
|
53
82
|
ulid_id = self._parse_ulid(entity_id)
|
|
54
83
|
|
|
55
84
|
expanded = await manager.expand_artifact(ulid_id)
|
|
@@ -58,12 +87,12 @@ class ArtifactRouter(CrudRouter[ArtifactIn, ArtifactOut]):
|
|
|
58
87
|
status_code=status.HTTP_404_NOT_FOUND,
|
|
59
88
|
detail=f"Artifact with id {entity_id} not found",
|
|
60
89
|
)
|
|
61
|
-
return expanded
|
|
90
|
+
return ArtifactSummaryTreeNode.from_tree_node(expanded)
|
|
62
91
|
|
|
63
92
|
async def build_tree(
|
|
64
93
|
entity_id: str,
|
|
65
94
|
manager: ArtifactManager = Depends(manager_factory),
|
|
66
|
-
) ->
|
|
95
|
+
) -> ArtifactSummaryTreeNode:
|
|
67
96
|
ulid_id = self._parse_ulid(entity_id)
|
|
68
97
|
|
|
69
98
|
tree = await manager.build_tree(ulid_id)
|
|
@@ -72,22 +101,22 @@ class ArtifactRouter(CrudRouter[ArtifactIn, ArtifactOut]):
|
|
|
72
101
|
status_code=status.HTTP_404_NOT_FOUND,
|
|
73
102
|
detail=f"Artifact with id {entity_id} not found",
|
|
74
103
|
)
|
|
75
|
-
return tree
|
|
104
|
+
return ArtifactSummaryTreeNode.from_tree_node(tree)
|
|
76
105
|
|
|
77
106
|
self.register_entity_operation(
|
|
78
107
|
"expand",
|
|
79
108
|
expand_artifact,
|
|
80
|
-
response_model=
|
|
109
|
+
response_model=ArtifactSummaryTreeNode,
|
|
81
110
|
summary="Expand artifact",
|
|
82
|
-
description="Get artifact with hierarchy metadata but without children",
|
|
111
|
+
description="Get artifact with hierarchy metadata but without children or content",
|
|
83
112
|
)
|
|
84
113
|
|
|
85
114
|
self.register_entity_operation(
|
|
86
115
|
"tree",
|
|
87
116
|
build_tree,
|
|
88
|
-
response_model=
|
|
117
|
+
response_model=ArtifactSummaryTreeNode,
|
|
89
118
|
summary="Build artifact tree",
|
|
90
|
-
description="Build hierarchical tree structure rooted at the given artifact",
|
|
119
|
+
description="Build hierarchical tree structure rooted at the given artifact, without content",
|
|
91
120
|
)
|
|
92
121
|
|
|
93
122
|
# Conditionally register config access endpoint
|
|
@@ -39,6 +39,40 @@ class ArtifactTreeNode(ArtifactOut):
|
|
|
39
39
|
return cls.model_validate(artifact.model_dump())
|
|
40
40
|
|
|
41
41
|
|
|
42
|
+
def strip_content(data: Any) -> Any:
|
|
43
|
+
"""Return a shallow copy of artifact data without the heavy 'content' key."""
|
|
44
|
+
if not isinstance(data, dict):
|
|
45
|
+
return data
|
|
46
|
+
return {key: value for key, value in data.items() if key != "content"}
|
|
47
|
+
|
|
48
|
+
|
|
49
|
+
class ArtifactSummaryOut(ArtifactOut):
|
|
50
|
+
"""Artifact output without the heavy inline 'content', for list responses."""
|
|
51
|
+
|
|
52
|
+
@classmethod
|
|
53
|
+
def from_artifact(cls, artifact: ArtifactOut) -> Self:
|
|
54
|
+
"""Create a content-less summary from a full artifact output schema."""
|
|
55
|
+
return cls.model_validate({**artifact.model_dump(exclude={"data"}), "data": strip_content(artifact.data)})
|
|
56
|
+
|
|
57
|
+
|
|
58
|
+
class ArtifactSummaryTreeNode(ArtifactTreeNode):
|
|
59
|
+
"""Artifact tree node without inline 'content', with content stripped recursively."""
|
|
60
|
+
|
|
61
|
+
@classmethod
|
|
62
|
+
def from_tree_node(cls, node: ArtifactTreeNode) -> Self:
|
|
63
|
+
"""Create a content-less tree node, stripping content from the node and its children."""
|
|
64
|
+
children = (
|
|
65
|
+
[cls.from_tree_node(child).model_dump() for child in node.children] if node.children is not None else None
|
|
66
|
+
)
|
|
67
|
+
return cls.model_validate(
|
|
68
|
+
{
|
|
69
|
+
**node.model_dump(exclude={"data", "children"}),
|
|
70
|
+
"data": strip_content(node.data),
|
|
71
|
+
"children": children,
|
|
72
|
+
}
|
|
73
|
+
)
|
|
74
|
+
|
|
75
|
+
|
|
42
76
|
class ArtifactHierarchy(BaseModel):
|
|
43
77
|
"""Configuration for artifact hierarchy with level labels."""
|
|
44
78
|
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{chapkit-0.26.0 → chapkit-0.28.0}/src/chapkit/cli/templates/migrate/CHAPKIT_migrate.md.jinja2
RENAMED
|
File without changes
|
{chapkit-0.26.0 → chapkit-0.28.0}/src/chapkit/cli/templates/migrate/Dockerfile_migrate.jinja2
RENAMED
|
File without changes
|
|
File without changes
|
{chapkit-0.26.0 → chapkit-0.28.0}/src/chapkit/cli/templates/migrate/README_migrate.md.jinja2
RENAMED
|
File without changes
|
{chapkit-0.26.0 → chapkit-0.28.0}/src/chapkit/cli/templates/migrate/dockerignore_migrate.jinja2
RENAMED
|
File without changes
|
{chapkit-0.26.0 → chapkit-0.28.0}/src/chapkit/cli/templates/migrate/gitignore_migrate.jinja2
RENAMED
|
File without changes
|
|
File without changes
|
{chapkit-0.26.0 → chapkit-0.28.0}/src/chapkit/cli/templates/migrate/pyproject_migrate.toml.jinja2
RENAMED
|
File without changes
|
{chapkit-0.26.0 → chapkit-0.28.0}/src/chapkit/cli/templates/migrate/requirements_migrate.txt.jinja2
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|