14
14
import ruamel .yaml as ryaml
15
15
import six
16
16
import cwlgen
17
+ import cwlgen .workflow
17
18
18
19
logging .basicConfig (level = logging .INFO )
19
20
logger = logging .getLogger (__name__ )
20
21
21
22
# Class(es) ------------------------------
22
23
24
+ def parse_cwl (cwl_path ):
25
+ with open (cwl_path ) as yaml_file :
26
+ cwl_dict = ryaml .load (yaml_file , Loader = ryaml .Loader )
27
+ cl = cwl_dict ['class' ]
28
+
29
+ if cl == "CommandLineTool" :
30
+ p = CWLToolParser ()
31
+ return p .import_cwl (cwl_path )
32
+ if cl == "Workflow" :
33
+ p = CWLToolParser ()
34
+ return p .import_cwl (cwl_path )
35
+ return None
23
36
24
37
class CWLToolParser (object ):
25
38
"""
@@ -46,6 +59,12 @@ def _load_id(self, tool, id_el):
46
59
"""
47
60
tool .id = id_el
48
61
62
+ def _load_requirements (self , tool , req_el ):
63
+ pass
64
+
65
+ def _load_hints (self , tool , req_el ):
66
+ pass
67
+
49
68
def _load_baseCommand (self , tool , command_el ):
50
69
"""
51
70
Load the content of baseCommand into the tool.
@@ -178,6 +197,15 @@ def import_cwl(self, cwl_path):
178
197
logger .warning (key + " content is not processed (yet)." )
179
198
return tool
180
199
200
+ def dict_or_idlist_items (v ):
201
+ if isinstance (v , dict ):
202
+ return v .items ()
203
+ o = []
204
+ for i in v :
205
+ e = dict (i )
206
+ del e ['id' ]
207
+ o .append ( (i ['id' ], e ) )
208
+ return o
181
209
182
210
class InputsParser (object ):
183
211
"""
@@ -283,7 +311,7 @@ def load_inputs(self, inputs, inputs_el):
283
311
:type inputs_el: LIST or DICT
284
312
"""
285
313
# For the moment, only deal with the format exported by cwlgen
286
- for key , value in inputs_el . items ( ):
314
+ for key , value in dict_or_idlist_items ( inputs_el ):
287
315
input_obj = cwlgen .CommandInputParameter (key )
288
316
for key , element in value .items ():
289
317
try :
@@ -476,6 +504,17 @@ def _load_type(self, output_obj, type_el):
476
504
"""
477
505
output_obj .type = type_el
478
506
507
+ def _load_outputSource (self , output_obj , type_el ):
508
+ """
509
+ Load the content of type into the output object.
510
+
511
+ :param output_obj: output obj
512
+ :type output_obj: : :class:`cwlgen.CommandInputParameter`
513
+ :param type_el: Content of type
514
+ :type type_el: STRING
515
+ """
516
+ output_obj .outputSource = type_el
517
+
479
518
def load_outputs (self , outputs , outputs_el ):
480
519
"""
481
520
Load the content of outputs into the outputs list.
@@ -486,7 +525,7 @@ def load_outputs(self, outputs, outputs_el):
486
525
:type outputs_el: LIST or DICT
487
526
"""
488
527
# For the moment, only deal with the format exported by cwlgen
489
- for key , value in outputs_el . items ( ):
528
+ for key , value in dict_or_idlist_items ( outputs_el ):
490
529
output_obj = cwlgen .CommandOutputParameter (key )
491
530
for key , element in value .items ():
492
531
try :
@@ -550,3 +589,160 @@ def load_outbinding(self, output_obj, outbinding_el):
550
589
except AttributeError :
551
590
logger .warning (key + " content for outputBinding is not processed (yet)." )
552
591
output_obj .outputBinding = outbinding_obj
592
+
593
+
594
+ class StepsParser (object ):
595
+ """
596
+ Class to parse content of steps of workflow from existing CWL Workflow.
597
+ """
598
+ def __init__ (self , basedir = None ):
599
+ self .basedir = basedir
600
+
601
+ def _load_in (self , step_obj , in_el ):
602
+ for key , val in in_el .items ():
603
+ o = cwlgen .workflow .WorkflowStepInput (key )
604
+ if isinstance (val , dict ) and 'default' in val :
605
+ o .default = val ['default' ]
606
+ else :
607
+ o .src = val
608
+ step_obj .inputs .append (o )
609
+
610
+ def _load_out (self , step_obj , in_el ):
611
+ for val in in_el :
612
+ o = cwlgen .workflow .WorkflowStepOutput (val )
613
+ step_obj .outputs .append (o )
614
+
615
+ def _load_run (self , step_obj , in_el ):
616
+ if isinstance (in_el , basestring ):
617
+ path = os .path .join (self .basedir , in_el )
618
+ #logger.info("Parsing: %s", path)
619
+ step_obj .run = parse_cwl (path )
620
+
621
+
622
+ def load_steps (self , steps_obj , steps_elm ):
623
+ """
624
+ Load the content of step into the output object.
625
+
626
+ :param output_obj: output object
627
+ :type output_obj: :class:`cwlgen.CommandOutputParameter`
628
+ :param outbinding_el: Content of outputBinding element
629
+ :type outbinding_el: DICT
630
+ """
631
+ for key , value in steps_elm .items ():
632
+ step_obj = cwlgen .workflow .WorkflowStep (key )
633
+ for key , element in value .items ():
634
+ try :
635
+ getattr (self , '_load_{}' .format (key ))(step_obj , element )
636
+ except AttributeError :
637
+ logger .warning (key + " content for input is not processed (yet)." )
638
+ steps_obj .append (step_obj )
639
+
640
+
641
+ class CWLWorkflowParser (object ):
642
+
643
+ def __init__ (self , basedir = None ):
644
+ self .basedir = basedir
645
+
646
+ def _init_workflow (self , cwl_dict ):
647
+ """
648
+ Init tool from existing CWL tool.
649
+
650
+ :param cwl_dict: Full content of CWL file
651
+ :type cwl_dict: DICT
652
+ """
653
+ return cwlgen .workflow .Workflow ()
654
+
655
+ def import_cwl (self , cwl_path ):
656
+ """
657
+ Load content of cwl into the :class:`cwlgen.workflow.Workflow` object.
658
+
659
+ :param cwl_path: Path of the CWL tool to be loaded.
660
+ :type cwl_path: STRING
661
+ :return: CWL tool content in cwlgen model.
662
+ :rtype: :class:`cwlgen.workflow.Workflow`
663
+ """
664
+ with open (cwl_path ) as yaml_file :
665
+ cwl_dict = ryaml .load (yaml_file , Loader = ryaml .Loader )
666
+ tool = self ._init_workflow (cwl_dict )
667
+ self .basedir = os .path .dirname (cwl_path )
668
+ for key , element in cwl_dict .items ():
669
+ try :
670
+ getattr (self , '_load_{}' .format (key ))(tool , element )
671
+ except AttributeError :
672
+ logger .warning (key + " workflow content is not processed (yet)." )
673
+ return tool
674
+
675
+ def _load_id (self , tool , id_el ):
676
+ """
677
+ Load the content of id into the tool.
678
+
679
+ :param tool: Tool object from cwlgen
680
+ :type tool: :class:`cwlgen.CommandLineTool`
681
+ :param id_el: Content of id
682
+ :type id_el: STRING or [STRING]
683
+ """
684
+ tool .id = id_el
685
+
686
+ def _load_cwlVersion (self , tool , cwl_version_el ):
687
+ """
688
+ Load the content of cwlVersion into the tool.
689
+
690
+ :param tool: Tool object from cwlgen
691
+ :type tool: :class:`cwlgen.workflow.Workflow`
692
+ :param cwl_version_el: Content of cwlVersion
693
+ :type cwl_version_el: STRING
694
+ """
695
+ tool .cwlVersion = cwl_version_el
696
+
697
+
698
+ def _load_class (self , tool , class_el ):
699
+ """
700
+ Display message to inform that cwlgen only deal with Workflow for the moment.
701
+
702
+ :param tool: Workflow object from cwlgen
703
+ :type tool: :class:`cwlgen.workflow.Workflow`
704
+ :param class_el: Content of class
705
+ :type class_el: STRING
706
+ """
707
+ if class_el != 'Workflow' :
708
+ logger .warning ('cwlgen library only handle Workflow for the moment' )
709
+
710
+ def _load_requirements (self , tool , req_el ):
711
+ pass
712
+
713
+ def _load_inputs (self , tool , inputs_el ):
714
+ """
715
+ Load the content of inputs into the tool.
716
+
717
+ :param tool: Tool object from cwlgen
718
+ :type tool: :class:`cwlgen.workflow.Workflow`
719
+ :param inputs_el: Content of inputs
720
+ :type inputs_el: LIST or DICT
721
+ """
722
+ inp_parser = InputsParser ()
723
+ inp_parser .load_inputs (tool .inputs , inputs_el )
724
+
725
+ def _load_outputs (self , tool , outputs_el ):
726
+ """
727
+ Load the content of inputs into the tool.
728
+
729
+ :param tool: Tool object from cwlgen
730
+ :type tool: :class:`cwlgen.workflow.Workflow`
731
+ :param outputs_el: Content of outputs
732
+ :type outputs_el: LIST or DICT
733
+ """
734
+ inp_parser = OutputsParser ()
735
+ inp_parser .load_outputs (tool .outputs , outputs_el )
736
+
737
+
738
+ def _load_steps (self , tool , outputs_el ):
739
+ """
740
+ Load the content of inputs into the tool.
741
+
742
+ :param tool: Tool object from cwlgen
743
+ :type tool: :class:`cwlgen.workflow.Workflow`
744
+ :param outputs_el: Content of outputs
745
+ :type outputs_el: LIST or DICT
746
+ """
747
+ inp_parser = StepsParser (self .basedir )
748
+ inp_parser .load_steps (tool .steps , outputs_el )
0 commit comments