§
    +" h™8  ã                  ó*  — d dl 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mZ d dl	m
Z
 d dlmZmZ d dlmZ d dlmZ d dlmZ d d	lmZ  ej        e¦  «        Z G d
„ dej        ¬¦  «        Z G d„ de¦  «        Zdd„Zdd„Zdd„Z G d„ de¦  «        ZdS )é    )ÚannotationsN)Ú
HTTPStatus)ÚAny)ÚResponseÚSession)ÚConnectionError)ÚCaseInsensitiveDict)Ú	TypeGuard)Ú	JIRAErrorc                  ó4   — e Zd ZdZej        dd„¦   «         ZdS )ÚPrepareRequestForRetryz²This class allows for the manipulation of the Request keyword arguments before a retry.

    The :py:meth:`.prepare` handles the processing of the Request keyword arguments.
    Úoriginal_request_kwargsr	   Úreturnc                ó   — |S )a)  Process the Request's keyword arguments before retrying the Request.

        Args:
            original_request_kwargs (CaseInsensitiveDict): The keyword arguments of the Request.

        Returns:
            CaseInsensitiveDict: The new keyword arguments to use in the retried Request.
        © )Úselfr   s     úOc:\xampp_lite_8_4\www\timesheet\venv\Lib\site-packages\jira/resilientsession.pyÚpreparezPrepareRequestForRetry.prepare   s
   € ð 'Ð&ó    N©r   r	   r   r	   )Ú__name__Ú
__module__Ú__qualname__Ú__doc__ÚabcÚabstractmethodr   r   r   r   r   r      sB   € € € € € ðð ð
 	Ôð'ð 'ð 'ñ Ôð'ð 'ð 'r   r   )Ú	metaclassc                  ó$   ‡ — e Zd ZdZdˆ fd„Zˆ xZS )ÚPassthroughRetryPreparezbReturns the Request's keyword arguments unchanged, when no change needs to be made before a retry.r   r	   r   c                óF   •— t          ¦   «                              |¦  «        S )N)Úsuperr   )r   r   Ú	__class__s     €r   r   zPassthroughRetryPrepare.prepare-   s   ø€ õ ‰wŒw�ŠÐ6Ñ7Ô7Ð7r   r   )r   r   r   r   r   Ú__classcell__©r"   s   @r   r   r   *   sC   ø€ € € € € ØlÐlð8ð 8ð 8ð 8ð 8ð 8ð 8ð 8ð 8ð 8r   r   ÚrespúResponse | Noner   úTypeGuard[Response]c                ó¸   — |                      dd¦  «        }| €t          dd| i|¤Ž‚| j        s,t          | ¬¦  «        }t          |f| j        | j        || dœ|¤Ž‚dS )	a.  Handle errors from a Jira Request.

    Args:
        resp (Optional[Response]): Response from Jira request

    Raises:
        JIRAError: If Response is None
        JIRAError: for unhandled 400 status codes.

    Returns:
        TypeGuard[Response]: True if the passed in Response is all good.
    ÚrequestNúEmpty Response!Úresponse)r%   )Ústatus_codeÚurlr)   r+   T)r*   )Úgetr   ÚokÚparse_error_msgr,   r-   )r%   Úkwargsr)   Úerrors       r   Úraise_on_errorr3   3   s�   € ð �jŠj˜ DÑ)Ô)€Gà€|ÝÐCÐC°DÐC¸FÐCÐCÐCàŒ7ð 

Ý TÐ*Ñ*Ô*ˆåØð
àÔ(Ø”ØØð
ð 
ð ð
ð 
ð 	
ð ˆ4r   r   ú	list[str]c                ó6  — i }g }| j         dk    rd| j        v r| j        d         gS | j        r.	 |                      ¦   «         }n# t          $ r | j        gcY S w xY wd|v r
|d         g}n¯d|v r
|d         g}n¡d|v rK|d         }t          |¦  «        dk    r/t          |t          t          f¦  «        rt          |¦  «        }nV|g}nRd|v rN|d         }t          |¦  «        dk    r3t          |t          ¦  «        rd„ | 
                    ¦   «         D ¦   «         }|S )	a;  Parse a Jira Error messages from the Response.

    https://developer.atlassian.com/cloud/jira/platform/rest/v2/intro/#status-codes

    Args:
        resp (Response): The Jira API request's response.

    Returns:
        List[str]: The error messages list parsed from the Response. An empty list if no error.
    i“  zx-authentication-denied-reasonÚmessageÚerrorMessageÚerrorMessagesr   Úerrorsc                ó,   — g | ]}t          |¦  «        ‘ŒS r   )Ústr)Ú.0Úerrs     r   ú
