
    5iA                     8   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	Z	ddl
Z
ddlZddlZddlZddlmZ ddlmZ ddlZddlmZ dd	lmZ  ej.                  d
      Zej3                  ej4                          G d de      Z G d d      Z G d de      Zd Zy)z
Utilities for client-side usage of the streaming log API
(https://documentation.dnanexus.com/developer/api/running-analyses/applets-and-entry-points#api-method-job-xxxx-getlog).
    )print_functionunicode_literalsdivisionabsolute_importN)Thread)WebSocketApp   )get_find_executions_string   )err_exit	websocketc                       e Zd Zy)DXJobLogStreamingExceptionN)__name__
__module____qualname__     {/home/marpiech/ifpan-abm-pgxpred/analysis/marpiech-gwas-test/venv/lib/python3.12/site-packages/dxpy/utils/job_log_client.pyr   r   ,   s    r   r   c                   F    e Zd Z	 	 d
dZd Zd Zd ZddZddZd Z	d	 Z
y)DXJobLogStreamClientNc                    || _         || _        |du| _        || _        || _        || _        || _        i | _        d| _        d| _	        d| _
        d| _        || _        dj                  t        j                  dk(  rdndt        j                   t        j"                  t        j"                  nt        j$                  |      | _        d| _        y)a  Initialize job log client.

        :param job_id: dxid for a job (hash ID 'job-xxxx')
        :type job_id: str
        :param job_try: try for given job. If None, it will use the latest try.
        :type job_id: int or None
        :param input_params: blob with connection parameters, should have keys
        ``numRecentMessages`` (int) (wich may not be more than 1024 * 256, otherwise no logs will be returned),
        ``recurseJobs`` (bool) - if True, attempts to traverse subtree
        ``tail`` (bool) - if True, keep watching job. Should also be set to True to get all logs
        from a completed job.
        :type input_params: dict
        :param msg_output_format: how messages should be printed to console. Ignored if
        ``msg_callback`` is specified
        :type msg_output_form: str
        :param print_job_info: if True, prints metadata about job
        :type print_job_info: bool
        :param msg_callback: single argument function that accepts a JSON blob with message
        details. Example:
        ``{"timestamp": 1575465039481, "source": "APP", "level": "STDOUT", "job": "job-123",
           "line":24, "msg": "success WfFragment"}``
        where ``timestamp`` is Unix epoch time in milliseconds and ``line`` is a sequence number.
        :type msg_callback: callable
        :param exit_on_failed: if True, will raise SystemExit with code of 3 if encountering a
        failed job (this is the default behavior)
        :type exit_on_failed: bool
        NFz4{protocol}://{host}:{port}/{job_id}/getLog/websockethttpswssws)protocolhostportjob_id)r   job_tryjob_has_tryinput_paramsmsg_output_formatmsg_callbackprint_job_info	seen_jobserror	exceptionclosed_codeclosed_reasonexit_on_failedformatdxpyAPISERVER_PROTOCOLAPISERVER_HOST
WATCH_PORTAPISERVER_PORTurl_app)selfr   r    r"   r#   r$   r%   r+   s           r   __init__zDXJobLogStreamClient.__init__1   s    B "$.(!2(,
!,IPP"55@Ud$$$(OO$?TEXEX	 Q 
 	r   c                     	 d _         d  _        d  _        d  _        	 t	         j
                   fd fd fd fd       _         j                  j                  dt        j                  i       d  _         j                         rFt        j                  d	       t        j                  d
        j                   j                          ny #   j                         s Y txY w# d  _        w xY w)NFc                 $    j                         S N)opened)appr4   s    r   <lambda>z.DXJobLogStreamClient.connect.<locals>.<lambda>q   s     r   c                 (    j                  ||      S r8   )closed)r:   close_status_code	close_msgr4   s      r   r;   z.DXJobLogStreamClient.connect.<locals>.<lambda>r   s    t{{SdfoGp r   c                 &    j                  |      S r8   )errored)r:   r(   r4   s     r   r;   z.DXJobLogStreamClient.connect.<locals>.<lambda>s   s    DLL4K r   c                 &    j                  |      S r8   )received_message)r:   messager4   s     r   r;   z.DXJobLogStreamClient.connect.<locals>.<lambda>t   s    D4I4I'4R r   )on_openon_closeon_error
on_message	cert_reqs)ssloptzServer restart, reconnecting...r	   )r'   r(   r)   r*   r   r2   r3   run_foreverssl	CERT_NONEserver_restartedloggerwarntimesleep_describe_jobr   r4   s   `r   connectzDXJobLogStreamClient.connectg   s    DJ!DN#D!%D!(HH5pKR	 		%%k3==-I%J
 !	$$& =>

