o
    d۷i'                     @   s0  U d dl Z d dlZd dlZd dlmZmZ d dlmZ d dlm	Z	 d dl
mZ d dlmZ d dlmZmZmZ d dlZd dl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mZ e e!Z"dZ#e	ddZ$G dd de%Z&G dd de%Z'G dd deZ(G dd deZ)G dd deZ*e*e)B Z+eee+eddf Z,ee+ e-d< ede.ded  fd!d"Z/ed#Z0ed$Z1de	ddfd%e.d&e	deee0ee1ddf f gee0ee1ddf f f fd'd(Z2G d)d* d*e3eZ4e4j5e4j6hZ7e4j8e4j9e4j:e4j;e4j<hZ=e7e=B Z>d+Z?e	d,d-Z@dZAG d.d/ d/ejBZCdS )0    N)Callable	Generator)contextmanager)	timedelta)Enum)wraps)	AnnotatedLiteralTypeVar)	BaseModelFieldTypeAdapterValidationError)	ParamSpec)__version__)Settings   )Identity      )minutesc                       s8   e Zd ZdZdddededB ddf fddZ  ZS )	StreamLogErrorz@Raised when there's an error streaming logs (build or app logs).Nstatus_codemessager   returnc                   s   t  | || _d S )N)super__init__r   )selfr   r   	__class__ Q/home/ubuntu/vllm_env/lib/python3.10/site-packages/fastapi_cloud_cli/utils/api.pyr   !   s   
zStreamLogError.__init__)__name__
__module____qualname____doc__strintr   __classcell__r!   r!   r   r"   r      s    ,r   c                   @   s   e Zd ZdS )TooManyRetriesErrorN)r#   r$   r%   r!   r!   r!   r"   r*   &   s    r*   c                   @   s&   e Zd ZU eed< eed< eed< dS )AppLogEntry	timestampr   levelN)r#   r$   r%   r'   __annotations__r!   r!   r!   r"   r+   *   s   
 r+   c                   @   s*   e Zd ZU ed ed< dZedB ed< dS )BuildLogLineGeneric)completefailedtimeout	heartbeattypeNid)r#   r$   r%   r	   r.   r5   r'   r!   r!   r!   r"   r/   0   s   
 r/   c                   @   s6   e Zd ZU dZed ed< eed< dZedB ed< dS )BuildLogLineMessager   r4   Nr5   )r#   r$   r%   r4   r	   r.   r'   r5   r!   r!   r!   r"   r6   5   s   
 r6   r4   )discriminatorBuildLogAdapterattempt_numberr   )NNNc                 #   s    d fdd}zd V  W d S  t jt jt jfy0 } ztd| |  W Y d }~d S d }~w t jyy } z=|jjdkrKtd|jj| |  n#z|jj	}W n t
y\   d}Y nw td|jj d	| |jjd
|W Y d }~d S d }~ww )Nr   c                     s*   t d  d} td|   t|  d S )N      zRetrying in %ds (attempt %d))minloggerdebugtimesleep)backoff_secondsr9   r!   r"   _backoffC   s   zattempt.<locals>._backoffzNetwork error (will retry): %si  z Server error %d (will retry): %sz(response body unavailable)zHTTP z: r   r   N)httpxTimeoutExceptionNetworkErrorRemoteProtocolErrorr=   r>   HTTPStatusErrorresponser   text	Exceptionr   )r9   rC   errorerror_detailr!   rB   r"   attemptA   sD   	rO   PTtotal_attemptsr2   c              	      s@   dt tttd d f f dt tttd d f f f fdd}|S )Nfuncr   c              
      s8   t  dtjdtjdttd d f f fdd}|S )Nargskwargsr   c               	   ?   s    t  }tD ]8}t  |  kr td ddt|  | i |E d H  	 W d     d S 1 s<w   Y  q	td d)NzLog streaming timed out after z.0fsFailed after z	 attempts)r?   	monotonicrangetotal_secondsTimeoutErrorrO   r*   )rT   rU   startr9   )rS   r2   rR   r!   r"   wrapperx   s   
