a
    d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rd 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                   @  s>   e Zd ZdZedddddZedd	dd
ddddZdS )FlaggingCallbackz[
    An abstract class for defining the methods that any FlaggingCallback should have.
    list[IOComponent]str
componentsflagging_dirc                 C  s   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   X/var/www/html/stable-diffusion-webui/venv/lib/python3.9/site-packages/gradio/flagging.pysetup"   s    	zFlaggingCallback.setup N	list[Any]
str | Noneint	flag_dataflag_optionusernamereturnc                 C  s   dS )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   N)__name__
__module____qualname____doc__r   r   r"   r   r   r   r   r      s   
  r   c                   @  s>   e Zd ZdZdd ZdddddZdddd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  s   d S Nr   r   r   r   r   __init__P   s    zSimpleCSVLogger.__init__r   
str | Pathr   c                 C  s   || _ || _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   c                 C  s   | j }t|d }g }t| j|D ]4\}}t|t|jp<d }	||||	d  q"t	|ddd*}
t
|
}|t| W d    n1 s0    Y  t	|&}
ttt
|
d }W d    n1 s0    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csvfiler=   
line_countr   r   r   r"   X   s,    
.
4zSimpleCSVLogger.flag)r   Nr#   r$   r%   r&   r*   r   r"   r   r   r   r   r'   B   s     r'   c                   @  s>   e Zd ZdZdd ZdddddZddddddddZd
S )	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  s   d S r(   r   r)   r   r   r   r*      s    zCSVLogger.__init__r   r+   r   c                 C  s   || _ || _tj|dd d S r,   r.   r   r   r   r   r      s    zCSVLogger.setupr   Nr   r   r   r   r   c                 C  s  | j }t|d }t|  }dd t| jD g d }g }tt| j|D ]j\}	\}
}t|tt|
dd pzd|	  }t	
|r|t| qP||d ur|
j||dnd qP|| ||d ur|nd |ttj  t|d	dd
d@}t|}|r"|t	| |t	| W d    n1 sH0    Y  t|d
d&}ttt|d }W d    n1 s0    Y  |S )Nr1   c                 S  s&   g | ]\}}t |d dp d| qS )r8   N
component )getattr).0idxrE   r   r   r   
<listcomp>   s   z"CSVLogger.flag.<locals>.<listcomp>)r"   r    	timestampr8   rL   )rG   r   r2   utf-8r3   encodingrT   r4   )r   r   exists	enumerater   r5   r6   r7   rM   r	   Z	is_updater9   r   r:   datetimenowr;   r<   r=   r>   r?   r@   rA   rB   )r   r   r   r    r   rC   is_newheadersrD   rO   rE   rF   rG   rH   r=   rI   r   r   r   r"      sF    	


