✊🏿 Black Lives Matter. Please consider donating to Black Girls Code today.
⚡️ Concerned about the grid? Kyle Baranko teaches how to predicting peak loads using XGBoost. Register for the August webinar!

Dcc.upload working on localhost but not on a hosted server in deployment

Hello All,

I have built a multipage app. One of the pages from the app is shown in the code block below. In the layout section of this page there is a dcc.upload component. The data from this component is used to populate a dash_table.DataTable.

When I run the app on localhost, it works perfectly. As soon as I put it on a hosted server, the dcc.upload stops working. When I say stops working I mean that if you click select a file, or if you drag and drop a file into the selection box, nothing happens. Nothing happens in the error logs and it seems like the callback function is not being triggered (but only on the hosted version, on localhost it is being triggered). At first I thought that the host server was blocking users from uploading files. To test this I used the fist example app from: https://dash.plotly.com/dash-core-components/upload, and it ran perfectly on the hosted server. I have also checked that the servers upload limit isn’t blocking the upload, and I have set the max upload limit to 32mb, well above the size of the xlsx file being uploaded which is <1mb.

It seems as if the way that I am using dcc.upload in my code is the root of the problem. Any advice would be much appreciated.

from server import app
import ...


warnings.filterwarnings("ignore")

format_0d = Format(
    group=Group.yes,  # 'format': Format(group=',')
    precision=0,
    scheme=Scheme.fixed,
    symbol=Symbol.no,
    # symbol_suffix=u'˚F'
)

format_4d = Format(
    group=Group.yes,  # 'format': Format(group=',')
    precision=4,
    scheme=Scheme.fixed,
    symbol=Symbol.no,
)


top_choices_multi = ['Equity', 'Bonds', 'Money Market', 'Collective Investment Schemes', 'Foreign Exchange']

