itkdb-gtk 0.10.7__tar.gz → 0.10.9__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.

Potentially problematic release.


This version of itkdb-gtk might be problematic. Click here for more details.

Files changed (40) hide show
  1. {itkdb_gtk-0.10.7 → itkdb_gtk-0.10.9}/PKG-INFO +1 -1
  2. {itkdb_gtk-0.10.7 → itkdb_gtk-0.10.9}/itkdb_gtk/CreateShipments.py +24 -19
  3. {itkdb_gtk-0.10.7 → itkdb_gtk-0.10.9}/itkdb_gtk/GetShipments.py +53 -26
  4. {itkdb_gtk-0.10.7 → itkdb_gtk-0.10.9}/itkdb_gtk/GlueWeight.py +2 -2
  5. {itkdb_gtk-0.10.7 → itkdb_gtk-0.10.9}/itkdb_gtk/ITkDBlogin.py +2 -2
  6. {itkdb_gtk-0.10.7 → itkdb_gtk-0.10.9}/itkdb_gtk/ITkDButils.py +133 -17
  7. itkdb_gtk-0.10.9/itkdb_gtk/PanelVisualInspection.py +585 -0
  8. {itkdb_gtk-0.10.7 → itkdb_gtk-0.10.9}/itkdb_gtk/PetalReceptionTests.py +35 -25
  9. {itkdb_gtk-0.10.7 → itkdb_gtk-0.10.9}/itkdb_gtk/SensorUtils.py +16 -14
  10. {itkdb_gtk-0.10.7 → itkdb_gtk-0.10.9}/itkdb_gtk/ShowAttachments.py +3 -1
  11. {itkdb_gtk-0.10.7 → itkdb_gtk-0.10.9}/itkdb_gtk/UploadModuleIV.py +8 -8
  12. {itkdb_gtk-0.10.7 → itkdb_gtk-0.10.9}/itkdb_gtk/UploadMultipleTests.py +54 -51
  13. {itkdb_gtk-0.10.7 → itkdb_gtk-0.10.9}/itkdb_gtk/UploadPetalInformation.py +8 -9
  14. {itkdb_gtk-0.10.7 → itkdb_gtk-0.10.9}/itkdb_gtk/UploadTest.py +7 -7
  15. {itkdb_gtk-0.10.7 → itkdb_gtk-0.10.9}/itkdb_gtk/WireBondGui.py +79 -29
  16. {itkdb_gtk-0.10.7 → itkdb_gtk-0.10.9}/itkdb_gtk/__init__.py +6 -1
  17. {itkdb_gtk-0.10.7 → itkdb_gtk-0.10.9}/itkdb_gtk/dashBoard.py +36 -13
  18. {itkdb_gtk-0.10.7 → itkdb_gtk-0.10.9}/itkdb_gtk/dbGtkUtils.py +60 -22
  19. {itkdb_gtk-0.10.7 → itkdb_gtk-0.10.9}/itkdb_gtk.egg-info/PKG-INFO +1 -1
  20. {itkdb_gtk-0.10.7 → itkdb_gtk-0.10.9}/itkdb_gtk.egg-info/SOURCES.txt +2 -0
  21. {itkdb_gtk-0.10.7 → itkdb_gtk-0.10.9}/itkdb_gtk.egg-info/entry_points.txt +1 -0
  22. {itkdb_gtk-0.10.7 → itkdb_gtk-0.10.9}/pyproject.toml +2 -1
  23. itkdb_gtk-0.10.9/test/testBatch.py +87 -0
  24. itkdb_gtk-0.10.9/test/test_attachment.py +70 -0
  25. itkdb_gtk-0.10.7/itkdb_gtk/PanelVisualInspection.py +0 -230
  26. {itkdb_gtk-0.10.7 → itkdb_gtk-0.10.9}/README.md +0 -0
  27. {itkdb_gtk-0.10.7 → itkdb_gtk-0.10.9}/itkdb_gtk/ITkDB.desktop +0 -0
  28. {itkdb_gtk-0.10.7 → itkdb_gtk-0.10.9}/itkdb_gtk/ITkDB.svg +0 -0
  29. {itkdb_gtk-0.10.7 → itkdb_gtk-0.10.9}/itkdb_gtk/ShowComments.py +0 -0
  30. {itkdb_gtk-0.10.7 → itkdb_gtk-0.10.9}/itkdb_gtk/ShowDefects.py +0 -0
  31. {itkdb_gtk-0.10.7 → itkdb_gtk-0.10.9}/itkdb_gtk/readAVSdata.py +0 -0
  32. {itkdb_gtk-0.10.7 → itkdb_gtk-0.10.9}/itkdb_gtk/readGoogleSheet.py +0 -0
  33. {itkdb_gtk-0.10.7 → itkdb_gtk-0.10.9}/itkdb_gtk/untrash_component.py +0 -0
  34. {itkdb_gtk-0.10.7 → itkdb_gtk-0.10.9}/itkdb_gtk.egg-info/dependency_links.txt +0 -0
  35. {itkdb_gtk-0.10.7 → itkdb_gtk-0.10.9}/itkdb_gtk.egg-info/requires.txt +0 -0
  36. {itkdb_gtk-0.10.7 → itkdb_gtk-0.10.9}/itkdb_gtk.egg-info/top_level.txt +0 -0
  37. {itkdb_gtk-0.10.7 → itkdb_gtk-0.10.9}/setup.cfg +0 -0
  38. {itkdb_gtk-0.10.7 → itkdb_gtk-0.10.9}/test/testAnimated.py +0 -0
  39. {itkdb_gtk-0.10.7 → itkdb_gtk-0.10.9}/test/testComponent.py +0 -0
  40. {itkdb_gtk-0.10.7 → itkdb_gtk-0.10.9}/test/test_holes.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: itkdb_gtk
