U
    ARdG                     @   s\  U d dl Z d dlmZ d dlmZ d dlmZmZmZm	Z	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mZmZ d d	l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%m&Z&m'Z'm(Z( d dl)m*Z*m+Z+ erd dl,m-Z- dZ.ee/d< e
e0e1e	ee j2f Z3eG dd dZ4G dd dZ5de0e3eee0 ee0 ddddZ6dS )    N)	dataclass)dedent)TYPE_CHECKINGBinaryIOOptionalTextIOUnioncast)FinalLiteral)runtime)current_form_id
is_in_form)check_callback_rulescheck_session_state_rules)StreamlitAPIException)Button)DownloadButton)gather_metrics)ScriptRunContextget_script_run_ctx)
WidgetArgsWidgetCallbackWidgetKwargsregister_widget)Keyto_key)DeltaGeneratorz

For more information, refer to the
[documentation for forms](https://docs.streamlit.io/library/api-reference/control-flow/st.form).
FORM_DOCS_INFOc                   @   s4   e Zd ZeedddZd	ee eedddZdS )
ButtonSerde)vreturnc                 C   s   t |S )N)bool)selfr     r$   =/tmp/pip-unpacked-wheel-b9et7o5g/streamlit/elements/button.py	serialize5   s    zButtonSerde.serialize )ui_value	widget_idr!   c                 C   s   |pdS )NFr$   )r#   r(   r)   r$   r$   r%   deserialize8   s    zButtonSerde.deserializeN)r'   )__name__
__module____qualname__r"   r&   r   strr*   r$   r$   r$   r%   r   3   s   r   c                   @   s\  e Zd Zeddddddeee ee ee ee ee	 e
d eeed
dd	Zed
ddddeeee ee ee ee ee ee ee	 eeedddZdddddeeee ee ee ee ee ee ee	 eeee edddZddddddeee ee eee ee ee	 e
d eeee edddZeddddZdS )ButtonMixinbuttonN	secondaryF)typedisableduse_container_widthZprimaryr1   )
labelkeyhelpon_clickargskwargsr2   r3   r4   r!   c                C   sH   t |}t }
|dkr&td| d| jj|||d||||||	|
dS )a  Display a button widget.

        Parameters
        ----------
        label : str
            A short label explaining to the user what this button is for.
            The label can optionally contain Markdown and supports the following
            elements: Bold, Italics, Strikethroughs, Inline Code, and Emojis.

            This also supports:

            * Emoji shortcodes, such as ``:+1:``  and ``:sunglasses:``.
              For a list of all supported codes,
              see https://share.streamlit.io/streamlit/emoji-shortcodes.

            * LaTeX expressions, by wrapping them in "$" or "$$" (the "$$"
              must be on their own lines). Supported LaTeX functions are listed
              at https://katex.org/docs/supported.html.

            * Colored text, using the syntax ``:color[text to be colored]``,
              where ``color`` needs to be replaced with any of the following
              supported colors: blue, green, orange, red, violet.

            Unsupported elements are unwrapped so only their children (text contents) render.
            Display unsupported elements as literal characters by
            backslash-escaping them. E.g. ``1\. Not an ordered list``.
        key : str or int
            An optional string or integer to use as the unique key for the widget.
            If this is omitted, a key will be generated for the widget
            based on its content. Multiple widgets of the same type may
            not share the same key.
        help : str
            An optional tooltip that gets displayed when the button is
            hovered over.
        on_click : callable
            An optional callback invoked when this button is clicked.
        args : tuple
            An optional tuple of args to pass to the callback.
        kwargs : dict
            An optional dict of kwargs to pass to the callback.
        type : "secondary" or "primary"
            An optional string that specifies the button type. Can be "primary" for a
            button with additional emphasis or "secondary" for a normal button. This
            argument can only be supplied by keyword. Defaults to "secondary".
        disabled : bool
            An optional boolean, which disables the button if set to True. The
            default is False. This argument can only be supplied by keyword.
        use_container_width: bool
            An optional boolean, which makes the button stretch its width to match the parent container.

        Returns
        -------
        bool
            True if the button was clicked on the last run of the app,
            False otherwise.

        Example
        -------
        >>> import streamlit as st
        >>>
        >>> if st.button('Say hello'):
        ...     st.write('Why hello there')
        ... else:
        ...     st.write('Goodbye')

        .. output::
           https://doc-buton.streamlitapp.com/
           height: 220px

        r5   z[The type argument to st.button must be "primary" or "secondary". 
The argument passed was "z".F)is_form_submitterr9   r:   r;   r3   r2   r4   ctx)r   r   r   dg_button)r#   r6   r7   r8   r9   r:   r;   r2   r3   r4   r=   r$   r$   r%   r0   =   s&    T
zButtonMixin.buttondownload_button)r3   r4   )r6   data	file_namemimer7   r8   r9   r:   r;   r3   r4   r!   c
                C   s(   t  }| j|||||||||	|
