
    GJjѸ              *          d 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mZ ddl	m	Z	 ddl
mZ ddlmZmZ ddlmZmZmZ ddlmZ dd	lmZ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"m#Z# ddl$m%Z% ddl&m'Z'm(Z( ddl)m*Z*m+Z+m,Z,m-Z-m.Z.m/Z/m0Z0m1Z1m2Z2m3Z3m4Z4m5Z5m6Z6 ddl7m8Z8m9Z9 ddl:m;Z;m<Z<  e!jz                  e>      Z?de@de@dz  deAe@e@dz  f   fdZBdeCe@   dz  dede@dz  deCe   dz  fdZDdZEee@ e8d      f   ZFee@dz   e9d      f   ZGee@dz   e9d e.e             f   ZHeeCe@   dz   e9d!d"d#      f   ZIee@dz   e9d$      f   ZJeeK e9d%d&d'      f   ZLee@dz   e9d(      f   ZMeeCeN   dz   e9d)d*      f   ZOeeK e9d+d,      f   ZPeeCe@   dz   e9d-d.      f   ZQee@dz   e9d/d0d1      f   ZReeKdz   e9d2      f   ZSeeKdz   e9d3      f   ZTee@ e8d4      f   ZUee@ e8d5      f   ZVeeCe@   dz   e8d6      f   ZWeeCe@    e8d7      f   ZXee@ e8d8      f   ZYeeCe@   dz   e8d9      f   ZZee@ e8d:      f   Z[eeCe@   dz   e9d;d<d=      f   Z\ e6d>      Z]ded?eddfd@Z^e]j                  dAdBdCig dDE      	 	 	 	 	 	 	 	 	 	 	 	 	 ddFeFdGeXdHe+dIe-dJeIdKe\dLe*dMe,dNeHdOeJdPeLdQeOdRePdeMdSe1ddf dT       Z`e]j                  dUg dVW      	 	 	 	 ddeYdXeeK e9dYdZd[      f   d\eeNdz   e9d]d^d_      f   deMdSe1ddfd`       Zadaebe@e@f   dbeCeAe@e@e@f      deKfdcZcddeNddfdeZdde@dfeebe@ef      dgeCe@   deeAeKe@eCeCe@eNz        f      fdhZee]j                  didjgW      	 	 	 ddkeZdeMdSe1ddfdl       Zfe]j                  dmg dnW      	 	 	 	 	 	 	 ddoeeK e9dpdqdr      f   dseeCe@   dz   e9dt e.e      duv      f   dJeeCe@   dz   e9d!d"dw      f   dxeeN e9dydz      f   deMdSe1d{eeCe@   dz   e9dYd|d}      f   ddfd~       Zge]j                  ddgW      dd       Zhe]j                  ddgW      	 	 ddkeeCe@    e8d      f   deMdSe1ddfd       Zie]j                  ddgW      	 	 ddeYdeMdSe1ddfd       Zje]j                  dg dW      	 	 	 ddkeeCe@    e8d      f   dOee@dz   e9d      f   deMdSe1ddf
d       Zke]j                  dddgW      	 	 	 	 ddeYdJeIdeeK e9dd      f   deMdSe1ddfd       Zle]j                  dRg dW      	 	 	 	 ddeYde0de/deMdSe1ddfd       Zm e6d      Zne]j                  end       enj                  dAdBdCig dE      	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 ddeVdeWdFeGdNeHdHe+dIe-dJeIdKe\dLe*dMe,dOeJdPeLdQeOdRePdeMdSe1deQdeRddf&d       Zp e6d      Zqe]j                  eqd       eqj                  dAdBdCidgE      	 	 	 	 	 	 	 	 	 	 	 	 	 ddeUdFeFdGeXdeSdeTdHe+dIe-dJeIdKe\dLe*dMe,dNeHdOeJdQeOdeMdSe1ddf"d       Zreqj                  dmdgW      	 	 	 	 ddoeeK e9dpdqd      f   deMdSe1d{eeCe@   dz   e9dYd|d      f   ddf
d       Zseqj                  ddgW      	 	 ddeeCe@    e8d      f   deMdSe1ddfd       Zteqj                  ddgW      	 	 dde[deMdSe1ddfd       Zueqj                  ddgW      	 	 dde[deMdSe1ddfd       Zveqj                  ddgW      	 	 dde[deMdSe1ddfd       Zweqj                  ddgW      	 	 dde[deMdSe1ddfd       Zxeqj                  dddgW      	 	 	 	 dde[dJeIdeeK e9dd      f   deMdSe1ddfd       Zy e6d      Zzeqj                  ezd       ezj                  dAdBdCiddgE      	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 ddeUdeVdeWdeSdeTdFeGdNeHdHe+dIe-dJeIdKe\dLe*dMe,dOeJdQeOdeMdSe1deQdeRddf(dĄ       Z{deCe@   dz  debe@e@f   dz  fdńZ|deCeCe@eNz        deCe@   de@fdȄZ} edɫ      Z~dee~   dedee~   f   debddfd΄Zdej                   j                  dedee~   f   deCeb   dee~   fdфZy)z@Contains commands to interact with jobs on the Hugging Face Hub.    N)CallableIterable)fnmatch)Path)EmptyQueue)	AnnotatedAnyTypeVar)urlsplit)HfApiJobHardwareJobInfoJobStageVolume	constants)TERMINAL_JOB_STAGES)CLIError)logging)_format_size)_split_mount)format_durationparse_duration   )
EnvFileOptEnvOptSecretsFileOpt
SecretsOpt
SoftChoiceSshDryRunOptSshIdentityFileOptTokenOptexec_ssh
get_hf_apiparse_env_mapparse_volumestyper_factory)ArgumentOption)_dataclass_to_dictoutjob_id	namespacereturnc                     | st        d      | j                  d      dkD  rt        d|  d      d| vr| |fS | j                  dd      \  }}|r|st        d|  d      |||k7  rt        d| d| d      ||fS )	a&  Extract namespace from job_id if provided in 'namespace/job_id' format.

    Allows users to pass job IDs copied from the Hub UI (e.g. 'username/job_id')
    instead of only bare job IDs. If the namespace is also provided explicitly via
    --namespace and conflicts, a CLIError is raised.
    zJob ID cannot be empty./r   z<Job ID must be in the form 'job_id' or 'namespace/job_id': 'z'.z(Conflicting namespace: got --namespace='z ' but job ID implies namespace='')r   countsplit)r,   r-   extracted_namespaceparsed_job_ids       b/Users/ahmed/devFolder/claude-voice/.venv/lib/python3.12/site-packages/huggingface_hub/cli/jobs.py_parse_namespace_from_job_idr7   :   s     011||C1UV\U]]_`aa
&y  )/c1)=&mUV\U]]_`aa.A!A6ykAabuavvwx
 	
 ---    volumesapic                *   | syg }| D ]  }|j                  t        j                        r |j                  t	        |g      xs g        Ct        ||      \  }}}|t        d| d      t        |      j                         j                         st        d| d      |j                  ||||nd|      }|j                  d	u r5t        j                  d
