hd wallpaper, nature wallpaper, thunderstorm

Python 101: Retrieve weather alerts using the NWS API

Posted on December 27, 2022

One of the most common needs and uses of weather information is to stay on top of breaking severe weather events. In a previous post, we explored using the NWS API to retrieve the current forecast for a specific location. Let’s walk through how you would retrieve any active weather alerts for your area.

The NWS API exposes “alerts” endpoints that give us an easy way to query for this information.

One of the endpoints retrieves all of the active alerts for a given state. In this case, we’ll pull all of the alerts for New York state.

https://api.weather.gov/alerts/active?area=NY

As we’ve discussed previously, the JSON output gives us all the details of each alert. A sample alert in the array of alerts looks like this:

{
      "id": "https://api.weather.gov/alerts/urn:oid:2.49.0.1.840.0.37f811d73a521ad46d254ebb95e71cc467280da5.001.1",
      "type": "Feature",
      "geometry": null,
      "properties": {
        "@id": "https://api.weather.gov/alerts/urn:oid:2.49.0.1.840.0.37f811d73a521ad46d254ebb95e71cc467280da5.001.1",
        "@type": "wx:Alert",
        "id": "urn:oid:2.49.0.1.840.0.37f811d73a521ad46d254ebb95e71cc467280da5.001.1",
        "areaDesc": "Jefferson; Lewis",
        "geocode": {
          "SAME": [
            "036045",
            "036049"
          ],
          "UGC": [
            "NYZ007",
            "NYZ008"
          ]
        },
        "affectedZones": [
          "https://api.weather.gov/zones/forecast/NYZ007",
          "https://api.weather.gov/zones/forecast/NYZ008"
        ],
        "references": [
          {
            "@id": "https://api.weather.gov/alerts/urn:oid:2.49.0.1.840.0.2a77c73b10a75081e1fce4c72c41df0ca42568c0.001.1",
            "identifier": "urn:oid:2.49.0.1.840.0.2a77c73b10a75081e1fce4c72c41df0ca42568c0.001.1",
            "sender": "[email protected]",
            "sent": "2022-12-27T03:15:00-05:00"
          }
        ],
        "sent": "2022-12-27T09:35:00-05:00",
        "effective": "2022-12-27T09:35:00-05:00",
        "onset": "2022-12-27T09:35:00-05:00",
        "expires": "2022-12-27T13:00:00-05:00",
        "ends": "2022-12-27T13:00:00-05:00",
        "status": "Actual",
        "messageType": "Update",
        "category": "Met",
        "severity": "Severe",
        "certainty": "Likely",
        "urgency": "Expected",
        "event": "Winter Storm Warning",
        "sender": "[email protected]",
        "senderName": "NWS Buffalo NY",
        "headline": "Winter Storm Warning issued December 27 at 9:35AM EST until December 27 at 1:00PM EST by NWS Buffalo NY",
        "description": "* WHAT...Heavy snow. Additional snow accumulations of 3 to 6\ninches...with the highest amounts south of Watertown near the\nTug Hill plateau.\n\n* WHERE...Jefferson and Lewis counties.\n\n* WHEN...Until 1 PM EST this afternoon.\n\n* IMPACTS...Travel could be very difficult.",
        "instruction": "Widespread accumulating snow will create dangerous travel\nconditions.\n\nSubmit snow reports through our website or social media.",
        "response": "Prepare",
        "parameters": {
          "AWIPSidentifier": [
            "WSWBUF"
          ],
          "WMOidentifier": [
            "WWUS41 KBUF 271435"
          ],
          "NWSheadline": [
            "WINTER STORM WARNING REMAINS IN EFFECT UNTIL 1 PM EST THIS AFTERNOON"
          ],
          "BLOCKCHANNEL": [
            "EAS",
            "NWEM",
            "CMAS"
          ],
          "EAS-ORG": [
            "WXR"
          ],
          "VTEC": [
            "/O.CON.KBUF.WS.W.0009.000000T0000Z-221227T1800Z/"
          ],
          "eventEndingTime": [
            "2022-12-27T18:00:00+00:00"
          ],
          "expiredReferences": [
            "[email protected],urn:oid:2.49.0.1.840.0.b3c01566aee0f251978977107dd52ef38e254898.001.1,2022-12-26T21:54:00-05:00 [email protected],urn:oid:2.49.0.1.840.0.b2aa72db6db6635d978d332b8ca9a9cdfb9fd391.001.1,2022-12-26T13:59:00-05:00 [email protected],urn:oid:2.49.0.1.840.0.9be7a9ed0927b0058460437436dfafe152ac41fd.001.1,2022-12-26T10:27:00-05:00 [email protected],urn:oid:2.49.0.1.840.0.605d3b3c897bb59e37cd441f8276c89ffb38e587.002.1,2022-12-26T06:35:00-05:00 [email protected],urn:oid:2.49.0.1.840.0.b1937a175f828ab14298f6cddca13a88a614b53b.003.1,2022-12-26T03:41:00-05:00 [email protected],urn:oid:2.49.0.1.840.0.6bfea1b11482a4f3d90b8f2972933d803ed8f49a.003.1,2022-12-26T00:32:00-05:00 [email protected],urn:oid:2.49.0.1.840.0.778b7e71548cad483b8c566a95fe7f34460edf05.003.1,2022-12-25T19:02:00-05:00 [email protected],urn:oid:2.49.0.1.840.0.88c4b11d52365d3dd2576c88463ee058980c79d5.004.1,2022-12-25T15:37:00-05:00 [email protected],urn:oid:2.49.0.1.840.0.5755b1a7793644caf7e06298830ca8e0d9a96902.002.1,2022-12-25T12:44:00-05:00 [email protected],urn:oid:2.49.0.1.840.0.5755b1a7793644caf7e06298830ca8e0d9a96902.001.2,2022-12-25T12:44:00-05:00 [email protected],urn:oid:2.49.0.1.840.0.75d8a35b9eb3325cfb71617374a54142cbd71e59.004.1,2022-12-25T05:45:00-05:00 [email protected],urn:oid:2.49.0.1.840.0.2fe3d02c71f828358a8136675bdc11d90ddfd4a2.006.1,2022-12-25T02:35:00-05:00 [email protected],urn:oid:2.49.0.1.840.0.c37086da3a53947f74b0a835abb0232a3ded6416.005.1,2022-12-24T21:12:00-05:00 [email protected],urn:oid:2.49.0.1.840.0.df16e84fcf90e12fdbfdfb3104658a22cff1fe5b.006.1,2022-12-24T15:57:00-05:00 [email protected],urn:oid:2.49.0.1.840.0.db0dc7219b447a6296f6e9d3383ae8e33fcfcd17.005.1,2022-12-24T09:53:00-05:00 [email protected],urn:oid:2.49.0.1.840.0.0c75d1d8bf67f9662207f33125b4d19208350355.007.1,2022-12-24T01:56:00-05:00 [email protected],urn:oid:2.49.0.1.840.0.11908c988dcc26135f9635e8a269827212f6c9d1.006.1,2022-12-23T18:25:00-05:00 [email protected],urn:oid:2.49.0.1.840.0.4d5350bc76f650021e3ae5ef4a07ec4425392ad0.006.1,2022-12-23T09:56:00-05:00 [email protected],urn:oid:2.49.0.1.840.0.d1c595288f87a3ac84e9eb7bccf55213a915897a.005.1,2022-12-23T02:36:00-05:00 [email protected],urn:oid:2.49.0.1.840.0.43d570e6f2c8dc2675731b4b354025174b8c8ce2.005.1,2022-12-22T18:48:00-05:00 [email protected],urn:oid:2.49.0.1.840.0.48d6600db0f0c78b5fc4a07193b054a6125bf94b.005.1,2022-12-22T14:09:00-05:00 [email protected],urn:oid:2.49.0.1.840.0.6360fc9abad5efef43bb5d32ae60b176d44ddd06.004.1,2022-12-22T11:28:00-05:00 [email protected],urn:oid:2.49.0.1.840.0.48d6600db0f0c78b5fc4a07193b054a6125bf94b.001.1,2022-12-22T14:09:00-05:00 [email protected],urn:oid:2.49.0.1.840.0.71eb6ca0b00797506383aa57e7a158bc9ae5e4d3.004.2,2022-12-22T03:54:00-05:00"
          ]
        }
      }
    }

