Degree Days

Degree Days

Weather Data for Energy Professionals

Weather Underground

Python Client Library for Degree Days.net API

The Python client library is well tested and ready for production use. It's not yet at version 1.0 because we might still make breaking changes in future updates... But the underlying XML API is stable, so, if you integrate with the current version of the client library now, it should continue to work fine in the future. If any future client-library updates aren't simple drop-in replacements, the changes required to update are likely to be very small. So don't let the sub-1.0 version number put you off using this client library today.

The client library is available from PyPI at http://pypi.python.org/pypi/degreedays. You can install it with pip install degreedays or just download the source and unpack it yourself.

Quick-start guide

You'll need:

Here's a simple example showing how to fetch the latest 12 months of 65F-base-temperature heating degree days from an automatically-selected weather station near Times Square, New York (US zip code 10036). The HDD figures are output to the command line:

from degreedays.api import DegreeDaysApi, AccountKey, SecurityKey
from degreedays.api.data import DataSpec, Calculation, Temperature, \
    DatedBreakdown, Period, Location, DataSpecs, LocationDataRequest

api = DegreeDaysApi.fromKeys(
        AccountKey(yourStringAccountKey),
        SecurityKey(yourStringSecurityKey))

hddSpec = DataSpec.dated(
        Calculation.heatingDegreeDays(Temperature.fahrenheit(65)),
        DatedBreakdown.monthly(Period.latestValues(12)))

request = LocationDataRequest(
        Location.postalCode('10036', 'US'),
        DataSpecs(hddSpec))

response = api.dataApi.getLocationData(request)

hddData = response.dataSets[hddSpec]

for v in hddData.values:
    print('%s: %g' % (v.firstDay, v.value))

Just swap in your access keys (account key and security key) and the example code above should work right away.

But bear in mind that this example is just a starting point...

The LocationDataRequest is highly configurable:

There are multiple ways to specify all the various components of the LocationDataRequest:

# The Location can be a station ID, or a "geographic location" for which the API
# will select the best weather station to use automatically:
Location.stationId('EGLL')
Location.longLat(degreedays.geo.LongLat(-135.23127, 43.92135))
Location.postalCode('10036', 'US')

# Calculation:
Calculation.heatingDegreeDays(Temperature.fahrenheit(65))
Calculation.coolingDegreeDays(Temperature.celsius(21.5))

# Period of coverage:
Period.latestValues(12)
Period.dayRange(degreedays.time.DayRange(
    datetime.date(2012, 1, 1), datetime.date(2012, 12, 31)))

# Breakdown (using a period like those specified above):
DatedBreakdown.daily(period)
DatedBreakdown.weekly(period, firstDayOfWeek=degreedays.time.DayOfWeek.MONDAY)
DatedBreakdown.monthly(period)
DatedBreakdown.yearly(period)
AverageBreakdown.fullYears(period)

# DataSpecs (using DataSpec objects like the one specified in the first code sample on this page):
DataSpecs(hddSpec) # HDD only (with only one base temperature and breakdown)
DataSpecs(hddSpec, cddSpec) # HDD and CDD (assuming you've defined cddSpec)
DataSpecs(listOfUpTo100DataSpecObjects) # e.g. HDD & CDD with a range of base temperatures or breakdowns

The LocationDataResponse contains more than just data:

It also contains information about the weather station(s) used to generate the returned data. For example, if you request data from a geographic location initially, you might want to use the station ID to fetch updates later:

print(response.stationId)

Error handling

Error handling would be important for production code:

Local input validation

The Python client library tries its best to fail fast on invalid input. We'd rather give you a ValueError immediately than use up your rate limit with invalid API requests that are destined to fail.

This is mainly relevant if you are dealing with user input, particularly for:

All the relevant methods will throw a ValueError (or subclass) if they are passed an ID, code, or key that is clearly invalid. If you are dealing with user input, you might want to catch those exceptions explicitly as a means of validation.

Failures in remote calls (DegreeDaysApiError)

All the exceptions that can arise from a remote call to the API servers extend from degreedays.api.DegreeDaysApiError.

The methods that make a remote call to the API servers are accessible through degreedays.api.DegreeDaysApi. At present the only such method is DataApi.getLocationData(LocationDataRequest). For example:

api = DegreeDaysApi.fromKeys(
    AccountKey(yourStringAccountKey),
    SecurityKey(yourStringSecurityKey))
response = api.dataApi.getLocationData(yourLocationDataRequest)

getLocationData can throw a range of subclasses of DegreeDaysApiError. Take a look at the Javadocs for that method to see which subclasses can be thrown (the Python exceptions mirror the Java exceptions, except their names end with Error instead of Exception).

There is also SourceDataError (another subclass of DegreeDaysApiError), which can be thrown when you try to retrieve a DataSet from the DataSets object in the response. For example:

try:
    hddSet = response.dataSets[hddSpec]
except SourceDataError:
    # hddSpec couldn't be fulfilled as there wasn't enough good temperature data
    # to calculate degree days covering the specified period.

Which, if any, of these exceptions you'll want to handle explicitly will depend on the nature of your application:

Getting less data than you requested

This isn't an error as such, but it's important to realize that, in certain circumstances, the API can return less data than you requested. For example, you might request 10 years of data for a certain weather station, but get only 5 years back if that's all the usable temperature data that the weather station has. Or you might request data up to and including yesterday, but get only data to the day before yesterday. (Note that you should never be able to get the data for yesterday until that day has finished in the location's local time zone, and it's best not to expect it until at least a couple of hours after that. More on update schedules here.)

There are clear rules about how and when the API can deliver less data than requested, and you can control this behaviour as well. See the Javadocs for DataApi.getLocationData(LocationDataRequest) to find out more.

But otherwise there should be no surprises...

We've built the API and the Python client library for robustness and predictability:

More detailed documentation

The documentation for the Python client library is currently limited to this page and the source code (a documentation of sorts). But the Python library is very similar to the Java library, which has very detailed documentation. Follow that link and then through to the javadoc if you're looking for more detail on anything. All the public Python classes have an equivalent Java class, and the Java packages are mirrored by the Python packages/modules as follows:

Virtually all the classes have the same names in Python as they do in Java... The main exception is the exceptions (no pun intended):

The Javadocs have detailed notes about the different request options, the types of response data, and the exceptions, and the vast majority of the notes are equally applicable to Python as to Java.

Hopefully this page, the Python source, and the Javadocs will be plenty, but please do let us know if you're finding the lack of detailed Python-specific documentation a pain. We'd like to have the Python client library better documented, but, as most of our customers are using Java or .NET, we need a bit of a push to justify prioritizing more Python docs over the many other things on our todo list.

Choose your Plan and Sign Up Today!

© 2014 BizEE Software Limited - About | Contact | Privacy Policy | FAQ | Desktop App | API