streamlit-nightly 1.29.1.dev20240108__py2.py3-none-any.whl → 1.30.1.dev20240111__py2.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 (24) hide show
  1. streamlit/commands/execution_control.py +1 -1
  2. streamlit/commands/experimental_query_params.py +5 -4
  3. streamlit/connections/snowflake_connection.py +4 -1
  4. streamlit/connections/util.py +8 -5
  5. streamlit/constants.py +17 -0
  6. streamlit/runtime/caching/cache_data_api.py +2 -2
  7. streamlit/runtime/caching/cache_resource_api.py +2 -2
  8. streamlit/runtime/forward_msg_cache.py +2 -2
  9. streamlit/runtime/memory_media_file_storage.py +2 -2
  10. streamlit/runtime/memory_uploaded_file_manager.py +3 -2
  11. streamlit/runtime/state/query_params.py +34 -14
  12. streamlit/runtime/state/session_state.py +2 -2
  13. streamlit/runtime/stats.py +24 -20
  14. streamlit/static/asset-manifest.json +2 -2
  15. streamlit/static/index.html +1 -1
  16. streamlit/static/static/js/{main.cbbf0bd5.js → main.673a9494.js} +2 -2
  17. streamlit/testing/v1/element_tree.py +7 -0
  18. {streamlit_nightly-1.29.1.dev20240108.dist-info → streamlit_nightly-1.30.1.dev20240111.dist-info}/METADATA +2 -2
  19. {streamlit_nightly-1.29.1.dev20240108.dist-info → streamlit_nightly-1.30.1.dev20240111.dist-info}/RECORD +24 -23
  20. /streamlit/static/static/js/{main.cbbf0bd5.js.LICENSE.txt → main.673a9494.js.LICENSE.txt} +0 -0
  21. {streamlit_nightly-1.29.1.dev20240108.data → streamlit_nightly-1.30.1.dev20240111.data}/scripts/streamlit.cmd +0 -0
  22. {streamlit_nightly-1.29.1.dev20240108.dist-info → streamlit_nightly-1.30.1.dev20240111.dist-info}/WHEEL +0 -0
  23. {streamlit_nightly-1.29.1.dev20240108.dist-info → streamlit_nightly-1.30.1.dev20240111.dist-info}/entry_points.txt +0 -0
  24. {streamlit_nightly-1.29.1.dev20240108.dist-info → streamlit_nightly-1.30.1.dev20240111.dist-info}/top_level.txt +0 -0
@@ -157,7 +157,7 @@ def switch_page(page: str) -> NoReturn: # type: ignore[misc]
157
157
 
158
158
  ctx.script_requests.request_rerun(
159
159
  RerunData(
160
- query_string="",
160
+ query_string=ctx.query_string,
161
161
  page_script_hash=matched_pages[0]["page_script_hash"],
162
162
  )
163
163
  )
@@ -16,15 +16,16 @@ import urllib.parse as parse
16
16
  from typing import Any, Dict, List, Union
17
17
 
18
18
  from streamlit import util
19
+ from streamlit.constants import (
20
+ EMBED_OPTIONS_QUERY_PARAM,
21
+ EMBED_QUERY_PARAM,
22
+ EMBED_QUERY_PARAMS_KEYS,
23
+ )
19
24
  from streamlit.errors import StreamlitAPIException
20
25
  from streamlit.proto.ForwardMsg_pb2 import ForwardMsg
21
26
  from streamlit.runtime.metrics_util import gather_metrics
22
27
  from streamlit.runtime.scriptrunner import get_script_run_ctx
23
28
 
24
- EMBED_QUERY_PARAM = "embed"
25
- EMBED_OPTIONS_QUERY_PARAM = "embed_options"
26
- EMBED_QUERY_PARAMS_KEYS = [EMBED_QUERY_PARAM, EMBED_OPTIONS_QUERY_PARAM]
27
-
28
29
 
29
30
  @gather_metrics("experimental_get_query_params")
30
31
  def get_query_params() -> Dict[str, List[str]]:
@@ -52,11 +52,14 @@ class SnowflakeConnection(BaseConnection["InternalSnowflakeConnection"]):
52
52
  def _connect(self, **kwargs) -> "InternalSnowflakeConnection":
53
53
  import snowflake.connector # type:ignore[import]
54
54
  from snowflake.connector import Error as SnowflakeError # type:ignore[import]
55
- from snowflake.snowpark.context import get_active_session # type:ignore[import]
56
55
 
