
    Y                        S r SSKJr  SSKJr  SSKJr  SSKrSSKJr  SSKJr	  SSK
Jr  SS	KJr  SS
KJr  SSKJr  SSKJr  SSKJr  SSKJr  SSKJr  SSKJr  SSKJr  SSKJr  SSKJr  SSKJr  SrSSSSSSSSSSS.
r S S!S"S#S$S%S&S'S(S)S.
r!S*r"S+ r#S, r$S- r% S9S. jr& S9S/ jr'S0 r(S1 r)S2 r*S3 r+S4 r,S5 r-S6 r.S7 r/S8 r0g):z-Utilities for the model garden command group.    )absolute_import)division)unicode_literalsN)encoding)
exceptions)
operations)client)metric)
quota_info)endpoints_util)models_util)operations_util)log)
properties)requests)	resources)
console_io?   +CustomModelServingP4GPUsPerProjectPerRegion+CustomModelServingT4GPUsPerProjectPerRegion+CustomModelServingL4GPUsPerProjectPerRegion,CustomModelServingK80GPUsPerProjectPerRegion-CustomModelServingV100GPUsPerProjectPerRegion-CustomModelServingP100GPUsPerProjectPerRegion-CustomModelServingA100GPUsPerProjectPerRegion1CustomModelServingA10080GBGPUsPerProjectPerRegion-CustomModelServingH100GPUsPerProjectPerRegion+CustomModelServingV5ETPUPerProjectPerRegion)
NVIDIA_TESLA_P4NVIDIA_TESLA_T4	NVIDIA_L4NVIDIA_TESLA_K80NVIDIA_TESLA_V100NVIDIA_TESLA_P100NVIDIA_TESLA_A100NVIDIA_A100_80GBNVIDIA_H100_80GBTPU_V5_LITEPOD#custom_model_serving_nvidia_p4_gpus#custom_model_serving_nvidia_t4_gpus#custom_model_serving_nvidia_l4_gpus$custom_model_serving_nvidia_k80_gpus%custom_model_serving_nvidia_v100_gpus%custom_model_serving_nvidia_p100_gpus%custom_model_serving_nvidia_a100_gpus*custom_model_serving_nvidia_a100_80gb_gpus%custom_model_serving_nvidia_h100_gpuscustom_model_serving_tpu_v5ea  metric.type="serviceruntime.googleapis.com/quota/allocation/usage" AND resource.type="consumer_quota" AND metric.label.quota_metric="aiplatform.googleapis.com/{}" AND resource.label.project_id="{}" AND resource.label.location="{}" AND resource.label.service="aiplatform.googleapis.com"c                     [         R                  R                  U U[        R                  R
                  R                  R                  S.SS9$ )z<Parses a Vertex Endpoint ID into a endpoint resource object.)locationsId
projectsIdz'aiplatform.projects.locations.endpoints)params
collection)r   REGISTRYParser   VALUEScoreproject	GetOrFail)endpoint_idlocation_ids     7lib/googlecloudsdk/command_lib/ai/model_garden_utils.py_ParseEndpointrA   Q   sK    				!	!$"))..66@@ ; 
" 
     c                     [         R                  " USSS[        U   5      nUR                   H7  nUR                  S   U :X  d  M  UR
                  R                  =(       d    Ss  $    g)z<Gets the quota limit for the accelerator type in the region.Nzaiplatform.googleapis.comr   )r   GetQuotaInfo!_ACCELERATOR_TYPE_TO_QUOTA_ID_MAPdimensionsInfosapplicableLocationsdetailsvalue)regionr<   accelerator_typeaccelerator_quotaregion_infos        r@   _GetQuotaLimitrN   ]   si     --

