hiddenlayer-sdk 1.0.0__py3-none-any.whl → 1.1.0__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.
@@ -12,3 +12,4 @@ class ScanStatus(str, Enum):
12
12
 
13
13
  class ApiErrors(str, Enum):
14
14
  NON_ADHOC_SENSOR_DELETE = "only adhoc sensors may be deleted"
15
+ SENSOR_EXISTS = "already exists"
hiddenlayer/sdk/models.py CHANGED
@@ -9,7 +9,7 @@ from hiddenlayer.sdk.rest.models import (
9
9
  ModelInventoryInfo,
10
10
  ScanReportV3,
11
11
  )
12
- from hiddenlayer.sdk.rest.models.file_results_inner import FileResultsInner
12
+ from hiddenlayer.sdk.rest.models.file_scan_report_v3 import FileScanReportV3
13
13
  from hiddenlayer.sdk.rest.models.sarif210 import Sarif210
14
14
 
15
15
 
@@ -50,7 +50,7 @@ class EmptyScanResults(ScanResults):
50
50
  start_time: datetime = datetime.now()
51
51
  end_time: Optional[datetime] = datetime.now()
52
52
  severity: Optional[StrictStr] = ""
53
- file_results: Optional[List[FileResultsInner]] = []
53
+ file_results: Optional[List[FileScanReportV3]] = []
54
54
 
55
55
 
56
56
  class Sarif(Sarif210):
@@ -54,8 +54,8 @@ from hiddenlayer.sdk.rest.models.external_properties import ExternalProperties
54
54
  from hiddenlayer.sdk.rest.models.external_property_file_reference import ExternalPropertyFileReference
55
55
  from hiddenlayer.sdk.rest.models.external_property_file_references import ExternalPropertyFileReferences
56
56
  from hiddenlayer.sdk.rest.models.file_details_v3 import FileDetailsV3
57
- from hiddenlayer.sdk.rest.models.file_results_inner import FileResultsInner
58
57
  from hiddenlayer.sdk.rest.models.file_scan_report_v3 import FileScanReportV3
58
+ from hiddenlayer.sdk.rest.models.file_scan_reports_v3 import FileScanReportsV3
59
59
  from hiddenlayer.sdk.rest.models.fix import Fix
60
60
  from hiddenlayer.sdk.rest.models.get_multipart_upload_response import GetMultipartUploadResponse
61
61
  from hiddenlayer.sdk.rest.models.graph import Graph
@@ -17,7 +17,7 @@ from typing import Any, Dict, List, Optional, Tuple, Union
17
17
  from typing_extensions import Annotated
18
18
 
19
19
  from pydantic import Field, StrictFloat, StrictInt, StrictStr, field_validator
20
- from typing import Any, Dict, Optional, Union
20
+ from typing import Any, Optional, Union
21
21
  from typing_extensions import Annotated
22
22
  from hiddenlayer.sdk.rest.models.create_sensor_request import CreateSensorRequest
23
23
  from hiddenlayer.sdk.rest.models.get_multipart_upload_response import GetMultipartUploadResponse
@@ -334,7 +334,7 @@ class SensorApi:
334
334
  _content_type: Optional[StrictStr] = None,
335
335
  _headers: Optional[Dict[StrictStr, Any]] = None,
336
336
  _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,
337
- ) -> object:
337
+ ) -> None:
338
338
  """Complete Multipart Upload
339
339
 
340
340
 
@@ -374,7 +374,7 @@ class SensorApi:
374
374
  )
375
375
 
376
376
  _response_types_map: Dict[str, Optional[str]] = {
377
- '200': "object",
377
+ '200': None,
378
378
  '400': None,
379
379
  }
380
380
  response_data = self.api_client.call_api(
@@ -405,7 +405,7 @@ class SensorApi:
405
405
  _content_type: Optional[StrictStr] = None,
406
406
  _headers: Optional[Dict[StrictStr, Any]] = None,
407
407
  _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,
408
- ) -> ApiResponse[object]:
408
+ ) -> ApiResponse[None]:
409
409
  """Complete Multipart Upload
410
410
 
411
411
 
@@ -445,7 +445,7 @@ class SensorApi:
445
445
  )
446
446
 
447
447
  _response_types_map: Dict[str, Optional[str]] = {
448
- '200': "object",
448
+ '200': None,
449
449
  '400': None,
450
450
  }
451
451
  response_data = self.api_client.call_api(
@@ -516,7 +516,7 @@ class SensorApi:
516
516
  )
517
517
 
518
518
  _response_types_map: Dict[str, Optional[str]] = {
519
- '200': "object",
519
+ '200': None,
520
520
  '400': None,
521
521
  }