| d|j                   d|j                   d|        |j!                  |       
 |S )a  Parse `-v` specs for Jobs commands.

    Same as [`parse_volumes`] but the source side can also be a local directory: it is synced to a
    bucket via [`HfApi.sync_job_volume`] and the resulting bucket subfolder is mounted (read-only
    unless ':rw' is specified).
    N)rawz#Missing mount path in volume spec 'zC'. Expected 'LOCAL_DIR:/MOUNT_PATH[:ro|:rw]' (e.g. './data:/data').zVolume source 'z' is not an existing local directory. To mount a repo or bucket instead, use the 'hf://' syntax (e.g. 'hf://buckets/my-org/my-bucket:/data').T)	read_onlyr-   FzVolume 'zg' is mounted read-write. Once the job is over, pull back its data with:
  hf buckets sync hf://buckets/r0    )
startswithr   HF_PROTOCOLextendr&   r   r   r   
expanduseris_dirsync_job_volumer=   r+   hintsourcepathappend)	r9   r:   r-   resultraw_specrF   
mount_pathr=   volumes	            r6   _parse_and_sync_job_volumesrM   V   sF    Fy445MM-
39r: )5X8(L%
I5hZ  @C  D  F|&&(//1!& *z z  $$#,#8id	 % 
 u$HH:, '228--&++aPVxY 	f7 8 Mr8   g?zThe Docker image to use.)helpz.Use a custom Docker image with `uv` installed.zcFlavor for the hardware. Run 'hf jobs hardware' to list available flavors. Defaults to `cpu-basic`.)rN   
click_typez-lz--labelz3Set labels. E.g. --label KEY=VALUE or --label LABELzVMax duration: int/float with s (seconds, default), m (minutes), h (hours) or d (days).z-dz--detachz3Run the Job in the background and print the Job ID.zVThe namespace where the job will be running. Defaults to the current user's namespace.z--exposezExpose a container port through the jobs proxy. Repeat the flag for multiple ports (e.g. `--expose 8000 --expose 8001`). Each exposed port is reachable on the public jobs domain; access requires an HF token with read access to the job's namespace.z--sshzMake the job's container reachable over SSH. Connect with `hf jobs ssh <job_id>`. Requires an SSH public key registered on https://huggingface.co/settings/keys.z--withz%Run with the given packages installedz-pz--pythonz5The Python interpreter to use for the run environmentz!Suspend (pause) the scheduled Jobz8Allow multiple instances of this Job to run concurrentlyzWOne of annually, yearly, monthly, weekly, daily, hourly, or a CRON schedule expression.z$UV script to run (local file or URL)zArguments for the scriptzThe command to run.zJob ID (or 'namespace/job_id')zJob IDs (or 'namespace/job_id')z2Scheduled Job ID (or 'namespace/scheduled_job_id')z-vz--volumea  Mount one or more volumes. Format: hf://[TYPE/]SOURCE:/MOUNT_PATH[:ro|:rw] or LOCAL_DIR:/MOUNT_PATH[:ro|:rw]. TYPE is one of: models, datasets, spaces, buckets. TYPE defaults to models if omitted. models, datasets and spaces are always mounted read-only. buckets are read+write by default. A local directory source is first synced to a bucket and mounted read-only by default. E.g. -v hf://datasets/org/ds:/data or -v hf://buckets/org/b:/mnt:ro or -v ./inputs:/inputszRun and manage Jobs on the Hub.jobc                 X   | j                  |j                  |j                  j                  d      D ]  }t	        j
                  |        | j                  |j                  |j                  j                        }|j                  j                  t        j                  k7  rc|j                  j                  rd|j                  j                   nd}t        d|j                   d|j                  j                   d|       t	        j
                  d|j                   d	       y
)zcStream Job logs until the Job ends, then fail the command if the Job did not complete successfully.T)r,   r-   followr,   r-   z:  zJob z finished with stage 'r1   z
 completedN)fetch_job_logsidownernamer+   textwait_for_jobstatusstager   	COMPLETEDmessager   )r:   rP   logfinalr^   s        r6   _stream_logs_and_check_statusra   .  s    !!399>>RV!W X CFFciinnEE||X///161E1EBu||++,-2ehhZ'=ell>P>P=QQRSZR[\]]HHtEHH:Z()r8   runignore_unknown_optionsT)z3hf jobs run python:3.12 python -c 'print("Hello!")'z1hf jobs run --detach python:3.12 python script.pyz3hf jobs run -e FOO=foo python:3.12 python script.pyz;hf jobs run --secrets HF_TOKEN python:3.12 python script.pyz^hf jobs run -v hf://org/my-model:/data -v hf://buckets/org/b:/mnt python:3.12 python script.py)context_settingsexamplesimagecommandenvsecretslabelrL   env_filesecrets_fileflavortimeoutdetachexposesshtokenc                 d   t        ||      }t        ||      }t        |      }|j                  | |||t        |      t	        |||      ||	|||      }t        j                  d|j                  |j                         t        |j                  j                  t              rDdj                  d |j                  j                  D              }t        j                  d|        t        |j                  j                  t               r:t        j                  d	|j"                  j$                   d
