wizata-dsapi 2.1.0.dev9__tar.gz → 2.1.0.dev11__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 (66) hide show
  1. {wizata_dsapi-2.1.0.dev9 → wizata_dsapi-2.1.0.dev11}/PKG-INFO +1 -1
  2. {wizata_dsapi-2.1.0.dev9 → wizata_dsapi-2.1.0.dev11}/wizata_dsapi/__init__.py +1 -1
  3. {wizata_dsapi-2.1.0.dev9 → wizata_dsapi-2.1.0.dev11}/wizata_dsapi/trigger.py +62 -1
  4. {wizata_dsapi-2.1.0.dev9 → wizata_dsapi-2.1.0.dev11}/wizata_dsapi/twin.py +29 -10
  5. wizata_dsapi-2.1.0.dev11/wizata_dsapi/version.py +1 -0
  6. {wizata_dsapi-2.1.0.dev9 → wizata_dsapi-2.1.0.dev11}/wizata_dsapi.egg-info/PKG-INFO +1 -1
  7. wizata_dsapi-2.1.0.dev9/wizata_dsapi/version.py +0 -1
  8. {wizata_dsapi-2.1.0.dev9 → wizata_dsapi-2.1.0.dev11}/LICENSE.txt +0 -0
  9. {wizata_dsapi-2.1.0.dev9 → wizata_dsapi-2.1.0.dev11}/README.rst +0 -0
  10. {wizata_dsapi-2.1.0.dev9 → wizata_dsapi-2.1.0.dev11}/setup.cfg +0 -0
  11. {wizata_dsapi-2.1.0.dev9 → wizata_dsapi-2.1.0.dev11}/setup.py +0 -0
  12. {wizata_dsapi-2.1.0.dev9 → wizata_dsapi-2.1.0.dev11}/wizata_dsapi/api_config.py +0 -0
  13. {wizata_dsapi-2.1.0.dev9 → wizata_dsapi-2.1.0.dev11}/wizata_dsapi/api_dto.py +0 -0
  14. {wizata_dsapi-2.1.0.dev9 → wizata_dsapi-2.1.0.dev11}/wizata_dsapi/api_interface.py +0 -0
  15. {wizata_dsapi-2.1.0.dev9 → wizata_dsapi-2.1.0.dev11}/wizata_dsapi/bucket.py +0 -0
  16. {wizata_dsapi-2.1.0.dev9 → wizata_dsapi-2.1.0.dev11}/wizata_dsapi/business_label.py +0 -0
  17. {wizata_dsapi-2.1.0.dev9 → wizata_dsapi-2.1.0.dev11}/wizata_dsapi/context.py +0 -0
  18. {wizata_dsapi-2.1.0.dev9 → wizata_dsapi-2.1.0.dev11}/wizata_dsapi/dashboard.py +0 -0
  19. {wizata_dsapi-2.1.0.dev9 → wizata_dsapi-2.1.0.dev11}/wizata_dsapi/dataframe_toolkit.py +0 -0
  20. {wizata_dsapi-2.1.0.dev9 → wizata_dsapi-2.1.0.dev11}/wizata_dsapi/datapoint.py +0 -0
  21. {wizata_dsapi-2.1.0.dev9 → wizata_dsapi-2.1.0.dev11}/wizata_dsapi/datastore.py +0 -0
  22. {wizata_dsapi-2.1.0.dev9 → wizata_dsapi-2.1.0.dev11}/wizata_dsapi/ds_dataframe.py +0 -0
  23. {wizata_dsapi-2.1.0.dev9 → wizata_dsapi-2.1.0.dev11}/wizata_dsapi/dsapi_json_encoder.py +0 -0
  24. {wizata_dsapi-2.1.0.dev9 → wizata_dsapi-2.1.0.dev11}/wizata_dsapi/edge_config.py +0 -0
  25. {wizata_dsapi-2.1.0.dev9 → wizata_dsapi-2.1.0.dev11}/wizata_dsapi/edge_device.py +0 -0
  26. {wizata_dsapi-2.1.0.dev9 → wizata_dsapi-2.1.0.dev11}/wizata_dsapi/edge_module.py +0 -0
  27. {wizata_dsapi-2.1.0.dev9 → wizata_dsapi-2.1.0.dev11}/wizata_dsapi/evaluation.py +0 -0
  28. {wizata_dsapi-2.1.0.dev9 → wizata_dsapi-2.1.0.dev11}/wizata_dsapi/execution.py +0 -0
  29. {wizata_dsapi-2.1.0.dev9 → wizata_dsapi-2.1.0.dev11}/wizata_dsapi/execution_log.py +0 -0
  30. {wizata_dsapi-2.1.0.dev9 → wizata_dsapi-2.1.0.dev11}/wizata_dsapi/experiment.py +0 -0
  31. {wizata_dsapi-2.1.0.dev9 → wizata_dsapi-2.1.0.dev11}/wizata_dsapi/graylog_log.py +0 -0
  32. {wizata_dsapi-2.1.0.dev9 → wizata_dsapi-2.1.0.dev11}/wizata_dsapi/group_system.py +0 -0
  33. {wizata_dsapi-2.1.0.dev9 → wizata_dsapi-2.1.0.dev11}/wizata_dsapi/ilogger.py +0 -0
  34. {wizata_dsapi-2.1.0.dev9 → wizata_dsapi-2.1.0.dev11}/wizata_dsapi/insight.py +0 -0
  35. {wizata_dsapi-2.1.0.dev9 → wizata_dsapi-2.1.0.dev11}/wizata_dsapi/mlmodel.py +0 -0
  36. {wizata_dsapi-2.1.0.dev9 → wizata_dsapi-2.1.0.dev11}/wizata_dsapi/mobile_asset.py +0 -0
  37. {wizata_dsapi-2.1.0.dev9 → wizata_dsapi-2.1.0.dev11}/wizata_dsapi/model_toolkit.py +0 -0
  38. {wizata_dsapi-2.1.0.dev9 → wizata_dsapi-2.1.0.dev11}/wizata_dsapi/models/__init__.py +0 -0
  39. {wizata_dsapi-2.1.0.dev9 → wizata_dsapi-2.1.0.dev11}/wizata_dsapi/models/common.py +0 -0
  40. {wizata_dsapi-2.1.0.dev9 → wizata_dsapi-2.1.0.dev11}/wizata_dsapi/notification.py +0 -0
  41. {wizata_dsapi-2.1.0.dev9 → wizata_dsapi-2.1.0.dev11}/wizata_dsapi/paged_query_result.py +0 -0
  42. {wizata_dsapi-2.1.0.dev9 → wizata_dsapi-2.1.0.dev11}/wizata_dsapi/pipeline.py +0 -0
  43. {wizata_dsapi-2.1.0.dev9 → wizata_dsapi-2.1.0.dev11}/wizata_dsapi/pipeline_image.py +0 -0
  44. {wizata_dsapi-2.1.0.dev9 → wizata_dsapi-2.1.0.dev11}/wizata_dsapi/plot.py +0 -0
  45. {wizata_dsapi-2.1.0.dev9 → wizata_dsapi-2.1.0.dev11}/wizata_dsapi/plots/__init__.py +0 -0
  46. {wizata_dsapi-2.1.0.dev9 → wizata_dsapi-2.1.0.dev11}/wizata_dsapi/plots/common.py +0 -0
  47. {wizata_dsapi-2.1.0.dev9 → wizata_dsapi-2.1.0.dev11}/wizata_dsapi/plots/theme.py +0 -0
  48. {wizata_dsapi-2.1.0.dev9 → wizata_dsapi-2.1.0.dev11}/wizata_dsapi/request.py +0 -0
  49. {wizata_dsapi-2.1.0.dev9 → wizata_dsapi-2.1.0.dev11}/wizata_dsapi/script.py +0 -0
  50. {wizata_dsapi-2.1.0.dev9 → wizata_dsapi-2.1.0.dev11}/wizata_dsapi/scripts/__init__.py +0 -0
  51. {wizata_dsapi-2.1.0.dev9 → wizata_dsapi-2.1.0.dev11}/wizata_dsapi/scripts/common.py +0 -0
  52. {wizata_dsapi-2.1.0.dev9 → wizata_dsapi-2.1.0.dev11}/wizata_dsapi/search.py +0 -0
  53. {wizata_dsapi-2.1.0.dev9 → wizata_dsapi-2.1.0.dev11}/wizata_dsapi/solution_component.py +0 -0
  54. {wizata_dsapi-2.1.0.dev9 → wizata_dsapi-2.1.0.dev11}/wizata_dsapi/streamlit_utils.py +0 -0
  55. {wizata_dsapi-2.1.0.dev9 → wizata_dsapi-2.1.0.dev11}/wizata_dsapi/template.py +0 -0
  56. {wizata_dsapi-2.1.0.dev9 → wizata_dsapi-2.1.0.dev11}/wizata_dsapi/template_config.py +0 -0
  57. {wizata_dsapi-2.1.0.dev9 → wizata_dsapi-2.1.0.dev11}/wizata_dsapi/twinregistration.py +0 -0
  58. {wizata_dsapi-2.1.0.dev9 → wizata_dsapi-2.1.0.dev11}/wizata_dsapi/user.py +0 -0
  59. {wizata_dsapi-2.1.0.dev9 → wizata_dsapi-2.1.0.dev11}/wizata_dsapi/wizard_function.py +0 -0
  60. {wizata_dsapi-2.1.0.dev9 → wizata_dsapi-2.1.0.dev11}/wizata_dsapi/wizard_request.py +0 -0
  61. {wizata_dsapi-2.1.0.dev9 → wizata_dsapi-2.1.0.dev11}/wizata_dsapi/wizata_dsapi_client.py +0 -0
  62. {wizata_dsapi-2.1.0.dev9 → wizata_dsapi-2.1.0.dev11}/wizata_dsapi/words.py +0 -0
  63. {wizata_dsapi-2.1.0.dev9 → wizata_dsapi-2.1.0.dev11}/wizata_dsapi.egg-info/SOURCES.txt +0 -0
  64. {wizata_dsapi-2.1.0.dev9 → wizata_dsapi-2.1.0.dev11}/wizata_dsapi.egg-info/dependency_links.txt +0 -0
  65. {wizata_dsapi-2.1.0.dev9 → wizata_dsapi-2.1.0.dev11}/wizata_dsapi.egg-info/requires.txt +0 -0
  66. {wizata_dsapi-2.1.0.dev9 → wizata_dsapi-2.1.0.dev11}/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.1.0.dev9
