streamlit 1.45.1__py3-none-any.whl → 1.46.1__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.
Files changed (335) hide show
  1. streamlit/__init__.py +5 -1
  2. streamlit/auth_util.py +12 -12
  3. streamlit/cli_util.py +4 -3
  4. streamlit/column_config.py +11 -9
  5. streamlit/commands/echo.py +6 -4
  6. streamlit/commands/execution_control.py +33 -32
  7. streamlit/commands/experimental_query_params.py +2 -2
  8. streamlit/commands/logo.py +9 -4
  9. streamlit/commands/navigation.py +61 -18
  10. streamlit/commands/page_config.py +57 -47
  11. streamlit/components/types/base_custom_component.py +7 -7
  12. streamlit/components/v1/component_registry.py +7 -3
  13. streamlit/components/v1/components.py +1 -1
  14. streamlit/components/v1/custom_component.py +8 -8
  15. streamlit/config.py +289 -144
  16. streamlit/config_option.py +19 -15
  17. streamlit/config_util.py +29 -23
  18. streamlit/connections/__init__.py +2 -2
  19. streamlit/connections/base_connection.py +5 -5
  20. streamlit/connections/snowflake_connection.py +13 -11
  21. streamlit/connections/snowpark_connection.py +3 -3
  22. streamlit/connections/sql_connection.py +20 -18
  23. streamlit/connections/util.py +2 -2
  24. streamlit/cursor.py +6 -6
  25. streamlit/dataframe_util.py +52 -52
  26. streamlit/delta_generator.py +46 -48
  27. streamlit/delta_generator_singletons.py +3 -3
  28. streamlit/deprecation_util.py +6 -6
  29. streamlit/elements/alert.py +37 -29
  30. streamlit/elements/arrow.py +40 -22
  31. streamlit/elements/code.py +46 -13
  32. streamlit/elements/deck_gl_json_chart.py +38 -27
  33. streamlit/elements/dialog_decorator.py +3 -4
  34. streamlit/elements/doc_string.py +64 -58
  35. streamlit/elements/exception.py +23 -27
  36. streamlit/elements/form.py +41 -0
  37. streamlit/elements/graphviz_chart.py +1 -1
  38. streamlit/elements/heading.py +60 -9
  39. streamlit/elements/html.py +3 -4
  40. streamlit/elements/image.py +8 -9
  41. streamlit/elements/json.py +21 -2
  42. streamlit/elements/layouts.py +120 -31
  43. streamlit/elements/lib/built_in_chart_utils.py +96 -73
  44. streamlit/elements/lib/color_util.py +3 -3
  45. streamlit/elements/lib/column_config_utils.py +2 -4
  46. streamlit/elements/lib/column_types.py +14 -8
  47. streamlit/elements/lib/dialog.py +9 -5
  48. streamlit/elements/lib/image_utils.py +39 -40
  49. streamlit/elements/lib/js_number.py +4 -4
  50. streamlit/elements/lib/layout_utils.py +65 -1
  51. streamlit/elements/lib/mutable_status_container.py +14 -3
  52. streamlit/elements/lib/options_selector_utils.py +22 -12
  53. streamlit/elements/lib/pandas_styler_utils.py +25 -21
  54. streamlit/elements/lib/policies.py +6 -5
  55. streamlit/elements/lib/streamlit_plotly_theme.py +54 -53
  56. streamlit/elements/lib/subtitle_utils.py +6 -9
  57. streamlit/elements/lib/utils.py +20 -5
  58. streamlit/elements/map.py +32 -56
  59. streamlit/elements/markdown.py +101 -12
  60. streamlit/elements/media.py +78 -21
  61. streamlit/elements/metric.py +32 -16
  62. streamlit/elements/plotly_chart.py +15 -15
  63. streamlit/elements/progress.py +33 -15
  64. streamlit/elements/spinner.py +31 -6
  65. streamlit/elements/text.py +21 -1
  66. streamlit/elements/toast.py +1 -2
  67. streamlit/elements/vega_charts.py +54 -23
  68. streamlit/elements/widgets/audio_input.py +24 -7
  69. streamlit/elements/widgets/button.py +26 -19
  70. streamlit/elements/widgets/button_group.py +10 -15
  71. streamlit/elements/widgets/camera_input.py +27 -7
  72. streamlit/elements/widgets/chat.py +91 -38
  73. streamlit/elements/widgets/checkbox.py +45 -4
  74. streamlit/elements/widgets/color_picker.py +40 -17
  75. streamlit/elements/widgets/data_editor.py +76 -37
  76. streamlit/elements/widgets/file_uploader.py +42 -13
  77. streamlit/elements/widgets/multiselect.py +7 -10
  78. streamlit/elements/widgets/number_input.py +123 -47
  79. streamlit/elements/widgets/radio.py +59 -13
  80. streamlit/elements/widgets/select_slider.py +35 -30
  81. streamlit/elements/widgets/selectbox.py +56 -9
  82. streamlit/elements/widgets/slider.py +190 -99
  83. streamlit/elements/widgets/text_widgets.py +54 -8
  84. streamlit/elements/widgets/time_widgets.py +53 -14
  85. streamlit/elements/write.py +5 -8
  86. streamlit/env_util.py +2 -7
  87. streamlit/error_util.py +16 -9
  88. streamlit/errors.py +69 -48
  89. streamlit/external/langchain/streamlit_callback_handler.py +10 -5
  90. streamlit/file_util.py +27 -10
  91. streamlit/git_util.py +29 -24
  92. streamlit/hello/animation_demo.py +9 -9
  93. streamlit/hello/dataframe_demo.py +5 -5
  94. streamlit/hello/hello.py +1 -0
  95. streamlit/hello/mapping_demo.py +7 -8
  96. streamlit/hello/plotting_demo.py +3 -3
  97. streamlit/hello/streamlit_app.py +28 -26
  98. streamlit/hello/utils.py +2 -1
  99. streamlit/logger.py +10 -11
  100. streamlit/navigation/page.py +11 -8
  101. streamlit/proto/Audio_pb2.py +4 -3
  102. streamlit/proto/Audio_pb2.pyi +8 -1
  103. streamlit/proto/Block_pb2.py +38 -29
  104. streamlit/proto/Block_pb2.pyi +72 -4
  105. streamlit/proto/ClientState_pb2.py +4 -4
  106. streamlit/proto/ClientState_pb2.pyi +7 -2
  107. streamlit/proto/Code_pb2.py +4 -2
  108. streamlit/proto/Code_pb2.pyi +1 -0
  109. streamlit/proto/DataFrame_pb2.pyi +1 -1
  110. streamlit/proto/DeckGlJsonChart_pb2.pyi +1 -1
  111. streamlit/proto/Element_pb2.py +5 -3
  112. streamlit/proto/Element_pb2.pyi +20 -3
  113. streamlit/proto/GapSize_pb2.py +29 -0
  114. streamlit/proto/GapSize_pb2.pyi +70 -0
  115. streamlit/proto/HeightConfig_pb2.py +27 -0
  116. streamlit/proto/HeightConfig_pb2.pyi +48 -0
  117. streamlit/proto/NamedDataSet_pb2.pyi +1 -1
  118. streamlit/proto/Navigation_pb2.py +3 -3
  119. streamlit/proto/Navigation_pb2.pyi +4 -0
  120. streamlit/proto/NewSession_pb2.py +18 -16
  121. streamlit/proto/NewSession_pb2.pyi +29 -3
  122. streamlit/proto/PageConfig_pb2.py +7 -7
  123. streamlit/proto/PageConfig_pb2.pyi +21 -1
  124. streamlit/proto/Video_pb2.py +8 -7
  125. streamlit/proto/Video_pb2.pyi +8 -1
  126. streamlit/proto/WidthConfig_pb2.py +2 -2
  127. streamlit/proto/WidthConfig_pb2.pyi +15 -1
  128. streamlit/runtime/__init__.py +1 -1
  129. streamlit/runtime/app_session.py +53 -40
  130. streamlit/runtime/caching/__init__.py +9 -9
  131. streamlit/runtime/caching/cache_data_api.py +36 -30
  132. streamlit/runtime/caching/cache_errors.py +4 -4
  133. streamlit/runtime/caching/cache_resource_api.py +8 -8
  134. streamlit/runtime/caching/cache_utils.py +15 -14
  135. streamlit/runtime/caching/cached_message_replay.py +14 -8
  136. streamlit/runtime/caching/hashing.py +91 -97
  137. streamlit/runtime/caching/legacy_cache_api.py +2 -2
  138. streamlit/runtime/caching/storage/cache_storage_protocol.py +1 -1
  139. streamlit/runtime/caching/storage/dummy_cache_storage.py +1 -1
  140. streamlit/runtime/caching/storage/in_memory_cache_storage_wrapper.py +12 -14
  141. streamlit/runtime/caching/storage/local_disk_cache_storage.py +6 -6
  142. streamlit/runtime/connection_factory.py +36 -36
  143. streamlit/runtime/context.py +58 -9
  144. streamlit/runtime/credentials.py +29 -40
  145. streamlit/runtime/forward_msg_queue.py +11 -11
  146. streamlit/runtime/fragment.py +7 -7
  147. streamlit/runtime/media_file_manager.py +3 -4
  148. streamlit/runtime/memory_media_file_storage.py +6 -5
  149. streamlit/runtime/memory_uploaded_file_manager.py +2 -2
  150. streamlit/runtime/metrics_util.py +11 -12
  151. streamlit/runtime/pages_manager.py +4 -6
  152. streamlit/runtime/runtime.py +8 -6
  153. streamlit/runtime/runtime_util.py +7 -6
  154. streamlit/runtime/scriptrunner/__init__.py +4 -4
  155. streamlit/runtime/scriptrunner/exec_code.py +12 -5
  156. streamlit/runtime/scriptrunner/magic.py +16 -12
  157. streamlit/runtime/scriptrunner/script_cache.py +1 -1
  158. streamlit/runtime/scriptrunner/script_runner.py +53 -29
  159. streamlit/runtime/scriptrunner_utils/exceptions.py +1 -1
  160. streamlit/runtime/scriptrunner_utils/script_requests.py +7 -4
  161. streamlit/runtime/scriptrunner_utils/script_run_context.py +10 -23
  162. streamlit/runtime/secrets.py +40 -35
  163. streamlit/runtime/session_manager.py +2 -1
  164. streamlit/runtime/state/__init__.py +5 -5
  165. streamlit/runtime/state/common.py +2 -2
  166. streamlit/runtime/state/query_params.py +13 -15
  167. streamlit/runtime/state/query_params_proxy.py +17 -13
  168. streamlit/runtime/state/safe_session_state.py +2 -2
  169. streamlit/runtime/state/session_state.py +52 -34
  170. streamlit/runtime/stats.py +2 -2
  171. streamlit/runtime/uploaded_file_manager.py +1 -1
  172. streamlit/runtime/websocket_session_manager.py +10 -6
  173. streamlit/source_util.py +8 -6
  174. streamlit/static/index.html +3 -17
  175. streamlit/static/manifest.json +1180 -0
  176. streamlit/static/static/css/{index.DqDwtg6_.css → index.CJVRHjQZ.css} +1 -1
  177. streamlit/static/static/js/{ErrorOutline.esm.DU9IrB3M.js → ErrorOutline.esm.DitPpe1Y.js} +1 -1
  178. streamlit/static/static/js/{FileDownload.esm.P9rKwKo8.js → FileDownload.esm.AI3watX9.js} +1 -1
  179. streamlit/static/static/js/{FileHelper.D7RMkx0e.js → FileHelper.kt7mhnu8.js} +5 -5
  180. streamlit/static/static/js/{FormClearHelper.B67tgll0.js → FormClearHelper.D1M9GM_c.js} +1 -1
  181. streamlit/static/static/js/{Hooks.ncTJktu9.js → Hooks.BGwHKeUc.js} +1 -1
  182. streamlit/static/static/js/{InputInstructions.D-Y8geDN.js → InputInstructions.DaZ89mzH.js} +1 -1
  183. streamlit/static/static/js/{ProgressBar.B-kexwwD.js → ProgressBar.C0zPMe-p.js} +2 -2
  184. streamlit/static/static/js/{RenderInPortalIfExists.BgaoZgep.js → RenderInPortalIfExists.Ox8gQvdz.js} +1 -1
  185. streamlit/static/static/js/Toolbar.KhlcEc0K.js +1 -0
  186. streamlit/static/static/js/UploadFileInfo.0DCkpDDf.js +6 -0
  187. streamlit/static/static/js/{base-input.BoAa1U94.js → base-input.BJ4qsfSq.js} +4 -4
  188. streamlit/static/static/js/{checkbox.Z6iSfe5F.js → checkbox.DSDh78Xz.js} +2 -2
  189. streamlit/static/static/js/{createSuper.B4oGDYRm.js → createSuper.wQ9SIXEJ.js} +1 -1
  190. streamlit/static/static/js/{data-grid-overlay-editor.msYws2Ou.js → data-grid-overlay-editor.DvbdPJ15.js} +1 -1
  191. streamlit/static/static/js/{downloader.kc14n2Hv.js → downloader.CD9rzih5.js} +1 -1
  192. streamlit/static/static/js/{es6.CxQz807-.js → es6.48Q9Qjgb.js} +2 -2
  193. streamlit/static/static/js/{iframeResizer.contentWindow.B19u0ONI.js → iframeResizer.contentWindow.CKdem3Bn.js} +1 -1
  194. streamlit/static/static/js/{index.LaIasviC.js → index.6md5Qhod.js} +1 -1
  195. streamlit/static/static/js/index.7hy6AeJ1.js +1 -0
  196. streamlit/static/static/js/index.B4CGJiBW.js +1 -0
  197. streamlit/static/static/js/index.B8oW0ZTD.js +1 -0
  198. streamlit/static/static/js/index.BU6RnlHI.js +73 -0
  199. streamlit/static/static/js/index.BUq9Wcf8.js +197 -0
  200. streamlit/static/static/js/{index.BFz9U2y0.js → index.BXXo-Yoj.js} +1 -1
  201. streamlit/static/static/js/index.Bae9H0OS.js +1 -0
  202. streamlit/static/static/js/{index.-5ruC9At.js → index.BhTl2Uyb.js} +1 -1
  203. streamlit/static/static/js/{index.BpILzHf_.js → index.BiSaCB1o.js} +20 -20
  204. streamlit/static/static/js/{index.xNQq3Ei5.js → index.BulSAJ9z.js} +1 -1
  205. streamlit/static/static/js/{index.9V1KdxfP.js → index.Bv-EuTKR.js} +1 -1
  206. streamlit/static/static/js/index.BvMLYCHi.js +1 -0
  207. streamlit/static/static/js/index.C1NIn1Y2.js +783 -0
  208. streamlit/static/static/js/index.CP-fthOJ.js +2 -0
  209. streamlit/static/static/js/{index.BoigZiu7.js → index.CS9guO3p.js} +1 -1
  210. streamlit/static/static/js/index.CYTBHth8.js +1 -0
  211. streamlit/static/static/js/{index.CmTAF0dM.js → index.CcJufcuD.js} +1 -1
  212. streamlit/static/static/js/index.CnENU1yn.js +1 -0
  213. streamlit/static/static/js/index.Cns13qBb.js +1 -0
  214. streamlit/static/static/js/index.Ct_xXq7w.js +1 -0
  215. streamlit/static/static/js/{index.BqfdT8-Q.js → index.CxGSemHL.js} +1 -1
  216. streamlit/static/static/js/index.D5S0ldVb.js +1 -0
  217. streamlit/static/static/js/index.D72B_ksb.js +2 -0
  218. streamlit/static/static/js/index.DI4yZ27M.js +1 -0
  219. streamlit/static/static/js/index.DN51vLxR.js +1 -0
  220. streamlit/static/static/js/index.DRtq5dka.js +1 -0
  221. streamlit/static/static/js/{index.BHXxWdde.js → index.DX-oiXlb.js} +1 -1
  222. streamlit/static/static/js/index.DlFE4_Aq.js +12 -0
  223. streamlit/static/static/js/{index.BHGGDa8K.js → index.J7BJwXOi.js} +2 -2
  224. streamlit/static/static/js/index.Jg38kJPP.js +1 -0
  225. streamlit/static/static/js/index.JhIO6abf.js +3 -0
  226. streamlit/static/static/js/{index.DeB9iKFW.js → index.NkRcWwc5.js} +255 -255
  227. streamlit/static/static/js/{index.BGga-hcS.js → index.prekPLrm.js} +25 -25
  228. streamlit/static/static/js/{index.BRXmLIsC.js → index.wyzngKUE.js} +1 -1
  229. streamlit/static/static/js/index.xW7mVdI8.js +1 -0
  230. streamlit/static/static/js/index.yk07dYGx.js +1 -0
  231. streamlit/static/static/js/{input.DsCfafm0.js → input.CxKZ5Wrc.js} +2 -2
  232. streamlit/static/static/js/{memory.nY_lMTtu.js → memory.DeZ9VUvl.js} +1 -1
  233. streamlit/static/static/js/{mergeWith.B_7zmsM4.js → mergeWith.CVkhrWUb.js} +1 -1
  234. streamlit/static/static/js/{number-overlay-editor.CSeVhHRU.js → number-overlay-editor.Bpkm3nTq.js} +1 -1
  235. streamlit/static/static/js/{possibleConstructorReturn.nNhsvgRd.js → possibleConstructorReturn.CIDCId52.js} +1 -1
  236. streamlit/static/static/js/{sandbox.Cgm3iuL6.js → sandbox.TrkMaokR.js} +1 -1
  237. streamlit/static/static/js/{textarea.BR8rlyih.js → textarea.QKjxR64N.js} +2 -2
  238. streamlit/static/static/js/{timepicker.w4XhAenH.js → timepicker.DJYmE1dK.js} +1 -1
  239. streamlit/static/static/js/{toConsumableArray.CgkEPBwD.js → toConsumableArray.BZoworE-.js} +1 -1
  240. streamlit/static/static/js/{uniqueId.j-1rlNNH.js → uniqueId.O0UbJ2Bu.js} +1 -1
  241. streamlit/static/static/js/{useBasicWidgetState.zXY9CjFS.js → useBasicWidgetState.Ci89jaH5.js} +1 -1
  242. streamlit/static/static/js/useOnInputChange.Cxh6ExEn.js +1 -0
  243. streamlit/static/static/js/{withFullScreenWrapper.Ov13692o.js → withFullScreenWrapper.iW37lS8Z.js} +1 -1
  244. streamlit/static/static/media/SourceCodeVF-Italic.ttf.Ba1oaZG1.woff2 +0 -0
  245. streamlit/static/static/media/SourceCodeVF-Upright.ttf.BjWn63N-.woff2 +0 -0
  246. streamlit/static/static/media/SourceSansVF-Italic.ttf.Bt9VkdQ3.woff2 +0 -0
  247. streamlit/static/static/media/SourceSansVF-Upright.ttf.BsWL4Kly.woff2 +0 -0
  248. streamlit/static/static/media/SourceSerifVariable-Italic.ttf.CVdzAtxO.woff2 +0 -0
  249. streamlit/static/static/media/SourceSerifVariable-Roman.ttf.mdpVL9bi.woff2 +0 -0
  250. streamlit/string_util.py +14 -19
  251. streamlit/temporary_directory.py +13 -4
  252. streamlit/testing/v1/app_test.py +15 -10
  253. streamlit/testing/v1/element_tree.py +157 -178
  254. streamlit/testing/v1/local_script_runner.py +11 -15
  255. streamlit/testing/v1/util.py +11 -4
  256. streamlit/type_util.py +8 -12
  257. streamlit/url_util.py +1 -1
  258. streamlit/user_info.py +6 -5
  259. streamlit/util.py +25 -1
  260. streamlit/vendor/pympler/asizeof.py +3 -2
  261. streamlit/watcher/event_based_path_watcher.py +21 -2
  262. streamlit/watcher/folder_black_list.py +2 -2
  263. streamlit/watcher/local_sources_watcher.py +64 -18
  264. streamlit/watcher/path_watcher.py +6 -10
  265. streamlit/watcher/polling_path_watcher.py +8 -7
  266. streamlit/watcher/util.py +7 -6
  267. streamlit/web/bootstrap.py +16 -14
  268. streamlit/web/cli.py +52 -45
  269. streamlit/web/server/__init__.py +7 -3
  270. streamlit/web/server/app_static_file_handler.py +1 -1
  271. streamlit/web/server/authlib_tornado_integration.py +9 -4
  272. streamlit/web/server/browser_websocket_handler.py +8 -2
  273. streamlit/web/server/component_request_handler.py +14 -10
  274. streamlit/web/server/media_file_handler.py +14 -7
  275. streamlit/web/server/oauth_authlib_routes.py +41 -9
  276. streamlit/web/server/oidc_mixin.py +35 -17
  277. streamlit/web/server/routes.py +32 -22
  278. streamlit/web/server/server.py +13 -24
  279. streamlit/web/server/server_util.py +43 -9
  280. streamlit/web/server/stats_request_handler.py +7 -5
  281. streamlit/web/server/upload_file_request_handler.py +22 -19
  282. streamlit/web/server/websocket_headers.py +1 -1
  283. {streamlit-1.45.1.dist-info → streamlit-1.46.1.dist-info}/METADATA +4 -4
  284. streamlit-1.46.1.dist-info/RECORD +559 -0
  285. {streamlit-1.45.1.dist-info → streamlit-1.46.1.dist-info}/WHEEL +1 -1
  286. streamlit/elements/lib/event_utils.py +0 -39
  287. streamlit/static/static/js/Toolbar.D9RUZv9G.js +0 -1
  288. streamlit/static/static/js/UploadFileInfo.C-jY39rj.js +0 -1
  289. streamlit/static/static/js/index.8jhZBWF2.js +0 -3
  290. streamlit/static/static/js/index.BCx3C6e_.js +0 -1
  291. streamlit/static/static/js/index.BRuTz_S4.js +0 -1
  292. streamlit/static/static/js/index.Bcru_ti-.js +0 -1
  293. streamlit/static/static/js/index.Bl1FMJRd.js +0 -1
  294. streamlit/static/static/js/index.C1z8KpLA.js +0 -779
  295. streamlit/static/static/js/index.C32I2PUe.js +0 -2
  296. streamlit/static/static/js/index.C5GnDRB7.js +0 -1
  297. streamlit/static/static/js/index.CG4qPaaW.js +0 -2
  298. streamlit/static/static/js/index.C_msmT1u.js +0 -1
  299. streamlit/static/static/js/index.CbeNTdd6.js +0 -1
  300. streamlit/static/static/js/index.CnGQVJcw.js +0 -12
  301. streamlit/static/static/js/index.CopVVq4l.js +0 -1
  302. streamlit/static/static/js/index.CtXupx4d.js +0 -197
  303. streamlit/static/static/js/index.DGmCchO7.js +0 -1
  304. streamlit/static/static/js/index.DH6zBk0e.js +0 -1
  305. streamlit/static/static/js/index.DHVlVWsm.js +0 -1
  306. streamlit/static/static/js/index.DRKIVBoi.js +0 -1
  307. streamlit/static/static/js/index.DUd-lFXx.js +0 -73
  308. streamlit/static/static/js/index.D_uRBA4B.js +0 -1
  309. streamlit/static/static/js/index.QHNfgPJd.js +0 -1
  310. streamlit/static/static/js/index.a-RJocYL.js +0 -1
  311. streamlit/static/static/js/index.cvz4B1gy.js +0 -1
  312. streamlit/static/static/js/index.t--hEgTQ.js +0 -6
  313. streamlit/static/static/js/useOnInputChange.z04u96A8.js +0 -1
  314. streamlit/static/static/media/SourceCodePro-Bold.CFEfr7-q.woff2 +0 -0
  315. streamlit/static/static/media/SourceCodePro-BoldItalic.C-LkFXxa.woff2 +0 -0
  316. streamlit/static/static/media/SourceCodePro-Italic.CxFOx7N-.woff2 +0 -0
  317. streamlit/static/static/media/SourceCodePro-Regular.CBOlD63d.woff2 +0 -0
  318. streamlit/static/static/media/SourceCodePro-SemiBold.CFHwW3Wd.woff2 +0 -0
  319. streamlit/static/static/media/SourceCodePro-SemiBoldItalic.Cg2yRu82.woff2 +0 -0
  320. streamlit/static/static/media/SourceSansPro-Bold.-6c9oR8J.woff2 +0 -0
  321. streamlit/static/static/media/SourceSansPro-BoldItalic.DmM_grLY.woff2 +0 -0
  322. streamlit/static/static/media/SourceSansPro-Italic.I1ipWe7Q.woff2 +0 -0
  323. streamlit/static/static/media/SourceSansPro-Regular.DZLUzqI4.woff2 +0 -0
  324. streamlit/static/static/media/SourceSansPro-SemiBold.sKQIyTMz.woff2 +0 -0
  325. streamlit/static/static/media/SourceSansPro-SemiBoldItalic.C0wP0icr.woff2 +0 -0
  326. streamlit/static/static/media/SourceSerifPro-Bold.8TUnKj4x.woff2 +0 -0
  327. streamlit/static/static/media/SourceSerifPro-BoldItalic.CBVO7Ve7.woff2 +0 -0
  328. streamlit/static/static/media/SourceSerifPro-Italic.DkFgL2HZ.woff2 +0 -0
  329. streamlit/static/static/media/SourceSerifPro-Regular.CNJNET2S.woff2 +0 -0
  330. streamlit/static/static/media/SourceSerifPro-SemiBold.CHyh9GC5.woff2 +0 -0
  331. streamlit/static/static/media/SourceSerifPro-SemiBoldItalic.CBtz8sWN.woff2 +0 -0
  332. streamlit-1.45.1.dist-info/RECORD +0 -568
  333. {streamlit-1.45.1.data → streamlit-1.46.1.data}/scripts/streamlit.cmd +0 -0
  334. {streamlit-1.45.1.dist-info → streamlit-1.46.1.dist-info}/entry_points.txt +0 -0
  335. {streamlit-1.45.1.dist-info → streamlit-1.46.1.dist-info}/top_level.txt +0 -0
