✊🏿 Black Lives Matter. Please consider donating to Black Girls Code today.
🐇 Announcing Dash VTK for 3d simulation graphics. Check out the March webinar.

Dash + AioHTTP?

is it possible to just set the dash.server instance to an aiohttp?

I read that it is based on flask, but flask isn’t suitable for production/etc. I’m using aiohttp for a graphql subscription server / api that is then working with IOT devices so… flask isn’t entirely suitable. However, I’d like to use dash with this.

Thanks

flask is suitable for production if you run it with gunicorn. In any case, you probably won’t be able to swap in aiohttp as a replacement for flask but you could write an alternative dash backend that uses aiohttp if you want.

I recommend looking through the source code of Dash to learn more: https://github.com/plotly/dash/blob/3cd6a78ee21620c77ccdbdf2724c995872383666/dash/dash.py

Oblivious to this thread I have taken a stab at the topic due to my app’s demand (one part of my app generates data via asyncio/aiohttp and another needs to visualise and update based on a DataFrame).

Here’s a partially working example:

from asyncio import get_event_loop
from aiohttp.web import AppRunner, Application, Response, TCPSite, get
from aiohttp_wsgi import WSGIHandler
import dash_core_components as dcc
import dash_html_components as html
from dash.dependencies import Output,Input
from dash import Dash
from numpy.random import rand

def graph_figure():
    print(rand(5))
    return {'data':   [{'x': rand(5), 'y': rand(5), 'type': 'bar', 'name': 'SF'}],
            'layout': {'title': 'Test'}
            }

app = Dash('Orderbook')

def layout():
    return html.Div(children=[
    dcc.Graph(id='example-graph',
              figure=graph_figure()
             ),

    html.Button(
            'Submit',
            id='button'),

    dcc.Interval(
            id='interval-component',
            interval=1*1000, # in milliseconds
            n_intervals=0
            )
    ])

app.layout = layout

@app.callback(Output('example-graph', 'figure'), [Input('button', 'n_clicks'), Input('interval-component', 'n_intervals')])
def update_graph(n, n2):
    return graph_figure()

server = Application()
runner = AppRunner(server)

async def start_webapp() -> None:
    wsgi_handler = WSGIHandler(app.server)
    server.router.add_route('get', '/{path_info:.*}', wsgi_handler)
    await runner.setup()
    await TCPSite(runner, 'localhost', 8080).start()

if __name__ == '__main__':
    # app.run_server() # THIS WORKS

    # THIS DOES NOT WORK:
    loop = get_event_loop()
    loop.run_until_complete(start_webapp())
    loop.run_forever()

This generates and serves a plot, however updates via Interval and Button components do not work - the callback is not called.
Does anybody have any neat ideas how to force the callback trigger? Or should I come to terms with a static plot?