
    5il                         d Z ddlmZmZmZmZ ddlZddlZddlm	Z	 ddl
mZmZmZ ddlmZ ddlmZ dd	Z G d
 dee      Zy)z
DXWorkflow Handler
++++++++++++++++++

Workflows are data objects which contain metadata for a set of jobs to
be run together.  They can be run by calling the
:func:`DXWorkflow.run` method.

    )print_functionunicode_literalsdivisionabsolute_importN   )SystemRequirementsDict)DXDataObjectDXExecutable
DXAnalysis)DXError)
basestringc           	      J    t               } |j                  d| ||||d| |S )am  
    :param title: Workflow title (optional)
    :type title: string
    :param summary: Workflow summary (optional)
    :type summary: string
    :param description: Workflow description (optional)
    :type description: string
    :param output_folder: Default output folder of the workflow (optional)
    :type output_folder: string
    :param init_from: Another analysis workflow object handler or and analysis (string or handler) from which to initialize the metadata (optional)
    :type init_from: :class:`~dxpy.bindings.dxworkflow.DXWorkflow`, :class:`~dxpy.bindings.dxanalysis.DXAnalysis`, or string (for analysis IDs only)
    :rtype: :class:`DXWorkflow`

    Additional optional parameters not listed: all those under
    :func:`dxpy.bindings.DXDataObject.new`, except `details`.

    Creates a new remote workflow object with project set to *project*
    and returns the appropriate handler.

    Example:

        r = dxpy.new_dxworkflow(title="My Workflow", description="This workflow contains...")

    Note that this function is shorthand for::

        dxworkflow = DXWorkflow()
        dxworkflow.new(**kwargs)
    )titlesummarydescriptionoutput_folder	init_from )
DXWorkflownew)r   r   r   r   r   kwargs
dxworkflows          z/home/marpiech/ifpan-abm-pgxpred/analysis/marpiech-gwas-test/venv/lib/python3.12/site-packages/dxpy/bindings/dxworkflow.pynew_dxworkflowr   (   s?    : JJNN  F[Xeqz  F  E  F    c                   <    e Zd ZdZdZ eej                  j                        Z	 eej                  j                        Z eej                  j                        Z eej                  j                        Z eej                  j                         Z eej                  j$                        Z eej                  j(                        Z eej                  j,                        Z eej                  j0                        Z eej                  j4                        Z eej                  j8                        Z eej                  j<                        Zd Z ddZ!d Z"	 	 ddZ#d Z$ddZ%dd	Z&	 	 	 	 	 dd
Z'	 	 	 ddZ(d Z)ddZ*d Z+d Z,d Z- fdZ. xZ/S )r   z
    Remote workflow object handler.  This class is used for the
    workflow class data objects which produce an analysis when run.
    workflowc                    dd}d|v r|d   t        |d   t        t        f      sEt        |d   t              r't	        j
                  d      j                  |d         st        d      t        |d   t              rd|d   i|d<   nDd|d   j                         i|d<   t        |d   t              r|d   j                         |d   d<   |d=  |||d	        |||d
        |||d        |||dd        |||d        |||dd        |||dd       t        j                  j                  |fi |}| j                  |d   |d          y)a  
        :param dx_hash: Standard hash populated in :func:`dxpy.bindings.DXDataObject.new()` containing attributes common to all data object classes.
        :type dx_hash: dict
        :param title: Workflow title (optional)
        :type title: string
        :param summary: Workflow summary (optional)
        :type summary: string
        :param description: Workflow description (optional)
        :type description: string
        :param output_folder: Default output folder of the workflow (optional)
        :type output_folder: string
        :param stages: Stages of the workflow (optional)
        :type stages: array of dictionaries
        :param workflow_inputs: Workflow-level input specification (optional)
        :type workflow_inputs: array of dictionaries
        :param workflow_outputs: Workflow-level output specification (optional)
        :type workflow_outputs: array of dictionaries
        :param init_from: Another analysis workflow object handler or and analysis (string or handler) from which to initialize the metadata (optional)
        :type init_from: :class:`~dxpy.bindings.dxworkflow.DXWorkflow`, :class:`~dxpy.bindings.dxanalysis.DXAnalysis`, or string (for analysis IDs only)

        Create a new remote workflow object.
        Nc                 :    ||n|}|| v r| |   | |   ||<   | |= y y Nr   )r   dxhashkeynew_keys       r   _set_dx_hashz%DXWorkflow._new.<locals>._set_dx_hashv   s7    $_c'Gf}#;*&,SkF7O3K r   r   z^analysis-[0-9A-Za-z]{24}$z`Expected init_from to be an instance of DXWorkflow or DXAnalysis, or to be a string analysis ID.idinitializeFromprojectr   r   r   r   outputFolderstagesworkflow_inputsinputsworkflow_outputsoutputsr    )