A ton of data can be gleaned from the alert information. What is the alert, when was it issued, when does it expire, what counties does it include, and much more.

Depending on when the data is queried, and the current weather, a state’s worth of data could be very exhaustive. We can limit the data through pagination, but we’ll only pull data for our forecast zone, similar to what we did when we retrieved the forecast.

For this next example, we’ll say we’re looking for alerts for Buffalo, NY. If we refer to the zone maps, we’ll find that Buffalo is in zone “010” in New York, so we’ll modify our API call URL to be:

https://api.weather.gov/alerts/active/zone/NYZ010

This produces a list of alerts specific to that forecast zone. In this case, we’ll see that Buffalo is under a Winter Weather Advisory:

{
      "id": "https://api.weather.gov/alerts/urn:oid:2.49.0.1.840.0.37f811d73a521ad46d254ebb95e71cc467280da5.002.1",
      "type": "Feature",
      "geometry": null,
      "properties": {
        "@id": "https://api.weather.gov/alerts/urn:oid:2.49.0.1.840.0.37f811d73a521ad46d254ebb95e71cc467280da5.002.1",
        "@type": "wx:Alert",
        "id": "urn:oid:2.49.0.1.840.0.37f811d73a521ad46d254ebb95e71cc467280da5.002.1",
        "areaDesc": "Northern Erie; Southern Erie",
        "geocode": {
          "SAME": [
            "036029"
          ],
          "UGC": [
            "NYZ010",
            "NYZ085"
          ]
        },
        "affectedZones": [
          "https://api.weather.gov/zones/forecast/NYZ010",
          "https://api.weather.gov/zones/forecast/NYZ085"
        ],
        "references": [
          {
            "@id": "https://api.weather.gov/alerts/urn:oid:2.49.0.1.840.0.2a77c73b10a75081e1fce4c72c41df0ca42568c0.002.1",
            "identifier": "urn:oid:2.49.0.1.840.0.2a77c73b10a75081e1fce4c72c41df0ca42568c0.002.1",
            "sender": "[email protected]",
            "sent": "2022-12-27T03:15:00-05:00"
          }
        ],
        "sent": "2022-12-27T09:35:00-05:00",
        "effective": "2022-12-27T09:35:00-05:00",
        "onset": "2022-12-27T09:35:00-05:00",
        "expires": "2022-12-27T13:00:00-05:00",
        "ends": "2022-12-27T13:00:00-05:00",
        "status": "Actual",
        "messageType": "Update",
        "category": "Met",
        "severity": "Moderate",
        "certainty": "Likely",
        "urgency": "Expected",
        "event": "Winter Weather Advisory",
        "sender": "[email protected]",
        "senderName": "NWS Buffalo NY",
        "headline": "Winter Weather Advisory issued December 27 at 9:35AM EST until December 27 at 1:00PM EST by NWS Buffalo NY",
        "description": "* WHAT...Lake effect snow. Additional snow accumulations of an\ninch or so in the most persistent lake snows.\n\n* WHERE...Erie county.\n\n* WHEN...Until 1 PM EST this afternoon.\n\n* IMPACTS...Plan on slippery road conditions.",
        "instruction": "If traveling, be prepared for rapidly changing road conditions\nand visibilities.\n\nSubmit snow reports through our website or social media.",
        "response": "Execute",
        "parameters": {
          "AWIPSidentifier": [
            "WSWBUF"
          ],
          "WMOidentifier": [
            "WWUS41 KBUF 271435"
          ],
          "NWSheadline": [
            "WINTER WEATHER ADVISORY REMAINS IN EFFECT UNTIL 1 PM EST THIS AFTERNOON"
          ],
          "BLOCKCHANNEL": [
            "EAS",
            "NWEM",
            "CMAS"
          ],
          "VTEC": [
            "/O.CON.KBUF.WW.Y.0030.000000T0000Z-221227T1800Z/"
          ],
          "eventEndingTime": [
            "2022-12-27T18:00:00+00:00"
          ],
          "expiredReferences": [
            "[email protected],urn:oid:2.49.0.1.840.0.b3c01566aee0f251978977107dd52ef38e254898.002.1,2022-12-26T21:54:00-05:00 [email protected],urn:oid:2.49.0.1.840.0.b2aa72db6db6635d978d332b8ca9a9cdfb9fd391.002.1,2022-12-26T13:59:00-05:00 [email protected],urn:oid:2.49.0.1.840.0.9be7a9ed0927b0058460437436dfafe152ac41fd.002.1,2022-12-26T10:27:00-05:00 [email protected],urn:oid:2.49.0.1.840.0.605d3b3c897bb59e37cd441f8276c89ffb38e587.003.1,2022-12-26T06:35:00-05:00 [email protected],urn:oid:2.49.0.1.840.0.b1937a175f828ab14298f6cddca13a88a614b53b.001.2,2022-12-26T03:41:00-05:00"
          ]
        }
      }
    }