|j                   d       |
r[|j"                  j$                   d
|j                   }t        j                  d| d| d       t        j                  d| d       yt'        ||       y)z
Run a Job.rr   r:   r-   )rf   rg   rh   ri   labelsr9   rm   rn   rp   rq   r-   Job startedrV   url
c              3   &   K   | ]	  }d |   ywz  N .0ry   s     r6   	<genexpr>zjobs_run.<locals>.<genexpr>j       F/E2cU/E   SExposed ports are reachable at (requires an HF token with read access to the job):
Use `hf jobs ssh r0   &` to open an SSH session into the job.Use `hf jobs logs -f &` to stream logs, or `hf jobs inspect ` to check status.Use `hf jobs wait ` to block until it finishes.N)r%   r$   run_job_parse_labels_maprM   r+   rI   rV   ry   
isinstancer[   expose_urlslistjoinrE   ssh_urlstrrW   rX   ra   )rf   rg   rh   ri   rj   rL   rk   rl   rm   rn   ro   rp   rq   r-   rr   env_mapsecrets_mapr:   rP   urlsjob_refs                        r6   jobs_runr   :  sl   : C*G6K
5
!C
++ '+FyQ  C JJ}SWW5#**(($/yyFszz/E/EFFghlgmno#**$$c*$SYY^^$4AcffX=cdeYY^^$AcffX.(	1WX_W``rst%gY.KLM!#s+r8   logs)zhf jobs logs <job_id>zhf jobs logs -f <job_id>zhf jobs logs --tail 20 <job_id>z#hf jobs logs -f --tail 100 <job_id>)re   rR   z-fz--followzqFollow log output (stream until the job completes). Without this flag, only currently available logs are printed.tailz-nz--tailzvNumber of lines to show from the end of the logs. When combined with --follow, starts streaming from the last N lines.c                     t        | |      \  } }t        |      }|j                  | |||      }|D ]  }t        j                  |        |r%|r| d|  n| }t        j
                  d| d       yy)a  Fetch the logs of a Job.

    By default, prints currently available logs and exits (non-blocking).
    Use --follow/-f to stream logs in real-time until the job completes.
    Use --tail/-n to limit the number of lines returned (server-side when supported).

    Note: following exits when the log stream ends, regardless of whether the Job
    succeeded or failed. Run `hf jobs inspect <job_id>` to check the final status.
    rt   )r,   r-   rR   r   r0   z#Stream ended. Run `hf jobs inspect z6` to check the final status (e.g. COMPLETED or ERROR).N)r7   r$   rU   r+   rY   rE   )	r,   rR   r   r-   rr   r:   r   r_   r   s	            r6   	jobs_logsr   v  s    N 5VYGFI
5
!CVyVZ[D -6YKq)F6wi?uvw r8   job_propertiesfiltersc                     |D ]Z  \  }}}| j                  |      }||dk(  r  yt        |j                         |j                               }|dk(  r|r	|dk(  sW|sZ y y)z5Check if scheduled job matches all specified filters.!=F=T)getr   lower)r   r   keyop_strpatternvaluematchs          r6   _matches_filtersr     sf     'VW""3'=~w}}7cM%Vt^ !( r8   nc                 F    d}d}t        |       D ]  }t        ||        y )Nz[1Az[2K)end)rangeprint)r   LINE_UP
LINE_CLEARis       r6   _clear_liner     s$    GJ1Xg:& r8   metrics_streamtable_headersc              #     K   |D ]J  }| |d    dt        |d   dz  d      t        d|d   z  |d   z  d	       dt        |d          d
t        |d          dt        |d          dt        |d          dg}|d   rt        |d   t              r|gdgt	        |      z  gt	        |d         dz
  z  z   }t        |t        |d               D ]R  \  }}|d   |   }||d    dt        d|d   z  |d   z  d	       dt        |d          d
t        |d          dgz  }T n!|dgt	        |      t	        |      z
  z  z  }|g}d| |f M d| g f y w)Ncpu_usage_pct%cpu_millicoresg     @@r   d   memory_used_bytesmemory_total_bytes   zB / Brx_bpszbps / tx_bpsbpsgpusrT   utilizationN/AFT)roundr   r   dictlenzipsorted)r,   r   r   metricsrowrowsgpu_idgpus           r6   _get_jobs_stats_rowsr     s     "'(*'*+f4a8S7#677'BV:WWYZ[\\]^G$789:$|GThLi?j>kklmGH-./vl78CT6U5VVYZ
 6?z'&/4@5RD3s8O,GFO0Dq0HIID"4)@AVfof-=)*!,S3':#;;cBV>WWYZ[\\]^#C(;$<=>d<PSThPiCjBkklm   B E7c-03s8;<<C5DVT!!+ ", 
s   EEstatszhf jobs stats <job_id>job_idsc           	         | +g }| D ]"  }t        ||      \  }}|j                  |       $ |} t        |      }||j                         d   }| O|j	                  |      D cg c]4  }|j
                  r|j
                  j                  nddv r|j                  6 } }t        |       dk(  rt        j                  d       yg d	}t        j                  j                  t        |             5 }i }	| D ]+  }|g}
|
|d
d D cg c]  }d|v sd|v rdnd c}z  }
|
g|	|<   - t        j                         }|	D 
cg c]  }|	|   D ]  }
|
  }}}
t        t!        ||             | D cg c]  }||j#                  ||      |d }}t%        |t&        |      D ]  \  }}}|r|	j)                  |d       n||	|<   t        j                         }||z
  t*        k\  sBt-        dt        |      z          |	D 
cg c]  }|	|   D ]  }
|
  }}}
t        t!        ||             |} 	 ddd       yc c}w c c}w c c}
}w c c}w c c}
}w # 1 sw Y   yxY w)z7Fetch the resource usage statistics and metrics of JobsNrt   rX   r-   UNKNOWN)RUNNINGUPDATINGr   zNo running jobs found)	zJOB IDzCPU %zNUM CPUzMEM %z	MEM USAGEzNET I/Oz
GPU UTIL %z	GPU MEM %zGPU MEM USAGEr   r0   USAGEz-- / --z--)headersrS   )r,   r   r   )kwargs_listr   )r7   rH   r$   whoami	list_jobsr[   r\   rV   r   r+   rY   multiprocessingpool
ThreadPooltimer   	_tabulatefetch_job_metricsiflatmap_unorderedr   popSTATS_UPDATE_MIN_INTERVALr   )r   r-   rr   
parsed_idsr,   r:   rP   r   r   rows_per_job_idr   headerlast_update_time
total_rowsr   doner   nows                     r6   
jobs_statsr     s    
F <VY OFIf%  
5
!CJJL(	 }}y}9
9$'JJ

  IBYY FF9 	 

 7|q()