1""4;;/9 ,,. / !	s   AC C+)C. .	C7c                 B    | j                   dk(  xr | j                  dk(  S )Ni  z&Server restart, please reconnect later)r)   r*   rT   s    r   rN   z%DXJobLogStreamClient.server_restarted   s*    $ K"JJ	
r   c                     t         j                  d   t         j                  d   d}| j                  r|j                  | j                         | j                  j                  t        j                  |             y )N
auth_tokenauth_token_type)access_token
token_type)r-   SECURITY_CONTEXTr"   updater3   sendjsondumps)r4   argss     r   r9   zDXJobLogStreamClient.opened   s\     11,?//0AB
 KK))*		tzz$'(r   c                      d| _         || _        y )NT)r'   r(   )r4   r(   s     r   rA   zDXJobLogStreamClient.errored   s    
"r   c           	         |r|| _         || _        n| j                  sd| _         d| _        nk| j                  r0t	        | j                        t
        t        hv rd| _         d| _        n/d| _         | j                  rt        | j                        nd| _        | j                   dk7  r;	 t        j                  | j                        }t         dj                  di |      | j                  r| j                  | j                   vri | j                   | j                  <   | j                   j#                         D ]O  }| j%                  |      | j                   |<   t'        t)        | j                   |   d	d
| j*                               Q n2| j%                  | j                        | j                   | j                  <   | j,                  r8| j                   | j                     j/                  d      dv rt1        d       y y y # t        t        f$ r1 t        dj                  | j                   | j                              w xY w)Ni  NormalzConnection terminated by clienti  Abnormalz2Error while streaming job logs: {type}: {message}
z1Error while streaming job logs: {code}: {reason}
)codereasonFThas_childrenshow_outputsshow_trystate>   failed
terminated   )rf   r   )r)   r*   r'   r(   typeKeyboardInterrupt
SystemExitstrr_   loadsr   r,   KeyError
ValueErrorr%   r   r&   keysrS   printr
   r!   r+   getr   )r4   rf   rg   r'   r   s        r   r=   zDXJobLogStreamClient.closed   s   #D!'D#D!)D^^T^^ 49JJ8W W#D!BD#D8<T^^!4JDt#

4#5#560PIPP     {{$..0.0t{{+..--/ 	)-););F)Cv&.v.%*%)!%!1!1		 +/*<*<T[[*IDNN4;;'NN4;;/33G<@XX! Y  - j) 0HOO!--d6H6H P  s   (:H A Ic                    t        j                  |      }| j                  rkd|v rg|d   | j                  vrV| j	                  |d         | j                  |d   <   t        t        | j                  |d      dd| j                               |j                  d      dk(  r&|j                  d      dk(  rd| j                  _
        y | j                  r| j                  |       y t         | j                  j                  di |       y )	NjobFrh   sourceSYSTEMmsgEND_LOGr   )r_   rt   r%   r&   rS   rx   r
   r!   ry   r3   keep_runningr$   r#   r,   )r4   rD   message_dicts      r   rC   z%DXJobLogStreamClient.received_message   s    zz'* \!t~~5262D2D\RWEX2YDNN<./*NN<#67!&!&!--	 X&(2U#y0%*DII"l+/$((//?,?@r   c                 ~    t         j                  j                  || j                  rd| j                  i      S i       S )Ntry)r-   apijob_describer!   r    )r4   r   s     r   rS   z"DXJobLogStreamClient._describe_job   s3    xx$$VdFVFVeT\\-B__\^__r   )NNz{job} {level} {msg}NTTr8   )NN)r   r   r   r5   rU   rN   r9   rA   r=   rC   rS   r   r   r   r   r   0   s4    I^?C4l>
)#.`A8`r   r   c                        e Zd Z fdZ xZS )CursesDXJobLogStreamClientc                     t         t        |   ||       t        j                  t        j
                         t        j                         y r8   )superr   r=   oskillgetpidsignalSIGINT)r4   ra   kwargs	__class__s      r   r=   z!CursesDXJobLogStreamClient.closed   s-    ($6tVD
		V]]+r   )r   r   r   r=   __classcell__)r   s   @r   r   r      s    , ,r   r   c                      	 dd l  G  fdd      } |       }j                  |j                         y #  t        d       Y BxY w)Nr   zM--metrics top is not supported on your platform due to missing curses libraryc                   T    e Zd ZfdZfdZfdZd