3
- Version: 0.10.7
3
+ Version: 0.10.9
4
4
  Summary: A collection of Gtk based GUI to access ITkDB.
5
5
  Author-email: Carlos Lacasta <carlos.lacasta@cern.ch>
6
6
  Project-URL: Homepage, https://gitlab.cern.ch/atlas-itk/sw/db/itk-pdb-gtk-gui-utils
@@ -9,7 +9,7 @@ import re
9
9
 
10
10
  try:
11
11
  import itkdb_gtk
12
-
12
+
13
13
  except ImportError:
14
14
  from pathlib import Path
15
15
  cwd = Path(__file__).parent.parent
@@ -28,7 +28,7 @@ gtk_runs, gtk_args = Gtk.init_check()
28
28
  class CreateShipments(dbGtkUtils.ITkDBWindow):
29
29
  """Create a shipment from input."""
30
30
 
31
- def __init__(self, session):
31
+ def __init__(self, session, help_link=None):
32
32
  """Initialization.
33
33
 
34
34
  Args:
@@ -41,7 +41,8 @@ class CreateShipments(dbGtkUtils.ITkDBWindow):
41
41
  self.attachment = None
42
42
  global gtk_runs
43
43
  if gtk_runs:
44
- super().__init__(session=session, title="Upload AVS Data", gtk_runs=gtk_runs)
44
+ super().__init__(session=session, title="Upload AVS Data",
45
+ help_link=help_link, gtk_runs=gtk_runs)
45
46
  self.init_window()
46
47
 
47
48
  def init_window(self):
@@ -193,24 +194,28 @@ class CreateShipments(dbGtkUtils.ITkDBWindow):
193
194
  dbGtkUtils.complain("Item {} is already in transit".format(SN),
194
195
  "This item is already in transit to {}".format(rc['shipmentDestination']['code']))
195
196
  return
197
+
196
198
  nick = rc['alternativeIdentifier']
197
- id = rc['id']
199
+ obj_id = rc['id']
198
200
  obj = rc['componentType']['name']
199
201
  loc = rc['currentLocation']['code']
202
+ serialN = rc['serialNumber']
203
+ if serialN is None:
204
+ serialN = obj_id
200
205
 
201
206
  # Check tha tthe input is not already there
202
207
  model = self.tree.get_model()
203
- iter = model.get_iter_first()
204
- while iter:
205
- if model.get_value(iter, 0) == SN:
208
+ lv_iter = model.get_iter_first()
209
+ while lv_iter:
210
+ if model.get_value(lv_iter, 0) == SN:
206
211
  dbGtkUtils.complain("Duplicated item.",
207
212
  "Object {} is already in the list".format(SN))
208
213
  return
209
214
 
210
- iter = model.iter_next(iter)
215
+ lv_iter = model.iter_next(lv_iter)
211
216
 
212
217
  # Add the item in the liststore.
213
- model.append([SN, nick, obj, loc, id])
218
+ model.append([serialN, nick, obj, loc, obj_id])
214
219
 
215
220
  except Exception:
216
221
  dbGtkUtils.complain("Error querying DB",
@@ -220,12 +225,12 @@ class CreateShipments(dbGtkUtils.ITkDBWindow):
220
225
  def remove_item(self, *args):
221
226
  """Remove selected item."""
222
227
  select = self.tree.get_selection()
223
- model, iter = select.get_selected()
224
- if iter:
225
- values = model[iter]
228
+ model, lv_iter = select.get_selected()
229
+ if lv_iter:
230
+ values = model[lv_iter]
226
231
  rc = dbGtkUtils.ask_for_confirmation("Remove this items ?", values[0])
227
232
  if rc:
228
- model.remove(iter)
233
+ model.remove(lv_iter)
229
234
 
230
235
  def add_attachment_dialog(self):
231
236
  """Create the add attachment dialog."""
@@ -278,7 +283,7 @@ class CreateShipments(dbGtkUtils.ITkDBWindow):
278
283
 
279
284
  T = T if len(T) else None
280
285
  D = D if len(D) else None
281
- att = ITkDButils.Attachment(path, T, D)
286
+ att = ITkDButils.Attachment(path=path, title=T, desc=D)
282
287
  self.attachment = att
283
288
 
284
289
  dlg.hide()
@@ -305,16 +310,16 @@ class CreateShipments(dbGtkUtils.ITkDBWindow):
305
310
  def send_items(self, *args):
306
311
  """Send items in liststore."""
307
312
  model = self.tree.get_model()
308
- iter = model.get_iter_first()
313
+ lv_iter = model.get_iter_first()
309
314
  items = []
310
315
  senders = {}
311
- while iter:
312
- values = model[iter]
316
+ while lv_iter:
317
+ values = model[lv_iter]
313
318
  items.append(values[0])
314
319
  senders[values[3]] = senders.setdefault(values[3], 0) + 1
315
- iter = model.iter_next(iter)
320
+ lv_iter = model.iter_next(lv_iter)
316
321
 
317
- if len(items):
322
+ if len(items)>0:
318
323
  if len(senders) != 1:
319
324
  dbGtkUtils.complain("Too many senders.",
320
325
  "There are objects located in differen sites:{}".format('\n'.join(senders.keys())))
@@ -1,19 +1,17 @@
1
1
  #!/usr/bin/env python3
2
2
  """GEt shipments to a particular site (default is IFIC)."""
3
- import pathlib
4
3
  import sys
4
+ from pathlib import Path
5
5
 
6
6
  try:
7
7
  import itkdb_gtk
8
-
8
+
9
9
  except ImportError:
10
- from pathlib import Path
11
10
  cwd = Path(__file__).parent.parent
12
11
  sys.path.append(cwd.as_posix())
13
12
 
14
13
  from itkdb_gtk import dbGtkUtils, ITkDBlogin, ITkDButils
15
14
  import gi
16
- import serial
17
15
 
18
16
  gi.require_version("Gtk", "3.0")
19
17
  from gi.repository import Gtk, Gio, GLib
@@ -22,10 +20,31 @@ from gi.repository import Gtk, Gio, GLib
22
20
  gtk_runs, gtk_args = Gtk.init_check()
23
21
 
24
22
 
23
+ def find_vtrx(client, SN):
24
+ """Searches VTRx."""
25
+ payload = {
26
+ "filterMap": {
27
+ "project": "CE",
28
+ "componentType": ["VTRX"],
29
+ "propertyFilter": [{"code": "PACKAGE_SN", "operator": "=", "value": SN}],
30
+ }
31
+ }
32
+ out = client.get("listComponentsByProperty", json=payload)
33
+ vtrx = None
34
+ nitem = 0
35
+ for item in out:
36
+ vtrx = item["serialNumber"]
37
+ nitem += 1
38
+
39
+ if nitem > 1:
40
+ raise ValueError("Too many VTRx with same device SN.")
41
+
42
+ return vtrx
43
+
25
44
  class ReceiveShipments(dbGtkUtils.ITkDBWindow):
26
45
  """Find shipments related to given recipient."""
27
46
 
28
- def __init__(self, session, recipient="IFIC", help=None):
47
+ def __init__(self, session, recipient="IFIC", help_link=None):
29
48
  """Initialization.
