o
    eM                     @  sL  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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Zd dlZd dlmZ d dlmZmZ d dlZd dlmZ d d	lmZ erhd d
lmZ ed G dd de	Z e G dd de Z!e G dd de Z"e G dd de Z#G dd de#Z$G dd dZ%dS )    )annotationsN)ABCabstractmethod)OrderedDict)Path)TYPE_CHECKINGAny)utils)documentset_documentation_group)warn_deprecation)IOComponentZflaggingc                   @  s2   e Zd ZdZedddZe			ddddZd	S )FlaggingCallbackz[
    An abstract class for defining the methods that any FlaggingCallback should have.
    
componentslist[IOComponent]flagging_dirstrc                 C     dS )a  
        This method should be overridden and ensure that everything is set up correctly for flag().
        This method gets called once at the beginning of the Interface.launch() method.
        Parameters:
        components: Set of components that will provide flagged data.
        flagging_dir: A string, typically containing the path to the directory where the flagging file should be storied (provided as an argument to Interface.__init__()).
        N selfr   r   r   r   ?D:\Projects\ConvertPro\env\Lib\site-packages\gradio/flagging.pysetup"   s   	zFlaggingCallback.setup N	flag_data	list[Any]flag_optionusername
str | Nonereturnintc                 C  r   )a  
        This method should be overridden by the FlaggingCallback subclass and may contain optional additional arguments.
        This gets called every time the <flag> button is pressed.
        Parameters:
        interface: The Interface object that is being used to launch the flagging interface.
        flag_data: The data to be flagged.
        flag_option (optional): In the case that flagging_options are provided, the flag option that is being used.
        username (optional): The username of the user that is flagging the data, if logged in.
        Returns:
        (int) The total number of samples that have been flagged.
        Nr   )r   r   r   r   r   r   r   flag-   s   zFlaggingCallback.flagr   r   r   r   r   Nr   r   r   r   r   r   r   r    )__name__
__module____qualname____doc__r   r   r!   r   r   r   r   r      s    
r   c                   @  2   e Zd ZdZdd Zddd	Z	
	ddddZdS )SimpleCSVLoggera  
    A simplified implementation of the FlaggingCallback abstract class
    provided for illustrative purposes.  Each flagged sample (both the input and output data)
    is logged to a CSV file on the machine running the gradio app.
    Example:
        import gradio as gr
        def image_classifier(inp):
            return {'cat': 0.3, 'dog': 0.7}
        demo = gr.Interface(fn=image_classifier, inputs="image", outputs="label",
                            flagging_callback=SimpleCSVLogger())
    c                 C     d S Nr   r   r   r   r   __init__P      zSimpleCSVLogger.__init__r   r   r   
str | Pathc                 C     || _ || _tj|dd d S NT)exist_okr   r   osmakedirsr   r   r   r   r   S   s   zSimpleCSVLogger.setupr   Nr   r   r   r   r   r   r   r    c                 C  s   | j }t|d }g }t| j|D ]\}}t|t|jpd }	||||	d  qt	|ddd}
t
|
}|t| W d    n1 sKw   Y  t	|}
ttt
|
d }W d    |S 1 skw   Y  |S )Nlog.csvr   a)newline   )r   r   zipr   client_utils!strip_invalid_filename_characterslabelappenddeserializeopencsvwriterwriterowr	   sanitize_list_for_csvlenlistreader)r   r   r   r   r   log_filepathcsv_data	componentsamplesave_dircsvfilerC   
line_countr   r   r   r!   X   s4   


zSimpleCSVLogger.flagr   r   r   r0   r#   r$   r%   r&   r'   r(   r.   r   r!   r   r   r   r   r*   B   s    
r*   c                   @  r)   )	CSVLoggera  
    The default implementation of the FlaggingCallback abstract class. Each flagged
    sample (both the input and output data) is logged to a CSV file with headers on the machine running the gradio app.
    Example:
        import gradio as gr
        def image_classifier(inp):
            return {'cat': 0.3, 'dog': 0.7}
        demo = gr.Interface(fn=image_classifier, inputs="image", outputs="label",
                            flagging_callback=CSVLogger())
    Guides: using-flagging
    c                 C  r+   r,   r   r-   r   r   r   r.      r/   zCSVLogger.__init__r   r   r   r0   c                 C  r1   r2   r4   r   r   r   r   r      s   zCSVLogger.setupr   Nr   r   r   r   r   r   r   r    c                 C  s  | j }t|d }t|  }dd t| jD g d }g }tt| j|D ]5\}	\}
}t|tt|
dd p=d|	  }t	
|rM|t| q(||d urZ|
j||dnd q(|| ||d urk|nd |ttj  t|d	dd
d}t|}|r|t	| |t	| W d    n1 sw   Y  t|d
d}ttt|d }W d    |S 1 sw   Y  |S )Nr7   c                 S  s&   g | ]\}}t |d dpd| qS )r>   N
component )getattr).0idxrK   r   r   r   
<listcomp>   s    z"CSVLogger.flag.<locals>.<listcomp>)r!   r   	timestampr>   rS   )rM   r   r8   utf-8r9   encodingr[   r:   )r   r   exists	enumerater   r;   r<   r=   rT   r	   Z	is_updater?   r   r@   datetimenowrA   rB   rC   rD   rE   rF   rG   rH   )r   r   r   r   r   rI   is_newheadersrJ   rV   rK   rL   rM   rN   rC   rO   r   r   r   r!      sN   	