<listcomp>z parse_errors.<locals>.<listcomp>~   s   € ÐFÐFÐF¨#�S ™XœXÐFÐFÐFr   )r,   ÚheadersÚtextÚjsonÚ
ValueErrorÚlenÚ
isinstanceÚlistÚtupleÚdictÚvalues)r%   Ú	resp_dataÚparsed_errorsÚerror_messagesÚresp_errorss        r   Úparse_errorsrM   T   sr  € ð !#€IØ!€MØÔ˜3ÒÐÐ#CÀtÄ|Ð#SÐ#SØ”Ð=Ô>Ð?Ð?Ø	Œð ð	ØŸ	š	™œˆIˆIøÝð 	ð 	ð 	Ø”I�;ÐÐÐð	øøøð �IÐÐà" 9Ô-Ð.ˆˆØ	˜9Ð	$Ð	$ð # >Ô2Ð3ˆˆØ	˜IÐ	%Ð	%ð # ?Ô3ˆÝˆ~ÑÔ Ò"Ð"Ý˜.­4µ¨-Ñ8Ô8ð 1Ý $ ^Ñ 4Ô 4��à!/Ð 0�øØ	�YÐ	Ð	Ø Ô)ˆÝˆ{ÑÔ˜aÒÐ¥J¨{½DÑ$AÔ$AÐð GÐF°×1CÒ1CÑ1EÔ1EÐFÑFÔFˆMàÐs   ¯A ÁAÁAr;   c                óJ   — t          | ¦  «        }d                     |¦  «        S )aE  Parse a Jira Error messages from the Response and join them by comma.

    https://developer.atlassian.com/cloud/jira/platform/rest/v2/intro/#status-codes

    Args:
        resp (Response): The Jira API request's response.

    Returns:
        str: The error message parsed from the Response. An empty str if no error.
    z, )rM   Újoin)r%   r9   s     r   r0   r0   ƒ   s#   € õ ˜$ÑÔ€FØ�9Š9�VÑÔÐr   c                  ój   ‡ — e Zd ZdZddˆ fd„Zdd„Z e¦   «         fdˆ fd„Zd d„Z	 d!d"d„Z	d d„Z
