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,325 @@
|
|
|
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
|
+
from __future__ import annotations
|
|
15
|
+
|
|
16
|
+
from dataclasses import dataclass
|
|
17
|
+
from typing import Literal, TypeAlias, cast
|
|
18
|
+
|
|
19
|
+
from streamlit.errors import (
|
|
20
|
+
StreamlitInvalidColumnGapError,
|
|
21
|
+
StreamlitInvalidHeightError,
|
|
22
|
+
StreamlitInvalidHorizontalAlignmentError,
|
|
23
|
+
StreamlitInvalidSizeError,
|
|
24
|
+
StreamlitInvalidTextAlignmentError,
|
|
25
|
+
StreamlitInvalidVerticalAlignmentError,
|
|
26
|
+
StreamlitInvalidWidthError,
|
|
27
|
+
)
|
|
28
|
+
from streamlit.proto.Block_pb2 import Block
|
|
29
|
+
from streamlit.proto.GapSize_pb2 import GapSize
|
|
30
|
+
from streamlit.proto.HeightConfig_pb2 import HeightConfig
|
|
31
|
+
from streamlit.proto.TextAlignmentConfig_pb2 import TextAlignmentConfig
|
|
32
|
+
from streamlit.proto.WidthConfig_pb2 import WidthConfig
|
|
33
|
+
|
|
34
|
+
WidthWithoutContent: TypeAlias = int | Literal["stretch"]
|
|
35
|
+
Width: TypeAlias = int | Literal["stretch", "content"]
|
|
36
|
+
HeightWithoutContent: TypeAlias = int | Literal["stretch"]
|
|
37
|
+
Height: TypeAlias = int | Literal["stretch", "content"]
|
|
38
|
+
SpaceSize: TypeAlias = (
|
|
39
|
+
int
|
|
40
|
+
| Literal[
|
|
41
|
+
"stretch", "xxsmall", "xsmall", "small", "medium", "large", "xlarge", "xxlarge"
|
|
42
|
+
]
|
|
43
|
+
)
|
|
44
|
+
Gap: TypeAlias = Literal[
|
|
45
|
+
"xxsmall", "xsmall", "small", "medium", "large", "xlarge", "xxlarge"
|
|
46
|
+
]
|
|
47
|
+
HorizontalAlignment: TypeAlias = Literal["left", "center", "right", "distribute"]
|
|
48
|
+
VerticalAlignment: TypeAlias = Literal["top", "center", "bottom", "distribute"]
|
|
49
|
+
TextAlignment: TypeAlias = Literal["left", "center", "right", "justify"]
|
|
50
|
+
|
|
51
|
+
# Mapping of size literals to rem values for st.space
|
|
52
|
+
# If changing these, also check streamlit/frontend/lib/src/theme/primitives/sizes.ts
|
|
53
|
+
# to ensure sizes are kept in sync.
|
|
54
|
+
SIZE_TO_REM_MAPPING = {
|
|
55
|
+
"xxsmall": 0.25, # Aligns with gap "xxsmall" (4px)
|
|
56
|
+
"xsmall": 0.5, # Aligns with gap "xsmall" (8px)
|
|
57
|
+
"small": 0.75, # Height of widget label minus gap
|
|
58
|
+
"medium": 2.5, # Height of button/input field
|
|
59
|
+
"large": 4.25, # Height of large widget without label
|
|
60
|
+
"xlarge": 6, # Aligns with gap "xlarge" (96px)
|
|
61
|
+
"xxlarge": 8, # Aligns with gap "xxlarge" (128px)
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
|
|
65
|
+
@dataclass
|
|
66
|
+
class LayoutConfig:
|
|
67
|
+
width: Width | SpaceSize | None = None
|
|
68
|
+
height: Height | SpaceSize | None = None
|
|
69
|
+
text_alignment: TextAlignment | None = None
|
|
70
|
+
|
|
71
|
+
|
|
72
|
+
def validate_width(width: Width, allow_content: bool = False) -> None:
|
|
73
|
+
"""Validate the width parameter.
|
|
74
|
+
|
|
75
|
+
Parameters
|
|
76
|
+
----------
|
|
77
|
+
width : Any
|
|
78
|
+
The width value to validate.
|
|
79
|
+
allow_content : bool
|
|
80
|
+
Whether to allow "content" as a valid width value.
|
|
81
|
+
|
|
82
|
+
Raises
|
|
83
|
+
------
|
|
84
|
+
StreamlitInvalidWidthError
|
|
85
|
+
If the width value is invalid.
|
|
86
|
+
"""
|
|
87
|
+
if not isinstance(width, (int, str)):
|
|
88
|
+
raise StreamlitInvalidWidthError(width, allow_content)
|
|
89
|
+
|
|
90
|
+
if isinstance(width, str):
|
|
91
|
+
valid_strings = ["stretch"]
|
|
92
|
+
if allow_content:
|
|
93
|
+
valid_strings.append("content")
|
|
94
|
+
|
|
95
|
+
if width not in valid_strings:
|
|
96
|
+
raise StreamlitInvalidWidthError(width, allow_content)
|
|
97
|
+
elif width <= 0:
|
|
98
|
+
raise StreamlitInvalidWidthError(width, allow_content)
|
|
99
|
+
|
|
100
|
+
|
|
101
|
+
def validate_height(
|
|
102
|
+
height: Height | Literal["auto"],
|
|
103
|
+
allow_content: bool = False,
|
|
104
|
+
allow_stretch: bool = True,
|
|
105
|
+
additional_allowed: list[str] | None = None,
|
|
106
|
+
) -> None:
|
|
107
|
+
"""Validate the height parameter.
|
|
108
|
+
|
|
109
|
+
Parameters
|
|
110
|
+
----------
|
|
111
|
+
height : Any
|
|
112
|
+
The height value to validate.
|
|
113
|
+
allow_content : bool
|
|
114
|
+
Whether to allow "content" as a valid height value.
|
|
115
|
+
allow_stretch : bool
|
|
116
|
+
Whether to allow "stretch" as a valid height value.
|
|
117
|
+
additional_allowed : list[str] or None
|
|
118
|
+
Additional string values to allow beyond the base allowed values.
|
|
119
|
+
|
|
120
|
+
Raises
|
|
121
|
+
------
|
|
122
|
+
StreamlitInvalidHeightError
|
|
123
|
+
If the height value is invalid.
|
|
124
|
+
"""
|
|
125
|
+
if not isinstance(height, (int, str)):
|
|
126
|
+
raise StreamlitInvalidHeightError(height, allow_content)
|
|
127
|
+
|
|
128
|
+
if isinstance(height, str):
|
|
129
|
+
valid_strings = []
|
|
130
|
+
if allow_stretch:
|
|
131
|
+
valid_strings.append("stretch")
|
|
132
|
+
if allow_content:
|
|
133
|
+
valid_strings.append("content")
|
|
134
|
+
if additional_allowed:
|
|
135
|
+
valid_strings.extend(additional_allowed)
|
|
136
|
+
|
|
137
|
+
if height not in valid_strings:
|
|
138
|
+
raise StreamlitInvalidHeightError(height, allow_content)
|
|
139
|
+
|
|
140
|
+
elif height <= 0:
|
|
141
|
+
raise StreamlitInvalidHeightError(height, allow_content)
|
|
142
|
+
|
|
143
|
+
|
|
144
|
+
def validate_space_size(size: SpaceSize) -> None:
|
|
145
|
+
"""Validate the size parameter for st.space.
|
|
146
|
+
|
|
147
|
+
Parameters
|
|
148
|
+
----------
|
|
149
|
+
size : Any
|
|
150
|
+
The size value to validate.
|
|
151
|
+
|
|
152
|
+
Raises
|
|
153
|
+
------
|
|
154
|
+
StreamlitInvalidSizeError
|
|
155
|
+
If the size value is invalid.
|
|
156
|
+
"""
|
|
157
|
+
if not isinstance(size, (int, str)):
|
|
158
|
+
raise StreamlitInvalidSizeError(size)
|
|
159
|
+
|
|
160
|
+
if isinstance(size, str):
|
|
161
|
+
valid_strings = [
|
|
162
|
+
"stretch",
|
|
163
|
+
"xxsmall",
|
|
164
|
+
"xsmall",
|
|
165
|
+
"small",
|
|
166
|
+
"medium",
|
|
167
|
+
"large",
|
|
168
|
+
"xlarge",
|
|
169
|
+
"xxlarge",
|
|
170
|
+
]
|
|
171
|
+
if size not in valid_strings:
|
|
172
|
+
raise StreamlitInvalidSizeError(size)
|
|
173
|
+
elif isinstance(size, int) and size <= 0:
|
|
174
|
+
raise StreamlitInvalidSizeError(size)
|
|
175
|
+
|
|
176
|
+
|
|
177
|
+
def get_width_config(width: Width | SpaceSize) -> WidthConfig:
|
|
178
|
+
width_config = WidthConfig()
|
|
179
|
+
if isinstance(width, str) and width in SIZE_TO_REM_MAPPING:
|
|
180
|
+
width_config.rem_width = SIZE_TO_REM_MAPPING[width]
|
|
181
|
+
elif isinstance(width, (int, float)):
|
|
182
|
+
width_config.pixel_width = int(width)
|
|
183
|
+
elif width == "content":
|
|
184
|
+
width_config.use_content = True
|
|
185
|
+
else:
|
|
186
|
+
width_config.use_stretch = True
|
|
187
|
+
return width_config
|
|
188
|
+
|
|
189
|
+
|
|
190
|
+
def get_height_config(height: Height | SpaceSize) -> HeightConfig:
|
|
191
|
+
height_config = HeightConfig()
|
|
192
|
+
if isinstance(height, str) and height in SIZE_TO_REM_MAPPING:
|
|
193
|
+
height_config.rem_height = SIZE_TO_REM_MAPPING[height]
|
|
194
|
+
elif isinstance(height, (int, float)):
|
|
195
|
+
height_config.pixel_height = int(height)
|
|
196
|
+
elif height == "content":
|
|
197
|
+
height_config.use_content = True
|
|
198
|
+
else:
|
|
199
|
+
height_config.use_stretch = True
|
|
200
|
+
return height_config
|
|
201
|
+
|
|
202
|
+
|
|
203
|
+
def get_gap_size(gap: str | None, element_type: str) -> GapSize.ValueType:
|
|
204
|
+
"""Convert a gap string or None to a GapSize proto value."""
|
|
205
|
+
gap_mapping = {
|
|
206
|
+
"xxsmall": GapSize.XXSMALL,
|
|
207
|
+
"xsmall": GapSize.XSMALL,
|
|
208
|
+
"small": GapSize.SMALL,
|
|
209
|
+
"medium": GapSize.MEDIUM,
|
|
210
|
+
"large": GapSize.LARGE,
|
|
211
|
+
"xlarge": GapSize.XLARGE,
|
|
212
|
+
"xxlarge": GapSize.XXLARGE,
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
if isinstance(gap, str):
|
|
216
|
+
gap_size = gap.lower()
|
|
217
|
+
valid_sizes = gap_mapping.keys()
|
|
218
|
+
|
|
219
|
+
if gap_size in valid_sizes:
|
|
220
|
+
return gap_mapping[gap_size]
|
|
221
|
+
elif gap is None:
|
|
222
|
+
return GapSize.NONE
|
|
223
|
+
|
|
224
|
+
raise StreamlitInvalidColumnGapError(gap=gap, element_type=element_type)
|
|
225
|
+
|
|
226
|
+
|
|
227
|
+
def validate_horizontal_alignment(horizontal_alignment: HorizontalAlignment) -> None:
|
|
228
|
+
valid_horizontal_alignments = ["left", "center", "right", "distribute"]
|
|
229
|
+
if horizontal_alignment not in valid_horizontal_alignments:
|
|
230
|
+
raise StreamlitInvalidHorizontalAlignmentError(
|
|
231
|
+
horizontal_alignment, "st.container"
|
|
232
|
+
)
|
|
233
|
+
|
|
234
|
+
|
|
235
|
+
def validate_vertical_alignment(vertical_alignment: VerticalAlignment) -> None:
|
|
236
|
+
valid_vertical_alignments = ["top", "center", "bottom", "distribute"]
|
|
237
|
+
if vertical_alignment not in valid_vertical_alignments:
|
|
238
|
+
raise StreamlitInvalidVerticalAlignmentError(vertical_alignment, "st.container")
|
|
239
|
+
|
|
240
|
+
|
|
241
|
+
def validate_text_alignment(text_alignment: TextAlignment) -> None:
|
|
242
|
+
"""Validate the text_alignment parameter.
|
|
243
|
+
|
|
244
|
+
Parameters
|
|
245
|
+
----------
|
|
246
|
+
text_alignment : TextAlignment
|
|
247
|
+
The text alignment value to validate.
|
|
248
|
+
|
|
249
|
+
Raises
|
|
250
|
+
------
|
|
251
|
+
StreamlitInvalidTextAlignmentError
|
|
252
|
+
If the text_alignment value is invalid.
|
|
253
|
+
"""
|
|
254
|
+
valid_alignments = ["left", "center", "right", "justify"]
|
|
255
|
+
if text_alignment not in valid_alignments:
|
|
256
|
+
raise StreamlitInvalidTextAlignmentError(text_alignment)
|
|
257
|
+
|
|
258
|
+
|
|
259
|
+
map_to_flex_terminology = {
|
|
260
|
+
"left": "start",
|
|
261
|
+
"center": "center",
|
|
262
|
+
"right": "end",
|
|
263
|
+
"top": "start",
|
|
264
|
+
"bottom": "end",
|
|
265
|
+
"distribute": "space_between",
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
|
|
269
|
+
def get_justify(
|
|
270
|
+
alignment: HorizontalAlignment | VerticalAlignment,
|
|
271
|
+
) -> Block.FlexContainer.Justify.ValueType:
|
|
272
|
+
valid_justify = ["start", "center", "end", "space_between"]
|
|
273
|
+
justify = map_to_flex_terminology[alignment]
|
|
274
|
+
if justify not in valid_justify:
|
|
275
|
+
return Block.FlexContainer.Justify.JUSTIFY_UNDEFINED
|
|
276
|
+
if justify in {"start", "end", "center"}:
|
|
277
|
+
return cast(
|
|
278
|
+
"Block.FlexContainer.Justify.ValueType",
|
|
279
|
+
getattr(Block.FlexContainer.Justify, f"JUSTIFY_{justify.upper()}"),
|
|
280
|
+
)
|
|
281
|
+
return cast(
|
|
282
|
+
"Block.FlexContainer.Justify.ValueType",
|
|
283
|
+
getattr(Block.FlexContainer.Justify, f"{justify.upper()}"),
|
|
284
|
+
)
|
|
285
|
+
|
|
286
|
+
|
|
287
|
+
def get_align(
|
|
288
|
+
alignment: HorizontalAlignment | VerticalAlignment,
|
|
289
|
+
) -> Block.FlexContainer.Align.ValueType:
|
|
290
|
+
valid_align = ["start", "end", "center"]
|
|
291
|
+
align = map_to_flex_terminology[alignment]
|
|
292
|
+
if align not in valid_align:
|
|
293
|
+
return Block.FlexContainer.Align.ALIGN_UNDEFINED
|
|
294
|
+
return cast(
|
|
295
|
+
"Block.FlexContainer.Align.ValueType",
|
|
296
|
+
getattr(Block.FlexContainer.Align, f"ALIGN_{align.upper()}"),
|
|
297
|
+
)
|
|
298
|
+
|
|
299
|
+
|
|
300
|
+
def get_text_alignment_config(
|
|
301
|
+
text_alignment: TextAlignment,
|
|
302
|
+
) -> TextAlignmentConfig:
|
|
303
|
+
"""Convert text alignment string to proto config.
|
|
304
|
+
|
|
305
|
+
Parameters
|
|
306
|
+
----------
|
|
307
|
+
text_alignment : TextAlignment
|
|
308
|
+
The text alignment value ("left", "center", "right", "justify").
|
|
309
|
+
|
|
310
|
+
Returns
|
|
311
|
+
-------
|
|
312
|
+
TextAlignmentConfig
|
|
313
|
+
Proto message with alignment set.
|
|
314
|
+
"""
|
|
315
|
+
|
|
316
|
+
alignment_mapping = {
|
|
317
|
+
"left": TextAlignmentConfig.Alignment.LEFT,
|
|
318
|
+
"center": TextAlignmentConfig.Alignment.CENTER,
|
|
319
|
+
"right": TextAlignmentConfig.Alignment.RIGHT,
|
|
320
|
+
"justify": TextAlignmentConfig.Alignment.JUSTIFY,
|
|
321
|
+
}
|
|
322
|
+
|
|
323
|
+
config = TextAlignmentConfig()
|
|
324
|
+
config.alignment = alignment_mapping[text_alignment]
|
|
325
|
+
return config
|
|
@@ -0,0 +1,73 @@
|
|
|
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
|
+
from typing import TYPE_CHECKING, Literal
|
|
18
|
+
|
|
19
|
+
from typing_extensions import Self
|
|
20
|
+
|
|
21
|
+
from streamlit.delta_generator import DeltaGenerator
|
|
22
|
+
|
|
23
|
+
if TYPE_CHECKING:
|
|
24
|
+
from types import TracebackType
|
|
25
|
+
|
|
26
|
+
from streamlit.cursor import Cursor
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
class ExpanderContainer(DeltaGenerator):
|
|
30
|
+
"""DeltaGenerator subclass returned by ``st.expander``.
|
|
31
|
+
|
|
32
|
+
Provides the ``.open`` property for checking expander state when
|
|
33
|
+
``on_change`` is used.
|
|
34
|
+
"""
|
|
35
|
+
|
|
36
|
+
def __init__(
|
|
37
|
+
self,
|
|
38
|
+
root_container: int | None,
|
|
39
|
+
cursor: Cursor | None,
|
|
40
|
+
parent: DeltaGenerator | None,
|
|
41
|
+
block_type: str | None,
|
|
42
|
+
) -> None:
|
|
43
|
+
super().__init__(root_container, cursor, parent, block_type)
|
|
44
|
+
self._open: bool | None = None
|
|
45
|
+
|
|
46
|
+
@property
|
|
47
|
+
def open(self) -> bool | None:
|
|
48
|
+
"""The open/collapsed state of the expander.
|
|
49
|
+
|
|
50
|
+
Returns
|
|
51
|
+
-------
|
|
52
|
+
bool or None
|
|
53
|
+
``True`` if expanded, ``False`` if collapsed, or ``None`` if
|
|
54
|
+
state tracking is not enabled (``on_change`` was not set or
|
|
55
|
+
set to ``"ignore"``).
|
|
56
|
+
"""
|
|
57
|
+
return self._open
|
|
58
|
+
|
|
59
|
+
@open.setter # noqa: A003
|
|
60
|
+
def open(self, value: bool | None) -> None:
|
|
61
|
+
self._open = value
|
|
62
|
+
|
|
63
|
+
def __enter__(self) -> Self: # type: ignore[override]
|
|
64
|
+
super().__enter__()
|
|
65
|
+
return self
|
|
66
|
+
|
|
67
|
+
def __exit__(
|
|
68
|
+
self,
|
|
69
|
+
exc_type: type[BaseException] | None,
|
|
70
|
+
exc_val: BaseException | None,
|
|
71
|
+
exc_tb: TracebackType | None,
|
|
72
|
+
) -> Literal[False]:
|
|
73
|
+
return super().__exit__(exc_type, exc_val, exc_tb)
|
|
@@ -0,0 +1,73 @@
|
|
|
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
|
+
from typing import TYPE_CHECKING, Literal
|
|
18
|
+
|
|
19
|
+
from typing_extensions import Self
|
|
20
|
+
|
|
21
|
+
from streamlit.delta_generator import DeltaGenerator
|
|
22
|
+
|
|
23
|
+
if TYPE_CHECKING:
|
|
24
|
+
from types import TracebackType
|
|
25
|
+
|
|
26
|
+
from streamlit.cursor import Cursor
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
class PopoverContainer(DeltaGenerator):
|
|
30
|
+
"""DeltaGenerator subclass returned by ``st.popover``.
|
|
31
|
+
|
|
32
|
+
Provides the ``.open`` property for checking popover state when
|
|
33
|
+
``on_change`` is used.
|
|
34
|
+
"""
|
|
35
|
+
|
|
36
|
+
def __init__(
|
|
37
|
+
self,
|
|
38
|
+
root_container: int | None,
|
|
39
|
+
cursor: Cursor | None,
|
|
40
|
+
parent: DeltaGenerator | None,
|
|
41
|
+
block_type: str | None,
|
|
42
|
+
) -> None:
|
|
43
|
+
super().__init__(root_container, cursor, parent, block_type)
|
|
44
|
+
self._open: bool | None = None
|
|
45
|
+
|
|
46
|
+
@property
|
|
47
|
+
def open(self) -> bool | None:
|
|
48
|
+
"""The open/closed state of the popover.
|
|
49
|
+
|
|
50
|
+
Returns
|
|
51
|
+
-------
|
|
52
|
+
bool or None
|
|
53
|
+
``True`` if open, ``False`` if closed, or ``None`` if state
|
|
54
|
+
tracking is not enabled (``on_change`` was not set or set to
|
|
55
|
+
``"ignore"``).
|
|
56
|
+
"""
|
|
57
|
+
return self._open
|
|
58
|
+
|
|
59
|
+
@open.setter # noqa: A003
|
|
60
|
+
def open(self, value: bool | None) -> None:
|
|
61
|
+
self._open = value
|
|
62
|
+
|
|
63
|
+
def __enter__(self) -> Self: # type: ignore[override]
|
|
64
|
+
super().__enter__()
|
|
65
|
+
return self
|
|
66
|
+
|
|
67
|
+
def __exit__(
|
|
68
|
+
self,
|
|
69
|
+
exc_type: type[BaseException] | None,
|
|
70
|
+
exc_val: BaseException | None,
|
|
71
|
+
exc_tb: TracebackType | None,
|
|
72
|
+
) -> Literal[False]:
|
|
73
|
+
return super().__exit__(exc_type, exc_val, exc_tb)
|
|
@@ -0,0 +1,194 @@
|
|
|
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 time
|
|
18
|
+
from typing import TYPE_CHECKING, Literal, TypeAlias, cast
|
|
19
|
+
|
|
20
|
+
from typing_extensions import Self
|
|
21
|
+
|
|
22
|
+
from streamlit.delta_generator import DeltaGenerator
|
|
23
|
+
from streamlit.elements.lib.layout_utils import (
|
|
24
|
+
WidthWithoutContent,
|
|
25
|
+
get_width_config,
|
|
26
|
+
validate_width,
|
|
27
|
+
)
|
|
28
|
+
from streamlit.errors import StreamlitAPIException
|
|
29
|
+
from streamlit.proto.Block_pb2 import Block as BlockProto
|
|
30
|
+
from streamlit.proto.ForwardMsg_pb2 import ForwardMsg
|
|
31
|
+
from streamlit.runtime.scriptrunner_utils.script_run_context import enqueue_message
|
|
32
|
+
|
|
33
|
+
if TYPE_CHECKING:
|
|
34
|
+
from types import TracebackType
|
|
35
|
+
|
|
36
|
+
from streamlit.cursor import Cursor
|
|
37
|
+
|
|
38
|
+
States: TypeAlias = Literal["running", "complete", "error"]
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
class StatusContainer(DeltaGenerator):
|
|
42
|
+
@staticmethod
|
|
43
|
+
def _create(
|
|
44
|
+
parent: DeltaGenerator,
|
|
45
|
+
label: str,
|
|
46
|
+
expanded: bool = False,
|
|
47
|
+
state: States = "running",
|
|
48
|
+
width: WidthWithoutContent = "stretch",
|
|
49
|
+
) -> StatusContainer:
|
|
50
|
+
expandable_proto = BlockProto.Expandable()
|
|
51
|
+
expandable_proto.expanded = expanded
|
|
52
|
+
expandable_proto.label = label or ""
|
|
53
|
+
|
|
54
|
+
if state == "running":
|
|
55
|
+
expandable_proto.icon = "spinner"
|
|
56
|
+
elif state == "complete":
|
|
57
|
+
expandable_proto.icon = ":material/check:"
|
|
58
|
+
elif state == "error":
|
|
59
|
+
expandable_proto.icon = ":material/error:"
|
|
60
|
+
else:
|
|
61
|
+
raise StreamlitAPIException(
|
|
62
|
+
f"Unknown state ({state}). Must be one of 'running', 'complete', or 'error'."
|
|
63
|
+
)
|
|
64
|
+
|
|
65
|
+
block_proto = BlockProto()
|
|
66
|
+
block_proto.allow_empty = True
|
|
67
|
+
block_proto.expandable.CopyFrom(expandable_proto)
|
|
68
|
+
|
|
69
|
+
validate_width(width=width)
|
|
70
|
+
block_proto.width_config.CopyFrom(get_width_config(width))
|
|
71
|
+
|
|
72
|
+
delta_path: list[int] = (
|
|
73
|
+
parent._active_dg._cursor.delta_path if parent._active_dg._cursor else []
|
|
74
|
+
)
|
|
75
|
+
|
|
76
|
+
status_container = cast(
|
|
77
|
+
"StatusContainer",
|
|
78
|
+
parent._block(block_proto=block_proto, dg_type=StatusContainer),
|
|
79
|
+
)
|
|
80
|
+
|
|
81
|
+
# Apply initial configuration
|
|
82
|
+
status_container._delta_path = delta_path
|
|
83
|
+
status_container._current_proto = block_proto
|
|
84
|
+
status_container._current_state = state
|
|
85
|
+
|
|
86
|
+
# We need to sleep here for a very short time to prevent issues when
|
|
87
|
+
# the status is updated too quickly. If an .update() directly follows the
|
|
88
|
+
# the initialization, sometimes only the latest update is applied.
|
|
89
|
+
# Adding a short timeout here allows the frontend to render the update before.
|
|
90
|
+
time.sleep(0.05)
|
|
91
|
+
|
|
92
|
+
return status_container
|
|
93
|
+
|
|
94
|
+
def __init__(
|
|
95
|
+
self,
|
|
96
|
+
root_container: int | None,
|
|
97
|
+
cursor: Cursor | None,
|
|
98
|
+
parent: DeltaGenerator | None,
|
|
99
|
+
block_type: str | None,
|
|
100
|
+
) -> None:
|
|
101
|
+
super().__init__(root_container, cursor, parent, block_type)
|
|
102
|
+
|
|
103
|
+
# Initialized in `_create()`:
|
|
104
|
+
self._current_proto: BlockProto | None = None
|
|
105
|
+
self._current_state: States | None = None
|
|
106
|
+
self._delta_path: list[int] | None = None
|
|
107
|
+
|
|
108
|
+
def update(
|
|
109
|
+
self,
|
|
110
|
+
*,
|
|
111
|
+
label: str | None = None,
|
|
112
|
+
expanded: bool | None = None,
|
|
113
|
+
state: States | None = None,
|
|
114
|
+
) -> None:
|
|
115
|
+
"""Update the status container.
|
|
116
|
+
|
|
117
|
+
Only specified arguments are updated. Container contents and unspecified
|
|
118
|
+
arguments remain unchanged.
|
|
119
|
+
|
|
120
|
+
Parameters
|
|
121
|
+
----------
|
|
122
|
+
label : str or None
|
|
123
|
+
A new label of the status container. If None, the label is not
|
|
124
|
+
changed.
|
|
125
|
+
|
|
126
|
+
expanded : bool or None
|
|
127
|
+
The new expanded state of the status container. If None,
|
|
128
|
+
the expanded state is not changed.
|
|
129
|
+
|
|
130
|
+
state : "running", "complete", "error", or None
|
|
131
|
+
The new state of the status container. This mainly changes the
|
|
132
|
+
icon. If None, the state is not changed.
|
|
133
|
+
"""
|
|
134
|
+
if self._current_proto is None or self._delta_path is None:
|
|
135
|
+
raise RuntimeError(
|
|
136
|
+
"StatusContainer is not correctly initialized. This should never happen."
|
|
137
|
+
)
|
|
138
|
+
|
|
139
|
+
msg = ForwardMsg()
|
|
140
|
+
msg.metadata.delta_path[:] = self._delta_path
|
|
141
|
+
msg.delta.add_block.CopyFrom(self._current_proto)
|
|
142
|
+
|
|
143
|
+
if expanded is not None:
|
|
144
|
+
msg.delta.add_block.expandable.expanded = expanded
|
|
145
|
+
else:
|
|
146
|
+
msg.delta.add_block.expandable.ClearField("expanded")
|
|
147
|
+
|
|
148
|
+
if label is not None:
|
|
149
|
+
msg.delta.add_block.expandable.label = label
|
|
150
|
+
|
|
151
|
+
if state is not None:
|
|
152
|
+
if state == "running":
|
|
153
|
+
msg.delta.add_block.expandable.icon = "spinner"
|
|
154
|
+
elif state == "complete":
|
|
155
|
+
msg.delta.add_block.expandable.icon = ":material/check:"
|
|
156
|
+
elif state == "error":
|
|
157
|
+
msg.delta.add_block.expandable.icon = ":material/error:"
|
|
158
|
+
else:
|
|
159
|
+
raise StreamlitAPIException(
|
|
160
|
+
f"Unknown state ({state}). Must be one of 'running', 'complete', or 'error'."
|
|
161
|
+
)
|
|
162
|
+
self._current_state = state
|
|
163
|
+
|
|
164
|
+
self._current_proto = msg.delta.add_block
|
|
165
|
+
enqueue_message(msg)
|
|
166
|
+
|
|
167
|
+
def __enter__(self) -> Self: # type: ignore[override]
|
|
168
|
+
# This is a little dubious: we're returning a different type than
|
|
169
|
+
# our superclass' `__enter__` function. Maybe DeltaGenerator.__enter__
|
|
170
|
+
# should always return `self`?
|
|
171
|
+
super().__enter__()
|
|
172
|
+
return self
|
|
173
|
+
|
|
174
|
+
def __exit__(
|
|
175
|
+
self,
|
|
176
|
+
exc_type: type[BaseException] | None,
|
|
177
|
+
exc_val: BaseException | None,
|
|
178
|
+
exc_tb: TracebackType | None,
|
|
179
|
+
) -> Literal[False]:
|
|
180
|
+
# Only update if the current state is running
|
|
181
|
+
if self._current_state == "running":
|
|
182
|
+
# We need to sleep here for a very short time to prevent issues when
|
|
183
|
+
# the status is updated too quickly. If an .update() is directly followed
|
|
184
|
+
# by the exit of the context manager, sometimes only the last update
|
|
185
|
+
# (to complete) is applied. Adding a short timeout here allows the frontend
|
|
186
|
+
# to render the update before.
|
|
187
|
+
time.sleep(0.05)
|
|
188
|
+
if exc_type is not None:
|
|
189
|
+
# If an exception was raised in the context,
|
|
190
|
+
# we want to update the status to error.
|
|
191
|
+
self.update(state="error")
|
|
192
|
+
else:
|
|
193
|
+
self.update(state="complete")
|
|
194
|
+
return super().__exit__(exc_type, exc_val, exc_tb)
|