app.py
CHANGED
|
@@ -6,6 +6,7 @@ import gradio as gr
|
|
| 6 |
from transformers import pipeline
|
| 7 |
import csv
|
| 8 |
import tempfile
|
|
|
|
| 9 |
from datetime import datetime, timedelta
|
| 10 |
from urllib.parse import quote
|
| 11 |
|
|
@@ -43,16 +44,23 @@ def analyze_single_company(company_name: str, api_key: str, is_forced_analysis:
|
|
| 43 |
url = f'https://newsapi.org/v2/everything?q="{encoded_company_name}"&from={thirty_days_ago}&sortBy=relevancy&language=en&apiKey={api_key}'
|
| 44 |
|
| 45 |
try:
|
| 46 |
-
response = requests.get(url, timeout=
|
| 47 |
-
response.raise_for_status()
|
| 48 |
articles = response.json().get("articles", [])
|
| 49 |
except requests.exceptions.RequestException as e:
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 50 |
print(f"API request failed for {company_name}: {e}")
|
| 51 |
return {
|
| 52 |
"Company": f"{company_name} {'(Forensic)' if is_forced_analysis else ''}",
|
| 53 |
"Distress Score": -1,
|
| 54 |
-
"Summary":
|
| 55 |
-
"Key Evidence": "
|
| 56 |
}
|
| 57 |
|
| 58 |
if not articles:
|
|
@@ -61,7 +69,7 @@ def analyze_single_company(company_name: str, api_key: str, is_forced_analysis:
|
|
| 61 |
summary = "Forensic search found no articles matching distress keywords."
|
| 62 |
return {"Company": f"{company_name} {'(Forensic)' if is_forced_analysis else ''}", "Distress Score": 0, "Summary": summary, "Key Evidence": "N/A"}
|
| 63 |
|
| 64 |
-
#
|
| 65 |
total_sentiment_score, sentiment_articles_count = 0, 0
|
| 66 |
shutdown_mentions, layoff_mentions, exec_departure_mentions, negative_funding_mentions = 0, 0, 0, 0
|
| 67 |
key_evidence = []
|
|
@@ -126,14 +134,13 @@ def batch_analyze_companies(company_list_str: str, high_suspicion_list_str: str,
|
|
| 126 |
all_results = []
|
| 127 |
progress(0, desc="Starting Analysis...")
|
| 128 |
|
| 129 |
-
# --- Sequential Processing for Reliability ---
|
| 130 |
-
# This loop processes one company at a time to avoid API rate limits.
|
| 131 |
for i, name in enumerate(all_names):
|
| 132 |
is_suspicious = name in suspicion_names
|
| 133 |
progress((i) / len(all_names), desc=f"Analyzing {name}...")
|
| 134 |
try:
|
| 135 |
result = analyze_single_company(name, api_key, is_suspicious)
|
| 136 |
if result: all_results.append(result)
|
|
|
|
| 137 |
except Exception as exc:
|
| 138 |
print(f'{name} generated an exception: {exc}')
|
| 139 |
all_results.append({
|
|
@@ -158,15 +165,15 @@ with gr.Blocks(theme=gr.themes.Soft(primary_hue="blue", secondary_hue="blue")) a
|
|
| 158 |
gr.Markdown("# PE Sourcing Intelligence Engine")
|
| 159 |
gr.Markdown(
|
| 160 |
"""
|
| 161 |
-
**Step 1:** Add companies
|
| 162 |
-
**Step 2:** For
|
| 163 |
**Pro Tip:** This tool runs sequentially to be reliable with free APIs. Long lists will take time. Please be patient.
|
| 164 |
"""
|
| 165 |
)
|
| 166 |
|
| 167 |
with gr.Row():
|
| 168 |
with gr.Column(scale=1):
|
| 169 |
-
news_api_key_input = gr.Textbox(label="Enter Your NewsAPI Key", type="password", placeholder="Paste your key here")
|
| 170 |
company_list_input = gr.TextArea(label="Standard Watch List", lines=8, placeholder="Screening List:\nAcme Corp\nInnovate Inc...")
|
| 171 |
high_suspicion_input = gr.TextArea(label="Forensic Analysis List", lines=7, placeholder="High-Suspicion Targets:\nConvoy\nWeWork...")
|
| 172 |
submit_button = gr.Button("Generate Distress Briefing", variant="primary")
|
|
|
|
| 6 |
from transformers import pipeline
|
| 7 |
import csv
|
| 8 |
import tempfile
|
| 9 |
+
import time
|
| 10 |
from datetime import datetime, timedelta
|
| 11 |
from urllib.parse import quote
|
| 12 |
|
|
|
|
| 44 |
url = f'https://newsapi.org/v2/everything?q="{encoded_company_name}"&from={thirty_days_ago}&sortBy=relevancy&language=en&apiKey={api_key}'
|
| 45 |
|
| 46 |
try:
|
| 47 |
+
response = requests.get(url, timeout=20)
|
| 48 |
+
response.raise_for_status() # This will raise an HTTPError for 4xx/5xx responses
|
| 49 |
articles = response.json().get("articles", [])
|
| 50 |
except requests.exceptions.RequestException as e:
|
| 51 |
+
error_message = "API Request Failed."
|
| 52 |
+
if hasattr(e, 'response') and e.response is not None:
|
| 53 |
+
if e.response.status_code == 401:
|
| 54 |
+
error_message = "API Key is invalid or expired."
|
| 55 |
+
elif e.response.status_code == 429:
|
| 56 |
+
error_message = "API Rate Limit Exceeded."
|
| 57 |
+
|
| 58 |
print(f"API request failed for {company_name}: {e}")
|
| 59 |
return {
|
| 60 |
"Company": f"{company_name} {'(Forensic)' if is_forced_analysis else ''}",
|
| 61 |
"Distress Score": -1,
|
| 62 |
+
"Summary": error_message,
|
| 63 |
+
"Key Evidence": "Please check your API key and try again with a smaller list."
|
| 64 |
}
|
| 65 |
|
| 66 |
if not articles:
|
|
|
|
| 69 |
summary = "Forensic search found no articles matching distress keywords."
|
| 70 |
return {"Company": f"{company_name} {'(Forensic)' if is_forced_analysis else ''}", "Distress Score": 0, "Summary": summary, "Key Evidence": "N/A"}
|
| 71 |
|
| 72 |
+
# ... [rest of the analysis logic is the same] ...
|
| 73 |
total_sentiment_score, sentiment_articles_count = 0, 0
|
| 74 |
shutdown_mentions, layoff_mentions, exec_departure_mentions, negative_funding_mentions = 0, 0, 0, 0
|
| 75 |
key_evidence = []
|
|
|
|
| 134 |
all_results = []
|
| 135 |
progress(0, desc="Starting Analysis...")
|
| 136 |
|
|
|
|
|
|
|
| 137 |
for i, name in enumerate(all_names):
|
| 138 |
is_suspicious = name in suspicion_names
|
| 139 |
progress((i) / len(all_names), desc=f"Analyzing {name}...")
|
| 140 |
try:
|
| 141 |
result = analyze_single_company(name, api_key, is_suspicious)
|
| 142 |
if result: all_results.append(result)
|
| 143 |
+
time.sleep(0.5) # Add a small delay between requests to be gentle on the API
|
| 144 |
except Exception as exc:
|
| 145 |
print(f'{name} generated an exception: {exc}')
|
| 146 |
all_results.append({
|
|
|
|
| 165 |
gr.Markdown("# PE Sourcing Intelligence Engine")
|
| 166 |
gr.Markdown(
|
| 167 |
"""
|
| 168 |
+
**Step 1:** Add companies to the **Standard Watch List**.
|
| 169 |
+
**Step 2:** For high-suspicion targets, add them to the **Forensic Analysis List** for a deeper search.
|
| 170 |
**Pro Tip:** This tool runs sequentially to be reliable with free APIs. Long lists will take time. Please be patient.
|
| 171 |
"""
|
| 172 |
)
|
| 173 |
|
| 174 |
with gr.Row():
|
| 175 |
with gr.Column(scale=1):
|
| 176 |
+
news_api_key_input = gr.Textbox(label="Enter Your NewsAPI Key", type="password", placeholder="Paste your new, correct key here")
|
| 177 |
company_list_input = gr.TextArea(label="Standard Watch List", lines=8, placeholder="Screening List:\nAcme Corp\nInnovate Inc...")
|
| 178 |
high_suspicion_input = gr.TextArea(label="Forensic Analysis List", lines=7, placeholder="High-Suspicion Targets:\nConvoy\nWeWork...")
|
| 179 |
submit_button = gr.Button("Generate Distress Briefing", variant="primary")
|