@@ -57,7 +57,9 @@ class InMemoryCacheStorageWrapper(CacheStorage):
57
57
  it from multiple threads.
58
58
  """
59
59
 
60
- def __init__(self, persist_storage: CacheStorage, context: CacheStorageContext):
60
+ def __init__(
61
+ self, persist_storage: CacheStorage, context: CacheStorageContext
62
+ ) -> None:
61
63
  self.function_key = context.function_key
62
64
  self.function_display_name = context.function_display_name
63
65
  self._ttl_seconds = context.ttl_seconds
@@ -108,18 +110,15 @@ class InMemoryCacheStorageWrapper(CacheStorage):
108
110
 
109
111
  def get_stats(self) -> list[CacheStat]:
110
112
  """Returns a list of stats in bytes for the cache memory storage per item."""
111
- stats = []
112
-
113
113
  with self._mem_cache_lock:
114
- for item in self._mem_cache.values():
115
- stats.append(
116
- CacheStat(
117
- category_name="st_cache_data",
118
- cache_name=self.function_display_name,
119
- byte_length=len(item),
120
- )
114
+ return [
115
+ CacheStat(
116
+ category_name="st_cache_data",
117
+ cache_name=self.function_display_name,
118
+ byte_length=len(item),
121
119
  )
122
- return stats
120
+ for item in self._mem_cache.values()
121
+ ]
123
122
 
124
123
  def close(self) -> None:
125
124
  """Closes the cache storage."""
@@ -132,9 +131,8 @@ class InMemoryCacheStorageWrapper(CacheStorage):
132
131
  _LOGGER.debug("Memory cache HIT: %s", key)
133
132
  return entry
134
133
 
135
- else:
136
- _LOGGER.debug("Memory cache MISS: %s", key)
137
- raise CacheStorageKeyNotFoundError("Key not found in mem cache")
134
+ _LOGGER.debug("Memory cache MISS: %s", key)
135
+ raise CacheStorageKeyNotFoundError("Key not found in mem cache")
138
136
 
139
137
  def _write_to_mem_cache(self, key: str, entry_bytes: bytes) -> None:
140
138
  with self._mem_cache_lock:
@@ -109,9 +109,9 @@ class LocalDiskCacheStorageManager(CacheStorageManager):
109
109
  and not math.isinf(context.ttl_seconds)
110
110
  ):
111
111
  _LOGGER.warning(
112
- f"The cached function '{context.function_display_name}' has a TTL "
113
- "that will be ignored. Persistent cached functions currently don't "
114
- "support TTL."
112
+ "The cached function '%s' has a TTL that will be ignored. "
113
+ "Persistent cached functions currently don't support TTL.",
114
+ context.function_display_name,
115
115
  )
116
116
 
117
117
 
@@ -120,7 +120,7 @@ class LocalDiskCacheStorage(CacheStorage):
120
120
  This is the default cache persistence layer for `@st.cache_data`.
121
121
  """
