
    |	Ii              	          d Z ddlZddlZddlZddl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 	 ddlZddlZddlZ ej*                  e      Z e	d      Z G d d	      Zed"d
edefd       Zd#d
ededefdZd$d
edededefdZde
de
fdZ d%dededefdZ!d&dede"de"fdZ#d'dede"dedefdZ$ G d d      Z%d(dededefd Z&dedefd!Z'y# e$ r dZY w xY w))zA
Utility Functions
File operations, JSON handling, async helpers
    N)AnyDictOptionalTypeVarCallable)Pathwraps)contextmanagerTc                   (    e Zd ZdZdefdZd Zd Zy)AtomicFileWriteru6   Écriture atomique de fichiers pour éviter corruptionfilepathc                 2    t        |      | _        d | _        y N)r   r   	temp_file)selfr   s     ,/home/ubuntu/crypto_trading_bot/api/utils.py__init__zAtomicFileWriter.__init__   s    X    c           	          t        j                  ddd| j                  j                  d| j                  j                   d      | _        | j
                  S )u   Créer fichier temporairewutf-8Fz.tmp__)modeencodingdeletedirprefix)tempfileNamedTemporaryFiler   parentnamer   r   s    r   	__enter__zAtomicFileWriter.__enter__!   sM    !44$$4==--.a0
 ~~r   c                    | j                   r}| j                   j                          |6	 t        j                  | j                   j                  | j
                         y	 t        j                  | j                   j                         yy# t        $ rG}t        j                  d|        t        j                  | j                   j                          d}~ww xY w#  Y yxY w)u+   Déplacer le fichier temporaire ou nettoyerNu   Erreur déplacement fichier: )r   closeshutilmover#   r   	Exceptionloggererrorosunlink)r   exc_typeexc_valexc_tbes        r   __exit__zAtomicFileWriter.__exit__,   s    >>NN  "KK 3 3T]]CIIdnn112  ! LL#@!DEIIdnn112s$   4B  )C 	CACCC"N)__name__
__module____qualname____doc__strr   r%   r3    r   r   r   r      s    @ 	r   r   r   timeoutc              #     K   |  d}d}	 t        j                  |t         j                  t         j                  z        }t         j                  dk7  roddl}|j                         }|j                         |z
  |k  r7	 t        j                  |t        j                  t        j                  z         nt        d|        d |d	 t         j                  dk7  r$t        j                  |t        j                         t        j                  |       	 t        j                  |       yy# t        $ r |j                  d       Y nw xY w|j                         |z
  |k  r猱#  Y TxY w#  Y yxY w# |s	 t         j                  dk7  r$t        j                  |t        j                         t        j                  |       n#  Y nxY w	 t        j                  |       w #  Y w xY ww xY ww)u;   Context manager pour lock fichier (éviter race conditions)z.lockNntr   g?zCannot acquire lock for )r-   openO_CREATO_WRONLYr#   timefcntlflockLOCK_EXLOCK_NBIOErrorsleepTimeoutErrorLOCK_UNr'   r.   )r   r:   	lock_filelock_fdr@   starts         r   	file_lockrL   A   s     *E"IG'')RZZ"++%=> 77d?IIKE))+%/$KK)FG #%=hZ#HII 77d?KK7!		)$   $JJsO$	 ))+%/" 77d?KK7!		)$ s   G-A2E3 >5D- 3E3 G-	AE% E, +G--E
E3 	E

E3 %E)'G-,E0.G-3G*7AGG*GG*G"!G*"G&$G**G-defaultreturnc                    	 t         j                  j                  |       st        j	                  d|         ||S i S t        | d      5  t        | dd      5 }t        j                  |      }|cddd       cddd       S # 1 sw Y   nxY w	 ddd       y# 1 sw Y   yxY w# t        j                  $ r+}t        j                  d|  d	|        ||ni cY d}~S d}~wt        $ rf t        j                  d
|         	 t        | dd      5 }t        j                  |      cddd       cY S # 1 sw Y   nxY wY y#  ||ni cY cY S xY wt        $ r+}t        j                  d|  d	|        ||ni cY d}~S d}~ww xY w)u   
    Charger un fichier JSON de manière sécurisée

    Args:
        filepath: Chemin du fichier
        default: Valeur par défaut si erreur ou fichier inexistant

    Returns:
        Données JSON ou valeur par défaut
    zFile not found: N       @r:   rr   )r   zJSON decode error in : zTimeout acquiring lock for zError reading )r-   pathexistsr+   debugrL   r=   jsonloadJSONDecodeErrorr,   rG   warningr*   )r   rM   fdatar2   s        r   load_json_filer]   h   sv   6ww~~h'LL+H:67%179r9x- 	hg6 !yy| 	 	  	 	 	
  6,XJb<=!-w25 :4XJ?@	:hg6 $!yy|$ $ $ $	:%17r9 6~hZr!56!-w256s   :B' B' B' BB2	B;	B' B	
