Spaces:
Paused
Paused
Update main.py
Browse files
main.py
CHANGED
|
@@ -1,181 +1,20 @@
|
|
| 1 |
-
from
|
| 2 |
-
from half_json.core import JSONFixer
|
| 3 |
-
from openai import OpenAI
|
| 4 |
-
from retry import retry
|
| 5 |
-
import re
|
| 6 |
-
from dotenv import load_dotenv
|
| 7 |
-
import os
|
| 8 |
-
from fastapi import FastAPI
|
| 9 |
-
from fastapi import Query
|
| 10 |
from pydantic import BaseModel
|
| 11 |
-
|
| 12 |
-
from helper_functions_api import md_to_html
|
| 13 |
-
from duckduckgo_search import DDGS
|
| 14 |
-
import time
|
| 15 |
|
| 16 |
-
|
| 17 |
-
TOGETHER_API_KEY = os.getenv("TOGETHER_API_KEY")
|
| 18 |
-
GROQ_API_KEY = "gsk_"+os.getenv("GROQ_API_KEY")
|
| 19 |
-
HELICON_API_KEY = os.getenv("HELICON_API_KEY")
|
| 20 |
-
|
| 21 |
-
SysPromptDefault = "You are an expert AI, complete the given task. Do not add any additional comments."
|
| 22 |
-
SysPromptList = "You are now in the role of an expert AI who can extract structured information from user request. All elements must be in double quotes. You must respond ONLY with a valid python List. Do not add any additional comments."
|
| 23 |
-
SysPromptJson = "You are now in the role of an expert AI who can extract structured information from user request. Both key and value pairs must be in double quotes. You must respond ONLY with a valid JSON file. Do not add any additional comments."
|
| 24 |
-
SysPromptMd = "You are an expert AI who can create a structured report using information provided in the context from user request.The report should be in markdown format consists of markdown tables structured into subtopics. Do not add any additional comments."
|
| 25 |
-
SysPromptMdOffline = "You are an expert AI who can create a structured report using your knowledge on user request.The report should be in markdown format consists of markdown tables/lists/paragraphs as needed, structured into subtopics. Do not add any additional comments."
|
| 26 |
-
|
| 27 |
-
|
| 28 |
-
prompt_topics = """
|
| 29 |
-
You are an expert data analyst. You have been providing data analysis and structuring services for over 15 years. You specialize in creating detailed and comprehensive lists of subtopics for various fields.
|
| 30 |
-
|
| 31 |
-
Your task is to create a list of essential subtopics along with their descriptions based on the given USER_QUERY. The objective is to generate a detailed and precise list of subtopics that can help in understanding the main topic thoroughly.
|
| 32 |
-
|
| 33 |
-
Follow these steps to complete the task:
|
| 34 |
-
|
| 35 |
-
1. Identify and list 2 to {num_topics} essential subtopics related to {user_input}.
|
| 36 |
-
2. Provide a detailed description for each subtopic explaining its significance and relevance to the main topic.
|
| 37 |
-
3. Format your response as a valid Python list of lists, where each sub-list contains the subtopic and its description.
|
| 38 |
-
|
| 39 |
-
Make sure your response is well-organized and provides comprehensive details for each subtopic.
|
| 40 |
-
|
| 41 |
-
Take a deep breath and work on this problem step-by-step.
|
| 42 |
-
|
| 43 |
-
output format
|
| 44 |
-
[
|
| 45 |
-
["Subtask Title 1", "Detailed description of subtask 1."],
|
| 46 |
-
["Subtask Title 2", "Detailed description of subtask 2."],
|
| 47 |
-
...
|
| 48 |
-
]
|
| 49 |
-
YOUR OUTPUT SHOULD CONSIST ONLY A VALID PYTHON LIST, DO NOT ADD ADDITIONAL COMMENTS
|
| 50 |
-
"""
|
| 51 |
-
|
| 52 |
-
prompt_subtopics = """You are a professional task manager and prompt engineer. You have been helping teams and individuals decompose complex tasks into actionable subtasks for over 20 years. Your expertise lies in breaking down intricate tasks into clear, manageable steps and ensuring that all relevant aspects are covered while excluding any specified topics.**
|
| 53 |
-
|
| 54 |
-
Objective: Help create 2 to {num_topics} subtasks for an LLM to perform the specified task in the context of the given user query. Ensure that the generated subtasks are precise, actionable, and detailed. Exclude the specified topics from the subtasks.
|
| 55 |
-
|
| 56 |
-
**Steps to complete the task:**
|
| 57 |
-
|
| 58 |
-
1. **Understand the Main Task and User Query:**
|
| 59 |
-
- Read the main task and user query carefully to grasp the core objectives and context.
|
| 60 |
-
- Identify any specific requirements or constraints mentioned in the query.
|
| 61 |
-
|
| 62 |
-
2. **Identify Key Components:**
|
| 63 |
-
- Break down the main task into its fundamental components.
|
| 64 |
-
- Ensure each component is essential to the overall goal and can be clearly defined.
|
| 65 |
-
|
| 66 |
-
3. **Create Detailed Subtasks:**
|
| 67 |
-
- For each key component, create 2 to 5 detailed subtasks.
|
| 68 |
-
- Ensure each subtask is actionable and provides clear instructions on what needs to be done.
|
| 69 |
-
- Maintain logical order and ensure that the completion of each subtask contributes to the overall objective.
|
| 70 |
-
|
| 71 |
-
4. **Exclude Specified Topics:**
|
| 72 |
-
- Review the list of topics to be excluded.
|
| 73 |
-
- Ensure that none of the generated subtasks include these topics.
|
| 74 |
-
|
| 75 |
-
5. **Format the Response:**
|
| 76 |
-
- Present the subtasks in a structured Python list of lists format.
|
| 77 |
-
- Each sub-list should contain the subtask title and its detailed description.
|
| 78 |
-
|
| 79 |
-
Output Format:
|
| 80 |
-
[
|
| 81 |
-
["Subtask Title 1", "Detailed description of subtask 1."],
|
| 82 |
-
["Subtask Title 2", "Detailed description of subtask 2."],
|
| 83 |
-
...
|
| 84 |
-
]
|
| 85 |
-
|
| 86 |
-
MAIN TASK: {main_task}
|
| 87 |
-
USER QUERY:{user_input}
|
| 88 |
-
TOPICS TO BE EXCLUDED:{excluded_topics}
|
| 89 |
-
YOUR OUTPUT SHOULD CONSIST ONLY A VALID PYTHON LIST, DO NOT ADD ADDITIONAL COMMENTS
|
| 90 |
-
"""
|
| 91 |
-
### ------LLM CONFIG-------- ###
|
| 92 |
-
|
| 93 |
-
together_client = OpenAI(
|
| 94 |
-
api_key=TOGETHER_API_KEY,
|
| 95 |
-
base_url="https://together.hconeai.com/v1",
|
| 96 |
-
default_headers={ "Helicone-Auth": f"Bearer {HELICON_API_KEY}"})
|
| 97 |
-
|
| 98 |
-
groq_client = OpenAI(
|
| 99 |
-
api_key=GROQ_API_KEY,
|
| 100 |
-
base_url="https://groq.hconeai.com/openai/v1",
|
| 101 |
-
default_headers={ "Helicone-Auth": f"Bearer {HELICON_API_KEY}"})
|
| 102 |
-
|
| 103 |
-
# Groq model names
|
| 104 |
-
llm_default_small = "llama3-8b-8192"
|
| 105 |
-
llm_default_medium = "llama3-70b-8192"
|
| 106 |
-
|
| 107 |
-
# Together Model names (fallback)
|
| 108 |
-
llm_fallback_small = "meta-llama/Llama-3-8b-chat-hf"
|
| 109 |
-
llm_fallback_medium = "meta-llama/Llama-3-70b-chat-hf"
|
| 110 |
-
|
| 111 |
-
### ------END OF LLM CONFIG-------- ###
|
| 112 |
-
|
| 113 |
-
def together_response(message, model = llm_default_small, SysPrompt = SysPromptDefault, temperature=0.2, frequency_penalty =0.1, max_tokens= 2000):
|
| 114 |
-
|
| 115 |
-
messages=[{"role": "system", "content": SysPrompt},{"role": "user", "content": message}]
|
| 116 |
-
params = {
|
| 117 |
-
"model": model,
|
| 118 |
-
"messages": messages,
|
| 119 |
-
"temperature": temperature,
|
| 120 |
-
"frequency_penalty": frequency_penalty,
|
| 121 |
-
"max_tokens": max_tokens
|
| 122 |
-
}
|
| 123 |
-
try:
|
| 124 |
-
response = groq_client.chat.completions.create(**params)
|
| 125 |
-
return response.choices[0].message.content
|
| 126 |
-
|
| 127 |
-
except Exception as e:
|
| 128 |
-
print(f"Error calling GROQ API: {e}")
|
| 129 |
-
params["model"] = llm_fallback_small if model == llm_default_small else llm_fallback_medium
|
| 130 |
-
response = together_client.chat.completions.create(**params)
|
| 131 |
-
return response.choices[0].message.content
|
| 132 |
|
|
|
|
|
|
|
| 133 |
|
| 134 |
-
|
| 135 |
-
|
| 136 |
-
Extracts JSON from text using regex and fuzzy JSON loading.
|
| 137 |
-
"""
|
| 138 |
try:
|
| 139 |
-
|
| 140 |
-
|
| 141 |
-
|
| 142 |
-
|
| 143 |
-
|
| 144 |
-
else:
|
| 145 |
-
json_out = text
|
| 146 |
-
# Use Fuzzy JSON loading
|
| 147 |
-
return loads(json_out)
|
| 148 |
-
|
| 149 |
-
@retry(tries=3, delay=0.5)
|
| 150 |
-
def generate_topics(user_input, num_topics, previous_queries):
|
| 151 |
-
prompt = prompt_topics.format(user_input=user_input, num_topics=num_topics)
|
| 152 |
-
response_topics = together_response(prompt, model=llm_default_medium, SysPrompt=SysPromptList, temperature=1)
|
| 153 |
-
subtopics = json_from_text(response_topics)
|
| 154 |
-
return subtopics
|
| 155 |
-
|
| 156 |
-
@retry(tries=3, delay=0.5)
|
| 157 |
-
def generate_subtopics(main_task,user_input,num_topics,excluded_topics):
|
| 158 |
-
excluded_topics = ",".join(excluded_topics)
|
| 159 |
-
prompt = prompt_subtopics.format(main_task = main_task,user_input=user_input, num_topics=num_topics, excluded_topics=excluded_topics)
|
| 160 |
-
response_topics = together_response(prompt, model=llm_default_medium, SysPrompt=SysPromptList, temperature=1)
|
| 161 |
-
subtopics = json_from_text(response_topics)
|
| 162 |
-
return subtopics
|
| 163 |
-
|
| 164 |
-
@retry(tries=3, delay=0.5)
|
| 165 |
-
def generate_report(topic, description):
|
| 166 |
-
prompt = f"""create a detailed report on: {topic} by following the instructions: {description}"""
|
| 167 |
-
md_report = together_response(prompt, model = llm_default_medium, SysPrompt = SysPromptMdOffline)
|
| 168 |
-
return md_to_html(md_report)
|
| 169 |
-
|
| 170 |
-
@retry(tries=3, delay=0.5)
|
| 171 |
-
def get_images(query, num_results):
|
| 172 |
-
time.sleep(0.5)
|
| 173 |
-
ddgs = DDGS()
|
| 174 |
-
imgs = ddgs.images(keywords=query, safesearch="on", max_results=num_results)
|
| 175 |
-
return imgs
|
| 176 |
-
|
| 177 |
-
# Define the app
|
| 178 |
-
app = FastAPI()
|
| 179 |
|
| 180 |
app.add_middleware(
|
| 181 |
CORSMiddleware,
|
|
@@ -185,69 +24,6 @@ app.add_middleware(
|
|
| 185 |
allow_headers=["*"],
|
| 186 |
)
|
| 187 |
|
| 188 |
-
# Create a Pydantic model to handle the input data
|
| 189 |
-
class TopicInput(BaseModel):
|
| 190 |
-
user_input: str = Query(default="market research", description="input query to generate subtopics")
|
| 191 |
-
num_topics: int = Query(default=5, description="Number of subtopics to generate (default: 5)")
|
| 192 |
-
previous_queries: list[str] = Query(default=[], description="Deprecated: Use /generate_subtopics instead for subtopics")
|
| 193 |
-
|
| 194 |
-
class SubTopicInput(BaseModel):
|
| 195 |
-
main_task: str = Query(default="detailed market research", description="Main task to be completed")
|
| 196 |
-
user_input: str = Query(default="I want to start a business in retail", description="input query to generate subtopics")
|
| 197 |
-
num_topics: int = Query(default=3, description="Number of max subtopics to generate (default: 3)")
|
| 198 |
-
excluded_topics: list[str] = Query(default=[], description="List all other main tasks to exclude")
|
| 199 |
-
|
| 200 |
-
class imageInput(BaseModel):
|
| 201 |
-
user_input: str = Query(default="market research", description="input query to generate subtopics")
|
| 202 |
-
num_images: int = Query(default=5, description="Number of subtopics to generate (default: 5)")
|
| 203 |
-
|
| 204 |
-
class ReportInput(BaseModel):
|
| 205 |
-
topic: str = Query(default="market research",description="The main topic for the report")
|
| 206 |
-
description: str = Query(default="",description="A brief description of the topic")
|
| 207 |
-
|
| 208 |
-
class RecommendationInput(BaseModel):
|
| 209 |
-
user_input: str = Query(default="", description="Input query to generate follow-up questions")
|
| 210 |
-
num_recommendations: int = Query(default=5, description="Number of recommendations to generate")
|
| 211 |
-
|
| 212 |
@app.get("/", tags=["Home"])
|
| 213 |
def api_home():
|
| 214 |
-
return {'detail': 'Welcome to FastAPI Subtopics API! Visit https://pvanand-generate-subtopics.hf.space/docs to test'}
|
| 215 |
-
|
| 216 |
-
@app.post("/generate_topics")
|
| 217 |
-
async def create_topics(input: TopicInput):
|
| 218 |
-
topics = generate_topics(input.user_input, input.num_topics, input.previous_queries)
|
| 219 |
-
return {"topics": topics}
|
| 220 |
-
|
| 221 |
-
@app.post("/generate_subtopics")
|
| 222 |
-
async def create_subtopics(input: SubTopicInput):
|
| 223 |
-
topics = generate_subtopics(input.main_task, input.user_input, input.num_topics, input.excluded_topics)
|
| 224 |
-
return {"subtopics": topics}
|
| 225 |
-
|
| 226 |
-
@app.post("/generate_report")
|
| 227 |
-
async def create_report(input: ReportInput):
|
| 228 |
-
report = generate_report(input.topic, input.description)
|
| 229 |
-
return {"report": report}
|
| 230 |
-
|
| 231 |
-
@app.post("/get_images")
|
| 232 |
-
async def fetch_images(input: imageInput):
|
| 233 |
-
images = get_images(input.user_input, input.num_images)
|
| 234 |
-
return {"images": images}
|
| 235 |
-
|
| 236 |
-
@app.post("/get_recommendations")
|
| 237 |
-
async def generate_recommendations(input: RecommendationInput):
|
| 238 |
-
|
| 239 |
-
if input.user_input:
|
| 240 |
-
prompt = f"""create a list of {input.num_recommendations} questions that a user might ask following the question: {input.user_input}:"""
|
| 241 |
-
else:
|
| 242 |
-
prompt = f"""create a list of mixed {input.num_recommendations} questions to create a report or plan or course on any of the topics product,market,research topic """
|
| 243 |
-
|
| 244 |
-
response_topics = json_from_text(
|
| 245 |
-
together_response(
|
| 246 |
-
prompt, model=llm_default_small, SysPrompt=SysPromptList,temperature=1
|
| 247 |
-
)
|
| 248 |
-
)
|
| 249 |
-
return {"recommendations": response_topics}
|
| 250 |
-
|
| 251 |
-
|
| 252 |
-
|
| 253 |
-
|
|
|
|
| 1 |
+
from fastapi import FastAPI, HTTPException
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 2 |
from pydantic import BaseModel
|
| 3 |
+
import hrequests
|
|
|
|
|
|
|
|
|
|
| 4 |
|
| 5 |
+
app = FastAPI()
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 6 |
|
| 7 |
+
class URLRequest(BaseModel):
|
| 8 |
+
url: str
|
| 9 |
|
| 10 |
+
@app.post("/scrape")
|
| 11 |
+
async def scrape(url_request: URLRequest):
|
|
|
|
|
|
|
| 12 |
try:
|
| 13 |
+
response = hrequests.get(url_request.url)
|
| 14 |
+
response.raise_for_status() # Raise an HTTPError for bad responses
|
| 15 |
+
return {"content": response.text}
|
| 16 |
+
except hrequests.exceptions.RequestException as e:
|
| 17 |
+
raise HTTPException(status_code=400, detail=str(e))
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 18 |
|
| 19 |
app.add_middleware(
|
| 20 |
CORSMiddleware,
|
|
|
|
| 24 |
allow_headers=["*"],
|
| 25 |
)
|
| 26 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 27 |
@app.get("/", tags=["Home"])
|
| 28 |
def api_home():
|
| 29 |
+
return {'detail': 'Welcome to FastAPI Subtopics API! Visit https://pvanand-generate-subtopics.hf.space/docs to test'}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|