wizata-dsapi 2.2.0.dev17__tar.gz → 2.2.0.dev19__tar.gz
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.
- {wizata_dsapi-2.2.0.dev17 → wizata_dsapi-2.2.0.dev19}/PKG-INFO +1 -1
- {wizata_dsapi-2.2.0.dev17 → wizata_dsapi-2.2.0.dev19}/wizata_dsapi/__init__.py +1 -0
- {wizata_dsapi-2.2.0.dev17 → wizata_dsapi-2.2.0.dev19}/wizata_dsapi/edge_device.py +80 -17
- wizata_dsapi-2.2.0.dev19/wizata_dsapi/edge_package.py +128 -0
- wizata_dsapi-2.2.0.dev19/wizata_dsapi/version.py +1 -0
- {wizata_dsapi-2.2.0.dev17 → wizata_dsapi-2.2.0.dev19}/wizata_dsapi/wizata_dsapi_client.py +20 -2
- {wizata_dsapi-2.2.0.dev17 → wizata_dsapi-2.2.0.dev19}/wizata_dsapi.egg-info/PKG-INFO +1 -1
- {wizata_dsapi-2.2.0.dev17 → wizata_dsapi-2.2.0.dev19}/wizata_dsapi.egg-info/SOURCES.txt +1 -0
- wizata_dsapi-2.2.0.dev17/wizata_dsapi/version.py +0 -1
- {wizata_dsapi-2.2.0.dev17 → wizata_dsapi-2.2.0.dev19}/LICENSE.txt +0 -0
- {wizata_dsapi-2.2.0.dev17 → wizata_dsapi-2.2.0.dev19}/README.rst +0 -0
- {wizata_dsapi-2.2.0.dev17 → wizata_dsapi-2.2.0.dev19}/setup.cfg +0 -0
- {wizata_dsapi-2.2.0.dev17 → wizata_dsapi-2.2.0.dev19}/setup.py +0 -0
- {wizata_dsapi-2.2.0.dev17 → wizata_dsapi-2.2.0.dev19}/wizata_dsapi/api_config.py +0 -0
- {wizata_dsapi-2.2.0.dev17 → wizata_dsapi-2.2.0.dev19}/wizata_dsapi/api_dto.py +0 -0
- {wizata_dsapi-2.2.0.dev17 → wizata_dsapi-2.2.0.dev19}/wizata_dsapi/api_interface.py +0 -0
- {wizata_dsapi-2.2.0.dev17 → wizata_dsapi-2.2.0.dev19}/wizata_dsapi/bucket.py +0 -0
- {wizata_dsapi-2.2.0.dev17 → wizata_dsapi-2.2.0.dev19}/wizata_dsapi/business_label.py +0 -0
- {wizata_dsapi-2.2.0.dev17 → wizata_dsapi-2.2.0.dev19}/wizata_dsapi/connection.py +0 -0
- {wizata_dsapi-2.2.0.dev17 → wizata_dsapi-2.2.0.dev19}/wizata_dsapi/connection_types.py +0 -0
- {wizata_dsapi-2.2.0.dev17 → wizata_dsapi-2.2.0.dev19}/wizata_dsapi/context.py +0 -0
- {wizata_dsapi-2.2.0.dev17 → wizata_dsapi-2.2.0.dev19}/wizata_dsapi/dashboard.py +0 -0
- {wizata_dsapi-2.2.0.dev17 → wizata_dsapi-2.2.0.dev19}/wizata_dsapi/dataframe_toolkit.py +0 -0
- {wizata_dsapi-2.2.0.dev17 → wizata_dsapi-2.2.0.dev19}/wizata_dsapi/datapoint.py +0 -0
- {wizata_dsapi-2.2.0.dev17 → wizata_dsapi-2.2.0.dev19}/wizata_dsapi/datastore.py +0 -0
- {wizata_dsapi-2.2.0.dev17 → wizata_dsapi-2.2.0.dev19}/wizata_dsapi/deployment.py +0 -0
- {wizata_dsapi-2.2.0.dev17 → wizata_dsapi-2.2.0.dev19}/wizata_dsapi/ds_dataframe.py +0 -0
- {wizata_dsapi-2.2.0.dev17 → wizata_dsapi-2.2.0.dev19}/wizata_dsapi/dsapi_json_encoder.py +0 -0
- {wizata_dsapi-2.2.0.dev17 → wizata_dsapi-2.2.0.dev19}/wizata_dsapi/edge_config.py +0 -0
- {wizata_dsapi-2.2.0.dev17 → wizata_dsapi-2.2.0.dev19}/wizata_dsapi/edge_module.py +0 -0
- {wizata_dsapi-2.2.0.dev17 → wizata_dsapi-2.2.0.dev19}/wizata_dsapi/evaluation.py +0 -0
- {wizata_dsapi-2.2.0.dev17 → wizata_dsapi-2.2.0.dev19}/wizata_dsapi/execution.py +0 -0
- {wizata_dsapi-2.2.0.dev17 → wizata_dsapi-2.2.0.dev19}/wizata_dsapi/execution_log.py +0 -0
- {wizata_dsapi-2.2.0.dev17 → wizata_dsapi-2.2.0.dev19}/wizata_dsapi/experiment.py +0 -0
- {wizata_dsapi-2.2.0.dev17 → wizata_dsapi-2.2.0.dev19}/wizata_dsapi/graylog_log.py +0 -0
- {wizata_dsapi-2.2.0.dev17 → wizata_dsapi-2.2.0.dev19}/wizata_dsapi/group_system.py +0 -0
- {wizata_dsapi-2.2.0.dev17 → wizata_dsapi-2.2.0.dev19}/wizata_dsapi/ilogger.py +0 -0
- {wizata_dsapi-2.2.0.dev17 → wizata_dsapi-2.2.0.dev19}/wizata_dsapi/insight.py +0 -0
- {wizata_dsapi-2.2.0.dev17 → wizata_dsapi-2.2.0.dev19}/wizata_dsapi/inventory.py +0 -0
- {wizata_dsapi-2.2.0.dev17 → wizata_dsapi-2.2.0.dev19}/wizata_dsapi/mlmodel.py +0 -0
- {wizata_dsapi-2.2.0.dev17 → wizata_dsapi-2.2.0.dev19}/wizata_dsapi/mobile_asset.py +0 -0
- {wizata_dsapi-2.2.0.dev17 → wizata_dsapi-2.2.0.dev19}/wizata_dsapi/model_toolkit.py +0 -0
- {wizata_dsapi-2.2.0.dev17 → wizata_dsapi-2.2.0.dev19}/wizata_dsapi/models/__init__.py +0 -0
- {wizata_dsapi-2.2.0.dev17 → wizata_dsapi-2.2.0.dev19}/wizata_dsapi/models/common.py +0 -0
- {wizata_dsapi-2.2.0.dev17 → wizata_dsapi-2.2.0.dev19}/wizata_dsapi/notification.py +0 -0
- {wizata_dsapi-2.2.0.dev17 → wizata_dsapi-2.2.0.dev19}/wizata_dsapi/paged_query_result.py +0 -0
- {wizata_dsapi-2.2.0.dev17 → wizata_dsapi-2.2.0.dev19}/wizata_dsapi/pipeline.py +0 -0
- {wizata_dsapi-2.2.0.dev17 → wizata_dsapi-2.2.0.dev19}/wizata_dsapi/pipeline_image.py +0 -0
- {wizata_dsapi-2.2.0.dev17 → wizata_dsapi-2.2.0.dev19}/wizata_dsapi/plot.py +0 -0
- {wizata_dsapi-2.2.0.dev17 → wizata_dsapi-2.2.0.dev19}/wizata_dsapi/plots/__init__.py +0 -0
- {wizata_dsapi-2.2.0.dev17 → wizata_dsapi-2.2.0.dev19}/wizata_dsapi/plots/common.py +0 -0
- {wizata_dsapi-2.2.0.dev17 → wizata_dsapi-2.2.0.dev19}/wizata_dsapi/plots/theme.py +0 -0
- {wizata_dsapi-2.2.0.dev17 → wizata_dsapi-2.2.0.dev19}/wizata_dsapi/product.py +0 -0
- {wizata_dsapi-2.2.0.dev17 → wizata_dsapi-2.2.0.dev19}/wizata_dsapi/request.py +0 -0
- {wizata_dsapi-2.2.0.dev17 → wizata_dsapi-2.2.0.dev19}/wizata_dsapi/script.py +0 -0
- {wizata_dsapi-2.2.0.dev17 → wizata_dsapi-2.2.0.dev19}/wizata_dsapi/scripts/__init__.py +0 -0
- {wizata_dsapi-2.2.0.dev17 → wizata_dsapi-2.2.0.dev19}/wizata_dsapi/scripts/common.py +0 -0
- {wizata_dsapi-2.2.0.dev17 → wizata_dsapi-2.2.0.dev19}/wizata_dsapi/search.py +0 -0
- {wizata_dsapi-2.2.0.dev17 → wizata_dsapi-2.2.0.dev19}/wizata_dsapi/solution_component.py +0 -0
- {wizata_dsapi-2.2.0.dev17 → wizata_dsapi-2.2.0.dev19}/wizata_dsapi/streamlit_utils.py +0 -0
- {wizata_dsapi-2.2.0.dev17 → wizata_dsapi-2.2.0.dev19}/wizata_dsapi/template.py +0 -0
- {wizata_dsapi-2.2.0.dev17 → wizata_dsapi-2.2.0.dev19}/wizata_dsapi/template_config.py +0 -0
- {wizata_dsapi-2.2.0.dev17 → wizata_dsapi-2.2.0.dev19}/wizata_dsapi/trigger.py +0 -0
- {wizata_dsapi-2.2.0.dev17 → wizata_dsapi-2.2.0.dev19}/wizata_dsapi/twin.py +0 -0
- {wizata_dsapi-2.2.0.dev17 → wizata_dsapi-2.2.0.dev19}/wizata_dsapi/twinregistration.py +0 -0
- {wizata_dsapi-2.2.0.dev17 → wizata_dsapi-2.2.0.dev19}/wizata_dsapi/user.py +0 -0
- {wizata_dsapi-2.2.0.dev17 → wizata_dsapi-2.2.0.dev19}/wizata_dsapi/wizard_function.py +0 -0
- {wizata_dsapi-2.2.0.dev17 → wizata_dsapi-2.2.0.dev19}/wizata_dsapi/wizard_request.py +0 -0
- {wizata_dsapi-2.2.0.dev17 → wizata_dsapi-2.2.0.dev19}/wizata_dsapi/words.py +0 -0
- {wizata_dsapi-2.2.0.dev17 → wizata_dsapi-2.2.0.dev19}/wizata_dsapi.egg-info/dependency_links.txt +0 -0
- {wizata_dsapi-2.2.0.dev17 → wizata_dsapi-2.2.0.dev19}/wizata_dsapi.egg-info/requires.txt +0 -0
- {wizata_dsapi-2.2.0.dev17 → wizata_dsapi-2.2.0.dev19}/wizata_dsapi.egg-info/top_level.txt +0 -0
|
@@ -61,6 +61,7 @@ from .notification import NotificationScope, DeviceToken, AlertRule, AlertActive
|
|
|
61
61
|
from .edge_device import EdgeDevice, EdgeDeviceStatus, EdgeDeviceType, EdgeDeviceProvisioning
|
|
62
62
|
from .edge_module import EdgeModule, EdgeModuleType, WIZATA_MODULES
|
|
63
63
|
from .edge_config import EdgeConsumer, EdgeWriter, EdgeTrigger, EdgeFile, EdgeConfig, EdgeCommand
|
|
64
|
+
from .edge_package import EdgePackage, EdgePackageOperation, EdgeRelease
|
|
64
65
|
from .connection import Connection, ConnectionMapping, ConnectionDirection, TransformKind, \
|
|
65
66
|
EdgeDeviceKey, EdgeDeviceKeyStatus
|
|
66
67
|
from .connection_types import ConnectionType, CONNECTION_TYPES, TRANSFORM_SCHEMAS, get_connection_type, \
|
|
@@ -9,6 +9,7 @@ class EdgeDeviceStatus(Enum):
|
|
|
9
9
|
"""
|
|
10
10
|
WAITING_FOR_REGISTRATION = "WaitingForRegistration"
|
|
11
11
|
REGISTERED = "Registered"
|
|
12
|
+
DEPLOYING = "Deploying"
|
|
12
13
|
DEPLOYED = "Deployed"
|
|
13
14
|
FAILED = "Failed"
|
|
14
15
|
OFFLINE = "Offline"
|
|
@@ -35,25 +36,41 @@ class EdgeDevice(ApiDto):
|
|
|
35
36
|
"""
|
|
36
37
|
Edge device registered on the platform.
|
|
37
38
|
|
|
38
|
-
|
|
39
|
-
|
|
39
|
+
The device id is its only identifier (DEV-6101): the name it runs as (its IoT Hub
|
|
40
|
+
device id), and what connections, keys and deployment targets refer to.
|
|
41
|
+
|
|
42
|
+
:ivar str device_id: the device identifier.
|
|
40
43
|
:ivar str name: display name of the edge device.
|
|
41
44
|
:ivar str twin_name: name of the associated twin.
|
|
42
45
|
:ivar uuid.UUID twin_id: technical id of the associated twin.
|
|
43
46
|
:ivar EdgeDeviceStatus status: current status of the device.
|
|
44
|
-
:ivar int status_code:
|
|
47
|
+
:ivar int status_code: last ``$edgeAgent`` ``lastDesiredStatus.code`` read (417, 200, 406...).
|
|
45
48
|
:ivar EdgeDeviceType device_type: type of the edge device.
|
|
46
49
|
:ivar EdgeDeviceProvisioning provisioning: how the device is installed.
|
|
47
50
|
:ivar int created_at: creation time, epoch ms (the PostgreSQL registry, DEV-6015).
|
|
48
51
|
:ivar int updated_at: last update time, epoch ms.
|
|
49
52
|
:ivar str connection_state: IoT Hub connection state ('Connected' or 'Disconnected'), enriched from IoT Hub.
|
|
50
53
|
:ivar str last_activity_time: last device activity timestamp from IoT Hub.
|
|
54
|
+
:ivar str applied_hash: digest of the manifest the platform last applied (DEV-6101).
|
|
55
|
+
:ivar int applied_version: ``$edgeAgent`` desired ``$version`` that apply produced.
|
|
56
|
+
:ivar int applied_at: when it was applied, epoch ms.
|
|
57
|
+
:ivar dict image_overrides: module -> image, winning over the release's images.
|
|
58
|
+
:ivar str runner_python_version: Python version of the edge's pipeline runner.
|
|
59
|
+
:ivar bool managed: the platform keeps this device's manifest ("deploy modules").
|
|
60
|
+
:ivar dict applied_modules: what was last applied: module -> {image, env names}.
|
|
61
|
+
:ivar str reconcile_error: why the last apply failed, until one succeeds.
|
|
62
|
+
:ivar int last_seen_at: last heartbeat of a manual edge, epoch ms (DEV-6109).
|
|
51
63
|
"""
|
|
52
64
|
|
|
53
65
|
@classmethod
|
|
54
66
|
def route(cls):
|
|
55
67
|
return "edgedevices"
|
|
56
68
|
|
|
69
|
+
@classmethod
|
|
70
|
+
def get_id_type(cls) -> type:
|
|
71
|
+
"""The device id (a string) is the edge's only identifier (DEV-6101)."""
|
|
72
|
+
return str
|
|
73
|
+
|
|
57
74
|
@classmethod
|
|
58
75
|
def from_dict(cls, data):
|
|
59
76
|
obj = EdgeDevice()
|
|
@@ -61,7 +78,6 @@ class EdgeDevice(ApiDto):
|
|
|
61
78
|
return obj
|
|
62
79
|
|
|
63
80
|
def __init__(self,
|
|
64
|
-
edge_device_id: uuid.UUID = None,
|
|
65
81
|
device_id: str = None,
|
|
66
82
|
name: str = None,
|
|
67
83
|
twin_name: str = None,
|
|
@@ -73,11 +89,16 @@ class EdgeDevice(ApiDto):
|
|
|
73
89
|
last_activity_time: str = None,
|
|
74
90
|
provisioning: EdgeDeviceProvisioning = None,
|
|
75
91
|
created_at: int = None,
|
|
76
|
-
updated_at: int = None
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
92
|
+
updated_at: int = None,
|
|
93
|
+
applied_hash: str = None,
|
|
94
|
+
applied_version: int = None,
|
|
95
|
+
applied_at: int = None,
|
|
96
|
+
image_overrides: dict = None,
|
|
97
|
+
runner_python_version: str = None,
|
|
98
|
+
managed: bool = None,
|
|
99
|
+
applied_modules: dict = None,
|
|
100
|
+
reconcile_error: str = None,
|
|
101
|
+
last_seen_at: int = None):
|
|
81
102
|
self.device_id = device_id
|
|
82
103
|
self.name = name
|
|
83
104
|
self.twin_name = twin_name
|
|
@@ -90,22 +111,29 @@ class EdgeDevice(ApiDto):
|
|
|
90
111
|
self.provisioning = provisioning
|
|
91
112
|
self.created_at = created_at
|
|
92
113
|
self.updated_at = updated_at
|
|
114
|
+
self.applied_hash = applied_hash
|
|
115
|
+
self.applied_version = applied_version
|
|
116
|
+
self.applied_at = applied_at
|
|
117
|
+
self.image_overrides = image_overrides
|
|
118
|
+
self.runner_python_version = runner_python_version
|
|
119
|
+
self.managed = managed
|
|
120
|
+
self.applied_modules = applied_modules
|
|
121
|
+
self.reconcile_error = reconcile_error
|
|
122
|
+
self.last_seen_at = last_seen_at
|
|
93
123
|
|
|
94
124
|
def api_id(self) -> str:
|
|
95
|
-
return
|
|
125
|
+
return self.device_id
|
|
96
126
|
|
|
97
127
|
def api_key(self) -> str:
|
|
98
128
|
return self.device_id
|
|
99
129
|
|
|
100
130
|
def set_id(self, id_value):
|
|
101
|
-
self.
|
|
131
|
+
self.device_id = str(id_value)
|
|
102
132
|
|
|
103
133
|
def endpoint(self) -> str:
|
|
104
134
|
return "EdgeDevices"
|
|
105
135
|
|
|
106
136
|
def from_json(self, obj):
|
|
107
|
-
if "id" in obj and obj["id"] is not None:
|
|
108
|
-
self.edge_device_id = uuid.UUID(obj["id"])
|
|
109
137
|
if "deviceId" in obj and obj["deviceId"] is not None:
|
|
110
138
|
self.device_id = obj["deviceId"]
|
|
111
139
|
if "name" in obj and obj["name"] is not None:
|
|
@@ -130,11 +158,29 @@ class EdgeDevice(ApiDto):
|
|
|
130
158
|
self.created_at = int(obj["createdAt"])
|
|
131
159
|
if "updatedAt" in obj and obj["updatedAt"] is not None:
|
|
132
160
|
self.updated_at = int(obj["updatedAt"])
|
|
161
|
+
if "appliedHash" in obj and obj["appliedHash"] is not None:
|
|
162
|
+
self.applied_hash = obj["appliedHash"]
|
|
163
|
+
if "appliedVersion" in obj and obj["appliedVersion"] is not None:
|
|
164
|
+
self.applied_version = int(obj["appliedVersion"])
|
|
165
|
+
if "appliedAt" in obj and obj["appliedAt"] is not None:
|
|
166
|
+
self.applied_at = int(obj["appliedAt"])
|
|
167
|
+
if "imageOverrides" in obj and obj["imageOverrides"] is not None:
|
|
168
|
+
if not isinstance(obj["imageOverrides"], dict):
|
|
169
|
+
raise ValueError("imageOverrides must be an object: module -> image")
|
|
170
|
+
self.image_overrides = dict(obj["imageOverrides"])
|
|
171
|
+
if "runnerPythonVersion" in obj and obj["runnerPythonVersion"] is not None:
|
|
172
|
+
self.runner_python_version = str(obj["runnerPythonVersion"])
|
|
173
|
+
if "managed" in obj and obj["managed"] is not None:
|
|
174
|
+
self.managed = bool(obj["managed"])
|
|
175
|
+
if "appliedModules" in obj and obj["appliedModules"] is not None:
|
|
176
|
+
self.applied_modules = obj["appliedModules"]
|
|
177
|
+
if "reconcileError" in obj and obj["reconcileError"] is not None:
|
|
178
|
+
self.reconcile_error = obj["reconcileError"]
|
|
179
|
+
if "lastSeenAt" in obj and obj["lastSeenAt"] is not None:
|
|
180
|
+
self.last_seen_at = int(obj["lastSeenAt"])
|
|
133
181
|
|
|
134
182
|
def to_json(self, target: str = None):
|
|
135
|
-
obj = {
|
|
136
|
-
"id": str(self.edge_device_id)
|
|
137
|
-
}
|
|
183
|
+
obj = {}
|
|
138
184
|
if self.device_id is not None:
|
|
139
185
|
obj["deviceId"] = self.device_id
|
|
140
186
|
if self.name is not None:
|
|
@@ -159,4 +205,21 @@ class EdgeDevice(ApiDto):
|
|
|
159
205
|
obj["createdAt"] = self.created_at
|
|
160
206
|
if self.updated_at is not None:
|
|
161
207
|
obj["updatedAt"] = self.updated_at
|
|
162
|
-
|
|
208
|
+
if self.applied_hash is not None:
|
|
209
|
+
obj["appliedHash"] = self.applied_hash
|
|
210
|
+
if self.applied_version is not None:
|
|
211
|
+
obj["appliedVersion"] = self.applied_version
|
|
212
|
+
if self.applied_at is not None:
|
|
213
|
+
obj["appliedAt"] = self.applied_at
|
|
214
|
+
if self.image_overrides is not None:
|
|
215
|
+
obj["imageOverrides"] = self.image_overrides
|
|
216
|
+
if self.runner_python_version is not None:
|
|
217
|
+
obj["runnerPythonVersion"] = self.runner_python_version
|
|
218
|
+
obj["managed"] = bool(self.managed)
|
|
219
|
+
if self.applied_modules is not None:
|
|
220
|
+
obj["appliedModules"] = self.applied_modules
|
|
221
|
+
if self.reconcile_error is not None:
|
|
222
|
+
obj["reconcileError"] = self.reconcile_error
|
|
223
|
+
if self.last_seen_at is not None:
|
|
224
|
+
obj["lastSeenAt"] = self.last_seen_at
|
|
225
|
+
return obj
|
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
from enum import Enum
|
|
2
|
+
|
|
3
|
+
from .api_dto import Dto
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
class EdgePackageOperation(Enum):
|
|
7
|
+
"""
|
|
8
|
+
What a package for a manual edge does (DEV-6109). A manual edge serves a validated
|
|
9
|
+
(21 CFR Part 11) site: the platform never changes it, the site's operator runs each
|
|
10
|
+
package as a procedure.
|
|
11
|
+
|
|
12
|
+
- ``pipeline``: the pipelines it runs — triggers.json and the pipeline images;
|
|
13
|
+
- ``platform``: the platform version — docker-compose.yml, the module settings and
|
|
14
|
+
the profile files of a release;
|
|
15
|
+
- ``full``: everything, for the first install or any other change (connections,
|
|
16
|
+
writers, functions).
|
|
17
|
+
"""
|
|
18
|
+
PIPELINE = "pipeline"
|
|
19
|
+
PLATFORM = "platform"
|
|
20
|
+
FULL = "full"
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
class EdgeRelease(Dto):
|
|
24
|
+
"""
|
|
25
|
+
The edge images of a release, as Wizata.Jobs publishes them (DEV-6109).
|
|
26
|
+
|
|
27
|
+
``edge_images.json`` in Wizata.Jobs stays where they are pinned. The Jobs consumer
|
|
28
|
+
writes them here at its start, so the DS API can compose a manual edge's platform
|
|
29
|
+
package with the images the environment runs.
|
|
30
|
+
|
|
31
|
+
:ivar str id: digest of the images: the same images are the same release.
|
|
32
|
+
:ivar str version: what published them, e.g. ``wizata-packages 2.2.0``.
|
|
33
|
+
:ivar dict images: module -> image; ``pipeline_runner`` maps a Python version to one.
|
|
34
|
+
:ivar int published_at: when last published, epoch ms.
|
|
35
|
+
"""
|
|
36
|
+
|
|
37
|
+
def __init__(self, id=None, version=None, images=None, published_at=None):
|
|
38
|
+
self.id = id
|
|
39
|
+
self.version = version
|
|
40
|
+
self.images = images
|
|
41
|
+
self.published_at = published_at
|
|
42
|
+
|
|
43
|
+
@classmethod
|
|
44
|
+
def from_dict(cls, data: dict) -> "EdgeRelease":
|
|
45
|
+
return cls(id=data.get("id"), version=data.get("version"), images=data.get("images"),
|
|
46
|
+
published_at=data.get("publishedAt"))
|
|
47
|
+
|
|
48
|
+
def to_dict(self) -> dict:
|
|
49
|
+
return {"id": self.id, "version": self.version, "images": self.images,
|
|
50
|
+
"publishedAt": self.published_at}
|
|
51
|
+
|
|
52
|
+
|
|
53
|
+
class EdgePackage(Dto):
|
|
54
|
+
"""
|
|
55
|
+
A procedure composed for a manual edge, and its record (DEV-6109): what it contains,
|
|
56
|
+
who generated and downloaded it, and when the edge reported it applied.
|
|
57
|
+
|
|
58
|
+
The package itself holds secrets (the module settings) and is never stored: it is
|
|
59
|
+
rendered again at each download, and refused if its contents changed since it was
|
|
60
|
+
generated. The record holds names and digests only.
|
|
61
|
+
|
|
62
|
+
:ivar str id: package id (UUID). The edge reports it once installed.
|
|
63
|
+
:ivar str edge_device_id: the device it is for.
|
|
64
|
+
:ivar EdgePackageOperation operation: pipeline, platform or full.
|
|
65
|
+
:ivar int sequence: 1, 2, 3... per device.
|
|
66
|
+
:ivar str release_id: the ``EdgeRelease`` its module images come from (platform, full).
|
|
67
|
+
:ivar str contents_hash: digest of the contents, secrets excluded.
|
|
68
|
+
:ivar dict contents: ``files`` (path -> sha256), ``settings`` (module -> variable
|
|
69
|
+
names), ``modules`` (module -> image), ``images`` (pipeline image ids),
|
|
70
|
+
``warnings``.
|
|
71
|
+
:ivar dict diff: against what the edge runs (its applied packages): added, changed
|
|
72
|
+
and removed files, pipeline images, module images.
|
|
73
|
+
:ivar list procedure: the steps, each ``{"title", "command"}``.
|
|
74
|
+
:ivar str generated_by: who generated it.
|
|
75
|
+
:ivar int generated_at: epoch ms.
|
|
76
|
+
:ivar list downloads: each ``{"by", "at"}``.
|
|
77
|
+
:ivar int applied_at: when it was first reported installed, epoch ms.
|
|
78
|
+
:ivar str applied_by: ``edge`` (its heartbeat), or the admin who confirmed it for an
|
|
79
|
+
edge that cannot reach the platform.
|
|
80
|
+
"""
|
|
81
|
+
|
|
82
|
+
def __init__(self, id=None, edge_device_id=None, operation=None, sequence=None,
|
|
83
|
+
release_id=None, contents_hash=None, contents=None, diff=None, procedure=None,
|
|
84
|
+
generated_by=None, generated_at=None, downloads=None, applied_at=None,
|
|
85
|
+
applied_by=None):
|
|
86
|
+
self.id = id
|
|
87
|
+
self.edge_device_id = edge_device_id
|
|
88
|
+
self.operation = operation
|
|
89
|
+
self.sequence = sequence
|
|
90
|
+
self.release_id = release_id
|
|
91
|
+
self.contents_hash = contents_hash
|
|
92
|
+
self.contents = contents
|
|
93
|
+
self.diff = diff
|
|
94
|
+
self.procedure = procedure
|
|
95
|
+
self.generated_by = generated_by
|
|
96
|
+
self.generated_at = generated_at
|
|
97
|
+
self.downloads = downloads
|
|
98
|
+
self.applied_at = applied_at
|
|
99
|
+
self.applied_by = applied_by
|
|
100
|
+
|
|
101
|
+
@classmethod
|
|
102
|
+
def from_dict(cls, data: dict) -> "EdgePackage":
|
|
103
|
+
operation = data.get("operation")
|
|
104
|
+
return cls(id=data.get("id"), edge_device_id=data.get("edgeDeviceId"),
|
|
105
|
+
operation=EdgePackageOperation(operation) if operation else None,
|
|
106
|
+
sequence=data.get("sequence"), release_id=data.get("releaseId"),
|
|
107
|
+
contents_hash=data.get("contentsHash"), contents=data.get("contents"),
|
|
108
|
+
diff=data.get("diff"), procedure=data.get("procedure"),
|
|
109
|
+
generated_by=data.get("generatedBy"), generated_at=data.get("generatedAt"),
|
|
110
|
+
downloads=data.get("downloads"), applied_at=data.get("appliedAt"),
|
|
111
|
+
applied_by=data.get("appliedBy"))
|
|
112
|
+
|
|
113
|
+
def to_dict(self) -> dict:
|
|
114
|
+
return {"id": self.id, "edgeDeviceId": self.edge_device_id,
|
|
115
|
+
"operation": self.operation.value if self.operation else None,
|
|
116
|
+
"sequence": self.sequence, "releaseId": self.release_id,
|
|
117
|
+
"contentsHash": self.contents_hash, "contents": self.contents,
|
|
118
|
+
"diff": self.diff, "procedure": self.procedure,
|
|
119
|
+
"generatedBy": self.generated_by, "generatedAt": self.generated_at,
|
|
120
|
+
"downloads": self.downloads or [], "appliedAt": self.applied_at,
|
|
121
|
+
"appliedBy": self.applied_by}
|
|
122
|
+
|
|
123
|
+
def marker(self) -> dict:
|
|
124
|
+
"""What the package installs as ``conf/_packages/<id>.json`` and the edge reports."""
|
|
125
|
+
return {"id": self.id, "edgeDeviceId": self.edge_device_id,
|
|
126
|
+
"operation": self.operation.value if self.operation else None,
|
|
127
|
+
"sequence": self.sequence, "releaseId": self.release_id,
|
|
128
|
+
"contentsHash": self.contents_hash}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
__version__ = "2.2.0.dev19"
|
|
@@ -446,7 +446,7 @@ class WizataDSAPIClient(ApiInterface, ApiDtoInterface):
|
|
|
446
446
|
return self._query(request=obj)
|
|
447
447
|
else:
|
|
448
448
|
dto_class = self._get_class(entity=type(obj), operation=operation)
|
|
449
|
-
if dto_class == PipelineImage:
|
|
449
|
+
if dto_class == PipelineImage or dto_class.get_id_type() == str:
|
|
450
450
|
id = obj.api_id()
|
|
451
451
|
else:
|
|
452
452
|
id = uuid.UUID(obj.api_id())
|
|
@@ -582,6 +582,8 @@ class WizataDSAPIClient(ApiInterface, ApiDtoInterface):
|
|
|
582
582
|
if dto_class.get_id_type() == int:
|
|
583
583
|
obj.set_id(response.json()["id"])
|
|
584
584
|
return response.json()["id"]
|
|
585
|
+
elif dto_class.get_id_type() == str:
|
|
586
|
+
return obj.api_id()
|
|
585
587
|
else:
|
|
586
588
|
return uuid.UUID(obj.api_id())
|
|
587
589
|
|
|
@@ -3002,13 +3004,14 @@ class WizataDSAPIClient(ApiInterface, ApiDtoInterface):
|
|
|
3002
3004
|
return "edge/" + "/".join(quoted)
|
|
3003
3005
|
|
|
3004
3006
|
def _edge_request(self, method: str, route: str, body=None, headers=None,
|
|
3005
|
-
expected=(200,), stream=False):
|
|
3007
|
+
expected=(200,), stream=False, timeout=None):
|
|
3006
3008
|
response = requests.request(
|
|
3007
3009
|
method,
|
|
3008
3010
|
self.__url() + route,
|
|
3009
3011
|
headers={**self.__header(), **(headers or {})},
|
|
3010
3012
|
data=json.dumps(body) if body is not None else None,
|
|
3011
3013
|
stream=stream,
|
|
3014
|
+
timeout=timeout,
|
|
3012
3015
|
)
|
|
3013
3016
|
if response.status_code not in expected:
|
|
3014
3017
|
raise self.__raise_error(response)
|
|
@@ -3078,6 +3081,21 @@ class WizataDSAPIClient(ApiInterface, ApiDtoInterface):
|
|
|
3078
3081
|
os.remove(temporary)
|
|
3079
3082
|
return path
|
|
3080
3083
|
|
|
3084
|
+
def send_edge_heartbeat(self, edge_device_id: str, packages: list = None,
|
|
3085
|
+
timeout=(5, 15)) -> dict:
|
|
3086
|
+
"""
|
|
3087
|
+
A manual edge's heartbeat (DEV-6109): it is alive, and these packages (the ids in
|
|
3088
|
+
its ``conf/_packages``) are installed. The platform records when it was seen, and
|
|
3089
|
+
each package as installed the first time it is listed.
|
|
3090
|
+
|
|
3091
|
+
:param timeout: (connect, read) seconds — a site that blocks outbound traffic must
|
|
3092
|
+
not hold the caller.
|
|
3093
|
+
:return: ``{"lastSeenAt", "applied": [ids newly recorded], "unknown": [ids]}``.
|
|
3094
|
+
"""
|
|
3095
|
+
response = self._edge_request("POST", self._edge_route(edge_device_id, "heartbeat"),
|
|
3096
|
+
body={"packages": list(packages or [])}, timeout=timeout)
|
|
3097
|
+
return response.json()
|
|
3098
|
+
|
|
3081
3099
|
|
|
3082
3100
|
def api() -> WizataDSAPIClient:
|
|
3083
3101
|
"""
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
__version__ = "2.2.0.dev17"
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{wizata_dsapi-2.2.0.dev17 → wizata_dsapi-2.2.0.dev19}/wizata_dsapi.egg-info/dependency_links.txt
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|