Skip to content

Commit 865809a

Browse files
authored
Merge pull request #782 from EvanKomp/master
CLI can be called in offline mode without and API endpoint
2 parents ef1d1d9 + f73024a commit 865809a

2 files changed

Lines changed: 59 additions & 22 deletions

File tree

codecarbon/cli/main.py

Lines changed: 48 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import os
2+
import signal
23
import sys
34
import time
45
from pathlib import Path
@@ -23,7 +24,7 @@
2324
)
2425
from codecarbon.core.api_client import ApiClient, get_datetime_with_timezone
2526
from codecarbon.core.schemas import ExperimentCreate, OrganizationCreate, ProjectCreate
26-
from codecarbon.emissions_tracker import EmissionsTracker
27+
from codecarbon.emissions_tracker import EmissionsTracker, OfflineEmissionsTracker
2728

2829
AUTH_CLIENT_ID = os.environ.get(
2930
"AUTH_CLIENT_ID",
@@ -336,28 +337,55 @@ def monitor(
336337
api: Annotated[
337338
bool, typer.Option(help="Choose to call Code Carbon API or not")
338339
] = True,
340+
offline: Annotated[bool, typer.Option(help="Run in offline mode")] = False,
341+
country_iso_code: Annotated[
342+
str, typer.Option(help="3-letter country ISO code for offline mode")
343+
] = None,
344+
region: Annotated[
345+
str, typer.Option(help="Region/province for offline mode")
346+
] = None,
339347
):
340-
"""Monitor your machine's carbon emissions.
348+
"""Monitor your machine's carbon emissions."""
349+
if offline:
350+
if not country_iso_code:
351+
print(
352+
"ERROR: country_iso_code is required for offline mode", file=sys.stderr
353+
)
354+
raise typer.Exit(1)
341355

342-
Args:
343-
measure_power_secs (Annotated[int, typer.Argument, optional): Interval between two measures. Defaults to 10.
344-
api_call_interval (Annotated[int, typer.Argument, optional): Number of measures before calling API. Defaults to 30.
345-
api (Annotated[bool, typer.Option, optional): Choose to call Code Carbon API or not. Defaults to True.
346-
"""
347-
experiment_id = get_existing_local_exp_id()
348-
if api:
349-
if experiment_id is None:
356+
tracker = OfflineEmissionsTracker(
357+
measure_power_secs=measure_power_secs,
358+
country_iso_code=country_iso_code,
359+
region=region,
360+
)
361+
else:
362+
experiment_id = get_existing_local_exp_id()
363+
if api and experiment_id is None:
350364
print(
351365
"ERROR: No experiment id, call 'codecarbon config' first.",
352366
file=sys.stderr,
353367
)
368+
raise typer.Exit(1)
369+
370+
tracker = EmissionsTracker(
371+
measure_power_secs=measure_power_secs,
372+
api_call_interval=api_call_interval,
373+
save_to_api=api,
374+
)
375+
376+
def signal_handler(signum, frame):
377+
print("\nReceived signal to stop. Saving emissions data...")
378+
tracker.stop()
379+
sys.exit(0)
380+
381+
signal.signal(signal.SIGINT, signal_handler)
382+
signal.signal(signal.SIGTERM, signal_handler)
383+
354384
print("CodeCarbon is going in an infinite loop to monitor this machine.")
355-
with EmissionsTracker(
356-
measure_power_secs=measure_power_secs,
357-
api_call_interval=api_call_interval,
358-
save_to_api=api,
359-
) as tracker:
360-
# Infinite loop
385+
print("Press Ctrl+C to stop and save emissions data.")
386+
387+
tracker.start()
388+
try:
361389
while True:
362390
if (
363391
hasattr(tracker, "_another_instance_already_running")
@@ -366,6 +394,10 @@ def monitor(
366394
print("Another instance of CodeCarbon is already running. Exiting.")
367395
break
368396
time.sleep(300)
397+
except Exception as e:
398+
print(f"\nError occurred: {e}")
399+
tracker.stop()
400+
raise e
369401

370402

371403
def questionary_prompt(prompt, list_options, default):

docs/edit/usage.rst

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -15,17 +15,17 @@ Command line
1515
~~~~~~~~~~~~
1616

1717

18-
Create a minimal configuration file (just follow the prompts) :
18+
Create a minimal configuration file (just follow the prompts) :
1919

2020
.. code-block:: console
2121
22-
codecarbon config
22+
codecarbon config
2323
2424
.. image:: https://asciinema.org/a/667970.svg
2525
:align: center
2626
:alt: Init config
2727
:target: https://asciinema.org/a/667970
28-
28+
2929
You can use the same command to modify an existing config :
3030

3131
.. image:: https://asciinema.org/a/667971.svg
@@ -38,12 +38,12 @@ If you want to track the emissions of a computer without having to modify your c
3838

3939
.. code-block:: console
4040
41-
codecarbon monitor
41+
codecarbon monitor
4242
4343
You have to stop the monitoring manually with ``Ctrl+C``.
4444

45-
In the following example you will see how to use the CLI to monitor all the emissions of you computer and sending everything
46-
to an API running on "localhost:8008" (Or you can start a private local API with "docker-compose up"). Using the public API with
45+
In the following example you will see how to use the CLI to monitor all the emissions of you computer and sending everything
46+
to an API running on "localhost:8008" (Or you can start a private local API with "docker-compose up"). Using the public API with
4747
this is not supported yet (coming soon!)
4848

4949
.. image:: https://asciinema.org/a/667984.svg
@@ -52,6 +52,11 @@ this is not supported yet (coming soon!)
5252
:target: https://asciinema.org/a/667984
5353

5454

55+
The command line could also works without internet by providing the country code like this:
56+
57+
.. code-block:: console
58+
59+
codecarbon monitor --offline --country-iso-code FRA
5560
5661
Implementing CodeCarbon in your code allows you to track the emissions of a specific block of code.
5762

0 commit comments

Comments
 (0)