streamlit-nightly 1.34.1.dev20240522__py2.py3-none-any.whl → 1.35.1.dev20240524__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 (35) hide show
  1. streamlit/__init__.py +4 -5
  2. streamlit/commands/logo.py +61 -13
  3. streamlit/config.py +9 -15
  4. streamlit/elements/arrow.py +141 -46
  5. streamlit/elements/bokeh_chart.py +9 -5
  6. streamlit/elements/deck_gl_json_chart.py +6 -0
  7. streamlit/elements/dialog_decorator.py +5 -3
  8. streamlit/elements/graphviz_chart.py +6 -2
  9. streamlit/elements/lib/built_in_chart_utils.py +4 -4
  10. streamlit/elements/map.py +6 -2
  11. streamlit/elements/plotly_chart.py +158 -39
  12. streamlit/elements/pyplot.py +9 -4
  13. streamlit/elements/utils.py +3 -6
  14. streamlit/elements/vega_charts.py +327 -84
  15. streamlit/elements/widgets/data_editor.py +17 -8
  16. streamlit/runtime/app_session.py +3 -3
  17. streamlit/runtime/caching/__init__.py +5 -0
  18. streamlit/runtime/caching/legacy_cache_api.py +164 -0
  19. streamlit/runtime/fragment.py +91 -80
  20. streamlit/runtime/runtime.py +0 -2
  21. streamlit/static/asset-manifest.json +2 -2
  22. streamlit/static/index.html +1 -1
  23. streamlit/static/static/js/{main.7e42f54d.js → main.e93f99a3.js} +2 -2
  24. streamlit/web/cli.py +1 -8
  25. streamlit/web/server/browser_websocket_handler.py +8 -4
  26. {streamlit_nightly-1.34.1.dev20240522.dist-info → streamlit_nightly-1.35.1.dev20240524.dist-info}/METADATA +1 -1
  27. {streamlit_nightly-1.34.1.dev20240522.dist-info → streamlit_nightly-1.35.1.dev20240524.dist-info}/RECORD +32 -34
  28. streamlit/runtime/legacy_caching/__init__.py +0 -17
  29. streamlit/runtime/legacy_caching/caching.py +0 -810
  30. streamlit/runtime/legacy_caching/hashing.py +0 -1005
  31. /streamlit/static/static/js/{main.7e42f54d.js.LICENSE.txt → main.e93f99a3.js.LICENSE.txt} +0 -0
  32. {streamlit_nightly-1.34.1.dev20240522.data → streamlit_nightly-1.35.1.dev20240524.data}/scripts/streamlit.cmd +0 -0
  33. {streamlit_nightly-1.34.1.dev20240522.dist-info → streamlit_nightly-1.35.1.dev20240524.dist-info}/WHEEL +0 -0
  34. {streamlit_nightly-1.34.1.dev20240522.dist-info → streamlit_nightly-1.35.1.dev20240524.dist-info}/entry_points.txt +0 -0
  35. {streamlit_nightly-1.34.1.dev20240522.dist-info → streamlit_nightly-1.35.1.dev20240524.dist-info}/top_level.txt +0 -0
@@ -30,6 +30,7 @@ from streamlit.runtime.caching.cache_resource_api import (
30
30
  CacheResourceAPI,
31
31
  _resource_caches,
32
32
  )
33
+ from streamlit.runtime.caching.legacy_cache_api import cache as _cache
33
34
  from streamlit.runtime.state.common import WidgetMetadata
34
35
 
35
36
 
