azureml-registry-tools 0.1.0a6__py3-none-any.whl → 0.1.0a7__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.
- azureml/registry/_cli/registry_syndication_cli.py +84 -0
- azureml/registry/data/__init__.py +4 -0
- azureml/registry/data/asset.yaml.template +4 -0
- azureml/registry/data/description.md.template +3 -0
- azureml/registry/data/evaluation.md.template +3 -0
- azureml/registry/data/model-variant.schema.json +61 -0
- azureml/registry/data/model.schema.json +597 -0
- azureml/registry/data/model.yaml.template +8 -0
- azureml/registry/data/notes.md.template +3 -0
- azureml/registry/data/validate_model_schema.py +119 -0
- azureml/registry/data/validate_model_variant_schema.py +85 -0
- azureml/registry/mgmt/asset_management.py +260 -0
- azureml/registry/mgmt/create_asset_template.py +87 -0
- azureml/registry/mgmt/create_model_spec.py +239 -0
- azureml/registry/mgmt/registry_config.py +147 -0
- {azureml_registry_tools-0.1.0a6.dist-info → azureml_registry_tools-0.1.0a7.dist-info}/METADATA +1 -1
- azureml_registry_tools-0.1.0a7.dist-info/RECORD +37 -0
- azureml_registry_tools-0.1.0a6.dist-info/RECORD +0 -23
- {azureml_registry_tools-0.1.0a6.dist-info → azureml_registry_tools-0.1.0a7.dist-info}/WHEEL +0 -0
- {azureml_registry_tools-0.1.0a6.dist-info → azureml_registry_tools-0.1.0a7.dist-info}/entry_points.txt +0 -0
- {azureml_registry_tools-0.1.0a6.dist-info → azureml_registry_tools-0.1.0a7.dist-info}/licenses/LICENSE.txt +0 -0
- {azureml_registry_tools-0.1.0a6.dist-info → azureml_registry_tools-0.1.0a7.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,239 @@
|
|
1
|
+
# ---------------------------------------------------------
|
2
|
+
# Copyright (c) Microsoft Corporation. All rights reserved.
|
3
|
+
# ---------------------------------------------------------
|
4
|
+
"""Generate model template spec.yaml file from model.schema.json."""
|
5
|
+
|
6
|
+
import json
|
7
|
+
import re
|
8
|
+
from pathlib import Path
|
9
|
+
from typing import Dict, Any, List, Tuple
|
10
|
+
|
11
|
+
|
12
|
+
class ModelTemplateGenerator:
|
13
|
+
"""ModelTemplateGenerator class."""
|
14
|
+
|
15
|
+
def __init__(self, schema_path: Path, output_path: Path):
|
16
|
+
"""Init for ModelTemplateGenerator."""
|
17
|
+
self.schema_path = schema_path
|
18
|
+
self.output_path = output_path
|
19
|
+
self.schema = self._load_schema()
|
20
|
+
|
21
|
+
def _load_schema(self) -> Dict[str, Any]:
|
22
|
+
"""Load and parse the JSON schema file."""
|
23
|
+
with open(self.schema_path, "r", encoding="utf-8") as f:
|
24
|
+
return json.load(f)
|
25
|
+
|
26
|
+
def _get_enum_values(self, prop_def: Dict[str, Any]) -> List[str]:
|
27
|
+
"""Extract enum values from property definition."""
|
28
|
+
if "enum" in prop_def:
|
29
|
+
return prop_def["enum"]
|
30
|
+
return []
|
31
|
+
|
32
|
+
def _get_pattern_examples(self, pattern: str, prop_name: str) -> List[str]:
|
33
|
+
"""Generate examples from regex patterns by extracting options."""
|
34
|
+
# Special handling for trainingDataDate pattern
|
35
|
+
if prop_name == "trainingDataDate":
|
36
|
+
return ["January 2024"]
|
37
|
+
|
38
|
+
# Extract options from regex patterns
|
39
|
+
if "(" in pattern and "|" in pattern:
|
40
|
+
# Look for the main pattern group - typically the first group that has multiple options
|
41
|
+
# Handle patterns like ^(option1|option2|option3)(?:...)
|
42
|
+
main_match = re.search(r"\^?\(([^)]+\|[^)]*)\)", pattern)
|
43
|
+
if main_match:
|
44
|
+
options_str = main_match.group(1)
|
45
|
+
options = []
|
46
|
+
|
47
|
+
# Split by | and clean up each option
|
48
|
+
for opt in options_str.split("|"):
|
49
|
+
# Clean up the option - remove anchors, whitespace, escape chars
|
50
|
+
cleaned = opt.strip().replace("\\", "")
|
51
|
+
|
52
|
+
# Skip empty options and regex artifacts
|
53
|
+
if (cleaned and
|
54
|
+
len(cleaned) > 1 and
|
55
|
+
not cleaned.startswith("?") and
|
56
|
+
not cleaned.startswith("*") and
|
57
|
+
not cleaned.startswith("+") and
|
58
|
+
not re.match(r"^[^a-zA-Z0-9-]+$", cleaned)): # Skip pure symbol patterns
|
59
|
+
options.append(cleaned)
|
60
|
+
|
61
|
+
if options:
|
62
|
+
# Return up to 6 unique options
|
63
|
+
unique_options = list(dict.fromkeys(options)) # Remove duplicates while preserving order
|
64
|
+
if len(unique_options) > 6:
|
65
|
+
return unique_options[:6] + ["etc."]
|
66
|
+
return unique_options[:6]
|
67
|
+
|
68
|
+
return []
|
69
|
+
|
70
|
+
def _get_example_value(self, prop_def: Dict[str, Any], prop_name: str) -> Tuple[str, str]:
|
71
|
+
"""Generate a generic example value based on property type and schema constraints."""
|
72
|
+
prop_type = prop_def.get("type", "string")
|
73
|
+
|
74
|
+
# Handle special cases first
|
75
|
+
if prop_name == "notes":
|
76
|
+
description = prop_def.get("description", "Reference to notes documentation")
|
77
|
+
return '"notes.md"', description
|
78
|
+
elif prop_name == "evaluation":
|
79
|
+
description = prop_def.get("description", "Reference to evaluation documentation")
|
80
|
+
return '"evaluation.md"', description
|
81
|
+
|
82
|
+
# Handle enum values
|
83
|
+
enum_values = self._get_enum_values(prop_def)
|
84
|
+
if enum_values:
|
85
|
+
if enum_values == [""]:
|
86
|
+
return '""', "Empty string means enabled. Remove if disabled."
|
87
|
+
return f'"{enum_values[0]}"', f"options: {', '.join(enum_values)}"
|
88
|
+
|
89
|
+
# Handle patterns - extract options if available
|
90
|
+
if "pattern" in prop_def:
|
91
|
+
pattern = prop_def["pattern"]
|
92
|
+
examples = self._get_pattern_examples(pattern, prop_name)
|
93
|
+
if examples:
|
94
|
+
if len(examples) > 1:
|
95
|
+
value = ",".join(examples[:3])
|
96
|
+
return f'"{value}"', f"options: {', '.join(examples)} (comma-separated)"
|
97
|
+
else:
|
98
|
+
return f'"{examples[0]}"', f"pattern: {pattern[:50]}..." if len(pattern) > 50 else f"pattern: {pattern}"
|
99
|
+
else:
|
100
|
+
return '"example-value"', f"pattern: {pattern[:50]}..." if len(pattern) > 50 else f"pattern: {pattern}"
|
101
|
+
|
102
|
+
# Handle oneOf types
|
103
|
+
if "oneOf" in prop_def:
|
104
|
+
type_info = []
|
105
|
+
minimum = None
|
106
|
+
for oneof in prop_def["oneOf"]:
|
107
|
+
if oneof.get("type"):
|
108
|
+
type_info.append(oneof["type"])
|
109
|
+
if oneof.get("type") == "integer" and "minimum" in oneof:
|
110
|
+
minimum = oneof["minimum"]
|
111
|
+
types_str = " or ".join(set(type_info))
|
112
|
+
min_info = f" (minimum: {minimum})" if minimum else ""
|
113
|
+
return "1", f"can be {types_str}{min_info}"
|
114
|
+
|
115
|
+
# Handle arrays
|
116
|
+
if prop_type == "array":
|
117
|
+
items_def = prop_def.get("items", {})
|
118
|
+
if "enum" in items_def:
|
119
|
+
return f'["{items_def["enum"][0]}"]', f"options: {', '.join(items_def['enum'])}"
|
120
|
+
else:
|
121
|
+
return '["example-value"]', "Array of values"
|
122
|
+
|
123
|
+
# Handle objects
|
124
|
+
if prop_type == "object":
|
125
|
+
return None, "Object type"
|
126
|
+
|
127
|
+
# Handle basic types with constraints
|
128
|
+
if prop_type == "integer":
|
129
|
+
minimum = prop_def.get("minimum", 1)
|
130
|
+
return str(minimum), f"minimum: {minimum}"
|
131
|
+
elif prop_type == "number":
|
132
|
+
return "1.0", "Number type"
|
133
|
+
elif prop_type == "boolean":
|
134
|
+
return "true", "Boolean type"
|
135
|
+
else:
|
136
|
+
# String type
|
137
|
+
return '"example-value"', "String type"
|
138
|
+
|
139
|
+
def _format_comment(self, comment: str, is_required: bool, additional_info: str = "") -> str:
|
140
|
+
"""Format the inline comment for a property."""
|
141
|
+
if additional_info and additional_info != comment:
|
142
|
+
comment += f" ({additional_info})"
|
143
|
+
|
144
|
+
required_text = "required" if is_required else "optional"
|
145
|
+
return f"# {comment} ({required_text})"
|
146
|
+
|
147
|
+
def _generate_property_line(self, prop_name: str, prop_def: Dict[str, Any],
|
148
|
+
indent: int = 0, is_required: bool = False) -> List[str]:
|
149
|
+
"""Generate YAML lines for a single property."""
|
150
|
+
description = prop_def.get("description", prop_name.replace("_", " ").replace("-", " ").title())
|
151
|
+
example_value, additional_info = self._get_example_value(prop_def, prop_name)
|
152
|
+
|
153
|
+
indent_str = " " * indent
|
154
|
+
|
155
|
+
# Handle object types that need special formatting
|
156
|
+
if example_value is None and prop_def.get("type") == "object":
|
157
|
+
comment = self._format_comment(description, is_required, additional_info)
|
158
|
+
# For generic objects, just show the key with comment
|
159
|
+
return [f"{indent_str}{prop_name}: {comment}"]
|
160
|
+
|
161
|
+
comment = self._format_comment(description, is_required, additional_info)
|
162
|
+
return [f"{indent_str}{prop_name}: {example_value} {comment}"]
|
163
|
+
|
164
|
+
def generate_template(self) -> str:
|
165
|
+
"""Generate the complete template file content."""
|
166
|
+
lines = [
|
167
|
+
"# AzureML Model Specification Template",
|
168
|
+
"# Generated from schema - Fill in the values below to create your model specification",
|
169
|
+
"",
|
170
|
+
]
|
171
|
+
|
172
|
+
# Get required fields
|
173
|
+
required_fields = set(self.schema.get("required", []))
|
174
|
+
|
175
|
+
# Add top-level required fields first
|
176
|
+
for field in ["$schema", "name", "path"]:
|
177
|
+
if field in self.schema["properties"]:
|
178
|
+
prop_def = self.schema["properties"][field]
|
179
|
+
is_required = field in required_fields
|
180
|
+
if field == "$schema":
|
181
|
+
lines.append('$schema: "https://azuremlschemas.azureedge.net/latest/model.schema.json" # JSON schema reference (required)')
|
182
|
+
elif field == "name":
|
183
|
+
lines.append('name: "example-model-name" # Model name (required)')
|
184
|
+
elif field == "path":
|
185
|
+
lines.append('path: "./" # Path to model files (required)')
|
186
|
+
|
187
|
+
lines.append("")
|
188
|
+
|
189
|
+
# Add all other sections dynamically (excluding the ones we already handled)
|
190
|
+
handled_fields = {"$schema", "name", "path", "version"}
|
191
|
+
required_fields = set(self.schema.get("required", []))
|
192
|
+
|
193
|
+
for section_name, section_def in self.schema["properties"].items():
|
194
|
+
if section_name in handled_fields:
|
195
|
+
continue
|
196
|
+
# Check if this section has properties (indicating it's a structured section)
|
197
|
+
if isinstance(section_def, dict) and "properties" in section_def:
|
198
|
+
is_required = section_name in required_fields
|
199
|
+
required_text = "required" if is_required else "optional"
|
200
|
+
lines.append(f"{section_name}: # {section_name.title()} ({required_text})")
|
201
|
+
|
202
|
+
# Add all properties within this section
|
203
|
+
for prop_name, prop_def in section_def["properties"].items():
|
204
|
+
lines.extend(self._generate_property_line(prop_name, prop_def, indent=1))
|
205
|
+
|
206
|
+
lines.append("")
|
207
|
+
|
208
|
+
# Add version at the end
|
209
|
+
if "version" in self.schema["properties"]:
|
210
|
+
version_def = self.schema["properties"]["version"]
|
211
|
+
is_required = "version" in required_fields
|
212
|
+
lines.extend(self._generate_property_line("version", version_def, is_required=is_required))
|
213
|
+
|
214
|
+
return "\n".join(lines)
|
215
|
+
|
216
|
+
def write_template(self):
|
217
|
+
"""Generate and write the template file."""
|
218
|
+
template_content = self.generate_template()
|
219
|
+
|
220
|
+
with open(self.output_path, "w", encoding="utf-8") as f:
|
221
|
+
f.write(template_content)
|
222
|
+
|
223
|
+
print(f"Template generated successfully: {self.output_path}")
|
224
|
+
|
225
|
+
|
226
|
+
def generate_model_spec_content(schema_path: Path) -> str:
|
227
|
+
"""Generate model spec content from schema file.
|
228
|
+
|
229
|
+
Args:
|
230
|
+
schema_path (Path): Path to the model.schema.json file
|
231
|
+
|
232
|
+
Returns:
|
233
|
+
str: Generated model spec YAML content
|
234
|
+
"""
|
235
|
+
if not schema_path.exists():
|
236
|
+
raise FileNotFoundError(f"Schema file not found: {schema_path}")
|
237
|
+
|
238
|
+
generator = ModelTemplateGenerator(schema_path, "")
|
239
|
+
return generator.generate_template()
|
@@ -0,0 +1,147 @@
|
|
1
|
+
# ---------------------------------------------------------
|
2
|
+
# Copyright (c) Microsoft Corporation. All rights reserved.
|
3
|
+
# ---------------------------------------------------------
|
4
|
+
|
5
|
+
"""RegistryConfig class."""
|
6
|
+
|
7
|
+
import configparser
|
8
|
+
from pathlib import Path
|
9
|
+
from typing import Dict
|
10
|
+
|
11
|
+
|
12
|
+
class RegistryConfig:
|
13
|
+
"""RegistryConfig class."""
|
14
|
+
|
15
|
+
def __init__(self, config_path: Path = None):
|
16
|
+
"""Registry config init.
|
17
|
+
|
18
|
+
Args:
|
19
|
+
config_path (Path, optional): Path to configuration file. Defaults to "registry-mgmt.cfg".
|
20
|
+
"""
|
21
|
+
if config_path is None:
|
22
|
+
print("No config path provided, using default 'registry-mgmt.cfg'.")
|
23
|
+
config_path = Path("registry-mgmt.cfg")
|
24
|
+
self.config_path = config_path
|
25
|
+
if not self.config_path.is_file():
|
26
|
+
raise FileNotFoundError(f"File '{self.config_path.resolve().as_posix()}' does not exist.")
|
27
|
+
|
28
|
+
self.config = configparser.ConfigParser()
|
29
|
+
self.config.read(self.config_path)
|
30
|
+
self._validate_schema()
|
31
|
+
|
32
|
+
def _validate_schema(self) -> None:
|
33
|
+
"""Validate registry config schema."""
|
34
|
+
config_file_name = str(self.config_path)
|
35
|
+
|
36
|
+
if not self.config.has_section("registry"):
|
37
|
+
raise Exception(f'"registry" section not found in config file {config_file_name}')
|
38
|
+
|
39
|
+
# Validate registry section
|
40
|
+
if not self.config.has_option("registry", "registry_name"):
|
41
|
+
raise Exception(f'Key "registry_name" not found under "registry" section in config file {config_file_name}')
|
42
|
+
if not self.config.has_option("registry", "tenant_id"):
|
43
|
+
raise Exception(f'Key "tenant_id" not found under "registry" section in config file {config_file_name}')
|
44
|
+
if not self.config.has_option("registry", "subscription_id"):
|
45
|
+
raise Exception(f'Key "subscription_id" not found under "registry" section in config file {config_file_name}')
|
46
|
+
if not self.config.has_option("registry", "resource_group"):
|
47
|
+
raise Exception(f'Key "resource_group" not found under "registry" section in config file {config_file_name}')
|
48
|
+
|
49
|
+
# Validate that values are not empty
|
50
|
+
required_settings = ["registry_name", "tenant_id", "subscription_id", "resource_group"]
|
51
|
+
for setting in required_settings:
|
52
|
+
if not self.config.get("registry", setting).strip():
|
53
|
+
raise Exception(f'Value for "{setting}" is empty in "registry" section in config file {config_file_name}')
|
54
|
+
|
55
|
+
# Validate storage_overrides section (optional, but if present, validate its contents)
|
56
|
+
if self.config.has_section("storage_overrides"):
|
57
|
+
allowed_storage_keys = {"storage_name", "container_name", "container_path"}
|
58
|
+
actual_storage_keys = set(self.config.options("storage_overrides"))
|
59
|
+
|
60
|
+
# Check for unexpected keys
|
61
|
+
unexpected_keys = actual_storage_keys - allowed_storage_keys
|
62
|
+
if unexpected_keys:
|
63
|
+
raise Exception(f'Unexpected keys {sorted(unexpected_keys)} found in "storage_overrides" section in config file {config_file_name}. Only {sorted(allowed_storage_keys)} are allowed.')
|
64
|
+
|
65
|
+
# Check for required keys
|
66
|
+
if not self.config.has_option("storage_overrides", "storage_name"):
|
67
|
+
raise Exception(f'Key "storage_name" not found under "storage_overrides" section in config file {config_file_name}')
|
68
|
+
if not self.config.has_option("storage_overrides", "container_name"):
|
69
|
+
raise Exception(f'Key "container_name" not found under "storage_overrides" section in config file {config_file_name}')
|
70
|
+
if not self.config.has_option("storage_overrides", "container_path"):
|
71
|
+
raise Exception(f'Key "container_path" not found under "storage_overrides" section in config file {config_file_name}')
|
72
|
+
|
73
|
+
# Validate that storage values are not empty
|
74
|
+
required_storage_settings = ["storage_name", "container_name", "container_path"]
|
75
|
+
for setting in required_storage_settings:
|
76
|
+
if not self.config.get("storage_overrides", setting).strip():
|
77
|
+
raise Exception(f'Value for "{setting}" is empty in "storage_overrides" section in config file {config_file_name}')
|
78
|
+
|
79
|
+
@property
|
80
|
+
def registry_name(self) -> str:
|
81
|
+
"""Get registry name from config."""
|
82
|
+
return self.config.get("registry", "registry_name")
|
83
|
+
|
84
|
+
@property
|
85
|
+
def tenant_id(self) -> str:
|
86
|
+
"""Get tenant ID from config."""
|
87
|
+
return self.config.get("registry", "tenant_id")
|
88
|
+
|
89
|
+
@property
|
90
|
+
def subscription_id(self) -> str:
|
91
|
+
"""Get subscription ID from config."""
|
92
|
+
return self.config.get("registry", "subscription_id")
|
93
|
+
|
94
|
+
@property
|
95
|
+
def resource_group(self) -> str:
|
96
|
+
"""Get resource group from config."""
|
97
|
+
return self.config.get("registry", "resource_group")
|
98
|
+
|
99
|
+
@property
|
100
|
+
def storage_config(self) -> Dict[str, str]:
|
101
|
+
"""Get storage configuration."""
|
102
|
+
if self.config.has_section("storage_overrides"):
|
103
|
+
return dict(self.config["storage_overrides"])
|
104
|
+
return {}
|
105
|
+
|
106
|
+
|
107
|
+
def create_registry_config(registry_name: str, subscription_id: str, resource_group: str, tenant_id: str,
|
108
|
+
config_file_path: Path, storage_name: str = None, container_name: str = None,
|
109
|
+
container_path: str = None):
|
110
|
+
"""Create registry config.
|
111
|
+
|
112
|
+
Args:
|
113
|
+
registry_name (str): Registry name.
|
114
|
+
subscription_id (str): Registry subscription id.
|
115
|
+
resource_group (str): Registry resource group.
|
116
|
+
tenant_id (str): Tenant ID.
|
117
|
+
config_file_path (Path): Path to config file.
|
118
|
+
storage_name (str, optional): Storage account name for storage overrides. Defaults to None.
|
119
|
+
container_name (str, optional): Container name for storage overrides. Defaults to None.
|
120
|
+
container_path (str, optional): Container path for storage overrides. Defaults to None.
|
121
|
+
"""
|
122
|
+
print("Creating registry config...")
|
123
|
+
|
124
|
+
registry_config = configparser.ConfigParser()
|
125
|
+
registry_config.add_section("registry")
|
126
|
+
registry_config.set("registry", "registry_name", registry_name)
|
127
|
+
registry_config.set("registry", "subscription_id", subscription_id)
|
128
|
+
registry_config.set("registry", "resource_group", resource_group)
|
129
|
+
registry_config.set("registry", "tenant_id", tenant_id)
|
130
|
+
|
131
|
+
# Add storage overrides if provided
|
132
|
+
if storage_name and container_name and container_path:
|
133
|
+
registry_config.add_section("storage_overrides")
|
134
|
+
registry_config.set("storage_overrides", "storage_name", storage_name)
|
135
|
+
registry_config.set("storage_overrides", "container_name", container_name)
|
136
|
+
registry_config.set("storage_overrides", "container_path", container_path)
|
137
|
+
|
138
|
+
# Write to path
|
139
|
+
if config_file_path is None:
|
140
|
+
print('No config file path provided, using default "registry-mgmt.cfg"')
|
141
|
+
config_file_path = Path("registry-mgmt.cfg")
|
142
|
+
with open(config_file_path, "w") as config_file:
|
143
|
+
registry_config.write(config_file)
|
144
|
+
|
145
|
+
config_abs_path = Path(config_file_path).resolve().as_posix()
|
146
|
+
|
147
|
+
print(f"Wrote registry config file to {config_abs_path}")
|
@@ -0,0 +1,37 @@
|
|
1
|
+
azureml/__init__.py,sha256=_gYz_vABVrp9EyOZEYn4Ya8XotJC2rZn-b9kFTEj1Dk,266
|
2
|
+
azureml/registry/__init__.py,sha256=qjP86n1Yz6hdZb3az-wjfi7LNndsFjMQI6lXmKfXapM,266
|
3
|
+
azureml/registry/_cli/__init__.py,sha256=dJ020ynrregpUaNGu8xVLLmX3cC9DAjaBMP1qnljLEE,208
|
4
|
+
azureml/registry/_cli/registry_syndication_cli.py,sha256=6Lf2ydgSBKZ3S9AAsY7zLfr0RBX_TcRmKTUaZ9gX3fI,18031
|
5
|
+
azureml/registry/_cli/repo2registry_cli.py,sha256=4CDv4tYWLTjVgdXIcoKA9iu_gOv_Z_xn05wSANkdmdg,5378
|
6
|
+
azureml/registry/_rest_client/__init__.py,sha256=Eh0vB8AVlwkZlHLO4DCGHyyfRYYgeTeVjiUAX_WujG0,219
|
7
|
+
azureml/registry/_rest_client/arm_client.py,sha256=KVSj0V1bN-vCUV3fBbIdZDpWTLKYT6qdWIZtDjx2la4,4516
|
8
|
+
azureml/registry/_rest_client/base_rest_client.py,sha256=JcmhckfR-ZdUtEh0EeQIKfe63Zjowa1fLzmVeWpeLno,8173
|
9
|
+
azureml/registry/_rest_client/registry_management_client.py,sha256=3-PBwj91lkG1yrlB-s7jaYj0w5j177oSHZHvcoO8icQ,4984
|
10
|
+
azureml/registry/data/__init__.py,sha256=cW3X6HATz6XF-K_7uKdybTbJb9EZSecBN4J27NGdZmU,231
|
11
|
+
azureml/registry/data/asset.yaml.template,sha256=WTgfuvKEBp-EVFSQ0JpU0h4z_ULJdULO9kHmB_9Fr1o,96
|
12
|
+
azureml/registry/data/description.md.template,sha256=tIcjydGGScMP0PhJMrYjzdWMjd-8z5winufNjH2A3OE,135
|
13
|
+
azureml/registry/data/evaluation.md.template,sha256=UZJti1kFu-VsRGVl_QA_GhUS8hU63Yo3Flih3_RMD14,328
|
14
|
+
azureml/registry/data/model-variant.schema.json,sha256=AT4Dy6cCtp_SFUfSqYIqcER8AldpYm0QIEy1abY3QWE,1699
|
15
|
+
azureml/registry/data/model.schema.json,sha256=sNzo7agu_49GdfSa08T61Hy87j-XY5IwLh6XU39QTAY,25814
|
16
|
+
azureml/registry/data/model.yaml.template,sha256=h5uqAN22FLaWrbPxIb8yVKH9cGDBrIwooXYYfsKhxDw,245
|
17
|
+
azureml/registry/data/notes.md.template,sha256=yFQ7qbrjlGDLZGuSoJUvQjctXsnCdoUd6txJuT-duCY,300
|
18
|
+
azureml/registry/data/validate_model_schema.py,sha256=VLgQQhgS-lWuYC9bCBop_Yp1k70SzaM_8JU4Sc7aE14,5198
|
19
|
+
azureml/registry/data/validate_model_variant_schema.py,sha256=4gpL9fTN4APu3TdrAUTzd3oavByBv19afjHbK__BEno,3583
|
20
|
+
azureml/registry/mgmt/__init__.py,sha256=LMhqcEC8ItmmpKZljElGXH-6olHlT3SLl0dJU01OvuM,226
|
21
|
+
azureml/registry/mgmt/asset_management.py,sha256=7dUp8Dg-YffAWBtqLK6l2to8lafcPfh5GB0aH7ujVsc,9911
|
22
|
+
azureml/registry/mgmt/create_asset_template.py,sha256=ejwLuIsmzJOoUePoxbM-eGMg2E3QHfdX-nPMBzYUVMQ,3525
|
23
|
+
azureml/registry/mgmt/create_manifest.py,sha256=N9wRmjAKO09A3utN_lCUsM_Ufpj7PL0SJz-XHPHWuyM,9528
|
24
|
+
azureml/registry/mgmt/create_model_spec.py,sha256=1PdAcUf-LomvljoT8wKQihXMTLd7DoTgN0qDX4Lol1A,10473
|
25
|
+
azureml/registry/mgmt/registry_config.py,sha256=NhIkTCNlfbfJrVGw61AmBAIZQ5HU2cb4kXAI9j3Wwy4,7181
|
26
|
+
azureml/registry/mgmt/syndication_manifest.py,sha256=8Sfd49QuCA5en5_mIOLE21kZVpnReUXowx_g0TVRgWg,9025
|
27
|
+
azureml/registry/tools/__init__.py,sha256=IAuWWpGfZm__pAkBIxmpJz84QskpkxBr0yDk1TUSnkE,223
|
28
|
+
azureml/registry/tools/config.py,sha256=tjPaoBsWtPXBL8Ww1hcJtsr2SuIjPKt79dR8iovcebg,3639
|
29
|
+
azureml/registry/tools/create_or_update_assets.py,sha256=Q-_BV7KWn1huQn5JriKT_8xJNoQQ_HK5wCftrq9DepA,15988
|
30
|
+
azureml/registry/tools/registry_utils.py,sha256=zgYlCiOONtQJ4yZ9wg8tKVoE8dh6rrjB8hYBGhpV9-0,1403
|
31
|
+
azureml/registry/tools/repo2registry_config.py,sha256=eXp_tU8Jyi30g8xGf7wbpLgKEPpieohBANKxMSLzq7s,4873
|
32
|
+
azureml_registry_tools-0.1.0a7.dist-info/licenses/LICENSE.txt,sha256=n20rxwp7_NGrrShv9Qvcs90sjI1l3Pkt3m-5OPCWzgs,845
|
33
|
+
azureml_registry_tools-0.1.0a7.dist-info/METADATA,sha256=R1Pk35pE-6ocXl6mlW3DBOKa-6SJ2XMM27bOlJLpjhI,521
|
34
|
+
azureml_registry_tools-0.1.0a7.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
35
|
+
azureml_registry_tools-0.1.0a7.dist-info/entry_points.txt,sha256=iRUkAeQidMnO6RQzpLqMUBTcyYtNzAfSin9WnSdVGLw,147
|
36
|
+
azureml_registry_tools-0.1.0a7.dist-info/top_level.txt,sha256=ZOeEa0TAXo6i5wOjwBoqfIGEuxOcKuscGgNSpizqREY,8
|
37
|
+
azureml_registry_tools-0.1.0a7.dist-info/RECORD,,
|
@@ -1,23 +0,0 @@
|
|
1
|
-
azureml/__init__.py,sha256=_gYz_vABVrp9EyOZEYn4Ya8XotJC2rZn-b9kFTEj1Dk,266
|
2
|
-
azureml/registry/__init__.py,sha256=qjP86n1Yz6hdZb3az-wjfi7LNndsFjMQI6lXmKfXapM,266
|
3
|
-
azureml/registry/_cli/__init__.py,sha256=dJ020ynrregpUaNGu8xVLLmX3cC9DAjaBMP1qnljLEE,208
|
4
|
-
azureml/registry/_cli/registry_syndication_cli.py,sha256=3PpXkq0EF6-adCMnz6HDALeugqfS9l86oIvh4isZyvw,12962
|
5
|
-
azureml/registry/_cli/repo2registry_cli.py,sha256=4CDv4tYWLTjVgdXIcoKA9iu_gOv_Z_xn05wSANkdmdg,5378
|
6
|
-
azureml/registry/_rest_client/__init__.py,sha256=Eh0vB8AVlwkZlHLO4DCGHyyfRYYgeTeVjiUAX_WujG0,219
|
7
|
-
azureml/registry/_rest_client/arm_client.py,sha256=KVSj0V1bN-vCUV3fBbIdZDpWTLKYT6qdWIZtDjx2la4,4516
|
8
|
-
azureml/registry/_rest_client/base_rest_client.py,sha256=JcmhckfR-ZdUtEh0EeQIKfe63Zjowa1fLzmVeWpeLno,8173
|
9
|
-
azureml/registry/_rest_client/registry_management_client.py,sha256=3-PBwj91lkG1yrlB-s7jaYj0w5j177oSHZHvcoO8icQ,4984
|
10
|
-
azureml/registry/mgmt/__init__.py,sha256=LMhqcEC8ItmmpKZljElGXH-6olHlT3SLl0dJU01OvuM,226
|
11
|
-
azureml/registry/mgmt/create_manifest.py,sha256=N9wRmjAKO09A3utN_lCUsM_Ufpj7PL0SJz-XHPHWuyM,9528
|
12
|
-
azureml/registry/mgmt/syndication_manifest.py,sha256=8Sfd49QuCA5en5_mIOLE21kZVpnReUXowx_g0TVRgWg,9025
|
13
|
-
azureml/registry/tools/__init__.py,sha256=IAuWWpGfZm__pAkBIxmpJz84QskpkxBr0yDk1TUSnkE,223
|
14
|
-
azureml/registry/tools/config.py,sha256=tjPaoBsWtPXBL8Ww1hcJtsr2SuIjPKt79dR8iovcebg,3639
|
15
|
-
azureml/registry/tools/create_or_update_assets.py,sha256=Q-_BV7KWn1huQn5JriKT_8xJNoQQ_HK5wCftrq9DepA,15988
|
16
|
-
azureml/registry/tools/registry_utils.py,sha256=zgYlCiOONtQJ4yZ9wg8tKVoE8dh6rrjB8hYBGhpV9-0,1403
|
17
|
-
azureml/registry/tools/repo2registry_config.py,sha256=eXp_tU8Jyi30g8xGf7wbpLgKEPpieohBANKxMSLzq7s,4873
|
18
|
-
azureml_registry_tools-0.1.0a6.dist-info/licenses/LICENSE.txt,sha256=n20rxwp7_NGrrShv9Qvcs90sjI1l3Pkt3m-5OPCWzgs,845
|
19
|
-
azureml_registry_tools-0.1.0a6.dist-info/METADATA,sha256=cHaW5YddH_-oZuk3WdrCjAH5xTaFKcKZZDWuBpj-B0A,521
|
20
|
-
azureml_registry_tools-0.1.0a6.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
21
|
-
azureml_registry_tools-0.1.0a6.dist-info/entry_points.txt,sha256=iRUkAeQidMnO6RQzpLqMUBTcyYtNzAfSin9WnSdVGLw,147
|
22
|
-
azureml_registry_tools-0.1.0a6.dist-info/top_level.txt,sha256=ZOeEa0TAXo6i5wOjwBoqfIGEuxOcKuscGgNSpizqREY,8
|
23
|
-
azureml_registry_tools-0.1.0a6.dist-info/RECORD,,
|
File without changes
|
File without changes
|
File without changes
|
{azureml_registry_tools-0.1.0a6.dist-info → azureml_registry_tools-0.1.0a7.dist-info}/top_level.txt
RENAMED
File without changes
|