-
Notifications
You must be signed in to change notification settings - Fork 2
/
streamlit_app.py
205 lines (156 loc) · 8.11 KB
/
streamlit_app.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
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
import streamlit as st
import time
import pandas as pd
import seaborn as sns
sns.set()
from datetime import datetime
from PIL import Image # this package is used to put images within streamlit
# Standard plotly imports
import plotly
import plotly.graph_objs as go
from plotly.offline import iplot, init_notebook_mode
import plotly.figure_factory as ff
from plotting_funs import plot_weather_data_plotly
from geoloc_api import get_lat_long_opencage
from weather_api_current import get_weather_data
from weather_api_hist import get_historical_weather_data
# Page setting
st.set_page_config(
page_title="Real-Time Weather Data Dashboard",
page_icon="✅",
layout="wide",
)
# Disable warning on st.pyplot (the config option: deprecation.showPyplotGlobalUse)
st.set_option('deprecation.showPyplotGlobalUse', False)
with open('style.css') as f:
st.markdown(f'<style>{f.read()}</style>', unsafe_allow_html=True)
#%% Web app design
# Title
st.title("Real-time Weather App")
# User input
location = st.text_input("Enter Location:", "Barcelona, Spain")
# Geocode the location
lat, lon = get_lat_long_opencage(location)
coords = str(lat) + "," + str(lon)
# Create a placeholder for the weather info
weather_placeholder = st.empty()
# if input is successful
if coords:
# get data with get request
weather_data = get_weather_data(location)
# Extract data from the API response
timestamp = datetime.strptime(weather_data["location"]["localtime"], "%Y-%m-%d %H:%M")
temperature = weather_data["current"]["temp_c"]
humidity = weather_data["current"]["humidity"]
#####################################################################################
### Display weather data
#####################################################################################
with weather_placeholder.container():
#st.header(f"Weather in {weather_data['location']['name']}, {weather_data['location']['country']}")
# Set background color based on temperature
background_color = '#FFD700' if weather_data['current']['temp_c'] > 10 else '#87CEEB'
st.markdown(f'<style>body{{background-color: {background_color}; margin: 0; padding: 0;}}</style>',
unsafe_allow_html=True)
localtime = weather_data['location']['localtime']
localtime = datetime.strptime(localtime, "%Y-%m-%d %H:%M")
condition = weather_data["current"]["condition"]["text"]
condition_icon = weather_data['current']['condition']['icon']
# container for time, condition and icon
with st.container():
time_col, condition_col, icon_col = st.columns([3, 1, 1])
# Display time information on the left
time_col.subheader(f'{localtime}')
# Display condition info with icon on the right
condition_col.metric("Condition:", f"{condition}")
# Display condition info with icon on the right
icon_col.image(f"https:{condition_icon}", width=100)
#####################################################################################
# 1st ROW - Principal Weather data
a1, a2, a3, a4 = st.columns(4)
a1.metric("Temperature (°C)", f"{weather_data['current']['temp_c']}°C")
a2.metric("Feels Like (°C)", f"{weather_data['current']['feelslike_c']}°C")
a3.metric("Humidity (%)", f"{weather_data['current']['humidity']}%")
a4.metric("Wind (km/h)", f"{weather_data['current']['wind_kph']} km/h")
# put a separator
st.markdown("""---""")
#####################################################################################
# 2nd ROW - Additional Weather data
b1, b2, b3, b4 = st.columns(4)
with b1:
st.subheader("Additional Weather Data")
st.write(f"Temperature: {weather_data['current']['temp_f']}°F")
st.write(f"Pressure: {weather_data['current']['pressure_mb']} mb")
st.write(f"Cloudiness: {weather_data['current']['cloud']}%")
st.write(
f"Visibility: {weather_data['current']['vis_km']} km ({weather_data['current']['vis_miles']} miles)")
st.write(f"UV Index: {weather_data['current']['uv']}")
with b2:
st.subheader("Wind Data")
st.write(f"Wind Speed: {weather_data['current']['wind_kph']} km/h")
st.write(f"Wind Direction: {weather_data['current']['wind_dir']}")
st.write(f"Gust Speed: {weather_data['current']['gust_kph']} km/h")
st.write(f"Gust Speed: {weather_data['current']['gust_mph']} mph")
with b3:
st.subheader("Additional Information")
st.write("Latitude:", lat, "Longitude:", lon)
st.write("Country:", weather_data['location']['country'])
st.write("Region:", weather_data['location']['region'])
st.write("Timezone:", weather_data['location']['tz_id'])
with b4:
st.subheader("Last Updated")
st.write(f"Local Time: {weather_data['location']['localtime']}")
st.write(f"API Last Updated: {weather_data['current']['last_updated']}")
# put a separator
st.markdown("""---""")
#####################################################################################
### Create an historic of weather data to be plotted
#####################################################################################
# Structures to store historic data to be plotted
timestamps, temperatures, humidities = [], [], []
# get historical weather of the previous 7 days
historic_weather_data = get_historical_weather_data(coords)
# Extract data from the API response
for day in historic_weather_data['forecast']['forecastday']:
for hour in day['hour']:
timestamps.append(hour['time'])
temperatures.append(hour['temp_c'])
humidities.append(hour['humidity'])
# other app design idea:
# find a way to make different api calls every t time and store the data in a dataframe
# to be later plotted real time in a chart'''
#####################################################################################
# 3rd ROW - Map and Historic Data
c1, c2 = st.columns(2, gap='large')
# Map
map_data = pd.DataFrame({
'lat': [weather_data['location']['lat']],
'lon': [weather_data['location']['lon']],
})
with c1:
st.map(map_data, zoom=10)
# Historic Data Plot
with c2:
# crate the plot
fig = plot_weather_data_plotly(timestamps, temperatures, humidities)
# display the plot
st.plotly_chart(fig)
# put a separator
st.markdown("""---""")
#####################################################################################
# Additional information
with st.expander("More Information"):
st.write("Historical weather data are available for the previous 7 days only with the free API plan")
st.write("Real-time weather data are available every 15 mins with the free API plan")
st.write("Weather data provided by [WeatherAPI.com](https://www.weatherapi.com/)")
st.write("Geocoding data provided by [OpenCage](https://opencagedata.com/)")
st.write("Map tiles by [OpenStreetMap](https://www.openstreetmap.org/)")
st.write("Plot created with [Plotly](https://plotly.com/)")
st.write("App created with [Streamlit](https://streamlit.io/)")
st.write("Hosting service provided by [Streamlit](https://streamlit.io/)")
st.write("Source code available on [GitHub](https://github.com/andreabragantini/streamlit_weather_realtime)")
st.write("If you like this app, please consider giving it a ⭐ on GitHub.")
st.write("Created by [Andrea Bragantini](https://www.linkedin.com/in/andrea-bragantini-693b50136/)")
# Wait for a specified time before making the next request
time.sleep(2)
else:
st.write("Invalid location. Please enter a valid location.")