isinstancer   r   r   recompilematchr   get_idget_proj_iddxpyapiworkflow_newset_ids)selfdx_hashr   r$   resps        r   _newzDXWorkflow._new^   st   0	  & k"."6+#6Z8PQ#F;$7D$@AGG{H[\!  #E  F  Ff[1:>15vk7J0KG,-15vk7J7Q7Q7S0TG,-!&"5zB?Ek?R?^?^?` 01)<{#VWg.VWi0VWm4VWo~FVWh/VW&7BVW&8)Dxx$$W77T$Z!34r   c                 2    || j                   |d<   y ||d<   y )NeditVersion)r=   )r8   request_hashedit_versions      r   _add_edit_version_to_requestz'DXWorkflow._add_edit_version_to_request   s"    *.*:*:L'*6L'r   c                 4   t        |t              r	 t        |      }t        |t              st	 t        |      }|dk  s|t	        | j
                        k\  r-t        dt        t	        | j
                              z   dz         | j
                  |   j                  d      S t        j                  d      j                  |      ?t        | j
                  D cg c]  }|j                  d      |k(  s|d    c}      }|r|S | j
                  D cg c]  }|j                  d      |k(  s|d    }}t	        |      dk(  rt        d|z   d	z         t	        |      d
kD  rt        d|z   dz         |d   S #  Y `xY w#  t        d      xY wc c}w c c}w )a  
        :param stage: A stage ID, name, or index (stage index is the number n for the nth stage, starting from 0; can be provided as an int or a string)
        :type stage: int or string
        :returns: The stage ID (this is a no-op if it was already a stage ID)
        :raises: :class:`~dxpy.exceptions.DXError` if *stage* could not be parsed, resolved to a stage ID, or it could not be found in the workflow
        zYDXWorkflow: the given stage identifier was neither a string stage ID nor an integer indexr   z"DXWorkflow: the workflow contains zP stage(s), and the numerical value of the given stage identifier is out of ranger%   z!^([a-zA-Z_]|stage-)[0-9a-zA-Z_]*$namez'DXWorkflow: the given stage identifier z5 could not be found as a stage ID nor as a stage name   zEDXWorkflow: more than one workflow stage was found to have the name "")r.   r   intr   lenr)   strgetr/   r0   r1   any)r8   stagestage_indexstgstage_id_existsstage_ids_matching_names         r   _get_stage_idzDXWorkflow._get_stage_id   s    eZ(E

 %,{!%j Q+T[[1A"ABST[[IYEZZpq r r;;{+//55::9:@@GS!"^swwt}X]G]3t9"^_O 9="`swwvZ_G_3t9"`"`&'1,CeK  OF  F  G  G()A-adiiloopp*1--;{yzz #_
 #as.   E8 F  F2FF,F8E= Fc                    t        |t              r|}	n,t        |t              r|j                         }	nt	        d      d|	i}
|||
d<   |||
d<   |||
d<   |||
d<   |&t        j                  |      j                         |
d<   | j                  |
|       	 t        j                  j                  | j                  |
fi |}| j                          |d   S # | j                          w xY w)	a  
        :param executable: string or a handler for an app or applet
        :type executable: string, DXApplet, or DXApp
        :param stage_id: id for the stage (optional)
        :type stage_id: string
        :param name: name for the stage (optional)
        :type name: string
        :param folder: default output folder for the stage; either a relative or absolute path (optional)
        :type folder: string
        :param stage_input: input fields to bind as default inputs for the executable (optional)
        :type stage_input: dict
        :param instance_type: Default instance type on which all jobs will be run for this stage, or a dict mapping function names to instance type requests
        :type instance_type: string or dict
        :param edit_version: if provided, the edit version of the workflow that should be modified; if not provided, the current edit version will be used (optional)
        :type edit_version: int
        :returns: ID of the added stage
        :rtype: string
        :raises: :class:`~dxpy.exceptions.DXError` if *executable* is not an expected type :class:`~dxpy.exceptions.DXAPIError` for errors thrown from the API call

        Adds the specified executable as a new stage in the workflow.
        zZdxpy.DXWorkflow.add_stage: executable must be a string or an instance of DXApplet or DXApp