30
49
 
31
50
  Args:
@@ -38,13 +57,14 @@ class ReceiveShipments(dbGtkUtils.ITkDBWindow):
38
57
  self.institute = None
39
58
  self.model = None
40
59
  self.store = None
60
+ self.tree = None
41
61
  self.shipments = {}
42
62
 
43
63
  global gtk_runs
44
64
  if gtk_runs:
45
65
  super().__init__(session=session, title="Upload AVS Data",
46
66
  show_search="Click to search shipments",
47
- gtk_runs=gtk_runs, help=help)
67
+ gtk_runs=gtk_runs, help_link=help_link)
48
68
 
49
69
  self.init_window()
50
70
 
@@ -159,15 +179,22 @@ class ReceiveShipments(dbGtkUtils.ITkDBWindow):
159
179
  txt = dbGtkUtils.scanner_get_line(reader)
160
180
  self.write_message("{}\n".format(txt))
161
181
 
182
+ if txt.find("J-SD") == 0:
183
+ try:
184
+ txt = find_vtrx(self.session, txt)
185
+ except ValueError as e:
186
+ self.write_message("Error: {}".format(e))
187
+ return
188
+
162
189
  # search code in the list
163
190
  if self.store:
164
- iter = self.store.get_iter_first()
165
- while iter:
166
- if (self.store.get_value(iter, 0) == txt):
191
+ lv_iter = self.store.get_iter_first()
192
+ while lv_iter:
193
+ if (self.store.get_value(lv_iter, 0) == txt):
167
194
  self.write_message("...found\n")
