aephiday commited on
Commit
abb807c
Β·
verified Β·
1 Parent(s): db744d5

Upload streamlit_app.py

Browse files
Files changed (1) hide show
  1. src/streamlit_app.py +140 -40
src/streamlit_app.py CHANGED
@@ -1,40 +1,140 @@
1
- import altair as alt
2
- import numpy as np
3
- import pandas as pd
4
- import streamlit as st
5
-
6
- """
7
- # Welcome to Streamlit!
8
-
9
- Edit `/streamlit_app.py` to customize this app to your heart's desire :heart:.
10
- If you have any questions, checkout our [documentation](https://docs.streamlit.io) and [community
11
- forums](https://discuss.streamlit.io).
12
-
13
- In the meantime, below is an example of what you can do with just a few lines of code:
14
- """
15
-
16
- num_points = st.slider("Number of points in spiral", 1, 10000, 1100)
17
- num_turns = st.slider("Number of turns in spiral", 1, 300, 31)
18
-
19
- indices = np.linspace(0, 1, num_points)
20
- theta = 2 * np.pi * num_turns * indices
21
- radius = indices
22
-
23
- x = radius * np.cos(theta)
24
- y = radius * np.sin(theta)
25
-
26
- df = pd.DataFrame({
27
- "x": x,
28
- "y": y,
29
- "idx": indices,
30
- "rand": np.random.randn(num_points),
31
- })
32
-
33
- st.altair_chart(alt.Chart(df, height=700, width=700)
34
- .mark_point(filled=True)
35
- .encode(
36
- x=alt.X("x", axis=None),
37
- y=alt.Y("y", axis=None),
38
- color=alt.Color("idx", legend=None, scale=alt.Scale()),
39
- size=alt.Size("rand", legend=None, scale=alt.Scale(range=[1, 150])),
40
- ))
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import streamlit as st
2
+ from langchain_community.utilities import SQLDatabase
3
+ from langchain_core.prompts import ChatPromptTemplate
4
+ from langchain_openai import ChatOpenAI
5
+ import os
6
+ import re
7
+
8
+ # === Konfigurasi API Hugging Face Inference API ===
9
+
10
+ HF_TOKEN = os.environ.get("HF_TOKEN", "") # simpan secret via HF Spaces
11
+ os.environ["OPENAI_API_KEY"] = HF_TOKEN
12
+ HF_BASE_URL = "https://api-inference.huggingface.com/v1"
13
+
14
+ # Fungsi koneksi database
15
+ def connectDatabase(username, port, host, password, database):
16
+ try:
17
+ db_uri = f"postgresql://{username}:{password}@{host}:{port}/{database}"
18
+ st.session_state.db = SQLDatabase.from_uri(db_uri)
19
+ st.success("βœ… Database connected successfully.")
20
+ except Exception as e:
21
+ st.session_state.db = None
22
+ st.error(f"❌ Failed to connect to database:\n{e}")
23
+
24
+ # Fungsi menjalankan query SQL
25
+ def runQuery(query):
26
+ if "db" in st.session_state and st.session_state.db:
27
+ try:
28
+ return st.session_state.db.run(query)
29
+ except Exception as e:
30
+ return f"❌ Query execution failed: {e}"
31
+ return "❌ Please connect to database first."
32
+
33
+ # Ambil skema database
34
+ def getDatabaseSchema():
35
+ if "db" in st.session_state and st.session_state.db:
36
+ try:
37
+ return st.session_state.db.get_table_info()
38
+ except Exception as e:
39
+ return f"❌ Failed to fetch schema: {e}"
40
+ return "❌ Please connect to database first."
41
+
42
+ # Prompt untuk menghasilkan SQL
43
+ def getQueryFromLLM(question):
44
+ template = """
45
+ Below is the schema of a PostgreSQL database. Read the schema carefully and answer the user's question using a valid SQL query. Be careful with table and column names (case-sensitive). Only provide the SQL query, and nothing else.
46
+
47
+ Schema:
48
+ {schema}
49
+
50
+ Sekarang giliran Anda:
51
+ Question: {question}
52
+ SQL query:
53
+ """
54
+ try:
55
+ schema = getDatabaseSchema()[:3000]
56
+ prompt = ChatPromptTemplate.from_template(template)
57
+ chain = prompt | llm
58
+ response = chain.invoke({"question": question, "schema": schema})
59
+ query_only = re.sub(r"<think>.*?</think>", "", response.content, flags=re.DOTALL).strip()
60
+ return query_only
61
+ except Exception as e:
62
+ st.error(f"❌ Model gagal merespons: {e}")
63
+ return "Gagal membuat query SQL."
64
+
65
+ # Prompt untuk menjelaskan hasil
66
+ def getResponseForQueryResult(question, query, result):
67
+ template = """
68
+ Berdasarkan pertanyaan, SQL query, dan hasilnya, berikan jawaban dalam bahasa alami. Gunakan bahasa Indonesia jika pertanyaannya dalam bahasa Indonesia.
69
+
70
+ Schema:
71
+ {schema}
72
+
73
+ Pertanyaan: {question}
74
+ SQL query: {query}
75
+ Hasil: {result}
76
+ Jawaban:
77
+ """
78
+ prompt2 = ChatPromptTemplate.from_template(template)
79
+ chain2 = prompt2 | llm
80
+ response = chain2.invoke({
81
+ "question": question,
82
+ "schema": getDatabaseSchema(),
83
+ "query": query,
84
+ "result": result
85
+ })
86
+ return response.content.strip()
87
+
88
+ # Konfigurasi halaman
89
+ st.set_page_config(page_title="Chat with PostgreSQL DB", page_icon="🧠", layout="centered")
90
+ st.title("🧠 Chat with your Database")
91
+
92
+ # Inisialisasi state
93
+ if "chat" not in st.session_state:
94
+ st.session_state.chat = []
95
+
96
+ # Sidebar
97
+ with st.sidebar:
98
+ st.subheader("πŸ”— Koneksi Database")
99
+ host = st.text_input("Host", value="aws-0-ap-southeast-1.pooler.supabase.com")
100
+ port = st.text_input("Port", value="6543")
101
+ username = st.text_input("Username", value="postgres")
102
+ password = st.text_input("Password", type="password", value="password")
103
+ database = st.text_input("Database", value="postgres")
104
+ if st.button("Connect"):
105
+ connectDatabase(username, port, host, password, database)
106
+
107
+ # Inisialisasi LLM
108
+ llm = ChatOpenAI(
109
+ model="qwen/qwen3-1.7b",
110
+ base_url=HF_BASE_URL,
111
+ api_key=HF_TOKEN,
112
+ temperature=0
113
+ )
114
+
115
+ # Input pertanyaan
116
+ question = st.chat_input("Tanyakan sesuatu tentang database Anda...")
117
+
118
+ # Proses pertanyaan
119
+ if question:
120
+ if "db" not in st.session_state or st.session_state.db is None:
121
+ st.error("❌ Please connect to database first.")
122
+ else:
123
+ st.session_state.chat.append({"role": "user", "content": question})
124
+
125
+ with st.spinner("πŸ’‘ Sedang berpikir..."):
126
+ query = getQueryFromLLM(question)
127
+ result = runQuery(query)
128
+ response = getResponseForQueryResult(question, query, result)
129
+
130
+ st.session_state.chat.append({"role": "assistant", "content": response})
131
+
132
+ with st.expander("🧾 Generated SQL Query"):
133
+ st.code(query, language="sql")
134
+
135
+ with st.expander("πŸ“Š Raw Result"):
136
+ st.write(result)
137
+
138
+ # Tampilkan chat
139
+ for chat in st.session_state.chat:
140
+ st.chat_message(chat["role"]).markdown(chat["content"])