Skip to content

Instantly share code, notes, and snippets.

@hakkm
Created April 5, 2025 21:45
Show Gist options
  • Save hakkm/b676b056594a1a7a84b18cf402f08bdb to your computer and use it in GitHub Desktop.
Save hakkm/b676b056594a1a7a84b18cf402f08bdb to your computer and use it in GitHub Desktop.
import streamlit as st
import requests
import pandas as pd
import matplotlib.pyplot as plt
from textblob import TextBlob
from datetime import datetime
from io import BytesIO
from fpdf import FPDF
# --- CONFIGURATION ---
OPENWEATHER_API_KEY = "YOUR_API_KEY" # Remplace avec ta clé OpenWeatherMap
# --- FONCTIONS ---
def get_air_quality(city):
url = f"http://api.openweathermap.org/data/2.5/air_pollution?appid={OPENWEATHER_API_KEY}&q={city}"
geocode_url = f"http://api.openweathermap.org/geo/1.0/direct?q={city}&limit=1&appid={OPENWEATHER_API_KEY}"
geo_res = requests.get(geocode_url).json()
if not geo_res:
return None
lat, lon = geo_res[0]['lat'], geo_res[0]['lon']
air_url = f"http://api.openweathermap.org/data/2.5/air_pollution?lat={lat}&lon={lon}&appid={OPENWEATHER_API_KEY}"
res = requests.get(air_url)
if res.status_code == 200:
return res.json()['list'][0]
return None
def fake_social_comments(city):
return [
f"The air in {city} is terrible today!",
f"I love how walkable {city} is.",
f"Too much traffic in downtown {city}...",
f"Great use of solar energy in {city}!",
f"{city} needs more bike lanes."
]
def analyze_sentiment(comments):
results = []
for comment in comments:
blob = TextBlob(comment)
sentiment = blob.sentiment.polarity
results.append({"comment": comment, "sentiment": sentiment})
return results
def summarize_report(air_data, sentiment_data):
avg_sentiment = sum(d['sentiment'] for d in sentiment_data) / len(sentiment_data)
quality_index = air_data['main']['aqi'] if air_data else 'Unknown'
if avg_sentiment > 0.3:
mood = "Generally positive social feedback."
elif avg_sentiment < -0.3:
mood = "Widespread dissatisfaction in social media."
else:
mood = "Mixed or neutral sentiments."
report = f"Air Quality Index: {quality_index}\nSocial Sentiment Score: {avg_sentiment:.2f}\nAnalysis: {mood}"
return report
def generate_sentiment_chart(data):
df = pd.DataFrame(data)
fig, ax = plt.subplots()
df['sentiment'].plot(kind='bar', color='skyblue', ax=ax)
ax.set_title("Sentiment Score per Comment")
ax.set_xticks(range(len(df)))
ax.set_xticklabels([f"{i+1}" for i in range(len(df))])
ax.set_ylabel("Sentiment Polarity")
st.pyplot(fig)
def generate_pdf_report(city, air_data, sentiment_data, summary):
pdf = FPDF()
pdf.add_page()
pdf.set_font("Arial", size=12)
pdf.cell(200, 10, txt=f"Ville Durable Report - {city}", ln=True, align='C')
pdf.ln(10)
pdf.set_font("Arial", 'B', 12)
pdf.cell(200, 10, txt="Résumé de l'analyse:", ln=True)
pdf.set_font("Arial", size=11)
pdf.multi_cell(0, 10, summary)
pdf.ln(5)
pdf.set_font("Arial", 'B', 12)
pdf.cell(200, 10, txt="Commentaires sociaux:", ln=True)
pdf.set_font("Arial", size=11)
for item in sentiment_data:
pdf.multi_cell(0, 10, f"{item['comment']} (Score: {item['sentiment']:.2f})")
buffer = BytesIO()
pdf.output(buffer)
buffer.seek(0)
return buffer
# --- STREAMLIT APP ---
st.set_page_config(page_title="Ville Durable Dashboard", layout="centered")
st.title("🌍 Ville Durable Dashboard")
city = st.text_input("Entrez le nom d'une ville:", value="Paris")
if st.button("Analyser"):
with st.spinner("Collecte des données..."):
air_data = get_air_quality(city)
comments = fake_social_comments(city)
sentiment_data = analyze_sentiment(comments)
summary = summarize_report(air_data, sentiment_data)
st.subheader("📋 Rapport Résumé")
st.code(summary)
st.subheader("📊 Graphique des sentiments")
generate_sentiment_chart(sentiment_data)
st.subheader("💬 Commentaires sociaux analysés")
for d in sentiment_data:
st.write(f"{d['comment']} (Sentiment: {d['sentiment']:.2f})")
pdf = generate_pdf_report(city, air_data, sentiment_data, summary)
st.download_button(
label="📥 Télécharger le rapport PDF",
data=pdf,
file_name=f"rapport_{city.lower()}.pdf",
mime="application/pdf"
)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment