Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

AttributeError: 'function' object has no attribute 'expanded' #484

Open
zvi-quantivly opened this issue Jan 21, 2024 · 4 comments
Open

AttributeError: 'function' object has no attribute 'expanded' #484

zvi-quantivly opened this issue Jan 21, 2024 · 4 comments

Comments

@zvi-quantivly
Copy link

zvi-quantivly commented Jan 21, 2024

I have a requirement to create my Dash application within the context of a class. I tried following the example here to have something like:

from dash import Input, Output, State, dcc, html
from django_plotly_dash import DjangoDash

class MyClass(Base):
    def __init___(self, *args, **kwrags):
        self.app = DjangoDash("name")
        plot = dcc.Graph(id="my-plot")
        store = dcc.Store(id="my-store")
        div = html.Div("my-div", children=[])
        self.app.layout = html.Div(children=[plot, store, div])
        self.app.callback(Output("my-plot", "figure"), Input("my-store", "data"))(self.update_plot)

    def update_plot(self, data):
        ...
        return a_figure

However, this raises:

File "/usr/local/lib/python3.9/site-packages/django_plotly_dash/views.py", line 75, in update
     return _update(request, ident, stateless, **kwargs)
File "/usr/local/lib/python3.9/site-packages/django_plotly_dash/views.py", line 95, in _update
     resp = app.dispatch_with_args(request_body, arg_map)
File "/usr/local/lib/python3.9/site-packages/django_plotly_dash/dash_wrapper.py", line 699, in dispatch_with_args
     if callback.expanded is not None:
AttributeError: 'function' object has no attribute 'expanded'

Since self.app is a DjangoDash instance, so far, I haven't managed to figure out why expanded isn't set. Any help resolving this would be greatly appreciated.

EDIT: It seems it is caused by the inclusion of self (i.e., static methods are not effected).

@zvi-quantivly
Copy link
Author

I tried excluding self inside DjangoDash.get_expanded_arguments() (see here). Unfortunately, there was no difference.

@GibbsConsulting
Copy link
Owner

@zvi-quantivly what is the driver behind wanting to embed the DjangoDash instance inside a class? In particular, is there something specific that leads you to this code structure?

@zvi-quantivly
Copy link
Author

Yes. It's a little difficult to explain briefly, but I am working on a Django project that needs to be able to run user provided code as a “plugin”. Each plugin is written as a small Python package that depends on a common SDK and exposes a subclass of some base Plugin class (from the SDK). These plugin subclasses are dynamically imported, initialized, and executed by the project. The initialization procedures populate specific plugin attributes with endpoints and authorization information that is required for its execution.

E.g., if we consider the example above, Base provides something like self.run_query(), which uses an attribute such as self.server_address, which is populated by the Django project as part of the initialization of a plugin. The self.update_plot() method needs to be able to use self.run_query() to run. HTH.

@zvi-quantivly
Copy link
Author

It looks like the source of the problem is that setting method attributes on bound methods is disallowed [ref]. This happens in the custom callback() decorator's func.expanded assignment (here) whenever self.app.callback(...)(self.some_method) is called (in which case, func is a bound method). I still haven't found a solution for this. Now trying to think whether function objects (see second example here) might somehow work.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants