Deploy Dash App to Azure Function

I am trying to deploy a Dash app in an Azure Function. When I am using

app = func.WsgiFunctionApp(
    app=dash_app.server.wsgi_app, 
    http_auth_level=func.AuthLevel.ANONYMOUS
    )

@app.function_name(name="HomePage")
@app.route(route="api", auth_level=func.AuthLevel.ANONYMOUS)
def api_page(req: func.HttpRequest) -> func.HttpResponse:
    return func.WsgiMiddleware(dash_app.server).handle(req)

It works pretty good. However, when I tried to use

app = func.FunctionApp()
@app.function_name('App-1')
@app.route(route="api", auth_level=func.AuthLevel.ANONYMOUS)
def app_1(req: func.HttpRequest) -> func.HttpResponse:
    dash_app = create_dash()
    return func.WsgiMiddleware(dash_app.server).handle(req)

It shows ‘Error Loading Layout’ in local emulator and remains ‘Loading…’ in Azure Function.

Does anyone know how to fix it?

Here is a simple demo that can reproduce the error.

simple_demo.py

import dash
from dash import html

def create_dash():
    app = dash.Dash(
        __name__,
        )

    app.layout = html.Div([
        html.H1(f"Dash App"),
    ])

    return app.server

function_app.py

import azure.functions as func
fomr simple_demo import create_dash

app = func.FunctionApp()

@app.function_name(name="HomePage")
@app.route(route="api", auth_level=func.AuthLevel.ANONYMOUS)
def api_page(req: func.HttpRequest) -> func.HttpResponse:
    dash_app = create_dash()
    return func.WsgiMiddleware(dash_app).handle(req)

It shows 404 when trying to get dash-layout, dash-dependencies, and css from /asset/style.css

Hello @xychen,

It looks like maybe you should have the route of api added to the dash app. I’m assuming that it doesnt have the proper configuration carried over to direct the requests to the proper endpoint.

Hi @jinnyzor,

Thanks for your reply! Could you give me a detail about how to add the route of api to the dash app? Does that mean I need to create dash app like following?

app = dash.Dash(
        __name__,
        routes_pathname_prefix="/api/"
        )

Yes, I believe so.

It still shows 404. But now it shows 404 on uri: "/api/_dash-component-suites, /api/assets/script.js, /api/_favicon.ico, etc.

According to this:

It looks like you are missing this:

def main(req: func.HttpRequest, context: func.Context) -> func.HttpResponse:
    """Each request is redirected to the WSGI handler.
    """
    return func.WsgiMiddleware(app.wsgi_app).handle(req, context)

Notice the bit about the context.

I’m also not quite sure of what you do with these:

It looks host.json should be in the main app director, while the function.json should be in the HandleApproach directory

Thanks for the information. However, I am trying to use the Azure Function Python V2 model, which is using the decorator to do what function.json does.

I have a create_dash(id) function and try to deploy it for different ids in a single Function App.

When I was using following code to deploy in different Function Apps, they can work.

dash_app = create_dash()

app = func.WsgiFunctionApp(
    app=dash_app.wsgi_app, 
    http_auth_level=func.AuthLevel.ANONYMOUS
    )

However, when I tried to use following code, it won’t work. It will show ‘Error Loading Layout’ when running locally and remaining ‘Loading’ in cloud.

app = func.FunctionApp()

It seems like when using WsgiFunctionApp, it can detect the ‘assets’ folder and any other .css or .js files. But FunctionApp can not.

Do you have any idea about it?

This is what copilot says:

My guess is that, with FunctionApp you need to explicitly open the routes, while WsgiFunctionApp and AsgiFunctionApp allow you to run the whole webserver.

1 Like

Thanks for your help! This may explain why when I used FunctionApp, it didn’t get those static files.

1 Like