codecarbon 2.1.3__tar.gz → 2.2.0__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 (103) hide show
  1. codecarbon-2.2.0/PKG-INFO +140 -0
  2. codecarbon-2.2.0/README.md +125 -0
  3. {codecarbon-2.1.3 → codecarbon-2.2.0}/carbonserver/carbonserver/api/errors.py +8 -0
  4. {codecarbon-2.1.3 → codecarbon-2.2.0}/carbonserver/carbonserver/api/routers/authenticate.py +4 -5
  5. {codecarbon-2.1.3 → codecarbon-2.2.0}/carbonserver/carbonserver/api/routers/experiments.py +0 -1
  6. {codecarbon-2.1.3 → codecarbon-2.2.0}/carbonserver/carbonserver/api/routers/runs.py +11 -5
  7. {codecarbon-2.1.3 → codecarbon-2.2.0}/carbonserver/carbonserver/api/schemas.py +16 -9
  8. {codecarbon-2.1.3 → codecarbon-2.2.0}/carbonserver/container.py +0 -1
  9. {codecarbon-2.1.3 → codecarbon-2.2.0}/carbonserver/main.py +4 -2
  10. {codecarbon-2.1.3 → codecarbon-2.2.0}/codecarbon/__init__.py +1 -2
  11. codecarbon-2.2.0/codecarbon/_version.py +1 -0
  12. {codecarbon-2.1.3 → codecarbon-2.2.0}/codecarbon/cli/main.py +2 -1
  13. {codecarbon-2.1.3 → codecarbon-2.2.0}/codecarbon/core/api_client.py +9 -2
  14. {codecarbon-2.1.3 → codecarbon-2.2.0}/codecarbon/core/cloud.py +4 -6
  15. {codecarbon-2.1.3 → codecarbon-2.2.0}/codecarbon/core/cpu.py +23 -21
  16. codecarbon-2.2.0/codecarbon/core/rapl.py +54 -0
  17. {codecarbon-2.1.3 → codecarbon-2.2.0}/codecarbon/core/schemas.py +1 -0
  18. {codecarbon-2.1.3 → codecarbon-2.2.0}/codecarbon/core/util.py +1 -3
  19. {codecarbon-2.1.3 → codecarbon-2.2.0}/codecarbon/data/hardware/cpu_power.csv +9 -0
  20. {codecarbon-2.1.3 → codecarbon-2.2.0}/codecarbon/data/private_infra/global_energy_mix.json +1 -1
  21. {codecarbon-2.1.3 → codecarbon-2.2.0}/codecarbon/emissions_tracker.py +63 -51
  22. {codecarbon-2.1.3 → codecarbon-2.2.0}/codecarbon/external/geography.py +11 -6
  23. {codecarbon-2.1.3 → codecarbon-2.2.0}/codecarbon/external/hardware.py +3 -7
  24. {codecarbon-2.1.3 → codecarbon-2.2.0}/codecarbon/external/logger.py +0 -1
  25. {codecarbon-2.1.3 → codecarbon-2.2.0}/codecarbon/external/scheduler.py +1 -1
  26. {codecarbon-2.1.3 → codecarbon-2.2.0}/codecarbon/output.py +3 -2
  27. {codecarbon-2.1.3 → codecarbon-2.2.0}/codecarbon/viz/carbonboard.py +2 -4
  28. {codecarbon-2.1.3 → codecarbon-2.2.0}/codecarbon/viz/carbonboard_on_api.py +2 -4
  29. {codecarbon-2.1.3 → codecarbon-2.2.0}/codecarbon/viz/components.py +30 -31
  30. {codecarbon-2.1.3 → codecarbon-2.2.0}/codecarbon/viz/data.py +11 -14
  31. codecarbon-2.2.0/codecarbon.egg-info/PKG-INFO +140 -0
  32. {codecarbon-2.1.3 → codecarbon-2.2.0}/codecarbon.egg-info/SOURCES.txt +20 -1
  33. {codecarbon-2.1.3 → codecarbon-2.2.0}/codecarbon.egg-info/requires.txt +6 -1
  34. {codecarbon-2.1.3 → codecarbon-2.2.0}/setup.py +7 -2
  35. codecarbon-2.2.0/tests/test_api_call.py +92 -0
  36. codecarbon-2.2.0/tests/test_cloud.py +73 -0
  37. codecarbon-2.2.0/tests/test_co2_signal.py +47 -0
  38. codecarbon-2.2.0/tests/test_config.py +178 -0
  39. codecarbon-2.2.0/tests/test_core_util.py +17 -0
  40. codecarbon-2.2.0/tests/test_cpu.py +276 -0
  41. codecarbon-2.2.0/tests/test_emissions.py +175 -0
  42. codecarbon-2.2.0/tests/test_emissions_tracker.py +410 -0
  43. codecarbon-2.2.0/tests/test_emissions_tracker_constant.py +101 -0
  44. codecarbon-2.2.0/tests/test_emissions_tracker_flush.py +86 -0
  45. codecarbon-2.2.0/tests/test_energy.py +42 -0
  46. codecarbon-2.2.0/tests/test_geography.py +74 -0
  47. codecarbon-2.2.0/tests/test_gpu.py +217 -0
  48. codecarbon-2.2.0/tests/test_hardware.py +26 -0
  49. codecarbon-2.2.0/tests/test_logging_output.py +101 -0
  50. codecarbon-2.2.0/tests/test_ram.py +36 -0
  51. codecarbon-2.2.0/tests/testdata.py +234 -0
  52. codecarbon-2.2.0/tests/testutils.py +35 -0
  53. codecarbon-2.1.3/PKG-INFO +0 -442
  54. codecarbon-2.1.3/README.md +0 -429
  55. codecarbon-2.1.3/codecarbon/core/rapl.py +0 -53
  56. codecarbon-2.1.3/codecarbon.egg-info/PKG-INFO +0 -442
  57. {codecarbon-2.1.3 → codecarbon-2.2.0}/LICENSE +0 -0
  58. {codecarbon-2.1.3 → codecarbon-2.2.0}/carbonserver/__init__.py +0 -0
  59. {codecarbon-2.1.3 → codecarbon-2.2.0}/carbonserver/carbonserver/__init__.py +0 -0
  60. {codecarbon-2.1.3 → codecarbon-2.2.0}/carbonserver/carbonserver/api/__init__.py +0 -0
  61. {codecarbon-2.1.3 → codecarbon-2.2.0}/carbonserver/carbonserver/api/dependencies.py +0 -0
  62. {codecarbon-2.1.3 → codecarbon-2.2.0}/carbonserver/carbonserver/api/domain/__init__.py +0 -0
  63. {codecarbon-2.1.3 → codecarbon-2.2.0}/carbonserver/carbonserver/api/domain/emissions.py +0 -0
  64. {codecarbon-2.1.3 → codecarbon-2.2.0}/carbonserver/carbonserver/api/domain/experiments.py +0 -0
  65. {codecarbon-2.1.3 → codecarbon-2.2.0}/carbonserver/carbonserver/api/domain/organizations.py +0 -0
  66. {codecarbon-2.1.3 → codecarbon-2.2.0}/carbonserver/carbonserver/api/domain/projects.py +0 -0
  67. {codecarbon-2.1.3 → codecarbon-2.2.0}/carbonserver/carbonserver/api/domain/runs.py +0 -0
  68. {codecarbon-2.1.3 → codecarbon-2.2.0}/carbonserver/carbonserver/api/domain/teams.py +0 -0
  69. {codecarbon-2.1.3 → codecarbon-2.2.0}/carbonserver/carbonserver/api/domain/users.py +0 -0
  70. {codecarbon-2.1.3 → codecarbon-2.2.0}/carbonserver/carbonserver/api/routers/__init__.py +0 -0
  71. {codecarbon-2.1.3 → codecarbon-2.2.0}/carbonserver/carbonserver/api/routers/emissions.py +0 -0
  72. {codecarbon-2.1.3 → codecarbon-2.2.0}/carbonserver/carbonserver/api/routers/organizations.py +0 -0
  73. {codecarbon-2.1.3 → codecarbon-2.2.0}/carbonserver/carbonserver/api/routers/projects.py +0 -0
  74. {codecarbon-2.1.3 → codecarbon-2.2.0}/carbonserver/carbonserver/api/routers/teams.py +0 -0
  75. {codecarbon-2.1.3 → codecarbon-2.2.0}/carbonserver/carbonserver/api/routers/users.py +0 -0
  76. {codecarbon-2.1.3 → codecarbon-2.2.0}/carbonserver/carbonserver/config.py +0 -0
  77. {codecarbon-2.1.3 → codecarbon-2.2.0}/carbonserver/carbonserver/database/__init__.py +0 -0
  78. {codecarbon-2.1.3 → codecarbon-2.2.0}/carbonserver/carbonserver/database/database.py +0 -0
  79. {codecarbon-2.1.3 → codecarbon-2.2.0}/carbonserver/carbonserver/logger.py +0 -0
  80. {codecarbon-2.1.3 → codecarbon-2.2.0}/carbonserver/setup.py +0 -0
  81. {codecarbon-2.1.3 → codecarbon-2.2.0}/codecarbon/cli/__init__.py +0 -0
  82. {codecarbon-2.1.3 → codecarbon-2.2.0}/codecarbon/cli/cli_utils.py +0 -0
  83. {codecarbon-2.1.3 → codecarbon-2.2.0}/codecarbon/core/__init__.py +0 -0
  84. {codecarbon-2.1.3 → codecarbon-2.2.0}/codecarbon/core/co2_signal.py +0 -0
  85. {codecarbon-2.1.3 → codecarbon-2.2.0}/codecarbon/core/config.py +0 -0
  86. {codecarbon-2.1.3 → codecarbon-2.2.0}/codecarbon/core/emissions.py +0 -0
  87. {codecarbon-2.1.3 → codecarbon-2.2.0}/codecarbon/core/gpu.py +0 -0
  88. {codecarbon-2.1.3 → codecarbon-2.2.0}/codecarbon/core/units.py +0 -0
  89. {codecarbon-2.1.3 → codecarbon-2.2.0}/codecarbon/data/cloud/impact.csv +0 -0
  90. {codecarbon-2.1.3 → codecarbon-2.2.0}/codecarbon/data/private_infra/2016/canada_energy_mix.json +0 -0
  91. {codecarbon-2.1.3 → codecarbon-2.2.0}/codecarbon/data/private_infra/2016/usa_emissions.json +0 -0
  92. {codecarbon-2.1.3 → codecarbon-2.2.0}/codecarbon/data/private_infra/carbon_intensity_per_source.json +0 -0
  93. {codecarbon-2.1.3 → codecarbon-2.2.0}/codecarbon/external/__init__.py +0 -0
  94. {codecarbon-2.1.3 → codecarbon-2.2.0}/codecarbon/input.py +0 -0
  95. {codecarbon-2.1.3 → codecarbon-2.2.0}/codecarbon/viz/__init__.py +0 -0
  96. {codecarbon-2.1.3 → codecarbon-2.2.0}/codecarbon/viz/assets/__init__.py +0 -0
  97. {codecarbon-2.1.3 → codecarbon-2.2.0}/codecarbon/viz/assets/car_icon.png +0 -0
  98. {codecarbon-2.1.3 → codecarbon-2.2.0}/codecarbon/viz/assets/house_icon.png +0 -0
  99. {codecarbon-2.1.3 → codecarbon-2.2.0}/codecarbon/viz/assets/tv_icon.png +0 -0
  100. {codecarbon-2.1.3 → codecarbon-2.2.0}/codecarbon.egg-info/dependency_links.txt +0 -0
  101. {codecarbon-2.1.3 → codecarbon-2.2.0}/codecarbon.egg-info/entry_points.txt +0 -0
  102. {codecarbon-2.1.3 → codecarbon-2.2.0}/codecarbon.egg-info/top_level.txt +0 -0
  103. {codecarbon-2.1.3 → codecarbon-2.2.0}/setup.cfg +0 -0
