Spaces:
Build error
Build error
Commit Β·
632031b
1
Parent(s): 274ebc3
- .gitignore +3 -0
- __pycache__/app.cpython-311.pyc +0 -0
- __pycache__/webscrape.cpython-311.pyc +0 -0
- app.py +78 -73
- chainlit.md +14 -0
- webscrape.py +59 -0
.gitignore
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
.env
|
| 2 |
+
.cache
|
| 3 |
+
.__pycache__
|
__pycache__/app.cpython-311.pyc
ADDED
|
Binary file (14.1 kB). View file
|
|
|
__pycache__/webscrape.cpython-311.pyc
ADDED
|
Binary file (2.63 kB). View file
|
|
|
app.py
CHANGED
|
@@ -13,19 +13,15 @@ import autogen
|
|
| 13 |
from autogen import Agent, AssistantAgent, UserProxyAgent, config_list_from_json
|
| 14 |
import chainlit as cl
|
| 15 |
from chainlit.client.base import ConversationDict
|
| 16 |
-
import
|
| 17 |
-
import
|
| 18 |
-
from dotenv import load_dotenv
|
| 19 |
import os
|
| 20 |
|
| 21 |
-
load_dotenv()
|
| 22 |
-
|
| 23 |
-
API_KEY = os.getenv('NEWS_API_KEY')
|
| 24 |
-
BASE_URL = 'https://newsapi.org/v2/everything'
|
| 25 |
|
| 26 |
WELCOME_MESSAGE = f"""Soap Opera Team πΎ
|
| 27 |
\n\n
|
| 28 |
-
Let's make some soap opera! What topic do you want to search?
|
| 29 |
"""
|
| 30 |
|
| 31 |
# Agents
|
|
@@ -33,54 +29,6 @@ USER_PROXY_NAME = "Query Agent"
|
|
| 33 |
PROOF_READER = "Proofreader"
|
| 34 |
WRITER = "Writer"
|
| 35 |
ARTICLES = None
|
| 36 |
-
|
| 37 |
-
def get_top_articles(query, n):
|
| 38 |
-
# Prepare the parameters for the API call
|
| 39 |
-
params = {
|
| 40 |
-
'q': query, # search query
|
| 41 |
-
'apiKey': API_KEY,
|
| 42 |
-
'pageSize': n, # number of articles to return
|
| 43 |
-
'language': 'en', # get English articles
|
| 44 |
-
}
|
| 45 |
-
|
| 46 |
-
# Make the API request
|
| 47 |
-
response = requests.get(BASE_URL, params=params)
|
| 48 |
-
|
| 49 |
-
# Check if the request was successful
|
| 50 |
-
if response.status_code == 200:
|
| 51 |
-
return response.json()['articles']
|
| 52 |
-
else:
|
| 53 |
-
raise Exception(f"Error: {response.status_code}, {response.text}")
|
| 54 |
-
|
| 55 |
-
def grab_articles(query, num):
|
| 56 |
-
try:
|
| 57 |
-
# Get top N articles
|
| 58 |
-
articles = get_top_articles(query, num)
|
| 59 |
-
# Save articles to JSON file
|
| 60 |
-
return(articles)
|
| 61 |
-
except Exception as e:
|
| 62 |
-
print(str(e))
|
| 63 |
-
|
| 64 |
-
def extract_article_info_from_list(article_list):
|
| 65 |
-
try:
|
| 66 |
-
# Initialize a string to store the extracted information
|
| 67 |
-
extracted_info = ""
|
| 68 |
-
|
| 69 |
-
# Extract and store the desired information for each article
|
| 70 |
-
for article in article_list:
|
| 71 |
-
description = article.get("description", "N/A")
|
| 72 |
-
title = article.get("title", "N/A")
|
| 73 |
-
author = article.get("author", "N/A")
|
| 74 |
-
content = article.get("content", "N/A")
|
| 75 |
-
|
| 76 |
-
# Append the information to the string
|
| 77 |
-
extracted_info += f"Title: {title}\nAuthor: {author}\nDescription: {description}\nContent: {content}\n\n"
|
| 78 |
-
|
| 79 |
-
return extracted_info
|
| 80 |
-
|
| 81 |
-
except Exception as e:
|
| 82 |
-
# Handle any exceptions
|
| 83 |
-
return f"An error occurred: {str(e)}"
|
| 84 |
|
| 85 |
async def ask_helper(func, **kwargs):
|
| 86 |
res = await func(**kwargs).send()
|
|
@@ -111,7 +59,6 @@ class ChainlitAssistantAgent(AssistantAgent):
|
|
| 111 |
request_reply=request_reply,
|
| 112 |
silent=silent,
|
| 113 |
)
|
| 114 |
-
|
| 115 |
class ChainlitUserProxyAgent(UserProxyAgent):
|
| 116 |
"""
|
| 117 |
Wrapper for AutoGens UserProxy Agent. Simplifies the UI by adding CL Actions.
|
|
@@ -177,13 +124,29 @@ class ChainlitUserProxyAgent(UserProxyAgent):
|
|
| 177 |
# cl.user_session.get("chat_profile")
|
| 178 |
# # Or just pass if you do not need to run any custom logic
|
| 179 |
# pass
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 180 |
|
|
|
|
|
|
|
| 181 |
@cl.on_chat_start
|
| 182 |
async def on_chat_start():
|
|
|
|
| 183 |
try:
|
| 184 |
# app_user = cl.user_session.get("user")
|
| 185 |
# await cl.Message(f"Hello {app_user.username}").send()
|
| 186 |
-
|
| 187 |
config_list = config_list_from_json(env_or_file="OAI_CONFIG_LIST")
|
| 188 |
proof_reader = ChainlitAssistantAgent(
|
| 189 |
name="Proof_Reader", llm_config={"config_list": config_list},
|
|
@@ -209,27 +172,69 @@ async def on_chat_start():
|
|
| 209 |
cl.user_session.set(WRITER, writer)
|
| 210 |
|
| 211 |
# WEB-SCRAPING LOGIC
|
| 212 |
-
|
| 213 |
-
|
| 214 |
-
|
| 215 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 216 |
|
| 217 |
-
|
| 218 |
-
|
| 219 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 220 |
|
| 221 |
-
|
| 222 |
-
|
| 223 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 224 |
await msg.send()
|
| 225 |
|
| 226 |
-
cl.user_session.set(ARTICLES,
|
| 227 |
print("Articles set...")
|
| 228 |
|
| 229 |
-
msg = cl.Message(content=f"""This is the Soap Opera Team, please give instructions on how the Soap Opera should be structured and made.
|
| 230 |
-
|
| 231 |
-
who are entangled in a complex web of emotions, ambitions, and conflicts. Craft dialogue and actions that convey the
|
| 232 |
-
essence of the articles, infusing drama, suspense, and emotion. Leave the audience eagerly anticipating the next twist in this gripping narrative."
|
| 233 |
""",
|
| 234 |
disable_human_feedback=True,
|
| 235 |
author="User_Proxy")
|
|
|
|
| 13 |
from autogen import Agent, AssistantAgent, UserProxyAgent, config_list_from_json
|
| 14 |
import chainlit as cl
|
| 15 |
from chainlit.client.base import ConversationDict
|
| 16 |
+
from webscrape import grab_articles
|
| 17 |
+
from dotenv import load_dotenv, find_dotenv
|
|
|
|
| 18 |
import os
|
| 19 |
|
| 20 |
+
load_dotenv(find_dotenv())
|
|
|
|
|
|
|
|
|
|
| 21 |
|
| 22 |
WELCOME_MESSAGE = f"""Soap Opera Team πΎ
|
| 23 |
\n\n
|
| 24 |
+
Let's make some soap opera! What topic do you want to search?
|
| 25 |
"""
|
| 26 |
|
| 27 |
# Agents
|
|
|
|
| 29 |
PROOF_READER = "Proofreader"
|
| 30 |
WRITER = "Writer"
|
| 31 |
ARTICLES = None
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 32 |
|
| 33 |
async def ask_helper(func, **kwargs):
|
| 34 |
res = await func(**kwargs).send()
|
|
|
|
| 59 |
request_reply=request_reply,
|
| 60 |
silent=silent,
|
| 61 |
)
|
|
|
|
| 62 |
class ChainlitUserProxyAgent(UserProxyAgent):
|
| 63 |
"""
|
| 64 |
Wrapper for AutoGens UserProxy Agent. Simplifies the UI by adding CL Actions.
|
|
|
|
| 124 |
# cl.user_session.get("chat_profile")
|
| 125 |
# # Or just pass if you do not need to run any custom logic
|
| 126 |
# pass
|
| 127 |
+
@cl.action_callback("confirm_action")
|
| 128 |
+
async def on_action(action: cl.Action):
|
| 129 |
+
if action.value == "everything":
|
| 130 |
+
content = "everything"
|
| 131 |
+
elif action.value == "top-headlines":
|
| 132 |
+
content = "top_headlines"
|
| 133 |
+
else:
|
| 134 |
+
await cl.ErrorMessage(content="Invalid action").send()
|
| 135 |
+
return
|
| 136 |
+
|
| 137 |
+
prev_msg = cl.user_session.get("url_actions") # type: cl.Message
|
| 138 |
+
if prev_msg:
|
| 139 |
+
await prev_msg.remove_actions()
|
| 140 |
+
cl.user_session.set("url_actions", None)
|
| 141 |
|
| 142 |
+
await cl.Message(content=content).send()
|
| 143 |
+
|
| 144 |
@cl.on_chat_start
|
| 145 |
async def on_chat_start():
|
| 146 |
+
|
| 147 |
try:
|
| 148 |
# app_user = cl.user_session.get("user")
|
| 149 |
# await cl.Message(f"Hello {app_user.username}").send()
|
|
|
|
| 150 |
config_list = config_list_from_json(env_or_file="OAI_CONFIG_LIST")
|
| 151 |
proof_reader = ChainlitAssistantAgent(
|
| 152 |
name="Proof_Reader", llm_config={"config_list": config_list},
|
|
|
|
| 172 |
cl.user_session.set(WRITER, writer)
|
| 173 |
|
| 174 |
# WEB-SCRAPING LOGIC
|
| 175 |
+
URL = None
|
| 176 |
+
URL_option = None
|
| 177 |
+
BASE_URL_EVERYTHING = 'https://newsapi.org/v2/everything?'
|
| 178 |
+
BASE_URL_TOP_HEADLINES = 'https://newsapi.org/v2/top-headlines?'
|
| 179 |
+
TOPIC = None # Topic
|
| 180 |
+
SORTBY = 'relevancy' # relevancy, popularity, publishedAt
|
| 181 |
+
COUNTRY = 'gb' # Country you want to use
|
| 182 |
+
CATEGORY = None # 'business' # Options: business, entertainment, general health, science, sports, technology
|
| 183 |
+
API_KEY = os.getenv('NEWS_API_KEY')
|
| 184 |
|
| 185 |
+
everything = cl.Action( name="everything", value="everything", label="Everything" )
|
| 186 |
+
top_headlines = cl.Action( name="top-headlines",value="top-headlines", label="TopHeadlines")
|
| 187 |
+
business = cl.Action( name="business", value="business", label="Business" )
|
| 188 |
+
entertainment = cl.Action( name="entertainment", value="entertainment", label="Entertainment" )
|
| 189 |
+
science = cl.Action( name="science", value="science", label="Science" )
|
| 190 |
+
sports = cl.Action( name="sports", value="sports", label="Sports" )
|
| 191 |
+
technology = cl.Action( name="technology", value="technology", label="Technology" )
|
| 192 |
+
|
| 193 |
+
url_actions = [everything, top_headlines]
|
| 194 |
+
category_actions = [business, entertainment, science, sports, technology]
|
| 195 |
|
| 196 |
+
URL_option = cl.AskActionMessage(
|
| 197 |
+
content="Would you like to grab sources from Everything or from Top Headlines?",
|
| 198 |
+
actions=url_actions,
|
| 199 |
+
)
|
| 200 |
+
|
| 201 |
+
await URL_option.send()
|
| 202 |
+
|
| 203 |
+
URL_choice = URL_option.content.split()[-1]
|
| 204 |
+
if URL_choice == "Everything":
|
| 205 |
+
while TOPIC is None:
|
| 206 |
+
TOPIC = await cl.AskUserMessage(content="What topic would you like to make a Soap Opera about?", timeout=180, author="User_Proxy").send()
|
| 207 |
+
topic = TOPIC['content']
|
| 208 |
+
URL = f'{BASE_URL_EVERYTHING}q={topic}&sortBy={SORTBY}&pageSize=5&apiKey={API_KEY}'
|
| 209 |
+
print("URL: ", URL)
|
| 210 |
+
if URL_choice == "TopHeadlines":
|
| 211 |
+
while TOPIC is None:
|
| 212 |
+
TOPIC = await cl.AskUserMessage(content="What topic would you like to make a Soap Opera about?",
|
| 213 |
+
timeout=180,
|
| 214 |
+
author="User_Proxy").send()
|
| 215 |
+
category = cl.AskActionMessage(
|
| 216 |
+
content="What category would you like to use?",
|
| 217 |
+
actions=category_actions,
|
| 218 |
+
)
|
| 219 |
+
await category.send()
|
| 220 |
+
CATEGORY = category.content.split()[-1]
|
| 221 |
+
topic = TOPIC['content']
|
| 222 |
+
URL = f'{BASE_URL_TOP_HEADLINES}topic={topic}&country={COUNTRY}&category={CATEGORY}&pageSize=5&apiKey={API_KEY}'
|
| 223 |
+
print("URL: ", URL)
|
| 224 |
+
|
| 225 |
+
articles = grab_articles(URL)
|
| 226 |
+
print(articles)
|
| 227 |
+
print("Articles grabbed.")
|
| 228 |
+
|
| 229 |
+
msg = cl.Message(content=f"Processing `{articles}`...", disable_human_feedback=True, author="User_Proxy")
|
| 230 |
await msg.send()
|
| 231 |
|
| 232 |
+
cl.user_session.set(ARTICLES, articles)
|
| 233 |
print("Articles set...")
|
| 234 |
|
| 235 |
+
msg = cl.Message(content=f"""This is the Soap Opera Team, please give instructions on how the Soap Opera should be structured and made.
|
| 236 |
+
\nSample input:
|
| 237 |
+
"Create a captivating soap opera scene inspired by the content of the articles. Feature characters who are entangled in a complex web of emotions, ambitions, and conflicts. Craft dialogue and actions that convey the essence of the articles, infusing drama, suspense, and emotion. Leave the audience eagerly anticipating the next twist in this gripping narrative."
|
|
|
|
| 238 |
""",
|
| 239 |
disable_human_feedback=True,
|
| 240 |
author="User_Proxy")
|
chainlit.md
ADDED
|
@@ -0,0 +1,14 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Welcome to Chainlit! ππ€
|
| 2 |
+
|
| 3 |
+
Hi there, Developer! π We're excited to have you on board. Chainlit is a powerful tool designed to help you prototype, debug and share applications built on top of LLMs.
|
| 4 |
+
|
| 5 |
+
## Useful Links π
|
| 6 |
+
|
| 7 |
+
- **Documentation:** Get started with our comprehensive [Chainlit Documentation](https://docs.chainlit.io) π
|
| 8 |
+
- **Discord Community:** Join our friendly [Chainlit Discord](https://discord.gg/k73SQ3FyUh) to ask questions, share your projects, and connect with other developers! π¬
|
| 9 |
+
|
| 10 |
+
We can't wait to see what you create with Chainlit! Happy coding! π»π
|
| 11 |
+
|
| 12 |
+
## Welcome screen
|
| 13 |
+
|
| 14 |
+
To modify the welcome screen, edit the `chainlit.md` file at the root of your project. If you do not want a welcome screen, just leave this file empty.
|
webscrape.py
ADDED
|
@@ -0,0 +1,59 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import requests
|
| 2 |
+
import json
|
| 3 |
+
from dotenv import load_dotenv
|
| 4 |
+
import os
|
| 5 |
+
|
| 6 |
+
load_dotenv()
|
| 7 |
+
|
| 8 |
+
API_KEY = os.getenv('NEWS_API_KEY')
|
| 9 |
+
|
| 10 |
+
# Functions ------------------------------------------------------------------------------------------------------------->
|
| 11 |
+
def extract_article_info_from_list(article_list):
|
| 12 |
+
try:
|
| 13 |
+
# Initialize a string to store the extracted information
|
| 14 |
+
extracted_info = ""
|
| 15 |
+
|
| 16 |
+
# Extract and store the desired information for each article
|
| 17 |
+
for article in article_list:
|
| 18 |
+
description = article.get("description", "N/A")
|
| 19 |
+
title = article.get("title", "N/A")
|
| 20 |
+
author = article.get("author", "N/A")
|
| 21 |
+
content = article.get("content", "N/A")
|
| 22 |
+
|
| 23 |
+
# Append the information to the string
|
| 24 |
+
extracted_info += f"Title: {title}\nAuthor: {author}\nDescription: {description}\nContent: {content}\n\n"
|
| 25 |
+
|
| 26 |
+
return extracted_info
|
| 27 |
+
|
| 28 |
+
except Exception as e:
|
| 29 |
+
# Handle any exceptions
|
| 30 |
+
return f"An error occurred: {str(e)}"
|
| 31 |
+
|
| 32 |
+
def grab_articles(url, **kwargs):
|
| 33 |
+
response = requests.get(url, 5)
|
| 34 |
+
|
| 35 |
+
if response.status_code == 200:
|
| 36 |
+
extracted_article = extract_article_info_from_list(response.json()['articles'])
|
| 37 |
+
print(extracted_article)
|
| 38 |
+
return extracted_article
|
| 39 |
+
else:
|
| 40 |
+
raise Exception(f"Error: {response.status_code}, {response.text}")
|
| 41 |
+
|
| 42 |
+
# URL Configuration Here ------------------------------------------------------------------------------------------------------------->
|
| 43 |
+
|
| 44 |
+
BASE_URL_EVERYTHING = 'https://newsapi.org/v2/everything?'
|
| 45 |
+
BASE_URL_TOP_HEADLINES = 'https://newsapi.org/v2/top-headlines?'
|
| 46 |
+
TOPIC = 'bitcoin'
|
| 47 |
+
FROM = '2023-01-08' # Starting date
|
| 48 |
+
TO = '2023-11-08' # Ending date
|
| 49 |
+
SORTBY = 'popularity' # Relevancy, Popularity, PublishedAt
|
| 50 |
+
DOMAINS = 'techcrunch.com, thenextweb.com' # Domains you want to use.
|
| 51 |
+
COUNTRY = 'gb&' # Options: US, AU, JP, PH etc.
|
| 52 |
+
SOURCES = 'bbc-news'
|
| 53 |
+
CATEGORY = 'business' # Options: business, entertainment, general health, science, sports, technology
|
| 54 |
+
|
| 55 |
+
# Everything URL list
|
| 56 |
+
urls_everything = f"{BASE_URL_EVERYTHING}q={TOPIC}&domains={DOMAINS}&sortBy={SORTBY}&apiKey={API_KEY}"
|
| 57 |
+
|
| 58 |
+
# Top Headlines URL list
|
| 59 |
+
urls_top_headlines = f"{BASE_URL_TOP_HEADLINES}topic={TOPIC}&country={COUNTRY}&category={CATEGORY}&sources={SOURCES}&apiKey={API_KEY}"
|