ˆ xZS )#ÚResilientSessionz‹This class is supposed to retry requests that do return temporary errors.

    :py:meth:`__recoverable` handles all retry-able errors.
    Né   é<   Úmax_retriesÚintÚmax_retry_delayc                óö   •— || _         || _        || _        t          ¦   «                              ¦   «          | j                             ddi¦  «         t                               ddt          › d�z   ¦  «         dS )a�  A Session subclass catered for the Jira API with exponential delaying retry.

        Args:
            timeout (Optional[Union[Union[float, int], Tuple[float, float]]]): Connection/read timeout delay. Defaults to None.
            max_retries (int): Max number of times to retry a request. Defaults to 3.
            max_retry_delay (int): Max delay allowed between retries. Defaults to 60.
        ÚAcceptzapplication/json,*/*;q=0.9z@WARNING: On error, will dump Response headers and body to logs. zLog level debug in 'z"' is not safe for production code!N)
ÚtimeoutrT   rV   r!   Ú__init__r?   ÚupdateÚLOGÚdebugr   )r   rY   rT   rV   r"   s       €r   rZ   zResilientSession.__init__˜   s‰   ø€ ð ˆŒØ&ˆÔØ.ˆÔÝ‰Œ×ÒÑÔÐð 	Œ×Ò˜XÐ'CÐDÑEÔEÐEõ 	�	Š	ØNØQ¥XÐQÐQÐQñRñ	
ô 	
ð 	
ð 	
ð 	
r   r   rG   c                ó`  — |                      ¦   «         }|  | j                              ¦   «         }|                     |                     di ¦  «        ¦  «         ||d<   |                     dd¦  «        }t	          |t
          ¦  «        rt          j        |¦  «        |d<   d|vr
| j        |d<   |S )z?Do any pre-processing of our own and return the updated kwargs.r?   ÚdataNÚverify)	Úcopyr?   r[   r.   rD   rG   rA   Údumpsr`   )r   Úoriginal_kwargsÚprepared_kwargsÚrequest_headersr_   s        r   Ú_jira_preparezResilientSession._jira_prepare®   s´   € à)×.Ò.Ñ0Ô0ˆØÐ)Øœ,×+Ò+Ñ-Ô-ˆØ×Ò˜×2Ò2°9¸bÑAÔAÑBÔBÐBØ%4ˆ˜	Ñ"à×"Ò" 6¨4Ñ0Ô0ˆÝ�d�DÑ!Ô!ð 	7õ '+¤j°Ñ&6Ô&6ˆO˜FÑ#à˜?Ð*Ð*Ø(,¬ˆO˜HÑ%àÐr   Úmethodr;   r-   ústr | bytesÚ_prepare_retry_classr   r   c                ó$  •‡ ‡— dŠd}d} ‰ j         d	i |¤Ž}d
ˆˆ fd„} |¦   «         rÈd}d}	  t          ¦   «         j        ||fd‰ j        i|¤Ž}|j        r‰                      |¦  «         |S n# t          $ r}	|	}Y d}	~	nd}	~	ww xY w|�|n|}
‰dz  Š |¦   «         r@‰                      |
||                     ¦   «         ‰¦  «        r| 	                    |¦  «         n
‰ j
        dz   Š |¦   «         °È|�|‚t          |fi |¤Žr|S t          d¦  «        ‚)a	  This is an intentional override of `Session.request()` to inject some error handling and retry logic.

        Raises:
            Exception: Various exceptions as defined in py:method:`raise_on_error`.

        Returns:
            Response: The response.
        r   Nr   Úboolc                 ó   •— ‰ ‰j         k    S )z4Helper method to say if we should still be retrying.)rT   )Úretry_numberr   s   €€r   Úis_allowed_to_retryz5ResilientSession.request.<locals>.is_allowed_to_retry×   s   ø€ à 4Ô#3Ò3Ð3r   rY   é   z*Expected a Response or Exception to raise!r   )r   rk   )rf   r!   r)   rY   r/   Ú2_ResilientSession__handle_known_ok_response_errorsr   Ú_ResilientSession__recoverableÚupperr   rT   r3   ÚRuntimeError)r   rg   r-   ri   r1   Ú	exceptionr+   Úprocessed_kwargsrn   ÚeÚresponse_or_exceptionrm   r"   s   `          @€r   r)   zResilientSession.requestÁ   sÎ  øøø€ ð ˆØ&*ˆ	Ø$(ˆð .˜4Ô-Ð7Ð7°Ð7Ð7Ðð	4ð 	4ð 	4ð 	4ð 	4ð 	4ð 	4ð "Ð!Ñ#Ô#ð 	4ØˆHØˆIð	Ø*�5™7œ7œ?Ø˜Cðð Ø)-¬ðØ9Iðð �ð ”;ð $Ø×:Ò:¸8ÑDÔDÐDØ#�Oð$øõ #ð ð ð Ø�	�	�	�	�	�	øøøøðøøøð 19Ð0D H HÈ)Ð!Ø˜AÑˆLØ"Ð"Ñ$Ô$ð 4¨×);Ò);Ø% s¨F¯LªL©N¬N¸Lñ*ô *ð 4ð %×,Ò,Ð-=Ñ>Ô>Ð>Ð>à#Ô/°!Ñ3�ð/ "Ð!Ñ#Ô#ð 	4ð2 Ð àˆOÝ˜HÐ9Ð9Ð(8Ð9Ð9ð 	MàˆOõ ÐKÑLÔLÐLs   ­?A. Á.
BÁ8A?Á?Br+   c                ó¸   — |j         sdS t          |j        ¦  «        dk    r4d|j        v r-d|j        d         v r t                               d¦  «         dS dS dS dS )zÂResponses that report ok may also have errors.

        We can either log the error or raise the error as appropriate here.

        Args:
            response (Response): The response.
        Nr   zX-Seraph-LoginReasonÚAUTHENTICATED_FAILEDz;Atlassian's bug https://jira.atlassian.com/browse/JRA-41559)r/   rC   Úcontentr?   r\   Úwarning)r   r+   s     r   Ú!__handle_known_ok_response_errorsz2ResilientSession.__handle_known_ok_response_errorsþ   sx   € ð Œ{ð 	ØˆFå�Ô Ñ!Ô! QÒ&Ð&Ø&¨(Ô*:Ð:Ð:Ø&¨(Ô*:Ð;QÔ*RÐRÐRå�KŠKÐUÑVÔVÐVÐVÐVð	 'Ð&Ø:Ð:ØRÐRr   ro   ú!ConnectionError | Response | NoneÚrequest_methodÚcounterc                óœ  — d}t          |¦  «        }t          |t          ¦  «        rldd|z  z  }t                               d|› d|j        › d|› d�|› d�z   ¦  «         t          j        t          j        k    rt                               d	¦  «         nËt          |t          ¦  «        r¶t          j        t          j        g}|j        |v r•|j                             d
¦  «        }|r!dt!          t#          |¦  «        d¦  «        z  }n|j        t          j        k    rdd|z  z  }|j        t          j        k    r&|j        › d|j        › �}|                      |¦  «         |dk    }	|	ræt)          | j        |¦  «        t-          j        dd¦  «        z  }
t                               d|› d|› d|› d| j        › d|
› d|› �¦  «         t          |t          ¦  «        rat                               dt5          j        t9          |j        ¦  «        d¬¦  «        ¦  «         t                               d|j        ¦  «         t=          j        |
¦  «         |	S )a‰  Return whether the request is recoverable and hence should be retried.

        Exponentially delays if recoverable.

        At this moment it supports: 429, 503

        Args:
            response (Optional[Union[ConnectionError, Response]]): The response or exception.
              Note: the response here is expected to be ``not response.ok``.
            url (Union[str, bytes]): The URL.
            request_method (str): The request method.
            counter (int, optional): The retry counter to use when calculating the exponential delay. Defaults to 1.

        Returns:
            bool: True if the request should be retried.
        éÿÿÿÿé
   é   zGot ConnectionError [z] errno:z on ú ú
zJResponse headers for ConnectionError are only printed for log level DEBUG.úRetry-Afterro   r   g      à?g      ð?zGot recoverable error from z, will retry [ú/z] in zs. Err: zresponse.headers:
%sé   )Úindentzresponse.body:
%s) r;   rD   r   r\   r{   ÚerrnoÚlevelÚloggingÚDEBUGr   r   ÚTOO_MANY_REQUESTSÚSERVICE_UNAVAILABLEr,   r?   r.   ÚmaxrU   ÚreasonÚ(_ResilientSession__log_http_429_responseÚminrV   ÚrandomÚuniformrT   r]   rA   rb   rG   rz   ÚtimeÚsleep)r   r+   r-   r~   r   Úsuggested_delayÚmsgÚrecoverable_error_codesÚretry_afterÚis_recoverableÚdelays              r   Ú__recoverablezResilientSession.__recoverable  s±  € ð. ˆÝ�(‰mŒmˆå�h¥Ñ0Ô0ð 	;Ø  1 g¡:™oˆOå�KŠKØ_¨Ð_Ð_¸(¼.Ð_Ð_ÈnÐ_Ð_Ð_Ø�*�*�*ññô ð õ Œy�7œ=Ò(Ð(Ý—’Ø`ñô ð øõ ˜¥(Ñ+Ô+ð 	;åÔ,ÝÔ.ð'Ð#ð
 Ô#Ð'>Ð>Ð>Ø&Ô.×2Ò2°=ÑAÔA�Øð 6Ø&'­#Ý˜KÑ(Ô(¨!ñ+ô +ñ '�O�Oð Ô)­ZÔ-IÒIÐIØ&(¨1¨g©:¡o�OàÔ'­:Ô+GÒGÐGØ%Ô1ÐEÐE°H´OÐEÐE�CØ×0Ò0°Ñ:Ô:Ð:à(¨1Ò,ˆØð 	å˜Ô,¨oÑ>Ô>ÅÄØ�SñBô Bñ ˆEõ �KŠKð H¨nð  Hð  H¸sð  Hð  HÐRYð  Hð  HÐ\`Ô\lð  Hð  HÐsxð  Hð  Hð  CFð  Hð  Hñô ð õ ˜(¥HÑ-Ô-ð BÝ—	’	Ø+Ý”J�t HÔ$4Ñ5Ô5¸aÐ@Ñ@Ô@ñô ð õ —	’	Ð.°Ô0@ÑAÔAÐAÝŒJ�uÑÔÐàÐr   c                ól  — |j                              d¦  «        }|j                              d¦  «        }|j                              d¦  «        }|j                              d¦  «        }d}||�d|› d�ndz  }|�|�||› d	|› d�z  }|�	|d
|› d�z  }|dz   dz   }t                               |¦  «         d S )Nr†   zX-RateLimit-FillRatezX-RateLimit-Interval-SecondszX-RateLimit-LimitzRequest rate limited by Jira.z! Request should be retried after z
 seconds.
r…   z tokens are issued every zYou can accumulate up to z	 tokens.
z;Consider adding an exemption for the user as explained in: zohttps://confluence.atlassian.com/adminjiraserver/improving-instance-stability-with-rate-limiting-983794911.html)r?   r.   r\   r{   )r   r+   r›   Ú$number_of_tokens_issued_per_intervalÚ#token_issuing_rate_interval_secondsÚmaximum_number_of_tokensÚwarning_msgs          r   Ú__log_http_429_responsez(ResilientSession.__log_http_429_response[  s.  € ØÔ&×*Ò*¨=Ñ9Ô9ˆØ/7Ô/?×/CÒ/CØ"ñ0
ô 0
Ð,ð /7Ô.>×.BÒ.BØ*ñ/
ô /
Ð+ð $,Ô#3×#7Ò#7Ð8KÑ#LÔ#LÐ à5ˆØàÐ&ð I°ÐHÐHÐHÐHàñ	
ˆð 1Ð<Ø3Ð?àÐBð  Nð  Nð  ^Að  Nð  Nð  Nñ  NˆKà#Ð/ØØPÐ,DÐPÐPÐPñˆKð
 ØKñLàñ@ð 	õ 	�Š�KÑ Ô Ð Ð Ð r   )NrR   rS   )rT   rU   rV   rU   )r   rG   )rg   r;   r-   rh   ri   r   r   r   )r+   r   )ro   )r+   r}   r-   rh   r~   r;   r   rU   )r   r   r   r   rZ   rf   r   r)   rp   rq   r’   r#   r$   s   @r   rQ   rQ   ’   sê   ø€ € € € € ðð ð

ð 
ð 
ð 
ð 
ð 
ð 
ð,ð ð ð ð. 8OÐ7NÑ7PÔ7Pð	;Mð ;Mð ;Mð ;Mð ;Mð ;Mð ;MðzWð Wð Wð Wð, ðJð Jð Jð Jð JðX"!ð "!ð "!ð "!ð "!ð "!ð "!ð "!r   rQ   )r%   r&   r   r'   )r%   r   r   r4   )r%   r   r   r;   ) Ú
__future__r   r   rA   rŒ   r”   r–   Úhttpr   Útypingr   Úrequestsr   r   Úrequests.exceptionsr   Úrequests.structuresr	   Útyping_extensionsr
   Újira.exceptionsr   Ú	getLoggerr   r\   ÚABCMetar   r   r3   rM   r0   rQ   r   r   r   ú<module>r¯      s²  ðØ "Ð "Ð "Ð "Ð "Ð "à 
€
€
€
Ø €€€Ø €€€Ø €€€Ø €€€Ø Ð Ð Ð Ð Ð Ø Ð Ð Ð Ð Ð à &Ð &Ð &Ð &Ð &Ð &Ð &Ð &Ø /Ð /Ð /Ð /Ð /Ð /Ø 3Ð 3Ð 3Ð 3Ð 3Ð 3Ø 'Ð 'Ð 'Ð 'Ð 'Ð 'à %Ð %Ð %Ð %Ð %Ð %à€gÔ˜Ñ!Ô!€ð'ð 'ð 'ð 'ð ' s¤{ð 'ñ 'ô 'ð 'ð*8ð 8ð 8ð 8ð 8Ð4ñ 8ô 8ð 8ðð ð ð ðB,ð ,ð ,ð ,ð^ð ð ð ðk!ð k!ð k!ð k!ð k!�wñ k!ô k!ð k!ð k!ð k!r   