This notebook demonstrates how to authenticate with the Spire Weather API and make your first requests.
import os
import requests
from dotenv import load_dotenv
# Load environment variables from .env file if present
load_dotenv()Setting Up Your API Key¶
Never commit API keys to version control!
Store your API key in an environment variable or .env file:
export SPIRE_API_KEY="your-api-key-here"Or create a .env file:
SPIRE_API_KEY=your-api-key-here# Get API key from environment
API_KEY = os.environ.get('SPIRE_API_KEY')
if not API_KEY:
raise ValueError(
"SPIRE_API_KEY environment variable not set. "
"Please set it before running this notebook."
)
print("API key loaded successfully!")API Configuration¶
# Base URL for all API requests
BASE_URL = 'https://api.wx.spire.com'
# Headers for authentication
HEADERS = {
'spire-api-key': API_KEY
}Helper Function¶
Let’s create a helper function to make API requests:
def spire_request(endpoint, params=None, method='GET', json_data=None):
"""
Make a request to the Spire Weather API.
Parameters
----------
endpoint : str
API endpoint (e.g., '/forecast/point')
params : dict, optional
Query parameters
method : str, optional
HTTP method (GET or POST)
json_data : dict, optional
JSON body for POST requests
Returns
-------
dict
JSON response from the API
"""
url = f"{BASE_URL}{endpoint}"
if method == 'GET':
response = requests.get(url, headers=HEADERS, params=params)
elif method == 'POST':
response = requests.post(url, headers=HEADERS, params=params, json=json_data)
else:
raise ValueError(f"Unsupported method: {method}")
# Check for errors
response.raise_for_status()
return response.json()Test API Connection¶
Let’s verify the API connection by requesting a point forecast:
# Test location: Boulder, Colorado
test_params = {
'lat': 40.0,
'lon': -105.0,
'bundles': 'basic'
}
try:
response = spire_request('/forecast/point', params=test_params)
print("Connection successful!")
print(f"Forecast product: {response['meta'].get('forecast', 'N/A')}")
print(f"Unit system: {response['meta'].get('unit_system', 'N/A')}")
print(f"Number of forecast times: {len(response['data'])}")
except requests.exceptions.HTTPError as e:
print(f"API Error: {e}")
print(f"Response: {e.response.text}")View Sample Data¶
# Look at the first forecast record
if response and response.get('data'):
first_record = response['data'][0]
print("Location:")
print(f" Lat: {first_record['location']['coordinates']['lat']}")
print(f" Lon: {first_record['location']['coordinates']['lon']}")
print()
print("Times:")
print(f" Issuance: {first_record['times']['issuance_time']}")
print(f" Valid: {first_record['times']['valid_time']}")
print()
print("Values:")
for key, value in first_record['values'].items():
print(f" {key}: {value}")Check Available Files¶
# List available forecast files
files_response = spire_request('/forecast/file', params={'bundles': 'basic'})
print(f"Available files: {files_response['meta']['count']}")
print()
print("First 5 files:")
for f in files_response['files'][:5]:
print(f" {f}")Error Handling Example¶
# Example: Handle invalid parameters gracefully
try:
bad_params = {
'lat': 999, # Invalid latitude
'lon': -105.0
}
spire_request('/forecast/point', params=bad_params)
except requests.exceptions.HTTPError as e:
print(f"Expected error for invalid latitude:")
print(f"Status code: {e.response.status_code}")
print(f"Response: {e.response.text}")Next Steps¶
Now that you’re authenticated, continue with:
Point Forecasts - Working with point forecast data
File Downloads - Downloading GRIB2 files
Route Forecasts - Weather along routes
Data Visualization - Visualizing weather data