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
streamlit/version.py
ADDED
@@ -0,0 +1,18 @@
|
|
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 importlib.metadata import version as _version
|
16
|
+
from typing import Final
|
17
|
+
|
18
|
+
STREAMLIT_VERSION_STRING: Final[str] = _version("streamlit-nightly")
|
@@ -0,0 +1,28 @@
|
|
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
|
+
|
16
|
+
from streamlit.watcher.local_sources_watcher import LocalSourcesWatcher
|
17
|
+
from streamlit.watcher.path_watcher import (
|
18
|
+
report_watchdog_availability,
|
19
|
+
watch_dir,
|
20
|
+
watch_file,
|
21
|
+
)
|
22
|
+
|
23
|
+
__all__ = [
|
24
|
+
"LocalSourcesWatcher",
|
25
|
+
"report_watchdog_availability",
|
26
|
+
"watch_dir",
|
27
|
+
"watch_file",
|
28
|
+
]
|
@@ -0,0 +1,406 @@
|
|
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
|
+
"""Declares the EventBasedPathWatcher class, which watches given paths in the file system.
|
16
|
+
|
17
|
+
How these classes work together
|
18
|
+
-------------------------------
|
19
|
+
|
20
|
+
- EventBasedPathWatcher : each instance of this is able to watch a single
|
21
|
+
file or directory at a given path so long as there's a browser interested in
|
22
|
+
it. This uses _MultiPathWatcher to watch paths.
|
23
|
+
|
24
|
+
- _MultiPathWatcher : singleton that watches multiple paths. It does this by
|
25
|
+
holding a watchdog.observer.Observer object, and manages several
|
26
|
+
_FolderEventHandler instances. This creates _FolderEventHandlers as needed,
|
27
|
+
if the required folder is not already being watched. And it also tells
|
28
|
+
existing _FolderEventHandlers which paths it should be watching for.
|
29
|
+
|
30
|
+
- _FolderEventHandler : event handler for when a folder is modified. You can
|
31
|
+
register paths in that folder that you're interested in. Then this object
|
32
|
+
listens to folder events, sees if registered paths changed, and fires
|
33
|
+
callbacks if so.
|
34
|
+
|
35
|
+
This module is lazy-loaded and used only if watchdog is installed.
|
36
|
+
"""
|
37
|
+
|
38
|
+
from __future__ import annotations
|
39
|
+
|
40
|
+
import os
|
41
|
+
import threading
|
42
|
+
from typing import TYPE_CHECKING, Callable, Final, cast
|
43
|
+
|
44
|
+
from blinker import ANY, Signal
|
45
|
+
from typing_extensions import Self
|
46
|
+
from watchdog import events
|
47
|
+
from watchdog.observers import Observer
|
48
|
+
|
49
|
+
from streamlit.logger import get_logger
|
50
|
+
from streamlit.util import repr_
|
51
|
+
from streamlit.watcher import util
|
52
|
+
|
53
|
+
if TYPE_CHECKING:
|
54
|
+
from watchdog.observers.api import ObservedWatch
|
55
|
+
|
56
|
+
_LOGGER: Final = get_logger(__name__)
|
57
|
+
|
58
|
+
|
59
|
+
def _get_abs_folder_path(path: str) -> str:
|
60
|
+
"""Get the absolute folder path for a given path.
|
61
|
+
|
62
|
+
If the path is a directory, return the absolute path.
|
63
|
+
Otherwise, return the absolute path of the parent directory.
|
64
|
+
"""
|
65
|
+
return os.path.abspath(path if os.path.isdir(path) else os.path.dirname(path))
|
66
|
+
|
67
|
+
|
68
|
+
class EventBasedPathWatcher:
|
69
|
+
"""Watches a single path on disk using watchdog"""
|
70
|
+
|
71
|
+
@staticmethod
|
72
|
+
def close_all() -> None:
|
73
|
+
"""Close the _MultiPathWatcher singleton."""
|
74
|
+
path_watcher = _MultiPathWatcher.get_singleton()
|
75
|
+
path_watcher.close()
|
76
|
+
_LOGGER.debug("Watcher closed")
|
77
|
+
|
78
|
+
def __init__(
|
79
|
+
self,
|
80
|
+
path: str,
|
81
|
+
on_changed: Callable[[str], None],
|
82
|
+
*, # keyword-only arguments:
|
83
|
+
glob_pattern: str | None = None,
|
84
|
+
allow_nonexistent: bool = False,
|
85
|
+
) -> None:
|
86
|
+
"""Constructor for EventBasedPathWatchers.
|
87
|
+
|
88
|
+
Parameters
|
89
|
+
----------
|
90
|
+
path : str
|
91
|
+
The path to watch.
|
92
|
+
on_changed : Callable[[str], None]
|
93
|
+
Callback to call when the path changes.
|
94
|
+
glob_pattern : str or None
|
95
|
+
A glob pattern to filter the files in a directory that should be
|
96
|
+
watched. Only relevant when creating an EventBasedPathWatcher on a
|
97
|
+
directory.
|
98
|
+
allow_nonexistent : bool
|
99
|
+
If True, the watcher will not raise an exception if the path does
|
100
|
+
not exist. This can be used to watch for the creation of a file or
|
101
|
+
directory at a given path.
|
102
|
+
"""
|
103
|
+
self._path = os.path.abspath(path)
|
104
|
+
self._on_changed = on_changed
|
105
|
+
|
106
|
+
path_watcher = _MultiPathWatcher.get_singleton()
|
107
|
+
path_watcher.watch_path(
|
108
|
+
self._path,
|
109
|
+
on_changed,
|
110
|
+
glob_pattern=glob_pattern,
|
111
|
+
allow_nonexistent=allow_nonexistent,
|
112
|
+
)
|
113
|
+
_LOGGER.debug("Watcher created for %s", self._path)
|
114
|
+
|
115
|
+
def __repr__(self) -> str:
|
116
|
+
return repr_(self)
|
117
|
+
|
118
|
+
def close(self) -> None:
|
119
|
+
"""Stop watching the path corresponding to this EventBasedPathWatcher."""
|
120
|
+
path_watcher = _MultiPathWatcher.get_singleton()
|
121
|
+
path_watcher.stop_watching_path(self._path, self._on_changed)
|
122
|
+
|
123
|
+
|
124
|
+
class _MultiPathWatcher:
|
125
|
+
"""Watches multiple paths."""
|
126
|
+
|
127
|
+
_singleton: _MultiPathWatcher | None = None
|
128
|
+
|
129
|
+
@classmethod
|
130
|
+
def get_singleton(cls) -> _MultiPathWatcher:
|
131
|
+
"""Return the singleton _MultiPathWatcher object.
|
132
|
+
|
133
|
+
Instantiates one if necessary.
|
134
|
+
"""
|
135
|
+
if cls._singleton is None:
|
136
|
+
_LOGGER.debug("No singleton. Registering one.")
|
137
|
+
_MultiPathWatcher()
|
138
|
+
|
139
|
+
return cast("_MultiPathWatcher", _MultiPathWatcher._singleton)
|
140
|
+
|
141
|
+
# Don't allow constructor to be called more than once.
|
142
|
+
def __new__(cls) -> Self:
|
143
|
+
"""Constructor."""
|
144
|
+
if _MultiPathWatcher._singleton is not None:
|
145
|
+
raise RuntimeError("Use .get_singleton() instead")
|
146
|
+
return super().__new__(cls)
|
147
|
+
|
148
|
+
def __init__(self) -> None:
|
149
|
+
"""Constructor."""
|
150
|
+
_MultiPathWatcher._singleton = self
|
151
|
+
|
152
|
+
# Map of folder_to_watch -> _FolderEventHandler.
|
153
|
+
self._folder_handlers: dict[str, _FolderEventHandler] = {}
|
154
|
+
|
155
|
+
# Used for mutation of _folder_handlers dict
|
156
|
+
self._lock = threading.Lock()
|
157
|
+
|
158
|
+
# The Observer object from the Watchdog module. Since this class is
|
159
|
+
# only instantiated once, we only have a single Observer in Streamlit,
|
160
|
+
# and it's in charge of watching all paths we're interested in.
|
161
|
+
self._observer = Observer()
|
162
|
+
self._observer.start() # Start observer thread.
|
163
|
+
|
164
|
+
def __repr__(self) -> str:
|
165
|
+
return repr_(self)
|
166
|
+
|
167
|
+
def watch_path(
|
168
|
+
self,
|
169
|
+
path: str,
|
170
|
+
callback: Callable[[str], None],
|
171
|
+
*, # keyword-only arguments:
|
172
|
+
glob_pattern: str | None = None,
|
173
|
+
allow_nonexistent: bool = False,
|
174
|
+
) -> None:
|
175
|
+
"""Start watching a path."""
|
176
|
+
folder_path = _get_abs_folder_path(path)
|
177
|
+
|
178
|
+
with self._lock:
|
179
|
+
folder_handler = self._folder_handlers.get(folder_path)
|
180
|
+
|
181
|
+
if folder_handler is None:
|
182
|
+
folder_handler = _FolderEventHandler()
|
183
|
+
self._folder_handlers[folder_path] = folder_handler
|
184
|
+
|
185
|
+
folder_handler.watch = self._observer.schedule(
|
186
|
+
folder_handler, folder_path, recursive=True
|
187
|
+
)
|
188
|
+
|
189
|
+
folder_handler.add_path_change_listener(
|
190
|
+
path,
|
191
|
+
callback,
|
192
|
+
glob_pattern=glob_pattern,
|
193
|
+
allow_nonexistent=allow_nonexistent,
|
194
|
+
)
|
195
|
+
|
196
|
+
def stop_watching_path(self, path: str, callback: Callable[[str], None]) -> None:
|
197
|
+
"""Stop watching a path."""
|
198
|
+
folder_path = _get_abs_folder_path(path)
|
199
|
+
|
200
|
+
with self._lock:
|
201
|
+
folder_handler = self._folder_handlers.get(folder_path)
|
202
|
+
|
203
|
+
if folder_handler is None:
|
204
|
+
_LOGGER.debug(
|
205
|
+
"Cannot stop watching path, because it is already not being "
|
206
|
+
"watched. %s",
|
207
|
+
folder_path,
|
208
|
+
)
|
209
|
+
return
|
210
|
+
|
211
|
+
folder_handler.remove_path_change_listener(path, callback)
|
212
|
+
|
213
|
+
if (
|
214
|
+
not folder_handler.is_watching_paths()
|
215
|
+
and folder_handler.watch is not None
|
216
|
+
):
|
217
|
+
self._observer.unschedule(folder_handler.watch)
|
218
|
+
del self._folder_handlers[folder_path]
|
219
|
+
|
220
|
+
def close(self) -> None:
|
221
|
+
with self._lock:
|
222
|
+
"""Close this _MultiPathWatcher object forever."""
|
223
|
+
if len(self._folder_handlers) != 0:
|
224
|
+
self._folder_handlers = {}
|
225
|
+
_LOGGER.debug(
|
226
|
+
"Stopping observer thread even though there is a non-zero "
|
227
|
+
"number of event observers!"
|
228
|
+
)
|
229
|
+
else:
|
230
|
+
_LOGGER.debug("Stopping observer thread")
|
231
|
+
|
232
|
+
self._observer.stop()
|
233
|
+
self._observer.join(timeout=5)
|
234
|
+
|
235
|
+
|
236
|
+
class WatchedPath:
|
237
|
+
"""Emits notifications when a single path is modified."""
|
238
|
+
|
239
|
+
def __init__(
|
240
|
+
self,
|
241
|
+
md5: str,
|
242
|
+
modification_time: float,
|
243
|
+
*, # keyword-only arguments:
|
244
|
+
glob_pattern: str | None = None,
|
245
|
+
allow_nonexistent: bool = False,
|
246
|
+
):
|
247
|
+
self.md5 = md5
|
248
|
+
self.modification_time = modification_time
|
249
|
+
|
250
|
+
self.glob_pattern = glob_pattern
|
251
|
+
self.allow_nonexistent = allow_nonexistent
|
252
|
+
|
253
|
+
self.on_changed = Signal()
|
254
|
+
|
255
|
+
def __repr__(self) -> str:
|
256
|
+
return repr_(self)
|
257
|
+
|
258
|
+
|
259
|
+
class _FolderEventHandler(events.FileSystemEventHandler):
|
260
|
+
"""Listen to folder events. If certain paths change, fire a callback.
|
261
|
+
|
262
|
+
The super class, FileSystemEventHandler, listens to changes to *folders*,
|
263
|
+
but we need to listen to changes to *both* folders and files. I believe
|
264
|
+
this is a limitation of the Mac FSEvents system API, and the watchdog
|
265
|
+
library takes the lower common denominator.
|
266
|
+
|
267
|
+
So in this class we watch for folder events and then filter them based
|
268
|
+
on whether or not we care for the path the event is about.
|
269
|
+
"""
|
270
|
+
|
271
|
+
def __init__(self) -> None:
|
272
|
+
super().__init__()
|
273
|
+
self._watched_paths: dict[str, WatchedPath] = {}
|
274
|
+
self._lock = threading.Lock() # for watched_paths mutations
|
275
|
+
self.watch: ObservedWatch | None = None
|
276
|
+
|
277
|
+
def __repr__(self) -> str:
|
278
|
+
return repr_(self)
|
279
|
+
|
280
|
+
def add_path_change_listener(
|
281
|
+
self,
|
282
|
+
path: str,
|
283
|
+
callback: Callable[[str], None],
|
284
|
+
*, # keyword-only arguments:
|
285
|
+
glob_pattern: str | None = None,
|
286
|
+
allow_nonexistent: bool = False,
|
287
|
+
) -> None:
|
288
|
+
"""Add a path to this object's event filter."""
|
289
|
+
with self._lock:
|
290
|
+
watched_path = self._watched_paths.get(path, None)
|
291
|
+
if watched_path is None:
|
292
|
+
md5 = util.calc_md5_with_blocking_retries(
|
293
|
+
path,
|
294
|
+
glob_pattern=glob_pattern,
|
295
|
+
allow_nonexistent=allow_nonexistent,
|
296
|
+
)
|
297
|
+
modification_time = util.path_modification_time(path, allow_nonexistent)
|
298
|
+
watched_path = WatchedPath(
|
299
|
+
md5=md5,
|
300
|
+
modification_time=modification_time,
|
301
|
+
glob_pattern=glob_pattern,
|
302
|
+
allow_nonexistent=allow_nonexistent,
|
303
|
+
)
|
304
|
+
self._watched_paths[path] = watched_path
|
305
|
+
|
306
|
+
watched_path.on_changed.connect(callback, weak=False)
|
307
|
+
|
308
|
+
def remove_path_change_listener(
|
309
|
+
self, path: str, callback: Callable[[str], None]
|
310
|
+
) -> None:
|
311
|
+
"""Remove a path from this object's event filter."""
|
312
|
+
with self._lock:
|
313
|
+
watched_path = self._watched_paths.get(path, None)
|
314
|
+
if watched_path is None:
|
315
|
+
return
|
316
|
+
|
317
|
+
watched_path.on_changed.disconnect(callback)
|
318
|
+
if not watched_path.on_changed.has_receivers_for(ANY):
|
319
|
+
del self._watched_paths[path]
|
320
|
+
|
321
|
+
def is_watching_paths(self) -> bool:
|
322
|
+
"""Return true if this object has 1+ paths in its event filter."""
|
323
|
+
return len(self._watched_paths) > 0
|
324
|
+
|
325
|
+
def handle_path_change_event(self, event: events.FileSystemEvent) -> None:
|
326
|
+
"""Handle when a path (corresponding to a file or dir) is changed.
|
327
|
+
|
328
|
+
The events that can call this are modification, creation or moved
|
329
|
+
events.
|
330
|
+
"""
|
331
|
+
|
332
|
+
# Check for both modified and moved files, because many programs write
|
333
|
+
# to a backup file then rename (i.e. move) it.
|
334
|
+
if event.event_type == events.EVENT_TYPE_MODIFIED:
|
335
|
+
changed_path = event.src_path
|
336
|
+
elif event.event_type == events.EVENT_TYPE_MOVED:
|
337
|
+
# Teach mypy that this event has a dest_path, because it can't infer
|
338
|
+
# the desired subtype from the event_type check
|
339
|
+
event = cast(events.FileSystemMovedEvent, event)
|
340
|
+
|
341
|
+
_LOGGER.debug(
|
342
|
+
"Move event: src %s; dest %s", event.src_path, event.dest_path
|
343
|
+
)
|
344
|
+
changed_path = event.dest_path
|
345
|
+
# On OSX with VI, on save, the file is deleted, the swap file is
|
346
|
+
# modified and then the original file is created hence why we
|
347
|
+
# capture EVENT_TYPE_CREATED
|
348
|
+
elif event.event_type == events.EVENT_TYPE_CREATED:
|
349
|
+
changed_path = event.src_path
|
350
|
+
else:
|
351
|
+
_LOGGER.debug("Don't care about event type %s", event.event_type)
|
352
|
+
return
|
353
|
+
|
354
|
+
# Watchdog 5.X is supported Python >=3.9, so watchdog 4.X is used for Python 3.8.
|
355
|
+
# In Watchdog 5.X, the path can be bytes or str, but in Watchdog 4.X, the path is always str,
|
356
|
+
# that's why we convert the path to str, but we need to ignore the unreachable code warning for Python 3.8.
|
357
|
+
if isinstance(changed_path, bytes): # type: ignore[unreachable, unused-ignore]
|
358
|
+
changed_path = changed_path.decode("utf-8") # type: ignore[unreachable, unused-ignore]
|
359
|
+
|
360
|
+
abs_changed_path = os.path.abspath(changed_path)
|
361
|
+
|
362
|
+
changed_path_info = self._watched_paths.get(abs_changed_path, None)
|
363
|
+
if changed_path_info is None:
|
364
|
+
_LOGGER.debug(
|
365
|
+
"Ignoring changed path %s.\nWatched_paths: %s",
|
366
|
+
abs_changed_path,
|
367
|
+
self._watched_paths,
|
368
|
+
)
|
369
|
+
return
|
370
|
+
|
371
|
+
modification_time = util.path_modification_time(
|
372
|
+
abs_changed_path, changed_path_info.allow_nonexistent
|
373
|
+
)
|
374
|
+
|
375
|
+
# We add modification_time != 0.0 check since on some file systems (s3fs/fuse)
|
376
|
+
# modification_time is always 0.0 because of file system limitations.
|
377
|
+
if (
|
378
|
+
modification_time != 0.0
|
379
|
+
and modification_time == changed_path_info.modification_time
|
380
|
+
):
|
381
|
+
_LOGGER.debug("File/dir timestamp did not change: %s", abs_changed_path)
|
382
|
+
return
|
383
|
+
|
384
|
+
changed_path_info.modification_time = modification_time
|
385
|
+
|
386
|
+
new_md5 = util.calc_md5_with_blocking_retries(
|
387
|
+
abs_changed_path,
|
388
|
+
glob_pattern=changed_path_info.glob_pattern,
|
389
|
+
allow_nonexistent=changed_path_info.allow_nonexistent,
|
390
|
+
)
|
391
|
+
if new_md5 == changed_path_info.md5:
|
392
|
+
_LOGGER.debug("File/dir MD5 did not change: %s", abs_changed_path)
|
393
|
+
return
|
394
|
+
|
395
|
+
_LOGGER.debug("File/dir MD5 changed: %s", abs_changed_path)
|
396
|
+
changed_path_info.md5 = new_md5
|
397
|
+
changed_path_info.on_changed.send(abs_changed_path)
|
398
|
+
|
399
|
+
def on_created(self, event: events.FileSystemEvent) -> None:
|
400
|
+
self.handle_path_change_event(event)
|
401
|
+
|
402
|
+
def on_modified(self, event: events.FileSystemEvent) -> None:
|
403
|
+
self.handle_path_change_event(event)
|
404
|
+
|
405
|
+
def on_moved(self, event: events.FileSystemEvent) -> None:
|
406
|
+
self.handle_path_change_event(event)
|
@@ -0,0 +1,82 @@
|
|
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
|
+
|
19
|
+
from streamlit import config, file_util, util
|
20
|
+
|
21
|
+
# The files in the folders below should always be blacklisted.
|
22
|
+
DEFAULT_FOLDER_BLACKLIST = [
|
23
|
+
"**/.*",
|
24
|
+
"**/anaconda",
|
25
|
+
"**/anaconda2",
|
26
|
+
"**/anaconda3",
|
27
|
+
"**/dist-packages",
|
28
|
+
"**/miniconda",
|
29
|
+
"**/miniconda2",
|
30
|
+
"**/miniconda3",
|
31
|
+
"**/node_modules",
|
32
|
+
"**/pyenv",
|
33
|
+
"**/site-packages",
|
34
|
+
"**/venv",
|
35
|
+
"**/virtualenv",
|
36
|
+
"**/htmlcov",
|
37
|
+
]
|
38
|
+
|
39
|
+
|
40
|
+
class FolderBlackList:
|
41
|
+
"""Implement a black list object with globbing.
|
42
|
+
|
43
|
+
Note
|
44
|
+
----
|
45
|
+
Blacklist any path that matches a glob in `DEFAULT_FOLDER_BLACKLIST`.
|
46
|
+
|
47
|
+
"""
|
48
|
+
|
49
|
+
def __init__(self, folder_blacklist):
|
50
|
+
"""Constructor.
|
51
|
+
|
52
|
+
Parameters
|
53
|
+
----------
|
54
|
+
folder_blacklist : list of str
|
55
|
+
list of folder names with globbing to blacklist.
|
56
|
+
|
57
|
+
"""
|
58
|
+
self._folder_blacklist = list(folder_blacklist)
|
59
|
+
self._folder_blacklist.extend(DEFAULT_FOLDER_BLACKLIST)
|
60
|
+
|
61
|
+
# Add the Streamlit lib folder when in dev mode, since otherwise we end
|
62
|
+
# up with weird situations where the ID of a class in one run is not
|
63
|
+
# the same as in another run.
|
64
|
+
if config.get_option("global.developmentMode"):
|
65
|
+
self._folder_blacklist.append(os.path.dirname(__file__))
|
66
|
+
|
67
|
+
def __repr__(self) -> str:
|
68
|
+
return util.repr_(self)
|
69
|
+
|
70
|
+
def is_blacklisted(self, filepath):
|
71
|
+
"""Test if filepath is in the blacklist.
|
72
|
+
|
73
|
+
Parameters
|
74
|
+
----------
|
75
|
+
filepath : str
|
76
|
+
File path that we intend to test.
|
77
|
+
|
78
|
+
"""
|
79
|
+
return any(
|
80
|
+
file_util.file_is_in_folder_glob(filepath, blacklisted_folder)
|
81
|
+
for blacklisted_folder in self._folder_blacklist
|
82
|
+
)
|