Spaces:
Sleeping
Sleeping
Linh Vuu
commited on
Commit
•
d359e96
1
Parent(s):
c897ee0
Add application file
Browse files
app.py
ADDED
@@ -0,0 +1,250 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import openai
|
2 |
+
import os
|
3 |
+
from dotenv import find_dotenv, load_dotenv
|
4 |
+
import time
|
5 |
+
import logging
|
6 |
+
from datetime import datetime
|
7 |
+
import requests
|
8 |
+
import json
|
9 |
+
import streamlit as st
|
10 |
+
|
11 |
+
load_dotenv()
|
12 |
+
# openai.api_key = os.environ.get("OPENAI_API_KEY")
|
13 |
+
# defaults to getting the key using os.environ.get("OPENAI_API_KEY")
|
14 |
+
# if you saved the key under a different environment variable name, you can do something like:
|
15 |
+
# client = OpenAI(
|
16 |
+
# api_key=os.environ.get("CUSTOM_ENV_NAME"),
|
17 |
+
# )
|
18 |
+
|
19 |
+
news_api_key = '398bee7b77d64d63af02cd1d2541b210'
|
20 |
+
|
21 |
+
client = openai.OpenAI(api_key='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')
|
22 |
+
model = "gpt-3.5-turbo-16k"
|
23 |
+
|
24 |
+
|
25 |
+
def get_news(topic):
|
26 |
+
url = (
|
27 |
+
f"https://newsapi.org/v2/everything?q={topic}&apiKey={news_api_key}&pageSize=5"
|
28 |
+
)
|
29 |
+
|
30 |
+
try:
|
31 |
+
response = requests.get(url)
|
32 |
+
if response.status_code == 200:
|
33 |
+
news = json.dumps(response.json(), indent=4)
|
34 |
+
news_json = json.loads(news)
|
35 |
+
|
36 |
+
data = news_json
|
37 |
+
|
38 |
+
# Access all the fiels == loop through
|
39 |
+
status = data["status"]
|
40 |
+
total_results = data["totalResults"]
|
41 |
+
articles = data["articles"]
|
42 |
+
final_news = []
|
43 |
+
|
44 |
+
# Loop through articles
|
45 |
+
for article in articles:
|
46 |
+
source_name = article["source"]["name"]
|
47 |
+
author = article["author"]
|
48 |
+
title = article["title"]
|
49 |
+
description = article["description"]
|
50 |
+
url = article["url"]
|
51 |
+
content = article["content"]
|
52 |
+
title_description = f"""
|
53 |
+
Title: {title},
|
54 |
+
Author: {author},
|
55 |
+
Source: {source_name},
|
56 |
+
Description: {description},
|
57 |
+
URL: {url}
|
58 |
+
|
59 |
+
"""
|
60 |
+
final_news.append(title_description)
|
61 |
+
|
62 |
+
return final_news
|
63 |
+
else:
|
64 |
+
return []
|
65 |
+
|
66 |
+
except requests.exceptions.RequestException as e:
|
67 |
+
print("Error occured during API Request", e)
|
68 |
+
|
69 |
+
|
70 |
+
class AssistantManager:
|
71 |
+
thread_id = None
|
72 |
+
assistant_id = None
|
73 |
+
|
74 |
+
def __init__(self, model: str = model):
|
75 |
+
self.client = client
|
76 |
+
self.model = model
|
77 |
+
self.assistant = None
|
78 |
+
self.thread = None
|
79 |
+
self.run = None
|
80 |
+
self.summary = None
|
81 |
+
|
82 |
+
# Retrieve existing assistant and thread if IDs are already set
|
83 |
+
if AssistantManager.assistant_id:
|
84 |
+
self.assistant = self.client.beta.assistants.retrieve(
|
85 |
+
assistant_id=AssistantManager.assistant_id
|
86 |
+
)
|
87 |
+
if AssistantManager.thread_id:
|
88 |
+
self.thread = self.client.beta.threads.retrieve(
|
89 |
+
thread_id=AssistantManager.thread_id
|
90 |
+
)
|
91 |
+
|
92 |
+
def create_assistant(self, name, instructions, tools):
|
93 |
+
if not self.assistant:
|
94 |
+
assistant_obj = self.client.beta.assistants.create(
|
95 |
+
name=name, instructions=instructions, tools=tools, model=self.model
|
96 |
+
)
|
97 |
+
AssistantManager.assistant_id = assistant_obj.id
|
98 |
+
self.assistant = assistant_obj
|
99 |
+
print(f"AssisID:::: {self.assistant.id}")
|
100 |
+
|
101 |
+
def create_thread(self):
|
102 |
+
if not self.thread:
|
103 |
+
thread_obj = self.client.beta.threads.create()
|
104 |
+
AssistantManager.thread_id = thread_obj.id
|
105 |
+
self.thread = thread_obj
|
106 |
+
print(f"ThreadID::: {self.thread.id}")
|
107 |
+
|
108 |
+
def add_message_to_thread(self, role, content):
|
109 |
+
if self.thread:
|
110 |
+
self.client.beta.threads.messages.create(
|
111 |
+
thread_id=self.thread.id, role=role, content=content
|
112 |
+
)
|
113 |
+
|
114 |
+
def run_assistant(self, instructions):
|
115 |
+
if self.thread and self.assistant:
|
116 |
+
self.run = self.client.beta.threads.runs.create(
|
117 |
+
thread_id=self.thread.id,
|
118 |
+
assistant_id=self.assistant.id,
|
119 |
+
instructions=instructions,
|
120 |
+
)
|
121 |
+
|
122 |
+
def process_message(self):
|
123 |
+
if self.thread:
|
124 |
+
messages = self.client.beta.threads.messages.list(thread_id=self.thread.id)
|
125 |
+
summary = []
|
126 |
+
|
127 |
+
last_message = messages.data[0]
|
128 |
+
role = last_message.role
|
129 |
+
response = last_message.content[0].text.value
|
130 |
+
summary.append(response)
|
131 |
+
|
132 |
+
self.summary = "\n".join(summary)
|
133 |
+
print(f"SUMMARY-----> {role.capitalize()}: ==> {response}")
|
134 |
+
|
135 |
+
# for msg in messages:
|
136 |
+
# role = msg.role
|
137 |
+
# content = msg.content[0].text.value
|
138 |
+
# print(f"SUMMARY-----> {role.capitalize()}: ==> {content}")
|
139 |
+
|
140 |
+
def call_required_functions(self, required_actions):
|
141 |
+
if not self.run:
|
142 |
+
return
|
143 |
+
tool_outputs = []
|
144 |
+
|
145 |
+
for action in required_actions["tool_calls"]:
|
146 |
+
func_name = action["function"]["name"]
|
147 |
+
arguments = json.loads(action["function"]["arguments"])
|
148 |
+
|
149 |
+
if func_name == "get_news":
|
150 |
+
output = get_news(topic=arguments["topic"])
|
151 |
+
print(f"STUFFFFF;;;;{output}")
|
152 |
+
final_str = ""
|
153 |
+
for item in output:
|
154 |
+
final_str += "".join(item)
|
155 |
+
|
156 |
+
tool_outputs.append({"tool_call_id": action["id"], "output": final_str})
|
157 |
+
else:
|
158 |
+
raise ValueError(f"Unknown function: {func_name}")
|
159 |
+
|
160 |
+
print("Submitting outputs back to the Assistant...")
|
161 |
+
self.client.beta.threads.runs.submit_tool_outputs(
|
162 |
+
thread_id=self.thread.id, run_id=self.run.id, tool_outputs=tool_outputs
|
163 |
+
)
|
164 |
+
|
165 |
+
# for streamlit
|
166 |
+
def get_summary(self):
|
167 |
+
return self.summary
|
168 |
+
|
169 |
+
def wait_for_completion(self):
|
170 |
+
if self.thread and self.run:
|
171 |
+
while True:
|
172 |
+
time.sleep(5)
|
173 |
+
run_status = self.client.beta.threads.runs.retrieve(
|
174 |
+
thread_id=self.thread.id, run_id=self.run.id
|
175 |
+
)
|
176 |
+
print(f"RUN STATUS:: {run_status.model_dump_json(indent=4)}")
|
177 |
+
|
178 |
+
if run_status.status == "completed":
|
179 |
+
self.process_message()
|
180 |
+
break
|
181 |
+
elif run_status.status == "requires_action":
|
182 |
+
print("FUNCTION CALLING NOW...")
|
183 |
+
self.call_required_functions(
|
184 |
+
required_actions=run_status.required_action.submit_tool_outputs.model_dump()
|
185 |
+
)
|
186 |
+
|
187 |
+
# Run the steps
|
188 |
+
def run_steps(self):
|
189 |
+
run_steps = self.client.beta.threads.runs.steps.list(
|
190 |
+
thread_id=self.thread.id, run_id=self.run.id
|
191 |
+
)
|
192 |
+
print(f"Run-Steps::: {run_steps}")
|
193 |
+
return run_steps.data
|
194 |
+
|
195 |
+
|
196 |
+
def main():
|
197 |
+
news = get_news("bitcoin")
|
198 |
+
print(news[0])
|
199 |
+
|
200 |
+
manager = AssistantManager()
|
201 |
+
|
202 |
+
# Streamlit interface
|
203 |
+
st.title("News Summariser")
|
204 |
+
|
205 |
+
with st.form(key="user_input_form"):
|
206 |
+
instructions = st.text_input("Enter topic:")
|
207 |
+
submit_button = st.form_submit_button(label="Summarise for me please")
|
208 |
+
|
209 |
+
if submit_button:
|
210 |
+
manager.create_assistant(
|
211 |
+
name="News Summariser",
|
212 |
+
instructions="You are a personal article summarizer Assistant who knows how to take a list of article's titles and descriptions and then write a short summary of all the news articles",
|
213 |
+
tools=[
|
214 |
+
{
|
215 |
+
"type": "function",
|
216 |
+
"function": {
|
217 |
+
"name": "get_news",
|
218 |
+
"description": "Get the list of articles/news for the given topic",
|
219 |
+
"parameters": {
|
220 |
+
"type": "object",
|
221 |
+
"properties": {
|
222 |
+
"topic": {
|
223 |
+
"type": "string",
|
224 |
+
"description": "The topic for the news, e.g. bitcoin",
|
225 |
+
}
|
226 |
+
},
|
227 |
+
"required": ["topic"],
|
228 |
+
},
|
229 |
+
},
|
230 |
+
}
|
231 |
+
],
|
232 |
+
)
|
233 |
+
manager.create_thread()
|
234 |
+
|
235 |
+
# Add the message and run the assistant
|
236 |
+
manager.add_message_to_thread(
|
237 |
+
role="user", content=f"summarize the news on this topic {instructions}?"
|
238 |
+
)
|
239 |
+
manager.run_assistant(instructions="Summarize the news")
|
240 |
+
|
241 |
+
# Wait for completions and process messages
|
242 |
+
manager.wait_for_completion()
|
243 |
+
|
244 |
+
summary = manager.get_summary()
|
245 |
+
|
246 |
+
st.write(summary)
|
247 |
+
|
248 |
+
|
249 |
+
if __name__ == "__main__":
|
250 |
+
main()
|