The National Weather Service(NWS) API, provided by the U.S. National Weather Service, is a free public data API that offers a wide range of weather information. One of its key benefits is that it can be used without an API key, making it easy to access. In this post, we will explore how to use the NWS API with Python and examine the returned results.
Introduction to the National Weather Service(NWS) API
The NWS API has several endpoints that provide various weather data.
What is an Endpoint?
An API endpoint is a digital location where an API receives requests for a specific resource on a server. In the context of an API, an endpoint typically refers to a URL (Uniform Resource Locator) that specifies the resource location on a server.
Each endpoint is designed to access specific types of weather information:
- /points: Location-based weather data
- /gridpoints: Grid-based weather data
- /alerts: Weather alerts and notifications
- /stations: Weather observation station data
We will provide a more detailed explanation of the various endpoints at the end of this post.
API Key Issuance
The NWS API is free to use and does not require an API key, making it very easy to use.
API Request and Response Format
The NWS API provides data via HTTP requests, and responses are primarily returned in JSON format.
Basic Request Example
Fetching Current Weather Data Based on Location
/point
NWS API operates based on location(latitude and longitude). Here, we will look at an example of fetching the current weather data for Dallas, Texas(latitude: 32.7767 N, longitude: -96.7970 W).
First, add the latitude and longitude to the endpoint URL and use requests.get
to request and retrieve the data. The data is returned in JSON format, including metadata, identifiers, geographical coordinates, and weather information links. Next, parse the URL for the observation station and use that URL to request the current weather information. Parse and format the current weather information and print it.
import requests # Latitude and longitude of Dallas latitude = 32.7767 longitude = -96.7970 # NWS API endpoint points_url = f"https://api.weather.gov/points/{latitude},{longitude}" # Fetch location information response = requests.get(points_url) data = response.json() # Extract observation station URL observation_stations_url = data['properties']['observationStations'] # Fetch observation station data stations_response = requests.get(observation_stations_url) stations_data = stations_response.json() stations = stations_data['observationStations'] # Fetch data from the first observation station station_url = stations[0] # Fetch current weather data current_weather_url = f"{station_url}/observations/latest" current_weather_response = requests.get(current_weather_url) current_weather_data = current_weather_response.json() # Print current weather information current_observation = current_weather_data['properties'] print("Current Weather") print(f"Temperature: {current_observation['temperature']['value']}°C") print(f"Humidity: {current_observation['relativeHumidity']['value']}%") print(f"Wind Speed: {current_observation['windSpeed']['value']} m/s") print(f"Wind Direction: {current_observation['windDirection']['value']}°") print(f"Weather Description: {current_observation['textDescription']}")
Output
Current Weather Temperature: 30°C Humidity: 77.340048483797% Wind Speed: None m/s Wind Direction: None° Weather Description: Partly Cloudy
Fetching Weather Alerts and Notifications
In this example, we fetch alerts and notifications by first getting the alert URL via the /points
endpoint and then fetching the alert data via the /alerts
endpoint.
import requests # Latitude and longitude of Oklahoma City latitude = 35.4676 longitude = -97.5164 # NWS API endpoint points_url = f"https://api.weather.gov/points/{latitude},{longitude}" # Fetch location information response = requests.get(points_url) data = response.json() # Extract alert URL forecast_zone_url = data['properties']['forecastZone'] # Fetch alert data alerts_url = f"https://api.weather.gov/alerts/active?zone={forecast_zone_url.split('/')[-1]}" alerts_response = requests.get(alerts_url) alerts_data = alerts_response.json() # Print alert information alerts = alerts_data['features'] if alerts: print("Current Weather Alerts and Notifications") for alert in alerts: properties = alert['properties'] print(f"Title: {properties['headline']}") print(f"Event: {properties['event']}") print(f"Description: {properties['description']}") print(f"Instructions: {properties['instruction']}") print("-" * 40) else: print("There are no active weather alerts and notifications.")
Output
Current Weather Alerts and Notifications Title: Flood Watch issued June 4 at 9:58PM CDT until June 5 at 7:00AM CDT by NWS Norman OK Event: Flood Watch Description: * WHAT...Flooding caused by excessive rainfall continues to be possible. * WHERE...Portions of central, east central, southeast, and southern Oklahoma, including the following counties, in central Oklahoma, Cleveland, Grady, Lincoln, McClain, Oklahoma and Pottawatomie. In east central Oklahoma, Pontotoc and Seminole. In southeast Oklahoma, Atoka, Bryan, Coal, Hughes, Johnston and Marshall. In southern Oklahoma, Garvin and Murray. * WHEN...Until 7 AM CDT Wednesday. * IMPACTS...Excessive runoff may result in flooding of rivers, creeks, streams, and other low-lying and flood-prone locations. Area creeks and streams are running high and could flood with more heavy rain. * ADDITIONAL DETAILS... - A complex of storms is expected to bring heavy rain to areas already saturated from previous rains. - http://www.weather.gov/safety/flood Instructions: You should monitor later forecasts and be alert for possible Flood Warnings. Those living in areas prone to flooding should be prepared to take action should flooding develop. ----------------------------------------
Detailed Description of Endpoints
/points
Provides weather information for a specific location(latitude and longitude).
- Example:
https://api.weather.gov/points/{latitude},{longitude}
- Returns: Forecast and grid point URLs, observation station information, etc.
/gridpoints
Provides detailed weather information for a specific grid point.
- Example:
https://api.weather.gov/gridpoints/{wfo}/{x},{y}
- Returns: Weather forecast data for a specific grid point.
/alerts
Provides weather alerts and notifications for a specific area.
- Example:
https://api.weather.gov/alerts/active?area={state}
- Returns: Active weather alerts and notifications.
/stations
Provides data from weather observation stations.
- Example:
https://api.weather.gov/stations/{stationId}/observations/latest
- Returns: Latest observation data from a specific station.
Advanced Example
Visualizing 7-Day Forecast Data
Here is an example of fetching and visualizing the 7-day forecast data for Dallas(latitude: 32.7767 N, longitude: -96.7970 W). Use the code below to create a more visually appealing forecast chart.
import requests import pandas as pd import matplotlib.pyplot as plt # Latitude and longitude of Dallas latitude = 32.7767 longitude = -96.7970 # NWS API endpoint points_url = f"https://api.weather.gov/points/{latitude},{longitude}" response = requests.get(points_url) data = response.json() # Extract forecast URL forecast_url = data['properties']['forecast'] # Fetch forecast data forecast_response = requests.get(forecast_url) forecast_data = forecast_response.json() # Extract high/low temperature data by date periods = forecast_data['properties']['periods'] dates = [period['startTime'][:10] for period in periods if period['isDaytime']] highs = [period['temperature'] for period in periods if period['isDaytime']] lows = [period['temperature'] for period in periods if not period['isDaytime']] # Create a DataFrame df = pd.DataFrame({ 'Date': dates[:len(lows)], 'High': highs[:len(lows)], 'Low': lows }) # Visualize the data plt.figure(figsize=(10, 5)) plt.plot(df['Date'], df['High'], label='High Temp (F)', marker='o') plt.plot(df['Date'], df['Low'], label='Low Temp (F)', marker='o') plt.fill_between(df['Date'], df['High'], df['Low'], color='grey', alpha=0.2) plt.xlabel('Date') plt.ylabel('Temperature (°F)') plt.title('7-Day Temperature Forecast for Dallas, TX') plt.xticks(rotation=45) plt.legend() plt.grid(True) plt.tight_layout() plt.show()
Output
Error Handling and Exception Management
When using the NWS API, various errors can occur, so it is important to handle potential exceptions.
import requests import json # Latitude and longitude of Dallas latitude = 32.7767 longitude = -96.7970 # NWS API endpoint points_url = f"https://api.weather.gov/points/{latitude},{longitude}" try: # Fetch location information response = requests.get(points_url) response.raise_for_status() data = response.json() # Extract forecast URL from location information forecast_url = data['properties']['forecast'] # Fetch forecast data forecast_response = requests.get(forecast_url) forecast_response.raise_for_status() forecast_data = forecast_response.json() # Print current weather information forecast_data_string = json.dumps(forecast_data, indent=4, sort_keys=True) print(forecast_data_string) except requests.exceptions.RequestException as e: print(f"HTTP Request Error: {e}") except KeyError as e: print(f"Data Processing Error: {e}") except Exception as e: print(f"Other Error: {e}")
Conclusion
Using the National Weather Service(NWS) API, you can fetch various real-time weather data across the United States for free, without the need for a separate API key, making it very convenient to use.
The NWS API provides location-based weather information, alerts, and observation station data through various endpoints. With simple HTTP requests, you can retrieve data in JSON format, making it easy to process and further analyze the data.