scipion-pyworkflow 3.11.0__py3-none-any.whl → 3.11.1__py3-none-any.whl

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 (98) hide show
  1. pyworkflow/apps/__init__.py +29 -0
  2. pyworkflow/apps/pw_manager.py +37 -0
  3. pyworkflow/apps/pw_plot.py +51 -0
  4. pyworkflow/apps/pw_project.py +113 -0
  5. pyworkflow/apps/pw_protocol_list.py +143 -0
  6. pyworkflow/apps/pw_protocol_run.py +51 -0
  7. pyworkflow/apps/pw_run_tests.py +267 -0
  8. pyworkflow/apps/pw_schedule_run.py +322 -0
  9. pyworkflow/apps/pw_sleep.py +37 -0
  10. pyworkflow/apps/pw_sync_data.py +439 -0
  11. pyworkflow/apps/pw_viewer.py +78 -0
  12. pyworkflow/constants.py +1 -1
  13. pyworkflow/gui/__init__.py +36 -0
  14. pyworkflow/gui/browser.py +760 -0
  15. pyworkflow/gui/canvas.py +1190 -0
  16. pyworkflow/gui/dialog.py +979 -0
  17. pyworkflow/gui/form.py +2726 -0
  18. pyworkflow/gui/graph.py +247 -0
  19. pyworkflow/gui/graph_layout.py +271 -0
  20. pyworkflow/gui/gui.py +566 -0
  21. pyworkflow/gui/matplotlib_image.py +233 -0
  22. pyworkflow/gui/plotter.py +247 -0
  23. pyworkflow/gui/project/__init__.py +25 -0
  24. pyworkflow/gui/project/base.py +192 -0
  25. pyworkflow/gui/project/constants.py +139 -0
  26. pyworkflow/gui/project/labels.py +205 -0
  27. pyworkflow/gui/project/project.py +491 -0
  28. pyworkflow/gui/project/searchprotocol.py +238 -0
  29. pyworkflow/gui/project/searchrun.py +181 -0
  30. pyworkflow/gui/project/steps.py +171 -0
  31. pyworkflow/gui/project/utils.py +332 -0
  32. pyworkflow/gui/project/variables.py +179 -0
  33. pyworkflow/gui/project/viewdata.py +472 -0
  34. pyworkflow/gui/project/viewprojects.py +510 -0
  35. pyworkflow/gui/project/viewprotocols.py +2116 -0
  36. pyworkflow/gui/project/viewprotocols_extra.py +562 -0
  37. pyworkflow/gui/text.py +771 -0
  38. pyworkflow/gui/tooltip.py +185 -0
  39. pyworkflow/gui/tree.py +684 -0
  40. pyworkflow/gui/widgets.py +307 -0
  41. pyworkflow/mapper/__init__.py +26 -0
  42. pyworkflow/mapper/mapper.py +222 -0
  43. pyworkflow/mapper/sqlite.py +1581 -0
  44. pyworkflow/mapper/sqlite_db.py +145 -0
  45. pyworkflow/project/__init__.py +31 -0
  46. pyworkflow/project/config.py +454 -0
  47. pyworkflow/project/manager.py +180 -0
  48. pyworkflow/project/project.py +2095 -0
  49. pyworkflow/project/usage.py +165 -0
  50. pyworkflow/protocol/__init__.py +38 -0
  51. pyworkflow/protocol/bibtex.py +48 -0
  52. pyworkflow/protocol/constants.py +87 -0
  53. pyworkflow/protocol/executor.py +483 -0
  54. pyworkflow/protocol/hosts.py +317 -0
  55. pyworkflow/protocol/launch.py +277 -0
  56. pyworkflow/protocol/package.py +42 -0
  57. pyworkflow/protocol/params.py +781 -0
  58. pyworkflow/protocol/protocol.py +2707 -0
  59. pyworkflow/tests/__init__.py +29 -0
  60. pyworkflow/tests/test_utils.py +25 -0
  61. pyworkflow/tests/tests.py +341 -0
  62. pyworkflow/utils/__init__.py +38 -0
  63. pyworkflow/utils/dataset.py +414 -0
  64. pyworkflow/utils/echo.py +104 -0
  65. pyworkflow/utils/graph.py +169 -0
  66. pyworkflow/utils/log.py +293 -0
  67. pyworkflow/utils/path.py +528 -0
  68. pyworkflow/utils/process.py +153 -0
  69. pyworkflow/utils/profiler.py +92 -0
  70. pyworkflow/utils/progressbar.py +154 -0
  71. pyworkflow/utils/properties.py +617 -0
  72. pyworkflow/utils/reflection.py +129 -0
  73. pyworkflow/utils/utils.py +880 -0
  74. pyworkflow/utils/which.py +229 -0
  75. pyworkflow/webservices/__init__.py +8 -0
  76. pyworkflow/webservices/config.py +8 -0
  77. pyworkflow/webservices/notifier.py +152 -0
  78. pyworkflow/webservices/repository.py +59 -0
  79. pyworkflow/webservices/workflowhub.py +74 -0
  80. pyworkflowtests/tests/__init__.py +0 -0
  81. pyworkflowtests/tests/test_canvas.py +72 -0
  82. pyworkflowtests/tests/test_domain.py +45 -0
  83. pyworkflowtests/tests/test_logs.py +74 -0
  84. pyworkflowtests/tests/test_mappers.py +392 -0
  85. pyworkflowtests/tests/test_object.py +507 -0
  86. pyworkflowtests/tests/test_project.py +42 -0
  87. pyworkflowtests/tests/test_protocol_execution.py +146 -0
  88. pyworkflowtests/tests/test_protocol_export.py +78 -0
  89. pyworkflowtests/tests/test_protocol_output.py +158 -0
  90. pyworkflowtests/tests/test_streaming.py +47 -0
  91. pyworkflowtests/tests/test_utils.py +210 -0
  92. {scipion_pyworkflow-3.11.0.dist-info → scipion_pyworkflow-3.11.1.dist-info}/METADATA +2 -2
  93. scipion_pyworkflow-3.11.1.dist-info/RECORD +161 -0
  94. scipion_pyworkflow-3.11.0.dist-info/RECORD +0 -71
  95. {scipion_pyworkflow-3.11.0.dist-info → scipion_pyworkflow-3.11.1.dist-info}/WHEEL +0 -0
  96. {scipion_pyworkflow-3.11.0.dist-info → scipion_pyworkflow-3.11.1.dist-info}/entry_points.txt +0 -0
  97. {scipion_pyworkflow-3.11.0.dist-info → scipion_pyworkflow-3.11.1.dist-info}/licenses/LICENSE.txt +0 -0
  98. {scipion_pyworkflow-3.11.0.dist-info → scipion_pyworkflow-3.11.1.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,139 @@
1
+ # **************************************************************************
2
+ # *
3
+ # * Authors: J.M. De la Rosa Trevin (jmdelarosa@cnb.csic.es)
4
+ # *
5
+ # * Unidad de Bioinformatica of Centro Nacional de Biotecnologia , CSIC
6
+ # *
7
+ # * This program is free software; you can redistribute it and/or modify
8
+ # * it under the terms of the GNU General Public License as published by
9
+ # * the Free Software Foundation; either version 3 of the License, or
10
+ # * (at your option) any later version.
11
+ # *
12
+ # * This program is distributed in the hope that it will be useful,
13
+ # * but WITHOUT ANY WARRANTY; without even the implied warranty of
14
+ # * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15
+ # * GNU General Public License for more details.
16
+ # *
17
+ # * You should have received a copy of the GNU General Public License
18
+ # * along with this program; if not, write to the Free Software
19
+ # * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
20
+ # * 02111-1307 USA
21
+ # *
22
+ # * All comments concerning this program package may be sent to the
23
+ # * e-mail address 'scipion@cnb.csic.es'
24
+ # *
25
+ # **************************************************************************
26
+
27
+
28
+ from pyworkflow.protocol import (STATUS_SAVED, STATUS_LAUNCHED, STATUS_RUNNING,
29
+ STATUS_FINISHED, STATUS_FAILED,
30
+ STATUS_INTERACTIVE, STATUS_ABORTED,
31
+ STATUS_SCHEDULED)
32
+
33
+ from pyworkflow.utils.properties import Message, Icon, KEYSYM
34
+
35
+ STATUS_COLORS = {
36
+ STATUS_SAVED: '#D9F1FA',
37
+ STATUS_LAUNCHED: '#D9F1FA',
38
+ STATUS_RUNNING: '#FCCE62',
39
+ STATUS_FINISHED: '#D2F5CB',
40
+ STATUS_FAILED: '#F5CCCB',
41
+ STATUS_INTERACTIVE: '#F3F5CB',
42
+ STATUS_ABORTED: '#F5CCCB',
43
+ STATUS_SCHEDULED: '#F3F5CB'
44
+ }
45
+
46
+ # For protocols with warnings
47
+ WARNING_COLOR = '#848484'
48
+
49
+ ACTION_NEW = Message.LABEL_NEW
50
+ ACTION_EDIT = Message.LABEL_EDIT
51
+ ACTION_RENAME = Message.LABEL_RENAME
52
+ ACTION_SELECT_FROM = Message.LABEL_SELECT_FROM
53
+ ACTION_SELECT_TO = Message.LABEL_SELECT_TO
54
+ ACTION_COPY = Message.LABEL_COPY
55
+ ACTION_PASTE = Message.LABEL_PASTE
56
+ ACTION_DUPLICATE = Message.LABEL_DUPLICATE
57
+ ACTION_DELETE = Message.LABEL_DELETE
58
+ ACTION_REFRESH = Message.LABEL_REFRESH
59
+ ACTION_STEPS = Message.LABEL_STEPS
60
+ ACTION_BROWSE = Message.LABEL_BROWSE
61
+ ACTION_DB = Message.LABEL_DB
62
+ ACTION_TREE = Message.LABEL_TREE
63
+ ACTION_STOP = Message.LABEL_STOP
64
+ ACTION_DEFAULT = Message.LABEL_DEFAULT
65
+ ACTION_CONTINUE = Message.LABEL_CONTINUE
66
+ ACTION_RESULTS = Message.LABEL_ANALYZE
67
+ ACTION_EXPORT = Message.LABEL_EXPORT
68
+ ACTION_EXPORT_UPLOAD = Message.LABEL_EXPORT_UPLOAD
69
+ ACTION_SWITCH_VIEW = 'Switch_View'
70
+ ACTION_COLLAPSE = 'Collapse'
71
+ ACTION_EXPAND = 'Expand'
72
+ ACTION_LABELS = 'Labels'
73
+ ACTION_RESTART_WORKFLOW = Message.LABEL_RESTART_WORKFLOW
74
+ ACTION_CONTINUE_WORKFLOW = Message.LABEL_CONTINUE_WORKFLOW
75
+ ACTION_STOP_WORKFLOW = Message.LABEL_STOP_WORKFLOW
76
+ ACTION_RESET_WORKFLOW = Message.LABEL_RESET_WORKFLOW
77
+ ACTION_SEARCH = 'Search'
78
+
79
+ ActionIcons = {
80
+ ACTION_NEW: Icon.ACTION_NEW,
81
+ ACTION_EDIT: Icon.ACTION_EDIT,
82
+ ACTION_SELECT_FROM: Icon.ACTION_SELECT_FROM,
83
+ ACTION_SELECT_TO: Icon.ACTION_SELECT_TO,
84
+ ACTION_DUPLICATE: Icon.ACTION_DUPLICATE,
85
+ ACTION_COPY: Icon.ACTION_COPY,
86
+ ACTION_PASTE:Icon.ACTION_PASTE,
87
+ ACTION_DELETE: Icon.ACTION_DELETE,
88
+ ACTION_REFRESH: Icon.ACTION_REFRESH,
89
+ ACTION_RENAME: Icon.ACTION_RENAME,
90
+ ACTION_STEPS: Icon.CODE_BRANCH,
91
+ ACTION_BROWSE: Icon.ACTION_BROWSE,
92
+ ACTION_DB: Icon.ACTION_DB,
93
+ ACTION_TREE: None, # should be set
94
+ ACTION_STOP: Icon.ACTION_STOP,
95
+ ACTION_CONTINUE: Icon.ACTION_CONTINUE,
96
+ ACTION_RESULTS: Icon.ACTION_RESULTS,
97
+ ACTION_EXPORT: Icon.ACTION_EXPORT,
98
+ ACTION_EXPORT_UPLOAD: Icon.ACTION_EXPORT_UPLOAD,
99
+ ACTION_COLLAPSE: Icon.ACTION_COLLAPSE,
100
+ ACTION_EXPAND: Icon.ACTION_EXPAND,
101
+ ACTION_LABELS: Icon.TAGS,
102
+ ACTION_RESTART_WORKFLOW: Icon.BACKWARD,
103
+ ACTION_CONTINUE_WORKFLOW: Icon.ACTION_CONTINUE,
104
+ ACTION_STOP_WORKFLOW: Icon.ACTION_STOP_WORKFLOW,
105
+ ACTION_RESET_WORKFLOW: Icon.BROOM,
106
+ ACTION_SEARCH: Icon.ACTION_SEARCH,
107
+ }
108
+
109
+ # TODO: Centralize this and the 2 above collections
110
+ ActionShortCuts = {
111
+ ACTION_NEW: "<Control-f>",
112
+ # F keys
113
+ ACTION_RENAME: "<F2>",
114
+ ACTION_REFRESH: "<F5>",
115
+ # Letter keys, uppercase first, sorted
116
+ ACTION_COLLAPSE: "-",
117
+ ACTION_EXPAND: "+",
118
+ ACTION_RESULTS: "a",
119
+ ACTION_BROWSE: "b",
120
+ ACTION_CONTINUE_WORKFLOW:"c",
121
+ ACTION_DB: "d",
122
+ ACTION_EDIT: "e",
123
+ ACTION_SELECT_FROM: "f",
124
+ ACTION_LABELS: "l",
125
+ ACTION_TREE: "o",
126
+ ACTION_RESTART_WORKFLOW: "R",
127
+ ACTION_RESET_WORKFLOW:"r",
128
+ ACTION_STEPS: "S",
129
+ ACTION_STOP: "s",
130
+ ACTION_SELECT_TO: "t",
131
+ # Control +, sorted
132
+ ACTION_COPY: "<Control-c>",
133
+ ACTION_DUPLICATE: "<Control-d>",
134
+ ACTION_PASTE: "<Control-v>",
135
+ ACTION_STOP_WORKFLOW: "<Control-s>",
136
+ ACTION_DELETE: "<Delete>",
137
+
138
+
139
+ }
@@ -0,0 +1,205 @@
1
+ # **************************************************************************
2
+ # *
3
+ # * Authors: J.M. De la Rosa Trevin (jmdelarosa@cnb.csic.es)
4
+ # *
5
+ # * Unidad de Bioinformatica of Centro Nacional de Biotecnologia , CSIC
6
+ # *
7
+ # * This program is free software; you can redistribute it and/or modify
8
+ # * it under the terms of the GNU General Public License as published by
9
+ # * the Free Software Foundation; either version 3 of the License, or
10
+ # * (at your option) any later version.
11
+ # *
12
+ # * This program is distributed in the hope that it will be useful,
13
+ # * but WITHOUT ANY WARRANTY; without even the implied warranty of
14
+ # * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15
+ # * GNU General Public License for more details.
16
+ # *
17
+ # * You should have received a copy of the GNU General Public License
18
+ # * along with this program; if not, write to the Free Software
19
+ # * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
20
+ # * 02111-1307 USA
21
+ # *
22
+ # * All comments concerning this program package may be sent to the
23
+ # * e-mail address 'scipion@cnb.csic.es'
24
+ # *
25
+ # **************************************************************************
26
+ """
27
+ Tree widget implementation.
28
+ """
29
+
30
+ import tkinter as tk
31
+
32
+
33
+ from pyworkflow import Config
34
+ from pyworkflow.project import Label
35
+ from pyworkflow.gui import Icon, configureWeigths, getDefaultFont
36
+ from pyworkflow.gui.tree import TreeProvider
37
+ import pyworkflow.gui.dialog as dialog
38
+
39
+
40
+ class LabelsTreeProvider(TreeProvider):
41
+ """ Populate Tree from Labels. """
42
+ def __init__(self, objList=None):
43
+ TreeProvider.__init__(self)
44
+ self.objList = objList
45
+ self._parentDict = {}
46
+
47
+ def getColumns(self):
48
+ return [('name', 300), ('color', 150)]
49
+
50
+ def getObjectInfo(self, label:Label):
51
+
52
+ return {'key': label.getName(), 'parent': None,
53
+ 'text': label.getName(), 'values': (label.getColor()),
54
+ 'tags': label.getColor()}
55
+
56
+ def getObjectPreview(self, obj):
57
+ return None, None
58
+
59
+ def getObjectActions(self, obj):
60
+ return []
61
+
62
+ def _getObjectList(self):
63
+ """Retrieve the object list"""
64
+ return self.objList
65
+
66
+ def getObjects(self):
67
+ objList = self._getObjectList()
68
+ return objList
69
+
70
+ def configureTags(self, tree):
71
+ for label in self.getObjects():
72
+ tree.tag_configure(label.getColor(), background=label.getColor())
73
+
74
+
75
+ class LabelsDialog(dialog.ToolbarListDialog):
76
+ """
77
+ This class extend from ListDialog to allow an
78
+ extra toolbar to handle operations over the elements
79
+ in the list (e.g. Edit, New, Delete).
80
+ """
81
+ def __init__(self, parent, labels, **kwargs):
82
+ """ From kwargs:
83
+ message: message tooltip to show when browsing.
84
+ selected: the item that should be selected.
85
+ validateSelectionCallback:
86
+ a callback function to validate selected items.
87
+ allowSelect: if set to False, the 'Select' button will not
88
+ be shown.
89
+ """
90
+ self.labels = labels
91
+ toolbarButtons = [
92
+ dialog.ToolbarButton('Add', self._addLabel, Icon.ACTION_NEW),
93
+ dialog.ToolbarButton('Edit', self._editLabel, Icon.ACTION_EDIT),
94
+ dialog.ToolbarButton('Delete', self._deleteLabel, Icon.ACTION_DELETE)
95
+ ]
96
+
97
+ helpMsg ="Select the label to edit or delete. Selected labels will be assigned to selected protocols." \
98
+ "\nUse 'Control' key for multiple selection. Do not select any label to clear the labels of selected protocols."
99
+
100
+ dialog.ToolbarListDialog.__init__(self, parent,
101
+ "Manage labels",
102
+ LabelsTreeProvider(labels),
103
+ helpMsg,
104
+ toolbarButtons,
105
+ allowsEmptySelection=True,
106
+ itemDoubleClick=self._editLabel,
107
+ cancelButton=False,
108
+ **kwargs)
109
+
110
+ def _newColor(self):
111
+ """ Pick a color by default for a given label from a predefined list.
112
+ Check that the color have not been used by other label.
113
+ """
114
+ colors = ["#e57373", "#4fc3f7", "#81c784", "#ff8a65", "#9575cd",
115
+ "#a1887f", "#ffd54f", "#dce775", "#4db6ac"]
116
+
117
+ for c in colors:
118
+ if all(l.getColor().lower() != c for l in self.labels):
119
+ return c
120
+
121
+ return 'red'
122
+
123
+ def _addLabel(self, e=None):
124
+ label = Label(color=self._newColor())
125
+ dlg = EditLabelDialog(self, "Add label", label)
126
+ if dlg.resultYes():
127
+ self.labels.addLabel(label)
128
+ self.tree.update()
129
+
130
+ def _editLabel(self, e=None):
131
+ selection = self.tree.getSelectedObjects()
132
+ if selection:
133
+ label = selection[0]
134
+ dlg = EditLabelDialog(self, "Edit label", label)
135
+ if dlg.resultYes():
136
+ self.tree.update()
137
+
138
+ def _deleteLabel(self, e=None):
139
+ selection = self.tree.getSelectedObjects()
140
+ if selection:
141
+ labelsStr = '\n'.join('- %s' % l.getName() for l in selection)
142
+ if dialog.askYesNo("Delete a label",
143
+ "Are you sure to delete the "
144
+ "following label(s)?\n %s" % labelsStr, self):
145
+ for label in selection:
146
+ self.labels.deleteLabel(label)
147
+ self.tree.update()
148
+
149
+
150
+ class EditLabelDialog(dialog.Dialog):
151
+ """ Dialog to edit a label (name, color) """
152
+ def __init__(self, parent, title, label, **kwargs):
153
+ self.label = label
154
+ dialog.Dialog.__init__(self, parent, title)
155
+
156
+ def body(self, bodyFrame):
157
+ bodyFrame.config(bg=Config.SCIPION_BG_COLOR)
158
+ configureWeigths(bodyFrame, 1, 1)
159
+
160
+ # Label
161
+ label_text = tk.Label(bodyFrame, text="Name", bg=Config.SCIPION_BG_COLOR, bd=0)
162
+ label_text.grid(row=0, column=0, sticky='nw', padx=(15, 10), pady=15)
163
+ # Label box
164
+ var = tk.StringVar()
165
+ var.set(self.label.getName())
166
+ self.textVar = var
167
+ self.textLabel = tk.Entry(bodyFrame, width=20, font=getDefaultFont(), textvariable=var)
168
+ self.textLabel.grid(row=0, column=1, sticky='news', padx=5, pady=5)
169
+
170
+ # Comment
171
+ colorLabel = tk.Label(bodyFrame, text='Color \n(Click to change)',
172
+ bg=Config.SCIPION_BG_COLOR, bd=0)
173
+ colorLabel.grid(row=1, column=0, sticky='nw', padx=(15, 10), pady=15)
174
+ self.colorVar = tk.StringVar()
175
+ self.colorVar.set(self.label.getColor())
176
+ self.colorBox = tk.Frame(bodyFrame, bg=self.colorVar.get())
177
+ self.colorBox.grid(row=1, column=1, sticky='news', padx=5, pady=5)
178
+ colorLabel.bind('<Button-1>', self._changeColor)
179
+ self.colorBox.bind('<Button-1>', self._changeColor)
180
+
181
+ def apply(self):
182
+ self.label.setName(self.textVar.get())
183
+ self.label.setColor(self.colorVar.get())
184
+
185
+ def _changeColor(self, e=None):
186
+ hexColor = dialog.askColor(parent=self, defaultColor=self.colorVar.get())
187
+ if hexColor is not None:
188
+ self.colorBox.config(bg=hexColor)
189
+ self.colorVar.set(hexColor)
190
+
191
+ def validate(self):
192
+
193
+ validationMsg = None
194
+
195
+ if len(self.textVar.get().strip()) == 0:
196
+ validationMsg = "Label name can't be empty.\n"
197
+
198
+ if validationMsg is not None:
199
+ dialog.showError("Validation error", validationMsg, self)
200
+ return False
201
+
202
+ return True
203
+
204
+
205
+