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.
Files changed (563) hide show
  1. streamlit/__init__.py +306 -0
  2. streamlit/__main__.py +20 -0
  3. streamlit/auth_util.py +218 -0
  4. streamlit/cli_util.py +105 -0
  5. streamlit/column_config.py +56 -0
  6. streamlit/commands/__init__.py +13 -0
  7. streamlit/commands/echo.py +126 -0
  8. streamlit/commands/execution_control.py +238 -0
  9. streamlit/commands/experimental_query_params.py +169 -0
  10. streamlit/commands/logo.py +189 -0
  11. streamlit/commands/navigation.py +385 -0
  12. streamlit/commands/page_config.py +311 -0
  13. streamlit/components/__init__.py +13 -0
  14. streamlit/components/lib/__init__.py +13 -0
  15. streamlit/components/lib/local_component_registry.py +84 -0
  16. streamlit/components/types/__init__.py +13 -0
  17. streamlit/components/types/base_component_registry.py +99 -0
  18. streamlit/components/types/base_custom_component.py +150 -0
  19. streamlit/components/v1/__init__.py +31 -0
  20. streamlit/components/v1/component_arrow.py +141 -0
  21. streamlit/components/v1/component_registry.py +130 -0
  22. streamlit/components/v1/components.py +38 -0
  23. streamlit/components/v1/custom_component.py +243 -0
  24. streamlit/config.py +1513 -0
  25. streamlit/config_option.py +311 -0
  26. streamlit/config_util.py +177 -0
  27. streamlit/connections/__init__.py +28 -0
  28. streamlit/connections/base_connection.py +174 -0
  29. streamlit/connections/snowflake_connection.py +562 -0
  30. streamlit/connections/snowpark_connection.py +213 -0
  31. streamlit/connections/sql_connection.py +425 -0
  32. streamlit/connections/util.py +97 -0
  33. streamlit/cursor.py +210 -0
  34. streamlit/dataframe_util.py +1416 -0
  35. streamlit/delta_generator.py +602 -0
  36. streamlit/delta_generator_singletons.py +204 -0
  37. streamlit/deprecation_util.py +209 -0
  38. streamlit/development.py +21 -0
  39. streamlit/elements/__init__.py +13 -0
  40. streamlit/elements/alert.py +234 -0
  41. streamlit/elements/arrow.py +962 -0
  42. streamlit/elements/balloons.py +47 -0
  43. streamlit/elements/bokeh_chart.py +133 -0
  44. streamlit/elements/code.py +114 -0
  45. streamlit/elements/deck_gl_json_chart.py +546 -0
  46. streamlit/elements/dialog_decorator.py +267 -0
  47. streamlit/elements/doc_string.py +558 -0
  48. streamlit/elements/empty.py +130 -0
  49. streamlit/elements/exception.py +331 -0
  50. streamlit/elements/form.py +354 -0
  51. streamlit/elements/graphviz_chart.py +150 -0
  52. streamlit/elements/heading.py +302 -0
  53. streamlit/elements/html.py +105 -0
  54. streamlit/elements/iframe.py +191 -0
  55. streamlit/elements/image.py +196 -0
  56. streamlit/elements/json.py +139 -0
  57. streamlit/elements/layouts.py +879 -0
  58. streamlit/elements/lib/__init__.py +13 -0
  59. streamlit/elements/lib/built_in_chart_utils.py +1157 -0
  60. streamlit/elements/lib/color_util.py +263 -0
  61. streamlit/elements/lib/column_config_utils.py +542 -0
  62. streamlit/elements/lib/column_types.py +2188 -0
  63. streamlit/elements/lib/dialog.py +147 -0
  64. streamlit/elements/lib/dicttools.py +154 -0
  65. streamlit/elements/lib/event_utils.py +37 -0
  66. streamlit/elements/lib/file_uploader_utils.py +66 -0
  67. streamlit/elements/lib/form_utils.py +77 -0
  68. streamlit/elements/lib/image_utils.py +441 -0
  69. streamlit/elements/lib/js_number.py +105 -0
  70. streamlit/elements/lib/mutable_status_container.py +183 -0
  71. streamlit/elements/lib/options_selector_utils.py +250 -0
  72. streamlit/elements/lib/pandas_styler_utils.py +274 -0
  73. streamlit/elements/lib/policies.py +194 -0
  74. streamlit/elements/lib/streamlit_plotly_theme.py +207 -0
  75. streamlit/elements/lib/subtitle_utils.py +176 -0
  76. streamlit/elements/lib/utils.py +250 -0
  77. streamlit/elements/map.py +508 -0
  78. streamlit/elements/markdown.py +277 -0
  79. streamlit/elements/media.py +793 -0
  80. streamlit/elements/metric.py +301 -0
  81. streamlit/elements/plotly_chart.py +546 -0
  82. streamlit/elements/progress.py +156 -0
  83. streamlit/elements/pyplot.py +194 -0
  84. streamlit/elements/snow.py +47 -0
  85. streamlit/elements/spinner.py +113 -0
  86. streamlit/elements/text.py +76 -0
  87. streamlit/elements/toast.py +98 -0
  88. streamlit/elements/vega_charts.py +1984 -0
  89. streamlit/elements/widgets/__init__.py +13 -0
  90. streamlit/elements/widgets/audio_input.py +310 -0
  91. streamlit/elements/widgets/button.py +1123 -0
  92. streamlit/elements/widgets/button_group.py +1008 -0
  93. streamlit/elements/widgets/camera_input.py +263 -0
  94. streamlit/elements/widgets/chat.py +647 -0
  95. streamlit/elements/widgets/checkbox.py +352 -0
  96. streamlit/elements/widgets/color_picker.py +265 -0
  97. streamlit/elements/widgets/data_editor.py +983 -0
  98. streamlit/elements/widgets/file_uploader.py +486 -0
  99. streamlit/elements/widgets/multiselect.py +338 -0
  100. streamlit/elements/widgets/number_input.py +545 -0
  101. streamlit/elements/widgets/radio.py +407 -0
  102. streamlit/elements/widgets/select_slider.py +437 -0
  103. streamlit/elements/widgets/selectbox.py +366 -0
  104. streamlit/elements/widgets/slider.py +880 -0
  105. streamlit/elements/widgets/text_widgets.py +628 -0
  106. streamlit/elements/widgets/time_widgets.py +970 -0
  107. streamlit/elements/write.py +574 -0
  108. streamlit/emojis.py +34 -0
  109. streamlit/env_util.py +61 -0
  110. streamlit/error_util.py +105 -0
  111. streamlit/errors.py +452 -0
  112. streamlit/external/__init__.py +13 -0
  113. streamlit/external/langchain/__init__.py +23 -0
  114. streamlit/external/langchain/streamlit_callback_handler.py +406 -0
  115. streamlit/file_util.py +247 -0
  116. streamlit/git_util.py +173 -0
  117. streamlit/hello/__init__.py +13 -0
  118. streamlit/hello/animation_demo.py +82 -0
  119. streamlit/hello/dataframe_demo.py +71 -0
  120. streamlit/hello/hello.py +37 -0
  121. streamlit/hello/mapping_demo.py +114 -0
  122. streamlit/hello/plotting_demo.py +55 -0
  123. streamlit/hello/streamlit_app.py +55 -0
  124. streamlit/hello/utils.py +28 -0
  125. streamlit/logger.py +130 -0
  126. streamlit/material_icon_names.py +25 -0
  127. streamlit/navigation/__init__.py +13 -0
  128. streamlit/navigation/page.py +302 -0
  129. streamlit/net_util.py +125 -0
  130. streamlit/platform.py +33 -0
  131. streamlit/proto/Alert_pb2.py +29 -0
  132. streamlit/proto/Alert_pb2.pyi +90 -0
  133. streamlit/proto/AppPage_pb2.py +27 -0
  134. streamlit/proto/AppPage_pb2.pyi +64 -0
  135. streamlit/proto/ArrowNamedDataSet_pb2.py +28 -0
  136. streamlit/proto/ArrowNamedDataSet_pb2.pyi +57 -0
  137. streamlit/proto/ArrowVegaLiteChart_pb2.py +29 -0
  138. streamlit/proto/ArrowVegaLiteChart_pb2.pyi +84 -0
  139. streamlit/proto/Arrow_pb2.py +33 -0
  140. streamlit/proto/Arrow_pb2.pyi +188 -0
  141. streamlit/proto/AudioInput_pb2.py +28 -0
  142. streamlit/proto/AudioInput_pb2.pyi +58 -0
  143. streamlit/proto/Audio_pb2.py +27 -0
  144. streamlit/proto/Audio_pb2.pyi +58 -0
  145. streamlit/proto/AuthRedirect_pb2.py +27 -0
  146. streamlit/proto/AuthRedirect_pb2.pyi +41 -0
  147. streamlit/proto/AutoRerun_pb2.py +27 -0
  148. streamlit/proto/AutoRerun_pb2.pyi +45 -0
  149. streamlit/proto/BackMsg_pb2.py +29 -0
  150. streamlit/proto/BackMsg_pb2.pyi +105 -0
  151. streamlit/proto/Balloons_pb2.py +27 -0
  152. streamlit/proto/Balloons_pb2.pyi +43 -0
  153. streamlit/proto/Block_pb2.py +53 -0
  154. streamlit/proto/Block_pb2.pyi +322 -0
  155. streamlit/proto/BokehChart_pb2.py +27 -0
  156. streamlit/proto/BokehChart_pb2.pyi +49 -0
  157. streamlit/proto/ButtonGroup_pb2.py +36 -0
  158. streamlit/proto/ButtonGroup_pb2.pyi +169 -0
  159. streamlit/proto/Button_pb2.py +27 -0
  160. streamlit/proto/Button_pb2.pyi +71 -0
  161. streamlit/proto/CameraInput_pb2.py +28 -0
  162. streamlit/proto/CameraInput_pb2.pyi +58 -0
  163. streamlit/proto/ChatInput_pb2.py +31 -0
  164. streamlit/proto/ChatInput_pb2.pyi +111 -0
  165. streamlit/proto/Checkbox_pb2.py +30 -0
  166. streamlit/proto/Checkbox_pb2.pyi +90 -0
  167. streamlit/proto/ClientState_pb2.py +30 -0
  168. streamlit/proto/ClientState_pb2.pyi +90 -0
  169. streamlit/proto/Code_pb2.py +27 -0
  170. streamlit/proto/Code_pb2.pyi +55 -0
  171. streamlit/proto/ColorPicker_pb2.py +28 -0
  172. streamlit/proto/ColorPicker_pb2.pyi +67 -0
  173. streamlit/proto/Common_pb2.py +51 -0
  174. streamlit/proto/Common_pb2.pyi +293 -0
  175. streamlit/proto/Components_pb2.py +35 -0
  176. streamlit/proto/Components_pb2.pyi +172 -0
  177. streamlit/proto/DataFrame_pb2.py +56 -0
  178. streamlit/proto/DataFrame_pb2.pyi +397 -0
  179. streamlit/proto/DateInput_pb2.py +28 -0
  180. streamlit/proto/DateInput_pb2.pyi +83 -0
  181. streamlit/proto/DeckGlJsonChart_pb2.py +29 -0
  182. streamlit/proto/DeckGlJsonChart_pb2.pyi +102 -0
  183. streamlit/proto/Delta_pb2.py +31 -0
  184. streamlit/proto/Delta_pb2.pyi +74 -0
  185. streamlit/proto/DocString_pb2.py +29 -0
  186. streamlit/proto/DocString_pb2.pyi +93 -0
  187. streamlit/proto/DownloadButton_pb2.py +27 -0
  188. streamlit/proto/DownloadButton_pb2.pyi +70 -0
  189. streamlit/proto/Element_pb2.py +78 -0
  190. streamlit/proto/Element_pb2.pyi +312 -0
  191. streamlit/proto/Empty_pb2.py +27 -0
  192. streamlit/proto/Empty_pb2.pyi +36 -0
  193. streamlit/proto/Exception_pb2.py +27 -0
  194. streamlit/proto/Exception_pb2.pyi +72 -0
  195. streamlit/proto/Favicon_pb2.py +27 -0
  196. streamlit/proto/Favicon_pb2.pyi +40 -0
  197. streamlit/proto/FileUploader_pb2.py +28 -0
  198. streamlit/proto/FileUploader_pb2.pyi +78 -0
  199. streamlit/proto/ForwardMsg_pb2.py +53 -0
  200. streamlit/proto/ForwardMsg_pb2.pyi +293 -0
  201. streamlit/proto/GitInfo_pb2.py +29 -0
  202. streamlit/proto/GitInfo_pb2.pyi +83 -0
  203. streamlit/proto/GraphVizChart_pb2.py +27 -0
  204. streamlit/proto/GraphVizChart_pb2.pyi +53 -0
  205. streamlit/proto/Heading_pb2.py +27 -0
  206. streamlit/proto/Heading_pb2.pyi +56 -0
  207. streamlit/proto/Html_pb2.py +27 -0
  208. streamlit/proto/Html_pb2.pyi +42 -0
  209. streamlit/proto/IFrame_pb2.py +27 -0
  210. streamlit/proto/IFrame_pb2.pyi +59 -0
  211. streamlit/proto/Image_pb2.py +29 -0
  212. streamlit/proto/Image_pb2.pyi +84 -0
  213. streamlit/proto/Json_pb2.py +27 -0
  214. streamlit/proto/Json_pb2.pyi +53 -0
  215. streamlit/proto/LabelVisibilityMessage_pb2.py +29 -0
  216. streamlit/proto/LabelVisibilityMessage_pb2.pyi +68 -0
  217. streamlit/proto/LinkButton_pb2.py +27 -0
  218. streamlit/proto/LinkButton_pb2.pyi +58 -0
  219. streamlit/proto/Logo_pb2.py +27 -0
  220. streamlit/proto/Logo_pb2.pyi +51 -0
  221. streamlit/proto/Markdown_pb2.py +29 -0
  222. streamlit/proto/Markdown_pb2.pyi +86 -0
  223. streamlit/proto/Metric_pb2.py +32 -0
  224. streamlit/proto/Metric_pb2.pyi +101 -0
  225. streamlit/proto/MetricsEvent_pb2.py +30 -0
  226. streamlit/proto/MetricsEvent_pb2.pyi +200 -0
  227. streamlit/proto/MultiSelect_pb2.py +28 -0
  228. streamlit/proto/MultiSelect_pb2.pyi +81 -0
  229. streamlit/proto/NamedDataSet_pb2.py +28 -0
  230. streamlit/proto/NamedDataSet_pb2.pyi +59 -0
  231. streamlit/proto/Navigation_pb2.py +30 -0
  232. streamlit/proto/Navigation_pb2.pyi +84 -0
  233. streamlit/proto/NewSession_pb2.py +51 -0
  234. streamlit/proto/NewSession_pb2.pyi +481 -0
  235. streamlit/proto/NumberInput_pb2.py +30 -0
  236. streamlit/proto/NumberInput_pb2.pyi +121 -0
  237. streamlit/proto/PageConfig_pb2.py +33 -0
  238. streamlit/proto/PageConfig_pb2.pyi +126 -0
  239. streamlit/proto/PageInfo_pb2.py +27 -0
  240. streamlit/proto/PageInfo_pb2.pyi +43 -0
  241. streamlit/proto/PageLink_pb2.py +27 -0
  242. streamlit/proto/PageLink_pb2.pyi +63 -0
  243. streamlit/proto/PageNotFound_pb2.py +27 -0
  244. streamlit/proto/PageNotFound_pb2.pyi +42 -0
  245. streamlit/proto/PageProfile_pb2.py +31 -0
  246. streamlit/proto/PageProfile_pb2.pyi +127 -0
  247. streamlit/proto/PagesChanged_pb2.py +28 -0
  248. streamlit/proto/PagesChanged_pb2.pyi +48 -0
  249. streamlit/proto/ParentMessage_pb2.py +27 -0
  250. streamlit/proto/ParentMessage_pb2.pyi +46 -0
  251. streamlit/proto/PlotlyChart_pb2.py +31 -0
  252. streamlit/proto/PlotlyChart_pb2.pyi +131 -0
  253. streamlit/proto/Progress_pb2.py +27 -0
  254. streamlit/proto/Progress_pb2.pyi +43 -0
  255. streamlit/proto/Radio_pb2.py +28 -0
  256. streamlit/proto/Radio_pb2.pyi +84 -0
  257. streamlit/proto/RootContainer_pb2.py +27 -0
  258. streamlit/proto/RootContainer_pb2.pyi +56 -0
  259. streamlit/proto/Selectbox_pb2.py +28 -0
  260. streamlit/proto/Selectbox_pb2.pyi +80 -0
  261. streamlit/proto/SessionEvent_pb2.py +28 -0
  262. streamlit/proto/SessionEvent_pb2.pyi +62 -0
  263. streamlit/proto/SessionStatus_pb2.py +27 -0
  264. streamlit/proto/SessionStatus_pb2.pyi +57 -0
  265. streamlit/proto/Skeleton_pb2.py +29 -0
  266. streamlit/proto/Skeleton_pb2.pyi +71 -0
  267. streamlit/proto/Slider_pb2.py +32 -0
  268. streamlit/proto/Slider_pb2.pyi +142 -0
  269. streamlit/proto/Snow_pb2.py +27 -0
  270. streamlit/proto/Snow_pb2.pyi +43 -0
  271. streamlit/proto/Spinner_pb2.py +27 -0
  272. streamlit/proto/Spinner_pb2.pyi +49 -0
  273. streamlit/proto/TextArea_pb2.py +28 -0
  274. streamlit/proto/TextArea_pb2.pyi +80 -0
  275. streamlit/proto/TextInput_pb2.py +30 -0
  276. streamlit/proto/TextInput_pb2.pyi +107 -0
  277. streamlit/proto/Text_pb2.py +27 -0
  278. streamlit/proto/Text_pb2.pyi +46 -0
  279. streamlit/proto/TimeInput_pb2.py +28 -0
  280. streamlit/proto/TimeInput_pb2.pyi +74 -0
  281. streamlit/proto/Toast_pb2.py +27 -0
  282. streamlit/proto/Toast_pb2.pyi +45 -0
  283. streamlit/proto/VegaLiteChart_pb2.py +29 -0
  284. streamlit/proto/VegaLiteChart_pb2.pyi +71 -0
  285. streamlit/proto/Video_pb2.py +31 -0
  286. streamlit/proto/Video_pb2.pyi +117 -0
  287. streamlit/proto/WidgetStates_pb2.py +31 -0
  288. streamlit/proto/WidgetStates_pb2.pyi +126 -0
  289. streamlit/proto/__init__.py +15 -0
  290. streamlit/proto/openmetrics_data_model_pb2.py +60 -0
  291. streamlit/proto/openmetrics_data_model_pb2.pyi +522 -0
  292. streamlit/py.typed +0 -0
  293. streamlit/runtime/__init__.py +50 -0
  294. streamlit/runtime/app_session.py +982 -0
  295. streamlit/runtime/caching/__init__.py +98 -0
  296. streamlit/runtime/caching/cache_data_api.py +665 -0
  297. streamlit/runtime/caching/cache_errors.py +142 -0
  298. streamlit/runtime/caching/cache_resource_api.py +527 -0
  299. streamlit/runtime/caching/cache_type.py +33 -0
  300. streamlit/runtime/caching/cache_utils.py +523 -0
  301. streamlit/runtime/caching/cached_message_replay.py +290 -0
  302. streamlit/runtime/caching/hashing.py +637 -0
  303. streamlit/runtime/caching/legacy_cache_api.py +169 -0
  304. streamlit/runtime/caching/storage/__init__.py +29 -0
  305. streamlit/runtime/caching/storage/cache_storage_protocol.py +239 -0
  306. streamlit/runtime/caching/storage/dummy_cache_storage.py +60 -0
  307. streamlit/runtime/caching/storage/in_memory_cache_storage_wrapper.py +145 -0
  308. streamlit/runtime/caching/storage/local_disk_cache_storage.py +223 -0
  309. streamlit/runtime/connection_factory.py +436 -0
  310. streamlit/runtime/context.py +280 -0
  311. streamlit/runtime/credentials.py +364 -0
  312. streamlit/runtime/forward_msg_cache.py +296 -0
  313. streamlit/runtime/forward_msg_queue.py +240 -0
  314. streamlit/runtime/fragment.py +477 -0
  315. streamlit/runtime/media_file_manager.py +234 -0
  316. streamlit/runtime/media_file_storage.py +143 -0
  317. streamlit/runtime/memory_media_file_storage.py +181 -0
  318. streamlit/runtime/memory_session_storage.py +77 -0
  319. streamlit/runtime/memory_uploaded_file_manager.py +138 -0
  320. streamlit/runtime/metrics_util.py +486 -0
  321. streamlit/runtime/pages_manager.py +165 -0
  322. streamlit/runtime/runtime.py +792 -0
  323. streamlit/runtime/runtime_util.py +106 -0
  324. streamlit/runtime/script_data.py +46 -0
  325. streamlit/runtime/scriptrunner/__init__.py +38 -0
  326. streamlit/runtime/scriptrunner/exec_code.py +159 -0
  327. streamlit/runtime/scriptrunner/magic.py +273 -0
  328. streamlit/runtime/scriptrunner/magic_funcs.py +32 -0
  329. streamlit/runtime/scriptrunner/script_cache.py +89 -0
  330. streamlit/runtime/scriptrunner/script_runner.py +756 -0
  331. streamlit/runtime/scriptrunner_utils/__init__.py +19 -0
  332. streamlit/runtime/scriptrunner_utils/exceptions.py +48 -0
  333. streamlit/runtime/scriptrunner_utils/script_requests.py +307 -0
  334. streamlit/runtime/scriptrunner_utils/script_run_context.py +287 -0
  335. streamlit/runtime/secrets.py +534 -0
  336. streamlit/runtime/session_manager.py +394 -0
  337. streamlit/runtime/state/__init__.py +41 -0
  338. streamlit/runtime/state/common.py +191 -0
  339. streamlit/runtime/state/query_params.py +205 -0
  340. streamlit/runtime/state/query_params_proxy.py +218 -0
  341. streamlit/runtime/state/safe_session_state.py +138 -0
  342. streamlit/runtime/state/session_state.py +772 -0
  343. streamlit/runtime/state/session_state_proxy.py +153 -0
  344. streamlit/runtime/state/widgets.py +135 -0
  345. streamlit/runtime/stats.py +109 -0
  346. streamlit/runtime/uploaded_file_manager.py +148 -0
  347. streamlit/runtime/websocket_session_manager.py +167 -0
  348. streamlit/source_util.py +98 -0
  349. streamlit/static/favicon.png +0 -0
  350. streamlit/static/index.html +61 -0
  351. streamlit/static/static/css/index.Bmkmz40k.css +1 -0
  352. streamlit/static/static/css/index.DpJG_94W.css +1 -0
  353. streamlit/static/static/css/index.DzuxGC_t.css +1 -0
  354. streamlit/static/static/js/FileDownload.esm.Bp9m5jrx.js +1 -0
  355. streamlit/static/static/js/FileHelper.D_3pbilj.js +5 -0
  356. streamlit/static/static/js/FormClearHelper.Ct2rwLXo.js +1 -0
  357. streamlit/static/static/js/Hooks.BKdzj5MJ.js +1 -0
  358. streamlit/static/static/js/InputInstructions.DB3QGNJP.js +1 -0
  359. streamlit/static/static/js/ProgressBar.D40A5xc2.js +2 -0
  360. streamlit/static/static/js/RenderInPortalIfExists.DLUCooTN.js +1 -0
  361. streamlit/static/static/js/Toolbar.BiGGIQun.js +1 -0
  362. streamlit/static/static/js/UploadFileInfo.C-jY39rj.js +1 -0
  363. streamlit/static/static/js/base-input.CQBQT24M.js +4 -0
  364. streamlit/static/static/js/checkbox.Buj8gd_M.js +9 -0
  365. streamlit/static/static/js/createDownloadLinkElement.DZMwyjvU.js +1 -0
  366. streamlit/static/static/js/createSuper.CesK3I23.js +1 -0
  367. streamlit/static/static/js/data-grid-overlay-editor.B69OOFM4.js +1 -0
  368. streamlit/static/static/js/downloader.BZQhlBNT.js +1 -0
  369. streamlit/static/static/js/es6.D9Zhqujy.js +2 -0
  370. streamlit/static/static/js/iframeResizer.contentWindow.CAzcBpCC.js +1 -0
  371. streamlit/static/static/js/index.08vcOOvb.js +1 -0
  372. streamlit/static/static/js/index.0uqKfJUS.js +1 -0
  373. streamlit/static/static/js/index.B02M5u69.js +203 -0
  374. streamlit/static/static/js/index.B7mcZKMx.js +1 -0
  375. streamlit/static/static/js/index.BAQDHFA_.js +1 -0
  376. streamlit/static/static/js/index.BI60cMVr.js +2 -0
  377. streamlit/static/static/js/index.BLug2inK.js +1 -0
  378. streamlit/static/static/js/index.BM6TMY8g.js +2 -0
  379. streamlit/static/static/js/index.BZ9p1t7G.js +1 -0
  380. streamlit/static/static/js/index.BZqa87a1.js +2 -0
  381. streamlit/static/static/js/index.BcsRUzZZ.js +1 -0
  382. streamlit/static/static/js/index.BgVMiY_P.js +197 -0
  383. streamlit/static/static/js/index.BtuGy7By.js +6 -0
  384. streamlit/static/static/js/index.BuDuBmrs.js +1 -0
  385. streamlit/static/static/js/index.BvXU2oKV.js +1 -0
  386. streamlit/static/static/js/index.BxcwPacT.js +73 -0
  387. streamlit/static/static/js/index.CWX8KB81.js +1 -0
  388. streamlit/static/static/js/index.CXzZTo_q.js +1 -0
  389. streamlit/static/static/js/index.CcRWp_KL.js +1 -0
  390. streamlit/static/static/js/index.Cd-_xe55.js +3 -0
  391. streamlit/static/static/js/index.CdG2PXln.js +4537 -0
  392. streamlit/static/static/js/index.CjXvXmcP.js +1 -0
  393. streamlit/static/static/js/index.D1HZENZx.js +776 -0
  394. streamlit/static/static/js/index.D21Efo64.js +1617 -0
  395. streamlit/static/static/js/index.D9WgGVBx.js +7 -0
  396. streamlit/static/static/js/index.DEcsHtvb.js +12 -0
  397. streamlit/static/static/js/index.DFeMfr_K.js +1 -0
  398. streamlit/static/static/js/index.DHFBoItz.js +1 -0
  399. streamlit/static/static/js/index.D_PrBKnJ.js +3 -0
  400. streamlit/static/static/js/index.DmuRkekN.js +3855 -0
  401. streamlit/static/static/js/index.Do6eY8sf.js +1 -0
  402. streamlit/static/static/js/index.Dz3lP2P-.js +1 -0
  403. streamlit/static/static/js/index.Dz_UqF-s.js +1 -0
  404. streamlit/static/static/js/index.GkSUsPhJ.js +1 -0
  405. streamlit/static/static/js/index.H1U1IC_d.js +3 -0
  406. streamlit/static/static/js/index.g6p_4DPr.js +1 -0
  407. streamlit/static/static/js/index.g9x_GKss.js +1 -0
  408. streamlit/static/static/js/index.zo9jm08y.js +1 -0
  409. streamlit/static/static/js/input.DnaFglHq.js +2 -0
  410. streamlit/static/static/js/inputUtils.CQWz5UKz.js +1 -0
  411. streamlit/static/static/js/memory.Crb9x4-F.js +1 -0
  412. streamlit/static/static/js/mergeWith.ouAz0sK3.js +1 -0
  413. streamlit/static/static/js/number-overlay-editor._UaN-O48.js +9 -0
  414. streamlit/static/static/js/possibleConstructorReturn.CtGjGFHz.js +1 -0
  415. streamlit/static/static/js/sandbox.CBybYOhV.js +1 -0
  416. streamlit/static/static/js/sprintf.D7DtBTRn.js +1 -0
  417. streamlit/static/static/js/textarea.Cb_uJt5U.js +2 -0
  418. streamlit/static/static/js/threshold.DjX0wlsa.js +1 -0
  419. streamlit/static/static/js/timepicker.DKT7pfoF.js +4 -0
  420. streamlit/static/static/js/timer.CAwTRJ_g.js +1 -0
  421. streamlit/static/static/js/toConsumableArray.05Ikp13-.js +3 -0
  422. streamlit/static/static/js/uniqueId.D2FMWUEI.js +1 -0
  423. streamlit/static/static/js/useBasicWidgetState.urnZLANY.js +1 -0
  424. streamlit/static/static/js/useOnInputChange.BOKIIdJ1.js +1 -0
  425. streamlit/static/static/js/value.CgPGBV_l.js +1 -0
  426. streamlit/static/static/js/withFullScreenWrapper.C_N8J0Xx.js +1 -0
  427. streamlit/static/static/media/KaTeX_AMS-Regular.BQhdFMY1.woff2 +0 -0
  428. streamlit/static/static/media/KaTeX_AMS-Regular.DMm9YOAa.woff +0 -0
  429. streamlit/static/static/media/KaTeX_AMS-Regular.DRggAlZN.ttf +0 -0
  430. streamlit/static/static/media/KaTeX_Caligraphic-Bold.ATXxdsX0.ttf +0 -0
  431. streamlit/static/static/media/KaTeX_Caligraphic-Bold.BEiXGLvX.woff +0 -0
  432. streamlit/static/static/media/KaTeX_Caligraphic-Bold.Dq_IR9rO.woff2 +0 -0
  433. streamlit/static/static/media/KaTeX_Caligraphic-Regular.CTRA-rTL.woff +0 -0
  434. streamlit/static/static/media/KaTeX_Caligraphic-Regular.Di6jR-x-.woff2 +0 -0
  435. streamlit/static/static/media/KaTeX_Caligraphic-Regular.wX97UBjC.ttf +0 -0
  436. streamlit/static/static/media/KaTeX_Fraktur-Bold.BdnERNNW.ttf +0 -0
  437. streamlit/static/static/media/KaTeX_Fraktur-Bold.BsDP51OF.woff +0 -0
  438. streamlit/static/static/media/KaTeX_Fraktur-Bold.CL6g_b3V.woff2 +0 -0
  439. streamlit/static/static/media/KaTeX_Fraktur-Regular.CB_wures.ttf +0 -0
  440. streamlit/static/static/media/KaTeX_Fraktur-Regular.CTYiF6lA.woff2 +0 -0
  441. streamlit/static/static/media/KaTeX_Fraktur-Regular.Dxdc4cR9.woff +0 -0
  442. streamlit/static/static/media/KaTeX_Main-Bold.Cx986IdX.woff2 +0 -0
  443. streamlit/static/static/media/KaTeX_Main-Bold.Jm3AIy58.woff +0 -0
  444. streamlit/static/static/media/KaTeX_Main-Bold.waoOVXN0.ttf +0 -0
  445. streamlit/static/static/media/KaTeX_Main-BoldItalic.DxDJ3AOS.woff2 +0 -0
  446. streamlit/static/static/media/KaTeX_Main-BoldItalic.DzxPMmG6.ttf +0 -0
  447. streamlit/static/static/media/KaTeX_Main-BoldItalic.SpSLRI95.woff +0 -0
  448. streamlit/static/static/media/KaTeX_Main-Italic.3WenGoN9.ttf +0 -0
  449. streamlit/static/static/media/KaTeX_Main-Italic.BMLOBm91.woff +0 -0
  450. streamlit/static/static/media/KaTeX_Main-Italic.NWA7e6Wa.woff2 +0 -0
  451. streamlit/static/static/media/KaTeX_Main-Regular.B22Nviop.woff2 +0 -0
  452. streamlit/static/static/media/KaTeX_Main-Regular.Dr94JaBh.woff +0 -0
  453. streamlit/static/static/media/KaTeX_Main-Regular.ypZvNtVU.ttf +0 -0
  454. streamlit/static/static/media/KaTeX_Math-BoldItalic.B3XSjfu4.ttf +0 -0
  455. streamlit/static/static/media/KaTeX_Math-BoldItalic.CZnvNsCZ.woff2 +0 -0
  456. streamlit/static/static/media/KaTeX_Math-BoldItalic.iY-2wyZ7.woff +0 -0
  457. streamlit/static/static/media/KaTeX_Math-Italic.DA0__PXp.woff +0 -0
  458. streamlit/static/static/media/KaTeX_Math-Italic.flOr_0UB.ttf +0 -0
  459. streamlit/static/static/media/KaTeX_Math-Italic.t53AETM-.woff2 +0 -0
  460. streamlit/static/static/media/KaTeX_SansSerif-Bold.CFMepnvq.ttf +0 -0
  461. streamlit/static/static/media/KaTeX_SansSerif-Bold.D1sUS0GD.woff2 +0 -0
  462. streamlit/static/static/media/KaTeX_SansSerif-Bold.DbIhKOiC.woff +0 -0
  463. streamlit/static/static/media/KaTeX_SansSerif-Italic.C3H0VqGB.woff2 +0 -0
  464. streamlit/static/static/media/KaTeX_SansSerif-Italic.DN2j7dab.woff +0 -0
  465. streamlit/static/static/media/KaTeX_SansSerif-Italic.YYjJ1zSn.ttf +0 -0
  466. streamlit/static/static/media/KaTeX_SansSerif-Regular.BNo7hRIc.ttf +0 -0
  467. streamlit/static/static/media/KaTeX_SansSerif-Regular.CS6fqUqJ.woff +0 -0
  468. streamlit/static/static/media/KaTeX_SansSerif-Regular.DDBCnlJ7.woff2 +0 -0
  469. streamlit/static/static/media/KaTeX_Script-Regular.C5JkGWo-.ttf +0 -0
  470. streamlit/static/static/media/KaTeX_Script-Regular.D3wIWfF6.woff2 +0 -0
  471. streamlit/static/static/media/KaTeX_Script-Regular.D5yQViql.woff +0 -0
  472. streamlit/static/static/media/KaTeX_Size1-Regular.C195tn64.woff +0 -0
  473. streamlit/static/static/media/KaTeX_Size1-Regular.Dbsnue_I.ttf +0 -0
  474. streamlit/static/static/media/KaTeX_Size1-Regular.mCD8mA8B.woff2 +0 -0
  475. streamlit/static/static/media/KaTeX_Size2-Regular.B7gKUWhC.ttf +0 -0
  476. streamlit/static/static/media/KaTeX_Size2-Regular.Dy4dx90m.woff2 +0 -0
  477. streamlit/static/static/media/KaTeX_Size2-Regular.oD1tc_U0.woff +0 -0
  478. streamlit/static/static/media/KaTeX_Size3-Regular.CTq5MqoE.woff +0 -0
  479. streamlit/static/static/media/KaTeX_Size3-Regular.DgpXs0kz.ttf +0 -0
  480. streamlit/static/static/media/KaTeX_Size4-Regular.BF-4gkZK.woff +0 -0
  481. streamlit/static/static/media/KaTeX_Size4-Regular.DWFBv043.ttf +0 -0
  482. streamlit/static/static/media/KaTeX_Size4-Regular.Dl5lxZxV.woff2 +0 -0
  483. streamlit/static/static/media/KaTeX_Typewriter-Regular.C0xS9mPB.woff +0 -0
  484. streamlit/static/static/media/KaTeX_Typewriter-Regular.CO6r4hn1.woff2 +0 -0
  485. streamlit/static/static/media/KaTeX_Typewriter-Regular.D3Ib7_Hf.ttf +0 -0
  486. streamlit/static/static/media/MaterialSymbols-Rounded.DcZbplWk.woff2 +0 -0
  487. streamlit/static/static/media/SourceCodePro-Bold.CFEfr7-q.woff2 +0 -0
  488. streamlit/static/static/media/SourceCodePro-BoldItalic.C-LkFXxa.woff2 +0 -0
  489. streamlit/static/static/media/SourceCodePro-Italic.CxFOx7N-.woff2 +0 -0
  490. streamlit/static/static/media/SourceCodePro-Regular.CBOlD63d.woff2 +0 -0
  491. streamlit/static/static/media/SourceCodePro-SemiBold.CFHwW3Wd.woff2 +0 -0
  492. streamlit/static/static/media/SourceCodePro-SemiBoldItalic.Cg2yRu82.woff2 +0 -0
  493. streamlit/static/static/media/SourceSansPro-Bold.-6c9oR8J.woff2 +0 -0
  494. streamlit/static/static/media/SourceSansPro-BoldItalic.DmM_grLY.woff2 +0 -0
  495. streamlit/static/static/media/SourceSansPro-Italic.I1ipWe7Q.woff2 +0 -0
  496. streamlit/static/static/media/SourceSansPro-Regular.DZLUzqI4.woff2 +0 -0
  497. streamlit/static/static/media/SourceSansPro-SemiBold.sKQIyTMz.woff2 +0 -0
  498. streamlit/static/static/media/SourceSansPro-SemiBoldItalic.C0wP0icr.woff2 +0 -0
  499. streamlit/static/static/media/SourceSerifPro-Bold.8TUnKj4x.woff2 +0 -0
  500. streamlit/static/static/media/SourceSerifPro-BoldItalic.CBVO7Ve7.woff2 +0 -0
  501. streamlit/static/static/media/SourceSerifPro-Italic.DkFgL2HZ.woff2 +0 -0
  502. streamlit/static/static/media/SourceSerifPro-Regular.CNJNET2S.woff2 +0 -0
  503. streamlit/static/static/media/SourceSerifPro-SemiBold.CHyh9GC5.woff2 +0 -0
  504. streamlit/static/static/media/SourceSerifPro-SemiBoldItalic.CBtz8sWN.woff2 +0 -0
  505. streamlit/static/static/media/balloon-0.Czj7AKwE.png +0 -0
  506. streamlit/static/static/media/balloon-1.CNvFFrND.png +0 -0
  507. streamlit/static/static/media/balloon-2.DTvC6B1t.png +0 -0
  508. streamlit/static/static/media/balloon-3.CgSk4tbL.png +0 -0
  509. streamlit/static/static/media/balloon-4.mbtFrzxf.png +0 -0
  510. streamlit/static/static/media/balloon-5.CSwkUfRA.png +0 -0
  511. streamlit/static/static/media/fireworks.B4d-_KUe.gif +0 -0
  512. streamlit/static/static/media/flake-0.DgWaVvm5.png +0 -0
  513. streamlit/static/static/media/flake-1.B2r5AHMK.png +0 -0
  514. streamlit/static/static/media/flake-2.BnWSExPC.png +0 -0
  515. streamlit/static/static/media/snowflake.JU2jBHL8.svg +11 -0
  516. streamlit/string_util.py +203 -0
  517. streamlit/temporary_directory.py +56 -0
  518. streamlit/testing/__init__.py +13 -0
  519. streamlit/testing/v1/__init__.py +17 -0
  520. streamlit/testing/v1/app_test.py +1050 -0
  521. streamlit/testing/v1/element_tree.py +2083 -0
  522. streamlit/testing/v1/local_script_runner.py +180 -0
  523. streamlit/testing/v1/util.py +53 -0
  524. streamlit/time_util.py +75 -0
  525. streamlit/type_util.py +460 -0
  526. streamlit/url_util.py +122 -0
  527. streamlit/user_info.py +519 -0
  528. streamlit/util.py +72 -0
  529. streamlit/vendor/__init__.py +0 -0
  530. streamlit/vendor/pympler/__init__.py +0 -0
  531. streamlit/vendor/pympler/asizeof.py +2869 -0
  532. streamlit/version.py +18 -0
  533. streamlit/watcher/__init__.py +28 -0
  534. streamlit/watcher/event_based_path_watcher.py +406 -0
  535. streamlit/watcher/folder_black_list.py +82 -0
  536. streamlit/watcher/local_sources_watcher.py +233 -0
  537. streamlit/watcher/path_watcher.py +185 -0
  538. streamlit/watcher/polling_path_watcher.py +124 -0
  539. streamlit/watcher/util.py +207 -0
  540. streamlit/web/__init__.py +13 -0
  541. streamlit/web/bootstrap.py +353 -0
  542. streamlit/web/cache_storage_manager_config.py +38 -0
  543. streamlit/web/cli.py +369 -0
  544. streamlit/web/server/__init__.py +26 -0
  545. streamlit/web/server/app_static_file_handler.py +93 -0
  546. streamlit/web/server/authlib_tornado_integration.py +60 -0
  547. streamlit/web/server/browser_websocket_handler.py +246 -0
  548. streamlit/web/server/component_request_handler.py +116 -0
  549. streamlit/web/server/media_file_handler.py +141 -0
  550. streamlit/web/server/oauth_authlib_routes.py +176 -0
  551. streamlit/web/server/oidc_mixin.py +108 -0
  552. streamlit/web/server/routes.py +295 -0
  553. streamlit/web/server/server.py +479 -0
  554. streamlit/web/server/server_util.py +161 -0
  555. streamlit/web/server/stats_request_handler.py +95 -0
  556. streamlit/web/server/upload_file_request_handler.py +137 -0
  557. streamlit/web/server/websocket_headers.py +56 -0
  558. streamlit_nightly-1.43.2.dev20250307.data/scripts/streamlit.cmd +16 -0
  559. streamlit_nightly-1.43.2.dev20250307.dist-info/METADATA +207 -0
  560. streamlit_nightly-1.43.2.dev20250307.dist-info/RECORD +563 -0
  561. streamlit_nightly-1.43.2.dev20250307.dist-info/WHEEL +5 -0
  562. streamlit_nightly-1.43.2.dev20250307.dist-info/entry_points.txt +2 -0
  563. streamlit_nightly-1.43.2.dev20250307.dist-info/top_level.txt +1 -0