522
522
  response_data = self.api_client.call_api(
@@ -559,12 +559,6 @@ class SensorApi:
559
559
  # process the body parameter
560
560
 
561
561
 
562
- # set the HTTP header `Accept`
563
- _header_params['Accept'] = self.api_client.select_header_accept(
564
- [
565
- 'application/json'
566
- ]
567
- )
568
562
 
569
563
 
570
564
  # authentication setting
@@ -1998,7 +1992,7 @@ class SensorApi:
1998
1992
  _content_type: Optional[StrictStr] = None,
1999
1993
  _headers: Optional[Dict[StrictStr, Any]] = None,
2000
1994
  _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,
2001
- ) -> object:
1995
+ ) -> None:
2002
1996
  """Upload part
2003
1997
 
2004
1998
 
@@ -2044,7 +2038,7 @@ class SensorApi:
2044
2038
  )
2045
2039
 
2046
2040
  _response_types_map: Dict[str, Optional[str]] = {
2047
- '200': "object",
2041
+ '200': None,
2048
2042
  '400': None,
2049
2043
  }
2050
2044
  response_data = self.api_client.call_api(
@@ -2077,7 +2071,7 @@ class SensorApi:
2077
2071
  _content_type: Optional[StrictStr] = None,
2078
2072
  _headers: Optional[Dict[StrictStr, Any]] = None,
2079
2073
  _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,
2080
- ) -> ApiResponse[object]:
2074
+ ) -> ApiResponse[None]:
2081
2075
  """Upload part
2082
2076
 
2083
2077
 
@@ -2123,7 +2117,7 @@ class SensorApi:
2123
2117
  )
2124
2118
 
2125
2119
  _response_types_map: Dict[str, Optional[str]] = {
2126
- '200': "object",
2120
+ '200': None,
2127
2121
  '400': None,
2128
2122
  }
2129
2123
  response_data = self.api_client.call_api(
@@ -2202,7 +2196,7 @@ class SensorApi:
2202
2196
  )
2203
2197
 
2204
2198
  _response_types_map: Dict[str, Optional[str]] = {
2205
- '200': "object",
2199
+ '200': None,
2206
2200
  '400': None,
2207
2201
  }
