-
Notifications
You must be signed in to change notification settings - Fork 3
/
Copy pathmain.py
97 lines (78 loc) · 3.61 KB
/
main.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
import datetime
import requests
import string
from flask import Flask, render_template, request, redirect, url_for
import os
from dotenv import load_dotenv
load_dotenv()
OWM_ENDPOINT = "https://api.openweathermap.org/data/2.5/weather"
OWM_FORECAST_ENDPOINT = "https://api.openweathermap.org/data/2.5/forecast"
GEOCODING_API_ENDPOINT = "http://api.openweathermap.org/geo/1.0/direct"
api_key = os.getenv("OWM_API_KEY")
# api_key = os.environ.get("OWM_API_KEY")
app = Flask(__name__)
# Display home page and get city name entered into search form
@app.route("/", methods=["GET", "POST"])
def home():
if request.method == "POST":
city = request.form.get("search")
return redirect(url_for("get_weather", city=city))
return render_template("index.html")
# Display weather forecast for specific city using data from OpenWeather API
@app.route("/<city>", methods=["GET", "POST"])
def get_weather(city):
# Format city name and get current date to display on page
city_name = string.capwords(city)
today = datetime.datetime.now()
current_date = today.strftime("%A, %B %d")
# Get latitude and longitude for city
location_params = {
"q": city_name,
"appid": api_key,
"limit": 3,
}
location_response = requests.get(GEOCODING_API_ENDPOINT, params=location_params)
location_data = location_response.json()
# Prevent IndexError if user entered a city name with no coordinates by redirecting to error page
if not location_data:
return redirect(url_for("error"))
else:
lat = location_data[0]['lat']
lon = location_data[0]['lon']
# Get OpenWeather API data
weather_params = {
"lat": lat,
"lon": lon,
"appid": api_key,
"units": "metric",
}
weather_response = requests.get(OWM_ENDPOINT, weather_params)
weather_response.raise_for_status()
weather_data = weather_response.json()
# Get current weather data
current_temp = round(weather_data['main']['temp'])
current_weather = weather_data['weather'][0]['main']
min_temp = round(weather_data['main']['temp_min'])
max_temp = round(weather_data['main']['temp_max'])
wind_speed = weather_data['wind']['speed']
# Get five-day weather forecast data
forecast_response = requests.get(OWM_FORECAST_ENDPOINT, weather_params)
forecast_data = forecast_response.json()
# Make lists of temperature and weather description data to show user
five_day_temp_list = [round(item['main']['temp']) for item in forecast_data['list'] if '12:00:00' in item['dt_txt']]
five_day_weather_list = [item['weather'][0]['main'] for item in forecast_data['list']
if '12:00:00' in item['dt_txt']]
# Get next four weekdays to show user alongside weather data
five_day_unformatted = [today, today + datetime.timedelta(days=1), today + datetime.timedelta(days=2),
today + datetime.timedelta(days=3), today + datetime.timedelta(days=4)]
five_day_dates_list = [date.strftime("%a") for date in five_day_unformatted]
return render_template("city.html", city_name=city_name, current_date=current_date, current_temp=current_temp,
current_weather=current_weather, min_temp=min_temp, max_temp=max_temp, wind_speed=wind_speed,
five_day_temp_list=five_day_temp_list, five_day_weather_list=five_day_weather_list,
five_day_dates_list=five_day_dates_list)
# Display error page for invalid input
@app.route("/error")
def error():
return render_template("error.html")
if __name__ == "__main__":
app.run(debug=True)