Expose user input via API

Hi all.

I’m trying to prototype a Dash front end to connect with a third party web service. I’m accessing tabular data from this third party service via their API, then displaying it in a table in Dash. However, I would like to allow the user to input data in Dash which will be passed to this third party service (via API), altering the response which is then returned to Dash. I.e., the user in Dash can control the data returned by this third party service.

To do this I need to expose an API in Dash from the underlying Flask instance. I’ve read posts here and here which detail how to achieve this.

However, I can’t get the API endpoint to work with user input returned from a callback. I’ve attached a simplified version of my code below.

I’m aware that the code attached leads to a ‘duplicate callback outputs’ error. I’ve tried adding a hidden div element to act as a faux callback output, but that approach doesn’t work with the JSON response returned by jsonify. I’ve also tried moving the server.route API endpoint into the callback function, but this doesn’t work either as the callback input isn’t passed into the get_tasks function.

All help is appreciated. Thanks.

from flask import jsonify
import dash
import dash_html_components as html
import pandas as pd
import dash_core_components as dcc
import dash_bootstrap_components as dbc
from dash.dependencies import Input, Output
import dash_table

# I've removed the actual API call. Below is an example response 
# once it's been read into pandas.
df = pd.DataFrame({'Column1': [1,2,3], 'Column2': ['a','b','c']})

external_stylesheets = ['https://codepen.io/chriddyp/pen/bWLwgP.css']

app = dash.Dash(__name__, external_stylesheets=external_stylesheets)
server = app.server

app.layout = html.Div([
    dbc.Row([
        dbc.Col([
            
            html.H5(children='Third party response data.'),
            dash_table.DataTable(
                id='table',
                columns = [{'name': i, 'id': i} for i in df.columns],
                data = df.to_dict('records'),
                fixed_rows={'headers': True},
                page_size = 10
            ),
        
        ], width = 12),
    ]), 
    html.Br(),
    # Get user input
    dbc.Row([
        dbc.Col([

            dcc.Input(
            id="input1",
            type="text",
            placeholder="input text",
            )

        ]),
    ]),
    html.Div(id="output"),
])

@app.callback(
    Output("output", "children"),
    [Input("input1", "value")],
)
def update_output_div(input1):
    return u'{}'.format(input1)

@app.callback(
    Output("output", "children"),
    [Input("input1", "value")],
)
@server.route('/api-test', methods=['GET'])
def get_tasks(input1):
    record = input1
    return jsonify({'record': record})

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

@aidanw43 I’ve been facing the same issue. Did you find any solution?

@rics unfortunately not. I’ve moved onto different projects for now but will be revisiting this at some point in the future. If I find a solution I will raise it here and mention you.