dZ fdZd ZfdZ	d	 Z
y)"metrics_top.<locals>.ScreenManagerc                     d | _         || _        t        |j                  | j                  d dd      | _        d| _        g | _        dg| _        d| _	        d| _
        d| _        d| _        d| _        d| _        d| _        d| _        d| _        y )NF)r"   r$   r#   r%   r+   logszWaiting for job logs...r   )stdscrra   r   jobidr$   
log_clientcurr_screenlogmetrics	scr_dim_yscr_y_offsetscr_y_max_offset	scr_dim_xscr_x_offsetscr_x_max_offsetcurr_rowcurr_row_total_charscurr_col)r4   ra   r"   s     r   r5   z+metrics_top.<locals>.ScreenManager.__init__   s    DKDI8R^mqm~m~KO`ev{}DO%DDH56DLDN !D$%D!DN !D$%D!DM()D%DMr   c                 f   || _         j                          j                  dj                  d       j                  dj                  d       j                  dj
                  d       j                  dj                  d       t        | j                  j                        }d|_
        |j                          | j                          	 	 |j                         }|j                  k(  r| j                          n| j                  dk(  r|j                   k(  r| j                  d	       n|j"                  k(  r| j                  d	       n|j$                  k(  r| j                  d
	       n|j&                  k(  r| j                  d	       nj|j(                  k(  r| j                  | j*                   	       n<|j,                  k(  r| j                  | j.                  	       n|j0                  k(  r| j                  d       n|j2                  k(  r| j                  d       n|j4                  k(  r| j                  d       n|j6                  k(  r| j                  d       n|t9        d      k(  s|t9        d      k(  r| j                  d       nX|t9        d      k(  s|t9        d      k(  r<t;        j<                  d       n&| j                  dk(  r|dk\  r| j                  d       9# t>        $ r t;        j<                  d       Y y w xY w)Nr	   r   ro      )targetTr   )scr_x_offset_diff   i)scr_y_offset_diff
   i?help)target_screenqQr   ) r   use_default_colors	init_pair
COLOR_BLUE	COLOR_REDCOLOR_YELLOWCOLOR_GREENr   r   rU   daemonstartrefreshgetch
KEY_RESIZEr   	KEY_RIGHTKEY_LEFT
KEY_SRIGHT	KEY_SLEFTKEY_HOMEr   KEY_ENDr   KEY_UPKEY_DOWN	KEY_PPAGE	KEY_NPAGEordsysexitrq   )r4   r   tchcursess       r   mainz'metrics_top.<locals>.ScreenManager.main  s|    DK%%'Q 1 126Q 0 0"5Q 3 3R8Q 2 2B7doo556AAHGGILLNBV...))V3!1!114<<RS<3T6??2DLLSUL4V6#4#44dllUWl6X6#3#33T\\TW\5X6??2DLLTXTeTeSeL4f6>>14<<RVRgRg<3h6==0$,,QR,2S6??2DLLSUL4V6#3#33T\\TV\5W6#3#33T\\TW\5X3s8^rSX~t||Z`|?a3s8^rSX~sxx{))V37DLLvL$F# & % s   H:L L0/L0c                 `   t        | j                        dk(  rd| j                  d<    | j                  |       |d   dk(  rd|d   d|d   | j                  d<   n?| j                  j	                  |       | j
                  dkD  r| xj
                  d	z  c_        | j                          y )
Nr    levelMETRICS[	timestampz] r~   r	   )lenr   r   r   appendr   r   )r4   rD   
enrich_msgs     r   r$   z/metrics_top.<locals>.ScreenManager.msg_callback0  s    488}!"$Qt0w9,/6{/CWU^"TQ($$q(%%*%LLNr   Nc                    | j                   j                          | j                   j                         \  | _        | _        t        t        | j                        | j                  z
  dz   d      | _        | j                  ||       d| _
        ||| _        | j                  dk(  r| j                          n| j                          | j                   j                          y )Nro   r   r   )r   erasegetmaxyxr   r   maxr   r   r   update_screen_offsetsr   r   	draw_help	draw_logsr   )r4   r   r   r   s       r   r   z*metrics_top.<locals>.ScreenManager.refresh>  s    KK-1[[-A-A-C*DNDN$'DHH(F(JA$ND!&&'8:KLDM(#0 6)  KK!r   c                    t        | j                  dz
  t        | j                              }| j                  j                  | j                  d| j                  d   | j                         | xj                  dz  c_        t        |      D ]d  }| j                  t        | j                        |z
  |z   | j                  z
     }d| _        d| _        j                  r-| j                   j                  j                  di |d       n| j                  j                   r| j                  |d   d       | j                  |d   d       | j                  j"                  r| j                  d|d	   z  d       | j                  |j%                  d
d      |d          | j                  |d   d       t'        | j(                  | j                  dz
        | _        | xj                  dz  c_        g y )Nro   r   r   r   r   job_namer	   z(%s)r{   r   r   level_color_cursesr~   r   )minr   r   r   r   addnstrr   r   r   ranger   r   r   r,   print_fieldra   
timestampsjob_idsry   r   r   )r4   nlinesirD   ra   s       r   r   z,metrics_top.<locals>.ScreenManager.draw_logsQ  s   !+S];FKKq$,,r2BDNNSMMQM6] #((3txx=6#9A#=@Q@Q#QR !,-);;$$%7T[[%7%7%B'%BAFyy++(()=qA$$WZ%8!<yy(((('%.)@!D$$W[["%=wG[?\]$$WU^Q7(+D,A,A4C\C\_`C`(a%"##r   c                 `   d}g }|j                         D ]?  }|dk(  r|j                  d       |t        j                  || j                  dz
        z  }A t        t        t        |      | j                              D ]-  }| j                  j                  |d||   | j                         / y )Na  Metrics top mode help
