From cb4fe525d1fd3553c7c5713e9f21b0f962091fb6 Mon Sep 17 00:00:00 2001 From: fvaleye Date: Mon, 20 Mar 2023 18:41:36 +0100 Subject: [PATCH] Add the URL of the endpoint of the CO2 Signal API as a configuration key --- README.md | 26 +++-- helm/tracarbon/templates/daemonset.yaml | 8 +- helm/tracarbon/values.yaml | 2 +- poetry.lock | 126 ++++++++++----------- pyproject.toml | 2 +- tests/locations/test_country.py | 35 +++++- tracarbon/builder.py | 1 + tracarbon/cli/__init__.py | 1 + tracarbon/conf.py | 3 + tracarbon/exporters/prometheus_exporter.py | 2 +- tracarbon/general_metrics.py | 6 + tracarbon/locations/country.py | 13 ++- tracarbon/locations/location.py | 1 + 13 files changed, 142 insertions(+), 84 deletions(-) diff --git a/README.md b/README.md index 13b882d..3f736d5 100644 --- a/README.md +++ b/README.md @@ -48,26 +48,28 @@ pip install 'tracarbon[datadog,prometheus,kubernetes]' | Datadog | Send the metrics to Datadog. | ### πŸ—ΊοΈ Locations -| **Location** | **Description** | **Source** | -|--------------|:-------------------------------------------------------------------------------------------------------------------------------------------------------:|:--------------------------------------------------------------------------------------------------------------------------------------------------------------| -| Worldwide | Get the latest co2g/kwh in near real-time using the CO2 Signal API. See [here](http://api.electricitymap.org/v3/zones) for the list of available zones. | [CO2Signal API](https://www.co2signal.com) | -| Europe | Static file created from the European Environment Agency Emission for the co2g/kwh in European countries. | [EEA website](https://www.eea.europa.eu/data-and-maps/daviz/co2-emission-intensity-9#tab-googlechartid_googlechartid_googlechartid_googlechartid_chart_11111) | -| AWS | Static file of the AWS Grid emissions factors. | [cloud-carbon-coefficients](https://github.com/cloud-carbon-footprint/cloud-carbon-coefficients/blob/main/data/grid-emissions-factors-aws.csv) | +| **Location** | **Description** | **Source** | +|--------------|:--------------------------------------------------------------------------------------------------------------------------------------------------------------------------:|:--------------------------------------------------------------------------------------------------------------------------------------------------------------| +| Worldwide | Get the latest co2g/kwh in near real-time using the CO2Signal or ElectricityMaps APIs. See [here](http://api.electricitymap.org/v3/zones) for the list of available zones. | [CO2Signal API](https://www.co2signal.com) or [ElectricityMaps](https://static.electricitymaps.com/api/docs/index.html) | +| Europe | Static file created from the European Environment Agency Emission for the co2g/kwh in European countries. | [EEA website](https://www.eea.europa.eu/data-and-maps/daviz/co2-emission-intensity-9#tab-googlechartid_googlechartid_googlechartid_googlechartid_chart_11111) | +| AWS | Static file of the AWS Grid emissions factors. | [cloud-carbon-coefficients](https://github.com/cloud-carbon-footprint/cloud-carbon-coefficients/blob/main/data/grid-emissions-factors-aws.csv) | ### βš™οΈ Configuration The environment variables can be set from an environment file `.env`. -| **Parameter** | **Description** | -|-------------------------------|:-------------------------------------------------------------------------------| -| TRACARBON_CO2SIGNAL_API_KEY | The api key received from [CO2 Signal](https://www.co2signal.com). | -| TRACARBON_METRIC_PREFIX_NAME | The prefix to use in all the metrics name. | -| TRACARBON_INTERVAL_IN_SECONDS | The interval in seconds to wait between the metrics evaluation. | -| TRACARBON_LOG_LEVEL | The level to use for displaying the logs. | +| **Parameter** | **Description** | +|-------------------------------|:---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| +| TRACARBON_CO2SIGNAL_API_KEY | The api key received from [CO2Signal](https://www.co2signal.com) or [ElectricityMaps](https://static.electricitymaps.com/api/docs/index.html). | +| TRACARBON_CO2SIGNAL_URL | The url of [CO2Signal](https://docs.co2signal.com/#get-latest-by-country-code) is the default endpoint to retrieve the last known state of the zone, but it could be changed to [ElectricityMaps](https://static.electricitymaps.com/api/docs/index.html#live-carbon-intensity). | +| TRACARBON_METRIC_PREFIX_NAME | The prefix to use in all the metrics name. | +| TRACARBON_INTERVAL_IN_SECONDS | The interval in seconds to wait between the metrics evaluation. | +| TRACARBON_LOG_LEVEL | The level to use for displaying the logs. | ## πŸ”Ž Usage **Request your API key** -- Go to https://www.co2signal.com/ and get your free API key (for non-commercial use only) for getting the latest carbon intensity from your location in near-real time. +- Go to [CO2Signal](https://www.co2signal.com/) and get your free API key for non-commercial use, or go to [ElectricityMaps](https://static.electricitymaps.com/api/docs/index.html) for commercial use. +- This API is used to retrieve the last known carbon intensity (in gCO2eq/kWh) of electricity consumed in your location. - Set your API key in the environment variables, in the `.env` file or directly in the configuration. - If you would like to start without an API key, it's possible, the carbon intensity will be loaded statistically from a file. - Launch Tracarbon πŸš€ diff --git a/helm/tracarbon/templates/daemonset.yaml b/helm/tracarbon/templates/daemonset.yaml index fb2ed13..71182e4 100644 --- a/helm/tracarbon/templates/daemonset.yaml +++ b/helm/tracarbon/templates/daemonset.yaml @@ -24,9 +24,13 @@ spec: - {{ . }} {{ end }} env: - {{- if .Values.tracarbon.co2_signal_api_key }} + {{- if .Values.tracarbon.co2signal_api_key }} - name: TRACARBON_CO2SIGNAL_API_KEY - value: '{{ .Values.tracarbon.co2_signal_api_key }}' + value: '{{ .Values.tracarbon.co2signal_api_key }}' + {{- end }} + {{- if .Values.tracarbon.co2signal_url }} + - name: TRACARBON_CO2SIGNAL_URL + value: '{{ .Values.tracarbon.co2signal_url }}' {{- end }} - name: TRACARBON_INTERVAL_IN_SECONDS value: '{{ .Values.tracarbon.interval_in_seconds }}' diff --git a/helm/tracarbon/values.yaml b/helm/tracarbon/values.yaml index b86b16e..3311630 100644 --- a/helm/tracarbon/values.yaml +++ b/helm/tracarbon/values.yaml @@ -15,7 +15,7 @@ tracarbon: args: - --exporter-name=Prometheus - --containers - co2_signal_api_key: "" + co2signal_api_key: "" interval_in_seconds: 60 log_level: "INFO" metric_prefix_name: "tracarbon" diff --git a/poetry.lock b/poetry.lock index 3d390a4..5da6cd8 100644 --- a/poetry.lock +++ b/poetry.lock @@ -1,4 +1,4 @@ -# This file is automatically @generated by Poetry and should not be changed by hand. +# This file is automatically @generated by Poetry 1.4.0 and should not be changed by hand. [[package]] name = "accessible-pygments" @@ -252,14 +252,14 @@ yaml = ["PyYAML"] [[package]] name = "beautifulsoup4" -version = "4.11.2" +version = "4.12.0" description = "Screen-scraping library" category = "dev" optional = false python-versions = ">=3.6.0" files = [ - {file = "beautifulsoup4-4.11.2-py3-none-any.whl", hash = "sha256:0e79446b10b3ecb499c1556f7e228a53e64a2bfcebd455f370d8927cb5b59e39"}, - {file = "beautifulsoup4-4.11.2.tar.gz", hash = "sha256:bc4bdda6717de5a2987436fb8d72f45dc90dd856bdfd512a1314ce90349a0106"}, + {file = "beautifulsoup4-4.12.0-py3-none-any.whl", hash = "sha256:2130a5ad7f513200fae61a17abb5e338ca980fa28c439c0571014bc0217e9591"}, + {file = "beautifulsoup4-4.12.0.tar.gz", hash = "sha256:c5fceeaec29d09c84970e47c65f2f0efe57872f7cff494c9691a26ec0ff13234"}, ] [package.dependencies] @@ -457,63 +457,63 @@ files = [ [[package]] name = "coverage" -version = "7.2.1" +version = "7.2.2" description = "Code coverage measurement for Python" category = "dev" optional = false python-versions = ">=3.7" files = [ - {file = "coverage-7.2.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:49567ec91fc5e0b15356da07a2feabb421d62f52a9fff4b1ec40e9e19772f5f8"}, - {file = "coverage-7.2.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:d2ef6cae70168815ed91388948b5f4fcc69681480a0061114db737f957719f03"}, - {file = "coverage-7.2.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3004765bca3acd9e015794e5c2f0c9a05587f5e698127ff95e9cfba0d3f29339"}, - {file = "coverage-7.2.1-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:cca7c0b7f5881dfe0291ef09ba7bb1582cb92ab0aeffd8afb00c700bf692415a"}, - {file = "coverage-7.2.1-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b2167d116309f564af56f9aa5e75ef710ef871c5f9b313a83050035097b56820"}, - {file = "coverage-7.2.1-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:cb5f152fb14857cbe7f3e8c9a5d98979c4c66319a33cad6e617f0067c9accdc4"}, - {file = "coverage-7.2.1-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:87dc37f16fb5e3a28429e094145bf7c1753e32bb50f662722e378c5851f7fdc6"}, - {file = "coverage-7.2.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:e191a63a05851f8bce77bc875e75457f9b01d42843f8bd7feed2fc26bbe60833"}, - {file = "coverage-7.2.1-cp310-cp310-win32.whl", hash = "sha256:e3ea04b23b114572b98a88c85379e9e9ae031272ba1fb9b532aa934c621626d4"}, - {file = "coverage-7.2.1-cp310-cp310-win_amd64.whl", hash = "sha256:0cf557827be7eca1c38a2480484d706693e7bb1929e129785fe59ec155a59de6"}, - {file = "coverage-7.2.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:570c21a29493b350f591a4b04c158ce1601e8d18bdcd21db136fbb135d75efa6"}, - {file = "coverage-7.2.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:9e872b082b32065ac2834149dc0adc2a2e6d8203080501e1e3c3c77851b466f9"}, - {file = "coverage-7.2.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:fac6343bae03b176e9b58104a9810df3cdccd5cfed19f99adfa807ffbf43cf9b"}, - {file = "coverage-7.2.1-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:abacd0a738e71b20e224861bc87e819ef46fedba2fb01bc1af83dfd122e9c319"}, - {file = "coverage-7.2.1-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d9256d4c60c4bbfec92721b51579c50f9e5062c21c12bec56b55292464873508"}, - {file = "coverage-7.2.1-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:80559eaf6c15ce3da10edb7977a1548b393db36cbc6cf417633eca05d84dd1ed"}, - {file = "coverage-7.2.1-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:0bd7e628f6c3ec4e7d2d24ec0e50aae4e5ae95ea644e849d92ae4805650b4c4e"}, - {file = "coverage-7.2.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:09643fb0df8e29f7417adc3f40aaf379d071ee8f0350ab290517c7004f05360b"}, - {file = "coverage-7.2.1-cp311-cp311-win32.whl", hash = "sha256:1b7fb13850ecb29b62a447ac3516c777b0e7a09ecb0f4bb6718a8654c87dfc80"}, - {file = "coverage-7.2.1-cp311-cp311-win_amd64.whl", hash = "sha256:617a94ada56bbfe547aa8d1b1a2b8299e2ec1ba14aac1d4b26a9f7d6158e1273"}, - {file = "coverage-7.2.1-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:8649371570551d2fd7dee22cfbf0b61f1747cdfb2b7587bb551e4beaaa44cb97"}, - {file = "coverage-7.2.1-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5d2b9b5e70a21474c105a133ba227c61bc95f2ac3b66861143ce39a5ea4b3f84"}, - {file = "coverage-7.2.1-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ae82c988954722fa07ec5045c57b6d55bc1a0890defb57cf4a712ced65b26ddd"}, - {file = "coverage-7.2.1-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:861cc85dfbf55a7a768443d90a07e0ac5207704a9f97a8eb753292a7fcbdfcfc"}, - {file = "coverage-7.2.1-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:0339dc3237c0d31c3b574f19c57985fcbe494280153bbcad33f2cdf469f4ac3e"}, - {file = "coverage-7.2.1-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:5928b85416a388dd557ddc006425b0c37e8468bd1c3dc118c1a3de42f59e2a54"}, - {file = "coverage-7.2.1-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:8d3843ca645f62c426c3d272902b9de90558e9886f15ddf5efe757b12dd376f5"}, - {file = "coverage-7.2.1-cp37-cp37m-win32.whl", hash = "sha256:6a034480e9ebd4e83d1aa0453fd78986414b5d237aea89a8fdc35d330aa13bae"}, - {file = "coverage-7.2.1-cp37-cp37m-win_amd64.whl", hash = "sha256:6fce673f79a0e017a4dc35e18dc7bb90bf6d307c67a11ad5e61ca8d42b87cbff"}, - {file = "coverage-7.2.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:7f099da6958ddfa2ed84bddea7515cb248583292e16bb9231d151cd528eab657"}, - {file = "coverage-7.2.1-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:97a3189e019d27e914ecf5c5247ea9f13261d22c3bb0cfcfd2a9b179bb36f8b1"}, - {file = "coverage-7.2.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a81dbcf6c6c877986083d00b834ac1e84b375220207a059ad45d12f6e518a4e3"}, - {file = "coverage-7.2.1-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:78d2c3dde4c0b9be4b02067185136b7ee4681978228ad5ec1278fa74f5ca3e99"}, - {file = "coverage-7.2.1-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3a209d512d157379cc9ab697cbdbb4cfd18daa3e7eebaa84c3d20b6af0037384"}, - {file = "coverage-7.2.1-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:f3d07edb912a978915576a776756069dede66d012baa503022d3a0adba1b6afa"}, - {file = "coverage-7.2.1-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:8dca3c1706670297851bca1acff9618455122246bdae623be31eca744ade05ec"}, - {file = "coverage-7.2.1-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:b1991a6d64231a3e5bbe3099fb0dd7c9aeaa4275ad0e0aeff4cb9ef885c62ba2"}, - {file = "coverage-7.2.1-cp38-cp38-win32.whl", hash = "sha256:22c308bc508372576ffa3d2dbc4824bb70d28eeb4fcd79d4d1aed663a06630d0"}, - {file = "coverage-7.2.1-cp38-cp38-win_amd64.whl", hash = "sha256:b0c0d46de5dd97f6c2d1b560bf0fcf0215658097b604f1840365296302a9d1fb"}, - {file = "coverage-7.2.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:4dd34a935de268a133e4741827ae951283a28c0125ddcdbcbba41c4b98f2dfef"}, - {file = "coverage-7.2.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:0f8318ed0f3c376cfad8d3520f496946977abde080439d6689d7799791457454"}, - {file = "coverage-7.2.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:834c2172edff5a08d78e2f53cf5e7164aacabeb66b369f76e7bb367ca4e2d993"}, - {file = "coverage-7.2.1-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e4d70c853f0546855f027890b77854508bdb4d6a81242a9d804482e667fff6e6"}, - {file = "coverage-7.2.1-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8a6450da4c7afc4534305b2b7d8650131e130610cea448ff240b6ab73d7eab63"}, - {file = "coverage-7.2.1-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:99f4dd81b2bb8fc67c3da68b1f5ee1650aca06faa585cbc6818dbf67893c6d58"}, - {file = "coverage-7.2.1-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:bdd3f2f285ddcf2e75174248b2406189261a79e7fedee2ceeadc76219b6faa0e"}, - {file = "coverage-7.2.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:f29351393eb05e6326f044a7b45ed8e38cb4dcc38570d12791f271399dc41431"}, - {file = "coverage-7.2.1-cp39-cp39-win32.whl", hash = "sha256:e2b50ebc2b6121edf352336d503357321b9d8738bb7a72d06fc56153fd3f4cd8"}, - {file = "coverage-7.2.1-cp39-cp39-win_amd64.whl", hash = "sha256:bd5a12239c0006252244f94863f1c518ac256160cd316ea5c47fb1a11b25889a"}, - {file = "coverage-7.2.1-pp37.pp38.pp39-none-any.whl", hash = "sha256:436313d129db7cf5b4ac355dd2bd3f7c7e5294af077b090b85de75f8458b8616"}, - {file = "coverage-7.2.1.tar.gz", hash = "sha256:c77f2a9093ccf329dd523a9b2b3c854c20d2a3d968b6def3b820272ca6732242"}, + {file = "coverage-7.2.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:c90e73bdecb7b0d1cea65a08cb41e9d672ac6d7995603d6465ed4914b98b9ad7"}, + {file = "coverage-7.2.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:e2926b8abedf750c2ecf5035c07515770944acf02e1c46ab08f6348d24c5f94d"}, + {file = "coverage-7.2.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:57b77b9099f172804e695a40ebaa374f79e4fb8b92f3e167f66facbf92e8e7f5"}, + {file = "coverage-7.2.2-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:efe1c0adad110bf0ad7fb59f833880e489a61e39d699d37249bdf42f80590169"}, + {file = "coverage-7.2.2-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2199988e0bc8325d941b209f4fd1c6fa007024b1442c5576f1a32ca2e48941e6"}, + {file = "coverage-7.2.2-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:81f63e0fb74effd5be736cfe07d710307cc0a3ccb8f4741f7f053c057615a137"}, + {file = "coverage-7.2.2-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:186e0fc9cf497365036d51d4d2ab76113fb74f729bd25da0975daab2e107fd90"}, + {file = "coverage-7.2.2-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:420f94a35e3e00a2b43ad5740f935358e24478354ce41c99407cddd283be00d2"}, + {file = "coverage-7.2.2-cp310-cp310-win32.whl", hash = "sha256:38004671848b5745bb05d4d621526fca30cee164db42a1f185615f39dc997292"}, + {file = "coverage-7.2.2-cp310-cp310-win_amd64.whl", hash = "sha256:0ce383d5f56d0729d2dd40e53fe3afeb8f2237244b0975e1427bfb2cf0d32bab"}, + {file = "coverage-7.2.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:3eb55b7b26389dd4f8ae911ba9bc8c027411163839dea4c8b8be54c4ee9ae10b"}, + {file = "coverage-7.2.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:d2b96123a453a2d7f3995ddb9f28d01fd112319a7a4d5ca99796a7ff43f02af5"}, + {file = "coverage-7.2.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:299bc75cb2a41e6741b5e470b8c9fb78d931edbd0cd009c58e5c84de57c06731"}, + {file = "coverage-7.2.2-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:5e1df45c23d4230e3d56d04414f9057eba501f78db60d4eeecfcb940501b08fd"}, + {file = "coverage-7.2.2-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:006ed5582e9cbc8115d2e22d6d2144a0725db542f654d9d4fda86793832f873d"}, + {file = "coverage-7.2.2-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:d683d230b5774816e7d784d7ed8444f2a40e7a450e5720d58af593cb0b94a212"}, + {file = "coverage-7.2.2-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:8efb48fa743d1c1a65ee8787b5b552681610f06c40a40b7ef94a5b517d885c54"}, + {file = "coverage-7.2.2-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:4c752d5264053a7cf2fe81c9e14f8a4fb261370a7bb344c2a011836a96fb3f57"}, + {file = "coverage-7.2.2-cp311-cp311-win32.whl", hash = "sha256:55272f33da9a5d7cccd3774aeca7a01e500a614eaea2a77091e9be000ecd401d"}, + {file = "coverage-7.2.2-cp311-cp311-win_amd64.whl", hash = "sha256:92ebc1619650409da324d001b3a36f14f63644c7f0a588e331f3b0f67491f512"}, + {file = "coverage-7.2.2-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:5afdad4cc4cc199fdf3e18088812edcf8f4c5a3c8e6cb69127513ad4cb7471a9"}, + {file = "coverage-7.2.2-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0484d9dd1e6f481b24070c87561c8d7151bdd8b044c93ac99faafd01f695c78e"}, + {file = "coverage-7.2.2-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d530191aa9c66ab4f190be8ac8cc7cfd8f4f3217da379606f3dd4e3d83feba69"}, + {file = "coverage-7.2.2-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4ac0f522c3b6109c4b764ffec71bf04ebc0523e926ca7cbe6c5ac88f84faced0"}, + {file = "coverage-7.2.2-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:ba279aae162b20444881fc3ed4e4f934c1cf8620f3dab3b531480cf602c76b7f"}, + {file = "coverage-7.2.2-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:53d0fd4c17175aded9c633e319360d41a1f3c6e352ba94edcb0fa5167e2bad67"}, + {file = "coverage-7.2.2-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:8c99cb7c26a3039a8a4ee3ca1efdde471e61b4837108847fb7d5be7789ed8fd9"}, + {file = "coverage-7.2.2-cp37-cp37m-win32.whl", hash = "sha256:5cc0783844c84af2522e3a99b9b761a979a3ef10fb87fc4048d1ee174e18a7d8"}, + {file = "coverage-7.2.2-cp37-cp37m-win_amd64.whl", hash = "sha256:817295f06eacdc8623dc4df7d8b49cea65925030d4e1e2a7c7218380c0072c25"}, + {file = "coverage-7.2.2-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:6146910231ece63facfc5984234ad1b06a36cecc9fd0c028e59ac7c9b18c38c6"}, + {file = "coverage-7.2.2-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:387fb46cb8e53ba7304d80aadca5dca84a2fbf6fe3faf6951d8cf2d46485d1e5"}, + {file = "coverage-7.2.2-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:046936ab032a2810dcaafd39cc4ef6dd295df1a7cbead08fe996d4765fca9fe4"}, + {file = "coverage-7.2.2-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e627dee428a176ffb13697a2c4318d3f60b2ccdde3acdc9b3f304206ec130ccd"}, + {file = "coverage-7.2.2-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4fa54fb483decc45f94011898727802309a109d89446a3c76387d016057d2c84"}, + {file = "coverage-7.2.2-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:3668291b50b69a0c1ef9f462c7df2c235da3c4073f49543b01e7eb1dee7dd540"}, + {file = "coverage-7.2.2-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:7c20b731211261dc9739bbe080c579a1835b0c2d9b274e5fcd903c3a7821cf88"}, + {file = "coverage-7.2.2-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:5764e1f7471cb8f64b8cda0554f3d4c4085ae4b417bfeab236799863703e5de2"}, + {file = "coverage-7.2.2-cp38-cp38-win32.whl", hash = "sha256:4f01911c010122f49a3e9bdc730eccc66f9b72bd410a3a9d3cb8448bb50d65d3"}, + {file = "coverage-7.2.2-cp38-cp38-win_amd64.whl", hash = "sha256:c448b5c9e3df5448a362208b8d4b9ed85305528313fca1b479f14f9fe0d873b8"}, + {file = "coverage-7.2.2-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:bfe7085783cda55e53510482fa7b5efc761fad1abe4d653b32710eb548ebdd2d"}, + {file = "coverage-7.2.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:9d22e94e6dc86de981b1b684b342bec5e331401599ce652900ec59db52940005"}, + {file = "coverage-7.2.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:507e4720791977934bba016101579b8c500fb21c5fa3cd4cf256477331ddd988"}, + {file = "coverage-7.2.2-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:bc4803779f0e4b06a2361f666e76f5c2e3715e8e379889d02251ec911befd149"}, + {file = "coverage-7.2.2-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:db8c2c5ace167fd25ab5dd732714c51d4633f58bac21fb0ff63b0349f62755a8"}, + {file = "coverage-7.2.2-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:4f68ee32d7c4164f1e2c8797535a6d0a3733355f5861e0f667e37df2d4b07140"}, + {file = "coverage-7.2.2-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:d52f0a114b6a58305b11a5cdecd42b2e7f1ec77eb20e2b33969d702feafdd016"}, + {file = "coverage-7.2.2-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:797aad79e7b6182cb49c08cc5d2f7aa7b2128133b0926060d0a8889ac43843be"}, + {file = "coverage-7.2.2-cp39-cp39-win32.whl", hash = "sha256:db45eec1dfccdadb179b0f9ca616872c6f700d23945ecc8f21bb105d74b1c5fc"}, + {file = "coverage-7.2.2-cp39-cp39-win_amd64.whl", hash = "sha256:8dbe2647bf58d2c5a6c5bcc685f23b5f371909a5624e9f5cd51436d6a9f6c6ef"}, + {file = "coverage-7.2.2-pp37.pp38.pp39-none-any.whl", hash = "sha256:872d6ce1f5be73f05bea4df498c140b9e7ee5418bfa2cc8204e7f9b817caa968"}, + {file = "coverage-7.2.2.tar.gz", hash = "sha256:36dd42da34fe94ed98c39887b86db9d06777b1c8f860520e21126a75507024f2"}, ] [package.dependencies] @@ -770,14 +770,14 @@ files = [ [[package]] name = "importlib-metadata" -version = "6.0.0" +version = "6.1.0" description = "Read metadata from Python packages" category = "dev" optional = false python-versions = ">=3.7" files = [ - {file = "importlib_metadata-6.0.0-py3-none-any.whl", hash = "sha256:7efb448ec9a5e313a57655d35aa54cd3e01b7e1fbcf72dce1bf06119420f5bad"}, - {file = "importlib_metadata-6.0.0.tar.gz", hash = "sha256:e354bedeb60efa6affdcc8ae121b73544a7aa74156d047311948f6d711cd378d"}, + {file = "importlib_metadata-6.1.0-py3-none-any.whl", hash = "sha256:ff80f3b5394912eb1b108fcfd444dc78b7f1f3e16b16188054bd01cb9cb86f09"}, + {file = "importlib_metadata-6.1.0.tar.gz", hash = "sha256:43ce9281e097583d758c2c708c4376371261a02c34682491a8e98352365aad20"}, ] [package.dependencies] @@ -1244,14 +1244,14 @@ files = [ [[package]] name = "pathspec" -version = "0.11.0" +version = "0.11.1" description = "Utility library for gitignore style pattern matching of file paths." category = "dev" optional = false python-versions = ">=3.7" files = [ - {file = "pathspec-0.11.0-py3-none-any.whl", hash = "sha256:3a66eb970cbac598f9e5ccb5b2cf58930cd8e3ed86d393d541eaf2d8b1705229"}, - {file = "pathspec-0.11.0.tar.gz", hash = "sha256:64d338d4e0914e91c1792321e6907b5a593f1ab1851de7fc269557a21b30ebbc"}, + {file = "pathspec-0.11.1-py3-none-any.whl", hash = "sha256:d8af70af76652554bd134c22b3e8a1cc46ed7d91edcdd721ef1a0c51a84a5293"}, + {file = "pathspec-0.11.1.tar.gz", hash = "sha256:2798de800fa92780e33acca925945e9a19a133b715067cf165b8866c15a31687"}, ] [[package]] @@ -2330,4 +2330,4 @@ prometheus = ["prometheus-client"] [metadata] lock-version = "2.0" python-versions = "^3.8" -content-hash = "d484176deae5ae3ae487217883ca7cb858b1ea492e84fedaa400f87e7b2fb9d3" +content-hash = "3de89785788f17415f7bb3bde5fd82e6f69d0c3c2bf1e574a5b905525f3af6a0" diff --git a/pyproject.toml b/pyproject.toml index 03f984c..ea19286 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -41,7 +41,7 @@ pytest-cov = "^4.0.0" pytest-xdist = "^3.1.0" pytest-clarity = "^1.0.1" sphinx = "^6.1.3" -pydata-sphinx-theme = "^0.13.0" +pydata-sphinx-theme = "^0.13.1" toml = "^0.10.2" types-ujson = "^5.7.0" datadog = "^0.44.0" diff --git a/tests/locations/test_country.py b/tests/locations/test_country.py index 9df5adb..93a9c94 100644 --- a/tests/locations/test_country.py +++ b/tests/locations/test_country.py @@ -30,7 +30,40 @@ async def test_france_location_should_return_latest_known(mocker): assert result == co2_expected assert country.name == "fr" - assert country.co2g_kwh == 51.1 + assert country.co2g_kwh == co2_expected + assert country.co2g_kwh_source == CarbonIntensitySource.CO2SignalAPI + + +@pytest.mark.asyncio +async def test_france_location_with_recent_api_versions_should_return_latest_known( + mocker, +): + co2_expected = 83 + response = { + "zone": "FR", + "carbonIntensity": co2_expected, + "datetime": "2023-03-20T17:00:00.000Z", + "updatedAt": "2023-03-20T16:51:02.892Z", + "createdAt": "2023-03-17T17:54:01.319Z", + "emissionFactorType": "lifecycle", + "isEstimated": True, + "estimationMethod": "TIME_SLICER_AVERAGE", + } + mocker.patch.object(Country, "request", return_value=response) + co2signal_api_key = "API_KEY" + + country = Country( + name="fr", + co2signal_api_key=co2signal_api_key, + co2g_kwh_source=CarbonIntensitySource.CO2SignalAPI, + co2g_kwh=co2_expected, + ) + + result = await country.get_latest_co2g_kwh() + + assert result == co2_expected + assert country.name == "fr" + assert country.co2g_kwh == co2_expected assert country.co2g_kwh_source == CarbonIntensitySource.CO2SignalAPI diff --git a/tracarbon/builder.py b/tracarbon/builder.py index b91cc0a..8d538d5 100644 --- a/tracarbon/builder.py +++ b/tracarbon/builder.py @@ -29,6 +29,7 @@ def __init__( else: self.location = Country.get_location( co2signal_api_key=self.configuration.co2signal_api_key, + co2signal_url=self.configuration.co2signal_url, ) if exporter: self.exporter = exporter diff --git a/tracarbon/cli/__init__.py b/tracarbon/cli/__init__.py index de3c50f..fc916a1 100644 --- a/tracarbon/cli/__init__.py +++ b/tracarbon/cli/__init__.py @@ -93,6 +93,7 @@ def run_metrics( tracarbon_builder = TracarbonBuilder() location = Country.get_location( co2signal_api_key=tracarbon_builder.configuration.co2signal_api_key, + co2signal_url=tracarbon_builder.configuration.co2signal_url, country_code_alpha_iso_2=country_code_alpha_iso_2, ) metric_generators: List[MetricGenerator] = [ diff --git a/tracarbon/conf.py b/tracarbon/conf.py index dca0a61..96f100c 100755 --- a/tracarbon/conf.py +++ b/tracarbon/conf.py @@ -48,6 +48,7 @@ class TracarbonConfiguration(BaseModel): log_level: str interval_in_seconds: int co2signal_api_key: str + co2signal_url: str def __init__( self, @@ -55,6 +56,7 @@ def __init__( interval_in_seconds: int = 60, log_level: str = "INFO", co2signal_api_key: str = "", + co2signal_url: str = "https://api.co2signal.com/v1/latest?countryCode=", env_file_path: Optional[str] = None, **data: Any, ) -> None: @@ -72,5 +74,6 @@ def __init__( co2signal_api_key=os.environ.get( "TRACARBON_CO2SIGNAL_API_KEY", co2signal_api_key ), + co2signal_url=os.environ.get("TRACARBON_CO2SIGNAL_URL", co2signal_url), **data, ) diff --git a/tracarbon/exporters/prometheus_exporter.py b/tracarbon/exporters/prometheus_exporter.py index 34b4662..b54cce0 100644 --- a/tracarbon/exporters/prometheus_exporter.py +++ b/tracarbon/exporters/prometheus_exporter.py @@ -53,7 +53,7 @@ async def launch(self, metric_generator: MetricGenerator) -> None: ) metric_value = await metric.value() logger.info( - f"Sending metric[{metric_name}] with value [{metric_value}] and labels{metric.format_tags()} to Prometeus." + f"Sending metric[{metric_name}] with value [{metric_value}] and labels{metric.format_tags()} to Prometheus." ) self.prometheus_metrics[metric_name].labels( *[tag.value for tag in metric.tags] diff --git a/tracarbon/general_metrics.py b/tracarbon/general_metrics.py index 244b96b..dabf038 100644 --- a/tracarbon/general_metrics.py +++ b/tracarbon/general_metrics.py @@ -58,6 +58,9 @@ def __init__(self, location: Location, **data: Any) -> None: co2signal_api_key=data["co2signal_api_key"] if "co2signal_api_key" in data else location.co2signal_api_key, + co2signal_url=data["co2signal_url"] + if "co2signal_url" in data + else location.co2signal_url, location=location, ) super().__init__(location=location, metrics=[], **data) @@ -155,6 +158,9 @@ def __init__(self, location: Location, **data: Any) -> None: co2signal_api_key=data["co2signal_api_key"] if "co2signal_api_key" in data else location.co2signal_api_key, + co2signal_url=data["co2signal_url"] + if "co2signal_url" in data + else location.co2signal_url, location=location, ) if "kubernetes" not in data: diff --git a/tracarbon/locations/country.py b/tracarbon/locations/country.py index b45fa94..92e1fa5 100644 --- a/tracarbon/locations/country.py +++ b/tracarbon/locations/country.py @@ -56,7 +56,7 @@ def get_current_country( logger.debug(f"Send request to this url: {url}, timeout {timeout}s") text = requests.get(url, timeout=timeout).text content_json = ujson.loads(text) - return content_json["country"].lower() + return content_json["country"] except Exception as exception: logger.error(f"Failed to request this url: {url}") raise exception @@ -65,6 +65,7 @@ def get_current_country( def get_location( cls, co2signal_api_key: Optional[str] = None, + co2signal_url: Optional[str] = None, country_code_alpha_iso_2: Optional[str] = None, ) -> "Country": """ @@ -72,6 +73,7 @@ def get_location( :param country_code_alpha_iso_2: the alpha iso 2 country name. :param co2signal_api_key: api key for fetching CO2 Signal API. + :param co2signal_url: api url for fetching CO2 Signal API endpoint. :return: the country """ # Cloud Providers @@ -85,6 +87,7 @@ def get_location( if co2signal_api_key: return cls( co2signal_api_key=co2signal_api_key, + co2signal_url=co2signal_url, name=country_code_alpha_iso_2, co2g_kwh_source=CarbonIntensitySource.CO2SignalAPI, ) @@ -107,12 +110,16 @@ async def get_latest_co2g_kwh(self) -> float: ) if not self.co2signal_api_key: raise CO2SignalAPIKeyIsMissing() + url = f"{self.co2signal_url}{self.name}" response = await self.request( - url=f"https://api.co2signal.com/v1/latest?countryCode={self.name}", + url=url, headers={"auth-token": self.co2signal_api_key}, ) try: - self.co2g_kwh = float(response["data"]["carbonIntensity"]) + logger.debug(f"Response from the {url}: {response}.") + if "data" in response: + response = response["data"] + self.co2g_kwh = float(response["carbonIntensity"]) logger.info( f"The latest carbon intensity of your country {self.name} is: {self.co2g_kwh} CO2g/kwh." ) diff --git a/tracarbon/locations/location.py b/tracarbon/locations/location.py index 75e9484..74113b3 100755 --- a/tracarbon/locations/location.py +++ b/tracarbon/locations/location.py @@ -22,6 +22,7 @@ class Location(ABC, BaseModel): name: str co2g_kwh_source: CarbonIntensitySource = CarbonIntensitySource.FILE co2signal_api_key: Optional[str] = None + co2signal_url: Optional[str] = None co2g_kwh: float = 0.0 @classmethod