executabler%   rB   folderinputsystemRequirementsrJ   )r.   r   r
   r2   r   r   from_instance_typeas_dictr@   r4   r5   workflow_add_stage_dxiddescribe)r8   rQ   stage_idrB   rR   stage_inputinstance_typer?   r   exec_idadd_stage_inputresults               r   	add_stagezDXWorkflow.add_stage   s    . j*- G
L1 '')Gvww'1$,OD!&*OF#(.OH%"'2OG$$4J4]4]^k4l4t4t4vO01))/<H	XX00_WPVWFMMOg MMOs   +C C-c                     | j                  |      t        fd| j                  D        d      }|t        dz   dz         |S )z
        :param stage: A number for the stage index (for the nth stage, starting from 0), or a string of the stage index, name, or ID
        :type stage: int or string
        :returns: Hash of stage descriptor in workflow
        c              3   4   K   | ]  }|d    k(  s|  yw)r%   Nr   ).0rJ   rZ   s     r   	<genexpr>z'DXWorkflow.get_stage.<locals>.<genexpr>   s     Qt9PuQs   NzThe stage ID z could not be found)rO   nextr)   r   )r8   rJ   r   r_   rZ   s       @r   	get_stagezDXWorkflow.get_stage   sL     %%e,Q$++QSWX>/H47LLMMr   c                     | j                  |      }d|i}| j                  ||       	 t        j                  j                  | j
                  |fi | | j                          |S # | j                          w xY w)a  
        :param stage: A number for the stage index (for the nth stage, starting from 0), or a string of the stage index, name, or ID
        :type stage: int or string
        :param edit_version: if provided, the edit version of the workflow that should be modified; if not provided, the current edit version will be used (optional)
        :type edit_version: int
        :returns: Stage ID that was removed
        :rtype: string

        Removes the specified stage from the workflow
        rJ   )rO   r@   r4   r5   workflow_remove_stagerX   rY   )r8   rJ   r?   r   rZ   remove_stage_inputs         r   remove_stagezDXWorkflow.remove_stage  sn     %%e,%x0))*<lK	HH**4::7ITVTMMO MMOs   +A& &A8c                     | j                  |      }||d}| j                  ||       	 t        j                  j                  | j
                  |fi | | j                          y# | j                          w xY w)aV  
        :param stage: A number for the stage index (for the nth stage, starting from 0), or a string of the stage index, name, or ID
        :type stage: int or string
        :param new_index: The new position in the order of stages that the specified stage should have (where 0 indicates the first stage)
        :type new_index: int
        :param edit_version: if provided, the edit version of the workflow that should be modified; if not provided, the current edit version will be used (optional)
        :type edit_version: int

        Removes the specified stage from the workflow
        )rJ   newIndexN)rO   r@   r4   r5   workflow_move_stagerX   rY   )r8   rJ   	new_indexr?   r   rZ   move_stage_inputs          r   
