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,479 @@
|
|
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 errno
|
18
|
+
import logging
|
19
|
+
import mimetypes
|
20
|
+
import os
|
21
|
+
import sys
|
22
|
+
from pathlib import Path
|
23
|
+
from typing import TYPE_CHECKING, Any, Final
|
24
|
+
|
25
|
+
import tornado.concurrent
|
26
|
+
import tornado.locks
|
27
|
+
import tornado.netutil
|
28
|
+
import tornado.web
|
29
|
+
import tornado.websocket
|
30
|
+
from tornado.httpserver import HTTPServer
|
31
|
+
|
32
|
+
from streamlit import cli_util, config, file_util, util
|
33
|
+
from streamlit.auth_util import is_authlib_installed
|
34
|
+
from streamlit.config_option import ConfigOption
|
35
|
+
from streamlit.logger import get_logger
|
36
|
+
from streamlit.runtime import Runtime, RuntimeConfig, RuntimeState
|
37
|
+
from streamlit.runtime.memory_media_file_storage import MemoryMediaFileStorage
|
38
|
+
from streamlit.runtime.memory_session_storage import MemorySessionStorage
|
39
|
+
from streamlit.runtime.memory_uploaded_file_manager import MemoryUploadedFileManager
|
40
|
+
from streamlit.runtime.runtime_util import get_max_message_size_bytes
|
41
|
+
from streamlit.web.cache_storage_manager_config import (
|
42
|
+
create_default_cache_storage_manager,
|
43
|
+
)
|
44
|
+
from streamlit.web.server.app_static_file_handler import AppStaticFileHandler
|
45
|
+
from streamlit.web.server.browser_websocket_handler import BrowserWebSocketHandler
|
46
|
+
from streamlit.web.server.component_request_handler import ComponentRequestHandler
|
47
|
+
from streamlit.web.server.media_file_handler import MediaFileHandler
|
48
|
+
from streamlit.web.server.routes import (
|
49
|
+
AddSlashHandler,
|
50
|
+
HealthHandler,
|
51
|
+
HostConfigHandler,
|
52
|
+
MessageCacheHandler,
|
53
|
+
RemoveSlashHandler,
|
54
|
+
StaticFileHandler,
|
55
|
+
)
|
56
|
+
from streamlit.web.server.server_util import (
|
57
|
+
DEVELOPMENT_PORT,
|
58
|
+
get_cookie_secret,
|
59
|
+
is_xsrf_enabled,
|
60
|
+
make_url_path_regex,
|
61
|
+
)
|
62
|
+
from streamlit.web.server.stats_request_handler import StatsRequestHandler
|
63
|
+
from streamlit.web.server.upload_file_request_handler import UploadFileRequestHandler
|
64
|
+
|
65
|
+
if TYPE_CHECKING:
|
66
|
+
from collections.abc import Awaitable
|
67
|
+
from ssl import SSLContext
|
68
|
+
|
69
|
+
_LOGGER: Final = get_logger(__name__)
|
70
|
+
|
71
|
+
TORNADO_SETTINGS = {
|
72
|
+
# Gzip HTTP responses.
|
73
|
+
"compress_response": True,
|
74
|
+
# Ping every 1s to keep WS alive.
|
75
|
+
# 2021.06.22: this value was previously 20s, and was causing
|
76
|
+
# connection instability for a small number of users. This smaller
|
77
|
+
# ping_interval fixes that instability.
|
78
|
+
# https://github.com/streamlit/streamlit/issues/3196
|
79
|
+
"websocket_ping_interval": 1,
|
80
|
+
# If we don't get a ping response within 30s, the connection
|
81
|
+
# is timed out.
|
82
|
+
"websocket_ping_timeout": 30,
|
83
|
+
"xsrf_cookie_name": "_streamlit_xsrf",
|
84
|
+
}
|
85
|
+
|
86
|
+
# When server.port is not available it will look for the next available port
|
87
|
+
# up to MAX_PORT_SEARCH_RETRIES.
|
88
|
+
MAX_PORT_SEARCH_RETRIES: Final = 100
|
89
|
+
|
90
|
+
# When server.address starts with this prefix, the server will bind
|
91
|
+
# to an unix socket.
|
92
|
+
UNIX_SOCKET_PREFIX: Final = "unix://"
|
93
|
+
|
94
|
+
MEDIA_ENDPOINT: Final = "/media"
|
95
|
+
UPLOAD_FILE_ENDPOINT: Final = "/_stcore/upload_file"
|
96
|
+
STREAM_ENDPOINT: Final = r"_stcore/stream"
|
97
|
+
METRIC_ENDPOINT: Final = r"(?:st-metrics|_stcore/metrics)"
|
98
|
+
MESSAGE_ENDPOINT: Final = r"_stcore/message"
|
99
|
+
NEW_HEALTH_ENDPOINT: Final = "_stcore/health"
|
100
|
+
HEALTH_ENDPOINT: Final = rf"(?:healthz|{NEW_HEALTH_ENDPOINT})"
|
101
|
+
HOST_CONFIG_ENDPOINT: Final = r"_stcore/host-config"
|
102
|
+
SCRIPT_HEALTH_CHECK_ENDPOINT: Final = (
|
103
|
+
r"(?:script-health-check|_stcore/script-health-check)"
|
104
|
+
)
|
105
|
+
|
106
|
+
OAUTH2_CALLBACK_ENDPOINT: Final = "/oauth2callback"
|
107
|
+
AUTH_LOGIN_ENDPOINT: Final = "/auth/login"
|
108
|
+
AUTH_LOGOUT_ENDPOINT: Final = "/auth/logout"
|
109
|
+
|
110
|
+
|
111
|
+
class RetriesExceeded(Exception):
|
112
|
+
pass
|
113
|
+
|
114
|
+
|
115
|
+
def server_port_is_manually_set() -> bool:
|
116
|
+
return config.is_manually_set("server.port")
|
117
|
+
|
118
|
+
|
119
|
+
def server_address_is_unix_socket() -> bool:
|
120
|
+
address = config.get_option("server.address")
|
121
|
+
return address is not None and address.startswith(UNIX_SOCKET_PREFIX)
|
122
|
+
|
123
|
+
|
124
|
+
def start_listening(app: tornado.web.Application) -> None:
|
125
|
+
"""Makes the server start listening at the configured port.
|
126
|
+
|
127
|
+
In case the port is already taken it tries listening to the next available
|
128
|
+
port. It will error after MAX_PORT_SEARCH_RETRIES attempts.
|
129
|
+
|
130
|
+
"""
|
131
|
+
cert_file = config.get_option("server.sslCertFile")
|
132
|
+
key_file = config.get_option("server.sslKeyFile")
|
133
|
+
ssl_options = _get_ssl_options(cert_file, key_file)
|
134
|
+
|
135
|
+
http_server = HTTPServer(
|
136
|
+
app,
|
137
|
+
max_buffer_size=config.get_option("server.maxUploadSize") * 1024 * 1024,
|
138
|
+
ssl_options=ssl_options,
|
139
|
+
)
|
140
|
+
|
141
|
+
if server_address_is_unix_socket():
|
142
|
+
start_listening_unix_socket(http_server)
|
143
|
+
else:
|
144
|
+
start_listening_tcp_socket(http_server)
|
145
|
+
|
146
|
+
|
147
|
+
def _get_ssl_options(cert_file: str | None, key_file: str | None) -> SSLContext | None:
|
148
|
+
if bool(cert_file) != bool(key_file):
|
149
|
+
_LOGGER.error(
|
150
|
+
"Options 'server.sslCertFile' and 'server.sslKeyFile' must "
|
151
|
+
"be set together. Set missing options or delete existing options."
|
152
|
+
)
|
153
|
+
sys.exit(1)
|
154
|
+
if cert_file and key_file:
|
155
|
+
# ssl_ctx.load_cert_chain raise exception as below, but it is not
|
156
|
+
# sufficiently user-friendly
|
157
|
+
# FileNotFoundError: [Errno 2] No such file or directory
|
158
|
+
if not Path(cert_file).exists():
|
159
|
+
_LOGGER.error("Cert file '%s' does not exist.", cert_file)
|
160
|
+
sys.exit(1)
|
161
|
+
if not Path(key_file).exists():
|
162
|
+
_LOGGER.error("Key file '%s' does not exist.", key_file)
|
163
|
+
sys.exit(1)
|
164
|
+
|
165
|
+
import ssl
|
166
|
+
|
167
|
+
ssl_ctx = ssl.create_default_context(ssl.Purpose.CLIENT_AUTH)
|
168
|
+
# When the SSL certificate fails to load, an exception is raised as below,
|
169
|
+
# but it is not sufficiently user-friendly.
|
170
|
+
# ssl.SSLError: [SSL] PEM lib (_ssl.c:4067)
|
171
|
+
try:
|
172
|
+
ssl_ctx.load_cert_chain(cert_file, key_file)
|
173
|
+
except ssl.SSLError:
|
174
|
+
_LOGGER.error(
|
175
|
+
"Failed to load SSL certificate. Make sure "
|
176
|
+
"cert file '%s' and key file '%s' are correct.",
|
177
|
+
cert_file,
|
178
|
+
key_file,
|
179
|
+
)
|
180
|
+
sys.exit(1)
|
181
|
+
|
182
|
+
return ssl_ctx
|
183
|
+
return None
|
184
|
+
|
185
|
+
|
186
|
+
def start_listening_unix_socket(http_server: HTTPServer) -> None:
|
187
|
+
address = config.get_option("server.address")
|
188
|
+
file_name = os.path.expanduser(address[len(UNIX_SOCKET_PREFIX) :])
|
189
|
+
|
190
|
+
unix_socket = tornado.netutil.bind_unix_socket(file_name)
|
191
|
+
http_server.add_socket(unix_socket)
|
192
|
+
|
193
|
+
|
194
|
+
def start_listening_tcp_socket(http_server: HTTPServer) -> None:
|
195
|
+
call_count = 0
|
196
|
+
|
197
|
+
port = None
|
198
|
+
while call_count < MAX_PORT_SEARCH_RETRIES:
|
199
|
+
address = config.get_option("server.address")
|
200
|
+
port = config.get_option("server.port")
|
201
|
+
|
202
|
+
if int(port) == DEVELOPMENT_PORT:
|
203
|
+
_LOGGER.warning(
|
204
|
+
"Port %s is reserved for internal development. "
|
205
|
+
"It is strongly recommended to select an alternative port "
|
206
|
+
"for `server.port`.",
|
207
|
+
DEVELOPMENT_PORT,
|
208
|
+
)
|
209
|
+
|
210
|
+
try:
|
211
|
+
http_server.listen(port, address)
|
212
|
+
break # It worked! So let's break out of the loop.
|
213
|
+
|
214
|
+
except OSError as e:
|
215
|
+
if e.errno == errno.EADDRINUSE:
|
216
|
+
if server_port_is_manually_set():
|
217
|
+
_LOGGER.error("Port %s is already in use", port)
|
218
|
+
sys.exit(1)
|
219
|
+
else:
|
220
|
+
_LOGGER.debug(
|
221
|
+
"Port %s already in use, trying to use the next one.", port
|
222
|
+
)
|
223
|
+
port += 1
|
224
|
+
# Don't use the development port here:
|
225
|
+
if port == DEVELOPMENT_PORT:
|
226
|
+
port += 1
|
227
|
+
|
228
|
+
config.set_option(
|
229
|
+
"server.port", port, ConfigOption.STREAMLIT_DEFINITION
|
230
|
+
)
|
231
|
+
call_count += 1
|
232
|
+
else:
|
233
|
+
raise
|
234
|
+
|
235
|
+
if call_count >= MAX_PORT_SEARCH_RETRIES:
|
236
|
+
raise RetriesExceeded(
|
237
|
+
f"Cannot start Streamlit server. Port {port} is already in use, and "
|
238
|
+
f"Streamlit was unable to find a free port after {MAX_PORT_SEARCH_RETRIES} attempts.",
|
239
|
+
)
|
240
|
+
|
241
|
+
|
242
|
+
class Server:
|
243
|
+
def __init__(self, main_script_path: str, is_hello: bool):
|
244
|
+
"""Create the server. It won't be started yet."""
|
245
|
+
_set_tornado_log_levels()
|
246
|
+
self.initialize_mimetypes()
|
247
|
+
|
248
|
+
self._main_script_path = main_script_path
|
249
|
+
|
250
|
+
# Initialize MediaFileStorage and its associated endpoint
|
251
|
+
media_file_storage = MemoryMediaFileStorage(MEDIA_ENDPOINT)
|
252
|
+
MediaFileHandler.initialize_storage(media_file_storage)
|
253
|
+
|
254
|
+
uploaded_file_mgr = MemoryUploadedFileManager(UPLOAD_FILE_ENDPOINT)
|
255
|
+
|
256
|
+
self._runtime = Runtime(
|
257
|
+
RuntimeConfig(
|
258
|
+
script_path=main_script_path,
|
259
|
+
command_line=None,
|
260
|
+
media_file_storage=media_file_storage,
|
261
|
+
uploaded_file_manager=uploaded_file_mgr,
|
262
|
+
cache_storage_manager=create_default_cache_storage_manager(),
|
263
|
+
is_hello=is_hello,
|
264
|
+
session_storage=MemorySessionStorage(
|
265
|
+
ttl_seconds=config.get_option("server.disconnectedSessionTTL")
|
266
|
+
),
|
267
|
+
),
|
268
|
+
)
|
269
|
+
|
270
|
+
self._runtime.stats_mgr.register_provider(media_file_storage)
|
271
|
+
|
272
|
+
@classmethod
|
273
|
+
def initialize_mimetypes(cls) -> None:
|
274
|
+
"""Ensures that common mime-types are robust against system misconfiguration."""
|
275
|
+
mimetypes.add_type("text/html", ".html")
|
276
|
+
mimetypes.add_type("application/javascript", ".js")
|
277
|
+
mimetypes.add_type("text/css", ".css")
|
278
|
+
mimetypes.add_type("image/webp", ".webp")
|
279
|
+
|
280
|
+
def __repr__(self) -> str:
|
281
|
+
return util.repr_(self)
|
282
|
+
|
283
|
+
@property
|
284
|
+
def main_script_path(self) -> str:
|
285
|
+
return self._main_script_path
|
286
|
+
|
287
|
+
async def start(self) -> None:
|
288
|
+
"""Start the server.
|
289
|
+
|
290
|
+
When this returns, Streamlit is ready to accept new sessions.
|
291
|
+
"""
|
292
|
+
|
293
|
+
_LOGGER.debug("Starting server...")
|
294
|
+
|
295
|
+
app = self._create_app()
|
296
|
+
start_listening(app)
|
297
|
+
|
298
|
+
port = config.get_option("server.port")
|
299
|
+
_LOGGER.debug("Server started on port %s", port)
|
300
|
+
|
301
|
+
await self._runtime.start()
|
302
|
+
|
303
|
+
@property
|
304
|
+
def stopped(self) -> Awaitable[None]:
|
305
|
+
"""A Future that completes when the Server's run loop has exited."""
|
306
|
+
return self._runtime.stopped
|
307
|
+
|
308
|
+
def _create_app(self) -> tornado.web.Application:
|
309
|
+
"""Create our tornado web app."""
|
310
|
+
base = config.get_option("server.baseUrlPath")
|
311
|
+
|
312
|
+
routes: list[Any] = [
|
313
|
+
(
|
314
|
+
make_url_path_regex(base, STREAM_ENDPOINT),
|
315
|
+
BrowserWebSocketHandler,
|
316
|
+
{"runtime": self._runtime},
|
317
|
+
),
|
318
|
+
(
|
319
|
+
make_url_path_regex(base, HEALTH_ENDPOINT),
|
320
|
+
HealthHandler,
|
321
|
+
{"callback": lambda: self._runtime.is_ready_for_browser_connection},
|
322
|
+
),
|
323
|
+
(
|
324
|
+
make_url_path_regex(base, MESSAGE_ENDPOINT),
|
325
|
+
MessageCacheHandler,
|
326
|
+
{"cache": self._runtime.message_cache},
|
327
|
+
),
|
328
|
+
(
|
329
|
+
make_url_path_regex(base, METRIC_ENDPOINT),
|
330
|
+
StatsRequestHandler,
|
331
|
+
{"stats_manager": self._runtime.stats_mgr},
|
332
|
+
),
|
333
|
+
(
|
334
|
+
make_url_path_regex(base, HOST_CONFIG_ENDPOINT),
|
335
|
+
HostConfigHandler,
|
336
|
+
),
|
337
|
+
(
|
338
|
+
make_url_path_regex(
|
339
|
+
base,
|
340
|
+
rf"{UPLOAD_FILE_ENDPOINT}/(?P<session_id>[^/]+)/(?P<file_id>[^/]+)",
|
341
|
+
),
|
342
|
+
UploadFileRequestHandler,
|
343
|
+
{
|
344
|
+
"file_mgr": self._runtime.uploaded_file_mgr,
|
345
|
+
"is_active_session": self._runtime.is_active_session,
|
346
|
+
},
|
347
|
+
),
|
348
|
+
(
|
349
|
+
make_url_path_regex(base, f"{MEDIA_ENDPOINT}/(.*)"),
|
350
|
+
MediaFileHandler,
|
351
|
+
{"path": ""},
|
352
|
+
),
|
353
|
+
(
|
354
|
+
make_url_path_regex(base, "component/(.*)"),
|
355
|
+
ComponentRequestHandler,
|
356
|
+
{"registry": self._runtime.component_registry},
|
357
|
+
),
|
358
|
+
]
|
359
|
+
|
360
|
+
if config.get_option("server.scriptHealthCheckEnabled"):
|
361
|
+
routes.extend(
|
362
|
+
[
|
363
|
+
(
|
364
|
+
make_url_path_regex(base, SCRIPT_HEALTH_CHECK_ENDPOINT),
|
365
|
+
HealthHandler,
|
366
|
+
{
|
367
|
+
"callback": lambda: self._runtime.does_script_run_without_error()
|
368
|
+
},
|
369
|
+
)
|
370
|
+
]
|
371
|
+
)
|
372
|
+
|
373
|
+
if config.get_option("server.enableStaticServing"):
|
374
|
+
routes.extend(
|
375
|
+
[
|
376
|
+
(
|
377
|
+
make_url_path_regex(base, "app/static/(.*)"),
|
378
|
+
AppStaticFileHandler,
|
379
|
+
{"path": file_util.get_app_static_dir(self.main_script_path)},
|
380
|
+
),
|
381
|
+
]
|
382
|
+
)
|
383
|
+
|
384
|
+
if is_authlib_installed():
|
385
|
+
from streamlit.web.server.oauth_authlib_routes import (
|
386
|
+
AuthCallbackHandler,
|
387
|
+
AuthLoginHandler,
|
388
|
+
AuthLogoutHandler,
|
389
|
+
)
|
390
|
+
|
391
|
+
routes.extend(
|
392
|
+
[
|
393
|
+
(
|
394
|
+
make_url_path_regex(base, OAUTH2_CALLBACK_ENDPOINT),
|
395
|
+
AuthCallbackHandler,
|
396
|
+
{"base_url": base},
|
397
|
+
),
|
398
|
+
(
|
399
|
+
make_url_path_regex(base, AUTH_LOGIN_ENDPOINT),
|
400
|
+
AuthLoginHandler,
|
401
|
+
{"base_url": base},
|
402
|
+
),
|
403
|
+
(
|
404
|
+
make_url_path_regex(base, AUTH_LOGOUT_ENDPOINT),
|
405
|
+
AuthLogoutHandler,
|
406
|
+
{"base_url": base},
|
407
|
+
),
|
408
|
+
]
|
409
|
+
)
|
410
|
+
|
411
|
+
if config.get_option("global.developmentMode"):
|
412
|
+
_LOGGER.debug("Serving static content from the Node dev server")
|
413
|
+
else:
|
414
|
+
static_path = file_util.get_static_dir()
|
415
|
+
_LOGGER.debug("Serving static content from %s", static_path)
|
416
|
+
|
417
|
+
routes.extend(
|
418
|
+
[
|
419
|
+
(
|
420
|
+
# We want to remove paths with a trailing slash, but if the path
|
421
|
+
# starts with a double slash //, the redirect will point
|
422
|
+
# the browser to the wrong host.
|
423
|
+
make_url_path_regex(
|
424
|
+
base, "(?!/)(.*)", trailing_slash="required"
|
425
|
+
),
|
426
|
+
RemoveSlashHandler,
|
427
|
+
),
|
428
|
+
(
|
429
|
+
make_url_path_regex(base, "(.*)"),
|
430
|
+
StaticFileHandler,
|
431
|
+
{
|
432
|
+
"path": "%s/" % static_path,
|
433
|
+
"default_filename": "index.html",
|
434
|
+
"reserved_paths": [
|
435
|
+
# These paths are required for identifying
|
436
|
+
# the base url path.
|
437
|
+
NEW_HEALTH_ENDPOINT,
|
438
|
+
HOST_CONFIG_ENDPOINT,
|
439
|
+
],
|
440
|
+
},
|
441
|
+
),
|
442
|
+
(
|
443
|
+
make_url_path_regex(base, trailing_slash="prohibited"),
|
444
|
+
AddSlashHandler,
|
445
|
+
),
|
446
|
+
]
|
447
|
+
)
|
448
|
+
|
449
|
+
return tornado.web.Application(
|
450
|
+
routes,
|
451
|
+
cookie_secret=get_cookie_secret(),
|
452
|
+
xsrf_cookies=is_xsrf_enabled(),
|
453
|
+
# Set the websocket message size. The default value is too low.
|
454
|
+
websocket_max_message_size=get_max_message_size_bytes(),
|
455
|
+
**TORNADO_SETTINGS, # type: ignore[arg-type]
|
456
|
+
)
|
457
|
+
|
458
|
+
@property
|
459
|
+
def browser_is_connected(self) -> bool:
|
460
|
+
return self._runtime.state == RuntimeState.ONE_OR_MORE_SESSIONS_CONNECTED
|
461
|
+
|
462
|
+
@property
|
463
|
+
def is_running_hello(self) -> bool:
|
464
|
+
from streamlit.hello import streamlit_app
|
465
|
+
|
466
|
+
return self._main_script_path == streamlit_app.__file__
|
467
|
+
|
468
|
+
def stop(self) -> None:
|
469
|
+
cli_util.print_to_cli(" Stopping...", fg="blue")
|
470
|
+
self._runtime.stop()
|
471
|
+
|
472
|
+
|
473
|
+
def _set_tornado_log_levels() -> None:
|
474
|
+
if not config.get_option("global.developmentMode"):
|
475
|
+
# Hide logs unless they're super important.
|
476
|
+
# Example of stuff we don't care about: 404 about .js.map files.
|
477
|
+
logging.getLogger("tornado.access").setLevel(logging.ERROR)
|
478
|
+
logging.getLogger("tornado.application").setLevel(logging.ERROR)
|
479
|
+
logging.getLogger("tornado.general").setLevel(logging.ERROR)
|
@@ -0,0 +1,161 @@
|
|
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
|
+
"""Server related utility functions"""
|
16
|
+
|
17
|
+
from __future__ import annotations
|
18
|
+
|
19
|
+
from typing import TYPE_CHECKING, Final, Literal
|
20
|
+
from urllib.parse import urljoin
|
21
|
+
|
22
|
+
from streamlit import config, net_util, url_util
|
23
|
+
from streamlit.runtime.secrets import secrets_singleton
|
24
|
+
|
25
|
+
if TYPE_CHECKING:
|
26
|
+
from tornado.web import RequestHandler
|
27
|
+
|
28
|
+
# The port reserved for internal development.
|
29
|
+
DEVELOPMENT_PORT: Final = 3000
|
30
|
+
|
31
|
+
AUTH_COOKIE_NAME: Final = "_streamlit_user"
|
32
|
+
|
33
|
+
|
34
|
+
def is_url_from_allowed_origins(url: str) -> bool:
|
35
|
+
"""Return True if URL is from allowed origins (for CORS purpose).
|
36
|
+
|
37
|
+
Allowed origins:
|
38
|
+
1. localhost
|
39
|
+
2. The internal and external IP addresses of the machine where this
|
40
|
+
function was called from.
|
41
|
+
|
42
|
+
If `server.enableCORS` is False, this allows all origins.
|
43
|
+
"""
|
44
|
+
if not config.get_option("server.enableCORS"):
|
45
|
+
# Allow everything when CORS is disabled.
|
46
|
+
return True
|
47
|
+
|
48
|
+
hostname = url_util.get_hostname(url)
|
49
|
+
|
50
|
+
allowed_domains = [ # List[Union[str, Callable[[], Optional[str]]]]
|
51
|
+
# Check localhost first.
|
52
|
+
"localhost",
|
53
|
+
"0.0.0.0",
|
54
|
+
"127.0.0.1",
|
55
|
+
# Try to avoid making unnecessary HTTP requests by checking if the user
|
56
|
+
# manually specified a server address.
|
57
|
+
_get_server_address_if_manually_set,
|
58
|
+
# Then try the options that depend on HTTP requests or opening sockets.
|
59
|
+
net_util.get_internal_ip,
|
60
|
+
net_util.get_external_ip,
|
61
|
+
]
|
62
|
+
|
63
|
+
for allowed_domain in allowed_domains:
|
64
|
+
if callable(allowed_domain):
|
65
|
+
allowed_domain = allowed_domain()
|
66
|
+
|
67
|
+
if allowed_domain is None:
|
68
|
+
continue
|
69
|
+
|
70
|
+
if hostname == allowed_domain:
|
71
|
+
return True
|
72
|
+
|
73
|
+
return False
|
74
|
+
|
75
|
+
|
76
|
+
def get_cookie_secret() -> str:
|
77
|
+
"""Get the cookie secret.
|
78
|
+
|
79
|
+
If the user has not set a cookie secret, we generate a random one.
|
80
|
+
"""
|
81
|
+
cookie_secret: str = config.get_option("server.cookieSecret")
|
82
|
+
if secrets_singleton.load_if_toml_exists():
|
83
|
+
auth_section = secrets_singleton.get("auth")
|
84
|
+
if auth_section:
|
85
|
+
cookie_secret = auth_section.get("cookie_secret", cookie_secret)
|
86
|
+
return cookie_secret
|
87
|
+
|
88
|
+
|
89
|
+
def is_xsrf_enabled():
|
90
|
+
csrf_enabled = config.get_option("server.enableXsrfProtection")
|
91
|
+
if not csrf_enabled and secrets_singleton.load_if_toml_exists():
|
92
|
+
auth_section = secrets_singleton.get("auth", None)
|
93
|
+
csrf_enabled = csrf_enabled or auth_section is not None
|
94
|
+
return csrf_enabled
|
95
|
+
|
96
|
+
|
97
|
+
def _get_server_address_if_manually_set() -> str | None:
|
98
|
+
if config.is_manually_set("browser.serverAddress"):
|
99
|
+
return url_util.get_hostname(config.get_option("browser.serverAddress"))
|
100
|
+
return None
|
101
|
+
|
102
|
+
|
103
|
+
def make_url_path_regex(
|
104
|
+
*path, trailing_slash: Literal["optional", "required", "prohibited"] = "optional"
|
105
|
+
) -> str:
|
106
|
+
"""Get a regex of the form ^/foo/bar/baz/?$ for a path (foo, bar, baz)."""
|
107
|
+
path = [x.strip("/") for x in path if x] # Filter out falsely components.
|
108
|
+
path_format = r"^/%s$"
|
109
|
+
if trailing_slash == "optional":
|
110
|
+
path_format = r"^/%s/?$"
|
111
|
+
elif trailing_slash == "required":
|
112
|
+
path_format = r"^/%s/$"
|
113
|
+
|
114
|
+
return path_format % "/".join(path)
|
115
|
+
|
116
|
+
|
117
|
+
def get_url(host_ip: str) -> str:
|
118
|
+
"""Get the URL for any app served at the given host_ip.
|
119
|
+
|
120
|
+
Parameters
|
121
|
+
----------
|
122
|
+
host_ip : str
|
123
|
+
The IP address of the machine that is running the Streamlit Server.
|
124
|
+
|
125
|
+
Returns
|
126
|
+
-------
|
127
|
+
str
|
128
|
+
The URL.
|
129
|
+
"""
|
130
|
+
protocol = "https" if config.get_option("server.sslCertFile") else "http"
|
131
|
+
|
132
|
+
port = _get_browser_address_bar_port()
|
133
|
+
base_path = config.get_option("server.baseUrlPath").strip("/")
|
134
|
+
|
135
|
+
if base_path:
|
136
|
+
base_path = "/" + base_path
|
137
|
+
|
138
|
+
host_ip = host_ip.strip("/")
|
139
|
+
return f"{protocol}://{host_ip}:{port}{base_path}"
|
140
|
+
|
141
|
+
|
142
|
+
def _get_browser_address_bar_port() -> int:
|
143
|
+
"""Get the app URL that will be shown in the browser's address bar.
|
144
|
+
|
145
|
+
That is, this is the port where static assets will be served from. In dev,
|
146
|
+
this is different from the URL that will be used to connect to the
|
147
|
+
server-browser websocket.
|
148
|
+
|
149
|
+
"""
|
150
|
+
if config.get_option("global.developmentMode"):
|
151
|
+
return DEVELOPMENT_PORT
|
152
|
+
return int(config.get_option("browser.serverPort"))
|
153
|
+
|
154
|
+
|
155
|
+
def emit_endpoint_deprecation_notice(handler: RequestHandler, new_path: str) -> None:
|
156
|
+
"""
|
157
|
+
Emits the warning about deprecation of HTTP endpoint in the HTTP header.
|
158
|
+
"""
|
159
|
+
handler.set_header("Deprecation", True)
|
160
|
+
new_url = urljoin(f"{handler.request.protocol}://{handler.request.host}", new_path)
|
161
|
+
handler.set_header("Link", f'<{new_url}>; rel="alternate"')
|