GibbsConsulting / django-plotly-dash

Expose plotly dash apps as django tags
MIT License
560 stars 125 forks source link

Assets not fetched correctly while using plotly_direct template tags #486

Open hkhare42 opened 10 months ago

hkhare42 commented 10 months ago

Really appreciate this library and the maintainers.

Previously, I had raised an issue (https://github.com/GibbsConsulting/django-plotly-dash/issues/459) when the assets for my dash app were not loading correctly. The fix was that I had to provide external_stylesheets and external_scripts in my DjangoDash constructor. Now, the app along with the related locally available assets (same folder as app) are both loading perfectly within an IFrame when I'm using the plotly_app template tag.

The issue now comes up when I try to use the plotly_direct method as per documentation (https://django-plotly-dash.readthedocs.io/en/latest/template_tags.html)

Log:

[04/Feb/2024 12:49:53] "GET /app1/assets/app_css.css HTTP/1.1" 404 2776
[04/Feb/2024 12:49:53] "GET /app1/assets/app_loading.css HTTP/1.1" 404 2776
[04/Feb/2024 12:49:53] "GET /app1/assets/app_allowed_fonts.css HTTP/1.1" 404 2776
[04/Feb/2024 12:49:53] "GET /app1/assets/app_loading_script.js HTTP/1.1" 404 2776

PLOTLY_COMPONENTS in settings.py look like this. I'm not adding dpd_components here. Don't know if that might create an issue. 'dpd_static_support' is present both here and in INSTALLED_APPS.

PLOTLY_COMPONENTS = [
    # 'dpd_components',
    'dpd_static_support',
    'dash_mantine_components',
]

DjangoDash constructor in app.py:

app_stylesheets = ['assets/app_css.css',
               'assets/app_allowed_fonts.css',
               'assets/app_loading.css']

app_scripts = ['assets/app_loading_script.js',]

app = DjangoDash('SimpleExample', serve_locally=True,
                 external_stylesheets=app_stylesheets,
                 external_scripts=app_scripts
                 )

App template:

<!-- templates/base.html -->
<!DOCTYPE html>
<html>
    <head>
    {% load plotly_dash%}
    {% plotly_header %}
    </head>
    <body>
    {%plotly_direct name="SimpleExample"%}
    </body>
    {% plotly_footer %}
</html>

This is what the app should look like: image

And this is what it looks like right now: (Basically assets are not loading properly and positioning / fonts are off) image

GibbsConsulting commented 9 months ago

@hkhare42 are you able to look in the browser developer tools window and see what URLs it is requesting, and how they vary between the normal and direct case? Also, are there any warnings or errors in the console output?

As a rule, the direct template tag variant is a bit more of a pain as you lose the isolation and compartmentalisation of the iframe. Is there a particular reason that you need to use it?

Nice app, btw. Is it, or will it be, available at a public URL?

GibbsConsulting commented 9 months ago

@hkhare42 did you add the middleware entry as mentioned in the tag documentation?

hkhare42 commented 9 months ago

thanks! the iframe version of the app is live here: https://www.datadabble.in/2018-fifa-mens-wc-explorer/

I do have the middleware entry added as well as per documentation.


URLs it is trying to access for the plotly_direct version:

image

image


In case of IFrame, it gets it from this URL:

image

Even though the links within the IFrame look similar to direct case: image


Console Log for IFrame version:

image


The only issue I have with the IFrame version is that I have to provide an aspect ratio before hand and that doesn't change dynamically with screen size. My app.css uses vw and vh units to ensure that the width and height exactly fits the user window. So, I was wondering if the plotly_direct route could get me there.

delsim commented 9 months ago

@hkhare42 I think you need to wrap them in calls to app.get_asset_url as noted in passing here but unfortunately you can't do that in the constructor of app. Can you use the vw and vh values somehow in the plotly_app template tag or change the html by overriding the actual template itself by creating a file in your Django TEMPLATES path ahead of the django-plotly-dash one?

hkhare42 commented 9 months ago

I'm wary about breaking something by trying to override the template themselves. Let me try that as last resort. For now:


For the plotly_app approach, tried: {%plotly_app name="SimpleExample" dstyle="padding-bottom: 0; height: 100vh;" %}

Got a 500 error. Probably not the right way to try passing something to dstyle. (https://github.com/GibbsConsulting/django-plotly-dash/blob/master/django_plotly_dash/templates/django_plotly_dash/plotly_app.html)


For the plotly_direct suggestion, i.e. the app.get_asset_url method, I tried to add it to the body of the app like so:

app.layout = html.Div(id='bodydiv', children = [
                    html.Link(rel='stylesheet', href=app.get_asset_url('app_css.css')),
                    ... 

But the app is still looking in the same place and unable to fetch: Refused to apply style from 'http://127.0.0.1:8000/app1/assets/app_css.css' because its MIME type ('text/html') is not a supported stylesheet MIME type, and strict MIME checking is enabled.

hkhare42 commented 8 months ago

@GibbsConsulting @delsim Looking forward to your guidance and suggestions.

GibbsConsulting commented 8 months ago

@hkhare42 did you try overriding the templates? If they are in your Django app's templates directory structure and your app is ahead of dpd in the list of Django apps, then your version of the template will be used ahead of the dpd one.