BB' B$ B' $B' 'F: C F $FED4(	E1F4D=	9EE
FF E?9F?Fr\   prettyc                    	 t        j                  t         j                  j                  |       xs dd       t	        | d      5  t        |       5 }|rt        j                  ||dd       nt        j                  ||d	       |j                  d
       ddd       ddd       y# 1 sw Y   xY w# 1 sw Y   yxY w# t        $ r%}t        j                  d|  d|        Y d}~yd}~ww xY w)u   
    Sauvegarder un fichier JSON de manière atomique

    Args:
        filepath: Chemin du fichier
        data: Données à sauvegarder
        pretty: Formater avec indentation

    Returns:
        True si succès, False sinon
    .T)exist_okrP   rQ      F)indentensure_ascii)rd   
NzError writing rS   )r-   makedirsrT   dirnamerL   r   rW   dumpwriter*   r+   r,   )r   r\   r^   r[   r2   s        r   save_json_filerj      s    
BGGOOH-4tDx- 	!(+ qIIdAaeDIIdAE:	  	  ~hZr!56sO   AC B6AB*B6!C *B3	/B66B?;C ?C 	C0C++C0	coro_funcc                 .     t                fd       }|S )uC   Décorateur pour exécuter une fonction async de manière synchronec                      	 t        j                         }|j                   | i |      S # t        $ r, t        j                         }t        j                  |       Y Kw xY wr   )asyncioget_event_loopRuntimeErrornew_event_loopset_event_looprun_until_complete)argskwargslooprk   s      r   wrapperzasync_to_sync.<locals>.wrapper   s`    	)))+D
 &&y$'A&'ABB	  	)))+D""4(	)s   . 2A#"A#r	   )rk   rw   s   ` r   async_to_syncrx      s#    
9C C Nr   valuec                 H    	 t        |       S # t        t        f$ r |cY S w xY w)u*   Convertir en float de manière sécurisée)float
ValueError	TypeErrorry   rM   s     r   
safe_floatr      s*    U|	"    
 !!c                 H    	 t        |       S # t        t        f$ r |cY S w xY w)u(   Convertir en int de manière sécurisée)intr|   r}   r~   s     r   safe_intr      s*    5z	" r   s
max_lengthsuffixc                 J    t        |       |k  r| S | d|t        |      z
   |z   S )u#   Tronquer une chaîne si trop longueN)len)r   r   r   s      r   truncate_stringr      s/    
1v&j3v;&'&00r   c                   <    e Zd ZdZd
defdZdefdZdefdZ	d Z
y	)CircularBufferz)Buffer circulaire pour logging/monitoringmax_sizec                 .    || _         g | _        d| _        y )Nr   )r   bufferindex)r   r   s     r   r   zCircularBuffer.__init__   s     
r   itemc                     t        | j                        | j                  k  r| j                  j                  |       y|| j                  | j                  <   | j                  dz   | j                  z  | _        y)u   Ajouter un élément au buffer   N)r   r   r   appendr   )r   r   s     r   r   zCircularBuffer.append   sS    t{{dmm+KKt$&*DKK

#**q.DMM9DJr   rN   c                     t        | j                        | j                  k  r| j                  j                         S | j                  | j                  d | j                  d| j                   z   S )u,   Récupérer tous les éléments dans l'ordreN)r   r   r   copyr   r$   s    r   get_allzCircularBuffer.get_all   sS    t{{dmm+;;##%%{{4::;'$++ktzz*BBBr   c                 F    | j                   j                          d| _        y)zVider le bufferr   N)r   clearr   r$   s    r   r   zCircularBuffer.clear   s    
r   N)d   )r4   r5   r6   r7   r   r   r   r   listr   r   r9   r   r   r   r      s0    3 
:3 :C Cr   r   pnlcurrencyc                 (    | dk\  rdnd}| | dd| S )zFormater un P&L avec couleurr   + .2f r9   )r   r   signs      r   
format_pnlr      s&    (3DVC9AhZ((r   c                 $    | dk\  rdnd}| | ddS )zFormater un pourcentager   r   r   r   %r9   )ry   r   s     r   format_percentager      s"    1*3"DVE#;a  r   )g      @r   )T)g        )r   )r   z...)u   €)(r7   rW   r-   rn   loggingtypingr   r   r   r   r   pathlibr   	functoolsr
   
contextlibr   rA   ImportErrorr    r(   	getLoggerr4   r+   r   r   r8   r{   rL   r]   boolrj   rx   r   r   r   r   r   r   r   r9   r   r   <module>r      sr  
  	   9 9   %  			8	$CL$ $N # #e # #L"6S "63 "6# "6JS  T T >X ( c E E C # c 1s 1 13 13 1 8)E )S )S )!U !s !I  Es   C CC