streamlit 1.47.1__py3-none-any.whl → 1.48.1__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (193) hide show
  1. streamlit/cli_util.py +1 -1
  2. streamlit/commands/echo.py +2 -2
  3. streamlit/commands/execution_control.py +1 -1
  4. streamlit/commands/page_config.py +16 -16
  5. streamlit/components/v1/component_arrow.py +4 -4
  6. streamlit/config.py +23 -5
  7. streamlit/connections/base_connection.py +2 -2
  8. streamlit/connections/snowflake_connection.py +2 -2
  9. streamlit/connections/sql_connection.py +4 -3
  10. streamlit/dataframe_util.py +1 -1
  11. streamlit/deprecation_util.py +20 -5
  12. streamlit/elements/arrow.py +105 -79
  13. streamlit/elements/deck_gl_json_chart.py +6 -6
  14. streamlit/elements/dialog_decorator.py +72 -17
  15. streamlit/elements/form.py +36 -7
  16. streamlit/elements/graphviz_chart.py +7 -0
  17. streamlit/elements/iframe.py +13 -22
  18. streamlit/elements/json.py +3 -3
  19. streamlit/elements/layouts.py +241 -75
  20. streamlit/elements/lib/built_in_chart_utils.py +11 -3
  21. streamlit/elements/lib/dialog.py +43 -0
  22. streamlit/elements/lib/file_uploader_utils.py +21 -2
  23. streamlit/elements/lib/layout_utils.py +88 -2
  24. streamlit/elements/lib/options_selector_utils.py +1 -1
  25. streamlit/elements/lib/utils.py +23 -3
  26. streamlit/elements/map.py +12 -11
  27. streamlit/elements/plotly_chart.py +21 -21
  28. streamlit/elements/pyplot.py +8 -4
  29. streamlit/elements/vega_charts.py +237 -143
  30. streamlit/elements/widgets/audio_input.py +2 -2
  31. streamlit/elements/widgets/button.py +147 -35
  32. streamlit/elements/widgets/button_group.py +9 -8
  33. streamlit/elements/widgets/camera_input.py +2 -2
  34. streamlit/elements/widgets/chat.py +8 -2
  35. streamlit/elements/widgets/checkbox.py +4 -4
  36. streamlit/elements/widgets/color_picker.py +2 -2
  37. streamlit/elements/widgets/data_editor.py +22 -15
  38. streamlit/elements/widgets/file_uploader.py +8 -2
  39. streamlit/elements/widgets/multiselect.py +27 -17
  40. streamlit/elements/widgets/number_input.py +2 -2
  41. streamlit/elements/widgets/radio.py +5 -4
  42. streamlit/elements/widgets/select_slider.py +8 -5
  43. streamlit/elements/widgets/selectbox.py +14 -4
  44. streamlit/elements/widgets/slider.py +59 -33
  45. streamlit/elements/widgets/text_widgets.py +4 -4
  46. streamlit/elements/widgets/time_widgets.py +4 -4
  47. streamlit/elements/write.py +9 -8
  48. streamlit/env_util.py +1 -1
  49. streamlit/errors.py +20 -4
  50. streamlit/file_util.py +1 -1
  51. streamlit/git_util.py +1 -1
  52. streamlit/logger.py +2 -2
  53. streamlit/proto/Block_pb2.py +39 -31
  54. streamlit/proto/Block_pb2.pyi +54 -3
  55. streamlit/proto/Button_pb2.py +4 -2
  56. streamlit/proto/Button_pb2.pyi +1 -0
  57. streamlit/proto/IFrame_pb2.py +8 -2
  58. streamlit/proto/IFrame_pb2.pyi +3 -0
  59. streamlit/runtime/caching/cache_data_api.py +15 -2
  60. streamlit/runtime/caching/cache_errors.py +1 -1
  61. streamlit/runtime/caching/cache_resource_api.py +24 -2
  62. streamlit/runtime/caching/cache_utils.py +6 -3
  63. streamlit/runtime/caching/hashing.py +6 -9
  64. streamlit/runtime/fragment.py +3 -2
  65. streamlit/runtime/runtime.py +19 -2
  66. streamlit/runtime/scriptrunner/script_runner.py +3 -3
  67. streamlit/runtime/state/common.py +2 -1
  68. streamlit/runtime/state/query_params.py +2 -1
  69. streamlit/runtime/state/session_state.py +1 -1
  70. streamlit/static/index.html +1 -1
  71. streamlit/static/manifest.json +231 -231
  72. streamlit/static/static/css/index.CQt5TjGB.css +1 -0
  73. streamlit/static/static/js/{ErrorOutline.esm.BEZPMjuG.js → ErrorOutline.esm.DjObtx4K.js} +1 -1
  74. streamlit/static/static/js/{FileDownload.esm.Dy1V9a2E.js → FileDownload.esm.Bz9nxNC5.js} +1 -1
  75. streamlit/static/static/js/{FileHelper.D0K06YBq.js → FileHelper.BrQvUXVD.js} +1 -1
  76. streamlit/static/static/js/{FormClearHelper.Cdw5Y7_m.js → FormClearHelper.DF4gFAOO.js} +1 -1
  77. streamlit/static/static/js/{Hooks.C_qx1sSw.js → Hooks.DEoLCfOE.js} +1 -1
  78. streamlit/static/static/js/{InputInstructions.D3IDU-eY.js → InputInstructions.D8zoMog9.js} +1 -1
  79. streamlit/static/static/js/Particles.CCFySwdL.js +1 -0
  80. streamlit/static/static/js/ProgressBar.COK9j1l0.js +2 -0
  81. streamlit/static/static/js/Toolbar.Dt4jIKlY.js +1 -0
  82. streamlit/static/static/js/{base-input.DMlw5p7n.js → base-input.BmvSaPd2.js} +4 -4
  83. streamlit/static/static/js/{checkbox.C7QR6llE.js → checkbox.Cgxgc0et.js} +2 -2
  84. streamlit/static/static/js/createDownloadLinkElement.ZaXNnPK4.js +1 -0
  85. streamlit/static/static/js/{createSuper.C5k_2vfB.js → createSuper.siQeagI2.js} +1 -1
  86. streamlit/static/static/js/data-grid-overlay-editor.Ct51iCb_.js +1 -0
  87. streamlit/static/static/js/{downloader.Nj6v3ioB.js → downloader.M6jQeNDf.js} +1 -1
  88. streamlit/static/static/js/{es6.CVz13CSz.js → es6.CMaUdEZ5.js} +2 -2
  89. streamlit/static/static/js/{iframeResizer.contentWindow.gZ8zjT0K.js → iframeResizer.contentWindow.C33BryyP.js} +1 -1
  90. streamlit/static/static/js/index.8GJD0eeD.js +1 -0
  91. streamlit/static/static/js/index.8QEYHMQD.js +1 -0
  92. streamlit/static/static/js/index.Ay41Wnu9.js +1 -0
  93. streamlit/static/static/js/index.BLiKiJ7_.js +1 -0
  94. streamlit/static/static/js/index.BT78cJmU.js +1 -0
  95. streamlit/static/static/js/index.BXDq9dj4.js +1 -0
  96. streamlit/static/static/js/index.BdGvnhlM.js +1 -0
  97. streamlit/static/static/js/index.BfasrT0d.js +1 -0
  98. streamlit/static/static/js/index.CCdtFMFG.js +1 -0
  99. streamlit/static/static/js/index.CFRGZDz1.js +1 -0
  100. streamlit/static/static/js/{index.MbqsiUV4.js → index.CFSFYiPA.js} +289 -289
  101. streamlit/static/static/js/{index.B2L574n6.js → index.CbdWnLqS.js} +3 -3
  102. streamlit/static/static/js/index.CeiIiXap.js +1 -0
  103. streamlit/static/static/js/index.CgZDfhN4.js +2 -0
  104. streamlit/static/static/js/{index.xfcNJBLM.js → index.Cqa4gqqN.js} +1 -1
  105. streamlit/static/static/js/index.CzX2xpyc.js +1 -0
  106. streamlit/static/static/js/index.D1EayrNh.js +73 -0
  107. streamlit/static/static/js/index.D1ErX5go.js +2 -0
  108. streamlit/static/static/js/{index.CTT2YqEU.js → index.D1jHqUJq.js} +1 -1
  109. streamlit/static/static/js/index.D5gweoL5.js +7 -0
  110. streamlit/static/static/js/index.DByVKZgq.js +1 -0
  111. streamlit/static/static/js/index.DEND45D1.js +3 -0
  112. streamlit/static/static/js/{index.CbQtRkVt.js → index.DKN5MVff.js} +162 -188
  113. streamlit/static/static/js/index.DfoxW1gP.js +3855 -0
  114. streamlit/static/static/js/index.Dtf1Ac0x.js +1 -0
  115. streamlit/static/static/js/index.DxrLhpeO.js +1 -0
  116. streamlit/static/static/js/{index.BSFzxMXi.js → index.J7o-_HIh.js} +1 -1
  117. streamlit/static/static/js/index.LU8juINp.js +197 -0
  118. streamlit/static/static/js/index.L_N2iylt.js +1 -0
  119. streamlit/static/static/js/{index.BscWuWHL.js → index.PZUX2kRz.js} +3 -3
  120. streamlit/static/static/js/index.ROjU6K0k.js +1 -0
  121. streamlit/static/static/js/index.WSNLkF94.js +1 -0
  122. streamlit/static/static/js/index.X5W3gJLn.js +1 -0
  123. streamlit/static/static/js/index.k9LYqfSL.js +1 -0
  124. streamlit/static/static/js/{index.D3wOJJsg.js → index.pnHtHv_c.js} +12 -12
  125. streamlit/static/static/js/index.tPUXqsfW.js +1 -0
  126. streamlit/static/static/js/index.tsvTLdio.js +12 -0
  127. streamlit/static/static/js/{input.D_45B0P-.js → input.DZd6EQlV.js} +2 -2
  128. streamlit/static/static/js/{memory.BmhrRyO2.js → memory.ptkfuI71.js} +1 -1
  129. streamlit/static/static/js/{mergeWith.DvOME7eH.js → mergeWith.GRNk8iwv.js} +1 -1
  130. streamlit/static/static/js/{number-overlay-editor.BRNxOzEZ.js → number-overlay-editor.DXS2qb1U.js} +1 -1
  131. streamlit/static/static/js/{possibleConstructorReturn.C5GiK_Ob.js → possibleConstructorReturn.Bd4ImlQ9.js} +1 -1
  132. streamlit/static/static/js/{sandbox.B-Q9S7vW.js → sandbox.DsH8LuID.js} +1 -1
  133. streamlit/static/static/js/{timepicker.DOMbfm_a.js → timepicker.QVekV78C.js} +1 -1
  134. streamlit/static/static/js/{toConsumableArray.CbNz0Ciu.js → toConsumableArray.BJvaP8gb.js} +1 -1
  135. streamlit/static/static/js/{uniqueId.-ygIU7IL.js → uniqueId.D_5M8Dgf.js} +1 -1
  136. streamlit/static/static/js/{useBasicWidgetState.Bx3VaRHk.js → useBasicWidgetState.DB3vMS9V.js} +1 -1
  137. streamlit/static/static/js/useTextInputAutoExpand.CBkGkaRt.js +2 -0
  138. streamlit/static/static/js/useUpdateUiValue.C7ZKpLQK.js +1 -0
  139. streamlit/static/static/js/withFullScreenWrapper.C-gXt0Rl.js +1 -0
  140. streamlit/temporary_directory.py +5 -3
  141. streamlit/testing/v1/app_test.py +4 -1
  142. streamlit/testing/v1/element_tree.py +4 -5
  143. streamlit/type_util.py +10 -3
  144. streamlit/user_info.py +6 -1
  145. streamlit/util.py +11 -1
  146. streamlit/watcher/local_sources_watcher.py +4 -3
  147. streamlit/web/bootstrap.py +18 -12
  148. streamlit/web/cli.py +2 -1
  149. streamlit/web/server/server.py +72 -21
  150. {streamlit-1.47.1.dist-info → streamlit-1.48.1.dist-info}/METADATA +14 -2
  151. {streamlit-1.47.1.dist-info → streamlit-1.48.1.dist-info}/RECORD +155 -155
  152. streamlit/static/static/css/index.CsLB_Bnz.css +0 -1
  153. streamlit/static/static/js/ProgressBar.EhJ_lCOf.js +0 -2
  154. streamlit/static/static/js/RenderInPortalIfExists.D6a0mMll.js +0 -1
  155. streamlit/static/static/js/Toolbar.D6yqQ65-.js +0 -1
  156. streamlit/static/static/js/createDownloadLinkElement.DZMwyjvU.js +0 -1
  157. streamlit/static/static/js/data-grid-overlay-editor.CoquyZNK.js +0 -1
  158. streamlit/static/static/js/index.B3n-pURl.js +0 -2
  159. streamlit/static/static/js/index.B9jJp9aE.js +0 -1
  160. streamlit/static/static/js/index.BBVtld-D.js +0 -1
  161. streamlit/static/static/js/index.BKHPnvYd.js +0 -1
  162. streamlit/static/static/js/index.B_1CXynz.js +0 -1
  163. streamlit/static/static/js/index.Bm1LklYO.js +0 -1
  164. streamlit/static/static/js/index.Byi6__iF.js +0 -1
  165. streamlit/static/static/js/index.BzJeMpQ-.js +0 -197
  166. streamlit/static/static/js/index.C4tw7-Cl.js +0 -2
  167. streamlit/static/static/js/index.CG0C49ex.js +0 -1
  168. streamlit/static/static/js/index.CMuSJPv-.js +0 -1
  169. streamlit/static/static/js/index.COPFcr_K.js +0 -3855
  170. streamlit/static/static/js/index.CU3TLDlu.js +0 -1
  171. streamlit/static/static/js/index.CVKKDwaf.js +0 -1
  172. streamlit/static/static/js/index.CWZeK3mV.js +0 -12
  173. streamlit/static/static/js/index.CWbiNJQl.js +0 -1
  174. streamlit/static/static/js/index.CWxefYP6.js +0 -73
  175. streamlit/static/static/js/index.DOdWa88b.js +0 -1
  176. streamlit/static/static/js/index.DXtnaPua.js +0 -1
  177. streamlit/static/static/js/index.DatDwFl3.js +0 -3
  178. streamlit/static/static/js/index.DeWYPvQR.js +0 -1
  179. streamlit/static/static/js/index.Do4vzIvK.js +0 -1
  180. streamlit/static/static/js/index.Dvrstlh8.js +0 -1
  181. streamlit/static/static/js/index.DvznfdF_.js +0 -1
  182. streamlit/static/static/js/index.U1vvXeGn.js +0 -1
  183. streamlit/static/static/js/index._WAuWRkp.js +0 -7
  184. streamlit/static/static/js/index.bwA9_eWC.js +0 -1
  185. streamlit/static/static/js/index.m1njXuKl.js +0 -1
  186. streamlit/static/static/js/index.mihWZKb1.js +0 -1
  187. streamlit/static/static/js/useOnInputChange.CDZx-L6q.js +0 -1
  188. streamlit/static/static/js/useTextInputAutoExpand.BuE9l5TG.js +0 -2
  189. streamlit/static/static/js/withFullScreenWrapper.DWXejOhQ.js +0 -1
  190. {streamlit-1.47.1.data → streamlit-1.48.1.data}/scripts/streamlit.cmd +0 -0
  191. {streamlit-1.47.1.dist-info → streamlit-1.48.1.dist-info}/WHEEL +0 -0
  192. {streamlit-1.47.1.dist-info → streamlit-1.48.1.dist-info}/entry_points.txt +0 -0
  193. {streamlit-1.47.1.dist-info → streamlit-1.48.1.dist-info}/top_level.txt +0 -0