168
- self.store[iter][3] = False
195
+ self.store[lv_iter][3] = False
169
196
 
170
- iter = self.store.iter_next(iter)
197
+ lv_iter = self.store.iter_next(lv_iter)
171
198
 
172
199
  return True
173
200
 
@@ -206,9 +233,9 @@ class ReceiveShipments(dbGtkUtils.ITkDBWindow):
206
233
 
207
234
  # Store the model associated to this shipment.
208
235
  self.store = self.shipments[shpmnt]
209
- filter = self.store.filter_new()
210
- filter.set_visible_column(3)
211
- self.tree.set_model(filter)
236
+ sfilter = self.store.filter_new()
237
+ sfilter.set_visible_column(3)
238
+ self.tree.set_model(sfilter)
212
239
 
213
240
  def on_status_changed(self, combo):
214
241
  """Status changed."""
@@ -301,25 +328,25 @@ class ReceiveShipments(dbGtkUtils.ITkDBWindow):
301
328
 
302
329
  # self.store is the model of the tree view
303
330
  if self.store:
304
- iter = self.store.get_iter_first()
305
- while iter:
306
- shpmnt = self.store.get_value(iter, 2)
331
+ lv_iter = self.store.get_iter_first()
332
+ while lv_iter:
333
+ shpmnt = self.store.get_value(lv_iter, 2)
307
334
  if shpmnt not in data:
308
335
  data[shpmnt] = create_shipment_status(shpmnt)
309
- names[shpmnt] = self.store.get_value(iter, 4)
336
+ names[shpmnt] = self.store.get_value(lv_iter, 4)
310
337
 
311
338
  item = {
312
- "code": self.store[iter][5],
313
- "delivered": not self.store[iter][3]
339
+ "code": self.store[lv_iter][5],
340
+ "delivered": not self.store[lv_iter][3]
314
341
  }
