Weather Widget
Weather Widget
App Script 👇
from flask import Flask, request, render_template_string, flash
import requests
app = Flask(__name__)
app.secret_key = 'your_secret_key_here'
# Your current OpenWeatherMap API key
API_KEY = ''
def get_weather(city):
"""Fetch weather data from OpenWeatherMap API."""
url = f'http://api.openweathermap.org/data/2.5/weather?q={city}&appid={API_KEY}&units=metric'
try:
response = requests.get(url, timeout=5)
print(f"API URL: {url}") # Debug: See the exact URL
print(f"API Response: {response.status_code} - {response.text}") # Debug: Raw response
if response.status_code == 200:
return response.json()
elif response.status_code == 401:
flash("Invalid API key. Waiting for activation or check your account!", "error")
elif response.status_code == 404:
flash(f"City '{city}' not found. Try again!", "error")
return None
except requests.RequestException as e:
flash(f"Network error: {str(e)}. Check your connection!", "error")
return None
@app.route('/', methods=['GET', 'POST'])
def weather_widget():
weather_data = None
city = None
if request.method == 'POST':
city = request.form.get('city')
if city:
weather_data = get_weather(city)
if weather_data:
flash(f"Weather for {weather_data['name']} loaded!", "success")
template = '''
<!DOCTYPE html>
<html>
<head>
<title>Weather Widget</title>
<style>
body { background: linear-gradient(135deg, #2c3e50, #3498db);
color: #ecf0f1; font-family: Arial, sans-serif;
display: flex; flex-direction: column; align-items: center;
min-height: 100vh; margin: 0; }
.container { text-align: center; margin-top: 50px; }
.weather-box { background: rgba(52, 73, 94, 0.9); padding: 25px;
border-radius: 15px; box-shadow: 0 6px 20px rgba(0,0,0,0.4);
width: 320px; margin: 20px 0; opacity: 0;
transform: translateY(20px); transition: all 0.5s ease-out; }
.weather-box.visible { opacity: 1; transform: translateY(0); }
.weather-box img { vertical-align: middle; filter: drop-shadow(0 2px 4px rgba(0,0,0,0.3)); }
.form { margin: 20px 0; }
input[type="text"] { padding: 12px; font-size: 16px; width: 220px;
border: none; border-radius: 8px; box-shadow: inset 0 2px 4px rgba(0,0,0,0.1); }
button { padding: 12px 24px; font-size: 16px; background: #e67e22;
color: #fff; border: none; border-radius: 8px; cursor: pointer;
box-shadow: 0 4px #d35400; transition: all 0.2s; }
button:hover { background: #f39c12; }
button:active { transform: translateY(4px); box-shadow: none; }
.message { padding: 12px; border-radius: 8px; margin: 10px 0;
font-weight: bold; width: 320px; text-align: center;
box-shadow: 0 2px 10px rgba(0,0,0,0.2); }
.success { background: #27ae60; }
.error { background: #c0392b; }
</style>
</head>
<body>
<div class="container">
<h1>Weather Widget</h1>
<form method="post" class="form">
<input type="text" name="city" placeholder="Enter city name" required>
<button type="submit">Get Weather</button>
</form>
{% if weather_data %}
<div class="weather-box" id="weatherBox">
<h2>{{ weather_data.name }}</h2>
<p>{{ weather_data.main.temp }}°C</p>
<p>{{ weather_data.weather[0].description|capitalize }}</p>
<img src="http://openweathermap.org/img/wn/{{ weather_data.weather[0].icon }}@2x.png"
alt="Weather Icon" height="100">
</div>
{% endif %}
{% with messages = get_flashed_messages(with_categories=true) %}
{% if messages %}
{% for category, message in messages %}
<div class="message {{ category }}">{{ message }}</div>
{% endfor %}
{% endif %}
{% endwith %}
</div>
<script>
document.addEventListener('DOMContentLoaded', () => {
const weatherBox = document.getElementById('weatherBox');
if (weatherBox) {
setTimeout(() => weatherBox.classList.add('visible'), 100);
}
});
</script>
</body>
</html>
'''
return render_template_string(template, weather_data=weather_data)
if __name__ == '__main__':
app.run(debug=True)