streamlit 1.51.0__py3-none-any.whl → 1.52.0__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 (314) hide show
  1. streamlit/__init__.py +1 -0
  2. streamlit/commands/execution_control.py +89 -14
  3. streamlit/components/v1/component_arrow.py +7 -7
  4. streamlit/components/v2/__init__.py +59 -3
  5. streamlit/components/v2/bidi_component/main.py +161 -13
  6. streamlit/components/v2/bidi_component/serialization.py +13 -6
  7. streamlit/components/v2/component_manager.py +11 -3
  8. streamlit/components/v2/component_registry.py +18 -1
  9. streamlit/components/v2/types.py +2 -2
  10. streamlit/connections/snowflake_connection.py +1 -1
  11. streamlit/connections/snowpark_connection.py +1 -1
  12. streamlit/dataframe_util.py +18 -18
  13. streamlit/delta_generator.py +7 -0
  14. streamlit/delta_generator_singletons.py +8 -14
  15. streamlit/elements/alert.py +16 -0
  16. streamlit/elements/arrow.py +36 -6
  17. streamlit/elements/bokeh_chart.py +10 -78
  18. streamlit/elements/code.py +2 -2
  19. streamlit/elements/deck_gl_json_chart.py +1 -1
  20. streamlit/elements/exception.py +1 -1
  21. streamlit/elements/form.py +27 -0
  22. streamlit/elements/heading.py +60 -5
  23. streamlit/elements/html.py +13 -2
  24. streamlit/elements/image.py +1 -1
  25. streamlit/elements/layouts.py +28 -22
  26. streamlit/elements/lib/built_in_chart_utils.py +49 -16
  27. streamlit/elements/lib/color_util.py +1 -1
  28. streamlit/elements/lib/column_config_utils.py +6 -5
  29. streamlit/elements/lib/layout_utils.py +50 -0
  30. streamlit/elements/lib/pandas_styler_utils.py +17 -9
  31. streamlit/elements/lib/shortcut_utils.py +152 -0
  32. streamlit/elements/markdown.py +50 -3
  33. streamlit/elements/metric.py +31 -1
  34. streamlit/elements/plotly_chart.py +75 -6
  35. streamlit/elements/spinner.py +1 -1
  36. streamlit/elements/text.py +20 -3
  37. streamlit/elements/toast.py +2 -0
  38. streamlit/elements/vega_charts.py +17 -1
  39. streamlit/elements/widgets/audio_input.py +8 -7
  40. streamlit/elements/widgets/button.py +279 -40
  41. streamlit/elements/widgets/button_group.py +27 -2
  42. streamlit/elements/widgets/camera_input.py +1 -1
  43. streamlit/elements/widgets/chat.py +300 -42
  44. streamlit/elements/widgets/color_picker.py +7 -0
  45. streamlit/elements/widgets/data_editor.py +68 -28
  46. streamlit/elements/widgets/file_uploader.py +4 -1
  47. streamlit/elements/widgets/number_input.py +2 -0
  48. streamlit/elements/widgets/text_widgets.py +2 -0
  49. streamlit/elements/widgets/time_widgets.py +581 -9
  50. streamlit/errors.py +22 -0
  51. streamlit/git_util.py +1 -1
  52. streamlit/navigation/page.py +7 -0
  53. streamlit/net_util.py +2 -2
  54. streamlit/proto/Alert_pb2.pyi +3 -3
  55. streamlit/proto/AppPage_pb2.pyi +7 -1
  56. streamlit/proto/ArrowData_pb2.pyi +7 -1
  57. streamlit/proto/ArrowNamedDataSet_pb2.pyi +7 -1
  58. streamlit/proto/ArrowVegaLiteChart_pb2.pyi +7 -1
  59. streamlit/proto/Arrow_pb2.py +10 -10
  60. streamlit/proto/Arrow_pb2.pyi +19 -12
  61. streamlit/proto/AudioInput_pb2.pyi +7 -1
  62. streamlit/proto/Audio_pb2.pyi +7 -1
  63. streamlit/proto/AuthRedirect_pb2.pyi +7 -1
  64. streamlit/proto/AutoRerun_pb2.pyi +7 -1
  65. streamlit/proto/BackMsg_pb2.py +4 -2
  66. streamlit/proto/BackMsg_pb2.pyi +34 -4
  67. streamlit/proto/Balloons_pb2.pyi +7 -1
  68. streamlit/proto/BidiComponent_pb2.pyi +10 -4
  69. streamlit/proto/Block_pb2.pyi +35 -35
  70. streamlit/proto/BokehChart_pb2.pyi +7 -1
  71. streamlit/proto/ButtonGroup_pb2.pyi +9 -9
  72. streamlit/proto/Button_pb2.py +2 -2
  73. streamlit/proto/Button_pb2.pyi +11 -2
  74. streamlit/proto/CameraInput_pb2.pyi +7 -1
  75. streamlit/proto/ChatInput_pb2.py +6 -6
  76. streamlit/proto/ChatInput_pb2.pyi +18 -6
  77. streamlit/proto/Checkbox_pb2.pyi +3 -3
  78. streamlit/proto/ClientState_pb2.pyi +10 -4
  79. streamlit/proto/Code_pb2.pyi +7 -1
  80. streamlit/proto/ColorPicker_pb2.pyi +7 -1
  81. streamlit/proto/Common_pb2.py +3 -3
  82. streamlit/proto/Common_pb2.pyi +35 -23
  83. streamlit/proto/Components_pb2.pyi +19 -13
  84. streamlit/proto/DataFrame_pb2.pyi +55 -49
  85. streamlit/proto/DateInput_pb2.pyi +7 -1
  86. streamlit/proto/DateTimeInput_pb2.py +28 -0
  87. streamlit/proto/DateTimeInput_pb2.pyi +92 -0
  88. streamlit/proto/DeckGlJsonChart_pb2.pyi +3 -3
  89. streamlit/proto/Delta_pb2.pyi +7 -1
  90. streamlit/proto/DocString_pb2.pyi +10 -4
  91. streamlit/proto/DownloadButton_pb2.py +2 -2
  92. streamlit/proto/DownloadButton_pb2.pyi +16 -2
  93. streamlit/proto/Element_pb2.py +5 -3
  94. streamlit/proto/Element_pb2.pyi +23 -5
  95. streamlit/proto/Empty_pb2.pyi +7 -1
  96. streamlit/proto/Exception_pb2.pyi +7 -1
  97. streamlit/proto/Favicon_pb2.pyi +7 -1
  98. streamlit/proto/FileUploader_pb2.pyi +7 -1
  99. streamlit/proto/ForwardMsg_pb2.py +12 -10
  100. streamlit/proto/ForwardMsg_pb2.pyi +42 -15
  101. streamlit/proto/GapSize_pb2.pyi +4 -4
  102. streamlit/proto/GitInfo_pb2.pyi +3 -3
  103. streamlit/proto/GraphVizChart_pb2.pyi +7 -1
  104. streamlit/proto/Heading_pb2.pyi +7 -1
  105. streamlit/proto/HeightConfig_pb2.pyi +7 -1
  106. streamlit/proto/Html_pb2.py +2 -2
  107. streamlit/proto/Html_pb2.pyi +11 -2
  108. streamlit/proto/IFrame_pb2.pyi +7 -1
  109. streamlit/proto/Image_pb2.pyi +10 -4
  110. streamlit/proto/Json_pb2.pyi +7 -1
  111. streamlit/proto/LabelVisibilityMessage_pb2.pyi +3 -3
  112. streamlit/proto/LinkButton_pb2.py +2 -2
  113. streamlit/proto/LinkButton_pb2.pyi +15 -2
  114. streamlit/proto/Logo_pb2.pyi +7 -1
  115. streamlit/proto/Markdown_pb2.pyi +3 -3
  116. streamlit/proto/Metric_pb2.pyi +7 -7
  117. streamlit/proto/MetricsEvent_pb2.pyi +10 -4
  118. streamlit/proto/MultiSelect_pb2.pyi +7 -1
  119. streamlit/proto/NamedDataSet_pb2.pyi +7 -1
  120. streamlit/proto/Navigation_pb2.pyi +3 -3
  121. streamlit/proto/NewSession_pb2.pyi +40 -40
  122. streamlit/proto/NumberInput_pb2.pyi +3 -3
  123. streamlit/proto/PageConfig_pb2.pyi +7 -7
  124. streamlit/proto/PageInfo_pb2.pyi +7 -1
  125. streamlit/proto/PageLink_pb2.py +2 -2
  126. streamlit/proto/PageLink_pb2.pyi +11 -2
  127. streamlit/proto/PageNotFound_pb2.pyi +7 -1
  128. streamlit/proto/PageProfile_pb2.pyi +13 -7
  129. streamlit/proto/PagesChanged_pb2.pyi +7 -1
  130. streamlit/proto/ParentMessage_pb2.pyi +7 -1
  131. streamlit/proto/PlotlyChart_pb2.pyi +6 -6
  132. streamlit/proto/Progress_pb2.pyi +7 -1
  133. streamlit/proto/Radio_pb2.pyi +7 -1
  134. streamlit/proto/RootContainer_pb2.pyi +1 -1
  135. streamlit/proto/Selectbox_pb2.pyi +7 -1
  136. streamlit/proto/SessionEvent_pb2.pyi +7 -1
  137. streamlit/proto/SessionStatus_pb2.pyi +7 -1
  138. streamlit/proto/Skeleton_pb2.pyi +3 -3
  139. streamlit/proto/Slider_pb2.pyi +5 -5
  140. streamlit/proto/Snow_pb2.pyi +7 -1
  141. streamlit/proto/Space_pb2.pyi +7 -1
  142. streamlit/proto/Spinner_pb2.pyi +7 -1
  143. streamlit/proto/TextAlignmentConfig_pb2.py +29 -0
  144. streamlit/proto/TextAlignmentConfig_pb2.pyi +68 -0
  145. streamlit/proto/TextArea_pb2.pyi +7 -1
  146. streamlit/proto/TextInput_pb2.pyi +3 -3
  147. streamlit/proto/Text_pb2.pyi +7 -1
  148. streamlit/proto/TimeInput_pb2.pyi +7 -1
  149. streamlit/proto/Toast_pb2.pyi +7 -1
  150. streamlit/proto/VegaLiteChart_pb2.pyi +7 -1
  151. streamlit/proto/Video_pb2.pyi +6 -6
  152. streamlit/proto/WidgetStates_pb2.pyi +10 -4
  153. streamlit/proto/WidthConfig_pb2.pyi +7 -1
  154. streamlit/proto/openmetrics_data_model_pb2.pyi +52 -52
  155. streamlit/runtime/app_session.py +38 -1
  156. streamlit/runtime/caching/cache_data_api.py +1 -1
  157. streamlit/runtime/caching/cache_resource_api.py +2 -2
  158. streamlit/runtime/caching/cache_utils.py +1 -1
  159. streamlit/runtime/caching/hashing.py +1 -1
  160. streamlit/runtime/download_data_util.py +53 -0
  161. streamlit/runtime/forward_msg_queue.py +1 -0
  162. streamlit/runtime/media_file_manager.py +178 -2
  163. streamlit/runtime/metrics_util.py +87 -3
  164. streamlit/runtime/scriptrunner/script_runner.py +3 -1
  165. streamlit/runtime/state/query_params.py +80 -29
  166. streamlit/runtime/state/session_state.py +2 -2
  167. streamlit/static/index.html +1 -1
  168. streamlit/static/manifest.json +530 -229
  169. streamlit/static/static/js/{ErrorOutline.esm.YoJdlW1p.js → ErrorOutline.esm.ZJDbmVTx.js} +1 -1
  170. streamlit/static/static/js/{FileDownload.esm.Ddx8VEYy.js → FileDownload.esm.Dx0vI3vH.js} +1 -1
  171. streamlit/static/static/js/{FileHelper.90EtOmj9.js → FileHelper.B7Ero7qQ.js} +3 -3
  172. streamlit/static/static/js/{FormClearHelper.BB1Km6eP.js → FormClearHelper.CG2XN1_g.js} +1 -1
  173. streamlit/static/static/js/IFrameUtil.DefezniK.js +1 -0
  174. streamlit/static/static/js/InputInstructions.Cj5-1zf6.js +1 -0
  175. streamlit/static/static/js/Particles.BfWfv0Aw.js +1 -0
  176. streamlit/static/static/js/{ProgressBar.DLY8H6nE.js → ProgressBar.CGQ8OgfO.js} +2 -2
  177. streamlit/static/static/js/StreamlitSyntaxHighlighter.DTKLpwhl.js +20 -0
  178. streamlit/static/static/js/{Toolbar.D8nHCkuz.js → Toolbar.B2qFUmd9.js} +1 -1
  179. streamlit/static/static/js/_arrayIncludes.B19Iyn2B.js +1 -0
  180. streamlit/static/static/js/_baseIndexOf.BTknn6Gb.js +1 -0
  181. streamlit/static/static/js/{base-input.CJGiNqed.js → base-input.o9tL8MDP.js} +4 -4
  182. streamlit/static/static/js/{checkbox.Cpdd482O.js → checkbox.0BeV1IBL.js} +1 -1
  183. streamlit/static/static/js/{createSuper.CuQIogbW.js → createSuper.RBO59fEm.js} +1 -1
  184. streamlit/static/static/js/data-grid-overlay-editor.CiTkUy0t.js +1 -0
  185. streamlit/static/static/js/{downloader.CN0K7xlu.js → downloader.DwNZg3Mw.js} +1 -1
  186. streamlit/static/static/js/embed.XT9xNd3F.js +195 -0
  187. streamlit/static/static/js/{es6.BJcsVXQ0.js → es6.x9KsYQg-.js} +2 -2
  188. streamlit/static/static/js/{iframeResizer.contentWindow.XzUvQqcZ.js → iframeResizer.contentWindow.ZVXpMPi0.js} +1 -1
  189. streamlit/static/static/js/index.5VPOamri.js +1 -0
  190. streamlit/static/static/js/index.8HslT92O.js +14 -0
  191. streamlit/static/static/js/index.AnXMIBz3.js +7 -0
  192. streamlit/static/static/js/index.B0yp3bM1.js +6 -0
  193. streamlit/static/static/js/index.B1fRb5wF.js +1 -0
  194. streamlit/static/static/js/index.B527JZdO.js +3 -0
  195. streamlit/static/static/js/index.BHgV-yW4.js +1 -0
  196. streamlit/static/static/js/index.BQr-XwGV.js +1 -0
  197. streamlit/static/static/js/index.BTtmaLDB.js +1 -0
  198. streamlit/static/static/js/index.BWB_91TA.js +1 -0
  199. streamlit/static/static/js/index.BfEKaEmw.js +1 -0
  200. streamlit/static/static/js/index.BfXjTO8b.js +1 -0
  201. streamlit/static/static/js/index.Bjy4NRu9.js +3 -0
  202. streamlit/static/static/js/index.Bu5JWpT_.js +1 -0
  203. streamlit/static/static/js/index.BuCx76ZV.js +1 -0
  204. streamlit/static/static/js/index.BxjzhVUb.js +2 -0
  205. streamlit/static/static/js/index.By55VdPY.js +1 -0
  206. streamlit/static/static/js/index.CF5MxTbK.js +1 -0
  207. streamlit/static/static/js/index.CLmq_z9K.js +1 -0
  208. streamlit/static/static/js/index.CNH4rdSz.js +1 -0
  209. streamlit/static/static/js/{index.D3GPA5k4.js → index.CTgm_-jO.js} +9 -40
  210. streamlit/static/static/js/index.C_rK-Swb.js +188 -0
  211. streamlit/static/static/js/index.CjozwSzS.js +1 -0
  212. streamlit/static/static/js/{index.DOFlg3dS.js → index.CkGVt6-G.js} +1 -1
  213. streamlit/static/static/js/index.CuvXOyER.js +2 -0
  214. streamlit/static/static/js/{index.B_dWA3vd.js → index.CyUHWoCC.js} +2 -2
  215. streamlit/static/static/js/index.CyroQtI4.js +2 -0
  216. streamlit/static/static/js/index.D6HmkoDm.js +263 -0
  217. streamlit/static/static/js/index.DAqCNvsO.js +1 -0
  218. streamlit/static/static/js/index.DB_w_CZQ.js +1 -0
  219. streamlit/static/static/js/index.DBalctjj.js +2 -0
  220. streamlit/static/static/js/index.DK0RFJUG.js +11 -0
  221. streamlit/static/static/js/index.DMxc2XFp.js +151 -0
  222. streamlit/static/static/js/index.DO5utP74.js +2 -0
  223. streamlit/static/static/js/index.DS7lf09n.js +1 -0
  224. streamlit/static/static/js/index.DWexTVLY.js +1 -0
  225. streamlit/static/static/js/index.DXxnU5ej.js +1 -0
  226. streamlit/static/static/js/index.DcU3uDvB.js +2 -0
  227. streamlit/static/static/js/index.DlltaH7J.js +1 -0
  228. streamlit/static/static/js/index.DpNTZz82.js +27 -0
  229. streamlit/static/static/js/index.Dr9HIhQw.js +1 -0
  230. streamlit/static/static/js/index.DsgAU5lc.js +1 -0
  231. streamlit/static/static/js/{index.DPUXkcQL.js → index.KfXqjDYy.js} +1 -1
  232. streamlit/static/static/js/index.PaidgjCs.js +1 -0
  233. streamlit/static/static/js/index.RJZuWCGA.js +1 -0
  234. streamlit/static/static/js/{index.CxIUUfab.js → index.hbeqcRTn.js} +53 -122
  235. streamlit/static/static/js/index.q5hIQwAY.js +1 -0
  236. streamlit/static/static/js/index.rORSX6IW.js +1 -0
  237. streamlit/static/static/js/index.uSX757_v.js +1 -0
  238. streamlit/static/static/js/index.x_QRaLMd.js +1 -0
  239. streamlit/static/static/js/{input.D4MN_FzN.js → input.D5oh9-aB.js} +2 -2
  240. streamlit/static/static/js/main.q9oGOg0H.js +13 -0
  241. streamlit/static/static/js/{memory.DrZjtdGT.js → memory.5kCSFUJS.js} +1 -1
  242. streamlit/static/static/js/moment.C3j7ZXd7.js +4 -0
  243. streamlit/static/static/js/number-overlay-editor.Cn_LsK8N.js +9 -0
  244. streamlit/static/static/js/pandasStylerUtils.BqhXt51_.js +1 -0
  245. streamlit/static/static/js/{possibleConstructorReturn.exeeJQEP.js → possibleConstructorReturn.DD9NK1Z8.js} +1 -1
  246. streamlit/static/static/js/{sandbox.ClO3IuUr.js → sandbox.DACSyz29.js} +1 -1
  247. streamlit/static/static/js/styled-components.C3R090At.js +1 -0
  248. streamlit/static/static/js/threshold.Q1mXg5rX.js +1 -0
  249. streamlit/static/static/js/throttle.B0GR3Iyz.js +1 -0
  250. streamlit/static/static/js/{timepicker.DAhu-vcF.js → timepicker.BdhzPxrv.js} +1 -1
  251. streamlit/static/static/js/timer.C2hYhUse.js +1 -0
  252. streamlit/static/static/js/{toConsumableArray.DNbljYEC.js → toConsumableArray.Db2pdqM2.js} +1 -1
  253. streamlit/static/static/js/uniqueId.CtqIr-Yh.js +1 -0
  254. streamlit/static/static/js/urls.BwSlolu9.js +1 -0
  255. streamlit/static/static/js/{useBasicWidgetState.D6sOH6oI.js → useBasicWidgetState.Bfp6TnSw.js} +1 -1
  256. streamlit/static/static/js/useIntlLocale.hRV75Xgj.js +12 -0
  257. streamlit/static/static/js/{useTextInputAutoExpand.4u3_GcuN.js → useTextInputAutoExpand.QepX7n8Y.js} +1 -1
  258. streamlit/static/static/js/useUpdateUiValue.DHx8TzX6.js +1 -0
  259. streamlit/static/static/js/useWaveformController.WxVzpzEX.js +1 -0
  260. streamlit/static/static/js/value.B4vHRSi7.js +1 -0
  261. streamlit/static/static/js/withCalculatedWidth.DcKeRSWJ.js +1 -0
  262. streamlit/static/static/js/withFullScreenWrapper.CrHddARq.js +1 -0
  263. streamlit/string_util.py +8 -1
  264. streamlit/testing/v1/app_test.py +15 -0
  265. streamlit/testing/v1/element_tree.py +62 -0
  266. streamlit/web/bootstrap.py +24 -0
  267. streamlit/web/server/oauth_authlib_routes.py +5 -2
  268. streamlit/web/server/upload_file_request_handler.py +16 -0
  269. {streamlit-1.51.0.dist-info → streamlit-1.52.0.dist-info}/METADATA +9 -5
  270. {streamlit-1.51.0.dist-info → streamlit-1.52.0.dist-info}/RECORD +274 -239
  271. streamlit/static/static/js/InputInstructions.jhH15PqV.js +0 -1
  272. streamlit/static/static/js/Particles.DUsputn1.js +0 -1
  273. streamlit/static/static/js/data-grid-overlay-editor.2Ufgxc6y.js +0 -1
  274. streamlit/static/static/js/index.B1ZQh4P1.js +0 -1
  275. streamlit/static/static/js/index.BKstZk0M.js +0 -27
  276. streamlit/static/static/js/index.BMcFsUee.js +0 -1
  277. streamlit/static/static/js/index.BR-IdcTb.js +0 -2
  278. streamlit/static/static/js/index.BgnZEMVh.js +0 -1
  279. streamlit/static/static/js/index.BohqXifI.js +0 -1
  280. streamlit/static/static/js/index.Br5nxKNj.js +0 -2
  281. streamlit/static/static/js/index.BrIKVbNc.js +0 -3
  282. streamlit/static/static/js/index.BtWUPzle.js +0 -1
  283. streamlit/static/static/js/index.C0RLraek.js +0 -1
  284. streamlit/static/static/js/index.CAIjskgG.js +0 -1
  285. streamlit/static/static/js/index.CAj-7vWz.js +0 -949
  286. streamlit/static/static/js/index.CMtEit2O.js +0 -1
  287. streamlit/static/static/js/index.CkRlykEE.js +0 -12
  288. streamlit/static/static/js/index.CmN3FXfI.js +0 -1617
  289. streamlit/static/static/js/index.CwbFI1_-.js +0 -1
  290. streamlit/static/static/js/index.D2KPNy7e.js +0 -1
  291. streamlit/static/static/js/index.DGAh7DMq.js +0 -1
  292. streamlit/static/static/js/index.DKb_NvmG.js +0 -197
  293. streamlit/static/static/js/index.DMqgUYKq.js +0 -1
  294. streamlit/static/static/js/index.DX1xY89g.js +0 -1
  295. streamlit/static/static/js/index.DYATBCsq.js +0 -2
  296. streamlit/static/static/js/index.DaSmGJ76.js +0 -3
  297. streamlit/static/static/js/index.Dd7bMeLP.js +0 -1
  298. streamlit/static/static/js/index.DjmmgI5U.js +0 -1
  299. streamlit/static/static/js/index.Dq56CyM2.js +0 -1
  300. streamlit/static/static/js/index.DuiXaS5_.js +0 -7
  301. streamlit/static/static/js/index.DvFidMLe.js +0 -2
  302. streamlit/static/static/js/index.DwkhC5Pc.js +0 -1
  303. streamlit/static/static/js/index.Q-3sFn1v.js +0 -1
  304. streamlit/static/static/js/index.QJ5QO9sJ.js +0 -1
  305. streamlit/static/static/js/index.VwTaeety.js +0 -1
  306. streamlit/static/static/js/index.YOqQbeX8.js +0 -1
  307. streamlit/static/static/js/number-overlay-editor.DRwAw1In.js +0 -9
  308. streamlit/static/static/js/uniqueId.oG4Gvj1v.js +0 -1
  309. streamlit/static/static/js/useUpdateUiValue.F2R3eTeR.js +0 -1
  310. streamlit/static/static/js/withFullScreenWrapper.zothJIsI.js +0 -1
  311. {streamlit-1.51.0.data → streamlit-1.52.0.data}/scripts/streamlit.cmd +0 -0
  312. {streamlit-1.51.0.dist-info → streamlit-1.52.0.dist-info}/WHEEL +0 -0
  313. {streamlit-1.51.0.dist-info → streamlit-1.52.0.dist-info}/entry_points.txt +0 -0
  314. {streamlit-1.51.0.dist-info → streamlit-1.52.0.dist-info}/top_level.txt +0 -0
