o
    w+f&                     @   s   d Z ddlZddlZddlmZ zddlmZ ddlm	Z	 ddl
mZ W n ey=   ddlZddlmZ ddlm	Z	 Y nw eeZG dd deZG d	d
 d
eZdS )zHTTP Client library    N   )handle_error)	urlencode)	HTTPErrorc                   @   sH   e Zd ZdZdd Zedd Zedd Zedd	 Zed
d Z	dS )Responsez$Holds the response from an API call.c                 C   s"   |  | _| | _| | _dS )z
        :param response: The return value from a open call
                         on a urllib.build_opener()
        :type response:  urllib response object
        N)getcode_status_coderead_bodyinfo_headers)selfresponse r   L/var/www/html/venv/lib/python3.10/site-packages/python_http_client/client.py__init__   s   

zResponse.__init__c                 C      | j S )z;
        :return: integer, status code of API call
        )r   r   r   r   r   status_code!      zResponse.status_codec                 C   r   )z0
        :return: response from the API
        )r
   r   r   r   r   body(   r   zResponse.bodyc                 C   r   )z3
        :return: dict of response headers
        )r   r   r   r   r   headers/   r   zResponse.headersc                 C   s   | j rt| j dS dS )z8
        :return: dict of response from the API
        utf-8N)r   jsonloadsdecoder   r   r   r   to_dict6   s   zResponse.to_dictN)
__name__
__module____qualname____doc__r   propertyr   r   r   r   r   r   r   r   r      s    



r   c                   @   sx   e Zd ZdZh dZ					dddZdd Zd	d
 Zdd ZdddZ	dddZ
dd Zdd Zdd Zdd ZdS )Clientz4Quickly and easily access any REST or REST-like API.>   getputpostpatchdeleteNFc                 C   s0   || _ |pi | _|| _|pg | _|| _|| _dS )a  
        :param host: Base URL for the api. (e.g. https://api.sendgrid.com)
        :type host:  string
        :param request_headers: A dictionary of the headers you want
                                applied on all calls
        :type request_headers: dictionary
        :param version: The version number of the API.
                        Subclass _build_versioned_url for custom behavior.
                        Or just pass the version as part of the URL
                        (e.g. client._("/v3"))
        :type version: integer
        :param url_path: A list of the url path segments
        :type url_path: list of strings
        N)hostrequest_headers_version	_url_pathappend_slashtimeout)r   r(   r)   versionurl_pathr,   r-   r   r   r   r   G   s   


zClient.__init__c                 C   s   d | jt| j|S )zSubclass this function for your own needs.
           Or just pass the version as part of the URL
           (e.g. client._('/v3'))
        :param url: URI portion of the full URL being requested
        :type url: string
        :return: string
        z{}/v{}{})formatr(   strr*   )r   urlr   r   r   _build_versioned_urle   s   zClient._build_versioned_urlc                 C   s   d}d}|t | jk r |d| j| 7 }|d7 }|t | jk s| jr'|d7 }|r8tt| d}d||}| jrB| |}|S d| j	|}|S )	zBuild the final URL to be passed to urllib

        :param query_params: A dictionary of all the query parameters
        :type query_params: dictionary
        :return: string
         r   z/{}r   /Tz{}?{}z{}{})
lenr+   r0   r,   r   sorteditemsr*   r3   r(   )r   query_paramsr2   count
url_valuesr   r   r   
_build_urlo   s    
zClient._build_urlc                 C   s   | j | dS )zUpdate the headers for the request

        :param request_headers: headers to set for the API call
        :type request_headers: dictionary
        :return: dictionary
        N)r)   update)r   r)   r   r   r   _update_headers   s   zClient._update_headersc                 C   s4   |r| j |g n| j }t| j| j| j|| j| jdS )zMake a new Client object

        :param name: Name of the url segment
        :type name: string
        :return: A Client object
        )r(   r.   r)   r/   r,   r-   )r+   r"   r(   r*   r)   r,   r-   )r   namer/   r   r   r   _build_client   s   zClient._build_clientc              
   C   sd   |p| j }z|j||dW S  ty1 } zt|}d|_tdj| |j	|j
d |d}~ww )a  Make the API call and return the response. This is separated into
           it's own function, so we can mock it easily for testing.

        :param opener:
        :type opener:
        :param request: url payload to request
        :type request: urllib.Request object
        :param timeout: timeout value or None
        :type timeout: float
        :return: urllib response
        r-   N"{method} Response: {status} {body}methodstatusr   )r-   openr   r   	__cause___loggerdebugr0   
get_methodr   r   )r   openerrequestr-   errexcr   r   r   _make_request   s   
zClient._make_requestc                 C   s
   |  |S )aD  Add variable values to the url.
           (e.g. /your/api/{variable_value}/call)
           Another example: if you have a Python reserved word, such as global,
           in your url, you must use this method.

        :param name: Name of the url segment
        :type name: string
        :return: Client object
        )r@   )r   r?   r   r   r   _   s   

zClient._c                    sP   |dkrfdd}|S |j v r#|  				d fdd	}|S |S )aD  Dynamically add method calls to the url, then call a method.
           (e.g. client.name.name.method())
           You can also add a version number by using .version(<int>)

        :param name: Name of the url segment or method call
        :type name: string or integer if name == version
        :return: mixed
        r.   c                     s   | d  _   S )z
                :param args: dict of settings
                :param kwargs: unused
                :return: string, version
                r   )r*   r@   )argskwargsr   r   r   get_version   s   
z'Client.__getattr__.<locals>.get_versionNc           	         s  |r | | du rd}n!djv r jd dkr | d}njdd t| d}t }tj	|j|d} fdd|_
tdj | d	 |jr_td
j|jd tdj|jd tj|||d}tdj |j|jd |S )a  Make the API call
                :param timeout: HTTP request timeout. Will be propagated to
                    urllib client
                :type timeout: float
                :param request_headers: HTTP headers. Will be merged into
                    current client object state
                :type request_headers: dict
                :param query_params: HTTP query parameters
                :type query_params: dict
                :param request_body: HTTP request body
                :type request_body: string or json-serializable object
                :param kwargs:
                :return: Response object
                NzContent-Typezapplication/jsonr   )r   datac                      s    S Nr   r   )rD   r   r   <lambda>	  s    z:Client.__getattr__.<locals>.http_request.<locals>.<lambda>z{method} Request: {url})rD   r2   zPAYLOAD: {data})rT   zHEADERS: {headers})r   rA   rB   rC   )r>   r)   encode
setdefaultr   dumpsurllibbuild_openerRequestr<   rJ   rH   rI   r0   get_full_urlrT   r   r   rO   r   r   )	request_bodyr9   r)   r-   rP   rT   rK   rL   r   rD   r   r   r   http_request   sP   

z(Client.__getattr__.<locals>.http_request)NNNN)methodsupperrP   )r   r?   rS   r`   r   r_   r   __getattr__   s   	
A
zClient.__getattr__c                 C   r   rU   __dict__r   r   r   r   __getstate__$  s   zClient.__getstate__c                 C   s
   || _ d S rU   rd   )r   stater   r   r   __setstate__'  s   
zClient.__setstate__)NNNFNrU   )r   r   r   r    ra   r   r3   r<   r>   r@   rO   rP   rc   rf   rh   r   r   r   r   r"   A   s$    


	
^r"   )r    r   logging
exceptionsr   urllib.requestrL   rZ   urllib.parser   urllib.errorr   ImportErrorurllib2	getLoggerr   rH   objectr   r"   r   r   r   r   <module>   s     
-