scipion-pyworkflow 3.10.6__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.
- pyworkflow/config.py +131 -67
- pyworkflow/constants.py +2 -1
- pyworkflow/gui/browser.py +39 -5
- pyworkflow/gui/dialog.py +2 -0
- pyworkflow/gui/form.py +141 -52
- pyworkflow/gui/gui.py +8 -8
- pyworkflow/gui/project/project.py +6 -7
- pyworkflow/gui/project/searchprotocol.py +91 -7
- pyworkflow/gui/project/viewdata.py +1 -1
- pyworkflow/gui/project/viewprotocols.py +45 -22
- pyworkflow/gui/project/viewprotocols_extra.py +9 -6
- pyworkflow/gui/widgets.py +2 -2
- pyworkflow/mapper/sqlite.py +4 -4
- pyworkflow/plugin.py +93 -44
- pyworkflow/project/project.py +158 -70
- pyworkflow/project/usage.py +165 -0
- pyworkflow/protocol/executor.py +30 -18
- pyworkflow/protocol/hosts.py +9 -6
- pyworkflow/protocol/launch.py +15 -8
- pyworkflow/protocol/params.py +59 -19
- pyworkflow/protocol/protocol.py +124 -58
- pyworkflow/resources/showj/arrowDown.png +0 -0
- pyworkflow/resources/showj/arrowUp.png +0 -0
- pyworkflow/resources/showj/background_section.png +0 -0
- pyworkflow/resources/showj/colRowModeOff.png +0 -0
- pyworkflow/resources/showj/colRowModeOn.png +0 -0
- pyworkflow/resources/showj/delete.png +0 -0
- pyworkflow/resources/showj/doc_icon.png +0 -0
- pyworkflow/resources/showj/download_icon.png +0 -0
- pyworkflow/resources/showj/enabled_gallery.png +0 -0
- pyworkflow/resources/showj/galleryViewOff.png +0 -0
- pyworkflow/resources/showj/galleryViewOn.png +0 -0
- pyworkflow/resources/showj/goto.png +0 -0
- pyworkflow/resources/showj/menu.png +0 -0
- pyworkflow/resources/showj/separator.png +0 -0
- pyworkflow/resources/showj/tableViewOff.png +0 -0
- pyworkflow/resources/showj/tableViewOn.png +0 -0
- pyworkflow/resources/showj/ui-bg_glass_75_e6e6e6_1x400.png +0 -0
- pyworkflow/resources/showj/ui-bg_glass_95_fef1ec_1x400.png +0 -0
- pyworkflow/resources/showj/ui-bg_highlight-soft_75_cccccc_1x100.png +0 -0
- pyworkflow/resources/showj/volumeOff.png +0 -0
- pyworkflow/resources/showj/volumeOn.png +0 -0
- pyworkflow/utils/log.py +15 -6
- pyworkflow/utils/properties.py +78 -92
- pyworkflow/utils/utils.py +3 -2
- pyworkflow/viewer.py +23 -1
- pyworkflow/webservices/config.py +0 -3
- pyworkflow/webservices/notifier.py +24 -34
- pyworkflowtests/protocols.py +1 -3
- pyworkflowtests/tests/test_protocol_execution.py +4 -0
- {scipion_pyworkflow-3.10.6.dist-info → scipion_pyworkflow-3.11.1.dist-info}/METADATA +13 -27
- {scipion_pyworkflow-3.10.6.dist-info → scipion_pyworkflow-3.11.1.dist-info}/RECORD +56 -35
- {scipion_pyworkflow-3.10.6.dist-info → scipion_pyworkflow-3.11.1.dist-info}/WHEEL +1 -1
- scipion_pyworkflow-3.10.6.dist-info/dependency_links.txt +0 -1
- {scipion_pyworkflow-3.10.6.dist-info → scipion_pyworkflow-3.11.1.dist-info}/entry_points.txt +0 -0
- {scipion_pyworkflow-3.10.6.dist-info → scipion_pyworkflow-3.11.1.dist-info}/licenses/LICENSE.txt +0 -0
- {scipion_pyworkflow-3.10.6.dist-info → scipion_pyworkflow-3.11.1.dist-info}/top_level.txt +0 -0
pyworkflow/utils/log.py
CHANGED
@@ -82,9 +82,9 @@ class LoggingConfigurator:
|
|
82
82
|
customLoggingActive = False # Holds if a custom logging configuration has taken place.
|
83
83
|
|
84
84
|
@classmethod
|
85
|
-
def setupLogging(cls, logFile=None, console=True):
|
85
|
+
def setupLogging(cls, logFile=None, console=True, consoleLevel='ERROR'):
|
86
86
|
if not cls.loadCustomLoggingConfig():
|
87
|
-
cls.setupDefaultLogging(logFile=logFile, console=console)
|
87
|
+
cls.setupDefaultLogging(logFile=logFile, console=console, consoleLevel=consoleLevel)
|
88
88
|
|
89
89
|
@classmethod
|
90
90
|
def loadCustomLoggingConfig(cls):
|
@@ -104,13 +104,13 @@ class LoggingConfigurator:
|
|
104
104
|
return False
|
105
105
|
|
106
106
|
@staticmethod
|
107
|
-
def setupDefaultLogging(logFile=None, console=True):
|
107
|
+
def setupDefaultLogging(logFile=None, console=True, consoleLevel="ERROR"):
|
108
108
|
""" Configures logging in a default way that is to file (rotating) and console
|
109
109
|
|
110
110
|
:param logFile: Optional, path to the log file. Defaults to SCIPION_LOG variable value. If folder
|
111
|
-
does not
|
111
|
+
does not exist it will be created.
|
112
112
|
:param console: Optional, defaults to True, so log messages are sent to the terminal as well
|
113
|
-
|
113
|
+
:param consoleLevel: Optional, defaults to ERROR. Only error messages are sent to the console.
|
114
114
|
"""
|
115
115
|
from pyworkflow import Config
|
116
116
|
|
@@ -147,7 +147,7 @@ class LoggingConfigurator:
|
|
147
147
|
|
148
148
|
if console:
|
149
149
|
config["handlers"][CONSOLE_HANDLER] = {
|
150
|
-
'level':
|
150
|
+
'level': consoleLevel,
|
151
151
|
'class': 'logging.StreamHandler',
|
152
152
|
'formatter': 'standard',
|
153
153
|
}
|
@@ -282,3 +282,12 @@ def getExtraLogInfo(measurement, status, project_name=None, prot_id=None, prot_n
|
|
282
282
|
|
283
283
|
except Exception as e:
|
284
284
|
print("getExtraLogInfo failed: %s.Params were: dbFilename %s" % (e, dbfilename))
|
285
|
+
|
286
|
+
|
287
|
+
def changeLogLevel(newLoglevel):
|
288
|
+
""" Changes "on-the-fly" the log level iterating through the handlders"""
|
289
|
+
|
290
|
+
logger = logging.getLogger()
|
291
|
+
logger.setLevel(newLoglevel)
|
292
|
+
for handler in logger.handlers:
|
293
|
+
handler.setLevel(newLoglevel)
|
pyworkflow/utils/properties.py
CHANGED
@@ -121,11 +121,8 @@ class Message:
|
|
121
121
|
LABEL_RUNNAME = 'Run name'
|
122
122
|
LABEL_EXECUTION = 'Run mode'
|
123
123
|
LABEL_RUNMODE = 'Mode'
|
124
|
-
LABEL_PARALLEL = '
|
124
|
+
LABEL_PARALLEL = 'Program compute'
|
125
125
|
LABEL_HOST = 'Host'
|
126
|
-
LABEL_THREADS = 'Threads'
|
127
|
-
LABEL_SCIPION_THREADS = 'Scipion threads'
|
128
|
-
LABEL_MPI = 'MPI'
|
129
126
|
LABEL_QUEUE = 'Use a queue engine?'
|
130
127
|
|
131
128
|
LABEL_WAIT_FOR = 'Wait for'
|
@@ -144,17 +141,6 @@ will clean the whole run directory and start from scratch.
|
|
144
141
|
"""
|
145
142
|
|
146
143
|
HELP_PARALLEL_HEADER = 'Define the number of processors to be used in the execution.\nCheck %s for more detailed info.\n\n' % DOCSITEURLS.THREADS_MPIS_AND_GPUS
|
147
|
-
HELP_PARALLEL_MPI = ("*MPI*:\nThis is a number of independent processes"
|
148
|
-
" that communicate through message passing "
|
149
|
-
"over the network (or the same computer).\n")
|
150
|
-
HELP_PARALLEL_THREADS = ("*Threads*:\nThis refers to different execution threads in the same process that "
|
151
|
-
"can share memory. They run in the same computer. This value is an argument"
|
152
|
-
" passed to the program integrated")
|
153
|
-
|
154
|
-
HELP_SCIPION_THREADS = ("*Scipion threads*:\n threads created by Scipion to run the steps."
|
155
|
-
" 1 thread is always used by the master/main process. Then extra threads will allow"
|
156
|
-
" this protocol to run several steps at the same time, taking always into account "
|
157
|
-
"restrictions to previous steps and 'theoretical GPU availability'")
|
158
144
|
|
159
145
|
HELP_USEQUEUE = """
|
160
146
|
Click Yes if you want to send this execution to a queue engine like Slurm, Torque, ...
|
@@ -478,54 +464,54 @@ class Sprite:
|
|
478
464
|
# To get font awesome icons into png use: http://fa2png.io/
|
479
465
|
class Icon:
|
480
466
|
# Protocols status
|
481
|
-
PROT_DISABLED = SpriteImage(16,32,'prot_disabled.png',bottom=32,right=64)
|
482
|
-
BETA = SpriteImage(0,0,'beta.png',bottom=16,right=32)
|
483
|
-
NEW = SpriteImage(32,0,'new.png',bottom=48,right=32)
|
484
|
-
PRODUCTION = SpriteImage(32,32,'production.png',bottom=48,right=64)
|
485
|
-
UPDATED = SpriteImage(16,0,'updated.png',bottom=32,right=32)
|
486
|
-
|
487
|
-
GROUP = SpriteImage(80, 224,'class_obj.png')
|
488
|
-
FAVORITE = SpriteImage(80,256,'bookmark.png')
|
489
|
-
DEBUG = SpriteImage(64,288,'debug.png')
|
490
|
-
DOWNLOAD = SpriteImage(48,272,'fa-download.png')
|
491
|
-
FIND = SpriteImage(80,272,'binoculares.png')
|
492
|
-
SELECT_ALL = SpriteImage(0,32,'workflow.png')
|
467
|
+
PROT_DISABLED = SpriteImage(16,32, 'prot_disabled.png', bottom=32, right=64)
|
468
|
+
BETA = SpriteImage(0, 0, 'beta.png', bottom=16, right=32)
|
469
|
+
NEW = SpriteImage(32, 0, 'new.png', bottom=48, right=32)
|
470
|
+
PRODUCTION = SpriteImage(32, 32, 'production.png', bottom=48, right=64)
|
471
|
+
UPDATED = SpriteImage(16, 0, 'updated.png', bottom=32, right=32)
|
472
|
+
|
473
|
+
GROUP = SpriteImage(80, 224, 'class_obj.png')
|
474
|
+
FAVORITE = SpriteImage(80, 256, 'bookmark.png')
|
475
|
+
DEBUG = SpriteImage(64, 288, 'debug.png')
|
476
|
+
DOWNLOAD = SpriteImage(48, 272, 'fa-download.png')
|
477
|
+
FIND = SpriteImage(80, 272, 'binoculares.png')
|
478
|
+
SELECT_ALL = SpriteImage(0, 32, 'workflow.png')
|
493
479
|
|
494
480
|
# Project window icons
|
495
|
-
RUNS_TREE = SpriteImage(16,272,'fa-sitemap.png')
|
496
|
-
ACTION_NEW = SpriteImage(80,304,'fa-plus-circle.png')
|
497
|
-
ACTION_EDIT = SpriteImage(32,272,'fa-pencil.png')
|
498
|
-
ACTION_SELECT_FROM = SpriteImage(64,272,'fa-arrow-down.png')
|
499
|
-
ACTION_SELECT_TO = SpriteImage(64,256,'fa-arrow-up.png')
|
500
|
-
ACTION_COPY = SpriteImage(80,208,'clipboard-regular.png')
|
501
|
-
ACTION_PASTE = SpriteImage(0,64,'paste-solid.png')
|
502
|
-
ACTION_DUPLICATE = SpriteImage(48,208,'fa-files-o.png')
|
503
|
-
ACTION_DELETE = SpriteImage(16,176,'fa-trash-o.png')
|
504
|
-
ACTION_REFRESH = SpriteImage(32,144, 'fa-refresh.png')
|
505
|
-
ACTION_RENAME = SpriteImage(0,48,'rename.png')
|
506
|
-
ACTION_BROWSE = SpriteImage(32,304,'fa-folder-open.png')
|
507
|
-
ACTION_DB = SpriteImage(48,288,'fa-database.png')
|
508
|
-
ACTION_STOP = SpriteImage(16,256,'fa-stop.png')
|
509
|
-
ACTION_CONTINUE = SpriteImage(32,256,'fa-play-circle-o.png')
|
510
|
-
ACTION_STOP_WORKFLOW = SpriteImage(16,240,'fa-stop-workflow.png')
|
511
|
-
ACTION_RESULTS = SpriteImage(48,240,'fa-eye.png')
|
512
|
-
ACTION_SAVE = SpriteImage(32,112, 'fa-save.png')
|
481
|
+
RUNS_TREE = SpriteImage(16, 272, 'fa-sitemap.png')
|
482
|
+
ACTION_NEW = SpriteImage(80, 304, 'fa-plus-circle.png')
|
483
|
+
ACTION_EDIT = SpriteImage(32, 272, 'fa-pencil.png')
|
484
|
+
ACTION_SELECT_FROM = SpriteImage(64, 272, 'fa-arrow-down.png')
|
485
|
+
ACTION_SELECT_TO = SpriteImage(64, 256, 'fa-arrow-up.png')
|
486
|
+
ACTION_COPY = SpriteImage(80, 208, 'clipboard-regular.png')
|
487
|
+
ACTION_PASTE = SpriteImage(0, 64, 'paste-solid.png')
|
488
|
+
ACTION_DUPLICATE = SpriteImage(48, 208, 'fa-files-o.png')
|
489
|
+
ACTION_DELETE = SpriteImage(16, 176, 'fa-trash-o.png')
|
490
|
+
ACTION_REFRESH = SpriteImage(32, 144, 'fa-refresh.png')
|
491
|
+
ACTION_RENAME = SpriteImage(0, 48, 'rename.png')
|
492
|
+
ACTION_BROWSE = SpriteImage(32, 304, 'fa-folder-open.png')
|
493
|
+
ACTION_DB = SpriteImage(48, 288, 'fa-database.png')
|
494
|
+
ACTION_STOP = SpriteImage(16, 256, 'fa-stop.png')
|
495
|
+
ACTION_CONTINUE = SpriteImage(32, 256, 'fa-play-circle-o.png')
|
496
|
+
ACTION_STOP_WORKFLOW = SpriteImage(16, 240, 'fa-stop-workflow.png')
|
497
|
+
ACTION_RESULTS = SpriteImage(48, 240, 'fa-eye.png')
|
498
|
+
ACTION_SAVE = SpriteImage(32, 112, 'fa-save.png')
|
513
499
|
ACTION_VISUALIZE = ACTION_RESULTS
|
514
|
-
ACTION_WIZ = SpriteImage(32,288,'fa-magic.png')
|
515
|
-
ACTION_HELP = SpriteImage(32,160,'fa-question-circle.png')
|
516
|
-
ACTION_REFERENCES = SpriteImage(48,256,'link')
|
500
|
+
ACTION_WIZ = SpriteImage(32, 288, 'fa-magic.png')
|
501
|
+
ACTION_HELP = SpriteImage(32, 160, 'fa-question-circle.png')
|
502
|
+
ACTION_REFERENCES = SpriteImage(48, 256, 'link')
|
517
503
|
ACTION_EXPORT = ACTION_REFERENCES
|
518
|
-
ACTION_EXPORT_UPLOAD = SpriteImage(16,96, 'fa-upload.png')
|
519
|
-
ACTION_SEARCH = SpriteImage(32,96, 'fa-search.png')
|
520
|
-
SETTINGS = SpriteImage(48,304,'fa-cogs.png')
|
504
|
+
ACTION_EXPORT_UPLOAD = SpriteImage(16, 96, 'fa-upload.png')
|
505
|
+
ACTION_SEARCH = SpriteImage(32, 96, 'fa-search.png')
|
506
|
+
SETTINGS = SpriteImage(48, 304, 'fa-cogs.png')
|
521
507
|
ACTION_EXECUTE = SETTINGS
|
522
|
-
ACTION_IN = SpriteImage(16,304,'fa-sign-in.png')
|
523
|
-
ACTION_OUT = SpriteImage(16,288,'fa-sign-out.png')
|
524
|
-
ACTION_FIND_NEXT = SpriteImage(32,208,'fa-next.png')
|
525
|
-
ACTION_FIND_PREVIOUS = SpriteImage(32,192,'fa-previous.png')
|
526
|
-
ACTION_COLLAPSE = SpriteImage(32,240,'fa-minus-square.png')
|
527
|
-
ACTION_EXPAND = SpriteImage(32,224,'fa-plus-square.png')
|
528
|
-
ACTION_CIRCLE = SpriteImage(48,192,'circle.png')
|
508
|
+
ACTION_IN = SpriteImage(16, 304, 'fa-sign-in.png')
|
509
|
+
ACTION_OUT = SpriteImage(16, 288, 'fa-sign-out.png')
|
510
|
+
ACTION_FIND_NEXT = SpriteImage(32, 208, 'fa-next.png')
|
511
|
+
ACTION_FIND_PREVIOUS = SpriteImage(32, 192, 'fa-previous.png')
|
512
|
+
ACTION_COLLAPSE = SpriteImage(32, 240, 'fa-minus-square.png')
|
513
|
+
ACTION_EXPAND = SpriteImage(32, 224, 'fa-plus-square.png')
|
514
|
+
ACTION_CIRCLE = SpriteImage(48, 192, 'circle.png')
|
529
515
|
ACTION_PICKING = SpriteImage(64, 192, 'picking.png')
|
530
516
|
ACTION_STATS = SpriteImage(80, 192, 'stats.png')
|
531
517
|
ACTION_ZOOM = SpriteImage(64, 176, 'zoom.png')
|
@@ -536,38 +522,38 @@ class Icon:
|
|
536
522
|
|
537
523
|
|
538
524
|
# Host template
|
539
|
-
BUTTON_SELECT = SpriteImage(64,224,'fa-check.png')
|
540
|
-
BUTTON_CANCEL = SpriteImage(64,240,'fa-ban.png')
|
525
|
+
BUTTON_SELECT = SpriteImage(64, 224, 'fa-check.png')
|
526
|
+
BUTTON_CANCEL = SpriteImage(64, 240, 'fa-ban.png')
|
541
527
|
ACTION_CLOSE = BUTTON_CANCEL
|
542
528
|
BUTTON_CLOSE = ACTION_CLOSE
|
543
529
|
BUTTON_SAVE = ACTION_SAVE
|
544
530
|
|
545
531
|
ARROW_UP = ACTION_SELECT_TO
|
546
|
-
TAGS = SpriteImage(16,224,'fa-tags.png')
|
547
|
-
HOME = SpriteImage(0,304,'fa-home.png')
|
548
|
-
LIGHTBULB = SpriteImage(32,80,'fa-lightbulb-o.png')
|
549
|
-
ROCKET = SpriteImage(32,128, 'fa-rocket.png')
|
532
|
+
TAGS = SpriteImage(16, 224, 'fa-tags.png')
|
533
|
+
HOME = SpriteImage(0, 304, 'fa-home.png')
|
534
|
+
LIGHTBULB = SpriteImage(32, 80, 'fa-lightbulb-o.png')
|
535
|
+
ROCKET = SpriteImage(32, 128, 'fa-rocket.png')
|
550
536
|
|
551
537
|
# File browser icons
|
552
538
|
FOLDER_OPEN = ACTION_BROWSE
|
553
|
-
DB = SpriteImage(0,144,'file_sqlite.png')
|
554
|
-
TXT_FILE = SpriteImage(0,96,'file_text.png')
|
555
|
-
FILE_VOL = SpriteImage(0,80,'file_vol.png')
|
556
|
-
FILE_STACK = SpriteImage(0,112,'file_stack.png')
|
557
|
-
FILE_STACK_LINK = SpriteImage(0,128, 'file_stack_link.png')
|
558
|
-
PYTHON_FILE = SpriteImage(0,160,'file_python.png')
|
559
|
-
FILE_METADATA = SpriteImage(0,176,'file_md.png')
|
560
|
-
FILE_METADATA_LINK = SpriteImage(0,192, 'file_md_link.png')
|
561
|
-
FILE_IMAGE = SpriteImage(0,208, 'file_image.png')
|
562
|
-
FILE_IMAGE_LINK = SpriteImage(0,224, 'file_image_link.png')
|
563
|
-
FILE = SpriteImage(0,240, 'file_generic.png')
|
564
|
-
FILE_LINK = SpriteImage(0,256, 'file_generic_link.png')
|
565
|
-
FOLDER = SpriteImage(0,272, 'file_folder.png')
|
566
|
-
FOLDER_LINK = SpriteImage(0,288, 'file_folder_link.png')
|
567
|
-
|
568
|
-
BROOM = SpriteImage(80,240,'broom-solid.png')
|
569
|
-
BACKWARD = SpriteImage(80,288,'backward-solid.png')
|
570
|
-
CODE_BRANCH = SpriteImage(64,304,'code-branch-solid.png')
|
539
|
+
DB = SpriteImage(0, 144, 'file_sqlite.png')
|
540
|
+
TXT_FILE = SpriteImage(0, 96, 'file_text.png')
|
541
|
+
FILE_VOL = SpriteImage(0, 80, 'file_vol.png')
|
542
|
+
FILE_STACK = SpriteImage(0, 112, 'file_stack.png')
|
543
|
+
FILE_STACK_LINK = SpriteImage(0, 128, 'file_stack_link.png')
|
544
|
+
PYTHON_FILE = SpriteImage(0, 160, 'file_python.png')
|
545
|
+
FILE_METADATA = SpriteImage(0, 176, 'file_md.png')
|
546
|
+
FILE_METADATA_LINK = SpriteImage(0, 192, 'file_md_link.png')
|
547
|
+
FILE_IMAGE = SpriteImage(0, 208, 'file_image.png')
|
548
|
+
FILE_IMAGE_LINK = SpriteImage(0, 224, 'file_image_link.png')
|
549
|
+
FILE = SpriteImage(0, 240, 'file_generic.png')
|
550
|
+
FILE_LINK = SpriteImage(0, 256, 'file_generic_link.png')
|
551
|
+
FOLDER = SpriteImage(0, 272, 'file_folder.png')
|
552
|
+
FOLDER_LINK = SpriteImage(0, 288, 'file_folder_link.png')
|
553
|
+
|
554
|
+
BROOM = SpriteImage(80, 240, 'broom-solid.png')
|
555
|
+
BACKWARD = SpriteImage(80, 288, 'backward-solid.png')
|
556
|
+
CODE_BRANCH = SpriteImage(64, 304, 'code-branch-solid.png')
|
571
557
|
|
572
558
|
# Dialog icons
|
573
559
|
ERROR = 'fa-times-circle_alert.png'
|
@@ -585,20 +571,20 @@ class Icon:
|
|
585
571
|
CHIMERA = 'chimera.png'
|
586
572
|
|
587
573
|
# PLUGIN MANAGER ICONS
|
588
|
-
CHECKED = SpriteImage(64,208,'fa-checked.png')
|
589
|
-
UNCHECKED = SpriteImage(16,160,'fa-unchecked.png')
|
590
|
-
INSTALL = SpriteImage(32,64,'fa-install.png')
|
574
|
+
CHECKED = SpriteImage(64, 208, 'fa-checked.png')
|
575
|
+
UNCHECKED = SpriteImage(16, 160, 'fa-unchecked.png')
|
576
|
+
INSTALL = SpriteImage(32, 64, 'fa-install.png')
|
591
577
|
UNINSTALL = ACTION_CLOSE
|
592
|
-
TO_INSTALL = SpriteImage(32,256,'fa-to_install.png')
|
593
|
-
INSTALLED = SpriteImage(16, 64,'fa-installed.png')
|
594
|
-
PROCESSING = SpriteImage(32, 176, 'fa-processing.png',48,192)
|
595
|
-
FAILURE = SpriteImage(48,224,'fa-failure.png')
|
578
|
+
TO_INSTALL = SpriteImage(32, 256, 'fa-to_install.png')
|
579
|
+
INSTALLED = SpriteImage(16, 64, 'fa-installed.png')
|
580
|
+
PROCESSING = SpriteImage(32, 176, 'fa-processing.png', 48, 192)
|
581
|
+
FAILURE = SpriteImage(48, 224, 'fa-failure.png')
|
596
582
|
DELETE_OPERATION = ACTION_DELETE
|
597
|
-
TO_UPDATE = SpriteImage(32,144,'fa-update.png')
|
583
|
+
TO_UPDATE = SpriteImage(32, 144, 'fa-update.png')
|
598
584
|
WAITING = 'wait.gif'
|
599
|
-
ACTION_UNDO = SpriteImage(16,144,'fa-undo.png')
|
585
|
+
ACTION_UNDO = SpriteImage(16, 144, 'fa-undo.png')
|
600
586
|
|
601
|
-
PLUGIN_AUTHORS = SpriteImage(16,80,'users.png')
|
587
|
+
PLUGIN_AUTHORS = SpriteImage(16, 80, 'users.png')
|
602
588
|
PLUGIN_DESCRIPTION = FILE_STACK
|
603
589
|
PLUGIN_RELEASE_DATE = ACTION_EXPORT_UPLOAD
|
604
590
|
PLUGIN_VERSION = FILE_VOL
|
pyworkflow/utils/utils.py
CHANGED
@@ -22,6 +22,7 @@
|
|
22
22
|
# *
|
23
23
|
# **************************************************************************
|
24
24
|
import logging
|
25
|
+
|
25
26
|
logger = logging.getLogger(__name__)
|
26
27
|
|
27
28
|
import contextlib
|
@@ -36,7 +37,7 @@ import sysconfig
|
|
36
37
|
import bibtexparser
|
37
38
|
import numpy as np
|
38
39
|
import math
|
39
|
-
from pyworkflow.constants import StrColors
|
40
|
+
from pyworkflow.constants import StrColors, TRUE_YES_ON_
|
40
41
|
from pyworkflow import Config
|
41
42
|
|
42
43
|
|
@@ -705,7 +706,7 @@ def envVarOn(varName, env=None):
|
|
705
706
|
|
706
707
|
def strToBoolean(string):
|
707
708
|
""" Converts a string into a Boolean if the string is on of true, yes, on, 1. Case insensitive."""
|
708
|
-
return string is not None and string.lower() in
|
709
|
+
return string is not None and string.lower() in TRUE_YES_ON_
|
709
710
|
|
710
711
|
def strToDuration(durationStr):
|
711
712
|
""" Converts a string representing an elapsed time to seconds
|
pyworkflow/viewer.py
CHANGED
@@ -133,6 +133,22 @@ class Viewer(object):
|
|
133
133
|
self._keyPressed = args.get('keyPressed', None)
|
134
134
|
self._tkRoot = self.formWindow.root if self.formWindow else None
|
135
135
|
|
136
|
+
@classmethod
|
137
|
+
def can_handle_this(cls, classHierarchy, instance=None):
|
138
|
+
""" Returns none if it cannot handle the instance, otherwise returns which of the
|
139
|
+
classes of the hierarchy it targets (used for establishing priority"""
|
140
|
+
|
141
|
+
for t in cls._targets:
|
142
|
+
if t in classHierarchy:
|
143
|
+
|
144
|
+
if instance is not None and not cls.can_handle_this_instance(instance):
|
145
|
+
return None
|
146
|
+
else:
|
147
|
+
return t
|
148
|
+
|
149
|
+
@classmethod
|
150
|
+
def can_handle_this_instance(cls, instance):
|
151
|
+
return True
|
136
152
|
def getKeyPressed(self):
|
137
153
|
return self._keyPressed
|
138
154
|
|
@@ -222,6 +238,8 @@ class ProtocolViewer(Viewer, pwprot.Protocol):
|
|
222
238
|
If should provide a mapping between form params and the corresponding
|
223
239
|
functions that will return the corresponding Views.
|
224
240
|
"""
|
241
|
+
|
242
|
+
_label ="Protocol viewer"
|
225
243
|
def __init__(self, **kwargs):
|
226
244
|
# Here we are going to intercept the original _defineParams function
|
227
245
|
# and replace by an empty one, this is to postpone the definition of
|
@@ -241,7 +259,11 @@ class ProtocolViewer(Viewer, pwprot.Protocol):
|
|
241
259
|
|
242
260
|
def getWindow(self):
|
243
261
|
return self.formWindow
|
244
|
-
|
262
|
+
|
263
|
+
@classmethod
|
264
|
+
def getName(cls):
|
265
|
+
return cls._label
|
266
|
+
|
245
267
|
def getTkRoot(self):
|
246
268
|
return self._tkRoot
|
247
269
|
|
pyworkflow/webservices/config.py
CHANGED
@@ -1,9 +1,6 @@
|
|
1
1
|
# Variable related to the online services (workflow stats and repository) that Scipion reports to or communicate.
|
2
2
|
# These variables may change between Scipion versions but do not depend on the user or system
|
3
3
|
|
4
|
-
# Web that gathers protocol usage
|
5
|
-
SCIPION_STATS_SERVER = 'https://scipion.i2pc.es'
|
6
|
-
SCIPION_STATS_WORKFLOW_APP = SCIPION_STATS_SERVER + '/report_protocols/api/workflow/workflow/'
|
7
4
|
|
8
5
|
# Web that handles workflows
|
9
6
|
WORKFLOW_REPOSITORY_SERVER = 'https://workflows.scipion.i2pc.es/'
|
@@ -34,9 +34,9 @@ from datetime import timedelta, datetime
|
|
34
34
|
from urllib.parse import urlencode
|
35
35
|
from urllib.request import build_opener, HTTPHandler
|
36
36
|
|
37
|
-
import pyworkflow
|
38
37
|
import pyworkflow.utils as pwutils
|
39
|
-
from
|
38
|
+
from pyworkflow import Config
|
39
|
+
|
40
40
|
|
41
41
|
|
42
42
|
class ProjectWorkflowNotifier(object):
|
@@ -79,18 +79,32 @@ class ProjectWorkflowNotifier(object):
|
|
79
79
|
|
80
80
|
return delta < timedelta(seconds=seconds)
|
81
81
|
|
82
|
-
def _sendData(self, url,
|
82
|
+
def _sendData(self, url, project_workflow):
|
83
83
|
try:
|
84
84
|
# then connect to webserver a send json
|
85
85
|
# set debuglevel=0 for no messages
|
86
|
+
|
87
|
+
dataDict = {'project_uuid': self._getUuid(),
|
88
|
+
'project_workflow': project_workflow}
|
89
|
+
|
86
90
|
opener = build_opener(HTTPHandler(debuglevel=0))
|
87
91
|
data = urlencode(dataDict).encode()
|
88
|
-
|
92
|
+
opener.open(url, data=data).read()
|
93
|
+
|
94
|
+
# Store file time stamp with last time it was sent
|
89
95
|
now = time.time()
|
90
96
|
os.utime(self._getUuidFileName(), (now, now))
|
97
|
+
|
98
|
+
# Write what was sent in a file for _modifiedBefore to check file TS and avoid resending stats
|
99
|
+
dataFile = self._getDataFileName()
|
100
|
+
# create the folder of the file path if not exists
|
101
|
+
pwutils.makeFilePath(dataFile)
|
102
|
+
with open(dataFile, 'w') as f:
|
103
|
+
f.write(project_workflow)
|
104
|
+
|
91
105
|
except Exception as e:
|
106
|
+
# Tolerate errors
|
92
107
|
pass
|
93
|
-
# print("Could not notify, maybe there is not internet connection.")
|
94
108
|
|
95
109
|
def _dataModified(self, projectWorfklow):
|
96
110
|
try:
|
@@ -106,12 +120,13 @@ class ProjectWorkflowNotifier(object):
|
|
106
120
|
|
107
121
|
try:
|
108
122
|
# check if environment exists otherwise abort
|
109
|
-
if not
|
123
|
+
if not Config.SCIPION_NOTIFY:
|
110
124
|
return
|
111
125
|
|
112
126
|
# if project specifies not to send stats
|
113
127
|
if self._isProjectMuted():
|
114
128
|
return
|
129
|
+
|
115
130
|
# Check the seconds range of the notify, by default one day
|
116
131
|
seconds = int(os.environ.get('SCIPION_NOTIFY_SECONDS', '86400'))
|
117
132
|
|
@@ -120,28 +135,11 @@ class ProjectWorkflowNotifier(object):
|
|
120
135
|
|
121
136
|
# INFO: now we are only sending the protocols names in the project.
|
122
137
|
# We could pass namesOnly=False to get the full workflow template
|
123
|
-
|
124
|
-
|
125
|
-
# if list with workflow has not been altered do not sent it
|
126
|
-
if not self._dataModified(projectWorfklow):
|
127
|
-
return
|
128
|
-
else:
|
129
|
-
# For compatibility with version 1.0 check
|
130
|
-
# if Log directory exists. If it does not
|
131
|
-
# create it
|
132
|
-
# TODO: REMOVE this check in scipion 1.3
|
133
|
-
dataFile = self._getDataFileName()
|
134
|
-
# create the folder of the file path if not exists
|
135
|
-
pwutils.makeFilePath(dataFile)
|
136
|
-
with open(dataFile, 'w') as f:
|
137
|
-
f.write(projectWorfklow)
|
138
|
-
dataDict = {'project_uuid': self._getUuid(),
|
139
|
-
'project_workflow': projectWorfklow}
|
138
|
+
project_workflow = self.project.getProjectUsage().toJSON() # self.project.getProtocolsJson(namesOnly=True)
|
140
139
|
|
141
|
-
urlName =
|
142
|
-
config.SCIPION_STATS_WORKFLOW_APP).strip()
|
140
|
+
urlName = Config.SCIPION_STATS_WORKFLOW_APP.strip()
|
143
141
|
urlName += "addOrUpdateWorkflow/"
|
144
|
-
t = threading.Thread(name="notifier", target=lambda: self._sendData(urlName,
|
142
|
+
t = threading.Thread(name="notifier", target=lambda: self._sendData(urlName, project_workflow))
|
145
143
|
t.start() # will execute function in a separate thread
|
146
144
|
except Exception as e:
|
147
145
|
print("Can't report usage: ", e)
|
@@ -152,11 +150,3 @@ class ProjectWorkflowNotifier(object):
|
|
152
150
|
a test and therefore no statistics will be sent"""
|
153
151
|
return os.path.basename(self.project.name).startswith("Test")
|
154
152
|
|
155
|
-
def getEntryFromWebservice(self, uuid):
|
156
|
-
if not pyworkflow.Config.SCIPION_NOTIFY:
|
157
|
-
return
|
158
|
-
urlName = os.environ.get('SCIPION_NOTIFY_URL').strip()
|
159
|
-
# remove last directory
|
160
|
-
urlName = os.path.split(urlName)[0]
|
161
|
-
url = urlName + "/?project_uuid=" + uuid
|
162
|
-
resultDict = self._sendData(url)
|
pyworkflowtests/protocols.py
CHANGED
@@ -69,9 +69,7 @@ class ParallelSleepingProtocol(SleepingProtocol):
|
|
69
69
|
class ConcurrencyProtocol(SleepingProtocol):
|
70
70
|
""" Protocol to test concurrency access to sets"""
|
71
71
|
|
72
|
-
|
73
|
-
super().__init__(**kwargs)
|
74
|
-
self.stepsExecutionMode = pwprot.STEPS_PARALLEL
|
72
|
+
stepsExecutionMode = pwprot.STEPS_PARALLEL
|
75
73
|
|
76
74
|
def _defineParams(self, form):
|
77
75
|
form.addParallelSection(threads=2, mpi=0)
|
@@ -98,6 +98,10 @@ class TestProtocolExecution(pwtests.BaseTest):
|
|
98
98
|
|
99
99
|
|
100
100
|
currThread = threading.currentThread()
|
101
|
+
def needForGPU():
|
102
|
+
return True
|
103
|
+
|
104
|
+
currThread.needsGPU =needForGPU
|
101
105
|
currThread.thId = 1
|
102
106
|
self.assertEqual(stepExecutor.getGpuList(),[], "Gpu list should be empty")
|
103
107
|
|
@@ -1,22 +1,15 @@
|
|
1
1
|
Metadata-Version: 2.4
|
2
2
|
Name: scipion-pyworkflow
|
3
|
-
Version: 3.
|
4
|
-
Summary:
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
Project-URL:
|
9
|
-
Project-URL:
|
10
|
-
Keywords:
|
11
|
-
|
12
|
-
|
13
|
-
Classifier: License :: OSI Approved :: GNU General Public License v3 (GPLv3)
|
14
|
-
Classifier: Programming Language :: Python :: 3.8
|
15
|
-
Classifier: Programming Language :: Python :: 3.9
|
16
|
-
Classifier: Programming Language :: Python :: 3.10
|
17
|
-
Classifier: Programming Language :: Python :: 3.11
|
18
|
-
Classifier: Programming Language :: Python :: 3.12
|
19
|
-
Classifier: Topic :: Scientific/Engineering
|
3
|
+
Version: 3.11.1
|
4
|
+
Summary: Workflow platform used in scientific applications, initially developed within the Scipion framework for image processing in Electron Microscopy but generic by design to be applied to any domain.
|
5
|
+
Author-email: Pablo Conesa <pconesa@cnb.csic.es>, Yunior Fonseca <cfonseca@cnb.csic.es>, "J.M. De la Rosa Trevin" <josemiguel.delarosatrevin@stjude.org>, Roberto Marabini <roberto@cnb.csic.es>, Grigory Sharov <sharov.grigory@gmail.com>, Josue Gomez Blanco <josue.gomez-blanco@mcgill.ca>
|
6
|
+
License: GNU General Public License v3 (GPLv3)
|
7
|
+
Project-URL: Homepage, https://scipion.i2pc.es
|
8
|
+
Project-URL: Repository, https://github.com/scipion-em/scipion-pyworkflow
|
9
|
+
Project-URL: Issues, https://github.com/scipion-em/scipion-pyworkflow/issues
|
10
|
+
Keywords: scipion,electron-microscopy,cryo-em,structural-biology,generic-workflow-engine,image-processing,scipion-3.0
|
11
|
+
Requires-Python: >=3.8
|
12
|
+
Description-Content-Type: text/x-rst
|
20
13
|
License-File: LICENSE.txt
|
21
14
|
Requires-Dist: bibtexparser<=1.4.1
|
22
15
|
Requires-Dist: psutil<=5.9.6
|
@@ -27,19 +20,12 @@ Requires-Dist: pillow==10.1.0; python_version >= "3.8"
|
|
27
20
|
Requires-Dist: numpy==1.24.4; python_version == "3.8"
|
28
21
|
Requires-Dist: numpy==1.26.1; python_version >= "3.9"
|
29
22
|
Requires-Dist: requests==2.31.0; python_version >= "3.8"
|
30
|
-
Requires-Dist:
|
23
|
+
Requires-Dist: tkcolorpicker2
|
31
24
|
Requires-Dist: distro<=1.8
|
32
25
|
Requires-Dist: importlib-metadata<=6.8.0
|
33
|
-
|
34
|
-
|
35
|
-
Dynamic: classifier
|
36
|
-
Dynamic: description
|
37
|
-
Dynamic: home-page
|
38
|
-
Dynamic: keywords
|
26
|
+
Requires-Dist: setuptools>=62.6
|
27
|
+
Requires-Dist: pyperclip==1.9.0
|
39
28
|
Dynamic: license-file
|
40
|
-
Dynamic: project-url
|
41
|
-
Dynamic: requires-dist
|
42
|
-
Dynamic: summary
|
43
29
|
|
44
30
|
.. image:: https://img.shields.io/pypi/v/scipion-pyworkflow.svg
|
45
31
|
:target: https://pypi.python.org/pypi/scipion-pyworkflow
|