zCSVLogger.flagrP   r#   r$   rQ   r   r   r   r   rR   w   s    
rR   c                   @  s|   e Zd ZdZ					d1d2ddZd3ddZ		d4d5ddZ		d6d7d$d%Zed8d)d*Z	ed9d+d,Z
		d6d:d/d0ZdS );HuggingFaceDatasetSavera  
    A callback that saves each flagged sample (both the input and output data) to a HuggingFace dataset.

    Example:
        import gradio as gr
        hf_writer = gr.HuggingFaceDatasetSaver(HF_API_TOKEN, "image-classification-mistakes")
        def image_classifier(inp):
            return {'cat': 0.3, 'dog': 0.7}
        demo = gr.Interface(fn=image_classifier, inputs="image", outputs="label",
                            allow_flagging="manual", flagging_callback=hf_writer)
    Guides: using-flagging
    NFdataset_info.jsonThf_tokenr   dataset_nameorganizationr   privateboolinfo_filenameseparate_dirsverbosec                 C  s2   |durt d || _|| _|| _|| _|| _dS )a;  
        Parameters:
            hf_token: The HuggingFace token to use to create (and write the flagged sample to) the HuggingFace dataset (defaults to the registered one).
            dataset_name: The repo_id of the dataset to save the data to, e.g. "image-classifier-1" or "username/image-classifier-1".
            organization: Deprecated argument. Please pass a full dataset id (e.g. 'username/dataset_name') to `dataset_name` instead.
            private: Whether the dataset should be private (defaults to False).
            info_filename: The name of the file to save the dataset info (defaults to "dataset_infos.json").
            separate_dirs: If True, each flagged item will be saved in a separate directory. This makes the flagging more robust to concurrent editing, but may be less convenient to use.
        NzParameter `organization` is not used anymore. Please pass a full dataset id (e.g. 'username/dataset_name') to `dataset_name` instead.)r   re   
dataset_iddataset_privaterj   rk   )r   re   rf   rg   rh   rj   rk   rl   r   r   r   r.      s   
z HuggingFaceDatasetSaver.__init__r   r   r   c              	   C  s   t j| j| j| jdddj| _| jrdnd}t j| jdddd|d	gd
gid| jd || _t	|
 | jdd  | _| jjddd | j| j | _| jg}| jsY|d |D ]}zt j| jd|| j| jd W q[ t jjyw   Y q[w dS )z
        Params:
        flagging_dir (str): local directory where the dataset is cloned,
        updated, and pushed from.
        datasetT)repo_idtokenrh   	repo_typer3   z
