Learn how to use Dash Bio for next-gen sequencing & quality control. 🧬Register for the Oct 27 webinar.

Create table with input of crypto address with callback

Hello,
Im trying to use a basic input box with submit button to input an ethereum crypto address and then use that in a url inside a function for a callback to create a datatable from the results of the output, im having two problems i cant seem to get over. Just to say, all of this works independently in jupyterlab with python/web3.py as I work with python/web3 and crypto data alot, its just the callbacks/function/output in dash that i cant seem to get to read the address correctly from the input box…

  1. The initial load is firing the callback even though i have… prevent_initial_callback=True… when i refresh the page i get an error that is the following (below) . Im sure this is from the method/function call to the api in the url reading the address=input-value from the 1st line inside the function which is this…

address_df = eth.get_erc20_token_transfer_events_by_address(
address=input_value, startblock=0, endblock=999999999, sort=“asc”)

it seems it doesnt like the data type of the address=input_value… i can do this exact thing in jupterlab w/
address = input(“address”) and then use address= address…

For those who arent familar w/addresses they are like ( 0x3339EBb4c07Eed001E2BdA6447B8591ba6F6D687)
so it has # and letters… so cant use type=number i believe…

The first error screenshot here is the invalid address… this happens when the app is fired (should not be firing as i have put in prevent initial callback=true…and then when i input the address with “” it says invalid address error message again… when i try the address with no ‘’"" it gives me this 2nd error… no transactions found?

I have made this example as simple as possible in the below code w/1 page app to be recreatable for anyone to use.

I have dash1.20.0
Dcc verion 1.16.0
python 3.7.10

import dash
import dash_core_components as dcc
import dash_html_components as html
import pandas as pd
import plotly.express as px     
from dash.dependencies import Input, Output, State
import dash_table
from etherscan.etherscan import Etherscan
from pandas.io.json import json_normalize
import datetime
from eth_utils import address
import web3

app = dash.Dash(__name__)

# (link to get free key below, this is simple call to free api)
api_key = "PXPK9N" 

eth = Etherscan(api_key, net="ropsten")
# ------------------------------------------------------------------------
input_types = ['text']

app.layout = html.Div([
    html.Div([
        dcc.Input(id='input-box', value='', type='text',
                  placeholder='Enter Your Crypto Address', ),
        html.Button('Submit', id='button'),

    ]),

    html.Br(),

    html.Div(id='mytable', className='pb-5'),
    # dash_table.DataTable(
    #    id='mytable')

])

# ------------------------------------------------------------------------

@app.callback(
    Output(component_id='mytable', component_property='children'),
    [Input(component_id='button', component_property='n_clicks'),
     State('input-box', 'value'),
    
     ], prevent_initial_callback=True,
)
def make_table(n_clicks, input_value):
    # Get Token Transfer Events By Address
    address_df = eth.get_erc20_token_transfer_events_by_address(
        address=input_value, startblock=0, endblock=999999999, sort="asc")
    address_df = json_normalize(address_df)
#  address_df.head()
    address_date = address_df['timeStamp'].astype(int)
    time_list = []
    time = address_date.to_list()
    for t in time:
        big_time = datetime.datetime.fromtimestamp(t).isoformat()
        time_list.append(big_time)
#   print(time_list)

    address_df['Date'] = time_list
    address_df['id'] = address_df['tokenName']
    address_df.set_index(pd.to_datetime(
        address_df['Date'], infer_datetime_format=True), inplace=True),
#   address_df.drop(columns=['Date'], inplace=True)
    print(type(address_df))
    return dash_table.DataTable(
        id=id,
        css=[{'selector': '.row', 'rule': 'margin: 0'}],
        columns=[
            {"name": i, "id": i} for i in address_df.columns
        ],
        style_header={
            'backgroundColor': 'rgb(230, 230, 230)',
            'fontWeight': 'bold'},
        style_cell={'textAlign': 'left'},
        style_data={
            'whiteSpace': 'normal',
            'height': 'auto',
            # 'lineHeight': lineHeight
        },

        style_data_conditional=[
            {
                'if': {'row_index': 'odd'},
                'backgroundColor': 'rgb(248, 248, 248)'
            }
        ],
        style_cell_conditional=[
            {'if': {'column_id': 'title'},
             'width': '130px'},
            {'if': {'column_id': 'post'},
                'width': '500px'},
            {'if': {'column_id': 'datetime'},
                'width': '130px'},
            {'if': {'column_id': 'text'},
                'width': '500px'}],
        page_current=0,
        # page_size=page_size,
        page_action='custom',
        filter_action='custom',
        filter_query='',
        sort_action='custom',
        sort_mode='multi',
        sort_by=[]
    )  # end table


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

ANY HELP would be appreciated.

So to sum up, the problem is the data type ( i think this is how i should be saying this) of the “address” that is being entered into the input box and then submitted with the button is not going into the url = address=“address” part right to make the url call to etherscan to get the address transaction data…

The only issue to recreate is an api key for etherscan which is free to get at the link below … Sorry there is no other way to query this blockchain data but to get an api key for etherscan or someone like infura but for ease of use i put in this example etherscan…

https://etherscan.io/apis

Thanks so much in advance!