@@ -0,0 +1,140 @@
1
+ Metadata-Version: 2.1
2
+ Name: codecarbon
3
+ Version: 2.2.0
4
+ Author: Mila, DataForGood, BCG GAMMA, Comet.ml, Haverford College
5
+ Classifier: Natural Language :: English
6
+ Classifier: Programming Language :: Python :: 3.7
7
+ Classifier: Programming Language :: Python :: 3.8
8
+ Classifier: Programming Language :: Python :: 3.9
9
+ Classifier: License :: OSI Approved :: MIT License
10
+ Requires-Python: >3.6
11
+ Description-Content-Type: text/markdown
12
+ Provides-Extra: viz
13
+ Provides-Extra: dashboard
14
+ License-File: LICENSE
15
+
16
+ ![banner](docs/edit/images/banner.png)
17
+
18
+ Estimate and track carbon emissions from your computer, quantify and analyze their impact.
19
+
20
+ [**Documentation**](https://mlco2.github.io/codecarbon)
21
+
22
+ <br/>
23
+
24
+ [![](https://anaconda.org/conda-forge/codecarbon/badges/version.svg)](https://anaconda.org/conda-forge/codecarbon)
25
+ [![](https://img.shields.io/pypi/v/codecarbon?color=024758)](https://pypi.org/project/codecarbon/)
26
+ [![DOI](https://zenodo.org/badge/263364731.svg)](https://zenodo.org/badge/latestdoi/263364731)
27
+
28
+
29
+ - [About CodeCarbon 💡](#about-codecarbon-)
30
+ - [Quickstart 🚀](#quickstart-)
31
+ - [Installation 🔧](#installation-)
32
+ - [Start to estimate your impact 📏](#start-to-estimate-your-impact-)
33
+ - [Monitoring your whole machine](#monitoring-your-machine-)
34
+ - [In your python code](#in-your-python-code-)
35
+ - [Visualize](#visualize-)
36
+ - [Contributing 🤝](#contributing-)
37
+ - [Contact 📝](#contact-)
38
+
39
+ # About CodeCarbon 💡
40
+
41
+ **CodeCarbon** started with a quite simple question:
42
+
43
+ **What is the carbon emission impact of my computer program? :shrug:**
44
+
45
+ We found some global data like "computing currently represents roughly 0.5% of the world’s energy consumption" but nothing on our individual/organisation level impact.
46
+
47
+ At **CodeCarbon**, we believe, along with Niels Bohr, that "Nothing exists until it is measured". So we found a way to estimate how much CO<sub>2</sub> we produce while running our code.
48
+
49
+ *How?*
50
+
51
+ We created a Python package that estimates your hardware electricity power consumption (GPU + CPU + RAM) and we apply to it the carbon intensity of the region where the computing is done.
52
+
53
+ ![calculation Summary](docs/edit/images/calculation.png)
54
+
55
+ We explain more about this calculation in the [**Methodology**](https://mlco2.github.io/codecarbon/methodology.html#) section of the documentation.
56
+
57
+ 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.
58
+
59
+ **So ready to "change the world one run at a time"? Let's start with a very quick set up.**
60
+
61
+ # Quickstart 🚀
62
+
63
+ ## Installation 🔧
64
+
65
+ **From PyPI repository**
66
+ ```python
67
+ pip install codecarbon
68
+ ```
69
+
70
+ **From Conda repository**
71
+ ```python
72
+ conda install -c conda-forge codecarbon
73
+ ```
74
+ To see more installation options please refer to the documentation : [**Installation**](https://mlco2.github.io/codecarbon/installation.html#)
75
+
76
+ ## Start to estimate your impact 📏
77
+
78
+ To get an experiment_id enter:
79
+ ```python
80
+ ! codecarbon init
81
+ ```
82
+ You can now store it in a **.codecarbon.config** at the root of your project
83
+ ```python
84
+ [codecarbon]
85
+ log_level = DEBUG
86
+ save_to_api = True
87
+ experiment_id = 2bcbcbb8-850d-4692-af0d-76f6f36d79b2 #the experiment_id you get with init
88
+ ```
89
+ Now you have 2 main options:
90
+
91
+ ### Monitoring your machine 💻
92
+
93
+ In your command prompt use:
94
+ ```codecarbon monitor```
95
+ The package will track your emissions independently from your code.
96
+
97
+ ### In your Python code 🐍
98
+ ```python
99
+ from codecarbon import track_emissions
100
+ @track_emissions()
101
+ def your_function_to_track():
102
+ # your code
103
+ ```
104
+ The package will track the emissions generated by the execution of your function.
105
+
106
+ 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#)
107
+
108
+ ## Visualize 📊
109
+
110
+ You can now visualize your experiment emissions on the [dashboard](https://dashboard.codecarbon.io/).
111
+ ![dashboard](docs/edit/images/dashboard.png)
112
+
113
+ *Note that for now, all emissions data send to codecarbon API are public.*
114
+
115
+ > Hope you enjoy your first steps monitoring your carbon computing impact!
116
+ > Thanks to the incredible codecarbon community 💪🏼 a lot more options are available using *codecarbon* including:
117
+ > - offline mode
118
+ > - cloud mode
119
+ > - comet integration...
120
+ >
121
+ > Please explore the [**Documentation**](https://mlco2.github.io/codecarbon) to learn about it
122
+ > 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 👇🏼
123
+
124
+
125
+ # Contributing 🤝
126
+
127
+ We are hoping that the open-source community will help us edit the code and make it better!
128
+
129
+ You are welcome to open issues, even suggest solutions and better still contribute the fix/improvement! We can guide you if you're not sure where to start but want to help us out 🥇
130
+
131
+ 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.
132
+
133
+ Check out our [contribution guidelines :arrow_upper_right:](https://github.com/mlco2/codecarbon/blob/master/CONTRIBUTING.md)
134
+
135
+ Contact [@vict0rsch](https://github.com/vict0rsch) to be added to our slack workspace if you want to contribute regularly!
136
+
137
+
138
+ # Contact 📝
139
+
140
+ Maintainers are [@vict0rsch](https://github.com/vict0rsch) [@benoit-cty](https://github.com/benoit-cty) and [@SaboniAmine](https://github.com/saboniamine). Codecarbon is developed by volunteers from [**Mila**](http://mila.quebec) and the [**DataForGoodFR**](https://twitter.com/dataforgood_fr) community alongside donated professional time of engineers at [**Comet.ml**](https://comet.ml) and [**BCG GAMMA**](https://www.bcg.com/en-nl/beyond-consulting/bcg-gamma/default).
@@ -0,0 +1,125 @@
1
+ ![banner](docs/edit/images/banner.png)
2
+
3
+ Estimate and track carbon emissions from your computer, quantify and analyze their impact.
4
+
5
+ [**Documentation**](https://mlco2.github.io/codecarbon)
6
+
7
+ <br/>
8
+
9
+ [![](https://anaconda.org/conda-forge/codecarbon/badges/version.svg)](https://anaconda.org/conda-forge/codecarbon)
10
+ [![](https://img.shields.io/pypi/v/codecarbon?color=024758)](https://pypi.org/project/codecarbon/)
11
+ [![DOI](https://zenodo.org/badge/263364731.svg)](https://zenodo.org/badge/latestdoi/263364731)
12
+
13
+
14
+ - [About CodeCarbon 💡](#about-codecarbon-)
15
+ - [Quickstart 🚀](#quickstart-)
16
+ - [Installation 🔧](#installation-)
17
+ - [Start to estimate your impact 📏](#start-to-estimate-your-impact-)
18
+ - [Monitoring your whole machine](#monitoring-your-machine-)
19
+ - [In your python code](#in-your-python-code-)
20
+ - [Visualize](#visualize-)
21
+ - [Contributing 🤝](#contributing-)
22
+ - [Contact 📝](#contact-)
23
+
24
+ # About CodeCarbon 💡
25
+
26
+ **CodeCarbon** started with a quite simple question:
27
+
28
+ **What is the carbon emission impact of my computer program? :shrug:**
29
+
30
+ We found some global data like "computing currently represents roughly 0.5% of the world’s energy consumption" but nothing on our individual/organisation level impact.
31
+
32
+ At **CodeCarbon**, we believe, along with Niels Bohr, that "Nothing exists until it is measured". So we found a way to estimate how much CO<sub>2</sub> we produce while running our code.
33
+
34
+ *How?*
35
+
36
+ We created a Python package that estimates your hardware electricity power consumption (GPU + CPU + RAM) and we apply to it the carbon intensity of the region where the computing is done.
37
+
38
+ ![calculation Summary](docs/edit/images/calculation.png)
39
+
40
+ We explain more about this calculation in the [**Methodology**](https://mlco2.github.io/codecarbon/methodology.html#) section of the documentation.
41
+
42
+ 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.
43
+
44
+ **So ready to "change the world one run at a time"? Let's start with a very quick set up.**
45
+
46
+ # Quickstart 🚀
47
+
48
+ ## Installation 🔧
49
+
50
+ **From PyPI repository**
51
+ ```python
52
+ pip install codecarbon
53
+ ```
54
+
55
+ **From Conda repository**
56
+ ```python
57
+ conda install -c conda-forge codecarbon
58
+ ```
59
+ To see more installation options please refer to the documentation : [**Installation**](https://mlco2.github.io/codecarbon/installation.html#)
60
+
61
+ ## Start to estimate your impact 📏
62
+
63
+ To get an experiment_id enter:
64
+ ```python
65
+ ! codecarbon init
66
+ ```
67
+ You can now store it in a **.codecarbon.config** at the root of your project
68
+ ```python
69
+ [codecarbon]
70
+ log_level = DEBUG
71
+ save_to_api = True
72
+ experiment_id = 2bcbcbb8-850d-4692-af0d-76f6f36d79b2 #the experiment_id you get with init
73
+ ```
74
+ Now you have 2 main options:
75
+
76
+ ### Monitoring your machine 💻
77
+
78
+ In your command prompt use:
79
+ ```codecarbon monitor```
80
+ The package will track your emissions independently from your code.
81
+
82
+ ### In your Python code 🐍
83
+ ```python
84
+ from codecarbon import track_emissions
85
+ @track_emissions()
86
+ def your_function_to_track():
87
+ # your code
88
+ ```
89
+ The package will track the emissions generated by the execution of your function.
90
+
91
+ 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#)
92
+
93
+ ## Visualize 📊
94
+
95
+ You can now visualize your experiment emissions on the [dashboard](https://dashboard.codecarbon.io/).
96
+ ![dashboard](docs/edit/images/dashboard.png)
97
+
98
+ *Note that for now, all emissions data send to codecarbon API are public.*
99
+
100
+ > Hope you enjoy your first steps monitoring your carbon computing impact!
101
+ > Thanks to the incredible codecarbon community 💪🏼 a lot more options are available using *codecarbon* including:
102
+ > - offline mode
103
+ > - cloud mode
104
+ > - comet integration...
105
+ >
106
+ > Please explore the [**Documentation**](https://mlco2.github.io/codecarbon) to learn about it
107
+ > 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 👇🏼
108
+
109
+
110
+ # Contributing 🤝
111
+
112
+ We are hoping that the open-source community will help us edit the code and make it better!
113
+
114
+ You are welcome to open issues, even suggest solutions and better still contribute the fix/improvement! We can guide you if you're not sure where to start but want to help us out 🥇
115
+
116
+ 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.
117
+
118
+ Check out our [contribution guidelines :arrow_upper_right:](https://github.com/mlco2/codecarbon/blob/master/CONTRIBUTING.md)
119
+
120
+ Contact [@vict0rsch](https://github.com/vict0rsch) to be added to our slack workspace if you want to contribute regularly!
121
+
122
+
123
+ # Contact 📝
124
+
125
+ Maintainers are [@vict0rsch](https://github.com/vict0rsch) [@benoit-cty](https://github.com/benoit-cty) and [@SaboniAmine](https://github.com/saboniamine). Codecarbon is developed by volunteers from [**Mila**](http://mila.quebec) and the [**DataForGoodFR**](https://twitter.com/dataforgood_fr) community alongside donated professional time of engineers at [**Comet.ml**](https://comet.ml) and [**BCG GAMMA**](https://www.bcg.com/en-nl/beyond-consulting/bcg-gamma/default).
@@ -2,6 +2,14 @@ from dataclasses import dataclass
2
2
  from enum import Enum
3
3
 
4
4
 
5
+ class EmptyResultException(Exception):
6
+ """
7
+ The request return an empty result.
8
+ """
9
+
10
+ pass
11
+
12
+
5
13
  @dataclass
6
14
  class ErrorBase:
7
15
  code: str
@@ -25,8 +25,7 @@ def auth_user(
25
25
  verified_user = user_service.verify_user(user)
26
26
  if verified_user:
27
27
  return Token(access_token="a", token_type="access")
28
- else:
29
- raise HTTPException(
30
- status_code=status.HTTP_401_UNAUTHORIZED,
31
- detail="Incorrect password or email!",
32
- )
28
+ raise HTTPException(
29
+ status_code=status.HTTP_401_UNAUTHORIZED,
30
+ detail="Incorrect password or email!",
31
+ )
@@ -69,7 +69,6 @@ def read_project_experiments(
69
69
  Provide[ServerContainer.experiment_service]
70
70
  ),
71
71
  ) -> List[Experiment]:
72
-
73
72
  return experiment_service.get_experiments_from_project(project_id)
74
73
 
75
74
 
@@ -1,5 +1,5 @@
1
1
  from datetime import datetime, timedelta
2
- from typing import List, Optional
2
+ from typing import List, Optional, Union
3
3
 
4
4
  import dateutil.relativedelta
5
5
  from container import ServerContainer
@@ -8,11 +8,13 @@ from fastapi import APIRouter, Depends
8
8
  from starlette import status
9
9
 
10
10
  from carbonserver.api.dependencies import get_token_header
11
- from carbonserver.api.schemas import Run, RunCreate, RunReport
11
+ from carbonserver.api.errors import EmptyResultException
12
+ from carbonserver.api.schemas import Empty, Run, RunCreate, RunReport
12
13
  from carbonserver.api.services.run_service import RunService
13
14
  from carbonserver.api.usecases.run.experiment_sum_by_run import (
14
15
  ExperimentSumsByRunUsecase,
15
16
  )
17
+ from carbonserver.logger import logger
16
18
 
17
19
  RUNS_ROUTER_TAGS = ["Runs"]
18
20
 
@@ -105,7 +107,7 @@ def read_experiment_detailed_sums_by_run(
105
107
  "/lastrun/project/{project_id}",
106
108
  tags=RUNS_ROUTER_TAGS,
107
109
  status_code=status.HTTP_200_OK,
108
- response_model=Run,
110
+ response_model=Union[Run, Empty],
109
111
  )
110
112
  @inject
111
113
  def read_project_last_run(
@@ -113,11 +115,15 @@ def read_project_last_run(
113
115
  start_date: Optional[datetime] = None,
114
116
  end_date: Optional[datetime] = None,
115
117
  run_service: RunService = Depends(Provide[ServerContainer.run_service]),
116
- ) -> Run:
118
+ ) -> Union[Run, Empty]:
117
119
  start_date = (
118
120
  start_date
119
121
  if start_date
120
122
  else datetime.now() - dateutil.relativedelta.relativedelta(months=3)
121
123
  )
122
124
  end_date = end_date if end_date else datetime.now() + timedelta(days=1)
123
- return run_service.read_project_last_run(project_id, start_date, end_date)
125
+ try:
126
+ return run_service.read_project_last_run(project_id, start_date, end_date)
127
+ except EmptyResultException as e:
128
+ logger.warning(f"read_project_last_run : {e}")
129
+ return Empty()
@@ -12,7 +12,11 @@ from datetime import datetime
12
12
  from typing import List, Optional
13
13
  from uuid import UUID
14
14
 
15
- from pydantic import BaseModel, EmailStr, Field, SecretStr
15
+ from pydantic import BaseModel, EmailStr, Extra, Field, SecretStr
16
+
17
+
18
+ class Empty(BaseModel, extra=Extra.forbid):
19
+ pass
16
20
 
17
21
 
18
22
  class EmissionBase(BaseModel):
@@ -81,6 +85,7 @@ class RunBase(BaseModel):
81
85
  experiment_id: UUID
82
86
  os: Optional[str]
83
87
  python_version: Optional[str]
88
+ codecarbon_version: Optional[str]
84
89
  cpu_count: Optional[int]
85
90
  cpu_model: Optional[str]
86
91
  gpu_count: Optional[int]
@@ -99,6 +104,7 @@ class RunBase(BaseModel):
99
104
  "experiment_id": "8edb03e1-9a28-452a-9c93-a3b6560136d7",
100
105
  "os": "macOS-10.15.7-x86_64-i386-64bit",
101
106
  "python_version": "3.8.0",
107
+ "codecarbon_version": "2.1.3",
102
108
  "cpu_count": 12,
103
109
  "cpu_model": "Intel(R) Core(TM) i7-8850H CPU @ 2.60GHz",
104
110
  "gpu_count": 4,
@@ -122,8 +128,10 @@ class Run(RunBase):
122
128
 
123
129
 
124
130
  class RunReport(RunBase):
131
+ run_id: UUID
125
132
  timestamp: datetime
126
- emission: float
133
+ experiment_id: Optional[UUID]
134
+ emissions: float
127
135
  cpu_power: float
128
136
  gpu_power: float
129
137
  ram_power: float
@@ -183,9 +191,9 @@ class ExperimentReport(ExperimentBase):
183
191
  country_iso_code: str
184
192
  region: str
185
193
  on_cloud: str
186
- cloud_provider: str
187
- cloud_region: str
188
- emission: float
194
+ cloud_provider: Optional[str] = None
195
+ cloud_region: Optional[str] = None
196
+ emissions: float
189
197
  cpu_power: float
190
198
  gpu_power: float
191
199
  ram_power: float
@@ -198,7 +206,6 @@ class ExperimentReport(ExperimentBase):
198
206
  emissions_count: int
199
207
 
200
208
  class Config:
201
-
202
209
  schema_extra = {
203
210
  "experiment_id": "943b2aa5-9e21-41a9-8a38-562505b4b2aa",
204
211
  "timestamp": "2021-10-07T20:19:27.716693",
@@ -248,11 +255,11 @@ class Project(ProjectBase):
248
255
  experiments: Optional[List[Experiment]] = []
249
256
 
250
257
 
251
- class ProjectReport(ExperimentBase):
258
+ class ProjectReport(ProjectBase):
252
259
  project_id: UUID
253
260
  name: str
254
261
  description: str
255
- emission: float
262
+ emissions: float
256
263
  cpu_power: float
257
264
  gpu_power: float
258
265
  ram_power: float
@@ -319,7 +326,7 @@ class OrganizationReport(OrganizationBase):
319
326
  organization_id: UUID
320
327
  name: str
321
328
  description: str
322
- emission: float
329
+ emissions: float
323
330
  cpu_power: float
324
331
  gpu_power: float
325
332
  ram_power: float
@@ -32,7 +32,6 @@ from carbonserver.config import settings
32
32
 
33
33
 
34
34
  class ServerContainer(containers.DeclarativeContainer):
35
-
36
35
  config = providers.Configuration()
37
36
  db_url = settings.db_url
38
37
  db = providers.Singleton(
@@ -19,6 +19,7 @@ from carbonserver.api.routers import (
19
19
  users,
20
20
  )
21
21
  from carbonserver.database.database import engine
22
+ from carbonserver.logger import logger
22
23
 
23
24
 
24
25
  async def db_exception_handler(request: Request, exc: DBException):
@@ -30,16 +31,17 @@ async def generic_exception_handler(request: Request, exc: Exception):
30
31
 
31
32
 
32
33
  async def validation_exception_handler(request: Request, exc: ValidationError):
34
+ logger.error(f"ValidationError {exc}")
33
35
  return JSONResponse(
34
36
  {
35
- "detail": "Validation error : a data is missing or in wrong format. Could be an error in our answer, not only in your request"
37
+ "detail": "Validation error : a data is missing or in wrong format. Could be an error in our answer, not only in your request",
38
+ "validation_error_message": str(exc),
36
39
  },
37
40
  status_code=400,
38
41
  )
39
42
 
40
43
 
41
44
  def create_app() -> FastAPI:
42
-
43
45
  container = init_container()
44
46
 
45
47
  init_db(container)
@@ -2,6 +2,7 @@
2
2
  The Carbon Tracker module. The following objects/decorators belong to the Public API
3
3
  """
4
4
 
5
+ from ._version import __version__ # noqa
5
6
  from .emissions_tracker import (
6
7
  EmissionsTracker,
7
8
  OfflineEmissionsTracker,
@@ -9,5 +10,3 @@ from .emissions_tracker import (
9
10
  )
10
11
 
11
12
  __all__ = ["EmissionsTracker", "OfflineEmissionsTracker", "track_emissions"]
12
-
13
- __version__ = "2.1.3"
@@ -0,0 +1 @@
1
+ __version__ = "2.2.0"
@@ -1,3 +1,4 @@
1
+ import sys
1
2
  import time
2
3
 
3
4
  import click
@@ -76,7 +77,7 @@ def monitor(measure_power_secs, api_call_interval, api):
76
77
  experiment_id = get_existing_local_exp_id()
77
78
  if api and experiment_id is None:
78
79
  click.echo("ERROR: No experiment id, call 'codecarbon init' first.")
79
- exit(1)
80
+ sys.exit(1)
80
81
  click.echo("CodeCarbon is going in an infinite loop to monitor this machine.")
81
82
  with EmissionsTracker(
82
83
  measure_power_secs=measure_power_secs,
@@ -114,12 +114,14 @@ class ApiClient: # (AsyncClient)
114
114
  experiment_id=experiment_id,
115
115
  os=self.conf.get("os"),
116
116
  python_version=self.conf.get("python_version"),
117
+ codecarbon_version=self.conf.get("codecarbon_version"),
117
118
  cpu_count=self.conf.get("cpu_count"),
118
119
  cpu_model=self.conf.get("cpu_model"),
119
120
  gpu_count=self.conf.get("gpu_count"),
120
121
  gpu_model=self.conf.get("gpu_model"),
121
- longitude=self.conf.get("longitude"),
122
- latitude=self.conf.get("latitude"),
122
+ # Reduce precision for Privacy
123
+ longitude=round(self.conf.get("longitude"), 1),
124
+ latitude=round(self.conf.get("latitude"), 1),
123
125
  region=self.conf.get("region"),
124
126
  provider=self.conf.get("provider"),
125
127
  ram_total_size=self.conf.get("ram_total_size"),
@@ -138,6 +140,11 @@ class ApiClient: # (AsyncClient)
138
140
  + f"Experiment ID: {self.experiment_id}\n"
139
141
  )
140
142
  return self.run_id
143
+ except requests.exceptions.ConnectionError as e:
144
+ logger.error(
145
+ f"Failed to connect to API, please check the configuration. {e}",
146
+ exc_info=False,
147
+ )
141
148
  except Exception as e:
142
149
  logger.error(e, exc_info=True)
143
150
 
@@ -26,7 +26,7 @@ import requests
26
26
  from codecarbon.external.logger import logger
27
27
 
28
28
 
29
- def postprocess_gcp_cloud_metadata(cloud_metadata):
29
+ def postprocess_gcp_cloud_metadata(cloud_metadata: Dict[str, Any]) -> Dict[str, Any]:
30
30
  # type: (Dict[str, Any]) -> Dict[str, Any]
31
31
 
32
32
  # Attributes contains custom metadata and also contains Kubernetes config,
@@ -54,7 +54,7 @@ CLOUD_METADATA_MAPPING: Dict[str, Dict[str, Any]] = {
54
54
  }
55
55
 
56
56
 
57
- def get_env_cloud_details(timeout=1):
57
+ def get_env_cloud_details(timeout: int = 1) -> Optional[Any]:
58
58
  # type: (int) -> Optional[Any]
59
59
  """
60
60
  >>> get_env_cloud_details()
@@ -89,9 +89,7 @@ def get_env_cloud_details(timeout=1):
89
89
  response_data = postprocess_function(response_data)
90
90
 
91
91
  return {"provider": provider, "metadata": response_data}
92
- except Exception as e:
93
- logger.debug(
94
- "Not running on %s, couldn't retrieve metadata: %r", provider, e
95
- )
92
+ except requests.exceptions.RequestException:
93
+ logger.debug("Not running on %s", provider)
96
94
 
97
95
  return None
@@ -200,15 +200,22 @@ class IntelRAPL:
200
200
  if "package" in name:
201
201
  name = f"Processor Energy Delta_{i}(kWh)"
202
202
  i += 1
203
+ # RAPL file to take measurement from
203
204
  rapl_file = os.path.join(self._lin_rapl_dir, file, "energy_uj")
205
+ # RAPL file containing maximum possible value of energy_uj above which it wraps
206
+ rapl_file_max = os.path.join(
207
+ self._lin_rapl_dir, file, "max_energy_range_uj"
208
+ )
204
209
  try:
205
210
  # Try to read the file to be sure we can
206
211
  with open(rapl_file, "r") as f:
207
212
  _ = float(f.read())
208
- self._rapl_files.append(RAPLFile(name=name, path=rapl_file))
213
+ self._rapl_files.append(
214
+ RAPLFile(name=name, path=rapl_file, max_path=rapl_file_max)
215
+ )
209
216
  logger.debug(f"We will read Intel RAPL files at {rapl_file}")
210
217
  except PermissionError as e:
211
- logger.error(
218
+ raise PermissionError(
212
219
  "Unable to read Intel RAPL files for CPU power, we will use a constant for your CPU power."
213
220
  + " Please view https://github.com/mlco2/codecarbon/issues/244"
214
221
  + f" for workarounds : {e}"
@@ -269,8 +276,7 @@ class TDP:
269
276
  if cpu_matching:
270
277
  power = self._get_cpu_constant_power(cpu_matching, cpu_power_df)
271
278
  return power
272
- else:
273
- return None
279
+ return None
274
280
 
275
281
  @staticmethod
276
282
  def _get_cpus(cpu_df, cpu_idxs) -> list:
@@ -341,15 +347,13 @@ class TDP:
341
347
  # Check if an indirect match exists
342
348
  if max_ratio_token_set < THRESHOLD_TOKEN_SET:
343
349
  return None
344
- else:
345
- cpu_idxs = self._get_max_idxs(ratios_token_set, max_ratio_token_set)
346
- cpu_machings = self._get_cpus(cpu_df, cpu_idxs)
350
+ cpu_idxs = self._get_max_idxs(ratios_token_set, max_ratio_token_set)
351
+ cpu_machings = self._get_cpus(cpu_df, cpu_idxs)
347
352
 
348
- if (cpu_machings and len(cpu_machings) == 1) or greedy:
349
- cpu_matched = cpu_machings[0]
350
- return cpu_matched
351
- else:
352
- return None
353
+ if (cpu_machings and len(cpu_machings) == 1) or greedy:
354
+ cpu_matched = cpu_machings[0]
355
+ return cpu_matched
356
+ return None
353
357
 
354
358
  @staticmethod
355
359
  def _get_max_idxs(ratios: list, max_ratio: int) -> list:
@@ -371,17 +375,15 @@ class TDP:
371
375
  f"CPU : We detect a {cpu_model_detected} with a TDP of {power} W"
372
376
  )
373
377
  return cpu_model_detected, power
374
- else:
375
- logger.warning(
376
- f"We saw that you have a {cpu_model_detected} but we don't know it."
377
- + " Please contact us."
378
- )
379
- return cpu_model_detected, None
380
- else:
381
378
  logger.warning(
382
- "We were unable to detect your CPU using the `cpuinfo` package."
383
- + " Resorting to a default power consumption of 85W."
379
+ f"We saw that you have a {cpu_model_detected} but we don't know it."
380
+ + " Please contact us."
384
381
  )
382
+ return cpu_model_detected, None
383
+ logger.warning(
384
+ "We were unable to detect your CPU using the `cpuinfo` package."
385
+ + " Resorting to a default power consumption of 85W."
386
+ )
385
387
  return "Unknown", None
386
388
 
387
389
  def start(self):