@@ -65,7 +65,7 @@ GAUGE_HISTOGRAM: MetricType.ValueType # 6
65
65
  """Gauge histogram must use histogram value MetricPoint values."""
66
66
  SUMMARY: MetricType.ValueType # 7
67
67
  """Summary quantiles must use summary value MetricPoint values."""
68
- global___MetricType = MetricType
68
+ Global___MetricType: typing_extensions.TypeAlias = MetricType
69
69
 
70
70
  @typing.final
71
71
  class MetricSet(google.protobuf.message.Message):
@@ -75,17 +75,17 @@ class MetricSet(google.protobuf.message.Message):
75
75
 
76
76
  METRIC_FAMILIES_FIELD_NUMBER: builtins.int
77
77
  @property
78
- def metric_families(self) -> google.protobuf.internal.containers.RepeatedCompositeFieldContainer[global___MetricFamily]:
78
+ def metric_families(self) -> google.protobuf.internal.containers.RepeatedCompositeFieldContainer[Global___MetricFamily]:
79
79
  """Each MetricFamily has one or more MetricPoints for a single Metric."""
80
80
 
81
81
  def __init__(
82
82
  self,
83
83
  *,
84
- metric_families: collections.abc.Iterable[global___MetricFamily] | None = ...,
84
+ metric_families: collections.abc.Iterable[Global___MetricFamily] | None = ...,
85
85
  ) -> None: ...
