posit-dev / py-shinywidgets

Render ipywidgets inside a PyShiny app
MIT License
47 stars 5 forks source link

`import ipydatagrid` fails with error about not having an active Shiny session #99

Open jcheng5 opened 1 year ago

jcheng5 commented 1 year ago

Reported by @andrie

App:

from shiny import Inputs, Outputs, Session, App, reactive, render, req, ui
import shinywidgets
import ipydatagrid

app_ui = ui.page_fluid()

def server(input: Inputs, output: Outputs, session: Session):
    ...

app = App(app_ui, server)

Simply starting the app gives this:

Traceback (most recent call last):
  File "/Users/jcheng/.pyenv/versions/3.10.6/lib/python3.10/multiprocessing/process.py", line 314, in _bootstrap
    self.run()
  File "/Users/jcheng/.pyenv/versions/3.10.6/lib/python3.10/multiprocessing/process.py", line 108, in run
    self._target(*self._args, **self._kwargs)
  File "/Users/jcheng/Development/scratchpad/ipydatagrid-repro/.venv/lib/python3.10/site-packages/uvicorn/_subprocess.py", line 76, in subprocess_started
    target(sockets=sockets)
  File "/Users/jcheng/Development/scratchpad/ipydatagrid-repro/.venv/lib/python3.10/site-packages/uvicorn/server.py", line 61, in run
    return asyncio.run(self.serve(sockets=sockets))
  File "/Users/jcheng/.pyenv/versions/3.10.6/lib/python3.10/asyncio/runners.py", line 44, in run
    return loop.run_until_complete(main)
  File "/Users/jcheng/.pyenv/versions/3.10.6/lib/python3.10/asyncio/base_events.py", line 646, in run_until_complete
    return future.result()
  File "/Users/jcheng/Development/scratchpad/ipydatagrid-repro/.venv/lib/python3.10/site-packages/uvicorn/server.py", line 68, in serve
    config.load()
  File "/Users/jcheng/Development/scratchpad/ipydatagrid-repro/.venv/lib/python3.10/site-packages/uvicorn/config.py", line 473, in load
    self.loaded_app = import_from_string(self.app)
  File "/Users/jcheng/Development/scratchpad/ipydatagrid-repro/.venv/lib/python3.10/site-packages/uvicorn/importer.py", line 21, in import_from_string
    module = importlib.import_module(module_str)
  File "/Users/jcheng/.pyenv/versions/3.10.6/lib/python3.10/importlib/__init__.py", line 126, in import_module
    return _bootstrap._gcd_import(name[level:], package, level)
  File "<frozen importlib._bootstrap>", line 1050, in _gcd_import
  File "<frozen importlib._bootstrap>", line 1027, in _find_and_load
  File "<frozen importlib._bootstrap>", line 1006, in _find_and_load_unlocked
  File "<frozen importlib._bootstrap>", line 688, in _load_unlocked
  File "<frozen importlib._bootstrap_external>", line 883, in exec_module
  File "<frozen importlib._bootstrap>", line 241, in _call_with_frames_removed
  File "/Users/jcheng/Development/scratchpad/ipydatagrid-repro/app.py", line 3, in <module>
    import ipydatagrid
  File "/Users/jcheng/Development/scratchpad/ipydatagrid-repro/.venv/lib/python3.10/site-packages/ipydatagrid/__init__.py", line 5, in <module>
    from .cellrenderer import (
  File "/Users/jcheng/Development/scratchpad/ipydatagrid-repro/.venv/lib/python3.10/site-packages/ipydatagrid/cellrenderer.py", line 52, in <module>
    class TextRenderer(CellRenderer):
  File "/Users/jcheng/Development/scratchpad/ipydatagrid-repro/.venv/lib/python3.10/site-packages/ipydatagrid/cellrenderer.py", line 71, in TextRenderer
    default_value=Expr("default_value"),
  File "/Users/jcheng/Development/scratchpad/ipydatagrid-repro/.venv/lib/python3.10/site-packages/ipydatagrid/cellrenderer.py", line 25, in __init__
    super().__init__(value=value, **kwargs)
  File "/Users/jcheng/Development/scratchpad/ipydatagrid-repro/.venv/lib/python3.10/site-packages/ipywidgets/widgets/widget.py", line 503, in __init__
    Widget._call_widget_constructed(self)
  File "/Users/jcheng/Development/scratchpad/ipydatagrid-repro/.venv/lib/python3.10/site-packages/ipywidgets/widgets/widget.py", line 363, in _call_widget_constructed
    Widget._widget_construction_callback(widget)
  File "/Users/jcheng/Development/scratchpad/ipydatagrid-repro/.venv/lib/python3.10/site-packages/shinywidgets/_shinywidgets.py", line 82, in init_shiny_widget
    raise RuntimeError(
RuntimeError: shinywidgets requires that all ipywidgets be constructed within an active Shiny session
CYee3589 commented 1 year ago

Is there any updates or follow-ups with this issue. I'm encountering the same issue when trying to implement ipydatagrid into a python shiny app. Note: I'm using versions ipydatagrid==1.1.12 and shinywidgets==0.2.1

cpsievert commented 1 year ago

I haven't looked into this at all, but a potential workaround might be to import ipydatagrid at the top of the server function?

andrie commented 1 year ago

I agree with the conclusion by @cpsievert.

If you put import ipydatagrid inside the server module you can get this widget to work.

@module.server
def metrics_explorer_server(input, output, session, metrics_data):

    import ipydatagrid

   <... etc. ...>
CYee3589 commented 1 year ago

I agree with the conclusion by @cpsievert.

If you put import ipydatagrid inside the server module you can get this widget to work.

@module.server
def metrics_explorer_server(input, output, session, metrics_data):

    import ipydatagrid

   <... etc. ...>

Wow. That worked. Thanks @andrie and @cpsievert.

maartenbreddels commented 4 months ago

I think this should be fixed in ipydatagrid 1.3.2, which is probably due to https://github.com/bloomberg/ipydatagrid/pull/400