o
    2gU0                     @  s|  d Z ddlmZ ddlZddlZddlZddlmZm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mZmZ dd
lmZ ddlmZ ddlmZmZ ddlmZmZm Z m!Z!m"Z"m#Z#m$Z$m%Z%m&Z&m'Z'm(Z(m)Z)m*Z* ddl+m,Z, ddl-m.Z. erddl/m0Z0 ddl1m2Z2 ddlm3Z3 ddl4m5Z5 e6e7Z8G dd deZ9G dd dZ:defd"ddZ;G d d! d!e9Z<dS )#zBprawcore.sessions: Provides prawcore.Session and prawcore.session.    )annotationsN)ABCabstractmethod)deepcopy)pformat)TYPE_CHECKINGAny)urljoin)ChunkedEncodingErrorConnectionErrorReadTimeout)codes   )BaseAuthorizer)TIMEOUTWINDOW_SIZE)BadJSON
BadRequestConflictInvalidInvocationNotFoundRedirectRequestExceptionServerErrorSpecialErrorTooLargeTooManyRequestsUnavailableForLegalReasons
URITooLong)RateLimiter)authorization_error_class)BufferedReader)Response)
Authorizer)	Requestorc                   @  s(   e Zd ZdZed
ddZdddZd	S )RetryStrategyzAn abstract class for scheduling request retries.

    The strategy controls both the number and frequency of retry attempts.

    Instances of this class are immutable.

    returnfloat | Nonec                 C  s   d S N selfr)   r)   I/home/garg/my-data/venv/lib/python3.10/site-packages/prawcore/sessions.py_sleep_seconds8      zRetryStrategy._sleep_secondsNonec                 C  s:   |   }|durd|dd}t| t| dS dS )z0Sleep until we are ready to attempt the request.Nz
Sleeping: z0.2fz seconds prior to retry)r-   logdebugtimesleep)r+   sleep_secondsmessager)   r)   r,   r3   <   s   
zRetryStrategy.sleepNr&   r'   r&   r/   )__name__
__module____qualname____doc__r   r-   r3   r)   r)   r)   r,   r%   /   s
    r%   c                   @  s  e Zd ZdZeeefZdded ed ed ed ed hZ	i ed e
ed	 eed
 eed eed eed e
ed e
ed eed eed eed eed eed e
ed eed eed ede
de
iZed ed ed hZedQd!d"ZedRd$d%ZdSd&d'ZdTd(d)ZefdUd.d/ZdVd>d?ZdWdAdBZ 	CdXdYdEdFZ!dZdHdIZ"dTdJdKZ#dCdCdCdCe$fd[dOdPZ%dCS )\Sessionz3The low-level connection interface to Reddit's API.i  i
  bad_gatewaygateway_timeoutinternal_server_errorrequest_timeoutservice_unavailablebad_requestconflictfound	forbidden
media_typemoved_permanently	not_foundrequest_entity_too_largerequest_uri_too_largetoo_many_requestsunauthorizedunavailable_for_legal_reasonsacceptedcreatedokdatalist[tuple[str, str]] | Nonemethodstrparamsdict[str, int]urlr&   r/   c                 C  s8   t d||t  t dt|  t dt| d S )NzFetching: %s %s at %szData: %sz
Params: %s)r0   r1   r2   r   )rQ   rS   rU   rW   r)   r)   r,   _log_requestj   s   zSession._log_requestr$   c                 C  s
   | j jjS r(   )_authorizer_authenticator
_requestorr*   r)   r)   r,   r[   u      
zSession._requestorc                 C  s   | S )2Allow this object to be used as a context manager.r)   r*   r)   r)   r,   	__enter__y   r.   zSession.__enter__c                 G  s   |    dS )r]   N)close)r+   _argsr)   r)   r,   __exit__}   s   zSession.__exit__
authorizerBaseAuthorizer | Nonewindow_sizeintc                 C  s8   t |tsd| }t||| _t|d| _t| _dS )zPrepare the connection to Reddit's API.

        :param authorizer: An instance of :class:`.Authorizer`.
        :param window_size: The size of the rate limit reset window in seconds.

        zinvalid Authorizer: )rd   N)
isinstancer   r   rY   r   _rate_limiterFiniteRetryStrategy_retry_strategy_class)r+   rb   rd   msgr)   r)   r,   __init__   s   


zSession.__init__list[tuple[str, Any]]filesdict[str, BufferedReader]jsondict[str, Any]responseResponse | Noneretry_strategy_staterh   saved_exceptionException | Nonetimeoutfloatdict[str, Any] | str | Nonec              
   C  s@   |rt |n|j}td|||
 | j||||||	|
| dS )Nz Retrying due to %s status: %s %s)rQ   rm   ro   rS   rU   rv   rW   rs   )reprstatus_coder0   warning_request_with_retriesconsume_available_retry)r+   rQ   rm   ro   rS   rU   rq   rs   rt   rv   rW   statusr)   r)   r,   	_do_retry   s   zSession._do_retry.tuple[Response, None] | tuple[None, Exception]c	                 C  s   z6| j j| jj| j||d|||||d
}	td|	j|	j	d|	j	d|	j	d|	j	dt

  |	d fW S  tyY }
 z| rIt|
j| jsJ d |
jfW  Y d }
~
S d }
~
ww )NF)allow_redirectsrQ   rm   ro   rU   rv   z?Response: %s (%s bytes) (rst-%s:rem-%s:used-%s ratelimit) at %scontent-lengthzx-ratelimit-resetzx-ratelimit-remainingzx-ratelimit-used)rg   callr[   request_set_header_callbackr0   r1   rz   headersgetr2   r   should_retry_on_failurerf   original_exceptionRETRY_EXCEPTIONS)r+   rQ   rm   ro   rS   rU   rs   rv   rW   rq   	exceptionr)   r)   r,   _make_request   sD   




	zSession._make_requestNFiniteRetryStrategy | Nonec	                 C  s6  |d u r|   }|  | |||| | ||||||||\}	}
