@@ -123,8 +123,8 @@ class FullScanMetadata:
123123 repository_id : str
124124 branch : str
125125 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
128128 committers : Optional [List [str ]] = None
129129 commit_message : Optional [str ] = None
130130 commit_hash : Optional [str ] = None
@@ -189,21 +189,30 @@ def from_dict(cls, data: dict) -> "GetFullScanMetadataResponse":
189189 data = FullScanMetadata .from_dict (data .get ("data" )) if data .get ("data" ) else None
190190 )
191191
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
196199
197200 def __getitem__ (self , key ): return getattr (self , key )
198201 def to_dict (self ): return asdict (self )
199202
200203 @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 )
202207 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
205213 )
206214
215+
207216@dataclass
208217class SocketScore :
209218 supplyChain : float
@@ -355,11 +364,11 @@ def from_dict(cls, data: dict) -> "LicenseAttribution":
355364 )
356365
357366@dataclass
358- class DiffArtifactAlert :
367+ class SocketAlert :
359368 key : str
360369 type : str
361- severity : Optional [ SocketIssueSeverity ] = None
362- category : Optional [ SocketCategory ] = None
370+ severity : SocketIssueSeverity
371+ category : SocketCategory
363372 file : Optional [str ] = None
364373 start : Optional [int ] = None
365374 end : Optional [int ] = None
@@ -371,14 +380,12 @@ def __getitem__(self, key): return getattr(self, key)
371380 def to_dict (self ): return asdict (self )
372381
373382 @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" :
377384 return cls (
378385 key = data ["key" ],
379386 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" ]) ,
382389 file = data .get ("file" ),
383390 start = data .get ("start" ),
384391 end = data .get ("end" ),
@@ -387,28 +394,29 @@ def from_dict(cls, data: dict) -> "DiffArtifactAlert":
387394 actionPolicyIndex = data .get ("actionPolicyIndex" )
388395 )
389396
397+
390398@dataclass
391399class DiffArtifact :
392400 diffType : DiffType
393401 id : str
394402 type : str
395403 name : str
396- license : str
397- scores : SocketScore
398- capabilities : SecurityCapabilities
399- files : str
404+ score : SocketScore
400405 version : str
401- alerts : List [DiffArtifactAlert ]
406+ alerts : List [SocketAlert ]
402407 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
405414 namespace : Optional [str ] = None
406415 subpath : Optional [str ] = None
407416 artifact_id : Optional [str ] = None
408417 artifactId : Optional [str ] = None
409418 qualifiers : Optional [Dict [str , Any ]] = None
410419 size : Optional [int ] = None
411- author : Optional [str ] = None
412420 state : Optional [str ] = None
413421 error : Optional [str ] = None
414422 licenseAttrib : Optional [List [LicenseAttribution ]] = None
@@ -418,27 +426,29 @@ def to_dict(self): return asdict(self)
418426
419427 @classmethod
420428 def from_dict (cls , data : dict ) -> "DiffArtifact" :
429+ base_data = data .get ("base" )
430+ head_data = data .get ("head" )
421431 return cls (
422432 diffType = DiffType (data ["diffType" ]),
423433 id = data ["id" ],
424434 type = data ["type" ],
425435 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" ]),
430437 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" ]],
432439 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 ,
435445 namespace = data .get ("namespace" ),
436446 subpath = data .get ("subpath" ),
437447 artifact_id = data .get ("artifact_id" ),
438448 artifactId = data .get ("artifactId" ),
439449 qualifiers = data .get ("qualifiers" ),
440450 size = data .get ("size" ),
441- author = data .get ("author" ),
451+ author = data .get ("author" , [] ),
442452 state = data .get ("state" ),
443453 error = data .get ("error" ),
444454 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":
532542 data = FullScanDiffReport .from_dict (data .get ("data" )) if data .get ("data" ) else None
533543 )
534544
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-
588545@dataclass (kw_only = True )
589546class SocketArtifact (SocketPURL , SocketArtifactLink ):
590547 id : str
591- alerts : Optional [List [SocketAlert ]] = field (default_factory = list )
548+ alerts : List [SocketAlert ]
549+ score : SocketScore
592550 author : Optional [List [str ]] = field (default_factory = list )
593551 batchIndex : Optional [int ] = None
594552 license : Optional [str ] = None
595553 licenseAttrib : Optional [List [LicenseAttribution ]] = field (default_factory = list )
596554 licenseDetails : Optional [List [LicenseDetail ]] = field (default_factory = list )
597- score : Optional [SocketScore ] = None
598- size : Optional [float ] = None
555+ size : Optional [int ] = None
599556
600557 def __getitem__ (self , key ): return getattr (self , key )
601558 def to_dict (self ): return asdict (self )
602559
603560 @classmethod
604561 def from_dict (cls , data : dict ) -> "SocketArtifact" :
605- # First get the base class data
606562 purl_data = {k : data .get (k ) for k in SocketPURL .__dataclass_fields__ }
607563 link_data = {k : data .get (k ) for k in SocketArtifactLink .__dataclass_fields__ }
608564
609- # Handle nested types
610565 alerts = data .get ("alerts" )
611566 license_attrib = data .get ("licenseAttrib" )
612567 license_details = data .get ("licenseDetails" )
@@ -658,7 +613,7 @@ def create_params_string(self, params: dict) -> str:
658613 for name , value in params .items ():
659614 if value :
660615 if name == "committers" and isinstance (value , list ):
661- # Handle committers specially - add multiple params
616+
662617 for committer in value :
663618 param_str += f"&{ name } ={ committer } "
664619 else :
@@ -699,7 +654,7 @@ def post(self, files: list, params: FullScanParams) -> CreateFullScanResponse:
699654 org_slug = str (params .org_slug )
700655 params_dict = params .to_dict ()
701656 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 )
703658
704659 path = "orgs/" + org_slug + "/full-scans" + str (params_arg )
705660
@@ -772,12 +727,12 @@ def stream(self, org_slug: str, full_scan_id: str) -> FullScanStreamResponse:
772727 item = json .loads (line )
773728 stream_str .append (item )
774729 for val in stream_str :
775- artifacts [val ["id" ]] = val # Just store the raw dict
730+ artifacts [val ["id" ]] = val
776731
777732 return FullScanStreamResponse .from_dict ({
778733 "success" : True ,
779734 "status" : 200 ,
780- "artifacts" : artifacts # Let from_dict handle the conversion
735+ "artifacts" : artifacts
781736 })
782737 except Exception as e :
783738 error_message = f"Error parsing stream response: { str (e )} "
0 commit comments