azureml-registry-tools 0.1.0a15__py3-none-any.whl → 0.1.0a16__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.
@@ -432,7 +432,7 @@
432
432
  "skuListDefinition": {
433
433
  "type": "string",
434
434
  "description": "A comma-separated list of valid SKUs with no duplicates",
435
- "pattern": "^(Standard_(DS3_v2|NC12s_v3|NC16as_T4_v3|NC24ads_A100_v4|NC24rs_v3|NC24s_v3|NC40ads_H100_v5|NC48ads_A100_v4|NC4as_T4_v3|NC64as_T4_v3|NC6s_v3|NC80adis_H100_v5|NC8as_T4_v3|NC96ads_A100_v4|ND40rs_v2|ND96amsr_A100_v4|ND96asr_v4|ND96isr_H100_v5|DS12_v2|DS4_v2|DS5_v2|D16a_v4|D16as_v4|D32a_v4|D32as_v4|D48a_v4|D48as_v4|D64a_v4|D64as_v4|D8a_v4|D8as_v4|D96a_v4|D96as_v4|E16s_v3|E2s_v3|E32s_v3|E48s_v3|E4s_v3|E64s_v3|E8s_v3|F16s_v2|F32s_v2|F48s_v2|F4s_v2|F64s_v2|F72s_v2|F8s_v2|FX12mds|FX24mds|FX36mds|FX48mds|FX4mds|NV12s_v3|NV24s_v3|NV48s_v3))(?:\\s*,\\s*Standard_(DS3_v2|NC12s_v3|NC16as_T4_v3|NC24ads_A100_v4|NC24rs_v3|NC24s_v3|NC40ads_H100_v5|NC48ads_A100_v4|NC4as_T4_v3|NC64as_T4_v3|NC6s_v3|NC80adis_H100_v5|NC8as_T4_v3|NC96ads_A100_v4|ND40rs_v2|ND96amsr_A100_v4|ND96asr_v4|ND96isr_H100_v5|DS12_v2|DS4_v2|DS5_v2|D16a_v4|D16as_v4|D32a_v4|D32as_v4|D48a_v4|D48as_v4|D64a_v4|D64as_v4|D8a_v4|D8as_v4|D96a_v4|D96as_v4|E16s_v3|E2s_v3|E32s_v3|E48s_v3|E4s_v3|E64s_v3|E8s_v3|F16s_v2|F32s_v2|F48s_v2|F4s_v2|F64s_v2|F72s_v2|F8s_v2|FX12mds|FX24mds|FX36mds|FX48mds|FX4mds|NV12s_v3|NV24s_v3|NV48s_v3))*$"
435
+ "pattern": "^(Standard_(DS3_v2|NC12s_v3|NC16as_T4_v3|NC24ads_A100_v4|NC24rs_v3|NC24s_v3|NC40ads_H100_v5|NC48ads_A100_v4|NC4as_T4_v3|NC64as_T4_v3|NC6s_v3|NC80adis_H100_v5|NC8as_T4_v3|NC96ads_A100_v4|ND40rs_v2|ND96amsr_A100_v4|ND96amsr_v4|ND96asr_v4|ND96isr_H100_v5|DS12_v2|DS4_v2|DS5_v2|D16a_v4|D16as_v4|D32a_v4|D32as_v4|D48a_v4|D48as_v4|D64a_v4|D64as_v4|D8a_v4|D8as_v4|D96a_v4|D96as_v4|E16s_v3|E2s_v3|E32s_v3|E48s_v3|E4s_v3|E64s_v3|E8s_v3|F16s_v2|F32s_v2|F48s_v2|F4s_v2|F64s_v2|F72s_v2|F8s_v2|FX12mds|FX24mds|FX36mds|FX48mds|FX4mds|NV12s_v3|NV24s_v3|NV48s_v3))(?:\\s*,\\s*Standard_(DS3_v2|NC12s_v3|NC16as_T4_v3|NC24ads_A100_v4|NC24rs_v3|NC24s_v3|NC40ads_H100_v5|NC48ads_A100_v4|NC4as_T4_v3|NC64as_T4_v3|NC6s_v3|NC80adis_H100_v5|NC8as_T4_v3|NC96ads_A100_v4|ND40rs_v2|ND96amsr_A100_v4|ND96amsr_v4|ND96asr_v4|ND96isr_H100_v5|DS12_v2|DS4_v2|DS5_v2|D16a_v4|D16as_v4|D32a_v4|D32as_v4|D48a_v4|D48as_v4|D64a_v4|D64as_v4|D8a_v4|D8as_v4|D96a_v4|D96as_v4|E16s_v3|E2s_v3|E32s_v3|E48s_v3|E4s_v3|E64s_v3|E8s_v3|F16s_v2|F32s_v2|F48s_v2|F4s_v2|F64s_v2|F72s_v2|F8s_v2|FX12mds|FX24mds|FX36mds|FX48mds|FX4mds|NV12s_v3|NV24s_v3|NV48s_v3))*$"
436
436
  },
