AttributeError: assets_external_path when calling dash.get_asset_url

I get AttributeError: assets_external_path when calling dash.get_asset_url. Maybe is worth noting that when creating the app with dash.Dash I’m setting a custom assets_folder='path/to/my/assets'
Is it a bug or am I missing something?
I think the problem arouse when updating dash to 2.3, but I’m not 100% sure and I can’t get rid of the problem downgrading to dash 2.1

Hi @aleskeyfedorovich

Could you please make a minimal example that reproduces the error? It seems to work fine when I tried it.

I had an image in my_file/assets/home.jpeg it worked for both app.get_assets_url() and dash.get_assets.url()

import dash
from dash import Dash, html

app= Dash(__name__, assets_folder="my_files/assets")

app.layout = html.Div([
    html.Img(src=dash.get_asset_url("home.jpeg")),
    html.Img(src=app.get_asset_url("home.jpeg"))

])

if __name__ == '__main__':
    app.run_server(debug=True)

Hi @aleskeyfedorovich

I ran into a similar error these days. In my case the error was associated to situations where the get_asset_url was not used in a function in nested module to split the application. Here is the minimal examples. There are two files:

no error

This one works (with function)

# main app.py file
from dash import Dash, html

from components import my_img

app= Dash(__name__, assets_folder="my_files/assets")

app.layout = html.Div([
    my_img()
])

if __name__ == '__main__':
    app.run_server(debug=True)
# components.py

import dash
from dash import html

def my_img():
    return html.Img(src=dash.get_asset_url("home.jpeg"))

with error

This one returns an error (without function). Note that the only difference is the parenthesis in app.py

# main app.py file
from dash import Dash, html

from components import my_img

app= Dash(__name__, assets_folder="my_files/assets")

app.layout = html.Div([
    my_img
])

if __name__ == '__main__':
    app.run_server(debug=True)
# components.py

import dash
from dash import html

my_img = html.Img(src=dash.get_asset_url("home.jpeg"))

Here is the error:

Traceback (most recent call last):
  File "/Users/toto/git/projet/app/test_app/app2.py", line 4, in <module>
    from components import my_img
  File "/Users/toto/git/projet/app/test_app/components.py", line 9, in <module>
    my_img = html.Img(src=dash.get_asset_url("home.jpeg"))
  File "/Users/toto/opt/miniconda3/envs/env/lib/python3.9/site-packages/dash/_get_paths.py", line 8, in get_asset_url
    return app_get_asset_url(CONFIG, path)
  File "/Users/toto/opt/miniconda3/envs/env/lib/python3.9/site-packages/dash/_get_paths.py", line 12, in app_get_asset_url
    if config.assets_external_path:
  File "/Users/toto/opt/miniconda3/envs/env/lib/python3.9/site-packages/dash/_utils.py", line 84, in __getattr__
    raise AttributeError(key)
AttributeError: assets_external_path

@AnnMarieW maybe here it is a “best practice” error ? Why do I need the function ?

Hi @gvallverdu

Thanks for the excellent minimal examples - it clearly shows the issue. :medal_sports:

For now, the best practice for this type of project structure is to make my_image a function like in your first example. It’s necessary for the app to be instantiated before dash.get_asset_url() will work properly.

When my_image is a function, it runs when it’s called (after the app starts) so there is no error.

If my_image is not a function, dash.get_asset_url() runs when it’s imported (before the app starts). Since it relies on configuration files that exist only after the app starts, you see the error.

Ideally, it should work both ways without errors. But in the meantime, I can at least make that error message better. If you have any suggestions for a concise and meaningful message, that would be great.

wow nice, thank you