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,223 @@
|
|
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 LocalDiskCacheStorageManager class, which is used
|
16
|
+
to create LocalDiskCacheStorage instances wrapped by InMemoryCacheStorageWrapper,
|
17
|
+
InMemoryCacheStorageWrapper wrapper allows to have first layer of in-memory cache,
|
18
|
+
before accessing to LocalDiskCacheStorage itself.
|
19
|
+
|
20
|
+
Declares the LocalDiskCacheStorage class, which is used to store cached
|
21
|
+
values on disk.
|
22
|
+
|
23
|
+
How these classes work together
|
24
|
+
-------------------------------
|
25
|
+
|
26
|
+
- LocalDiskCacheStorageManager : each instance of this is able
|
27
|
+
to create LocalDiskCacheStorage instances wrapped by InMemoryCacheStorageWrapper,
|
28
|
+
and to clear data from cache storage folder. It is also LocalDiskCacheStorageManager
|
29
|
+
responsibility to check if the context is valid for the storage, and to log warning
|
30
|
+
if the context is not valid.
|
31
|
+
|
32
|
+
- LocalDiskCacheStorage : each instance of this is able to get, set, delete, and clear
|
33
|
+
entries from disk for a single `@st.cache_data` decorated function if `persist="disk"`
|
34
|
+
is used in CacheStorageContext.
|
35
|
+
|
36
|
+
|
37
|
+
┌───────────────────────────────┐
|
38
|
+
│ LocalDiskCacheStorageManager │
|
39
|
+
│ │
|
40
|
+
│ - clear_all │
|
41
|
+
│ - check_context │
|
42
|
+
│ │
|
43
|
+
└──┬────────────────────────────┘
|
44
|
+
│
|
45
|
+
│ ┌──────────────────────────────┐
|
46
|
+
│ │ │
|
47
|
+
│ create(context)│ InMemoryCacheStorageWrapper │
|
48
|
+
└────────────────► │
|
49
|
+
│ ┌─────────────────────┐ │
|
50
|
+
│ │ │ │
|
51
|
+
│ │ LocalDiskStorage │ │
|
52
|
+
│ │ │ │
|
53
|
+
│ └─────────────────────┘ │
|
54
|
+
│ │
|
55
|
+
└──────────────────────────────┘
|
56
|
+
|
57
|
+
"""
|
58
|
+
|
59
|
+
from __future__ import annotations
|
60
|
+
|
61
|
+
import math
|
62
|
+
import os
|
63
|
+
import shutil
|
64
|
+
from typing import Final
|
65
|
+
|
66
|
+
from streamlit import errors
|
67
|
+
from streamlit.file_util import get_streamlit_file_path, streamlit_read, streamlit_write
|
68
|
+
from streamlit.logger import get_logger
|
69
|
+
from streamlit.runtime.caching.storage.cache_storage_protocol import (
|
70
|
+
CacheStorage,
|
71
|
+
CacheStorageContext,
|
72
|
+
CacheStorageError,
|
73
|
+
CacheStorageKeyNotFoundError,
|
74
|
+
CacheStorageManager,
|
75
|
+
)
|
76
|
+
from streamlit.runtime.caching.storage.in_memory_cache_storage_wrapper import (
|
77
|
+
InMemoryCacheStorageWrapper,
|
78
|
+
)
|
79
|
+
|
80
|
+
_LOGGER: Final = get_logger(__name__)
|
81
|
+
|
82
|
+
# Streamlit directory where persisted @st.cache_data objects live.
|
83
|
+
# (This is the same directory that @st.cache persisted objects live.
|
84
|
+
# But @st.cache_data uses a different extension, so they don't overlap.)
|
85
|
+
_CACHE_DIR_NAME: Final = "cache"
|
86
|
+
|
87
|
+
# The extension for our persisted @st.cache_data objects.
|
88
|
+
# (`@st.cache_data` was originally called `@st.memo`)
|
89
|
+
_CACHED_FILE_EXTENSION: Final = "memo"
|
90
|
+
|
91
|
+
|
92
|
+
class LocalDiskCacheStorageManager(CacheStorageManager):
|
93
|
+
def create(self, context: CacheStorageContext) -> CacheStorage:
|
94
|
+
"""Creates a new cache storage instance wrapped with in-memory cache layer"""
|
95
|
+
persist_storage = LocalDiskCacheStorage(context)
|
96
|
+
return InMemoryCacheStorageWrapper(
|
97
|
+
persist_storage=persist_storage, context=context
|
98
|
+
)
|
99
|
+
|
100
|
+
def clear_all(self) -> None:
|
101
|
+
cache_path = get_cache_folder_path()
|
102
|
+
if os.path.isdir(cache_path):
|
103
|
+
shutil.rmtree(cache_path)
|
104
|
+
|
105
|
+
def check_context(self, context: CacheStorageContext) -> None:
|
106
|
+
if (
|
107
|
+
context.persist == "disk"
|
108
|
+
and context.ttl_seconds is not None
|
109
|
+
and not math.isinf(context.ttl_seconds)
|
110
|
+
):
|
111
|
+
_LOGGER.warning(
|
112
|
+
f"The cached function '{context.function_display_name}' has a TTL "
|
113
|
+
"that will be ignored. Persistent cached functions currently don't "
|
114
|
+
"support TTL."
|
115
|
+
)
|
116
|
+
|
117
|
+
|
118
|
+
class LocalDiskCacheStorage(CacheStorage):
|
119
|
+
"""Cache storage that persists data to disk
|
120
|
+
This is the default cache persistence layer for `@st.cache_data`
|
121
|
+
"""
|
122
|
+
|
123
|
+
def __init__(self, context: CacheStorageContext):
|
124
|
+
self.function_key = context.function_key
|
125
|
+
self.persist = context.persist
|
126
|
+
self._ttl_seconds = context.ttl_seconds
|
127
|
+
self._max_entries = context.max_entries
|
128
|
+
|
129
|
+
@property
|
130
|
+
def ttl_seconds(self) -> float:
|
131
|
+
return self._ttl_seconds if self._ttl_seconds is not None else math.inf
|
132
|
+
|
133
|
+
@property
|
134
|
+
def max_entries(self) -> float:
|
135
|
+
return float(self._max_entries) if self._max_entries is not None else math.inf
|
136
|
+
|
137
|
+
def get(self, key: str) -> bytes:
|
138
|
+
"""
|
139
|
+
Returns the stored value for the key if persisted,
|
140
|
+
raise CacheStorageKeyNotFoundError if not found, or not configured
|
141
|
+
with persist="disk"
|
142
|
+
"""
|
143
|
+
if self.persist == "disk":
|
144
|
+
path = self._get_cache_file_path(key)
|
145
|
+
try:
|
146
|
+
with streamlit_read(path, binary=True) as input:
|
147
|
+
value = input.read()
|
148
|
+
_LOGGER.debug("Disk cache HIT: %s", key)
|
149
|
+
return bytes(value)
|
150
|
+
except FileNotFoundError:
|
151
|
+
raise CacheStorageKeyNotFoundError("Key not found in disk cache")
|
152
|
+
except Exception as ex:
|
153
|
+
_LOGGER.exception("Error reading from cache")
|
154
|
+
raise CacheStorageError("Unable to read from cache") from ex
|
155
|
+
else:
|
156
|
+
raise CacheStorageKeyNotFoundError(
|
157
|
+
f"Local disk cache storage is disabled (persist={self.persist})"
|
158
|
+
)
|
159
|
+
|
160
|
+
def set(self, key: str, value: bytes) -> None:
|
161
|
+
"""Sets the value for a given key"""
|
162
|
+
if self.persist == "disk":
|
163
|
+
path = self._get_cache_file_path(key)
|
164
|
+
try:
|
165
|
+
with streamlit_write(path, binary=True) as output:
|
166
|
+
output.write(value)
|
167
|
+
except errors.Error as ex:
|
168
|
+
_LOGGER.debug("Unable to write to cache", exc_info=ex)
|
169
|
+
# Clean up file so we don't leave zero byte files.
|
170
|
+
try:
|
171
|
+
os.remove(path)
|
172
|
+
except (FileNotFoundError, OSError):
|
173
|
+
# If we can't remove the file, it's not a big deal.
|
174
|
+
pass
|
175
|
+
raise CacheStorageError("Unable to write to cache") from ex
|
176
|
+
|
177
|
+
def delete(self, key: str) -> None:
|
178
|
+
"""Delete a cache file from disk. If the file does not exist on disk,
|
179
|
+
return silently. If another exception occurs, log it. Does not throw.
|
180
|
+
"""
|
181
|
+
if self.persist == "disk":
|
182
|
+
path = self._get_cache_file_path(key)
|
183
|
+
try:
|
184
|
+
os.remove(path)
|
185
|
+
except FileNotFoundError:
|
186
|
+
# The file is already removed.
|
187
|
+
pass
|
188
|
+
except Exception as ex:
|
189
|
+
_LOGGER.exception(
|
190
|
+
"Unable to remove a file from the disk cache", exc_info=ex
|
191
|
+
)
|
192
|
+
|
193
|
+
def clear(self) -> None:
|
194
|
+
"""Delete all keys for the current storage"""
|
195
|
+
cache_dir = get_cache_folder_path()
|
196
|
+
|
197
|
+
if os.path.isdir(cache_dir):
|
198
|
+
# We try to remove all files in the cache directory that start with
|
199
|
+
# the function key, whether `clear` called for `self.persist`
|
200
|
+
# storage or not, to avoid leaving orphaned files in the cache directory.
|
201
|
+
for file_name in os.listdir(cache_dir):
|
202
|
+
if self._is_cache_file(file_name):
|
203
|
+
os.remove(os.path.join(cache_dir, file_name))
|
204
|
+
|
205
|
+
def close(self) -> None:
|
206
|
+
"""Dummy implementation of close, we don't need to actually "close" anything"""
|
207
|
+
|
208
|
+
def _get_cache_file_path(self, value_key: str) -> str:
|
209
|
+
"""Return the path of the disk cache file for the given value."""
|
210
|
+
cache_dir = get_cache_folder_path()
|
211
|
+
return os.path.join(
|
212
|
+
cache_dir, f"{self.function_key}-{value_key}.{_CACHED_FILE_EXTENSION}"
|
213
|
+
)
|
214
|
+
|
215
|
+
def _is_cache_file(self, fname: str) -> bool:
|
216
|
+
"""Return true if the given file name is a cache file for this storage."""
|
217
|
+
return fname.startswith(f"{self.function_key}-") and fname.endswith(
|
218
|
+
f".{_CACHED_FILE_EXTENSION}"
|
219
|
+
)
|
220
|
+
|
221
|
+
|
222
|
+
def get_cache_folder_path() -> str:
|
223
|
+
return get_streamlit_file_path(_CACHE_DIR_NAME)
|
@@ -0,0 +1,436 @@
|
|
1
|
+
# Copyright (c) Streamlit Inc. (2018-2022) Snowflake Inc. (2022-2025)
|
2
|
+
#
|
3
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
4
|
+
# you may not use this file except in compliance with the License.
|
5
|
+
# You may obtain a copy of the License at
|
6
|
+
#
|
7
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
8
|
+
#
|
9
|
+
# Unless required by applicable law or agreed to in writing, software
|
10
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
11
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
12
|
+
# See the License for the specific language governing permissions and
|
13
|
+
# limitations under the License.
|
14
|
+
|
15
|
+
from __future__ import annotations
|
16
|
+
|
17
|
+
import os
|
18
|
+
import re
|
19
|
+
from typing import TYPE_CHECKING, Any, Final, Literal, TypeVar, overload
|
20
|
+
|
21
|
+
from streamlit.connections import (
|
22
|
+
BaseConnection,
|
23
|
+
SnowflakeConnection,
|
24
|
+
SnowparkConnection,
|
25
|
+
SQLConnection,
|
26
|
+
)
|
27
|
+
from streamlit.deprecation_util import deprecate_obj_name
|
28
|
+
from streamlit.errors import StreamlitAPIException
|
29
|
+
from streamlit.runtime.caching import cache_resource
|
30
|
+
from streamlit.runtime.metrics_util import gather_metrics
|
31
|
+
from streamlit.runtime.secrets import secrets_singleton
|
32
|
+
|
33
|
+
if TYPE_CHECKING:
|
34
|
+
from datetime import timedelta
|
35
|
+
|
36
|
+
# NOTE: Adding support for a new first party connection requires:
|
37
|
+
# 1. Adding the new connection name and class to this dict.
|
38
|
+
# 2. Writing two new @overloads for connection_factory (one for the case where the
|
39
|
+
# only the connection name is specified and another when both name and type are).
|
40
|
+
# 3. Updating test_get_first_party_connection_helper in connection_factory_test.py.
|
41
|
+
FIRST_PARTY_CONNECTIONS = {
|
42
|
+
"snowflake": SnowflakeConnection,
|
43
|
+
"snowpark": SnowparkConnection,
|
44
|
+
"sql": SQLConnection,
|
45
|
+
}
|
46
|
+
MODULE_EXTRACTION_REGEX = re.compile(r"No module named \'(.+)\'")
|
47
|
+
MODULES_TO_PYPI_PACKAGES: Final[dict[str, str]] = {
|
48
|
+
"MySQLdb": "mysqlclient",
|
49
|
+
"psycopg2": "psycopg2-binary",
|
50
|
+
"sqlalchemy": "sqlalchemy",
|
51
|
+
"snowflake": "snowflake-connector-python",
|
52
|
+
"snowflake.connector": "snowflake-connector-python",
|
53
|
+
"snowflake.snowpark": "snowflake-snowpark-python",
|
54
|
+
}
|
55
|
+
|
56
|
+
# The BaseConnection bound is parameterized to `Any` below as subclasses of
|
57
|
+
# BaseConnection are responsible for binding the type parameter of BaseConnection to a
|
58
|
+
# concrete type, but the type it gets bound to isn't important to us here.
|
59
|
+
ConnectionClass = TypeVar("ConnectionClass", bound=BaseConnection[Any])
|
60
|
+
|
61
|
+
|
62
|
+
@gather_metrics("connection")
|
63
|
+
def _create_connection(
|
64
|
+
name: str,
|
65
|
+
connection_class: type[ConnectionClass],
|
66
|
+
max_entries: int | None = None,
|
67
|
+
ttl: float | timedelta | None = None,
|
68
|
+
**kwargs,
|
69
|
+
) -> ConnectionClass:
|
70
|
+
"""Create an instance of connection_class with the given name and kwargs.
|
71
|
+
|
72
|
+
The weird implementation of this function with the @cache_resource annotated
|
73
|
+
function defined internally is done to:
|
74
|
+
- Always @gather_metrics on the call even if the return value is a cached one.
|
75
|
+
- Allow the user to specify ttl and max_entries when calling st.connection.
|
76
|
+
"""
|
77
|
+
|
78
|
+
def __create_connection(
|
79
|
+
name: str, connection_class: type[ConnectionClass], **kwargs
|
80
|
+
) -> ConnectionClass:
|
81
|
+
return connection_class(connection_name=name, **kwargs)
|
82
|
+
|
83
|
+
if not issubclass(connection_class, BaseConnection):
|
84
|
+
raise StreamlitAPIException(
|
85
|
+
f"{connection_class} is not a subclass of BaseConnection!"
|
86
|
+
)
|
87
|
+
|
88
|
+
# We modify our helper function's `__qualname__` here to work around default
|
89
|
+
# `@st.cache_resource` behavior. Otherwise, `st.connection` being called with
|
90
|
+
# different `ttl` or `max_entries` values will reset the cache with each call.
|
91
|
+
ttl_str = str(ttl).replace( # Avoid adding extra `.` characters to `__qualname__`
|
92
|
+
".", "_"
|
93
|
+
)
|
94
|
+
__create_connection.__qualname__ = (
|
95
|
+
f"{__create_connection.__qualname__}_{ttl_str}_{max_entries}"
|
96
|
+
)
|
97
|
+
__create_connection = cache_resource(
|
98
|
+
max_entries=max_entries,
|
99
|
+
show_spinner="Running `st.connection(...)`.",
|
100
|
+
ttl=ttl,
|
101
|
+
)(__create_connection)
|
102
|
+
|
103
|
+
return __create_connection(name, connection_class, **kwargs)
|
104
|
+
|
105
|
+
|
106
|
+
def _get_first_party_connection(connection_class: str):
|
107
|
+
if connection_class in FIRST_PARTY_CONNECTIONS:
|
108
|
+
return FIRST_PARTY_CONNECTIONS[connection_class]
|
109
|
+
|
110
|
+
raise StreamlitAPIException(
|
111
|
+
f"Invalid connection '{connection_class}'. "
|
112
|
+
f"Supported connection classes: {FIRST_PARTY_CONNECTIONS}"
|
113
|
+
)
|
114
|
+
|
115
|
+
|
116
|
+
@overload
|
117
|
+
def connection_factory(
|
118
|
+
name: Literal["sql"],
|
119
|
+
max_entries: int | None = None,
|
120
|
+
ttl: float | timedelta | None = None,
|
121
|
+
autocommit: bool = False,
|
122
|
+
**kwargs,
|
123
|
+
) -> SQLConnection:
|
124
|
+
pass
|
125
|
+
|
126
|
+
|
127
|
+
@overload
|
128
|
+
def connection_factory(
|
129
|
+
name: str,
|
130
|
+
type: Literal["sql"],
|
131
|
+
max_entries: int | None = None,
|
132
|
+
ttl: float | timedelta | None = None,
|
133
|
+
autocommit: bool = False,
|
134
|
+
**kwargs,
|
135
|
+
) -> SQLConnection:
|
136
|
+
pass
|
137
|
+
|
138
|
+
|
139
|
+
@overload
|
140
|
+
def connection_factory(
|
141
|
+
name: Literal["snowflake"],
|
142
|
+
max_entries: int | None = None,
|
143
|
+
ttl: float | timedelta | None = None,
|
144
|
+
autocommit: bool = False,
|
145
|
+
**kwargs,
|
146
|
+
) -> SnowflakeConnection:
|
147
|
+
pass
|
148
|
+
|
149
|
+
|
150
|
+
@overload
|
151
|
+
def connection_factory(
|
152
|
+
name: str,
|
153
|
+
type: Literal["snowflake"],
|
154
|
+
max_entries: int | None = None,
|
155
|
+
ttl: float | timedelta | None = None,
|
156
|
+
autocommit: bool = False,
|
157
|
+
**kwargs,
|
158
|
+
) -> SnowflakeConnection:
|
159
|
+
pass
|
160
|
+
|
161
|
+
|
162
|
+
@overload
|
163
|
+
def connection_factory(
|
164
|
+
name: Literal["snowpark"],
|
165
|
+
max_entries: int | None = None,
|
166
|
+
ttl: float | timedelta | None = None,
|
167
|
+
**kwargs,
|
168
|
+
) -> SnowparkConnection:
|
169
|
+
pass
|
170
|
+
|
171
|
+
|
172
|
+
@overload
|
173
|
+
def connection_factory(
|
174
|
+
name: str,
|
175
|
+
type: Literal["snowpark"],
|
176
|
+
max_entries: int | None = None,
|
177
|
+
ttl: float | timedelta | None = None,
|
178
|
+
**kwargs,
|
179
|
+
) -> SnowparkConnection:
|
180
|
+
pass
|
181
|
+
|
182
|
+
|
183
|
+
@overload
|
184
|
+
def connection_factory(
|
185
|
+
name: str,
|
186
|
+
type: type[ConnectionClass],
|
187
|
+
max_entries: int | None = None,
|
188
|
+
ttl: float | timedelta | None = None,
|
189
|
+
**kwargs,
|
190
|
+
) -> ConnectionClass:
|
191
|
+
pass
|
192
|
+
|
193
|
+
|
194
|
+
@overload
|
195
|
+
def connection_factory(
|
196
|
+
name: str,
|
197
|
+
type: str | None = None,
|
198
|
+
max_entries: int | None = None,
|
199
|
+
ttl: float | timedelta | None = None,
|
200
|
+
**kwargs,
|
201
|
+
) -> BaseConnection[Any]:
|
202
|
+
pass
|
203
|
+
|
204
|
+
|
205
|
+
def connection_factory(
|
206
|
+
name,
|
207
|
+
type=None,
|
208
|
+
max_entries=None,
|
209
|
+
ttl=None,
|
210
|
+
**kwargs,
|
211
|
+
):
|
212
|
+
"""Create a new connection to a data store or API, or return an existing one.
|
213
|
+
|
214
|
+
Configuration options, credentials, and secrets for connections are
|
215
|
+
combined from the following sources:
|
216
|
+
|
217
|
+
- The keyword arguments passed to this command.
|
218
|
+
- The app's ``secrets.toml`` files.
|
219
|
+
- Any connection-specific configuration files.
|
220
|
+
|
221
|
+
The connection returned from ``st.connection`` is internally cached with
|
222
|
+
``st.cache_resource`` and is therefore shared between sessions.
|
223
|
+
|
224
|
+
Parameters
|
225
|
+
----------
|
226
|
+
name : str
|
227
|
+
The connection name used for secrets lookup in ``secrets.toml``.
|
228
|
+
Streamlit uses secrets under ``[connections.<name>]`` for the
|
229
|
+
connection. ``type`` will be inferred if ``name`` is one of the
|
230
|
+
following: ``"snowflake"``, ``"snowpark"``, or ``"sql"``.
|
231
|
+
|
232
|
+
type : str, connection class, or None
|
233
|
+
The type of connection to create. This can be one of the following:
|
234
|
+
|
235
|
+
- ``None`` (default): Streamlit will infer the connection type from
|
236
|
+
``name``. If the type is not inferrable from ``name``, the type must
|
237
|
+
be specified in ``secrets.toml`` instead.
|
238
|
+
- ``"snowflake"``: Streamlit will initialize a connection with
|
239
|
+
|SnowflakeConnection|_.
|
240
|
+
- ``"snowpark"``: Streamlit will initialize a connection with
|
241
|
+
|SnowparkConnection|_. This is deprecated.
|
242
|
+
- ``"sql"``: Streamlit will initialize a connection with
|
243
|
+
|SQLConnection|_.
|
244
|
+
- A string path to an importable class: This must be a dot-separated
|
245
|
+
module path ending in the importable class. Streamlit will import the
|
246
|
+
class and initialize a connection with it. The class must extend
|
247
|
+
``st.connections.BaseConnection``.
|
248
|
+
- An imported class reference: Streamlit will initialize a connection
|
249
|
+
with the referenced class, which must extend
|
250
|
+
``st.connections.BaseConnection``.
|
251
|
+
|
252
|
+
.. |SnowflakeConnection| replace:: ``SnowflakeConnection``
|
253
|
+
.. _SnowflakeConnection: https://docs.streamlit.io/develop/api-reference/connections/st.connections.snowflakeconnection
|
254
|
+
.. |SnowparkConnection| replace:: ``SnowparkConnection``
|
255
|
+
.. _SnowparkConnection: https://docs.streamlit.io/develop/api-reference/connections/st.connections.snowparkconnection
|
256
|
+
.. |SQLConnection| replace:: ``SQLConnection``
|
257
|
+
.. _SQLConnection: https://docs.streamlit.io/develop/api-reference/connections/st.connections.sqlconnection
|
258
|
+
|
259
|
+
max_entries : int or None
|
260
|
+
The maximum number of connections to keep in the cache.
|
261
|
+
If this is ``None`` (default), the cache is unbounded. Otherwise, when
|
262
|
+
a new entry is added to a full cache, the oldest cached entry is
|
263
|
+
removed.
|
264
|
+
ttl : float, timedelta, or None
|
265
|
+
The maximum number of seconds to keep results in the cache.
|
266
|
+
If this is ``None`` (default), cached results do not expire with time.
|
267
|
+
**kwargs : any
|
268
|
+
Connection-specific keyword arguments that are passed to the
|
269
|
+
connection's ``._connect()`` method. ``**kwargs`` are typically
|
270
|
+
combined with (and take precendence over) key-value pairs in
|
271
|
+
``secrets.toml``. To learn more, see the specific connection's
|
272
|
+
documentation.
|
273
|
+
|
274
|
+
Returns
|
275
|
+
-------
|
276
|
+
Subclass of BaseConnection
|
277
|
+
An initialized connection object of the specified ``type``.
|
278
|
+
|
279
|
+
Examples
|
280
|
+
--------
|
281
|
+
|
282
|
+
**Example 1: Inferred connection type**
|
283
|
+
|
284
|
+
The easiest way to create a first-party (SQL, Snowflake, or Snowpark) connection is
|
285
|
+
to use their default names and define corresponding sections in your ``secrets.toml``
|
286
|
+
file. The following example creates a ``"sql"``-type connection.
|
287
|
+
|
288
|
+
``.streamlit/secrets.toml``:
|
289
|
+
|
290
|
+
>>> [connections.sql]
|
291
|
+
>>> dialect = "xxx"
|
292
|
+
>>> host = "xxx"
|
293
|
+
>>> username = "xxx"
|
294
|
+
>>> password = "xxx"
|
295
|
+
|
296
|
+
Your app code:
|
297
|
+
|
298
|
+
>>> import streamlit as st
|
299
|
+
>>> conn = st.connection("sql")
|
300
|
+
|
301
|
+
**Example 2: Named connections**
|
302
|
+
|
303
|
+
Creating a connection with a custom name requires you to explicitly
|
304
|
+
specify the type. If ``type`` is not passed as a keyword argument, it must
|
305
|
+
be set in the appropriate section of ``secrets.toml``. The following
|
306
|
+
example creates two ``"sql"``-type connections, each with their own
|
307
|
+
custom name. The first defines ``type`` in the ``st.connection`` command;
|
308
|
+
the second defines ``type`` in ``secrets.toml``.
|
309
|
+
|
310
|
+
``.streamlit/secrets.toml``:
|
311
|
+
|
312
|
+
>>> [connections.first_connection]
|
313
|
+
>>> dialect = "xxx"
|
314
|
+
>>> host = "xxx"
|
315
|
+
>>> username = "xxx"
|
316
|
+
>>> password = "xxx"
|
317
|
+
>>>
|
318
|
+
>>> [connections.second_connection]
|
319
|
+
>>> type = "sql"
|
320
|
+
>>> dialect = "yyy"
|
321
|
+
>>> host = "yyy"
|
322
|
+
>>> username = "yyy"
|
323
|
+
>>> password = "yyy"
|
324
|
+
|
325
|
+
Your app code:
|
326
|
+
|
327
|
+
>>> import streamlit as st
|
328
|
+
>>> conn1 = st.connection("first_connection", type="sql")
|
329
|
+
>>> conn2 = st.connection("second_connection")
|
330
|
+
|
331
|
+
**Example 3: Using a path to the connection class**
|
332
|
+
|
333
|
+
Passing the full module path to the connection class can be useful,
|
334
|
+
especially when working with a custom connection. Although this is not the
|
335
|
+
typical way to create first party connections, the following example
|
336
|
+
creates the same type of connection as one with ``type="sql"``. Note that
|
337
|
+
``type`` is a string path.
|
338
|
+
|
339
|
+
``.streamlit/secrets.toml``:
|
340
|
+
|
341
|
+
>>> [connections.my_sql_connection]
|
342
|
+
>>> url = "xxx+xxx://xxx:xxx@xxx:xxx/xxx"
|
343
|
+
|
344
|
+
Your app code:
|
345
|
+
|
346
|
+
>>> import streamlit as st
|
347
|
+
>>> conn = st.connection(
|
348
|
+
... "my_sql_connection", type="streamlit.connections.SQLConnection"
|
349
|
+
... )
|
350
|
+
|
351
|
+
**Example 4: Importing the connection class**
|
352
|
+
|
353
|
+
You can pass the connection class directly to the ``st.connection``
|
354
|
+
command. Doing so allows static type checking tools such as ``mypy`` to
|
355
|
+
infer the exact return type of ``st.connection``. The following example
|
356
|
+
creates the same connection as in Example 3.
|
357
|
+
|
358
|
+
``.streamlit/secrets.toml``:
|
359
|
+
|
360
|
+
>>> [connections.my_sql_connection]
|
361
|
+
>>> url = "xxx+xxx://xxx:xxx@xxx:xxx/xxx"
|
362
|
+
|
363
|
+
Your app code:
|
364
|
+
|
365
|
+
>>> import streamlit as st
|
366
|
+
>>> from streamlit.connections import SQLConnection
|
367
|
+
>>> conn = st.connection("my_sql_connection", type=SQLConnection)
|
368
|
+
|
369
|
+
"""
|
370
|
+
USE_ENV_PREFIX = "env:"
|
371
|
+
|
372
|
+
if name.startswith(USE_ENV_PREFIX):
|
373
|
+
# It'd be nice to use str.removeprefix() here, but we won't be able to do that
|
374
|
+
# until the minimium Python version we support is 3.9.
|
375
|
+
envvar_name = name[len(USE_ENV_PREFIX) :]
|
376
|
+
name = os.environ[envvar_name]
|
377
|
+
|
378
|
+
if type is None:
|
379
|
+
if name in FIRST_PARTY_CONNECTIONS:
|
380
|
+
# We allow users to simply write `st.connection("sql")` instead of
|
381
|
+
# `st.connection("sql", type="sql")`.
|
382
|
+
type = _get_first_party_connection(name)
|
383
|
+
else:
|
384
|
+
# The user didn't specify a type, so we try to pull it out from their
|
385
|
+
# secrets.toml file. NOTE: we're okay with any of the dict lookups below
|
386
|
+
# exploding with a KeyError since, if type isn't explicitly specified here,
|
387
|
+
# it must be the case that it's defined in secrets.toml and should raise an
|
388
|
+
# Exception otherwise.
|
389
|
+
secrets_singleton.load_if_toml_exists()
|
390
|
+
type = secrets_singleton["connections"][name]["type"]
|
391
|
+
|
392
|
+
# type is a nice kwarg name for the st.connection user but is annoying to work with
|
393
|
+
# since it conflicts with the builtin function name and thus gets syntax
|
394
|
+
# highlighted.
|
395
|
+
connection_class = type
|
396
|
+
|
397
|
+
if isinstance(connection_class, str):
|
398
|
+
# We assume that a connection_class specified via string is either the fully
|
399
|
+
# qualified name of a class (its module and exported classname) or the string
|
400
|
+
# literal shorthand for one of our first party connections. In the former case,
|
401
|
+
# connection_class will always contain a "." in its name.
|
402
|
+
if "." in connection_class:
|
403
|
+
parts = connection_class.split(".")
|
404
|
+
classname = parts.pop()
|
405
|
+
|
406
|
+
import importlib
|
407
|
+
|
408
|
+
connection_module = importlib.import_module(".".join(parts))
|
409
|
+
connection_class = getattr(connection_module, classname)
|
410
|
+
else:
|
411
|
+
connection_class = _get_first_party_connection(connection_class)
|
412
|
+
|
413
|
+
# At this point, connection_class should be of type Type[ConnectionClass].
|
414
|
+
try:
|
415
|
+
conn = _create_connection(
|
416
|
+
name, connection_class, max_entries=max_entries, ttl=ttl, **kwargs
|
417
|
+
)
|
418
|
+
if isinstance(conn, SnowparkConnection):
|
419
|
+
conn = deprecate_obj_name(
|
420
|
+
conn,
|
421
|
+
'connection("snowpark")',
|
422
|
+
'connection("snowflake")',
|
423
|
+
"2024-04-01",
|
424
|
+
)
|
425
|
+
return conn
|
426
|
+
except ModuleNotFoundError as e:
|
427
|
+
err_string = str(e)
|
428
|
+
missing_module = re.search(MODULE_EXTRACTION_REGEX, err_string)
|
429
|
+
|
430
|
+
extra_info = "You may be missing a dependency required to use this connection."
|
431
|
+
if missing_module:
|
432
|
+
pypi_package = MODULES_TO_PYPI_PACKAGES.get(missing_module.group(1))
|
433
|
+
if pypi_package:
|
434
|
+
extra_info = f"You need to install the '{pypi_package}' package to use this connection."
|
435
|
+
|
436
|
+
raise ModuleNotFoundError(f"{str(e)}. {extra_info}")
|