2208
2202
  response_data = self.api_client.call_api(
@@ -2251,12 +2245,6 @@ class SensorApi:
2251
2245
  _body_params = body
2252
2246
 
2253
2247
 
2254
- # set the HTTP header `Accept`
2255
- _header_params['Accept'] = self.api_client.select_header_accept(
2256
- [
2257
- 'application/json'
2258
- ]
2259
- )
2260
2248
 
2261
2249
  # set the HTTP header `Content-Type`
2262
2250
  if _content_type:
@@ -32,8 +32,8 @@ from hiddenlayer.sdk.rest.models.external_properties import ExternalProperties
32
32
  from hiddenlayer.sdk.rest.models.external_property_file_reference import ExternalPropertyFileReference
33
33
  from hiddenlayer.sdk.rest.models.external_property_file_references import ExternalPropertyFileReferences
34
34
  from hiddenlayer.sdk.rest.models.file_details_v3 import FileDetailsV3
35
- from hiddenlayer.sdk.rest.models.file_results_inner import FileResultsInner
36
35
  from hiddenlayer.sdk.rest.models.file_scan_report_v3 import FileScanReportV3
36
+ from hiddenlayer.sdk.rest.models.file_scan_reports_v3 import FileScanReportsV3
37
37
  from hiddenlayer.sdk.rest.models.fix import Fix
38
38
  from hiddenlayer.sdk.rest.models.get_multipart_upload_response import GetMultipartUploadResponse
39
39
  from hiddenlayer.sdk.rest.models.graph import Graph
@@ -17,9 +17,11 @@ import pprint
17
17
  import re # noqa: F401
18
18
  import json
19
19
 
20
- from pydantic import BaseModel, ConfigDict
20
+ from datetime import datetime
21
+ from pydantic import BaseModel, ConfigDict, Field, StrictStr, field_validator
21
22
  from typing import Any, ClassVar, Dict, List, Optional
22
- from hiddenlayer.sdk.rest.models.file_results_inner import FileResultsInner
23
+ from hiddenlayer.sdk.rest.models.file_details_v3 import FileDetailsV3
24
+ from hiddenlayer.sdk.rest.models.scan_detection_v3 import ScanDetectionV3
23
25
  from typing import Optional, Set
24
26
  from typing_extensions import Self
25
27
 
@@ -27,8 +29,23 @@ class FileScanReportV3(BaseModel):
27
29
  """
28
30
  FileScanReportV3
29
31
  """ # noqa: E501
30
- file_results: Optional[List[FileResultsInner]] = None
31
- __properties: ClassVar[List[str]] = ["file_results"]
32
+ file_instance_id: StrictStr = Field(description="unique ID of the file")
33
+ file_location: StrictStr = Field(description="full file path")
34
+ start_time: datetime = Field(description="time the scan started")
35
+ end_time: datetime = Field(description="time the scan ended")
36
+ details: FileDetailsV3
37
+ status: StrictStr = Field(description="status of the scan")
38
+ seen: datetime = Field(description="time the scan was seen at")
39
+ detections: Optional[List[ScanDetectionV3]] = None
40
+ file_results: Optional[List[FileScanReportV3]] = None
41
+ __properties: ClassVar[List[str]] = ["file_instance_id", "file_location", "start_time", "end_time", "details", "status", "seen", "detections", "file_results"]
42
+
43
+ @field_validator('status')
44
+ def status_validate_enum(cls, value):
45
+ """Validates the enum"""
46
+ if value not in set(['skipped', 'pending', 'running', 'done', 'failed', 'canceled']):
47
+ raise ValueError("must be one of enum values ('skipped', 'pending', 'running', 'done', 'failed', 'canceled')")
48
+ return value
32
49
 
33
50
  model_config = ConfigDict(
34
51
  populate_by_name=True,
@@ -69,6 +86,16 @@ class FileScanReportV3(BaseModel):
69
86
  exclude=excluded_fields,
70
87
  exclude_none=True,
71
88
  )
89
+ # override the default output from pydantic by calling `to_dict()` of details
90
+ if self.details:
91
+ _dict['details'] = self.details.to_dict()
92
+ # override the default output from pydantic by calling `to_dict()` of each item in detections (list)
93
+ _items = []
94
+ if self.detections:
95
+ for _item in self.detections:
96
+ if _item:
97
+ _items.append(_item.to_dict())
98
+ _dict['detections'] = _items
72
99
  # override the default output from pydantic by calling `to_dict()` of each item in file_results (list)
73
100
  _items = []
74
101
  if self.file_results:
@@ -88,8 +115,18 @@ class FileScanReportV3(BaseModel):
88
115
  return cls.model_validate(obj)
89
116
 
90
117
  _obj = cls.model_validate({
91
- "file_results": [FileResultsInner.from_dict(_item) for _item in obj["file_results"]] if obj.get("file_results") is not None else None
118
+ "file_instance_id": obj.get("file_instance_id"),
119
+ "file_location": obj.get("file_location"),
120
+ "start_time": obj.get("start_time"),
121
+ "end_time": obj.get("end_time"),
122
+ "details": FileDetailsV3.from_dict(obj["details"]) if obj.get("details") is not None else None,
123
+ "status": obj.get("status"),
124
+ "seen": obj.get("seen"),
125
+ "detections": [ScanDetectionV3.from_dict(_item) for _item in obj["detections"]] if obj.get("detections") is not None else None,
126
+ "file_results": [FileScanReportV3.from_dict(_item) for _item in obj["file_results"]] if obj.get("file_results") is not None else None
92
127
  })
93
128
  return _obj
94
129
 
130
+ # TODO: Rewrite to not use raise_errors
131
+ FileScanReportV3.model_rebuild(raise_errors=False)
95
132
 
@@ -0,0 +1,95 @@
1
+ # coding: utf-8
2
+
3
+ """
4
+ HiddenLayer ModelScan V2
5
+
6
+ HiddenLayer ModelScan API for scanning of models
7
+
8
+ The version of the OpenAPI document: 1
9
+ Generated by OpenAPI Generator (https://openapi-generator.tech)
10
+
11
+ Do not edit the class manually.
12
+ """ # noqa: E501
13
+
14
+
15
+ from __future__ import annotations
16
+ import pprint
17
+ import re # noqa: F401
18
+ import json
19
+
20
+ from pydantic import BaseModel, ConfigDict
21
+ from typing import Any, ClassVar, Dict, List, Optional
22
+ from hiddenlayer.sdk.rest.models.file_scan_report_v3 import FileScanReportV3
23
+ from typing import Optional, Set
24
+ from typing_extensions import Self
25
+
26
+ class FileScanReportsV3(BaseModel):
27
+ """
28
+ FileScanReportsV3
29
+ """ # noqa: E501
30
+ file_results: Optional[List[FileScanReportV3]] = None
31
+ __properties: ClassVar[List[str]] = ["file_results"]
32
+
33
+ model_config = ConfigDict(
34
+ populate_by_name=True,
35
+ validate_assignment=True,
36
+ protected_namespaces=(),
37
+ )
38
+
39
+
40
+ def to_str(self) -> str:
41
+ """Returns the string representation of the model using alias"""
42
+ return pprint.pformat(self.model_dump(by_alias=True))
43
+
44
+ def to_json(self) -> str:
45
+ """Returns the JSON representation of the model using alias"""
46
+ # TODO: pydantic v2: use .model_dump_json(by_alias=True, exclude_unset=True) instead
47
+ return json.dumps(self.to_dict())
48
+
49
+ @classmethod
50
+ def from_json(cls, json_str: str) -> Optional[Self]:
51
+ """Create an instance of FileScanReportsV3 from a JSON string"""
52
+ return cls.from_dict(json.loads(json_str))
53
+
54
+ def to_dict(self) -> Dict[str, Any]:
55
+ """Return the dictionary representation of the model using alias.
56
+
57
+ This has the following differences from calling pydantic's
58
+ `self.model_dump(by_alias=True)`:
59
+
60
+ * `None` is only added to the output dict for nullable fields that
61
+ were set at model initialization. Other fields with value `None`
62
+ are ignored.
63
+ """
64
+ excluded_fields: Set[str] = set([
65
+ ])
66
+
67
+ _dict = self.model_dump(
68
+ by_alias=True,
69
+ exclude=excluded_fields,
70
+ exclude_none=True,
71
+ )
72
+ # override the default output from pydantic by calling `to_dict()` of each item in file_results (list)
73
+ _items = []
74
+ if self.file_results:
75
+ for _item in self.file_results:
76
+ if _item:
77
+ _items.append(_item.to_dict())
78
+ _dict['file_results'] = _items
79
+ return _dict
80
+
81
+ @classmethod
82
+ def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]:
83
+ """Create an instance of FileScanReportsV3 from a dict"""
84
+ if obj is None:
85
+ return None
86
+
87
+ if not isinstance(obj, dict):
88
+ return cls.model_validate(obj)
89
+
90
+ _obj = cls.model_validate({
91
+ "file_results": [FileScanReportV3.from_dict(_item) for _item in obj["file_results"]] if obj.get("file_results") is not None else None
92
+ })
93
+ return _obj
94
+
95
+
@@ -20,7 +20,7 @@ import json
20
20
  from datetime import datetime
