Scraping the Weather: Build a Python CLI for Real-Time Forecasts
As developers, we often need quick access to live data—like weather—without opening a browser. In this guide, we’ll build a command-line interface (CLI) using Python that fetches real-time weather forecasts using the OpenWeatherMap API. This tool is ideal for terminal users, automation scripts, or for integrating small utilities into larger projects.
1. Setting Up the Environment and OpenWeatherMap API Key
To begin, you’ll need:
- Python 3 installed
- An API key from OpenWeatherMap (free tier available)
- The
requests
library for making HTTP requests
First, install the required library:
pip install requests
Next, store your API key in an environment variable so you don’t hard-code it:
# Bash example:
export OPENWEATHER_API_KEY="your_api_key_here"
2. Creating the Basic CLI with argparse
We’ll use Python’s built-in argparse
to accept city names as CLI arguments. This makes the tool flexible to user input and scriptable.
import argparse
def parse_args():
parser = argparse.ArgumentParser(description="Get current weather information for a city.")
parser.add_argument("city", help="City name (e.g., London, Tokyo, New York)")
return parser.parse_args()
With this setup, we can now run:
python weather_cli.py Paris
3. Fetching Real-Time Data from OpenWeatherMap API
Now, let’s integrate the API. The OpenWeatherMap current weather endpoint is:
https://api.openweathermap.org/data/2.5/weather?q={city}&appid={API_key}&units=metric
Here’s how we make the request and handle basic errors:
import os
import requests
def get_weather(city):
api_key = os.getenv("OPENWEATHER_API_KEY")
if not api_key:
raise EnvironmentError("OPENWEATHER_API_KEY not set.")
url = f"https://api.openweathermap.org/data/2.5/weather?q={city}&appid={api_key}&units=metric"
resp = requests.get(url)
if resp.status_code != 200:
raise Exception(f"API request failed: {resp.status_code} - {resp.json().get('message')}")
return resp.json()
This function returns a parsed JSON object containing temperature, conditions, wind speed, and more.
4. Presenting Weather Data Nicely in the Terminal
Let’s extract and format the relevant information for user-friendly terminal output:
def display_weather(data):
city = data["name"]
country = data["sys"]["country"]
weather = data["weather"][0]["description"].capitalize()
temp = data["main"]["temp"]
humidity = data["main"]["humidity"]
wind_speed = data["wind"]["speed"]
print(f"\nWeather in {city}, {country}:")
print(f" Condition: {weather}")
print(f" Temperature: {temp}°C")
print(f" Humidity: {humidity}%")
print(f" Wind Speed: {wind_speed} m/s\n")
This makes reading the output easier, especially when integrated into scripts or pipelines.
5. Wrapping It All Together
Putting the modules together, here’s a complete runnable script:
import argparse
import requests
import os
def parse_args():
parser = argparse.ArgumentParser(description="Get current weather info for a city.")
parser.add_argument("city", help="City name (e.g., Helsinki, Tokyo)")
return parser.parse_args()
def get_weather(city):
api_key = os.getenv("OPENWEATHER_API_KEY")
if not api_key:
raise EnvironmentError("OPENWEATHER_API_KEY not set.")
url = f"https://api.openweathermap.org/data/2.5/weather?q={city}&appid={api_key}&units=metric"
resp = requests.get(url)
if resp.status_code != 200:
raise Exception(f"API Error: {resp.status_code} - {resp.json().get('message')}")
return resp.json()
def display_weather(data):
city = data["name"]
country = data["sys"]["country"]
weather = data["weather"][0]["description"].capitalize()
temp = data["main"]["temp"]
humidity = data["main"]["humidity"]
wind_speed = data["wind"]["speed"]
print(f"\nWeather in {city}, {country}:")
print(f" Condition: {weather}")
print(f" Temperature: {temp}°C")
print(f" Humidity: {humidity}%")
print(f" Wind Speed: {wind_speed} m/s\n")
def main():
args = parse_args()
data = get_weather(args.city)
display_weather(data)
if __name__ == '__main__':
main()
6. Bonus: Tips and Considerations
- Rate limits: Free API plans limit requests per minute. Avoid spamming the API.
- Error handling: Consider catching specific errors (e.g., connection errors).
- Caching: For frequent lookups, consider using a 10-minute cache to reduce API use.
- Extendability: This CLI can be expanded with forecasts, multiple locations, or background weather logging.
Now you have a lightweight Python CLI that brings weather data directly into your terminal, boosting productivity and demonstrating API integration skills.
Happy hacking!
Useful links: