wizata-dsapi 2.2.0.dev18__tar.gz → 2.2.0.dev20__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.
Files changed (73) hide show
  1. {wizata_dsapi-2.2.0.dev18 → wizata_dsapi-2.2.0.dev20}/PKG-INFO +1 -1
  2. {wizata_dsapi-2.2.0.dev18 → wizata_dsapi-2.2.0.dev20}/wizata_dsapi/__init__.py +5 -1
  3. {wizata_dsapi-2.2.0.dev18 → wizata_dsapi-2.2.0.dev20}/wizata_dsapi/edge_device.py +8 -1
  4. wizata_dsapi-2.2.0.dev20/wizata_dsapi/edge_package.py +128 -0
  5. wizata_dsapi-2.2.0.dev20/wizata_dsapi/formula.py +493 -0
  6. {wizata_dsapi-2.2.0.dev18 → wizata_dsapi-2.2.0.dev20}/wizata_dsapi/pipeline.py +70 -0
  7. {wizata_dsapi-2.2.0.dev18 → wizata_dsapi-2.2.0.dev20}/wizata_dsapi/request.py +12 -1
  8. {wizata_dsapi-2.2.0.dev18 → wizata_dsapi-2.2.0.dev20}/wizata_dsapi/scripts/common.py +26 -56
  9. wizata_dsapi-2.2.0.dev20/wizata_dsapi/version.py +1 -0
  10. {wizata_dsapi-2.2.0.dev18 → wizata_dsapi-2.2.0.dev20}/wizata_dsapi/wizata_dsapi_client.py +28 -4
  11. {wizata_dsapi-2.2.0.dev18 → wizata_dsapi-2.2.0.dev20}/wizata_dsapi.egg-info/PKG-INFO +1 -1
  12. {wizata_dsapi-2.2.0.dev18 → wizata_dsapi-2.2.0.dev20}/wizata_dsapi.egg-info/SOURCES.txt +2 -0
  13. wizata_dsapi-2.2.0.dev18/wizata_dsapi/version.py +0 -1
  14. {wizata_dsapi-2.2.0.dev18 → wizata_dsapi-2.2.0.dev20}/LICENSE.txt +0 -0
  15. {wizata_dsapi-2.2.0.dev18 → wizata_dsapi-2.2.0.dev20}/README.rst +0 -0
  16. {wizata_dsapi-2.2.0.dev18 → wizata_dsapi-2.2.0.dev20}/setup.cfg +0 -0
  17. {wizata_dsapi-2.2.0.dev18 → wizata_dsapi-2.2.0.dev20}/setup.py +0 -0
  18. {wizata_dsapi-2.2.0.dev18 → wizata_dsapi-2.2.0.dev20}/wizata_dsapi/api_config.py +0 -0
  19. {wizata_dsapi-2.2.0.dev18 → wizata_dsapi-2.2.0.dev20}/wizata_dsapi/api_dto.py +0 -0
  20. {wizata_dsapi-2.2.0.dev18 → wizata_dsapi-2.2.0.dev20}/wizata_dsapi/api_interface.py +0 -0
  21. {wizata_dsapi-2.2.0.dev18 → wizata_dsapi-2.2.0.dev20}/wizata_dsapi/bucket.py +0 -0
  22. {wizata_dsapi-2.2.0.dev18 → wizata_dsapi-2.2.0.dev20}/wizata_dsapi/business_label.py +0 -0
  23. {wizata_dsapi-2.2.0.dev18 → wizata_dsapi-2.2.0.dev20}/wizata_dsapi/connection.py +0 -0
  24. {wizata_dsapi-2.2.0.dev18 → wizata_dsapi-2.2.0.dev20}/wizata_dsapi/connection_types.py +0 -0
  25. {wizata_dsapi-2.2.0.dev18 → wizata_dsapi-2.2.0.dev20}/wizata_dsapi/context.py +0 -0
  26. {wizata_dsapi-2.2.0.dev18 → wizata_dsapi-2.2.0.dev20}/wizata_dsapi/dashboard.py +0 -0
  27. {wizata_dsapi-2.2.0.dev18 → wizata_dsapi-2.2.0.dev20}/wizata_dsapi/dataframe_toolkit.py +0 -0
  28. {wizata_dsapi-2.2.0.dev18 → wizata_dsapi-2.2.0.dev20}/wizata_dsapi/datapoint.py +0 -0
  29. {wizata_dsapi-2.2.0.dev18 → wizata_dsapi-2.2.0.dev20}/wizata_dsapi/datastore.py +0 -0
  30. {wizata_dsapi-2.2.0.dev18 → wizata_dsapi-2.2.0.dev20}/wizata_dsapi/deployment.py +0 -0
  31. {wizata_dsapi-2.2.0.dev18 → wizata_dsapi-2.2.0.dev20}/wizata_dsapi/ds_dataframe.py +0 -0
  32. {wizata_dsapi-2.2.0.dev18 → wizata_dsapi-2.2.0.dev20}/wizata_dsapi/dsapi_json_encoder.py +0 -0
  33. {wizata_dsapi-2.2.0.dev18 → wizata_dsapi-2.2.0.dev20}/wizata_dsapi/edge_config.py +0 -0
  34. {wizata_dsapi-2.2.0.dev18 → wizata_dsapi-2.2.0.dev20}/wizata_dsapi/edge_module.py +0 -0
  35. {wizata_dsapi-2.2.0.dev18 → wizata_dsapi-2.2.0.dev20}/wizata_dsapi/evaluation.py +0 -0
  36. {wizata_dsapi-2.2.0.dev18 → wizata_dsapi-2.2.0.dev20}/wizata_dsapi/execution.py +0 -0
  37. {wizata_dsapi-2.2.0.dev18 → wizata_dsapi-2.2.0.dev20}/wizata_dsapi/execution_log.py +0 -0
  38. {wizata_dsapi-2.2.0.dev18 → wizata_dsapi-2.2.0.dev20}/wizata_dsapi/experiment.py +0 -0
  39. {wizata_dsapi-2.2.0.dev18 → wizata_dsapi-2.2.0.dev20}/wizata_dsapi/graylog_log.py +0 -0
  40. {wizata_dsapi-2.2.0.dev18 → wizata_dsapi-2.2.0.dev20}/wizata_dsapi/group_system.py +0 -0
  41. {wizata_dsapi-2.2.0.dev18 → wizata_dsapi-2.2.0.dev20}/wizata_dsapi/ilogger.py +0 -0
  42. {wizata_dsapi-2.2.0.dev18 → wizata_dsapi-2.2.0.dev20}/wizata_dsapi/insight.py +0 -0
  43. {wizata_dsapi-2.2.0.dev18 → wizata_dsapi-2.2.0.dev20}/wizata_dsapi/inventory.py +0 -0
  44. {wizata_dsapi-2.2.0.dev18 → wizata_dsapi-2.2.0.dev20}/wizata_dsapi/mlmodel.py +0 -0
  45. {wizata_dsapi-2.2.0.dev18 → wizata_dsapi-2.2.0.dev20}/wizata_dsapi/mobile_asset.py +0 -0
  46. {wizata_dsapi-2.2.0.dev18 → wizata_dsapi-2.2.0.dev20}/wizata_dsapi/model_toolkit.py +0 -0
  47. {wizata_dsapi-2.2.0.dev18 → wizata_dsapi-2.2.0.dev20}/wizata_dsapi/models/__init__.py +0 -0
  48. {wizata_dsapi-2.2.0.dev18 → wizata_dsapi-2.2.0.dev20}/wizata_dsapi/models/common.py +0 -0
  49. {wizata_dsapi-2.2.0.dev18 → wizata_dsapi-2.2.0.dev20}/wizata_dsapi/notification.py +0 -0
  50. {wizata_dsapi-2.2.0.dev18 → wizata_dsapi-2.2.0.dev20}/wizata_dsapi/paged_query_result.py +0 -0
  51. {wizata_dsapi-2.2.0.dev18 → wizata_dsapi-2.2.0.dev20}/wizata_dsapi/pipeline_image.py +0 -0
  52. {wizata_dsapi-2.2.0.dev18 → wizata_dsapi-2.2.0.dev20}/wizata_dsapi/plot.py +0 -0
  53. {wizata_dsapi-2.2.0.dev18 → wizata_dsapi-2.2.0.dev20}/wizata_dsapi/plots/__init__.py +0 -0
  54. {wizata_dsapi-2.2.0.dev18 → wizata_dsapi-2.2.0.dev20}/wizata_dsapi/plots/common.py +0 -0
  55. {wizata_dsapi-2.2.0.dev18 → wizata_dsapi-2.2.0.dev20}/wizata_dsapi/plots/theme.py +0 -0
  56. {wizata_dsapi-2.2.0.dev18 → wizata_dsapi-2.2.0.dev20}/wizata_dsapi/product.py +0 -0
  57. {wizata_dsapi-2.2.0.dev18 → wizata_dsapi-2.2.0.dev20}/wizata_dsapi/script.py +0 -0
  58. {wizata_dsapi-2.2.0.dev18 → wizata_dsapi-2.2.0.dev20}/wizata_dsapi/scripts/__init__.py +0 -0
  59. {wizata_dsapi-2.2.0.dev18 → wizata_dsapi-2.2.0.dev20}/wizata_dsapi/search.py +0 -0
  60. {wizata_dsapi-2.2.0.dev18 → wizata_dsapi-2.2.0.dev20}/wizata_dsapi/solution_component.py +0 -0
  61. {wizata_dsapi-2.2.0.dev18 → wizata_dsapi-2.2.0.dev20}/wizata_dsapi/streamlit_utils.py +0 -0
  62. {wizata_dsapi-2.2.0.dev18 → wizata_dsapi-2.2.0.dev20}/wizata_dsapi/template.py +0 -0
  63. {wizata_dsapi-2.2.0.dev18 → wizata_dsapi-2.2.0.dev20}/wizata_dsapi/template_config.py +0 -0
  64. {wizata_dsapi-2.2.0.dev18 → wizata_dsapi-2.2.0.dev20}/wizata_dsapi/trigger.py +0 -0
  65. {wizata_dsapi-2.2.0.dev18 → wizata_dsapi-2.2.0.dev20}/wizata_dsapi/twin.py +0 -0
  66. {wizata_dsapi-2.2.0.dev18 → wizata_dsapi-2.2.0.dev20}/wizata_dsapi/twinregistration.py +0 -0
  67. {wizata_dsapi-2.2.0.dev18 → wizata_dsapi-2.2.0.dev20}/wizata_dsapi/user.py +0 -0
  68. {wizata_dsapi-2.2.0.dev18 → wizata_dsapi-2.2.0.dev20}/wizata_dsapi/wizard_function.py +0 -0
  69. {wizata_dsapi-2.2.0.dev18 → wizata_dsapi-2.2.0.dev20}/wizata_dsapi/wizard_request.py +0 -0
  70. {wizata_dsapi-2.2.0.dev18 → wizata_dsapi-2.2.0.dev20}/wizata_dsapi/words.py +0 -0
  71. {wizata_dsapi-2.2.0.dev18 → wizata_dsapi-2.2.0.dev20}/wizata_dsapi.egg-info/dependency_links.txt +0 -0
  72. {wizata_dsapi-2.2.0.dev18 → wizata_dsapi-2.2.0.dev20}/wizata_dsapi.egg-info/requires.txt +0 -0
  73. {wizata_dsapi-2.2.0.dev18 → wizata_dsapi-2.2.0.dev20}/wizata_dsapi.egg-info/top_level.txt +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: wizata_dsapi
