o
    Mi                     @   s   d dl Z d dlmZmZmZmZmZmZmZ d dl	m
Z
 d dlZddlmZ ddlmZmZmZ e eZG dd deZeeeef eeeef  f Zeeee f ZG d	d
 d
ZdddZdS )    N)AnyDictOptionalUnionListTupleSequence)	urlencode   )AroFloSettings)build_authorization_valuebuild_timestampbuild_hmac_signaturec                   @   s   e Zd ZdZdS )AroFloErroru/   Error genérico al hablar con la API de AroFlo.N)__name__
__module____qualname____doc__ r   r   >/var/www/html/flask_server/apps/aroflo_connector_app/client.pyr      s    r   c                   @   s   e Zd ZdZ		ddee deej ddfddZ	ddddd	dddd
de	de	dee
 dedede	dee dee dee dedefddZdee
 de	dede
fddZd	dde
de	defddZdS ) AroFloClientu   
    Cliente para la API de AroFlo.

    - Carga settings desde .env
    - Construye headers HMAC (igual Postman)
    - Hace request genérico y parsea JSON
    Nsettingssessionreturnc                 C   s2   |pt  | _|pt | _| jjddi d S )Nz
User-Agentzaroflo-connector-app/0.0.1)r   from_envr   requestsSessionr   headersupdate)selfr   r   r   r   r   __init__&   s   zAroFloClient.__init__GET )paramsdatajson
var_stringorderorder_byorderbypathmethodr#   r$   r%   r&   r'   r(   r)   kwargsc             
   K   sV  |pd  }|d u r|p|	}d|
v r|d u r|
d}n|
dd  d|
v r0|d u r0|
d}n|
dd  |d urA| |d|}| jjd}|rS|d|d 7 }|se|r\t|}n	t|t	ret|}t
| j}t }t||prd||| jd\}}|
di pi }i ||}t|t	rd	|vrd
|d	< |d urd	|vrd|d	< |
d| jj}td||||d urt|jnd |d urdnd | z| jj||f|||||d|
}W n tjy } ztd| |d }~ww z| }W n ty } ztd|j d|j|d }~ww |d}|jdks|dvr)td|j d||S )Nr!   r(   r)   r'   /r"   )request_typer&   authorizationiso_timestampr   r   zContent-Typez!application/x-www-form-urlencodedzapplication/jsontimeoutz<AroFlo request %s %s params=%s data=%s json=%s var_string=%sz<json>)r#   r$   r%   r   r1   z%Error de red al conectar con AroFlo: z'Respuesta no JSON desde AroFlo (status=z): statusi  )N0r   OKz#Error en respuesta de AroFlo. HTTP=z
, payload=)upperpop_inject_multi_paramr   base_urlrstriplstripr	   
isinstancedictr   r   r   r1   logdebugtyper   r   requestr   RequestExceptionr   r%   
ValueErrorstatus_codetextget)r   r*   r+   r#   r$   r%   r&   r'   r(   r)   r,   method_uurlr/   iso_ts_hmac_headersextra_headersr   r1   respexc	data_respr2   r   r   r   r@   /   s   







zAroFloClient.requestkeyvaluec           	      C   s   t |ttfrdd |D }nt| rt|gng }|s"|p!i S |du r6g }|D ]	}|||f q*|S t |trMt|}|D ]	}|||f qA|S t|dkr[|d ||< |S dd | D }|D ]	}|||f qf|S )uE  
        Inserta un parámetro que puede repetirse (where/join/order) de forma segura.

        - Si params es None: crea lista de tuplas.
        - Si params es dict: si value es str -> set simple; si value es lista -> convierte a lista de tuplas.
        - Si params es lista de tuplas: agrega una o varias tuplas.
        c                 S   s(   g | ]}|d urt | rt |qS N)strstrip).0vr   r   r   
<listcomp>   s   ( z4AroFloClient._inject_multi_param.<locals>.<listcomp>Nr
   r   c                 S   s   g | ]
\}}|t |fqS r   )rR   )rT   krU   r   r   r   rV      s    )r;   listtuplerR   rS   appendlenitems)	r   r#   rO   rP   valuesoutrU   out2out3r   r   r   r7      s,   
z AroFloClient._inject_multi_param)r*   c                C   s   | j |d|dS )Nr!   )r+   r#   )r@   )r   r#   r*   r   r   r   rE      s   zAroFloClient.get)NN)r!   )r   r   r   r   r   r   r   r   r    rR   
ParamsTyper   MultiStrr@   r7   rE   r   r   r   r   r      sj    



p
 1r   r   c                   C   s   t  S rQ   )r   r   r   r   r   
get_client   s   rc   )r   r   )loggingtypingr   r   r   r   r   r   r   urllib.parser	   r   configr   authr   r   r   	getLoggerr   r=   RuntimeErrorr   rR   ra   rb   r   rc   r   r   r   r   <module>   s   $
  8