codecarbon 3.2.5__tar.gz → 3.2.6__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (126) hide show
  1. {codecarbon-3.2.5 → codecarbon-3.2.6}/PKG-INFO +8 -8
  2. {codecarbon-3.2.5 → codecarbon-3.2.6}/README.md +7 -7
  3. codecarbon-3.2.6/codecarbon/_version.py +1 -0
  4. {codecarbon-3.2.5 → codecarbon-3.2.6}/codecarbon/cli/cli_utils.py +12 -16
  5. {codecarbon-3.2.5 → codecarbon-3.2.6}/codecarbon/cli/main.py +21 -12
  6. {codecarbon-3.2.5 → codecarbon-3.2.6}/codecarbon/cli/monitor.py +2 -1
  7. {codecarbon-3.2.5 → codecarbon-3.2.6}/codecarbon/core/powermetrics.py +1 -1
  8. {codecarbon-3.2.5 → codecarbon-3.2.6}/codecarbon/emissions_tracker.py +3 -2
  9. {codecarbon-3.2.5 → codecarbon-3.2.6}/codecarbon/external/hardware.py +4 -4
  10. {codecarbon-3.2.5 → codecarbon-3.2.6}/codecarbon/external/ram.py +1 -1
  11. {codecarbon-3.2.5 → codecarbon-3.2.6}/codecarbon/output.py +3 -0
  12. codecarbon-3.2.6/codecarbon/output_methods/boamps/__init__.py +25 -0
  13. codecarbon-3.2.6/codecarbon/output_methods/boamps/mapper.py +260 -0
  14. codecarbon-3.2.6/codecarbon/output_methods/boamps/models.py +303 -0
  15. codecarbon-3.2.6/codecarbon/output_methods/boamps/output.py +164 -0
  16. {codecarbon-3.2.5 → codecarbon-3.2.6}/codecarbon.egg-info/PKG-INFO +8 -8
  17. {codecarbon-3.2.5 → codecarbon-3.2.6}/codecarbon.egg-info/SOURCES.txt +5 -0
  18. {codecarbon-3.2.5 → codecarbon-3.2.6}/pyproject.toml +4 -3
  19. codecarbon-3.2.6/tests/test_api_call.py +307 -0
  20. codecarbon-3.2.6/tests/test_boamps_output.py +1172 -0
  21. {codecarbon-3.2.5 → codecarbon-3.2.6}/tests/test_config.py +17 -0
  22. {codecarbon-3.2.5 → codecarbon-3.2.6}/tests/test_core_util.py +25 -10
  23. {codecarbon-3.2.5 → codecarbon-3.2.6}/tests/test_cpu.py +192 -0
  24. {codecarbon-3.2.5 → codecarbon-3.2.6}/tests/test_cpu_load.py +65 -0
  25. {codecarbon-3.2.5 → codecarbon-3.2.6}/tests/test_emissions_tracker.py +27 -0
  26. codecarbon-3.2.6/tests/test_powermetrics.py +161 -0
  27. {codecarbon-3.2.5 → codecarbon-3.2.6}/tests/test_ram.py +147 -0
  28. codecarbon-3.2.6/tests/test_resource_tracker.py +352 -0
  29. {codecarbon-3.2.5 → codecarbon-3.2.6}/tests/test_unsupported_gpu.py +6 -2
  30. codecarbon-3.2.5/codecarbon/_version.py +0 -1
  31. codecarbon-3.2.5/tests/test_api_call.py +0 -108
  32. codecarbon-3.2.5/tests/test_powermetrics.py +0 -37
  33. codecarbon-3.2.5/tests/test_resource_tracker.py +0 -43
  34. {codecarbon-3.2.5 → codecarbon-3.2.6}/LICENSE +0 -0
  35. {codecarbon-3.2.5 → codecarbon-3.2.6}/codecarbon/__init__.py +0 -0
  36. {codecarbon-3.2.5 → codecarbon-3.2.6}/codecarbon/cli/__init__.py +0 -0
  37. {codecarbon-3.2.5 → codecarbon-3.2.6}/codecarbon/cli/auth.py +0 -0
  38. {codecarbon-3.2.5 → codecarbon-3.2.6}/codecarbon/core/__init__.py +0 -0
  39. {codecarbon-3.2.5 → codecarbon-3.2.6}/codecarbon/core/api_client.py +0 -0
  40. {codecarbon-3.2.5 → codecarbon-3.2.6}/codecarbon/core/cloud.py +0 -0
  41. {codecarbon-3.2.5 → codecarbon-3.2.6}/codecarbon/core/config.py +0 -0
  42. {codecarbon-3.2.5 → codecarbon-3.2.6}/codecarbon/core/cpu.py +0 -0
  43. {codecarbon-3.2.5 → codecarbon-3.2.6}/codecarbon/core/electricitymaps_api.py +0 -0
  44. {codecarbon-3.2.5 → codecarbon-3.2.6}/codecarbon/core/emissions.py +0 -0
  45. {codecarbon-3.2.5 → codecarbon-3.2.6}/codecarbon/core/gpu.py +0 -0
  46. {codecarbon-3.2.5 → codecarbon-3.2.6}/codecarbon/core/gpu_amd.py +0 -0
  47. {codecarbon-3.2.5 → codecarbon-3.2.6}/codecarbon/core/gpu_device.py +0 -0
  48. {codecarbon-3.2.5 → codecarbon-3.2.6}/codecarbon/core/gpu_nvidia.py +0 -0
  49. {codecarbon-3.2.5 → codecarbon-3.2.6}/codecarbon/core/measure.py +0 -0
  50. {codecarbon-3.2.5 → codecarbon-3.2.6}/codecarbon/core/rapl.py +0 -0
  51. {codecarbon-3.2.5 → codecarbon-3.2.6}/codecarbon/core/resource_tracker.py +0 -0
  52. {codecarbon-3.2.5 → codecarbon-3.2.6}/codecarbon/core/schemas.py +0 -0
  53. {codecarbon-3.2.5 → codecarbon-3.2.6}/codecarbon/core/units.py +0 -0
  54. {codecarbon-3.2.5 → codecarbon-3.2.6}/codecarbon/core/util.py +0 -0
  55. {codecarbon-3.2.5 → codecarbon-3.2.6}/codecarbon/data/canada_provinces.geojson +0 -0
  56. {codecarbon-3.2.5 → codecarbon-3.2.6}/codecarbon/data/cloud/impact.csv +0 -0
  57. {codecarbon-3.2.5 → codecarbon-3.2.6}/codecarbon/data/hardware/cpu_dataset_builder/amd_cpu_scrapper.py +0 -0
  58. {codecarbon-3.2.5 → codecarbon-3.2.6}/codecarbon/data/hardware/cpu_dataset_builder/intel_cpu_scrapper.py +0 -0
  59. {codecarbon-3.2.5 → codecarbon-3.2.6}/codecarbon/data/hardware/cpu_dataset_builder/merge_scrapped_cpu_power.py +0 -0
  60. {codecarbon-3.2.5 → codecarbon-3.2.6}/codecarbon/data/hardware/cpu_power.csv +0 -0
  61. {codecarbon-3.2.5 → codecarbon-3.2.6}/codecarbon/data/private_infra/2016/usa_emissions.json +0 -0
  62. {codecarbon-3.2.5 → codecarbon-3.2.6}/codecarbon/data/private_infra/2023/canada_energy_mix.json +0 -0
  63. {codecarbon-3.2.5 → codecarbon-3.2.6}/codecarbon/data/private_infra/carbon_intensity_per_source.json +0 -0
  64. {codecarbon-3.2.5 → codecarbon-3.2.6}/codecarbon/data/private_infra/global_energy_mix.json +0 -0
  65. {codecarbon-3.2.5 → codecarbon-3.2.6}/codecarbon/data/private_infra/nordic_emissions.json +0 -0
  66. {codecarbon-3.2.5 → codecarbon-3.2.6}/codecarbon/external/__init__.py +0 -0
  67. {codecarbon-3.2.5 → codecarbon-3.2.6}/codecarbon/external/geography.py +0 -0
  68. {codecarbon-3.2.5 → codecarbon-3.2.6}/codecarbon/external/logger.py +0 -0
  69. {codecarbon-3.2.5 → codecarbon-3.2.6}/codecarbon/external/scheduler.py +0 -0
  70. {codecarbon-3.2.5 → codecarbon-3.2.6}/codecarbon/external/task.py +0 -0
  71. {codecarbon-3.2.5 → codecarbon-3.2.6}/codecarbon/input.py +0 -0
  72. {codecarbon-3.2.5 → codecarbon-3.2.6}/codecarbon/lock.py +0 -0
  73. {codecarbon-3.2.5 → codecarbon-3.2.6}/codecarbon/output_methods/__init__.py +0 -0
  74. {codecarbon-3.2.5 → codecarbon-3.2.6}/codecarbon/output_methods/base_output.py +0 -0
  75. {codecarbon-3.2.5 → codecarbon-3.2.6}/codecarbon/output_methods/emissions_data.py +0 -0
  76. {codecarbon-3.2.5 → codecarbon-3.2.6}/codecarbon/output_methods/file.py +0 -0
  77. {codecarbon-3.2.5 → codecarbon-3.2.6}/codecarbon/output_methods/http.py +0 -0
  78. {codecarbon-3.2.5 → codecarbon-3.2.6}/codecarbon/output_methods/logger.py +0 -0
  79. {codecarbon-3.2.5 → codecarbon-3.2.6}/codecarbon/output_methods/metrics/__init__.py +0 -0
  80. {codecarbon-3.2.5 → codecarbon-3.2.6}/codecarbon/output_methods/metrics/logfire.py +0 -0
  81. {codecarbon-3.2.5 → codecarbon-3.2.6}/codecarbon/output_methods/metrics/metric_docs.py +0 -0
  82. {codecarbon-3.2.5 → codecarbon-3.2.6}/codecarbon/output_methods/metrics/prometheus.py +0 -0
  83. {codecarbon-3.2.5 → codecarbon-3.2.6}/codecarbon/py.typed +0 -0
  84. {codecarbon-3.2.5 → codecarbon-3.2.6}/codecarbon/viz/__init__.py +0 -0
  85. {codecarbon-3.2.5 → codecarbon-3.2.6}/codecarbon/viz/assets/__init__.py +0 -0
  86. {codecarbon-3.2.5 → codecarbon-3.2.6}/codecarbon/viz/assets/car_icon.png +0 -0
  87. {codecarbon-3.2.5 → codecarbon-3.2.6}/codecarbon/viz/assets/house_icon.png +0 -0
  88. {codecarbon-3.2.5 → codecarbon-3.2.6}/codecarbon/viz/assets/tv_icon.png +0 -0
  89. {codecarbon-3.2.5 → codecarbon-3.2.6}/codecarbon/viz/carbonboard.py +0 -0
  90. {codecarbon-3.2.5 → codecarbon-3.2.6}/codecarbon/viz/carbonboard_on_api.py +0 -0
  91. {codecarbon-3.2.5 → codecarbon-3.2.6}/codecarbon/viz/components.py +0 -0
  92. {codecarbon-3.2.5 → codecarbon-3.2.6}/codecarbon/viz/data.py +0 -0
  93. {codecarbon-3.2.5 → codecarbon-3.2.6}/codecarbon/viz/units.py +0 -0
  94. {codecarbon-3.2.5 → codecarbon-3.2.6}/codecarbon.egg-info/dependency_links.txt +0 -0
  95. {codecarbon-3.2.5 → codecarbon-3.2.6}/codecarbon.egg-info/entry_points.txt +0 -0
  96. {codecarbon-3.2.5 → codecarbon-3.2.6}/codecarbon.egg-info/requires.txt +0 -0
  97. {codecarbon-3.2.5 → codecarbon-3.2.6}/codecarbon.egg-info/top_level.txt +0 -0
  98. {codecarbon-3.2.5 → codecarbon-3.2.6}/setup.cfg +0 -0
  99. {codecarbon-3.2.5 → codecarbon-3.2.6}/tests/test_cloud.py +0 -0
  100. {codecarbon-3.2.5 → codecarbon-3.2.6}/tests/test_custom_handler.py +0 -0
  101. {codecarbon-3.2.5 → codecarbon-3.2.6}/tests/test_electricitymaps_api.py +0 -0
  102. {codecarbon-3.2.5 → codecarbon-3.2.6}/tests/test_electricitymaps_backward_compatibility.py +0 -0
  103. {codecarbon-3.2.5 → codecarbon-3.2.6}/tests/test_electricitymaps_config_backward_compatibility.py +0 -0
  104. {codecarbon-3.2.5 → codecarbon-3.2.6}/tests/test_emissions.py +0 -0
  105. {codecarbon-3.2.5 → codecarbon-3.2.6}/tests/test_emissions_tracker_constant.py +0 -0
  106. {codecarbon-3.2.5 → codecarbon-3.2.6}/tests/test_emissions_tracker_flush.py +0 -0
  107. {codecarbon-3.2.5 → codecarbon-3.2.6}/tests/test_energy.py +0 -0
  108. {codecarbon-3.2.5 → codecarbon-3.2.6}/tests/test_geography.py +0 -0
  109. {codecarbon-3.2.5 → codecarbon-3.2.6}/tests/test_gpu.py +0 -0
  110. {codecarbon-3.2.5 → codecarbon-3.2.6}/tests/test_gpu_amd.py +0 -0
  111. {codecarbon-3.2.5 → codecarbon-3.2.6}/tests/test_gpu_nvidia.py +0 -0
  112. {codecarbon-3.2.5 → codecarbon-3.2.6}/tests/test_input.py +0 -0
  113. {codecarbon-3.2.5 → codecarbon-3.2.6}/tests/test_lock.py +0 -0
  114. {codecarbon-3.2.5 → codecarbon-3.2.6}/tests/test_logger.py +0 -0
  115. {codecarbon-3.2.5 → codecarbon-3.2.6}/tests/test_logging_output.py +0 -0
  116. {codecarbon-3.2.5 → codecarbon-3.2.6}/tests/test_offline_emissions_tracker.py +0 -0
  117. {codecarbon-3.2.5 → codecarbon-3.2.6}/tests/test_package_integrity.py +0 -0
  118. {codecarbon-3.2.5 → codecarbon-3.2.6}/tests/test_rapl_mmio_scanning.py +0 -0
  119. {codecarbon-3.2.5 → codecarbon-3.2.6}/tests/test_rapl_parameters.py +0 -0
  120. {codecarbon-3.2.5 → codecarbon-3.2.6}/tests/test_rapl_permissions.py +0 -0
  121. {codecarbon-3.2.5 → codecarbon-3.2.6}/tests/test_tracking_inference.py +0 -0
  122. {codecarbon-3.2.5 → codecarbon-3.2.6}/tests/test_utilization_tracking.py +0 -0
  123. {codecarbon-3.2.5 → codecarbon-3.2.6}/tests/test_viz_data.py +0 -0
  124. {codecarbon-3.2.5 → codecarbon-3.2.6}/tests/test_viz_units.py +0 -0
  125. {codecarbon-3.2.5 → codecarbon-3.2.6}/tests/testdata.py +0 -0
  126. {codecarbon-3.2.5 → codecarbon-3.2.6}/tests/testutils.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: codecarbon