315
342
  data[shpmnt]["shipmentItems"].append(item)
316
343
 
317
- iter = self.store.iter_next(iter)
344
+ lv_iter = self.store.iter_next(lv_iter)
318
345
 
319
346
  else:
320
347
  self.write_message("Empty list of items.\n")
321
348
 
322
- for id, S in data.items():
349
+ for oid, S in data.items():
323
350
  # Check that all items are there
324
351
  nlost = 0
325
352
  for item in S["shipmentItems"]:
@@ -338,7 +365,7 @@ class ReceiveShipments(dbGtkUtils.ITkDBWindow):
338
365
  return
339
366
 
340
367
  # Open dialog to fill-in questions
341
- create_check_list(S["checklist"]["questionList"], names[id])
368
+ create_check_list(S["checklist"]["questionList"], names[oid])
342
369
 
343
370
  # send the update to the DB
344
371
  S['status'] = "delivered"
@@ -354,10 +381,10 @@ class ReceiveShipments(dbGtkUtils.ITkDBWindow):
354
381
  self.write_message("Could not update the shipment status.\n{}\n".foramt(rc))
355
382
 
356
383
  else:
357
- self.write_message("Shipment {} received\n".format(names[id]))
384
+ self.write_message("Shipment {} received\n".format(names[oid]))
358
385
  # Now remove the current shipment
359
- iter = self.cmb_shipment.get_active_iter()
360
- self.cmb_shipment.get_model().remove(iter)
386
+ lv_iter = self.cmb_shipment.get_active_iter()
387
+ self.cmb_shipment.get_model().remove(lv_iter)
361
388
  self.cmb_shipment.set_active(0)
362
389
 
363
390
 
@@ -86,7 +86,7 @@ def remove_defaul_keys(data, default_value=-9999):
86
86
  class GlueWeight(Gtk.Window):
87
87
  """Upluead Glue Weight test."""
88
88
 
89
- def __init__(self, session, ifile=None, help=None):
89
+ def __init__(self, session, ifile=None, help_link=None):
90
90
  """Initialization.
91
91
 
92
92
  Args:
@@ -113,7 +113,7 @@ class GlueWeight(Gtk.Window):
113
113
  session, "MODULE", "GLUE_WEIGHT", defaults)
114
114
 
115
115
  if gtk_runs:
116
- super().__init__(title="Upload Glue Weight")
116
+ super().__init__(title="Upload Glue Weight", help_link=help_link)
117
117
  self.init_window()
118
118
 
119
119
  def init_window(self):
@@ -306,12 +306,12 @@ class ITkDBlogin(Gtk.Dialog):
306
306
  # token_file.write(json.dumps(self.token))
307
307
  self.hide()
308
308
 
309
- def get_client(self):
309
+ def get_client(self, use_eos=True):
310
310
  """Return the client."""
311
311
  if not self.is_connected():
312
312
  return None
313
313
 
314
- return itkdb.Client(user=self.user)
314
+ return itkdb.Client(user=self.user, use_eos=use_eos)
315
315
 
316
316
  def __del__(self):
317
317
  """Delete."""
@@ -3,24 +3,38 @@ import mimetypes
3
3
  from collections.abc import Iterable
4
4
  from datetime import datetime
5
5
  from pathlib import Path
6
+ import getpass
6
7
 
7
8
  import dateutil.parser
9
+ import itkdb
8
10
 
9
11
  # The response of the DB
10
12
  db_response = ""
13
+ attachment_urls = {}
14
+ uploaded_test_runs = []
11
15
 
12
16
 
13
17
  # define an Attachment object.
14
18
  class Attachment(object):
15
19
  """Encapsulates Attachment information."""
16
20
 
17
- def __init__(self, path=None, title=None, desc=None):
21
+ def __init__(self, path=None, url=None, title=None, desc=None):
18
22
  """Initialization."""
19
23
  if path is not None:
20
24
  self.path = Path(path).expanduser().resolve()
25
+ self.type = "file"
21
26
  else:
22
27
  self.path = None
23
28
 
29
+ if url is not None:
30
+ self.url = url
31
+ self.type = "link"
32
+ else:
33
+ self.url = None
34
+
35
+ if self.path and self.url:
36
+ raise ValueError("Invalid Attachment. Has both file and link.")
37
+
24
38
  self.title = title
25
39
  self.desc = desc
26
40
 
@@ -159,13 +173,13 @@ def create_component_attachment(client, SN, file_path, title=None, description="
159
173
  return db_response
160
174
 
161
175
 
162
- def set_component_property(client, SN, property, value):
176
+ def set_component_property(client, SN, the_property, value):
163
177
  """Set the value of an object property.
