aipmodel 0.2.71__tar.gz → 0.2.72__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.
- {aipmodel-0.2.71 → aipmodel-0.2.72}/PKG-INFO +1 -1
- {aipmodel-0.2.71 → aipmodel-0.2.72}/README.md +91 -1
- {aipmodel-0.2.71 → aipmodel-0.2.72}/aipmodel/__init__.py +1 -1
- {aipmodel-0.2.71 → aipmodel-0.2.72}/aipmodel/model_registry.py +21 -1
- {aipmodel-0.2.71 → aipmodel-0.2.72}/aipmodel.egg-info/PKG-INFO +1 -1
- {aipmodel-0.2.71 → aipmodel-0.2.72}/setup.py +1 -1
- {aipmodel-0.2.71 → aipmodel-0.2.72}/MANIFEST.in +0 -0
- {aipmodel-0.2.71 → aipmodel-0.2.72}/aipmodel/CephS3Manager.py +0 -0
- {aipmodel-0.2.71 → aipmodel-0.2.72}/aipmodel/acl_manager.py +0 -0
- {aipmodel-0.2.71 → aipmodel-0.2.72}/aipmodel/exceptions.py +0 -0
- {aipmodel-0.2.71 → aipmodel-0.2.72}/aipmodel/template.py +0 -0
- {aipmodel-0.2.71 → aipmodel-0.2.72}/aipmodel/update_checker.py +0 -0
- {aipmodel-0.2.71 → aipmodel-0.2.72}/aipmodel.egg-info/SOURCES.txt +0 -0
- {aipmodel-0.2.71 → aipmodel-0.2.72}/aipmodel.egg-info/dependency_links.txt +0 -0
- {aipmodel-0.2.71 → aipmodel-0.2.72}/aipmodel.egg-info/requires.txt +0 -0
- {aipmodel-0.2.71 → aipmodel-0.2.72}/aipmodel.egg-info/top_level.txt +0 -0
- {aipmodel-0.2.71 → aipmodel-0.2.72}/requirements.txt +0 -0
- {aipmodel-0.2.71 → aipmodel-0.2.72}/setup.cfg +0 -0
|
@@ -120,6 +120,71 @@ reset). The SDK now **retries these automatically**, so `add_model`,
|
|
|
120
120
|
worker) is fully protected; for multiple workers/replicas add a distributed
|
|
121
121
|
lock (Mlops-Core/Redis).
|
|
122
122
|
|
|
123
|
+
## Registry ↔ Storage Consistency (Integrity, Repair & Disaster Recovery)
|
|
124
|
+
|
|
125
|
+
A model lives in **two systems at once**: its metadata in the registry
|
|
126
|
+
(Mlops-Core) and its files in S3/Ceph. If either side changes behind the SDK's
|
|
127
|
+
back (someone deletes a folder in Ceph by hand, or the registry loses data),
|
|
128
|
+
you get a **zombie** (registry entry pointing at missing files) or an
|
|
129
|
+
**orphan** (files no registry entry references). The SDK detects, repairs, and
|
|
130
|
+
recovers all of these:
|
|
131
|
+
|
|
132
|
+
### Recovery sidecar: `_meta.json`
|
|
133
|
+
|
|
134
|
+
Every `add_model` writes a small `_meta.json` next to each version's files
|
|
135
|
+
(model name, version, number, category, tags, owner, size, created, public).
|
|
136
|
+
Storage is therefore **self-describing** — a registry entry can be rebuilt from
|
|
137
|
+
S3 alone.
|
|
138
|
+
|
|
139
|
+
### Detect
|
|
140
|
+
|
|
141
|
+
```python
|
|
142
|
+
report = manager.verify_model_integrity(model_name="my_model")
|
|
143
|
+
# {"status": "ok" | "missing_files" | "orphan_files",
|
|
144
|
+
# "versions": [{"version": "v1.0", "files_exist": True, ...}],
|
|
145
|
+
# "orphan_folders": [...]}
|
|
146
|
+
|
|
147
|
+
manager.verify_all_models() # one report per model in your project
|
|
148
|
+
manager.find_orphan_models() # S3 model folders unknown to the registry
|
|
149
|
+
# (each flagged recoverable=True when _meta.json exists)
|
|
150
|
+
```
|
|
151
|
+
|
|
152
|
+
### Repair (each guarded against misuse)
|
|
153
|
+
|
|
154
|
+
```python
|
|
155
|
+
# Zombie version (files deleted in Ceph) -> remove it from the registry.
|
|
156
|
+
# REFUSES if the files actually still exist (use delete_model for a real delete).
|
|
157
|
+
manager.remove_missing_version("my_model", "v1.0")
|
|
158
|
+
|
|
159
|
+
# Stray folders under a model that no version references -> delete them.
|
|
160
|
+
manager.purge_orphan_folders(model_name="my_model")
|
|
161
|
+
|
|
162
|
+
# S3 model folder the registry doesn't know -> delete it.
|
|
163
|
+
# REFUSES if the id IS registered.
|
|
164
|
+
manager.purge_orphan_model(model_id)
|
|
165
|
+
```
|
|
166
|
+
|
|
167
|
+
### Disaster recovery (registry data lost, S3 survives)
|
|
168
|
+
|
|
169
|
+
```python
|
|
170
|
+
for orphan in manager.find_orphan_models():
|
|
171
|
+
if orphan["recoverable"]:
|
|
172
|
+
manager.recover_model_from_storage(orphan["model_id"])
|
|
173
|
+
# Rebuilds the registry entry (name, all versions, latest, sizes, category,
|
|
174
|
+
# tags) from the _meta.json sidecars. Files stay where they are.
|
|
175
|
+
```
|
|
176
|
+
|
|
177
|
+
Consistency is also protected *proactively*: `add_model` rolls back files,
|
|
178
|
+
registry entry and ACL record together on failure, and `delete_model` updates
|
|
179
|
+
the registry **before** deleting S3 (a crash can leave a harmless orphan, never
|
|
180
|
+
a zombie). Versions added before the sidecar feature (< 0.2.69) have no
|
|
181
|
+
`_meta.json` and are reported as non-recoverable.
|
|
182
|
+
|
|
183
|
+
> **S3-compat note:** the client is configured to stay compatible with
|
|
184
|
+
> MinIO/Ceph RGW across boto3 versions (legacy `Content-MD5` checksums on
|
|
185
|
+
> newer boto3, with a per-object delete fallback if a batch delete is
|
|
186
|
+
> rejected) — no user action needed.
|
|
187
|
+
|
|
123
188
|
## Access Control (ACL)
|
|
124
189
|
|
|
125
190
|
ACL is **off by default** and fully optional. Toggle it with one env var:
|
|
@@ -314,7 +379,32 @@ manager.delete_model(model_name="demo_model_hf")
|
|
|
314
379
|
| **`set_latest_version`** | `model_name`, `version` | Updates the 'latest' pointer to a specific version without modifying files. |
|
|
315
380
|
| **`set_model_public`** | `model_name`, `public` | Moves a model's files between the private and public buckets (transactional, parallel server-side copy). |
|
|
316
381
|
| **`share_model`** | `model_name`, `target_user`, `access_level` | Grants another user access to a model. Requires `ACL_ENABLED=true`. |
|
|
317
|
-
| **`delete_model`** | `model_name`, `version` | If `version` provided: deletes that version (and rolls "latest" back to the next one if it was the latest). If that was the *last* version, the model container is removed too. If `version` is omitted: deletes the entire model in one call — this already is "delete all versions", no need to delete one by one. |
|
|
382
|
+
| **`delete_model`** | `model_name`, `version` | If `version` provided: deletes that version (and rolls "latest" back to the next one if it was the latest). If that was the *last* version, the model container is removed too. If `version` is omitted: deletes the entire model in one call — this already is "delete all versions", no need to delete one by one. Registry metadata is updated **before** S3 files are removed (crash-safe ordering). |
|
|
383
|
+
| **`verify_model_integrity`** | `model_name` or `model_id` | Cross-checks one model between registry and S3. Returns `{status: ok\|missing_files\|orphan_files, versions: [...], orphan_folders: [...]}`. |
|
|
384
|
+
| **`verify_all_models`** | — | Runs `verify_model_integrity` over every model in your project; returns a list of reports. |
|
|
385
|
+
| **`find_orphan_models`** | — | Lists S3 model folders the registry doesn't know about, each flagged `recoverable` when a `_meta.json` sidecar exists. |
|
|
386
|
+
| **`remove_missing_version`** | `model_name`, `version` | Sync-repair for a zombie version whose S3 files were deleted: removes it from the registry. Refuses if the files still exist. |
|
|
387
|
+
| **`purge_orphan_folders`** | `model_name` or `model_id` | Deletes S3 folders under a model that no registry version references. Returns the purged folder names. |
|
|
388
|
+
| **`purge_orphan_model`** | `model_id` | Deletes the S3 storage of a model unknown to the registry. Refuses for registered ids. |
|
|
389
|
+
| **`recover_model_from_storage`** | `model_id` | Disaster recovery: rebuilds the registry entry (all versions, latest, category, tags) from the `_meta.json` sidecars in S3. Returns the new registry id. |
|
|
390
|
+
|
|
391
|
+
### Backward compatibility
|
|
392
|
+
|
|
393
|
+
The ClearML → Mlops-Core rename kept the old public names working, so code
|
|
394
|
+
written against the pre-0.2.65 SDK does not break:
|
|
395
|
+
|
|
396
|
+
- **Health-check methods** — `check_clearml_service()` and `check_clearml_auth()`
|
|
397
|
+
still exist as thin aliases of `check_mlops_core_service()` /
|
|
398
|
+
`check_mlops_core_auth()`.
|
|
399
|
+
- **Instance attributes** — `mgr.CLEARML_API_HOST`, `CLEARML_WEB_HOST`,
|
|
400
|
+
`CLEARML_USERNAME`, `CLEARML_ACCESS_KEY`, `CLEARML_SECRET_KEY` are kept as
|
|
401
|
+
aliases of the canonical `MLOPS_CORE_*` attributes.
|
|
402
|
+
- **Constructor / env** — the `CLEARML_API_HOST` / `CLEARML_WEB_HOST` kwargs and
|
|
403
|
+
env vars are accepted as deprecated fallbacks (the `MLOPS_CORE_*` names win if
|
|
404
|
+
both are set).
|
|
405
|
+
- **Method signatures are additive only** — every new parameter (`owner`,
|
|
406
|
+
`model_folder_name`, the `list_models` filters) is optional with a default
|
|
407
|
+
that reproduces the old behavior; nothing was removed or reordered.
|
|
318
408
|
|
|
319
409
|
---
|
|
320
410
|
|
|
@@ -434,7 +434,17 @@ class MLOpsManager:
|
|
|
434
434
|
# from the user-management wire format — do not rename them.
|
|
435
435
|
self.MLOPS_CORE_ACCESS_KEY = user_info["clearml_access_key"]
|
|
436
436
|
self.MLOPS_CORE_SECRET_KEY = user_info["clearml_secret_key"]
|
|
437
|
-
|
|
437
|
+
|
|
438
|
+
# Backward-compatibility attribute aliases (pre-0.2.65 names). Callers
|
|
439
|
+
# that read mgr.CLEARML_API_HOST / CLEARML_WEB_HOST / CLEARML_USERNAME /
|
|
440
|
+
# CLEARML_ACCESS_KEY / CLEARML_SECRET_KEY keep working after the
|
|
441
|
+
# Mlops-Core rename — the new MLOPS_CORE_* names are canonical.
|
|
442
|
+
self.CLEARML_API_HOST = self.MLOPS_CORE_API_HOST
|
|
443
|
+
self.CLEARML_WEB_HOST = self.MLOPS_CORE_WEB_HOST
|
|
444
|
+
self.CLEARML_USERNAME = self.MLOPS_CORE_USERNAME
|
|
445
|
+
self.CLEARML_ACCESS_KEY = self.MLOPS_CORE_ACCESS_KEY
|
|
446
|
+
self.CLEARML_SECRET_KEY = self.MLOPS_CORE_SECRET_KEY
|
|
447
|
+
|
|
438
448
|
if not skip_connection_check:
|
|
439
449
|
if self.verbose:
|
|
440
450
|
print("[SDK_INFO] Performing health checks...")
|
|
@@ -608,6 +618,16 @@ class MLOpsManager:
|
|
|
608
618
|
print(f"[SDK_FAIL] Mlops-Core Auth Check Failed: {e}")
|
|
609
619
|
return False
|
|
610
620
|
|
|
621
|
+
# Backward-compatibility aliases. These methods were renamed
|
|
622
|
+
# check_clearml_* -> check_mlops_core_* as part of the Mlops-Core rename;
|
|
623
|
+
# the old names are kept as thin forwarders so pre-0.2.65 callers that do
|
|
624
|
+
# mgr.check_clearml_service() / mgr.check_clearml_auth() keep working.
|
|
625
|
+
def check_clearml_service(self):
|
|
626
|
+
return self.check_mlops_core_service()
|
|
627
|
+
|
|
628
|
+
def check_clearml_auth(self):
|
|
629
|
+
return self.check_mlops_core_auth()
|
|
630
|
+
|
|
611
631
|
def get_model_id_by_name(self, name, owner=None):
|
|
612
632
|
"""
|
|
613
633
|
Resolves a model name to its Mlops-Core ID.
|
|
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
|