d}|	d ur<|	jtd kr<| j  t| jdr<d}|	 rZ|sL|	d u sL|	j| j
v rZ| ||||||	||
||
S |	j| jv rh| j|	j |	|	jtd krqd S |	j| jv sJ d|	j |	jddkrd	S z|	 W S  ty   t|	d w )
NFrL   refreshT
no_contentzUnexpected status code: r   0 )ri   r3   rX   r   rz   r   rY   _clear_access_tokenhasattrr   RETRY_STATUSESr   STATUS_EXCEPTIONSSUCCESS_STATUSESr   r   ro   
ValueErrorr   )r+   rQ   rm   ro   rS   rU   rv   rW   rs   rq   rt   do_retryr)   r)   r,   r|      sb   



zSession._request_with_retriesdict[str, str]c                 C  s2   | j  st| j dr| j   dd| j j iS )Nr   Authorizationzbearer )rY   is_validr   r   access_tokenr*   r)   r)   r,   r     s   
zSession._set_header_callbackc                 C  s   | j   dS )z+Close the session and perform any clean up.N)r[   r_   r*   r)   r)   r,   r_     s   zSession.closepathdict[str, Any] | None dict[str, BufferedReader] | Nonec           	   	   C  sz   t |pi }d|d< t|trt |}d|d< t| }t|tr*t |}d|d< t| jj|}| j|||||||dS )a  Return the json content from the resource at ``path``.

        :param method: The request verb. E.g., ``"GET"``, ``"POST"``, ``"PUT"``.
        :param path: The path of the request. This path will be combined with the
            ``oauth_url`` of the Requestor.
        :param data: Dictionary, bytes, or file-like object to send in the body of the
            request.
        :param files: Dictionary, mapping ``filename`` to file-like object.
        :param json: Object to be serialized to JSON in the body of the request.
        :param params: The query parameters to send with the request.
        :param timeout: Specifies a particular timeout, in seconds.

        Automatically refreshes the access token if it becomes invalid and a refresh
        token is available.

        :raises: :class:`.InvalidInvocation` in such a case if a refresh token is not
            available.

        r   raw_jsonro   api_type)rQ   rm   ro   rS   rU   rv   rW   )	r   rf   dictsorteditemsr	   r[   	oauth_urlr|   )	r+   rS   r   rQ   rm   ro   rU   rv   rW   r)   r)   r,   r   !  s&   

zSession.request)
rQ   rR   rS   rT   rU   rV   rW   rT   r&   r/   )r&   r$   )r&   r<   r7   )rb   rc   rd   re   r&   r/   )rQ   rl   rm   rn   ro   rp   rS   rT   rU   rV   rq   rr   rs   rh   rt   ru   rv   rw   rW   rT   r&   rx   )rQ   rl   rm   rn   ro   rp   rS   rT   rU   rp   rs   rh   rv   rw   rW   rT   r&   r   r(   )rQ   rl   rm   rn   ro   rp   rS   rT   rU   rV   rv   rw   rW   rT   rs   r   r&   rx   )r&   r   )rS   rT   r   rT   rQ   r   rm   r   ro   r   rU   r   rv   rw   r&   rx   )&r8   r9   r:   r;   r
   r   r   r   r   r   r   r   r   r   r    r   r   r   r   r   r   r   r   staticmethodrX   propertyr[   r^   ra   r   rk   r   r   r|   r   r_   r   r   r)   r)   r)   r,   r<   E   s    
		





5
>
r<   rb   r#   rd   re   r&   c                 C  s   t | |dS )zReturn a :class:`.Session` instance.

    :param authorizer: An instance of :class:`.Authorizer`.
    :param window_size: The size of the rate limit reset window in seconds.

    rb   rd   )r<   r   r)   r)   r,   sessionS  s   
r   c                   @  s:   e Zd ZdZddddZdd
dZdddZdddZdS )rh   zCA ``RetryStrategy`` that retries requests a finite number of times.   retriesre   r&   r/   c                 C  s
   || _ dS )zrInitialize the strategy.

        :param retries: Number of times to attempt a request (default: ``3``).

        N_retries)r+   r   r)   r)   r,   rk   c  s   
zFiniteRetryStrategy.__init__r'   c                 C  s0   | j dk r| j dkrdnd}|dt   S d S )Nr      r   )r   random)r+   baser)   r)   r,   r-   k  s   
z"FiniteRetryStrategy._sleep_secondsc                 C  s   t | | jd S )zAllow one fewer retry.r   )typer   r*   r)   r)   r,   r}   q  s   z+FiniteRetryStrategy.consume_available_retryboolc                 C  s
   | j dkS )zEReturn ``True`` if and only if the strategy will allow another retry.r   r   r*   r)   r)   r,   r   u  r\   z+FiniteRetryStrategy.should_retry_on_failureN)r   )r   re   r&   r/   r6   )r&   rh   )r&   r   )r8   r9   r:   r;   rk   r-   r}   r   r)   r)   r)   r,   rh   `  s    

rh   )rb   r#   rd   re   r&   r<   )=r;   
__future__r   loggingr   r2   abcr   r   copyr   pprintr   typingr   r   urllib.parser	   requests.exceptionsr
   r   r   requests.status_codesr   authr   constr   r   
exceptionsr   r   r   r   r   r   r   r   r   r   r   r   r   
rate_limitr   utilr    ior!   requests.modelsr"   r#   	requestorr$   	getLogger__package__r0   r%   r<   r   rh   r)   r)   r)   r,   <module>   s>    <
  