M 
			(	(W	6$<>F$*8C^klmln^op^oTZ#-7f3DI4O^oppC'*eOF#   99;(7[f?SYCZCcCZc
[ 	i
M:; "
 "	 !"%"7"7vQZ"7"[!.
 " 	 
 #5T;O]h"iD&$##FD1*.'))+C%%)BBAJ/00?cf?[aKbCcKbc
ci
MBC#&  #j) 
7	6'
. q \

  d9 
7	6sO   %9H60IH;
&I<I I,I
AI I<I
I;IIzlist | ls | ps)z
hf jobs lszhf jobs ls -az&hf jobs ls --status running,schedulingz+hf jobs ls --label env=prod --label team=mlz%hf jobs ls --all --label hf-sandbox=1allz-az--allzWShow all Jobs (default shows running and scheduling). Cannot be combined with --status.r[   z--statuszfOnly show Jobs with the given status. Comma-separated or repeated, e.g. `--status running,scheduling`.)rO   rN   z{Only show Jobs with the given `key=value` label. Repeat to require several labels, e.g. `--label env=prod --label team=ml`.limitz--limitzCMaximum number of Jobs to display. Set to 0 to show all (no limit).filterz--filterz2(Deprecated) Use `--status` and `--label` instead.c                    t        |      }|rt        j                  d| d       | r|rt        d      g }|xs g D ])  }	|j	                  d |	j                  d      D               + |r|}
n9| rd}
n4t        j                  j                  t        j                  j                  g}
i }|xs g D ].  }d|vrt        d	| d
      |j                  d      \  }}	|	||<   0 |j                  ||
|xs d      }d}|dkD  r8t        t        j                  ||dz               }t        |      |kD  rd}|d| }nt        |      }g }|D ]  }t        |      }|j!                  d      xs i }|j!                  d      xs g }|j!                  dd      |d<   |j!                  d      xs d|d<   |rdj#                  |      nd|d<   |j!                  d      r|d   dd j%                  dd      nd|d<   |j!                  d      xs i j!                  dd      |d<   t'        |j!                  d             |d!<   |j)                  |        t        j*                  |g d"d#       |rt        j,                  d$| d%       |sg|s|rJd&j#                  g d' |D        d( |j/                         D              }t        j0                  d)|        y| st        j,                  d*       yyy)+zList Jobs.

    Use `--status` to filter by status (see [`JobStage`] for possible values) and `--label` to filter by `key=value`
    labels. A Job must match every filter to be listed.
    rt   zIgnoring filter 'zc'. `-f`/`--filter` is deprecated and will be removed in a future release. Use `--status`/`--label`.z0`-a`/`--all` cannot be combined with `--status`.c              3   ^   K   | ]%  }|j                         s|j                          ' y wN)strip)r   parts     r6   r   zjobs_ps.<locals>.<genexpr>f  s!     V5ETDJJL5Es   --,Nr   zInvalid label filter 'z"': must be in the form 'key=value')r-   r[   rv   Fr   r   T	durationsrg   rV   rT   r,   docker_imager   image/spacer>   
created_at   Tcreatedr[   r\   r   running_secsruntime)r,   r   rg   r   r[   r   r   id_keyzOutput truncated to z4 Jobs. Use `--limit 0` to show all (or `--limit N`)., c              3   &   K   | ]	  }d |   yw)zstatus=Nr}   )r   ss     r6   r   zjobs_ps.<locals>.<genexpr>  s     7,QWQC=,r   c              3   2   K   | ]  \  }}d | d|   yw)zlabel=r   Nr}   )r   kvs      r6   r   zjobs_ps.<locals>.<genexpr>  s'     :gXfPTPQSTVA3as;KXf   zNo jobs matched filters: zHNo running jobs. Use `-a`/`--all` to include finished (and failed) jobs.)r$   r+   warningr   rA   r3   r   r   r   
SCHEDULINGr   r   	itertoolsislicer   r*   r   r   replacer   rH   tablerE   itemsrY   )r   r[   rj   r   r-   rr   r   r:   raw_statusesr   server_statusesrv   itemr   	jobs_iter	truncatedjobs	job_itemsrP   job_itemr   cmdfilters_msgs                          r6   jobs_psr    s   t 5
!Cx (p p	

 vIJJ !L2VU[[5EVV  &	#++1183F3F3L3LM  Fd?3D69[\]]ZZ_
Us	  	/RXR`\`aI IqyI$$Y	:;t9uI<DI ')I%c*LL-3	ll9%+%\\$3"*,,~">"G%/2chhsmOW||\hOih|4Sb9AA#sKot&ll84:??S-immN.KL"  IIT
 'w.bcd6))h7,7h:gX^XdXdXf:ghK HH0>?HH_`  r8   hardwarezhf jobs hardwarec                  ^   t               } | j                         }g }|D ]  }d}|j                  rG|j                  j                   d|j                  j                   d|j                  j
                   d}|j                  rd|j                  dnd}|j                  rd|j                  dz  d	nd}|j                  |j                  |j                  |j                  |j                  |j                  |||d
        t        j                  |       t        j                  d       y)z(List available hardware options for JobsrT   zx  ()$z.4ffree<   z.2f)rX   zpretty namecpuramstorageacceleratorzcost/minz	cost/hourzLUse `hf jobs run --flavor <name> ...` to request a specific hardware flavor.N)r$   list_jobs_hardwarer"  quantitymodelvramunit_cost_usdrH   rX   pretty_namer  r   ephemeral_storager+   r  rE   )r:   hardware_listr  hwaccelerator_infocost_min	cost_hours          r6   jobs_hardwarer/    s    ,C**,ME>>"$.."9"9!:"R^^=Q=Q<RRTUWUcUcUhUhTiijk131A1AQr'',-v797G7Ga((2-c23V	!~~vvvv///$&		
 $ IIeHH[\r8   inspectzhf jobs inspect <job_id>z*Job IDs to inspect (or 'namespace/job_id')c                    g }| D ]"  }t        ||      \  }}|j                  |       $ |} t        |      }| D cg c]  }|j                  ||       }}t	        j
                  |D cg c]  }t        |       c}       yc c}w c c}w )z0Display detailed information on one or more Jobsrt   rS   N)r7   rH   r$   inspect_jobr+   r  r*   )r   r-   rr   r   r,   r:   r  rP   s           r6   jobs_inspectr3    s     J8K	&!  G