3
- Version: 2.2.0.dev18
3
+ Version: 2.2.0.dev20
4
4
  Summary: Wizata Data Science Toolkit
5
5
  Author: Wizata S.A.
6
6
  Author-email: info@wizata.com
@@ -5,6 +5,8 @@ from .paged_query_result import PagedQueryResult
5
5
  from .plot import Plot
6
6
  from .mlmodel import ModelInfo, ModelList, MLModelConfig, ModelFile, ModelIdentifierInfo
7
7
  from .request import Request, filter_map, RequestGroup, RequestGroupMap, DynamicSelector
8
+ from .formula import (FormulaError, apply_formulas, evaluate_formula, normalize_formulas, check_result_name,
9
+ formula_catalog, FORMULA_OPERATORS, FORMULA_FUNCTIONS, FORMULA_CONSTANTS)
8
10
  from .execution import Execution, ExecutionStatus, ExecutionStepLog, AbortedException
9
11
  from .execution_log import ExecutionLog
10
12
  from .experiment import Experiment
@@ -45,7 +47,8 @@ from .wizard_function import WizardStep, WizardFunction
45
47
  from .wizard_request import WizardRequest
46
48
 
47
49
  # Pipeline Entities (Dto)
48
- from .pipeline import Pipeline, PipelineStep, StepType, WriteConfig, AlertConfig, PipelineIO, RunnerStatus, AlertType
50
+ from .pipeline import Pipeline, PipelineStep, StepType, WriteConfig, AlertConfig, FormulaConfig, PipelineIO, RunnerStatus, \
51
+ AlertType
49
52
  from .context import Context