86
86
  def ClearField(self, field_name: typing.Literal["metric_families", b"metric_families"]) -> None: ...
87
87
 
88
- global___MetricSet = MetricSet
88
+ Global___MetricSet: typing_extensions.TypeAlias = MetricSet
89
89
 
90
90
  @typing.final
91
91
  class MetricFamily(google.protobuf.message.Message):
@@ -102,28 +102,28 @@ class MetricFamily(google.protobuf.message.Message):
102
102
  METRICS_FIELD_NUMBER: builtins.int
103
103
  name: builtins.str
104
104
  """Required."""
105
- type: global___MetricType.ValueType
105
+ type: Global___MetricType.ValueType
106
106
  """Optional."""
107
107
  unit: builtins.str
108
108
  """Optional."""
109
109
  help: builtins.str
110
110
  """Optional."""
111
111
  @property
112
- def metrics(self) -> google.protobuf.internal.containers.RepeatedCompositeFieldContainer[global___Metric]:
112
+ def metrics(self) -> google.protobuf.internal.containers.RepeatedCompositeFieldContainer[Global___Metric]:
113
113
  """Optional."""
114
114
 
115
115
  def __init__(
116
116
  self,
117
117
  *,
118
118
  name: builtins.str = ...,
119
- type: global___MetricType.ValueType = ...,
119
+ type: Global___MetricType.ValueType = ...,
120
120
  unit: builtins.str = ...,
121
121
  help: builtins.str = ...,
122
- metrics: collections.abc.Iterable[global___Metric] | None = ...,
122
+ metrics: collections.abc.Iterable[Global___Metric] | None = ...,
123
123
  ) -> None: ...
