streamlit-data-editor-plus 0.1.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 (456) hide show
  1. streamlit/__init__.py +292 -0
  2. streamlit/__main__.py +20 -0
  3. streamlit/auth_util.py +583 -0
  4. streamlit/cli_util.py +107 -0
  5. streamlit/column_config.py +60 -0
  6. streamlit/commands/__init__.py +13 -0
  7. streamlit/commands/echo.py +128 -0
  8. streamlit/commands/execution_control.py +318 -0
  9. streamlit/commands/logo.py +250 -0
  10. streamlit/commands/navigation.py +430 -0
  11. streamlit/commands/page_config.py +335 -0
  12. streamlit/components/__init__.py +13 -0
  13. streamlit/components/lib/__init__.py +13 -0
  14. streamlit/components/lib/local_component_registry.py +84 -0
  15. streamlit/components/types/__init__.py +13 -0
  16. streamlit/components/types/base_component_registry.py +99 -0
  17. streamlit/components/types/base_custom_component.py +158 -0
  18. streamlit/components/v1/__init__.py +29 -0
  19. streamlit/components/v1/component_arrow.py +141 -0
  20. streamlit/components/v1/component_registry.py +147 -0
  21. streamlit/components/v1/components.py +38 -0
  22. streamlit/components/v1/custom_component.py +239 -0
  23. streamlit/components/v2/__init__.py +531 -0
  24. streamlit/components/v2/bidi_component/__init__.py +20 -0
  25. streamlit/components/v2/bidi_component/constants.py +29 -0
  26. streamlit/components/v2/bidi_component/main.py +537 -0
  27. streamlit/components/v2/bidi_component/serialization.py +272 -0
  28. streamlit/components/v2/bidi_component/state.py +92 -0
  29. streamlit/components/v2/component_definition_resolver.py +143 -0
  30. streamlit/components/v2/component_file_watcher.py +403 -0
  31. streamlit/components/v2/component_manager.py +439 -0
  32. streamlit/components/v2/component_manifest_handler.py +122 -0
  33. streamlit/components/v2/component_path_utils.py +233 -0
  34. streamlit/components/v2/component_registry.py +426 -0
  35. streamlit/components/v2/get_bidi_component_manager.py +51 -0
  36. streamlit/components/v2/manifest_scanner.py +620 -0
  37. streamlit/components/v2/presentation.py +198 -0
  38. streamlit/components/v2/types.py +317 -0
  39. streamlit/config.py +2977 -0
  40. streamlit/config_option.py +319 -0
  41. streamlit/config_util.py +887 -0
  42. streamlit/connections/__init__.py +32 -0
  43. streamlit/connections/base_connection.py +215 -0
  44. streamlit/connections/snowflake_connection.py +765 -0
  45. streamlit/connections/snowpark_connection.py +213 -0
  46. streamlit/connections/sql_connection.py +427 -0
  47. streamlit/connections/util.py +97 -0
  48. streamlit/cursor.py +314 -0
  49. streamlit/dataframe_util.py +1434 -0
  50. streamlit/delta_generator.py +696 -0
  51. streamlit/delta_generator_singletons.py +243 -0
  52. streamlit/deprecation_util.py +253 -0
  53. streamlit/development.py +21 -0
  54. streamlit/elements/__init__.py +13 -0
  55. streamlit/elements/alert.py +341 -0
  56. streamlit/elements/arrow.py +1065 -0
  57. streamlit/elements/balloons.py +47 -0
  58. streamlit/elements/bokeh_chart.py +75 -0
  59. streamlit/elements/code.py +154 -0
  60. streamlit/elements/deck_gl_json_chart.py +627 -0
  61. streamlit/elements/dialog_decorator.py +320 -0
  62. streamlit/elements/empty.py +130 -0
  63. streamlit/elements/exception.py +370 -0
  64. streamlit/elements/form.py +481 -0
  65. streamlit/elements/graphviz_chart.py +226 -0
  66. streamlit/elements/heading.py +407 -0
  67. streamlit/elements/help.py +565 -0
  68. streamlit/elements/html.py +189 -0
  69. streamlit/elements/iframe.py +245 -0
  70. streamlit/elements/image.py +221 -0
  71. streamlit/elements/json.py +171 -0
  72. streamlit/elements/layouts.py +1534 -0
  73. streamlit/elements/lib/__init__.py +13 -0
  74. streamlit/elements/lib/built_in_chart_utils.py +1316 -0
  75. streamlit/elements/lib/color_util.py +272 -0
  76. streamlit/elements/lib/column_config_utils.py +555 -0
  77. streamlit/elements/lib/column_types.py +2699 -0
  78. streamlit/elements/lib/dialog.py +212 -0
  79. streamlit/elements/lib/dicttools.py +152 -0
  80. streamlit/elements/lib/file_uploader_utils.py +91 -0
  81. streamlit/elements/lib/form_utils.py +77 -0
  82. streamlit/elements/lib/image_utils.py +447 -0
  83. streamlit/elements/lib/js_number.py +105 -0
  84. streamlit/elements/lib/layout_utils.py +325 -0
  85. streamlit/elements/lib/mutable_expander_container.py +73 -0
  86. streamlit/elements/lib/mutable_popover_container.py +73 -0
  87. streamlit/elements/lib/mutable_status_container.py +194 -0
  88. streamlit/elements/lib/mutable_tab_container.py +73 -0
  89. streamlit/elements/lib/options_selector_utils.py +480 -0
  90. streamlit/elements/lib/pandas_styler_utils.py +302 -0
  91. streamlit/elements/lib/policies.py +198 -0
  92. streamlit/elements/lib/shortcut_utils.py +152 -0
  93. streamlit/elements/lib/streamlit_plotly_theme.py +206 -0
  94. streamlit/elements/lib/subtitle_utils.py +175 -0
  95. streamlit/elements/lib/utils.py +274 -0
  96. streamlit/elements/map.py +526 -0
  97. streamlit/elements/markdown.py +529 -0
  98. streamlit/elements/media.py +843 -0
  99. streamlit/elements/metric.py +529 -0
  100. streamlit/elements/pdf.py +190 -0
  101. streamlit/elements/plotly_chart.py +779 -0
  102. streamlit/elements/progress.py +172 -0
  103. streamlit/elements/pyplot.py +240 -0
  104. streamlit/elements/snow.py +47 -0
  105. streamlit/elements/space.py +121 -0
  106. streamlit/elements/spinner.py +152 -0
  107. streamlit/elements/table.py +240 -0
  108. streamlit/elements/text.py +113 -0
  109. streamlit/elements/toast.py +175 -0
  110. streamlit/elements/vega_charts.py +2510 -0
  111. streamlit/elements/widgets/__init__.py +13 -0
  112. streamlit/elements/widgets/audio_input.py +334 -0
  113. streamlit/elements/widgets/button.py +1559 -0
  114. streamlit/elements/widgets/button_group.py +1061 -0
  115. streamlit/elements/widgets/camera_input.py +281 -0
  116. streamlit/elements/widgets/chat.py +1028 -0
  117. streamlit/elements/widgets/checkbox.py +420 -0
  118. streamlit/elements/widgets/color_picker.py +329 -0
  119. streamlit/elements/widgets/data_editor.py +1168 -0
  120. streamlit/elements/widgets/data_editor_plus.py +902 -0
  121. streamlit/elements/widgets/feedback.py +322 -0
  122. streamlit/elements/widgets/file_uploader.py +592 -0
  123. streamlit/elements/widgets/multiselect.py +654 -0
  124. streamlit/elements/widgets/number_input.py +719 -0
  125. streamlit/elements/widgets/radio.py +551 -0
  126. streamlit/elements/widgets/select_slider.py +568 -0
  127. streamlit/elements/widgets/selectbox.py +680 -0
  128. streamlit/elements/widgets/slider.py +1093 -0
  129. streamlit/elements/widgets/text_widgets.py +779 -0
  130. streamlit/elements/widgets/time_widgets.py +1712 -0
  131. streamlit/elements/write.py +585 -0
  132. streamlit/emojis.py +34 -0
  133. streamlit/env_util.py +56 -0
  134. streamlit/error_util.py +112 -0
  135. streamlit/errors.py +680 -0
  136. streamlit/external/__init__.py +13 -0
  137. streamlit/external/langchain/__init__.py +23 -0
  138. streamlit/external/langchain/streamlit_callback_handler.py +410 -0
  139. streamlit/file_util.py +266 -0
  140. streamlit/git_util.py +200 -0
  141. streamlit/hello/__init__.py +13 -0
  142. streamlit/hello/__pycache__/__init__.cpython-312.pyc +0 -0
  143. streamlit/hello/__pycache__/streamlit_app.cpython-312.pyc +0 -0
  144. streamlit/hello/animation_demo.py +82 -0
  145. streamlit/hello/dataframe_demo.py +71 -0
  146. streamlit/hello/hello.py +46 -0
  147. streamlit/hello/mapping_demo.py +113 -0
  148. streamlit/hello/plotting_demo.py +62 -0
  149. streamlit/hello/streamlit_app.py +57 -0
  150. streamlit/hello/utils.py +30 -0
  151. streamlit/logger.py +129 -0
  152. streamlit/material_icon_names.py +25 -0
  153. streamlit/navigation/__init__.py +13 -0
  154. streamlit/navigation/page.py +365 -0
  155. streamlit/net_util.py +125 -0
  156. streamlit/path_security.py +98 -0
  157. streamlit/platform.py +31 -0
  158. streamlit/proto/Alert_pb2.py +28 -0
  159. streamlit/proto/Alert_pb2.pyi +100 -0
  160. streamlit/proto/AppPage_pb2.py +25 -0
  161. streamlit/proto/AppPage_pb2.pyi +75 -0
  162. streamlit/proto/ArrowData_pb2.py +27 -0
  163. streamlit/proto/ArrowData_pb2.pyi +103 -0
  164. streamlit/proto/ArrowNamedDataSet_pb2.py +26 -0
  165. streamlit/proto/ArrowNamedDataSet_pb2.pyi +65 -0
  166. streamlit/proto/AudioInput_pb2.py +26 -0
  167. streamlit/proto/AudioInput_pb2.pyi +72 -0
  168. streamlit/proto/Audio_pb2.py +26 -0
  169. streamlit/proto/Audio_pb2.pyi +75 -0
  170. streamlit/proto/AuthRedirect_pb2.py +25 -0
  171. streamlit/proto/AuthRedirect_pb2.pyi +48 -0
  172. streamlit/proto/AutoRerun_pb2.py +25 -0
  173. streamlit/proto/AutoRerun_pb2.pyi +52 -0
  174. streamlit/proto/BackMsg_pb2.py +29 -0
  175. streamlit/proto/BackMsg_pb2.pyi +132 -0
  176. streamlit/proto/Balloons_pb2.py +25 -0
  177. streamlit/proto/Balloons_pb2.pyi +48 -0
  178. streamlit/proto/BidiComponent_pb2.py +32 -0
  179. streamlit/proto/BidiComponent_pb2.pyi +176 -0
  180. streamlit/proto/Block_pb2.py +62 -0
  181. streamlit/proto/Block_pb2.pyi +518 -0
  182. streamlit/proto/ButtonGroup_pb2.py +32 -0
  183. streamlit/proto/ButtonGroup_pb2.pyi +157 -0
  184. streamlit/proto/ButtonLikeIconPosition_pb2.py +25 -0
  185. streamlit/proto/ButtonLikeIconPosition_pb2.pyi +47 -0
  186. streamlit/proto/Button_pb2.py +26 -0
  187. streamlit/proto/Button_pb2.pyi +82 -0
  188. streamlit/proto/CameraInput_pb2.py +26 -0
  189. streamlit/proto/CameraInput_pb2.pyi +66 -0
  190. streamlit/proto/ChatInput_pb2.py +27 -0
  191. streamlit/proto/ChatInput_pb2.pyi +113 -0
  192. streamlit/proto/Checkbox_pb2.py +28 -0
  193. streamlit/proto/Checkbox_pb2.pyi +99 -0
  194. streamlit/proto/ClientState_pb2.py +28 -0
  195. streamlit/proto/ClientState_pb2.pyi +137 -0
  196. streamlit/proto/Code_pb2.py +25 -0
  197. streamlit/proto/Code_pb2.pyi +59 -0
  198. streamlit/proto/ColorPicker_pb2.py +26 -0
  199. streamlit/proto/ColorPicker_pb2.pyi +82 -0
  200. streamlit/proto/Common_pb2.py +49 -0
  201. streamlit/proto/Common_pb2.pyi +325 -0
  202. streamlit/proto/Components_pb2.py +33 -0
  203. streamlit/proto/Components_pb2.pyi +196 -0
  204. streamlit/proto/Dataframe_pb2.py +30 -0
  205. streamlit/proto/Dataframe_pb2.pyi +172 -0
  206. streamlit/proto/DateInput_pb2.py +26 -0
  207. streamlit/proto/DateInput_pb2.pyi +91 -0
  208. streamlit/proto/DateTimeInput_pb2.py +26 -0
  209. streamlit/proto/DateTimeInput_pb2.pyi +94 -0
  210. streamlit/proto/DeckGlJsonChart_pb2.py +27 -0
  211. streamlit/proto/DeckGlJsonChart_pb2.pyi +91 -0
  212. streamlit/proto/Delta_pb2.py +29 -0
  213. streamlit/proto/Delta_pb2.pyi +82 -0
  214. streamlit/proto/DownloadButton_pb2.py +26 -0
  215. streamlit/proto/DownloadButton_pb2.pyi +92 -0
  216. streamlit/proto/Element_pb2.py +81 -0
  217. streamlit/proto/Element_pb2.pyi +348 -0
  218. streamlit/proto/Empty_pb2.py +25 -0
  219. streamlit/proto/Empty_pb2.pyi +42 -0
  220. streamlit/proto/Exception_pb2.py +26 -0
  221. streamlit/proto/Exception_pb2.pyi +88 -0
  222. streamlit/proto/Favicon_pb2.py +25 -0
  223. streamlit/proto/Favicon_pb2.pyi +47 -0
  224. streamlit/proto/Feedback_pb2.py +27 -0
  225. streamlit/proto/Feedback_pb2.pyi +93 -0
  226. streamlit/proto/FileUploader_pb2.py +26 -0
  227. streamlit/proto/FileUploader_pb2.pyi +90 -0
  228. streamlit/proto/ForwardMsg_pb2.py +48 -0
  229. streamlit/proto/ForwardMsg_pb2.pyi +296 -0
  230. streamlit/proto/GapSize_pb2.py +27 -0
  231. streamlit/proto/GapSize_pb2.pyi +82 -0
  232. streamlit/proto/GitInfo_pb2.py +27 -0
  233. streamlit/proto/GitInfo_pb2.pyi +84 -0
  234. streamlit/proto/GraphVizChart_pb2.py +25 -0
  235. streamlit/proto/GraphVizChart_pb2.pyi +56 -0
  236. streamlit/proto/Heading_pb2.py +25 -0
  237. streamlit/proto/Heading_pb2.pyi +63 -0
  238. streamlit/proto/HeightConfig_pb2.py +25 -0
  239. streamlit/proto/HeightConfig_pb2.pyi +61 -0
  240. streamlit/proto/Help_pb2.py +27 -0
  241. streamlit/proto/Help_pb2.pyi +104 -0
  242. streamlit/proto/Html_pb2.py +25 -0
  243. streamlit/proto/Html_pb2.pyi +52 -0
  244. streamlit/proto/IFrame_pb2.py +25 -0
  245. streamlit/proto/IFrame_pb2.pyi +68 -0
  246. streamlit/proto/Image_pb2.py +27 -0
  247. streamlit/proto/Image_pb2.pyi +73 -0
  248. streamlit/proto/Json_pb2.py +25 -0
  249. streamlit/proto/Json_pb2.pyi +63 -0
  250. streamlit/proto/LabelVisibility_pb2.py +27 -0
  251. streamlit/proto/LabelVisibility_pb2.pyi +69 -0
  252. streamlit/proto/LinkButton_pb2.py +26 -0
  253. streamlit/proto/LinkButton_pb2.pyi +76 -0
  254. streamlit/proto/Logo_pb2.py +27 -0
  255. streamlit/proto/Logo_pb2.pyi +82 -0
  256. streamlit/proto/Markdown_pb2.py +27 -0
  257. streamlit/proto/Markdown_pb2.pyi +83 -0
  258. streamlit/proto/Metric_pb2.py +32 -0
  259. streamlit/proto/Metric_pb2.pyi +145 -0
  260. streamlit/proto/MetricsEvent_pb2.py +28 -0
  261. streamlit/proto/MetricsEvent_pb2.pyi +224 -0
  262. streamlit/proto/MultiSelect_pb2.py +26 -0
  263. streamlit/proto/MultiSelect_pb2.pyi +108 -0
  264. streamlit/proto/Navigation_pb2.py +28 -0
  265. streamlit/proto/Navigation_pb2.pyi +89 -0
  266. streamlit/proto/NewSession_pb2.py +47 -0
  267. streamlit/proto/NewSession_pb2.pyi +753 -0
  268. streamlit/proto/NumberInput_pb2.py +28 -0
  269. streamlit/proto/NumberInput_pb2.pyi +138 -0
  270. streamlit/proto/PageConfig_pb2.py +33 -0
  271. streamlit/proto/PageConfig_pb2.pyi +179 -0
  272. streamlit/proto/PageInfo_pb2.py +25 -0
  273. streamlit/proto/PageInfo_pb2.pyi +50 -0
  274. streamlit/proto/PageLink_pb2.py +26 -0
  275. streamlit/proto/PageLink_pb2.pyi +80 -0
  276. streamlit/proto/PageNotFound_pb2.py +25 -0
  277. streamlit/proto/PageNotFound_pb2.pyi +49 -0
  278. streamlit/proto/PageProfile_pb2.py +29 -0
  279. streamlit/proto/PageProfile_pb2.pyi +146 -0
  280. streamlit/proto/ParentMessage_pb2.py +25 -0
  281. streamlit/proto/ParentMessage_pb2.pyi +53 -0
  282. streamlit/proto/PlotlyChart_pb2.py +27 -0
  283. streamlit/proto/PlotlyChart_pb2.pyi +96 -0
  284. streamlit/proto/Progress_pb2.py +25 -0
  285. streamlit/proto/Progress_pb2.pyi +50 -0
  286. streamlit/proto/Radio_pb2.py +26 -0
  287. streamlit/proto/Radio_pb2.pyi +104 -0
  288. streamlit/proto/RootContainer_pb2.py +25 -0
  289. streamlit/proto/RootContainer_pb2.pyi +56 -0
  290. streamlit/proto/Selectbox_pb2.py +26 -0
  291. streamlit/proto/Selectbox_pb2.pyi +107 -0
  292. streamlit/proto/SessionEvent_pb2.py +26 -0
  293. streamlit/proto/SessionEvent_pb2.pyi +72 -0
  294. streamlit/proto/SessionStatus_pb2.py +25 -0
  295. streamlit/proto/SessionStatus_pb2.pyi +64 -0
  296. streamlit/proto/Skeleton_pb2.py +27 -0
  297. streamlit/proto/Skeleton_pb2.pyi +75 -0
  298. streamlit/proto/Slider_pb2.py +30 -0
  299. streamlit/proto/Slider_pb2.pyi +161 -0
  300. streamlit/proto/Snow_pb2.py +25 -0
  301. streamlit/proto/Snow_pb2.pyi +48 -0
  302. streamlit/proto/Space_pb2.py +25 -0
  303. streamlit/proto/Space_pb2.pyi +48 -0
  304. streamlit/proto/Spinner_pb2.py +25 -0
  305. streamlit/proto/Spinner_pb2.pyi +56 -0
  306. streamlit/proto/Table_pb2.py +28 -0
  307. streamlit/proto/Table_pb2.pyi +83 -0
  308. streamlit/proto/TextAlignmentConfig_pb2.py +27 -0
  309. streamlit/proto/TextAlignmentConfig_pb2.pyi +69 -0
  310. streamlit/proto/TextArea_pb2.py +26 -0
  311. streamlit/proto/TextArea_pb2.pyi +97 -0
  312. streamlit/proto/TextInput_pb2.py +28 -0
  313. streamlit/proto/TextInput_pb2.pyi +124 -0
  314. streamlit/proto/Text_pb2.py +25 -0
  315. streamlit/proto/Text_pb2.pyi +53 -0
  316. streamlit/proto/TimeInput_pb2.py +26 -0
  317. streamlit/proto/TimeInput_pb2.pyi +86 -0
  318. streamlit/proto/Toast_pb2.py +25 -0
  319. streamlit/proto/Toast_pb2.pyi +64 -0
  320. streamlit/proto/Transient_pb2.py +26 -0
  321. streamlit/proto/Transient_pb2.pyi +53 -0
  322. streamlit/proto/VegaLiteChart_pb2.py +27 -0
  323. streamlit/proto/VegaLiteChart_pb2.pyi +92 -0
  324. streamlit/proto/Video_pb2.py +30 -0
  325. streamlit/proto/Video_pb2.pyi +129 -0
  326. streamlit/proto/WidgetStates_pb2.py +31 -0
  327. streamlit/proto/WidgetStates_pb2.pyi +157 -0
  328. streamlit/proto/WidthConfig_pb2.py +25 -0
  329. streamlit/proto/WidthConfig_pb2.pyi +61 -0
  330. streamlit/proto/__init__.py +15 -0
  331. streamlit/proto/openmetrics_data_model_pb2.py +58 -0
  332. streamlit/proto/openmetrics_data_model_pb2.pyi +558 -0
  333. streamlit/py.typed +0 -0
  334. streamlit/runtime/__init__.py +50 -0
  335. streamlit/runtime/app_session.py +1302 -0
  336. streamlit/runtime/caching/__init__.py +118 -0
  337. streamlit/runtime/caching/cache_data_api.py +775 -0
  338. streamlit/runtime/caching/cache_errors.py +143 -0
  339. streamlit/runtime/caching/cache_resource_api.py +756 -0
  340. streamlit/runtime/caching/cache_type.py +33 -0
  341. streamlit/runtime/caching/cache_utils.py +601 -0
  342. streamlit/runtime/caching/cached_message_replay.py +290 -0
  343. streamlit/runtime/caching/hashing.py +655 -0
  344. streamlit/runtime/caching/legacy_cache_api.py +170 -0
  345. streamlit/runtime/caching/storage/__init__.py +29 -0
  346. streamlit/runtime/caching/storage/cache_storage_protocol.py +236 -0
  347. streamlit/runtime/caching/storage/dummy_cache_storage.py +60 -0
  348. streamlit/runtime/caching/storage/in_memory_cache_storage_wrapper.py +159 -0
  349. streamlit/runtime/caching/storage/local_disk_cache_storage.py +223 -0
  350. streamlit/runtime/caching/ttl_cleanup_cache.py +85 -0
  351. streamlit/runtime/connection_factory.py +498 -0
  352. streamlit/runtime/context.py +449 -0
  353. streamlit/runtime/context_util.py +49 -0
  354. streamlit/runtime/credentials.py +355 -0
  355. streamlit/runtime/download_data_util.py +53 -0
  356. streamlit/runtime/forward_msg_cache.py +101 -0
  357. streamlit/runtime/forward_msg_queue.py +263 -0
  358. streamlit/runtime/fragment.py +441 -0
  359. streamlit/runtime/media_file_manager.py +409 -0
  360. streamlit/runtime/media_file_storage.py +143 -0
  361. streamlit/runtime/memory_media_file_storage.py +201 -0
  362. streamlit/runtime/memory_session_storage.py +77 -0
  363. streamlit/runtime/memory_uploaded_file_manager.py +149 -0
  364. streamlit/runtime/metrics_util.py +612 -0
  365. streamlit/runtime/pages_manager.py +160 -0
  366. streamlit/runtime/runtime.py +775 -0
  367. streamlit/runtime/runtime_util.py +108 -0
  368. streamlit/runtime/script_data.py +46 -0
  369. streamlit/runtime/scriptrunner/__init__.py +38 -0
  370. streamlit/runtime/scriptrunner/exec_code.py +167 -0
  371. streamlit/runtime/scriptrunner/magic.py +277 -0
  372. streamlit/runtime/scriptrunner/magic_funcs.py +32 -0
  373. streamlit/runtime/scriptrunner/script_cache.py +89 -0
  374. streamlit/runtime/scriptrunner/script_runner.py +805 -0
  375. streamlit/runtime/scriptrunner_utils/__init__.py +19 -0
  376. streamlit/runtime/scriptrunner_utils/exceptions.py +44 -0
  377. streamlit/runtime/scriptrunner_utils/script_requests.py +311 -0
  378. streamlit/runtime/scriptrunner_utils/script_run_context.py +277 -0
  379. streamlit/runtime/secrets.py +533 -0
  380. streamlit/runtime/session_manager.py +430 -0
  381. streamlit/runtime/state/__init__.py +47 -0
  382. streamlit/runtime/state/common.py +256 -0
  383. streamlit/runtime/state/presentation.py +85 -0
  384. streamlit/runtime/state/query_params.py +767 -0
  385. streamlit/runtime/state/query_params_proxy.py +222 -0
  386. streamlit/runtime/state/safe_session_state.py +146 -0
  387. streamlit/runtime/state/session_state.py +1299 -0
  388. streamlit/runtime/state/session_state_proxy.py +153 -0
  389. streamlit/runtime/state/widgets.py +197 -0
  390. streamlit/runtime/stats.py +356 -0
  391. streamlit/runtime/theme_util.py +148 -0
  392. streamlit/runtime/uploaded_file_manager.py +152 -0
  393. streamlit/runtime/websocket_session_manager.py +301 -0
  394. streamlit/source_util.py +97 -0
  395. streamlit/starlette.py +34 -0
  396. streamlit/string_util.py +264 -0
  397. streamlit/temporary_directory.py +67 -0
  398. streamlit/testing/__init__.py +13 -0
  399. streamlit/testing/v1/__init__.py +17 -0
  400. streamlit/testing/v1/app_test.py +1089 -0
  401. streamlit/testing/v1/element_tree.py +2272 -0
  402. streamlit/testing/v1/local_script_runner.py +176 -0
  403. streamlit/testing/v1/util.py +61 -0
  404. streamlit/time_util.py +73 -0
  405. streamlit/type_util.py +480 -0
  406. streamlit/url_util.py +120 -0
  407. streamlit/user_info.py +698 -0
  408. streamlit/util.py +108 -0
  409. streamlit/vendor/__init__.py +0 -0
  410. streamlit/vendor/pympler/__init__.py +0 -0
  411. streamlit/vendor/pympler/asizeof.py +2870 -0
  412. streamlit/version.py +18 -0
  413. streamlit/watcher/__init__.py +28 -0
  414. streamlit/watcher/event_based_path_watcher.py +500 -0
  415. streamlit/watcher/folder_black_list.py +82 -0
  416. streamlit/watcher/local_sources_watcher.py +297 -0
  417. streamlit/watcher/path_watcher.py +244 -0
  418. streamlit/watcher/polling_path_watcher.py +138 -0
  419. streamlit/watcher/util.py +223 -0
  420. streamlit/web/__init__.py +13 -0
  421. streamlit/web/bootstrap.py +463 -0
  422. streamlit/web/cache_storage_manager_config.py +38 -0
  423. streamlit/web/cli.py +465 -0
  424. streamlit/web/server/__init__.py +30 -0
  425. streamlit/web/server/app_discovery.py +422 -0
  426. streamlit/web/server/app_static_file_handler.py +102 -0
  427. streamlit/web/server/authlib_tornado_integration.py +125 -0
  428. streamlit/web/server/bidi_component_request_handler.py +193 -0
  429. streamlit/web/server/browser_websocket_handler.py +341 -0
  430. streamlit/web/server/component_file_utils.py +105 -0
  431. streamlit/web/server/component_request_handler.py +107 -0
  432. streamlit/web/server/media_file_handler.py +148 -0
  433. streamlit/web/server/oauth_authlib_routes.py +314 -0
  434. streamlit/web/server/oidc_mixin.py +138 -0
  435. streamlit/web/server/routes.py +257 -0
  436. streamlit/web/server/server.py +555 -0
  437. streamlit/web/server/server_util.py +235 -0
  438. streamlit/web/server/starlette/__init__.py +23 -0
  439. streamlit/web/server/starlette/starlette_app.py +541 -0
  440. streamlit/web/server/starlette/starlette_app_utils.py +306 -0
  441. streamlit/web/server/starlette/starlette_auth_routes.py +584 -0
  442. streamlit/web/server/starlette/starlette_gzip_middleware.py +121 -0
  443. streamlit/web/server/starlette/starlette_path_security_middleware.py +97 -0
  444. streamlit/web/server/starlette/starlette_routes.py +884 -0
  445. streamlit/web/server/starlette/starlette_server.py +496 -0
  446. streamlit/web/server/starlette/starlette_server_config.py +55 -0
  447. streamlit/web/server/starlette/starlette_static_routes.py +181 -0
  448. streamlit/web/server/starlette/starlette_websocket.py +560 -0
  449. streamlit/web/server/stats_request_handler.py +116 -0
  450. streamlit/web/server/upload_file_request_handler.py +158 -0
  451. streamlit/web/server/websocket_headers.py +56 -0
  452. streamlit_data_editor_plus-0.1.0.dist-info/METADATA +76 -0
  453. streamlit_data_editor_plus-0.1.0.dist-info/RECORD +456 -0
  454. streamlit_data_editor_plus-0.1.0.dist-info/WHEEL +5 -0
  455. streamlit_data_editor_plus-0.1.0.dist-info/entry_points.txt +2 -0
  456. streamlit_data_editor_plus-0.1.0.dist-info/top_level.txt +1 -0
