lumen-resources 0.2.0__py3-none-any.whl
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.
- lumen_resources/__init__.py +89 -0
- lumen_resources/cli.py +402 -0
- lumen_resources/downloader.py +449 -0
- lumen_resources/exceptions.py +110 -0
- lumen_resources/lumen_config.py +459 -0
- lumen_resources/lumen_config_validator.py +270 -0
- lumen_resources/model_info.py +233 -0
- lumen_resources/model_info_validator.py +257 -0
- lumen_resources/platform.py +270 -0
- lumen_resources/result_schemas/README.md +14 -0
- lumen_resources/result_schemas/__init__.py +14 -0
- lumen_resources/result_schemas/embedding_v1.py +29 -0
- lumen_resources/result_schemas/face_v1.py +55 -0
- lumen_resources/result_schemas/labels_v1.py +39 -0
- lumen_resources/schemas/config-schema.yaml +249 -0
- lumen_resources/schemas/model_info-schema.json +166 -0
- lumen_resources/schemas/result_schemas/embedding_v1.json +35 -0
- lumen_resources/schemas/result_schemas/face_v1.json +61 -0
- lumen_resources/schemas/result_schemas/labels_v1.json +49 -0
- lumen_resources-0.2.0.dist-info/METADATA +133 -0
- lumen_resources-0.2.0.dist-info/RECORD +24 -0
- lumen_resources-0.2.0.dist-info/WHEEL +5 -0
- lumen_resources-0.2.0.dist-info/entry_points.txt +2 -0
- lumen_resources-0.2.0.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
"""Lumen Resources - Unified Model Resource Management.
|
|
2
|
+
|
|
3
|
+
Configuration-driven tool for managing ML model resources with production-grade
|
|
4
|
+
YAML configuration, JSON Schema validation, and Pydantic models. Provides a
|
|
5
|
+
unified interface for downloading models from multiple platforms including
|
|
6
|
+
HuggingFace Hub and ModelScope.
|
|
7
|
+
|
|
8
|
+
This package offers:
|
|
9
|
+
- Configuration-driven YAML setup for ML model resources
|
|
10
|
+
- Multi-platform support (HuggingFace Hub, ModelScope)
|
|
11
|
+
- Runtime flexibility (ONNX, PyTorch, TensorFlow, RKNN)
|
|
12
|
+
- Production-grade validation using JSON Schema and Pydantic
|
|
13
|
+
- CLI interface for command-line operations
|
|
14
|
+
- Programmatic API for integration into other applications
|
|
15
|
+
|
|
16
|
+
Example:
|
|
17
|
+
>>> from lumen_resources import load_and_validate_config, Downloader
|
|
18
|
+
>>>
|
|
19
|
+
>>> # Load and validate configuration
|
|
20
|
+
>>> config = load_and_validate_config("config.yaml")
|
|
21
|
+
>>>
|
|
22
|
+
>>> # Download models
|
|
23
|
+
>>> downloader = Downloader(config, verbose=True)
|
|
24
|
+
>>> results = downloader.download_all()
|
|
25
|
+
>>>
|
|
26
|
+
>>> # Check results
|
|
27
|
+
>>> for model_type, result in results.items():
|
|
28
|
+
... if result.success:
|
|
29
|
+
... print(f"Downloaded: {model_type} to {result.model_path}")
|
|
30
|
+
... else:
|
|
31
|
+
... print(f"Failed: {model_type} - {result.error}")
|
|
32
|
+
|
|
33
|
+
The package follows a layered architecture:
|
|
34
|
+
- Configuration layer: Pydantic models for type-safe config handling
|
|
35
|
+
- Validation layer: JSON Schema and Pydantic validation
|
|
36
|
+
- Platform layer: Unified interface for different model repositories
|
|
37
|
+
- Download layer: Efficient model downloading with validation
|
|
38
|
+
- CLI layer: User-friendly command-line interface
|
|
39
|
+
"""
|
|
40
|
+
|
|
41
|
+
from .lumen_config import LumenConfig, Runtime, Region
|
|
42
|
+
from .downloader import Downloader, DownloadResult
|
|
43
|
+
from .exceptions import (
|
|
44
|
+
ResourceError,
|
|
45
|
+
ConfigError,
|
|
46
|
+
DownloadError,
|
|
47
|
+
PlatformUnavailableError,
|
|
48
|
+
ValidationError,
|
|
49
|
+
ModelInfoError,
|
|
50
|
+
)
|
|
51
|
+
from .lumen_config_validator import load_and_validate_config
|
|
52
|
+
|
|
53
|
+
from .model_info import ModelInfo, Source, Runtimes, Metadata
|
|
54
|
+
from .model_info_validator import load_and_validate_model_info
|
|
55
|
+
from .result_schemas import (
|
|
56
|
+
EmbeddingV1,
|
|
57
|
+
FaceV1,
|
|
58
|
+
LabelsV1
|
|
59
|
+
)
|
|
60
|
+
|
|
61
|
+
__version__ = "0.1.0"
|
|
62
|
+
|
|
63
|
+
__all__ = [
|
|
64
|
+
# Configuration
|
|
65
|
+
"LumenConfig",
|
|
66
|
+
"Runtime",
|
|
67
|
+
"Region",
|
|
68
|
+
"load_and_validate_config",
|
|
69
|
+
# Model Info
|
|
70
|
+
"ModelInfo",
|
|
71
|
+
"Source",
|
|
72
|
+
"Runtimes",
|
|
73
|
+
"Metadata",
|
|
74
|
+
"load_and_validate_model_info",
|
|
75
|
+
# Response Validation
|
|
76
|
+
"FaceV1",
|
|
77
|
+
"EmbeddingV1",
|
|
78
|
+
"LabelsV1",
|
|
79
|
+
# Downloader
|
|
80
|
+
"Downloader",
|
|
81
|
+
"DownloadResult",
|
|
82
|
+
# Exceptions
|
|
83
|
+
"ResourceError",
|
|
84
|
+
"ConfigError",
|
|
85
|
+
"DownloadError",
|
|
86
|
+
"PlatformUnavailableError",
|
|
87
|
+
"ValidationError",
|
|
88
|
+
"ModelInfoError",
|
|
89
|
+
]
|
lumen_resources/cli.py
ADDED
|
@@ -0,0 +1,402 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Command Line Interface for Lumen Resources
|
|
3
|
+
|
|
4
|
+
Provides user-friendly commands for downloading and managing model resources.
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
import argparse
|
|
8
|
+
import sys
|
|
9
|
+
from pathlib import Path
|
|
10
|
+
|
|
11
|
+
from .downloader import Downloader, DownloadResult
|
|
12
|
+
from .lumen_config_validator import ConfigValidator, load_and_validate_config
|
|
13
|
+
from .model_info_validator import (
|
|
14
|
+
ModelInfoValidator,
|
|
15
|
+
load_and_validate_model_info,
|
|
16
|
+
)
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
def print_banner():
|
|
20
|
+
"""Print welcome banner.
|
|
21
|
+
|
|
22
|
+
Displays the Lumen Resources application banner with formatting
|
|
23
|
+
to provide a professional command-line interface experience.
|
|
24
|
+
"""
|
|
25
|
+
print("=" * 60)
|
|
26
|
+
print(" Lumen Resources - Model Resource Manager")
|
|
27
|
+
print("=" * 60)
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
def print_summary(results: dict[str, DownloadResult]) -> None:
|
|
31
|
+
"""Print download summary with results and statistics.
|
|
32
|
+
|
|
33
|
+
Args:
|
|
34
|
+
results: Dictionary mapping model type identifiers to DownloadResult objects.
|
|
35
|
+
Contains information about download success status, file paths, and errors.
|
|
36
|
+
"""
|
|
37
|
+
print("\n" + "=" * 60)
|
|
38
|
+
print("📊 Download Summary")
|
|
39
|
+
print("=" * 60)
|
|
40
|
+
|
|
41
|
+
success_count = sum(1 for r in results.values() if r.success)
|
|
42
|
+
total_count = len(results)
|
|
43
|
+
|
|
44
|
+
for model_type, result in results.items():
|
|
45
|
+
status = "✅" if result.success else "❌"
|
|
46
|
+
print(f"{status} {model_type.upper()}")
|
|
47
|
+
if result.success:
|
|
48
|
+
print(f" Path: {result.model_path}")
|
|
49
|
+
if result.missing_files:
|
|
50
|
+
print(f" ⚠️ Missing: {', '.join(result.missing_files)}")
|
|
51
|
+
else:
|
|
52
|
+
print(f" Error: {result.error}")
|
|
53
|
+
|
|
54
|
+
print("\n" + "=" * 60)
|
|
55
|
+
print(f"🎉 Completed: {success_count}/{total_count} successful")
|
|
56
|
+
print("=" * 60)
|
|
57
|
+
|
|
58
|
+
|
|
59
|
+
def cmd_download(args: argparse.Namespace) -> None:
|
|
60
|
+
"""Handle download command for model resources.
|
|
61
|
+
|
|
62
|
+
Downloads all enabled models from the configuration file, with support for
|
|
63
|
+
forced re-downloading and detailed progress reporting. Validates configuration
|
|
64
|
+
before downloading and provides a comprehensive summary of results.
|
|
65
|
+
|
|
66
|
+
Args:
|
|
67
|
+
args: Parsed command line arguments containing:
|
|
68
|
+
- config: Path to configuration YAML file
|
|
69
|
+
- force: Whether to force re-download even if models are cached
|
|
70
|
+
|
|
71
|
+
Raises:
|
|
72
|
+
SystemExit: If configuration validation fails or downloads encounter errors.
|
|
73
|
+
"""
|
|
74
|
+
config_path = Path(args.config)
|
|
75
|
+
|
|
76
|
+
try:
|
|
77
|
+
# Load and validate configuration
|
|
78
|
+
print("📋 Loading configuration...")
|
|
79
|
+
config = load_and_validate_config(config_path)
|
|
80
|
+
|
|
81
|
+
print(f"🌍 Region: {config.metadata.region.value}")
|
|
82
|
+
print(f"📁 Cache directory: {config.metadata.cache_dir}")
|
|
83
|
+
|
|
84
|
+
# Count enabled models
|
|
85
|
+
enabled_models = []
|
|
86
|
+
for service_name, service_config in config.services.items():
|
|
87
|
+
if service_config.enabled:
|
|
88
|
+
for alias in service_config.models.keys():
|
|
89
|
+
enabled_models.append(f"{service_name}:{alias}")
|
|
90
|
+
print(f"🎯 Enabled models: {', '.join(enabled_models)}")
|
|
91
|
+
|
|
92
|
+
# Download resources
|
|
93
|
+
print("\n🚀 Starting download...")
|
|
94
|
+
downloader = Downloader(config, verbose=True)
|
|
95
|
+
results = downloader.download_all(force=args.force)
|
|
96
|
+
|
|
97
|
+
# Print summary
|
|
98
|
+
print_summary(results)
|
|
99
|
+
|
|
100
|
+
# Exit with error if any downloads failed
|
|
101
|
+
if not all(r.success for r in results.values()):
|
|
102
|
+
sys.exit(1)
|
|
103
|
+
|
|
104
|
+
except Exception as e:
|
|
105
|
+
print(f"\n❌ Error: {e}")
|
|
106
|
+
sys.exit(1)
|
|
107
|
+
|
|
108
|
+
|
|
109
|
+
def cmd_validate(args: argparse.Namespace) -> None:
|
|
110
|
+
"""Handle validate command for configuration files.
|
|
111
|
+
|
|
112
|
+
Validates YAML configuration files against the Lumen configuration schema
|
|
113
|
+
with options for strict Pydantic validation or flexible JSON Schema validation.
|
|
114
|
+
Displays detailed configuration information when validation succeeds.
|
|
115
|
+
|
|
116
|
+
Args:
|
|
117
|
+
args: Parsed command line arguments containing:
|
|
118
|
+
- config: Path to configuration YAML file
|
|
119
|
+
- strict: Whether to use strict Pydantic validation
|
|
120
|
+
|
|
121
|
+
Raises:
|
|
122
|
+
SystemExit: If configuration validation fails.
|
|
123
|
+
"""
|
|
124
|
+
config_path = Path(args.config)
|
|
125
|
+
|
|
126
|
+
try:
|
|
127
|
+
print("📋 Validating configuration...")
|
|
128
|
+
|
|
129
|
+
# Use new Pydantic-based validator
|
|
130
|
+
validator = ConfigValidator()
|
|
131
|
+
is_valid, errors = validator.validate_file(config_path, strict=args.strict)
|
|
132
|
+
|
|
133
|
+
if not is_valid:
|
|
134
|
+
print("❌ Validation failed:\n")
|
|
135
|
+
for error in errors:
|
|
136
|
+
print(f" • {error}")
|
|
137
|
+
sys.exit(1)
|
|
138
|
+
|
|
139
|
+
# Load the validated config
|
|
140
|
+
config = load_and_validate_config(config_path)
|
|
141
|
+
|
|
142
|
+
print("✅ Configuration is valid!")
|
|
143
|
+
print(f"\n🌍 Region: {config.metadata.region.value}")
|
|
144
|
+
print(f"📁 Cache directory: {config.metadata.cache_dir}")
|
|
145
|
+
print(f"🚀 Deployment mode: {config.deployment.mode}")
|
|
146
|
+
|
|
147
|
+
if config.deployment.mode == "single":
|
|
148
|
+
print(f" Service: {config.deployment.service}")
|
|
149
|
+
else:
|
|
150
|
+
services_list = [s.root for s in (config.deployment.services or [])]
|
|
151
|
+
print(f" Services: {', '.join(services_list)}")
|
|
152
|
+
|
|
153
|
+
print("\n🌐 Server:")
|
|
154
|
+
print(f" Port: {config.server.port}")
|
|
155
|
+
print(f" Host: {config.server.host}")
|
|
156
|
+
if config.server.mdns and config.server.mdns.enabled:
|
|
157
|
+
print(f" mDNS: {config.server.mdns.service_name}")
|
|
158
|
+
|
|
159
|
+
print("\n📦 Services:")
|
|
160
|
+
for service_name, service_config in config.services.items():
|
|
161
|
+
status = "✅ enabled" if service_config.enabled else "⚪ disabled"
|
|
162
|
+
print(f" • {service_name} ({status})")
|
|
163
|
+
if service_config.enabled:
|
|
164
|
+
print(f" Package: {service_config.package}")
|
|
165
|
+
print(f" Models: {', '.join(service_config.models.keys())}")
|
|
166
|
+
for alias, model in service_config.models.items():
|
|
167
|
+
print(f" - {alias}: {model.model} ({model.runtime.value})")
|
|
168
|
+
if model.dataset:
|
|
169
|
+
print(f" Dataset: {model.dataset}")
|
|
170
|
+
|
|
171
|
+
except Exception as e:
|
|
172
|
+
print(f"❌ Validation failed: {e}")
|
|
173
|
+
sys.exit(1)
|
|
174
|
+
|
|
175
|
+
|
|
176
|
+
def cmd_validate_model_info(args: argparse.Namespace) -> None:
|
|
177
|
+
"""Handle validate-model-info command for model metadata files.
|
|
178
|
+
|
|
179
|
+
Validates model_info.json files against the model information schema
|
|
180
|
+
with options for strict Pydantic validation or flexible JSON Schema validation.
|
|
181
|
+
Displays comprehensive model information when validation succeeds.
|
|
182
|
+
|
|
183
|
+
Args:
|
|
184
|
+
args: Parsed command line arguments containing:
|
|
185
|
+
- model_info: Path to model_info.json file
|
|
186
|
+
- strict: Whether to use strict Pydantic validation
|
|
187
|
+
|
|
188
|
+
Raises:
|
|
189
|
+
SystemExit: If model_info.json validation fails.
|
|
190
|
+
"""
|
|
191
|
+
model_info_path = Path(args.model_info)
|
|
192
|
+
|
|
193
|
+
try:
|
|
194
|
+
print("📋 Validating model_info.json...")
|
|
195
|
+
|
|
196
|
+
# Use ModelInfoValidator
|
|
197
|
+
validator = ModelInfoValidator()
|
|
198
|
+
is_valid, errors = validator.validate_file(model_info_path, strict=args.strict)
|
|
199
|
+
|
|
200
|
+
if not is_valid:
|
|
201
|
+
print("❌ Validation failed:\n")
|
|
202
|
+
for error in errors:
|
|
203
|
+
print(f" • {error}")
|
|
204
|
+
sys.exit(1)
|
|
205
|
+
|
|
206
|
+
# Load the validated model info
|
|
207
|
+
model_info = load_and_validate_model_info(model_info_path)
|
|
208
|
+
|
|
209
|
+
print("✅ Model info is valid!")
|
|
210
|
+
print(f"\n📦 Model: {model_info.name}")
|
|
211
|
+
print(f" Version: {model_info.version}")
|
|
212
|
+
print(f" Type: {model_info.model_type}")
|
|
213
|
+
print(f" Embedding dimension: {model_info.embedding_dim}")
|
|
214
|
+
|
|
215
|
+
print("\n📥 Source:")
|
|
216
|
+
print(f" Format: {model_info.source.format.value}")
|
|
217
|
+
print(f" Repository: {model_info.source.repo_id}")
|
|
218
|
+
|
|
219
|
+
print("\n🔧 Runtimes:")
|
|
220
|
+
for runtime_name, runtime_config in model_info.runtimes.items():
|
|
221
|
+
status = "✅ available" if runtime_config.available else "⚪ not available"
|
|
222
|
+
print(f" • {runtime_name} ({status})")
|
|
223
|
+
if runtime_config.available and runtime_config.files:
|
|
224
|
+
if isinstance(runtime_config.files, list):
|
|
225
|
+
print(f" Files: {len(runtime_config.files)} file(s)")
|
|
226
|
+
else:
|
|
227
|
+
total_files = sum(
|
|
228
|
+
len(files) for files in runtime_config.files.values()
|
|
229
|
+
)
|
|
230
|
+
devices_count = len(runtime_config.files)
|
|
231
|
+
print(
|
|
232
|
+
f" Files: {total_files} file(s) across {devices_count} device(s)"
|
|
233
|
+
)
|
|
234
|
+
if runtime_config.devices:
|
|
235
|
+
print(f" Devices: {', '.join(runtime_config.devices)}")
|
|
236
|
+
|
|
237
|
+
if model_info.datasets:
|
|
238
|
+
print("\n📊 Datasets:")
|
|
239
|
+
for dataset_name, dataset_file in model_info.datasets.items():
|
|
240
|
+
print(f" • {dataset_name}: {dataset_file}")
|
|
241
|
+
|
|
242
|
+
if model_info.metadata:
|
|
243
|
+
print("\n📝 Metadata:")
|
|
244
|
+
if model_info.metadata.license:
|
|
245
|
+
print(f" License: {model_info.metadata.license}")
|
|
246
|
+
if model_info.metadata.author:
|
|
247
|
+
print(f" Author: {model_info.metadata.author}")
|
|
248
|
+
if model_info.metadata.created_at:
|
|
249
|
+
print(f" Created: {model_info.metadata.created_at}")
|
|
250
|
+
if model_info.metadata.tags:
|
|
251
|
+
print(f" Tags: {', '.join(model_info.metadata.tags)}")
|
|
252
|
+
|
|
253
|
+
except Exception as e:
|
|
254
|
+
print(f"❌ Validation failed: {e}")
|
|
255
|
+
sys.exit(1)
|
|
256
|
+
|
|
257
|
+
|
|
258
|
+
def cmd_list(args: argparse.Namespace) -> None:
|
|
259
|
+
"""Handle list command for cached models.
|
|
260
|
+
|
|
261
|
+
Lists all models currently cached in the specified cache directory,
|
|
262
|
+
showing model information including version, available runtimes, and
|
|
263
|
+
file contents when model_info.json files are available.
|
|
264
|
+
|
|
265
|
+
Args:
|
|
266
|
+
args: Parsed command line arguments containing:
|
|
267
|
+
- cache_dir: Path to cache directory (defaults to ~/.lumen/)
|
|
268
|
+
"""
|
|
269
|
+
cache_dir = Path(args.cache_dir).expanduser()
|
|
270
|
+
models_dir = cache_dir / "models"
|
|
271
|
+
|
|
272
|
+
if not models_dir.exists():
|
|
273
|
+
print(f"No models found in {cache_dir}")
|
|
274
|
+
return
|
|
275
|
+
|
|
276
|
+
print(f"📦 Models in {cache_dir}:")
|
|
277
|
+
print()
|
|
278
|
+
|
|
279
|
+
model_dirs = sorted([d for d in models_dir.iterdir() if d.is_dir()])
|
|
280
|
+
|
|
281
|
+
if not model_dirs:
|
|
282
|
+
print(" (empty)")
|
|
283
|
+
return
|
|
284
|
+
|
|
285
|
+
for model_dir in model_dirs:
|
|
286
|
+
print(f" 📁 {model_dir.name}")
|
|
287
|
+
|
|
288
|
+
# Check for model_info.json
|
|
289
|
+
info_file = model_dir / "model_info.json"
|
|
290
|
+
if info_file.exists():
|
|
291
|
+
import json
|
|
292
|
+
|
|
293
|
+
try:
|
|
294
|
+
with open(info_file, "r") as f:
|
|
295
|
+
info = json.load(f)
|
|
296
|
+
print(f" Version: {info.get('version', 'unknown')}")
|
|
297
|
+
runtimes = info.get("runtimes", {})
|
|
298
|
+
available_runtimes = [
|
|
299
|
+
r for r, data in runtimes.items() if data.get("available")
|
|
300
|
+
]
|
|
301
|
+
if available_runtimes:
|
|
302
|
+
print(f" Runtimes: {', '.join(available_runtimes)}")
|
|
303
|
+
except Exception:
|
|
304
|
+
pass
|
|
305
|
+
|
|
306
|
+
# List subdirectories
|
|
307
|
+
subdirs = [d.name for d in model_dir.iterdir() if d.is_dir()]
|
|
308
|
+
if subdirs:
|
|
309
|
+
print(f" Contents: {', '.join(subdirs)}")
|
|
310
|
+
|
|
311
|
+
print()
|
|
312
|
+
|
|
313
|
+
|
|
314
|
+
def main() -> None:
|
|
315
|
+
"""Main CLI entry point.
|
|
316
|
+
|
|
317
|
+
Sets up the argument parser with subcommands for different operations
|
|
318
|
+
(download, validate, validate-model-info, list) and dispatches to the
|
|
319
|
+
appropriate handler functions. Handles help display and error cases.
|
|
320
|
+
|
|
321
|
+
Raises:
|
|
322
|
+
SystemExit: If no command is provided or if a command handler exits with an error.
|
|
323
|
+
"""
|
|
324
|
+
parser = argparse.ArgumentParser(
|
|
325
|
+
prog="lumen-resources",
|
|
326
|
+
description="Lumen Resources - Model Resource Manager",
|
|
327
|
+
formatter_class=argparse.RawDescriptionHelpFormatter,
|
|
328
|
+
)
|
|
329
|
+
|
|
330
|
+
subparsers = parser.add_subparsers(dest="command", help="Available commands")
|
|
331
|
+
|
|
332
|
+
# Download command
|
|
333
|
+
download_parser = subparsers.add_parser(
|
|
334
|
+
"download", help="Download model resources from configuration"
|
|
335
|
+
)
|
|
336
|
+
_ = download_parser.add_argument("config", help="Path to configuration YAML file")
|
|
337
|
+
_ = download_parser.add_argument(
|
|
338
|
+
"--force", action="store_true", help="Force re-download even if cached"
|
|
339
|
+
)
|
|
340
|
+
download_parser.set_defaults(func=cmd_download)
|
|
341
|
+
|
|
342
|
+
# Validate command
|
|
343
|
+
validate_parser = subparsers.add_parser(
|
|
344
|
+
"validate", help="Validate configuration file"
|
|
345
|
+
)
|
|
346
|
+
_ = validate_parser.add_argument("config", help="Path to configuration YAML file")
|
|
347
|
+
_ = validate_parser.add_argument(
|
|
348
|
+
"--strict",
|
|
349
|
+
action="store_true",
|
|
350
|
+
default=True,
|
|
351
|
+
help="Use strict Pydantic validation (default: True)",
|
|
352
|
+
)
|
|
353
|
+
_ = validate_parser.add_argument(
|
|
354
|
+
"--schema-only",
|
|
355
|
+
action="store_false",
|
|
356
|
+
dest="strict",
|
|
357
|
+
help="Use JSON Schema validation only (less strict)",
|
|
358
|
+
)
|
|
359
|
+
validate_parser.set_defaults(func=cmd_validate)
|
|
360
|
+
|
|
361
|
+
# Validate model info command
|
|
362
|
+
validate_model_parser = subparsers.add_parser(
|
|
363
|
+
"validate-model-info", help="Validate model_info.json file"
|
|
364
|
+
)
|
|
365
|
+
_ = validate_model_parser.add_argument(
|
|
366
|
+
"model_info", help="Path to model_info.json file"
|
|
367
|
+
)
|
|
368
|
+
_ = validate_model_parser.add_argument(
|
|
369
|
+
"--strict",
|
|
370
|
+
action="store_true",
|
|
371
|
+
default=True,
|
|
372
|
+
help="Use strict Pydantic validation (default: True)",
|
|
373
|
+
)
|
|
374
|
+
_ = validate_model_parser.add_argument(
|
|
375
|
+
"--schema-only",
|
|
376
|
+
action="store_false",
|
|
377
|
+
dest="strict",
|
|
378
|
+
help="Use JSON Schema validation only (less strict)",
|
|
379
|
+
)
|
|
380
|
+
validate_model_parser.set_defaults(func=cmd_validate_model_info)
|
|
381
|
+
|
|
382
|
+
# List command
|
|
383
|
+
list_parser = subparsers.add_parser("list", help="List cached models")
|
|
384
|
+
_ = list_parser.add_argument(
|
|
385
|
+
"cache_dir", nargs="?", default="~/.lumen/", help="Cache directory path"
|
|
386
|
+
)
|
|
387
|
+
list_parser.set_defaults(func=cmd_list)
|
|
388
|
+
|
|
389
|
+
args: argparse.Namespace = parser.parse_args()
|
|
390
|
+
|
|
391
|
+
if not args.command:
|
|
392
|
+
parser.print_help()
|
|
393
|
+
sys.exit(1)
|
|
394
|
+
|
|
395
|
+
print_banner()
|
|
396
|
+
print()
|
|
397
|
+
|
|
398
|
+
args.func(args)
|
|
399
|
+
|
|
400
|
+
|
|
401
|
+
if __name__ == "__main__":
|
|
402
|
+
main()
|