
    g                         d Z ddlZddlZddlZddlZddlmZ ddlmZm	Z	m
Z
 ddlmZ ddlmZ ddlmZmZmZ dd	lmZ  ej*                  e      Z G d
 de      Z G d d      ZdefdZde
e   fdZ G d d      Zy)a  
Implementation of a custom transfer agent for the transfer type "multipart" for
git-lfs.

Inspired by:
github.com/cbartz/git-lfs-swift-transfer-agent/blob/master/git_lfs_swift_transfer.py

Spec is: github.com/git-lfs/git-lfs/blob/master/docs/custom-transfers.md


To launch debugger while developing:

``` [lfs "customtransfer.multipart"]
path = /path/to/huggingface_hub/.env/bin/python args = -m debugpy --listen 5678
--wait-for-client
/path/to/huggingface_hub/src/huggingface_hub/commands/huggingface_cli.py
lfs-multipart-upload ```    N)_SubParsersAction)DictListOptional)BaseHuggingfaceCLICommand)LFS_MULTIPART_UPLOAD_COMMAND   )get_sessionhf_raise_for_statuslogging)SliceFileObjc                   &    e Zd ZdZedefd       Zy)LfsCommandsu  
    Implementation of a custom transfer agent for the transfer type "multipart"
    for git-lfs. This lets users upload large files >5GB 🔥. Spec for LFS custom
    transfer agent is:
    https://github.com/git-lfs/git-lfs/blob/master/docs/custom-transfers.md

    This introduces two commands to the CLI:

    1. $ huggingface-cli lfs-enable-largefiles

    This should be executed once for each model repo that contains a model file
    >5GB. It's documented in the error message you get if you just try to git
    push a 5GB file without having enabled it before.

    2. $ huggingface-cli lfs-multipart-upload

    This command is called by lfs directly and is not meant to be called by the
    user.
    parserc                     | j                  dd      }|j                  dt        d       |j                  d        | j                  t        d	
      }|j                  d        y )Nzlfs-enable-largefilesz:Configure your repository to enable upload of files > 5GB.)helppathz/Local path to repository you want to configure.)typer   c                     t        |       S N)LfsEnableCommandargss    Q/var/www/openai/venv/lib/python3.12/site-packages/huggingface_hub/commands/lfs.py<lambda>z1LfsCommands.register_subcommand.<locals>.<lambda>?   
    5Ed5K    )funcF)add_helpc                     t        |       S r   )LfsUploadCommandr   s    r   r   z1LfsCommands.register_subcommand.<locals>.<lambda>C   r   r   )
add_parseradd_argumentstrset_defaultsr   )r   enable_parserupload_parsers      r   register_subcommandzLfsCommands.register_subcommand9   sr    ))#*f * 
 	""6:k"l""(K"L ))*FQV)W""(K"Lr   N)__name__
__module____qualname____doc__staticmethodr   r(    r   r   r   r   $   s&    ( 	M$5 	M 	Mr   r   c                       e Zd Zd Zd Zy)r   c                     || _         y r   r   selfr   s     r   __init__zLfsEnableCommand.__init__G   	    	r   c                    t         j                  j                  | j                  j                        }t         j                  j	                  |      st        d       t        d       t        j                  dj                         d|       t        j                  dt         j                         d|       t        d       y )Nz)This does not look like a valid git repo.   z<git config lfs.customtransfer.multipart.path huggingface-cliT)checkcwdz-git config lfs.customtransfer.multipart.args z Local repo set up for largefiles)osr   abspathr   isdirprintexit
subprocessrunsplitr   )r2   
local_paths     r   r?   zLfsEnableCommand.runJ   s    WW__TYY^^4
ww}}Z(=>GJPPR	

 	;<X;YZ``b	

 	01r   Nr)   r*   r+   r3   r?   r.   r   r   r   r   F   s    2r   r   msgc                     t        j                  |       dz   }t        j                  j	                  |       t        j                  j                          y)z-Write out the message in Line delimited JSON.
N)jsondumpssysstdoutwriteflush)rC   msg_strs     r   	write_msgrM   \   s6    jjo$GJJWJJr   returnc                  H   t        j                  t        j                  j	                         j                               } d| j                  d      | j                  d      fv ry| j                  d      dvr*t        j                  d       t        j                  d       | S )z$Read Line delimited JSON from stdin.	terminater   eventN)downloaduploadzReceived unexpected messager6   )
rF   loadsrH   stdinreadlinestripgetloggercriticalr=   )rC   s    r   read_msgr[   c   sv    
**SYY'')//1
2Cswwv(899
www5556Jr   c                       e Zd ZddZddZy)r!   Nc                     || _         y r   r   r1   s     r   r3   zLfsUploadCommand.__init__s   r4   r   c           
      2   t        j                  t        j                  j	                         j                               }|j                  d      dk(  r|j                  d      dk(  s%t        ddddi       t        j                  d	       t        i        	 t               }|t        j                  d
       |d   }|d   }|d   d   }|d   d   }t        |j                  d            }t        |j                               }t        d|d	d
d       g }	t        |d      5 }
t        |      D ]  \  }}t!        |
||z  |      5 }t#               j%                  ||      }t'        |       |	j)                  |j*                  j                  d      |d	z   d       t        d||d	z   |z  |d       d d d         	 d d d        t#               j-                  |||	d      }t'        |       t        d|d       h# 1 sw Y   xY w# 1 sw Y   NxY w)NrQ   init	operationrS   error    zWrong lfs init operation)codemessager6   r   oidr   actionhrefheader
chunk_sizeprogress)rQ   re   
bytesSoFarbytesSinceLastrb)	seek_from
read_limit)dataetag)rq   
partNumber)re   parts)rF   complete)rQ   re   )rF   rT   rH   rU   rV   rW   rX   rM   r=   r[   intpoplistvaluesopen	enumerater   r
   putr   appendheaderspost)r2   init_msgrC   re   filepathcompletion_urlrh   ri   presigned_urlsrs   fileipresigned_urlrp   rs                  r   r?   zLfsUploadCommand.runv   s    ::cii00288:;W%/HLL4MQY4Yw8R STUHHQK 	" *C{
 e*C6{H ]62N]8,FVZZ56J(,V]]_(=N
 '"#&'	 Eh%(1.(A$A}%"#j.#- 'M--m$-G+A.()		f(=./!e ")3'*/01u
.B2<	  )B &6 """ # A  "
378C >  &%s%   %#HA-H5
HH
HH)rN   NrB   r.   r   r   r!   r!   r   s    R9r   r!   )r,   rF   r9   r>   rH   argparser   typingr   r   r   huggingface_hub.commandsr   huggingface_hub.lfsr   utilsr
   r   r   
utils._lfsr   
get_loggerr)   rY   r   r   rM   r[   r!   r.   r   r   <module>r      s   $  	  
 & ' ' > < = = % 
		H	%M+ MD2 2,4 (4. V9 V9r   