/
_build_scan.py
106 lines (74 loc) · 2.78 KB
/
_build_scan.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
# -*- coding: utf-8 -*-
from datetime import datetime
from enum import Enum
from typing import Optional
from verta._internal_utils import _utils, time_utils
class ScanProgressEnum(str, Enum):
"""The current progress of a build scan.
For all intents and purposes, this can be treated as a :class:`str`.
Examples
--------
.. code-block:: python
assert build.get_scan().progress == "scanned"
"""
UNSCANNED = "unscanned"
SCANNING = "scanning"
SCANNED = "scanned"
ERROR = "error"
class ScanResultEnum(str, Enum):
"""The result of a build scan.
For all intents and purposes, this can be treated as a :class:`str`.
Examples
--------
.. code-block:: python
assert build.get_scan().result == "safe"
"""
UNKNOWN = "unknown"
SAFE = "safe"
UNSAFE = "unsafe"
class BuildScan:
"""A scan of a Verta model build.
There should not be a need to instantiate this class directly; please use
:meth:`Build.get_scan() <verta.endpoint.build.Build.get_scan>` instead.
Attributes
----------
date_updated : timezone-aware :class:`~datetime.datetime`
The date and time when this scan was performed/updated.
progress : :class:`ScanProgressEnum`
The current progress of this scan.
result : :class:`ScanResultEnum` or None
The result of this scan. ``None`` is returned if this scan is not yet
finished, and therefore has no result.
passed : bool
Whether this scan finished and passed. This property is for
convenience, equivalent to
.. code-block:: python
(build_scan.progress == "scanned") and (build_scan.result == "safe")
"""
def __init__(self, json):
self._json = json
def __repr__(self):
detail_str = f'progress "{self.progress.value}"'
if self.result is not None:
detail_str += f', result "{self.result.value}"'
return f"<BuildScan ({detail_str})>"
@classmethod
def _get(cls, conn: _utils.Connection, build_id: int):
url = f"{conn.scheme}://{conn.socket}/api/v1/deployment/builds/{build_id}/scan"
response = _utils.make_request("GET", url, conn)
_utils.raise_for_http_error(response)
return cls(response.json())
@property
def date_updated(self) -> datetime:
return time_utils.datetime_from_iso(self._json["date_updated"])
@property
def progress(self) -> ScanProgressEnum:
return ScanProgressEnum(self._json["scan_status"])
@property
def result(self) -> Optional[ScanResultEnum]:
if self.progress != ScanProgressEnum.SCANNED:
return None
return ScanResultEnum(self._json["safety_status"])
@property
def passed(self) -> bool:
return self.result == ScanResultEnum.SAFE