Spaces:
Running
Running
Update src/aibom_generator/generator.py
Browse files- src/aibom_generator/generator.py +16 -17
src/aibom_generator/generator.py
CHANGED
@@ -1,7 +1,7 @@
|
|
1 |
import json
|
2 |
import uuid
|
3 |
import datetime
|
4 |
-
from typing import Dict, Optional, Any
|
5 |
|
6 |
from huggingface_hub import HfApi, ModelCard
|
7 |
from .utils import calculate_completeness_score
|
@@ -25,17 +25,29 @@ class AIBOMGenerator:
|
|
25 |
model_id: str,
|
26 |
output_file: Optional[str] = None,
|
27 |
include_inference: Optional[bool] = None,
|
28 |
-
) -> Dict[str, Any]:
|
29 |
use_inference = include_inference if include_inference is not None else self.use_inference
|
30 |
model_info = self._fetch_model_info(model_id)
|
31 |
model_card = self._fetch_model_card(model_id)
|
32 |
aibom = self._create_aibom_structure(model_id, model_info, model_card, use_inference)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
33 |
|
34 |
if output_file:
|
35 |
with open(output_file, 'w') as f:
|
36 |
json.dump(aibom, f, indent=2)
|
37 |
|
38 |
-
return aibom
|
39 |
|
40 |
def _fetch_model_info(self, model_id: str) -> Dict[str, Any]:
|
41 |
try:
|
@@ -125,16 +137,6 @@ class AIBOMGenerator:
|
|
125 |
return {}
|
126 |
|
127 |
def _create_metadata_section(self, model_id: str, metadata: Dict[str, Any]) -> Dict[str, Any]:
|
128 |
-
aibom_stub = {
|
129 |
-
"bomFormat": "CycloneDX",
|
130 |
-
"specVersion": "1.6",
|
131 |
-
"serialNumber": f"urn:uuid:{str(uuid.uuid4())}",
|
132 |
-
"version": 1,
|
133 |
-
"metadata": {},
|
134 |
-
"components": [self._create_component_section(model_id, metadata)]
|
135 |
-
}
|
136 |
-
score_report = calculate_completeness_score(aibom_stub)
|
137 |
-
|
138 |
timestamp = datetime.datetime.utcnow().isoformat() + "Z"
|
139 |
tools = [{
|
140 |
"vendor": "Aetheris AI",
|
@@ -162,9 +164,6 @@ class AIBOMGenerator:
|
|
162 |
value = json.dumps(value)
|
163 |
properties.append({"name": key, "value": str(value)})
|
164 |
|
165 |
-
properties.append({"name": "aibom:quality-score", "value": str(score_report["total_score"])})
|
166 |
-
properties.append({"name": "aibom:quality-breakdown", "value": json.dumps(score_report["section_scores"])})
|
167 |
-
|
168 |
metadata_section = {
|
169 |
"timestamp": timestamp,
|
170 |
"tools": tools,
|
@@ -183,7 +182,7 @@ class AIBOMGenerator:
|
|
183 |
"type": "machine-learning-model",
|
184 |
"bom-ref": f"pkg:generic/{model_id.replace('/', '%2F')}",
|
185 |
"name": metadata.get("name", model_id.split("/")[-1]),
|
186 |
-
"purl": f"pkg:
|
187 |
}
|
188 |
|
189 |
if "description" in metadata:
|
|
|
1 |
import json
|
2 |
import uuid
|
3 |
import datetime
|
4 |
+
from typing import Dict, Optional, Any, Tuple
|
5 |
|
6 |
from huggingface_hub import HfApi, ModelCard
|
7 |
from .utils import calculate_completeness_score
|
|
|
25 |
model_id: str,
|
26 |
output_file: Optional[str] = None,
|
27 |
include_inference: Optional[bool] = None,
|
28 |
+
) -> Tuple[Dict[str, Any], Dict[str, Any]]:
|
29 |
use_inference = include_inference if include_inference is not None else self.use_inference
|
30 |
model_info = self._fetch_model_info(model_id)
|
31 |
model_card = self._fetch_model_card(model_id)
|
32 |
aibom = self._create_aibom_structure(model_id, model_info, model_card, use_inference)
|
33 |
+
|
34 |
+
# Calculate score after AIBOM is complete
|
35 |
+
score_report = calculate_completeness_score(aibom)
|
36 |
+
|
37 |
+
# Add score to metadata properties
|
38 |
+
if "metadata" in aibom and not "properties" in aibom["metadata"]:
|
39 |
+
aibom["metadata"]["properties"] = []
|
40 |
+
|
41 |
+
if "metadata" in aibom and "properties" in aibom["metadata"]:
|
42 |
+
aibom["metadata"]["properties"].append({"name": "aibom:quality-score", "value": str(score_report["total_score"])})
|
43 |
+
aibom["metadata"]["properties"].append({"name": "aibom:quality-breakdown", "value": json.dumps(score_report["section_scores"])})
|
44 |
+
aibom["metadata"]["properties"].append({"name": "aibom:max-scores", "value": json.dumps(score_report["max_scores"])})
|
45 |
|
46 |
if output_file:
|
47 |
with open(output_file, 'w') as f:
|
48 |
json.dump(aibom, f, indent=2)
|
49 |
|
50 |
+
return aibom, score_report
|
51 |
|
52 |
def _fetch_model_info(self, model_id: str) -> Dict[str, Any]:
|
53 |
try:
|
|
|
137 |
return {}
|
138 |
|
139 |
def _create_metadata_section(self, model_id: str, metadata: Dict[str, Any]) -> Dict[str, Any]:
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
140 |
timestamp = datetime.datetime.utcnow().isoformat() + "Z"
|
141 |
tools = [{
|
142 |
"vendor": "Aetheris AI",
|
|
|
164 |
value = json.dumps(value)
|
165 |
properties.append({"name": key, "value": str(value)})
|
166 |
|
|
|
|
|
|
|
167 |
metadata_section = {
|
168 |
"timestamp": timestamp,
|
169 |
"tools": tools,
|
|
|
182 |
"type": "machine-learning-model",
|
183 |
"bom-ref": f"pkg:generic/{model_id.replace('/', '%2F')}",
|
184 |
"name": metadata.get("name", model_id.split("/")[-1]),
|
185 |
+
"purl": f"pkg:huggingface/{model_id.replace('/', '/')}"
|
186 |
}
|
187 |
|
188 |
if "description" in metadata:
|