@@ -92,6 +93,9 @@ from streamlit.runtime.caching.cache_resource_api import (
92
93
  # Create and export public API singletons.
93
94
  cache_data = CacheDataAPI(decorator_metric_name="cache_data")
94
95
  cache_resource = CacheResourceAPI(decorator_metric_name="cache_resource")
96
+ # TODO(lukasmasuch): This is the legacy cache API name which is deprecated
97
+ # and it should be removed in the future.
98
+ cache = _cache
95
99
 
96
100
  # Deprecated singletons
97
101
  _MEMO_WARNING = (
@@ -115,6 +119,7 @@ experimental_singleton = CacheResourceAPI(
115
119
 
116
120
 
117
121
  __all__ = [
122
+ "cache",
118
123
  "CACHE_DOCS_URL",
119
124
  "save_element_message",
120
125
  "save_block_message",
@@ -0,0 +1,164 @@
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
+ """A library of caching utilities."""
16
+
17
+ from __future__ import annotations
18
+
19
+ from typing import TYPE_CHECKING, Any, Callable, TypeVar
20
+
21
+ from streamlit import deprecation_util
22
+ from streamlit.runtime.caching import CACHE_DOCS_URL
23
+ from streamlit.runtime.metrics_util import gather_metrics
24
+
25
+ if TYPE_CHECKING:
26
+ from streamlit.runtime.caching.hashing import HashFuncsDict
27
+
28
+ # Type-annotate the decorator function.
29
+ # (See https://mypy.readthedocs.io/en/stable/generics.html#decorator-factories)
30
+ F = TypeVar("F", bound=Callable[..., Any])
31
+
32
+
33
+ @gather_metrics("cache")
34
+ def cache(
35
+ func: F | None = None,
36
+ persist: bool = False,
37
+ allow_output_mutation: bool = False,
38
+ show_spinner: bool = True,
39
+ suppress_st_warning: bool = False,
40
+ hash_funcs: HashFuncsDict | None = None,
41
+ max_entries: int | None = None,
42
+ ttl: float | None = None,
43
+ ):
44
+ """Function decorator to memoize function executions.
45
+
46
+ Parameters
47
+ ----------
48
+ func : callable
49
+ The function to cache. Streamlit hashes the function and dependent code.
50
+
51
+ persist : bool
52
+ Whether to persist the cache on disk.
53
+
54
+ allow_output_mutation : bool
55
+ Streamlit shows a warning when return values are mutated, as that
56
+ can have unintended consequences. This is done by hashing the return value internally.
57
+
58
+ If you know what you're doing and would like to override this warning, set this to True.
59
+
60
+ show_spinner : bool
61
+ Enable the spinner. Default is True to show a spinner when there is
62
+ a cache miss.
63
+
64
+ suppress_st_warning : bool
65
+ Suppress warnings about calling Streamlit commands from within
66
+ the cached function.
67
+
68
+ hash_funcs : dict or None
69
+ Mapping of types or fully qualified names to hash functions. This is used to override
70
+ the behavior of the hasher inside Streamlit's caching mechanism: when the hasher
71
+ encounters an object, it will first check to see if its type matches a key in this
72
+ dict and, if so, will use the provided function to generate a hash for it. See below
73
+ for an example of how this can be used.
74
+
75
+ max_entries : int or None
76
+ The maximum number of entries to keep in the cache, or None
77
+ for an unbounded cache. (When a new entry is added to a full cache,
78
+ the oldest cached entry will be removed.) The default is None.
79
+
80
+ ttl : float or None
81
+ The maximum number of seconds to keep an entry in the cache, or
82
+ None if cache entries should not expire. The default is None.
83
+
84
+ Example
85
+ -------
86
+ >>> import streamlit as st
87
+ >>>
88
+ >>> @st.cache
89
+ ... def fetch_and_clean_data(url):
90
+ ... # Fetch data from URL here, and then clean it up.
91
+ ... return data
92
+ ...
93
+ >>> d1 = fetch_and_clean_data(DATA_URL_1)
94
+ >>> # Actually executes the function, since this is the first time it was
95
+ >>> # encountered.
96
+ >>>
97
+ >>> d2 = fetch_and_clean_data(DATA_URL_1)
98
+ >>> # Does not execute the function. Instead, returns its previously computed
99
+ >>> # value. This means that now the data in d1 is the same as in d2.
100
+ >>>
101
+ >>> d3 = fetch_and_clean_data(DATA_URL_2)
102
+ >>> # This is a different URL, so the function executes.
103
+
104
+ To set the ``persist`` parameter, use this command as follows:
105
+
106
+ >>> @st.cache(persist=True)
107
+ ... def fetch_and_clean_data(url):
108
+ ... # Fetch data from URL here, and then clean it up.
109
+ ... return data
110
+
111
+ To disable hashing return values, set the ``allow_output_mutation`` parameter to ``True``:
112
+
113
+ >>> @st.cache(allow_output_mutation=True)
114
+ ... def fetch_and_clean_data(url):
115
+ ... # Fetch data from URL here, and then clean it up.
116
+ ... return data
117
+
118
+
119
+ To override the default hashing behavior, pass a custom hash function.
120
+ You can do that by mapping a type (e.g. ``MongoClient``) to a hash function (``id``) like this:
121
+
122
+ >>> @st.cache(hash_funcs={MongoClient: id})
123
+ ... def connect_to_database(url):
124
+ ... return MongoClient(url)
125
+
126
+ Alternatively, you can map the type's fully-qualified name
127
+ (e.g. ``"pymongo.mongo_client.MongoClient"``) to the hash function instead:
128
+
129
+ >>> @st.cache(hash_funcs={"pymongo.mongo_client.MongoClient": id})
130
+ ... def connect_to_database(url):
131
+ ... return MongoClient(url)
132
+
133
+ """
134
+ import streamlit as st
135
+
136
+ deprecation_util.show_deprecation_warning(
137
+ f"""
138
+ `st.cache` is deprecated and will be removed soon. Please use one of Streamlit's new caching commands, `st.cache_data` or `st.cache_resource`.
139
+ More information [in our docs]({CACHE_DOCS_URL}).
140
+
141
+ **Note**: The behavior of `st.cache` was updated in Streamlit 1.36 to the new caching logic used by `st.cache_data` and `st.cache_resource`.
142
+ This might lead to some problems or unexpected behavior in certain edge cases.
143
+ """
144
+ )
145
+
146
+ # suppress_st_warning is unused since its not supported by the new caching commands
147
+
148
+ if allow_output_mutation:
149
+ return st.cache_resource( # type: ignore
150
+ func,
151
+ show_spinner=show_spinner,
152
+ hash_funcs=hash_funcs,
153
+ max_entries=max_entries,
154
+ ttl=ttl,
155
+ )
156
+
157
+ return st.cache_data( # type: ignore
158
+ func,
159
+ persist=persist,
160
+ show_spinner=show_spinner,
161
+ hash_funcs=hash_funcs,
162
+ max_entries=max_entries,
163
+ ttl=ttl,
164
+ )
@@ -93,6 +93,96 @@ class MemoryFragmentStorage(FragmentStorage):
93
93
  self._fragments.clear()
94
94
 
95
95
 
96
+ def _fragment(
97
+ func: F | None = None, *, run_every: int | float | timedelta | str | None = None
98
+ ) -> Callable[[F], F] | F:
99
+ """Contains the actual fragment logic.
100
+
101
+ This function should be used by our internal functions that use fragments under-the-hood,
102
+ so that fragment metrics are not tracked for those elements (note that the @gather_metrics annotation is only on the publicly exposed function)
103
+ """
104
+
105
+ if func is None:
106
+ # Support passing the params via function decorator
107
+ def wrapper(f: F) -> F:
108
+ return fragment(
109
+ func=f,
110
+ run_every=run_every,
111
+ )
112
+
113
+ return wrapper
114
+ else:
115
+ non_optional_func = func
116
+
117
+ @wraps(non_optional_func)
118
+ def wrap(*args, **kwargs):
119
+ from streamlit.delta_generator import dg_stack
120
+
121
+ ctx = get_script_run_ctx()
122
+ if ctx is None:
123
+ return
124
+
125
+ cursors_snapshot = deepcopy(ctx.cursors)
126
+ dg_stack_snapshot = deepcopy(dg_stack.get())
127
+ active_dg = dg_stack_snapshot[-1]
128
+ h = hashlib.new("md5")
129
+ h.update(
130
+ f"{non_optional_func.__module__}.{non_optional_func.__qualname__}{active_dg._get_delta_path_str()}".encode(
131
+ "utf-8"
132
+ )
133
+ )
134
+ fragment_id = h.hexdigest()
135
+
136
+ def wrapped_fragment():
137
+ import streamlit as st
138
+
139
+ # NOTE: We need to call get_script_run_ctx here again and can't just use the
140
+ # value of ctx from above captured by the closure because subsequent
141
+ # fragment runs will generally run in a new script run, thus we'll have a
142
+ # new ctx.
143
+ ctx = get_script_run_ctx(suppress_warning=True)
144
+ assert ctx is not None
145
+
146
+ if ctx.fragment_ids_this_run:
147
+ # This script run is a run of one or more fragments. We restore the
148
+ # state of ctx.cursors and dg_stack to the snapshots we took when this
149
+ # fragment was declared.
150
+ ctx.cursors = deepcopy(cursors_snapshot)
151
+ dg_stack.set(deepcopy(dg_stack_snapshot))
152
+ else:
153
+ # Otherwise, we must be in a full script run. We need to temporarily set
154
+ # ctx.current_fragment_id so that elements corresponding to this
155
+ # fragment get tagged with the appropriate ID. ctx.current_fragment_id
156
+ # gets reset after the fragment function finishes running.
157
+ ctx.current_fragment_id = fragment_id
158
+
159
+ try:
160
+ with st.container():
161
+ result = non_optional_func(*args, **kwargs)
162
+ finally:
163
+ ctx.current_fragment_id = None
164
+
165
+ return result
166
+
167
+ ctx.fragment_storage.set(fragment_id, wrapped_fragment)
168
+
169
+ if run_every:
170
+ msg = ForwardMsg()
171
+ msg.auto_rerun.interval = time_to_seconds(run_every)
172
+ msg.auto_rerun.fragment_id = fragment_id
173
+ ctx.enqueue(msg)
174
+
175
+ return wrapped_fragment()
176
+
177
+ with contextlib.suppress(AttributeError):
178
+ # Make this a well-behaved decorator by preserving important function
179
+ # attributes.
180
+ wrap.__dict__.update(non_optional_func.__dict__)
181
+ wrap.__signature__ = inspect.signature(non_optional_func) # type: ignore
182
+
183
+ return wrap
184
+
185
+
96
186
  @overload
97
187
  def fragment(
98
188
  func: F,
@@ -228,83 +318,4 @@ def fragment(
228
318
  height: 400px
229
319
 
230
320
  """
231
-
232
- if func is None:
233
- # Support passing the params via function decorator
234
- def wrapper(f: F) -> F:
235
- return fragment(
236
- func=f,
237
- run_every=run_every,
238
- )
239
-
240
- return wrapper
241
- else:
242
- non_optional_func = func
243
-
244
- @wraps(non_optional_func)
245
- def wrap(*args, **kwargs):
246
- from streamlit.delta_generator import dg_stack
247
-
248
- ctx = get_script_run_ctx()
249
- if ctx is None:
250
- return
251
-
252
- cursors_snapshot = deepcopy(ctx.cursors)
253
- dg_stack_snapshot = deepcopy(dg_stack.get())
254
- active_dg = dg_stack_snapshot[-1]
255
- h = hashlib.new("md5")
256
- h.update(
257
- f"{non_optional_func.__module__}.{non_optional_func.__qualname__}{active_dg._get_delta_path_str()}".encode(
258
- "utf-8"
259
- )
260
- )
261
- fragment_id = h.hexdigest()
262
-
263
- def wrapped_fragment():
264
- import streamlit as st
265
-
266
- # NOTE: We need to call get_script_run_ctx here again and can't just use the
267
- # value of ctx from above captured by the closure because subsequent
268
- # fragment runs will generally run in a new script run, thus we'll have a
269
- # new ctx.
270
- ctx = get_script_run_ctx(suppress_warning=True)
271
- assert ctx is not None
272
-
273
- if ctx.fragment_ids_this_run:
274
- # This script run is a run of one or more fragments. We restore the
275
- # state of ctx.cursors and dg_stack to the snapshots we took when this
276
- # fragment was declared.
277
- ctx.cursors = deepcopy(cursors_snapshot)
278
- dg_stack.set(deepcopy(dg_stack_snapshot))
279
- else:
280
- # Otherwise, we must be in a full script run. We need to temporarily set
281
- # ctx.current_fragment_id so that elements corresponding to this
282
- # fragment get tagged with the appropriate ID. ctx.current_fragment_id
283
- # gets reset after the fragment function finishes running.
284
- ctx.current_fragment_id = fragment_id
285
-
286
- try:
287
- with st.container():
288
- result = non_optional_func(*args, **kwargs)
289
- finally:
290
- ctx.current_fragment_id = None
291
-
292
- return result
293
-
294
- ctx.fragment_storage.set(fragment_id, wrapped_fragment)
295
-
296
- if run_every:
297
- msg = ForwardMsg()
298
- msg.auto_rerun.interval = time_to_seconds(run_every)
299
- msg.auto_rerun.fragment_id = fragment_id
300
- ctx.enqueue(msg)
301
-
302
- return wrapped_fragment()
303
-
304
- with contextlib.suppress(AttributeError):
305
- # Make this a well-behaved decorator by preserving important function
306
- # attributes.
307
- wrap.__dict__.update(non_optional_func.__dict__)
308
- wrap.__signature__ = inspect.signature(non_optional_func) # type: ignore
309
-
310
- return wrap
321
+ return _fragment(func, run_every=run_every)
@@ -40,7 +40,6 @@ from streamlit.runtime.forward_msg_cache import (
40
40
  create_reference_msg,
41
41
  populate_hash_if_needed,
42
42
  )
43
- from streamlit.runtime.legacy_caching.caching import _mem_caches
44
43
  from streamlit.runtime.media_file_manager import MediaFileManager
45
44
  from streamlit.runtime.media_file_storage import MediaFileStorage
46
45
  from streamlit.runtime.memory_session_storage import MemorySessionStorage
@@ -218,7 +217,6 @@ class Runtime:
218
217
  self._stats_mgr = StatsManager()
219
218
  self._stats_mgr.register_provider(get_data_cache_stats_provider())
220
219
  self._stats_mgr.register_provider(get_resource_cache_stats_provider())
221
- self._stats_mgr.register_provider(_mem_caches)
222
220
  self._stats_mgr.register_provider(self._message_cache)
223
221
  self._stats_mgr.register_provider(self._uploaded_file_mgr)
224
222
  self._stats_mgr.register_provider(SessionStateStatProvider(self._session_mgr))
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "files": {
3
3
  "main.css": "./static/css/main.3aaaea00.css",
4
- "main.js": "./static/js/main.7e42f54d.js",
4
+ "main.js": "./static/js/main.e93f99a3.js",
5
5
  "static/js/9336.3e046ad7.chunk.js": "./static/js/9336.3e046ad7.chunk.js",
6
6
  "static/js/9330.2b4c99e0.chunk.js": "./static/js/9330.2b4c99e0.chunk.js",
7
7
  "static/js/2736.4336e2b9.chunk.js": "./static/js/2736.4336e2b9.chunk.js",
@@ -151,6 +151,6 @@
151
151
  },
152
152
  "entrypoints": [
153
153
  "static/css/main.3aaaea00.css",
154
- "static/js/main.7e42f54d.js"
154
+ "static/js/main.e93f99a3.js"
155
155
  ]
156
156
  }
@@ -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.7e42f54d.js"></script><link href="./static/css/main.3aaaea00.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.e93f99a3.js"></script><link href="./static/css/main.3aaaea00.css" rel="stylesheet"></head><body><noscript>You need to enable JavaScript to run this app.</noscript><div id="root"></div></body></html>