streamlit 1.45.0__py3-none-any.whl → 1.46.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- streamlit/__init__.py +5 -1
- streamlit/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/file_uploader_utils.py +7 -2
- 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 +55 -34
- 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.DyIfDYvY.js → ErrorOutline.esm.6PVAQvlT.js} +1 -1
- streamlit/static/static/js/{FileDownload.esm.kF1FCxeJ.js → FileDownload.esm.BZQHC61b.js} +1 -1
- streamlit/static/static/js/{FileHelper.DKt6tIeO.js → FileHelper.Bn1VShMJ.js} +5 -5
- streamlit/static/static/js/{FormClearHelper.DpJR9YCu.js → FormClearHelper.CsFEiTNN.js} +1 -1
- streamlit/static/static/js/{Hooks.BT6PF2Zi.js → Hooks.DguOHQL1.js} +1 -1
- streamlit/static/static/js/{InputInstructions.BmnD4oa3.js → InputInstructions.CTYn2BJQ.js} +1 -1
- streamlit/static/static/js/{ProgressBar.Ch7VNdkM.js → ProgressBar.CPOGBKCi.js} +2 -2
- streamlit/static/static/js/{RenderInPortalIfExists.43tDswzK.js → RenderInPortalIfExists.BYu_CZaF.js} +1 -1
- streamlit/static/static/js/Toolbar.gXKw7ANv.js +1 -0
- streamlit/static/static/js/UploadFileInfo.0DCkpDDf.js +6 -0
- streamlit/static/static/js/{base-input.BjeC3XFX.js → base-input.DBYPj91R.js} +4 -4
- streamlit/static/static/js/{checkbox.DIVN0GOS.js → checkbox.BUm2vnNv.js} +2 -2
- streamlit/static/static/js/{createSuper.CKyBiJe0.js → createSuper.KD4RuZ-W.js} +1 -1
- streamlit/static/static/js/{data-grid-overlay-editor.CXpaXRk5.js → data-grid-overlay-editor.CUwpDfvI.js} +1 -1
- streamlit/static/static/js/{downloader.B-uWAyLB.js → downloader.CkDtclup.js} +1 -1
- streamlit/static/static/js/{es6._eGNfJ2i.js → es6.Dlcvh_r0.js} +2 -2
- streamlit/static/static/js/{iframeResizer.contentWindow.CebQfV1Q.js → iframeResizer.contentWindow.DOXlFfve.js} +1 -1
- streamlit/static/static/js/{index.EbMzSayc.js → index.B0cuGMAB.js} +25 -25
- streamlit/static/static/js/index.BCWTclSV.js +73 -0
- streamlit/static/static/js/index.BJY_fap7.js +1 -0
- streamlit/static/static/js/index.BL3l6dnk.js +1 -0
- streamlit/static/static/js/{index.CpV1hnf8.js → index.BMZzRZjB.js} +1 -1
- streamlit/static/static/js/{index.l6QfBDTC.js → index.BOzUTGDe.js} +1 -1
- streamlit/static/static/js/index.BYI5iO-o.js +1 -0
- streamlit/static/static/js/index.BYo0ywlm.js +783 -0
- streamlit/static/static/js/{index.CuUJHsRK.js → index.BYz9btsY.js} +1 -1
- streamlit/static/static/js/{index.C_nMqHLH.js → index.CCVzQz0Z.js} +2 -2
- streamlit/static/static/js/index.CD6FydK9.js +1 -0
- streamlit/static/static/js/index.CDYEqgC8.js +2 -0
- streamlit/static/static/js/{index.BAdBHmJD.js → index.CMP9c4xA.js} +1 -1
- streamlit/static/static/js/index.CN30QAPD.js +1 -0
- streamlit/static/static/js/{index.CtTgot1Z.js → index.CNqWQkTe.js} +1 -1
- streamlit/static/static/js/index.CaxS67Xz.js +1 -0
- streamlit/static/static/js/{index.HsXxdgGd.js → index.CbsT4sGW.js} +1 -1
- streamlit/static/static/js/index.ChAVlxpQ.js +1 -0
- streamlit/static/static/js/{index.BaYSBSaz.js → index.ClLMMmDd.js} +1 -1
- streamlit/static/static/js/{index.CxxktCLw.js → index.D-O9rQmV.js} +1 -1
- streamlit/static/static/js/{index.Coc8OVG7.js → index.D4k7VZZL.js} +1 -1
- streamlit/static/static/js/index.DLBi0Ar1.js +1 -0
- streamlit/static/static/js/index.DVq5XmJo.js +197 -0
- streamlit/static/static/js/{index.ClX0ambk.js → index.DZKmKXWw.js} +1 -1
- streamlit/static/static/js/index.DkaVx80F.js +1 -0
- streamlit/static/static/js/index.Dr968Klx.js +1 -0
- streamlit/static/static/js/{index.BaozEIL-.js → index.DtUYLn9j.js} +20 -20
- streamlit/static/static/js/index.DwjYSyhs.js +1 -0
- streamlit/static/static/js/index.DzrImxu4.js +1 -0
- streamlit/static/static/js/index.HyGsn4VM.js +1 -0
- streamlit/static/static/js/index.OwxC65od.js +12 -0
- streamlit/static/static/js/index.PZs7VZkC.js +1 -0
- streamlit/static/static/js/index.Voiqpj4q.js +1 -0
- streamlit/static/static/js/index.bSROvR-J.js +3 -0
- streamlit/static/static/js/index.oT9GD3l4.js +1 -0
- streamlit/static/static/js/{index.schmj9D9.js → index.qb-yAPH6.js} +255 -255
- streamlit/static/static/js/index.rJFy_Ygy.js +2 -0
- streamlit/static/static/js/{input.VQEe_bZy.js → input.CwQtEnFN.js} +2 -2
- streamlit/static/static/js/{memory.DGVHab07.js → memory.C5XaFIjR.js} +1 -1
- streamlit/static/static/js/{mergeWith.-RIuUGoA.js → mergeWith.DzwwH6AG.js} +1 -1
- streamlit/static/static/js/{number-overlay-editor.wzFLIbEE.js → number-overlay-editor.Dx0XqCkD.js} +1 -1
- streamlit/static/static/js/{possibleConstructorReturn.GIObu6rf.js → possibleConstructorReturn.CVfSu9Ws.js} +1 -1
- streamlit/static/static/js/{sandbox.DpjSeqe2.js → sandbox.BT0gdMXk.js} +1 -1
- streamlit/static/static/js/{textarea.Dz0J9LZe.js → textarea.DNCbrtbM.js} +2 -2
- streamlit/static/static/js/{timepicker.BLgJZnzX.js → timepicker.4UYJD9Ts.js} +1 -1
- streamlit/static/static/js/{toConsumableArray.0OZlxz7U.js → toConsumableArray.DUmnaVWV.js} +1 -1
- streamlit/static/static/js/{uniqueId.DbzplC8D.js → uniqueId.DUvh-GL8.js} +1 -1
- streamlit/static/static/js/{useBasicWidgetState.COJZng1S.js → useBasicWidgetState.Cwd7-jJa.js} +1 -1
- streamlit/static/static/js/useOnInputChange.DvemQrOM.js +1 -0
- streamlit/static/static/js/{withFullScreenWrapper.CzWvNbvi.js → withFullScreenWrapper.CiQ10ByU.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 +15 -1
- 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 +6 -18
- streamlit/web/server/server_util.py +19 -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.0.dist-info → streamlit-1.46.0.dist-info}/METADATA +4 -4
- streamlit-1.46.0.dist-info/RECORD +559 -0
- {streamlit-1.45.0.dist-info → streamlit-1.46.0.dist-info}/WHEEL +1 -1
- streamlit/elements/lib/event_utils.py +0 -39
- streamlit/static/static/js/Toolbar.HTGsjfCP.js +0 -1
- streamlit/static/static/js/UploadFileInfo.C-jY39rj.js +0 -1
- streamlit/static/static/js/index.B5TWFN5r.js +0 -1
- streamlit/static/static/js/index.BI9-p_-s.js +0 -3
- streamlit/static/static/js/index.BYHnDZYn.js +0 -1
- streamlit/static/static/js/index.B_M97aPz.js +0 -1
- streamlit/static/static/js/index.BdN5swP0.js +0 -1
- streamlit/static/static/js/index.BfCAp_Sj.js +0 -1
- streamlit/static/static/js/index.BqDl3eRM.js +0 -779
- streamlit/static/static/js/index.C0VtYb3T.js +0 -2
- streamlit/static/static/js/index.C1qW_Owy.js +0 -1
- streamlit/static/static/js/index.C4AcBARa.js +0 -1
- streamlit/static/static/js/index.CCOiJRk1.js +0 -1
- streamlit/static/static/js/index.COvpza5W.js +0 -1
- streamlit/static/static/js/index.C_9qGjbK.js +0 -2
- streamlit/static/static/js/index.CqISBfsc.js +0 -197
- streamlit/static/static/js/index.D1WOs2Ce.js +0 -1
- streamlit/static/static/js/index.DQljs-9e.js +0 -1
- streamlit/static/static/js/index.DZqX4P_2.js +0 -1
- streamlit/static/static/js/index.DajIfBOb.js +0 -1
- streamlit/static/static/js/index.DuOXre0H.js +0 -1
- streamlit/static/static/js/index.EWD98YhP.js +0 -1
- streamlit/static/static/js/index.LaZloCTl.js +0 -73
- streamlit/static/static/js/index.S_1klBoy.js +0 -1
- streamlit/static/static/js/index.b0Gf958T.js +0 -12
- streamlit/static/static/js/index.t--hEgTQ.js +0 -6
- streamlit/static/static/js/useOnInputChange.CgOwAHyw.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.0.dist-info/RECORD +0 -568
- {streamlit-1.45.0.data → streamlit-1.46.0.data}/scripts/streamlit.cmd +0 -0
- {streamlit-1.45.0.dist-info → streamlit-1.46.0.dist-info}/entry_points.txt +0 -0
- {streamlit-1.45.0.dist-info → streamlit-1.46.0.dist-info}/top_level.txt +0 -0
streamlit/config.py
CHANGED
|
@@ -54,6 +54,9 @@ _config_options_template: dict[str, ConfigOption] = OrderedDict()
|
|
|
54
54
|
# Stores the current state of config options.
|
|
55
55
|
_config_options: dict[str, ConfigOption] | None = None
|
|
56
56
|
|
|
57
|
+
# Stores the path to the main script. This is used to
|
|
58
|
+
# resolve config and secret files relative to the main script:
|
|
59
|
+
_main_script_path: str | None = None
|
|
57
60
|
|
|
58
61
|
# Indicates that a config option was defined by the user.
|
|
59
62
|
_USER_DEFINED: Final = "<user defined>"
|
|
@@ -77,11 +80,11 @@ class ShowErrorDetailsConfigOptions(str, Enum):
|
|
|
77
80
|
NONE = "none"
|
|
78
81
|
|
|
79
82
|
@staticmethod
|
|
80
|
-
def is_true_variation(val: str | bool):
|
|
83
|
+
def is_true_variation(val: str | bool) -> bool:
|
|
81
84
|
return val in ["true", "True", True]
|
|
82
85
|
|
|
83
86
|
@staticmethod
|
|
84
|
-
def is_false_variation(val: str | bool):
|
|
87
|
+
def is_false_variation(val: str | bool) -> bool:
|
|
85
88
|
return val in ["false", "False", False]
|
|
86
89
|
|
|
87
90
|
# Config options can be set from several places including the command-line and
|
|
@@ -167,7 +170,7 @@ def set_user_option(key: str, value: Any) -> None:
|
|
|
167
170
|
|
|
168
171
|
raise StreamlitAPIException(
|
|
169
172
|
f"{key} cannot be set on the fly. Set as command line option, e.g. "
|
|
170
|
-
"streamlit run script.py --{key}, or in config.toml instead."
|
|
173
|
+
f"streamlit run script.py --{key}, or in config.toml instead."
|
|
171
174
|
)
|
|
172
175
|
|
|
173
176
|
|
|
@@ -226,9 +229,8 @@ def get_options_for_section(section: str) -> dict[str, Any]:
|
|
|
226
229
|
|
|
227
230
|
def _create_section(section: str, description: str) -> None:
|
|
228
231
|
"""Create a config section and store it globally in this module."""
|
|
229
|
-
|
|
230
|
-
f'Cannot define section "{section}" twice.'
|
|
231
|
-
)
|
|
232
|
+
if section in _section_descriptions:
|
|
233
|
+
raise RuntimeError(f'Cannot define section "{section}" twice.')
|
|
232
234
|
_section_descriptions[section] = description
|
|
233
235
|
|
|
234
236
|
|
|
@@ -244,6 +246,7 @@ def _create_option(
|
|
|
244
246
|
replaced_by: str | None = None,
|
|
245
247
|
type_: type = str,
|
|
246
248
|
sensitive: bool = False,
|
|
249
|
+
multiple: bool = False,
|
|
247
250
|
) -> ConfigOption:
|
|
248
251
|
'''Create a ConfigOption and store it globally in this module.
|
|
249
252
|
|
|
@@ -292,14 +295,14 @@ def _create_option(
|
|
|
292
295
|
replaced_by=replaced_by,
|
|
293
296
|
type_=type_,
|
|
294
297
|
sensitive=sensitive,
|
|
298
|
+
multiple=multiple,
|
|
295
299
|
)
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
option.section,
|
|
299
|
-
", ".join(_section_descriptions.keys()),
|
|
300
|
+
if option.section not in _section_descriptions:
|
|
301
|
+
raise RuntimeError(
|
|
302
|
+
f'Section "{option.section}" must be one of {", ".join(_section_descriptions.keys())}.'
|
|
300
303
|
)
|
|
301
|
-
|
|
302
|
-
|
|
304
|
+
if key in _config_options_template:
|
|
305
|
+
raise RuntimeError(f'Cannot define option "{key}" twice.')
|
|
303
306
|
_config_options_template[key] = option
|
|
304
307
|
return option
|
|
305
308
|
|
|
@@ -342,13 +345,15 @@ def _delete_option(key: str) -> None:
|
|
|
342
345
|
|
|
343
346
|
Only for use in testing.
|
|
344
347
|
"""
|
|
348
|
+
if _config_options is None:
|
|
349
|
+
raise RuntimeError(
|
|
350
|
+
"_config_options should always be populated here. This should never happen."
|
|
351
|
+
)
|
|
352
|
+
|
|
345
353
|
try:
|
|
346
354
|
del _config_options_template[key]
|
|
347
|
-
assert _config_options is not None, (
|
|
348
|
-
"_config_options should always be populated here."
|
|
349
|
-
)
|
|
350
355
|
del _config_options[key]
|
|
351
|
-
except Exception:
|
|
356
|
+
except Exception: # noqa: S110
|
|
352
357
|
# We don't care if the option already doesn't exist.
|
|
353
358
|
pass
|
|
354
359
|
|
|
@@ -384,6 +389,7 @@ _create_option(
|
|
|
384
389
|
|
|
385
390
|
|
|
386
391
|
@_create_option("global.developmentMode", visibility="hidden", type_=bool)
|
|
392
|
+
@util.memoize
|
|
387
393
|
def _global_development_mode() -> bool:
|
|
388
394
|
"""Are we in development mode.
|
|
389
395
|
|
|
@@ -466,8 +472,7 @@ def _logger_log_level() -> str:
|
|
|
466
472
|
"""
|
|
467
473
|
if get_option("global.developmentMode"):
|
|
468
474
|
return "debug"
|
|
469
|
-
|
|
470
|
-
return "info"
|
|
475
|
+
return "info"
|
|
471
476
|
|
|
472
477
|
|
|
473
478
|
@_create_option("logger.messageFormat", type_=str)
|
|
@@ -484,8 +489,7 @@ def _logger_message_format() -> str:
|
|
|
484
489
|
from streamlit.logger import DEFAULT_LOG_MESSAGE
|
|
485
490
|
|
|
486
491
|
return DEFAULT_LOG_MESSAGE
|
|
487
|
-
|
|
488
|
-
return "%(asctime)s %(message)s"
|
|
492
|
+
return "%(asctime)s %(message)s"
|
|
489
493
|
|
|
490
494
|
|
|
491
495
|
@_create_option(
|
|
@@ -494,6 +498,7 @@ def _logger_message_format() -> str:
|
|
|
494
498
|
type_=bool,
|
|
495
499
|
scriptable=True,
|
|
496
500
|
)
|
|
501
|
+
@util.memoize
|
|
497
502
|
def _logger_enable_rich() -> bool:
|
|
498
503
|
"""
|
|
499
504
|
Controls whether uncaught app exceptions are logged via the rich library.
|
|
@@ -605,8 +610,9 @@ _create_option(
|
|
|
605
610
|
_create_option(
|
|
606
611
|
"runner.postScriptGC",
|
|
607
612
|
description="""
|
|
608
|
-
Run the Python Garbage Collector after each script execution.
|
|
609
|
-
|
|
613
|
+
Run the Python Garbage Collector after each script execution.
|
|
614
|
+
|
|
615
|
+
This can help avoid excess memory use in Streamlit apps, but could
|
|
610
616
|
introduce delay in rerunning the app script for high-memory-use
|
|
611
617
|
applications.
|
|
612
618
|
""",
|
|
@@ -618,11 +624,12 @@ _create_option(
|
|
|
618
624
|
_create_option(
|
|
619
625
|
"runner.fastReruns",
|
|
620
626
|
description="""
|
|
621
|
-
Handle script rerun requests immediately, rather than waiting for
|
|
622
|
-
execution to reach a yield point.
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
|
|
627
|
+
Handle script rerun requests immediately, rather than waiting for
|
|
628
|
+
script execution to reach a yield point.
|
|
629
|
+
|
|
630
|
+
This makes Streamlit much more responsive to user interaction, but it
|
|
631
|
+
can lead to race conditions in apps that mutate session_state data
|
|
632
|
+
outside of explicit session_state assignment statements.
|
|
626
633
|
""",
|
|
627
634
|
default_val=True,
|
|
628
635
|
type_=bool,
|
|
@@ -632,6 +639,7 @@ _create_option(
|
|
|
632
639
|
"runner.enforceSerializableSessionState",
|
|
633
640
|
description="""
|
|
634
641
|
Raise an exception after adding unserializable data to Session State.
|
|
642
|
+
|
|
635
643
|
Some execution environments may require serializing all data in Session
|
|
636
644
|
State, so it may be useful to detect incompatibility during development,
|
|
637
645
|
or when the execution environment will stop supporting it in the future.
|
|
@@ -644,8 +652,10 @@ _create_option(
|
|
|
644
652
|
"runner.enumCoercion",
|
|
645
653
|
description="""
|
|
646
654
|
Adjust how certain 'options' widgets like radio, selectbox, and
|
|
647
|
-
multiselect coerce Enum members
|
|
648
|
-
|
|
655
|
+
multiselect coerce Enum members.
|
|
656
|
+
|
|
657
|
+
This is useful when the Enum class gets re-defined during a script
|
|
658
|
+
re-run. For more information, check out the docs:
|
|
649
659
|
https://docs.streamlit.io/develop/concepts/design/custom-classes#enums
|
|
650
660
|
|
|
651
661
|
Allowed values:
|
|
@@ -662,16 +672,34 @@ _create_option(
|
|
|
662
672
|
|
|
663
673
|
_create_section("server", "Settings for the Streamlit server")
|
|
664
674
|
|
|
675
|
+
|
|
676
|
+
_create_option(
|
|
677
|
+
"server.folderWatchList",
|
|
678
|
+
description="""
|
|
679
|
+
List of directories to watch for changes.
|
|
680
|
+
|
|
681
|
+
By default, Streamlit watches files in the current working directory
|
|
682
|
+
and its subdirectories. Use this option to specify additional
|
|
683
|
+
directories to watch. Paths must be absolute.
|
|
684
|
+
""",
|
|
685
|
+
default_val=[],
|
|
686
|
+
multiple=True,
|
|
687
|
+
)
|
|
688
|
+
|
|
665
689
|
_create_option(
|
|
666
690
|
"server.folderWatchBlacklist",
|
|
667
691
|
description="""
|
|
668
|
-
List of
|
|
692
|
+
List of directories to ignore for changes.
|
|
669
693
|
|
|
670
|
-
|
|
694
|
+
By default, Streamlit watches files in the current working directory
|
|
695
|
+
and its subdirectories. Use this option to specify exceptions within
|
|
696
|
+
watched directories. Paths can be absolute or relative to the current
|
|
697
|
+
working directory.
|
|
671
698
|
|
|
672
699
|
Example: ['/home/user1/env', 'relative/path/to/folder']
|
|
673
700
|
""",
|
|
674
701
|
default_val=[],
|
|
702
|
+
multiple=True,
|
|
675
703
|
)
|
|
676
704
|
|
|
677
705
|
_create_option(
|
|
@@ -711,15 +739,12 @@ def _server_headless() -> bool:
|
|
|
711
739
|
Default: false unless (1) we are on a Linux box where DISPLAY is unset, or
|
|
712
740
|
(2) we are running in the Streamlit Atom plugin.
|
|
713
741
|
"""
|
|
714
|
-
if
|
|
742
|
+
# Check if we are running in Linux and DISPLAY is unset
|
|
743
|
+
return (
|
|
715
744
|
env_util.IS_LINUX_OR_BSD
|
|
716
745
|
and not os.getenv("DISPLAY")
|
|
717
746
|
and not os.getenv("WAYLAND_DISPLAY")
|
|
718
|
-
)
|
|
719
|
-
# We're running in Linux and DISPLAY is unset
|
|
720
|
-
return True
|
|
721
|
-
|
|
722
|
-
return False
|
|
747
|
+
)
|
|
723
748
|
|
|
724
749
|
|
|
725
750
|
_create_option(
|
|
@@ -745,7 +770,9 @@ _create_option(
|
|
|
745
770
|
@_create_option("server.address")
|
|
746
771
|
def _server_address() -> str | None:
|
|
747
772
|
"""The address where the server will listen for client and browser
|
|
748
|
-
connections.
|
|
773
|
+
connections.
|
|
774
|
+
|
|
775
|
+
Use this if you want to bind the server to a specific address.
|
|
749
776
|
If set, the server will only be accessible from this address, and not from
|
|
750
777
|
any aliases (like localhost).
|
|
751
778
|
|
|
@@ -758,8 +785,6 @@ _create_option(
|
|
|
758
785
|
"server.port",
|
|
759
786
|
description="""
|
|
760
787
|
The port where the server will listen for browser connections.
|
|
761
|
-
|
|
762
|
-
Don't use port 3000 which is reserved for internal development.
|
|
763
788
|
""",
|
|
764
789
|
default_val=8501,
|
|
765
790
|
type_=int,
|
|
@@ -803,6 +828,22 @@ _create_option(
|
|
|
803
828
|
type_=bool,
|
|
804
829
|
)
|
|
805
830
|
|
|
831
|
+
_create_option(
|
|
832
|
+
"server.corsAllowedOrigins",
|
|
833
|
+
description="""
|
|
834
|
+
Allowed list of origins.
|
|
835
|
+
|
|
836
|
+
If CORS protection is enabled (`server.enableCORS=True`), use this
|
|
837
|
+
option to set a list of allowed origins that the Streamlit server will
|
|
838
|
+
accept traffic from.
|
|
839
|
+
|
|
840
|
+
This config option does nothing if CORS protection is disabled.
|
|
841
|
+
|
|
842
|
+
Example: ['http://example.com', 'https://streamlit.io']
|
|
843
|
+
""",
|
|
844
|
+
default_val=[],
|
|
845
|
+
multiple=True,
|
|
846
|
+
)
|
|
806
847
|
|
|
807
848
|
_create_option(
|
|
808
849
|
"server.enableXsrfProtection",
|
|
@@ -873,9 +914,11 @@ _create_option(
|
|
|
873
914
|
_create_option(
|
|
874
915
|
"server.disconnectedSessionTTL",
|
|
875
916
|
description="""
|
|
876
|
-
TTL in seconds for sessions whose websockets have been disconnected.
|
|
877
|
-
|
|
878
|
-
|
|
917
|
+
TTL in seconds for sessions whose websockets have been disconnected.
|
|
918
|
+
|
|
919
|
+
The server may choose to clean up session state, uploaded files, etc
|
|
920
|
+
for a given session with no active websocket connection at any point
|
|
921
|
+
after this time has passed.
|
|
879
922
|
""",
|
|
880
923
|
default_val=120,
|
|
881
924
|
type_=int,
|
|
@@ -923,8 +966,7 @@ def _browser_server_port() -> int:
|
|
|
923
966
|
- Open the browser automatically (part of `streamlit run`).
|
|
924
967
|
|
|
925
968
|
This option is for advanced use cases. To change the port of your app, use
|
|
926
|
-
`server.Port` instead.
|
|
927
|
-
development.
|
|
969
|
+
`server.Port` instead.
|
|
928
970
|
|
|
929
971
|
Default: whatever value is set in server.port.
|
|
930
972
|
"""
|
|
@@ -985,13 +1027,18 @@ _create_section("mapbox", "Mapbox configuration that is being used by DeckGL.")
|
|
|
985
1027
|
_create_option(
|
|
986
1028
|
"mapbox.token",
|
|
987
1029
|
description="""
|
|
988
|
-
|
|
989
|
-
|
|
990
|
-
To get a token for yourself, create an account at
|
|
991
|
-
https://mapbox.com. It's free (for moderate usage levels)!
|
|
1030
|
+
If you'd like to show maps using Mapbox rather than Carto, use this
|
|
1031
|
+
to pass the Mapbox API token.
|
|
992
1032
|
""",
|
|
993
1033
|
default_val="",
|
|
1034
|
+
type_=str,
|
|
994
1035
|
sensitive=True,
|
|
1036
|
+
deprecated=True,
|
|
1037
|
+
deprecation_text="""
|
|
1038
|
+
Instead of this, you should use either the MAPBOX_API_KEY environment
|
|
1039
|
+
variable or PyDeck's `api_keys` argument.
|
|
1040
|
+
""",
|
|
1041
|
+
expiration_date="2026-05-01",
|
|
995
1042
|
)
|
|
996
1043
|
|
|
997
1044
|
|
|
@@ -1041,6 +1088,7 @@ _create_theme_options(
|
|
|
1041
1088
|
categories=["theme"],
|
|
1042
1089
|
description="""
|
|
1043
1090
|
The preset Streamlit theme that your custom theme inherits from.
|
|
1091
|
+
|
|
1044
1092
|
This can be one of the following: "light" or "dark".
|
|
1045
1093
|
""",
|
|
1046
1094
|
)
|
|
@@ -1097,16 +1145,19 @@ _create_theme_options(
|
|
|
1097
1145
|
"font",
|
|
1098
1146
|
categories=["theme", CustomThemeCategories.SIDEBAR],
|
|
1099
1147
|
description="""
|
|
1100
|
-
The font family for all text, except code blocks.
|
|
1101
|
-
|
|
1148
|
+
The font family for all text, except code blocks.
|
|
1149
|
+
|
|
1150
|
+
This can be one of the following:
|
|
1102
1151
|
- "sans-serif"
|
|
1103
1152
|
- "serif"
|
|
1104
1153
|
- "monospace"
|
|
1105
|
-
-
|
|
1106
|
-
-
|
|
1154
|
+
- The `family` value for a custom font table under [[theme.fontFaces]]
|
|
1155
|
+
- A comma-separated list of these (as a single string) to specify
|
|
1107
1156
|
fallbacks
|
|
1157
|
+
|
|
1108
1158
|
For example, you can use the following:
|
|
1109
|
-
|
|
1159
|
+
|
|
1160
|
+
font = "cool-font, fallback-cool-font, sans-serif"
|
|
1110
1161
|
""",
|
|
1111
1162
|
)
|
|
1112
1163
|
|
|
@@ -1114,28 +1165,45 @@ _create_theme_options(
|
|
|
1114
1165
|
"codeFont",
|
|
1115
1166
|
categories=["theme", CustomThemeCategories.SIDEBAR],
|
|
1116
1167
|
description="""
|
|
1117
|
-
The font family to use for code (monospace) in the sidebar.
|
|
1118
|
-
|
|
1168
|
+
The font family to use for code (monospace) in the sidebar.
|
|
1169
|
+
|
|
1170
|
+
This can be one of the following:
|
|
1119
1171
|
- "sans-serif"
|
|
1120
1172
|
- "serif"
|
|
1121
1173
|
- "monospace"
|
|
1122
|
-
-
|
|
1123
|
-
-
|
|
1174
|
+
- The `family` value for a custom font table under [[theme.fontFaces]]
|
|
1175
|
+
- A comma-separated list of these (as a single string) to specify
|
|
1124
1176
|
fallbacks
|
|
1125
1177
|
""",
|
|
1126
1178
|
)
|
|
1127
1179
|
|
|
1180
|
+
_create_theme_options(
|
|
1181
|
+
"codeFontSize",
|
|
1182
|
+
categories=["theme", CustomThemeCategories.SIDEBAR],
|
|
1183
|
+
description="""
|
|
1184
|
+
Sets the font size (in pixels or rem) for code blocks and code text.
|
|
1185
|
+
|
|
1186
|
+
This applies to code blocks (ex: `st.code`), as well as font in `st.json` and `st.help`.
|
|
1187
|
+
It does not apply to inline code, which is set by default to 0.75em.
|
|
1188
|
+
|
|
1189
|
+
When unset, the code font size will be 0.875rem.
|
|
1190
|
+
""",
|
|
1191
|
+
)
|
|
1192
|
+
|
|
1128
1193
|
_create_theme_options(
|
|
1129
1194
|
"headingFont",
|
|
1130
1195
|
categories=["theme", CustomThemeCategories.SIDEBAR],
|
|
1131
1196
|
description="""
|
|
1132
|
-
The font family to use for headings.
|
|
1197
|
+
The font family to use for headings.
|
|
1198
|
+
|
|
1199
|
+
This can be one of the following:
|
|
1133
1200
|
- "sans-serif"
|
|
1134
1201
|
- "serif"
|
|
1135
1202
|
- "monospace"
|
|
1136
|
-
-
|
|
1137
|
-
-
|
|
1203
|
+
- The `family` value for a custom font table under [[theme.fontFaces]]
|
|
1204
|
+
- A comma-separated list of these (as a single string) to specify
|
|
1138
1205
|
fallbacks
|
|
1206
|
+
|
|
1139
1207
|
If no heading font is set, Streamlit uses `theme.font` for headings.
|
|
1140
1208
|
""",
|
|
1141
1209
|
)
|
|
@@ -1144,19 +1212,30 @@ _create_theme_options(
|
|
|
1144
1212
|
"fontFaces",
|
|
1145
1213
|
categories=["theme"],
|
|
1146
1214
|
description="""
|
|
1147
|
-
An array of fonts to use in your app.
|
|
1148
|
-
|
|
1149
|
-
|
|
1150
|
-
|
|
1151
|
-
|
|
1152
|
-
|
|
1153
|
-
|
|
1154
|
-
|
|
1155
|
-
|
|
1156
|
-
|
|
1157
|
-
|
|
1158
|
-
|
|
1159
|
-
|
|
1215
|
+
An array of fonts to use in your app.
|
|
1216
|
+
|
|
1217
|
+
Each font in the array is a table (dictionary) that can have the
|
|
1218
|
+
following attributes, closely resembling CSS font-face definitions:
|
|
1219
|
+
- family
|
|
1220
|
+
- url
|
|
1221
|
+
- weight (optional)
|
|
1222
|
+
- style (optional)
|
|
1223
|
+
- unicodeRange (optional)
|
|
1224
|
+
|
|
1225
|
+
To host a font with your app, enable static file serving with
|
|
1226
|
+
`server.enableStaticServing=true`.
|
|
1227
|
+
|
|
1228
|
+
You can define multiple [[theme.fontFaces]] tables, including multiple
|
|
1229
|
+
tables with the same family if your font is defined by multiple files.
|
|
1230
|
+
|
|
1231
|
+
For example, a font hosted with your app may have a [[theme.fontFaces]]
|
|
1232
|
+
table as follows:
|
|
1233
|
+
|
|
1234
|
+
[[theme.fontFaces]]
|
|
1235
|
+
family = "font_name"
|
|
1236
|
+
url = "app/static/font_file.woff"
|
|
1237
|
+
weight = "400"
|
|
1238
|
+
style = "normal"
|
|
1160
1239
|
""",
|
|
1161
1240
|
)
|
|
1162
1241
|
|
|
@@ -1164,11 +1243,39 @@ _create_theme_options(
|
|
|
1164
1243
|
"baseRadius",
|
|
1165
1244
|
categories=["theme", CustomThemeCategories.SIDEBAR],
|
|
1166
1245
|
description="""
|
|
1167
|
-
The radius used as basis for the corners of most UI elements.
|
|
1168
|
-
|
|
1169
|
-
|
|
1170
|
-
|
|
1171
|
-
|
|
1246
|
+
The radius used as basis for the corners of most UI elements.
|
|
1247
|
+
|
|
1248
|
+
This can be one of the following:
|
|
1249
|
+
- "none"
|
|
1250
|
+
- "small"
|
|
1251
|
+
- "medium"
|
|
1252
|
+
- "large"
|
|
1253
|
+
- "full"
|
|
1254
|
+
- The number in pixels or rem.
|
|
1255
|
+
|
|
1256
|
+
For example, you can use "10px", "0.5rem", or "2rem". To follow best
|
|
1257
|
+
practices, use rem instead of pixels when specifying a numeric size.
|
|
1258
|
+
""",
|
|
1259
|
+
)
|
|
1260
|
+
|
|
1261
|
+
_create_theme_options(
|
|
1262
|
+
"buttonRadius",
|
|
1263
|
+
categories=["theme", CustomThemeCategories.SIDEBAR],
|
|
1264
|
+
description="""
|
|
1265
|
+
The radius used as basis for the corners of buttons.
|
|
1266
|
+
|
|
1267
|
+
This can be one of the following:
|
|
1268
|
+
- "none"
|
|
1269
|
+
- "small"
|
|
1270
|
+
- "medium"
|
|
1271
|
+
- "large"
|
|
1272
|
+
- "full"
|
|
1273
|
+
- The number in pixels or rem.
|
|
1274
|
+
|
|
1275
|
+
For example, you can use "10px", "0.5rem", or "2rem". To follow best
|
|
1276
|
+
practices, use rem instead of pixels when specifying a numeric size.
|
|
1277
|
+
|
|
1278
|
+
If no button radius is set, Streamlit uses `theme.baseRadius` instead.
|
|
1172
1279
|
""",
|
|
1173
1280
|
)
|
|
1174
1281
|
|
|
@@ -1180,6 +1287,17 @@ _create_theme_options(
|
|
|
1180
1287
|
""",
|
|
1181
1288
|
)
|
|
1182
1289
|
|
|
1290
|
+
_create_theme_options(
|
|
1291
|
+
"dataframeBorderColor",
|
|
1292
|
+
categories=["theme", CustomThemeCategories.SIDEBAR],
|
|
1293
|
+
description="""
|
|
1294
|
+
The color of the border around dataframes and tables.
|
|
1295
|
+
|
|
1296
|
+
If no dataframe border color is set, Streamlit uses `theme.borderColor`
|
|
1297
|
+
instead.
|
|
1298
|
+
""",
|
|
1299
|
+
)
|
|
1300
|
+
|
|
1183
1301
|
_create_theme_options(
|
|
1184
1302
|
"showWidgetBorder",
|
|
1185
1303
|
categories=["theme", CustomThemeCategories.SIDEBAR],
|
|
@@ -1193,8 +1311,11 @@ _create_theme_options(
|
|
|
1193
1311
|
"baseFontSize",
|
|
1194
1312
|
categories=["theme"],
|
|
1195
1313
|
description="""
|
|
1196
|
-
Sets the root font size (in pixels) for the app
|
|
1197
|
-
|
|
1314
|
+
Sets the root font size (in pixels) for the app.
|
|
1315
|
+
|
|
1316
|
+
This determines the overall scale of text and UI elements.
|
|
1317
|
+
|
|
1318
|
+
When unset, the font size will be 16px.
|
|
1198
1319
|
""",
|
|
1199
1320
|
type_=int,
|
|
1200
1321
|
)
|
|
@@ -1213,21 +1334,17 @@ _create_theme_options(
|
|
|
1213
1334
|
|
|
1214
1335
|
_create_section("secrets", "Secrets configuration.")
|
|
1215
1336
|
|
|
1216
|
-
|
|
1217
|
-
|
|
1218
|
-
|
|
1219
|
-
|
|
1220
|
-
|
|
1221
|
-
|
|
1222
|
-
|
|
1223
|
-
|
|
1224
|
-
|
|
1225
|
-
|
|
1226
|
-
|
|
1227
|
-
file_util.get_streamlit_file_path("secrets.toml"),
|
|
1228
|
-
file_util.get_project_streamlit_file_path("secrets.toml"),
|
|
1229
|
-
],
|
|
1230
|
-
)
|
|
1337
|
+
|
|
1338
|
+
@_create_option("secrets.files", multiple=True)
|
|
1339
|
+
def _secrets_files() -> list[str]:
|
|
1340
|
+
"""List of locations where secrets are searched.
|
|
1341
|
+
|
|
1342
|
+
An entry can be a path to a TOML file or directory path where
|
|
1343
|
+
Kubernetes style secrets are saved. Order is important, import is
|
|
1344
|
+
first to last, so secrets in later files will take precedence over
|
|
1345
|
+
earlier ones.
|
|
1346
|
+
"""
|
|
1347
|
+
return get_config_files("secrets.toml")
|
|
1231
1348
|
|
|
1232
1349
|
|
|
1233
1350
|
def get_where_defined(key: str) -> str:
|
|
@@ -1243,7 +1360,8 @@ def get_where_defined(key: str) -> str:
|
|
|
1243
1360
|
config_options = get_config_options()
|
|
1244
1361
|
|
|
1245
1362
|
if key not in config_options:
|
|
1246
|
-
|
|
1363
|
+
msg = f'Config key "{key}" not defined.'
|
|
1364
|
+
raise RuntimeError(msg)
|
|
1247
1365
|
return config_options[key].where_defined
|
|
1248
1366
|
|
|
1249
1367
|
|
|
@@ -1289,9 +1407,10 @@ def is_manually_set(option_name: str) -> bool:
|
|
|
1289
1407
|
def show_config() -> None:
|
|
1290
1408
|
"""Print all config options to the terminal."""
|
|
1291
1409
|
with _config_lock:
|
|
1292
|
-
|
|
1293
|
-
|
|
1294
|
-
|
|
1410
|
+
if _config_options is None:
|
|
1411
|
+
raise RuntimeError(
|
|
1412
|
+
"_config_options should always be populated here. This should never happen."
|
|
1413
|
+
)
|
|
1295
1414
|
config_util.show_config(_section_descriptions, _config_options)
|
|
1296
1415
|
|
|
1297
1416
|
|
|
@@ -1314,25 +1433,28 @@ def _set_option(key: str, value: Any, where_defined: str) -> None:
|
|
|
1314
1433
|
Tells the config system where this was set.
|
|
1315
1434
|
|
|
1316
1435
|
"""
|
|
1317
|
-
|
|
1318
|
-
"_config_options should always be populated here."
|
|
1319
|
-
|
|
1436
|
+
if _config_options is None:
|
|
1437
|
+
raise RuntimeError("_config_options should always be populated here.")
|
|
1438
|
+
|
|
1320
1439
|
if key not in _config_options:
|
|
1321
1440
|
# Import logger locally to prevent circular references
|
|
1322
1441
|
from streamlit.logger import get_logger
|
|
1323
1442
|
|
|
1324
|
-
|
|
1443
|
+
logger: Final = get_logger(__name__)
|
|
1325
1444
|
|
|
1326
|
-
|
|
1327
|
-
|
|
1328
|
-
"option set, it may have been removed."
|
|
1445
|
+
logger.warning(
|
|
1446
|
+
'"%s" is not a valid config option. If you previously had this config '
|
|
1447
|
+
"option set, it may have been removed.",
|
|
1448
|
+
key,
|
|
1329
1449
|
)
|
|
1330
1450
|
|
|
1331
1451
|
else:
|
|
1332
1452
|
_config_options[key].set_value(value, where_defined)
|
|
1333
1453
|
|
|
1334
1454
|
|
|
1335
|
-
def _update_config_with_sensitive_env_var(
|
|
1455
|
+
def _update_config_with_sensitive_env_var(
|
|
1456
|
+
config_options: dict[str, ConfigOption],
|
|
1457
|
+
) -> None:
|
|
1336
1458
|
"""Update the config system by parsing the environment variable.
|
|
1337
1459
|
|
|
1338
1460
|
This should only be called from get_config_options.
|
|
@@ -1444,9 +1566,9 @@ def _maybe_read_env_variable(value: Any) -> Any:
|
|
|
1444
1566
|
# Import logger locally to prevent circular references
|
|
1445
1567
|
from streamlit.logger import get_logger
|
|
1446
1568
|
|
|
1447
|
-
|
|
1569
|
+
logger: Final = get_logger(__name__)
|
|
1448
1570
|
|
|
1449
|
-
|
|
1571
|
+
logger.error("No environment variable called %s", var_name)
|
|
1450
1572
|
else:
|
|
1451
1573
|
return _maybe_convert_to_number(env_var)
|
|
1452
1574
|
|
|
@@ -1457,12 +1579,12 @@ def _maybe_convert_to_number(v: Any) -> Any:
|
|
|
1457
1579
|
"""Convert v to int or float, or leave it as is."""
|
|
1458
1580
|
try:
|
|
1459
1581
|
return int(v)
|
|
1460
|
-
except Exception:
|
|
1582
|
+
except Exception: # noqa: S110
|
|
1461
1583
|
pass
|
|
1462
1584
|
|
|
1463
1585
|
try:
|
|
1464
1586
|
return float(v)
|
|
1465
|
-
except Exception:
|
|
1587
|
+
except Exception: # noqa: S110
|
|
1466
1588
|
pass
|
|
1467
1589
|
|
|
1468
1590
|
return v
|
|
@@ -1472,14 +1594,34 @@ def _maybe_convert_to_number(v: Any) -> Any:
|
|
|
1472
1594
|
# something.
|
|
1473
1595
|
_on_config_parsed = Signal(doc="Emitted when the config file is parsed.")
|
|
1474
1596
|
|
|
1475
|
-
|
|
1476
|
-
|
|
1477
|
-
|
|
1478
|
-
|
|
1597
|
+
|
|
1598
|
+
def get_config_files(file_name: str) -> list[str]:
|
|
1599
|
+
"""Return the list of config files (e.g. config.toml or secrets.toml) to be parsed.
|
|
1600
|
+
|
|
1601
|
+
Order is important, import is first to last, so options in later files
|
|
1602
|
+
will take precedence over earlier ones.
|
|
1603
|
+
"""
|
|
1604
|
+
# script-level config files overwrite project-level config
|
|
1605
|
+
# files, which in turn overwrite global config files.
|
|
1606
|
+
config_files = [
|
|
1607
|
+
file_util.get_streamlit_file_path(file_name),
|
|
1608
|
+
file_util.get_project_streamlit_file_path(file_name),
|
|
1609
|
+
]
|
|
1610
|
+
|
|
1611
|
+
if _main_script_path is not None:
|
|
1612
|
+
script_level_config = file_util.get_main_script_streamlit_file_path(
|
|
1613
|
+
_main_script_path, file_name
|
|
1614
|
+
)
|
|
1615
|
+
if script_level_config not in config_files:
|
|
1616
|
+
# We need to append the script-level config file to the list
|
|
1617
|
+
# so that it overwrites project & global level config files:
|
|
1618
|
+
config_files.append(script_level_config)
|
|
1619
|
+
|
|
1620
|
+
return config_files
|
|
1479
1621
|
|
|
1480
1622
|
|
|
1481
1623
|
def get_config_options(
|
|
1482
|
-
force_reparse=False, options_from_flags: dict[str, Any] | None = None
|
|
1624
|
+
force_reparse: bool = False, options_from_flags: dict[str, Any] | None = None
|
|
1483
1625
|
) -> dict[str, ConfigOption]:
|
|
1484
1626
|
"""Create and return a dict mapping config option names to their values,
|
|
1485
1627
|
returning a cached dict if possible.
|
|
@@ -1526,12 +1668,12 @@ def get_config_options(
|
|
|
1526
1668
|
|
|
1527
1669
|
# Values set in files later in the CONFIG_FILENAMES list overwrite those
|
|
1528
1670
|
# set earlier.
|
|
1529
|
-
for filename in
|
|
1671
|
+
for filename in get_config_files("config.toml"):
|
|
1530
1672
|
if not os.path.exists(filename):
|
|
1531
1673
|
continue
|
|
1532
1674
|
|
|
1533
|
-
with open(filename, encoding="utf-8") as
|
|
1534
|
-
file_contents =
|
|
1675
|
+
with open(filename, encoding="utf-8") as file:
|
|
1676
|
+
file_contents = file.read()
|
|
1535
1677
|
|
|
1536
1678
|
_update_config_with_toml(file_contents, filename)
|
|
1537
1679
|
|
|
@@ -1546,8 +1688,8 @@ def get_config_options(
|
|
|
1546
1688
|
# Import logger locally to prevent circular references.
|
|
1547
1689
|
from streamlit.logger import get_logger
|
|
1548
1690
|
|
|
1549
|
-
|
|
1550
|
-
|
|
1691
|
+
logger: Final = get_logger(__name__)
|
|
1692
|
+
logger.warning(
|
|
1551
1693
|
"An update to the [server] config option section was detected."
|
|
1552
1694
|
" To have these changes be reflected, please restart streamlit."
|
|
1553
1695
|
)
|
|
@@ -1561,28 +1703,31 @@ def _check_conflicts() -> None:
|
|
|
1561
1703
|
|
|
1562
1704
|
# When using the Node server, we must always connect to 8501 (this is
|
|
1563
1705
|
# hard-coded in JS). Otherwise, the browser would decide what port to
|
|
1564
|
-
# connect to based on window.location.port, which in dev is going
|
|
1565
|
-
# be
|
|
1706
|
+
# connect to based on window.location.port, which in dev is going
|
|
1707
|
+
# to be 3000.
|
|
1566
1708
|
|
|
1567
1709
|
# Import logger locally to prevent circular references
|
|
1568
1710
|
from streamlit.logger import get_logger
|
|
1569
1711
|
|
|
1570
|
-
|
|
1712
|
+
logger: Final = get_logger(__name__)
|
|
1571
1713
|
|
|
1572
1714
|
if get_option("global.developmentMode"):
|
|
1573
|
-
|
|
1574
|
-
|
|
1575
|
-
|
|
1715
|
+
if not _is_unset("server.port"):
|
|
1716
|
+
raise RuntimeError(
|
|
1717
|
+
"server.port does not work when global.developmentMode is true."
|
|
1718
|
+
)
|
|
1576
1719
|
|
|
1577
|
-
|
|
1578
|
-
|
|
1579
|
-
|
|
1720
|
+
if not _is_unset("browser.serverPort"):
|
|
1721
|
+
raise RuntimeError(
|
|
1722
|
+
"browser.serverPort does not work when global.developmentMode is true."
|
|
1723
|
+
)
|
|
1580
1724
|
|
|
1581
1725
|
# XSRF conflicts
|
|
1582
|
-
if get_option("server.enableXsrfProtection")
|
|
1583
|
-
|
|
1584
|
-
|
|
1585
|
-
|
|
1726
|
+
if get_option("server.enableXsrfProtection") and (
|
|
1727
|
+
not get_option("server.enableCORS") or get_option("global.developmentMode")
|
|
1728
|
+
):
|
|
1729
|
+
logger.warning(
|
|
1730
|
+
"""
|
|
1586
1731
|
Warning: the config option 'server.enableCORS=false' is not compatible with
|
|
1587
1732
|
'server.enableXsrfProtection=true'.
|
|
1588
1733
|
As a result, 'server.enableCORS' is being overridden to 'true'.
|
|
@@ -1594,7 +1739,7 @@ cross-origin resource sharing.
|
|
|
1594
1739
|
|
|
1595
1740
|
If cross origin resource sharing is required, please disable server.enableXsrfProtection.
|
|
1596
1741
|
"""
|
|
1597
|
-
|
|
1742
|
+
)
|
|
1598
1743
|
|
|
1599
1744
|
|
|
1600
1745
|
def _set_development_mode() -> None:
|
|
@@ -1602,8 +1747,8 @@ def _set_development_mode() -> None:
|
|
|
1602
1747
|
|
|
1603
1748
|
|
|
1604
1749
|
def on_config_parsed(
|
|
1605
|
-
func: Callable[[], None], force_connect=False, lock=False
|
|
1606
|
-
) -> Callable[[],
|
|
1750
|
+
func: Callable[[], None], force_connect: bool = False, lock: bool = False
|
|
1751
|
+
) -> Callable[[], None]:
|
|
1607
1752
|
"""Wait for the config file to be parsed then call func.
|
|
1608
1753
|
|
|
1609
1754
|
If the config file has already been parsed, just calls func immediately
|
|
@@ -1623,7 +1768,7 @@ def on_config_parsed(
|
|
|
1623
1768
|
|
|
1624
1769
|
Returns
|
|
1625
1770
|
-------
|
|
1626
|
-
Callable[[],
|
|
1771
|
+
Callable[[], None]
|
|
1627
1772
|
A function that the caller can use to deregister func.
|
|
1628
1773
|
"""
|
|
1629
1774
|
|
|
@@ -1632,13 +1777,13 @@ def on_config_parsed(
|
|
|
1632
1777
|
# leading to a memory leak because the Signal will keep a reference of the
|
|
1633
1778
|
# callable argument. When the callable argument is an object method, then
|
|
1634
1779
|
# the reference to that object won't be released.
|
|
1635
|
-
def receiver(_):
|
|
1636
|
-
|
|
1780
|
+
def receiver(_: Any) -> None:
|
|
1781
|
+
func_with_lock()
|
|
1637
1782
|
|
|
1638
|
-
def disconnect():
|
|
1639
|
-
|
|
1783
|
+
def disconnect() -> None:
|
|
1784
|
+
_on_config_parsed.disconnect(receiver)
|
|
1640
1785
|
|
|
1641
|
-
def func_with_lock():
|
|
1786
|
+
def func_with_lock() -> None:
|
|
1642
1787
|
if lock:
|
|
1643
1788
|
with _config_lock:
|
|
1644
1789
|
func()
|