_
This mode shows the latest METRICS message at the top of the screen and updates it for running jobs instead of showing every METRICS message interspersed with the currently-displayed job log messages. For completed jobs, this mode does not show any metrics.
_
Controls:
  Up/Down               scroll up/down by one line
  PgUp/PgDn             scroll up/down by 10 lines
  Left/Right            scroll left/right by one character
  Shift + Left/Right    scroll left/right by 20 characters
  Home/End              scroll to the beginning/end of the line
  ?                     display this help
  q                     quit
_
Press any key to return.
_r   r	   r   )
splitlinesr   textwrapwrapr   r   r   r   r   r   r   )r4   textlineslinerows        r   r   z,metrics_top.<locals>.ScreenManager.draw_helpi  s    D E) A3;LL$tT^^a-?@@	A SUT^^<= H##CE#JGHr   c           	      P   | j                   | j                  k  rj| j                  | j                  k\  r{| j                  j                  | j                  | j                   || j                  | j                   z
  j                  |             | xj                   t        |      dz   z  c_         n| j                  t        |      z   dz   | j                  kD  r| j                  j                  | j                  | j                   || j                  | j                  z
  d  | j                  | j                   z
  j                  |             | xj                   t        || j                  | j                  z
  d        dz   z  c_         | xj                  t        |      dz   z  c_        y )Nr	   )	r   r   r   r   r   r   r   
color_pairr   )r4   r   colorr   s      r   r   z.metrics_top.<locals>.ScreenManager.print_field  s   }}t~~-,,0A0AAKK''t}}dDNN]a]j]jLjlrl}l}  D  mE  FMMSY]2M..T:Q>ARARRKK''t}}d4K\K\_c_x_xKxKyFz  }A  }K  }K  NR  N[  N[  }[  ]c  ]n  ]n  ot  ]u  vMMSd.?.?$B[B[.[.\)]%^ab%bbM%%TQ6%r   c                 8   |sd}|sd}|dkD  r#t        | j                  |z   | j                        nt        | j                  |z   d      | _        |dkD  r)t        | j                  |z   | j
                        | _        y t        | j                  |z   d      | _        y )Nr   )r   r   r   r   r   r   )r4   diff_ydiff_xs      r   r   z8metrics_top.<locals>.ScreenManager.update_screen_offsets  s    Z`cdZdD$5$5$>@U@U Vjmnrnn  CI  oI  KL  kMDZ`cdZdD$5$5$>@U@U VDjmnrnn  CI  oI  KL  kMDr   )NNN)r   r   r   r5   r   r$   r   r   r   r   r   )ra   r   r   r"   s   r   ScreenManagerr      s.    	$#	J		"&	#0	H4		7	Mr   r   )r   r   wrapperr   )ra   r"   r   r   managerr   s   ```  @r   metrics_topr      sI    b]M ]M~ D!G
NN7<< Gb`as	   = A) __doc__
__future__r   r   r   r   r_   loggingr   r   rL   r   r   rQ   	threadingr   r   r   r-   describer
   
exceptionsr   	getLoggerrO   setLevelWARN	Exceptionr   r   r   r   r   r   r   <module>r     s   "
 S R   	  
 
    "  0 !			;	'  	 	v` v`r,!5 ,f!r   