||dS )a  Display a download button widget.

        This is useful when you would like to provide a way for your users
        to download a file directly from your app.

        Note that the data to be downloaded is stored in-memory while the
        user is connected, so it's a good idea to keep file sizes under a
        couple hundred megabytes to conserve memory.

        Parameters
        ----------
        label : str
            A short label explaining to the user what this button is for.
            The label can optionally contain Markdown and supports the following
            elements: Bold, Italics, Strikethroughs, Inline Code, and Emojis.

            This also supports:

            * Emoji shortcodes, such as ``:+1:``  and ``:sunglasses:``.
              For a list of all supported codes,
              see https://share.streamlit.io/streamlit/emoji-shortcodes.

            * LaTeX expressions, by wrapping them in "$" or "$$" (the "$$"
              must be on their own lines). Supported LaTeX functions are listed
              at https://katex.org/docs/supported.html.

            * Colored text, using the syntax ``:color[text to be colored]``,
              where ``color`` needs to be replaced with any of the following
              supported colors: blue, green, orange, red, violet.

            Unsupported elements are unwrapped so only their children (text contents) render.
            Display unsupported elements as literal characters by
            backslash-escaping them. E.g. ``1\. Not an ordered list``.
        data : str or bytes or file
            The contents of the file to be downloaded. See example below for
            caching techniques to avoid recomputing this data unnecessarily.
        file_name: str
            An optional string to use as the name of the file to be downloaded,
            such as 'my_file.csv'. If not specified, the name will be
            automatically generated.
        mime : str or None
            The MIME type of the data. If None, defaults to "text/plain"
            (if data is of type *str* or is a textual *file*) or
            "application/octet-stream" (if data is of type *bytes* or is a
            binary *file*).
        key : str or int
            An optional string or integer to use as the unique key for the widget.
            If this is omitted, a key will be generated for the widget
            based on its content. Multiple widgets of the same type may
            not share the same key.
        help : str
            An optional tooltip that gets displayed when the button is
            hovered over.
        on_click : callable
            An optional callback invoked when this button is clicked.
        args : tuple
            An optional tuple of args to pass to the callback.
        kwargs : dict
            An optional dict of kwargs to pass to the callback.
        disabled : bool
            An optional boolean, which disables the download button if set to
            True. The default is False. This argument can only be supplied by
            keyword.
        use_container_width: bool
            An optional boolean, which makes the button stretch its width to match the parent container.


        Returns
        -------
        bool
            True if the button was clicked on the last run of the app,
            False otherwise.

        Examples
        --------
        Download a large DataFrame as a CSV:

        >>> import streamlit as st
        >>>
        >>> @st.cache
        ... def convert_df(df):
        ...     # IMPORTANT: Cache the conversion to prevent computation on every rerun
        ...     return df.to_csv().encode('utf-8')
        >>>
        >>> csv = convert_df(my_large_df)
        >>>
        >>> st.download_button(
        ...     label="Download data as CSV",
        ...     data=csv,
        ...     file_name='large_df.csv',
        ...     mime='text/csv',
        ... )

        Download a string as a file:

        >>> import streamlit as st
        >>>
        >>> text_contents = '''This is some text'''
        >>> st.download_button('Download some text', text_contents)

        Download a binary file:

        >>> import streamlit as st
        >>>
        >>> binary_contents = b'example content'
        >>> # Defaults to 'application/octet-stream'
        >>> st.download_button('Download binary file', binary_contents)

        Download an image:

        >>> import streamlit as st
        >>>
        >>> with open("flower.png", "rb") as file:
        ...     btn = st.download_button(
        ...             label="Download image",
        ...             data=file,
        ...             file_name="flower.png",
        ...             mime="image/png"
        ...           )

        .. output::
           https://doc-download-buton.streamlitapp.com/
           height: 335px

        )r6   rA   rB   rC   r7   r8   r9   r:   r;   r3   r4   r=   )r   _download_button)r#   r6   rA   rB   rC   r7   r8   r9   r:   r;   r3   r4   r=   r$   r$   r%   r@      s      zButtonMixin.download_button)r3   r4   r=   )r6   rA   rB   rC   r7   r8   r9   r:   r;   r3   r4   r=   r!   c
                C   s   t |}td |dd t| jr.tdt t }||_||_d|_	t