164
178
 
165
179
  Args:
166
180
  client: The DB client
167
181
  SN: The object SN
168
- property: The property name
182
+ the_property: The property name
169
183
  value: The property value
170
184
 
171
185
  """
@@ -173,7 +187,7 @@ def set_component_property(client, SN, property, value):
173
187
  try:
174
188
  db_response = client.post('setComponentProperty',
175
189
  json={'component': SN,
176
- 'code': property,
190
+ 'code': the_property,
177
191
  'value': value})
178
192
  return db_response
179
193
 
@@ -245,7 +259,7 @@ def get_DB_component(client, SN):
245
259
  db_response = str(e)
246
260
  return None
247
261
 
248
- def upload_test(client, data, attachments=None):
262
+ def upload_test(client, data, attachments=None, check_runNumber=False):
249
263
  """Upload a test to the DB.
250
264
 
251
265
  Args:
@@ -258,38 +272,124 @@ def upload_test(client, data, attachments=None):
258
272
 
259
273
  """
260
274
  global db_response
275
+ global attachment_urls
276
+ global uploaded_test_runs
277
+
278
+ uploaded_test_runs = []
279
+ attachment_urls = {}
280
+ db_response = None
281
+
282
+ # Check the given run_number. If already existing, give another one which
283
+ # will try to be consecutive.
284
+ if check_runNumber:
285
+ def get_new_value(values):
286
+ run_no = max([x for x in values.keys()])+1
287
+ return run_no
288
+
289
+ test_list = client.get("listTestRunsByComponent",
290
+ json={
291
+ "filterMap":{
292
+ "serialNumber": data["component"],
293
+ "state": "ready",
294
+ "testType":[data["testType"]]
295
+ }
296
+ }
297
+ )
298
+ values = {}
299
+ for T in test_list:
300
+ try:
301
+ run_no = int(T["runNumber"])
302
+ except ValueError:
303
+ run_no = get_new_value(values)
304
+
305
+ values[run_no] = 1
306
+
307
+ try:
308
+ if int(data["runNumber"]) in values.keys():
309
+ data["runNumber"] = "{}".format(get_new_value(values))
310
+ except ValueError:
311
+ data["runNumber"] = "{}".format(get_new_value(values))
312
+
313
+ # Try to upload the test
261
314
  try:
262
315
  db_response = client.post("uploadTestRunResults", json=data)
263
316
  testRun = db_response["testRun"]["id"]
317
+ uploaded_test_runs.append(testRun)
318
+
319
+ # Handle attachments.
320
+ attachment_urls = {}
264
321
  if attachments is not None:
265
322
  if not isinstance(attachments, Iterable):
266
323
  attachments = (attachments)
267
324
 
268
325
  for att in attachments:
269
- path = Path(att.path).expanduser().resolve()
270
- if not path.exists():
271
- print("File {} does not exist".format(path))
272
- continue
273
-
274
326
  data = {"testRun": testRun,
275
327
  "title": att.title if att.title is not None else path.name,
276
328
  "description": att.desc if att.desc is not None else path.name,
277
- "type": "file",
329
+ "type": att.type,
278
330
  }
279
- filetype = mimetypes.guess_type(path.name)
280
- attachment = {'data': (path.name, open(path.as_posix(), 'rb'), filetype[0])}
331
+ if att.type == "file":
332
+ path = Path(att.path).expanduser().resolve()
333
+ if not path.exists():
334
+ print("File {} does not exist".format(path))
335
+ continue
336
+
337
+ data["url"] = path.name
338
+ filetype = mimetypes.guess_type(path.name)
339
+ attachment = {'data': (path.name, open(path.as_posix(), 'rb'), filetype[0])}
340
+ else:
341
+ data["url"] = att.url
342
+ filetype = mimetypes.guess_type(att.url)
343
+ attachment = {'data':(att.url, None, "text/x-uri") }
344
+
281
345
  db_response = client.post('createTestRunAttachment',
282
346
  data=data,
283
347
  files=attachment)
348
+ try:
349
+ attachment_urls[path.name] = db_response['url']
350
+
351
+ except KeyError:
352
+ pass
353
+
284
354
 
285
355
  return None
286
356
 
287
357
  except Exception as e:
288
358
  return (str(e))
289
359
 
360
+ def set_test_run_parameter(session, test_run, parameter, value):
361
+ """Modify testRun Parameter
362
+
363
+ Args:
364
+ session: The ITkDB session
365
+ test_run: ID of test run
366
+ parameter: parameter code
367
+ value: The new value
368
+ """
369
+ global db_response
370
+ try:
371
+ db_response = session.post("setTestRunParameter",
372
+ json={"testRun": test_run, "code": parameter, "value": value})
373
+ return None
374
+
375
+ except Exception as E:
376
+ return (str(E))
377
+
378
+ def create_test_run_comment(session, test_run, comments):
379
+ """Adds a new comment in testRun."""
380
+ global db_response
381
+ if not isinstance(comments, Iterable):
382
+ comments = (comments)
383
+
384
+ try:
385
+ db_response = session.post("createTestRunComment", json={"testRun": test_run, "comments": comments})
386
+ return None
387
+
388
+ except Exception as E:
389
+ return (str(E))
290
390
 
291
391
  def create_shipment(session, sender, recipient, items, name=None, send=False,
292
- type="domestic", attachment=None, comments=None):
392
+ shipment_type="domestic", attachment=None, comments=None):
293
393
  """Create a chipment.
