@zhuoyuezs/ml-platform 0.1.12 → 0.1.14
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.
package/checksums.json
CHANGED
|
@@ -7,18 +7,18 @@
|
|
|
7
7
|
},
|
|
8
8
|
{
|
|
9
9
|
"path": "runtime/business-client/package-lock.json",
|
|
10
|
-
"sha256": "sha256:
|
|
10
|
+
"sha256": "sha256:ce726848e97416159f1fe8141082f67927405b45de8367e35c3da30cb0e8a639",
|
|
11
11
|
"size_bytes": 381
|
|
12
12
|
},
|
|
13
13
|
{
|
|
14
14
|
"path": "runtime/business-client/package.json",
|
|
15
|
-
"sha256": "sha256:
|
|
15
|
+
"sha256": "sha256:c275cc028d7f1e0257d1354ed2df082f879a6c79d17e73d65ae2e21b80dee33d",
|
|
16
16
|
"size_bytes": 501
|
|
17
17
|
},
|
|
18
18
|
{
|
|
19
19
|
"path": "runtime/business-client/src/catalog.js",
|
|
20
|
-
"sha256": "sha256:
|
|
21
|
-
"size_bytes":
|
|
20
|
+
"sha256": "sha256:6c8f800574fda6ccc4e6176d9d607d4408df2e88c8e9c33289701dd7699b50ca",
|
|
21
|
+
"size_bytes": 56017
|
|
22
22
|
},
|
|
23
23
|
{
|
|
24
24
|
"path": "runtime/business-client/src/cli.js",
|
package/package.json
CHANGED
package/release.json
CHANGED
|
@@ -13,8 +13,8 @@
|
|
|
13
13
|
"entrypoint": "src/cli.js",
|
|
14
14
|
"name": "ml-platform",
|
|
15
15
|
"path": "runtime/business-client",
|
|
16
|
-
"sha256": "sha256:
|
|
17
|
-
"version": "0.7.
|
|
16
|
+
"sha256": "sha256:b7c1b24987c680dc1b13bbcf49dc61c4856e9843a06499f78ed5bbd6ac10c0f5",
|
|
17
|
+
"version": "0.7.4"
|
|
18
18
|
},
|
|
19
19
|
"policy_sha256": "sha256:02fbde0134696b78c0c365d6e0b76c9814227208da5b2b3d4e5dbd82dc4a3606",
|
|
20
20
|
"public_schema_versions": [
|
|
@@ -25,7 +25,7 @@
|
|
|
25
25
|
"ml_data_platform.feature_set/v1",
|
|
26
26
|
"ml_data_platform.dataset_manifest/v1"
|
|
27
27
|
],
|
|
28
|
-
"release_version": "0.1.
|
|
28
|
+
"release_version": "0.1.14",
|
|
29
29
|
"runtime_requirements": {
|
|
30
30
|
"node": ">=18",
|
|
31
31
|
"os": [
|
|
@@ -37,16 +37,16 @@
|
|
|
37
37
|
"skills": {
|
|
38
38
|
"feature-management": {
|
|
39
39
|
"path": "skills/feature-management",
|
|
40
|
-
"requires_cli": ">=0.7.
|
|
41
|
-
"revision": "0.1.
|
|
40
|
+
"requires_cli": ">=0.7.4 <0.8.0",
|
|
41
|
+
"revision": "0.1.14",
|
|
42
42
|
"sha256": "sha256:182b6f2df4fe58c946e482dfaf416c7d5b78c6fde9c8c8d7293103246618cb4e"
|
|
43
43
|
},
|
|
44
44
|
"model-lifecycle-management": {
|
|
45
45
|
"path": "skills/model-lifecycle-management",
|
|
46
|
-
"requires_cli": ">=0.7.
|
|
47
|
-
"revision": "0.1.
|
|
46
|
+
"requires_cli": ">=0.7.4 <0.8.0",
|
|
47
|
+
"revision": "0.1.14",
|
|
48
48
|
"sha256": "sha256:61ba17f955b36d1c2e8329a10454d040ee7eca5afdb90ff0914d3f85b6e2d203"
|
|
49
49
|
}
|
|
50
50
|
},
|
|
51
|
-
"source_commit": "
|
|
51
|
+
"source_commit": "9175c96d8475003b17c5e0c4c3df4f8cf8614c0f"
|
|
52
52
|
}
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@zhuoyuezs/ml-platform-business-client",
|
|
3
|
-
"version": "0.7.
|
|
3
|
+
"version": "0.7.4",
|
|
4
4
|
"lockfileVersion": 3,
|
|
5
5
|
"requires": true,
|
|
6
6
|
"packages": {
|
|
7
7
|
"": {
|
|
8
8
|
"name": "@zhuoyuezs/ml-platform-business-client",
|
|
9
|
-
"version": "0.7.
|
|
9
|
+
"version": "0.7.4",
|
|
10
10
|
"license": "UNLICENSED",
|
|
11
11
|
"bin": {
|
|
12
12
|
"ml-platform": "src/cli.js"
|
|
@@ -167,7 +167,22 @@ function loadCatalog(directory) {
|
|
|
167
167
|
}
|
|
168
168
|
|
|
169
169
|
async function fetchAll(client, endpoint, params = {}) { const rows = []; for (let offset = 0; ; offset += 500) { const response = await client.get(endpoint, { ...params, limit: 500, offset }); if (Array.isArray(response)) return response; const page = response.items; if (!Array.isArray(page)) throw new Error(`${endpoint} returned an invalid list response`); rows.push(...page); if (response.total == null || rows.length >= response.total || page.length < 500) return rows; } }
|
|
170
|
-
async function snapshot(client, targetProject) { const scope = { project: targetProject ?? "default" }; const [parameters, operators, features, featureSets, datasets] = await Promise.all([fetchAll(client, "/parameters", scope), fetchAll(client, "/operators", scope), fetchAll(client, "/features", scope), fetchAll(client, "/feature-sets", scope), fetchAll(client, "/datasets", { ...scope, include_deleted: true })]); return { parameters: new Map(parameters.map((x) => [key(x), x])), operators: new Map(operators.map((x) => [key(
|
|
170
|
+
async function snapshot(client, targetProject) { const scope = { project: targetProject ?? "default" }; const [parameters, operators, features, featureSets, datasets] = await Promise.all([fetchAll(client, "/parameters", scope), fetchAll(client, "/operators", scope), fetchAll(client, "/features", scope), fetchAll(client, "/feature-sets", scope), fetchAll(client, "/datasets", { ...scope, include_deleted: true })]); return { parameters: new Map(parameters.map((x) => [key(x), x])), operators: new Map(operators.map((x) => [key(x), x])), features: new Map(features.map((x) => [key(x), x])), feature_sets: new Map(featureSets.map((x) => [key(x), x])), datasets: new Map(datasets.filter((x) => !x.deleted_at).map((x) => [datasetKey(x), x])) }; }
|
|
171
|
+
|
|
172
|
+
async function hydrate(client, current, assets, endpoint, normalizer, keyFn = key, seen = new Set()) { for (const asset of assets) { const assetKey = keyFn(asset); if (current.has(assetKey) && !seen.has(assetKey)) { current.set(assetKey, normalizer(await client.get(endpoint(asset)))); seen.add(assetKey); } } }
|
|
173
|
+
async function hydrateCatalog(client, catalog, current) {
|
|
174
|
+
const hydrated = { parameters: new Set(), operators: new Set(), features: new Set(), feature_sets: new Set(), datasets: new Set() };
|
|
175
|
+
const resource = (prefix) => (asset) => `/${prefix}/${encodeURIComponent(asset.project)}/${encodeURIComponent(asset.name)}/${encodeURIComponent(asset.version)}`;
|
|
176
|
+
await hydrate(client, current.parameters, catalog.parameters, resource("parameters"), normalizeParameter, key, hydrated.parameters);
|
|
177
|
+
const operatorRefs = catalog.features.map((asset) => ({ project: asset.project, name: asset.operator, version: asset.operator_version }));
|
|
178
|
+
await hydrate(client, current.operators, [...catalog.operators.map((item) => item.spec), ...operatorRefs], resource("operators"), normalizeOperator, key, hydrated.operators);
|
|
179
|
+
const featureSetRefs = catalog.datasets.map((asset) => ({ project: asset.project, ...asset.feature_set }));
|
|
180
|
+
await hydrate(client, current.feature_sets, [...catalog.feature_sets, ...featureSetRefs], resource("feature-sets"), normalizeFeatureSet, key, hydrated.feature_sets);
|
|
181
|
+
await hydrate(client, current.datasets, catalog.datasets, (asset) => `/datasets/${encodeURIComponent(asset.project)}/${encodeURIComponent(asset.dataset_id)}/${encodeURIComponent(asset.dataset_version)}`, normalizeDataset, datasetKey, hydrated.datasets);
|
|
182
|
+
const declaredFeatureSets = new Map(catalog.feature_sets.map((asset) => [key(asset), asset]));
|
|
183
|
+
const featureRefs = catalog.datasets.flatMap((asset) => (declaredFeatureSets.get(referenceKey(asset.feature_set)) ?? current.feature_sets.get(referenceKey(asset.feature_set)) ?? { features: [] }).features.map((feature) => ({ project: asset.project, ...feature })));
|
|
184
|
+
await hydrate(client, current.features, [...catalog.features, ...featureRefs], resource("features"), normalizeFeature, key, hydrated.features);
|
|
185
|
+
}
|
|
171
186
|
|
|
172
187
|
function requiresPackage(spec) { return ["custom_python", "feature", "spark_udf"].includes(spec.type) && spec.code_artifact == null && !String(spec.package_uri ?? "").startsWith("pythonpath://"); }
|
|
173
188
|
function validateCatalog(catalog, current) {
|
|
@@ -198,8 +213,7 @@ function assertImmutable(label, assetKey, candidate, existing) { if (existing &&
|
|
|
198
213
|
function sha256File(file) { return `sha256:${crypto.createHash("sha256").update(fs.readFileSync(file)).digest("hex")}`; }
|
|
199
214
|
|
|
200
215
|
async function applyCatalog(catalog, client, dryRun, targetProject) {
|
|
201
|
-
validateCatalogProject(catalog, targetProject); const current = await snapshot(client, targetProject); validateCatalog(catalog, current); const groups = { parameters: catalog.parameters.length, operators: catalog.operators.length, features: catalog.features.length, feature_sets: catalog.feature_sets.length, datasets: catalog.datasets.length }; const summary = Object.fromEntries(Object.entries(groups).map(([name, count]) => [name, { declared: count, planned: 0, applied: 0, unchanged: 0 }]));
|
|
202
|
-
for (const asset of catalog.parameters) { const assetKey = key(asset); if (current.parameters.has(assetKey)) current.parameters.set(assetKey, normalizeParameter(await client.get(`/parameters/${encodeURIComponent(asset.project)}/${encodeURIComponent(asset.name)}/${encodeURIComponent(asset.version)}`))); }
|
|
216
|
+
validateCatalogProject(catalog, targetProject); const current = await snapshot(client, targetProject); await hydrateCatalog(client, catalog, current); validateCatalog(catalog, current); const groups = { parameters: catalog.parameters.length, operators: catalog.operators.length, features: catalog.features.length, feature_sets: catalog.feature_sets.length, datasets: catalog.datasets.length }; const summary = Object.fromEntries(Object.entries(groups).map(([name, count]) => [name, { declared: count, planned: 0, applied: 0, unchanged: 0 }]));
|
|
203
217
|
for (const asset of catalog.parameters) assertImmutable("parameter", key(asset), asset, current.parameters.get(key(asset)));
|
|
204
218
|
for (const item of catalog.operators) { const existing = current.operators.get(key(item.spec)); if (!existing) continue; let candidate = item.spec; if (item.package_path) { if (existing.code_hash !== sha256File(item.package_path) || !existing.code_artifact) throw new Error(`operator version is immutable: ${key(item.spec)}; publish a new version`); candidate = normalizeOperator({ ...item.spec, code_hash: existing.code_artifact.sha256, package_uri: existing.code_artifact.uri, code_artifact: existing.code_artifact }); } assertImmutable("operator", key(item.spec), candidate, existing); }
|
|
205
219
|
const plain = async (assets, existing, label, endpoint, keyFn = key, params) => { for (const asset of assets) { const assetKey = keyFn(asset); assertImmutable(label, assetKey, asset, existing.get(assetKey)); if (existing.has(assetKey)) summary[label].unchanged += 1; else if (dryRun) summary[label].planned += 1; else { await client.post(endpoint, asset, params); summary[label].applied += 1; } } };
|