streamlit-nightly 1.43.2.dev20250307__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 +306 -0
- streamlit/__main__.py +20 -0
- streamlit/auth_util.py +218 -0
- streamlit/cli_util.py +105 -0
- streamlit/column_config.py +56 -0
- streamlit/commands/__init__.py +13 -0
- streamlit/commands/echo.py +126 -0
- streamlit/commands/execution_control.py +238 -0
- streamlit/commands/experimental_query_params.py +169 -0
- streamlit/commands/logo.py +189 -0
- streamlit/commands/navigation.py +385 -0
- streamlit/commands/page_config.py +311 -0
- streamlit/components/__init__.py +13 -0
- streamlit/components/lib/__init__.py +13 -0
- streamlit/components/lib/local_component_registry.py +84 -0
- streamlit/components/types/__init__.py +13 -0
- streamlit/components/types/base_component_registry.py +99 -0
- streamlit/components/types/base_custom_component.py +150 -0
- streamlit/components/v1/__init__.py +31 -0
- streamlit/components/v1/component_arrow.py +141 -0
- streamlit/components/v1/component_registry.py +130 -0
- streamlit/components/v1/components.py +38 -0
- streamlit/components/v1/custom_component.py +243 -0
- streamlit/config.py +1513 -0
- streamlit/config_option.py +311 -0
- streamlit/config_util.py +177 -0
- streamlit/connections/__init__.py +28 -0
- streamlit/connections/base_connection.py +174 -0
- streamlit/connections/snowflake_connection.py +562 -0
- streamlit/connections/snowpark_connection.py +213 -0
- streamlit/connections/sql_connection.py +425 -0
- streamlit/connections/util.py +97 -0
- streamlit/cursor.py +210 -0
- streamlit/dataframe_util.py +1416 -0
- streamlit/delta_generator.py +602 -0
- streamlit/delta_generator_singletons.py +204 -0
- streamlit/deprecation_util.py +209 -0
- streamlit/development.py +21 -0
- streamlit/elements/__init__.py +13 -0
- streamlit/elements/alert.py +234 -0
- streamlit/elements/arrow.py +962 -0
- streamlit/elements/balloons.py +47 -0
- streamlit/elements/bokeh_chart.py +133 -0
- streamlit/elements/code.py +114 -0
- streamlit/elements/deck_gl_json_chart.py +546 -0
- streamlit/elements/dialog_decorator.py +267 -0
- streamlit/elements/doc_string.py +558 -0
- streamlit/elements/empty.py +130 -0
- streamlit/elements/exception.py +331 -0
- streamlit/elements/form.py +354 -0
- streamlit/elements/graphviz_chart.py +150 -0
- streamlit/elements/heading.py +302 -0
- streamlit/elements/html.py +105 -0
- streamlit/elements/iframe.py +191 -0
- streamlit/elements/image.py +196 -0
- streamlit/elements/json.py +139 -0
- streamlit/elements/layouts.py +879 -0
- streamlit/elements/lib/__init__.py +13 -0
- streamlit/elements/lib/built_in_chart_utils.py +1157 -0
- streamlit/elements/lib/color_util.py +263 -0
- streamlit/elements/lib/column_config_utils.py +542 -0
- streamlit/elements/lib/column_types.py +2188 -0
- streamlit/elements/lib/dialog.py +147 -0
- streamlit/elements/lib/dicttools.py +154 -0
- streamlit/elements/lib/event_utils.py +37 -0
- streamlit/elements/lib/file_uploader_utils.py +66 -0
- streamlit/elements/lib/form_utils.py +77 -0
- streamlit/elements/lib/image_utils.py +441 -0
- streamlit/elements/lib/js_number.py +105 -0
- streamlit/elements/lib/mutable_status_container.py +183 -0
- streamlit/elements/lib/options_selector_utils.py +250 -0
- streamlit/elements/lib/pandas_styler_utils.py +274 -0
- streamlit/elements/lib/policies.py +194 -0
- streamlit/elements/lib/streamlit_plotly_theme.py +207 -0
- streamlit/elements/lib/subtitle_utils.py +176 -0
- streamlit/elements/lib/utils.py +250 -0
- streamlit/elements/map.py +508 -0
- streamlit/elements/markdown.py +277 -0
- streamlit/elements/media.py +793 -0
- streamlit/elements/metric.py +301 -0
- streamlit/elements/plotly_chart.py +546 -0
- streamlit/elements/progress.py +156 -0
- streamlit/elements/pyplot.py +194 -0
- streamlit/elements/snow.py +47 -0
- streamlit/elements/spinner.py +113 -0
- streamlit/elements/text.py +76 -0
- streamlit/elements/toast.py +98 -0
- streamlit/elements/vega_charts.py +1984 -0
- streamlit/elements/widgets/__init__.py +13 -0
- streamlit/elements/widgets/audio_input.py +310 -0
- streamlit/elements/widgets/button.py +1123 -0
- streamlit/elements/widgets/button_group.py +1008 -0
- streamlit/elements/widgets/camera_input.py +263 -0
- streamlit/elements/widgets/chat.py +647 -0
- streamlit/elements/widgets/checkbox.py +352 -0
- streamlit/elements/widgets/color_picker.py +265 -0
- streamlit/elements/widgets/data_editor.py +983 -0
- streamlit/elements/widgets/file_uploader.py +486 -0
- streamlit/elements/widgets/multiselect.py +338 -0
- streamlit/elements/widgets/number_input.py +545 -0
- streamlit/elements/widgets/radio.py +407 -0
- streamlit/elements/widgets/select_slider.py +437 -0
- streamlit/elements/widgets/selectbox.py +366 -0
- streamlit/elements/widgets/slider.py +880 -0
- streamlit/elements/widgets/text_widgets.py +628 -0
- streamlit/elements/widgets/time_widgets.py +970 -0
- streamlit/elements/write.py +574 -0
- streamlit/emojis.py +34 -0
- streamlit/env_util.py +61 -0
- streamlit/error_util.py +105 -0
- streamlit/errors.py +452 -0
- streamlit/external/__init__.py +13 -0
- streamlit/external/langchain/__init__.py +23 -0
- streamlit/external/langchain/streamlit_callback_handler.py +406 -0
- streamlit/file_util.py +247 -0
- streamlit/git_util.py +173 -0
- streamlit/hello/__init__.py +13 -0
- streamlit/hello/animation_demo.py +82 -0
- streamlit/hello/dataframe_demo.py +71 -0
- streamlit/hello/hello.py +37 -0
- streamlit/hello/mapping_demo.py +114 -0
- streamlit/hello/plotting_demo.py +55 -0
- streamlit/hello/streamlit_app.py +55 -0
- streamlit/hello/utils.py +28 -0
- streamlit/logger.py +130 -0
- streamlit/material_icon_names.py +25 -0
- streamlit/navigation/__init__.py +13 -0
- streamlit/navigation/page.py +302 -0
- streamlit/net_util.py +125 -0
- streamlit/platform.py +33 -0
- streamlit/proto/Alert_pb2.py +29 -0
- streamlit/proto/Alert_pb2.pyi +90 -0
- streamlit/proto/AppPage_pb2.py +27 -0
- streamlit/proto/AppPage_pb2.pyi +64 -0
- streamlit/proto/ArrowNamedDataSet_pb2.py +28 -0
- streamlit/proto/ArrowNamedDataSet_pb2.pyi +57 -0
- streamlit/proto/ArrowVegaLiteChart_pb2.py +29 -0
- streamlit/proto/ArrowVegaLiteChart_pb2.pyi +84 -0
- streamlit/proto/Arrow_pb2.py +33 -0
- streamlit/proto/Arrow_pb2.pyi +188 -0
- streamlit/proto/AudioInput_pb2.py +28 -0
- streamlit/proto/AudioInput_pb2.pyi +58 -0
- streamlit/proto/Audio_pb2.py +27 -0
- streamlit/proto/Audio_pb2.pyi +58 -0
- streamlit/proto/AuthRedirect_pb2.py +27 -0
- streamlit/proto/AuthRedirect_pb2.pyi +41 -0
- streamlit/proto/AutoRerun_pb2.py +27 -0
- streamlit/proto/AutoRerun_pb2.pyi +45 -0
- streamlit/proto/BackMsg_pb2.py +29 -0
- streamlit/proto/BackMsg_pb2.pyi +105 -0
- streamlit/proto/Balloons_pb2.py +27 -0
- streamlit/proto/Balloons_pb2.pyi +43 -0
- streamlit/proto/Block_pb2.py +53 -0
- streamlit/proto/Block_pb2.pyi +322 -0
- streamlit/proto/BokehChart_pb2.py +27 -0
- streamlit/proto/BokehChart_pb2.pyi +49 -0
- streamlit/proto/ButtonGroup_pb2.py +36 -0
- streamlit/proto/ButtonGroup_pb2.pyi +169 -0
- streamlit/proto/Button_pb2.py +27 -0
- streamlit/proto/Button_pb2.pyi +71 -0
- streamlit/proto/CameraInput_pb2.py +28 -0
- streamlit/proto/CameraInput_pb2.pyi +58 -0
- streamlit/proto/ChatInput_pb2.py +31 -0
- streamlit/proto/ChatInput_pb2.pyi +111 -0
- streamlit/proto/Checkbox_pb2.py +30 -0
- streamlit/proto/Checkbox_pb2.pyi +90 -0
- streamlit/proto/ClientState_pb2.py +30 -0
- streamlit/proto/ClientState_pb2.pyi +90 -0
- streamlit/proto/Code_pb2.py +27 -0
- streamlit/proto/Code_pb2.pyi +55 -0
- streamlit/proto/ColorPicker_pb2.py +28 -0
- streamlit/proto/ColorPicker_pb2.pyi +67 -0
- streamlit/proto/Common_pb2.py +51 -0
- streamlit/proto/Common_pb2.pyi +293 -0
- streamlit/proto/Components_pb2.py +35 -0
- streamlit/proto/Components_pb2.pyi +172 -0
- streamlit/proto/DataFrame_pb2.py +56 -0
- streamlit/proto/DataFrame_pb2.pyi +397 -0
- streamlit/proto/DateInput_pb2.py +28 -0
- streamlit/proto/DateInput_pb2.pyi +83 -0
- streamlit/proto/DeckGlJsonChart_pb2.py +29 -0
- streamlit/proto/DeckGlJsonChart_pb2.pyi +102 -0
- streamlit/proto/Delta_pb2.py +31 -0
- streamlit/proto/Delta_pb2.pyi +74 -0
- streamlit/proto/DocString_pb2.py +29 -0
- streamlit/proto/DocString_pb2.pyi +93 -0
- streamlit/proto/DownloadButton_pb2.py +27 -0
- streamlit/proto/DownloadButton_pb2.pyi +70 -0
- streamlit/proto/Element_pb2.py +78 -0
- streamlit/proto/Element_pb2.pyi +312 -0
- streamlit/proto/Empty_pb2.py +27 -0
- streamlit/proto/Empty_pb2.pyi +36 -0
- streamlit/proto/Exception_pb2.py +27 -0
- streamlit/proto/Exception_pb2.pyi +72 -0
- streamlit/proto/Favicon_pb2.py +27 -0
- streamlit/proto/Favicon_pb2.pyi +40 -0
- streamlit/proto/FileUploader_pb2.py +28 -0
- streamlit/proto/FileUploader_pb2.pyi +78 -0
- streamlit/proto/ForwardMsg_pb2.py +53 -0
- streamlit/proto/ForwardMsg_pb2.pyi +293 -0
- streamlit/proto/GitInfo_pb2.py +29 -0
- streamlit/proto/GitInfo_pb2.pyi +83 -0
- streamlit/proto/GraphVizChart_pb2.py +27 -0
- streamlit/proto/GraphVizChart_pb2.pyi +53 -0
- streamlit/proto/Heading_pb2.py +27 -0
- streamlit/proto/Heading_pb2.pyi +56 -0
- streamlit/proto/Html_pb2.py +27 -0
- streamlit/proto/Html_pb2.pyi +42 -0
- streamlit/proto/IFrame_pb2.py +27 -0
- streamlit/proto/IFrame_pb2.pyi +59 -0
- streamlit/proto/Image_pb2.py +29 -0
- streamlit/proto/Image_pb2.pyi +84 -0
- streamlit/proto/Json_pb2.py +27 -0
- streamlit/proto/Json_pb2.pyi +53 -0
- streamlit/proto/LabelVisibilityMessage_pb2.py +29 -0
- streamlit/proto/LabelVisibilityMessage_pb2.pyi +68 -0
- streamlit/proto/LinkButton_pb2.py +27 -0
- streamlit/proto/LinkButton_pb2.pyi +58 -0
- streamlit/proto/Logo_pb2.py +27 -0
- streamlit/proto/Logo_pb2.pyi +51 -0
- streamlit/proto/Markdown_pb2.py +29 -0
- streamlit/proto/Markdown_pb2.pyi +86 -0
- streamlit/proto/Metric_pb2.py +32 -0
- streamlit/proto/Metric_pb2.pyi +101 -0
- streamlit/proto/MetricsEvent_pb2.py +30 -0
- streamlit/proto/MetricsEvent_pb2.pyi +200 -0
- streamlit/proto/MultiSelect_pb2.py +28 -0
- streamlit/proto/MultiSelect_pb2.pyi +81 -0
- streamlit/proto/NamedDataSet_pb2.py +28 -0
- streamlit/proto/NamedDataSet_pb2.pyi +59 -0
- streamlit/proto/Navigation_pb2.py +30 -0
- streamlit/proto/Navigation_pb2.pyi +84 -0
- streamlit/proto/NewSession_pb2.py +51 -0
- streamlit/proto/NewSession_pb2.pyi +481 -0
- streamlit/proto/NumberInput_pb2.py +30 -0
- streamlit/proto/NumberInput_pb2.pyi +121 -0
- streamlit/proto/PageConfig_pb2.py +33 -0
- streamlit/proto/PageConfig_pb2.pyi +126 -0
- streamlit/proto/PageInfo_pb2.py +27 -0
- streamlit/proto/PageInfo_pb2.pyi +43 -0
- streamlit/proto/PageLink_pb2.py +27 -0
- streamlit/proto/PageLink_pb2.pyi +63 -0
- streamlit/proto/PageNotFound_pb2.py +27 -0
- streamlit/proto/PageNotFound_pb2.pyi +42 -0
- streamlit/proto/PageProfile_pb2.py +31 -0
- streamlit/proto/PageProfile_pb2.pyi +127 -0
- streamlit/proto/PagesChanged_pb2.py +28 -0
- streamlit/proto/PagesChanged_pb2.pyi +48 -0
- streamlit/proto/ParentMessage_pb2.py +27 -0
- streamlit/proto/ParentMessage_pb2.pyi +46 -0
- streamlit/proto/PlotlyChart_pb2.py +31 -0
- streamlit/proto/PlotlyChart_pb2.pyi +131 -0
- streamlit/proto/Progress_pb2.py +27 -0
- streamlit/proto/Progress_pb2.pyi +43 -0
- streamlit/proto/Radio_pb2.py +28 -0
- streamlit/proto/Radio_pb2.pyi +84 -0
- streamlit/proto/RootContainer_pb2.py +27 -0
- streamlit/proto/RootContainer_pb2.pyi +56 -0
- streamlit/proto/Selectbox_pb2.py +28 -0
- streamlit/proto/Selectbox_pb2.pyi +80 -0
- streamlit/proto/SessionEvent_pb2.py +28 -0
- streamlit/proto/SessionEvent_pb2.pyi +62 -0
- streamlit/proto/SessionStatus_pb2.py +27 -0
- streamlit/proto/SessionStatus_pb2.pyi +57 -0
- streamlit/proto/Skeleton_pb2.py +29 -0
- streamlit/proto/Skeleton_pb2.pyi +71 -0
- streamlit/proto/Slider_pb2.py +32 -0
- streamlit/proto/Slider_pb2.pyi +142 -0
- streamlit/proto/Snow_pb2.py +27 -0
- streamlit/proto/Snow_pb2.pyi +43 -0
- streamlit/proto/Spinner_pb2.py +27 -0
- streamlit/proto/Spinner_pb2.pyi +49 -0
- streamlit/proto/TextArea_pb2.py +28 -0
- streamlit/proto/TextArea_pb2.pyi +80 -0
- streamlit/proto/TextInput_pb2.py +30 -0
- streamlit/proto/TextInput_pb2.pyi +107 -0
- streamlit/proto/Text_pb2.py +27 -0
- streamlit/proto/Text_pb2.pyi +46 -0
- streamlit/proto/TimeInput_pb2.py +28 -0
- streamlit/proto/TimeInput_pb2.pyi +74 -0
- streamlit/proto/Toast_pb2.py +27 -0
- streamlit/proto/Toast_pb2.pyi +45 -0
- streamlit/proto/VegaLiteChart_pb2.py +29 -0
- streamlit/proto/VegaLiteChart_pb2.pyi +71 -0
- streamlit/proto/Video_pb2.py +31 -0
- streamlit/proto/Video_pb2.pyi +117 -0
- streamlit/proto/WidgetStates_pb2.py +31 -0
- streamlit/proto/WidgetStates_pb2.pyi +126 -0
- streamlit/proto/__init__.py +15 -0
- streamlit/proto/openmetrics_data_model_pb2.py +60 -0
- streamlit/proto/openmetrics_data_model_pb2.pyi +522 -0
- streamlit/py.typed +0 -0
- streamlit/runtime/__init__.py +50 -0
- streamlit/runtime/app_session.py +982 -0
- streamlit/runtime/caching/__init__.py +98 -0
- streamlit/runtime/caching/cache_data_api.py +665 -0
- streamlit/runtime/caching/cache_errors.py +142 -0
- streamlit/runtime/caching/cache_resource_api.py +527 -0
- streamlit/runtime/caching/cache_type.py +33 -0
- streamlit/runtime/caching/cache_utils.py +523 -0
- streamlit/runtime/caching/cached_message_replay.py +290 -0
- streamlit/runtime/caching/hashing.py +637 -0
- streamlit/runtime/caching/legacy_cache_api.py +169 -0
- streamlit/runtime/caching/storage/__init__.py +29 -0
- streamlit/runtime/caching/storage/cache_storage_protocol.py +239 -0
- streamlit/runtime/caching/storage/dummy_cache_storage.py +60 -0
- streamlit/runtime/caching/storage/in_memory_cache_storage_wrapper.py +145 -0
- streamlit/runtime/caching/storage/local_disk_cache_storage.py +223 -0
- streamlit/runtime/connection_factory.py +436 -0
- streamlit/runtime/context.py +280 -0
- streamlit/runtime/credentials.py +364 -0
- streamlit/runtime/forward_msg_cache.py +296 -0
- streamlit/runtime/forward_msg_queue.py +240 -0
- streamlit/runtime/fragment.py +477 -0
- streamlit/runtime/media_file_manager.py +234 -0
- streamlit/runtime/media_file_storage.py +143 -0
- streamlit/runtime/memory_media_file_storage.py +181 -0
- streamlit/runtime/memory_session_storage.py +77 -0
- streamlit/runtime/memory_uploaded_file_manager.py +138 -0
- streamlit/runtime/metrics_util.py +486 -0
- streamlit/runtime/pages_manager.py +165 -0
- streamlit/runtime/runtime.py +792 -0
- streamlit/runtime/runtime_util.py +106 -0
- streamlit/runtime/script_data.py +46 -0
- streamlit/runtime/scriptrunner/__init__.py +38 -0
- streamlit/runtime/scriptrunner/exec_code.py +159 -0
- streamlit/runtime/scriptrunner/magic.py +273 -0
- streamlit/runtime/scriptrunner/magic_funcs.py +32 -0
- streamlit/runtime/scriptrunner/script_cache.py +89 -0
- streamlit/runtime/scriptrunner/script_runner.py +756 -0
- streamlit/runtime/scriptrunner_utils/__init__.py +19 -0
- streamlit/runtime/scriptrunner_utils/exceptions.py +48 -0
- streamlit/runtime/scriptrunner_utils/script_requests.py +307 -0
- streamlit/runtime/scriptrunner_utils/script_run_context.py +287 -0
- streamlit/runtime/secrets.py +534 -0
- streamlit/runtime/session_manager.py +394 -0
- streamlit/runtime/state/__init__.py +41 -0
- streamlit/runtime/state/common.py +191 -0
- streamlit/runtime/state/query_params.py +205 -0
- streamlit/runtime/state/query_params_proxy.py +218 -0
- streamlit/runtime/state/safe_session_state.py +138 -0
- streamlit/runtime/state/session_state.py +772 -0
- streamlit/runtime/state/session_state_proxy.py +153 -0
- streamlit/runtime/state/widgets.py +135 -0
- streamlit/runtime/stats.py +109 -0
- streamlit/runtime/uploaded_file_manager.py +148 -0
- streamlit/runtime/websocket_session_manager.py +167 -0
- streamlit/source_util.py +98 -0
- streamlit/static/favicon.png +0 -0
- streamlit/static/index.html +61 -0
- streamlit/static/static/css/index.Bmkmz40k.css +1 -0
- streamlit/static/static/css/index.DpJG_94W.css +1 -0
- streamlit/static/static/css/index.DzuxGC_t.css +1 -0
- streamlit/static/static/js/FileDownload.esm.Bp9m5jrx.js +1 -0
- streamlit/static/static/js/FileHelper.D_3pbilj.js +5 -0
- streamlit/static/static/js/FormClearHelper.Ct2rwLXo.js +1 -0
- streamlit/static/static/js/Hooks.BKdzj5MJ.js +1 -0
- streamlit/static/static/js/InputInstructions.DB3QGNJP.js +1 -0
- streamlit/static/static/js/ProgressBar.D40A5xc2.js +2 -0
- streamlit/static/static/js/RenderInPortalIfExists.DLUCooTN.js +1 -0
- streamlit/static/static/js/Toolbar.BiGGIQun.js +1 -0
- streamlit/static/static/js/UploadFileInfo.C-jY39rj.js +1 -0
- streamlit/static/static/js/base-input.CQBQT24M.js +4 -0
- streamlit/static/static/js/checkbox.Buj8gd_M.js +9 -0
- streamlit/static/static/js/createDownloadLinkElement.DZMwyjvU.js +1 -0
- streamlit/static/static/js/createSuper.CesK3I23.js +1 -0
- streamlit/static/static/js/data-grid-overlay-editor.B69OOFM4.js +1 -0
- streamlit/static/static/js/downloader.BZQhlBNT.js +1 -0
- streamlit/static/static/js/es6.D9Zhqujy.js +2 -0
- streamlit/static/static/js/iframeResizer.contentWindow.CAzcBpCC.js +1 -0
- streamlit/static/static/js/index.08vcOOvb.js +1 -0
- streamlit/static/static/js/index.0uqKfJUS.js +1 -0
- streamlit/static/static/js/index.B02M5u69.js +203 -0
- streamlit/static/static/js/index.B7mcZKMx.js +1 -0
- streamlit/static/static/js/index.BAQDHFA_.js +1 -0
- streamlit/static/static/js/index.BI60cMVr.js +2 -0
- streamlit/static/static/js/index.BLug2inK.js +1 -0
- streamlit/static/static/js/index.BM6TMY8g.js +2 -0
- streamlit/static/static/js/index.BZ9p1t7G.js +1 -0
- streamlit/static/static/js/index.BZqa87a1.js +2 -0
- streamlit/static/static/js/index.BcsRUzZZ.js +1 -0
- streamlit/static/static/js/index.BgVMiY_P.js +197 -0
- streamlit/static/static/js/index.BtuGy7By.js +6 -0
- streamlit/static/static/js/index.BuDuBmrs.js +1 -0
- streamlit/static/static/js/index.BvXU2oKV.js +1 -0
- streamlit/static/static/js/index.BxcwPacT.js +73 -0
- streamlit/static/static/js/index.CWX8KB81.js +1 -0
- streamlit/static/static/js/index.CXzZTo_q.js +1 -0
- streamlit/static/static/js/index.CcRWp_KL.js +1 -0
- streamlit/static/static/js/index.Cd-_xe55.js +3 -0
- streamlit/static/static/js/index.CdG2PXln.js +4537 -0
- streamlit/static/static/js/index.CjXvXmcP.js +1 -0
- streamlit/static/static/js/index.D1HZENZx.js +776 -0
- streamlit/static/static/js/index.D21Efo64.js +1617 -0
- streamlit/static/static/js/index.D9WgGVBx.js +7 -0
- streamlit/static/static/js/index.DEcsHtvb.js +12 -0
- streamlit/static/static/js/index.DFeMfr_K.js +1 -0
- streamlit/static/static/js/index.DHFBoItz.js +1 -0
- streamlit/static/static/js/index.D_PrBKnJ.js +3 -0
- streamlit/static/static/js/index.DmuRkekN.js +3855 -0
- streamlit/static/static/js/index.Do6eY8sf.js +1 -0
- streamlit/static/static/js/index.Dz3lP2P-.js +1 -0
- streamlit/static/static/js/index.Dz_UqF-s.js +1 -0
- streamlit/static/static/js/index.GkSUsPhJ.js +1 -0
- streamlit/static/static/js/index.H1U1IC_d.js +3 -0
- streamlit/static/static/js/index.g6p_4DPr.js +1 -0
- streamlit/static/static/js/index.g9x_GKss.js +1 -0
- streamlit/static/static/js/index.zo9jm08y.js +1 -0
- streamlit/static/static/js/input.DnaFglHq.js +2 -0
- streamlit/static/static/js/inputUtils.CQWz5UKz.js +1 -0
- streamlit/static/static/js/memory.Crb9x4-F.js +1 -0
- streamlit/static/static/js/mergeWith.ouAz0sK3.js +1 -0
- streamlit/static/static/js/number-overlay-editor._UaN-O48.js +9 -0
- streamlit/static/static/js/possibleConstructorReturn.CtGjGFHz.js +1 -0
- streamlit/static/static/js/sandbox.CBybYOhV.js +1 -0
- streamlit/static/static/js/sprintf.D7DtBTRn.js +1 -0
- streamlit/static/static/js/textarea.Cb_uJt5U.js +2 -0
- streamlit/static/static/js/threshold.DjX0wlsa.js +1 -0
- streamlit/static/static/js/timepicker.DKT7pfoF.js +4 -0
- streamlit/static/static/js/timer.CAwTRJ_g.js +1 -0
- streamlit/static/static/js/toConsumableArray.05Ikp13-.js +3 -0
- streamlit/static/static/js/uniqueId.D2FMWUEI.js +1 -0
- streamlit/static/static/js/useBasicWidgetState.urnZLANY.js +1 -0
- streamlit/static/static/js/useOnInputChange.BOKIIdJ1.js +1 -0
- streamlit/static/static/js/value.CgPGBV_l.js +1 -0
- streamlit/static/static/js/withFullScreenWrapper.C_N8J0Xx.js +1 -0
- streamlit/static/static/media/KaTeX_AMS-Regular.BQhdFMY1.woff2 +0 -0
- streamlit/static/static/media/KaTeX_AMS-Regular.DMm9YOAa.woff +0 -0
- streamlit/static/static/media/KaTeX_AMS-Regular.DRggAlZN.ttf +0 -0
- streamlit/static/static/media/KaTeX_Caligraphic-Bold.ATXxdsX0.ttf +0 -0
- streamlit/static/static/media/KaTeX_Caligraphic-Bold.BEiXGLvX.woff +0 -0
- streamlit/static/static/media/KaTeX_Caligraphic-Bold.Dq_IR9rO.woff2 +0 -0
- streamlit/static/static/media/KaTeX_Caligraphic-Regular.CTRA-rTL.woff +0 -0
- streamlit/static/static/media/KaTeX_Caligraphic-Regular.Di6jR-x-.woff2 +0 -0
- streamlit/static/static/media/KaTeX_Caligraphic-Regular.wX97UBjC.ttf +0 -0
- streamlit/static/static/media/KaTeX_Fraktur-Bold.BdnERNNW.ttf +0 -0
- streamlit/static/static/media/KaTeX_Fraktur-Bold.BsDP51OF.woff +0 -0
- streamlit/static/static/media/KaTeX_Fraktur-Bold.CL6g_b3V.woff2 +0 -0
- streamlit/static/static/media/KaTeX_Fraktur-Regular.CB_wures.ttf +0 -0
- streamlit/static/static/media/KaTeX_Fraktur-Regular.CTYiF6lA.woff2 +0 -0
- streamlit/static/static/media/KaTeX_Fraktur-Regular.Dxdc4cR9.woff +0 -0
- streamlit/static/static/media/KaTeX_Main-Bold.Cx986IdX.woff2 +0 -0
- streamlit/static/static/media/KaTeX_Main-Bold.Jm3AIy58.woff +0 -0
- streamlit/static/static/media/KaTeX_Main-Bold.waoOVXN0.ttf +0 -0
- streamlit/static/static/media/KaTeX_Main-BoldItalic.DxDJ3AOS.woff2 +0 -0
- streamlit/static/static/media/KaTeX_Main-BoldItalic.DzxPMmG6.ttf +0 -0
- streamlit/static/static/media/KaTeX_Main-BoldItalic.SpSLRI95.woff +0 -0
- streamlit/static/static/media/KaTeX_Main-Italic.3WenGoN9.ttf +0 -0
- streamlit/static/static/media/KaTeX_Main-Italic.BMLOBm91.woff +0 -0
- streamlit/static/static/media/KaTeX_Main-Italic.NWA7e6Wa.woff2 +0 -0
- streamlit/static/static/media/KaTeX_Main-Regular.B22Nviop.woff2 +0 -0
- streamlit/static/static/media/KaTeX_Main-Regular.Dr94JaBh.woff +0 -0
- streamlit/static/static/media/KaTeX_Main-Regular.ypZvNtVU.ttf +0 -0
- streamlit/static/static/media/KaTeX_Math-BoldItalic.B3XSjfu4.ttf +0 -0
- streamlit/static/static/media/KaTeX_Math-BoldItalic.CZnvNsCZ.woff2 +0 -0
- streamlit/static/static/media/KaTeX_Math-BoldItalic.iY-2wyZ7.woff +0 -0
- streamlit/static/static/media/KaTeX_Math-Italic.DA0__PXp.woff +0 -0
- streamlit/static/static/media/KaTeX_Math-Italic.flOr_0UB.ttf +0 -0
- streamlit/static/static/media/KaTeX_Math-Italic.t53AETM-.woff2 +0 -0
- streamlit/static/static/media/KaTeX_SansSerif-Bold.CFMepnvq.ttf +0 -0
- streamlit/static/static/media/KaTeX_SansSerif-Bold.D1sUS0GD.woff2 +0 -0
- streamlit/static/static/media/KaTeX_SansSerif-Bold.DbIhKOiC.woff +0 -0
- streamlit/static/static/media/KaTeX_SansSerif-Italic.C3H0VqGB.woff2 +0 -0
- streamlit/static/static/media/KaTeX_SansSerif-Italic.DN2j7dab.woff +0 -0
- streamlit/static/static/media/KaTeX_SansSerif-Italic.YYjJ1zSn.ttf +0 -0
- streamlit/static/static/media/KaTeX_SansSerif-Regular.BNo7hRIc.ttf +0 -0
- streamlit/static/static/media/KaTeX_SansSerif-Regular.CS6fqUqJ.woff +0 -0
- streamlit/static/static/media/KaTeX_SansSerif-Regular.DDBCnlJ7.woff2 +0 -0
- streamlit/static/static/media/KaTeX_Script-Regular.C5JkGWo-.ttf +0 -0
- streamlit/static/static/media/KaTeX_Script-Regular.D3wIWfF6.woff2 +0 -0
- streamlit/static/static/media/KaTeX_Script-Regular.D5yQViql.woff +0 -0
- streamlit/static/static/media/KaTeX_Size1-Regular.C195tn64.woff +0 -0
- streamlit/static/static/media/KaTeX_Size1-Regular.Dbsnue_I.ttf +0 -0
- streamlit/static/static/media/KaTeX_Size1-Regular.mCD8mA8B.woff2 +0 -0
- streamlit/static/static/media/KaTeX_Size2-Regular.B7gKUWhC.ttf +0 -0
- streamlit/static/static/media/KaTeX_Size2-Regular.Dy4dx90m.woff2 +0 -0
- streamlit/static/static/media/KaTeX_Size2-Regular.oD1tc_U0.woff +0 -0
- streamlit/static/static/media/KaTeX_Size3-Regular.CTq5MqoE.woff +0 -0
- streamlit/static/static/media/KaTeX_Size3-Regular.DgpXs0kz.ttf +0 -0
- streamlit/static/static/media/KaTeX_Size4-Regular.BF-4gkZK.woff +0 -0
- streamlit/static/static/media/KaTeX_Size4-Regular.DWFBv043.ttf +0 -0
- streamlit/static/static/media/KaTeX_Size4-Regular.Dl5lxZxV.woff2 +0 -0
- streamlit/static/static/media/KaTeX_Typewriter-Regular.C0xS9mPB.woff +0 -0
- streamlit/static/static/media/KaTeX_Typewriter-Regular.CO6r4hn1.woff2 +0 -0
- streamlit/static/static/media/KaTeX_Typewriter-Regular.D3Ib7_Hf.ttf +0 -0
- streamlit/static/static/media/MaterialSymbols-Rounded.DcZbplWk.woff2 +0 -0
- 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/static/static/media/balloon-0.Czj7AKwE.png +0 -0
- streamlit/static/static/media/balloon-1.CNvFFrND.png +0 -0
- streamlit/static/static/media/balloon-2.DTvC6B1t.png +0 -0
- streamlit/static/static/media/balloon-3.CgSk4tbL.png +0 -0
- streamlit/static/static/media/balloon-4.mbtFrzxf.png +0 -0
- streamlit/static/static/media/balloon-5.CSwkUfRA.png +0 -0
- streamlit/static/static/media/fireworks.B4d-_KUe.gif +0 -0
- streamlit/static/static/media/flake-0.DgWaVvm5.png +0 -0
- streamlit/static/static/media/flake-1.B2r5AHMK.png +0 -0
- streamlit/static/static/media/flake-2.BnWSExPC.png +0 -0
- streamlit/static/static/media/snowflake.JU2jBHL8.svg +11 -0
- streamlit/string_util.py +203 -0
- streamlit/temporary_directory.py +56 -0
- streamlit/testing/__init__.py +13 -0
- streamlit/testing/v1/__init__.py +17 -0
- streamlit/testing/v1/app_test.py +1050 -0
- streamlit/testing/v1/element_tree.py +2083 -0
- streamlit/testing/v1/local_script_runner.py +180 -0
- streamlit/testing/v1/util.py +53 -0
- streamlit/time_util.py +75 -0
- streamlit/type_util.py +460 -0
- streamlit/url_util.py +122 -0
- streamlit/user_info.py +519 -0
- streamlit/util.py +72 -0
- streamlit/vendor/__init__.py +0 -0
- streamlit/vendor/pympler/__init__.py +0 -0
- streamlit/vendor/pympler/asizeof.py +2869 -0
- streamlit/version.py +18 -0
- streamlit/watcher/__init__.py +28 -0
- streamlit/watcher/event_based_path_watcher.py +406 -0
- streamlit/watcher/folder_black_list.py +82 -0
- streamlit/watcher/local_sources_watcher.py +233 -0
- streamlit/watcher/path_watcher.py +185 -0
- streamlit/watcher/polling_path_watcher.py +124 -0
- streamlit/watcher/util.py +207 -0
- streamlit/web/__init__.py +13 -0
- streamlit/web/bootstrap.py +353 -0
- streamlit/web/cache_storage_manager_config.py +38 -0
- streamlit/web/cli.py +369 -0
- streamlit/web/server/__init__.py +26 -0
- streamlit/web/server/app_static_file_handler.py +93 -0
- streamlit/web/server/authlib_tornado_integration.py +60 -0
- streamlit/web/server/browser_websocket_handler.py +246 -0
- streamlit/web/server/component_request_handler.py +116 -0
- streamlit/web/server/media_file_handler.py +141 -0
- streamlit/web/server/oauth_authlib_routes.py +176 -0
- streamlit/web/server/oidc_mixin.py +108 -0
- streamlit/web/server/routes.py +295 -0
- streamlit/web/server/server.py +479 -0
- streamlit/web/server/server_util.py +161 -0
- streamlit/web/server/stats_request_handler.py +95 -0
- streamlit/web/server/upload_file_request_handler.py +137 -0
- streamlit/web/server/websocket_headers.py +56 -0
- streamlit_nightly-1.43.2.dev20250307.data/scripts/streamlit.cmd +16 -0
- streamlit_nightly-1.43.2.dev20250307.dist-info/METADATA +207 -0
- streamlit_nightly-1.43.2.dev20250307.dist-info/RECORD +563 -0
- streamlit_nightly-1.43.2.dev20250307.dist-info/WHEEL +5 -0
- streamlit_nightly-1.43.2.dev20250307.dist-info/entry_points.txt +2 -0
- streamlit_nightly-1.43.2.dev20250307.dist-info/top_level.txt +1 -0
@@ -0,0 +1,207 @@
|
|
1
|
+
# Copyright (c) Streamlit Inc. (2018-2022) Snowflake Inc. (2022-2025)
|
2
|
+
#
|
3
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
4
|
+
# you may not use this file except in compliance with the License.
|
5
|
+
# You may obtain a copy of the License at
|
6
|
+
#
|
7
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
8
|
+
#
|
9
|
+
# Unless required by applicable law or agreed to in writing, software
|
10
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
11
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
12
|
+
# See the License for the specific language governing permissions and
|
13
|
+
# limitations under the License.
|
14
|
+
|
15
|
+
"""A bunch of useful utilities for the watcher.
|
16
|
+
|
17
|
+
These are functions that only make sense within the watcher. In particular,
|
18
|
+
functions that use streamlit.config can go here to avoid a dependency cycle.
|
19
|
+
"""
|
20
|
+
|
21
|
+
from __future__ import annotations
|
22
|
+
|
23
|
+
import os
|
24
|
+
import time
|
25
|
+
from pathlib import Path
|
26
|
+
from typing import Callable, TypeVar
|
27
|
+
|
28
|
+
from streamlit.errors import Error
|
29
|
+
from streamlit.util import calc_md5
|
30
|
+
|
31
|
+
# How many times to try to grab the MD5 hash.
|
32
|
+
_MAX_RETRIES = 5
|
33
|
+
|
34
|
+
# How long to wait between retries.
|
35
|
+
_RETRY_WAIT_SECS = 0.1
|
36
|
+
|
37
|
+
|
38
|
+
def calc_md5_with_blocking_retries(
|
39
|
+
path: str,
|
40
|
+
*, # keyword-only arguments:
|
41
|
+
glob_pattern: str | None = None,
|
42
|
+
allow_nonexistent: bool = False,
|
43
|
+
) -> str:
|
44
|
+
"""Calculate the MD5 checksum of a given path.
|
45
|
+
|
46
|
+
For a file, this means calculating the md5 of the file's contents. For a
|
47
|
+
directory, we concatenate the directory's path with the names of all the
|
48
|
+
files in it and calculate the md5 of that.
|
49
|
+
|
50
|
+
IMPORTANT: This method calls time.sleep(), which blocks execution. So you
|
51
|
+
should only use this outside the main thread.
|
52
|
+
"""
|
53
|
+
|
54
|
+
if allow_nonexistent and not os.path.exists(path):
|
55
|
+
content = path.encode("UTF-8")
|
56
|
+
elif os.path.isdir(path):
|
57
|
+
glob_pattern = glob_pattern or "*"
|
58
|
+
content = _stable_dir_identifier(path, glob_pattern).encode("UTF-8")
|
59
|
+
else:
|
60
|
+
# There's a race condition where sometimes file_path no longer exists when
|
61
|
+
# we try to read it (since the file is in the process of being written).
|
62
|
+
# So here we retry a few times using this loop. See issue #186.
|
63
|
+
content = _do_with_retries(
|
64
|
+
lambda: _get_file_content(path),
|
65
|
+
FileNotFoundError,
|
66
|
+
path,
|
67
|
+
)
|
68
|
+
|
69
|
+
return calc_md5(content)
|
70
|
+
|
71
|
+
|
72
|
+
def path_modification_time(path: str, allow_nonexistent: bool = False) -> float:
|
73
|
+
"""Return the modification time of a path (file or directory).
|
74
|
+
|
75
|
+
If allow_nonexistent is True and the path does not exist, we return 0.0 to
|
76
|
+
guarantee that any file/dir later created at the path has a later
|
77
|
+
modification time than the last time returned by this function for that
|
78
|
+
path.
|
79
|
+
|
80
|
+
If allow_nonexistent is False and no file/dir exists at the path, a
|
81
|
+
FileNotFoundError is raised (by os.stat).
|
82
|
+
|
83
|
+
For any path that does correspond to an existing file/dir, we return its
|
84
|
+
modification time.
|
85
|
+
"""
|
86
|
+
if allow_nonexistent and not os.path.exists(path):
|
87
|
+
return 0.0
|
88
|
+
|
89
|
+
# Use retries to avoid race condition where file may be in the process of being
|
90
|
+
# modified.
|
91
|
+
return _do_with_retries(
|
92
|
+
lambda: os.stat(path).st_mtime,
|
93
|
+
FileNotFoundError,
|
94
|
+
path,
|
95
|
+
)
|
96
|
+
|
97
|
+
|
98
|
+
def _get_file_content(file_path: str) -> bytes:
|
99
|
+
with open(file_path, "rb") as f:
|
100
|
+
return f.read()
|
101
|
+
|
102
|
+
|
103
|
+
def _dirfiles(dir_path: str, glob_pattern: str) -> str:
|
104
|
+
p = Path(dir_path)
|
105
|
+
filenames = sorted(
|
106
|
+
[f.name for f in p.glob(glob_pattern) if not f.name.startswith(".")]
|
107
|
+
)
|
108
|
+
return "+".join(filenames)
|
109
|
+
|
110
|
+
|
111
|
+
def _stable_dir_identifier(dir_path: str, glob_pattern: str) -> str:
|
112
|
+
"""Wait for the files in a directory to look stable-ish before returning an id.
|
113
|
+
|
114
|
+
We do this to deal with problems that would otherwise arise from many tools
|
115
|
+
(e.g. git) and editors (e.g. vim) "editing" files (from the user's
|
116
|
+
perspective) by doing some combination of deleting, creating, and moving
|
117
|
+
various files under the hood.
|
118
|
+
|
119
|
+
Because of this, we're unable to rely on FileSystemEvents that we receive
|
120
|
+
from watchdog to determine when a file has been added to or removed from a
|
121
|
+
directory.
|
122
|
+
|
123
|
+
This is a bit of an unfortunate situation, but the approach we take here is
|
124
|
+
most likely fine as:
|
125
|
+
- The worst thing that can happen taking this approach is a false
|
126
|
+
positive page added/removed notification, which isn't too disastrous
|
127
|
+
and can just be ignored.
|
128
|
+
- It is impossible (that is, I'm fairly certain that the problem is
|
129
|
+
undecidable) to know whether a file created/deleted/moved event
|
130
|
+
corresponds to a legitimate file creation/deletion/move or is part of
|
131
|
+
some sequence of events that results in what the user sees as a file
|
132
|
+
"edit".
|
133
|
+
"""
|
134
|
+
dirfiles = _dirfiles(dir_path, glob_pattern)
|
135
|
+
|
136
|
+
for _ in _retry_dance():
|
137
|
+
new_dirfiles = _dirfiles(dir_path, glob_pattern)
|
138
|
+
if dirfiles == new_dirfiles:
|
139
|
+
break
|
140
|
+
|
141
|
+
dirfiles = new_dirfiles
|
142
|
+
|
143
|
+
return f"{dir_path}+{dirfiles}"
|
144
|
+
|
145
|
+
|
146
|
+
T = TypeVar("T")
|
147
|
+
|
148
|
+
|
149
|
+
def _do_with_retries(
|
150
|
+
orig_fn: Callable[[], T],
|
151
|
+
exception: type[Exception],
|
152
|
+
path: str | Path,
|
153
|
+
) -> T:
|
154
|
+
"""Helper for retrying a function.
|
155
|
+
|
156
|
+
Calls `orig_fn`. If `exception` is raised, retry.
|
157
|
+
|
158
|
+
To use this, just replace things like this...
|
159
|
+
|
160
|
+
result = thing_to_do(file_path, a, b, c)
|
161
|
+
|
162
|
+
...with this:
|
163
|
+
|
164
|
+
result = _do_with_retries(
|
165
|
+
lambda: thing_to_do(file_path, a, b, c),
|
166
|
+
exception: ExceptionThatWillCauseARetry,
|
167
|
+
file_path, # For pretty error message.
|
168
|
+
)
|
169
|
+
"""
|
170
|
+
for i in _retry_dance():
|
171
|
+
try:
|
172
|
+
return orig_fn()
|
173
|
+
except exception:
|
174
|
+
if i >= _MAX_RETRIES - 1:
|
175
|
+
raise
|
176
|
+
else:
|
177
|
+
# Continue with loop to either retry or raise MaxRetriesError.
|
178
|
+
pass
|
179
|
+
|
180
|
+
raise MaxRetriesError(f"Unable to access file or folder: {path}")
|
181
|
+
|
182
|
+
|
183
|
+
def _retry_dance():
|
184
|
+
"""Helper for writing a retry loop.
|
185
|
+
|
186
|
+
This is useful to make sure all our retry loops work the same way. For example,
|
187
|
+
prior to this helper, some loops had time.sleep() *before the first try*, which just
|
188
|
+
slowed things down for no reason.
|
189
|
+
|
190
|
+
Usage:
|
191
|
+
|
192
|
+
for i in _retry_dance():
|
193
|
+
# Do the thing you want to retry automatically.
|
194
|
+
the_thing_worked = do_thing()
|
195
|
+
|
196
|
+
# Don't forget to include a break/return when the thing you're trying to do
|
197
|
+
# works.
|
198
|
+
if the_thing_worked:
|
199
|
+
break
|
200
|
+
"""
|
201
|
+
for i in range(_MAX_RETRIES):
|
202
|
+
yield i
|
203
|
+
time.sleep(_RETRY_WAIT_SECS)
|
204
|
+
|
205
|
+
|
206
|
+
class MaxRetriesError(Error):
|
207
|
+
pass
|
@@ -0,0 +1,13 @@
|
|
1
|
+
# Copyright (c) Streamlit Inc. (2018-2022) Snowflake Inc. (2022-2025)
|
2
|
+
#
|
3
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
4
|
+
# you may not use this file except in compliance with the License.
|
5
|
+
# You may obtain a copy of the License at
|
6
|
+
#
|
7
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
8
|
+
#
|
9
|
+
# Unless required by applicable law or agreed to in writing, software
|
10
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
11
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
12
|
+
# See the License for the specific language governing permissions and
|
13
|
+
# limitations under the License.
|
@@ -0,0 +1,353 @@
|
|
1
|
+
# Copyright (c) Streamlit Inc. (2018-2022) Snowflake Inc. (2022-2025)
|
2
|
+
#
|
3
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
4
|
+
# you may not use this file except in compliance with the License.
|
5
|
+
# You may obtain a copy of the License at
|
6
|
+
#
|
7
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
8
|
+
#
|
9
|
+
# Unless required by applicable law or agreed to in writing, software
|
10
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
11
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
12
|
+
# See the License for the specific language governing permissions and
|
13
|
+
# limitations under the License.
|
14
|
+
|
15
|
+
from __future__ import annotations
|
16
|
+
|
17
|
+
import asyncio
|
18
|
+
import os
|
19
|
+
import signal
|
20
|
+
import sys
|
21
|
+
from typing import Any, Final
|
22
|
+
|
23
|
+
from streamlit import cli_util, config, env_util, file_util, net_util, secrets
|
24
|
+
from streamlit.config import CONFIG_FILENAMES
|
25
|
+
from streamlit.git_util import MIN_GIT_VERSION, GitRepo
|
26
|
+
from streamlit.logger import get_logger
|
27
|
+
from streamlit.watcher import report_watchdog_availability, watch_file
|
28
|
+
from streamlit.web.server import Server, server_address_is_unix_socket, server_util
|
29
|
+
|
30
|
+
_LOGGER: Final = get_logger(__name__)
|
31
|
+
|
32
|
+
|
33
|
+
# The maximum possible total size of a static directory.
|
34
|
+
# We agreed on these limitations for the initial release of static file sharing,
|
35
|
+
# based on security concerns from the SiS and Community Cloud teams
|
36
|
+
MAX_APP_STATIC_FOLDER_SIZE = 1 * 1024 * 1024 * 1024 # 1 GB
|
37
|
+
|
38
|
+
|
39
|
+
def _set_up_signal_handler(server: Server) -> None:
|
40
|
+
_LOGGER.debug("Setting up signal handler")
|
41
|
+
|
42
|
+
def signal_handler(signal_number, stack_frame):
|
43
|
+
# The server will shut down its threads and exit its loop.
|
44
|
+
server.stop()
|
45
|
+
|
46
|
+
signal.signal(signal.SIGTERM, signal_handler)
|
47
|
+
signal.signal(signal.SIGINT, signal_handler)
|
48
|
+
if sys.platform == "win32":
|
49
|
+
signal.signal(signal.SIGBREAK, signal_handler)
|
50
|
+
else:
|
51
|
+
signal.signal(signal.SIGQUIT, signal_handler)
|
52
|
+
|
53
|
+
|
54
|
+
def _fix_sys_path(main_script_path: str) -> None:
|
55
|
+
"""Add the script's folder to the sys path.
|
56
|
+
|
57
|
+
Python normally does this automatically, but since we exec the script
|
58
|
+
ourselves we need to do it instead.
|
59
|
+
"""
|
60
|
+
sys.path.insert(0, os.path.dirname(main_script_path))
|
61
|
+
|
62
|
+
|
63
|
+
def _fix_tornado_crash() -> None:
|
64
|
+
"""Set default asyncio policy to be compatible with Tornado 6.
|
65
|
+
|
66
|
+
Tornado 6 (at least) is not compatible with the default
|
67
|
+
asyncio implementation on Windows. So here we
|
68
|
+
pick the older SelectorEventLoopPolicy when the OS is Windows
|
69
|
+
if the known-incompatible default policy is in use.
|
70
|
+
|
71
|
+
This has to happen as early as possible to make it a low priority and
|
72
|
+
overridable
|
73
|
+
|
74
|
+
See: https://github.com/tornadoweb/tornado/issues/2608
|
75
|
+
|
76
|
+
FIXME: if/when tornado supports the defaults in asyncio,
|
77
|
+
remove and bump tornado requirement for py38
|
78
|
+
"""
|
79
|
+
if env_util.IS_WINDOWS:
|
80
|
+
try:
|
81
|
+
from asyncio import ( # type: ignore[attr-defined]
|
82
|
+
WindowsProactorEventLoopPolicy,
|
83
|
+
WindowsSelectorEventLoopPolicy,
|
84
|
+
)
|
85
|
+
except ImportError:
|
86
|
+
pass
|
87
|
+
# Not affected
|
88
|
+
else:
|
89
|
+
if type(asyncio.get_event_loop_policy()) is WindowsProactorEventLoopPolicy:
|
90
|
+
# WindowsProactorEventLoopPolicy is not compatible with
|
91
|
+
# Tornado 6 fallback to the pre-3.8 default of Selector
|
92
|
+
asyncio.set_event_loop_policy(WindowsSelectorEventLoopPolicy())
|
93
|
+
|
94
|
+
|
95
|
+
def _fix_sys_argv(main_script_path: str, args: list[str]) -> None:
|
96
|
+
"""sys.argv needs to exclude streamlit arguments and parameters
|
97
|
+
and be set to what a user's script may expect.
|
98
|
+
"""
|
99
|
+
import sys
|
100
|
+
|
101
|
+
sys.argv = [main_script_path] + list(args)
|
102
|
+
|
103
|
+
|
104
|
+
def _on_server_start(server: Server) -> None:
|
105
|
+
_maybe_print_old_git_warning(server.main_script_path)
|
106
|
+
_maybe_print_static_folder_warning(server.main_script_path)
|
107
|
+
_print_url(server.is_running_hello)
|
108
|
+
report_watchdog_availability()
|
109
|
+
|
110
|
+
# Load secrets.toml if it exists. If the file doesn't exist, this
|
111
|
+
# function will return without raising an exception. We catch any parse
|
112
|
+
# errors and display them here.
|
113
|
+
try:
|
114
|
+
secrets.load_if_toml_exists()
|
115
|
+
except Exception as ex:
|
116
|
+
_LOGGER.error("Failed to load secrets.toml file", exc_info=ex)
|
117
|
+
|
118
|
+
def maybe_open_browser():
|
119
|
+
if config.get_option("server.headless"):
|
120
|
+
# Don't open browser when in headless mode.
|
121
|
+
return
|
122
|
+
|
123
|
+
if config.is_manually_set("browser.serverAddress"):
|
124
|
+
addr = config.get_option("browser.serverAddress")
|
125
|
+
elif config.is_manually_set("server.address"):
|
126
|
+
if server_address_is_unix_socket():
|
127
|
+
# Don't open browser when server address is an unix socket
|
128
|
+
return
|
129
|
+
addr = config.get_option("server.address")
|
130
|
+
else:
|
131
|
+
addr = "localhost"
|
132
|
+
|
133
|
+
cli_util.open_browser(server_util.get_url(addr))
|
134
|
+
|
135
|
+
# Schedule the browser to open on the main thread.
|
136
|
+
asyncio.get_running_loop().call_soon(maybe_open_browser)
|
137
|
+
|
138
|
+
|
139
|
+
def _fix_pydeck_mapbox_api_warning() -> None:
|
140
|
+
"""Sets MAPBOX_API_KEY environment variable needed for PyDeck otherwise it will throw an exception"""
|
141
|
+
|
142
|
+
os.environ["MAPBOX_API_KEY"] = config.get_option("mapbox.token")
|
143
|
+
|
144
|
+
|
145
|
+
def _maybe_print_static_folder_warning(main_script_path: str) -> None:
|
146
|
+
"""Prints a warning if the static folder is misconfigured."""
|
147
|
+
|
148
|
+
if config.get_option("server.enableStaticServing"):
|
149
|
+
static_folder_path = file_util.get_app_static_dir(main_script_path)
|
150
|
+
if not os.path.isdir(static_folder_path):
|
151
|
+
cli_util.print_to_cli(
|
152
|
+
f"WARNING: Static file serving is enabled, but no static folder found "
|
153
|
+
f"at {static_folder_path}. To disable static file serving, "
|
154
|
+
f"set server.enableStaticServing to false.",
|
155
|
+
fg="yellow",
|
156
|
+
)
|
157
|
+
else:
|
158
|
+
# Raise warning when static folder size is larger than 1 GB
|
159
|
+
static_folder_size = file_util.get_directory_size(static_folder_path)
|
160
|
+
|
161
|
+
if static_folder_size > MAX_APP_STATIC_FOLDER_SIZE:
|
162
|
+
config.set_option("server.enableStaticServing", False)
|
163
|
+
cli_util.print_to_cli(
|
164
|
+
"WARNING: Static folder size is larger than 1GB. "
|
165
|
+
"Static file serving has been disabled.",
|
166
|
+
fg="yellow",
|
167
|
+
)
|
168
|
+
|
169
|
+
|
170
|
+
def _print_url(is_running_hello: bool) -> None:
|
171
|
+
if is_running_hello:
|
172
|
+
title_message = "Welcome to Streamlit. Check out our demo in your browser."
|
173
|
+
else:
|
174
|
+
title_message = "You can now view your Streamlit app in your browser."
|
175
|
+
|
176
|
+
named_urls = []
|
177
|
+
|
178
|
+
if config.is_manually_set("browser.serverAddress"):
|
179
|
+
named_urls = [
|
180
|
+
("URL", server_util.get_url(config.get_option("browser.serverAddress")))
|
181
|
+
]
|
182
|
+
|
183
|
+
elif (
|
184
|
+
config.is_manually_set("server.address") and not server_address_is_unix_socket()
|
185
|
+
):
|
186
|
+
named_urls = [
|
187
|
+
("URL", server_util.get_url(config.get_option("server.address"))),
|
188
|
+
]
|
189
|
+
|
190
|
+
elif server_address_is_unix_socket():
|
191
|
+
named_urls = [
|
192
|
+
("Unix Socket", config.get_option("server.address")),
|
193
|
+
]
|
194
|
+
|
195
|
+
else:
|
196
|
+
named_urls = [
|
197
|
+
("Local URL", server_util.get_url("localhost")),
|
198
|
+
]
|
199
|
+
|
200
|
+
internal_ip = net_util.get_internal_ip()
|
201
|
+
if internal_ip:
|
202
|
+
named_urls.append(("Network URL", server_util.get_url(internal_ip)))
|
203
|
+
|
204
|
+
if config.get_option("server.headless"):
|
205
|
+
external_ip = net_util.get_external_ip()
|
206
|
+
if external_ip:
|
207
|
+
named_urls.append(("External URL", server_util.get_url(external_ip)))
|
208
|
+
|
209
|
+
cli_util.print_to_cli("")
|
210
|
+
cli_util.print_to_cli(" %s" % title_message, fg="blue", bold=True)
|
211
|
+
cli_util.print_to_cli("")
|
212
|
+
|
213
|
+
for url_name, url in named_urls:
|
214
|
+
cli_util.print_to_cli(f" {url_name}: ", nl=False, fg="blue")
|
215
|
+
cli_util.print_to_cli(url, bold=True)
|
216
|
+
|
217
|
+
cli_util.print_to_cli("")
|
218
|
+
|
219
|
+
if is_running_hello:
|
220
|
+
cli_util.print_to_cli(" Ready to create your own Python apps super quickly?")
|
221
|
+
cli_util.print_to_cli(" Head over to ", nl=False)
|
222
|
+
cli_util.print_to_cli("https://docs.streamlit.io", bold=True)
|
223
|
+
cli_util.print_to_cli("")
|
224
|
+
cli_util.print_to_cli(" May you create awesome apps!")
|
225
|
+
cli_util.print_to_cli("")
|
226
|
+
cli_util.print_to_cli("")
|
227
|
+
|
228
|
+
|
229
|
+
def _maybe_print_old_git_warning(main_script_path: str) -> None:
|
230
|
+
"""If our script is running in a Git repo, and we're running a very old
|
231
|
+
Git version, print a warning that Git integration will be unavailable.
|
232
|
+
"""
|
233
|
+
repo = GitRepo(main_script_path)
|
234
|
+
if (
|
235
|
+
not repo.is_valid()
|
236
|
+
and repo.git_version is not None
|
237
|
+
and repo.git_version < MIN_GIT_VERSION
|
238
|
+
):
|
239
|
+
git_version_string = ".".join(str(val) for val in repo.git_version)
|
240
|
+
min_version_string = ".".join(str(val) for val in MIN_GIT_VERSION)
|
241
|
+
cli_util.print_to_cli("")
|
242
|
+
cli_util.print_to_cli(" Git integration is disabled.", fg="yellow", bold=True)
|
243
|
+
cli_util.print_to_cli("")
|
244
|
+
cli_util.print_to_cli(
|
245
|
+
f" Streamlit requires Git {min_version_string} or later, "
|
246
|
+
f"but you have {git_version_string}.",
|
247
|
+
fg="yellow",
|
248
|
+
)
|
249
|
+
cli_util.print_to_cli(
|
250
|
+
" Git is used by Streamlit Cloud (https://streamlit.io/cloud).",
|
251
|
+
fg="yellow",
|
252
|
+
)
|
253
|
+
cli_util.print_to_cli(
|
254
|
+
" To enable this feature, please update Git.", fg="yellow"
|
255
|
+
)
|
256
|
+
|
257
|
+
|
258
|
+
def load_config_options(flag_options: dict[str, Any]) -> None:
|
259
|
+
"""Load config options from config.toml files, then overlay the ones set by
|
260
|
+
flag_options.
|
261
|
+
|
262
|
+
The "streamlit run" command supports passing Streamlit's config options
|
263
|
+
as flags. This function reads through the config options set via flag,
|
264
|
+
massages them, and passes them to get_config_options() so that they
|
265
|
+
overwrite config option defaults and those loaded from config.toml files.
|
266
|
+
|
267
|
+
Parameters
|
268
|
+
----------
|
269
|
+
flag_options : dict[str, Any]
|
270
|
+
A dict of config options where the keys are the CLI flag version of the
|
271
|
+
config option names.
|
272
|
+
"""
|
273
|
+
# We want to filter out two things: values that are None, and values that
|
274
|
+
# are empty tuples. The latter is a special case that indicates that the
|
275
|
+
# no values were provided, and the config should reset to the default
|
276
|
+
options_from_flags = {
|
277
|
+
name.replace("_", "."): val
|
278
|
+
for name, val in flag_options.items()
|
279
|
+
if val is not None and val != ()
|
280
|
+
}
|
281
|
+
|
282
|
+
# Force a reparse of config files (if they exist). The result is cached
|
283
|
+
# for future calls.
|
284
|
+
config.get_config_options(force_reparse=True, options_from_flags=options_from_flags)
|
285
|
+
|
286
|
+
|
287
|
+
def _install_config_watchers(flag_options: dict[str, Any]) -> None:
|
288
|
+
def on_config_changed(_path):
|
289
|
+
load_config_options(flag_options)
|
290
|
+
|
291
|
+
for filename in CONFIG_FILENAMES:
|
292
|
+
if os.path.exists(filename):
|
293
|
+
watch_file(filename, on_config_changed)
|
294
|
+
|
295
|
+
|
296
|
+
def run(
|
297
|
+
main_script_path: str,
|
298
|
+
is_hello: bool,
|
299
|
+
args: list[str],
|
300
|
+
flag_options: dict[str, Any],
|
301
|
+
*,
|
302
|
+
stop_immediately_for_testing: bool = False,
|
303
|
+
) -> None:
|
304
|
+
"""Run a script in a separate thread and start a server for the app.
|
305
|
+
|
306
|
+
This starts a blocking asyncio eventloop.
|
307
|
+
"""
|
308
|
+
_fix_sys_path(main_script_path)
|
309
|
+
_fix_tornado_crash()
|
310
|
+
_fix_sys_argv(main_script_path, args)
|
311
|
+
_fix_pydeck_mapbox_api_warning()
|
312
|
+
_install_config_watchers(flag_options)
|
313
|
+
|
314
|
+
# Create the server. It won't start running yet.
|
315
|
+
server = Server(main_script_path, is_hello)
|
316
|
+
|
317
|
+
async def run_server() -> None:
|
318
|
+
# Start the server
|
319
|
+
await server.start()
|
320
|
+
_on_server_start(server)
|
321
|
+
|
322
|
+
# Install a signal handler that will shut down the server
|
323
|
+
# and close all our threads
|
324
|
+
_set_up_signal_handler(server)
|
325
|
+
|
326
|
+
# return immediately if we're testing the server start
|
327
|
+
if stop_immediately_for_testing:
|
328
|
+
_LOGGER.debug("Stopping server immediately for testing")
|
329
|
+
server.stop()
|
330
|
+
|
331
|
+
# Wait until `Server.stop` is called, either by our signal handler, or
|
332
|
+
# by a debug websocket session.
|
333
|
+
await server.stopped
|
334
|
+
|
335
|
+
# Run the server. This function will not return until the server is shut down.
|
336
|
+
# FIX RuntimeError: asyncio.run() cannot be called from a running event loop on Python 3.10.16
|
337
|
+
# asyncio.run(run_server())
|
338
|
+
|
339
|
+
# Define a main function to handle the event loop logic
|
340
|
+
async def main():
|
341
|
+
await run_server()
|
342
|
+
|
343
|
+
try:
|
344
|
+
# Check if we're already in an event loop
|
345
|
+
if asyncio.get_running_loop().is_running():
|
346
|
+
# Use `asyncio.create_task` if we're in an async context
|
347
|
+
asyncio.create_task(main())
|
348
|
+
else:
|
349
|
+
# Otherwise, use `asyncio.run`
|
350
|
+
asyncio.run(main())
|
351
|
+
except RuntimeError:
|
352
|
+
# get_running_loop throws RuntimeError if no running event loop
|
353
|
+
asyncio.run(main())
|
@@ -0,0 +1,38 @@
|
|
1
|
+
# Copyright (c) Streamlit Inc. (2018-2022) Snowflake Inc. (2022-2025)
|
2
|
+
#
|
3
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
4
|
+
# you may not use this file except in compliance with the License.
|
5
|
+
# You may obtain a copy of the License at
|
6
|
+
#
|
7
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
8
|
+
#
|
9
|
+
# Unless required by applicable law or agreed to in writing, software
|
10
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
11
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
12
|
+
# See the License for the specific language governing permissions and
|
13
|
+
# limitations under the License.
|
14
|
+
|
15
|
+
from __future__ import annotations
|
16
|
+
|
17
|
+
from typing import TYPE_CHECKING
|
18
|
+
|
19
|
+
from streamlit.runtime.caching.storage.local_disk_cache_storage import (
|
20
|
+
LocalDiskCacheStorageManager,
|
21
|
+
)
|
22
|
+
|
23
|
+
if TYPE_CHECKING:
|
24
|
+
from streamlit.runtime.caching.storage import CacheStorageManager
|
25
|
+
|
26
|
+
|
27
|
+
def create_default_cache_storage_manager() -> CacheStorageManager:
|
28
|
+
"""
|
29
|
+
Get the cache storage manager.
|
30
|
+
It would be used both in server.py and in cli.py to have unified cache storage
|
31
|
+
|
32
|
+
Returns
|
33
|
+
-------
|
34
|
+
CacheStorageManager
|
35
|
+
The cache storage manager.
|
36
|
+
|
37
|
+
"""
|
38
|
+
return LocalDiskCacheStorageManager()
|