$z,attempts.<locals>.decorator.<locals>.wrapper)r   rP   rT   rU   r   rQ   )rS   r]   r2   rR   )rS   r"   	decoratoru   s   .zattempts.<locals>.decorator)r   rP   r   rQ   )rR   r2   r_   r!   r^   r"   attemptsp   s   r`   c                   @   sZ   e Zd ZdZdZdZdZdZdZdZ	dZ
d	Zd
ZdZdZdZdZedd defddZdS )DeploymentStatuswaiting_uploadready_for_buildbuilding
extractingextracting_failedbuilding_imagebuilding_image_failed	deployingdeploying_failed	verifyingverifying_failedverifying_skippedsuccessr1   statusr   c                 C   s\   | j d| jd| jd| jd| jd| jd| jd| jd| jd	| j	d
| j
d| jd| jd| jdi| S )NzWaiting for uploadzReady for buildBuilding
ExtractingzExtracting failedzBuilding imagezBuild failed	DeployingzDeploying failed	VerifyingzVerifying failedzVerification skippedSuccessFailed)rb   rc   rd   re   rf   rg   rh   ri   rj   rk   rl   rm   rn   r1   )clsro   r!   r!   r"   to_human_readable   s"   z"DeploymentStatus.to_human_readableN)r#   r$   r%   rb   rc   rd   re   rf   rg   rh   ri   rj   rk   rl   rm   rn   r1   classmethodr'   rw   r!   r!   r!   r"   ra      s"    ra   g       @x   )secondsc                       s   e Zd Zd fddZeeededee	ddf fddZ
dede	dB fd	d
Zeeedededededeeddf f
ddZdededefddZ  ZS )	APIClientr   Nc                    s@   t  }t }t j|jtdd|j dt	 dd d S )N   zBearer zfastapi-cloud-cli/)Authorizationz
User-Agent)base_urlr2   headers)
r   getr   r   r   base_api_urlrE   Timeouttokenr   )r   settingsidentityr   r!   r"   r      s   

zAPIClient.__init__deployment_idc                 c   s    d }	 |r
d|ind }| j dd| dd|dV}|  | D ];}|r*| s+q"| | }r]|jr8|j}|jdkr@|V  |jd	v rQ|V   W d    d S |jd
kr]td  nq"td t	
dW d    n1 srw   Y  td q)NTlast_idGET/deployments/z/build-logs<   )r2   paramsr   )r0   r1   r2   zReceived timeout; reconnectingz4Connection closed by server unexpectedly; will retryz(Connection closed without terminal stateg      ?)streamraise_for_status
iter_linesstrip_parse_log_liner5   r4   r=   r>   rE   rG   r?   r@   )r   r   r   r   rJ   linelog_liner!   r!   r"   stream_build_logs   sD   







zAPIClient.stream_build_logsr   c              
   C   sP   zt |W S  ttjfy' } ztd|d d | W Y d }~d S d }~ww )Nz&Skipping malformed log: %s (error: %s)d   )r8   validate_jsonr   jsonJSONDecodeErrorr=   r>   )r   r   er!   r!   r"   r      s   zAPIClient._parse_log_lineapp_idtailsincefollowc           
      c   s   |rdnd}| j dd| d|||d|dk}|  | D ]Y}|r)| s*q!zt|}W n tjyA   td| Y q!w |	d	d
krJq!|	d	dkrYt
|	ddzt|V  W q! tyz }	 ztd||	 W Y d }	~	q!d }	~	ww W d    d S 1 sw   Y  d S )Nry   r;   r   /apps/z/logs/stream)r   r   r   )r   r2   zFailed to parse log line: %sr4   r3   rM   r   zUnknown errorz"Failed to parse log entry: %s - %s)r   r   r   r   r   loadsr   r=   r>   r   r   r+   model_validater   )
r   r   r   r   r   r2   rJ   r   datar   r!   r!   r"   stream_app_logs   sF   
	"zAPIClient.stream_app_logsc                 C   s   t  }d}	 t  | t krtdt|4 | d| d| }|  t|	 d }d}|t
v r@|W  d    S t t 	 W d    q1 sPw   Y  |d7 }|tkretdt d	q)
Nr   Tz!Deployment verification timed outr   r   ro   r   rW   z# attempts polling deployment status)r?   rX   POLL_TIMEOUTrZ   r[   rO   r   r   ra   r   TERMINAL_STATUSESr@   POLL_INTERVALPOLL_MAX_RETRIESr*   )r   r   r   r\   error_countrJ   ro   r!   r!   r"   poll_deployment_status)  s,   

	
z APIClient.poll_deployment_statusrD   )r#   r$   r%   r   r`   STREAM_LOGS_MAX_RETRIESSTREAM_LOGS_TIMEOUTr'   r   BuildLogLiner   r   r(   boolr+   r   ra   r   r)   r!   r!   r   r"   r{      s8    )(r{   )Dr   loggingr?   collections.abcr   r   
contextlibr   datetimer   enumr   	functoolsr   typingr   r	   r
   rE   pydanticr   r   r   r   typing_extensionsr   fastapi_cloud_clir   fastapi_cloud_cli.configr   authr   	getLoggerr#   r=   r   r   rL   r   r*   r+   r/   r6   r   r8   r.   r(   rO   rP   rQ   r`   r'   ra   rn   rm   SUCCESSFUL_STATUSESr1   rl   rj   rh   rf   FAILED_STATUSESr   r   r   r   Clientr{   r!   r!   r!   r"   <module>   sl   
 

*
,
$
