o
    [+ iX                     @   s  d Z ddlm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	 ddl
mZ ddlmZm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 ddlm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% ddl&m'Z' ddl&m(Z( ddl)m*Z* ddlm+Z+m,Z,m-Z-m.Z.m/Z/m0Z0m1Z1m2Z2m3Z3m4Z4m5Z5 ddl6m7Z7 ddl8m8Z8 ddl9m:Z: e1dZ;g dZ<e4d Z=ddgZ>G dd  d e?Z@G d!d" d"ZAG d#d$ d$ZBd%d& ZCd'd( ZDde(jEde(jFd)d*e,eGe	eHe-f d+eGd,eGd-e,eGdf d.eeG d/eeG d0eeG fd1d2ZIdd3dde(jEdde(jJe(jFd4	d,eGd5e,eGe	e+eG e+e	 f d+eeG d/eeG d-e,eGdf d.eeG d6ee,e+eG eGf  d7ee,e+eG eGf  d8eKd0eeG fd9d:ZLd;d< ZMdS )=uh  
本文件实现了模型库hub接口封装

TODO: 
    当前脚本后续将移动至sdk目录下, 但用法将发生变化, 需和pm确认
    旧：
        from aistudio_sdk.hub import create_repo
        create_repo()
    新：
        from aistudio_sdk import hub
        hub.create_repo()

Authors: linyichong(linyichong@baidu.com)
Date:    2023/08/21
    )OptionalN)Path)	ErrorEnum)request_aistudio_hubrequest_aistudio_app_service)request_aistudio_git_file_infocommit_files)request_aistudio_git_file_typerequest_aistudio_git_files_type)"request_aistudio_git_upload_access)request_bos_upload)#request_aistudio_git_upload_pointer)"request_aistudio_git_upload_common request_single_git_upload_common)get_exist_file_old_sha)request_aistudio_repo_visible) request_aistudio_verify_lfs_file!request_single_git_upload_pointer)convert_to_dict_objectis_valid_hostcalculate_sha256)err_resp)extract_yaml_blockis_readme_mdget_file_sizeget_file_hashthread_executor)log)config)post_upload_statistic_async)ListUnionBinaryIOIterableCallable	GeneratorTypeVarDictAnyLiteralIterator)	dataclassfnmatch)contextmanagerT)create_repouploadfile_existsupload_folderupload_file)Zlfsnormalz.gitz.cachec                   @   s   e Zd ZdZdS )UploadFileExceptionu   
    上传文件异常
    N)__name__
__module____qualname____doc__ r;   r;   \/home/app/PaddleOCR-VL-test/.venv_paddleocr/lib/python3.10/site-packages/aistudio_sdk/hub.pyr6   E   s    r6   c                   @   s  e Zd ZdZdZdd Zdd Zdd Zed	d
 Z	dd Z
		d,deeeee ee f dedeeee ef  deeee ef  fddZdejdejddeeeeef dededeedf dee dee dee fddZddddejddejejdf
dedeeeee ee f dee dee deedf dee deeee ef  deeee ef  d edee d!efd"d#Zded$ed%ed&ededed'ed(ed)efd*d+ZdS )-Hubu   Hub类Zhubc                 C   s   t jddds:t jdt dd}| d}t j|r:t|d}|  t jd< W d   n1 s5w   Y  t | _	dS )	u   初始化函数，从本地磁盘加载AI Studio认证令牌。
        
        Args:
            无参数。
        
        Returns:
            无返回值。
        AISTUDIO_ACCESS_TOKEN defaultZAISTUDIO_CACHE_HOMEHOMEz/.cache/aistudio/.auth/tokenrN)
osgetenvpathexistsopenreadstripenvironUploadingCheckupload_checker)selfZ
cache_homeZtoken_file_pathfiler;   r;   r<   __init__O   s   
zHub.__init__c              
   K   s*  i }d|vrt tjjtjjS |dd}|dkrid|vr(t tjjtjjd S |d}|r3|dvr>t tjjtjjd	 S |d
krSd|vrMt tjjdS |d |d< |dkrhd|vrbt tjjdS |d |d< n|dkrxd|vrx|d|d< d|v rt|d tst tjjdS dD ]/}||v rt|| tst tjjd|   S || 	 ||< || st tjjd|   S qt
dsd|vrt tjjtjjS d|v rt|d tst tjjtjjS |d }d|v r|d\}}|	 }|	 }|r|st tjjdS ||d< n|	 |d< |dkrH|drdnd|d |dd|dd|dd |ddd!}	||	 ttd5i |}
nH|drPdnd|d |dd|dd|dd|dd |ddd"}	||	 td5i |}td#|  t|}
td$|
  d%|
