
    5i6D                         d Z ddlmZmZmZmZ ddlZddlZddlZddl	m
Z
mZmZmZ ddlmZ ddlmZ dd	lmZ dd
lmZ 	 	 	 ddZ G d de
      Zy)af  
DXJob Handler
+++++++++++++

Jobs are DNAnexus entities that capture an instantiation of a running
app or applet. They can be created from either
:func:`dxpy.bindings.dxapplet.DXApplet.run` or
:func:`dxpy.bindings.dxapp.DXApp.run` if running an applet or app, or
via :func:`new_dxjob` or :func:`DXJob.new` in the case of an existing
job creating a subjob.

    )print_functionunicode_literalsdivisionabsolute_importN   )DXObjectDXDataObjectDXJobFailureErrorverify_string_dxid   )DXError)SystemRequirementsDict)queue_entry_point)
basestringc                 Z    t               } |j                  | |f||||||||	|
||d| |S )a	  
    :param fn_input: Function input
    :type fn_input: dict
    :param fn_name: Name of the function to be called
    :type fn_name: string
    :param name: Name for the new job (default is "<parent job name>:<fn_name>")
    :type name: string
    :param tags: Tags to associate with the job
    :type tags: list of strings
    :param properties: Properties to associate with the job
    :type properties: dict with string values
    :param details: Details to set for the job
    :type details: dict or list
    :param instance_type: Instance type on which the job will be run, or a dict mapping function names to instance type requests
    :type instance_type: string or dict
    :param depends_on: List of data objects or jobs to wait that need to enter the "closed" or "done" states, respectively, before the new job will be run; each element in the list can either be a dxpy handler or a string ID
    :type depends_on: list
    :param cluster_spec: a dict mapping function names to cluster spec requests
    :type cluster_spec: dict
    :param fpga_driver: a dict mapping function names to fpga driver requests
    :type fpga_driver: dict
    :param system_requirements: System requirement single mapping
    :type system_requirements: dict
    :param system_requirements_by_executable: System requirement by executable double mapping
    :type system_requirements_by_executable: dict
    :param nvidia_driver: a dict mapping function names to nvidia driver requests
    :type nvidia_driver: dict
    :rtype: :class:`~dxpy.bindings.dxjob.DXJob`

    Creates and enqueues a new job that will execute a particular
    function (from the same app or applet as the one the current job is
    running). Returns the :class:`~dxpy.bindings.dxjob.DXJob` handle for
    the job.

    Note that this function is shorthand for::

        dxjob = DXJob()
        dxjob.new(fn_input, fn_name, **kwargs)

    .. note:: This method is intended for calls made from within
       already-executing jobs or apps. If it is called from outside of
       an Execution Environment, an exception will be thrown. To create
       new jobs from outside the Execution Environment, use
       :func:`dxpy.bindings.dxapplet.DXApplet.run` or
       :func:`dxpy.bindings.dxapp.DXApp.run`.

    .. note:: If the environment variable ``DX_JOB_ID`` is not set, this method assmes that it is running within the debug harness, executes the job in place, and provides a debug job handler object that does not have a corresponding remote API job object.

    )nametags
propertiesdetailsinstance_type
depends_oncluster_specfpga_driversystem_requirements!system_requirements_by_executablenvidia_driver)DXJobnew)fn_inputfn_namer   r   r   r   r   r   r   r   r   r   r   kwargsdxjobs                  u/home/marpiech/ifpan-abm-pgxpred/analysis/marpiech-gwas-test/venv/lib/python3.12/site-packages/dxpy/bindings/dxjob.py	new_dxjobr$   /   sP    h GEEIIh 5d*V])j|it"5Yz)5 .45 L    c                   l    e Zd ZdZdZddZ	 	 	 ddZd ZddZd Z	d	 Z
d
 Zd ZddZd ZddZd Zy)r   z$
    Remote job object handler.
    jobNc                 b    d | _         t        j                  | |       | j                  |       y )N)dxid)_test_harness_resultr   __init__set_idselfr)   s     r#   r+   zDXJob.__init__r   s&    $(!$T*Dr%   c                 v   g }|t        |t              r|D ]  }t        |t              st        |t              r;|j	                         t        d      |j                  |j	                                ^t        |t              r|j                  |       t        d       nt        d      dt        j                  v ri }||d<   ||d<   |||d<   |||d	<   |||d
