Last active
July 27, 2023 07:40
-
-
Save codeinthehole/5f274f46b5798f435e6984397f1abb64 to your computer and use it in GitHub Desktop.
Sample Python client for working with the Octopus Energy REST API
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# Requires the requests library (install with 'pip install requests') | |
import requests | |
class APIClient(object): | |
BASE_URL = "https://api.octopus.energy/v1" | |
class DataUnavailable(Exception): | |
""" | |
Catch-all exception indicating we can't get data back from the API | |
""" | |
def __init__(self, api_key): | |
self.api_key = api_key | |
self.session = requests.Session() | |
def _get(self, path, params=None): | |
""" | |
Make a GET HTTP request | |
""" | |
if params is None: | |
params = {} | |
url = self.BASE_URL + path | |
try: | |
response = self.session.request( | |
method="GET", url=url, auth=(self.api_key, ""), params=params) | |
except requests.RequestException as e: | |
raise self.DataUnavailable("Network exception") from e | |
if response.status_code != 200: | |
raise self.DataUnavailable("Unexpected response status (%s)" % response.status_code) | |
return response.json() | |
def electricity_meter_point(self, mpan): | |
# See https://developer.octopus.energy/docs/api/#electricity-meter-points | |
return self._get("/electricity-meter-points/%s/" % mpan) | |
def electricity_tariff_unit_rates(self, product_code, tariff_code, period_from=None, period_to=None): | |
# See https://developer.octopus.energy/docs/api/#list-tariff-charges | |
params = {} | |
if period_from: | |
params['period_from'] = period_from.isoformat() | |
if period_to: | |
params['period_to'] = period_to.isoformat() | |
return self._get("/products/%s/electricity-tariffs/%s/standard-unit-rates/" % ( | |
product_code, tariff_code), params=params) | |
def electricity_tariff_standing_charges(self, product_code, tariff_code, period_from=None, period_to=None): | |
# See https://developer.octopus.energy/docs/api/#list-tariff-charges | |
params = {} | |
if period_from: | |
params['period_from'] = period_from.isoformat() | |
if period_to: | |
params['period_to'] = period_to.isoformat() | |
return self._get("/products/%s/electricity-tariffs/%s/standing-charges/" % ( | |
product_code, tariff_code), params=params) | |
def agile_tariff_unit_rates(self, gsp, period_from=None, period_to=None): | |
""" | |
Helper method to easily look-up the electricity unit rates for given GSP | |
""" | |
# Handle GSPs passed with leading underscore | |
if len(gsp) == 2: | |
gsp = gsp[1] | |
assert gsp in ("A", "B", "C", "D", "E", "F", "G", "P", "N", "J", "H", "K", "L", "M") | |
return self.electricity_tariff_unit_rates( | |
product_code="AGILE-18-02-21", | |
tariff_code="E-1R-AGILE-18-02-21-%s" % gsp, | |
period_from=period_from, | |
period_to=period_to) | |
def electricity_meter_consumption(self, mpan, serial_number, **params): | |
# See https://developer.octopus.energy/docs/api/#list-consumption-for-a-meter | |
return self._get("/electricity-meter-points/%s/meters/%s/consumption/" % ( | |
mpan, serial_number), params=params) | |
def gas_meter_consumption(self, mprn, serial_number, **params): | |
# See https://developer.octopus.energy/docs/api/#list-consumption-for-a-meter | |
return self._get("/gas-meter-points/%s/meters/%s/consumption/" % ( | |
mprn, serial_number), params=params) |
@DougieLawson The gist is just a Python client — it returns dicts for use by other Python code. To turn it into a script that prints JSON to STDOUT, you could append something like:
if __name__ == "__main__":
client = APIClient(api_key=os.environ["API_KEY"])
response = client.electricity_meter_point(mpan=sys.argv[1])
print(json.dumps(response))
then it's possible to pipe its output to jq
:
API_KEY="sk_live_..." python client.py $MPAN | jq .
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Your gist doesn't emit valid JSON (it failed to parse with the jq tool). So here's my hack to fix it.