@@ -216,30 +216,64 @@ def load_files_for_sending(files: List[str], workspace: str) -> List[Tuple[str,
216
216
217
217
return send_files
218
218
219
- def create_full_scan (self , files : List [str ], params : FullScanParams ) -> FullScan :
220
- """
221
- Creates a new full scan via the Socket API.
222
-
223
- Args:
224
- files: List of files to scan
225
- params: Parameters for the full scan
226
-
227
- Returns:
228
- FullScan object with scan results
229
- """
219
+ def create_full_scan (self , files : List [str ], params : FullScanParams , store_results : bool = True ) -> FullScan :
220
+ """Creates a new full scan via the Socket API."""
230
221
log .debug ("Creating new full scan" )
231
222
create_full_start = time .time ()
232
223
224
+ # Time the post API call
225
+ post_start = time .time ()
233
226
res = self .sdk .fullscans .post (files , params )
227
+ post_end = time .time ()
228
+ log .debug (f"API fullscans.post took { post_end - post_start :.2f} seconds" )
229
+
234
230
if not res .success :
235
231
log .error (f"Error creating full scan: { res .message } , status: { res .status } " )
236
232
raise Exception (f"Error creating full scan: { res .message } , status: { res .status } " )
237
233
238
234
full_scan = FullScan (** asdict (res .data ))
235
+
236
+ if not store_results :
237
+ full_scan .sbom_artifacts = []
238
+ full_scan .packages = {}
239
+ return full_scan
239
240
240
- full_scan_artifacts_dict = self .get_sbom_data (full_scan .id )
241
- full_scan .sbom_artifacts = self .get_sbom_data_list (full_scan_artifacts_dict )
242
- full_scan .packages = self .create_packages_dict (full_scan .sbom_artifacts )
241
+ # Time the stream API call
242
+ stream_start = time .time ()
243
+ artifacts_response = self .sdk .fullscans .stream (self .config .org_slug , full_scan .id )
244
+ stream_end = time .time ()
245
+ log .debug (f"API fullscans.stream took { stream_end - stream_start :.2f} seconds" )
246
+
247
+ if not artifacts_response .success :
248
+ log .error (f"Failed to get SBOM data for full-scan { full_scan .id } " )
249
+ log .error (artifacts_response .message )
250
+ full_scan .sbom_artifacts = []
251
+ full_scan .packages = {}
252
+ return full_scan
253
+
254
+ # Store the original SocketArtifact objects
255
+ full_scan .sbom_artifacts = list (artifacts_response .artifacts .values ())
256
+
257
+ # Create packages dictionary directly from the artifacts
258
+ packages = {}
259
+ top_level_count = {}
260
+
261
+ for artifact in artifacts_response .artifacts .values ():
262
+ package = Package .from_socket_artifact (artifact )
263
+ if package .id not in packages :
264
+ package .license_text = self .get_package_license_text (package )
265
+ packages [package .id ] = package
266
+
267
+ # Count top-level ancestors in the same pass
268
+ if package .topLevelAncestors :
269
+ for top_id in package .topLevelAncestors :
270
+ top_level_count [top_id ] = top_level_count .get (top_id , 0 ) + 1
271
+
272
+ # Update transitive counts
273
+ for package in packages .values ():
274
+ package .transitives = top_level_count .get (package .id , 0 )
275
+
276
+ full_scan .packages = packages
243
277
244
278
create_full_end = time .time ()
245
279
total_time = create_full_end - create_full_start
@@ -351,22 +385,18 @@ def get_head_scan_for_repo(self, repo_slug: str) -> str:
351
385
return repo_info .head_full_scan_id if repo_info .head_full_scan_id else None
352
386
353
387
def get_added_and_removed_packages (self , head_full_scan_id : Optional [str ], new_full_scan : FullScan ) -> Tuple [Dict [str , Package ], Dict [str , Package ]]:
354
- """
355
- Get packages that were added and removed between scans.
356
-
357
- Args:
358
- head_full_scan: Previous scan (may be None if first scan)
359
- new_full_scan: New scan just created
360
-
361
- Returns:
362
- Tuple of (added_packages, removed_packages) dictionaries
363
- """
388
+ """Get packages that were added and removed between scans."""
364
389
if head_full_scan_id is None :
365
390
log .info (f"No head scan found. New scan ID: { new_full_scan .id } " )
366
391
return new_full_scan .packages , {}
367
392
368
393
log .info (f"Comparing scans - Head scan ID: { head_full_scan_id } , New scan ID: { new_full_scan .id } " )
394
+
395
+ # Time the stream_diff API call
396
+ diff_start = time .time ()
369
397
diff_report = self .sdk .fullscans .stream_diff (self .config .org_slug , head_full_scan_id , new_full_scan .id ).data
398
+ diff_end = time .time ()
399
+ log .debug (f"API fullscans.stream_diff took { diff_end - diff_start :.2f} seconds" )
370
400
371
401
log .info (f"Diff report artifact counts:" )
372
402
log .info (f"Added: { len (diff_report .artifacts .added )} " )
@@ -383,12 +413,12 @@ def get_added_and_removed_packages(self, head_full_scan_id: Optional[str], new_f
383
413
384
414
for artifact in added_artifacts :
385
415
try :
386
- pkg = Package .from_diff_artifact (asdict ( artifact ) )
416
+ pkg = Package .from_diff_artifact (artifact )
387
417
added_packages [artifact .id ] = pkg
388
418
except KeyError :
389
419
log .error (f"KeyError: Could not create package from added artifact { artifact .id } " )
390
420
log .error (f"Artifact details - name: { artifact .name } , version: { artifact .version } " )
391
- matches = [p for p in new_full_scan . packages .values () if p .name == artifact .name and p .version == artifact .version ]
421
+ matches = [p for p in added_artifacts .values () if p .name == artifact .name and p .version == artifact .version ]
392
422
if matches :
393
423
log .error (f"Found { len (matches )} packages with matching name/version:" )
394
424
for m in matches :
@@ -403,7 +433,7 @@ def get_added_and_removed_packages(self, head_full_scan_id: Optional[str], new_f
403
433
except KeyError :
404
434
log .error (f"KeyError: Could not create package from removed artifact { artifact .id } " )
405
435
log .error (f"Artifact details - name: { artifact .name } , version: { artifact .version } " )
406
- matches = [p for p in head_full_scan . packages .values () if p .name == artifact .name and p .version == artifact .version ]
436
+ matches = [p for p in removed_artifacts .values () if p .name == artifact .name and p .version == artifact .version ]
407
437
if matches :
408
438
log .error (f"Found { len (matches )} packages with matching name/version:" )
409
439
for m in matches :
@@ -419,14 +449,7 @@ def create_new_diff(
419
449
params : FullScanParams ,
420
450
no_change : bool = False
421
451
) -> Diff :
422
- """Create a new diff using the Socket SDK.
423
-
424
- Args:
425
- path: Path to look for manifest files
426
- params: Query params for the Full Scan endpoint
427
-
428
- no_change: If True, return empty diff
429
- """
452
+ """Create a new diff using the Socket SDK."""
430
453
print (f"starting create_new_diff with no_change: { no_change } " )
431
454
if no_change :
432
455
return Diff (id = "no_diff_id" )
@@ -439,20 +462,16 @@ def create_new_diff(
439
462
if not files :
440
463
return Diff (id = "no_diff_id" )
441
464
465
+ # Initialize head scan ID
442
466
head_full_scan_id = None
443
-
444
467
try :
445
468
# Get head scan ID
446
469
head_full_scan_id = self .get_head_scan_for_repo (params .repo )
447
470
except APIResourceNotFound :
448
- head_full_scan_id = None
449
-
450
- # Create new scan
451
- new_scan_start = time .time ()
452
- new_full_scan = self .create_full_scan (files_for_sending , params )
453
- new_scan_end = time .time ()
454
- log .info (f"Total time to create new full scan: { new_scan_end - new_scan_start :.2f} " )
471
+ pass
455
472
473
+ # Create new scan - only store results if we don't have a head scan to diff against
474
+ new_full_scan = self .create_full_scan (files_for_sending , params , store_results = head_full_scan_id is None )
456
475
457
476
added_packages , removed_packages = self .get_added_and_removed_packages (head_full_scan_id , new_full_scan )
458
477
0 commit comments