57
56
  # If we're running in SiS, just call get_active_session() and retrieve the
58
57
  # lower-level connection from it.
59
58
  if running_in_sis():
59
+ from snowflake.snowpark.context import ( # type:ignore[import] # isort: skip
60
+ get_active_session,
61
+ )
62
+
60
63
  session = get_active_session()
61
64
 
62
65
  if hasattr(session, "connection"):
@@ -81,8 +81,11 @@ def load_from_snowsql_config_file(connection_name: str) -> Dict[str, Any]:
81
81
 
82
82
  def running_in_sis() -> bool:
83
83
  """Return whether this app is running in SiS."""
84
- from snowflake.snowpark._internal.utils import ( # type: ignore[import] # isort: skip
85
- is_in_stored_procedure,
86
- )
87
-
88
- return cast(bool, is_in_stored_procedure())
84
+ try:
85
+ from snowflake.snowpark._internal.utils import ( # type: ignore[import] # isort: skip
86
+ is_in_stored_procedure,
87
+ )
88
+
89
+ return cast(bool, is_in_stored_procedure())
90
+ except ModuleNotFoundError:
91
+ return False
streamlit/constants.py ADDED
@@ -0,0 +1,17 @@
1
+ # Copyright (c) Streamlit Inc. (2018-2022) Snowflake Inc. (2022-2024)
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
+ EMBED_QUERY_PARAM = "embed"
16
+ EMBED_OPTIONS_QUERY_PARAM = "embed_options"
17
+ EMBED_QUERY_PARAMS_KEYS = [EMBED_QUERY_PARAM, EMBED_OPTIONS_QUERY_PARAM]
@@ -60,7 +60,7 @@ from streamlit.runtime.caching.storage.dummy_cache_storage import (
60
60
  )
61
61
  from streamlit.runtime.metrics_util import gather_metrics
62
62
  from streamlit.runtime.scriptrunner.script_run_context import get_script_run_ctx
63
- from streamlit.runtime.stats import CacheStat, CacheStatsProvider
63
+ from streamlit.runtime.stats import CacheStat, CacheStatsProvider, group_stats
64
64
 
65
65
  _LOGGER = get_logger(__name__)
66
66
 
@@ -236,7 +236,7 @@ class DataCaches(CacheStatsProvider):
236
236
  stats: list[CacheStat] = []
237
237
  for cache in function_caches.values():
238
238
  stats.extend(cache.get_stats())
239
- return stats
239
+ return group_stats(stats)
240
240
 
241
241
  def validate_cache_params(
242
242
  self,
@@ -47,7 +47,7 @@ from streamlit.runtime.caching.cached_message_replay import (
47
47
  from streamlit.runtime.caching.hashing import HashFuncsDict
48
48
  from streamlit.runtime.metrics_util import gather_metrics
49
49
  from streamlit.runtime.scriptrunner.script_run_context import get_script_run_ctx
50
- from streamlit.runtime.stats import CacheStat, CacheStatsProvider
50
+ from streamlit.runtime.stats import CacheStat, CacheStatsProvider, group_stats
51
51
  from streamlit.vendor.pympler.asizeof import asizeof
52
52
 
53
53
  _LOGGER = get_logger(__name__)
@@ -131,7 +131,7 @@ class ResourceCaches(CacheStatsProvider):
131
131
  stats: list[CacheStat] = []
132
132
  for cache in function_caches.values():
133
133
  stats.extend(cache.get_stats())
134
- return stats
134
+ return group_stats(stats)
135
135
 
136
136
 
137
137
  # Singleton ResourceCaches instance
@@ -19,7 +19,7 @@ from weakref import WeakKeyDictionary
19
19
  from streamlit import config, util
20
20
  from streamlit.logger import get_logger
21
21
  from streamlit.proto.ForwardMsg_pb2 import ForwardMsg
22
- from streamlit.runtime.stats import CacheStat, CacheStatsProvider
22
+ from streamlit.runtime.stats import CacheStat, CacheStatsProvider, group_stats
23
23
  from streamlit.util import HASHLIB_KWARGS
24
24
 
25
25
  if TYPE_CHECKING:
@@ -292,4 +292,4 @@ class ForwardMsgCache(CacheStatsProvider):
292
292
  byte_length=entry.msg.ByteSize() if entry.msg is not None else 0,
293
293
  )
294
294
  )
295
- return stats
295
+ return group_stats(stats)
@@ -28,7 +28,7 @@ from streamlit.runtime.media_file_storage import (
28
28
  MediaFileStorage,
29
29
  MediaFileStorageError,
30
30
  )