# Create MULTI layout
layout = html.Div(children=[
    dcc.Dropdown(
        id='top_dropdown_multi',
        options=[{'label': name, 'value': name} for name in top_choices_multi],
        # value=top_choices[0],
        placeholder="Select Option",
        value='Equity',
        style={'width': '100%', 'display': 'inline-block', 'color': '#5d5151'}
    ),
    html.Br(),

    html.Div(id='multi_trade_rows', children=[
        html.Div(id='multi_intermediate-value3', style={'display': 'none'}),
        dash_table.DataTable(  # adjustable table block
            id='table_dropdown_multi_order',

            columns=[
                {'id': 'spacer', 'name': ' .  ', 'editable': False},
                {'id': 'Basket ID', 'name': 'Basket ID', 'editable': False},
                {'id': 'Entry Type', 'name': 'Side', 'editable': False},
                {'id': 'Portfolio', 'name': 'Portfolio', 'editable': False},
                {'id': 'TIF', 'name': 'TIF', 'editable': True, 'presentation': 'dropdown'},
                {'id': 'Bloomberg_Ticker', 'name': 'Ticker', 'editable': False},
                {'id': 'Order Type', 'name': 'Type', 'editable': True, 'presentation': 'dropdown'},
                {'id': 'Limit', 'name': 'Limit Price', 'editable': True, 'type': 'numeric', 'format': format_0d},
                {'id': 'Currency', 'name': 'Currency', 'editable': False},
                {'id': 'Percent_NAV', 'name': '% NAV', 'editable': False, 'type': 'numeric', 'format': format_4d},
                {'id': 'Target_Percent', 'name': '% Target', 'editable': False, 'type': 'numeric', 'format': format_4d},
                {'id': 'Order Weight', 'name': '% Order', 'editable': True, 'type': 'numeric', 'format': format_4d},
                {'id': 'Holding', 'name': 'Current Holding', 'editable': False, 'type': 'numeric', 'format': format_0d},
                {'id': 'Market_Value', 'name': 'Market Value', 'editable': False, 'type': 'numeric',
                 'format': format_0d},
                {'id': 'New Holding', 'name': 'New Holding', 'editable': False, 'type': 'numeric', 'format': format_0d},
                {'id': 'New Value', 'name': 'New Val', 'editable': False, 'type': 'numeric', 'format': format_0d},
                {'id': 'Quantity', 'name': 'Order Qty', 'editable': False, 'type': 'numeric', 'format': format_0d},
                {'id': 'Order Value', 'name': 'Order Val', 'editable': False, 'type': 'numeric', 'format': format_0d},

            ],
            editable=True,
            dropdown={

                'Order Type': {
                    'options': [
                        {'label': i, 'value': i}
                        for i in ['MKT', 'LMT']
                    ]
                },

                'TIF': {
                    'options': [
                        {'label': i, 'value': i}
                        for i in ['DAY', 'GTC']
                    ]
                },
                # 'Target_Percent': {
                #    'options': return_actions()
                # }
            },
            style_table=table_style[0],
            style_cell=table_style_cell[0],
            style_cell_conditional=table_style_cell_conditional[0],
            style_header=table_style_header[0],
            style_data_conditional=[table_style_data_conditional[0]],
        ),
        html.Br(),

        dbc.Row(children=[
            dbc.Col(width=7,
                    children=[

                        html.Div(
                            className="three columns",
                            children=[
                                # html.Br(),
                                html.Div('Instructions', style={'color': '#fdfdfd'}),
                                dcc.Input(id="multi_2_input_instructions", placeholder="...",  # type="text",
                                          # debounce=True,
                                          style={'height': '35px', 'width': '100%'}),
                            ]  # instructions
                        ),
                        html.Div(
                            className="three columns",
                            children=[
                                # html.Br(),
                                html.Div('Benchmark', style={'color': '#fdfdfd'}),
                                dcc.Dropdown(id='multi_drop_down_benchmark', placeholder='Benchmark',
                                             style={'height': '30px', 'color': '#5d5151', 'width': '100%'},
                                             value='Price',
                                             options=[{'label': 'Price', 'value': 'Price'},
                                                      {'label': 'Volume', 'value': 'Volume'},
                                                      {'label': 'VWAP', 'value': 'VWAP'}]
                                             # {'label': 'Pair', 'value': 'Pair'}],
                                             )
                            ]  # bench
                        ),
                        # last six 66666
                        html.Div(id='multi_2_block_last_six', className='six rows', children=[
                            html.Div(id='multi_2_hidden_price',
                                     children=[html.Div(className="one columns"), html.Div(
                                         className="three columns",
                                         children=[
                                             # html.Br(),
                                             html.Div('Price Target', style={'color': '#fdfdfd'}),
                                             dcc.Dropdown(id='multi_2_drop_down_price_target',
                                                          placeholder='Price Target',
                                                          style={'height': '30px', 'color': '#5d5151', 'width': '100%'},
                                                          options=[{'label': i, 'value': i} for i in
                                                                   ['Arrival', 'Close']],
                                                          # , 'Specific']],
                                                          value='Arrival')
                                         ]
                                     ),
                                               html.Div(id='multi_2_last_three_price',
                                                        style={'display': 'none'},
                                                        className="three columns",
                                                        children=[
                                                            # html.Br(),
                                                            html.Div('Target Price', style={'color': '#fdfdfd'}),

                                                            dcc.Input(
                                                                id="multi_2_input_target_price_single_order",
                                                                placeholder="Target",
                                                                type='number', min=0, max=99999999, step=0.1,
                                                                debounce=True,
                                                                value=None,
                                                                style={'height': '35px', 'width': '100%',
                                                                       'format': format_0d},
                                                            ),

                                                        ],
                                                        )]),
                            html.Div(id='multi_2_hidden_vwap',
                                     children=[html.Div(className="one columns"), html.Div(
                                         className="three columns",
                                         children=[
                                             # html.Br(),
                                             html.Div('VWAP Target', style={'color': '#fdfdfd'}),
                                             dcc.Dropdown(id='multi_2_drop_down_vwap_target',
                                                          placeholder='VWAP Target',
                                                          style={'height': '30px', 'color': '#5d5151', 'width': '100%'},
                                                          options=[{'label': i, 'value': i} for i in
                                                                   ['Full Day', 'Now to Close', 'Duration']], )
                                         ]),
                                               html.Div(id='multi_2_last_three_vwap', style={'display': 'none'},
                                                        className="three columns",
                                                        children=[
                                                            # html.Br(),
                                                            html.Div('VWAP Duration', style={'color': '#fdfdfd'}),
                                                            dcc.Dropdown(id='multi_2_drop_down_vwap_hours',
                                                                         placeholder='VWAP Duration',
                                                                         style={'height': '30px', 'color': '#5d5151',
                                                                                'width': '100%'},
                                                                         options=[{'label': i, 'value': i} for i
                                                                                  in
                                                                                  ['Next 1 Hour',
                                                                                   'Next 2 Hours',
                                                                                   'Next 3 Hours',
                                                                                   'Next 4 Hours',
                                                                                   'Next 5 Hours',
                                                                                   'Next 6 Hours',
                                                                                   'Next 7 Hours']], )

                                                        ],
                                                        )]),
                            html.Div(id='multi_2_hidden_volume',
                                     children=[html.Div(className="one columns"), html.Div(
                                         className="three columns",
                                         children=[
                                             # html.Br(),
                                             html.Div('Volume Target', style={'color': '#fdfdfd'}),
                                             dcc.Dropdown(id='multi_2_drop_down_volume_target',
                                                          placeholder='Volume Target',
                                                          style={'height': '30px', 'color': '#5d5151', 'width': '100%'},
                                                          options=[{'label': i, 'value': i} for i in
                                                                   ['5%', '10%', '15%', '20%', '25%', '33%',
                                                                    '40%', '50%']],
                                                          )
                                         ]
                                     )]),
                            html.Div(id='multi_2_hidden_pair',
                                     children=[html.Div(className="one columns"), html.Div(
                                         className="three columns",
                                         children=[
                                             # html.Br(),
                                             html.Div('Other Security', style={'color': '#fdfdfd'}),
                                             dcc.Input(id="multi_2_input_ticker_pair", type="text",
                                                       placeholder="...",
                                                       debounce=True,
                                                       style={'height': '35px', 'width': '100%', 'color': '#5d5151',
                                                              'text-transform': 'uppercase'})
                                         ]
                                     ),
                                               html.Div(id='multi_2_last_three_pair',
                                                        style={'display': 'block'},
                                                        className="three columns",
                                                        children=[
                                                            # html.Br(),
                                                            html.Div('Target Ratio', style={'color': '#fdfdfd'}),
                                                            dcc.Input(id="multi_2_input_target_pair_price",
                                                                      placeholder="Target Ratio",
                                                                      debounce=True,
                                                                      type='number', min=0, max=999999999,
                                                                      step=0.0000000001,
                                                                      style={'height': '35px',
                                                                             'width': '100%', 'color': '#5d5151'}),

                                                        ],
                                                        )])

                        ]),

                    ]),
            dbc.Col(width=5,
                    children=[
                        html.Div(
                            className="row",  # buttons
                            children=[
                                html.Div(
                                    className="four columns",  # clear button
                                    children=[
                                        html.Br(),
                                        html.Div(' '),
                                        html.Button('Clear', id='multi_button_clear',
                                                    style={'height': '35px',
                                                           'width': '100%',
                                                           'backgroundColor': 'rgb(45, 130, 133)'})

                                    ]
                                ),
                                html.Div(
                                    className="four columns",  # clear button
                                    children=[
                                        html.Br(),
                                        html.Div(' '),
                                        html.Button('Import ⇊', id='multi_button_import',
                                                    style={'height': '35px',
                                                           'width': '100%',
                                                           'backgroundColor': 'rgb(45, 130, 133)'})

                                    ]
                                ),
                                html.Div(
                                    className="four columns",  # create button
                                    children=[
                                        html.Br(),
                                        html.Div(' '),
                                        dcc.ConfirmDialogProvider(
                                            children=[
                                                html.Button('SEND', style={'height': '35px',
                                                                           'width': '100%',
                                                                           'backgroundColor': 'rgb(45, 130, 133)'})
                                            ],
                                            id='multi_21_button_create_provider_',
                                            message='Confirm Send Orders'
                                        ),
                                    ]
                                ),

                            ]
                        ),
                        html.Div(
                            className="row",  # buttons
                            children=[
                                html.Div(
                                    className="twelve columns",  # clear button
                                    children=[
                                        html.Br(),
                                        dcc.Upload(
                                            id='upload_data',
                                            children=html.Div([
                                                'Drag and Drop or ',
                                                html.A('Select a File', style={'color': '#fdfdfd',
                                                                               'backgroundColor': 'rgb(45, 130, 133)'},
                                                       )
                                            ], style={'color': 'grey'}, ),
                                            style={'display': 'none'},
                                            # Allow multiple files to be uploaded
                                            multiple=False
                                        )]
                                ), ]
                        )
                    ]),
        ]),

    ]),
    html.Div(id='output-provider', style={'display': 'none'}),
    html.Div(id='multi_div_hidden_create_button', style={'display': 'none'}),
    dcc.Store(id='multi_2_stored_bench', storage_type='session'),
    html.Div(list("ABC"), id="multi_2_data_hid", style={"display": "none"}),
])


