Skip to content

Commit dddfedb

Browse files
authored
Merge pull request #21 from codegreen-framework/main
new ver
2 parents ec0aa8b + 097f0c4 commit dddfedb

File tree

7 files changed

+379
-272
lines changed

7 files changed

+379
-272
lines changed

codegreen_core/tools/carbon_emission.py

+2-3
Original file line numberDiff line numberDiff line change
@@ -12,9 +12,8 @@ def compute_ce(
1212
runtime_minutes: int,
1313
) -> tuple[float, pd.DataFrame]:
1414
"""
15-
Calculates the carbon footprint of a job, given its hardware configuration, time, and location.
15+
Calculates the carbon footprint of a job, given the server details , start time and runtime.
1616
This method returns an hourly time series of the carbon emissions.
17-
1817
The methodology is defined in the documentation.
1918
2019
:param server: A dictionary containing the details about the server, including its hardware specifications.
@@ -37,7 +36,7 @@ def compute_ce(
3736
"""
3837

3938
# Round to the nearest hour (in minutes)
40-
# base valued taken from http://calculator.green-algorithms.org/
39+
# base values taken from http://calculator.green-algorithms.org/
4140

4241
rounded_runtime_minutes = round(runtime_minutes / 60) * 60
4342
end_time = start_time + timedelta(minutes=rounded_runtime_minutes)

codegreen_core/utilities/config.py

+51-141
Original file line numberDiff line numberDiff line change
@@ -11,97 +11,24 @@ class Config:
1111
config_file_path = None
1212
section_name = "codegreen"
1313
all_keys = [
14-
{
15-
"name":"ENTSOE_token",
16-
"default": "None",
17-
"use":"To fetch data from ENTSOE portal",
18-
"boolean":False,
19-
},
20-
{
21-
"name":"default_energy_mode",
22-
"default":"public_data",
23-
"use":"Determines which type of data to use.",
24-
"boolean":False,
25-
},
26-
{
27-
"name":"enable_energy_caching",
28-
"default":"False",
29-
"use":"To indicate if data used by tools must be cached",
30-
"boolean":True,
31-
},
32-
{
33-
"name":"energy_redis_path",
34-
"default":"None",
35-
"boolean":False,
36-
"use":"Path to redis server to cache data.required if enable_energy_caching is enabled "
37-
},
38-
{
39-
"name":"enable_time_prediction_logging",
40-
"default":"False",
41-
"boolean":True,
42-
"use":"To indicate if logs must me saved in a log file "
43-
},
44-
{
45-
"name":"log_folder_path",
46-
"default":" ",
47-
"boolean":False,
48-
"use":"Path of the folder where logs will be stored"
49-
},
50-
{
51-
"name":"offline_data_dir_path",
52-
"default":"",
53-
"boolean":False,
54-
"use":"Path of the folder where bulk energy data will be stored"
55-
},
56-
{
57-
"name":"enable_offline_energy_generation",
58-
"default":"False",
59-
"boolean":True,
60-
"use":"To enable storing energy production data for available countries locally and in cache for quick access"
61-
},
62-
{
63-
"name":"offline_data_start_date",
64-
"default":"",
65-
"boolean":False,
66-
"use":"The start date for offline energy generation download,YYYY-mm-dd format"
67-
},
68-
{
69-
"name":"generation_cache_hour",
70-
"default":"72",
71-
"boolean":False,
72-
"use":"Indicate the number of hours in the past the data will be stored in the cache "
73-
},
74-
75-
{
76-
"name":"cron_refresh_offline_files_hour",
77-
"default":"6",
78-
"boolean":False,
79-
"use":"time to setup cron for updating offline energy files"
80-
},
81-
{
82-
"name":"cron_refresh_cache_hour",
83-
"default":"6",
84-
"boolean":False,
85-
"use":"time to setup CRON job to update the energy generation cache"
86-
},
87-
88-
{
89-
"name":"enable_logging",
90-
"default":"False",
91-
"boolean":True,
92-
"use":"Indicates if logging is enabled for the whole package"
93-
},
94-
{
95-
"name":"log_folder_path",
96-
"default":"",
97-
"boolean":False,
98-
"use":"The folder where log files will be stored. Log files name are of the format: 'year-month' "
99-
}
14+
{"name": "ENTSOE_token", "default": "None", "use": "To fetch data from ENTSOE portal", "boolean": False},
15+
{"name": "default_energy_mode", "default": "public_data", "use": "Determines which type of data to use.", "boolean": False},
16+
{"name": "enable_energy_caching", "default": "False", "use": "To indicate if data used by tools must be cached", "boolean": True},
17+
{"name": "energy_redis_path", "default": "None", "boolean": False, "use": "Path to redis server to cache data."},
18+
{"name": "enable_time_prediction_logging", "default": "False", "boolean": True, "use": "To indicate if logs must be saved."},
19+
{"name": "log_folder_path", "default": "", "boolean": False, "use": "Path of the folder where logs will be stored"},
20+
{"name": "offline_data_dir_path", "default": "", "boolean": False, "use": "Path where bulk energy data will be stored"},
21+
{"name": "enable_offline_energy_generation", "default": "False", "boolean": True, "use": "Enable storing energy data locally"},
22+
{"name": "offline_data_start_date", "default": "", "boolean": False, "use": "Start date for offline energy data"},
23+
{"name": "generation_cache_hour", "default": "72", "boolean": False, "use": "Number of hours data will be cached"},
24+
{"name": "cron_refresh_offline_files_hour", "default": "6", "boolean": False, "use": "CRON schedule for updating offline files"},
25+
{"name": "cron_refresh_cache_hour", "default": "6", "boolean": False, "use": "CRON job to update energy cache"},
26+
{"name": "enable_logging", "default": "False", "boolean": True, "use": "Enable logging for the package"}
10027
]
10128