31
- from streamlit.runtime.stats import CacheStat, CacheStatsProvider
31
+ from streamlit.runtime.stats import CacheStat, CacheStatsProvider, group_stats
32
32
  from streamlit.util import HASHLIB_KWARGS
33
33
 
34
34
  LOGGER = get_logger(__name__)
@@ -181,4 +181,4 @@ class MemoryMediaFileStorage(MediaFileStorage, CacheStatsProvider):
181
181
  byte_length=len(file.content),
182
182
  )
183
183
  )
184
- return stats
184
+ return group_stats(stats)
@@ -18,7 +18,7 @@ from typing import Dict, List, Sequence
18
18
 
19
19
  from streamlit import util
20
20
  from streamlit.logger import get_logger
21
- from streamlit.runtime.stats import CacheStat
21
+ from streamlit.runtime.stats import CacheStat, group_stats
22
22
  from streamlit.runtime.uploaded_file_manager import (
23
23
  UploadedFileManager,
24
24
  UploadedFileRec,
@@ -125,7 +125,7 @@ class MemoryUploadedFileManager(UploadedFileManager):
125
125
  for session_storage in file_storage_copy.values():
126
126
  all_files.extend(session_storage.values())
127
127
 
128
- return [
128
+ stats: List[CacheStat] = [
129
129
  CacheStat(
130
130
  category_name="UploadedFileManager",
131
131
  cache_name="",
@@ -133,3 +133,4 @@ class MemoryUploadedFileManager(UploadedFileManager):
133
133
  )
134
134
  for file in all_files
135
135
  ]
136
+ return group_stats(stats)
@@ -14,7 +14,9 @@
14
14
 
15
15
  from dataclasses import dataclass, field
16
16
  from typing import Dict, Iterable, Iterator, List, MutableMapping, Union
17
+ from urllib import parse
17
18
 
19
+ from streamlit.constants import EMBED_QUERY_PARAMS_KEYS
18
20
  from streamlit.errors import StreamlitAPIException
19
21
  from streamlit.proto.ForwardMsg_pb2 import ForwardMsg
20
22
 
@@ -29,7 +31,12 @@ class QueryParams(MutableMapping[str, str]):
29
31
 
30
32
  def __iter__(self) -> Iterator[str]:
31
33
  self._ensure_single_query_api_used()
32
- return iter(self._query_params.keys())
34
+
35
+ return iter(
36
+ key
37
+ for key in self._query_params.keys()
38
+ if key not in EMBED_QUERY_PARAMS_KEYS
39
+ )
33
40
 
34
41
  def __getitem__(self, key: str) -> str:
35
42
  """Retrieves a value for a given key in query parameters.
@@ -38,6 +45,8 @@ class QueryParams(MutableMapping[str, str]):
38
45
  """
39
46
  self._ensure_single_query_api_used()
40
47
  try:
48
+ if key in EMBED_QUERY_PARAMS_KEYS:
49
+ raise KeyError(missing_key_error_message(key))
41
50
  value = self._query_params[key]
42
51
  if isinstance(value, list):
43
52
  if len(value) == 0:
@@ -56,6 +65,10 @@ class QueryParams(MutableMapping[str, str]):
56
65
  f"You cannot set a query params key `{key}` to a dictionary."
57
66
  )
58
67
 
68
+ if key in EMBED_QUERY_PARAMS_KEYS:
69
+ raise StreamlitAPIException(
70
+ "Query param embed and embed_options (case-insensitive) cannot be set programmatically."
71
+ )
59
72
  # Type checking users should handle the string serialization themselves
60
73
  # We will accept any type for the list and serialize to str just in case
61
74
  if isinstance(value, Iterable) and not isinstance(value, str):
@@ -66,6 +79,8 @@ class QueryParams(MutableMapping[str, str]):
66
79
 
67
80
  def __delitem__(self, key: str) -> None:
68
81
  try:
82
+ if key in EMBED_QUERY_PARAMS_KEYS:
83
+ raise KeyError(missing_key_error_message(key))
69
84
  del self._query_params[key]
70
85
  self._send_query_param_msg()
71
86
  except KeyError:
@@ -73,18 +88,19 @@ class QueryParams(MutableMapping[str, str]):
73
88
 
74
89
  def get_all(self, key: str) -> List[str]:
75
90
  self._ensure_single_query_api_used()
76
- if key not in self._query_params:
91
+ if key not in self._query_params or key in EMBED_QUERY_PARAMS_KEYS:
77
92
  return []
78
93
  value = self._query_params[key]
79
94
  return value if isinstance(value, list) else [value]
80
95
 
81
96
  def __len__(self) -> int:
82
97
  self._ensure_single_query_api_used()
83
- return len(self._query_params)
98
+ return len(
99
+ {key for key in self._query_params if key not in EMBED_QUERY_PARAMS_KEYS}
100
+ )
84
101
 
85
102
  def _send_query_param_msg(self) -> None:
86
103
  # Avoid circular imports
87
- from streamlit.commands.experimental_query_params import _ensure_no_embed_params
88
104
  from streamlit.runtime.scriptrunner import get_script_run_ctx
89
105
 
90
106
  ctx = get_script_run_ctx()
@@ -93,27 +109,31 @@ class QueryParams(MutableMapping[str, str]):
93
109
  self._ensure_single_query_api_used()
94
110
 
95
111
  msg = ForwardMsg()
96
- msg.page_info_changed.query_string = _ensure_no_embed_params(
97
- self._query_params, ctx.query_string
112
+ msg.page_info_changed.query_string = parse.urlencode(
113
+ self._query_params, doseq=True
98
114
  )
99
115
  ctx.query_string = msg.page_info_changed.query_string
100
116
  ctx.enqueue(msg)
101
117
 
102
118
  def clear(self) -> None:
103
- self._query_params.clear()
119
+ new_query_params = {}
120
+ for key, value in self._query_params.items():
121
+ if key in EMBED_QUERY_PARAMS_KEYS:
122
+ new_query_params[key] = value
123
+ self._query_params = new_query_params
124
+
104
125
  self._send_query_param_msg()
105
126
 
106
127
  def to_dict(self) -> Dict[str, str]:
107
128
  self._ensure_single_query_api_used()
108
- # return the last query param if multiple keys are set
109
- return {key: self[key] for key in self._query_params}
129
+ # return the last query param if multiple values are set
130
+ return {
131
+ key: self[key]
132
+ for key in self._query_params
133
+ if key not in EMBED_QUERY_PARAMS_KEYS
134
+ }
110
135
 
111
136
  def set_with_no_forward_msg(self, key: str, val: Union[List[str], str]) -> None:
112
- # Avoid circular imports
113
- from streamlit.commands.experimental_query_params import EMBED_QUERY_PARAMS_KEYS
114
-
115
- if key.lower() in EMBED_QUERY_PARAMS_KEYS:
116
- return
117
137
  self._query_params[key] = val
118
138
 
119
139
  def clear_with_no_forward_msg(self) -> None:
@@ -43,7 +43,7 @@ from streamlit.runtime.state.common import (
43
43
  is_widget_id,
44
44
  )
45
45
  from streamlit.runtime.state.query_params import QueryParams
46
- from streamlit.runtime.stats import CacheStat, CacheStatsProvider
46
+ from streamlit.runtime.stats import CacheStat, CacheStatsProvider, group_stats
47
47
  from streamlit.type_util import ValueFieldName, is_array_value_field_name
48
48
  from streamlit.vendor.pympler.asizeof import asizeof
49
49
 
@@ -677,4 +677,4 @@ class SessionStateStatProvider(CacheStatsProvider):
677
677
  for session_info in self._session_mgr.list_active_sessions():
678
678
  session_state = session_info.session.session_state
679
679
  stats.extend(session_state.get_stats())
680
- return stats
680
+ return group_stats(stats)
@@ -11,7 +11,6 @@
11
11
  # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
12
  # See the License for the specific language governing permissions and
13
13
  # limitations under the License.
14
-
15
14
  import itertools
16
15
  from abc import abstractmethod
17
16
  from typing import List, NamedTuple
@@ -63,6 +62,28 @@ class CacheStat(NamedTuple):
63
62
  metric_point.gauge_value.int_value = self.byte_length
64
63
 
65
64
 
65
+ def group_stats(stats: List[CacheStat]) -> List[CacheStat]:
66
+ """Group a list of CacheStats by category_name and cache_name and sum byte_length"""
67
+
68
+ def key_function(individual_stat):
69
+ return individual_stat.category_name, individual_stat.cache_name
70
+
71
+ result: List[CacheStat] = []
72
+
73
+ sorted_stats = sorted(stats, key=key_function)
74
+ grouped_stats = itertools.groupby(sorted_stats, key=key_function)
75
+
76
+ for (category_name, cache_name), single_group_stats in grouped_stats:
77
+ result.append(
78
+ CacheStat(
79
+ category_name=category_name,
80
+ cache_name=cache_name,
81
+ byte_length=sum(map(lambda item: item.byte_length, single_group_stats)),
82
+ )
83
+ )
84
+ return result
85
+
86
+
66
87
  @runtime_checkable
67
88
  class CacheStatsProvider(Protocol):
68
89
  @abstractmethod
@@ -82,26 +103,9 @@ class StatsManager:
82
103
  self._cache_stats_providers.append(provider)
83
104
 
84
105
  def get_stats(self) -> List[CacheStat]:
85
- """Return a list containing all stats from each registered provider.
86
- Stats are grouped by category_name and cache_type."""
106
+ """Return a list containing all stats from each registered provider."""
87
107
  all_stats: List[CacheStat] = []
88
108
  for provider in self._cache_stats_providers:
89
- provider_stats = provider.get_stats()
90
- grouped_stats = itertools.groupby(
91
- provider_stats,
92
- lambda individual_stat: (
93
- individual_stat.category_name,
94
- individual_stat.cache_name,
95
- ),
96
- )
97
-
98
- for (category_name, cache_name), stats in grouped_stats:
99
- all_stats.append(
100
- CacheStat(
101
- category_name=category_name,
102
- cache_name=cache_name,
103
- byte_length=sum(map(lambda item: item.byte_length, stats)),
104
- )
105
- )
109
+ all_stats.extend(provider.get_stats())
106
110
 
107
111
  return all_stats
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "files": {
3
3
  "main.css": "./static/css/main.77d1c464.css",
4
- "main.js": "./static/js/main.cbbf0bd5.js",
4
+ "main.js": "./static/js/main.673a9494.js",
5
5
  "static/js/9336.2d95d840.chunk.js": "./static/js/9336.2d95d840.chunk.js",
6
6
  "static/js/9330.c0dd1723.chunk.js": "./static/js/9330.c0dd1723.chunk.js",
7
7
  "static/js/7217.d970c074.chunk.js": "./static/js/7217.d970c074.chunk.js",
@@ -149,6 +149,6 @@
149
149
  },
150
150
  "entrypoints": [
151
151
  "static/css/main.77d1c464.css",
152
- "static/js/main.cbbf0bd5.js"
152
+ "static/js/main.673a9494.js"
153
153
  ]
154
154
  }
@@ -1 +1 @@
1
- <!doctype html><html lang="en"><head><meta charset="UTF-8"/><meta name="viewport" content="width=device-width,initial-scale=1,shrink-to-fit=no"/><link rel="shortcut icon" href="./favicon.png"/><link rel="preload" href="./static/media/SourceSansPro-Regular.0d69e5ff5e92ac64a0c9.woff2" as="font" type="font/woff2" crossorigin><link rel="preload" href="./static/media/SourceSansPro-SemiBold.abed79cd0df1827e18cf.woff2" as="font" type="font/woff2" crossorigin><link rel="preload" href="./static/media/SourceSansPro-Bold.118dea98980e20a81ced.woff2" as="font" type="font/woff2" crossorigin><title>Streamlit</title><script>window.prerenderReady=!1</script><script defer="defer" src="./static/js/main.cbbf0bd5.js"></script><link href="./static/css/main.77d1c464.css" rel="stylesheet"></head><body><noscript>You need to enable JavaScript to run this app.</noscript><div id="root"></div></body></html>
1
+ <!doctype html><html lang="en"><head><meta charset="UTF-8"/><meta name="viewport" content="width=device-width,initial-scale=1,shrink-to-fit=no"/><link rel="shortcut icon" href="./favicon.png"/><link rel="preload" href="./static/media/SourceSansPro-Regular.0d69e5ff5e92ac64a0c9.woff2" as="font" type="font/woff2" crossorigin><link rel="preload" href="./static/media/SourceSansPro-SemiBold.abed79cd0df1827e18cf.woff2" as="font" type="font/woff2" crossorigin><link rel="preload" href="./static/media/SourceSansPro-Bold.118dea98980e20a81ced.woff2" as="font" type="font/woff2" crossorigin><title>Streamlit</title><script>window.prerenderReady=!1</script><script defer="defer" src="./static/js/main.673a9494.js"></script><link href="./static/css/main.77d1c464.css" rel="stylesheet"></head><body><noscript>You need to enable JavaScript to run this app.</noscript><div id="root"></div></body></html>