Hi all,
I am trying to write an app using dash components to generate sql queries, then allow users to stream download queried data in csv format, writing row by row.
Is there anyway to have the dash app to do similar stuff as below?
from flask import Flask, render_template, request, Response
from google.cloud import bigquery
app = Flask(__name__, template_folder = 'template')
#google cloud config
client = bigquery.Client()
job_config = bigquery.QueryJobConfig()
job_config.use_legacy_sql = False
@app.route('/')
def index():
return render_template('index.html')
@app.route('/download.csv', methods = ['GET', 'POST'])
def download_csv():
query = request.form['query']
query_job = client.query(
query,
location='US',
job_config=job_config)
def generate():
for row in query_job:
yield ','.join(str(x) for x in row.values()) + '\n'
return Response(generate(), mimetype = 'text/csv')
if __name__ == '__main__':
app.run(debug = True)
above code takes a text input from a html form and the button submit will invoke a response that writes data row by row into a csv file on the user end called download.csv.
Is there anyway to get the text input from a dash component? I tried something as below, but it didn’t work.
import dash
import dash_core_components as dcc
import dash_html_components as html
from dash.dependencies import Input, Output, Event, State
import plotly.graph_objs as go
from datetime import datetime as dt
from google.cloud import bigquery
from flask import Flask, render_template, request, Response
client = bigquery.Client()
job_config = bigquery.QueryJobConfig()
job_config.use_legacy_sql = False
app = dash.Dash(__name__)
server = app.server
app.config.supress_callback_exceptions = True
app.layout = html.Div([
html.Div(dcc.Input(id='input-box', type='text')),
html.Button('Submit', id='button'),
html.Div(id='hidden-div', style={'display':'none'})
])
@server.route('/download.csv', methods = ['GET', 'POST'])
@app.callback(
dash.dependencies.Output('hidden-div', 'children'),
[dash.dependencies.Input('button', 'n_clicks')],
[dash.dependencies.State('input-box', 'value')])
def update_output(n_clicks, value):
query = value
query_job = client.query(
query,
location='US',
job_config=job_config)
def generate():
for row in query_job:
yield ','.join(str(x) for x in row.values()) + '\n'
return Response(generate(), mimetype = 'text/csv')
if __name__ == '__main__':
app.run_server(debug=True)
The error message was TypeError: Object of type ‘Response’ is not JSON serializable.
it seems like the response gets returned to the hidden-div, but I would like it to be returned to the server route. how do I do that?