Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
94 changes: 62 additions & 32 deletions main.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import datetime
import requests
import string
from flask import Flask, render_template, request, redirect, url_for
from flask import Flask, render_template, request, redirect, url_for , flash
import os
from dotenv import load_dotenv
load_dotenv()
Expand All @@ -14,13 +14,16 @@

app = Flask(__name__)


app.secret_key = os.getenv("FLASK_SECRET_KEY" , "default_secret_key")
# 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))
if not city:
flash("Please enter a city name." , "error")
return redirect(url_for("home"))
return redirect(url_for("get_weather" , city = city))
return render_template("index.html")


Expand All @@ -33,32 +36,62 @@ def get_weather(city):
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()
try:
location_params = {
"q": city_name,
"appid": api_key,
"limit": 3,
}

location_response = requests.get(GEOCODING_API_ENDPOINT, params=location_params)
location_response.raise_for_status()
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:
flash("City not found. Please enter a valid city name." , "error")
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 , timeout=5)
weather_response.raise_for_status()
weather_data = weather_response.json()
# Get five-day weather forecast data
forecast_response = requests.get(OWM_FORECAST_ENDPOINT, weather_params , timeout=5)
forecast_data = forecast_response.json()

except requests.exceptions.Timeout:
flash("The request to the weather service timed out. Please try again later." , "error")
return redirect(url_for("home"))

except requests.exceptions.ConnectionError:
flash("Network error occurred while trying to connect to the weather service. Please check your internet connection and try again." , "error")
return redirect(url_for("home"))

except requests.exceptions.HTTPError as http_err:
if http_err.response.status_code == 404:
flash("City not found. Please enter a valid city name." , "error")
return redirect(url_for("error"))
elif http_err.response.status_code == 401:
flash("Invalid API key. Please check your API key and try again." , "error")
return redirect(url_for("home"))
else:
flash(f"An error occurred: {http_err}" , "error")
return redirect(url_for("home"))

except Exception as e:
flash(f"An unexpected error occurred: {e}" , "error")
return redirect(url_for("home"))


# Get current weather data
current_temp = round(weather_data['main']['temp'])
Expand All @@ -67,9 +100,6 @@ def get_weather(city):
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']]
Expand Down
13 changes: 13 additions & 0 deletions templates/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,19 @@ <h1> Weather </h1>
<div class="background">
<img src="/static/assets/weather-home-background.jpg" alt="" class="desktop-background">
</div>
{% with messages = get_flashed_messages(with_categories=true) %}
{% if messages %}
{% for category, message in messages %}
<div class="alert-{{ category }}">
{{ message }}
</div>
{% endfor %}
{% endif %}
{% endwith %}

<form action="/" method="POST">
...
</form>
<div class="search-bar">
<img class="search-icon" src="/static/assets/search.png" alt="">
<form class="search" action="" autocomplete="off" method="post">
Expand Down