3
+ Version: 2.1.0.dev11
4
4
  Summary: Wizata Data Science Toolkit
5
5
  Author: Wizata S.A.
6
6
  Author-email: info@wizata.com
@@ -14,7 +14,7 @@ from .template import Template, TemplateProperty
14
14
  from .solution_component import SolutionComponent, SolutionType
15
15
  from .business_label import BusinessLabel
16
16
  from .twinregistration import TwinRegistration, TwinRegistrationProperty
17
- from .trigger import Trigger
17
+ from .trigger import Trigger, validate_trigger_branch
18
18
  from .group_system import GroupSystem
19
19
  from .bucket import Bucket
20
20
 
@@ -1,8 +1,45 @@
1
+ import re
1
2
  import uuid
2
3
  import json
3
4
  from .api_dto import ApiDto
4
5
 
5
6
 
7
+ # Mirrors BranchNamer._release_re in wizata_ds_gitstore/branches.py (the source of
8
+ # truth for branch naming). Duplicated as a pure regex on purpose: importing
9
+ # wizata_ds_gitstore pulls pygit2 through its package __init__, which this public
10
+ # package must not depend on.
11
+ RELEASE_BRANCH_RE = re.compile(r"^release/[A-Za-z0-9_\-\.]{1,64}$")
12
+
13
+
14
+ def validate_trigger_branch(branch):
15
+ """
16
+ Check a value destined for `Trigger.branch` (DEV-5962 / DEV-5966).
17
+
18
+ A schedule must pin a version that cannot move under it: a `release/<name>`
19
+ branch is fast-forward-only and never rewound, whereas master changes every
20
+ time anyone publishes — a trigger on master would silently change what
21
+ production executes. Feature branches are ephemeral (deleted on publish), so
22
+ they are refused too. An image-based trigger carries no branch at all.
23
+
24
+ Call this on WRITE only (`TriggerClient.create` / `update`). It is deliberately
25
+ NOT called from `from_json`: validating on the read path is what made a single
26
+ bad row break `GET /dsapi/twins/` (DEV-5970).
27
+
28
+ :param branch: branch value or None (None is valid — image or legacy trigger).
29
+ :raise ValueError: when branch is set but is not a release branch.
30
+ """
31
+ if branch is None:
32
+ return None
33
+ branch = str(branch)
34
+ if RELEASE_BRANCH_RE.match(branch) is None:
35
+ raise ValueError(
36
+ f"a trigger can only run a release branch, got {branch!r} — "
37
+ f"publish and cut a release/<name> first (master moves, feature "
38
+ f"branches are deleted on publish)"
39
+ )
40
+ return branch
41
+
42
+
6
43
  class Trigger(ApiDto):
