pritmanvar commited on
Commit
fbd9e3e
·
verified ·
1 Parent(s): 9ec9476

Upload 8 files

Browse files
.dockerignore ADDED
@@ -0,0 +1,9 @@
 
 
 
 
 
 
 
 
 
 
1
+ __pycache__/
2
+ *.pyc
3
+ *.pyo
4
+ *.pyd
5
+ .venv/
6
+ .env
7
+ .git
8
+ *.log
9
+ news_data.json
Dockerfile ADDED
@@ -0,0 +1,18 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Dockerfile for deploying the FastAPI app on Hugging Face Spaces or any Docker environment
2
+ FROM python:3.10-slim
3
+
4
+ # Set working directory
5
+ WORKDIR /app
6
+
7
+ # Install Python dependencies
8
+ COPY requirements.txt ./
9
+ RUN pip install --no-cache-dir -r requirements.txt
10
+
11
+ # Copy application code
12
+ COPY . .
13
+
14
+ # Expose port (Hugging Face Spaces uses port 80)
15
+ EXPOSE 80
16
+
17
+ # Run the FastAPI app with Gunicorn and Uvicorn worker
18
+ CMD ["gunicorn", "app:app", "--workers", "1", "--bind", "0.0.0.0:80", "--worker-class", "uvicorn.workers.UvicornWorker"]
agents.py ADDED
@@ -0,0 +1,102 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import os
2
+ import json
3
+ import time
4
+ import traceback
5
+
6
+ from langchain_core.prompts import PromptTemplate
7
+ from langchain_core.output_parsers import JsonOutputParser
8
+ from pydantic import BaseModel, Field
9
+
10
+ from langchain_groq import ChatGroq
11
+ from dotenv import load_dotenv
12
+
13
+ load_dotenv()
14
+
15
+ analysis_llm = ChatGroq(
16
+ model="llama-3.1-8b-instant ",
17
+ temperature=0.8,
18
+ max_tokens=800,
19
+ timeout=None,
20
+ max_retries=2,
21
+ api_key=os.getenv("GROQ_ANALYSIS_API_KEY"),
22
+ )
23
+ post_content_llm = ChatGroq(
24
+ model="qwen-qwq-32b",
25
+ temperature=0.8,
26
+ timeout=None,
27
+ max_retries=2,
28
+ api_key=os.getenv("THREADS_POST_GENERATION_API_KEY"),
29
+ )
30
+
31
+
32
+ def basic_analysis(news):
33
+ global analysis_llm_indx
34
+ prompt = PromptTemplate.from_file(
35
+ template_file="prompts/news_selector.yml",
36
+ input_variables=["news_object"],
37
+ )
38
+
39
+ for _ in range(5):
40
+ try:
41
+ response = analysis_llm.invoke(
42
+ prompt.invoke({"news_object": news})
43
+ )
44
+ print("################ BASIC ANALYSIS AGENT RESPONSE ################")
45
+ print(response.content)
46
+ print("################ BASIC ANALYSIS END AGENT RESPONSE ################")
47
+
48
+ start_index = response.content.find("{")
49
+ end_index = response.content.rfind("}")
50
+
51
+ print("start index:", start_index)
52
+ print("end index:", end_index)
53
+
54
+ abstracted_string = ""
55
+ if start_index != -1 and end_index != -1 and start_index < end_index:
56
+ abstracted_string = response.content[start_index : end_index + 1]
57
+
58
+ try:
59
+ results = json.loads(abstracted_string)
60
+ print(results)
61
+ return results
62
+ except Exception as e:
63
+ print(e)
64
+ traceback.print_exc()
65
+ except Exception as e:
66
+ print(e)
67
+ traceback.print_exc()
68
+ time.sleep(30)
69
+
70
+ raise ValueError("LLM response is not in correct format.")
71
+
72
+
73
+ def get_text_post_content(details, reference):
74
+ try:
75
+ prompt = PromptTemplate.from_file(
76
+ template_file="prompts/post_generator_without_source.yml",
77
+ input_variables=["NEWS_CONTENT", "CHAR_LENGTH"],
78
+ )
79
+
80
+ user_query = prompt.invoke(
81
+ {"NEWS_CONTENT": details, "CHAR_LENGTH": 490- len(reference)}
82
+ )
83
+ response = post_content_llm.invoke(user_query)
84
+
85
+ print("POST CONTENT RESPONSE:", response)
86
+
87
+ content = response.content.replace('"', '')
88
+
89
+ if "</think>" in content:
90
+ content = content.split("</think>")[1]
91
+
92
+ start_indx = content.find("#")
93
+ content = f"""{content[:start_indx]}
94
+ {reference}
95
+
96
+ {content[start_indx:]}"""
97
+
98
+ return content, True
99
+ except Exception as e:
100
+ print(e)
101
+ traceback.print_exc()
102
+ return "", False
app.py ADDED
@@ -0,0 +1,13 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from fastapi import FastAPI
2
+
3
+ from agents import basic_analysis, get_text_post_content
4
+
5
+ app = FastAPI()
6
+
7
+ @app.post("/get_basic_analysis")
8
+ def handle_basic_analysis(news: dict):
9
+ return basic_analysis(news)
10
+
11
+ @app.post("/get_text_post_content")
12
+ def handle_text_post_content(details: str, reference: str):
13
+ return get_text_post_content(details, reference)
prompts/news_selector.yml ADDED
@@ -0,0 +1,27 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ input_variables:
2
+ - news_object
3
+
4
+ template: >-
5
+ You are an expert news analyzer. Your task is to analyze news to determine how it will impact the Indian stock market with the help of a title and a small description of the news if given. You will be given a news object in which some fields will be empty. You have to fill in those fields and return the same filled object.
6
+
7
+ Formate of news object:
8
+ {{
9
+ "title": "",
10
+ "url": "",
11
+ "description": " ",
12
+ "time": "",
13
+ "source": "",
14
+ "will_it_directly_impact_any_stock": "" -> boolean: true/false,
15
+ "directly_mentioned_companies_in_news": [] -> name of companies which are directly mentioned in the news and listed in indian stockmarket.,
16
+ "how_will_it_impact": "" -> categorical: Very Positive, Positive, Nautural, Negative, Very Negative.
17
+ "reason": "" -> reason for the impact.
18
+ }}
19
+
20
+ Output instructions:
21
+ - You have to strictly return news object after filling empty fields.
22
+ - You have to fill the fields in the same news object and return it.
23
+ - Don't give any additional information apart from filled news object.
24
+ - You must always return valid JSON fenced by a markdown code block. Do not return any additional text.
25
+
26
+ NEWS objects to analyze:
27
+ {news_object}
prompts/post_generator.yml ADDED
@@ -0,0 +1,26 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Not in use.
2
+ input_variables:
3
+ - NEWS_CONTENT
4
+ - REFERENCE_URL
5
+ - CHAR_LENGTH
6
+
7
+ template: >-
8
+ You are an AI assistant specializing in creating concise, impactful social media posts for Threads. Your task is to generate a post based on the provided news and its reference link, ensuring it meets the following criteria:
9
+
10
+ 1. **Summary:** Provide a brief yet informative summary of the news, highlighting key details and numbers.
11
+ 2. **Impacted Stocks:** Identify Indian stocks that may be affected by this news but don't directly mention this in post content by saing impacted stocks.
12
+ 3. **Character Limit:** Ensure the entire post does not exceed {CHAR_LENGTH} characters.
13
+ 4. **Format:** You can use any format to present the news but above guidelines must be followed.
14
+ 5. **HashTags:** Add few tranding hashtags under 20 chars in the post content.
15
+ 6. **Source URL:** You must Include the full provided Source URL with given route in the post.
16
+
17
+ Output instructions:
18
+ - Don't use emoji in the post content.
19
+ - You have to strictly return post content only not any other information or your thoughts.
20
+
21
+ Here is the news:
22
+ {NEWS_CONTENT}
23
+
24
+ Source URL: {REFERENCE_URL}
25
+
26
+ Generate the post following these guidelines without add any additional details or information.
prompts/post_generator_without_source.yml ADDED
@@ -0,0 +1,20 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ input_variables:
2
+ - NEWS_CONTENT
3
+ - CHAR_LENGTH
4
+
5
+ template: >-
6
+ You are an AI assistant specializing in creating concise, impactful social media posts for Threads. Your task is to generate a post based on the provided news and its reference link, ensuring it meets the following criteria:
7
+
8
+ 1. **Summary:** Provide a brief yet informative summary of the news, highlighting key details and numbers.
9
+ 2. **Impacted Stocks:** Identify Indian stocks that may be affected by this news but don't directly mention this in post content by saing impacted stocks.
10
+ 3. **Character Limit:** Ensure the entire post does not exceed {CHAR_LENGTH} characters.
11
+ 4. **Format:** You can use any format to present the news but above guidelines must be followed.
12
+ 5. **HashTags:** Add only one related tranding hashtags under 10 chars at the last.
13
+
14
+ Output instructions:
15
+ - You have to strictly return post content only not any other information or your thoughts. Don't include Link in the post content.
16
+
17
+ Here is the news:
18
+ {NEWS_CONTENT}
19
+
20
+ Generate the post following these guidelines without add any additional details or information.
requirements.txt ADDED
@@ -0,0 +1,16 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ bs4==0.0.2
2
+ html2text==2024.2.26
3
+ pymongo[srv]==4.11
4
+ selenium==4.28.1
5
+ webdriver-manager==4.0.2
6
+ tiktoken==0.8.0
7
+ python-dotenv==1.0.1
8
+ langchain==0.3.17
9
+ langchain_core==0.3.33
10
+ langchain_groq==0.2.4
11
+ langchain_community==0.3.16
12
+ fastapi===0.115.8
13
+ gunicorn===23.0.0
14
+ uvicorn===0.34.0
15
+ pydantic==2.9.2
16
+ certifi