Adds charts and graphs functionality from quickchart

#7
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 correspoding function and call it with the given arguments
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 to get insights on your data set. Currently accepts CSV, TSV, TXT, XLS, XLSX, XML, and JSON files. Try a sample file to get started!</p>")
 
 
 
 
 
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
- openpyxl
 
 
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 SQL table called 'data_source' with the following Columns: {columns}",
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 SQL table called 'data_source' with the following Columns: {columns}",
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
  ]