7
44
  """
8
45
  trigger defines how pipelines are automatically executed.
@@ -14,6 +51,12 @@ class Trigger(ApiDto):
14
51
  :ivar uuid.UUID template_id: set a template id to trigger.
15
52
  :ivar dict properties: set a dict of properties to pass when triggering the pipeline.
16
53
  :ivar list twin_ids: set a list of twin ids on which executed the pipelines (must be registered on the pipeline).
54
+ :ivar str branch: git release branch this schedule runs (`release/<name>`), None for an
55
+ image-based or non-git trigger.
56
+ :ivar str version: runner runtime this schedule executes on (e.g. `3.12`, `3.12-julia`)
57
+ — same meaning as `ExecutionLog.version`, hence the same attribute name here. The
58
+ backend calls it `pythonVersion` on the wire, and the front-end presents it as
59
+ "Environment".
17
60
  :ivar uuid.UUID createdById: unique identifier of creating user.
18
61
  :ivar int createdDate: timestamp of created date.
19
62
  :ivar uuid.UUID updatedById: unique identifier of updating user.
@@ -38,7 +81,9 @@ class Trigger(ApiDto):
38
81
  pipeline_image_id: str = None,
39
82
  template_id: uuid.UUID = None,
40
83
  properties: dict = None,
41
- twin_ids: list = None):
84
+ twin_ids: list = None,
85
+ branch: str = None,
86
+ version: str = None):
42
87
  if trigger_id is None:
43
88
  trigger_id = uuid.uuid4()
44
89
  self.trigger_id = trigger_id
@@ -49,6 +94,8 @@ class Trigger(ApiDto):
49
94
  self.template_id = template_id
50
95
  self.properties = properties
51
96
  self.twin_ids = twin_ids
97
+ self.branch = branch
98
+ self.version = version
52
99
  self.createdById = None
53
100
  self.createdDate = None
54
101
  self.updatedById = None
@@ -82,6 +129,15 @@ class Trigger(ApiDto):
82
129
  else:
83
130
  self.properties = obj["jsonProperties"]
84
131
 
132
+ # DEV-5966: the version the schedule runs and the runtime it runs on. Both
133
+ # exist on the backend (`pythonVersion` has always been there and drives the
134
+ # runner queue; `branch` arrived with DEV-5962) but neither was mapped here,
135
+ # so they were silently dropped in both directions.
136
+ if "branch" in obj.keys() and obj["branch"] is not None:
137
+ self.branch = str(obj["branch"])
138
+ if "pythonVersion" in obj.keys() and obj["pythonVersion"] is not None:
139
+ self.version = str(obj["pythonVersion"])
140
+
85
141
  if "twinIds" in obj.keys() and isinstance(obj["twinIds"], list):
86
142
  self.twin_ids = []
87
143
  for twinId in obj["twinIds"]:
@@ -114,6 +170,11 @@ class Trigger(ApiDto):
114
170
  if self.pipeline_image_id is not None:
115
171
  obj["pipelineImageId"] = str(self.pipeline_image_id)
116
172
 
173
+ if self.branch is not None:
174
+ obj["branch"] = str(self.branch)
175
+ if self.version is not None:
176
+ obj["pythonVersion"] = str(self.version)
177
+
117
178
  if self.properties is not None:
118
179
  obj["jsonProperties"] = json.dumps(self.properties)
119
180
 
@@ -14,6 +14,31 @@ def is_valid_hex_color(color):
14
14
  return True
15
15
 
16
16
 
17
+ def parse_color(color):
18
+ """
19
+ Normalize a colour coming from a payload or a constructor (DEV-5970).
20
+
21
+ A BLANK value means "no colour", not an invalid one: the platform's own
22
+ .NET side stores `""` on twins it creates, and because this validation runs
23
+ on the READ path (`from_json`) a single such row used to raise and make
24
+ `GET /dsapi/twins/` fail for the WHOLE collection.
25
+
26
+ Anything else non-blank is still validated and still raises, because
27
+ `from_json` is also the write path (`POST` / `PUT /dsapi/twins/` validate
28
+ nowhere else) — a colour typed as `red` must remain a 400.
29
+
30
+ :param color: raw colour value or None.
31
+ :return: the colour string, or None when absent/blank.
32
+ """
33
+ if color is None:
34
+ return None
35
+ color = str(color)
36
+ if color.strip() == '':
37
+ return None
38
+ is_valid_hex_color(color)
39
+ return color
40
+
41
+
17
42
  class TwinType(ApiDto):
18
43
  """