122
122
 
123
- def __init__(self, context: CacheStorageContext):
123
+ def __init__(self, context: CacheStorageContext) -> None:
124
124
  self.function_key = context.function_key
125
125
  self.persist = context.persist
126
126
  self._ttl_seconds = context.ttl_seconds
@@ -143,8 +143,8 @@ class LocalDiskCacheStorage(CacheStorage):
143
143
  if self.persist == "disk":
144
144
  path = self._get_cache_file_path(key)
145
145
  try:
146
- with streamlit_read(path, binary=True) as input:
147
- value = input.read()
146
+ with streamlit_read(path, binary=True) as file:
147
+ value = file.read()
148
148
  _LOGGER.debug("Disk cache HIT: %s", key)
149
149
  return bytes(value)
150
150
  except FileNotFoundError:
@@ -38,13 +38,13 @@ if TYPE_CHECKING:
38
38
  # 2. Writing two new @overloads for connection_factory (one for the case where the
39
39
  # only the connection name is specified and another when both name and type are).
40
40
  # 3. Updating test_get_first_party_connection_helper in connection_factory_test.py.
41
- FIRST_PARTY_CONNECTIONS = {
41
+ _FIRST_PARTY_CONNECTIONS: Final[dict[str, type[BaseConnection[Any]]]] = {
42
42
  "snowflake": SnowflakeConnection,
43
43
  "snowpark": SnowparkConnection,
44
44
  "sql": SQLConnection,
45
45
  }
46
- MODULE_EXTRACTION_REGEX = re.compile(r"No module named \'(.+)\'")
47
- MODULES_TO_PYPI_PACKAGES: Final[dict[str, str]] = {
46
+ _MODULE_EXTRACTION_REGEX = re.compile(r"No module named \'(.+)\'")
47
+ _MODULES_TO_PYPI_PACKAGES: Final[dict[str, str]] = {
48
48
  "MySQLdb": "mysqlclient",
49
49
  "psycopg2": "psycopg2-binary",
50
50
  "sqlalchemy": "sqlalchemy",
@@ -52,6 +52,7 @@ MODULES_TO_PYPI_PACKAGES: Final[dict[str, str]] = {
52
52
  "snowflake.connector": "snowflake-connector-python",
53
53
  "snowflake.snowpark": "snowflake-snowpark-python",
54
54
  }
55
+ _USE_ENV_PREFIX: Final = "env:"
55
56
 
56
57
  # The BaseConnection bound is parameterized to `Any` below as subclasses of
57
58
  # BaseConnection are responsible for binding the type parameter of BaseConnection to a
@@ -65,7 +66,7 @@ def _create_connection(
65
66
  connection_class: type[ConnectionClass],
66
67
  max_entries: int | None = None,
67
68
  ttl: float | timedelta | None = None,
68
- **kwargs,
69
+ **kwargs: Any,
69
70
  ) -> ConnectionClass:
70
71
  """Create an instance of connection_class with the given name and kwargs.
71
72
 
@@ -76,7 +77,7 @@ def _create_connection(
76
77
  """
77
78
 
78
79
  def __create_connection(
79
- name: str, connection_class: type[ConnectionClass], **kwargs
80
+ name: str, connection_class: type[ConnectionClass], **kwargs: Any
80
81
  ) -> ConnectionClass:
81
82
  return connection_class(connection_name=name, **kwargs)
82
83
 
@@ -103,13 +104,13 @@ def _create_connection(
103
104
  return __create_connection(name, connection_class, **kwargs)
104
105
 
105
106
 
106
- def _get_first_party_connection(connection_class: str):
107
- if connection_class in FIRST_PARTY_CONNECTIONS:
108
- return FIRST_PARTY_CONNECTIONS[connection_class]
107
+ def _get_first_party_connection(connection_class: str) -> type[BaseConnection[Any]]:
108
+ if connection_class in _FIRST_PARTY_CONNECTIONS:
109
+ return _FIRST_PARTY_CONNECTIONS[connection_class]
109
110
 
110
111
  raise StreamlitAPIException(
111
112
  f"Invalid connection '{connection_class}'. "
112
- f"Supported connection classes: {FIRST_PARTY_CONNECTIONS}"
113
+ f"Supported connection classes: {_FIRST_PARTY_CONNECTIONS}"
113
114
  )
114
115
 
115
116
 
@@ -119,7 +120,7 @@ def connection_factory(
119
120
  max_entries: int | None = None,
120
121
  ttl: float | timedelta | None = None,
121
122
  autocommit: bool = False,
122
- **kwargs,
123
+ **kwargs: Any,
123
124
  ) -> SQLConnection:
124
125
  pass
125
126
 
@@ -131,7 +132,7 @@ def connection_factory(
131
132
  max_entries: int | None = None,
132
133
  ttl: float | timedelta | None = None,
133
134
  autocommit: bool = False,
134
- **kwargs,
135
+ **kwargs: Any,
135
136
  ) -> SQLConnection:
136
137
  pass
137
138
 
@@ -142,7 +143,7 @@ def connection_factory(
142
143
  max_entries: int | None = None,
143
144
  ttl: float | timedelta | None = None,
144
145
  autocommit: bool = False,
145
- **kwargs,
146
+ **kwargs: Any,
146
147
  ) -> SnowflakeConnection:
147
148
  pass
148
149
 
@@ -154,7 +155,7 @@ def connection_factory(
154
155
  max_entries: int | None = None,
155
156
  ttl: float | timedelta | None = None,
156
157
  autocommit: bool = False,
157
- **kwargs,
158
+ **kwargs: Any,
158
159
  ) -> SnowflakeConnection:
159
160
  pass
160
161
 
@@ -164,7 +165,7 @@ def connection_factory(
164
165
  name: Literal["snowpark"],
165
166
  max_entries: int | None = None,
166
167
  ttl: float | timedelta | None = None,
167
- **kwargs,
168
+ **kwargs: Any,
168
169
  ) -> SnowparkConnection:
169
170
  pass
170
171
 
@@ -175,7 +176,7 @@ def connection_factory(
175
176
  type: Literal["snowpark"],
176
177
  max_entries: int | None = None,
177
178
  ttl: float | timedelta | None = None,
178
- **kwargs,
179
+ **kwargs: Any,
179
180
  ) -> SnowparkConnection:
180
181
  pass
181
182
 
@@ -186,7 +187,7 @@ def connection_factory(
186
187
  type: type[ConnectionClass],
187
188
  max_entries: int | None = None,
188
189
  ttl: float | timedelta | None = None,
189
- **kwargs,
190
+ **kwargs: Any,
190
191
  ) -> ConnectionClass:
191
192
  pass
192
193
 
@@ -197,12 +198,12 @@ def connection_factory(
197
198
  type: str | None = None,
198
199
  max_entries: int | None = None,
199
200
  ttl: float | timedelta | None = None,
200
- **kwargs,
201
+ **kwargs: Any,
201
202
  ) -> BaseConnection[Any]:
202
203
  pass
203
204
 
204
205
 
205
- def connection_factory(
206
+ def connection_factory( # type: ignore
206
207
  name,
207
208
  type=None,
208
209
  max_entries=None,
@@ -233,7 +234,7 @@ def connection_factory(
233
234
  The type of connection to create. This can be one of the following:
234
235
 
235
236
  - ``None`` (default): Streamlit will infer the connection type from
236
- ``name``. If the type is not inferrable from ``name``, the type must
237
+ ``name``. If the type is not inferable from ``name``, the type must
237
238
  be specified in ``secrets.toml`` instead.
238
239
  - ``"snowflake"``: Streamlit will initialize a connection with
239
240
  |SnowflakeConnection|_.
@@ -267,7 +268,7 @@ def connection_factory(
267
268
  **kwargs : any
268
269
  Connection-specific keyword arguments that are passed to the
269
270
  connection's ``._connect()`` method. ``**kwargs`` are typically
270
- combined with (and take precendence over) key-value pairs in
271
+ combined with (and take precedence over) key-value pairs in
271
272
  ``secrets.toml``. To learn more, see the specific connection's
272
273
  documentation.
273
274
 
@@ -366,19 +367,23 @@ def connection_factory(
366
367
  >>> conn = st.connection("my_sql_connection", type=SQLConnection)
367
368
 
368
369
  """
369
- USE_ENV_PREFIX = "env:"
370
370
 
371
- if name.startswith(USE_ENV_PREFIX):
371
+ if name.startswith(_USE_ENV_PREFIX):
372
372
  # It'd be nice to use str.removeprefix() here, but we won't be able to do that
373
- # until the minimium Python version we support is 3.9.
374
- envvar_name = name[len(USE_ENV_PREFIX) :]
373
+ # until the minimum Python version we support is 3.9.
374
+ envvar_name = name[len(_USE_ENV_PREFIX) :]
375
375
  name = os.environ[envvar_name]
376
376
 
377
- if type is None:
378
- if name in FIRST_PARTY_CONNECTIONS:
377
+ # type is a nice kwarg name for the st.connection user but is annoying to work with
378
+ # since it conflicts with the builtin function name and thus gets syntax
379
+ # highlighted.
380
+ connection_class = type
381
+
382
+ if connection_class is None:
383
+ if name in _FIRST_PARTY_CONNECTIONS:
379
384
  # We allow users to simply write `st.connection("sql")` instead of
380
385
  # `st.connection("sql", type="sql")`.
381
- type = _get_first_party_connection(name)
386
+ connection_class = _get_first_party_connection(name)
382
387
  else:
383
388
  # The user didn't specify a type, so we try to pull it out from their
384
389
  # secrets.toml file. NOTE: we're okay with any of the dict lookups below
@@ -386,12 +391,7 @@ def connection_factory(
386
391
  # it must be the case that it's defined in secrets.toml and should raise an
387
392
  # Exception otherwise.
388
393
  secrets_singleton.load_if_toml_exists()
389
- type = secrets_singleton["connections"][name]["type"]
390
-
391
- # type is a nice kwarg name for the st.connection user but is annoying to work with
392
- # since it conflicts with the builtin function name and thus gets syntax
393
- # highlighted.
394
- connection_class = type
394
+ connection_class = secrets_singleton["connections"][name]["type"]
395
395
 
396
396
  if isinstance(connection_class, str):
397
397
  # We assume that a connection_class specified via string is either the fully
@@ -424,12 +424,12 @@ def connection_factory(
424
424
  return conn
425
425
  except ModuleNotFoundError as e:
426
426
  err_string = str(e)
427
- missing_module = re.search(MODULE_EXTRACTION_REGEX, err_string)
427
+ missing_module = re.search(_MODULE_EXTRACTION_REGEX, err_string)
428
428
 
429
429
  extra_info = "You may be missing a dependency required to use this connection."
430
430
  if missing_module:
431
- pypi_package = MODULES_TO_PYPI_PACKAGES.get(missing_module.group(1))
431
+ pypi_package = _MODULES_TO_PYPI_PACKAGES.get(missing_module.group(1))
432
432
  if pypi_package:
433
433
  extra_info = f"You need to install the '{pypi_package}' package to use this connection."
434
434
 
435
- raise ModuleNotFoundError(f"{str(e)}. {extra_info}")
435
+ raise ModuleNotFoundError(f"{e}. {extra_info}")
@@ -17,12 +17,13 @@ from __future__ import annotations
17
17
  from collections.abc import Iterable, Iterator, Mapping
18
18
  from functools import lru_cache
19
19
  from types import MappingProxyType
20
- from typing import TYPE_CHECKING, Any, cast
20
+ from typing import TYPE_CHECKING, Any, Literal, cast
21
21
 
22
22
  from streamlit import runtime
23
23
  from streamlit.runtime.context_util import maybe_add_page_path, maybe_trim_page_path
24
24
  from streamlit.runtime.metrics_util import gather_metrics
25
25
  from streamlit.runtime.scriptrunner_utils.script_run_context import get_script_run_ctx
26
+ from streamlit.util import AttributeDictionary
26
27
 
27
28
  if TYPE_CHECKING:
28
29
  from http.cookies import Morsel
@@ -63,8 +64,28 @@ def _normalize_header(name: str) -> str:
63
64
  return "-".join(w.capitalize() for w in name.split("-"))
64
65
 
65
66
 
67
+ class StreamlitTheme(AttributeDictionary):
68
+ """A dictionary-like object containing theme information.
69
+
70
+ This class extends the functionality of a standard dictionary to allow items
71
+ to be accessed via attribute-style dot notation in addition to the traditional
72
+ key-based access. If a dictionary item is accessed and is itself a dictionary,
73
+ it is automatically wrapped in another `AttributeDictionary`, enabling recursive
74
+ attribute-style access.
75
+ """
76
+
77
+ type: Literal["dark", "light"] | None
78
+
79
+ def __init__(self, theme_info: dict[str, str | None]):
80
+ super().__init__(theme_info)
81
+
82
+ @classmethod
83
+ def from_context_info(cls, context_dict: dict[str, str | None]) -> StreamlitTheme:
84
+ return cls(context_dict)
85
+
86
+
66
87
  class StreamlitHeaders(Mapping[str, str]):
67
- def __init__(self, headers: Iterable[tuple[str, str]]):
88
+ def __init__(self, headers: Iterable[tuple[str, str]]) -> None:
68
89
  dict_like_headers: dict[str, list[str]] = {}
69
90
 
70
91
  for key, value in headers:
@@ -98,7 +119,7 @@ class StreamlitHeaders(Mapping[str, str]):
98
119
 
99
120
 
100
121
  class StreamlitCookies(Mapping[str, str]):
101
- def __init__(self, cookies: Mapping[str, str]):
122
+ def __init__(self, cookies: Mapping[str, str]) -> None:
102
123
  self._cookies = MappingProxyType(cookies)
103
124
 
104
125
  @classmethod
@@ -215,6 +236,38 @@ class ContextProxy:
215
236
  cookies = session_client_request.cookies
216
237
  return StreamlitCookies.from_tornado_cookies(cookies)
217
238
 
239
+ @property
240
+ @gather_metrics("context.theme")
241
+ def theme(self) -> StreamlitTheme:
242
+ """A read-only, dictionary-like object containing theme information.
243
+
244
+ Theme information is restricted to the ``type`` of the theme (dark or
245
+ light) and is inferred from the background color of the app.
246
+
247
+ .. note::
248
+ Changes made to the background color through CSS are not included.
249
+
250
+ Attributes
251
+ ----------
252
+ type : "light", "dark"
253
+ The theme type inferred from the background color of the app.
254
+
255
+ Example
256
+ -------
257
+ Access the theme type of the app:
258
+
259
+ >>> import streamlit as st
260
+ >>>
261
+ >>> st.write(f"The current theme type is {st.context.theme.type}.")
262
+
263
+ """
264
+ ctx = get_script_run_ctx()
265
+
266
+ if ctx is None or ctx.context_info is None:
267
+ return StreamlitTheme({"type": None})
268
+
269
+ return StreamlitTheme.from_context_info({"type": ctx.context_info.color_scheme})
270
+
218
271
  @property
219
272
  @gather_metrics("context.timezone")
220
273
  def timezone(self) -> str | None:
@@ -328,11 +381,7 @@ class ContextProxy:
328
381
  url_without_page_prefix = maybe_trim_page_path(
329
382
  url_from_frontend, ctx.pages_manager
330
383
  )
331
- url_with_page_prefix = maybe_add_page_path(
332
- url_without_page_prefix, ctx.pages_manager
333
- )
334
-
335
- return url_with_page_prefix
384
+ return maybe_add_page_path(url_without_page_prefix, ctx.pages_manager)
336
385
 
337
386
  @property
338
387
  @gather_metrics("context.ip_address")
@@ -367,7 +416,7 @@ class ContextProxy:
367
416
  session_client_request = _get_request()
368
417
  if session_client_request is not None:
369
418
  remote_ip = session_client_request.remote_ip
370
- if remote_ip == "::1" or remote_ip == "127.0.0.1":
419
+ if remote_ip in {"::1", "127.0.0.1"}:
371
420
  return None
372
421
  return remote_ip
373
422
  return None
@@ -20,7 +20,7 @@ import json
20
20
  import os
21
21
  import sys
22
22
  import textwrap
23
- from typing import Final, NamedTuple, NoReturn
23
+ from typing import Final, NamedTuple, NoReturn, cast
24
24
  from uuid import uuid4
25
25
 
26
26
  from streamlit import cli_util, env_util, file_util, util
@@ -29,10 +29,11 @@ from streamlit.logger import get_logger
29
29
  _LOGGER: Final = get_logger(__name__)
30
30
 
31
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"
32
+ _CONFIG_FILE_PATH: Final = (
33
+ r"%userprofile%/.streamlit/config.toml"
34
+ if env_util.IS_WINDOWS
35
+ else "~/.streamlit/config.toml"
36
+ )
36
37
 
37
38
 
38
39
  class _Activation(NamedTuple):
@@ -53,7 +54,7 @@ def email_prompt() -> str:
53
54
  return f"""
54
55
  {"👋 " if show_emoji else ""}{cli_util.style_for_cli("Welcome to Streamlit!", bold=True)}
55
56
 
56
- If youd like to receive helpful onboarding emails, news, offers, promotions,
57
+ If you'd like to receive helpful onboarding emails, news, offers, promotions,
57
58
  and the occasional swag, please enter your email address below. Otherwise,
58
59
  leave this field blank.
59
60
 
@@ -65,7 +66,7 @@ Collecting usage statistics. To deactivate, set browser.gatherUsageStats to fals
65
66
  """
66
67
 
67
68
 
68
- def _send_email(email: str) -> None:
69
+ def _send_email(email: str | None) -> None:
69
70
  """Send the user's email for metrics, if submitted."""
70
71
  import requests
71
72
 
@@ -79,7 +80,7 @@ def _send_email(email: str) -> None:
79
80
  ).json()
80
81
  metrics_url = response_json.get("url", "")
81
82
  except Exception:
82
- _LOGGER.error("Failed to fetch metrics URL")
83
+ _LOGGER.exception("Failed to fetch metrics URL")
83
84
  return
84
85
 
85
86
  headers = {
@@ -104,6 +105,7 @@ def _send_email(email: str) -> None:
104
105
  metrics_url,
105
106
  headers=headers,
106
107
  data=json.dumps(data).encode(),
108
+ timeout=10,
107
109
  )
108
110
 
109
111
  response.raise_for_status()
@@ -115,22 +117,22 @@ class Credentials:
115
117
  _singleton: Credentials | None = None
116
118
 
117
119
  @classmethod
118
- def get_current(cls):
120
+ def get_current(cls) -> Credentials:
119
121
  """Return the singleton instance."""
120
122
  if cls._singleton is None:
121
123
  Credentials()
122
124
 
123
- return Credentials._singleton
125
+ return cast("Credentials", Credentials._singleton)
124
126
 
125
- def __init__(self):
127
+ def __init__(self) -> None:
126
128
  """Initialize class."""
127
129
  if Credentials._singleton is not None:
128
130
  raise RuntimeError(
129
131
  "Credentials already initialized. Use .get_current() instead"
130
132
  )
131
133
 
132
- self.activation = None
133
- self._conf_file = _get_credential_file_path()
134
+ self.activation: _Activation | None = None
135
+ self._conf_file: str = _get_credential_file_path()
134
136
 
135
137
  Credentials._singleton = self
136
138
 
@@ -149,7 +151,7 @@ class Credentials:
149
151
  with open(self._conf_file) as f:
150
152
  data = toml.load(f).get("general")
151
153
  if data is None:
152
- raise Exception
154
+ raise RuntimeError # noqa: TRY301
153
155
  self.activation = _verify_email(data.get("email"))
154
156
  except FileNotFoundError:
155
157
  if auto_resolve:
@@ -163,7 +165,7 @@ class Credentials:
163
165
  self.reset()
164
166
  self.activate(show_instructions=not auto_resolve)
165
167
  return
166
- raise Exception(
168
+ raise RuntimeError(
167
169
  textwrap.dedent(
168
170
  """
169
171
  Unable to load credentials from %s.
@@ -261,43 +263,30 @@ class Credentials:
261
263
  if self.activation.is_valid:
262
264
  self.save()
263
265
  # IMPORTANT: Break the text below at 80 chars.
264
- TELEMETRY_TEXT = """
265
- You can find our privacy policy at %(link)s
266
+ telemetry_text = f"""
267
+ You can find our privacy policy at {cli_util.style_for_cli("https://streamlit.io/privacy-policy", underline=True)}
266
268
 
267
269
  Summary:
268
270
  - This open source library collects usage statistics.
269
271
  - We cannot see and do not store information contained inside Streamlit apps,
270
272
  such as text, charts, images, etc.
271
273
  - Telemetry data is stored in servers in the United States.
272
- - If you'd like to opt out, add the following to %(config)s,
274
+ - If you'd like to opt out, add the following to {cli_util.style_for_cli(_CONFIG_FILE_PATH)},
273
275
  creating that file if necessary:
274
276
 
275
277
  [browser]
276
278
  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)
279
+ """
280
+
281
+ cli_util.print_to_cli(telemetry_text)
285
282
  if show_instructions:
286
283
  # 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)
284
+ instructions_text = f"""
285
+ {cli_util.style_for_cli("Get started by typing:", fg="blue", bold=True)}
286
+ {cli_util.style_for_cli("$", fg="blue")} {cli_util.style_for_cli("streamlit hello", bold=True)}
287
+ """
288
+
289
+ cli_util.print_to_cli(instructions_text)
301
290
  activated = True
302
291
  else: # pragma: nocover
303
292
  _LOGGER.error("Please try again.")
@@ -41,7 +41,7 @@ class ForwardMsgQueue:
41
41
  """
42
42
  ForwardMsgQueue._before_enqueue_msg = before_enqueue_msg
43
43
 
44
- def __init__(self):
44
+ def __init__(self) -> None:
45
45
  self._queue: list[ForwardMsg] = []
46
46
  # A mapping of (delta_path -> _queue.indexof(msg)) for each
47
47
  # Delta message in the queue. We use this for coalescing
@@ -82,13 +82,13 @@ class ForwardMsgQueue:
82
82
  # since the queue can be flushed to the browser at any time.
83
83
  # For example:
84
84
  # queue 1:
85
- # empty [0, 0] <- skipped
86
- # markdown [0, 0]
87
- # empty [1, 0] <- send to frontend
85
+ # > empty [0, 0] <- skipped
86
+ # > markdown [0, 0]
87
+ # > empty [1, 0] <- send to frontend
88
88
  #
89
89
  # queue 2:
90
- # markdown [1, 0]
91
- # ...
90
+ # > markdown [1, 0]
91
+ # > ...
92
92
 
93
93
  delta_key = tuple(msg.metadata.delta_path)
94
94
  if delta_key in self._delta_index_map:
@@ -184,7 +184,7 @@ def _is_composable_message(msg: ForwardMsg) -> bool:
184
184
  # operation can raise errors, and we don't have a good way of handling
185
185
  # those errors in the message queue.
186
186
  delta_type = msg.delta.WhichOneof("type")
187
- return delta_type != "add_rows" and delta_type != "arrow_add_rows"
187
+ return delta_type not in {"add_rows", "arrow_add_rows"}
188
188
 
189
189
 
190
190
  def _maybe_compose_delta_msgs(
@@ -204,9 +204,9 @@ def _maybe_compose_delta_msgs(
204
204
  # We never replace add_block deltas, because blocks can have
205
205
  # other dependent deltas later in the queue. For example:
206
206
  #
207
- # placeholder = st.empty()
208
- # placeholder.columns(1)
209
- # placeholder.empty()
207
+ # > placeholder = st.empty()
208
+ # > placeholder.columns(1)
209
+ # > placeholder.empty()
210
210
  #
211
211
  # The call to "placeholder.columns(1)" creates two blocks, a parent
212
212
  # container with delta_path (0, 0), and a column child with
@@ -222,7 +222,7 @@ def _maybe_compose_delta_msgs(
222
222
  return new_msg
223
223
 
224
224
  new_delta_type = new_msg.delta.WhichOneof("type")
225
- if new_delta_type == "new_element" or new_delta_type == "add_block":
225
+ if new_delta_type in {"new_element", "add_block"}:
226
226
  return new_msg
227
227
 
228
228
  return None
@@ -155,11 +155,10 @@ def _fragment(
155
155
  )
156
156
 
157
157
  return wrapper
158
- else:
159
- non_optional_func = func
158
+ non_optional_func = func
160
159
 
161
160
  @wraps(non_optional_func)
162
- def wrap(*args, **kwargs):
161
+ def wrap(*args: Any, **kwargs: Any) -> Any:
163
162
  from streamlit.delta_generator_singletons import context_dg_stack
164
163
 
165
164
  ctx = get_script_run_ctx()
@@ -176,7 +175,7 @@ def _fragment(
176
175
  # that the fragment is associated with the correct script running.
177
176
  initialized_active_script_hash = ctx.active_script_hash
178
177
 
179
- def wrapped_fragment():
178
+ def wrapped_fragment() -> Any:
180
179
  import streamlit as st
181
180
 
182
181
  if should_show_deprecation_warning:
@@ -193,7 +192,8 @@ def _fragment(
193
192
  # fragment runs will generally run in a new script run, thus we'll have a
194
193
  # new ctx.
195
194
  ctx = get_script_run_ctx(suppress_warning=True)
196
- assert ctx is not None
195
+ if ctx is None:
196
+ raise RuntimeError("ctx is None. This should never happen.")
197
197
 
198
198
  if ctx.fragment_ids_this_run:
199
199
  # This script run is a run of one or more fragments. We restore the
@@ -246,11 +246,11 @@ def _fragment(
246
246
  except (
247
247
  RerunException,
248
248
  StopException,
249
- ) as e:
249
+ ):
250
250
  # The wrapped_fragment function is executed
251
251
  # inside of a exec_func_with_error_handling call, so
252
252
  # there is a correct handler for these exceptions.
253
- raise e
253
+ raise
254
254
  except Exception as e:
255
255
  # render error here so that the delta path is correct
256
256
  # for full app runs, the error will be displayed by the