10229
@classmethod
103-
def load_config(self, file_path=None):
104-
"""to load configurations from the user config file"""
30+
def load_config(cls, file_path=None):
31+
"""Load configurations from a config file or environment variables."""
10532
config_file_name = ".codegreencore.config"
10633
config_locations = [
10734
os.path.join(os.path.expanduser("~"), config_file_name),
@@ -111,63 +38,46 @@ def load_config(self, file_path=None):
11138
if os.path.isfile(loc):
11239
file_path = loc
11340
break
41+
cls.config_data = configparser.ConfigParser()
42+
if file_path:
43+
cls.config_data.read(file_path)
44+
cls.config_file_path = file_path
11445

115-
if file_path is None:
116-
raise ConfigError("Could not find the '.codegreencore.config' file. Please ensure that this file is created in the root folder of your project.")
117-
118-
self.config_data = configparser.ConfigParser()
119-
self.config_data.read(file_path)
120-
self.config_file_path = file_path
121-
122-
if self.section_name not in self.config_data:
123-
self.config_data[self.section_name] = {}
124-
raise ConfigError("Invalid config file. The config file must have a section called codegreen")
46+
if cls.section_name not in cls.config_data:
47+
raise ConfigError(f"Invalid config file. Missing required section: {cls.section_name}")
48+
else:
49+
cls.config_data[cls.section_name] = {}
12550

126-
for ky in self.all_keys:
127-
try :
128-
value = self.config_data.get(self.section_name, ky["name"])
129-
# print(value)
130-
except configparser.NoOptionError:
131-
# print(ky)
132-
self.config_data.set(self.section_name, ky["name"],ky["default"])
133-
134-
if self.get("enable_energy_caching") == True:
135-
if self.get("energy_redis_path") is None:
136-
raise ConfigError(
137-
"Invalid configuration. If 'enable_energy_caching' is set, 'energy_redis_path' is also required "
138-
)
51+
for ky in cls.all_keys:
52+
if cls.config_data.has_option(cls.section_name, ky["name"]):
53+
value = cls.config_data.get(cls.section_name, ky["name"])
13954
else:
140-
r = redis.from_url(self.get("energy_redis_path"))
141-
r.ping()
142-
# print("Connection to redis works")
55+
env_key = f"cgc_{ky['name']}"
56+
value = os.getenv(env_key, ky["default"])
57+
cls.config_data.set(cls.section_name, ky["name"], value)
58+
59+
if cls.get("enable_energy_caching"):
60+
if not cls.get("energy_redis_path"):
61+
raise ConfigError("'energy_redis_path' is required when 'enable_energy_caching' is enabled.")
62+
redis.from_url(cls.get("energy_redis_path")).ping()
14363

144-
if self.get("enable_logging") == True:
145-
if self.get("log_folder_path") is None:
146-
raise ConfigError(
147-
"Invalid configuration. If 'enable_logging' is set, 'log_folder_path' is also required "
148-
)
149-
else:
150-
base_dir = self.get("log_folder_path")
151-
os.makedirs(base_dir, exist_ok=True)
64+
if cls.get("enable_logging"):
65+
if not cls.get("log_folder_path"):
66+
raise ConfigError("'log_folder_path' is required when 'enable_logging' is enabled.")
67+
os.makedirs(cls.get("log_folder_path"), exist_ok=True)
15268

15369
@classmethod
154-
def get(self, key):
155-
if not self.config_data.sections():
156-
raise ConfigError(
157-
"Configuration not loaded. Please call 'load_config' first."
158-
)
159-
try:
160-
value = self.config_data.get(self.section_name, key)
161-
config = next((d for d in self.all_keys if d.get("name") == key), None)
162-
if config["boolean"]:
163-
return value.lower() == "true"
164-
return value
165-
except (configparser.NoSectionError, configparser.NoOptionError) as e:
166-
print("Config not found")
167-
print(key)
168-
raise e
169-
70+
def get(cls, key):
71+
if not cls.config_data.sections():
72+
raise ConfigError("Configuration not loaded. Call 'load_config' first.")
73+
74+
value = cls.config_data.get(cls.section_name, key, fallback=None)
75+
config = next((d for d in cls.all_keys if d["name"] == key), None)
76+
if config and config["boolean"]:
77+
return value.lower() == "true"
78+
return value
79+
17080
@classmethod
171-
def get_config_file_path(self):
172-
"""Returns the path of the config file"""
173-
return self.config_file_path
81+
def get_config_file_path(cls):
82+
"""Returns the path of the config file."""
83+
return cls.config_file_path

0 commit comments

Comments
 (0)