Develoerweb commited on
Commit
59ce898
Β·
verified Β·
1 Parent(s): 7037b53

Upload 3 files

Browse files
Files changed (3) hide show
  1. app.py +162 -0
  2. readme.md +17 -0
  3. requirement.txt +2 -0
app.py ADDED
@@ -0,0 +1,162 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # -*- coding: utf-8 -*-
2
+ """Market trent.ipynb
3
+
4
+ Automatically generated by Colab.
5
+
6
+ Original file is located at
7
+ https://colab.research.google.com/drive/17xZqaTqSxGLAUBlBnktmkfsON24wtK5d
8
+ """
9
+
10
+ !pip install requests #install dependency
11
+
12
+ import requests
13
+ import json
14
+
15
+ !pip install streamlit
16
+
17
+ import streamlit as st
18
+
19
+ def search_google(query, num_results=5):
20
+ url = "https://google.serper.dev/search"
21
+ headers = {
22
+ "X-API-KEY": SERPER_API_KEY,
23
+ "Content-Type": "application/json"
24
+ }
25
+ payload = {
26
+ "q": query
27
+ }
28
+
29
+ response = requests.post(url, headers=headers, json=payload)
30
+ if response.status_code == 200:
31
+ data = response.json()
32
+ links = [result['link'] for result in data.get('organic', [])][:num_results]
33
+ return links
34
+ else:
35
+ raise Exception("Google Search failed:", response.text)
36
+
37
+ def scrape_with_firecrawl(url):
38
+
39
+ endpoint = "https://api.firecrawl.dev/v1/scrape"
40
+ headers = {
41
+ "Authorization": f"Bearer {FIRECRAWL_API_KEY}",
42
+ "Content-Type": "application/json"
43
+ }
44
+ payload = {
45
+ "url": url,
46
+ "formats": ["markdown"],
47
+ "onlyMainContent": True
48
+ }
49
+
50
+ response = requests.post(endpoint, headers=headers, json=payload)
51
+ if response.status_code == 200:
52
+ result = response.json()
53
+ return result.get("data", {}).get("markdown", "No markdown content found.")
54
+ else:
55
+ raise Exception(f"Firecrawl error: {response.text}")
56
+
57
+ def mistral_call(prompt):
58
+ url = "https://api.mistral.ai/v1/chat/completions"
59
+ headers = {
60
+ "Authorization": f"Bearer {MISTRAL_API_KEY}",
61
+ "Content-Type": "application/json"
62
+ }
63
+ data = {
64
+ "model": "mistral-medium",
65
+ "messages": [
66
+ {"role": "system", "content": " Youre an emotion classifier for fashion-related content. Classify the overall emotional tone from the reader's perspective β€” does the content feel exciting, dull, or negative in tone? only respond with one word: exciting, dull, or negative"},
67
+ {"role": "user", "content": prompt}
68
+ ],
69
+ "temperature": 0.3
70
+ }
71
+
72
+ response = requests.post(url, json=data, headers=headers)
73
+ if response.status_code == 200:
74
+ return response.json()["choices"][0]["message"]["content"].strip().lower()
75
+ else:
76
+ raise Exception(f"Mistral API Error: {response.status_code} | {response.text}")
77
+
78
+ def filter_sentiment_mistral(text):
79
+ print("πŸ§ͺ Running sentiment analysis...")
80
+ sentiment = mistral_call(text[:3000]) # truncating large input for safety
81
+ print(f"πŸ“Š Sentiment detected: {sentiment}")
82
+ return sentiment
83
+
84
+ def extract_trends_with_mistral(content):
85
+ endpoint = "https://api.mistral.ai/v1/chat/completions"
86
+ headers = {
87
+ "Authorization": f"Bearer {MISTRAL_API_KEY}",
88
+ "Content-Type": "application/json"
89
+ }
90
+ prompt = f"""
91
+ You are a trend analyst. From the following content, identify up to 5 emerging microtrends.
92
+ Format your response as a JSON list with trend name and short description.
93
+
94
+ Content:
95
+ {content[:3000]}
96
+ """
97
+
98
+ payload = {
99
+ "model": "mistral-medium",
100
+ "messages": [{"role": "user", "content": prompt}],
101
+ "temperature": 0.7
102
+ }
103
+
104
+ response = requests.post(endpoint, headers=headers, json=payload)
105
+ if response.status_code == 200:
106
+ return response.json()['choices'][0]['message']['content']
107
+ else:
108
+ return "Error: Could not extract trends."
109
+
110
+ EXCLUDED_DOMAINS = ["instagram.com", "facebook.com", "linkedin.com", "youtube.com"]
111
+
112
+ def is_valid_url(url):
113
+ return not any(domain in url for domain in EXCLUDED_DOMAINS)
114
+
115
+ '''def run_trend_detection(topic):
116
+ urls = search_google(topic)
117
+ for url in urls:
118
+ try:
119
+ content = scrape_with_firecrawl(url)
120
+ sentiment = filter_sentiment_mistral(content)
121
+ print(f"πŸ“Š Sentiment detected: {sentiment}")
122
+
123
+ # --- Insert the loosening filter here ---
124
+ if sentiment.lower() in ["exciting", "neutral"]:
125
+ trend_prompt = f"Extract 3 fashion trends as hashtags from this content:\n{content[:3000]}"
126
+ trends = mistral_call(trend_prompt)
127
+ print(f"πŸ”₯ Trends:\n{trends}")
128
+ else:
129
+ print(f"⚠️ Content sentiment '{sentiment}' not exciting enough for trend extraction")
130
+
131
+ except Exception as e:
132
+ print(f"❌ Skipping {url} due to error: {e}")
133
+
134
+ st.title("πŸ‘— TrendDetective: AI-Powered Trend Spotter")
135
+
136
+ topic = st.text_input("Enter a topic to analyze trends:", value="Summer fashion 2025 in Bengaluru")
137
+
138
+ if st.button("Run Trend Detection"):
139
+ with st.spinner("πŸ” Scanning the web and analyzing..."):
140
+ urls = search_google(topic)
141
+ if not urls:
142
+ st.error("No URLs found.")
143
+ else:
144
+ for url in urls:
145
+ if not is_valid_url(url):
146
+ continue
147
+ st.markdown(f"**πŸ”— URL:** {url}")
148
+ content = scrape_with_firecrawl(url)
149
+ if not content:
150
+ st.warning("No content extracted.")
151
+ continue
152
+ sentiment = filter_sentiment_mistral(content)
153
+ st.markdown(f"**🧠 Sentiment:** `{sentiment}`")
154
+ if sentiment in ["exciting", "neutral"]:
155
+ trends = extract_trends_with_mistral(content)
156
+ st.markdown("**πŸ“ˆ Extracted Trends:**")
157
+ st.code(trends)
158
+ else:
159
+ st.markdown("_Skipped due to sentiment filter_")
160
+ st.markdown("---")
161
+
162
+ streamlit run /usr/local/lib/python3.11/dist-packages/colab_kernel_launcher.py
readme.md ADDED
@@ -0,0 +1,17 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # πŸ‘— TrendDetective – AI-Powered Microtrend Analyzer
2
+
3
+ This app uses AI agents to detect emerging microtrends from web content. Built using Streamlit, Mistral AI, Firecrawl, and Serper.dev.
4
+
5
+ ### How it works:
6
+ 1. Search relevant articles based on your topic
7
+ 2. Scrape content from the articles
8
+ 3. Analyze sentiment
9
+ 4. Extract actionable fashion trends as hashtags
10
+
11
+ ### Technologies:
12
+ - Firecrawl MCP (web scraping)
13
+ - Mistral LLM API (sentiment + trend extraction)
14
+ - Serper.dev (Google Search API)
15
+ - Streamlit (UI)
16
+
17
+ Built by Vaisakh, aspiring AI Product Manager.
requirement.txt ADDED
@@ -0,0 +1,2 @@
 
 
 
1
+ streamlit
2
+ requests