o
    沪g                     @  s  U d dl mZ 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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mZ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, d dl-m.Z. d dl/m0Z1 d dl2m3Z3 d dl4m5Z5 d dl6m7Z7m8Z8m9Z9m:Z: d dl;m<Z< d dl=m>Z> erd dl?m@Z@mAZA d dlBZCd dlDZEd dlFZGd dlHmIZI d dlJmKZK eLeMZNdeOd< edeejPe	 eQe	 eRe	 eSe	 eTeUe	f f dZVeddddd d!eQe	 eRe	 eSe	 eTeUe	f f
 ZWd"eOd#< G d$d% d%ed&d'ZXeG d(d) d)ZYdTd0d1ZZdUd8d9Z[dVd<d=Z\dWd@dAZ]dXdCdDZ^dYdGdHZ_dZdJdKZ`d[dLdMZad\dPdQZbG dRdS dSZcdS )]    )annotationsN)	dataclass)Decimal)	TYPE_CHECKINGAnyFinalLiteral	TypedDictTypeVarUnioncastoverload)	TypeAlias)dataframe_util)logger)INDEX_IDENTIFIERColumnConfigMappingColumnConfigMappingInputColumnDataKindDataframeSchemaapply_data_specific_configsdetermine_dataframe_schemais_type_compatiblemarshall_column_configprocess_config_mappingupdate_column_config)current_form_id)marshall_styler)check_widget_policies)Keycompute_and_register_element_idto_key)StreamlitAPIException)Arrow)gather_metrics)get_script_run_ctx)
WidgetArgsWidgetCallbackWidgetKwargsregister_widget)is_type)calc_md5)IterableMapping)Styler)DeltaGeneratorr   _LOGGEREditableData)boundpd.DataFramez	pd.Seriespd.Indexr.   zpa.Tablez%np.ndarray[Any, np.dtype[np.float64]]r   	DataTypesc                   @  s*   e Zd ZU dZded< ded< ded< dS )	EditingStatea,  
    A dictionary representing the current state of the data editor.

    Attributes
    ----------
    edited_rows : Dict[int, Dict[str, str | int | float | bool | None]]
        An hierarchical mapping of edited cells based on: row position -> column name -> value.

    added_rows : List[Dict[str, str | int | float | bool | None]]
        A list of added rows, where each row is a mapping from column name to the cell value.

    deleted_rows : List[int]
        A list of deleted rows, where each row is the numerical position of the deleted row.
    z5dict[int, dict[str, str | int | float | bool | None]]edited_rowsz0list[dict[str, str | int | float | bool | None]]
added_rows	list[int]deleted_rowsN)__name__
__module____qualname____doc____annotations__ r@   r@   b/var/www/html/chatdoc2/venv/lib/python3.10/site-packages/streamlit/elements/widgets/data_editor.pyr6   p   s
   
 r6   F)totalc                   @  s&   e Zd ZdZddd	d
ZdddZdS )DataEditorSerdezKDataEditorSerde is used to serialize and deserialize the data editor state. ui_value
str | None	widget_idstrreturnr6   c                 C  sl   |d u r
i g g dnt |}d|vri |d< d|vrg |d< d|vr'g |d< dd |d  D |d< |S )N)r7   r8   r:   r7   r:   r8   c                 S  s   i | ]	\}}t ||qS r@   )int).0kvr@   r@   rA   
<dictcomp>   s    z/DataEditorSerde.deserialize.<locals>.<dictcomp>)jsonloadsitems)selfrE   rG   data_editor_stater@   r@   rA   deserialize   s"   

zDataEditorSerde.deserializeediting_statec                 C  s   t j|tdS )N)default)rO   dumpsrH   )rR   rU   r@   r@   rA   	serialize   s   zDataEditorSerde.serializeN)rD   )rE   rF   rG   rH   rI   r6   )rU   r6   rI   rH   )r;   r<   r=   r>   rT   rX   r@   r@   r@   rA   rC      s    rC   valuestr | int | float | bool | Nonecolumn_data_kindr   rI   r   c              
   C  sF  | du rdS ddl }zx|tjkrt| W S |tjkrt| W S |tjkr)t| W S |tjkr3t	| W S |tj
