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
|
@@ -11,11 +11,15 @@
|
|
|
11
11
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
12
12
|
# See the License for the specific language governing permissions and
|
|
13
13
|
# limitations under the License.
|
|
14
|
+
|
|
15
|
+
# Assert statements are allowed here since the app testing logic is used within unit tests:
|
|
16
|
+
# ruff: noqa: S101
|
|
17
|
+
|
|
14
18
|
from __future__ import annotations
|
|
15
19
|
|
|
16
20
|
import textwrap
|
|
17
21
|
from abc import ABC, abstractmethod
|
|
18
|
-
from collections.abc import Sequence
|
|
22
|
+
from collections.abc import Iterator, Sequence
|
|
19
23
|
from dataclasses import dataclass, field, fields, is_dataclass
|
|
20
24
|
from datetime import date, datetime, time, timedelta
|
|
21
25
|
from typing import (
|
|
@@ -29,7 +33,7 @@ from typing import (
|
|
|
29
33
|
overload,
|
|
30
34
|
)
|
|
31
35
|
|
|
32
|
-
from typing_extensions import TypeAlias
|
|
36
|
+
from typing_extensions import Self, TypeAlias
|
|
33
37
|
|
|
34
38
|
from streamlit import dataframe_util, util
|
|
35
39
|
from streamlit.elements.heading import HeadingProtoTag
|
|
@@ -124,9 +128,9 @@ class Element(ABC):
|
|
|
124
128
|
key: str | None
|
|
125
129
|
|
|
126
130
|
@abstractmethod
|
|
127
|
-
def __init__(self, proto: ElementProto, root: ElementTree): ...
|
|
131
|
+
def __init__(self, proto: ElementProto, root: ElementTree) -> None: ...
|
|
128
132
|
|
|
129
|
-
def __iter__(self):
|
|
133
|
+
def __iter__(self) -> Iterator[Self]:
|
|
130
134
|
yield self
|
|
131
135
|
|
|
132
136
|
@property
|
|
@@ -150,13 +154,13 @@ class Element(ABC):
|
|
|
150
154
|
"""
|
|
151
155
|
return self.root.run(timeout=timeout)
|
|
152
156
|
|
|
153
|
-
def __repr__(self):
|
|
157
|
+
def __repr__(self) -> str:
|
|
154
158
|
return util.repr_(self)
|
|
155
159
|
|
|
156
160
|
|
|
157
161
|
@dataclass(repr=False)
|
|
158
162
|
class UnknownElement(Element):
|
|
159
|
-
def __init__(self, proto: ElementProto, root: ElementTree):
|
|
163
|
+
def __init__(self, proto: ElementProto, root: ElementTree) -> None:
|
|
160
164
|
ty = proto.WhichOneof("type")
|
|
161
165
|
assert ty is not None
|
|
162
166
|
self.proto = getattr(proto, ty)
|
|
@@ -184,13 +188,13 @@ class Widget(Element, ABC):
|
|
|
184
188
|
key: str | None
|
|
185
189
|
_value: Any
|
|
186
190
|
|
|
187
|
-
def __init__(self, proto: Any, root: ElementTree):
|
|
191
|
+
def __init__(self, proto: Any, root: ElementTree) -> None:
|
|
188
192
|
self.proto = proto
|
|
189
193
|
self.root = root
|
|
190
194
|
self.key = user_key_from_element_id(self.id)
|
|
191
195
|
self._value = None
|
|
192
196
|
|
|
193
|
-
def set_value(self, v: Any):
|
|
197
|
+
def set_value(self, v: Any) -> Self:
|
|
194
198
|
"""Set the value of the widget."""
|
|
195
199
|
self._value = v
|
|
196
200
|
return self
|
|
@@ -204,7 +208,7 @@ El_co = TypeVar("El_co", bound=Element, covariant=True)
|
|
|
204
208
|
|
|
205
209
|
|
|
206
210
|
class ElementList(Generic[El_co]):
|
|
207
|
-
def __init__(self, els: Sequence[El_co]):
|
|
211
|
+
def __init__(self, els: Sequence[El_co]) -> None:
|
|
208
212
|
self._list: Sequence[El_co] = els
|
|
209
213
|
|
|
210
214
|
def __len__(self) -> int:
|
|
@@ -223,20 +227,18 @@ class ElementList(Generic[El_co]):
|
|
|
223
227
|
def __getitem__(self, idx: int | slice) -> El_co | ElementList[El_co]:
|
|
224
228
|
if isinstance(idx, slice):
|
|
225
229
|
return ElementList(self._list[idx])
|
|
226
|
-
|
|
227
|
-
return self._list[idx]
|
|
230
|
+
return self._list[idx]
|
|
228
231
|
|
|
229
|
-
def __iter__(self):
|
|
232
|
+
def __iter__(self) -> Iterator[El_co]:
|
|
230
233
|
yield from self._list
|
|
231
234
|
|
|
232
|
-
def __repr__(self):
|
|
235
|
+
def __repr__(self) -> str:
|
|
233
236
|
return util.repr_(self)
|
|
234
237
|
|
|
235
238
|
def __eq__(self, other: ElementList[El_co] | object) -> bool:
|
|
236
239
|
if isinstance(other, ElementList):
|
|
237
240
|
return self._list == other._list
|
|
238
|
-
|
|
239
|
-
return self._list == other
|
|
241
|
+
return self._list == other
|
|
240
242
|
|
|
241
243
|
@property
|
|
242
244
|
def values(self) -> Sequence[Any]:
|
|
@@ -260,7 +262,7 @@ class AlertBase(Element):
|
|
|
260
262
|
proto: AlertProto = field(repr=False)
|
|
261
263
|
icon: str
|
|
262
264
|
|
|
263
|
-
def __init__(self, proto: AlertProto, root: ElementTree):
|
|
265
|
+
def __init__(self, proto: AlertProto, root: ElementTree) -> None:
|
|
264
266
|
self.proto = proto
|
|
265
267
|
self.key = None
|
|
266
268
|
self.root = root
|
|
@@ -272,28 +274,28 @@ class AlertBase(Element):
|
|
|
272
274
|
|
|
273
275
|
@dataclass(repr=False)
|
|
274
276
|
class Error(AlertBase):
|
|
275
|
-
def __init__(self, proto: AlertProto, root: ElementTree):
|
|
277
|
+
def __init__(self, proto: AlertProto, root: ElementTree) -> None:
|
|
276
278
|
super().__init__(proto, root)
|
|
277
279
|
self.type = "error"
|
|
278
280
|
|
|
279
281
|
|
|
280
282
|
@dataclass(repr=False)
|
|
281
|
-
class Warning(AlertBase):
|
|
282
|
-
def __init__(self, proto: AlertProto, root: ElementTree):
|
|
283
|
+
class Warning(AlertBase): # noqa: A001
|
|
284
|
+
def __init__(self, proto: AlertProto, root: ElementTree) -> None:
|
|
283
285
|
super().__init__(proto, root)
|
|
284
286
|
self.type = "warning"
|
|
285
287
|
|
|
286
288
|
|
|
287
289
|
@dataclass(repr=False)
|
|
288
290
|
class Info(AlertBase):
|
|
289
|
-
def __init__(self, proto: AlertProto, root: ElementTree):
|
|
291
|
+
def __init__(self, proto: AlertProto, root: ElementTree) -> None:
|
|
290
292
|
super().__init__(proto, root)
|
|
291
293
|
self.type = "info"
|
|
292
294
|
|
|
293
295
|
|
|
294
296
|
@dataclass(repr=False)
|
|
295
297
|
class Success(AlertBase):
|
|
296
|
-
def __init__(self, proto: AlertProto, root: ElementTree):
|
|
298
|
+
def __init__(self, proto: AlertProto, root: ElementTree) -> None:
|
|
297
299
|
super().__init__(proto, root)
|
|
298
300
|
self.type = "success"
|
|
299
301
|
|
|
@@ -309,7 +311,7 @@ class Button(Widget):
|
|
|
309
311
|
help: str
|
|
310
312
|
form_id: str
|
|
311
313
|
|
|
312
|
-
def __init__(self, proto: ButtonProto, root: ElementTree):
|
|
314
|
+
def __init__(self, proto: ButtonProto, root: ElementTree) -> None:
|
|
313
315
|
super().__init__(proto, root)
|
|
314
316
|
self._value = False
|
|
315
317
|
self.type = "button"
|
|
@@ -326,10 +328,9 @@ class Button(Widget):
|
|
|
326
328
|
"""The value of the button. (bool)""" # noqa: D400
|
|
327
329
|
if self._value:
|
|
328
330
|
return self._value
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
return cast("bool", state[TESTING_KEY][self.id])
|
|
331
|
+
state = self.root.session_state
|
|
332
|
+
assert state
|
|
333
|
+
return cast("bool", state[TESTING_KEY][self.id])
|
|
333
334
|
|
|
334
335
|
def set_value(self, v: bool) -> Button:
|
|
335
336
|
"""Set the value of the button."""
|
|
@@ -349,7 +350,7 @@ class ChatInput(Widget):
|
|
|
349
350
|
proto: ChatInputProto = field(repr=False)
|
|
350
351
|
placeholder: str
|
|
351
352
|
|
|
352
|
-
def __init__(self, proto: ChatInputProto, root: ElementTree):
|
|
353
|
+
def __init__(self, proto: ChatInputProto, root: ElementTree) -> None:
|
|
353
354
|
super().__init__(proto, root)
|
|
354
355
|
self.type = "chat_input"
|
|
355
356
|
|
|
@@ -371,10 +372,9 @@ class ChatInput(Widget):
|
|
|
371
372
|
"""The value of the widget. (str)""" # noqa: D400
|
|
372
373
|
if self._value:
|
|
373
374
|
return self._value
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
return state[TESTING_KEY][self.id] # type: ignore
|
|
375
|
+
state = self.root.session_state
|
|
376
|
+
assert state
|
|
377
|
+
return state[TESTING_KEY][self.id] # type: ignore
|
|
378
378
|
|
|
379
379
|
|
|
380
380
|
@dataclass(repr=False)
|
|
@@ -388,7 +388,7 @@ class Checkbox(Widget):
|
|
|
388
388
|
help: str
|
|
389
389
|
form_id: str
|
|
390
390
|
|
|
391
|
-
def __init__(self, proto: CheckboxProto, root: ElementTree):
|
|
391
|
+
def __init__(self, proto: CheckboxProto, root: ElementTree) -> None:
|
|
392
392
|
super().__init__(proto, root)
|
|
393
393
|
self.type = "checkbox"
|
|
394
394
|
|
|
@@ -404,10 +404,9 @@ class Checkbox(Widget):
|
|
|
404
404
|
"""The value of the widget. (bool)""" # noqa: D400
|
|
405
405
|
if self._value is not None:
|
|
406
406
|
return self._value
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
return cast("bool", state[self.id])
|
|
407
|
+
state = self.root.session_state
|
|
408
|
+
assert state
|
|
409
|
+
return cast("bool", state[self.id])
|
|
411
410
|
|
|
412
411
|
def set_value(self, v: bool) -> Checkbox:
|
|
413
412
|
"""Set the value of the widget."""
|
|
@@ -433,7 +432,7 @@ class Code(Element):
|
|
|
433
432
|
show_line_numbers: bool
|
|
434
433
|
key: None
|
|
435
434
|
|
|
436
|
-
def __init__(self, proto: CodeProto, root: ElementTree):
|
|
435
|
+
def __init__(self, proto: CodeProto, root: ElementTree) -> None:
|
|
437
436
|
self.proto = proto
|
|
438
437
|
self.key = None
|
|
439
438
|
self.root = root
|
|
@@ -456,7 +455,7 @@ class ColorPicker(Widget):
|
|
|
456
455
|
|
|
457
456
|
proto: ColorPickerProto = field(repr=False)
|
|
458
457
|
|
|
459
|
-
def __init__(self, proto: ColorPickerProto, root: ElementTree):
|
|
458
|
+
def __init__(self, proto: ColorPickerProto, root: ElementTree) -> None:
|
|
460
459
|
super().__init__(proto, root)
|
|
461
460
|
self.type = "color_picker"
|
|
462
461
|
|
|
@@ -465,10 +464,9 @@ class ColorPicker(Widget):
|
|
|
465
464
|
"""The currently selected value as a hex string. (str)""" # noqa: D400
|
|
466
465
|
if self._value is not None:
|
|
467
466
|
return self._value
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
return cast("str", state[self.id])
|
|
467
|
+
state = self.root.session_state
|
|
468
|
+
assert state
|
|
469
|
+
return cast("str", state[self.id])
|
|
472
470
|
|
|
473
471
|
@property
|
|
474
472
|
def _widget_state(self) -> WidgetState:
|
|
@@ -497,7 +495,7 @@ class ColorPicker(Widget):
|
|
|
497
495
|
class Dataframe(Element):
|
|
498
496
|
proto: ArrowProto = field(repr=False)
|
|
499
497
|
|
|
500
|
-
def __init__(self, proto: ArrowProto, root: ElementTree):
|
|
498
|
+
def __init__(self, proto: ArrowProto, root: ElementTree) -> None:
|
|
501
499
|
self.key = None
|
|
502
500
|
self.proto = proto
|
|
503
501
|
self.root = root
|
|
@@ -525,7 +523,7 @@ class DateInput(Widget):
|
|
|
525
523
|
help: str
|
|
526
524
|
form_id: str
|
|
527
525
|
|
|
528
|
-
def __init__(self, proto: DateInputProto, root: ElementTree):
|
|
526
|
+
def __init__(self, proto: DateInputProto, root: ElementTree) -> None:
|
|
529
527
|
super().__init__(proto, root)
|
|
530
528
|
self._value = InitialValue()
|
|
531
529
|
self.type = "date_input"
|
|
@@ -552,20 +550,19 @@ class DateInput(Widget):
|
|
|
552
550
|
if not isinstance(self._value, InitialValue):
|
|
553
551
|
parsed, _ = _parse_date_value(self._value)
|
|
554
552
|
return tuple(parsed) if parsed is not None else None # type: ignore
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
return state[self.id] # type: ignore
|
|
553
|
+
state = self.root.session_state
|
|
554
|
+
assert state
|
|
555
|
+
return state[self.id] # type: ignore
|
|
559
556
|
|
|
560
557
|
|
|
561
558
|
@dataclass(repr=False)
|
|
562
|
-
class Exception(Element):
|
|
559
|
+
class Exception(Element): # noqa: A001
|
|
563
560
|
message: str
|
|
564
561
|
is_markdown: bool
|
|
565
562
|
stack_trace: list[str]
|
|
566
563
|
is_warning: bool
|
|
567
564
|
|
|
568
|
-
def __init__(self, proto: ExceptionProto, root: ElementTree):
|
|
565
|
+
def __init__(self, proto: ExceptionProto, root: ElementTree) -> None:
|
|
569
566
|
self.key = None
|
|
570
567
|
self.root = root
|
|
571
568
|
self.proto = proto
|
|
@@ -588,7 +585,7 @@ class HeadingBase(Element, ABC):
|
|
|
588
585
|
hide_anchor: bool
|
|
589
586
|
key: None
|
|
590
587
|
|
|
591
|
-
def __init__(self, proto: HeadingProto, root: ElementTree, type_: str):
|
|
588
|
+
def __init__(self, proto: HeadingProto, root: ElementTree, type_: str) -> None:
|
|
592
589
|
self.proto = proto
|
|
593
590
|
self.key = None
|
|
594
591
|
self.root = root
|
|
@@ -601,19 +598,19 @@ class HeadingBase(Element, ABC):
|
|
|
601
598
|
|
|
602
599
|
@dataclass(repr=False)
|
|
603
600
|
class Header(HeadingBase):
|
|
604
|
-
def __init__(self, proto: HeadingProto, root: ElementTree):
|
|
601
|
+
def __init__(self, proto: HeadingProto, root: ElementTree) -> None:
|
|
605
602
|
super().__init__(proto, root, "header")
|
|
606
603
|
|
|
607
604
|
|
|
608
605
|
@dataclass(repr=False)
|
|
609
606
|
class Subheader(HeadingBase):
|
|
610
|
-
def __init__(self, proto: HeadingProto, root: ElementTree):
|
|
607
|
+
def __init__(self, proto: HeadingProto, root: ElementTree) -> None:
|
|
611
608
|
super().__init__(proto, root, "subheader")
|
|
612
609
|
|
|
613
610
|
|
|
614
611
|
@dataclass(repr=False)
|
|
615
612
|
class Title(HeadingBase):
|
|
616
|
-
def __init__(self, proto: HeadingProto, root: ElementTree):
|
|
613
|
+
def __init__(self, proto: HeadingProto, root: ElementTree) -> None:
|
|
617
614
|
super().__init__(proto, root, "title")
|
|
618
615
|
|
|
619
616
|
|
|
@@ -623,7 +620,7 @@ class Json(Element):
|
|
|
623
620
|
|
|
624
621
|
expanded: bool
|
|
625
622
|
|
|
626
|
-
def __init__(self, proto: JsonProto, root: ElementTree):
|
|
623
|
+
def __init__(self, proto: JsonProto, root: ElementTree) -> None:
|
|
627
624
|
self.proto = proto
|
|
628
625
|
self.key = None
|
|
629
626
|
self.root = root
|
|
@@ -642,7 +639,7 @@ class Markdown(Element):
|
|
|
642
639
|
allow_html: bool
|
|
643
640
|
key: None
|
|
644
641
|
|
|
645
|
-
def __init__(self, proto: MarkdownProto, root: ElementTree):
|
|
642
|
+
def __init__(self, proto: MarkdownProto, root: ElementTree) -> None:
|
|
646
643
|
self.proto = proto
|
|
647
644
|
self.key = None
|
|
648
645
|
self.root = root
|
|
@@ -655,21 +652,21 @@ class Markdown(Element):
|
|
|
655
652
|
|
|
656
653
|
@dataclass(repr=False)
|
|
657
654
|
class Caption(Markdown):
|
|
658
|
-
def __init__(self, proto: MarkdownProto, root: ElementTree):
|
|
655
|
+
def __init__(self, proto: MarkdownProto, root: ElementTree) -> None:
|
|
659
656
|
super().__init__(proto, root)
|
|
660
657
|
self.type = "caption"
|
|
661
658
|
|
|
662
659
|
|
|
663
660
|
@dataclass(repr=False)
|
|
664
661
|
class Divider(Markdown):
|
|
665
|
-
def __init__(self, proto: MarkdownProto, root: ElementTree):
|
|
662
|
+
def __init__(self, proto: MarkdownProto, root: ElementTree) -> None:
|
|
666
663
|
super().__init__(proto, root)
|
|
667
664
|
self.type = "divider"
|
|
668
665
|
|
|
669
666
|
|
|
670
667
|
@dataclass(repr=False)
|
|
671
668
|
class Latex(Markdown):
|
|
672
|
-
def __init__(self, proto: MarkdownProto, root: ElementTree):
|
|
669
|
+
def __init__(self, proto: MarkdownProto, root: ElementTree) -> None:
|
|
673
670
|
super().__init__(proto, root)
|
|
674
671
|
self.type = "latex"
|
|
675
672
|
|
|
@@ -682,7 +679,7 @@ class Metric(Element):
|
|
|
682
679
|
color: str
|
|
683
680
|
help: str
|
|
684
681
|
|
|
685
|
-
def __init__(self, proto: MetricProto, root: ElementTree):
|
|
682
|
+
def __init__(self, proto: MetricProto, root: ElementTree) -> None:
|
|
686
683
|
self.proto = proto
|
|
687
684
|
self.key = None
|
|
688
685
|
self.root = root
|
|
@@ -703,7 +700,7 @@ class ButtonGroup(Widget, Generic[T]):
|
|
|
703
700
|
options: list[ButtonGroupProto.Option]
|
|
704
701
|
form_id: str
|
|
705
702
|
|
|
706
|
-
def __init__(self, proto: ButtonGroupProto, root: ElementTree):
|
|
703
|
+
def __init__(self, proto: ButtonGroupProto, root: ElementTree) -> None:
|
|
707
704
|
super().__init__(proto, root)
|
|
708
705
|
self.type = "button_group"
|
|
709
706
|
self.options = list(proto.options)
|
|
@@ -724,10 +721,9 @@ class ButtonGroup(Widget, Generic[T]):
|
|
|
724
721
|
"""The currently selected values from the options. (list)""" # noqa: D400
|
|
725
722
|
if self._value is not None:
|
|
726
723
|
return self._value
|
|
727
|
-
|
|
728
|
-
|
|
729
|
-
|
|
730
|
-
return cast("list[T]", state[self.id])
|
|
724
|
+
state = self.root.session_state
|
|
725
|
+
assert state
|
|
726
|
+
return cast("list[T]", state[self.id])
|
|
731
727
|
|
|
732
728
|
@property
|
|
733
729
|
def indices(self) -> Sequence[int]:
|
|
@@ -755,11 +751,10 @@ class ButtonGroup(Widget, Generic[T]):
|
|
|
755
751
|
current = self.value
|
|
756
752
|
if v in current:
|
|
757
753
|
return self
|
|
758
|
-
|
|
759
|
-
|
|
760
|
-
|
|
761
|
-
|
|
762
|
-
return self
|
|
754
|
+
new = current.copy()
|
|
755
|
+
new.append(v)
|
|
756
|
+
self.set_value(new)
|
|
757
|
+
return self
|
|
763
758
|
|
|
764
759
|
def unselect(self, v: T) -> ButtonGroup[T]:
|
|
765
760
|
"""
|
|
@@ -770,12 +765,11 @@ class ButtonGroup(Widget, Generic[T]):
|
|
|
770
765
|
current = self.value
|
|
771
766
|
if v not in current:
|
|
772
767
|
return self
|
|
773
|
-
|
|
774
|
-
|
|
775
|
-
|
|
776
|
-
|
|
777
|
-
|
|
778
|
-
return self
|
|
768
|
+
new = current.copy()
|
|
769
|
+
while v in new:
|
|
770
|
+
new.remove(v)
|
|
771
|
+
self.set_value(new)
|
|
772
|
+
return self
|
|
779
773
|
|
|
780
774
|
|
|
781
775
|
@dataclass(repr=False)
|
|
@@ -791,7 +785,7 @@ class Multiselect(Widget, Generic[T]):
|
|
|
791
785
|
help: str
|
|
792
786
|
form_id: str
|
|
793
787
|
|
|
794
|
-
def __init__(self, proto: MultiSelectProto, root: ElementTree):
|
|
788
|
+
def __init__(self, proto: MultiSelectProto, root: ElementTree) -> None:
|
|
795
789
|
super().__init__(proto, root)
|
|
796
790
|
self.type = "multiselect"
|
|
797
791
|
self.options = list(proto.options)
|
|
@@ -812,10 +806,9 @@ class Multiselect(Widget, Generic[T]):
|
|
|
812
806
|
"""The currently selected values from the options. (list)""" # noqa: D400
|
|
813
807
|
if self._value is not None:
|
|
814
808
|
return self._value
|
|
815
|
-
|
|
816
|
-
|
|
817
|
-
|
|
818
|
-
return cast("list[T]", state[self.id])
|
|
809
|
+
state = self.root.session_state
|
|
810
|
+
assert state
|
|
811
|
+
return cast("list[T]", state[self.id])
|
|
819
812
|
|
|
820
813
|
@property
|
|
821
814
|
def indices(self) -> Sequence[int]:
|
|
@@ -848,11 +841,10 @@ class Multiselect(Widget, Generic[T]):
|
|
|
848
841
|
current = self.value
|
|
849
842
|
if v in current:
|
|
850
843
|
return self
|
|
851
|
-
|
|
852
|
-
|
|
853
|
-
|
|
854
|
-
|
|
855
|
-
return self
|
|
844
|
+
new = current.copy()
|
|
845
|
+
new.append(v)
|
|
846
|
+
self.set_value(new)
|
|
847
|
+
return self
|
|
856
848
|
|
|
857
849
|
def unselect(self, v: T) -> Multiselect[T]:
|
|
858
850
|
"""
|
|
@@ -863,12 +855,11 @@ class Multiselect(Widget, Generic[T]):
|
|
|
863
855
|
current = self.value
|
|
864
856
|
if v not in current:
|
|
865
857
|
return self
|
|
866
|
-
|
|
867
|
-
|
|
868
|
-
|
|
869
|
-
|
|
870
|
-
|
|
871
|
-
return self
|
|
858
|
+
new = current.copy()
|
|
859
|
+
while v in new:
|
|
860
|
+
new.remove(v)
|
|
861
|
+
self.set_value(new)
|
|
862
|
+
return self
|
|
872
863
|
|
|
873
864
|
|
|
874
865
|
Number = Union[int, float]
|
|
@@ -887,7 +878,7 @@ class NumberInput(Widget):
|
|
|
887
878
|
help: str
|
|
888
879
|
form_id: str
|
|
889
880
|
|
|
890
|
-
def __init__(self, proto: NumberInputProto, root: ElementTree):
|
|
881
|
+
def __init__(self, proto: NumberInputProto, root: ElementTree) -> None:
|
|
891
882
|
super().__init__(proto, root)
|
|
892
883
|
self._value = InitialValue()
|
|
893
884
|
self.type = "number_input"
|
|
@@ -912,12 +903,11 @@ class NumberInput(Widget):
|
|
|
912
903
|
"""Get the current value of the ``st.number_input`` widget."""
|
|
913
904
|
if not isinstance(self._value, InitialValue):
|
|
914
905
|
return self._value
|
|
915
|
-
|
|
916
|
-
|
|
917
|
-
assert state
|
|
906
|
+
state = self.root.session_state
|
|
907
|
+
assert state
|
|
918
908
|
|
|
919
|
-
|
|
920
|
-
|
|
909
|
+
# Awkward to do this with `cast`
|
|
910
|
+
return state[self.id] # type: ignore
|
|
921
911
|
|
|
922
912
|
def increment(self) -> NumberInput:
|
|
923
913
|
"""Increment the ``st.number_input`` widget as if the user clicked "+"."""
|
|
@@ -949,7 +939,7 @@ class Radio(Widget, Generic[T]):
|
|
|
949
939
|
help: str
|
|
950
940
|
form_id: str
|
|
951
941
|
|
|
952
|
-
def __init__(self, proto: RadioProto, root: ElementTree):
|
|
942
|
+
def __init__(self, proto: RadioProto, root: ElementTree) -> None:
|
|
953
943
|
super().__init__(proto, root)
|
|
954
944
|
self._value = InitialValue()
|
|
955
945
|
self.type = "radio"
|
|
@@ -967,10 +957,9 @@ class Radio(Widget, Generic[T]):
|
|
|
967
957
|
"""The currently selected value from the options. (Any)""" # noqa: D400
|
|
968
958
|
if not isinstance(self._value, InitialValue):
|
|
969
959
|
return self._value
|
|
970
|
-
|
|
971
|
-
|
|
972
|
-
|
|
973
|
-
return cast("T", state[self.id])
|
|
960
|
+
state = self.root.session_state
|
|
961
|
+
assert state
|
|
962
|
+
return cast("T", state[self.id])
|
|
974
963
|
|
|
975
964
|
@property
|
|
976
965
|
def format_func(self) -> Callable[[Any], Any]:
|
|
@@ -1008,7 +997,7 @@ class Selectbox(Widget, Generic[T]):
|
|
|
1008
997
|
help: str
|
|
1009
998
|
form_id: str
|
|
1010
999
|
|
|
1011
|
-
def __init__(self, proto: SelectboxProto, root: ElementTree):
|
|
1000
|
+
def __init__(self, proto: SelectboxProto, root: ElementTree) -> None:
|
|
1012
1001
|
super().__init__(proto, root)
|
|
1013
1002
|
self._value = InitialValue()
|
|
1014
1003
|
self.type = "selectbox"
|
|
@@ -1029,10 +1018,9 @@ class Selectbox(Widget, Generic[T]):
|
|
|
1029
1018
|
"""The currently selected value from the options. (Any)""" # noqa: D400
|
|
1030
1019
|
if not isinstance(self._value, InitialValue):
|
|
1031
1020
|
return self._value
|
|
1032
|
-
|
|
1033
|
-
|
|
1034
|
-
|
|
1035
|
-
return cast("T", state[self.id])
|
|
1021
|
+
state = self.root.session_state
|
|
1022
|
+
assert state
|
|
1023
|
+
return cast("T", state[self.id])
|
|
1036
1024
|
|
|
1037
1025
|
@property
|
|
1038
1026
|
def format_func(self) -> Callable[[Any], Any]:
|
|
@@ -1081,7 +1069,7 @@ class SelectSlider(Widget, Generic[T]):
|
|
|
1081
1069
|
help: str
|
|
1082
1070
|
form_id: str
|
|
1083
1071
|
|
|
1084
|
-
def __init__(self, proto: SliderProto, root: ElementTree):
|
|
1072
|
+
def __init__(self, proto: SliderProto, root: ElementTree) -> None:
|
|
1085
1073
|
super().__init__(proto, root)
|
|
1086
1074
|
self.type = "select_slider"
|
|
1087
1075
|
self.options = list(proto.options)
|
|
@@ -1112,11 +1100,10 @@ class SelectSlider(Widget, Generic[T]):
|
|
|
1112
1100
|
"""The currently selected value or range. (Any or Sequence of Any)""" # noqa: D400
|
|
1113
1101
|
if self._value is not None:
|
|
1114
1102
|
return self._value
|
|
1115
|
-
|
|
1116
|
-
|
|
1117
|
-
|
|
1118
|
-
|
|
1119
|
-
return state[self.id] # type: ignore
|
|
1103
|
+
state = self.root.session_state
|
|
1104
|
+
assert state
|
|
1105
|
+
# Awkward to do this with `cast`
|
|
1106
|
+
return state[self.id] # type: ignore
|
|
1120
1107
|
|
|
1121
1108
|
@property
|
|
1122
1109
|
def format_func(self) -> Callable[[Any], Any]:
|
|
@@ -1144,7 +1131,7 @@ class Slider(Widget, Generic[SliderValueT]):
|
|
|
1144
1131
|
help: str
|
|
1145
1132
|
form_id: str
|
|
1146
1133
|
|
|
1147
|
-
def __init__(self, proto: SliderProto, root: ElementTree):
|
|
1134
|
+
def __init__(self, proto: SliderProto, root: ElementTree) -> None:
|
|
1148
1135
|
super().__init__(proto, root)
|
|
1149
1136
|
self.type = "slider"
|
|
1150
1137
|
|
|
@@ -1171,11 +1158,10 @@ class Slider(Widget, Generic[SliderValueT]):
|
|
|
1171
1158
|
"""The currently selected value or range. (Any or Sequence of Any)""" # noqa: D400
|
|
1172
1159
|
if self._value is not None:
|
|
1173
1160
|
return self._value
|
|
1174
|
-
|
|
1175
|
-
|
|
1176
|
-
|
|
1177
|
-
|
|
1178
|
-
return state[self.id] # type: ignore
|
|
1161
|
+
state = self.root.session_state
|
|
1162
|
+
assert state
|
|
1163
|
+
# Awkward to do this with `cast`
|
|
1164
|
+
return state[self.id] # type: ignore
|
|
1179
1165
|
|
|
1180
1166
|
def set_range(
|
|
1181
1167
|
self, lower: SliderValueT, upper: SliderValueT
|
|
@@ -1188,7 +1174,7 @@ class Slider(Widget, Generic[SliderValueT]):
|
|
|
1188
1174
|
class Table(Element):
|
|
1189
1175
|
proto: ArrowProto = field(repr=False)
|
|
1190
1176
|
|
|
1191
|
-
def __init__(self, proto: ArrowProto, root: ElementTree):
|
|
1177
|
+
def __init__(self, proto: ArrowProto, root: ElementTree) -> None:
|
|
1192
1178
|
self.key = None
|
|
1193
1179
|
self.proto = proto
|
|
1194
1180
|
self.root = root
|
|
@@ -1205,7 +1191,7 @@ class Text(Element):
|
|
|
1205
1191
|
|
|
1206
1192
|
key: None = None
|
|
1207
1193
|
|
|
1208
|
-
def __init__(self, proto: TextProto, root: ElementTree):
|
|
1194
|
+
def __init__(self, proto: TextProto, root: ElementTree) -> None:
|
|
1209
1195
|
self.proto = proto
|
|
1210
1196
|
self.root = root
|
|
1211
1197
|
self.type = "text"
|
|
@@ -1229,7 +1215,7 @@ class TextArea(Widget):
|
|
|
1229
1215
|
help: str
|
|
1230
1216
|
form_id: str
|
|
1231
1217
|
|
|
1232
|
-
def __init__(self, proto: TextAreaProto, root: ElementTree):
|
|
1218
|
+
def __init__(self, proto: TextAreaProto, root: ElementTree) -> None:
|
|
1233
1219
|
super().__init__(proto, root)
|
|
1234
1220
|
self._value = InitialValue()
|
|
1235
1221
|
self.type = "text_area"
|
|
@@ -1252,11 +1238,10 @@ class TextArea(Widget):
|
|
|
1252
1238
|
"""The current value of the widget. (str)""" # noqa: D400
|
|
1253
1239
|
if not isinstance(self._value, InitialValue):
|
|
1254
1240
|
return self._value
|
|
1255
|
-
|
|
1256
|
-
|
|
1257
|
-
|
|
1258
|
-
|
|
1259
|
-
return state[self.id] # type: ignore
|
|
1241
|
+
state = self.root.session_state
|
|
1242
|
+
assert state
|
|
1243
|
+
# Awkward to do this with `cast`
|
|
1244
|
+
return state[self.id] # type: ignore
|
|
1260
1245
|
|
|
1261
1246
|
def input(self, v: str) -> TextArea:
|
|
1262
1247
|
"""
|
|
@@ -1282,7 +1267,7 @@ class TextInput(Widget):
|
|
|
1282
1267
|
help: str
|
|
1283
1268
|
form_id: str
|
|
1284
1269
|
|
|
1285
|
-
def __init__(self, proto: TextInputProto, root: ElementTree):
|
|
1270
|
+
def __init__(self, proto: TextInputProto, root: ElementTree) -> None:
|
|
1286
1271
|
super().__init__(proto, root)
|
|
1287
1272
|
self._value = InitialValue()
|
|
1288
1273
|
self.type = "text_input"
|
|
@@ -1305,11 +1290,10 @@ class TextInput(Widget):
|
|
|
1305
1290
|
"""The current value of the widget. (str)""" # noqa: D400
|
|
1306
1291
|
if not isinstance(self._value, InitialValue):
|
|
1307
1292
|
return self._value
|
|
1308
|
-
|
|
1309
|
-
|
|
1310
|
-
|
|
1311
|
-
|
|
1312
|
-
return state[self.id] # type: ignore
|
|
1293
|
+
state = self.root.session_state
|
|
1294
|
+
assert state
|
|
1295
|
+
# Awkward to do this with `cast`
|
|
1296
|
+
return state[self.id] # type: ignore
|
|
1313
1297
|
|
|
1314
1298
|
def input(self, v: str) -> TextInput:
|
|
1315
1299
|
"""
|
|
@@ -1336,7 +1320,7 @@ class TimeInput(Widget):
|
|
|
1336
1320
|
help: str
|
|
1337
1321
|
form_id: str
|
|
1338
1322
|
|
|
1339
|
-
def __init__(self, proto: TimeInputProto, root: ElementTree):
|
|
1323
|
+
def __init__(self, proto: TimeInputProto, root: ElementTree) -> None:
|
|
1340
1324
|
super().__init__(proto, root)
|
|
1341
1325
|
self._value = InitialValue()
|
|
1342
1326
|
self.type = "time_input"
|
|
@@ -1362,12 +1346,10 @@ class TimeInput(Widget):
|
|
|
1362
1346
|
"""The current value of the widget. (time)""" # noqa: D400
|
|
1363
1347
|
if not isinstance(self._value, InitialValue):
|
|
1364
1348
|
v = self._value
|
|
1365
|
-
|
|
1366
|
-
|
|
1367
|
-
|
|
1368
|
-
|
|
1369
|
-
assert state
|
|
1370
|
-
return state[self.id] # type: ignore
|
|
1349
|
+
return v.time() if isinstance(v, datetime) else v
|
|
1350
|
+
state = self.root.session_state
|
|
1351
|
+
assert state
|
|
1352
|
+
return state[self.id] # type: ignore
|
|
1371
1353
|
|
|
1372
1354
|
def increment(self) -> TimeInput:
|
|
1373
1355
|
"""Select the next available time."""
|
|
@@ -1389,7 +1371,7 @@ class Toast(Element):
|
|
|
1389
1371
|
proto: ToastProto = field(repr=False)
|
|
1390
1372
|
icon: str
|
|
1391
1373
|
|
|
1392
|
-
def __init__(self, proto: ToastProto, root: ElementTree):
|
|
1374
|
+
def __init__(self, proto: ToastProto, root: ElementTree) -> None:
|
|
1393
1375
|
self.proto = proto
|
|
1394
1376
|
self.key = None
|
|
1395
1377
|
self.root = root
|
|
@@ -1411,7 +1393,7 @@ class Toggle(Widget):
|
|
|
1411
1393
|
help: str
|
|
1412
1394
|
form_id: str
|
|
1413
1395
|
|
|
1414
|
-
def __init__(self, proto: CheckboxProto, root: ElementTree):
|
|
1396
|
+
def __init__(self, proto: CheckboxProto, root: ElementTree) -> None:
|
|
1415
1397
|
super().__init__(proto, root)
|
|
1416
1398
|
self._value = None
|
|
1417
1399
|
self.type = "toggle"
|
|
@@ -1428,10 +1410,9 @@ class Toggle(Widget):
|
|
|
1428
1410
|
"""The current value of the widget. (bool)""" # noqa: D400
|
|
1429
1411
|
if self._value is not None:
|
|
1430
1412
|
return self._value
|
|
1431
|
-
|
|
1432
|
-
|
|
1433
|
-
|
|
1434
|
-
return cast("bool", state[self.id])
|
|
1413
|
+
state = self.root.session_state
|
|
1414
|
+
assert state
|
|
1415
|
+
return cast("bool", state[self.id])
|
|
1435
1416
|
|
|
1436
1417
|
def set_value(self, v: bool) -> Toggle:
|
|
1437
1418
|
"""Set the value of the widget."""
|
|
@@ -1460,7 +1441,7 @@ class Block:
|
|
|
1460
1441
|
self,
|
|
1461
1442
|
proto: BlockProto | None,
|
|
1462
1443
|
root: ElementTree,
|
|
1463
|
-
):
|
|
1444
|
+
) -> None:
|
|
1464
1445
|
self.children = {}
|
|
1465
1446
|
self.proto = proto
|
|
1466
1447
|
if proto:
|
|
@@ -1477,7 +1458,7 @@ class Block:
|
|
|
1477
1458
|
def __len__(self) -> int:
|
|
1478
1459
|
return len(self.children)
|
|
1479
1460
|
|
|
1480
|
-
def __iter__(self):
|
|
1461
|
+
def __iter__(self) -> Iterator[Node]:
|
|
1481
1462
|
yield self
|
|
1482
1463
|
for child_idx in self.children:
|
|
1483
1464
|
yield from self.children[child_idx]
|
|
@@ -1665,11 +1646,11 @@ class Block:
|
|
|
1665
1646
|
"""
|
|
1666
1647
|
return self.root.run(timeout=timeout)
|
|
1667
1648
|
|
|
1668
|
-
def __repr__(self):
|
|
1649
|
+
def __repr__(self) -> str:
|
|
1669
1650
|
return repr_(self)
|
|
1670
1651
|
|
|
1671
1652
|
|
|
1672
|
-
def repr_(self) -> str:
|
|
1653
|
+
def repr_(self: object) -> str:
|
|
1673
1654
|
"""A custom repr similar to `streamlit.util.repr_` but that shows tree
|
|
1674
1655
|
structure using indentation.
|
|
1675
1656
|
"""
|
|
@@ -1690,10 +1671,11 @@ def repr_(self) -> str:
|
|
|
1690
1671
|
|
|
1691
1672
|
reprs = []
|
|
1692
1673
|
for field_name, value in fields_vals:
|
|
1693
|
-
|
|
1694
|
-
|
|
1695
|
-
|
|
1696
|
-
|
|
1674
|
+
line = (
|
|
1675
|
+
f"{field_name}={format_dict(value)}"
|
|
1676
|
+
if isinstance(value, dict)
|
|
1677
|
+
else f"{field_name}={value!r}"
|
|
1678
|
+
)
|
|
1697
1679
|
reprs.append(line)
|
|
1698
1680
|
|
|
1699
1681
|
reprs[0] = "\n" + reprs[0]
|
|
@@ -1703,15 +1685,14 @@ def repr_(self) -> str:
|
|
|
1703
1685
|
return f"{classname}({field_reprs}\n)"
|
|
1704
1686
|
|
|
1705
1687
|
|
|
1706
|
-
def format_dict(d: dict[Any, Any]):
|
|
1688
|
+
def format_dict(d: dict[Any, Any]) -> str:
|
|
1707
1689
|
lines = []
|
|
1708
1690
|
for k, v in d.items():
|
|
1709
1691
|
line = f"{k}: {v!r}"
|
|
1710
1692
|
lines.append(line)
|
|
1711
1693
|
r = ",\n".join(lines)
|
|
1712
1694
|
r = textwrap.indent(r, " " * 4)
|
|
1713
|
-
|
|
1714
|
-
return r
|
|
1695
|
+
return f"{{\n{r}\n}}"
|
|
1715
1696
|
|
|
1716
1697
|
|
|
1717
1698
|
@dataclass(repr=False)
|
|
@@ -1723,7 +1704,7 @@ class SpecialBlock(Block):
|
|
|
1723
1704
|
proto: BlockProto | None,
|
|
1724
1705
|
root: ElementTree,
|
|
1725
1706
|
type: str | None = None,
|
|
1726
|
-
):
|
|
1707
|
+
) -> None:
|
|
1727
1708
|
self.children = {}
|
|
1728
1709
|
self.proto = proto
|
|
1729
1710
|
if type:
|
|
@@ -1750,7 +1731,7 @@ class ChatMessage(Block):
|
|
|
1750
1731
|
self,
|
|
1751
1732
|
proto: BlockProto.ChatMessage,
|
|
1752
1733
|
root: ElementTree,
|
|
1753
|
-
):
|
|
1734
|
+
) -> None:
|
|
1754
1735
|
self.children = {}
|
|
1755
1736
|
self.proto = proto
|
|
1756
1737
|
self.root = root
|
|
@@ -1772,7 +1753,7 @@ class Column(Block):
|
|
|
1772
1753
|
self,
|
|
1773
1754
|
proto: BlockProto.Column,
|
|
1774
1755
|
root: ElementTree,
|
|
1775
|
-
):
|
|
1756
|
+
) -> None:
|
|
1776
1757
|
self.children = {}
|
|
1777
1758
|
self.proto = proto
|
|
1778
1759
|
self.root = root
|
|
@@ -1788,7 +1769,7 @@ class Expander(Block):
|
|
|
1788
1769
|
icon: str
|
|
1789
1770
|
label: str
|
|
1790
1771
|
|
|
1791
|
-
def __init__(self, proto: BlockProto.Expandable, root: ElementTree):
|
|
1772
|
+
def __init__(self, proto: BlockProto.Expandable, root: ElementTree) -> None:
|
|
1792
1773
|
self.children = {}
|
|
1793
1774
|
self.proto = proto
|
|
1794
1775
|
self.root = root
|
|
@@ -1806,7 +1787,7 @@ class Status(Block):
|
|
|
1806
1787
|
icon: str
|
|
1807
1788
|
label: str
|
|
1808
1789
|
|
|
1809
|
-
def __init__(self, proto: BlockProto.Expandable, root: ElementTree):
|
|
1790
|
+
def __init__(self, proto: BlockProto.Expandable, root: ElementTree) -> None:
|
|
1810
1791
|
self.children = {}
|
|
1811
1792
|
self.proto = proto
|
|
1812
1793
|
self.root = root
|
|
@@ -1815,15 +1796,14 @@ class Status(Block):
|
|
|
1815
1796
|
self.label = proto.label
|
|
1816
1797
|
|
|
1817
1798
|
@property
|
|
1818
|
-
def state(self):
|
|
1799
|
+
def state(self) -> str:
|
|
1819
1800
|
if self.icon == "spinner":
|
|
1820
1801
|
return "running"
|
|
1821
|
-
|
|
1802
|
+
if self.icon == ":material/check:":
|
|
1822
1803
|
return "complete"
|
|
1823
|
-
|
|
1804
|
+
if self.icon == ":material/error:":
|
|
1824
1805
|
return "error"
|
|
1825
|
-
|
|
1826
|
-
raise ValueError("Unknown Status state")
|
|
1806
|
+
raise ValueError("Unknown Status state")
|
|
1827
1807
|
|
|
1828
1808
|
|
|
1829
1809
|
@dataclass(repr=False)
|
|
@@ -1838,7 +1818,7 @@ class Tab(Block):
|
|
|
1838
1818
|
self,
|
|
1839
1819
|
proto: BlockProto.Tab,
|
|
1840
1820
|
root: ElementTree,
|
|
1841
|
-
):
|
|
1821
|
+
) -> None:
|
|
1842
1822
|
self.children = {}
|
|
1843
1823
|
self.proto = proto
|
|
1844
1824
|
self.root = root
|
|
@@ -1852,8 +1832,7 @@ Node: TypeAlias = Union[Element, Block]
|
|
|
1852
1832
|
def get_widget_state(node: Node) -> WidgetState | None:
|
|
1853
1833
|
if isinstance(node, Widget):
|
|
1854
1834
|
return node._widget_state
|
|
1855
|
-
|
|
1856
|
-
return None
|
|
1835
|
+
return None
|
|
1857
1836
|
|
|
1858
1837
|
|
|
1859
1838
|
@dataclass(repr=False)
|
|
@@ -1883,7 +1862,7 @@ class ElementTree(Block):
|
|
|
1883
1862
|
|
|
1884
1863
|
_runner: AppTest | None = field(repr=False, default=None)
|
|
1885
1864
|
|
|
1886
|
-
def __init__(self):
|
|
1865
|
+
def __init__(self) -> None:
|
|
1887
1866
|
self.children = {}
|
|
1888
1867
|
self.root = self
|
|
1889
1868
|
self.type = "root"
|
|
@@ -1928,7 +1907,7 @@ class ElementTree(Block):
|
|
|
1928
1907
|
widget_states = self.get_widget_states()
|
|
1929
1908
|
return self._runner._run(widget_states, timeout=timeout)
|
|
1930
1909
|
|
|
1931
|
-
def __repr__(self):
|
|
1910
|
+
def __repr__(self) -> str:
|
|
1932
1911
|
return format_dict(self.children)
|
|
1933
1912
|
|
|
1934
1913
|
|
|
@@ -1956,14 +1935,14 @@ def parse_tree_from_messages(messages: list[ForwardMsg]) -> ElementTree:
|
|
|
1956
1935
|
ty = elt.WhichOneof("type")
|
|
1957
1936
|
new_node: Node
|
|
1958
1937
|
if ty == "alert":
|
|
1959
|
-
|
|
1960
|
-
if
|
|
1938
|
+
alert_format = elt.alert.format
|
|
1939
|
+
if alert_format == AlertProto.Format.ERROR:
|
|
1961
1940
|
new_node = Error(elt.alert, root=root)
|
|
1962
|
-
elif
|
|
1941
|
+
elif alert_format == AlertProto.Format.INFO:
|
|
1963
1942
|
new_node = Info(elt.alert, root=root)
|
|
1964
|
-
elif
|
|
1943
|
+
elif alert_format == AlertProto.Format.SUCCESS:
|
|
1965
1944
|
new_node = Success(elt.alert, root=root)
|
|
1966
|
-
elif
|
|
1945
|
+
elif alert_format == AlertProto.Format.WARNING:
|
|
1967
1946
|
new_node = Warning(elt.alert, root=root)
|
|
1968
1947
|
else:
|
|
1969
1948
|
raise ValueError(
|