Package: aiowatttime
🌎 aiowatttime: an asyncio-based, Python3 library for WattTime emissions dataaiowatttimeis a Python 3, asyncio-friendly library for interacting withWattTimeemissions data.Python VersionsInstallationUsageContributingPython Versionsaiowatttimeis currently supported on:Python 3.10Python 3.11Python 3.12InstallationpipinstallaiowatttimeUsageGetting an API KeySimply clone this repo and run the included interactive script:$script/registerNote that WattTime offers three plans: Visitors, Analyst, and Pro. The type you use
will determine which elements of this library are available to use. You can read more
detailshere.Creating and Using a ClientTheClientis the primary method of interacting with the API:importasynciofromaiowatttimeimportClientasyncdefmain()->None:client=awaitClient.login("<USERNAME>","<PASSWORD>")# ...asyncio.run(main())By default, the library creates a new connection to the API with each coroutine. If
you are calling a large number of coroutines (or merely want to squeeze out every second
of runtime savings possible), anaiohttpClientSessioncan be used for
connection pooling:importasynciofromaiohttpimportClientSessionfromaiowatttimeimportClientasyncdefmain()->None:asyncwithClientSession()assession:client=awaitClient.login("<USERNAME>","<PASSWORD>",session=session)# ...asyncio.run(main())Programmatically Requesting a Password Resetawaitclient.async_request_password_reset()Getting Emissions DataGrid RegionIt may be useful to first get the "grid region" (i.e., geographical info) for the area
you care about:awaitclient.emissions.async_get_grid_region("<LATITUDE>","<LONGITUDE>")# >>> { "id": 263, "abbrev": "PJM_NJ", "name": "PJM New Jersey" }Getting emissions data will require either your latitude/longitudeorthe "balancing
authority abbreviation" (PJM_NJin the example above).Realtime Dataawaitclient.emissions.async_get_realtime_emissions("<LATITUDE>","<LONGITUDE>")# >>> { "freq": "300", "ba": "CAISO_NORTH", "percent": "53", "moer": "850.743982", ... }Forecasted Dataawaitclient.emissions.async_get_forecasted_emissions("<BA_ABBREVATION>")# >>> [ { "generated_at": "2021-08-05T09:05:00+00:00", "forecast": [...] } ]You can also get the forecasted data using a specific start and enddatetime.datetime:fromdatetimeimportdatetimeawaitclient.emissions.async_get_forecasted_emissions("<BA_ABBREVATION>",start_datetime=datetime(2021,1,1),end_datetime=datetime(2021,2,1),)# >>> [ { "generated_at": "2021-08-05T09:05:00+00:00", "forecast": [...] } ]Historical Dataawaitclient.emissions.async_get_historical_emissions("<LATITUDE>","<LONGITUDE>")# >>> [ { "point_time": "2019-02-21T00:15:00.000Z", "value": 844, ... } ]You can also get the historical data using a specific start and enddatetime.datetime:fromdatetimeimportdatetimeawaitclient.emissions.async_get_historical_emissions("<LATITUDE>","<LONGITUDE>",start_datetime=datetime(2021,1,1),end_datetime=datetime(2021,2,1),)# >>> [ { "point_time": "2019-02-21T00:15:00.000Z", "value": 844, ... } ]Retry LogicBy default,aiowatttimewill handle expired access tokens for you. When a token expires,
the library will attempt the following sequence 3 times:Request a new tokenPause for 1 second (to be respectful of the API rate limiting)Execute the original request againBoth the number of retries and the delay between retries can be configured when
instantiating a client:importasynciofromaiohttpimportClientSessionfromaiowatttimeimportClientasyncdefmain()->None:asyncwithClientSession()assession:client=awaitClient.async_login("user","password",session=session,# Make 7 retry attempts:request_retries=7,# Delay 4 seconds between attempts:request_retry_delay=4,)asyncio.run(main())As always, an invalid username/password combination will immediately throw an exception.Custom LoggerBy default,aiowatttimeprovides its own logger. If you should wish to use your own, you
can pass it to the client during instantiation:importasyncioimportloggingfromaiohttpimportClientSessionfromaiowatttimeimportClientCUSTOM_LOGGER=logging.getLogger("my_custom_logger")asyncdefmain()->None:asyncwithClientSession()assession:client=awaitClient.async_login("user","password",session=session,logger=logger,)asyncio.run(main())ContributingThanks to all ofour contributorsso far!Check for open features/bugsorinitiate a discussion on one.Fork the repository.(optional, but highly recommended) Create a virtual environment:python3 -m venv .venv(optional, but highly recommended) Enter the virtual environment:source ./.venv/bin/activateInstall the dev environment:script/setupCode your new feature or bug fix on a new branch.Write tests that cover your new functionality.Run tests and ensure 100% code coverage:poetry run pytest --cov aiowatttime testsUpdateREADME.mdwith any new documentation.Submit a pull request!