nolanzandi commited on
Commit
c895015
·
verified ·
1 Parent(s): e033d9a

Adds charts and graphs functionality from quickchart

Browse files

Adds charts and graph functionality from Quickchart. Only an image, goal for future release are dynamic JS style charts and graphs.

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
  ]