5
!CNUVgFCOO6YO?gDVII$7$3!#&$78 W7   B+B
cancelzhf jobs cancel <job_id>c                     t        | |      \  } }t        |      }|j                  | |       t        j                  d|        y)zCancel a Jobrt   rS   zJob cancelledrV   N)r7   r$   
cancel_jobr+   rI   )r,   r-   rr   r:   s       r6   jobs_cancelr9    s=     5VYGFI
5
!CNN&IN6JJ6*r8   wait)zhf jobs wait <job_id>z"hf jobs wait <job_id_1> <job_id_2>z"hf jobs ls -q | xargs hf jobs waitz,Job IDs to wait for (or 'namespace/job_id').zZMax time to wait: int/float with s (seconds, default), m (minutes), h (hours) or d (days).c           
      *   g }t               }| D ]3  }t        ||      \  }}|j                  |       |j                  |       5 t	        |      dkD  r3t        ddj                  d t        |t              D              z         |j                         }|t        |      nd}	t        |      }
t        j                  dt	        |       d	      }	 |
j                  ||	|
      }|j!                  t	        |       d       t        j"                  |D cg c]C  }|j$                  t        |j                  j&                        |j                  j(                  dE c}       |D cg c],  }|j                  j&                  t*        j,                  k7  s+|. }}|r<t        t	        |       dt	        |       ddj                  d |D              z         y# t        $ r" |j!                  d       t        d| d      dw xY wc c}w c c}w )a  Wait for one or more Jobs to reach a terminal state.

    Blocks until every Job has finished, then exits with code 0 if all Jobs completed
    successfully, or a non-zero exit code if any Job was canceled, errored or deleted.

    All Jobs must belong to the same namespace.
    r   z0All Job IDs must be in the same namespace, got: r   c              3   2   K   | ]  }t        |        y wr   )r   )r   nss     r6   r   zjobs_wait.<locals>.<genexpr>
  s     F*EBB*Er  )r   Nrt   zWaiting for z Job(s) to finish...)rn   r-   z
Timed out.zTimed out after z waiting for Job(s) to finish.z Job(s) finished.)rV   r\   r^   z of z' Job(s) did not complete successfully: c              3   h   K   | ]*  }|j                    d |j                  j                   d , yw)r  r  N)rV   r[   r\   )r   rP   s     r6   r   zjobs_wait.<locals>.<genexpr>  s-     KFS366("SZZ%5%5$6a8Fs   02)setr7   rH   addr   r   r   r   r   r   r   r$   r+   r[   rZ   TimeoutErrorr   r  rV   r\   r^   r   r]   )r   rn   r-   rr   r   
namespacesr,   	parsed_idparsed_namespacetimeout_secsr:   r[   r  rP   faileds                  r6   	jobs_waitrG    s   > JJ&B69&U#	#)$'(  :>iiF&*EFFG
 	
  I.5.A>'*tL
5
!CZZ,s:&77KLMF]
LIV KK3t9+./0IIhlmhladcffs3::+;+;'<I[I[\hlmn!LTcSZZ%5%59K9K%KcTFL6{m4D	{*QRiiKFKKL
 	
   ]L!)'2PQRX\\]
 nLs   G AH+,HH+Hrv   z8hf jobs labels <job_id> --label env=prod --label team=mlzhf jobs labels <job_id> --clearclearz--clearzRemove all labels from the job.c                     |s|st        d      |r|rt        d      t        | |      \  } }t        |      xs i }t        |      }|j	                  | ||      }t        j                  d|j                         y)z5Update labels on a Job. Replaces all existing labels.OPlease set at least one label with --label. To remove all labels, pass --clear.bCannot set labels and clear them at the same time. Please use either --label or --clear, not both.rt   )r,   rv   r-   Labels updatedr7  N)r   r7   r   r$   update_job_labelsr+   rI   rV   )r,   rj   rH  r-   rr   rv   r:   rP   s           r6   jobs_labelsrN  !  s     hiip
 	
 5VYGFIu%+F
5
!C


vf	