kr?tt| W S |tjkrJ|| W S |tjtjtjfv r}|| }||ju raW dS |tjkri|W S |tjkrs| W S |tjkr| W S W | S W | S  t|jjfy } ztjd| ||d W Y d}~dS d}~ww )a  Convert a value to the correct type.

    Parameters
    ----------
    value : str | int | float | bool | None
        The value to convert.

    column_data_kind : ColumnDataKind
        The determined data kind of the column. The column data kind refers to the
        shared data type of the values in the column (e.g. int, float, str).

    Returns
    -------
    The converted value.
    Nr   zFailed to parse value %s as %s.)exc_info)pandasr   STRINGrH   INTEGERrJ   FLOATfloatBOOLEANboolDECIMALr   	TIMEDELTA	TimedeltaDATETIMEDATETIME	TimestampNaTdatetime
ValueErrorerrorsParserErrorr0   warning)rY   r[   pddatetime_valueexr@   r@   rA   _parse_value   sX   
















ru   dfr7   ;Mapping[int, Mapping[str, str | int | float | bool | None]]dataframe_schemar   Nonec           	      C  st   |  D ]3\}}t|}|  D ]&\}}|tkr$t||t | jj|< q| j|}t||| | j||f< qqdS )a  Apply cell edits to the provided dataframe (inplace).

    Parameters
    ----------
    df : pd.DataFrame
        The dataframe to apply the cell edits to.

    edited_rows : Mapping[int, Mapping[str, str | int | float | bool | None]]
        A hierarchical mapping based on row position -> column name -> value

    dataframe_schema: DataframeSchema
        The schema of the dataframe.
    N)	rQ   rJ   r   ru   indexvaluescolumnsget_lociat)	rv   r7   rx   row_idrow_changesrow_poscol_namerY   col_posr@   r@   rA   _apply_cell_edits   s   r   r8   list[dict[str, Any]]c                 C  s   |sdS ddl }d}d}t| j|jr| jj}| jj}|D ]U}d}dd t| jd D }| D ]!}	||	 }
|	t	krCt
|
|t	 }q1| j|	}t
|
||	 ||< q1|dure|| j|ddf< ||7 }q|durr|| j|ddf< qdS )a  Apply row additions to the provided dataframe (inplace).

    Parameters
    ----------
    df : pd.DataFrame
        The dataframe to apply the row additions to.

    added_rows : List[Dict[str, Any]]
        A list of row additions. Each row addition is a dictionary with the
        column position as key and the new cell value as value.

    dataframe_schema: DataframeSchema
        The schema of the dataframe.
    Nr   c                 S  s   g | ]}d qS Nr@   )rK   _r@   r@   rA   
<listcomp><  s    z(_apply_row_additions.<locals>.<listcomp>   )r]   
isinstancerz   
RangeIndexstopsteprangeshapekeysr   ru   r|   r}   loc)rv   r8   rx   rr   range_index_stoprange_index_step	added_rowindex_valuenew_rowr   rY   r   r@   r@   rA   _apply_row_additions  s0   
r   r:   r9   c                 C  s   | j | j| dd dS )zApply row deletions to the provided dataframe (inplace).

    Parameters
    ----------
    df : pd.DataFrame
        The dataframe to apply the row deletions to.

    deleted_rows : List[int]
        A list of row numbers to delete.
    T)inplaceN)droprz   )rv   r:   r@   r@   rA   _apply_row_deletionsT  s   r   rS   c                 C  sT   | drt| |d | | drt| |d  | dr(t| |d | dS dS )a  Apply edits to the provided dataframe (inplace).

    This includes cell edits, row additions and row deletions.

    Parameters
    ----------
    df : pd.DataFrame
        The dataframe to apply the edits to.

    data_editor_state : EditingState
        The editing state of the data editor component.

    dataframe_schema: DataframeSchema
        The schema of the dataframe.
    r7   r:   r8   N)getr   r   r   )rv   rS   rx   r@   r@   rA   _apply_dataframe_editsc  s   


