Ë
    {Ìjg  ã                   óZ  — 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 ddl	Z	ddl
mZ  ej                  e«      Z ed«      ZddlmZ ej$                  Zej(                  Z ej,                  d«      ZdZd	ed
efd„Zded
efd„Zddedœdeg ee   f   dededz  dedz  deegef   d
efd„Z y)u,  
Reintento con backoff para las llamadas a los servicios de StoryFace.

Los endpoints de IA (`picasso-fast-seed`) y de remociÃ³n de fondo (`remove-bg`)
fallan de forma esporÃ¡dica cuando les entra un lote en paralelo: se han visto
500 Â«Failed to generate image with modelÂ» y 500 Â«Failed to use creditsÂ» con la
misma peticiÃ³n funcionando 20 s despuÃ©s. Sin reintento esas generaciones se
pierden para siempre: nadie vuelve a pasar por una foto ya ordenada.

Solo se repite lo que puede arreglarse solo (red, timeout, 429, 5xx). Un error
de configuraciÃ³n â€”API key ausente o invÃ¡lida, cualquier 4xxâ€” falla al primer
intento: repetirlo Ãºnicamente retrasa el error.

Ajustable por entorno: `SF_RETRY_ATTEMPTS` (intentos totales, 1 = sin
reintento) y `SF_RETRY_BASE_DELAY` (segundos de la primera espera).
é    N)Ú	AwaitableÚCallableÚTypeVar)ÚHTTPExceptionÚT)ÚconfigzHTTP (\d{3}))z
no api keyzinvalid api keyzsin api keyÚcodeÚreturnc                 ó   — | dv xs | dk\  S )N)i˜  i­  iô  © )r	   s    ú&/var/www/photos/backend/utils/retry.pyÚ_retriable_statusr   )   s   € Ø�:ÐÒ, ¨¡Ð,ó    Úexcc                 ó   ‡— t        | t        j                  «      ryt        | t        j                  «      rt	        | j
                  j                  «      S t        | t        «      rit        | j                  «      Št        ˆfd„t        D «       «      ryt        j                  ‰«      }|r#t	        t        |j                  d«      «      «      S yy)u/   Â¿Merece la pena repetir esta llamada tal cual?Tc              3   óB   •K  — | ]  }|‰j                  «       v –— Œ y ­w)N)Úlower)Ú.0ÚmÚdetails     €r   ú	<genexpr>zis_transient.<locals>.<genexpr>5   s   øè ø€ Ò? qˆq�F—L‘L“NÔ"Ñ?ùs   ƒFé   )Ú
isinstanceÚhttpxÚRequestErrorÚHTTPStatusErrorr   ÚresponseÚstatus_coder   Ústrr   ÚanyÚ_PERMANENT_MARKERSÚ_HTTP_STATUS_REÚsearchÚintÚgroup)r   r   r   s     @r   Úis_transientr&   -   s”   ø€ ä�#”u×)Ñ)Ô*ØÜ�#”u×,Ñ,Ô-Ü  §¡×!9Ñ!9Ó:Ð:Ü�#”}Ô%Ü�S—Z‘Z“ˆÜÓ?Ô,>Ô?Ô?ØÜ×"Ñ" 6Ó*ˆÙÜ$¤S¨¯©°«£_Ó5Ð5ØØr   )ÚattemptsÚ
base_delayÚretry_onÚfactoryÚlabelr'   r(   r)   c          
   ƒ   ó*  K  — |€t         nt        d|«      }|€t        n|}t        d|dz   «      D ]  }	  | «       ƒ d{  –—† c S  t        d	|› d
�«      ‚7 Œ# t        $ r°}t        |«      xs t        |«      j                  › d�}	||k\  s ||«      st        j                  d||||	«       ‚ |d|dz
  z  z  t        j                  dd«      z  }
t        j                  d||||	|
«       t        j                  |
«      ƒ d{  –—†7   Y d}~ŒÛd}~ww xY w­w)u·  
    Ejecuta `factory()` reintentando los fallos transitorios con backoff
    exponencial y jitter (â‰ˆ3 s, â‰ˆ6 s con los valores por defecto).

    `factory` es una funciÃ³n que DEVUELVE la corrutina, no una corrutina ya
    creada: hay que poder llamarla de nuevo en cada intento.

    Propaga la Ãºltima excepciÃ³n si se agotan los intentos o si el fallo no es
    transitorio, asÃ­ que el llamante no cambia su manejo de errores.
    Nr   z (sin mensaje)u1   â�Œ %s fallÃ³ definitivamente (intento %d/%d): %sé   gš™™™™™é?g333333ó?u9   ðŸ”� %s fallÃ³ (intento %d/%d): %s â€” reintento en %.1fszwith_retries(z): estado inalcanzable)ÚRETRY_ATTEMPTSÚmaxÚRETRY_BASE_DELAYÚrangeÚ	Exceptionr   ÚtypeÚ__name__ÚloggerÚerrorÚrandomÚuniformÚwarningÚasyncioÚsleepÚRuntimeError)r*   r+   r'   r(   r)   ÚtotalÚdelayÚattemptr   r   Úwaits              r   Úwith_retriesrA   >   s  è ø€ ð$ 'Ð.�N´C¸¸8Ó4D€EØ *Ð 2Õ¸
€Eä˜˜E A™IÓ&ò &ˆð	&Ù ›—?Ò"ð&ô0 ˜ u gÐ-CÐDÓ
EÐEð- #ùÜò 	&ô ˜“XÒF¤D¨£I×$6Ñ$6Ð#7°~Ð!FˆFØ˜%Ò¡x°¤}ô
 —‘ØGØ˜7 E¨6ôð Ø˜A '¨A¡+Ñ.Ñ/´&·.±.ÀÀcÓ2JÑJˆDÜ�N‰NØKØ�w  v¨tôô —-‘- Ó%×%Ö%ûð'	&üsK   ‚1D´
A¾A¿AÁDÁAÁ	DÁ B DÄ DÄDÄDÄDÄD)!Ú__doc__r:   Úloggingr7   ÚreÚtypingr   r   r   r   Úfastapir   Ú	getLoggerr4   r5   r   Úcorer   ÚSF_RETRY_ATTEMPTSr.   ÚSF_RETRY_BASE_DELAYr0   Úcompiler"   r!   r$   Úboolr   ÚBaseExceptionr&   r   ÚfloatrA   r   r   r   ú<module>rO      s
  ðñó  Û Û Û 	ß /Ñ /ã Ý !à	ˆ×	Ñ	˜8Ó	$€áˆCƒL€å à×)Ñ)€Ø×-Ñ-Ð ð �"—*‘*˜_Ó-€ØEÐ ð-˜Cð - Dó -ð�mð ¨ó ð*  Ø#Ø0<ò-FØ�b˜) A™,Ð&Ñ'ð-Fð ð-Fð �D‰jð	-Fð
 ˜‘ð-Fð ˜�¨Ð,Ñ-ð-Fð ô-Fr   