RCJJCFF+r8   )zhf jobs ssh <job_id>zhf jobs ssh <job_id> --dry-runz)hf jobs ssh <job_id> -i ~/.ssh/id_ed25519identity_filedry_runc                    t        | |      \  } }t        |      }|j                  | |      }|j                  j                  t        d      |j                  j                  t        v r0t        d|j                   d|j                  j                   d      |j                  j                  t        j                  k7  rt        j                  d|j                   d	|j                  j                   d
      }|j                  |j                  |t        j                  g      }|j                  j                  t        j                  k7  rA|j                  d       t        d|j                   d|j                  j                   d      |j                  d       t        |j                  j                        }t        |j                    d|j"                   |j$                  ||       y)a   SSH into a running Job.

    If the Job is not yet running, waits until it reaches the RUNNING state before
    connecting. Requires the Job to be started with SSH enabled (`hf jobs run --ssh ...`)
    and your SSH public key to be registered at https://huggingface.co/settings/keys.
    rt   rS   Nz[SSH is not enabled on this job. Start a job with SSH support using `hf jobs run --ssh ...`.zCannot SSH into job 'z%': job has already finished (stage: 'z').zWaiting for job 'z' to be running (stage: 'z')...)r,   r-   stageszJob finished.z1': job finished before reaching RUNNING (stage: 'zJob is running.@)portrO  rP  )r7   r$   r2  r[   r   r   r\   r   rV   r   r   r+   rZ   r   r   r#   usernamehostnamerT  )	r,   rO  rP  r-   rr   r:   rP   r[   r   s	            r6   jobs_sshrW  =  s   * 5VYGFI
5
!C
//9/
=C
zz!tuu
zz...svvh6[\_\f\f\l\l[mmpqrr
zz8+++/x7PQTQ[Q[QaQaPbbghicff	8K[K[J\]::x///KK('x/`adakakaqaq`rruv  	%&szz))*G
Ag../0\\#	r8   zFRun UV scripts (Python with inline dependencies) on HF infrastructure.uv)rX   )zhf jobs uv run my_script.pyz$hf jobs uv run --detach my_script.pyz1hf jobs uv run ml_training.py --flavor a10g-smallz+hf jobs uv run --with transformers train.pyzNhf jobs uv run -v hf://org/my-model:/data -v hf://buckets/org/b:/mnt script.pyscriptscript_argswith_pythonc                 r   t        ||      }t        ||	      }t        |      }|j                  | |xs g |||||t        |      t	        |||      ||
|||      }t        j                  d|j                  |j                         t        |j                  j                  t              rDdj                  d |j                  j                  D              }t        j                  d|        t        |j                  j                  t               r:t        j                  d	|j"                  j$                   d
|j                   d       |r[|j"                  j$                   d
|j                   }t        j                  d| d| d       t        j                  d| d       yt'        ||       y)8Run a UV script (local file or URL) on HF infrastructurert   ru   )rY  rZ  dependenciesr\  rf   rh   ri   rv   r9   rm   rn   rp   rq   r-   rw   rx   rz   c              3   &   K   | ]	  }d |   ywr|   r}   r~   s     r6   r   zjobs_uv_run.<locals>.<genexpr>  r   r   r   r   r0   r   r   r   r   r   r   N)r%   r$   
run_uv_jobr   rM   r+   rI   rV   ry   r   r[   r   r   r   rE   r   r   rW   rX   ra   )rY  rZ  rf   rm   rh   ri   rj   rL   rk   rl   rn   ro   rp   rq   r-   rr   r[  r\  r   r   r:   rP   r   r   s                           r6   jobs_uv_runrb  o  s{   @ C*G6K
5
!C
..%2 '+FyQ  C  JJ}SWW5#**(($/yyFszz/E/EFFghlgmno#**$$c*$SYY^^$4AcffX=cdeYY^^$AcffX.(	1WX_W``rst%gY.KLM!#s+r8   z,Create and manage scheduled Jobs on the Hub.	scheduledz>hf jobs scheduled run "0 0 * * *" python:3.12 python script.pyschedulesuspendconcurrencyc                 :   t        ||	      }t        ||
      }t        |      }|j                  ||| ||||t        |      t	        |||      ||||      }t        j                  d|j                         t        j                  d|j                   d       y)	zSchedule a Job.rt   ru   )rf   rg   rd  re  rf  rh   ri   rv   r9   rm   rn   rp   r-   Scheduled Job createdr7  Use `hf jobs scheduled inspect ` to view its details.N)	r%   r$   create_scheduled_jobr   rM   r+   rI   rV   rE   )rd  rf   rg   re  rf  rh   ri   rj   rL   rk   rl   rm   rn   rp   r-   rr   r   r   r:   scheduled_jobs                       r6   scheduled_runrm    s    0 C*G6K
5
!C,, '+FyQ - M JJ&=+;+;<HH.}/?/?.@@VWXr8   zhf jobs scheduled lsz1Show all scheduled Jobs (default hides suspended)z>Filter output based on conditions provided (format: key=value)c                    t        |      }|j                  |      }g }|xs g D ]  }d|v ra|j                  dd      \  }}	|j                  d      rd}
|dd }nd}
|j	                  |j                         |
|	j                         f       ht        j                  d	| d
        g }|D ]  }|j                  xs d}| s|r|j                  j                  xs d}|j                  j                  xs g }|rdj                  |      nd}|j                  |t        |      |d}t        ||      s|j	                  |        g }|D ]  }t!        |      }|j#                  d      xs i }|j#                  d      xs i }|j#                  d      }|j#                  d      xs g }|j#                  d      xs d|d<   |rdj                  |      nd|d<   |r)|j#                  d      r|d   dd j%                  dd      nd|d<   |j#                  d      r|d   dd j%                  dd      nd|d<   |j#                  d      xs d|d<   |j	                  |        t        j&                  |g dd       |s2|r0dj                  d  |D              }t        j(                  d!|        |r;|d"   d   }t        j*                  d#| d$       t        j*                  d%| d&       yy)'zList scheduled Jobsrt   r   r   r   !r   Nz Ignoring invalid filter format 'z'. Use key=value format.Fr   r>   )rV   rf   re  rg   job_specr[   last_jobrg   r   r   atr   r   last_runnext_job_run_atnext_runre  )rV   rd  r   rg   rt  rv  re  rV   r   r   c              3   4   K   | ]  \  }}}| | |   y wr   r}   )r   r  or  s       r6   r   zscheduled_ps.<locals>.<genexpr>/  s#     DGAq1#aSGs   z#No scheduled jobs matched filters: r   ri  z(` to view details about a scheduled job.zUse `hf jobs scheduled trigger z)` to trigger a scheduled job immediately.)r$   list_scheduled_jobsr3   endswithrH   r   r+   r  re  rq  r   rg   r   rV   r   r   r*   r   r
  r  rY   rE   )r   r-   rr   r   r:   scheduled_jobsr   fr   r   opfiltered_jobsrl  re  image_or_spacer  command_strpropsr  sjr  rq  status_dictrr  r  first_item_ids                             r6   scheduled_psr    s   , 5
