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,280 @@
|
|
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
|
+
from collections.abc import Iterable, Iterator, Mapping
|
18
|
+
from functools import lru_cache
|
19
|
+
from types import MappingProxyType
|
20
|
+
from typing import TYPE_CHECKING, Any, cast
|
21
|
+
|
22
|
+
from streamlit import runtime
|
23
|
+
from streamlit.runtime.metrics_util import gather_metrics
|
24
|
+
from streamlit.runtime.scriptrunner_utils.script_run_context import get_script_run_ctx
|
25
|
+
|
26
|
+
if TYPE_CHECKING:
|
27
|
+
from http.cookies import Morsel
|
28
|
+
|
29
|
+
from tornado.httputil import HTTPHeaders, HTTPServerRequest
|
30
|
+
from tornado.web import RequestHandler
|
31
|
+
|
32
|
+
|
33
|
+
def _get_request() -> HTTPServerRequest | None:
|
34
|
+
ctx = get_script_run_ctx()
|
35
|
+
if ctx is None:
|
36
|
+
return None
|
37
|
+
|
38
|
+
session_client = runtime.get_instance().get_client(ctx.session_id)
|
39
|
+
if session_client is None:
|
40
|
+
return None
|
41
|
+
|
42
|
+
# We return websocket request only if session_client is an instance of
|
43
|
+
# BrowserWebSocketHandler (which is True for the Streamlit open-source
|
44
|
+
# implementation). For any other implementation, we return None.
|
45
|
+
# We are not using `type_util.is_type` here to avoid circular import.
|
46
|
+
if (
|
47
|
+
f"{type(session_client).__module__}.{type(session_client).__qualname__}"
|
48
|
+
!= "streamlit.web.server.browser_websocket_handler.BrowserWebSocketHandler"
|
49
|
+
):
|
50
|
+
return None
|
51
|
+
|
52
|
+
return cast("RequestHandler", session_client).request
|
53
|
+
|
54
|
+
|
55
|
+
@lru_cache
|
56
|
+
def _normalize_header(name: str) -> str:
|
57
|
+
"""Map a header name to Http-Header-Case.
|
58
|
+
|
59
|
+
>>> _normalize_header("coNtent-TYPE")
|
60
|
+
'Content-Type'
|
61
|
+
"""
|
62
|
+
return "-".join(w.capitalize() for w in name.split("-"))
|
63
|
+
|
64
|
+
|
65
|
+
class StreamlitHeaders(Mapping[str, str]):
|
66
|
+
def __init__(self, headers: Iterable[tuple[str, str]]):
|
67
|
+
dict_like_headers: dict[str, list[str]] = {}
|
68
|
+
|
69
|
+
for key, value in headers:
|
70
|
+
header_value = dict_like_headers.setdefault(_normalize_header(key), [])
|
71
|
+
header_value.append(value)
|
72
|
+
|
73
|
+
self._headers = dict_like_headers
|
74
|
+
|
75
|
+
@classmethod
|
76
|
+
def from_tornado_headers(cls, tornado_headers: HTTPHeaders) -> StreamlitHeaders:
|
77
|
+
return cls(tornado_headers.get_all())
|
78
|
+
|
79
|
+
def get_all(self, key: str) -> list[str]:
|
80
|
+
return list(self._headers.get(_normalize_header(key), []))
|
81
|
+
|
82
|
+
def __getitem__(self, key: str) -> str:
|
83
|
+
try:
|
84
|
+
return self._headers[_normalize_header(key)][0]
|
85
|
+
except LookupError:
|
86
|
+
raise KeyError(key) from None
|
87
|
+
|
88
|
+
def __len__(self) -> int:
|
89
|
+
"""Number of unique headers present in request."""
|
90
|
+
return len(self._headers)
|
91
|
+
|
92
|
+
def __iter__(self) -> Iterator[str]:
|
93
|
+
return iter(self._headers)
|
94
|
+
|
95
|
+
def to_dict(self) -> dict[str, str]:
|
96
|
+
return {key: self[key] for key in self}
|
97
|
+
|
98
|
+
|
99
|
+
class StreamlitCookies(Mapping[str, str]):
|
100
|
+
def __init__(self, cookies: Mapping[str, str]):
|
101
|
+
self._cookies = MappingProxyType(cookies)
|
102
|
+
|
103
|
+
@classmethod
|
104
|
+
def from_tornado_cookies(
|
105
|
+
cls, tornado_cookies: dict[str, Morsel[Any]]
|
106
|
+
) -> StreamlitCookies:
|
107
|
+
dict_like_cookies = {}
|
108
|
+
for key, morsel in tornado_cookies.items():
|
109
|
+
dict_like_cookies[key] = morsel.value
|
110
|
+
return cls(dict_like_cookies)
|
111
|
+
|
112
|
+
def __getitem__(self, key: str) -> str:
|
113
|
+
return self._cookies[key]
|
114
|
+
|
115
|
+
def __len__(self) -> int:
|
116
|
+
"""Number of unique headers present in request."""
|
117
|
+
return len(self._cookies)
|
118
|
+
|
119
|
+
def __iter__(self) -> Iterator[str]:
|
120
|
+
return iter(self._cookies)
|
121
|
+
|
122
|
+
def to_dict(self) -> dict[str, str]:
|
123
|
+
return dict(self._cookies)
|
124
|
+
|
125
|
+
|
126
|
+
class ContextProxy:
|
127
|
+
"""An interface to access user session context.
|
128
|
+
|
129
|
+
``st.context`` provides a read-only interface to access headers and cookies
|
130
|
+
for the current user session.
|
131
|
+
|
132
|
+
Each property (``st.context.headers`` and ``st.context.cookies``) returns
|
133
|
+
a dictionary of named values.
|
134
|
+
|
135
|
+
"""
|
136
|
+
|
137
|
+
@property
|
138
|
+
@gather_metrics("context.headers")
|
139
|
+
def headers(self) -> StreamlitHeaders:
|
140
|
+
"""A read-only, dict-like object containing headers sent in the initial request.
|
141
|
+
|
142
|
+
Keys are case-insensitive and may be repeated. When keys are repeated,
|
143
|
+
dict-like methods will only return the last instance of each key. Use
|
144
|
+
``.get_all(key="your_repeated_key")`` to see all values if the same
|
145
|
+
header is set multiple times.
|
146
|
+
|
147
|
+
Examples
|
148
|
+
--------
|
149
|
+
**Example 1: Access all available headers**
|
150
|
+
|
151
|
+
Show a dictionary of headers (with only the last instance of any
|
152
|
+
repeated key):
|
153
|
+
|
154
|
+
>>> import streamlit as st
|
155
|
+
>>>
|
156
|
+
>>> st.context.headers
|
157
|
+
|
158
|
+
**Example 2: Access a specific header**
|
159
|
+
|
160
|
+
Show the value of a specific header (or the last instance if it's
|
161
|
+
repeated):
|
162
|
+
|
163
|
+
>>> import streamlit as st
|
164
|
+
>>>
|
165
|
+
>>> st.context.headers["host"]
|
166
|
+
|
167
|
+
Show of list of all headers for a given key:
|
168
|
+
|
169
|
+
>>> import streamlit as st
|
170
|
+
>>>
|
171
|
+
>>> st.context.headers.get_all("pragma")
|
172
|
+
|
173
|
+
"""
|
174
|
+
# We have a docstring in line above as one-liner, to have a correct docstring
|
175
|
+
# in the st.write(st,context) call.
|
176
|
+
session_client_request = _get_request()
|
177
|
+
|
178
|
+
if session_client_request is None:
|
179
|
+
return StreamlitHeaders({})
|
180
|
+
|
181
|
+
return StreamlitHeaders.from_tornado_headers(session_client_request.headers)
|
182
|
+
|
183
|
+
@property
|
184
|
+
@gather_metrics("context.cookies")
|
185
|
+
def cookies(self) -> StreamlitCookies:
|
186
|
+
"""A read-only, dict-like object containing cookies sent in the initial request.
|
187
|
+
|
188
|
+
Examples
|
189
|
+
--------
|
190
|
+
**Example 1: Access all available cookies**
|
191
|
+
|
192
|
+
Show a dictionary of cookies:
|
193
|
+
|
194
|
+
>>> import streamlit as st
|
195
|
+
>>>
|
196
|
+
>>> st.context.cookies
|
197
|
+
|
198
|
+
**Example 2: Access a specific cookie**
|
199
|
+
|
200
|
+
Show the value of a specific cookie:
|
201
|
+
|
202
|
+
>>> import streamlit as st
|
203
|
+
>>>
|
204
|
+
>>> st.context.cookies["_ga"]
|
205
|
+
|
206
|
+
"""
|
207
|
+
# We have a docstring in line above as one-liner, to have a correct docstring
|
208
|
+
# in the st.write(st,context) call.
|
209
|
+
session_client_request = _get_request()
|
210
|
+
|
211
|
+
if session_client_request is None:
|
212
|
+
return StreamlitCookies({})
|
213
|
+
|
214
|
+
cookies = session_client_request.cookies
|
215
|
+
return StreamlitCookies.from_tornado_cookies(cookies)
|
216
|
+
|
217
|
+
@property
|
218
|
+
@gather_metrics("context.timezone")
|
219
|
+
def timezone(self) -> str | None:
|
220
|
+
"""The read-only timezone of the user's browser.
|
221
|
+
|
222
|
+
Example
|
223
|
+
-------
|
224
|
+
Access the user's timezone, and format a datetime to display locally:
|
225
|
+
|
226
|
+
>>> import streamlit as st
|
227
|
+
>>> from datetime import datetime, timezone
|
228
|
+
>>> import pytz
|
229
|
+
>>>
|
230
|
+
>>> tz = st.context.timezone
|
231
|
+
>>> tz_obj = pytz.timezone(tz)
|
232
|
+
>>>
|
233
|
+
>>> now = datetime.now(timezone.utc)
|
234
|
+
>>>
|
235
|
+
>>> f"The user's timezone is {tz}."
|
236
|
+
>>> f"The UTC time is {now}."
|
237
|
+
>>> f"The user's local time is {now.astimezone(tz_obj)}"
|
238
|
+
|
239
|
+
"""
|
240
|
+
ctx = get_script_run_ctx()
|
241
|
+
|
242
|
+
if ctx is None or ctx.context_info is None:
|
243
|
+
return None
|
244
|
+
return ctx.context_info.timezone
|
245
|
+
|
246
|
+
@property
|
247
|
+
@gather_metrics("context.timezone_offset")
|
248
|
+
def timezone_offset(self) -> int | None:
|
249
|
+
"""The read-only timezone offset of the user's browser.
|
250
|
+
|
251
|
+
Example
|
252
|
+
-------
|
253
|
+
Access the user's timezone offset, and format a datetime to display locally:
|
254
|
+
|
255
|
+
>>> import streamlit as st
|
256
|
+
>>> from datetime import datetime, timezone, timedelta
|
257
|
+
>>>
|
258
|
+
>>> tzoff = st.context.timezone_offset
|
259
|
+
>>> tz_obj = timezone(-timedelta(minutes=tzoff))
|
260
|
+
>>>
|
261
|
+
>>> now = datetime.now(timezone.utc)
|
262
|
+
>>>
|
263
|
+
>>> f"The user's timezone is {tz}."
|
264
|
+
>>> f"The UTC time is {now}."
|
265
|
+
>>> f"The user's local time is {now.astimezone(tz_obj)}"
|
266
|
+
|
267
|
+
"""
|
268
|
+
ctx = get_script_run_ctx()
|
269
|
+
if ctx is None or ctx.context_info is None:
|
270
|
+
return None
|
271
|
+
return ctx.context_info.timezone_offset
|
272
|
+
|
273
|
+
@property
|
274
|
+
@gather_metrics("context.locale")
|
275
|
+
def locale(self) -> str | None:
|
276
|
+
"""The locale of the user browser, read-only"""
|
277
|
+
ctx = get_script_run_ctx()
|
278
|
+
if ctx is None or ctx.context_info is None:
|
279
|
+
return None
|
280
|
+
return ctx.context_info.locale
|
@@ -0,0 +1,364 @@
|
|
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
|
+
"""Manage the user's Streamlit credentials."""
|
16
|
+
|
17
|
+
from __future__ import annotations
|
18
|
+
|
19
|
+
import json
|
20
|
+
import os
|
21
|
+
import sys
|
22
|
+
import textwrap
|
23
|
+
from typing import Final, NamedTuple, NoReturn
|
24
|
+
from uuid import uuid4
|
25
|
+
|
26
|
+
from streamlit import cli_util, env_util, file_util, util
|
27
|
+
from streamlit.logger import get_logger
|
28
|
+
|
29
|
+
_LOGGER: Final = get_logger(__name__)
|
30
|
+
|
31
|
+
|
32
|
+
if env_util.IS_WINDOWS:
|
33
|
+
_CONFIG_FILE_PATH = r"%userprofile%/.streamlit/config.toml"
|
34
|
+
else:
|
35
|
+
_CONFIG_FILE_PATH = "~/.streamlit/config.toml"
|
36
|
+
|
37
|
+
|
38
|
+
class _Activation(NamedTuple):
|
39
|
+
email: str | None # the user's email.
|
40
|
+
is_valid: bool # whether the email is valid.
|
41
|
+
|
42
|
+
|
43
|
+
def email_prompt() -> str:
|
44
|
+
# Emoji can cause encoding errors on non-UTF-8 terminals
|
45
|
+
# (See https://github.com/streamlit/streamlit/issues/2284.)
|
46
|
+
# WT_SESSION is a Windows Terminal specific environment variable. If it exists,
|
47
|
+
# we are on the latest Windows Terminal that supports emojis
|
48
|
+
show_emoji = sys.stdout.encoding == "utf-8" and (
|
49
|
+
not env_util.IS_WINDOWS or os.environ.get("WT_SESSION")
|
50
|
+
)
|
51
|
+
|
52
|
+
# IMPORTANT: Break the text below at 80 chars.
|
53
|
+
return f"""
|
54
|
+
{"👋 " if show_emoji else ""}{cli_util.style_for_cli("Welcome to Streamlit!", bold=True)}
|
55
|
+
|
56
|
+
If you’d like to receive helpful onboarding emails, news, offers, promotions,
|
57
|
+
and the occasional swag, please enter your email address below. Otherwise,
|
58
|
+
leave this field blank.
|
59
|
+
|
60
|
+
{cli_util.style_for_cli("Email: ", fg="blue")}"""
|
61
|
+
|
62
|
+
|
63
|
+
_TELEMETRY_HEADLESS_TEXT = """
|
64
|
+
Collecting usage statistics. To deactivate, set browser.gatherUsageStats to false.
|
65
|
+
"""
|
66
|
+
|
67
|
+
|
68
|
+
def _send_email(email: str) -> None:
|
69
|
+
"""Send the user's email for metrics, if submitted"""
|
70
|
+
import requests
|
71
|
+
|
72
|
+
if email is None or "@" not in email:
|
73
|
+
return
|
74
|
+
|
75
|
+
metrics_url = ""
|
76
|
+
try:
|
77
|
+
response_json = requests.get(
|
78
|
+
"https://data.streamlit.io/metrics.json", timeout=2
|
79
|
+
).json()
|
80
|
+
metrics_url = response_json.get("url", "")
|
81
|
+
except Exception:
|
82
|
+
_LOGGER.error("Failed to fetch metrics URL")
|
83
|
+
return
|
84
|
+
|
85
|
+
headers = {
|
86
|
+
"accept": "*/*",
|
87
|
+
"accept-language": "en-US,en;q=0.9",
|
88
|
+
"content-type": "application/json",
|
89
|
+
"origin": "localhost:8501",
|
90
|
+
"referer": "localhost:8501/",
|
91
|
+
}
|
92
|
+
|
93
|
+
data = {
|
94
|
+
"anonymous_id": None,
|
95
|
+
"messageId": str(uuid4()),
|
96
|
+
"event": "submittedEmail",
|
97
|
+
"author_email": email,
|
98
|
+
"source": "provided_email",
|
99
|
+
"type": "track",
|
100
|
+
"userId": email,
|
101
|
+
}
|
102
|
+
|
103
|
+
response = requests.post(
|
104
|
+
metrics_url,
|
105
|
+
headers=headers,
|
106
|
+
data=json.dumps(data).encode(),
|
107
|
+
)
|
108
|
+
|
109
|
+
response.raise_for_status()
|
110
|
+
|
111
|
+
|
112
|
+
class Credentials:
|
113
|
+
"""Credentials class."""
|
114
|
+
|
115
|
+
_singleton: Credentials | None = None
|
116
|
+
|
117
|
+
@classmethod
|
118
|
+
def get_current(cls):
|
119
|
+
"""Return the singleton instance."""
|
120
|
+
if cls._singleton is None:
|
121
|
+
Credentials()
|
122
|
+
|
123
|
+
return Credentials._singleton
|
124
|
+
|
125
|
+
def __init__(self):
|
126
|
+
"""Initialize class."""
|
127
|
+
if Credentials._singleton is not None:
|
128
|
+
raise RuntimeError(
|
129
|
+
"Credentials already initialized. Use .get_current() instead"
|
130
|
+
)
|
131
|
+
|
132
|
+
self.activation = None
|
133
|
+
self._conf_file = _get_credential_file_path()
|
134
|
+
|
135
|
+
Credentials._singleton = self
|
136
|
+
|
137
|
+
def __repr__(self) -> str:
|
138
|
+
return util.repr_(self)
|
139
|
+
|
140
|
+
def load(self, auto_resolve: bool = False) -> None:
|
141
|
+
"""Load from toml file."""
|
142
|
+
if self.activation is not None:
|
143
|
+
_LOGGER.error("Credentials already loaded. Not rereading file.")
|
144
|
+
return
|
145
|
+
|
146
|
+
import toml
|
147
|
+
|
148
|
+
try:
|
149
|
+
with open(self._conf_file) as f:
|
150
|
+
data = toml.load(f).get("general")
|
151
|
+
if data is None:
|
152
|
+
raise Exception
|
153
|
+
self.activation = _verify_email(data.get("email"))
|
154
|
+
except FileNotFoundError:
|
155
|
+
if auto_resolve:
|
156
|
+
self.activate(show_instructions=not auto_resolve)
|
157
|
+
return
|
158
|
+
raise RuntimeError(
|
159
|
+
'Credentials not found. Please run "streamlit activate".'
|
160
|
+
)
|
161
|
+
except Exception:
|
162
|
+
if auto_resolve:
|
163
|
+
self.reset()
|
164
|
+
self.activate(show_instructions=not auto_resolve)
|
165
|
+
return
|
166
|
+
raise Exception(
|
167
|
+
textwrap.dedent(
|
168
|
+
"""
|
169
|
+
Unable to load credentials from %s.
|
170
|
+
Run "streamlit reset" and try again.
|
171
|
+
"""
|
172
|
+
)
|
173
|
+
% (self._conf_file)
|
174
|
+
)
|
175
|
+
|
176
|
+
def _check_activated(self, auto_resolve: bool = True) -> None:
|
177
|
+
"""Check if streamlit is activated.
|
178
|
+
|
179
|
+
Used by `streamlit run script.py`
|
180
|
+
"""
|
181
|
+
try:
|
182
|
+
self.load(auto_resolve)
|
183
|
+
except (Exception, RuntimeError) as e:
|
184
|
+
_exit(str(e))
|
185
|
+
|
186
|
+
if self.activation is None or not self.activation.is_valid:
|
187
|
+
_exit("Activation email not valid.")
|
188
|
+
|
189
|
+
@classmethod
|
190
|
+
def reset(cls) -> None:
|
191
|
+
"""Reset credentials by removing file.
|
192
|
+
|
193
|
+
This is used by `streamlit activate reset` in case a user wants
|
194
|
+
to start over.
|
195
|
+
"""
|
196
|
+
c = Credentials.get_current()
|
197
|
+
c.activation = None
|
198
|
+
|
199
|
+
try:
|
200
|
+
os.remove(c._conf_file)
|
201
|
+
except OSError:
|
202
|
+
_LOGGER.exception("Error removing credentials file.")
|
203
|
+
|
204
|
+
def save(self) -> None:
|
205
|
+
"""Save to toml file and send email."""
|
206
|
+
from requests.exceptions import RequestException
|
207
|
+
|
208
|
+
if self.activation is None:
|
209
|
+
return
|
210
|
+
|
211
|
+
# Create intermediate directories if necessary
|
212
|
+
os.makedirs(os.path.dirname(self._conf_file), exist_ok=True)
|
213
|
+
|
214
|
+
# Write the file
|
215
|
+
data = {"email": self.activation.email}
|
216
|
+
|
217
|
+
import toml
|
218
|
+
|
219
|
+
with open(self._conf_file, "w") as f:
|
220
|
+
toml.dump({"general": data}, f)
|
221
|
+
|
222
|
+
try:
|
223
|
+
_send_email(self.activation.email)
|
224
|
+
except RequestException:
|
225
|
+
_LOGGER.exception("Error saving email:")
|
226
|
+
|
227
|
+
def activate(self, show_instructions: bool = True) -> None:
|
228
|
+
"""Activate Streamlit.
|
229
|
+
|
230
|
+
Used by `streamlit activate`.
|
231
|
+
"""
|
232
|
+
try:
|
233
|
+
self.load()
|
234
|
+
except RuntimeError:
|
235
|
+
# Runtime Error is raised if credentials file is not found. In that case,
|
236
|
+
# `self.activation` is None and we will show the activation prompt below.
|
237
|
+
pass
|
238
|
+
|
239
|
+
if self.activation:
|
240
|
+
if self.activation.is_valid:
|
241
|
+
_exit("Already activated")
|
242
|
+
else:
|
243
|
+
_exit(
|
244
|
+
"Activation not valid. Please run "
|
245
|
+
"`streamlit activate reset` then `streamlit activate`"
|
246
|
+
)
|
247
|
+
else:
|
248
|
+
activated = False
|
249
|
+
|
250
|
+
while not activated:
|
251
|
+
import click
|
252
|
+
|
253
|
+
email = click.prompt(
|
254
|
+
text=email_prompt(),
|
255
|
+
prompt_suffix="",
|
256
|
+
default="",
|
257
|
+
show_default=False,
|
258
|
+
)
|
259
|
+
|
260
|
+
self.activation = _verify_email(email)
|
261
|
+
if self.activation.is_valid:
|
262
|
+
self.save()
|
263
|
+
# IMPORTANT: Break the text below at 80 chars.
|
264
|
+
TELEMETRY_TEXT = """
|
265
|
+
You can find our privacy policy at %(link)s
|
266
|
+
|
267
|
+
Summary:
|
268
|
+
- This open source library collects usage statistics.
|
269
|
+
- We cannot see and do not store information contained inside Streamlit apps,
|
270
|
+
such as text, charts, images, etc.
|
271
|
+
- Telemetry data is stored in servers in the United States.
|
272
|
+
- If you'd like to opt out, add the following to %(config)s,
|
273
|
+
creating that file if necessary:
|
274
|
+
|
275
|
+
[browser]
|
276
|
+
gatherUsageStats = false
|
277
|
+
""" % {
|
278
|
+
"link": cli_util.style_for_cli(
|
279
|
+
"https://streamlit.io/privacy-policy", underline=True
|
280
|
+
),
|
281
|
+
"config": cli_util.style_for_cli(_CONFIG_FILE_PATH),
|
282
|
+
}
|
283
|
+
|
284
|
+
cli_util.print_to_cli(TELEMETRY_TEXT)
|
285
|
+
if show_instructions:
|
286
|
+
# IMPORTANT: Break the text below at 80 chars.
|
287
|
+
INSTRUCTIONS_TEXT = """
|
288
|
+
%(start)s
|
289
|
+
%(prompt)s %(hello)s
|
290
|
+
""" % {
|
291
|
+
"start": cli_util.style_for_cli(
|
292
|
+
"Get started by typing:", fg="blue", bold=True
|
293
|
+
),
|
294
|
+
"prompt": cli_util.style_for_cli("$", fg="blue"),
|
295
|
+
"hello": cli_util.style_for_cli(
|
296
|
+
"streamlit hello", bold=True
|
297
|
+
),
|
298
|
+
}
|
299
|
+
|
300
|
+
cli_util.print_to_cli(INSTRUCTIONS_TEXT)
|
301
|
+
activated = True
|
302
|
+
else: # pragma: nocover
|
303
|
+
_LOGGER.error("Please try again.")
|
304
|
+
|
305
|
+
|
306
|
+
def _verify_email(email: str) -> _Activation:
|
307
|
+
"""Verify the user's email address.
|
308
|
+
|
309
|
+
The email can either be an empty string (if the user chooses not to enter
|
310
|
+
it), or a string with a single '@' somewhere in it.
|
311
|
+
|
312
|
+
Parameters
|
313
|
+
----------
|
314
|
+
email : str
|
315
|
+
|
316
|
+
Returns
|
317
|
+
-------
|
318
|
+
_Activation
|
319
|
+
An _Activation object. Its 'is_valid' property will be True only if
|
320
|
+
the email was validated.
|
321
|
+
|
322
|
+
"""
|
323
|
+
email = email.strip()
|
324
|
+
|
325
|
+
# We deliberately use simple email validation here
|
326
|
+
# since we do not use email address anywhere to send emails.
|
327
|
+
if len(email) > 0 and email.count("@") != 1:
|
328
|
+
_LOGGER.error("That doesn't look like an email :(")
|
329
|
+
return _Activation(None, False)
|
330
|
+
|
331
|
+
return _Activation(email, True)
|
332
|
+
|
333
|
+
|
334
|
+
def _exit(message: str) -> NoReturn:
|
335
|
+
"""Exit program with error."""
|
336
|
+
_LOGGER.error(message)
|
337
|
+
sys.exit(-1)
|
338
|
+
|
339
|
+
|
340
|
+
def _get_credential_file_path() -> str:
|
341
|
+
return file_util.get_streamlit_file_path("credentials.toml")
|
342
|
+
|
343
|
+
|
344
|
+
def _check_credential_file_exists() -> bool:
|
345
|
+
return os.path.exists(_get_credential_file_path())
|
346
|
+
|
347
|
+
|
348
|
+
def check_credentials() -> None:
|
349
|
+
"""Check credentials and potentially activate.
|
350
|
+
|
351
|
+
Note
|
352
|
+
----
|
353
|
+
If there is no credential file and we are in headless mode, we should not
|
354
|
+
check, since credential would be automatically set to an empty string.
|
355
|
+
|
356
|
+
"""
|
357
|
+
from streamlit import config
|
358
|
+
|
359
|
+
if not _check_credential_file_exists() and config.get_option("server.headless"):
|
360
|
+
if not config.is_manually_set("browser.gatherUsageStats"):
|
361
|
+
# If not manually defined, show short message about usage stats gathering.
|
362
|
+
cli_util.print_to_cli(_TELEMETRY_HEADLESS_TEXT)
|
363
|
+
return
|
364
|
+
Credentials.get_current()._check_activated()
|