In today’s blog, we’ll dive into creating a dynamic weather widget using Python’s Dash framework. This widget will fetch live weather data and display it alongside engaging animations, providing a visually appealing and informative user experience.
![](https://blog.toolfe.com/wp-content/uploads/2024/07/Screenshot-2024-07-11-194726-1024x544.png)
Prerequisites
Before we begin, make sure you have Python installed on your system. You’ll also need to install Dash and other necessary libraries using pip:
pip install dash dash-bootstrap-components requests dash-extensions dash-leaflet
Setting Up the Project
![](https://blog.toolfe.com/wp-content/uploads/2024/07/Screenshot-2024-07-11-201358.png)
Let’s start by importing the required libraries and setting up our Dash application.
import dash
import dash_bootstrap_components as dbc from dash import html, dcc import requests from dash.dependencies import Input, Output from dash_extensions import Lottie # For animations import dash_leaflet as dl # For the map
Next, initialize the Dash app and include Bootstrap CSS for styling:
app = dash.Dash(__name__, external_stylesheets=[dbc.themes.BOOTSTRAP])
Fetching Live Weather Data
To fetch live weather data, we’ll use an API provided by Open Meteo:
def get_weather():
url = "https://api.open-meteo.com/v1/forecast"
params = {"latitude": 13.0827, "longitude": 80.2707, "current_weather": True}
response = requests.get(url, params=params)
weather_data = response.json()
if "current_weather" in weather_data:
current_weather = weather_data["current_weather"]
temperature = current_weather["temperature"]
windspeed = current_weather["windspeed"]
winddirection = current_weather["winddirection"]
weather_code = current_weather["weathercode"]
weather_info = {
"Temperature": f"{temperature}°C",
"Windspeed": f"{windspeed} km/h",
"Winddirection": f"{winddirection}°",
"Weathercode": weather_code,
}
return weather_info
else:
return None
Building the User Interface
Now, let’s construct the layout of our Dash application. We’ll use Bootstrap components for structuring and styling our weather widget
.app.layout = html.Div(
[ html.Script( src="https://unpkg.com/@dotlottie/player-component@latest/dist/dotlottie-player.mjs",
type="module",
),
dbc.Container(
[
dbc.Row(
dbc.Col(
html.H1("Weather Widget", className="text-center my-4"),
width=12,
),
justify="center",
),
dbc.Row(
[
# Temperature card
dbc.Col(
dbc.Card(
[
dbc.CardHeader("Temperature"),
dbc.CardBody(
[
html.Div(
Lottie(
options=dict(
loop=True, autoplay=True
),
width="50%",
height="50%",
url=weather_icons["temperature"],
),
),
html.Div(
id="temperature", className="value"
),
]
),
],
className="card mb-4",
),
width=3,
),
# Windspeed card
dbc.Col(
dbc.Card(
[
dbc.CardHeader("Windspeed"),
dbc.CardBody(
[
html.Div(
Lottie(
options=dict(
loop=True, autoplay=True
),
width="50%",
height="50%",
url=weather_icons["windspeed"],
),
),
html.Div(id="windspeed", className="value"),
]
),
],
className="card mb-4",
),
width=3,
),
# Winddirection card
dbc.Col(
dbc.Card(
[
dbc.CardHeader("Winddirection"),
dbc.CardBody(
[
html.Div(
Lottie(
options=dict(
loop=True, autoplay=True
),
width="50%",
height="50%",
url=weather_icons["winddirection"],
),
),
html.Div(
id="winddirection", className="value"
),
]
),
],
className="card mb-4",
),
width=3,
),
# Weathercode and Map card
dbc.Col(
dbc.Card(
[
dbc.CardHeader("Weathercode and Location"),
dbc.CardBody(
[
html.Div(
Lottie(
options=dict(
loop=True, autoplay=True
),
width="50%",
height="50%",
url=weather_icons["weathercode"],
),
),
html.Div(
id="weathercode", className="value"
),
dl.Map(
style={
"width": "100%",
"height": "300px",
},
center=[13.0827, 80.2707],
zoom=10,
children=[
dl.TileLayer(),
dl.Marker(
position=[13.0827, 80.2707],
children=[
dl.Tooltip(
"Chennai, India"
),
dl.Popup(
[
html.H1("Chennai"),
html.P(
"Weather data location."
),
]
),
],
),
],
),
]
),
],
className="card mb-4",
),
width=3,
),
],
justify="center",
),
dcc.Interval(
id="interval-component", interval=60000, n_intervals=0
), # Update every 60 seconds
],
fluid=True,
className="bg-dark text-white", # Dark mode styling
),
],
className="full-page",
)
Live Updates with Callbacks:
To ensure the weather information updates dynamically, we’ll set up a callback function that updates the data every minute (dcc.Interval).
@app.callback(
[
Output("temperature", "children"),
Output("windspeed", "children"),
Output("winddirection", "children"),
Output("weathercode", "children"),
],
Input("interval-component", "n_intervals"),
)
def update_weather(n):
weather_info = get_weather()
if weather_info is None:
return ["Data not available!"] * 4
return [
weather_info["Temperature"],
weather_info["Windspeed"],
weather_info["Winddirection"],
weather_info["Weathercode"],
]
Styling with CSS
Lastly, we’ll add custom CSS to style our application, ensuring it looks sleek and professional.
body {
margin: 0;
padding: 0;
height: 100%;
background: url('https://lottie.host/embed/710935a8-5df6-4baf-8461-b9dbf1cc35e0/Bw1LlmZoFA.json') no-repeat center center fixed;
background-color: #181818;
color: white;
}
.full-page {
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
height: 100vh;
}
.card {
background-color: #282828;
border: none;
color: white;
}
.card-header {
background-color: #282828;
border-bottom: 1px solid #444;
}
.card-body {
display: flex;
flex-direction: column;
align-items: center;
}
.value {
font-size: 1.5rem;
margin-top: 1rem;
}
.bg-dark {
background-color: #181818 !important;
}
Conclusion
In this blog, we’ve walked through the process of creating a weather widget using Dash and Python. By leveraging APIs for weather data and integrating dynamic updates with Dash’s callback functions, we’ve created a responsive and visually appealing application. Feel free to customize the widget further or explore additional features to enhance its functionality!
Chakilam Satya Lohit
Customer Success Manager
Toolfe – IT & Process Automation