!C,,y,AN*,G\r\!8aJC||C #2hNNCIIKU[[];<KK:1#=UVW  M'''05w&//<<E$$,,2'*chhsm$''.SQX\fqrw/]+ ( #%E!"%88J'-2hhx(.B??:.ll9%+&ll>:Ce]+.#((3-EYDLQYQ]Q]^bQc8D>#2.66sC@inZEP__UfEgK)*3B/77SAmr 	Z ((9-6YT  II_
 WiiDGDD6{mDEa2=/Aijk2=/Ajkl r8   zhf jobs scheduled inspect <id>scheduled_job_idsz>Scheduled Job IDs to inspect (or 'namespace/scheduled_job_id')c                    g }| D ]"  }t        ||      \  }}|j                  |       $ |} t        |      }| D cg c]  }|j                  ||       }}t	        j
                  |D cg c]  }t        |       c}       yc c}w c c}w )z:Display detailed information on one or more scheduled Jobsrt   scheduled_job_idr-   N)r7   rH   r$   inspect_scheduled_jobr+   r  r*   )	r  r-   rr   r   r,   r:   r  r{  rl  s	            r6   scheduled_inspectr  7  s     J#8K	&! $ #
5
!C !2 1 	!!3Cy!Y 1   IInUn]!-0nUV	 Vr4  deletezhf jobs scheduled delete <id>r  c                     t        | |      \  } }t        |      }|j                  | |       t        j                  d|        y)zDelete a scheduled Job.rt   r  zScheduled Job deletedr7  N)r7   r$   delete_scheduled_jobr+   rI   r  r-   rr   r:   s       r6   scheduled_deleter  P  F     #??OQZ"[i
5
!C.>)TJJ&+;<r8   zhf jobs scheduled suspend <id>c                     t        | |      \  } }t        |      }|j                  | |       t        j                  d|        t        j
                  d|  d       y)z Suspend (pause) a scheduled Job.rt   r  zScheduled Job suspendedr7  zUse `hf jobs scheduled resume z` to resume it.N)r7   r$   suspend_scheduled_jobr+   rI   rE   r  s       r6   scheduled_suspendr  ]  s^     #??OQZ"[i
5
!C/?9UJJ(-=>HH-.>-?OPr8   resumezhf jobs scheduled resume <id>c                     t        | |      \  } }t        |      }|j                  | |       t        j                  d|        y)z!Resume (unpause) a scheduled Job.rt   r  zScheduled Job resumedr7  N)r7   r$   resume_scheduled_jobr+   rI   r  s       r6   scheduled_resumer  k  r  r8   triggerzhf jobs scheduled trigger <id>c                 ,   t        | |      \  } }t        |      }|j                  | |      }t        j                  d|j
                  |j                         t        j                  d|j                  j                   d|j
                   d       y)	zJTrigger a scheduled Job to run immediately (does not change the schedule).rt   r  zScheduled Job triggeredrx   r   r0   z` to stream logs.N)
r7   r$   trigger_scheduled_jobr+   rI   rV   ry   rE   rW   rX   )r  r-   rr   r:   rP   s        r6   scheduled_triggerr  x  s|     #??OQZ"[i
5
!C

#
#5EQZ
#
[CJJ(SVVAHH$SYY^^$4AcffX=NOPr8   z>hf jobs scheduled labels <id> --label env=prod --label team=mlz%hf jobs scheduled labels <id> --clearz)Remove all labels from the scheduled job.c                     |s|st        d      |r|rt        d      t        | |      \  } }t        |      xs i }t        |      }|j	                  | ||      }t        j                  d|j                         y)z?Update labels on a scheduled Job. Replaces all existing labels.rJ  rK  rt   )r  rv   r-   rL  r7  N)r   r7   r   r$   update_scheduled_job_labelsr+   rI   rV   )r  rj   rH  r-   rr   rv   r:   rl  s           r6   scheduled_labelsr    s     hiip
 	
 #??OQZ"[iu%+F
5
!C33)&I 4 M JJM$4$45r8   z)Schedule UV scripts on HF infrastructure.z.hf jobs scheduled uv run "0 0 * * *" script.pyz<hf jobs scheduled uv run "0 0 * * *" script.py --with pandasc                 H   t        ||      }t        ||      }t        |      }|j                  ||xs g | |||||||t        |	      t	        |
||      ||||      }t        j                  d|j                         t        j                  d|j                   d       y)	r^  rt   ru   )rY  rZ  rd  re  rf  r_  r\  rf   rh   ri   rv   r9   rm   rn   rp   r-   rh  r7  ri  rj  N)	r%   r$   create_scheduled_uv_jobr   rM   r+   rI   rV   rE   )rd  rY  rZ  re  rf  rf   rm   rh   ri   rj   rL   rk   rl   rn   rp   r-   rr   r[  r\  r   r   r:   rP   s                          r6   scheduled_uv_runr    s    < C*G6K
5
!C

%
%%2 '+FyQ! & C$ JJ&3662HH.svvh6LMNr8   c                 b    | syi }| D ]$  }d|v r|j                  dd      n|df\  }}|||<   & |S )a  Parse label key-value pairs from CLI arguments.

    Args:
        labels: List of label strings in KEY=VALUE format. If KEY only, then VALUE is set to empty string.

    Returns:
        Dictionary mapping label keys to values, or None if no labels provided.
    Nr   r   rT   )r3   )rv   
labels_map	label_varr   r   s        r6   r   r     sL     !#J	03y0@Y__S!,yRTo
U
3  r8   r   r   c           
         t        g | | D cg c]  }t        d |D               }}t        t        j                         j                  t        |      dz        }t        |      t        |      z   |kD  r|j                  t        |            }||xx   dz  cc<   t        |      t        |      z   |k  r#|t        |      z
  t        |      z
  ||   z   ||<   t        |      t        |      z   |kD  r dt        |      z  j                  | }g }|j                   |j                  |        |j                   |j                  |D cg c]  }d|z  	 c}        | D ]r  }	t        |	|      D 
cg c];  \  }
}t        t        |
            |kD  rt        |
      d|dz
   dz   n
t        |
      = }}
}|j                   |j                  |        t d	j                  |      S c c}w c c}w c c}}
w )
z
    Inspired by:

    - stackoverflow.com/a/8356620/593036
    - stackoverflow.com/questions/9535954/printing-lists-as-tabular-data
    c              3   D   K   | ]  }t        t        |              y wr   )r   r   )r   xs     r6   r   z_tabulate.<locals>.<genexpr>  s     /3ac#a&k3s       r   z{{:{}}} -N   z...rz   )r   maxshutilget_terminal_sizecolumnsr   sumindexformatrH   r   r   )r   r   col
col_widthsterminal_widthcol_to_minimize
row_formatlineswr   r  	col_widthrow_format_argss                r6   r   r     s    <?;N;Ng;NO;NC#/3//;NJO113;;S\B=NON
g,Z
(>
9$**3z?;?#)#w<#j/)^;*83z?*JSQX\*Y\fgv\w*wJ'	 g,Z
(>
9
 4*s7|+33Z@JE	LL"""G,-	LL"""j$AjS1Wj$ABC !$C 4
 49 033q6{Y/FCF?Y]#e+CPQFR 4 	 
 	&Z&&89  99U# P %B
s   G*G/6A G4r   queuefunc.kwargsc                 @     |di |D ]  }| j                  |        y )Nr}   )put)r  r  r  rI   s       r6   _write_generator_to_queuer    s    ..		& !r8   r   r   c          	   #   6  K   t               }|D cg c]  }| j                  t        |||f       }}	 	 	 |j                  d       c c}w # t        $ r' t        d |D              r|j                         rY nY 5w xY wn# t        $ r Y nw xY w	 |D cg c]  }|j                  d       nc c}w c} y# t        j                  $ r Y yw xY w# 	 |D cg c]  }|j                  d       nc c}w c} w # t        j                  $ r Y w w xY wxY ww)a;  
    Takes a function that returns an iterable of items, and run it in parallel using threads to return the flattened iterable of items as they arrive.

    This is inspired by those three `map()` variants, and is the mix of all three:

    * `imap()`: like `map()` but returns an iterable instead of a list of results
    * `imap_unordered()`: like `imap()` but the output is sorted by time of arrival
    * `flatmap()`: like `map()` but given a function which returns a list, `flatmap()` returns the flattened list that is the concatenation of all the output lists
    g?)rn   c              3   <   K   | ]  }|j                           y wr   )ready)r   async_results     r6   r   z%iflatmap_unordered.<locals>.<genexpr>.  s     N|))+s   N)
r   apply_asyncr  r   r   r   emptyKeyboardInterruptr   rA  )r   r  r   r  r  async_resultsr  s          r6   r   r     s!     gEfqrfq\bT%%&?%vAVWfqMriii--  s
  NNNSXS^S^S` 	@MN\d+N++ 			@MN\d+N++ 		s   D ADB A 