Putting it all together

Let’s build a script that takes some key alert information and prints it out in a readable format, all of the weather alerts for New York.

We’re going to make use of the Requests library in Python. This makes the calls to the API URL and the response back from the server.

import requests

Let’s establish the URL for the API that we’ll use to get the alert information for the state of New York. Check out the documentation on the various calls that can be used. We want alert information for a state, so we’d use this:

URL = 'https://api.weather.gov/alerts/active?area=NY'

Now we’ll make the request to the API and save the response in a variable called “response.”

response = requests.get(URL)

Once we receive the JSON response from the server, hopefully, with the contents of the requested list of alerts, we’ll read the JSON looking for the start of the alerts. Again, the documentation will provide you with the format of the returned JSON. You can also look at the JSON itself and figure out what the format of the data is.

We’re looking for the “features” portion of the JSON return. This will contain an array of alert objects. We will take the JSON response and save that into an (array) object called “alerts.”

alerts = response.json()['features']

Now we’re ready to work with the alert details. We can iterate through the alerts array and print out the alert name and when it expires.

for alert in alerts:
    expireTime = datetime.fromisoformat(alert['properties']['expires'])
    print(f"{alert['properties']['event']} till {expireTime.strftime('%A, %B %d, %Y at %I:%M %p %Z')}")

Final code

Here’s what the whole script looks like when complete:

import requests

URL = 'https://api.weather.gov/alerts/active?area=NY'
response = requests.get(URL)
alerts = response.json()['features']

print(f'There are {len(alerts)} active alerts.')

for alert in alerts:
    expireTime = datetime.fromisoformat(alert['properties']['expires'])
    print(f"{alert['properties']['event']} for {alert['properties']['areaDesc']} till {expireTime.strftime('%A, %B %d, %Y at %I:%M %p %Z')}")

Output

And here’s what it would look like when printed out:

You might find these interesting...

0 0 votes
Article Rating
Subscribe
Notify of
0 Comments
Inline Feedbacks
View all comments