o
    K&b                     @   s   d dl Z d dlZd dlZd dlmZ d dlmZmZm	Z	m
Z
mZ d dlmZ d dlmZ d dlmZmZmZmZ G dd de jd	ZdS )
    N)join)AnyDictOptionalTupleType)error)	urlencode)config
exceptionsutilversionc                	   @   s   e Zd ZdZdZeejdee	 fddZ
eejdefddZddeej ddfdd	Zd
d Z	dddZdefddZdedeeeeef  eeeef  f fddZdS )UAServiceClientNreturnc                 C      dS )z1Set in subclasses to the type of API error raisedN selfr   r   8/usr/lib/python3/dist-packages/uaclient/serviceclient.pyapi_error_cls      zUAServiceClient.api_error_clsc                 C   r   )z@String in subclasses, the UAConfig attribute containing base urlNr   r   r   r   r   cfg_url_base_attr   r   z!UAServiceClient.cfg_url_base_attrcfgc                 C   s   |s	t  | _d S || _d S N)r
   UAConfigr   )r   r   r   r   r   __init__   s   
zUAServiceClient.__init__c                 C   s   d t dddS )NzUA-Client/{}application/json)z
user-agentZacceptcontent-type)formatr   Zget_versionr   r   r   r   headers%   s   zUAServiceClient.headersc                 C   sX  | d}|s|  }|ddkr|rt|d}tt| j| j	|}| 
|\}}|r3||fS |rHdd t| D }	|dt|	 7 }ztj||||| jd\}
}W |
|fS  tjy } zDd }t|d	rn|j}nt|d
rz| d}|rz
tj|tjd}W n ty   d }Y nw |r| ||tj|t|dd ||dd }~ww )N/r   r   zutf-8c                 S   s   i | ]\}}|d ur||qS r   r   ).0kvr   r   r   
<dictcomp>:   s
    z/UAServiceClient.request_url.<locals>.<dictcomp>?)urldatar   methodZtimeoutbodyread)clscoder,   r   r&   )lstripr   getjsondumpsencodeurljoingetattrr   r   _get_fake_responsessorteditemsr	   r   Zreadurlurl_timeoutr   URLErrorhasattrr)   r*   decodeloadsZDatetimeAwareJSONDecoder
ValueErrorr   r   UrlError)r   pathr'   r   r(   Zquery_paramsr&   Zfake_responseZfake_headersZfiltered_paramsresponseer)   Zerror_detailsr   r   r   request_url,   sX   




zUAServiceClient.request_urlr&   c                 C   sf   | j dur| j |g S | jjd}|si | _ ntj|s#i | _ n	tt	
|| _ | j |g S )a.  Return a list of fake response dicts for a given URL.

        serviceclient_url_responses in uaclient.conf should be a path
        to a json file which contains a dictionary keyed by full URL path.
        Each value will be a list of dicts representing each faked response
        for the given URL.

            The response dict item will have a code: <HTTP_STATUS_CODE> and
               response: "some string of content".
            The JSON string below fakes the available_resources URL on the
            contract server:
            '{"https://contracts.canonical.com/v1/resources":                [{"code": 200, "response": {"key": "val1", "key2": "val2"}}]}'

        :return: List of dicts for each faked response matching the url, or
           and empty list when no matching url found.
        NZserviceclient_url_responses)_response_overlayr/   r   Zfeaturesosr?   existsr0   r<   r   Z	load_file)r   r&   Zresponse_overlay_pathr   r   r   _get_response_overlayZ   s   
z%UAServiceClient._get_response_overlayc                 C   s   |  |}|sdi fS t|dkr|d }n|d}|d dkr+|d |di fS t|d }tj||d |di |d)	a  Return response and headers if faked for this URL in uaclient.conf.

        :return: A tuple of response and header dicts if the URL has an overlay
            response defined. Return (None, {}) otherwise.

        :raises exceptions.URLError: When faked response "code" is != 200.
            URLError reason will be "response" value and any optional
            "headers" provided.
        N   r   r,      r@   r   r-   )rF   lenpopr/   r   r9   r   r>   )r   r&   Z	responsesr@   rA   r   r   r   r5   |   s   



z#UAServiceClient._get_fake_responsesr   )NNNN)__name__
__module____qualname__r8   rC   propertyabcabstractmethodr   	Exceptionr   strr   r   r
   r   r   r   rB   rF   r   r   r   r5   r   r   r   r   r      s&    
.""r   )	metaclass)rO   r0   rD   	posixpathr   r3   typingr   r   r   r   r   Zurllibr   Zurllib.parser	   Zuaclientr
   r   r   r   ABCMetar   r   r   r   r   <module>   s    