r   df_indexrc   c                 C  sB   ddl }t| |j|j|j|jfv p t| dp t| dp t| dS )zCheck if the index is supported by the data editor component.

    Parameters
    ----------

    df_index : pd.Index
        The index to check.

    Returns
    -------

    bool
        True if the index is supported, False otherwise.
    r   Nz&pandas.core.indexes.numeric.Int64Indexz(pandas.core.indexes.numeric.Float64Indexz'pandas.core.indexes.numeric.UInt64Index)r]   typer   IndexDatetimeIndexCategoricalIndexr*   )r   rr   r@   r@   rA   _is_supported_index  s   r   data_dfc                 C  sf   ddl }t| j|jrdd | j D | _dS |jj| jdkr1| jdd | jD dd	 dS dS )
z`Fix the column headers of the provided dataframe inplace to work
    correctly for data editing.r   Nc                 S  s   g | ]
}d  tt|qS )r   )joinmaprH   )rK   headerr@   r@   rA   r     s    z'_fix_column_headers.<locals>.<listcomp>stringc                 S  s   i | ]}|t |qS r@   )rH   )rK   columnr@   r@   rA   rN     s    z'_fix_column_headers.<locals>.<dictcomp>T)r|   r   )	r]   r   r|   
MultiIndexto_flat_indexapitypesinfer_dtyperename)r   rr   r@   r@   rA   _fix_column_headers  s   
r   c                 C  sZ   | j jrdS | j | j   }t|dkrtdt| dt| j v r+tdt ddS )zCheck if the column names in the provided dataframe are valid.

    It's not allowed to have duplicate column names or column names that are
    named ``_index``. If the column names are not valid, a ``StreamlitAPIException``
    is raised.
    Nr   zrAll column names are required to be unique for usage with data editor. The following column names are duplicated: z<. Please rename the duplicated columns in the provided data.zThe column name 'zu' is reserved for the index column and can't be used for data columns. Please rename the column in the provided data.)r|   empty
duplicatedlenr"   listr   )r   duplicated_columnsr@   r@   rA   _check_column_names  s   

r   columns_configr   c              	   C  s   t | jfg}|t|   D ]C}|\}}|| }||v rQ|| }|ddu r(q|d}	|	du r2q|	d}
|
du r<qt|
|du rQtd|
 d| d	| d
qdS )a  Check column type to data type compatibility.

    Iterates the index and all columns of the dataframe to check if
    the configured column types are compatible with the underlying data types.

    Parameters
    ----------
    data_df : pd.DataFrame
        The dataframe to check the type compatibilities for.

    columns_config : ColumnConfigMapping
        A mapping of column to column configurations.

    dataframe_schema : DataframeSchema
        The schema of the dataframe.

    Raises
    ------
    StreamlitAPIException
        If a configured column type is editable and not compatible with the
        underlying data type.
    disabledTtype_configNr   FzThe configured column type `z` for column `z:` is not compatible for editing the underlying data type `z`.

You have following options to fix this: 1) choose a compatible type 2) disable the column 3) convert the column into a compatible data type.)r   rz   r   rQ   r   r   r"   )r   r   rx   indicesr   column_namer   r[   column_configr   configured_column_typer@   r@   rA   _check_type_compatibilities  s0   

r   c                   @  s   e Zd Zedddddddddddddd*dd Zedddddddddddddd+d#d Zed$dddddddddddddd,d&d Zed-d(d)ZdS ).DataEditorMixinNFfixed)widthheightuse_container_width
hide_indexcolumn_orderr   num_rowsr   key	on_changeargskwargsdatar1   r   
int | Noner   r   rc   r   bool | Noner   Iterable[str] | Noner   ColumnConfigMappingInput | Noner   Literal['fixed', 'dynamic']r   bool | Iterable[str]r   
Key | Noner   WidgetCallback | Noner   WidgetArgs | Noner   WidgetKwargs | NonerI   c                C     d S r   r@   rR   r   r   r   r   r   r   r   r   r   r   r   r   r   r@   r@   rA   data_editor     zDataEditorMixin.data_editorr   r3   c                C  r   r   r@   r   r@   r@   rA   r   ,  r   r   r5   c                 C  s  ddl }ddl}t|
}
t| j|
|ddd |durt|}i }t|}|tjj	kr6t
dt|j dtj|dd}t|jsNt
d	t|jj d
t| t|}| D ]\}}t|rrt||ddi |d||< qZt|| t| t|j|j}|st|tddi |du r|r|dkrd}|durt|td|i t|	ts|	D ]
}t||ddi q|j|}t||j}t ||| t!|}t" }t#d|
t$| j|||||t%||d
}t& }||_'||_(|r||_)|r||_*|r||j+dd< |	du |_,|dkrt&j-j.nt&j-j/|_0t$| j|_1t2|r9t3|
p(| j4 dd }|5| t6||| ||_7t8|| t9 }t:|j'||||j;|j<|dd}t=||j>| | j?d| t@||S )u`!  Display a data editor widget.

        The data editor widget allows you to edit dataframes and many other data structures in a table-like UI.

        Parameters
        ----------
        data : Anything supported by st.dataframe
            The data to edit in the data editor.

            .. note::
                - Styles from ``pandas.Styler`` will only be applied to non-editable columns.
                - Text and number formatting from ``column_config`` always takes
                  precedence over text and number formatting from ``pandas.Styler``.
                - Mixing data types within a column can make the column uneditable.
                - Additionally, the following data types are not yet supported for editing:
                  ``complex``, ``list``, ``tuple``, ``bytes``, ``bytearray``,
                  ``memoryview``, ``dict``, ``set``, ``frozenset``,
                  ``fractions.Fraction``, ``pandas.Interval``, and
                  ``pandas.Period``.
                - To prevent overflow in JavaScript, columns containing
                  ``datetime.timedelta`` and ``pandas.Timedelta`` values will
                  default to uneditable, but this can be changed through column
                  configuration.

        width : int or None
            Desired width of the data editor expressed in pixels. If ``width``
            is ``None`` (default), Streamlit sets the data editor width to fit
            its contents up to the width of the parent container. If ``width``
            is greater than the width of the parent container, Streamlit sets
            the data editor width to match the width of the parent container.

        height : int or None
            Desired height of the data editor expressed in pixels. If ``height``
            is ``None`` (default), Streamlit sets the height to show at most
            ten rows. Vertical scrolling within the data editor element is
            enabled when the height does not accomodate all rows.

        use_container_width : bool
            Whether to override ``width`` with the width of the parent
            container. If ``use_container_width`` is ``False`` (default),
            Streamlit sets the data editor's width according to ``width``. If
            ``use_container_width`` is ``True``, Streamlit sets the width of
            the data editor to match the width of the parent container.

        hide_index : bool or None
            Whether to hide the index column(s). If ``hide_index`` is ``None``
            (default), the visibility of index columns is automatically
            determined based on the data.

        column_order : Iterable of str or None
            Specifies the display order of columns. This also affects which columns are
            visible. For example, ``column_order=("col2", "col1")`` will display 'col2'
            first, followed by 'col1', and will hide all other non-index columns. If
            None (default), the order is inherited from the original data structure.

        column_config : dict or None
            Configures how columns are displayed, e.g. their title, visibility, type, or
            format, as well as editing properties such as min/max value or step.
            This needs to be a dictionary where each key is a column name and the value
            is one of:

            - ``None`` to hide the column.

            - A string to set the display label of the column.

            - One of the column types defined under ``st.column_config``, e.g.
              ``st.column_config.NumberColumn("Dollar values”, format=”$ %d")`` to show
              a column as dollar amounts. See more info on the available column types
              and config options `here <https://docs.streamlit.io/develop/api-reference/data/st.column_config>`_.

            To configure the index column(s), use ``_index`` as the column name.

        num_rows : "fixed" or "dynamic"
            Specifies if the user can add and delete rows in the data editor.
            If "fixed", the user cannot add or delete rows. If "dynamic", the user can
            add and delete rows in the data editor, but column sorting is disabled.
            Defaults to "fixed".

        disabled : bool or Iterable of str
            Controls the editing of columns. If True, editing is disabled for all columns.
            If an Iterable of column names is provided (e.g., ``disabled=("col1", "col2"))``,
            only the specified columns will be disabled for editing. If False (default),
            all columns that support editing are editable.

        key : str
            An optional string to use as the unique key for this widget. If this
            is omitted, a key will be generated for the widget based on its
            content. No two widgets may have the same key.

        on_change : callable
            An optional callback invoked when this data_editor's value changes.

        args : tuple
            An optional tuple of args to pass to the callback.

        kwargs : dict
            An optional dict of kwargs to pass to the callback.

        Returns
        -------
        pandas.DataFrame, pandas.Series, pyarrow.Table, numpy.ndarray, list, set, tuple, or dict.
            The edited data. The edited data is returned in its original data type if
            it corresponds to any of the supported return types. All other data types
            are returned as a ``pandas.DataFrame``.

        Examples
        --------
        >>> import streamlit as st
        >>> import pandas as pd
        >>>
        >>> df = pd.DataFrame(
        >>>     [
        >>>        {"command": "st.selectbox", "rating": 4, "is_widget": True},
        >>>        {"command": "st.balloons", "rating": 5, "is_widget": False},
        >>>        {"command": "st.time_input", "rating": 3, "is_widget": True},
        >>>    ]
        >>> )
        >>> edited_df = st.data_editor(df)
        >>>
        >>> favorite_command = edited_df.loc[edited_df["rating"].idxmax()]["command"]
        >>> st.markdown(f"Your favorite command is **{favorite_command}** 🎈")

        .. output::
           https://doc-data-editor.streamlit.app/
           height: 350px

        You can also allow the user to add and delete rows by setting ``num_rows`` to "dynamic":

        >>> import streamlit as st
        >>> import pandas as pd
        >>>
        >>> df = pd.DataFrame(
        >>>     [
        >>>        {"command": "st.selectbox", "rating": 4, "is_widget": True},
        >>>        {"command": "st.balloons", "rating": 5, "is_widget": False},
        >>>        {"command": "st.time_input", "rating": 3, "is_widget": True},
        >>>    ]
        >>> )
        >>> edited_df = st.data_editor(df, num_rows="dynamic")
        >>>
        >>> favorite_command = edited_df.loc[edited_df["rating"].idxmax()]["command"]
        >>> st.markdown(f"Your favorite command is **{favorite_command}** 🎈")

        .. output::
           https://doc-data-editor1.streamlit.app/
           height: 450px

        Or you can customize the data editor via ``column_config``, ``hide_index``, ``column_order``, or ``disabled``:

        >>> import pandas as pd
        >>> import streamlit as st
        >>>
        >>> df = pd.DataFrame(
        >>>     [
        >>>         {"command": "st.selectbox", "rating": 4, "is_widget": True},
        >>>         {"command": "st.balloons", "rating": 5, "is_widget": False},
        >>>         {"command": "st.time_input", "rating": 3, "is_widget": True},
        >>>     ]
        >>> )
        >>> edited_df = st.data_editor(
        >>>     df,
        >>>     column_config={
        >>>         "command": "Streamlit Command",
        >>>         "rating": st.column_config.NumberColumn(
        >>>             "Your rating",
        >>>             help="How much do you like this command (1-5)?",
        >>>             min_value=1,
        >>>             max_value=5,
        >>>             step=1,
        >>>             format="%d ⭐",
        >>>         ),
        >>>         "is_widget": "Widget ?",
        >>>     },
        >>>     disabled=["command", "is_widget"],
        >>>     hide_index=True,
        >>> )
        >>>
        >>> favorite_command = edited_df.loc[edited_df["rating"].idxmax()]["command"]
        >>> st.markdown(f"Your favorite command is **{favorite_command}** 🎈")


        .. output::
           https://doc-data-editor-config.streamlit.app/
           height: 350px

        r   NF)default_valuewrites_allowedzThe data type (z) or format is not supported by the data editor. Please convert your data into a Pandas Dataframe or another supported data format.T)ensure_copyz"The type of the dataframe index - z+ - is not yet supported by the data editor.r   r   requireddynamichiddenr   )	user_keyform_idr   r   r   r   r   column_config_mappingr   
   string_value)on_change_handlerr   r   deserializer
