streamlit 1.50.0__py3-none-any.whl → 1.52.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 +5 -1
- streamlit/commands/execution_control.py +89 -14
- streamlit/commands/navigation.py +4 -6
- streamlit/commands/page_config.py +4 -6
- streamlit/components/v1/component_arrow.py +7 -7
- streamlit/components/v2/__init__.py +514 -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 +534 -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 +245 -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 +615 -0
- streamlit/components/v2/presentation.py +198 -0
- streamlit/components/v2/types.py +324 -0
- streamlit/config.py +456 -53
- streamlit/config_option.py +4 -1
- streamlit/config_util.py +650 -1
- streamlit/connections/snowflake_connection.py +1 -1
- streamlit/connections/snowpark_connection.py +1 -1
- streamlit/dataframe_util.py +33 -26
- streamlit/delta_generator.py +13 -4
- streamlit/delta_generator_singletons.py +11 -15
- streamlit/deprecation_util.py +17 -6
- streamlit/elements/alert.py +16 -0
- streamlit/elements/arrow.py +68 -10
- streamlit/elements/bokeh_chart.py +10 -78
- streamlit/elements/code.py +2 -2
- streamlit/elements/deck_gl_json_chart.py +98 -40
- streamlit/elements/dialog_decorator.py +2 -1
- streamlit/elements/exception.py +4 -2
- streamlit/elements/form.py +27 -0
- streamlit/elements/graphviz_chart.py +1 -3
- streamlit/elements/heading.py +63 -10
- streamlit/elements/html.py +13 -2
- streamlit/elements/image.py +3 -5
- streamlit/elements/layouts.py +59 -33
- streamlit/elements/lib/built_in_chart_utils.py +50 -19
- streamlit/elements/lib/color_util.py +9 -19
- streamlit/elements/lib/column_config_utils.py +9 -12
- streamlit/elements/lib/column_types.py +40 -12
- streamlit/elements/lib/dialog.py +2 -2
- streamlit/elements/lib/image_utils.py +3 -5
- streamlit/elements/lib/layout_utils.py +100 -13
- streamlit/elements/lib/mutable_status_container.py +2 -2
- streamlit/elements/lib/options_selector_utils.py +2 -2
- streamlit/elements/lib/pandas_styler_utils.py +17 -9
- streamlit/elements/lib/shortcut_utils.py +152 -0
- streamlit/elements/lib/utils.py +4 -4
- streamlit/elements/map.py +80 -37
- streamlit/elements/markdown.py +50 -3
- streamlit/elements/media.py +5 -7
- streamlit/elements/metric.py +34 -6
- streamlit/elements/pdf.py +2 -4
- streamlit/elements/plotly_chart.py +197 -20
- streamlit/elements/progress.py +2 -4
- streamlit/elements/space.py +113 -0
- streamlit/elements/spinner.py +1 -1
- streamlit/elements/text.py +20 -3
- streamlit/elements/toast.py +2 -0
- streamlit/elements/vega_charts.py +356 -149
- streamlit/elements/widgets/audio_input.py +12 -11
- streamlit/elements/widgets/button.py +280 -43
- streamlit/elements/widgets/button_group.py +60 -9
- streamlit/elements/widgets/camera_input.py +3 -5
- streamlit/elements/widgets/chat.py +307 -43
- streamlit/elements/widgets/color_picker.py +8 -1
- streamlit/elements/widgets/data_editor.py +88 -44
- streamlit/elements/widgets/file_uploader.py +9 -11
- streamlit/elements/widgets/multiselect.py +4 -3
- streamlit/elements/widgets/number_input.py +4 -4
- streamlit/elements/widgets/radio.py +10 -3
- streamlit/elements/widgets/select_slider.py +8 -5
- streamlit/elements/widgets/selectbox.py +6 -3
- streamlit/elements/widgets/slider.py +38 -42
- streamlit/elements/widgets/text_widgets.py +2 -0
- streamlit/elements/widgets/time_widgets.py +587 -21
- streamlit/elements/write.py +27 -6
- streamlit/emojis.py +1 -1
- streamlit/errors.py +137 -0
- streamlit/git_util.py +1 -1
- streamlit/hello/hello.py +8 -0
- streamlit/hello/utils.py +2 -1
- streamlit/material_icon_names.py +1 -1
- streamlit/navigation/page.py +11 -1
- streamlit/net_util.py +2 -2
- streamlit/proto/Alert_pb2.pyi +3 -3
- streamlit/proto/AppPage_pb2.pyi +7 -1
- streamlit/proto/ArrowData_pb2.py +27 -0
- streamlit/proto/ArrowData_pb2.pyi +52 -0
- streamlit/proto/ArrowNamedDataSet_pb2.pyi +7 -1
- streamlit/proto/ArrowVegaLiteChart_pb2.pyi +7 -1
- streamlit/proto/Arrow_pb2.py +10 -10
- streamlit/proto/Arrow_pb2.pyi +19 -12
- streamlit/proto/AudioInput_pb2.pyi +7 -1
- streamlit/proto/Audio_pb2.pyi +7 -1
- streamlit/proto/AuthRedirect_pb2.pyi +7 -1
- streamlit/proto/AutoRerun_pb2.pyi +7 -1
- streamlit/proto/BackMsg_pb2.py +4 -2
- streamlit/proto/BackMsg_pb2.pyi +34 -4
- streamlit/proto/Balloons_pb2.pyi +7 -1
- streamlit/proto/BidiComponent_pb2.py +34 -0
- streamlit/proto/BidiComponent_pb2.pyi +159 -0
- streamlit/proto/Block_pb2.py +7 -7
- streamlit/proto/Block_pb2.pyi +39 -36
- streamlit/proto/BokehChart_pb2.pyi +7 -1
- streamlit/proto/ButtonGroup_pb2.pyi +9 -9
- streamlit/proto/Button_pb2.py +2 -2
- streamlit/proto/Button_pb2.pyi +11 -2
- streamlit/proto/CameraInput_pb2.pyi +7 -1
- streamlit/proto/ChatInput_pb2.py +6 -6
- streamlit/proto/ChatInput_pb2.pyi +18 -6
- streamlit/proto/Checkbox_pb2.pyi +3 -3
- streamlit/proto/ClientState_pb2.pyi +10 -4
- streamlit/proto/Code_pb2.pyi +7 -1
- streamlit/proto/ColorPicker_pb2.pyi +7 -1
- streamlit/proto/Common_pb2.py +3 -3
- streamlit/proto/Common_pb2.pyi +35 -23
- streamlit/proto/Components_pb2.pyi +19 -13
- streamlit/proto/DataFrame_pb2.pyi +55 -49
- streamlit/proto/DateInput_pb2.pyi +7 -1
- streamlit/proto/DateTimeInput_pb2.py +28 -0
- streamlit/proto/DateTimeInput_pb2.pyi +92 -0
- streamlit/proto/DeckGlJsonChart_pb2.py +10 -4
- streamlit/proto/DeckGlJsonChart_pb2.pyi +12 -6
- streamlit/proto/Delta_pb2.pyi +7 -1
- streamlit/proto/DocString_pb2.pyi +10 -4
- streamlit/proto/DownloadButton_pb2.py +2 -2
- streamlit/proto/DownloadButton_pb2.pyi +16 -2
- streamlit/proto/Element_pb2.py +7 -3
- streamlit/proto/Element_pb2.pyi +33 -5
- streamlit/proto/Empty_pb2.pyi +7 -1
- streamlit/proto/Exception_pb2.pyi +7 -1
- streamlit/proto/Favicon_pb2.pyi +7 -1
- streamlit/proto/FileUploader_pb2.pyi +7 -1
- streamlit/proto/ForwardMsg_pb2.py +12 -10
- streamlit/proto/ForwardMsg_pb2.pyi +42 -15
- streamlit/proto/GapSize_pb2.pyi +4 -4
- streamlit/proto/GitInfo_pb2.pyi +3 -3
- streamlit/proto/GraphVizChart_pb2.pyi +7 -1
- streamlit/proto/Heading_pb2.pyi +7 -1
- streamlit/proto/HeightConfig_pb2.py +2 -2
- streamlit/proto/HeightConfig_pb2.pyi +13 -4
- streamlit/proto/Html_pb2.py +2 -2
- streamlit/proto/Html_pb2.pyi +11 -2
- streamlit/proto/IFrame_pb2.pyi +7 -1
- streamlit/proto/Image_pb2.pyi +10 -4
- streamlit/proto/Json_pb2.pyi +7 -1
- streamlit/proto/LabelVisibilityMessage_pb2.pyi +3 -3
- streamlit/proto/LinkButton_pb2.py +2 -2
- streamlit/proto/LinkButton_pb2.pyi +15 -2
- streamlit/proto/Logo_pb2.pyi +7 -1
- streamlit/proto/Markdown_pb2.pyi +3 -3
- streamlit/proto/Metric_pb2.pyi +7 -7
- streamlit/proto/MetricsEvent_pb2.pyi +10 -4
- streamlit/proto/MultiSelect_pb2.pyi +7 -1
- streamlit/proto/NamedDataSet_pb2.pyi +7 -1
- streamlit/proto/Navigation_pb2.pyi +3 -3
- streamlit/proto/NewSession_pb2.py +18 -18
- streamlit/proto/NewSession_pb2.pyi +59 -40
- streamlit/proto/NumberInput_pb2.pyi +3 -3
- streamlit/proto/PageConfig_pb2.pyi +7 -7
- streamlit/proto/PageInfo_pb2.pyi +7 -1
- streamlit/proto/PageLink_pb2.py +2 -2
- streamlit/proto/PageLink_pb2.pyi +11 -2
- streamlit/proto/PageNotFound_pb2.pyi +7 -1
- streamlit/proto/PageProfile_pb2.pyi +13 -7
- streamlit/proto/PagesChanged_pb2.pyi +7 -1
- streamlit/proto/ParentMessage_pb2.pyi +7 -1
- streamlit/proto/PlotlyChart_pb2.py +8 -6
- streamlit/proto/PlotlyChart_pb2.pyi +9 -7
- streamlit/proto/Progress_pb2.pyi +7 -1
- streamlit/proto/Radio_pb2.pyi +7 -1
- streamlit/proto/RootContainer_pb2.pyi +1 -1
- streamlit/proto/Selectbox_pb2.pyi +7 -1
- streamlit/proto/SessionEvent_pb2.pyi +7 -1
- streamlit/proto/SessionStatus_pb2.pyi +7 -1
- streamlit/proto/Skeleton_pb2.pyi +3 -3
- streamlit/proto/Slider_pb2.pyi +5 -5
- streamlit/proto/Snow_pb2.pyi +7 -1
- streamlit/proto/Space_pb2.py +27 -0
- streamlit/proto/Space_pb2.pyi +48 -0
- streamlit/proto/Spinner_pb2.pyi +7 -1
- streamlit/proto/TextAlignmentConfig_pb2.py +29 -0
- streamlit/proto/TextAlignmentConfig_pb2.pyi +68 -0
- streamlit/proto/TextArea_pb2.pyi +7 -1
- streamlit/proto/TextInput_pb2.pyi +3 -3
- streamlit/proto/Text_pb2.pyi +7 -1
- streamlit/proto/TimeInput_pb2.pyi +7 -1
- streamlit/proto/Toast_pb2.pyi +7 -1
- streamlit/proto/VegaLiteChart_pb2.pyi +7 -1
- streamlit/proto/Video_pb2.pyi +6 -6
- streamlit/proto/WidgetStates_pb2.py +2 -2
- streamlit/proto/WidgetStates_pb2.pyi +23 -7
- streamlit/proto/WidthConfig_pb2.py +2 -2
- streamlit/proto/WidthConfig_pb2.pyi +13 -4
- streamlit/proto/openmetrics_data_model_pb2.pyi +52 -52
- streamlit/runtime/app_session.py +65 -2
- streamlit/runtime/caching/cache_data_api.py +5 -5
- streamlit/runtime/caching/cache_errors.py +4 -1
- streamlit/runtime/caching/cache_resource_api.py +5 -4
- streamlit/runtime/caching/cache_utils.py +3 -2
- streamlit/runtime/caching/cached_message_replay.py +3 -3
- streamlit/runtime/caching/hashing.py +4 -5
- streamlit/runtime/caching/legacy_cache_api.py +2 -1
- streamlit/runtime/connection_factory.py +1 -3
- streamlit/runtime/download_data_util.py +53 -0
- streamlit/runtime/forward_msg_queue.py +5 -1
- streamlit/runtime/fragment.py +2 -1
- streamlit/runtime/media_file_manager.py +178 -2
- streamlit/runtime/memory_media_file_storage.py +1 -1
- streamlit/runtime/metrics_util.py +91 -3
- streamlit/runtime/runtime.py +14 -0
- streamlit/runtime/scriptrunner/exec_code.py +2 -1
- streamlit/runtime/scriptrunner/script_runner.py +5 -3
- streamlit/runtime/scriptrunner_utils/script_run_context.py +3 -6
- streamlit/runtime/secrets.py +2 -4
- streamlit/runtime/session_manager.py +3 -1
- streamlit/runtime/state/common.py +30 -5
- streamlit/runtime/state/presentation.py +85 -0
- streamlit/runtime/state/query_params.py +80 -29
- streamlit/runtime/state/safe_session_state.py +2 -2
- streamlit/runtime/state/session_state.py +221 -17
- streamlit/runtime/state/widgets.py +19 -3
- streamlit/runtime/websocket_session_manager.py +3 -1
- streamlit/source_util.py +2 -2
- streamlit/static/index.html +2 -2
- streamlit/static/manifest.json +557 -239
- streamlit/static/static/css/{index.CIiu7Ygf.css → index.BpABIXK9.css} +1 -1
- streamlit/static/static/css/index.DgR7E2CV.css +1 -0
- streamlit/static/static/js/{ErrorOutline.esm.DUpR0_Ka.js → ErrorOutline.esm.ZJDbmVTx.js} +1 -1
- streamlit/static/static/js/{FileDownload.esm.CN4j9-1w.js → FileDownload.esm.Dx0vI3vH.js} +1 -1
- streamlit/static/static/js/{FileHelper.CaIUKG91.js → FileHelper.B7Ero7qQ.js} +3 -3
- streamlit/static/static/js/{FormClearHelper.DTcdrasw.js → FormClearHelper.CG2XN1_g.js} +1 -1
- streamlit/static/static/js/IFrameUtil.DefezniK.js +1 -0
- streamlit/static/static/js/InputInstructions.Cj5-1zf6.js +1 -0
- streamlit/static/static/js/Particles.BfWfv0Aw.js +1 -0
- streamlit/static/static/js/{ProgressBar.DetlP5aY.js → ProgressBar.CGQ8OgfO.js} +2 -2
- streamlit/static/static/js/StreamlitSyntaxHighlighter.DTKLpwhl.js +20 -0
- streamlit/static/static/js/{Toolbar.C77ar7rq.js → Toolbar.B2qFUmd9.js} +1 -1
- streamlit/static/static/js/_arrayIncludes.B19Iyn2B.js +1 -0
- streamlit/static/static/js/_baseIndexOf.BTknn6Gb.js +1 -0
- streamlit/static/static/js/{base-input.BQft14La.js → base-input.o9tL8MDP.js} +4 -4
- streamlit/static/static/js/{checkbox.yZOfXCeX.js → checkbox.0BeV1IBL.js} +1 -1
- streamlit/static/static/js/{createSuper.Dh9w1cs8.js → createSuper.RBO59fEm.js} +1 -1
- streamlit/static/static/js/data-grid-overlay-editor.CiTkUy0t.js +1 -0
- streamlit/static/static/js/{downloader.MeHtkq8r.js → downloader.DwNZg3Mw.js} +1 -1
- streamlit/static/static/js/embed.XT9xNd3F.js +195 -0
- streamlit/static/static/js/{es6.VpBPGCnM.js → es6.x9KsYQg-.js} +2 -2
- streamlit/static/static/js/{iframeResizer.contentWindow.yMw_ARIL.js → iframeResizer.contentWindow.ZVXpMPi0.js} +1 -1
- streamlit/static/static/js/index.5VPOamri.js +1 -0
- streamlit/static/static/js/index.8HslT92O.js +14 -0
- streamlit/static/static/js/index.AnXMIBz3.js +7 -0
- streamlit/static/static/js/index.B0yp3bM1.js +6 -0
- streamlit/static/static/js/index.B1fRb5wF.js +1 -0
- streamlit/static/static/js/index.B527JZdO.js +3 -0
- streamlit/static/static/js/index.BHgV-yW4.js +1 -0
- streamlit/static/static/js/index.BQr-XwGV.js +1 -0
- streamlit/static/static/js/index.BTtmaLDB.js +1 -0
- streamlit/static/static/js/index.BWB_91TA.js +1 -0
- streamlit/static/static/js/index.BfEKaEmw.js +1 -0
- streamlit/static/static/js/index.BfXjTO8b.js +1 -0
- streamlit/static/static/js/index.Bjy4NRu9.js +3 -0
- streamlit/static/static/js/index.Bu5JWpT_.js +1 -0
- streamlit/static/static/js/index.BuCx76ZV.js +1 -0
- streamlit/static/static/js/index.BxjzhVUb.js +2 -0
- streamlit/static/static/js/index.By55VdPY.js +1 -0
- streamlit/static/static/js/index.CF5MxTbK.js +1 -0
- streamlit/static/static/js/index.CLmq_z9K.js +1 -0
- streamlit/static/static/js/index.CNH4rdSz.js +1 -0
- streamlit/static/static/js/{index.B0H9IXUJ.js → index.CTgm_-jO.js} +10 -41
- streamlit/static/static/js/index.C_rK-Swb.js +188 -0
- streamlit/static/static/js/index.CjozwSzS.js +1 -0
- streamlit/static/static/js/{index.CH1tqnSs.js → index.CkGVt6-G.js} +1 -1
- streamlit/static/static/js/index.CuvXOyER.js +2 -0
- streamlit/static/static/js/{index.FFOzOWzC.js → index.CyUHWoCC.js} +2 -2
- streamlit/static/static/js/index.CyroQtI4.js +2 -0
- streamlit/static/static/js/index.D6HmkoDm.js +263 -0
- streamlit/static/static/js/index.DAqCNvsO.js +1 -0
- streamlit/static/static/js/index.DB_w_CZQ.js +1 -0
- streamlit/static/static/js/index.DBalctjj.js +2 -0
- streamlit/static/static/js/index.DK0RFJUG.js +11 -0
- streamlit/static/static/js/index.DMxc2XFp.js +151 -0
- streamlit/static/static/js/index.DO5utP74.js +2 -0
- streamlit/static/static/js/index.DS7lf09n.js +1 -0
- streamlit/static/static/js/index.DWexTVLY.js +1 -0
- streamlit/static/static/js/index.DXxnU5ej.js +1 -0
- streamlit/static/static/js/index.DcU3uDvB.js +2 -0
- streamlit/static/static/js/index.DlltaH7J.js +1 -0
- streamlit/static/static/js/index.DpNTZz82.js +27 -0
- streamlit/static/static/js/index.Dr9HIhQw.js +1 -0
- streamlit/static/static/js/index.DsgAU5lc.js +1 -0
- streamlit/static/static/js/{index.64ejlaaT.js → index.KfXqjDYy.js} +1 -1
- streamlit/static/static/js/index.PaidgjCs.js +1 -0
- streamlit/static/static/js/index.RJZuWCGA.js +1 -0
- streamlit/static/static/js/{index.Ctn27_AE.js → index.hbeqcRTn.js} +53 -122
- streamlit/static/static/js/index.q5hIQwAY.js +1 -0
- streamlit/static/static/js/index.rORSX6IW.js +1 -0
- streamlit/static/static/js/index.uSX757_v.js +1 -0
- streamlit/static/static/js/index.x_QRaLMd.js +1 -0
- streamlit/static/static/js/{input.s6pjQ49A.js → input.D5oh9-aB.js} +2 -2
- streamlit/static/static/js/main.q9oGOg0H.js +13 -0
- streamlit/static/static/js/{memory.Cuvsdfrl.js → memory.5kCSFUJS.js} +1 -1
- streamlit/static/static/js/moment.C3j7ZXd7.js +4 -0
- streamlit/static/static/js/number-overlay-editor.Cn_LsK8N.js +9 -0
- streamlit/static/static/js/pandasStylerUtils.BqhXt51_.js +1 -0
- streamlit/static/static/js/{possibleConstructorReturn.CqidKeei.js → possibleConstructorReturn.DD9NK1Z8.js} +1 -1
- streamlit/static/static/js/record.B-tDciZb.js +1 -0
- streamlit/static/static/js/{sandbox.CCQREcJx.js → sandbox.DACSyz29.js} +1 -1
- streamlit/static/static/js/styled-components.C3R090At.js +1 -0
- streamlit/static/static/js/threshold.Q1mXg5rX.js +1 -0
- streamlit/static/static/js/throttle.B0GR3Iyz.js +1 -0
- streamlit/static/static/js/{timepicker.mkJF97Bb.js → timepicker.BdhzPxrv.js} +1 -1
- streamlit/static/static/js/timer.C2hYhUse.js +1 -0
- streamlit/static/static/js/{toConsumableArray.De7I7KVR.js → toConsumableArray.Db2pdqM2.js} +1 -1
- streamlit/static/static/js/uniqueId.CtqIr-Yh.js +1 -0
- streamlit/static/static/js/urls.BwSlolu9.js +1 -0
- streamlit/static/static/js/{useBasicWidgetState.CedkNjUW.js → useBasicWidgetState.Bfp6TnSw.js} +1 -1
- streamlit/static/static/js/useIntlLocale.hRV75Xgj.js +12 -0
- streamlit/static/static/js/{useTextInputAutoExpand.Ca7w8dVs.js → useTextInputAutoExpand.QepX7n8Y.js} +1 -1
- streamlit/static/static/js/useUpdateUiValue.DHx8TzX6.js +1 -0
- streamlit/static/static/js/useWaveformController.WxVzpzEX.js +1 -0
- streamlit/static/static/js/value.B4vHRSi7.js +1 -0
- streamlit/static/static/js/wavesurfer.esm.vI8Eid4k.js +73 -0
- streamlit/static/static/js/withCalculatedWidth.DcKeRSWJ.js +1 -0
- streamlit/static/static/js/withFullScreenWrapper.CrHddARq.js +1 -0
- streamlit/static/static/media/MaterialSymbols-Rounded.C7IFxh57.woff2 +0 -0
- streamlit/string_util.py +9 -4
- streamlit/testing/v1/app_test.py +17 -2
- streamlit/testing/v1/element_tree.py +85 -9
- streamlit/testing/v1/util.py +2 -2
- streamlit/type_util.py +3 -4
- streamlit/url_util.py +1 -3
- streamlit/user_info.py +1 -2
- streamlit/util.py +3 -1
- streamlit/watcher/event_based_path_watcher.py +23 -12
- streamlit/watcher/local_sources_watcher.py +11 -1
- streamlit/watcher/path_watcher.py +9 -6
- streamlit/watcher/polling_path_watcher.py +4 -1
- streamlit/watcher/util.py +2 -2
- streamlit/web/bootstrap.py +24 -0
- streamlit/web/cli.py +51 -22
- streamlit/web/server/bidi_component_request_handler.py +193 -0
- streamlit/web/server/component_file_utils.py +97 -0
- streamlit/web/server/component_request_handler.py +8 -21
- streamlit/web/server/oauth_authlib_routes.py +5 -2
- streamlit/web/server/oidc_mixin.py +3 -1
- streamlit/web/server/routes.py +2 -2
- streamlit/web/server/server.py +9 -0
- streamlit/web/server/server_util.py +3 -1
- streamlit/web/server/upload_file_request_handler.py +19 -1
- {streamlit-1.50.0.dist-info → streamlit-1.52.0.dist-info}/METADATA +10 -7
- streamlit-1.52.0.dist-info/RECORD +620 -0
- streamlit/static/static/css/index.CHEnSPGk.css +0 -1
- streamlit/static/static/js/Hooks.BRba_Own.js +0 -1
- streamlit/static/static/js/InputInstructions.xnSDuYeQ.js +0 -1
- streamlit/static/static/js/Particles.CElH0XX2.js +0 -1
- streamlit/static/static/js/data-grid-overlay-editor.DcuHuCyW.js +0 -1
- streamlit/static/static/js/index.6xX1278W.js +0 -975
- streamlit/static/static/js/index.B-hiXRzw.js +0 -1
- streamlit/static/static/js/index.B4cAbHP6.js +0 -1
- streamlit/static/static/js/index.B4dUQfni.js +0 -1
- streamlit/static/static/js/index.BPQo7BKk.js +0 -1
- streamlit/static/static/js/index.Baqa90pe.js +0 -2
- streamlit/static/static/js/index.Bj9JgOEC.js +0 -1
- streamlit/static/static/js/index.BjCwMzj4.js +0 -3
- streamlit/static/static/js/index.Bm3VbPB5.js +0 -1
- streamlit/static/static/js/index.Bxz2yX3P.js +0 -1
- streamlit/static/static/js/index.BycLveZ4.js +0 -1
- streamlit/static/static/js/index.C9BdUqTi.js +0 -1
- streamlit/static/static/js/index.CFMf5_ez.js +0 -197
- streamlit/static/static/js/index.CGYqqs6j.js +0 -1
- streamlit/static/static/js/index.CMItVsFA.js +0 -1
- streamlit/static/static/js/index.CTBk8Vk2.js +0 -1
- streamlit/static/static/js/index.CiAQIz1H.js +0 -7
- streamlit/static/static/js/index.Cj7DSzVR.js +0 -73
- streamlit/static/static/js/index.Ck8rQ9OL.js +0 -1
- streamlit/static/static/js/index.ClELlchS.js +0 -1617
- streamlit/static/static/js/index.Cnpi3o3E.js +0 -1
- streamlit/static/static/js/index.D2QEXQq_.js +0 -1
- streamlit/static/static/js/index.DH71Ezyj.js +0 -1
- streamlit/static/static/js/index.DHh-U0dK.js +0 -3
- streamlit/static/static/js/index.DK7hD7_w.js +0 -1
- streamlit/static/static/js/index.DKv_lNO7.js +0 -2
- streamlit/static/static/js/index.DNLrMXgm.js +0 -12
- streamlit/static/static/js/index.DW0Grddz.js +0 -1
- streamlit/static/static/js/index.Dbe-Q3C-.js +0 -2
- streamlit/static/static/js/index.DcPNYEUo.js +0 -1
- streamlit/static/static/js/index.DuxqVQpd.js +0 -1
- streamlit/static/static/js/index.GRUzrudl.js +0 -1
- streamlit/static/static/js/number-overlay-editor.DdgVR5m3.js +0 -9
- streamlit/static/static/js/uniqueId.RI1LJdtz.js +0 -1
- streamlit/static/static/js/useUpdateUiValue.DeXelfRH.js +0 -1
- streamlit/static/static/js/withFullScreenWrapper.C3561XxJ.js +0 -1
- streamlit/static/static/media/MaterialSymbols-Rounded.DeCZgS-4.woff2 +0 -0
- streamlit-1.50.0.dist-info/RECORD +0 -557
- {streamlit-1.50.0.data → streamlit-1.52.0.data}/scripts/streamlit.cmd +0 -0
- {streamlit-1.50.0.dist-info → streamlit-1.52.0.dist-info}/WHEEL +0 -0
- {streamlit-1.50.0.dist-info → streamlit-1.52.0.dist-info}/entry_points.txt +0 -0
- {streamlit-1.50.0.dist-info → streamlit-1.52.0.dist-info}/top_level.txt +0 -0
streamlit/elements/html.py
CHANGED
|
@@ -42,6 +42,7 @@ class HtmlMixin:
|
|
|
42
42
|
body: str | Path | SupportsStr | SupportsReprHtml,
|
|
43
43
|
*, # keyword-only arguments:
|
|
44
44
|
width: Width = "stretch",
|
|
45
|
+
unsafe_allow_javascript: bool = False,
|
|
45
46
|
) -> DeltaGenerator:
|
|
46
47
|
"""Insert HTML into your app.
|
|
47
48
|
|
|
@@ -52,8 +53,10 @@ class HtmlMixin:
|
|
|
52
53
|
loading external code can increase the risk of vulnerabilities in your
|
|
53
54
|
app.
|
|
54
55
|
|
|
55
|
-
``st.html`` content is **not** iframed.
|
|
56
|
-
|
|
56
|
+
``st.html`` content is **not** iframed. By default, JavaScript is
|
|
57
|
+
ignored. To execute JavaScript contained in your HTML, set
|
|
58
|
+
``unsafe_allow_javascript=True``. Use this with caution and never pass
|
|
59
|
+
untrusted input.
|
|
57
60
|
|
|
58
61
|
Parameters
|
|
59
62
|
----------
|
|
@@ -89,6 +92,12 @@ class HtmlMixin:
|
|
|
89
92
|
the parent container, the width of the element matches the width
|
|
90
93
|
of the parent container.
|
|
91
94
|
|
|
95
|
+
unsafe_allow_javascript : bool
|
|
96
|
+
Whether to execute JavaScript contained in your HTML. If this is
|
|
97
|
+
``False`` (default), JavaScript is ignored. If this is ``True``,
|
|
98
|
+
JavaScript is executed. Use this with caution and never pass
|
|
99
|
+
untrusted input.
|
|
100
|
+
|
|
92
101
|
Example
|
|
93
102
|
-------
|
|
94
103
|
>>> import streamlit as st
|
|
@@ -136,6 +145,8 @@ class HtmlMixin:
|
|
|
136
145
|
html_proto.body = html_content
|
|
137
146
|
return self._event_dg._enqueue("html", html_proto)
|
|
138
147
|
# Otherwise, send the html to the main container as normal
|
|
148
|
+
# Only set the unsafe JS flag for non-style-only HTML content
|
|
149
|
+
html_proto.unsafe_allow_javascript = unsafe_allow_javascript
|
|
139
150
|
html_proto.body = html_content
|
|
140
151
|
return self.dg._enqueue("html", html_proto, layout_config=layout_config)
|
|
141
152
|
|
streamlit/elements/image.py
CHANGED
|
@@ -21,9 +21,7 @@
|
|
|
21
21
|
|
|
22
22
|
from __future__ import annotations
|
|
23
23
|
|
|
24
|
-
from typing import TYPE_CHECKING, Literal,
|
|
25
|
-
|
|
26
|
-
from typing_extensions import TypeAlias
|
|
24
|
+
from typing import TYPE_CHECKING, Literal, TypeAlias, cast
|
|
27
25
|
|
|
28
26
|
from streamlit.deprecation_util import (
|
|
29
27
|
make_deprecated_name_warning,
|
|
@@ -43,7 +41,7 @@ from streamlit.runtime.metrics_util import gather_metrics
|
|
|
43
41
|
if TYPE_CHECKING:
|
|
44
42
|
from streamlit.delta_generator import DeltaGenerator
|
|
45
43
|
|
|
46
|
-
UseColumnWith: TypeAlias =
|
|
44
|
+
UseColumnWith: TypeAlias = Literal["auto", "always", "never"] | bool | None
|
|
47
45
|
|
|
48
46
|
|
|
49
47
|
class ImageMixin:
|
|
@@ -173,7 +171,7 @@ class ImageMixin:
|
|
|
173
171
|
|
|
174
172
|
show_deprecation_warning(
|
|
175
173
|
"The `use_column_width` parameter has been deprecated and will be removed "
|
|
176
|
-
"in a future release. Please utilize the `
|
|
174
|
+
"in a future release. Please utilize the `width` parameter instead."
|
|
177
175
|
)
|
|
178
176
|
if use_column_width in {"auto", "never"} or use_column_width is False:
|
|
179
177
|
width = "content"
|
streamlit/elements/layouts.py
CHANGED
|
@@ -15,9 +15,7 @@
|
|
|
15
15
|
from __future__ import annotations
|
|
16
16
|
|
|
17
17
|
from collections.abc import Sequence
|
|
18
|
-
from typing import TYPE_CHECKING, Literal,
|
|
19
|
-
|
|
20
|
-
from typing_extensions import TypeAlias
|
|
18
|
+
from typing import TYPE_CHECKING, Literal, TypeAlias, cast
|
|
21
19
|
|
|
22
20
|
from streamlit.delta_generator_singletons import get_dg_singleton_instance
|
|
23
21
|
from streamlit.elements.lib.layout_utils import (
|
|
@@ -54,7 +52,7 @@ if TYPE_CHECKING:
|
|
|
54
52
|
from streamlit.elements.lib.mutable_status_container import StatusContainer
|
|
55
53
|
from streamlit.runtime.state import WidgetCallback
|
|
56
54
|
|
|
57
|
-
SpecType: TypeAlias =
|
|
55
|
+
SpecType: TypeAlias = int | Sequence[int | float]
|
|
58
56
|
|
|
59
57
|
|
|
60
58
|
class LayoutsMixin:
|
|
@@ -64,7 +62,7 @@ class LayoutsMixin:
|
|
|
64
62
|
*,
|
|
65
63
|
border: bool | None = None,
|
|
66
64
|
key: Key | None = None,
|
|
67
|
-
width:
|
|
65
|
+
width: Width = "stretch",
|
|
68
66
|
height: Height = "content",
|
|
69
67
|
horizontal: bool = False,
|
|
70
68
|
horizontal_alignment: HorizontalAlignment = "left",
|
|
@@ -94,11 +92,13 @@ class LayoutsMixin:
|
|
|
94
92
|
Additionally, if ``key`` is provided, it will be used as CSS
|
|
95
93
|
class name prefixed with ``st-key-``.
|
|
96
94
|
|
|
97
|
-
width : "stretch" or int
|
|
95
|
+
width : "stretch", "content", or int
|
|
98
96
|
The width of the container. This can be one of the following:
|
|
99
97
|
|
|
100
98
|
- ``"stretch"`` (default): The width of the container matches the
|
|
101
99
|
width of the parent container.
|
|
100
|
+
- ``"content"``: The width of the container matches the width of
|
|
101
|
+
its content.
|
|
102
102
|
- An integer specifying the width in pixels: The container has a
|
|
103
103
|
fixed width. If the specified width is greater than the width of
|
|
104
104
|
the parent container, the width of the container matches the width
|
|
@@ -201,7 +201,7 @@ class LayoutsMixin:
|
|
|
201
201
|
>>>
|
|
202
202
|
>>> st.write("This is outside the container")
|
|
203
203
|
|
|
204
|
-
.. output
|
|
204
|
+
.. output::
|
|
205
205
|
https://doc-container1.streamlit.app/
|
|
206
206
|
height: 520px
|
|
207
207
|
|
|
@@ -220,7 +220,7 @@ class LayoutsMixin:
|
|
|
220
220
|
>>>
|
|
221
221
|
>>> container.write("This is inside too")
|
|
222
222
|
|
|
223
|
-
.. output
|
|
223
|
+
.. output::
|
|
224
224
|
https://doc-container2.streamlit.app/
|
|
225
225
|
height: 300px
|
|
226
226
|
|
|
@@ -238,7 +238,7 @@ class LayoutsMixin:
|
|
|
238
238
|
>>> tile = col.container(height=120)
|
|
239
239
|
>>> tile.title(":balloon:")
|
|
240
240
|
|
|
241
|
-
.. output
|
|
241
|
+
.. output::
|
|
242
242
|
https://doc-container3.streamlit.app/
|
|
243
243
|
height: 350px
|
|
244
244
|
|
|
@@ -254,7 +254,7 @@ class LayoutsMixin:
|
|
|
254
254
|
>>> with st.container(height=300):
|
|
255
255
|
>>> st.markdown(long_text)
|
|
256
256
|
|
|
257
|
-
.. output
|
|
257
|
+
.. output::
|
|
258
258
|
https://doc-container4.streamlit.app/
|
|
259
259
|
height: 400px
|
|
260
260
|
|
|
@@ -270,7 +270,7 @@ class LayoutsMixin:
|
|
|
270
270
|
>>> for card in range(3):
|
|
271
271
|
>>> flex.button(f"Button {card + 1}")
|
|
272
272
|
|
|
273
|
-
.. output
|
|
273
|
+
.. output::
|
|
274
274
|
https://doc-container5.streamlit.app/
|
|
275
275
|
height: 250px
|
|
276
276
|
|
|
@@ -300,7 +300,7 @@ class LayoutsMixin:
|
|
|
300
300
|
block_proto.flex_container.justify = get_justify(vertical_alignment)
|
|
301
301
|
block_proto.flex_container.align = get_align(horizontal_alignment)
|
|
302
302
|
|
|
303
|
-
validate_width(width)
|
|
303
|
+
validate_width(width, allow_content=True)
|
|
304
304
|
block_proto.width_config.CopyFrom(get_width_config(width))
|
|
305
305
|
|
|
306
306
|
if isinstance(height, int) or border:
|
|
@@ -385,13 +385,15 @@ class LayoutsMixin:
|
|
|
385
385
|
``False`` (default), no border is shown. If this is ``True``, a
|
|
386
386
|
border is shown around each column.
|
|
387
387
|
|
|
388
|
-
width :
|
|
389
|
-
The
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
388
|
+
width : "stretch" or int
|
|
389
|
+
The width of the column group. This can be one of the following:
|
|
390
|
+
|
|
391
|
+
- ``"stretch"`` (default): The width of the column group matches the
|
|
392
|
+
width of the parent container.
|
|
393
|
+
- An integer specifying the width in pixels: The column group has a
|
|
394
|
+
fixed width. If the specified width is greater than the width of
|
|
395
|
+
the parent container, the width of the column group matches the
|
|
396
|
+
width of the parent container.
|
|
395
397
|
|
|
396
398
|
Returns
|
|
397
399
|
-------
|
|
@@ -420,7 +422,7 @@ class LayoutsMixin:
|
|
|
420
422
|
... st.header("An owl")
|
|
421
423
|
... st.image("https://static.streamlit.io/examples/owl.jpg")
|
|
422
424
|
|
|
423
|
-
.. output
|
|
425
|
+
.. output::
|
|
424
426
|
https://doc-columns1.streamlit.app/
|
|
425
427
|
height: 620px
|
|
426
428
|
|
|
@@ -441,7 +443,7 @@ class LayoutsMixin:
|
|
|
441
443
|
>>> col2.subheader("A narrow column with the data")
|
|
442
444
|
>>> col2.write(df)
|
|
443
445
|
|
|
444
|
-
.. output
|
|
446
|
+
.. output::
|
|
445
447
|
https://doc-columns2.streamlit.app/
|
|
446
448
|
height: 550px
|
|
447
449
|
|
|
@@ -457,7 +459,7 @@ class LayoutsMixin:
|
|
|
457
459
|
>>> middle.button("Click me", use_container_width=True)
|
|
458
460
|
>>> right.checkbox("Check me")
|
|
459
461
|
|
|
460
|
-
.. output
|
|
462
|
+
.. output::
|
|
461
463
|
https://doc-columns-bottom-widgets.streamlit.app/
|
|
462
464
|
height: 200px
|
|
463
465
|
|
|
@@ -476,7 +478,7 @@ class LayoutsMixin:
|
|
|
476
478
|
>>> middle.image("https://static.streamlit.io/examples/dog.jpg")
|
|
477
479
|
>>> right.image("https://static.streamlit.io/examples/owl.jpg")
|
|
478
480
|
|
|
479
|
-
.. output
|
|
481
|
+
.. output::
|
|
480
482
|
https://doc-columns-vertical-alignment.streamlit.app/
|
|
481
483
|
height: 600px
|
|
482
484
|
|
|
@@ -493,7 +495,7 @@ class LayoutsMixin:
|
|
|
493
495
|
>>> middle.markdown("Lorem ipsum " * 5)
|
|
494
496
|
>>> right.markdown("Lorem ipsum ")
|
|
495
497
|
|
|
496
|
-
.. output
|
|
498
|
+
.. output::
|
|
497
499
|
https://doc-columns-borders.streamlit.app/
|
|
498
500
|
height: 250px
|
|
499
501
|
|
|
@@ -640,7 +642,7 @@ class LayoutsMixin:
|
|
|
640
642
|
... st.header("An owl")
|
|
641
643
|
... st.image("https://static.streamlit.io/examples/owl.jpg", width=200)
|
|
642
644
|
|
|
643
|
-
.. output
|
|
645
|
+
.. output::
|
|
644
646
|
https://doc-tabs1.streamlit.app/
|
|
645
647
|
height: 620px
|
|
646
648
|
|
|
@@ -661,7 +663,7 @@ class LayoutsMixin:
|
|
|
661
663
|
>>> tab2.subheader("A tab with the data")
|
|
662
664
|
>>> tab2.write(df)
|
|
663
665
|
|
|
664
|
-
.. output
|
|
666
|
+
.. output::
|
|
665
667
|
https://doc-tabs2.streamlit.app/
|
|
666
668
|
height: 700px
|
|
667
669
|
|
|
@@ -686,7 +688,7 @@ class LayoutsMixin:
|
|
|
686
688
|
>>> st.header("An owl")
|
|
687
689
|
>>> st.image("https://static.streamlit.io/examples/owl.jpg", width=200)
|
|
688
690
|
|
|
689
|
-
.. output
|
|
691
|
+
.. output::
|
|
690
692
|
https://doc-tabs3.streamlit.app/
|
|
691
693
|
height: 620px
|
|
692
694
|
|
|
@@ -791,6 +793,8 @@ class LayoutsMixin:
|
|
|
791
793
|
<https://fonts.google.com/icons?icon.set=Material+Symbols&icon.style=Rounded>`_
|
|
792
794
|
font library.
|
|
793
795
|
|
|
796
|
+
- ``"spinner"``: Displays a spinner as an icon.
|
|
797
|
+
|
|
794
798
|
width : "stretch" or int
|
|
795
799
|
The width of the expander container. This can be one of the following:
|
|
796
800
|
|
|
@@ -817,7 +821,7 @@ class LayoutsMixin:
|
|
|
817
821
|
... ''')
|
|
818
822
|
... st.image("https://static.streamlit.io/examples/dice.jpg")
|
|
819
823
|
|
|
820
|
-
.. output
|
|
824
|
+
.. output::
|
|
821
825
|
https://doc-expander.streamlit.app/
|
|
822
826
|
height: 750px
|
|
823
827
|
|
|
@@ -835,7 +839,7 @@ class LayoutsMixin:
|
|
|
835
839
|
... ''')
|
|
836
840
|
>>> expander.image("https://static.streamlit.io/examples/dice.jpg")
|
|
837
841
|
|
|
838
|
-
.. output
|
|
842
|
+
.. output::
|
|
839
843
|
https://doc-expander.streamlit.app/
|
|
840
844
|
height: 750px
|
|
841
845
|
|
|
@@ -862,6 +866,7 @@ class LayoutsMixin:
|
|
|
862
866
|
self,
|
|
863
867
|
label: str,
|
|
864
868
|
*,
|
|
869
|
+
type: Literal["primary", "secondary", "tertiary"] = "secondary",
|
|
865
870
|
help: str | None = None,
|
|
866
871
|
icon: str | None = None,
|
|
867
872
|
disabled: bool = False,
|
|
@@ -912,6 +917,17 @@ class LayoutsMixin:
|
|
|
912
917
|
including the Markdown directives described in the ``body``
|
|
913
918
|
parameter of ``st.markdown``.
|
|
914
919
|
|
|
920
|
+
type : "primary", "secondary", or "tertiary"
|
|
921
|
+
An optional string that specifies the button type. This can be one
|
|
922
|
+
of the following:
|
|
923
|
+
|
|
924
|
+
- ``"primary"``: The button's background is the app's primary color
|
|
925
|
+
for additional emphasis.
|
|
926
|
+
- ``"secondary"`` (default): The button's background coordinates
|
|
927
|
+
with the app's background color for normal emphasis.
|
|
928
|
+
- ``"tertiary"``: The button is plain text without a border or
|
|
929
|
+
background for subtlety.
|
|
930
|
+
|
|
915
931
|
icon : str
|
|
916
932
|
An optional emoji or icon to display next to the button label. If ``icon``
|
|
917
933
|
is ``None`` (default), no icon is displayed. If ``icon`` is a
|
|
@@ -929,6 +945,8 @@ class LayoutsMixin:
|
|
|
929
945
|
<https://fonts.google.com/icons?icon.set=Material+Symbols&icon.style=Rounded>`_
|
|
930
946
|
font library.
|
|
931
947
|
|
|
948
|
+
- ``"spinner"``: Displays a spinner as an icon.
|
|
949
|
+
|
|
932
950
|
disabled : bool
|
|
933
951
|
An optional boolean that disables the popover button if set to
|
|
934
952
|
``True``. The default is ``False``.
|
|
@@ -981,7 +999,7 @@ class LayoutsMixin:
|
|
|
981
999
|
>>>
|
|
982
1000
|
>>> st.write("Your name:", name)
|
|
983
1001
|
|
|
984
|
-
.. output
|
|
1002
|
+
.. output::
|
|
985
1003
|
https://doc-popover.streamlit.app/
|
|
986
1004
|
height: 400px
|
|
987
1005
|
|
|
@@ -998,7 +1016,7 @@ class LayoutsMixin:
|
|
|
998
1016
|
>>> if blue:
|
|
999
1017
|
... st.write(":blue[This is a blue item.]")
|
|
1000
1018
|
|
|
1001
|
-
.. output
|
|
1019
|
+
.. output::
|
|
1002
1020
|
https://doc-popover2.streamlit.app/
|
|
1003
1021
|
height: 400px
|
|
1004
1022
|
|
|
@@ -1009,9 +1027,17 @@ class LayoutsMixin:
|
|
|
1009
1027
|
if use_container_width is not None:
|
|
1010
1028
|
width = "stretch" if use_container_width else "content"
|
|
1011
1029
|
|
|
1030
|
+
# Checks whether the entered button type is one of the allowed options
|
|
1031
|
+
if type not in ["primary", "secondary", "tertiary"]:
|
|
1032
|
+
raise StreamlitAPIException(
|
|
1033
|
+
'The type argument to st.popover must be "primary", "secondary", or "tertiary". '
|
|
1034
|
+
f'\nThe argument passed was "{type}".'
|
|
1035
|
+
)
|
|
1036
|
+
|
|
1012
1037
|
popover_proto = BlockProto.Popover()
|
|
1013
1038
|
popover_proto.label = label
|
|
1014
1039
|
popover_proto.disabled = disabled
|
|
1040
|
+
popover_proto.type = type
|
|
1015
1041
|
if help:
|
|
1016
1042
|
popover_proto.help = str(help)
|
|
1017
1043
|
if icon is not None:
|
|
@@ -1122,7 +1148,7 @@ class LayoutsMixin:
|
|
|
1122
1148
|
>>>
|
|
1123
1149
|
>>> st.button("Rerun")
|
|
1124
1150
|
|
|
1125
|
-
.. output
|
|
1151
|
+
.. output::
|
|
1126
1152
|
https://doc-status.streamlit.app/
|
|
1127
1153
|
height: 300px
|
|
1128
1154
|
|
|
@@ -1145,7 +1171,7 @@ class LayoutsMixin:
|
|
|
1145
1171
|
>>>
|
|
1146
1172
|
>>> st.button("Rerun")
|
|
1147
1173
|
|
|
1148
|
-
.. output
|
|
1174
|
+
.. output::
|
|
1149
1175
|
https://doc-status-update.streamlit.app/
|
|
1150
1176
|
height: 300px
|
|
1151
1177
|
|
|
@@ -19,9 +19,7 @@ from __future__ import annotations
|
|
|
19
19
|
from dataclasses import dataclass
|
|
20
20
|
from datetime import date
|
|
21
21
|
from enum import Enum
|
|
22
|
-
from typing import TYPE_CHECKING, Any, Final, Literal, TypedDict, cast
|
|
23
|
-
|
|
24
|
-
from typing_extensions import TypeAlias
|
|
22
|
+
from typing import TYPE_CHECKING, Any, Final, Literal, TypeAlias, TypedDict, cast
|
|
25
23
|
|
|
26
24
|
from streamlit import dataframe_util, type_util
|
|
27
25
|
from streamlit.elements.lib.color_util import (
|
|
@@ -48,6 +46,11 @@ if TYPE_CHECKING:
|
|
|
48
46
|
VegaLiteType: TypeAlias = Literal["quantitative", "ordinal", "temporal", "nominal"]
|
|
49
47
|
ChartStackType: TypeAlias = Literal["normalize", "center", "layered"]
|
|
50
48
|
|
|
49
|
+
# Threshold for applying hover event throttling on large datasets.
|
|
50
|
+
# For datasets with more points than this threshold, hover events are throttled
|
|
51
|
+
# to 16ms (~60fps) to improve performance.
|
|
52
|
+
_LARGE_DATASET_POINT_THRESHOLD: Final = 1000
|
|
53
|
+
|
|
51
54
|
|
|
52
55
|
class PrepDataColumns(TypedDict):
|
|
53
56
|
"""Columns used for the prep_data step in Altair Arrow charts."""
|
|
@@ -288,37 +291,65 @@ def generate_chart(
|
|
|
288
291
|
and is_altair_version_5_or_greater
|
|
289
292
|
):
|
|
290
293
|
return _add_improved_hover_tooltips(
|
|
291
|
-
chart, x_column, chart_width, chart_height
|
|
294
|
+
chart, x_column, chart_width, chart_height, len(df)
|
|
292
295
|
).interactive(), add_rows_metadata
|
|
293
296
|
|
|
294
297
|
return chart.interactive(), add_rows_metadata
|
|
295
298
|
|
|
296
299
|
|
|
297
300
|
def _add_improved_hover_tooltips(
|
|
298
|
-
chart: alt.Chart,
|
|
301
|
+
chart: alt.Chart,
|
|
302
|
+
x_column: str,
|
|
303
|
+
width: int | None,
|
|
304
|
+
height: int | None,
|
|
305
|
+
data_point_count: int,
|
|
299
306
|
) -> alt.LayerChart:
|
|
300
|
-
"""Adds improved hover tooltips to an existing line chart.
|
|
307
|
+
"""Adds improved hover tooltips to an existing line chart.
|
|
308
|
+
|
|
309
|
+
This implementation uses a three-layer approach for better performance:
|
|
310
|
+
1. Base chart layer: The original line chart
|
|
311
|
+
2. Detection layer: Invisible points for detecting the nearest point on hover
|
|
312
|
+
3. Highlight layer: Only renders the selected point(s) using transform_filter
|
|
313
|
+
|
|
314
|
+
The filter-based approach is more efficient than using conditional opacity
|
|
315
|
+
because it only renders the selected point(s) rather than evaluating opacity
|
|
316
|
+
for every single data point on each hover event.
|
|
317
|
+
"""
|
|
301
318
|
|
|
302
319
|
import altair as alt
|
|
303
320
|
|
|
304
|
-
#
|
|
321
|
+
# Throttle hover events for large datasets to 16ms (~60fps) to improve performance.
|
|
322
|
+
# For smaller datasets, use standard mousemove without throttling.
|
|
323
|
+
hover_event = (
|
|
324
|
+
"mousemove{16}"
|
|
325
|
+
if data_point_count > _LARGE_DATASET_POINT_THRESHOLD
|
|
326
|
+
else "mousemove"
|
|
327
|
+
)
|
|
328
|
+
|
|
329
|
+
# Create a selection that chooses the nearest point & selects based on x-value.
|
|
330
|
+
# Uses mouseleave instead of mouseout/pointerout for more reliable hover clearing
|
|
331
|
+
# (mouseout fires when moving over child elements like tooltips).
|
|
305
332
|
nearest = alt.selection_point(
|
|
306
333
|
nearest=True,
|
|
307
|
-
on=
|
|
334
|
+
on=hover_event,
|
|
308
335
|
fields=[x_column],
|
|
309
336
|
empty=False,
|
|
310
|
-
clear="
|
|
337
|
+
clear="mouseleave",
|
|
311
338
|
)
|
|
312
339
|
|
|
313
|
-
#
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
340
|
+
# Detection layer: Invisible points for detecting the nearest point.
|
|
341
|
+
# This layer is needed because selections must be attached to a mark.
|
|
342
|
+
detection_points = chart.mark_point(opacity=0).add_params(nearest)
|
|
343
|
+
|
|
344
|
+
# Highlight layer: Only renders the selected point(s) using transform_filter.
|
|
345
|
+
# This is more efficient than conditional opacity because it only renders
|
|
346
|
+
# the filtered data (typically 1-2 points) rather than all points.
|
|
347
|
+
highlighted_points = chart.mark_point(filled=True, size=65).transform_filter(
|
|
348
|
+
nearest
|
|
318
349
|
)
|
|
319
350
|
|
|
320
351
|
layer_chart = (
|
|
321
|
-
alt.layer(chart,
|
|
352
|
+
alt.layer(chart, detection_points, highlighted_points)
|
|
322
353
|
.configure_legend(symbolType="stroke")
|
|
323
354
|
.properties(
|
|
324
355
|
width=width or 0,
|
|
@@ -340,7 +371,7 @@ def prep_chart_data_for_add_rows(
|
|
|
340
371
|
"""
|
|
341
372
|
import pandas as pd
|
|
342
373
|
|
|
343
|
-
df =
|
|
374
|
+
df = dataframe_util.convert_anything_to_pandas_df(data)
|
|
344
375
|
|
|
345
376
|
# Make range indices start at last_index.
|
|
346
377
|
if isinstance(df.index, pd.RangeIndex):
|
|
@@ -433,7 +464,7 @@ def _infer_vegalite_type(
|
|
|
433
464
|
|
|
434
465
|
|
|
435
466
|
def _get_pandas_index_attr(
|
|
436
|
-
data: pd.DataFrame | pd.Series,
|
|
467
|
+
data: pd.DataFrame | pd.Series[Any],
|
|
437
468
|
attr: str,
|
|
438
469
|
) -> Any | None:
|
|
439
470
|
return getattr(data.index, attr, None)
|
|
@@ -636,7 +667,7 @@ def _drop_unused_columns(df: pd.DataFrame, *column_names: str | None) -> pd.Data
|
|
|
636
667
|
seen.add(x)
|
|
637
668
|
keep.append(x)
|
|
638
669
|
|
|
639
|
-
return df[keep]
|
|
670
|
+
return df[keep] # ty: ignore[invalid-return-type]
|
|
640
671
|
|
|
641
672
|
|
|
642
673
|
def _maybe_convert_color_column_in_place(
|
|
@@ -653,7 +684,7 @@ def _maybe_convert_color_column_in_place(
|
|
|
653
684
|
pass
|
|
654
685
|
elif is_color_tuple_like(first_color_datum):
|
|
655
686
|
# Tuples need to be converted to CSS-valid.
|
|
656
|
-
df.loc[:, color_column] = df[color_column].
|
|
687
|
+
df.loc[:, color_column] = df[color_column].apply(to_css_color)
|
|
657
688
|
else:
|
|
658
689
|
# Other kinds of colors columns (i.e. pure numbers or nominal strings) shouldn't
|
|
659
690
|
# be converted since they are treated by Vega-Lite as sequential or categorical
|
|
@@ -14,10 +14,8 @@
|
|
|
14
14
|
|
|
15
15
|
from __future__ import annotations
|
|
16
16
|
|
|
17
|
-
from collections.abc import Collection
|
|
18
|
-
from typing import Any,
|
|
19
|
-
|
|
20
|
-
from typing_extensions import TypeAlias
|
|
17
|
+
from collections.abc import Callable, Collection
|
|
18
|
+
from typing import Any, TypeAlias, cast
|
|
21
19
|
|
|
22
20
|
from streamlit.errors import StreamlitInvalidColorError
|
|
23
21
|
|
|
@@ -35,26 +33,18 @@ IntRGBAColorTuple: TypeAlias = tuple[int, int, int, int]
|
|
|
35
33
|
# CSS uses these.
|
|
36
34
|
MixedRGBAColorTuple: TypeAlias = tuple[int, int, int, float]
|
|
37
35
|
|
|
38
|
-
Color4Tuple: TypeAlias =
|
|
39
|
-
FloatRGBAColorTuple,
|
|
40
|
-
IntRGBAColorTuple,
|
|
41
|
-
MixedRGBAColorTuple,
|
|
42
|
-
]
|
|
36
|
+
Color4Tuple: TypeAlias = FloatRGBAColorTuple | IntRGBAColorTuple | MixedRGBAColorTuple
|
|
43
37
|
|
|
44
|
-
Color3Tuple: TypeAlias =
|
|
45
|
-
FloatRGBColorTuple,
|
|
46
|
-
IntRGBColorTuple,
|
|
47
|
-
]
|
|
38
|
+
Color3Tuple: TypeAlias = FloatRGBColorTuple | IntRGBColorTuple
|
|
48
39
|
|
|
49
|
-
ColorTuple: TypeAlias =
|
|
40
|
+
ColorTuple: TypeAlias = Color4Tuple | Color3Tuple
|
|
50
41
|
|
|
51
|
-
IntColorTuple =
|
|
52
|
-
CSSColorStr = Union[IntRGBAColorTuple, MixedRGBAColorTuple]
|
|
42
|
+
IntColorTuple: TypeAlias = IntRGBColorTuple | IntRGBAColorTuple
|
|
53
43
|
|
|
54
44
|
ColorStr: TypeAlias = str
|
|
55
45
|
|
|
56
|
-
Color: TypeAlias =
|
|
57
|
-
MaybeColor: TypeAlias =
|
|
46
|
+
Color: TypeAlias = ColorTuple | ColorStr
|
|
47
|
+
MaybeColor: TypeAlias = str | Collection[Any]
|
|
58
48
|
|
|
59
49
|
|
|
60
50
|
def to_int_color_tuple(color: MaybeColor) -> IntColorTuple:
|
|
@@ -229,7 +219,7 @@ def _normalize_tuple(
|
|
|
229
219
|
r = rgb_formatter(color_4tuple[0], color_4tuple)
|
|
230
220
|
g = rgb_formatter(color_4tuple[1], color_4tuple)
|
|
231
221
|
b = rgb_formatter(color_4tuple[2], color_4tuple)
|
|
232
|
-
alpha = alpha_formatter(color_4tuple[3], color_4tuple)
|
|
222
|
+
alpha = alpha_formatter(color_4tuple[3], color_4tuple) # ty: ignore[index-out-of-bounds]
|
|
233
223
|
return r, g, b, alpha
|
|
234
224
|
|
|
235
225
|
raise StreamlitInvalidColorError(color)
|
|
@@ -18,9 +18,7 @@ import copy
|
|
|
18
18
|
import json
|
|
19
19
|
from collections.abc import Mapping
|
|
20
20
|
from enum import Enum
|
|
21
|
-
from typing import TYPE_CHECKING, Final, Literal,
|
|
22
|
-
|
|
23
|
-
from typing_extensions import TypeAlias
|
|
21
|
+
from typing import TYPE_CHECKING, Any, Final, Literal, TypeAlias
|
|
24
22
|
|
|
25
23
|
from streamlit.dataframe_util import DataFormat
|
|
26
24
|
from streamlit.elements.lib.column_types import ColumnConfig, ColumnType
|
|
@@ -210,7 +208,7 @@ def _determine_data_kind_via_arrow(field: pa.Field) -> ColumnDataKind:
|
|
|
210
208
|
|
|
211
209
|
|
|
212
210
|
def _determine_data_kind_via_pandas_dtype(
|
|
213
|
-
column: Series | Index,
|
|
211
|
+
column: Series[Any] | Index[Any],
|
|
214
212
|
) -> ColumnDataKind:
|
|
215
213
|
"""Determine the data kind by using the pandas dtype.
|
|
216
214
|
|
|
@@ -264,7 +262,7 @@ def _determine_data_kind_via_pandas_dtype(
|
|
|
264
262
|
|
|
265
263
|
|
|
266
264
|
def _determine_data_kind_via_inferred_type(
|
|
267
|
-
column: Series | Index,
|
|
265
|
+
column: Series[Any] | Index[Any],
|
|
268
266
|
) -> ColumnDataKind:
|
|
269
267
|
"""Determine the data kind by inferring it from the underlying data.
|
|
270
268
|
|
|
@@ -333,7 +331,7 @@ def _determine_data_kind_via_inferred_type(
|
|
|
333
331
|
|
|
334
332
|
|
|
335
333
|
def _determine_data_kind(
|
|
336
|
-
column: Series | Index, field: pa.Field | None = None
|
|
334
|
+
column: Series[Any] | Index[Any], field: pa.Field | None = None
|
|
337
335
|
) -> ColumnDataKind:
|
|
338
336
|
"""Determine the data kind of a column.
|
|
339
337
|
|
|
@@ -397,7 +395,8 @@ def determine_dataframe_schema(
|
|
|
397
395
|
|
|
398
396
|
# Add types for all columns:
|
|
399
397
|
for i, column in enumerate(data_df.items()):
|
|
400
|
-
column_name
|
|
398
|
+
column_name = str(column[0])
|
|
399
|
+
column_data = column[1]
|
|
401
400
|
dataframe_schema[column_name] = _determine_data_kind(
|
|
402
401
|
column_data, arrow_schema.field(i)
|
|
403
402
|
)
|
|
@@ -405,16 +404,14 @@ def determine_dataframe_schema(
|
|
|
405
404
|
|
|
406
405
|
|
|
407
406
|
# A mapping of column names/IDs to column configs.
|
|
408
|
-
ColumnConfigMapping: TypeAlias = dict[
|
|
409
|
-
Union[IndexIdentifierType, str, int], ColumnConfig
|
|
410
|
-
]
|
|
407
|
+
ColumnConfigMapping: TypeAlias = dict[IndexIdentifierType | str | int, ColumnConfig]
|
|
411
408
|
ColumnConfigMappingInput: TypeAlias = Mapping[
|
|
412
409
|
# TODO(lukasmasuch): This should also use int here to
|
|
413
410
|
# correctly type the support for positional index. However,
|
|
414
411
|
# allowing int here leads mypy to complain about simple dict[str, ...]
|
|
415
412
|
# as input -> which seems like a mypy bug.
|
|
416
|
-
|
|
417
|
-
|
|
413
|
+
IndexIdentifierType | str,
|
|
414
|
+
ColumnConfig | None | str,
|
|
418
415
|
]
|
|
419
416
|
|
|
420
417
|
|