Sigrid De los Santos commited on
Commit
342fd5f
·
1 Parent(s): 2d6be16

Add Streamlit app files

Browse files
Files changed (2) hide show
  1. app.py +141 -0
  2. requirements.txt +88 -0
app.py ADDED
@@ -0,0 +1,141 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import os
2
+ import sys
3
+ import tempfile
4
+ import streamlit as st
5
+ import pandas as pd
6
+ from io import StringIO
7
+ import contextlib
8
+
9
+ # Add 'src' to Python path so we can import main.py
10
+ sys.path.append(os.path.join(os.path.dirname(__file__), 'src'))
11
+ from main import run_pipeline
12
+
13
+ st.set_page_config(page_title="📰 AI News Analyzer", layout="wide")
14
+ st.title("🧠 AI-Powered Investing News Analyzer")
15
+
16
+ # === API Key Input ===
17
+ st.subheader("🔐 API Keys")
18
+ openai_api_key = st.text_input("OpenAI API Key", type="password").strip()
19
+ tavily_api_key = st.text_input("Tavily API Key", type="password").strip()
20
+
21
+ # === Topic Input ===
22
+ st.subheader("📈 Topics of Interest")
23
+ topics_data = []
24
+
25
+ with st.form("topics_form"):
26
+ topic_count = st.number_input("How many topics?", min_value=1, max_value=10, value=1, step=1)
27
+
28
+ for i in range(topic_count):
29
+ col1, col2 = st.columns(2)
30
+ with col1:
31
+ topic = st.text_input(f"Topic {i+1}", key=f"topic_{i}")
32
+ with col2:
33
+ days = st.number_input(f"Timespan (days)", min_value=1, max_value=30, value=7, key=f"days_{i}")
34
+ topics_data.append({"topic": topic, "timespan_days": days})
35
+
36
+ submitted = st.form_submit_button("Run Analysis")
37
+
38
+ # === Submission logic ===
39
+ if submitted:
40
+ if not openai_api_key or not tavily_api_key or not all([td['topic'] for td in topics_data]):
41
+ st.warning("Please fill in all fields.")
42
+ else:
43
+ os.environ["OPENAI_API_KEY"] = openai_api_key
44
+ os.environ["TAVILY_API_KEY"] = tavily_api_key
45
+
46
+ df = pd.DataFrame(topics_data)
47
+ with tempfile.NamedTemporaryFile(delete=False, suffix=".csv") as tmp_csv:
48
+ df.to_csv(tmp_csv.name, index=False)
49
+ csv_path = tmp_csv.name
50
+
51
+ # Live log capture
52
+ log_output = st.empty()
53
+ string_buffer = StringIO()
54
+
55
+ with contextlib.redirect_stdout(string_buffer), st.spinner("🔍 Running analysis..."):
56
+ output_path = run_pipeline(csv_path, tavily_api_key)
57
+
58
+ logs = string_buffer.getvalue()
59
+ log_output.code(logs)
60
+
61
+ if output_path and isinstance(output_path, list):
62
+ st.success("✅ Analysis complete!")
63
+
64
+ for path in output_path:
65
+ if os.path.exists(path):
66
+ with open(path, 'r', encoding='utf-8') as file:
67
+ html_content = file.read()
68
+ filename = os.path.basename(path)
69
+
70
+ st.download_button(
71
+ label=f"📥 Download {filename}",
72
+ data=html_content,
73
+ file_name=filename,
74
+ mime="text/html"
75
+ )
76
+ st.components.v1.html(html_content, height=600, scrolling=True)
77
+ else:
78
+ st.error("❌ No reports were generated.")
79
+
80
+
81
+
82
+ # import os
83
+ # import sys
84
+ # import tempfile
85
+ # import streamlit as st
86
+ # import pandas as pd
87
+
88
+ # # Add 'src' to Python path so we can import main.py
89
+ # sys.path.append(os.path.join(os.path.dirname(__file__), 'src'))
90
+ # from main import run_pipeline
91
+
92
+ # st.title("AI-Powered Investing News Analyzer")
93
+
94
+ # # === API Key Input ===
95
+ # st.subheader("🔐 API Keys")
96
+ # openai_api_key = st.text_input("OpenAI API Key", type="password").strip()
97
+ # tavily_api_key = st.text_input("Tavily API Key", type="password").strip()
98
+
99
+ # # === Topic Input ===
100
+ # st.subheader("📰 Topics of Interest")
101
+ # topics_data = []
102
+
103
+ # with st.form("topics_form"):
104
+ # topic_count = st.number_input("How many topics do you want to analyze?", min_value=1, max_value=10, step=1, value=1)
105
+
106
+ # for i in range(topic_count):
107
+ # col1, col2 = st.columns(2)
108
+ # with col1:
109
+ # topic = st.text_input(f"Topic {i+1}", key=f"topic_{i}")
110
+ # with col2:
111
+ # timespan = st.number_input(f"Timespan (days) for Topic {i+1}", min_value=1, max_value=30, value=7, key=f"days_{i}")
112
+ # topics_data.append({"topic": topic, "timespan_days": timespan})
113
+
114
+ # submitted = st.form_submit_button("Analyze Topics")
115
+
116
+ # # === Run pipeline on submit ===
117
+ # if submitted:
118
+ # if not openai_api_key or not tavily_api_key or not all([td['topic'] for td in topics_data]):
119
+ # st.warning("Please fill in all fields.")
120
+ # else:
121
+ # # Set environment variables so downstream modules can use them
122
+ # os.environ["OPENAI_API_KEY"] = openai_api_key
123
+ # os.environ["TAVILY_API_KEY"] = tavily_api_key
124
+
125
+ # # Save user topics to temp CSV
126
+ # df = pd.DataFrame(topics_data)
127
+ # with tempfile.NamedTemporaryFile(delete=False, suffix=".csv") as tmp_csv:
128
+ # df.to_csv(tmp_csv.name, index=False)
129
+ # csv_path = tmp_csv.name
130
+
131
+ # with st.spinner("Running analysis..."):
132
+ # output_path = run_pipeline(csv_path, tavily_api_key)
133
+
134
+ # if os.path.exists(output_path):
135
+ # st.success("✅ Analysis complete!")
136
+ # with open(output_path, 'r', encoding='utf-8') as file:
137
+ # html_content = file.read()
138
+ # st.download_button("📥 Download HTML Report", html_content, file_name="news_report.html", mime="text/html")
139
+ # st.components.v1.html(html_content, height=600, scrolling=True)
140
+ # else:
141
+ # st.error("❌ Something went wrong during the analysis.")
requirements.txt ADDED
@@ -0,0 +1,88 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ altair==5.5.0
2
+ annotated-types==0.7.0
3
+ anyio==4.9.0
4
+ async-timeout==4.0.3
5
+ attrs==25.3.0
6
+ blinker==1.9.0
7
+ cachetools==6.1.0
8
+ certifi==2025.6.15
9
+ charset-normalizer==3.4.2
10
+ click==8.1.8
11
+ distro==1.9.0
12
+ exceptiongroup==1.3.0
13
+ filelock==3.18.0
14
+ fsspec==2025.5.1
15
+ gitdb==4.0.12
16
+ GitPython==3.1.44
17
+ greenlet==3.2.3
18
+ h11==0.16.0
19
+ hf-xet==1.1.5
20
+ httpcore==1.0.9
21
+ httpx==0.28.1
22
+ huggingface-hub==0.33.1
23
+ idna==3.10
24
+ importlib_metadata==8.7.0
25
+ Jinja2==3.1.6
26
+ jiter==0.10.0
27
+ jsonpatch==1.33
28
+ jsonpointer==3.0.0
29
+ jsonschema==4.24.0
30
+ jsonschema-specifications==2025.4.1
31
+ langchain==0.3.26
32
+ langchain-core==0.3.66
33
+ langchain-openai==0.3.27
34
+ langchain-text-splitters==0.3.8
35
+ langsmith==0.4.4
36
+ Markdown==3.8.2
37
+ MarkupSafe==3.0.2
38
+ mpmath==1.3.0
39
+ narwhals==1.45.0
40
+ networkx==3.2.1
41
+ numpy==1.26.4
42
+ openai==1.93.0
43
+ orjson==3.10.18
44
+ packaging==24.2
45
+ pandas==2.3.0
46
+ pillow==11.0.0
47
+ protobuf==6.31.1
48
+ pyarrow==20.0.0
49
+ pydantic==2.11.7
50
+ pydantic_core==2.33.2
51
+ pydeck==0.9.1
52
+ python-dateutil==2.9.0.post0
53
+ python-dotenv==1.1.1
54
+ pytz==2025.2
55
+ PyYAML==6.0.2
56
+ referencing==0.36.2
57
+ regex==2024.11.6
58
+ requests==2.32.4
59
+ requests-toolbelt==1.0.0
60
+ rpds-py==0.26.0
61
+ safetensors==0.5.3
62
+ six==1.17.0
63
+ smmap==5.0.2
64
+ sniffio==1.3.1
65
+ SQLAlchemy==2.0.41
66
+ streamlit==1.46.1
67
+ sympy==1.13.1
68
+ tenacity==9.1.2
69
+ tiktoken==0.9.0
70
+ tokenizers==0.21.2
71
+ toml==0.10.2
72
+ torch==2.2.2
73
+ torchvision==0.17.2
74
+ # OR if 0.17.2 still breaks, try:
75
+ # torchvision==0.16.1
76
+ sympy==1.13.1
77
+ #sympy==1.14.0
78
+ #torch>=2.2.0,<2.6.0
79
+ #torchaudio==2.2.2
80
+ tornado==6.5.1
81
+ tqdm==4.67.1
82
+ transformers==4.53.0
83
+ typing-inspection==0.4.1
84
+ typing_extensions==4.14.0
85
+ tzdata==2025.2
86
+ urllib3==2.5.0
87
+ zipp==3.23.0
88
+ zstandard==0.23.0