v r|
d% dkrtd&|
  d'|
d( v rt tjj|
d( |
d% |
d) }|S t tjj|
d( |
d% |
d) }|S |dkr|
d* d+ |
d* d, |
d* d- dkrd.nd/|
d* d |
d* d d0}|S |
d* d1 |
d* d2 |
d* d, |
d* d |
d* d d3}|S )6u  
        创建一个repo仓库并返回创建成功后的信息。
        Params:
            repo_id (str): 仓库名称，格式为user_name/repo_name 或者 repo_name，必填。
            repo_type (str): 仓库类型，取值为app/model，分别为应用仓库和模型仓库。如果未指定，默认为model。
            app_name (str): 应用名称，如果repo_type为app，则必填。默认值为repo_id (如果不填，后端自动生成）。

            app_sdk (str): 应用SDK, 如果repo_type为app，则必填，可以填写 streamlit, gradio, static 三种
            version (str): streamlit 或 gradio 版本，必填
                * gradio版本支持"4.26.0", "4.0.0"
                * streamlit版本支持"1.33.0", "1.30.0"
            model_name (str): 模型名称，如果repo_type为model，则必填。默认值为repo_id。
            desc (str): 仓库描述，可选，默认为空。
            license (str): 仓库许可证，可选，默认为"Apache License 2.0"。
            private (bool): 是否私有仓库，可选，默认为False。
            token (str): 认证令牌，可选，默认为环境变量的值。
        Demo:
            创建应用仓库：
            create_repo(repo_id='app_repo_0425',
                        app_sdk='streamlit',
                        version="1.33.0"
                        desc='my app demo')
        Returns:
            dict: 仓库创建结果。
        repo_id	repo_typemodelappapp_namezshould provide param app_nameapp_sdk)	streamlitgradioZstaticz.app_sdk should be streamlit, gradio or static.rW   versionzstreamlit version needed.ZstreamlitVersionrX   zgradio version needed.ZgradioVersion
model_nameprivatezprivate should be bool type.)rQ   rZ   licensetokenzshould be str type: zshould not be empty: r>   r]   desc/zNuser_name or repo_name is empty. repo_id should be user_name/repo_name format.r      r?   r\   zApache License 2.0)repoTyperepoName	modelNamer^   r\   r]   )ra   rb   appNameZappTyper^   r\   r]   zcreate_repo resp: zcreate_repo resp dict: 	errorCodezcreate_repo failed: zrepo already createderrorMsglogIdresultrc   rb   ra   TF)rZ   rQ   r[   r^   r\   ZappIdrd   )Zapp_idrU   rQ   r^   r\   Nr;   )r   r   PARAMS_INVALIDcodemessageget
isinstanceboolstrrJ   rD   rE   ZTOKEN_IS_EMPTYsplitupdater   r   r   r   debugerrorZREPO_ALREADY_EXISTZAISTUDIO_CREATE_REPO_FAILED)rN   kwargsparamsrR   rV   keyZrepo_name_raw	user_name	repo_nameZmore_paramsrespZresp_rawresr;   r;   r<   r0   d   s   

















		









zHub.create_repoc                    sx  | dstd dS |d | di d}r! dr!d}r*|tjk r*dnd} fdd	} fd
d}g }|rC|| |rJ|| tjj ddddksX|  |sat	d dS d}	|D ]T}
z-td|
j
  |
 }|du rtd|
j
  d}	W  |	S t	d|
j
 d|  W qe ty } zt	d|
j
 d|  tt  W Y d}~qed}~ww |	S )u$  
        上传文件
        settings: 上传文件的配置信息
        settings = {
            'upload'[bool]: True or False
            'upload_href'[str]:  upload url
            'sts_token'[dict]: sts token
                {
                "bos_host":"",
                "bucket_name": "",
                "key":"",
                "access_key_id": "",
                "secret_access_key": "",
                "session_token": "",
                "expiration": ""
                }
        }
        file_path: 本地文件路径
        r1   z%file already exists, skip the upload.Tupload_href	sts_tokenFbos_hostc               
      s~   ddl m} m}m} z$| dddd}||d dd	}|W S  ty> } zt|d
}~ww )u/   
            使用sts上传文件
            r   )