3
- Version: 3.2.5
3
+ Version: 3.2.6
4
4
  Author: Mila, DataForGood, BCG GAMMA, Comet.ml, Haverford College
5
5
  License-Expression: MIT
6
6
  Project-URL: Homepage, https://codecarbon.io/
@@ -52,8 +52,8 @@ Estimate and track carbon emissions from your computer, quantify and analyze the
52
52
 
53
53
  CodeCarbon websites:
54
54
  - [Main website](https://codecarbon.io) to learn why we do this.
55
- - [Dashboard](https://dashboard.codecarbon.io/) to see your emissions, [read the API doc](https://mlco2.github.io/codecarbon/api.html) before.
56
- - [Documentation](https://mlco2.github.io/codecarbon) to learn how to use the package and our methodology.
55
+ - [Dashboard](https://dashboard.codecarbon.io/) to see your emissions, [read the API doc](https://docs.codecarbon.io/latest/getting-started/api/) before.
56
+ - [Documentation](https://docs.codecarbon.io) to learn how to use the package and our methodology.
57
57
  - [GitHub](https://github.com/mlco2/codecarbon) to look at the source code and contribute.
58
58
  - [Discord](https://discord.gg/GS9js2XkJR) to chat with us.
59
59
 
@@ -99,7 +99,7 @@ We created a Python package that estimates your hardware electricity power consu
99
99
 
100
100
  ![calculation Summary](docs/images/calculation.png)
101
101
 
102
- We explain more about this calculation in the [**Methodology**](https://mlco2.github.io/codecarbon/methodology.html#) section of the documentation.
102
+ We explain more about this calculation in the [**Methodology**](https://docs.codecarbon.io/latest/introduction/methodology/) section of the documentation.
103
103
 
104
104
  Our hope is that this package will be used widely for estimating the carbon footprint of computing, and for establishing best practices with regards to the disclosure and reduction of this footprint.
105
105
 
@@ -121,7 +121,7 @@ conda activate your_env
121
121
  pip install codecarbon
122
122
  ```
123
123
 
124
- To see more installation options please refer to the documentation: [**Installation**](https://mlco2.github.io/codecarbon/installation.html#)
124
+ To see more installation options please refer to the documentation: [**Installation**](https://docs.codecarbon.io/latest/getting-started/installation/)
125
125
 
126
126
  ## Start to estimate your impact 📏
127
127
 
@@ -175,7 +175,7 @@ def your_function_to_track():
175
175
  ```
176
176
  The package will track the emissions generated by the execution of your function.
177
177
 
178
- There is other ways to use **codecarbon** package, please refer to the documentation to learn more about it: [**Usage**](https://mlco2.github.io/codecarbon/usage.html#)
178
+ There is other ways to use **codecarbon** package, please refer to the documentation to learn more about it: [**Usage**](https://docs.codecarbon.io/latest/getting-started/usage/)
179
179
 
180
180
  ## Visualize 📊
181
181
 
@@ -189,7 +189,7 @@ You can now visualize your experiment emissions on the [dashboard](https://dashb
189
189
  > - cloud mode
190
190
  > - comet integration...
191
191
  >
192
- > Please explore the [**Documentation**](https://mlco2.github.io/codecarbon) to learn about it
192
+ > Please explore the [**Documentation**](https://docs.codecarbon.io/) to learn about it
193
193
  > If ever what your are looking for is not yet implemented, let us know through the *issues* and even better become one of our 🦸🏼‍♀️🦸🏼‍♂️ contributors! more info 👇🏼
194
194
 
195
195
 
@@ -201,7 +201,7 @@ You are welcome to open issues, even suggest solutions and better still contribu
201
201
 
202
202
  In order to contribute a change to our code base, please submit a pull request (PR) via GitHub and someone from our team will go over it and accept it.
203
203
 
204
- Check out our [contribution guidelines :arrow_upper_right:](https://github.com/mlco2/codecarbon/blob/master/CONTRIBUTING.md)
204
+ Check out our [contribution guidelines :arrow_upper_right:](https://github.com/mlco2/codecarbon/blob/master/docs/contributing/CONTRIBUTING.md)
205
205
 
206
206
  Feel free to chat with us on [Discord](https://discord.gg/GS9js2XkJR).
207
207
 
@@ -4,8 +4,8 @@ Estimate and track carbon emissions from your computer, quantify and analyze the
4
4
 
5
5
  CodeCarbon websites:
6
6
  - [Main website](https://codecarbon.io) to learn why we do this.
7
- - [Dashboard](https://dashboard.codecarbon.io/) to see your emissions, [read the API doc](https://mlco2.github.io/codecarbon/api.html) before.
8
- - [Documentation](https://mlco2.github.io/codecarbon) to learn how to use the package and our methodology.
7
+ - [Dashboard](https://dashboard.codecarbon.io/) to see your emissions, [read the API doc](https://docs.codecarbon.io/latest/getting-started/api/) before.
8
+ - [Documentation](https://docs.codecarbon.io) to learn how to use the package and our methodology.
9
9
  - [GitHub](https://github.com/mlco2/codecarbon) to look at the source code and contribute.
10
10
  - [Discord](https://discord.gg/GS9js2XkJR) to chat with us.
11
11
 
@@ -51,7 +51,7 @@ We created a Python package that estimates your hardware electricity power consu
51
51
 
52
52
  ![calculation Summary](docs/images/calculation.png)
53
53
 
54
- We explain more about this calculation in the [**Methodology**](https://mlco2.github.io/codecarbon/methodology.html#) section of the documentation.
54
+ We explain more about this calculation in the [**Methodology**](https://docs.codecarbon.io/latest/introduction/methodology/) section of the documentation.
55
55
 
56
56
  Our hope is that this package will be used widely for estimating the carbon footprint of computing, and for establishing best practices with regards to the disclosure and reduction of this footprint.
57
57
 
@@ -73,7 +73,7 @@ conda activate your_env
73
73
  pip install codecarbon
74
74
  ```
75
75
 
76
- To see more installation options please refer to the documentation: [**Installation**](https://mlco2.github.io/codecarbon/installation.html#)
76
+ To see more installation options please refer to the documentation: [**Installation**](https://docs.codecarbon.io/latest/getting-started/installation/)
77
77
 
78
78
  ## Start to estimate your impact 📏
79
79
 
@@ -127,7 +127,7 @@ def your_function_to_track():
127
127
  ```
128
128
  The package will track the emissions generated by the execution of your function.
129
129
 
130
- There is other ways to use **codecarbon** package, please refer to the documentation to learn more about it: [**Usage**](https://mlco2.github.io/codecarbon/usage.html#)
130
+ There is other ways to use **codecarbon** package, please refer to the documentation to learn more about it: [**Usage**](https://docs.codecarbon.io/latest/getting-started/usage/)
131
131
 
132
132
  ## Visualize 📊
133
133
 
@@ -141,7 +141,7 @@ You can now visualize your experiment emissions on the [dashboard](https://dashb
141
141
  > - cloud mode
142
142
  > - comet integration...
143
143
  >
144
- > Please explore the [**Documentation**](https://mlco2.github.io/codecarbon) to learn about it
144
+ > Please explore the [**Documentation**](https://docs.codecarbon.io/) to learn about it
145
145
  > If ever what your are looking for is not yet implemented, let us know through the *issues* and even better become one of our 🦸🏼‍♀️🦸🏼‍♂️ contributors! more info 👇🏼
146
146
 
147
147
 
@@ -153,7 +153,7 @@ You are welcome to open issues, even suggest solutions and better still contribu
153
153
 
154
154
  In order to contribute a change to our code base, please submit a pull request (PR) via GitHub and someone from our team will go over it and accept it.
155
155
 
156
- Check out our [contribution guidelines :arrow_upper_right:](https://github.com/mlco2/codecarbon/blob/master/CONTRIBUTING.md)
156
+ Check out our [contribution guidelines :arrow_upper_right:](https://github.com/mlco2/codecarbon/blob/master/docs/contributing/CONTRIBUTING.md)
157
157
 
158
158
  Feel free to chat with us on [Discord](https://discord.gg/GS9js2XkJR).
159
159
 
@@ -0,0 +1 @@
1
+ __version__ = "3.2.6"
@@ -5,6 +5,8 @@ from typing import Optional
5
5
  import typer
6
6
  from rich.prompt import Confirm
7
7
 
8
+ from codecarbon.core.config import get_hierarchical_config
9
+
8
10
 
9
11
  def get_config(path: Optional[Path] = None):
10
12
  p = path or Path.cwd().resolve() / ".codecarbon.config"
@@ -37,22 +39,16 @@ def get_api_endpoint(path: Optional[Path] = None):
37
39
  return "https://api.codecarbon.io"
38
40
 
39
41
 
40
- def get_existing_local_exp_id(path: Optional[Path] = None):
41
- p = path or Path.cwd().resolve() / ".codecarbon.config"
42
- if p.exists():
43
- existing_path = p
44
- else:
45
- existing_path = Path("~/.codecarbon.config").expanduser()
46
- return _get_local_exp_id(existing_path)
47
-
48
-
49
- def _get_local_exp_id(p: Optional[Path] = None):
50
- config = configparser.ConfigParser()
51
- config.read(str(p))
52
- if "codecarbon" in config.sections():
53
- d = dict(config["codecarbon"])
54
- if "experiment_id" in d:
55
- return d["experiment_id"]
42
+ def get_existing_exp_id() -> Optional[str]:
43
+ """
44
+ Return experiment_id resolved from the same hierarchical config strategy
45
+ used by EmissionsTracker (global file, local file, then CODECARBON_* env).
46
+ """
47
+ try:
48
+ conf = get_hierarchical_config()
49
+ except KeyError:
50
+ return None
51
+ return conf.get("experiment_id")
56
52
 
57
53
 
58
54
  def write_local_exp_id(exp_id, path: Optional[Path] = None):
@@ -18,7 +18,7 @@ from codecarbon.cli.cli_utils import (
18
18
  create_new_config_file,
19
19
  get_api_endpoint,
20
20
  get_config,
21
- get_existing_local_exp_id,
21
+ get_existing_exp_id,
22
22
  overwrite_local_config,
23
23
  )
24
24
  from codecarbon.cli.monitor import run_and_monitor
@@ -114,7 +114,8 @@ def api_get():
114
114
  """
115
115
  ex: test-api
116
116
  """
117
- api = ApiClient(endpoint_url=API_URL) # TODO: get endpoint from config
117
+ api_endpoint = get_api_endpoint()
118
+ api = ApiClient(endpoint_url=api_endpoint)
118
119
  api.set_access_token(get_access_token())
119
120
  organizations = api.get_list_organizations()
120
121
  print(organizations)
@@ -123,15 +124,18 @@ def api_get():
123
124
  @codecarbon.command("login", short_help="Login to CodeCarbon")
124
125
  def login():
125
126
  authorize()
126
- api = ApiClient(endpoint_url=API_URL) # TODO: get endpoint from config
127
+ api_endpoint = get_api_endpoint()
128
+ api = ApiClient(endpoint_url=api_endpoint)
127
129
  access_token = get_access_token()
128
130
  api.set_access_token(access_token)
129
131
  api.check_auth()
130
132
 
131
133
 
132
134
  def get_api_key(project_id: str):
135
+ api_endpoint = get_api_endpoint()
136
+ api_endpoint = api_endpoint.rstrip("/")
133
137
  req = requests.post(
134
- f"{API_URL}/projects/{project_id}/api-tokens",
138
+ f"{api_endpoint}/projects/{project_id}/api-tokens",
135
139
  json={
136
140
  "project_id": project_id,
137
141
  "name": "api token",
@@ -306,7 +310,7 @@ def config():
306
310
  overwrite_local_config("api_key", api_key, path=file_path)
307
311
  show_config(file_path)
308
312
  print(
309
- "Consult [link=https://mlco2.github.io/codecarbon/usage.html#configuration]configuration documentation[/link] for more configuration options"
313
+ "Consult [link=https://docs.codecarbon.io/latest/getting-started/usage/#configuration]configuration documentation[/link] for more configuration options"
310
314
  )
311
315
 
312
316
 
@@ -318,20 +322,25 @@ def config():
318
322
  def monitor(
319
323
  ctx: typer.Context,
320
324
  measure_power_secs: Annotated[
321
- int, typer.Option(help="Interval between two measures.")
325
+ int,
326
+ typer.Option(help="Interval between two measures."),
322
327
  ] = 10,
323
328
  api_call_interval: Annotated[
324
- int, typer.Option(help="Number of measures between API calls.")
329
+ int,
330
+ typer.Option(help="Number of measures between API calls."),
325
331
  ] = 30,
326
332
  api: Annotated[
327
- bool, typer.Option(help="Choose to call Code Carbon API or not")
333
+ bool,
334
+ typer.Option(help="Choose to call Code Carbon API or not"),
328
335
  ] = True,
329
336
  offline: Annotated[bool, typer.Option(help="Run in offline mode")] = False,
330
337
  country_iso_code: Annotated[
331
- str, typer.Option(help="3-letter country ISO code for offline mode")
338
+ str,
339
+ typer.Option(help="3-letter country ISO code for offline mode"),
332
340
  ] = None,
333
341
  region: Annotated[
334
- str, typer.Option(help="Region/province for offline mode")
342
+ str,
343
+ typer.Option(help="Region/province for offline mode"),
335
344
  ] = None,
336
345
  ):
337
346
  """Monitor your machine's carbon emissions."""
@@ -356,10 +365,10 @@ def monitor(
356
365
  "region": region,
357
366
  }
358
367
  else:
359
- experiment_id = get_existing_local_exp_id()
368
+ experiment_id = get_existing_exp_id()
360
369
  if api and experiment_id is None:
361
370
  print(
362
- "ERROR: No experiment id, call 'codecarbon config' first. Or run in offline mode with `--offline --country-iso-code FRA` flag if you don't want to connect to the API.",
371
+ "ERROR: No experiment id. Set CODECARBON_EXPERIMENT_ID, call 'codecarbon config' first, or run in offline mode with `--offline --country-iso-code FRA`.",
363
372
  file=sys.stderr,
364
373
  )
365
374
  raise typer.Exit(1)
@@ -14,7 +14,8 @@ from codecarbon.emissions_tracker import EmissionsTracker
14
14
  def run_and_monitor(
15
15
  ctx: typer.Context,
16
16
  log_level: Annotated[
17
- str, typer.Option(help="Log level (critical, error, warning, info, debug)")
17
+ str,
18
+ typer.Option(help="Log level (critical, error, warning, info, debug)"),
18
19
  ] = "error",
19
20
  **tracker_args,
20
21
  ):
@@ -58,7 +58,7 @@ def _has_powermetrics_sudo() -> bool:
58
58
  """Not using PowerMetrics, sudo password prompt detected.
59
59
  If you want to enable Powermetrics please modify your sudoers file
60
60
  as described in :
61
- https://mlco2.github.io/codecarbon/methodology.html#power-usage
61
+ https://docs.codecarbon.io/latest/introduction/methodology/#power-usage
62
62
  """
63
63
  )
64
64
  return False
@@ -978,9 +978,10 @@ class BaseEmissionsTracker(ABC):
978
978
  if isinstance(hardware, GPU):
979
979
  gpu_ids_to_monitor = hardware.gpu_ids
980
980
  gpu_details = hardware.devices.get_gpu_details()
981
- for gpu_detail in gpu_details:
981
+ for gpu_index, gpu_detail in enumerate(gpu_details):
982
+ resolved_gpu_index = gpu_detail.get("gpu_index", gpu_index)
982
983
  if (
983
- gpu_detail["gpu_index"] in gpu_ids_to_monitor
984
+ resolved_gpu_index in gpu_ids_to_monitor
984
985
  and "gpu_utilization" in gpu_detail
985
986
  ):
986
987
  self._gpu_utilization_history.append(
@@ -377,12 +377,12 @@ class CPU(BaseHardware):
377
377
 
378
378
  def total_power(self) -> Power:
379
379
  self._power_history.append(self._get_power_from_cpus())
380
- if len(self._power_history) == 0:
381
- logger.warning("Power history is empty, returning 0 W")
382
- return Power.from_watts(0)
383
380
  power_history_in_W = [power.W for power in self._power_history]
384
- cpu_power = sum(power_history_in_W) / len(power_history_in_W)
385
381
  self._power_history = []
382
+ if not power_history_in_W:
383
+ logger.warning("No power samples collected, returning 0 W")
384
+ return Power.from_watts(0)
385
+ cpu_power = sum(power_history_in_W) / len(power_history_in_W)
386
386
  return Power.from_watts(cpu_power)
387
387
 
388
388
  def measure_power_and_energy(self, last_duration: float) -> Tuple[Power, Energy]:
@@ -24,7 +24,7 @@ class RAM(BaseHardware):
24
24
  In V3, we need to improve the accuracy of the RAM power estimation.
25
25
  Because the power consumption of RAM is not linear with the amount of memory used,
26
26
 
27
- See https://mlco2.github.io/codecarbon/methodology.html#ram for details on the RAM
27
+ See https://docs.codecarbon.io/latest/introduction/methodology/#ram for details on the RAM
28
28
  power estimation methodology.
29
29
 
30
30
  """
@@ -4,6 +4,9 @@ Provides functionality for persistence of data
4
4
 
5
5
  from codecarbon.output_methods.base_output import BaseOutput # noqa: F401
6
6
 
7
+ # Output to BoAmps format
8
+ from codecarbon.output_methods.boamps import BoAmpsOutput # noqa: F401
9
+
7
10
  # emissions data
8
11
  from codecarbon.output_methods.emissions_data import ( # noqa: F401
9
12
  EmissionsData,
@@ -0,0 +1,25 @@
1
+ """
2
+ BoAmps output support for CodeCarbon.
3
+
4
+ Provides first-class support for generating BoAmps (Boavizta) standardized
5
+ JSON reports from CodeCarbon emission tracking data.
6
+ """
7
+
8
+ from codecarbon.output_methods.boamps.mapper import ( # noqa: F401
9
+ map_emissions_to_boamps,
10
+ )
11
+ from codecarbon.output_methods.boamps.models import ( # noqa: F401
12
+ BoAmpsAlgorithm,
13
+ BoAmpsDataset,
14
+ BoAmpsEnvironment,
15
+ BoAmpsHardware,
16
+ BoAmpsHeader,
17
+ BoAmpsInfrastructure,
18
+ BoAmpsMeasure,
19
+ BoAmpsPublisher,
20
+ BoAmpsReport,
21
+ BoAmpsSoftware,
22
+ BoAmpsSystem,
23
+ BoAmpsTask,
24
+ )
25
+ from codecarbon.output_methods.boamps.output import BoAmpsOutput # noqa: F401
@@ -0,0 +1,260 @@
1
+ """
2
+ Maps CodeCarbon EmissionsData to BoAmps report format.
3
+ """
4
+
5
+ import warnings
6
+ from dataclasses import fields as dataclass_fields
7
+ from dataclasses import replace
8
+ from typing import Optional
9
+
10
+ from codecarbon.output_methods.boamps.models import (
11
+ BoAmpsEnvironment,
12
+ BoAmpsHardware,
13
+ BoAmpsHeader,
14
+ BoAmpsInfrastructure,
15
+ BoAmpsMeasure,
16
+ BoAmpsReport,
17
+ BoAmpsSoftware,
18
+ BoAmpsSystem,
19
+ BoAmpsTask,
20
+ )
21
+ from codecarbon.output_methods.emissions_data import EmissionsData
22
+
23
+ BOAMPS_FORMAT_VERSION = "0.1"
24
+ BOAMPS_FORMAT_SPEC_URI = "https://github.com/Boavizta/BoAmps/tree/main/model"
25
+
26
+
27
+ def _to_boamps_datetime(timestamp: str) -> str:
28
+ """Normalize a timestamp to BoAmps format (YYYY-MM-DD HH:MM:SS)."""
29
+ return timestamp.replace("T", " ") if timestamp else timestamp
30
+
31
+
32
+ def map_emissions_to_boamps(
33
+ emissions: EmissionsData,
34
+ task: Optional[BoAmpsTask] = None,
35
+ header: Optional[BoAmpsHeader] = None,
36
+ quality: Optional[str] = None,
37
+ infra_overrides: Optional[dict] = None,
38
+ environment_overrides: Optional[dict] = None,
39
+ ) -> BoAmpsReport:
40
+ """
41
+ Map CodeCarbon EmissionsData to a BoAmps report.
42
+
43
+ Auto-fills fields from EmissionsData and merges with user-provided context.
44
+ User-provided values take precedence over auto-detected values.
45
+
46
+ Args:
47
+ emissions: CodeCarbon emissions data from a completed run.
48
+ task: User-provided task context (required for schema-valid BoAmps).
49
+ header: User-provided header overrides.
50
+ quality: Quality assessment ("high", "medium", "low").
51
+ infra_overrides: Additional infrastructure fields (cloud_instance, cloud_service).
52
+ environment_overrides: Additional environment fields (power_source, etc.).
53
+
54
+ Returns:
55
+ A BoAmpsReport populated with auto-detected and user-provided data.
56
+ """
57
+ report_header = _build_header(emissions, header)
58
+ measures = [_build_measure(emissions)]
59
+ system = _build_system(emissions)
60
+ software = _build_software(emissions)
61
+ infrastructure = _build_infrastructure(emissions, infra_overrides)
62
+ environment = _build_environment(emissions, environment_overrides)
63
+
64
+ if task is None:
65
+ warnings.warn(
66
+ "No BoAmps task context provided. The output will be missing required "
67
+ "fields (taskStage, taskFamily, algorithms, dataset) and will not "
68
+ "validate against the BoAmps schema.",
69
+ UserWarning,
70
+ stacklevel=2,
71
+ )
72
+
73
+ return BoAmpsReport(
74
+ header=report_header,
75
+ task=task,
76
+ measures=measures,
77
+ system=system,
78
+ software=software,
79
+ infrastructure=infrastructure,
80
+ environment=environment,
81
+ quality=quality,
82
+ )
83
+
84
+
85
+ def _build_header(
86
+ emissions: EmissionsData, user_header: Optional[BoAmpsHeader]
87
+ ) -> BoAmpsHeader:
88
+ """Build header from EmissionsData, merging with user overrides."""
89
+ auto_header = BoAmpsHeader(
90
+ format_version=BOAMPS_FORMAT_VERSION,
91
+ format_version_specification_uri=BOAMPS_FORMAT_SPEC_URI,
92
+ report_id=emissions.run_id,
93
+ report_datetime=_to_boamps_datetime(emissions.timestamp),
94
+ )
95
+
96
+ if user_header is None:
97
+ return auto_header
98
+
99
+ # User values override auto-detected values
100
+ return BoAmpsHeader(
101
+ licensing=user_header.licensing or auto_header.licensing,
102
+ format_version=user_header.format_version or auto_header.format_version,
103
+ format_version_specification_uri=(
104
+ user_header.format_version_specification_uri
105
+ or auto_header.format_version_specification_uri
106
+ ),
107
+ report_id=user_header.report_id or auto_header.report_id,
108
+ report_datetime=user_header.report_datetime or auto_header.report_datetime,
109
+ report_status=user_header.report_status or auto_header.report_status,
110
+ publisher=user_header.publisher or auto_header.publisher,
111
+ )
112
+
113
+
114
+ def _build_measure(emissions: EmissionsData) -> BoAmpsMeasure:
115
+ """Build a BoAmps measure from EmissionsData."""
116
+ # Note: emissions.tracking_mode is "process"/"machine" (CodeCarbon's scope),
117
+ # not the CPU/GPU power tracking method (rapl, nvml, etc.) that BoAmps expects
118
+ # for cpuTrackingMode/gpuTrackingMode. We omit these fields since we don't
119
+ # have the actual tracker implementation details in EmissionsData.
120
+ measure = BoAmpsMeasure(
121
+ measurement_method="codecarbon",
122
+ version=emissions.codecarbon_version,
123
+ power_consumption=emissions.energy_consumed,
124
+ measurement_duration=emissions.duration,
125
+ measurement_date_time=_to_boamps_datetime(emissions.timestamp),
126
+ )
127
+
128
+ # CPU utilization as fraction (0-1)
129
+ if emissions.cpu_utilization_percent > 0:
130
+ measure.average_utilization_cpu = round(
131
+ emissions.cpu_utilization_percent / 100.0, 4
132
+ )
133
+
134
+ # GPU fields only if GPU is present
135
+ if emissions.gpu_count and emissions.gpu_count > 0:
136
+ if emissions.gpu_utilization_percent > 0:
137
+ measure.average_utilization_gpu = round(
138
+ emissions.gpu_utilization_percent / 100.0, 4
139
+ )
140
+
141
+ return measure
142
+
143
+
144
+ def _build_system(emissions: EmissionsData) -> BoAmpsSystem:
145
+ """Build system info from EmissionsData."""
146
+ return BoAmpsSystem(os=emissions.os)
147
+
148
+
149
+ def _build_software(emissions: EmissionsData) -> BoAmpsSoftware:
150
+ """Build software info from EmissionsData."""
151
+ return BoAmpsSoftware(
152
+ language="python",
153
+ version=emissions.python_version,
154
+ )
155
+
156
+
157
+ def _build_infrastructure(
158
+ emissions: EmissionsData, overrides: Optional[dict] = None
159
+ ) -> BoAmpsInfrastructure:
160
+ """Build infrastructure from EmissionsData hardware fields."""
161
+ components = []
162
+
163
+ # CPU component (always present)
164
+ # emissions.cpu_count is logical thread count. BoAmps nbComponent expects
165
+ # physical cores. Standard SMT/HT uses 2 threads per core.
166
+ cpu_cores = max(1, int(emissions.cpu_count) // 2) if emissions.cpu_count else 1
167
+ cpu_component = BoAmpsHardware(
168
+ component_type="cpu",
169
+ component_name=emissions.cpu_model,
170
+ nb_component=cpu_cores,
171
+ )
172
+ components.append(cpu_component)
173
+
174
+ # GPU component (only if present)
175
+ if emissions.gpu_count and emissions.gpu_count > 0:
176
+ gpu_component = BoAmpsHardware(
177
+ component_type="gpu",
178
+ component_name=emissions.gpu_model if emissions.gpu_model else None,
179
+ nb_component=int(emissions.gpu_count),
180
+ )
181
+ components.append(gpu_component)
182
+
183
+ # RAM component (always present)
184
+ ram_component = BoAmpsHardware(
185
+ component_type="ram",
186
+ nb_component=1,
187
+ memory_size=emissions.ram_total_size,
188
+ )
189
+ components.append(ram_component)
190
+
191
+ # emissions.on_cloud can be "N" even on public cloud (the tracker clears
192
+ # cloud_provider/region for some providers). Use cloud_provider as a
193
+ # secondary signal to avoid misreporting cloud runs as on-premise.
194
+ is_cloud = emissions.on_cloud == "Y" or bool(emissions.cloud_provider)
195
+ infra = BoAmpsInfrastructure(
196
+ infra_type="publicCloud" if is_cloud else "onPremise",
197
+ cloud_provider=(
198
+ emissions.cloud_provider if is_cloud and emissions.cloud_provider else None
199
+ ),
200
+ components=components,
201
+ )
202
+
203
+ # Apply overrides from context file
204
+ if overrides:
205
+ for attr in ("cloud_instance", "cloud_service", "infra_type"):
206
+ if attr in overrides:
207
+ setattr(infra, attr, overrides[attr])
208
+
209
+ # Merge user-provided components: enrich auto-detected components
210
+ # with user-supplied details (manufacturer, family, series, share, etc.)
211
+ # by matching on component_type. Extra user components are appended.
212
+ if "components" in overrides:
213
+ user_components = overrides["components"]
214
+ auto_by_type = {c.component_type: c for c in infra.components}
215
+ merged = []
216
+ used_types = set()
217
+ for user_comp in user_components:
218
+ if user_comp.component_type in auto_by_type:
219
+ auto = auto_by_type[user_comp.component_type]
220
+ # Build a merged copy: user values take precedence,
221
+ # auto-detected fill blanks. Avoids mutating the originals.
222
+ fill = {
223
+ f.name: getattr(auto, f.name)
224
+ for f in dataclass_fields(user_comp)
225
+ if f.name != "component_type"
226
+ and getattr(user_comp, f.name) is None
227
+ }
228
+ user_comp = replace(user_comp, **fill) if fill else user_comp
229
+ used_types.add(user_comp.component_type)
230
+ merged.append(user_comp)
231
+ # Keep auto-detected components that the user didn't override
232
+ for auto in infra.components:
233
+ if auto.component_type not in used_types:
234
+ merged.append(auto)
235
+ infra.components = merged
236
+
237
+ return infra
238
+
239
+
240
+ def _build_environment(
241
+ emissions: EmissionsData, overrides: Optional[dict] = None
242
+ ) -> BoAmpsEnvironment:
243
+ """Build environment from EmissionsData location fields."""
244
+ env = BoAmpsEnvironment(
245
+ country=emissions.country_name,
246
+ latitude=emissions.latitude,
247
+ longitude=emissions.longitude,
248
+ )
249
+
250
+ if overrides:
251
+ for attr in (
252
+ "location",
253
+ "power_supplier_type",
254
+ "power_source",
255
+ "power_source_carbon_intensity",
256
+ ):
257
+ if attr in overrides:
258
+ setattr(env, attr, overrides[attr])
259
+
260
+ return env