o
     
jV                     @   s  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ZddlZddlm	Z	m
Z
 ddlmZmZ ddlmZ ddlmZmZ ddlZddlmZmZmZ ddlmZmZ d	d
lmZ d	dlmZ dZedZdZ dZ!ee!dZ"dZ#dZ$dZ%dZ&e'e(Z)e
G dd dZ*e"j+dg dd	drdej,dee-ej.ddf dee/ej0dd df d!dfd"d#Z1e"j+d$d%dd%d&d'd(gd)dej,d*ee-ej.d+df d!dfd,d-Z2e"j+d.d/gddsd0d1Z3e"j+d2d3gddsd4d5Z4e"j+d6d7gdd*ee-ej.d8df d!dfd9d:Z5d!e6e* fd;d<Z7d!e6e8e-e-f  fd=d>Z9d?e6e- d@e:e- d!e;dB fdAdBZ<dCe-d!edB fdDdEZ=ddFdGe-dHe-dCe-dIedJe-dKe-dB d!e*fdLdMZ>dGe-dHe-dJe-dCe-d!e?f
dNdOZ@dGe-dHe-dCe-dIedPe?d!e*fdQdRZAdGe-dHe-dCe-dIedJe-d!e*fdSdTZBdGe-dHe-dJe-dUe-dB d!e-dB f
dVdWZCd!efdXdYZDdCe-d!efdZd[ZEdGe-dHe-d!e8e-e-dB f fd\d]ZFdCe-d!e-fd^d_ZGdCe-d!efd`daZHdbed!efdcddZIdbedCe-d!efdedfZJeKdgZLdCe-dhe-d!e-fdidjZMde-d!e8e-e-e-f fdkdlZNd*e-d!e-fdmdnZOdoed?e6e- d!e;fdpdqZPdS )tz0Contains helper utilities for hf CLI extensions.    N)asdict	dataclass)datetimetimezone)Path)	AnnotatedLiteral)CLIErrorCLIExtensionInstallErrorConfirmationError)get_sessionlogging   )typer_factory)outhuggingfacez~/.local/share/hf/extensionszmanifest.jsonzManage hf CLI extensions.

Security Warning: extensions are third-party executables or Python packages. Install only from sources you trust.)helpmainzhf-extension
   i,  c                   @   s   e Zd ZU eed< eed< eed< eed< eed< eed< ed ed< eed	< eed
< dZedB ed< ede	dd fddZ
de	ddfddZdS )ExtensionManifestownerreporepo_id
short_nameexecutable_nameexecutable_path)binarypythontypeinstalled_atsourceNdescriptionpathreturnc                 C   sN   |t  }| std| dt| }t|d |d< tdi |S )NzManifest file not found at z". Your extension may be corrupted.r    )	MANIFEST_FILENAMEis_filer	   jsonloads	read_textr   fromisoformatr   )clsr"   manifest_pathdatar$   r$   Q/home/kuhnn/.local/lib/python3.10/site-packages/huggingface_hub/cli/extensions.pyloadC   s   zExtensionManifest.loadc                 C   sH   |t  }|jjddd t| }| j |d< |tj|ddd d S )NTparentsexist_okr      )indent	sort_keys)	r%   parentmkdirr   r   	isoformat
write_textr'   dumps)selfr"   r,   r-   r$   r$   r.   saveL   s
   zExtensionManifest.save)__name__
__module____qualname__str__annotations__r   r   r!   classmethodr   r/   r<   r$   r$   r$   r.   r   6   s   
 r   install)zhf extensions install hf-claudez-hf extensions install hanouticelina/hf-claudez(hf extensions install alvarobartt/hf-mem)examplesFctxr   z:GitHub extension repository in `[OWNER/]hf-<name>` format.forcez--forcezOverwrite if already installed.r#   c                 C   s   t |\}}}|  }tt|jdi  }||v r%td| d| dt|}| }	|	r9|s9td| dt	||d\}
}|	rHt
| t|||||
|d}|j }t| d	| d
| d td|  dS )zInstall an extension from a public GitHub repository.

    Security warning: this installs a third-party executable or Python package.
    Install only from sources you trust.
    commandszCannot install extension 'z,' because it conflicts with an existing `hf z