sts_clientr4   upload_super_filer}   Zaccess_key_idZsecret_access_keyZsession_tokenZbucket_namerv   )ZbucketrO   rv   N)Zaistudio_sdk.utils.bos_sdkr~   r4   r   rl   	Exceptionr6   )r~   r4   r   clientrz   e)	file_pathr|   r;   r<   _uploading_using_sts  s   z2Hub._upload_lfs_file.<locals>._uploading_using_stsc               
      sP   zt  } d| v r| d tjjkr| W S W dS  ty' } zt|d}~ww )u0   
            使用http上传文件
            
error_codeTN)r   r   SUCCESSrj   r   r6   )rz   r   )r   r{   r;   r<   _uploading_using_http'  s   
z3Hub._upload_lfs_file.<locals>._uploading_using_httpZPERFER_STS_UPLOADtruer@   zno upload method available.zuploading file using zupload lfs file success. zupload lfs file failed. : N)rl   logginginfor   ZLFS_FILE_SIZE_LIMIT_PUTappendrD   rK   reversers   r7   r6   rr   	traceback
format_exc)rN   settingsr   	file_sizeZis_sts_validZis_http_validr   r   Z	functionsZupload_successfuncrz   r   r;   )r   r|   r{   r<   _upload_lfs_file   sL   




zHub._upload_lfs_filec              
   C   s   z5d tjdtjdtj}| r| d|  }t|}|jdkr3|	 }|d dkr0|d W S g W S W g S  t
yP } ztd	|  W Y d }~g S d }~ww )
N{}{}STUDIO_MODEL_API_URL_PREFIXr@   z?repoId=   re   r   rh   zget black list fail:)formatrD   rE   r   #STUDIO_MODEL_API_URL_PREFIX_DEFAULTZBLACK_LIST_URLrequestsrl   status_codejsonr   r   rs   )rQ   urlresponserC   r   r;   r;   r<   _get_suffix_forbiddenP  s(   


zHub._get_suffix_forbiddenc                 O   s  d}||d< ||d< dD ]0}||v r<t || tkr%ttjjtjj  S ||  ||< || s<ttjjtjj  S q|drF|d nd}|d }d|v rT|d nd}	|d }
d	|
vrgttjjtjjS |
	d	\}}
| }|
 }
|
rz|sttjjtjjS t
jd
tjd}t|sttjjdS t
jjddddkr|d d|v r|d ndd}ttdi |}d|v r|d dkrttjj|d |d |d }|S t|||
|||	}t|dkrdS dS )u   
        文件是否存在
        params:
            repo_id: 仓库id，格式为user_name/repo_name
            filename: 仓库中的文件路径
            revision: 分支名
            token: 认证令牌
        zparams not valid.rQ   filename)r   rQ   revisionr]   r   masterr]   r?   r_   STUDIO_GIT_HOSTr@   zhost not valid.ZSKIP_REPO_VISIBLE_CHECKfalser   )repoIdr]   re   r   rf   rg   FTNr;   )typero   r   r   ri   rj   rk   rJ   rl   rp   rD   rE   r   STUDIO_GIT_HOST_DEFAULTr   rK   r   r   ZAISTUDIO_NO_REPO_READ_AUTHr   r   )rN   rQ   r   argsrt   Zstr_params_not_validrv   r   r   r]   rx   rw   Z	call_hostru   ry   rz   Zinfo_resr;   r;   r<   r2   f  sj   

zHub.file_existsNfolder_path_or_filespath_in_repoallow_patternsignore_patternsc           	         s   d  d }t |trtj|d r|}ntdtj|r"|g}n| |d u rQ| j  t 	 
    sBtd  d fddt dD ni |D ]}tj|rk| j| |tj|< qUttj ||d}|r|d	 d	nd