21
21
  from pydantic import BaseModel, ConfigDict, Field, StrictInt, StrictStr, field_validator
22
22
  from typing import Any, ClassVar, Dict, List, Optional
23
- from hiddenlayer.sdk.rest.models.file_results_inner import FileResultsInner
23
+ from hiddenlayer.sdk.rest.models.file_scan_report_v3 import FileScanReportV3
24
24
  from hiddenlayer.sdk.rest.models.model_inventory_info import ModelInventoryInfo
25
25
  from typing import Optional, Set
26
26
  from typing_extensions import Self
@@ -40,7 +40,7 @@ class ScanReportV3(BaseModel):
40
40
  end_time: Optional[datetime] = Field(default=None, description="time the scan ended")
41
41
  status: StrictStr = Field(description="status of the scan")
42
42
  severity: Optional[StrictStr] = Field(default=None, description="detection severity")
43
- file_results: Optional[List[FileResultsInner]] = None
43
+ file_results: Optional[List[FileScanReportV3]] = None
44
44
  __properties: ClassVar[List[str]] = ["file_count", "files_with_detections_count", "detection_count", "detection_categories", "inventory", "version", "scan_id", "start_time", "end_time", "status", "severity", "file_results"]
45
45
 
46
46
  @field_validator('status')
@@ -132,7 +132,7 @@ class ScanReportV3(BaseModel):
132
132
  "end_time": obj.get("end_time"),
133
133
  "status": obj.get("status"),
134
134
  "severity": obj.get("severity"),
135
- "file_results": [FileResultsInner.from_dict(_item) for _item in obj["file_results"]] if obj.get("file_results") is not None else None
135
+ "file_results": [FileScanReportV3.from_dict(_item) for _item in obj["file_results"]] if obj.get("file_results") is not None else None
136
136
  })
137
137
  return _obj
138
138
 
@@ -28,7 +28,7 @@ class SensorSORModelCardResponse(BaseModel):
28
28
  SensorSORModelCardResponse
29
29
  """ # noqa: E501
30
30
  model_id: StrictStr
31
- created_at: StrictInt = Field(description="Unix timestamp")
31
+ created_at: StrictInt = Field(description="Unix Nano Epoch")
32
32
  plaintext_name: StrictStr
33
33
  active_versions: List[StrictInt]
34
34
  source: StrictStr
@@ -1,4 +1,6 @@
1
1
  import json
2
+ import random
3
+ import time
2
4
  from typing import Optional
3
5
 
4
6
  from hiddenlayer.sdk.constants import ApiErrors
@@ -37,6 +39,49 @@ class ModelAPI:
37
39
  )
38
40
  )
39
41
 
42
+ def create_or_get(self, *, model_name: str, model_version: Optional[int]) -> Model:
43
+ """
44
+ Creates a model in the HiddenLayer Platform if it does not exist.
45
+ If the model and version already exists, returns the existing model.
46
+
47
+ :params model_name: Name of the model
48
+ :params model_version: Version of the model
49
+
50
+ :returns: HiddenLayer ModelID
51
+ """
52
+ try:
53
+ return self.create(model_name=model_name, model_version=model_version)
54
+ except ApiException as e:
55
+ if e.status == 400 and str(e.body).find(ApiErrors.SENSOR_EXISTS) != -1:
56
+ return self.get_with_retry(
57
+ model_name=model_name, version=model_version, retry=3
58
+ )
59
+ else:
60
+ raise e
61
+
62
+ def get_with_retry(
63
+ self, *, model_name: str, version: Optional[int], retry: int
64
+ ) -> Model:
65
+ """
66
+ Gets a HiddenLayer model object. If not version is supplied, the latest model is returned.
67
+ Retries if the model is not found.
68
+
69
+ :param model_name: Name of the model.
70
+ :param version: Version of the model to get.
71
+ :param retry: Number of retries
72
+
73
+ :returns: HiddenLayer Model object
74
+ """
75
+
76
+ base_delay = 0.1 # seconds
77
+ for retryCount in range(retry):
78
+ try:
79
+ return self.get(model_name=model_name, version=version)
80
+ except ModelDoesNotExistError:
81
+ time.sleep(base_delay * 2**retryCount + random.uniform(0, 1))
82
+ pass
83
+ raise ModelDoesNotExistError(f"Model {model_name} does not exist")
84
+
40
85
  def get(self, *, model_name: str, version: Optional[int] = None) -> Model:
41
86
  """
