streamlit 1.45.1__py3-none-any.whl → 1.46.1__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/auth_util.py +12 -12
- streamlit/cli_util.py +4 -3
- streamlit/column_config.py +11 -9
- streamlit/commands/echo.py +6 -4
- streamlit/commands/execution_control.py +33 -32
- streamlit/commands/experimental_query_params.py +2 -2
- streamlit/commands/logo.py +9 -4
- streamlit/commands/navigation.py +61 -18
- streamlit/commands/page_config.py +57 -47
- streamlit/components/types/base_custom_component.py +7 -7
- streamlit/components/v1/component_registry.py +7 -3
- streamlit/components/v1/components.py +1 -1
- streamlit/components/v1/custom_component.py +8 -8
- streamlit/config.py +289 -144
- streamlit/config_option.py +19 -15
- streamlit/config_util.py +29 -23
- streamlit/connections/__init__.py +2 -2
- streamlit/connections/base_connection.py +5 -5
- streamlit/connections/snowflake_connection.py +13 -11
- streamlit/connections/snowpark_connection.py +3 -3
- streamlit/connections/sql_connection.py +20 -18
- streamlit/connections/util.py +2 -2
- streamlit/cursor.py +6 -6
- streamlit/dataframe_util.py +52 -52
- streamlit/delta_generator.py +46 -48
- streamlit/delta_generator_singletons.py +3 -3
- streamlit/deprecation_util.py +6 -6
- streamlit/elements/alert.py +37 -29
- streamlit/elements/arrow.py +40 -22
- streamlit/elements/code.py +46 -13
- streamlit/elements/deck_gl_json_chart.py +38 -27
- streamlit/elements/dialog_decorator.py +3 -4
- streamlit/elements/doc_string.py +64 -58
- streamlit/elements/exception.py +23 -27
- streamlit/elements/form.py +41 -0
- streamlit/elements/graphviz_chart.py +1 -1
- streamlit/elements/heading.py +60 -9
- streamlit/elements/html.py +3 -4
- streamlit/elements/image.py +8 -9
- streamlit/elements/json.py +21 -2
- streamlit/elements/layouts.py +120 -31
- streamlit/elements/lib/built_in_chart_utils.py +96 -73
- streamlit/elements/lib/color_util.py +3 -3
- streamlit/elements/lib/column_config_utils.py +2 -4
- streamlit/elements/lib/column_types.py +14 -8
- streamlit/elements/lib/dialog.py +9 -5
- streamlit/elements/lib/image_utils.py +39 -40
- streamlit/elements/lib/js_number.py +4 -4
- streamlit/elements/lib/layout_utils.py +65 -1
- streamlit/elements/lib/mutable_status_container.py +14 -3
- streamlit/elements/lib/options_selector_utils.py +22 -12
- streamlit/elements/lib/pandas_styler_utils.py +25 -21
- streamlit/elements/lib/policies.py +6 -5
- streamlit/elements/lib/streamlit_plotly_theme.py +54 -53
- streamlit/elements/lib/subtitle_utils.py +6 -9
- streamlit/elements/lib/utils.py +20 -5
- streamlit/elements/map.py +32 -56
- streamlit/elements/markdown.py +101 -12
- streamlit/elements/media.py +78 -21
- streamlit/elements/metric.py +32 -16
- streamlit/elements/plotly_chart.py +15 -15
- streamlit/elements/progress.py +33 -15
- streamlit/elements/spinner.py +31 -6
- streamlit/elements/text.py +21 -1
- streamlit/elements/toast.py +1 -2
- streamlit/elements/vega_charts.py +54 -23
- streamlit/elements/widgets/audio_input.py +24 -7
- streamlit/elements/widgets/button.py +26 -19
- streamlit/elements/widgets/button_group.py +10 -15
- streamlit/elements/widgets/camera_input.py +27 -7
- streamlit/elements/widgets/chat.py +91 -38
- streamlit/elements/widgets/checkbox.py +45 -4
- streamlit/elements/widgets/color_picker.py +40 -17
- streamlit/elements/widgets/data_editor.py +76 -37
- streamlit/elements/widgets/file_uploader.py +42 -13
- streamlit/elements/widgets/multiselect.py +7 -10
- streamlit/elements/widgets/number_input.py +123 -47
- streamlit/elements/widgets/radio.py +59 -13
- streamlit/elements/widgets/select_slider.py +35 -30
- streamlit/elements/widgets/selectbox.py +56 -9
- streamlit/elements/widgets/slider.py +190 -99
- streamlit/elements/widgets/text_widgets.py +54 -8
- streamlit/elements/widgets/time_widgets.py +53 -14
- streamlit/elements/write.py +5 -8
- streamlit/env_util.py +2 -7
- streamlit/error_util.py +16 -9
- streamlit/errors.py +69 -48
- streamlit/external/langchain/streamlit_callback_handler.py +10 -5
- streamlit/file_util.py +27 -10
- streamlit/git_util.py +29 -24
- streamlit/hello/animation_demo.py +9 -9
- streamlit/hello/dataframe_demo.py +5 -5
- streamlit/hello/hello.py +1 -0
- streamlit/hello/mapping_demo.py +7 -8
- streamlit/hello/plotting_demo.py +3 -3
- streamlit/hello/streamlit_app.py +28 -26
- streamlit/hello/utils.py +2 -1
- streamlit/logger.py +10 -11
- streamlit/navigation/page.py +11 -8
- streamlit/proto/Audio_pb2.py +4 -3
- streamlit/proto/Audio_pb2.pyi +8 -1
- streamlit/proto/Block_pb2.py +38 -29
- streamlit/proto/Block_pb2.pyi +72 -4
- streamlit/proto/ClientState_pb2.py +4 -4
- streamlit/proto/ClientState_pb2.pyi +7 -2
- streamlit/proto/Code_pb2.py +4 -2
- streamlit/proto/Code_pb2.pyi +1 -0
- streamlit/proto/DataFrame_pb2.pyi +1 -1
- streamlit/proto/DeckGlJsonChart_pb2.pyi +1 -1
- streamlit/proto/Element_pb2.py +5 -3
- streamlit/proto/Element_pb2.pyi +20 -3
- streamlit/proto/GapSize_pb2.py +29 -0
- streamlit/proto/GapSize_pb2.pyi +70 -0
- streamlit/proto/HeightConfig_pb2.py +27 -0
- streamlit/proto/HeightConfig_pb2.pyi +48 -0
- streamlit/proto/NamedDataSet_pb2.pyi +1 -1
- streamlit/proto/Navigation_pb2.py +3 -3
- streamlit/proto/Navigation_pb2.pyi +4 -0
- streamlit/proto/NewSession_pb2.py +18 -16
- streamlit/proto/NewSession_pb2.pyi +29 -3
- streamlit/proto/PageConfig_pb2.py +7 -7
- streamlit/proto/PageConfig_pb2.pyi +21 -1
- streamlit/proto/Video_pb2.py +8 -7
- streamlit/proto/Video_pb2.pyi +8 -1
- streamlit/proto/WidthConfig_pb2.py +2 -2
- streamlit/proto/WidthConfig_pb2.pyi +15 -1
- streamlit/runtime/__init__.py +1 -1
- streamlit/runtime/app_session.py +53 -40
- streamlit/runtime/caching/__init__.py +9 -9
- streamlit/runtime/caching/cache_data_api.py +36 -30
- streamlit/runtime/caching/cache_errors.py +4 -4
- streamlit/runtime/caching/cache_resource_api.py +8 -8
- streamlit/runtime/caching/cache_utils.py +15 -14
- streamlit/runtime/caching/cached_message_replay.py +14 -8
- streamlit/runtime/caching/hashing.py +91 -97
- streamlit/runtime/caching/legacy_cache_api.py +2 -2
- streamlit/runtime/caching/storage/cache_storage_protocol.py +1 -1
- streamlit/runtime/caching/storage/dummy_cache_storage.py +1 -1
- streamlit/runtime/caching/storage/in_memory_cache_storage_wrapper.py +12 -14
- streamlit/runtime/caching/storage/local_disk_cache_storage.py +6 -6
- streamlit/runtime/connection_factory.py +36 -36
- streamlit/runtime/context.py +58 -9
- streamlit/runtime/credentials.py +29 -40
- streamlit/runtime/forward_msg_queue.py +11 -11
- streamlit/runtime/fragment.py +7 -7
- streamlit/runtime/media_file_manager.py +3 -4
- streamlit/runtime/memory_media_file_storage.py +6 -5
- streamlit/runtime/memory_uploaded_file_manager.py +2 -2
- streamlit/runtime/metrics_util.py +11 -12
- streamlit/runtime/pages_manager.py +4 -6
- streamlit/runtime/runtime.py +8 -6
- streamlit/runtime/runtime_util.py +7 -6
- streamlit/runtime/scriptrunner/__init__.py +4 -4
- streamlit/runtime/scriptrunner/exec_code.py +12 -5
- streamlit/runtime/scriptrunner/magic.py +16 -12
- streamlit/runtime/scriptrunner/script_cache.py +1 -1
- streamlit/runtime/scriptrunner/script_runner.py +53 -29
- streamlit/runtime/scriptrunner_utils/exceptions.py +1 -1
- streamlit/runtime/scriptrunner_utils/script_requests.py +7 -4
- streamlit/runtime/scriptrunner_utils/script_run_context.py +10 -23
- streamlit/runtime/secrets.py +40 -35
- streamlit/runtime/session_manager.py +2 -1
- streamlit/runtime/state/__init__.py +5 -5
- streamlit/runtime/state/common.py +2 -2
- streamlit/runtime/state/query_params.py +13 -15
- streamlit/runtime/state/query_params_proxy.py +17 -13
- streamlit/runtime/state/safe_session_state.py +2 -2
- streamlit/runtime/state/session_state.py +52 -34
- streamlit/runtime/stats.py +2 -2
- streamlit/runtime/uploaded_file_manager.py +1 -1
- streamlit/runtime/websocket_session_manager.py +10 -6
- streamlit/source_util.py +8 -6
- streamlit/static/index.html +3 -17
- streamlit/static/manifest.json +1180 -0
- streamlit/static/static/css/{index.DqDwtg6_.css → index.CJVRHjQZ.css} +1 -1
- streamlit/static/static/js/{ErrorOutline.esm.DU9IrB3M.js → ErrorOutline.esm.DitPpe1Y.js} +1 -1
- streamlit/static/static/js/{FileDownload.esm.P9rKwKo8.js → FileDownload.esm.AI3watX9.js} +1 -1
- streamlit/static/static/js/{FileHelper.D7RMkx0e.js → FileHelper.kt7mhnu8.js} +5 -5
- streamlit/static/static/js/{FormClearHelper.B67tgll0.js → FormClearHelper.D1M9GM_c.js} +1 -1
- streamlit/static/static/js/{Hooks.ncTJktu9.js → Hooks.BGwHKeUc.js} +1 -1
- streamlit/static/static/js/{InputInstructions.D-Y8geDN.js → InputInstructions.DaZ89mzH.js} +1 -1
- streamlit/static/static/js/{ProgressBar.B-kexwwD.js → ProgressBar.C0zPMe-p.js} +2 -2
- streamlit/static/static/js/{RenderInPortalIfExists.BgaoZgep.js → RenderInPortalIfExists.Ox8gQvdz.js} +1 -1
- streamlit/static/static/js/Toolbar.KhlcEc0K.js +1 -0
- streamlit/static/static/js/UploadFileInfo.0DCkpDDf.js +6 -0
- streamlit/static/static/js/{base-input.BoAa1U94.js → base-input.BJ4qsfSq.js} +4 -4
- streamlit/static/static/js/{checkbox.Z6iSfe5F.js → checkbox.DSDh78Xz.js} +2 -2
- streamlit/static/static/js/{createSuper.B4oGDYRm.js → createSuper.wQ9SIXEJ.js} +1 -1
- streamlit/static/static/js/{data-grid-overlay-editor.msYws2Ou.js → data-grid-overlay-editor.DvbdPJ15.js} +1 -1
- streamlit/static/static/js/{downloader.kc14n2Hv.js → downloader.CD9rzih5.js} +1 -1
- streamlit/static/static/js/{es6.CxQz807-.js → es6.48Q9Qjgb.js} +2 -2
- streamlit/static/static/js/{iframeResizer.contentWindow.B19u0ONI.js → iframeResizer.contentWindow.CKdem3Bn.js} +1 -1
- streamlit/static/static/js/{index.LaIasviC.js → index.6md5Qhod.js} +1 -1
- streamlit/static/static/js/index.7hy6AeJ1.js +1 -0
- streamlit/static/static/js/index.B4CGJiBW.js +1 -0
- streamlit/static/static/js/index.B8oW0ZTD.js +1 -0
- streamlit/static/static/js/index.BU6RnlHI.js +73 -0
- streamlit/static/static/js/index.BUq9Wcf8.js +197 -0
- streamlit/static/static/js/{index.BFz9U2y0.js → index.BXXo-Yoj.js} +1 -1
- streamlit/static/static/js/index.Bae9H0OS.js +1 -0
- streamlit/static/static/js/{index.-5ruC9At.js → index.BhTl2Uyb.js} +1 -1
- streamlit/static/static/js/{index.BpILzHf_.js → index.BiSaCB1o.js} +20 -20
- streamlit/static/static/js/{index.xNQq3Ei5.js → index.BulSAJ9z.js} +1 -1
- streamlit/static/static/js/{index.9V1KdxfP.js → index.Bv-EuTKR.js} +1 -1
- streamlit/static/static/js/index.BvMLYCHi.js +1 -0
- streamlit/static/static/js/index.C1NIn1Y2.js +783 -0
- streamlit/static/static/js/index.CP-fthOJ.js +2 -0
- streamlit/static/static/js/{index.BoigZiu7.js → index.CS9guO3p.js} +1 -1
- streamlit/static/static/js/index.CYTBHth8.js +1 -0
- streamlit/static/static/js/{index.CmTAF0dM.js → index.CcJufcuD.js} +1 -1
- streamlit/static/static/js/index.CnENU1yn.js +1 -0
- streamlit/static/static/js/index.Cns13qBb.js +1 -0
- streamlit/static/static/js/index.Ct_xXq7w.js +1 -0
- streamlit/static/static/js/{index.BqfdT8-Q.js → index.CxGSemHL.js} +1 -1
- streamlit/static/static/js/index.D5S0ldVb.js +1 -0
- streamlit/static/static/js/index.D72B_ksb.js +2 -0
- streamlit/static/static/js/index.DI4yZ27M.js +1 -0
- streamlit/static/static/js/index.DN51vLxR.js +1 -0
- streamlit/static/static/js/index.DRtq5dka.js +1 -0
- streamlit/static/static/js/{index.BHXxWdde.js → index.DX-oiXlb.js} +1 -1
- streamlit/static/static/js/index.DlFE4_Aq.js +12 -0
- streamlit/static/static/js/{index.BHGGDa8K.js → index.J7BJwXOi.js} +2 -2
- streamlit/static/static/js/index.Jg38kJPP.js +1 -0
- streamlit/static/static/js/index.JhIO6abf.js +3 -0
- streamlit/static/static/js/{index.DeB9iKFW.js → index.NkRcWwc5.js} +255 -255
- streamlit/static/static/js/{index.BGga-hcS.js → index.prekPLrm.js} +25 -25
- streamlit/static/static/js/{index.BRXmLIsC.js → index.wyzngKUE.js} +1 -1
- streamlit/static/static/js/index.xW7mVdI8.js +1 -0
- streamlit/static/static/js/index.yk07dYGx.js +1 -0
- streamlit/static/static/js/{input.DsCfafm0.js → input.CxKZ5Wrc.js} +2 -2
- streamlit/static/static/js/{memory.nY_lMTtu.js → memory.DeZ9VUvl.js} +1 -1
- streamlit/static/static/js/{mergeWith.B_7zmsM4.js → mergeWith.CVkhrWUb.js} +1 -1
- streamlit/static/static/js/{number-overlay-editor.CSeVhHRU.js → number-overlay-editor.Bpkm3nTq.js} +1 -1
- streamlit/static/static/js/{possibleConstructorReturn.nNhsvgRd.js → possibleConstructorReturn.CIDCId52.js} +1 -1
- streamlit/static/static/js/{sandbox.Cgm3iuL6.js → sandbox.TrkMaokR.js} +1 -1
- streamlit/static/static/js/{textarea.BR8rlyih.js → textarea.QKjxR64N.js} +2 -2
- streamlit/static/static/js/{timepicker.w4XhAenH.js → timepicker.DJYmE1dK.js} +1 -1
- streamlit/static/static/js/{toConsumableArray.CgkEPBwD.js → toConsumableArray.BZoworE-.js} +1 -1
- streamlit/static/static/js/{uniqueId.j-1rlNNH.js → uniqueId.O0UbJ2Bu.js} +1 -1
- streamlit/static/static/js/{useBasicWidgetState.zXY9CjFS.js → useBasicWidgetState.Ci89jaH5.js} +1 -1
- streamlit/static/static/js/useOnInputChange.Cxh6ExEn.js +1 -0
- streamlit/static/static/js/{withFullScreenWrapper.Ov13692o.js → withFullScreenWrapper.iW37lS8Z.js} +1 -1
- streamlit/static/static/media/SourceCodeVF-Italic.ttf.Ba1oaZG1.woff2 +0 -0
- streamlit/static/static/media/SourceCodeVF-Upright.ttf.BjWn63N-.woff2 +0 -0
- streamlit/static/static/media/SourceSansVF-Italic.ttf.Bt9VkdQ3.woff2 +0 -0
- streamlit/static/static/media/SourceSansVF-Upright.ttf.BsWL4Kly.woff2 +0 -0
- streamlit/static/static/media/SourceSerifVariable-Italic.ttf.CVdzAtxO.woff2 +0 -0
- streamlit/static/static/media/SourceSerifVariable-Roman.ttf.mdpVL9bi.woff2 +0 -0
- streamlit/string_util.py +14 -19
- streamlit/temporary_directory.py +13 -4
- streamlit/testing/v1/app_test.py +15 -10
- streamlit/testing/v1/element_tree.py +157 -178
- streamlit/testing/v1/local_script_runner.py +11 -15
- streamlit/testing/v1/util.py +11 -4
- streamlit/type_util.py +8 -12
- streamlit/url_util.py +1 -1
- streamlit/user_info.py +6 -5
- streamlit/util.py +25 -1
- streamlit/vendor/pympler/asizeof.py +3 -2
- streamlit/watcher/event_based_path_watcher.py +21 -2
- streamlit/watcher/folder_black_list.py +2 -2
- streamlit/watcher/local_sources_watcher.py +64 -18
- streamlit/watcher/path_watcher.py +6 -10
- streamlit/watcher/polling_path_watcher.py +8 -7
- streamlit/watcher/util.py +7 -6
- streamlit/web/bootstrap.py +16 -14
- streamlit/web/cli.py +52 -45
- streamlit/web/server/__init__.py +7 -3
- streamlit/web/server/app_static_file_handler.py +1 -1
- streamlit/web/server/authlib_tornado_integration.py +9 -4
- streamlit/web/server/browser_websocket_handler.py +8 -2
- streamlit/web/server/component_request_handler.py +14 -10
- streamlit/web/server/media_file_handler.py +14 -7
- streamlit/web/server/oauth_authlib_routes.py +41 -9
- streamlit/web/server/oidc_mixin.py +35 -17
- streamlit/web/server/routes.py +32 -22
- streamlit/web/server/server.py +13 -24
- streamlit/web/server/server_util.py +43 -9
- streamlit/web/server/stats_request_handler.py +7 -5
- streamlit/web/server/upload_file_request_handler.py +22 -19
- streamlit/web/server/websocket_headers.py +1 -1
- {streamlit-1.45.1.dist-info → streamlit-1.46.1.dist-info}/METADATA +4 -4
- streamlit-1.46.1.dist-info/RECORD +559 -0
- {streamlit-1.45.1.dist-info → streamlit-1.46.1.dist-info}/WHEEL +1 -1
- streamlit/elements/lib/event_utils.py +0 -39
- streamlit/static/static/js/Toolbar.D9RUZv9G.js +0 -1
- streamlit/static/static/js/UploadFileInfo.C-jY39rj.js +0 -1
- streamlit/static/static/js/index.8jhZBWF2.js +0 -3
- streamlit/static/static/js/index.BCx3C6e_.js +0 -1
- streamlit/static/static/js/index.BRuTz_S4.js +0 -1
- streamlit/static/static/js/index.Bcru_ti-.js +0 -1
- streamlit/static/static/js/index.Bl1FMJRd.js +0 -1
- streamlit/static/static/js/index.C1z8KpLA.js +0 -779
- streamlit/static/static/js/index.C32I2PUe.js +0 -2
- streamlit/static/static/js/index.C5GnDRB7.js +0 -1
- streamlit/static/static/js/index.CG4qPaaW.js +0 -2
- streamlit/static/static/js/index.C_msmT1u.js +0 -1
- streamlit/static/static/js/index.CbeNTdd6.js +0 -1
- streamlit/static/static/js/index.CnGQVJcw.js +0 -12
- streamlit/static/static/js/index.CopVVq4l.js +0 -1
- streamlit/static/static/js/index.CtXupx4d.js +0 -197
- streamlit/static/static/js/index.DGmCchO7.js +0 -1
- streamlit/static/static/js/index.DH6zBk0e.js +0 -1
- streamlit/static/static/js/index.DHVlVWsm.js +0 -1
- streamlit/static/static/js/index.DRKIVBoi.js +0 -1
- streamlit/static/static/js/index.DUd-lFXx.js +0 -73
- streamlit/static/static/js/index.D_uRBA4B.js +0 -1
- streamlit/static/static/js/index.QHNfgPJd.js +0 -1
- streamlit/static/static/js/index.a-RJocYL.js +0 -1
- streamlit/static/static/js/index.cvz4B1gy.js +0 -1
- streamlit/static/static/js/index.t--hEgTQ.js +0 -6
- streamlit/static/static/js/useOnInputChange.z04u96A8.js +0 -1
- streamlit/static/static/media/SourceCodePro-Bold.CFEfr7-q.woff2 +0 -0
- streamlit/static/static/media/SourceCodePro-BoldItalic.C-LkFXxa.woff2 +0 -0
- streamlit/static/static/media/SourceCodePro-Italic.CxFOx7N-.woff2 +0 -0
- streamlit/static/static/media/SourceCodePro-Regular.CBOlD63d.woff2 +0 -0
- streamlit/static/static/media/SourceCodePro-SemiBold.CFHwW3Wd.woff2 +0 -0
- streamlit/static/static/media/SourceCodePro-SemiBoldItalic.Cg2yRu82.woff2 +0 -0
- streamlit/static/static/media/SourceSansPro-Bold.-6c9oR8J.woff2 +0 -0
- streamlit/static/static/media/SourceSansPro-BoldItalic.DmM_grLY.woff2 +0 -0
- streamlit/static/static/media/SourceSansPro-Italic.I1ipWe7Q.woff2 +0 -0
- streamlit/static/static/media/SourceSansPro-Regular.DZLUzqI4.woff2 +0 -0
- streamlit/static/static/media/SourceSansPro-SemiBold.sKQIyTMz.woff2 +0 -0
- streamlit/static/static/media/SourceSansPro-SemiBoldItalic.C0wP0icr.woff2 +0 -0
- streamlit/static/static/media/SourceSerifPro-Bold.8TUnKj4x.woff2 +0 -0
- streamlit/static/static/media/SourceSerifPro-BoldItalic.CBVO7Ve7.woff2 +0 -0
- streamlit/static/static/media/SourceSerifPro-Italic.DkFgL2HZ.woff2 +0 -0
- streamlit/static/static/media/SourceSerifPro-Regular.CNJNET2S.woff2 +0 -0
- streamlit/static/static/media/SourceSerifPro-SemiBold.CHyh9GC5.woff2 +0 -0
- streamlit/static/static/media/SourceSerifPro-SemiBoldItalic.CBtz8sWN.woff2 +0 -0
- streamlit-1.45.1.dist-info/RECORD +0 -568
- {streamlit-1.45.1.data → streamlit-1.46.1.data}/scripts/streamlit.cmd +0 -0
- {streamlit-1.45.1.dist-info → streamlit-1.46.1.dist-info}/entry_points.txt +0 -0
- {streamlit-1.45.1.dist-info → streamlit-1.46.1.dist-info}/top_level.txt +0 -0
streamlit/elements/media.py
CHANGED
|
@@ -24,11 +24,13 @@ from typing_extensions import TypeAlias
|
|
|
24
24
|
|
|
25
25
|
from streamlit import runtime, type_util, url_util
|
|
26
26
|
from streamlit.elements.lib.form_utils import current_form_id
|
|
27
|
+
from streamlit.elements.lib.layout_utils import WidthWithoutContent, validate_width
|
|
27
28
|
from streamlit.elements.lib.subtitle_utils import process_subtitle_data
|
|
28
29
|
from streamlit.elements.lib.utils import compute_and_register_element_id
|
|
29
30
|
from streamlit.errors import StreamlitAPIException
|
|
30
31
|
from streamlit.proto.Audio_pb2 import Audio as AudioProto
|
|
31
32
|
from streamlit.proto.Video_pb2 import Video as VideoProto
|
|
33
|
+
from streamlit.proto.WidthConfig_pb2 import WidthConfig
|
|
32
34
|
from streamlit.runtime import caching
|
|
33
35
|
from streamlit.runtime.metrics_util import gather_metrics
|
|
34
36
|
from streamlit.time_util import time_to_seconds
|
|
@@ -80,6 +82,7 @@ class MediaMixin:
|
|
|
80
82
|
end_time: MediaTime | None = None,
|
|
81
83
|
loop: bool = False,
|
|
82
84
|
autoplay: bool = False,
|
|
85
|
+
width: WidthWithoutContent = "stretch",
|
|
83
86
|
) -> DeltaGenerator:
|
|
84
87
|
"""Display an audio player.
|
|
85
88
|
|
|
@@ -106,7 +109,7 @@ class MediaMixin:
|
|
|
106
109
|
For more information about MIME types, see
|
|
107
110
|
https://www.iana.org/assignments/media-types/media-types.xhtml.
|
|
108
111
|
|
|
109
|
-
start_time: int, float, timedelta, str, or None
|
|
112
|
+
start_time : int, float, timedelta, str, or None
|
|
110
113
|
The time from which the element should start playing. This can be
|
|
111
114
|
one of the following:
|
|
112
115
|
|
|
@@ -119,10 +122,10 @@ class MediaMixin:
|
|
|
119
122
|
- A ``timedelta`` object from `Python's built-in datetime library
|
|
120
123
|
<https://docs.python.org/3/library/datetime.html#timedelta-objects>`_,
|
|
121
124
|
e.g. ``timedelta(seconds=70)``.
|
|
122
|
-
sample_rate: int or None
|
|
125
|
+
sample_rate : int or None
|
|
123
126
|
The sample rate of the audio data in samples per second. This is
|
|
124
127
|
only required if ``data`` is a NumPy array.
|
|
125
|
-
end_time: int, float, timedelta, str, or None
|
|
128
|
+
end_time : int, float, timedelta, str, or None
|
|
126
129
|
The time at which the element should stop playing. This can be
|
|
127
130
|
one of the following:
|
|
128
131
|
|
|
@@ -135,12 +138,22 @@ class MediaMixin:
|
|
|
135
138
|
- A ``timedelta`` object from `Python's built-in datetime library
|
|
136
139
|
<https://docs.python.org/3/library/datetime.html#timedelta-objects>`_,
|
|
137
140
|
e.g. ``timedelta(seconds=70)``.
|
|
138
|
-
loop: bool
|
|
141
|
+
loop : bool
|
|
139
142
|
Whether the audio should loop playback.
|
|
140
|
-
autoplay: bool
|
|
143
|
+
autoplay : bool
|
|
141
144
|
Whether the audio file should start playing automatically. This is
|
|
142
145
|
``False`` by default. Browsers will not autoplay audio files if the
|
|
143
146
|
user has not interacted with the page by clicking somewhere.
|
|
147
|
+
width : "stretch" or int
|
|
148
|
+
The width of the audio player element. This can be one of the
|
|
149
|
+
following:
|
|
150
|
+
|
|
151
|
+
- ``"stretch"`` (default): The width of the element matches the
|
|
152
|
+
width of the parent container.
|
|
153
|
+
- An integer specifying the width in pixels: The element has a
|
|
154
|
+
fixed width. If the specified width is greater than the width of
|
|
155
|
+
the parent container, the width of the element matches the width
|
|
156
|
+
of the parent container.
|
|
144
157
|
|
|
145
158
|
Examples
|
|
146
159
|
--------
|
|
@@ -181,6 +194,7 @@ class MediaMixin:
|
|
|
181
194
|
|
|
182
195
|
"""
|
|
183
196
|
start_time, end_time = _parse_start_time_end_time(start_time, end_time)
|
|
197
|
+
validate_width(width)
|
|
184
198
|
|
|
185
199
|
audio_proto = AudioProto()
|
|
186
200
|
|
|
@@ -207,6 +221,7 @@ class MediaMixin:
|
|
|
207
221
|
loop,
|
|
208
222
|
autoplay,
|
|
209
223
|
form_id=current_form_id(self.dg),
|
|
224
|
+
width=width,
|
|
210
225
|
)
|
|
211
226
|
return self.dg._enqueue("audio", audio_proto)
|
|
212
227
|
|
|
@@ -222,6 +237,7 @@ class MediaMixin:
|
|
|
222
237
|
loop: bool = False,
|
|
223
238
|
autoplay: bool = False,
|
|
224
239
|
muted: bool = False,
|
|
240
|
+
width: WidthWithoutContent = "stretch",
|
|
225
241
|
) -> DeltaGenerator:
|
|
226
242
|
"""Display a video player.
|
|
227
243
|
|
|
@@ -242,7 +258,7 @@ class MediaMixin:
|
|
|
242
258
|
For more information about MIME types, see
|
|
243
259
|
https://www.iana.org/assignments/media-types/media-types.xhtml.
|
|
244
260
|
|
|
245
|
-
start_time: int, float, timedelta, str, or None
|
|
261
|
+
start_time : int, float, timedelta, str, or None
|
|
246
262
|
The time from which the element should start playing. This can be
|
|
247
263
|
one of the following:
|
|
248
264
|
|
|
@@ -255,7 +271,7 @@ class MediaMixin:
|
|
|
255
271
|
- A ``timedelta`` object from `Python's built-in datetime library
|
|
256
272
|
<https://docs.python.org/3/library/datetime.html#timedelta-objects>`_,
|
|
257
273
|
e.g. ``timedelta(seconds=70)``.
|
|
258
|
-
subtitles: str, bytes, Path, io.BytesIO, or dict
|
|
274
|
+
subtitles : str, bytes, Path, io.BytesIO, or dict
|
|
259
275
|
Optional subtitle data for the video, supporting several input types:
|
|
260
276
|
|
|
261
277
|
- ``None`` (default): No subtitles.
|
|
@@ -281,7 +297,7 @@ class MediaMixin:
|
|
|
281
297
|
in a dictrionary's first pair: ``{"None": "", "English": "path/to/english.vtt"}``
|
|
282
298
|
|
|
283
299
|
Not supported for YouTube videos.
|
|
284
|
-
end_time: int, float, timedelta, str, or None
|
|
300
|
+
end_time : int, float, timedelta, str, or None
|
|
285
301
|
The time at which the element should stop playing. This can be
|
|
286
302
|
one of the following:
|
|
287
303
|
|
|
@@ -294,18 +310,28 @@ class MediaMixin:
|
|
|
294
310
|
- A ``timedelta`` object from `Python's built-in datetime library
|
|
295
311
|
<https://docs.python.org/3/library/datetime.html#timedelta-objects>`_,
|
|
296
312
|
e.g. ``timedelta(seconds=70)``.
|
|
297
|
-
loop: bool
|
|
313
|
+
loop : bool
|
|
298
314
|
Whether the video should loop playback.
|
|
299
|
-
autoplay: bool
|
|
315
|
+
autoplay : bool
|
|
300
316
|
Whether the video should start playing automatically. This is
|
|
301
317
|
``False`` by default. Browsers will not autoplay unmuted videos
|
|
302
318
|
if the user has not interacted with the page by clicking somewhere.
|
|
303
319
|
To enable autoplay without user interaction, you must also set
|
|
304
320
|
``muted=True``.
|
|
305
|
-
muted: bool
|
|
321
|
+
muted : bool
|
|
306
322
|
Whether the video should play with the audio silenced. This is
|
|
307
323
|
``False`` by default. Use this in conjunction with ``autoplay=True``
|
|
308
324
|
to enable autoplay without user interaction.
|
|
325
|
+
width : "stretch" or int
|
|
326
|
+
The width of the video player element. This can be one of the
|
|
327
|
+
following:
|
|
328
|
+
|
|
329
|
+
- ``"stretch"`` (default): The width of the element matches the
|
|
330
|
+
width of the parent container.
|
|
331
|
+
- An integer specifying the width in pixels: The element has a
|
|
332
|
+
fixed width. If the specified width is greater than the width of
|
|
333
|
+
the parent container, the width of the element matches the width
|
|
334
|
+
of the parent container.
|
|
309
335
|
|
|
310
336
|
Example
|
|
311
337
|
-------
|
|
@@ -350,14 +376,16 @@ class MediaMixin:
|
|
|
350
376
|
`video subtitles feature demo <https://doc-video-subtitle-inputs.streamlit.app/>`_.
|
|
351
377
|
|
|
352
378
|
.. note::
|
|
353
|
-
Some videos may not display if they are encoded using MP4V (which is an export option in OpenCV),
|
|
354
|
-
not widely supported by browsers. Converting your video to H.264 will allow
|
|
379
|
+
Some videos may not display if they are encoded using MP4V (which is an export option in OpenCV),
|
|
380
|
+
as this codec is not widely supported by browsers. Converting your video to H.264 will allow
|
|
381
|
+
the video to be displayed in Streamlit.
|
|
355
382
|
See this `StackOverflow post <https://stackoverflow.com/a/49535220/2394542>`_ or this
|
|
356
383
|
`Streamlit forum post <https://discuss.streamlit.io/t/st-video-doesnt-show-opencv-generated-mp4/3193/2>`_
|
|
357
384
|
for more information.
|
|
358
385
|
|
|
359
386
|
"""
|
|
360
387
|
start_time, end_time = _parse_start_time_end_time(start_time, end_time)
|
|
388
|
+
validate_width(width)
|
|
361
389
|
|
|
362
390
|
video_proto = VideoProto()
|
|
363
391
|
coordinates = self.dg._get_delta_path_str()
|
|
@@ -373,6 +401,7 @@ class MediaMixin:
|
|
|
373
401
|
autoplay,
|
|
374
402
|
muted,
|
|
375
403
|
form_id=current_form_id(self.dg),
|
|
404
|
+
width=width,
|
|
376
405
|
)
|
|
377
406
|
return self.dg._enqueue("video", video_proto)
|
|
378
407
|
|
|
@@ -448,17 +477,16 @@ def _marshall_av_media(
|
|
|
448
477
|
elif isinstance(data, io.BytesIO):
|
|
449
478
|
data.seek(0)
|
|
450
479
|
data_or_filename = data.getvalue()
|
|
451
|
-
elif isinstance(data, io.RawIOBase
|
|
480
|
+
elif isinstance(data, (io.RawIOBase, io.BufferedReader)):
|
|
452
481
|
data.seek(0)
|
|
453
482
|
read_data = data.read()
|
|
454
483
|
if read_data is None:
|
|
455
484
|
return
|
|
456
|
-
|
|
457
|
-
data_or_filename = read_data
|
|
485
|
+
data_or_filename = read_data
|
|
458
486
|
elif type_util.is_type(data, "numpy.ndarray"):
|
|
459
|
-
data_or_filename = data.tobytes()
|
|
487
|
+
data_or_filename = cast("npt.NDArray[Any]", data).tobytes()
|
|
460
488
|
else:
|
|
461
|
-
raise RuntimeError("Invalid binary data format:
|
|
489
|
+
raise RuntimeError(f"Invalid binary data format: {type(data)}")
|
|
462
490
|
|
|
463
491
|
if runtime.exists():
|
|
464
492
|
file_url = runtime.get_instance().media_file_mgr.add(
|
|
@@ -484,6 +512,7 @@ def marshall_video(
|
|
|
484
512
|
autoplay: bool = False,
|
|
485
513
|
muted: bool = False,
|
|
486
514
|
form_id: str | None = None,
|
|
515
|
+
width: WidthWithoutContent = "stretch",
|
|
487
516
|
) -> None:
|
|
488
517
|
"""Marshalls a video proto, using url processors as needed.
|
|
489
518
|
|
|
@@ -505,8 +534,9 @@ def marshall_video(
|
|
|
505
534
|
subtitles: str, dict, or io.BytesIO
|
|
506
535
|
Optional subtitle data for the video, supporting several input types:
|
|
507
536
|
- None (default): No subtitles.
|
|
508
|
-
- A string: File path to a subtitle file in '.vtt' or '.srt' formats, or the raw content
|
|
509
|
-
If providing raw content, the string must
|
|
537
|
+
- A string: File path to a subtitle file in '.vtt' or '.srt' formats, or the raw content
|
|
538
|
+
of subtitles conforming to these formats. If providing raw content, the string must
|
|
539
|
+
adhere to the WebVTT or SRT format specifications.
|
|
510
540
|
- A dictionary: Pairs of labels and file paths or raw subtitle content in '.vtt' or '.srt' formats.
|
|
511
541
|
Enables multiple subtitle tracks. The label will be shown in the video player.
|
|
512
542
|
Example: {'English': 'path/to/english.vtt', 'French': 'path/to/french.srt'}
|
|
@@ -529,6 +559,11 @@ def marshall_video(
|
|
|
529
559
|
form_id: str | None
|
|
530
560
|
The ID of the form that this element is placed in. Provide None if
|
|
531
561
|
the element is not placed in a form.
|
|
562
|
+
width: int or "stretch"
|
|
563
|
+
The width of the video player. This can be one of the following:
|
|
564
|
+
- An int: The width in pixels, e.g. 200 for a width of 200 pixels.
|
|
565
|
+
- "stretch": The default value. The video player stretches to fill
|
|
566
|
+
available space in its container.
|
|
532
567
|
"""
|
|
533
568
|
|
|
534
569
|
if start_time < 0 or (end_time is not None and end_time <= start_time):
|
|
@@ -541,6 +576,13 @@ def marshall_video(
|
|
|
541
576
|
proto.end_time = end_time
|
|
542
577
|
proto.loop = loop
|
|
543
578
|
|
|
579
|
+
width_config = WidthConfig()
|
|
580
|
+
if isinstance(width, int):
|
|
581
|
+
width_config.pixel_width = width
|
|
582
|
+
else:
|
|
583
|
+
width_config.use_stretch = True
|
|
584
|
+
proto.width_config.CopyFrom(width_config)
|
|
585
|
+
|
|
544
586
|
# "type" distinguishes between YouTube and non-YouTube links
|
|
545
587
|
proto.type = VideoProto.Type.NATIVE
|
|
546
588
|
|
|
@@ -610,6 +652,7 @@ def marshall_video(
|
|
|
610
652
|
loop=loop,
|
|
611
653
|
autoplay=autoplay,
|
|
612
654
|
muted=muted,
|
|
655
|
+
width=width,
|
|
613
656
|
)
|
|
614
657
|
|
|
615
658
|
|
|
@@ -621,7 +664,7 @@ def _parse_start_time_end_time(
|
|
|
621
664
|
try:
|
|
622
665
|
maybe_start_time = time_to_seconds(start_time, coerce_none_to_inf=False)
|
|
623
666
|
if maybe_start_time is None:
|
|
624
|
-
raise ValueError
|
|
667
|
+
raise ValueError # noqa: TRY301
|
|
625
668
|
start_time = int(maybe_start_time)
|
|
626
669
|
except (StreamlitAPIException, ValueError):
|
|
627
670
|
error_msg = TIMEDELTA_PARSE_ERROR_MESSAGE.format(
|
|
@@ -731,6 +774,7 @@ def marshall_audio(
|
|
|
731
774
|
loop: bool = False,
|
|
732
775
|
autoplay: bool = False,
|
|
733
776
|
form_id: str | None = None,
|
|
777
|
+
width: WidthWithoutContent = "stretch",
|
|
734
778
|
) -> None:
|
|
735
779
|
"""Marshalls an audio proto, using data and url processors as needed.
|
|
736
780
|
|
|
@@ -760,6 +804,11 @@ def marshall_audio(
|
|
|
760
804
|
form_id: str | None
|
|
761
805
|
The ID of the form that this element is placed in. Provide None if
|
|
762
806
|
the element is not placed in a form.
|
|
807
|
+
width: int or "stretch"
|
|
808
|
+
The width of the audio player. This can be one of the following:
|
|
809
|
+
- An int: The width in pixels, e.g. 200 for a width of 200 pixels.
|
|
810
|
+
- "stretch": The default value. The audio player stretches to fill
|
|
811
|
+
available space in its container.
|
|
763
812
|
"""
|
|
764
813
|
|
|
765
814
|
proto.start_time = start_time
|
|
@@ -767,6 +816,13 @@ def marshall_audio(
|
|
|
767
816
|
proto.end_time = end_time
|
|
768
817
|
proto.loop = loop
|
|
769
818
|
|
|
819
|
+
width_config = WidthConfig()
|
|
820
|
+
if isinstance(width, int):
|
|
821
|
+
width_config.pixel_width = width
|
|
822
|
+
else:
|
|
823
|
+
width_config.use_stretch = True
|
|
824
|
+
proto.width_config.CopyFrom(width_config)
|
|
825
|
+
|
|
770
826
|
if isinstance(data, Path):
|
|
771
827
|
data = str(data) # Convert Path to string
|
|
772
828
|
|
|
@@ -791,4 +847,5 @@ def marshall_audio(
|
|
|
791
847
|
end_time=end_time,
|
|
792
848
|
loop=loop,
|
|
793
849
|
autoplay=autoplay,
|
|
850
|
+
width=width,
|
|
794
851
|
)
|
streamlit/elements/metric.py
CHANGED
|
@@ -20,6 +20,7 @@ from typing import TYPE_CHECKING, Any, Literal, Union, cast
|
|
|
20
20
|
|
|
21
21
|
from typing_extensions import TypeAlias
|
|
22
22
|
|
|
23
|
+
from streamlit.elements.lib.layout_utils import LayoutConfig, Width, validate_width
|
|
23
24
|
from streamlit.elements.lib.policies import maybe_raise_label_warnings
|
|
24
25
|
from streamlit.elements.lib.utils import (
|
|
25
26
|
LabelVisibility,
|
|
@@ -58,6 +59,7 @@ class MetricMixin:
|
|
|
58
59
|
help: str | None = None,
|
|
59
60
|
label_visibility: LabelVisibility = "visible",
|
|
60
61
|
border: bool = False,
|
|
62
|
+
width: Width = "stretch",
|
|
61
63
|
) -> DeltaGenerator:
|
|
62
64
|
r"""Display a metric in big bold font, with an optional indicator of how the metric changed.
|
|
63
65
|
|
|
@@ -114,7 +116,7 @@ class MetricMixin:
|
|
|
114
116
|
label_visibility : "visible", "hidden", or "collapsed"
|
|
115
117
|
The visibility of the label. The default is ``"visible"``. If this
|
|
116
118
|
is ``"hidden"``, Streamlit displays an empty spacer instead of the
|
|
117
|
-
label, which can help keep the widget
|
|
119
|
+
label, which can help keep the widget aligned with other widgets.
|
|
118
120
|
If this is ``"collapsed"``, Streamlit displays no label or spacer.
|
|
119
121
|
|
|
120
122
|
border : bool
|
|
@@ -122,6 +124,18 @@ class MetricMixin:
|
|
|
122
124
|
``False`` (default), no border is shown. If this is ``True``, a
|
|
123
125
|
border is shown.
|
|
124
126
|
|
|
127
|
+
width : "stretch", "content", or int
|
|
128
|
+
The width of the metric element. This can be one of the following:
|
|
129
|
+
|
|
130
|
+
- ``"stretch"`` (default): The width of the element matches the
|
|
131
|
+
width of the parent container.
|
|
132
|
+
- ``"content"``: The width of the element matches the width of its
|
|
133
|
+
content, but doesn't exceed the width of the parent container.
|
|
134
|
+
- An integer specifying the width in pixels: The element has a
|
|
135
|
+
fixed width. If the specified width is greater than the width of
|
|
136
|
+
the parent container, the width of the element matches the width
|
|
137
|
+
of the parent container.
|
|
138
|
+
|
|
125
139
|
Examples
|
|
126
140
|
--------
|
|
127
141
|
**Example 1: Show a metric**
|
|
@@ -204,7 +218,10 @@ class MetricMixin:
|
|
|
204
218
|
label_visibility
|
|
205
219
|
)
|
|
206
220
|
|
|
207
|
-
|
|
221
|
+
validate_width(width, allow_content=True)
|
|
222
|
+
layout_config = LayoutConfig(width=width)
|
|
223
|
+
|
|
224
|
+
return self.dg._enqueue("metric", metric_proto, layout_config=layout_config)
|
|
208
225
|
|
|
209
226
|
@property
|
|
210
227
|
def dg(self) -> DeltaGenerator:
|
|
@@ -214,7 +231,7 @@ class MetricMixin:
|
|
|
214
231
|
def _parse_label(label: str) -> str:
|
|
215
232
|
if not isinstance(label, str):
|
|
216
233
|
raise TypeError(
|
|
217
|
-
f"'{
|
|
234
|
+
f"'{label}' is of type {type(label)}, which is not an accepted type."
|
|
218
235
|
" label only accepts: str. Please convert the label to an accepted type."
|
|
219
236
|
)
|
|
220
237
|
return label
|
|
@@ -223,20 +240,20 @@ def _parse_label(label: str) -> str:
|
|
|
223
240
|
def _parse_value(value: Value) -> str:
|
|
224
241
|
if value is None:
|
|
225
242
|
return "—"
|
|
226
|
-
if isinstance(value, int
|
|
243
|
+
if isinstance(value, (int, float, str)):
|
|
227
244
|
return str(value)
|
|
228
|
-
|
|
245
|
+
if hasattr(value, "item"):
|
|
229
246
|
# Add support for numpy values (e.g. int16, float64, etc.)
|
|
230
247
|
try:
|
|
231
248
|
# Item could also be just a variable, so we use try, except
|
|
232
|
-
if isinstance(value.item(), float
|
|
249
|
+
if isinstance(value.item(), (float, int)):
|
|
233
250
|
return str(value.item())
|
|
234
|
-
except Exception:
|
|
251
|
+
except Exception: # noqa: S110
|
|
235
252
|
# If the numpy item is not a valid value, the TypeError below will be raised.
|
|
236
253
|
pass
|
|
237
254
|
|
|
238
255
|
raise TypeError(
|
|
239
|
-
f"'{
|
|
256
|
+
f"'{value}' is of type {type(value)}, which is not an accepted type."
|
|
240
257
|
" value only accepts: int, float, str, or None."
|
|
241
258
|
" Please convert the value to an accepted type."
|
|
242
259
|
)
|
|
@@ -247,14 +264,13 @@ def _parse_delta(delta: Delta) -> str:
|
|
|
247
264
|
return ""
|
|
248
265
|
if isinstance(delta, str):
|
|
249
266
|
return dedent(delta)
|
|
250
|
-
|
|
267
|
+
if isinstance(delta, (int, float)):
|
|
251
268
|
return str(delta)
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
)
|
|
269
|
+
raise TypeError(
|
|
270
|
+
f"'{delta}' is of type {type(delta)}, which is not an accepted type."
|
|
271
|
+
" delta only accepts: int, float, str, or None."
|
|
272
|
+
" Please convert the value to an accepted type."
|
|
273
|
+
)
|
|
258
274
|
|
|
259
275
|
|
|
260
276
|
def _determine_delta_color_and_direction(
|
|
@@ -263,7 +279,7 @@ def _determine_delta_color_and_direction(
|
|
|
263
279
|
) -> MetricColorAndDirection:
|
|
264
280
|
if delta_color not in {"normal", "inverse", "off"}:
|
|
265
281
|
raise StreamlitAPIException(
|
|
266
|
-
f"'{
|
|
282
|
+
f"'{delta_color}' is not an accepted value. delta_color only accepts: "
|
|
267
283
|
"'normal', 'inverse', or 'off'"
|
|
268
284
|
)
|
|
269
285
|
|
|
@@ -29,11 +29,10 @@ from typing import (
|
|
|
29
29
|
overload,
|
|
30
30
|
)
|
|
31
31
|
|
|
32
|
-
from typing_extensions import TypeAlias
|
|
32
|
+
from typing_extensions import Required, TypeAlias
|
|
33
33
|
|
|
34
34
|
from streamlit import type_util
|
|
35
35
|
from streamlit.deprecation_util import show_deprecation_warning
|
|
36
|
-
from streamlit.elements.lib.event_utils import AttributeDictionary
|
|
37
36
|
from streamlit.elements.lib.form_utils import current_form_id
|
|
38
37
|
from streamlit.elements.lib.policies import check_widget_policies
|
|
39
38
|
from streamlit.elements.lib.streamlit_plotly_theme import (
|
|
@@ -45,6 +44,7 @@ from streamlit.proto.PlotlyChart_pb2 import PlotlyChart as PlotlyChartProto
|
|
|
45
44
|
from streamlit.runtime.metrics_util import gather_metrics
|
|
46
45
|
from streamlit.runtime.scriptrunner_utils.script_run_context import get_script_run_ctx
|
|
47
46
|
from streamlit.runtime.state import WidgetCallback, register_widget
|
|
47
|
+
from streamlit.util import AttributeDictionary
|
|
48
48
|
|
|
49
49
|
if TYPE_CHECKING:
|
|
50
50
|
from collections.abc import Iterable
|
|
@@ -159,10 +159,10 @@ class PlotlySelectionState(TypedDict, total=False):
|
|
|
159
159
|
|
|
160
160
|
"""
|
|
161
161
|
|
|
162
|
-
points: list[dict[str, Any]]
|
|
163
|
-
point_indices: list[int]
|
|
164
|
-
box: list[dict[str, Any]]
|
|
165
|
-
lasso: list[dict[str, Any]]
|
|
162
|
+
points: Required[list[dict[str, Any]]]
|
|
163
|
+
point_indices: Required[list[int]]
|
|
164
|
+
box: Required[list[dict[str, Any]]]
|
|
165
|
+
lasso: Required[list[dict[str, Any]]]
|
|
166
166
|
|
|
167
167
|
|
|
168
168
|
class PlotlyState(TypedDict, total=False):
|
|
@@ -205,7 +205,7 @@ class PlotlyState(TypedDict, total=False):
|
|
|
205
205
|
|
|
206
206
|
"""
|
|
207
207
|
|
|
208
|
-
selection: PlotlySelectionState
|
|
208
|
+
selection: Required[PlotlySelectionState]
|
|
209
209
|
|
|
210
210
|
|
|
211
211
|
@dataclass
|
|
@@ -214,7 +214,7 @@ class PlotlyChartSelectionSerde:
|
|
|
214
214
|
selection state.
|
|
215
215
|
"""
|
|
216
216
|
|
|
217
|
-
def deserialize(self, ui_value: str | None
|
|
217
|
+
def deserialize(self, ui_value: str | None) -> PlotlyState:
|
|
218
218
|
empty_selection_state: PlotlyState = {
|
|
219
219
|
"selection": {
|
|
220
220
|
"points": [],
|
|
@@ -231,7 +231,7 @@ class PlotlyChartSelectionSerde:
|
|
|
231
231
|
)
|
|
232
232
|
|
|
233
233
|
if "selection" not in selection_state:
|
|
234
|
-
selection_state = empty_selection_state
|
|
234
|
+
selection_state = empty_selection_state # type: ignore[unreachable]
|
|
235
235
|
|
|
236
236
|
return cast("PlotlyState", AttributeDictionary(selection_state))
|
|
237
237
|
|
|
@@ -257,12 +257,12 @@ def parse_selection_mode(
|
|
|
257
257
|
)
|
|
258
258
|
|
|
259
259
|
parsed_selection_modes = []
|
|
260
|
-
for
|
|
261
|
-
if
|
|
260
|
+
for mode in selection_mode_set:
|
|
261
|
+
if mode == "points":
|
|
262
262
|
parsed_selection_modes.append(PlotlyChartProto.SelectionMode.POINTS)
|
|
263
|
-
elif
|
|
263
|
+
elif mode == "lasso":
|
|
264
264
|
parsed_selection_modes.append(PlotlyChartProto.SelectionMode.LASSO)
|
|
265
|
-
elif
|
|
265
|
+
elif mode == "box":
|
|
266
266
|
parsed_selection_modes.append(PlotlyChartProto.SelectionMode.BOX)
|
|
267
267
|
return set(parsed_selection_modes)
|
|
268
268
|
|
|
@@ -510,6 +510,7 @@ class PlotlyMixin:
|
|
|
510
510
|
"plotly_chart",
|
|
511
511
|
user_key=key,
|
|
512
512
|
form_id=plotly_chart_proto.form_id,
|
|
513
|
+
dg=self.dg,
|
|
513
514
|
plotly_spec=plotly_chart_proto.spec,
|
|
514
515
|
plotly_config=plotly_chart_proto.config,
|
|
515
516
|
selection_mode=selection_mode,
|
|
@@ -537,8 +538,7 @@ class PlotlyMixin:
|
|
|
537
538
|
|
|
538
539
|
self.dg._enqueue("plotly_chart", plotly_chart_proto)
|
|
539
540
|
return cast("PlotlyState", widget_state.value)
|
|
540
|
-
|
|
541
|
-
return self.dg._enqueue("plotly_chart", plotly_chart_proto)
|
|
541
|
+
return self.dg._enqueue("plotly_chart", plotly_chart_proto)
|
|
542
542
|
|
|
543
543
|
@property
|
|
544
544
|
def dg(self) -> DeltaGenerator:
|
streamlit/elements/progress.py
CHANGED
|
@@ -19,12 +19,14 @@ from typing import TYPE_CHECKING, Union, cast
|
|
|
19
19
|
|
|
20
20
|
from typing_extensions import TypeAlias
|
|
21
21
|
|
|
22
|
+
from streamlit.elements.lib.layout_utils import LayoutConfig, validate_width
|
|
22
23
|
from streamlit.errors import StreamlitAPIException
|
|
23
24
|
from streamlit.proto.Progress_pb2 import Progress as ProgressProto
|
|
24
25
|
from streamlit.string_util import clean_text
|
|
25
26
|
|
|
26
27
|
if TYPE_CHECKING:
|
|
27
28
|
from streamlit.delta_generator import DeltaGenerator
|
|
29
|
+
from streamlit.elements.lib.layout_utils import WidthWithoutContent
|
|
28
30
|
|
|
29
31
|
|
|
30
32
|
# Currently, equates to just float, but we can't use `numbers.Real` due to
|
|
@@ -58,26 +60,23 @@ def _check_float_between(value: float, low: float = 0.0, high: float = 1.0) -> b
|
|
|
58
60
|
)
|
|
59
61
|
|
|
60
62
|
|
|
61
|
-
def _get_value(value):
|
|
63
|
+
def _get_value(value: FloatOrInt) -> int:
|
|
62
64
|
if isinstance(value, int):
|
|
63
65
|
if 0 <= value <= 100:
|
|
64
66
|
return value
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
)
|
|
67
|
+
raise StreamlitAPIException(
|
|
68
|
+
f"Progress Value has invalid value [0, 100]: {value}"
|
|
69
|
+
)
|
|
69
70
|
|
|
70
|
-
|
|
71
|
+
if isinstance(value, float):
|
|
71
72
|
if _check_float_between(value, low=0.0, high=1.0):
|
|
72
73
|
return int(value * 100)
|
|
73
|
-
else:
|
|
74
|
-
raise StreamlitAPIException(
|
|
75
|
-
"Progress Value has invalid value [0.0, 1.0]: %f" % value
|
|
76
|
-
)
|
|
77
|
-
else:
|
|
78
74
|
raise StreamlitAPIException(
|
|
79
|
-
"Progress Value has invalid
|
|
75
|
+
f"Progress Value has invalid value [0.0, 1.0]: {value}"
|
|
80
76
|
)
|
|
77
|
+
raise StreamlitAPIException(
|
|
78
|
+
f"Progress Value has invalid type: {type(value).__name__}"
|
|
79
|
+
)
|
|
81
80
|
|
|
82
81
|
|
|
83
82
|
def _get_text(text: str | None) -> str | None:
|
|
@@ -86,13 +85,18 @@ def _get_text(text: str | None) -> str | None:
|
|
|
86
85
|
if isinstance(text, str):
|
|
87
86
|
return clean_text(text)
|
|
88
87
|
raise StreamlitAPIException(
|
|
89
|
-
f"Progress Text is of type {
|
|
88
|
+
f"Progress Text is of type {type(text)}, which is not an accepted type."
|
|
90
89
|
"Text only accepts: str. Please convert the text to an accepted type."
|
|
91
90
|
)
|
|
92
91
|
|
|
93
92
|
|
|
94
93
|
class ProgressMixin:
|
|
95
|
-
def progress(
|
|
94
|
+
def progress(
|
|
95
|
+
self,
|
|
96
|
+
value: FloatOrInt,
|
|
97
|
+
text: str | None = None,
|
|
98
|
+
width: WidthWithoutContent = "stretch",
|
|
99
|
+
) -> DeltaGenerator:
|
|
96
100
|
r"""Display a progress bar.
|
|
97
101
|
|
|
98
102
|
Parameters
|
|
@@ -119,6 +123,16 @@ class ProgressMixin:
|
|
|
119
123
|
.. |st.markdown| replace:: ``st.markdown``
|
|
120
124
|
.. _st.markdown: https://docs.streamlit.io/develop/api-reference/text/st.markdown
|
|
121
125
|
|
|
126
|
+
width : "stretch" or int
|
|
127
|
+
The width of the progress element. This can be one of the following:
|
|
128
|
+
|
|
129
|
+
- ``"stretch"`` (default): The width of the element matches the
|
|
130
|
+
width of the parent container.
|
|
131
|
+
- An integer specifying the width in pixels: The element has a
|
|
132
|
+
fixed width. If the specified width is greater than the width of
|
|
133
|
+
the parent container, the width of the element matches the width
|
|
134
|
+
of the parent container.
|
|
135
|
+
|
|
122
136
|
Example
|
|
123
137
|
-------
|
|
124
138
|
Here is an example of a progress bar increasing over time and disappearing when it reaches completion:
|
|
@@ -148,7 +162,11 @@ class ProgressMixin:
|
|
|
148
162
|
text = _get_text(text)
|
|
149
163
|
if text is not None:
|
|
150
164
|
progress_proto.text = text
|
|
151
|
-
|
|
165
|
+
|
|
166
|
+
validate_width(width)
|
|
167
|
+
layout_config = LayoutConfig(width=width)
|
|
168
|
+
|
|
169
|
+
return self.dg._enqueue("progress", progress_proto, layout_config=layout_config)
|
|
152
170
|
|
|
153
171
|
@property
|
|
154
172
|
def dg(self) -> DeltaGenerator:
|