437
437
  "skuEnum": {
438
438
  "enum": [
@@ -452,6 +452,7 @@
452
452
  "Standard_NC96ads_A100_v4",
453
453
  "Standard_ND40rs_v2",
454
454
  "Standard_ND96amsr_A100_v4",
455
+ "Standard_ND96amsr_v4",
455
456
  "Standard_ND96asr_v4",
456
457
  "Standard_ND96isr_H100_v5",
457
458
  "Standard_DS12_v2",
@@ -53,7 +53,8 @@ def load_schema(schema_file: Path, allow_additional_properties: bool = False) ->
53
53
  def validate_model_schema(input_dirs: List[Path],
54
54
  schema_file: Path,
55
55
  asset_config_filename: str,
56
- allow_additional_properties: bool = False) -> bool:
56
+ allow_additional_properties: bool = False,
57
+ changed_files: List[Path] = None) -> bool:
57
58
  """Validate model variant schema.
58
59
 
59
60
  Args:
@@ -61,6 +62,7 @@ def validate_model_schema(input_dirs: List[Path],
61
62
  schema_file (Path): File containing model variant schema.
62
63
  asset_config_filename (str): Asset config filename to search for.
63
64
  allow_additional_properties (bool): Whether to allow additional properties not defined in schema.
65
+ changed_files (List[Path], optional): List of changed files, used to filter assets. Defaults to None.
64
66
 
65
67
  Returns:
66
68
  bool: True on success.
@@ -71,63 +73,82 @@ def validate_model_schema(input_dirs: List[Path],
71
73
  # Create validator instance for collecting all errors
72
74
  validator = jsonschema.Draft7Validator(loaded_schema)
73
75
 
76
+ # Gather list of just changed assets, for later filtering
77
+ changed_assets = util.find_asset_config_files(input_dirs, asset_config_filename, changed_files) if changed_files else None # noqa: E501
78
+
74
79
  asset_count = 0
75
80
  model_count = 0
81
+ changed_model_count = 0
76
82
  error_count = 0
77
83
  for input_dir in input_dirs:
78
84
  # Recursively find all files with the name matching asset_config_filename
79
- for asset_config in util.find_assets(input_dir, asset_config_filename):
85
+ for asset_config_path in util.find_asset_config_files(input_dir, asset_config_filename):
80
86
  asset_count += 1
87
+
88
+ validate_this = changed_assets is None or asset_config_path in changed_assets
89
+
90
+ try:
91
+ asset_config = assets.AssetConfig(asset_config_path)
92
+ except Exception as e:
93
+ raise Exception(f"Error loading asset config from {asset_config_path}: {e}")
94
+
81
95
  file_path = asset_config.spec_with_path
96
+
82
97
  if asset_config.type == assets.AssetType.MODEL:
83
98
  model_count += 1
84
- # Validate the file against the schema
85
- try:
86
- with open(file_path, "r") as f:
87
- spec_config = yaml.safe_load(f)
88
-
89
- # Collect all validation errors
90
- errors = list(validator.iter_errors(spec_config))
91
-
92
- if not errors:
93
- logger.print(f"{file_path} is valid.")
94
- else:
95
- logger.log_error(f"\n‼️{file_path} has {len(errors)} validation error(s):")
96
-
97
- for e in errors:
98
- # Get detailed error information for each error
99
- error_path = '.'.join(str(p) for p in e.path) if e.path else "root"
100
- line_info = ""
101
-
102
- # Get line number from jsonschema error if available
103
- if hasattr(e, 'lineno') and e.lineno is not None:
104
- line_info = f" at line {e.lineno}"
105
- else:
106
- # Try to find line number by looking at the path and instance
107
- try:
108
- with open(file_path, "r") as f:
109
- yaml_content = f.readlines()
110
- yaml_lines = []
111
- for idx, line in enumerate(yaml_content):
112
- if error_path in line:
113
- yaml_lines.append(f"line {idx+1}: {line.strip()}")
114
- if yaml_lines:
115
- line_info = "\nPossible location(s):\n " + "\n ".join(yaml_lines)
116
- except Exception:
117
- pass
118
-
119
- schema_path = '.'.join(str(p) for p in e.schema_path)
120
- logger.print(f"⚠️ {file_path} is invalid at path '{error_path}'{line_info}:")
121
- logger.print(f" Error: {e.message}")
122
- logger.print(f" Instance: {e.instance}")
123
- logger.print(f" Schema path: {schema_path}")
99
+
100
+ if validate_this:
101
+ changed_model_count += 1
102
+ # Validate the file against the schema
103
+ try:
104
+ with open(file_path, "r") as f:
105
+ spec_config = yaml.safe_load(f)
106
+
107
+ # Collect all validation errors
108
+ errors = list(validator.iter_errors(spec_config))
109
+
110
+ if not errors:
111
+ logger.print(f"{file_path} is valid.")
112
+ else:
113
+ logger.log_error(f"\n‼️{file_path} has {len(errors)} validation error(s):")
114
+
115
+ for e in errors:
116
+ # Get detailed error information for each error
117
+ error_path = '.'.join(str(p) for p in e.path) if e.path else "root"
118
+ line_info = ""
119
+
120
+ # Get line number from jsonschema error if available
121
+ if hasattr(e, 'lineno') and e.lineno is not None:
122
+ line_info = f" at line {e.lineno}"
123
+ else:
124
+ # Try to find line number by looking at the path and instance
125
+ try:
126
+ with open(file_path, "r") as f:
127
+ yaml_content = f.readlines()
128
+ yaml_lines = []
129
+ for idx, line in enumerate(yaml_content):
130
+ if error_path in line:
131
+ yaml_lines.append(f"line {idx+1}: {line.strip()}")
132
+ if yaml_lines:
133
+ line_info = "\nPossible location(s):\n " + "\n ".join(yaml_lines)
134
+ except Exception:
135
+ pass
136
+
137
+ schema_path = '.'.join(str(p) for p in e.schema_path)
138
+ logger.print(f"⚠️ {file_path} is invalid at path '{error_path}'{line_info}:")
139
+ logger.print(f" Error: {e.message}")
140
+ logger.print(f" Instance: {e.instance}")
141
+ logger.print(f" Schema path: {schema_path}")
142
+ error_count += 1
143
+ except Exception as e:
144
+ logger.log_error(f"Error processing {file_path}: {str(e)}")
124
145
  error_count += 1
125
- except Exception as e:
126
- logger.log_error(f"Error processing {file_path}: {str(e)}")
127
- error_count += 1
128
146
 
129
147
  logger.print(f"Found {asset_count} total asset(s).")
130
- logger.print(f"Found {error_count} model(s) with error(s) out of {model_count} total model(s)")
148
+ if changed_assets is not None:
149
+ logger.print(f"Found {error_count} model(s) with error(s) out of {changed_model_count} total changed model(s)")
150
+ else:
151
+ logger.print(f"Found {error_count} model(s) with error(s) out of {model_count} total model(s)")
131
152
  return error_count == 0
132
153
 
133
154
 
@@ -142,16 +163,20 @@ if __name__ == "__main__":
142
163
  help="Asset config file name to search for")
143
164
  parser.add_argument("--allow-additional-properties", action="store_true",
144
165
  help="Allow additional properties not defined in the schema")
166
+ parser.add_argument("-c", "--changed-files",
167
+ help="Comma-separated list of changed files, used to filter assets")
145
168
  args = parser.parse_args()
146
169
 
147
170
  # Convert comma-separated values to lists
148
171
  input_dirs = [Path(d) for d in args.input_dirs.split(",")]
172
+ changed_files = [Path(f) for f in args.changed_files.split(",")] if args.changed_files else []
149
173
 
150
174
  # Validate against model schema
151
175
  success = validate_model_schema(input_dirs=input_dirs,
152
176
  schema_file=args.schema_file,
153
177
  asset_config_filename=args.asset_config_filename,
154
- allow_additional_properties=args.allow_additional_properties)
178
+ allow_additional_properties=args.allow_additional_properties,
179
+ changed_files=changed_files)
155
180
 
156
181
  if not success:
157
182
  sys.exit(1)
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: azureml-registry-tools
3
- Version: 0.1.0a15
3
+ Version: 0.1.0a16
4
4
  Summary: AzureML Registry tools and CLI
5
5
  Author: Microsoft Corp
6
6
  License: https://aka.ms/azureml-sdk-license
@@ -13,10 +13,10 @@ azureml/registry/data/asset.yaml.template,sha256=WTgfuvKEBp-EVFSQ0JpU0h4z_ULJdUL
13
13
  azureml/registry/data/description.md.template,sha256=wQLk54U8hoXU1y9235R4irc6FGYPXGO-x9EHUorP15Q,84
14
14
  azureml/registry/data/evaluation.md.template,sha256=JaDecIfLV9vZDUrZzVRPzVHHnKD-BQGBgQ-cw1dHavU,277
15
15
  azureml/registry/data/model-variant.schema.json,sha256=AT4Dy6cCtp_SFUfSqYIqcER8AldpYm0QIEy1abY3QWE,1699
16
- azureml/registry/data/model.schema.json,sha256=2Ew3wt9QMzIBdLeIQXph0Fj7X8OqZJbzu_7-c4SEKZY,26062
16
+ azureml/registry/data/model.schema.json,sha256=TORbhePqEYovjg2Cem-JGJL7Tm-EbA00WvYeybMuWO4,26118
17
17
  azureml/registry/data/model.yaml.template,sha256=h5uqAN22FLaWrbPxIb8yVKH9cGDBrIwooXYYfsKhxDw,245
18
18
  azureml/registry/data/notes.md.template,sha256=zSRyOR__9NGL2j0tugY7HgFkwkAdcE2pJyyyGsz1SAk,248
19
- azureml/registry/data/validate_model_schema.py,sha256=bcxeyAT0Cl-0WbpVj_AXpMPnkJbnRxAbNKODtE-kBJg,6884
19
+ azureml/registry/data/validate_model_schema.py,sha256=OQp2E01kdxSphvUQYQvelSiD24-qUG6nTFuzW60wX2c,8322
20
20
  azureml/registry/data/validate_model_variant_schema.py,sha256=JPVNtRBn6qciMu4PaRXOvS86OGGW0cocL2Rri4xYKo8,3629
21
21
  azureml/registry/mgmt/__init__.py,sha256=LMhqcEC8ItmmpKZljElGXH-6olHlT3SLl0dJU01OvuM,226
22
22
  azureml/registry/mgmt/asset_management.py,sha256=bipZR_yLMEka0PU-vaPDhBsc9D5veTacrHYwaIT5Dpw,10977
@@ -30,9 +30,9 @@ azureml/registry/tools/config.py,sha256=tjPaoBsWtPXBL8Ww1hcJtsr2SuIjPKt79dR8iovc
30
30
  azureml/registry/tools/create_or_update_assets.py,sha256=Q-_BV7KWn1huQn5JriKT_8xJNoQQ_HK5wCftrq9DepA,15988
31
31
  azureml/registry/tools/registry_utils.py,sha256=zgYlCiOONtQJ4yZ9wg8tKVoE8dh6rrjB8hYBGhpV9-0,1403
32
32
  azureml/registry/tools/repo2registry_config.py,sha256=eXp_tU8Jyi30g8xGf7wbpLgKEPpieohBANKxMSLzq7s,4873
33
- azureml_registry_tools-0.1.0a15.dist-info/licenses/LICENSE.txt,sha256=n20rxwp7_NGrrShv9Qvcs90sjI1l3Pkt3m-5OPCWzgs,845
34
- azureml_registry_tools-0.1.0a15.dist-info/METADATA,sha256=JoRnlHgWhdH6ZJss_on0g2OdFGnaMh06XnEFUSEfWzI,522
35
- azureml_registry_tools-0.1.0a15.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
36
- azureml_registry_tools-0.1.0a15.dist-info/entry_points.txt,sha256=iRUkAeQidMnO6RQzpLqMUBTcyYtNzAfSin9WnSdVGLw,147
37
- azureml_registry_tools-0.1.0a15.dist-info/top_level.txt,sha256=ZOeEa0TAXo6i5wOjwBoqfIGEuxOcKuscGgNSpizqREY,8
38
- azureml_registry_tools-0.1.0a15.dist-info/RECORD,,
33
+ azureml_registry_tools-0.1.0a16.dist-info/licenses/LICENSE.txt,sha256=n20rxwp7_NGrrShv9Qvcs90sjI1l3Pkt3m-5OPCWzgs,845
34
+ azureml_registry_tools-0.1.0a16.dist-info/METADATA,sha256=tQuJc5f47M5C2roGH_tm4D9elTB_DmW9G_1YNaLrnHw,522
35
+ azureml_registry_tools-0.1.0a16.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
36
+ azureml_registry_tools-0.1.0a16.dist-info/entry_points.txt,sha256=iRUkAeQidMnO6RQzpLqMUBTcyYtNzAfSin9WnSdVGLw,147
37
+ azureml_registry_tools-0.1.0a16.dist-info/top_level.txt,sha256=ZOeEa0TAXo6i5wOjwBoqfIGEuxOcKuscGgNSpizqREY,8
38
+ azureml_registry_tools-0.1.0a16.dist-info/RECORD,,