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,365 @@
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 types
18
+ from pathlib import Path
19
+ from typing import TYPE_CHECKING, Literal
20
+
21
+ from streamlit.errors import StreamlitAPIException, StreamlitValueError
22
+ from streamlit.runtime.metrics_util import gather_metrics
23
+ from streamlit.runtime.scriptrunner_utils.script_run_context import get_script_run_ctx
24
+ from streamlit.source_util import page_icon_and_name
25
+ from streamlit.string_util import validate_icon_or_emoji
26
+ from streamlit.util import calc_md5
27
+
28
+ if TYPE_CHECKING:
29
+ from collections.abc import Callable
30
+
31
+
32
+ @gather_metrics("Page")
33
+ def Page( # noqa: N802
34
+ page: str | Path | Callable[[], None],
35
+ *,
36
+ title: str | None = None,
37
+ icon: str | None = None,
38
+ url_path: str | None = None,
39
+ default: bool = False,
40
+ visibility: Literal["visible", "hidden"] = "visible",
41
+ ) -> StreamlitPage:
42
+ """Configure a page for ``st.navigation`` in a multipage app.
43
+
44
+ Call ``st.Page`` to initialize a ``StreamlitPage`` object, and pass it to
45
+ ``st.navigation`` to declare a page in your app.
46
+
47
+ When a user navigates to a page, ``st.navigation`` returns the selected
48
+ ``StreamlitPage`` object. Call ``.run()`` on the returned ``StreamlitPage``
49
+ object to execute the page. You can only run the page returned by
50
+ ``st.navigation``, and you can only run it once per app rerun.
51
+
52
+ A page can be defined by a Python file or ``Callable``.
53
+
54
+ Parameters
55
+ ----------
56
+ page : str, Path, or callable
57
+ The page source as a ``Callable`` or path to a Python file. If the page
58
+ source is defined by a Python file, the path can be a string or
59
+ ``pathlib.Path`` object. Paths can be absolute or relative to the
60
+ entrypoint file. If the page source is defined by a ``Callable``, the
61
+ ``Callable`` can't accept arguments.
62
+
63
+ title : str or None
64
+ The title of the page. If this is ``None`` (default), the page title
65
+ (in the browser tab) and label (in the navigation menu) will be
66
+ inferred from the filename or callable name in ``page``. For more
67
+ information, see `Overview of multipage apps
68
+ <https://docs.streamlit.io/st.page.automatic-page-labels>`_.
69
+
70
+ The title supports GitHub-flavored Markdown. The following elements
71
+ are supported: **bold**, *italics*, ~strikethroughs~, ``inline code``,
72
+ :material/thumb_up: Material icons, and images. Unsupported elements
73
+ are unwrapped so only their text content renders.
74
+
75
+ icon : str or None
76
+ An optional emoji or icon to display next to the page title and label.
77
+ If ``icon`` is ``None`` (default), no icon is displayed next to the
78
+ page label in the navigation menu, and a Streamlit icon is displayed
79
+ next to the title (in the browser tab). If ``icon`` is a string, the
80
+ following options are valid:
81
+
82
+ - A single-character emoji. For example, you can set ``icon="🚨"``
83
+ or ``icon="🔥"``. Emoji short codes are not supported.
84
+
85
+ - An icon from the Material Symbols library (rounded style) in the
86
+ format ``":material/icon_name:"`` where "icon_name" is the name
87
+ of the icon in snake case.
88
+
89
+ For example, ``icon=":material/thumb_up:"`` will display the
90
+ Thumb Up icon. Find additional icons in the `Material Symbols \
91
+ <https://fonts.google.com/icons?icon.set=Material+Symbols&icon.style=Rounded>`_
92
+ font library.
93
+
94
+ - ``"spinner"``: Displays a spinner as an icon. In this case, the
95
+ spinner only displays next to the page label in the navigation menu.
96
+ The spinner isn't used as the page favicon next to the title in the
97
+ browser tab. The favicon is the default Streamlit icon unless
98
+ otherwise specified with the ``page_icon`` parameter of
99
+ ``st.set_page_config``.
100
+
101
+ url_path : str or None
102
+ The page's URL pathname, which is the path relative to the app's root
103
+ URL. If this is ``None`` (default), the URL pathname will be inferred
104
+ from the filename or callable name in ``page``. For more information,
105
+ see `Overview of multipage apps
106
+ <https://docs.streamlit.io/st.page.automatic-page-urls>`_.
107
+
108
+ The default page will have a pathname of ``""``, indicating the root
109
+ URL of the app. If you set ``default=True``, ``url_path`` is ignored.
110
+ ``url_path`` can't include forward slashes; paths can't include
111
+ subdirectories.
112
+
113
+ default : bool
114
+ Whether this page is the default page to be shown when the app is
115
+ loaded. If ``default`` is ``False`` (default), the page will have a
116
+ nonempty URL pathname. However, if no default page is passed to
117
+ ``st.navigation`` and this is the first page, this page will become the
118
+ default page. If ``default`` is ``True``, then the page will have
119
+ an empty pathname and ``url_path`` will be ignored.
120
+
121
+ visibility : "visible" or "hidden"
122
+ Whether the page is shown in the navigation menu. If ``"visible"``
123
+ (default), the page appears in the navigation menu. If ``"hidden"``,
124
+ the page is excluded from the navigation menu but remains accessible
125
+ via direct URL, ``st.page_link``, or ``st.switch_page``.
126
+
127
+ Returns
128
+ -------
129
+ StreamlitPage
130
+ The page object associated to the given script.
131
+
132
+ Example
133
+ -------
134
+ >>> import streamlit as st
135
+ >>>
136
+ >>> def page2():
137
+ >>> st.title("Second page")
138
+ >>>
139
+ >>> pg = st.navigation([
140
+ >>> st.Page("page1.py", title="First page", icon="🔥"),
141
+ >>> st.Page(page2, title="Second page", icon=":material/favorite:"),
142
+ >>> ])
143
+ >>> pg.run()
144
+ """
145
+ return StreamlitPage(
146
+ page,
147
+ title=title,
148
+ icon=icon,
149
+ url_path=url_path,
150
+ default=default,
151
+ visibility=visibility,
152
+ )
153
+
154
+
155
+ class StreamlitPage:
156
+ """A page within a multipage Streamlit app.
157
+
158
+ Use ``st.Page`` to initialize a ``StreamlitPage`` object.
159
+
160
+ Attributes
161
+ ----------
162
+ icon : str
163
+ The icon of the page.
164
+
165
+ If no icon was declared in ``st.Page``, this property returns ``""``.
166
+
167
+ title : str
168
+ The title of the page.
169
+
170
+ Unless declared otherwise in ``st.Page``, the page title is inferred
171
+ from the filename or callable name. For more information, see
172
+ `Overview of multipage apps
173
+ <https://docs.streamlit.io/st.page.automatic-page-labels>`_.
174
+
175
+ The title supports GitHub-flavored Markdown with restricted elements
176
+ (bold, italics, strikethroughs, inline code, Material icons, and
177
+ images).
178
+
179
+ url_path : str
180
+ The page's URL pathname, which is the path relative to the app's root
181
+ URL.
182
+
183
+ Unless declared otherwise in ``st.Page``, the URL pathname is inferred
184
+ from the filename or callable name. For more information, see
185
+ `Overview of multipage apps
186
+ <https://docs.streamlit.io/st.page.automatic-page-urls>`_.
187
+
188
+ The default page will always have a ``url_path`` of ``""`` to indicate
189
+ the root URL (e.g. homepage).
190
+
191
+ visibility : Literal["visible", "hidden"]
192
+ The visibility of the page in the navigation menu.
193
+
194
+ This property returns ``"visible"`` (default) or ``"hidden"``.
195
+ Hidden pages are not shown in the navigation menu but can still
196
+ be accessed via URL or programmatically.
197
+
198
+ """
199
+
200
+ def __init__(
201
+ self,
202
+ page: str | Path | Callable[[], None],
203
+ *,
204
+ title: str | None = None,
205
+ icon: str | None = None,
206
+ url_path: str | None = None,
207
+ default: bool = False,
208
+ visibility: Literal["visible", "hidden"] = "visible",
209
+ ) -> None:
210
+ # Must appear before the return so all pages, even if running in bare Python,
211
+ # have a _default property. This way we can always tell which script needs to run.
212
+ self._default: bool = default
213
+
214
+ # Validate and store visibility before potential early return
215
+ if visibility not in {"visible", "hidden"}:
216
+ raise StreamlitValueError("visibility", ["visible", "hidden"])
217
+ self._visibility: Literal["visible", "hidden"] = visibility
218
+
219
+ ctx = get_script_run_ctx()
220
+ if not ctx:
221
+ return
222
+
223
+ main_path = ctx.pages_manager.main_script_parent
224
+ if isinstance(page, str):
225
+ page = Path(page)
226
+ if isinstance(page, Path):
227
+ page = (main_path / page).resolve()
228
+
229
+ if not page.is_file():
230
+ raise StreamlitAPIException(
231
+ f"Unable to create Page. The file `{page.name}` could not be found."
232
+ )
233
+
234
+ inferred_name = ""
235
+ inferred_icon = ""
236
+ if isinstance(page, Path):
237
+ inferred_icon, inferred_name = page_icon_and_name(page)
238
+ elif hasattr(page, "__name__"):
239
+ inferred_name = str(page.__name__)
240
+ elif title is None:
241
+ # At this point, we know the page is not a string or a path, so it
242
+ # must be a callable. We expect it to have a __name__ attribute,
243
+ # but in special cases (e.g. a callable class instance), one may
244
+ # not exist. In that case, we should inform the user the title is
245
+ # mandatory.
246
+ raise StreamlitAPIException(
247
+ "Cannot infer page title for Callable. Set the `title=` keyword argument."
248
+ )
249
+
250
+ self._page: Path | Callable[[], None] = page
251
+ self._title: str = title or inferred_name.replace("_", " ")
252
+
253
+ if icon is not None:
254
+ # validate user provided icon.
255
+ validate_icon_or_emoji(icon)
256
+ self._icon: str = icon or inferred_icon
257
+
258
+ if self._title.strip() == "":
259
+ raise StreamlitAPIException(
260
+ "The title of the page cannot be empty or consist of underscores/spaces only"
261
+ )
262
+
263
+ self._url_path: str = inferred_name
264
+ if url_path is not None:
265
+ url_path_trimmed = url_path.strip()
266
+ stripped_url_path = url_path_trimmed.strip("/")
267
+ if stripped_url_path.strip() == "" and not default:
268
+ raise StreamlitAPIException(
269
+ "The URL path cannot be an empty string unless the page is the default page."
270
+ )
271
+
272
+ self._url_path = stripped_url_path
273
+ if "/" in self._url_path:
274
+ raise StreamlitAPIException(
275
+ "The URL path cannot contain a nested path (e.g. foo/bar)."
276
+ )
277
+
278
+ if self._icon:
279
+ validate_icon_or_emoji(self._icon)
280
+
281
+ # used by st.navigation to ordain a page as runnable
282
+ self._can_be_called: bool = False
283
+
284
+ @property
285
+ def title(self) -> str:
286
+ """The title of the page.
287
+
288
+ Unless declared otherwise in ``st.Page``, the page title is inferred
289
+ from the filename or callable name. For more information, see
290
+ `Overview of multipage apps
291
+ <https://docs.streamlit.io/st.page.automatic-page-labels>`_.
292
+
293
+ The title supports GitHub-flavored Markdown with restricted elements
294
+ (bold, italics, strikethroughs, inline code, Material icons, and
295
+ images).
296
+ """
297
+ return self._title
298
+
299
+ @property
300
+ def icon(self) -> str:
301
+ """The icon of the page.
302
+
303
+ If no icon was declared in ``st.Page``, this property returns ``""``.
304
+ """
305
+ return self._icon
306
+
307
+ @property
308
+ def url_path(self) -> str:
309
+ """The page's URL pathname, which is the path relative to the app's \
310
+ root URL.
311
+
312
+ Unless declared otherwise in ``st.Page``, the URL pathname is inferred
313
+ from the filename or callable name. For more information, see
314
+ `Overview of multipage apps
315
+ <https://docs.streamlit.io/st.page.automatic-page-urls>`_.
316
+
317
+ The default page will always have a ``url_path`` of ``""`` to indicate
318
+ the root URL (e.g. homepage).
319
+ """
320
+ return "" if self._default else self._url_path
321
+
322
+ @property
323
+ def visibility(self) -> Literal["visible", "hidden"]:
324
+ """The visibility of the page in the navigation menu.
325
+
326
+ This property returns ``"visible"`` (default) or ``"hidden"``.
327
+ Hidden pages are not shown in the navigation menu but can still
328
+ be accessed via URL or programmatically using ``st.switch_page``
329
+ or ``st.page_link``.
330
+ """
331
+ return self._visibility
332
+
333
+ def run(self) -> None:
334
+ """Execute the page.
335
+
336
+ When a page is returned by ``st.navigation``, use the ``.run()`` method
337
+ within your entrypoint file to render the page. You can only call this
338
+ method on the page returned by ``st.navigation``. You can only call
339
+ this method once per run of your entrypoint file.
340
+
341
+ """
342
+ if not self._can_be_called:
343
+ raise StreamlitAPIException(
344
+ "This page cannot be called directly. Only the page returned from st.navigation can be called once."
345
+ )
346
+
347
+ self._can_be_called = False
348
+
349
+ ctx = get_script_run_ctx()
350
+ if not ctx:
351
+ return
352
+
353
+ with ctx.run_with_active_hash(self._script_hash):
354
+ if callable(self._page):
355
+ self._page()
356
+ return
357
+ code = ctx.pages_manager.get_page_script_byte_code(str(self._page))
358
+ module = types.ModuleType("__main__")
359
+ # We want __file__ to be the string path to the script
360
+ module.__dict__["__file__"] = str(self._page)
361
+ exec(code, module.__dict__) # noqa: S102
362
+
363
+ @property
364
+ def _script_hash(self) -> str:
365
+ return calc_md5(self._url_path)
streamlit/net_util.py ADDED
@@ -0,0 +1,125 @@
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 Final
18
+
19
+ from streamlit.logger import get_logger
20
+
21
+ _LOGGER: Final = get_logger(__name__)
22
+
23
+ # URLs for checking the current machine's external IP address.
24
+ _AWS_CHECK_IP: Final = "http://checkip.amazonaws.com"
25
+ _AWS_CHECK_IP_HTTPS: Final = "https://checkip.amazonaws.com"
26
+
27
+ # URL of Streamlit's help page.
28
+ _HELP_DOC: Final = "https://docs.streamlit.io/"
29
+
30
+ _external_ip: str | None = None
31
+ _internal_ip: str | None = None
32
+
33
+
34
+ def get_external_ip() -> str | None:
35
+ """Get the *external* IP address of the current machine.
36
+
37
+ Returns
38
+ -------
39
+ string
40
+ The external IPv4 address of the current machine.
41
+
42
+ """
43
+ global _external_ip # noqa: PLW0603
44
+
45
+ if _external_ip is not None:
46
+ return _external_ip
47
+
48
+ response = _make_blocking_http_get(_AWS_CHECK_IP, timeout=5)
49
+
50
+ if response is None:
51
+ response = _make_blocking_http_get(_AWS_CHECK_IP_HTTPS, timeout=5)
52
+
53
+ if _looks_like_an_ip_address(response):
54
+ _external_ip = response
55
+ else:
56
+ _LOGGER.warning(
57
+ "Did not auto detect external IP.\nPlease go to %s for debugging hints.",
58
+ _HELP_DOC,
59
+ )
60
+ _external_ip = None
61
+
62
+ return _external_ip
63
+
64
+
65
+ def get_internal_ip() -> str | None:
66
+ """Get the *local* IP address of the current machine.
67
+
68
+ From: https://stackoverflow.com/a/28950776
69
+
70
+ Returns
71
+ -------
72
+ string
73
+ The local IPv4 address of the current machine.
74
+
75
+ """
76
+ global _internal_ip # noqa: PLW0603
77
+
78
+ if _internal_ip is not None:
79
+ return _internal_ip
80
+
81
+ import socket
82
+
83
+ with socket.socket(socket.AF_INET, socket.SOCK_DGRAM) as s:
84
+ try:
85
+ # Doesn't even have to be reachable
86
+ s.connect(("8.8.8.8", 1))
87
+ _internal_ip = s.getsockname()[0]
88
+ except Exception:
89
+ _internal_ip = "127.0.0.1"
90
+
91
+ return _internal_ip
92
+
93
+
94
+ def _make_blocking_http_get(url: str, timeout: float = 5) -> str | None:
95
+ import requests
96
+
97
+ try:
98
+ text = requests.get(url, timeout=timeout).text
99
+ if isinstance(text, str):
100
+ text = text.strip()
101
+ return text
102
+ except Exception:
103
+ return None
104
+
105
+
106
+ def _looks_like_an_ip_address(address: str | None) -> bool:
107
+ if address is None:
108
+ return False
109
+
110
+ import socket
111
+
112
+ try:
113
+ socket.inet_pton(socket.AF_INET, address)
114
+ return True # Yup, this is an IPv4 address!
115
+ except (AttributeError, OSError):
116
+ pass
117
+
118
+ try:
119
+ socket.inet_pton(socket.AF_INET6, address)
120
+ return True # Yup, this is an IPv6 address!
121
+ except (AttributeError, OSError):
122
+ pass
123
+
124
+ # Nope, this is not an IP address.
125
+ return False
@@ -0,0 +1,98 @@
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
+ """Shared path security utilities for preventing path traversal and SSRF attacks.
16
+
17
+ This module provides a centralized implementation for path validation that is
18
+ used by multiple parts of the codebase. Having a single implementation ensures
19
+ consistent security checks and avoids divergent behavior between components.
20
+
21
+ Security Context
22
+ ----------------
23
+ These checks are designed to run BEFORE any filesystem operations (like
24
+ ``os.path.realpath()``) to prevent Windows from triggering SMB connections
25
+ to attacker-controlled servers when resolving UNC paths. This prevents
26
+ SSRF attacks and NTLM hash disclosure.
27
+ """
28
+
29
+ from __future__ import annotations
30
+
31
+ import os
32
+ import string
33
+
34
+
35
+ def is_unsafe_path_pattern(path: str) -> bool:
36
+ r"""Return True if path contains UNC, absolute, drive, or traversal patterns.
37
+
38
+ This function checks for dangerous path patterns that could lead to:
39
+ - SSRF attacks via Windows UNC path resolution
40
+ - NTLM hash disclosure via SMB connections
41
+ - Path traversal outside intended directories
42
+ - Path truncation via null bytes
43
+
44
+ IMPORTANT: This check must run BEFORE any ``os.path.realpath()`` calls
45
+ to prevent Windows from triggering SMB connections to attacker-controlled
46
+ servers.
47
+
48
+ Parameters
49
+ ----------
50
+ path : str
51
+ The path string to validate.
52
+
53
+ Returns
54
+ -------
55
+ bool
56
+ True if the path contains unsafe patterns, False if it appears safe
57
+ for further processing.
58
+
59
+ Examples
60
+ --------
61
+ >>> is_unsafe_path_pattern("subdir/file.js")
62
+ False
63
+ >>> is_unsafe_path_pattern("\\\\server\\share")
64
+ True
65
+ >>> is_unsafe_path_pattern("../../../etc/passwd")
66
+ True
67
+ >>> is_unsafe_path_pattern("C:\\Windows\\system32")
68
+ True
69
+ """
70
+ # Null bytes can be used for path truncation attacks
71
+ if "\x00" in path:
72
+ return True
73
+
74
+ # UNC paths (Windows network shares, including \\?\ and \\.\ prefixes)
75
+ if path.startswith(("\\\\", "//")):
76
+ return True
77
+
78
+ # Windows drive paths (e.g. C:\, D:foo) - on Windows, os.path.realpath() on a
79
+ # drive path can trigger SMB connections if the drive is mapped to a network share.
80
+ # This enables SSRF attacks and NTLM hash disclosure. We reject all drive-qualified
81
+ # paths including drive-relative paths like "C:foo" which resolve against the current
82
+ # directory of that drive. Checked on all platforms for defense-in-depth and
83
+ # testability (CI runs on Linux).
84
+ if len(path) >= 2 and path[0] in string.ascii_letters and path[1] == ":":
85
+ return True
86
+
87
+ # Rooted backslash or forward slash (absolute paths)
88
+ if path.startswith(("\\", "/")):
89
+ return True
90
+
91
+ # Also check os.path.isabs for platform-specific absolute path detection
92
+ if os.path.isabs(path):
93
+ return True
94
+
95
+ # Path traversal - check segments after normalizing separators
96
+ normalized = path.replace("\\", "/")
97
+ segments = [seg for seg in normalized.split("/") if seg]
98
+ return ".." in segments
streamlit/platform.py ADDED
@@ -0,0 +1,31 @@
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
+ """Platform module."""
16
+
17
+ from __future__ import annotations
18
+
19
+ from streamlit.proto.ForwardMsg_pb2 import ForwardMsg
20
+ from streamlit.runtime.scriptrunner_utils.script_run_context import get_script_run_ctx
21
+
22
+
23
+ def post_parent_message(message: str) -> None:
24
+ """Sends a string message to the parent window (when host configuration allows)."""
25
+ ctx = get_script_run_ctx()
26
+ if ctx is None:
27
+ return
28
+
29
+ fwd_msg = ForwardMsg()
30
+ fwd_msg.parent_message.message = message
31
+ ctx.enqueue(fwd_msg)
@@ -0,0 +1,28 @@
1
+ # -*- coding: utf-8 -*-
2
+ # Generated by the protocol buffer compiler. DO NOT EDIT!
3
+ # source: streamlit/proto/Alert.proto
4
+ """Generated protocol buffer code."""
5
+ from google.protobuf.internal import builder as _builder
6
+ from google.protobuf import descriptor as _descriptor
7
+ from google.protobuf import descriptor_pool as _descriptor_pool
8
+ from google.protobuf import symbol_database as _symbol_database
9
+ # @@protoc_insertion_point(imports)
10
+
11
+ _sym_db = _symbol_database.Default()
12
+
13
+
14
+ from streamlit.proto import WidthConfig_pb2 as streamlit_dot_proto_dot_WidthConfig__pb2
15
+
16
+
17
+ DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x1bstreamlit/proto/Alert.proto\x1a!streamlit/proto/WidthConfig.proto\"\xb5\x01\n\x05\x41lert\x12\x0c\n\x04\x62ody\x18\x01 \x01(\t\x12\x1d\n\x06\x66ormat\x18\x02 \x01(\x0e\x32\r.Alert.Format\x12\x0c\n\x04icon\x18\x03 \x01(\t\x12,\n\x0cwidth_config\x18\x04 \x01(\x0b\x32\x16.streamlit.WidthConfig\"C\n\x06\x46ormat\x12\n\n\x06UNUSED\x10\x00\x12\t\n\x05\x45RROR\x10\x01\x12\x0b\n\x07WARNING\x10\x02\x12\x08\n\x04INFO\x10\x03\x12\x0b\n\x07SUCCESS\x10\x04\x62\x06proto3')
18
+
19
+ _builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, globals())
20
+ _builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'streamlit.proto.Alert_pb2', globals())
21
+ if _descriptor._USE_C_DESCRIPTORS == False:
22
+
23
+ DESCRIPTOR._options = None
24
+ _ALERT._serialized_start=67
25
+ _ALERT._serialized_end=248
26
+ _ALERT_FORMAT._serialized_start=181
27
+ _ALERT_FORMAT._serialized_end=248
28
+ # @@protoc_insertion_point(module_scope)