06zCSVLogger.flag)r   NrJ   r   r   r   r   rK   w   s     rK   c                	   @  s   e Zd ZdZd$dddddddd	d
dZdddddZd%dddddddZd&ddddddddddZedddddddZ	edddddddZ
d'ddddd d!d"d#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.jsonTr   r   bool)hf_tokendataset_nameorganizationprivate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   r_   
dataset_iddataset_privaterc   rd   )r   r_   r`   ra   rb   rc   rd   re   r   r   r   r*      s    z HuggingFaceDatasetSaver.__init__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s|d |D ]:}zt j| jd|| j| jd W q t jjy   Y q0 qdS )z
        Params:
        flagging_dir (str): local directory where the dataset is cloned,
        updated, and pushed from.
        datasetT)repo_idtokenrb   	repo_typer-   z
**/*.jsonldata.csvZconfigsdefaultZtrain)splitpath)Zconfig_name
data_files)ri   rk   metadata	overwriterj   /parentsr-   )ri   rk   filenameZ	local_dirrj   N)huggingface_hubZcreate_reporf   r_   rg   ri   rd   Zmetadata_updater   r   absolutern   dataset_dirmkdirrc   
infos_filer9   Zhf_hub_downloadr	   ZEntryNotFoundError)r   r   r   	path_globZremote_filesrw   r   r   r   r      sN    



zHuggingFaceDatasetSaver.setupr   r   r   r   c                 C  sV   | j r*tt }| j| }|d }|}n| j}|d }d }| j||||||pPddS )Nzmetadata.jsonlrl   r   )	data_filecomponents_dirpath_in_repor   r   r    )rd   r   uuiduuid4rz   _flag_in_dir)r   r   r   r    Z	unique_idr   r~   r   r   r   r   r"   %  s     
zHuggingFaceDatasetSaver.flagr   )r~   r   r   r   r   r    r!   c              
   C  sV  |  ||||\}}tt| jd R | j sl| jtdd|ii t	j
| jd| j| jj| jd W d    n1 s0    Y  t| }	| jst|d J | j||	|d}
t|
}t	j| jdd| |d|| jd	 W d    n1 s0    Y  nJ| j||	|d}td
d | j D }
t	j| jdd| |d|| jd	 |
S )Nz.lockZflaggedfeaturesrh   )ri   rk   rj   r   Zpath_or_fileobj)r[   rowzFlagged sample #z*.lock)ri   rk   Zcommit_messager   ignore_patternsZfolder_pathrj   c                 S  s   g | ]}|  r|qS r   )is_dir)rN   ro   r   r   r   rP   o      z8HuggingFaceDatasetSaver._flag_in_dir.<locals>.<listcomp>)_deserialize_componentsfilelockZFileLockr   r|   rV   
write_textjsondumpsrx   Zupload_filerf   r_   namerA   keysrd   _save_as_csvZupload_folder_save_as_jsonlr@   rz   iterdir)r   r~   r   r   r   r   r    r   r   r[   Z	sample_nbZsample_namer   r   r   r   @  sV    

$&

z$HuggingFaceDatasetSaver._flag_in_dirz	list[str])r~   r[   r   r!   c                 C  s   |    }| jdddd>}t|}|r:|t| |t| W d   n1 s^0    Y  | jdd,}tdd t|D d	 W  d   S 1 s0    Y  dS )
z9Save data as CSV and return the sample name (row number).r2   r   rR   rS   NrU   c                 s  s   | ]
}d V  qdS )r4   Nr   )rN   _r   r   r   	<genexpr>  r   z7HuggingFaceDatasetSaver._save_as_csv.<locals>.<genexpr>r4   )	rV   r;   r<   r=   r>   r	   r?   sumrB   )r~   r[   r   rZ   rH   r=   r   r   r   r   }  s    

.z$HuggingFaceDatasetSaver._save_as_csvc                 C  sZ   t j| jddd t| d&}ttt||| W d   n1 sH0    Y  | jjS )z5Save data as JSONL and return the sample name (uuid).Tru   wN)	r   r{   parentr;   r   dumpdictr5   r   )r~   r[   r   fr   r   r   r     s    4z&HuggingFaceDatasetSaver._save_as_jsonlz tuple[dict[Any, Any], list[Any]])data_dirr   r   r    r!   c                 C  s  t jdt jdi}t }g }t| j|D ](\}}	|jp8d}
|t|
 }|	|	|d}ddd||
< z.t
| svJ |tt
|| j W n6 tttfy   |du rdnt|}|| Y n0 t|t|r&| D ](\}}t||rd|i||
d	 <  q
q|rFt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\rs   rh   )ri   rw   rk   r"   r    )grr   r   r   r5   r   r8   r6   r7   r:   r   rV   r9   r   relative_torz   AssertionError	TypeError
ValueError
isinstancetupleitemsreplacerx   Z
hf_hub_urlrf   )r   r   r   r   r    Zfile_preview_typesr   r   rE   rF   r8   rG   ZdeserializedZ
_componentr   r   r   r   r   r     sL    



z/HuggingFaceDatasetSaver._deserialize_components)NFr]   FT)r   N)r   r   )r   r   )r#   r$   r%   r&   r*   r   r"   r   staticmethodr   r   r   r   r   r   r   r\      s*        ;  !  =  r\   c                      s.   e Zd Zdddddddd fd	d
Z  ZS )HuggingFaceDatasetJSONSaverNFr]   Tr   r   r^   )r_   r`   ra   rb   rc   re   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)r_   r`   ra   rb   rc   rd   )r   superr*   )r   r_   r`   ra   rb   rc   re   	__class__r   r   r*     s    	z$HuggingFaceDatasetJSONSaver.__init__)NFr]   T)r#   r$   r%   r*   __classcell__r   r   r   r   r     s
       r   c                   @  s<   e Zd ZdZddddddddZd	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.
    Tr   r   r^   )flagging_callbackr8   valuevisual_feedbackc                 C  s"   || _ || _|| _d| _|| _d S )NFlag)r   r8   r   r#   r   )r   r   r8   r   r   r   r   r   r*     s
    zFlagMethod.__init__z
gr.Request)requestc              
   G  s   z| j jt|| j|jd W nF tyd } z.td|  | jrPW Y d }~dS W Y d }~n
d }~0 0 | jspd S t	d | 
 S )N)r   r    zError while flagging: zError!g?)r   r"   rA   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updater8   r)   r   r   r   r     s    zFlagMethod.resetN)T)r#   r$   r%   r&   r*   r   r   r   r   r   r   r     s
   
 r   )&
__future__r   r<   rX   r   r/   r   r   abcr   r   collectionsr   pathlibr   typingr   r   r   rx   Zgradio_clientr	   r6   Zgradio_client.documentationr
   r   Zgradior   Zgradio.deprecationr   Zgradio.componentsr   r   r'   rK   r\   r   r   r   r   r   r   <module>   s>   %4I  