streamlit-data-editor-plus 0.1.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- streamlit/__init__.py +292 -0
- streamlit/__main__.py +20 -0
- streamlit/auth_util.py +583 -0
- streamlit/cli_util.py +107 -0
- streamlit/column_config.py +60 -0
- streamlit/commands/__init__.py +13 -0
- streamlit/commands/echo.py +128 -0
- streamlit/commands/execution_control.py +318 -0
- streamlit/commands/logo.py +250 -0
- streamlit/commands/navigation.py +430 -0
- streamlit/commands/page_config.py +335 -0
- streamlit/components/__init__.py +13 -0
- streamlit/components/lib/__init__.py +13 -0
- streamlit/components/lib/local_component_registry.py +84 -0
- streamlit/components/types/__init__.py +13 -0
- streamlit/components/types/base_component_registry.py +99 -0
- streamlit/components/types/base_custom_component.py +158 -0
- streamlit/components/v1/__init__.py +29 -0
- streamlit/components/v1/component_arrow.py +141 -0
- streamlit/components/v1/component_registry.py +147 -0
- streamlit/components/v1/components.py +38 -0
- streamlit/components/v1/custom_component.py +239 -0
- streamlit/components/v2/__init__.py +531 -0
- streamlit/components/v2/bidi_component/__init__.py +20 -0
- streamlit/components/v2/bidi_component/constants.py +29 -0
- streamlit/components/v2/bidi_component/main.py +537 -0
- streamlit/components/v2/bidi_component/serialization.py +272 -0
- streamlit/components/v2/bidi_component/state.py +92 -0
- streamlit/components/v2/component_definition_resolver.py +143 -0
- streamlit/components/v2/component_file_watcher.py +403 -0
- streamlit/components/v2/component_manager.py +439 -0
- streamlit/components/v2/component_manifest_handler.py +122 -0
- streamlit/components/v2/component_path_utils.py +233 -0
- streamlit/components/v2/component_registry.py +426 -0
- streamlit/components/v2/get_bidi_component_manager.py +51 -0
- streamlit/components/v2/manifest_scanner.py +620 -0
- streamlit/components/v2/presentation.py +198 -0
- streamlit/components/v2/types.py +317 -0
- streamlit/config.py +2977 -0
- streamlit/config_option.py +319 -0
- streamlit/config_util.py +887 -0
- streamlit/connections/__init__.py +32 -0
- streamlit/connections/base_connection.py +215 -0
- streamlit/connections/snowflake_connection.py +765 -0
- streamlit/connections/snowpark_connection.py +213 -0
- streamlit/connections/sql_connection.py +427 -0
- streamlit/connections/util.py +97 -0
- streamlit/cursor.py +314 -0
- streamlit/dataframe_util.py +1434 -0
- streamlit/delta_generator.py +696 -0
- streamlit/delta_generator_singletons.py +243 -0
- streamlit/deprecation_util.py +253 -0
- streamlit/development.py +21 -0
- streamlit/elements/__init__.py +13 -0
- streamlit/elements/alert.py +341 -0
- streamlit/elements/arrow.py +1065 -0
- streamlit/elements/balloons.py +47 -0
- streamlit/elements/bokeh_chart.py +75 -0
- streamlit/elements/code.py +154 -0
- streamlit/elements/deck_gl_json_chart.py +627 -0
- streamlit/elements/dialog_decorator.py +320 -0
- streamlit/elements/empty.py +130 -0
- streamlit/elements/exception.py +370 -0
- streamlit/elements/form.py +481 -0
- streamlit/elements/graphviz_chart.py +226 -0
- streamlit/elements/heading.py +407 -0
- streamlit/elements/help.py +565 -0
- streamlit/elements/html.py +189 -0
- streamlit/elements/iframe.py +245 -0
- streamlit/elements/image.py +221 -0
- streamlit/elements/json.py +171 -0
- streamlit/elements/layouts.py +1534 -0
- streamlit/elements/lib/__init__.py +13 -0
- streamlit/elements/lib/built_in_chart_utils.py +1316 -0
- streamlit/elements/lib/color_util.py +272 -0
- streamlit/elements/lib/column_config_utils.py +555 -0
- streamlit/elements/lib/column_types.py +2699 -0
- streamlit/elements/lib/dialog.py +212 -0
- streamlit/elements/lib/dicttools.py +152 -0
- streamlit/elements/lib/file_uploader_utils.py +91 -0
- streamlit/elements/lib/form_utils.py +77 -0
- streamlit/elements/lib/image_utils.py +447 -0
- streamlit/elements/lib/js_number.py +105 -0
- streamlit/elements/lib/layout_utils.py +325 -0
- streamlit/elements/lib/mutable_expander_container.py +73 -0
- streamlit/elements/lib/mutable_popover_container.py +73 -0
- streamlit/elements/lib/mutable_status_container.py +194 -0
- streamlit/elements/lib/mutable_tab_container.py +73 -0
- streamlit/elements/lib/options_selector_utils.py +480 -0
- streamlit/elements/lib/pandas_styler_utils.py +302 -0
- streamlit/elements/lib/policies.py +198 -0
- streamlit/elements/lib/shortcut_utils.py +152 -0
- streamlit/elements/lib/streamlit_plotly_theme.py +206 -0
- streamlit/elements/lib/subtitle_utils.py +175 -0
- streamlit/elements/lib/utils.py +274 -0
- streamlit/elements/map.py +526 -0
- streamlit/elements/markdown.py +529 -0
- streamlit/elements/media.py +843 -0
- streamlit/elements/metric.py +529 -0
- streamlit/elements/pdf.py +190 -0
- streamlit/elements/plotly_chart.py +779 -0
- streamlit/elements/progress.py +172 -0
- streamlit/elements/pyplot.py +240 -0
- streamlit/elements/snow.py +47 -0
- streamlit/elements/space.py +121 -0
- streamlit/elements/spinner.py +152 -0
- streamlit/elements/table.py +240 -0
- streamlit/elements/text.py +113 -0
- streamlit/elements/toast.py +175 -0
- streamlit/elements/vega_charts.py +2510 -0
- streamlit/elements/widgets/__init__.py +13 -0
- streamlit/elements/widgets/audio_input.py +334 -0
- streamlit/elements/widgets/button.py +1559 -0
- streamlit/elements/widgets/button_group.py +1061 -0
- streamlit/elements/widgets/camera_input.py +281 -0
- streamlit/elements/widgets/chat.py +1028 -0
- streamlit/elements/widgets/checkbox.py +420 -0
- streamlit/elements/widgets/color_picker.py +329 -0
- streamlit/elements/widgets/data_editor.py +1168 -0
- streamlit/elements/widgets/data_editor_plus.py +902 -0
- streamlit/elements/widgets/feedback.py +322 -0
- streamlit/elements/widgets/file_uploader.py +592 -0
- streamlit/elements/widgets/multiselect.py +654 -0
- streamlit/elements/widgets/number_input.py +719 -0
- streamlit/elements/widgets/radio.py +551 -0
- streamlit/elements/widgets/select_slider.py +568 -0
- streamlit/elements/widgets/selectbox.py +680 -0
- streamlit/elements/widgets/slider.py +1093 -0
- streamlit/elements/widgets/text_widgets.py +779 -0
- streamlit/elements/widgets/time_widgets.py +1712 -0
- streamlit/elements/write.py +585 -0
- streamlit/emojis.py +34 -0
- streamlit/env_util.py +56 -0
- streamlit/error_util.py +112 -0
- streamlit/errors.py +680 -0
- streamlit/external/__init__.py +13 -0
- streamlit/external/langchain/__init__.py +23 -0
- streamlit/external/langchain/streamlit_callback_handler.py +410 -0
- streamlit/file_util.py +266 -0
- streamlit/git_util.py +200 -0
- streamlit/hello/__init__.py +13 -0
- streamlit/hello/__pycache__/__init__.cpython-312.pyc +0 -0
- streamlit/hello/__pycache__/streamlit_app.cpython-312.pyc +0 -0
- streamlit/hello/animation_demo.py +82 -0
- streamlit/hello/dataframe_demo.py +71 -0
- streamlit/hello/hello.py +46 -0
- streamlit/hello/mapping_demo.py +113 -0
- streamlit/hello/plotting_demo.py +62 -0
- streamlit/hello/streamlit_app.py +57 -0
- streamlit/hello/utils.py +30 -0
- streamlit/logger.py +129 -0
- streamlit/material_icon_names.py +25 -0
- streamlit/navigation/__init__.py +13 -0
- streamlit/navigation/page.py +365 -0
- streamlit/net_util.py +125 -0
- streamlit/path_security.py +98 -0
- streamlit/platform.py +31 -0
- streamlit/proto/Alert_pb2.py +28 -0
- streamlit/proto/Alert_pb2.pyi +100 -0
- streamlit/proto/AppPage_pb2.py +25 -0
- streamlit/proto/AppPage_pb2.pyi +75 -0
- streamlit/proto/ArrowData_pb2.py +27 -0
- streamlit/proto/ArrowData_pb2.pyi +103 -0
- streamlit/proto/ArrowNamedDataSet_pb2.py +26 -0
- streamlit/proto/ArrowNamedDataSet_pb2.pyi +65 -0
- streamlit/proto/AudioInput_pb2.py +26 -0
- streamlit/proto/AudioInput_pb2.pyi +72 -0
- streamlit/proto/Audio_pb2.py +26 -0
- streamlit/proto/Audio_pb2.pyi +75 -0
- streamlit/proto/AuthRedirect_pb2.py +25 -0
- streamlit/proto/AuthRedirect_pb2.pyi +48 -0
- streamlit/proto/AutoRerun_pb2.py +25 -0
- streamlit/proto/AutoRerun_pb2.pyi +52 -0
- streamlit/proto/BackMsg_pb2.py +29 -0
- streamlit/proto/BackMsg_pb2.pyi +132 -0
- streamlit/proto/Balloons_pb2.py +25 -0
- streamlit/proto/Balloons_pb2.pyi +48 -0
- streamlit/proto/BidiComponent_pb2.py +32 -0
- streamlit/proto/BidiComponent_pb2.pyi +176 -0
- streamlit/proto/Block_pb2.py +62 -0
- streamlit/proto/Block_pb2.pyi +518 -0
- streamlit/proto/ButtonGroup_pb2.py +32 -0
- streamlit/proto/ButtonGroup_pb2.pyi +157 -0
- streamlit/proto/ButtonLikeIconPosition_pb2.py +25 -0
- streamlit/proto/ButtonLikeIconPosition_pb2.pyi +47 -0
- streamlit/proto/Button_pb2.py +26 -0
- streamlit/proto/Button_pb2.pyi +82 -0
- streamlit/proto/CameraInput_pb2.py +26 -0
- streamlit/proto/CameraInput_pb2.pyi +66 -0
- streamlit/proto/ChatInput_pb2.py +27 -0
- streamlit/proto/ChatInput_pb2.pyi +113 -0
- streamlit/proto/Checkbox_pb2.py +28 -0
- streamlit/proto/Checkbox_pb2.pyi +99 -0
- streamlit/proto/ClientState_pb2.py +28 -0
- streamlit/proto/ClientState_pb2.pyi +137 -0
- streamlit/proto/Code_pb2.py +25 -0
- streamlit/proto/Code_pb2.pyi +59 -0
- streamlit/proto/ColorPicker_pb2.py +26 -0
- streamlit/proto/ColorPicker_pb2.pyi +82 -0
- streamlit/proto/Common_pb2.py +49 -0
- streamlit/proto/Common_pb2.pyi +325 -0
- streamlit/proto/Components_pb2.py +33 -0
- streamlit/proto/Components_pb2.pyi +196 -0
- streamlit/proto/Dataframe_pb2.py +30 -0
- streamlit/proto/Dataframe_pb2.pyi +172 -0
- streamlit/proto/DateInput_pb2.py +26 -0
- streamlit/proto/DateInput_pb2.pyi +91 -0
- streamlit/proto/DateTimeInput_pb2.py +26 -0
- streamlit/proto/DateTimeInput_pb2.pyi +94 -0
- streamlit/proto/DeckGlJsonChart_pb2.py +27 -0
- streamlit/proto/DeckGlJsonChart_pb2.pyi +91 -0
- streamlit/proto/Delta_pb2.py +29 -0
- streamlit/proto/Delta_pb2.pyi +82 -0
- streamlit/proto/DownloadButton_pb2.py +26 -0
- streamlit/proto/DownloadButton_pb2.pyi +92 -0
- streamlit/proto/Element_pb2.py +81 -0
- streamlit/proto/Element_pb2.pyi +348 -0
- streamlit/proto/Empty_pb2.py +25 -0
- streamlit/proto/Empty_pb2.pyi +42 -0
- streamlit/proto/Exception_pb2.py +26 -0
- streamlit/proto/Exception_pb2.pyi +88 -0
- streamlit/proto/Favicon_pb2.py +25 -0
- streamlit/proto/Favicon_pb2.pyi +47 -0
- streamlit/proto/Feedback_pb2.py +27 -0
- streamlit/proto/Feedback_pb2.pyi +93 -0
- streamlit/proto/FileUploader_pb2.py +26 -0
- streamlit/proto/FileUploader_pb2.pyi +90 -0
- streamlit/proto/ForwardMsg_pb2.py +48 -0
- streamlit/proto/ForwardMsg_pb2.pyi +296 -0
- streamlit/proto/GapSize_pb2.py +27 -0
- streamlit/proto/GapSize_pb2.pyi +82 -0
- streamlit/proto/GitInfo_pb2.py +27 -0
- streamlit/proto/GitInfo_pb2.pyi +84 -0
- streamlit/proto/GraphVizChart_pb2.py +25 -0
- streamlit/proto/GraphVizChart_pb2.pyi +56 -0
- streamlit/proto/Heading_pb2.py +25 -0
- streamlit/proto/Heading_pb2.pyi +63 -0
- streamlit/proto/HeightConfig_pb2.py +25 -0
- streamlit/proto/HeightConfig_pb2.pyi +61 -0
- streamlit/proto/Help_pb2.py +27 -0
- streamlit/proto/Help_pb2.pyi +104 -0
- streamlit/proto/Html_pb2.py +25 -0
- streamlit/proto/Html_pb2.pyi +52 -0
- streamlit/proto/IFrame_pb2.py +25 -0
- streamlit/proto/IFrame_pb2.pyi +68 -0
- streamlit/proto/Image_pb2.py +27 -0
- streamlit/proto/Image_pb2.pyi +73 -0
- streamlit/proto/Json_pb2.py +25 -0
- streamlit/proto/Json_pb2.pyi +63 -0
- streamlit/proto/LabelVisibility_pb2.py +27 -0
- streamlit/proto/LabelVisibility_pb2.pyi +69 -0
- streamlit/proto/LinkButton_pb2.py +26 -0
- streamlit/proto/LinkButton_pb2.pyi +76 -0
- streamlit/proto/Logo_pb2.py +27 -0
- streamlit/proto/Logo_pb2.pyi +82 -0
- streamlit/proto/Markdown_pb2.py +27 -0
- streamlit/proto/Markdown_pb2.pyi +83 -0
- streamlit/proto/Metric_pb2.py +32 -0
- streamlit/proto/Metric_pb2.pyi +145 -0
- streamlit/proto/MetricsEvent_pb2.py +28 -0
- streamlit/proto/MetricsEvent_pb2.pyi +224 -0
- streamlit/proto/MultiSelect_pb2.py +26 -0
- streamlit/proto/MultiSelect_pb2.pyi +108 -0
- streamlit/proto/Navigation_pb2.py +28 -0
- streamlit/proto/Navigation_pb2.pyi +89 -0
- streamlit/proto/NewSession_pb2.py +47 -0
- streamlit/proto/NewSession_pb2.pyi +753 -0
- streamlit/proto/NumberInput_pb2.py +28 -0
- streamlit/proto/NumberInput_pb2.pyi +138 -0
- streamlit/proto/PageConfig_pb2.py +33 -0
- streamlit/proto/PageConfig_pb2.pyi +179 -0
- streamlit/proto/PageInfo_pb2.py +25 -0
- streamlit/proto/PageInfo_pb2.pyi +50 -0
- streamlit/proto/PageLink_pb2.py +26 -0
- streamlit/proto/PageLink_pb2.pyi +80 -0
- streamlit/proto/PageNotFound_pb2.py +25 -0
- streamlit/proto/PageNotFound_pb2.pyi +49 -0
- streamlit/proto/PageProfile_pb2.py +29 -0
- streamlit/proto/PageProfile_pb2.pyi +146 -0
- streamlit/proto/ParentMessage_pb2.py +25 -0
- streamlit/proto/ParentMessage_pb2.pyi +53 -0
- streamlit/proto/PlotlyChart_pb2.py +27 -0
- streamlit/proto/PlotlyChart_pb2.pyi +96 -0
- streamlit/proto/Progress_pb2.py +25 -0
- streamlit/proto/Progress_pb2.pyi +50 -0
- streamlit/proto/Radio_pb2.py +26 -0
- streamlit/proto/Radio_pb2.pyi +104 -0
- streamlit/proto/RootContainer_pb2.py +25 -0
- streamlit/proto/RootContainer_pb2.pyi +56 -0
- streamlit/proto/Selectbox_pb2.py +26 -0
- streamlit/proto/Selectbox_pb2.pyi +107 -0
- streamlit/proto/SessionEvent_pb2.py +26 -0
- streamlit/proto/SessionEvent_pb2.pyi +72 -0
- streamlit/proto/SessionStatus_pb2.py +25 -0
- streamlit/proto/SessionStatus_pb2.pyi +64 -0
- streamlit/proto/Skeleton_pb2.py +27 -0
- streamlit/proto/Skeleton_pb2.pyi +75 -0
- streamlit/proto/Slider_pb2.py +30 -0
- streamlit/proto/Slider_pb2.pyi +161 -0
- streamlit/proto/Snow_pb2.py +25 -0
- streamlit/proto/Snow_pb2.pyi +48 -0
- streamlit/proto/Space_pb2.py +25 -0
- streamlit/proto/Space_pb2.pyi +48 -0
- streamlit/proto/Spinner_pb2.py +25 -0
- streamlit/proto/Spinner_pb2.pyi +56 -0
- streamlit/proto/Table_pb2.py +28 -0
- streamlit/proto/Table_pb2.pyi +83 -0
- streamlit/proto/TextAlignmentConfig_pb2.py +27 -0
- streamlit/proto/TextAlignmentConfig_pb2.pyi +69 -0
- streamlit/proto/TextArea_pb2.py +26 -0
- streamlit/proto/TextArea_pb2.pyi +97 -0
- streamlit/proto/TextInput_pb2.py +28 -0
- streamlit/proto/TextInput_pb2.pyi +124 -0
- streamlit/proto/Text_pb2.py +25 -0
- streamlit/proto/Text_pb2.pyi +53 -0
- streamlit/proto/TimeInput_pb2.py +26 -0
- streamlit/proto/TimeInput_pb2.pyi +86 -0
- streamlit/proto/Toast_pb2.py +25 -0
- streamlit/proto/Toast_pb2.pyi +64 -0
- streamlit/proto/Transient_pb2.py +26 -0
- streamlit/proto/Transient_pb2.pyi +53 -0
- streamlit/proto/VegaLiteChart_pb2.py +27 -0
- streamlit/proto/VegaLiteChart_pb2.pyi +92 -0
- streamlit/proto/Video_pb2.py +30 -0
- streamlit/proto/Video_pb2.pyi +129 -0
- streamlit/proto/WidgetStates_pb2.py +31 -0
- streamlit/proto/WidgetStates_pb2.pyi +157 -0
- streamlit/proto/WidthConfig_pb2.py +25 -0
- streamlit/proto/WidthConfig_pb2.pyi +61 -0
- streamlit/proto/__init__.py +15 -0
- streamlit/proto/openmetrics_data_model_pb2.py +58 -0
- streamlit/proto/openmetrics_data_model_pb2.pyi +558 -0
- streamlit/py.typed +0 -0
- streamlit/runtime/__init__.py +50 -0
- streamlit/runtime/app_session.py +1302 -0
- streamlit/runtime/caching/__init__.py +118 -0
- streamlit/runtime/caching/cache_data_api.py +775 -0
- streamlit/runtime/caching/cache_errors.py +143 -0
- streamlit/runtime/caching/cache_resource_api.py +756 -0
- streamlit/runtime/caching/cache_type.py +33 -0
- streamlit/runtime/caching/cache_utils.py +601 -0
- streamlit/runtime/caching/cached_message_replay.py +290 -0
- streamlit/runtime/caching/hashing.py +655 -0
- streamlit/runtime/caching/legacy_cache_api.py +170 -0
- streamlit/runtime/caching/storage/__init__.py +29 -0
- streamlit/runtime/caching/storage/cache_storage_protocol.py +236 -0
- streamlit/runtime/caching/storage/dummy_cache_storage.py +60 -0
- streamlit/runtime/caching/storage/in_memory_cache_storage_wrapper.py +159 -0
- streamlit/runtime/caching/storage/local_disk_cache_storage.py +223 -0
- streamlit/runtime/caching/ttl_cleanup_cache.py +85 -0
- streamlit/runtime/connection_factory.py +498 -0
- streamlit/runtime/context.py +449 -0
- streamlit/runtime/context_util.py +49 -0
- streamlit/runtime/credentials.py +355 -0
- streamlit/runtime/download_data_util.py +53 -0
- streamlit/runtime/forward_msg_cache.py +101 -0
- streamlit/runtime/forward_msg_queue.py +263 -0
- streamlit/runtime/fragment.py +441 -0
- streamlit/runtime/media_file_manager.py +409 -0
- streamlit/runtime/media_file_storage.py +143 -0
- streamlit/runtime/memory_media_file_storage.py +201 -0
- streamlit/runtime/memory_session_storage.py +77 -0
- streamlit/runtime/memory_uploaded_file_manager.py +149 -0
- streamlit/runtime/metrics_util.py +612 -0
- streamlit/runtime/pages_manager.py +160 -0
- streamlit/runtime/runtime.py +775 -0
- streamlit/runtime/runtime_util.py +108 -0
- streamlit/runtime/script_data.py +46 -0
- streamlit/runtime/scriptrunner/__init__.py +38 -0
- streamlit/runtime/scriptrunner/exec_code.py +167 -0
- streamlit/runtime/scriptrunner/magic.py +277 -0
- streamlit/runtime/scriptrunner/magic_funcs.py +32 -0
- streamlit/runtime/scriptrunner/script_cache.py +89 -0
- streamlit/runtime/scriptrunner/script_runner.py +805 -0
- streamlit/runtime/scriptrunner_utils/__init__.py +19 -0
- streamlit/runtime/scriptrunner_utils/exceptions.py +44 -0
- streamlit/runtime/scriptrunner_utils/script_requests.py +311 -0
- streamlit/runtime/scriptrunner_utils/script_run_context.py +277 -0
- streamlit/runtime/secrets.py +533 -0
- streamlit/runtime/session_manager.py +430 -0
- streamlit/runtime/state/__init__.py +47 -0
- streamlit/runtime/state/common.py +256 -0
- streamlit/runtime/state/presentation.py +85 -0
- streamlit/runtime/state/query_params.py +767 -0
- streamlit/runtime/state/query_params_proxy.py +222 -0
- streamlit/runtime/state/safe_session_state.py +146 -0
- streamlit/runtime/state/session_state.py +1299 -0
- streamlit/runtime/state/session_state_proxy.py +153 -0
- streamlit/runtime/state/widgets.py +197 -0
- streamlit/runtime/stats.py +356 -0
- streamlit/runtime/theme_util.py +148 -0
- streamlit/runtime/uploaded_file_manager.py +152 -0
- streamlit/runtime/websocket_session_manager.py +301 -0
- streamlit/source_util.py +97 -0
- streamlit/starlette.py +34 -0
- streamlit/string_util.py +264 -0
- streamlit/temporary_directory.py +67 -0
- streamlit/testing/__init__.py +13 -0
- streamlit/testing/v1/__init__.py +17 -0
- streamlit/testing/v1/app_test.py +1089 -0
- streamlit/testing/v1/element_tree.py +2272 -0
- streamlit/testing/v1/local_script_runner.py +176 -0
- streamlit/testing/v1/util.py +61 -0
- streamlit/time_util.py +73 -0
- streamlit/type_util.py +480 -0
- streamlit/url_util.py +120 -0
- streamlit/user_info.py +698 -0
- streamlit/util.py +108 -0
- streamlit/vendor/__init__.py +0 -0
- streamlit/vendor/pympler/__init__.py +0 -0
- streamlit/vendor/pympler/asizeof.py +2870 -0
- streamlit/version.py +18 -0
- streamlit/watcher/__init__.py +28 -0
- streamlit/watcher/event_based_path_watcher.py +500 -0
- streamlit/watcher/folder_black_list.py +82 -0
- streamlit/watcher/local_sources_watcher.py +297 -0
- streamlit/watcher/path_watcher.py +244 -0
- streamlit/watcher/polling_path_watcher.py +138 -0
- streamlit/watcher/util.py +223 -0
- streamlit/web/__init__.py +13 -0
- streamlit/web/bootstrap.py +463 -0
- streamlit/web/cache_storage_manager_config.py +38 -0
- streamlit/web/cli.py +465 -0
- streamlit/web/server/__init__.py +30 -0
- streamlit/web/server/app_discovery.py +422 -0
- streamlit/web/server/app_static_file_handler.py +102 -0
- streamlit/web/server/authlib_tornado_integration.py +125 -0
- streamlit/web/server/bidi_component_request_handler.py +193 -0
- streamlit/web/server/browser_websocket_handler.py +341 -0
- streamlit/web/server/component_file_utils.py +105 -0
- streamlit/web/server/component_request_handler.py +107 -0
- streamlit/web/server/media_file_handler.py +148 -0
- streamlit/web/server/oauth_authlib_routes.py +314 -0
- streamlit/web/server/oidc_mixin.py +138 -0
- streamlit/web/server/routes.py +257 -0
- streamlit/web/server/server.py +555 -0
- streamlit/web/server/server_util.py +235 -0
- streamlit/web/server/starlette/__init__.py +23 -0
- streamlit/web/server/starlette/starlette_app.py +541 -0
- streamlit/web/server/starlette/starlette_app_utils.py +306 -0
- streamlit/web/server/starlette/starlette_auth_routes.py +584 -0
- streamlit/web/server/starlette/starlette_gzip_middleware.py +121 -0
- streamlit/web/server/starlette/starlette_path_security_middleware.py +97 -0
- streamlit/web/server/starlette/starlette_routes.py +884 -0
- streamlit/web/server/starlette/starlette_server.py +496 -0
- streamlit/web/server/starlette/starlette_server_config.py +55 -0
- streamlit/web/server/starlette/starlette_static_routes.py +181 -0
- streamlit/web/server/starlette/starlette_websocket.py +560 -0
- streamlit/web/server/stats_request_handler.py +116 -0
- streamlit/web/server/upload_file_request_handler.py +158 -0
- streamlit/web/server/websocket_headers.py +56 -0
- streamlit_data_editor_plus-0.1.0.dist-info/METADATA +76 -0
- streamlit_data_editor_plus-0.1.0.dist-info/RECORD +456 -0
- streamlit_data_editor_plus-0.1.0.dist-info/WHEEL +5 -0
- streamlit_data_editor_plus-0.1.0.dist-info/entry_points.txt +2 -0
- streamlit_data_editor_plus-0.1.0.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1,206 @@
|
|
|
1
|
+
# Copyright (c) Streamlit Inc. (2018-2022) Snowflake Inc. (2022-2026)
|
|
2
|
+
#
|
|
3
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
4
|
+
# you may not use this file except in compliance with the License.
|
|
5
|
+
# You may obtain a copy of the License at
|
|
6
|
+
#
|
|
7
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
|
8
|
+
#
|
|
9
|
+
# Unless required by applicable law or agreed to in writing, software
|
|
10
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
11
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
12
|
+
# See the License for the specific language governing permissions and
|
|
13
|
+
# limitations under the License.
|
|
14
|
+
|
|
15
|
+
from __future__ import annotations
|
|
16
|
+
|
|
17
|
+
import contextlib
|
|
18
|
+
from typing import Final
|
|
19
|
+
|
|
20
|
+
# This is the streamlit theme for plotly where we pass in a template.data
|
|
21
|
+
# and a template.layout.
|
|
22
|
+
# Template.data is for changing specific graph properties in a general aspect
|
|
23
|
+
# such as Contour plots or Waterfall plots.
|
|
24
|
+
# Template.layout is for changing things such as the x axis and fonts and other
|
|
25
|
+
# general layout properties for general graphs.
|
|
26
|
+
# We pass in temporary colors to the frontend and the frontend will replace
|
|
27
|
+
# those colors because we want to change colors based on the background color.
|
|
28
|
+
# Start at #0000001 because developers may be likely to use #000000
|
|
29
|
+
CATEGORY_0: Final = "#000001"
|
|
30
|
+
CATEGORY_1: Final = "#000002"
|
|
31
|
+
CATEGORY_2: Final = "#000003"
|
|
32
|
+
CATEGORY_3: Final = "#000004"
|
|
33
|
+
CATEGORY_4: Final = "#000005"
|
|
34
|
+
CATEGORY_5: Final = "#000006"
|
|
35
|
+
CATEGORY_6: Final = "#000007"
|
|
36
|
+
CATEGORY_7: Final = "#000008"
|
|
37
|
+
CATEGORY_8: Final = "#000009"
|
|
38
|
+
CATEGORY_9: Final = "#000010"
|
|
39
|
+
|
|
40
|
+
SEQUENTIAL_0: Final = "#000011"
|
|
41
|
+
SEQUENTIAL_1: Final = "#000012"
|
|
42
|
+
SEQUENTIAL_2: Final = "#000013"
|
|
43
|
+
SEQUENTIAL_3: Final = "#000014"
|
|
44
|
+
SEQUENTIAL_4: Final = "#000015"
|
|
45
|
+
SEQUENTIAL_5: Final = "#000016"
|
|
46
|
+
SEQUENTIAL_6: Final = "#000017"
|
|
47
|
+
SEQUENTIAL_7: Final = "#000018"
|
|
48
|
+
SEQUENTIAL_8: Final = "#000019"
|
|
49
|
+
SEQUENTIAL_9: Final = "#000020"
|
|
50
|
+
|
|
51
|
+
DIVERGING_0: Final = "#000021"
|
|
52
|
+
DIVERGING_1: Final = "#000022"
|
|
53
|
+
DIVERGING_2: Final = "#000023"
|
|
54
|
+
DIVERGING_3: Final = "#000024"
|
|
55
|
+
DIVERGING_4: Final = "#000025"
|
|
56
|
+
DIVERGING_5: Final = "#000026"
|
|
57
|
+
DIVERGING_6: Final = "#000027"
|
|
58
|
+
DIVERGING_7: Final = "#000028"
|
|
59
|
+
DIVERGING_8: Final = "#000029"
|
|
60
|
+
DIVERGING_9: Final = "#000030"
|
|
61
|
+
|
|
62
|
+
INCREASING: Final = "#000032"
|
|
63
|
+
DECREASING: Final = "#000033"
|
|
64
|
+
TOTAL: Final = "#000034"
|
|
65
|
+
|
|
66
|
+
GRAY_70: Final = "#000036"
|
|
67
|
+
GRAY_90: Final = "#000037"
|
|
68
|
+
BG_COLOR: Final = "#000038"
|
|
69
|
+
FADED_TEXT_05: Final = "#000039"
|
|
70
|
+
BG_MIX: Final = "#000040"
|
|
71
|
+
|
|
72
|
+
|
|
73
|
+
def configure_streamlit_plotly_theme() -> None:
|
|
74
|
+
"""Configure the Streamlit chart theme for Plotly.
|
|
75
|
+
|
|
76
|
+
The theme is only configured if Plotly is installed.
|
|
77
|
+
"""
|
|
78
|
+
# We do nothing if Plotly is not installed. This is expected since Plotly is an optional dependency.
|
|
79
|
+
with contextlib.suppress(ImportError):
|
|
80
|
+
import plotly.graph_objects as go
|
|
81
|
+
import plotly.io as pio
|
|
82
|
+
|
|
83
|
+
# Plotly represents continuous colorscale through an array of pairs.
|
|
84
|
+
# The pair's first index is the starting point and the next pair's first index is the end point.
|
|
85
|
+
# The pair's second index is the starting color and the next pair's second index is the end color.
|
|
86
|
+
# For more information, please refer to https://plotly.com/python/colorscales/
|
|
87
|
+
|
|
88
|
+
streamlit_colorscale = [
|
|
89
|
+
[0.0, SEQUENTIAL_0],
|
|
90
|
+
[0.1111111111111111, SEQUENTIAL_1],
|
|
91
|
+
[0.2222222222222222, SEQUENTIAL_2],
|
|
92
|
+
[0.3333333333333333, SEQUENTIAL_3],
|
|
93
|
+
[0.4444444444444444, SEQUENTIAL_4],
|
|
94
|
+
[0.5555555555555556, SEQUENTIAL_5],
|
|
95
|
+
[0.6666666666666666, SEQUENTIAL_6],
|
|
96
|
+
[0.7777777777777778, SEQUENTIAL_7],
|
|
97
|
+
[0.8888888888888888, SEQUENTIAL_8],
|
|
98
|
+
[1.0, SEQUENTIAL_9],
|
|
99
|
+
]
|
|
100
|
+
|
|
101
|
+
pio.templates["streamlit"] = go.layout.Template(
|
|
102
|
+
data=go.layout.template.Data(
|
|
103
|
+
candlestick=[
|
|
104
|
+
go.layout.template.data.Candlestick(
|
|
105
|
+
decreasing=go.candlestick.Decreasing(
|
|
106
|
+
line=go.candlestick.decreasing.Line(color=DECREASING)
|
|
107
|
+
),
|
|
108
|
+
increasing=go.candlestick.Increasing(
|
|
109
|
+
line=go.candlestick.increasing.Line(color=INCREASING)
|
|
110
|
+
),
|
|
111
|
+
)
|
|
112
|
+
],
|
|
113
|
+
contour=[
|
|
114
|
+
go.layout.template.data.Contour(colorscale=streamlit_colorscale)
|
|
115
|
+
],
|
|
116
|
+
contourcarpet=[
|
|
117
|
+
go.layout.template.data.Contourcarpet(
|
|
118
|
+
colorscale=streamlit_colorscale
|
|
119
|
+
)
|
|
120
|
+
],
|
|
121
|
+
heatmap=[
|
|
122
|
+
go.layout.template.data.Heatmap(colorscale=streamlit_colorscale)
|
|
123
|
+
],
|
|
124
|
+
histogram2d=[
|
|
125
|
+
go.layout.template.data.Histogram2d(colorscale=streamlit_colorscale)
|
|
126
|
+
],
|
|
127
|
+
icicle=[
|
|
128
|
+
go.layout.template.data.Icicle(
|
|
129
|
+
textfont=go.icicle.Textfont(color="white")
|
|
130
|
+
)
|
|
131
|
+
],
|
|
132
|
+
sankey=[
|
|
133
|
+
go.layout.template.data.Sankey(
|
|
134
|
+
textfont=go.sankey.Textfont(color=GRAY_70)
|
|
135
|
+
)
|
|
136
|
+
],
|
|
137
|
+
scatter=[
|
|
138
|
+
go.layout.template.data.Scatter(
|
|
139
|
+
marker=go.scatter.Marker(line=go.scatter.marker.Line(width=0))
|
|
140
|
+
)
|
|
141
|
+
],
|
|
142
|
+
table=[
|
|
143
|
+
go.layout.template.data.Table(
|
|
144
|
+
cells=go.table.Cells(
|
|
145
|
+
fill=go.table.cells.Fill(color=BG_COLOR),
|
|
146
|
+
font=go.table.cells.Font(color=GRAY_90),
|
|
147
|
+
line=go.table.cells.Line(color=FADED_TEXT_05),
|
|
148
|
+
),
|
|
149
|
+
header=go.table.Header(
|
|
150
|
+
font=go.table.header.Font(color=GRAY_70),
|
|
151
|
+
line=go.table.header.Line(color=FADED_TEXT_05),
|
|
152
|
+
fill=go.table.header.Fill(color=BG_MIX),
|
|
153
|
+
),
|
|
154
|
+
)
|
|
155
|
+
],
|
|
156
|
+
waterfall=[
|
|
157
|
+
go.layout.template.data.Waterfall(
|
|
158
|
+
increasing=go.waterfall.Increasing(
|
|
159
|
+
marker=go.waterfall.increasing.Marker(color=INCREASING)
|
|
160
|
+
),
|
|
161
|
+
decreasing=go.waterfall.Decreasing(
|
|
162
|
+
marker=go.waterfall.decreasing.Marker(color=DECREASING)
|
|
163
|
+
),
|
|
164
|
+
totals=go.waterfall.Totals(
|
|
165
|
+
marker=go.waterfall.totals.Marker(color=TOTAL)
|
|
166
|
+
),
|
|
167
|
+
connector=go.waterfall.Connector(
|
|
168
|
+
line=go.waterfall.connector.Line(color=GRAY_70, width=2)
|
|
169
|
+
),
|
|
170
|
+
)
|
|
171
|
+
],
|
|
172
|
+
),
|
|
173
|
+
layout=go.Layout(
|
|
174
|
+
colorway=[
|
|
175
|
+
CATEGORY_0,
|
|
176
|
+
CATEGORY_1,
|
|
177
|
+
CATEGORY_2,
|
|
178
|
+
CATEGORY_3,
|
|
179
|
+
CATEGORY_4,
|
|
180
|
+
CATEGORY_5,
|
|
181
|
+
CATEGORY_6,
|
|
182
|
+
CATEGORY_7,
|
|
183
|
+
CATEGORY_8,
|
|
184
|
+
CATEGORY_9,
|
|
185
|
+
],
|
|
186
|
+
colorscale=go.layout.Colorscale(
|
|
187
|
+
sequential=streamlit_colorscale,
|
|
188
|
+
sequentialminus=streamlit_colorscale,
|
|
189
|
+
diverging=[
|
|
190
|
+
[0.0, DIVERGING_0],
|
|
191
|
+
[0.1111111111111111, DIVERGING_1],
|
|
192
|
+
[0.2222222222222222, DIVERGING_2],
|
|
193
|
+
[0.3333333333333333, DIVERGING_3],
|
|
194
|
+
[0.4444444444444444, DIVERGING_4],
|
|
195
|
+
[0.5555555555555556, DIVERGING_5],
|
|
196
|
+
[0.6666666666666666, DIVERGING_6],
|
|
197
|
+
[0.7777777777777778, DIVERGING_7],
|
|
198
|
+
[0.8888888888888888, DIVERGING_8],
|
|
199
|
+
[1.0, DIVERGING_9],
|
|
200
|
+
],
|
|
201
|
+
),
|
|
202
|
+
coloraxis=go.layout.Coloraxis(colorscale=streamlit_colorscale),
|
|
203
|
+
),
|
|
204
|
+
)
|
|
205
|
+
|
|
206
|
+
pio.templates.default = "streamlit"
|
|
@@ -0,0 +1,175 @@
|
|
|
1
|
+
# Copyright (c) Streamlit Inc. (2018-2022) Snowflake Inc. (2022-2026)
|
|
2
|
+
#
|
|
3
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
4
|
+
# you may not use this file except in compliance with the License.
|
|
5
|
+
# You may obtain a copy of the License at
|
|
6
|
+
#
|
|
7
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
|
8
|
+
#
|
|
9
|
+
# Unless required by applicable law or agreed to in writing, software
|
|
10
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
11
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
12
|
+
# See the License for the specific language governing permissions and
|
|
13
|
+
# limitations under the License.
|
|
14
|
+
|
|
15
|
+
from __future__ import annotations
|
|
16
|
+
|
|
17
|
+
import io
|
|
18
|
+
import os
|
|
19
|
+
import re
|
|
20
|
+
from pathlib import Path
|
|
21
|
+
|
|
22
|
+
from streamlit import runtime
|
|
23
|
+
from streamlit.runtime import caching
|
|
24
|
+
from streamlit.util import calc_md5
|
|
25
|
+
|
|
26
|
+
# Regular expression to match the SRT timestamp format
|
|
27
|
+
# It matches the
|
|
28
|
+
# "hours:minutes:seconds,milliseconds --> hours:minutes:seconds,milliseconds" format
|
|
29
|
+
SRT_VALIDATION_REGEX = r"\d{2}:\d{2}:\d{2},\d{3} --> \d{2}:\d{2}:\d{2},\d{3}"
|
|
30
|
+
|
|
31
|
+
SRT_CONVERSION_REGEX = r"(\d{2}:\d{2}:\d{2}),(\d{3})"
|
|
32
|
+
|
|
33
|
+
SUBTITLE_ALLOWED_FORMATS = (".srt", ".vtt")
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
def _is_srt(stream: str | io.BytesIO | bytes) -> bool:
|
|
37
|
+
# Handle raw bytes
|
|
38
|
+
if isinstance(stream, bytes):
|
|
39
|
+
stream = io.BytesIO(stream)
|
|
40
|
+
|
|
41
|
+
# Convert str to io.BytesIO if 'stream' is a string
|
|
42
|
+
if isinstance(stream, str):
|
|
43
|
+
stream = io.BytesIO(stream.encode("utf-8"))
|
|
44
|
+
|
|
45
|
+
# Set the stream position to the beginning in case it's been moved
|
|
46
|
+
stream.seek(0)
|
|
47
|
+
|
|
48
|
+
# Read enough bytes to reliably check for SRT patterns
|
|
49
|
+
# This might be adjusted, but 33 bytes should be enough to read the first numeric
|
|
50
|
+
# line, the full timestamp line, and a bit of the next line
|
|
51
|
+
header = stream.read(33)
|
|
52
|
+
|
|
53
|
+
try:
|
|
54
|
+
header_str = header.decode("utf-8").strip() # Decode and strip whitespace
|
|
55
|
+
except UnicodeDecodeError:
|
|
56
|
+
# If it's not valid utf-8, it's probably not a valid SRT file
|
|
57
|
+
return False
|
|
58
|
+
|
|
59
|
+
# Split the header into lines and process them
|
|
60
|
+
lines = header_str.split("\n")
|
|
61
|
+
|
|
62
|
+
# Check for the pattern of an SRT file: digit(s), newline, timestamp
|
|
63
|
+
if len(lines) >= 2 and lines[0].isdigit():
|
|
64
|
+
match = re.search(SRT_VALIDATION_REGEX, lines[1])
|
|
65
|
+
if match:
|
|
66
|
+
return True
|
|
67
|
+
|
|
68
|
+
return False
|
|
69
|
+
|
|
70
|
+
|
|
71
|
+
def _srt_to_vtt(srt_data: str | bytes) -> bytes:
|
|
72
|
+
"""
|
|
73
|
+
Convert subtitles from SubRip (.srt) format to WebVTT (.vtt) format.
|
|
74
|
+
This function accepts the content of the .srt file either as a string
|
|
75
|
+
or as a BytesIO stream.
|
|
76
|
+
|
|
77
|
+
Parameters
|
|
78
|
+
----------
|
|
79
|
+
srt_data : str or bytes
|
|
80
|
+
The content of the .srt file as a string or a bytes stream.
|
|
81
|
+
|
|
82
|
+
Returns
|
|
83
|
+
-------
|
|
84
|
+
bytes
|
|
85
|
+
The content converted into .vtt format.
|
|
86
|
+
"""
|
|
87
|
+
|
|
88
|
+
# If the input is a bytes stream, convert it to a string
|
|
89
|
+
if isinstance(srt_data, bytes):
|
|
90
|
+
# Decode the bytes to a UTF-8 string
|
|
91
|
+
try:
|
|
92
|
+
srt_data = srt_data.decode("utf-8")
|
|
93
|
+
except UnicodeDecodeError as e:
|
|
94
|
+
raise ValueError("Could not decode the input stream as UTF-8.") from e
|
|
95
|
+
if not isinstance(srt_data, str):
|
|
96
|
+
# If it's not a string by this point, something is wrong.
|
|
97
|
+
raise TypeError(
|
|
98
|
+
f"Input must be a string or a bytes stream, not {type(srt_data)}."
|
|
99
|
+
)
|
|
100
|
+
|
|
101
|
+
# Replace SubRip timing with WebVTT timing
|
|
102
|
+
vtt_data = re.sub(SRT_CONVERSION_REGEX, r"\1.\2", srt_data)
|
|
103
|
+
|
|
104
|
+
# Add WebVTT file header
|
|
105
|
+
vtt_content = "WEBVTT\n\n" + vtt_data
|
|
106
|
+
# Convert the vtt content to bytes
|
|
107
|
+
return vtt_content.strip().encode("utf-8")
|
|
108
|
+
|
|
109
|
+
|
|
110
|
+
def _handle_string_or_path_data(data_or_path: str | Path) -> bytes:
|
|
111
|
+
"""Handles string data, either as a file path or raw content."""
|
|
112
|
+
if os.path.isfile(data_or_path):
|
|
113
|
+
path = Path(data_or_path)
|
|
114
|
+
file_extension = path.suffix.lower()
|
|
115
|
+
|
|
116
|
+
if file_extension not in SUBTITLE_ALLOWED_FORMATS:
|
|
117
|
+
raise ValueError(
|
|
118
|
+
f"Incorrect subtitle format {file_extension}. Subtitles must be in "
|
|
119
|
+
f"one of the following formats: {', '.join(SUBTITLE_ALLOWED_FORMATS)}"
|
|
120
|
+
)
|
|
121
|
+
with open(data_or_path, "rb") as file:
|
|
122
|
+
content = file.read()
|
|
123
|
+
return _srt_to_vtt(content) if file_extension == ".srt" else content
|
|
124
|
+
if isinstance(data_or_path, Path):
|
|
125
|
+
raise ValueError(f"File {data_or_path} does not exist.") # noqa: TRY004
|
|
126
|
+
|
|
127
|
+
content_string = data_or_path.strip()
|
|
128
|
+
|
|
129
|
+
if content_string.startswith("WEBVTT") or content_string == "":
|
|
130
|
+
return content_string.encode("utf-8")
|
|
131
|
+
if _is_srt(content_string):
|
|
132
|
+
return _srt_to_vtt(content_string)
|
|
133
|
+
raise ValueError("The provided string neither matches valid VTT nor SRT format.")
|
|
134
|
+
|
|
135
|
+
|
|
136
|
+
def _handle_stream_data(stream: io.BytesIO) -> bytes:
|
|
137
|
+
"""Handles io.BytesIO data, converting SRT to VTT content if needed."""
|
|
138
|
+
stream.seek(0)
|
|
139
|
+
stream_data = stream.getvalue()
|
|
140
|
+
return _srt_to_vtt(stream_data) if _is_srt(stream) else stream_data
|
|
141
|
+
|
|
142
|
+
|
|
143
|
+
def _handle_bytes_data(data: bytes) -> bytes:
|
|
144
|
+
"""Handles io.BytesIO data, converting SRT to VTT content if needed."""
|
|
145
|
+
return _srt_to_vtt(data) if _is_srt(data) else data
|
|
146
|
+
|
|
147
|
+
|
|
148
|
+
def process_subtitle_data(
|
|
149
|
+
coordinates: str,
|
|
150
|
+
data: str | bytes | Path | io.BytesIO,
|
|
151
|
+
label: str,
|
|
152
|
+
) -> str:
|
|
153
|
+
# Determine the type of data and process accordingly
|
|
154
|
+
if isinstance(data, (str, Path)):
|
|
155
|
+
subtitle_data = _handle_string_or_path_data(data)
|
|
156
|
+
elif isinstance(data, io.BytesIO):
|
|
157
|
+
subtitle_data = _handle_stream_data(data)
|
|
158
|
+
elif isinstance(data, bytes):
|
|
159
|
+
subtitle_data = _handle_bytes_data(data)
|
|
160
|
+
else:
|
|
161
|
+
raise TypeError(f"Invalid binary data format for subtitle: {type(data)}.")
|
|
162
|
+
|
|
163
|
+
if runtime.exists():
|
|
164
|
+
filename = calc_md5(label.encode())
|
|
165
|
+
# Save the processed data and return the file URL
|
|
166
|
+
file_url = runtime.get_instance().media_file_mgr.add(
|
|
167
|
+
path_or_data=subtitle_data,
|
|
168
|
+
mimetype="text/vtt",
|
|
169
|
+
coordinates=coordinates,
|
|
170
|
+
file_name=f"{filename}.vtt",
|
|
171
|
+
)
|
|
172
|
+
caching.save_media_data(subtitle_data, "text/vtt", coordinates)
|
|
173
|
+
return file_url
|
|
174
|
+
# When running in "raw mode", we can't access the MediaFileManager.
|
|
175
|
+
return ""
|
|
@@ -0,0 +1,274 @@
|
|
|
1
|
+
# Copyright (c) Streamlit Inc. (2018-2022) Snowflake Inc. (2022-2026)
|
|
2
|
+
#
|
|
3
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
4
|
+
# you may not use this file except in compliance with the License.
|
|
5
|
+
# You may obtain a copy of the License at
|
|
6
|
+
#
|
|
7
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
|
8
|
+
#
|
|
9
|
+
# Unless required by applicable law or agreed to in writing, software
|
|
10
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
11
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
12
|
+
# See the License for the specific language governing permissions and
|
|
13
|
+
# limitations under the License.
|
|
14
|
+
|
|
15
|
+
from __future__ import annotations
|
|
16
|
+
|
|
17
|
+
import hashlib
|
|
18
|
+
from datetime import date, datetime, time, timedelta
|
|
19
|
+
from typing import (
|
|
20
|
+
TYPE_CHECKING,
|
|
21
|
+
Any,
|
|
22
|
+
Literal,
|
|
23
|
+
TypeAlias,
|
|
24
|
+
Union,
|
|
25
|
+
overload,
|
|
26
|
+
)
|
|
27
|
+
|
|
28
|
+
from google.protobuf.message import Message
|
|
29
|
+
|
|
30
|
+
from streamlit import config
|
|
31
|
+
from streamlit.elements.lib.form_utils import current_form_id
|
|
32
|
+
from streamlit.errors import StreamlitDuplicateElementId, StreamlitDuplicateElementKey
|
|
33
|
+
from streamlit.proto.ChatInput_pb2 import ChatInput
|
|
34
|
+
from streamlit.proto.LabelVisibility_pb2 import LabelVisibility as LabelVisibilityProto
|
|
35
|
+
from streamlit.runtime.scriptrunner_utils.script_run_context import (
|
|
36
|
+
ScriptRunContext,
|
|
37
|
+
get_script_run_ctx,
|
|
38
|
+
)
|
|
39
|
+
from streamlit.runtime.state.common import (
|
|
40
|
+
GENERATED_ELEMENT_ID_PREFIX,
|
|
41
|
+
TESTING_KEY,
|
|
42
|
+
user_key_from_element_id,
|
|
43
|
+
)
|
|
44
|
+
|
|
45
|
+
if TYPE_CHECKING:
|
|
46
|
+
from builtins import ellipsis
|
|
47
|
+
from collections.abc import Iterable
|
|
48
|
+
|
|
49
|
+
from streamlit.delta_generator import DeltaGenerator
|
|
50
|
+
|
|
51
|
+
|
|
52
|
+
Key: TypeAlias = str | int
|
|
53
|
+
|
|
54
|
+
LabelVisibility: TypeAlias = Literal["visible", "hidden", "collapsed"]
|
|
55
|
+
|
|
56
|
+
PROTO_SCALAR_VALUE: TypeAlias = float | int | bool | str | bytes
|
|
57
|
+
SAFE_VALUES: TypeAlias = Union[
|
|
58
|
+
date,
|
|
59
|
+
time,
|
|
60
|
+
datetime,
|
|
61
|
+
timedelta,
|
|
62
|
+
"ellipsis",
|
|
63
|
+
Message,
|
|
64
|
+
PROTO_SCALAR_VALUE,
|
|
65
|
+
None,
|
|
66
|
+
]
|
|
67
|
+
|
|
68
|
+
|
|
69
|
+
def get_label_visibility_proto_value(
|
|
70
|
+
label_visibility_string: LabelVisibility,
|
|
71
|
+
) -> LabelVisibilityProto.LabelVisibilityOptions.ValueType:
|
|
72
|
+
"""Returns one of LabelVisibilityProto enum constants based on string value."""
|
|
73
|
+
|
|
74
|
+
if label_visibility_string == "visible":
|
|
75
|
+
return LabelVisibilityProto.LabelVisibilityOptions.VISIBLE
|
|
76
|
+
if label_visibility_string == "hidden":
|
|
77
|
+
return LabelVisibilityProto.LabelVisibilityOptions.HIDDEN
|
|
78
|
+
if label_visibility_string == "collapsed":
|
|
79
|
+
return LabelVisibilityProto.LabelVisibilityOptions.COLLAPSED
|
|
80
|
+
|
|
81
|
+
raise ValueError(f"Unknown label visibility value: {label_visibility_string}")
|
|
82
|
+
|
|
83
|
+
|
|
84
|
+
def get_chat_input_accept_file_proto_value(
|
|
85
|
+
accept_file_value: Literal["multiple", "directory"] | bool,
|
|
86
|
+
) -> ChatInput.AcceptFile.ValueType:
|
|
87
|
+
"""Returns one of ChatInput.AcceptFile enum value based on string value."""
|
|
88
|
+
|
|
89
|
+
if accept_file_value is False:
|
|
90
|
+
return ChatInput.AcceptFile.NONE
|
|
91
|
+
if accept_file_value is True:
|
|
92
|
+
return ChatInput.AcceptFile.SINGLE
|
|
93
|
+
if accept_file_value == "multiple":
|
|
94
|
+
return ChatInput.AcceptFile.MULTIPLE
|
|
95
|
+
if accept_file_value == "directory":
|
|
96
|
+
return ChatInput.AcceptFile.DIRECTORY
|
|
97
|
+
|
|
98
|
+
raise ValueError(f"Unknown accept file value: {accept_file_value}")
|
|
99
|
+
|
|
100
|
+
|
|
101
|
+
@overload
|
|
102
|
+
def to_key(key: None) -> None: ...
|
|
103
|
+
|
|
104
|
+
|
|
105
|
+
@overload
|
|
106
|
+
def to_key(key: Key) -> str: ...
|
|
107
|
+
|
|
108
|
+
|
|
109
|
+
def to_key(key: Key | None) -> str | None:
|
|
110
|
+
return None if key is None else str(key)
|
|
111
|
+
|
|
112
|
+
|
|
113
|
+
def _register_element_id(
|
|
114
|
+
ctx: ScriptRunContext, element_type: str, element_id: str
|
|
115
|
+
) -> None:
|
|
116
|
+
"""Register the element ID and key for the given element.
|
|
117
|
+
|
|
118
|
+
If the element ID or key is not unique, an error is raised.
|
|
119
|
+
|
|
120
|
+
Parameters
|
|
121
|
+
----------
|
|
122
|
+
element_type : str
|
|
123
|
+
The type of the element to register.
|
|
124
|
+
|
|
125
|
+
element_id : str
|
|
126
|
+
The ID of the element to register.
|
|
127
|
+
|
|
128
|
+
Raises
|
|
129
|
+
------
|
|
130
|
+
StreamlitDuplicateElementKey
|
|
131
|
+
If the element key is not unique.
|
|
132
|
+
|
|
133
|
+
StreamlitDuplicateElementID
|
|
134
|
+
If the element ID is not unique.
|
|
135
|
+
|
|
136
|
+
"""
|
|
137
|
+
|
|
138
|
+
if not element_id:
|
|
139
|
+
return
|
|
140
|
+
|
|
141
|
+
if user_key := user_key_from_element_id(element_id):
|
|
142
|
+
if user_key not in ctx.widget_user_keys_this_run:
|
|
143
|
+
ctx.widget_user_keys_this_run.add(user_key)
|
|
144
|
+
else:
|
|
145
|
+
raise StreamlitDuplicateElementKey(user_key)
|
|
146
|
+
|
|
147
|
+
if element_id not in ctx.widget_ids_this_run:
|
|
148
|
+
ctx.widget_ids_this_run.add(element_id)
|
|
149
|
+
else:
|
|
150
|
+
raise StreamlitDuplicateElementId(element_type)
|
|
151
|
+
|
|
152
|
+
|
|
153
|
+
def _compute_element_id(
|
|
154
|
+
element_type: str,
|
|
155
|
+
user_key: str | None = None,
|
|
156
|
+
**kwargs: SAFE_VALUES | Iterable[SAFE_VALUES],
|
|
157
|
+
) -> str:
|
|
158
|
+
"""Compute the ID for the given element.
|
|
159
|
+
|
|
160
|
+
This ID is stable: a given set of inputs to this function will always produce
|
|
161
|
+
the same ID output. Only stable, deterministic values should be used to compute
|
|
162
|
+
element IDs. Using nondeterministic values as inputs can cause the resulting
|
|
163
|
+
element ID to change between runs.
|
|
164
|
+
|
|
165
|
+
The element ID includes the user_key so elements with identical arguments can
|
|
166
|
+
use it to be distinct. The element ID includes an easily identified prefix, and the
|
|
167
|
+
user_key as a suffix, to make it easy to identify it and know if a key maps to it.
|
|
168
|
+
"""
|
|
169
|
+
h = hashlib.new("md5", usedforsecurity=False)
|
|
170
|
+
h.update(element_type.encode("utf-8"))
|
|
171
|
+
if user_key:
|
|
172
|
+
# Adding this to the hash isn't necessary for uniqueness since the
|
|
173
|
+
# key is also appended to the ID as raw text. But since the hash and
|
|
174
|
+
# the appending of the key are two slightly different aspects, it
|
|
175
|
+
# still gets put into the hash.
|
|
176
|
+
h.update(user_key.encode("utf-8"))
|
|
177
|
+
# This will iterate in a consistent order when the provided arguments have
|
|
178
|
+
# consistent order; dicts are always in insertion order.
|
|
179
|
+
for k, v in kwargs.items():
|
|
180
|
+
h.update(str(k).encode("utf-8"))
|
|
181
|
+
h.update(str(v).encode("utf-8"))
|
|
182
|
+
return f"{GENERATED_ELEMENT_ID_PREFIX}-{h.hexdigest()}-{user_key}"
|
|
183
|
+
|
|
184
|
+
|
|
185
|
+
def compute_and_register_element_id(
|
|
186
|
+
element_type: str,
|
|
187
|
+
*,
|
|
188
|
+
user_key: str | None,
|
|
189
|
+
dg: DeltaGenerator | None,
|
|
190
|
+
key_as_main_identity: bool | set[str],
|
|
191
|
+
**kwargs: SAFE_VALUES | Iterable[SAFE_VALUES],
|
|
192
|
+
) -> str:
|
|
193
|
+
"""Compute and register the ID for the given element.
|
|
194
|
+
|
|
195
|
+
This ID is stable: a given set of inputs to this function will always produce
|
|
196
|
+
the same ID output. Only stable, deterministic values should be used to compute
|
|
197
|
+
element IDs. Using nondeterministic values as inputs can cause the resulting
|
|
198
|
+
element ID to change between runs.
|
|
199
|
+
|
|
200
|
+
The element ID includes the user_key so elements with identical arguments can
|
|
201
|
+
use it to be distinct. The element ID includes an easily identified prefix, and the
|
|
202
|
+
user_key as a suffix, to make it easy to identify it and know if a key maps to it.
|
|
203
|
+
|
|
204
|
+
The element ID gets registered to make sure that only one ID and user-specified
|
|
205
|
+
key exists at the same time. If there are duplicated IDs or keys, an error
|
|
206
|
+
is raised.
|
|
207
|
+
|
|
208
|
+
Parameters
|
|
209
|
+
----------
|
|
210
|
+
element_type : str
|
|
211
|
+
The type (command name) of the element to register.
|
|
212
|
+
|
|
213
|
+
user_key : str | None
|
|
214
|
+
The user-specified key for the element. `None` if no key is provided
|
|
215
|
+
or if the element doesn't support a specifying a key.
|
|
216
|
+
|
|
217
|
+
dg : DeltaGenerator | None
|
|
218
|
+
The DeltaGenerator of each element. `None` if the element is not a widget.
|
|
219
|
+
|
|
220
|
+
kwargs : SAFE_VALUES | Iterable[SAFE_VALUES]
|
|
221
|
+
The arguments to use to compute the element ID.
|
|
222
|
+
The arguments must be stable, deterministic values.
|
|
223
|
+
Some common parameters like key, disabled,
|
|
224
|
+
format_func, label_visibility, args, kwargs, on_change, and
|
|
225
|
+
the active_script_hash are not supposed to be added here
|
|
226
|
+
|
|
227
|
+
key_as_main_identity : bool | set[str]
|
|
228
|
+
If True and a key is provided by the user, we don't include
|
|
229
|
+
command kwargs in the element ID computation.
|
|
230
|
+
If a set of kwarg names is provided and a key is provided,
|
|
231
|
+
only the kwargs with names in this set will be included
|
|
232
|
+
in the element ID computation.
|
|
233
|
+
"""
|
|
234
|
+
ctx = get_script_run_ctx()
|
|
235
|
+
|
|
236
|
+
# When a user_key is present and key_as_main_identity is True OR a set (even empty),
|
|
237
|
+
# we should ignore general command kwargs and form/sidebar context. For the set case,
|
|
238
|
+
# only explicitly whitelisted kwargs will be included below.
|
|
239
|
+
ignore_command_kwargs = user_key is not None and (
|
|
240
|
+
(key_as_main_identity is True) or isinstance(key_as_main_identity, set)
|
|
241
|
+
)
|
|
242
|
+
|
|
243
|
+
if isinstance(key_as_main_identity, set) and user_key:
|
|
244
|
+
# Only include the explicitly whitelisted kwargs in the computation
|
|
245
|
+
kwargs_to_use = {k: v for k, v in kwargs.items() if k in key_as_main_identity}
|
|
246
|
+
else:
|
|
247
|
+
kwargs_to_use = {} if ignore_command_kwargs else {**kwargs}
|
|
248
|
+
|
|
249
|
+
if ctx:
|
|
250
|
+
# Add the active script hash to give elements on different
|
|
251
|
+
# pages unique IDs. This is added even if
|
|
252
|
+
# key_as_main_identity is specified.
|
|
253
|
+
kwargs_to_use["active_script_hash"] = ctx.active_script_hash
|
|
254
|
+
|
|
255
|
+
if dg and not ignore_command_kwargs:
|
|
256
|
+
kwargs_to_use["form_id"] = current_form_id(dg)
|
|
257
|
+
# If no key is provided and the widget element is inside the sidebar area
|
|
258
|
+
# add it to the kwargs
|
|
259
|
+
# allowing the same widget to be both in main area and sidebar.
|
|
260
|
+
kwargs_to_use["active_dg_root_container"] = dg._active_dg._root_container
|
|
261
|
+
|
|
262
|
+
element_id = _compute_element_id(element_type, user_key, **kwargs_to_use)
|
|
263
|
+
|
|
264
|
+
if ctx:
|
|
265
|
+
_register_element_id(ctx, element_type, element_id)
|
|
266
|
+
return element_id
|
|
267
|
+
|
|
268
|
+
|
|
269
|
+
def save_for_app_testing(ctx: ScriptRunContext, k: str, v: Any) -> None:
|
|
270
|
+
if config.get_option("global.appTest"):
|
|
271
|
+
try:
|
|
272
|
+
ctx.session_state[TESTING_KEY][k] = v
|
|
273
|
+
except KeyError:
|
|
274
|
+
ctx.session_state[TESTING_KEY] = {k: v}
|