124
124
  def ClearField(self, field_name: typing.Literal["help", b"help", "metrics", b"metrics", "name", b"name", "type", b"type", "unit", b"unit"]) -> None: ...
125
125
 
126
- global___MetricFamily = MetricFamily
126
+ Global___MetricFamily: typing_extensions.TypeAlias = MetricFamily
127
127
 
128
128
  @typing.final
129
129
  class Metric(google.protobuf.message.Message):
@@ -134,22 +134,22 @@ class Metric(google.protobuf.message.Message):
134
134
  LABELS_FIELD_NUMBER: builtins.int
135
135
  METRIC_POINTS_FIELD_NUMBER: builtins.int
136
136
  @property
137
- def labels(self) -> google.protobuf.internal.containers.RepeatedCompositeFieldContainer[global___Label]:
137
+ def labels(self) -> google.protobuf.internal.containers.RepeatedCompositeFieldContainer[Global___Label]:
138
138
  """Optional."""
139
139
 
140
140
  @property
141
- def metric_points(self) -> google.protobuf.internal.containers.RepeatedCompositeFieldContainer[global___MetricPoint]:
141
+ def metric_points(self) -> google.protobuf.internal.containers.RepeatedCompositeFieldContainer[Global___MetricPoint]:
142
142
  """Optional."""