294
394
 
295
395
  Args:
@@ -308,7 +408,7 @@ def create_shipment(session, sender, recipient, items, name=None, send=False,
308
408
  if name is None:
309
409
  name = "From {} to {}".format(sender, recipient)
310
410
 
311
- if type not in ["domestic", "intraContinental", "continental"]:
411
+ if shipment_type not in ["domestic", "intraContinental", "continental"]:
312
412
  db_response = "Wrong shipment type."
313
413
  return None
314
414
 
@@ -327,7 +427,7 @@ def create_shipment(session, sender, recipient, items, name=None, send=False,
327
427
  "name": name,
328
428
  "sender": sender,
329
429
  "recipient": recipient,
330
- "type": type,
430
+ "type": shipment_type,
331
431
  "shipmentItems": items,
332
432
  }
333
433
 
@@ -453,7 +553,7 @@ def get_testrun(session, test_id, out_type="object"):
453
553
  return None
454
554
 
455
555
 
456
- def get_test_skeleton(session, component, test_code, userdef={}, uservalues={}):
556
+ def get_test_skeleton(session, component, test_code, userdef=None, uservalues=None):
457
557
  """Get the skeleton of the given test.
458
558
 
459
559
  Args:
@@ -465,6 +565,13 @@ def get_test_skeleton(session, component, test_code, userdef={}, uservalues={}):
465
565
 
466
566
  """
467
567
  global db_response
568
+
569
+ if userdef is None:
570
+ userdef = {}
571
+
572
+ if uservalues is None:
573
+ uservalues = {}
574
+
468
575
  defvalues = {
469
576
  "string": "",
470
577
  "integer": -9999,
@@ -550,3 +657,12 @@ def get_test_skeleton(session, component, test_code, userdef={}, uservalues={}):
550
657
  skltn['results'][key] = get_default(par)
551
658
 
552
659
  return skltn
660
+
661
+ def create_client():
662
+ """Create a Client."""
663
+ client = itkdb.Client()
664
+ client.user._access_code1 = getpass.getpass("Access 1: ")
665
+ client.user._access_code2 = getpass.getpass("Access 2: ")
666
+ client.user.authenticate()
667
+ print("Hello {} !".format(client.user.name))
668
+ return client