fdd|D }|S )Nr   z0Uploading multiple folders is not supported now.zProvided path: 'z' is not a directoryc                    s$   i | ]}|  r|  |qS r;   )is_filerelative_toas_posix).0rF   )folder_pathr;   r<   
<dictcomp>  s    z.Hub._prepare_upload_folder.<locals>.<dictcomp>z**/*)r   r   r_   r?   c                    s    g | ]} | t | fqS r;   )ro   )r   relpath)prefixrelpath_to_abspathr;   r<   
<listcomp>  s    z.Hub._prepare_upload_folder.<locals>.<listcomp>)rm   listrD   rF   isfile
ValueErrorrM   check_folderr   
expanduserresolveis_dirsortedglob
check_filebasenamerL   filter_repo_objectskeysrJ   )	rN   r   r   r   r   Z
files_pathrF   Zfiltered_repo_objectsprepared_repo_objectsr;   )r   r   r   r<   _prepare_upload_folder  sB   


zHub._prepare_upload_folderr]   rR   commit_messager   path_or_fileobjrQ   r]   rR   r   r   c             
   C   s   |t jvrtd| dt j |stdt|ttfr0tjtj	|}|p.tj
|}n|s6td|dur<|nd| }t|tjrK| }| j|||||||dd dS )	z$
        upload single file
        Invalid repo type: , supported repos: z$Path or file object cannot be empty!z#Arg `path_in_repo` cannot be empty!NzAdd T)rQ   r   r   r]   rR   r   r   single)r   REPO_TYPE_SUPPORTr   rm   ro   r   rD   rF   abspathr   r   ioBufferedIOBaserI   r3   )rN   r   r   rQ   r]   rR   r   r   r;   r;   r<   r4     s"   

zHub.upload_filer?   Fr   max_workersr   c                    s  |t jvrtd| dt j du rtd|r|nd}|r#|nd}|du r,g }nt|tr4|g}|dur:|nd}|rD||fg}n	j||||d}tjdt jd	d	\}}|
 }|
 }|rh|sltd
g }|D ]	\}}|| qpt|dkrdS t|||i }|D ]
\}}| ||< qjjdd |D |d  t|	dd fdd}g }|||d}dd |D }t|dks|du rtd dS t|||d t|dkrtd |D ]\}}t| d|  qdS dS )r1   r   r   Nr>   zUpload folder to repo)r   r   r   r   r   r@   r_   -repo_name or user_name is empty,abort upload.r   c                 S   s   g | ]\}}|qS r;   r;   )r   _itemr;   r;   r<   r   M      z%Hub.upload_folder.<locals>.<listcomp>)file_path_listlfs_mapF)r   Zdisable_tqdmc                    s  | \}}t |dr|dkrdkrz^dtjdtjdtj}t|}|d}dd	i}tj	|||d
d}|j
dkrn| }	|	ddkrQtd|	d  n|	d}
td|
 d|  ||d|
 f W d S W n% ty } ztd|  ||d| f W Y d }~d S d }~ww t|j } r| v rtd| d ||df d S t|d}|d }|d }j||||||d
S )N)r   z	README.mdr   r   r   r@   )yamlr   zContent-Typezapplication/json)
   r   )r   headerstimeoutr   re   r   u   调用成功，logId:rg   rf   zcheck readme fail:z,skipzcheck readme failFile:z  forbidden! Skip.zfile type forbidden)file_path_or_objr   	file_hash)
rQ   sha256sizedatar]   r   file_path_in_repogit_hostis_lfslog_list)r   r   rD   rE   r   r   ZREADME_CHECK_URLr   r   postr   r   rl   r   rr   rs   r   r   r   r   suffixlowerr   _upload_and_gather_commit_info)Z	item_pairr   r   r   r   Zyaml_contentpayloadr   r   r   	error_msgr   r   Zhash_info_dr   r   Zblack_extensionsr   r   rQ   r   rN   r]   r;   r<   _upload_itemsS  sf   

z(Hub.upload_folder.<locals>._upload_items)r   c                 S   s   g | ]}|d ur|qS Nr;   r   r   r;   r;   r<   r         znothing to commit)r   rQ   r   r   Z
file_quadsr]   z&these files were skipped with reasons:r   )r   r   r   rD   rE   rm   ro   r   r   rp   rJ   r   lenr
   rM   check_normal_filesr   r   r   rs   r   print)rN   rQ   r   r   r   r]   rR   r   r   r   r   r   r   rw   rx   Zrepo_path_listnamer   Zlfs_local_path_mapZremote_pathZ
local_pathr   Z	skip_listZuploaded_item_rawZuploaded_item_listreasonr;   r   r<   r3   
  s   




7
zHub.upload_folderr   r   r   r   r   r   c       
      
   C   s  d|vrt d|d\}}| }| }|r|st d|	rzt|||||||}W n$ tyQ } zt| d|  |
|df W Y d }~d S d }~ww t	d|  d|v ry|d t
jjkryt| d|  |
|d	f d S |d
std| d|d d  d |||	|fS | |||}|std| d |
|df d S |drt|d|||}td|  d|v r|d t
jjkrtd| d |
|df d S |||	|fS t	d |tjkrtd| d |
|df d S |||	|fS )Nr_   z-repo_id should be user_name/repo_name format.r   u#    request upload_access fail,skip，zrequest upload_access failz,the request_aistudio_git_upload_access res: r   z- upload fail due to request git upload error:z+upload fail due to request git upload errorr1   zfile z
 with sha    z has already uploaded.zupload this lfs file u    failed. 文件上传终止z$upload lfs file failed,server error Zverify_hrefzverify lfs file res: zverify lfs file failed:.zverify lfs file failedz!Start uploading this common file.r   z+ is larger than 5MB for a common file. Failz!larger than 5MB for a common file)r   rp   rJ   r   r   r   rs   r   r   rr   r   r   rj   rl   r   r   r   r   ZCOMMON_FILE_SIZE_LIMIT)rN   rQ   r   r   r   r]   r   r   r   r   r   rw   rx   Zpre_resr   Z
upload_resZ
verify_resr;   r;   r<   r     sZ   

 

z"Hub._upload_and_gather_commit_info)NN)r7   r8   r9   r:   ZOBJECT_NAMErP   r0   r   staticmethodr   r2   r!   ro   r   r    r   r   r   REPO_TYPE_MODELDEFAULT_REPOSITORY_REVISIONbytesr"   r4   DEFAULT_MAX_WORKERSintrn   r3   r   r;   r;   r;   r<   r=   K   s     X
G
=
	
-
	

 	
r=   c                   @   s   e Zd ZdZejejejejej	fde
de
de
de
de
f
ddZd	d
 Zdeeef fddZdeeeef  defddZedddddee deeee ef  deeee ef  deeegef  fddZedefddZdS )rL   z
    check class
    max_file_countmax_file_count_in_dirmax_file_sizesize_threshold_to_enforce_lfsnormal_file_size_total_limitc                 C   s"   || _ || _|| _|| _|| _d S r   )r   r   r   r   r   )rN   r   r   r   r   r   r;   r;   r<   rP     s
   
zUploadingCheck.__init__c                 C   sl   t |ttfrtj|std| dt|}|| jkr4t	
d| jd  dt|d d d dS dS )	z
        check size
        File z does not existzFile exceeds size limit:    @	 GB, got     GBN)rm   ro   r   rD   rF   rG   r   r   r   r   warnround)rN   r   r   r;   r;   r<   r     s   
zUploadingCheck.check_filer   c                 C   s   d}d}t |trt|}| D ]Y}| r<|d7 }t|}|| jkr;td| d| jd  dt	|d d d q|
 rj|d7 }| |\}}|| | jkrbtd	| d
||  d| j ||7 }||7 }q|| jkr{td| d| j ||fS )
        check
        r   r`   r  z exceeds size limit: r  r  r  r  z
Directory z
 contains z items and exceeds limit: zTotal file count z and exceeds limit: )rm   ro   r   iterdirr   r   r   r   r  r  r   r   r   r   r   )rN   r   Z
file_countZ	dir_countr   Z	item_sizeZsub_file_countZsub_dir_countr;   r;   r<   r     s4   



zUploadingCheck.check_folderr   r   c                    sR    fdd|D }t dd |D }|| jkr'td|d  d| jd  ddS )	r  c                    s   g | ]} | s|qS r;   r;   r   r   r;   r<   r   .  r   z5UploadingCheck.check_normal_files.<locals>.<listcomp>c                 S   s   g | ]}t |qS r;   )r   r   r;   r;   r<   r   /  r   zTotal size of non-lfs files i   zMB and exceeds limit: MBN)sumr   r   )rN   r   r   Znormal_file_list
total_sizer;   r
  r<   r   )  s   

z!UploadingCheck.check_normal_filesN)r   r   rv   itemsr   r   rv   c                #   s    |r|nd}|r|nd}t |tr|g}t |tr|g}|dur(dd |D }|dur3dd |D }|du r@dtfdd}|}| D ])}|| |durXt fdd	|D sXqB|durht fd
d	|D rhqB|V  qBdS )a  Filter repo objects based on an allowlist and a denylist.

        Input must be a list of paths (`str` or `Path`) or a list of arbitrary objects.
        In the later case, `key` must be provided and specifies a function of one argument
        that is used to extract a path from each element in iterable.

        Patterns are Unix shell-style wildcards which are NOT regular expressions. See
        https://docs.python.org/3/library/fnmatch.html for more details.

        Args:
            items (`Iterable`):
                List of items to filter.
            allow_patterns (`str` or `List[str]`, *optional*):
                Patterns constituting the allowlist. If provided, item paths must match at
                least one pattern from the allowlist.
            ignore_patterns (`str` or `List[str]`, *optional*):
                Patterns constituting the denylist. If provided, item paths must not match
                any patterns from the denylist.
            key (`Callable[[T], str]`, *optional*):
                Single-argument function to extract a path from each item. If not provided,
                the `items` must already be `str` or `Path`.

        Returns:
            Filtered list of objects, as a generator.

        Raises:
            :class:`ValueError`:
                If `key` is not provided and items are not `str` or `Path`.

        Example usage with paths:
        ```python
        >>> # Filter only PDFs that are not hidden.
        >>> list(UploadingCheck.filter_repo_objects(
        ...     ["aaa.PDF", "bbb.jpg", ".ccc.pdf", ".ddd.png"],
        ...     allow_patterns=["*.pdf"],
        ...     ignore_patterns=[".*"],
        ... ))
        ["aaa.pdf"]
        ```
        Nc                 S      g | ]}t |qS r;   rL   _add_wildcard_to_directoriesr   pr;   r;   r<   r   p      z6UploadingCheck.filter_repo_objects.<locals>.<listcomp>c                 S   r  r;   r  r  r;   r;   r<   r   u  r  r   c                 S   s0   t | tr| S t | trt| S td|  d)Nz9Please provide `key` argument in `filter_repo_objects`: `z` is not a string.)rm   ro   r   r   )r   r;   r;   r<   	_identity|  s   


z5UploadingCheck.filter_repo_objects.<locals>._identityc                 3       | ]}t  |V  qd S r   r,   r   rC   rF   r;   r<   	<genexpr>      

z5UploadingCheck.filter_repo_objects.<locals>.<genexpr>c                 3   r  r   r,   r  r  r;   r<   r    r  )rm   ro   r/   any)r  r   r   rv   r  r   r;   r  r<   r   5  s<   1

	z"UploadingCheck.filter_repo_objectspatternc                 C   s   | d dkr
| d S | S )Nr_   *r;   )r  r;   r;   r<   r    s   z+UploadingCheck._add_wildcard_to_directories)r7   r8   r9   r:   r   ZUPLOAD_MAX_FILE_COUNTZUPLOAD_MAX_FILE_COUNT_IN_DIRZUPLOAD_MAX_FILE_SIZEZ$UPLOAD_SIZE_THRESHOLD_TO_ENFORCE_LFSZ#UPLOAD_NORMAL_FILE_SIZE_TOTAL_LIMITr   rP   r   r!   ro   r   r   r    dictr   r   r#   r/   r   r$   r   r  r;   r;   r;   r<   rL     sH    
!`rL   c                  K   s   t  jdi | S )u   
    创建
    Nr;   )r=   r0   rt   r;   r;   r<   r0     s   r0   c                  K   s   t d dS )   
    上传
    z>This function is not supported.Please use upload_file instead.N)r   rs   r   r;   r;   r<   r1     s   
r1   r   r   r   rQ   r]   rR   r   r   c              	   C   s   t  j| ||||||dS )z
    single file
    r   r   rQ   r]   rR   r   r   )r=   r4   r"  r;   r;   r<   r4     s   r4   r?   )	r   r   r   r]   rR   r   r   r   r   r   r   r   r   c        
   
      C   s   t  | |||||||||	
S )r!  )r=   r3   )
rQ   r   r   r   r]   rR   r   r   r   r   r;   r;   r<   r3     s   r3   c                 O   s   t  j| |g|R i |S )u(   
    检查云端文件存在与否
    )r=   r2   )rQ   r   r   rt   r;   r;   r<   r2     s   r2   )Nr:   typingr   r   rD   r   r   r   pathlibr   Zaistudio_sdk.constant.err_coder   Zaistudio_sdk.requests.hubr   r   r   r   r	   r
   r   r   r   r   r   r   r   r   r   Zaistudio_sdk.utils.utilr   r   r   r   r   r   r   r   r   Zaistudio_sdkr   r   Zaistudio_sdk.dotr   r    r!   r"   r#   r$   r%   r&   r'   r(   r)   r*   dataclassesr+   r-   
contextlibr.   r/   __all__Z
UploadModeZFORBIDDEN_FOLDERSr   r6   r=   rL   r0   r1   r   r   ro   r   r4   r   r   r3   r2   r;   r;   r;   r<   <module>   s   4     " 5


	