serializerctx
value_typearrow_data_frame)Ar]   pyarrowr!   r   dgr   r   determine_data_format
DataFormatUNKNOWNr"   r   r;   convert_anything_to_pandas_dfr   rz   r   r   rQ    is_colum_type_arrow_incompatibler   astyper   r   r   r   r   rc   Tablefrom_pandasr   schemar   "convert_arrow_table_to_arrow_bytesr%   r    r   rH   
ArrowProtoidr   r   r   r   r   EditingModeDYNAMICFIXEDediting_moder   is_pandas_stylerr+   _get_delta_path_strset_uuidr   r   r   rC   r)   rT   rX   r   rY   _enqueue convert_pandas_df_to_data_format) rR   r   r   r   r   r   r   r   r   r   r   r   r   r   rr   par   data_formatr   r   column_datahas_range_indexr   arrow_tablerx   arrow_bytesr   
element_idprotostyler_uuidserdewidget_stater@   r@   rA   r   @  s    N













r/   c                 C  s
   t d| S )zGet our DeltaGenerator.r/   )r   )rR   r@   r@   rA   r     s   
zDataEditorMixin.dg)r   r1   r   r   r   r   r   rc   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   rI   r1   )r   r   r   r   r   r   r   rc   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   rI   r3   )r   r5   r   r   r   r   r   rc   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   rI   r5   )rI   r/   )r;   r<   r=   r   r   r$   propertyr   r@   r@   r@   rA   r     s^      r   )rY   rZ   r[   r   rI   r   )rv   r3   r7   rw   rx   r   rI   ry   )rv   r3   r8   r   rx   r   rI   ry   )rv   r3   r:   r9   rI   ry   )rv   r3   rS   r6   rx   r   rI   ry   )r   r4   rI   rc   )r   r3   rI   ry   )r   r3   )r   r3   r   r   rx   r   )d
__future__r   rO   dataclassesr   decimalr   typingr   r   r   r   r	   r
   r   r   r   typing_extensionsr   	streamlitr   r   _logger*streamlit.elements.lib.column_config_utilsr   r   r   r   r   r   r   r   r   r   r   !streamlit.elements.lib.form_utilsr   *streamlit.elements.lib.pandas_styler_utilsr   streamlit.elements.lib.policiesr   streamlit.elements.lib.utilsr   r    r!   streamlit.errorsr"   streamlit.proto.Arrow_pb2r#   r   streamlit.runtime.metrics_utilr$   7streamlit.runtime.scriptrunner_utils.script_run_contextr%   streamlit.runtime.stater&   r'   r(   r)   streamlit.type_utilr*   streamlit.utilr+   collections.abcr,   r-   numpynpr]   rr   r   r  pandas.io.formats.styler.   streamlit.delta_generatorr/   
get_loggerr;   r0   r?   DataFrameGenericAliastupler   setdictrH   r1   r5   r6   rC   ru   r   r   r   r   r   r   r   r   r   r@   r@   r@   rA   <module>   s   ,4


#
L
#
<

 
%

>