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,233 @@
|
|
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 os
|
18
|
+
import sys
|
19
|
+
from pathlib import Path
|
20
|
+
from typing import TYPE_CHECKING, Any, Callable, Final, NamedTuple
|
21
|
+
|
22
|
+
from streamlit import config, file_util
|
23
|
+
from streamlit.logger import get_logger
|
24
|
+
from streamlit.watcher.folder_black_list import FolderBlackList
|
25
|
+
from streamlit.watcher.path_watcher import (
|
26
|
+
NoOpPathWatcher,
|
27
|
+
get_default_path_watcher_class,
|
28
|
+
)
|
29
|
+
|
30
|
+
if TYPE_CHECKING:
|
31
|
+
from types import ModuleType
|
32
|
+
|
33
|
+
from streamlit.runtime.pages_manager import PagesManager
|
34
|
+
|
35
|
+
_LOGGER: Final = get_logger(__name__)
|
36
|
+
|
37
|
+
|
38
|
+
class WatchedModule(NamedTuple):
|
39
|
+
watcher: Any
|
40
|
+
module_name: Any
|
41
|
+
|
42
|
+
|
43
|
+
# This needs to be initialized lazily to avoid calling config.get_option() and
|
44
|
+
# thus initializing config options when this file is first imported.
|
45
|
+
PathWatcher = None
|
46
|
+
|
47
|
+
|
48
|
+
class LocalSourcesWatcher:
|
49
|
+
def __init__(self, pages_manager: PagesManager):
|
50
|
+
self._pages_manager = pages_manager
|
51
|
+
self._main_script_path = os.path.abspath(self._pages_manager.main_script_path)
|
52
|
+
self._script_folder = os.path.dirname(self._main_script_path)
|
53
|
+
self._on_file_changed: list[Callable[[str], None]] = []
|
54
|
+
self._is_closed = False
|
55
|
+
self._cached_sys_modules: set[str] = set()
|
56
|
+
|
57
|
+
# Blacklist for folders that should not be watched
|
58
|
+
self._folder_black_list = FolderBlackList(
|
59
|
+
config.get_option("server.folderWatchBlacklist")
|
60
|
+
)
|
61
|
+
|
62
|
+
self._watched_modules: dict[str, WatchedModule] = {}
|
63
|
+
self._watched_pages: set[str] = set()
|
64
|
+
|
65
|
+
self.update_watched_pages()
|
66
|
+
|
67
|
+
def update_watched_pages(self) -> None:
|
68
|
+
old_page_paths = self._watched_pages.copy()
|
69
|
+
new_pages_paths: set[str] = set()
|
70
|
+
|
71
|
+
for page_info in self._pages_manager.get_pages().values():
|
72
|
+
if not page_info["script_path"]:
|
73
|
+
continue
|
74
|
+
|
75
|
+
new_pages_paths.add(page_info["script_path"])
|
76
|
+
if page_info["script_path"] not in self._watched_pages:
|
77
|
+
self._register_watcher(
|
78
|
+
page_info["script_path"],
|
79
|
+
module_name=None,
|
80
|
+
)
|
81
|
+
|
82
|
+
for old_page_path in old_page_paths:
|
83
|
+
# Only remove pages that are no longer valid files
|
84
|
+
if old_page_path not in new_pages_paths and not os.path.isfile(
|
85
|
+
old_page_path
|
86
|
+
):
|
87
|
+
self._deregister_watcher(old_page_path)
|
88
|
+
self._watched_pages.remove(old_page_path)
|
89
|
+
|
90
|
+
self._watched_pages = self._watched_pages.union(new_pages_paths)
|
91
|
+
|
92
|
+
def register_file_change_callback(self, cb: Callable[[str], None]) -> None:
|
93
|
+
self._on_file_changed.append(cb)
|
94
|
+
|
95
|
+
def on_file_changed(self, filepath):
|
96
|
+
if filepath not in self._watched_modules:
|
97
|
+
_LOGGER.error("Received event for non-watched file: %s", filepath)
|
98
|
+
return
|
99
|
+
|
100
|
+
# Workaround:
|
101
|
+
# Delete all watched modules so we can guarantee changes to the
|
102
|
+
# updated module are reflected on reload.
|
103
|
+
#
|
104
|
+
# In principle, for reloading a given module, we only need to unload
|
105
|
+
# the module itself and all of the modules which import it (directly
|
106
|
+
# or indirectly) such that when we exec the application code, the
|
107
|
+
# changes are reloaded and reflected in the running application.
|
108
|
+
#
|
109
|
+
# However, determining all import paths for a given loaded module is
|
110
|
+
# non-trivial, and so as a workaround we simply unload all watched
|
111
|
+
# modules.
|
112
|
+
for wm in self._watched_modules.values():
|
113
|
+
if wm.module_name is not None and wm.module_name in sys.modules:
|
114
|
+
del sys.modules[wm.module_name]
|
115
|
+
|
116
|
+
for cb in self._on_file_changed:
|
117
|
+
cb(filepath)
|
118
|
+
|
119
|
+
def close(self):
|
120
|
+
for wm in self._watched_modules.values():
|
121
|
+
wm.watcher.close()
|
122
|
+
self._watched_modules = {}
|
123
|
+
self._watched_pages = set()
|
124
|
+
self._is_closed = True
|
125
|
+
|
126
|
+
def _register_watcher(self, filepath, module_name):
|
127
|
+
global PathWatcher
|
128
|
+
if PathWatcher is None:
|
129
|
+
PathWatcher = get_default_path_watcher_class()
|
130
|
+
|
131
|
+
if PathWatcher is NoOpPathWatcher:
|
132
|
+
return
|
133
|
+
|
134
|
+
try:
|
135
|
+
wm = WatchedModule(
|
136
|
+
watcher=PathWatcher(filepath, self.on_file_changed),
|
137
|
+
module_name=module_name,
|
138
|
+
)
|
139
|
+
except PermissionError:
|
140
|
+
# If you don't have permission to read this file, don't even add it
|
141
|
+
# to watchers.
|
142
|
+
return
|
143
|
+
|
144
|
+
self._watched_modules[filepath] = wm
|
145
|
+
|
146
|
+
def _deregister_watcher(self, filepath):
|
147
|
+
if filepath not in self._watched_modules:
|
148
|
+
return
|
149
|
+
|
150
|
+
if filepath == self._main_script_path:
|
151
|
+
return
|
152
|
+
|
153
|
+
wm = self._watched_modules[filepath]
|
154
|
+
wm.watcher.close()
|
155
|
+
del self._watched_modules[filepath]
|
156
|
+
|
157
|
+
def _file_is_new(self, filepath):
|
158
|
+
return filepath not in self._watched_modules
|
159
|
+
|
160
|
+
def _file_should_be_watched(self, filepath):
|
161
|
+
# Using short circuiting for performance.
|
162
|
+
return self._file_is_new(filepath) and (
|
163
|
+
file_util.file_is_in_folder_glob(filepath, self._script_folder)
|
164
|
+
or file_util.file_in_pythonpath(filepath)
|
165
|
+
)
|
166
|
+
|
167
|
+
def update_watched_modules(self):
|
168
|
+
if self._is_closed:
|
169
|
+
return
|
170
|
+
|
171
|
+
if set(sys.modules) != self._cached_sys_modules:
|
172
|
+
modules_paths = {
|
173
|
+
name: self._exclude_blacklisted_paths(get_module_paths(module))
|
174
|
+
for name, module in dict(sys.modules).items()
|
175
|
+
}
|
176
|
+
self._cached_sys_modules = set(sys.modules)
|
177
|
+
self._register_necessary_watchers(modules_paths)
|
178
|
+
|
179
|
+
def _register_necessary_watchers(self, module_paths: dict[str, set[str]]) -> None:
|
180
|
+
for name, paths in module_paths.items():
|
181
|
+
for path in paths:
|
182
|
+
if self._file_should_be_watched(path):
|
183
|
+
self._register_watcher(str(Path(path).resolve()), name)
|
184
|
+
|
185
|
+
def _exclude_blacklisted_paths(self, paths: set[str]) -> set[str]:
|
186
|
+
return {p for p in paths if not self._folder_black_list.is_blacklisted(p)}
|
187
|
+
|
188
|
+
|
189
|
+
def get_module_paths(module: ModuleType) -> set[str]:
|
190
|
+
paths_extractors = [
|
191
|
+
# https://docs.python.org/3/reference/datamodel.html
|
192
|
+
# __file__ is the pathname of the file from which the module was loaded
|
193
|
+
# if it was loaded from a file.
|
194
|
+
# The __file__ attribute may be missing for certain types of modules
|
195
|
+
lambda m: [m.__file__],
|
196
|
+
# https://docs.python.org/3/reference/import.html#__spec__
|
197
|
+
# The __spec__ attribute is set to the module spec that was used
|
198
|
+
# when importing the module. one exception is __main__,
|
199
|
+
# where __spec__ is set to None in some cases.
|
200
|
+
# https://www.python.org/dev/peps/pep-0451/#id16
|
201
|
+
# "origin" in an import context means the system
|
202
|
+
# (or resource within a system) from which a module originates
|
203
|
+
# ... It is up to the loader to decide on how to interpret
|
204
|
+
# and use a module's origin, if at all.
|
205
|
+
lambda m: [m.__spec__.origin],
|
206
|
+
# https://www.python.org/dev/peps/pep-0420/
|
207
|
+
# Handling of "namespace packages" in which the __path__ attribute
|
208
|
+
# is a _NamespacePath object with a _path attribute containing
|
209
|
+
# the various paths of the package.
|
210
|
+
lambda m: list(m.__path__._path),
|
211
|
+
]
|
212
|
+
|
213
|
+
all_paths = set()
|
214
|
+
for extract_paths in paths_extractors:
|
215
|
+
potential_paths = []
|
216
|
+
try:
|
217
|
+
potential_paths = extract_paths(module)
|
218
|
+
except AttributeError:
|
219
|
+
# Some modules might not have __file__ or __spec__ attributes.
|
220
|
+
pass
|
221
|
+
except Exception:
|
222
|
+
_LOGGER.warning(
|
223
|
+
f"Examining the path of {module.__name__} raised:", exc_info=True
|
224
|
+
)
|
225
|
+
|
226
|
+
all_paths.update(
|
227
|
+
[os.path.abspath(str(p)) for p in potential_paths if _is_valid_path(p)]
|
228
|
+
)
|
229
|
+
return all_paths
|
230
|
+
|
231
|
+
|
232
|
+
def _is_valid_path(path: str | None) -> bool:
|
233
|
+
return isinstance(path, str) and (os.path.isfile(path) or os.path.isdir(path))
|
@@ -0,0 +1,185 @@
|
|
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 os
|
18
|
+
from typing import Callable, Union
|
19
|
+
|
20
|
+
import streamlit.watcher
|
21
|
+
from streamlit import cli_util, config, env_util
|
22
|
+
from streamlit.watcher.polling_path_watcher import PollingPathWatcher
|
23
|
+
|
24
|
+
|
25
|
+
# local_sources_watcher.py caches the return value of
|
26
|
+
# get_default_path_watcher_class(), so it needs to differentiate between the
|
27
|
+
# cases where it:
|
28
|
+
# 1. has yet to call get_default_path_watcher_class()
|
29
|
+
# 2. has called get_default_path_watcher_class(), which returned that no
|
30
|
+
# path watcher should be installed.
|
31
|
+
# This forces us to define this stub class since the cached value equaling
|
32
|
+
# None corresponds to case 1 above.
|
33
|
+
class NoOpPathWatcher:
|
34
|
+
def __init__(
|
35
|
+
self,
|
36
|
+
_path_str: str,
|
37
|
+
_on_changed: Callable[[str], None],
|
38
|
+
*, # keyword-only arguments:
|
39
|
+
glob_pattern: str | None = None,
|
40
|
+
allow_nonexistent: bool = False,
|
41
|
+
):
|
42
|
+
pass
|
43
|
+
|
44
|
+
|
45
|
+
# EventBasedPathWatcher will be a stub and have no functional
|
46
|
+
# implementation if its import failed (due to missing watchdog module),
|
47
|
+
# so we can't reference it directly in this type.
|
48
|
+
PathWatcherType = Union[
|
49
|
+
type["streamlit.watcher.event_based_path_watcher.EventBasedPathWatcher"],
|
50
|
+
type[PollingPathWatcher],
|
51
|
+
type[NoOpPathWatcher],
|
52
|
+
]
|
53
|
+
|
54
|
+
|
55
|
+
def _is_watchdog_available() -> bool:
|
56
|
+
"""Check if the watchdog module is installed."""
|
57
|
+
try:
|
58
|
+
import watchdog # noqa: F401
|
59
|
+
|
60
|
+
return True
|
61
|
+
except ImportError:
|
62
|
+
return False
|
63
|
+
|
64
|
+
|
65
|
+
def report_watchdog_availability():
|
66
|
+
if (
|
67
|
+
config.get_option("server.fileWatcherType") not in ["poll", "none"]
|
68
|
+
and not _is_watchdog_available()
|
69
|
+
):
|
70
|
+
msg = "\n $ xcode-select --install" if env_util.IS_DARWIN else ""
|
71
|
+
|
72
|
+
cli_util.print_to_cli(
|
73
|
+
" %s" % "For better performance, install the Watchdog module:",
|
74
|
+
fg="blue",
|
75
|
+
bold=True,
|
76
|
+
)
|
77
|
+
cli_util.print_to_cli(
|
78
|
+
"""%s
|
79
|
+
$ pip install watchdog
|
80
|
+
"""
|
81
|
+
% msg
|
82
|
+
)
|
83
|
+
|
84
|
+
|
85
|
+
def _watch_path(
|
86
|
+
path: str,
|
87
|
+
on_path_changed: Callable[[str], None],
|
88
|
+
watcher_type: str | None = None,
|
89
|
+
*, # keyword-only arguments:
|
90
|
+
glob_pattern: str | None = None,
|
91
|
+
allow_nonexistent: bool = False,
|
92
|
+
) -> bool:
|
93
|
+
"""Create a PathWatcher for the given path if we have a viable
|
94
|
+
PathWatcher class.
|
95
|
+
|
96
|
+
Parameters
|
97
|
+
----------
|
98
|
+
path
|
99
|
+
Path to watch.
|
100
|
+
on_path_changed
|
101
|
+
Function that's called when the path changes.
|
102
|
+
watcher_type
|
103
|
+
Optional watcher_type string. If None, it will default to the
|
104
|
+
'server.fileWatcherType` config option.
|
105
|
+
glob_pattern
|
106
|
+
Optional glob pattern to use when watching a directory. If set, only
|
107
|
+
files matching the pattern will be counted as being created/deleted
|
108
|
+
within the watched directory.
|
109
|
+
allow_nonexistent
|
110
|
+
If True, allow the file or directory at the given path to be
|
111
|
+
nonexistent.
|
112
|
+
|
113
|
+
Returns
|
114
|
+
-------
|
115
|
+
bool
|
116
|
+
True if the path is being watched, or False if we have no
|
117
|
+
PathWatcher class.
|
118
|
+
"""
|
119
|
+
if watcher_type is None:
|
120
|
+
watcher_type = config.get_option("server.fileWatcherType")
|
121
|
+
|
122
|
+
watcher_class = get_path_watcher_class(watcher_type)
|
123
|
+
if watcher_class is NoOpPathWatcher:
|
124
|
+
return False
|
125
|
+
|
126
|
+
watcher_class(
|
127
|
+
path,
|
128
|
+
on_path_changed,
|
129
|
+
glob_pattern=glob_pattern,
|
130
|
+
allow_nonexistent=allow_nonexistent,
|
131
|
+
)
|
132
|
+
return True
|
133
|
+
|
134
|
+
|
135
|
+
def watch_file(
|
136
|
+
path: str,
|
137
|
+
on_file_changed: Callable[[str], None],
|
138
|
+
watcher_type: str | None = None,
|
139
|
+
) -> bool:
|
140
|
+
return _watch_path(path, on_file_changed, watcher_type)
|
141
|
+
|
142
|
+
|
143
|
+
def watch_dir(
|
144
|
+
path: str,
|
145
|
+
on_dir_changed: Callable[[str], None],
|
146
|
+
watcher_type: str | None = None,
|
147
|
+
*, # keyword-only arguments:
|
148
|
+
glob_pattern: str | None = None,
|
149
|
+
allow_nonexistent: bool = False,
|
150
|
+
) -> bool:
|
151
|
+
# Add a trailing slash to the path to ensure
|
152
|
+
# that its interpreted as a directory.
|
153
|
+
path = os.path.join(path, "")
|
154
|
+
|
155
|
+
return _watch_path(
|
156
|
+
path,
|
157
|
+
on_dir_changed,
|
158
|
+
watcher_type,
|
159
|
+
glob_pattern=glob_pattern,
|
160
|
+
allow_nonexistent=allow_nonexistent,
|
161
|
+
)
|
162
|
+
|
163
|
+
|
164
|
+
def get_default_path_watcher_class() -> PathWatcherType:
|
165
|
+
"""Return the class to use for path changes notifications, based on the
|
166
|
+
server.fileWatcherType config option.
|
167
|
+
"""
|
168
|
+
return get_path_watcher_class(config.get_option("server.fileWatcherType"))
|
169
|
+
|
170
|
+
|
171
|
+
def get_path_watcher_class(watcher_type: str) -> PathWatcherType:
|
172
|
+
"""Return the PathWatcher class that corresponds to the given watcher_type
|
173
|
+
string. Acceptable values are 'auto', 'watchdog', 'poll' and 'none'.
|
174
|
+
"""
|
175
|
+
if watcher_type in {"watchdog", "auto"} and _is_watchdog_available():
|
176
|
+
# Lazy-import this module to prevent unnecessary imports of the watchdog package.
|
177
|
+
from streamlit.watcher.event_based_path_watcher import EventBasedPathWatcher
|
178
|
+
|
179
|
+
return EventBasedPathWatcher
|
180
|
+
elif watcher_type == "auto":
|
181
|
+
return PollingPathWatcher
|
182
|
+
elif watcher_type == "poll":
|
183
|
+
return PollingPathWatcher
|
184
|
+
else:
|
185
|
+
return NoOpPathWatcher
|
@@ -0,0 +1,124 @@
|
|
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 class that watches a given path via polling."""
|
16
|
+
|
17
|
+
from __future__ import annotations
|
18
|
+
|
19
|
+
import time
|
20
|
+
from concurrent.futures import ThreadPoolExecutor
|
21
|
+
from typing import Callable, Final
|
22
|
+
|
23
|
+
from streamlit.logger import get_logger
|
24
|
+
from streamlit.util import repr_
|
25
|
+
from streamlit.watcher import util
|
26
|
+
|
27
|
+
_LOGGER: Final = get_logger(__name__)
|
28
|
+
|
29
|
+
_MAX_WORKERS: Final = 4
|
30
|
+
_POLLING_PERIOD_SECS: Final = 0.2
|
31
|
+
|
32
|
+
|
33
|
+
class PollingPathWatcher:
|
34
|
+
"""Watches a path on disk via a polling loop."""
|
35
|
+
|
36
|
+
_executor = ThreadPoolExecutor(max_workers=_MAX_WORKERS)
|
37
|
+
|
38
|
+
@staticmethod
|
39
|
+
def close_all() -> None:
|
40
|
+
"""Close top-level watcher object.
|
41
|
+
|
42
|
+
This is a no-op, and exists for interface parity with
|
43
|
+
EventBasedPathWatcher.
|
44
|
+
"""
|
45
|
+
_LOGGER.debug("Watcher closed")
|
46
|
+
|
47
|
+
def __init__(
|
48
|
+
self,
|
49
|
+
path: str,
|
50
|
+
on_changed: Callable[[str], None],
|
51
|
+
*, # keyword-only arguments:
|
52
|
+
glob_pattern: str | None = None,
|
53
|
+
allow_nonexistent: bool = False,
|
54
|
+
) -> None:
|
55
|
+
"""Constructor.
|
56
|
+
|
57
|
+
You do not need to retain a reference to a PollingPathWatcher to
|
58
|
+
prevent it from being garbage collected. (The global _executor object
|
59
|
+
retains references to all active instances.)
|
60
|
+
"""
|
61
|
+
# TODO(vdonato): Modernize this by switching to pathlib.
|
62
|
+
self._path = path
|
63
|
+
self._on_changed = on_changed
|
64
|
+
|
65
|
+
self._glob_pattern = glob_pattern
|
66
|
+
self._allow_nonexistent = allow_nonexistent
|
67
|
+
|
68
|
+
self._active = True
|
69
|
+
|
70
|
+
self._modification_time = util.path_modification_time(
|
71
|
+
self._path, self._allow_nonexistent
|
72
|
+
)
|
73
|
+
self._md5 = util.calc_md5_with_blocking_retries(
|
74
|
+
self._path,
|
75
|
+
glob_pattern=self._glob_pattern,
|
76
|
+
allow_nonexistent=self._allow_nonexistent,
|
77
|
+
)
|
78
|
+
self._schedule()
|
79
|
+
|
80
|
+
def __repr__(self) -> str:
|
81
|
+
return repr_(self)
|
82
|
+
|
83
|
+
def _schedule(self) -> None:
|
84
|
+
def task():
|
85
|
+
time.sleep(_POLLING_PERIOD_SECS)
|
86
|
+
self._check_if_path_changed()
|
87
|
+
|
88
|
+
PollingPathWatcher._executor.submit(task)
|
89
|
+
|
90
|
+
def _check_if_path_changed(self) -> None:
|
91
|
+
if not self._active:
|
92
|
+
# Don't call self._schedule()
|
93
|
+
return
|
94
|
+
|
95
|
+
modification_time = util.path_modification_time(
|
96
|
+
self._path, self._allow_nonexistent
|
97
|
+
)
|
98
|
+
# We add modification_time != 0.0 check since on some file systems (s3fs/fuse)
|
99
|
+
# modification_time is always 0.0 because of file system limitations.
|
100
|
+
if modification_time != 0.0 and modification_time <= self._modification_time:
|
101
|
+
self._schedule()
|
102
|
+
return
|
103
|
+
|
104
|
+
self._modification_time = modification_time
|
105
|
+
|
106
|
+
md5 = util.calc_md5_with_blocking_retries(
|
107
|
+
self._path,
|
108
|
+
glob_pattern=self._glob_pattern,
|
109
|
+
allow_nonexistent=self._allow_nonexistent,
|
110
|
+
)
|
111
|
+
if md5 == self._md5:
|
112
|
+
self._schedule()
|
113
|
+
return
|
114
|
+
|
115
|
+
self._md5 = md5
|
116
|
+
|
117
|
+
_LOGGER.debug("Change detected: %s", self._path)
|
118
|
+
self._on_changed(self._path)
|
119
|
+
|
120
|
+
self._schedule()
|
121
|
+
|
122
|
+
def close(self) -> None:
|
123
|
+
"""Stop watching the file system."""
|
124
|
+
self._active = False
|