thegreenwebfoundation / co2.js

An npm module for accessing the green web API, and estimating the carbon emissions from using digital services
Other
375 stars 47 forks source link

Enable external data sources to be added and accessed #188

Open fershad opened 5 months ago

fershad commented 5 months ago

This PR adds the Electricity Maps API as an external data sources which can be accessed within CO2.js (#134).

This change adds a new DataSource class which is exposed to users. The class has as single function set() which is used to set the data source being used.

import { dataSources } from '@tgwf/co2';
const eMaps = new dataSources().set("electricityMapsApi");

eMaps.source.authToken = "MyAuthToken"

Each data source is its own class, and can contain any number of functions which map to the structure of the external API being queried.

In the case of Electricity Maps, we use the free API endpoint and expose three functions:

For example, to get the latest grid intensity for Taiwan we can:

const taiwanZoneLatest = await eMaps.source.getLatest("TW");

const taiwanLatLonLatest = await eMaps.source.getLatest(undefined, "23.6978", "120.9605");

With this update, it will also be possible for additional data sources to be added. The kinds of data sources which could be added are not just limited to grid intensity either, meaning it could be possible to add an adaptor for connecting with a service like the Boavista API (for example) to return environmental impact data for hardware and cloud devices.

fershad commented 5 months ago

@mrchrisadams 🎉 the main files to look at for this change are:

I can show you an example of this in action if you want.

fershad commented 5 months ago

One thing I might look to change here is to pass an options object into the getLatest and getHistory functions. Right now, passing in the zone variable as undefined doesn't feel great.

So instead of:

const taiwanZoneLatest = await eMaps.source.getLatest("TW");

const taiwanLatLonLatest = await eMaps.source.getLatest(undefined, "23.6978", "120.9605");

You'd have:

const taiwanZoneLatest = await eMaps.source.getLatest({ zone: "TW" });

const taiwanLatLonLatest = await eMaps.source.getLatest({ lat: "23.6978", lon: "120.9605" });
fershad commented 5 months ago

Probably also need someone from Electricity Maps to confirm the proper API base URL we should be using here for the free tier routes.

Is it https://api-access.electricitymaps.com/free-tier/ or https://api.electricitymap.org/?

madsnedergaard commented 5 months ago

Probably also need someone from Electricity Maps to confirm the proper API base URL we should be using here for the free tier routes.

Is it https://api-access.electricitymaps.com/free-tier/ or https://api.electricitymap.org/?

Hey @fershad, happy to quickly answer this one - and we'd also love to jump on a call together with you guys to give more details and context if required!

We are in the process of aligning everything under the https://api.electricitymap.org/ domain to simply things :) Right now api-access.electricitymaps.com is just redirecting, so it would be best to avoid using that.

Users can get a token to use for the free tier over at https://api-portal.electricitymaps.com/. I've also been updating our API documentation recently to explain more about what endpoints are available for the free tier tokens (although it seems like I forgot about /zones, I'll get that one added to the docs soon!):

Screenshot 2024-02-07 at 16 15 34

madsnedergaard commented 5 months ago

PS. We're also thinking of building SDKs for interacting with the API - would you be interested in using that if we did, or do you prefer having your own code for this? :)

PPS. This is really cool and we're super excited that you're implementing this! 😍