holoviz / panel

Panel: The powerful data exploration & web app framework for Python
https://panel.holoviz.org
BSD 3-Clause "New" or "Revised" License
4.81k stars 520 forks source link

TypeError: Design._apply_hooks() missing 1 required positional argument: 'changed' #7438

Open MarcSkovMadsen opened 1 month ago

MarcSkovMadsen commented 1 month ago

panel==1.5.3

I've started seeing TypeError: Design._apply_hooks() missing 1 required positional argument: 'changed' when I start my Panel apps.

It seems Design._apply_hooks() does not allow providing only self and root.

image

Logs

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/home/jovyan/repos/mt-pm-reporting/.venv/lib/python3.11/site-packages/tornado/web.py", line 1790, in _execute
    result = await result
             ^^^^^^^^^^^^
  File "/home/jovyan/repos/mt-pm-reporting/.venv/lib/python3.11/site-packages/panel/io/server.py", line 466, in get
    session = await self.get_session()
              ^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/jovyan/repos/mt-pm-reporting/.venv/lib/python3.11/site-packages/panel/io/server.py", line 356, in get_session
    session = await super().get_session()
              ^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/jovyan/repos/mt-pm-reporting/.venv/lib/python3.11/site-packages/bokeh/server/views/session_handler.py", line 145, in get_session
    session = await self.application_context.create_session_if_needed(session_id, self.request, token)
              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/jovyan/repos/mt-pm-reporting/.venv/lib/python3.11/site-packages/bokeh/server/contexts.py", line 240, in create_session_if_needed
    self._application.initialize_document(doc)
  File "/home/jovyan/repos/mt-pm-reporting/.venv/lib/python3.11/site-packages/panel/io/application.py", line 149, in initialize_document
    super().initialize_document(doc)
  File "/home/jovyan/repos/mt-pm-reporting/.venv/lib/python3.11/site-packages/bokeh/application/application.py", line 190, in initialize_document
    h.modify_document(doc)
  File "/home/jovyan/repos/mt-pm-reporting/.venv/lib/python3.11/site-packages/panel/io/handlers.py", line 469, in modify_document
    run_app(self, module, doc)
  File "/home/jovyan/repos/mt-pm-reporting/.venv/lib/python3.11/site-packages/panel/io/handlers.py", line 277, in run_app
    handler._runner.run(module, post_check)
  File "/home/jovyan/repos/mt-pm-reporting/.venv/lib/python3.11/site-packages/panel/io/handlers.py", line 410, in run
    autoreload_handle_exception(self, module, e)
  File "/home/jovyan/repos/mt-pm-reporting/.venv/lib/python3.11/site-packages/panel/io/handlers.py", line 240, in autoreload_handle_exception
    ).servable()
      ^^^^^^^^^^
  File "/home/jovyan/repos/mt-pm-reporting/.venv/lib/python3.11/site-packages/panel/viewable.py", line 399, in servable
    self.server_doc(title=title, location=location) # type: ignore
    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/jovyan/repos/mt-pm-reporting/.venv/lib/python3.11/site-packages/panel/viewable.py", line 1019, in server_doc
    notification_model = state.notifications.get_root(doc)
                         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/jovyan/repos/mt-pm-reporting/.venv/lib/python3.11/site-packages/panel/io/notifications.py", line 84, in get_root
    root = super().get_root(doc, comm, preprocess)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/jovyan/repos/mt-pm-reporting/.venv/lib/python3.11/site-packages/panel/viewable.py", line 681, in get_root
    self._preprocess(root)
  File "/home/jovyan/repos/mt-pm-reporting/.venv/lib/python3.11/site-packages/panel/viewable.py", line 606, in _preprocess
    hook(self, root)
TypeError: Design._apply_hooks() missing 1 required positional argument: 'changed'

Minimum reproducible example coming later. But I included ChatInterface with openai in my app and that triggered it.

itsgifnotjiff commented 5 days ago

Same issue with a Xarray -> Matplotlib Panel param.Parameterized app

MarcSkovMadsen commented 5 days ago

I see this often across many complicated apps.

philippjfr commented 5 days ago

I'd really need a reproducible example here. The problem is that there's likely some other error that's being masked here, specifically we try both signatures, and it seems like some other TypeError is causing it to fall back to the except branch here:

            try:
                hook(self, root, changed, old_models)
            except TypeError:
                hook(self, root)
philippjfr commented 5 days ago

What we could do is actually inspecting the signature instead of try/except, so that we are no longer masking the actual error.

itsgifnotjiff commented 5 days ago

Tried to create an MRE but can't quite get the error, anyways here is the analogue scatfold app that does not show the error in case someone can tweak it to produce it.

import json
from datetime import datetime, timedelta
from pathlib import Path
from typing import List
from warnings import filterwarnings

import cartopy.crs as ccrs
import cartopy.feature as cf
import fstd2nc
import geoviews as gv
import matplotlib.pyplot as plt
import numpy as np
import panel as pn
import param
import utils
import xarray as xr
from fstd2nc.extra import get_crs
import hvplot.xarray

filterwarnings("ignore")

pn.extension(sizing_mode="stretch_width")

with open("domains.json", "r") as json_file:
    DOMAINS = json.load(json_file)

class MRE(param.Parameterized):
    def __init__(self):
        self.loc_widg = pn.widgets.RadioButtonGroup(
            name="Region",
            options=DOMAINS,
            orientation="vertical",
            button_style="outline",
            button_type="primary",
        )

        self.ds = xr.tutorial.open_dataset('air_temperature')['air'].isel(time=0)
        self.ds = self.ds.assign_coords(lon=(self.ds.lon - 360))
        # Initializes the pn.Row where the map will be displayed
        self.col = pn.Column("init")

        self._display("init")

        self.loc_widg.param.watch(self._display, "value")

    @pn.cache
    def _matplotlib(
        self, location: List[float], **kwargs
    ) -> plt.Figure:

        air_temp = self.ds.sel(lon=slice(location[0],location[1]), lat=slice(location[3],location[2]))

        fig, ax = plt.subplots(figsize=(24, 24))

        plot = air_temp.plot(
            ax=ax,
            cmap="coolwarm",
            cbar_kwargs={
                "label": "Air Temperature (K)",
                "fraction": 0.02,
                "pad": 0.04,
            },
        )

        plt.title(f"Air Temperature within the specified domain", fontsize=10)

        plt.close(fig)
        return fig

    def _display(self, event: str):
        self.col[0] = pn.pane.Matplotlib(
            self._matplotlib(
                self.loc_widg.value
            ),
            format="svg",
            tight=True,
            fixed_aspect=True,
            sizing_mode="stretch_both",
        )

app = MRE()

template = pn.template.MaterialTemplate(
    logo="https://www.canada.ca/etc/designs/canada/wet-boew/assets/sig-blk-en.svg",
    site="CMC",
    title="MRE",
    sidebar=[ "Region:", app.loc_widg],
    main=[app.col],
    sidebar_width=300,
).servable()