solara-ui 1.45.0__py3-none-any.whl → 1.47.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.
solara/__init__.py CHANGED
@@ -1,6 +1,6 @@
1
1
  """Build webapps using IPywidgets"""
2
2
 
3
- __version__ = "1.45.0"
3
+ __version__ = "1.47.0"
4
4
  github_url = "https://github.com/widgetti/solara"
5
5
  git_branch = "master"
6
6
 
@@ -145,7 +145,7 @@ def ColumnsResponsive(
145
145
 
146
146
  class_ = _combine_classes([*(["flex-nowrap"] if not wrap else []), *classes])
147
147
  style_flat = solara.util._flatten_style(style)
148
- with rv.Row(class_=class_ if not wrap else "", style_=style_flat, no_gutters=not gutters, dense=gutters_dense) as main:
148
+ with rv.Row(class_=class_, style_=style_flat, no_gutters=not gutters, dense=gutters_dense) as main:
149
149
  for child, xsmall, small, medium, large, xlarge in zip(children, cycle(default), cycle(small), cycle(medium), cycle(large), cycle(xlarge)):
150
150
  with rv.Col(
151
151
  cols=xsmall,
solara/server/app.py CHANGED
@@ -8,6 +8,7 @@ import threading
8
8
  import traceback
9
9
  import warnings
10
10
  import weakref
11
+ import html
11
12
  from enum import Enum
12
13
  from pathlib import Path
13
14
  from typing import Any, Dict, List, Optional, cast
@@ -15,6 +16,7 @@ from typing import Any, Dict, List, Optional, cast
15
16
  import ipywidgets as widgets
16
17
  import reacton
17
18
  from reacton.core import Element, render
19
+ from reacton import ipywidgets
18
20
 
19
21
  import solara
20
22
  import solara.lifecycle
@@ -26,7 +28,7 @@ from .utils import pdb_guard
26
28
 
27
29
  WebSocket = Any
28
30
  apps: Dict[str, "AppScript"] = {}
29
- thread_lock = threading.Lock()
31
+ thread_lock = threading.RLock()
30
32
 
31
33
  logger = logging.getLogger("solara.server.app")
32
34
 
@@ -232,12 +234,22 @@ class AppScript:
232
234
 
233
235
  def run(self):
234
236
  self.check()
235
- if reload.reloader.requires_reload or self._first_execute_app is None:
237
+ if self._first_execute_app is None:
236
238
  with thread_lock:
237
- if reload.reloader.requires_reload or self._first_execute_app is None:
238
- self._first_execute_app = None
239
- self._first_execute_app = self._execute()
240
- print("Re-executed app", self.name) # noqa
239
+ if self._first_execute_app is None:
240
+ try:
241
+ self._first_execute_app = self._execute()
242
+ print("Re-executed app", self.name) # noqa
243
+ except Exception as e:
244
+ error = ""
245
+ error = "".join(traceback.format_exception(None, e, e.__traceback__))
246
+ print(error, file=sys.stdout, flush=True) # noqa
247
+
248
+ error = html.escape(error)
249
+ self._first_execute_app = ipywidgets.HTML(value=f"<pre>{error}</pre>", layout=ipywidgets.Layout(overflow="auto"))
250
+ # We now ran the app again, might contain new imports
251
+
252
+ print("Failed to execute app, fix the error and save the file to reload") # noqa
241
253
  # We now ran the app again, might contain new imports
242
254
  patch.patch_heavy_imports()
243
255
 
@@ -319,6 +331,9 @@ class AppScript:
319
331
  except Exception as e:
320
332
  logger.exception("Could not close render context: %s", e)
321
333
 
334
+ self._first_execute_app = None
335
+ self.run()
336
+
322
337
  # ask all contexts/users to reload
323
338
  for context in context_values:
324
339
  with context:
@@ -230,9 +230,9 @@ await to_thread.run_sync(my_update)
230
230
  fut = self.portal.spawn_task(self.ws.receive)
231
231
 
232
232
  message = await asyncio.wrap_future(fut)
233
- if "text" in message:
233
+ if message.get("text") is not None:
234
234
  return message["text"]
235
- elif "bytes" in message:
235
+ elif message.get("bytes") is not None:
236
236
  return message["bytes"]
237
237
  elif message.get("type") == "websocket.disconnect":
238
238
  raise websocket.WebSocketDisconnect()
@@ -119,7 +119,7 @@ async def main():
119
119
  ]
120
120
  for dep in requirements:
121
121
  await micropip.install(dep, keep_going=True)
122
- await micropip.install("/wheels/solara-1.45.0-py2.py3-none-any.whl", keep_going=True)
122
+ await micropip.install("/wheels/solara-1.47.0-py2.py3-none-any.whl", keep_going=True)
123
123
  import solara
124
124
 
125
125
  el = solara.Warning("lala")
solara/tasks.py CHANGED
@@ -7,6 +7,7 @@ import inspect
7
7
  import logging
8
8
  import threading
9
9
  from enum import Enum
10
+ import typing
10
11
  from typing import (
11
12
  Any,
12
13
  Callable,
@@ -19,6 +20,7 @@ from typing import (
19
20
  cast,
20
21
  overload,
21
22
  )
23
+ import weakref
22
24
 
23
25
  import typing_extensions
24
26
 
@@ -35,6 +37,11 @@ else:
35
37
  from typing_extensions import Literal
36
38
 
37
39
 
40
+ # Import kernel_context for typing only
41
+ if typing.TYPE_CHECKING:
42
+ import solara.server.kernel_context
43
+
44
+
38
45
  R = TypeVar("R")
39
46
  T = TypeVar("T")
40
47
  P = typing_extensions.ParamSpec("P")
@@ -201,6 +208,7 @@ class TaskAsyncio(Task[P, R]):
201
208
  current_future: Optional[asyncio.Future] = None
202
209
  _cancel: Optional[Callable[[], None]] = None
203
210
  _retry: Optional[Callable[[], None]] = None
211
+ _context: Optional["weakref.ReferenceType[solara.server.kernel_context.VirtualKernelContext]"] = None
204
212
 
205
213
  def __init__(self, run_in_thread: bool, function: Callable[P, Coroutine[Any, Any, R]], key: str):
206
214
  self.run_in_thread = run_in_thread
@@ -249,6 +257,7 @@ class TaskAsyncio(Task[P, R]):
249
257
  import solara.server.kernel_context
250
258
 
251
259
  context = solara.server.kernel_context.get_current_context()
260
+ self._context = weakref.ref(context)
252
261
  call_event_loop = context.event_loop
253
262
  else:
254
263
  call_event_loop = _main_event_loop or asyncio.get_event_loop()
@@ -263,14 +272,32 @@ class TaskAsyncio(Task[P, R]):
263
272
  try:
264
273
  thread_event_loop.run_until_complete(current_task)
265
274
  except asyncio.CancelledError as e:
266
- call_event_loop.call_soon_threadsafe(future.set_exception, e)
275
+ try:
276
+ call_event_loop.call_soon_threadsafe(future.set_exception, e)
277
+ except Exception as e2:
278
+ if not self._is_context_closed():
279
+ logger.exception(
280
+ "error setting exception from for task %s. Original exception: %s\nReason for failing to set exception: %s",
281
+ self.function.__name__,
282
+ e,
283
+ e2,
284
+ )
267
285
  except Exception as e:
268
286
  logger.exception("error running in thread")
269
- call_event_loop.call_soon_threadsafe(future.set_exception, e)
287
+ try:
288
+ call_event_loop.call_soon_threadsafe(future.set_exception, e)
289
+ except Exception as e2:
290
+ if not self._is_context_closed():
291
+ logger.exception(
292
+ "error setting exception from for task %s. Original exception: %s\nReason for failing to set exception: %s",
293
+ self.function.__name__,
294
+ e,
295
+ e2,
296
+ )
270
297
  raise
271
298
 
272
299
  self._result.value = TaskResult[R](latest=self._last_value, _state=TaskState.STARTING)
273
- thread = threading.Thread(target=runs_in_thread)
300
+ thread = threading.Thread(target=runs_in_thread, daemon=True)
274
301
  thread.start()
275
302
  else:
276
303
  self.current_task = current_task = asyncio.create_task(self._async_run(call_event_loop, future, args, kwargs))
@@ -281,6 +308,14 @@ class TaskAsyncio(Task[P, R]):
281
308
  assert running_task is not None
282
309
  return (self.current_task == _get_current_task()) and not running_task.cancelled()
283
310
 
311
+ def _is_context_closed(self):
312
+ if self._context is None:
313
+ return False
314
+ context = self._context()
315
+ if context is None:
316
+ return False
317
+ return context.closed_event.is_set()
318
+
284
319
  async def _async_run(self, call_event_loop: asyncio.AbstractEventLoop, future: asyncio.Future, args, kwargs) -> None:
285
320
  self._start_event.wait()
286
321
 
@@ -298,12 +333,34 @@ class TaskAsyncio(Task[P, R]):
298
333
  if self.is_current() and not task_for_this_call.cancelled(): # type: ignore
299
334
  self._result.value = TaskResult[R](value=value, latest=value, _state=TaskState.FINISHED, progress=self._last_progress)
300
335
  logger.info("setting result to %r", value)
301
- call_event_loop.call_soon_threadsafe(future.set_result, value)
336
+ try:
337
+ call_event_loop.call_soon_threadsafe(future.set_result, value)
338
+ except Exception as e:
339
+ if not self._is_context_closed():
340
+ logger.exception(
341
+ "error setting result from for task %s. Original exception: %s\nReason for failing to set result: %s", self.function.__name__, e, e
342
+ )
343
+ else:
344
+ logger.debug(
345
+ "ignoring error setting result from for task %s. Original exception: %s\nReason for failing to set result: %s",
346
+ self.function.__name__,
347
+ e,
348
+ e,
349
+ )
302
350
  except Exception as e:
303
351
  if self.is_current():
304
352
  logger.exception(e)
305
353
  self._result.value = TaskResult[R](latest=self._last_value, exception=e, _state=TaskState.ERROR)
306
- call_event_loop.call_soon_threadsafe(future.set_exception, e)
354
+ try:
355
+ call_event_loop.call_soon_threadsafe(future.set_exception, e)
356
+ except Exception as e2:
357
+ # we don't know if it is still useful to show this error, so we show it regardless if the context is closed or not
358
+ logger.exception(
359
+ "error setting exception from for task %s. Original exception: %s\nReason for failing to set exception: %s",
360
+ self.function.__name__,
361
+ e,
362
+ e2,
363
+ )
307
364
  # Although this seems like an easy way to handle cancellation, an early cancelled task will never execute
308
365
  # so this code will never execute, so we need to handle this in the cancel function in __call__
309
366
  # except asyncio.CancelledError as e:
@@ -715,12 +772,15 @@ def task(
715
772
  def wrapper(f: Union[None, Callable[P, Union[Coroutine[Any, Any, R], R]]]) -> Task[P, R]:
716
773
  # we use wraps to make the key of the reactive variable more unique
717
774
  # and less likely to mixup during hot reloads
775
+ assert f is not None
776
+ key = solara.toestand._create_key_callable(f)
777
+
718
778
  @functools.wraps(f) # type: ignore
719
779
  def create_task():
720
780
  if inspect.iscoroutinefunction(f):
721
- return TaskAsyncio[P, R](prefer_threaded and has_threads, f, key=solara.toestand._create_key_callable(create_task))
781
+ return TaskAsyncio[P, R](prefer_threaded and has_threads, f, key=key)
722
782
  else:
723
- return TaskThreaded[P, R](cast(Callable[P, R], f), key=solara.toestand._create_key_callable(create_task))
783
+ return TaskThreaded[P, R](cast(Callable[P, R], f), key=key)
724
784
 
725
785
  return cast(Task[P, R], Proxy(create_task))
726
786
 
@@ -334,7 +334,7 @@ class ServerVoila(ServerBase):
334
334
 
335
335
  def serve(self):
336
336
  if self.has_started():
337
- raise RuntimeError("Jupyter server already running, use lsof -i :{self.port} to find the process and kill it")
337
+ raise RuntimeError(f"Jupyter server already running, use lsof -i :{self.port} to find the process and kill it")
338
338
  cmd = (
339
339
  "voila --no-browser --VoilaTest.log_level=DEBUG --Voila.port_retries=0 --VoilaExecutor.timeout=240"
340
340
  f' --Voila.port={self.port} --show_tracebacks=True "{self.notebook_path}" --enable_nbextensions=True'
solara/toestand.py CHANGED
@@ -442,7 +442,7 @@ reactive_df = solara.reactive(df, equals=solara.util.equals_pickle)
442
442
  raise ValueError(msg)
443
443
 
444
444
 
445
- def _create_key_callable(f: Callable[[], S]):
445
+ def _create_key_callable(f: Callable):
446
446
  try:
447
447
  prefix = f.__qualname__
448
448
  except Exception:
@@ -1,5 +1,15 @@
1
1
  # Solara Changelog
2
2
 
3
+ ## Version 1.45.0
4
+
5
+ * Bug Fix: Correctly handle expected websocket errors instead of logging them. [#1013](https://github.com/widgetti/solara/pull/1013)
6
+ * Bug Fix: Ensure component re-renders correctly when a reactive variable is updated from another thread during rendering. [#1030](https://github.com/widgetti/solara/pull/1030)
7
+ * Bug Fix: Allow calling async tasks from within threaded tasks. [#1029](https://github.com/widgetti/solara/pull/1029)
8
+ * Bug Fix: Replace deprecated `use_side_effect` calls with `use_effect`. [#1026](https://github.com/widgetti/solara/pull/1026)
9
+ * Bug Fix(pytest-ipywidgets): Support `pytest-playwright` version 0.7.0. [#1006](https://github.com/widgetti/solara/pull/1006)
10
+ * Docs: Ensure Twitter/OpenGraph meta tags are present on documentation pages. [#998](https://github.com/widgetti/solara/pull/998)
11
+ * Breaking change: Drop support for Python 3.6 due to CI runner deprecation. [#1032](https://github.com/widgetti/solara/pull/1032)
12
+
3
13
  ## Version 1.44.0
4
14
 
5
15
  * Feature: Separate `disable_send` and `disable_input` to allow typing but not sending or vice versa for the `ChatInput` component. [86fc2ad](https://github.com/widgetti/solara/commit/86fc2ad88a89ffe134eaa6700a8c416bcab036b4).
@@ -11,6 +11,7 @@
11
11
  :vertical-compact="true"
12
12
  :margin="[10, 10]"
13
13
  :use-css-transforms="true"
14
+ @layout-updated="onLayoutUpdated"
14
15
  >
15
16
 
16
17
  <grid-item v-for="item in grid_layout"
@@ -49,6 +50,9 @@ module.exports = {
49
50
  // this will cause bqplot to layout itself
50
51
  window.dispatchEvent(new Event('resize'));
51
52
  },
53
+ onLayoutUpdated(layout) {
54
+ this.layout_updated(layout);
55
+ },
52
56
  import(deps) {
53
57
  return this.loadRequire().then(
54
58
  () => {
solara/widgets/widgets.py CHANGED
@@ -52,6 +52,11 @@ class GridLayout(v.VuetifyTemplate):
52
52
  draggable = traitlets.CBool(True).tag(sync=True)
53
53
  resizable = traitlets.CBool(True).tag(sync=True)
54
54
  cdn = traitlets.Unicode(None, allow_none=True).tag(sync=True)
55
+ on_layout_updated = traitlets.traitlets.Callable(None, allow_none=True)
56
+
57
+ def vue_layout_updated(self, *args):
58
+ if self.on_layout_updated is not None:
59
+ self.on_layout_updated(*args)
55
60
 
56
61
  @traitlets.default("cdn")
57
62
  def _cdn(self):
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: solara-ui
3
- Version: 1.45.0
3
+ Version: 1.47.0
4
4
  Dynamic: Summary
5
5
  Project-URL: Home, https://www.github.com/widgetti/solara
6
6
  Project-URL: Documentation, https://solara.dev
@@ -1,6 +1,6 @@
1
1
  prefix/etc/jupyter/jupyter_notebook_config.d/solara.json,sha256=3UhTBQi6z7F7pPjmqXxfddv79c8VGR9H7zStDLp6AwY,115
2
2
  prefix/etc/jupyter/jupyter_server_config.d/solara.json,sha256=D9J-rYxAzyD5GOqWvuPjacGUVFHsYtTfZ4FUbRzRvIA,113
3
- solara/__init__.py,sha256=ETRGAtf8f2RuTpPEwpUnttdIUVxWwCBzmjpyBnaNmIw,3647
3
+ solara/__init__.py,sha256=jBYuG7OuKcvsz7an94e3Q-_v9wxV3LotKgn69jDdWgI,3647
4
4
  solara/__main__.py,sha256=pm79jfba-0ZapLR0PtwZfMeiTHrLz8kEt79EygRyXxQ,24828
5
5
  solara/_stores.py,sha256=N2Ec-61XNFXwigBx8f5QYPx7gDXenCOBdmLPXiJB45E,12320
6
6
  solara/alias.py,sha256=9vfLzud77NP8in3OID9b5mmIO8NyrnFjN2_aE0lSb1k,216
@@ -20,8 +20,8 @@ solara/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
20
20
  solara/reactive.py,sha256=KN0PJl-ivxjgQj008zyPGnORo5bTNaY77uASsSW0mFQ,3430
21
21
  solara/routing.py,sha256=G_iZKozdVoUuD-qSMyuPV6jeN4qBqujAUvekw036f88,9143
22
22
  solara/settings.py,sha256=FED5SYfw1W88U8SPk9iXSgSSvMHgPkU1auONSdk5cNs,2688
23
- solara/tasks.py,sha256=cMYuh3ruTP22aoSGw5XiTjGoOn5rMF4JefMWFNqALpI,31898
24
- solara/toestand.py,sha256=pXUdvINF5x9reKL0yBdSjz-hxNkYILTsQjZVfKAYlVg,33446
23
+ solara/tasks.py,sha256=eAMwY80dHg_GRiQniaoLG2fJz6GjKZ-v3S1LQs2MgGo,34556
24
+ solara/toestand.py,sha256=kVyGgmUcgRKK70FZKrf1VqbE1-tW5fAOG7zoR66jD94,33439
25
25
  solara/util.py,sha256=UUO3BfhXb3tGP-uj8UuTYMx6kuph6PiDp4XXm-f6uyg,9697
26
26
  solara/validate_hooks.py,sha256=F0CYDOVF_23O1apJBIk9lZMq11JmkoE3BrVVT8QvZWI,9999
27
27
  solara/components/__init__.py,sha256=j5Tv0tyzs80Bsl5hvTIF_x-RQyAvr3ooqIXnABamW44,3214
@@ -32,7 +32,7 @@ solara/components/card.py,sha256=2xNXrIRJ4jGJtRbirX1Xp8V2h3HtW9vnxhLGUCrPr9I,279
32
32
  solara/components/checkbox.py,sha256=MLQ9Hxvtv5aKLj4XO3ILWtGc6nKOUH560A2bBt0Z030,1445
33
33
  solara/components/code_highlight_css.py,sha256=J0fZHuEu8jeEKAq_HKbzgiMR1-VwMVnKA4dAOKE0AQU,235
34
34
  solara/components/code_highlight_css.vue,sha256=UX4jtEetV1W25Uvu8xQ-TbEaBzbp_7DlXtXDO9SdZfY,5776
35
- solara/components/columns.py,sha256=bGCUU9MLxkt2OiS31oLHWrEOlskxT1Xo65dBxXhmhbQ,5564
35
+ solara/components/columns.py,sha256=zC4PVGMivHMn2jCaQoV_mmRBzaF12gRTeMqyuWANMyo,5544
36
36
  solara/components/component_vue.py,sha256=iFjmklw3uKkGPxnf5Hn6JQQ1Nw6sfAICLmkPYJEmbbE,5068
37
37
  solara/components/cross_filter.py,sha256=Q5vOkerWXNCtRbSboHjXcnjoys8bHv5b7G_fH1A1lio,13663
38
38
  solara/components/dataframe.py,sha256=F-FdIjCj_rovstOVvZd3bwypKfshq3RXAF7FT2HLDVw,21032
@@ -106,7 +106,7 @@ solara/lab/utils/headers.py,sha256=RMo8JUdztRePrdNfYCX1QEhrfyF6ktodr4v6tIREKbs,2
106
106
  solara/scope/__init__.py,sha256=0sP3B6L4Aai0b6nadPtEETb8XqdGmSFKvQusNH0-yvY,2987
107
107
  solara/scope/types.py,sha256=HTf_wnkpkhhtGaeFsB690KBP623CUuqiMssd72-u9yg,1540
108
108
  solara/server/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
109
- solara/server/app.py,sha256=DHl06kWFcAQbc36ytBKzAeChirysGwQvmy7BCZyuTvw,21490
109
+ solara/server/app.py,sha256=Ro_-V9RIVCGOubm8aW8eCVfW1A6peD0DKaqmim1--ZE,22134
110
110
  solara/server/cdn_helper.py,sha256=mjdDWL1jVed40rEagP9L5CfZwFB77yUKqcFg--u2eds,3250
111
111
  solara/server/esm.py,sha256=dX9pzTJQ6kd6qNHQgzC938O5LTowLhuATXO0Q1paz44,2951
112
112
  solara/server/fastapi.py,sha256=qVIHn0_Kxr6zWqcBWySu5nnJ6pNTSDqb4EHIh-cqH_8,93
@@ -120,7 +120,7 @@ solara/server/reload.py,sha256=BBH7QhrV1-e9RVyNE3uz1oPj1DagC3t_XSqGPNz0nJE,9747
120
120
  solara/server/server.py,sha256=9NQcg_ncrGPQUDs50-jJGdzhlub3G3dsgcBjxqrIxX0,17120
121
121
  solara/server/settings.py,sha256=tXXpoK5CBBDbuRSMiert6UKpzMQaDbsBfyoX1Hk8iLM,7599
122
122
  solara/server/shell.py,sha256=eLrpTAw3j_1pU-2S7_Jzd4xkoSs_CA7Nv7w0Q7IVLUM,9333
123
- solara/server/starlette.py,sha256=OtUiCV3VoqsfUaRI0jyojxDfZvj4QVhr9DN7DY4s4l8,32588
123
+ solara/server/starlette.py,sha256=wchutafZy2V9lBaX3ZFfSGcARDOw6K2sti3D0XhnQGU,32616
124
124
  solara/server/telemetry.py,sha256=GPKGA5kCIqJb76wgxQ2_U2uV_s0r-1tKqv-GVxo5hs8,6038
125
125
  solara/server/threaded.py,sha256=k9k461md4MxEFX-RLit5RpVRPFlQNwr-qp5pprT8JB0,2347
126
126
  solara/server/utils.py,sha256=1Pa6HF8O1jsxDBcCWlVfP_9jFiUIQgqiIhT4oJ-iUmo,1207
@@ -146,7 +146,7 @@ solara/server/static/highlight-dark.css,sha256=xO8-vta9vG4s1OfJNHXWqiLWzx_gM03jo
146
146
  solara/server/static/highlight.css,sha256=k8ZdT5iwrGQ5tXTQHAXuxvZrSUq3kwCdEpy3mlFoZjs,2637
147
147
  solara/server/static/main-vuetify.js,sha256=R3qM4xMlstMpRUdRaul78p34z_Av2ONSTXksg2V9TqQ,9503
148
148
  solara/server/static/main.js,sha256=mcx4JNQ4Lg4pNdUIqMoZos1mZyYFS48yd_JNFFJUqIE,5679
149
- solara/server/static/solara_bootstrap.py,sha256=czQrpaCPRQSA4n7q6lOD0G4Bem6jv957ZzxjLOR1pns,3195
149
+ solara/server/static/solara_bootstrap.py,sha256=ildevVHVjvZI43tKpjjCcTLDdAv4ept91zCTLtOxAQU,3195
150
150
  solara/server/static/sun.svg,sha256=jEKBAGCr7b9zNYv0VUb7lMWKjnU2dX69_Ye_DZWGXJI,6855
151
151
  solara/server/static/webworker.js,sha256=cjAFz7-SygStHJnYlJUlJs-gE_7YQeQ-WBDcmKYyjvo,1372
152
152
  solara/server/templates/index.html.j2,sha256=JXQo1M-STFHLBOFetgG7509cAq8xUP0VAEtYDzz35fY,31
@@ -179,7 +179,7 @@ solara/template/portal/solara_portal/pages/article/__init__.py,sha256=6PgHyyeK1_
179
179
  solara/template/portal/solara_portal/pages/viz/__init__.py,sha256=l65uqBpFJ6Uh5XytXhLMnR-8G4FBnjqJg86OJX7_LO0,2858
180
180
  solara/template/portal/solara_portal/pages/viz/overview.py,sha256=GPlzFxUR0LRQhR96a_CVWquGTjHhDehL1PR03Tcm3gs,365
181
181
  solara/test/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
182
- solara/test/pytest_plugin.py,sha256=xwNW6ek2Z3dtV0_ZB83Ad1rl-eWzulIqpo4hVlXkftA,30125
182
+ solara/test/pytest_plugin.py,sha256=17waJlD9pHgTWHkCWN-WRzm7ejOLiUtsJui_LE4fX20,30126
183
183
  solara/website/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
184
184
  solara/website/utils.py,sha256=TfoExocZ8ko2hTcA7XDKI5FfKZ4gi3JTc_f9Oi5L7Fs,855
185
185
  solara/website/assets/custom.css,sha256=Qw_FZpAmPrus38TgYKmLmSgEYf6djWzO5pm2fF8kutk,9330
@@ -222,7 +222,7 @@ solara/website/pages/apps/multipage/page1.py,sha256=5hK0RZ8UBBOaZcPKaplbLeb0Vvae
222
222
  solara/website/pages/apps/multipage/page2.py,sha256=uRJ8YPFyKy7GR_Ii8DJSx3akb3H15rQAJZETMt9jVEk,1422
223
223
  solara/website/pages/careers/__init__.py,sha256=_aaO9YQOvy8JE9PYkWeSNzLU4pUU-PJMAaYy07YbKsU,1479
224
224
  solara/website/pages/changelog/__init__.py,sha256=0ouQpbt5EGEY6bHmSMt6S7Gk71gAmuaIuevT5wEE2zQ,277
225
- solara/website/pages/changelog/changelog.md,sha256=LlHUxQiXgf_UH4dXanEkgp2wc59MF5KjGJE__eS0Er4,27079
225
+ solara/website/pages/changelog/changelog.md,sha256=rmu461GhH_EsBn4GjypFAn6grGyzpC2Y3UO-84esGuA,28065
226
226
  solara/website/pages/contact/__init__.py,sha256=NkjxJo258RTHLFPQ18IVZ9euS_vJciHUrM4o1fz9QJE,1259
227
227
  solara/website/pages/documentation/__init__.py,sha256=lv9cleVukKDLKRtjTYIlfBDi8Aw3bEz2iV8-IxBz3LA,5563
228
228
  solara/website/pages/documentation/advanced/__init__.py,sha256=bLLvasuqVVWJxGN89m77ChZhDivEhVavw9-_CiG3IZA,414
@@ -451,14 +451,14 @@ solara/website/public/social/github.svg,sha256=XGlfnNccpMHYjfji25r5UW9FvS9pYPR1H
451
451
  solara/website/public/social/twitter.svg,sha256=3Ub5a29H_NM2g7ed3689rKHU-K66PA8r3hWExpzGmdQ,430
452
452
  solara/website/templates/index.html.j2,sha256=NYBuEHmKeSju-b3apY0h3FEJ-tnGDhrnkY-0cZ92Rro,4358
453
453
  solara/widgets/__init__.py,sha256=D3RfEez9dllmst64_nyzzII-NZXoNMEPDnEog4ov3VE,43
454
- solara/widgets/widgets.py,sha256=AIRcMhSDFpESQ1JzUszlb2NH5FwSImLnmd4kqcc9jkY,2452
455
- solara/widgets/vue/gridlayout.vue,sha256=hk10RsEQBxkknTmqa0wtBia9LWQGdDsXlejnAj7USU8,3441
454
+ solara/widgets/widgets.py,sha256=RTB6RR8UFQ31U3_7740c-2St3xM4NlJc__d7-0onjvU,2659
455
+ solara/widgets/vue/gridlayout.vue,sha256=YlDJohAV8gvoZCEdABbFm6uXcy2tfCMfH8GQqPW9M7o,3571
456
456
  solara/widgets/vue/html.vue,sha256=48K5rjp0AdJDeRV6F3nOHW3J0WXPeHn55r5pGClK2fU,112
457
457
  solara/widgets/vue/navigator.vue,sha256=7fkX-4_YSnnMIPUMKMvQVVEzrmhY9BFAYvHMqZqTXpI,4790
458
458
  solara/widgets/vue/vegalite.vue,sha256=zhocRsUCNIRQCEbD16er5sYnuHU0YThatRHnorA3P18,4596
459
- solara_ui-1.45.0.data/data/etc/jupyter/jupyter_notebook_config.d/solara.json,sha256=3UhTBQi6z7F7pPjmqXxfddv79c8VGR9H7zStDLp6AwY,115
460
- solara_ui-1.45.0.data/data/etc/jupyter/jupyter_server_config.d/solara.json,sha256=D9J-rYxAzyD5GOqWvuPjacGUVFHsYtTfZ4FUbRzRvIA,113
461
- solara_ui-1.45.0.dist-info/METADATA,sha256=_TqYXgdyCVETIAwUyLImkCBV4VxaNrO5gqWPy3koFLE,7459
462
- solara_ui-1.45.0.dist-info/WHEEL,sha256=C2FUgwZgiLbznR-k0b_5k3Ai_1aASOXDss3lzCUsUug,87
463
- solara_ui-1.45.0.dist-info/licenses/LICENSE,sha256=fFJUz-CWzZ9nEc4QZKu44jMEoDr5fEW-SiqljKpD82E,1086
464
- solara_ui-1.45.0.dist-info/RECORD,,
459
+ solara_ui-1.47.0.data/data/etc/jupyter/jupyter_notebook_config.d/solara.json,sha256=3UhTBQi6z7F7pPjmqXxfddv79c8VGR9H7zStDLp6AwY,115
460
+ solara_ui-1.47.0.data/data/etc/jupyter/jupyter_server_config.d/solara.json,sha256=D9J-rYxAzyD5GOqWvuPjacGUVFHsYtTfZ4FUbRzRvIA,113
461
+ solara_ui-1.47.0.dist-info/METADATA,sha256=vo9lBZKU-TY9kjVktWpUs9vqg-MkPE-PDvcU5xNFFHE,7459
462
+ solara_ui-1.47.0.dist-info/WHEEL,sha256=C2FUgwZgiLbznR-k0b_5k3Ai_1aASOXDss3lzCUsUug,87
463
+ solara_ui-1.47.0.dist-info/licenses/LICENSE,sha256=fFJUz-CWzZ9nEc4QZKu44jMEoDr5fEW-SiqljKpD82E,1086
464
+ solara_ui-1.47.0.dist-info/RECORD,,