scipion-pyworkflow 3.7.0__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 (140) hide show
  1. pyworkflow/__init__.py +33 -0
  2. pyworkflow/apps/__init__.py +29 -0
  3. pyworkflow/apps/pw_manager.py +37 -0
  4. pyworkflow/apps/pw_plot.py +51 -0
  5. pyworkflow/apps/pw_project.py +113 -0
  6. pyworkflow/apps/pw_protocol_list.py +143 -0
  7. pyworkflow/apps/pw_protocol_run.py +51 -0
  8. pyworkflow/apps/pw_run_tests.py +267 -0
  9. pyworkflow/apps/pw_schedule_run.py +322 -0
  10. pyworkflow/apps/pw_sleep.py +37 -0
  11. pyworkflow/apps/pw_sync_data.py +439 -0
  12. pyworkflow/apps/pw_viewer.py +78 -0
  13. pyworkflow/config.py +536 -0
  14. pyworkflow/constants.py +212 -0
  15. pyworkflow/exceptions.py +18 -0
  16. pyworkflow/gui/__init__.py +36 -0
  17. pyworkflow/gui/browser.py +726 -0
  18. pyworkflow/gui/canvas.py +1190 -0
  19. pyworkflow/gui/dialog.py +976 -0
  20. pyworkflow/gui/form.py +2627 -0
  21. pyworkflow/gui/graph.py +247 -0
  22. pyworkflow/gui/graph_layout.py +271 -0
  23. pyworkflow/gui/gui.py +566 -0
  24. pyworkflow/gui/matplotlib_image.py +233 -0
  25. pyworkflow/gui/plotter.py +247 -0
  26. pyworkflow/gui/project/__init__.py +25 -0
  27. pyworkflow/gui/project/base.py +192 -0
  28. pyworkflow/gui/project/constants.py +139 -0
  29. pyworkflow/gui/project/labels.py +205 -0
  30. pyworkflow/gui/project/project.py +484 -0
  31. pyworkflow/gui/project/searchprotocol.py +154 -0
  32. pyworkflow/gui/project/searchrun.py +181 -0
  33. pyworkflow/gui/project/steps.py +166 -0
  34. pyworkflow/gui/project/utils.py +332 -0
  35. pyworkflow/gui/project/variables.py +179 -0
  36. pyworkflow/gui/project/viewdata.py +472 -0
  37. pyworkflow/gui/project/viewprojects.py +510 -0
  38. pyworkflow/gui/project/viewprotocols.py +2093 -0
  39. pyworkflow/gui/project/viewprotocols_extra.py +560 -0
  40. pyworkflow/gui/text.py +771 -0
  41. pyworkflow/gui/tooltip.py +185 -0
  42. pyworkflow/gui/tree.py +684 -0
  43. pyworkflow/gui/widgets.py +307 -0
  44. pyworkflow/mapper/__init__.py +26 -0
  45. pyworkflow/mapper/mapper.py +222 -0
  46. pyworkflow/mapper/sqlite.py +1578 -0
  47. pyworkflow/mapper/sqlite_db.py +145 -0
  48. pyworkflow/object.py +1512 -0
  49. pyworkflow/plugin.py +712 -0
  50. pyworkflow/project/__init__.py +31 -0
  51. pyworkflow/project/config.py +451 -0
  52. pyworkflow/project/manager.py +179 -0
  53. pyworkflow/project/project.py +1990 -0
  54. pyworkflow/project/scripts/clean_projects.py +77 -0
  55. pyworkflow/project/scripts/config.py +92 -0
  56. pyworkflow/project/scripts/create.py +77 -0
  57. pyworkflow/project/scripts/edit_workflow.py +90 -0
  58. pyworkflow/project/scripts/fix_links.py +39 -0
  59. pyworkflow/project/scripts/load.py +87 -0
  60. pyworkflow/project/scripts/refresh.py +83 -0
  61. pyworkflow/project/scripts/schedule.py +111 -0
  62. pyworkflow/project/scripts/stack2volume.py +41 -0
  63. pyworkflow/project/scripts/stop.py +81 -0
  64. pyworkflow/protocol/__init__.py +38 -0
  65. pyworkflow/protocol/bibtex.py +48 -0
  66. pyworkflow/protocol/constants.py +86 -0
  67. pyworkflow/protocol/executor.py +334 -0
  68. pyworkflow/protocol/hosts.py +313 -0
  69. pyworkflow/protocol/launch.py +270 -0
  70. pyworkflow/protocol/package.py +42 -0
  71. pyworkflow/protocol/params.py +744 -0
  72. pyworkflow/protocol/protocol.py +2554 -0
  73. pyworkflow/resources/Imagej.png +0 -0
  74. pyworkflow/resources/chimera.png +0 -0
  75. pyworkflow/resources/fa-exclamation-triangle_alert.png +0 -0
  76. pyworkflow/resources/fa-info-circle_alert.png +0 -0
  77. pyworkflow/resources/fa-search.png +0 -0
  78. pyworkflow/resources/fa-times-circle_alert.png +0 -0
  79. pyworkflow/resources/file_vol.png +0 -0
  80. pyworkflow/resources/loading.gif +0 -0
  81. pyworkflow/resources/no-image128.png +0 -0
  82. pyworkflow/resources/scipion_bn.png +0 -0
  83. pyworkflow/resources/scipion_icon.png +0 -0
  84. pyworkflow/resources/scipion_icon.svg +397 -0
  85. pyworkflow/resources/scipion_icon_proj.png +0 -0
  86. pyworkflow/resources/scipion_icon_projs.png +0 -0
  87. pyworkflow/resources/scipion_icon_prot.png +0 -0
  88. pyworkflow/resources/scipion_logo.png +0 -0
  89. pyworkflow/resources/scipion_logo_normal.png +0 -0
  90. pyworkflow/resources/scipion_logo_small.png +0 -0
  91. pyworkflow/resources/sprites.png +0 -0
  92. pyworkflow/resources/sprites.xcf +0 -0
  93. pyworkflow/resources/wait.gif +0 -0
  94. pyworkflow/template.py +322 -0
  95. pyworkflow/tests/__init__.py +29 -0
  96. pyworkflow/tests/test_utils.py +25 -0
  97. pyworkflow/tests/tests.py +341 -0
  98. pyworkflow/utils/__init__.py +38 -0
  99. pyworkflow/utils/dataset.py +414 -0
  100. pyworkflow/utils/echo.py +104 -0
  101. pyworkflow/utils/graph.py +196 -0
  102. pyworkflow/utils/log.py +284 -0
  103. pyworkflow/utils/path.py +527 -0
  104. pyworkflow/utils/process.py +132 -0
  105. pyworkflow/utils/profiler.py +92 -0
  106. pyworkflow/utils/progressbar.py +154 -0
  107. pyworkflow/utils/properties.py +627 -0
  108. pyworkflow/utils/reflection.py +129 -0
  109. pyworkflow/utils/utils.py +877 -0
  110. pyworkflow/utils/which.py +229 -0
  111. pyworkflow/viewer.py +328 -0
  112. pyworkflow/webservices/__init__.py +8 -0
  113. pyworkflow/webservices/config.py +11 -0
  114. pyworkflow/webservices/notifier.py +162 -0
  115. pyworkflow/webservices/repository.py +59 -0
  116. pyworkflow/webservices/workflowhub.py +74 -0
  117. pyworkflow/wizard.py +64 -0
  118. pyworkflowtests/__init__.py +51 -0
  119. pyworkflowtests/bibtex.py +51 -0
  120. pyworkflowtests/objects.py +830 -0
  121. pyworkflowtests/protocols.py +154 -0
  122. pyworkflowtests/tests/__init__.py +0 -0
  123. pyworkflowtests/tests/test_canvas.py +72 -0
  124. pyworkflowtests/tests/test_domain.py +45 -0
  125. pyworkflowtests/tests/test_logs.py +74 -0
  126. pyworkflowtests/tests/test_mappers.py +392 -0
  127. pyworkflowtests/tests/test_object.py +507 -0
  128. pyworkflowtests/tests/test_project.py +42 -0
  129. pyworkflowtests/tests/test_protocol_execution.py +72 -0
  130. pyworkflowtests/tests/test_protocol_export.py +78 -0
  131. pyworkflowtests/tests/test_protocol_output.py +158 -0
  132. pyworkflowtests/tests/test_streaming.py +47 -0
  133. pyworkflowtests/tests/test_utils.py +210 -0
  134. scipion_pyworkflow-3.7.0.dist-info/LICENSE.txt +674 -0
  135. scipion_pyworkflow-3.7.0.dist-info/METADATA +107 -0
  136. scipion_pyworkflow-3.7.0.dist-info/RECORD +140 -0
  137. scipion_pyworkflow-3.7.0.dist-info/WHEEL +5 -0
  138. scipion_pyworkflow-3.7.0.dist-info/dependency_links.txt +1 -0
  139. scipion_pyworkflow-3.7.0.dist-info/entry_points.txt +5 -0
  140. scipion_pyworkflow-3.7.0.dist-info/top_level.txt +2 -0