<   t        d ||	|
|fD              rSt        j                  ||      }t        |	      }t        |
      }t        |      }||z   |z   |z   j                         |d<   |||d<   |||d<   |||d<   |||d<   t        j                  j                   |fi |}| j#                  |d          y| j#                  t%        ||||             y)a  
        :param fn_input: Function input
        :type fn_input: dict
        :param fn_name: Name of the function to be called
        :type fn_name: string
        :param name: Name for the new job (default is "<parent job name>:<fn_name>")
        :type name: string
        :param tags: Tags to associate with the job
        :type tags: list of strings
        :param properties: Properties to associate with the job
        :type properties: dict with string values
        :param details: Details to set for the job
        :type details: dict or list
        :param instance_type: Instance type on which the job will be run, or a dict mapping function names to instance type requests
        :type instance_type: string or dict
        :param depends_on: List of data objects or jobs to wait that need to enter the "closed" or "done" states, respectively, before the new job will be run; each element in the list can either be a dxpy handler or a string ID
        :type depends_on: list
        :param cluster_spec: a dict mapping function names to cluster spec requests
        :type cluster_spec: dict
        :param fpga_driver: a dict mapping function names to fpga driver requests
        :type fpga_driver: dict
        :param system_requirements: System requirement single mapping
        :type system_requirements: dict
        :param system_requirements_by_executable: System requirement by executable double mapping
        :type system_requirements_by_executable: dict
        :param nvidia_driver: a dict mapping function names to nvidia driver requests
        :type nvidia_driver: dict

        Creates and enqueues a new job that will execute a particular
        function (from the same app or applet as the one the current job
        is running).

        .. note:: This method is intended for calls made from within
           already-executing jobs or apps. If it is called from outside
           of an Execution Environment, an exception will be thrown. To
           create new jobs from outside the Execution Environment, use
           :func:`dxpy.bindings.dxapplet.DXApplet.run` or
           :func:`dxpy.bindings.dxapp.DXApp.run`.

        Nz:A dxpy handler given in depends_on does not have an ID setz`Expected elements of depends_on to only be either instances of DXJob or DXDataObject, or stringsz&Expected depends_on field to be a list	DX_JOB_IDinputfunctionr   r   r   c              3   $   K   | ]  }|d u 
 y wN ).0requirements     r#   	<genexpr>zDXJob.new.<locals>.<genexpr>   s     x{;d*xs   systemRequirementssystemRequirementsByExecutable	dependsOnr   id)r2   
input_hashr   r   )
isinstancelistr   r	   get_idr   appendr   osenvironanyr   from_instance_typeas_dictdxpyapijob_newr,   r   )r.   r   r    r   r   r   r   r   r   r   r   r   r   r   r!   final_depends_onitem	req_inputinstance_type_srdcluster_spec_srdfpga_driver_srdnvidia_driver_srdresps                          r#   r   z	DXJob.neww   s    V !*d+& JD!$.*T<2P;;=0")*f"gg(//>#D*5(//5%  'I  J  JJ FGG"**$I!)Ig$+Ij!$(	&!$(	&!%*4	,'x}l\giv>wxx$:$M$Mm]d$e!#9,#G "8"E$:=$I!3DGW3WZi3il}3}  3G  3G  3I	./".2E	./0<>_	:;%)9	+&"'.	)$88##I88DKKT
#KK)7x5E/35 6r%   c                     |7t        |t              r|j                  d      st        || j                         || _        y)z
        :param dxid: New job ID to be associated with the handler (localjob IDs also accepted for local runs)
        :type dxid: string

        Discards the currently stored ID and associates the handler with *dxid*
        Nz	localjob-)r>   r   
startswithr   _class_dxidr-   s     r#   r,   zDXJob.set_id   s6     tZ0T__[5Q #45
r%   c                     ||t        d      i }|||d<   |||d<   |||d<   t        j                  j                  | j                  |fi || _        | j
                  S )a  
        :param fields: dict where the keys are field names that should
            be returned, and values should be set to True (by default,
            all fields are returned)
        :type fields: dict
        :param defaultFields: include default fields when fields is supplied
        :type defaultFields: bool
        :param io: Include input and output fields in description;
            cannot be provided with *fields*; default is True if
            *fields* is not provided (deprecated)
        :type io: bool
        :returns: Description of the job
        :rtype: dict

        Returns a hash with key-value pairs containing information about
        the job, including its state and (optionally) its inputs and
        outputs, as described in the API documentation for the
        `/job-xxxx/describe
        <https://documentation.dnanexus.com/developer/api/running-analyses/applets-and-entry-points#api-method-job-xxxx-describe>`_
        method.

        zEDXJob.describe: cannot provide non-None values for both fields and iofieldsdefaultFieldsio)r   rG   rH   job_describerU   _desc)r.   rW   rX   rY   r!   describe_inputs         r#   describezDXJob.describe   sy    . ".abb'-N8$$.;N?+>#%N4 XX**4::~PP