@@ -0,0 +1,325 @@
1
+ # Copyright (c) Streamlit Inc. (2018-2022) Snowflake Inc. (2022-2026)
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
+ from __future__ import annotations
15
+
16
+ from dataclasses import dataclass
17
+ from typing import Literal, TypeAlias, cast
18
+
19
+ from streamlit.errors import (
20
+ StreamlitInvalidColumnGapError,
21
+ StreamlitInvalidHeightError,
22
+ StreamlitInvalidHorizontalAlignmentError,
23
+ StreamlitInvalidSizeError,
24
+ StreamlitInvalidTextAlignmentError,
25
+ StreamlitInvalidVerticalAlignmentError,
26
+ StreamlitInvalidWidthError,
27
+ )
28
+ from streamlit.proto.Block_pb2 import Block
29
+ from streamlit.proto.GapSize_pb2 import GapSize
30
+ from streamlit.proto.HeightConfig_pb2 import HeightConfig
31
+ from streamlit.proto.TextAlignmentConfig_pb2 import TextAlignmentConfig
32
+ from streamlit.proto.WidthConfig_pb2 import WidthConfig
33
+
34
+ WidthWithoutContent: TypeAlias = int | Literal["stretch"]
35
+ Width: TypeAlias = int | Literal["stretch", "content"]
36
+ HeightWithoutContent: TypeAlias = int | Literal["stretch"]
37
+ Height: TypeAlias = int | Literal["stretch", "content"]
38
+ SpaceSize: TypeAlias = (
39
+ int
40
+ | Literal[
41
+ "stretch", "xxsmall", "xsmall", "small", "medium", "large", "xlarge", "xxlarge"
42
+ ]
43
+ )
44
+ Gap: TypeAlias = Literal[
45
+ "xxsmall", "xsmall", "small", "medium", "large", "xlarge", "xxlarge"
46
+ ]
47
+ HorizontalAlignment: TypeAlias = Literal["left", "center", "right", "distribute"]
48
+ VerticalAlignment: TypeAlias = Literal["top", "center", "bottom", "distribute"]
49
+ TextAlignment: TypeAlias = Literal["left", "center", "right", "justify"]
50
+
51
+ # Mapping of size literals to rem values for st.space
52
+ # If changing these, also check streamlit/frontend/lib/src/theme/primitives/sizes.ts
53
+ # to ensure sizes are kept in sync.
54
+ SIZE_TO_REM_MAPPING = {
55
+ "xxsmall": 0.25, # Aligns with gap "xxsmall" (4px)
56
+ "xsmall": 0.5, # Aligns with gap "xsmall" (8px)
57
+ "small": 0.75, # Height of widget label minus gap
58
+ "medium": 2.5, # Height of button/input field
59
+ "large": 4.25, # Height of large widget without label
60
+ "xlarge": 6, # Aligns with gap "xlarge" (96px)
61
+ "xxlarge": 8, # Aligns with gap "xxlarge" (128px)
62
+ }
63
+
64
+
65
+ @dataclass
66
+ class LayoutConfig:
67
+ width: Width | SpaceSize | None = None
68
+ height: Height | SpaceSize | None = None
69
+ text_alignment: TextAlignment | None = None
70
+
71
+
72
+ def validate_width(width: Width, allow_content: bool = False) -> None:
73
+ """Validate the width parameter.
74
+
75
+ Parameters
76
+ ----------
77
+ width : Any
78
+ The width value to validate.
79
+ allow_content : bool
80
+ Whether to allow "content" as a valid width value.
81
+
82
+ Raises
83
+ ------
84
+ StreamlitInvalidWidthError
85
+ If the width value is invalid.
86
+ """
87
+ if not isinstance(width, (int, str)):
88
+ raise StreamlitInvalidWidthError(width, allow_content)
89
+
90
+ if isinstance(width, str):
91
+ valid_strings = ["stretch"]
92
+ if allow_content:
93
+ valid_strings.append("content")
94
+
95
+ if width not in valid_strings:
96
+ raise StreamlitInvalidWidthError(width, allow_content)
97
+ elif width <= 0:
98
+ raise StreamlitInvalidWidthError(width, allow_content)
99
+
100
+
101
+ def validate_height(
102
+ height: Height | Literal["auto"],
103
+ allow_content: bool = False,
104
+ allow_stretch: bool = True,
105
+ additional_allowed: list[str] | None = None,
106
+ ) -> None:
107
+ """Validate the height parameter.
108
+
109
+ Parameters
110
+ ----------
111
+ height : Any
112
+ The height value to validate.
113
+ allow_content : bool
114
+ Whether to allow "content" as a valid height value.
115
+ allow_stretch : bool
116
+ Whether to allow "stretch" as a valid height value.
117
+ additional_allowed : list[str] or None
118
+ Additional string values to allow beyond the base allowed values.
119
+
120
+ Raises
121
+ ------
122
+ StreamlitInvalidHeightError
123
+ If the height value is invalid.
124
+ """
125
+ if not isinstance(height, (int, str)):
126
+ raise StreamlitInvalidHeightError(height, allow_content)
127
+
128
+ if isinstance(height, str):
129
+ valid_strings = []
130
+ if allow_stretch:
131
+ valid_strings.append("stretch")
132
+ if allow_content:
133
+ valid_strings.append("content")
134
+ if additional_allowed:
135
+ valid_strings.extend(additional_allowed)
136
+
137
+ if height not in valid_strings:
138
+ raise StreamlitInvalidHeightError(height, allow_content)
139
+
140
+ elif height <= 0:
141
+ raise StreamlitInvalidHeightError(height, allow_content)
142
+
143
+
144
+ def validate_space_size(size: SpaceSize) -> None:
145
+ """Validate the size parameter for st.space.
146
+
147
+ Parameters
148
+ ----------
149
+ size : Any
150
+ The size value to validate.
151
+
152
+ Raises
153
+ ------
154
+ StreamlitInvalidSizeError
155
+ If the size value is invalid.
156
+ """
157
+ if not isinstance(size, (int, str)):
158
+ raise StreamlitInvalidSizeError(size)
159
+
160
+ if isinstance(size, str):
161
+ valid_strings = [
162
+ "stretch",
163
+ "xxsmall",
164
+ "xsmall",
165
+ "small",
166
+ "medium",
167
+ "large",
168
+ "xlarge",
169
+ "xxlarge",
170
+ ]
171
+ if size not in valid_strings:
172
+ raise StreamlitInvalidSizeError(size)
173
+ elif isinstance(size, int) and size <= 0:
174
+ raise StreamlitInvalidSizeError(size)
175
+
176
+
177
+ def get_width_config(width: Width | SpaceSize) -> WidthConfig:
178
+ width_config = WidthConfig()
179
+ if isinstance(width, str) and width in SIZE_TO_REM_MAPPING:
180
+ width_config.rem_width = SIZE_TO_REM_MAPPING[width]
181
+ elif isinstance(width, (int, float)):
182
+ width_config.pixel_width = int(width)
183
+ elif width == "content":
184
+ width_config.use_content = True
185
+ else:
186
+ width_config.use_stretch = True
187
+ return width_config
188
+
189
+
190
+ def get_height_config(height: Height | SpaceSize) -> HeightConfig:
191
+ height_config = HeightConfig()
192
+ if isinstance(height, str) and height in SIZE_TO_REM_MAPPING:
193
+ height_config.rem_height = SIZE_TO_REM_MAPPING[height]
194
+ elif isinstance(height, (int, float)):
195
+ height_config.pixel_height = int(height)
196
+ elif height == "content":
197
+ height_config.use_content = True
198
+ else:
199
+ height_config.use_stretch = True
200
+ return height_config
201
+
202
+
203
+ def get_gap_size(gap: str | None, element_type: str) -> GapSize.ValueType:
204
+ """Convert a gap string or None to a GapSize proto value."""
205
+ gap_mapping = {
206
+ "xxsmall": GapSize.XXSMALL,
207
+ "xsmall": GapSize.XSMALL,
208
+ "small": GapSize.SMALL,
209
+ "medium": GapSize.MEDIUM,
210
+ "large": GapSize.LARGE,
211
+ "xlarge": GapSize.XLARGE,
212
+ "xxlarge": GapSize.XXLARGE,
213
+ }
214
+
215
+ if isinstance(gap, str):
216
+ gap_size = gap.lower()
217
+ valid_sizes = gap_mapping.keys()
218
+
219
+ if gap_size in valid_sizes:
220
+ return gap_mapping[gap_size]
221
+ elif gap is None:
222
+ return GapSize.NONE
223
+
224
+ raise StreamlitInvalidColumnGapError(gap=gap, element_type=element_type)
225
+
226
+
227
+ def validate_horizontal_alignment(horizontal_alignment: HorizontalAlignment) -> None:
228
+ valid_horizontal_alignments = ["left", "center", "right", "distribute"]
229
+ if horizontal_alignment not in valid_horizontal_alignments:
230
+ raise StreamlitInvalidHorizontalAlignmentError(
231
+ horizontal_alignment, "st.container"
232
+ )
233
+
234
+
235
+ def validate_vertical_alignment(vertical_alignment: VerticalAlignment) -> None:
236
+ valid_vertical_alignments = ["top", "center", "bottom", "distribute"]
237
+ if vertical_alignment not in valid_vertical_alignments:
238
+ raise StreamlitInvalidVerticalAlignmentError(vertical_alignment, "st.container")
239
+
240
+
241
+ def validate_text_alignment(text_alignment: TextAlignment) -> None:
242
+ """Validate the text_alignment parameter.
243
+
244
+ Parameters
245
+ ----------
246
+ text_alignment : TextAlignment
247
+ The text alignment value to validate.
248
+
249
+ Raises
250
+ ------
251
+ StreamlitInvalidTextAlignmentError
252
+ If the text_alignment value is invalid.
253
+ """
254
+ valid_alignments = ["left", "center", "right", "justify"]
255
+ if text_alignment not in valid_alignments:
256
+ raise StreamlitInvalidTextAlignmentError(text_alignment)
257
+
258
+
259
+ map_to_flex_terminology = {
260
+ "left": "start",
261
+ "center": "center",
262
+ "right": "end",
263
+ "top": "start",
264
+ "bottom": "end",
265
+ "distribute": "space_between",
266
+ }
267
+
268
+
269
+ def get_justify(
270
+ alignment: HorizontalAlignment | VerticalAlignment,
271
+ ) -> Block.FlexContainer.Justify.ValueType:
272
+ valid_justify = ["start", "center", "end", "space_between"]
273
+ justify = map_to_flex_terminology[alignment]
274
+ if justify not in valid_justify:
275
+ return Block.FlexContainer.Justify.JUSTIFY_UNDEFINED
276
+ if justify in {"start", "end", "center"}:
277
+ return cast(
278
+ "Block.FlexContainer.Justify.ValueType",
279
+ getattr(Block.FlexContainer.Justify, f"JUSTIFY_{justify.upper()}"),
280
+ )
281
+ return cast(
282
+ "Block.FlexContainer.Justify.ValueType",
283
+ getattr(Block.FlexContainer.Justify, f"{justify.upper()}"),
284
+ )
285
+
286
+
287
+ def get_align(
288
+ alignment: HorizontalAlignment | VerticalAlignment,
289
+ ) -> Block.FlexContainer.Align.ValueType:
290
+ valid_align = ["start", "end", "center"]
291
+ align = map_to_flex_terminology[alignment]
292
+ if align not in valid_align:
293
+ return Block.FlexContainer.Align.ALIGN_UNDEFINED
294
+ return cast(
295
+ "Block.FlexContainer.Align.ValueType",
296
+ getattr(Block.FlexContainer.Align, f"ALIGN_{align.upper()}"),
297
+ )
298
+
299
+
300
+ def get_text_alignment_config(
301
+ text_alignment: TextAlignment,
302
+ ) -> TextAlignmentConfig:
303
+ """Convert text alignment string to proto config.
304
+
305
+ Parameters
306
+ ----------
307
+ text_alignment : TextAlignment
308
+ The text alignment value ("left", "center", "right", "justify").
309
+
310
+ Returns
311
+ -------
312
+ TextAlignmentConfig
313
+ Proto message with alignment set.
314
+ """
315
+
316
+ alignment_mapping = {
317
+ "left": TextAlignmentConfig.Alignment.LEFT,
318
+ "center": TextAlignmentConfig.Alignment.CENTER,
319
+ "right": TextAlignmentConfig.Alignment.RIGHT,
320
+ "justify": TextAlignmentConfig.Alignment.JUSTIFY,
321
+ }
322
+
323
+ config = TextAlignmentConfig()
324
+ config.alignment = alignment_mapping[text_alignment]
325
+ return config
@@ -0,0 +1,73 @@
1
+ # Copyright (c) Streamlit Inc. (2018-2022) Snowflake Inc. (2022-2026)
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+
15
+ from __future__ import annotations
16
+
17
+ from typing import TYPE_CHECKING, Literal
18
+
19
+ from typing_extensions import Self
20
+
21
+ from streamlit.delta_generator import DeltaGenerator
22
+
23
+ if TYPE_CHECKING:
24
+ from types import TracebackType
25
+
26
+ from streamlit.cursor import Cursor
27
+
28
+
29
+ class ExpanderContainer(DeltaGenerator):
30
+ """DeltaGenerator subclass returned by ``st.expander``.
31
+
32
+ Provides the ``.open`` property for checking expander state when
33
+ ``on_change`` is used.
34
+ """
35
+
36
+ def __init__(
37
+ self,
38
+ root_container: int | None,
39
+ cursor: Cursor | None,
40
+ parent: DeltaGenerator | None,
41
+ block_type: str | None,
42
+ ) -> None:
43
+ super().__init__(root_container, cursor, parent, block_type)
44
+ self._open: bool | None = None
45
+
46
+ @property
47
+ def open(self) -> bool | None:
48
+ """The open/collapsed state of the expander.
49
+
50
+ Returns
51
+ -------
52
+ bool or None
53
+ ``True`` if expanded, ``False`` if collapsed, or ``None`` if
54
+ state tracking is not enabled (``on_change`` was not set or
55
+ set to ``"ignore"``).
56
+ """
57
+ return self._open
58
+
59
+ @open.setter # noqa: A003
60
+ def open(self, value: bool | None) -> None:
61
+ self._open = value
62
+
63
+ def __enter__(self) -> Self: # type: ignore[override]
64
+ super().__enter__()
65
+ return self
66
+
67
+ def __exit__(
68
+ self,
69
+ exc_type: type[BaseException] | None,
70
+ exc_val: BaseException | None,
71
+ exc_tb: TracebackType | None,
72
+ ) -> Literal[False]:
73
+ return super().__exit__(exc_type, exc_val, exc_tb)
@@ -0,0 +1,73 @@
1
+ # Copyright (c) Streamlit Inc. (2018-2022) Snowflake Inc. (2022-2026)
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+
15
+ from __future__ import annotations
16
+
17
+ from typing import TYPE_CHECKING, Literal
18
+
19
+ from typing_extensions import Self
20
+
21
+ from streamlit.delta_generator import DeltaGenerator
22
+
23
+ if TYPE_CHECKING:
24
+ from types import TracebackType
25
+
26
+ from streamlit.cursor import Cursor
27
+
28
+
29
+ class PopoverContainer(DeltaGenerator):
30
+ """DeltaGenerator subclass returned by ``st.popover``.
31
+
32
+ Provides the ``.open`` property for checking popover state when
33
+ ``on_change`` is used.
34
+ """
35
+
36
+ def __init__(
37
+ self,
38
+ root_container: int | None,
39
+ cursor: Cursor | None,
40
+ parent: DeltaGenerator | None,
41
+ block_type: str | None,
42
+ ) -> None:
43
+ super().__init__(root_container, cursor, parent, block_type)
44
+ self._open: bool | None = None
45
+
46
+ @property
47
+ def open(self) -> bool | None:
48
+ """The open/closed state of the popover.
49
+
50
+ Returns
51
+ -------
52
+ bool or None
53
+ ``True`` if open, ``False`` if closed, or ``None`` if state
54
+ tracking is not enabled (``on_change`` was not set or set to
55
+ ``"ignore"``).
56
+ """
57
+ return self._open
58
+
59
+ @open.setter # noqa: A003
60
+ def open(self, value: bool | None) -> None:
61
+ self._open = value
62
+
63
+ def __enter__(self) -> Self: # type: ignore[override]
64
+ super().__enter__()
65
+ return self
66
+
67
+ def __exit__(
68
+ self,
69
+ exc_type: type[BaseException] | None,
70
+ exc_val: BaseException | None,
71
+ exc_tb: TracebackType | None,
72
+ ) -> Literal[False]:
73
+ return super().__exit__(exc_type, exc_val, exc_tb)
@@ -0,0 +1,194 @@
1
+ # Copyright (c) Streamlit Inc. (2018-2022) Snowflake Inc. (2022-2026)
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 time
18
+ from typing import TYPE_CHECKING, Literal, TypeAlias, cast
19
+
20
+ from typing_extensions import Self
21
+
22
+ from streamlit.delta_generator import DeltaGenerator
23
+ from streamlit.elements.lib.layout_utils import (
24
+ WidthWithoutContent,
25
+ get_width_config,
26
+ validate_width,
27
+ )
28
+ from streamlit.errors import StreamlitAPIException
29
+ from streamlit.proto.Block_pb2 import Block as BlockProto
30
+ from streamlit.proto.ForwardMsg_pb2 import ForwardMsg
31
+ from streamlit.runtime.scriptrunner_utils.script_run_context import enqueue_message
32
+
33
+ if TYPE_CHECKING:
34
+ from types import TracebackType
35
+
36
+ from streamlit.cursor import Cursor
37
+
38
+ States: TypeAlias = Literal["running", "complete", "error"]
39
+
40
+
41
+ class StatusContainer(DeltaGenerator):
42
+ @staticmethod
43
+ def _create(
44
+ parent: DeltaGenerator,
45
+ label: str,
46
+ expanded: bool = False,
47
+ state: States = "running",
48
+ width: WidthWithoutContent = "stretch",
49
+ ) -> StatusContainer:
50
+ expandable_proto = BlockProto.Expandable()
51
+ expandable_proto.expanded = expanded
52
+ expandable_proto.label = label or ""
53
+
54
+ if state == "running":
55
+ expandable_proto.icon = "spinner"
56
+ elif state == "complete":
57
+ expandable_proto.icon = ":material/check:"
58
+ elif state == "error":
59
+ expandable_proto.icon = ":material/error:"
60
+ else:
61
+ raise StreamlitAPIException(
62
+ f"Unknown state ({state}). Must be one of 'running', 'complete', or 'error'."
63
+ )
64
+
65
+ block_proto = BlockProto()
66
+ block_proto.allow_empty = True
67
+ block_proto.expandable.CopyFrom(expandable_proto)
68
+
69
+ validate_width(width=width)
70
+ block_proto.width_config.CopyFrom(get_width_config(width))
71
+
72
+ delta_path: list[int] = (
73
+ parent._active_dg._cursor.delta_path if parent._active_dg._cursor else []
74
+ )
75
+
76
+ status_container = cast(
77
+ "StatusContainer",
78
+ parent._block(block_proto=block_proto, dg_type=StatusContainer),
79
+ )
80
+
81
+ # Apply initial configuration
82
+ status_container._delta_path = delta_path
83
+ status_container._current_proto = block_proto
84
+ status_container._current_state = state
85
+
86
+ # We need to sleep here for a very short time to prevent issues when
87
+ # the status is updated too quickly. If an .update() directly follows the
88
+ # the initialization, sometimes only the latest update is applied.
89
+ # Adding a short timeout here allows the frontend to render the update before.
90
+ time.sleep(0.05)
91
+
92
+ return status_container
93
+
94
+ def __init__(
95
+ self,
96
+ root_container: int | None,
97
+ cursor: Cursor | None,
98
+ parent: DeltaGenerator | None,
99
+ block_type: str | None,
100
+ ) -> None:
101
+ super().__init__(root_container, cursor, parent, block_type)
102
+
103
+ # Initialized in `_create()`:
104
+ self._current_proto: BlockProto | None = None
105
+ self._current_state: States | None = None
106
+ self._delta_path: list[int] | None = None
107
+
108
+ def update(
109
+ self,
110
+ *,
111
+ label: str | None = None,
112
+ expanded: bool | None = None,
113
+ state: States | None = None,
114
+ ) -> None:
115
+ """Update the status container.
116
+
117
+ Only specified arguments are updated. Container contents and unspecified
118
+ arguments remain unchanged.
119
+
120
+ Parameters
121
+ ----------
122
+ label : str or None
123
+ A new label of the status container. If None, the label is not
124
+ changed.
125
+
126
+ expanded : bool or None
127
+ The new expanded state of the status container. If None,
128
+ the expanded state is not changed.
129
+
130
+ state : "running", "complete", "error", or None
131
+ The new state of the status container. This mainly changes the
132
+ icon. If None, the state is not changed.
133
+ """
134
+ if self._current_proto is None or self._delta_path is None:
135
+ raise RuntimeError(
136
+ "StatusContainer is not correctly initialized. This should never happen."
137
+ )
138
+
139
+ msg = ForwardMsg()
140
+ msg.metadata.delta_path[:] = self._delta_path
141
+ msg.delta.add_block.CopyFrom(self._current_proto)
142
+
143
+ if expanded is not None:
144
+ msg.delta.add_block.expandable.expanded = expanded
145
+ else:
146
+ msg.delta.add_block.expandable.ClearField("expanded")
147
+
148
+ if label is not None:
149
+ msg.delta.add_block.expandable.label = label
150
+
151
+ if state is not None:
152
+ if state == "running":
153
+ msg.delta.add_block.expandable.icon = "spinner"
154
+ elif state == "complete":
155
+ msg.delta.add_block.expandable.icon = ":material/check:"
156
+ elif state == "error":
157
+ msg.delta.add_block.expandable.icon = ":material/error:"
158
+ else:
159
+ raise StreamlitAPIException(
160
+ f"Unknown state ({state}). Must be one of 'running', 'complete', or 'error'."
161
+ )
162
+ self._current_state = state
163
+
164
+ self._current_proto = msg.delta.add_block
165
+ enqueue_message(msg)
166
+
167
+ def __enter__(self) -> Self: # type: ignore[override]
168
+ # This is a little dubious: we're returning a different type than
169
+ # our superclass' `__enter__` function. Maybe DeltaGenerator.__enter__
170
+ # should always return `self`?
171
+ super().__enter__()
172
+ return self
173
+
174
+ def __exit__(
175
+ self,
176
+ exc_type: type[BaseException] | None,
177
+ exc_val: BaseException | None,
178
+ exc_tb: TracebackType | None,
179
+ ) -> Literal[False]:
180
+ # Only update if the current state is running
181
+ if self._current_state == "running":
182
+ # We need to sleep here for a very short time to prevent issues when
183
+ # the status is updated too quickly. If an .update() is directly followed
184
+ # by the exit of the context manager, sometimes only the last update
185
+ # (to complete) is applied. Adding a short timeout here allows the frontend
186
+ # to render the update before.
187
+ time.sleep(0.05)
188
+ if exc_type is not None:
189
+ # If an exception was raised in the context,
190
+ # we want to update the status to error.
191
+ self.update(state="error")
192
+ else:
193
+ self.update(state="complete")
194
+ return super().__exit__(exc_type, exc_val, exc_tb)