o
    X¨Êh‘"  ã                   @   s˜   d 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y9   ddlZddlm
Z
 ddlmZ Y nw 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   úK/var/www/html/env/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_dict3   s   zResponse.to_dictN)
Ú__name__Ú
__module__Ú__qualname__Ú__doc__r   Úpropertyr   r   r   r   r   r   r   r   r      s    



r   c                   @   sp   e Zd Z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.NFc                 C   s:   || _ |pi | _|| _|pg | _g d¢| _|| _|| _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
        )ÚdeleteÚgetÚpatchÚpostÚputN)ÚhostÚrequest_headersÚ_versionÚ	_url_pathÚmethodsÚappend_slashÚtimeout)r   r(   r)   ÚversionÚurl_pathr-   r.   r   r   r   r   A   s   



zClient.__init__c                 C   s   d  | jt| jƒ|¡S )zþSubclass 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{0}/v{1}{2})Úformatr(   Ústrr*   )r   Úurlr   r   r   Ú_build_versioned_urla   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 | j	| }|S )z¹Build 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/{0}r   ú/Tz{0}?{1})
Úlenr+   r1   r-   r   ÚsortedÚitemsr*   r4   r(   )r   Úquery_paramsr3   ÚcountÚ
url_valuesr   r   r   Ú
_build_urlk   s    þ

ÿzClient._build_urlc                 C   s   | j  |¡ dS )z²Update 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 )z‹Make a new Client object

        :param name: Name of the url segment
        :type name: string
        :return: A Client object
        )r(   r/   r)   r0   r-   r.   )r+   r"   r(   r*   r)   r-   r.   )r   Únamer0   r   r   r   Ú_build_client�   s   ûzClient._build_clientc              
   C   sF   |p| j }z|j||d�W S  ty" } z	t|ƒ}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)r.   Úopenr   r   Ú	__cause__)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
        )rA   )r   r@   r   r   r   Ú_²   s   

zClient._c                    sF   |dkr‡fdd„}|S |ˆj v r| ¡ ‰ ‡ ‡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*   rA   )ÚargsÚkwargsr   r   r   Úget_versionÈ   s   
z'Client.__getattr__.<locals>.get_versionc            	         s  d|v rˆ  |d ¡ d|vrd}n)dˆjv r1ˆjd dkr&|d  d¡}nt |d ¡ d¡}n
t |d ¡ d¡}d|v rD|d }nd}t ¡ }tjˆ |¡|d�}ˆjrgˆj 	¡ D ]
\}}| 
||¡ q\|rtdˆjvrt| 
dd	¡ ‡ fd
d„|_| dd¡}tˆj|||d�ƒS )zŒMake the API call
                :param args: unused
                :param kwargs:
                :return: Client object
                r)   Úrequest_bodyNzContent-Typez(application                        /jsonr   r:   )Údatazapplication/jsonc                      s   ˆ S ©Nr   r   )Úmethodr   r   Ú<lambda>ú   s    z:Client.__getattr__.<locals>.http_request.<locals>.<lambda>r.   rB   )r?   r)   Úencoder   ÚdumpsÚurllibÚbuild_openerÚRequestr=   r9   Ú
add_headerÚ
get_methodÚpopr   rI   )	rJ   rL   rO   ÚparamsrE   rF   ÚkeyÚvaluer.   ©rQ   r   r   r   Úhttp_requestÖ   s<   
ÿÿÿÿ
z(Client.__getattr__.<locals>.http_request)r,   ÚupperrJ   )r   r@   rM   r_   r   r^   r   Ú__getattr__¾   s   	
'
zClient.__getattr__c                 C   r   rP   ©Ú__dict__r   r   r   r   Ú__getstate__  s   zClient.__getstate__c                 C   s
   || _ d S rP   rb   )r   Ústater   r   r   Ú__setstate__  s   
zClient.__setstate__)NNNFNrP   )r   r   r   r    r   r4   r=   r?   rA   rI   rJ   ra   rd   rf   r   r   r   r   r"   >   s"    
ú 

	
Dr"   )r    r   Ú
exceptionsr   Úurllib.requestrF   rU   Úurllib.parser   Úurllib.errorr   ÚImportErrorÚurllib2Úobjectr   r"   r   r   r   r   Ú<module>   s    ü-