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

Multi Page Apps: circular reference when importing app #65

Open
stevej2608 opened this issue Dec 18, 2021 · 10 comments · Fixed by plotly/dash#1923
Open

Multi Page Apps: circular reference when importing app #65

stevej2608 opened this issue Dec 18, 2021 · 10 comments · Fixed by plotly/dash#1923
Assignees

Comments

@stevej2608
Copy link

I define my dash app instance in app.py:

server = flask.Flask(__name__)
app = Dash(__name__,
        plugins=[dl.plugins.pages],
        external_stylesheets=external_stylesheets,
        external_scripts=external_scripts, server=server)

By default the pages plug-in iterates over the modules in the ./pages folder. I have a page that needs
to reference the dash app instance in order to call the get_asset_url() method.

In my page module, the import:

from app import app

Creates a circular reference. I can fix this with an embedded import but I'd prefer not to. Is there a way
to resolve this? Ideally a proxy reference to the current dash instance (dash.current_app) would be one
solution.

Cheers.

@AnnMarieW
Copy link
Collaborator

AnnMarieW commented Dec 18, 2021

@stevej2608

It's true that importing app within the pages folder will create a circular reference. I'll look into adding a proxy reference, but in the meantime, to access items in assets, rather than using app.get_assets_url() could you try adding the path? For example: html.Img(src="/assets/my_image.jpeg"). It worked for me when I tried it.

@M4thM4gician
Copy link

M4thM4gician commented Jan 25, 2022

First of all, BIG thank you for this module. It's been a lot of fun to learn and play with.

Is there a suggested workaround for calling the get_relative_path() method? Similar to what @stevej2608 mentioned, I get a circular reference when trying to run from app import app, but I need the relative path because the platform I'm looking to host my app on applies a unique prefix for the app (guid generated during deployment). Because of this, I can't know the path name when deploying until I've deployed the app at least once. The platform does recognize that the prefix exists as a variable and has the correct value, but I can't figure out a way to pass the requests_pathname_prefix to the modules in the /pages folder.

@AnnMarieW
Copy link
Collaborator

@M4thM4gician Glad you like pages/

We definitely need to be able to accommodate this use case. Thanks for reporting. I'll keep you posted on the progress.

@AnnMarieW
Copy link
Collaborator

AnnMarieW commented Jan 27, 2022

@stevej2608, @M4thM4gician To solve the circular reference issue we will be adding the following functions that will be similar to dash.callback where the appobject is not needed. This is on the project plan to be completed before pages/ is moved into Dash.

  • dash.get_relative_path
  • dash.strip_relative_path
  • dash.get_asset_url

This is a good first issue. Here are some tips for getting started:

  • The pull request will be in dash, rather than here in dash-labs
  • The solution will be similar to how dash.callback was created. Here is the pull request

Related issues:

Are there plans to integrate a solution to accessing the cache in callbacks outside the app.py file? For example, I have multipage app that uses a structure similar to the “Caching and Signaling” example in the docs. Once the expensive query is complete, callbacks on every page will be utilizing this same data source and need to access the global cache. Since the cache is tied to the app object, I haven’t been able to make this work on a multipage setup without just putting all my callbacks inside the app.py file. This quickly becomes hard to navigate with a larger multipage app.

@M4thM4gician
Copy link

@AnnMarieW That is REALLY exciting! Thank you so much for following up on this and for the quick responses. I'm looking forward to using this new capability to build beautiful content using Dash and Dash Labs!

@AnnMarieW
Copy link
Collaborator

PR: plotly/dash#1923

@bigmike36c
Copy link

Should a new issue be opened up for the caching issue detailed here?

Are there plans to integrate a solution to accessing the cache in callbacks outside the app.py file? For example, I have multipage app that uses a structure similar to the “Caching and Signaling” example in the docs. Once the expensive query is complete, callbacks on every page will be utilizing this same data source and need to access the global cache. Since the cache is tied to the app object, I haven’t been able to make this work on a multipage setup without just putting all my callbacks inside the app.py file. This quickly becomes hard to navigate with a larger multipage app.

@AnnMarieW AnnMarieW reopened this Feb 16, 2022
@AnnMarieW
Copy link
Collaborator

Reopening this issue - PR#1923 created:

  • dash.get_relative_path
  • dash.get_asset_url
  • dash.strip_relative_path

As described above, the following is still open:
Caching and Signaling
app.long_callback

@bigmike36c
Copy link

Just to add to this, the same issue occurs with the dashboard engine for enterprise users. The workaround is easy enough by simply registering the dashboard engine page and declaring its layout inside the app.py file. However, for code organization, it would be nice to eventually be able to break this code and the associated callbacks into its own file.

@chriddyp
Copy link
Member

Thanks for reporting @bigmike36c ! Yes agreed re dashboard engine. We'll need to make an update to that library that doesn't require app as an input argument as well. That's becoming easier with dash.callback and other properties, so we're close.

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

Successfully merging a pull request may close this issue.

5 participants