Dhanushraja commited on
Commit
df51720
·
verified ·
1 Parent(s): 4236f7f

Create streamlit_app.py

Browse files
Files changed (1) hide show
  1. streamlit_app.py +204 -0
streamlit_app.py ADDED
@@ -0,0 +1,204 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import time
2
+ import streamlit as st
3
+ import pandas as pd
4
+ import openai
5
+ import pinecone
6
+ import requests
7
+ import certifi
8
+ from tiktoken import get_encoding
9
+ from pinecone import Pinecone, ServerlessSpec
10
+ from retry import retry
11
+ from concurrent.futures import ThreadPoolExecutor, as_completed
12
+ from requests.exceptions import SSLError
13
+ from urllib3.exceptions import MaxRetryError
14
+
15
+ # Configuration
16
+ OPENAI_API_KEY = os.getenv('OPENAI_API_KEY')
17
+ PINECONE_API_KEY = os.getenv('PINECONE_API_KEY ')
18
+ INDEX_NAME = "gradient-cyber"
19
+ BATCH_SIZE = 100
20
+
21
+ # Initialize OpenAI
22
+ openai.api_key = OPENAI_API_KEY
23
+
24
+ # Retry Pinecone initialization if network issues occur
25
+ @retry(tries=5, delay=2, backoff=2)
26
+ def initialize_pinecone():
27
+ pc = Pinecone(api_key=PINECONE_API_KEY)
28
+ if INDEX_NAME not in pc.list_indexes().names():
29
+ pc.create_index(
30
+ name=INDEX_NAME,
31
+ dimension=1536,
32
+ metric='cosine',
33
+ spec=ServerlessSpec(cloud='aws', region='us-east-1')
34
+ )
35
+ return pc.Index(INDEX_NAME)
36
+
37
+ # Initialize Pinecone with retries
38
+ index = initialize_pinecone()
39
+
40
+ def generate_embedding(text, OPENAI_API_KEY):
41
+ headers = {
42
+ 'Authorization': f'Bearer {OPENAI_API_KEY}',
43
+ 'Content-Type': 'application/json',
44
+ }
45
+ data = {
46
+ 'model': 'text-embedding-ada-002',
47
+ 'input': text
48
+ }
49
+ response = requests.post(
50
+ 'https://api.openai.com/v1/embeddings',
51
+ headers=headers,
52
+ json=data,
53
+ verify=certifi.where()
54
+ )
55
+ if response.status_code == 200:
56
+ result = response.json()
57
+ tokens_used = result['usage']['total_tokens']
58
+ return result['data'][0]['embedding'], tokens_used
59
+ else:
60
+ st.error(f"Error creating embedding: {response.status_code} - {response.text}")
61
+ return None, 0
62
+
63
+ @retry(tries=5, delay=2, backoff=2, exceptions=(SSLError, MaxRetryError))
64
+ def upsert_in_batches(index, vectors):
65
+ try:
66
+ index.upsert(vectors=vectors, namespace="ns1")
67
+ except (SSLError, MaxRetryError) as e:
68
+ st.error(f"Error upserting batch: {e}")
69
+ raise
70
+
71
+ def process_batches(df, batch_size=100):
72
+ total_tokens_used = 0
73
+ total_requests = 0
74
+
75
+ with ThreadPoolExecutor(max_workers=2) as executor:
76
+ futures = []
77
+ for start in range(0, len(df), batch_size):
78
+ batch = df.iloc[start:start + batch_size]
79
+ for i, row in batch.iterrows():
80
+ text = row['combined_text']
81
+ future = executor.submit(generate_embedding, text, OPENAI_API_KEY)
82
+ futures.append((future, start + i, text))
83
+
84
+ vectors = []
85
+ for future, idx, text in futures:
86
+ embedding, tokens_used = future.result()
87
+ if embedding is not None:
88
+ total_tokens_used += tokens_used
89
+ total_requests += 1
90
+ vectors.append({'id': f"{idx}", 'values': embedding, 'metadata': {'text': text}})
91
+
92
+ if vectors:
93
+ upsert_future = executor.submit(upsert_in_batches, index, vectors)
94
+ futures.append(upsert_future)
95
+ futures = [] # Clear the futures list for the next batch
96
+
97
+ return total_tokens_used, total_requests
98
+
99
+ def summarize_texts(texts, OPENAI_API_KEY):
100
+ headers = {
101
+ 'Authorization': f'Bearer {OPENAI_API_KEY}',
102
+ 'Content-Type': 'application/json',
103
+ }
104
+ data = {
105
+ 'model': 'text-davinci-003',
106
+ 'prompt': f"Summarize the following texts:\n\n{texts}\n\n",
107
+ 'max_tokens': 150,
108
+ 'temperature': 0.5,
109
+ }
110
+ response = requests.post(
111
+ 'https://api.openai.com/v1/completions',
112
+ headers=headers,
113
+ json=data,
114
+ verify=certifi.where()
115
+ )
116
+ if response.status_code == 200:
117
+ result = response.json()
118
+ return result['choices'][0]['text'].strip()
119
+ else:
120
+ st.error(f"Error summarizing text: {response.status_code} - {response.text}")
121
+ return None
122
+
123
+ def answer_query(query, summaries, api_key):
124
+ combined_text = "\n\n".join([f"ID: {summary['hash_id']}\n\n{summary['text']}" for summary in summaries])
125
+ headers = {
126
+ 'Authorization': f'Bearer {api_key}',
127
+ 'Content-Type': 'application/json',
128
+ }
129
+ data = {
130
+ 'model': 'gpt-3.5-turbo',
131
+ 'messages': [
132
+ {"role": "system",
133
+ "content": ("Core Capabilities: Expert Knowledge on SITREPs: Understand and explain SITREP components "
134
+ "like threat analysis, incident summaries, and risk assessments. Flexible Query Handling: "
135
+ "Interpret and respond to diverse queries, supporting access to data by date, theme, severity, etc. "
136
+ "Data Retrieval: Provide specific information such as incident dates, threat actors, and mitigation strategies. "
137
+ "Offer summaries or detailed reports based on user needs. Analytical Engagement: Engage in discussions, offering insights and hypotheses. "
138
+ "Support user analysis of cyber threats and incidents. Interaction Guidelines: Understanding Queries: "
139
+ "Use NLP to interpret user queries and ask clarifying questions if needed. Providing Context: Give context to help users understand the relevance and implications of information. "
140
+ "Customizing Detail: Adjust detail levels based on user preferences, providing summaries or deep dives. "
141
+ "Allow users to specify the format of information (e.g., bullet points, detailed paragraphs, tables). "
142
+ "Encouraging Exploration: Suggest related queries and additional information. Provide thorough explanations to support learning and decision-making.")
143
+ },
144
+ {"role": "user", "content": f"Here are some summaries \n\n{combined_text}\n\nAnswer this query: {query}"}
145
+ ],
146
+ 'max_tokens': 1500,
147
+ 'temperature': 0.4,
148
+ }
149
+ response = requests.post(
150
+ 'https://api.openai.com/v1/chat/completions',
151
+ headers=headers,
152
+ json=data,
153
+ verify=certifi.where()
154
+ )
155
+ if response.status_code == 200:
156
+ result = response.json()
157
+ tokens_used = result['usage']['total_tokens']
158
+ answer = result['choices'][0]['message']['content']
159
+ used_hash_ids = [summary['hash_id'] for summary in summaries if summary['hash_id'] in result['choices'][0]['message']['content']]
160
+ return answer, used_hash_ids, tokens_used
161
+ else:
162
+ return f"Error: {response.status_code} - {response.text}", [], 0
163
+
164
+ # Streamlit UI for file upload
165
+ st.title("Excel File Upload and Processing")
166
+ uploaded_file = st.file_uploader("Upload an Excel file", type=["xlsx"])
167
+ if uploaded_file is not None:
168
+ st.write("File uploaded successfully!")
169
+ # Load Excel file
170
+ df = pd.read_excel(uploaded_file)
171
+ st.write("Excel file loaded:")
172
+ st.write(df.head())
173
+ # Concatenate text from all columns for each row
174
+ def create_meaningful_sentence(row):
175
+ return '. '.join([f"{col}: {row[col]}" for col in df.columns])
176
+ df['combined_text'] = df.apply(create_meaningful_sentence, axis=1)
177
+ st.write("Columns concatenated into meaningful sentences:")
178
+ st.write(df[['combined_text']].head())
179
+
180
+ # Process rows in batches and upsert vectors
181
+ total_tokens_used, total_requests = process_batches(df, BATCH_SIZE)
182
+
183
+ st.success(f"Data successfully uploaded to Pinecone.")
184
+ st.info(f"Total tokens used: {total_tokens_used}")
185
+ st.info(f"Total requests made: {total_requests}")
186
+
187
+ # Query input and response
188
+ st.title("Query the Uploaded Data")
189
+ query = st.text_input("Enter your query:")
190
+ if query:
191
+ query_embedding, _ = generate_embedding(query, OPENAI_API_KEY)
192
+ if query_embedding is not None:
193
+ # Search Pinecone with the query embedding
194
+ results = index.query(namespace="ns1", include_values=True, vector=query_embedding, top_k=5, include_metadata=True)
195
+ # Collect texts for summarization
196
+ summaries = [{'hash_id': match['id'], 'text': match['metadata']['text']} for match in results['matches']]
197
+ answer, used_hash_ids, tokens_used = answer_query(query, summaries, OPENAI_API_KEY)
198
+ # Display results
199
+ if answer:
200
+ st.write("Answer to your query:")
201
+ st.write(answer)
202
+ st.info(f"Tokens used for this query: {tokens_used}")
203
+ else:
204
+ st.write("No answer could be generated.")