@@ -123,8 +123,8 @@ class FullScanMetadata:
123
123
repository_id : str
124
124
branch : str
125
125
html_report_url : str
126
- repo : Optional [str ] = None # In docs, never shows up
127
- organization_slug : Optional [str ] = None # In docs, never shows up
126
+ repo : Optional [str ] = None
127
+ organization_slug : Optional [str ] = None
128
128
committers : Optional [List [str ]] = None
129
129
commit_message : Optional [str ] = None
130
130
commit_hash : Optional [str ] = None
@@ -189,21 +189,30 @@ def from_dict(cls, data: dict) -> "GetFullScanMetadataResponse":
189
189
data = FullScanMetadata .from_dict (data .get ("data" )) if data .get ("data" ) else None
190
190
)
191
191
192
- @dataclass
193
- class DependencyRef :
194
- direct : bool
195
- toplevelAncestors : List [str ]
192
+ @dataclass (kw_only = True )
193
+ class SocketArtifactLink :
194
+ topLevelAncestors : List [str ]
195
+ direct : bool = False
196
+ artifact : Optional [Dict ] = None
197
+ dependencies : Optional [List [str ]] = None
198
+ manifestFiles : Optional [List [SocketManifestReference ]] = None
196
199
197
200
def __getitem__ (self , key ): return getattr (self , key )
198
201
def to_dict (self ): return asdict (self )
199
202
200
203
@classmethod
201
- def from_dict (cls , data : dict ) -> "DependencyRef" :
204
+ def from_dict (cls , data : dict ) -> "SocketArtifactLink" :
205
+ manifest_files = data .get ("manifestFiles" )
206
+ direct_val = data .get ("direct" , False )
202
207
return cls (
203
- direct = data ["direct" ],
204
- toplevelAncestors = data ["toplevelAncestors" ]
208
+ topLevelAncestors = data ["topLevelAncestors" ],
209
+ direct = direct_val if isinstance (direct_val , bool ) else direct_val .lower () == "true" ,
210
+ artifact = data .get ("artifact" ),
211
+ dependencies = data .get ("dependencies" ),
212
+ manifestFiles = [SocketManifestReference .from_dict (m ) for m in manifest_files ] if manifest_files else None
205
213
)
206
214
215
+
207
216
@dataclass
208
217
class SocketScore :
209
218
supplyChain : float
@@ -355,11 +364,11 @@ def from_dict(cls, data: dict) -> "LicenseAttribution":
355
364
)
356
365
357
366
@dataclass
358
- class DiffArtifactAlert :
367
+ class SocketAlert :
359
368
key : str
360
369
type : str
361
- severity : Optional [ SocketIssueSeverity ] = None
362
- category : Optional [ SocketCategory ] = None
370
+ severity : SocketIssueSeverity
371
+ category : SocketCategory
363
372
file : Optional [str ] = None
364
373
start : Optional [int ] = None
365
374
end : Optional [int ] = None
@@ -371,14 +380,12 @@ def __getitem__(self, key): return getattr(self, key)
371
380
def to_dict (self ): return asdict (self )
372
381
373
382
@classmethod
374
- def from_dict (cls , data : dict ) -> "DiffArtifactAlert" :
375
- severity = data .get ("severity" )
376
- category = data .get ("category" )
383
+ def from_dict (cls , data : dict ) -> "SocketAlert" :
377
384
return cls (
378
385
key = data ["key" ],
379
386
type = data ["type" ],
380
- severity = SocketIssueSeverity (severity ) if severity else None ,
381
- category = SocketCategory (category ) if category else None ,
387
+ severity = SocketIssueSeverity (data [ " severity" ]) ,
388
+ category = SocketCategory (data [ " category" ]) ,
382
389
file = data .get ("file" ),
383
390
start = data .get ("start" ),
384
391
end = data .get ("end" ),
@@ -387,28 +394,29 @@ def from_dict(cls, data: dict) -> "DiffArtifactAlert":
387
394
actionPolicyIndex = data .get ("actionPolicyIndex" )
388
395
)
389
396
397
+
390
398
@dataclass
391
399
class DiffArtifact :
392
400
diffType : DiffType
393
401
id : str
394
402
type : str
395
403
name : str
396
- license : str
397
- scores : SocketScore
398
- capabilities : SecurityCapabilities
399
- files : str
404
+ score : SocketScore
400
405
version : str
401
- alerts : List [DiffArtifactAlert ]
406
+ alerts : List [SocketAlert ]
402
407
licenseDetails : List [LicenseDetail ]
403
- base : Optional [DependencyRef ] = None
404
- head : Optional [DependencyRef ] = None
408
+ author : List [str ] = field (default_factory = list )
409
+ license : Optional [str ] = None
410
+ files : Optional [str ] = None
411
+ capabilities : Optional [SecurityCapabilities ] = None
412
+ base : Optional [List [SocketArtifactLink ]] = None
413
+ head : Optional [List [SocketArtifactLink ]] = None
405
414
namespace : Optional [str ] = None
406
415
subpath : Optional [str ] = None
407
416
artifact_id : Optional [str ] = None
408
417
artifactId : Optional [str ] = None
409
418
qualifiers : Optional [Dict [str , Any ]] = None
410
419
size : Optional [int ] = None
411
- author : Optional [str ] = None
412
420
state : Optional [str ] = None
413
421
error : Optional [str ] = None
414
422
licenseAttrib : Optional [List [LicenseAttribution ]] = None
@@ -418,27 +426,29 @@ def to_dict(self): return asdict(self)
418
426
419
427
@classmethod
420
428
def from_dict (cls , data : dict ) -> "DiffArtifact" :
429
+ base_data = data .get ("base" )
430
+ head_data = data .get ("head" )
421
431
return cls (
422
432
diffType = DiffType (data ["diffType" ]),
423
433
id = data ["id" ],
424
434
type = data ["type" ],
425
435
name = data ["name" ],
426
- license = data .get ("license" , "" ),
427
- scores = SocketScore .from_dict (data ["score" ]),
428
- capabilities = SecurityCapabilities .from_dict (data ["capabilities" ]),
429
- files = data ["files" ],
436
+ score = SocketScore .from_dict (data ["score" ]),
430
437
version = data ["version" ],
431
- alerts = [DiffArtifactAlert .from_dict (alert ) for alert in data ["alerts" ]],
438
+ alerts = [SocketAlert .from_dict (alert ) for alert in data ["alerts" ]],
432
439
licenseDetails = [LicenseDetail .from_dict (detail ) for detail in data ["licenseDetails" ]],
433
- base = DependencyRef .from_dict (data ["base" ]) if data .get ("base" ) else None ,
434
- head = DependencyRef .from_dict (data ["head" ]) if data .get ("head" ) else None ,
440
+ files = data .get ("files" ),
441
+ license = data .get ("license" ),
442
+ capabilities = SecurityCapabilities .from_dict (data ["capabilities" ]) if data .get ("capabilities" ) else None ,
443
+ base = [SocketArtifactLink .from_dict (b ) for b in base_data ] if base_data else None ,
444
+ head = [SocketArtifactLink .from_dict (h ) for h in head_data ] if head_data else None ,
435
445
namespace = data .get ("namespace" ),
436
446
subpath = data .get ("subpath" ),
437
447
artifact_id = data .get ("artifact_id" ),
438
448
artifactId = data .get ("artifactId" ),
439
449
qualifiers = data .get ("qualifiers" ),
440
450
size = data .get ("size" ),
441
- author = data .get ("author" ),
451
+ author = data .get ("author" , [] ),
442
452
state = data .get ("state" ),
443
453
error = data .get ("error" ),
444
454
licenseAttrib = [LicenseAttribution .from_dict (attrib ) for attrib in data ["licenseAttrib" ]] if data .get ("licenseAttrib" ) else None
@@ -532,81 +542,26 @@ def from_dict(cls, data: dict) -> "StreamDiffResponse":
532
542
data = FullScanDiffReport .from_dict (data .get ("data" )) if data .get ("data" ) else None
533
543
)
534
544
535
- @dataclass (kw_only = True )
536
- class SocketArtifactLink :
537
- topLevelAncestors : List [str ]
538
- artifact : Optional [Dict ] = None
539
- dependencies : Optional [List [str ]] = None
540
- direct : Optional [bool ] = None
541
- manifestFiles : Optional [List [SocketManifestReference ]] = None
542
-
543
- def __getitem__ (self , key ): return getattr (self , key )
544
- def to_dict (self ): return asdict (self )
545
-
546
- @classmethod
547
- def from_dict (cls , data : dict ) -> "SocketArtifactLink" :
548
- manifest_files = data .get ("manifestFiles" )
549
- return cls (
550
- topLevelAncestors = data ["topLevelAncestors" ],
551
- artifact = data .get ("artifact" ),
552
- dependencies = data .get ("dependencies" ),
553
- direct = data .get ("direct" ),
554
- manifestFiles = [SocketManifestReference .from_dict (m ) for m in manifest_files ] if manifest_files else None
555
- )
556
-
557
- @dataclass
558
- class SocketAlert :
559
- key : str
560
- type : str
561
- severity : SocketIssueSeverity
562
- category : SocketCategory
563
- file : Optional [str ] = None
564
- start : Optional [int ] = None
565
- end : Optional [int ] = None
566
- props : Optional [Dict [str , Any ]] = None
567
- action : Optional [str ] = None
568
- actionPolicyIndex : Optional [int ] = None
569
-
570
- def __getitem__ (self , key ): return getattr (self , key )
571
- def to_dict (self ): return asdict (self )
572
-
573
- @classmethod
574
- def from_dict (cls , data : dict ) -> "SocketAlert" :
575
- return cls (
576
- key = data ["key" ],
577
- type = data ["type" ],
578
- severity = SocketIssueSeverity (data ["severity" ]),
579
- category = SocketCategory (data ["category" ]),
580
- file = data .get ("file" ),
581
- start = data .get ("start" ),
582
- end = data .get ("end" ),
583
- props = data .get ("props" ),
584
- action = data .get ("action" ),
585
- actionPolicyIndex = data .get ("actionPolicyIndex" )
586
- )
587
-
588
545
@dataclass (kw_only = True )
589
546
class SocketArtifact (SocketPURL , SocketArtifactLink ):
590
547
id : str
591
- alerts : Optional [List [SocketAlert ]] = field (default_factory = list )
548
+ alerts : List [SocketAlert ]
549
+ score : SocketScore
592
550
author : Optional [List [str ]] = field (default_factory = list )
593
551
batchIndex : Optional [int ] = None
594
552
license : Optional [str ] = None
595
553
licenseAttrib : Optional [List [LicenseAttribution ]] = field (default_factory = list )
596
554
licenseDetails : Optional [List [LicenseDetail ]] = field (default_factory = list )
597
- score : Optional [SocketScore ] = None
598
- size : Optional [float ] = None
555
+ size : Optional [int ] = None
599
556
600
557
def __getitem__ (self , key ): return getattr (self , key )
601
558
def to_dict (self ): return asdict (self )
602
559
603
560
@classmethod
604
561
def from_dict (cls , data : dict ) -> "SocketArtifact" :
605
- # First get the base class data
606
562
purl_data = {k : data .get (k ) for k in SocketPURL .__dataclass_fields__ }
607
563
link_data = {k : data .get (k ) for k in SocketArtifactLink .__dataclass_fields__ }
608
564
609
- # Handle nested types
610
565
alerts = data .get ("alerts" )
611
566
license_attrib = data .get ("licenseAttrib" )
612
567
license_details = data .get ("licenseDetails" )
@@ -658,7 +613,7 @@ def create_params_string(self, params: dict) -> str:
658
613
for name , value in params .items ():
659
614
if value :
660
615
if name == "committers" and isinstance (value , list ):
661
- # Handle committers specially - add multiple params
616
+
662
617
for committer in value :
663
618
param_str += f"&{ name } ={ committer } "
664
619
else :
@@ -699,7 +654,7 @@ def post(self, files: list, params: FullScanParams) -> CreateFullScanResponse:
699
654
org_slug = str (params .org_slug )
700
655
params_dict = params .to_dict ()
701
656
params_dict .pop ("org_slug" )
702
- params_arg = self .create_params_string (params_dict ) # Convert params to dict
657
+ params_arg = self .create_params_string (params_dict )
703
658
704
659
path = "orgs/" + org_slug + "/full-scans" + str (params_arg )
705
660
@@ -772,12 +727,12 @@ def stream(self, org_slug: str, full_scan_id: str) -> FullScanStreamResponse:
772
727
item = json .loads (line )
773
728
stream_str .append (item )
774
729
for val in stream_str :
775
- artifacts [val ["id" ]] = val # Just store the raw dict
730
+ artifacts [val ["id" ]] = val
776
731
777
732
return FullScanStreamResponse .from_dict ({
778
733
"success" : True ,
779
734
"status" : 200 ,
780
- "artifacts" : artifacts # Let from_dict handle the conversion
735
+ "artifacts" : artifacts
781
736
})
782
737
except Exception as e :
783
738
error_message = f"Error parsing stream response: { str (e )} "
0 commit comments