42
87
  Gets a HiddenLayer model object. If not version is supplied, the latest model is returned.
@@ -90,7 +135,7 @@ class ModelAPI:
90
135
  )
91
136
  )
92
137
 
93
- if not models.results:
138
+ if not models.results or len(models.results) == 0:
94
139
  msg = f"Model {model_name} does not exist"
95
140
 
96
141
  if version:
@@ -70,7 +70,7 @@ class ModelScanAPI:
70
70
  file_path = Path(model_path)
71
71
 
72
72
  filesize = file_path.stat().st_size
73
- sensor = self._model_api.create(
73
+ sensor = self._model_api.create_or_get(
74
74
  model_name=model_name, model_version=model_version
75
75
  )
76
76
  upload = self._sensor_api.begin_multipart_upload(sensor.sensor_id, filesize)
@@ -1 +1 @@
1
- VERSION = "1.0.0"
1
+ VERSION = "1.1.0"
@@ -1,6 +1,6 @@
1
- Metadata-Version: 2.1
1
+ Metadata-Version: 2.2
2
2
  Name: hiddenlayer-sdk
3
- Version: 1.0.0
3
+ Version: 1.1.0
4
4
  Summary: Official HiddenLayer Python SDK
5
5
  Author-email: HiddenLayer Integrations Team <integrations@hiddenlayer.com>
6
6
  Maintainer-email: HiddenLayer Integrations Team <integrations@hiddenlayer.com>
@@ -1,11 +1,11 @@
1
1
  hiddenlayer/__init__.py,sha256=Uik1ha6cV_6MkpB0zpKn6f7Zsw7q6W_sh3MgGq2M3vU,3582
2
2
  hiddenlayer/sdk/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
3
- hiddenlayer/sdk/constants.py,sha256=517WH-MCaedeOK2yXDfJvjmuqWSpRFvuQzV6e22-3jg,283
3
+ hiddenlayer/sdk/constants.py,sha256=QwBZAQdF7FW9q4C-O8LyxrpqfJFBBlqRUDMjnJ-ouZQ,320
4
4
  hiddenlayer/sdk/exceptions.py,sha256=LNkD6AvSwNwQjnTDrvY152DmvPKzSejrBsIu-qI44Ec,225
5
- hiddenlayer/sdk/models.py,sha256=FxNn_D9vHWjQW2t79UWWwwLLfkkVqMWsaEgmVLWS02I,1835
5
+ hiddenlayer/sdk/models.py,sha256=T6GJTFCfBQgBteR0pl0eyYzan-iIFOSpcnlmlCuuQwc,1836
6
6
  hiddenlayer/sdk/utils.py,sha256=Ntao8hfsYuB7obZOanayIlrgJ98IWcPhs3sRi39IDkg,2997
7
- hiddenlayer/sdk/version.py,sha256=lzGFsymf0DtA_1oAZcPbeQ557iY-1BRkekhfA2qaFh8,18
8
- hiddenlayer/sdk/rest/__init__.py,sha256=5zmzsJXKVVfk-V6En3_0R0XjNu5HNESfM3Mtj7lgi24,7806
7
+ hiddenlayer/sdk/version.py,sha256=DFGnvNkISEu0RDsAfc03O0dRz9PfmIb63Kyi-am-trE,18
8
+ hiddenlayer/sdk/rest/__init__.py,sha256=Egcd1PM10KlYQww3y-HkVz0IqF3jnycvn5lYcE6uXVw,7809
9
9
  hiddenlayer/sdk/rest/api_client.py,sha256=Zd_yX0nQq06z0Ome2KcsNUcETnOxzhQK9js53qsN7aI,26333
10
10
  hiddenlayer/sdk/rest/api_response.py,sha256=eMxw1mpmJcoGZ3gs9z6jM4oYoZ10Gjk333s9sKxGv7s,652
11
11
  hiddenlayer/sdk/rest/configuration.py,sha256=0AzoYBOp3MzQvM9R3AkUWTycx1I3bcvNtn759JQ0fLo,14747
@@ -17,8 +17,8 @@ hiddenlayer/sdk/rest/api/health_api.py,sha256=oKHVksIqs_Vt_aQK-n9ZcQfbwW06pVeiYJ
17
17
  hiddenlayer/sdk/rest/api/model_scan_api.py,sha256=G32t9LzeDTCUF4QOMYYs3Vjm8bo0a2kZa3FXBAqPo6s,22047
18
18
  hiddenlayer/sdk/rest/api/model_supply_chain_api.py,sha256=kyay-8hob2E5HoGJPFQXYuffsZOKrg4yJ_S3wMuW030,116057
19
19
  hiddenlayer/sdk/rest/api/readiness_api.py,sha256=5SddYxvRA3GuwZ43DoVTRfPBeTkLXyBGbQtIdUyc2FA,10102
20
- hiddenlayer/sdk/rest/api/sensor_api.py,sha256=TKmqa5kuqCb1Ax_kIDkhoNCP3zMEOxPUxpilutn_Evg,87935
21
- hiddenlayer/sdk/rest/models/__init__.py,sha256=w7xG3tRuBAZDFB77NMjS5EwuIDnUYDLuELl13OmY9u8,6808
20
+ hiddenlayer/sdk/rest/api/sensor_api.py,sha256=yEvLUOVkpHAxsMZdoLQLWUW1TimlpKJ1bkRjJsGsAcU,87527
21
+ hiddenlayer/sdk/rest/models/__init__.py,sha256=-SO-mMt_gSxn-3hRXPeekUXEMe9hweu-ihepPrMNjXU,6811
22
22
  hiddenlayer/sdk/rest/models/address.py,sha256=amsl9GIcBhHswzfA8eQ0jbRw9zVEd6DmtDFSKRyQB9s,5285
23
23
  hiddenlayer/sdk/rest/models/artifact.py,sha256=FSV-aFgOpyZU3khHkbWXajenYLi_Zfn153cZTlz6TAI,8138
24
24
  hiddenlayer/sdk/rest/models/artifact_change.py,sha256=714PhIumUnwj1bBAtaFEFl78zoKbsiJfEGFQtkhFzgI,4136
@@ -37,8 +37,8 @@ hiddenlayer/sdk/rest/models/external_properties.py,sha256=_kr2izVVqjDaKAZYM9YljI
37
37
  hiddenlayer/sdk/rest/models/external_property_file_reference.py,sha256=CYWp1dkeTyONFxgyL1s9lgEIrL_WRLfCHu2uesTo0hM,3741
38
38
  hiddenlayer/sdk/rest/models/external_property_file_references.py,sha256=exYjkAMMKsWnj5PYAM9JvdrfnvoooeM1_-JKK0HEWtI,14776
39
39
  hiddenlayer/sdk/rest/models/file_details_v3.py,sha256=jnIDdpjngvEP29GTvVAbuAlonaDiIlsorpBKfsk8iH8,5419
40
- hiddenlayer/sdk/rest/models/file_results_inner.py,sha256=KpXwUU-7Gw4BLBTi7N9wLLwQk6F-MxZHuwcLMJhpvHk,4541
41
- hiddenlayer/sdk/rest/models/file_scan_report_v3.py,sha256=ppamPmZfb3KlugmYWQf8ukkFmQhutX54jyBzHVqaF1k,2991
40
+ hiddenlayer/sdk/rest/models/file_scan_report_v3.py,sha256=SiHmoz13npUwPGxsfWtPIFhuFSBJ__l7MqnOcuUjKX8,5178
41
+ hiddenlayer/sdk/rest/models/file_scan_reports_v3.py,sha256=eF39zwE-TQjbY0ChH28NyKlF285QqcTX5Hoiwk78FqE,2996
42
42
  hiddenlayer/sdk/rest/models/fix.py,sha256=IMGNyz-obFVq4xTNHxpwnlJhiSLI2ILg1XnmjrbqyFY,4397
43
43
  hiddenlayer/sdk/rest/models/get_multipart_upload_response.py,sha256=mSg6L4R_CoTNKtCNV2wDvCTk0dEkW8E6ChrRjBbdaDc,3049
44
44
  hiddenlayer/sdk/rest/models/graph.py,sha256=iMO4X58bcyPhrtMnnsVlRb2gbYtvkOoW8kLA7uwdQvM,4806
@@ -83,12 +83,12 @@ hiddenlayer/sdk/rest/models/scan_job_inventory.py,sha256=OV1KAy1czwndF7h-OZg4KYw
83
83
  hiddenlayer/sdk/rest/models/scan_model_details_v3.py,sha256=U63IEpPWJNnZfKoW4-G51m05iXjwoT8cXyP3Va-x3NI,3195
84
84
  hiddenlayer/sdk/rest/models/scan_model_ids_v3.py,sha256=FSJn2oVqEKd0YOF3xsKs1xnSgpYuVT5WBIEwAm5DcKY,2681
85
85
  hiddenlayer/sdk/rest/models/scan_model_request.py,sha256=vjIE1onx_OTS-wcpuFWcPpMe-wp9IU1fM7oWVJxBkEk,2451
86
- hiddenlayer/sdk/rest/models/scan_report_v3.py,sha256=3ArfJ_kOK-eYKKS_vgWnvTH0bQWg2ADTiYrbJ2eyeYE,5699
86
+ hiddenlayer/sdk/rest/models/scan_report_v3.py,sha256=C3dMv1ndMLGerBB1bWgYnG7cjS2BhucljsU8-Ne2YAA,5700
87
87
  hiddenlayer/sdk/rest/models/scan_results.py,sha256=02__33uy5wf_LMDoJfaSnNr2wMv4b59IcVq9F9suWUA,4031
88
88
  hiddenlayer/sdk/rest/models/scan_results_v2.py,sha256=-JCwgKrbjpAhye0uAQGq9rg2M6L6cHL3dqkoM_tmDnc,4494
89
89
  hiddenlayer/sdk/rest/models/security_posture.py,sha256=QJAJzaqrL1R69-jUkLX8Hpjz7-aCw99doUIAgPR6n7w,2619
90
90
  hiddenlayer/sdk/rest/models/sensor_sor_model_card_query_response.py,sha256=axRm4bobSm-VfsBS9qRLo5IBT07OXfej24lEY-u6z2s,3303
91
- hiddenlayer/sdk/rest/models/sensor_sor_model_card_response.py,sha256=_O1QiTzF-d1FjwCHtv-mIme7rI-W8G4apji5CJ3I1ss,4693
91
+ hiddenlayer/sdk/rest/models/sensor_sor_model_card_response.py,sha256=-tV9VWuN-bqOkOCuGcXT-QmKTqmeVe01jvEFt2Mmo0A,4694
92
92
  hiddenlayer/sdk/rest/models/sensor_sor_query_filter.py,sha256=t1ZdI4iwNk-mPjGX1j1oVCwrJ9qMAmEkMAxVkDE38yg,3406
93
93
  hiddenlayer/sdk/rest/models/sensor_sor_query_request.py,sha256=QdCmGShcIpQUVbFgLtzxtk9ucrmrwNfTLLwe78chuuY,3740
94
94
  hiddenlayer/sdk/rest/models/special_locations.py,sha256=FU5Y9nHrth5hixkeleSkxB3a9ZYALC4TI8BQXV4tWCw,3322
@@ -109,10 +109,10 @@ hiddenlayer/sdk/rest/models/web_request.py,sha256=0LKMRsAIg7oVOPso8DiaFgfsozpdKv
109
109
  hiddenlayer/sdk/rest/models/web_response.py,sha256=iwGQ5WjqAB4qGwe9nzGOwtxB1OSUc024pXSOaZM3Cdc,4746
110
110
  hiddenlayer/sdk/services/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
111
111
  hiddenlayer/sdk/services/aidr_predictive.py,sha256=aD2anFzWQzfLsR13NwwdQjt_X_iAlOkmss_yHy-154U,2958
112
- hiddenlayer/sdk/services/model.py,sha256=Lgx1_4I2u1aV6Az0yw1nFgi1q9-SYuVV9GXH2SycU-w,3180
113
- hiddenlayer/sdk/services/model_scan.py,sha256=FMwRwqHQ_VrrWyhl3OuDHNlcGGZWan1HnLtkVaxZNGg,17116
114
- hiddenlayer_sdk-1.0.0.dist-info/LICENSE,sha256=xx0jnfkXJvxRnG63LTGOxlggYnIysveWIZ6H3PNdCrQ,11357
115
- hiddenlayer_sdk-1.0.0.dist-info/METADATA,sha256=9k9M9WvNBngYYo6KiJiTEshS3VlMpa0kdqhybXo5iwE,17342
116
- hiddenlayer_sdk-1.0.0.dist-info/WHEEL,sha256=PZUExdf71Ui_so67QXpySuHtCi3-J3wvF4ORK6k_S8U,91
117
- hiddenlayer_sdk-1.0.0.dist-info/top_level.txt,sha256=8BxcmGvEN1RqsMvTWg9Q0vDmtBGcTmatnme6nzyPj2U,12
118
- hiddenlayer_sdk-1.0.0.dist-info/RECORD,,
112
+ hiddenlayer/sdk/services/model.py,sha256=qoVrwgL7E0raCUI0bNyim4SrmDEGBmcU1UaoJ-JNoCg,4871
113
+ hiddenlayer/sdk/services/model_scan.py,sha256=xGHveChHA6pHArSNF8YKXFOi0FqaH9BnzfuKC_6VyBY,17123
114
+ hiddenlayer_sdk-1.1.0.dist-info/LICENSE,sha256=xx0jnfkXJvxRnG63LTGOxlggYnIysveWIZ6H3PNdCrQ,11357
115
+ hiddenlayer_sdk-1.1.0.dist-info/METADATA,sha256=8M5hvwdG5HDkwRvIAiKDQJf3vSGCoex7itoWrd8baUk,17342
116
+ hiddenlayer_sdk-1.1.0.dist-info/WHEEL,sha256=In9FTNxeP60KnTkGw7wk6mJPYd_dQSjEZmXdBdMCI-8,91
117
+ hiddenlayer_sdk-1.1.0.dist-info/top_level.txt,sha256=8BxcmGvEN1RqsMvTWg9Q0vDmtBGcTmatnme6nzyPj2U,12
118
+ hiddenlayer_sdk-1.1.0.dist-info/RECORD,,
@@ -1,5 +1,5 @@
1
1
  Wheel-Version: 1.0
2
- Generator: setuptools (75.6.0)
2
+ Generator: setuptools (75.8.0)
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any
5
5
 
@@ -1,121 +0,0 @@
1
- # coding: utf-8
2
-
3
- """
4
- HiddenLayer ModelScan V2
5
-
6
- HiddenLayer ModelScan API for scanning of models
7
-
8
- The version of the OpenAPI document: 1
9
- Generated by OpenAPI Generator (https://openapi-generator.tech)
10
-
11
- Do not edit the class manually.
12
- """ # noqa: E501
13
-
14
-
15
- from __future__ import annotations
16
- import pprint
17
- import re # noqa: F401
18
- import json
19
-
20
- from datetime import datetime
21
- from pydantic import BaseModel, ConfigDict, Field, StrictStr, field_validator
22
- from typing import Any, ClassVar, Dict, List, Optional
23
- from hiddenlayer.sdk.rest.models.file_details_v3 import FileDetailsV3
24
- from hiddenlayer.sdk.rest.models.scan_detection_v3 import ScanDetectionV3
25
- from typing import Optional, Set
26
- from typing_extensions import Self
27
-
28
- class FileResultsInner(BaseModel):
29
- """
30
- FileResultsInner
31
- """ # noqa: E501
32
- file_instance_id: StrictStr = Field(description="unique ID of the file")
33
- file_location: StrictStr = Field(description="full file path")
34
- start_time: datetime = Field(description="time the scan started")
35
- end_time: datetime = Field(description="time the scan ended")
36
- details: FileDetailsV3
37
- status: StrictStr = Field(description="status of the scan")
38
- seen: datetime = Field(description="time the scan was seen at")
39
- detections: Optional[List[ScanDetectionV3]] = None
40
- __properties: ClassVar[List[str]] = ["file_instance_id", "file_location", "start_time", "end_time", "details", "status", "seen", "detections"]
41
-
42
- @field_validator('status')
43
- def status_validate_enum(cls, value):
44
- """Validates the enum"""
45
- if value not in set(['skipped', 'pending', 'running', 'done', 'failed', 'canceled']):
46
- raise ValueError("must be one of enum values ('skipped', 'pending', 'running', 'done', 'failed', 'canceled')")
47
- return value
48
-
49
- model_config = ConfigDict(
50
- populate_by_name=True,
51
- validate_assignment=True,
52
- protected_namespaces=(),
53
- )
54
-
55
-
56
- def to_str(self) -> str:
57
- """Returns the string representation of the model using alias"""
58
- return pprint.pformat(self.model_dump(by_alias=True))
59
-
60
- def to_json(self) -> str:
61
- """Returns the JSON representation of the model using alias"""
62
- # TODO: pydantic v2: use .model_dump_json(by_alias=True, exclude_unset=True) instead
63
- return json.dumps(self.to_dict())
64
-
65
- @classmethod
66
- def from_json(cls, json_str: str) -> Optional[Self]:
67
- """Create an instance of FileResultsInner from a JSON string"""
68
- return cls.from_dict(json.loads(json_str))
69
-
70
- def to_dict(self) -> Dict[str, Any]:
71
- """Return the dictionary representation of the model using alias.
72
-
73
- This has the following differences from calling pydantic's
74
- `self.model_dump(by_alias=True)`:
75
-
76
- * `None` is only added to the output dict for nullable fields that
77
- were set at model initialization. Other fields with value `None`
78
- are ignored.
79
- """
80
- excluded_fields: Set[str] = set([
81
- ])
82
-
83
- _dict = self.model_dump(
84
- by_alias=True,
85
- exclude=excluded_fields,
86
- exclude_none=True,
87
- )
88
- # override the default output from pydantic by calling `to_dict()` of details
89
- if self.details:
90
- _dict['details'] = self.details.to_dict()
91
- # override the default output from pydantic by calling `to_dict()` of each item in detections (list)
92
- _items = []
93
- if self.detections:
94
- for _item in self.detections:
95
- if _item:
96
- _items.append(_item.to_dict())
97
- _dict['detections'] = _items
98
- return _dict
99
-
100
- @classmethod
101
- def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]:
102
- """Create an instance of FileResultsInner from a dict"""
103
- if obj is None:
104
- return None
105
-
106
- if not isinstance(obj, dict):
107
- return cls.model_validate(obj)
108
-
109
- _obj = cls.model_validate({
110
- "file_instance_id": obj.get("file_instance_id"),
111
- "file_location": obj.get("file_location"),
112
- "start_time": obj.get("start_time"),
113
- "end_time": obj.get("end_time"),
114
- "details": FileDetailsV3.from_dict(obj["details"]) if obj.get("details") is not None else None,
115
- "status": obj.get("status"),
116
- "seen": obj.get("seen"),
117
- "detections": [ScanDetectionV3.from_dict(_item) for _item in obj["detections"]] if obj.get("detections") is not None else None
118
- })
119
- return _obj
120
-
121
-