Adds charts and graphs functionality from quickchart (#7)
Browse files- Adds charts and graphs functionality from quickchart (c895015004a3111f3ba4e825a26f613c8eaf4794)
- functions/__init__.py +2 -1
- functions/chart_functions.py +24 -0
- functions/chat_functions.py +14 -5
- requirements.txt +2 -1
- tools.py +24 -2
functions/__init__.py
CHANGED
|
@@ -1,4 +1,5 @@
|
|
| 1 |
from .sqlite_functions import SQLiteQuery, sqlite_query_func
|
|
|
|
| 2 |
from .chat_functions import demo
|
| 3 |
|
| 4 |
-
__all__ = ["SQLiteQuery","sqlite_query_func","demo"]
|
|
|
|
| 1 |
from .sqlite_functions import SQLiteQuery, sqlite_query_func
|
| 2 |
+
from .chart_functions import chart_generation_func
|
| 3 |
from .chat_functions import demo
|
| 4 |
|
| 5 |
+
__all__ = ["SQLiteQuery","sqlite_query_func","chart_generation_func","demo"]
|
functions/chart_functions.py
ADDED
|
@@ -0,0 +1,24 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
from typing import List
|
| 2 |
+
from haystack import component
|
| 3 |
+
import pandas as pd
|
| 4 |
+
from quickchart import QuickChart
|
| 5 |
+
import json
|
| 6 |
+
import ast
|
| 7 |
+
|
| 8 |
+
def chart_generation_func(queries: List[str], session_hash):
|
| 9 |
+
print("CHART GENERATION")
|
| 10 |
+
query_dict = queries[0]
|
| 11 |
+
print(query_dict)
|
| 12 |
+
|
| 13 |
+
qc = QuickChart()
|
| 14 |
+
qc.width = 1000
|
| 15 |
+
qc.height = 500
|
| 16 |
+
|
| 17 |
+
# Config can be set as a string or as a nested dict
|
| 18 |
+
qc.config = query_dict
|
| 19 |
+
|
| 20 |
+
# You can get the chart URL...
|
| 21 |
+
|
| 22 |
+
iframe = '<iframe\n scrolling="yes"\n width="1000px"\n height="500px"\n src="' + qc.get_url() + '"\n frameborder="0"\n allowfullscreen\n></iframe>\n'
|
| 23 |
+
|
| 24 |
+
return {"reply": iframe}
|
functions/chat_functions.py
CHANGED
|
@@ -23,11 +23,12 @@ messages = [
|
|
| 23 |
]
|
| 24 |
|
| 25 |
def chatbot_with_fc(message, history, session_hash):
|
| 26 |
-
from functions import sqlite_query_func
|
| 27 |
from pipelines import rag_pipeline_func
|
| 28 |
import tools
|
| 29 |
|
| 30 |
-
available_functions = {"sql_query_func": sqlite_query_func, "rag_pipeline_func": rag_pipeline_func}
|
|
|
|
| 31 |
messages.append(ChatMessage.from_user(message))
|
| 32 |
response = chat_generator.run(messages=messages, generation_kwargs={"tools": tools.tools_call(session_hash)})
|
| 33 |
|
|
@@ -41,9 +42,10 @@ def chatbot_with_fc(message, history, session_hash):
|
|
| 41 |
function_name = function_call.tool_name
|
| 42 |
function_args = function_call.arguments
|
| 43 |
|
| 44 |
-
## Find the
|
| 45 |
function_to_call = available_functions[function_name]
|
| 46 |
function_response = function_to_call(**function_args, session_hash=session_hash)
|
|
|
|
| 47 |
## Append function response to the messages list using `ChatMessage.from_tool`
|
| 48 |
messages.append(ChatMessage.from_tool(tool_result=function_response['reply'], origin=function_call))
|
| 49 |
response = chat_generator.run(messages=messages, generation_kwargs={"tools": tools.tools_call(session_hash)})
|
|
@@ -73,7 +75,12 @@ css= ".file_marker .large{min-height:50px !important;} .example_btn{max-width:30
|
|
| 73 |
|
| 74 |
with gr.Blocks(css=css) as demo:
|
| 75 |
title = gr.HTML("<h1 style='text-align:center;'>Virtual Data Analyst</h1>")
|
| 76 |
-
description = gr.HTML("<p style='text-align:center;'>Upload a data file and chat with our virtual data analyst
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 77 |
example_file_1 = gr.File(visible=False, value="samples/bank_marketing_campaign.csv")
|
| 78 |
example_file_2 = gr.File(visible=False, value="samples/online_retail_data.csv")
|
| 79 |
with gr.Row():
|
|
@@ -94,12 +101,14 @@ with gr.Blocks(css=css) as demo:
|
|
| 94 |
["Describe the dataset"],
|
| 95 |
["What levels of education have the highest and lowest average balance?"],
|
| 96 |
["What job is most and least common for a yes response from the individuals, not counting 'unknown'?"],
|
|
|
|
| 97 |
]
|
| 98 |
elif "online_retail_data" in filename:
|
| 99 |
example_questions = [
|
| 100 |
["Describe the dataset"],
|
| 101 |
["What month had the highest revenue?"],
|
| 102 |
["Is revenue higher in the morning or afternoon?"],
|
|
|
|
| 103 |
]
|
| 104 |
else:
|
| 105 |
example_questions = [
|
|
@@ -108,7 +117,7 @@ with gr.Blocks(css=css) as demo:
|
|
| 108 |
["What could this data be used for?"],
|
| 109 |
]
|
| 110 |
parameters = gr.Textbox(visible=False, value=request.session_hash)
|
| 111 |
-
bot = gr.Chatbot(type='messages', label="CSV Chat Window", show_label=True, render=False, visible=True, elem_classes="chatbot")
|
| 112 |
chat = gr.ChatInterface(
|
| 113 |
fn=chatbot_with_fc,
|
| 114 |
type='messages',
|
|
|
|
| 23 |
]
|
| 24 |
|
| 25 |
def chatbot_with_fc(message, history, session_hash):
|
| 26 |
+
from functions import sqlite_query_func, chart_generation_func
|
| 27 |
from pipelines import rag_pipeline_func
|
| 28 |
import tools
|
| 29 |
|
| 30 |
+
available_functions = {"sql_query_func": sqlite_query_func, "rag_pipeline_func": rag_pipeline_func, "chart_generation_func": chart_generation_func}
|
| 31 |
+
|
| 32 |
messages.append(ChatMessage.from_user(message))
|
| 33 |
response = chat_generator.run(messages=messages, generation_kwargs={"tools": tools.tools_call(session_hash)})
|
| 34 |
|
|
|
|
| 42 |
function_name = function_call.tool_name
|
| 43 |
function_args = function_call.arguments
|
| 44 |
|
| 45 |
+
## Find the corresponding function and call it with the given arguments
|
| 46 |
function_to_call = available_functions[function_name]
|
| 47 |
function_response = function_to_call(**function_args, session_hash=session_hash)
|
| 48 |
+
print(function_name)
|
| 49 |
## Append function response to the messages list using `ChatMessage.from_tool`
|
| 50 |
messages.append(ChatMessage.from_tool(tool_result=function_response['reply'], origin=function_call))
|
| 51 |
response = chat_generator.run(messages=messages, generation_kwargs={"tools": tools.tools_call(session_hash)})
|
|
|
|
| 75 |
|
| 76 |
with gr.Blocks(css=css) as demo:
|
| 77 |
title = gr.HTML("<h1 style='text-align:center;'>Virtual Data Analyst</h1>")
|
| 78 |
+
description = gr.HTML("""<p style='text-align:center;'>Upload a data file and chat with our virtual data analyst
|
| 79 |
+
to get insights on your data set. Currently accepts CSV, TSV, TXT, XLS, XLSX, XML, and JSON files.
|
| 80 |
+
Can now generate charts and graphs!
|
| 81 |
+
Try a sample file to get started!</p>
|
| 82 |
+
<p style='text-align:center;'>This tool is under active development. If you experience bugs with use,
|
| 83 |
+
open a discussion in the community tab and I will respond.</p>""")
|
| 84 |
example_file_1 = gr.File(visible=False, value="samples/bank_marketing_campaign.csv")
|
| 85 |
example_file_2 = gr.File(visible=False, value="samples/online_retail_data.csv")
|
| 86 |
with gr.Row():
|
|
|
|
| 101 |
["Describe the dataset"],
|
| 102 |
["What levels of education have the highest and lowest average balance?"],
|
| 103 |
["What job is most and least common for a yes response from the individuals, not counting 'unknown'?"],
|
| 104 |
+
["Can you generate a bar chart of education vs. average balance?"]
|
| 105 |
]
|
| 106 |
elif "online_retail_data" in filename:
|
| 107 |
example_questions = [
|
| 108 |
["Describe the dataset"],
|
| 109 |
["What month had the highest revenue?"],
|
| 110 |
["Is revenue higher in the morning or afternoon?"],
|
| 111 |
+
["Can you generate a line graph of revenue per month?"]
|
| 112 |
]
|
| 113 |
else:
|
| 114 |
example_questions = [
|
|
|
|
| 117 |
["What could this data be used for?"],
|
| 118 |
]
|
| 119 |
parameters = gr.Textbox(visible=False, value=request.session_hash)
|
| 120 |
+
bot = gr.Chatbot(type='messages', label="CSV Chat Window", render_markdown=True, sanitize_html=False, show_label=True, render=False, visible=True, elem_classes="chatbot")
|
| 121 |
chat = gr.ChatInterface(
|
| 122 |
fn=chatbot_with_fc,
|
| 123 |
type='messages',
|
requirements.txt
CHANGED
|
@@ -2,4 +2,5 @@ haystack-ai
|
|
| 2 |
python-dotenv
|
| 3 |
gradio
|
| 4 |
pandas
|
| 5 |
-
|
|
|
|
|
|
| 2 |
python-dotenv
|
| 3 |
gradio
|
| 4 |
pandas
|
| 5 |
+
quickchart.io
|
| 6 |
+
openpyxl
|
tools.py
CHANGED
|
@@ -15,7 +15,7 @@ def tools_call(session_hash):
|
|
| 15 |
"type": "function",
|
| 16 |
"function": {
|
| 17 |
"name": "sql_query_func",
|
| 18 |
-
"description": f"This a tool useful to query a
|
| 19 |
"parameters": {
|
| 20 |
"type": "object",
|
| 21 |
"properties": {
|
|
@@ -35,7 +35,7 @@ def tools_call(session_hash):
|
|
| 35 |
"type": "function",
|
| 36 |
"function": {
|
| 37 |
"name": "rag_pipeline_func",
|
| 38 |
-
"description": f"This a tool useful to query a
|
| 39 |
"parameters": {
|
| 40 |
"type": "object",
|
| 41 |
"properties": {
|
|
@@ -50,5 +50,27 @@ def tools_call(session_hash):
|
|
| 50 |
"required": ["question"],
|
| 51 |
},
|
| 52 |
},
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 53 |
}
|
| 54 |
]
|
|
|
|
| 15 |
"type": "function",
|
| 16 |
"function": {
|
| 17 |
"name": "sql_query_func",
|
| 18 |
+
"description": f"This a tool useful to query a SQLite table called 'data_source' with the following Columns: {columns}",
|
| 19 |
"parameters": {
|
| 20 |
"type": "object",
|
| 21 |
"properties": {
|
|
|
|
| 35 |
"type": "function",
|
| 36 |
"function": {
|
| 37 |
"name": "rag_pipeline_func",
|
| 38 |
+
"description": f"This a tool useful to query a SQLite table called 'data_source' with the following Columns: {columns}",
|
| 39 |
"parameters": {
|
| 40 |
"type": "object",
|
| 41 |
"properties": {
|
|
|
|
| 50 |
"required": ["question"],
|
| 51 |
},
|
| 52 |
},
|
| 53 |
+
},
|
| 54 |
+
{
|
| 55 |
+
"type": "function",
|
| 56 |
+
"function": {
|
| 57 |
+
"name": "chart_generation_func",
|
| 58 |
+
"description": f"This an chart generation tool useful to generate charts and graphs from queried data from our SQL table called 'data_source with the following Columns: {columns}. Returns an iframe string.",
|
| 59 |
+
"parameters": {
|
| 60 |
+
"type": "object",
|
| 61 |
+
"properties": {
|
| 62 |
+
"queries": {
|
| 63 |
+
"type": "array",
|
| 64 |
+
"description": """The data points to use in the chart generation. Infer this from the user's message.
|
| 65 |
+
Send a chart.js dictionary with options that correspond to the users request. But also format this dictionary as a string as this will allow javascript to be interpreted by the API we are using.
|
| 66 |
+
Return nothing else.""",
|
| 67 |
+
"items": {
|
| 68 |
+
"type": "string",
|
| 69 |
+
}
|
| 70 |
+
}
|
| 71 |
+
},
|
| 72 |
+
"required": ["question"],
|
| 73 |
+
},
|
| 74 |
+
},
|
| 75 |
}
|
| 76 |
]
|