143
143
 
144
144
  def __init__(
145
145
  self,
146
146
  *,
147
- labels: collections.abc.Iterable[global___Label] | None = ...,
148
- metric_points: collections.abc.Iterable[global___MetricPoint] | None = ...,
147
+ labels: collections.abc.Iterable[Global___Label] | None = ...,
148
+ metric_points: collections.abc.Iterable[Global___MetricPoint] | None = ...,
149
149
  ) -> None: ...
150
150
  def ClearField(self, field_name: typing.Literal["labels", b"labels", "metric_points", b"metric_points"]) -> None: ...
151
151
 
152
- global___Metric = Metric
152
+ Global___Metric: typing_extensions.TypeAlias = Metric
153
153
 
154
154
  @typing.final
155
155
  class Label(google.protobuf.message.Message):
@@ -173,7 +173,7 @@ class Label(google.protobuf.message.Message):
173
173
  ) -> None: ...
174
174
  def ClearField(self, field_name: typing.Literal["name", b"name", "value", b"value"]) -> None: ...
175
175
 
176
- global___Label = Label
176
+ Global___Label: typing_extensions.TypeAlias = Label
177
177
 
178
178
  @typing.final
179
179
  class MetricPoint(google.protobuf.message.Message):
@@ -190,19 +190,19 @@ class MetricPoint(google.protobuf.message.Message):
190
190
  SUMMARY_VALUE_FIELD_NUMBER: builtins.int
191
191
  TIMESTAMP_FIELD_NUMBER: builtins.int
192
192
  @property
193
- def unknown_value(self) -> global___UnknownValue: ...
193
+ def unknown_value(self) -> Global___UnknownValue: ...
194
194
  @property
195
- def gauge_value(self) -> global___GaugeValue: ...
195
+ def gauge_value(self) -> Global___GaugeValue: ...
196
196
  @property
197
- def counter_value(self) -> global___CounterValue: ...
197
+ def counter_value(self) -> Global___CounterValue: ...
198
198
  @property
199
- def histogram_value(self) -> global___HistogramValue: ...
199
+ def histogram_value(self) -> Global___HistogramValue: ...
200
200
  @property
201
- def state_set_value(self) -> global___StateSetValue: ...
201
+ def state_set_value(self) -> Global___StateSetValue: ...
202
202
  @property
203
- def info_value(self) -> global___InfoValue: ...
203
+ def info_value(self) -> Global___InfoValue: ...
204
204
  @property
205
- def summary_value(self) -> global___SummaryValue: ...
205
+ def summary_value(self) -> Global___SummaryValue: ...
206
206
  @property
207
207
  def timestamp(self) -> google.protobuf.timestamp_pb2.Timestamp:
208
208
  """Optional."""
@@ -210,20 +210,20 @@ class MetricPoint(google.protobuf.message.Message):
210
210
  def __init__(
211
211
  self,
212
212
  *,
213
- unknown_value: global___UnknownValue | None = ...,
214
- gauge_value: global___GaugeValue | None = ...,
215
- counter_value: global___CounterValue | None = ...,
216
- histogram_value: global___HistogramValue | None = ...,
217
- state_set_value: global___StateSetValue | None = ...,
218
- info_value: global___InfoValue | None = ...,
219
- summary_value: global___SummaryValue | None = ...,
213
+ unknown_value: Global___UnknownValue | None = ...,
214
+ gauge_value: Global___GaugeValue | None = ...,
215
+ counter_value: Global___CounterValue | None = ...,
216
+ histogram_value: Global___HistogramValue | None = ...,
217
+ state_set_value: Global___StateSetValue | None = ...,
218
+ info_value: Global___InfoValue | None = ...,
219
+ summary_value: Global___SummaryValue | None = ...,
220
220
  timestamp: google.protobuf.timestamp_pb2.Timestamp | None = ...,
221
221
  ) -> None: ...