@@ -335,23 +335,29 @@ def run(
335
335
  # by a debug websocket session.
336
336
  await server.stopped
337
337
 
338
- # Run the server. This function will not return until the server is shut down.
339
- # FIX RuntimeError: asyncio.run() cannot be called from a running event loop
340
- # asyncio.run(run_server()) # noqa: ERA001
341
-
342
338
  # Define a main function to handle the event loop logic
343
339
  async def main() -> None:
344
340
  await run_server()
345
341
 
342
+ # Handle running in existing event loop vs creating new one
343
+ running_in_event_loop = False
346
344
  try:
347
345
  # Check if we're already in an event loop
348
- if asyncio.get_running_loop().is_running():
349
- # Use `asyncio.create_task` if we're in an async context
350
- # TODO(lukasmasuch): Do we have to store a reference for the task here?
351
- asyncio.create_task(main()) # noqa: RUF006
352
- else:
353
- # Otherwise, use `asyncio.run`
354
- asyncio.run(main())
346
+ asyncio.get_running_loop()
347
+ running_in_event_loop = True
355
348
  except RuntimeError:
356
- # get_running_loop throws RuntimeError if no running event loop
349
+ # No running event loop - this is expected for normal CLI usage
350
+ pass
351
+
352
+ if running_in_event_loop:
353
+ _LOGGER.debug("Running server in existing event loop.")
354
+ # We're in an existing event loop.
355
+ task = asyncio.create_task(main(), name="bootstrap.run_server")
356
+ # Store task reference on the server to keep it alive
357
+ # This prevents the task from being garbage collected
358
+ server._bootstrap_task = task
359
+ else:
360
+ # No running event loop, so we can use asyncio.run
361
+ # This is the normal case when running streamlit from the command line
362
+ _LOGGER.debug("Starting new event loop for server")
357
363
  asyncio.run(main())
streamlit/web/cli.py CHANGED
@@ -114,13 +114,14 @@ def configurator_options(func: F) -> F:
114
114
  def _download_remote(main_script_path: str, url_path: str) -> None:
115
115
  """Fetch remote file at url_path to main_script_path."""
116
116
  import requests
117
+ from requests.exceptions import RequestException
117
118
 
118
119
  with open(main_script_path, "wb") as fp:
119
120
  try:
120
121
  resp = requests.get(url_path, timeout=30)
121
122
  resp.raise_for_status()
122
123
  fp.write(resp.content)
123
- except requests.exceptions.RequestException as e:
124
+ except RequestException as e:
124
125
  raise click.BadParameter(f"Unable to fetch {url_path}.\n{e}")
125
126
 
126
127
 
@@ -22,11 +22,7 @@ import sys
22
22
  from pathlib import Path
23
23
  from typing import TYPE_CHECKING, Any, Final
24
24
 
25
- import tornado.concurrent
26
- import tornado.locks
27
- import tornado.netutil
28
25
  import tornado.web
29
- import tornado.websocket
30
26
  from tornado.httpserver import HTTPServer
31
27
 
32
28
  from streamlit import cli_util, config, file_util, util
@@ -62,25 +58,67 @@ from streamlit.web.server.stats_request_handler import StatsRequestHandler
62
58
  from streamlit.web.server.upload_file_request_handler import UploadFileRequestHandler
63
59
 
64
60
  if TYPE_CHECKING:
61
+ import asyncio
65
62
  from collections.abc import Awaitable
66
63
  from ssl import SSLContext
67
64
 
68
65
  _LOGGER: Final = get_logger(__name__)
69
66
 
70
- TORNADO_SETTINGS = {
71
- # Gzip HTTP responses.
72
- "compress_response": True,
73
- # Ping every 30s to keep WS alive.
74
- # With recent versions of Tornado, this value must be greater than or
75
- # equal to websocket_ping_timeout.
76
- # For details, see https://github.com/tornadoweb/tornado/pull/3376
77
- # For compatibility with older versions of Tornado, we set the value to 1.
78
- "websocket_ping_interval": 1 if is_tornado_version_less_than("6.5.0") else 30,
79
- # If we don't get a ping response within 30s, the connection
80
- # is timed out.
81
- "websocket_ping_timeout": 30,
82
- "xsrf_cookie_name": "_streamlit_xsrf",
83
- }
67
+
68
+ def _get_websocket_ping_interval_and_timeout() -> tuple[int, int]:
69
+ """Get the websocket ping interval and timeout from config or defaults.
70
+
71
+ Returns
72
+ -------
73
+ tuple: (ping_interval, ping_timeout)
74
+ """
75
+ configured_interval = config.get_option("server.websocketPingInterval")
76
+
77
+ if configured_interval is not None:
78
+ # User has explicitly set a value
79
+ interval = int(configured_interval)
80
+
81
+ # Warn if using Tornado 6.5+ with low interval
82
+ if not is_tornado_version_less_than("6.5.0") and interval < 30:
83
+ _LOGGER.warning(
84
+ "You have set server.websocketPingInterval to %s, but Tornado >= 6.5 "
85
+ "requires websocket_ping_interval >= websocket_ping_timeout. "
86
+ "To comply, we are setting both the ping interval and ping timeout to %s. "
87
+ "Depending on the specific deployment setup, this may cause connection issues.",
88
+ interval,
89
+ interval,
90
+ )
91
+
92
+ # When user configures interval, set timeout to match
93
+ return interval, interval
94
+
95
+ # Default behavior: respect Tornado version for interval, always 30s timeout
96
+ default_interval = 1 if is_tornado_version_less_than("6.5.0") else 30
97
+ return default_interval, 30
98
+
99
+
100
+ def get_tornado_settings() -> dict[str, Any]:
101
+ """Get Tornado settings for the server.
102
+
103
+ This is a function to allow for testing and dynamic configuration.
104
+ """
105
+ ping_interval, ping_timeout = _get_websocket_ping_interval_and_timeout()
106
+
107
+ return {
108
+ # Gzip HTTP responses.
109
+ "compress_response": True,
110
+ # Ping interval for websocket keepalive.
111
+ # With recent versions of Tornado, this value must be greater than or
112
+ # equal to websocket_ping_timeout.
113
+ # For details, see https://github.com/tornadoweb/tornado/pull/3376
114
+ # For compatibility with older versions of Tornado, we set the value to 1.
115
+ "websocket_ping_interval": ping_interval,
116
+ # If we don't get a ping response within this time, the connection
117
+ # is timed out.
118
+ "websocket_ping_timeout": ping_timeout,
119
+ "xsrf_cookie_name": "_streamlit_xsrf",
120
+ }
121
+
84
122
 
85
123
  # When server.port is not available it will look for the next available port
86
124
  # up to MAX_PORT_SEARCH_RETRIES.
@@ -191,8 +229,16 @@ def start_listening_unix_socket(http_server: HTTPServer) -> None:
191
229
  address = config.get_option("server.address")
192
230
  file_name = os.path.expanduser(address[len(UNIX_SOCKET_PREFIX) :])
193
231
 
194
- unix_socket = tornado.netutil.bind_unix_socket(file_name)
195
- http_server.add_socket(unix_socket)
232
+ import tornado.netutil
233
+
234
+ if hasattr(tornado.netutil, "bind_unix_socket"):
235
+ unix_socket = tornado.netutil.bind_unix_socket(file_name)
236
+ http_server.add_socket(unix_socket)
237
+ else:
238
+ _LOGGER.error(
239
+ "Unix socket support is not available in this version of Tornado."
240
+ )
241
+ sys.exit(1)
196
242
 
197
243
 
198
244
  def start_listening_tcp_socket(http_server: HTTPServer) -> None:
@@ -240,6 +286,11 @@ class Server:
240
286
 
241
287
  self._main_script_path = main_script_path
242
288
 
289
+ # The task that runs the server if an event loop is already running.
290
+ # We need to save a reference to it so that it doesn't get
291
+ # garbage collected while running.
292
+ self._bootstrap_task: asyncio.Task[None] | None = None
293
+
243
294
  # Initialize MediaFileStorage and its associated endpoint
244
295
  media_file_storage = MemoryMediaFileStorage(MEDIA_ENDPOINT)
245
296
  MediaFileHandler.initialize_storage(media_file_storage)
@@ -440,7 +491,7 @@ class Server:
440
491
  xsrf_cookies=is_xsrf_enabled(),
441
492
  # Set the websocket message size. The default value is too low.
442
493
  websocket_max_message_size=get_max_message_size_bytes(),
443
- **TORNADO_SETTINGS, # type: ignore[arg-type]
494
+ **get_tornado_settings(),
444
495
  )