zzr%   c                 ^    t        j                  j                  | j                  d|ifi | y)z
        :param tags: Tags to add to the job
        :type tags: list of strings

        Adds each of the specified tags to the job. Takes no
        action for tags that are already listed for the job.

        r   N)rG   rH   job_add_tagsrU   r.   r   r!   s      r#   add_tagszDXJob.add_tags  s%     	djj64.CFCr%   c                 ^    t        j                  j                  | j                  d|ifi | y)z
        :param tags: Tags to remove from the job
        :type tags: list of strings

        Removes each of the specified tags from the job. Takes
        no action for tags that the job does not currently have.

        r   N)rG   rH   job_remove_tagsrU   r`   s      r#   remove_tagszDXJob.remove_tags  s%     	  fd^FvFr%   c                 ^    t        j                  j                  | j                  d|ifi | y)z
        :param allow_ssh: Allowable IP ranges to set for SSH access to the job
        :type allow_ssh: list of strings

        Updates a job's allowSSH field, overwrites existing values

        allowSSHN)rG   rH   
job_updaterU   )r.   	allow_sshr!   s      r#   updatezDXJob.update  s&     	DJJY(?J6Jr%   c                 ^    t        j                  j                  | j                  d|ifi | y)a  
        :param properties: Property names and values given as key-value pairs of strings
        :type properties: dict

        Given key-value pairs in *properties* for property names and
        values, the properties are set on the job for the given
        property names. Any property with a value of :const:`None`
        indicates the property will be deleted.

        .. note:: Any existing properties not mentioned in *properties*
           are not modified by this method.

        r   N)rG   rH   job_set_propertiesrU   )r.   r   r!   s      r#   set_propertieszDXJob.set_properties&  s&     	##DJJz0JUfUr%   c                    d}	  | j                   di |}|dk(  ry|dk(  rl | j                  di |} dj                  di |}|j                  d      dk7  r)|d   d   |d   k7  r|dj                  |d   d   	      z  }t	        |      |d
k(  rt	        d      ||k\  s|dk  rt	        d      t        j                  |       ||z  })a  
        :param interval: Number of seconds between queries to the job's state
        :type interval: integer
        :param timeout: Maximum amount of time to wait, in seconds, until the job is done running
        :type timeout: integer
        :raises: :exc:`~dxpy.exceptions.DXError` if the timeout is reached before the job has finished running, or :exc:`dxpy.exceptions.DXJobFailureError` if the job fails

        Waits until the job has finished running.
        r   donefailedz;Job has failed because of {failureReason}: {failureMessage}failureFromNr<   z (failure from {id}))r<   
terminatedzJob was terminated.z3Reached timeout while waiting for the job to finishr5   )
_get_stater]   formatgetr
   timesleep)r.   intervaltimeoutr!   elapsedstatedescerr_msgs           r#   wait_on_donezDXJob.wait_on_done7  s     #DOO-f-E $t}}.v.^W^^faef88M*d2tM7J47PTXY]T^7^5<<]@STX@Y<ZZG'00$'(=>>'!Wq['(]^^JJx xG# r%   c                 X    t        j                  j                  | j                  fi | y)z0
        Terminates the associated job.
        N)rG   rH   job_terminaterU   r.   r!   s     r#   	terminatezDXJob.terminateV  s     	tzz4V4r%   c                 P    d| j                   |di}|||d   d<   |||d   d<   |S )a  
        :param field: Output field name of this job
        :type field: string
        :param index: If the referenced field is an array, optionally specify an index (starting from 0) to indicate a particular member of the array
        :type index: int
        :param metadata: If the referenced field is of a data object class, a string indicating the metadata that should be read, e.g. "name", "properties.propkey", "details.refgenome"
        :type metadata: string

        Returns a dict containing a valid job-based object reference
        to refer to an output of this job.  This can be used directly
        in place of a DNAnexus link when used as a job output value.
        For example, after creating a subjob, the following app
        snippet uses a reference to the new job's output as part of
        its own output::

            mysubjob = dxpy.new_dxjob({}, "my_function")
            return { "myfileoutput": mysubjob.get_output_ref("output_field_name"),
                     "myotherfileoutput": mysubjob.get_output_ref("output_array",
                                                                  index=1),
                     "filename": mysubjob.get_output_ref("output_field_name",
                                                         metadata="name") }
        z$dnanexus_link)r'   fieldindexmetadata)rU   )r.   r   r   r   links        r#   get_output_refzDXJob.get_output_ref\  sH    0 !$**u"EF.3D!"7+19D!":.r%   c                 D     | j                   ddt        d      i|d   S )z
        :returns: State of the remote object
        :rtype: string

        Queries the API server for the job's state.

        Note that this function is shorthand for:

            dxjob.describe(io=False, **kwargs)["state"]

        rW   T)rz   rz   r5   )r]   dictr   s     r#   rr   zDXJob._get_state{  s'     t}}?Dt$4??HHr%   r4   NNNNNNNNNNN)NNN)r   i:	 )NN)__name__
__module____qualname____doc__rT   r+   r   r,   r]   ra   rd   ri   rl   r}   r   r   rr   r5   r%   r#   r   r   k   s_     F
 imVZBFW6r!F
D
G	KV" >5>Ir%   r   r   )r   
__future__r   r   r   r   rB   ru   rG    r   r	   r
   r   
exceptionsr   r   r   utils.local_exec_utilsr   compatr   r$   r   r5   r%   r#   <module>r      sN   " S R   K K   8 6  eiX\DH9x]IH ]Ir%   