move_stagezDXWorkflow.move_stage  si     %%e,%-(13))*:LI	HH((5EPPMMODMMOs   +A& &A8c                    i }||rt        d      ||rt        d      ||rt        d      |	|
rt        d      |||d<   n|rd|d<   |||d<   |||d<   |||d	<   n|rd|d	<   |||d
<   |||d<   n|rd|d<   |	|	|d<   n|
rd|d<   |rO| j                  ||       	 t        j                  j                  | j
                  |fi | | j                          yy# | j                          w xY w)a  
        :param title: workflow title to set; cannot be provided with *unset_title* set to True
        :type title: string
        :param unset_title: whether to unset the title; cannot be provided with string value for *title*
        :type unset_title: boolean
        :param summary: workflow summary to set
        :type summary: string
        :param description: workflow description to set
        :type description: string
        :param output_folder: new default output folder for the workflow
        :type output_folder: string
        :param unset_folder: whether to unset the default output folder; cannot be True with string value for *output_folder*
        :type unset_folder: boolean
        :param stages: updates to the stages to make; see API documentation for /workflow-xxxx/update for syntax of this field; use :meth:`update_stage()` to update a single stage
        :type stages: dict
        :param workflow_inputs: updates to the workflow input to make; see API documentation for /workflow-xxxx/update for syntax of this field
        :type workflow_inputs: dict
        :param workflow_outputs: updates to the workflow output to make; see API documentation for /workflow-xxxx/update for syntax of this field
        :type workflow_outputs: dict
        :param edit_version: if provided, the edit version of the workflow that should be modified; if not provided, the current edit version will be used (optional)
        :type edit_version: int

        Make general metadata updates to the workflow
        NzIdxpy.DXWorkflow.update: cannot provide both "title" and set "unset_title"zYdxpy.DXWorkflow.update: cannot provide both "output_folder" and set "unset_output_folder"z]dxpy.DXWorkflow.update: cannot provide both "workflow_inputs" and set "unset_workflow_inputs"z_dxpy.DXWorkflow.update: cannot provide both "workflow_outputs" and set "unset_workflow_outputs"r   r   r   r(   r)   r+   r-   )r   r@   r4   r5   workflow_updaterX   rY   )r8   r   unset_titler   r   r   unset_output_folderr*   unset_workflow_inputsr,   unset_workflow_outputsr)   r?   r   update_inputs                  r   updatezDXWorkflow.update)  sR   : eff$)<uvv&+@yzz',B{||$)L!$(L!&-L#"*5L'$+8L( +/L(%+L"&%4L""%)L"'&6L##&*L# --lLI ((\LVL 
 s   %+C" "C4c                 ,   | j                  |      }||rt        d      ||rt        d      |t        |t              r|}n,t        |t              r|j                         }nt        d      |||d}| j                  ||
       	 t        j                  j                  | j                  |fi | | j                          i }|||d<   n|rd|d<   |r||d<   n|rd|d<   |r||d<   |	&t        j                  |	      j                         |d	<   |rUd