445
496
 
446
497
  @property
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: streamlit
3
- Version: 1.47.1
3
+ Version: 1.48.1
4
4
  Summary: A faster way to build and share data apps
5
5
  Home-page: https://streamlit.io
6
6
  Author: Snowflake Inc
@@ -31,7 +31,7 @@ Classifier: Topic :: Software Development :: Libraries :: Application Frameworks
31
31
  Classifier: Topic :: Software Development :: Widget Sets
32
32
  Requires-Python: >=3.9, !=3.9.7
33
33
  Description-Content-Type: text/markdown
34
- Requires-Dist: altair<6,>=4.0
34
+ Requires-Dist: altair!=5.4.0,!=5.4.1,<6,>=4.0
35
35
  Requires-Dist: blinker<2,>=1.5.0
36
36
  Requires-Dist: cachetools<7,>=4.0
37
37
  Requires-Dist: click<9,>=7.0
@@ -52,6 +52,18 @@ Requires-Dist: tornado!=6.5.0,<7,>=6.0.3
52
52
  Provides-Extra: snowflake
53
53
  Requires-Dist: snowflake-snowpark-python[modin]>=1.17.0; python_version < "3.12" and extra == "snowflake"
54
54
  Requires-Dist: snowflake-connector-python>=3.3.0; python_version < "3.12" and extra == "snowflake"
55
+ Provides-Extra: auth
56
+ Requires-Dist: Authlib>=1.3.2; extra == "auth"
57
+ Provides-Extra: charts
58
+ Requires-Dist: matplotlib>=3.0.0; extra == "charts"
59
+ Requires-Dist: graphviz>=0.19.0; extra == "charts"
60
+ Requires-Dist: plotly>=4.0.0; extra == "charts"
61
+ Requires-Dist: orjson>=3.5.0; extra == "charts"
62
+ Provides-Extra: sql
63
+ Requires-Dist: SQLAlchemy>=2.0.0; extra == "sql"
64
+ Provides-Extra: all
65
+ Requires-Dist: streamlit[auth,charts,snowflake,sql]; extra == "all"
66
+ Requires-Dist: rich>=11.0.0; extra == "all"
55
67
  Dynamic: author
56
68
  Dynamic: author-email
57
69
  Dynamic: classifier