Binary file
Binary file
Binary file
Binary file
pyworkflow/template.py ADDED
@@ -0,0 +1,322 @@
1
+ """ Module to host templates classes"""
2
+ import collections
3
+ import glob
4
+ import os
5
+ import tempfile
6
+ from datetime import datetime
7
+ from pyworkflow import SCIPION_JSON_TEMPLATES, Config, VarTypes
8
+ from pyworkflow.utils import greenStr
9
+ import logging
10
+ logger = logging.getLogger(__name__)
11
+
12
+ class Template:
13
+ def __init__(self, source, name, description):
14
+ self.source = source
15
+ # Tidy up templates names: removing .json.template and .json (when passed as parameter)
16
+ self.name = name
17
+ self.description = description
18
+ self.content = None
19
+ self.params = None
20
+ self.projectName = None
21
+
22
+ def __str__(self):
23
+ return self.name
24
+
25
+ def getContent(self):
26
+ """ Returns the content of the template if not present it calls , loadContent"""
27
+
28
+ if self.content is None:
29
+ self.content = self.loadContent()
30
+
31
+ return self.content
32
+
33
+ def loadContent(self):
34
+ """ Method to load into self.content the content of a template"""
35
+ pass
36
+
37
+ def getObjId(self):
38
+ return self.source + '-' + self.name
39
+
40
+ def genProjectName(self):
41
+ self.projectName = self.getObjId() + '-' + datetime.now().strftime("%y%m%d-%H%M%S")
42
+
43
+ def replaceEnvVariables(self):
44
+ self.content = (self.getContent() % os.environ).split('~')
45
+
46
+ def parseContent(self):
47
+
48
+ content = self.getContent()
49
+
50
+ def paramStr2Param(fieldIndex, fieldString):
51
+ fieldLst = fieldString.split('|')
52
+
53
+ title = fieldLst[0]
54
+ defaultValue = fieldLst[1] if len(fieldLst) >= 2 else None
55
+ varType = fieldLst[2] if len(fieldLst) >= 3 else None
56
+ alias = fieldLst[3] if len(fieldLst) >= 4 else None
57
+
58
+ return TemplateParam(fieldIndex, title, defaultValue, varType, alias)
59
+
60
+ # Fill each field in the template in order to prevent spreading in the form
61
+ self.params = collections.OrderedDict()
62
+ for index in range(1, len(content), 2):
63
+ param = paramStr2Param(index, content[index])
64
+ self.params[param.getTitle()] = param
65
+
66
+ def createTemplateFile(self):
67
+
68
+ # Where to write the json file.
69
+ (fileHandle, path) = tempfile.mkstemp()
70
+
71
+ self._replaceFields()
72
+
73
+ finalJson = "".join(self.getContent())
74
+
75
+ os.write(fileHandle, finalJson.encode())
76
+ os.close(fileHandle)
77
+
78
+ print("New workflow saved at " + path)
79
+
80
+ return path
81
+
82
+ def _replaceFields(self):
83
+
84
+ for field in self.params.values():
85
+ self.content[field.getIndex()] = field.getValue()
86
+
87
+ def getParams(self):
88
+ return self.params
89
+
90
+ def setParamValue(self, alias, newValue):
91
+ paramsSetted = 0
92
+ for field in self.params.values():
93
+ if field.getAlias() == alias:
94
+ oldValue = field.getValue()
95
+ field.setValue(newValue)
96
+ if field.validate() is None:
97
+ paramsSetted += 1
98
+ print(greenStr("%s set to %s") %
99
+ (field.getTitle(), str(newValue)))
100
+ else:
101
+ field.setValue(oldValue)
102
+ raise Exception("%s is not compatible with %s(%s) parameter." % (newValue, field.getTitle(), alias))
103
+ if not paramsSetted:
104
+ raise Exception("Alias %s not recognized." % alias)
105
+ return paramsSetted
106
+
107
+ class LocalTemplate(Template):
108
+ """ Local template representing a json file in the file system"""
109
+
110
+ def __init__(self, source, tempPath):
111
+ # Tidy up templates names: removing .json.template and .json (when passed as parameter)
112
+ name = os.path.basename(tempPath).replace(SCIPION_JSON_TEMPLATES, "").replace(".json", "")
113
+ super().__init__(source,name, "")
114
+ self.templatePath = os.path.abspath(tempPath)
115
+ self.description, self.content = self._parseTemplate()
116
+
117
+ def _parseTemplate(self):
118
+ with open(self.templatePath, 'r') as myFile:
119
+ allContents = myFile.read().splitlines()
120
+ description, index = LocalTemplate.getDescription(allContents)
121
+
122
+ if not description:
123
+ description = 'Not provided'
124
+ content = ''.join(allContents[index:])
125
+ return description, content
126
+
127
+
128
+ @staticmethod
129
+ def getDescription(strList):
130
+ # Example of json.template file with description:
131
+ # -----------------------------------------------
132
+ # Here goes the description
133
+ # Description
134
+ # Another description line...
135
+ # [
136
+ # {
137
+ # "object.className": "ProtImportMovies",
138
+ # "object.id": "2",...
139
+ # -----------------------------------------------
140
+
141
+ contents_start_1 = '['
142
+ contents_start_2 = '{'
143
+ description = []
144
+ counter = 0
145
+ nLines = len(strList)
146
+
147
+ while counter + 1 < nLines:
148
+ currentLine = strList[counter]
149
+ nextLine = strList[counter + 1]
150
+ if contents_start_1 not in currentLine:
151
+ description.append(currentLine)
152
+ else:
153
+ if contents_start_2 in nextLine:
154
+ break
155
+ else:
156
+ description.append(currentLine)
157
+ counter += 1
158
+
159
+ return ''.join(description), counter
160
+
161
+
162
+
163
+ class TemplateParam(object):
164
+ def __init__(self, index, title, value=None, varType=None, alias=None):
165
+ self._index = index
166
+ self._title = title
167
+ self._value = value
168
+ self._type = int(varType)
169
+ self._alias = alias
170
+
171
+ def getTitle(self):
172
+ return self._title
173
+
174
+ def getIndex(self):
175
+ return self._index
176
+
177
+ def getType(self):
178
+ return self._type
179
+
180
+ def getValue(self):
181
+ return self._value
182
+
183
+ def setValue(self, value):
184
+ self._value = value
185
+
186
+ def getAlias(self):
187
+ return self._alias
188
+
189
+ def validate(self):
190
+ return Validations.check(self._value, self._type)
191
+
192
+
193
+ class Validations:
194
+
195
+ """ FIELDS VALIDATION """
196
+ """ FIELDS TYPES"""
197
+ @classmethod
198
+ def check(cls, value, fieldType):
199
+ if fieldType == VarTypes.BOOLEAN.value:
200
+ return cls.validBoolean(value)
201
+ elif fieldType == VarTypes.DECIMAL.value:
202
+ return cls.validDecimal(value)
203
+ elif fieldType == VarTypes.INTEGER.value:
204
+ return cls.validInteger(value)
205
+ elif fieldType in (VarTypes.PATH.value, VarTypes.FOLDER.value):
206
+ return cls.validPath(value)
207
+ elif fieldType == VarTypes.STRING.value:
208
+ return cls.validString(value)
209
+
210
+ else:
211
+ return "Type %s for %s not recognized. Review the template." % (fieldType, value)
212
+
213
+ @staticmethod
214
+ def validString(value):
215
+ if value is None:
216
+ return "String does not accept None/empty values."
217
+
218
+ @staticmethod
219
+ def validInteger(value):
220
+ if not value.isdigit():
221
+ return "Value does not seem to be an integer number."
222
+
223
+ @staticmethod
224
+ def validPath(value):
225
+ if not os.path.exists(value):
226
+ return "Path does not exists."
227
+
228
+ @staticmethod
229
+ def validDecimal(value):
230
+
231
+ try:
232
+ float(value)
233
+ return None
234
+ except Exception as e:
235
+ return "Value can't be converted to a float (%s)" % str(e)
236
+
237
+ @staticmethod
238
+ def validBoolean(value):
239
+ validValues = ["true", "1", "false", "0"]
240
+
241
+ valueL = value.lower()
242
+
243
+ if valueL not in validValues:
244
+ return "Only valid values for a boolean type are: %s" % validValues
245
+
246
+
247
+ class TemplateList:
248
+ def __init__(self, templates=None):
249
+ self.templates = templates if templates else []
250
+
251
+ def addTemplate(self, t):
252
+ self.templates.append(t)
253
+
254
+ def genFromStrList(self, templateList):
255
+ for t in templateList:
256
+ parsedPath = t.split(os.path.sep)
257
+ pluginName = parsedPath[parsedPath.index('templates') - 1]
258
+ self.addTemplate(LocalTemplate(pluginName, t))
259
+
260
+ def sortListByPluginName(self):
261
+ # Create a identifier with both plugin and template names to sort by both
262
+ self.templates = sorted(self.templates, key=lambda template: '.' + template.getObjId()
263
+ if template.getObjId().startswith('local') else template.getObjId())
264
+
265
+ return self
266
+
267
+ def addScipionTemplates(self, tempId=None):
268
+ """ Adds scipion templates from local file system or from workflow hub.
269
+ :param tempId: identifier of the template to look up for. If fount only this template is chosen
270
+ """
271
+
272
+ self.addLocalTemplates(tempId)
273
+
274
+ if tempId is None or len(self.templates) == 0:
275
+ self.addWHTemplates(tempId)
276
+
277
+
278
+ def addLocalTemplates(self, tempId=None):
279
+ # Check if there is any .json.template in the template folder
280
+ # get the template folder (we only want it to be included once)
281
+ templateFolder = Config.getExternalJsonTemplates()
282
+ for templateName in glob.glob1(templateFolder,
283
+ "*" + SCIPION_JSON_TEMPLATES):
284
+ t = LocalTemplate("local", os.path.join(templateFolder, templateName))
285
+ if tempId is not None:
286
+ if t.getObjId() == tempId:
287
+ self.addTemplate(t)
288
+ break
289
+ else:
290
+ self.addTemplate(t)
291
+
292
+ def addWHTemplates(self, tempId=None):
293
+
294
+ try:
295
+
296
+ from pyworkflow.webservices.workflowhub import get_wh_templates
297
+
298
+ templates = get_wh_templates(tempId)
299
+
300
+ self.templates.extend(templates)
301
+ except Exception as e:
302
+ logger.warning("Can't get templates from workflow hub: %s" % e)
303
+
304
+ def addPluginTemplates(self, tempId=None):
305
+ """
306
+ Get the templates provided by all plugins.
307
+ :return: a list of templates
308
+ """
309
+ # Check if other plugins have json.templates
310
+ domain = Config.getDomain()
311
+ # Check if there is any .json.template in the template folder
312
+ # get the template folder (we only want it to be included once)
313
+ for pluginName, pluginModule in domain.getPlugins().items():
314
+ tempListPlugin = pluginModule._pluginInstance.getTemplates()
315
+ for t in tempListPlugin:
316
+ if tempId is not None:
317
+ if t.getObjId() == tempId:
318
+ self.addTemplate(t)
319
+ break
320
+ else:
321
+ self.addTemplate(t)
322
+
@@ -0,0 +1,29 @@
1
+ #!/usr/bin/env python
2
+ # **************************************************************************
3
+ # *
4
+ # * Authors: J.M. De la Rosa Trevin (jmdelarosa@cnb.csic.es)
5
+ # Laura del Cano (ldelcano@cnb.csic.es)
6
+ # *
7
+ # * Unidad de Bioinformatica of Centro Nacional de Biotecnologia , CSIC
8
+ # *
9
+ # * This program is free software; you can redistribute it and/or modify
10
+ # * it under the terms of the GNU General Public License as published by
11
+ # * the Free Software Foundation; either version 3 of the License, or
12
+ # * (at your option) any later version.
13
+ # *
14
+ # * This program is distributed in the hope that it will be useful,
15
+ # * but WITHOUT ANY WARRANTY; without even the implied warranty of
16
+ # * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17
+ # * GNU General Public License for more details.
18
+ # *
19
+ # * You should have received a copy of the GNU General Public License
20
+ # * along with this program; if not, write to the Free Software
21
+ # * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
22
+ # * 02111-1307 USA
23
+ # *
24
+ # * All comments concerning this program package may be sent to the
25
+ # * e-mail address 'scipion@cnb.csic.es'
26
+ # *
27
+ # **************************************************************************
28
+
29
+ from .tests import *
@@ -0,0 +1,25 @@
1
+ #!/usr/bin/env python
2
+ # coding: latin-1
3
+ """
4
+ Created on Mar 25, 2014
5
+
6
+ @author: airen
7
+ @author: roberto.marabini
8
+ """
9
+ import time
10
+
11
+
12
+ def wait(condition, timeout=30):
13
+ """ Wait until "condition" returns False or return after timeout (seconds)
14
+ param"""
15
+ t0 = time.time()
16
+
17
+ while condition():
18
+ time.sleep(1)
19
+
20
+ # Check timeout
21
+ tDelta = time.time()
22
+
23
+ if tDelta - t0 >= timeout:
24
+ print("Wait timed out after ", timeout, " seconds")
25
+ return