||ii}| j                  ||
       	 t        j                  j                  | j                  |fi | | j                          yy# | j                          w xY w# | j                          w xY w)a  
        :param stage: A number for the stage index (for the nth stage, starting from 0), or a string stage index, name, or ID
        :type stage: int or string
        :param executable: string or a handler for an app or applet
        :type executable: string, DXApplet, or DXApp
        :param force: whether to use *executable* even if it is incompatible with the previous executable's spec
        :type force: boolean
        :param name: new name for the stage; cannot be provided with *unset_name* set to True
        :type name: string
        :param unset_name: whether to unset the stage name; cannot be True with string value for *name*
        :type unset_name: boolean
        :param folder: new default output folder for the stage; either a relative or absolute path (optional)
        :type folder: string
        :param unset_folder: whether to unset the stage folder; cannot be True with string value for *folder*
        :type unset_folder: boolean
        :param stage_input: input fields to bind as default inputs for the executable (optional)
        :type stage_input: dict
        :param instance_type: Default instance type on which all jobs will be run for this stage, or a dict mapping function names to instance type requests
        :type instance_type: string or dict
        :param edit_version: if provided, the edit version of the workflow that should be modified; if not provided, the current edit version will be used (optional)
        :type edit_version: int

        Removes the specified stage from the workflow
        NzMdxpy.DXWorkflow.update_stage: cannot provide both "name" and set "unset_name"zQdxpy.DXWorkflow.update_stage: cannot provide both "folder" and set "unset_folder"zkdxpy.DXWorkflow.update_stage: executable (if provided) must be a string or an instance of DXApplet or DXApp)rJ   rQ   forcerB   rR   rS   rT   r)   )rO   r   r.   r   r
   r2   r@   r4   r5    workflow_update_stage_executablerX   rY   r   rU   rV   rr   )r8   rJ   rQ   rz   rB   
unset_namerR   unset_folderr[   r\   r?   r   rZ   r]   update_stage_exec_inputupdate_stage_inputrw   s                    r   update_stagezDXWorkflow.update_stageo  s   6 %%e,
ijj,mnn!*j1$J5$++-  L  M  M085<05'7# --.E|T 99$**F]hagh  )-v&)-v&+1x(+/x(*5w'$7M7`7`an7o7w7w7y34$x1C&DEL--lLI ((\LVL ! , s   
+E, /+F ,E>Fc                 |    | j                   j                  d      d uxr | j                   j                  d      dk(  S )Nr+   stateclosed)_descrH   )r8   s    r   	is_lockedzDXWorkflow.is_locked  s2    zz~~h't3[

w8OS[8[[r   c                 f    d|v r,|j                  dd      \  }}| j                  |      dz   |z   S |S )a  
        :param input_str: A string of one of the forms: "<exported input field name>", "<explicit workflow input field name>", "<stage ID>.<input field name>", "<stage index>.<input field name>", "<stage name>.<input field name>"
        :type input_str: string
        :returns: If the given form was one of those which uses the stage index or stage name, it is translated to the stage ID for use in the API call (stage name takes precedence)
        .rC   )splitrO   )r8   	input_strregiondescribe_outputstage_identifier
input_names         r   _get_input_namezDXWorkflow._get_input_name  sD     )+4??3+B(j%%&67#=
JJr   c                 t    i }|D ]0  }| j                  |      }||v rt        d|z   dz         ||   ||<   2 |S )NzDXWorkflow: the input for z was provided more than once)r   r   )r8   workflow_inputeffective_inputr"   r   s        r   _get_effective_inputzDXWorkflow._get_effective_input  s\    ! 	>C--c2J_,:ZGJhhii*8*=OJ'		>
 r   c                 
   | j                  |      }t        j                  |fi |}|j                  d      _i |d<   |d   j	                         D ]D  \  }}|dk7  r| j                  |      }t        j                  |      j                         |d   |<   F |j                  d      >i |d<   |d   j	                         D ]#  \  }}|dk7  r| j                  |      }||d   |<   % |j                  d      ,|d   D cg c]  }|dk(  r|n| j                  |       c}|d<   |j                  dd	      rdg|d
