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,523 @@
|
|
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
|
+
"""Common cache logic shared by st.cache_data and st.cache_resource."""
|
16
|
+
|
17
|
+
from __future__ import annotations
|
18
|
+
|
19
|
+
import contextlib
|
20
|
+
import functools
|
21
|
+
import hashlib
|
22
|
+
import inspect
|
23
|
+
import threading
|
24
|
+
import time
|
25
|
+
from abc import abstractmethod
|
26
|
+
from collections import defaultdict
|
27
|
+
from typing import TYPE_CHECKING, Any, Callable, Final
|
28
|
+
|
29
|
+
from streamlit import type_util
|
30
|
+
from streamlit.dataframe_util import is_unevaluated_data_object
|
31
|
+
from streamlit.elements.spinner import spinner
|
32
|
+
from streamlit.logger import get_logger
|
33
|
+
from streamlit.runtime.caching.cache_errors import (
|
34
|
+
CacheError,
|
35
|
+
CacheKeyNotFoundError,
|
36
|
+
UnevaluatedDataFrameError,
|
37
|
+
UnhashableParamError,
|
38
|
+
UnhashableTypeError,
|
39
|
+
UnserializableReturnValueError,
|
40
|
+
get_cached_func_name_md,
|
41
|
+
)
|
42
|
+
from streamlit.runtime.caching.cached_message_replay import (
|
43
|
+
CachedMessageReplayContext,
|
44
|
+
CachedResult,
|
45
|
+
MsgData,
|
46
|
+
replay_cached_messages,
|
47
|
+
)
|
48
|
+
from streamlit.runtime.caching.hashing import HashFuncsDict, update_hash
|
49
|
+
from streamlit.runtime.scriptrunner_utils.script_run_context import (
|
50
|
+
in_cached_function,
|
51
|
+
)
|
52
|
+
|
53
|
+
if TYPE_CHECKING:
|
54
|
+
from types import FunctionType
|
55
|
+
|
56
|
+
from streamlit.runtime.caching.cache_type import CacheType
|
57
|
+
|
58
|
+
_LOGGER: Final = get_logger(__name__)
|
59
|
+
|
60
|
+
# The timer function we use with TTLCache. This is the default timer func, but
|
61
|
+
# is exposed here as a constant so that it can be patched in unit tests.
|
62
|
+
TTLCACHE_TIMER = time.monotonic
|
63
|
+
|
64
|
+
|
65
|
+
class Cache:
|
66
|
+
"""Function cache interface. Caches persist across script runs."""
|
67
|
+
|
68
|
+
def __init__(self):
|
69
|
+
self._value_locks: dict[str, threading.Lock] = defaultdict(threading.Lock)
|
70
|
+
self._value_locks_lock = threading.Lock()
|
71
|
+
|
72
|
+
@abstractmethod
|
73
|
+
def read_result(self, value_key: str) -> CachedResult:
|
74
|
+
"""Read a value and associated messages from the cache.
|
75
|
+
|
76
|
+
Raises
|
77
|
+
------
|
78
|
+
CacheKeyNotFoundError
|
79
|
+
Raised if value_key is not in the cache.
|
80
|
+
|
81
|
+
"""
|
82
|
+
raise NotImplementedError
|
83
|
+
|
84
|
+
@abstractmethod
|
85
|
+
def write_result(self, value_key: str, value: Any, messages: list[MsgData]) -> None:
|
86
|
+
"""Write a value and associated messages to the cache, overwriting any existing
|
87
|
+
result that uses the value_key.
|
88
|
+
"""
|
89
|
+
# We *could* `del self._value_locks[value_key]` here, since nobody will be taking
|
90
|
+
# a compute_value_lock for this value_key after the result is written.
|
91
|
+
raise NotImplementedError
|
92
|
+
|
93
|
+
def compute_value_lock(self, value_key: str) -> threading.Lock:
|
94
|
+
"""Return the lock that should be held while computing a new cached value.
|
95
|
+
In a popular app with a cache that hasn't been pre-warmed, many sessions may try
|
96
|
+
to access a not-yet-cached value simultaneously. We use a lock to ensure that
|
97
|
+
only one of those sessions computes the value, and the others block until
|
98
|
+
the value is computed.
|
99
|
+
"""
|
100
|
+
with self._value_locks_lock:
|
101
|
+
return self._value_locks[value_key]
|
102
|
+
|
103
|
+
def clear(self, key: str | None = None):
|
104
|
+
"""Clear values from this cache.
|
105
|
+
If no argument is passed, all items are cleared from the cache.
|
106
|
+
A key can be passed to clear that key from the cache only."""
|
107
|
+
with self._value_locks_lock:
|
108
|
+
if not key:
|
109
|
+
self._value_locks.clear()
|
110
|
+
elif key in self._value_locks:
|
111
|
+
del self._value_locks[key]
|
112
|
+
self._clear(key=key)
|
113
|
+
|
114
|
+
@abstractmethod
|
115
|
+
def _clear(self, key: str | None = None) -> None:
|
116
|
+
"""Subclasses must implement this to perform cache-clearing logic."""
|
117
|
+
raise NotImplementedError
|
118
|
+
|
119
|
+
|
120
|
+
class CachedFuncInfo:
|
121
|
+
"""Encapsulates data for a cached function instance.
|
122
|
+
|
123
|
+
CachedFuncInfo instances are scoped to a single script run - they're not
|
124
|
+
persistent.
|
125
|
+
"""
|
126
|
+
|
127
|
+
def __init__(
|
128
|
+
self,
|
129
|
+
func: FunctionType,
|
130
|
+
show_spinner: bool | str,
|
131
|
+
hash_funcs: HashFuncsDict | None,
|
132
|
+
):
|
133
|
+
self.func = func
|
134
|
+
self.show_spinner = show_spinner
|
135
|
+
self.hash_funcs = hash_funcs
|
136
|
+
|
137
|
+
@property
|
138
|
+
def cache_type(self) -> CacheType:
|
139
|
+
raise NotImplementedError
|
140
|
+
|
141
|
+
@property
|
142
|
+
def cached_message_replay_ctx(self) -> CachedMessageReplayContext:
|
143
|
+
raise NotImplementedError
|
144
|
+
|
145
|
+
def get_function_cache(self, function_key: str) -> Cache:
|
146
|
+
"""Get or create the function cache for the given key."""
|
147
|
+
raise NotImplementedError
|
148
|
+
|
149
|
+
|
150
|
+
def make_cached_func_wrapper(info: CachedFuncInfo) -> Callable[..., Any]:
|
151
|
+
"""Create a callable wrapper around a CachedFunctionInfo.
|
152
|
+
|
153
|
+
Calling the wrapper will return the cached value if it's already been
|
154
|
+
computed, and will call the underlying function to compute and cache the
|
155
|
+
value otherwise.
|
156
|
+
|
157
|
+
The wrapper also has a `clear` function that can be called to clear
|
158
|
+
some or all of the wrapper's cached values.
|
159
|
+
"""
|
160
|
+
cached_func = CachedFunc(info)
|
161
|
+
return functools.update_wrapper(cached_func, info.func)
|
162
|
+
|
163
|
+
|
164
|
+
class BoundCachedFunc:
|
165
|
+
"""A wrapper around a CachedFunc that binds it to a specific instance in case of
|
166
|
+
decorated function is a class method."""
|
167
|
+
|
168
|
+
def __init__(self, cached_func: CachedFunc, instance: Any):
|
169
|
+
self._cached_func = cached_func
|
170
|
+
self._instance = instance
|
171
|
+
|
172
|
+
def __call__(self, *args, **kwargs) -> Any:
|
173
|
+
return self._cached_func(self._instance, *args, **kwargs)
|
174
|
+
|
175
|
+
def __repr__(self):
|
176
|
+
return f"<BoundCachedFunc: {self._cached_func._info.func} of {self._instance}>"
|
177
|
+
|
178
|
+
def clear(self, *args, **kwargs):
|
179
|
+
if args or kwargs:
|
180
|
+
# The instance is required as first parameter to allow
|
181
|
+
# args to be correctly resolved to the parameter names:
|
182
|
+
self._cached_func.clear(self._instance, *args, **kwargs)
|
183
|
+
else:
|
184
|
+
# if no args/kwargs are specified, we just want to clear the
|
185
|
+
# entire cache of this method:
|
186
|
+
self._cached_func.clear()
|
187
|
+
|
188
|
+
|
189
|
+
class CachedFunc:
|
190
|
+
def __init__(self, info: CachedFuncInfo):
|
191
|
+
self._info = info
|
192
|
+
self._function_key = _make_function_key(info.cache_type, info.func)
|
193
|
+
|
194
|
+
def __repr__(self):
|
195
|
+
return f"<CachedFunc: {self._info.func}>"
|
196
|
+
|
197
|
+
def __get__(self, instance, owner=None):
|
198
|
+
"""CachedFunc implements descriptor protocol to support cache methods."""
|
199
|
+
if instance is None:
|
200
|
+
return self
|
201
|
+
|
202
|
+
return functools.update_wrapper(BoundCachedFunc(self, instance), self)
|
203
|
+
|
204
|
+
def __call__(self, *args, **kwargs) -> Any:
|
205
|
+
"""The wrapper. We'll only call our underlying function on a cache miss."""
|
206
|
+
|
207
|
+
spinner_message: str | None = None
|
208
|
+
if isinstance(self._info.show_spinner, str):
|
209
|
+
spinner_message = self._info.show_spinner
|
210
|
+
elif self._info.show_spinner is True:
|
211
|
+
name = self._info.func.__qualname__
|
212
|
+
if len(args) == 0 and len(kwargs) == 0:
|
213
|
+
spinner_message = f"Running `{name}()`."
|
214
|
+
else:
|
215
|
+
spinner_message = f"Running `{name}(...)`."
|
216
|
+
|
217
|
+
return self._get_or_create_cached_value(args, kwargs, spinner_message)
|
218
|
+
|
219
|
+
def _get_or_create_cached_value(
|
220
|
+
self,
|
221
|
+
func_args: tuple[Any, ...],
|
222
|
+
func_kwargs: dict[str, Any],
|
223
|
+
spinner_message: str | None = None,
|
224
|
+
) -> Any:
|
225
|
+
# Retrieve the function's cache object. We must do this "just-in-time"
|
226
|
+
# (as opposed to in the constructor), because caches can be invalidated
|
227
|
+
# at any time.
|
228
|
+
cache = self._info.get_function_cache(self._function_key)
|
229
|
+
|
230
|
+
# Generate the key for the cached value. This is based on the
|
231
|
+
# arguments passed to the function.
|
232
|
+
value_key = _make_value_key(
|
233
|
+
cache_type=self._info.cache_type,
|
234
|
+
func=self._info.func,
|
235
|
+
func_args=func_args,
|
236
|
+
func_kwargs=func_kwargs,
|
237
|
+
hash_funcs=self._info.hash_funcs,
|
238
|
+
)
|
239
|
+
|
240
|
+
with contextlib.suppress(CacheKeyNotFoundError):
|
241
|
+
cached_result = cache.read_result(value_key)
|
242
|
+
return self._handle_cache_hit(cached_result)
|
243
|
+
|
244
|
+
# only show spinner if there is a message to show and always only for the
|
245
|
+
# outermost cache function if cache functions are nested, because the outermost
|
246
|
+
# function has to wait for the inner functions anyways. This avoids surprising
|
247
|
+
# users with slowdowned apps in case the inner functions are called very often,
|
248
|
+
# which would lead to a ton of (empty/spinner) proto messages that will make the
|
249
|
+
# app slow (see https://github.com/streamlit/streamlit/issues/9951). This is
|
250
|
+
# basically like auto-setting "show_spinner=False" on the @st.cache decorators
|
251
|
+
# on behalf of the user.
|
252
|
+
is_nested_cache_function = in_cached_function.get()
|
253
|
+
spinner_or_no_context = (
|
254
|
+
spinner(spinner_message, _cache=True)
|
255
|
+
if spinner_message is not None and not is_nested_cache_function
|
256
|
+
else contextlib.nullcontext()
|
257
|
+
)
|
258
|
+
with spinner_or_no_context:
|
259
|
+
return self._handle_cache_miss(cache, value_key, func_args, func_kwargs)
|
260
|
+
|
261
|
+
def _handle_cache_hit(self, result: CachedResult) -> Any:
|
262
|
+
"""Handle a cache hit: replay the result's cached messages, and return its
|
263
|
+
value."""
|
264
|
+
replay_cached_messages(
|
265
|
+
result,
|
266
|
+
self._info.cache_type,
|
267
|
+
self._info.func,
|
268
|
+
)
|
269
|
+
return result.value
|
270
|
+
|
271
|
+
def _handle_cache_miss(
|
272
|
+
self,
|
273
|
+
cache: Cache,
|
274
|
+
value_key: str,
|
275
|
+
func_args: tuple[Any, ...],
|
276
|
+
func_kwargs: dict[str, Any],
|
277
|
+
) -> Any:
|
278
|
+
"""Handle a cache miss: compute a new cached value, write it back to the cache,
|
279
|
+
and return that newly-computed value.
|
280
|
+
"""
|
281
|
+
|
282
|
+
# Implementation notes:
|
283
|
+
# - We take a "compute_value_lock" before computing our value. This ensures that
|
284
|
+
# multiple sessions don't try to compute the same value simultaneously.
|
285
|
+
#
|
286
|
+
# - We use a different lock for each value_key, as opposed to a single lock for
|
287
|
+
# the entire cache, so that unrelated value computations don't block on each other.
|
288
|
+
#
|
289
|
+
# - When retrieving a cache entry that may not yet exist, we use a "double-checked locking"
|
290
|
+
# strategy: first we try to retrieve the cache entry without taking a value lock. (This
|
291
|
+
# happens in `_get_or_create_cached_value()`.) If that fails because the value hasn't
|
292
|
+
# been computed yet, we take the value lock and then immediately try to retrieve cache entry
|
293
|
+
# *again*, while holding the lock. If the cache entry exists at this point, it means that
|
294
|
+
# another thread computed the value before us.
|
295
|
+
#
|
296
|
+
# This means that the happy path ("cache entry exists") is a wee bit faster because
|
297
|
+
# no lock is acquired. But the unhappy path ("cache entry needs to be recomputed") is
|
298
|
+
# a wee bit slower, because we do two lookups for the entry.
|
299
|
+
|
300
|
+
with cache.compute_value_lock(value_key):
|
301
|
+
# We've acquired the lock - but another thread may have acquired it first
|
302
|
+
# and already computed the value. So we need to test for a cache hit again,
|
303
|
+
# before computing.
|
304
|
+
try:
|
305
|
+
cached_result = cache.read_result(value_key)
|
306
|
+
# Another thread computed the value before us. Early exit!
|
307
|
+
return self._handle_cache_hit(cached_result)
|
308
|
+
except CacheKeyNotFoundError:
|
309
|
+
# No cache hit -> we will call the cached function
|
310
|
+
# below.
|
311
|
+
pass
|
312
|
+
|
313
|
+
# We acquired the lock before any other thread. Compute the value!
|
314
|
+
with self._info.cached_message_replay_ctx.calling_cached_function(
|
315
|
+
self._info.func
|
316
|
+
):
|
317
|
+
computed_value = self._info.func(*func_args, **func_kwargs)
|
318
|
+
|
319
|
+
# We've computed our value, and now we need to write it back to the cache
|
320
|
+
# along with any "replay messages" that were generated during value computation.
|
321
|
+
messages = self._info.cached_message_replay_ctx._most_recent_messages
|
322
|
+
try:
|
323
|
+
cache.write_result(value_key, computed_value, messages)
|
324
|
+
return computed_value
|
325
|
+
except (CacheError, RuntimeError) as ex:
|
326
|
+
# An exception was thrown while we tried to write to the cache. Report
|
327
|
+
# it to the user. (We catch `RuntimeError` here because it will be
|
328
|
+
# raised by Apache Spark if we do not collect dataframe before
|
329
|
+
# using `st.cache_data`.)
|
330
|
+
if is_unevaluated_data_object(computed_value):
|
331
|
+
# If the returned value is an unevaluated dataframe, raise an error.
|
332
|
+
# Unevaluated dataframes are not yet in the local memory, which also
|
333
|
+
# means they cannot be properly cached (serialized).
|
334
|
+
raise UnevaluatedDataFrameError(
|
335
|
+
f"The function {get_cached_func_name_md(self._info.func)} is "
|
336
|
+
"decorated with `st.cache_data` but it returns an unevaluated "
|
337
|
+
f"data object of type `{type_util.get_fqn_type(computed_value)}`. "
|
338
|
+
"Please convert the object to a serializable format "
|
339
|
+
"(e.g. Pandas DataFrame) before returning it, so "
|
340
|
+
"`st.cache_data` can serialize and cache it."
|
341
|
+
) from ex
|
342
|
+
raise UnserializableReturnValueError(
|
343
|
+
return_value=computed_value, func=self._info.func
|
344
|
+
)
|
345
|
+
|
346
|
+
def clear(self, *args, **kwargs):
|
347
|
+
"""Clear the cached function's associated cache.
|
348
|
+
|
349
|
+
If no arguments are passed, Streamlit will clear all values cached for
|
350
|
+
the function. If arguments are passed, Streamlit will clear the cached
|
351
|
+
value for these arguments only.
|
352
|
+
|
353
|
+
Parameters
|
354
|
+
----------
|
355
|
+
|
356
|
+
*args: Any
|
357
|
+
Arguments of the cached functions.
|
358
|
+
|
359
|
+
**kwargs: Any
|
360
|
+
Keyword arguments of the cached function.
|
361
|
+
|
362
|
+
Example
|
363
|
+
-------
|
364
|
+
>>> import streamlit as st
|
365
|
+
>>> import time
|
366
|
+
>>>
|
367
|
+
>>> @st.cache_data
|
368
|
+
>>> def foo(bar):
|
369
|
+
>>> time.sleep(2)
|
370
|
+
>>> st.write(f"Executed foo({bar}).")
|
371
|
+
>>> return bar
|
372
|
+
>>>
|
373
|
+
>>> if st.button("Clear all cached values for `foo`", on_click=foo.clear):
|
374
|
+
>>> foo.clear()
|
375
|
+
>>>
|
376
|
+
>>> if st.button("Clear the cached value of `foo(1)`"):
|
377
|
+
>>> foo.clear(1)
|
378
|
+
>>>
|
379
|
+
>>> foo(1)
|
380
|
+
>>> foo(2)
|
381
|
+
|
382
|
+
"""
|
383
|
+
cache = self._info.get_function_cache(self._function_key)
|
384
|
+
if args or kwargs:
|
385
|
+
key = _make_value_key(
|
386
|
+
cache_type=self._info.cache_type,
|
387
|
+
func=self._info.func,
|
388
|
+
func_args=args,
|
389
|
+
func_kwargs=kwargs,
|
390
|
+
hash_funcs=self._info.hash_funcs,
|
391
|
+
)
|
392
|
+
else:
|
393
|
+
key = None
|
394
|
+
cache.clear(key=key)
|
395
|
+
|
396
|
+
|
397
|
+
def _make_value_key(
|
398
|
+
cache_type: CacheType,
|
399
|
+
func: FunctionType,
|
400
|
+
func_args: tuple[Any, ...],
|
401
|
+
func_kwargs: dict[str, Any],
|
402
|
+
hash_funcs: HashFuncsDict | None,
|
403
|
+
) -> str:
|
404
|
+
"""Create the key for a value within a cache.
|
405
|
+
|
406
|
+
This key is generated from the function's arguments. All arguments
|
407
|
+
will be hashed, except for those named with a leading "_".
|
408
|
+
|
409
|
+
Raises
|
410
|
+
------
|
411
|
+
StreamlitAPIException
|
412
|
+
Raised (with a nicely-formatted explanation message) if we encounter
|
413
|
+
an un-hashable arg.
|
414
|
+
"""
|
415
|
+
|
416
|
+
# Create a (name, value) list of all *args and **kwargs passed to the
|
417
|
+
# function.
|
418
|
+
arg_pairs: list[tuple[str | None, Any]] = []
|
419
|
+
for arg_idx in range(len(func_args)):
|
420
|
+
arg_name = _get_positional_arg_name(func, arg_idx)
|
421
|
+
arg_pairs.append((arg_name, func_args[arg_idx]))
|
422
|
+
|
423
|
+
for kw_name, kw_val in func_kwargs.items():
|
424
|
+
# **kwargs ordering is preserved, per PEP 468
|
425
|
+
# https://www.python.org/dev/peps/pep-0468/, so this iteration is
|
426
|
+
# deterministic.
|
427
|
+
arg_pairs.append((kw_name, kw_val))
|
428
|
+
|
429
|
+
# Create the hash from each arg value, except for those args whose name
|
430
|
+
# starts with "_". (Underscore-prefixed args are deliberately excluded from
|
431
|
+
# hashing.)
|
432
|
+
args_hasher = hashlib.new("md5", usedforsecurity=False)
|
433
|
+
for arg_name, arg_value in arg_pairs:
|
434
|
+
if arg_name is not None and arg_name.startswith("_"):
|
435
|
+
_LOGGER.debug("Not hashing %s because it starts with _", arg_name)
|
436
|
+
continue
|
437
|
+
|
438
|
+
try:
|
439
|
+
update_hash(
|
440
|
+
arg_name,
|
441
|
+
hasher=args_hasher,
|
442
|
+
cache_type=cache_type,
|
443
|
+
hash_source=func,
|
444
|
+
)
|
445
|
+
# we call update_hash twice here, first time for `arg_name`
|
446
|
+
# without `hash_funcs`, and second time for `arg_value` with hash_funcs
|
447
|
+
# to evaluate user defined `hash_funcs` only for computing `arg_value` hash.
|
448
|
+
update_hash(
|
449
|
+
arg_value,
|
450
|
+
hasher=args_hasher,
|
451
|
+
cache_type=cache_type,
|
452
|
+
hash_funcs=hash_funcs,
|
453
|
+
hash_source=func,
|
454
|
+
)
|
455
|
+
except UnhashableTypeError as exc:
|
456
|
+
raise UnhashableParamError(cache_type, func, arg_name, arg_value, exc)
|
457
|
+
|
458
|
+
value_key = args_hasher.hexdigest()
|
459
|
+
_LOGGER.debug("Cache key: %s", value_key)
|
460
|
+
|
461
|
+
return value_key
|
462
|
+
|
463
|
+
|
464
|
+
def _make_function_key(cache_type: CacheType, func: FunctionType) -> str:
|
465
|
+
"""Create the unique key for a function's cache.
|
466
|
+
|
467
|
+
A function's key is stable across reruns of the app, and changes when
|
468
|
+
the function's source code changes.
|
469
|
+
"""
|
470
|
+
func_hasher = hashlib.new("md5", usedforsecurity=False)
|
471
|
+
|
472
|
+
# Include the function's __module__ and __qualname__ strings in the hash.
|
473
|
+
# This means that two identical functions in different modules
|
474
|
+
# will not share a hash; it also means that two identical *nested*
|
475
|
+
# functions in the same module will not share a hash.
|
476
|
+
update_hash(
|
477
|
+
(func.__module__, func.__qualname__),
|
478
|
+
hasher=func_hasher,
|
479
|
+
cache_type=cache_type,
|
480
|
+
hash_source=func,
|
481
|
+
)
|
482
|
+
|
483
|
+
# Include the function's source code in its hash. If the source code can't
|
484
|
+
# be retrieved, fall back to the function's bytecode instead.
|
485
|
+
source_code: str | bytes
|
486
|
+
try:
|
487
|
+
source_code = inspect.getsource(func)
|
488
|
+
except (OSError, TypeError) as ex:
|
489
|
+
_LOGGER.debug(
|
490
|
+
"Failed to retrieve function's source code when building its key; "
|
491
|
+
"falling back to bytecode.",
|
492
|
+
exc_info=ex,
|
493
|
+
)
|
494
|
+
source_code = func.__code__.co_code
|
495
|
+
|
496
|
+
update_hash(
|
497
|
+
source_code, hasher=func_hasher, cache_type=cache_type, hash_source=func
|
498
|
+
)
|
499
|
+
|
500
|
+
return func_hasher.hexdigest()
|
501
|
+
|
502
|
+
|
503
|
+
def _get_positional_arg_name(func: FunctionType, arg_index: int) -> str | None:
|
504
|
+
"""Return the name of a function's positional argument.
|
505
|
+
|
506
|
+
If arg_index is out of range, or refers to a parameter that is not a
|
507
|
+
named positional argument (e.g. an *args, **kwargs, or keyword-only param),
|
508
|
+
return None instead.
|
509
|
+
"""
|
510
|
+
if arg_index < 0:
|
511
|
+
return None
|
512
|
+
|
513
|
+
params: list[inspect.Parameter] = list(inspect.signature(func).parameters.values())
|
514
|
+
if arg_index >= len(params):
|
515
|
+
return None
|
516
|
+
|
517
|
+
if params[arg_index].kind in (
|
518
|
+
inspect.Parameter.POSITIONAL_OR_KEYWORD,
|
519
|
+
inspect.Parameter.POSITIONAL_ONLY,
|
520
|
+
):
|
521
|
+
return params[arg_index].name
|
522
|
+
|
523
|
+
return None
|