File size: 2,144 Bytes
d11c4c9
 
 
 
 
 
dd863a6
d11c4c9
72597fa
 
 
 
dd863a6
d11c4c9
 
 
 
72597fa
d11c4c9
 
 
 
6997742
 
 
 
 
 
 
d11c4c9
dd863a6
d11c4c9
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
6997742
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
import shiny
from shiny import App, ui, reactive
import pandas as pd
import matplotlib.pyplot as plt
import ollama
import io
from shinywidgets import render_plotly
import plotly.express as px
import os

# Fix for Matplotlib permission error
os.environ["MPLCONFIGDIR"] = "/tmp/matplotlib"

# UI
app_ui = ui.page_fluid(
    ui.panel_title("LLM-Powered Data Analytics and Visualization"),
    ui.layout_sidebar(
        ui.sidebar(
            ui.input_file("file", "Upload CSV/Parquet", accept=[".csv", ".parquet"]),
            ui.input_text("question", "Ask about the data:"),
            ui.input_action_button("analyze", "Analyze & Visualize"),
        ),
        ui.layout_columns(
            ui.card(
                ui.output_text("llm_response")
            ),
            ui.card(
                ui.output_plot("plot")
            )
        )
    )
)

# SERVER
def server(input, output, session):
    data = reactive.Value(None)
    
    @reactive.effect
    @reactive.event(input.file)
    def load_data():
        file_info = input.file()
        if file_info is not None:
            ext = file_info["name"].split(".")[-1]
            if ext == "csv":
                df = pd.read_csv(file_info["datapath"])
            elif ext == "parquet":
                df = pd.read_parquet(file_info["datapath"])
            data.set(df)
    
    @output
    @render.text
    @reactive.event(input.analyze)
    def llm_response():
        df = data.get()
        if df is None:
            return "Please upload a dataset."
        question = input.question()
        prompt = f"Dataset: {df.head().to_string()}\nUser Question: {question}\nProvide insights based on the data."
        response = ollama.chat(model="mistral", messages=[{"role": "user", "content": prompt}])
        return response["message"]["content"]
    
    @output
    @render_plotly
    @reactive.event(input.analyze)
    def plot():
        df = data.get()
        if df is None:
            return None
        if len(df.columns) < 2:
            return None
        fig = px.scatter(df, x=df.columns[0], y=df.columns[1])
        return fig

app = App(app_ui, server)