B D+B ;B ?B  B C 	BC BC B; B21	B; :D;CDCDDC=C43	C=<D=DDDDD)NNNNNNNNFNFNN)FNNN)NNN)FNNr   NNN)r.   N)NN)NFNN)NNNNNNNNNNFNFNNNN)NNNNNNNNNNNNN)NNNNNNNNNNNNNNNNN)__doc__r  r   multiprocessing.poolr  r   collections.abcr   r   r   pathlibr   r  r   r   typingr	   r
   r   urllib.parser   huggingface_hubr   r   r   r   r   r   huggingface_hub._jobs_apir   huggingface_hub.errorsr   huggingface_hub.utilsr   $huggingface_hub.utils._cache_managerr   huggingface_hub.utils._hf_urisr   huggingface_hub.utils._parsingr   r   
_cli_utilsr   r   r   r   r   r    r!   r"   r#   r$   r%   r&   r'   
_frameworkr(   r)   _outputr*   r+   
get_logger__name__loggerr   tupler7   r   rM   r   ImageArgImageOpt	FlavorOpt	LabelsOpt
TimeoutOptbool	DetachOptNamespaceOptint	ExposeOptSshEnabledOptWithOpt	PythonOpt
SuspendOptConcurrencyOptScheduleArg	ScriptArgScriptArgsArg
CommandArgJobIdArg	JobIdsArgScheduledJobIdArgJobVolumesOptjobs_clira   rg   r   r   r   r   r   r   r   r  r/  r3  r9  rG  rN  rW  uv_app	add_grouprb  scheduled_apprm  r  r  r  r  r  r  r  scheduled_uv_appr  r   r   r   r  r   r   r   r}   r8   r6   <module>r     s   G      .    * * ! T T 9 + ) = 7 J    ) , 
		H	%. .t .cSVY]S]oH^ .8)#Y)',)9<t)	&\D)X    ' $J
= $J
rk*	 I
B	 $J
e
 
B	 $J
e I
 G	 
 p I
4 $J
D	 4K
0
 4K
G f 3	 I' I"
 - I.	 A  I
e	
 ?@	*u 	*7 	*t 	* 
	.5  
  #'".,.,., 
., 	.,
 ., ., ., !., ., ., ., ., 
., ., .,  
!.,
.,b 

  $ 	 	"'&x&x E	
	&x d
 J	
	&x$ %&x& '&x( 
)&x&xRT#s(^ d5cSVCW>X ]a '3 '4 '!)$sCx.!9JNs)eD#tDsO44568 
'%=$>?"A'A'A' A' 
	A' @A'H 
  	$ 	 	 	 	" 	Sxa	j	
	
xa S	D!(+y	
	xa" S	D O	
	#xa2 V	
	3xa@ AxaB CxaD S	DE	
	ExaT 
Uxa	xav 
*(:';<] =]6 
)'A&BC #9S	=	
	9 9 9 
9 D9* 
(&?%@A #	+	+	+ 	+ 
		+ B	+ 

  ( 	"4
S	?	
	4
 d
m	
	4
 4
 4
 
4
4
n 
B)   X]",,, T6)2STTU, 	,
 , 
,,* 
	   )-!"##%# # 	#
 # 
##L 
d	e   6  % 	.5  
 "& #'"%4,4,4, 4, 	4,
 
4, 4, 4, 4, 4, !4, 4, 4, 4, 
4, 4,  !4," #4,$ %4,& 
'4,
4,n #QR   ={  3 	.5NO   "& #'"!'Y'Y'Y 'Y 	'Y
  'Y 
'Y 'Y 'Y 'Y 'Y !'Y 'Y 'Y 'Y 'Y  !'Y" 
#'Y
'YT '3I2JK 	" 	%Om	D	
	
Om Om Om S	DQ	
	Om& 
'Om LOmd y,L+MN #W S	Q	
	W W W 
W OW0 x+J*KL #	='	=	= 	= 
		= M	= y,L+MN #
Q'
Q
Q 
Q 
	
Q O
Q x+J*KL #	='	=	= 	= 
		= M	= y,L+MN #
Q'
Q
Q 
Q 
	
Q O
Q H/   bg"6'66 T6)2]^^_6 	6
 6 
66. !&QR    (t  4 	.58F   "&"& #'"'-O-O-O -O 	-O
  -O -O -O 
-O -O -O -O -O !-O -O -O  !-O" #-O$ %-O& '-O( 
)-O-Ofd3i$. 4S>D3H $DcCi) DI # 6 CLU1X Xc8A;>N5O Y] bf 




)
)
3#
$ d	
 a[r8   