19
44
  twin type
@@ -41,9 +66,7 @@ class TwinType(ApiDto):
41
66
  self.twin_type_id = twin_type_id
42
67
  self.name = name
43
68
  self.icon = icon
44
- self.color = color
45
- if color is not None:
46
- is_valid_hex_color(color)
69
+ self.color = parse_color(color)
47
70
  self.description = description
48
71
  self.createdById = None
49
72
  self.createdDate = None
@@ -62,8 +85,7 @@ class TwinType(ApiDto):
62
85
  if "name" in obj.keys() and obj["name"] is not None:
63
86
  self.name = obj["name"]
64
87
  if "color" in obj.keys() and obj["color"] is not None:
65
- is_valid_hex_color(str(obj["color"]))
66
- self.color = str(obj["color"])
88
+ self.color = parse_color(obj["color"])
67
89
  if "icon" in obj.keys() and obj["icon"] is not None:
68
90
  self.icon = str(obj["icon"])
69
91
  if "description" in obj.keys() and obj["description"] is not None:
@@ -185,9 +207,7 @@ class Twin(ApiDto):
185
207
  self.longitude = longitude
186
208
  self.latitude_id = latitude_id
187
209
  self.longitude_id = longitude_id
188
- if color is not None:
189
- is_valid_hex_color(color)
190
- self.color = color
210
+ self.color = parse_color(color)
191
211
  self.icon = icon
192
212
  self.extra_properties = extra_properties
193
213
  self.is_asset = is_asset
@@ -229,8 +249,7 @@ class Twin(ApiDto):
229
249
  if "longitudeSensorId" in obj.keys() and obj["longitudeSensorId"] is not None:
230
250
  self.longitude_id = uuid.UUID(obj["longitudeSensorId"])
231
251
  if "color" in obj.keys() and obj["color"] is not None:
232
- is_valid_hex_color(str(obj["color"]))
233
- self.color = str(obj["color"])
252
+ self.color = parse_color(obj["color"])
234
253
  if "icon" in obj.keys() and obj["icon"] is not None:
235
254
  self.icon = str(obj["icon"])
236
255
  if "description" in obj.keys() and obj["description"] is not None:
@@ -0,0 +1 @@
1
+ __version__ = "2.1.0.dev11"
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: wizata_dsapi
3
- Version: 2.1.0.dev9
3
+ Version: 2.1.0.dev11
4
4
  Summary: Wizata Data Science Toolkit
5
5
  Author: Wizata S.A.
6
6
  Author-email: info@wizata.com
@@ -1 +0,0 @@
1
- __version__ = "2.1.0.dev9"