o
    iy                     @   s  d dl Z d dlZd dlZd dlZd dlZd dlZd dlmZ d dlZe	e
Zdd ZdedefddZd	d
dededefddZdedededefddZdedefddZ							d=dededededB dedB dededB dedB dededB fdd Ze
d!kreej eed"sG d#d$ d$Ze Zed%d&d'd(d)id*d+id,d-d.id/ ed0d1d2d3d4d5id6d7d8 ed9d&d:d,d;d< dS dS )>    N)Anyc               
   C   sf   t  } tj| d}z
tj|dd W |S  ty2 } ztd|t	| | W  Y d}~S d}~ww )zZEnsures the API log directory exists within ComfyUI's temp directory and returns its path.api_logsTexist_okz'Error creating API log directory %s: %sN)
folder_pathsget_temp_directoryospathjoinmakedirs	Exceptionloggererrorstr)base_temp_dirlog_dire r   A/mnt/c/Users/fbmor/ComfyUI/comfy_api_nodes/util/request_logger.pyget_log_directory   s   r   namereturnc                 C   s,   | sdS t dd| }|d}|sd}|S )Nlogz[^A-Za-z0-9._-]+_z ._)resubstrip)r   	sanitizedr   r   r   _sanitize_filename_component   s   
r   
   )lengthpartsr    c                 G   s"   t d|d d |  S )N|utf-8)hashlibsha1r
   encode	hexdigest)r    r!   r   r   r   _short_hash%   s   "r(   r   operation_idrequest_urlc                 C   s   t j  d}t|}t|pd|pd}d}| d}d| d}|s&d}td|t|  d }	td	|	t| t| }
t||
krM|d
|
 d}tj	
| | | | S )zgBuild log filepath. We keep it well under common path length limits aiming for <= 240 characters total.z%Y%m%d_%H%M%S_%f    r   z.logop<         Nz ._-)datetimenowstrftimer   r(   maxlenrstripr   r	   r
   )r   r)   r*   	timestampslughmax_total_pathprefixsuffixmax_filename_lenmax_slug_lenr   r   r   _build_log_filepath)   s   
r?   datac                 C   s~   t | trz| dW S  ty   dt|  d Y S w t | ttfr;z	tj| dddW S  t	y:   t
|  Y S w t
| S )z5Helper to format data (dict, str, bytes) for logging.r#   z[Binary data of length z bytes]   F)indentensure_ascii)
isinstancebytesdecodeUnicodeDecodeErrorr5   dictlistjsondumps	TypeErrorr   )r@   r   r   r   _format_data_for_logging=   s   
rM   request_methodrequest_headersrequest_paramsrequest_dataresponse_status_coderesponse_headersresponse_contenterror_messagec
              
   C   s  zt  }
t|
| |}g }|dtj    |d|   |d |d|  |d|  |rB|dt|  |rN|dt|  |dur\|d	t|  |d
 |durm|d|  |ry|dt|  |dur|dt|  |	r|d|	  z)t|ddd}|d	| W d   n1 sw   Y  t
d| W W dS  ty } zt
d|t| W Y d}~W dS d}~ww  ty } ztd| W Y d}~dS d}~ww )z
    Logs API request and response details to a file in the temp/api_logs directory.
    Filenames are sanitized and length-limited for cross-platform safety.
    If we still fail to write, we fall back to appending into api.log.
    zTimestamp: zOperation ID: zE------------------------------ REQUEST ------------------------------zMethod: zURL: z	Headers:
zParams:
NzData/Body:
zG
------------------------------ RESPONSE ------------------------------zStatus Code: z	Content:
zError:
wr#   )encoding
zAPI log saved to: %szError writing API log to %s: %sz'[DEBUG] log_request_response failed: %s)r   r?   appendr1   r2   	isoformatrM   openwriter
   r   debugr   r   r   logging)r)   rN   r*   rO   rP   rQ   rR   rS   rT   rU   r   filepathlog_contentfr   _log_er   r   r   log_request_responseL   sJ   

"rc   __main__r   c                   @   s   e Zd Zdd ZdS )MockFolderPathsc                 C   s(   t jt jtd}t j|dd |S )Ntemp_test_logsTr   )r   r	   r
   dirname__file__r   )selfpr   r   r   r      s   z"MockFolderPaths.get_temp_directoryN)__name__
__module____qualname__r   r   r   r   r   re      s    re   test_operation_getGETzhttps://api.example.com/testAuthorizationzBearer testtokenparam1value1   messagezSuccess!)r)   rN   r*   rO   rP   rR   rT   test_operation_post_errorPOSTzhttps://api.example.com/submitvaluenum{   )keynestedzConnection timed out)r)   rN   r*   rQ   rU   test_binary_responsez!https://api.example.com/image.pngs   PNG

   IHDR...)r)   rN   r*   rR   rT   )NNNNNNN)r1   r$   rJ   r^   r   r   typingr   r   	getLoggerrk   r   r   r   r   intr(   r?   rM   rH   rc   setLevelDEBUGhasattrre   r   r   r   r   <module>   s    

	

6
	