@app.callback(Output('multi_button_clear', 'n_clicks'),
              [Input('multi_21_button_create_provider_', 'submit_n_clicks')])
def clear_all(n):
    return 1


# Hidden fields BUTTON
@app.callback(Output('upload_data', 'style'),
              [Input('multi_button_import', 'n_clicks')])
def show_hide_element_limit(n_clicks):
    if n_clicks != None:
        if n_clicks % 2 != 0:
            return {
                'width': '100%',
                'height': '60px',
                'lineHeight': '60px',
                'borderWidth': '1px',
                'borderStyle': 'dashed',
                'borderRadius': '5px',
                'textAlign': 'center',
                'display': 'block',
                'backgroundColor': '#fdfdfd'
            }
        else:
            return {'display': 'none'}

    else:
        return {'display': 'none'}


@app.callback(Output('multi_2_stored_bench', 'data'),
              [
                  Input('multi_2_data_hid', 'children'),
                  # Input('multi_div_hidden_create_button', 'children'),
                  Input('multi_drop_down_benchmark', 'value'),
                  Input('multi_2_drop_down_price_target', 'value'),
                  Input('multi_2_input_target_price_single_order', 'value'),
                  Input('multi_2_drop_down_vwap_target', 'value'),
                  Input('multi_2_drop_down_vwap_hours', 'value'),
                  Input('multi_2_drop_down_volume_target', 'value'),
                  Input('multi_2_input_ticker_pair', 'value'),
                  Input('multi_2_input_target_pair_price', 'value'),
              ])