<   |j                  d      ,|d   D cg c]  }|dk(  r|n| j                  |       c}|d
<   |S c c}w c c}w )Nstage_instance_typesstageSystemRequirements*stage_foldersstageFoldersrerun_stagesrerunStagesignore_reuseFignoreReuseignore_reuse_stages)	r   r
   _get_run_input_common_fieldsrH   itemsrO   r   rU   rV   )r8   r   r   effective_workflow_input	run_inputrJ   value_stages           r   _get_run_inputzDXWorkflow._get_run_input  s   #'#<#<^#L  ==>VaZ`a	::,-935I/0 &'= > D D F yuC< ..u5E>T>g>ghm>n>v>v>x	34U;y
 ::o&2(*In% & 7 = = ? 9uC< ..u5E38	.)%09
 ::n%1 %^4( !C-T-?-?-GG(Im$
 ::ne,(+uIm$::+,8 %%:;( !C-T-?-?-GG(Im$
 ((s   ?E;F c                 p    t        t        j                  j                  | j                  |fi |d         S )Nr%   )r   r4   r5   workflow_runrX   )r8   r   r   s      r   	_run_implzDXWorkflow._run_impl  s-    $((//

IPPQUVWWr   c                 2    t        t        | 
  |g|i |S )a8	  
        :param workflow_input: Dictionary of the workflow's input arguments; see below for more details
        :type workflow_input: dict
        :param instance_type: Instance type on which all stages' jobs will be run, or a dict mapping function names to instance types. These may be overridden on a per-stage basis if stage_instance_types is specified.
        :type instance_type: string or dict
        :param stage_instance_types: A dict mapping stage IDs, names, or indices to either a string (representing an instance type to be used for all functions in that stage), or a dict mapping function names to instance types.
        :type stage_instance_types: dict
        :param stage_folders: A dict mapping stage IDs, names, indices, and/or the string "*" to folder values to be used for the stages' output folders (use "*" as the default for all unnamed stages)
        :type stage_folders: dict
        :param rerun_stages: A list of stage IDs, names, indices, and/or the string "*" to indicate which stages should be run even if there are cached executions available
        :type rerun_stages: list of strings
        :param ignore_reuse_stages: Stages of a workflow (IDs, names, or indices) or "*" for which job reuse should be disabled
        :type ignore_reuse_stages: list
        :returns: Object handler of the newly created analysis
        :rtype: :class:`~dxpy.bindings.dxanalysis.DXAnalysis`

        Run the associated workflow. See :meth:`dxpy.bindings.dxapplet.DXExecutable.run` for additional args.

        When providing input for the workflow, keys should be of one of the following forms:

        * "N.name" where *N* is the stage number, and *name* is the
          name of the input, e.g. "0.reads" if the first stage takes
          in an input called "reads"

        * "stagename.name" where *stagename* is the stage name, and
          *name* is the name of the input within the stage

        * "stageID.name" where *stageID* is the stage ID, and *name*
          is the name of the input within the stage

        * "name" where *name* is the name of a workflow level input
          (defined in inputs) or the name that has been
          exported for the workflow (this name will appear as a key
          in the "inputSpec" of this workflow's description if it has
          been exported for this purpose)

        )superr   run)r8   r   argsr   	__class__s       r   r   zDXWorkflow.run  s"    L Z*>KDKFKKr   r    )NNNNNN)NFNNNFNFNFNN)	NFNFNFNNN)NN)0__name__
__module____qualname____doc___classstaticmethodr4   r5   workflow_describe	_describeworkflow_add_types
_add_typesworkflow_remove_types_remove_typesworkflow_get_details_get_detailsworkflow_set_details_set_detailsworkflow_set_visibility_set_visibilityworkflow_rename_renameworkflow_set_properties_set_propertiesworkflow_add_tags	_add_tagsworkflow_remove_tags_remove_tagsworkflow_close_closeworkflow_list_projects_list_projectsr;   r@   rO   r`   rf   rj   rp   rx   r   r   r   r   r   r   r   __classcell__)r   s   @r   r   r   I   s   
 FTXX778Idhh99:J !?!?@M = =>L = =>L"488#C#CDO488334G"488#C#CDOTXX778I = =>L$((112F!$(("A"ABN65p7(.T lp#-^
(( OS7<;@=B)-	D L :?_c6:F P\"HX&L &Lr   r   )NNNNN)r   
__future__r   r   r   r   r/   r4   system_requirementsr   bindingsr	   r
   r   
exceptionsr   compatr   r   r   r   r   r   <module>r      s@   " S R 	  8 = =   BTL| TLr   