222
222
  def HasField(self, field_name: typing.Literal["counter_value", b"counter_value", "gauge_value", b"gauge_value", "histogram_value", b"histogram_value", "info_value", b"info_value", "state_set_value", b"state_set_value", "summary_value", b"summary_value", "timestamp", b"timestamp", "unknown_value", b"unknown_value", "value", b"value"]) -> builtins.bool: ...
223
223
  def ClearField(self, field_name: typing.Literal["counter_value", b"counter_value", "gauge_value", b"gauge_value", "histogram_value", b"histogram_value", "info_value", b"info_value", "state_set_value", b"state_set_value", "summary_value", b"summary_value", "timestamp", b"timestamp", "unknown_value", b"unknown_value", "value", b"value"]) -> None: ...
224
224
  def WhichOneof(self, oneof_group: typing.Literal["value", b"value"]) -> typing.Literal["unknown_value", "gauge_value", "counter_value", "histogram_value", "state_set_value", "info_value", "summary_value"] | None: ...
225
225
 
226
- global___MetricPoint = MetricPoint
226
+ Global___MetricPoint: typing_extensions.TypeAlias = MetricPoint
227
227
 
228
228
  @typing.final
229
229
  class UnknownValue(google.protobuf.message.Message):
@@ -245,7 +245,7 @@ class UnknownValue(google.protobuf.message.Message):
245
245
  def ClearField(self, field_name: typing.Literal["double_value", b"double_value", "int_value", b"int_value", "value", b"value"]) -> None: ...
246
246
  def WhichOneof(self, oneof_group: typing.Literal["value", b"value"]) -> typing.Literal["double_value", "int_value"] | None: ...
247
247
 
248
- global___UnknownValue = UnknownValue
248
+ Global___UnknownValue: typing_extensions.TypeAlias = UnknownValue
249
249
 
250
250
  @typing.final
251
251
  class GaugeValue(google.protobuf.message.Message):
@@ -267,7 +267,7 @@ class GaugeValue(google.protobuf.message.Message):
267
267
  def ClearField(self, field_name: typing.Literal["double_value", b"double_value", "int_value", b"int_value", "value", b"value"]) -> None: ...
268
268
  def WhichOneof(self, oneof_group: typing.Literal["value", b"value"]) -> typing.Literal["double_value", "int_value"] | None: ...
269
269
 
270
- global___GaugeValue = GaugeValue
270
+ Global___GaugeValue: typing_extensions.TypeAlias = GaugeValue
271
271
 
272
272
  @typing.final
273
273
  class CounterValue(google.protobuf.message.Message):
@@ -288,7 +288,7 @@ class CounterValue(google.protobuf.message.Message):
288
288
  """
289
289
 
290
290
  @property
291
- def exemplar(self) -> global___Exemplar:
291
+ def exemplar(self) -> Global___Exemplar:
292
292
  """Optional."""
293
293
 
294
294
  def __init__(
@@ -297,13 +297,13 @@ class CounterValue(google.protobuf.message.Message):
297
297
  double_value: builtins.float = ...,
298
298
  int_value: builtins.int = ...,
299
299
  created: google.protobuf.timestamp_pb2.Timestamp | None = ...,
300
- exemplar: global___Exemplar | None = ...,
300
+ exemplar: Global___Exemplar | None = ...,
301
301
  ) -> None: ...
302
302
  def HasField(self, field_name: typing.Literal["created", b"created", "double_value", b"double_value", "exemplar", b"exemplar", "int_value", b"int_value", "total", b"total"]) -> builtins.bool: ...
303
303
  def ClearField(self, field_name: typing.Literal["created", b"created", "double_value", b"double_value", "exemplar", b"exemplar", "int_value", b"int_value", "total", b"total"]) -> None: ...
304
304
  def WhichOneof(self, oneof_group: typing.Literal["total", b"total"]) -> typing.Literal["double_value", "int_value"] | None: ...
305
305
 
306
- global___CounterValue = CounterValue
306
+ Global___CounterValue: typing_extensions.TypeAlias = CounterValue
307
307
 
308
308
  @typing.final
309
309
  class HistogramValue(google.protobuf.message.Message):
@@ -327,7 +327,7 @@ class HistogramValue(google.protobuf.message.Message):
327
327
  upper_bound: builtins.float
328
328
  """Optional."""
329
329
  @property
330
- def exemplar(self) -> global___Exemplar:
330
+ def exemplar(self) -> Global___Exemplar:
331
331
  """Optional."""
332
332
 
333
333
  def __init__(
@@ -335,7 +335,7 @@ class HistogramValue(google.protobuf.message.Message):
335
335
  *,
336
336
  count: builtins.int = ...,
337
337
  upper_bound: builtins.float = ...,
338
- exemplar: global___Exemplar | None = ...,
338
+ exemplar: Global___Exemplar | None = ...,
339
339
  ) -> None: ...
340
340
  def HasField(self, field_name: typing.Literal["exemplar", b"exemplar"]) -> builtins.bool: ...
341
341
  def ClearField(self, field_name: typing.Literal["count", b"count", "exemplar", b"exemplar", "upper_bound", b"upper_bound"]) -> None: ...
@@ -356,7 +356,7 @@ class HistogramValue(google.protobuf.message.Message):
356
356
  """
357
357
 
358
358
  @property
359
- def buckets(self) -> google.protobuf.internal.containers.RepeatedCompositeFieldContainer[global___HistogramValue.Bucket]:
359
+ def buckets(self) -> google.protobuf.internal.containers.RepeatedCompositeFieldContainer[Global___HistogramValue.Bucket]:
360
360
  """Optional."""
361
361
 
362
362
  def __init__(
@@ -366,13 +366,13 @@ class HistogramValue(google.protobuf.message.Message):
366
366
  int_value: builtins.int = ...,
367
367
  count: builtins.int = ...,
368
368
  created: google.protobuf.timestamp_pb2.Timestamp | None = ...,
369
- buckets: collections.abc.Iterable[global___HistogramValue.Bucket] | None = ...,
369
+ buckets: collections.abc.Iterable[Global___HistogramValue.Bucket] | None = ...,
370
370
  ) -> None: ...