**/*.jsonldata.csvZconfigsdefaulttrain)splitpath)Zconfig_nameZ
data_files)rp   rr   metadata	overwriterq   /parentsr3   )rp   rr   filenameZ	local_dirrq   N)huggingface_hubZcreate_reporm   re   rn   rp   rk   Zmetadata_updater   r   absoluterv   dataset_dirmkdirrj   
infos_filer?   Zhf_hub_downloadr	   ZEntryNotFoundError)r   r   r   	path_globZremote_filesr~   r   r   r   r      sV   


zHuggingFaceDatasetSaver.setupr   r   r   r   r   r   r    c                 C  sV   | j rtt }| j| }|d }|}n	| j}|d }d }| j||||||p(ddS )Nzmetadata.jsonlrs   r   )	data_filecomponents_dirpath_in_repor   r   r   )rk   r   uuiduuid4r   _flag_in_dir)r   r   r   r   	unique_idr   r   r   r   r   r   r!   %  s    
zHuggingFaceDatasetSaver.flagr   r   r   r   c              
   C  sX  |  ||||\}}tt| jd ) | j s6| jtdd|ii t	j
| jd| j| jj| jd W d    n1 s@w   Y  t| }	| jst|d & | j||	|d}
t|
}t	j| jdd| |d|| jd	 W d    |
S 1 s~w   Y  |
S | j||	|d}td
d | j D }
t	j| jdd| |d|| jd	 |
S )Nz.lockZflaggedfeaturesro   )rp   rr   rq   r   Zpath_or_fileobj)rb   rowzFlagged sample #z*.lock)rp   rr   Zcommit_messager   ignore_patternsZfolder_pathrq   c                 S  s   g | ]}|  r|qS r   )is_dir)rU   rw   r   r   r   rW   o  s    z8HuggingFaceDatasetSaver._flag_in_dir.<locals>.<listcomp>)_deserialize_componentsfilelockZFileLockr   r   r]   
write_textjsondumpsr   Zupload_filerm   re   namerG   keysrk   _save_as_csvZupload_folder_save_as_jsonlrF   r   iterdir)r   r   r   r   r   r   r   r   r   rb   Z	sample_nbZsample_namer   r   r   r   @  sb   



z$HuggingFaceDatasetSaver._flag_in_dirrb   	list[str]r   c                 C  s   |    }| jdddd}t|}|r|t| |t| W d   n1 s/w   Y  | jdd}tdd t|D d	 W  d   S 1 sSw   Y  dS )
z9Save data as CSV and return the sample name (row number).r8   r   rY   rZ   Nr\   c                 s  s    | ]}d V  qdS )r:   Nr   )rU   _r   r   r   	<genexpr>  s    z7HuggingFaceDatasetSaver._save_as_csv.<locals>.<genexpr>r:   )	r]   rA   rB   rC   rD   r	   rE   sumrH   )r   rb   r   ra   rN   rC   r   r   r   r   }  s   


$z$HuggingFaceDatasetSaver._save_as_csvc                 C  s`   t j| jddd t| d}ttt||| W d   | jjS 1 s'w   Y  | jjS )z5Save data as JSONL and return the sample name (uuid).Tr|   wN)	r   r   parentrA   r   dumpdictr;   r   )r   rb   r   fr   r   r   r     s   
z&HuggingFaceDatasetSaver._save_as_jsonldata_dir tuple[dict[Any, Any], list[Any]]c                 C  s  t jdt jdi}t }g }t| j|D ]\}}	|jpd}
|t|
 }|	|	|d}ddd||
< zt
| s:J |tt
|| j W n tttfyc   |du rXdnt|}|| Y nw t|t|r| D ]\}}t||rd|i||
d	 <  nqo|rtt
|| jd
d}|tj| j|dd q|d qddd|d< ddd|d< || || ||fS )zDeserialize components and return the corresponding row for the flagged sample.

        Images/audio are saved to disk as individual files.
        AudioImager   NstringValue)Zdtype_typer   z file\rz   ro   )rp   r~   rr   r!   r   )grr   r   r   r;   r   r>   r<   r=   r@   r   r]   r?   r   relative_tor   AssertionError	TypeError
ValueError
isinstancetupleitemsreplacer   Z
hf_hub_urlrm   )r   r   r   r   r   Zfile_preview_typesr   r   rK   rL   r>   rM   ZdeserializedZ
_componentr   r   r   r   r   r     sV   




z/HuggingFaceDatasetSaver._deserialize_components)NFrd   FT)re   r   rf   r   rg   r   rh   ri   rj   r   rk   ri   rl   ri   r"   r#   r$   )r   r   )r   r   r   r   r   r   r   r   r   r   r   r   r   r    )r   r   rb   r   r   r   r   r    )r   r   rb   r   r   r   r   r   )
r   r   r   r   r   r   r   r   r   r   )r%   r&   r'   r(   r.   r   r!   r   staticmethodr   r   r   r   r   r   r   rc      s,    
;!=rc   c                      s(   e Zd Z				dd fddZ  ZS )HuggingFaceDatasetJSONSaverNFrd   Tre   r   rf   rg   r   rh   ri   rj   rl   c                   s$   t d t j|||||dd d S )NzCallback `HuggingFaceDatasetJSONSaver` is deprecated in favor of using `HuggingFaceDatasetSaver` and passing `separate_dirs=True` as parameter.T)re   rf   rg   rh   rj   rk   )r   superr.   )r   re   rf   rg   rh   rj   rl   	__class__r   r   r.     s   	
z$HuggingFaceDatasetJSONSaver.__init__)NFrd   T)re   r   rf   r   rg   r   rh   ri   rj   r   rl   ri   )r%   r&   r'   r.   __classcell__r   r   r   r   r     s    r   c                   @  s0   e Zd ZdZ	ddd
dZdddZdd ZdS )
FlagMethodz
    Helper class that contains the flagging options and calls the flagging method. Also
    provides visual feedback to the user when flag is clicked.
    Tflagging_callbackr   r>   r   valuevisual_feedbackri   c                 C  s"   || _ || _|| _d| _|| _d S )NFlag)r   r>   r   r%   r   )r   r   r>   r   r   r   r   r   r.     s
   
zFlagMethod.__init__request
gr.Requestc              
   G  s   z| j jt|| j|jd W n# ty2 } ztd|  | jr(W Y d }~dS W Y d }~nd }~ww | js8d S t	d | 
 S )N)r   r   zError while flagging: zError!g?)r   r!   rG   r   r   	Exceptionprintr   timesleepreset)r   r   r   er   r   r   __call__  s   

zFlagMethod.__call__c                 C  s   t jj| jddS )NT)r   interactive)r   ZButtonupdater>   r-   r   r   r   r     s   zFlagMethod.resetN)T)r   r   r>   r   r   r   r   ri   )r   r   )r%   r&   r'   r(   r.   r   r   r   r   r   r   r     s    

r   )&
__future__r   rB   r_   r   r5   r   r   abcr   r   collectionsr   pathlibr   typingr   r   r   r   Zgradio_clientr	   r<   Zgradio_client.documentationr
   r   Zgradior   Zgradio.deprecationr   Zgradio.componentsr   r   r*   rR   rc   r   r   r   r   r   r   <module>   s@    %4I  