!'(89 '66k&&q)V3  &&+!+ 7 
rB   c                    [         R                   R                  [         R                  R                  5      nU[         R                  " SS9-
  nUR                  SS9R                  SS5      nUR                  SS9R                  SS5      n[        R                  " 5       R                  US[        R                  " 5       R                  R                  R                  UU[        R                  [         U   UU 5      S9n UR"                  S	   R$                  S	   R&                  R(                  nU$ ! [*         a    S	n U$ f = f)
zTGets the quota usage for the accelerator type in the region using the monitoring AP.   )hoursseconds)timespecz+00:00Z60s)r<   aggregation_alignment_periodaggregation_per_series_alignerinterval_start_timeinterval_end_time
filter_strr   )datetimenowtimezoneutc	timedelta	isoformatreplacer
   MetricClientListTimeSeriesByProjectGetMessagesModule'MonitoringProjectsTimeSeriesListRequest*AggregationPerSeriesAlignerValueValuesEnumALIGN_NEXT_OLDER_TIME_SERIES_FILTERformat%_ACCELERATOR_TYPE_TP_QUOTA_METRIC_MAP
timeSeriespointsrI   
int64Value
IndexError)	rJ   r<   rK   current_time_utctwenty_five_hours_ago_time_utcrfc3339_time"rfc3339_time_twenty_five_hours_agoquota_usage_time_seriescurrent_usages	            r@   _GetQuotaUsageru   m   sZ    &&**8+<+<+@+@A#3h6H6H7 $  "++Y+?GG, (F'O'O (P (GHc % #//1II#(%+%=%=%?%g%g  &S  &S  &d  &d<$$++
/0@
A

 J **1-44Q7==HH  
 
 M	s   0D4 4EEc                     U (       a  SU SU 3R                  SS5      S [         $ SU SU 3R                  SS5      S [         $ )Nhf--._zmg-ra   _MAX_LABEL_VALUE_LENGTHis_hf_modelpublisher_name
model_namemodel_version_names       r@   GetCLIEndpointLabelValuer      sg      *.66sC@ 	    "4!56>>sCH 	  rB   c                     U (       a  SU SU 3R                  SS5      S [         $ SU SU SU 3R                  SS5      S [         $ )Nrw   rx   ry   rz   zpublishers-z-models-r{   r}   s       r@   GetOneClickEndpointLabelValuer      sq      *.66sC@ 	  
 n%Xj\;M:NO	

 %$		
rB   c                     [         R                  " 5       R                  SU  SU S35      nUR                  S:w  a  [        R
                  " S5      e[        UR                  5       S   5      $ )z9Checks if the HF model is gated or not by calling HF API."https://huggingface.co/api/models//z?blobs=true   zfSomething went wrong when we call HuggingFace's API to get the model metadata. Please try again later.gated)r   
GetSessiongetstatus_codecore_exceptionsInternalErrorbooljson)r   r   hf_responses      r@   IsHFModelGatedr      sq    ##%))*>*:!J<{S+ #

'
'	3  
k )	**rB   c                     [         R                  " 5       R                  SSU SU S3SSU  30S9nUR                  S:w  a  [        R
                  " S	5      eg )
NGETr   r   z/auth-checkAuthorizationzBearer )headersr   zaThe Hugging Face access token is not valid or does not have permission to access the gated model.)r   r   requestr   r   Error)hf_tokenr   r   r   s       r@   VerifyHFTokenPermissionr      sr    ##%--*>*:!J<{S'( 45 . +
 #


	&  	rB   c                     UR                   R                  R                  nSnU R
                  (       d#  U R                  (       d  U R                  (       Ga  U H  nU R
                  (       a.  UR                  R                  R                  U R
                  :w  d  U R                  (       aE  [        UR                  R                  R                  5      U R                  R                  5       :w  d5  U R                  (       a&  UR                  R                  U R                  :w  a  M  Un  O   U(       d  [        R                  " S5      e[         R"                  R%                  S5        O$US   n[         R"                  R%                  S5        UR                  R                  nUR                  R                  nUR                  (       a,  [         R"                  R%                  SUR                   35        UR                  (       a,  [         R"                  R%                  SUR                   35        UR&                  (       a,  [         R"                  R%                  S	UR&                   35        U(       a"  [         R"                  R%                  S
U 35        U$ ! [         a    [        R                  " S5      ef = f)zGReturns a best suited deployment configuration for the publisher model.zModel does not support deployment, please use a deploy-able model instead. You can use the `gcloud ai model-garden models list` command to find out which ones are currently supported by the `deploy` command.NzThe machine type, accelerator type and/or container image URI is not supported by the model. You can use `gcloud alpha/beta ai model-garden models list-deployment-config` command to find the supported configurationsz,Using the selected deployment configuration:r   z+Using the default deployment configuration:z Machine type: z Accelerator type: z Accelerator count: z Container image URI: )supportedActionsmultiDeployVertexAttributeErrorr   r   machine_typerK   container_image_uridedicatedResourcesmachineSpecmachineTypestracceleratorTypeuppercontainerSpecimageUrir   statusPrintacceleratorCount)argspublisher_modelmulti_deploydeploy_configdeploymachine_specr   s          r@   GetDeployConfigr      s)   
((::LL  -	$//43K3K3K ++77CC""# ##f//;;KKL&&,,./ &&&&//43K3KK 	m' * !!&  JJCD !OMJJBC11==,%33<<JJ|'?'?&@AB!!JJ*<+G+G*HIJ""JJ+L,I,I+JKLJJ-.A-BCD	m 
 


	 s    J !J?c                 F   US:X  a  SnSnO
US:X  a  SnSn[         R                  R                  R                  R	                  5       n[        U R                  XB5      nXS:  a4  [        R                  " S[        U    SU R                   SU S	U S
3	5      e[        U R                  XB5      nXc-   U:  a7  [        R                  " S[        U    SU R                   SU SU S	U S
35      e[        R                  R                  SU SU R                   SU SU S3	5        g)z8Checks the accelerator quota for the project and region.zct5lp-hightpu-1tr(      zct5lp-hightpu-4t   z+The project does not have enough quota for z in z) to deploy the model. The quota limit is z and you are requesting for z. Please use a different region or request more quota by following https://cloud.google.com/vertex-ai/docs/quotas#requesting_additional_quota.z+ to deploy the model. The current usage is z out of zNThe project has enough quota. The current usage of quota for accelerator type z in region z is ry   N)r   r:   r;   r<   r=   rN   rJ   r   r   rj   ru   r   r   r   )r   r   rK   accelerator_countr<   quota_limitrt   s          r@   CheckAcceleratorQuotar     su    '''))'""**446't{{GF+$


	12BCD EKK= 11< >,- .W		W  !gH-&4


	12BCD EKK= 33@/ B= ,- .W	W	 	 **+,K} E

Q0rB   c                 R   UR                  UU UR                  R                  R                  UR                  R                  R                  R	                  SUS9/S9S9n[
        R                  " UU[        R                  " UR                  5      5      nUc  [        R                  " S5      e[        R                  " U5      nSU;  a  [        R                  " S5      e[        R                  R!                  SR#                  US   5      5        US   R%                  S5      S	   $ )
z)Creates a Vertex endpoint for deployment.zmg-cli-deploy)keyrI   )additionalProperties)labelszEInternal error: Failed to create a Vertex endpoint. Please try again.namezOCreated Vertex AI endpoint: {}.
Starting to upload the model to Model Registry.r   )
CreateBetamessages$GoogleCloudAiplatformV1beta1EndpointLabelsValueAdditionalPropertyr   WaitForOpMayber   ParseOperationr   r   r   r   MessageToPyValuer   r   r   ri   split)endpoint_namelabel_value
region_refoperation_clientendpoints_clientcreate_endpoint_opcreate_endpoint_response_msgresponses           r@   CreateEndpointr   8  s2    (22&&KKWW''LLXXkk%[ l   X  3 
 "1!?!?##$6$;$;<"
 ")

'
'O  &&'CD(8

'
'O  ** x 	 
&				$R	((rB   c                    Su  pxn	U R                   R                  (       aV  U R                   R                   V
s0 s H  oR                  U
R                  _M     nn
U(       a  SU;   a  UR                  US'   U R                   R
                  (       a  [        U R                   R
                  5      nU R                   R                  (       a  [        U R                   R                  5      n	[        R                  " 5       nUR                  UR                  R                  R                  5       USSU R                  U R                   R                  U	UUU R                   R                   S   R"                  /SU R                   R$                  U R                   R&                  UR(                  R+                  UR(                  R-                  SR/                  U(       a  SU-   OUU5      S9S9S	9n[0        R2                  " [4        R6                  " 5       U[8        R:                  " UR                  5      S
9nUc  [<        R>                  " S5      e[@        RB                  " U5      nSU;  a  [<        R>                  " S5      e[D        RF                  RI                  SR/                  US   5      5        US   RK                  S5      S   $ s  sn
f )z1Uploads the Model Garden model to Model Registry.)NNNHUGGING_FACE_HUB_TOKENNr   zpublishers/{}/models/{}rw   )publicModelName)modelGardenSource)base_model_source)operations_clientopop_refz`Internal error: Failed to upload a Model Garden model to Model Registry. Please try again later.modelzEUploaded model to Model Registry at {}.
Starting to deploy the model.r   r   )&r   envr   rI   hugging_face_access_tokenr   listcommandclient_modelsModelsClientUploadV1Beta1CONCEPTSrJ   r9   artifactUrir   portscontainerPortpredictRoutehealthRouter   0GoogleCloudAiplatformV1beta1ModelBaseModelSource-GoogleCloudAiplatformV1beta1ModelGardenSourceri   r   r   r   OperationsClientr   ParseModelOperationr   r   r   r   r   r   r   r   )r   r   requires_hf_tokenr~   uploaded_model_namer   publisher_model_namecontainer_env_varscontainer_argscontainer_commandsvarmodels_clientupload_model_opupload_model_response_msgupload_model_responses                  r@   UploadModelr   b  s    <L8&8  $$'4'B'B'F'F'F#))'F   59KK

(
( 12   %%-55::;N  ((m99AAB,,.-!//
mm  "

!!**""((+99:
!!..!!--%..__)22``7>>,7%.(^& a  `  0 /2 .<<"335	,,_-A-AB
 &

'
'	-  #334MN))

'
'	-  **$W-.	 
w	'	-	-c	22	66ys    K
c                    UR                   R                  R                  nUR                   R                  R                  nSn	Uc  Ub8  0 n	Ub,  [	        U5      R                  5       R                  SS5      U	S'   Ub  XS'   UR                  [        X R                  5      UU R                  UUR                   R                  R                  U	SSS9n
[        R                  " UU
[        R                  " U
R                  5      SS9  U
R                  R!                  S	5      S
   n[#        SU SU SU R                   SU SU R                   S35        g)z8Deploys the Model Registry model to the Vertex endpoint.Nrz   rx   typecountT)r   accelerator_dictenable_access_loggingenable_container_logging)asynchronousr   r   Deploying the model to the endpoint. To check the deployment status, you can try one of the following methods:
1) Look for endpoint `g` at the [Vertex AI] -> [Online prediction] tab in Cloud Console
2) Use `gcloud ai operations describe 
 --region=zc` to find the status of the deployment long-running operation
3) Use `gcloud ai endpoints describe z+` command to check the endpoint's metadata.)r   r   r   r   r   lowerra   DeployModelBetarA   rJ   r   r   r   r   r   r   r   print)r   r   r>   r   model_idr   r   rK   r   r   deploy_model_opdeploy_op_ids               r@   DeployModelr    sj    &&22BB  &&22CC  !%6%B#!$%5!6!<!<!>!F!FsC!Pv$"3w$44[++.
kk 33??KK' # 5 	/   ##O$8$89	 !%%++C04,!? #.
4;;- 8(MDKK= A++	rB   c           
      X    Ub%  UR                   nUR                  nUR                  nOSnSnSnUR                  " S80 S[        R
                  R                  R                  R                  5       _SU R                  _SU_SU R                  _SU_SU_SU_S	U_S
U R                  _SU R                  _SU R                  _SU R                  _SU R                  _SU R                   _SU R"                  _SU R$                  _SU R&                  _SU R(                  _SU R*                  _SU R,                  _SU R.                  _SU R0                  _SU R2                  _SU R4                  _SU R6                  _SU R8                  _SU R:                  _SU R<                  _SU R>                  _6n	U	R\                  RU                  S'5      S1   n[L        RN                  RQ                  S2U S3U S4U R                   S535        [^        R`                  " UU	[c        U	R\                  5      U Rd                  S6S79  g! [@        RB                   Ga`  n
U
RD                  S:X  aq  S U
RF                  ;   aa  U R                  cT  U R                  (       d.  [H        RJ                  " S!5      U l        U R                  (       d  M.  [        U UUUUU5         Sn
A
gU
RD                  S":X  a  S#U
RF                  ;   a  [L        RN                  RQ                  S$5        U RR                  RU                  S%5      S&   RU                  S'5      u  p [H        RV                  " S(U S)U S*3S+S,S-S.S-S/9U l
        O.! [H        RX                   a    [Z        RX                  " S05      ef = f[        U UUUUU5         Sn
A
gU
eSn
A
ff = f)9z1Deploys the publisher model to a Vertex endpoint.Nr<   locationr   accept_eularK   r   r   endpoint_display_namer   spotreservation_affinityuse_dedicated_endpointenable_fast_tryoutr   container_commandr   r   container_portscontainer_grpc_portscontainer_predict_routecontainer_health_route$container_deployment_timeout_secondscontainer_shared_memory_size_mbcontainer_startup_probe_exec&container_startup_probe_period_seconds'container_startup_probe_timeout_secondscontainer_health_probe_exec%container_health_probe_period_seconds&container_health_probe_timeout_secondsi  z)provide a valid Hugging Face access tokenz2Please enter your Hugging Face read access token: i  EULAzIThe End User License Agreement (EULA) of the model has not been accepted.@r   r   zThe model can be deployed only if the EULA of the model has been accepted. You can view it at https://console.cloud.google.com/vertex-ai/publishers/z/model-garden/z):zDo you want to accept the EULA?FTzEULA is not accepted.)messageprompt_stringdefaultcancel_on_nocancel_stringthrow_if_unattendedz6Please accept the EULA using the `--accept-eula` flag.r   r   r   r   z>` to find the status of the deployment long-running operation
i6 )r   max_wait_ms )3r   r   r   Deployr   r:   r;   r<   r=   rJ   r
  r   r  r  r  r  r   r  r   r   r  r  r  r  r  r  r  r  r  r  r  r  apitools_exceptions	HttpErrorr   contentr   PromptPasswordr   r   r   r   r   PromptContinuer   r   r   r   r   r   r   )r   r   r   r   r   	mg_clientr   rK   r   	deploy_ope	publisherr  r  s                 r@   r'  r'    s   ^!--l%55&77l   !!&&..88:  $$	
 * , " , #'"@"@ YY "66  $::  22 !44 00  **!"  22#$ ,,%& "66'( !% < <)*  $::+, .2-V-V-. )-(L(L/0 &*%F%F12 04/Z/Z34 150\0\56 %)$D$D78 /3.X.X9: 04/Z/Z;In %%c*2.,**!? #.
4;;- 84	4   Y^^$$$C 
	&	& 6 	
7199D**2..)3)B)B@*
& ... 





 	
#	&AII"5	jj8 !JJ,,S1!4::3?i
%44J KTTbckbllnp
 <1 $
  
##D
 	

 





 gm6sD   F+H4 4N)	A*N$5N$
A.N$9%MN$+N

N$"N$$N)c                 >    [         R                  R                  U SS9$ )zParse operation resource to the operation reference object.

Args:
  operation_name: The operation resource to wait on

Returns:
  The operation reference object
z(aiplatform.projects.locations.operations)r7   )r   r8   ParseRelativeName)operation_names    r@   r   r   Y  s(     
			-	-; 
. 
 rB   ) r4  )1__doc__
__future__r   r   r   r[   apitools.base.pyr   r   r(  googlecloudsdk.api_lib.air    googlecloudsdk.api_lib.ai.modelsr	   r   !googlecloudsdk.api_lib.monitoringr
   googlecloudsdk.api_lib.quotasr   googlecloudsdk.command_lib.air   r   r   googlecloudsdk.corer   r   r   r   r   googlecloudsdk.core.consoler   r|   rE   rj   rh   rA   rN   ru   r   r   r   r   r   r   r   r   r  r'  r   r&  rB   r@   <module>r?     s   4 &  '  % > 0 D 4 4 8 5 9 = # * ( ) 2   ED>FHHHKGC% ! =<6>@@@D?4) %: 	 #N DF
 DF$
+	<~)X')TH7V3lslrB   