371
371
  def HasField(self, field_name: typing.Literal["created", b"created", "double_value", b"double_value", "int_value", b"int_value", "sum", b"sum"]) -> builtins.bool: ...
372
372
  def ClearField(self, field_name: typing.Literal["buckets", b"buckets", "count", b"count", "created", b"created", "double_value", b"double_value", "int_value", b"int_value", "sum", b"sum"]) -> None: ...
373
373
  def WhichOneof(self, oneof_group: typing.Literal["sum", b"sum"]) -> typing.Literal["double_value", "int_value"] | None: ...
374
374
 
375
- global___HistogramValue = HistogramValue
375
+ Global___HistogramValue: typing_extensions.TypeAlias = HistogramValue
376
376
 
377
377
  @typing.final
378
378
  class Exemplar(google.protobuf.message.Message):
@@ -388,7 +388,7 @@ class Exemplar(google.protobuf.message.Message):
388
388
  """Optional."""
389
389
 
390
390
  @property
391
- def label(self) -> google.protobuf.internal.containers.RepeatedCompositeFieldContainer[global___Label]:
391
+ def label(self) -> google.protobuf.internal.containers.RepeatedCompositeFieldContainer[Global___Label]:
392
392
  """Labels are additional information about the exemplar value (e.g. trace id).
393
393
  Optional.
394
394
  """
@@ -398,12 +398,12 @@ class Exemplar(google.protobuf.message.Message):
398
398
  *,
399
399
  value: builtins.float = ...,
400
400
  timestamp: google.protobuf.timestamp_pb2.Timestamp | None = ...,
401
- label: collections.abc.Iterable[global___Label] | None = ...,
401
+ label: collections.abc.Iterable[Global___Label] | None = ...,
402
402
  ) -> None: ...
403
403
  def HasField(self, field_name: typing.Literal["timestamp", b"timestamp"]) -> builtins.bool: ...
404
404
  def ClearField(self, field_name: typing.Literal["label", b"label", "timestamp", b"timestamp", "value", b"value"]) -> None: ...
405
405
 
406
- global___Exemplar = Exemplar
406
+ Global___Exemplar: typing_extensions.TypeAlias = Exemplar
407
407
 
408
408
  @typing.final
409
409
  class StateSetValue(google.protobuf.message.Message):
@@ -431,17 +431,17 @@ class StateSetValue(google.protobuf.message.Message):
431
431
 
432
432
  STATES_FIELD_NUMBER: builtins.int
433
433
  @property
434
- def states(self) -> google.protobuf.internal.containers.RepeatedCompositeFieldContainer[global___StateSetValue.State]:
434
+ def states(self) -> google.protobuf.internal.containers.RepeatedCompositeFieldContainer[Global___StateSetValue.State]:
435
435
  """Optional."""
436
436
 
437
437
  def __init__(
438
438
  self,
439
439
  *,
440
- states: collections.abc.Iterable[global___StateSetValue.State] | None = ...,
440
+ states: collections.abc.Iterable[Global___StateSetValue.State] | None = ...,
441
441
  ) -> None: ...
442
442
  def ClearField(self, field_name: typing.Literal["states", b"states"]) -> None: ...
443
443
 
444
- global___StateSetValue = StateSetValue
444
+ Global___StateSetValue: typing_extensions.TypeAlias = StateSetValue
445
445
 
446
446
  @typing.final
447
447
  class InfoValue(google.protobuf.message.Message):
@@ -451,17 +451,17 @@ class InfoValue(google.protobuf.message.Message):
451
451
 
452
452
  INFO_FIELD_NUMBER: builtins.int
453
453
  @property
454
- def info(self) -> google.protobuf.internal.containers.RepeatedCompositeFieldContainer[global___Label]:
454
+ def info(self) -> google.protobuf.internal.containers.RepeatedCompositeFieldContainer[Global___Label]:
455
455
  """Optional."""
456
456
 
457
457
  def __init__(
458
458
  self,
459
459
  *,
460
- info: collections.abc.Iterable[global___Label] | None = ...,
460
+ info: collections.abc.Iterable[Global___Label] | None = ...,
461
461
  ) -> None: ...
462
462
  def ClearField(self, field_name: typing.Literal["info", b"info"]) -> None: ...
463
463
 
464
- global___InfoValue = InfoValue
464
+ Global___InfoValue: typing_extensions.TypeAlias = InfoValue
465
465
 
466
466
  @typing.final
467
467
  class SummaryValue(google.protobuf.message.Message):