` command.Extension 'z1' is already installed. Use --force to overwrite.)r   	repo_name)r   rI   r   extension_dirbranchr!   z' extension installed successfully from /.zRun it with: hf N)_normalize_repo_id	find_rootsetgetattrcommandkeysr	   _get_extension_direxists_resolve_github_repo_infoshutilrmtree_install_extension_from_githubr   
capitalizeprint)rE   r   rF   r   rI   r   root_ctxreserved_commandsrJ   extension_existsrK   r!   manifestext_typer$   r$   r.   extension_installT   s2   

ra   execT)allow_extra_argsallow_interspersed_argsignore_unknown_optionsz#hf extensions exec claude -- --helpz/hf extensions exec claude --model zai-org/GLM-5)context_settingsrD   namez.Extension name (with or without `hf-` prefix).c                 C   sF   t |}t|}| std| dt|t| jd}tj|d)zExecute an installed extension.rH   ' is not installed.r   args)code)	_normalize_extension_name"_resolve_installed_executable_pathr&   r	   _execute_extension_binarylistrj   typerExit)rE   rg   r   r   	exit_coder$   r$   r.   extension_exec   s   rs   z	list | lszhf extensions listc                  C   s"   dd t  D } tj| dd dS )z"List installed extension commands.c                 S   s:   g | ]}d |j  t|jt|j|jd|jdqS )zhf z%Y-%m-%d)rR   r    r   	installedr!   )r   r@   r   r   r   strftimer!   ).0r_   r$   r$   r.   
<listcomp>   s    

z"extension_list.<locals>.<listcomp>rR   )id_keyN)_list_installed_extensionsr   table)rowsr$   r$   r.   extension_list   s   
r|   searchzhf extensions searchc               	   C   s   t  jddt dddddtd} |   |  }d	d
 t D }g }|dg D ]/}|d }|dr;|dd n|}|||d |dd|dpNd||v rTdndd q*t	j
|dddid dS )zISearch extensions available on GitHub (tagged with 'hf-extension' topic).z*https://api.github.com/search/repositoriesztopic:starsdescd   )qsortorderper_pageT)paramsfollow_redirectstimeoutc                 S   s   h | ]}|j qS r$   )r   )rv   mr$   r$   r.   	<setcomp>   s    z#extension_search.<locals>.<setcomp>itemsrg   hf-   N	full_namestargazers_countr   r!    yes)rg   r   r~   r!   rt   r   right)rx   
alignments)r   get_EXTENSIONS_GITHUB_TOPIC_EXTENSIONS_DOWNLOAD_TIMEOUTraise_for_statusr'   ry   
startswithappendr   rz   )responser-   rt   r{   r   rI   r   r$   r$   r.   extension_search   s,   

r   zremove | rmzhf extensions remove claudez8Extension name to remove (with or without `hf-` prefix).c                 C   sF   t | }t|}| std| dt| td| d dS )zRemove an installed extension.rH   rh   zRemoved extension ''.N)rl   rT   is_dirr	   rW   rX   r[   )rg   r   rJ   r$   r$   r.   extension_remove   s   
r   c                  C   s   t  } |  s
g S g }t|  D ]5}| r|jdsqz
|t	| W q t
yG } ztd|j d|  W Y d}~qd}~ww |S )zPReturn manifests for all validly-installed extensions, sorted by directory name.r   z'Failed to load manifest for extension '': N)EXTENSIONS_ROOT
expanduserr   sortediterdirrg   r   r   r   r/   	Exceptionloggerdebug)root_dir	manifestsrJ   er$   r$   r.   ry      s   ry   c                  C   sP   g } t  D ] }d|j d}|jd ur|j d| n|}| |j|f q| S )Nz[extension ] )ry   r   r!   r   r   )entriesr_   tag	help_textr$   r$   r.   "list_installed_extensions_for_help   s   
r   rj   known_commandsc                 C   s   | sd S | d }| drd S dd |D }||v rd S | dr'|dd  n|}|s-d S d }zt|}W n tyB   t|}Y nw |d u sK| sMd S t|t| dd  dS )	Nr   -c                 S   s$   h | ]}| d D ]}| q	qS )|)splitstrip)rv   cmdar$   r$   r.   r     s   $ z7dispatch_unknown_top_level_extension.<locals>.<setcomp>r   r   r   ri   )r   rm   r    _auto_install_official_extensionr&   rn   ro   )rj   r   command_name	all_knownr   r   r$   r$   r.   $dispatch_unknown_top_level_extension   s(   
r   r   c              	   C   s  t d|  }}zt| }W n
 ty   Y dS w | rdS z#t jd| d| dtd}|jdkr7W dS |  |	 d }W n
 tyL   Y dS w zt
d	|  d
| d| d W n
 tyh   Y dS w zt||| ||d}t|j W S  ty   tj|dd Y dS w )zKTry to auto-install huggingface/hf-<name>. Returns executable path or None.r   Nhttps://api.github.com/repos/rL   Tr   r   i  default_branch'z)' is an official Hugging Face extension (z). Install it?r   rI   r   rJ   rK   ignore_errors)DEFAULT_EXTENSION_OWNERrT   r   rU   r   r   r   status_coder   r'   r   confirmr   rY   r   r   r   rW   rX   )r   r   rI   rJ   r   rK   r_   r$   r$   r.   r     sF   
"
r   )r!   r   rI   rJ   rK   r!   c                 C   sz   z
t | |||d}W n ty   d}Y nw |dur$t| ||||d}n	t| ||||d}t| |||d|_|| |S )zLFetch, install (binary or Python), and save manifest for a GitHub extension.)r   rI   rK   r   N)r   rI   r   rJ   r   r   )r   rI   rK   candidate_description)_fetch_remote_binaryr   _install_binary_extension_install_python_extension_try_fetch_remote_descriptionr!   r<   )r   rI   r   rJ   rK   r!   r   r_   r$   r$   r.   rY   >  s"   



rY   c                 C   sD   t |}d|  d| d| d| }t j|dtd}|  |jS )N"https://raw.githubusercontent.com/rL   /refs/heads/Tr   )_get_executable_namer   r   r   r   content)r   rI   rK   r   r   raw_urlr   r$   r$   r.   r   [  s
   r   r   c                 C   sz   t |}|jddd || }|| tjdkrt|d t| ||  d| ||t|dt	t
jd|  d| d		S )
NTFr0   nti  rL   r   https://github.com/	r   r   r   r   r   r   r   r   r    )r   r7   write_bytesosrg   chmodr   r@   r   nowr   utc)r   rI   r   rJ   r   r   r   r$   r$   r.   r   c  s"   


r   c                 C   s  d|  d| d| d}|d }d}t  }z-z|d|  | r,tj|dd	 |jddd
 td}	t|}
|	rkt	j
|	dt|gdd |d|  |d|  t	j
|	dddt|
|gdtd n,tjddt| |d|  |d|  t	j
t|
ddddd|gdtd |d|  t|}t||}| std|  d| d| dt| ||  d| ||t| dttjd|  d| d	}d}|W W |stj|dd	 S S  ty     t	jy } ztdt d|  d| d|d }~w t	jy* } ztd |  d| d!|j d"|d }~w tyD } ztd#|  d| d$| |d }~ww |sPtj|dd	 w w )%Nr   rL   z/archive/refs/heads/z.zipvenvFz Creating virtual environment in Tr   r0   uv)checkzVirtual environment created in zInstalling package from piprC   z--python)r   r   )with_pipz-mz--disable-pip-version-checkz
--no-inputzPackage installed from zInstalled package from 'z/' does not expose the required console script 'r   r   r   zPip install timed out after zs for 'z$'. See pip output above for details.z$Failed to install pip package from 'z' (exit code z$). See pip output above for details.z%Failed to set up pip extension from 'r   ) r   statusupdaterU   rW   rX   r7   which_get_venv_python_path
subprocessrunr@   done_EXTENSIONS_PIP_INSTALL_TIMEOUTr   
EnvBuildercreater   #_get_venv_extension_executable_pathr&   r	   r   resolver   r   r   r   TimeoutExpiredr
   CalledProcessError
returncoder   )r   rI   r   rJ   rK   
source_urlvenv_dirrt   r   uv_pathvenv_pythonr   venv_executabler_   r   r$   r$   r.   r   ~  s   
	


r   r   c           
   	   C   s   z+t  jd|  d| d| dt dd}|  | }|d}t|tr*|W S W n	 ty4   Y nw z<t  jd|  d| d| ddd}|  |j	 D ]}|
 }|drn|d\}}}	|	
 
d	  W S qQW |S  ty{   Y |S w )
zTry to fetch project description either from:
    - manifest.json
    - pyproject.toml

    Only best effort, no error handling.
    r   rL   r   T)r   r!   z/pyproject.toml=z"')r   r   r%   r   r'   
isinstancer@   r   text
splitlinesr   r   	partition)
r   rI   rK   r   r   r-   r!   line_valuer$   r$   r.   r     s@   



	r   c                  C   s   t  } | jddd | S )NTr0   )r   r   r7   )r   r$   r$   r.   _get_extensions_root   s   r   c                 C   sF   t | | d}t  }|d|   }||jvr!td|  d|S )Noriginal_inputr   Invalid extension name 'r   )_validate_extension_short_namer   r   r1   r	   )r   	safe_nameroottargetr$   r$   r.   rT     s   

rT   c                 C   s^   z!t  jd|  d| dtd}|  | }|d |dfW S  ty.   td f Y S w )Nr   rL   Tr   r   r!   )r   r   r   r   r'   r   _EXTENSIONS_DEFAULT_BRANCH)r   rI   r   r-   r$   r$   r.   rV     s   rV   c                 C   s    d|  }t jdkr|d7 }|S )Nr   r   z.exer   rg   )r   rg   r$   r$   r.   r     s   

r   c                 C   s    t | }t|}t|j S N)rT   r   r/   r   r   r   )r   rJ   r_   r$   r$   r.   rm   $  s   
rm   r   c                 C   s"   t jdkr| d d S | d d S )Nr   Scriptsz
python.exebinr   r   )r   r$   r$   r.   r   *  s   
r   c                 C   s*   t |}tjdkr| d | S | d | S )Nr   r  r  )r   r   rg   )r   r   r   r$   r$   r.   r   0  s   
r   z^[A-Za-z0-9][A-Za-z0-9._-]*$r   c                   sx   |     s
tdt fdddD rtd| dd v s%d v r-td| dt s:td| d	 S )
NExtension name cannot be empty.c                 3   s    | ]}| v V  qd S r  r$   )rv   seprg   r$   r.   	<genexpr>>  s    z1_validate_extension_short_name.<locals>.<genexpr>)rL   \r   r   z..:z9'. Allowed characters: letters, digits, '.', '_' and '-'.)r   r	   any_ALLOWED_EXTENSION_NAME	fullmatch)r   r   r$   r  r.   r   :  s   

r   c                 C   s   d| v rt d| d}t|dkrt}|d }nt|dkr)t|r)|\}}nt d|  d|d	s>t d
| d|dd  }|sJt dt|| d |||fS )Nz://zEOnly GitHub repositories in `[OWNER/]hf-<name>` format are supported.rL   r   r   r3   z%Expected `[OWNER/]REPO` format, got 'r   r   z6Extension repository name must start with 'hf-', got 'r   z(Invalid extension repository name 'hf-'.r   )r	   r   lenr   allr   r   )r   partsr   rI   r   r$   r$   r.   rN   I  s    




rN   c                 C   s:   |   }|s
td|dr|dd  n|}t|| dS )Nr  r   r   r   )r   r	   r   r   )rg   	candidate
normalizedr$   r$   r.   rl   a  s
   rl   r   c              
   C   sj   zt t| g| W S  ty4 } ztjdks|jtjkr t dt| g| W  Y d }~S d }~ww )Nr   sh)r   callr@   OSErrorr   rg   errnoENOEXEC)r   rj   r   r$   r$   r.   rn   i  s   "rn   )F)r#   N)Q__doc__r  r'   r   rerW   r   r   dataclassesr   r   r   r   pathlibr   typingr   r   rp   huggingface_hub.errorsr	   r
   r   huggingface_hub.utilsr   r   
_cli_utilsr   _outputr   r   r   r%   EXTENSIONS_HELPextensions_clir   r   r   r   
get_loggerr=   r   r   rR   Contextr@   ArgumentboolOptionra   rs   r|   r   r   ro   ry   tupler   rP   intr   r   rY   bytesr   r   r   r   r   rT   rV   r   rm   r   r   compiler  r   rN   rl   rn   r$   r$   r$   r.   <module>   s,  


,


"	*


V
,"	