50
53
  from .ilogger import ILogger
51
54
  from .pipeline_image import PipelineImage
@@ -61,6 +64,7 @@ from .notification import NotificationScope, DeviceToken, AlertRule, AlertActive
61
64
  from .edge_device import EdgeDevice, EdgeDeviceStatus, EdgeDeviceType, EdgeDeviceProvisioning
62
65
  from .edge_module import EdgeModule, EdgeModuleType, WIZATA_MODULES
63
66
  from .edge_config import EdgeConsumer, EdgeWriter, EdgeTrigger, EdgeFile, EdgeConfig, EdgeCommand
67
+ from .edge_package import EdgePackage, EdgePackageOperation, EdgeRelease
64
68
  from .connection import Connection, ConnectionMapping, ConnectionDirection, TransformKind, \
65
69
  EdgeDeviceKey, EdgeDeviceKeyStatus
66
70
  from .connection_types import ConnectionType, CONNECTION_TYPES, TRANSFORM_SCHEMAS, get_connection_type, \
@@ -59,6 +59,7 @@ class EdgeDevice(ApiDto):
59
59
  :ivar bool managed: the platform keeps this device's manifest ("deploy modules").
60
60
  :ivar dict applied_modules: what was last applied: module -> {image, env names}.
61
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).
62
63
  """
63
64
 
64
65
  @classmethod
@@ -96,7 +97,8 @@ class EdgeDevice(ApiDto):
96
97
  runner_python_version: str = None,
97
98
  managed: bool = None,
98
99
  applied_modules: dict = None,
99
- reconcile_error: str = None):
100
+ reconcile_error: str = None,
101
+ last_seen_at: int = None):
100
102
  self.device_id = device_id
101
103
  self.name = name
102
104
  self.twin_name = twin_name
@@ -117,6 +119,7 @@ class EdgeDevice(ApiDto):
117
119
  self.managed = managed
118
120
  self.applied_modules = applied_modules
119
121
  self.reconcile_error = reconcile_error
122
+ self.last_seen_at = last_seen_at
120
123
 
121
124
  def api_id(self) -> str:
122
125
  return self.device_id
@@ -173,6 +176,8 @@ class EdgeDevice(ApiDto):
173
176
  self.applied_modules = obj["appliedModules"]
174
177
  if "reconcileError" in obj and obj["reconcileError"] is not None:
175
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"])
176
181
 
177
182
  def to_json(self, target: str = None):
178
183
  obj = {}
@@ -215,4 +220,6 @@ class EdgeDevice(ApiDto):
215
220
  obj["appliedModules"] = self.applied_modules
216
221
  if self.reconcile_error is not None:
217
222
  obj["reconcileError"] = self.reconcile_error
223
+ if self.last_seen_at is not None:
224
+ obj["lastSeenAt"] = self.last_seen_at
218
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}