def make_bench_string(hd1, bench, target, spec_price, vwap_targ, vwap_dur, vol_targ, pair, pair_price):
    if bench == None:
        return ''

    if bench == 'Price':
        bench_str = str(bench) + ' ' + str(target)
        if target == 'Specific':
            bench_str += ' ' + str(spec_price)

    if bench == 'VWAP':
        bench_str = str(bench) + ' ' + str(vwap_targ)
        if vwap_targ == 'Duration':
            bench_str += ' ' + str(vwap_dur)

    if bench == 'Volume':
        bench_str = str(bench) + ' ' + str(vol_targ)

    if bench == 'Pair':
        bench_str = 'Pair' + ' ' + str(pair) + ' ' + str(pair_price)

    return str(bench_str)


@app.callback(Output('multi_div_hidden_create_button', 'children'),
              [Input('multi_21_button_create_provider_', 'submit_n_clicks')],
              [State('store_privileges', 'data'),
               State('table_dropdown_multi_order', 'data'),
               State('multi_2_stored_bench', 'data'),
               State('top_dropdown_multi', 'value'),
               State('multi_2_input_instructions', 'value'),
               ])
def multi_clear_side(n_clicks, df, store, bench_str, ac, instruct):
    if (not n_clicks) or (not store):
        return None
    asc = str(ac)
    for i in range(len(store)):
        # print(store[i])
        por = store[i]['Portfolio']
        ticr = store[i]['Bloomberg_Ticker']
        side = store[i]['Entry Type']
        quan = store[i]['Quantity']
        tif = store[i]['TIF']

        if 'Basket ID' in store[i].keys():
            bskt = store[i]['Basket ID']
        else:
            bskt = None

        if 'Order Type' in store[i].keys():
            typ = store[i]['Order Type']
        else:
            typ = None

        if 'Order Weight' in store[i].keys():
            ord_weight = store[i]['Order Weight']
        else:
            ord_weight = None

        if 'Currency' in store[i].keys():
            cur = store[i]['Currency']
        else:
            cur = None

        if 'Percent_NAV' in store[i].keys():
            cp = store[i]['Percent_NAV']
        else:
            cp = None

        if 'Limit' in store[i].keys():
            lim_price = store[i]['Limit']
        else:
            lim_price = None

        place_order_in_db.create_order(port=por, ac=asc, tic=ticr, side=side,
                                       amount=str(quan), order_type=typ, cfd=None, tif=tif, strat=bench_str,
                                       instructions=str(instruct), broker=None, pf_c=str(cp), pf_t=str(ord_weight),
                                       limit=str(lim_price), tp=None, cur=cur, bskt=bskt)