@@ -0,0 +1,756 @@
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 gc
18
+ import sys
19
+ import threading
20
+ import types
21
+ from contextlib import contextmanager
22
+ from enum import Enum
23
+ from timeit import default_timer as timer
24
+ from typing import TYPE_CHECKING, Callable, Final, Literal, cast
25
+
26
+ from blinker import Signal
27
+
28
+ from streamlit import config, runtime, util
29
+ from streamlit.errors import FragmentStorageKeyError
30
+ from streamlit.logger import get_logger
31
+ from streamlit.proto.ClientState_pb2 import ClientState
32
+ from streamlit.proto.ForwardMsg_pb2 import ForwardMsg
33
+ from streamlit.runtime.metrics_util import (
34
+ create_page_profile_message,
35
+ to_microseconds,
36
+ )
37
+ from streamlit.runtime.pages_manager import PagesManager
38
+ from streamlit.runtime.scriptrunner.exec_code import (
39
+ exec_func_with_error_handling,
40
+ modified_sys_path,
41
+ )
42
+ from streamlit.runtime.scriptrunner.script_cache import ScriptCache
43
+ from streamlit.runtime.scriptrunner_utils.exceptions import (
44
+ RerunException,
45
+ StopException,
46
+ )
47
+ from streamlit.runtime.scriptrunner_utils.script_requests import (
48
+ RerunData,
49
+ ScriptRequests,
50
+ ScriptRequestType,
51
+ )
52
+ from streamlit.runtime.scriptrunner_utils.script_run_context import (
53
+ ScriptRunContext,
54
+ add_script_run_ctx,
55
+ get_script_run_ctx,
56
+ )
57
+ from streamlit.runtime.state import (
58
+ SCRIPT_RUN_WITHOUT_ERRORS_KEY,
59
+ SafeSessionState,
60
+ SessionState,
61
+ )
62
+ from streamlit.source_util import page_sort_key
63
+
64
+ if TYPE_CHECKING:
65
+ from streamlit.runtime.fragment import FragmentStorage
66
+ from streamlit.runtime.scriptrunner.script_cache import ScriptCache
67
+ from streamlit.runtime.uploaded_file_manager import UploadedFileManager
68
+
69
+ _LOGGER: Final = get_logger(__name__)
70
+
71
+
72
+ class ScriptRunnerEvent(Enum):
73
+ # "Control" events. These are emitted when the ScriptRunner's state changes.
74
+
75
+ # The script started running.
76
+ SCRIPT_STARTED = "SCRIPT_STARTED"
77
+
78
+ # The script run stopped because of a compile error.
79
+ SCRIPT_STOPPED_WITH_COMPILE_ERROR = "SCRIPT_STOPPED_WITH_COMPILE_ERROR"
80
+
81
+ # The script run stopped because it ran to completion, or was
82
+ # interrupted by the user.
83
+ SCRIPT_STOPPED_WITH_SUCCESS = "SCRIPT_STOPPED_WITH_SUCCESS"
84
+
85
+ # The script run stopped in order to start a script run with newer widget state.
86
+ SCRIPT_STOPPED_FOR_RERUN = "SCRIPT_STOPPED_FOR_RERUN"
87
+
88
+ # The script run corresponding to a fragment ran to completion, or was interrupted
89
+ # by the user.
90
+ FRAGMENT_STOPPED_WITH_SUCCESS = "FRAGMENT_STOPPED_WITH_SUCCESS"
91
+
92
+ # The ScriptRunner is done processing the ScriptEventQueue and
93
+ # is shut down.
94
+ SHUTDOWN = "SHUTDOWN"
95
+
96
+ # "Data" events. These are emitted when the ScriptRunner's script has
97
+ # data to send to the frontend.
98
+
99
+ # The script has a ForwardMsg to send to the frontend.
100
+ ENQUEUE_FORWARD_MSG = "ENQUEUE_FORWARD_MSG"
101
+
102
+
103
+ """
104
+ Note [Threading]
105
+ There are two kinds of threads in Streamlit, the main thread and script threads.
106
+ The main thread is started by invoking the Streamlit CLI, and bootstraps the
107
+ framework and runs the Tornado webserver.
108
+ A script thread is created by a ScriptRunner when it starts. The script thread
109
+ is where the ScriptRunner executes, including running the user script itself,
110
+ processing messages to/from the frontend, and all the Streamlit library function
111
+ calls in the user script.
112
+ It is possible for the user script to spawn its own threads, which could call
113
+ Streamlit functions. We restrict the ScriptRunner's execution control to the
114
+ script thread. Calling Streamlit functions from other threads is unlikely to
115
+ work correctly due to lack of ScriptRunContext, so we may add a guard against
116
+ it in the future.
117
+ """
118
+
119
+
120
+ # For projects that have a pages folder, we assume that this is a script that
121
+ # is designed to leverage our original v1 version of multi-page apps. This
122
+ # function will be called to run the script in lieu of the main script. This
123
+ # function simulates the v1 setup using the modern v2 commands (st.navigation)
124
+ def _mpa_v1(main_script_path: str):
125
+ from pathlib import Path
126
+
127
+ from streamlit.commands.navigation import PageType, _navigation
128
+ from streamlit.navigation.page import StreamlitPage
129
+
130
+ # Select the folder that should be used for the pages:
131
+ MAIN_SCRIPT_PATH = Path(main_script_path).resolve()
132
+ PAGES_FOLDER = MAIN_SCRIPT_PATH.parent / "pages"
133
+
134
+ # Read out the my_pages folder and create a page for every script:
135
+ pages = PAGES_FOLDER.glob("*.py")
136
+ pages = sorted(
137
+ [page for page in pages if page.name.endswith(".py")], key=page_sort_key
138
+ )
139
+
140
+ # Use this script as the main page and
141
+ main_page = StreamlitPage(MAIN_SCRIPT_PATH, default=True)
142
+ all_pages = [main_page] + [
143
+ StreamlitPage(PAGES_FOLDER / page.name) for page in pages
144
+ ]
145
+ # Initialize the navigation with all the pages:
146
+ position: Literal["sidebar", "hidden"] = (
147
+ "hidden"
148
+ if config.get_option("client.showSidebarNavigation") is False
149
+ else "sidebar"
150
+ )
151
+ page = _navigation(
152
+ cast(list[PageType], all_pages),
153
+ position=position,
154
+ expanded=False,
155
+ )
156
+
157
+ if page._page != main_page._page:
158
+ # Only run the page if it is not pointing to this script:
159
+ page.run()
160
+ # Finish the script execution here to only run the selected page
161
+ raise StopException()
162
+
163
+
164
+ class ScriptRunner:
165
+ def __init__(
166
+ self,
167
+ session_id: str,
168
+ main_script_path: str,
169
+ session_state: SessionState,
170
+ uploaded_file_mgr: UploadedFileManager,
171
+ script_cache: ScriptCache,
172
+ initial_rerun_data: RerunData,
173
+ user_info: dict[str, str | bool | None],
174
+ fragment_storage: FragmentStorage,
175
+ pages_manager: PagesManager,
176
+ ):
177
+ """Initialize the ScriptRunner.
178
+
179
+ (The ScriptRunner won't start executing until start() is called.)
180
+
181
+ Parameters
182
+ ----------
183
+ session_id
184
+ The AppSession's id.
185
+
186
+ main_script_path
187
+ Path to our main app script.
188
+
189
+ session_state
190
+ The AppSession's SessionState instance.
191
+
192
+ uploaded_file_mgr
193
+ The File manager to store the data uploaded by the file_uploader widget.
194
+
195
+ script_cache
196
+ A ScriptCache instance.
197
+
198
+ initial_rerun_data
199
+ RerunData to initialize this ScriptRunner with.
200
+
201
+ user_info
202
+ A dict that contains information about the current user. For now,
203
+ it only contains the user's email address.
204
+
205
+ {
206
+ "email": "example@example.com"
207
+ }
208
+
209
+ Information about the current user is optionally provided when a
210
+ websocket connection is initialized via the "X-Streamlit-User" header.
211
+
212
+ fragment_storage
213
+ The AppSession's FragmentStorage instance.
214
+ """
215
+ self._session_id = session_id
216
+ self._main_script_path = main_script_path
217
+ self._session_state = SafeSessionState(
218
+ session_state, yield_callback=self._maybe_handle_execution_control_request
219
+ )
220
+ self._uploaded_file_mgr = uploaded_file_mgr
221
+ self._script_cache = script_cache
222
+ self._user_info = user_info
223
+ self._fragment_storage = fragment_storage
224
+
225
+ self._pages_manager = pages_manager
226
+ self._requests = ScriptRequests()
227
+ self._requests.request_rerun(initial_rerun_data)
228
+
229
+ self.on_event = Signal(
230
+ doc="""Emitted when a ScriptRunnerEvent occurs.
231
+
232
+ This signal is generally emitted on the ScriptRunner's script
233
+ thread (which is *not* the same thread that the ScriptRunner was
234
+ created on).
235
+
236
+ Parameters
237
+ ----------
238
+ sender: ScriptRunner
239
+ The sender of the event (this ScriptRunner).
240
+
241
+ event : ScriptRunnerEvent
242
+
243
+ forward_msg : ForwardMsg | None
244
+ The ForwardMsg to send to the frontend. Set only for the
245
+ ENQUEUE_FORWARD_MSG event.
246
+
247
+ exception : BaseException | None
248
+ Our compile error. Set only for the
249
+ SCRIPT_STOPPED_WITH_COMPILE_ERROR event.
250
+
251
+ widget_states : streamlit.proto.WidgetStates_pb2.WidgetStates | None
252
+ The ScriptRunner's final WidgetStates. Set only for the
253
+ SHUTDOWN event.
254
+ """
255
+ )
256
+
257
+ # Set to true while we're executing. Used by
258
+ # _maybe_handle_execution_control_request.
259
+ self._execing = False
260
+
261
+ # This is initialized in start()
262
+ self._script_thread: threading.Thread | None = None
263
+
264
+ def __repr__(self) -> str:
265
+ return util.repr_(self)
266
+
267
+ def request_stop(self) -> None:
268
+ """Request that the ScriptRunner stop running its script and
269
+ shut down. The ScriptRunner will handle this request when it reaches
270
+ an interrupt point.
271
+
272
+ Safe to call from any thread.
273
+ """
274
+ self._requests.request_stop()
275
+
276
+ def request_rerun(self, rerun_data: RerunData) -> bool:
277
+ """Request that the ScriptRunner interrupt its currently-running
278
+ script and restart it.
279
+
280
+ If the ScriptRunner has been stopped, this request can't be honored:
281
+ return False.
282
+
283
+ Otherwise, record the request and return True. The ScriptRunner will
284
+ handle the rerun request as soon as it reaches an interrupt point.
285
+
286
+ Safe to call from any thread.
287
+ """
288
+ return self._requests.request_rerun(rerun_data)
289
+
290
+ def start(self) -> None:
291
+ """Start a new thread to process the ScriptEventQueue.
292
+
293
+ This must be called only once.
294
+
295
+ """
296
+ if self._script_thread is not None:
297
+ raise Exception("ScriptRunner was already started")
298
+
299
+ self._script_thread = threading.Thread(
300
+ target=self._run_script_thread,
301
+ name="ScriptRunner.scriptThread",
302
+ )
303
+ self._script_thread.start()
304
+
305
+ def _get_script_run_ctx(self) -> ScriptRunContext:
306
+ """Get the ScriptRunContext for the current thread.
307
+
308
+ Returns
309
+ -------
310
+ ScriptRunContext
311
+ The ScriptRunContext for the current thread.
312
+
313
+ Raises
314
+ ------
315
+ AssertionError
316
+ If called outside of a ScriptRunner thread.
317
+ RuntimeError
318
+ If there is no ScriptRunContext for the current thread.
319
+
320
+ """
321
+ assert self._is_in_script_thread()
322
+
323
+ ctx = get_script_run_ctx()
324
+ if ctx is None:
325
+ # This should never be possible on the script_runner thread.
326
+ raise RuntimeError(
327
+ "ScriptRunner thread has a null ScriptRunContext. "
328
+ "Something has gone very wrong!"
329
+ )
330
+ return ctx
331
+
332
+ def _run_script_thread(self) -> None:
333
+ """The entry point for the script thread.
334
+
335
+ Processes the ScriptRequestQueue, which will at least contain the RERUN
336
+ request that will trigger the first script-run.
337
+
338
+ When the ScriptRequestQueue is empty, or when a SHUTDOWN request is
339
+ dequeued, this function will exit and its thread will terminate.
340
+ """
341
+ assert self._is_in_script_thread()
342
+
343
+ _LOGGER.debug("Beginning script thread")
344
+
345
+ # Create and attach the thread's ScriptRunContext
346
+ ctx = ScriptRunContext(
347
+ session_id=self._session_id,
348
+ _enqueue=self._enqueue_forward_msg,
349
+ script_requests=self._requests,
350
+ query_string="",
351
+ session_state=self._session_state,
352
+ uploaded_file_mgr=self._uploaded_file_mgr,
353
+ main_script_path=self._main_script_path,
354
+ user_info=self._user_info,
355
+ gather_usage_stats=bool(config.get_option("browser.gatherUsageStats")),
356
+ fragment_storage=self._fragment_storage,
357
+ pages_manager=self._pages_manager,
358
+ context_info=None,
359
+ )
360
+ add_script_run_ctx(threading.current_thread(), ctx)
361
+
362
+ request = self._requests.on_scriptrunner_ready()
363
+ while request.type == ScriptRequestType.RERUN:
364
+ # When the script thread starts, we'll have a pending rerun
365
+ # request that we'll handle immediately. When the script finishes,
366
+ # it's possible that another request has come in that we need to
367
+ # handle, which is why we call _run_script in a loop.
368
+ self._run_script(request.rerun_data)
369
+ request = self._requests.on_scriptrunner_ready()
370
+
371
+ assert request.type == ScriptRequestType.STOP
372
+
373
+ # Send a SHUTDOWN event before exiting, so some state can be saved
374
+ # for use in a future script run when not triggered by the client.
375
+ client_state = ClientState()
376
+ client_state.query_string = ctx.query_string
377
+ client_state.page_script_hash = ctx.page_script_hash
378
+ self.on_event.send(
379
+ self, event=ScriptRunnerEvent.SHUTDOWN, client_state=client_state
380
+ )
381
+
382
+ def _is_in_script_thread(self) -> bool:
383
+ """True if the calling function is running in the script thread"""
384
+ return self._script_thread == threading.current_thread()
385
+
386
+ def _enqueue_forward_msg(self, msg: ForwardMsg) -> None:
387
+ """Enqueue a ForwardMsg to our browser queue.
388
+ This private function is called by ScriptRunContext only.
389
+
390
+ It may be called from the script thread OR the main thread.
391
+ """
392
+ # Whenever we enqueue a ForwardMsg, we also handle any pending
393
+ # execution control request. This means that a script can be
394
+ # cleanly interrupted and stopped inside most `st.foo` calls.
395
+ self._maybe_handle_execution_control_request()
396
+
397
+ # Pass the message to our associated AppSession.
398
+ self.on_event.send(
399
+ self, event=ScriptRunnerEvent.ENQUEUE_FORWARD_MSG, forward_msg=msg
400
+ )
401
+
402
+ def _maybe_handle_execution_control_request(self) -> None:
403
+ """Check our current ScriptRequestState to see if we have a
404
+ pending STOP or RERUN request.
405
+
406
+ This function is called every time the app script enqueues a
407
+ ForwardMsg, which means that most `st.foo` commands - which generally
408
+ involve sending a ForwardMsg to the frontend - act as implicit
409
+ yield points in the script's execution.
410
+ """
411
+ if not self._is_in_script_thread():
412
+ # We can only handle execution_control_request if we're on the
413
+ # script execution thread. However, it's possible for deltas to
414
+ # be enqueued (and, therefore, for this function to be called)
415
+ # in separate threads, so we check for that here.
416
+ return
417
+
418
+ if not self._execing:
419
+ # If the _execing flag is not set, we're not actually inside
420
+ # an exec() call. This happens when our script exec() completes,
421
+ # we change our state to STOPPED, and a statechange-listener
422
+ # enqueues a new ForwardEvent
423
+ return
424
+
425
+ request = self._requests.on_scriptrunner_yield()
426
+ if request is None:
427
+ # No RERUN or STOP request.
428
+ return
429
+
430
+ if request.type == ScriptRequestType.RERUN:
431
+ raise RerunException(request.rerun_data)
432
+
433
+ assert request.type == ScriptRequestType.STOP
434
+ raise StopException()
435
+
436
+ @contextmanager
437
+ def _set_execing_flag(self):
438
+ """A context for setting the ScriptRunner._execing flag.
439
+
440
+ Used by _maybe_handle_execution_control_request to ensure that
441
+ we only handle requests while we're inside an exec() call
442
+ """
443
+ if self._execing:
444
+ raise RuntimeError("Nested set_execing_flag call")
445
+ self._execing = True
446
+ try:
447
+ yield
448
+ finally:
449
+ self._execing = False
450
+
451
+ def _run_script(self, rerun_data: RerunData) -> None:
452
+ """Run our script.
453
+
454
+ Parameters
455
+ ----------
456
+ rerun_data: RerunData
457
+ The RerunData to use.
458
+
459
+ """
460
+
461
+ assert self._is_in_script_thread()
462
+
463
+ # An explicit loop instead of recursion to avoid stack overflows
464
+ while True:
465
+ _LOGGER.debug("Running script %s", rerun_data)
466
+ start_time: float = timer()
467
+ prep_time: float = 0 # This will be overwritten once preparations are done.
468
+
469
+ if not rerun_data.fragment_id_queue:
470
+ # Don't clear session refs for media files if we're running a fragment.
471
+ # Otherwise, we're likely to remove files that still have corresponding
472
+ # download buttons/links to them present in the app, which will result
473
+ # in a 404 should the user click on them.
474
+ runtime.get_instance().media_file_mgr.clear_session_refs()
475
+
476
+ self._pages_manager.set_script_intent(
477
+ rerun_data.page_script_hash, rerun_data.page_name
478
+ )
479
+ active_script = self._pages_manager.get_initial_active_script(
480
+ rerun_data.page_script_hash, rerun_data.page_name
481
+ )
482
+ main_page_info = self._pages_manager.get_main_page()
483
+
484
+ page_script_hash = (
485
+ active_script["page_script_hash"]
486
+ if active_script is not None
487
+ else main_page_info["page_script_hash"]
488
+ )
489
+
490
+ ctx = self._get_script_run_ctx()
491
+ # Clear widget state on page change. This normally happens implicitly
492
+ # in the script run cleanup steps, but doing it explicitly ensures
493
+ # it happens even if a script run was interrupted.
494
+ previous_page_script_hash = ctx.page_script_hash
495
+ if previous_page_script_hash != page_script_hash:
496
+ # Page changed, enforce reset widget state where possible.
497
+ # This enforcement matters when a new script thread is started
498
+ # before the previous script run is completed (from user
499
+ # interaction). Use the widget ids from the rerun data to
500
+ # maintain some widget state, as the rerun data should
501
+ # contain the latest widget ids from the frontend.
502
+ widget_ids: set[str] = set()
503
+
504
+ if (
505
+ rerun_data.widget_states is not None
506
+ and rerun_data.widget_states.widgets is not None
507
+ ):
508
+ widget_ids = {w.id for w in rerun_data.widget_states.widgets}
509
+ self._session_state.on_script_finished(widget_ids)
510
+
511
+ fragment_ids_this_run = list(rerun_data.fragment_id_queue)
512
+
513
+ ctx.reset(
514
+ query_string=rerun_data.query_string,
515
+ page_script_hash=page_script_hash,
516
+ fragment_ids_this_run=fragment_ids_this_run,
517
+ context_info=rerun_data.context_info,
518
+ )
519
+
520
+ self.on_event.send(
521
+ self,
522
+ event=ScriptRunnerEvent.SCRIPT_STARTED,
523
+ page_script_hash=page_script_hash,
524
+ fragment_ids_this_run=fragment_ids_this_run,
525
+ pages=self._pages_manager.get_pages(),
526
+ )
527
+
528
+ # Compile the script. Any errors thrown here will be surfaced
529
+ # to the user via a modal dialog in the frontend, and won't result
530
+ # in their previous script elements disappearing.
531
+ try:
532
+ if active_script is not None:
533
+ script_path = active_script["script_path"]
534
+ else:
535
+ # page must not be found
536
+ script_path = main_page_info["script_path"]
537
+
538
+ # At this point, we know that either
539
+ # * the script corresponding to the hash requested no longer
540
+ # exists, or
541
+ # * we were not able to find a script with the requested page
542
+ # name.
543
+ # In both of these cases, we want to send a page_not_found
544
+ # message to the frontend.
545
+ msg = ForwardMsg()
546
+ msg.page_not_found.page_name = rerun_data.page_name
547
+ ctx.enqueue(msg)
548
+
549
+ code = self._script_cache.get_bytecode(script_path)
550
+
551
+ except Exception as ex:
552
+ # We got a compile error. Send an error event and bail immediately.
553
+ _LOGGER.debug("Fatal script error", exc_info=ex)
554
+ self._session_state[SCRIPT_RUN_WITHOUT_ERRORS_KEY] = False
555
+ self.on_event.send(
556
+ self,
557
+ event=ScriptRunnerEvent.SCRIPT_STOPPED_WITH_COMPILE_ERROR,
558
+ exception=ex,
559
+ )
560
+ return
561
+
562
+ # If we get here, we've successfully compiled our script. The next step
563
+ # is to run it. Errors thrown during execution will be shown to the
564
+ # user as ExceptionElements.
565
+
566
+ # Create fake module. This gives us a name global namespace to
567
+ # execute the code in.
568
+ module = self._new_module("__main__")
569
+
570
+ # Install the fake module as the __main__ module. This allows
571
+ # the pickle module to work inside the user's code, since it now
572
+ # can know the module where the pickled objects stem from.
573
+ # IMPORTANT: This means we can't use "if __name__ == '__main__'" in
574
+ # our code, as it will point to the wrong module!!!
575
+ sys.modules["__main__"] = module
576
+
577
+ # Add special variables to the module's globals dict.
578
+ # Note: The following is a requirement for the CodeHasher to
579
+ # work correctly. The CodeHasher is scoped to
580
+ # files contained in the directory of __main__.__file__, which we
581
+ # assume is the main script directory.
582
+ module.__dict__["__file__"] = script_path
583
+
584
+ def code_to_exec(code=code, module=module, ctx=ctx, rerun_data=rerun_data):
585
+ with (
586
+ modified_sys_path(self._main_script_path),
587
+ self._set_execing_flag(),
588
+ ):
589
+ # Run callbacks for widgets whose values have changed.
590
+ if rerun_data.widget_states is not None:
591
+ self._session_state.on_script_will_rerun(
592
+ rerun_data.widget_states
593
+ )
594
+
595
+ ctx.on_script_start()
596
+
597
+ if rerun_data.fragment_id_queue:
598
+ for fragment_id in rerun_data.fragment_id_queue:
599
+ try:
600
+ wrapped_fragment = self._fragment_storage.get(
601
+ fragment_id
602
+ )
603
+ wrapped_fragment()
604
+
605
+ except FragmentStorageKeyError:
606
+ # This can happen if the fragment_id is removed from the
607
+ # storage before the script runner gets to it. In this
608
+ # case, the fragment is simply skipped.
609
+ # Also, only log an error if the fragment is not an
610
+ # auto_rerun to avoid noise. If it is an auto_rerun, we
611
+ # might have a race condition where the fragment_id is
612
+ # removed but the webapp sends a rerun request before
613
+ # the removal information has reached the web app
614
+ # (see https://github.com/streamlit/streamlit/issues/9080).
615
+ if not rerun_data.is_auto_rerun:
616
+ _LOGGER.warning(
617
+ f"Couldn't find fragment with id {fragment_id}."
618
+ " This can happen if the fragment does not"
619
+ " exist anymore when this request is processed,"
620
+ " for example because a full app rerun happened"
621
+ " that did not register the fragment."
622
+ " Usually this doesn't happen or no action is"
623
+ " required, so its mainly for debugging."
624
+ )
625
+ except (RerunException, StopException) as e:
626
+ # The wrapped_fragment function is executed
627
+ # inside of a exec_func_with_error_handling call, so
628
+ # there is a correct handler for these exceptions.
629
+ raise e
630
+ except Exception:
631
+ # Ignore exceptions raised by fragments here as we don't
632
+ # want to stop the execution of other fragments. The
633
+ # error itself is already rendered within the wrapped
634
+ # fragment.
635
+ pass
636
+
637
+ else:
638
+ if PagesManager.uses_pages_directory:
639
+ _mpa_v1(self._main_script_path)
640
+ exec(code, module.__dict__)
641
+ self._fragment_storage.clear(
642
+ new_fragment_ids=ctx.new_fragment_ids
643
+ )
644
+
645
+ self._session_state.maybe_check_serializable()
646
+ # check for control requests, e.g. rerun requests have arrived
647
+ self._maybe_handle_execution_control_request()
648
+
649
+ prep_time = timer() - start_time
650
+ (
651
+ _,
652
+ run_without_errors,
653
+ rerun_exception_data,
654
+ premature_stop,
655
+ uncaught_exception,
656
+ ) = exec_func_with_error_handling(code_to_exec, ctx)
657
+ # setting the session state here triggers a yield-callback call
658
+ # which reads self._requests and checks for rerun data
659
+ self._session_state[SCRIPT_RUN_WITHOUT_ERRORS_KEY] = run_without_errors
660
+
661
+ if rerun_exception_data:
662
+ # The handling for when a full script run or a fragment is stopped early
663
+ # is the same, so we only have one ScriptRunnerEvent for this scenario.
664
+ finished_event = ScriptRunnerEvent.SCRIPT_STOPPED_FOR_RERUN
665
+ elif rerun_data.fragment_id_queue:
666
+ finished_event = ScriptRunnerEvent.FRAGMENT_STOPPED_WITH_SUCCESS
667
+ else:
668
+ finished_event = ScriptRunnerEvent.SCRIPT_STOPPED_WITH_SUCCESS
669
+
670
+ if ctx.gather_usage_stats:
671
+ try:
672
+ # Create and send page profile information
673
+ ctx.enqueue(
674
+ create_page_profile_message(
675
+ commands=ctx.tracked_commands,
676
+ exec_time=to_microseconds(timer() - start_time),
677
+ prep_time=to_microseconds(prep_time),
678
+ uncaught_exception=(
679
+ type(uncaught_exception).__name__
680
+ if uncaught_exception
681
+ else None
682
+ ),
683
+ )
684
+ )
685
+ except Exception as ex:
686
+ # Always capture all exceptions since we want to make sure that
687
+ # the telemetry never causes any issues.
688
+ _LOGGER.debug("Failed to create page profile", exc_info=ex)
689
+ self._on_script_finished(ctx, finished_event, premature_stop)
690
+
691
+ # # Use _log_if_error() to make sure we never ever ever stop running the
692
+ # # script without meaning to.
693
+ _log_if_error(_clean_problem_modules)
694
+
695
+ if rerun_exception_data is not None:
696
+ rerun_data = rerun_exception_data
697
+ else:
698
+ break
699
+
700
+ def _on_script_finished(
701
+ self, ctx: ScriptRunContext, event: ScriptRunnerEvent, premature_stop: bool
702
+ ) -> None:
703
+ """Called when our script finishes executing, even if it finished
704
+ early with an exception. We perform post-run cleanup here.
705
+ """
706
+ # Tell session_state to update itself in response
707
+ if not premature_stop:
708
+ self._session_state.on_script_finished(ctx.widget_ids_this_run)
709
+
710
+ # Signal that the script has finished. (We use SCRIPT_STOPPED_WITH_SUCCESS
711
+ # even if we were stopped with an exception.)
712
+ self.on_event.send(self, event=event)
713
+
714
+ # Remove orphaned files now that the script has run and files in use
715
+ # are marked as active.
716
+ runtime.get_instance().media_file_mgr.remove_orphaned_files()
717
+
718
+ # Force garbage collection to run, to help avoid memory use building up
719
+ # This is usually not an issue, but sometimes GC takes time to kick in and
720
+ # causes apps to go over resource limits, and forcing it to run between
721
+ # script runs is low cost, since we aren't doing much work anyway.
722
+ if config.get_option("runner.postScriptGC"):
723
+ gc.collect(2)
724
+
725
+ def _new_module(self, name: str) -> types.ModuleType:
726
+ """Create a new module with the given name."""
727
+ return types.ModuleType(name)
728
+
729
+
730
+ def _clean_problem_modules() -> None:
731
+ """Some modules are stateful, so we have to clear their state."""
732
+
733
+ if "keras" in sys.modules:
734
+ try:
735
+ keras = sys.modules["keras"]
736
+ keras.backend.clear_session()
737
+ except Exception:
738
+ # We don't want to crash the app if we can't clear the Keras session.
739
+ pass
740
+
741
+ if "matplotlib.pyplot" in sys.modules:
742
+ try:
743
+ plt = sys.modules["matplotlib.pyplot"]
744
+ plt.close("all")
745
+ except Exception:
746
+ # We don't want to crash the app if we can't close matplotlib
747
+ pass
748
+
749
+
750
+ # The reason this is not a decorator is because we want to make it clear at the
751
+ # calling location that this function is being used.
752
+ def _log_if_error(fn: Callable[[], None]) -> None:
753
+ try:
754
+ fn()
755
+ except Exception as e:
756
+ _LOGGER.warning(e)