| j |||| |d k	rnt||_t }td|||||	|j|j|d	}|
|_| jd| |jS )NFdefault_valuer7   Zwrites_allowedz7`st.download_button()` can't be used in an `st.form()`.r@   Zuser_keyZon_change_handlerr:   r;   Zdeserializer
serializerr=   )r   r   r   r>   r   r   DownloadButtonProtor4   r6   defaultmarshall_fileZ_get_delta_path_strr   r8   r   r   r*   r&   r3   _enqueuevalue)r#   r6   rA   rB   rC   r7   r8   r9   r:   r;   r3   r4   r=   Zdownload_button_protoserdebutton_stater$   r$   r%   rD   F  sD    
    
zButtonMixin._download_button)r2   r3   r4   r=   )r6   r7   r8   r<   r9   r:   r;   r2   r3   r4   r=   r!   c                C   s   |st | j| td |dd t r`t| jrD|sDtdt nt| js`|r`tdt t }||_	d|_
||_t| j|_||_|
|_|d k	rt||_t }td||||||j|j|d	}|	|_| jd| |jS )NFrE   z.`st.button()` can't be used in an `st.form()`.z=`st.form_submit_button()` must be used inside an `st.form()`.r0   rG   )r   r>   r   r   existsr   r   r   ButtonProtor6   rJ   r<   r   Zform_idr2   r4   r   r8   r   r   r*   r&   r3   rL   rM   )r#   r6   r7   r8   r<   r9   r:   r;   r2   r3   r4   r=   Zbutton_protorN   rO   r$   r$   r%   r?     sH    
zButtonMixin._buttonr   )r!   c                 C   s
   t d| S )zGet our DeltaGenerator.r   )r	   )r#   r$   r$   r%   r>     s    zButtonMixin.dg)NNNNN)NNNNNNN)NNNNNNN)NNN)r+   r,   r-   r   r.   r   r   r   r   r   r   r"   r0   DownloadButtonDataTyper@   r   rD   r?   propertyr>   r$   r$   r$   r%   r/   <   s        	k        !       ?   
Br/   )coordinatesrA   proto_download_buttonmimetyperB   r!   c                 C   s  t |tr| }|pd}nt |tjrB| }| }|p>d}nt |trZ|}|pVd}nt |tjr|d |	 }|p~d}ndt |tj
r|d | }|pd}n<t |tjr|d | pd}|pd}ntdt| t rt jj||| |dd}nd}||_d S )	Nz
text/plainzapplication/octet-streamr       zInvalid binary data format: %sT)rB   Zis_for_static_downloadr'   )
isinstancer.   encodeioTextIOWrapperreadbytesBytesIOseekgetvalueBufferedReader	RawIOBaseRuntimeErrorr2   r   rP   Zget_instanceZmedia_file_mgraddurl)rT   rA   rU   rV   rB   Zdata_as_bytesZstring_dataZfile_urlr$   r$   r%   rK     sB    












	rK   )N)7rZ   Zdataclassesr   textwrapr   typingr   r   r   r   r   r	   Ztyping_extensionsr
   r   Z	streamlitr   Zstreamlit.elements.formr   r   Zstreamlit.elements.utilsr   r   Zstreamlit.errorsr   Zstreamlit.proto.Button_pb2r   rQ   Z"streamlit.proto.DownloadButton_pb2r   rI   Zstreamlit.runtime.metrics_utilr   Zstreamlit.runtime.scriptrunnerr   r   Zstreamlit.runtime.stater   r   r   r   Zstreamlit.type_utilr   r   Zstreamlit.delta_generatorr   r   __annotations__r.   r]   rb   rR   r   r/   rK   r$   r$   r$   r%   <module>   sD         