def parse_contents(contents, filename, date):
    content_type, content_string = contents.split(',')

    decoded = base64.b64decode(content_string)
    try:
        if 'csv' in filename:
            # Assume that the user uploaded a CSV file
            df = pd.read_csv(
                io.StringIO(decoded.decode('utf-8')))
        elif 'xls' in filename:
            # Assume that the user uploaded an excel file
            df = pd.read_excel(io.BytesIO(decoded),  sheet_name='Equity Orders')
            df.columns = df.iloc[0]
            df = df.drop(df.index[0])

    except Exception as e:
        print(e)
        return html.Div([
            'There was an error processing this file.'
        ])
    return df.to_dict('records')


@app.callback(Output('table_dropdown_multi_order', 'data'),
              [Input('multi_21_button_create_provider_', 'submit_n_clicks'),
               Input('multi_button_clear', 'n_clicks'),
               Input('table_dropdown_multi_order', 'data_timestamp'),
               Input('store_1', 'data'),
               Input('upload_data', 'contents')],
              [State('table_dropdown_multi_order', 'data'),
               State('store_1', 'data'),
               State('upload_data', 'filename'),
               State('upload_data', 'last_modified')])
def multi_clear_all(upload_event, n_clicks, time_stamp, df, list_of_contents, df_state, df_state_store_1,
                    list_of_names, list_of_dates):
    ctx = dash.callback_context
    if not ctx.triggered:
        trigger_id = 'No clicks yet'
    else:
        trigger_id = ctx.triggered[0]['prop_id'].split('.')[0]

    if trigger_id == 'multi_21_button_create_provider_':
        trigger_id = 'multi_button_clear'

    if trigger_id == 'upload_data':
        print('upload triggered')
        if list_of_contents is not None:
            children = [
                parse_contents(list_of_contents, list_of_names, list_of_dates)]
            print(children)
            return children[0]

        else:
            return []

    if trigger_id == 'multi_button_clear':
        return list()

    data = pd.DataFrame(df_state)
    if trigger_id == 'table_dropdown_multi_order' and all(data.get('Order Weight') == None):
        trigger_id = 'store_1'
        df = df_state

    if trigger_id == 'store_1':
        data = pd.DataFrame(df)
        df_to_ret = data.copy()

        if len(data) > 1 and 'Target_Percent' in data.keys():

            if data['Target_Percent'].isnull().sum() > 0:
                return list()


            data['Target_Percent'] = pd.to_numeric(data['Target_Percent'], errors='coerce')
            if data['Target_Percent'].isnull().sum() > 0:
                return list()


            df_to_ret['Quantity'] = round(
                abs((data['Target_Percent'] - data['Percent_NAV']) / data['Percent_NAV']) * data['Holding'])

            df_to_ret['price_per_sec'] = (data['Market_Value'] / data['Holding'])

            df_to_ret['New Holding'] = df_to_ret['price_per_sec'].copy()

            if all(data.get('Entry Type') == None):
                df_to_ret['Entry Type'] = df_to_ret['price_per_sec'].copy()
                df_to_ret.loc[data['Target_Percent'] == data['Percent_NAV'], 'Entry Type'] = None
                df_to_ret.loc[data['Target_Percent'] > data['Percent_NAV'], 'Entry Type'] = 'BUY'
                df_to_ret.loc[data['Target_Percent'] < data['Percent_NAV'], 'Entry Type'] = 'SELL'

            df_to_ret.loc[data['Target_Percent'] == data['Percent_NAV'], 'New Holding'] = \
                df_to_ret.loc[data['Target_Percent'] == data['Percent_NAV'], 'Holding']

            df_to_ret.loc[data['Target_Percent'] > data['Percent_NAV'], 'New Holding'] = \
                df_to_ret.loc[data['Target_Percent'] > data['Percent_NAV'], 'Holding'] + \
                df_to_ret.loc[data['Target_Percent'] > data['Percent_NAV'], 'Quantity']

            df_to_ret.loc[data['Target_Percent'] < data['Percent_NAV'], 'New Holding'] = \
                df_to_ret.loc[data['Target_Percent'] < data['Percent_NAV'], 'Holding'] - \
                df_to_ret.loc[data['Target_Percent'] < data['Percent_NAV'], 'Quantity']

            # TIF default
            if all(data.get('TIF') == None):
                df_to_ret['TIF'] = 'GTC'

            if all(data.get('Order Type') == None):
                df_to_ret['Order Type'] = 'MKT'

            df_to_ret['New Value'] = df_to_ret['New Holding'] * df_to_ret['price_per_sec']

            df_to_ret['Order Value'] = df_to_ret['Quantity'] * df_to_ret['price_per_sec']

            df_to_ret['Order Weight'] = df_to_ret['Target_Percent']

            return df_to_ret.to_dict('records')
        else:
            return list()

    returner = pd.DataFrame(df_state_store_1)

    if trigger_id == 'table_dropdown_multi_order' and 'Target_Percent' in data.keys():

        data = pd.DataFrame(df_state)
        data['Order Weight'] = pd.to_numeric(data['Order Weight'], errors='coerce')

        df_to_ret = data.copy()

        df_to_ret['Order weight temp'] = data['Order Weight']

        df_to_ret.loc[data['Order Weight'] == None, 'Order weight'] = df_to_ret.loc[
            data['Order Weight'] == None, 'Target_Percent']

        if data['Target_Percent'].isnull().sum() > 0:
            return returner.to_dict('records')

        # df['Target_Percent Column'] = df['Target_Percent Column'].astype(float)

        data['Target_Percent'] = pd.to_numeric(data['Target_Percent'], errors='coerce')
        if data['Target_Percent'].isnull().sum() > 0:
            return returner.to_dict('records')

        df_to_ret['Quantity'] = round(
            abs((data['Order Weight'] - data['Percent_NAV']) / data['Percent_NAV']) * data['Holding'])

        df_to_ret['price_per_sec'] = (data['Market_Value'] / data['Holding'])

        df_to_ret['Entry Type'] = df_to_ret['price_per_sec'].copy()
        df_to_ret['New Holding'] = df_to_ret['price_per_sec'].copy()

        # Side:
        df_to_ret.loc[data['Order Weight'] == data['Percent_NAV'], 'Entry Type'] = None
        df_to_ret.loc[data['Order Weight'] > data['Percent_NAV'], 'Entry Type'] = 'BUY'
        df_to_ret.loc[data['Order Weight'] < data['Percent_NAV'], 'Entry Type'] = 'SELL'

        df_to_ret.loc[data['Order Weight'] >= data['Percent_NAV'], 'New Holding'] = \
            df_to_ret.loc[data['Order Weight'] >= data['Percent_NAV'], 'Holding'] + \
            df_to_ret.loc[data['Order Weight'] >= data['Percent_NAV'], 'Quantity']

        df_to_ret.loc[data['Order Weight'] < data['Percent_NAV'], 'New Holding'] = \
            df_to_ret.loc[data['Order Weight'] < data['Percent_NAV'], 'Holding'] - \
            df_to_ret.loc[data['Order Weight'] < data['Percent_NAV'], 'Quantity']

        df_to_ret['TIF'] = 'GTC'


        for i, row in df_to_ret.iterrows():
            ifor_val = 'MKT'
            print(data.at[i, 'Limit'])
            if data.at[i, 'Limit'] > 0:
                ifor_val = 'LMT'
            print('next')
            df_to_ret.at[i, 'Order Type'] = ifor_val

        df_to_ret['New Value'] = df_to_ret['New Holding'] * df_to_ret['price_per_sec']

        df_to_ret['Order Value'] = df_to_ret['Quantity'] * df_to_ret['price_per_sec']



        return df_to_ret.to_dict('records')


    else:
        return df_state

I don’t want to inundate the person reading this question with code, so I have included just the page in question from the multipage app. If this is not enough then please let me know and I will make a simple app that copies mine with some of the other scripts included.

Thank you

Hi @maaxnaax,

Let’s settle on the terminologies first: the python app runs on a host, called server side. On the contrary, in a production setting, clients will be accessing the server from their ends, called client side.

That being said, I can load a file in the client side fine for the first example here. However, I made sure the client has access to the server. For my purpose, I use and SSH tunnel.

Now coming back to your debugging-- I would write a simple callback like the example to check if file loading indeed triggers the callback or not. Putting a print() statement inside that callback can help.

1 Like

Could you be able to produce a minimal example code that reproduces your problem?

1 Like

Hello All thank you for the replies and for clearing up the terminology. It turned out that there was a circular set of callbacks that was causing the app to hang in the live version, so the update which would usually be caused by the upload want triggering.

1 Like