@@ -503,7 +503,7 @@ class SummaryValue(google.protobuf.message.Message):
503
503
  """
504
504
 
505
505
  @property
506
- def quantile(self) -> google.protobuf.internal.containers.RepeatedCompositeFieldContainer[global___SummaryValue.Quantile]:
506
+ def quantile(self) -> google.protobuf.internal.containers.RepeatedCompositeFieldContainer[Global___SummaryValue.Quantile]:
507
507
  """Optional."""
508
508
 
509
509
  def __init__(
@@ -513,10 +513,10 @@ class SummaryValue(google.protobuf.message.Message):
513
513
  int_value: builtins.int = ...,
514
514
  count: builtins.int = ...,
515
515
  created: google.protobuf.timestamp_pb2.Timestamp | None = ...,
516
- quantile: collections.abc.Iterable[global___SummaryValue.Quantile] | None = ...,
516
+ quantile: collections.abc.Iterable[Global___SummaryValue.Quantile] | None = ...,
517
517
  ) -> None: ...
518
518
  def HasField(self, field_name: typing.Literal["created", b"created", "double_value", b"double_value", "int_value", b"int_value", "sum", b"sum"]) -> builtins.bool: ...
519
519
  def ClearField(self, field_name: typing.Literal["count", b"count", "created", b"created", "double_value", b"double_value", "int_value", b"int_value", "quantile", b"quantile", "sum", b"sum"]) -> None: ...
520
520
  def WhichOneof(self, oneof_group: typing.Literal["sum", b"sum"]) -> typing.Literal["double_value", "int_value"] | None: ...
521
521
 
522
- global___SummaryValue = SummaryValue
522
+ Global___SummaryValue: typing_extensions.TypeAlias = SummaryValue
@@ -53,7 +53,7 @@ from streamlit.watcher import LocalSourcesWatcher
53
53
  if TYPE_CHECKING:
54
54
  from collections.abc import Callable
55
55
 
56
- from streamlit.proto.BackMsg_pb2 import BackMsg
56
+ from streamlit.proto.BackMsg_pb2 import BackMsg, DeferredFileRequest
57
57
  from streamlit.runtime.script_data import ScriptData
58
58
  from streamlit.runtime.scriptrunner.script_cache import ScriptCache
59
59
  from streamlit.runtime.state import SessionState
@@ -304,6 +304,15 @@ class AppSession:
304
304
  self._handle_stop_script_request()
305
305
  elif msg_type == "file_urls_request":
306
306
  self._handle_file_urls_request(msg.file_urls_request)
307
+ elif msg_type == "deferred_file_request":
308
+ # Execute deferred callable in a separate thread to avoid blocking
309
+ # the main event loop. Use create_task to run the async handler.
310
+ # Store task reference to prevent garbage collection.
311
+ task = asyncio.create_task(
312
+ self._handle_deferred_file_request(msg.deferred_file_request)
313
+ )
314
+ # Add task name for better debugging
315
+ task.set_name(f"deferred_file_{msg.deferred_file_request.file_id}")
307
316
  else:
308
317
  _LOGGER.warning('No handler for "%s"', msg_type)
309
318
 
@@ -922,6 +931,34 @@ class AppSession:
922
931
 
923
932
  self._enqueue_forward_msg(msg)
924
933
 
934
+ async def _handle_deferred_file_request(self, request: DeferredFileRequest) -> None:
935
+ """Handle a deferred_file_request BackMsg sent by the client.
936
+
937
+ Execute the deferred callable in a separate thread and send the URL back
938
+ to the frontend. This prevents blocking the main event loop if the callable
939
+ is slow.
940
+ """
941
+ response = ForwardMsg()
942
+ response.deferred_file_response.file_id = request.file_id
943
+
944
+ try:
945
+ # Execute the deferred callable in a separate thread to avoid blocking
946
+ # the main event loop. This is critical for shared apps where a slow
947
+ # callable could freeze all sessions.
948
+ url = await asyncio.to_thread(
949
+ runtime.get_instance().media_file_mgr.execute_deferred,
950
+ request.file_id,
951
+ )
952
+ response.deferred_file_response.url = url
953
+ except Exception as e:
954
+ # Send error response if callable execution fails
955
+ _LOGGER.exception(
956
+ "Error executing deferred callable for file_id %s", request.file_id
957
+ )
958
+ response.deferred_file_response.error_msg = str(e)
959
+
960
+ self._enqueue_forward_msg(response)
961
+
925
962
  def _populate_app_pages(
926
963
  self, msg: NewSession, pages: dict[PageHash, PageInfo]
927
964
  ) -> None:
@@ -372,7 +372,7 @@ class CacheDataAPI:
372
372
  hash_funcs: HashFuncsDict | None = None,
373
373
  ) -> CachedFunc[P, R] | Callable[[Callable[P, R]], CachedFunc[P, R]]:
374
374
  return self._decorator(
375
- func,
375
+ func, # ty: ignore[invalid-argument-type]
376
376
  ttl=ttl,
377
377
  max_entries=max_entries,
378
378
  persist=persist,
@@ -247,8 +247,8 @@ class CacheResourceAPI:
247
247
  validate: ValidateFunc | None = None,
248
248
  hash_funcs: HashFuncsDict | None = None,
249
249
  ) -> CachedFunc[P, R] | Callable[[Callable[P, R]], CachedFunc[P, R]]:
250
- return self._decorator(
251
- func,
250
+ return self._decorator( # ty: ignore
251
+ func, # ty: ignore[invalid-argument-type]
252
252
  ttl=ttl,
253
253
  max_entries=max_entries,
254
254
  show_spinner=show_spinner,
@@ -219,7 +219,7 @@ class CachedFunc(Generic[P, R]): # ty: ignore[invalid-argument-type]
219
219
  if isinstance(self._info.show_spinner, str):
220
220
  spinner_message = self._info.show_spinner
221
221
  elif self._info.show_spinner is True:
222
- name = self._info.func.__qualname__
222
+ name = cast("types.FunctionType", self._info.func).__qualname__
223
223
  if len(args) == 0 and len(kwargs) == 0:
224
224
  spinner_message = f"Running `{name}()`."
225
225
  else:
@@ -418,7 +418,7 @@ class _CacheFuncHasher:
418
418
  if type_util.is_type(obj, "pandas.core.series.Series"):
419
419
  from pandas.util import hash_pandas_object
420
420
 
421
- series_obj: pd.Series = cast("pd.Series", obj)
421
+ series_obj = cast("pd.Series[Any]", obj)
422
422
  self.update(h, series_obj.size)
423
423
  self.update(h, series_obj.dtype.name)
424
424
 
@@ -0,0 +1,53 @@
1
+ # Copyright (c) Streamlit Inc. (2018-2022) Snowflake Inc. (2022-2025)
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+
15
+ from __future__ import annotations
16
+
17
+ import io
18
+
19
+
20
+ def convert_data_to_bytes_and_infer_mime(
21
+ data: object, unsupported_error: Exception
22
+ ) -> tuple[bytes, str]:
23
+ # Convert data to bytes and infer mimetype if needed
24
+ data_as_bytes: bytes
25
+ inferred_mime_type: str
26
+
27
+ if isinstance(data, str):
28
+ data_as_bytes = data.encode()
29
+ inferred_mime_type = "text/plain"
30
+ elif isinstance(data, io.TextIOWrapper):
31
+ string_data = data.read()
32
+ data_as_bytes = string_data.encode()
33
+ inferred_mime_type = "text/plain"
34
+ # Assume bytes; try methods until we run out.
35
+ elif isinstance(data, bytes):
36
+ data_as_bytes = data
37
+ inferred_mime_type = "application/octet-stream"
38
+ elif isinstance(data, io.BytesIO):
39
+ data.seek(0)
40
+ data_as_bytes = data.getvalue()
41
+ inferred_mime_type = "application/octet-stream"
42
+ elif isinstance(data, io.BufferedReader):
43
+ data.seek(0)
44
+ data_as_bytes = data.read()
45
+ inferred_mime_type = "application/octet-stream"
46
+ elif isinstance(data, io.RawIOBase):
47
+ data.seek(0)
48
+ data_as_bytes = data.read() or b""
49
+ inferred_mime_type = "application/octet-stream"
50
+ else:
51
+ raise unsupported_error
52
+
53
+ return data_as_bytes, inferred_mime_type
@@ -137,6 +137,7 @@ class ForwardMsgQueue:
137
137
  "script_finished",
138
138
  "session_status_changed",
139
139
  "parent_message",
140
+ "page_info_changed",
140
141
  }
141
142
  or (
142
143
  # preserve all messages if this is a fragment rerun and...