New to Dash, how to get host url in dash

like flask:

from flask import request
print(request.host_url)

I would like to get the full url of a resources to share (eg. http://127.0.0.1:8050/assets/somepng.png).

app.get_asset_url('sompng.png') 

just show the path (/assets/sompgn.png).
Thanks

As Dash uses Flask, you should just be able to use the same Flask code you posted. You’ll have to call it inside a callback, as that is during a request context.

Thanks very much!

By the way. if there is no call back needed, is it the best practice to create an invislbe DIV to binding page loading?

layout = html.Div([html.Div(id='outputdiv'),html.Div(id='invisible')])

@app.callback(Output('outputdiv', 'children'),
              [Input('invisible', 'value')])
def display_asset(value):
    SRC = request.host_url + 'assets/data.pdf'
    return html.Iframe(
    id = 'iframe',
    height='1200px',
    width='1800px',
    src = SRC
)

sorry, not quite sure what you mean. could you rephrase?

Thanks for your reply, @nedned !

You suggest that we could only call flask.request.host_url inside a callback function due to the dependency of a request context.

I have another question

import dash
import dash_html_components as html

app = dash.Dash(__name__)

app.layout = html.Div(children=[
    html.H1(children='Hello Dash'),
    # Here, I want to get this string "http://127.0.0.1:8050/assets/data.pdf"
    # But there is no callback binding with this component because it's static resource. In my opinion we should not bind callback to this function which serves static thing
    # My question is: Is there any way to get `host_url` without callback context? or I have to create a callback for it?
    html.Div(children='URL of assets/data.pdf is ...'),
    ])

app.run_server()

Actually yes, you can do this inside a layout. The trick is making your app.layout assigned to a function that returns a layout. This way the creation of the layout will be within a request context. The one catch to this is that initial callback validation needs to run the function once before the app loads, which will not be inside a request context. Rather than disabling callback validation, you can detect whether the function is being evaluated within a request context and react accordingly.

This is discussed in the URLs page of the docs, under “Dynamically Create a Layout for Multi-Page App Validation”.

Here’s a simple example illustrating this:

import dash
import dash_core_components as dcc
import dash_html_components as html
from dash.dependencies import Input, State, Output
import flask


def make_layout():
    # need to detect whether we're in a request context                                                                                                                       
    host = flask.request.host_url if flask.has_request_context() else ''
    return html.Div([
        html.Div(f"Host: {host}"),
        html.Div(id='target'),
        dcc.Input(id='my-input', type='text', value=''),
        html.Button(id='submit', n_clicks=0, children='Save')
    ])


app = dash.Dash()
app.layout = make_layout


@app.callback(Output('target', 'children'), [Input('submit', 'n_clicks')],
              [State('my-input', 'value')])
def callback(n_clicks, state):
    # we are always within a request context here                                                                                                                             
    print(flask.request.host_url)
    return "callback received value: {}".format(state)


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

Your explanation is clear.
Thanks for your time!!

1 Like